Merge branch 'assimp:master' into master

pull/4453/head
Promit Roy 2022-03-17 15:00:09 -04:00 committed by GitHub
commit 5ec7e57b99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
768 changed files with 19489 additions and 18582 deletions

1
.github/FUNDING.yml vendored
View File

@ -1 +1,2 @@
open_collective: assimp
patreon: assimp

5
.gitignore vendored
View File

@ -25,7 +25,7 @@ CMakeSettings.json
# Output
bin/
lib/
x64/
# QtCreator
CMakeLists.txt.user
@ -94,6 +94,7 @@ test/gtest/src/gtest-stamp/gtest-gitinfo.txt
test/gtest/src/gtest-stamp/gtest-gitclone-lastrun.txt
Assimp.opensdf
contrib/zlib/CTestTestfile.cmake
contrib/zlib/Debug/zlibstaticd.pdb
ipch/assimp_viewer-44bbbcd1/assimp_viewerd-ccc45335.ipch
bin64/assimp-vc140-mt.dll
bin64/assimp-vc140-mtd.dll
@ -118,4 +119,4 @@ tools/assimp_qt_viewer/moc_mainwindow.cpp_parameters
tools/assimp_qt_viewer/ui_mainwindow.h
#Generated directory
generated/*
generated/*

View File

@ -1,67 +0,0 @@
#---------------------------------------------------------------------------
#Open Asset Import Library (assimp)
#---------------------------------------------------------------------------
# Copyright (c) 2006-2020, assimp team
#
# License see LICENSE file
#
function generate() {
OPTIONS="-DASSIMP_WERROR=ON"
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=NO"
if [ "$DISABLE_EXPORTERS" = "YES" ] ; then
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=YES"
else
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=NO"
fi
if [ "$SHARED_BUILD" = "ON" ] ; then
OPTIONS="$OPTIONS -DBUILD_SHARED_LIBS=ON"
else
OPTIONS="$OPTIONS -DBUILD_SHARED_LIBS=OFF"
fi
if [ "$ENABLE_COVERALLS" = "ON" ] ; then
OPTIONS="$OPTIONS -DASSIMP_COVERALLS=ON"
else
OPTIONS="$OPTIONS -DASSIMP_COVERALLS=OFF"
fi
if [ "$ASAN" = "ON" ] ; then
OPTIONS="$OPTIONS -DASSIMP_ASAN=ON"
else
OPTIONS="$OPTIONS -DASSIMP_ASAN=OFF"
fi
if [ "$UBSAN" = "ON" ] ; then
OPTIONS="$OPTIONS -DASSIMP_UBSAN=ON"
fi
cmake -G "Unix Makefiles" $OPTIONS
}
# build and run unittests, if not android
if [ $ANDROID ]; then
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
fi
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
if [ $ANALYZE = "ON" ] ; then
if [ "$CC" = "clang" ]; then
scan-build cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS=OFF -DASSIMP_BUILD_TESTS=OFF
scan-build --status-bugs make -j2
else
cppcheck --version
generate \
&& cppcheck --error-exitcode=1 -j2 -Iinclude -Icode code 2> cppcheck.txt
if [ -s cppcheck.txt ]; then
cat cppcheck.txt
exit 1
fi
fi
else
generate \
&& make -j4 \
&& sudo make install \
&& sudo ldconfig \
&& (cd test/unit; ../../bin/unit)
fi
fi

View File

@ -1,78 +0,0 @@
sudo: required
language: cpp
cache: ccache
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake cppcheck && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi
- 'if [ "$TRAVIS_OS_NAME" = "osx" ]; then
if brew ls --versions cmake > /dev/null; then
echo cmake already installed.;
else
brew install cmake;
fi;
brew install python3;
brew install homebrew/x11/freeglut;
fi'
- echo -e "#ifndef A_R_H_INC\n#define A_R_H_INC\n#define GitVersion ${TRAVIS_JOB_ID}\n#define GitBranch \"${TRAVIS_BRANCH}\"\n#endif // A_R_H_INC" > revision.h
# install latest LCOV (1.9 was failing)
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz && tar xf lcov_1.11.orig.tar.gz && sudo make -C lcov-1.11/ install && gem install coveralls-lcov && lcov --version && g++ --version ; fi
os:
- linux
compiler:
- gcc
- clang
env:
global:
- secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
git:
depth: 1
matrix:
include:
- os: linux
compiler: clang
env: ASAN=ON
- os: linux
compiler: clang
env: UBSAN=ON
- os: linux
compiler: clang
env: SHARED_BUILD=ON
- os: linux
compiler: gcc
env: ANALYZE=ON
- os: linux
compiler: gcc
env: ENABLE_COVERALLS=ON
- os: linux
compiler: gcc
env: SHARED_BUILD=ON
install:
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
before_script:
cmake . -DASSIMP_ENABLE_BOOST_WORKAROUND=YES
script:
- export COVERALLS_SERVICE_NAME=travis-ci
- export COVERALLS_REPO_TOKEN=abc12345
- . ./.travis.sh
after_success:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --capture --output-file coverage.info && lcov --remove coverage.info '/usr/*' 'contrib/*' 'test/*' --output-file coverage.info && lcov --list coverage.info && coveralls-lcov --source-encoding=ISO-8859-1 --repo-token=${COVERALLS_TOKEN} coverage.info ; fi
addons:
coverity_scan:
project:
name: "assimp/assimp"
notification_email: kim.kulling@googlemail.com
build_command_prepend: "cmake ./"
build_command: "make -j4"
branch_pattern: coverity_scan

View File

@ -10,16 +10,15 @@
:: Also see: https://github.com/assimp/assimp/pull/2646
SET SOURCE_DIR=.
SET GENERATOR=Visual Studio 16 2019
:: For generators see "cmake --help"
SET GENERATOR=Visual Studio 15 2017
SET BINARIES_DIR="./BINARIES/Win32"
cmake CMakeLists.txt -G "%GENERATOR%" -S %SOURCE_DIR% -B %BINARIES_DIR%
SET BINARIES_DIR="./build/Win32"
cmake . -G "%GENERATOR%" -A Win32 -S %SOURCE_DIR% -B %BINARIES_DIR%
cmake --build %BINARIES_DIR% --config debug
cmake --build %BINARIES_DIR% --config release
SET BINARIES_DIR="./BINARIES/x64"
cmake CMakeLists.txt -G "%GENERATOR% Win64" -S %SOURCE_DIR% -B %BINARIES_DIR%
SET BINARIES_DIR="./build/x64"
cmake . -G "%GENERATOR%" -A x64 -S %SOURCE_DIR% -B %BINARIES_DIR%
cmake --build %BINARIES_DIR% --config debug
cmake --build %BINARIES_DIR% --config release

View File

@ -1,6 +1,6 @@
# Open Asset Import Library (assimp)
# ----------------------------------------------------------------------
# Copyright (c) 2006-2021, assimp team
# Copyright (c) 2006-2022, assimp team
#
# All rights reserved.
#
@ -40,20 +40,23 @@ SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW)
CMAKE_MINIMUM_REQUIRED( VERSION 3.10 )
# Disabled importers: m3d for 5.1
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER)
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER)
# Toggles the use of the hunter package manager
option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
IF(ASSIMP_HUNTER_ENABLED)
include("cmake/HunterGate.cmake")
include("cmake-modules/HunterGate.cmake")
HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.23.293.tar.gz"
SHA1 "e8e5470652db77149d9b38656db2a6c0b7642693"
URL "https://github.com/cpp-pm/hunter/archive/v0.24.0.tar.gz"
SHA1 "a3d7f4372b1dcd52faa6ff4a3bd5358e1d0e5efd"
)
add_definitions(-DASSIMP_USE_HUNTER)
ENDIF()
PROJECT( Assimp VERSION 5.0.1 )
PROJECT(Assimp VERSION 5.2.0)
# All supported options ###############################################
@ -131,15 +134,15 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH
OFF
)
IF ( WIN32 )
IF (WIN32)
# Use subset of Windows.h
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW
"If the Assimp view tool is built. (requires DirectX)"
OFF )
IF(MSVC)
OPTION (ASSIMP_BUILD_ASSIMP_VIEW
"If the Assimp view tool is built. (requires DirectX)"
OFF )
OPTION( ASSIMP_INSTALL_PDB
"Install MSVC debug files."
ON )
@ -147,6 +150,27 @@ IF ( WIN32 )
# Multibyte character set is deprecated since at least MSVC2015 (possibly earlier)
ADD_DEFINITIONS( -DUNICODE -D_UNICODE )
ENDIF()
# Link statically against c/c++ lib to avoid missing redistriburable such as
# "VCRUNTIME140.dll not found. Try reinstalling the app.", but give users
# a choice to opt for the shared runtime if they want.
option(USE_STATIC_CRT "Link against the static runtime libraries." OFF)
# The CMAKE_CXX_FLAGS vars can be overriden by some Visual Studio generators, so we use an alternative
# global method here:
if (${USE_STATIC_CRT})
add_compile_options(
$<$<CONFIG:>:/MT>
$<$<CONFIG:Debug>:/MTd>
$<$<CONFIG:Release>:/MT>
)
else()
add_compile_options(
$<$<CONFIG:>:/MD>
$<$<CONFIG:Debug>:/MDd>
$<$<CONFIG:Release>:/MD>
)
endif()
ENDIF()
ENDIF()
@ -180,7 +204,9 @@ SET (ASSIMP_SOVERSION 5)
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
if(NOT ASSIMP_HUNTER_ENABLED)
# Enable C++11 support globally
set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 99)
endif()
IF(NOT ASSIMP_IGNORE_GIT_HASH)
@ -238,10 +264,17 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
IF( UNIX )
# Use GNUInstallDirs for Unix predefined directories
INCLUDE(GNUInstallDirs)
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
IF( ${OPERATING_SYSTEM} MATCHES "Android")
ELSE()
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
ENDIF()
ENDIF()
ENDIF()
# Grouped compiler settings ########################################
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW)
IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
@ -265,8 +298,9 @@ ELSEIF(MSVC)
ENDIF()
# disable "elements of array '' will be default initialized" warning on MSVC2013
IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351)
ADD_COMPILE_OPTIONS(/wd4351)
ENDIF()
ADD_COMPILE_OPTIONS(/wd4244) #supress warning for double to float conversion if Double precission is activated
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
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")
@ -277,19 +311,18 @@ ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
ENDIF()
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
ELSEIF( CMAKE_COMPILER_IS_MINGW )
ELSEIF( MINGW )
IF (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
message(FATAL_ERROR "MinGW is too old to be supported. Please update MinGW and try again.")
ELSEIF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.3)
message(WARNING "MinGW is old, if you experience errors, update MinGW.")
ENDIF()
IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
ENDIF()
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF()
IF ( IOS AND NOT ASSIMP_HUNTER_ENABLED)
@ -336,9 +369,24 @@ INCLUDE (FindPkgMacros)
INCLUDE (PrecompiledHeader)
# Set Assimp project output directory variables.
SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for runtime output files")
SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for library output files")
SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib" CACHE STRING "Path for archive output files")
# Will respect top-level CMAKE_*_OUTPUT_DIRECTORY variables if any are set.
IF(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for runtime output files")
ELSE()
SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} CACHE STRING "Path for runtime output files")
ENDIF()
IF(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for library output files")
ELSE()
SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} CACHE STRING "Path for runtime output files")
ENDIF()
IF(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib" CACHE STRING "Path for library output files")
ELSE()
SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} CACHE STRING "Path for runtime output files")
ENDIF()
# Macro used to set the output directories of a target to the
# respective Assimp output directories.
@ -397,14 +445,14 @@ set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
IF(ASSIMP_HUNTER_ENABLED)
set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
set(CMAKE_CONFIG_TEMPLATE_FILE "cmake/assimp-hunter-config.cmake.in")
set(CMAKE_CONFIG_TEMPLATE_FILE "cmake-modules/assimp-hunter-config.cmake.in")
set(NAMESPACE "${PROJECT_NAME}::")
set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
ELSE()
set(CONFIG_INSTALL_DIR "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
set(CMAKE_CONFIG_TEMPLATE_FILE "cmake/assimp-plain-config.cmake.in")
set(CMAKE_CONFIG_TEMPLATE_FILE "cmake-modules/assimp-plain-config.cmake.in")
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE)
set(NAMESPACE "${PROJECT_NAME_LOWERCASE}::")
set(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWERCASE}Targets")
@ -667,11 +715,13 @@ ENDIF()
ADD_SUBDIRECTORY( code/ )
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
# The viewer for windows only
IF ( WIN32 )
IF (WIN32)
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" OFF )
IF ( ASSIMP_BUILD_ASSIMP_VIEW )
ADD_SUBDIRECTORY( tools/assimp_view/ )
ENDIF ()
ELSE()
MESSAGE("Building Assimp Viewer only supported on Windows.")
ENDIF ()
# The command line tool
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
@ -759,7 +809,7 @@ if(WIN32)
IF(MSVC_TOOLSET_VERSION)
SET(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
SET(ASSIMP_MSVC_VERSION ${MCVS_PREFIX})
SET(ASSIMP_MSVC_VERSION ${MSVC_PREFIX})
ELSE()
IF(MSVC12)
SET(ASSIMP_MSVC_VERSION "vc120")

View File

@ -42,7 +42,9 @@ Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file.
* [.NET](https://bitbucket.org/Starnick/assimpnet/src/master/)
* [Pascal](port/AssimpPascal/Readme.md)
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
* [Javascript/Node.js Interface](https://github.com/kovacsv/assimpjs)
* [Unity 3d Plugin](https://ricardoreis.net/trilib-2/)
* [Unreal Engine Plugin](https://github.com/irajsb/UE4_Assimp/)
* [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status))
* [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port.
* [Rust](https://github.com/jkvargas/russimp)

View File

@ -1,17 +0,0 @@
# Find IrrXMl from irrlicht project
#
# Find LibIrrXML headers and library
#
# IRRXML_FOUND - IrrXML found
# IRRXML_INCLUDE_DIR - Headers location
# IRRXML_LIBRARY - IrrXML main library
find_path(IRRXML_INCLUDE_DIR irrXML.h
PATH_SUFFIXES include/irrlicht include/irrxml)
find_library(IRRXML_LIBRARY IrrXML)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(IrrXML REQUIRED_VARS IRRXML_INCLUDE_DIR IRRXML_LIBRARY)
mark_as_advanced(IRRXML_INCLUDE_DIR IRRXML_LIBRARY)

View File

@ -0,0 +1,19 @@
@PACKAGE_INIT@
find_package(RapidJSON CONFIG REQUIRED)
find_package(ZLIB CONFIG REQUIRED)
find_package(utf8cpp CONFIG REQUIRED)
find_package(minizip CONFIG REQUIRED)
find_package(openddlparser CONFIG REQUIRED)
find_package(poly2tri CONFIG REQUIRED)
find_package(polyclipping CONFIG REQUIRED)
find_package(zip CONFIG REQUIRED)
find_package(pugixml CONFIG REQUIRED)
find_package(stb CONFIG REQUIRED)
if(@ASSIMP_BUILD_DRACO@)
find_package(draco CONFIG REQUIRED)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
check_required_components("@PROJECT_NAME@")

View File

@ -1,18 +0,0 @@
@PACKAGE_INIT@
find_package(RapidJSON CONFIG REQUIRED)
find_package(ZLIB CONFIG REQUIRED)
find_package(utf8cpp CONFIG REQUIRED)
find_package(minizip CONFIG REQUIRED)
find_package(openddlparser CONFIG REQUIRED)
find_package(poly2tri CONFIG REQUIRED)
find_package(polyclipping CONFIG REQUIRED)
find_package(zip CONFIG REQUIRED)
find_package(pugixml CONFIG REQUIRED)
if(@ASSIMP_BUILD_DRACO@)
find_package(draco CONFIG REQUIRED)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
check_required_components("@PROJECT_NAME@")

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -68,8 +68,8 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
unsigned int idx(NotSet);
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
std::string s = mScene->mMaterials[i].mName;
for (std::string::iterator it = s.begin(); it != s.end(); ++it) {
*it = static_cast<char>(::tolower(static_cast<unsigned char>(*it)));
for (char & it : s) {
it = static_cast<char>(::tolower(static_cast<unsigned char>(it)));
}
if (std::string::npos == s.find("default")) continue;
@ -79,12 +79,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
mScene->mMaterials[i].mDiffuse.r !=
mScene->mMaterials[i].mDiffuse.b) continue;
if (mScene->mMaterials[i].sTexDiffuse.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexBump.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexOpacity.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexEmissive.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexSpecular.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexShininess.mMapName.length() != 0) {
if (ContainsTextures(i)) {
continue;
}
idx = i;

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -56,8 +56,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory>
using namespace Assimp;
namespace Assimp {
using namespace D3DS;
namespace {
@ -291,7 +291,7 @@ void Discreet3DSExporter::WriteMaterials() {
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
WriteColor(color);
}
if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
WriteColor(color);
@ -330,6 +330,7 @@ void Discreet3DSExporter::WriteMaterials() {
case aiShadingMode_Blinn:
case aiShadingMode_CookTorrance:
case aiShadingMode_Fresnel:
case aiShadingMode_PBR_BRDF: // Possibly should be Discreet3DS::Metal in some cases but this is undocumented
shading_mode_out = Discreet3DS::Phong;
break;
@ -356,7 +357,10 @@ void Discreet3DSExporter::WriteMaterials() {
writer.PutI2(1);
}
WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE);
// Fallback to BASE_COLOR if no DIFFUSE
if (!WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE))
WriteTexture(mat, aiTextureType_BASE_COLOR, Discreet3DS::CHUNK_MAT_TEXTURE);
WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP);
WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP);
WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP);
@ -367,20 +371,21 @@ void Discreet3DSExporter::WriteMaterials() {
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type, uint16_t chunk_flags) {
// returns true if the texture existed
bool Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type, uint16_t chunk_flags) {
aiString path;
aiTextureMapMode map_mode[2] = {
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
};
ai_real blend = 1.0;
if (mat.GetTexture(type, 0, &path, nullptr, nullptr, &blend, nullptr, map_mode) != AI_SUCCESS || !path.length) {
return;
return false;
}
// TODO: handle embedded textures properly
if (path.data[0] == '*') {
ASSIMP_LOG_ERROR("Ignoring embedded texture for export: ", path.C_Str());
return;
return false;
}
ChunkWriter chunk(writer, chunk_flags);
@ -402,6 +407,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type
writer.PutU2(val);
}
// TODO: export texture transformation (i.e. UV offset, scale, rotation)
return true;
}
// ------------------------------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -73,7 +73,7 @@ public:
private:
void WriteMeshes();
void WriteMaterials();
void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags);
bool WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags);
void WriteFaceMaterialChunk(const aiMesh& mesh);
int WriteHierarchy(const aiNode& node, int level, int sibling_level);
void WriteString(const std::string& s);

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/light.h>
#include <assimp/material.h>
#include <assimp/qnan.h>
#include <stdio.h> //sprintf
#include <cstdio> //sprintf
namespace Assimp {
namespace D3DS {
@ -259,7 +259,7 @@ namespace Discreet3DS {
// Specifies the file name of a texture
CHUNK_MAPFILE = 0xA300,
// Specifies whether a materail requires two-sided rendering
// Specifies whether a material requires two-sided rendering
CHUNK_MAT_TWO_SIDE = 0xA081,
// ********************************************************************
@ -348,16 +348,16 @@ struct Texture {
// empty
}
Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(std::move(other.mTextureBlend)),
Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(other.mTextureBlend),
mMapName(std::move(other.mMapName)),
mOffsetU(std::move(other.mOffsetU)),
mOffsetV(std::move(other.mOffsetV)),
mScaleU(std::move(other.mScaleU)),
mScaleV(std::move(other.mScaleV)),
mRotation(std::move(other.mRotation)),
mMapMode(std::move(other.mMapMode)),
bPrivate(std::move(other.bPrivate)),
iUVSrc(std::move(other.iUVSrc)) {
mOffsetU(other.mOffsetU),
mOffsetV(other.mOffsetV),
mScaleU(other.mScaleU),
mScaleV(other.mScaleV),
mRotation(other.mRotation),
mMapMode(other.mMapMode),
bPrivate(other.bPrivate),
iUVSrc(other.iUVSrc) {
// empty
}
@ -366,16 +366,16 @@ struct Texture {
return *this;
}
mTextureBlend = std::move(other.mTextureBlend);
mTextureBlend = other.mTextureBlend;
mMapName = std::move(other.mMapName);
mOffsetU = std::move(other.mOffsetU);
mOffsetV = std::move(other.mOffsetV);
mScaleU = std::move(other.mScaleU);
mScaleV = std::move(other.mScaleV);
mRotation = std::move(other.mRotation);
mMapMode = std::move(other.mMapMode);
bPrivate = std::move(other.bPrivate);
iUVSrc = std::move(other.iUVSrc);
mOffsetU = other.mOffsetU;
mOffsetV = other.mOffsetV;
mScaleU = other.mScaleU;
mScaleV = other.mScaleV;
mRotation = other.mRotation;
mMapMode = other.mMapMode;
bPrivate = other.bPrivate;
iUVSrc = other.iUVSrc;
return *this;
}
@ -461,13 +461,13 @@ struct Material {
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
mDiffuse(std::move(other.mDiffuse)),
mSpecularExponent(std::move(other.mSpecularExponent)),
mShininessStrength(std::move(other.mShininessStrength)),
mSpecular(std::move(other.mSpecular)),
mAmbient(std::move(other.mAmbient)),
mShading(std::move(other.mShading)),
mTransparency(std::move(other.mTransparency)),
mDiffuse(other.mDiffuse),
mSpecularExponent(other.mSpecularExponent),
mShininessStrength(other.mShininessStrength),
mSpecular(other.mSpecular),
mAmbient(other.mAmbient),
mShading(other.mShading),
mTransparency(other.mTransparency),
sTexDiffuse(std::move(other.sTexDiffuse)),
sTexOpacity(std::move(other.sTexOpacity)),
sTexSpecular(std::move(other.sTexSpecular)),
@ -475,10 +475,10 @@ struct Material {
sTexBump(std::move(other.sTexBump)),
sTexEmissive(std::move(other.sTexEmissive)),
sTexShininess(std::move(other.sTexShininess)),
mBumpHeight(std::move(other.mBumpHeight)),
mEmissive(std::move(other.mEmissive)),
mBumpHeight(other.mBumpHeight),
mEmissive(other.mEmissive),
sTexAmbient(std::move(other.sTexAmbient)),
mTwoSided(std::move(other.mTwoSided)) {
mTwoSided(other.mTwoSided) {
// empty
}
@ -488,13 +488,13 @@ struct Material {
}
mName = std::move(other.mName);
mDiffuse = std::move(other.mDiffuse);
mSpecularExponent = std::move(other.mSpecularExponent);
mShininessStrength = std::move(other.mShininessStrength),
mSpecular = std::move(other.mSpecular);
mAmbient = std::move(other.mAmbient);
mShading = std::move(other.mShading);
mTransparency = std::move(other.mTransparency);
mDiffuse = other.mDiffuse;
mSpecularExponent = other.mSpecularExponent;
mShininessStrength = other.mShininessStrength,
mSpecular = other.mSpecular;
mAmbient = other.mAmbient;
mShading = other.mShading;
mTransparency = other.mTransparency;
sTexDiffuse = std::move(other.sTexDiffuse);
sTexOpacity = std::move(other.sTexOpacity);
sTexSpecular = std::move(other.sTexSpecular);
@ -502,10 +502,10 @@ struct Material {
sTexBump = std::move(other.sTexBump);
sTexEmissive = std::move(other.sTexEmissive);
sTexShininess = std::move(other.sTexShininess);
mBumpHeight = std::move(other.mBumpHeight);
mEmissive = std::move(other.mEmissive);
mBumpHeight = other.mBumpHeight;
mEmissive = other.mEmissive;
sTexAmbient = std::move(other.sTexAmbient);
mTwoSided = std::move(other.mTwoSided);
mTwoSided = other.mTwoSided;
return *this;
}

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -111,20 +111,9 @@ Discreet3DSImporter::~Discreet3DSImporter() {
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
std::string extension = GetExtension(pFile);
if (extension == "3ds" || extension == "prj") {
return true;
}
if (!extension.length() || checkSig) {
uint16_t token[3];
token[0] = 0x4d4d;
token[1] = 0x3dc2;
//token[2] = 0x3daa;
return CheckMagicToken(pIOHandler, pFile, token, 2, 0, 2);
}
return false;
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
static const uint16_t token[] = { 0x4d4d, 0x3dc2 /*, 0x3daa */ };
return CheckMagicToken(pIOHandler, pFile, token, AI_COUNT_OF(token), 0, sizeof token[0]);
}
// ------------------------------------------------------------------------------------------------
@ -449,7 +438,7 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
// Read the lense angle
camera->mHorizontalFOV = AI_DEG_TO_RAD(stream->GetF4());
if (camera->mHorizontalFOV < 0.001f) {
camera->mHorizontalFOV = AI_DEG_TO_RAD(45.f);
camera->mHorizontalFOV = float(AI_DEG_TO_RAD(45.f));
}
// Now check for further subchunks

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -46,11 +46,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef AI_3DSIMPORTER_H_INC
#define AI_3DSIMPORTER_H_INC
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
#include <assimp/BaseImporter.h>
#include <assimp/types.h>
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
#include "3DSHelper.h"
#include <assimp/StreamReader.h>
@ -75,14 +75,14 @@ public:
* See BaseImporter::CanRead() for details.
*/
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool checkSig) const override;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
protected:
@ -90,14 +90,14 @@ protected:
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const;
const aiImporterDesc* GetInfo () const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
IOSystem* pIOHandler) override;
// -------------------------------------------------------------------
/** Converts a temporary material to the outer representation
@ -208,6 +208,15 @@ protected:
*/
void ReplaceDefaultMaterial();
bool ContainsTextures(unsigned int i) const {
return !mScene->mMaterials[i].sTexDiffuse.mMapName.empty() ||
!mScene->mMaterials[i].sTexBump.mMapName.empty() ||
!mScene->mMaterials[i].sTexOpacity.mMapName.empty() ||
!mScene->mMaterials[i].sTexEmissive.mMapName.empty() ||
!mScene->mMaterials[i].sTexSpecular.mMapName.empty() ||
!mScene->mMaterials[i].sTexShininess.mMapName.empty() ;
}
// -------------------------------------------------------------------
/** Convert the whole scene
*/

View File

@ -0,0 +1,165 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#pragma once
#include <assimp/vector3.h>
#include <assimp/matrix4x4.h>
#include <assimp/ParsingUtils.h>
#include <vector>
#include <string>
struct aiMaterial;
struct aiMesh;
namespace Assimp {
namespace D3MF {
enum class ResourceType {
RT_Object,
RT_BaseMaterials,
RT_EmbeddedTexture2D,
RT_Texture2DGroup,
RT_Unknown
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
class Resource {
public:
int mId;
Resource(int id) :
mId(id) {
// empty
}
virtual ~Resource() {
// empty
}
virtual ResourceType getType() const {
return ResourceType::RT_Unknown;
}
};
class EmbeddedTexture : public Resource {
public:
std::string mPath;
std::string mContentType;
std::string mTilestyleU;
std::string mTilestyleV;
std::vector<char> mBuffer;
EmbeddedTexture(int id) :
Resource(id),
mPath(),
mContentType(),
mTilestyleU(),
mTilestyleV() {
// empty
}
~EmbeddedTexture() = default;
ResourceType getType() const override {
return ResourceType::RT_EmbeddedTexture2D;
}
};
class Texture2DGroup : public Resource {
public:
std::vector<aiVector2D> mTex2dCoords;
int mTexId;
Texture2DGroup(int id) :
Resource(id),
mTexId(-1) {
// empty
}
~Texture2DGroup() = default;
ResourceType getType() const override {
return ResourceType::RT_Texture2DGroup;
}
};
class BaseMaterials : public Resource {
public:
std::vector<unsigned int> mMaterialIndex;
BaseMaterials(int id) :
Resource(id),
mMaterialIndex() {
// empty
}
~BaseMaterials() = default;
ResourceType getType() const override {
return ResourceType::RT_BaseMaterials;
}
};
struct Component {
int mObjectId;
aiMatrix4x4 mTransformation;
};
class Object : public Resource {
public:
std::vector<aiMesh *> mMeshes;
std::vector<unsigned int> mMeshIndex;
std::vector<Component> mComponents;
std::string mName;
Object(int id) :
Resource(id),
mName(std::string("Object_") + ai_to_string(id)) {
// empty
}
~Object() = default;
ResourceType getType() const override {
return ResourceType::RT_Object;
}
};
} // namespace D3MF
} // namespace Assimp

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -80,13 +80,21 @@ namespace XmlTag {
const char* const item = "item";
const char* const objectid = "objectid";
const char* const transform = "transform";
const char *const path = "path";
// Material definitions
const char* const basematerials = "basematerials";
const char* const basematerials_id = "id";
const char* const basematerials_base = "base";
const char* const basematerials_name = "name";
const char* const basematerials_displaycolor = "displaycolor";
const char* const texture_2d = "m:texture2d";
const char *const texture_group = "m:texture2dgroup";
const char *const texture_content_type = "contenttype";
const char *const texture_tilestyleu = "tilestyleu";
const char *const texture_tilestylev = "tilestylev";
const char *const texture_2d_coord = "m:tex2coord";
const char *const texture_cuurd_u = "u";
const char *const texture_cuurd_v = "v";
// Meta info tags
const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
@ -103,7 +111,7 @@ namespace XmlTag {
const char* const PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
const char* const PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
const char* const PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
}
}
} // Namespace D3MF
} // Namespace Assimp

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -40,6 +40,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
#include <memory>
#include <sstream>
#include <vector>
@ -58,8 +61,6 @@ class IOStream;
namespace D3MF {
#ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
struct OpcPackageRelationship;
@ -100,9 +101,11 @@ private:
std::vector<OpcPackageRelationship*> mRelations;
};
#endif // ASSIMP_BUILD_NO_3MF_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT
} // Namespace D3MF
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_3MF_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "D3MFImporter.h"
#include "3MFXmlTags.h"
#include "D3MFOpcPackage.h"
#include "XmlSerializer.h"
#include <assimp/StringComparison.h>
#include <assimp/StringUtils.h>
@ -61,513 +62,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
#include <iomanip>
#include <string.h>
#include <cstring>
namespace Assimp {
namespace D3MF {
enum class ResourceType {
RT_Object,
RT_BaseMaterials,
RT_Unknown
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
class Resource {
public:
int mId;
Resource(int id) :
mId(id) {
// empty
}
virtual ~Resource() {
// empty
}
virtual ResourceType getType() const {
return ResourceType::RT_Unknown;
}
};
class BaseMaterials : public Resource {
public:
std::vector<aiMaterial *> mMaterials;
std::vector<unsigned int> mMaterialIndex;
BaseMaterials(int id) :
Resource(id),
mMaterials(),
mMaterialIndex() {
// empty
}
~BaseMaterials() = default;
ResourceType getType() const override {
return ResourceType::RT_BaseMaterials;
}
};
struct Component {
int mObjectId;
aiMatrix4x4 mTransformation;
};
class Object : public Resource {
public:
std::vector<aiMesh *> mMeshes;
std::vector<unsigned int> mMeshIndex;
std::vector<Component> mComponents;
std::string mName;
Object(int id) :
Resource(id),
mName(std::string("Object_") + ai_to_string(id)) {
// empty
}
~Object() = default;
ResourceType getType() const override {
return ResourceType::RT_Object;
}
};
class XmlSerializer {
public:
XmlSerializer(XmlParser *xmlParser) :
mResourcesDictionnary(),
mMaterialCount(0),
mMeshCount(0),
mXmlParser(xmlParser) {
// empty
}
~XmlSerializer() {
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it ) {
delete it->second;
}
}
void ImportXml(aiScene *scene) {
if (nullptr == scene) {
return;
}
scene->mRootNode = new aiNode(XmlTag::RootTag);
XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
if (node.empty()) {
return;
}
XmlNode resNode = node.child(XmlTag::resources);
for (auto &currentNode : resNode.children()) {
const std::string currentNodeName = currentNode.name();
if (currentNodeName == XmlTag::object) {
ReadObject(currentNode);
} else if (currentNodeName == XmlTag::basematerials) {
ReadBaseMaterials(currentNode);
} else if (currentNodeName == XmlTag::meta) {
ReadMetadata(currentNode);
}
}
XmlNode buildNode = node.child(XmlTag::build);
for (auto &currentNode : buildNode.children()) {
const std::string currentNodeName = currentNode.name();
if (currentNodeName == XmlTag::item) {
int objectId = -1;
std::string transformationMatrixStr;
aiMatrix4x4 transformationMatrix;
getNodeAttribute(currentNode, D3MF::XmlTag::objectid, objectId);
bool hasTransform = getNodeAttribute(currentNode, D3MF::XmlTag::transform, transformationMatrixStr);
auto it = mResourcesDictionnary.find(objectId);
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
Object *obj = static_cast<Object *>(it->second);
if (hasTransform) {
transformationMatrix = parseTransformMatrix(transformationMatrixStr);
}
addObjectToNode(scene->mRootNode, obj, transformationMatrix);
}
}
}
// import the metadata
if (!mMetaData.empty()) {
const size_t numMeta = mMetaData.size();
scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
for (size_t i = 0; i < numMeta; ++i) {
aiString val(mMetaData[i].value);
scene->mMetaData->Set(static_cast<unsigned int>(i), mMetaData[i].name, val);
}
}
// import the meshes
scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
if (scene->mNumMeshes != 0) {
scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
if (it->second->getType() == ResourceType::RT_Object) {
Object *obj = static_cast<Object *>(it->second);
ai_assert(nullptr != obj);
for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
}
}
}
}
// import the materials
scene->mNumMaterials = mMaterialCount;
if (scene->mNumMaterials != 0) {
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
for (unsigned int i = 0; i < baseMaterials->mMaterials.size(); ++i) {
scene->mMaterials[baseMaterials->mMaterialIndex[i]] = baseMaterials->mMaterials[i];
}
}
}
}
}
private:
void addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform) {
ai_assert(nullptr != obj);
aiNode *sceneNode = new aiNode(obj->mName);
sceneNode->mNumMeshes = static_cast<unsigned int>(obj->mMeshes.size());
sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes];
std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes);
sceneNode->mTransformation = nodeTransform;
if (nullptr != parent) {
parent->addChildren(1, &sceneNode);
}
for (size_t i = 0; i < obj->mComponents.size(); ++i) {
Component c = obj->mComponents[i];
auto it = mResourcesDictionnary.find(c.mObjectId);
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
addObjectToNode(sceneNode, static_cast<Object *>(it->second), c.mTransformation);
}
}
}
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, std::string &value) {
pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str());
if (!objectAttribute.empty()) {
value = objectAttribute.as_string();
return true;
}
return false;
}
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
std::string strValue;
bool ret = getNodeAttribute(node, attribute, strValue);
if (ret) {
value = std::atoi(strValue.c_str());
return true;
}
return false;
}
aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
// split the string
std::vector<float> numbers;
std::string currentNumber;
for (size_t i = 0; i < matrixStr.size(); ++i) {
const char c = matrixStr[i];
if (c == ' ') {
if (currentNumber.size() > 0) {
float f = std::stof(currentNumber);
numbers.push_back(f);
currentNumber.clear();
}
} else {
currentNumber.push_back(c);
}
}
if (currentNumber.size() > 0) {
const float f = std::stof(currentNumber);
numbers.push_back(f);
}
aiMatrix4x4 transformMatrix;
transformMatrix.a1 = numbers[0];
transformMatrix.b1 = numbers[1];
transformMatrix.c1 = numbers[2];
transformMatrix.d1 = 0;
transformMatrix.a2 = numbers[3];
transformMatrix.b2 = numbers[4];
transformMatrix.c2 = numbers[5];
transformMatrix.d2 = 0;
transformMatrix.a3 = numbers[6];
transformMatrix.b3 = numbers[7];
transformMatrix.c3 = numbers[8];
transformMatrix.d3 = 0;
transformMatrix.a4 = numbers[9];
transformMatrix.b4 = numbers[10];
transformMatrix.c4 = numbers[11];
transformMatrix.d4 = 1;
return transformMatrix;
}
void ReadObject(XmlNode &node) {
int id = -1, pid = -1, pindex = -1;
bool hasId = getNodeAttribute(node, XmlTag::id, id);
bool hasPid = getNodeAttribute(node, XmlTag::pid, pid);
bool hasPindex = getNodeAttribute(node, XmlTag::pindex, pindex);
if (!hasId) {
return;
}
Object *obj = new Object(id);
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::mesh) {
auto mesh = ReadMesh(currentNode);
mesh->mName.Set(ai_to_string(id));
if (hasPid) {
auto it = mResourcesDictionnary.find(pid);
if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
}
}
obj->mMeshes.push_back(mesh);
obj->mMeshIndex.push_back(mMeshCount);
mMeshCount++;
} else if (currentName == D3MF::XmlTag::components) {
for (XmlNode &currentSubNode : currentNode.children()) {
const std::string subNodeName = currentSubNode.name();
if (subNodeName == D3MF::XmlTag::component) {
int objectId = -1;
std::string componentTransformStr;
aiMatrix4x4 componentTransform;
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::transform, componentTransformStr)) {
componentTransform = parseTransformMatrix(componentTransformStr);
}
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) {
obj->mComponents.push_back({ objectId, componentTransform });
}
}
}
}
}
mResourcesDictionnary.insert(std::make_pair(id, obj));
}
aiMesh *ReadMesh(XmlNode &node) {
aiMesh *mesh = new aiMesh();
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::vertices) {
ImportVertices(currentNode, mesh);
} else if (currentName == XmlTag::triangles) {
ImportTriangles(currentNode, mesh);
}
}
return mesh;
}
void ReadMetadata(XmlNode &node) {
pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name);
const std::string name = attribute.as_string();
const std::string value = node.value();
if (name.empty()) {
return;
}
MetaEntry entry;
entry.name = name;
entry.value = value;
mMetaData.push_back(entry);
}
void ImportVertices(XmlNode &node, aiMesh *mesh) {
std::vector<aiVector3D> vertices;
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::vertex) {
vertices.push_back(ReadVertex(currentNode));
}
}
mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
}
aiVector3D ReadVertex(XmlNode &node) {
aiVector3D vertex;
vertex.x = ai_strtof(node.attribute(XmlTag::x).as_string(), nullptr);
vertex.y = ai_strtof(node.attribute(XmlTag::y).as_string(), nullptr);
vertex.z = ai_strtof(node.attribute(XmlTag::z).as_string(), nullptr);
return vertex;
}
void ImportTriangles(XmlNode &node, aiMesh *mesh) {
std::vector<aiFace> faces;
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::triangle) {
aiFace face = ReadTriangle(currentNode);
faces.push_back(face);
int pid = 0, p1 = 0;
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
if (hasPid && hasP1) {
auto it = mResourcesDictionnary.find(pid);
if (it != mResourcesDictionnary.end()) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
}
// TODO: manage the separation into several meshes if the triangles of the mesh do not all refer to the same material
}
}
}
}
mesh->mNumFaces = static_cast<unsigned int>(faces.size());
mesh->mFaces = new aiFace[mesh->mNumFaces];
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
std::copy(faces.begin(), faces.end(), mesh->mFaces);
}
aiFace ReadTriangle(XmlNode &node) {
aiFace face;
face.mNumIndices = 3;
face.mIndices = new unsigned int[face.mNumIndices];
face.mIndices[0] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v1).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()));
return face;
}
void ReadBaseMaterials(XmlNode &node) {
int id = -1;
if (getNodeAttribute(node, D3MF::XmlTag::basematerials_id, id)) {
BaseMaterials *baseMaterials = new BaseMaterials(id);
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::basematerials_base) {
baseMaterials->mMaterialIndex.push_back(mMaterialCount);
baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id));
++mMaterialCount;
}
}
mResourcesDictionnary.insert(std::make_pair(id, baseMaterials));
}
}
bool parseColor(const char *color, aiColor4D &diffuse) {
if (nullptr == color) {
return false;
}
//format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
const size_t len = strlen(color);
if (9 != len && 7 != len) {
return false;
}
const char *buf(color);
if ('#' != buf[0]) {
return false;
}
char r[3] = { buf[1], buf[2], '\0' };
diffuse.r = static_cast<ai_real>(strtol(r, nullptr, 16)) / ai_real(255.0);
char g[3] = { buf[3], buf[4], '\0' };
diffuse.g = static_cast<ai_real>(strtol(g, nullptr, 16)) / ai_real(255.0);
char b[3] = { buf[5], buf[6], '\0' };
diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
if (7 == len)
return true;
char a[3] = { buf[7], buf[8], '\0' };
diffuse.a = static_cast<ai_real>(strtol(a, nullptr, 16)) / ai_real(255.0);
return true;
}
void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
const char *color = node.attribute(XmlTag::basematerials_displaycolor).as_string();
aiColor4D diffuse;
if (parseColor(color, diffuse)) {
mat->AddProperty<aiColor4D>(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
}
}
aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId) {
aiMaterial *material = new aiMaterial();
material->mNumProperties = 0;
std::string name;
bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
std::string stdMaterialName;
const std::string strId(ai_to_string(basematerialsId));
stdMaterialName += "id";
stdMaterialName += strId;
stdMaterialName += "_";
if (hasName) {
stdMaterialName += std::string(name);
} else {
stdMaterialName += "basemat_";
stdMaterialName += ai_to_string(mMaterialCount - basematerialsId);
}
aiString assimpMaterialName(stdMaterialName);
material->AddProperty(&assimpMaterialName, AI_MATKEY_NAME);
assignDiffuseColor(node, material);
return material;
}
private:
struct MetaEntry {
std::string name;
std::string value;
};
std::vector<MetaEntry> mMetaData;
std::map<unsigned int, Resource *> mResourcesDictionnary;
unsigned int mMaterialCount, mMeshCount;
XmlParser *mXmlParser;
};
} //namespace D3MF
using namespace D3MF;
@ -593,25 +90,15 @@ D3MFImporter::~D3MFImporter() {
// empty
}
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension(GetExtension(filename));
if (extension == desc.mFileExtensions) {
return true;
} else if (!extension.length() || checkSig) {
if (nullptr == pIOHandler) {
return false;
}
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
return false;
}
D3MFOpcPackage opcPackage(pIOHandler, filename);
return opcPackage.validate();
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
return false;
}
return false;
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
return opcPackage.validate();
}
void D3MFImporter::SetupProperties(const Importer * /*pImp*/) {
void D3MFImporter::SetupProperties(const Importer*) {
// empty
}
@ -626,6 +113,15 @@ void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene,
if (xmlParser.parse(opcPackage.RootStream())) {
XmlSerializer xmlSerializer(&xmlParser);
xmlSerializer.ImportXml(pScene);
const std::vector<aiTexture*> &tex = opcPackage.GetEmbeddedTextures();
if (!tex.empty()) {
pScene->mNumTextures = static_cast<unsigned int>(tex.size());
pScene->mTextures = new aiTexture *[pScene->mNumTextures];
for (unsigned int i = 0; i < pScene->mNumTextures; ++i) {
pScene->mTextures[i] = tex[i];
}
}
}
}

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -43,23 +42,50 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_D3MFLOADER_H_INCLUDED
#define AI_D3MFLOADER_H_INCLUDED
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
#include <assimp/BaseImporter.h>
namespace Assimp {
// ---------------------------------------------------------------------------
/// @brief The 3MF-importer class.
///
/// Implements the basic topology import and embedded textures.
// ---------------------------------------------------------------------------
class D3MFImporter : public BaseImporter {
public:
/// @brief The default class constructor.
D3MFImporter();
~D3MFImporter();
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
void SetupProperties(const Importer *pImp);
const aiImporterDesc *GetInfo() const;
/// @brief The class destructor.
~D3MFImporter() override;
/// @brief Performs the data format detection.
/// @param pFile The filename to check.
/// @param pIOHandler The used IO-System.
/// @param checkSig true for signature checking.
/// @return true for can be loaded, false for not.
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
/// @brief Not used
/// @param pImp Not used
void SetupProperties(const Importer *pImp) override;
/// @brief The importer description getter.
/// @return The info
const aiImporterDesc *GetInfo() const override;
protected:
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
/// @brief Internal read function, performs the file parsing.
/// @param pFile The filename
/// @param pScene The scene to load in.
/// @param pIOHandler The io-system
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
};
} // Namespace Assimp
#endif // #ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
#endif // AI_D3MFLOADER_H_INCLUDED

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -43,20 +43,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "D3MFOpcPackage.h"
#include <assimp/Exceptional.h>
#include <assimp/XmlParser.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/ai_assert.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/texture.h>
#include "3MFXmlTags.h"
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <map>
#include <memory>
#include <vector>
namespace Assimp {
@ -64,11 +63,12 @@ namespace Assimp {
namespace D3MF {
// ------------------------------------------------------------------------------------------------
typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
class OpcPackageRelationshipReader {
public:
OpcPackageRelationshipReader(XmlParser &parser) {
OpcPackageRelationshipReader(XmlParser &parser) :
m_relationShips() {
XmlNode root = parser.getRootNode();
ParseRootNode(root);
}
@ -91,6 +91,7 @@ public:
if (relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty()) {
return false;
}
return true;
}
@ -100,7 +101,7 @@ public:
}
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
std::string name = currentNode.name();
const std::string name = currentNode.name();
if (name == "Relationship") {
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID).as_string();
@ -116,11 +117,23 @@ public:
std::vector<OpcPackageRelationshipPtr> m_relationShips;
};
static bool IsEmbeddedTexture( const std::string &filename ) {
const std::string extension = BaseImporter::GetExtension(filename);
if (extension == "jpg" || extension == "png") {
std::string::size_type pos = filename.find("thumbnail");
if (pos == std::string::npos) {
return false;
}
return true;
}
return false;
}
// ------------------------------------------------------------------------------------------------
D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
mRootStream(nullptr),
mZipArchive() {
mZipArchive.reset(new ZipArchiveIOSystem(pIOHandler, rFile));
mZipArchive = new ZipArchiveIOSystem(pIOHandler, rFile);
if (!mZipArchive->isOpen()) {
throw DeadlyImportError("Failed to open file ", rFile, ".");
}
@ -136,18 +149,18 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
IOStream *fileStream = mZipArchive->Open(file.c_str());
if (nullptr == fileStream) {
ai_assert(fileStream != nullptr);
ASSIMP_LOG_ERROR("Filestream is nullptr.");
continue;
}
std::string rootFile = ReadPackageRootRelationship(fileStream);
if (rootFile.size() > 0 && rootFile[0] == '/') {
if (!rootFile.empty() && rootFile[0] == '/') {
rootFile = rootFile.substr(1);
if (rootFile[0] == '/') {
// deal with zip-bug
rootFile = rootFile.substr(1);
}
}
}
ASSIMP_LOG_VERBOSE_DEBUG(rootFile);
@ -158,9 +171,12 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
if (nullptr == mRootStream) {
throw DeadlyImportError("Cannot open root-file in archive : " + rootFile);
}
} else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
ASSIMP_LOG_WARN("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file);
} else if (IsEmbeddedTexture(file)) {
IOStream *fileStream = mZipArchive->Open(file.c_str());
LoadEmbeddedTextures(fileStream, file);
mZipArchive->Close(fileStream);
} else {
ASSIMP_LOG_WARN("Ignored file of unknown type: ", file);
}
@ -169,20 +185,25 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
D3MFOpcPackage::~D3MFOpcPackage() {
mZipArchive->Close(mRootStream);
delete mZipArchive;
}
IOStream *D3MFOpcPackage::RootStream() const {
return mRootStream;
}
static const std::string ModelRef = "3D/3dmodel.model";
const std::vector<aiTexture *> &D3MFOpcPackage::GetEmbeddedTextures() const {
return mEmbeddedTextures;
}
static const char *const ModelRef = "3D/3dmodel.model";
bool D3MFOpcPackage::validate() {
if (nullptr == mRootStream || nullptr == mZipArchive) {
return false;
}
return mZipArchive->Exists(ModelRef.c_str());
return mZipArchive->Exists(ModelRef);
}
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
@ -204,6 +225,31 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
return (*itr)->target;
}
void D3MFOpcPackage::LoadEmbeddedTextures(IOStream *fileStream, const std::string &filename) {
if (nullptr == fileStream) {
return;
}
const size_t size = fileStream->FileSize();
if (0 == size) {
return;
}
unsigned char *data = new unsigned char[size];
fileStream->Read(data, 1, size);
aiTexture *texture = new aiTexture;
std::string embName = "*" + filename;
texture->mFilename.Set(embName.c_str());
texture->mWidth = static_cast<unsigned int>(size);
texture->mHeight = 0;
texture->achFormatHint[0] = 'p';
texture->achFormatHint[1] = 'n';
texture->achFormatHint[2] = 'g';
texture->achFormatHint[3] = '\0';
texture->pcData = (aiTexel*) data;
mEmbeddedTextures.emplace_back(texture);
}
} // Namespace D3MF
} // Namespace Assimp

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -42,12 +42,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef D3MFOPCPACKAGE_H
#define D3MFOPCPACKAGE_H
#include <assimp/IOSystem.hpp>
#include <memory>
#include <string>
#include <assimp/IOSystem.hpp>
struct aiTexture;
namespace Assimp {
class ZipArchiveIOSystem;
class ZipArchiveIOSystem;
namespace D3MF {
@ -63,16 +66,19 @@ public:
~D3MFOpcPackage();
IOStream* RootStream() const;
bool validate();
const std::vector<aiTexture*> &GetEmbeddedTextures() const;
protected:
std::string ReadPackageRootRelationship(IOStream* stream);
void LoadEmbeddedTextures(IOStream *fileStream, const std::string &filename);
private:
IOStream* mRootStream;
std::unique_ptr<ZipArchiveIOSystem> mZipArchive;
ZipArchiveIOSystem *mZipArchive;
std::vector<aiTexture *> mEmbeddedTextures;
};
} // Namespace D3MF
} // Namespace Assimp
} // namespace D3MF
} // namespace Assimp
#endif // D3MFOPCPACKAGE_H

View File

@ -0,0 +1,593 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#include "XmlSerializer.h"
#include "D3MFOpcPackage.h"
#include "3MFXmlTags.h"
#include "3MFTypes.h"
#include <assimp/scene.h>
namespace Assimp {
namespace D3MF {
static const int IdNotSet = -1;
namespace {
static const size_t ColRGBA_Len = 9;
static const size_t ColRGB_Len = 7;
// format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
bool validateColorString(const char *color) {
const size_t len = strlen(color);
if (ColRGBA_Len != len && ColRGB_Len != len) {
return false;
}
return true;
}
aiFace ReadTriangle(XmlNode &node) {
aiFace face;
face.mNumIndices = 3;
face.mIndices = new unsigned int[face.mNumIndices];
face.mIndices[0] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v1).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()));
return face;
}
aiVector3D ReadVertex(XmlNode &node) {
aiVector3D vertex;
vertex.x = ai_strtof(node.attribute(XmlTag::x).as_string(), nullptr);
vertex.y = ai_strtof(node.attribute(XmlTag::y).as_string(), nullptr);
vertex.z = ai_strtof(node.attribute(XmlTag::z).as_string(), nullptr);
return vertex;
}
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, std::string &value) {
pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str());
if (!objectAttribute.empty()) {
value = objectAttribute.as_string();
return true;
}
return false;
}
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
std::string strValue;
const bool ret = getNodeAttribute(node, attribute, strValue);
if (ret) {
value = std::atoi(strValue.c_str());
return true;
}
return false;
}
aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
// split the string
std::vector<float> numbers;
std::string currentNumber;
for (char c : matrixStr) {
if (c == ' ') {
if (!currentNumber.empty()) {
float f = std::stof(currentNumber);
numbers.push_back(f);
currentNumber.clear();
}
} else {
currentNumber.push_back(c);
}
}
if (!currentNumber.empty()) {
const float f = std::stof(currentNumber);
numbers.push_back(f);
}
aiMatrix4x4 transformMatrix;
transformMatrix.a1 = numbers[0];
transformMatrix.b1 = numbers[1];
transformMatrix.c1 = numbers[2];
transformMatrix.d1 = 0;
transformMatrix.a2 = numbers[3];
transformMatrix.b2 = numbers[4];
transformMatrix.c2 = numbers[5];
transformMatrix.d2 = 0;
transformMatrix.a3 = numbers[6];
transformMatrix.b3 = numbers[7];
transformMatrix.c3 = numbers[8];
transformMatrix.d3 = 0;
transformMatrix.a4 = numbers[9];
transformMatrix.b4 = numbers[10];
transformMatrix.c4 = numbers[11];
transformMatrix.d4 = 1;
return transformMatrix;
}
bool parseColor(const char *color, aiColor4D &diffuse) {
if (nullptr == color) {
return false;
}
if (!validateColorString(color)) {
return false;
}
if ('#' != color[0]) {
return false;
}
char r[3] = { color[1], color[2], '\0' };
diffuse.r = static_cast<ai_real>(strtol(r, nullptr, 16)) / ai_real(255.0);
char g[3] = { color[3], color[4], '\0' };
diffuse.g = static_cast<ai_real>(strtol(g, nullptr, 16)) / ai_real(255.0);
char b[3] = { color[5], color[6], '\0' };
diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
const size_t len = strlen(color);
if (ColRGB_Len == len) {
return true;
}
char a[3] = { color[7], color[8], '\0' };
diffuse.a = static_cast<ai_real>(strtol(a, nullptr, 16)) / ai_real(255.0);
return true;
}
void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
const char *color = node.attribute(XmlTag::basematerials_displaycolor).as_string();
aiColor4D diffuse;
if (parseColor(color, diffuse)) {
mat->AddProperty<aiColor4D>(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
}
}
} // namespace
XmlSerializer::XmlSerializer(XmlParser *xmlParser) :
mResourcesDictionnary(),
mMeshCount(0),
mXmlParser(xmlParser) {
ai_assert(nullptr != xmlParser);
}
XmlSerializer::~XmlSerializer() {
for (auto &it : mResourcesDictionnary) {
delete it.second;
}
}
void XmlSerializer::ImportXml(aiScene *scene) {
if (nullptr == scene) {
return;
}
scene->mRootNode = new aiNode(XmlTag::RootTag);
XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
if (node.empty()) {
return;
}
XmlNode resNode = node.child(XmlTag::resources);
for (auto &currentNode : resNode.children()) {
const std::string currentNodeName = currentNode.name();
if (currentNodeName == XmlTag::texture_2d) {
ReadEmbeddecTexture(currentNode);
} else if (currentNodeName == XmlTag::texture_group) {
ReadTextureGroup(currentNode);
} else if (currentNodeName == XmlTag::object) {
ReadObject(currentNode);
} else if (currentNodeName == XmlTag::basematerials) {
ReadBaseMaterials(currentNode);
} else if (currentNodeName == XmlTag::meta) {
ReadMetadata(currentNode);
}
}
StoreMaterialsInScene(scene);
XmlNode buildNode = node.child(XmlTag::build);
if (buildNode.empty()) {
return;
}
for (auto &currentNode : buildNode.children()) {
const std::string currentNodeName = currentNode.name();
if (currentNodeName == XmlTag::item) {
int objectId = IdNotSet;
std::string transformationMatrixStr;
aiMatrix4x4 transformationMatrix;
getNodeAttribute(currentNode, D3MF::XmlTag::objectid, objectId);
bool hasTransform = getNodeAttribute(currentNode, D3MF::XmlTag::transform, transformationMatrixStr);
auto it = mResourcesDictionnary.find(objectId);
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
Object *obj = static_cast<Object *>(it->second);
if (hasTransform) {
transformationMatrix = parseTransformMatrix(transformationMatrixStr);
}
addObjectToNode(scene->mRootNode, obj, transformationMatrix);
}
}
}
// import the metadata
if (!mMetaData.empty()) {
const size_t numMeta = mMetaData.size();
scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
for (size_t i = 0; i < numMeta; ++i) {
aiString val(mMetaData[i].value);
scene->mMetaData->Set(static_cast<unsigned int>(i), mMetaData[i].name, val);
}
}
// import the meshes, materials are already stored
scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
if (scene->mNumMeshes != 0) {
scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
for (auto &it : mResourcesDictionnary) {
if (it.second->getType() == ResourceType::RT_Object) {
Object *obj = static_cast<Object *>(it.second);
ai_assert(nullptr != obj);
for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
}
}
}
}
}
void XmlSerializer::addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform) {
ai_assert(nullptr != obj);
aiNode *sceneNode = new aiNode(obj->mName);
sceneNode->mNumMeshes = static_cast<unsigned int>(obj->mMeshes.size());
sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes];
std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes);
sceneNode->mTransformation = nodeTransform;
if (nullptr != parent) {
parent->addChildren(1, &sceneNode);
}
for (Assimp::D3MF::Component c : obj->mComponents) {
auto it = mResourcesDictionnary.find(c.mObjectId);
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
addObjectToNode(sceneNode, static_cast<Object *>(it->second), c.mTransformation);
}
}
}
void XmlSerializer::ReadObject(XmlNode &node) {
int id = IdNotSet, pid = IdNotSet, pindex = IdNotSet;
bool hasId = getNodeAttribute(node, XmlTag::id, id);
if (!hasId) {
return;
}
bool hasPid = getNodeAttribute(node, XmlTag::pid, pid);
bool hasPindex = getNodeAttribute(node, XmlTag::pindex, pindex);
Object *obj = new Object(id);
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == D3MF::XmlTag::mesh) {
auto mesh = ReadMesh(currentNode);
mesh->mName.Set(ai_to_string(id));
if (hasPid) {
auto it = mResourcesDictionnary.find(pid);
if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
}
}
obj->mMeshes.push_back(mesh);
obj->mMeshIndex.push_back(mMeshCount);
mMeshCount++;
} else if (currentName == D3MF::XmlTag::components) {
for (XmlNode &currentSubNode : currentNode.children()) {
const std::string subNodeName = currentSubNode.name();
if (subNodeName == D3MF::XmlTag::component) {
int objectId = IdNotSet;
std::string componentTransformStr;
aiMatrix4x4 componentTransform;
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::transform, componentTransformStr)) {
componentTransform = parseTransformMatrix(componentTransformStr);
}
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) {
obj->mComponents.push_back({ objectId, componentTransform });
}
}
}
}
}
mResourcesDictionnary.insert(std::make_pair(id, obj));
}
aiMesh *XmlSerializer::ReadMesh(XmlNode &node) {
if (node.empty()) {
return nullptr;
}
aiMesh *mesh = new aiMesh();
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::vertices) {
ImportVertices(currentNode, mesh);
} else if (currentName == XmlTag::triangles) {
ImportTriangles(currentNode, mesh);
}
}
return mesh;
}
void XmlSerializer::ReadMetadata(XmlNode &node) {
pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name);
const std::string name = attribute.as_string();
const std::string value = node.value();
if (name.empty()) {
return;
}
MetaEntry entry;
entry.name = name;
entry.value = value;
mMetaData.push_back(entry);
}
void XmlSerializer::ImportVertices(XmlNode &node, aiMesh *mesh) {
ai_assert(nullptr != mesh);
std::vector<aiVector3D> vertices;
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::vertex) {
vertices.push_back(ReadVertex(currentNode));
}
}
mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
}
void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
std::vector<aiFace> faces;
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::triangle) {
int pid = IdNotSet, p1 = IdNotSet;
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
if (hasPid && hasP1) {
auto it = mResourcesDictionnary.find(pid);
if (it != mResourcesDictionnary.end()) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
} else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
if (mesh->mTextureCoords[0] == nullptr) {
Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second);
const std::string name = ai_to_string(group->mTexId);
for (size_t i = 0; i < mMaterials.size(); ++i) {
if (name == mMaterials[i]->GetName().C_Str()) {
mesh->mMaterialIndex = static_cast<unsigned int>(i);
}
}
mesh->mTextureCoords[0] = new aiVector3D[group->mTex2dCoords.size()];
for (unsigned int i = 0; i < group->mTex2dCoords.size(); ++i) {
mesh->mTextureCoords[0][i] = aiVector3D(group->mTex2dCoords[i].x, group->mTex2dCoords[i].y, 0);
}
}
}
}
}
aiFace face = ReadTriangle(currentNode);
faces.push_back(face);
}
}
mesh->mNumFaces = static_cast<unsigned int>(faces.size());
mesh->mFaces = new aiFace[mesh->mNumFaces];
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
std::copy(faces.begin(), faces.end(), mesh->mFaces);
}
void XmlSerializer::ReadBaseMaterials(XmlNode &node) {
int id = IdNotSet;
if (getNodeAttribute(node, D3MF::XmlTag::id, id)) {
BaseMaterials *baseMaterials = new BaseMaterials(id);
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::basematerials_base) {
baseMaterials->mMaterialIndex.push_back(static_cast<unsigned int>(mMaterials.size()));
mMaterials.push_back(readMaterialDef(currentNode, id));
}
}
mResourcesDictionnary.insert(std::make_pair(id, baseMaterials));
}
}
void XmlSerializer::ReadEmbeddecTexture(XmlNode &node) {
if (node.empty()) {
return;
}
std::string value;
EmbeddedTexture *tex2D = nullptr;
if (XmlParser::getStdStrAttribute(node, XmlTag::id, value)) {
tex2D = new EmbeddedTexture(atoi(value.c_str()));
}
if (nullptr == tex2D) {
return;
}
if (XmlParser::getStdStrAttribute(node, XmlTag::path, value)) {
tex2D->mPath = value;
}
if (XmlParser::getStdStrAttribute(node, XmlTag::texture_content_type, value)) {
tex2D->mContentType = value;
}
if (XmlParser::getStdStrAttribute(node, XmlTag::texture_tilestyleu, value)) {
tex2D->mTilestyleU = value;
}
if (XmlParser::getStdStrAttribute(node, XmlTag::texture_tilestylev, value)) {
tex2D->mTilestyleV = value;
}
mEmbeddedTextures.emplace_back(tex2D);
StoreEmbeddedTexture(tex2D);
}
void XmlSerializer::StoreEmbeddedTexture(EmbeddedTexture *tex) {
aiMaterial *mat = new aiMaterial;
aiString s;
s.Set(ai_to_string(tex->mId).c_str());
mat->AddProperty(&s, AI_MATKEY_NAME);
const std::string name = "*" + tex->mPath;
s.Set(name);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
aiColor3D col;
mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_DIFFUSE);
mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_AMBIENT);
mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_EMISSIVE);
mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_SPECULAR);
mMaterials.emplace_back(mat);
}
void XmlSerializer::ReadTextureCoords2D(XmlNode &node, Texture2DGroup *tex2DGroup) {
if (node.empty() || nullptr == tex2DGroup) {
return;
}
int id = IdNotSet;
if (XmlParser::getIntAttribute(node, "texid", id)) {
tex2DGroup->mTexId = id;
}
double value = 0.0;
for (XmlNode currentNode : node.children()) {
const std::string currentName = currentNode.name();
aiVector2D texCoord;
if (currentName == XmlTag::texture_2d_coord) {
XmlParser::getDoubleAttribute(currentNode, XmlTag::texture_cuurd_u, value);
texCoord.x = (ai_real)value;
XmlParser::getDoubleAttribute(currentNode, XmlTag::texture_cuurd_v, value);
texCoord.y = (ai_real)value;
tex2DGroup->mTex2dCoords.push_back(texCoord);
}
}
}
void XmlSerializer::ReadTextureGroup(XmlNode &node) {
if (node.empty()) {
return;
}
int id = IdNotSet;
if (!XmlParser::getIntAttribute(node, XmlTag::id, id)) {
return;
}
Texture2DGroup *group = new Texture2DGroup(id);
ReadTextureCoords2D(node, group);
mResourcesDictionnary.insert(std::make_pair(id, group));
}
aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basematerialsId) {
aiMaterial *material = new aiMaterial();
material->mNumProperties = 0;
std::string name;
bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
std::string stdMaterialName;
const std::string strId(ai_to_string(basematerialsId));
stdMaterialName += "id";
stdMaterialName += strId;
stdMaterialName += "_";
if (hasName) {
stdMaterialName += std::string(name);
} else {
stdMaterialName += "basemat_";
stdMaterialName += ai_to_string(mMaterials.size());
}
aiString assimpMaterialName(stdMaterialName);
material->AddProperty(&assimpMaterialName, AI_MATKEY_NAME);
assignDiffuseColor(node, material);
return material;
}
void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
if (nullptr == scene || mMaterials.empty()) {
return;
}
scene->mNumMaterials = static_cast<unsigned int>(mMaterials.size());
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
for (size_t i = 0; i < mMaterials.size(); ++i) {
scene->mMaterials[i] = mMaterials[i];
}
}
} // namespace D3MF
} // namespace Assimp

View File

@ -0,0 +1,96 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#pragma once
#include <assimp/XmlParser.h>
#include <assimp/mesh.h>
#include <vector>
#include <map>
struct aiNode;
struct aiMesh;
struct aiMaterial;
namespace Assimp {
namespace D3MF {
class Resource;
class D3MFOpcPackage;
class Object;
class Texture2DGroup;
class EmbeddedTexture;
class XmlSerializer {
public:
XmlSerializer(XmlParser *xmlParser);
~XmlSerializer();
void ImportXml(aiScene *scene);
private:
void addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform);
void ReadObject(XmlNode &node);
aiMesh *ReadMesh(XmlNode &node);
void ReadMetadata(XmlNode &node);
void ImportVertices(XmlNode &node, aiMesh *mesh);
void ImportTriangles(XmlNode &node, aiMesh *mesh);
void ReadBaseMaterials(XmlNode &node);
void ReadEmbeddecTexture(XmlNode &node);
void StoreEmbeddedTexture(EmbeddedTexture *tex);
void ReadTextureCoords2D(XmlNode &node, Texture2DGroup *tex2DGroup);
void ReadTextureGroup(XmlNode &node);
aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId);
void StoreMaterialsInScene(aiScene *scene);
private:
struct MetaEntry {
std::string name;
std::string value;
};
std::vector<MetaEntry> mMetaData;
std::vector<EmbeddedTexture *> mEmbeddedTextures;
std::vector<aiMaterial *> mMaterials;
std::map<unsigned int, Resource *> mResourcesDictionnary;
unsigned int mMeshCount;
XmlParser *mXmlParser;
};
} // namespace D3MF
} // namespace Assimp

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -152,18 +152,9 @@ AC3DImporter::~AC3DImporter() {
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool AC3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
std::string extension = GetExtension(pFile);
// fixme: are acc and ac3d *really* used? Some sources say they are
if (extension == "ac" || extension == "ac3d" || extension == "acc") {
return true;
}
if (!extension.length() || checkSig) {
uint32_t token = AI_MAKE_MAGIC("AC3D");
return CheckMagicToken(pIOHandler, pFile, &token, 1, 0);
}
return false;
bool AC3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
static const uint32_t tokens[] = { AI_MAKE_MAGIC("AC3D") };
return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}
// ------------------------------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -63,7 +63,7 @@ namespace Assimp {
class AC3DImporter : public BaseImporter {
public:
AC3DImporter();
~AC3DImporter();
~AC3DImporter() override;
// Represents an AC3D material
struct Material {
@ -185,25 +185,25 @@ public:
* See BaseImporter::CanRead() for details.
*/
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details */
const aiImporterDesc *GetInfo() const;
const aiImporterDesc *GetInfo() const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details*/
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
IOSystem *pIOHandler) override;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.*/
void SetupProperties(const Importer *pImp);
void SetupProperties(const Importer *pImp) override;
private:
// -------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -303,7 +303,7 @@ void AMFImporter::ParseNode_Root() {
}
XmlNode node = *root;
mUnit = ai_tolower(std::string(node.attribute("unit").as_string()));
mVersion = node.attribute("version").as_string();
// Read attributes for node <amf>.
@ -503,19 +503,9 @@ void AMFImporter::ParseNode_Metadata(XmlNode &node) {
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
}
bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const {
const std::string extension = GetExtension(pFile);
if (extension == "amf") {
return true;
}
if (extension.empty() || pCheckSig) {
const char *tokens[] = { "<amf" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*pCheckSig*/) const {
static const char *tokens[] = { "<amf" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}
const aiImporterDesc *AMFImporter::GetInfo() const {

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -267,7 +267,7 @@ public:
AMFImporter() AI_NO_EXCEPT;
/// Default destructor.
~AMFImporter();
~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.
@ -276,9 +276,9 @@ public:
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
void ParseHelper_Node_Exit();
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
const aiImporterDesc *GetInfo() const;
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;

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -75,7 +75,7 @@ void AMFImporter::ParseNode_Mesh(XmlNode &node) {
found_volumes = true;
}
ParseHelper_Node_Exit();
}
}
if (!found_verts && !found_volumes) {
mNodeElement_Cur->Child.push_back(ne);
@ -199,9 +199,9 @@ void AMFImporter::ParseNode_Volume(XmlNode &node) {
// Read attributes for node <color>.
// and assign read data
((AMFVolume *)ne)->MaterialID = node.attribute("materialid").as_string();
((AMFVolume *)ne)->Type = type;
// Check for child nodes
bool col_read = false;

View File

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

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -48,15 +48,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_AI_AMF_IMPORTER_NODE_H
#define INCLUDED_AI_AMF_IMPORTER_NODE_H
// Header files, stdlib.
// Header files, Assimp.
#include <assimp/scene.h>
#include <assimp/types.h>
#include <list>
#include <string>
#include <vector>
// Header files, Assimp.
#include "assimp/scene.h"
#include "assimp/types.h"
/// \class CAMFImporter_NodeElement
/// Base class for elements of nodes.
class AMFNodeElementBase {

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -69,7 +69,7 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
}
tcol = Color->Color;
// Check if default color must be used
if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) {
tcol.r = 0.5f;
@ -99,10 +99,10 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &nodeEleme
}
// all coordinates stored as child and we need to reserve space for future push_back's.
vertexCoordinateArray.reserve(vn->Child.size());
vertexCoordinateArray.reserve(vn->Child.size());
// colors count equal vertices count.
pVertexColorArray.resize(vn->Child.size());
pVertexColorArray.resize(vn->Child.size());
col_idx = 0;
// Inside vertices collect all data and place to arrays
@ -690,7 +690,7 @@ void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellatio
if (ne->Type == AMFNodeElementBase::ENET_Metadata) continue;
if (ne->Type != AMFNodeElementBase::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");
// create alias for conveniance
// create alias for convenience
AMFInstance &als = *((AMFInstance *)ne);
// find referenced object
if (!Find_ConvertedNode(als.ObjectID, nodeArray, &found_node)) Throw_ID_NotFound(als.ObjectID);

View File

@ -3,9 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -97,19 +95,9 @@ ASEImporter::~ASEImporter() {
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool ASEImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const {
// check file extension
const std::string extension = GetExtension(pFile);
if (extension == "ase" || extension == "ask") {
return true;
}
if ((!extension.length() || cs) && pIOHandler) {
const char *tokens[] = { "*3dsmax_asciiexport" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
bool ASEImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
static const char *tokens[] = { "*3dsmax_asciiexport" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}
// ------------------------------------------------------------------------------------------------
@ -683,7 +671,7 @@ void ASEImporter::BuildNodes(std::vector<BaseNode *> &nodes) {
}
}
// Are there ane orphaned nodes?
// Are there any orphaned nodes?
if (!aiList.empty()) {
std::vector<aiNode *> apcNodes;
apcNodes.reserve(aiList.size() + pcScene->mRootNode->mNumChildren);

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -62,42 +62,37 @@ namespace Assimp {
class ASEImporter : public BaseImporter {
public:
ASEImporter();
~ASEImporter();
~ASEImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
*/
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const;
const aiImporterDesc* GetInfo () const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
IOSystem* pIOHandler) override;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
private:
// -------------------------------------------------------------------
/** Generate normal vectors basing on smoothing groups
* (in some cases the normal are already contained in the file)
@ -106,7 +101,6 @@ private:
*/
bool GenerateNormals(ASE::Mesh& mesh);
// -------------------------------------------------------------------
/** Create valid vertex/normal/UV/color/face lists.
* All elements are unique, faces have only one set of indices
@ -115,51 +109,43 @@ private:
*/
void BuildUniqueRepresentation(ASE::Mesh& mesh);
/** Create one-material-per-mesh meshes ;-)
* \param mesh Mesh to work with
* \param Receives the list of all created meshes
*/
void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut);
// -------------------------------------------------------------------
/** Convert a material to a aiMaterial object
* \param mat Input material
*/
void ConvertMaterial(ASE::Material& mat);
// -------------------------------------------------------------------
/** Setup the final material indices for each mesh
*/
void BuildMaterialIndices();
// -------------------------------------------------------------------
/** Build the node graph
*/
void BuildNodes(std::vector<ASE::BaseNode*>& nodes);
// -------------------------------------------------------------------
/** Build output cameras
*/
void BuildCameras();
// -------------------------------------------------------------------
/** Build output lights
*/
void BuildLights();
// -------------------------------------------------------------------
/** Build output animations
*/
void BuildAnimations(const std::vector<ASE::BaseNode*>& nodes);
// -------------------------------------------------------------------
/** Add sub nodes to a node
* \param pcParent parent node to be filled
@ -183,7 +169,6 @@ private:
void GenerateDefaultMaterial();
protected:
/** Parser instance */
ASE::Parser* mParser;

View File

@ -3,9 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -114,6 +112,7 @@ using namespace Assimp::ASE;
// ------------------------------------------------------------------------------------------------
Parser::Parser(const char *szFile, unsigned int fileFormatDefault) {
ai_assert(nullptr != szFile);
filePtr = szFile;
iFileFormat = fileFormatDefault;
@ -490,6 +489,7 @@ void Parser::ParseLV1MaterialListBlock() {
if (iIndex >= iMaterialCount) {
LogWarning("Out of range: material index is too large");
iIndex = iMaterialCount - 1;
return;
}
// get a reference to the material
@ -906,7 +906,6 @@ void Parser::ParseLV2LightSettingsBlock(ASE::Light &light) {
}
AI_ASE_HANDLE_SECTION("2", "LIGHT_SETTINGS");
}
return;
}
// ------------------------------------------------------------------------------------------------
@ -1783,7 +1782,9 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
// *MESH_MTLID is optional, too
while (true) {
if ('*' == *filePtr) break;
if ('*' == *filePtr) {
break;
}
if (IsLineEnd(*filePtr)) {
return;
}
@ -1832,8 +1833,9 @@ void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) {
void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) {
ai_assert(nullptr != apOut);
for (unsigned int i = 0; i < 3; ++i)
for (unsigned int i = 0; i < 3; ++i) {
ParseLV4MeshFloat(apOut[i]);
}
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshFloat(ai_real &fOut) {

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -95,8 +95,8 @@ struct Material : public D3DS::Material {
Material(Material &&other) AI_NO_EXCEPT
: D3DS::Material(std::move(other)),
avSubMaterials(std::move(other.avSubMaterials)),
pcInstance(std::move(other.pcInstance)),
bNeed(std::move(other.bNeed)) {
pcInstance(other.pcInstance),
bNeed(other.bNeed) {
other.pcInstance = nullptr;
}
@ -108,8 +108,8 @@ struct Material : public D3DS::Material {
//D3DS::Material::operator=(std::move(other));
avSubMaterials = std::move(other.avSubMaterials);
pcInstance = std::move(other.pcInstance);
bNeed = std::move(other.bNeed);
pcInstance = other.pcInstance;
bNeed = other.bNeed;
other.pcInstance = nullptr;

View File

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

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -43,16 +42,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file AssbinExporter.h
* ASSBIN Exporter Main Header
*/
#pragma once
#ifndef AI_ASSBINEXPORTER_H_INC
#define AI_ASSBINEXPORTER_H_INC
#include <assimp/defs.h>
#ifndef ASSIMP_BUILD_NO_EXPORT
// nothing really needed here - reserved for future use like properties
namespace Assimp {
void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/);
}
#endif
#endif // AI_ASSBINEXPORTER_H_INC

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -43,13 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "AssbinFileWriter.h"
#include "Common/assbin_chunks.h"
#include "PostProcessing/ProcessHelper.h"
#include <assimp/Exceptional.h>
#include <assimp/version.h>
#include <assimp/Exporter.hpp>
#include <assimp/IOStream.hpp>
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
@ -58,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../contrib/zlib/zlib.h"
#endif
#include <time.h>
#include <ctime>
#if _MSC_VER
#pragma warning(push)
@ -172,7 +170,7 @@ inline size_t Write<aiQuaternion>(IOStream *stream, const aiQuaternion &v) {
t += Write<float>(stream, v.z);
ai_assert(t == 16);
return 16;
return t;
}
// -----------------------------------------------------------------------------------
@ -184,6 +182,8 @@ inline size_t Write<aiVertexWeight>(IOStream *stream, const aiVertexWeight &v) {
return t + Write<float>(stream, v.mWeight);
}
constexpr size_t MatrixSize = 64;
// -----------------------------------------------------------------------------------
// Serialize a mat4x4
template <>
@ -194,7 +194,7 @@ inline size_t Write<aiMatrix4x4>(IOStream *stream, const aiMatrix4x4 &m) {
}
}
return 64;
return MatrixSize;
}
// -----------------------------------------------------------------------------------
@ -277,7 +277,7 @@ public:
// empty
}
virtual ~AssbinChunkWriter() {
~AssbinChunkWriter() override {
if (container) {
container->Write(&magic, sizeof(uint32_t), 1);
container->Write(&cursor, sizeof(uint32_t), 1);
@ -288,26 +288,27 @@ public:
void *GetBufferPointer() { return buffer; }
// -------------------------------------------------------------------
virtual size_t Read(void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) {
size_t Read(void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) override {
return 0;
}
virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) {
aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) override {
return aiReturn_FAILURE;
}
virtual size_t Tell() const {
size_t Tell() const override {
return cursor;
}
virtual void Flush() {
void Flush() override {
// not implemented
}
virtual size_t FileSize() const {
size_t FileSize() const override {
return cursor;
}
// -------------------------------------------------------------------
virtual size_t Write(const void *pvBuffer, size_t pSize, size_t pCount) {
size_t Write(const void *pvBuffer, size_t pSize, size_t pCount) override {
pSize *= pCount;
if (cursor + pSize > cur_size) {
Grow(cursor + pSize);

View File

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

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -406,7 +406,7 @@ void AssbinImporter::ReadBinaryMesh(IOStream *stream, aiMesh *mesh) {
f.mIndices = new unsigned int[f.mNumIndices];
for (unsigned int a = 0; a < f.mNumIndices; ++a) {
// Check if unsigned short ( 16 bit ) are big enought for the indices
// Check if unsigned short ( 16 bit ) are big enough for the indices
if (fitsIntoUI16(mesh->mNumVertices)) {
f.mIndices[a] = Read<uint16_t>(stream);
} else {

View File

@ -3,8 +3,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -74,17 +73,11 @@ private:
bool compressed;
public:
virtual bool CanRead(
const std::string& pFile,
IOSystem* pIOHandler,
bool checkSig
) const;
virtual const aiImporterDesc* GetInfo() const;
virtual void InternReadFile(
const std::string& pFile,
aiScene* pScene,
IOSystem* pIOHandler
);
bool CanRead(const std::string& pFile,
IOSystem* pIOHandler, bool checkSig) const override;
const aiImporterDesc* GetInfo() const override;
void InternReadFile(
const std::string& pFile,aiScene* pScene,IOSystem* pIOHandler) override;
void ReadHeader();
void ReadBinaryScene( IOStream * stream, aiScene* pScene );
void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );

View File

@ -41,12 +41,17 @@ public:
enum {
Flag_DoNotIndent = 0x1,
Flag_WriteSpecialFloats = 0x2,
Flag_SkipWhitespaces = 0x4
};
JSONWriter(Assimp::IOStream &out, unsigned int flags = 0u) :
out(out), first(), flags(flags) {
out(out), indent (""), newline("\n"), space(" "), buff (), first(false), flags(flags) {
// make sure that all formatting happens using the standard, C locale and not the user's current locale
buff.imbue(std::locale("C"));
if (flags & Flag_SkipWhitespaces) {
newline = "";
space = "";
}
}
~JSONWriter() {
@ -70,7 +75,7 @@ public:
void Key(const std::string &name) {
AddIndentation();
Delimit();
buff << '\"' + name + "\": ";
buff << '\"' + name + "\":" << space;
}
template <typename Literal>
@ -78,12 +83,12 @@ public:
AddIndentation();
Delimit();
LiteralToString(buff, name) << '\n';
LiteralToString(buff, name) << newline;
}
template <typename Literal>
void SimpleValue(const Literal &s) {
LiteralToString(buff, s) << '\n';
LiteralToString(buff, s) << newline;
}
void SimpleValue(const void *buffer, size_t len) {
@ -102,7 +107,7 @@ public:
}
}
buff << '\"' << cur_out << "\"\n";
buff << '\"' << cur_out << "\"" << newline;
delete[] cur_out;
}
@ -115,7 +120,7 @@ public:
}
}
first = true;
buff << "{\n";
buff << "{" << newline;
PushIndent();
}
@ -123,7 +128,7 @@ public:
PopIndent();
AddIndentation();
first = false;
buff << "}\n";
buff << "}" << newline;
}
void StartArray(bool is_element = false) {
@ -135,19 +140,19 @@ public:
}
}
first = true;
buff << "[\n";
buff << "[" << newline;
PushIndent();
}
void EndArray() {
PopIndent();
AddIndentation();
buff << "]\n";
buff << "]" << newline;
first = false;
}
void AddIndentation() {
if (!(flags & Flag_DoNotIndent)) {
if (!(flags & Flag_DoNotIndent) && !(flags & Flag_SkipWhitespaces)) {
buff << indent;
}
}
@ -156,7 +161,7 @@ public:
if (!first) {
buff << ',';
} else {
buff << ' ';
buff << space;
first = false;
}
}
@ -227,7 +232,9 @@ private:
private:
Assimp::IOStream &out;
std::string indent, newline;
std::string indent;
std::string newline;
std::string space;
std::stringstream buff;
bool first;
@ -765,7 +772,7 @@ void Write(JSONWriter &out, const aiScene &ai) {
out.EndObj();
}
void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *scene, const Assimp::ExportProperties *) {
void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *scene, const Assimp::ExportProperties *pProperties) {
std::unique_ptr<Assimp::IOStream> str(io->Open(file, "wt"));
if (!str) {
throw DeadlyExportError("could not open output file");
@ -782,7 +789,12 @@ void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *sc
splitter.Execute(scenecopy_tmp);
// XXX Flag_WriteSpecialFloats is turned on by default, right now we don't have a configuration interface for exporters
JSONWriter s(*str, JSONWriter::Flag_WriteSpecialFloats);
unsigned int flags = JSONWriter::Flag_WriteSpecialFloats;
if (pProperties->GetPropertyBool("JSON_SKIP_WHITESPACES", false)) {
flags |= JSONWriter::Flag_SkipWhitespaces;
}
JSONWriter s(*str, flags);
Write(s, *scenecopy_tmp);
} catch (...) {

View File

@ -69,13 +69,12 @@ void MeshSplitter::UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh
for (unsigned int i = 0, end = pcNode->mNumChildren; i < end;++i) {
UpdateNode ( pcNode->mChildren[i], source_mesh_map );
}
return;
}
#define WAS_NOT_COPIED 0xffffffff
static const unsigned int WAS_NOT_COPIED = 0xffffffff;
typedef std::pair <unsigned int,float> PerVertexWeight;
typedef std::vector <PerVertexWeight> VertexWeightTable;
using PerVertexWeight = std::pair <unsigned int,float>;
using VertexWeightTable = std::vector <PerVertexWeight>;
// ------------------------------------------------------------------------------------------------
VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh) {
@ -89,7 +88,7 @@ VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh) {
aiBone* bone = pMesh->mBones[i];
for (unsigned int a = 0; a < bone->mNumWeights;++a) {
const aiVertexWeight& weight = bone->mWeights[a];
avPerVertexWeights[weight.mVertexId].push_back( std::make_pair(i,weight.mWeight) );
avPerVertexWeights[weight.mVertexId].emplace_back(i,weight.mWeight);
}
}
return avPerVertexWeights;
@ -100,7 +99,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
// TODO: should better use std::(multi)set for source_mesh_map.
if (in_mesh->mNumVertices <= LIMIT) {
source_mesh_map.push_back(std::make_pair(in_mesh,a));
source_mesh_map.emplace_back(in_mesh,a);
return;
}
@ -110,7 +109,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
// we need to split this mesh into sub meshes. Estimate submesh size
const unsigned int sub_meshes = (in_mesh->mNumVertices / LIMIT) + 1;
// create a std::vector<unsigned int> to remember which vertices have already
// create a std::vector<unsigned int> to remember which vertices have already
// been copied and to which position (i.e. output index)
std::vector<unsigned int> was_copied_to;
was_copied_to.resize(in_mesh->mNumVertices,WAS_NOT_COPIED);
@ -125,7 +124,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
while (true) {
const unsigned int out_vertex_index = LIMIT;
aiMesh* out_mesh = new aiMesh();
aiMesh* out_mesh = new aiMesh();
out_mesh->mNumVertices = 0;
out_mesh->mMaterialIndex = in_mesh->mMaterialIndex;
@ -179,7 +178,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
// check whether we do already have this vertex
if (WAS_NOT_COPIED == was_copied_to[index]) {
iNeed++;
iNeed++;
}
}
if (out_mesh->mNumVertices + iNeed > out_vertex_index) {
@ -187,7 +186,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
break;
}
vFaces.push_back(aiFace());
vFaces.emplace_back();
aiFace& rFace = vFaces.back();
// setup face type and number of indices
@ -240,7 +239,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
out_mesh->mTextureCoords[c][out_mesh->mNumVertices] = in_mesh->mTextureCoords[c][index];
}
}
// vertex colors
// vertex colors
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
if (in_mesh->HasVertexColors( c)) {
out_mesh->mColors[c][out_mesh->mNumVertices] = in_mesh->mColors[c][index];

View File

@ -22,40 +22,31 @@ struct aiNode;
// ---------------------------------------------------------------------------
/** Splits meshes of unique vertices into meshes with no more vertices than
* a given, configurable threshold value.
* a given, configurable threshold value.
*/
class MeshSplitter
{
class MeshSplitter {
public:
void SetLimit(unsigned int l) {
LIMIT = l;
}
unsigned int LIMIT;
unsigned int GetLimit() const {
return LIMIT;
}
void SetLimit(unsigned int l) {
LIMIT = l;
}
public:
unsigned int GetLimit() const {
return LIMIT;
}
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
void Execute(aiScene *pScene);
private:
void UpdateNode(aiNode *pcNode, const std::vector<std::pair<aiMesh *, unsigned int>> &source_mesh_map);
void SplitMesh(unsigned int index, aiMesh *mesh, std::vector<std::pair<aiMesh *, unsigned int>> &source_mesh_map);
void UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh*, unsigned int> >& source_mesh_map);
void SplitMesh (unsigned int index, aiMesh* mesh, std::vector<std::pair<aiMesh*, unsigned int> >& source_mesh_map);
public:
unsigned int LIMIT;
};
#endif // INCLUDED_MESH_SPLITTER

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp>
#include <assimp/Exporter.hpp>
namespace Assimp {
namespace Assimp {
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
{

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file AssxmlExporter.h
* ASSXML Exporter Main Header
*/
#pragma once
#ifndef AI_ASSXMLEXPORTER_H_INC
#define AI_ASSXMLEXPORTER_H_INC

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -168,7 +168,7 @@ static void WriteNode(const aiNode *node, IOStream *io, unsigned int depth) {
}
// -----------------------------------------------------------------------------------
// Some chuncks of text will need to be encoded for XML
// Some chunks of text will need to be encoded for XML
// http://stackoverflow.com/questions/5665231/most-efficient-way-to-escape-xml-html-in-c-string#5665377
static std::string encodeXML(const std::string &data) {
std::string buffer;
@ -601,7 +601,7 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
ioprintf(io, "\t\t<TextureCoords num=\"%u\" set=\"%u\" name=\"%s\" num_components=\"%u\"> \n",
mesh->mNumVertices,
a,
mesh->mTextureCoordsNames[a].C_Str(),
(mesh->HasTextureCoordsName(a) ? mesh->GetTextureCoordsName(a)->C_Str() : ""),
mesh->mNumUVComponents[a]);
if (!shortened) {

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -43,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file AssxmlFileWriter.h
* @brief Declaration of Assxml file writer.
*/
#pragma once
#ifndef AI_ASSXMLFILEWRITER_H_INC
#define AI_ASSXMLFILEWRITER_H_INC

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -81,7 +81,7 @@ static const aiImporterDesc desc = {
//#define DEBUG_B3D
template <typename T>
template<typename T>
void DeleteAllBarePointers(std::vector<T> &x) {
for (auto p : x) {
delete p;
@ -89,11 +89,11 @@ void DeleteAllBarePointers(std::vector<T> &x) {
}
B3DImporter::~B3DImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
bool B3DImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
size_t pos = pFile.find_last_of('.');
if (pos == string::npos) {
return false;
@ -143,7 +143,7 @@ AI_WONT_RETURN void B3DImporter::Oops() {
}
// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void B3DImporter::Fail(string str) {
AI_WONT_RETURN void B3DImporter::Fail(const string &str) {
#ifdef DEBUG_B3D
ASSIMP_LOG_ERROR("Error in B3D file data: ", str);
#endif

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -40,8 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Definition of the .b3d importer class. */
/**
* @file Definition of the .b3d importer class.
*/
#pragma once
#ifndef AI_B3DIMPORTER_H_INC
#define AI_B3DIMPORTER_H_INC
@ -62,14 +63,12 @@ namespace Assimp{
class B3DImporter : public BaseImporter{
public:
B3DImporter() = default;
virtual ~B3DImporter();
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
~B3DImporter() override;
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
protected:
virtual const aiImporterDesc* GetInfo () const;
virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
const aiImporterDesc* GetInfo () const override;
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
private:
@ -96,7 +95,7 @@ private:
};
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Fail(const std::string &str) AI_WONT_RETURN_SUFFIX;
void ReadTEXS();
void ReadBRUS();
@ -113,7 +112,6 @@ private:
void ReadBB3D( aiScene *scene );
size_t _pos;
// unsigned _size;
std::vector<unsigned char> _buf;
std::vector<size_t> _stack;

View File

@ -4,7 +4,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
@ -92,18 +92,9 @@ BVHLoader::~BVHLoader() {}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool BVHLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const {
// check file extension
const std::string extension = GetExtension(pFile);
if (extension == "bvh")
return true;
if ((!extension.length() || cs) && pIOHandler) {
const char *tokens[] = { "HIERARCHY" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
bool BVHLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
static const char *tokens[] = { "HIERARCHY" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}
// ------------------------------------------------------------------------------------------------
@ -178,7 +169,7 @@ void BVHLoader::ReadHierarchy(aiScene *pScene) {
}
// ------------------------------------------------------------------------------------------------
// Reads a node and recursively its childs and returns the created node;
// Reads a node and recursively its children and returns the created node;
aiNode *BVHLoader::ReadNode() {
// first token is name
std::string nodeName = GetNextToken();

View File

@ -4,7 +4,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -112,7 +112,7 @@ protected:
/** Reads the hierarchy */
void ReadHierarchy(aiScene *pScene);
/** Reads a node and recursively its childs and returns the created node. */
/** Reads a node and recursively its children and returns the created node. */
aiNode *ReadNode();
/** Reads an end node and returns the created node. */

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -476,7 +476,7 @@ public:
* in BlenderScene.cpp and is machine-generated.
* Converters are used to quickly handle objects whose
* exact data type is a runtime-property and not yet
* known at compile time (consier Object::data).*/
* known at compile time (consider Object::data).*/
void RegisterConverters();
// --------------------------------------------------------

View File

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

View File

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

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -66,11 +66,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// zlib is needed for compressed blend files
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
#include "Common/Compression.h"
/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
# else
# include "../contrib/zlib/zlib.h"
# endif
# endif*/
#endif
namespace Assimp {
@ -113,23 +114,15 @@ BlenderImporter::~BlenderImporter() {
delete modifier_cache;
}
static const char *Tokens[] = { "BLENDER" };
static const char *TokensForSearch[] = { "blender" };
static const char * const Tokens[] = { "BLENDER" };
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string &extension = GetExtension(pFile);
if (extension == "blend") {
return true;
}
bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
// note: this won't catch compressed files
static const char *tokens[] = { "<BLENDER", "blender" };
if ((!extension.length() || checkSig) && pIOHandler) {
// note: this won't catch compressed files
return SearchFileHeaderForToken(pIOHandler, pFile, TokensForSearch, 1);
}
return false;
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}
// ------------------------------------------------------------------------------------------------
@ -149,7 +142,7 @@ void BlenderImporter::SetupProperties(const Importer * /*pImp*/) {
void BlenderImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
std::vector<Bytef> uncompressed;
std::vector<char> uncompressed;
#endif
FileDatabase file;
@ -167,7 +160,6 @@ void BlenderImporter::InternReadFile(const std::string &pFile,
#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");
}
@ -181,42 +173,12 @@ void BlenderImporter::InternReadFile(const std::string &pFile,
stream->Seek(0L, aiOrigin_SET);
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
// build a zlib stream
z_stream zstream;
zstream.opaque = Z_NULL;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.data_type = Z_BINARY;
// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
inflateInit2(&zstream, 16 + MAX_WBITS);
zstream.next_in = reinterpret_cast<Bytef *>(reader->GetPtr());
zstream.avail_in = (uInt)reader->GetRemainingSize();
size_t total = 0l;
// TODO: be smarter about this, decompress directly into heap buffer
// and decompress the data .... do 1k chunks in the hope that we won't kill the stack
#define MYBLOCK 1024
Bytef block[MYBLOCK];
int ret;
do {
zstream.avail_out = MYBLOCK;
zstream.next_out = block;
ret = inflate(&zstream, Z_NO_FLUSH);
if (ret != Z_STREAM_END && ret != Z_OK) {
ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .BLEND file");
}
const size_t have = MYBLOCK - zstream.avail_out;
total += have;
uncompressed.resize(total);
memcpy(uncompressed.data() + total - have, block, have);
} while (ret != Z_STREAM_END);
// terminate zlib
inflateEnd(&zstream);
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.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total));
@ -318,42 +280,81 @@ void BlenderImporter::ExtractScene(Scene &out, const FileDatabase &file) {
#endif
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ParseSubCollection(const Blender::Scene &in, aiNode *root, std::shared_ptr<Collection> collection, ConversionData &conv_data) {
std::deque<Object *> root_objects;
// Count number of objects
for (std::shared_ptr<CollectionObject> cur = std::static_pointer_cast<CollectionObject>(collection->gobject.first); cur; cur = cur->next) {
if (cur->ob) {
root_objects.push_back(cur->ob);
}
}
std::deque<Collection *> root_children;
// Count number of child nodes
for (std::shared_ptr<CollectionChild> cur = std::static_pointer_cast<CollectionChild>(collection->children.first); cur; cur = cur->next) {
if (cur->collection) {
root_children.push_back(cur->collection.get());
}
}
root->mNumChildren = static_cast<unsigned int>(root_objects.size() + root_children.size());
root->mChildren = new aiNode *[root->mNumChildren]();
for (unsigned int i = 0; i < static_cast<unsigned int>(root_objects.size()); ++i) {
root->mChildren[i] = ConvertNode(in, root_objects[i], conv_data, aiMatrix4x4());
root->mChildren[i]->mParent = root;
}
// For each subcollection create a new node to represent it
unsigned int iterator = static_cast<unsigned int>(root_objects.size());
for (std::shared_ptr<CollectionChild> cur = std::static_pointer_cast<CollectionChild>(collection->children.first); cur; cur = cur->next) {
if (cur->collection) {
root->mChildren[iterator] = new aiNode(cur->collection->id.name + 2); // skip over the name prefix 'OB'
root->mChildren[iterator]->mParent = root;
ParseSubCollection(in, root->mChildren[iterator], cur->collection, conv_data);
}
iterator += 1;
}
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ConvertBlendFile(aiScene *out, const Scene &in, const FileDatabase &file) {
ConversionData conv(file);
// FIXME it must be possible to take the hierarchy directly from
// the file. This is terrible. Here, we're first looking for
// all objects which don't have parent objects at all -
std::deque<const Object *> no_parents;
for (std::shared_ptr<Base> cur = std::static_pointer_cast<Base>(in.base.first); cur; cur = cur->next) {
if (cur->object) {
if (!cur->object->parent) {
no_parents.push_back(cur->object.get());
} else {
conv.objects.insert(cur->object.get());
}
}
}
for (std::shared_ptr<Base> cur = in.basact; cur; cur = cur->next) {
if (cur->object) {
if (cur->object->parent) {
conv.objects.insert(cur->object.get());
}
}
}
if (no_parents.empty()) {
ThrowException("Expected at least one object with no parent");
}
aiNode *root = out->mRootNode = new aiNode("<BlenderRoot>");
// Iterate over all objects directly under master_collection,
// If in.master_collection == null, then we're parsing something older.
if (in.master_collection) {
ParseSubCollection(in, root, in.master_collection, conv);
} else {
std::deque<const Object *> no_parents;
for (std::shared_ptr<Base> cur = std::static_pointer_cast<Base>(in.base.first); cur; cur = cur->next) {
if (cur->object) {
if (!cur->object->parent) {
no_parents.push_back(cur->object.get());
} else {
conv.objects.insert(cur->object.get());
}
}
}
for (std::shared_ptr<Base> cur = in.basact; cur; cur = cur->next) {
if (cur->object) {
if (cur->object->parent) {
conv.objects.insert(cur->object.get());
}
}
}
root->mNumChildren = static_cast<unsigned int>(no_parents.size());
root->mChildren = new aiNode *[root->mNumChildren]();
for (unsigned int i = 0; i < root->mNumChildren; ++i) {
root->mChildren[i] = ConvertNode(in, no_parents[i], conv, aiMatrix4x4());
root->mChildren[i]->mParent = root;
if (no_parents.empty()) {
ThrowException("Expected at least one object with no parent");
}
root->mNumChildren = static_cast<unsigned int>(no_parents.size());
root->mChildren = new aiNode *[root->mNumChildren]();
for (unsigned int i = 0; i < root->mNumChildren; ++i) {
root->mChildren[i] = ConvertNode(in, no_parents[i], conv, aiMatrix4x4());
root->mChildren[i]->mParent = root;
}
}
BuildMaterials(conv);
@ -679,7 +680,7 @@ void BlenderImporter::BuildMaterials(ConversionData &conv_data) {
BuildDefaultMaterial(conv_data);
for (std::shared_ptr<Material> mat : conv_data.materials_raw) {
for (const std::shared_ptr<Material> &mat : conv_data.materials_raw) {
// reset per material global counters
for (size_t i = 0; i < sizeof(conv_data.next_texture) / sizeof(conv_data.next_texture[0]); ++i) {

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -43,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file BlenderLoader.h
* @brief Declaration of the Blender 3D (*.blend) importer class.
*/
#pragma once
#ifndef INCLUDED_AI_BLEND_LOADER_H
#define INCLUDED_AI_BLEND_LOADER_H
@ -56,149 +56,141 @@ struct aiLight;
struct aiCamera;
struct aiMaterial;
namespace Assimp {
namespace Assimp {
// TinyFormatter.h
namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter;
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
}
// TinyFormatter.h
namespace Formatter {
// BlenderDNA.h
namespace Blender {
class FileDatabase;
struct ElemBase;
}
template <typename T, typename TR, typename A>
class basic_formatter;
// BlenderScene.h
namespace Blender {
struct Scene;
struct Object;
struct Mesh;
struct Camera;
struct Lamp;
struct MTex;
struct Image;
struct Material;
}
typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>> format;
// BlenderIntermediate.h
namespace Blender {
struct ConversionData;
template <template <typename,typename> class TCLASS, typename T> struct TempArray;
}
} // namespace Formatter
// BlenderModifier.h
namespace Blender {
class BlenderModifierShowcase;
class BlenderModifier;
}
// BlenderDNA.h
namespace Blender {
class FileDatabase;
struct ElemBase;
} // namespace Blender
// BlenderScene.h
namespace Blender {
struct Scene;
struct Object;
struct Collection;
struct Mesh;
struct Camera;
struct Lamp;
struct MTex;
struct Image;
struct Material;
} // namespace Blender
// BlenderIntermediate.h
namespace Blender {
struct ConversionData;
template <template <typename, typename> class TCLASS, typename T>
struct TempArray;
} // namespace Blender
// BlenderModifier.h
namespace Blender {
class BlenderModifierShowcase;
class BlenderModifier;
} // namespace Blender
// -------------------------------------------------------------------------------------------
/** Load blenders official binary format. The actual file structure (the `DNA` how they
* call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
* conversion from intermediate format to aiScene. */
// -------------------------------------------------------------------------------------------
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
{
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter> {
public:
BlenderImporter();
~BlenderImporter();
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
~BlenderImporter() override;
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
protected:
const aiImporterDesc* GetInfo () const;
void SetupProperties(const Importer* pImp);
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
void ParseBlendFile(Blender::FileDatabase& out, std::shared_ptr<IOStream> stream);
void ExtractScene(Blender::Scene& out, const Blender::FileDatabase& file);
void ConvertBlendFile(aiScene* out, const Blender::Scene& in, const Blender::FileDatabase& file);
const aiImporterDesc *GetInfo() const override;
void SetupProperties(const Importer *pImp) override;
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
void ParseBlendFile(Blender::FileDatabase &out, std::shared_ptr<IOStream> stream);
void ExtractScene(Blender::Scene &out, const Blender::FileDatabase &file);
void ParseSubCollection(const Blender::Scene &in, aiNode *root, std::shared_ptr<Blender::Collection> collection, Blender::ConversionData &conv_data);
void ConvertBlendFile(aiScene *out, const Blender::Scene &in, const Blender::FileDatabase &file);
private:
aiNode* ConvertNode(const Blender::Scene& in,
const Blender::Object* obj,
Blender::ConversionData& conv_info,
const aiMatrix4x4& parentTransform
);
aiNode *ConvertNode(const Blender::Scene &in,
const Blender::Object *obj,
Blender::ConversionData &conv_info,
const aiMatrix4x4 &parentTransform);
// --------------------
void ConvertMesh(const Blender::Scene& in,
const Blender::Object* obj,
const Blender::Mesh* mesh,
Blender::ConversionData& conv_data,
Blender::TempArray<std::vector,aiMesh>& temp
);
void ConvertMesh(const Blender::Scene &in,
const Blender::Object *obj,
const Blender::Mesh *mesh,
Blender::ConversionData &conv_data,
Blender::TempArray<std::vector, aiMesh> &temp);
// --------------------
aiLight* ConvertLight(const Blender::Scene& in,
const Blender::Object* obj,
const Blender::Lamp* mesh,
Blender::ConversionData& conv_data
);
aiLight *ConvertLight(const Blender::Scene &in,
const Blender::Object *obj,
const Blender::Lamp *mesh,
Blender::ConversionData &conv_data);
// --------------------
aiCamera* ConvertCamera(const Blender::Scene& in,
const Blender::Object* obj,
const Blender::Camera* mesh,
Blender::ConversionData& conv_data
);
aiCamera *ConvertCamera(const Blender::Scene &in,
const Blender::Object *obj,
const Blender::Camera *mesh,
Blender::ConversionData &conv_data);
// --------------------
void BuildDefaultMaterial(
Blender::ConversionData& conv_data
);
Blender::ConversionData &conv_data);
// --------------------
void AddBlendParams(
aiMaterial* result,
const Blender::Material* source
);
aiMaterial *result,
const Blender::Material *source);
// --------------------
void BuildMaterials(
Blender::ConversionData& conv_data
);
Blender::ConversionData &conv_data);
// --------------------
void ResolveTexture(
aiMaterial* out,
const Blender::Material* mat,
const Blender::MTex* tex,
Blender::ConversionData& conv_data
);
aiMaterial *out,
const Blender::Material *mat,
const Blender::MTex *tex,
Blender::ConversionData &conv_data);
// --------------------
void ResolveImage(
aiMaterial* out,
const Blender::Material* mat,
const Blender::MTex* tex,
const Blender::Image* img,
Blender::ConversionData& conv_data
);
aiMaterial *out,
const Blender::Material *mat,
const Blender::MTex *tex,
const Blender::Image *img,
Blender::ConversionData &conv_data);
// --------------------
void AddSentinelTexture(
aiMaterial* out,
const Blender::Material* mat,
const Blender::MTex* tex,
Blender::ConversionData& conv_data
);
aiMaterial *out,
const Blender::Material *mat,
const Blender::MTex *tex,
Blender::ConversionData &conv_data);
private: // static stuff, mostly logging and error reporting.
// --------------------
static void CheckActualType(const Blender::ElemBase *dt,
const char *check);
// --------------------
static void CheckActualType(const Blender::ElemBase* dt,
const char* check
);
// --------------------
static void NotSupportedObjectType(const Blender::Object* obj,
const char* type
);
static void NotSupportedObjectType(const Blender::Object *obj,
const char *type);
private:
Blender::BlenderModifierShowcase* modifier_cache;
Blender::BlenderModifierShowcase *modifier_cache;
}; // !class BlenderImporter

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -52,9 +52,9 @@ namespace Assimp {
namespace Blender {
// -------------------------------------------------------------------------------------------
/**
/**
* Dummy base class for all blender modifiers. Modifiers are reused between imports, so
* they should be stateless and not try to cache model data.
* they should be stateless and not try to cache model data.
*/
// -------------------------------------------------------------------------------------------
class BlenderModifier {
@ -67,7 +67,7 @@ public:
}
// --------------------
/**
/**
* Check if *this* modifier is active, given a ModifierData& block.
*/
virtual bool IsActive( const ModifierData& /*modin*/) {
@ -75,10 +75,10 @@ public:
}
// --------------------
/**
/**
* Apply the modifier to a given output node. The original data used
* to construct the node is given as well. Not called unless IsActive()
* was called and gave positive response.
* was called and gave positive response.
*/
virtual void DoIt(aiNode& /*out*/,
ConversionData& /*conv_data*/,
@ -92,8 +92,8 @@ public:
};
// -------------------------------------------------------------------------------------------
/**
* Manage all known modifiers and instance and apply them if necessary
/**
* Manage all known modifiers and instance and apply them if necessary
*/
// -------------------------------------------------------------------------------------------
class BlenderModifierShowcase {
@ -113,8 +113,8 @@ private:
// MODIFIERS /////////////////////////////////////////////////////////////////////////////////
// -------------------------------------------------------------------------------------------
/**
* Mirror modifier. Status: implemented.
/**
* Mirror modifier. Status: implemented.
*/
// -------------------------------------------------------------------------------------------
class BlenderModifier_Mirror : public BlenderModifier {

View File

@ -49,8 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BlenderDNA.h"
#include "BlenderSceneGen.h"
using namespace Assimp;
using namespace Assimp::Blender;
namespace Assimp {
namespace Blender {
//--------------------------------------------------------------------------------
template <>
@ -94,6 +94,52 @@ void Structure ::Convert<Group>(
db.reader->IncPtr(size);
}
//--------------------------------------------------------------------------------
template <>
void Structure::Convert<CollectionObject>(
CollectionObject &dest,
const FileDatabase &db) const {
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;
ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db);
dest.ob = ob.get();
}
db.reader->IncPtr(size);
}
//--------------------------------------------------------------------------------
template <>
void Structure::Convert<CollectionChild>(
CollectionChild &dest,
const FileDatabase &db) const {
ReadFieldPtr<ErrorPolicy_Fail>(dest.prev, "*prev", db);
ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db);
ReadFieldPtr<ErrorPolicy_Igno>(dest.collection, "*collection", db);
db.reader->IncPtr(size);
}
//--------------------------------------------------------------------------------
template <>
void Structure::Convert<Collection>(
Collection &dest,
const FileDatabase &db) const {
ReadField<ErrorPolicy_Fail>(dest.id, "id", db);
ReadField<ErrorPolicy_Fail>(dest.gobject, "gobject", db);
ReadField<ErrorPolicy_Fail>(dest.children, "children", db);
db.reader->IncPtr(size);
}
//--------------------------------------------------------------------------------
template <>
void Structure ::Convert<MTex>(
@ -660,6 +706,7 @@ void Structure ::Convert<Scene>(
ReadFieldPtr<ErrorPolicy_Warn>(dest.camera, "*camera", db);
ReadFieldPtr<ErrorPolicy_Warn>(dest.world, "*world", db);
ReadFieldPtr<ErrorPolicy_Warn>(dest.basact, "*basact", db);
ReadFieldPtr<ErrorPolicy_Warn>(dest.master_collection, "*master_collection", db);
ReadField<ErrorPolicy_Igno>(dest.base, "base", db);
db.reader->IncPtr(size);
@ -833,6 +880,12 @@ void DNA::RegisterConverters() {
converters["Image"] = DNA::FactoryPair(&Structure::Allocate<Image>, &Structure::Convert<Image>);
converters["CustomData"] = DNA::FactoryPair(&Structure::Allocate<CustomData>, &Structure::Convert<CustomData>);
converters["CustomDataLayer"] = DNA::FactoryPair(&Structure::Allocate<CustomDataLayer>, &Structure::Convert<CustomDataLayer>);
converters["Collection"] = DNA::FactoryPair(&Structure::Allocate<Collection>, &Structure::Convert<Collection>);
converters["CollectionChild"] = DNA::FactoryPair(&Structure::Allocate<CollectionChild>, &Structure::Convert<CollectionChild>);
converters["CollectionObject"] = DNA::FactoryPair(&Structure::Allocate<CollectionObject>, &Structure::Convert<CollectionObject>);
}
} // namespace Blender
} //namespace Assimp
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -107,6 +107,7 @@ namespace Blender {
struct Object;
struct MTex;
struct Image;
struct Collection;
#include <memory>
@ -147,6 +148,26 @@ struct Group : ElemBase {
std::shared_ptr<GroupObject> gobject;
};
// -------------------------------------------------------------------------------
struct CollectionObject : ElemBase {
//CollectionObject* prev;
std::shared_ptr<CollectionObject> next;
Object *ob;
};
// -------------------------------------------------------------------------------
struct CollectionChild : ElemBase {
std::shared_ptr<CollectionChild> next, prev;
std::shared_ptr<Collection> collection;
};
// -------------------------------------------------------------------------------
struct Collection : ElemBase {
ID id FAIL;
ListBase gobject; // CollectionObject
ListBase children; // CollectionChild
};
// -------------------------------------------------------------------------------
struct World : ElemBase {
ID id FAIL;
@ -729,11 +750,12 @@ struct Scene : ElemBase {
std::shared_ptr<Object> camera WARN;
std::shared_ptr<World> world WARN;
std::shared_ptr<Base> basact WARN;
std::shared_ptr<Collection> master_collection WARN;
ListBase base;
Scene() :
ElemBase(), camera(), world(), basact() {
ElemBase(), camera(), world(), basact(), master_collection() {
// empty
}
};

View File

@ -62,6 +62,12 @@ template <> void Structure :: Convert<Group> (
) const
;
template <> void Structure::Convert<Collection>(
Collection& dest,
const FileDatabase& db
) const
;
template <> void Structure :: Convert<MTex> (
MTex& dest,
const FileDatabase& db

View File

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

View File

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

View File

@ -106,14 +106,25 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
C4DImporter::C4DImporter()
: BaseImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
C4DImporter::~C4DImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const {
const std::string& extension = GetExtension(pFile);
if (extension == "c4d") {
return true;
} else if ((!extension.length() || checkSig) && pIOHandler) {
// TODO
}
return false;
}
@ -146,8 +157,14 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
ThrowException("failed to read document " + pFile);
}
// Generate the root-node
pScene->mRootNode = new aiNode("<C4DRoot>");
// convert left-handed to right-handed
pScene->mRootNode->mTransformation.a1 = 0.01f;
pScene->mRootNode->mTransformation.b2 = 0.01f;
pScene->mRootNode->mTransformation.c3 = -0.01f;
// first convert all materials
ReadMaterials(doc->GetFirstMaterial());

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -103,17 +103,9 @@ COBImporter::~COBImporter() {
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string &extension = GetExtension(pFile);
if (extension == "cob" || extension == "scn" || extension == "COB" || extension == "SCN") {
return true;
}
else if ((!extension.length() || checkSig) && pIOHandler) {
const char *tokens[] = { "Caligary" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
static const char *tokens[] = { "Caligary" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}
// ------------------------------------------------------------------------------------------------
@ -230,7 +222,7 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
// ------------------------------------------------------------------------------------------------
void ConvertTexture(std::shared_ptr<Texture> tex, aiMaterial *out, aiTextureType type) {
void ConvertTexture(const std::shared_ptr<Texture> &tex, aiMaterial *out, aiTextureType type) {
const aiString path(tex->path);
out->AddProperty(&path, AI_MATKEY_TEXTURE(type, 0));
out->AddProperty(&tex->transform, 1, AI_MATKEY_UVTRANSFORM(type, 0));
@ -586,7 +578,7 @@ void COBImporter::ReadUnit_Ascii(Scene &out, LineSplitter &splitter, const Chunk
return;
}
// parent chunks preceede their childs, so we should have the
// parent chunks preceede their children, so we should have the
// corresponding chunk already.
for (std::shared_ptr<Node> &nd : out.nodes) {
if (nd->id == nfo.parent_id) {
@ -668,7 +660,7 @@ void COBImporter::ReadCame_Ascii(Scene &out, LineSplitter &splitter, const Chunk
ReadBasicNodeInfo_Ascii(msh, ++splitter, nfo);
// skip the next line, we don't know this differenciation between a
// skip the next line, we don't know this differentiation between a
// standard camera and a panoramic camera.
++splitter;
}
@ -884,7 +876,7 @@ void COBImporter::ReadBinaryFile(Scene &out, StreamReaderLE *reader) {
std::string type;
type += reader->GetI1();
type += reader->GetI1();
type += reader->GetI1();
type += reader->GetI1();
type += reader->GetI1();
ChunkInfo nfo;
@ -1169,7 +1161,7 @@ void COBImporter::ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const
const chunk_guard cn(nfo, reader);
// parent chunks preceede their childs, so we should have the
// parent chunks preceede their children, so we should have the
// corresponding chunk already.
for (std::shared_ptr<Node> &nd : out.nodes) {
if (nd->id == nfo.parent_id) {

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -51,104 +51,100 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct aiNode;
namespace Assimp {
class LineSplitter;
namespace Assimp {
class LineSplitter;
// TinyFormatter.h
namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter;
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
}
// TinyFormatter.h
namespace Formatter {
template <typename T, typename TR, typename A>
class basic_formatter;
typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>> format;
} // namespace Formatter
// COBScene.h
namespace COB {
struct ChunkInfo;
struct Node;
struct Scene;
}
// COBScene.h
namespace COB {
struct ChunkInfo;
struct Node;
struct Scene;
} // namespace COB
// -------------------------------------------------------------------------------------------
/** Importer class to load TrueSpace files (cob,scn) up to v6.
*
* Currently relatively limited, loads only ASCII files and needs more test coverage. */
// -------------------------------------------------------------------------------------------
class COBImporter : public BaseImporter
{
class COBImporter : public BaseImporter {
public:
COBImporter();
~COBImporter();
~COBImporter() override;
// --------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const override;
protected:
// --------------------
const aiImporterDesc *GetInfo() const override;
// --------------------
const aiImporterDesc* GetInfo () const;
void SetupProperties(const Importer *pImp) override;
// --------------------
void SetupProperties(const Importer* pImp);
// --------------------
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler) override;
private:
// -------------------------------------------------------------------
/** Prepend 'COB: ' and throw msg.*/
AI_WONT_RETURN static void ThrowException(const std::string& msg) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN static void ThrowException(const std::string &msg) AI_WONT_RETURN_SUFFIX;
// -------------------------------------------------------------------
/** @brief Read from an ascii scene/object file
* @param out Receives output data.
* @param stream Stream to read from. */
void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream);
void ReadAsciiFile(COB::Scene &out, StreamReaderLE *stream);
// -------------------------------------------------------------------
/** @brief Read from a binary scene/object file
* @param out Receives output data.
* @param stream Stream to read from. */
void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
void ReadBinaryFile(COB::Scene &out, StreamReaderLE *stream);
// Conversion to Assimp output format
aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
aiNode *BuildNodes(const COB::Node &root, const COB::Scene &scin, aiScene *fill);
private:
// ASCII file support
void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter);
void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo);
template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
void ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadMat1_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadGrou_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadBone_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadCame_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadLght_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void UnsupportedChunk_Ascii(LineSplitter &splitter, const COB::ChunkInfo &nfo, const char *name);
void ReadChunkInfo_Ascii(COB::ChunkInfo &out, const LineSplitter &splitter);
void ReadBasicNodeInfo_Ascii(COB::Node &msh, LineSplitter &splitter, const COB::ChunkInfo &nfo);
template <typename T>
void ReadFloat3Tuple_Ascii(T &fill, const char **in);
void ReadPolH_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadBitM_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadMat1_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadGrou_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadBone_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadCame_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadLght_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadUnit_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadChan_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
// Binary file support
void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);
void ReadString_Binary(std::string& out, StreamReaderLE& reader);
void ReadBasicNodeInfo_Binary(COB::Node& msh, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadBitM_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void UnsupportedChunk_Binary(StreamReaderLE &reader, const COB::ChunkInfo &nfo, const char *name);
void ReadString_Binary(std::string &out, StreamReaderLE &reader);
void ReadBasicNodeInfo_Binary(COB::Node &msh, StreamReaderLE &reader, const COB::ChunkInfo &nfo);
void ReadPolH_Binary(COB::Scene &out, StreamReaderLE &reader, const COB::ChunkInfo &nfo);
void ReadBitM_Binary(COB::Scene &out, StreamReaderLE &reader, const COB::ChunkInfo &nfo);
void ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const COB::ChunkInfo &nfo);
void ReadCame_Binary(COB::Scene &out, StreamReaderLE &reader, const COB::ChunkInfo &nfo);
void ReadLght_Binary(COB::Scene &out, StreamReaderLE &reader, const COB::ChunkInfo &nfo);
void ReadGrou_Binary(COB::Scene &out, StreamReaderLE &reader, const COB::ChunkInfo &nfo);
void ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const COB::ChunkInfo &nfo);
}; // !class COBImporter

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -43,16 +42,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file COBScene.h
* @brief Utilities for the COB importer.
*/
#pragma once
#ifndef INCLUDED_AI_COB_SCENE_H
#define INCLUDED_AI_COB_SCENE_H
#include <memory>
#include <deque>
#include <map>
#include <assimp/BaseImporter.h>
#include <assimp/material.h>
#include <deque>
#include <map>
namespace Assimp {
namespace COB {

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
@ -90,19 +90,10 @@ CSMImporter::~CSMImporter()
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
{
// check file extension
const std::string extension = GetExtension(pFile);
if( extension == "csm")
return true;
if ((checkSig || !extension.length()) && pIOHandler) {
const char* tokens[] = {"$Filename"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
}
return false;
static const char* tokens[] = {"$Filename"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
}
// ------------------------------------------------------------------------------------------------

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -48,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/BaseImporter.h>
namespace Assimp {
namespace Assimp {
// ---------------------------------------------------------------------------
/** Importer class to load MOCAPs in CharacterStudio Motion format.
@ -59,35 +58,32 @@ namespace Assimp {
* Link to file format specification:
* <max_8_dvd>\samples\Motion\Docs\CSM.rtf
*/
class CSMImporter : public BaseImporter
{
class CSMImporter : public BaseImporter {
public:
CSMImporter();
~CSMImporter();
~CSMImporter() override;
public:
// -------------------------------------------------------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
const aiImporterDesc *GetInfo() const override;
// -------------------------------------------------------------------
const aiImporterDesc* GetInfo () const;
void SetupProperties(const Importer *pImp) override;
// -------------------------------------------------------------------
void SetupProperties(const Importer* pImp);
// -------------------------------------------------------------------
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler) override;
private:
bool noSkeletonMesh;
}; // end of class CSMImporter
} // end of namespace Assimp
#endif // AI_AC3DIMPORTER_H_INC

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -47,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ColladaParser.h"
#include <assimp/ColladaMetaData.h>
#include <assimp/CreateAnimMesh.h>
#include <assimp/Defines.h>
#include <assimp/ParsingUtils.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/ZipArchiveIOSystem.h>
@ -117,36 +116,15 @@ ColladaLoader::~ColladaLoader() {
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
// check file extension
const std::string extension = GetExtension(pFile);
const bool readSig = checkSig && (pIOHandler != nullptr);
if (!readSig) {
if (extension == "dae" || extension == "zae") {
return true;
}
} else {
// Look for a DAE file inside, but don't extract it
ZipArchiveIOSystem zip_archive(pIOHandler, pFile);
if (zip_archive.isOpen()) {
return !ColladaParser::ReadZaeManifest(zip_archive).empty();
}
bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
// Look for a DAE file inside, but don't extract it
ZipArchiveIOSystem zip_archive(pIOHandler, pFile);
if (zip_archive.isOpen()) {
return !ColladaParser::ReadZaeManifest(zip_archive).empty();
}
// XML - too generic, we need to open the file and search for typical keywords
if (extension == "xml" || !extension.length() || checkSig) {
/* If CanRead() is called in order to check whether we
* support a specific file extension in general pIOHandler
* might be nullptr and it's our duty to return true here.
*/
if (!pIOHandler) {
return true;
}
static const char *tokens[] = { "<collada" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
static const char *tokens[] = { "<collada" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}
// ------------------------------------------------------------------------------------------------
@ -379,9 +357,9 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node
out->mAngleInnerCone = AI_DEG_TO_RAD(srcLight->mFalloffAngle);
// ... some extension magic.
if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - 1e-6f)) {
if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - ai_epsilon)) {
// ... some deprecation magic.
if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - 1e-6f)) {
if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - ai_epsilon)) {
// Need to rely on falloff_exponent. I don't know how to interpret it, so I need to guess ....
// epsilon chosen to be 0.1
float f = 1.0f;
@ -573,7 +551,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
// now place all mesh references we gathered in the target node
pTarget->mNumMeshes = static_cast<unsigned int>(newMeshRefs.size());
if (newMeshRefs.size()) {
if (!newMeshRefs.empty()) {
struct UIntTypeConverter {
unsigned int operator()(const size_t &v) const {
return static_cast<unsigned int>(v);
@ -619,6 +597,10 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
dstMesh->mName = pSrcMesh->mId;
}
if (pSrcMesh->mPositions.empty()) {
return dstMesh.release();
}
// count the vertices addressed by its faces
const size_t numVertices = std::accumulate(pSrcMesh->mFaceSize.begin() + pStartFace,
pSrcMesh->mFaceSize.begin() + pStartFace + pSubMesh.mNumFaces, size_t(0));
@ -1083,7 +1065,7 @@ void insertMorphTimeValue(std::vector<MorphTimeValues> &values, float time, floa
return;
}
for (unsigned int i = 0; i < values.size(); i++) {
if (std::abs(time - values[i].mTime) < 1e-6f) {
if (std::abs(time - values[i].mTime) < ai_epsilon) {
values[i].mKeys.push_back(k);
return;
} else if (time > values[i].mTime && time < values[i + 1].mTime) {
@ -1540,7 +1522,7 @@ void ColladaLoader::AddTexture(aiMaterial &mat,
map = -1;
for (std::string::const_iterator it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
if (IsNumeric(*it)) {
map = strtoul10(&(*it));
map = strtoul10(&(*it));
break;
}
}
@ -1671,7 +1653,7 @@ void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/)
const Material &material = matIt->second;
// a material is only a reference to an effect
ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find(material.mEffect);
if (effIt == pParser.mEffectLibrary.end())
if (effIt == pParser.mEffectLibrary.end())
continue;
Effect &effect = effIt->second;
@ -1682,7 +1664,7 @@ void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/)
// store the material
mMaterialIndexByName[matIt->first] = newMats.size();
newMats.push_back(std::pair<Effect *, aiMaterial *>(&effect, mat));
newMats.emplace_back(&effect, mat);
}
// ScenePreprocessor generates a default material automatically if none is there.
// All further code here in this loader works well without a valid material so

View File

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

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -170,10 +170,10 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
ColladaParser::~ColladaParser() {
for (auto & it : mNodeLibrary) {
for (auto &it : mNodeLibrary) {
delete it.second;
}
for (auto & it : mMeshLibrary) {
for (auto &it : mMeshLibrary) {
delete it.second;
}
}
@ -231,11 +231,7 @@ void ColladaParser::UriDecodePath(aiString &ss) {
// Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
// I need to filter it without destroying linux paths starting with "/somewhere"
#if defined(_MSC_VER)
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
#else
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
#endif
--ss.length;
::memmove(ss.data, ss.data + 1, ss.length);
ss.data[ss.length] = 0;
@ -335,7 +331,16 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
const std::string &currentName = currentNode.name();
if (currentName == "unit") {
mUnitSize = 1.f;
XmlParser::getRealAttribute(currentNode, "meter", mUnitSize);
std::string tUnitSizeString;
if (XmlParser::getStdStrAttribute(currentNode, "meter", tUnitSizeString)) {
try {
fast_atoreal_move<ai_real>(tUnitSizeString.data(), mUnitSize);
} catch (const DeadlyImportError& die) {
std::string warning("Collada: Failed to parse meter parameter to real number. Exception:\n");
warning.append(die.what());
ASSIMP_LOG_WARN(warning.data());
}
}
} else if (currentName == "up_axis") {
std::string v;
if (!XmlParser::getValueAsString(currentNode, v)) {
@ -396,7 +401,7 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
std::string animName;
if (!XmlParser::getStdStrAttribute(node, "name", animName)) {
if (!XmlParser::getStdStrAttribute( node, "id", animName )) {
if (!XmlParser::getStdStrAttribute(node, "id", animName)) {
animName = std::string("animation_") + ai_to_string(mAnimationClipLibrary.size());
}
}
@ -420,7 +425,7 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
void ColladaParser::PostProcessControllers() {
std::string meshId;
for (auto & it : mControllerLibrary) {
for (auto &it : mControllerLibrary) {
meshId = it.second.mMeshId;
if (meshId.empty()) {
continue;
@ -445,7 +450,7 @@ void ColladaParser::PostProcessRootAnimations() {
}
Animation temp;
for (auto & it : mAnimationClipLibrary) {
for (auto &it : mAnimationClipLibrary) {
std::string clipName = it.first;
Animation *clip = new Animation();
@ -453,7 +458,7 @@ void ColladaParser::PostProcessRootAnimations() {
temp.mSubAnims.push_back(clip);
for (std::string animationID : it.second) {
for (const std::string &animationID : it.second) {
AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
if (animation != mAnimationLibrary.end()) {
@ -529,7 +534,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
// have it read into a channel
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
ReadAnimationSampler(currentNode, newChannel->second);
}
}
} else if (currentName == "channel") {
std::string source_name, target;
XmlParser::getStdStrAttribute(currentNode, "source", source_name);
@ -552,7 +557,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
pParent->mSubAnims.push_back(anim);
}
for (const auto & channel : channels) {
for (const auto &channel : channels) {
anim->mChannels.push_back(channel.second);
}
@ -626,8 +631,6 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
//for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "morph") {
controller.mType = Morph;
@ -644,7 +647,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
} else if (currentName == "skin") {
std::string id;
if (XmlParser::getStdStrAttribute(currentNode, "source", id)) {
controller.mMeshId = id.substr(1, id.size()-1);
controller.mMeshId = id.substr(1, id.size() - 1);
}
} else if (currentName == "bind_shape_matrix") {
std::string v;
@ -698,7 +701,7 @@ void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pCo
} else if (strcmp(attrSemantic, "INV_BIND_MATRIX") == 0) {
pController.mJointOffsetMatrixSource = attrSource;
} else {
throw DeadlyImportError("Unknown semantic \"" , attrSemantic , "\" in <joints> data <input> element");
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <joints> data <input> element");
}
}
}
@ -708,7 +711,7 @@ void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pCo
// Reads the joint weights for the given controller
void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) {
// Read vertex count from attributes and resize the array accordingly
int vertexCount=0;
int vertexCount = 0;
XmlParser::getIntAttribute(node, "count", vertexCount);
pController.mWeightCounts.resize(vertexCount);
@ -723,7 +726,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
// local URLS always start with a '#'. We don't support global URLs
if (attrSource[0] != '#') {
throw DeadlyImportError( "Unsupported URL format in \"", attrSource, "\" in source attribute of <vertex_weights> data <input> element");
throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of <vertex_weights> data <input> element");
}
channel.mAccessor = attrSource + 1;
@ -777,7 +780,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) {
const std::string &currentName = currentNode.name();
if (currentName == "image") {
std::string id;
if (XmlParser::getStdStrAttribute( currentNode, "id", id )) {
if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
mImageLibrary[id] = Image();
// read on from there
ReadImage(currentNode, mImageLibrary[id]);
@ -907,7 +910,7 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) {
if (!name.empty()) {
cam.mName = name;
}
ReadCamera(currentNode, cam);
ReadCamera(currentNode, cam);
}
}
}
@ -920,7 +923,7 @@ void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
if (currentName == "instance_effect") {
std::string url;
readUrlAttribute(currentNode, url);
pMaterial.mEffect = url.c_str();
pMaterial.mEffect = url;
}
}
}
@ -930,6 +933,8 @@ void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
// TODO: Check the current technique and skip over unsupported extra techniques
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
if (currentName == "spot") {
@ -955,33 +960,34 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
SkipSpacesAndLineEnd(&content);
} else if (currentName == "constant_attenuation") {
XmlParser::getRealAttribute(currentNode, "constant_attenuation", pLight.mAttConstant);
XmlParser::getValueAsFloat(currentNode, pLight.mAttConstant);
} else if (currentName == "linear_attenuation") {
XmlParser::getRealAttribute(currentNode, "linear_attenuation", pLight.mAttLinear);
XmlParser::getValueAsFloat(currentNode, pLight.mAttLinear);
} else if (currentName == "quadratic_attenuation") {
XmlParser::getRealAttribute(currentNode, "quadratic_attenuation", pLight.mAttQuadratic);
XmlParser::getValueAsFloat(currentNode, pLight.mAttQuadratic);
} else if (currentName == "falloff_angle") {
XmlParser::getRealAttribute(currentNode, "falloff_angle", pLight.mFalloffAngle);
XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
} else if (currentName == "falloff_exponent") {
XmlParser::getRealAttribute(currentNode, "falloff_exponent", pLight.mFalloffExponent);
XmlParser::getValueAsFloat(currentNode, pLight.mFalloffExponent);
}
// FCOLLADA extensions
// -------------------------------------------------------
else if (currentName == "outer_cone") {
XmlParser::getRealAttribute(currentNode, "outer_cone", pLight.mOuterAngle);
} else if (currentName == "penumbra_angle") { // ... and this one is even deprecated
XmlParser::getRealAttribute(currentNode, "penumbra_angle", pLight.mPenumbraAngle);
XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
} else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone
XmlParser::getValueAsFloat(currentNode, pLight.mPenumbraAngle);
} else if (currentName == "intensity") {
XmlParser::getRealAttribute(currentNode, "intensity", pLight.mIntensity);
} else if (currentName == "falloff") {
XmlParser::getRealAttribute(currentNode, "falloff", pLight.mOuterAngle);
XmlParser::getValueAsFloat(currentNode, pLight.mIntensity);
}
else if (currentName == "falloff") {
XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
} else if (currentName == "hotspot_beam") {
XmlParser::getRealAttribute(currentNode, "hotspot_beam", pLight.mFalloffAngle);
XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
}
// OpenCOLLADA extensions
// -------------------------------------------------------
else if (currentName == "decay_falloff") {
XmlParser::getRealAttribute(currentNode, "decay_falloff", pLight.mOuterAngle);
XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
}
}
}
@ -1115,7 +1121,7 @@ void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEff
// GOOGLEEARTH/OKINO extensions
// -------------------------------------------------------
else if (currentName == "double_sided")
XmlParser::getBoolAttribute(currentNode, currentName.c_str(), pEffect.mDoubleSided);
XmlParser::getValueAsBool(currentNode, pEffect.mDoubleSided);
// FCOLLADA extensions
// -------------------------------------------------------
@ -1127,9 +1133,9 @@ void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEff
// MAX3D extensions
// -------------------------------------------------------
else if (currentName == "wireframe") {
XmlParser::getBoolAttribute(currentNode, currentName.c_str(), pEffect.mWireframe);
XmlParser::getValueAsBool(currentNode, pEffect.mWireframe);
} else if (currentName == "faceted") {
XmlParser::getBoolAttribute(currentNode, currentName.c_str(), pEffect.mFaceted);
XmlParser::getValueAsBool(currentNode, pEffect.mFaceted);
}
}
}
@ -1148,23 +1154,23 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
// MAYA extensions
// -------------------------------------------------------
if (currentName == "wrapU") {
XmlParser::getBoolAttribute(currentNode, currentName.c_str(), out.mWrapU);
XmlParser::getValueAsBool(currentNode, out.mWrapU);
} else if (currentName == "wrapV") {
XmlParser::getBoolAttribute(currentNode, currentName.c_str(), out.mWrapV);
XmlParser::getValueAsBool(currentNode, out.mWrapV);
} else if (currentName == "mirrorU") {
XmlParser::getBoolAttribute(currentNode, currentName.c_str(), out.mMirrorU);
XmlParser::getValueAsBool(currentNode, out.mMirrorU);
} else if (currentName == "mirrorV") {
XmlParser::getBoolAttribute(currentNode, currentName.c_str(), out.mMirrorV);
XmlParser::getValueAsBool(currentNode, out.mMirrorV);
} else if (currentName == "repeatU") {
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mTransform.mScaling.x);
XmlParser::getValueAsFloat(currentNode, out.mTransform.mScaling.x);
} else if (currentName == "repeatV") {
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mTransform.mScaling.y);
XmlParser::getValueAsFloat(currentNode, out.mTransform.mScaling.y);
} else if (currentName == "offsetU") {
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mTransform.mTranslation.x);
XmlParser::getValueAsFloat(currentNode, out.mTransform.mTranslation.x);
} else if (currentName == "offsetV") {
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mTransform.mTranslation.y);
XmlParser::getValueAsFloat(currentNode, out.mTransform.mTranslation.y);
} else if (currentName == "rotateUV") {
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mTransform.mRotation);
XmlParser::getValueAsFloat(currentNode, out.mTransform.mRotation);
} else if (currentName == "blend_mode") {
std::string v;
XmlParser::getValueAsString(currentNode, v);
@ -1184,14 +1190,14 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
// OKINO extensions
// -------------------------------------------------------
else if (currentName == "weighting") {
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mWeighting);
XmlParser::getValueAsFloat(currentNode, out.mWeighting);
} else if (currentName == "mix_with_previous_layer") {
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mMixWithPrevious);
XmlParser::getValueAsFloat(currentNode, out.mMixWithPrevious);
}
// MAX3D extensions
// -------------------------------------------------------
else if (currentName == "amount") {
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mWeighting);
XmlParser::getValueAsFloat(currentNode, out.mWeighting);
}
}
}
@ -1361,8 +1367,8 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
} else if (currentName == "vertices") {
ReadVertexData(currentNode, pMesh);
} else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" ||
currentName == "polygons" || currentName == "polylist" || currentName == "trifans" ||
currentName == "tristrips") {
currentName == "polygons" || currentName == "polylist" || currentName == "trifans" ||
currentName == "tristrips") {
ReadIndexData(currentNode, pMesh);
}
}
@ -1439,9 +1445,8 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
throw DeadlyImportError("Expected more values while reading float_array contents.");
}
ai_real value;
// read a number
//SkipSpacesAndLineEnd(&content);
ai_real value;
content = fast_atoreal_move<ai_real>(content, value);
data.mValues.push_back(value);
// skip whitespace after it
@ -1489,11 +1494,10 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
std::string name;
if (XmlParser::hasAttribute(currentNode, "name")) {
XmlParser::getStdStrAttribute(currentNode, "name", name);
//name = mReader->getAttributeValue(attrName);
// analyse for common type components and store it's sub-offset in the corresponding field
/* Cartesian coordinates */
// Cartesian coordinates
if (name == "X")
acc.mSubOffset[0] = acc.mParams.size();
else if (name == "Y")
@ -1674,12 +1678,9 @@ void ColladaParser::ReadInputChannel(XmlNode &node, std::vector<InputChannel> &p
// read set if texture coordinates
if (channel.mType == IT_Texcoord || channel.mType == IT_Color) {
int attrSet = -1;
if (XmlParser::hasAttribute(node, "set")) {
XmlParser::getIntAttribute(node, "set", attrSet);
}
channel.mIndex = attrSet;
unsigned int attrSet = 0;
if (XmlParser::getUIntAttribute(node, "set", attrSet))
channel.mIndex = attrSet;
}
// store, if valid type
@ -1704,20 +1705,20 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
// determine the expected number of indices
size_t expectedPointCount = 0;
switch (pPrimType) {
case Prim_Polylist: {
for (size_t i : pVCount)
expectedPointCount += i;
break;
}
case Prim_Lines:
expectedPointCount = 2 * pNumPrimitives;
break;
case Prim_Triangles:
expectedPointCount = 3 * pNumPrimitives;
break;
default:
// other primitive types don't state the index count upfront... we need to guess
break;
case Prim_Polylist: {
for (size_t i : pVCount)
expectedPointCount += i;
break;
}
case Prim_Lines:
expectedPointCount = 2 * pNumPrimitives;
break;
case Prim_Triangles:
expectedPointCount = 3 * pNumPrimitives;
break;
default:
// other primitive types don't state the index count upfront... we need to guess
break;
}
// and read all indices into a temporary array
@ -1727,7 +1728,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
}
// It is possible to not contain any indices
if (pNumPrimitives > 0) {
if (pNumPrimitives > 0) {
std::string v;
XmlParser::getValueAsString(node, v);
const char *content = v.c_str();
@ -1925,87 +1926,87 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
// now we reinterpret it according to the type we're reading here
switch (pInput.mType) {
case IT_Position: // ignore all position streams except 0 - there can be only one position
if (pInput.mIndex == 0) {
pMesh.mPositions.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
}
break;
case IT_Normal:
case IT_Position: // ignore all position streams except 0 - there can be only one position
if (pInput.mIndex == 0) {
pMesh.mPositions.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
}
break;
case IT_Normal:
// pad to current vertex count if necessary
if (pMesh.mNormals.size() < pMesh.mPositions.size() - 1)
pMesh.mNormals.insert(pMesh.mNormals.end(), pMesh.mPositions.size() - pMesh.mNormals.size() - 1, aiVector3D(0, 1, 0));
// ignore all normal streams except 0 - there can be only one normal
if (pInput.mIndex == 0) {
pMesh.mNormals.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
}
break;
case IT_Tangent:
// pad to current vertex count if necessary
if (pMesh.mTangents.size() < pMesh.mPositions.size() - 1)
pMesh.mTangents.insert(pMesh.mTangents.end(), pMesh.mPositions.size() - pMesh.mTangents.size() - 1, aiVector3D(1, 0, 0));
// ignore all tangent streams except 0 - there can be only one tangent
if (pInput.mIndex == 0) {
pMesh.mTangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
}
break;
case IT_Bitangent:
// pad to current vertex count if necessary
if (pMesh.mBitangents.size() < pMesh.mPositions.size() - 1) {
pMesh.mBitangents.insert(pMesh.mBitangents.end(), pMesh.mPositions.size() - pMesh.mBitangents.size() - 1, aiVector3D(0, 0, 1));
}
// ignore all bitangent streams except 0 - there can be only one bitangent
if (pInput.mIndex == 0) {
pMesh.mBitangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
}
break;
case IT_Texcoord:
// up to 4 texture coord sets are fine, ignore the others
if (pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) {
// pad to current vertex count if necessary
if (pMesh.mNormals.size() < pMesh.mPositions.size() - 1)
pMesh.mNormals.insert(pMesh.mNormals.end(), pMesh.mPositions.size() - pMesh.mNormals.size() - 1, aiVector3D(0, 1, 0));
if (pMesh.mTexCoords[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
pMesh.mTexCoords[pInput.mIndex].insert(pMesh.mTexCoords[pInput.mIndex].end(),
pMesh.mPositions.size() - pMesh.mTexCoords[pInput.mIndex].size() - 1, aiVector3D(0, 0, 0));
// ignore all normal streams except 0 - there can be only one normal
if (pInput.mIndex == 0) {
pMesh.mNormals.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
pMesh.mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2]));
if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) {
pMesh.mNumUVComponents[pInput.mIndex] = 3;
}
break;
case IT_Tangent:
} else {
ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping.");
}
break;
case IT_Color:
// up to 4 color sets are fine, ignore the others
if (pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) {
// pad to current vertex count if necessary
if (pMesh.mTangents.size() < pMesh.mPositions.size() - 1)
pMesh.mTangents.insert(pMesh.mTangents.end(), pMesh.mPositions.size() - pMesh.mTangents.size() - 1, aiVector3D(1, 0, 0));
if (pMesh.mColors[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
pMesh.mColors[pInput.mIndex].insert(pMesh.mColors[pInput.mIndex].end(),
pMesh.mPositions.size() - pMesh.mColors[pInput.mIndex].size() - 1, aiColor4D(0, 0, 0, 1));
// ignore all tangent streams except 0 - there can be only one tangent
if (pInput.mIndex == 0) {
pMesh.mTangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
}
break;
case IT_Bitangent:
// pad to current vertex count if necessary
if (pMesh.mBitangents.size() < pMesh.mPositions.size() - 1) {
pMesh.mBitangents.insert(pMesh.mBitangents.end(), pMesh.mPositions.size() - pMesh.mBitangents.size() - 1, aiVector3D(0, 0, 1));
aiColor4D result(0, 0, 0, 1);
for (size_t i = 0; i < pInput.mResolved->mSize; ++i) {
result[static_cast<unsigned int>(i)] = obj[pInput.mResolved->mSubOffset[i]];
}
pMesh.mColors[pInput.mIndex].push_back(result);
} else {
ASSIMP_LOG_ERROR("Collada: too many vertex color sets. Skipping.");
}
// ignore all bitangent streams except 0 - there can be only one bitangent
if (pInput.mIndex == 0) {
pMesh.mBitangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
}
break;
case IT_Texcoord:
// up to 4 texture coord sets are fine, ignore the others
if (pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) {
// pad to current vertex count if necessary
if (pMesh.mTexCoords[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
pMesh.mTexCoords[pInput.mIndex].insert(pMesh.mTexCoords[pInput.mIndex].end(),
pMesh.mPositions.size() - pMesh.mTexCoords[pInput.mIndex].size() - 1, aiVector3D(0, 0, 0));
pMesh.mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2]));
if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) {
pMesh.mNumUVComponents[pInput.mIndex] = 3;
}
} else {
ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping.");
}
break;
case IT_Color:
// up to 4 color sets are fine, ignore the others
if (pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) {
// pad to current vertex count if necessary
if (pMesh.mColors[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
pMesh.mColors[pInput.mIndex].insert(pMesh.mColors[pInput.mIndex].end(),
pMesh.mPositions.size() - pMesh.mColors[pInput.mIndex].size() - 1, aiColor4D(0, 0, 0, 1));
aiColor4D result(0, 0, 0, 1);
for (size_t i = 0; i < pInput.mResolved->mSize; ++i) {
result[static_cast<unsigned int>(i)] = obj[pInput.mResolved->mSubOffset[i]];
}
pMesh.mColors[pInput.mIndex].push_back(result);
} else {
ASSIMP_LOG_ERROR("Collada: too many vertex color sets. Skipping.");
}
break;
default:
// IT_Invalid and IT_Vertex
ai_assert(false && "shouldn't ever get here");
break;
default:
// IT_Invalid and IT_Vertex
ai_assert(false && "shouldn't ever get here");
}
}
@ -2170,10 +2171,10 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
// read as many parameters and store in the transformation
for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
// skip whitespace before the number
SkipSpacesAndLineEnd(&content);
// read a number
content = fast_atoreal_move<ai_real>(content, tf.f[a]);
// skip whitespace after it
SkipSpacesAndLineEnd(&content);
}
// place the transformation at the queue of the node
@ -2215,8 +2216,8 @@ void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::Seman
void ColladaParser::ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive) {
// Attempt to load any undefined Collada::Image in ImageLibrary
for (ImageLibrary::iterator it = mImageLibrary.begin(); it != mImageLibrary.end(); ++it) {
Collada::Image &image = (*it).second;
for (auto &it : mImageLibrary) {
Collada::Image &image = it.second;
if (image.mImageData.empty()) {
std::unique_ptr<IOStream> image_file(zip_archive.Open(image.mFileName.c_str()));
@ -2250,20 +2251,26 @@ void ColladaParser::ReadNodeGeometry(XmlNode &node, Node *pNode) {
if (currentName == "bind_material") {
XmlNode techNode = currentNode.child("technique_common");
if (techNode) {
XmlNode instanceMatNode = techNode.child("instance_material");
// read ID of the geometry subgroup and the target material
std::string group;
XmlParser::getStdStrAttribute(instanceMatNode, "symbol", group);
XmlParser::getStdStrAttribute(instanceMatNode, "target", url);
const char *urlMat = url.c_str();
Collada::SemanticMappingTable s;
if (urlMat[0] == '#')
urlMat++;
for (XmlNode instanceMatNode = techNode.child("instance_material"); instanceMatNode; instanceMatNode = instanceMatNode.next_sibling())
{
const std::string &instance_name = instanceMatNode.name();
if (instance_name == "instance_material")
{
// read ID of the geometry subgroup and the target material
std::string group;
XmlParser::getStdStrAttribute(instanceMatNode, "symbol", group);
XmlParser::getStdStrAttribute(instanceMatNode, "target", url);
const char *urlMat = url.c_str();
Collada::SemanticMappingTable s;
if (urlMat[0] == '#')
urlMat++;
s.mMatName = urlMat;
// store the association
instance.mMaterials[group] = s;
ReadMaterialVertexInputBinding(instanceMatNode, s);
s.mMatName = urlMat;
// store the association
instance.mMaterials[group] = s;
ReadMaterialVertexInputBinding(instanceMatNode, s);
}
}
}
}
}

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -43,6 +43,7 @@
* @brief Defines the parser helper class for the collada loader
*/
#pragma once
#ifndef AI_COLLADAPARSER_H_INC
#define AI_COLLADAPARSER_H_INC

View File

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

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -123,18 +123,9 @@ DXFImporter::~DXFImporter() {
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool checkSig ) const {
const std::string& extension = GetExtension( filename );
if ( extension == desc.mFileExtensions ) {
return true;
}
if ( extension.empty() || checkSig ) {
const char *pTokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
return BaseImporter::SearchFileHeaderForToken(pIOHandler, filename, pTokens, 4, 32 );
}
return false;
bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool /*checkSig*/ ) const {
static const char *tokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
return SearchFileHeaderForToken(pIOHandler, filename, tokens, AI_COUNT_OF(tokens), 32);
}
// ------------------------------------------------------------------------------------------------
@ -378,6 +369,11 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
const DXF::Block& bl_src = *(*it).second;
for (std::shared_ptr<const DXF::PolyLine> pl_in : bl_src.lines) {
if (!pl_in) {
ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping.");
continue;
}
std::shared_ptr<DXF::PolyLine> pl_out = std::shared_ptr<DXF::PolyLine>(new DXF::PolyLine(*pl_in));
if (bl_src.base.Length() || insert.scale.x!=1.f || insert.scale.y!=1.f || insert.scale.z!=1.f || insert.angle || insert.pos.Length()) {
@ -547,7 +543,7 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
++reader;
}
ASSIMP_LOG_VERBOSE_DEBUG( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(),
ASSIMP_LOG_VERBOSE_DEBUG( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(),
" inserted blocks in ENTITIES" );
}

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -43,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file DXFLoader.h
* @brief Declaration of the .dxf importer class.
*/
#pragma once
#ifndef AI_DXFLOADER_H_INCLUDED
#define AI_DXFLOADER_H_INCLUDED
@ -59,39 +59,36 @@ namespace DXF {
struct Block;
struct InsertBlock;
typedef std::map<std::string, const DXF::Block*> BlockMap;
using BlockMap = std::map<std::string, const DXF::Block*>;
}
// ---------------------------------------------------------------------------
/**
/**
* @brief DXF importer implementation.
*/
class DXFImporter : public BaseImporter {
public:
DXFImporter();
~DXFImporter();
~DXFImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details*/
const aiImporterDesc* GetInfo () const;
const aiImporterDesc* GetInfo () const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details */
void InternReadFile( const std::string& pFile,
aiScene* pScene,
IOSystem* pIOHandler);
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
private:
// -----------------------------------------------------
void SkipSection(DXF::LineReader& reader);

View File

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

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -80,8 +80,10 @@ enum TransformInheritance {
TransformInheritance_MAX // end-of-enum sentinel
};
} // namespace FBX
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // AI_FBXCOMMON_H_INC

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -79,7 +79,7 @@ using namespace Util;
#define MAGIC_NODE_TAG "_$AssimpFbx$"
#define CONVERT_FBX_TIME(time) (static_cast<double>(time) * 1000.0 / 46186158000LL)
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL
FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBones) :
defaultMaterialIndex(),
@ -653,7 +653,7 @@ bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
const PropertyTable &props = model.Props();
bool ok;
const float zero_epsilon = 1e-6f;
const float zero_epsilon = ai_epsilon;
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
const TransformationComp comp = static_cast<TransformationComp>(i);
@ -862,7 +862,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
output_nodes.push_back(std::move(nd));
return false;
}
void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
const PropertyTable &props = model.Props();
DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
@ -917,8 +917,10 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root
} else if (line) {
const std::vector<unsigned int> &indices = ConvertLine(*line, root_node);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
} else {
} else if (geo) {
FBXImporter::LogWarn("ignoring unrecognized geometry: ", geo->Name());
} else {
FBXImporter::LogWarn("skipping null geometry");
}
}
@ -1126,7 +1128,7 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
*out_uv++ = aiVector3D(v.x, v.y, 0.0f);
}
out_mesh->mTextureCoordsNames[i] = mesh.GetTextureCoordChannelName(i);
out_mesh->SetTextureCoordsName(i, aiString(mesh.GetTextureCoordChannelName(i)));
out_mesh->mNumUVComponents[i] = 2;
}
@ -1265,7 +1267,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
const std::vector<aiVector3D> &normals = mesh.GetNormals();
if (normals.size()) {
ai_assert(normals.size() == vertices.size());
out_mesh->mNormals = new aiVector3D[vertices.size()];
out_mesh->mNormals = new aiVector3D[count_vertices];
}
// allocate tangents, binormals.
@ -1293,8 +1295,8 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
ai_assert(tangents.size() == vertices.size());
ai_assert(binormals->size() == vertices.size());
out_mesh->mTangents = new aiVector3D[vertices.size()];
out_mesh->mBitangents = new aiVector3D[vertices.size()];
out_mesh->mTangents = new aiVector3D[count_vertices];
out_mesh->mBitangents = new aiVector3D[count_vertices];
}
}
@ -1306,7 +1308,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
break;
}
out_mesh->mTextureCoords[i] = new aiVector3D[vertices.size()];
out_mesh->mTextureCoords[i] = new aiVector3D[count_vertices];
out_mesh->mNumUVComponents[i] = 2;
}
@ -1318,7 +1320,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
break;
}
out_mesh->mColors[i] = new aiColor4D[vertices.size()];
out_mesh->mColors[i] = new aiColor4D[count_vertices];
}
unsigned int cursor = 0, in_cursor = 0;
@ -1593,7 +1595,7 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
bone_map.insert(std::pair<const std::string, aiBone *>(deformer_name, bone));
}
ASSIMP_LOG_DEBUG("bone research: Indicies size: ", out_indices.size());
ASSIMP_LOG_DEBUG("bone research: Indices size: ", out_indices.size());
// lookup must be populated in case something goes wrong
// this also allocates bones to mesh instance outside
@ -1766,6 +1768,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap
// XXX handle all kinds of UV transformations
uvTrafo.mScaling = tex->UVScaling();
uvTrafo.mTranslation = tex->UVTranslation();
uvTrafo.mRotation = tex->UVRotation();
out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, 0);
const PropertyTable &props = tex->Props();
@ -1885,6 +1888,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex
// XXX handle all kinds of UV transformations
uvTrafo.mScaling = tex->UVScaling();
uvTrafo.mTranslation = tex->UVTranslation();
uvTrafo.mRotation = tex->UVRotation();
out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, texIndex);
const PropertyTable &props = tex->Props();
@ -2066,6 +2070,7 @@ void FBXConverter::SetTextureProperties(aiMaterial *out_mat, const LayeredTextur
TrySetTextureProperties(out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh);
TrySetTextureProperties(out_mat, layeredTextures, "EmissiveFactor", aiTextureType_EMISSIVE, mesh);
TrySetTextureProperties(out_mat, layeredTextures, "TransparencyFactor", aiTextureType_OPACITY, mesh);
TrySetTextureProperties(out_mat, layeredTextures, "ReflectionFactor", aiTextureType_METALNESS, mesh);
}
aiColor3D FBXConverter::GetColorPropertyFactored(const PropertyTable &props, const std::string &colorName,
@ -2129,7 +2134,7 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
if (ok) {
out_mat->AddProperty(&Emissive, 1, AI_MATKEY_COLOR_EMISSIVE);
} else {
const aiColor3D &emissiveColor = GetColorPropertyFromMaterial(props, "Maya|emissive", ok);
const aiColor3D &emissiveColor = GetColorProperty(props, "Maya|emissive", ok);
if (ok) {
out_mat->AddProperty(&emissiveColor, 1, AI_MATKEY_COLOR_EMISSIVE);
}
@ -2216,7 +2221,7 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
}
// PBR material information
const aiColor3D &baseColor = GetColorPropertyFromMaterial(props, "Maya|base_color", ok);
const aiColor3D &baseColor = GetColorProperty(props, "Maya|base_color", ok);
if (ok) {
out_mat->AddProperty(&baseColor, 1, AI_MATKEY_BASE_COLOR);
}
@ -2324,6 +2329,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
// XXX handle all kinds of UV transformations
uvTrafo.mScaling = tex->UVScaling();
uvTrafo.mTranslation = tex->UVTranslation();
uvTrafo.mRotation = tex->UVRotation();
out_mat->AddProperty(&uvTrafo, 1, (name + "|uvtrafo").c_str(), aiTextureType_UNKNOWN, 0);
int uvIndex = 0;
@ -2599,7 +2605,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
anim->mMorphMeshChannels = new aiMeshMorphAnim *[numMorphMeshChannels];
anim->mNumMorphMeshChannels = numMorphMeshChannels;
unsigned int i = 0;
for (auto morphAnimIt : morphAnimDatas) {
for (const auto &morphAnimIt : morphAnimDatas) {
morphAnimData *animData = morphAnimIt.second;
unsigned int numKeys = static_cast<unsigned int>(animData->size());
aiMeshMorphAnim *meshMorphAnim = new aiMeshMorphAnim();
@ -2613,7 +2619,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
meshMorphAnim->mKeys[j].mNumValuesAndWeights = numValuesAndWeights;
meshMorphAnim->mKeys[j].mValues = new unsigned int[numValuesAndWeights];
meshMorphAnim->mKeys[j].mWeights = new double[numValuesAndWeights];
meshMorphAnim->mKeys[j].mTime = CONVERT_FBX_TIME(animIt.first);
meshMorphAnim->mKeys[j].mTime = CONVERT_FBX_TIME(animIt.first) * anim_fps;
for (unsigned int k = 0; k < numValuesAndWeights; k++) {
meshMorphAnim->mKeys[j].mValues[k] = keyData->values.at(k);
meshMorphAnim->mKeys[j].mWeights[k] = keyData->weights.at(k);
@ -2631,8 +2637,8 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
return;
}
double start_time_fps = has_local_startstop ? CONVERT_FBX_TIME(start_time) : min_time;
double stop_time_fps = has_local_startstop ? CONVERT_FBX_TIME(stop_time) : max_time;
double start_time_fps = has_local_startstop ? (CONVERT_FBX_TIME(start_time) * anim_fps) : min_time;
double stop_time_fps = has_local_startstop ? (CONVERT_FBX_TIME(stop_time) * anim_fps) : max_time;
// adjust relative timing for animation
for (unsigned int c = 0; c < anim->mNumChannels; c++) {
@ -3122,7 +3128,12 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
if (chain[i] == iterEnd)
continue;
keyframeLists[i] = GetKeyframeList((*chain[i]).second, start, stop);
if (i == TransformationComp_Rotation || i == TransformationComp_PreRotation
|| i == TransformationComp_PostRotation || i == TransformationComp_GeometricRotation) {
keyframeLists[i] = GetRotationKeyframeList((*chain[i]).second, start, stop);
} else {
keyframeLists[i] = GetKeyframeList((*chain[i]).second, start, stop);
}
for (KeyFrameListList::const_iterator it = keyframeLists[i].begin(); it != keyframeLists[i].end(); ++it) {
const KeyTimeList& times = *std::get<0>(*it);
@ -3152,7 +3163,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
InterpolateKeys(outTranslations, keytimes, keyframeLists[TransformationComp_Translation], defTranslate, maxTime, minTime);
} else {
for (size_t i = 0; i < keyCount; ++i) {
outTranslations[i].mTime = CONVERT_FBX_TIME(keytimes[i]);
outTranslations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
outTranslations[i].mValue = defTranslate;
}
}
@ -3161,7 +3172,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], defRotation, maxTime, minTime, rotOrder);
} else {
for (size_t i = 0; i < keyCount; ++i) {
outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]);
outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
outRotations[i].mValue = defQuat;
}
}
@ -3170,13 +3181,14 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
InterpolateKeys(outScales, keytimes, keyframeLists[TransformationComp_Scaling], defScale, maxTime, minTime);
} else {
for (size_t i = 0; i < keyCount; ++i) {
outScales[i].mTime = CONVERT_FBX_TIME(keytimes[i]);
outScales[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
outScales[i].mValue = defScale;
}
}
bool ok = false;
const float zero_epsilon = 1e-6f;
const float zero_epsilon = ai_epsilon;
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
if (ok && preRotation.SquareLength() > zero_epsilon) {
@ -3269,6 +3281,79 @@ FBXConverter::KeyFrameListList FBXConverter::GetKeyframeList(const std::vector<c
return inputs; // pray for NRVO :-)
}
FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::vector<const AnimationCurveNode *> &nodes,
int64_t start, int64_t stop) {
KeyFrameListList inputs;
inputs.reserve(nodes.size() * 3);
//give some breathing room for rounding errors
const int64_t adj_start = start - 10000;
const int64_t adj_stop = stop + 10000;
for (const AnimationCurveNode *node : nodes) {
ai_assert(node);
const AnimationCurveMap &curves = node->Curves();
for (const AnimationCurveMap::value_type &kv : curves) {
unsigned int mapto;
if (kv.first == "d|X") {
mapto = 0;
} else if (kv.first == "d|Y") {
mapto = 1;
} else if (kv.first == "d|Z") {
mapto = 2;
} else {
FBXImporter::LogWarn("ignoring scale animation curve, did not recognize target component");
continue;
}
const AnimationCurve *const curve = kv.second;
ai_assert(curve->GetKeys().size() == curve->GetValues().size());
ai_assert(curve->GetKeys().size());
//get values within the start/stop time window
std::shared_ptr<KeyTimeList> Keys(new KeyTimeList());
std::shared_ptr<KeyValueList> Values(new KeyValueList());
const size_t count = curve->GetKeys().size();
int64_t tp = curve->GetKeys().at(0);
float vp = curve->GetValues().at(0);
Keys->push_back(tp);
Values->push_back(vp);
if (count > 1) {
int64_t tc = curve->GetKeys().at(1);
float vc = curve->GetValues().at(1);
for (size_t n = 1; n < count; n++) {
while (std::abs(vc - vp) >= 180.0f) {
float step = std::floor(float(tc - tp) / (vc - vp) * 179.0f);
int64_t tnew = tp + int64_t(step);
float vnew = vp + (vc - vp) * step / float(tc - tp);
if (tnew >= adj_start && tnew <= adj_stop) {
Keys->push_back(tnew);
Values->push_back(vnew);
}
tp = tnew;
vp = vnew;
}
if (tc >= adj_start && tc <= adj_stop) {
Keys->push_back(tc);
Values->push_back(vc);
}
if (n + 1 < count) {
tp = tc;
vp = vc;
tc = curve->GetKeys().at(n + 1);
vc = curve->GetValues().at(n + 1);
}
}
}
inputs.push_back(std::make_tuple(Keys, Values, mapto));
}
}
return inputs;
}
KeyTimeList FBXConverter::GetKeyTimeList(const KeyFrameListList &inputs) {
ai_assert(!inputs.empty());
@ -3359,7 +3444,7 @@ void FBXConverter::InterpolateKeys(aiVectorKey *valOut, const KeyTimeList &keys,
}
// magic value to convert fbx times to seconds
valOut->mTime = CONVERT_FBX_TIME(time);
valOut->mTime = CONVERT_FBX_TIME(time) * anim_fps;
min_time = std::min(min_time, valOut->mTime);
max_time = std::max(max_time, valOut->mTime);
@ -3459,7 +3544,7 @@ void FBXConverter::ConvertRotationKeys(aiNodeAnim *na, const std::vector<const A
ai_assert(nodes.size());
// XXX see notes in ConvertScaleKeys()
const std::vector<KeyFrameList> &inputs = GetKeyframeList(nodes, start, stop);
const std::vector<KeyFrameList> &inputs = GetRotationKeyframeList(nodes, start, stop);
const KeyTimeList &keys = GetKeyTimeList(inputs);
na->mNumRotationKeys = static_cast<unsigned int>(keys.size());
@ -3569,7 +3654,7 @@ void FBXConverter::ConvertOrphanedEmbeddedTextures() {
if (texture->Media() && texture->Media()->ContentLength() > 0) {
realTexture = texture;
}
}
}
}
} catch (...) {
// do nothing

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -76,7 +76,7 @@ namespace Assimp {
namespace FBX {
class Document;
/**
/**
* Convert a FBX #Document to #aiScene
* @param out Empty scene to be populated
* @param doc Parsed FBX document
@ -182,7 +182,7 @@ private:
// ------------------------------------------------------------------------------------------------
void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
std::vector<unsigned int>
@ -361,6 +361,7 @@ private:
// ------------------------------------------------------------------------------------------------
KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop);
KeyFrameListList GetRotationKeyframeList(const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop);
// ------------------------------------------------------------------------------------------------
KeyTimeList GetKeyTimeList(const KeyFrameListList& inputs);

View File

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

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -57,9 +56,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp>
#include <memory>
#include <functional>
#include <map>
#include <memory>
#include <utility>
namespace Assimp {
namespace FBX {
@ -67,23 +67,13 @@ namespace FBX {
using namespace Util;
// ------------------------------------------------------------------------------------------------
LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc)
: doc(doc)
, element(element)
, id(id)
, flags() {
LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc) :
doc(doc), element(element), id(id), flags() {
// empty
}
// ------------------------------------------------------------------------------------------------
LazyObject::~LazyObject()
{
// empty
}
// ------------------------------------------------------------------------------------------------
const Object* LazyObject::Get(bool dieOnError)
{
const Object* LazyObject::Get(bool dieOnError) {
if(IsBeingConstructed() || FailedToConstruct()) {
return nullptr;
}
@ -233,39 +223,20 @@ const Object* LazyObject::Get(bool dieOnError)
}
// ------------------------------------------------------------------------------------------------
Object::Object(uint64_t id, const Element& element, const std::string& name)
: element(element)
, name(name)
, id(id)
{
Object::Object(uint64_t id, const Element& element, const std::string& name) :
element(element), name(name), id(id) {
// empty
}
// ------------------------------------------------------------------------------------------------
Object::~Object()
{
FileGlobalSettings::FileGlobalSettings(const Document &doc, std::shared_ptr<const PropertyTable> props) :
props(std::move(props)), doc(doc) {
// empty
}
// ------------------------------------------------------------------------------------------------
FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props)
: props(props)
, doc(doc)
{
// empty
}
// ------------------------------------------------------------------------------------------------
FileGlobalSettings::~FileGlobalSettings()
{
// empty
}
// ------------------------------------------------------------------------------------------------
Document::Document(const Parser& parser, const ImportSettings& settings)
: settings(settings)
, parser(parser)
{
Document::Document(const Parser& parser, const ImportSettings& settings) :
settings(settings), parser(parser) {
ASSIMP_LOG_DEBUG("Creating FBX Document");
// Cannot use array default initialization syntax because vc8 fails on it
@ -286,8 +257,7 @@ Document::Document(const Parser& parser, const ImportSettings& settings)
}
// ------------------------------------------------------------------------------------------------
Document::~Document()
{
Document::~Document() {
for(ObjectMap::value_type& v : objects) {
delete v.second;
}
@ -349,8 +319,7 @@ void Document::ReadHeader() {
}
// ------------------------------------------------------------------------------------------------
void Document::ReadGlobalSettings()
{
void Document::ReadGlobalSettings() {
const Scope& sc = parser.GetRootScope();
const Element* const ehead = sc["GlobalSettings"];
if ( nullptr == ehead || !ehead->Compound() ) {
@ -371,8 +340,7 @@ void Document::ReadGlobalSettings()
}
// ------------------------------------------------------------------------------------------------
void Document::ReadObjects()
{
void Document::ReadObjects() {
// read ID objects from "Objects" section
const Scope& sc = parser.GetRootScope();
const Element* const eobjects = sc["Objects"];
@ -419,8 +387,7 @@ void Document::ReadObjects()
}
// ------------------------------------------------------------------------------------------------
void Document::ReadPropertyTemplates()
{
void Document::ReadPropertyTemplates() {
const Scope& sc = parser.GetRootScope();
// read property templates from "Definitions" section
const Element* const edefs = sc["Definitions"];
@ -477,8 +444,7 @@ void Document::ReadPropertyTemplates()
}
// ------------------------------------------------------------------------------------------------
void Document::ReadConnections()
{
void Document::ReadConnections() {
const Scope& sc = parser.GetRootScope();
// read property templates from "Definitions" section
const Element* const econns = sc["Connections"];
@ -525,8 +491,7 @@ void Document::ReadConnections()
}
// ------------------------------------------------------------------------------------------------
const std::vector<const AnimationStack*>& Document::AnimationStacks() const
{
const std::vector<const AnimationStack*>& Document::AnimationStacks() const {
if (!animationStacksResolved.empty() || animationStacks.empty()) {
return animationStacksResolved;
}
@ -546,17 +511,15 @@ const std::vector<const AnimationStack*>& Document::AnimationStacks() const
}
// ------------------------------------------------------------------------------------------------
LazyObject* Document::GetObject(uint64_t id) const
{
LazyObject* Document::GetObject(uint64_t id) const {
ObjectMap::const_iterator it = objects.find(id);
return it == objects.end() ? nullptr : (*it).second;
}
#define MAX_CLASSNAMES 6
constexpr size_t MAX_CLASSNAMES = 6;
// ------------------------------------------------------------------------------------------------
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, const ConnectionMap& conns) const
{
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, const ConnectionMap& conns) const {
std::vector<const Connection*> temp;
const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range =
@ -574,11 +537,9 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, co
// ------------------------------------------------------------------------------------------------
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bool is_src,
const ConnectionMap& conns,
const char* const* classnames,
size_t count) const
{
const ConnectionMap& conns,
const char* const* classnames,
size_t count) const {
ai_assert(classnames);
ai_assert( count != 0 );
ai_assert( count <= MAX_CLASSNAMES);
@ -623,95 +584,72 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
}
// ------------------------------------------------------------------------------------------------
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const
{
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const {
return GetConnectionsSequenced(source, ConnectionsBySource());
}
// ------------------------------------------------------------------------------------------------
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t src, const char* classname) const
{
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t src, const char* classname) const {
const char* arr[] = {classname};
return GetConnectionsBySourceSequenced(src, arr,1);
}
// ------------------------------------------------------------------------------------------------
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source,
const char* const* classnames, size_t count) const
{
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source,
const char* const* classnames, size_t count) const {
return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count);
}
// ------------------------------------------------------------------------------------------------
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest,
const char* classname) const
{
const char* classname) const {
const char* arr[] = {classname};
return GetConnectionsByDestinationSequenced(dest, arr,1);
}
// ------------------------------------------------------------------------------------------------
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest) const
{
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest) const {
return GetConnectionsSequenced(dest, ConnectionsByDestination());
}
// ------------------------------------------------------------------------------------------------
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest,
const char* const* classnames, size_t count) const
{
const char* const* classnames, size_t count) const {
return GetConnectionsSequenced(dest, false, ConnectionsByDestination(),classnames, count);
}
// ------------------------------------------------------------------------------------------------
Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop,
const Document& doc)
: insertionOrder(insertionOrder)
, prop(prop)
, src(src)
, dest(dest)
, doc(doc)
{
const Document& doc) :
insertionOrder(insertionOrder), prop(prop), src(src), dest(dest), doc(doc) {
ai_assert(doc.Objects().find(src) != doc.Objects().end());
// dest may be 0 (root node)
ai_assert(!dest || doc.Objects().find(dest) != doc.Objects().end());
}
// ------------------------------------------------------------------------------------------------
Connection::~Connection()
{
// empty
}
// ------------------------------------------------------------------------------------------------
LazyObject& Connection::LazySourceObject() const
{
LazyObject& Connection::LazySourceObject() const {
LazyObject* const lazy = doc.GetObject(src);
ai_assert(lazy);
return *lazy;
}
// ------------------------------------------------------------------------------------------------
LazyObject& Connection::LazyDestinationObject() const
{
LazyObject& Connection::LazyDestinationObject() const {
LazyObject* const lazy = doc.GetObject(dest);
ai_assert(lazy);
return *lazy;
}
// ------------------------------------------------------------------------------------------------
const Object* Connection::SourceObject() const
{
const Object* Connection::SourceObject() const {
LazyObject* const lazy = doc.GetObject(src);
ai_assert(lazy);
return lazy->Get();
}
// ------------------------------------------------------------------------------------------------
const Object* Connection::DestinationObject() const
{
const Object* Connection::DestinationObject() const {
LazyObject* const lazy = doc.GetObject(dest);
ai_assert(lazy);
return lazy->Get();
@ -720,4 +658,4 @@ const Object* Connection::DestinationObject() const
} // !FBX
} // !Assimp
#endif
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -89,7 +88,7 @@ class LazyObject {
public:
LazyObject(uint64_t id, const Element& element, const Document& doc);
~LazyObject();
~LazyObject() = default;
const Object* Get(bool dieOnError = false);
@ -139,7 +138,7 @@ class Object {
public:
Object(uint64_t id, const Element& element, const std::string& name);
virtual ~Object();
virtual ~Object() = default;
const Element& SourceElement() const {
return element;
@ -267,8 +266,7 @@ public:
Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
virtual ~Light();
enum Type
{
enum Type {
Type_Point,
Type_Directional,
Type_Spot,
@ -278,8 +276,7 @@ public:
Type_MAX // end-of-enum sentinel
};
enum Decay
{
enum Decay {
Decay_None,
Decay_Linear,
Decay_Quadratic,
@ -347,7 +344,7 @@ public:
Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
virtual ~Model();
virtual ~Model() = default;
fbx_simple_property(QuaternionInterpolate, int, 0)
@ -500,6 +497,10 @@ public:
return uvScaling;
}
const ai_real &UVRotation() const {
return uvRotation;
}
const PropertyTable& Props() const {
ai_assert(props.get());
return *props.get();
@ -517,6 +518,7 @@ public:
private:
aiVector2D uvTrans;
aiVector2D uvScaling;
ai_real uvRotation;
std::string type;
std::string relativeFileName;
@ -573,31 +575,27 @@ public:
BlendMode_BlendModeCount
};
const Texture* getTexture(int index=0) const
{
const Texture* getTexture(int index=0) const {
return textures[index];
}
int textureCount() const {
return static_cast<int>(textures.size());
}
BlendMode GetBlendMode() const
{
BlendMode GetBlendMode() const {
return blendMode;
}
float Alpha()
{
float Alpha() {
return alpha;
}
private:
std::vector<const Texture*> textures;
BlendMode blendMode;
float alpha;
};
typedef std::fbx_unordered_map<std::string, const Texture*> TextureMap;
typedef std::fbx_unordered_map<std::string, const LayeredTexture*> LayeredTextureMap;
using TextureMap = std::fbx_unordered_map<std::string, const Texture*>;
using LayeredTextureMap = std::fbx_unordered_map<std::string, const LayeredTexture*>;
/** DOM class for generic FBX videos */
class Video : public Object {
@ -685,10 +683,10 @@ private:
LayeredTextureMap layeredTextures;
};
typedef std::vector<int64_t> KeyTimeList;
typedef std::vector<float> KeyValueList;
using KeyTimeList = std::vector<int64_t>;
using KeyValueList = std::vector<float>;
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefore) */
class AnimationCurve : public Object {
public:
AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
@ -722,7 +720,7 @@ private:
};
// property-name -> animation curve
typedef std::map<std::string, const AnimationCurve*> AnimationCurveMap;
using AnimationCurveMap = std::map<std::string, const AnimationCurve*>;
/** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */
class AnimationCurveNode : public Object {
@ -772,7 +770,7 @@ private:
const Document& doc;
};
typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList;
using AnimationCurveNodeList = std::vector<const AnimationCurveNode*>;
/** Represents a FBX animation layer (i.e. a list of node animations) */
class AnimationLayer : public Object {
@ -795,7 +793,7 @@ private:
const Document& doc;
};
typedef std::vector<const AnimationLayer*> AnimationLayerList;
using AnimationLayerList = std::vector<const AnimationLayer*>;
/** Represents a FBX animation stack (i.e. a list of animation layers) */
class AnimationStack : public Object {
@ -838,8 +836,8 @@ private:
std::shared_ptr<const PropertyTable> props;
};
typedef std::vector<float> WeightArray;
typedef std::vector<unsigned int> WeightIndexArray;
using WeightArray = std::vector<float>;
using WeightIndexArray = std::vector<unsigned int>;
/** DOM class for BlendShapeChannel deformers */
@ -951,7 +949,7 @@ class Connection {
public:
Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop, const Document& doc);
~Connection();
~Connection() = default;
// note: a connection ensures that the source and dest objects exist, but
// not that they have DOM representations, so the return value of one of
@ -1006,10 +1004,9 @@ public:
// during their entire lifetime (Document). FBX files have
// up to many thousands of objects (most of which we never use),
// so the memory overhead for them should be kept at a minimum.
typedef std::fbx_unordered_map<uint64_t, LazyObject*> ObjectMap;
typedef std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > PropertyTemplateMap;
typedef std::fbx_unordered_multimap<uint64_t, const Connection*> ConnectionMap;
using ObjectMap = std::fbx_unordered_map<uint64_t, LazyObject*> ;
using PropertyTemplateMap = std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > ;
using ConnectionMap = std::fbx_unordered_multimap<uint64_t, const Connection*>;
/** DOM class for global document settings, a single instance per document can
* be accessed via Document.Globals(). */
@ -1017,7 +1014,7 @@ class FileGlobalSettings {
public:
FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props);
~FileGlobalSettings();
~FileGlobalSettings() = default;
const PropertyTable& Props() const {
ai_assert(props.get());

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -144,9 +144,8 @@ void FBX::Node::AddP70time(
// public member functions for writing nodes to stream
void FBX::Node::Dump(
std::shared_ptr<Assimp::IOStream> outfile,
bool binary, int indent
) {
const std::shared_ptr<Assimp::IOStream> &outfile,
bool binary, int indent) {
if (binary) {
Assimp::StreamWriterLE outstream(outfile);
DumpBinary(outstream);

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