diff --git a/.clang-format b/.clang-format
index c700d9700..1b47c9d29 100644
--- a/.clang-format
+++ b/.clang-format
@@ -70,7 +70,7 @@ IncludeCategories:
- Regex: '^<.*'
Priority: 3
# IncludeIsMainRegex: '(Test)?$'
-IndentCaseLabels: false
+IndentCaseLabels: false
#IndentPPDirectives: AfterHash
IndentWidth: 4
# IndentWrappedFunctionNames: false
diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml
index 2c5ca438b..9acad9d41 100644
--- a/.github/workflows/ccpp.yml
+++ b/.github/workflows/ccpp.yml
@@ -7,14 +7,147 @@ 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:
fail-fast: false
+ matrix:
+ name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, windows-latest-clang.exe, ubuntu-latest-clang++]
+ # For Windows msvc, for Linux and macOS let's use the clang compiler, use gcc for Linux.
+ include:
+ - name: windows-latest-clang.exe
+ os: windows-latest
+ cxx: clang++.exe
+ cc: clang.exe
+ - name: windows-latest-cl.exe
+ os: windows-latest
+ cxx: cl.exe
+ cc: cl.exe
+ - name: windows-hunter-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
+
+ steps:
+ - name: ccache
+ uses: hendrikmuhs/ccache-action@v1.2
+
+ - uses: actions/checkout@v4
+ with:
+ submodules: true
+
+ - uses: lukka/get-cmake@latest
+
+ - uses: ilammy/msvc-dev-cmd@v1
+
+ - name: Set Compiler Environment
+ uses: lukka/set-shell-env@v1
+ with:
+ CXX: ${{ matrix.cxx }}
+ CC: ${{ matrix.cc }}
+
+ - name: Cache DX SDK
+ id: dxcache
+ if: contains(matrix.name, 'windows')
+ uses: actions/cache@v4
+ with:
+ path: '${{ github.workspace }}/DX_SDK'
+ key: ${{ runner.os }}-DX_SDK
+ restore-keys: |
+ ${{ runner.os }}-DX_SDK
+
+ - name: Download DXSetup
+ if: contains(matrix.name, 'windows-latest-cl.exe') && steps.dxcache.outputs.cache-hit != 'true'
+ run: |
+ curl -s -o DXSDK_Jun10.exe --location https://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe
+ cmd.exe /c start /wait .\DXSDK_Jun10.exe /U /O /F /S /P "${{ github.workspace }}\DX_SDK"
+
+ - name: Set Windows specific CMake arguments
+ if: contains(matrix.name, 'windows-latest-cl.exe')
+ id: windows_extra_cmake_args
+ 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 "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
+ 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: Exclude certain tests in Hunter specific builds
+ if: contains(matrix.name, 'hunter')
+ id: hunter_extra_test_args
+ 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 }}
+ shell: bash
+
+ - uses: actions/upload-artifact@v4
+ if: matrix.name == 'windows-msvc'
+ with:
+ 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.
@@ -44,85 +177,24 @@ jobs:
- 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: actions/checkout@v4
- with:
- submodules: true
-
- - uses: lukka/get-cmake@latest
-
- - uses: ilammy/msvc-dev-cmd@v1
-
- - name: Set Compiler Environment
- if: "!endsWith(matrix.name, 'hunter')"
- uses: lukka/set-shell-env@v1
- with:
- CXX: ${{ matrix.cxx }}
- CC: ${{ matrix.cc }}
-
- - name: Set Compiler Environment for Hunter on Windows
- if: startsWith(matrix.name, 'windows') && endsWith(matrix.name, 'hunter')
- uses: lukka/set-shell-env@v1
- with:
- VS160COMNTOOLS: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools
-
- - name: Checkout Hunter toolchains
- if: endsWith(matrix.name, 'hunter')
- uses: actions/checkout@v4
- with:
- repository: cpp-pm/polly
- path: cmake/polly
-
- - name: Cache DX SDK
- id: dxcache
- if: contains(matrix.name, 'windows')
- uses: actions/cache@v3
- with:
- path: '${{ github.workspace }}/DX_SDK'
- key: ${{ runner.os }}-DX_SDK
- restore-keys: |
- ${{ runner.os }}-DX_SDK
-
- - name: Download DXSetup
- if: contains(matrix.name, 'windows') && steps.dxcache.outputs.cache-hit != 'true'
- run: |
- curl -s -o DXSDK_Jun10.exe --location https://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe
- cmd.exe /c start /wait .\DXSDK_Jun10.exe /U /O /F /S /P "${{ github.workspace }}\DX_SDK"
-
- - name: Set Windows specific CMake arguments
- if: 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"
-
- - name: Set Hunter specific CMake arguments
- if: contains(matrix.name, 'hunter')
- id: hunter_extra_cmake_args
- run: echo "::set-output name=args::-DBUILD_SHARED_LIBS=OFF -DASSIMP_HUNTER_ENABLED=ON -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/cmake/polly/${{ matrix.toolchain }}.cmake"
-
- - name: configure and build
- uses: lukka/run-cmake@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: Exclude certain tests in Hunter specific builds
- if: contains(matrix.name, 'hunter')
- id: hunter_extra_test_args
- run: echo "::set-output name=args::--gtest_filter=-utOpenGEXImportExport.Importissue1340_EmptyCameraObject:utColladaZaeImportExport.importBlenFromFileTest"
-
- - name: test
- run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
- shell: bash
-
- - uses: actions/upload-artifact@v3
- if: matrix.name == 'windows-msvc'
- with:
- name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
- path: build/bin
+ - 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
+
diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml
new file mode 100644
index 000000000..a5ec10c7a
--- /dev/null
+++ b/.github/workflows/cd.yml
@@ -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
diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml
index a84be8cbc..38f54ce06 100644
--- a/.github/workflows/cifuzz.yml
+++ b/.github/workflows/cifuzz.yml
@@ -19,7 +19,7 @@ jobs:
dry-run: false
language: c++
- name: Upload Crash
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
diff --git a/.github/workflows/inno_setup b/.github/workflows/inno_setup
new file mode 100644
index 000000000..92f16918e
--- /dev/null
+++ b/.github/workflows/inno_setup
@@ -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+
diff --git a/.gitignore b/.gitignore
index 09d631ee8..68b6e8de4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/Build.md b/Build.md
index 9440a0073..440410032 100644
--- a/Build.md
+++ b/Build.md
@@ -1,36 +1,12 @@
# 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 (must support C++17 and C99 at least)
+* For Windows
+ * DX-SDK 9 if you want to use our 3D-Viewer
### Get the source
Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
@@ -38,15 +14,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,19 +40,8 @@ This will generate the project files for the visual studio. All dependencies use
### Build instructions for Windows with UWP
See
-### 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
+ 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.
Version 7.3.0 of g++-mingw-w64 & gcc-mingw-w64 appears to work.
@@ -111,3 +83,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)
diff --git a/CHANGES b/CHANGES
index c0c73b98c..3c4242239 100644
--- a/CHANGES
+++ b/CHANGES
@@ -290,7 +290,7 @@ FEATURES:
- Added support for 64 bit version header introduced in FbxSdk2016
- Travis: enable coverall support.
- PyAssimp: New version of the pyASSIMP 3D viewer, with much improved 3D controls
- - Morph animation support for collada
+ - Morph animation support for collada
- Added support for parameters Ni and Tf in OBJ/MTL file format
- aiScene: add method to add children
- Added new option to IFC importer to control tessellation angle + removed unused IFC option
@@ -300,7 +300,7 @@ FEATURES:
- travis ci: enable sudo support.
- openddlparser: integrate release v0.4.0
- aiMetaData: Added support for metadata in assbin format
-
+
FIXES/HOUSEKEEPING:
- Introduce usage of #pragma statement
- Put cmake-scripts into their own folder
@@ -352,7 +352,7 @@ FIXES/HOUSEKEEPING:
- add vertex color export support ( issue 809 )
- Fix memory leak in Collada importer ( issue 1169 )
- add stp to the list of supported extensions for step-files ( issue 1183 )
- - fix clang build ( Issue-1169 )
+ - fix clang build ( Issue-1169 )
- fix for FreeBSD
- Import FindPkgMacros to main CMake Configuration
- Extended support for tessellation parameter to more IFC shapes
@@ -375,7 +375,7 @@ FIXES/HOUSEKEEPING:
- Obj-Importer: do not break when detecting an overflow ( issue 1244 )
- Obj-Importer: fix parsing of multible line data definitions
- Fixed bug where IFC models with multiple IFCSite only loaded 1 site instead of the complete model
- - PLYImporter: - optimize memory and speed on ply importer / change parser to use a file stream - manage texture path in ply
+ - PLYImporter: - optimize memory and speed on ply importer / change parser to use a file stream - manage texture path in ply
import - manage texture coords on faces in ply import - correction on point cloud faces generation
- Utf8: integrate new lib ( issue 1158 )
- fixed CMAKE_MODULE_PATH overwriting previous values
@@ -400,7 +400,7 @@ FIXES/HOUSEKEEPING:
- Remove std functions deprecated by C++11.
- X-Importer: make it deal with lines
- use correct path for compilers ( issue 1335 )
- - Collada: add workaround to deal with polygon with holes
+ - Collada: add workaround to deal with polygon with holes
- update python readme
- Use unique node names when loading Collada files
- Fixed many FBX bugs
@@ -429,7 +429,7 @@ FEATURES:
- C4D: update to latest Melange-SDK
- Add a gitter channel
- Coverity check enabled
- - Switch to <...> include brackets for public headers
+ - Switch to <...> include brackets for public headers
- Enable export by pyAssimp
- CI: check windows build
- Add functionality to perform a singlepost-processing step
@@ -564,7 +564,7 @@ API CHANGES:
currently used, however ...)
- Some Assimp::Importer methods are const now.
-
+
1.1 (2010-04-17)
This is the list of relevant changes from the 1.0 (r412) release to 1.1 (r700).
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88f69174a..b0633b4e5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
# Open Asset Import Library (assimp)
# ----------------------------------------------------------------------
-# Copyright (c) 2006-2023, assimp team
+# Copyright (c) 2006-2025, assimp team
#
# All rights reserved.
#
@@ -38,24 +38,76 @@ SET(CMAKE_POLICY_DEFAULT_CMP0012 NEW)
SET(CMAKE_POLICY_DEFAULT_CMP0074 NEW)
SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW)
-CMAKE_MINIMUM_REQUIRED( VERSION 3.10 )
+CMAKE_MINIMUM_REQUIRED( VERSION 3.22 )
+
+#================================================================================#
+# 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()
-# Disabled importers: m3d for 5.1
-ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER)
-ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER)
# 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.24.18.tar.gz"
- SHA1 "1292e4d661e1770d6d6ca08c12c07cf34a0bf718"
+ URL "https://github.com/cpp-pm/hunter/archive/v0.25.8.tar.gz"
+ SHA1 "26c79d587883ec910bce168e25f6ac4595f97033"
)
- add_definitions(-DASSIMP_USE_HUNTER)
+ ADD_DEFINITIONS(-DASSIMP_USE_HUNTER)
ENDIF()
-PROJECT(Assimp VERSION 5.3.0)
+PROJECT(Assimp VERSION 6.0.2
+ LANGUAGES C CXX
+ DESCRIPTION "Open Asset Import Library (Assimp) is a library to import various well-known 3D model formats in a uniform manner."
+)
# All supported options ###############################################
@@ -131,35 +183,35 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH
IF (WIN32)
OPTION( ASSIMP_BUILD_ZLIB
- "Build your own zlib"
+ "Build your zlib"
ON
)
ELSE()
OPTION( ASSIMP_BUILD_ZLIB
- "Build your own zlib"
- ON
+ "Build your zlib"
+ OFF
)
ENDIF()
IF (WIN32)
- # Use subset of Windows.h
+ # Use a subset of Windows.h
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
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 is deprecated since at least MSVC2015 (possibly earlier)
+ # Multibyte character set has been deprecated since at least MSVC2015 (possibly earlier)
ADD_DEFINITIONS( -DUNICODE -D_UNICODE )
ENDIF()
- # Link statically against c/c++ lib to avoid missing redistriburable such as
+ # Link statically against c/c++ lib to avoid missing redistributable such as
# "VCRUNTIME140.dll not found. Try reinstalling the app.", but give users
# a choice to opt for the shared runtime if they want.
option(USE_STATIC_CRT "Link against the static runtime libraries." OFF)
- # The CMAKE_CXX_FLAGS vars can be overriden by some Visual Studio generators, so we use an alternative
+ # The CMAKE_CXX_FLAGS vars can be overridden by some Visual Studio generators, so we use an alternative
# global method here:
if (${USE_STATIC_CRT})
add_compile_options(
@@ -197,7 +249,7 @@ SET (ASSIMP_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
SET (ASSIMP_VERSION_MINOR ${PROJECT_VERSION_MINOR})
SET (ASSIMP_VERSION_PATCH ${PROJECT_VERSION_PATCH})
SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
-SET (ASSIMP_SOVERSION 5)
+SET (ASSIMP_SOVERSION 6)
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
set(CMAKE_CXX_STANDARD 17)
@@ -249,21 +301,32 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
IF( UNIX )
# Use GNUInstallDirs for Unix predefined directories
INCLUDE(GNUInstallDirs)
- # Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
+ # Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit Linux
IF(NOT ${OPERATING_SYSTEM} MATCHES "Android")
- IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
+ IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit Linux
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
ENDIF()
ENDIF()
ENDIF()
+IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND WIN32)
+ ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
+ ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
+ENDIF()
+
+IF( MSVC OR "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC") # clang with MSVC ABI
+ ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
+ ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
+endif ()
+
+
# Grouped compiler settings ########################################
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("$<$:-Wno-dangling-reference>")
ENDIF()
@@ -284,22 +347,31 @@ 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 precission is activated
- ADD_COMPILE_OPTIONS(/wd4244)
+ # supress warning for double to float conversion if Double precision is activated
+ 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()
+ if(NOT /utf-8 IN_LIST CMAKE_CXX_FLAGS)
+ # Source code is encoded in UTF-8
+ ADD_COMPILE_OPTIONS(/source-charset:utf-8)
+ endif()
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
ENDIF()
- SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
- SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
+ SET(CMAKE_CXX_FLAGS "-Wno-deprecated-non-prototype -fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
+ SET(CMAKE_C_FLAGS "-Wno-deprecated-non-prototype -fno-strict-aliasing ${CMAKE_C_FLAGS}")
ELSEIF( MINGW )
IF (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
message(FATAL_ERROR "MinGW is too old to be supported. Please update MinGW and try again.")
@@ -311,9 +383,9 @@ ELSEIF( MINGW )
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
ENDIF()
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
- SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -g ${CMAKE_CXX_FLAGS}")
+ SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wno-dangling-reference -Wall -Wno-long-long -Wa,-mbig-obj -g ${CMAKE_CXX_FLAGS}")
ELSE()
- SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
+ SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wno-dangling-reference -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
ENDIF()
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
ENDIF()
@@ -330,7 +402,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 +410,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()
@@ -422,20 +494,20 @@ ENDIF()
set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
IF(ASSIMP_HUNTER_ENABLED)
- set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
- set(CMAKE_CONFIG_TEMPLATE_FILE "cmake-modules/assimp-hunter-config.cmake.in")
- set(NAMESPACE "${PROJECT_NAME}::")
- set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
- set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
- set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
+ SET(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
+ SET(CMAKE_CONFIG_TEMPLATE_FILE "cmake-modules/assimp-hunter-config.cmake.in")
+ SET(NAMESPACE "${PROJECT_NAME}::")
+ SET(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
+ SET(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
+ SET(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
ELSE()
- set(CONFIG_INSTALL_DIR "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
- set(CMAKE_CONFIG_TEMPLATE_FILE "cmake-modules/assimp-plain-config.cmake.in")
+ SET(CONFIG_INSTALL_DIR "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
+ SET(CMAKE_CONFIG_TEMPLATE_FILE "cmake-modules/assimp-plain-config.cmake.in")
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE)
- set(NAMESPACE "${PROJECT_NAME_LOWERCASE}::")
- set(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWERCASE}Targets")
- set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME_LOWERCASE}ConfigVersion.cmake")
- set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME_LOWERCASE}Config.cmake")
+ SET(NAMESPACE "${PROJECT_NAME_LOWERCASE}::")
+ SET(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWERCASE}Targets")
+ SET(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME_LOWERCASE}ConfigVersion.cmake")
+ SET(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME_LOWERCASE}Config.cmake")
ENDIF()
set(INCLUDE_INSTALL_DIR "include")
@@ -452,18 +524,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)
@@ -476,12 +550,12 @@ IF(ASSIMP_HUNTER_ENABLED)
find_package(ZLIB CONFIG REQUIRED)
add_definitions(-DASSIMP_BUILD_NO_OWN_ZLIB)
- set(ZLIB_FOUND TRUE)
- set(ZLIB_LIBRARIES ZLIB::zlib)
- set(ASSIMP_BUILD_MINIZIP TRUE)
+ SET(ZLIB_FOUND TRUE)
+ SET(ZLIB_LIBRARIES ZLIB::zlib)
+ 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()
@@ -505,8 +579,8 @@ ELSE()
# https://github.com/madler/zlib/issues/41#issuecomment-125848075
# Also prevents these options from "polluting" the cmake options if assimp is being
# included as a submodule.
- set( ASM686 FALSE CACHE INTERNAL "Override ZLIB flag to turn off assembly" FORCE )
- set( AMD64 FALSE CACHE INTERNAL "Override ZLIB flag to turn off assembly" FORCE )
+ SET(ASM686 FALSE CACHE INTERNAL "Override ZLIB flag to turn off assembly" FORCE )
+ SET(AMD64 FALSE CACHE INTERNAL "Override ZLIB flag to turn off assembly" FORCE )
# compile from sources
ADD_SUBDIRECTORY(contrib/zlib)
@@ -529,7 +603,7 @@ IF( NOT IOS )
ELSE ()
IF( NOT BUILD_SHARED_LIBS )
IF( NOT ASSIMP_BUILD_MINIZIP )
- use_pkgconfig(UNZIP minizip)
+ USE_PKGCONFIG(UNZIP minizip)
ENDIF()
ENDIF ()
ENDIF ()
@@ -563,9 +637,9 @@ SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL
)
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
- IF ( MSVC )
- SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/includes")
+ SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/includes")
+ IF (WIN32)
# pick the correct prebuilt library
IF(MSVC143)
SET(C4D_LIB_POSTFIX "_2022")
@@ -583,7 +657,7 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
SET(C4D_LIB_POSTFIX "_2010")
ELSE()
MESSAGE( FATAL_ERROR
- "C4D is currently only supported with MSVC 10, 11, 12, 14, 14.2, 14.3"
+ "C4D for Windows is currently only supported with MSVC 10, 11, 12, 14, 14.2, 14.3"
)
ENDIF()
@@ -601,68 +675,90 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
# winsock and winmm are necessary (and undocumented) dependencies of Cineware SDK because
# it can be used to communicate with a running Cinema 4D instance
SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib)
- ELSE ()
- MESSAGE( FATAL_ERROR
- "C4D is currently only available on Windows with Cineware SDK installed in contrib/Cineware"
+ ELSEIF (APPLE)
+ SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/libraries/osx")
+
+ SET(C4D_DEBUG_LIBRARIES
+ "${C4D_LIB_BASE_PATH}/debug/libcinewarelib.a"
+ "${C4D_LIB_BASE_PATH}/debug/libjpeglib.a"
)
- ENDIF ()
+ SET(C4D_RELEASE_LIBRARIES
+ "${C4D_LIB_BASE_PATH}/release/libcinewarelib.a"
+ "${C4D_LIB_BASE_PATH}/release/libjpeglib.a"
+ )
+ ELSE()
+ MESSAGE( FATAL_ERROR
+ "C4D is currently only available on Windows and macOS with Cineware SDK installed in contrib/Cineware"
+ )
+ ENDIF()
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")
+ MESSAGE(NOTICE "draco requires cmake 3.12 or newer, cmake is ${CMAKE_VERSION} . Draco is disabled")
SET ( ASSIMP_BUILD_DRACO OFF CACHE BOOL "Disabled: Draco requires newer cmake" FORCE )
ELSE()
OPTION ( ASSIMP_BUILD_DRACO "If the Draco libraries are to be built. Primarily for glTF" OFF )
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)
- set(DRACO_MAYA_PLUGIN OFF CACHE BOOL "" FORCE)
- set(DRACO_UNITY_PLUGIN OFF CACHE BOOL "" FORCE)
- set(DRACO_TESTS OFF CACHE BOOL "" FORCE)
+ SET(DRACO_JS_GLUE OFF CACHE BOOL "" FORCE)
+ SET(DRACO_WASM OFF CACHE BOOL "" FORCE)
+ SET(DRACO_MAYA_PLUGIN OFF CACHE BOOL "" FORCE)
+ SET(DRACO_UNITY_PLUGIN OFF CACHE BOOL "" FORCE)
+ SET(DRACO_TESTS OFF CACHE BOOL "" FORCE)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(draco)
find_package(draco CONFIG REQUIRED)
- set(draco_LIBRARIES draco::draco)
+ SET(draco_LIBRARIES draco::draco)
ELSE()
# Draco 1.4.1 has many warnings and will not build with /WX or -Werror
# See https://github.com/google/draco/issues/672
# and https://github.com/google/draco/issues/673
IF(MSVC)
- set(DRACO_CXX_FLAGS "/W0")
+ SET(DRACO_CXX_FLAGS "/W0")
ELSE()
- list(APPEND DRACO_CXX_FLAGS
+ LIST(APPEND DRACO_CXX_FLAGS
"-Wno-bool-compare"
"-Wno-comment"
"-Wno-maybe-uninitialized"
"-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(MSVC OR WIN32)
- set(draco_LIBRARIES "draco")
- else()
- if(BUILD_SHARED_LIBS)
- set(draco_LIBRARIES "draco_shared")
- else()
- set(draco_LIBRARIES "draco_static")
- endif()
- endif()
+ 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(ASSIMP_BUILD_DRACO_STATIC)
+ SET(draco_LIBRARIES "draco_static")
+ ELSE()
+ SET(draco_LIBRARIES "draco_shared")
+ ENDIF()
+ ENDIF()
# Don't build the draco command-line tools by default
set_target_properties(draco_encoder draco_decoder PROPERTIES
@@ -680,18 +776,20 @@ ELSE()
TARGET_USE_COMMON_OUTPUT_DIRECTORY(draco_encoder)
TARGET_USE_COMMON_OUTPUT_DIRECTORY(draco_decoder)
- set(draco_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/draco/src")
+ 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()
@@ -735,8 +833,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(
@@ -824,24 +922,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 ()
diff --git a/CREDITS b/CREDITS
index 26e21d2f4..62b449614 100644
--- a/CREDITS
+++ b/CREDITS
@@ -60,7 +60,7 @@ The GUY who performed some of the CSM mocaps.
Contributed fixes for the documentation and the doxygen markup
- Zhao Lei
-Contributed several bugfixes fixing memory leaks and improving float parsing
+Contributed several bugfixes fixing memory leaks and improving float parsing
- sueastside
Updated PyAssimp to the latest Assimp data structures and provided a script to keep the Python binding up-to-date.
@@ -129,7 +129,7 @@ Contributed a patch to fix the VertexTriangleAdjacency postprocessing step.
Contributed the Debian build fixes ( architecture macro ).
- gellule
-Several LWO and LWS fixes (pivoting).
+Several LWO and LWS fixes (pivoting).
- Marcel Metz
GCC/Linux fixes for the SimpleOpenGL sample.
diff --git a/Dockerfile b/Dockerfile
index 5da5458f8..21dd41daa 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,21 +1,17 @@
-FROM ubuntu:22.04
+FROM gcc:1.5.1.0
-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 zlib1g-dev
-RUN add-apt-repository ppa:ubuntu-toolchain-r/test && apt-get update
+WORKDIR /app
-WORKDIR /opt
+COPY . .
-# Build Assimp
-RUN git clone https://github.com/assimp/assimp.git /opt/assimp
-
-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"]
diff --git a/INSTALL b/INSTALL
index 410050b10..e5e5938cb 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,17 +1,17 @@
-
+
========================================================================
-Open Asset Import Library (assimp) INSTALL
+Open Asset Import Library (assimp) INSTALL
========================================================================
------------------------------
Getting the documentation
------------------------------
-A regularly-updated copy is available at
+A regularly-updated copy is available at
https://assimp-docs.readthedocs.io/en/latest/
------------------------------
-Building Assimp
+Building Assimp
------------------------------
Just check the build-instructions which you can find here: https://github.com/assimp/assimp/blob/master/Build.md
diff --git a/Readme.md b/Readme.md
index a1f707a95..262456b6a 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,57 +1,61 @@
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 ###
-[](https://opencollective.com/assimp)

[](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade)
-[](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[](https://sonarcloud.io/summary/new_code?id=assimp_assimp)
[](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
[](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
+[](https://gurubase.io/g/assimp)
+[](https://opencollective.com/assimp)
-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 ##
+
+
### Documentation ###
-Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
+Read [our latest documentation](https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/).
### Pre-built binaries ###
-Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
+Download binaries from [our Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib).
-If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
+### Test data ###
+Clone [our model database](https://github.com/assimp/assimp-mdb).
### Communities ###
-- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
-- Ask on [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 [](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+- 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)
#### Supported file formats ####
-You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
+See [the complete list of supported formats](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md).
### Building ###
-Take a look [here](https://github.com/assimp/assimp/blob/master/Build.md) to get started. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
+Start by reading [our build instructions](https://github.com/assimp/assimp/blob/master/Build.md). We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
### Ports ###
* [Android](port/AndroidJNI/README.md)
* [Python](port/PyAssimp/README.md)
-* [.NET](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.
[Assimp-Viewer](https://github.com/assimp/assimp_view) is an experimental implementation for an Asset-Viewer based on ImGUI and Assimp (experimental).
#### Repository structure ####
@@ -59,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
@@ -79,7 +83,7 @@ The source code is organized in the following way:
code/AssetLib/ 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
@@ -101,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)]
@@ -111,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 ...
diff --git a/SECURITY.md b/SECURITY.md
index e4915cd1c..eee961e7f 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -7,10 +7,10 @@ currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
-| 5.2.4 | :white_check_mark: |
+| 6.0.2 | :white_check_mark: |
## Reporting a Vulnerability
-If you have found any security vulnerability you can contact us via
+If you have found any security vulnerability you can contact us via
kim.kulling@googlemail.com
diff --git a/cmake-modules/DebSourcePPA.cmake b/cmake-modules/DebSourcePPA.cmake
index d8a786fb2..ebf129b4f 100644
--- a/cmake-modules/DebSourcePPA.cmake
+++ b/cmake-modules/DebSourcePPA.cmake
@@ -6,7 +6,7 @@
# Creates source debian files and manages library dependencies
#
# Features:
-#
+#
# - Automatically generates symbols and run-time dependencies from the build dependencies
# - Custom copy of source directory via CPACK_DEBIAN_PACKAGE_SOURCE_COPY
# - Simultaneous output of multiple debian source packages for each distribution
@@ -114,7 +114,6 @@ foreach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES})
endif( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
endif( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
-
file(APPEND ${DEBIAN_CONTROL} "\n"
"Standards-Version: 3.8.4\n"
"Homepage: ${CPACK_PACKAGE_VENDOR}\n"
@@ -173,7 +172,7 @@ foreach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES})
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS})
endif( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
endif( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
-
+
file(APPEND ${DEBIAN_CONTROL} "\n"
"Description: ${CPACK_PACKAGE_DISPLAY_NAME} ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}\n"
"${DEB_LONG_DESCRIPTION}"
diff --git a/cmake-modules/FindDirectX.cmake b/cmake-modules/FindDirectX.cmake
index b37bc12a3..adc836902 100644
--- a/cmake-modules/FindDirectX.cmake
+++ b/cmake-modules/FindDirectX.cmake
@@ -26,7 +26,7 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
getenv_path(DIRECTX_BASE)
# construct search paths
- set(DirectX_PREFIX_PATH
+ set(DirectX_PREFIX_PATH
"${DXSDK_DIR}" "${ENV_DXSDK_DIR}"
"${DIRECTX_HOME}" "${ENV_DIRECTX_HOME}"
"${DIRECTX_ROOT}" "${ENV_DIRECTX_ROOT}"
@@ -66,7 +66,7 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
find_library(DirectX_D3DCOMPILER_LIBRARY NAMES d3dcompiler HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
findpkg_finish(DirectX)
- set(DirectX_LIBRARIES ${DirectX_LIBRARIES}
+ set(DirectX_LIBRARIES ${DirectX_LIBRARIES}
${DirectX_D3DX9_LIBRARY}
${DirectX_DXERR_LIBRARY}
${DirectX_DXGUID_LIBRARY}
@@ -82,7 +82,7 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
get_filename_component(DirectX_LIBRARY_DIR "${DirectX_LIBRARY}" PATH)
message(STATUS "DX lib dir: ${DirectX_LIBRARY_DIR}")
find_library(DirectX_D3D11_LIBRARY NAMES d3d11 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
- find_library(DirectX_D3DX11_LIBRARY NAMES d3dx11 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
+ find_library(DirectX_D3DX11_LIBRARY NAMES d3dx11 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
if (DirectX_D3D11_INCLUDE_DIR AND DirectX_D3D11_LIBRARY)
set(DirectX_D3D11_FOUND TRUE)
set(DirectX_D3D11_INCLUDE_DIR ${DirectX_D3D11_INCLUDE_DIR})
@@ -92,8 +92,8 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
${DirectX_DXGI_LIBRARY}
${DirectX_DXERR_LIBRARY}
${DirectX_DXGUID_LIBRARY}
- ${DirectX_D3DCOMPILER_LIBRARY}
- )
+ ${DirectX_D3DCOMPILER_LIBRARY}
+ )
endif ()
mark_as_advanced(DirectX_D3D11_INCLUDE_DIR DirectX_D3D11_LIBRARY DirectX_D3DX11_LIBRARY)
endif ()
diff --git a/cmake-modules/Findassimp.cmake b/cmake-modules/Findassimp.cmake
index 663645574..c5d7e269b 100644
--- a/cmake-modules/Findassimp.cmake
+++ b/cmake-modules/Findassimp.cmake
@@ -3,7 +3,7 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(ASSIMP_ARCHITECTURE "32")
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
-
+
if(WIN32)
set(ASSIMP_ROOT_DIR CACHE PATH "ASSIMP root directory")
@@ -17,29 +17,29 @@ if(WIN32)
if(MSVC12)
set(ASSIMP_MSVC_VERSION "vc120")
- elseif(MSVC14)
+ elseif(MSVC14)
set(ASSIMP_MSVC_VERSION "vc140")
endif(MSVC12)
-
+
if(MSVC12 OR MSVC14)
-
+
find_path(ASSIMP_LIBRARY_DIR
NAMES
assimp-${ASSIMP_MSVC_VERSION}-mt.lib
HINTS
${ASSIMP_ROOT_DIR}/lib${ASSIMP_ARCHITECTURE}
)
-
+
find_library(ASSIMP_LIBRARY_RELEASE assimp-${ASSIMP_MSVC_VERSION}-mt.lib PATHS ${ASSIMP_LIBRARY_DIR})
find_library(ASSIMP_LIBRARY_DEBUG assimp-${ASSIMP_MSVC_VERSION}-mtd.lib PATHS ${ASSIMP_LIBRARY_DIR})
-
- set(ASSIMP_LIBRARY
+
+ set(ASSIMP_LIBRARY
optimized ${ASSIMP_LIBRARY_RELEASE}
debug ${ASSIMP_LIBRARY_DEBUG}
)
-
+
set(ASSIMP_LIBRARIES "ASSIMP_LIBRARY_RELEASE" "ASSIMP_LIBRARY_DEBUG")
-
+
FUNCTION(ASSIMP_COPY_BINARIES TargetDirectory)
ADD_CUSTOM_TARGET(AssimpCopyBinaries
COMMAND ${CMAKE_COMMAND} -E copy ${ASSIMP_ROOT_DIR}/bin${ASSIMP_ARCHITECTURE}/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${TargetDirectory}/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll
@@ -47,9 +47,37 @@ if(WIN32)
COMMENT "Copying Assimp binaries to '${TargetDirectory}'"
VERBATIM)
ENDFUNCTION(ASSIMP_COPY_BINARIES)
-
+
+ if (NOT TARGET ASSIMP)
+ set(INCLUDE_DIRS ${ASSIMP_ROOT_DIR}/include)
+
+ find_library(ASSIMP_LIB_DEBUG
+ NAMES assimp-${ASSIMP_MSVC_VERSION}-mtd.lib
+ PATHS ${ASSIMP_LIBRARY_DIR})
+
+ find_file(ASSIMP_DLL_DEBUG
+ NAMES assimp-${ASSIMP_MSVC_VERSION}-mtd.dll
+ PATHS ${ASSIMP_ROOT_DIR}/bin${ASSIMP_ARCHITECTURE})
+
+ find_library(ASSIMP_LIB_RELEASE
+ NAMES assimp-${ASSIMP_MSVC_VERSION}-mt.lib
+ PATHS ${ASSIMP_LIBRARY_DIR})
+
+ find_file(ASSIMP_DLL_RELEASE
+ NAMES assimp-${ASSIMP_MSVC_VERSION}-mt.dll
+ PATHS ${ASSIMP_ROOT_DIR}/bin${ASSIMP_ARCHITECTURE})
+
+ add_library(ASSIMP SHARED IMPORTED)
+ set_target_properties(ASSIMP PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${INCLUDE_DIRS}"
+ IMPORTED_IMPLIB_DEBUG ${ASSIMP_LIB_DEBUG}
+ IMPORTED_IMPLIB_RELEASE ${ASSIMP_LIB_RELEASE}
+ IMPORTED_LOCATION_DEBUG ${ASSIMP_DLL_DEBUG}
+ IMPORTED_LOCATION_RELEASE ${ASSIMP_DLL_RELEASE}
+ )
+ endif()
endif()
-
+
else(WIN32)
find_path(
@@ -81,5 +109,5 @@ else(WIN32)
message(FATAL_ERROR "Could not find asset importer library")
endif (assimp_FIND_REQUIRED)
endif (assimp_FOUND)
-
+
endif(WIN32)
diff --git a/cmake-modules/HunterGate.cmake b/cmake-modules/HunterGate.cmake
index 6d9cc2401..48bd50658 100644
--- a/cmake-modules/HunterGate.cmake
+++ b/cmake-modules/HunterGate.cmake
@@ -22,45 +22,16 @@
# OR TORT (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)
option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
-set(HUNTER_ERROR_PAGE "https://docs.hunter.sh/en/latest/reference/errors")
+set(HUNTER_ERROR_PAGE "https://hunter.readthedocs.io/en/latest/reference/errors")
function(hunter_gate_status_print)
if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
diff --git a/cmake-modules/PrecompiledHeader.cmake b/cmake-modules/PrecompiledHeader.cmake
index 6af7866f5..92ae592c9 100644
--- a/cmake-modules/PrecompiledHeader.cmake
+++ b/cmake-modules/PrecompiledHeader.cmake
@@ -9,14 +9,14 @@ MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar
OBJECT_OUTPUTS "${PrecompiledBinary}")
# Do not consider .c files
- foreach(fname ${Sources})
+ foreach(fname ${Sources})
GET_FILENAME_COMPONENT(fext ${fname} EXT)
if(fext STREQUAL ".cpp")
SET_SOURCE_FILES_PROPERTIES(${fname}
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledBinary}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\""
- OBJECT_DEPENDS "${PrecompiledBinary}")
+ OBJECT_DEPENDS "${PrecompiledBinary}")
endif(fext STREQUAL ".cpp")
- endforeach(fname)
+ endforeach(fname)
ENDIF(MSVC)
# Add precompiled header to SourcesVar
diff --git a/code/.editorconfig b/code/.editorconfig
deleted file mode 100644
index 4a194a317..000000000
--- a/code/.editorconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-# See for details
-
-[*.{h,hpp,c,cpp}]
-end_of_line = lf
-insert_final_newline = true
-trim_trailing_whitespace = true
-indent_size = 4
-indent_style = space
diff --git a/code/AssetLib/3DS/3DSConverter.cpp b/code/AssetLib/3DS/3DSConverter.cpp
index 6d3f09cb7..5718ebbc0 100644
--- a/code/AssetLib/3DS/3DSConverter.cpp
+++ b/code/AssetLib/3DS/3DSConverter.cpp
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -91,15 +91,12 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
// now iterate through all meshes and through all faces and
// find all faces that are using the default material
unsigned int cnt = 0;
- for (std::vector::iterator
- i = mScene->mMeshes.begin();
- i != mScene->mMeshes.end(); ++i) {
- for (std::vector::iterator
- a = (*i).mFaceMaterials.begin();
- a != (*i).mFaceMaterials.end(); ++a) {
+ for (auto i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) {
+ for (auto a = (*i).mFaceMaterials.begin(); a != (*i).mFaceMaterials.end(); ++a) {
// NOTE: The additional check seems to be necessary,
// some exporters seem to generate invalid data here
- if (0xcdcdcdcd == (*a)) {
+
+ if (NotSet == (*a)) {
(*a) = idx;
++cnt;
} else if ((*a) >= mScene->mMaterials.size()) {
@@ -111,7 +108,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
}
if (cnt && idx == mScene->mMaterials.size()) {
// We need to create our own default material
- D3DS::Material sMat("%%%DEFAULT");
+ Material sMat("%%%DEFAULT");
sMat.mDiffuse = aiColor3D(0.3f, 0.3f, 0.3f);
mScene->mMaterials.push_back(sMat);
@@ -121,17 +118,17 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
// ------------------------------------------------------------------------------------------------
// Check whether all indices are valid. Otherwise we'd crash before the validation step is reached
-void Discreet3DSImporter::CheckIndices(D3DS::Mesh &sMesh) {
- for (std::vector::iterator i = sMesh.mFaces.begin(); i != sMesh.mFaces.end(); ++i) {
+void Discreet3DSImporter::CheckIndices(Mesh &sMesh) {
+ for (auto i = sMesh.mFaces.begin(); i != sMesh.mFaces.end(); ++i) {
// check whether all indices are in range
for (unsigned int a = 0; a < 3; ++a) {
if ((*i).mIndices[a] >= sMesh.mPositions.size()) {
ASSIMP_LOG_WARN("3DS: Vertex index overflow)");
- (*i).mIndices[a] = (uint32_t)sMesh.mPositions.size() - 1;
+ (*i).mIndices[a] = static_cast(sMesh.mPositions.size() - 1);
}
if (!sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size()) {
ASSIMP_LOG_WARN("3DS: Texture coordinate index overflow)");
- (*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size() - 1;
+ (*i).mIndices[a] = static_cast(sMesh.mTexCoords.size() - 1);
}
}
}
@@ -139,7 +136,7 @@ void Discreet3DSImporter::CheckIndices(D3DS::Mesh &sMesh) {
// ------------------------------------------------------------------------------------------------
// Generate out unique verbose format representation
-void Discreet3DSImporter::MakeUnique(D3DS::Mesh &sMesh) {
+void Discreet3DSImporter::MakeUnique(Mesh &sMesh) {
// TODO: really necessary? I don't think. Just a waste of memory and time
// to do it now in a separate buffer.
@@ -150,7 +147,7 @@ void Discreet3DSImporter::MakeUnique(D3DS::Mesh &sMesh) {
vNew2.resize(sMesh.mFaces.size() * 3);
for (unsigned int i = 0, base = 0; i < sMesh.mFaces.size(); ++i) {
- D3DS::Face &face = sMesh.mFaces[i];
+ Face &face = sMesh.mFaces[i];
// Positions
for (unsigned int a = 0; a < 3; ++a, ++base) {
@@ -167,10 +164,9 @@ void Discreet3DSImporter::MakeUnique(D3DS::Mesh &sMesh) {
// ------------------------------------------------------------------------------------------------
// Convert a 3DS texture to texture keys in an aiMaterial
-void CopyTexture(aiMaterial &mat, D3DS::Texture &texture, aiTextureType type) {
+void CopyTexture(aiMaterial &mat, Texture &texture, aiTextureType type) {
// Setup the texture name
- aiString tex;
- tex.Set(texture.mMapName);
+ aiString tex(texture.mMapName);
mat.AddProperty(&tex, AI_MATKEY_TEXTURE(type, 0));
// Setup the texture blend factor
@@ -197,13 +193,11 @@ void CopyTexture(aiMaterial &mat, D3DS::Texture &texture, aiTextureType type) {
// ------------------------------------------------------------------------------------------------
// Convert a 3DS material to an aiMaterial
-void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
- aiMaterial &mat) {
+void Discreet3DSImporter::ConvertMaterial(Material &oldMat, aiMaterial &mat) {
// NOTE: Pass the background image to the viewer by bypassing the
// material system. This is an evil hack, never do it again!
- if (0 != mBackgroundImage.length() && bHasBG) {
- aiString tex;
- tex.Set(mBackgroundImage);
+ if (mBackgroundImage.empty() && bHasBG) {
+ aiString tex(mBackgroundImage);
mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
// Be sure this is only done for the first material
@@ -215,8 +209,7 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
oldMat.mAmbient.g += mClrAmbient.g;
oldMat.mAmbient.b += mClrAmbient.b;
- aiString name;
- name.Set(oldMat.mName);
+ aiString name(oldMat.mName);
mat.AddProperty(&name, AI_MATKEY_NAME);
// Material colors
@@ -226,10 +219,9 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
mat.AddProperty(&oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
// Phong shininess and shininess strength
- if (D3DS::Discreet3DS::Phong == oldMat.mShading ||
- D3DS::Discreet3DS::Metal == oldMat.mShading) {
+ if (Discreet3DS::Phong == oldMat.mShading || Discreet3DS::Metal == oldMat.mShading) {
if (!oldMat.mSpecularExponent || !oldMat.mShininessStrength) {
- oldMat.mShading = D3DS::Discreet3DS::Gouraud;
+ oldMat.mShading = Discreet3DS::Gouraud;
} else {
mat.AddProperty(&oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
mat.AddProperty(&oldMat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
@@ -251,40 +243,41 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
// Shading mode
aiShadingMode eShading = aiShadingMode_NoShading;
switch (oldMat.mShading) {
- case D3DS::Discreet3DS::Flat:
+ case Discreet3DS::Flat:
eShading = aiShadingMode_Flat;
break;
// I don't know what "Wire" shading should be,
// assume it is simple lambertian diffuse shading
- case D3DS::Discreet3DS::Wire: {
+ case Discreet3DS::Wire: {
// Set the wireframe flag
unsigned int iWire = 1;
mat.AddProperty((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
}
[[fallthrough]];
- case D3DS::Discreet3DS::Gouraud:
+ case Discreet3DS::Gouraud:
eShading = aiShadingMode_Gouraud;
break;
// assume cook-torrance shading for metals.
- case D3DS::Discreet3DS::Phong:
+ case Discreet3DS::Phong:
eShading = aiShadingMode_Phong;
break;
- case D3DS::Discreet3DS::Metal:
+ case Discreet3DS::Metal:
eShading = aiShadingMode_CookTorrance;
break;
// FIX to workaround a warning with GCC 4 who complained
// about a missing case Blinn: here - Blinn isn't a valid
// value in the 3DS Loader, it is just needed for ASE
- case D3DS::Discreet3DS::Blinn:
+ case Discreet3DS::Blinn:
eShading = aiShadingMode_Blinn;
break;
}
- int eShading_ = static_cast(eShading);
+
+ const int eShading_ = eShading;
mat.AddProperty(&eShading_, 1, AI_MATKEY_SHADING_MODEL);
// DIFFUSE texture
@@ -643,11 +636,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(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(pcIn->mChildren.size());
+
for (unsigned int i = 0; i < size; ++i) {
pcOut->mChildren[i] = new aiNode();
pcOut->mChildren[i]->mParent = pcOut;
@@ -709,7 +708,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
@@ -777,7 +776,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
// Convert all meshes in the scene and generate the final output scene.
void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
// Allocate enough storage for all output materials
- pcOut->mNumMaterials = (unsigned int)mScene->mMaterials.size();
+ pcOut->mNumMaterials = static_cast(mScene->mMaterials.size());
pcOut->mMaterials = new aiMaterial *[pcOut->mNumMaterials];
// ... and convert the 3DS materials to aiMaterial's
@@ -791,17 +790,17 @@ void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
ConvertMeshes(pcOut);
// Now copy all light sources to the output scene
- pcOut->mNumLights = (unsigned int)mScene->mLights.size();
+ pcOut->mNumLights = static_cast(mScene->mLights.size());
if (pcOut->mNumLights) {
pcOut->mLights = new aiLight *[pcOut->mNumLights];
- ::memcpy(pcOut->mLights, &mScene->mLights[0], sizeof(void *) * pcOut->mNumLights);
+ memcpy(pcOut->mLights, &mScene->mLights[0], sizeof(void *) * pcOut->mNumLights);
}
// Now copy all cameras to the output scene
- pcOut->mNumCameras = (unsigned int)mScene->mCameras.size();
+ pcOut->mNumCameras = static_cast(mScene->mCameras.size());
if (pcOut->mNumCameras) {
pcOut->mCameras = new aiCamera *[pcOut->mNumCameras];
- ::memcpy(pcOut->mCameras, &mScene->mCameras[0], sizeof(void *) * pcOut->mNumCameras);
+ memcpy(pcOut->mCameras, &mScene->mCameras[0], sizeof(void *) * pcOut->mNumCameras);
}
}
diff --git a/code/AssetLib/3DS/3DSExporter.cpp b/code/AssetLib/3DS/3DSExporter.cpp
index 1b335a272..443011c0d 100644
--- a/code/AssetLib/3DS/3DSExporter.cpp
+++ b/code/AssetLib/3DS/3DSExporter.cpp
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, 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
#include
#include
+#include
#include
#include
@@ -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 &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
diff --git a/code/AssetLib/3DS/3DSExporter.h b/code/AssetLib/3DS/3DSExporter.h
index 66e91e10d..27804d461 100644
--- a/code/AssetLib/3DS/3DSExporter.h
+++ b/code/AssetLib/3DS/3DSExporter.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, 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 &outfile, const aiScene* pScene);
- ~Discreet3DSExporter();
+ ~Discreet3DSExporter() = default;
private:
void WriteMeshes();
@@ -88,7 +88,6 @@ private:
using MeshesByNodeMap = std::multimap;
MeshesByNodeMap meshes;
-
};
} // Namespace Assimp
diff --git a/code/AssetLib/3DS/3DSHelper.h b/code/AssetLib/3DS/3DSHelper.h
index 2279d105c..64ddff819 100644
--- a/code/AssetLib/3DS/3DSHelper.h
+++ b/code/AssetLib/3DS/3DSHelper.h
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
-
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -365,14 +364,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 +383,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),
diff --git a/code/AssetLib/3DS/3DSLoader.cpp b/code/AssetLib/3DS/3DSLoader.cpp
index a406ea1d2..1ee0b8b28 100644
--- a/code/AssetLib/3DS/3DSLoader.cpp
+++ b/code/AssetLib/3DS/3DSLoader.cpp
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -106,7 +106,7 @@ Discreet3DSImporter::Discreet3DSImporter() :
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
- static const uint16_t token[] = { 0x4d4d, 0x3dc2 /*, 0x3daa */ };
+ static constexpr uint16_t token[] = { 0x4d4d, 0x3dc2 /*, 0x3daa */ };
return CheckMagicToken(pIOHandler, pFile, token, AI_COUNT_OF(token), 0, sizeof token[0]);
}
diff --git a/code/AssetLib/3DS/3DSLoader.h b/code/AssetLib/3DS/3DSLoader.h
index c579507e0..fab1c0950 100644
--- a/code/AssetLib/3DS/3DSLoader.h
+++ b/code/AssetLib/3DS/3DSLoader.h
@@ -1,10 +1,8 @@
-
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
-
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -57,14 +55,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct aiNode;
-namespace Assimp {
+namespace Assimp {
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;
@@ -126,7 +124,6 @@ protected:
void ParseColorChunk(aiColor3D* p_pcOut,
bool p_bAcceptPercent = true);
-
// -------------------------------------------------------------------
/** Skip a chunk in the file
*/
diff --git a/code/AssetLib/3MF/3MFTypes.h b/code/AssetLib/3MF/3MFTypes.h
index 8207b568b..b123cd7c7 100644
--- a/code/AssetLib/3MF/3MFTypes.h
+++ b/code/AssetLib/3MF/3MFTypes.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -57,6 +57,7 @@ enum class ResourceType {
RT_BaseMaterials,
RT_EmbeddedTexture2D,
RT_Texture2DGroup,
+ RT_ColorGroup,
RT_Unknown
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
@@ -117,6 +118,21 @@ public:
}
};
+class ColorGroup : public Resource {
+public:
+ std::vector mColors;
+ ColorGroup(int id) :
+ Resource(id){
+ // empty
+ }
+
+ ~ColorGroup() override = default;
+
+ ResourceType getType() const override {
+ return ResourceType::RT_ColorGroup;
+ }
+};
+
class BaseMaterials : public Resource {
public:
std::vector mMaterialIndex;
diff --git a/code/AssetLib/3MF/3MFXmlTags.h b/code/AssetLib/3MF/3MFXmlTags.h
index 333d169aa..2efa4c9ff 100644
--- a/code/AssetLib/3MF/3MFXmlTags.h
+++ b/code/AssetLib/3MF/3MFXmlTags.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -98,6 +98,11 @@ namespace XmlTag {
const char *const texture_cuurd_u = "u";
const char *const texture_cuurd_v = "v";
+ // vertex color definitions
+ const char *const colorgroup = "m:colorgroup";
+ const char *const color_item = "m:color";
+ const char *const color_vaule = "color";
+
// Meta info tags
const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
diff --git a/code/AssetLib/3MF/D3MFExporter.cpp b/code/AssetLib/3MF/D3MFExporter.cpp
index 4ba3bbf24..64b94e593 100644
--- a/code/AssetLib/3MF/D3MFExporter.cpp
+++ b/code/AssetLib/3MF/D3MFExporter.cpp
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, 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 {
diff --git a/code/AssetLib/3MF/D3MFExporter.h b/code/AssetLib/3MF/D3MFExporter.h
index 680d54f91..7830086d2 100644
--- a/code/AssetLib/3MF/D3MFExporter.h
+++ b/code/AssetLib/3MF/D3MFExporter.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
diff --git a/code/AssetLib/3MF/D3MFImporter.cpp b/code/AssetLib/3MF/D3MFImporter.cpp
index e8529064c..25ba6ef88 100644
--- a/code/AssetLib/3MF/D3MFImporter.cpp
+++ b/code/AssetLib/3MF/D3MFImporter.cpp
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -81,12 +81,17 @@ static constexpr aiImporterDesc desc = {
"3mf"
};
-bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
+bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool ) const {
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
return false;
}
- D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
- return opcPackage.validate();
+ static constexpr char ModelRef[] = "3D/3dmodel.model";
+ ZipArchiveIOSystem archive(pIOHandler, filename);
+ if (!archive.Exists(ModelRef)) {
+ return false;
+ }
+
+ return true;
}
void D3MFImporter::SetupProperties(const Importer*) {
@@ -102,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 &tex = opcPackage.GetEmbeddedTextures();
diff --git a/code/AssetLib/3MF/D3MFImporter.h b/code/AssetLib/3MF/D3MFImporter.h
index 9ae68acb0..215b8b870 100644
--- a/code/AssetLib/3MF/D3MFImporter.h
+++ b/code/AssetLib/3MF/D3MFImporter.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
diff --git a/code/AssetLib/3MF/D3MFOpcPackage.cpp b/code/AssetLib/3MF/D3MFOpcPackage.cpp
index e772d8b7e..b54e80e15 100644
--- a/code/AssetLib/3MF/D3MFOpcPackage.cpp
+++ b/code/AssetLib/3MF/D3MFOpcPackage.cpp
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -119,9 +119,9 @@ public:
static bool IsEmbeddedTexture( const std::string &filename ) {
const std::string extension = BaseImporter::GetExtension(filename);
- if (extension == "jpg" || extension == "png") {
+ if (extension == "jpg" || extension == "png" || extension == "jpeg") {
std::string::size_type pos = filename.find("thumbnail");
- if (pos == std::string::npos) {
+ if (pos != std::string::npos) {
return false;
}
return true;
diff --git a/code/AssetLib/3MF/D3MFOpcPackage.h b/code/AssetLib/3MF/D3MFOpcPackage.h
index f6803a0ef..05d93ed87 100644
--- a/code/AssetLib/3MF/D3MFOpcPackage.h
+++ b/code/AssetLib/3MF/D3MFOpcPackage.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
diff --git a/code/AssetLib/3MF/XmlSerializer.cpp b/code/AssetLib/3MF/XmlSerializer.cpp
index 5fcdc0ccc..44293800d 100644
--- a/code/AssetLib/3MF/XmlSerializer.cpp
+++ b/code/AssetLib/3MF/XmlSerializer.cpp
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, 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;
}
@@ -75,7 +75,7 @@ aiFace ReadTriangle(XmlNode &node, int &texId0, int &texId1, int &texId2) {
face.mIndices[1] = static_cast(std::atoi(node.attribute(XmlTag::v2).as_string()));
face.mIndices[2] = static_cast(std::atoi(node.attribute(XmlTag::v3).as_string()));
- texId0 = texId1 = texId2 = -1;
+ texId0 = texId1 = texId2 = IdNotSet;
XmlParser::getIntAttribute(node, XmlTag::p1, texId0);
XmlParser::getIntAttribute(node, XmlTag::p2, texId1);
XmlParser::getIntAttribute(node, XmlTag::p3, texId2);
@@ -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(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;
}
@@ -236,6 +236,8 @@ void XmlSerializer::ImportXml(aiScene *scene) {
ReadBaseMaterials(currentNode);
} else if (currentNodeName == XmlTag::meta) {
ReadMetadata(currentNode);
+ } else if (currentNodeName == XmlTag::colorgroup) {
+ ReadColorGroup(currentNode);
}
}
StoreMaterialsInScene(scene);
@@ -331,9 +333,49 @@ void XmlSerializer::ReadObject(XmlNode &node) {
if (hasPid) {
auto it = mResourcesDictionnary.find(pid);
- if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
- BaseMaterials *materials = static_cast(it->second);
- mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
+ if (hasPindex && it != mResourcesDictionnary.end()) {
+ if (it->second->getType() == ResourceType::RT_BaseMaterials) {
+ BaseMaterials *materials = static_cast(it->second);
+ mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
+ } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
+ Texture2DGroup *group = static_cast(it->second);
+ if (mesh->mTextureCoords[0] == nullptr) {
+ mesh->mNumUVComponents[0] = 2;
+ for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
+ mesh->mNumUVComponents[i] = 0;
+ }
+
+ const std::string name = ai_to_string(group->mTexId);
+ for (size_t i = 0; i < mMaterials.size(); ++i) {
+ if (name == mMaterials[i]->GetName().C_Str()) {
+ mesh->mMaterialIndex = static_cast(i);
+ }
+ }
+
+ mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
+ for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
+ mesh->mTextureCoords[0][vertex_idx] =
+ aiVector3D(group->mTex2dCoords[pindex].x, group->mTex2dCoords[pindex].y, 0.0f);
+ }
+ } else {
+ for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
+ if (mesh->mTextureCoords[0][vertex_idx].z < 0) {
+ // use default
+ mesh->mTextureCoords[0][vertex_idx] =
+ aiVector3D(group->mTex2dCoords[pindex].x, group->mTex2dCoords[pindex].y, 0.0f);
+ }
+ }
+ }
+ }else if (it->second->getType() == ResourceType::RT_ColorGroup) {
+ if (mesh->mColors[0] == nullptr) {
+ mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
+
+ ColorGroup *group = static_cast(it->second);
+ for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
+ mesh->mColors[0][vertex_idx] = group->mColors[pindex];
+ }
+ }
+ }
}
}
@@ -415,27 +457,36 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
for (XmlNode ¤tNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::triangle) {
- int pid = IdNotSet, p1 = IdNotSet;
+ int pid = IdNotSet;
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
- bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
- int texId[3];
- Texture2DGroup *group = nullptr;
- aiFace face = ReadTriangle(currentNode, texId[0], texId[1], texId[2]);
- if (hasPid && hasP1) {
+ int pindex[3];
+ aiFace face = ReadTriangle(currentNode, pindex[0], pindex[1], pindex[2]);
+ if (hasPid && (pindex[0] != IdNotSet || pindex[1] != IdNotSet || pindex[2] != IdNotSet)) {
auto it = mResourcesDictionnary.find(pid);
if (it != mResourcesDictionnary.end()) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast(it->second);
- mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
+
+ auto update_material = [&](int idx) {
+ if (pindex[idx] != IdNotSet) {
+ mesh->mMaterialIndex = baseMaterials->mMaterialIndex[pindex[idx]];
+ }
+ };
+
+ update_material(0);
+ update_material(1);
+ update_material(2);
+
} else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
+ // Load texture coordinates into mesh, when any
+ Texture2DGroup *group = static_cast(it->second); // fix bug
if (mesh->mTextureCoords[0] == nullptr) {
mesh->mNumUVComponents[0] = 2;
for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
mesh->mNumUVComponents[i] = 0;
}
- group = static_cast(it->second);
const std::string name = ai_to_string(group->mTexId);
for (size_t i = 0; i < mMaterials.size(); ++i) {
if (name == mMaterials[i]->GetName().C_Str()) {
@@ -443,21 +494,44 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
}
}
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
+ for (unsigned int vertex_index = 0; vertex_index < mesh->mNumVertices; vertex_index++) {
+ mesh->mTextureCoords[0][vertex_index].z = IdNotSet;//mark not set
+ }
}
+
+ auto update_texture = [&](int idx) {
+ if (pindex[idx] != IdNotSet) {
+ size_t vertex_index = face.mIndices[idx];
+ mesh->mTextureCoords[0][vertex_index] =
+ aiVector3D(group->mTex2dCoords[pindex[idx]].x, group->mTex2dCoords[pindex[idx]].y, 0.0f);
+ }
+ };
+
+ update_texture(0);
+ update_texture(1);
+ update_texture(2);
+
+ } else if (it->second->getType() == ResourceType::RT_ColorGroup) {
+ // Load vertex color into mesh, when any
+ ColorGroup *group = static_cast(it->second);
+ if (mesh->mColors[0] == nullptr) {
+ mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
+ }
+
+ auto update_color = [&](int idx) {
+ if (pindex[idx] != IdNotSet) {
+ size_t vertex_index = face.mIndices[idx];
+ mesh->mColors[0][vertex_index] = group->mColors[pindex[idx]];
+ }
+ };
+
+ update_color(0);
+ update_color(1);
+ update_color(2);
}
}
}
- // Load texture coordinates into mesh, when any
- if (group != nullptr) {
- size_t i0 = face.mIndices[0];
- size_t i1 = face.mIndices[1];
- size_t i2 = face.mIndices[2];
- mesh->mTextureCoords[0][i0] = aiVector3D(group->mTex2dCoords[texId[0]].x, group->mTex2dCoords[texId[0]].y, 0.0f);
- mesh->mTextureCoords[0][i1] = aiVector3D(group->mTex2dCoords[texId[1]].x, group->mTex2dCoords[texId[1]].y, 0.0f);
- mesh->mTextureCoords[0][i2] = aiVector3D(group->mTex2dCoords[texId[2]].x, group->mTex2dCoords[texId[2]].y, 0.0f);
- }
-
faces.push_back(face);
}
}
@@ -598,6 +672,38 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater
return material;
}
+void XmlSerializer::ReadColor(XmlNode &node, ColorGroup *colorGroup) {
+ if (node.empty() || nullptr == colorGroup) {
+ return;
+ }
+
+ for (XmlNode currentNode : node.children()) {
+ const std::string currentName = currentNode.name();
+ if (currentName == XmlTag::color_item) {
+ const char *color = currentNode.attribute(XmlTag::color_vaule).as_string();
+ aiColor4D color_value;
+ if (parseColor(color, color_value)) {
+ colorGroup->mColors.push_back(color_value);
+ }
+ }
+ }
+}
+
+void XmlSerializer::ReadColorGroup(XmlNode &node) {
+ if (node.empty()) {
+ return;
+ }
+
+ int id = IdNotSet;
+ if (!XmlParser::getIntAttribute(node, XmlTag::id, id)) {
+ return;
+ }
+
+ ColorGroup *group = new ColorGroup(id);
+ ReadColor(node, group);
+ mResourcesDictionnary.insert(std::make_pair(id, group));
+}
+
void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
if (nullptr == scene) {
return;
diff --git a/code/AssetLib/3MF/XmlSerializer.h b/code/AssetLib/3MF/XmlSerializer.h
index 6cf6a70a9..4072a5df5 100644
--- a/code/AssetLib/3MF/XmlSerializer.h
+++ b/code/AssetLib/3MF/XmlSerializer.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -57,10 +57,11 @@ class D3MFOpcPackage;
class Object;
class Texture2DGroup;
class EmbeddedTexture;
+class ColorGroup;
-class XmlSerializer {
+class XmlSerializer final {
public:
- XmlSerializer(XmlParser *xmlParser);
+ XmlSerializer(XmlParser &xmlParser);
~XmlSerializer();
void ImportXml(aiScene *scene);
@@ -78,6 +79,8 @@ private:
void ReadTextureGroup(XmlNode &node);
aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId);
void StoreMaterialsInScene(aiScene *scene);
+ void ReadColorGroup(XmlNode &node);
+ void ReadColor(XmlNode &node, ColorGroup *colorGroup);
private:
struct MetaEntry {
@@ -89,7 +92,7 @@ private:
std::vector mMaterials;
std::map mResourcesDictionnary;
unsigned int mMeshCount;
- XmlParser *mXmlParser;
+ XmlParser &mXmlParser;
};
} // namespace D3MF
diff --git a/code/AssetLib/AC/ACLoader.cpp b/code/AssetLib/AC/ACLoader.cpp
index 1bb77c441..f9ef505c7 100644
--- a/code/AssetLib/AC/ACLoader.cpp
+++ b/code/AssetLib/AC/ACLoader.cpp
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -77,8 +77,8 @@ static constexpr aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// skip to the next token
-inline const char *AcSkipToNextToken(const char *buffer) {
- if (!SkipSpaces(&buffer)) {
+inline const char *AcSkipToNextToken(const char *buffer, const char *end) {
+ if (!SkipSpaces(&buffer, end)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL");
}
return buffer;
@@ -86,13 +86,13 @@ inline const char *AcSkipToNextToken(const char *buffer) {
// ------------------------------------------------------------------------------------------------
// read a string (may be enclosed in double quotation marks). buffer must point to "
-inline const char *AcGetString(const char *buffer, std::string &out) {
+inline const char *AcGetString(const char *buffer, const char *end, std::string &out) {
if (*buffer == '\0') {
throw DeadlyImportError("AC3D: Unexpected EOF in string");
}
++buffer;
const char *sz = buffer;
- while ('\"' != *buffer) {
+ while ('\"' != *buffer && buffer != end) {
if (IsLineEnd(*buffer)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string");
out = "ERROR";
@@ -112,8 +112,8 @@ inline const char *AcGetString(const char *buffer, std::string &out) {
// ------------------------------------------------------------------------------------------------
// read 1 to n floats prefixed with an optional predefined identifier
template
-inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name, size_t name_length, size_t num, T *out) {
- buffer = AcSkipToNextToken(buffer);
+inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *end, const char *name, size_t name_length, size_t num, T *out) {
+ buffer = AcSkipToNextToken(buffer, end);
if (0 != name_length) {
if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) {
ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected.");
@@ -122,7 +122,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name
buffer += name_length + 1;
}
for (unsigned int _i = 0; _i < num; ++_i) {
- buffer = AcSkipToNextToken(buffer);
+ buffer = AcSkipToNextToken(buffer, end);
buffer = fast_atoreal_move(buffer, ((float *)out)[_i]);
}
@@ -132,7 +132,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
AC3DImporter::AC3DImporter() :
- buffer(),
+ mBuffer(),
configSplitBFCull(),
configEvalSubdivision(),
mNumMeshes(),
@@ -144,14 +144,10 @@ 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 {
- static const uint32_t tokens[] = { AI_MAKE_MAGIC("AC3D") };
+ static constexpr uint32_t tokens[] = { AI_MAKE_MAGIC("AC3D") };
return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}
@@ -164,17 +160,18 @@ const aiImporterDesc *AC3DImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
// Get a pointer to the next line from the file
bool AC3DImporter::GetNextLine() {
- SkipLine(&buffer);
- return SkipSpaces(&buffer);
+ SkipLine(&mBuffer.data, mBuffer.end);
+ return SkipSpaces(&mBuffer.data, mBuffer.end);
}
// ------------------------------------------------------------------------------------------------
// Parse an object section in an AC file
-void AC3DImporter::LoadObjectSection(std::vector
" << endstr;
PopTag();
@@ -1085,8 +1151,9 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
mOutput << startstr << "" << endstr;
PushTag();
mOutput << startstr << "" << endstr;
- if (mesh->HasNormals())
+ if (mesh->HasNormals()) {
mOutput << startstr << "" << endstr;
+ }
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (mesh->HasTextureCoords(static_cast(a)))
mOutput << startstr << "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 << "" << 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 << "" << 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 << "mNodeName.data + std::string("_matrix-sampler")) << "\" target=\"" << XMLIDEncode(nodeAnim->mNodeName.data) << "/matrix\"/>" << endstr;
+ mOutput << startstr
+ << "mNodeName.data + std::string("_matrix-sampler"))
+ << "\" target=\""
+ << XMLIDEncode(nodeAnim->mNodeName.data)
+ << "/matrix\"/>"
+ << endstr;
}
}
PopTag();
mOutput << startstr << "" << endstr;
}
+
// ------------------------------------------------------------------------------------------------
void ColladaExporter::WriteAnimationsLibrary() {
- if (mScene->mNumAnimations > 0) {
- mOutput << startstr << "" << endstr;
- PushTag();
-
- // start recursive write at the root node
- for (size_t a = 0; a < mScene->mNumAnimations; ++a)
- WriteAnimationLibrary(a);
-
- PopTag();
- mOutput << startstr << "" << endstr;
- }
-}
-// ------------------------------------------------------------------------------------------------
-// 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;
-}
-
-// ------------------------------------------------------------------------------------------------
-// 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;
+ if (mScene->mNumAnimations == 0) {
+ return;
}
- 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;
- }
- }
- }
+ mOutput << startstr << "" << endstr;
+ PushTag();
+
+ // start recursive write at the root node
+ for (size_t a = 0; a < mScene->mNumAnimations; ++a) {
+ WriteAnimationLibrary(a);
}
- return nullptr;
-}
-
-const aiNode *findSkeletonRootNode(const aiScene *scene, const aiMesh *mesh) {
- std::set 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 << "" << 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 << "";
mOutput << startstr << "";
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 << "" << 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
diff --git a/code/AssetLib/Collada/ColladaExporter.h b/code/AssetLib/Collada/ColladaExporter.h
index e372a5c5c..26fd22f6d 100644
--- a/code/AssetLib/Collada/ColladaExporter.h
+++ b/code/AssetLib/Collada/ColladaExporter.h
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, 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
diff --git a/code/AssetLib/Collada/ColladaHelper.cpp b/code/AssetLib/Collada/ColladaHelper.cpp
index 0fb172fbb..562477796 100644
--- a/code/AssetLib/Collada/ColladaHelper.cpp
+++ b/code/AssetLib/Collada/ColladaHelper.cpp
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
diff --git a/code/AssetLib/Collada/ColladaHelper.h b/code/AssetLib/Collada/ColladaHelper.h
index c5b6a2d13..869703432 100644
--- a/code/AssetLib/Collada/ColladaHelper.h
+++ b/code/AssetLib/Collada/ColladaHelper.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
diff --git a/code/AssetLib/Collada/ColladaLoader.cpp b/code/AssetLib/Collada/ColladaLoader.cpp
index 41e529de0..e0c0648ad 100644
--- a/code/AssetLib/Collada/ColladaLoader.cpp
+++ b/code/AssetLib/Collada/ColladaLoader.cpp
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -89,6 +89,14 @@ inline void AddNodeMetaData(aiNode *node, const std::string &key, const T &value
node->mMetaData->Add(key, value);
}
+// ------------------------------------------------------------------------------------------------
+// Reads a float value from an accessor and its data array.
+static ai_real ReadFloat(const Accessor &pAccessor, const Data &pData, size_t pIndex, size_t pOffset) {
+ size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
+ ai_assert(pos < pData.mValues.size());
+ return pData.mValues[pos];
+}
+
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
ColladaLoader::ColladaLoader() :
@@ -152,7 +160,7 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
throw DeadlyImportError("Collada: File came out empty. Something is wrong here.");
}
- // reserve some storage to avoid unnecessary reallocs
+ // reserve some storage to avoid unnecessary reallocates
newMats.reserve(parser.mMaterialLibrary.size() * 2u);
mMeshes.reserve(parser.mMeshLibrary.size() * 2u);
@@ -176,7 +184,7 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
0, 0, parser.mUnitSize, 0,
0, 0, 0, 1);
}
-
+
if (!ignoreUpDirection) {
// Convert to Y_UP, if different orientation
if (parser.mUpDirection == ColladaParser::UP_X) {
@@ -224,7 +232,7 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
// Recursively constructs a scene node for the given parser node and returns it.
aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collada::Node *pNode) {
// create a node for it
- aiNode *node = new aiNode();
+ auto *node = new aiNode();
// find a name for the new node. It's more complicated than you might think
node->mName.Set(FindNameForNode(pNode));
@@ -247,7 +255,9 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
// add children. first the *real* ones
node->mNumChildren = static_cast(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]);
@@ -270,24 +280,24 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
// ------------------------------------------------------------------------------------------------
// Resolve node instances
void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Node *pNode,
- std::vector &resolved) {
+ std::vector &resolved) const {
// reserve enough storage
resolved.reserve(pNode->mNodeInstances.size());
// ... and iterate through all nodes to be instanced as children of pNode
- for (const auto &nodeInst : pNode->mNodeInstances) {
+ for (const auto &[mNode] : pNode->mNodeInstances) {
// find the corresponding node in the library
- const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find(nodeInst.mNode);
+ const auto itt = pParser.mNodeLibrary.find(mNode);
const Node *nd = itt == pParser.mNodeLibrary.end() ? nullptr : (*itt).second;
// FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632
// need to check for both name and ID to catch all. To avoid breaking valid files,
// the workaround is only enabled when the first attempt to resolve the node has failed.
if (nullptr == nd) {
- nd = FindNode(pParser.mRootNode, nodeInst.mNode);
+ nd = FindNode(pParser.mRootNode, mNode);
}
if (nullptr == nd) {
- ASSIMP_LOG_ERROR("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode);
+ ASSIMP_LOG_ERROR("Collada: Unable to resolve reference to instanced node ", mNode);
} else {
// attach this node to the list of children
resolved.push_back(nd);
@@ -297,8 +307,8 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Nod
// ------------------------------------------------------------------------------------------------
// Resolve UV channels
-void ColladaLoader::ApplyVertexToEffectSemanticMapping(Sampler &sampler, const SemanticMappingTable &table) {
- SemanticMappingTable::InputSemanticMap::const_iterator it = table.mMap.find(sampler.mUVChannel);
+static void ApplyVertexToEffectSemanticMapping(Sampler &sampler, const SemanticMappingTable &table) {
+ const auto it = table.mMap.find(sampler.mUVChannel);
if (it == table.mMap.end()) {
return;
}
@@ -315,7 +325,7 @@ void ColladaLoader::ApplyVertexToEffectSemanticMapping(Sampler &sampler, const S
void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
for (const LightInstance &lid : pNode->mLights) {
// find the referred light
- ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find(lid.mLight);
+ auto srcLightIt = pParser.mLightLibrary.find(lid.mLight);
if (srcLightIt == pParser.mLightLibrary.end()) {
ASSIMP_LOG_WARN("Collada: Unable to find light for ID \"", lid.mLight, "\". Skipping.");
continue;
@@ -323,7 +333,7 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node
const Collada::Light *srcLight = &srcLightIt->second;
// now fill our ai data structure
- aiLight *out = new aiLight();
+ auto out = new aiLight();
out->mName = pTarget->mName;
out->mType = (aiLightSourceType)srcLight->mType;
@@ -380,7 +390,7 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node
void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
for (const CameraInstance &cid : pNode->mCameras) {
// find the referred light
- ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find(cid.mCamera);
+ auto srcCameraIt = pParser.mCameraLibrary.find(cid.mCamera);
if (srcCameraIt == pParser.mCameraLibrary.end()) {
ASSIMP_LOG_WARN("Collada: Unable to find camera for ID \"", cid.mCamera, "\". Skipping.");
continue;
@@ -393,7 +403,7 @@ void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node
}
// now fill our ai data structure
- aiCamera *out = new aiCamera();
+ auto *out = new aiCamera();
out->mName = pTarget->mName;
// collada cameras point in -Z by default, rest is specified in node transform
@@ -443,10 +453,10 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
const Controller *srcController = nullptr;
// find the referred mesh
- ColladaParser::MeshLibrary::const_iterator srcMeshIt = pParser.mMeshLibrary.find(mid.mMeshOrController);
+ auto srcMeshIt = pParser.mMeshLibrary.find(mid.mMeshOrController);
if (srcMeshIt == pParser.mMeshLibrary.end()) {
// if not found in the mesh-library, it might also be a controller referring to a mesh
- ColladaParser::ControllerLibrary::const_iterator srcContrIt = pParser.mControllerLibrary.find(mid.mMeshOrController);
+ auto srcContrIt = pParser.mControllerLibrary.find(mid.mMeshOrController);
if (srcContrIt != pParser.mControllerLibrary.end()) {
srcController = &srcContrIt->second;
srcMeshIt = pParser.mMeshLibrary.find(srcController->mMeshId);
@@ -460,7 +470,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
continue;
}
} else {
- // ID found in the mesh library -> direct reference to an unskinned mesh
+ // ID found in the mesh library -> direct reference to a not skinned mesh
srcMesh = srcMeshIt->second;
}
@@ -474,7 +484,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
// find material assigned to this submesh
std::string meshMaterial;
- std::map::const_iterator meshMatIt = mid.mMaterials.find(submesh.mMaterial);
+ auto meshMatIt = mid.mMaterials.find(submesh.mMaterial);
const Collada::SemanticMappingTable *table = nullptr;
if (meshMatIt != mid.mMaterials.end()) {
@@ -490,7 +500,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
// OK ... here the *real* fun starts ... we have the vertex-input-to-effect-semantic-table
// given. The only mapping stuff which we do actually support is the UV channel.
- std::map::const_iterator matIt = mMaterialIndexByName.find(meshMaterial);
+ auto matIt = mMaterialIndexByName.find(meshMaterial);
unsigned int matIdx = 0;
if (matIt != mMaterialIndexByName.end()) {
matIdx = static_cast(matIt->second);
@@ -513,7 +523,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
ColladaMeshIndex index(mid.mMeshOrController, sm, meshMaterial);
// if we already have the mesh at the library, just add its index to the node's array
- std::map::const_iterator dstMeshIt = mMeshIndexByID.find(index);
+ auto dstMeshIt = mMeshIndexByID.find(index);
if (dstMeshIt != mMeshIndexByID.end()) {
newMeshRefs.push_back(dstMeshIt->second);
} else {
@@ -528,7 +538,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
faceStart += submesh.mNumFaces;
// assign the material index
- std::map::const_iterator subMatIt = mMaterialIndexByName.find(submesh.mMaterial);
+ auto subMatIt = mMaterialIndexByName.find(submesh.mMaterial);
if (subMatIt != mMaterialIndexByName.end()) {
dstMesh->mMaterialIndex = static_cast(subMatIt->second);
} else {
@@ -616,23 +626,21 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
std::copy(pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() + pStartVertex + numVertices, dstMesh->mTangents);
}
- // bitangents, if given.
+ // bi-tangents, if given.
if (pSrcMesh->mBitangents.size() >= pStartVertex + numVertices) {
dstMesh->mBitangents = new aiVector3D[numVertices];
std::copy(pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() + pStartVertex + numVertices, dstMesh->mBitangents);
}
// same for 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];
}
}
@@ -664,7 +672,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
std::vector targetWeights;
Collada::MorphMethod method = Normalized;
- for (std::map::const_iterator it = pParser.mControllerLibrary.begin();
+ for (auto it = pParser.mControllerLibrary.begin();
it != pParser.mControllerLibrary.end(); ++it) {
const Controller &c = it->second;
const Collada::Mesh *baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId);
@@ -754,7 +762,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
std::vector weightStartPerVertex;
weightStartPerVertex.resize(pSrcController->mWeightCounts.size(), pSrcController->mWeights.end());
- IndexPairVector::const_iterator pit = pSrcController->mWeights.begin();
+ auto pit = pSrcController->mWeights.begin();
for (size_t a = 0; a < pSrcController->mWeightCounts.size(); ++a) {
weightStartPerVertex[a] = pit;
pit += pSrcController->mWeightCounts[a];
@@ -766,7 +774,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
// the controller assigns the vertex weights
size_t orgIndex = pSrcMesh->mFacePosIndices[a];
// find the vertex weights for this vertex
- IndexPairVector::const_iterator iit = weightStartPerVertex[orgIndex];
+ auto iit = weightStartPerVertex[orgIndex];
size_t pairCount = pSrcController->mWeightCounts[orgIndex];
for (size_t b = 0; b < pairCount; ++b, ++iit) {
@@ -807,7 +815,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
}
// create bone with its weights
- aiBone *bone = new aiBone;
+ auto bone = new aiBone;
bone->mName = ReadString(jointNamesAcc, jointNames, a);
bone->mOffsetMatrix.a1 = ReadFloat(jointMatrixAcc, jointMatrices, a, 0);
bone->mOffsetMatrix.a2 = ReadFloat(jointMatrixAcc, jointMatrices, a, 1);
@@ -973,7 +981,7 @@ void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParse
// if there are other animations which fit the template anim, combine all channels into a single anim
if (!collectedAnimIndices.empty()) {
- aiAnimation *combinedAnim = new aiAnimation();
+ auto *combinedAnim = new aiAnimation();
combinedAnim->mName = aiString(std::string("combinedAnim_") + char('0' + a));
combinedAnim->mDuration = templateAnim->mDuration;
combinedAnim->mTicksPerSecond = templateAnim->mTicksPerSecond;
@@ -1040,7 +1048,7 @@ struct MorphTimeValues {
};
void insertMorphTimeValue(std::vector &values, float time, float weight, unsigned int value) {
- MorphTimeValues::key k;
+ MorphTimeValues::key k{};
k.mValue = value;
k.mWeight = weight;
if (values.empty() || time < values[0].mTime) {
@@ -1077,6 +1085,7 @@ static float getWeightAtKey(const std::vector &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;
@@ -1105,7 +1114,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// now check all channels if they affect the current node
std::string targetID, subElement;
- for (std::vector::const_iterator cit = pSrcAnim->mChannels.begin();
+ for (auto cit = pSrcAnim->mChannels.begin();
cit != pSrcAnim->mChannels.end(); ++cit) {
const AnimationChannel &srcChannel = *cit;
ChannelEntry entry;
@@ -1348,7 +1357,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// build an animation channel for the given node out of these trafo keys
if (!resultTrafos.empty()) {
- aiNodeAnim *dstAnim = new aiNodeAnim;
+ auto *dstAnim = new aiNodeAnim;
dstAnim->mNodeName = nodeName;
dstAnim->mNumPositionKeys = static_cast(resultTrafos.size());
dstAnim->mNumRotationKeys = static_cast(resultTrafos.size());
@@ -1390,7 +1399,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// or 2) one channel with morph target count arrays
// assume first
- aiMeshMorphAnim *morphAnim = new aiMeshMorphAnim;
+ auto *morphAnim = new aiMeshMorphAnim;
morphAnim->mName.Set(nodeName);
std::vector morphTimeValues;
@@ -1433,7 +1442,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
}
if (!anims.empty() || !morphAnims.empty()) {
- aiAnimation *anim = new aiAnimation;
+ auto anim = new aiAnimation;
anim->mName.Set(pName);
anim->mNumChannels = static_cast(anims.size());
if (anim->mNumChannels > 0) {
@@ -1513,7 +1522,7 @@ void ColladaLoader::AddTexture(aiMaterial &mat,
map = sampler.mUVId;
} else {
map = -1;
- for (std::string::const_iterator it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
+ for (auto it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
if (IsNumeric(*it)) {
map = strtoul10(&(*it));
break;
@@ -1531,7 +1540,7 @@ void ColladaLoader::AddTexture(aiMaterial &mat,
// Fills materials from the collada material definitions
void ColladaLoader::FillMaterials(const ColladaParser &pParser, aiScene * /*pScene*/) {
for (auto &elem : newMats) {
- aiMaterial &mat = (aiMaterial &)*elem.second;
+ auto &mat = (aiMaterial &)*elem.second;
Collada::Effect &effect = *elem.first;
// resolve shading mode
@@ -1641,17 +1650,17 @@ void ColladaLoader::FillMaterials(const ColladaParser &pParser, aiScene * /*pSce
void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/) {
newMats.reserve(pParser.mMaterialLibrary.size());
- for (ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin();
+ for (auto matIt = pParser.mMaterialLibrary.begin();
matIt != pParser.mMaterialLibrary.end(); ++matIt) {
const Material &material = matIt->second;
// a material is only a reference to an effect
- ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find(material.mEffect);
+ auto effIt = pParser.mEffectLibrary.find(material.mEffect);
if (effIt == pParser.mEffectLibrary.end())
continue;
Effect &effect = effIt->second;
// create material
- aiMaterial *mat = new aiMaterial;
+ auto *mat = new aiMaterial;
aiString name(material.mName.empty() ? matIt->first : material.mName);
mat->AddProperty(&name, AI_MATKEY_NAME);
@@ -1674,7 +1683,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
std::string name = pName;
while (true) {
// the given string is a param entry. Find it
- Effect::ParamLibrary::const_iterator it = pEffect.mParams.find(name);
+ auto it = pEffect.mParams.find(name);
// if not found, we're at the end of the recursion. The resulting string should be the image ID
if (it == pEffect.mParams.end())
break;
@@ -1684,7 +1693,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
}
// find the image referred by this name in the image library of the scene
- ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find(name);
+ auto imIt = pParser.mImageLibrary.find(name);
if (imIt == pParser.mImageLibrary.end()) {
ASSIMP_LOG_WARN("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\".");
@@ -1696,7 +1705,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
// if this is an embedded texture image setup an aiTexture for it
if (!imIt->second.mImageData.empty()) {
- aiTexture *tex = new aiTexture();
+ auto *tex = new aiTexture();
// Store embedded texture name reference
tex->mFilename.Set(imIt->second.mFileName.c_str());
@@ -1728,14 +1737,6 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
return result;
}
-// ------------------------------------------------------------------------------------------------
-// Reads a float value from an accessor and its data array.
-ai_real ColladaLoader::ReadFloat(const Accessor &pAccessor, const Data &pData, size_t pIndex, size_t pOffset) const {
- size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
- ai_assert(pos < pData.mValues.size());
- return pData.mValues[pos];
-}
-
// ------------------------------------------------------------------------------------------------
// Reads a string value from an accessor and its data array.
const std::string &ColladaLoader::ReadString(const Accessor &pAccessor, const Data &pData, size_t pIndex) const {
diff --git a/code/AssetLib/Collada/ColladaLoader.h b/code/AssetLib/Collada/ColladaLoader.h
index 3cea7f531..efeb4f1fa 100644
--- a/code/AssetLib/Collada/ColladaLoader.h
+++ b/code/AssetLib/Collada/ColladaLoader.h
@@ -4,8 +4,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, 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 &resolved);
+ std::vector &resolved) const;
- /** 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
@@ -163,10 +166,6 @@ protected:
/** Fill materials from the collada material definitions */
void FillMaterials(const ColladaParser &pParser, aiScene *pScene);
- /** Resolve UV channel mappings*/
- void ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler,
- const Collada::SemanticMappingTable &table);
-
/** Add a texture and all of its sampling properties to a material*/
void AddTexture(aiMaterial &mat, const ColladaParser &pParser,
const Collada::Effect &effect,
@@ -177,22 +176,13 @@ protected:
aiString FindFilenameForEffectTexture(const ColladaParser &pParser,
const Collada::Effect &pEffect, const std::string &pName);
- /** Reads a float value from an accessor and its data array.
- * @param pAccessor The accessor to use for reading
- * @param pData The data array to read from
- * @param pIndex The index of the element to retrieve
- * @param pOffset Offset into the element, for multipart elements such as vectors or matrices
- * @return the specified value
- */
- ai_real ReadFloat(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex, size_t pOffset) const;
-
/** Reads a string value from an accessor and its data array.
* @param pAccessor The accessor to use for reading
* @param pData The data array to read from
* @param pIndex The index of the element to retrieve
* @return the specified value
*/
- const std::string &ReadString(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex) const;
+ [[nodiscard]] const std::string &ReadString(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex) const;
/** Recursively collects all nodes into the given array */
void CollectNodes(const aiNode *pNode, std::vector &poNodes) const;
@@ -205,7 +195,7 @@ protected:
/** Finds a proper name for a node derived from the collada-node's properties */
std::string FindNameForNode(const Collada::Node *pNode);
-protected:
+private:
/** Filename, for a verbose error message */
std::string mFileName;
diff --git a/code/AssetLib/Collada/ColladaParser.cpp b/code/AssetLib/Collada/ColladaParser.cpp
index 42a8d6052..a9d965313 100644
--- a/code/AssetLib/Collada/ColladaParser.cpp
+++ b/code/AssetLib/Collada/ColladaParser.cpp
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -61,6 +61,7 @@ using namespace Assimp;
using namespace Assimp::Collada;
using namespace Assimp::Formatter;
+// ------------------------------------------------------------------------------------------------
static void ReportWarning(const char *msg, ...) {
ai_assert(nullptr != msg);
@@ -75,6 +76,7 @@ static void ReportWarning(const char *msg, ...) {
ASSIMP_LOG_WARN("Validation warning: ", std::string(szBuffer, iLen));
}
+// ------------------------------------------------------------------------------------------------
static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) {
for (size_t i = 0; i < key_renaming.size(); ++i) {
if (key_renaming[i].first == collada_key) {
@@ -87,6 +89,7 @@ static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVecto
return false;
}
+// ------------------------------------------------------------------------------------------------
static void readUrlAttribute(XmlNode &node, std::string &url) {
url.clear();
if (!XmlParser::getStdStrAttribute(node, "url", url)) {
@@ -98,23 +101,319 @@ static void readUrlAttribute(XmlNode &node, std::string &url) {
url = url.c_str() + 1;
}
+// ------------------------------------------------------------------------------------------------
+// Reads a node transformation entry of the given type and adds it to the given node's transformation list.
+static void ReadNodeTransformation(XmlNode &node, Node *pNode, TransformType pType) {
+ if (node.empty()) {
+ return;
+ }
+
+ std::string tagName = node.name();
+
+ Transform tf;
+ tf.mType = pType;
+
+ // read SID
+ if (XmlParser::hasAttribute(node, "sid")) {
+ XmlParser::getStdStrAttribute(node, "sid", tf.mID);
+ }
+
+ // how many parameters to read per transformation type
+ static constexpr unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
+ std::string value;
+ XmlParser::getValueAsString(node, value);
+ const char *content = value.c_str();
+ const char *end = value.c_str() + value.size();
+ // read as many parameters and store in the transformation
+ for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
+ // skip whitespace before the number
+ SkipSpacesAndLineEnd(&content, end);
+ // read a number
+ content = fast_atoreal_move(content, tf.f[a]);
+ }
+
+ // place the transformation at the queue of the node
+ pNode->mTransforms.push_back(tf);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Reads a single string metadata item
+static void ReadMetaDataItem(XmlNode &node, ColladaParser::StringMetaData &metadata) {
+ const MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase();
+ const std::string name = node.name();
+ if (name.empty()) {
+ return;
+ }
+
+ std::string v;
+ if (!XmlParser::getValueAsString(node, v)) {
+ return;
+ }
+
+ v = ai_trim(v);
+ aiString aistr;
+ aistr.Set(v);
+
+ std::string camel_key_str(name);
+ ToCamelCase(camel_key_str);
+
+ size_t found_index;
+ if (FindCommonKey(camel_key_str, key_renaming, found_index)) {
+ metadata.emplace(key_renaming[found_index].second, aistr);
+ } else {
+ metadata.emplace(camel_key_str, aistr);
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+// Reads an animation sampler into the given anim channel
+static void ReadAnimationSampler(const XmlNode &node, AnimationChannel &pChannel) {
+ for (XmlNode ¤tNode : node.children()) {
+ const std::string ¤tName = currentNode.name();
+ if (currentName == "input") {
+ if (XmlParser::hasAttribute(currentNode, "semantic")) {
+ std::string semantic, sourceAttr;
+ XmlParser::getStdStrAttribute(currentNode, "semantic", semantic);
+ if (XmlParser::hasAttribute(currentNode, "source")) {
+ XmlParser::getStdStrAttribute(currentNode, "source", sourceAttr);
+ const char *source = sourceAttr.c_str();
+ if (source[0] != '#') {
+ throw DeadlyImportError("Unsupported URL format");
+ }
+ source++;
+
+ if (semantic == "INPUT") {
+ pChannel.mSourceTimes = source;
+ } else if (semantic == "OUTPUT") {
+ pChannel.mSourceValues = source;
+ } else if (semantic == "IN_TANGENT") {
+ pChannel.mInTanValues = source;
+ } else if (semantic == "OUT_TANGENT") {
+ pChannel.mOutTanValues = source;
+ } else if (semantic == "INTERPOLATION") {
+ pChannel.mInterpolationValues = source;
+ }
+ }
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+// Reads the joint definitions for the given controller
+static void ReadControllerJoints(const XmlNode &node, Controller &pController) {
+ for (XmlNode ¤tNode : node.children()) {
+ const std::string ¤tName = currentNode.name();
+ if (currentName == "input") {
+ const char *attrSemantic = currentNode.attribute("semantic").as_string();
+ const char *attrSource = currentNode.attribute("source").as_string();
+ if (attrSource[0] != '#') {
+ throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of data element");
+ }
+ ++attrSource;
+ // parse source URL to corresponding source
+ if (strcmp(attrSemantic, "JOINT") == 0) {
+ pController.mJointNameSource = attrSource;
+ } else if (strcmp(attrSemantic, "INV_BIND_MATRIX") == 0) {
+ pController.mJointOffsetMatrixSource = attrSource;
+ } else {
+ throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in data element");
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+static void ReadControllerWeightsInput(const XmlNode ¤tNode, Controller &pController) {
+ InputChannel channel;
+
+ const char *attrSemantic = currentNode.attribute("semantic").as_string();
+ const char *attrSource = currentNode.attribute("source").as_string();
+ channel.mOffset = currentNode.attribute("offset").as_int();
+
+ // local URLS always start with a '#'. We don't support global URLs
+ if (attrSource[0] != '#') {
+ throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of data element");
+ }
+ channel.mAccessor = attrSource + 1;
+
+ // parse source URL to corresponding source
+ if (strcmp(attrSemantic, "JOINT") == 0) {
+ pController.mWeightInputJoints = channel;
+ } else if (strcmp(attrSemantic, "WEIGHT") == 0) {
+ pController.mWeightInputWeights = channel;
+ } else {
+ throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in data element");
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+static void ReadControllerWeightsVCount(const XmlNode ¤tNode, Controller &pController) {
+ const std::string stdText = currentNode.text().as_string();
+ const char *text = stdText.c_str();
+ const char *end = text + stdText.size();
+ size_t numWeights = 0;
+ for (auto it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
+ if (*text == 0) {
+ throw DeadlyImportError("Out of data while reading ");
+ }
+
+ *it = strtoul10(text, &text);
+ numWeights += *it;
+ SkipSpacesAndLineEnd(&text, end);
+ }
+ // reserve weight count
+ pController.mWeights.resize(numWeights);
+}
+
+// ------------------------------------------------------------------------------------------------
+static void ReadControllerWeightsJoint2verts(XmlNode ¤tNode, Controller &pController) {
+ // read JointIndex - WeightIndex pairs
+ std::string stdText;
+ XmlParser::getValueAsString(currentNode, stdText);
+ const char *text = stdText.c_str();
+ const char *end = text + stdText.size();
+ for (auto it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) {
+ if (text == nullptr) {
+ throw DeadlyImportError("Out of data while reading ");
+ }
+ SkipSpacesAndLineEnd(&text, end);
+ it->first = strtoul10(text, &text);
+ SkipSpacesAndLineEnd(&text, end);
+ if (*text == 0) {
+ throw DeadlyImportError("Out of data while reading ");
+ }
+ it->second = strtoul10(text, &text);
+ SkipSpacesAndLineEnd(&text, end);
+ }
+
+}
+
+// ------------------------------------------------------------------------------------------------
+// Reads the joint weights for the given controller
+static void ReadControllerWeights(XmlNode &node, Controller &pController) {
+ // Read vertex count from attributes and resize the array accordingly
+ int vertexCount = 0;
+ XmlParser::getIntAttribute(node, "count", vertexCount);
+ pController.mWeightCounts.resize(vertexCount);
+
+ for (XmlNode ¤tNode : node.children()) {
+ const std::string ¤tName = currentNode.name();
+ if (currentName == "input") {
+ ReadControllerWeightsInput(currentNode, pController);
+ } else if (currentName == "vcount" && vertexCount > 0) {
+ ReadControllerWeightsVCount(currentNode, pController);
+ } else if (currentName == "v" && vertexCount > 0) {
+ ReadControllerWeightsJoint2verts(currentNode, pController);
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+// Reads a material entry into the given material
+static void ReadMaterial(const XmlNode &node, Material &pMaterial) {
+ for (XmlNode ¤tNode : node.children()) {
+ const std::string ¤tName = currentNode.name();
+ if (currentName == "instance_effect") {
+ std::string url;
+ readUrlAttribute(currentNode, url);
+ pMaterial.mEffect = url;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+// Reads a light entry into the given light
+static void ReadLight(XmlNode &node, Light &pLight) {
+ XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
+ XmlNode currentNode;
+ // TODO: Check the current technique and skip over unsupported extra techniques
+
+ while (xmlIt.getNext(currentNode)) {
+ const std::string ¤tName = currentNode.name();
+ if (currentName == "spot") {
+ pLight.mType = aiLightSource_SPOT;
+ } else if (currentName == "ambient") {
+ pLight.mType = aiLightSource_AMBIENT;
+ } else if (currentName == "directional") {
+ pLight.mType = aiLightSource_DIRECTIONAL;
+ } else if (currentName == "point") {
+ pLight.mType = aiLightSource_POINT;
+ } else if (currentName == "color") {
+ // text content contains 3 floats
+ std::string v;
+ XmlParser::getValueAsString(currentNode, v);
+ const char *content = v.c_str();
+ const char *end = content + v.size();
+
+ content = fast_atoreal_move(content, (ai_real &)pLight.mColor.r);
+ SkipSpacesAndLineEnd(&content, end);
+
+ content = fast_atoreal_move(content, (ai_real &)pLight.mColor.g);
+ SkipSpacesAndLineEnd(&content, end);
+
+ content = fast_atoreal_move(content, (ai_real &)pLight.mColor.b);
+ SkipSpacesAndLineEnd(&content, end);
+ } else if (currentName == "constant_attenuation") {
+ XmlParser::getValueAsReal(currentNode, pLight.mAttConstant);
+ } else if (currentName == "linear_attenuation") {
+ XmlParser::getValueAsReal(currentNode, pLight.mAttLinear);
+ } else if (currentName == "quadratic_attenuation") {
+ XmlParser::getValueAsReal(currentNode, pLight.mAttQuadratic);
+ } else if (currentName == "falloff_angle") {
+ XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
+ } else if (currentName == "falloff_exponent") {
+ XmlParser::getValueAsReal(currentNode, pLight.mFalloffExponent);
+ }
+ // FCOLLADA extensions
+ // -------------------------------------------------------
+ else if (currentName == "outer_cone") {
+ XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
+ } else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone
+ XmlParser::getValueAsReal(currentNode, pLight.mPenumbraAngle);
+ } else if (currentName == "intensity") {
+ XmlParser::getValueAsReal(currentNode, pLight.mIntensity);
+ } else if (currentName == "falloff") {
+ XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
+ } else if (currentName == "hotspot_beam") {
+ XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
+ }
+ // OpenCOLLADA extensions
+ // -------------------------------------------------------
+ else if (currentName == "decay_falloff") {
+ XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+// Reads a camera entry into the given light
+static void ReadCamera(XmlNode &node, Camera &camera) {
+ XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
+ XmlNode currentNode;
+ while (xmlIt.getNext(currentNode)) {
+ const std::string ¤tName = currentNode.name();
+ if (currentName == "orthographic") {
+ camera.mOrtho = true;
+ } else if (currentName == "xfov" || currentName == "xmag") {
+ XmlParser::getValueAsReal(currentNode, camera.mHorFov);
+ } else if (currentName == "yfov" || currentName == "ymag") {
+ XmlParser::getValueAsReal(currentNode, camera.mVerFov);
+ } else if (currentName == "aspect_ratio") {
+ XmlParser::getValueAsReal(currentNode, camera.mAspect);
+ } else if (currentName == "znear") {
+ XmlParser::getValueAsReal(currentNode, camera.mZNear);
+ } else if (currentName == "zfar") {
+ XmlParser::getValueAsReal(currentNode, camera.mZFar);
+ }
+ }
+}
+
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
mFileName(pFile),
- mXmlParser(),
- mDataLibrary(),
- mAccessorLibrary(),
- mMeshLibrary(),
- mNodeLibrary(),
- mImageLibrary(),
- mEffectLibrary(),
- mMaterialLibrary(),
- mLightLibrary(),
- mCameraLibrary(),
- mControllerLibrary(),
mRootNode(nullptr),
- mAnims(),
mUnitSize(1.0f),
mUpDirection(UP_Y),
mFormat(FV_1_5_n) {
@@ -122,13 +421,13 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
throw DeadlyImportError("IOSystem is nullptr.");
}
- std::unique_ptr daefile;
+ std::unique_ptr daeFile;
std::unique_ptr zip_archive;
// Determine type
- std::string extension = BaseImporter::GetExtension(pFile);
+ const std::string extension = BaseImporter::GetExtension(pFile);
if (extension != "dae") {
- zip_archive.reset(new ZipArchiveIOSystem(pIOHandler, pFile));
+ zip_archive = std::make_unique(pIOHandler, pFile);
}
if (zip_archive && zip_archive->isOpen()) {
@@ -138,24 +437,24 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
throw DeadlyImportError("Invalid ZAE");
}
- daefile.reset(zip_archive->Open(dae_filename.c_str()));
- if (daefile == nullptr) {
+ daeFile.reset(zip_archive->Open(dae_filename.c_str()));
+ if (daeFile == nullptr) {
throw DeadlyImportError("Invalid ZAE manifest: '", dae_filename, "' is missing");
}
} else {
// attempt to open the file directly
- daefile.reset(pIOHandler->Open(pFile));
- if (daefile == nullptr) {
+ daeFile.reset(pIOHandler->Open(pFile));
+ if (daeFile == nullptr) {
throw DeadlyImportError("Failed to open file '", pFile, "'.");
}
}
// generate a XML reader for it
- if (!mXmlParser.parse(daefile.get())) {
+ if (!mXmlParser.parse(daeFile.get())) {
throw DeadlyImportError("Unable to read file, malformed XML");
}
// start reading
- XmlNode node = mXmlParser.getRootNode();
+ const XmlNode node = mXmlParser.getRootNode();
XmlNode colladaNode = node.child("COLLADA");
if (colladaNode.empty()) {
return;
@@ -190,14 +489,14 @@ std::string ColladaParser::ReadZaeManifest(ZipArchiveIOSystem &zip_archive) {
zip_archive.getFileListExtension(file_list, "dae");
if (file_list.empty()) {
- return std::string();
+ return {};
}
return file_list.front();
}
XmlParser manifestParser;
if (!manifestParser.parse(manifestfile.get())) {
- return std::string();
+ return {};
}
XmlNode root = manifestParser.getRootNode();
@@ -205,7 +504,7 @@ std::string ColladaParser::ReadZaeManifest(ZipArchiveIOSystem &zip_archive) {
if (name != "dae_root") {
root = *manifestParser.findNode("dae_root");
if (nullptr == root) {
- return std::string();
+ return {};
}
std::string v;
XmlParser::getValueAsString(root, v);
@@ -214,7 +513,7 @@ std::string ColladaParser::ReadZaeManifest(ZipArchiveIOSystem &zip_archive) {
return std::string(ai_str.C_Str());
}
- return std::string();
+ return {};
}
// ------------------------------------------------------------------------------------------------
@@ -246,7 +545,7 @@ void ColladaParser::UriDecodePath(aiString &ss) {
char mychar[3] = { it[1], it[2], 0 };
size_t nbr = strtoul16(mychar);
it += 3;
- *out++ = (char)(nbr & 0xFF);
+ *out++ = static_cast(nbr & 0xFF);
} else {
*out++ = *it++;
}
@@ -261,12 +560,11 @@ void ColladaParser::UriDecodePath(aiString &ss) {
// ------------------------------------------------------------------------------------------------
// Reads the contents of the file
void ColladaParser::ReadContents(XmlNode &node) {
- const std::string name = node.name();
- if (name == "COLLADA") {
+ if (const std::string name = node.name(); name == "COLLADA") {
std::string version;
if (XmlParser::getStdStrAttribute(node, "version", version)) {
aiString v;
- v.Set(version.c_str());
+ v.Set(version);
mAssetMetaData.emplace(AI_METADATA_SOURCE_FORMAT_VERSION, v);
if (!::strncmp(version.c_str(), "1.5", 3)) {
mFormat = FV_1_5_n;
@@ -287,8 +585,7 @@ void ColladaParser::ReadContents(XmlNode &node) {
// Reads the structure of the file
void ColladaParser::ReadStructure(XmlNode &node) {
for (XmlNode ¤tNode : node.children()) {
- const std::string ¤tName = currentNode.name();
- if (currentName == "asset") {
+ if (const std::string ¤tName = currentNode.name(); currentName == "asset") {
ReadAssetInfo(currentNode);
} else if (currentName == "library_animations") {
ReadAnimationLibrary(currentNode);
@@ -329,8 +626,7 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
}
for (XmlNode ¤tNode : node.children()) {
- const std::string ¤tName = currentNode.name();
- if (currentName == "unit") {
+ if (const std::string ¤tName = currentNode.name(); currentName == "unit") {
mUnitSize = 1.f;
std::string tUnitSizeString;
if (XmlParser::getStdStrAttribute(currentNode, "meter", tUnitSizeString)) {
@@ -364,35 +660,6 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
}
}
-// ------------------------------------------------------------------------------------------------
-// Reads a single string metadata item
-void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) {
- const Collada::MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase();
- const std::string name = node.name();
- if (name.empty()) {
- return;
- }
-
- std::string v;
- if (!XmlParser::getValueAsString(node, v)) {
- return;
- }
-
- v = ai_trim(v);
- aiString aistr;
- aistr.Set(v);
-
- std::string camel_key_str(name);
- ToCamelCase(camel_key_str);
-
- size_t found_index;
- if (FindCommonKey(camel_key_str, key_renaming, found_index)) {
- metadata.emplace(key_renaming[found_index].second, aistr);
- } else {
- metadata.emplace(camel_key_str, aistr);
- }
-}
-
// ------------------------------------------------------------------------------------------------
// Reads the animation clips
void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
@@ -424,15 +691,16 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
}
}
+// ------------------------------------------------------------------------------------------------
+// The controller post processing step
void ColladaParser::PostProcessControllers() {
- std::string meshId;
for (auto &it : mControllerLibrary) {
- meshId = it.second.mMeshId;
+ std::string meshId = it.second.mMeshId;
if (meshId.empty()) {
continue;
}
- ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
+ auto findItr = mControllerLibrary.find(meshId);
while (findItr != mControllerLibrary.end()) {
meshId = findItr->second.mMeshId;
findItr = mControllerLibrary.find(meshId);
@@ -454,13 +722,13 @@ void ColladaParser::PostProcessRootAnimations() {
for (auto &it : mAnimationClipLibrary) {
std::string clipName = it.first;
- Animation *clip = new Animation();
+ auto *clip = new Animation();
clip->mName = clipName;
temp.mSubAnims.push_back(clip);
for (const std::string &animationID : it.second) {
- AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
+ auto animation = mAnimationLibrary.find(animationID);
if (animation != mAnimationLibrary.end()) {
Animation *pSourceAnimation = animation->second;
@@ -533,7 +801,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
std::string id;
if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
// have it read into a channel
- ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
+ auto newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
ReadAnimationSampler(currentNode, newChannel->second);
}
} else if (currentName == "channel") {
@@ -543,7 +811,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
if (source_name[0] == '#') {
source_name = source_name.substr(1, source_name.size() - 1);
}
- ChannelMap::iterator cit = channels.find(source_name);
+ auto cit = channels.find(source_name);
if (cit != channels.end()) {
cit->second.mTarget = target;
}
@@ -568,40 +836,6 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
}
}
-// ------------------------------------------------------------------------------------------------
-// Reads an animation sampler into the given anim channel
-void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) {
- for (XmlNode ¤tNode : node.children()) {
- const std::string ¤tName = currentNode.name();
- if (currentName == "input") {
- if (XmlParser::hasAttribute(currentNode, "semantic")) {
- std::string semantic, sourceAttr;
- XmlParser::getStdStrAttribute(currentNode, "semantic", semantic);
- if (XmlParser::hasAttribute(currentNode, "source")) {
- XmlParser::getStdStrAttribute(currentNode, "source", sourceAttr);
- const char *source = sourceAttr.c_str();
- if (source[0] != '#') {
- throw DeadlyImportError("Unsupported URL format");
- }
- source++;
-
- if (semantic == "INPUT") {
- pChannel.mSourceTimes = source;
- } else if (semantic == "OUTPUT") {
- pChannel.mSourceValues = source;
- } else if (semantic == "IN_TANGENT") {
- pChannel.mInTanValues = source;
- } else if (semantic == "OUT_TANGENT") {
- pChannel.mOutTanValues = source;
- } else if (semantic == "INTERPOLATION") {
- pChannel.mInterpolationValues = source;
- }
- }
- }
- }
- }
-}
-
// ------------------------------------------------------------------------------------------------
// Reads the skeleton controller library
void ColladaParser::ReadControllerLibrary(XmlNode &node) {
@@ -614,8 +848,7 @@ void ColladaParser::ReadControllerLibrary(XmlNode &node) {
if (currentName != "controller") {
continue;
}
- std::string id;
- if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
+ if (std::string id; XmlParser::getStdStrAttribute(currentNode, "id", id)) {
mControllerLibrary[id] = Controller();
ReadController(currentNode, mControllerLibrary[id]);
}
@@ -632,12 +865,11 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
- const std::string ¤tName = currentNode.name();
- if (currentName == "morph") {
+ if (const std::string ¤tName = currentNode.name(); currentName == "morph") {
controller.mType = Morph;
- controller.mMeshId = currentNode.attribute("source").as_string();
- int methodIndex = currentNode.attribute("method").as_int();
- if (methodIndex > 0) {
+ std::string id = currentNode.attribute("source").as_string();
+ controller.mMeshId = id.substr(1, id.size() - 1);
+ if (const int methodIndex = currentNode.attribute("method").as_int(); methodIndex > 0) {
std::string method;
XmlParser::getValueAsString(currentNode, method);
@@ -646,20 +878,20 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
}
}
} else if (currentName == "skin") {
- std::string id;
- if (XmlParser::getStdStrAttribute(currentNode, "source", id)) {
+ if (std::string id; XmlParser::getStdStrAttribute(currentNode, "source", id)) {
controller.mMeshId = id.substr(1, id.size() - 1);
}
} else if (currentName == "bind_shape_matrix") {
std::string v;
XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str();
- for (unsigned int a = 0; a < 16; a++) {
- SkipSpacesAndLineEnd(&content);
+ const char *end = content + v.size();
+ for (auto & a : controller.mBindShapeMatrix) {
+ SkipSpacesAndLineEnd(&content, end);
// read a number
- content = fast_atoreal_move(content, controller.mBindShapeMatrix[a]);
+ content = fast_atoreal_move(content, a);
// skip whitespace after it
- SkipSpacesAndLineEnd(&content);
+ SkipSpacesAndLineEnd(&content, end);
}
} else if (currentName == "source") {
ReadSource(currentNode);
@@ -684,105 +916,13 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
}
}
-// ------------------------------------------------------------------------------------------------
-// Reads the joint definitions for the given controller
-void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) {
- for (XmlNode ¤tNode : node.children()) {
- const std::string ¤tName = currentNode.name();
- if (currentName == "input") {
- const char *attrSemantic = currentNode.attribute("semantic").as_string();
- const char *attrSource = currentNode.attribute("source").as_string();
- if (attrSource[0] != '#') {
- throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of data element");
- }
- ++attrSource;
- // parse source URL to corresponding source
- if (strcmp(attrSemantic, "JOINT") == 0) {
- pController.mJointNameSource = attrSource;
- } else if (strcmp(attrSemantic, "INV_BIND_MATRIX") == 0) {
- pController.mJointOffsetMatrixSource = attrSource;
- } else {
- throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in data element");
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the joint weights for the given controller
-void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) {
- // Read vertex count from attributes and resize the array accordingly
- int vertexCount = 0;
- XmlParser::getIntAttribute(node, "count", vertexCount);
- pController.mWeightCounts.resize(vertexCount);
-
- for (XmlNode ¤tNode : node.children()) {
- const std::string ¤tName = currentNode.name();
- if (currentName == "input") {
- InputChannel channel;
-
- const char *attrSemantic = currentNode.attribute("semantic").as_string();
- const char *attrSource = currentNode.attribute("source").as_string();
- channel.mOffset = currentNode.attribute("offset").as_int();
-
- // local URLS always start with a '#'. We don't support global URLs
- if (attrSource[0] != '#') {
- throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of data element");
- }
- channel.mAccessor = attrSource + 1;
-
- // parse source URL to corresponding source
- if (strcmp(attrSemantic, "JOINT") == 0) {
- pController.mWeightInputJoints = channel;
- } else if (strcmp(attrSemantic, "WEIGHT") == 0) {
- pController.mWeightInputWeights = channel;
- } else {
- throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in data element");
- }
- } else if (currentName == "vcount" && vertexCount > 0) {
- const char *text = currentNode.text().as_string();
- size_t numWeights = 0;
- for (std::vector::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
- if (*text == 0) {
- throw DeadlyImportError("Out of data while reading ");
- }
-
- *it = strtoul10(text, &text);
- numWeights += *it;
- SkipSpacesAndLineEnd(&text);
- }
- // reserve weight count
- pController.mWeights.resize(numWeights);
- } else if (currentName == "v" && vertexCount > 0) {
- // read JointIndex - WeightIndex pairs
- std::string stdText;
- XmlParser::getValueAsString(currentNode, stdText);
- const char *text = stdText.c_str();
- for (std::vector>::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) {
- if (text == nullptr) {
- throw DeadlyImportError("Out of data while reading ");
- }
- SkipSpacesAndLineEnd(&text);
- it->first = strtoul10(text, &text);
- SkipSpacesAndLineEnd(&text);
- if (*text == 0) {
- throw DeadlyImportError("Out of data while reading ");
- }
- it->second = strtoul10(text, &text);
- SkipSpacesAndLineEnd(&text);
- }
- }
- }
-}
-
// ------------------------------------------------------------------------------------------------
// Reads the image library contents
-void ColladaParser::ReadImageLibrary(XmlNode &node) {
+void ColladaParser::ReadImageLibrary(const XmlNode &node) {
for (XmlNode ¤tNode : node.children()) {
const std::string ¤tName = currentNode.name();
if (currentName == "image") {
- std::string id;
- if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
+ if (std::basic_string id; XmlParser::getStdStrAttribute(currentNode, "id", id)) {
mImageLibrary[id] = Image();
// read on from there
ReadImage(currentNode, mImageLibrary[id]);
@@ -793,7 +933,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) {
// ------------------------------------------------------------------------------------------------
// Reads an image entry into the given image
-void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
+void ColladaParser::ReadImage(const XmlNode &node, Collada::Image &pImage) const {
for (XmlNode ¤tNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == "image") {
@@ -856,13 +996,13 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
// Reads the material library
void ColladaParser::ReadMaterialLibrary(XmlNode &node) {
std::map names;
- for (XmlNode ¤tNode : node.children()) {
+ for (const XmlNode ¤tNode : node.children()) {
std::string id = currentNode.attribute("id").as_string();
std::string name = currentNode.attribute("name").as_string();
mMaterialLibrary[id] = Material();
if (!name.empty()) {
- std::map::iterator it = names.find(name);
+ auto it = names.find(name);
if (it != names.end()) {
std::ostringstream strStream;
strStream << ++it->second;
@@ -917,106 +1057,6 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) {
}
}
-// ------------------------------------------------------------------------------------------------
-// Reads a material entry into the given material
-void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
- for (XmlNode ¤tNode : node.children()) {
- const std::string ¤tName = currentNode.name();
- if (currentName == "instance_effect") {
- std::string url;
- readUrlAttribute(currentNode, url);
- pMaterial.mEffect = url;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a light entry into the given light
-void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
- XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
- XmlNode currentNode;
- // TODO: Check the current technique and skip over unsupported extra techniques
-
- while (xmlIt.getNext(currentNode)) {
- const std::string ¤tName = currentNode.name();
- if (currentName == "spot") {
- pLight.mType = aiLightSource_SPOT;
- } else if (currentName == "ambient") {
- pLight.mType = aiLightSource_AMBIENT;
- } else if (currentName == "directional") {
- pLight.mType = aiLightSource_DIRECTIONAL;
- } else if (currentName == "point") {
- pLight.mType = aiLightSource_POINT;
- } else if (currentName == "color") {
- // text content contains 3 floats
- std::string v;
- XmlParser::getValueAsString(currentNode, v);
- const char *content = v.c_str();
-
- content = fast_atoreal_move(content, (ai_real &)pLight.mColor.r);
- SkipSpacesAndLineEnd(&content);
-
- content = fast_atoreal_move(content, (ai_real &)pLight.mColor.g);
- SkipSpacesAndLineEnd(&content);
-
- content = fast_atoreal_move(content, (ai_real &)pLight.mColor.b);
- SkipSpacesAndLineEnd(&content);
- } else if (currentName == "constant_attenuation") {
- XmlParser::getValueAsFloat(currentNode, pLight.mAttConstant);
- } else if (currentName == "linear_attenuation") {
- XmlParser::getValueAsFloat(currentNode, pLight.mAttLinear);
- } else if (currentName == "quadratic_attenuation") {
- XmlParser::getValueAsFloat(currentNode, pLight.mAttQuadratic);
- } else if (currentName == "falloff_angle") {
- XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
- } else if (currentName == "falloff_exponent") {
- XmlParser::getValueAsFloat(currentNode, pLight.mFalloffExponent);
- }
- // FCOLLADA extensions
- // -------------------------------------------------------
- else if (currentName == "outer_cone") {
- XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
- } else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone
- XmlParser::getValueAsFloat(currentNode, pLight.mPenumbraAngle);
- } else if (currentName == "intensity") {
- XmlParser::getValueAsFloat(currentNode, pLight.mIntensity);
- }
- else if (currentName == "falloff") {
- XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
- } else if (currentName == "hotspot_beam") {
- XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
- }
- // OpenCOLLADA extensions
- // -------------------------------------------------------
- else if (currentName == "decay_falloff") {
- XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a camera entry into the given light
-void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) {
- XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
- XmlNode currentNode;
- while (xmlIt.getNext(currentNode)) {
- const std::string ¤tName = currentNode.name();
- if (currentName == "orthographic") {
- camera.mOrtho = true;
- } else if (currentName == "xfov" || currentName == "xmag") {
- XmlParser::getValueAsFloat(currentNode, camera.mHorFov);
- } else if (currentName == "yfov" || currentName == "ymag") {
- XmlParser::getValueAsFloat(currentNode, camera.mVerFov);
- } else if (currentName == "aspect_ratio") {
- XmlParser::getValueAsFloat(currentNode, camera.mAspect);
- } else if (currentName == "znear") {
- XmlParser::getValueAsFloat(currentNode, camera.mZNear);
- } else if (currentName == "zfar") {
- XmlParser::getValueAsFloat(currentNode, camera.mZFar);
- }
- }
-}
-
// ------------------------------------------------------------------------------------------------
// Reads the effect library
void ColladaParser::ReadEffectLibrary(XmlNode &node) {
@@ -1164,15 +1204,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);
@@ -1192,14 +1232,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);
}
}
}
@@ -1220,18 +1260,19 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
std::string v;
XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str();
+ const char *end = v.c_str() + v.size() + 1;
content = fast_atoreal_move(content, (ai_real &)pColor.r);
- SkipSpacesAndLineEnd(&content);
+ SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move(content, (ai_real &)pColor.g);
- SkipSpacesAndLineEnd(&content);
+ SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move(content, (ai_real &)pColor.b);
- SkipSpacesAndLineEnd(&content);
+ SkipSpacesAndLineEnd(&content, end);
content = fast_atoreal_move(content, (ai_real &)pColor.a);
- SkipSpacesAndLineEnd(&content);
+ SkipSpacesAndLineEnd(&content, end);
} else if (currentName == "texture") {
// get name of source texture/sampler
XmlParser::getStdStrAttribute(currentNode, "texture", pSampler.mName);
@@ -1258,13 +1299,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);
}
// ------------------------------------------------------------------------------------------------
@@ -1345,6 +1386,7 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
if (node.empty()) {
return;
}
+
for (XmlNode ¤tNode : node.children()) {
const std::string ¤tName = currentNode.name();
if (currentName == "mesh") {
@@ -1415,6 +1457,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
XmlParser::getValueAsString(node, v);
v = ai_trim(v);
const char *content = v.c_str();
+ const char *end = content + v.size();
// read values and store inside an array in the data library
mDataLibrary[id] = Data();
@@ -1433,11 +1476,13 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
}
s.clear();
- while (!IsSpaceOrNewLine(*content))
- s += *content++;
+ while (!IsSpaceOrNewLine(*content)) {
+ s += *content;
+ content++;
+ }
data.mStrings.push_back(s);
- SkipSpacesAndLineEnd(&content);
+ SkipSpacesAndLineEnd(&content, end);
}
} else {
data.mValues.reserve(count);
@@ -1452,7 +1497,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
content = fast_atoreal_move(content, value);
data.mValues.push_back(value);
// skip whitespace after it
- SkipSpacesAndLineEnd(&content);
+ SkipSpacesAndLineEnd(&content, end);
}
}
}
@@ -1617,8 +1662,10 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
std::string v;
XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str();
+ const char *end = content + v.size();
+
vcount.reserve(numPrimitives);
- SkipSpacesAndLineEnd(&content);
+ SkipSpacesAndLineEnd(&content, end);
for (unsigned int a = 0; a < numPrimitives; a++) {
if (*content == 0) {
throw DeadlyImportError("Expected more values while reading contents.");
@@ -1626,7 +1673,7 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
// read a number
vcount.push_back((size_t)strtoul10(content, &content));
// skip whitespace after it
- SkipSpacesAndLineEnd(&content);
+ SkipSpacesAndLineEnd(&content, end);
}
}
}
@@ -1720,7 +1767,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
+ for (auto it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
InputChannel &input = *it;
if (input.mResolved) {
continue;
@@ -1772,10 +1820,14 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vectormData) {
acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource);
+ const size_t dataSize = acc->mOffset + acc->mCount * acc->mStride;
+ if (dataSize > acc->mData->mValues.size()) {
+ throw DeadlyImportError("Not enough data for accessor");
+ }
}
}
// and the same for the per-index channels
- for (std::vector::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
+ for (auto it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
InputChannel &input = *it;
if (input.mResolved) {
continue;
@@ -1796,13 +1848,19 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vectormData) {
acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource);
+ const size_t dataSize = acc->mOffset + acc->mCount * acc->mStride;
+ if (dataSize > acc->mData->mValues.size()) {
+ throw DeadlyImportError("Not enough data for accessor");
+ }
}
}
// For continued primitives, the given count does not come all in one
, but only one primitive per
size_t numPrimitives = pNumPrimitives;
- if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon)
+ if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon) {
numPrimitives = 1;
+ }
+
// For continued primitives, the given count is actually the number of
's inside the parent tag
if (pPrimType == Prim_TriStrips) {
size_t numberOfVertices = indices.size() / numOffsets;
@@ -1877,11 +1935,11 @@ void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t n
ai_assert((baseOffset + numOffsets - 1) < indices.size());
// extract per-vertex channels using the global per-vertex offset
- for (std::vector::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
+ for (auto it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
ExtractDataObjectFromChannel(*it, indices[baseOffset + perVertexOffset], pMesh);
}
// and extract per-index channels using there specified offset
- for (std::vector::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
+ for (auto it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
ExtractDataObjectFromChannel(*it, indices[baseOffset + it->mOffset], pMesh);
}
@@ -2148,40 +2206,6 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
}
}
-// ------------------------------------------------------------------------------------------------
-// Reads a node transformation entry of the given type and adds it to the given node's transformation list.
-void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, TransformType pType) {
- if (node.empty()) {
- return;
- }
-
- std::string tagName = node.name();
-
- Transform tf;
- tf.mType = pType;
-
- // read SID
- if (XmlParser::hasAttribute(node, "sid")) {
- XmlParser::getStdStrAttribute(node, "sid", tf.mID);
- }
-
- // how many parameters to read per transformation type
- static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
- std::string value;
- XmlParser::getValueAsString(node, value);
- const char *content = value.c_str();
-
- // read as many parameters and store in the transformation
- for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
- // skip whitespace before the number
- SkipSpacesAndLineEnd(&content);
- // read a number
- content = fast_atoreal_move(content, tf.f[a]);
- }
-
- // place the transformation at the queue of the node
- pNode->mTransforms.push_back(tf);
-}
// ------------------------------------------------------------------------------------------------
// Processes bind_vertex_input and bind elements
@@ -2219,9 +2243,7 @@ void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::Seman
void ColladaParser::ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive) {
// Attempt to load any undefined Collada::Image in ImageLibrary
for (auto &it : mImageLibrary) {
- Collada::Image &image = it.second;
-
- if (image.mImageData.empty()) {
+ if (Image &image = it.second; image.mImageData.empty()) {
std::unique_ptr image_file(zip_archive.Open(image.mFileName.c_str()));
if (image_file) {
image.mImageData.resize(image_file->FileSize());
@@ -2268,9 +2290,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);
}
}
}
@@ -2304,7 +2326,7 @@ void ColladaParser::ReadScene(XmlNode &node) {
}
// find the referred scene, skip the leading #
- NodeLibrary::const_iterator sit = mNodeLibrary.find(url.c_str() + 1);
+ auto sit = mNodeLibrary.find(url.c_str() + 1);
if (sit == mNodeLibrary.end()) {
throw DeadlyImportError("Unable to resolve visual_scene reference \"", std::string(std::move(url)), "\" in element.");
}
@@ -2376,7 +2398,7 @@ aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector
// ------------------------------------------------------------------------------------------------
// Determines the input data type for the given semantic string
-Collada::InputType ColladaParser::GetTypeForSemantic(const std::string &semantic) {
+InputType ColladaParser::GetTypeForSemantic(const std::string &semantic) {
if (semantic.empty()) {
ASSIMP_LOG_WARN("Vertex input type is empty.");
return IT_Invalid;
diff --git a/code/AssetLib/Collada/ColladaParser.h b/code/AssetLib/Collada/ColladaParser.h
index 15982934f..e2bc895df 100644
--- a/code/AssetLib/Collada/ColladaParser.h
+++ b/code/AssetLib/Collada/ColladaParser.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
- Copyright (c) 2006-2022, assimp team
+ Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -48,7 +48,6 @@
#define AI_COLLADAPARSER_H_INC
#include "ColladaHelper.h"
-#include
#include
#include
@@ -67,268 +66,240 @@ class ZipArchiveIOSystem;
class ColladaParser {
friend class ColladaLoader;
- /** Converts a path read from a collada file to the usual representation */
- static void UriDecodePath(aiString &ss);
+public:
+ /// Map for generic metadata as aiString.
+ using StringMetaData = std::map;
-protected:
- /** Map for generic metadata as aiString */
- typedef std::map StringMetaData;
-
- /** Constructor from XML file */
+ /// Constructor from XML file.
ColladaParser(IOSystem *pIOHandler, const std::string &pFile);
- /** Destructor */
+ /// Destructor
~ColladaParser();
- /** Attempts to read the ZAE manifest and returns the DAE to open */
+ /// Attempts to read the ZAE manifest and returns the DAE to open
static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
- /** Reads the contents of the file */
+ /// Reads the contents of the file
void ReadContents(XmlNode &node);
- /** Reads the structure of the file */
+ /// Reads the structure of the file
void ReadStructure(XmlNode &node);
- /** Reads asset information such as coordinate system information and legal blah */
+ /// Reads asset information such as coordinate system information and legal blah
void ReadAssetInfo(XmlNode &node);
- /** Reads contributor information such as author and legal blah */
+ /// Reads contributor information such as author and legal blah
void ReadContributorInfo(XmlNode &node);
- /** Reads generic metadata into provided map and renames keys for Assimp */
- void ReadMetaDataItem(XmlNode &node, StringMetaData &metadata);
-
- /** Reads the animation library */
+ /// Reads the animation library
void ReadAnimationLibrary(XmlNode &node);
- /** Reads the animation clip library */
+ /// Reads the animation clip library
void ReadAnimationClipLibrary(XmlNode &node);
- /** Unwrap controllers dependency hierarchy */
+ /// Unwrap controllers dependency hierarchy
void PostProcessControllers();
- /** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
+ /// Re-build animations from animation clip library, if present, otherwise combine single-channel animations
void PostProcessRootAnimations();
- /** Reads an animation into the given parent structure */
+ /// Reads an animation into the given parent structure
void ReadAnimation(XmlNode &node, Collada::Animation *pParent);
- /** Reads an animation sampler into the given anim channel */
- void ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel);
-
- /** Reads the skeleton controller library */
+ /// Reads the skeleton controller library
void ReadControllerLibrary(XmlNode &node);
- /** Reads a controller into the given mesh structure */
+ /// Reads a controller into the given mesh structure
void ReadController(XmlNode &node, Collada::Controller &pController);
- /** Reads the joint definitions for the given controller */
- void ReadControllerJoints(XmlNode &node, Collada::Controller &pController);
+ /// Reads the image library contents
+ void ReadImageLibrary(const XmlNode &node);
- /** Reads the joint weights for the given controller */
- void ReadControllerWeights(XmlNode &node, Collada::Controller &pController);
+ /// Reads an image entry into the given image
+ void ReadImage(const XmlNode &node, Collada::Image &pImage) const;
- /** Reads the image library contents */
- void ReadImageLibrary(XmlNode &node);
-
- /** Reads an image entry into the given image */
- void ReadImage(XmlNode &node, Collada::Image &pImage);
-
- /** Reads the material library */
+ /// Reads the material library
void ReadMaterialLibrary(XmlNode &node);
- /** Reads a material entry into the given material */
- void ReadMaterial(XmlNode &node, Collada::Material &pMaterial);
-
- /** Reads the camera library */
+ /// Reads the camera library
void ReadCameraLibrary(XmlNode &node);
- /** Reads a camera entry into the given camera */
- void ReadCamera(XmlNode &node, Collada::Camera &pCamera);
-
- /** Reads the light library */
+ /// Reads the light library
void ReadLightLibrary(XmlNode &node);
- /** Reads a light entry into the given light */
- void ReadLight(XmlNode &node, Collada::Light &pLight);
-
- /** Reads the effect library */
+ /// Reads the effect library
void ReadEffectLibrary(XmlNode &node);
- /** Reads an effect entry into the given effect*/
+ /// Reads an effect entry into the given effect
void ReadEffect(XmlNode &node, Collada::Effect &pEffect);
- /** Reads an COMMON effect profile */
+ /// Reads an COMMON effect profile
void ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect);
- /** Read sampler properties */
+ /// Read sampler properties
void ReadSamplerProperties(XmlNode &node, Collada::Sampler &pSampler);
- /** Reads an effect entry containing a color or a texture defining that color */
+ /// Reads an effect entry containing a color or a texture defining that color
void ReadEffectColor(XmlNode &node, aiColor4D &pColor, Collada::Sampler &pSampler);
- /** Reads an effect entry containing a float */
+ /// Reads an effect entry containing a float
void ReadEffectFloat(XmlNode &node, ai_real &pFloat);
- /** Reads an effect parameter specification of any kind */
+ /// Reads an effect parameter specification of any kind
void ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam);
- /** Reads the geometry library contents */
+ /// Reads the geometry library contents
void ReadGeometryLibrary(XmlNode &node);
- /** Reads a geometry from the geometry library. */
+ /// Reads a geometry from the geometry library.
void ReadGeometry(XmlNode &node, Collada::Mesh &pMesh);
- /** Reads a mesh from the geometry library */
+ /// Reads a mesh from the geometry library
void ReadMesh(XmlNode &node, Collada::Mesh &pMesh);
- /** Reads a source element - a combination of raw data and an accessor defining
- * things that should not be redefinable. Yes, that's another rant.
- */
+ /// Reads a source element - a combination of raw data and an accessor defining
+ ///things that should not be definable. Yes, that's another rant.
void ReadSource(XmlNode &node);
- /** Reads a data array holding a number of elements, and stores it in the global library.
- * Currently supported are array of floats and arrays of strings.
- */
+ /// Reads a data array holding a number of elements, and stores it in the global library.
+ /// Currently supported are array of floats and arrays of strings.
void ReadDataArray(XmlNode &node);
- /** Reads an accessor and stores it in the global library under the given ID -
- * accessors use the ID of the parent element
- */
+ /// Reads an accessor and stores it in the global library under the given ID -
+ /// accessors use the ID of the parent element
void ReadAccessor(XmlNode &node, const std::string &pID);
- /** Reads input declarations of per-vertex mesh data into the given mesh */
+ /// Reads input declarations of per-vertex mesh data into the given mesh
void ReadVertexData(XmlNode &node, Collada::Mesh &pMesh);
- /** Reads input declarations of per-index mesh data into the given mesh */
+ /// Reads input declarations of per-index mesh data into the given mesh
void ReadIndexData(XmlNode &node, Collada::Mesh &pMesh);
- /** Reads a single input channel element and stores it in the given array, if valid */
+ /// Reads a single input channel element and stores it in the given array, if valid
void ReadInputChannel(XmlNode &node, std::vector &poChannels);
- /** Reads a
primitive index list and assembles the mesh data into the given mesh */
+ /// Reads a
primitive index list and assembles the mesh data into the given mesh
size_t ReadPrimitives(XmlNode &node, Collada::Mesh &pMesh, std::vector &pPerIndexChannels,
size_t pNumPrimitives, const std::vector &pVCount, Collada::PrimitiveType pPrimType);
- /** Copies the data for a single primitive into the mesh, based on the InputChannels */
+ /// Copies the data for a single primitive into the mesh, based on the InputChannels
void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
Collada::Mesh &pMesh, std::vector &pPerIndexChannels,
size_t currentPrimitive, const std::vector &indices);
- /** Reads one triangle of a tristrip into the mesh */
+ /// Reads one triangle of a tristrip into the mesh
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh &pMesh,
std::vector &pPerIndexChannels, size_t currentPrimitive, const std::vector &indices);
- /** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
+ /// Extracts a single object from an input channel and stores it in the appropriate mesh data array
void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh);
- /** Reads the library of node hierarchies and scene parts */
+ /// Reads the library of node hierarchies and scene parts
void ReadSceneLibrary(XmlNode &node);
- /** Reads a scene node's contents including children and stores it in the given node */
+ /// Reads a scene node's contents including children and stores it in the given node
void ReadSceneNode(XmlNode &node, Collada::Node *pNode);
-
- /** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
- void ReadNodeTransformation(XmlNode &node, Collada::Node *pNode, Collada::TransformType pType);
-
- /** Reads a mesh reference in a node and adds it to the node's mesh list */
+
+ /// Reads a mesh reference in a node and adds it to the node's mesh list
void ReadNodeGeometry(XmlNode &node, Collada::Node *pNode);
- /** Reads the collada scene */
+ /// Reads the collada scene
void ReadScene(XmlNode &node);
- // Processes bind_vertex_input and bind elements
+ /// Processes bind_vertex_input and bind elements
void ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl);
- /** Reads embedded textures from a ZAE archive*/
+ /// Reads embedded textures from a ZAE archive
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
protected:
- /** Calculates the resulting transformation from all the given transform steps */
+ /// Converts a path read from a collada file to the usual representation
+ static void UriDecodePath(aiString &ss);
+
+ /// Calculates the resulting transformation from all the given transform steps
aiMatrix4x4 CalculateResultTransform(const std::vector &pTransforms) const;
- /** Determines the input data type for the given semantic string */
+ /// Determines the input data type for the given semantic string
Collada::InputType GetTypeForSemantic(const std::string &pSemantic);
- /** Finds the item in the given library by its reference, throws if not found */
+ /// Finds the item in the given library by its reference, throws if not found
template
const Type &ResolveLibraryReference(const std::map &pLibrary, const std::string &pURL) const;
-protected:
- // Filename, for a verbose error message
+private:
+ /// Filename, for a verbose error message
std::string mFileName;
- // XML reader, member for everyday use
+ /// XML reader, member for everyday use
XmlParser mXmlParser;
- /** All data arrays found in the file by ID. Might be referred to by actually
- everyone. Collada, you are a steaming pile of indirection. */
+ /// All data arrays found in the file by ID. Might be referred to by actually
+ /// everyone. Collada, you are a steaming pile of indirection.
using DataLibrary = std::map ;
DataLibrary mDataLibrary;
- /** Same for accessors which define how the data in a data array is accessed. */
+ /// Same for accessors which define how the data in a data array is accessed.
using AccessorLibrary = std::map ;
AccessorLibrary mAccessorLibrary;
- /** Mesh library: mesh by ID */
+ /// Mesh library: mesh by ID
using MeshLibrary = std::map;
MeshLibrary mMeshLibrary;
- /** node library: root node of the hierarchy part by ID */
+ /// node library: root node of the hierarchy part by ID
using NodeLibrary = std::map;
NodeLibrary mNodeLibrary;
- /** Image library: stores texture properties by ID */
+ /// Image library: stores texture properties by ID
using ImageLibrary = std::map ;
ImageLibrary mImageLibrary;
- /** Effect library: surface attributes by ID */
+ /// Effect library: surface attributes by ID
using EffectLibrary = std::map ;
EffectLibrary mEffectLibrary;
- /** Material library: surface material by ID */
+ /// Material library: surface material by ID
using MaterialLibrary = std::map ;
MaterialLibrary mMaterialLibrary;
- /** Light library: surface light by ID */
+ /// Light library: surface light by ID
using LightLibrary = std::map ;
LightLibrary mLightLibrary;
- /** Camera library: surface material by ID */
+ /// Camera library: surface material by ID
using CameraLibrary = std::map ;
CameraLibrary mCameraLibrary;
- /** Controller library: joint controllers by ID */
+ /// Controller library: joint controllers by ID
using ControllerLibrary = std::map ;
ControllerLibrary mControllerLibrary;
- /** Animation library: animation references by ID */
+ /// Animation library: animation references by ID
using AnimationLibrary = std::map ;
AnimationLibrary mAnimationLibrary;
- /** Animation clip library: clip animation references by ID */
+ /// Animation clip library: clip animation references by ID
using AnimationClipLibrary = std::vector>> ;
AnimationClipLibrary mAnimationClipLibrary;
- /** Pointer to the root node. Don't delete, it just points to one of
- the nodes in the node library. */
+ /// Pointer to the root node. Don't delete, it just points to one of the nodes in the node library.
Collada::Node *mRootNode;
- /** Root animation container */
+ /// Root animation container
Collada::Animation mAnims;
- /** Size unit: how large compared to a meter */
+ /// Size unit: how large compared to a meter
ai_real mUnitSize;
- /** Which is the up vector */
+ /// Which is the up vector
enum { UP_X,
UP_Y,
UP_Z } mUpDirection;
- /** Asset metadata (global for scene) */
+ /// Asset metadata (global for scene)
StringMetaData mAssetMetaData;
- /** Collada file format version */
+ /// Collada file format version
Collada::FormatVersion mFormat;
};
diff --git a/code/AssetLib/DXF/DXFHelper.h b/code/AssetLib/DXF/DXFHelper.h
index 4d7893cc4..1626ee922 100644
--- a/code/AssetLib/DXF/DXFHelper.h
+++ b/code/AssetLib/DXF/DXFHelper.h
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, 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 > lines;
std::vector 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 blocks;
};
-}
-} // Namespace Assimp
+} // namespace DXF
+} // namespace Assimp
-#endif
+#endif // INCLUDED_DXFHELPER_H
diff --git a/code/AssetLib/DXF/DXFLoader.cpp b/code/AssetLib/DXF/DXFLoader.cpp
index f69cdfce2..213dce2b6 100644
--- a/code/AssetLib/DXF/DXFLoader.cpp
+++ b/code/AssetLib/DXF/DXFLoader.cpp
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -43,11 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the DXF importer class
*/
-
#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
-#include "AssetLib/DXF/DXFLoader.h"
-#include "AssetLib/DXF/DXFHelper.h"
+#include "DXFLoader.h"
+#include "DXFHelper.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include
@@ -68,25 +67,267 @@ static constexpr size_t AI_DXF_BINARY_IDENT_LEN = sizeof AI_DXF_BINARY_IDENT;
// default vertex color that all uncolored vertices will receive
static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
-// color indices for DXF - 16 are supported, the table is
-// taken directly from the DXF spec.
-static const aiColor4D g_aclrDxfIndexColors[] = {
- aiColor4D(0.6f, 0.6f, 0.6f, 1.0f),
- aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
- aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
- aiColor4D (0.0f, 0.0f, 1.0f, 1.0f), // blue
- aiColor4D (0.3f, 1.0f, 0.3f, 1.0f), // light green
- aiColor4D (0.3f, 0.3f, 1.0f, 1.0f), // light blue
- aiColor4D (1.0f, 0.3f, 0.3f, 1.0f), // light red
- aiColor4D (1.0f, 0.0f, 1.0f, 1.0f), // pink
- aiColor4D (1.0f, 0.6f, 0.0f, 1.0f), // orange
- aiColor4D (0.6f, 0.3f, 0.0f, 1.0f), // dark orange
- aiColor4D (1.0f, 1.0f, 0.0f, 1.0f), // yellow
- aiColor4D (0.3f, 0.3f, 0.3f, 1.0f), // dark gray
- aiColor4D (0.8f, 0.8f, 0.8f, 1.0f), // light gray
- aiColor4D (0.0f, 00.f, 0.0f, 1.0f), // black
- aiColor4D (1.0f, 1.0f, 1.0f, 1.0f), // white
- aiColor4D (0.6f, 0.0f, 1.0f, 1.0f) // violet
+// color indices for DXF - 256 are supported, the table is
+// taken directly from the AutoCad Index (ACI) table
+// https://gohtx.com/acadcolors.php
+//STH 2024-0126
+static const aiColor4D g_aclrDxfIndexColors[256] = {
+ aiColor4D (0.0f, 0.0f ,0.0f, 1.0f), //dxf color code 0
+ aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 1
+ aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 2
+ aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 3
+ aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 4
+ aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 5
+ aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 6
+ aiColor4D (1.0f, 1.0f ,1.0f, 1.0f), //dxf color code 7
+ aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 8
+ aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 9
+ aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 10
+ aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 11
+ aiColor4D (0.7f, 0.0f ,0.0f, 1.0f), //dxf color code 12
+ aiColor4D (0.7f, 0.5f ,0.5f, 1.0f), //dxf color code 13
+ aiColor4D (0.5f, 0.0f ,0.0f, 1.0f), //dxf color code 14
+ aiColor4D (0.5f, 0.3f ,0.3f, 1.0f), //dxf color code 15
+ aiColor4D (0.4f, 0.0f ,0.0f, 1.0f), //dxf color code 16
+ aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 17
+ aiColor4D (0.3f, 0.0f ,0.0f, 1.0f), //dxf color code 18
+ aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 19
+ aiColor4D (1.0f, 0.2f ,0.0f, 1.0f), //dxf color code 20
+ aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 21
+ aiColor4D (0.7f, 0.2f ,0.0f, 1.0f), //dxf color code 22
+ aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 23
+ aiColor4D (0.5f, 0.1f ,0.0f, 1.0f), //dxf color code 24
+ aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 25
+ aiColor4D (0.4f, 0.1f ,0.0f, 1.0f), //dxf color code 26
+ aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 27
+ aiColor4D (0.3f, 0.1f ,0.0f, 1.0f), //dxf color code 28
+ aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 29
+ aiColor4D (1.0f, 0.5f ,0.0f, 1.0f), //dxf color code 30
+ aiColor4D (1.0f, 0.8f ,0.7f, 1.0f), //dxf color code 31
+ aiColor4D (0.7f, 0.4f ,0.0f, 1.0f), //dxf color code 32
+ aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 33
+ aiColor4D (0.5f, 0.3f ,0.0f, 1.0f), //dxf color code 34
+ aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 35
+ aiColor4D (0.4f, 0.2f ,0.0f, 1.0f), //dxf color code 36
+ aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 37
+ aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 38
+ aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 39
+ aiColor4D (1.0f, 0.7f ,0.0f, 1.0f), //dxf color code 40
+ aiColor4D (1.0f, 0.9f ,0.7f, 1.0f), //dxf color code 41
+ aiColor4D (0.7f, 0.6f ,0.0f, 1.0f), //dxf color code 42
+ aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 43
+ aiColor4D (0.5f, 0.4f ,0.0f, 1.0f), //dxf color code 44
+ aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 45
+ aiColor4D (0.4f, 0.3f ,0.0f, 1.0f), //dxf color code 46
+ aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 47
+ aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 48
+ aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 49
+ aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 50
+ aiColor4D (1.0f, 1.0f ,0.7f, 1.0f), //dxf color code 51
+ aiColor4D (0.7f, 0.7f ,0.0f, 1.0f), //dxf color code 52
+ aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 53
+ aiColor4D (0.5f, 0.5f ,0.0f, 1.0f), //dxf color code 54
+ aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 55
+ aiColor4D (0.4f, 0.4f ,0.0f, 1.0f), //dxf color code 56
+ aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 57
+ aiColor4D (0.3f, 0.3f ,0.0f, 1.0f), //dxf color code 58
+ aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 59
+ aiColor4D (0.7f, 1.0f ,0.0f, 1.0f), //dxf color code 60
+ aiColor4D (0.9f, 1.0f ,0.7f, 1.0f), //dxf color code 61
+ aiColor4D (0.6f, 0.7f ,0.0f, 1.0f), //dxf color code 62
+ aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 63
+ aiColor4D (0.4f, 0.5f ,0.0f, 1.0f), //dxf color code 64
+ aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 65
+ aiColor4D (0.3f, 0.4f ,0.0f, 1.0f), //dxf color code 66
+ aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 67
+ aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 68
+ aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 69
+ aiColor4D (0.5f, 1.0f ,0.0f, 1.0f), //dxf color code 70
+ aiColor4D (0.8f, 1.0f ,0.7f, 1.0f), //dxf color code 71
+ aiColor4D (0.4f, 0.7f ,0.0f, 1.0f), //dxf color code 72
+ aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 73
+ aiColor4D (0.3f, 0.5f ,0.0f, 1.0f), //dxf color code 74
+ aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 75
+ aiColor4D (0.2f, 0.4f ,0.0f, 1.0f), //dxf color code 76
+ aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 77
+ aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 78
+ aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 79
+ aiColor4D (0.2f, 1.0f ,0.0f, 1.0f), //dxf color code 80
+ aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 81
+ aiColor4D (0.2f, 0.7f ,0.0f, 1.0f), //dxf color code 82
+ aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 83
+ aiColor4D (0.1f, 0.5f ,0.0f, 1.0f), //dxf color code 84
+ aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 85
+ aiColor4D (0.1f, 0.4f ,0.0f, 1.0f), //dxf color code 86
+ aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 87
+ aiColor4D (0.1f, 0.3f ,0.0f, 1.0f), //dxf color code 88
+ aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 89
+ aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 90
+ aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 91
+ aiColor4D (0.0f, 0.7f ,0.0f, 1.0f), //dxf color code 92
+ aiColor4D (0.5f, 0.7f ,0.5f, 1.0f), //dxf color code 93
+ aiColor4D (0.0f, 0.5f ,0.0f, 1.0f), //dxf color code 94
+ aiColor4D (0.3f, 0.5f ,0.3f, 1.0f), //dxf color code 95
+ aiColor4D (0.0f, 0.4f ,0.0f, 1.0f), //dxf color code 96
+ aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 97
+ aiColor4D (0.0f, 0.3f ,0.0f, 1.0f), //dxf color code 98
+ aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 99
+ aiColor4D (0.0f, 1.0f ,0.2f, 1.0f), //dxf color code 100
+ aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 101
+ aiColor4D (0.0f, 0.7f ,0.2f, 1.0f), //dxf color code 102
+ aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 103
+ aiColor4D (0.0f, 0.5f ,0.1f, 1.0f), //dxf color code 104
+ aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 105
+ aiColor4D (0.0f, 0.4f ,0.1f, 1.0f), //dxf color code 106
+ aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 107
+ aiColor4D (0.0f, 0.3f ,0.1f, 1.0f), //dxf color code 108
+ aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 109
+ aiColor4D (0.0f, 1.0f ,0.5f, 1.0f), //dxf color code 110
+ aiColor4D (0.7f, 1.0f ,0.8f, 1.0f), //dxf color code 111
+ aiColor4D (0.0f, 0.7f ,0.4f, 1.0f), //dxf color code 112
+ aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 113
+ aiColor4D (0.0f, 0.5f ,0.3f, 1.0f), //dxf color code 114
+ aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 115
+ aiColor4D (0.0f, 0.4f ,0.2f, 1.0f), //dxf color code 116
+ aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 117
+ aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 118
+ aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 119
+ aiColor4D (0.0f, 1.0f ,0.7f, 1.0f), //dxf color code 120
+ aiColor4D (0.7f, 1.0f ,0.9f, 1.0f), //dxf color code 121
+ aiColor4D (0.0f, 0.7f ,0.6f, 1.0f), //dxf color code 122
+ aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 123
+ aiColor4D (0.0f, 0.5f ,0.4f, 1.0f), //dxf color code 124
+ aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 125
+ aiColor4D (0.0f, 0.4f ,0.3f, 1.0f), //dxf color code 126
+ aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 127
+ aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 128
+ aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 129
+ aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 130
+ aiColor4D (0.7f, 1.0f ,1.0f, 1.0f), //dxf color code 131
+ aiColor4D (0.0f, 0.7f ,0.7f, 1.0f), //dxf color code 132
+ aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 133
+ aiColor4D (0.0f, 0.5f ,0.5f, 1.0f), //dxf color code 134
+ aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 135
+ aiColor4D (0.0f, 0.4f ,0.4f, 1.0f), //dxf color code 136
+ aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 137
+ aiColor4D (0.0f, 0.3f ,0.3f, 1.0f), //dxf color code 138
+ aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 139
+ aiColor4D (0.0f, 0.7f ,1.0f, 1.0f), //dxf color code 140
+ aiColor4D (0.7f, 0.9f ,1.0f, 1.0f), //dxf color code 141
+ aiColor4D (0.0f, 0.6f ,0.7f, 1.0f), //dxf color code 142
+ aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 143
+ aiColor4D (0.0f, 0.4f ,0.5f, 1.0f), //dxf color code 144
+ aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 145
+ aiColor4D (0.0f, 0.3f ,0.4f, 1.0f), //dxf color code 146
+ aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 147
+ aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 148
+ aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 149
+ aiColor4D (0.0f, 0.5f ,1.0f, 1.0f), //dxf color code 150
+ aiColor4D (0.7f, 0.8f ,1.0f, 1.0f), //dxf color code 151
+ aiColor4D (0.0f, 0.4f ,0.7f, 1.0f), //dxf color code 152
+ aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 153
+ aiColor4D (0.0f, 0.3f ,0.5f, 1.0f), //dxf color code 154
+ aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 155
+ aiColor4D (0.0f, 0.2f ,0.4f, 1.0f), //dxf color code 156
+ aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 157
+ aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 158
+ aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 159
+ aiColor4D (0.0f, 0.2f ,1.0f, 1.0f), //dxf color code 160
+ aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 161
+ aiColor4D (0.0f, 0.2f ,0.7f, 1.0f), //dxf color code 162
+ aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 163
+ aiColor4D (0.0f, 0.1f ,0.5f, 1.0f), //dxf color code 164
+ aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 165
+ aiColor4D (0.0f, 0.1f ,0.4f, 1.0f), //dxf color code 166
+ aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 167
+ aiColor4D (0.0f, 0.1f ,0.3f, 1.0f), //dxf color code 168
+ aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 169
+ aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 170
+ aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 171
+ aiColor4D (0.0f, 0.0f ,0.7f, 1.0f), //dxf color code 172
+ aiColor4D (0.5f, 0.5f ,0.7f, 1.0f), //dxf color code 173
+ aiColor4D (0.0f, 0.0f ,0.5f, 1.0f), //dxf color code 174
+ aiColor4D (0.3f, 0.3f ,0.5f, 1.0f), //dxf color code 175
+ aiColor4D (0.0f, 0.0f ,0.4f, 1.0f), //dxf color code 176
+ aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 177
+ aiColor4D (0.0f, 0.0f ,0.3f, 1.0f), //dxf color code 178
+ aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 179
+ aiColor4D (0.2f, 0.0f ,1.0f, 1.0f), //dxf color code 180
+ aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 181
+ aiColor4D (0.2f, 0.0f ,0.7f, 1.0f), //dxf color code 182
+ aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 183
+ aiColor4D (0.1f, 0.0f ,0.5f, 1.0f), //dxf color code 184
+ aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 185
+ aiColor4D (0.1f, 0.0f ,0.4f, 1.0f), //dxf color code 186
+ aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 187
+ aiColor4D (0.1f, 0.0f ,0.3f, 1.0f), //dxf color code 188
+ aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 189
+ aiColor4D (0.5f, 0.0f ,1.0f, 1.0f), //dxf color code 190
+ aiColor4D (0.8f, 0.7f ,1.0f, 1.0f), //dxf color code 191
+ aiColor4D (0.4f, 0.0f ,0.7f, 1.0f), //dxf color code 192
+ aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 193
+ aiColor4D (0.3f, 0.0f ,0.5f, 1.0f), //dxf color code 194
+ aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 195
+ aiColor4D (0.2f, 0.0f ,0.4f, 1.0f), //dxf color code 196
+ aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 197
+ aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 198
+ aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 199
+ aiColor4D (0.7f, 0.0f ,1.0f, 1.0f), //dxf color code 200
+ aiColor4D (0.9f, 0.7f ,1.0f, 1.0f), //dxf color code 201
+ aiColor4D (0.6f, 0.0f ,0.7f, 1.0f), //dxf color code 202
+ aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 203
+ aiColor4D (0.4f, 0.0f ,0.5f, 1.0f), //dxf color code 204
+ aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 205
+ aiColor4D (0.3f, 0.0f ,0.4f, 1.0f), //dxf color code 206
+ aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 207
+ aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 208
+ aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 209
+ aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 210
+ aiColor4D (1.0f, 0.7f ,1.0f, 1.0f), //dxf color code 211
+ aiColor4D (0.7f, 0.0f ,0.7f, 1.0f), //dxf color code 212
+ aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 213
+ aiColor4D (0.5f, 0.0f ,0.5f, 1.0f), //dxf color code 214
+ aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 215
+ aiColor4D (0.4f, 0.0f ,0.4f, 1.0f), //dxf color code 216
+ aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 217
+ aiColor4D (0.3f, 0.0f ,0.3f, 1.0f), //dxf color code 218
+ aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 219
+ aiColor4D (1.0f, 0.0f ,0.7f, 1.0f), //dxf color code 220
+ aiColor4D (1.0f, 0.7f ,0.9f, 1.0f), //dxf color code 221
+ aiColor4D (0.7f, 0.0f ,0.6f, 1.0f), //dxf color code 222
+ aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 223
+ aiColor4D (0.5f, 0.0f ,0.4f, 1.0f), //dxf color code 224
+ aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 225
+ aiColor4D (0.4f, 0.0f ,0.3f, 1.0f), //dxf color code 226
+ aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 227
+ aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 228
+ aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 229
+ aiColor4D (1.0f, 0.0f ,0.5f, 1.0f), //dxf color code 230
+ aiColor4D (1.0f, 0.7f ,0.8f, 1.0f), //dxf color code 231
+ aiColor4D (0.7f, 0.0f ,0.4f, 1.0f), //dxf color code 232
+ aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 233
+ aiColor4D (0.5f, 0.0f ,0.3f, 1.0f), //dxf color code 234
+ aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 235
+ aiColor4D (0.4f, 0.0f ,0.2f, 1.0f), //dxf color code 236
+ aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 237
+ aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 238
+ aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 239
+ aiColor4D (1.0f, 0.0f ,0.2f, 1.0f), //dxf color code 240
+ aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 241
+ aiColor4D (0.7f, 0.0f ,0.2f, 1.0f), //dxf color code 242
+ aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 243
+ aiColor4D (0.5f, 0.0f ,0.1f, 1.0f), //dxf color code 244
+ aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 245
+ aiColor4D (0.4f, 0.0f ,0.1f, 1.0f), //dxf color code 246
+ aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 247
+ aiColor4D (0.3f, 0.0f ,0.1f, 1.0f), //dxf color code 248
+ aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 249
+ aiColor4D (0.2f, 0.2f ,0.2f, 1.0f), //dxf color code 250
+ aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 251
+ aiColor4D (0.4f, 0.4f ,0.4f, 1.0f), //dxf color code 252
+ aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 253
+ aiColor4D (0.7f, 0.7f ,0.7f, 1.0f), //dxf color code 254
+ aiColor4D (1.0f, 1.0f ,1.0f, 1.0f) //dxf color code 255
};
#define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
@@ -372,8 +613,12 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
// XXX order
aiMatrix4x4 trafo, tmp;
aiMatrix4x4::Translation(-bl_src.base,trafo);
- trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
+ //Need to translate position before scaling the insert
+ //otherwise the position ends up being the position*scaling
+ //STH 2024.01.17
trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
+ trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
+ //trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
// XXX rotation currently ignored - I didn't find an appropriate sample model.
if (insert.angle != 0.f) {
diff --git a/code/AssetLib/DXF/DXFLoader.h b/code/AssetLib/DXF/DXFLoader.h
index 89a0b79c2..8cc798fbc 100644
--- a/code/AssetLib/DXF/DXFLoader.h
+++ b/code/AssetLib/DXF/DXFLoader.h
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
#include