Merge remote-tracking branch 'github/master' into contrib
commit
d0bee866c0
|
@ -81,3 +81,5 @@ lib64/assimp-vc120-mtd.ilk
|
|||
lib64/assimp-vc120-mtd.exp
|
||||
lib64/assimp-vc120-mt.exp
|
||||
xcuserdata
|
||||
|
||||
cmake-build-debug
|
||||
|
|
63
.travis.sh
63
.travis.sh
|
@ -1,17 +1,66 @@
|
|||
function generate()
|
||||
{
|
||||
cmake -G "Unix Makefiles" -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD -DASSIMP_COVERALLS=$ENABLE_COVERALLS
|
||||
}
|
||||
#---------------------------------------------------------------------------
|
||||
#Open Asset Import Library (assimp)
|
||||
#---------------------------------------------------------------------------
|
||||
# Copyright (c) 2006-2017, assimp team
|
||||
#
|
||||
# License see LICENSE file
|
||||
#
|
||||
function generate() {
|
||||
OPTIONS="-DASSIMP_WERROR=ON"
|
||||
|
||||
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) \
|
||||
#&& (cd test/regression; chmod 755 run.py; ./run.py ../../bin/assimp; \
|
||||
# chmod 755 result_checker.py; ./result_checker.py)
|
||||
&& (cd test/unit; ../../bin/unit)
|
||||
fi
|
||||
fi
|
||||
|
|
48
.travis.yml
48
.travis.yml
|
@ -1,8 +1,10 @@
|
|||
sudo: required
|
||||
language: cpp
|
||||
|
||||
cache: ccache
|
||||
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake && 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" = "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.;
|
||||
|
@ -16,26 +18,43 @@ before_install:
|
|||
# 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
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
os:
|
||||
- linux
|
||||
|
||||
osx_image: xcode8.3
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
env:
|
||||
global:
|
||||
# COVERITY_SCAN_TOKEN
|
||||
- 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}
|
||||
matrix:
|
||||
- LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON
|
||||
- LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF
|
||||
- LINUX=1 SHARED_BUILD=ON ENABLE_COVERALLS=OFF
|
||||
- LINUX=1 SHARED_BUILD=OFF ENABLE_COVERALLS=OFF
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
matrix:
|
||||
include:
|
||||
# disabled until clang 5.0 analyzer issues are fixed
|
||||
# - os: linux
|
||||
# compiler: clang
|
||||
# env: ANALYZE=ON
|
||||
- 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: DISABLE_EXPORTERS=YES 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
|
||||
|
@ -48,9 +67,6 @@ script:
|
|||
- export COVERALLS_SERVICE_NAME=travis-ci
|
||||
- export COVERALLS_REPO_TOKEN=abc12345
|
||||
- . ./.travis.sh
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
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
|
||||
|
|
|
@ -42,6 +42,10 @@ OPTION( BUILD_SHARED_LIBS
|
|||
"Build package with shared libraries."
|
||||
ON
|
||||
)
|
||||
OPTION( BUILD_FRAMEWORK
|
||||
"Build package as Mac OS X Framework bundle."
|
||||
OFF
|
||||
)
|
||||
OPTION( ASSIMP_DOUBLE_PRECISION
|
||||
"Set to ON to enable double precision processing"
|
||||
OFF
|
||||
|
@ -78,6 +82,18 @@ OPTION ( ASSIMP_COVERALLS
|
|||
"Enable this to measure test coverage."
|
||||
OFF
|
||||
)
|
||||
OPTION ( ASSIMP_WERROR
|
||||
"Treat warnings as errors."
|
||||
OFF
|
||||
)
|
||||
OPTION ( ASSIMP_ASAN
|
||||
"Enable AddressSanitizer."
|
||||
OFF
|
||||
)
|
||||
OPTION ( ASSIMP_UBSAN
|
||||
"Enable Undefined Behavior sanitizer."
|
||||
OFF
|
||||
)
|
||||
OPTION ( SYSTEM_IRRXML
|
||||
"Use system installed Irrlicht/IrrXML library."
|
||||
OFF
|
||||
|
@ -99,14 +115,22 @@ IF(MSVC)
|
|||
)
|
||||
ENDIF(MSVC)
|
||||
|
||||
IF (BUILD_FRAMEWORK)
|
||||
SET (BUILD_SHARED_LIBS ON)
|
||||
MESSAGE(STATUS "Framework bundle building enabled")
|
||||
ENDIF(BUILD_FRAMEWORK)
|
||||
|
||||
IF(NOT BUILD_SHARED_LIBS)
|
||||
MESSAGE(STATUS "Shared libraries disabled")
|
||||
SET(LINK_SEARCH_START_STATIC TRUE)
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Shared libraries enabled")
|
||||
ENDIF(NOT BUILD_SHARED_LIBS)
|
||||
|
||||
# Define here the needed parameters
|
||||
SET (ASSIMP_VERSION_MAJOR 4)
|
||||
SET (ASSIMP_VERSION_MINOR 0)
|
||||
SET (ASSIMP_VERSION_PATCH 1)
|
||||
SET (ASSIMP_VERSION_MINOR 1)
|
||||
SET (ASSIMP_VERSION_PATCH 0)
|
||||
SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
|
||||
SET (ASSIMP_SOVERSION 4)
|
||||
SET (PROJECT_VERSION "${ASSIMP_VERSION}")
|
||||
|
@ -143,19 +167,6 @@ IF(ASSIMP_DOUBLE_PRECISION)
|
|||
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
|
||||
ENDIF(ASSIMP_DOUBLE_PRECISION)
|
||||
|
||||
# Check for OpenMP support
|
||||
find_package(OpenMP)
|
||||
if (OPENMP_FOUND)
|
||||
SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
|
||||
IF(MSVC)
|
||||
IF(MSVC_VERSION GREATER 1910)
|
||||
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:twoPhase-")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
CONFIGURE_FILE(
|
||||
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
||||
|
@ -181,8 +192,11 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
|
|||
|
||||
IF( UNIX )
|
||||
# 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 )
|
||||
#ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Use GNUInstallDirs for Unix predefined directories
|
||||
|
@ -199,19 +213,49 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
|
|||
ELSEIF(MSVC)
|
||||
# enable multi-core compilation with MSVC
|
||||
add_compile_options(/MP)
|
||||
|
||||
# disable "elements of array '' will be default initialized" warning on MSVC2013
|
||||
IF(MSVC12)
|
||||
add_compile_options(/wd4351)
|
||||
ENDIF()
|
||||
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -pedantic -std=c++11" )
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" )
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
ELSEIF( CMAKE_COMPILER_IS_MINGW )
|
||||
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -pedantic -std=c++11" )
|
||||
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11" )
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
|
||||
ENDIF()
|
||||
|
||||
if (ASSIMP_COVERALLS)
|
||||
MESSAGE(STATUS "Coveralls enabled")
|
||||
INCLUDE(Coveralls)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||
endif()
|
||||
|
||||
if (ASSIMP_WERROR)
|
||||
MESSAGE(STATUS "Treating warnings as errors")
|
||||
IF (MSVC)
|
||||
add_compile_options(/WX)
|
||||
ELSE()
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
if (ASSIMP_ASAN)
|
||||
MESSAGE(STATUS "AddressSanitizer enabled")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
|
||||
endif()
|
||||
|
||||
if (ASSIMP_UBSAN)
|
||||
MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
|
||||
endif()
|
||||
|
||||
INCLUDE (FindPkgMacros)
|
||||
INCLUDE (PrecompiledHeader)
|
||||
|
||||
|
|
8
CREDITS
8
CREDITS
|
@ -158,3 +158,11 @@ Contributed X File exporter
|
|||
Contributed Step (stp) exporter
|
||||
|
||||
For a more detailed list just check: https://github.com/assimp/assimp/network/members
|
||||
|
||||
Patreons:
|
||||
- migenius
|
||||
- Marcus
|
||||
- Cort
|
||||
- elect
|
||||
- Steffen
|
||||
|
||||
|
|
10
Readme.md
10
Readme.md
|
@ -52,7 +52,8 @@ __Importers__:
|
|||
- DXF
|
||||
- ENFF
|
||||
- FBX
|
||||
- GLB/GLTF
|
||||
- glTF 1.0 + GLB
|
||||
- glTF 2.0
|
||||
- HMB
|
||||
- IFC-STEP
|
||||
- IRR / IRRMESH
|
||||
|
@ -106,8 +107,8 @@ __Exporters__:
|
|||
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
||||
- ASSBIN
|
||||
- STEP
|
||||
- glTF (partial)
|
||||
- glTF2.0
|
||||
- glTF 1.0 (partial)
|
||||
- glTF 2.0 (partial)
|
||||
|
||||
### Building ###
|
||||
Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
|
||||
|
@ -118,7 +119,8 @@ Take a look into the `INSTALL` file. Our build system is CMake, if you used CMak
|
|||
* [.NET](port/AssimpNET/Readme.md)
|
||||
* [Pascal](port/AssimpPascal/Readme.md)
|
||||
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
|
||||
* [Unity 3d Plugin] (https://www.assetstore.unity3d.com/en/#!/content/91777)
|
||||
* [Unity 3d Plugin](https://www.assetstore.unity3d.com/en/#!/content/91777)
|
||||
* [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (currently supported obj, ply, stl, collada, md2)
|
||||
|
||||
### Other tools ###
|
||||
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
|
||||
|
|
57
appveyor.yml
57
appveyor.yml
|
@ -10,32 +10,53 @@ branches:
|
|||
only:
|
||||
- master
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
image:
|
||||
- Visual Studio 2013
|
||||
- Visual Studio 2015
|
||||
- Visual Studio 2017
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- Win32
|
||||
- x64
|
||||
|
||||
configuration:
|
||||
- 14 2015
|
||||
- 12 2013
|
||||
#- MinGW
|
||||
#- 10 2010 # only works for x86
|
||||
|
||||
init:
|
||||
- if "%platform%" EQU "x64" ( for %%a in (2008 2010 MinGW) do ( if "%Configuration%"=="%%a" (echo "Skipping unsupported configuration" && exit /b 1 ) ) )
|
||||
configuration: Release
|
||||
|
||||
install:
|
||||
# Make compiler command line tools available
|
||||
- call c:\projects\assimp\scripts\appveyor\compiler_setup.bat
|
||||
- set PATH=C:\Ruby24-x64\bin;%PATH%
|
||||
- set CMAKE_DEFINES -DASSIMP_WERROR=ON
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2013" set CMAKE_GENERATOR_NAME=Visual Studio 12 2013
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
|
||||
- if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64
|
||||
- cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%"
|
||||
|
||||
build_script:
|
||||
- cd c:\projects\assimp
|
||||
- if "%platform%" equ "x64" (cmake CMakeLists.txt -G "Visual Studio %Configuration% Win64")
|
||||
- if "%platform%" equ "x86" (cmake CMakeLists.txt -G "Visual Studio %Configuration%")
|
||||
- if "%platform%" equ "x64" (msbuild /m /p:Configuration=Release /p:Platform="x64" Assimp.sln)
|
||||
- if "%platform%" equ "x86" (msbuild /m /p:Configuration=Release /p:Platform="Win32" Assimp.sln)
|
||||
cache:
|
||||
- code\assimp.dir\%CONFIGURATION%
|
||||
- contrib\zlib\zlibstatic.dir\%CONFIGURATION%
|
||||
- contrib\zlib\zlib.dir\%CONFIGURATION%
|
||||
- tools\assimp_cmd\assimp_cmd.dir\%CONFIGURATION%
|
||||
- tools\assimp_view\assimp_viewer.dir\%CONFIGURATION%
|
||||
- test\unit.dir\%CONFIGURATION%
|
||||
- bin\.mtime_cache
|
||||
|
||||
before_build:
|
||||
- ruby scripts\AppVeyor\mtime_cache -g scripts\AppVeyor\cacheglobs.txt -c bin\.mtime_cache\cache.json
|
||||
|
||||
build:
|
||||
parallel: true
|
||||
project: Assimp.sln
|
||||
|
||||
after_build:
|
||||
- 7z a assimp.7z c:\projects\assimp\bin\release\* c:\projects\assimp\lib\release\*
|
||||
- 7z a assimp.7z bin\%CONFIGURATION%\* lib\%CONFIGURATION%\*
|
||||
|
||||
test_script:
|
||||
- cmd: bin\%CONFIGURATION%\unit.exe --gtest_output=xml:testout.xml
|
||||
|
||||
on_finish:
|
||||
- ps: (new-object net.webclient).UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\testout.xml))
|
||||
|
||||
artifacts:
|
||||
- path: assimp.7z
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=@CMAKE_INSTALL_PREFIX@/
|
||||
libdir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_LIB_INSTALL_DIR@
|
||||
includedir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_INCLUDE_INSTALL_DIR@/assimp
|
||||
includedir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_INCLUDE_INSTALL_DIR@
|
||||
|
||||
Name: @CMAKE_PROJECT_NAME@
|
||||
Description: Import various well-known 3D model formats in an uniform manner.
|
||||
|
|
|
@ -310,7 +310,7 @@ foreach (GCOV_FILE ${GCOV_FILES})
|
|||
message("MD5: ${GCOV_SRC_PATH} = ${GCOV_CONTENTS_MD5}")
|
||||
|
||||
# Loads the gcov file as a list of lines.
|
||||
# (We first open the file and replace all occurences of [] with _
|
||||
# (We first open the file and replace all occurrences of [] with _
|
||||
# because CMake will fail to parse a line containing unmatched brackets...
|
||||
# also the \ to escaped \n in macros screws up things.)
|
||||
# https://public.kitware.com/Bug/view.php?id=15369
|
||||
|
@ -329,7 +329,7 @@ foreach (GCOV_FILE ${GCOV_FILES})
|
|||
# Instead of trying to parse the source from the
|
||||
# gcov file, simply read the file contents from the source file.
|
||||
# (Parsing it from the gcov is hard because C-code uses ; in many places
|
||||
# which also happens to be the same as the CMake list delimeter).
|
||||
# which also happens to be the same as the CMake list delimiter).
|
||||
file(READ ${GCOV_SRC_PATH} GCOV_FILE_SOURCE)
|
||||
|
||||
string(REPLACE "\\" "\\\\" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
||||
|
|
|
@ -56,18 +56,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
using namespace Assimp;
|
||||
|
||||
static const unsigned int NotSet = 0xcdcdcdcd;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Setup final material indices, generae a default material if necessary
|
||||
void Discreet3DSImporter::ReplaceDefaultMaterial()
|
||||
{
|
||||
|
||||
// Try to find an existing material that matches the
|
||||
// typical default material setting:
|
||||
// - no textures
|
||||
// - diffuse color (in grey!)
|
||||
// NOTE: This is here to workaround the fact that some
|
||||
// exporters are writing a default material, too.
|
||||
unsigned int idx = 0xcdcdcdcd;
|
||||
unsigned int idx( NotSet );
|
||||
for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
|
||||
{
|
||||
std::string s = mScene->mMaterials[i].mName;
|
||||
|
@ -93,7 +94,9 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
|
|||
}
|
||||
idx = i;
|
||||
}
|
||||
if (0xcdcdcdcd == idx)idx = (unsigned int)mScene->mMaterials.size();
|
||||
if ( NotSet == idx ) {
|
||||
idx = ( unsigned int )mScene->mMaterials.size();
|
||||
}
|
||||
|
||||
// now iterate through all meshes and through all faces and
|
||||
// find all faces that are using the default material
|
||||
|
|
|
@ -39,7 +39,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
||||
|
||||
|
@ -151,7 +150,7 @@ namespace {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
|
||||
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
||||
{
|
||||
std::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
|
||||
if(!outfile) {
|
||||
|
@ -210,6 +209,12 @@ Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr<IOStream> outfile, con
|
|||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Discreet3DSExporter::~Discreet3DSExporter() {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling_level)
|
||||
{
|
||||
|
|
|
@ -60,23 +60,21 @@ namespace Assimp
|
|||
{
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** Helper class to export a given scene to a 3DS file. */
|
||||
/**
|
||||
* @brief Helper class to export a given scene to a 3DS file.
|
||||
*/
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class Discreet3DSExporter
|
||||
{
|
||||
class Discreet3DSExporter {
|
||||
public:
|
||||
Discreet3DSExporter(std::shared_ptr<IOStream> outfile, const aiScene* pScene);
|
||||
~Discreet3DSExporter();
|
||||
|
||||
private:
|
||||
|
||||
void WriteMeshes();
|
||||
void WriteMaterials();
|
||||
void 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);
|
||||
void WriteString(const aiString& s);
|
||||
void WriteColor(const aiColor3D& color);
|
||||
|
@ -84,7 +82,6 @@ private:
|
|||
void WritePercentChunk(double f);
|
||||
|
||||
private:
|
||||
|
||||
const aiScene* const scene;
|
||||
StreamWriterLE writer;
|
||||
|
||||
|
@ -95,6 +92,6 @@ private:
|
|||
|
||||
};
|
||||
|
||||
}
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif
|
||||
#endif // AI_3DSEXPORTER_H_INC
|
||||
|
|
|
@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef AI_3DSFILEHELPER_H_INC
|
||||
#define AI_3DSFILEHELPER_H_INC
|
||||
|
||||
|
||||
#include "SpatialSort.h"
|
||||
#include "SmoothingGroups.h"
|
||||
#include "StringUtils.h"
|
||||
|
@ -64,16 +63,19 @@ namespace D3DS {
|
|||
/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
|
||||
* and data structures.
|
||||
*/
|
||||
class Discreet3DS
|
||||
{
|
||||
class Discreet3DS {
|
||||
private:
|
||||
inline Discreet3DS() {}
|
||||
Discreet3DS() {
|
||||
// empty
|
||||
}
|
||||
|
||||
~Discreet3DS() {
|
||||
// empty
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! data structure for a single chunk in a .3ds file
|
||||
struct Chunk
|
||||
{
|
||||
struct Chunk {
|
||||
uint16_t Flag;
|
||||
uint32_t Size;
|
||||
} PACK_STRUCT;
|
||||
|
|
|
@ -1381,7 +1381,7 @@ void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent )
|
|||
bGamma = true;
|
||||
|
||||
case Discreet3DS::CHUNK_RGBF:
|
||||
if (sizeof(ai_real) * 3 > diff) {
|
||||
if (sizeof(float) * 3 > diff) {
|
||||
*out = clrError;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2017, 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
|
||||
|
||||
namespace Assimp {
|
||||
namespace D3MF {
|
||||
|
||||
namespace XmlTag {
|
||||
static const std::string model = "model";
|
||||
static const std::string model_unit = "unit";
|
||||
static const std::string metadata = "metadata";
|
||||
static const std::string resources = "resources";
|
||||
static const std::string object = "object";
|
||||
static const std::string mesh = "mesh";
|
||||
static const std::string vertices = "vertices";
|
||||
static const std::string vertex = "vertex";
|
||||
static const std::string triangles = "triangles";
|
||||
static const std::string triangle = "triangle";
|
||||
static const std::string x = "x";
|
||||
static const std::string y = "y";
|
||||
static const std::string z = "z";
|
||||
static const std::string v1 = "v1";
|
||||
static const std::string v2 = "v2";
|
||||
static const std::string v3 = "v3";
|
||||
static const std::string id = "id";
|
||||
static const std::string name = "name";
|
||||
static const std::string type = "type";
|
||||
static const std::string build = "build";
|
||||
static const std::string item = "item";
|
||||
static const std::string objectid = "objectid";
|
||||
static const std::string transform = "transform";
|
||||
|
||||
static const std::string CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
|
||||
static const std::string ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
|
||||
static const std::string SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
|
||||
static const std::string SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
|
||||
static const std::string RELS_RELATIONSHIP_CONTAINER = "Relationships";
|
||||
static const std::string RELS_RELATIONSHIP_NODE = "Relationship";
|
||||
static const std::string RELS_ATTRIB_TARGET = "Target";
|
||||
static const std::string RELS_ATTRIB_TYPE = "Type";
|
||||
static const std::string RELS_ATTRIB_ID = "Id";
|
||||
static const std::string PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
|
||||
static const std::string PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
|
||||
static const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
|
||||
static const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
|
||||
static const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
|
||||
|
||||
}
|
||||
|
||||
} // Namespace D3MF
|
||||
} // Namespace Assimp
|
|
@ -249,7 +249,7 @@ private:
|
|||
|
||||
/// \fn size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A)
|
||||
/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
|
||||
/// converted texture will be returned. Convertion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
|
||||
/// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
|
||||
/// to converted textures list.
|
||||
/// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified.
|
||||
/// \param [in] pID_R - ID of source "red" texture.
|
||||
|
@ -378,7 +378,7 @@ private:
|
|||
void XML_CheckNode_MustHaveChildren();
|
||||
|
||||
/// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName)
|
||||
/// Chek if current node name is equal to pNodeName.
|
||||
/// Check if current node name is equal to pNodeName.
|
||||
/// \param [in] pNodeName - name for checking.
|
||||
/// return true if current node name is equal to pNodeName, else - false.
|
||||
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
|
||||
|
|
|
@ -137,7 +137,7 @@ struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement
|
|||
{
|
||||
/****************** Variables ******************/
|
||||
|
||||
std::string ObjectID;///< ID of object for instanciation.
|
||||
std::string ObjectID;///< ID of object for instantiation.
|
||||
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
|
||||
/// create an instance of the object in the current constellation.
|
||||
aiVector3D Delta;
|
||||
|
|
|
@ -60,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp
|
||||
{
|
||||
|
||||
aiColor4D AMFImporter::SPP_Material::GetColor(const float pX, const float pY, const float pZ) const
|
||||
aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*pY*/, const float /*pZ*/) const
|
||||
{
|
||||
aiColor4D tcol;
|
||||
|
||||
|
@ -281,8 +281,11 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
|
|||
{
|
||||
if(!pID.empty())
|
||||
{
|
||||
for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++)
|
||||
converted_texture.Data[idx_target] = src_texture[pSrcTexNum]->Data.at(idx_src);
|
||||
for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) {
|
||||
CAMFImporter_NodeElement_Texture* tex = src_texture[pSrcTexNum];
|
||||
ai_assert(tex);
|
||||
converted_texture.Data[idx_target] = tex->Data.at(idx_src);
|
||||
}
|
||||
}
|
||||
};// auto CopyTextureData = [&](const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void
|
||||
|
||||
|
@ -686,7 +689,6 @@ std::list<unsigned int> mesh_idx;
|
|||
tmesh->mNumVertices = static_cast<unsigned int>(vert_arr.size());
|
||||
tmesh->mVertices = new aiVector3D[tmesh->mNumVertices];
|
||||
tmesh->mColors[0] = new aiColor4D[tmesh->mNumVertices];
|
||||
tmesh->mFaces = new aiFace[face_list_cur.size()];
|
||||
|
||||
memcpy(tmesh->mVertices, vert_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D));
|
||||
memcpy(tmesh->mColors[0], col_arr.data(), tmesh->mNumVertices * sizeof(aiColor4D));
|
||||
|
|
|
@ -1021,6 +1021,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
|
|||
|
||||
// convert bones, if existing
|
||||
if (!mesh.mBones.empty()) {
|
||||
ai_assert(avOutputBones);
|
||||
// check whether there is a vertex weight for this vertex index
|
||||
if (iIndex2 < mesh.mBoneVertices.size()) {
|
||||
|
||||
|
|
|
@ -139,6 +139,17 @@ inline size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v)
|
|||
return t;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// Serialize a color value
|
||||
template <>
|
||||
inline size_t Write<aiColor3D>(IOStream * stream, const aiColor3D& v)
|
||||
{
|
||||
size_t t = Write<float>(stream,v.r);
|
||||
t += Write<float>(stream,v.g);
|
||||
t += Write<float>(stream,v.b);
|
||||
return t;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// Serialize a color value
|
||||
template <>
|
||||
|
@ -160,6 +171,7 @@ inline size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v)
|
|||
t += Write<float>(stream,v.x);
|
||||
t += Write<float>(stream,v.y);
|
||||
t += Write<float>(stream,v.z);
|
||||
ai_assert(t == 16);
|
||||
return 16;
|
||||
}
|
||||
|
||||
|
@ -325,7 +337,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
|||
{
|
||||
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE );
|
||||
|
||||
size_t nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
|
||||
unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
|
||||
|
||||
Write<aiString>(&chunk,node->mName);
|
||||
Write<aiMatrix4x4>(&chunk,node->mTransformation);
|
||||
|
@ -639,9 +651,9 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
|||
Write<float>(&chunk,l->mAttenuationQuadratic);
|
||||
}
|
||||
|
||||
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorDiffuse);
|
||||
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorSpecular);
|
||||
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorAmbient);
|
||||
Write<aiColor3D>(&chunk,l->mColorDiffuse);
|
||||
Write<aiColor3D>(&chunk,l->mColorSpecular);
|
||||
Write<aiColor3D>(&chunk,l->mColorAmbient);
|
||||
|
||||
if (l->mType == aiLightSource_SPOT) {
|
||||
Write<float>(&chunk,l->mAngleInnerCone);
|
||||
|
@ -799,7 +811,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
|||
}
|
||||
};
|
||||
|
||||
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
||||
{
|
||||
AssbinExport exporter;
|
||||
exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
|
||||
|
|
|
@ -200,6 +200,7 @@ template <typename T> void ReadBounds( IOStream * stream, T* /*p*/, unsigned int
|
|||
|
||||
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) {
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AINODE);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
@ -274,6 +275,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* p
|
|||
void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
|
||||
{
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
@ -298,6 +300,7 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
|
|||
void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
||||
{
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
@ -423,6 +426,7 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
|||
void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop)
|
||||
{
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
@ -440,6 +444,7 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro
|
|||
void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
|
||||
{
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
@ -462,6 +467,7 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
|
|||
void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
|
||||
{
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
@ -511,6 +517,7 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
|
|||
void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
|
||||
{
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
@ -532,6 +539,7 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
|
|||
void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
|
||||
{
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
@ -556,6 +564,7 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
|
|||
void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
|
||||
{
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
@ -583,6 +592,7 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
|
|||
void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
|
||||
{
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
@ -599,6 +609,7 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
|
|||
void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
||||
{
|
||||
uint32_t chunkID = Read<uint32_t>(stream);
|
||||
(void)(chunkID);
|
||||
ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
|
||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||
|
||||
|
|
|
@ -71,7 +71,6 @@ class AssbinImporter : public BaseImporter
|
|||
private:
|
||||
bool shortened;
|
||||
bool compressed;
|
||||
protected:
|
||||
|
||||
public:
|
||||
virtual bool CanRead(
|
||||
|
|
|
@ -631,7 +631,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
|
|||
|
||||
} // end of namespace AssxmlExport
|
||||
|
||||
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
||||
{
|
||||
IOStream * out = pIOSystem->Open( pFile, "wt" );
|
||||
if (!out) return;
|
||||
|
|
|
@ -82,6 +82,19 @@ static const aiImporterDesc desc = {
|
|||
|
||||
//#define DEBUG_B3D
|
||||
|
||||
template<typename T>
|
||||
void DeleteAllBarePointers(std::vector<T>& x)
|
||||
{
|
||||
for(auto p : x)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
B3DImporter::~B3DImporter()
|
||||
{
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool B3DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const{
|
||||
|
||||
|
@ -157,7 +170,8 @@ int B3DImporter::ReadByte(){
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
int B3DImporter::ReadInt(){
|
||||
if( _pos+4<=_buf.size() ){
|
||||
int n=*(int*)&_buf[_pos];
|
||||
int n;
|
||||
memcpy(&n, &_buf[_pos], 4);
|
||||
_pos+=4;
|
||||
return n;
|
||||
}
|
||||
|
@ -168,7 +182,8 @@ int B3DImporter::ReadInt(){
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
float B3DImporter::ReadFloat(){
|
||||
if( _pos+4<=_buf.size() ){
|
||||
float n=*(float*)&_buf[_pos];
|
||||
float n;
|
||||
memcpy(&n, &_buf[_pos], 4);
|
||||
_pos+=4;
|
||||
return n;
|
||||
}
|
||||
|
@ -251,6 +266,21 @@ T *B3DImporter::to_array( const vector<T> &v ){
|
|||
return p;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template<class T>
|
||||
T **unique_to_array( vector<std::unique_ptr<T> > &v ){
|
||||
if( v.empty() ) {
|
||||
return 0;
|
||||
}
|
||||
T **p = new T*[ v.size() ];
|
||||
for( size_t i = 0; i < v.size(); ++i ){
|
||||
p[i] = v[i].release();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void B3DImporter::ReadTEXS(){
|
||||
while( ChunkSize() ){
|
||||
|
@ -279,8 +309,7 @@ void B3DImporter::ReadBRUS(){
|
|||
/*int blend=**/ReadInt();
|
||||
int fx=ReadInt();
|
||||
|
||||
aiMaterial *mat=new aiMaterial;
|
||||
_materials.push_back( mat );
|
||||
std::unique_ptr<aiMaterial> mat(new aiMaterial);
|
||||
|
||||
// Name
|
||||
aiString ainame( name );
|
||||
|
@ -317,6 +346,7 @@ void B3DImporter::ReadBRUS(){
|
|||
mat->AddProperty( &texname,AI_MATKEY_TEXTURE_DIFFUSE(0) );
|
||||
}
|
||||
}
|
||||
_materials.emplace_back( std::move(mat) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,8 +400,7 @@ void B3DImporter::ReadTRIS( int v0 ){
|
|||
Fail( "Bad material id" );
|
||||
}
|
||||
|
||||
aiMesh *mesh=new aiMesh;
|
||||
_meshes.push_back( mesh );
|
||||
std::unique_ptr<aiMesh> mesh(new aiMesh);
|
||||
|
||||
mesh->mMaterialIndex=matid;
|
||||
mesh->mNumFaces=0;
|
||||
|
@ -399,6 +428,8 @@ void B3DImporter::ReadTRIS( int v0 ){
|
|||
++mesh->mNumFaces;
|
||||
++face;
|
||||
}
|
||||
|
||||
_meshes.emplace_back( std::move(mesh) );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -484,11 +515,11 @@ void B3DImporter::ReadANIM(){
|
|||
int frames=ReadInt();
|
||||
float fps=ReadFloat();
|
||||
|
||||
aiAnimation *anim=new aiAnimation;
|
||||
_animations.push_back( anim );
|
||||
std::unique_ptr<aiAnimation> anim(new aiAnimation);
|
||||
|
||||
anim->mDuration=frames;
|
||||
anim->mTicksPerSecond=fps;
|
||||
_animations.emplace_back( std::move(anim) );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -515,7 +546,7 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
|
|||
node->mParent=parent;
|
||||
node->mTransformation=tform;
|
||||
|
||||
aiNodeAnim *nodeAnim=0;
|
||||
std::unique_ptr<aiNodeAnim> nodeAnim;
|
||||
vector<unsigned> meshes;
|
||||
vector<aiNode*> children;
|
||||
|
||||
|
@ -533,11 +564,10 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
|
|||
ReadANIM();
|
||||
}else if( t=="KEYS" ){
|
||||
if( !nodeAnim ){
|
||||
nodeAnim=new aiNodeAnim;
|
||||
_nodeAnims.push_back( nodeAnim );
|
||||
nodeAnim.reset(new aiNodeAnim);
|
||||
nodeAnim->mNodeName=node->mName;
|
||||
}
|
||||
ReadKEYS( nodeAnim );
|
||||
ReadKEYS( nodeAnim.get() );
|
||||
}else if( t=="NODE" ){
|
||||
aiNode *child=ReadNODE( node );
|
||||
children.push_back( child );
|
||||
|
@ -545,6 +575,10 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
|
|||
ExitChunk();
|
||||
}
|
||||
|
||||
if (nodeAnim) {
|
||||
_nodeAnims.emplace_back( std::move(nodeAnim) );
|
||||
}
|
||||
|
||||
node->mNumMeshes= static_cast<unsigned int>(meshes.size());
|
||||
node->mMeshes=to_array( meshes );
|
||||
|
||||
|
@ -558,13 +592,18 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
|
|||
void B3DImporter::ReadBB3D( aiScene *scene ){
|
||||
|
||||
_textures.clear();
|
||||
|
||||
_materials.clear();
|
||||
|
||||
_vertices.clear();
|
||||
|
||||
_meshes.clear();
|
||||
|
||||
DeleteAllBarePointers(_nodes);
|
||||
_nodes.clear();
|
||||
|
||||
_nodeAnims.clear();
|
||||
|
||||
_animations.clear();
|
||||
|
||||
string t=ReadChunk();
|
||||
|
@ -600,7 +639,7 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
|
|||
aiNode *node=_nodes[i];
|
||||
|
||||
for( size_t j=0;j<node->mNumMeshes;++j ){
|
||||
aiMesh *mesh=_meshes[node->mMeshes[j]];
|
||||
aiMesh *mesh = _meshes[node->mMeshes[j]].get();
|
||||
|
||||
int n_tris=mesh->mNumFaces;
|
||||
int n_verts=mesh->mNumVertices=n_tris * 3;
|
||||
|
@ -663,27 +702,28 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
|
|||
|
||||
//nodes
|
||||
scene->mRootNode=_nodes[0];
|
||||
_nodes.clear(); // node ownership now belongs to scene
|
||||
|
||||
//material
|
||||
if( !_materials.size() ){
|
||||
_materials.push_back( new aiMaterial );
|
||||
_materials.emplace_back( std::unique_ptr<aiMaterial>(new aiMaterial) );
|
||||
}
|
||||
scene->mNumMaterials= static_cast<unsigned int>(_materials.size());
|
||||
scene->mMaterials=to_array( _materials );
|
||||
scene->mMaterials = unique_to_array( _materials );
|
||||
|
||||
//meshes
|
||||
scene->mNumMeshes= static_cast<unsigned int>(_meshes.size());
|
||||
scene->mMeshes=to_array( _meshes );
|
||||
scene->mMeshes = unique_to_array( _meshes );
|
||||
|
||||
//animations
|
||||
if( _animations.size()==1 && _nodeAnims.size() ){
|
||||
|
||||
aiAnimation *anim=_animations.back();
|
||||
aiAnimation *anim = _animations.back().get();
|
||||
anim->mNumChannels=static_cast<unsigned int>(_nodeAnims.size());
|
||||
anim->mChannels=to_array( _nodeAnims );
|
||||
anim->mChannels = unique_to_array( _nodeAnims );
|
||||
|
||||
scene->mNumAnimations=static_cast<unsigned int>(_animations.size());
|
||||
scene->mAnimations=to_array( _animations );
|
||||
scene->mAnimations=unique_to_array( _animations );
|
||||
}
|
||||
|
||||
// convert to RH
|
||||
|
|
|
@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/material.h>
|
||||
#include "BaseImporter.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
struct aiNodeAnim;
|
||||
|
@ -59,6 +60,8 @@ namespace Assimp{
|
|||
|
||||
class B3DImporter : public BaseImporter{
|
||||
public:
|
||||
B3DImporter() = default;
|
||||
virtual ~B3DImporter();
|
||||
|
||||
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
||||
|
||||
|
@ -114,15 +117,15 @@ private:
|
|||
std::vector<unsigned> _stack;
|
||||
|
||||
std::vector<std::string> _textures;
|
||||
std::vector<aiMaterial*> _materials;
|
||||
std::vector<std::unique_ptr<aiMaterial> > _materials;
|
||||
|
||||
int _vflags,_tcsets,_tcsize;
|
||||
std::vector<Vertex> _vertices;
|
||||
|
||||
std::vector<aiNode*> _nodes;
|
||||
std::vector<aiMesh*> _meshes;
|
||||
std::vector<aiNodeAnim*> _nodeAnims;
|
||||
std::vector<aiAnimation*> _animations;
|
||||
std::vector<std::unique_ptr<aiMesh> > _meshes;
|
||||
std::vector<std::unique_ptr<aiNodeAnim> > _nodeAnims;
|
||||
std::vector<std::unique_ptr<aiAnimation> > _animations;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -89,12 +89,12 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
|
|||
FileSystemFilter filter(pFile,pIOHandler);
|
||||
|
||||
// create a scene object to hold the data
|
||||
ScopeGuard<aiScene> sc(new aiScene());
|
||||
std::unique_ptr<aiScene> sc(new aiScene());
|
||||
|
||||
// dispatch importing
|
||||
try
|
||||
{
|
||||
InternReadFile( pFile, sc, &filter);
|
||||
InternReadFile( pFile, sc.get(), &filter);
|
||||
|
||||
} catch( const std::exception& err ) {
|
||||
// extract error description
|
||||
|
@ -104,8 +104,7 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
|
|||
}
|
||||
|
||||
// return what we gathered from the import.
|
||||
sc.dismiss();
|
||||
return sc;
|
||||
return sc.release();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -65,42 +65,6 @@ class IOStream;
|
|||
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
|
||||
(string[1] << 16) + (string[2] << 8) + string[3]))
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct ScopeGuard
|
||||
{
|
||||
explicit ScopeGuard(T* obj) : obj(obj), mdismiss() {}
|
||||
~ScopeGuard () throw() {
|
||||
if (!mdismiss) {
|
||||
delete obj;
|
||||
}
|
||||
obj = NULL;
|
||||
}
|
||||
|
||||
T* dismiss() {
|
||||
mdismiss=true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
operator T*() {
|
||||
return obj;
|
||||
}
|
||||
|
||||
T* operator -> () {
|
||||
return obj;
|
||||
}
|
||||
|
||||
private:
|
||||
// no copying allowed.
|
||||
ScopeGuard();
|
||||
ScopeGuard( const ScopeGuard & );
|
||||
ScopeGuard &operator = ( const ScopeGuard & );
|
||||
|
||||
T* obj;
|
||||
bool mdismiss;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface
|
||||
|
|
|
@ -102,7 +102,7 @@ namespace Assimp {
|
|||
offset += Copy(&data[offset], header.size);
|
||||
offset += Copy(&data[offset], header.reserved1);
|
||||
offset += Copy(&data[offset], header.reserved2);
|
||||
offset += Copy(&data[offset], header.offset);
|
||||
Copy(&data[offset], header.offset);
|
||||
|
||||
file->Write(data, Header::header_size, 1);
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ namespace Assimp {
|
|||
offset += Copy(&data[offset], dib.x_resolution);
|
||||
offset += Copy(&data[offset], dib.y_resolution);
|
||||
offset += Copy(&data[offset], dib.nb_colors);
|
||||
offset += Copy(&data[offset], dib.nb_important_colors);
|
||||
Copy(&data[offset], dib.nb_important_colors);
|
||||
|
||||
file->Write(data, DIB::dib_size, 1);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace Assimp
|
||||
{
|
||||
template< > const std::string LogFunctions< BlenderBMeshConverter >::log_prefix = "BLEND_BMESH: ";
|
||||
template< > const char* LogFunctions< BlenderBMeshConverter >::Prefix()
|
||||
{
|
||||
static auto prefix = "BLEND_BMESH: ";
|
||||
return prefix;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace Assimp;
|
||||
|
|
|
@ -92,6 +92,12 @@ struct Error : DeadlyImportError {
|
|||
* descendents. It serves as base class for all data structure fields. */
|
||||
// -------------------------------------------------------------------------------
|
||||
struct ElemBase {
|
||||
ElemBase()
|
||||
: dna_type(nullptr)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
virtual ~ElemBase() {
|
||||
// empty
|
||||
}
|
||||
|
@ -253,7 +259,7 @@ public:
|
|||
* a compiler complain is the result.
|
||||
* @param dest Destination value to be written
|
||||
* @param db File database, including input stream. */
|
||||
template <typename T> inline void Convert (T& dest, const FileDatabase& db) const;
|
||||
template <typename T> void Convert (T& dest, const FileDatabase& db) const;
|
||||
|
||||
// --------------------------------------------------------
|
||||
// generic converter
|
||||
|
|
|
@ -585,11 +585,14 @@ template <> inline void Structure :: Convert<int> (int& dest,const FileDataba
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <> inline void Structure :: Convert<short> (short& dest,const FileDatabase& db) const
|
||||
template<> inline void Structure :: Convert<short> (short& dest,const FileDatabase& db) const
|
||||
{
|
||||
// automatic rescaling from short to float and vice versa (seems to be used by normals)
|
||||
if (name == "float") {
|
||||
dest = static_cast<short>(db.reader->GetF4() * 32767.f);
|
||||
float f = db.reader->GetF4();
|
||||
if ( f > 1.0f )
|
||||
f = 1.0f;
|
||||
dest = static_cast<short>( f * 32767.f);
|
||||
//db.reader->IncPtr(-4);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ namespace Blender {
|
|||
void operator= (const TempArray&) {
|
||||
}
|
||||
|
||||
TempArray(const TempArray& arr) {
|
||||
TempArray(const TempArray& /*arr*/) {
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -74,7 +74,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#endif
|
||||
|
||||
namespace Assimp {
|
||||
template<> const std::string LogFunctions<BlenderImporter>::log_prefix = "BLEND: ";
|
||||
template<> const char* LogFunctions<BlenderImporter>::Prefix()
|
||||
{
|
||||
static auto prefix = "BLEND: ";
|
||||
return prefix;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace Assimp;
|
||||
|
@ -1144,7 +1148,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* cam, ConversionData& /*conv_data*/)
|
||||
{
|
||||
ScopeGuard<aiCamera> out(new aiCamera());
|
||||
std::unique_ptr<aiCamera> out(new aiCamera());
|
||||
out->mName = obj->id.name+2;
|
||||
out->mPosition = aiVector3D(0.f, 0.f, 0.f);
|
||||
out->mUp = aiVector3D(0.f, 1.f, 0.f);
|
||||
|
@ -1155,13 +1159,13 @@ aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj,
|
|||
out->mClipPlaneNear = cam->clipsta;
|
||||
out->mClipPlaneFar = cam->clipend;
|
||||
|
||||
return out.dismiss();
|
||||
return out.release();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, const Lamp* lamp, ConversionData& /*conv_data*/)
|
||||
{
|
||||
ScopeGuard<aiLight> out(new aiLight());
|
||||
std::unique_ptr<aiLight> out(new aiLight());
|
||||
out->mName = obj->id.name+2;
|
||||
|
||||
switch (lamp->type)
|
||||
|
@ -1199,7 +1203,7 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
|
|||
out->mColorAmbient = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||
out->mColorSpecular = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||
out->mColorDiffuse = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||
return out.dismiss();
|
||||
return out.release();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -1217,7 +1221,7 @@ aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, Convers
|
|||
++it;
|
||||
}
|
||||
|
||||
ScopeGuard<aiNode> node(new aiNode(obj->id.name+2)); // skip over the name prefix 'OB'
|
||||
std::unique_ptr<aiNode> node(new aiNode(obj->id.name+2)); // skip over the name prefix 'OB'
|
||||
if (obj->data) {
|
||||
switch (obj->type)
|
||||
{
|
||||
|
@ -1301,14 +1305,14 @@ aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, Convers
|
|||
aiNode** nd = node->mChildren = new aiNode*[node->mNumChildren]();
|
||||
for (const Object* nobj :children) {
|
||||
*nd = ConvertNode(in,nobj,conv_data,node->mTransformation * parentTransform);
|
||||
(*nd++)->mParent = node;
|
||||
(*nd++)->mParent = node.get();
|
||||
}
|
||||
}
|
||||
|
||||
// apply modifiers
|
||||
modifier_cache->ApplyModifiers(*node,conv_data,in,*obj);
|
||||
|
||||
return node.dismiss();
|
||||
return node.release();
|
||||
}
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||
|
|
|
@ -310,7 +310,9 @@ void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data
|
|||
|
||||
std::unique_ptr<Subdivider> subd(Subdivider::Create(algo));
|
||||
ai_assert(subd);
|
||||
|
||||
if ( conv_data.meshes->empty() ) {
|
||||
return;
|
||||
}
|
||||
aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
|
||||
std::unique_ptr<aiMesh*[]> tempmeshes(new aiMesh*[out.mNumMeshes]());
|
||||
|
||||
|
|
|
@ -59,7 +59,9 @@ template <> void Structure :: Convert<Object> (
|
|||
{
|
||||
|
||||
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
||||
int temp = 0;
|
||||
ReadField<ErrorPolicy_Fail>(temp,"type",db);
|
||||
dest.type = static_cast<Assimp::Blender::Object::Type>(temp);
|
||||
ReadFieldArray2<ErrorPolicy_Warn>(dest.obmat,"obmat",db);
|
||||
ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
|
||||
ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
|
||||
|
@ -100,14 +102,21 @@ template <> void Structure :: Convert<MTex> (
|
|||
) const
|
||||
{
|
||||
|
||||
ReadField<ErrorPolicy_Igno>((short&)dest.mapto,"mapto",db);
|
||||
ReadField<ErrorPolicy_Igno>((int&)dest.blendtype,"blendtype",db);
|
||||
int temp_short = 0;
|
||||
ReadField<ErrorPolicy_Igno>(temp_short,"mapto",db);
|
||||
dest.mapto = static_cast<Assimp::Blender::MTex::MapType>(temp_short);
|
||||
int temp = 0;
|
||||
ReadField<ErrorPolicy_Igno>(temp,"blendtype",db);
|
||||
dest.blendtype = static_cast<Assimp::Blender::MTex::BlendType>(temp);
|
||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.object,"*object",db);
|
||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.tex,"*tex",db);
|
||||
ReadFieldArray<ErrorPolicy_Igno>(dest.uvname,"uvname",db);
|
||||
ReadField<ErrorPolicy_Igno>((int&)dest.projx,"projx",db);
|
||||
ReadField<ErrorPolicy_Igno>((int&)dest.projy,"projy",db);
|
||||
ReadField<ErrorPolicy_Igno>((int&)dest.projz,"projz",db);
|
||||
ReadField<ErrorPolicy_Igno>(temp,"projx",db);
|
||||
dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
|
||||
ReadField<ErrorPolicy_Igno>(temp,"projy",db);
|
||||
dest.projy = static_cast<Assimp::Blender::MTex::Projection>(temp);
|
||||
ReadField<ErrorPolicy_Igno>(temp,"projz",db);
|
||||
dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
|
||||
ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
|
||||
ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
|
||||
ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
|
||||
|
@ -190,7 +199,9 @@ template <> void Structure :: Convert<Lamp> (
|
|||
{
|
||||
|
||||
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
||||
int temp = 0;
|
||||
ReadField<ErrorPolicy_Fail>(temp,"type",db);
|
||||
dest.type = static_cast<Assimp::Blender::Lamp::Type>(temp);
|
||||
ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
|
||||
ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
|
||||
ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
|
||||
|
@ -204,7 +215,8 @@ template <> void Structure :: Convert<Lamp> (
|
|||
ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
|
||||
ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
|
||||
ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
|
||||
ReadField<ErrorPolicy_Igno>((int&)dest.falloff_type,"falloff_type",db);
|
||||
ReadField<ErrorPolicy_Igno>(temp,"falloff_type",db);
|
||||
dest.falloff_type = static_cast<Assimp::Blender::Lamp::FalloffType>(temp);
|
||||
ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
|
||||
ReadField<ErrorPolicy_Igno>(dest.area_size,"area_size",db);
|
||||
ReadField<ErrorPolicy_Igno>(dest.area_sizey,"area_sizey",db);
|
||||
|
@ -693,8 +705,12 @@ template <> void Structure :: Convert<Tex> (
|
|||
const FileDatabase& db
|
||||
) const
|
||||
{
|
||||
ReadField<ErrorPolicy_Igno>((short&)dest.imaflag,"imaflag",db);
|
||||
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
||||
short temp_short = 0;
|
||||
ReadField<ErrorPolicy_Igno>(temp_short,"imaflag",db);
|
||||
dest.imaflag = static_cast<Assimp::Blender::Tex::ImageFlags>(temp_short);
|
||||
int temp = 0;
|
||||
ReadField<ErrorPolicy_Fail>(temp,"type",db);
|
||||
dest.type = static_cast<Assimp::Blender::Tex::Type>(temp);
|
||||
ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
|
||||
|
||||
db.reader->IncPtr(size);
|
||||
|
@ -708,8 +724,11 @@ template <> void Structure :: Convert<Camera> (
|
|||
{
|
||||
|
||||
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||
ReadField<ErrorPolicy_Warn>((int&)dest.type,"type",db);
|
||||
ReadField<ErrorPolicy_Warn>((int&)dest.flag,"flag",db);
|
||||
int temp = 0;
|
||||
ReadField<ErrorPolicy_Warn>(temp,"type",db);
|
||||
dest.type = static_cast<Assimp::Blender::Camera::Type>(temp);
|
||||
ReadField<ErrorPolicy_Warn>(temp,"flag",db);
|
||||
dest.flag = static_cast<Assimp::Blender::Camera::Type>(temp);
|
||||
ReadField<ErrorPolicy_Warn>(dest.lens,"lens",db);
|
||||
ReadField<ErrorPolicy_Warn>(dest.sensor_x,"sensor_x",db);
|
||||
ReadField<ErrorPolicy_Igno>(dest.clipsta,"clipsta",db);
|
||||
|
|
|
@ -225,6 +225,14 @@ struct TFace : ElemBase {
|
|||
|
||||
// -------------------------------------------------------------------------------
|
||||
struct MTFace : ElemBase {
|
||||
MTFace()
|
||||
: flag(0)
|
||||
, mode(0)
|
||||
, tile(0)
|
||||
, unwrap(0)
|
||||
{
|
||||
}
|
||||
|
||||
float uv[4][2] FAIL;
|
||||
char flag;
|
||||
short mode;
|
||||
|
|
|
@ -59,7 +59,11 @@ static const unsigned int BLEND_TESS_MAGIC = 0x83ed9ac3;
|
|||
|
||||
namspace Assimp
|
||||
{
|
||||
template< > const std::string LogFunctions< BlenderTessellatorGL >::log_prefix = "BLEND_TESS_GL: ";
|
||||
template< > const char* LogFunctions< BlenderTessellatorGL >::Prefix()
|
||||
{
|
||||
static auto prefix = "BLEND_TESS_GL: ";
|
||||
return prefix;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace Assimp;
|
||||
|
@ -252,7 +256,11 @@ void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* )
|
|||
|
||||
namespace Assimp
|
||||
{
|
||||
template< > const std::string LogFunctions< BlenderTessellatorP2T >::log_prefix = "BLEND_TESS_P2T: ";
|
||||
template< > const char* LogFunctions< BlenderTessellatorP2T >::Prefix()
|
||||
{
|
||||
static auto prefix = "BLEND_TESS_P2T: ";
|
||||
return prefix;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace Assimp;
|
||||
|
|
|
@ -185,11 +185,11 @@ void C4DImporter::InternReadFile( const std::string& pFile,
|
|||
if(mesh->mMaterialIndex >= mat_count) {
|
||||
++mat_count;
|
||||
|
||||
ScopeGuard<aiMaterial> def_material(new aiMaterial());
|
||||
std::unique_ptr<aiMaterial> def_material(new aiMaterial());
|
||||
const aiString name(AI_DEFAULT_MATERIAL_NAME);
|
||||
def_material->AddProperty(&name, AI_MATKEY_NAME);
|
||||
|
||||
materials.push_back(def_material.dismiss());
|
||||
materials.push_back(def_material.release());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
|||
const CPolygon* polys = polyObject->GetPolygonR();
|
||||
ai_assert(polys != NULL);
|
||||
|
||||
ScopeGuard<aiMesh> mesh(new aiMesh());
|
||||
std::unique_ptr<aiMesh> mesh(new aiMesh());
|
||||
mesh->mNumFaces = static_cast<unsigned int>(polyCount);
|
||||
aiFace* face = mesh->mFaces = new aiFace[mesh->mNumFaces]();
|
||||
|
||||
|
@ -616,7 +616,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
|||
}
|
||||
|
||||
mesh->mMaterialIndex = ResolveMaterial(polyObject);
|
||||
return mesh.dismiss();
|
||||
return mesh.release();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ SET( PUBLIC_HEADERS
|
|||
${HEADER_PATH}/color4.inl
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h
|
||||
${HEADER_PATH}/defs.h
|
||||
${HEADER_PATH}/Defines.h
|
||||
${HEADER_PATH}/cfileio.h
|
||||
${HEADER_PATH}/light.h
|
||||
${HEADER_PATH}/material.h
|
||||
|
@ -155,6 +156,8 @@ SET( Common_SRCS
|
|||
SkeletonMeshBuilder.h
|
||||
SplitByBoneCountProcess.cpp
|
||||
SplitByBoneCountProcess.h
|
||||
ScaleProcess.cpp
|
||||
ScaleProcess.h
|
||||
SmoothingGroups.h
|
||||
StandardShapes.cpp
|
||||
StandardShapes.h
|
||||
|
@ -665,6 +668,8 @@ ADD_ASSIMP_IMPORTER( GLTF
|
|||
glTF2Asset.inl
|
||||
glTF2AssetWriter.h
|
||||
glTF2AssetWriter.inl
|
||||
glTF2Importer.cpp
|
||||
glTF2Importer.h
|
||||
glTF2Exporter.h
|
||||
glTF2Exporter.cpp
|
||||
)
|
||||
|
@ -672,8 +677,11 @@ ADD_ASSIMP_IMPORTER( GLTF
|
|||
ADD_ASSIMP_IMPORTER( 3MF
|
||||
D3MFImporter.h
|
||||
D3MFImporter.cpp
|
||||
D3MFExporter.h
|
||||
D3MFExporter.cpp
|
||||
D3MFOpcPackage.h
|
||||
D3MFOpcPackage.cpp
|
||||
3MFXmlTags.h
|
||||
)
|
||||
|
||||
ADD_ASSIMP_IMPORTER( MMD
|
||||
|
@ -735,6 +743,14 @@ SET( unzip_SRCS
|
|||
)
|
||||
SOURCE_GROUP( unzip FILES ${unzip_SRCS})
|
||||
|
||||
SET( ziplib_SRCS
|
||||
../contrib/zip/src/miniz.h
|
||||
../contrib/zip/src/zip.c
|
||||
../contrib/zip/src/zip.h
|
||||
)
|
||||
|
||||
SOURCE_GROUP( ziplib FILES ${ziplib_SRCS} )
|
||||
|
||||
SET ( openddl_parser_SRCS
|
||||
../contrib/openddlparser/code/OpenDDLParser.cpp
|
||||
../contrib/openddlparser/code/DDLNode.cpp
|
||||
|
@ -846,6 +862,7 @@ SET( assimp_src
|
|||
${Clipper_SRCS}
|
||||
${openddl_parser_SRCS}
|
||||
${open3dgc_SRCS}
|
||||
${ziplib_SRCS}
|
||||
# Necessary to show the headers in the project when using the VC++ generator:
|
||||
|
||||
${PUBLIC_HEADERS}
|
||||
|
@ -909,8 +926,27 @@ SET_TARGET_PROPERTIES( assimp PROPERTIES
|
|||
)
|
||||
|
||||
if (APPLE)
|
||||
SET_TARGET_PROPERTIES( assimp PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${ASSIMP_LIB_INSTALL_DIR}")
|
||||
endif()
|
||||
SET_TARGET_PROPERTIES( assimp PROPERTIES
|
||||
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${ASSIMP_LIB_INSTALL_DIR}"
|
||||
)
|
||||
|
||||
if (BUILD_FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES( assimp PROPERTIES
|
||||
FRAMEWORK TRUE
|
||||
FRAMEWORK_VERSION C
|
||||
MACOSX_FRAMEWORK_IDENTIFIER net.sf.assimp
|
||||
PUBLIC_HEADER "${PUBLIC_HEADERS}"
|
||||
)
|
||||
|
||||
# PUBLIC_HEADER option does not support directory structure creation
|
||||
# add ./Compiler/*.h to assimp.framework via copy command
|
||||
ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
"../${HEADER_PATH}/Compiler"
|
||||
assimp.framework/Headers/Compiler
|
||||
COMMENT "Copying public ./Compiler/ header files to framework bundle's Headers/Compiler/")
|
||||
endif(BUILD_FRAMEWORK)
|
||||
endif(APPLE)
|
||||
|
||||
# Build against external unzip, or add ../contrib/unzip so
|
||||
# assimp can #include "unzip.h"
|
||||
|
@ -930,9 +966,11 @@ INSTALL( TARGETS assimp
|
|||
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
|
||||
FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
COMPONENT ${LIBASSIMP_COMPONENT})
|
||||
INSTALL( FILES ${PUBLIC_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp COMPONENT assimp-dev)
|
||||
INSTALL( FILES ${COMPILER_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp/Compiler COMPONENT assimp-dev)
|
||||
|
||||
if (ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||
INSTALL(FILES ${HEADER_PATH}/${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/AndroidJNIIOSystem.h
|
||||
DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace Assimp
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
|
||||
void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||
void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
||||
{
|
||||
std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
|
||||
std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
|
||||
|
@ -76,6 +76,10 @@ void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* p
|
|||
// invoke the exporter
|
||||
ColladaExporter iDoTheExportThing( pScene, pIOSystem, path, file);
|
||||
|
||||
if (iDoTheExportThing.mOutput.fail()) {
|
||||
throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
|
||||
}
|
||||
|
||||
// we're still here - export successfully completed. Write result to the given IOSYstem
|
||||
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||
if(outfile == NULL) {
|
||||
|
@ -104,7 +108,7 @@ ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, co
|
|||
// set up strings
|
||||
endstr = "\n";
|
||||
|
||||
// start writing
|
||||
// start writing the file
|
||||
WriteFile();
|
||||
}
|
||||
|
||||
|
@ -138,6 +142,9 @@ void ColladaExporter::WriteFile()
|
|||
|
||||
WriteSceneLibrary();
|
||||
|
||||
// customized, Writes the animation library
|
||||
WriteAnimationsLibrary();
|
||||
|
||||
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
|
||||
mOutput << startstr << "<scene>" << endstr;
|
||||
PushTag();
|
||||
|
@ -866,8 +873,8 @@ void ColladaExporter::WriteController( size_t pIndex)
|
|||
|
||||
std::vector<ai_real> bind_poses;
|
||||
bind_poses.reserve(mesh->mNumBones * 16);
|
||||
for( size_t i = 0; i < mesh->mNumBones; ++i)
|
||||
for( size_t j = 0; j < 4; ++j)
|
||||
for(unsigned int i = 0; i < mesh->mNumBones; ++i)
|
||||
for( unsigned int j = 0; j < 4; ++j)
|
||||
bind_poses.insert(bind_poses.end(), mesh->mBones[i]->mOffsetMatrix[j], mesh->mBones[i]->mOffsetMatrix[j] + 4);
|
||||
|
||||
WriteFloatArray( idstr + "-skin-bind_poses", FloatType_Mat4x4, (const ai_real*) bind_poses.data(), bind_poses.size() / 16);
|
||||
|
@ -924,11 +931,11 @@ void ColladaExporter::WriteController( size_t pIndex)
|
|||
|
||||
ai_uint weight_index = 0;
|
||||
std::vector<ai_int> joint_weight_indices(2 * joint_weight_indices_length, (ai_int)-1);
|
||||
for( size_t i = 0; i < mesh->mNumBones; ++i)
|
||||
for( size_t j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
|
||||
for( unsigned int i = 0; i < mesh->mNumBones; ++i)
|
||||
for( unsigned j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
|
||||
{
|
||||
unsigned int vId = mesh->mBones[i]->mWeights[j].mVertexId;
|
||||
for( size_t k = 0; k < num_influences[vId]; ++k)
|
||||
for( ai_uint k = 0; k < num_influences[vId]; ++k)
|
||||
{
|
||||
if (joint_weight_indices[2 * (accum_influences[vId] + k)] == -1)
|
||||
{
|
||||
|
@ -1125,6 +1132,7 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
|
|||
case FloatType_Color: floatsPerElement = 3; break;
|
||||
case FloatType_Mat4x4: floatsPerElement = 16; break;
|
||||
case FloatType_Weight: floatsPerElement = 1; break;
|
||||
case FloatType_Time: floatsPerElement = 1; break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -1201,6 +1209,12 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
|
|||
case FloatType_Weight:
|
||||
mOutput << startstr << "<param name=\"WEIGHT\" type=\"float\" />" << endstr;
|
||||
break;
|
||||
|
||||
// customized, add animation related
|
||||
case FloatType_Time:
|
||||
mOutput << startstr << "<param name=\"TIME\" type=\"float\" />" << endstr;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
PopTag();
|
||||
|
@ -1231,7 +1245,172 @@ void ColladaExporter::WriteSceneLibrary()
|
|||
PopTag();
|
||||
mOutput << startstr << "</library_visual_scenes>" << endstr;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
|
||||
{
|
||||
const aiAnimation * anim = mScene->mAnimations[pIndex];
|
||||
|
||||
if ( anim->mNumChannels == 0 && anim->mNumMeshChannels == 0 && anim->mNumMorphMeshChannels ==0 )
|
||||
return;
|
||||
|
||||
const std::string animation_name_escaped = XMLEscape( anim->mName.C_Str() );
|
||||
std::string idstr = anim->mName.C_Str();
|
||||
std::string ending = std::string( "AnimId" ) + to_string(pIndex);
|
||||
if (idstr.length() >= ending.length()) {
|
||||
if (0 != idstr.compare (idstr.length() - ending.length(), ending.length(), ending)) {
|
||||
idstr = idstr + ending;
|
||||
}
|
||||
} else {
|
||||
idstr = idstr + ending;
|
||||
}
|
||||
|
||||
const std::string idstrEscaped = XMLEscape(idstr);
|
||||
|
||||
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
for (size_t a = 0; a < anim->mNumChannels; ++a) {
|
||||
const aiNodeAnim * nodeAnim = anim->mChannels[a];
|
||||
|
||||
// sanity check
|
||||
if ( nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys ) continue;
|
||||
|
||||
{
|
||||
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-input");
|
||||
|
||||
std::vector<ai_real> frames;
|
||||
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
|
||||
frames.push_back(static_cast<ai_real>(nodeAnim->mPositionKeys[i].mTime));
|
||||
}
|
||||
|
||||
WriteFloatArray( node_idstr , FloatType_Time, (const ai_real*) frames.data(), frames.size());
|
||||
frames.clear();
|
||||
}
|
||||
|
||||
{
|
||||
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-output");
|
||||
|
||||
std::vector<ai_real> keyframes;
|
||||
keyframes.reserve(nodeAnim->mNumPositionKeys * 16);
|
||||
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
|
||||
|
||||
aiVector3D Scaling = nodeAnim->mScalingKeys[i].mValue;
|
||||
aiMatrix4x4 ScalingM; // identity
|
||||
ScalingM[0][0] = Scaling.x; ScalingM[1][1] = Scaling.y; ScalingM[2][2] = Scaling.z;
|
||||
|
||||
aiQuaternion RotationQ = nodeAnim->mRotationKeys[i].mValue;
|
||||
aiMatrix4x4 s = aiMatrix4x4( RotationQ.GetMatrix() );
|
||||
aiMatrix4x4 RotationM(s.a1, s.a2, s.a3, 0, s.b1, s.b2, s.b3, 0, s.c1, s.c2, s.c3, 0, 0, 0, 0, 1);
|
||||
|
||||
aiVector3D Translation = nodeAnim->mPositionKeys[i].mValue;
|
||||
aiMatrix4x4 TranslationM; // identity
|
||||
TranslationM[0][3] = Translation.x; TranslationM[1][3] = Translation.y; TranslationM[2][3] = Translation.z;
|
||||
|
||||
// Combine the above transformations
|
||||
aiMatrix4x4 mat = TranslationM * RotationM * ScalingM;
|
||||
|
||||
for( unsigned int j = 0; j < 4; ++j) {
|
||||
keyframes.insert(keyframes.end(), mat[j], mat[j] + 4);
|
||||
}
|
||||
}
|
||||
|
||||
WriteFloatArray( node_idstr, FloatType_Mat4x4, (const ai_real*) keyframes.data(), keyframes.size() / 16);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
for ( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
|
||||
if ( nodeAnim->mPreState == aiAnimBehaviour_DEFAULT
|
||||
|| nodeAnim->mPreState == aiAnimBehaviour_LINEAR
|
||||
|| nodeAnim->mPreState == aiAnimBehaviour_REPEAT
|
||||
) {
|
||||
names.push_back( "LINEAR" );
|
||||
} else if (nodeAnim->mPostState == aiAnimBehaviour_CONSTANT) {
|
||||
names.push_back( "STEP" );
|
||||
}
|
||||
}
|
||||
|
||||
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-interpolation");
|
||||
std::string arrayId = node_idstr + "-array";
|
||||
|
||||
mOutput << startstr << "<source id=\"" << XMLEscape(node_idstr) << "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
// source array
|
||||
mOutput << startstr << "<Name_array id=\"" << XMLEscape(arrayId) << "\" count=\"" << names.size() << "\"> ";
|
||||
for( size_t a = 0; a < names.size(); ++a ) {
|
||||
mOutput << names[a] << " ";
|
||||
}
|
||||
mOutput << "</Name_array>" << endstr;
|
||||
|
||||
mOutput << startstr << "<technique_common>" << endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<accessor source=\"#" << XMLEscape(arrayId) << "\" count=\"" << names.size() << "\" stride=\"" << 1 << "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<param name=\"INTERPOLATION\" type=\"name\"></param>" << endstr;
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</accessor>" << endstr;
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</technique_common>" << endstr;
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</source>" << endstr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (size_t a = 0; a < anim->mNumChannels; ++a) {
|
||||
const aiNodeAnim * nodeAnim = anim->mChannels[a];
|
||||
|
||||
{
|
||||
// samplers
|
||||
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-sampler");
|
||||
mOutput << startstr << "<sampler id=\"" << XMLEscape(node_idstr) << "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<input semantic=\"INPUT\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-input") ) << "\"/>" << endstr;
|
||||
mOutput << startstr << "<input semantic=\"OUTPUT\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-output") ) << "\"/>" << endstr;
|
||||
mOutput << startstr << "<input semantic=\"INTERPOLATION\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-interpolation") ) << "\"/>" << endstr;
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</sampler>" << endstr;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t a = 0; a < anim->mNumChannels; ++a) {
|
||||
const aiNodeAnim * nodeAnim = anim->mChannels[a];
|
||||
|
||||
{
|
||||
// channels
|
||||
mOutput << startstr << "<channel source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-sampler") ) << "\" target=\"" << XMLEscape(nodeAnim->mNodeName.data) << "/matrix\"/>" << endstr;
|
||||
}
|
||||
}
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</animation>" << endstr;
|
||||
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ColladaExporter::WriteAnimationsLibrary()
|
||||
{
|
||||
const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str());
|
||||
|
||||
if ( mScene->mNumAnimations > 0 ) {
|
||||
mOutput << startstr << "<library_animations>" << endstr;
|
||||
PushTag();
|
||||
|
||||
// start recursive write at the root node
|
||||
for( size_t a = 0; a < mScene->mNumAnimations; ++a)
|
||||
WriteAnimationLibrary( a );
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</library_animations>" << endstr;
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Helper to find a bone by name in the scene
|
||||
aiBone* findBone( const aiScene* scene, const char * name) {
|
||||
|
@ -1247,6 +1426,59 @@ aiBone* findBone( const aiScene* scene, const char * name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const aiNode * findBoneNode( const aiNode* aNode, const aiBone* bone)
|
||||
{
|
||||
if ( aNode && bone && aNode->mName == bone->mName ) {
|
||||
return aNode;
|
||||
}
|
||||
|
||||
if ( aNode && bone ) {
|
||||
for (unsigned int i=0; i < aNode->mNumChildren; ++i) {
|
||||
aiNode * aChild = aNode->mChildren[i];
|
||||
const aiNode * foundFromChild = 0;
|
||||
if ( aChild ) {
|
||||
foundFromChild = findBoneNode( aChild, bone );
|
||||
if ( foundFromChild ) return foundFromChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const aiNode * findSkeletonRootNode( const aiScene* scene, const aiMesh * mesh)
|
||||
{
|
||||
std::set<const aiNode*> topParentBoneNodes;
|
||||
if ( mesh && mesh->mNumBones > 0 ) {
|
||||
for (unsigned int i=0; i < mesh->mNumBones; ++i) {
|
||||
aiBone * bone = mesh->mBones[i];
|
||||
|
||||
const aiNode * node = findBoneNode( scene->mRootNode, bone);
|
||||
if ( node ) {
|
||||
while ( node->mParent && findBone(scene, node->mParent->mName.C_Str() ) != 0 ) {
|
||||
node = node->mParent;
|
||||
}
|
||||
topParentBoneNodes.insert( node );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !topParentBoneNodes.empty() ) {
|
||||
const aiNode * parentBoneNode = *topParentBoneNodes.begin();
|
||||
if ( topParentBoneNodes.size() == 1 ) {
|
||||
return parentBoneNode;
|
||||
} else {
|
||||
for (auto it : topParentBoneNodes) {
|
||||
if ( it->mParent ) return it->mParent;
|
||||
}
|
||||
return parentBoneNode;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Recursively writes the given node
|
||||
void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
||||
|
@ -1274,12 +1506,22 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
|||
}
|
||||
|
||||
const std::string node_name_escaped = XMLEscape(pNode->mName.data);
|
||||
/* // customized, Note! the id field is crucial for inter-xml look up, it cannot be replaced with sid ?!
|
||||
mOutput << startstr
|
||||
<< "<node ";
|
||||
if(is_skeleton_root)
|
||||
mOutput << "id=\"" << "skeleton_root" << "\" "; // For now, only support one skeleton in a scene.
|
||||
mOutput << (is_joint ? "s" : "") << "id=\"" << node_name_escaped;
|
||||
mOutput << "\" name=\"" << node_name_escaped
|
||||
*/
|
||||
mOutput << startstr << "<node ";
|
||||
if(is_skeleton_root) {
|
||||
mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"" : "") ; // For now, only support one skeleton in a scene.
|
||||
mFoundSkeletonRootNodeID = node_name_escaped;
|
||||
} else {
|
||||
mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"": "") ;
|
||||
}
|
||||
|
||||
mOutput << " name=\"" << node_name_escaped
|
||||
<< "\" type=\"" << node_type
|
||||
<< "\">" << endstr;
|
||||
PushTag();
|
||||
|
@ -1287,7 +1529,11 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
|||
// write transformation - we can directly put the matrix there
|
||||
// TODO: (thom) decompose into scale - rot - quad to allow addressing it by animations afterwards
|
||||
const aiMatrix4x4& mat = pNode->mTransformation;
|
||||
mOutput << startstr << "<matrix sid=\"transform\">";
|
||||
|
||||
// customized, sid should be 'matrix' to match with loader code.
|
||||
//mOutput << startstr << "<matrix sid=\"transform\">";
|
||||
mOutput << startstr << "<matrix sid=\"matrix\">";
|
||||
|
||||
mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " ";
|
||||
mOutput << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << " ";
|
||||
mOutput << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << " ";
|
||||
|
@ -1315,7 +1561,7 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
|||
for( size_t a = 0; a < pNode->mNumMeshes; ++a )
|
||||
{
|
||||
const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]];
|
||||
// do not instanciate mesh if empty. I wonder how this could happen
|
||||
// do not instantiate mesh if empty. I wonder how this could happen
|
||||
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
|
||||
continue;
|
||||
|
||||
|
@ -1331,7 +1577,13 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
|||
<< endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<skeleton>#skeleton_root</skeleton>" << endstr;
|
||||
// note! this mFoundSkeletonRootNodeID some how affects animation, it makes the mesh attaches to armature skeleton root node.
|
||||
// use the first bone to find skeleton root
|
||||
const aiNode * skeletonRootBoneNode = findSkeletonRootNode( pScene, mesh );
|
||||
if ( skeletonRootBoneNode ) {
|
||||
mFoundSkeletonRootNodeID = XMLEscape( skeletonRootBoneNode->mName.C_Str() );
|
||||
}
|
||||
mOutput << startstr << "<skeleton>#" << mFoundSkeletonRootNodeID << "</skeleton>" << endstr;
|
||||
}
|
||||
mOutput << startstr << "<bind_material>" << endstr;
|
||||
PushTag();
|
||||
|
|
|
@ -114,7 +114,9 @@ protected:
|
|||
/// Writes the given mesh
|
||||
void WriteGeometry( size_t pIndex);
|
||||
|
||||
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight };
|
||||
//enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight };
|
||||
// customized to add animation related type
|
||||
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight, FloatType_Time };
|
||||
|
||||
/// Writes a float array of the given type
|
||||
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const ai_real* pData, size_t pElementCount);
|
||||
|
@ -122,6 +124,11 @@ protected:
|
|||
/// Writes the scene library
|
||||
void WriteSceneLibrary();
|
||||
|
||||
// customized, Writes the animation library
|
||||
void WriteAnimationsLibrary();
|
||||
void WriteAnimationLibrary( size_t pIndex);
|
||||
std::string mFoundSkeletonRootNodeID = "skeleton_root"; // will be replaced by found node id in the WriteNode call.
|
||||
|
||||
/// Recursively writes the given node
|
||||
void WriteNode( const aiScene* scene, aiNode* pNode);
|
||||
|
||||
|
|
|
@ -302,7 +302,7 @@ struct Accessor
|
|||
size_t mOffset; // in number of values
|
||||
size_t mStride; // Stride in number of values
|
||||
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
|
||||
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, thats XYZ, for a color RGBA and so on.
|
||||
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on.
|
||||
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
|
||||
std::string mSource; // URL of the source array
|
||||
mutable const Data* mData; // Pointer to the source array, if resolved. NULL else
|
||||
|
|
|
@ -119,7 +119,7 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
|
|||
* might be NULL and it's our duty to return true here.
|
||||
*/
|
||||
if (!pIOHandler)return true;
|
||||
const char* tokens[] = {"collada"};
|
||||
const char* tokens[] = {"<collada"};
|
||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
||||
}
|
||||
return false;
|
||||
|
@ -674,7 +674,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|||
// create morph target meshes if any
|
||||
std::vector<aiMesh*> targetMeshes;
|
||||
std::vector<float> targetWeights;
|
||||
Collada::MorphMethod method;
|
||||
Collada::MorphMethod method = Collada::Normalized;
|
||||
|
||||
for(std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
|
||||
it != pParser.mControllerLibrary.end(); it++)
|
||||
|
@ -728,7 +728,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|||
? aiMorphingMethod_MORPH_RELATIVE
|
||||
: aiMorphingMethod_MORPH_NORMALIZED;
|
||||
dstMesh->mAnimMeshes = new aiAnimMesh*[animMeshes.size()];
|
||||
dstMesh->mNumAnimMeshes = animMeshes.size();
|
||||
dstMesh->mNumAnimMeshes = static_cast<unsigned int>(animMeshes.size());
|
||||
for (unsigned int i = 0; i < animMeshes.size(); i++)
|
||||
dstMesh->mAnimMeshes[i] = animMeshes.at(i);
|
||||
}
|
||||
|
@ -1377,9 +1377,9 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
|||
{
|
||||
aiNodeAnim* dstAnim = new aiNodeAnim;
|
||||
dstAnim->mNodeName = nodeName;
|
||||
dstAnim->mNumPositionKeys = resultTrafos.size();
|
||||
dstAnim->mNumRotationKeys= resultTrafos.size();
|
||||
dstAnim->mNumScalingKeys = resultTrafos.size();
|
||||
dstAnim->mNumPositionKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||
dstAnim->mNumRotationKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||
dstAnim->mNumScalingKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||
dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()];
|
||||
dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()];
|
||||
dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()];
|
||||
|
@ -1445,11 +1445,11 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
|||
++morphAnimChannelIndex;
|
||||
}
|
||||
|
||||
morphAnim->mNumKeys = morphTimeValues.size();
|
||||
morphAnim->mNumKeys = static_cast<unsigned int>(morphTimeValues.size());
|
||||
morphAnim->mKeys = new aiMeshMorphKey[morphAnim->mNumKeys];
|
||||
for (unsigned int key = 0; key < morphAnim->mNumKeys; key++)
|
||||
{
|
||||
morphAnim->mKeys[key].mNumValuesAndWeights = morphChannels.size();
|
||||
morphAnim->mKeys[key].mNumValuesAndWeights = static_cast<unsigned int>(morphChannels.size());
|
||||
morphAnim->mKeys[key].mValues = new unsigned int [morphChannels.size()];
|
||||
morphAnim->mKeys[key].mWeights = new double [morphChannels.size()];
|
||||
|
||||
|
@ -1470,13 +1470,13 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
|||
{
|
||||
aiAnimation* anim = new aiAnimation;
|
||||
anim->mName.Set( pName);
|
||||
anim->mNumChannels = anims.size();
|
||||
anim->mNumChannels = static_cast<unsigned int>(anims.size());
|
||||
if (anim->mNumChannels > 0)
|
||||
{
|
||||
anim->mChannels = new aiNodeAnim*[anims.size()];
|
||||
std::copy( anims.begin(), anims.end(), anim->mChannels);
|
||||
}
|
||||
anim->mNumMorphMeshChannels = morphAnims.size();
|
||||
anim->mNumMorphMeshChannels = static_cast<unsigned int>(morphAnims.size());
|
||||
if (anim->mNumMorphMeshChannels > 0)
|
||||
{
|
||||
anim->mMorphMeshChannels = new aiMeshMorphAnim*[anim->mNumMorphMeshChannels];
|
||||
|
@ -1619,7 +1619,7 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
|
|||
mat.AddProperty( &effect.mRefractIndex, 1, AI_MATKEY_REFRACTI);
|
||||
|
||||
// transparency, a very hard one. seemingly not all files are following the
|
||||
// specification here (1.0 transparency => completly opaque)...
|
||||
// specification here (1.0 transparency => completely opaque)...
|
||||
// therefore, we let the opportunity for the user to manually invert
|
||||
// the transparency if necessary and we add preliminary support for RGB_ZERO mode
|
||||
if(effect.mTransparency >= 0.f && effect.mTransparency <= 1.f) {
|
||||
|
@ -1778,6 +1778,11 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
|
|||
tex->pcData = (aiTexel*)new char[tex->mWidth];
|
||||
memcpy(tex->pcData,&imIt->second.mImageData[0],tex->mWidth);
|
||||
|
||||
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
||||
// In FBX files textures are now stored internally by Assimp with their filename included
|
||||
// Now Assimp can lookup thru the loaded textures after all data is processed
|
||||
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
|
||||
// This may occur on this case too, it has to be studied
|
||||
// setup texture reference string
|
||||
result.data[0] = '*';
|
||||
result.length = 1 + ASSIMP_itoa10(result.data+1,static_cast<unsigned int>(MAXLEN-1),static_cast<int32_t>(mTextures.size()));
|
||||
|
|
|
@ -224,7 +224,7 @@ void ColladaParser::ReadStructure()
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads asset informations such as coordinate system informations and legal blah
|
||||
// Reads asset information such as coordinate system information and legal blah
|
||||
void ColladaParser::ReadAssetInfo()
|
||||
{
|
||||
if( mReader->isEmptyElement())
|
||||
|
@ -2469,8 +2469,7 @@ void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t n
|
|||
size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets;
|
||||
|
||||
// don't overrun the boundaries of the index list
|
||||
size_t maxIndexRequested = baseOffset + numOffsets - 1;
|
||||
ai_assert(maxIndexRequested < indices.size());
|
||||
ai_assert((baseOffset + numOffsets - 1) < indices.size());
|
||||
|
||||
// extract per-vertex channels using the global per-vertex offset
|
||||
for (std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace Assimp
|
|||
/** Reads the structure of the file */
|
||||
void ReadStructure();
|
||||
|
||||
/** Reads asset informations such as coordinate system informations and legal blah */
|
||||
/** Reads asset information such as coordinate system information and legal blah */
|
||||
void ReadAssetInfo();
|
||||
|
||||
/** Reads the animation library */
|
||||
|
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2017, 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.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
|
||||
|
||||
#include "D3MFExporter.h"
|
||||
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
#include "Exceptional.h"
|
||||
#include "3MFXmlTags.h"
|
||||
#include "D3MFOpcPackage.h"
|
||||
|
||||
#include <contrib/zip/src/zip.h>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
void ExportScene3MF( const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/ ) {
|
||||
if ( nullptr == pIOSystem ) {
|
||||
throw DeadlyExportError( "Could not export 3MP archive: " + std::string( pFile ) );
|
||||
}
|
||||
D3MF::D3MFExporter myExporter( pFile, pScene );
|
||||
if ( myExporter.validate() ) {
|
||||
if ( pIOSystem->Exists( pFile ) ) {
|
||||
if ( !pIOSystem->DeleteFile( pFile ) ) {
|
||||
throw DeadlyExportError( "File exists, cannot override : " + std::string( pFile ) );
|
||||
}
|
||||
}
|
||||
bool ok = myExporter.exportArchive(pFile);
|
||||
if ( !ok ) {
|
||||
throw DeadlyExportError( "Could not export 3MP archive: " + std::string( pFile ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace D3MF {
|
||||
|
||||
D3MFExporter::D3MFExporter( const char* pFile, const aiScene* pScene )
|
||||
: mArchiveName( pFile )
|
||||
, m_zipArchive( nullptr )
|
||||
, mScene( pScene )
|
||||
, mModelOutput()
|
||||
, mRelOutput()
|
||||
, mContentOutput()
|
||||
, mBuildItems()
|
||||
, mRelations() {
|
||||
// empty
|
||||
}
|
||||
|
||||
D3MFExporter::~D3MFExporter() {
|
||||
for ( size_t i = 0; i < mRelations.size(); ++i ) {
|
||||
delete mRelations[ i ];
|
||||
}
|
||||
mRelations.clear();
|
||||
}
|
||||
|
||||
bool D3MFExporter::validate() {
|
||||
if ( mArchiveName.empty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( nullptr == mScene ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3MFExporter::exportArchive( const char *file ) {
|
||||
bool ok( true );
|
||||
|
||||
m_zipArchive = zip_open( file, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w' );
|
||||
if ( nullptr == m_zipArchive ) {
|
||||
return false;
|
||||
}
|
||||
ok |= exportContentTypes();
|
||||
ok |= export3DModel();
|
||||
ok |= exportRelations();
|
||||
|
||||
zip_close( m_zipArchive );
|
||||
m_zipArchive = nullptr;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
bool D3MFExporter::exportContentTypes() {
|
||||
mContentOutput.clear();
|
||||
|
||||
mContentOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||
mContentOutput << std::endl;
|
||||
mContentOutput << "<Types xmlns = \"http://schemas.openxmlformats.org/package/2006/content-types\">";
|
||||
mContentOutput << std::endl;
|
||||
mContentOutput << "<Default Extension = \"rels\" ContentType = \"application/vnd.openxmlformats-package.relationships+xml\" />";
|
||||
mContentOutput << std::endl;
|
||||
mContentOutput << "<Default Extension = \"model\" ContentType = \"application/vnd.ms-package.3dmanufacturing-3dmodel+xml\" />";
|
||||
mContentOutput << std::endl;
|
||||
mContentOutput << "</Types>";
|
||||
mContentOutput << std::endl;
|
||||
exportContentTyp( XmlTag::CONTENT_TYPES_ARCHIVE );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3MFExporter::exportRelations() {
|
||||
mRelOutput.clear();
|
||||
|
||||
mRelOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||
mRelOutput << std::endl;
|
||||
mRelOutput << "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
|
||||
|
||||
for ( size_t i = 0; i < mRelations.size(); ++i ) {
|
||||
mRelOutput << "<Relationship Target=\"/" << mRelations[ i ]->target << "\" ";
|
||||
mRelOutput << "Id=\"" << mRelations[i]->id << "\" ";
|
||||
mRelOutput << "Type=\"" << mRelations[ i ]->type << "\" />";
|
||||
mRelOutput << std::endl;
|
||||
}
|
||||
mRelOutput << "</Relationships>";
|
||||
mRelOutput << std::endl;
|
||||
|
||||
writeRelInfoToFile( "_rels", ".rels" );
|
||||
mRelOutput.flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3MFExporter::export3DModel() {
|
||||
mModelOutput.clear();
|
||||
|
||||
writeHeader();
|
||||
mModelOutput << "<" << XmlTag::model << " " << XmlTag::model_unit << "=\"millimeter\""
|
||||
<< "xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\">"
|
||||
<< std::endl;
|
||||
mModelOutput << "<" << XmlTag::resources << ">";
|
||||
mModelOutput << std::endl;
|
||||
|
||||
writeObjects();
|
||||
|
||||
|
||||
mModelOutput << "</" << XmlTag::resources << ">";
|
||||
mModelOutput << std::endl;
|
||||
writeBuild();
|
||||
|
||||
mModelOutput << "</" << XmlTag::model << ">\n";
|
||||
|
||||
OpcPackageRelationship *info = new OpcPackageRelationship;
|
||||
info->id = "rel0";
|
||||
info->target = "/3D/3DModel.model";
|
||||
info->type = XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
|
||||
mRelations.push_back( info );
|
||||
|
||||
writeModelToArchive( "3D", "3DModel.model" );
|
||||
mModelOutput.flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3MFExporter::writeHeader() {
|
||||
mModelOutput << "<?xml version=\"1.0\" encoding=\"UTF - 8\"?>";
|
||||
mModelOutput << std::endl;
|
||||
}
|
||||
|
||||
void D3MFExporter::writeObjects() {
|
||||
if ( nullptr == mScene->mRootNode ) {
|
||||
return;
|
||||
}
|
||||
|
||||
aiNode *root = mScene->mRootNode;
|
||||
for ( unsigned int i = 0; i < root->mNumChildren; ++i ) {
|
||||
aiNode *currentNode( root->mChildren[ i ] );
|
||||
if ( nullptr == currentNode ) {
|
||||
continue;
|
||||
}
|
||||
mModelOutput << "<" << XmlTag::object << " id=\"" << currentNode->mName.C_Str() << "\" type=\"model\">";
|
||||
mModelOutput << std::endl;
|
||||
for ( unsigned int j = 0; j < currentNode->mNumMeshes; ++j ) {
|
||||
aiMesh *currentMesh = mScene->mMeshes[ currentNode->mMeshes[ j ] ];
|
||||
if ( nullptr == currentMesh ) {
|
||||
continue;
|
||||
}
|
||||
writeMesh( currentMesh );
|
||||
}
|
||||
mBuildItems.push_back( i );
|
||||
|
||||
mModelOutput << "</" << XmlTag::object << ">";
|
||||
mModelOutput << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void D3MFExporter::writeMesh( aiMesh *mesh ) {
|
||||
if ( nullptr == mesh ) {
|
||||
return;
|
||||
}
|
||||
|
||||
mModelOutput << "<" << XmlTag::mesh << ">" << std::endl;
|
||||
mModelOutput << "<" << XmlTag::vertices << ">" << std::endl;
|
||||
for ( unsigned int i = 0; i < mesh->mNumVertices; ++i ) {
|
||||
writeVertex( mesh->mVertices[ i ] );
|
||||
}
|
||||
mModelOutput << "</" << XmlTag::vertices << ">" << std::endl;
|
||||
|
||||
writeFaces( mesh );
|
||||
|
||||
mModelOutput << "</" << XmlTag::mesh << ">" << std::endl;
|
||||
}
|
||||
|
||||
void D3MFExporter::writeVertex( const aiVector3D &pos ) {
|
||||
mModelOutput << "<" << XmlTag::vertex << " x=\"" << pos.x << "\" y=\"" << pos.y << "\" z=\"" << pos.z << "\" />";
|
||||
mModelOutput << std::endl;
|
||||
}
|
||||
|
||||
void D3MFExporter::writeFaces( aiMesh *mesh ) {
|
||||
if ( nullptr == mesh ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !mesh->HasFaces() ) {
|
||||
return;
|
||||
}
|
||||
mModelOutput << "<" << XmlTag::triangles << ">" << std::endl;
|
||||
for ( unsigned int i = 0; i < mesh->mNumFaces; ++i ) {
|
||||
aiFace ¤tFace = mesh->mFaces[ i ];
|
||||
mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[ 0 ] << "\" v2=\""
|
||||
<< currentFace.mIndices[ 1 ] << "\" v3=\"" << currentFace.mIndices[ 2 ] << "\"/>";
|
||||
mModelOutput << std::endl;
|
||||
}
|
||||
mModelOutput << "</" << XmlTag::triangles << ">";
|
||||
mModelOutput << std::endl;
|
||||
}
|
||||
|
||||
void D3MFExporter::writeBuild() {
|
||||
mModelOutput << "<" << XmlTag::build << ">" << std::endl;
|
||||
|
||||
for ( size_t i = 0; i < mBuildItems.size(); ++i ) {
|
||||
mModelOutput << "<" << XmlTag::item << " objectid=\"" << i + 1 << "\"/>";
|
||||
mModelOutput << std::endl;
|
||||
}
|
||||
mModelOutput << "</" << XmlTag::build << ">";
|
||||
mModelOutput << std::endl;
|
||||
}
|
||||
|
||||
void D3MFExporter::exportContentTyp( const std::string &filename ) {
|
||||
if ( nullptr == m_zipArchive ) {
|
||||
throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." );
|
||||
}
|
||||
const std::string entry = filename;
|
||||
zip_entry_open( m_zipArchive, entry.c_str() );
|
||||
|
||||
const std::string &exportTxt( mContentOutput.str() );
|
||||
zip_entry_write( m_zipArchive, exportTxt.c_str(), exportTxt.size() );
|
||||
|
||||
zip_entry_close( m_zipArchive );
|
||||
}
|
||||
|
||||
void D3MFExporter::writeModelToArchive( const std::string &folder, const std::string &modelName ) {
|
||||
if ( nullptr == m_zipArchive ) {
|
||||
throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." );
|
||||
}
|
||||
const std::string entry = folder + "/" + modelName;
|
||||
zip_entry_open( m_zipArchive, entry.c_str() );
|
||||
|
||||
const std::string &exportTxt( mModelOutput.str() );
|
||||
zip_entry_write( m_zipArchive, exportTxt.c_str(), exportTxt.size() );
|
||||
|
||||
zip_entry_close( m_zipArchive );
|
||||
}
|
||||
|
||||
void D3MFExporter::writeRelInfoToFile( const std::string &folder, const std::string &relName ) {
|
||||
if ( nullptr == m_zipArchive ) {
|
||||
throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." );
|
||||
}
|
||||
const std::string entry = folder + "/" + relName;
|
||||
zip_entry_open( m_zipArchive, entry.c_str() );
|
||||
|
||||
const std::string &exportTxt( mRelOutput.str() );
|
||||
zip_entry_write( m_zipArchive, exportTxt.c_str(), exportTxt.size() );
|
||||
|
||||
zip_entry_close( m_zipArchive );
|
||||
}
|
||||
|
||||
|
||||
} // Namespace D3MF
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_3MF_EXPORTER
|
||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2017, 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 <memory>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <assimp/vector3.h>
|
||||
|
||||
struct aiScene;
|
||||
struct aiNode;
|
||||
struct aiMaterial;
|
||||
struct aiMesh;
|
||||
|
||||
struct zip_t;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
class IOStream;
|
||||
|
||||
namespace D3MF {
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
|
||||
|
||||
struct OpcPackageRelationship;
|
||||
|
||||
class D3MFExporter {
|
||||
public:
|
||||
D3MFExporter( const char* pFile, const aiScene* pScene );
|
||||
~D3MFExporter();
|
||||
bool validate();
|
||||
bool exportArchive( const char *file );
|
||||
bool exportContentTypes();
|
||||
bool exportRelations();
|
||||
bool export3DModel();
|
||||
|
||||
protected:
|
||||
void writeHeader();
|
||||
void writeObjects();
|
||||
void writeMesh( aiMesh *mesh );
|
||||
void writeVertex( const aiVector3D &pos );
|
||||
void writeFaces( aiMesh *mesh );
|
||||
void writeBuild();
|
||||
void exportContentTyp( const std::string &filename );
|
||||
void writeModelToArchive( const std::string &folder, const std::string &modelName );
|
||||
void writeRelInfoToFile( const std::string &folder, const std::string &relName );
|
||||
|
||||
private:
|
||||
std::string mArchiveName;
|
||||
zip_t *m_zipArchive;
|
||||
const aiScene *mScene;
|
||||
std::ostringstream mModelOutput;
|
||||
std::ostringstream mRelOutput;
|
||||
std::ostringstream mContentOutput;
|
||||
std::vector<unsigned int> mBuildItems;
|
||||
std::vector<OpcPackageRelationship*> mRelations;
|
||||
};
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_3MF_EXPORTER
|
||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||
|
||||
} // Namespace D3MF
|
||||
} // Namespace Assimp
|
||||
|
|
@ -59,42 +59,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "D3MFOpcPackage.h"
|
||||
#include <contrib/unzip/unzip.h>
|
||||
#include "irrXMLWrapper.h"
|
||||
#include "3MFXmlTags.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace D3MF {
|
||||
|
||||
namespace XmlTag {
|
||||
static const std::string model = "model";
|
||||
static const std::string metadata = "metadata";
|
||||
static const std::string resources = "resources";
|
||||
static const std::string object = "object";
|
||||
static const std::string mesh = "mesh";
|
||||
static const std::string vertices = "vertices";
|
||||
static const std::string vertex = "vertex";
|
||||
static const std::string triangles = "triangles";
|
||||
static const std::string triangle = "triangle";
|
||||
static const std::string x = "x";
|
||||
static const std::string y = "y";
|
||||
static const std::string z = "z";
|
||||
static const std::string v1 = "v1";
|
||||
static const std::string v2 = "v2";
|
||||
static const std::string v3 = "v3";
|
||||
static const std::string id = "id";
|
||||
static const std::string name = "name";
|
||||
static const std::string type = "type";
|
||||
static const std::string build = "build";
|
||||
static const std::string item = "item";
|
||||
static const std::string objectid = "objectid";
|
||||
static const std::string transform = "transform";
|
||||
}
|
||||
|
||||
|
||||
class XmlSerializer
|
||||
{
|
||||
class XmlSerializer {
|
||||
public:
|
||||
XmlSerializer(XmlReader* xmlReader)
|
||||
: xmlReader(xmlReader)
|
||||
{
|
||||
: xmlReader(xmlReader) {
|
||||
// empty
|
||||
}
|
||||
|
||||
~XmlSerializer() {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -102,22 +79,17 @@ public:
|
|||
scene->mRootNode = new aiNode();
|
||||
std::vector<aiNode*> children;
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::model))
|
||||
{
|
||||
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::object)
|
||||
{
|
||||
while(ReadToEndElement(D3MF::XmlTag::model)) {
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::object) {
|
||||
children.push_back(ReadObject(scene));
|
||||
}
|
||||
else if(xmlReader->getNodeName() == D3MF::XmlTag::build)
|
||||
{
|
||||
} else if(xmlReader->getNodeName() == D3MF::XmlTag::build) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(scene->mRootNode->mName.length == 0)
|
||||
scene->mRootNode->mName.Set("3MF");
|
||||
|
||||
if ( scene->mRootNode->mName.length == 0 ) {
|
||||
scene->mRootNode->mName.Set( "3MF" );
|
||||
}
|
||||
|
||||
scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
|
||||
scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
|
||||
|
@ -128,13 +100,12 @@ public:
|
|||
scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
|
||||
|
||||
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
aiNode* ReadObject(aiScene* scene)
|
||||
{
|
||||
ScopeGuard<aiNode> node(new aiNode());
|
||||
std::unique_ptr<aiNode> node(new aiNode());
|
||||
|
||||
std::vector<unsigned long> meshIds;
|
||||
|
||||
|
@ -174,14 +145,12 @@ private:
|
|||
|
||||
std::copy(meshIds.begin(), meshIds.end(), node->mMeshes);
|
||||
|
||||
return node.dismiss();
|
||||
return node.release();
|
||||
|
||||
}
|
||||
|
||||
aiMesh* ReadMesh()
|
||||
{
|
||||
aiMesh* ReadMesh() {
|
||||
aiMesh* mesh = new aiMesh();
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::mesh))
|
||||
{
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::vertices)
|
||||
|
@ -192,10 +161,8 @@ private:
|
|||
{
|
||||
ImportTriangles(mesh);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
@ -216,6 +183,7 @@ private:
|
|||
std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
|
||||
|
||||
}
|
||||
|
||||
aiVector3D ReadVertex()
|
||||
{
|
||||
aiVector3D vertex;
|
||||
|
@ -261,7 +229,6 @@ private:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
bool ReadToStartElement(const std::string& startTag)
|
||||
{
|
||||
while(xmlReader->read())
|
||||
|
@ -305,6 +272,7 @@ private:
|
|||
|
||||
} //namespace D3MF
|
||||
|
||||
static const std::string Extension = "3mf";
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
"3mf Importer",
|
||||
|
@ -316,24 +284,22 @@ static const aiImporterDesc desc = {
|
|||
0,
|
||||
0,
|
||||
0,
|
||||
"3mf"
|
||||
Extension.c_str()
|
||||
};
|
||||
|
||||
|
||||
D3MFImporter::D3MFImporter()
|
||||
{
|
||||
|
||||
: BaseImporter() {
|
||||
// empty
|
||||
}
|
||||
|
||||
D3MFImporter::~D3MFImporter()
|
||||
{
|
||||
|
||||
D3MFImporter::~D3MFImporter() {
|
||||
// empty
|
||||
}
|
||||
|
||||
bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const
|
||||
{
|
||||
bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
|
||||
const std::string extension = GetExtension(pFile);
|
||||
if(extension == "3mf") {
|
||||
if(extension == Extension ) {
|
||||
return true;
|
||||
} else if ( !extension.length() || checkSig ) {
|
||||
if (nullptr == pIOHandler ) {
|
||||
|
@ -344,18 +310,15 @@ bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool
|
|||
return false;
|
||||
}
|
||||
|
||||
void D3MFImporter::SetupProperties(const Importer *pImp)
|
||||
{
|
||||
|
||||
void D3MFImporter::SetupProperties(const Importer * /*pImp*/) {
|
||||
// empty
|
||||
}
|
||||
|
||||
const aiImporterDesc *D3MFImporter::GetInfo() const
|
||||
{
|
||||
const aiImporterDesc *D3MFImporter::GetInfo() const {
|
||||
return &desc;
|
||||
}
|
||||
|
||||
void D3MFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler)
|
||||
{
|
||||
void D3MFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
||||
D3MF::D3MFOpcPackage opcPackage(pIOHandler, pFile);
|
||||
|
||||
std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(opcPackage.RootStream()));
|
||||
|
|
|
@ -46,21 +46,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace Assimp {
|
||||
|
||||
class D3MFImporter : public BaseImporter
|
||||
{
|
||||
class D3MFImporter : public BaseImporter {
|
||||
public:
|
||||
// BaseImporter interface
|
||||
D3MFImporter();
|
||||
~D3MFImporter();
|
||||
|
||||
// BaseImporter interface
|
||||
public:
|
||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
|
||||
void SetupProperties(const Importer *pImp);
|
||||
const aiImporterDesc *GetInfo() const;
|
||||
|
||||
protected:
|
||||
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // AI_D3MFLOADER_H_INCLUDED
|
||||
|
|
|
@ -55,48 +55,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include <contrib/unzip/unzip.h>
|
||||
#include "3MFXmlTags.h"
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
namespace D3MF {
|
||||
|
||||
namespace XmlTag {
|
||||
static const std::string CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
|
||||
static const std::string ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
|
||||
static const std::string SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
|
||||
static const std::string SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
|
||||
static const std::string RELS_RELATIONSHIP_CONTAINER = "Relationships";
|
||||
static const std::string RELS_RELATIONSHIP_NODE = "Relationship";
|
||||
static const std::string RELS_ATTRIB_TARGET = "Target";
|
||||
static const std::string RELS_ATTRIB_TYPE = "Type";
|
||||
static const std::string RELS_ATTRIB_ID = "Id";
|
||||
static const std::string PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
|
||||
static const std::string PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
|
||||
static const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
|
||||
static const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
|
||||
static const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
|
||||
}
|
||||
|
||||
class IOSystem2Unzip {
|
||||
|
||||
public:
|
||||
|
||||
public:
|
||||
static voidpf open(voidpf opaque, const char* filename, int mode);
|
||||
|
||||
static uLong read(voidpf opaque, voidpf stream, void* buf, uLong size);
|
||||
|
||||
static uLong write(voidpf opaque, voidpf stream, const void* buf, uLong size);
|
||||
|
||||
static long tell(voidpf opaque, voidpf stream);
|
||||
|
||||
static long seek(voidpf opaque, voidpf stream, uLong offset, int origin);
|
||||
|
||||
static int close(voidpf opaque, voidpf stream);
|
||||
|
||||
static int testerror(voidpf opaque, voidpf stream);
|
||||
|
||||
static zlib_filefunc_def get(IOSystem* pIOHandler);
|
||||
};
|
||||
|
||||
|
@ -116,7 +90,6 @@ voidpf IOSystem2Unzip::open(voidpf opaque, const char* filename, int mode) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return (voidpf) io_system->Open(filename, mode_fopen);
|
||||
}
|
||||
|
||||
|
@ -186,44 +159,33 @@ zlib_filefunc_def IOSystem2Unzip::get(IOSystem* pIOHandler) {
|
|||
return mapping;
|
||||
}
|
||||
|
||||
|
||||
class ZipFile : public IOStream
|
||||
{
|
||||
class ZipFile : public IOStream {
|
||||
friend class D3MFZipArchive;
|
||||
|
||||
public:
|
||||
explicit ZipFile(size_t size);
|
||||
|
||||
~ZipFile();
|
||||
|
||||
virtual ~ZipFile();
|
||||
size_t Read(void* pvBuffer, size_t pSize, size_t pCount );
|
||||
|
||||
size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/);
|
||||
|
||||
size_t FileSize() const;
|
||||
|
||||
aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/);
|
||||
|
||||
size_t Tell() const;
|
||||
|
||||
void Flush();
|
||||
|
||||
private:
|
||||
|
||||
void* m_Buffer;
|
||||
|
||||
void *m_Buffer;
|
||||
size_t m_Size;
|
||||
|
||||
};
|
||||
|
||||
ZipFile::ZipFile(size_t size) : m_Size(size) {
|
||||
ZipFile::ZipFile(size_t size)
|
||||
: m_Buffer( nullptr )
|
||||
, m_Size(size) {
|
||||
ai_assert(m_Size != 0);
|
||||
|
||||
m_Buffer = malloc(m_Size);
|
||||
m_Buffer = ::malloc(m_Size);
|
||||
}
|
||||
|
||||
ZipFile::~ZipFile() {
|
||||
free(m_Buffer);
|
||||
::free(m_Buffer);
|
||||
m_Buffer = NULL;
|
||||
}
|
||||
|
||||
|
@ -236,8 +198,12 @@ size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount) {
|
|||
return size;
|
||||
}
|
||||
|
||||
size_t ZipFile::Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) {
|
||||
return 0;
|
||||
size_t ZipFile::Write(const void* pvBuffer, size_t size, size_t pCount ) {
|
||||
const size_t size_to_write( size * pCount );
|
||||
if ( 0 == size_to_write ) {
|
||||
return 0U;
|
||||
}
|
||||
return 0U;
|
||||
}
|
||||
|
||||
size_t ZipFile::FileSize() const {
|
||||
|
@ -256,55 +222,36 @@ void ZipFile::Flush() {
|
|||
// empty
|
||||
}
|
||||
|
||||
|
||||
class D3MFZipArchive : public IOSystem
|
||||
{
|
||||
class D3MFZipArchive : public IOSystem {
|
||||
public:
|
||||
|
||||
static const unsigned int FileNameSize = 256;
|
||||
|
||||
public:
|
||||
|
||||
D3MFZipArchive(IOSystem* pIOHandler, const std::string & rFile);
|
||||
|
||||
~D3MFZipArchive();
|
||||
|
||||
bool Exists(const char* pFile) const;
|
||||
|
||||
char getOsSeparator() const;
|
||||
|
||||
IOStream* Open(const char* pFile, const char* pMode = "rb");
|
||||
|
||||
void Close(IOStream* pFile);
|
||||
|
||||
bool isOpen() const;
|
||||
|
||||
void getFileList(std::vector<std::string> &rFileList);
|
||||
|
||||
private:
|
||||
|
||||
bool mapArchive();
|
||||
|
||||
private:
|
||||
|
||||
unzFile m_ZipFileHandle;
|
||||
|
||||
std::map<std::string, ZipFile*> m_ArchiveMap;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor.
|
||||
D3MFZipArchive::D3MFZipArchive(IOSystem* pIOHandler, const std::string& rFile)
|
||||
: m_ZipFileHandle(NULL), m_ArchiveMap()
|
||||
{
|
||||
if (! rFile.empty())
|
||||
{
|
||||
: m_ZipFileHandle(NULL)
|
||||
, m_ArchiveMap() {
|
||||
if (! rFile.empty()) {
|
||||
zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler);
|
||||
|
||||
m_ZipFileHandle = unzOpen2(rFile.c_str(), &mapping);
|
||||
|
||||
if(m_ZipFileHandle != NULL) {
|
||||
mapArchive();
|
||||
}
|
||||
|
@ -379,6 +326,7 @@ IOStream *D3MFZipArchive::Open(const char* pFile, const char* /*pMode*/) {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Close a filestream.
|
||||
void D3MFZipArchive::Close(IOStream *pFile) {
|
||||
(void)(pFile);
|
||||
ai_assert(pFile != NULL);
|
||||
|
||||
// We don't do anything in case the file would be opened again in the future
|
||||
|
@ -433,24 +381,12 @@ bool D3MFZipArchive::mapArchive() {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
struct OpcPackageRelationship
|
||||
{
|
||||
std::string id;
|
||||
std::string type;
|
||||
std::string target;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
|
||||
|
||||
class OpcPackageRelationshipReader
|
||||
{
|
||||
class OpcPackageRelationshipReader {
|
||||
public:
|
||||
|
||||
OpcPackageRelationshipReader(XmlReader* xmlReader)
|
||||
{
|
||||
|
||||
while(xmlReader->read())
|
||||
{
|
||||
OpcPackageRelationshipReader(XmlReader* xmlReader) {
|
||||
while(xmlReader->read()) {
|
||||
if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
|
||||
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER)
|
||||
{
|
||||
|
@ -473,57 +409,68 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void ParseAttributes(XmlReader*)
|
||||
{
|
||||
|
||||
void ParseAttributes(XmlReader*) {
|
||||
// empty
|
||||
}
|
||||
|
||||
void ParseChildNode(XmlReader* xmlReader)
|
||||
{
|
||||
bool validateRels( OpcPackageRelationshipPtr &relPtr ) {
|
||||
if ( relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ParseChildNode(XmlReader* xmlReader) {
|
||||
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
|
||||
|
||||
relPtr->id = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_ID.c_str());
|
||||
relPtr->type = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_TYPE.c_str());
|
||||
relPtr->target = xmlReader->getAttributeValue(XmlTag::RELS_ATTRIB_TARGET.c_str());
|
||||
|
||||
m_relationShips.push_back(relPtr);
|
||||
relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str());
|
||||
relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str());
|
||||
relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str());
|
||||
if ( validateRels( relPtr ) ) {
|
||||
m_relationShips.push_back( relPtr );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<OpcPackageRelationshipPtr> m_relationShips;
|
||||
};
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
|
||||
: m_RootStream(nullptr)
|
||||
{
|
||||
zipArchive.reset(new D3MF::D3MFZipArchive( pIOHandler, rFile ));
|
||||
if(!zipArchive->isOpen()) {
|
||||
: mRootStream(nullptr)
|
||||
, mZipArchive() {
|
||||
mZipArchive.reset( new D3MF::D3MFZipArchive( pIOHandler, rFile ) );
|
||||
if(!mZipArchive->isOpen()) {
|
||||
throw DeadlyImportError("Failed to open file " + rFile+ ".");
|
||||
}
|
||||
|
||||
std::vector<std::string> fileList;
|
||||
zipArchive->getFileList(fileList);
|
||||
mZipArchive->getFileList(fileList);
|
||||
|
||||
for(auto& file: fileList){
|
||||
for (auto& file: fileList) {
|
||||
if(file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE) {
|
||||
//PkgRelationshipReader pkgRelReader(file, archive);
|
||||
ai_assert(zipArchive->Exists(file.c_str()));
|
||||
ai_assert(mZipArchive->Exists(file.c_str()));
|
||||
|
||||
IOStream *fileStream = zipArchive->Open(file.c_str());
|
||||
IOStream *fileStream = mZipArchive->Open(file.c_str());
|
||||
|
||||
ai_assert(fileStream != nullptr);
|
||||
|
||||
std::string rootFile = ReadPackageRootRelationship(fileStream);
|
||||
if(rootFile.size() > 0 && rootFile[0] == '/')
|
||||
rootFile = rootFile.substr(1);
|
||||
if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) {
|
||||
rootFile = rootFile.substr( 1 );
|
||||
if ( rootFile[ 0 ] == '/' ) {
|
||||
// deal with zipbug
|
||||
rootFile = rootFile.substr( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
DefaultLogger::get()->debug(rootFile);
|
||||
|
||||
m_RootStream = zipArchive->Open(rootFile.c_str());
|
||||
|
||||
ai_assert(m_RootStream != nullptr);
|
||||
|
||||
|
||||
|
||||
mRootStream = mZipArchive->Open(rootFile.c_str());
|
||||
ai_assert( mRootStream != nullptr );
|
||||
if ( nullptr == mRootStream ) {
|
||||
throw DeadlyExportError( "Cannot open rootfile in archive : " + rootFile );
|
||||
}
|
||||
|
||||
// const size_t size = zipArchive->FileSize();
|
||||
// m_Data.resize( size );
|
||||
|
@ -534,50 +481,40 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
|
|||
// m_Data.clear();
|
||||
// return false;
|
||||
// }
|
||||
zipArchive->Close( fileStream );
|
||||
mZipArchive->Close( fileStream );
|
||||
|
||||
}
|
||||
else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE)
|
||||
{
|
||||
} else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
D3MFOpcPackage::~D3MFOpcPackage()
|
||||
{
|
||||
|
||||
D3MFOpcPackage::~D3MFOpcPackage() {
|
||||
// empty
|
||||
}
|
||||
|
||||
IOStream* D3MFOpcPackage::RootStream() const
|
||||
{
|
||||
return m_RootStream;
|
||||
IOStream* D3MFOpcPackage::RootStream() const {
|
||||
return mRootStream;
|
||||
}
|
||||
|
||||
|
||||
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream)
|
||||
{
|
||||
|
||||
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) {
|
||||
std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(stream));
|
||||
std::unique_ptr<XmlReader> xml(irr::io::createIrrXMLReader(xmlStream.get()));
|
||||
|
||||
OpcPackageRelationshipReader reader(xml.get());
|
||||
|
||||
|
||||
auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr& rel){
|
||||
return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
|
||||
});
|
||||
|
||||
|
||||
|
||||
if(itr == reader.m_relationShips.end())
|
||||
throw DeadlyImportError("Cannot find" + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
|
||||
throw DeadlyImportError("Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
|
||||
|
||||
return (*itr)->target;
|
||||
}
|
||||
|
||||
} //namespace D3MF
|
||||
} // Namespace D3MF
|
||||
|
||||
}
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif //ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||
|
|
|
@ -48,26 +48,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "irrXMLWrapper.h"
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
namespace D3MF {
|
||||
|
||||
typedef irr::io::IrrXMLReader XmlReader;
|
||||
typedef std::shared_ptr<XmlReader> XmlReaderPtr;
|
||||
|
||||
struct OpcPackageRelationship {
|
||||
std::string id;
|
||||
std::string type;
|
||||
std::string target;
|
||||
};
|
||||
|
||||
class D3MFZipArchive;
|
||||
|
||||
class D3MFOpcPackage
|
||||
{
|
||||
class D3MFOpcPackage {
|
||||
public:
|
||||
D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile);
|
||||
~D3MFOpcPackage();
|
||||
|
||||
IOStream* RootStream() const;
|
||||
private:
|
||||
|
||||
protected:
|
||||
std::string ReadPackageRootRelationship(IOStream* stream);
|
||||
|
||||
private:
|
||||
IOStream* m_RootStream;
|
||||
std::unique_ptr<D3MFZipArchive> zipArchive;
|
||||
IOStream* mRootStream;
|
||||
std::unique_ptr<D3MFZipArchive> mZipArchive;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -123,7 +123,8 @@ size_t DefaultIOStream::FileSize() const
|
|||
// https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
|
||||
#if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
|
||||
struct __stat64 fileStat;
|
||||
int err = _stat64( mFilename.c_str(), &fileStat );
|
||||
//using fileno + fstat avoids having to handle the filename
|
||||
int err = _fstat64( _fileno(mFile), &fileStat );
|
||||
if (0 != err)
|
||||
return 0;
|
||||
mCachedSize = (size_t) (fileStat.st_size);
|
||||
|
|
|
@ -49,37 +49,54 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/ai_assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#ifdef __unix__
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor.
|
||||
DefaultIOSystem::DefaultIOSystem()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor.
|
||||
DefaultIOSystem::~DefaultIOSystem()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
// maximum path length
|
||||
// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
|
||||
#ifdef PATH_MAX
|
||||
# define PATHLIMIT PATH_MAX
|
||||
#else
|
||||
# define PATHLIMIT 4096
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Tests for the existence of a file at the given path.
|
||||
bool DefaultIOSystem::Exists( const char* pFile) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
wchar_t fileName16[PATHLIMIT];
|
||||
|
||||
bool isUnicode = IsTextUnicode(pFile, strlen(pFile), NULL);
|
||||
if (isUnicode) {
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
|
||||
struct _stat64 filestat;
|
||||
if (0 != _wstat64(fileName16, &filestat)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
FILE* file = ::fopen(pFile, "rb");
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
::fclose(file);
|
||||
}
|
||||
#else
|
||||
FILE* file = ::fopen( pFile, "rb");
|
||||
if( !file)
|
||||
return false;
|
||||
|
||||
::fclose( file);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -89,10 +106,22 @@ IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
|
|||
{
|
||||
ai_assert(NULL != strFile);
|
||||
ai_assert(NULL != strMode);
|
||||
|
||||
FILE* file = ::fopen( strFile, strMode);
|
||||
if( NULL == file)
|
||||
return NULL;
|
||||
FILE* file;
|
||||
#ifdef _WIN32
|
||||
wchar_t fileName16[PATHLIMIT];
|
||||
bool isUnicode = IsTextUnicode(strFile, strlen(strFile), NULL );
|
||||
if (isUnicode) {
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
|
||||
std::string mode8(strMode);
|
||||
file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str());
|
||||
} else {
|
||||
file = ::fopen(strFile, strMode);
|
||||
}
|
||||
#else
|
||||
file = ::fopen(strFile, strMode);
|
||||
#endif
|
||||
if (nullptr == file)
|
||||
return nullptr;
|
||||
|
||||
return new DefaultIOStream(file, (std::string) strFile);
|
||||
}
|
||||
|
@ -122,32 +151,47 @@ bool IOSystem::ComparePaths (const char* one, const char* second) const
|
|||
return !ASSIMP_stricmp(one,second);
|
||||
}
|
||||
|
||||
// maximum path length
|
||||
// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
|
||||
#ifdef PATH_MAX
|
||||
# define PATHLIMIT PATH_MAX
|
||||
#else
|
||||
# define PATHLIMIT 4096
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Convert a relative path into an absolute path
|
||||
inline void MakeAbsolutePath (const char* in, char* _out)
|
||||
inline static void MakeAbsolutePath (const char* in, char* _out)
|
||||
{
|
||||
ai_assert(in && _out);
|
||||
char* ret;
|
||||
#if defined( _MSC_VER ) || defined( __MINGW32__ )
|
||||
ret = ::_fullpath( _out, in, PATHLIMIT );
|
||||
bool isUnicode = IsTextUnicode(in, strlen(in), NULL);
|
||||
if (isUnicode) {
|
||||
wchar_t out16[PATHLIMIT];
|
||||
wchar_t in16[PATHLIMIT];
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT);
|
||||
wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT);
|
||||
if (ret) {
|
||||
WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr);
|
||||
}
|
||||
if (!ret) {
|
||||
// preserve the input path, maybe someone else is able to fix
|
||||
// the path before it is accessed (e.g. our file system filter)
|
||||
DefaultLogger::get()->warn("Invalid path: " + std::string(in));
|
||||
strcpy(_out, in);
|
||||
}
|
||||
|
||||
} else {
|
||||
char* ret = :: _fullpath(_out, in, PATHLIMIT);
|
||||
if (!ret) {
|
||||
// preserve the input path, maybe someone else is able to fix
|
||||
// the path before it is accessed (e.g. our file system filter)
|
||||
DefaultLogger::get()->warn("Invalid path: " + std::string(in));
|
||||
strcpy(_out, in);
|
||||
}
|
||||
}
|
||||
#else
|
||||
// use realpath
|
||||
ret = realpath(in, _out);
|
||||
#endif
|
||||
char* ret = realpath(in, _out);
|
||||
if(!ret) {
|
||||
// preserve the input path, maybe someone else is able to fix
|
||||
// the path before it is accessed (e.g. our file system filter)
|
||||
DefaultLogger::get()->warn("Invalid path: "+std::string(in));
|
||||
strcpy(_out,in);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -83,6 +83,7 @@ void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportPrope
|
|||
void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneStep(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneObjNoMtl(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||
|
@ -91,30 +92,34 @@ void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperti
|
|||
void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneGLTF2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneGLB2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// global array of all export formats which Assimp supports in its current build
|
||||
Exporter::ExportFormatEntry gExporters[] =
|
||||
{
|
||||
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
|
||||
Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada),
|
||||
Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada ),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_X_EXPORTER
|
||||
Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
|
||||
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs),
|
||||
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs ),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
|
||||
Exporter::ExportFormatEntry( "stp", "Step Files", "stp", &ExportSceneStep, 0),
|
||||
Exporter::ExportFormatEntry( "stp", "Step Files", "stp", &ExportSceneStep, 0 ),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
||||
Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
|
||||
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */),
|
||||
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */ ),
|
||||
Exporter::ExportFormatEntry( "objnomtl", "Wavefront OBJ format without material file", "obj", &ExportSceneObjNoMtl,
|
||||
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */ ),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
||||
|
@ -137,28 +142,34 @@ Exporter::ExportFormatEntry gExporters[] =
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
||||
Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS,
|
||||
aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices),
|
||||
aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices ),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
|
||||
Exporter::ExportFormatEntry( "gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
||||
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf2", &ExportSceneGLTF2,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb2", &ExportSceneGLB2,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
||||
Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0),
|
||||
Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0 ),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
||||
Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0),
|
||||
Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0 ),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
|
||||
Exporter::ExportFormatEntry( "x3d", "Extensible 3D", "x3d" , &ExportSceneX3D, 0),
|
||||
Exporter::ExportFormatEntry( "x3d", "Extensible 3D", "x3d" , &ExportSceneX3D, 0 ),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
|
||||
Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 )
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -241,7 +252,7 @@ bool Exporter::IsDefaultIOHandler() const {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
|
||||
unsigned int, const ExportProperties* pProperties ) {
|
||||
unsigned int, const ExportProperties* /*pProperties*/ ) {
|
||||
if (pimpl->blob) {
|
||||
delete pimpl->blob;
|
||||
pimpl->blob = NULL;
|
||||
|
|
|
@ -87,17 +87,16 @@ AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::s
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurve::~AnimationCurve()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
|
||||
const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/)
|
||||
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name,
|
||||
const Document& doc, const char* const * target_prop_whitelist /*= NULL*/,
|
||||
size_t whitelist_size /*= 0*/)
|
||||
: Object(id, element, name)
|
||||
, target()
|
||||
, doc(doc)
|
||||
|
@ -154,18 +153,16 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
|
|||
props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNode::~AnimationCurveNode()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const AnimationCurveMap& AnimationCurveNode::Curves() const
|
||||
{
|
||||
if(curves.empty()) {
|
||||
if ( curves.empty() ) {
|
||||
// resolve attached animation curves
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
|
||||
|
||||
|
@ -195,7 +192,6 @@ const AnimationCurveMap& AnimationCurveNode::Curves() const
|
|||
return curves;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||
: Object(id, element, name)
|
||||
|
@ -207,14 +203,12 @@ AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::s
|
|||
props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationLayer::~AnimationLayer()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/,
|
||||
size_t whitelist_size /*= 0*/) const
|
||||
|
@ -298,14 +292,13 @@ AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::s
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationStack::~AnimationStack()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
} //!FBX
|
||||
} //!Assimp
|
||||
|
||||
#endif
|
||||
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
|
|
@ -151,7 +151,8 @@ uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
|
|||
TokenizeError("cannot ReadWord, out of bounds",input, cursor);
|
||||
}
|
||||
|
||||
uint32_t word = *reinterpret_cast<const uint32_t*>(cursor);
|
||||
uint32_t word;
|
||||
memcpy(&word, cursor, 4);
|
||||
AI_SWAP4(word);
|
||||
|
||||
cursor += k_to_read;
|
||||
|
@ -421,7 +422,6 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -434,16 +434,24 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
|
|||
TokenizeError("file is too short",0);
|
||||
}
|
||||
|
||||
//uint32_t offset = 0x15;
|
||||
/* const char* cursor = input + 0x15;
|
||||
|
||||
const uint32_t flags = ReadWord(input, cursor, input + length);
|
||||
|
||||
const uint8_t padding_0 = ReadByte(input, cursor, input + length); // unused
|
||||
const uint8_t padding_1 = ReadByte(input, cursor, input + length); // unused*/
|
||||
|
||||
if (strncmp(input,"Kaydara FBX Binary",18)) {
|
||||
TokenizeError("magic bytes not found",0);
|
||||
}
|
||||
|
||||
const char* cursor = input + 18;
|
||||
const uint8_t unknown_1 = ReadByte(input, cursor, input + length);
|
||||
const uint8_t unknown_2 = ReadByte(input, cursor, input + length);
|
||||
const uint8_t unknown_3 = ReadByte(input, cursor, input + length);
|
||||
const uint8_t unknown_4 = ReadByte(input, cursor, input + length);
|
||||
const uint8_t unknown_5 = ReadByte(input, cursor, input + length);
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
const uint32_t version = ReadWord(input, cursor, input + length);
|
||||
const bool is64bits = version >= 7500;
|
||||
while (cursor < input + length)
|
||||
|
|
|
@ -66,4 +66,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif // INCLUDED_AI_FBX_COMPILECONFIG_H
|
||||
|
|
|
@ -55,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "StringComparison.h"
|
||||
|
||||
#include <assimp/scene.h>
|
||||
|
||||
#include <tuple>
|
||||
#include <memory>
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
|
@ -436,19 +436,6 @@ private:
|
|||
|
||||
aiScene* const out;
|
||||
const FBX::Document& doc;
|
||||
|
||||
bool FindTextureIndexByFilename(const Video& video, unsigned int& index) {
|
||||
index = 0;
|
||||
const char* videoFileName = video.FileName().c_str();
|
||||
for (auto texture = textures_converted.begin(); texture != textures_converted.end(); ++texture)
|
||||
{
|
||||
if (!strcmp(texture->first->FileName().c_str(), videoFileName)) {
|
||||
return true;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Converter::Converter( aiScene* out, const Document& doc )
|
||||
|
@ -566,7 +553,6 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
|
|||
|
||||
if ( !name_carrier ) {
|
||||
nodes_chain.push_back( new aiNode( original_name ) );
|
||||
name_carrier = nodes_chain.back();
|
||||
}
|
||||
|
||||
//setup metadata on newest node
|
||||
|
@ -645,7 +631,6 @@ void Converter::ConvertCameras( const Model& model )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Converter::ConvertLight( const Model& model, const Light& light )
|
||||
{
|
||||
lights.push_back( new aiLight() );
|
||||
|
@ -783,7 +768,6 @@ const char* Converter::NameTransformationComp( TransformationComp comp )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const char* Converter::NameTransformationCompProperty( TransformationComp comp )
|
||||
{
|
||||
switch ( comp )
|
||||
|
@ -949,8 +933,7 @@ std::string Converter::NameTransformationChainNode( const std::string& name, Tra
|
|||
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
|
||||
}
|
||||
|
||||
void Converter::GenerateTransformationNodeChain( const Model& model,
|
||||
std::vector<aiNode*>& output_nodes )
|
||||
void Converter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes )
|
||||
{
|
||||
const PropertyTable& props = model.Props();
|
||||
const Model::RotOrder rot = model.RotationOrder();
|
||||
|
@ -1065,6 +1048,10 @@ void Converter::GenerateTransformationNodeChain( const Model& model,
|
|||
continue;
|
||||
}
|
||||
|
||||
if ( comp == TransformationComp_PostRotation ) {
|
||||
chain[ i ] = chain[ i ].Inverse();
|
||||
}
|
||||
|
||||
aiNode* nd = new aiNode();
|
||||
output_nodes.push_back( nd );
|
||||
|
||||
|
@ -1093,7 +1080,7 @@ void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
|
|||
DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
|
||||
|
||||
// create metadata on node
|
||||
std::size_t numStaticMetaData = 2;
|
||||
const std::size_t numStaticMetaData = 2;
|
||||
aiMetadata* data = aiMetadata::Alloc( static_cast<unsigned int>(unparsedProperties.size() + numStaticMetaData) );
|
||||
nd.mMetaData = data;
|
||||
int index = 0;
|
||||
|
@ -1777,6 +1764,8 @@ unsigned int Converter::ConvertVideo( const Video& video )
|
|||
memcpy( out_tex->achFormatHint, ext.c_str(), ext.size() );
|
||||
}
|
||||
|
||||
out_tex->mFilename.Set(video.FileName().c_str());
|
||||
|
||||
return static_cast<unsigned int>( textures.size() - 1 );
|
||||
}
|
||||
|
||||
|
@ -1811,17 +1800,21 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
|
|||
textures_converted[media] = index;
|
||||
textureReady = true;
|
||||
}
|
||||
else if (doc.Settings().searchEmbeddedTextures) { //try to find the texture on the already-loaded textures by the filename, if the flag is on
|
||||
textureReady = FindTextureIndexByFilename(*media, index);
|
||||
}
|
||||
}
|
||||
|
||||
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready
|
||||
if (doc.Settings().useLegacyEmbeddedTextureNaming) {
|
||||
if (textureReady) {
|
||||
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
||||
// In FBX files textures are now stored internally by Assimp with their filename included
|
||||
// Now Assimp can lookup thru the loaded textures after all data is processed
|
||||
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
|
||||
// This may occur on this case too, it has to be studied
|
||||
path.data[0] = '*';
|
||||
path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 );
|
||||
|
||||
|
@ -2236,9 +2229,17 @@ void Converter::ConvertAnimations()
|
|||
}
|
||||
}
|
||||
|
||||
void Converter::RenameNode( const std::string& fixed_name, const std::string& new_name ) {
|
||||
if ( node_names.find( fixed_name ) == node_names.end() ) {
|
||||
FBXImporter::LogError( "Cannot rename node " + fixed_name + ", not existing.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( node_names.find( new_name ) != node_names.end() ) {
|
||||
FBXImporter::LogError( "Cannot rename node " + fixed_name + " to " + new_name +", name already existing." );
|
||||
return;
|
||||
}
|
||||
|
||||
void Converter::RenameNode( const std::string& fixed_name, const std::string& new_name )
|
||||
{
|
||||
ai_assert( node_names.find( fixed_name ) != node_names.end() );
|
||||
ai_assert( node_names.find( new_name ) == node_names.end() );
|
||||
|
||||
|
@ -2426,6 +2427,7 @@ void Converter::ConvertAnimationStack( const AnimationStack& st )
|
|||
anim->mTicksPerSecond = anim_fps;
|
||||
}
|
||||
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// sanity check whether the input is ok
|
||||
static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>& curves,
|
||||
|
@ -2443,6 +2445,7 @@ static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // ASSIMP_BUILD_DEBUG
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
|
||||
|
@ -2734,10 +2737,10 @@ aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name,
|
|||
double& max_time,
|
||||
double& min_time )
|
||||
{
|
||||
ScopeGuard<aiNodeAnim> na( new aiNodeAnim() );
|
||||
std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
|
||||
na->mNodeName.Set( name );
|
||||
|
||||
ConvertRotationKeys( na, curves, layer_map, start, stop, max_time, min_time, target.RotationOrder() );
|
||||
ConvertRotationKeys( na.get(), curves, layer_map, start, stop, max_time, min_time, target.RotationOrder() );
|
||||
|
||||
// dummy scaling key
|
||||
na->mScalingKeys = new aiVectorKey[ 1 ];
|
||||
|
@ -2753,7 +2756,7 @@ aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name,
|
|||
na->mPositionKeys[ 0 ].mTime = 0.;
|
||||
na->mPositionKeys[ 0 ].mValue = aiVector3D();
|
||||
|
||||
return na.dismiss();
|
||||
return na.release();
|
||||
}
|
||||
|
||||
aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
|
||||
|
@ -2764,10 +2767,10 @@ aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
|
|||
double& max_time,
|
||||
double& min_time )
|
||||
{
|
||||
ScopeGuard<aiNodeAnim> na( new aiNodeAnim() );
|
||||
std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
|
||||
na->mNodeName.Set( name );
|
||||
|
||||
ConvertScaleKeys( na, curves, layer_map, start, stop, max_time, min_time );
|
||||
ConvertScaleKeys( na.get(), curves, layer_map, start, stop, max_time, min_time );
|
||||
|
||||
// dummy rotation key
|
||||
na->mRotationKeys = new aiQuatKey[ 1 ];
|
||||
|
@ -2783,7 +2786,7 @@ aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
|
|||
na->mPositionKeys[ 0 ].mTime = 0.;
|
||||
na->mPositionKeys[ 0 ].mValue = aiVector3D();
|
||||
|
||||
return na.dismiss();
|
||||
return na.release();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2796,10 +2799,10 @@ aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
|
|||
double& min_time,
|
||||
bool inverse )
|
||||
{
|
||||
ScopeGuard<aiNodeAnim> na( new aiNodeAnim() );
|
||||
std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
|
||||
na->mNodeName.Set( name );
|
||||
|
||||
ConvertTranslationKeys( na, curves, layer_map, start, stop, max_time, min_time );
|
||||
ConvertTranslationKeys( na.get(), curves, layer_map, start, stop, max_time, min_time );
|
||||
|
||||
if ( inverse ) {
|
||||
for ( unsigned int i = 0; i < na->mNumPositionKeys; ++i ) {
|
||||
|
@ -2821,7 +2824,7 @@ aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
|
|||
na->mRotationKeys[ 0 ].mTime = 0.;
|
||||
na->mRotationKeys[ 0 ].mValue = aiQuaternion();
|
||||
|
||||
return na.dismiss();
|
||||
return na.release();
|
||||
}
|
||||
|
||||
aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
|
||||
|
@ -2835,7 +2838,7 @@ aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
|
|||
bool reverse_order )
|
||||
|
||||
{
|
||||
ScopeGuard<aiNodeAnim> na( new aiNodeAnim() );
|
||||
std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
|
||||
na->mNodeName.Set( name );
|
||||
|
||||
const PropertyTable& props = target.Props();
|
||||
|
@ -2907,7 +2910,7 @@ aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
|
|||
// which requires all of rotation, scaling and translation
|
||||
// to be set.
|
||||
if ( chain[ TransformationComp_Scaling ] != iter_end ) {
|
||||
ConvertScaleKeys( na, ( *chain[ TransformationComp_Scaling ] ).second,
|
||||
ConvertScaleKeys( na.get(), ( *chain[ TransformationComp_Scaling ] ).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
|
@ -2923,7 +2926,7 @@ aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
|
|||
}
|
||||
|
||||
if ( chain[ TransformationComp_Rotation ] != iter_end ) {
|
||||
ConvertRotationKeys( na, ( *chain[ TransformationComp_Rotation ] ).second,
|
||||
ConvertRotationKeys( na.get(), ( *chain[ TransformationComp_Rotation ] ).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
|
@ -2941,7 +2944,7 @@ aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
|
|||
}
|
||||
|
||||
if ( chain[ TransformationComp_Translation ] != iter_end ) {
|
||||
ConvertTranslationKeys( na, ( *chain[ TransformationComp_Translation ] ).second,
|
||||
ConvertTranslationKeys( na.get(), ( *chain[ TransformationComp_Translation ] ).second,
|
||||
layer_map,
|
||||
start, stop,
|
||||
max_time,
|
||||
|
@ -2957,7 +2960,7 @@ aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
|
|||
}
|
||||
|
||||
}
|
||||
return na.dismiss();
|
||||
return na.release();
|
||||
}
|
||||
|
||||
Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop )
|
||||
|
@ -3120,7 +3123,6 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
||||
const aiVector3D& def_value,
|
||||
double& maxTime,
|
||||
|
@ -3141,7 +3143,6 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con
|
|||
|
||||
valOut[ i ].mTime = temp[ i ].mTime;
|
||||
|
||||
|
||||
GetRotationMatrix( order, temp[ i ].mValue, m );
|
||||
aiQuaternion quat = aiQuaternion( aiMatrix3x3( m ) );
|
||||
|
||||
|
@ -3160,7 +3161,6 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale,
|
||||
aiVectorKey* out_translation,
|
||||
const KeyFrameListList& scaling,
|
||||
|
@ -3219,7 +3219,6 @@ void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order )
|
||||
{
|
||||
aiMatrix4x4 m;
|
||||
|
@ -3228,7 +3227,6 @@ aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrde
|
|||
return aiQuaternion( aiMatrix3x3( m ) );
|
||||
}
|
||||
|
||||
|
||||
void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
||||
int64_t start, int64_t stop,
|
||||
double& maxTime,
|
||||
|
@ -3249,7 +3247,6 @@ void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const Animat
|
|||
InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime );
|
||||
}
|
||||
|
||||
|
||||
void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||
const LayerMap& /*layers*/,
|
||||
int64_t start, int64_t stop,
|
||||
|
@ -3268,7 +3265,6 @@ void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const
|
|||
InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime );
|
||||
}
|
||||
|
||||
|
||||
void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||
const LayerMap& /*layers*/,
|
||||
int64_t start, int64_t stop,
|
||||
|
@ -3290,7 +3286,8 @@ void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const Ani
|
|||
|
||||
void Converter::TransferDataToScene()
|
||||
{
|
||||
ai_assert( !out->mMeshes && !out->mNumMeshes );
|
||||
ai_assert( !out->mMeshes );
|
||||
ai_assert( !out->mNumMeshes );
|
||||
|
||||
// note: the trailing () ensures initialization with NULL - not
|
||||
// many C++ users seem to know this, so pointing it out to avoid
|
||||
|
|
|
@ -70,13 +70,13 @@ LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc)
|
|||
, id(id)
|
||||
, flags()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LazyObject::~LazyObject()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -232,16 +232,15 @@ Object::Object(uint64_t id, const Element& element, const std::string& name)
|
|||
, name(name)
|
||||
, id(id)
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object::~Object()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props)
|
||||
: props(props)
|
||||
|
@ -361,7 +360,6 @@ void Document::ReadGlobalSettings()
|
|||
globals.reset(new FileGlobalSettings(*this, props));
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Document::ReadObjects()
|
||||
{
|
||||
|
@ -387,7 +385,6 @@ void Document::ReadObjects()
|
|||
}
|
||||
|
||||
const char* err;
|
||||
|
||||
const uint64_t id = ParseTokenAsID(*tok[0], err);
|
||||
if(err) {
|
||||
DOMError(err,el.second);
|
||||
|
@ -469,8 +466,6 @@ void Document::ReadPropertyTemplates()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Document::ReadConnections()
|
||||
{
|
||||
|
@ -482,7 +477,6 @@ void Document::ReadConnections()
|
|||
}
|
||||
|
||||
uint64_t insertionOrder = 0l;
|
||||
|
||||
const Scope& sconns = *econns->Compound();
|
||||
const ElementCollection conns = sconns.GetCollection("C");
|
||||
for(ElementMap::const_iterator it = conns.first; it != conns.second; ++it) {
|
||||
|
@ -491,7 +485,9 @@ void Document::ReadConnections()
|
|||
|
||||
// PP = property-property connection, ignored for now
|
||||
// (tokens: "PP", ID1, "Property1", ID2, "Property2")
|
||||
if(type == "PP") continue;
|
||||
if ( type == "PP" ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint64_t src = ParseTokenAsID(GetRequiredToken(el,1));
|
||||
const uint64_t dest = ParseTokenAsID(GetRequiredToken(el,2));
|
||||
|
@ -518,11 +514,10 @@ void Document::ReadConnections()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
||||
{
|
||||
if (!animationStacksResolved.empty() || !animationStacks.size()) {
|
||||
if (!animationStacksResolved.empty() || animationStacks.empty()) {
|
||||
return animationStacksResolved;
|
||||
}
|
||||
|
||||
|
@ -540,7 +535,6 @@ const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
|||
return animationStacksResolved;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LazyObject* Document::GetObject(uint64_t id) const
|
||||
{
|
||||
|
@ -551,8 +545,7 @@ LazyObject* Document::GetObject(uint64_t id) const
|
|||
#define 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;
|
||||
|
||||
|
@ -569,7 +562,6 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id,
|
|||
return temp; // NRVO should handle this
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bool is_src,
|
||||
const ConnectionMap& conns,
|
||||
|
@ -578,17 +570,17 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
|||
|
||||
{
|
||||
ai_assert(classnames);
|
||||
ai_assert(count != 0 && count <= MAX_CLASSNAMES);
|
||||
ai_assert( count != 0 );
|
||||
ai_assert( count <= MAX_CLASSNAMES);
|
||||
|
||||
size_t lenghts[MAX_CLASSNAMES];
|
||||
|
||||
const size_t c = count;
|
||||
for (size_t i = 0; i < c; ++i) {
|
||||
lenghts[i] = strlen(classnames[i]);
|
||||
lenghts[ i ] = strlen(classnames[i]);
|
||||
}
|
||||
|
||||
std::vector<const Connection*> temp;
|
||||
|
||||
const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range =
|
||||
conns.equal_range(id);
|
||||
|
||||
|
@ -620,25 +612,19 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
|||
return temp; // NRVO should handle this
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const
|
||||
{
|
||||
return GetConnectionsSequenced(source, ConnectionsBySource());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t dest,
|
||||
const char* classname) const
|
||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t src, const char* classname) const
|
||||
{
|
||||
const char* arr[] = {classname};
|
||||
return GetConnectionsBySourceSequenced(dest, arr,1);
|
||||
return GetConnectionsBySourceSequenced(src, arr,1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source,
|
||||
const char* const* classnames, size_t count) const
|
||||
|
@ -646,7 +632,6 @@ std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_
|
|||
return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest,
|
||||
const char* classname) const
|
||||
|
@ -655,14 +640,12 @@ std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(ui
|
|||
return GetConnectionsByDestinationSequenced(dest, arr,1);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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
|
||||
|
@ -671,7 +654,6 @@ std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(ui
|
|||
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)
|
||||
|
@ -687,14 +669,12 @@ Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, co
|
|||
ai_assert(!dest || doc.Objects().find(dest) != doc.Objects().end());
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Connection::~Connection()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LazyObject& Connection::LazySourceObject() const
|
||||
{
|
||||
|
@ -703,7 +683,6 @@ LazyObject& Connection::LazySourceObject() const
|
|||
return *lazy;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LazyObject& Connection::LazyDestinationObject() const
|
||||
{
|
||||
|
@ -712,7 +691,6 @@ LazyObject& Connection::LazyDestinationObject() const
|
|||
return *lazy;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Object* Connection::SourceObject() const
|
||||
{
|
||||
|
@ -721,7 +699,6 @@ const Object* Connection::SourceObject() const
|
|||
return lazy->Get();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Object* Connection::DestinationObject() const
|
||||
{
|
||||
|
@ -734,4 +711,3 @@ const Object* Connection::DestinationObject() const
|
|||
} // !Assimp
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -338,12 +338,7 @@ public:
|
|||
class Model : public Object
|
||||
{
|
||||
public:
|
||||
Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~Model();
|
||||
|
||||
public:
|
||||
enum RotOrder
|
||||
{
|
||||
enum RotOrder {
|
||||
RotOrder_EulerXYZ = 0,
|
||||
RotOrder_EulerXZY,
|
||||
RotOrder_EulerYZX,
|
||||
|
@ -357,8 +352,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
enum TransformInheritance
|
||||
{
|
||||
enum TransformInheritance {
|
||||
TransformInheritance_RrSs = 0,
|
||||
TransformInheritance_RSrs,
|
||||
TransformInheritance_Rrs,
|
||||
|
@ -366,7 +360,10 @@ public:
|
|||
TransformInheritance_MAX // end-of-enum sentinel
|
||||
};
|
||||
|
||||
public:
|
||||
Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~Model();
|
||||
|
||||
fbx_simple_property(QuaternionInterpolate, int, 0)
|
||||
|
||||
fbx_simple_property(RotationOffset, aiVector3D, aiVector3D())
|
||||
|
@ -443,7 +440,6 @@ public:
|
|||
fbx_simple_property(LODBox, bool, false)
|
||||
fbx_simple_property(Freeze, bool, false)
|
||||
|
||||
public:
|
||||
const std::string& Shading() const {
|
||||
return shading;
|
||||
}
|
||||
|
@ -462,13 +458,11 @@ public:
|
|||
return materials;
|
||||
}
|
||||
|
||||
|
||||
/** Get geometry links */
|
||||
const std::vector<const Geometry*>& GetGeometry() const {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
|
||||
/** Get node attachments */
|
||||
const std::vector<const NodeAttribute*>& GetAttributes() const {
|
||||
return attributes;
|
||||
|
@ -477,7 +471,6 @@ public:
|
|||
/** convenience method to check if the node has a Null node marker */
|
||||
bool IsNull() const;
|
||||
|
||||
|
||||
private:
|
||||
void ResolveLinks(const Element& element, const Document& doc);
|
||||
|
||||
|
@ -603,10 +596,10 @@ public:
|
|||
return textures[index];
|
||||
|
||||
}
|
||||
const int textureCount() const {
|
||||
int textureCount() const {
|
||||
return static_cast<int>(textures.size());
|
||||
}
|
||||
const BlendMode GetBlendMode() const
|
||||
BlendMode GetBlendMode() const
|
||||
{
|
||||
return blendMode;
|
||||
}
|
||||
|
@ -654,7 +647,7 @@ public:
|
|||
return content;
|
||||
}
|
||||
|
||||
const uint32_t ContentLength() const {
|
||||
uint32_t ContentLength() const {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
|
@ -805,7 +798,6 @@ private:
|
|||
|
||||
typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList;
|
||||
|
||||
|
||||
/** Represents a FBX animation layer (i.e. a list of node animations) */
|
||||
class AnimationLayer : public Object
|
||||
{
|
||||
|
@ -828,10 +820,8 @@ private:
|
|||
const Document& doc;
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<const AnimationLayer*> AnimationLayerList;
|
||||
|
||||
|
||||
/** Represents a FBX animation stack (i.e. a list of animation layers) */
|
||||
class AnimationStack : public Object
|
||||
{
|
||||
|
@ -839,7 +829,6 @@ public:
|
|||
AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||
virtual ~AnimationStack();
|
||||
|
||||
public:
|
||||
fbx_simple_property(LocalStart, int64_t, 0L)
|
||||
fbx_simple_property(LocalStop, int64_t, 0L)
|
||||
fbx_simple_property(ReferenceStart, int64_t, 0L)
|
||||
|
@ -879,7 +868,6 @@ private:
|
|||
typedef std::vector<float> WeightArray;
|
||||
typedef std::vector<unsigned int> WeightIndexArray;
|
||||
|
||||
|
||||
/** DOM class for skin deformer clusters (aka subdeformers) */
|
||||
class Cluster : public Deformer
|
||||
{
|
||||
|
@ -924,8 +912,6 @@ private:
|
|||
const Model* node;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** DOM class for skin deformers */
|
||||
class Skin : public Deformer
|
||||
{
|
||||
|
@ -1009,10 +995,8 @@ public:
|
|||
typedef std::map<uint64_t, LazyObject*> ObjectMap;
|
||||
typedef std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > PropertyTemplateMap;
|
||||
|
||||
|
||||
typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
|
||||
|
||||
|
||||
/** DOM class for global document settings, a single instance per document can
|
||||
* be accessed via Document.Globals(). */
|
||||
class FileGlobalSettings
|
||||
|
@ -1074,9 +1058,6 @@ private:
|
|||
const Document& doc;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** DOM root for a FBX file */
|
||||
class Document
|
||||
{
|
||||
|
@ -1154,8 +1135,6 @@ private:
|
|||
const ConnectionMap&,
|
||||
const char* const* classnames,
|
||||
size_t count) const;
|
||||
|
||||
private:
|
||||
void ReadHeader();
|
||||
void ReadObjects();
|
||||
void ReadPropertyTemplates();
|
||||
|
|
|
@ -63,7 +63,7 @@ struct ImportSettings
|
|||
, readWeights(true)
|
||||
, preservePivots(true)
|
||||
, optimizeEmptyAnimationCurves(true)
|
||||
, searchEmbeddedTextures(false)
|
||||
, useLegacyEmbeddedTextureNaming(false)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -139,9 +139,9 @@ struct ImportSettings
|
|||
* The default value is true. */
|
||||
bool optimizeEmptyAnimationCurves;
|
||||
|
||||
/** search for embedded loaded textures, where no embedded texture data is provided.
|
||||
* The default value is false. */
|
||||
bool searchEmbeddedTextures;
|
||||
/** use legacy naming for embedded textures eg: (*0, *1, *2)
|
||||
**/
|
||||
bool useLegacyEmbeddedTextureNaming;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -59,7 +59,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/importerdesc.h>
|
||||
|
||||
namespace Assimp {
|
||||
template<> const std::string LogFunctions<FBXImporter>::log_prefix = "FBX: ";
|
||||
template<> const char* LogFunctions<FBXImporter>::Prefix()
|
||||
{
|
||||
static auto prefix = "FBX: ";
|
||||
return prefix;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace Assimp;
|
||||
|
@ -131,7 +135,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
|
|||
settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
|
||||
settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
|
||||
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
|
||||
settings.searchEmbeddedTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES, false);
|
||||
settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -298,7 +298,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
|
|||
}
|
||||
|
||||
if(Content) {
|
||||
//this field is ommited when the embedded texture is already loaded, let's ignore if it´s not found
|
||||
//this field is ommited when the embedded texture is already loaded, let's ignore if it's not found
|
||||
try {
|
||||
const Token& token = GetRequiredToken(*Content, 0);
|
||||
const char* data = token.begin();
|
||||
|
@ -323,7 +323,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
|
|||
::memcpy(content, data + 5, len);
|
||||
}
|
||||
} catch (runtime_error runtimeError) {
|
||||
//we don´t need the content data for contents that has already been loaded
|
||||
//we don't need the content data for contents that has already been loaded
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,14 +77,12 @@ Model::Model(uint64_t id, const Element& element, const Document& doc, const std
|
|||
ResolveLinks(element,doc);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Model::~Model()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Model::ResolveLinks(const Element& element, const Document& doc)
|
||||
{
|
||||
|
@ -132,7 +130,6 @@ void Model::ResolveLinks(const Element& element, const Document& doc)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Model::IsNull() const
|
||||
{
|
||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
using namespace Util;
|
||||
using namespace Util;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
|
@ -75,7 +75,7 @@ NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
NodeAttribute::~NodeAttribute()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,33 +101,30 @@ CameraSwitcher::CameraSwitcher(uint64_t id, const Element& element, const Docume
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CameraSwitcher::~CameraSwitcher()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: NodeAttribute(id,element,doc,name)
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Camera::~Camera()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: NodeAttribute(id,element,doc,name)
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ namespace {
|
|||
T SafeParse(const char* data, const char* end) {
|
||||
// Actual size validation happens during Tokenization so
|
||||
// this is valid as an assertion.
|
||||
(void)(end);
|
||||
ai_assert(static_cast<size_t>(end - data) >= sizeof(T));
|
||||
T result = static_cast<T>(0);
|
||||
::memcpy(&result, data, sizeof(T));
|
||||
|
@ -224,41 +225,36 @@ Parser::Parser (const TokenList& tokens, bool is_binary)
|
|||
root.reset(new Scope(*this,true));
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Parser::~Parser()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
TokenPtr Parser::AdvanceToNextToken()
|
||||
{
|
||||
last = current;
|
||||
if (cursor == tokens.end()) {
|
||||
current = NULL;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
current = *cursor++;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
TokenPtr Parser::CurrentToken() const
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
TokenPtr Parser::LastToken() const
|
||||
{
|
||||
return last;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
||||
{
|
||||
|
@ -286,7 +282,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
|||
unsigned int length = static_cast<unsigned int>(t.end() - t.begin());
|
||||
ai_assert(length > 0);
|
||||
|
||||
const char* out;
|
||||
const char* out = nullptr;
|
||||
const uint64_t id = strtoul10_64(t.begin(),&out,&length);
|
||||
if (out > t.end()) {
|
||||
err_out = "failed to parse ID (text)";
|
||||
|
@ -296,7 +292,6 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
|||
return id;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
size_t ParseTokenAsDim(const Token& t, const char*& err_out)
|
||||
{
|
||||
|
@ -333,7 +328,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const char* out;
|
||||
const char* out = nullptr;
|
||||
const size_t id = static_cast<size_t>(strtoul10_64(t.begin() + 1,&out,&length));
|
||||
if (out > t.end()) {
|
||||
err_out = "failed to parse ID";
|
||||
|
@ -446,7 +441,7 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
|
|||
unsigned int length = static_cast<unsigned int>(t.end() - t.begin());
|
||||
ai_assert(length > 0);
|
||||
|
||||
const char* out;
|
||||
const char* out = nullptr;
|
||||
const int64_t id = strtol10_64(t.begin(), &out, &length);
|
||||
if (out > t.end()) {
|
||||
err_out = "failed to parse Int64 (text)";
|
||||
|
|
|
@ -85,12 +85,9 @@ typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> Element
|
|||
class Element
|
||||
{
|
||||
public:
|
||||
|
||||
Element(const Token& key_token, Parser& parser);
|
||||
~Element();
|
||||
|
||||
public:
|
||||
|
||||
const Scope* Compound() const {
|
||||
return compound.get();
|
||||
}
|
||||
|
@ -104,14 +101,11 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
const Token& key_token;
|
||||
TokenList tokens;
|
||||
std::unique_ptr<Scope> compound;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** FBX data entity that consists of a 'scope', a collection
|
||||
* of not necessarily unique #Element instances.
|
||||
*
|
||||
|
@ -125,14 +119,10 @@ private:
|
|||
* @endverbatim */
|
||||
class Scope
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
Scope(Parser& parser, bool topLevel = false);
|
||||
~Scope();
|
||||
|
||||
public:
|
||||
|
||||
const Element* operator[] (const std::string& index) const {
|
||||
ElementMap::const_iterator it = elements.find(index);
|
||||
return it == elements.end() ? NULL : (*it).second;
|
||||
|
@ -158,28 +148,23 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
ElementMap elements;
|
||||
};
|
||||
|
||||
|
||||
/** FBX parsing class, takes a list of input tokens and generates a hierarchy
|
||||
* of nested #Scope instances, representing the fbx DOM.*/
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
|
||||
/** Parse given a token list. Does not take ownership of the tokens -
|
||||
* the objects must persist during the entire parser lifetime */
|
||||
Parser (const TokenList& tokens,bool is_binary);
|
||||
~Parser();
|
||||
|
||||
public:
|
||||
const Scope& GetRootScope() const {
|
||||
return *root.get();
|
||||
}
|
||||
|
||||
|
||||
bool IsBinary() const {
|
||||
return is_binary;
|
||||
}
|
||||
|
@ -233,8 +218,6 @@ void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el);
|
|||
void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e);
|
||||
void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el);
|
||||
|
||||
|
||||
|
||||
// extract a required element from a scope, abort if the element cannot be found
|
||||
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL);
|
||||
|
||||
|
@ -243,8 +226,6 @@ const Scope& GetRequiredScope(const Element& el);
|
|||
// get token at a particular index
|
||||
const Token& GetRequiredToken(const Element& el, unsigned int index);
|
||||
|
||||
|
||||
|
||||
// read a 4x4 matrix from an array of 16 floats
|
||||
aiMatrix4x4 ReadMatrix(const Element& element);
|
||||
|
||||
|
|
|
@ -62,8 +62,7 @@ class Element;
|
|||
P: "ShininessExponent", "double", "Number", "",0.5
|
||||
@endvebatim
|
||||
*/
|
||||
class Property
|
||||
{
|
||||
class Property {
|
||||
protected:
|
||||
Property();
|
||||
|
||||
|
@ -78,15 +77,13 @@ public:
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
class TypedProperty : public Property
|
||||
{
|
||||
class TypedProperty : public Property {
|
||||
public:
|
||||
explicit TypedProperty(const T& value)
|
||||
: value(value)
|
||||
{
|
||||
: value(value) {
|
||||
// empty
|
||||
}
|
||||
|
||||
public:
|
||||
const T& Value() const {
|
||||
return value;
|
||||
}
|
||||
|
@ -103,15 +100,13 @@ typedef std::fbx_unordered_map<std::string,const Element*> LazyPropertyMap;
|
|||
/**
|
||||
* Represents a property table as can be found in the newer FBX files (Properties60, Properties70)
|
||||
*/
|
||||
class PropertyTable
|
||||
{
|
||||
class PropertyTable {
|
||||
public:
|
||||
// in-memory property table with no source element
|
||||
PropertyTable();
|
||||
PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps);
|
||||
~PropertyTable();
|
||||
|
||||
public:
|
||||
const Property* Get(const std::string& name) const;
|
||||
|
||||
// PropertyTable's need not be coupled with FBX elements so this can be NULL
|
||||
|
@ -132,7 +127,6 @@ private:
|
|||
const Element* const element;
|
||||
};
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline
|
||||
|
|
|
@ -45,19 +45,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||
|
||||
#include "FIReader.hpp"
|
||||
#include "StringUtils.h"
|
||||
|
||||
// Workaround for issue #1361
|
||||
// https://github.com/assimp/assimp/issues/1361
|
||||
#ifdef __ANDROID__
|
||||
#define _GLIBCXX_USE_C99 1
|
||||
# define _GLIBCXX_USE_C99 1
|
||||
#endif
|
||||
|
||||
#include "FIReader.hpp"
|
||||
#include "Exceptional.h"
|
||||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/types.h>
|
||||
#include "MemoryIOWrapper.h"
|
||||
#include "irrXMLWrapper.h"
|
||||
#include "../contrib/utf8cpp/source/utf8.h"
|
||||
#include "fast_atof.h"
|
||||
#include <stack>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
@ -168,7 +171,7 @@ struct FIBase64ValueImpl: public FIBase64Value {
|
|||
if (!strValueValid) {
|
||||
strValueValid = true;
|
||||
std::ostringstream os;
|
||||
uint8_t c1, c2;
|
||||
uint8_t c1 = 0, c2;
|
||||
int imod3 = 0;
|
||||
std::vector<uint8_t>::size_type valueSize = value.size();
|
||||
for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
|
||||
|
@ -485,7 +488,9 @@ struct FIFloatDecoder: public FIDecoder {
|
|||
value.reserve(numFloats);
|
||||
for (size_t i = 0; i < numFloats; ++i) {
|
||||
int v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
|
||||
value.push_back(*(float*)&v);
|
||||
float f;
|
||||
memcpy(&f, &v, 4);
|
||||
value.push_back(f);
|
||||
data += 4;
|
||||
}
|
||||
return FIFloatValue::create(std::move(value));
|
||||
|
@ -503,7 +508,9 @@ struct FIDoubleDecoder: public FIDecoder {
|
|||
for (size_t i = 0; i < numDoubles; ++i) {
|
||||
long long b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
|
||||
long long v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
||||
value.push_back(*(double*)&v);
|
||||
double f;
|
||||
memcpy(&f, &v, 8);
|
||||
value.push_back(f);
|
||||
data += 8;
|
||||
}
|
||||
return FIDoubleValue::create(std::move(value));
|
||||
|
@ -685,7 +692,7 @@ public:
|
|||
if (intValue) {
|
||||
return intValue->value.size() == 1 ? intValue->value.front() : 0;
|
||||
}
|
||||
return stoi(attr->value->toString());
|
||||
return atoi(attr->value->toString().c_str());
|
||||
}
|
||||
|
||||
virtual int getAttributeValueAsInt(int idx) const /*override*/ {
|
||||
|
@ -696,7 +703,7 @@ public:
|
|||
if (intValue) {
|
||||
return intValue->value.size() == 1 ? intValue->value.front() : 0;
|
||||
}
|
||||
return stoi(attributes[idx].value->toString());
|
||||
return atoi(attributes[idx].value->toString().c_str());
|
||||
}
|
||||
|
||||
virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
|
||||
|
@ -708,7 +715,8 @@ public:
|
|||
if (floatValue) {
|
||||
return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
|
||||
}
|
||||
return stof(attr->value->toString());
|
||||
|
||||
return fast_atof(attr->value->toString().c_str());
|
||||
}
|
||||
|
||||
virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
|
||||
|
@ -719,7 +727,7 @@ public:
|
|||
if (floatValue) {
|
||||
return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
|
||||
}
|
||||
return stof(attributes[idx].value->toString());
|
||||
return fast_atof(attributes[idx].value->toString().c_str());
|
||||
}
|
||||
|
||||
virtual const char* getNodeName() const /*override*/ {
|
||||
|
@ -984,13 +992,13 @@ private:
|
|||
if (index < 32) {
|
||||
FIDecoder *decoder = defaultDecoder[index];
|
||||
if (!decoder) {
|
||||
throw DeadlyImportError("Invalid encoding algorithm index " + std::to_string(index));
|
||||
throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
|
||||
}
|
||||
return decoder->decode(dataP, len);
|
||||
}
|
||||
else {
|
||||
if (index - 32 >= vocabulary.encodingAlgorithmTable.size()) {
|
||||
throw DeadlyImportError("Invalid encoding algorithm index " + std::to_string(index));
|
||||
throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
|
||||
}
|
||||
std::string uri = vocabulary.encodingAlgorithmTable[index - 32];
|
||||
auto it = decoderMap.find(uri);
|
||||
|
@ -1014,12 +1022,12 @@ private:
|
|||
alphabet = "0123456789-:TZ ";
|
||||
break;
|
||||
default:
|
||||
throw DeadlyImportError("Invalid restricted alphabet index " + std::to_string(index));
|
||||
throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (index - 16 >= vocabulary.restrictedAlphabetTable.size()) {
|
||||
throw DeadlyImportError("Invalid restricted alphabet index " + std::to_string(index));
|
||||
throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
|
||||
}
|
||||
alphabet = vocabulary.restrictedAlphabetTable[index - 16];
|
||||
}
|
||||
|
@ -1027,7 +1035,7 @@ private:
|
|||
utf8::utf8to32(alphabet.begin(), alphabet.end(), back_inserter(alphabetUTF32));
|
||||
std::string::size_type alphabetLength = alphabetUTF32.size();
|
||||
if (alphabetLength < 2) {
|
||||
throw DeadlyImportError("Invalid restricted alphabet length " + std::to_string(alphabetLength));
|
||||
throw DeadlyImportError("Invalid restricted alphabet length " + to_string(alphabetLength));
|
||||
}
|
||||
std::string::size_type bitsPerCharacter = 1;
|
||||
while ((1ull << bitsPerCharacter) <= alphabetLength) {
|
||||
|
@ -1776,17 +1784,18 @@ public:
|
|||
return reader->getParserFormat();
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const /*override*/ {
|
||||
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int /*idx*/) const /*override*/ {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* name) const /*override*/ {
|
||||
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* /*name*/) const /*override*/ {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr<FIDecoder> decoder) /*override*/ {}
|
||||
virtual void registerDecoder(const std::string & /*algorithmUri*/, std::unique_ptr<FIDecoder> /*decoder*/) /*override*/ {}
|
||||
|
||||
virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) /*override*/ {}
|
||||
|
||||
virtual void registerVocabulary(const std::string &/*vocabularyUri*/, const FIVocabulary * /*vocabulary*/) /*override*/ {}
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -46,16 +46,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef INCLUDED_AI_FI_READER_H
|
||||
#define INCLUDED_AI_FI_READER_H
|
||||
|
||||
#include <irrXML.h>
|
||||
#include <memory>
|
||||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||
|
||||
//#include <wchar.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <cerrno>
|
||||
#include <cwchar>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
//#include <stdio.h>
|
||||
//#include <cstdint>
|
||||
#include <irrXML.h>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
struct FIValue {
|
||||
virtual const std::string &toString() const = 0;
|
||||
virtual ~FIValue() {}
|
||||
};
|
||||
|
||||
struct FIStringValue: public FIValue {
|
||||
|
@ -115,6 +122,7 @@ struct FICDATAValue: public FIStringValue {
|
|||
|
||||
struct FIDecoder {
|
||||
virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) = 0;
|
||||
virtual ~FIDecoder() {}
|
||||
};
|
||||
|
||||
struct FIQName {
|
||||
|
@ -154,7 +162,7 @@ class IOStream;
|
|||
|
||||
class FIReader: public irr::io::IIrrXMLReader<char, irr::io::IXMLBase> {
|
||||
public:
|
||||
|
||||
virtual ~FIReader();
|
||||
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const = 0;
|
||||
|
||||
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char *name) const = 0;
|
||||
|
@ -167,6 +175,13 @@ public:
|
|||
|
||||
};// class IFIReader
|
||||
|
||||
inline
|
||||
FIReader::~FIReader() {
|
||||
// empty
|
||||
}
|
||||
|
||||
}// namespace Assimp
|
||||
|
||||
#endif // #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||
|
||||
#endif // INCLUDED_AI_FI_READER_H
|
||||
|
|
|
@ -56,98 +56,138 @@ using namespace Assimp;
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
FindDegeneratesProcess::FindDegeneratesProcess()
|
||||
: configRemoveDegenerates (false)
|
||||
{}
|
||||
: mConfigRemoveDegenerates( false )
|
||||
, mConfigCheckAreaOfTriangle( false ){
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
FindDegeneratesProcess::~FindDegeneratesProcess()
|
||||
{
|
||||
FindDegeneratesProcess::~FindDegeneratesProcess() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the processing step is present in the given flag field.
|
||||
bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const
|
||||
{
|
||||
bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const {
|
||||
return 0 != (pFlags & aiProcess_FindDegenerates);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Setup import configuration
|
||||
void FindDegeneratesProcess::SetupProperties(const Importer* pImp)
|
||||
{
|
||||
void FindDegeneratesProcess::SetupProperties(const Importer* pImp) {
|
||||
// Get the current value of AI_CONFIG_PP_FD_REMOVE
|
||||
configRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
|
||||
mConfigRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
|
||||
mConfigCheckAreaOfTriangle = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_CHECKAREA) );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Executes the post processing step on the given imported data.
|
||||
void FindDegeneratesProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
void FindDegeneratesProcess::Execute( aiScene* pScene) {
|
||||
DefaultLogger::get()->debug("FindDegeneratesProcess begin");
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
|
||||
ExecuteOnMesh( pScene->mMeshes[i]);
|
||||
ExecuteOnMesh( pScene->mMeshes[ i ] );
|
||||
}
|
||||
DefaultLogger::get()->debug("FindDegeneratesProcess finished");
|
||||
}
|
||||
|
||||
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
|
||||
ai_real s = (a + b + c) / 2;
|
||||
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
|
||||
return area;
|
||||
}
|
||||
|
||||
static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB ) {
|
||||
const ai_real lx = ( vB.x - vA.x );
|
||||
const ai_real ly = ( vB.y - vA.y );
|
||||
const ai_real lz = ( vB.z - vA.z );
|
||||
ai_real a = lx*lx + ly*ly + lz*lz;
|
||||
ai_real d = pow( a, (ai_real)0.5 );
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
|
||||
ai_real area = 0;
|
||||
|
||||
aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
|
||||
aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
|
||||
aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
|
||||
|
||||
ai_real a( distance3D( vA, vB ) );
|
||||
ai_real b( distance3D( vB, vC ) );
|
||||
ai_real c( distance3D( vC, vA ) );
|
||||
area = heron( a, b, c );
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Executes the post processing step on the given imported mesh
|
||||
void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh)
|
||||
{
|
||||
void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||
mesh->mPrimitiveTypes = 0;
|
||||
|
||||
std::vector<bool> remove_me;
|
||||
if (configRemoveDegenerates)
|
||||
remove_me.resize(mesh->mNumFaces,false);
|
||||
if (mConfigRemoveDegenerates) {
|
||||
remove_me.resize( mesh->mNumFaces, false );
|
||||
}
|
||||
|
||||
unsigned int deg = 0, limit;
|
||||
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
|
||||
{
|
||||
for ( unsigned int a = 0; a < mesh->mNumFaces; ++a ) {
|
||||
aiFace& face = mesh->mFaces[a];
|
||||
bool first = true;
|
||||
|
||||
// check whether the face contains degenerated entries
|
||||
for (unsigned int i = 0; i < face.mNumIndices; ++i)
|
||||
{
|
||||
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
|
||||
// Polygons with more than 4 points are allowed to have double points, that is
|
||||
// simulating polygons with holes just with concave polygons. However,
|
||||
// double points may not come directly after another.
|
||||
limit = face.mNumIndices;
|
||||
if (face.mNumIndices > 4)
|
||||
limit = std::min(limit,i+2);
|
||||
if (face.mNumIndices > 4) {
|
||||
limit = std::min( limit, i+2 );
|
||||
}
|
||||
|
||||
for (unsigned int t = i+1; t < limit; ++t)
|
||||
{
|
||||
if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]])
|
||||
{
|
||||
for (unsigned int t = i+1; t < limit; ++t) {
|
||||
if (mesh->mVertices[face.mIndices[ i ] ] == mesh->mVertices[ face.mIndices[ t ] ]) {
|
||||
// we have found a matching vertex position
|
||||
// remove the corresponding index from the array
|
||||
--face.mNumIndices;--limit;
|
||||
for (unsigned int m = t; m < face.mNumIndices; ++m)
|
||||
{
|
||||
face.mIndices[m] = face.mIndices[m+1];
|
||||
--face.mNumIndices;
|
||||
--limit;
|
||||
for (unsigned int m = t; m < face.mNumIndices; ++m) {
|
||||
face.mIndices[ m ] = face.mIndices[ m+1 ];
|
||||
}
|
||||
--t;
|
||||
|
||||
// NOTE: we set the removed vertex index to an unique value
|
||||
// to make sure the developer gets notified when his
|
||||
// application attemps to access this data.
|
||||
face.mIndices[face.mNumIndices] = 0xdeadbeef;
|
||||
face.mIndices[ face.mNumIndices ] = 0xdeadbeef;
|
||||
|
||||
if(first)
|
||||
{
|
||||
if(first) {
|
||||
++deg;
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (configRemoveDegenerates) {
|
||||
remove_me[a] = true;
|
||||
if ( mConfigRemoveDegenerates ) {
|
||||
remove_me[ a ] = true;
|
||||
goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( mConfigCheckAreaOfTriangle ) {
|
||||
if ( face.mNumIndices == 3 ) {
|
||||
ai_real area = calculateAreaOfTriangle( face, mesh );
|
||||
if ( area < 1e-6 ) {
|
||||
if ( mConfigRemoveDegenerates ) {
|
||||
remove_me[ a ] = true;
|
||||
goto evil_jump_outside;
|
||||
}
|
||||
|
||||
// todo: check for index which is corrupt.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We need to update the primitive flags array of the mesh.
|
||||
|
@ -171,7 +211,7 @@ evil_jump_outside:
|
|||
}
|
||||
|
||||
// If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
|
||||
if (configRemoveDegenerates && deg) {
|
||||
if (mConfigRemoveDegenerates && deg) {
|
||||
unsigned int n = 0;
|
||||
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
|
||||
{
|
||||
|
|
|
@ -54,15 +54,11 @@ namespace Assimp {
|
|||
// ---------------------------------------------------------------------------
|
||||
/** FindDegeneratesProcess: Searches a mesh for degenerated triangles.
|
||||
*/
|
||||
class ASSIMP_API FindDegeneratesProcess : public BaseProcess
|
||||
{
|
||||
class ASSIMP_API FindDegeneratesProcess : public BaseProcess {
|
||||
public:
|
||||
|
||||
FindDegeneratesProcess();
|
||||
~FindDegeneratesProcess();
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Check whether step is active
|
||||
bool IsActive( unsigned int pFlags) const;
|
||||
|
@ -79,28 +75,53 @@ public:
|
|||
// Execute step on a given mesh
|
||||
void ExecuteOnMesh( aiMesh* mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/// @brief Enable the instant removal of degenerated primitives
|
||||
/// @param enabled true for enabled.
|
||||
void EnableInstantRemoval(bool enabled);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Enable the instant removal of degenerated primitives
|
||||
* @param d hm ... difficult to guess what this means, hu!?
|
||||
*/
|
||||
void EnableInstantRemoval(bool d) {
|
||||
configRemoveDegenerates = d;
|
||||
}
|
||||
/// @brief Check whether instant removal is currently enabled
|
||||
/// @return The instant removal state.
|
||||
bool IsInstantRemoval() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Check whether instant removal is currently enabled
|
||||
* @return ...
|
||||
*/
|
||||
bool IsInstantRemoval() const {
|
||||
return configRemoveDegenerates;
|
||||
}
|
||||
/// @brief Enable the area check for triangles.
|
||||
/// @param enabled true for enabled.
|
||||
void EnableAreaCheck( bool enabled );
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/// @brief Check whether the area check is enabled.
|
||||
/// @return The area check state.
|
||||
bool isAreaCheckEnabled() const;
|
||||
|
||||
private:
|
||||
|
||||
//! Configuration option: remove degenerates faces immediately
|
||||
bool configRemoveDegenerates;
|
||||
bool mConfigRemoveDegenerates;
|
||||
//! Configuration option: check for area
|
||||
bool mConfigCheckAreaOfTriangle;
|
||||
};
|
||||
|
||||
inline
|
||||
void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) {
|
||||
mConfigRemoveDegenerates = enabled;
|
||||
}
|
||||
|
||||
inline
|
||||
bool FindDegeneratesProcess::IsInstantRemoval() const {
|
||||
return mConfigRemoveDegenerates;
|
||||
}
|
||||
|
||||
inline
|
||||
void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) {
|
||||
mConfigCheckAreaOfTriangle = enabled;
|
||||
}
|
||||
|
||||
inline
|
||||
bool FindDegeneratesProcess::isAreaCheckEnabled() const {
|
||||
return mConfigCheckAreaOfTriangle;
|
||||
}
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // !! AI_FINDDEGENERATESPROCESS_H_INC
|
||||
|
|
|
@ -169,8 +169,8 @@ void FindInvalidDataProcess::Execute( aiScene* pScene)
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline const char* ValidateArrayContents(const T* arr, unsigned int size,
|
||||
const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true)
|
||||
inline const char* ValidateArrayContents(const T* /*arr*/, unsigned int /*size*/,
|
||||
const std::vector<bool>& /*dirtyMask*/, bool /*mayBeIdentical = false*/, bool /*mayBeZero = true*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -339,32 +339,37 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
|
|||
int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
|
||||
{
|
||||
bool ret = false;
|
||||
std::vector<bool> dirtyMask(pMesh->mNumVertices,(pMesh->mNumFaces ? true : false));
|
||||
std::vector<bool> dirtyMask(pMesh->mNumVertices, pMesh->mNumFaces != 0);
|
||||
|
||||
// Ignore elements that are not referenced by vertices.
|
||||
// (they are, for example, caused by the FindDegenerates step)
|
||||
for (unsigned int m = 0; m < pMesh->mNumFaces;++m) {
|
||||
for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) {
|
||||
const aiFace& f = pMesh->mFaces[m];
|
||||
|
||||
for (unsigned int i = 0; i < f.mNumIndices;++i) {
|
||||
for (unsigned int i = 0; i < f.mNumIndices; ++i) {
|
||||
dirtyMask[f.mIndices[i]] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Process vertex positions
|
||||
if(pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask)) {
|
||||
if (pMesh->mVertices && ProcessArray(pMesh->mVertices, pMesh->mNumVertices, "positions", dirtyMask)) {
|
||||
DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions");
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
// process texture coordinates
|
||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i];++i) {
|
||||
if (ProcessArray(pMesh->mTextureCoords[i],pMesh->mNumVertices,"uvcoords",dirtyMask)) {
|
||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i]; ++i) {
|
||||
if (ProcessArray(pMesh->mTextureCoords[i], pMesh->mNumVertices, "uvcoords", dirtyMask)) {
|
||||
pMesh->mNumUVComponents[i] = 0;
|
||||
|
||||
// delete all subsequent texture coordinate sets.
|
||||
for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) {
|
||||
delete[] pMesh->mTextureCoords[a]; pMesh->mTextureCoords[a] = NULL;
|
||||
for (unsigned int a = i + 1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
|
||||
delete[] pMesh->mTextureCoords[a];
|
||||
pMesh->mTextureCoords[a] = NULL;
|
||||
pMesh->mNumUVComponents[a] = 0;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,14 +56,11 @@ namespace Assimp
|
|||
* vectors of an object are facing inwards. In this case they will be
|
||||
* flipped.
|
||||
*/
|
||||
class FixInfacingNormalsProcess : public BaseProcess
|
||||
{
|
||||
class FixInfacingNormalsProcess : public BaseProcess {
|
||||
public:
|
||||
|
||||
FixInfacingNormalsProcess();
|
||||
~FixInfacingNormalsProcess();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the processing step is present in the given flag field.
|
||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||
|
|
|
@ -111,7 +111,7 @@ inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline const bool HasGenericProperty(const std::map< unsigned int, T >& list,
|
||||
inline bool HasGenericProperty(const std::map< unsigned int, T >& list,
|
||||
const char* szName)
|
||||
{
|
||||
ai_assert(NULL != szName);
|
||||
|
|
|
@ -272,7 +272,6 @@ bool IntersectsBoundaryProfile(const IfcVector3& e0, const IfcVector3& e1, const
|
|||
const IfcVector3& b0 = boundary[i];
|
||||
const IfcVector3& b1 = boundary[(i + 1) % bcount];
|
||||
IfcVector3 b = b1 - b0;
|
||||
IfcFloat b_sqlen_inv = 1.0 / b.SquareLength();
|
||||
|
||||
// segment-segment intersection
|
||||
// solve b0 + b*s = e0 + e*t for (s,t)
|
||||
|
@ -281,6 +280,7 @@ bool IntersectsBoundaryProfile(const IfcVector3& e0, const IfcVector3& e1, const
|
|||
// no solutions (parallel lines)
|
||||
continue;
|
||||
}
|
||||
IfcFloat b_sqlen_inv = 1.0 / b.SquareLength();
|
||||
|
||||
const IfcFloat x = b0.x - e0.x;
|
||||
const IfcFloat y = b0.y - e0.y;
|
||||
|
|
|
@ -43,28 +43,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
* @brief Read profile and curves entities from IFC files
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
#include "IFCUtil.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace IFC {
|
||||
namespace {
|
||||
namespace IFC {
|
||||
namespace {
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// Conic is the base class for Circle and Ellipse
|
||||
// --------------------------------------------------------------------------------
|
||||
class Conic : public Curve
|
||||
{
|
||||
|
||||
class Conic : public Curve {
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
Conic(const IfcConic& entity, ConversionData& conv)
|
||||
: Curve(entity,conv)
|
||||
{
|
||||
: Curve(entity,conv) {
|
||||
IfcMatrix4 trafo;
|
||||
ConvertAxisPlacement(trafo,*entity.Position,conv);
|
||||
|
||||
|
@ -75,8 +69,6 @@ public:
|
|||
p[2] = IfcVector3(trafo.a3,trafo.b3,trafo.c3);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
bool IsClosed() const {
|
||||
return true;
|
||||
|
@ -84,7 +76,8 @@ public:
|
|||
|
||||
// --------------------------------------------------
|
||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
ai_assert( InRange( a ) );
|
||||
ai_assert( InRange( b ) );
|
||||
|
||||
a *= conv.angle_scale;
|
||||
b *= conv.angle_scale;
|
||||
|
@ -104,15 +97,11 @@ protected:
|
|||
IfcVector3 location, p[3];
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// Circle
|
||||
// --------------------------------------------------------------------------------
|
||||
class Circle : public Conic
|
||||
{
|
||||
|
||||
class Circle : public Conic {
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
Circle(const IfcCircle& entity, ConversionData& conv)
|
||||
: Conic(entity,conv)
|
||||
|
@ -120,8 +109,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
IfcVector3 Eval(IfcFloat u) const {
|
||||
u = -conv.angle_scale * u;
|
||||
|
@ -137,20 +124,15 @@ private:
|
|||
// --------------------------------------------------------------------------------
|
||||
// Ellipse
|
||||
// --------------------------------------------------------------------------------
|
||||
class Ellipse : public Conic
|
||||
{
|
||||
|
||||
class Ellipse : public Conic {
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
Ellipse(const IfcEllipse& entity, ConversionData& conv)
|
||||
: Conic(entity,conv)
|
||||
, entity(entity)
|
||||
{
|
||||
, entity(entity) {
|
||||
// empty
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
IfcVector3 Eval(IfcFloat u) const {
|
||||
u = -conv.angle_scale * u;
|
||||
|
@ -162,25 +144,18 @@ private:
|
|||
const IfcEllipse& entity;
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// Line
|
||||
// --------------------------------------------------------------------------------
|
||||
class Line : public Curve
|
||||
{
|
||||
|
||||
class Line : public Curve {
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
Line(const IfcLine& entity, ConversionData& conv)
|
||||
: Curve(entity,conv)
|
||||
{
|
||||
: Curve(entity,conv) {
|
||||
ConvertCartesianPoint(p,entity.Pnt);
|
||||
ConvertVector(v,entity.Dir);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
bool IsClosed() const {
|
||||
return false;
|
||||
|
@ -193,16 +168,17 @@ public:
|
|||
|
||||
// --------------------------------------------------
|
||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
ai_assert( InRange( a ) );
|
||||
ai_assert( InRange( b ) );
|
||||
// two points are always sufficient for a line segment
|
||||
return a==b ? 1 : 2;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
|
||||
{
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
|
||||
ai_assert( InRange( a ) );
|
||||
ai_assert( InRange( b ) );
|
||||
|
||||
if (a == b) {
|
||||
out.verts.push_back(Eval(a));
|
||||
|
@ -227,18 +203,14 @@ private:
|
|||
// --------------------------------------------------------------------------------
|
||||
// CompositeCurve joins multiple smaller, bounded curves
|
||||
// --------------------------------------------------------------------------------
|
||||
class CompositeCurve : public BoundedCurve
|
||||
{
|
||||
|
||||
class CompositeCurve : public BoundedCurve {
|
||||
typedef std::pair< std::shared_ptr< BoundedCurve >, bool > CurveEntry;
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
CompositeCurve(const IfcCompositeCurve& entity, ConversionData& conv)
|
||||
: BoundedCurve(entity,conv)
|
||||
, total()
|
||||
{
|
||||
, total() {
|
||||
curves.reserve(entity.Segments.size());
|
||||
for(const IfcCompositeCurveSegment& curveSegment :entity.Segments) {
|
||||
// according to the specification, this must be a bounded curve
|
||||
|
@ -263,8 +235,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
IfcVector3 Eval(IfcFloat u) const {
|
||||
if (curves.empty()) {
|
||||
|
@ -287,7 +257,8 @@ public:
|
|||
|
||||
// --------------------------------------------------
|
||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
ai_assert( InRange( a ) );
|
||||
ai_assert( InRange( b ) );
|
||||
size_t cnt = 0;
|
||||
|
||||
IfcFloat acc = 0;
|
||||
|
@ -306,9 +277,9 @@ public:
|
|||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
|
||||
{
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
|
||||
ai_assert( InRange( a ) );
|
||||
ai_assert( InRange( b ) );
|
||||
|
||||
const size_t cnt = EstimateSampleCount(a,b);
|
||||
out.verts.reserve(out.verts.size() + cnt);
|
||||
|
@ -330,19 +301,14 @@ public:
|
|||
|
||||
private:
|
||||
std::vector< CurveEntry > curves;
|
||||
|
||||
IfcFloat total;
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// TrimmedCurve can be used to trim an unbounded curve to a bounded range
|
||||
// --------------------------------------------------------------------------------
|
||||
class TrimmedCurve : public BoundedCurve
|
||||
{
|
||||
|
||||
class TrimmedCurve : public BoundedCurve {
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
TrimmedCurve(const IfcTrimmedCurve& entity, ConversionData& conv)
|
||||
: BoundedCurve(entity,conv)
|
||||
|
@ -409,8 +375,6 @@ public:
|
|||
ai_assert(maxval >= 0);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
IfcVector3 Eval(IfcFloat p) const {
|
||||
ai_assert(InRange(p));
|
||||
|
@ -419,7 +383,8 @@ public:
|
|||
|
||||
// --------------------------------------------------
|
||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
ai_assert( InRange( a ) );
|
||||
ai_assert( InRange( b ) );
|
||||
return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
|
||||
}
|
||||
|
||||
|
@ -435,13 +400,11 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------
|
||||
IfcFloat TrimParam(IfcFloat f) const {
|
||||
return agree_sense ? f + range.first : range.second - f;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
ParamRange range;
|
||||
IfcFloat maxval;
|
||||
|
@ -454,11 +417,8 @@ private:
|
|||
// --------------------------------------------------------------------------------
|
||||
// PolyLine is a 'curve' defined by linear interpolation over a set of discrete points
|
||||
// --------------------------------------------------------------------------------
|
||||
class PolyLine : public BoundedCurve
|
||||
{
|
||||
|
||||
class PolyLine : public BoundedCurve {
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
PolyLine(const IfcPolyline& entity, ConversionData& conv)
|
||||
: BoundedCurve(entity,conv)
|
||||
|
@ -472,8 +432,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------
|
||||
IfcVector3 Eval(IfcFloat p) const {
|
||||
ai_assert(InRange(p));
|
||||
|
@ -502,13 +460,10 @@ private:
|
|||
std::vector<IfcVector3> points;
|
||||
};
|
||||
|
||||
|
||||
} // anon
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv)
|
||||
{
|
||||
Curve* Curve::Convert(const IFC::IfcCurve& curve,ConversionData& conv) {
|
||||
if(curve.ToPtr<IfcBoundedCurve>()) {
|
||||
if(const IfcPolyline* c = curve.ToPtr<IfcPolyline>()) {
|
||||
return new PolyLine(*c,conv);
|
||||
|
@ -519,9 +474,6 @@ Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv)
|
|||
if(const IfcCompositeCurve* c = curve.ToPtr<IfcCompositeCurve>()) {
|
||||
return new CompositeCurve(*c,conv);
|
||||
}
|
||||
//if(const IfcBSplineCurve* c = curve.ToPtr<IfcBSplineCurve>()) {
|
||||
// return new BSplineCurve(*c,conv);
|
||||
//}
|
||||
}
|
||||
|
||||
if(curve.ToPtr<IfcConic>()) {
|
||||
|
@ -543,8 +495,7 @@ Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv)
|
|||
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Curve :: InRange(IfcFloat u) const
|
||||
{
|
||||
bool Curve::InRange(IfcFloat u) const {
|
||||
const ParamRange range = GetParametricRange();
|
||||
if (IsClosed()) {
|
||||
return true;
|
||||
|
@ -555,24 +506,24 @@ bool Curve :: InRange(IfcFloat u) const
|
|||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IfcFloat Curve :: GetParametricRangeDelta() const
|
||||
{
|
||||
IfcFloat Curve::GetParametricRangeDelta() const {
|
||||
const ParamRange& range = GetParametricRange();
|
||||
return std::abs(range.second - range.first);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
size_t Curve :: EstimateSampleCount(IfcFloat a, IfcFloat b) const
|
||||
{
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
size_t Curve::EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
||||
(void)(a); (void)(b);
|
||||
ai_assert( InRange( a ) );
|
||||
ai_assert( InRange( b ) );
|
||||
|
||||
// arbitrary default value, deriving classes should supply better suited values
|
||||
return 16;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, IfcFloat b, unsigned int samples, IfcFloat threshold, unsigned int recurse = 0, unsigned int max_recurse = 15)
|
||||
{
|
||||
IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, IfcFloat b,
|
||||
unsigned int samples, IfcFloat threshold, unsigned int recurse = 0, unsigned int max_recurse = 15) {
|
||||
ai_assert(samples>1);
|
||||
|
||||
const IfcFloat delta = (b-a)/samples, inf = std::numeric_limits<IfcFloat>::infinity();
|
||||
|
@ -594,7 +545,8 @@ IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, Ifc
|
|||
}
|
||||
}
|
||||
|
||||
ai_assert(min_diff[0] != inf && min_diff[1] != inf);
|
||||
ai_assert( min_diff[ 0 ] != inf );
|
||||
ai_assert( min_diff[ 1 ] != inf );
|
||||
if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
|
||||
return min_point[0];
|
||||
}
|
||||
|
@ -615,15 +567,15 @@ IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, Ifc
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Curve :: ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const
|
||||
bool Curve::ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const
|
||||
{
|
||||
// note: the following algorithm is not guaranteed to find the 'right' parameter value
|
||||
// in all possible cases, but it will always return at least some value so this function
|
||||
// will never fail in the default implementation.
|
||||
|
||||
// XXX derive threshold from curve topology
|
||||
const IfcFloat threshold = 1e-4f;
|
||||
const unsigned int samples = 16;
|
||||
static const IfcFloat threshold = 1e-4f;
|
||||
static const unsigned int samples = 16;
|
||||
|
||||
const ParamRange& range = GetParametricRange();
|
||||
paramOut = RecursiveSearch(this,val,range.first,range.second,samples,threshold);
|
||||
|
@ -632,9 +584,9 @@ bool Curve :: ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
|
||||
{
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
void Curve::SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
|
||||
ai_assert( InRange( a ) );
|
||||
ai_assert( InRange( b ) );
|
||||
|
||||
const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b));
|
||||
out.verts.reserve( out.verts.size() + cnt + 1);
|
||||
|
@ -646,16 +598,15 @@ void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool BoundedCurve :: IsClosed() const
|
||||
{
|
||||
bool BoundedCurve::IsClosed() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BoundedCurve :: SampleDiscrete(TempMesh& out) const
|
||||
{
|
||||
void BoundedCurve::SampleDiscrete(TempMesh& out) const {
|
||||
const ParamRange& range = GetParametricRange();
|
||||
ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
|
||||
ai_assert( range.first != std::numeric_limits<IfcFloat>::infinity() );
|
||||
ai_assert( range.second != std::numeric_limits<IfcFloat>::infinity() );
|
||||
|
||||
return SampleDiscrete(out,range.first,range.second);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
|
||||
namespace Assimp {
|
||||
template<> const std::string LogFunctions<IFCImporter>::log_prefix = "IFC: ";
|
||||
template<> const char* LogFunctions<IFCImporter>::Prefix()
|
||||
{
|
||||
static auto prefix = "IFC: ";
|
||||
return prefix;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace Assimp;
|
||||
|
|
|
@ -1499,7 +1499,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
|||
|
||||
|
||||
IfcVector3 wall_extrusion;
|
||||
bool do_connections = false, first = true;
|
||||
bool first = true;
|
||||
|
||||
try {
|
||||
|
||||
|
@ -1527,7 +1527,6 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
|||
if (first) {
|
||||
first = false;
|
||||
if (dot > 0.f) {
|
||||
do_connections = true;
|
||||
wall_extrusion = t.extrusionDir;
|
||||
if (is_extruded_side) {
|
||||
wall_extrusion = - wall_extrusion;
|
||||
|
@ -1607,44 +1606,6 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
|||
old_verts.swap(curmesh.verts);
|
||||
old_vertcnt.swap(curmesh.vertcnt);
|
||||
|
||||
|
||||
// add connection geometry to close the adjacent 'holes' for the openings
|
||||
// this should only be done from one side of the wall or the polygons
|
||||
// would be emitted twice.
|
||||
if (false && do_connections) {
|
||||
|
||||
std::vector<IfcVector3> tmpvec;
|
||||
for(ClipperLib::Polygon& opening : holes_union) {
|
||||
|
||||
ai_assert(ClipperLib::Orientation(opening));
|
||||
|
||||
tmpvec.clear();
|
||||
|
||||
for(ClipperLib::IntPoint& point : opening) {
|
||||
|
||||
tmpvec.push_back( minv * IfcVector3(
|
||||
vmin.x + from_int64(point.X) * vmax.x,
|
||||
vmin.y + from_int64(point.Y) * vmax.y,
|
||||
coord));
|
||||
}
|
||||
|
||||
for(size_t i = 0, size = tmpvec.size(); i < size; ++i) {
|
||||
const size_t next = (i+1)%size;
|
||||
|
||||
curmesh.vertcnt.push_back(4);
|
||||
|
||||
const IfcVector3& in_world = tmpvec[i];
|
||||
const IfcVector3& next_world = tmpvec[next];
|
||||
|
||||
// Assumptions: no 'partial' openings, wall thickness roughly the same across the wall
|
||||
curmesh.verts.push_back(in_world);
|
||||
curmesh.verts.push_back(in_world+wall_extrusion);
|
||||
curmesh.verts.push_back(next_world+wall_extrusion);
|
||||
curmesh.verts.push_back(next_world);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector< std::vector<p2t::Point*> > contours;
|
||||
for(ClipperLib::ExPolygon& clip : clipped) {
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh&
|
|||
meshout.verts.push_back( IfcVector3( std::cos(angle)*radius, std::sin(angle)*radius, 0.f ));
|
||||
}
|
||||
|
||||
meshout.vertcnt.push_back(segments);
|
||||
meshout.vertcnt.push_back(static_cast<unsigned int>(segments));
|
||||
}
|
||||
else if( const IfcIShapeProfileDef* const ishape = def.ToPtr<IfcIShapeProfileDef>()) {
|
||||
// construct simplified IBeam shape
|
||||
|
|
|
@ -1045,7 +1045,7 @@ void IFC::GetSchema(EXPRESS::ConversionSchema& out)
|
|||
namespace STEP {
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
template <> size_t GenericFill<NotImplemented>(const STEP::DB& db, const LIST& params, NotImplemented* in)
|
||||
template <> size_t GenericFill<NotImplemented>(const STEP::DB& /*db*/, const LIST& /*params*/, NotImplemented* /*in*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -1253,7 +1253,7 @@ template <> size_t GenericFill<IfcPerformanceHistory>(const DB& db, const LIST&
|
|||
return base;
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
template <> size_t GenericFill<IfcRepresentationItem>(const DB& db, const LIST& params, IfcRepresentationItem* in)
|
||||
template <> size_t GenericFill<IfcRepresentationItem>(const DB& /*db*/, const LIST& /*params*/, IfcRepresentationItem* /*in*/)
|
||||
{
|
||||
size_t base = 0;
|
||||
return base;
|
||||
|
@ -1715,7 +1715,7 @@ template <> size_t GenericFill<IfcPlateType>(const DB& db, const LIST& params, I
|
|||
return base;
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
template <> size_t GenericFill<IfcObjectPlacement>(const DB& db, const LIST& params, IfcObjectPlacement* in)
|
||||
template <> size_t GenericFill<IfcObjectPlacement>(const DB& /*db*/, const LIST& /*params*/, IfcObjectPlacement* /*in*/)
|
||||
{
|
||||
size_t base = 0;
|
||||
return base;
|
||||
|
|
|
@ -394,7 +394,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
|
|||
angles[1] %= 360;
|
||||
angles[2] %= 360;
|
||||
|
||||
if ((angles[0]*angles[1]) && (angles[1]*angles[2]))
|
||||
if ( (angles[0]*angles[1]) != 0 && (angles[1]*angles[2]) != 0 )
|
||||
{
|
||||
FindSuitableMultiple(angles[0]);
|
||||
FindSuitableMultiple(angles[1]);
|
||||
|
|
|
@ -274,10 +274,6 @@ aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
|
|||
|
||||
if (it != pimpl->mImporter.end()) {
|
||||
pimpl->mImporter.erase(it);
|
||||
|
||||
std::set<std::string> st;
|
||||
pImp->GetExtensionList(st);
|
||||
|
||||
DefaultLogger::get()->info("Unregistering custom importer: ");
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -182,6 +182,7 @@ corresponding preprocessor flag to selectively disable formats.
|
|||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||
# include "glTFImporter.h"
|
||||
# include "glTF2Importer.h"
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||
# include "C4DImporter.h"
|
||||
|
@ -336,6 +337,7 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
|||
#endif
|
||||
#if ( !defined ASSIMP_BUILD_NO_GLTF_IMPORTER )
|
||||
out.push_back( new glTFImporter() );
|
||||
out.push_back( new glTF2Importer() );
|
||||
#endif
|
||||
#if ( !defined ASSIMP_BUILD_NO_C4D_IMPORTER )
|
||||
out.push_back( new C4DImporter() );
|
||||
|
|
|
@ -223,6 +223,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
|
|||
iMaxRefTris = std::max(iMaxRefTris,*piCur);
|
||||
}
|
||||
}
|
||||
ai_assert(iMaxRefTris > 0);
|
||||
unsigned int* piCandidates = new unsigned int[iMaxRefTris*3];
|
||||
unsigned int iCacheMisses = 0;
|
||||
|
||||
|
|
|
@ -446,8 +446,6 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
|
|||
|
||||
// Iterate through all three arrays at once - it's tricky, but
|
||||
// rather interesting to implement.
|
||||
double lasttime = std::min(envl_x->keys[0].time,std::min(envl_y->keys[0].time,envl_z->keys[0].time));
|
||||
|
||||
cur_x = envl_x->keys.begin();
|
||||
cur_y = envl_y->keys.begin();
|
||||
cur_z = envl_z->keys.begin();
|
||||
|
@ -503,7 +501,7 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
|
|||
InterpolateTrack(out,fill,(end_y ? (*cur_x) : (*cur_y)).time);
|
||||
}
|
||||
}
|
||||
lasttime = fill.mTime;
|
||||
double lasttime = fill.mTime;
|
||||
out.push_back(fill);
|
||||
|
||||
if (lasttime >= (*cur_x).time) {
|
||||
|
|
|
@ -483,7 +483,7 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
|
|||
const LWO::VColorChannel& vc = layer.mVColorChannels[i];
|
||||
|
||||
if (surf.mVCMap == vc.name) {
|
||||
// The vertex color map is explicitely requested by the surface so we need to take special care of it
|
||||
// The vertex color map is explicitly requested by the surface so we need to take special care of it
|
||||
for (unsigned int a = 0; a < std::min(next,AI_MAX_NUMBER_OF_COLOR_SETS-1u); ++a) {
|
||||
out[a+1] = out[a];
|
||||
}
|
||||
|
|
|
@ -471,7 +471,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
|||
// Determine the exact location of a LWO file
|
||||
std::string LWSImporter::FindLWOFile(const std::string& in)
|
||||
{
|
||||
// insert missing directory seperator if necessary
|
||||
// insert missing directory separator if necessary
|
||||
std::string tmp;
|
||||
if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
|
||||
{
|
||||
|
|
|
@ -69,16 +69,13 @@ for(LineSplitter splitter(stream);splitter;++splitter) {
|
|||
|
||||
std::cout << "Current line is: " << splitter.get_index() << std::endl;
|
||||
}
|
||||
@endcode */
|
||||
@endcode
|
||||
*/
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class LineSplitter
|
||||
{
|
||||
class LineSplitter {
|
||||
public:
|
||||
|
||||
typedef size_t line_idx;
|
||||
|
||||
public:
|
||||
|
||||
// -----------------------------------------
|
||||
/** construct from existing stream reader
|
||||
note: trim is *always* assumed true if skyp_empty_lines==true
|
||||
|
@ -88,8 +85,7 @@ public:
|
|||
, stream(stream)
|
||||
, swallow()
|
||||
, skip_empty_lines(skip_empty_lines)
|
||||
, trim(trim)
|
||||
{
|
||||
, trim(trim) {
|
||||
cur.reserve(1024);
|
||||
operator++();
|
||||
|
||||
|
|
|
@ -60,34 +60,34 @@ public:
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
static void ThrowException(const std::string& msg)
|
||||
{
|
||||
throw DeadlyImportError(log_prefix+msg);
|
||||
throw DeadlyImportError(Prefix()+msg);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogWarn(const Formatter::format& message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
DefaultLogger::get()->warn(log_prefix+(std::string)message);
|
||||
DefaultLogger::get()->warn(Prefix()+(std::string)message);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogError(const Formatter::format& message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
DefaultLogger::get()->error(log_prefix+(std::string)message);
|
||||
DefaultLogger::get()->error(Prefix()+(std::string)message);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogInfo(const Formatter::format& message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
DefaultLogger::get()->info(log_prefix+(std::string)message);
|
||||
DefaultLogger::get()->info(Prefix()+(std::string)message);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogDebug(const Formatter::format& message) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
DefaultLogger::get()->debug(log_prefix+(std::string)message);
|
||||
DefaultLogger::get()->debug(Prefix()+(std::string)message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,8 +125,7 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
|
||||
static const std::string log_prefix;
|
||||
static const char* Prefix();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -274,11 +274,9 @@ void MD2Importer::InternReadFile( const std::string& pFile,
|
|||
aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
|
||||
pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||
|
||||
// navigate to the begin of the frame data
|
||||
// navigate to the begin of the current frame data
|
||||
BE_NCONST MD2::Frame* pcFrame = (BE_NCONST MD2::Frame*) ((uint8_t*)
|
||||
m_pcHeader + m_pcHeader->offsetFrames);
|
||||
|
||||
pcFrame += configFrameID;
|
||||
m_pcHeader + m_pcHeader->offsetFrames + (m_pcHeader->frameSize * configFrameID));
|
||||
|
||||
// navigate to the begin of the triangle data
|
||||
MD2::Triangle* pcTriangles = (MD2::Triangle*) ((uint8_t*)
|
||||
|
|
|
@ -1018,11 +1018,11 @@ void MD3Importer::InternReadFile( const std::string& pFile,
|
|||
|
||||
// Convert the normal vector to uncompressed float3 format
|
||||
aiVector3D& nor = pcMesh->mNormals[iCurrent];
|
||||
LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,(ai_real*)&nor);
|
||||
LatLngNormalToVec3(pcVertices[index].NORMAL,(ai_real*)&nor);
|
||||
|
||||
// Read texture coordinates
|
||||
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
|
||||
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-pcUVs[ pcTriangles->INDEXES[c]].V;
|
||||
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[index].U;
|
||||
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-pcUVs[index].V;
|
||||
}
|
||||
// Flip face order if necessary
|
||||
if (!shader || shader->cull == Q3Shader::CULL_CW) {
|
||||
|
|
|
@ -145,7 +145,7 @@ protected:
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
/** Load the contents of a specific file into memory and
|
||||
* alocates a buffer to keep it.
|
||||
* allocates a buffer to keep it.
|
||||
*
|
||||
* mBuffer is modified to point to this buffer.
|
||||
* @param pFile File stream to be read
|
||||
|
|
|
@ -283,9 +283,8 @@ void MDCImporter::InternReadFile(
|
|||
pcMesh->mNumVertices = pcMesh->mNumFaces * 3;
|
||||
|
||||
// store the name of the surface for use as node name.
|
||||
// FIX: make sure there is a 0 termination
|
||||
const_cast<char&>(pcSurface->ucName[AI_MDC_MAXQPATH-1]) = '\0';
|
||||
pcMesh->mTextureCoords[3] = (aiVector3D*)pcSurface->ucName;
|
||||
pcMesh->mName.Set(std::string(pcSurface->ucName
|
||||
, strnlen(pcSurface->ucName, AI_MDC_MAXQPATH - 1)));
|
||||
|
||||
// go to the first shader in the file. ignore the others.
|
||||
if (pcSurface->ulNumShaders)
|
||||
|
@ -294,8 +293,8 @@ void MDCImporter::InternReadFile(
|
|||
pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
|
||||
|
||||
// create a new shader
|
||||
aszShaders.push_back(std::string( pcShader->ucName, std::min(
|
||||
::strlen(pcShader->ucName),sizeof(pcShader->ucName)) ));
|
||||
aszShaders.push_back(std::string( pcShader->ucName,
|
||||
::strnlen(pcShader->ucName, sizeof(pcShader->ucName)) ));
|
||||
}
|
||||
// need to create a default material
|
||||
else if (UINT_MAX == iDefaultMatIndex)
|
||||
|
@ -432,7 +431,7 @@ void MDCImporter::InternReadFile(
|
|||
else if (1 == pScene->mNumMeshes)
|
||||
{
|
||||
pScene->mRootNode = new aiNode();
|
||||
pScene->mRootNode->mName.Set(std::string((const char*)pScene->mMeshes[0]->mTextureCoords[3]));
|
||||
pScene->mRootNode->mName = pScene->mMeshes[0]->mName;
|
||||
pScene->mRootNode->mNumMeshes = 1;
|
||||
pScene->mRootNode->mMeshes = new unsigned int[1];
|
||||
pScene->mRootNode->mMeshes[0] = 0;
|
||||
|
@ -447,17 +446,13 @@ void MDCImporter::InternReadFile(
|
|||
{
|
||||
aiNode* pcNode = pScene->mRootNode->mChildren[i] = new aiNode();
|
||||
pcNode->mParent = pScene->mRootNode;
|
||||
pcNode->mName.Set(std::string((const char*)pScene->mMeshes[i]->mTextureCoords[3]));
|
||||
pcNode->mName = pScene->mMeshes[i]->mName;
|
||||
pcNode->mNumMeshes = 1;
|
||||
pcNode->mMeshes = new unsigned int[1];
|
||||
pcNode->mMeshes[0] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure we invalidate the pointer to the mesh name
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||
pScene->mMeshes[i]->mTextureCoords[3] = NULL;
|
||||
|
||||
// create materials
|
||||
pScene->mNumMaterials = (unsigned int)aszShaders.size();
|
||||
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
|
||||
|
|
|
@ -126,16 +126,16 @@ struct Header {
|
|||
int32_t version;
|
||||
|
||||
//! scale factors for each axis
|
||||
aiVector3D scale;
|
||||
ai_real scale[3];
|
||||
|
||||
//! translation factors for each axis
|
||||
aiVector3D translate;
|
||||
ai_real translate[3];
|
||||
|
||||
//! bounding radius of the mesh
|
||||
float boundingradius;
|
||||
|
||||
//! Position of the viewer's exe. Ignored
|
||||
aiVector3D vEyePos;
|
||||
ai_real vEyePos[3];
|
||||
|
||||
//! Number of textures
|
||||
int32_t num_skins;
|
||||
|
|
|
@ -415,8 +415,15 @@ void MDLImporter::InternReadFile_Quake1( )
|
|||
else
|
||||
{
|
||||
// get the first frame in the group
|
||||
|
||||
#if 1
|
||||
// FIXME: the cast is wrong and causea a warning on clang 5.0
|
||||
// disable thi code for now, fix it later
|
||||
ai_assert(false && "Bad pointer cast");
|
||||
#else
|
||||
BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames;
|
||||
pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type);
|
||||
#endif
|
||||
}
|
||||
BE_NCONST MDL::Vertex* pcVertices = (BE_NCONST MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
|
||||
VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts));
|
||||
|
|
|
@ -56,6 +56,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/Defines.h>
|
||||
#include "qnan.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
using namespace Assimp;
|
||||
static aiTexel* const bad_texel = reinterpret_cast<aiTexel*>(SIZE_MAX);
|
||||
|
@ -489,7 +491,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
|||
unsigned int iWidth,
|
||||
unsigned int iHeight)
|
||||
{
|
||||
aiTexture* pcNew = nullptr;
|
||||
std::unique_ptr<aiTexture> pcNew;
|
||||
|
||||
// get the type of the skin
|
||||
unsigned int iMasked = (unsigned int)(iType & 0xF);
|
||||
|
@ -509,7 +511,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
|||
"but texture height is not equal to 1, which is not supported by MED");
|
||||
}
|
||||
|
||||
pcNew = new aiTexture();
|
||||
pcNew.reset(new aiTexture());
|
||||
pcNew->mHeight = 0;
|
||||
pcNew->mWidth = iWidth;
|
||||
|
||||
|
@ -546,7 +548,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
|||
}
|
||||
else if (iMasked || !iType || (iType && iWidth && iHeight))
|
||||
{
|
||||
pcNew = new aiTexture();
|
||||
pcNew.reset(new aiTexture());
|
||||
if (!iHeight || !iWidth)
|
||||
{
|
||||
DefaultLogger::get()->warn("Found embedded texture, but its width "
|
||||
|
@ -577,7 +579,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
|||
pcNew->mHeight = iHeight;
|
||||
|
||||
unsigned int iSkip = 0;
|
||||
ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew);
|
||||
ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew.get());
|
||||
|
||||
// skip length of texture data
|
||||
szCurrent += iSkip;
|
||||
|
@ -588,7 +590,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
|||
// texture instead of material colors ... posssible they have
|
||||
// been converted to MDL7 from other formats, such as MDL5
|
||||
aiColor4D clrTexture;
|
||||
if (pcNew)clrTexture = ReplaceTextureWithColor(pcNew);
|
||||
if (pcNew)clrTexture = ReplaceTextureWithColor(pcNew.get());
|
||||
else clrTexture.r = get_qnan();
|
||||
|
||||
// check whether a material definition is contained in the skin
|
||||
|
@ -665,7 +667,9 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
|||
if (0.0f != pcMatIn->Power)
|
||||
{
|
||||
iShadingMode = (int)aiShadingMode_Phong;
|
||||
pcMatOut->AddProperty<float>(&pcMatIn->Power,1,AI_MATKEY_SHININESS);
|
||||
// pcMatIn is packed, we can't form pointers to its members
|
||||
float power = pcMatIn->Power;
|
||||
pcMatOut->AddProperty<float>(&power,1,AI_MATKEY_SHININESS);
|
||||
}
|
||||
pcMatOut->AddProperty<int>(&iShadingMode,1,AI_MATKEY_SHADING_MODEL);
|
||||
}
|
||||
|
@ -678,8 +682,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
|||
// we don't need the texture anymore
|
||||
if (is_not_qnan(clrTexture.r))
|
||||
{
|
||||
delete pcNew;
|
||||
pcNew = NULL;
|
||||
pcNew.reset();
|
||||
}
|
||||
|
||||
// If an ASCII effect description (HLSL?) is contained in the file,
|
||||
|
@ -714,7 +717,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
|||
{
|
||||
pScene->mNumTextures = 1;
|
||||
pScene->mTextures = new aiTexture*[1];
|
||||
pScene->mTextures[0] = pcNew;
|
||||
pScene->mTextures[0] = pcNew.release();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -724,16 +727,13 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
|||
pScene->mTextures[i] = pc[i];
|
||||
}
|
||||
|
||||
pScene->mTextures[pScene->mNumTextures] = pcNew;
|
||||
pScene->mTextures[pScene->mNumTextures] = pcNew.release();
|
||||
pScene->mNumTextures++;
|
||||
delete[] pc;
|
||||
}
|
||||
}
|
||||
VALIDATE_FILE_SIZE(szCurrent);
|
||||
*szCurrentOut = szCurrent;
|
||||
if ( nullptr != pcNew ) {
|
||||
delete pcNew;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -107,7 +107,7 @@ const aiImporterDesc *MMDImporter::GetInfo() const { return &desc; }
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// MMD import implementation
|
||||
void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
|
||||
IOSystem *pIOHandler) {
|
||||
IOSystem * /*pIOHandler*/) {
|
||||
// Read file by istream
|
||||
std::filebuf fb;
|
||||
if (!fb.open(file, std::ios::in | std::ios::binary)) {
|
||||
|
@ -118,7 +118,7 @@ void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
|
|||
|
||||
// Get the file-size and validate it, throwing an exception when fails
|
||||
fileStream.seekg(0, fileStream.end);
|
||||
size_t fileSize = fileStream.tellg();
|
||||
size_t fileSize = static_cast<size_t>(fileStream.tellg());
|
||||
fileStream.seekg(0, fileStream.beg);
|
||||
|
||||
if (fileSize < sizeof(pmx::PmxModel)) {
|
||||
|
@ -141,8 +141,6 @@ void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
|
|||
aiNode *pNode = new aiNode;
|
||||
if (!pModel->model_name.empty()) {
|
||||
pNode->mName.Set(pModel->model_name);
|
||||
} else {
|
||||
ai_assert(false);
|
||||
}
|
||||
|
||||
pScene->mRootNode = pNode;
|
||||
|
@ -170,7 +168,7 @@ void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
|
|||
}
|
||||
|
||||
// create node hierarchy for bone position
|
||||
aiNode **ppNode = new aiNode *[pModel->bone_count];
|
||||
std::unique_ptr<aiNode *[]> ppNode(new aiNode *[pModel->bone_count]);
|
||||
for (auto i = 0; i < pModel->bone_count; i++) {
|
||||
ppNode[i] = new aiNode(pModel->bones[i].bone_name);
|
||||
}
|
||||
|
@ -179,9 +177,9 @@ void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
|
|||
const pmx::PmxBone &bone = pModel->bones[i];
|
||||
|
||||
if (bone.parent_index < 0) {
|
||||
pScene->mRootNode->addChildren(1, ppNode + i);
|
||||
pScene->mRootNode->addChildren(1, ppNode.get() + i);
|
||||
} else {
|
||||
ppNode[bone.parent_index]->addChildren(1, ppNode + i);
|
||||
ppNode[bone.parent_index]->addChildren(1, ppNode.get() + i);
|
||||
|
||||
aiVector3D v3 = aiVector3D(
|
||||
bone.position[0] - pModel->bones[bone.parent_index].position[0],
|
||||
|
@ -278,7 +276,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
|
|||
bone_vertex_map[vsBDEF2_ptr->bone_index1].push_back(
|
||||
aiVertexWeight(index, vsBDEF2_ptr->bone_weight));
|
||||
bone_vertex_map[vsBDEF2_ptr->bone_index2].push_back(
|
||||
aiVertexWeight(index, 1.0 - vsBDEF2_ptr->bone_weight));
|
||||
aiVertexWeight(index, 1.0f - vsBDEF2_ptr->bone_weight));
|
||||
break;
|
||||
case pmx::PmxVertexSkinningType::BDEF4:
|
||||
bone_vertex_map[vsBDEF4_ptr->bone_index1].push_back(
|
||||
|
@ -295,7 +293,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
|
|||
bone_vertex_map[vsSDEF_ptr->bone_index1].push_back(
|
||||
aiVertexWeight(index, vsSDEF_ptr->bone_weight));
|
||||
bone_vertex_map[vsSDEF_ptr->bone_index2].push_back(
|
||||
aiVertexWeight(index, 1.0 - vsSDEF_ptr->bone_weight));
|
||||
aiVertexWeight(index, 1.0f - vsSDEF_ptr->bone_weight));
|
||||
break;
|
||||
case pmx::PmxVertexSkinningType::QDEF:
|
||||
const auto vsQDEF_ptr =
|
||||
|
@ -325,9 +323,11 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
|
|||
aiMatrix4x4::Translation(-pos, pBone->mOffsetMatrix);
|
||||
auto it = bone_vertex_map.find(ii);
|
||||
if (it != bone_vertex_map.end()) {
|
||||
pBone->mNumWeights = it->second.size();
|
||||
pBone->mWeights = it->second.data();
|
||||
it->second.swap(*(new vector<aiVertexWeight>));
|
||||
pBone->mNumWeights = static_cast<unsigned int>(it->second.size());
|
||||
pBone->mWeights = new aiVertexWeight[pBone->mNumWeights];
|
||||
for (unsigned int j = 0; j < pBone->mNumWeights; j++) {
|
||||
pBone->mWeights[j] = it->second[j];
|
||||
}
|
||||
}
|
||||
bone_ptr_ptr[ii] = pBone;
|
||||
}
|
||||
|
|
|
@ -49,17 +49,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace pmd
|
||||
{
|
||||
/// ヘッダ
|
||||
class PmdHeader
|
||||
{
|
||||
public:
|
||||
/// モデル名
|
||||
std::string name;
|
||||
/// モデル名(英語)
|
||||
std::string name_english;
|
||||
/// コメント
|
||||
std::string comment;
|
||||
/// コメント(英語)
|
||||
std::string comment_english;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
|
@ -83,26 +78,19 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// 頂点
|
||||
class PmdVertex
|
||||
{
|
||||
public:
|
||||
/// 位置
|
||||
float position[3];
|
||||
|
||||
/// 法線
|
||||
float normal[3];
|
||||
|
||||
/// UV座標
|
||||
float uv[2];
|
||||
|
||||
/// 関連ボーンインデックス
|
||||
uint16_t bone_index[2];
|
||||
|
||||
/// ボーンウェイト
|
||||
uint8_t bone_weight;
|
||||
|
||||
/// エッジ不可視
|
||||
bool edge_invisible;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
|
@ -117,27 +105,17 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// 材質
|
||||
class PmdMaterial
|
||||
{
|
||||
public:
|
||||
/// 減衰色
|
||||
float diffuse[4];
|
||||
/// 光沢度
|
||||
float power;
|
||||
/// 光沢色
|
||||
float specular[3];
|
||||
/// 環境色
|
||||
float ambient[3];
|
||||
/// トーンインデックス
|
||||
uint8_t toon_index;
|
||||
/// エッジ
|
||||
uint8_t edge_flag;
|
||||
/// インデックス数
|
||||
uint32_t index_count;
|
||||
/// テクスチャファイル名
|
||||
std::string texture_filename;
|
||||
/// スフィアファイル名
|
||||
std::string sphere_filename;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
|
@ -180,23 +158,15 @@ namespace pmd
|
|||
RotationMovement
|
||||
};
|
||||
|
||||
/// ボーン
|
||||
class PmdBone
|
||||
{
|
||||
public:
|
||||
/// ボーン名
|
||||
std::string name;
|
||||
/// ボーン名(英語)
|
||||
std::string name_english;
|
||||
/// 親ボーン番号
|
||||
uint16_t parent_bone_index;
|
||||
/// 末端ボーン番号
|
||||
uint16_t tail_pos_bone_index;
|
||||
/// ボーン種類
|
||||
BoneType bone_type;
|
||||
/// IKボーン番号
|
||||
uint16_t ik_parent_bone_index;
|
||||
/// ボーンのヘッドの位置
|
||||
float bone_head_pos[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
|
@ -219,19 +189,13 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// IK
|
||||
class PmdIk
|
||||
{
|
||||
public:
|
||||
/// IKボーン番号
|
||||
uint16_t ik_bone_index;
|
||||
/// IKターゲットボーン番号
|
||||
uint16_t target_bone_index;
|
||||
/// 再帰回数
|
||||
uint16_t interations;
|
||||
/// 角度制限
|
||||
float angle_limit;
|
||||
/// 影響下ボーン番号
|
||||
std::vector<uint16_t> ik_child_bone_index;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
|
@ -303,7 +267,6 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// ボーン枠用の枠名
|
||||
class PmdBoneDispName
|
||||
{
|
||||
public:
|
||||
|
@ -338,59 +301,36 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// 衝突形状
|
||||
enum class RigidBodyShape : uint8_t
|
||||
{
|
||||
/// 球
|
||||
Sphere = 0,
|
||||
/// 直方体
|
||||
Box = 1,
|
||||
/// カプセル
|
||||
Cpusel = 2
|
||||
};
|
||||
|
||||
/// 剛体タイプ
|
||||
enum class RigidBodyType : uint8_t
|
||||
{
|
||||
/// ボーン追従
|
||||
BoneConnected = 0,
|
||||
/// 物理演算
|
||||
Physics = 1,
|
||||
/// 物理演算(Bone位置合せ)
|
||||
ConnectedPhysics = 2
|
||||
};
|
||||
|
||||
/// 剛体
|
||||
class PmdRigidBody
|
||||
{
|
||||
public:
|
||||
/// 名前
|
||||
std::string name;
|
||||
/// 関連ボーン番号
|
||||
uint16_t related_bone_index;
|
||||
/// グループ番号
|
||||
uint8_t group_index;
|
||||
/// マスク
|
||||
uint16_t mask;
|
||||
/// 形状
|
||||
RigidBodyShape shape;
|
||||
/// 大きさ
|
||||
float size[3];
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 回転
|
||||
float orientation[3];
|
||||
/// 質量
|
||||
float weight;
|
||||
/// 移動ダンピング
|
||||
float linear_damping;
|
||||
/// 回転ダンピング
|
||||
float anglar_damping;
|
||||
/// 反発係数
|
||||
float restitution;
|
||||
/// 摩擦係数
|
||||
float friction;
|
||||
/// 演算方法
|
||||
RigidBodyType rigid_type;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
|
@ -414,31 +354,19 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// 剛体の拘束
|
||||
class PmdConstraint
|
||||
{
|
||||
public:
|
||||
/// 名前
|
||||
std::string name;
|
||||
/// 剛体Aのインデックス
|
||||
uint32_t rigid_body_index_a;
|
||||
/// 剛体Bのインデックス
|
||||
uint32_t rigid_body_index_b;
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 回転
|
||||
float orientation[3];
|
||||
/// 最小移動制限
|
||||
float linear_lower_limit[3];
|
||||
/// 最大移動制限
|
||||
float linear_upper_limit[3];
|
||||
/// 最小回転制限
|
||||
float angular_lower_limit[3];
|
||||
/// 最大回転制限
|
||||
float angular_upper_limit[3];
|
||||
/// 移動に対する復元力
|
||||
float linear_stiffness[3];
|
||||
/// 回転に対する復元力
|
||||
float angular_stiffness[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
|
@ -459,7 +387,6 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// PMDモデル
|
||||
class PmdModel
|
||||
{
|
||||
public:
|
||||
|
@ -491,7 +418,6 @@ namespace pmd
|
|||
return result;
|
||||
}
|
||||
|
||||
/// ファイルからPmdModelを生成する
|
||||
static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream)
|
||||
{
|
||||
auto result = mmd::make_unique<PmdModel>();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue