Compare commits

..

No commits in common. "master" and "kimkulling/fbx_check_bone_name_issue-5085" have entirely different histories.

1279 changed files with 50900 additions and 135830 deletions

View File

@ -7,139 +7,14 @@ on:
branches: [ master ] branches: [ master ]
permissions: permissions:
contents: write # to fetch code (actions/checkout),and release contents: read # to fetch code (actions/checkout)
jobs: jobs:
build: job:
name: ${{ matrix.name }}-build-and-test name: ${{ matrix.name }}-build-and-test
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix:
name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.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-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') && 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" >> $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: matrix:
name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++, ubuntu-gcc-hunter, macos-clang-hunter, windows-msvc-hunter] 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. # For Windows msvc, for Linux and macOS let's use the clang compiler, use gcc for Linux.
@ -170,23 +45,90 @@ jobs:
os: windows-latest os: windows-latest
toolchain: ninja-vs-win64-cxx17 toolchain: ninja-vs-win64-cxx17
needs: [create-release]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps: steps:
- uses: softprops/action-gh-release@v2 - uses: actions/checkout@v3
with: with:
name: create-release submodules: true
- id: upload-url
- 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@v3
with:
repository: cpp-pm/polly
path: cmake/polly
- name: Remove contrib directory for Hunter builds
if: contains(matrix.name, 'hunter')
uses: JesseTG/rm@v1.0.3
with:
path: contrib
- 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: | run: |
echo "url=$(cat create-release/release_upload_url.txt)" >> $GITHUB_OUTPUT curl -s -o DXSDK_Jun10.exe --location https://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe
- uses: actions/download-artifact@v4 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: with:
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}' name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
- uses: actions/upload-release-asset@v1 path: build/bin
env:
GITHUB_TOKEN: '${{secrets.GITHUB_TOKEN}}'
with:
files: |
*.zip

View File

@ -19,7 +19,7 @@ jobs:
dry-run: false dry-run: false
language: c++ language: c++
- name: Upload Crash - name: Upload Crash
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
if: failure() && steps.build.outcome == 'success' if: failure() && steps.build.outcome == 'success'
with: with:
name: artifacts name: artifacts

View File

@ -1,51 +0,0 @@
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.2
with:
path: packaging/windows-innosetup/script_x64.iss
options: /O+

View File

@ -14,7 +14,7 @@ jobs:
name: adress-sanitizer name: adress-sanitizer
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: lukka/get-cmake@latest - uses: lukka/get-cmake@latest
- uses: lukka/set-shell-env@v1 - uses: lukka/set-shell-env@v1
with: with:
@ -38,7 +38,7 @@ jobs:
name: undefined-behavior-sanitizer name: undefined-behavior-sanitizer
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: lukka/get-cmake@latest - uses: lukka/get-cmake@latest
- uses: lukka/set-shell-env@v1 - uses: lukka/set-shell-env@v1
with: with:
@ -46,7 +46,7 @@ jobs:
CC: clang CC: clang
- name: configure and build - name: configure and build
uses: lukka/run-cmake@v3 uses: lukka/run-cmake@v2
with: with:
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt' cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt'
@ -62,7 +62,7 @@ jobs:
name: printf-sanitizer name: printf-sanitizer
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: run scan_printf script - name: run scan_printf script
run: ./scripts/scan_printf.sh run: ./scripts/scan_printf.sh

4
.gitignore vendored
View File

@ -120,7 +120,3 @@ tools/assimp_qt_viewer/ui_mainwindow.h
#Generated directory #Generated directory
generated/* generated/*
# 3rd party cloned repos/tarballs etc
# tinyusdz repo, automatically cloned via CMake
contrib/tinyusdz/autoclone

View File

@ -43,7 +43,6 @@ cd assimp
cmake CMakeLists.txt cmake CMakeLists.txt
cmake --build . 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 ### Build instructions for Windows with Visual-Studio

View File

@ -1,6 +1,6 @@
# Open Asset Import Library (assimp) # Open Asset Import Library (assimp)
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Copyright (c) 2006-2024, assimp team # Copyright (c) 2006-2023, assimp team
# #
# All rights reserved. # All rights reserved.
# #
@ -38,25 +38,9 @@ SET(CMAKE_POLICY_DEFAULT_CMP0012 NEW)
SET(CMAKE_POLICY_DEFAULT_CMP0074 NEW) SET(CMAKE_POLICY_DEFAULT_CMP0074 NEW)
SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW) SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW)
CMAKE_MINIMUM_REQUIRED( VERSION 3.22 ) CMAKE_MINIMUM_REQUIRED( VERSION 3.10 )
# Experimental USD importer: disabled, need to opt-in # Disabled importers: m3d for 5.1
# 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)
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 or later
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER) ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER)
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER) ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER)
# Toggles the use of the hunter package manager # Toggles the use of the hunter package manager
@ -65,13 +49,14 @@ option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
IF(ASSIMP_HUNTER_ENABLED) IF(ASSIMP_HUNTER_ENABLED)
include("cmake-modules/HunterGate.cmake") include("cmake-modules/HunterGate.cmake")
HunterGate( HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.25.5.tar.gz" URL "https://github.com/cpp-pm/hunter/archive/v0.24.0.tar.gz"
SHA1 "a20151e4c0740ee7d0f9994476856d813cdead29" SHA1 "a3d7f4372b1dcd52faa6ff4a3bd5358e1d0e5efd"
) )
add_definitions(-DASSIMP_USE_HUNTER) add_definitions(-DASSIMP_USE_HUNTER)
ENDIF() ENDIF()
PROJECT(Assimp VERSION 5.4.3) PROJECT(Assimp VERSION 5.2.5)
# All supported options ############################################### # All supported options ###############################################
@ -147,35 +132,35 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH
IF (WIN32) IF (WIN32)
OPTION( ASSIMP_BUILD_ZLIB OPTION( ASSIMP_BUILD_ZLIB
"Build your zlib" "Build your own zlib"
ON ON
) )
ELSE() ELSE()
OPTION( ASSIMP_BUILD_ZLIB OPTION( ASSIMP_BUILD_ZLIB
"Build your zlib" "Build your own zlib"
OFF ON
) )
ENDIF() ENDIF()
IF (WIN32) IF (WIN32)
# Use a subset of Windows.h # Use subset of Windows.h
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN ) ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
IF(MSVC) IF(MSVC)
OPTION( ASSIMP_INSTALL_PDB OPTION( ASSIMP_INSTALL_PDB
"Create MSVC debug symbol files and add to Install target." "Install MSVC debug files."
ON ) ON )
IF(NOT (MSVC_VERSION LESS 1900)) IF(NOT (MSVC_VERSION LESS 1900))
# Multibyte character set has been deprecated since at least MSVC2015 (possibly earlier) # Multibyte character set is deprecated since at least MSVC2015 (possibly earlier)
ADD_DEFINITIONS( -DUNICODE -D_UNICODE ) ADD_DEFINITIONS( -DUNICODE -D_UNICODE )
ENDIF() ENDIF()
# Link statically against c/c++ lib to avoid missing redistributable such as # Link statically against c/c++ lib to avoid missing redistriburable such as
# "VCRUNTIME140.dll not found. Try reinstalling the app.", but give users # "VCRUNTIME140.dll not found. Try reinstalling the app.", but give users
# a choice to opt for the shared runtime if they want. # a choice to opt for the shared runtime if they want.
option(USE_STATIC_CRT "Link against the static runtime libraries." OFF) option(USE_STATIC_CRT "Link against the static runtime libraries." OFF)
# The CMAKE_CXX_FLAGS vars can be overridden by some Visual Studio generators, so we use an alternative # The CMAKE_CXX_FLAGS vars can be overriden by some Visual Studio generators, so we use an alternative
# global method here: # global method here:
if (${USE_STATIC_CRT}) if (${USE_STATIC_CRT})
add_compile_options( add_compile_options(
@ -216,9 +201,12 @@ SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VER
SET (ASSIMP_SOVERSION 5) SET (ASSIMP_SOVERSION 5)
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" ) SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
if(NOT ASSIMP_HUNTER_ENABLED)
# Enable C++17 support globally
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
endif()
IF(NOT ASSIMP_IGNORE_GIT_HASH) IF(NOT ASSIMP_IGNORE_GIT_HASH)
# Get the current working branch # Get the current working branch
@ -265,24 +253,21 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
IF( UNIX ) IF( UNIX )
# Use GNUInstallDirs for Unix predefined directories # Use GNUInstallDirs for Unix predefined directories
INCLUDE(GNUInstallDirs) 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( ${OPERATING_SYSTEM} MATCHES "Android")
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit Linux ELSE()
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 ) ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF() ENDIF()
# Grouped compiler settings ######################################## # Grouped compiler settings ########################################
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW AND NOT HAIKU) IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW)
IF(NOT ASSIMP_HUNTER_ENABLED) IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON) SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
ENDIF() ENDIF()
IF(CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 13)
MESSAGE(STATUS "GCC13 detected disabling \"-Wdangling-reference\" in Cpp files as it appears to be a false positive")
ADD_COMPILE_OPTIONS("$<$<COMPILE_LANGUAGE:CXX>:-Wno-dangling-reference>")
ENDIF()
# hide all not-exported symbols # hide all not-exported symbols
IF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "mips64" ) IF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "mips64" )
SET(CMAKE_CXX_FLAGS "-mxgot -fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}") SET(CMAKE_CXX_FLAGS "-mxgot -fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
@ -296,29 +281,23 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW AND NOT HAIKU)
ELSEIF(MSVC) ELSEIF(MSVC)
# enable multi-core compilation with MSVC # enable multi-core compilation with MSVC
IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
ADD_COMPILE_OPTIONS(/bigobj) ADD_COMPILE_OPTIONS(/bigobj /W4 /WX )
ELSE() # msvc ELSE() # msvc
ADD_COMPILE_OPTIONS(/MP /bigobj) ADD_COMPILE_OPTIONS(/MP /bigobj /W4 /WX)
ENDIF() ENDIF()
# disable "elements of array '' will be default initialized" warning on MSVC2013 # disable "elements of array '' will be default initialized" warning on MSVC2013
IF(MSVC12) IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351) ADD_COMPILE_OPTIONS(/wd4351)
ENDIF() ENDIF()
# supress warning for double to float conversion if Double precision is activated # supress warning for double to float conversion if Double precission is activated
ADD_COMPILE_OPTIONS(/wd4244) ADD_COMPILE_OPTIONS(/wd4244)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od") SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
# Allow user to disable PDBs SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
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") SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
elseif((GENERATOR_IS_MULTI_CONFIG) OR (CMAKE_BUILD_TYPE MATCHES Release))
message("-- MSVC PDB generation disabled. Release binary will not be debuggable.")
endif()
# Source code is encoded in UTF-8
ADD_COMPILE_OPTIONS(/source-charset:utf-8)
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
IF(NOT ASSIMP_HUNTER_ENABLED) IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON) SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
ENDIF() ENDIF()
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" ) SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
@ -334,9 +313,9 @@ ELSEIF( MINGW )
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}") SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
ENDIF() ENDIF()
IF (CMAKE_BUILD_TYPE STREQUAL "Debug") IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wno-dangling-reference -Wall -Wno-long-long -Wa,-mbig-obj -g ${CMAKE_CXX_FLAGS}") SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -g ${CMAKE_CXX_FLAGS}")
ELSE() ELSE()
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wno-dangling-reference -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}") SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
ENDIF() ENDIF()
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}") SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
ENDIF() ENDIF()
@ -348,12 +327,12 @@ IF ( IOS AND NOT ASSIMP_HUNTER_ENABLED)
ELSE() ELSE()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
# Experimental for pdb generation
ENDIF() ENDIF()
ENDIF() ENDIF()
IF (ASSIMP_COVERALLS) IF (ASSIMP_COVERALLS)
MESSAGE(STATUS "Coveralls enabled") MESSAGE(STATUS "Coveralls enabled")
INCLUDE(Coveralls) INCLUDE(Coveralls)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") 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") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
@ -361,14 +340,12 @@ ENDIF()
IF (ASSIMP_ASAN) IF (ASSIMP_ASAN)
MESSAGE(STATUS "AddressSanitizer enabled") MESSAGE(STATUS "AddressSanitizer enabled")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
ENDIF() ENDIF()
IF (ASSIMP_UBSAN) IF (ASSIMP_UBSAN)
MESSAGE(STATUS "Undefined Behavior sanitizer enabled") MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
ENDIF() ENDIF()
@ -475,7 +452,6 @@ configure_package_config_file(
INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}" INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}"
) )
if(ASSIMP_INSTALL)
install( install(
FILES "${PROJECT_CONFIG}" "${VERSION_CONFIG}" FILES "${PROJECT_CONFIG}" "${VERSION_CONFIG}"
DESTINATION "${CONFIG_INSTALL_DIR}" DESTINATION "${CONFIG_INSTALL_DIR}"
@ -488,7 +464,6 @@ if(ASSIMP_INSTALL)
DESTINATION "${CONFIG_INSTALL_DIR}" DESTINATION "${CONFIG_INSTALL_DIR}"
COMPONENT ${LIBASSIMP-DEV_COMPONENT} COMPONENT ${LIBASSIMP-DEV_COMPONENT}
) )
endif()
IF( ASSIMP_BUILD_DOCS ) IF( ASSIMP_BUILD_DOCS )
ADD_SUBDIRECTORY(doc) ADD_SUBDIRECTORY(doc)
@ -506,7 +481,7 @@ IF(ASSIMP_HUNTER_ENABLED)
set(ASSIMP_BUILD_MINIZIP TRUE) set(ASSIMP_BUILD_MINIZIP TRUE)
ELSE() ELSE()
# If the zlib is already found outside, add an export in case assimpTargets can't find it. # If the zlib is already found outside, add an export in case assimpTargets can't find it.
IF( ZLIB_FOUND AND ASSIMP_INSTALL) IF( ZLIB_FOUND )
INSTALL( TARGETS zlib zlibstatic INSTALL( TARGETS zlib zlibstatic
EXPORT "${TARGETS_EXPORT_NAME}") EXPORT "${TARGETS_EXPORT_NAME}")
ENDIF() ENDIF()
@ -588,9 +563,9 @@ SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL
) )
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER) 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 # pick the correct prebuilt library
IF(MSVC143) IF(MSVC143)
SET(C4D_LIB_POSTFIX "_2022") SET(C4D_LIB_POSTFIX "_2022")
@ -608,7 +583,7 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
SET(C4D_LIB_POSTFIX "_2010") SET(C4D_LIB_POSTFIX "_2010")
ELSE() ELSE()
MESSAGE( FATAL_ERROR MESSAGE( FATAL_ERROR
"C4D for Windows is currently only supported with MSVC 10, 11, 12, 14, 14.2, 14.3" "C4D is currently only supported with MSVC 10, 11, 12, 14, 14.2, 14.3"
) )
ENDIF() ENDIF()
@ -626,30 +601,15 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
# winsock and winmm are necessary (and undocumented) dependencies of Cineware SDK because # winsock and winmm are necessary (and undocumented) dependencies of Cineware SDK because
# it can be used to communicate with a running Cinema 4D instance # it can be used to communicate with a running Cinema 4D instance
SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib) SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib)
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"
)
SET(C4D_RELEASE_LIBRARIES
"${C4D_LIB_BASE_PATH}/release/libcinewarelib.a"
"${C4D_LIB_BASE_PATH}/release/libjpeglib.a"
)
ELSE () ELSE ()
MESSAGE( FATAL_ERROR MESSAGE( FATAL_ERROR
"C4D is currently only available on Windows and macOS with Cineware SDK installed in contrib/Cineware" "C4D is currently only available on Windows with Cineware SDK installed in contrib/Cineware"
) )
ENDIF () ENDIF ()
ELSE () ELSE ()
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER ) ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
ENDIF () ENDIF ()
if(ASSIMP_BUILD_DRACO_STATIC)
set(ASSIMP_BUILD_DRACO ON)
endif()
# Draco requires cmake 3.12 # Draco requires cmake 3.12
IF (DEFINED CMAKE_VERSION AND "${CMAKE_VERSION}" VERSION_LESS "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")
@ -659,7 +619,7 @@ ELSE()
IF ( ASSIMP_BUILD_DRACO ) IF ( ASSIMP_BUILD_DRACO )
# Primarily for glTF v2 # Primarily for glTF v2
# Enable Draco glTF feature set # Enable Draco glTF feature set
set(DRACO_GLTF_BITSTREAM ON CACHE BOOL "" FORCE) set(DRACO_GLTF ON CACHE BOOL "" FORCE)
# Disable unnecessary or omitted components # Disable unnecessary or omitted components
set(DRACO_JS_GLUE OFF CACHE BOOL "" FORCE) set(DRACO_JS_GLUE OFF CACHE BOOL "" FORCE)
set(DRACO_WASM OFF CACHE BOOL "" FORCE) set(DRACO_WASM OFF CACHE BOOL "" FORCE)
@ -685,29 +645,22 @@ ELSE()
"-Wno-sign-compare" "-Wno-sign-compare"
"-Wno-unused-local-typedefs" "-Wno-unused-local-typedefs"
) )
if(NOT ASSIMP_BUILD_DRACO_STATIC)
# Draco 1.4.1 does not explicitly export any symbols under GCC/clang # Draco 1.4.1 does not explicitly export any symbols under GCC/clang
list(APPEND DRACO_CXX_FLAGS list(APPEND DRACO_CXX_FLAGS
"-fvisibility=default" "-fvisibility=default"
) )
endif()
ENDIF() ENDIF()
# Don't build or install all of Draco by default # Don't build or install all of Draco by default
ADD_SUBDIRECTORY( "contrib/draco" EXCLUDE_FROM_ALL ) ADD_SUBDIRECTORY( "contrib/draco" EXCLUDE_FROM_ALL )
if(ASSIMP_BUILD_DRACO_STATIC)
set_property(DIRECTORY "contrib/draco" PROPERTY BUILD_SHARED_LIBS OFF)
endif()
if(MSVC OR WIN32) if(MSVC OR WIN32)
set(draco_LIBRARIES "draco") set(draco_LIBRARIES "draco")
else() else()
if(ASSIMP_BUILD_DRACO_STATIC) if(BUILD_SHARED_LIBS)
set(draco_LIBRARIES "draco_static")
else()
set(draco_LIBRARIES "draco_shared") set(draco_LIBRARIES "draco_shared")
else()
set(draco_LIBRARIES "draco_static")
endif() endif()
endif() endif()
@ -730,7 +683,6 @@ ELSE()
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 # This is probably wrong
if (ASSIMP_INSTALL)
INSTALL( TARGETS ${draco_LIBRARIES} INSTALL( TARGETS ${draco_LIBRARIES}
EXPORT "${TARGETS_EXPORT_NAME}" EXPORT "${TARGETS_EXPORT_NAME}"
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR} LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
@ -740,7 +692,7 @@ ELSE()
COMPONENT ${LIBASSIMP_COMPONENT} COMPONENT ${LIBASSIMP_COMPONENT}
INCLUDES DESTINATION include INCLUDES DESTINATION include
) )
endif()
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF() ENDIF()
@ -784,8 +736,8 @@ IF ( ASSIMP_INSTALL )
ENDIF() ENDIF()
CONFIGURE_FILE( CONFIGURE_FILE(
${CMAKE_CURRENT_LIST_DIR}/include/assimp/revision.h.in ${CMAKE_CURRENT_LIST_DIR}/revision.h.in
${CMAKE_CURRENT_BINARY_DIR}/include/assimp/revision.h ${CMAKE_CURRENT_BINARY_DIR}/revision.h
) )
CONFIGURE_FILE( CONFIGURE_FILE(
@ -826,7 +778,7 @@ IF ( ASSIMP_INSTALL )
SET(CPACK_DEBIAN_PACKAGE_SECTION "libs" ) SET(CPACK_DEBIAN_PACKAGE_SECTION "libs" )
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}") SET(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}")
SET(CPACK_DEBIAN_PACKAGE_SUGGESTS) SET(CPACK_DEBIAN_PACKAGE_SUGGESTS)
SET(CPACK_DEBIAN_PACKAGE_NAME "assimp") SET(cPACK_DEBIAN_PACKAGE_NAME "assimp")
SET(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/gtest contrib/zlib workspaces test doc obj samples packaging) SET(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/gtest contrib/zlib workspaces test doc obj samples packaging)
SET(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force) SET(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
SET(CPACK_DEBIAN_CHANGELOG) SET(CPACK_DEBIAN_CHANGELOG)

View File

@ -1,12 +1,16 @@
FROM ubuntu:22.04 FROM ubuntu:14.04
RUN apt-get update && apt-get install --no-install-recommends -y ninja-build \ RUN apt-get update && apt-get install -y \
git cmake build-essential software-properties-common git cmake build-essential software-properties-common
RUN add-apt-repository ppa:ubuntu-toolchain-r/test && apt-get update RUN add-apt-repository ppa:ubuntu-toolchain-r/test && apt-get update && apt-get install -y gcc-4.9 g++-4.9 && \
cd /usr/bin && \
rm gcc g++ cpp && \
ln -s gcc-4.9 gcc && \
ln -s g++-4.9 g++ && \
ln -s cpp-4.9 cpp
WORKDIR /opt WORKDIR /opt
RUN apt install zlib1g-dev
# Build Assimp # Build Assimp
RUN git clone https://github.com/assimp/assimp.git /opt/assimp RUN git clone https://github.com/assimp/assimp.git /opt/assimp
@ -15,8 +19,7 @@ WORKDIR /opt/assimp
RUN git checkout master \ RUN git checkout master \
&& mkdir build && cd build && \ && mkdir build && cd build && \
cmake -G 'Ninja' \ cmake \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DASSIMP_BUILD_ASSIMP_TOOLS=ON \
.. && \ .. && \
ninja -j4 && ninja install make && make install

View File

@ -6,36 +6,42 @@ Open Asset Import Library is a library to load various 3d file formats into a sh
### Current project status ### ### Current project status ###
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp) [![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg) ![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
<a href="https://scan.coverity.com/projects/5607">
<img alt="Coverity Scan Build Status"
src="https://scan.coverity.com/projects/5607/badge.svg"/>
</a>
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open") [![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
<br> <br>
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS. APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
Additionally, assimp features various __mesh post-processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more. 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.
### Documentation ### ### Latest Doc's ###
Read [our latest documentation](https://assimp-docs.readthedocs.io/en/latest/). Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
### Pre-built binaries ### ### Prebuild binaries ###
Download binaries from [our Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib). Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
### Test data ### If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
Clone [our model database](https://github.com/assimp/assimp-mdb).
### Communities ### ### Communities ###
- Ask questions at [the Assimp Discussion Board](https://github.com/assimp/assimp/discussions). - Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
- Find us on [https://discord.gg/s9KJfaem](https://discord.gg/kKazXMXDy2) - Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
- 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). - 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) - Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
#### Supported file formats #### #### Supported file formats ####
See [the complete list of supported formats](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md). You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
### Building ### ### Building ###
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. Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. 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 ### ### Ports ###
* [Android](port/AndroidJNI/README.md) * [Android](port/AndroidJNI/README.md)
@ -52,21 +58,20 @@ Start by reading [our build instructions](https://github.com/assimp/assimp/blob/
### Other tools ### ### Other tools ###
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities. [open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on 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 #### #### Repository structure ####
Open Asset Import Library is implemented in C++. The directory structure looks like this: Open Asset Import Library is implemented in C++. The directory structure looks like:
/code Source code /code Source code
/contrib Third-party libraries /contrib Third-party libraries
/doc Documentation (doxysource and pre-compiled docs) /doc Documentation (doxysource and pre-compiled docs)
/fuzz Contains the test code for the Google Fuzzer project /fuzz Contains the test-code for the Google-Fuzzer project
/include Public header C and C++ header files /include Public header C and C++ header files
/scripts Scripts are used to generate the loading code for some formats /scripts Scripts used to generate the loading code for some formats
/port Ports to other languages and scripts to maintain those. /port Ports to other languages and scripts to maintain those.
/test Unit- and regression tests, test suite of models /test Unit- and regression tests, test suite of models
/tools Tools (old assimp viewer, command line `assimp`) /tools Tools (old assimp viewer, command line `assimp`)
/samples A small number of samples to illustrate possible use cases for Assimp /samples A small number of samples to illustrate possible use-cases for Assimp
The source code is organized in the following way: The source code is organized in the following way:
@ -74,9 +79,9 @@ The source code is organized in the following way:
code/CApi Special implementations which are only used for the C-API code/CApi Special implementations which are only used for the C-API
code/Geometry A collection of geometry tools code/Geometry A collection of geometry tools
code/Material The material system code/Material The material system
code/PBR An exporter for physical-based models code/PBR An exporter for physical based models
code/PostProcessing The post-processing steps code/PostProcessing The post-processing steps
code/AssetLib/<FormatName> Implementation for import and export of the format code/AssetLib/<FormatName> Implementation for import and export for the format
### Contributing ### ### Contributing ###
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
@ -113,4 +118,4 @@ and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you ma
For the legal details, see the `LICENSE` file. For the legal details, see the `LICENSE` file.
### Why this name ### ### Why this name ###
Sorry, we're germans :-), no English native speakers ... Sorry, we're germans :-), no english native speakers ...

View File

@ -22,9 +22,38 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # 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) 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 include(CMakeParseArguments) # cmake_parse_arguments
option(HUNTER_STATUS_PRINT "Print working status" ON) option(HUNTER_STATUS_PRINT "Print working status" ON)

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -52,9 +52,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cctype> #include <cctype>
#include <memory> #include <memory>
namespace Assimp { using namespace Assimp;
static constexpr unsigned int NotSet = 0xcdcdcdcd; static const unsigned int NotSet = 0xcdcdcdcd;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup final material indices, generae a default material if necessary // Setup final material indices, generae a default material if necessary
@ -593,7 +593,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
// Cameras or lights define their transformation in their parent node and in the // Cameras or lights define their transformation in their parent node and in the
// corresponding light or camera chunks. However, we read and process the latter // corresponding light or camera chunks. However, we read and process the latter
// to be able to return valid cameras/lights even if no scenegraph is given. // to to be able to return valid cameras/lights even if no scenegraph is given.
for (unsigned int n = 0; n < pcSOut->mNumCameras; ++n) { for (unsigned int n = 0; n < pcSOut->mNumCameras; ++n) {
if (pcSOut->mCameras[n]->mName == pcOut->mName) { if (pcSOut->mCameras[n]->mName == pcOut->mName) {
pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f, 0.f, 1.f); pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f, 0.f, 1.f);
@ -643,17 +643,11 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
} }
// Allocate storage for children // Allocate storage for children
const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size()); pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
pcOut->mNumChildren = size;
if (size == 0) {
return;
}
pcOut->mChildren = new aiNode *[pcIn->mChildren.size()]; pcOut->mChildren = new aiNode *[pcIn->mChildren.size()];
// Recursively process all children // Recursively process all children
const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
for (unsigned int i = 0; i < size; ++i) { for (unsigned int i = 0; i < size; ++i) {
pcOut->mChildren[i] = new aiNode(); pcOut->mChildren[i] = new aiNode();
pcOut->mChildren[i]->mParent = pcOut; pcOut->mChildren[i]->mParent = pcOut;
@ -715,7 +709,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
pcNode->mNumMeshes = 1; pcNode->mNumMeshes = 1;
// Build a name for the node // Build a name for the node
pcNode->mName.length = ai_snprintf(pcNode->mName.data, AI_MAXLEN, "3DSMesh_%u", i); pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u", i);
} }
// Build dummy nodes for all cameras // Build dummy nodes for all cameras
@ -811,6 +805,4 @@ void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
} }
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -52,7 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/Exporter.hpp> #include <assimp/Exporter.hpp>
#include <assimp/Exceptional.h>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <memory> #include <memory>

View File

@ -2,7 +2,8 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -56,7 +57,8 @@ struct aiNode;
struct aiMaterial; struct aiMaterial;
struct aiMesh; struct aiMesh;
namespace Assimp { namespace Assimp
{
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/** /**
@ -86,7 +88,7 @@ private:
std::map<const aiNode*, aiMatrix4x4> trafos; std::map<const aiNode*, aiMatrix4x4> trafos;
using MeshesByNodeMap = std::multimap<const aiNode*, unsigned int>; typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
MeshesByNodeMap meshes; MeshesByNodeMap meshes;
}; };

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -365,13 +365,14 @@ struct Texture {
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
#endif // _MSC_VER #endif // _MSC_VER
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure representing a 3ds material */ /** Helper structure representing a 3ds material */
struct Material { struct Material {
//! Default constructor has been deleted //! Default constructor has been deleted
Material() : Material() :
mName(), mName(),
mDiffuse(0.6f, 0.6f, 0.6f), mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
mSpecularExponent(ai_real(0.0)), mSpecularExponent(ai_real(0.0)),
mShininessStrength(ai_real(1.0)), mShininessStrength(ai_real(1.0)),
mShading(Discreet3DS::Gouraud), mShading(Discreet3DS::Gouraud),
@ -384,7 +385,7 @@ struct Material {
//! Constructor with explicit name //! Constructor with explicit name
explicit Material(const std::string &name) : explicit Material(const std::string &name) :
mName(name), mName(name),
mDiffuse(0.6f, 0.6f, 0.6f), mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
mSpecularExponent(ai_real(0.0)), mSpecularExponent(ai_real(0.0)),
mShininessStrength(ai_real(1.0)), mShininessStrength(ai_real(1.0)),
mShading(Discreet3DS::Gouraud), mShading(Discreet3DS::Gouraud),

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -54,9 +54,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
namespace Assimp { using namespace Assimp;
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"Discreet 3DS Importer", "Discreet 3DS Importer",
"", "",
"", "",
@ -103,6 +103,10 @@ Discreet3DSImporter::Discreet3DSImporter() :
// empty // empty
} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
Discreet3DSImporter::~Discreet3DSImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@ -365,7 +369,7 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
// IMPLEMENTATION NOTE; // IMPLEMENTATION NOTE;
// Cameras or lights define their transformation in their parent node and in the // Cameras or lights define their transformation in their parent node and in the
// corresponding light or camera chunks. However, we read and process the latter // corresponding light or camera chunks. However, we read and process the latter
// to be able to return valid cameras/lights even if no scenegraph is given. // to to be able to return valid cameras/lights even if no scenegraph is given.
// get chunk type // get chunk type
switch (chunk.Flag) { switch (chunk.Flag) {
@ -1335,6 +1339,4 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
(void)bGamma; (void)bGamma;
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -59,6 +59,7 @@ struct aiNode;
namespace Assimp { namespace Assimp {
using namespace D3DS; using namespace D3DS;
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
@ -67,7 +68,7 @@ using namespace D3DS;
class Discreet3DSImporter : public BaseImporter { class Discreet3DSImporter : public BaseImporter {
public: public:
Discreet3DSImporter(); Discreet3DSImporter();
~Discreet3DSImporter() override = default; ~Discreet3DSImporter() override;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -57,7 +57,6 @@ enum class ResourceType {
RT_BaseMaterials, RT_BaseMaterials,
RT_EmbeddedTexture2D, RT_EmbeddedTexture2D,
RT_Texture2DGroup, RT_Texture2DGroup,
RT_ColorGroup,
RT_Unknown RT_Unknown
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...) }; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
@ -118,21 +117,6 @@ public:
} }
}; };
class ColorGroup : public Resource {
public:
std::vector<aiColor4D> mColors;
ColorGroup(int id) :
Resource(id){
// empty
}
~ColorGroup() override = default;
ResourceType getType() const override {
return ResourceType::RT_ColorGroup;
}
};
class BaseMaterials : public Resource { class BaseMaterials : public Resource {
public: public:
std::vector<unsigned int> mMaterialIndex; std::vector<unsigned int> mMaterialIndex;

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -98,11 +98,6 @@ namespace XmlTag {
const char *const texture_cuurd_u = "u"; const char *const texture_cuurd_u = "u";
const char *const texture_cuurd_v = "v"; 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 // Meta info tags
const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml"; const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels"; const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -249,10 +249,10 @@ void D3MFExporter::writeBaseMaterials() {
if (color.r <= 1 && color.g <= 1 && color.b <= 1 && color.a <= 1) { if (color.r <= 1 && color.g <= 1 && color.b <= 1 && color.a <= 1) {
hexDiffuseColor = ai_rgba2hex( hexDiffuseColor = ai_rgba2hex(
(int)(((ai_real)color.r) * 255), (int)((ai_real)color.r) * 255,
(int)(((ai_real)color.g) * 255), (int)((ai_real)color.g) * 255,
(int)(((ai_real)color.b) * 255), (int)((ai_real)color.b) * 255,
(int)(((ai_real)color.a) * 255), (int)((ai_real)color.a) * 255,
true); true);
} else { } else {

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -68,7 +68,7 @@ namespace Assimp {
using namespace D3MF; using namespace D3MF;
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"3mf Importer", "3mf Importer",
"", "",
"", "",
@ -81,17 +81,16 @@ static constexpr aiImporterDesc desc = {
"3mf" "3mf"
}; };
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool ) const { D3MFImporter::D3MFImporter() = default;
D3MFImporter::~D3MFImporter() = default;
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) { if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
return false; return false;
} }
static const char *const ModelRef = "3D/3dmodel.model"; D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
ZipArchiveIOSystem archive(pIOHandler, filename); return opcPackage.validate();
if (!archive.Exists(ModelRef)) {
return false;
}
return true;
} }
void D3MFImporter::SetupProperties(const Importer*) { void D3MFImporter::SetupProperties(const Importer*) {

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -56,10 +56,10 @@ namespace Assimp {
class D3MFImporter : public BaseImporter { class D3MFImporter : public BaseImporter {
public: public:
/// @brief The default class constructor. /// @brief The default class constructor.
D3MFImporter() = default; D3MFImporter();
/// @brief The class destructor. /// @brief The class destructor.
~D3MFImporter() override = default; ~D3MFImporter() override;
/// @brief Performs the data format detection. /// @brief Performs the data format detection.
/// @param pFile The filename to check. /// @param pFile The filename to check.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -68,7 +68,7 @@ using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
class OpcPackageRelationshipReader { class OpcPackageRelationshipReader {
public: public:
OpcPackageRelationshipReader(XmlParser &parser) : OpcPackageRelationshipReader(XmlParser &parser) :
mRelations() { m_relationShips() {
XmlNode root = parser.getRootNode(); XmlNode root = parser.getRootNode();
ParseRootNode(root); ParseRootNode(root);
} }
@ -108,20 +108,20 @@ public:
relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string(); relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string();
relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string(); relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string();
if (validateRels(relPtr)) { if (validateRels(relPtr)) {
mRelations.push_back(relPtr); m_relationShips.push_back(relPtr);
} }
} }
} }
} }
std::vector<OpcPackageRelationshipPtr> mRelations; std::vector<OpcPackageRelationshipPtr> m_relationShips;
}; };
static bool IsEmbeddedTexture( const std::string &filename ) { static bool IsEmbeddedTexture( const std::string &filename ) {
const std::string extension = BaseImporter::GetExtension(filename); const std::string extension = BaseImporter::GetExtension(filename);
if (extension == "jpg" || extension == "png" || extension == "jpeg") { if (extension == "jpg" || extension == "png") {
std::string::size_type pos = filename.find("thumbnail"); std::string::size_type pos = filename.find("thumbnail");
if (pos != std::string::npos) { if (pos == std::string::npos) {
return false; return false;
} }
return true; return true;
@ -186,6 +186,9 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
D3MFOpcPackage::~D3MFOpcPackage() { D3MFOpcPackage::~D3MFOpcPackage() {
mZipArchive->Close(mRootStream); mZipArchive->Close(mRootStream);
delete mZipArchive; delete mZipArchive;
for (auto tex : mEmbeddedTextures) {
delete tex;
}
} }
IOStream *D3MFOpcPackage::RootStream() const { IOStream *D3MFOpcPackage::RootStream() const {
@ -214,11 +217,11 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
OpcPackageRelationshipReader reader(xmlParser); OpcPackageRelationshipReader reader(xmlParser);
auto itr = std::find_if(reader.mRelations.begin(), reader.mRelations.end(), [](const OpcPackageRelationshipPtr &rel) { auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr &rel) {
return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE; return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
}); });
if (itr == reader.mRelations.end()) { if (itr == reader.m_relationShips.end()) {
throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE); throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
} }

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -49,16 +49,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace D3MF { namespace D3MF {
static constexpr int IdNotSet = -1; static const int IdNotSet = -1;
namespace { namespace {
static constexpr size_t ColRGBA_Len = 9; static const size_t ColRGBA_Len = 9;
static constexpr size_t ColRGB_Len = 7; static const size_t ColRGB_Len = 7;
// format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1) // format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
bool validateColorString(const std::string color) { bool validateColorString(const char *color) {
const size_t len = color.size(); const size_t len = strlen(color);
if (ColRGBA_Len != len && ColRGB_Len != len) { if (ColRGBA_Len != len && ColRGB_Len != len) {
return false; return false;
} }
@ -75,7 +75,7 @@ aiFace ReadTriangle(XmlNode &node, int &texId0, int &texId1, int &texId2) {
face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string())); face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string())); face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
texId0 = texId1 = texId2 = IdNotSet; texId0 = texId1 = texId2 = -1;
XmlParser::getIntAttribute(node, XmlTag::p1, texId0); XmlParser::getIntAttribute(node, XmlTag::p1, texId0);
XmlParser::getIntAttribute(node, XmlTag::p2, texId1); XmlParser::getIntAttribute(node, XmlTag::p2, texId1);
XmlParser::getIntAttribute(node, XmlTag::p3, texId2); XmlParser::getIntAttribute(node, XmlTag::p3, texId2);
@ -157,8 +157,8 @@ aiMatrix4x4 parseTransformMatrix(const std::string& matrixStr) {
return transformMatrix; return transformMatrix;
} }
bool parseColor(const std::string &color, aiColor4D &diffuse) { bool parseColor(const char *color, aiColor4D &diffuse) {
if (color.empty()) { if (nullptr == color) {
return false; return false;
} }
@ -178,7 +178,7 @@ bool parseColor(const std::string &color, aiColor4D &diffuse) {
char b[3] = { color[5], color[6], '\0' }; char b[3] = { color[5], color[6], '\0' };
diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0); diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
const size_t len = color.size(); const size_t len = strlen(color);
if (ColRGB_Len == len) { if (ColRGB_Len == len) {
return true; return true;
} }
@ -236,8 +236,6 @@ void XmlSerializer::ImportXml(aiScene *scene) {
ReadBaseMaterials(currentNode); ReadBaseMaterials(currentNode);
} else if (currentNodeName == XmlTag::meta) { } else if (currentNodeName == XmlTag::meta) {
ReadMetadata(currentNode); ReadMetadata(currentNode);
} else if (currentNodeName == XmlTag::colorgroup) {
ReadColorGroup(currentNode);
} }
} }
StoreMaterialsInScene(scene); StoreMaterialsInScene(scene);
@ -333,49 +331,9 @@ void XmlSerializer::ReadObject(XmlNode &node) {
if (hasPid) { if (hasPid) {
auto it = mResourcesDictionnary.find(pid); auto it = mResourcesDictionnary.find(pid);
if (hasPindex && it != mResourcesDictionnary.end()) { if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second); BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = materials->mMaterialIndex[pindex]; mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
} else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
Texture2DGroup *group = static_cast<Texture2DGroup *>(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<unsigned int>(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<ColorGroup *>(it->second);
for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
mesh->mColors[0][vertex_idx] = group->mColors[pindex];
}
}
}
} }
} }
@ -457,36 +415,27 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
for (XmlNode &currentNode : node.children()) { for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string currentName = currentNode.name();
if (currentName == XmlTag::triangle) { if (currentName == XmlTag::triangle) {
int pid = IdNotSet; int pid = IdNotSet, p1 = IdNotSet;
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid); bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
int pindex[3]; int texId[3];
aiFace face = ReadTriangle(currentNode, pindex[0], pindex[1], pindex[2]); Texture2DGroup *group = nullptr;
if (hasPid && (pindex[0] != IdNotSet || pindex[1] != IdNotSet || pindex[2] != IdNotSet)) { aiFace face = ReadTriangle(currentNode, texId[0], texId[1], texId[2]);
if (hasPid && hasP1) {
auto it = mResourcesDictionnary.find(pid); auto it = mResourcesDictionnary.find(pid);
if (it != mResourcesDictionnary.end()) { if (it != mResourcesDictionnary.end()) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) { if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second); BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(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) { } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
// Load texture coordinates into mesh, when any
Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second); // fix bug
if (mesh->mTextureCoords[0] == nullptr) { if (mesh->mTextureCoords[0] == nullptr) {
mesh->mNumUVComponents[0] = 2; mesh->mNumUVComponents[0] = 2;
for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
mesh->mNumUVComponents[i] = 0; mesh->mNumUVComponents[i] = 0;
} }
group = static_cast<Texture2DGroup *>(it->second);
const std::string name = ai_to_string(group->mTexId); const std::string name = ai_to_string(group->mTexId);
for (size_t i = 0; i < mMaterials.size(); ++i) { for (size_t i = 0; i < mMaterials.size(); ++i) {
if (name == mMaterials[i]->GetName().C_Str()) { if (name == mMaterials[i]->GetName().C_Str()) {
@ -494,42 +443,19 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
} }
} }
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; 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) { // Load texture coordinates into mesh, when any
if (pindex[idx] != IdNotSet) { if (group != nullptr) {
size_t vertex_index = face.mIndices[idx]; size_t i0 = face.mIndices[0];
mesh->mTextureCoords[0][vertex_index] = size_t i1 = face.mIndices[1];
aiVector3D(group->mTex2dCoords[pindex[idx]].x, group->mTex2dCoords[pindex[idx]].y, 0.0f); 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);
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<ColorGroup *>(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);
}
}
} }
faces.push_back(face); faces.push_back(face);
@ -672,38 +598,6 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater
return material; 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) { void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
if (nullptr == scene) { if (nullptr == scene) {
return; return;

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -57,7 +57,6 @@ class D3MFOpcPackage;
class Object; class Object;
class Texture2DGroup; class Texture2DGroup;
class EmbeddedTexture; class EmbeddedTexture;
class ColorGroup;
class XmlSerializer { class XmlSerializer {
public: public:
@ -79,8 +78,6 @@ private:
void ReadTextureGroup(XmlNode &node); void ReadTextureGroup(XmlNode &node);
aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId); aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId);
void StoreMaterialsInScene(aiScene *scene); void StoreMaterialsInScene(aiScene *scene);
void ReadColorGroup(XmlNode &node);
void ReadColor(XmlNode &node, ColorGroup *colorGroup);
private: private:
struct MetaEntry { struct MetaEntry {

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -60,9 +60,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <memory> #include <memory>
namespace Assimp { using namespace Assimp;
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"AC3D Importer", "AC3D Importer",
"", "",
"", "",
@ -77,8 +77,8 @@ static constexpr aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// skip to the next token // skip to the next token
inline const char *AcSkipToNextToken(const char *buffer, const char *end) { inline const char *AcSkipToNextToken(const char *buffer) {
if (!SkipSpaces(&buffer, end)) { if (!SkipSpaces(&buffer)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL"); ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL");
} }
return buffer; return buffer;
@ -86,13 +86,13 @@ inline const char *AcSkipToNextToken(const char *buffer, const char *end) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read a string (may be enclosed in double quotation marks). buffer must point to " // read a string (may be enclosed in double quotation marks). buffer must point to "
inline const char *AcGetString(const char *buffer, const char *end, std::string &out) { inline const char *AcGetString(const char *buffer, std::string &out) {
if (*buffer == '\0') { if (*buffer == '\0') {
throw DeadlyImportError("AC3D: Unexpected EOF in string"); throw DeadlyImportError("AC3D: Unexpected EOF in string");
} }
++buffer; ++buffer;
const char *sz = buffer; const char *sz = buffer;
while ('\"' != *buffer && buffer != end) { while ('\"' != *buffer) {
if (IsLineEnd(*buffer)) { if (IsLineEnd(*buffer)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string"); ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string");
out = "ERROR"; out = "ERROR";
@ -112,8 +112,8 @@ inline const char *AcGetString(const char *buffer, const char *end, std::string
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read 1 to n floats prefixed with an optional predefined identifier // read 1 to n floats prefixed with an optional predefined identifier
template <class T> template <class T>
inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *end, const char *name, size_t name_length, size_t num, T *out) { inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name, size_t name_length, size_t num, T *out) {
buffer = AcSkipToNextToken(buffer, end); buffer = AcSkipToNextToken(buffer);
if (0 != name_length) { if (0 != name_length) {
if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) { if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) {
ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected."); ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected.");
@ -122,7 +122,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *end,
buffer += name_length + 1; buffer += name_length + 1;
} }
for (unsigned int _i = 0; _i < num; ++_i) { for (unsigned int _i = 0; _i < num; ++_i) {
buffer = AcSkipToNextToken(buffer, end); buffer = AcSkipToNextToken(buffer);
buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]); buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]);
} }
@ -132,7 +132,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *end,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
AC3DImporter::AC3DImporter() : AC3DImporter::AC3DImporter() :
mBuffer(), buffer(),
configSplitBFCull(), configSplitBFCull(),
configEvalSubdivision(), configEvalSubdivision(),
mNumMeshes(), mNumMeshes(),
@ -164,17 +164,17 @@ const aiImporterDesc *AC3DImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a pointer to the next line from the file // Get a pointer to the next line from the file
bool AC3DImporter::GetNextLine() { bool AC3DImporter::GetNextLine() {
SkipLine(&mBuffer.data, mBuffer.end); SkipLine(&buffer);
return SkipSpaces(&mBuffer.data, mBuffer.end); return SkipSpaces(&buffer);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Parse an object section in an AC file // Parse an object section in an AC file
bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) { void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
if (!TokenMatch(mBuffer.data, "OBJECT", 6)) if (!TokenMatch(buffer, "OBJECT", 6))
return false; return;
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
++mNumMeshes; ++mNumMeshes;
@ -182,7 +182,7 @@ bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
Object &obj = objects.back(); Object &obj = objects.back();
aiLight *light = nullptr; aiLight *light = nullptr;
if (!ASSIMP_strincmp(mBuffer.data, "light", 5)) { if (!ASSIMP_strincmp(buffer, "light", 5)) {
// This is a light source. Add it to the list // This is a light source. Add it to the list
mLights->push_back(light = new aiLight()); mLights->push_back(light = new aiLight());
@ -193,71 +193,67 @@ bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
// Generate a default name for both the light source and the node // Generate a default name for both the light source and the node
// FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version. // FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version.
light->mName.length = ::ai_snprintf(light->mName.data, AI_MAXLEN, "ACLight_%i", static_cast<unsigned int>(mLights->size()) - 1); light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i", static_cast<unsigned int>(mLights->size()) - 1);
obj.name = std::string(light->mName.data); obj.name = std::string(light->mName.data);
ASSIMP_LOG_VERBOSE_DEBUG("AC3D: Light source encountered"); ASSIMP_LOG_VERBOSE_DEBUG("AC3D: Light source encountered");
obj.type = Object::Light; obj.type = Object::Light;
} else if (!ASSIMP_strincmp(mBuffer.data, "group", 5)) { } else if (!ASSIMP_strincmp(buffer, "group", 5)) {
obj.type = Object::Group; obj.type = Object::Group;
} else if (!ASSIMP_strincmp(mBuffer.data, "world", 5)) { } else if (!ASSIMP_strincmp(buffer, "world", 5)) {
obj.type = Object::World; obj.type = Object::World;
} else } else
obj.type = Object::Poly; obj.type = Object::Poly;
while (GetNextLine()) { while (GetNextLine()) {
if (TokenMatch(mBuffer.data, "kids", 4)) { if (TokenMatch(buffer, "kids", 4)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
unsigned int num = strtoul10(mBuffer.data, &mBuffer.data); unsigned int num = strtoul10(buffer, &buffer);
GetNextLine(); GetNextLine();
if (num) { if (num) {
// load the children of this object recursively // load the children of this object recursively
obj.children.reserve(num); obj.children.reserve(num);
for (unsigned int i = 0; i < num; ++i) { for (unsigned int i = 0; i < num; ++i)
if (!LoadObjectSection(obj.children)) { LoadObjectSection(obj.children);
ASSIMP_LOG_WARN("AC3D: wrong number of kids");
break;
} }
} return;
} } else if (TokenMatch(buffer, "name", 4)) {
return true; SkipSpaces(&buffer);
} else if (TokenMatch(mBuffer.data, "name", 4)) { buffer = AcGetString(buffer, obj.name);
SkipSpaces(&mBuffer.data, mBuffer.data);
mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, obj.name);
// If this is a light source, we'll also need to store // If this is a light source, we'll also need to store
// the name of the node in it. // the name of the node in it.
if (light) { if (light) {
light->mName.Set(obj.name); light->mName.Set(obj.name);
} }
} else if (TokenMatch(mBuffer.data, "texture", 7)) { } else if (TokenMatch(buffer, "texture", 7)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
std::string texture; std::string texture;
mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, texture); buffer = AcGetString(buffer, texture);
obj.textures.push_back(texture); obj.textures.push_back(texture);
} else if (TokenMatch(mBuffer.data, "texrep", 6)) { } else if (TokenMatch(buffer, "texrep", 6)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &obj.texRepeat); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat);
if (!obj.texRepeat.x || !obj.texRepeat.y) if (!obj.texRepeat.x || !obj.texRepeat.y)
obj.texRepeat = aiVector2D(1.f, 1.f); obj.texRepeat = aiVector2D(1.f, 1.f);
} else if (TokenMatch(mBuffer.data, "texoff", 6)) { } else if (TokenMatch(buffer, "texoff", 6)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &obj.texOffset); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texOffset);
} else if (TokenMatch(mBuffer.data, "rot", 3)) { } else if (TokenMatch(buffer, "rot", 3)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 9, &obj.rotation); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 9, &obj.rotation);
} else if (TokenMatch(mBuffer.data, "loc", 3)) { } else if (TokenMatch(buffer, "loc", 3)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 3, &obj.translation); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &obj.translation);
} else if (TokenMatch(mBuffer.data, "subdiv", 6)) { } else if (TokenMatch(buffer, "subdiv", 6)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
obj.subDiv = strtoul10(mBuffer.data, &mBuffer.data); obj.subDiv = strtoul10(buffer, &buffer);
} else if (TokenMatch(mBuffer.data, "crease", 6)) { } else if (TokenMatch(buffer, "crease", 6)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
obj.crease = fast_atof(mBuffer.data); obj.crease = fast_atof(buffer);
} else if (TokenMatch(mBuffer.data, "numvert", 7)) { } else if (TokenMatch(buffer, "numvert", 7)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
unsigned int t = strtoul10(mBuffer.data, &mBuffer.data); unsigned int t = strtoul10(buffer, &buffer);
if (t >= AI_MAX_ALLOC(aiVector3D)) { if (t >= AI_MAX_ALLOC(aiVector3D)) {
throw DeadlyImportError("AC3D: Too many vertices, would run out of memory"); throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
} }
@ -266,59 +262,59 @@ bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
if (!GetNextLine()) { if (!GetNextLine()) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet"); ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet");
break; break;
} else if (!IsNumeric(*mBuffer.data)) { } else if (!IsNumeric(*buffer)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet"); ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet");
--mBuffer.data; // make sure the line is processed a second time --buffer; // make sure the line is processed a second time
break; break;
} }
obj.vertices.emplace_back(); obj.vertices.emplace_back();
aiVector3D &v = obj.vertices.back(); aiVector3D &v = obj.vertices.back();
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 3, &v.x); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x);
} }
} else if (TokenMatch(mBuffer.data, "numsurf", 7)) { } else if (TokenMatch(buffer, "numsurf", 7)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
bool Q3DWorkAround = false; bool Q3DWorkAround = false;
const unsigned int t = strtoul10(mBuffer.data, &mBuffer.data); const unsigned int t = strtoul10(buffer, &buffer);
obj.surfaces.reserve(t); obj.surfaces.reserve(t);
for (unsigned int i = 0; i < t; ++i) { for (unsigned int i = 0; i < t; ++i) {
GetNextLine(); GetNextLine();
if (!TokenMatch(mBuffer.data, "SURF", 4)) { if (!TokenMatch(buffer, "SURF", 4)) {
// FIX: this can occur for some files - Quick 3D for // FIX: this can occur for some files - Quick 3D for
// example writes no surf chunks // example writes no surf chunks
if (!Q3DWorkAround) { if (!Q3DWorkAround) {
ASSIMP_LOG_WARN("AC3D: SURF token was expected"); ASSIMP_LOG_WARN("AC3D: SURF token was expected");
ASSIMP_LOG_VERBOSE_DEBUG("Continuing with Quick3D Workaround enabled"); ASSIMP_LOG_VERBOSE_DEBUG("Continuing with Quick3D Workaround enabled");
} }
--mBuffer.data; // make sure the line is processed a second time --buffer; // make sure the line is processed a second time
// break; --- see fix notes above // break; --- see fix notes above
Q3DWorkAround = true; Q3DWorkAround = true;
} }
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
obj.surfaces.emplace_back(); obj.surfaces.emplace_back();
Surface &surf = obj.surfaces.back(); Surface &surf = obj.surfaces.back();
surf.flags = strtoul_cppstyle(mBuffer.data); surf.flags = strtoul_cppstyle(buffer);
while (true) { while (true) {
if (!GetNextLine()) { if (!GetNextLine()) {
throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete"); throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete");
} }
if (TokenMatch(mBuffer.data, "mat", 3)) { if (TokenMatch(buffer, "mat", 3)) {
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
surf.mat = strtoul10(mBuffer.data); surf.mat = strtoul10(buffer);
} else if (TokenMatch(mBuffer.data, "refs", 4)) { } else if (TokenMatch(buffer, "refs", 4)) {
// --- see fix notes above // --- see fix notes above
if (Q3DWorkAround) { if (Q3DWorkAround) {
if (!surf.entries.empty()) { if (!surf.entries.empty()) {
mBuffer.data -= 6; buffer -= 6;
break; break;
} }
} }
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
const unsigned int m = strtoul10(mBuffer.data); const unsigned int m = strtoul10(buffer);
surf.entries.reserve(m); surf.entries.reserve(m);
obj.numRefs += m; obj.numRefs += m;
@ -331,12 +327,12 @@ bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
surf.entries.emplace_back(); surf.entries.emplace_back();
Surface::SurfaceEntry &entry = surf.entries.back(); Surface::SurfaceEntry &entry = surf.entries.back();
entry.first = strtoul10(mBuffer.data, &mBuffer.data); entry.first = strtoul10(buffer, &buffer);
SkipSpaces(&mBuffer.data, mBuffer.end); SkipSpaces(&buffer);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &entry.second); buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &entry.second);
} }
} else { } else {
--mBuffer.data; // make sure the line is processed a second time --buffer; // make sure the line is processed a second time
break; break;
} }
} }
@ -344,7 +340,6 @@ bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
} }
} }
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: \'kids\' line was expected"); ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: \'kids\' line was expected");
return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -450,7 +445,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
idx = 0; idx = 0;
} }
if ((*it).entries.empty()) { if ((*it).entries.empty()) {
ASSIMP_LOG_WARN("AC3D: surface has zero vertex references"); ASSIMP_LOG_WARN("AC3D: surface her zero vertex references");
} }
// validate all vertex indices to make sure we won't crash here // validate all vertex indices to make sure we won't crash here
@ -468,15 +463,16 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
} }
switch ((*it).GetType()) { switch ((*it).GetType()) {
case Surface::ClosedLine: // closed line // closed line
needMat[idx].first += static_cast<unsigned int>((*it).entries.size()); case Surface::ClosedLine:
needMat[idx].second += static_cast<unsigned int>((*it).entries.size() << 1u); needMat[idx].first += (unsigned int)(*it).entries.size();
needMat[idx].second += (unsigned int)(*it).entries.size() << 1u;
break; break;
// unclosed line // unclosed line
case Surface::OpenLine: case Surface::OpenLine:
needMat[idx].first += static_cast<unsigned int>((*it).entries.size() - 1); needMat[idx].first += (unsigned int)(*it).entries.size() - 1;
needMat[idx].second += static_cast<unsigned int>(((*it).entries.size() - 1) << 1u); needMat[idx].second += ((unsigned int)(*it).entries.size() - 1) << 1u;
break; break;
// triangle strip // triangle strip
@ -578,6 +574,15 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
const Surface::SurfaceEntry &entry2 = src.entries[i + 1]; const Surface::SurfaceEntry &entry2 = src.entries[i + 1];
const Surface::SurfaceEntry &entry3 = src.entries[i + 2]; const Surface::SurfaceEntry &entry3 = src.entries[i + 2];
// skip degenerate triangles
if (object.vertices[entry1.first] == object.vertices[entry2.first] ||
object.vertices[entry1.first] == object.vertices[entry3.first] ||
object.vertices[entry2.first] == object.vertices[entry3.first]) {
mesh->mNumFaces--;
mesh->mNumVertices -= 3;
continue;
}
aiFace &face = *faces++; aiFace &face = *faces++;
face.mNumIndices = 3; face.mNumIndices = 3;
face.mIndices = new unsigned int[face.mNumIndices]; face.mIndices = new unsigned int[face.mNumIndices];
@ -696,18 +701,18 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
// generate a name depending on the type of the node // generate a name depending on the type of the node
switch (object.type) { switch (object.type) {
case Object::Group: case Object::Group:
node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACGroup_%i", mGroupsCounter++); node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i", mGroupsCounter++);
break; break;
case Object::Poly: case Object::Poly:
node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACPoly_%i", mPolysCounter++); node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i", mPolysCounter++);
break; break;
case Object::Light: case Object::Light:
node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACLight_%i", mLightsCounter++); node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i", mLightsCounter++);
break; break;
// there shouldn't be more than one world, but we don't care // there shouldn't be more than one world, but we don't care
case Object::World: case Object::World:
node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACWorld_%i", mWorldsCounter++); node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i", mWorldsCounter++);
break; break;
} }
} }
@ -755,18 +760,17 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
std::vector<char> mBuffer2; std::vector<char> mBuffer2;
TextFileToBuffer(file.get(), mBuffer2); TextFileToBuffer(file.get(), mBuffer2);
mBuffer.data = &mBuffer2[0]; buffer = &mBuffer2[0];
mBuffer.end = &mBuffer2[0] + mBuffer2.size();
mNumMeshes = 0; mNumMeshes = 0;
mLightsCounter = mPolysCounter = mWorldsCounter = mGroupsCounter = 0; mLightsCounter = mPolysCounter = mWorldsCounter = mGroupsCounter = 0;
if (::strncmp(mBuffer.data, "AC3D", 4)) { if (::strncmp(buffer, "AC3D", 4)) {
throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found"); throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found");
} }
// print the file format version to the console // print the file format version to the console
unsigned int version = HexDigitToDecimal(mBuffer.data[4]); unsigned int version = HexDigitToDecimal(buffer[4]);
char msg[3]; char msg[3];
ASSIMP_itoa10(msg, 3, version); ASSIMP_itoa10(msg, 3, version);
ASSIMP_LOG_INFO("AC3D file format version: ", msg); ASSIMP_LOG_INFO("AC3D file format version: ", msg);
@ -781,31 +785,30 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
mLights = &lights; mLights = &lights;
while (GetNextLine()) { while (GetNextLine()) {
if (TokenMatch(mBuffer.data, "MATERIAL", 8)) { if (TokenMatch(buffer, "MATERIAL", 8)) {
materials.emplace_back(); materials.emplace_back();
Material &mat = materials.back(); Material &mat = materials.back();
// manually parse the material ... sscanf would use the buldin atof ... // manually parse the material ... sscanf would use the buldin atof ...
// Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f // Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f
mBuffer.data = AcSkipToNextToken(mBuffer.data, mBuffer.end); buffer = AcSkipToNextToken(buffer);
if ('\"' == *mBuffer.data) { if ('\"' == *buffer) {
mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, mat.name); buffer = AcGetString(buffer, mat.name);
mBuffer.data = AcSkipToNextToken(mBuffer.data, mBuffer.end); buffer = AcSkipToNextToken(buffer);
} }
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "rgb", 3, 3, &mat.rgb); buffer = TAcCheckedLoadFloatArray(buffer, "rgb", 3, 3, &mat.rgb);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "amb", 3, 3, &mat.amb); buffer = TAcCheckedLoadFloatArray(buffer, "amb", 3, 3, &mat.amb);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "emis", 4, 3, &mat.emis); buffer = TAcCheckedLoadFloatArray(buffer, "emis", 4, 3, &mat.emis);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "spec", 4, 3, &mat.spec); buffer = TAcCheckedLoadFloatArray(buffer, "spec", 4, 3, &mat.spec);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "shi", 3, 1, &mat.shin); buffer = TAcCheckedLoadFloatArray(buffer, "shi", 3, 1, &mat.shin);
mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "trans", 5, 1, &mat.trans); buffer = TAcCheckedLoadFloatArray(buffer, "trans", 5, 1, &mat.trans);
} else { }
LoadObjectSection(rootObjects); LoadObjectSection(rootObjects);
} }
}
if (rootObjects.empty() || mNumMeshes == 0u) { if (rootObjects.empty() || !mNumMeshes) {
throw DeadlyImportError("AC3D: No meshes have been loaded"); throw DeadlyImportError("AC3D: No meshes have been loaded");
} }
if (materials.empty()) { if (materials.empty()) {
@ -821,7 +824,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
materials.reserve(mNumMeshes); materials.reserve(mNumMeshes);
// generate a dummy root if there are multiple objects on the top layer // generate a dummy root if there are multiple objects on the top layer
Object *root = nullptr; Object *root;
if (1 == rootObjects.size()) if (1 == rootObjects.size())
root = &rootObjects[0]; root = &rootObjects[0];
else { else {
@ -834,7 +837,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
delete root; delete root;
} }
if (::strncmp(pScene->mRootNode->mName.data, "Node", 4) == 0) { if (!::strncmp(pScene->mRootNode->mName.data, "Node", 4)) {
pScene->mRootNode->mName.Set("<AC3DWorld>"); pScene->mRootNode->mName.Set("<AC3DWorld>");
} }
@ -853,12 +856,10 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
// copy lights // copy lights
pScene->mNumLights = (unsigned int)lights.size(); pScene->mNumLights = (unsigned int)lights.size();
if (!lights.empty()) { if (lights.size()) {
pScene->mLights = new aiLight *[lights.size()]; pScene->mLights = new aiLight *[lights.size()];
::memcpy(pScene->mLights, &lights[0], lights.size() * sizeof(void *)); ::memcpy(pScene->mLights, &lights[0], lights.size() * sizeof(void *));
} }
} }
} // namespace Assimp
#endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER #endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -216,7 +216,7 @@ private:
* load subobjects, the method returns after a 'kids 0' was * load subobjects, the method returns after a 'kids 0' was
* encountered. * encountered.
* @objects List of output objects*/ * @objects List of output objects*/
bool LoadObjectSection(std::vector<Object> &objects); void LoadObjectSection(std::vector<Object> &objects);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert all objects into meshes and nodes. /** Convert all objects into meshes and nodes.
@ -242,7 +242,7 @@ private:
private: private:
// points to the next data line // points to the next data line
aiBuffer mBuffer; const char *buffer;
// Configuration option: if enabled, up to two meshes // Configuration option: if enabled, up to two meshes
// are generated per material: those faces who have // are generated per material: those faces who have

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
static constexpr aiImporterDesc Description = { const aiImporterDesc AMFImporter::Description = {
"Additive manufacturing file format(AMF) Importer", "Additive manufacturing file format(AMF) Importer",
"smalcom", "smalcom",
"", "",
@ -178,6 +178,28 @@ bool AMFImporter::XML_SearchNode(const std::string &nodeName) {
return nullptr != mXmlParser->findNode(nodeName); return nullptr != mXmlParser->findNode(nodeName);
} }
void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString) {
size_t instr_len;
pOutString.clear();
instr_len = strlen(pInStr);
if (!instr_len) return;
pOutString.reserve(instr_len * 3 / 2);
// check and correct floats in format ".x". Must be "x.y".
if (pInStr[0] == '.') pOutString.push_back('0');
pOutString.push_back(pInStr[0]);
for (size_t ci = 1; ci < instr_len; ci++) {
if ((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t'))) {
pOutString.push_back('0');
pOutString.push_back('.');
} else {
pOutString.push_back(pInStr[ci]);
}
}
}
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) { static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/')); return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/'));
} }
@ -191,10 +213,7 @@ void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std
uint8_t arr4[4], arr3[3]; uint8_t arr4[4], arr3[3];
// check input data // check input data
if (pInputBase64.size() % 4) { if (pInputBase64.size() % 4) throw DeadlyImportError("Base64-encoded data must have size multiply of four.");
throw DeadlyImportError("Base64-encoded data must have size multiply of four.");
}
// prepare output place // prepare output place
pOutputData.clear(); pOutputData.clear();
pOutputData.reserve(pInputBase64.size() / 4 * 3); pOutputData.reserve(pInputBase64.size() / 4 * 3);
@ -384,17 +403,17 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
for (auto &currentNode : node.children()) { for (auto &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "deltax") { if (currentName == "deltax") {
XmlParser::getValueAsReal(currentNode, als.Delta.x); XmlParser::getValueAsFloat(currentNode, als.Delta.x);
} else if (currentName == "deltay") { } else if (currentName == "deltay") {
XmlParser::getValueAsReal(currentNode, als.Delta.y); XmlParser::getValueAsFloat(currentNode, als.Delta.y);
} else if (currentName == "deltaz") { } else if (currentName == "deltaz") {
XmlParser::getValueAsReal(currentNode, als.Delta.z); XmlParser::getValueAsFloat(currentNode, als.Delta.z);
} else if (currentName == "rx") { } else if (currentName == "rx") {
XmlParser::getValueAsReal(currentNode, als.Delta.x); XmlParser::getValueAsFloat(currentNode, als.Delta.x);
} else if (currentName == "ry") { } else if (currentName == "ry") {
XmlParser::getValueAsReal(currentNode, als.Delta.y); XmlParser::getValueAsFloat(currentNode, als.Delta.y);
} else if (currentName == "rz") { } else if (currentName == "rz") {
XmlParser::getValueAsReal(currentNode, als.Delta.z); XmlParser::getValueAsFloat(currentNode, als.Delta.z);
} }
} }
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -98,12 +98,8 @@ namespace Assimp {
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3> /// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
/// ///
class AMFImporter : public BaseImporter { class AMFImporter : public BaseImporter {
using AMFMetaDataArray = std::vector<AMFMetadata *>; private:
using MeshArray = std::vector<aiMesh *>; struct SPP_Material; // forward declaration
using NodeArray = std::vector<aiNode *>;
public:
struct SPP_Material;
/// Data type for post-processing step. More suitable container for part of material's composition. /// Data type for post-processing step. More suitable container for part of material's composition.
struct SPP_Composite { struct SPP_Composite {
@ -111,6 +107,22 @@ public:
std::string Formula; ///< Formula for calculating ratio of \ref Material. std::string Formula; ///< Formula for calculating ratio of \ref Material.
}; };
/// \struct SPP_Material
/// Data type for post-processing step. More suitable container for material.
struct SPP_Material {
std::string ID; ///< Material ID.
std::list<AMFMetadata *> Metadata; ///< Metadata of material.
AMFColor *Color; ///< Color of material.
std::list<SPP_Composite> Composition; ///< List of child materials if current material is composition of few another.
/// Return color calculated for specified coordinate.
/// \param [in] pX - "x" coordinate.
/// \param [in] pY - "y" coordinate.
/// \param [in] pZ - "z" coordinate.
/// \return calculated color.
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
};
/// Data type for post-processing step. More suitable container for texture. /// Data type for post-processing step. More suitable container for texture.
struct SPP_Texture { struct SPP_Texture {
std::string ID; std::string ID;
@ -127,51 +139,10 @@ public:
const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face. const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
}; };
/// Data type for post-processing step. More suitable container for material. using AMFMetaDataArray = std::vector<AMFMetadata*>;
struct SPP_Material { using MeshArray = std::vector<aiMesh*>;
std::string ID; ///< Material ID. using NodeArray = std::vector<aiNode*>;
std::list<AMFMetadata *> Metadata; ///< Metadata of material.
AMFColor *Color; ///< Color of material.
std::list<SPP_Composite> Composition; ///< List of child materials if current material is composition of few another.
/// Return color calculated for specified coordinate.
/// \param [in] pX - "x" coordinate.
/// \param [in] pY - "y" coordinate.
/// \param [in] pZ - "z" coordinate.
/// \return calculated color.
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
};
/// Default constructor.
AMFImporter() AI_NO_EXCEPT;
/// Default destructor.
~AMFImporter() override;
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
/// Also exception can be thrown if trouble will found.
/// \param [in] pFile - name of file to be parsed.
/// \param [in] pIOHandler - pointer to IO helper object.
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
void ParseHelper_Node_Exit();
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const override;
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
const aiImporterDesc *GetInfo() const override;
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
bool XML_SearchNode(const std::string &nodeName);
AMFImporter(const AMFImporter &pScene) = delete;
AMFImporter &operator=(const AMFImporter &pScene) = delete;
private:
/// Clear all temporary data. /// Clear all temporary data.
void Clear(); void Clear();
@ -291,9 +262,40 @@ private:
/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>. /// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false); void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false);
public:
/// Default constructor.
AMFImporter() AI_NO_EXCEPT;
/// Default destructor.
~AMFImporter() override;
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
/// Also exception can be thrown if trouble will found.
/// \param [in] pFile - name of file to be parsed.
/// \param [in] pIOHandler - pointer to IO helper object.
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
void ParseHelper_Node_Exit();
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const override;
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
const aiImporterDesc *GetInfo() const override;
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
bool XML_SearchNode(const std::string &nodeName);
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
AMFImporter(const AMFImporter &pScene) = delete;
AMFImporter &operator=(const AMFImporter &pScene) = delete;
private: private:
static const aiImporterDesc Description;
AMFNodeElementBase *mNodeElement_Cur; ///< Current element. AMFNodeElementBase *mNodeElement_Cur; ///< Current element.
std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph. std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph.
XmlParser *mXmlParser; XmlParser *mXmlParser;

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -167,11 +167,11 @@ void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
const std::string &currentName = ai_tolower(currentNode.name()); const std::string &currentName = ai_tolower(currentNode.name());
if (currentName == "x") { if (currentName == "x") {
XmlParser::getValueAsReal(currentNode, als.Coordinate.x); XmlParser::getValueAsFloat(currentNode, als.Coordinate.x);
} else if (currentName == "y") { } else if (currentName == "y") {
XmlParser::getValueAsReal(currentNode, als.Coordinate.y); XmlParser::getValueAsFloat(currentNode, als.Coordinate.y);
} else if (currentName == "z") { } else if (currentName == "z") {
XmlParser::getValueAsReal(currentNode, als.Coordinate.z); XmlParser::getValueAsFloat(currentNode, als.Coordinate.z);
} }
} }
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -263,25 +263,26 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
const std::string &name = currentNode.name(); const std::string &name = currentNode.name();
if (name == "utex1") { if (name == "utex1") {
read_flag[0] = true; read_flag[0] = true;
XmlParser::getValueAsReal(node, als.TextureCoordinate[0].x); XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].x);
} else if (name == "utex2") { } else if (name == "utex2") {
read_flag[1] = true; read_flag[1] = true;
XmlParser::getValueAsReal(node, als.TextureCoordinate[1].x); XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].x);
} else if (name == "utex3") { } else if (name == "utex3") {
read_flag[2] = true; read_flag[2] = true;
XmlParser::getValueAsReal(node, als.TextureCoordinate[2].x); XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].x);
} else if (name == "vtex1") { } else if (name == "vtex1") {
read_flag[3] = true; read_flag[3] = true;
XmlParser::getValueAsReal(node, als.TextureCoordinate[0].y); XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].y);
} else if (name == "vtex2") { } else if (name == "vtex2") {
read_flag[4] = true; read_flag[4] = true;
XmlParser::getValueAsReal(node, als.TextureCoordinate[1].y); XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].y);
} else if (name == "vtex3") { } else if (name == "vtex3") {
read_flag[5] = true; read_flag[5] = true;
XmlParser::getValueAsReal(node, als.TextureCoordinate[2].y); XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].y);
} }
} }
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
} else { } else {
for (pugi::xml_attribute &attr : node.attributes()) { for (pugi::xml_attribute &attr : node.attributes()) {
const std::string name = attr.name(); const std::string name = attr.name();

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -56,6 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string> #include <string>
#include <vector> #include <vector>
/// \class CAMFImporter_NodeElement
/// Base class for elements of nodes. /// Base class for elements of nodes.
class AMFNodeElementBase { class AMFNodeElementBase {
public: public:
@ -105,6 +106,7 @@ protected:
} }
}; // class IAMFImporter_NodeElement }; // class IAMFImporter_NodeElement
/// \struct CAMFImporter_NodeElement_Constellation
/// A collection of objects or constellations with specific relative locations. /// A collection of objects or constellations with specific relative locations.
struct AMFConstellation : public AMFNodeElementBase { struct AMFConstellation : public AMFNodeElementBase {
/// Constructor. /// Constructor.
@ -114,6 +116,7 @@ struct AMFConstellation : public AMFNodeElementBase {
}; // struct CAMFImporter_NodeElement_Constellation }; // struct CAMFImporter_NodeElement_Constellation
/// \struct CAMFImporter_NodeElement_Instance
/// Part of constellation. /// Part of constellation.
struct AMFInstance : public AMFNodeElementBase { struct AMFInstance : public AMFNodeElementBase {
@ -132,6 +135,7 @@ struct AMFInstance : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Instance, pParent) {} AMFNodeElementBase(ENET_Instance, pParent) {}
}; };
/// \struct CAMFImporter_NodeElement_Metadata
/// Structure that define metadata node. /// Structure that define metadata node.
struct AMFMetadata : public AMFNodeElementBase { struct AMFMetadata : public AMFNodeElementBase {
@ -144,6 +148,7 @@ struct AMFMetadata : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Metadata, pParent) {} AMFNodeElementBase(ENET_Metadata, pParent) {}
}; };
/// \struct CAMFImporter_NodeElement_Root
/// Structure that define root node. /// Structure that define root node.
struct AMFRoot : public AMFNodeElementBase { struct AMFRoot : public AMFNodeElementBase {
@ -156,6 +161,7 @@ struct AMFRoot : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Root, pParent) {} AMFNodeElementBase(ENET_Root, pParent) {}
}; };
/// \struct CAMFImporter_NodeElement_Color
/// Structure that define object node. /// Structure that define object node.
struct AMFColor : public AMFNodeElementBase { struct AMFColor : public AMFNodeElementBase {
bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color. bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
@ -171,6 +177,7 @@ struct AMFColor : public AMFNodeElementBase {
} }
}; };
/// \struct CAMFImporter_NodeElement_Material
/// Structure that define material node. /// Structure that define material node.
struct AMFMaterial : public AMFNodeElementBase { struct AMFMaterial : public AMFNodeElementBase {
@ -180,6 +187,7 @@ struct AMFMaterial : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Material, pParent) {} AMFNodeElementBase(ENET_Material, pParent) {}
}; };
/// \struct CAMFImporter_NodeElement_Object
/// Structure that define object node. /// Structure that define object node.
struct AMFObject : public AMFNodeElementBase { struct AMFObject : public AMFNodeElementBase {
@ -198,6 +206,7 @@ struct AMFMesh : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Mesh, pParent) {} AMFNodeElementBase(ENET_Mesh, pParent) {}
}; };
/// \struct CAMFImporter_NodeElement_Vertex
/// Structure that define vertex node. /// Structure that define vertex node.
struct AMFVertex : public AMFNodeElementBase { struct AMFVertex : public AMFNodeElementBase {
/// Constructor. /// Constructor.
@ -206,6 +215,7 @@ struct AMFVertex : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Vertex, pParent) {} AMFNodeElementBase(ENET_Vertex, pParent) {}
}; };
/// \struct CAMFImporter_NodeElement_Edge
/// Structure that define edge node. /// Structure that define edge node.
struct AMFEdge : public AMFNodeElementBase { struct AMFEdge : public AMFNodeElementBase {
/// Constructor. /// Constructor.
@ -214,6 +224,7 @@ struct AMFEdge : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Edge, pParent) {} AMFNodeElementBase(ENET_Edge, pParent) {}
}; };
/// \struct CAMFImporter_NodeElement_Vertices
/// Structure that define vertices node. /// Structure that define vertices node.
struct AMFVertices : public AMFNodeElementBase { struct AMFVertices : public AMFNodeElementBase {
/// Constructor. /// Constructor.
@ -222,6 +233,7 @@ struct AMFVertices : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Vertices, pParent) {} AMFNodeElementBase(ENET_Vertices, pParent) {}
}; };
/// \struct CAMFImporter_NodeElement_Volume
/// Structure that define volume node. /// Structure that define volume node.
struct AMFVolume : public AMFNodeElementBase { struct AMFVolume : public AMFNodeElementBase {
std::string MaterialID; ///< Which material to use. std::string MaterialID; ///< Which material to use.
@ -233,6 +245,7 @@ struct AMFVolume : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Volume, pParent) {} AMFNodeElementBase(ENET_Volume, pParent) {}
}; };
/// \struct CAMFImporter_NodeElement_Coordinates
/// Structure that define coordinates node. /// Structure that define coordinates node.
struct AMFCoordinates : public AMFNodeElementBase { struct AMFCoordinates : public AMFNodeElementBase {
aiVector3D Coordinate; ///< Coordinate. aiVector3D Coordinate; ///< Coordinate.
@ -243,6 +256,7 @@ struct AMFCoordinates : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Coordinates, pParent) {} AMFNodeElementBase(ENET_Coordinates, pParent) {}
}; };
/// \struct CAMFImporter_NodeElement_TexMap
/// Structure that define texture coordinates node. /// Structure that define texture coordinates node.
struct AMFTexMap : public AMFNodeElementBase { struct AMFTexMap : public AMFNodeElementBase {
aiVector3D TextureCoordinate[3]; ///< Texture coordinates. aiVector3D TextureCoordinate[3]; ///< Texture coordinates.
@ -259,6 +273,7 @@ struct AMFTexMap : public AMFNodeElementBase {
} }
}; };
/// \struct CAMFImporter_NodeElement_Triangle
/// Structure that define triangle node. /// Structure that define triangle node.
struct AMFTriangle : public AMFNodeElementBase { struct AMFTriangle : public AMFNodeElementBase {
size_t V[3]; ///< Triangle vertices. size_t V[3]; ///< Triangle vertices.

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -224,8 +224,7 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
} }
// Create format hint. // Create format hint.
constexpr char templateColor[] = "rgba0000"; strcpy(converted_texture.FormatHint, "rgba0000"); // copy initial string.
memcpy(converted_texture.FormatHint, templateColor, 8);
if (!r.empty()) converted_texture.FormatHint[4] = '8'; if (!r.empty()) converted_texture.FormatHint[4] = '8';
if (!g.empty()) converted_texture.FormatHint[5] = '8'; if (!g.empty()) converted_texture.FormatHint[5] = '8';
if (!b.empty()) converted_texture.FormatHint[6] = '8'; if (!b.empty()) converted_texture.FormatHint[6] = '8';
@ -868,7 +867,7 @@ nl_clean_loop:
pScene->mTextures[idx]->mHeight = static_cast<unsigned int>(tex_convd.Height); pScene->mTextures[idx]->mHeight = static_cast<unsigned int>(tex_convd.Height);
pScene->mTextures[idx]->pcData = (aiTexel *)tex_convd.Data; pScene->mTextures[idx]->pcData = (aiTexel *)tex_convd.Data;
// texture format description. // texture format description.
strncpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint, HINTMAXTEXTURELEN); strcpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint);
idx++; idx++;
} // for(const SPP_Texture& tex_convd: mTexture_Converted) } // for(const SPP_Texture& tex_convd: mTexture_Converted)

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER #ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
// internal headers // internal headers
@ -63,10 +64,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// utilities // utilities
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
namespace Assimp { using namespace Assimp;
using namespace Assimp::ASE; using namespace Assimp::ASE;
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"ASE Importer", "ASE Importer",
"", "",
"", "",
@ -124,7 +125,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
// Allocate storage and copy the contents of the file to a memory buffer // Allocate storage and copy the contents of the file to a memory buffer
std::vector<char> mBuffer2; std::vector<char> mBuffer2;
TextFileToBuffer(file.get(), mBuffer2); TextFileToBuffer(file.get(), mBuffer2);
const size_t fileSize = mBuffer2.size();
this->mBuffer = &mBuffer2[0]; this->mBuffer = &mBuffer2[0];
this->pcScene = pScene; this->pcScene = pScene;
@ -146,7 +147,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
}; };
// Construct an ASE parser and parse the file // Construct an ASE parser and parse the file
ASE::Parser parser(mBuffer, fileSize, defaultFormat); ASE::Parser parser(mBuffer, defaultFormat);
mParser = &parser; mParser = &parser;
mParser->Parse(); mParser->Parse();
@ -321,6 +322,21 @@ void ASEImporter::BuildAnimations(const std::vector<BaseNode *> &nodes) {
aiNodeAnim *nd = pcAnim->mChannels[iNum++] = new aiNodeAnim(); aiNodeAnim *nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
nd->mNodeName.Set(me->mName + ".Target"); nd->mNodeName.Set(me->mName + ".Target");
// If there is no input position channel we will need
// to supply the default position from the node's
// local transformation matrix.
/*TargetAnimationHelper helper;
if (me->mAnim.akeyPositions.empty())
{
aiMatrix4x4& mat = (*i)->mTransform;
helper.SetFixedMainAnimationChannel(aiVector3D(
mat.a4, mat.b4, mat.c4));
}
else helper.SetMainAnimationChannel (&me->mAnim.akeyPositions);
helper.SetTargetAnimationChannel (&me->mTargetAnim.akeyPositions);
helper.Process(&me->mTargetAnim.akeyPositions);*/
// Allocate the key array and fill it // Allocate the key array and fill it
nd->mNumPositionKeys = (unsigned int)me->mTargetAnim.akeyPositions.size(); nd->mNumPositionKeys = (unsigned int)me->mTargetAnim.akeyPositions.size();
nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
@ -446,9 +462,10 @@ void ASEImporter::BuildLights() {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes, aiNode *pcParent, const std::string &name) { void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
aiNode *pcParent, const char *szName) {
aiMatrix4x4 m; aiMatrix4x4 m;
AddNodes(nodes, pcParent, name, m); AddNodes(nodes, pcParent, szName, m);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -505,9 +522,10 @@ void ASEImporter::AddMeshes(const ASE::BaseNode *snode, aiNode *node) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Add child nodes to a given parent node // Add child nodes to a given parent node
void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes, aiNode *pcParent, const std::string &name, void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
aiNode *pcParent, const char *szName,
const aiMatrix4x4 &mat) { const aiMatrix4x4 &mat) {
const size_t len = name.size(); const size_t len = szName ? ::strlen(szName) : 0;
ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS); ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
// Receives child nodes for the pcParent node // Receives child nodes for the pcParent node
@ -517,18 +535,16 @@ void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes, aiNode *pcParen
// which has *us* as parent. // which has *us* as parent.
for (std::vector<BaseNode *>::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) { for (std::vector<BaseNode *>::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) {
const BaseNode *snode = *it; const BaseNode *snode = *it;
if (!name.empty()) { if (szName) {
if (len != snode->mParent.length() || name != snode->mParent.c_str()) { if (len != snode->mParent.length() || ::strcmp(szName, snode->mParent.c_str()))
continue; continue;
} } else if (snode->mParent.length())
} else if (snode->mParent.length()) {
continue; continue;
}
(*it)->mProcessed = true; (*it)->mProcessed = true;
// Allocate a new node and add it to the output data structure // Allocate a new node and add it to the output data structure
apcNodes.push_back(new aiNode); apcNodes.push_back(new aiNode());
aiNode *node = apcNodes.back(); aiNode *node = apcNodes.back();
node->mName.Set((snode->mName.length() ? snode->mName.c_str() : "Unnamed_Node")); node->mName.Set((snode->mName.length() ? snode->mName.c_str() : "Unnamed_Node"));
@ -541,7 +557,7 @@ void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes, aiNode *pcParen
// Add sub nodes - prevent stack overflow due to recursive parenting // Add sub nodes - prevent stack overflow due to recursive parenting
if (node->mName != node->mParent->mName && node->mName != node->mParent->mParent->mName) { if (node->mName != node->mParent->mName && node->mName != node->mParent->mParent->mName) {
AddNodes(nodes, node, node->mName.C_Str(), snode->mTransform); AddNodes(nodes, node, node->mName.data, snode->mTransform);
} }
// Further processing depends on the type of the node // Further processing depends on the type of the node
@ -619,8 +635,7 @@ void ASEImporter::BuildNodes(std::vector<BaseNode *> &nodes) {
} }
// add all nodes // add all nodes
static const std::string none = ""; AddNodes(nodes, ch, nullptr);
AddNodes(nodes, ch, none);
// now iterate through al nodes and find those that have not yet // now iterate through al nodes and find those that have not yet
// been added to the nodegraph (= their parent could not be recognized) // been added to the nodegraph (= their parent could not be recognized)
@ -905,7 +920,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh &mesh, std::vector<aiMesh *> &avOutMes
ASSIMP_LOG_WARN("Material index is out of range"); ASSIMP_LOG_WARN("Material index is out of range");
} }
// If the material the mesh is assigned to consists of submeshes, split it // If the material the mesh is assigned to is consisting of submeshes, split it
if (!mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials.empty()) { if (!mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials.empty()) {
std::vector<ASE::Material> vSubMaterials = mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials; std::vector<ASE::Material> vSubMaterials = mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials;
@ -1263,8 +1278,6 @@ bool ASEImporter::GenerateNormals(ASE::Mesh &mesh) {
return false; return false;
} }
}
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER #endif // ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER #endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -153,10 +153,10 @@ private:
* \param matrix Current transform * \param matrix Current transform
*/ */
void AddNodes(const std::vector<ASE::BaseNode*>& nodes, void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
aiNode* pcParent, const std::string &name); aiNode* pcParent,const char* szName);
void AddNodes(const std::vector<ASE::BaseNode*>& nodes, void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
aiNode* pcParent, const std::string &name, aiNode* pcParent,const char* szName,
const aiMatrix4x4& matrix); const aiMatrix4x4& matrix);
void AddMeshes(const ASE::BaseNode* snode,aiNode* node); void AddMeshes(const ASE::BaseNode* snode,aiNode* node);
@ -188,4 +188,5 @@ protected:
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_3DSIMPORTER_H_INC #endif // AI_3DSIMPORTER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -391,11 +391,11 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Construct a parser from a given input file which is //! Construct a parser from a given input file which is
//! guaranteed to be terminated with zero. //! guaranteed to be terminated with zero.
//! @param file The name of the input file. //! @param szFile Input file
//! @param fileFormatDefault Assumed file format version. If the //! @param fileFormatDefault Assumed file format version. If the
//! file format is specified in the file the new value replaces //! file format is specified in the file the new value replaces
//! the default value. //! the default value.
Parser(const char *file, size_t fileLen, unsigned int fileFormatDefault); Parser(const char *szFile, unsigned int fileFormatDefault);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parses the file into the parsers internal representation //! Parses the file into the parsers internal representation
@ -553,15 +553,13 @@ private:
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...) //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
//! \param apOut Output buffer (3 floats) //! \param apOut Output buffer (3 floats)
//! \param rIndexOut Output index //! \param rIndexOut Output index
void ParseLV4MeshRealTriple(ai_real *apOut, unsigned int &rIndexOut); void ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut);
void ParseLV4MeshFloatTriple(float *apOut, unsigned int &rIndexOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_VERT block in a file //! Parse a *MESH_VERT block in a file
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...) //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
//! \param apOut Output buffer (3 floats) //! \param apOut Output buffer (3 floats)
void ParseLV4MeshRealTriple(ai_real *apOut); void ParseLV4MeshFloatTriple(ai_real *apOut);
void ParseLV4MeshFloatTriple(float *apOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_TFACE block in a file //! Parse a *MESH_TFACE block in a file
@ -579,8 +577,7 @@ private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a single float element //! Parse a single float element
//! \param fOut Output float //! \param fOut Output float
void ParseLV4MeshReal(ai_real &fOut); void ParseLV4MeshFloat(ai_real &fOut);
void ParseLV4MeshFloat(float &fOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a single int element //! Parse a single int element
@ -620,8 +617,8 @@ private:
bool ParseString(std::string &out, const char *szName); bool ParseString(std::string &out, const char *szName);
public: public:
const char *mFilePtr; ////< Pointer to current data //! Pointer to current data
const char *mEnd; ///< The end pointer of the file data const char *filePtr;
//! background color to be passed to the viewer //! background color to be passed to the viewer
//! QNAN if none was found //! QNAN if none was found

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -50,7 +50,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/version.h> #include <assimp/version.h>
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include "zlib.h" #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
#include <zlib.h>
#else
#include "../contrib/zlib/zlib.h"
#endif
#include <ctime> #include <ctime>

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -65,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"Assimp Binary Importer", "Assimp Binary Importer",
"Gargaj / Conspiracy", "Gargaj / Conspiracy",
"", "",

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -59,10 +59,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory> #include <memory>
namespace Assimp { using namespace Assimp;
using namespace std; using namespace std;
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"BlitzBasic 3D Importer", "BlitzBasic 3D Importer",
"", "",
"", "",
@ -738,6 +738,4 @@ void B3DImporter::ReadBB3D(aiScene *scene) {
flip.Execute(scene); flip.Execute(scene);
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER #endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -4,7 +4,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
@ -55,11 +55,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <map> #include <map>
#include <memory> #include <memory>
namespace Assimp { using namespace Assimp;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"BVH Importer (MoCap)", "BVH Importer (MoCap)",
"", "",
"", "",
@ -488,21 +487,24 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
aiMatrix3x3 rotMatrix; aiMatrix3x3 rotMatrix;
for (unsigned int channelIdx = 0; channelIdx < node.mChannels.size(); ++ channelIdx) { for (unsigned int channelIdx = 0; channelIdx < node.mChannels.size(); ++ channelIdx) {
switch (node.mChannels[channelIdx]) { switch (node.mChannels[channelIdx]) {
case Channel_RotationX: { case Channel_RotationX:
{
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f; const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
aiMatrix4x4::RotationX(angle, temp); aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp);
rotMatrix *= aiMatrix3x3(temp); }
} break; break;
case Channel_RotationY: { case Channel_RotationY:
{
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f; const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
aiMatrix4x4::RotationY(angle, temp); aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp);
rotMatrix *= aiMatrix3x3(temp); }
} break; break;
case Channel_RotationZ: { case Channel_RotationZ:
{
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f; const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
aiMatrix4x4::RotationZ(angle, temp); aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp);
rotMatrix *= aiMatrix3x3(temp); }
} break; break;
default: default:
break; break;
} }
@ -523,6 +525,4 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
} }
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER #endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER

View File

@ -4,7 +4,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -69,6 +69,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// zlib is needed for compressed blend files // zlib is needed for compressed blend files
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND #ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
#include "Common/Compression.h" #include "Common/Compression.h"
/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
# else
# include "../contrib/zlib/zlib.h"
# endif*/
#endif #endif
namespace Assimp { namespace Assimp {
@ -84,7 +89,7 @@ using namespace Assimp;
using namespace Assimp::Blender; using namespace Assimp::Blender;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
static constexpr aiImporterDesc blenderDesc = { static const aiImporterDesc blenderDesc = {
"Blender 3D Importer (http://www.blender3d.org)", "Blender 3D Importer (http://www.blender3d.org)",
"", "",
"", "",
@ -110,12 +115,15 @@ BlenderImporter::~BlenderImporter() {
delete modifier_cache; delete modifier_cache;
} }
static const char Token[] = "BLENDER"; static const char * const Tokens[] = { "BLENDER" };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
return ParseMagicToken(pFile, pIOHandler).error.empty(); // note: this won't catch compressed files
static const char *tokens[] = { "<BLENDER", "blender" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -134,21 +142,63 @@ void BlenderImporter::SetupProperties(const Importer * /*pImp*/) {
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void BlenderImporter::InternReadFile(const std::string &pFile, void BlenderImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) { aiScene *pScene, IOSystem *pIOHandler) {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
std::vector<char> uncompressed;
#endif
FileDatabase file; FileDatabase file;
StreamOrError streamOrError = ParseMagicToken(pFile, pIOHandler); std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
if (!streamOrError.error.empty()) { if (!stream) {
ThrowException(streamOrError.error); ThrowException("Could not open file for reading");
} }
std::shared_ptr<IOStream> stream = std::move(streamOrError.stream);
char version[4] = { 0 }; char magic[8] = { 0 };
file.i64bit = (stream->Read(version, 1, 1), version[0] == '-'); stream->Read(magic, 7, 1);
file.little = (stream->Read(version, 1, 1), version[0] == 'v'); if (strcmp(magic, Tokens[0])) {
// Check for presence of the gzip header. If yes, assume it is a
// compressed blend file and try uncompressing it, else fail. This is to
// avoid uncompressing random files which our loader might end up with.
#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
ThrowException("BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?");
#else
if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
ThrowException("BLENDER magic bytes are missing, couldn't find GZIP header either");
}
stream->Read(version, 3, 1); LogDebug("Found no BLENDER magic word but a GZIP header, might be a compressed file");
version[3] = '\0'; if (magic[2] != 8) {
ThrowException("Unsupported GZIP compression method");
}
LogInfo("Blender version is ", version[0], ".", version + 1, // http://www.gzip.org/zlib/rfc-gzip.html#header-trailer
stream->Seek(0L, aiOrigin_SET);
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
size_t total = 0;
Compression compression;
if (compression.open(Compression::Format::Binary, Compression::FlushMode::NoFlush, 16 + Compression::MaxWBits)) {
total = compression.decompress((unsigned char *)reader->GetPtr(), reader->GetRemainingSize(), uncompressed);
compression.close();
}
// replace the input stream with a memory stream
stream = std::make_shared<MemoryIOStream>(reinterpret_cast<uint8_t *>(uncompressed.data()), total);
// .. and retry
stream->Read(magic, 7, 1);
if (strcmp(magic, "BLENDER")) {
ThrowException("Found no BLENDER magic word in decompressed GZIP file");
}
#endif
}
file.i64bit = (stream->Read(magic, 1, 1), magic[0] == '-');
file.little = (stream->Read(magic, 1, 1), magic[0] == 'v');
stream->Read(magic, 3, 1);
magic[3] = '\0';
LogInfo("Blender version is ", magic[0], ".", magic + 1,
" (64bit: ", file.i64bit ? "true" : "false", " (64bit: ", file.i64bit ? "true" : "false",
", little endian: ", file.little ? "true" : "false", ")"); ", little endian: ", file.little ? "true" : "false", ")");
@ -359,7 +409,7 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M
// check if the file contents are bundled with the BLEND file // check if the file contents are bundled with the BLEND file
if (img->packedfile) { if (img->packedfile) {
name.data[0] = '*'; name.data[0] = '*';
name.length = 1 + ASSIMP_itoa10(name.data + 1, static_cast<unsigned int>(AI_MAXLEN - 1), static_cast<int32_t>(conv_data.textures->size())); name.length = 1 + ASSIMP_itoa10(name.data + 1, static_cast<unsigned int>(MAXLEN - 1), static_cast<int32_t>(conv_data.textures->size()));
conv_data.textures->push_back(new aiTexture()); conv_data.textures->push_back(new aiTexture());
aiTexture *curTex = conv_data.textures->back(); aiTexture *curTex = conv_data.textures->back();
@ -433,7 +483,7 @@ void BlenderImporter::AddSentinelTexture(aiMaterial *out, const Material *mat, c
(void)conv_data; (void)conv_data;
aiString name; aiString name;
name.length = ai_snprintf(name.data, AI_MAXLEN, "Procedural,num=%i,type=%s", conv_data.sentinel_cnt++, name.length = ai_snprintf(name.data, MAXLEN, "Procedural,num=%i,type=%s", conv_data.sentinel_cnt++,
GetTextureTypeDisplayString(tex->tex->type)); GetTextureTypeDisplayString(tex->tex->type));
out->AddProperty(&name, AI_MATKEY_TEXTURE_DIFFUSE( out->AddProperty(&name, AI_MATKEY_TEXTURE_DIFFUSE(
conv_data.next_texture[aiTextureType_DIFFUSE]++)); conv_data.next_texture[aiTextureType_DIFFUSE]++));
@ -1288,55 +1338,4 @@ aiNode *BlenderImporter::ConvertNode(const Scene &in, const Object *obj, Convers
return node.release(); return node.release();
} }
BlenderImporter::StreamOrError BlenderImporter::ParseMagicToken(const std::string &pFile, IOSystem *pIOHandler) const {
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
if (stream == nullptr) {
return {{}, {}, "Could not open file for reading"};
}
char magic[8] = { 0 };
stream->Read(magic, 7, 1);
if (strcmp(magic, Token) == 0) {
return {stream, {}, {}};
}
// Check for presence of the gzip header. If yes, assume it is a
// compressed blend file and try uncompressing it, else fail. This is to
// avoid uncompressing random files which our loader might end up with.
#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
return {{}, {}, "BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?"};
#else
if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
return {{}, {}, "BLENDER magic bytes are missing, couldn't find GZIP header either"};
}
LogDebug("Found no BLENDER magic word but a GZIP header, might be a compressed file");
if (magic[2] != 8) {
return {{}, {}, "Unsupported GZIP compression method"};
}
// http://www.gzip.org/zlib/rfc-gzip.html#header-trailer
stream->Seek(0L, aiOrigin_SET);
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
size_t total = 0;
Compression compression;
auto uncompressed = std::make_shared<std::vector<char>>();
if (compression.open(Compression::Format::Binary, Compression::FlushMode::NoFlush, 16 + Compression::MaxWBits)) {
total = compression.decompress((unsigned char *)reader->GetPtr(), reader->GetRemainingSize(), *uncompressed);
compression.close();
}
// replace the input stream with a memory stream
stream = std::make_shared<MemoryIOStream>(reinterpret_cast<uint8_t *>(uncompressed->data()), total);
// .. and retry
stream->Read(magic, 7, 1);
if (strcmp(magic, Token) == 0) {
return {stream, uncompressed, {}};
}
return {{}, {}, "Found no BLENDER magic word in decompressed GZIP file"};
#endif
}
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER #endif // ASSIMP_BUILD_NO_BLEND_IMPORTER

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -180,19 +180,6 @@ private:
const Blender::MTex *tex, const Blender::MTex *tex,
Blender::ConversionData &conv_data); Blender::ConversionData &conv_data);
// TODO: Move to a std::variant, once c++17 is supported.
struct StreamOrError {
std::shared_ptr<IOStream> stream;
std::shared_ptr<std::vector<char>> input;
std::string error;
};
// Returns either a stream (and optional input data for the stream) or
// an error if it can't parse the magic token.
StreamOrError ParseMagicToken(
const std::string &pFile,
IOSystem *pIOHandler) const;
private: // static stuff, mostly logging and error reporting. private: // static stuff, mostly logging and error reporting.
// -------------------- // --------------------
static void CheckActualType(const Blender::ElemBase *dt, static void CheckActualType(const Blender::ElemBase *dt,

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -283,11 +283,6 @@ void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data,
if (conv_data.meshes->empty()) { if (conv_data.meshes->empty()) {
return; return;
} }
const size_t meshIndex = conv_data.meshes->size() - out.mNumMeshes;
if (meshIndex >= conv_data.meshes->size()) {
ASSIMP_LOG_ERROR("Invalid index detected.");
return;
}
aiMesh **const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes]; aiMesh **const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
std::unique_ptr<aiMesh *[]> tempmeshes(new aiMesh *[out.mNumMeshes]()); std::unique_ptr<aiMesh *[]> tempmeshes(new aiMesh *[out.mNumMeshes]());

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -102,6 +102,10 @@ void Structure::Convert<CollectionObject>(
ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db); ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db);
{ {
//std::shared_ptr<CollectionObject> prev;
//ReadFieldPtr<ErrorPolicy_Fail>(prev, "*prev", db);
//dest.prev = prev.get();
std::shared_ptr<Object> ob; std::shared_ptr<Object> ob;
ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db); ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db);
dest.ob = ob.get(); dest.ob = ob.get();
@ -297,7 +301,7 @@ void Structure ::Convert<Base>(
const FileDatabase &db) const { const FileDatabase &db) const {
// note: as per https://github.com/assimp/assimp/issues/128, // note: as per https://github.com/assimp/assimp/issues/128,
// reading the Object linked list recursively is prone to stack overflow. // reading the Object linked list recursively is prone to stack overflow.
// This structure converter is therefore a hand-written exception that // This structure converter is therefore an hand-written exception that
// does it iteratively. // does it iteratively.
const int initial_pos = db.reader->GetCurrentPos(); const int initial_pos = db.reader->GetCurrentPos();

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,8 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -39,8 +40,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/// @file BlenderTessellator.cpp /** @file BlenderTessellator.cpp
/// @brief A simple tessellation wrapper * @brief A simple tessellation wrapper
*/
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER

View File

@ -2,7 +2,8 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -143,7 +144,11 @@ namespace Assimp
#if ASSIMP_BLEND_WITH_POLY_2_TRI #if ASSIMP_BLEND_WITH_POLY_2_TRI
#include "contrib/poly2tri/poly2tri/poly2tri.h" #ifdef ASSIMP_USE_HUNTER
# include <poly2tri/poly2tri.h>
#else
# include "../contrib/poly2tri/poly2tri/poly2tri.h"
#endif
namespace Assimp namespace Assimp
{ {

View File

@ -46,6 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// no #ifdefing here, Cinema4D support is carried out in a branch of assimp // no #ifdefing here, Cinema4D support is carried out in a branch of assimp
// where it is turned on in the CMake settings. // where it is turned on in the CMake settings.
#ifndef _MSC_VER
# error C4D support is currently MSVC only
#endif
#include "C4DImporter.h" #include "C4DImporter.h"
#include <memory> #include <memory>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
@ -107,7 +111,7 @@ C4DImporter::C4DImporter() = default;
C4DImporter::~C4DImporter() = default; C4DImporter::~C4DImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { bool C4DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const {
const std::string& extension = GetExtension(pFile); const std::string& extension = GetExtension(pFile);
if (extension == "c4d") { if (extension == "c4d") {
return true; return true;
@ -301,7 +305,7 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
// based on Cineware sample code // based on Cineware sample code
while (object) { while (object) {
const Int32 type = object->GetType(); const LONG type = object->GetType();
const Matrix& ml = object->GetMl(); const Matrix& ml = object->GetMl();
aiNode* const nd = new aiNode(); aiNode* const nd = new aiNode();
@ -364,8 +368,8 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object); PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
ai_assert(polyObject != nullptr); ai_assert(polyObject != nullptr);
const Int32 pointCount = polyObject->GetPointCount(); const LONG pointCount = polyObject->GetPointCount();
const Int32 polyCount = polyObject->GetPolygonCount(); const LONG polyCount = polyObject->GetPolygonCount();
if(!polyObject || !pointCount) { if(!polyObject || !pointCount) {
LogWarn("ignoring mesh with zero vertices or faces"); LogWarn("ignoring mesh with zero vertices or faces");
return nullptr; return nullptr;
@ -387,7 +391,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
unsigned int vcount = 0; unsigned int vcount = 0;
// first count vertices // first count vertices
for (Int32 i = 0; i < polyCount; i++) for (LONG i = 0; i < polyCount; i++)
{ {
vcount += 3; vcount += 3;
@ -430,7 +434,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
} }
// copy vertices and extra channels over and populate faces // copy vertices and extra channels over and populate faces
for (Int32 i = 0; i < polyCount; ++i, ++face) { for (LONG i = 0; i < polyCount; ++i, ++face) {
ai_assert(polys[i].a < pointCount && polys[i].a >= 0); ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
const Vector& pointA = points[polys[i].a]; const Vector& pointA = points[polys[i].a];
verts->x = pointA.x; verts->x = pointA.x;
@ -507,7 +511,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
if (tangents_src) { if (tangents_src) {
for(unsigned int k = 0; k < face->mNumIndices; ++k) { for(unsigned int k = 0; k < face->mNumIndices; ++k) {
Int32 l; LONG l;
switch(k) { switch(k) {
case 0: case 0:
l = polys[i].a; l = polys[i].a;

View File

@ -78,8 +78,6 @@ namespace Assimp {
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> { class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> {
public: public:
C4DImporter();
~C4DImporter() override;
bool CanRead( const std::string& pFile, IOSystem*, bool checkSig) const override; bool CanRead( const std::string& pFile, IOSystem*, bool checkSig) const override;
protected: protected:

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -61,11 +61,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory> #include <memory>
namespace Assimp { using namespace Assimp;
using namespace Assimp::COB; using namespace Assimp::COB;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
static constexpr float units[] = { static const float units[] = {
1000.f, 1000.f,
100.f, 100.f,
1.f, 1.f,
@ -76,7 +76,7 @@ static constexpr float units[] = {
1.f / 1609.344f 1.f / 1609.344f
}; };
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"TrueSpace Object Importer", "TrueSpace Object Importer",
"", "",
"", "",
@ -89,6 +89,14 @@ static constexpr aiImporterDesc desc = {
"cob scn" "cob scn"
}; };
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
COBImporter::COBImporter() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
COBImporter::~COBImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@ -372,12 +380,10 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi
} }
// add children recursively // add children recursively
if (!root.temp_children.empty()) {
nd->mChildren = new aiNode *[root.temp_children.size()](); nd->mChildren = new aiNode *[root.temp_children.size()]();
for (const Node *n : root.temp_children) { for (const Node *n : root.temp_children) {
(nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd; (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd;
} }
}
return nd; return nd;
} }
@ -475,9 +481,8 @@ void COBImporter::ReadBasicNodeInfo_Ascii(Node &msh, LineSplitter &splitter, con
} else if (splitter.match_start("Transform")) { } else if (splitter.match_start("Transform")) {
for (unsigned int y = 0; y < 4 && ++splitter; ++y) { for (unsigned int y = 0; y < 4 && ++splitter; ++y) {
const char *s = splitter->c_str(); const char *s = splitter->c_str();
const char *end = s + splitter->size();
for (unsigned int x = 0; x < 4; ++x) { for (unsigned int x = 0; x < 4; ++x) {
SkipSpaces(&s, end); SkipSpaces(&s);
msh.transform[y][x] = fast_atof(&s); msh.transform[y][x] = fast_atof(&s);
} }
} }
@ -489,12 +494,12 @@ void COBImporter::ReadBasicNodeInfo_Ascii(Node &msh, LineSplitter &splitter, con
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
void COBImporter::ReadFloat3Tuple_Ascii(T &fill, const char **in, const char *end) { void COBImporter::ReadFloat3Tuple_Ascii(T &fill, const char **in) {
const char *rgb = *in; const char *rgb = *in;
for (unsigned int i = 0; i < 3; ++i) { for (unsigned int i = 0; i < 3; ++i) {
SkipSpaces(&rgb, end); SkipSpaces(&rgb);
if (*rgb == ',') ++rgb; if (*rgb == ',') ++rgb;
SkipSpaces(&rgb, end); SkipSpaces(&rgb);
fill[i] = fast_atof(&rgb); fill[i] = fast_atof(&rgb);
} }
@ -541,7 +546,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk
} }
const char *rgb = splitter[1]; const char *rgb = splitter[1];
ReadFloat3Tuple_Ascii(mat.rgb, &rgb, splitter.getEnd()); ReadFloat3Tuple_Ascii(mat.rgb, &rgb);
++splitter; ++splitter;
if (!splitter.match_start("alpha ")) { if (!splitter.match_start("alpha ")) {
@ -620,21 +625,20 @@ void COBImporter::ReadLght_Ascii(Scene &out, LineSplitter &splitter, const Chunk
} }
const char *rgb = splitter[1]; const char *rgb = splitter[1];
const char *end = splitter.getEnd(); ReadFloat3Tuple_Ascii(msh.color, &rgb);
ReadFloat3Tuple_Ascii(msh.color, &rgb, end);
SkipSpaces(&rgb, end); SkipSpaces(&rgb);
if (strncmp(rgb, "cone angle", 10) != 0) { if (strncmp(rgb, "cone angle", 10) != 0) {
ASSIMP_LOG_WARN("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id); ASSIMP_LOG_WARN("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id);
} }
SkipSpaces(rgb + 10, &rgb, end); SkipSpaces(rgb + 10, &rgb);
msh.angle = fast_atof(&rgb); msh.angle = fast_atof(&rgb);
SkipSpaces(&rgb, end); SkipSpaces(&rgb);
if (strncmp(rgb, "inner angle", 11) != 0) { if (strncmp(rgb, "inner angle", 11) != 0) {
ASSIMP_LOG_WARN("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id); ASSIMP_LOG_WARN("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
} }
SkipSpaces(rgb + 11, &rgb, end); SkipSpaces(rgb + 11, &rgb);
msh.inner_angle = fast_atof(&rgb); msh.inner_angle = fast_atof(&rgb);
// skip the rest for we can't handle this kind of physically-based lighting information. // skip the rest for we can't handle this kind of physically-based lighting information.
@ -707,14 +711,14 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) { for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) {
const char *s = splitter->c_str(); const char *s = splitter->c_str();
const char *end = splitter.getEnd();
aiVector3D &v = msh.vertex_positions[cur]; aiVector3D &v = msh.vertex_positions[cur];
SkipSpaces(&s, end); SkipSpaces(&s);
v.x = fast_atof(&s); v.x = fast_atof(&s);
SkipSpaces(&s, end); SkipSpaces(&s);
v.y = fast_atof(&s); v.y = fast_atof(&s);
SkipSpaces(&s, end); SkipSpaces(&s);
v.z = fast_atof(&s); v.z = fast_atof(&s);
} }
} else if (splitter.match_start("Texture Vertices")) { } else if (splitter.match_start("Texture Vertices")) {
@ -723,13 +727,12 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) { for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) {
const char *s = splitter->c_str(); const char *s = splitter->c_str();
const char *end = splitter.getEnd();
aiVector2D &v = msh.texture_coords[cur]; aiVector2D &v = msh.texture_coords[cur];
SkipSpaces(&s, end); SkipSpaces(&s);
v.x = fast_atof(&s); v.x = fast_atof(&s);
SkipSpaces(&s, end); SkipSpaces(&s);
v.y = fast_atof(&s); v.y = fast_atof(&s);
} }
} else if (splitter.match_start("Faces")) { } else if (splitter.match_start("Faces")) {
@ -754,9 +757,8 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
face.material = strtoul10(splitter[6]); face.material = strtoul10(splitter[6]);
const char *s = (++splitter)->c_str(); const char *s = (++splitter)->c_str();
const char *end = splitter.getEnd();
for (size_t i = 0; i < face.indices.size(); ++i) { for (size_t i = 0; i < face.indices.size(); ++i) {
if (!SkipSpaces(&s, end)) { if (!SkipSpaces(&s)) {
ThrowException("Expected EOL token in Face entry"); ThrowException("Expected EOL token in Face entry");
} }
if ('<' != *s++) { if ('<' != *s++) {
@ -1170,6 +1172,4 @@ void COBImporter::ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const
ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist"); ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
} }
}
#endif // ASSIMP_BUILD_NO_COB_IMPORTER #endif // ASSIMP_BUILD_NO_COB_IMPORTER

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -75,8 +75,8 @@ namespace COB {
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class COBImporter : public BaseImporter { class COBImporter : public BaseImporter {
public: public:
COBImporter() = default; COBImporter();
~COBImporter() override = default; ~COBImporter() override;
// -------------------- // --------------------
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
@ -120,7 +120,7 @@ private:
void ReadChunkInfo_Ascii(COB::ChunkInfo &out, const LineSplitter &splitter); void ReadChunkInfo_Ascii(COB::ChunkInfo &out, const LineSplitter &splitter);
void ReadBasicNodeInfo_Ascii(COB::Node &msh, LineSplitter &splitter, const COB::ChunkInfo &nfo); void ReadBasicNodeInfo_Ascii(COB::Node &msh, LineSplitter &splitter, const COB::ChunkInfo &nfo);
template <typename T> template <typename T>
void ReadFloat3Tuple_Ascii(T &fill, const char **in, const char *end); void ReadFloat3Tuple_Ascii(T &fill, const char **in);
void ReadPolH_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo); void ReadPolH_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadBitM_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo); void ReadBitM_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
@ -44,6 +44,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file CSMLoader.cpp /** @file CSMLoader.cpp
* Implementation of the CSM importer class. * Implementation of the CSM importer class.
*/ */
#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER #ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
#include "CSMLoader.h" #include "CSMLoader.h"
@ -60,7 +63,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"CharacterStudio Motion Importer (MoCap)", "CharacterStudio Motion Importer (MoCap)",
"", "",
"", "",
@ -76,26 +79,33 @@ static constexpr aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
CSMImporter::CSMImporter() : noSkeletonMesh(){ CSMImporter::CSMImporter()
// empty : noSkeletonMesh()
} {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
CSMImporter::~CSMImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const { bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
{
static const char* tokens[] = {"$Filename"}; static const char* tokens[] = {"$Filename"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens)); return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Build a string of all file extensions supported // Build a string of all file extensions supported
const aiImporterDesc* CSMImporter::GetInfo () const { const aiImporterDesc* CSMImporter::GetInfo () const
{
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader // Setup configuration properties for the loader
void CSMImporter::SetupProperties(const Importer* pImp) { void CSMImporter::SetupProperties(const Importer* pImp)
{
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0; noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
} }
@ -115,29 +125,29 @@ void CSMImporter::InternReadFile( const std::string& pFile,
std::vector<char> mBuffer2; std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2); TextFileToBuffer(file.get(),mBuffer2);
const char* buffer = &mBuffer2[0]; const char* buffer = &mBuffer2[0];
const char *end = &mBuffer2[mBuffer2.size() - 1] + 1;
std::unique_ptr<aiAnimation> anim(new aiAnimation()); std::unique_ptr<aiAnimation> anim(new aiAnimation());
int first = 0, last = 0x00ffffff; int first = 0, last = 0x00ffffff;
// now process the file and look out for '$' sections // now process the file and look out for '$' sections
while (true) { while (true) {
SkipSpaces(&buffer, end); SkipSpaces(&buffer);
if ('\0' == *buffer) if ('\0' == *buffer)
break; break;
if ('$' == *buffer) { if ('$' == *buffer) {
++buffer; ++buffer;
if (TokenMatchI(buffer,"firstframe",10)) { if (TokenMatchI(buffer,"firstframe",10)) {
SkipSpaces(&buffer, end); SkipSpaces(&buffer);
first = strtol10(buffer,&buffer); first = strtol10(buffer,&buffer);
} }
else if (TokenMatchI(buffer,"lastframe",9)) { else if (TokenMatchI(buffer,"lastframe",9)) {
SkipSpaces(&buffer, end); SkipSpaces(&buffer);
last = strtol10(buffer,&buffer); last = strtol10(buffer,&buffer);
} }
else if (TokenMatchI(buffer,"rate",4)) { else if (TokenMatchI(buffer,"rate",4)) {
SkipSpaces(&buffer, end); SkipSpaces(&buffer);
float d = { 0.0f }; float d;
buffer = fast_atoreal_move<float>(buffer,d); buffer = fast_atoreal_move<float>(buffer,d);
anim->mTicksPerSecond = d; anim->mTicksPerSecond = d;
} }
@ -145,8 +155,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
std::vector< aiNodeAnim* > anims_temp; std::vector< aiNodeAnim* > anims_temp;
anims_temp.reserve(30); anims_temp.reserve(30);
while (true) { while (true) {
SkipSpaces(&buffer, end); SkipSpaces(&buffer);
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer, end) && *buffer == '$') if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
break; // next section break; // next section
// Construct a new node animation channel and setup its name // Construct a new node animation channel and setup its name
@ -154,43 +164,41 @@ void CSMImporter::InternReadFile( const std::string& pFile,
aiNodeAnim* nda = anims_temp.back(); aiNodeAnim* nda = anims_temp.back();
char* ot = nda->mNodeName.data; char* ot = nda->mNodeName.data;
while (!IsSpaceOrNewLine(*buffer)) { while (!IsSpaceOrNewLine(*buffer))
*ot++ = *buffer++; *ot++ = *buffer++;
}
*ot = '\0'; *ot = '\0';
nda->mNodeName.length = static_cast<ai_uint32>(ot-nda->mNodeName.data); nda->mNodeName.length = static_cast<ai_uint32>(ot-nda->mNodeName.data);
} }
anim->mNumChannels = static_cast<unsigned int>(anims_temp.size()); anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());
if (!anim->mNumChannels) { if (!anim->mNumChannels)
throw DeadlyImportError("CSM: Empty $order section"); throw DeadlyImportError("CSM: Empty $order section");
}
// copy over to the output animation // copy over to the output animation
anim->mChannels = new aiNodeAnim*[anim->mNumChannels]; anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels); ::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
} else if (TokenMatchI(buffer,"points",6)) {
if (!anim->mNumChannels) {
throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
} }
else if (TokenMatchI(buffer,"points",6)) {
if (!anim->mNumChannels)
throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
// If we know how many frames we'll read, we can preallocate some storage // If we know how many frames we'll read, we can preallocate some storage
unsigned int alloc = 100; unsigned int alloc = 100;
if (last != 0x00ffffff) { if (last != 0x00ffffff)
{
alloc = last-first; alloc = last-first;
alloc += alloc>>2u; // + 25% alloc += alloc>>2u; // + 25%
for (unsigned int i = 0; i < anim->mNumChannels; ++i) { for (unsigned int i = 0; i < anim->mNumChannels;++i)
anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc]; anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
} }
}
unsigned int filled = 0; unsigned int filled = 0;
// Now read all point data. // Now read all point data.
while (true) { while (true) {
SkipSpaces(&buffer, end); SkipSpaces(&buffer);
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer, end) || *buffer == '$')) { if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
break; // next section break; // next section
} }
@ -201,8 +209,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
for (unsigned int i = 0; i < anim->mNumChannels;++i) { for (unsigned int i = 0; i < anim->mNumChannels;++i) {
aiNodeAnim* s = anim->mChannels[i]; aiNodeAnim* s = anim->mChannels[i];
if (s->mNumPositionKeys == alloc) { if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
// need to reallocate?
aiVectorKey* old = s->mPositionKeys; aiVectorKey* old = s->mPositionKeys;
s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2]; s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc); ::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
@ -210,26 +218,24 @@ void CSMImporter::InternReadFile( const std::string& pFile,
} }
// read x,y,z // read x,y,z
if (!SkipSpacesAndLineEnd(&buffer, end)) { if(!SkipSpacesAndLineEnd(&buffer))
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample x coord"); throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample x coord");
}
if (TokenMatchI(buffer, "DROPOUT", 7)) { if (TokenMatchI(buffer, "DROPOUT", 7)) {
// seems this is invalid marker data; at least the doc says it's possible // seems this is invalid marker data; at least the doc says it's possible
ASSIMP_LOG_WARN("CSM: Encountered invalid marker data (DROPOUT)"); ASSIMP_LOG_WARN("CSM: Encountered invalid marker data (DROPOUT)");
} else { }
else {
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys; aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
sub->mTime = (double)frame; sub->mTime = (double)frame;
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x); buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
if (!SkipSpacesAndLineEnd(&buffer, end)) { if(!SkipSpacesAndLineEnd(&buffer))
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord"); throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord");
}
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y); buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
if (!SkipSpacesAndLineEnd(&buffer, end)) { if(!SkipSpacesAndLineEnd(&buffer))
throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord"); throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord");
}
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z); buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
++s->mNumPositionKeys; ++s->mNumPositionKeys;
@ -237,22 +243,22 @@ void CSMImporter::InternReadFile( const std::string& pFile,
} }
// update allocation granularity // update allocation granularity
if (filled == alloc) { if (filled == alloc)
alloc *= 2; alloc *= 2;
}
++filled; ++filled;
} }
// all channels must be complete in order to continue safely. // all channels must be complete in order to continue safely.
for (unsigned int i = 0; i < anim->mNumChannels;++i) { for (unsigned int i = 0; i < anim->mNumChannels;++i) {
if (!anim->mChannels[i]->mNumPositionKeys) {
if (!anim->mChannels[i]->mNumPositionKeys)
throw DeadlyImportError("CSM: Invalid marker track"); throw DeadlyImportError("CSM: Invalid marker track");
} }
} }
} }
} else { else {
// advance to the next line // advance to the next line
SkipLine(&buffer, end); SkipLine(&buffer);
} }
} }

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -61,7 +61,7 @@ namespace Assimp {
class CSMImporter : public BaseImporter { class CSMImporter : public BaseImporter {
public: public:
CSMImporter(); CSMImporter();
~CSMImporter() override = default; ~CSMImporter() override;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
@ -81,8 +81,9 @@ protected:
private: private:
bool noSkeletonMesh; bool noSkeletonMesh;
}; }; // end of class CSMImporter
} // namespace Assimp } // end of namespace Assimp
#endif // AI_AC3DIMPORTER_H_INC #endif // AI_AC3DIMPORTER_H_INC

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -64,7 +64,7 @@ namespace Assimp {
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
using namespace Assimp::Collada; using namespace Assimp::Collada;
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"Collada Importer", "Collada Importer",
"", "",
"", "",
@ -95,12 +95,15 @@ ColladaLoader::ColladaLoader() :
noSkeletonMesh(false), noSkeletonMesh(false),
removeEmptyBones(false), removeEmptyBones(false),
ignoreUpDirection(false), ignoreUpDirection(false),
ignoreUnitSize(false),
useColladaName(false), useColladaName(false),
mNodeNameCounter(0) { mNodeNameCounter(0) {
// empty // empty
} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
ColladaLoader::~ColladaLoader() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@ -119,7 +122,6 @@ void ColladaLoader::SetupProperties(const Importer *pImp) {
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0; noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0; removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0;
ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0; ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
ignoreUnitSize = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UNIT_SIZE, 0) != 0;
useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0; useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0;
} }
@ -168,15 +170,12 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
// ... then fill the materials with the now adjusted settings // ... then fill the materials with the now adjusted settings
FillMaterials(parser, pScene); FillMaterials(parser, pScene);
if (!ignoreUnitSize) {
// Apply unit-size scale calculation // Apply unit-size scale calculation
pScene->mRootNode->mTransformation *= aiMatrix4x4(
parser.mUnitSize, 0, 0, 0, pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
0, parser.mUnitSize, 0, 0, 0, parser.mUnitSize, 0, 0,
0, 0, parser.mUnitSize, 0, 0, 0, parser.mUnitSize, 0,
0, 0, 0, 1); 0, 0, 0, 1);
}
if (!ignoreUpDirection) { if (!ignoreUpDirection) {
// Convert to Y_UP, if different orientation // Convert to Y_UP, if different orientation
if (parser.mUpDirection == ColladaParser::UP_X) { if (parser.mUpDirection == ColladaParser::UP_X) {
@ -247,9 +246,7 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
// add children. first the *real* ones // add children. first the *real* ones
node->mNumChildren = static_cast<unsigned int>(pNode->mChildren.size() + instances.size()); node->mNumChildren = static_cast<unsigned int>(pNode->mChildren.size() + instances.size());
if (node->mNumChildren != 0) {
node->mChildren = new aiNode *[node->mNumChildren]; node->mChildren = new aiNode *[node->mNumChildren];
}
for (size_t a = 0; a < pNode->mChildren.size(); ++a) { for (size_t a = 0; a < pNode->mChildren.size(); ++a) {
node->mChildren[a] = BuildHierarchy(pParser, pNode->mChildren[a]); node->mChildren[a] = BuildHierarchy(pParser, pNode->mChildren[a]);
@ -625,14 +622,16 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
} }
// same for texture coords, as many as we have // same for texture coords, as many as we have
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { // empty slots are not allowed, need to pack and adjust UV indexes accordingly
for (size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices) { if (pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices) {
dstMesh->mTextureCoords[a] = new aiVector3D[numVertices]; dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
for (size_t b = 0; b < numVertices; ++b) { for (size_t b = 0; b < numVertices; ++b) {
dstMesh->mTextureCoords[a][b] = pSrcMesh->mTexCoords[a][pStartVertex + b]; dstMesh->mTextureCoords[real][b] = pSrcMesh->mTexCoords[a][pStartVertex + b];
} }
dstMesh->mNumUVComponents[a] = pSrcMesh->mNumUVComponents[a]; dstMesh->mNumUVComponents[real] = pSrcMesh->mNumUVComponents[a];
++real;
} }
} }

View File

@ -4,7 +4,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -86,7 +86,7 @@ public:
ColladaLoader(); ColladaLoader();
/// The class destructor. /// The class destructor.
~ColladaLoader() override = default; ~ColladaLoader() override;
/// Returns whether the class can handle the format of the given file. /// Returns whether the class can handle the format of the given file.
/// @see BaseImporter::CanRead() for more details. /// @see BaseImporter::CanRead() for more details.
@ -239,7 +239,6 @@ protected:
bool noSkeletonMesh; bool noSkeletonMesh;
bool removeEmptyBones; bool removeEmptyBones;
bool ignoreUpDirection; bool ignoreUpDirection;
bool ignoreUnitSize;
bool useColladaName; bool useColladaName;
/** Used by FindNameForNode() to generate unique node names */ /** Used by FindNameForNode() to generate unique node names */

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -635,8 +635,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "morph") { if (currentName == "morph") {
controller.mType = Morph; controller.mType = Morph;
std::string id = currentNode.attribute("source").as_string(); controller.mMeshId = currentNode.attribute("source").as_string();
controller.mMeshId = id.substr(1, id.size() - 1);
int methodIndex = currentNode.attribute("method").as_int(); int methodIndex = currentNode.attribute("method").as_int();
if (methodIndex > 0) { if (methodIndex > 0) {
std::string method; std::string method;
@ -655,13 +654,12 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
std::string v; std::string v;
XmlParser::getValueAsString(currentNode, v); XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str(); const char *content = v.c_str();
const char *end = content + v.size();
for (unsigned int a = 0; a < 16; a++) { for (unsigned int a = 0; a < 16; a++) {
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
// read a number // read a number
content = fast_atoreal_move<ai_real>(content, controller.mBindShapeMatrix[a]); content = fast_atoreal_move<ai_real>(content, controller.mBindShapeMatrix[a]);
// skip whitespace after it // skip whitespace after it
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
} }
} else if (currentName == "source") { } else if (currentName == "source") {
ReadSource(currentNode); ReadSource(currentNode);
@ -742,9 +740,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <vertex_weights> data <input> element"); throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <vertex_weights> data <input> element");
} }
} else if (currentName == "vcount" && vertexCount > 0) { } else if (currentName == "vcount" && vertexCount > 0) {
const std::string stdText = currentNode.text().as_string(); const char *text = currentNode.text().as_string();
const char *text = stdText.c_str();
const char *end = text + stdText.size();
size_t numWeights = 0; size_t numWeights = 0;
for (std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) { for (std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
if (*text == 0) { if (*text == 0) {
@ -753,7 +749,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
*it = strtoul10(text, &text); *it = strtoul10(text, &text);
numWeights += *it; numWeights += *it;
SkipSpacesAndLineEnd(&text, end); SkipSpacesAndLineEnd(&text);
} }
// reserve weight count // reserve weight count
pController.mWeights.resize(numWeights); pController.mWeights.resize(numWeights);
@ -762,19 +758,18 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
std::string stdText; std::string stdText;
XmlParser::getValueAsString(currentNode, stdText); XmlParser::getValueAsString(currentNode, stdText);
const char *text = stdText.c_str(); const char *text = stdText.c_str();
const char *end = text + stdText.size();
for (std::vector<std::pair<size_t, size_t>>::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) { for (std::vector<std::pair<size_t, size_t>>::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) {
if (text == nullptr) { if (text == nullptr) {
throw DeadlyImportError("Out of data while reading <vertex_weights>"); throw DeadlyImportError("Out of data while reading <vertex_weights>");
} }
SkipSpacesAndLineEnd(&text, end); SkipSpacesAndLineEnd(&text);
it->first = strtoul10(text, &text); it->first = strtoul10(text, &text);
SkipSpacesAndLineEnd(&text, end); SkipSpacesAndLineEnd(&text);
if (*text == 0) { if (*text == 0) {
throw DeadlyImportError("Out of data while reading <vertex_weights>"); throw DeadlyImportError("Out of data while reading <vertex_weights>");
} }
it->second = strtoul10(text, &text); it->second = strtoul10(text, &text);
SkipSpacesAndLineEnd(&text, end); SkipSpacesAndLineEnd(&text);
} }
} }
} }
@ -819,6 +814,7 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
if (!pImage.mFileName.length()) { if (!pImage.mFileName.length()) {
pImage.mFileName = "unknown_texture"; pImage.mFileName = "unknown_texture";
} }
}
} else if (mFormat == FV_1_5_n) { } else if (mFormat == FV_1_5_n) {
std::string value; std::string value;
XmlNode refChild = currentNode.child("ref"); XmlNode refChild = currentNode.child("ref");
@ -855,7 +851,6 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
} }
} }
} }
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the material library // Reads the material library
@ -957,45 +952,44 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
std::string v; std::string v;
XmlParser::getValueAsString(currentNode, v); XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str(); const char *content = v.c_str();
const char *end = content + v.size();
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.r); content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.r);
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.g); content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.g);
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b); content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
} else if (currentName == "constant_attenuation") { } else if (currentName == "constant_attenuation") {
XmlParser::getValueAsReal(currentNode, pLight.mAttConstant); XmlParser::getValueAsFloat(currentNode, pLight.mAttConstant);
} else if (currentName == "linear_attenuation") { } else if (currentName == "linear_attenuation") {
XmlParser::getValueAsReal(currentNode, pLight.mAttLinear); XmlParser::getValueAsFloat(currentNode, pLight.mAttLinear);
} else if (currentName == "quadratic_attenuation") { } else if (currentName == "quadratic_attenuation") {
XmlParser::getValueAsReal(currentNode, pLight.mAttQuadratic); XmlParser::getValueAsFloat(currentNode, pLight.mAttQuadratic);
} else if (currentName == "falloff_angle") { } else if (currentName == "falloff_angle") {
XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle); XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
} else if (currentName == "falloff_exponent") { } else if (currentName == "falloff_exponent") {
XmlParser::getValueAsReal(currentNode, pLight.mFalloffExponent); XmlParser::getValueAsFloat(currentNode, pLight.mFalloffExponent);
} }
// FCOLLADA extensions // FCOLLADA extensions
// ------------------------------------------------------- // -------------------------------------------------------
else if (currentName == "outer_cone") { else if (currentName == "outer_cone") {
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle); XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
} else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone } else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone
XmlParser::getValueAsReal(currentNode, pLight.mPenumbraAngle); XmlParser::getValueAsFloat(currentNode, pLight.mPenumbraAngle);
} else if (currentName == "intensity") { } else if (currentName == "intensity") {
XmlParser::getValueAsReal(currentNode, pLight.mIntensity); XmlParser::getValueAsFloat(currentNode, pLight.mIntensity);
} }
else if (currentName == "falloff") { else if (currentName == "falloff") {
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle); XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
} else if (currentName == "hotspot_beam") { } else if (currentName == "hotspot_beam") {
XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle); XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
} }
// OpenCOLLADA extensions // OpenCOLLADA extensions
// ------------------------------------------------------- // -------------------------------------------------------
else if (currentName == "decay_falloff") { else if (currentName == "decay_falloff") {
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle); XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
} }
} }
} }
@ -1010,15 +1004,15 @@ void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) {
if (currentName == "orthographic") { if (currentName == "orthographic") {
camera.mOrtho = true; camera.mOrtho = true;
} else if (currentName == "xfov" || currentName == "xmag") { } else if (currentName == "xfov" || currentName == "xmag") {
XmlParser::getValueAsReal(currentNode, camera.mHorFov); XmlParser::getValueAsFloat(currentNode, camera.mHorFov);
} else if (currentName == "yfov" || currentName == "ymag") { } else if (currentName == "yfov" || currentName == "ymag") {
XmlParser::getValueAsReal(currentNode, camera.mVerFov); XmlParser::getValueAsFloat(currentNode, camera.mVerFov);
} else if (currentName == "aspect_ratio") { } else if (currentName == "aspect_ratio") {
XmlParser::getValueAsReal(currentNode, camera.mAspect); XmlParser::getValueAsFloat(currentNode, camera.mAspect);
} else if (currentName == "znear") { } else if (currentName == "znear") {
XmlParser::getValueAsReal(currentNode, camera.mZNear); XmlParser::getValueAsFloat(currentNode, camera.mZNear);
} else if (currentName == "zfar") { } else if (currentName == "zfar") {
XmlParser::getValueAsReal(currentNode, camera.mZFar); XmlParser::getValueAsFloat(currentNode, camera.mZFar);
} }
} }
} }
@ -1170,15 +1164,15 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
} else if (currentName == "mirrorV") { } else if (currentName == "mirrorV") {
XmlParser::getValueAsBool(currentNode, out.mMirrorV); XmlParser::getValueAsBool(currentNode, out.mMirrorV);
} else if (currentName == "repeatU") { } else if (currentName == "repeatU") {
XmlParser::getValueAsReal(currentNode, out.mTransform.mScaling.x); XmlParser::getValueAsFloat(currentNode, out.mTransform.mScaling.x);
} else if (currentName == "repeatV") { } else if (currentName == "repeatV") {
XmlParser::getValueAsReal(currentNode, out.mTransform.mScaling.y); XmlParser::getValueAsFloat(currentNode, out.mTransform.mScaling.y);
} else if (currentName == "offsetU") { } else if (currentName == "offsetU") {
XmlParser::getValueAsReal(currentNode, out.mTransform.mTranslation.x); XmlParser::getValueAsFloat(currentNode, out.mTransform.mTranslation.x);
} else if (currentName == "offsetV") { } else if (currentName == "offsetV") {
XmlParser::getValueAsReal(currentNode, out.mTransform.mTranslation.y); XmlParser::getValueAsFloat(currentNode, out.mTransform.mTranslation.y);
} else if (currentName == "rotateUV") { } else if (currentName == "rotateUV") {
XmlParser::getValueAsReal(currentNode, out.mTransform.mRotation); XmlParser::getValueAsFloat(currentNode, out.mTransform.mRotation);
} else if (currentName == "blend_mode") { } else if (currentName == "blend_mode") {
std::string v; std::string v;
XmlParser::getValueAsString(currentNode, v); XmlParser::getValueAsString(currentNode, v);
@ -1198,14 +1192,14 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
// OKINO extensions // OKINO extensions
// ------------------------------------------------------- // -------------------------------------------------------
else if (currentName == "weighting") { else if (currentName == "weighting") {
XmlParser::getValueAsReal(currentNode, out.mWeighting); XmlParser::getValueAsFloat(currentNode, out.mWeighting);
} else if (currentName == "mix_with_previous_layer") { } else if (currentName == "mix_with_previous_layer") {
XmlParser::getValueAsReal(currentNode, out.mMixWithPrevious); XmlParser::getValueAsFloat(currentNode, out.mMixWithPrevious);
} }
// MAX3D extensions // MAX3D extensions
// ------------------------------------------------------- // -------------------------------------------------------
else if (currentName == "amount") { else if (currentName == "amount") {
XmlParser::getValueAsReal(currentNode, out.mWeighting); XmlParser::getValueAsFloat(currentNode, out.mWeighting);
} }
} }
} }
@ -1226,19 +1220,18 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
std::string v; std::string v;
XmlParser::getValueAsString(currentNode, v); XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str(); const char *content = v.c_str();
const char *end = v.c_str() + v.size() + 1;
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r); content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r);
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.g); content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.g);
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.b); content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.b);
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.a); content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.a);
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
} else if (currentName == "texture") { } else if (currentName == "texture") {
// get name of source texture/sampler // get name of source texture/sampler
XmlParser::getStdStrAttribute(currentNode, "texture", pSampler.mName); XmlParser::getStdStrAttribute(currentNode, "texture", pSampler.mName);
@ -1265,13 +1258,13 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an effect entry containing a float // Reads an effect entry containing a float
void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pReal) { void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pFloat) {
pReal = 0.f; pFloat = 0.f;
XmlNode floatNode = node.child("float"); XmlNode floatNode = node.child("float");
if (floatNode.empty()) { if (floatNode.empty()) {
return; return;
} }
XmlParser::getValueAsReal(floatNode, pReal); XmlParser::getValueAsFloat(floatNode, pFloat);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1281,7 +1274,9 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
return; return;
} }
for (XmlNode &currentNode : node.children()) { XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "surface") { if (currentName == "surface") {
// image ID given inside <init_from> tags // image ID given inside <init_from> tags
@ -1294,24 +1289,22 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
} }
} else if (currentName == "sampler2D" && (FV_1_4_n == mFormat || FV_1_3_n == mFormat)) { } else if (currentName == "sampler2D" && (FV_1_4_n == mFormat || FV_1_3_n == mFormat)) {
// surface ID is given inside <source> tags // surface ID is given inside <source> tags
XmlNode source = currentNode.child("source"); const char *content = currentNode.value();
if (source) {
std::string v;
XmlParser::getValueAsString(source, v);
pParam.mType = Param_Sampler; pParam.mType = Param_Sampler;
pParam.mReference = v.c_str(); pParam.mReference = content;
}
} else if (currentName == "sampler2D") { } else if (currentName == "sampler2D") {
// surface ID is given inside <instance_image> tags // surface ID is given inside <instance_image> tags
XmlNode instance_image = currentNode.child("instance_image");
if (instance_image) {
std::string url; std::string url;
XmlParser::getStdStrAttribute(instance_image, "url", url); XmlParser::getStdStrAttribute(currentNode, "url", url);
if (url[0] != '#') { if (url[0] != '#') {
throw DeadlyImportError("Unsupported URL format in instance_image"); throw DeadlyImportError("Unsupported URL format in instance_image");
} }
pParam.mType = Param_Sampler; pParam.mType = Param_Sampler;
pParam.mReference = url.c_str() + 1; pParam.mReference = url.c_str() + 1;
} else if (currentName == "source") {
const char *source = currentNode.child_value();
if (nullptr != source) {
pParam.mReference = source;
} }
} }
} }
@ -1352,7 +1345,6 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
if (node.empty()) { if (node.empty()) {
return; return;
} }
for (XmlNode &currentNode : node.children()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "mesh") { if (currentName == "mesh") {
@ -1423,7 +1415,6 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
XmlParser::getValueAsString(node, v); XmlParser::getValueAsString(node, v);
v = ai_trim(v); v = ai_trim(v);
const char *content = v.c_str(); const char *content = v.c_str();
const char *end = content + v.size();
// read values and store inside an array in the data library // read values and store inside an array in the data library
mDataLibrary[id] = Data(); mDataLibrary[id] = Data();
@ -1442,13 +1433,11 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
} }
s.clear(); s.clear();
while (!IsSpaceOrNewLine(*content)) { while (!IsSpaceOrNewLine(*content))
s += *content; s += *content++;
content++;
}
data.mStrings.push_back(s); data.mStrings.push_back(s);
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
} }
} else { } else {
data.mValues.reserve(count); data.mValues.reserve(count);
@ -1463,7 +1452,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
content = fast_atoreal_move<ai_real>(content, value); content = fast_atoreal_move<ai_real>(content, value);
data.mValues.push_back(value); data.mValues.push_back(value);
// skip whitespace after it // skip whitespace after it
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
} }
} }
} }
@ -1628,10 +1617,8 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
std::string v; std::string v;
XmlParser::getValueAsString(currentNode, v); XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str(); const char *content = v.c_str();
const char *end = content + v.size();
vcount.reserve(numPrimitives); vcount.reserve(numPrimitives);
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
for (unsigned int a = 0; a < numPrimitives; a++) { for (unsigned int a = 0; a < numPrimitives; a++) {
if (*content == 0) { if (*content == 0) {
throw DeadlyImportError("Expected more values while reading <vcount> contents."); throw DeadlyImportError("Expected more values while reading <vcount> contents.");
@ -1639,7 +1626,7 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
// read a number // read a number
vcount.push_back((size_t)strtoul10(content, &content)); vcount.push_back((size_t)strtoul10(content, &content));
// skip whitespace after it // skip whitespace after it
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
} }
} }
} }
@ -1748,16 +1735,14 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
std::string v; std::string v;
XmlParser::getValueAsString(node, v); XmlParser::getValueAsString(node, v);
const char *content = v.c_str(); const char *content = v.c_str();
const char *end = content + v.size(); SkipSpacesAndLineEnd(&content);
SkipSpacesAndLineEnd(&content, end);
while (*content != 0) { while (*content != 0) {
// read a value. // read a value.
// Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways. // Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways.
int value = std::max(0, strtol10(content, &content)); int value = std::max(0, strtol10(content, &content));
indices.push_back(size_t(value)); indices.push_back(size_t(value));
// skip whitespace after it // skip whitespace after it
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
} }
} }
@ -1787,10 +1772,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
const Accessor *acc = input.mResolved; const Accessor *acc = input.mResolved;
if (!acc->mData) { if (!acc->mData) {
acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource); 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 // and the same for the per-index channels
@ -1815,19 +1796,13 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
const Accessor *acc = input.mResolved; const Accessor *acc = input.mResolved;
if (!acc->mData) { if (!acc->mData) {
acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource); 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 <p>, but only one primitive per <p> // For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
size_t numPrimitives = pNumPrimitives; size_t numPrimitives = pNumPrimitives;
if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon) { if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon)
numPrimitives = 1; numPrimitives = 1;
}
// For continued primitives, the given count is actually the number of <p>'s inside the parent tag // For continued primitives, the given count is actually the number of <p>'s inside the parent tag
if (pPrimType == Prim_TriStrips) { if (pPrimType == Prim_TriStrips) {
size_t numberOfVertices = indices.size() / numOffsets; size_t numberOfVertices = indices.size() / numOffsets;
@ -1892,7 +1867,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
///@note This function won't work correctly if both PerIndex and PerVertex channels have same channels. ///@note This function won't work correctly if both PerIndex and PerVertex channels have same channels.
///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates. ///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates.
///It's not clear from COLLADA documentation whether this is allowed or not. For now only exporter fixed to avoid such behavior ///It's not clear from COLLADA documentation is this allowed or not. For now only exporter fixed to avoid such behavior
void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh, void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh,
std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) { std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) {
// calculate the base offset of the vertex whose attributes we ant to copy // calculate the base offset of the vertex whose attributes we ant to copy
@ -2191,15 +2166,15 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
} }
// how many parameters to read per transformation type // how many parameters to read per transformation type
static constexpr unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 }; static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
std::string value; std::string value;
XmlParser::getValueAsString(node, value); XmlParser::getValueAsString(node, value);
const char *content = value.c_str(); const char *content = value.c_str();
const char *end = value.c_str() + value.size();
// read as many parameters and store in the transformation // read as many parameters and store in the transformation
for (unsigned int a = 0; a < sNumParameters[pType]; a++) { for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
// skip whitespace before the number // skip whitespace before the number
SkipSpacesAndLineEnd(&content, end); SkipSpacesAndLineEnd(&content);
// read a number // read a number
content = fast_atoreal_move<ai_real>(content, tf.f[a]); content = fast_atoreal_move<ai_real>(content, tf.f[a]);
} }
@ -2293,9 +2268,9 @@ void ColladaParser::ReadNodeGeometry(XmlNode &node, Node *pNode) {
urlMat++; urlMat++;
s.mMatName = urlMat; s.mMatName = urlMat;
ReadMaterialVertexInputBinding(instanceMatNode, s);
// store the association // store the association
instance.mMaterials[group] = s; instance.mMaterials[group] = s;
ReadMaterialVertexInputBinding(instanceMatNode, s);
} }
} }
} }

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the DXF importer class * @brief Implementation of the DXF importer class
*/ */
#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER #ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
#include "AssetLib/DXF/DXFLoader.h" #include "AssetLib/DXF/DXFLoader.h"
@ -67,269 +68,26 @@ static constexpr size_t AI_DXF_BINARY_IDENT_LEN = sizeof AI_DXF_BINARY_IDENT;
// default vertex color that all uncolored vertices will receive // 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)); static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
// color indices for DXF - 256 are supported, the table is // color indices for DXF - 16 are supported, the table is
// taken directly from the AutoCad Index (ACI) table // taken directly from the DXF spec.
// https://gohtx.com/acadcolors.php static aiColor4D g_aclrDxfIndexColors[] = {
//STH 2024-0126 aiColor4D (0.6f, 0.6f, 0.6f, 1.0f),
static const aiColor4D g_aclrDxfIndexColors[256] = { aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
aiColor4D (0.0f, 0.0f ,0.0f, 1.0f), //dxf color code 0 aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 1 aiColor4D (0.0f, 0.0f, 1.0f, 1.0f), // blue
aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 2 aiColor4D (0.3f, 1.0f, 0.3f, 1.0f), // light green
aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 3 aiColor4D (0.3f, 0.3f, 1.0f, 1.0f), // light blue
aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 4 aiColor4D (1.0f, 0.3f, 0.3f, 1.0f), // light red
aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 5 aiColor4D (1.0f, 0.0f, 1.0f, 1.0f), // pink
aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 6 aiColor4D (1.0f, 0.6f, 0.0f, 1.0f), // orange
aiColor4D (1.0f, 1.0f ,1.0f, 1.0f), //dxf color code 7 aiColor4D (0.6f, 0.3f, 0.0f, 1.0f), // dark orange
aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 8 aiColor4D (1.0f, 1.0f, 0.0f, 1.0f), // yellow
aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 9 aiColor4D (0.3f, 0.3f, 0.3f, 1.0f), // dark gray
aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 10 aiColor4D (0.8f, 0.8f, 0.8f, 1.0f), // light gray
aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 11 aiColor4D (0.0f, 00.f, 0.0f, 1.0f), // black
aiColor4D (0.7f, 0.0f ,0.0f, 1.0f), //dxf color code 12 aiColor4D (1.0f, 1.0f, 1.0f, 1.0f), // white
aiColor4D (0.7f, 0.5f ,0.5f, 1.0f), //dxf color code 13 aiColor4D (0.6f, 0.0f, 1.0f, 1.0f) // violet
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])) #define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
#define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC" #define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC"
@ -338,7 +96,7 @@ static const int GroupCode_XComp = 10;
static const int GroupCode_YComp = 20; static const int GroupCode_YComp = 20;
static const int GroupCode_ZComp = 30; static const int GroupCode_ZComp = 30;
static constexpr aiImporterDesc desc = { static const aiImporterDesc desc = {
"Drawing Interchange Format (DXF) Importer", "Drawing Interchange Format (DXF) Importer",
"", "",
"", "",
@ -351,6 +109,14 @@ static constexpr aiImporterDesc desc = {
"dxf" "dxf"
}; };
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
DXFImporter::DXFImporter() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
DXFImporter::~DXFImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool /*checkSig*/ ) const { bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool /*checkSig*/ ) const {
@ -463,7 +229,7 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) {
ASSIMP_LOG_VERBOSE_DEBUG("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount); ASSIMP_LOG_VERBOSE_DEBUG("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount);
} }
if (output.blocks.empty()) { if (! output.blocks.size() ) {
throw DeadlyImportError("DXF: no data blocks loaded"); throw DeadlyImportError("DXF: no data blocks loaded");
} }
@ -613,12 +379,8 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
// XXX order // XXX order
aiMatrix4x4 trafo, tmp; aiMatrix4x4 trafo, tmp;
aiMatrix4x4::Translation(-bl_src.base,trafo); aiMatrix4x4::Translation(-bl_src.base,trafo);
//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::Scaling(insert.scale,tmp);
//trafo *= aiMatrix4x4::Translation(insert.pos,tmp); trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
// XXX rotation currently ignored - I didn't find an appropriate sample model. // XXX rotation currently ignored - I didn't find an appropriate sample model.
if (insert.angle != 0.f) { if (insert.angle != 0.f) {
@ -825,11 +587,10 @@ void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output)
} }
} }
static constexpr unsigned int DXF_POLYLINE_FLAG_CLOSED = 0x1; #define DXF_POLYLINE_FLAG_CLOSED 0x1
// Currently unused #define DXF_POLYLINE_FLAG_3D_POLYLINE 0x8
//static constexpr unsigned int DXF_POLYLINE_FLAG_3D_POLYLINE = 0x8; #define DXF_POLYLINE_FLAG_3D_POLYMESH 0x10
//static constexpr unsigned int DXF_POLYLINE_FLAG_3D_POLYMESH = 0x10; #define DXF_POLYLINE_FLAG_POLYFACEMESH 0x40
static constexpr unsigned int DXF_POLYLINE_FLAG_POLYFACEMESH = 0x40;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) { void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) {
@ -878,6 +639,12 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
reader++; reader++;
} }
//if (!(line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH)) {
// DefaultLogger::get()->warn((Formatter::format("DXF: polyline not currently supported: "),line.flags));
// output.blocks.back().lines.pop_back();
// return;
//}
if (vguess && line.positions.size() != vguess) { if (vguess && line.positions.size() != vguess) {
ASSIMP_LOG_WARN("DXF: unexpected vertex count in polymesh: ", ASSIMP_LOG_WARN("DXF: unexpected vertex count in polymesh: ",
line.positions.size(),", expected ", vguess ); line.positions.size(),", expected ", vguess );
@ -967,18 +734,12 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
case 71: case 71:
case 72: case 72:
case 73: case 73:
case 74: { case 74:
if (cnti == 4) { if (cnti == 4) {
ASSIMP_LOG_WARN("DXF: more than 4 indices per face not supported; ignoring"); ASSIMP_LOG_WARN("DXF: more than 4 indices per face not supported; ignoring");
break; break;
} }
const int index = reader.ValueAsSignedInt(); indices[cnti++] = reader.ValueAsUnsignedInt();
if (index >= 0) {
indices[cnti++] = static_cast<unsigned int>(index);
} else {
indices[cnti++] = static_cast<unsigned int>(-index);
}
}
break; break;
// color // color
@ -1016,7 +777,8 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output) { void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
{
// (note) this is also used for for parsing line entities, so we // (note) this is also used for for parsing line entities, so we
// must handle the vertex_count == 2 case as well. // must handle the vertex_count == 2 case as well.
@ -1033,7 +795,8 @@ void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output) {
if (reader.GroupCode() == 0) { if (reader.GroupCode() == 0) {
break; break;
} }
switch (reader.GroupCode()) { switch (reader.GroupCode())
{
// 8 specifies the layer // 8 specifies the layer
case 8: case 8:

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -68,8 +68,8 @@ namespace DXF {
*/ */
class DXFImporter : public BaseImporter { class DXFImporter : public BaseImporter {
public: public:
DXFImporter() = default; DXFImporter();
~DXFImporter() override = default; ~DXFImporter() override;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXUtil.h" #include "FBXUtil.h"
#include <assimp/defs.h> #include <assimp/defs.h>
#include <stdint.h> #include <stdint.h>
#include <cstdint>
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include <assimp/ByteSwapper.h> #include <assimp/ByteSwapper.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
@ -343,7 +342,8 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ReadScope(TokenList &output_tokens, StackAllocator &token_allocator, const char *input, const char *&cursor, const char *end, bool const is64bits) { bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, bool const is64bits)
{
// the first word contains the offset at which this block ends // the first word contains the offset at which this block ends
const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end); const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
@ -409,7 +409,7 @@ bool ReadScope(TokenList &output_tokens, StackAllocator &token_allocator, const
// XXX this is vulnerable to stack overflowing .. // XXX this is vulnerable to stack overflowing ..
while(Offset(input, cursor) < end_offset - sentinel_block_length) { while(Offset(input, cursor) < end_offset - sentinel_block_length) {
ReadScope(output_tokens, token_allocator, input, cursor, input + end_offset - sentinel_block_length, is64bits); ReadScope(output_tokens, input, cursor, input + end_offset - sentinel_block_length, is64bits);
} }
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) )); output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
@ -432,7 +432,8 @@ bool ReadScope(TokenList &output_tokens, StackAllocator &token_allocator, const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent // TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
void TokenizeBinary(TokenList &output_tokens, const char *input, size_t length, StackAllocator &token_allocator) { void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
{
ai_assert(input); ai_assert(input);
ASSIMP_LOG_DEBUG("Tokenizing binary FBX file"); ASSIMP_LOG_DEBUG("Tokenizing binary FBX file");
@ -465,7 +466,7 @@ void TokenizeBinary(TokenList &output_tokens, const char *input, size_t length,
try try
{ {
while (cursor < end ) { while (cursor < end ) {
if (!ReadScope(output_tokens, token_allocator, input, cursor, input + length, is64bits)) { if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
break; break;
} }
} }

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -55,7 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/MathFunctions.h> #include <assimp/MathFunctions.h>
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/CreateAnimMesh.h> #include <assimp/CreateAnimMesh.h>
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include <assimp/commonMetaData.h> #include <assimp/commonMetaData.h>
@ -76,53 +78,6 @@ using namespace Util;
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL
static void correctRootTransform(const aiScene *scene) {
if (scene == nullptr) {
return;
}
if (scene->mMetaData == nullptr) {
return;
}
int32_t UpAxis = 1, UpAxisSign = 1, FrontAxis = 2, FrontAxisSign = 1, CoordAxis = 0, CoordAxisSign = 1;
double UnitScaleFactor = 1.0;
for (unsigned MetadataIndex = 0; MetadataIndex < scene->mMetaData->mNumProperties; ++MetadataIndex) {
if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "UpAxis") == 0) {
scene->mMetaData->Get<int32_t>(MetadataIndex, UpAxis);
}
if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "UpAxisSign") == 0) {
scene->mMetaData->Get<int32_t>(MetadataIndex, UpAxisSign);
}
if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "FrontAxis") == 0) {
scene->mMetaData->Get<int32_t>(MetadataIndex, FrontAxis);
}
if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "FrontAxisSign") == 0) {
scene->mMetaData->Get<int32_t>(MetadataIndex, FrontAxisSign);
}
if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "CoordAxis") == 0) {
scene->mMetaData->Get<int32_t>(MetadataIndex, CoordAxis);
}
if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "CoordAxisSign") == 0) {
scene->mMetaData->Get<int32_t>(MetadataIndex, CoordAxisSign);
}
if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "UnitScaleFactor") == 0) {
scene->mMetaData->Get<double>(MetadataIndex, UnitScaleFactor);
}
}
aiVector3D upVec, forwardVec, rightVec;
upVec[UpAxis] = UpAxisSign * static_cast<float>(UnitScaleFactor);
forwardVec[FrontAxis] = FrontAxisSign * static_cast<float>(UnitScaleFactor);
rightVec[CoordAxis] = CoordAxisSign * (float)UnitScaleFactor;
aiMatrix4x4 mat(rightVec.x, rightVec.y, rightVec.z, 0.0f,
upVec.x, upVec.y, upVec.z, 0.0f,
forwardVec.x, forwardVec.y, forwardVec.z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
scene->mRootNode->mTransformation *= mat;
}
FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBones) : FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBones) :
defaultMaterialIndex(), defaultMaterialIndex(),
mMeshes(), mMeshes(),
@ -138,8 +93,6 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
mSceneOut(out), mSceneOut(out),
doc(doc), doc(doc),
mRemoveEmptyBones(removeEmptyBones) { mRemoveEmptyBones(removeEmptyBones) {
// animations need to be converted first since this will // animations need to be converted first since this will
// populate the node_anim_chain_bits map, which is needed // populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated. // to determine which nodes need to be generated.
@ -180,10 +133,6 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
// need not contain geometry (i.e. camera animations, raw armatures). // need not contain geometry (i.e. camera animations, raw armatures).
if (out->mNumMeshes == 0) { if (out->mNumMeshes == 0) {
out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
} else {
// Apply the FBX axis metadata unless requested not to
if (!doc.Settings().ignoreUpDirection)
correctRootTransform(mSceneOut);
} }
} }
@ -312,8 +261,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
child->mParent = last_parent; child->mParent = last_parent;
last_parent = child.mNode; last_parent = child.mNode;
new_abs_transform *= child->mTransformation;
} }
// attach geometry // attach geometry
@ -336,8 +283,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
postnode->mParent = last_parent; postnode->mParent = last_parent;
last_parent = postnode.mNode; last_parent = postnode.mNode;
new_abs_transform *= postnode->mTransformation;
} }
} else { } else {
// free the nodes we allocated as we don't need them // free the nodes we allocated as we don't need them
@ -363,14 +308,14 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
if (nodes.empty()) { if (nodes.empty()) {
parent->mNumChildren = 0; parent->mNumChildren = 0;
parent->mChildren = nullptr; parent->mChildren = nullptr;
} else { }
parent->mChildren = new aiNode *[nodes.size()](); parent->mChildren = new aiNode *[nodes.size()]();
parent->mNumChildren = static_cast<unsigned int>(nodes.size()); parent->mNumChildren = static_cast<unsigned int>(nodes.size());
for (unsigned int i = 0; i < nodes.size(); ++i) { for (unsigned int i = 0; i < nodes.size(); ++i) {
parent->mChildren[i] = nodes[i].mOwnership.release(); parent->mChildren[i] = nodes[i].mOwnership.release();
} }
} }
}
void FBXConverter::ConvertLights(const Model &model, const std::string &orig_name) { void FBXConverter::ConvertLights(const Model &model, const std::string &orig_name) {
const std::vector<const NodeAttribute *> &node_attrs = model.GetAttributes(); const std::vector<const NodeAttribute *> &node_attrs = model.GetAttributes();
@ -482,26 +427,12 @@ void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name
out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f); out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f); out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
// NOTE: Some software (maya) does not put FieldOfView in FBX, so we compute out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView());
// mHorizontalFOV from FocalLength and FilmWidth with unit conversion.
// TODO: This is not a complete solution for how FBX cameras can be stored. out_camera->mClipPlaneNear = cam.NearPlane();
// TODO: Incorporate non-square pixel aspect ratio. out_camera->mClipPlaneFar = cam.FarPlane();
// TODO: FBX aperture mode might be storing vertical FOV in need of conversion with aspect ratio.
float fov_deg = cam.FieldOfView();
// If FOV not specified in file, compute using FilmWidth and FocalLength.
if (fov_deg == kFovUnknown) {
float film_width_inches = cam.FilmWidth();
float focal_length_mm = cam.FocalLength();
ASSIMP_LOG_VERBOSE_DEBUG("FBX FOV unspecified. Computing from FilmWidth (", film_width_inches, "inches) and FocalLength (", focal_length_mm, "mm).");
double half_fov_rad = std::atan2(film_width_inches * 25.4 * 0.5, focal_length_mm);
out_camera->mHorizontalFOV = static_cast<float>(half_fov_rad);
} else {
// FBX fov is full-view degrees. We want half-view radians.
out_camera->mHorizontalFOV = AI_DEG_TO_RAD(fov_deg) * 0.5f;
}
out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView());
out_camera->mClipPlaneNear = cam.NearPlane(); out_camera->mClipPlaneNear = cam.NearPlane();
out_camera->mClipPlaneFar = cam.FarPlane(); out_camera->mClipPlaneFar = cam.FarPlane();
} }
@ -630,17 +561,16 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
bool is_id[3] = { true, true, true }; bool is_id[3] = { true, true, true };
aiMatrix4x4 temp[3]; aiMatrix4x4 temp[3];
const auto rot = AI_DEG_TO_RAD(rotation); if (std::fabs(rotation.z) > angle_epsilon) {
if (std::fabs(rot.z) > angle_epsilon) { aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(rotation.z), temp[2]);
aiMatrix4x4::RotationZ(rot.z, temp[2]);
is_id[2] = false; is_id[2] = false;
} }
if (std::fabs(rot.y) > angle_epsilon) { if (std::fabs(rotation.y) > angle_epsilon) {
aiMatrix4x4::RotationY(rot.y, temp[1]); aiMatrix4x4::RotationY(AI_DEG_TO_RAD(rotation.y), temp[1]);
is_id[1] = false; is_id[1] = false;
} }
if (std::fabs(rot.x) > angle_epsilon) { if (std::fabs(rotation.x) > angle_epsilon) {
aiMatrix4x4::RotationX(rot.x, temp[0]); aiMatrix4x4::RotationX(AI_DEG_TO_RAD(rotation.x), temp[0]);
is_id[0] = false; is_id[0] = false;
} }
@ -1259,7 +1189,7 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
const auto &curNormals = shapeGeometry->GetNormals(); const auto &curNormals = shapeGeometry->GetNormals();
const auto &curIndices = shapeGeometry->GetIndices(); const auto &curIndices = shapeGeometry->GetIndices();
//losing channel name if using shapeGeometry->Name() //losing channel name if using shapeGeometry->Name()
// if blendShapeChannel Name is empty or doesn't have a ".", add geoMetryName; // if blendShapeChannel Name is empty or don't have a ".", add geoMetryName;
auto aniName = FixAnimMeshName(blendShapeChannel->Name()); auto aniName = FixAnimMeshName(blendShapeChannel->Name());
auto geoMetryName = FixAnimMeshName(shapeGeometry->Name()); auto geoMetryName = FixAnimMeshName(shapeGeometry->Name());
if (aniName.empty()) { if (aniName.empty()) {
@ -1657,7 +1587,7 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const ai
void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const Cluster *cluster, void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const Cluster *cluster,
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices, std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform, std::vector<size_t> &count_out_indices, const aiMatrix4x4 & /* absolute_transform*/,
aiNode *) { aiNode *) {
ai_assert(cluster != nullptr); // make sure cluster valid ai_assert(cluster != nullptr); // make sure cluster valid
@ -1674,16 +1604,16 @@ void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const
bone = new aiBone(); bone = new aiBone();
bone->mName = bone_name; bone->mName = bone_name;
//bone->mOffsetMatrix = cluster->Transform(); bone->mOffsetMatrix = cluster->Transform();
// store local transform link for post processing // store local transform link for post processing
/*
bone->mOffsetMatrix = cluster->TransformLink(); bone->mOffsetMatrix = cluster->TransformLink();
bone->mOffsetMatrix.Inverse(); bone->mOffsetMatrix.Inverse();
const aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform; aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
*/
// //
// Now calculate the aiVertexWeights // Now calculate the aiVertexWeights
// //
@ -1866,7 +1796,7 @@ aiString FBXConverter::GetTexturePath(const Texture *tex) {
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it // We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
// This may occur on this case too, it has to be studied // This may occur on this case too, it has to be studied
path.data[0] = '*'; path.data[0] = '*';
path.length = 1 + ASSIMP_itoa10(path.data + 1, AI_MAXLEN - 1, index); path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
} }
} }
} }
@ -2134,10 +2064,6 @@ void FBXConverter::SetTextureProperties(aiMaterial *out_mat, const TextureMap &_
TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor", aiTextureType_EMISSION_COLOR, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|metalness", aiTextureType_METALNESS, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|metalness", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness", aiTextureType_DIFFUSE_ROUGHNESS, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|base", aiTextureType_MAYA_BASE, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|specular", aiTextureType_MAYA_SPECULAR, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|specularColor", aiTextureType_MAYA_SPECULAR_COLOR, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|specularRoughness", aiTextureType_MAYA_SPECULAR_ROUGHNESS, mesh);
// Maya stingray // Maya stingray
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map", aiTextureType_BASE_COLOR, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map", aiTextureType_BASE_COLOR, mesh);
@ -2450,7 +2376,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture) // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
path.data[0] = '*'; path.data[0] = '*';
path.length = 1 + ASSIMP_itoa10(path.data + 1, AI_MAXLEN - 1, index); path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
} }
out_mat->AddProperty(&path, (name + "|file").c_str(), aiTextureType_UNKNOWN, 0); out_mat->AddProperty(&path, (name + "|file").c_str(), aiTextureType_UNKNOWN, 0);
@ -2816,7 +2742,7 @@ void FBXConverter::ProcessMorphAnimDatas(std::map<std::string, morphAnimData *>
auto geoIt = std::find(model->GetGeometry().begin(), model->GetGeometry().end(), geo); auto geoIt = std::find(model->GetGeometry().begin(), model->GetGeometry().end(), geo);
auto geoIndex = static_cast<unsigned int>(std::distance(model->GetGeometry().begin(), geoIt)); auto geoIndex = static_cast<unsigned int>(std::distance(model->GetGeometry().begin(), geoIt));
auto name = aiString(FixNodeName(model->Name() + "*")); auto name = aiString(FixNodeName(model->Name() + "*"));
name.length = 1 + ASSIMP_itoa10(name.data + name.length, AI_MAXLEN - 1, geoIndex); name.length = 1 + ASSIMP_itoa10(name.data + name.length, MAXLEN - 1, geoIndex);
morphAnimData *animData; morphAnimData *animData;
auto animIt = morphAnimDatas->find(name.C_Str()); auto animIt = morphAnimDatas->find(name.C_Str());
if (animIt == morphAnimDatas->end()) { if (animIt == morphAnimDatas->end()) {
@ -3283,6 +3209,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
aiVector3D defTranslate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f)); aiVector3D defTranslate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f));
aiVector3D defRotation = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f)); aiVector3D defRotation = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f));
aiVector3D defScale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f)); aiVector3D defScale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f));
aiQuaternion defQuat = EulerToQuaternion(defRotation, rotOrder);
aiVectorKey* outTranslations = new aiVectorKey[keyCount]; aiVectorKey* outTranslations = new aiVectorKey[keyCount];
aiQuatKey* outRotations = new aiQuatKey[keyCount]; aiQuatKey* outRotations = new aiQuatKey[keyCount];
@ -3300,7 +3227,6 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
if (keyframeLists[TransformationComp_Rotation].size() > 0) { if (keyframeLists[TransformationComp_Rotation].size() > 0) {
InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], defRotation, maxTime, minTime, rotOrder); InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], defRotation, maxTime, minTime, rotOrder);
} else { } else {
aiQuaternion defQuat = EulerToQuaternion(defRotation, rotOrder);
for (size_t i = 0; i < keyCount; ++i) { for (size_t i = 0; i < keyCount; ++i) {
outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps; outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
outRotations[i].mValue = defQuat; outRotations[i].mValue = defQuat;

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -84,7 +84,7 @@ Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const
transform = ReadMatrix(Transform); transform = ReadMatrix(Transform);
transformLink = ReadMatrix(TransformLink); transformLink = ReadMatrix(TransformLink);
// it is actually possible that there are Deformer's with no weights // it is actually possible that there be Deformer's with no weights
if (!!Indexes != !!Weights) { if (!!Indexes != !!Weights) {
DOMError("either Indexes or Weights are missing from Cluster",&element); DOMError("either Indexes or Weights are missing from Cluster",&element);
} }

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -243,7 +243,7 @@ FileGlobalSettings::FileGlobalSettings(const Document &doc, std::shared_ptr<cons
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Document::Document(Parser& parser, const ImportSettings& settings) : Document::Document(const Parser& parser, const ImportSettings& settings) :
settings(settings), parser(parser) { settings(settings), parser(parser) {
ASSIMP_LOG_DEBUG("Creating FBX Document"); ASSIMP_LOG_DEBUG("Creating FBX Document");
@ -265,17 +265,13 @@ Document::Document(Parser& parser, const ImportSettings& settings) :
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Document::~Document() Document::~Document() {
{
// The document does not own the memory for the following objects, but we need to call their d'tor
// so they can properly free memory like string members:
for(ObjectMap::value_type& v : objects) { for(ObjectMap::value_type& v : objects) {
delete_LazyObject(v.second); delete v.second;
} }
for(ConnectionMap::value_type& v : src_connections) { for(ConnectionMap::value_type& v : src_connections) {
delete_Connection(v.second); delete v.second;
} }
// |dest_connections| contain the same Connection objects as the |src_connections| // |dest_connections| contain the same Connection objects as the |src_connections|
} }
@ -360,11 +356,9 @@ void Document::ReadObjects() {
DOMError("no Objects dictionary found"); DOMError("no Objects dictionary found");
} }
StackAllocator &allocator = parser.GetAllocator();
// add a dummy entry to represent the Model::RootNode object (id 0), // add a dummy entry to represent the Model::RootNode object (id 0),
// which is only indirectly defined in the input file // which is only indirectly defined in the input file
objects[0] = new_LazyObject(0L, *eobjects, *this); objects[0] = new LazyObject(0L, *eobjects, *this);
const Scope& sobjects = *eobjects->Compound(); const Scope& sobjects = *eobjects->Compound();
for(const ElementMap::value_type& el : sobjects.Elements()) { for(const ElementMap::value_type& el : sobjects.Elements()) {
@ -390,10 +384,10 @@ void Document::ReadObjects() {
const auto foundObject = objects.find(id); const auto foundObject = objects.find(id);
if(foundObject != objects.end()) { if(foundObject != objects.end()) {
DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second); DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second);
delete_LazyObject(foundObject->second); delete foundObject->second;
} }
objects[id] = new_LazyObject(id, *el.second, *this); objects[id] = new LazyObject(id, *el.second, *this);
// grab all animation stacks upfront since there is no listing of them // grab all animation stacks upfront since there is no listing of them
if(!strcmp(el.first.c_str(),"AnimationStack")) { if(!strcmp(el.first.c_str(),"AnimationStack")) {
@ -460,9 +454,7 @@ void Document::ReadPropertyTemplates() {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Document::ReadConnections() void Document::ReadConnections() {
{
StackAllocator &allocator = parser.GetAllocator();
const Scope& sc = parser.GetRootScope(); const Scope& sc = parser.GetRootScope();
// read property templates from "Definitions" section // read property templates from "Definitions" section
const Element* const econns = sc["Connections"]; const Element* const econns = sc["Connections"];
@ -502,7 +494,7 @@ void Document::ReadConnections()
} }
// add new connection // add new connection
const Connection* const c = new_Connection(insertionOrder++,src,dest,prop,*this); const Connection* const c = new Connection(insertionOrder++,src,dest,prop,*this);
src_connections.insert(ConnectionMap::value_type(src,c)); src_connections.insert(ConnectionMap::value_type(src,c));
dest_connections.insert(ConnectionMap::value_type(dest,c)); dest_connections.insert(ConnectionMap::value_type(dest,c));
} }

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -55,14 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define _AI_CONCAT(a,b) a ## b #define _AI_CONCAT(a,b) a ## b
#define AI_CONCAT(a,b) _AI_CONCAT(a,b) #define AI_CONCAT(a,b) _AI_CONCAT(a,b)
namespace Assimp { namespace Assimp {
namespace FBX { namespace FBX {
// Use an 'illegal' default FOV value to detect if the FBX camera has set the FOV.
static const float kFovUnknown = -1.0f;
class Parser; class Parser;
class Object; class Object;
struct ImportSettings; struct ImportSettings;
@ -86,10 +81,6 @@ class BlendShape;
class Skin; class Skin;
class Cluster; class Cluster;
#define new_LazyObject new (allocator.Allocate(sizeof(LazyObject))) LazyObject
#define new_Connection new (allocator.Allocate(sizeof(Connection))) Connection
#define delete_LazyObject(_p) (_p)->~LazyObject()
#define delete_Connection(_p) (_p)->~Connection()
/** Represents a delay-parsed FBX objects. Many objects in the scene /** Represents a delay-parsed FBX objects. Many objects in the scene
* are not needed by assimp, so it makes no sense to parse them * are not needed by assimp, so it makes no sense to parse them
@ -252,7 +243,7 @@ public:
fbx_simple_property(FilmAspectRatio, float, 1.0f) fbx_simple_property(FilmAspectRatio, float, 1.0f)
fbx_simple_property(ApertureMode, int, 0) fbx_simple_property(ApertureMode, int, 0)
fbx_simple_property(FieldOfView, float, kFovUnknown) fbx_simple_property(FieldOfView, float, 1.0f)
fbx_simple_property(FocalLength, float, 1.0f) fbx_simple_property(FocalLength, float, 1.0f)
}; };
@ -1082,7 +1073,7 @@ private:
/** DOM root for a FBX file */ /** DOM root for a FBX file */
class Document { class Document {
public: public:
Document(Parser& parser, const ImportSettings& settings); Document(const Parser& parser, const ImportSettings& settings);
~Document(); ~Document();
@ -1166,7 +1157,7 @@ private:
const ImportSettings& settings; const ImportSettings& settings;
ObjectMap objects; ObjectMap objects;
Parser& parser; const Parser& parser;
PropertyTemplateMap templates; PropertyTemplateMap templates;
ConnectionMap src_connections; ConnectionMap src_connections;

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.
@ -69,12 +69,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <unordered_set> #include <unordered_set>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <cmath>
// RESOURCES: // RESOURCES:
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/ // https://code.blender.org/2013/08/fbx-binary-file-format-specification/
// https://wiki.blender.org/index.php/User:Mont29/Foundation/FBX_File_Structure // https://wiki.blender.org/index.php/User:Mont29/Foundation/FBX_File_Structure
const ai_real DEG = ai_real( 57.29577951308232087679815481 ); // degrees per radian
using namespace Assimp; using namespace Assimp;
using namespace Assimp::FBX; using namespace Assimp::FBX;
@ -1051,7 +1052,7 @@ aiNode* get_node_for_mesh(unsigned int meshIndex, aiNode* node)
aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene) aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene)
{ {
std::vector<const aiNode*> node_chain; std::vector<const aiNode*> node_chain;
while (node != scene->mRootNode && node != nullptr) { while (node != scene->mRootNode) {
node_chain.push_back(node); node_chain.push_back(node);
node = node->mParent; node = node->mParent;
} }
@ -1062,14 +1063,14 @@ aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene)
return transform; return transform;
} }
inline int64_t to_ktime(double ticks, const aiAnimation* anim) { int64_t to_ktime(double ticks, const aiAnimation* anim) {
if (FP_ZERO == std::fpclassify(anim->mTicksPerSecond)) { if (anim->mTicksPerSecond <= 0) {
return static_cast<int64_t>(ticks) * FBX::SECOND; return static_cast<int64_t>(ticks) * FBX::SECOND;
} }
return (static_cast<int64_t>(ticks / anim->mTicksPerSecond)) * FBX::SECOND; return (static_cast<int64_t>(ticks) / static_cast<int64_t>(anim->mTicksPerSecond)) * FBX::SECOND;
} }
inline int64_t to_ktime(double time) { int64_t to_ktime(double time) {
return (static_cast<int64_t>(time * FBX::SECOND)); return (static_cast<int64_t>(time * FBX::SECOND));
} }
@ -1089,8 +1090,6 @@ void FBXExporter::WriteObjects ()
bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true); bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true);
std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later
const auto bTransparencyFactorReferencedToOpacity = mProperties->GetPropertyBool(AI_CONFIG_EXPORT_FBX_TRANSPARENCY_FACTOR_REFER_TO_OPACITY, false);
// geometry (aiMesh) // geometry (aiMesh)
mesh_uids.clear(); mesh_uids.clear();
indent = 1; indent = 1;
@ -1217,8 +1216,10 @@ void FBXExporter::WriteObjects ()
} }
// colors, if any // colors, if any
for (size_t ci = 0; ci < m->GetNumColorChannels(); ++ci) { // TODO only one color channel currently
FBX::Node vertexcolors("LayerElementColor", int32_t(ci)); const int32_t colorChannelIndex = 0;
if (m->HasVertexColors(colorChannelIndex)) {
FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
vertexcolors.Begin(outstream, binary, indent); vertexcolors.Begin(outstream, binary, indent);
vertexcolors.DumpProperties(outstream, binary, indent); vertexcolors.DumpProperties(outstream, binary, indent);
vertexcolors.EndProperties(outstream, binary, indent); vertexcolors.EndProperties(outstream, binary, indent);
@ -1228,7 +1229,7 @@ void FBXExporter::WriteObjects ()
"Version", int32_t(101), outstream, binary, indent "Version", int32_t(101), outstream, binary, indent
); );
char layerName[8]; char layerName[8];
snprintf(layerName, sizeof(layerName), "COLOR_%d", int32_t(ci)); snprintf(layerName, sizeof(layerName), "COLOR_%d", colorChannelIndex);
FBX::Node::WritePropertyNode( FBX::Node::WritePropertyNode(
"Name", (const char*)layerName, outstream, binary, indent "Name", (const char*)layerName, outstream, binary, indent
); );
@ -1245,7 +1246,7 @@ void FBXExporter::WriteObjects ()
for (size_t fi = 0; fi < m->mNumFaces; ++fi) { for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
const aiFace &f = m->mFaces[fi]; const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) { for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
const aiColor4D &c = m->mColors[ci][f.mIndices[pvi]]; const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]];
color_data.push_back(c.r); color_data.push_back(c.r);
color_data.push_back(c.g); color_data.push_back(c.g);
color_data.push_back(c.b); color_data.push_back(c.b);
@ -1352,14 +1353,11 @@ void FBXExporter::WriteObjects ()
le.AddChild("Type", "LayerElementNormal"); le.AddChild("Type", "LayerElementNormal");
le.AddChild("TypedIndex", int32_t(0)); le.AddChild("TypedIndex", int32_t(0));
layer.AddChild(le); layer.AddChild(le);
// TODO only 1 color channel currently
for (size_t ci = 0; ci < m->GetNumColorChannels(); ++ci) {
le = FBX::Node("LayerElement"); le = FBX::Node("LayerElement");
le.AddChild("Type", "LayerElementColor"); le.AddChild("Type", "LayerElementColor");
le.AddChild("TypedIndex", int32_t(ci)); le.AddChild("TypedIndex", int32_t(0));
layer.AddChild(le); layer.AddChild(le);
}
le = FBX::Node("LayerElement"); le = FBX::Node("LayerElement");
le.AddChild("Type", "LayerElementMaterial"); le.AddChild("Type", "LayerElementMaterial");
le.AddChild("TypedIndex", int32_t(0)); le.AddChild("TypedIndex", int32_t(0));
@ -1393,7 +1391,7 @@ void FBXExporter::WriteObjects ()
aiMaterial* m = mScene->mMaterials[i]; aiMaterial* m = mScene->mMaterials[i];
// these are used to receive material data // these are used to receive material data
ai_real f; aiColor3D c; float f; aiColor3D c;
// start the node record // start the node record
FBX::Node n("Material"); FBX::Node n("Material");
@ -1448,8 +1446,6 @@ void FBXExporter::WriteObjects ()
// "TransparentColor" / "TransparencyFactor"... // "TransparentColor" / "TransparencyFactor"...
// thanks FBX, for your insightful interpretation of consistency // thanks FBX, for your insightful interpretation of consistency
p.AddP70colorA("TransparentColor", c.r, c.g, c.b); p.AddP70colorA("TransparentColor", c.r, c.g, c.b);
if (!bTransparencyFactorReferencedToOpacity) {
// TransparencyFactor defaults to 0.0, so set it to 1.0. // TransparencyFactor defaults to 0.0, so set it to 1.0.
// note: Maya always sets this to 1.0, // note: Maya always sets this to 1.0,
// so we can't use it sensibly as "Opacity". // so we can't use it sensibly as "Opacity".
@ -1458,12 +1454,6 @@ void FBXExporter::WriteObjects ()
// probably for a similar reason. // probably for a similar reason.
p.AddP70numberA("TransparencyFactor", 1.0); p.AddP70numberA("TransparencyFactor", 1.0);
} }
}
if (bTransparencyFactorReferencedToOpacity) {
if (m->Get(AI_MATKEY_OPACITY, f) == aiReturn_SUCCESS) {
p.AddP70numberA("TransparencyFactor", 1.0 - f);
}
}
if (m->Get(AI_MATKEY_COLOR_REFLECTIVE, c) == aiReturn_SUCCESS) { if (m->Get(AI_MATKEY_COLOR_REFLECTIVE, c) == aiReturn_SUCCESS) {
p.AddP70colorA("ReflectionColor", c.r, c.g, c.b); p.AddP70colorA("ReflectionColor", c.r, c.g, c.b);
} }
@ -1760,7 +1750,7 @@ void FBXExporter::WriteObjects ()
int64_t blendshape_uid = generate_uid(); int64_t blendshape_uid = generate_uid();
mesh_uids.push_back(blendshape_uid); mesh_uids.push_back(blendshape_uid);
bsnode.AddProperty(blendshape_uid); bsnode.AddProperty(blendshape_uid);
bsnode.AddProperty(blendshape_name + FBX::SEPARATOR + "Geometry"); bsnode.AddProperty(blendshape_name + FBX::SEPARATOR + "Blendshape");
bsnode.AddProperty("Shape"); bsnode.AddProperty("Shape");
bsnode.AddChild("Version", int32_t(100)); bsnode.AddChild("Version", int32_t(100));
bsnode.Begin(outstream, binary, indent); bsnode.Begin(outstream, binary, indent);
@ -1819,7 +1809,7 @@ void FBXExporter::WriteObjects ()
p.AddP70numberA("DeformPercent", 0.0); p.AddP70numberA("DeformPercent", 0.0);
sdnode.AddChild(p); sdnode.AddChild(p);
// TODO: Normally just one weight per channel, adding stub for later development // TODO: Normally just one weight per channel, adding stub for later development
std::vector<double>fFullWeights; std::vector<float>fFullWeights;
fFullWeights.push_back(100.); fFullWeights.push_back(100.);
sdnode.AddChild("FullWeights", fFullWeights); sdnode.AddChild("FullWeights", fFullWeights);
sdnode.Dump(outstream, binary, indent); sdnode.Dump(outstream, binary, indent);
@ -1869,26 +1859,33 @@ void FBXExporter::WriteObjects ()
// one sticky point is that the number of vertices may not match, // one sticky point is that the number of vertices may not match,
// because assimp splits vertices by normal, uv, etc. // because assimp splits vertices by normal, uv, etc.
// functor for aiNode sorting
struct SortNodeByName
{
bool operator()(const aiNode *lhs, const aiNode *rhs) const
{
return strcmp(lhs->mName.C_Str(), rhs->mName.C_Str()) < 0;
}
};
// first we should mark the skeleton for each mesh. // first we should mark the skeleton for each mesh.
// the skeleton must include not only the aiBones, // the skeleton must include not only the aiBones,
// but also all their parent nodes. // but also all their parent nodes.
// anything that affects the position of any bone node must be included. // anything that affects the position of any bone node must be included.
// Use SorNodeByName to make sure the exported result will be the same across all systems
// note that we want to preserve input order as much as possible here. // Otherwise the aiNodes of the skeleton would be sorted based on the pointer address, which isn't consistent
// previously, sorting by name lead to consistent output across systems, but was not std::vector<std::set<const aiNode*, SortNodeByName>> skeleton_by_mesh(mScene->mNumMeshes);
// suitable for downstream consumption by some applications.
std::vector<std::vector<const aiNode*>> skeleton_by_mesh(mScene->mNumMeshes);
// at the same time we can build a list of all the skeleton nodes, // at the same time we can build a list of all the skeleton nodes,
// which will be used later to mark them as type "limbNode". // which will be used later to mark them as type "limbNode".
std::unordered_set<const aiNode*> limbnodes; std::unordered_set<const aiNode*> limbnodes;
//actual bone nodes in fbx, without parenting-up //actual bone nodes in fbx, without parenting-up
std::vector<std::string> allBoneNames; std::unordered_set<std::string> setAllBoneNamesInScene;
for(unsigned int m = 0; m < mScene->mNumMeshes; ++ m) { for(unsigned int m = 0; m < mScene->mNumMeshes; ++ m)
{
aiMesh* pMesh = mScene->mMeshes[m]; aiMesh* pMesh = mScene->mMeshes[m];
for(unsigned int b = 0; b < pMesh->mNumBones; ++ b) for(unsigned int b = 0; b < pMesh->mNumBones; ++ b)
allBoneNames.push_back(pMesh->mBones[b]->mName.data); setAllBoneNamesInScene.insert(pMesh->mBones[b]->mName.data);
} }
aiMatrix4x4 mxTransIdentity; aiMatrix4x4 mxTransIdentity;
@ -1896,7 +1893,7 @@ void FBXExporter::WriteObjects ()
std::map<std::string,aiNode*> node_by_bone; std::map<std::string,aiNode*> node_by_bone;
for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) { for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
const aiMesh* m = mScene->mMeshes[mi]; const aiMesh* m = mScene->mMeshes[mi];
std::vector<const aiNode*> skeleton; std::set<const aiNode*, SortNodeByName> skeleton;
for (size_t bi =0; bi < m->mNumBones; ++bi) { for (size_t bi =0; bi < m->mNumBones; ++bi) {
const aiBone* b = m->mBones[bi]; const aiBone* b = m->mBones[bi];
const std::string name(b->mName.C_Str()); const std::string name(b->mName.C_Str());
@ -1915,7 +1912,7 @@ void FBXExporter::WriteObjects ()
node_by_bone[name] = n; node_by_bone[name] = n;
limbnodes.insert(n); limbnodes.insert(n);
} }
skeleton.push_back(n); skeleton.insert(n);
// mark all parent nodes as skeleton as well, // mark all parent nodes as skeleton as well,
// up until we find the root node, // up until we find the root node,
// or else the node containing the mesh, // or else the node containing the mesh,
@ -1926,7 +1923,7 @@ void FBXExporter::WriteObjects ()
parent = parent->mParent parent = parent->mParent
) { ) {
// if we've already done this node we can skip it all // if we've already done this node we can skip it all
if (std::find(skeleton.begin(), skeleton.end(), parent) != skeleton.end()) { if (skeleton.count(parent)) {
break; break;
} }
// ignore fbx transform nodes as these will be collapsed later // ignore fbx transform nodes as these will be collapsed later
@ -1936,7 +1933,7 @@ void FBXExporter::WriteObjects ()
continue; continue;
} }
//not a bone in scene && no effect in transform //not a bone in scene && no effect in transform
if (std::find(allBoneNames.begin(), allBoneNames.end(), node_name) == allBoneNames.end() if(setAllBoneNamesInScene.find(node_name)==setAllBoneNamesInScene.end()
&& parent->mTransformation == mxTransIdentity) { && parent->mTransformation == mxTransIdentity) {
continue; continue;
} }
@ -2021,7 +2018,7 @@ void FBXExporter::WriteObjects ()
aiMatrix4x4 mesh_xform = get_world_transform(mesh_node, mScene); aiMatrix4x4 mesh_xform = get_world_transform(mesh_node, mScene);
// now make a subdeformer for each bone in the skeleton // now make a subdeformer for each bone in the skeleton
const auto & skeleton= skeleton_by_mesh[mi]; const std::set<const aiNode*, SortNodeByName> skeleton= skeleton_by_mesh[mi];
for (const aiNode* bone_node : skeleton) { for (const aiNode* bone_node : skeleton) {
// if there's a bone for this node, find it // if there's a bone for this node, find it
const aiBone* b = nullptr; const aiBone* b = nullptr;
@ -2418,7 +2415,7 @@ void FBXExporter::WriteObjects ()
// position/translation // position/translation
for (size_t ki = 0; ki < na->mNumPositionKeys; ++ki) { for (size_t ki = 0; ki < na->mNumPositionKeys; ++ki) {
const aiVectorKey& k = na->mPositionKeys[ki]; const aiVectorKey& k = na->mPositionKeys[ki];
times.push_back(to_ktime(k.mTime, anim)); times.push_back(to_ktime(k.mTime));
xval.push_back(k.mValue.x); xval.push_back(k.mValue.x);
yval.push_back(k.mValue.y); yval.push_back(k.mValue.y);
zval.push_back(k.mValue.z); zval.push_back(k.mValue.z);
@ -2432,12 +2429,12 @@ void FBXExporter::WriteObjects ()
times.clear(); xval.clear(); yval.clear(); zval.clear(); times.clear(); xval.clear(); yval.clear(); zval.clear();
for (size_t ki = 0; ki < na->mNumRotationKeys; ++ki) { for (size_t ki = 0; ki < na->mNumRotationKeys; ++ki) {
const aiQuatKey& k = na->mRotationKeys[ki]; const aiQuatKey& k = na->mRotationKeys[ki];
times.push_back(to_ktime(k.mTime, anim)); times.push_back(to_ktime(k.mTime));
// TODO: aiQuaternion method to convert to Euler... // TODO: aiQuaternion method to convert to Euler...
aiMatrix4x4 m(k.mValue.GetMatrix()); aiMatrix4x4 m(k.mValue.GetMatrix());
aiVector3D qs, qr, qt; aiVector3D qs, qr, qt;
m.Decompose(qs, qr, qt); m.Decompose(qs, qr, qt);
qr = AI_RAD_TO_DEG(qr); qr *= DEG;
xval.push_back(qr.x); xval.push_back(qr.x);
yval.push_back(qr.y); yval.push_back(qr.y);
zval.push_back(qr.z); zval.push_back(qr.z);
@ -2450,7 +2447,7 @@ void FBXExporter::WriteObjects ()
times.clear(); xval.clear(); yval.clear(); zval.clear(); times.clear(); xval.clear(); yval.clear(); zval.clear();
for (size_t ki = 0; ki < na->mNumScalingKeys; ++ki) { for (size_t ki = 0; ki < na->mNumScalingKeys; ++ki) {
const aiVectorKey& k = na->mScalingKeys[ki]; const aiVectorKey& k = na->mScalingKeys[ki];
times.push_back(to_ktime(k.mTime, anim)); times.push_back(to_ktime(k.mTime));
xval.push_back(k.mValue.x); xval.push_back(k.mValue.x);
yval.push_back(k.mValue.y); yval.push_back(k.mValue.y);
zval.push_back(k.mValue.z); zval.push_back(k.mValue.z);
@ -2487,57 +2484,6 @@ const std::map<std::string,std::pair<std::string,char>> transform_types = {
{"GeometricScalingInverse", {"GeometricScalingInverse", 'i'}} {"GeometricScalingInverse", {"GeometricScalingInverse", 'i'}}
}; };
//add metadata to fbx property
void add_meta(FBX::Node& fbx_node, const aiNode* node){
if(node->mMetaData == nullptr) return;
aiMetadata* meta = node->mMetaData;
for (unsigned int i = 0; i < meta->mNumProperties; ++i) {
aiString key = meta->mKeys[i];
aiMetadataEntry* entry = &meta->mValues[i];
switch (entry->mType) {
case AI_BOOL:{
bool val = *static_cast<bool *>(entry->mData);
fbx_node.AddP70bool(key.C_Str(), val);
break;
}
case AI_INT32:{
int32_t val = *static_cast<int32_t *>(entry->mData);
fbx_node.AddP70int(key.C_Str(), val);
break;
}
case AI_UINT64:{
//use string to add uint64
uint64_t val = *static_cast<uint64_t *>(entry->mData);
fbx_node.AddP70string(key.C_Str(), std::to_string(val).c_str());
break;
}
case AI_FLOAT:{
float val = *static_cast<float *>(entry->mData);
fbx_node.AddP70double(key.C_Str(), val);
break;
}
case AI_DOUBLE:{
double val = *static_cast<double *>(entry->mData);
fbx_node.AddP70double(key.C_Str(), val);
break;
}
case AI_AISTRING:{
aiString val = *static_cast<aiString *>(entry->mData);
fbx_node.AddP70string(key.C_Str(), val.C_Str());
break;
}
case AI_AIMETADATA: {
//ignore
break;
}
default:
break;
}
}
}
// write a single model node to the stream // write a single model node to the stream
void FBXExporter::WriteModelNode( void FBXExporter::WriteModelNode(
StreamWriterLE& outstream, StreamWriterLE& outstream,
@ -2569,10 +2515,9 @@ void FBXExporter::WriteModelNode(
); );
} }
if (r != zero) { if (r != zero) {
r = AI_RAD_TO_DEG(r);
p.AddP70( p.AddP70(
"Lcl Rotation", "Lcl Rotation", "", "A", "Lcl Rotation", "Lcl Rotation", "", "A",
double(r.x), double(r.y), double(r.z) double(DEG*r.x), double(DEG*r.y), double(DEG*r.z)
); );
} }
if (s != one) { if (s != one) {
@ -2605,7 +2550,6 @@ void FBXExporter::WriteModelNode(
} }
} }
} }
add_meta(p, node);
m.AddChild(p); m.AddChild(p);
// not sure what these are for, // not sure what these are for,
@ -2657,7 +2601,8 @@ void FBXExporter::WriteModelNodes(
transform_chain.emplace_back(elem->first, t); transform_chain.emplace_back(elem->first, t);
break; break;
case 'r': // rotation case 'r': // rotation
transform_chain.emplace_back(elem->first, AI_RAD_TO_DEG(r)); r *= float(DEG);
transform_chain.emplace_back(elem->first, r);
break; break;
case 's': // scale case 's': // scale
transform_chain.emplace_back(elem->first, s); transform_chain.emplace_back(elem->first, s);

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team Copyright (c) 2006-2022, assimp team
All rights reserved. All rights reserved.

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