Merge pull request #2 from assimp/master

Updating to latest version from origin
pull/2987/head
Tomas Mariancik 2019-10-18 14:30:34 +02:00 committed by GitHub
commit d8979cbc1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
165 changed files with 3393 additions and 4817 deletions

View File

@ -7,6 +7,7 @@
# #
function generate() { function generate() {
OPTIONS="-DASSIMP_WERROR=ON" OPTIONS="-DASSIMP_WERROR=ON"
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=NO"
if [ "$DISABLE_EXPORTERS" = "YES" ] ; then if [ "$DISABLE_EXPORTERS" = "YES" ] ; then
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=YES" OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=YES"

View File

@ -0,0 +1,26 @@
:: This is an example file to generate binaries using Windows Operating System
:: This script is configured to be executed from the source directory
:: Compiled binaries will be placed in BINARIES_DIR\code\CONFIG
:: NOTE
:: The build process will generate a config.h file that is placed in BINARIES_DIR\include
:: This file must be merged with SOURCE_DIR\include
:: You should write yourself a script that copies the files where you want them.
:: Also see: https://github.com/assimp/assimp/pull/2646
SET SOURCE_DIR=.
:: For generators see "cmake --help"
SET GENERATOR=Visual Studio 15 2017
SET BINARIES_DIR="./BINARIES/Win32"
cmake CMakeLists.txt -G "%GENERATOR%" -S %SOURCE_DIR% -B %BINARIES_DIR%
cmake --build %BINARIES_DIR% --config release
SET BINARIES_DIR="./BINARIES/x64"
cmake CMakeLists.txt -G "%GENERATOR% Win64" -S %SOURCE_DIR% -B %BINARIES_DIR%
cmake --build %BINARIES_DIR% --config debug
cmake --build %BINARIES_DIR% --config release
PAUSE

View File

@ -1,17 +1,31 @@
# Build Instructions # Build Instructions
## Install CMake
## Build on all platforms using vcpkg
You can download and install assimp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
```bash
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install assimp
```
The assimp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Manual build instructions
### Install CMake
Asset-Importer-Lib can be build for a lot of different platforms. We are using cmake to generate the build environment for these via cmake. So you have to make sure that you have a working cmake-installation on your system. You can download it at https://cmake.org/ or for linux install it via Asset-Importer-Lib can be build for a lot of different platforms. We are using cmake to generate the build environment for these via cmake. So you have to make sure that you have a working cmake-installation on your system. You can download it at https://cmake.org/ or for linux install it via
```bash ```bash
sudo apt-get install cmake sudo apt-get install cmake
``` ```
## Get the source ### Get the source
Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via: Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
```bash ```bash
git clone https://github.com/assimp/assimp.git git clone https://github.com/assimp/assimp.git
``` ```
## Build instructions for Windows with Visual-Studio ### Build instructions for Windows with Visual-Studio
First you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/ First you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
To generate the build environment for your IDE open a command prompt, navigate to your repo and type: To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
@ -20,10 +34,10 @@ cmake CMakeLists.txt
``` ```
This will generate the project files for the visual studio. All dependencies used to build Asset-IMporter-Lib shall be part of the repo. If you want to use you own zlib.installation this is possible as well. Check the options for it. This will generate the project files for the visual studio. All dependencies used to build Asset-IMporter-Lib shall be part of the repo. If you want to use you own zlib.installation this is possible as well. Check the options for it.
## Build instructions for Windows with UWP ### Build instructions for Windows with UWP
See <https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app> See <https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app>
## Build instructions for Linux / Unix ### Build instructions for Linux / Unix
Open a terminal and got to your repository. You can generate the makefiles and build the library via: Open a terminal and got to your repository. You can generate the makefiles and build the library via:
```bash ```bash
@ -34,7 +48,7 @@ The option -j descripes the number of parallel processes for the build. In this
If you want to use a IDE for linux you can try QTCreator for instance. If you want to use a IDE for linux you can try QTCreator for instance.
## Build instructions for MinGW ### Build instructions for MinGW
Older versions of MinGW's compiler (e.g. 5.1.0) do not support the -mbig_obj flag Older versions of MinGW's compiler (e.g. 5.1.0) do not support the -mbig_obj flag
required to compile some of assimp's files, especially for debug builds. required to compile some of assimp's files, especially for debug builds.
Version 7.3.0 of g++-mingw-w64 & gcc-mingw-w64 appears to work. Version 7.3.0 of g++-mingw-w64 & gcc-mingw-w64 appears to work.
@ -50,7 +64,7 @@ The following toolchain may or may not be helpful for building assimp using MinG
Besides the toolchain, compilation should be the same as for Linux / Unix. Besides the toolchain, compilation should be the same as for Linux / Unix.
## CMake build options ### CMake build options
The cmake-build-environment provides options to configure the build. The following options can be used: The cmake-build-environment provides options to configure the build. The following options can be used:
- **BUILD_SHARED_LIBS ( default ON )**: Generation of shared libs ( dll for windows, so for Linux ). Set this to OFF to get a static lib. - **BUILD_SHARED_LIBS ( default ON )**: Generation of shared libs ( dll for windows, so for Linux ). Set this to OFF to get a static lib.
- **BUILD_FRAMEWORK ( default OFF, MacOnly)**: Build package as Mac OS X Framework bundle - **BUILD_FRAMEWORK ( default OFF, MacOnly)**: Build package as Mac OS X Framework bundle

View File

@ -253,7 +253,7 @@ ELSEIF(MSVC)
IF(MSVC12) IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351) ADD_COMPILE_OPTIONS(/wd4351)
ENDIF() ENDIF()
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2") SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2 /DEBUG:FULL /Zi")
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
IF(NOT HUNTER_ENABLED) IF(NOT HUNTER_ENABLED)
SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}") SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}")
@ -271,22 +271,20 @@ ELSEIF( CMAKE_COMPILER_IS_MINGW )
SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}") SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
ENDIF() ENDIF()
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj ${CMAKE_CXX_FLAGS}") SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}") SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
ADD_DEFINITIONS( -U__STRICT_ANSI__ ) ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF() ENDIF()
IF ( IOS AND NOT HUNTER_ENABLED) IF ( IOS AND NOT HUNTER_ENABLED)
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
ELSE() ELSE()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
# Experimental for pdb generation # Experimental for pdb generation
ENDIF() ENDIF()
ENDIF( IOS AND NOT HUNTER_ENABLED) ENDIF( IOS AND NOT HUNTER_ENABLED)
IF (ASSIMP_COVERALLS) IF (ASSIMP_COVERALLS)
@ -559,17 +557,15 @@ ENDIF(NOT HUNTER_ENABLED)
ADD_SUBDIRECTORY( code/ ) ADD_SUBDIRECTORY( code/ )
IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
# The viewer for windows only
IF ( WIN32 AND DirectX_D3DX9_LIBRARY ) IF ( WIN32 AND DirectX_D3DX9_LIBRARY )
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} ) OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} )
IF ( ASSIMP_BUILD_ASSIMP_VIEW ) IF ( ASSIMP_BUILD_ASSIMP_VIEW )
ADD_SUBDIRECTORY( tools/assimp_view/ ) ADD_SUBDIRECTORY( tools/assimp_view/ )
ENDIF ( ASSIMP_BUILD_ASSIMP_VIEW ) ENDIF ( ASSIMP_BUILD_ASSIMP_VIEW )
ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY ) ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
# Te command line tool
ADD_SUBDIRECTORY( tools/assimp_cmd/ ) ADD_SUBDIRECTORY( tools/assimp_cmd/ )
IF (NOT IOS)
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
ENDIF (NOT IOS)
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS ) ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
IF ( ASSIMP_BUILD_SAMPLES) IF ( ASSIMP_BUILD_SAMPLES)

View File

@ -120,7 +120,7 @@ __Exporters__:
- FBX ( experimental ) - FBX ( experimental )
### Building ### ### Building ###
Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. Our build system is CMake, if you used CMake before there is a good chance you know what to do. Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
### Ports ### ### Ports ###
* [Android](port/AndroidJNI/README.md) * [Android](port/AndroidJNI/README.md)

View File

@ -16,6 +16,8 @@ matrix:
image: image:
- Visual Studio 2015 - Visual Studio 2015
- Visual Studio 2017 - Visual Studio 2017
- Visual Studio 2019
- MinGW
platform: platform:
- Win32 - Win32
@ -26,10 +28,13 @@ configuration: Release
install: install:
- set PATH=C:\Ruby24-x64\bin;%PATH% - set PATH=C:\Ruby24-x64\bin;%PATH%
- set CMAKE_DEFINES -DASSIMP_WERROR=ON - set CMAKE_DEFINES -DASSIMP_WERROR=ON
- if [%COMPILER%]==[MinGW] set PATH=C:\MinGW\bin;%PATH%
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015 - 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 "%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 - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2019" set CMAKE_GENERATOR_NAME=Visual Studio 16 2019
- cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%" . - cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%" -A %platform% .
# Rename sh.exe as sh.exe in PATH interferes with MinGW
- rename "C:\Program Files\Git\usr\bin\sh.exe" "sh2.exe"
- set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5" - set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5"
- ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/5/7/b/57b2947c-7221-4f33-b35e-2fc78cb10df4/vc_redist.x64.exe -OutFile .\packaging\windows-innosetup\vc_redist.x64.exe - ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/5/7/b/57b2947c-7221-4f33-b35e-2fc78cb10df4/vc_redist.x64.exe -OutFile .\packaging\windows-innosetup\vc_redist.x64.exe
- ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/1/d/8/1d8137db-b5bb-4925-8c5d-927424a2e4de/vc_redist.x86.exe -OutFile .\packaging\windows-innosetup\vc_redist.x86.exe - ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/1/d/8/1d8137db-b5bb-4925-8c5d-927424a2e4de/vc_redist.x86.exe -OutFile .\packaging\windows-innosetup\vc_redist.x86.exe

View File

@ -63,7 +63,11 @@ if(MSVC)
else() else()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the assimp libraries" ) set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the assimp libraries" )
if(ASSIMP_BUILD_SHARED_LIBS) if(ASSIMP_BUILD_SHARED_LIBS)
if(APPLE)
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@.@ASSIMP_VERSION_MAJOR@@CMAKE_SHARED_LIBRARY_SUFFIX@")
else(APPLE)
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@") set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
endif()
set_target_properties(assimp::assimp PROPERTIES set_target_properties(assimp::assimp PROPERTIES
IMPORTED_SONAME_DEBUG "${sharedLibraryName}" IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${sharedLibraryName}" IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"

View File

@ -63,7 +63,11 @@ if(MSVC)
else() else()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the assimp libraries" ) set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the assimp libraries" )
if(ASSIMP_BUILD_SHARED_LIBS) if(ASSIMP_BUILD_SHARED_LIBS)
if(APPLE)
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}.@ASSIMP_VERSION_MAJOR@@CMAKE_SHARED_LIBRARY_SUFFIX@")
else(APPLE)
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@") set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
endif()
set_target_properties(assimp::assimp PROPERTIES set_target_properties(assimp::assimp PROPERTIES
IMPORTED_SONAME_RELEASE "${sharedLibraryName}" IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${sharedLibraryName}" IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"

View File

@ -54,14 +54,18 @@ else(WIN32)
find_path( find_path(
assimp_INCLUDE_DIRS assimp_INCLUDE_DIRS
NAMES postprocess.h scene.h version.h config.h cimport.h NAMES assimp/postprocess.h assimp/scene.h assimp/version.h assimp/config.h assimp/cimport.h
PATHS /usr/local/include/ PATHS /usr/local/include
PATHS /usr/include/
) )
find_library( find_library(
assimp_LIBRARIES assimp_LIBRARIES
NAMES assimp NAMES assimp
PATHS /usr/local/lib/ PATHS /usr/local/lib/
PATHS /usr/lib64/
PATHS /usr/lib/
) )
if (assimp_INCLUDE_DIRS AND assimp_LIBRARIES) if (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)

View File

@ -50,9 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
// internal headers
#include "3DSLoader.h" #include "3DSLoader.h"
#include <assimp/Macros.h>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>

View File

@ -83,7 +83,7 @@ void AMFImporter::Clear()
mMaterial_Converted.clear(); mMaterial_Converted.clear();
mTexture_Converted.clear(); mTexture_Converted.clear();
// Delete all elements // Delete all elements
if(mNodeElement_List.size()) if(!mNodeElement_List.empty())
{ {
for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; } for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; }

View File

@ -66,7 +66,7 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
aiColor4D tcol; aiColor4D tcol;
// Check if stored data are supported. // Check if stored data are supported.
if(Composition.size() != 0) if(!Composition.empty())
{ {
throw DeadlyImportError("IME. GetColor for composition"); throw DeadlyImportError("IME. GetColor for composition");
} }
@ -321,7 +321,7 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
}; };
pOutputList_Separated.clear(); pOutputList_Separated.clear();
if(pInputList.size() == 0) return; if(pInputList.empty()) return;
do do
{ {
@ -334,19 +334,19 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
{ {
auto it_old = it; auto it_old = it;
it++; ++it;
face_list_cur.push_back(*it_old); face_list_cur.push_back(*it_old);
pInputList.erase(it_old); pInputList.erase(it_old);
} }
else else
{ {
it++; ++it;
} }
} }
if(face_list_cur.size() > 0) pOutputList_Separated.push_back(face_list_cur); if(!face_list_cur.empty()) pOutputList_Separated.push_back(face_list_cur);
} while(pInputList.size() > 0); } while(!pInputList.empty());
} }
void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
@ -712,7 +712,7 @@ std::list<unsigned int> mesh_idx;
}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child) }// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
// if meshes was created then assign new indices with current aiNode // if meshes was created then assign new indices with current aiNode
if(mesh_idx.size() > 0) if(!mesh_idx.empty())
{ {
std::list<unsigned int>::const_iterator mit = mesh_idx.begin(); std::list<unsigned int>::const_iterator mit = mesh_idx.begin();
@ -787,7 +787,7 @@ std::list<aiNode*> ch_node;
}// for(const CAMFImporter_NodeElement* ne: pConstellation.Child) }// for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
// copy found aiNode's as children // copy found aiNode's as children
if(ch_node.size() == 0) throw DeadlyImportError("<constellation> must have at least one <instance>."); if(ch_node.empty()) throw DeadlyImportError("<constellation> must have at least one <instance>.");
size_t ch_idx = 0; size_t ch_idx = 0;
@ -883,13 +883,13 @@ nl_clean_loop:
if(node_list.size() > 1) if(node_list.size() > 1)
{ {
// walk through all nodes // walk through all nodes
for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++) for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); ++nl_it)
{ {
// and try to find them in another top nodes. // and try to find them in another top nodes.
std::list<aiNode*>::const_iterator next_it = nl_it; std::list<aiNode*>::const_iterator next_it = nl_it;
next_it++; ++next_it;
for(; next_it != node_list.end(); next_it++) for(; next_it != node_list.end(); ++next_it)
{ {
if((*next_it)->FindNode((*nl_it)->mName) != nullptr) if((*next_it)->FindNode((*nl_it)->mName) != nullptr)
{ {
@ -907,7 +907,7 @@ nl_clean_loop:
// //
// //
// Nodes // Nodes
if(node_list.size() > 0) if(!node_list.empty())
{ {
std::list<aiNode*>::const_iterator nl_it = node_list.begin(); std::list<aiNode*>::const_iterator nl_it = node_list.begin();
@ -924,7 +924,7 @@ nl_clean_loop:
// //
// Meshes // Meshes
if(mesh_list.size() > 0) if(!mesh_list.empty())
{ {
std::list<aiMesh*>::const_iterator ml_it = mesh_list.begin(); std::list<aiMesh*>::const_iterator ml_it = mesh_list.begin();

View File

@ -137,7 +137,6 @@ SET( PUBLIC_HEADERS
${HEADER_PATH}/irrXMLWrapper.h ${HEADER_PATH}/irrXMLWrapper.h
${HEADER_PATH}/BlobIOSystem.h ${HEADER_PATH}/BlobIOSystem.h
${HEADER_PATH}/MathFunctions.h ${HEADER_PATH}/MathFunctions.h
${HEADER_PATH}/Macros.h
${HEADER_PATH}/Exceptional.h ${HEADER_PATH}/Exceptional.h
${HEADER_PATH}/ByteSwapper.h ${HEADER_PATH}/ByteSwapper.h
) )
@ -766,6 +765,8 @@ ADD_ASSIMP_EXPORTER( X3D
) )
ADD_ASSIMP_IMPORTER( GLTF ADD_ASSIMP_IMPORTER( GLTF
glTF/glTFCommon.h
glTF/glTFCommon.cpp
glTF/glTFAsset.h glTF/glTFAsset.h
glTF/glTFAsset.inl glTF/glTFAsset.inl
glTF/glTFAssetWriter.h glTF/glTFAssetWriter.h
@ -1057,6 +1058,8 @@ MESSAGE(STATUS "Disabled importer formats:${ASSIMP_IMPORTERS_DISABLED}")
MESSAGE(STATUS "Enabled exporter formats:${ASSIMP_EXPORTERS_ENABLED}") MESSAGE(STATUS "Enabled exporter formats:${ASSIMP_EXPORTERS_ENABLED}")
MESSAGE(STATUS "Disabled exporter formats:${ASSIMP_EXPORTERS_DISABLED}") MESSAGE(STATUS "Disabled exporter formats:${ASSIMP_EXPORTERS_DISABLED}")
SOURCE_GROUP( include\\assimp FILES ${PUBLIC_HEADERS} )
SET( assimp_src SET( assimp_src
# Assimp Files # Assimp Files
${Core_SRCS} ${Core_SRCS}

View File

@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ColladaExporter.h" #include "ColladaExporter.h"
#include <assimp/Bitmap.h> #include <assimp/Bitmap.h>
#include <assimp/MathFunctions.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/SceneCombiner.h> #include <assimp/SceneCombiner.h>
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
@ -155,7 +156,7 @@ void ColladaExporter::WriteFile() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Writes the asset header // Writes the asset header
void ColladaExporter::WriteHeader() { void ColladaExporter::WriteHeader() {
static const ai_real epsilon = ai_real( 0.00001 ); static const ai_real epsilon = Math::getEpsilon<ai_real>();
static const aiQuaternion x_rot(aiMatrix3x3( static const aiQuaternion x_rot(aiMatrix3x3(
0, -1, 0, 0, -1, 0,
1, 0, 0, 1, 0, 0,
@ -317,7 +318,7 @@ void ColladaExporter::WriteTextures() {
std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char*) texture->achFormatHint); std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char*) texture->achFormatHint);
std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + name, "wb")); std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb"));
if(outfile == NULL) { if(outfile == NULL) {
throw DeadlyExportError("could not open output texture file: " + mPath + name); throw DeadlyExportError("could not open output texture file: " + mPath + name);
} }

View File

@ -588,7 +588,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser& pParser, const Colla
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Find mesh from either meshes or morph target meshes // Find mesh from either meshes or morph target meshes
aiMesh *ColladaLoader::findMesh(std::string meshid) { aiMesh *ColladaLoader::findMesh(const std::string& meshid) {
for (unsigned int i = 0; i < mMeshes.size(); ++i) { for (unsigned int i = 0; i < mMeshes.size(); ++i) {
if (std::string(mMeshes[i]->mName.data) == meshid) { if (std::string(mMeshes[i]->mName.data) == meshid) {
return mMeshes[i]; return mMeshes[i];
@ -688,7 +688,7 @@ aiMesh* ColladaLoader::CreateMesh(const ColladaParser& pParser, const Collada::M
Collada::MorphMethod method = Collada::Normalized; Collada::MorphMethod method = Collada::Normalized;
for (std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin(); for (std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
it != pParser.mControllerLibrary.end(); it++) { it != pParser.mControllerLibrary.end(); ++it) {
const Collada::Controller &c = it->second; const Collada::Controller &c = it->second;
const Collada::Mesh* baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId); const Collada::Mesh* baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId);

View File

@ -120,7 +120,7 @@ protected:
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode, void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget); aiNode* pTarget);
aiMesh *findMesh(std::string meshid); aiMesh *findMesh(const std::string& meshid);
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */ /** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh, aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,

View File

@ -76,9 +76,25 @@ BaseImporter::~BaseImporter() {
// nothing to do here // nothing to do here
} }
void BaseImporter::UpdateImporterScale( Importer* pImp )
{
ai_assert(pImp != nullptr);
ai_assert(importerScale != 0.0);
ai_assert(fileScale != 0.0);
double activeScale = importerScale * fileScale;
// Set active scaling
pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) );
ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file and returns the imported data. // Imports the given file and returns the imported data.
aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) { aiScene* BaseImporter::ReadFile(Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
m_progress = pImp->GetProgressHandler(); m_progress = pImp->GetProgressHandler();
if (nullptr == m_progress) { if (nullptr == m_progress) {
return nullptr; return nullptr;
@ -100,6 +116,11 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
{ {
InternReadFile( pFile, sc.get(), &filter); InternReadFile( pFile, sc.get(), &filter);
// Calculate import scale hook - required because pImp not available anywhere else
// passes scale into ScaleProcess
UpdateImporterScale(pImp);
} catch( const std::exception& err ) { } catch( const std::exception& err ) {
// extract error description // extract error description
m_ErrorText = err.what(); m_ErrorText = err.what();
@ -112,7 +133,7 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BaseImporter::SetupProperties(const Importer* /*pImp*/) void BaseImporter::SetupProperties(const Importer* pImp)
{ {
// the default implementation does nothing // the default implementation does nothing
} }
@ -588,6 +609,8 @@ aiScene* BatchLoader::GetImport( unsigned int which )
return nullptr; return nullptr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BatchLoader::LoadAll() void BatchLoader::LoadAll()
{ {

View File

@ -61,83 +61,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
// maximum path length #ifdef _WIN32
// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html static std::wstring Utf8ToWide(const char* in)
#ifdef PATH_MAX {
# define PATHLIMIT PATH_MAX int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0);
#else // size includes terminating null; std::wstring adds null automatically
# define PATHLIMIT 4096 std::wstring out(static_cast<size_t>(size) - 1, L'\0');
MultiByteToWideChar(CP_UTF8, 0, in, -1, &out[0], size);
return out;
}
static std::string WideToUtf8(const wchar_t* in)
{
int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr);
// size includes terminating null; std::string adds null automatically
std::string out(static_cast<size_t>(size) - 1, '\0');
WideCharToMultiByte(CP_UTF8, 0, in, -1, &out[0], size, nullptr, nullptr);
return out;
}
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Tests for the existence of a file at the given path. // Tests for the existence of a file at the given path.
bool DefaultIOSystem::Exists( const char* pFile) const bool DefaultIOSystem::Exists(const char* pFile) const
{ {
#ifdef _WIN32 #ifdef _WIN32
wchar_t fileName16[PATHLIMIT];
#ifndef WindowsStore
bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
if (isUnicode) {
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
struct __stat64 filestat; struct __stat64 filestat;
if (0 != _wstat64(fileName16, &filestat)) { if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) {
return false; return false;
} }
} else { #else
#endif
FILE* file = ::fopen(pFile, "rb"); FILE* file = ::fopen(pFile, "rb");
if (!file) if (!file)
return false; return false;
::fclose(file); ::fclose(file);
#ifndef WindowsStore
}
#endif
#else
FILE* file = ::fopen( pFile, "rb");
if( !file)
return false;
::fclose( file);
#endif #endif
return true; return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Open a new file with a given path. // Open a new file with a given path.
IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode) IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode)
{ {
ai_assert(NULL != strFile); ai_assert(strFile != nullptr);
ai_assert(NULL != strMode); ai_assert(strMode != nullptr);
FILE* file; FILE* file;
#ifdef _WIN32 #ifdef _WIN32
wchar_t fileName16[PATHLIMIT]; file = ::_wfopen(Utf8ToWide(strFile).c_str(), Utf8ToWide(strMode).c_str());
#ifndef WindowsStore
bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
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 {
#endif
file = ::fopen(strFile, strMode);
#ifndef WindowsStore
}
#endif
#else #else
file = ::fopen(strFile, strMode); file = ::fopen(strFile, strMode);
#endif #endif
if (nullptr == file) if (!file)
return nullptr; return nullptr;
return new DefaultIOStream(file, (std::string) strFile); return new DefaultIOStream(file, strFile);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Closes the given file and releases all resources associated with it. // Closes the given file and releases all resources associated with it.
void DefaultIOSystem::Close( IOStream* pFile) void DefaultIOSystem::Close(IOStream* pFile)
{ {
delete pFile; delete pFile;
} }
@ -155,78 +138,56 @@ char DefaultIOSystem::getOsSeparator() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// IOSystem default implementation (ComparePaths isn't a pure virtual function) // IOSystem default implementation (ComparePaths isn't a pure virtual function)
bool IOSystem::ComparePaths (const char* one, const char* second) const bool IOSystem::ComparePaths(const char* one, const char* second) const
{ {
return !ASSIMP_stricmp(one,second); return !ASSIMP_stricmp(one, second);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Convert a relative path into an absolute path // Convert a relative path into an absolute path
inline static void MakeAbsolutePath (const char* in, char* _out) inline static std::string MakeAbsolutePath(const char* in)
{ {
ai_assert(in && _out); ai_assert(in);
#if defined( _MSC_VER ) || defined( __MINGW32__ ) std::string out;
#ifndef WindowsStore #ifdef _WIN32
bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0; wchar_t* ret = ::_wfullpath(nullptr, Utf8ToWide(in).c_str(), 0);
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) { if (ret) {
WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr); out = WideToUtf8(ret);
free(ret);
} }
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)
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
strcpy(_out, in);
}
} else {
#endif
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)
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
strcpy(_out, in);
}
#ifndef WindowsStore
}
#endif
#else #else
// use realpath char* ret = realpath(in, nullptr);
char* ret = realpath(in, _out); if (ret) {
if(!ret) { out = ret;
free(ret);
}
#endif
if (!ret) {
// preserve the input path, maybe someone else is able to fix // preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter) // the path before it is accessed (e.g. our file system filter)
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in)); ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
strcpy(_out,in); out = in;
} }
#endif return out;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// DefaultIOSystem's more specialized implementation // DefaultIOSystem's more specialized implementation
bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const
{ {
// chances are quite good both paths are formatted identically, // chances are quite good both paths are formatted identically,
// so we can hopefully return here already // so we can hopefully return here already
if( !ASSIMP_stricmp(one,second) ) if (!ASSIMP_stricmp(one, second))
return true; return true;
char temp1[PATHLIMIT]; std::string temp1 = MakeAbsolutePath(one);
char temp2[PATHLIMIT]; std::string temp2 = MakeAbsolutePath(second);
MakeAbsolutePath (one, temp1); return !ASSIMP_stricmp(temp1, temp2);
MakeAbsolutePath (second, temp2);
return !ASSIMP_stricmp(temp1,temp2);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::fileName( const std::string &path ) std::string DefaultIOSystem::fileName(const std::string& path)
{ {
std::string ret = path; std::string ret = path;
std::size_t last = ret.find_last_of("\\/"); std::size_t last = ret.find_last_of("\\/");
@ -235,16 +196,16 @@ std::string DefaultIOSystem::fileName( const std::string &path )
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::completeBaseName( const std::string &path ) std::string DefaultIOSystem::completeBaseName(const std::string& path)
{ {
std::string ret = fileName(path); std::string ret = fileName(path);
std::size_t pos = ret.find_last_of('.'); std::size_t pos = ret.find_last_of('.');
if(pos != ret.npos) ret = ret.substr(0, pos); if (pos != std::string::npos) ret = ret.substr(0, pos);
return ret; return ret;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::absolutePath( const std::string &path ) std::string DefaultIOSystem::absolutePath(const std::string& path)
{ {
std::string ret = path; std::string ret = path;
std::size_t last = ret.find_last_of("\\/"); std::size_t last = ret.find_last_of("\\/");
@ -253,5 +214,3 @@ std::string DefaultIOSystem::absolutePath( const std::string &path )
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#undef PATHLIMIT

View File

@ -315,34 +315,6 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
return pimpl->blob; return pimpl->blob;
} }
// ------------------------------------------------------------------------------------------------
bool IsVerboseFormat(const aiMesh* mesh) {
// avoid slow vector<bool> specialization
std::vector<unsigned int> seen(mesh->mNumVertices,0);
for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
const aiFace& f = mesh->mFaces[i];
for(unsigned int j = 0; j < f.mNumIndices; ++j) {
if(++seen[f.mIndices[j]] == 2) {
// found a duplicate index
return false;
}
}
}
return true;
}
// ------------------------------------------------------------------------------------------------
bool IsVerboseFormat(const aiScene* pScene) {
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
if(!IsVerboseFormat(pScene->mMeshes[i])) {
return false;
}
}
return true;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath, aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
unsigned int pPreprocessing, const ExportProperties* pProperties) { unsigned int pPreprocessing, const ExportProperties* pProperties) {
@ -352,7 +324,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
// format. They will likely not be aware that there is a flag in the scene to indicate // format. They will likely not be aware that there is a flag in the scene to indicate
// this, however. To avoid surprises and bug reports, we check for duplicates in // this, however. To avoid surprises and bug reports, we check for duplicates in
// meshes upfront. // meshes upfront.
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene); const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || MakeVerboseFormatProcess::IsVerboseFormat(pScene);
pimpl->mProgressHandler->UpdateFileWrite(0, 4); pimpl->mProgressHandler->UpdateFileWrite(0, 4);
@ -472,7 +444,10 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
} }
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry. ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties); ExportProperties* pProp = pProperties ? (ExportProperties*)pProperties : &emptyProperties;
pProp->SetPropertyBool("bJoinIdenticalVertices", must_join_again);
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
pimpl->mProgressHandler->UpdateFileWrite(4, 4); pimpl->mProgressHandler->UpdateFileWrite(4, 4);
} catch (DeadlyExportError& err) { } catch (DeadlyExportError& err) {

View File

@ -1091,6 +1091,35 @@ void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) {
aiFace& f = dest->mFaces[i]; aiFace& f = dest->mFaces[i];
GetArrayCopy(f.mIndices,f.mNumIndices); GetArrayCopy(f.mIndices,f.mNumIndices);
} }
// make a deep copy of all blend shapes
CopyPtrArray(dest->mAnimMeshes, dest->mAnimMeshes, dest->mNumAnimMeshes);
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy(aiAnimMesh** _dest, const aiAnimMesh* src) {
if (nullptr == _dest || nullptr == src) {
return;
}
aiAnimMesh* dest = *_dest = new aiAnimMesh();
// get a flat copy
::memcpy(dest, src, sizeof(aiAnimMesh));
// and reallocate all arrays
GetArrayCopy(dest->mVertices, dest->mNumVertices);
GetArrayCopy(dest->mNormals, dest->mNumVertices);
GetArrayCopy(dest->mTangents, dest->mNumVertices);
GetArrayCopy(dest->mBitangents, dest->mNumVertices);
unsigned int n = 0;
while (dest->HasTextureCoords(n))
GetArrayCopy(dest->mTextureCoords[n++], dest->mNumVertices);
n = 0;
while (dest->HasVertexColors(n))
GetArrayCopy(dest->mColors[n++], dest->mNumVertices);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1167,6 +1196,7 @@ void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src ) {
// and reallocate all arrays // and reallocate all arrays
CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels ); CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels );
CopyPtrArray( dest->mMorphMeshChannels, src->mMorphMeshChannels, dest->mNumMorphMeshChannels );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1186,6 +1216,26 @@ void SceneCombiner::Copy(aiNodeAnim** _dest, const aiNodeAnim* src) {
GetArrayCopy( dest->mRotationKeys, dest->mNumRotationKeys ); GetArrayCopy( dest->mRotationKeys, dest->mNumRotationKeys );
} }
void SceneCombiner::Copy(aiMeshMorphAnim** _dest, const aiMeshMorphAnim* src) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
aiMeshMorphAnim* dest = *_dest = new aiMeshMorphAnim();
// get a flat copy
::memcpy(dest,src,sizeof(aiMeshMorphAnim));
// and reallocate all arrays
GetArrayCopy( dest->mKeys, dest->mNumKeys );
for (ai_uint i = 0; i < dest->mNumKeys;++i) {
dest->mKeys[i].mValues = new unsigned int[dest->mKeys[i].mNumValuesAndWeights];
dest->mKeys[i].mWeights = new double[dest->mKeys[i].mNumValuesAndWeights];
::memcpy(dest->mKeys[i].mValues, src->mKeys[i].mValues, dest->mKeys[i].mNumValuesAndWeights * sizeof(unsigned int));
::memcpy(dest->mKeys[i].mWeights, src->mKeys[i].mWeights, dest->mKeys[i].mNumValuesAndWeights * sizeof(double));
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy( aiCamera** _dest,const aiCamera* src) { void SceneCombiner::Copy( aiCamera** _dest,const aiCamera* src) {
if ( nullptr == _dest || nullptr == src ) { if ( nullptr == _dest || nullptr == src ) {

View File

@ -46,8 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h> #include <assimp/scene.h>
#include "ScenePrivate.h" #include "ScenePrivate.h"
static const unsigned int MajorVersion = 4; static const unsigned int MajorVersion = 5;
static const unsigned int MinorVersion = 1; static const unsigned int MinorVersion = 0;
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
// Legal information string - don't remove this. // Legal information string - don't remove this.

View File

@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXImporter.h" #include "FBXImporter.h"
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/MathFunctions.h>
#include <assimp/scene.h> #include <assimp/scene.h>
@ -78,7 +79,7 @@ namespace Assimp {
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit ) FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones )
: defaultMaterialIndex() : defaultMaterialIndex()
, lights() , lights()
, cameras() , cameras()
@ -90,8 +91,7 @@ namespace Assimp {
, mNodeNames() , mNodeNames()
, anim_fps() , anim_fps()
, out(out) , out(out)
, doc(doc) , doc(doc) {
, mCurrentUnit(FbxUnit::cm) {
// animations need to be converted first since this will // animations need to be converted first since this will
// populate the node_anim_chain_bits map, which is needed // populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated. // to determine which nodes need to be generated.
@ -119,7 +119,6 @@ namespace Assimp {
ConvertGlobalSettings(); ConvertGlobalSettings();
TransferDataToScene(); TransferDataToScene();
ConvertToUnitScale(unit);
// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE // if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
// to make sure the scene passes assimp's validation. FBX files // to make sure the scene passes assimp's validation. FBX files
@ -555,7 +554,7 @@ namespace Assimp {
return; return;
} }
const float angle_epsilon = 1e-6f; const float angle_epsilon = Math::getEpsilon<float>();
out = aiMatrix4x4(); out = aiMatrix4x4();
@ -696,7 +695,7 @@ namespace Assimp {
std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4()); std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4());
// generate transformation matrices for all the different transformation components // generate transformation matrices for all the different transformation components
const float zero_epsilon = 1e-6f; const float zero_epsilon = Math::getEpsilon<float>();
const aiVector3D all_ones(1.0f, 1.0f, 1.0f); const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok); const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
@ -2003,6 +2002,21 @@ namespace Assimp {
TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh); TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh); TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh); TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
// Maya PBR
TrySetTextureProperties(out_mat, textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
// Maya stingray
TrySetTextureProperties(out_mat, textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);
} }
void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh) void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh)
@ -2954,7 +2968,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
TransformationCompDefaultValue(comp) TransformationCompDefaultValue(comp)
); );
const float epsilon = 1e-6f; const float epsilon = Math::getEpsilon<float>();
return (dyn_val - static_val).SquareLength() < epsilon; return (dyn_val - static_val).SquareLength() < epsilon;
} }
@ -3537,46 +3551,6 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate()); out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
} }
void FBXConverter::ConvertToUnitScale( FbxUnit unit ) {
if (mCurrentUnit == unit) {
return;
}
ai_real scale = 1.0;
if (mCurrentUnit == FbxUnit::cm) {
if (unit == FbxUnit::m) {
scale = (ai_real)0.01;
} else if (unit == FbxUnit::km) {
scale = (ai_real)0.00001;
}
} else if (mCurrentUnit == FbxUnit::m) {
if (unit == FbxUnit::cm) {
scale = (ai_real)100.0;
} else if (unit == FbxUnit::km) {
scale = (ai_real)0.001;
}
} else if (mCurrentUnit == FbxUnit::km) {
if (unit == FbxUnit::cm) {
scale = (ai_real)100000.0;
} else if (unit == FbxUnit::m) {
scale = (ai_real)1000.0;
}
}
for (auto mesh : meshes) {
if (nullptr == mesh) {
continue;
}
if (mesh->HasPositions()) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D &pos = mesh->mVertices[i];
pos *= scale;
}
}
}
}
void FBXConverter::TransferDataToScene() void FBXConverter::TransferDataToScene()
{ {
ai_assert(!out->mMeshes); ai_assert(!out->mMeshes);
@ -3630,9 +3604,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit) void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
{ {
FBXConverter converter(out, doc, removeEmptyBones, unit); FBXConverter converter(out, doc, removeEmptyBones);
} }
} // !FBX } // !FBX

View File

@ -76,23 +76,13 @@ namespace Assimp {
namespace FBX { namespace FBX {
class Document; class Document;
enum class FbxUnit {
cm = 0,
m,
km,
NumUnits,
Undefined
};
/** /**
* Convert a FBX #Document to #aiScene * Convert a FBX #Document to #aiScene
* @param out Empty scene to be populated * @param out Empty scene to be populated
* @param doc Parsed FBX document * @param doc Parsed FBX document
* @param removeEmptyBones Will remove bones, which do not have any references to vertices. * @param removeEmptyBones Will remove bones, which do not have any references to vertices.
*/ */
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit); void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones);
/** Dummy class to encapsulate the conversion process */ /** Dummy class to encapsulate the conversion process */
class FBXConverter { class FBXConverter {
@ -123,7 +113,7 @@ public:
}; };
public: public:
FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit); FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones);
~FBXConverter(); ~FBXConverter();
private: private:
@ -430,10 +420,6 @@ private:
void ConvertGlobalSettings(); void ConvertGlobalSettings();
// ------------------------------------------------------------------------------------------------
// Will perform the conversion from a given unit to the requested unit.
void ConvertToUnitScale(FbxUnit unit);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// copy generated meshes, animations, lights, cameras and textures to the output scene // copy generated meshes, animations, lights, cameras and textures to the output scene
void TransferDataToScene(); void TransferDataToScene();
@ -470,7 +456,6 @@ private:
aiScene* const out; aiScene* const out;
const FBX::Document& doc; const FBX::Document& doc;
FbxUnit mCurrentUnit;
}; };
} }

View File

@ -59,11 +59,7 @@ namespace FBX {
FBXExportProperty::FBXExportProperty(bool v) FBXExportProperty::FBXExportProperty(bool v)
: type('C') : type('C')
, data(1) { , data(1, uint8_t(v)) {}
data = {
uint8_t(v)
};
}
FBXExportProperty::FBXExportProperty(int16_t v) FBXExportProperty::FBXExportProperty(int16_t v)
: type('Y') : type('Y')

View File

@ -67,6 +67,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector> #include <vector>
#include <array> #include <array>
#include <unordered_set> #include <unordered_set>
#include <numeric>
// RESOURCES: // RESOURCES:
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/ // https://code.blender.org/2013/08/fbx-binary-file-format-specification/
@ -1005,6 +1006,9 @@ void FBXExporter::WriteObjects ()
object_node.EndProperties(outstream, binary, indent); object_node.EndProperties(outstream, binary, indent);
object_node.BeginChildren(outstream, binary, indent); object_node.BeginChildren(outstream, binary, indent);
bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true);
std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later
// geometry (aiMesh) // geometry (aiMesh)
mesh_uids.clear(); mesh_uids.clear();
indent = 1; indent = 1;
@ -1031,6 +1035,7 @@ void FBXExporter::WriteObjects ()
std::vector<int32_t> vertex_indices; std::vector<int32_t> vertex_indices;
// map of vertex value to its index in the data vector // map of vertex value to its index in the data vector
std::map<aiVector3D,size_t> index_by_vertex_value; std::map<aiVector3D,size_t> index_by_vertex_value;
if(bJoinIdenticalVertices){
int32_t index = 0; int32_t index = 0;
for (size_t vi = 0; vi < m->mNumVertices; ++vi) { for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
aiVector3D vtx = m->mVertices[vi]; aiVector3D vtx = m->mVertices[vi];
@ -1046,6 +1051,19 @@ void FBXExporter::WriteObjects ()
vertex_indices.push_back(int32_t(elem->second)); vertex_indices.push_back(int32_t(elem->second));
} }
} }
}
else { // do not join vertex, respect the export flag
vertex_indices.resize(m->mNumVertices);
std::iota(vertex_indices.begin(), vertex_indices.end(), 0);
for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
aiVector3D vtx = m->mVertices[v];
flattened_vertices.push_back(vtx.x);
flattened_vertices.push_back(vtx.y);
flattened_vertices.push_back(vtx.z);
}
}
vVertexIndice.push_back(vertex_indices);
FBX::Node::WritePropertyNode( FBX::Node::WritePropertyNode(
"Vertices", flattened_vertices, outstream, binary, indent "Vertices", flattened_vertices, outstream, binary, indent
); );
@ -1116,6 +1134,51 @@ void FBXExporter::WriteObjects ()
normals.End(outstream, binary, indent, true); normals.End(outstream, binary, indent, true);
} }
// colors, if any
// TODO only one color channel currently
const int32_t colorChannelIndex = 0;
if (m->HasVertexColors(colorChannelIndex)) {
FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
vertexcolors.Begin(outstream, binary, indent);
vertexcolors.DumpProperties(outstream, binary, indent);
vertexcolors.EndProperties(outstream, binary, indent);
vertexcolors.BeginChildren(outstream, binary, indent);
indent = 3;
FBX::Node::WritePropertyNode(
"Version", int32_t(101), outstream, binary, indent
);
char layerName[8];
sprintf(layerName, "COLOR_%d", colorChannelIndex);
FBX::Node::WritePropertyNode(
"Name", (const char*)layerName, outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"MappingInformationType", "ByPolygonVertex",
outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"ReferenceInformationType", "Direct",
outstream, binary, indent
);
std::vector<double> color_data;
color_data.reserve(4 * polygon_data.size());
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]];
color_data.push_back(c.r);
color_data.push_back(c.g);
color_data.push_back(c.b);
color_data.push_back(c.a);
}
}
FBX::Node::WritePropertyNode(
"Colors", color_data, outstream, binary, indent
);
indent = 2;
vertexcolors.End(outstream, binary, indent, true);
}
// uvs, if any // uvs, if any
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) { for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
if (m->mNumUVComponents[uvi] > 2) { if (m->mNumUVComponents[uvi] > 2) {
@ -1209,6 +1272,11 @@ void FBXExporter::WriteObjects ()
le.AddChild("Type", "LayerElementNormal"); le.AddChild("Type", "LayerElementNormal");
le.AddChild("TypedIndex", int32_t(0)); le.AddChild("TypedIndex", int32_t(0));
layer.AddChild(le); layer.AddChild(le);
// TODO only 1 color channel currently
le = FBX::Node("LayerElement");
le.AddChild("Type", "LayerElementColor");
le.AddChild("TypedIndex", int32_t(0));
layer.AddChild(le);
le = FBX::Node("LayerElement"); le = FBX::Node("LayerElement");
le.AddChild("Type", "LayerElementMaterial"); le.AddChild("Type", "LayerElementMaterial");
le.AddChild("TypedIndex", int32_t(0)); le.AddChild("TypedIndex", int32_t(0));
@ -1221,7 +1289,7 @@ void FBXExporter::WriteObjects ()
for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr) for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr)
{ {
FBX::Node layerExtra("Layer", int32_t(1)); FBX::Node layerExtra("Layer", int32_t(lr));
layerExtra.AddChild("Version", int32_t(100)); layerExtra.AddChild("Version", int32_t(100));
FBX::Node leExtra("LayerElement"); FBX::Node leExtra("LayerElement");
leExtra.AddChild("Type", "LayerElementUV"); leExtra.AddChild("Type", "LayerElementUV");
@ -1748,28 +1816,8 @@ void FBXExporter::WriteObjects ()
// connect it // connect it
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]); connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
// we will be indexing by vertex... //computed before
// but there might be a different number of "vertices" std::vector<int32_t>& vertex_indices = vVertexIndice[mi];
// between assimp and our output FBX.
// this code is cut-and-pasted from the geometry section above...
// ideally this should not be so.
// ---
// index of original vertex in vertex data vector
std::vector<int32_t> vertex_indices;
// map of vertex value to its index in the data vector
std::map<aiVector3D,size_t> index_by_vertex_value;
int32_t index = 0;
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
aiVector3D vtx = m->mVertices[vi];
auto elem = index_by_vertex_value.find(vtx);
if (elem == index_by_vertex_value.end()) {
vertex_indices.push_back(index);
index_by_vertex_value[vtx] = index;
++index;
} else {
vertex_indices.push_back(int32_t(elem->second));
}
}
// TODO, FIXME: this won't work if anything is not in the bind pose. // TODO, FIXME: this won't work if anything is not in the bind pose.
// for now if such a situation is detected, we throw an exception. // for now if such a situation is detected, we throw an exception.
@ -2435,7 +2483,7 @@ void FBXExporter::WriteModelNodes(
void FBXExporter::WriteAnimationCurveNode( void FBXExporter::WriteAnimationCurveNode(
StreamWriterLE& outstream, StreamWriterLE& outstream,
int64_t uid, int64_t uid,
std::string name, // "T", "R", or "S" const std::string& name, // "T", "R", or "S"
aiVector3D default_value, aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc std::string property_name, // "Lcl Translation" etc
int64_t layer_uid, int64_t layer_uid,

View File

@ -156,7 +156,7 @@ namespace Assimp
void WriteAnimationCurveNode( void WriteAnimationCurveNode(
StreamWriterLE& outstream, StreamWriterLE& outstream,
int64_t uid, int64_t uid,
std::string name, // "T", "R", or "S" const std::string& name, // "T", "R", or "S"
aiVector3D default_value, aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc std::string property_name, // "Lcl Translation" etc
int64_t animation_layer_uid, int64_t animation_layer_uid,

View File

@ -185,16 +185,15 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// take the raw parse-tree and convert it to a FBX DOM // take the raw parse-tree and convert it to a FBX DOM
Document doc(parser,settings); Document doc(parser,settings);
FbxUnit unit(FbxUnit::cm);
if (settings.convertToMeters) {
unit = FbxUnit::m;
}
// convert the FBX DOM to aiScene // convert the FBX DOM to aiScene
ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones, unit); ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
// units is relative to CM :) we need it in meters for assimp // size relative to cm
SetFileScale( doc.GlobalSettings().UnitScaleFactor() * 0.01f); float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
// Set FBX file scale is relative to CM must be converted to M for
// assimp universal format (M)
SetFileScale( size_relative_to_cm * 0.01f);
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>()); std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
} }

View File

@ -311,10 +311,9 @@ class TrimmedCurve : public BoundedCurve {
public: public:
// -------------------------------------------------- // --------------------------------------------------
TrimmedCurve(const Schema_2x3::IfcTrimmedCurve& entity, ConversionData& conv) TrimmedCurve(const Schema_2x3::IfcTrimmedCurve& entity, ConversionData& conv)
: BoundedCurve(entity,conv) : BoundedCurve(entity,conv),
base(std::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv)))
{ {
base = std::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv));
typedef std::shared_ptr<const STEP::EXPRESS::DataType> Entry; typedef std::shared_ptr<const STEP::EXPRESS::DataType> Entry;
// for some reason, trimmed curves can either specify a parametric value // for some reason, trimmed curves can either specify a parametric value
@ -500,7 +499,7 @@ bool Curve::InRange(IfcFloat u) const {
if (IsClosed()) { if (IsClosed()) {
return true; return true;
} }
const IfcFloat epsilon = 1e-5; const IfcFloat epsilon = Math::getEpsilon<float>();
return u - range.first > -epsilon && range.second - u > -epsilon; return u - range.first > -epsilon && range.second - u > -epsilon;
} }
#endif #endif

View File

@ -128,7 +128,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
outer_polygon_it = begin + master_bounds; outer_polygon_it = begin + master_bounds;
} }
else { else {
for(iit = begin; iit != end; iit++) { for(iit = begin; iit != end; ++iit) {
// find the polygon with the largest area and take it as the outer bound. // find the polygon with the largest area and take it as the outer bound.
IfcVector3& n = normals[std::distance(begin,iit)]; IfcVector3& n = normals[std::distance(begin,iit)];
const IfcFloat area = n.SquareLength(); const IfcFloat area = n.SquareLength();

View File

@ -593,7 +593,7 @@ typedef std::vector<std::pair<
bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb) bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb)
{ {
// TODO: I'm pretty sure there is a much more compact way to check this // TODO: I'm pretty sure there is a much more compact way to check this
const IfcFloat epsilon = 1e-5f; const IfcFloat epsilon = Math::getEpsilon<float>();
return (std::fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) || return (std::fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
(std::fabs(bb.first.x - ibb.second.x) < epsilon && ibb.first.y <= bb.second.y && ibb.second.y >= bb.first.y) || (std::fabs(bb.first.x - ibb.second.x) < epsilon && ibb.first.y <= bb.second.y && ibb.second.y >= bb.first.y) ||
(std::fabs(bb.second.y - ibb.first.y) < epsilon && bb.first.x <= ibb.second.x && bb.second.x >= ibb.first.x) || (std::fabs(bb.second.y - ibb.first.y) < epsilon && bb.first.x <= ibb.second.x && bb.second.x >= ibb.first.x) ||
@ -681,7 +681,7 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours) void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours)
{ {
const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(1e-8); const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
const BoundingBox& bb = (*current).bb; const BoundingBox& bb = (*current).bb;
// What is to be done here is to populate the skip lists for the contour // What is to be done here is to populate the skip lists for the contour
@ -758,7 +758,7 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta) AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta)
{ {
const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(1e-5); const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
return std::fabs(vdelta.x * vdelta.y) < dot_point_epsilon; return std::fabs(vdelta.x * vdelta.y) < dot_point_epsilon;
} }

View File

@ -57,7 +57,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/material.h> #include <assimp/material.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/Macros.h>
using namespace Assimp; using namespace Assimp;
using namespace irr; using namespace irr;

View File

@ -344,7 +344,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
if (pcSkins->name[0]) if (pcSkins->name[0])
{ {
aiString szString; aiString szString;
const size_t iLen = ::strlen(pcSkins->name); const ai_uint32 iLen = (ai_uint32) ::strlen(pcSkins->name);
::memcpy(szString.data,pcSkins->name,iLen); ::memcpy(szString.data,pcSkins->name,iLen);
szString.data[iLen] = '\0'; szString.data[iLen] = '\0';
szString.length = iLen; szString.length = iLen;

View File

@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MD5Loader.h" #include "MD5Loader.h"
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/MathFunctions.h>
#include <assimp/SkeletonMeshBuilder.h> #include <assimp/SkeletonMeshBuilder.h>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
@ -64,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
// Minimum weight value. Weights inside [-n ... n] are ignored // Minimum weight value. Weights inside [-n ... n] are ignored
#define AI_MD5_WEIGHT_EPSILON 1e-5f #define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>()
static const aiImporterDesc desc = { static const aiImporterDesc desc = {

View File

@ -235,7 +235,7 @@ bool MD5Parser::ParseSection(Section& out)
const char* szStart = ++sz; \ const char* szStart = ++sz; \
while('\"'!=*sz)++sz; \ while('\"'!=*sz)++sz; \
const char* szEnd = (sz++); \ const char* szEnd = (sz++); \
out.length = (size_t)(szEnd - szStart); \ out.length = (ai_uint32) (szEnd - szStart); \
::memcpy(out.data,szStart,out.length); \ ::memcpy(out.data,szStart,out.length); \
out.data[out.length] = '\0'; out.data[out.length] = '\0';
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team Copyright (c) 2006-2019, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -54,7 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MDL/MDLDefaultColorMap.h" #include "MDL/MDLDefaultColorMap.h"
#include "MD2/MD2FileData.h" #include "MD2/MD2FileData.h"
#include <assimp/Macros.h>
#include <assimp/qnan.h> #include <assimp/qnan.h>
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
@ -94,23 +91,24 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
MDLImporter::MDLImporter() MDLImporter::MDLImporter()
: configFrameID(), : configFrameID()
mBuffer(), , mBuffer()
iGSFileVersion(), , iGSFileVersion()
pIOHandler(), , pIOHandler()
pScene(), , pScene()
iFileSize() , iFileSize() {
{} // empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
MDLImporter::~MDLImporter() MDLImporter::~MDLImporter() {
{} // empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
{
const std::string extension = GetExtension(pFile); const std::string extension = GetExtension(pFile);
// if check for extension is not enough, check for the magic tokens // if check for extension is not enough, check for the magic tokens
@ -404,23 +402,15 @@ void MDLImporter::InternReadFile_Quake1() {
// now get a pointer to the first frame in the file // now get a pointer to the first frame in the file
BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent; BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent;
BE_NCONST MDL::SimpleFrame* pcFirstFrame; MDL::SimpleFrame* pcFirstFrame;
if (0 == pcFrames->type) { if (0 == pcFrames->type) {
// get address of single frame // get address of single frame
pcFirstFrame = &pcFrames->frame; pcFirstFrame =( MDL::SimpleFrame*) &pcFrames->frame;
} else { } else {
// get the first frame in the group // get the first frame in the group
BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*) pcFrames;
#if 1 pcFirstFrame = &(pcFrames2->frames[0]);
// FIXME: the cast is wrong and cause a warning on clang 5.0
// disable this code for now, fix it later
ai_assert(false && "Bad pointer cast");
pcFirstFrame = nullptr; // Workaround: msvc++ C4703 error
#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)); BE_NCONST MDL::Vertex* pcVertices = (BE_NCONST MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts)); VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts));

View File

@ -89,16 +89,12 @@ public:
MDLImporter(); MDLImporter();
~MDLImporter(); ~MDLImporter();
public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */ * See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ReadFile(). /** Called prior to ReadFile().
* The function is a request to the importer to update its configuration * The function is a request to the importer to update its configuration
@ -107,8 +103,6 @@ public:
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
@ -122,8 +116,6 @@ protected:
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Import a quake 1 MDL file (IDPO) /** Import a quake 1 MDL file (IDPO)
*/ */
@ -154,7 +146,6 @@ protected:
void SizeCheck(const void* szPos); void SizeCheck(const void* szPos);
void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine); void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Validate the header data structure of a game studio MDL7 file /** Validate the header data structure of a game studio MDL7 file
* \param pcHeader Input header to be validated * \param pcHeader Input header to be validated
@ -167,7 +158,6 @@ protected:
*/ */
void ValidateHeader_Quake1(const MDL::Header* pcHeader); void ValidateHeader_Quake1(const MDL::Header* pcHeader);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Try to load a palette from the current directory (colormap.lmp) /** Try to load a palette from the current directory (colormap.lmp)
* If it is not found the default palette of Quake1 is returned * If it is not found the default palette of Quake1 is returned
@ -179,9 +169,8 @@ protected:
*/ */
void FreePalette(const unsigned char* pszColorMap); void FreePalette(const unsigned char* pszColorMap);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Load a paletized texture from the file and convert it to 32bpp /** Load a palletized texture from the file and convert it to 32bpp
*/ */
void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData); void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData);
@ -195,7 +184,6 @@ protected:
unsigned int iType, unsigned int iType,
unsigned int* piSkip); unsigned int* piSkip);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Used to load textures from MDL5 /** Used to load textures from MDL5
* \param szData Input data * \param szData Input data
@ -206,7 +194,6 @@ protected:
unsigned int iType, unsigned int iType,
unsigned int* piSkip); unsigned int* piSkip);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Checks whether a texture can be replaced with a single color /** Checks whether a texture can be replaced with a single color
* This is useful for all file formats before MDL7 (all those * This is useful for all file formats before MDL7 (all those
@ -218,14 +205,12 @@ protected:
*/ */
aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture); aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Converts the absolute texture coordinates in MDL5 files to /** Converts the absolute texture coordinates in MDL5 files to
* relative in a range between 0 and 1 * relative in a range between 0 and 1
*/ */
void CalculateUVCoordinates_MDL5(); void CalculateUVCoordinates_MDL5();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Read an UV coordinate from the file. If the file format is not /** Read an UV coordinate from the file. If the file format is not
* MDL5, the function calculates relative texture coordinates * MDL5, the function calculates relative texture coordinates
@ -245,7 +230,6 @@ protected:
*/ */
void SetupMaterialProperties_3DGS_MDL5_Quake1( ); void SetupMaterialProperties_3DGS_MDL5_Quake1( );
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a skin lump in a MDL7/HMP7 file with all of its features /** Parse a skin lump in a MDL7/HMP7 file with all of its features
* variant 1: Current cursor position is the beginning of the skin header * variant 1: Current cursor position is the beginning of the skin header

View File

@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/types.h> #include <assimp/types.h>
#include <assimp/material.h> #include <assimp/material.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/Macros.h>
using namespace Assimp; using namespace Assimp;
@ -545,23 +544,7 @@ aiReturn aiMaterial::AddProperty (const aiString* pInput,
unsigned int type, unsigned int type,
unsigned int index) unsigned int index)
{ {
// We don't want to add the whole buffer .. write a 32 bit length ai_assert(sizeof(ai_uint32)==4);
// prefix followed by the zero-terminated UTF8 string.
// (HACK) I don't want to break the ABI now, but we definitely
// ought to change aiString::mLength to uint32_t one day.
if (sizeof(size_t) == 8) {
aiString copy = *pInput;
uint32_t* s = reinterpret_cast<uint32_t*>(&copy.length);
s[1] = static_cast<uint32_t>(pInput->length);
return AddBinaryProperty(s+1,
static_cast<unsigned int>(pInput->length+1+4),
pKey,
type,
index,
aiPTI_String);
}
ai_assert(sizeof(size_t)==4);
return AddBinaryProperty(pInput, return AddBinaryProperty(pInput,
static_cast<unsigned int>(pInput->length+1+4), static_cast<unsigned int>(pInput->length+1+4),
pKey, pKey,

View File

@ -79,10 +79,7 @@ using namespace std;
ObjFileImporter::ObjFileImporter() ObjFileImporter::ObjFileImporter()
: m_Buffer() : m_Buffer()
, m_pRootObject( nullptr ) , m_pRootObject( nullptr )
, m_strAbsPath( "" ) { , m_strAbsPath( std::string(1, DefaultIOSystem().getOsSeparator()) ) {}
DefaultIOSystem io;
m_strAbsPath = io.getOsSeparator();
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor. // Destructor.

View File

@ -244,8 +244,8 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
size_t index = 0; size_t index = 0;
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
if ( *m_DataIt == '\\' ) { if ( *m_DataIt == '\\' ) {
m_DataIt++; ++m_DataIt;
m_DataIt++; ++m_DataIt;
m_DataIt = getNextWord<DataArrayIt>( m_DataIt, m_DataItEnd ); m_DataIt = getNextWord<DataArrayIt>( m_DataIt, m_DataItEnd );
} }
while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) { while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {

View File

@ -49,7 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers // internal headers
#include "PlyLoader.h" #include "PlyLoader.h"
#include <assimp/IOStreamBuffer.h> #include <assimp/IOStreamBuffer.h>
#include <assimp/Macros.h>
#include <memory> #include <memory>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>

View File

@ -354,12 +354,12 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
} }
else if (axis * base_axis_z >= angle_epsilon) { else if (axis * base_axis_z >= angle_epsilon) {
FindMeshCenter(mesh, center, min, max); FindMeshCenter(mesh, center, min, max);
diffu = max.y - min.y; diffu = max.x - min.x;
diffv = max.z - min.z; diffv = max.y - min.y;
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D& pos = mesh->mVertices[pnt]; const aiVector3D& pos = mesh->mVertices[pnt];
out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.0); out[pnt].Set((pos.x - min.x) / diffu,(pos.y - min.y) / diffv,0.0);
} }
} }
// slower code path in case the mapping axis is not one of the coordinate system axes // slower code path in case the mapping axis is not one of the coordinate system axes

View File

@ -52,7 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FindInvalidDataProcess.h" #include "FindInvalidDataProcess.h"
#include "ProcessHelper.h" #include "ProcessHelper.h"
#include <assimp/Macros.h>
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include <assimp/qnan.h> #include <assimp/qnan.h>

View File

@ -224,3 +224,32 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
} }
return (pcMesh->mNumVertices != iOldNumVertices); return (pcMesh->mNumVertices != iOldNumVertices);
} }
// ------------------------------------------------------------------------------------------------
bool IsMeshInVerboseFormat(const aiMesh* mesh) {
// avoid slow vector<bool> specialization
std::vector<unsigned int> seen(mesh->mNumVertices,0);
for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
const aiFace& f = mesh->mFaces[i];
for(unsigned int j = 0; j < f.mNumIndices; ++j) {
if(++seen[f.mIndices[j]] == 2) {
// found a duplicate index
return false;
}
}
}
return true;
}
// ------------------------------------------------------------------------------------------------
bool MakeVerboseFormatProcess::IsVerboseFormat(const aiScene* pScene) {
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
if(!IsMeshInVerboseFormat(pScene->mMeshes[i])) {
return false;
}
}
return true;
}

View File

@ -94,6 +94,13 @@ public:
* @param pScene The imported data to work at. */ * @param pScene The imported data to work at. */
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
public:
// -------------------------------------------------------------------
/** Checks whether the scene is already in verbose format.
* @param pScene The data to check.
* @return true if the scene is already in verbose format. */
static bool IsVerboseFormat(const aiScene* pScene);
private: private:

View File

@ -538,13 +538,17 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
{ {
Validate(&pAnimation->mName); Validate(&pAnimation->mName);
// validate all materials // validate all animations
if (pAnimation->mNumChannels) if (pAnimation->mNumChannels || pAnimation->mNumMorphMeshChannels)
{ {
if (!pAnimation->mChannels) { if (!pAnimation->mChannels && pAnimation->mNumChannels) {
ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)", ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)",
pAnimation->mNumChannels); pAnimation->mNumChannels);
} }
if (!pAnimation->mMorphMeshChannels && pAnimation->mNumMorphMeshChannels) {
ReportError("aiAnimation::mMorphMeshChannels is NULL (aiAnimation::mNumMorphMeshChannels is %i)",
pAnimation->mNumMorphMeshChannels);
}
for (unsigned int i = 0; i < pAnimation->mNumChannels;++i) for (unsigned int i = 0; i < pAnimation->mNumChannels;++i)
{ {
if (!pAnimation->mChannels[i]) if (!pAnimation->mChannels[i])
@ -554,6 +558,15 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
} }
Validate(pAnimation, pAnimation->mChannels[i]); Validate(pAnimation, pAnimation->mChannels[i]);
} }
for (unsigned int i = 0; i < pAnimation->mNumMorphMeshChannels;++i)
{
if (!pAnimation->mMorphMeshChannels[i])
{
ReportError("aiAnimation::mMorphMeshChannels[%i] is NULL (aiAnimation::mNumMorphMeshChannels is %i)",
i, pAnimation->mNumMorphMeshChannels);
}
Validate(pAnimation, pAnimation->mMorphMeshChannels[i]);
}
} }
else { else {
ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there."); ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
@ -903,6 +916,48 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
} }
} }
void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
const aiMeshMorphAnim* pMeshMorphAnim)
{
Validate(&pMeshMorphAnim->mName);
if (!pMeshMorphAnim->mNumKeys) {
ReportError("Empty mesh morph animation channel");
}
// otherwise check whether one of the keys exceeds the total duration of the animation
if (pMeshMorphAnim->mNumKeys)
{
if (!pMeshMorphAnim->mKeys)
{
ReportError("aiMeshMorphAnim::mKeys is NULL (aiMeshMorphAnim::mNumKeys is %i)",
pMeshMorphAnim->mNumKeys);
}
double dLast = -10e10;
for (unsigned int i = 0; i < pMeshMorphAnim->mNumKeys;++i)
{
// ScenePreprocessor will compute the duration if still the default value
// (Aramis) Add small epsilon, comparison tended to fail if max_time == duration,
// seems to be due the compilers register usage/width.
if (pAnimation->mDuration > 0. && pMeshMorphAnim->mKeys[i].mTime > pAnimation->mDuration+0.001)
{
ReportError("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is larger "
"than aiAnimation::mDuration (which is %.5f)",i,
(float)pMeshMorphAnim->mKeys[i].mTime,
(float)pAnimation->mDuration);
}
if (i && pMeshMorphAnim->mKeys[i].mTime <= dLast)
{
ReportWarning("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is smaller "
"than aiMeshMorphAnim::mKeys[%i] (which is %.5f)",i,
(float)pMeshMorphAnim->mKeys[i].mTime,
i-1, (float)dLast);
}
dLast = pMeshMorphAnim->mKeys[i].mTime;
}
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiNode* pNode) void ValidateDSProcess::Validate( const aiNode* pNode)
{ {
@ -958,7 +1013,7 @@ void ValidateDSProcess::Validate( const aiString* pString)
{ {
if (pString->length > MAXLEN) if (pString->length > MAXLEN)
{ {
ReportError("aiString::length is too large (%lu, maximum is %lu)", ReportError("aiString::length is too large (%u, maximum is %lu)",
pString->length,MAXLEN); pString->length,MAXLEN);
} }
const char* sz = pString->data; const char* sz = pString->data;

View File

@ -55,6 +55,7 @@ struct aiBone;
struct aiMesh; struct aiMesh;
struct aiAnimation; struct aiAnimation;
struct aiNodeAnim; struct aiNodeAnim;
struct aiMeshMorphAnim;
struct aiTexture; struct aiTexture;
struct aiMaterial; struct aiMaterial;
struct aiNode; struct aiNode;
@ -150,6 +151,13 @@ protected:
void Validate( const aiAnimation* pAnimation, void Validate( const aiAnimation* pAnimation,
const aiNodeAnim* pBoneAnim); const aiNodeAnim* pBoneAnim);
/** Validates a mesh morph animation channel.
* @param pAnimation Input animation.
* @param pMeshMorphAnim Mesh morph animation channel.
* */
void Validate( const aiAnimation* pAnimation,
const aiMeshMorphAnim* pMeshMorphAnim);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Validates a node and all of its subnodes /** Validates a node and all of its subnodes
* @param Node Input node*/ * @param Node Input node*/

View File

@ -596,11 +596,11 @@ void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
// do not crah when no face definitions are there // do not crah when no face definitions are there
if (numFaces > 0) { if (numFaces > 0) {
// normal face creation // normal face creation
pMesh->mNormFaces.resize( pMesh->mNormFaces.size() + numFaces ); pMesh->mNormFaces.resize( numFaces );
for( unsigned int a = 0; a < numFaces; ++a ) { for( unsigned int a = 0; a < numFaces; ++a ) {
unsigned int numIndices = ReadInt(); unsigned int numIndices = ReadInt();
pMesh->mNormFaces.push_back( Face() ); pMesh->mNormFaces[a] = Face();
Face& face = pMesh->mNormFaces.back(); Face& face = pMesh->mNormFaces[a];
for( unsigned int b = 0; b < numIndices; ++b ) { for( unsigned int b = 0; b < numIndices; ++b ) {
face.mIndices.push_back( ReadInt()); face.mIndices.push_back( ReadInt());
} }

View File

@ -68,7 +68,7 @@ aiMatrix4x4 out_matr;
} }
// multiplicate all matrices in reverse order // multiplicate all matrices in reverse order
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit); for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); ++rit) out_matr = out_matr * (*rit);
return out_matr; return out_matr;
} }

View File

@ -136,8 +136,8 @@ X3DImporter::~X3DImporter() {
void X3DImporter::Clear() { void X3DImporter::Clear() {
NodeElement_Cur = nullptr; NodeElement_Cur = nullptr;
// Delete all elements // Delete all elements
if(NodeElement_List.size()) { if(!NodeElement_List.empty()) {
for ( std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++ ) { for ( std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); ++it ) {
delete *it; delete *it;
} }
NodeElement_List.clear(); NodeElement_List.clear();
@ -151,7 +151,7 @@ void X3DImporter::Clear() {
bool X3DImporter::FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement) bool X3DImporter::FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
{ {
for(std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++) for(std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); ++it)
{ {
if(((*it)->Type == pType) && ((*it)->ID == pID)) if(((*it)->Type == pType) && ((*it)->ID == pID))
{ {
@ -182,7 +182,7 @@ bool X3DImporter::FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode,
}// if((pStartNode->Type() == pType) && (pStartNode->ID() == pID)) }// if((pStartNode->Type() == pType) && (pStartNode->ID() == pID))
// Check childs of pStartNode. // Check childs of pStartNode.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ++ch_it)
{ {
found = FindNodeElement_FromNode(*ch_it, pID, pType, pElement); found = FindNodeElement_FromNode(*ch_it, pID, pType, pElement);
if ( found ) if ( found )
@ -614,10 +614,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::ve
XML_ReadNode_GetAttrVal_AsListCol3f(pAttrIdx, tlist);// read as list XML_ReadNode_GetAttrVal_AsListCol3f(pAttrIdx, tlist);// read as list
// and copy to array // and copy to array
if(tlist.size() > 0) if(!tlist.empty())
{ {
pValue.reserve(tlist.size()); pValue.reserve(tlist.size());
for(std::list<aiColor3D>::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it); for(std::list<aiColor3D>::iterator it = tlist.begin(); it != tlist.end(); ++it) pValue.push_back(*it);
} }
} }
@ -647,10 +647,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::ve
XML_ReadNode_GetAttrVal_AsListCol4f(pAttrIdx, tlist);// read as list XML_ReadNode_GetAttrVal_AsListCol4f(pAttrIdx, tlist);// read as list
// and copy to array // and copy to array
if(tlist.size() > 0) if(!tlist.empty())
{ {
pValue.reserve(tlist.size()); pValue.reserve(tlist.size());
for ( std::list<aiColor4D>::iterator it = tlist.begin(); it != tlist.end(); it++ ) for ( std::list<aiColor4D>::iterator it = tlist.begin(); it != tlist.end(); ++it )
{ {
pValue.push_back( *it ); pValue.push_back( *it );
} }
@ -684,10 +684,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::ve
XML_ReadNode_GetAttrVal_AsListVec2f(pAttrIdx, tlist);// read as list XML_ReadNode_GetAttrVal_AsListVec2f(pAttrIdx, tlist);// read as list
// and copy to array // and copy to array
if(tlist.size() > 0) if(!tlist.empty())
{ {
pValue.reserve(tlist.size()); pValue.reserve(tlist.size());
for ( std::list<aiVector2D>::iterator it = tlist.begin(); it != tlist.end(); it++ ) for ( std::list<aiVector2D>::iterator it = tlist.begin(); it != tlist.end(); ++it )
{ {
pValue.push_back( *it ); pValue.push_back( *it );
} }
@ -722,10 +722,10 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::ve
XML_ReadNode_GetAttrVal_AsListVec3f(pAttrIdx, tlist);// read as list XML_ReadNode_GetAttrVal_AsListVec3f(pAttrIdx, tlist);// read as list
// and copy to array // and copy to array
if(tlist.size() > 0) if(!tlist.empty())
{ {
pValue.reserve(tlist.size()); pValue.reserve(tlist.size());
for ( std::list<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); it++ ) for ( std::list<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); ++it )
{ {
pValue.push_back( *it ); pValue.push_back( *it );
} }
@ -823,7 +823,7 @@ void X3DImporter::GeometryHelper_Extend_PointToLine(const std::list<aiVector3D>&
std::list<aiVector3D>::const_iterator pit = pPoint.begin(); std::list<aiVector3D>::const_iterator pit = pPoint.begin();
std::list<aiVector3D>::const_iterator pit_last = pPoint.end(); std::list<aiVector3D>::const_iterator pit_last = pPoint.end();
pit_last--; --pit_last;
if ( pPoint.size() < 2 ) if ( pPoint.size() < 2 )
{ {
@ -837,7 +837,7 @@ void X3DImporter::GeometryHelper_Extend_PointToLine(const std::list<aiVector3D>&
{ {
pLine.push_back(*pit);// second point of previous line pLine.push_back(*pit);// second point of previous line
pLine.push_back(*pit);// first point of next line pLine.push_back(*pit);// first point of next line
pit++; ++pit;
} }
// add last point of last line // add last point of last line
pLine.push_back(*pit); pLine.push_back(*pit);
@ -855,7 +855,7 @@ void X3DImporter::GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list<int
{ {
std::list<int32_t>::const_iterator plit_next; std::list<int32_t>::const_iterator plit_next;
plit_next = plit, plit_next++; plit_next = plit, ++plit_next;
pLineCoordIdx.push_back(*plit);// second point of previous line. pLineCoordIdx.push_back(*plit);// second point of previous line.
pLineCoordIdx.push_back(-1);// delimiter pLineCoordIdx.push_back(-1);// delimiter
if((*plit_next == (-1)) || (plit_next == pPolylineCoordIdx.end())) break;// current polyline is finished if((*plit_next == (-1)) || (plit_next == pPolylineCoordIdx.end())) break;// current polyline is finished
@ -910,7 +910,7 @@ void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::vector<int32_t>
pFaces.reserve(f_data.size() / 3); pFaces.reserve(f_data.size() / 3);
inds.reserve(4); inds.reserve(4);
//PrintVectorSet("build. ci", pCoordIdx); //PrintVectorSet("build. ci", pCoordIdx);
for(std::vector<int32_t>::iterator it = f_data.begin(); it != f_data.end(); it++) for(std::vector<int32_t>::iterator it = f_data.begin(); it != f_data.end(); ++it)
{ {
// when face is got count how many indices in it. // when face is got count how many indices in it.
if(*it == (-1)) if(*it == (-1))
@ -957,7 +957,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor3D
std::list<aiColor4D> tcol; std::list<aiColor4D> tcol;
// create RGBA array from RGB. // create RGBA array from RGB.
for(std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); it++) tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1)); for(std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); ++it) tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1));
// call existing function for adding RGBA colors // call existing function for adding RGBA colors
MeshGeometry_AddColor(pMesh, tcol, pColorPerVertex); MeshGeometry_AddColor(pMesh, tcol, pColorPerVertex);
@ -997,7 +997,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D
pMesh.mColors[ 0 ][ pMesh.mFaces[ fi ].mIndices[ vi ] ] = *col_it; pMesh.mColors[ 0 ][ pMesh.mFaces[ fi ].mIndices[ vi ] ] = *col_it;
} }
col_it++; ++col_it;
} }
}// if(pColorPerVertex) else }// if(pColorPerVertex) else
} }
@ -1008,7 +1008,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
std::list<aiColor4D> tcol; std::list<aiColor4D> tcol;
// create RGBA array from RGB. // create RGBA array from RGB.
for ( std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); it++ ) for ( std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); ++it )
{ {
tcol.push_back( aiColor4D( ( *it ).r, ( *it ).g, ( *it ).b, 1 ) ); tcol.push_back( aiColor4D( ( *it ).r, ( *it ).g, ( *it ).b, 1 ) );
} }
@ -1031,7 +1031,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
// copy list to array because we are need indexed access to colors. // copy list to array because we are need indexed access to colors.
col_arr_copy.reserve(pColors.size()); col_arr_copy.reserve(pColors.size());
for ( std::list<aiColor4D>::const_iterator it = pColors.begin(); it != pColors.end(); it++ ) for ( std::list<aiColor4D>::const_iterator it = pColors.begin(); it != pColors.end(); ++it )
{ {
col_arr_copy.push_back( *it ); col_arr_copy.push_back( *it );
} }
@ -1048,7 +1048,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
} }
// create list with colors for every vertex. // create list with colors for every vertex.
col_tgt_arr.resize(pMesh.mNumVertices); col_tgt_arr.resize(pMesh.mNumVertices);
for(std::vector<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++) for(std::vector<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); ++colidx_it, ++coordidx_it)
{ {
if ( *colidx_it == ( -1 ) ) if ( *colidx_it == ( -1 ) )
{ {
@ -1121,7 +1121,7 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t
}// if(pColorPerVertex) else }// if(pColorPerVertex) else
// copy array to list for calling function that add colors. // copy array to list for calling function that add colors.
for(std::vector<aiColor4D>::const_iterator it = col_tgt_arr.begin(); it != col_tgt_arr.end(); it++) col_tgt_list.push_back(*it); for(std::vector<aiColor4D>::const_iterator it = col_tgt_arr.begin(); it != col_tgt_arr.end(); ++it) col_tgt_list.push_back(*it);
// add prepared colors list to mesh. // add prepared colors list to mesh.
MeshGeometry_AddColor(pMesh, col_tgt_list, pColorPerVertex); MeshGeometry_AddColor(pMesh, col_tgt_list, pColorPerVertex);
} }
@ -1134,7 +1134,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_
// copy list to array because we are need indexed access to normals. // copy list to array because we are need indexed access to normals.
norm_arr_copy.reserve(pNormals.size()); norm_arr_copy.reserve(pNormals.size());
for ( std::list<aiVector3D>::const_iterator it = pNormals.begin(); it != pNormals.end(); it++ ) for ( std::list<aiVector3D>::const_iterator it = pNormals.begin(); it != pNormals.end(); ++it )
{ {
norm_arr_copy.push_back( *it ); norm_arr_copy.push_back( *it );
} }
@ -1147,7 +1147,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_
if(pNormalIdx.size() != pCoordIdx.size()) throw DeadlyImportError("Normals and Coords inidces count must be equal."); if(pNormalIdx.size() != pCoordIdx.size()) throw DeadlyImportError("Normals and Coords inidces count must be equal.");
tind.reserve(pNormalIdx.size()); tind.reserve(pNormalIdx.size());
for(std::vector<int32_t>::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); it++) for(std::vector<int32_t>::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); ++it)
{ {
if(*it != (-1)) tind.push_back(*it); if(*it != (-1)) tind.push_back(*it);
} }
@ -1227,7 +1227,7 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<aiVector
// apply color to all vertices of face // apply color to all vertices of face
for(size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) pMesh.mNormals[pMesh.mFaces[fi].mIndices[vi]] = *norm_it; for(size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) pMesh.mNormals[pMesh.mFaces[fi].mIndices[vi]] = *norm_it;
norm_it++; ++norm_it;
} }
}// if(pNormalPerVertex) else }// if(pNormalPerVertex) else
} }
@ -1241,7 +1241,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::vector<int3
// copy list to array because we are need indexed access to normals. // copy list to array because we are need indexed access to normals.
texcoord_arr_copy.reserve(pTexCoords.size()); texcoord_arr_copy.reserve(pTexCoords.size());
for(std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); it++) for(std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); ++it)
{ {
texcoord_arr_copy.push_back(aiVector3D((*it).x, (*it).y, 0)); texcoord_arr_copy.push_back(aiVector3D((*it).x, (*it).y, 0));
} }
@ -1291,7 +1291,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<aiVect
// copy list to array because we are need convert aiVector2D to aiVector3D and also get indexed access as a bonus. // copy list to array because we are need convert aiVector2D to aiVector3D and also get indexed access as a bonus.
tc_arr_copy.reserve(pTexCoords.size()); tc_arr_copy.reserve(pTexCoords.size());
for ( std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); it++ ) for ( std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); ++it )
{ {
tc_arr_copy.push_back( aiVector3D( ( *it ).x, ( *it ).y, 0 ) ); tc_arr_copy.push_back( aiVector3D( ( *it ).x, ( *it ).y, 0 ) );
} }
@ -1699,7 +1699,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
// create nodes tree // create nodes tree
Postprocess_BuildNode(*NodeElement_Cur, *pScene->mRootNode, mesh_list, mat_list, light_list); Postprocess_BuildNode(*NodeElement_Cur, *pScene->mRootNode, mesh_list, mat_list, light_list);
// copy needed data to scene // copy needed data to scene
if(mesh_list.size() > 0) if(!mesh_list.empty())
{ {
std::list<aiMesh*>::const_iterator it = mesh_list.begin(); std::list<aiMesh*>::const_iterator it = mesh_list.begin();
@ -1708,7 +1708,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *it++; for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *it++;
} }
if(mat_list.size() > 0) if(!mat_list.empty())
{ {
std::list<aiMaterial*>::const_iterator it = mat_list.begin(); std::list<aiMaterial*>::const_iterator it = mat_list.begin();
@ -1717,7 +1717,7 @@ void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
for(size_t i = 0; i < pScene->mNumMaterials; i++) pScene->mMaterials[i] = *it++; for(size_t i = 0; i < pScene->mNumMaterials; i++) pScene->mMaterials[i] = *it++;
} }
if(light_list.size() > 0) if(!light_list.empty())
{ {
std::list<aiLight*>::const_iterator it = light_list.begin(); std::list<aiLight*>::const_iterator it = light_list.begin();

View File

@ -356,7 +356,7 @@ void X3DImporter::ParseNode_Geometry2D_Polyline2D()
std::list<aiVector3D> tlist; std::list<aiVector3D> tlist;
// convert vec2 to vec3 // convert vec2 to vec3
for(std::list<aiVector2D>::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); it2++) tlist.push_back(aiVector3D(it2->x, it2->y, 0)); for(std::list<aiVector2D>::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); ++it2) tlist.push_back(aiVector3D(it2->x, it2->y, 0));
// convert point set to line set // convert point set to line set
GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices); GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
@ -399,7 +399,7 @@ void X3DImporter::ParseNode_Geometry2D_Polypoint2D()
if(!def.empty()) ne->ID = def; if(!def.empty()) ne->ID = def;
// convert vec2 to vec3 // convert vec2 to vec3
for(std::list<aiVector2D>::iterator it2 = point.begin(); it2 != point.end(); it2++) for(std::list<aiVector2D>::iterator it2 = point.begin(); it2 != point.end(); ++it2)
{ {
((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0)); ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
} }
@ -500,7 +500,7 @@ void X3DImporter::ParseNode_Geometry2D_TriangleSet2D()
if(!def.empty()) ne->ID = def; if(!def.empty()) ne->ID = def;
// convert vec2 to vec3 // convert vec2 to vec3
for(std::list<aiVector2D>::iterator it2 = vertices.begin(); it2 != vertices.end(); it2++) for(std::list<aiVector2D>::iterator it2 = vertices.begin(); it2 != vertices.end(); ++it2)
{ {
((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0)); ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
} }

View File

@ -153,11 +153,11 @@ void X3DImporter::ParseNode_Geometry3D_Cone()
{ {
StandardShapes::MakeCircle(bottomRadius, tess, tvec); StandardShapes::MakeCircle(bottomRadius, tess, tvec);
height = -(height / 2); height = -(height / 2);
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); it++) it->y = height;// y - because circle made in oXZ. for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); ++it) it->y = height;// y - because circle made in oXZ.
} }
// copy data from temp array // copy data from temp array
for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); it++) ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it); for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); ++it) ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it);
((CX3DImporter_NodeElement_Geometry3D*)ne)->Solid = solid; ((CX3DImporter_NodeElement_Geometry3D*)ne)->Solid = solid;
((CX3DImporter_NodeElement_Geometry3D*)ne)->NumIndices = 3; ((CX3DImporter_NodeElement_Geometry3D*)ne)->NumIndices = 3;
@ -226,11 +226,11 @@ void X3DImporter::ParseNode_Geometry3D_Cylinder()
// copy data from temp arrays // copy data from temp arrays
std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices;// just short alias. std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices;// just short alias.
for(std::vector<aiVector3D>::iterator it = tside.begin(); it != tside.end(); it++) vlist.push_back(*it); for(std::vector<aiVector3D>::iterator it = tside.begin(); it != tside.end(); ++it) vlist.push_back(*it);
if(top) if(top)
{ {
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); it++) for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); ++it)
{ {
(*it).y = height;// y - because circle made in oXZ. (*it).y = height;// y - because circle made in oXZ.
vlist.push_back(*it); vlist.push_back(*it);
@ -239,7 +239,7 @@ void X3DImporter::ParseNode_Geometry3D_Cylinder()
if(bottom) if(bottom)
{ {
for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); it++) for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); ++it)
{ {
(*it).y = -height;// y - because circle made in oXZ. (*it).y = -height;// y - because circle made in oXZ.
vlist.push_back(*it); vlist.push_back(*it);
@ -336,7 +336,7 @@ void X3DImporter::ParseNode_Geometry3D_ElevationGrid()
aiVector3D tvec(xSpacing * xi, *he_it, zSpacing * zi); aiVector3D tvec(xSpacing * xi, *he_it, zSpacing * zi);
grid_alias.Vertices.push_back(tvec); grid_alias.Vertices.push_back(tvec);
he_it++; ++he_it;
} }
} }
}// END: create grid vertices list }// END: create grid vertices list
@ -977,7 +977,7 @@ void X3DImporter::ParseNode_Geometry3D_Sphere()
StandardShapes::MakeSphere(tess, tlist); StandardShapes::MakeSphere(tess, tlist);
// copy data from temp array and apply scale // copy data from temp array and apply scale
for(std::vector<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); it++) for(std::vector<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); ++it)
{ {
((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it * radius); ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it * radius);
} }

View File

@ -93,7 +93,7 @@ void X3DImporter::ParseNode_Networking_Inline()
// at this place new group mode created and made current, so we can name it. // at this place new group mode created and made current, so we can name it.
if(!def.empty()) NodeElement_Cur->ID = def; if(!def.empty()) NodeElement_Cur->ID = def;
if(load && (url.size() > 0)) if(load && !url.empty())
{ {
std::string full_path = mpIOHandler->CurrentDirectory() + url.front(); std::string full_path = mpIOHandler->CurrentDirectory() + url.front();

View File

@ -81,7 +81,7 @@ aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const
} }
// multiplicate all matrices in reverse order // multiplicate all matrices in reverse order
for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit); for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); ++rit) out_matr = out_matr * (*rit);
return out_matr; return out_matr;
} }
@ -89,7 +89,7 @@ aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const
void X3DImporter::PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list<CX3DImporter_NodeElement*>& pList) const void X3DImporter::PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list<CX3DImporter_NodeElement*>& pList) const
{ {
// walk through childs and find for metadata. // walk through childs and find for metadata.
for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++) for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); ++el_it)
{ {
if(((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaBoolean) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble) || if(((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaBoolean) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble) ||
((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger) ||
@ -194,7 +194,7 @@ void X3DImporter::Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNod
aiMaterial& taimat = **pMaterial;// creating alias for convenience. aiMaterial& taimat = **pMaterial;// creating alias for convenience.
// at this point pNodeElement point to <Appearance> node. Walk through childs and add all stored data. // at this point pNodeElement point to <Appearance> node. Walk through childs and add all stored data.
for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++) for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); ++el_it)
{ {
if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material) if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material)
{ {
@ -255,7 +255,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
std::vector<aiVector3D> tarr; std::vector<aiVector3D> tarr;
tarr.reserve(tnemesh.Vertices.size()); tarr.reserve(tnemesh.Vertices.size());
for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it); for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); ++it) tarr.push_back(*it);
*pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help. *pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help.
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
@ -273,7 +273,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
std::vector<aiVector3D> tarr; std::vector<aiVector3D> tarr;
tarr.reserve(tnemesh.Vertices.size()); tarr.reserve(tnemesh.Vertices.size());
for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it); for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); ++it) tarr.push_back(*it);
*pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help. *pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help.
@ -289,7 +289,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
// at first create mesh from existing vertices. // at first create mesh from existing vertices.
*pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIdx, tnemesh.Vertices); *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIdx, tnemesh.Vertices);
// copy additional information from children // copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex); MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
@ -301,7 +301,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + to_string((*ch_it)->Type) + ".");
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_ElevationGrid) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_ElevationGrid)
@ -313,7 +313,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh. // at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{ {
@ -322,7 +322,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
} }
// copy additional information from children // copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex); MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
@ -338,7 +338,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + to_string((*ch_it)->Type) + ".");
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedFaceSet) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedFaceSet)
@ -348,7 +348,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh. // at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{ {
@ -357,7 +357,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
} }
// copy additional information from children // copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
ai_assert(*pMesh); ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -369,7 +369,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
{} // skip because already read when mesh created. {} // skip because already read when mesh created.
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + to_string((*ch_it)->Type) + ".");
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedLineSet) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedLineSet)
@ -381,7 +381,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh. // at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{ {
@ -390,7 +390,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
} }
// copy additional information from children // copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
ai_assert(*pMesh); ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -408,7 +408,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \ throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \
IndexedTriangleStripSet: " + to_string((*ch_it)->Type) + "."); IndexedTriangleStripSet: " + to_string((*ch_it)->Type) + ".");
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
}// if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet)) }// if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet))
@ -430,7 +430,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh. // at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{ {
@ -438,7 +438,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size()); vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size());
for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin(); for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin();
it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++) it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); ++it)
{ {
vec_copy.push_back(*it); vec_copy.push_back(*it);
} }
@ -448,7 +448,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
} }
// copy additional information from children // copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
ai_assert(*pMesh); ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -459,7 +459,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
{} // skip because already read when mesh created. {} // skip because already read when mesh created.
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + to_string((*ch_it)->Type) + ".");
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_PointSet) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_PointSet)
@ -469,7 +469,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh. // at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{ {
@ -478,7 +478,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
} }
// copy additional information from children // copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
ai_assert(*pMesh); ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -489,7 +489,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
{} // skip because already read when mesh created. {} // skip because already read when mesh created.
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + to_string((*ch_it)->Type) + ".");
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_LineSet) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_LineSet)
@ -499,7 +499,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh. // at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{ {
@ -508,7 +508,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
} }
// copy additional information from children // copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if ( nullptr == *pMesh ) { if ( nullptr == *pMesh ) {
break; break;
@ -526,7 +526,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + to_string((*ch_it)->Type) + ".");
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleFanSet) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleFanSet)
@ -536,7 +536,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh. // at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{ {
@ -544,7 +544,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size()); vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size());
for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin(); for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin();
it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++) it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); ++it)
{ {
vec_copy.push_back(*it); vec_copy.push_back(*it);
} }
@ -554,7 +554,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
} }
// copy additional information from children // copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
ai_assert(*pMesh); ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -570,7 +570,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + to_string((*ch_it)->Type) + ".");
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet)
@ -580,7 +580,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
// at first search for <Coordinate> node and create mesh. // at first search for <Coordinate> node and create mesh.
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
{ {
@ -589,7 +589,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
} }
// copy additional information from children // copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
{ {
ai_assert(*pMesh); ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color) if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@ -605,7 +605,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value); MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
else else
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + to_string((*ch_it)->Type) + "."); throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + to_string((*ch_it)->Type) + ".");
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++) }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
return;// mesh is build, nothing to do anymore. return;// mesh is build, nothing to do anymore.
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet)
@ -639,16 +639,16 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
} }
else else
{ {
for(size_t i = 0; i < (size_t)tne_group.Choice; i++) chit_begin++;// forward iterator to chosen node. for(size_t i = 0; i < (size_t)tne_group.Choice; i++) ++chit_begin;// forward iterator to chosen node.
chit_end = chit_begin; chit_end = chit_begin;
chit_end++;// point end iterator to next element after chosen node. ++chit_end;// point end iterator to next element after chosen node.
} }
}// if(tne_group.UseChoice) }// if(tne_group.UseChoice)
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group) }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group)
// Reserve memory for fast access and check children. // Reserve memory for fast access and check children.
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++) for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; ++it)
{// in this loop we do not read metadata because it's already read at begin. {// in this loop we do not read metadata because it's already read at begin.
if((*it)->Type == CX3DImporter_NodeElement::ENET_Group) if((*it)->Type == CX3DImporter_NodeElement::ENET_Group)
{ {
@ -677,7 +677,7 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
}// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++) }// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++)
// copy data about children and meshes to aiNode. // copy data about children and meshes to aiNode.
if(SceneNode_Child.size() > 0) if(!SceneNode_Child.empty())
{ {
std::list<aiNode*>::const_iterator it = SceneNode_Child.begin(); std::list<aiNode*>::const_iterator it = SceneNode_Child.begin();
@ -686,7 +686,7 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
for(size_t i = 0; i < pSceneNode.mNumChildren; i++) pSceneNode.mChildren[i] = *it++; for(size_t i = 0; i < pSceneNode.mNumChildren; i++) pSceneNode.mChildren[i] = *it++;
} }
if(SceneNode_Mesh.size() > 0) if(!SceneNode_Mesh.empty())
{ {
std::list<unsigned int>::const_iterator it = SceneNode_Mesh.begin(); std::list<unsigned int>::const_iterator it = SceneNode_Mesh.begin();
@ -706,7 +706,7 @@ void X3DImporter::Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& p
CX3DImporter_NodeElement::EType mesh_type = CX3DImporter_NodeElement::ENET_Invalid; CX3DImporter_NodeElement::EType mesh_type = CX3DImporter_NodeElement::ENET_Invalid;
unsigned int mat_ind = 0; unsigned int mat_ind = 0;
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); it++) for(std::list<CX3DImporter_NodeElement*>::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); ++it)
{ {
if(PostprocessHelper_ElementIsMesh((*it)->Type)) if(PostprocessHelper_ElementIsMesh((*it)->Type))
{ {
@ -779,7 +779,7 @@ void X3DImporter::Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pN
// copy collected metadata to output node. // copy collected metadata to output node.
pSceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(meta_list.size()) ); pSceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(meta_list.size()) );
meta_idx = 0; meta_idx = 0;
for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++, meta_idx++) for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); ++it, ++meta_idx)
{ {
CX3DImporter_NodeElement_Meta* cur_meta = (CX3DImporter_NodeElement_Meta*)*it; CX3DImporter_NodeElement_Meta* cur_meta = (CX3DImporter_NodeElement_Meta*)*it;

View File

@ -295,7 +295,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet()
ne_alias.CoordIndex.clear(); ne_alias.CoordIndex.clear();
int counter = 0; int counter = 0;
int32_t idx[3]; int32_t idx[3];
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it)
{ {
idx[2] = *idx_it; idx[2] = *idx_it;
if (idx[2] < 0) if (idx[2] < 0)
@ -413,7 +413,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet()
ne_alias.CoordIndex.clear(); ne_alias.CoordIndex.clear();
int counter = 0; int counter = 0;
int32_t idx[3]; int32_t idx[3];
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it)
{ {
idx[counter++] = *idx_it; idx[counter++] = *idx_it;
if (counter > 2) if (counter > 2)
@ -519,7 +519,7 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet()
ne_alias.CoordIndex.clear(); ne_alias.CoordIndex.clear();
int counter = 0; int counter = 0;
int32_t idx[3]; int32_t idx[3];
for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++) for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); ++idx_it)
{ {
idx[2] = *idx_it; idx[2] = *idx_it;
if (idx[2] < 0) if (idx[2] < 0)
@ -617,7 +617,7 @@ void X3DImporter::ParseNode_Rendering_LineSet()
size_t coord_num = 0; size_t coord_num = 0;
ne_alias.CoordIndex.clear(); ne_alias.CoordIndex.clear();
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it)
{ {
if(*vc_it < 2) throw DeadlyImportError("LineSet. vertexCount shall be greater than or equal to two."); if(*vc_it < 2) throw DeadlyImportError("LineSet. vertexCount shall be greater than or equal to two.");
@ -765,7 +765,7 @@ void X3DImporter::ParseNode_Rendering_TriangleFanSet()
// assign indices for first triangle // assign indices for first triangle
coord_num_first = 0; coord_num_first = 0;
coord_num_prev = 1; coord_num_prev = 1;
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it)
{ {
if(*vc_it < 3) throw DeadlyImportError("TriangleFanSet. fanCount shall be greater than or equal to three."); if(*vc_it < 3) throw DeadlyImportError("TriangleFanSet. fanCount shall be greater than or equal to three.");
@ -956,7 +956,7 @@ void X3DImporter::ParseNode_Rendering_TriangleStripSet()
ne_alias.CoordIndex.clear(); ne_alias.CoordIndex.clear();
coord_num_sb = 0; coord_num_sb = 0;
for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++) for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); ++vc_it)
{ {
if(*vc_it < 3) throw DeadlyImportError("TriangleStripSet. stripCount shall be greater than or equal to three."); if(*vc_it < 3) throw DeadlyImportError("TriangleStripSet. stripCount shall be greater than or equal to three.");

View File

@ -89,7 +89,7 @@ void X3DImporter::ParseNode_Texturing_ImageTexture()
((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatS = repeatS; ((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatS = repeatS;
((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatT = repeatT; ((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatT = repeatT;
// Attribute "url" can contain list of strings. But we need only one - first. // Attribute "url" can contain list of strings. But we need only one - first.
if(url.size() > 0) if(!url.empty())
((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = url.front(); ((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = url.front();
else else
((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = ""; ((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = "";

View File

@ -92,38 +92,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# endif # endif
#endif #endif
#include "glTF/glTFCommon.h"
namespace glTF namespace glTF
{ {
#ifdef ASSIMP_API using glTFCommon::shared_ptr;
using Assimp::IOStream; using glTFCommon::IOSystem;
using Assimp::IOSystem; using glTFCommon::IOStream;
using std::shared_ptr;
#else
using std::shared_ptr;
typedef std::runtime_error DeadlyImportError;
typedef std::runtime_error DeadlyExportError;
enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
class IOSystem;
class IOStream
{
FILE* f;
public:
IOStream(FILE* file) : f(file) {}
~IOStream() { fclose(f); f = 0; }
size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
size_t Tell() const { return ftell(f); }
size_t FileSize() {
long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
return size_t((Seek(p, aiOrigin_SET), len));
}
};
#endif
using rapidjson::Value; using rapidjson::Value;
using rapidjson::Document; using rapidjson::Document;
@ -136,37 +111,9 @@ namespace glTF
struct Light; struct Light;
struct Skin; struct Skin;
using glTFCommon::vec3;
// Vec/matrix types, as raw float arrays using glTFCommon::vec4;
typedef float (vec3)[3]; using glTFCommon::mat4;
typedef float (vec4)[4];
typedef float (mat4)[16];
namespace Util
{
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
inline size_t DecodeBase64(const char* in, uint8_t*& out)
{
return DecodeBase64(in, strlen(in), out);
}
struct DataURI
{
const char* mediaType;
const char* charset;
bool base64;
const char* data;
size_t dataLength;
};
//! Check if a uri is a data URI
inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
}
//! Magic number for GLB files //! Magic number for GLB files
#define AI_GLB_MAGIC_NUMBER "glTF" #define AI_GLB_MAGIC_NUMBER "glTF"

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team Copyright (c) 2006-2019, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -52,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
using namespace Assimp; using namespace Assimp;
using namespace glTFCommon;
namespace glTF { namespace glTF {
@ -301,7 +301,7 @@ inline void Buffer::Read(Value& obj, Asset& r)
const char* uri = it->GetString(); const char* uri = it->GetString();
Util::DataURI dataURI; glTFCommon::Util::DataURI dataURI;
if (ParseDataURI(uri, it->GetStringLength(), dataURI)) { if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
if (dataURI.base64) { if (dataURI.base64) {
uint8_t* data = 0; uint8_t* data = 0;
@ -654,12 +654,12 @@ inline void Image::Read(Value& obj, Asset& r)
if (Value* uri = FindString(obj, "uri")) { if (Value* uri = FindString(obj, "uri")) {
const char* uristr = uri->GetString(); const char* uristr = uri->GetString();
Util::DataURI dataURI; glTFCommon::Util::DataURI dataURI;
if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) { if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
mimeType = dataURI.mediaType; mimeType = dataURI.mediaType;
if (dataURI.base64) { if (dataURI.base64) {
uint8_t *ptr = nullptr; uint8_t *ptr = nullptr;
mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr); mDataLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
mData.reset(ptr); mData.reset(ptr);
} }
} }
@ -1180,8 +1180,12 @@ inline void Light::SetDefaults()
falloffExponent = 0.f; falloffExponent = 0.f;
} }
inline void Node::Read(Value& obj, Asset& r) inline
{ void Node::Read(Value& obj, Asset& r) {
if (name.empty()) {
name = id;
}
if (Value* children = FindArray(obj, "children")) { if (Value* children = FindArray(obj, "children")) {
this->children.reserve(children->Size()); this->children.reserve(children->Size());
for (unsigned int i = 0; i < children->Size(); ++i) { for (unsigned int i = 0; i < children->Size(); ++i) {
@ -1474,190 +1478,4 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
return id; return id;
} }
namespace Util {
inline
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
if ( NULL == const_uri ) {
return false;
}
if (const_uri[0] != 0x10) { // we already parsed this uri?
if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
return false;
}
// set defaults
out.mediaType = "text/plain";
out.charset = "US-ASCII";
out.base64 = false;
char* uri = const_cast<char*>(const_uri);
if (uri[0] != 0x10) {
uri[0] = 0x10;
uri[1] = uri[2] = uri[3] = uri[4] = 0;
size_t i = 5, j;
if (uri[i] != ';' && uri[i] != ',') { // has media type?
uri[1] = char(i);
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
}
while (uri[i] == ';' && i < uriLen) {
uri[i++] = '\0';
for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
uri[2] = char(j + 8);
} else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
uri[3] = char(j);
}
}
if (i < uriLen) {
uri[i++] = '\0';
uri[4] = char(i);
} else {
uri[1] = uri[2] = uri[3] = 0;
uri[4] = 5;
}
}
if ( uri[ 1 ] != 0 ) {
out.mediaType = uri + uri[ 1 ];
}
if ( uri[ 2 ] != 0 ) {
out.charset = uri + uri[ 2 ];
}
if ( uri[ 3 ] != 0 ) {
out.base64 = true;
}
out.data = uri + uri[4];
out.dataLength = (uri + uriLen) - out.data;
return true;
}
template<bool B>
struct DATA
{
static const uint8_t tableDecodeBase64[128];
};
template<bool B>
const uint8_t DATA<B>::tableDecodeBase64[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
};
inline char EncodeCharBase64(uint8_t b)
{
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
}
inline uint8_t DecodeCharBase64(char c)
{
return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
/*if (c >= 'A' && c <= 'Z') return c - 'A';
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
if (c >= '0' && c <= '9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return 64; // '-' */
}
inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
{
ai_assert(inLength % 4 == 0);
if (inLength < 4) {
out = 0;
return 0;
}
int nEquals = int(in[inLength - 1] == '=') +
int(in[inLength - 2] == '=');
size_t outLength = (inLength * 3) / 4 - nEquals;
out = new uint8_t[outLength];
memset(out, 0, outLength);
size_t i, j = 0;
for (i = 0; i + 4 < inLength; i += 4) {
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
out[j++] = (uint8_t)((b2 << 6) | b3);
}
{
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
}
return outLength;
}
inline void EncodeBase64(
const uint8_t* in, size_t inLength,
std::string& out)
{
size_t outLength = ((inLength + 2) / 3) * 4;
size_t j = out.size();
out.resize(j + outLength);
for (size_t i = 0; i < inLength; i += 3) {
uint8_t b = (in[i] & 0xFC) >> 2;
out[j++] = EncodeCharBase64(b);
b = (in[i] & 0x03) << 4;
if (i + 1 < inLength) {
b |= (in[i + 1] & 0xF0) >> 4;
out[j++] = EncodeCharBase64(b);
b = (in[i + 1] & 0x0F) << 2;
if (i + 2 < inLength) {
b |= (in[i + 2] & 0xC0) >> 6;
out[j++] = EncodeCharBase64(b);
b = in[i + 2] & 0x3F;
out[j++] = EncodeCharBase64(b);
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
}
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
out[j++] = '=';
}
}
}
}
} // ns glTF } // ns glTF

View File

@ -55,7 +55,8 @@ namespace glTF {
namespace { namespace {
template<size_t N> template<size_t N>
inline Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) { inline
Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) {
val.SetArray(); val.SetArray();
val.Reserve(N, al); val.Reserve(N, al);
for (decltype(N) i = 0; i < N; ++i) { for (decltype(N) i = 0; i < N; ++i) {
@ -64,7 +65,8 @@ namespace glTF {
return val; return val;
} }
inline Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) { inline
Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
val.SetArray(); val.SetArray();
val.Reserve(static_cast<rapidjson::SizeType>(r.size()), al); val.Reserve(static_cast<rapidjson::SizeType>(r.size()), al);
for (unsigned int i = 0; i < r.size(); ++i) { for (unsigned int i = 0; i < r.size(); ++i) {
@ -213,7 +215,7 @@ namespace glTF {
else if (img.HasData()) { else if (img.HasData()) {
uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType); uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
uri += ";base64,"; uri += ";base64,";
Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri); glTFCommon::Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
} }
else { else {
uri = img.uri; uri = img.uri;

View File

@ -0,0 +1,193 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2019, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#include "glTF/glTFCommon.h"
namespace glTFCommon {
using namespace glTFCommon::Util;
namespace Util {
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out) {
ai_assert(inLength % 4 == 0);
if (inLength < 4) {
out = 0;
return 0;
}
int nEquals = int(in[inLength - 1] == '=') +
int(in[inLength - 2] == '=');
size_t outLength = (inLength * 3) / 4 - nEquals;
out = new uint8_t[outLength];
memset(out, 0, outLength);
size_t i, j = 0;
for (i = 0; i + 4 < inLength; i += 4) {
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
out[j++] = (uint8_t)((b2 << 6) | b3);
}
{
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
}
return outLength;
}
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out) {
size_t outLength = ((inLength + 2) / 3) * 4;
size_t j = out.size();
out.resize(j + outLength);
for (size_t i = 0; i < inLength; i += 3) {
uint8_t b = (in[i] & 0xFC) >> 2;
out[j++] = EncodeCharBase64(b);
b = (in[i] & 0x03) << 4;
if (i + 1 < inLength) {
b |= (in[i + 1] & 0xF0) >> 4;
out[j++] = EncodeCharBase64(b);
b = (in[i + 1] & 0x0F) << 2;
if (i + 2 < inLength) {
b |= (in[i + 2] & 0xC0) >> 6;
out[j++] = EncodeCharBase64(b);
b = in[i + 2] & 0x3F;
out[j++] = EncodeCharBase64(b);
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
}
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
out[j++] = '=';
}
}
}
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
if (nullptr == const_uri) {
return false;
}
if (const_uri[0] != 0x10) { // we already parsed this uri?
if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
return false;
}
// set defaults
out.mediaType = "text/plain";
out.charset = "US-ASCII";
out.base64 = false;
char* uri = const_cast<char*>(const_uri);
if (uri[0] != 0x10) {
uri[0] = 0x10;
uri[1] = uri[2] = uri[3] = uri[4] = 0;
size_t i = 5, j;
if (uri[i] != ';' && uri[i] != ',') { // has media type?
uri[1] = char(i);
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
}
while (uri[i] == ';' && i < uriLen) {
uri[i++] = '\0';
for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
if (strncmp(uri + j, "charset=", 8) == 0) {
uri[2] = char(j + 8);
}
else if (strncmp(uri + j, "base64", 6) == 0) {
uri[3] = char(j);
}
}
if (i < uriLen) {
uri[i++] = '\0';
uri[4] = char(i);
}
else {
uri[1] = uri[2] = uri[3] = 0;
uri[4] = 5;
}
}
if (uri[1] != 0) {
out.mediaType = uri + uri[1];
}
if (uri[2] != 0) {
out.charset = uri + uri[2];
}
if (uri[3] != 0) {
out.base64 = true;
}
out.data = uri + uri[4];
out.dataLength = (uri + uriLen) - out.data;
return true;
}
}
}

View File

@ -0,0 +1,248 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2019, 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 AI_GLFTCOMMON_H_INC
#define AI_GLFTCOMMON_H_INC
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#include <assimp/Exceptional.h>
#include <map>
#include <string>
#include <list>
#include <vector>
#include <algorithm>
#include <stdexcept>
#define RAPIDJSON_HAS_STDSTRING 1
#include <rapidjson/rapidjson.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#ifdef ASSIMP_API
# include <memory>
# include <assimp/DefaultIOSystem.h>
# include <assimp/ByteSwapper.h>
#else
# include <memory>
# define AI_SWAP4(p)
# define ai_assert
#endif
#if _MSC_VER > 1500 || (defined __GNUC___)
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
# else
# define gltf_unordered_map map
#endif
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
# include <unordered_map>
# if _MSC_VER > 1600
# define gltf_unordered_map unordered_map
# else
# define gltf_unordered_map tr1::unordered_map
# endif
#endif
namespace glTFCommon {
#ifdef ASSIMP_API
using Assimp::IOStream;
using Assimp::IOSystem;
using std::shared_ptr;
#else
using std::shared_ptr;
typedef std::runtime_error DeadlyImportError;
typedef std::runtime_error DeadlyExportError;
enum aiOrigin {
aiOrigin_SET = 0,
aiOrigin_CUR = 1,
aiOrigin_END = 2
};
class IOSystem;
class IOStream {
public:
IOStream(FILE* file) : f(file) {}
~IOStream() { fclose(f); f = 0; }
size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
size_t Tell() const { return ftell(f); }
size_t FileSize() {
long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
return size_t((Seek(p, aiOrigin_SET), len));
}
private:
FILE* f;
};
#endif
// Vec/matrix types, as raw float arrays
typedef float(vec3)[3];
typedef float(vec4)[4];
typedef float(mat4)[16];
inline
void CopyValue(const glTFCommon::vec3& v, aiColor4D& out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
out.a = 1.0;
}
inline
void CopyValue(const glTFCommon::vec4& v, aiColor4D& out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
out.a = v[3];
}
inline
void CopyValue(const glTFCommon::vec4& v, aiColor3D& out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
}
inline
void CopyValue(const glTFCommon::vec3& v, aiColor3D& out) {
out.r = v[0];
out.g = v[1];
out.b = v[2];
}
inline
void CopyValue(const glTFCommon::vec3& v, aiVector3D& out) {
out.x = v[0];
out.y = v[1];
out.z = v[2];
}
inline
void CopyValue(const glTFCommon::vec4& v, aiQuaternion& out) {
out.x = v[0];
out.y = v[1];
out.z = v[2];
out.w = v[3];
}
inline
void CopyValue(const glTFCommon::mat4& v, aiMatrix4x4& o) {
o.a1 = v[0]; o.b1 = v[1]; o.c1 = v[2]; o.d1 = v[3];
o.a2 = v[4]; o.b2 = v[5]; o.c2 = v[6]; o.d2 = v[7];
o.a3 = v[8]; o.b3 = v[9]; o.c3 = v[10]; o.d3 = v[11];
o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
}
namespace Util {
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
inline
size_t DecodeBase64(const char* in, uint8_t*& out) {
return DecodeBase64(in, strlen(in), out);
}
struct DataURI {
const char* mediaType;
const char* charset;
bool base64;
const char* data;
size_t dataLength;
};
//! Check if a uri is a data URI
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out);
template<bool B>
struct DATA {
static const uint8_t tableDecodeBase64[128];
};
template<bool B>
const uint8_t DATA<B>::tableDecodeBase64[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
};
inline
char EncodeCharBase64(uint8_t b) {
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
}
inline
uint8_t DecodeCharBase64(char c) {
return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
/*if (c >= 'A' && c <= 'Z') return c - 'A';
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
if (c >= '0' && c <= '9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return 64; // '-' */
}
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
}
}
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
#endif // AI_GLFTCOMMON_H_INC

View File

@ -242,7 +242,10 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
namespace { namespace {
void GetMatScalar(const aiMaterial* mat, float& val, const char* propName, int type, int idx) { void GetMatScalar(const aiMaterial* mat, float& val, const char* propName, int type, int idx) {
ai_assert(mat->Get(propName, type, idx, val) == AI_SUCCESS); ai_assert( nullptr != mat );
if ( nullptr != mat ) {
mat->Get(propName, type, idx, val);
}
} }
} }

View File

@ -82,7 +82,7 @@ glTFImporter::glTFImporter()
: BaseImporter() : BaseImporter()
, meshOffsets() , meshOffsets()
, embeddedTexIdxs() , embeddedTexIdxs()
, mScene( NULL ) { , mScene( nullptr ) {
// empty // empty
} }
@ -90,17 +90,16 @@ glTFImporter::~glTFImporter() {
// empty // empty
} }
const aiImporterDesc* glTFImporter::GetInfo() const const aiImporterDesc* glTFImporter::GetInfo() const {
{
return &desc; return &desc;
} }
bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const {
{
const std::string &extension = GetExtension(pFile); const std::string &extension = GetExtension(pFile);
if (extension != "gltf" && extension != "glb") if (extension != "gltf" && extension != "glb") {
return false; return false;
}
if (pIOHandler) { if (pIOHandler) {
glTF::Asset asset(pIOHandler); glTF::Asset asset(pIOHandler);
@ -116,44 +115,9 @@ bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
return false; return false;
} }
inline
void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
//static void CopyValue(const glTF::vec3& v, aiColor3D& out) aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx) {
//{
// out.r = v[0]; out.g = v[1]; out.b = v[2];
//}
static void CopyValue(const glTF::vec4& v, aiColor4D& out)
{
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
}
static void CopyValue(const glTF::vec4& v, aiColor3D& out)
{
out.r = v[0]; out.g = v[1]; out.b = v[2];
}
static void CopyValue(const glTF::vec3& v, aiVector3D& out)
{
out.x = v[0]; out.y = v[1]; out.z = v[2];
}
static void CopyValue(const glTF::vec4& v, aiQuaternion& out)
{
out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
}
static void CopyValue(const glTF::mat4& v, aiMatrix4x4& o)
{
o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
}
inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx)
{
if (prop.texture) { if (prop.texture) {
if (prop.texture->source) { if (prop.texture->source) {
aiString uri(prop.texture->source->uri); aiString uri(prop.texture->source->uri);
@ -167,16 +131,14 @@ inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /
mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0); mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0);
} }
} } else {
else {
aiColor4D col; aiColor4D col;
CopyValue(prop.color, col); CopyValue(prop.color, col);
mat->AddProperty(&col, 1, pKey, type, idx); mat->AddProperty(&col, 1, pKey, type, idx);
} }
} }
void glTFImporter::ImportMaterials(glTF::Asset& r) void glTFImporter::ImportMaterials(glTF::Asset& r) {
{
mScene->mNumMaterials = unsigned(r.materials.Size()); mScene->mNumMaterials = unsigned(r.materials.Size());
mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials]; mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials];
@ -304,7 +266,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
aim->mName = mesh.id; aim->mName = mesh.id;
if (mesh.primitives.size() > 1) { if (mesh.primitives.size() > 1) {
size_t& len = aim->mName.length; ai_uint32& len = aim->mName.length;
aim->mName.data[len] = '-'; aim->mName.data[len] = '-';
len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p); len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
} }
@ -499,27 +461,31 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes); CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
} }
void glTFImporter::ImportCameras(glTF::Asset& r) void glTFImporter::ImportCameras(glTF::Asset& r) {
{ if (!r.cameras.Size()) {
if (!r.cameras.Size()) return; return;
}
mScene->mNumCameras = r.cameras.Size(); mScene->mNumCameras = r.cameras.Size();
mScene->mCameras = new aiCamera*[r.cameras.Size()]; mScene->mCameras = new aiCamera*[r.cameras.Size()];
for (size_t i = 0; i < r.cameras.Size(); ++i) { for (size_t i = 0; i < r.cameras.Size(); ++i) {
Camera& cam = r.cameras[i]; Camera& cam = r.cameras[i];
aiCamera* aicam = mScene->mCameras[i] = new aiCamera(); aiCamera* aicam = mScene->mCameras[i] = new aiCamera();
if (cam.type == Camera::Perspective) { if (cam.type == Camera::Perspective) {
aicam->mAspect = cam.perspective.aspectRatio; aicam->mAspect = cam.perspective.aspectRatio;
aicam->mHorizontalFOV = cam.perspective.yfov * aicam->mAspect; aicam->mHorizontalFOV = cam.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect);
aicam->mClipPlaneFar = cam.perspective.zfar; aicam->mClipPlaneFar = cam.perspective.zfar;
aicam->mClipPlaneNear = cam.perspective.znear; aicam->mClipPlaneNear = cam.perspective.znear;
} else {
aicam->mClipPlaneFar = cam.ortographic.zfar;
aicam->mClipPlaneNear = cam.ortographic.znear;
aicam->mHorizontalFOV = 0.0;
aicam->mAspect = 1.0f;
if (0.f != cam.ortographic.ymag) {
aicam->mAspect = cam.ortographic.xmag / cam.ortographic.ymag;
} }
else {
// assimp does not support orthographic cameras
} }
} }
} }

View File

@ -95,38 +95,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include "glTF/glTFCommon.h"
namespace glTF2 namespace glTF2
{ {
#ifdef ASSIMP_API using glTFCommon::shared_ptr;
using Assimp::IOStream; using glTFCommon::IOSystem;
using Assimp::IOSystem; using glTFCommon::IOStream;
using std::shared_ptr;
#else
using std::shared_ptr;
typedef std::runtime_error DeadlyImportError;
typedef std::runtime_error DeadlyExportError;
enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
class IOSystem;
class IOStream
{
FILE* f;
public:
IOStream(FILE* file) : f(file) {}
~IOStream() { fclose(f); f = 0; }
size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
size_t Tell() const { return ftell(f); }
size_t FileSize() {
long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
return size_t((Seek(p, aiOrigin_SET), len));
}
};
#endif
using rapidjson::Value; using rapidjson::Value;
using rapidjson::Document; using rapidjson::Document;
@ -138,35 +113,9 @@ namespace glTF2
struct Texture; struct Texture;
struct Skin; struct Skin;
// Vec/matrix types, as raw float arrays using glTFCommon::vec3;
typedef float (vec3)[3]; using glTFCommon::vec4;
typedef float (vec4)[4]; using glTFCommon::mat4;
typedef float (mat4)[16];
namespace Util
{
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
inline size_t DecodeBase64(const char* in, uint8_t*& out)
{
return DecodeBase64(in, strlen(in), out);
}
struct DataURI
{
const char* mediaType;
const char* charset;
bool base64;
const char* data;
size_t dataLength;
};
//! Check if a uri is a data URI
inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
}
//! Magic number for GLB files //! Magic number for GLB files
#define AI_GLB_MAGIC_NUMBER "glTF" #define AI_GLB_MAGIC_NUMBER "glTF"
@ -552,7 +501,7 @@ namespace glTF2
/// but in real life you'll get: /// but in real life you'll get:
/// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4} /// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4}
/// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded. /// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded.
/// And when before you start to read data of current mesh (with encoded data ofcourse) you must decode region of "bufferView", after read finished /// And when before you start to read data of current mesh (with encoded data of course) you must decode region of "bufferView", after read finished
/// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data. /// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data.
/// ///
/// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in /// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in

View File

@ -282,9 +282,7 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i)
template<class T> template<class T>
Ref<T> LazyDict<T>::Get(unsigned int i) Ref<T> LazyDict<T>::Get(unsigned int i)
{ {
return Ref<T>(mObjs, i); return Ref<T>(mObjs, i);
} }
template<class T> template<class T>
@ -361,11 +359,11 @@ inline void Buffer::Read(Value& obj, Asset& r)
const char* uri = it->GetString(); const char* uri = it->GetString();
Util::DataURI dataURI; glTFCommon::Util::DataURI dataURI;
if (ParseDataURI(uri, it->GetStringLength(), dataURI)) { if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
if (dataURI.base64) { if (dataURI.base64) {
uint8_t* data = 0; uint8_t* data = 0;
this->byteLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, data); this->byteLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
this->mData.reset(data, std::default_delete<uint8_t[]>()); this->mData.reset(data, std::default_delete<uint8_t[]>());
if (statedLength > 0 && this->byteLength != statedLength) { if (statedLength > 0 && this->byteLength != statedLength) {
@ -717,12 +715,12 @@ inline void Image::Read(Value& obj, Asset& r)
if (Value* uri = FindString(obj, "uri")) { if (Value* uri = FindString(obj, "uri")) {
const char* uristr = uri->GetString(); const char* uristr = uri->GetString();
Util::DataURI dataURI; glTFCommon::Util::DataURI dataURI;
if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) { if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
mimeType = dataURI.mediaType; mimeType = dataURI.mediaType;
if (dataURI.base64) { if (dataURI.base64) {
uint8_t *ptr = nullptr; uint8_t *ptr = nullptr;
mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr); mDataLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
mData.reset(ptr); mData.reset(ptr);
} }
} }
@ -1100,8 +1098,11 @@ inline void Light::Read(Value& obj, Asset& /*r*/)
} }
} }
inline void Node::Read(Value& obj, Asset& r) inline
{ void Node::Read(Value& obj, Asset& r) {
if (name.empty()) {
name = id;
}
if (Value* children = FindArray(obj, "children")) { if (Value* children = FindArray(obj, "children")) {
this->children.reserve(children->Size()); this->children.reserve(children->Size());
@ -1515,190 +1516,4 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
return id; return id;
} }
namespace Util {
inline
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
if ( NULL == const_uri ) {
return false;
}
if (const_uri[0] != 0x10) { // we already parsed this uri?
if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
return false;
}
// set defaults
out.mediaType = "text/plain";
out.charset = "US-ASCII";
out.base64 = false;
char* uri = const_cast<char*>(const_uri);
if (uri[0] != 0x10) {
uri[0] = 0x10;
uri[1] = uri[2] = uri[3] = uri[4] = 0;
size_t i = 5, j;
if (uri[i] != ';' && uri[i] != ',') { // has media type?
uri[1] = char(i);
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
}
while (uri[i] == ';' && i < uriLen) {
uri[i++] = '\0';
for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
// nothing to do!
}
if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
uri[2] = char(j + 8);
} else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
uri[3] = char(j);
}
}
if (i < uriLen) {
uri[i++] = '\0';
uri[4] = char(i);
} else {
uri[1] = uri[2] = uri[3] = 0;
uri[4] = 5;
}
}
if ( uri[ 1 ] != 0 ) {
out.mediaType = uri + uri[ 1 ];
}
if ( uri[ 2 ] != 0 ) {
out.charset = uri + uri[ 2 ];
}
if ( uri[ 3 ] != 0 ) {
out.base64 = true;
}
out.data = uri + uri[4];
out.dataLength = (uri + uriLen) - out.data;
return true;
}
template<bool B>
struct DATA
{
static const uint8_t tableDecodeBase64[128];
};
template<bool B>
const uint8_t DATA<B>::tableDecodeBase64[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
};
inline char EncodeCharBase64(uint8_t b)
{
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
}
inline uint8_t DecodeCharBase64(char c)
{
return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
/*if (c >= 'A' && c <= 'Z') return c - 'A';
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
if (c >= '0' && c <= '9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return 64; // '-' */
}
inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
{
ai_assert(inLength % 4 == 0);
if (inLength < 4) {
out = 0;
return 0;
}
int nEquals = int(in[inLength - 1] == '=') +
int(in[inLength - 2] == '=');
size_t outLength = (inLength * 3) / 4 - nEquals;
out = new uint8_t[outLength];
memset(out, 0, outLength);
size_t i, j = 0;
for (i = 0; i + 4 < inLength; i += 4) {
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
out[j++] = (uint8_t)((b2 << 6) | b3);
}
{
uint8_t b0 = DecodeCharBase64(in[i]);
uint8_t b1 = DecodeCharBase64(in[i + 1]);
uint8_t b2 = DecodeCharBase64(in[i + 2]);
uint8_t b3 = DecodeCharBase64(in[i + 3]);
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
}
return outLength;
}
inline void EncodeBase64(
const uint8_t* in, size_t inLength,
std::string& out)
{
size_t outLength = ((inLength + 2) / 3) * 4;
size_t j = out.size();
out.resize(j + outLength);
for (size_t i = 0; i < inLength; i += 3) {
uint8_t b = (in[i] & 0xFC) >> 2;
out[j++] = EncodeCharBase64(b);
b = (in[i] & 0x03) << 4;
if (i + 1 < inLength) {
b |= (in[i + 1] & 0xF0) >> 4;
out[j++] = EncodeCharBase64(b);
b = (in[i + 1] & 0x0F) << 2;
if (i + 2 < inLength) {
b |= (in[i + 2] & 0xC0) >> 6;
out[j++] = EncodeCharBase64(b);
b = in[i + 2] & 0x3F;
out[j++] = EncodeCharBase64(b);
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
}
}
else {
out[j++] = EncodeCharBase64(b);
out[j++] = '=';
out[j++] = '=';
}
}
}
}
} // ns glTF } // ns glTF

View File

@ -218,7 +218,7 @@ namespace glTF2 {
if (img.HasData()) { if (img.HasData()) {
uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType); uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
uri += ";base64,"; uri += ";base64,";
Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri); glTFCommon::Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
} }
else { else {
uri = img.uri; uri = img.uri;

View File

@ -64,6 +64,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
using namespace glTF2; using namespace glTF2;
using namespace glTFCommon;
namespace { namespace {
// generate bi-tangents from normals and tangents according to spec // generate bi-tangents from normals and tangents according to spec
@ -140,22 +141,23 @@ static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode)
} }
} }
static void CopyValue(const glTF2::vec3& v, aiColor3D& out) /*static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
{ {
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.r = v[0]; out.g = v[1]; out.b = v[2];
} }
static void CopyValue(const glTF2::vec4& v, aiColor4D& out) static void CopyValue(const glTF2::vec4& v, aiColor4D& out)
{ {
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3]; out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
} }*/
/*static void CopyValue(const glTF2::vec4& v, aiColor3D& out) /*static void CopyValue(const glTF2::vec4& v, aiColor3D& out)
{ {
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.r = v[0]; out.g = v[1]; out.b = v[2];
}*/ }*/
static void CopyValue(const glTF2::vec3& v, aiColor4D& out) /*static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
{ {
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = 1.0; out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = 1.0;
} }
@ -168,15 +170,15 @@ static void CopyValue(const glTF2::vec3& v, aiVector3D& out)
static void CopyValue(const glTF2::vec4& v, aiQuaternion& out) static void CopyValue(const glTF2::vec4& v, aiQuaternion& out)
{ {
out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3]; out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
} }*/
static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o) /*static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
{ {
o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3]; o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7]; o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11]; o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15]; o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
} }*/
inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx) inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
{ {
@ -188,7 +190,7 @@ inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat,
inline void SetMaterialColorProperty(Asset& /*r*/, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx) inline void SetMaterialColorProperty(Asset& /*r*/, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
{ {
aiColor4D col; aiColor4D col;
CopyValue(prop, col); glTFCommon::CopyValue(prop, col);
mat->AddProperty(&col, 1, pKey, type, idx); mat->AddProperty(&col, 1, pKey, type, idx);
} }
@ -383,7 +385,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
aim->mName = mesh.name.empty() ? mesh.id : mesh.name; aim->mName = mesh.name.empty() ? mesh.id : mesh.name;
if (mesh.primitives.size() > 1) { if (mesh.primitives.size() > 1) {
size_t& len = aim->mName.length; ai_uint32& len = aim->mName.length;
aim->mName.data[len] = '-'; aim->mName.data[len] = '-';
len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p); len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
} }
@ -442,7 +444,6 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
"\" does not match the vertex count"); "\" does not match the vertex count");
continue; continue;
} }
aim->mColors[c] = new aiColor4D[attr.color[c]->count];
attr.color[c]->ExtractData(aim->mColors[c]); attr.color[c]->ExtractData(aim->mColors[c]);
} }
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) { for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
@ -700,12 +701,17 @@ void glTF2Importer::ImportCameras(glTF2::Asset& r)
if (cam.type == Camera::Perspective) { if (cam.type == Camera::Perspective) {
aicam->mAspect = cam.cameraProperties.perspective.aspectRatio; aicam->mAspect = cam.cameraProperties.perspective.aspectRatio;
aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * aicam->mAspect; aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect);
aicam->mClipPlaneFar = cam.cameraProperties.perspective.zfar; aicam->mClipPlaneFar = cam.cameraProperties.perspective.zfar;
aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear; aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear;
} else {
aicam->mClipPlaneFar = cam.cameraProperties.ortographic.zfar;
aicam->mClipPlaneNear = cam.cameraProperties.ortographic.znear;
aicam->mHorizontalFOV = 0.0;
aicam->mAspect = 1.0f;
if (0.f != cam.cameraProperties.ortographic.ymag ) {
aicam->mAspect = cam.cameraProperties.ortographic.xmag / cam.cameraProperties.ortographic.ymag;
} }
else {
// assimp does not support orthographic cameras
} }
} }
} }
@ -901,6 +907,9 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
std::vector<std::vector<aiVertexWeight>> weighting(mesh->mNumBones); std::vector<std::vector<aiVertexWeight>> weighting(mesh->mNumBones);
BuildVertexWeightMapping(node.meshes[0]->primitives[primitiveNo], weighting); BuildVertexWeightMapping(node.meshes[0]->primitives[primitiveNo], weighting);
mat4* pbindMatrices = nullptr;
node.skin->inverseBindMatrices->ExtractData(pbindMatrices);
for (uint32_t i = 0; i < mesh->mNumBones; ++i) { for (uint32_t i = 0; i < mesh->mNumBones; ++i) {
aiBone* bone = new aiBone(); aiBone* bone = new aiBone();
@ -916,6 +925,8 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
} }
GetNodeTransform(bone->mOffsetMatrix, *joint); GetNodeTransform(bone->mOffsetMatrix, *joint);
CopyValue(pbindMatrices[i], bone->mOffsetMatrix);
std::vector<aiVertexWeight>& weights = weighting[i]; std::vector<aiVertexWeight>& weights = weighting[i];
bone->mNumWeights = static_cast<uint32_t>(weights.size()); bone->mNumWeights = static_cast<uint32_t>(weights.size());
@ -931,6 +942,10 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
} }
mesh->mBones[i] = bone; mesh->mBones[i] = bone;
} }
if (pbindMatrices) {
delete[] pbindMatrices;
}
} }
} }
@ -987,11 +1002,18 @@ void glTF2Importer::ImportNodes(glTF2::Asset& r)
} }
struct AnimationSamplers { struct AnimationSamplers {
AnimationSamplers() : translation(nullptr), rotation(nullptr), scale(nullptr) {} AnimationSamplers()
: translation(nullptr)
, rotation(nullptr)
, scale(nullptr)
, weight(nullptr) {
// empty
}
Animation::Sampler* translation; Animation::Sampler* translation;
Animation::Sampler* rotation; Animation::Sampler* rotation;
Animation::Sampler* scale; Animation::Sampler* scale;
Animation::Sampler* weight;
}; };
aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& samplers) aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& samplers)
@ -1016,7 +1038,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
delete[] values; delete[] values;
} else if (node.translation.isPresent) { } else if (node.translation.isPresent) {
anim->mNumPositionKeys = 1; anim->mNumPositionKeys = 1;
anim->mPositionKeys = new aiVectorKey(); anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
anim->mPositionKeys->mTime = 0.f; anim->mPositionKeys->mTime = 0.f;
anim->mPositionKeys->mValue.x = node.translation.value[0]; anim->mPositionKeys->mValue.x = node.translation.value[0];
anim->mPositionKeys->mValue.y = node.translation.value[1]; anim->mPositionKeys->mValue.y = node.translation.value[1];
@ -1041,7 +1063,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
delete[] values; delete[] values;
} else if (node.rotation.isPresent) { } else if (node.rotation.isPresent) {
anim->mNumRotationKeys = 1; anim->mNumRotationKeys = 1;
anim->mRotationKeys = new aiQuatKey(); anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys];
anim->mRotationKeys->mTime = 0.f; anim->mRotationKeys->mTime = 0.f;
anim->mRotationKeys->mValue.x = node.rotation.value[0]; anim->mRotationKeys->mValue.x = node.rotation.value[0];
anim->mRotationKeys->mValue.y = node.rotation.value[1]; anim->mRotationKeys->mValue.y = node.rotation.value[1];
@ -1064,7 +1086,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
delete[] values; delete[] values;
} else if (node.scale.isPresent) { } else if (node.scale.isPresent) {
anim->mNumScalingKeys = 1; anim->mNumScalingKeys = 1;
anim->mScalingKeys = new aiVectorKey(); anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys];
anim->mScalingKeys->mTime = 0.f; anim->mScalingKeys->mTime = 0.f;
anim->mScalingKeys->mValue.x = node.scale.value[0]; anim->mScalingKeys->mValue.x = node.scale.value[0];
anim->mScalingKeys->mValue.y = node.scale.value[1]; anim->mScalingKeys->mValue.y = node.scale.value[1];
@ -1074,6 +1096,43 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
return anim; return anim;
} }
aiMeshMorphAnim* CreateMeshMorphAnim(glTF2::Asset& r, Node& node, AnimationSamplers& samplers)
{
aiMeshMorphAnim* anim = new aiMeshMorphAnim();
anim->mName = GetNodeName(node);
static const float kMillisecondsFromSeconds = 1000.f;
if (nullptr != samplers.weight) {
float* times = nullptr;
samplers.weight->input->ExtractData(times);
float* values = nullptr;
samplers.weight->output->ExtractData(values);
anim->mNumKeys = static_cast<uint32_t>(samplers.weight->input->count);
const unsigned int numMorphs = samplers.weight->output->count / anim->mNumKeys;
anim->mKeys = new aiMeshMorphKey[anim->mNumKeys];
unsigned int k = 0u;
for (unsigned int i = 0u; i < anim->mNumKeys; ++i) {
anim->mKeys[i].mTime = times[i] * kMillisecondsFromSeconds;
anim->mKeys[i].mNumValuesAndWeights = numMorphs;
anim->mKeys[i].mValues = new unsigned int[numMorphs];
anim->mKeys[i].mWeights = new double[numMorphs];
for (unsigned int j = 0u; j < numMorphs; ++j, ++k) {
anim->mKeys[i].mValues[j] = j;
anim->mKeys[i].mWeights[j] = ( 0.f > values[k] ) ? 0.f : values[k];
}
}
delete[] times;
delete[] values;
}
return anim;
}
std::unordered_map<unsigned int, AnimationSamplers> GatherSamplers(Animation& anim) std::unordered_map<unsigned int, AnimationSamplers> GatherSamplers(Animation& anim)
{ {
std::unordered_map<unsigned int, AnimationSamplers> samplers; std::unordered_map<unsigned int, AnimationSamplers> samplers;
@ -1092,6 +1151,8 @@ std::unordered_map<unsigned int, AnimationSamplers> GatherSamplers(Animation& an
sampler.rotation = &anim.samplers[channel.sampler]; sampler.rotation = &anim.samplers[channel.sampler];
} else if (channel.target.path == AnimationPath_SCALE) { } else if (channel.target.path == AnimationPath_SCALE) {
sampler.scale = &anim.samplers[channel.sampler]; sampler.scale = &anim.samplers[channel.sampler];
} else if (channel.target.path == AnimationPath_WEIGHTS) {
sampler.weight = &anim.samplers[channel.sampler];
} }
} }
@ -1118,18 +1179,45 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r)
std::unordered_map<unsigned int, AnimationSamplers> samplers = GatherSamplers(anim); std::unordered_map<unsigned int, AnimationSamplers> samplers = GatherSamplers(anim);
ai_anim->mNumChannels = static_cast<uint32_t>(samplers.size()); uint32_t numChannels = 0u;
uint32_t numMorphMeshChannels = 0u;
for (auto& iter : samplers) {
if ((nullptr != iter.second.rotation) || (nullptr != iter.second.scale) || (nullptr != iter.second.translation)) {
++numChannels;
}
if (nullptr != iter.second.weight) {
++numMorphMeshChannels;
}
}
ai_anim->mNumChannels = numChannels;
if (ai_anim->mNumChannels > 0) { if (ai_anim->mNumChannels > 0) {
ai_anim->mChannels = new aiNodeAnim*[ai_anim->mNumChannels]; ai_anim->mChannels = new aiNodeAnim*[ai_anim->mNumChannels];
int j = 0; int j = 0;
for (auto& iter : samplers) { for (auto& iter : samplers) {
if ((nullptr != iter.second.rotation) || (nullptr != iter.second.scale) || (nullptr != iter.second.translation)) {
ai_anim->mChannels[j] = CreateNodeAnim(r, r.nodes[iter.first], iter.second); ai_anim->mChannels[j] = CreateNodeAnim(r, r.nodes[iter.first], iter.second);
++j; ++j;
} }
} }
}
ai_anim->mNumMorphMeshChannels = numMorphMeshChannels;
if (ai_anim->mNumMorphMeshChannels > 0) {
ai_anim->mMorphMeshChannels = new aiMeshMorphAnim*[ai_anim->mNumMorphMeshChannels];
int j = 0;
for (auto& iter : samplers) {
if (nullptr != iter.second.weight) {
ai_anim->mMorphMeshChannels[j] = CreateMeshMorphAnim(r, r.nodes[iter.first], iter.second);
++j;
}
}
}
// Use the latest keyframe for the duration of the animation // Use the latest keyframe for the duration of the animation
double maxDuration = 0; double maxDuration = 0;
unsigned int maxNumberOfKeys = 0;
for (unsigned int j = 0; j < ai_anim->mNumChannels; ++j) { for (unsigned int j = 0; j < ai_anim->mNumChannels; ++j) {
auto chan = ai_anim->mChannels[j]; auto chan = ai_anim->mChannels[j];
if (chan->mNumPositionKeys) { if (chan->mNumPositionKeys) {
@ -1137,21 +1225,38 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r)
if (lastPosKey.mTime > maxDuration) { if (lastPosKey.mTime > maxDuration) {
maxDuration = lastPosKey.mTime; maxDuration = lastPosKey.mTime;
} }
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumPositionKeys);
} }
if (chan->mNumRotationKeys) { if (chan->mNumRotationKeys) {
auto lastRotKey = chan->mRotationKeys[chan->mNumRotationKeys - 1]; auto lastRotKey = chan->mRotationKeys[chan->mNumRotationKeys - 1];
if (lastRotKey.mTime > maxDuration) { if (lastRotKey.mTime > maxDuration) {
maxDuration = lastRotKey.mTime; maxDuration = lastRotKey.mTime;
} }
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumRotationKeys);
} }
if (chan->mNumScalingKeys) { if (chan->mNumScalingKeys) {
auto lastScaleKey = chan->mScalingKeys[chan->mNumScalingKeys - 1]; auto lastScaleKey = chan->mScalingKeys[chan->mNumScalingKeys - 1];
if (lastScaleKey.mTime > maxDuration) { if (lastScaleKey.mTime > maxDuration) {
maxDuration = lastScaleKey.mTime; maxDuration = lastScaleKey.mTime;
} }
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumScalingKeys);
} }
} }
for (unsigned int j = 0; j < ai_anim->mNumMorphMeshChannels; ++j) {
const auto* const chan = ai_anim->mMorphMeshChannels[j];
if (0u != chan->mNumKeys) {
const auto& lastKey = chan->mKeys[chan->mNumKeys - 1u];
if (lastKey.mTime > maxDuration) {
maxDuration = lastKey.mTime;
}
maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumKeys);
}
}
ai_anim->mDuration = maxDuration; ai_anim->mDuration = maxDuration;
ai_anim->mTicksPerSecond = 1000.0;
mScene->mAnimations[i] = ai_anim; mScene->mAnimations[i] = ai_anim;
} }

View File

@ -141,7 +141,7 @@ void VerifyGenerator(const ParamGenerator<T>& generator,
<< ", expected_values[i] is " << PrintValue(expected_values[i]) << ", expected_values[i] is " << PrintValue(expected_values[i])
<< ", *it is " << PrintValue(*it) << ", *it is " << PrintValue(*it)
<< ", and 'it' is an iterator created with the copy constructor.\n"; << ", and 'it' is an iterator created with the copy constructor.\n";
it++; ++it;
} }
EXPECT_TRUE(it == generator.end()) EXPECT_TRUE(it == generator.end())
<< "At the presumed end of sequence when accessing via an iterator " << "At the presumed end of sequence when accessing via an iterator "
@ -161,7 +161,7 @@ void VerifyGenerator(const ParamGenerator<T>& generator,
<< ", expected_values[i] is " << PrintValue(expected_values[i]) << ", expected_values[i] is " << PrintValue(expected_values[i])
<< ", *it is " << PrintValue(*it) << ", *it is " << PrintValue(*it)
<< ", and 'it' is an iterator created with the copy constructor.\n"; << ", and 'it' is an iterator created with the copy constructor.\n";
it++; ++it;
} }
EXPECT_TRUE(it == generator.end()) EXPECT_TRUE(it == generator.end())
<< "At the presumed end of sequence when accessing via an iterator " << "At the presumed end of sequence when accessing via an iterator "
@ -196,7 +196,7 @@ TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) {
<< "element same as its source points to"; << "element same as its source points to";
// Verifies that iterator assignment works as expected. // Verifies that iterator assignment works as expected.
it++; ++it;
EXPECT_FALSE(*it == *it2); EXPECT_FALSE(*it == *it2);
it2 = it; it2 = it;
EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the " EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the "
@ -215,7 +215,7 @@ TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) {
// Verifies that prefix and postfix operator++() advance an iterator // Verifies that prefix and postfix operator++() advance an iterator
// all the same. // all the same.
it2 = it; it2 = it;
it++; ++it;
++it2; ++it2;
EXPECT_TRUE(*it == *it2); EXPECT_TRUE(*it == *it2);
} }

View File

@ -215,7 +215,7 @@ namespace io
two methods to read your data and give a pointer to an instance of two methods to read your data and give a pointer to an instance of
your implementation when calling createIrrXMLReader(), your implementation when calling createIrrXMLReader(),
createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */ createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */
class IFileReadCallBack class IRRXML_API IFileReadCallBack
{ {
public: public:

View File

@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file Definition of the base class for all importer worker classes. */ /** @file Definition of the base class for all importer worker classes. */
#pragma once
#ifndef INCLUDED_AI_BASEIMPORTER_H #ifndef INCLUDED_AI_BASEIMPORTER_H
#define INCLUDED_AI_BASEIMPORTER_H #define INCLUDED_AI_BASEIMPORTER_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include "Exceptional.h" #include "Exceptional.h"
#include <vector> #include <vector>
@ -82,6 +87,10 @@ class IOStream;
class ASSIMP_API BaseImporter { class ASSIMP_API BaseImporter {
friend class Importer; friend class Importer;
private:
/* Pushes state into importer for the importer scale */
virtual void UpdateImporterScale( Importer* pImp );
public: public:
/** Constructor to be privately used by #Importer */ /** Constructor to be privately used by #Importer */
@ -134,7 +143,7 @@ public:
* a suitable response to the caller. * a suitable response to the caller.
*/ */
aiScene* ReadFile( aiScene* ReadFile(
const Importer* pImp, Importer* pImp,
const std::string& pFile, const std::string& pFile,
IOSystem* pIOHandler IOSystem* pIOHandler
); );
@ -209,14 +218,6 @@ public:
return applicationUnits; return applicationUnits;
} }
/* Returns scale used by application called by ScaleProcess */
double GetImporterScale() const
{
ai_assert(importerScale != 0);
ai_assert(fileScale != 0);
return importerScale * fileScale;
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called by #Importer::GetExtensionList for each loaded importer. /** Called by #Importer::GetExtensionList for each loaded importer.
* Take the extension list contained in the structure returned by * Take the extension list contained in the structure returned by
@ -230,6 +231,7 @@ protected:
double fileScale = 1.0; double fileScale = 1.0;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. The /** Imports the given file into the given scene structure. The
* function is expected to throw an ImportErrorException if there is * function is expected to throw an ImportErrorException if there is

View File

@ -46,10 +46,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* Used for file formats which embed their textures into the model file. * Used for file formats which embed their textures into the model file.
*/ */
#pragma once
#ifndef AI_BITMAP_H_INC #ifndef AI_BITMAP_H_INC
#define AI_BITMAP_H_INC #define AI_BITMAP_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include "defs.h" #include "defs.h"
#include <stdint.h> #include <stdint.h>
#include <cstddef> #include <cstddef>

View File

@ -42,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Helper class tp perform various byte oder swappings /** @file Helper class tp perform various byte oder swappings
(e.g. little to big endian) */ (e.g. little to big endian) */
#pragma once
#ifndef AI_BYTESWAPPER_H_INC #ifndef AI_BYTESWAPPER_H_INC
#define AI_BYTESWAPPER_H_INC #define AI_BYTESWAPPER_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/types.h> #include <assimp/types.h>
#include <stdint.h> #include <stdint.h>

View File

@ -43,16 +43,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file CreateAnimMesh.h /** @file CreateAnimMesh.h
* Create AnimMesh from Mesh * Create AnimMesh from Mesh
*/ */
#pragma once
#ifndef INCLUDED_AI_CREATE_ANIM_MESH_H #ifndef INCLUDED_AI_CREATE_ANIM_MESH_H
#define INCLUDED_AI_CREATE_ANIM_MESH_H #define INCLUDED_AI_CREATE_ANIM_MESH_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/mesh.h> #include <assimp/mesh.h>
namespace Assimp { namespace Assimp {
/** Create aiAnimMesh from aiMesh. */ /**
* Create aiAnimMesh from aiMesh.
* @param mesh The input mesh to create an animated mesh from.
* @return The new created animated mesh.
*/
ASSIMP_API aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh); ASSIMP_API aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh);
} // end of namespace Assimp } // end of namespace Assimp
#endif // INCLUDED_AI_CREATE_ANIM_MESH_H #endif // INCLUDED_AI_CREATE_ANIM_MESH_H

View File

@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file Default file I/O using fXXX()-family of functions */ /** @file Default file I/O using fXXX()-family of functions */
#pragma once
#ifndef AI_DEFAULTIOSTREAM_H_INC #ifndef AI_DEFAULTIOSTREAM_H_INC
#define AI_DEFAULTIOSTREAM_H_INC #define AI_DEFAULTIOSTREAM_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <stdio.h> #include <stdio.h>
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
@ -57,8 +62,7 @@ namespace Assimp {
//! @note An instance of this class can exist without a valid file handle //! @note An instance of this class can exist without a valid file handle
//! attached to it. All calls fail, but the instance can nevertheless be //! attached to it. All calls fail, but the instance can nevertheless be
//! used with no restrictions. //! used with no restrictions.
class ASSIMP_API DefaultIOStream : public IOStream class ASSIMP_API DefaultIOStream : public IOStream {
{
friend class DefaultIOSystem; friend class DefaultIOSystem;
#if __ANDROID__ #if __ANDROID__
# if __ANDROID_API__ > 9 # if __ANDROID_API__ > 9
@ -82,7 +86,6 @@ public:
size_t pSize, size_t pSize,
size_t pCount); size_t pCount);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Write to stream /// Write to stream
size_t Write(const void* pvBuffer, size_t Write(const void* pvBuffer,
@ -107,16 +110,13 @@ public:
void Flush(); void Flush();
private: private:
// File data-structure, using clib
FILE* mFile; FILE* mFile;
// Filename
std::string mFilename; std::string mFilename;
// Cached file size
mutable size_t mCachedSize; mutable size_t mCachedSize;
}; };
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
inline AI_FORCE_INLINE
DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
: mFile(nullptr) : mFile(nullptr)
, mFilename("") , mFilename("")
@ -125,7 +125,7 @@ DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
inline AI_FORCE_INLINE
DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename) DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
: mFile(pFile) : mFile(pFile)
, mFilename(strFilename) , mFilename(strFilename)
@ -137,4 +137,3 @@ DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
} // ns assimp } // ns assimp
#endif //!!AI_DEFAULTIOSTREAM_H_INC #endif //!!AI_DEFAULTIOSTREAM_H_INC

View File

@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file Default implementation of IOSystem using the standard C file functions */ /** @file Default implementation of IOSystem using the standard C file functions */
#pragma once
#ifndef AI_DEFAULTIOSYSTEM_H_INC #ifndef AI_DEFAULTIOSYSTEM_H_INC
#define AI_DEFAULTIOSYSTEM_H_INC #define AI_DEFAULTIOSYSTEM_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
namespace Assimp { namespace Assimp {

View File

@ -38,6 +38,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#pragma once
#ifndef AI_DEFINES_H_INC
#define AI_DEFINES_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
// We need those constants, workaround for any platforms where nobody defined them yet // We need those constants, workaround for any platforms where nobody defined them yet
#if (!defined SIZE_MAX) #if (!defined SIZE_MAX)
# define SIZE_MAX (~((size_t)0)) # define SIZE_MAX (~((size_t)0))
@ -47,3 +55,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# define UINT_MAX (~((unsigned int)0)) # define UINT_MAX (~((unsigned int)0))
#endif #endif
#endif // AI_DEINES_H_INC

View File

@ -38,11 +38,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#ifndef INCLUDED_EXCEPTIONAL_H #pragma once
#define INCLUDED_EXCEPTIONAL_H #ifndef AI_INCLUDED_EXCEPTIONAL_H
#define AI_INCLUDED_EXCEPTIONAL_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <stdexcept> #include <stdexcept>
#include <assimp/DefaultIOStream.h> #include <assimp/DefaultIOStream.h>
using std::runtime_error; using std::runtime_error;
#ifdef _MSC_VER #ifdef _MSC_VER
@ -53,17 +59,14 @@ using std::runtime_error;
/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an /** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an
* unrecoverable error occurs while importing. Loading APIs return * unrecoverable error occurs while importing. Loading APIs return
* NULL instead of a valid aiScene then. */ * NULL instead of a valid aiScene then. */
class DeadlyImportError class DeadlyImportError : public runtime_error {
: public runtime_error
{
public: public:
/** Constructor with arguments */ /** Constructor with arguments */
explicit DeadlyImportError( const std::string& errorText) explicit DeadlyImportError( const std::string& errorText)
: runtime_error(errorText) : runtime_error(errorText) {
{ // empty
} }
private:
}; };
typedef DeadlyImportError DeadlyExportError; typedef DeadlyImportError DeadlyExportError;
@ -84,7 +87,7 @@ struct ExceptionSwallower {
template <typename T> template <typename T>
struct ExceptionSwallower<T*> { struct ExceptionSwallower<T*> {
T* operator ()() const { T* operator ()() const {
return NULL; return nullptr;
} }
}; };
@ -122,4 +125,4 @@ struct ExceptionSwallower<void> {
}\ }\
} }
#endif // INCLUDED_EXCEPTIONAL_H #endif // AI_INCLUDED_EXCEPTIONAL_H

View File

@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_EXPORT_HPP_INC #ifndef AI_EXPORT_HPP_INC
#define AI_EXPORT_HPP_INC #define AI_EXPORT_HPP_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_EXPORT
#include "cexport.h" #include "cexport.h"

View File

@ -40,12 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#pragma once
#ifndef AI_GENERIC_PROPERTY_H_INCLUDED #ifndef AI_GENERIC_PROPERTY_H_INCLUDED
#define AI_GENERIC_PROPERTY_H_INCLUDED #define AI_GENERIC_PROPERTY_H_INCLUDED
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include "Hash.h" #include <assimp/Hash.h>
#include <map> #include <map>

View File

@ -39,10 +39,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#pragma once
#ifndef AI_HASH_H_INCLUDED #ifndef AI_HASH_H_INCLUDED
#define AI_HASH_H_INCLUDED #define AI_HASH_H_INCLUDED
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>

View File

@ -48,7 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IOSTREAM_H_INC #ifndef AI_IOSTREAM_H_INC
#define AI_IOSTREAM_H_INC #define AI_IOSTREAM_H_INC
#include "types.h" #ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/types.h>
#ifndef __cplusplus #ifndef __cplusplus
# error This header requires C++ to be used. aiFileIO.h is the \ # error This header requires C++ to be used. aiFileIO.h is the \
@ -125,13 +129,13 @@ public:
}; //! class IOStream }; //! class IOStream
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
inline AI_FORCE_INLINE
IOStream::IOStream() AI_NO_EXCEPT { IOStream::IOStream() AI_NO_EXCEPT {
// empty // empty
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
inline AI_FORCE_INLINE
IOStream::~IOStream() { IOStream::~IOStream() {
// empty // empty
} }

View File

@ -1,5 +1,3 @@
#pragma once
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -42,10 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#pragma once
#ifndef AI_IOSTREAMBUFFER_H_INC
#define AI_IOSTREAMBUFFER_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/types.h> #include <assimp/types.h>
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include <assimp/ParsingUtils.h>
#include "ParsingUtils.h"
#include <vector> #include <vector>
@ -124,7 +129,7 @@ private:
}; };
template<class T> template<class T>
inline AI_FORCE_INLINE
IOStreamBuffer<T>::IOStreamBuffer( size_t cache ) IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
: m_stream( nullptr ) : m_stream( nullptr )
, m_filesize( 0 ) , m_filesize( 0 )
@ -138,13 +143,13 @@ IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
IOStreamBuffer<T>::~IOStreamBuffer() { IOStreamBuffer<T>::~IOStreamBuffer() {
// empty // empty
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
bool IOStreamBuffer<T>::open( IOStream *stream ) { bool IOStreamBuffer<T>::open( IOStream *stream ) {
// file still opened! // file still opened!
if ( nullptr != m_stream ) { if ( nullptr != m_stream ) {
@ -174,7 +179,7 @@ bool IOStreamBuffer<T>::open( IOStream *stream ) {
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
bool IOStreamBuffer<T>::close() { bool IOStreamBuffer<T>::close() {
if ( nullptr == m_stream ) { if ( nullptr == m_stream ) {
return false; return false;
@ -192,19 +197,19 @@ bool IOStreamBuffer<T>::close() {
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
size_t IOStreamBuffer<T>::size() const { size_t IOStreamBuffer<T>::size() const {
return m_filesize; return m_filesize;
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
size_t IOStreamBuffer<T>::cacheSize() const { size_t IOStreamBuffer<T>::cacheSize() const {
return m_cacheSize; return m_cacheSize;
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
bool IOStreamBuffer<T>::readNextBlock() { bool IOStreamBuffer<T>::readNextBlock() {
m_stream->Seek( m_filePos, aiOrigin_SET ); m_stream->Seek( m_filePos, aiOrigin_SET );
size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize ); size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize );
@ -222,25 +227,25 @@ bool IOStreamBuffer<T>::readNextBlock() {
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getNumBlocks() const { size_t IOStreamBuffer<T>::getNumBlocks() const {
return m_numBlocks; return m_numBlocks;
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getCurrentBlockIndex() const { size_t IOStreamBuffer<T>::getCurrentBlockIndex() const {
return m_blockIdx; return m_blockIdx;
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getFilePos() const { size_t IOStreamBuffer<T>::getFilePos() const {
return m_filePos; return m_filePos;
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) { bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
buffer.resize( m_cacheSize ); buffer.resize( m_cacheSize );
if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) { if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) {
@ -289,13 +294,13 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT
return true; return true;
} }
static inline static AI_FORCE_INLINE
bool isEndOfCache( size_t pos, size_t cacheSize ) { bool isEndOfCache( size_t pos, size_t cacheSize ) {
return ( pos == cacheSize ); return ( pos == cacheSize );
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) { bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
buffer.resize(m_cacheSize); buffer.resize(m_cacheSize);
if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) { if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) {
@ -335,7 +340,7 @@ bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
} }
template<class T> template<class T>
inline AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) { bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
// Return the last block-value if getNextLine was used before // Return the last block-value if getNextLine was used before
if ( 0 != m_cachePos ) { if ( 0 != m_cachePos ) {
@ -353,3 +358,5 @@ bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
} }
} // !ns Assimp } // !ns Assimp
#endif // AI_IOSTREAMBUFFER_H_INC

View File

@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IOSYSTEM_H_INC #ifndef AI_IOSYSTEM_H_INC
#define AI_IOSYSTEM_H_INC #define AI_IOSYSTEM_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#ifndef __cplusplus #ifndef __cplusplus
# error This header requires C++ to be used. aiFileIO.h is the \ # error This header requires C++ to be used. aiFileIO.h is the \
corresponding C interface. corresponding C interface.

View File

@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASSIMP_HPP_INC #ifndef AI_ASSIMP_HPP_INC
#define AI_ASSIMP_HPP_INC #define AI_ASSIMP_HPP_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#ifndef __cplusplus #ifndef __cplusplus
# error This header requires C++ to be used. Use assimp.h for plain C. # error This header requires C++ to be used. Use assimp.h for plain C.
#endif // __cplusplus #endif // __cplusplus

View File

@ -48,9 +48,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_LINE_SPLITTER_H #ifndef INCLUDED_LINE_SPLITTER_H
#define INCLUDED_LINE_SPLITTER_H #define INCLUDED_LINE_SPLITTER_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <stdexcept> #include <stdexcept>
#include "StreamReader.h" #include <assimp/StreamReader.h>
#include "ParsingUtils.h" #include <assimp/ParsingUtils.h>
namespace Assimp { namespace Assimp {
@ -140,7 +144,7 @@ private:
bool mSwallow, mSkip_empty_lines, mTrim; bool mSwallow, mSkip_empty_lines, mTrim;
}; };
inline AI_FORCE_INLINE
LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim ) LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim )
: mIdx(0) : mIdx(0)
, mCur() , mCur()
@ -153,12 +157,12 @@ LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool t
mIdx = 0; mIdx = 0;
} }
inline AI_FORCE_INLINE
LineSplitter::~LineSplitter() { LineSplitter::~LineSplitter() {
// empty // empty
} }
inline AI_FORCE_INLINE
LineSplitter& LineSplitter::operator++() { LineSplitter& LineSplitter::operator++() {
if (mSwallow) { if (mSwallow) {
mSwallow = false; mSwallow = false;
@ -199,12 +203,12 @@ LineSplitter& LineSplitter::operator++() {
return *this; return *this;
} }
inline AI_FORCE_INLINE
LineSplitter &LineSplitter::operator++(int) { LineSplitter &LineSplitter::operator++(int) {
return ++(*this); return ++(*this);
} }
inline AI_FORCE_INLINE
const char *LineSplitter::operator[] (size_t idx) const { const char *LineSplitter::operator[] (size_t idx) const {
const char* s = operator->()->c_str(); const char* s = operator->()->c_str();
@ -222,7 +226,7 @@ const char *LineSplitter::operator[] (size_t idx) const {
} }
template <size_t N> template <size_t N>
inline AI_FORCE_INLINE
void LineSplitter::get_tokens(const char* (&tokens)[N]) const { void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
const char* s = operator->()->c_str(); const char* s = operator->()->c_str();
@ -238,44 +242,44 @@ void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
} }
} }
inline AI_FORCE_INLINE
const std::string* LineSplitter::operator -> () const { const std::string* LineSplitter::operator -> () const {
return &mCur; return &mCur;
} }
inline AI_FORCE_INLINE
std::string LineSplitter::operator* () const { std::string LineSplitter::operator* () const {
return mCur; return mCur;
} }
inline AI_FORCE_INLINE
LineSplitter::operator bool() const { LineSplitter::operator bool() const {
return mStream.GetRemainingSize() > 0; return mStream.GetRemainingSize() > 0;
} }
inline AI_FORCE_INLINE
LineSplitter::operator line_idx() const { LineSplitter::operator line_idx() const {
return mIdx; return mIdx;
} }
inline AI_FORCE_INLINE
LineSplitter::line_idx LineSplitter::get_index() const { LineSplitter::line_idx LineSplitter::get_index() const {
return mIdx; return mIdx;
} }
inline AI_FORCE_INLINE
StreamReaderLE &LineSplitter::get_stream() { StreamReaderLE &LineSplitter::get_stream() {
return mStream; return mStream;
} }
inline AI_FORCE_INLINE
bool LineSplitter::match_start(const char* check) { bool LineSplitter::match_start(const char* check) {
const size_t len = ::strlen(check); const size_t len = ::strlen(check);
return len <= mCur.length() && std::equal(check, check + len, mCur.begin()); return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
} }
inline AI_FORCE_INLINE
void LineSplitter::swallow_next_increment() { void LineSplitter::swallow_next_increment() {
mSwallow = true; mSwallow = true;
} }

View File

@ -43,9 +43,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file LogAux.h /** @file LogAux.h
* @brief Common logging usage patterns for importer implementations * @brief Common logging usage patterns for importer implementations
*/ */
#pragma once
#ifndef INCLUDED_AI_LOGAUX_H #ifndef INCLUDED_AI_LOGAUX_H
#define INCLUDED_AI_LOGAUX_H #define INCLUDED_AI_LOGAUX_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>

View File

@ -1,49 +0,0 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2019, 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.
---------------------------------------------------------------------------
*/
/* Helper macro to set a pointer to NULL in debug builds
*/
#if (defined ASSIMP_BUILD_DEBUG)
# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
#else
# define AI_DEBUG_INVALIDATE_PTR(x)
#endif

View File

@ -39,22 +39,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
#pragma once
#ifdef __GNUC__
# pragma GCC system_header
#endif
/** @file MathFunctions.h /** @file MathFunctions.h
* @brief Implementation of the math functions (gcd and lcm) * @brief Implementation of math utility functions.
* *
* Copied from BoostWorkaround/math */
*/
#include <limits>
namespace Assimp { namespace Assimp {
namespace Math { namespace Math {
// TODO: use binary GCD for unsigned integers .... // TODO: use binary GCD for unsigned integers ....
template < typename IntegerType > template < typename IntegerType >
IntegerType gcd( IntegerType a, IntegerType b ) inline
{ IntegerType gcd( IntegerType a, IntegerType b ) {
const IntegerType zero = (IntegerType)0; const IntegerType zero = (IntegerType)0;
while ( true ) while ( true ) {
{
if ( a == zero ) if ( a == zero )
return b; return b;
b %= a; b %= a;
@ -66,12 +72,19 @@ IntegerType gcd( IntegerType a, IntegerType b )
} }
template < typename IntegerType > template < typename IntegerType >
IntegerType lcm( IntegerType a, IntegerType b ) inline
{ IntegerType lcm( IntegerType a, IntegerType b ) {
const IntegerType t = gcd (a,b); const IntegerType t = gcd (a,b);
if (!t)return t; if (!t)
return t;
return a / t * b; return a / t * b;
} }
template<class T>
inline
T getEpsilon() {
return std::numeric_limits<T>::epsilon();
}
} }
} }

View File

@ -42,12 +42,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file MemoryIOWrapper.h /** @file MemoryIOWrapper.h
* Handy IOStream/IOSystem implemetation to read directly from a memory buffer */ * Handy IOStream/IOSystem implemetation to read directly from a memory buffer */
#pragma once
#ifndef AI_MEMORYIOSTREAM_H_INC #ifndef AI_MEMORYIOSTREAM_H_INC
#define AI_MEMORYIOSTREAM_H_INC #define AI_MEMORYIOSTREAM_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <stdint.h> #include <stdint.h>
namespace Assimp { namespace Assimp {

View File

@ -44,11 +44,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file ParsingUtils.h /** @file ParsingUtils.h
* @brief Defines helper functions for text parsing * @brief Defines helper functions for text parsing
*/ */
#pragma once
#ifndef AI_PARSING_UTILS_H_INC #ifndef AI_PARSING_UTILS_H_INC
#define AI_PARSING_UTILS_H_INC #define AI_PARSING_UTILS_H_INC
#include "StringComparison.h" #ifdef __GNUC__
#include "StringUtils.h" # pragma GCC system_header
#endif
#include <assimp/StringComparison.h>
#include <assimp/StringUtils.h>
#include <assimp/defs.h> #include <assimp/defs.h>
namespace Assimp { namespace Assimp {

View File

@ -43,12 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Profiler.h /** @file Profiler.h
* @brief Utility to measure the respective runtime of each import step * @brief Utility to measure the respective runtime of each import step
*/ */
#ifndef INCLUDED_PROFILER_H #pragma once
#define INCLUDED_PROFILER_H #ifndef AI_INCLUDED_PROFILER_H
#define AI_INCLUDED_PROFILER_H
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <chrono> #include <chrono>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include "TinyFormatter.h" #include <assimp/TinyFormatter.h>
#include <map> #include <map>
@ -67,7 +72,6 @@ public:
// empty // empty
} }
public:
/** Start a named timer */ /** Start a named timer */
void BeginRegion(const std::string& region) { void BeginRegion(const std::string& region) {
@ -95,5 +99,5 @@ private:
} }
} }
#endif #endif // AI_INCLUDED_PROFILER_H

View File

@ -47,7 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_PROGRESSHANDLER_H_INC #ifndef AI_PROGRESSHANDLER_H_INC
#define AI_PROGRESSHANDLER_H_INC #define AI_PROGRESSHANDLER_H_INC
#include "types.h" #ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/types.h>
namespace Assimp { namespace Assimp {

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team Copyright (c) 2006-2019, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -43,9 +42,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Declares a helper class, "CommentRemover", which can be /** @file Declares a helper class, "CommentRemover", which can be
* used to remove comments (single and multi line) from a text file. * used to remove comments (single and multi line) from a text file.
*/ */
#pragma once
#ifndef AI_REMOVE_COMMENTS_H_INC #ifndef AI_REMOVE_COMMENTS_H_INC
#define AI_REMOVE_COMMENTS_H_INC #define AI_REMOVE_COMMENTS_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/defs.h> #include <assimp/defs.h>
@ -58,8 +61,7 @@ namespace Assimp {
* to those in C or C++ so this code has been moved to a separate * to those in C or C++ so this code has been moved to a separate
* module. * module.
*/ */
class ASSIMP_API CommentRemover class ASSIMP_API CommentRemover {
{
// class cannot be instanced // class cannot be instanced
CommentRemover() {} CommentRemover() {}

View File

@ -42,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** Small helper classes to optimize finding vertices close to a given location /** Small helper classes to optimize finding vertices close to a given location
*/ */
#pragma once
#ifndef AI_D3DSSPATIALSORT_H_INC #ifndef AI_D3DSSPATIALSORT_H_INC
#define AI_D3DSSPATIALSORT_H_INC #define AI_D3DSSPATIALSORT_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/types.h> #include <assimp/types.h>
#include <vector> #include <vector>
#include <stdint.h> #include <stdint.h>

View File

@ -43,17 +43,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Declares a helper class, "SceneCombiner" providing various /** @file Declares a helper class, "SceneCombiner" providing various
* utilities to merge scenes. * utilities to merge scenes.
*/ */
#pragma once
#ifndef AI_SCENE_COMBINER_H_INC #ifndef AI_SCENE_COMBINER_H_INC
#define AI_SCENE_COMBINER_H_INC #define AI_SCENE_COMBINER_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/types.h> #include <assimp/types.h>
#include <assimp/Defines.h> #include <assimp/Defines.h>
#include <stddef.h> #include <stddef.h>
#include <set> #include <set>
#include <list> #include <list>
#include <stdint.h> #include <stdint.h>
#include <vector> #include <vector>
struct aiScene; struct aiScene;
@ -65,8 +70,10 @@ struct aiLight;
struct aiMetadata; struct aiMetadata;
struct aiBone; struct aiBone;
struct aiMesh; struct aiMesh;
struct aiAnimMesh;
struct aiAnimation; struct aiAnimation;
struct aiNodeAnim; struct aiNodeAnim;
struct aiMeshMorphAnim;
namespace Assimp { namespace Assimp {
@ -363,6 +370,7 @@ public:
static void Copy (aiMesh** dest, const aiMesh* src); static void Copy (aiMesh** dest, const aiMesh* src);
// similar to Copy(): // similar to Copy():
static void Copy (aiAnimMesh** dest, const aiAnimMesh* src);
static void Copy (aiMaterial** dest, const aiMaterial* src); static void Copy (aiMaterial** dest, const aiMaterial* src);
static void Copy (aiTexture** dest, const aiTexture* src); static void Copy (aiTexture** dest, const aiTexture* src);
static void Copy (aiAnimation** dest, const aiAnimation* src); static void Copy (aiAnimation** dest, const aiAnimation* src);
@ -370,6 +378,7 @@ public:
static void Copy (aiBone** dest, const aiBone* src); static void Copy (aiBone** dest, const aiBone* src);
static void Copy (aiLight** dest, const aiLight* src); static void Copy (aiLight** dest, const aiLight* src);
static void Copy (aiNodeAnim** dest, const aiNodeAnim* src); static void Copy (aiNodeAnim** dest, const aiNodeAnim* src);
static void Copy (aiMeshMorphAnim** dest, const aiMeshMorphAnim* src);
static void Copy (aiMetadata** dest, const aiMetadata* src); static void Copy (aiMetadata** dest, const aiMetadata* src);
// recursive, of course // recursive, of course

View File

@ -47,9 +47,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* for animation skeletons. * for animation skeletons.
*/ */
#pragma once
#ifndef AI_SKELETONMESHBUILDER_H_INC #ifndef AI_SKELETONMESHBUILDER_H_INC
#define AI_SKELETONMESHBUILDER_H_INC #define AI_SKELETONMESHBUILDER_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <vector> #include <vector>
#include <assimp/mesh.h> #include <assimp/mesh.h>

View File

@ -43,10 +43,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines the helper data structures for importing 3DS files. /** @file Defines the helper data structures for importing 3DS files.
http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */ http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */
#pragma once
#ifndef AI_SMOOTHINGGROUPS_H_INC #ifndef AI_SMOOTHINGGROUPS_H_INC
#define AI_SMOOTHINGGROUPS_H_INC #define AI_SMOOTHINGGROUPS_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/vector3.h> #include <assimp/vector3.h>
#include <stdint.h> #include <stdint.h>
#include <vector> #include <vector>

View File

@ -41,13 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Generation of normal vectors basing on smoothing groups */ /** @file Generation of normal vectors basing on smoothing groups */
#pragma once
#ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED #ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED
#define AI_SMOOTHINGGROUPS_INL_INCLUDED #define AI_SMOOTHINGGROUPS_INL_INCLUDED
// internal headers #ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/SGSpatialSort.h> #include <assimp/SGSpatialSort.h>
// CRT header
#include <algorithm> #include <algorithm>
using namespace Assimp; using namespace Assimp;

View File

@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** Small helper classes to optimise finding vertizes close to a given location */ /** Small helper classes to optimise finding vertizes close to a given location */
#pragma once
#ifndef AI_SPATIALSORT_H_INC #ifndef AI_SPATIALSORT_H_INC
#define AI_SPATIALSORT_H_INC #define AI_SPATIALSORT_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <vector> #include <vector>
#include <assimp/types.h> #include <assimp/types.h>

View File

@ -41,11 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/** @file Declares a helper class, "StandardShapes" which generates /** @file Declares a helper class, "StandardShapes" which generates
* vertices for standard shapes, such as cylnders, cones, spheres .. * vertices for standard shapes, such as cylinders, cones, spheres ..
*/ */
#pragma once
#ifndef AI_STANDARD_SHAPES_H_INC #ifndef AI_STANDARD_SHAPES_H_INC
#define AI_STANDARD_SHAPES_H_INC #define AI_STANDARD_SHAPES_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/vector3.h> #include <assimp/vector3.h>
#include <vector> #include <vector>

View File

@ -44,15 +44,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines the StreamReader class which reads data from /** @file Defines the StreamReader class which reads data from
* a binary stream with a well-defined endianness. * a binary stream with a well-defined endianness.
*/ */
#pragma once
#ifndef AI_STREAMREADER_H_INCLUDED #ifndef AI_STREAMREADER_H_INCLUDED
#define AI_STREAMREADER_H_INCLUDED #define AI_STREAMREADER_H_INCLUDED
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include <assimp/Defines.h> #include <assimp/Defines.h>
#include <assimp/ByteSwapper.h>
#include <assimp/Exceptional.h>
#include "ByteSwapper.h"
#include "Exceptional.h"
#include <memory> #include <memory>
namespace Assimp { namespace Assimp {

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