Marco Di Benedetto 2018-12-19 17:27:17 +01:00
commit cf6dff0b93
252 changed files with 132321 additions and 17120 deletions

1
.gitignore vendored
View File

@ -21,6 +21,7 @@ revision.h
contrib/zlib/zconf.h contrib/zlib/zconf.h
contrib/zlib/zlib.pc contrib/zlib/zlib.pc
include/assimp/config.h include/assimp/config.h
unit.vcxproj.user
# CMake # CMake
CMakeCache.txt CMakeCache.txt

View File

@ -51,7 +51,8 @@ matrix:
env: ANALYZE=ON env: ANALYZE=ON
- os: linux - os: linux
compiler: gcc compiler: gcc
env: DISABLE_EXPORTERS=YES ENABLE_COVERALLS=ON # env: DISABLE_EXPORTERS=YES ENABLE_COVERALLS=ON
env: ENABLE_COVERALLS=ON
- os: linux - os: linux
compiler: gcc compiler: gcc
env: SHARED_BUILD=ON env: SHARED_BUILD=ON

View File

@ -1,21 +0,0 @@
# - Config file for the FooBar package
# It defines the following variables
# FOOBAR_INCLUDE_DIRS - include directories for FooBar
# FOOBAR_LIBRARIES - libraries to link against
# FOOBAR_EXECUTABLE - the bar executable
# Compute paths
get_filename_component(FOOBAR_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
if(EXISTS "${FOOBAR_CMAKE_DIR}/CMakeCache.txt")
# In build tree
include("${FOOBAR_CMAKE_DIR}/FooBarBuildTreeSettings.cmake")
else()
set(FOOBAR_INCLUDE_DIRS "${FOOBAR_CMAKE_DIR}/@CONF_REL_INCLUDE_DIR@")
endif()
# Our library dependencies (contains definitions for IMPORTED targets)
include("${FOOBAR_CMAKE_DIR}/FooBarLibraryDepends.cmake")
# These are IMPORTED targets created by FooBarLibraryDepends.cmake
set(FOOBAR_LIBRARIES foo)
set(FOOBAR_EXECUTABLE bar)

58
Build.md 100644
View File

@ -0,0 +1,58 @@
# 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
```
sudo apt-get install cmake
```
# Get the source
Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
```
git clone https://github.com/assimp/assimp.git
```
# Build instructions for Windows with Visual-Studio
First you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
```
> 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.
# Build instructions for Windows with UWP
See https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app
# Build instrcutions for Linux / Unix
Open a terminal and got to your repository. You can generate the makefiles and build the library via:
```
cmake CMakeLists.txt
make -j4
```
The option -j descripes the number of parallel processes for the build. In this case make will try to use 4 cores for the build.
If you want to use a IDE for linux you can try QTCreator for instance.
# CMake build options
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_FRAMEWORK ( default OFF, MacOnly)**: Build package as Mac OS X Framework bundle
- **ASSIMP_DOUBLE_PRECISION( default OFF )**: All data will be stored as double values.
- **ASSIMP_OPT_BUILD_PACKAGES ( default OFF)**: Set to ON to generate CPack configuration files and packaging targets
- **ASSIMP_ANDROID_JNIIOSYSTEM ( default OFF )**: Android JNI IOSystem support is active
- **ASSIMP_NO_EXPORT ( default OFF )**: Disable Assimp's export functionality
- **ASSIMP_BUILD_ZLIB ( default OFF )**: Build your own zlib
- **ASSIMP_BUILD_ASSIMP_TOOLS ( default ON )**: If the supplementary tools for Assimp are built in addition to the library.
- **ASSIMP_BUILD_SAMPLES ( default OFF )**: If the official samples are built as well (needs Glut).
- **ASSIMP_BUILD_TESTS ( default ON )**: If the test suite for Assimp is built in addition to the library.
- **ASSIMP_COVERALLS ( default OFF )**: Enable this to measure test coverage.
- **ASSIMP_WERROR( default OFF )**: Treat warnings as errors.
- **ASSIMP_ASAN ( default OFF )**: Enable AddressSanitizer.
- **ASSIMP_UBSAN ( default OFF )**: Enable Undefined Behavior sanitizer.
- **SYSTEM_IRRXML ( default OFF )**: Use system installed Irrlicht/IrrXML library.
- **BUILD_DOCS ( default OFF )**: Build documentation using Doxygen.
- **INJECT_DEBUG_POSTFIX( default ON )**: Inject debug postfix in .a/.so lib names
- **IGNORE_GIT_HASH ( default OFF )**: Don't call git to get the hash.
- **ASSIMP_INSTALL_PDB ( default ON )**: Install MSVC debug files.

View File

@ -105,11 +105,20 @@ OPTION ( BUILD_DOCS
"Build documentation using Doxygen." "Build documentation using Doxygen."
OFF OFF
) )
OPTION( INJECT_DEBUG_POSTFIX
"Inject debug postfix in .a/.so lib names"
ON
)
OPTION ( IGNORE_GIT_HASH
"Don't call git to get the hash."
OFF
)
IF (IOS) IF (IOS)
IF (NOT CMAKE_BUILD_TYPE) IF (NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Release") SET(CMAKE_BUILD_TYPE "Release")
ENDIF (NOT CMAKE_BUILD_TYPE) ENDIF (NOT CMAKE_BUILD_TYPE)
ENDIF (IOS) ENDIF (IOS)
# Use subset of Windows.h # Use subset of Windows.h
@ -149,23 +158,25 @@ SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used
# Enable C++1 globally # Enable C++1 globally
set_property( GLOBAL PROPERTY CXX_STANDARD 11 ) set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
# Get the current working branch IF(NOT IGNORE_GIT_HASH)
EXECUTE_PROCESS( # Get the current working branch
COMMAND git rev-parse --abbrev-ref HEAD EXECUTE_PROCESS(
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND git rev-parse --abbrev-ref HEAD
OUTPUT_VARIABLE GIT_BRANCH WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE GIT_BRANCH
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
) ERROR_QUIET
)
# Get the latest abbreviated commit hash of the working branch # Get the latest abbreviated commit hash of the working branch
EXECUTE_PROCESS( EXECUTE_PROCESS(
COMMAND git log -1 --format=%h --no-show-signature COMMAND git rev-parse --short=8 HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_HASH OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET ERROR_QUIET
) )
ENDIF()
IF(NOT GIT_COMMIT_HASH) IF(NOT GIT_COMMIT_HASH)
SET(GIT_COMMIT_HASH 0) SET(GIT_COMMIT_HASH 0)
@ -206,25 +217,23 @@ ENDIF( UNIX )
# Grouped compiler settings # Grouped compiler settings
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW) IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
# hide all not-exported symbols # hide all not-exported symbols
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -std=c++0x") SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fPIC -fno-strict-aliasing -Wall -std=c++0x ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS}")
SET(LIBSTDC++_LIBRARIES -lstdc++) SET(LIBSTDC++_LIBRARIES -lstdc++)
ELSEIF(MSVC) ELSEIF(MSVC)
# enable multi-core compilation with MSVC # enable multi-core compilation with MSVC
ADD_COMPILE_OPTIONS(/MP) ADD_COMPILE_OPTIONS(/MP)
IF("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)") ADD_COMPILE_OPTIONS( /bigobj )
ADD_COMPILE_OPTIONS( /bigobj )
ENDIF()
# disable "elements of array '' will be default initialized" warning on MSVC2013 # disable "elements of array '' will be default initialized" warning on MSVC2013
IF(MSVC12) IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351) ADD_COMPILE_OPTIONS(/wd4351)
ENDIF() ENDIF()
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" ) SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fPIC -fno-strict-aliasing -Wall -Wno-long-long -std=c++11 ${CMAKE_CXX_FLAGS}" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS}")
ELSEIF( CMAKE_COMPILER_IS_MINGW ) ELSEIF( CMAKE_COMPILER_IS_MINGW )
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11" ) SET( CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -std=c++11 -Wa,-mbig-obj ${CMAKE_CXX_FLAGS}" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing ${CMAKE_C_FLAGS} ")
ADD_DEFINITIONS( -U__STRICT_ANSI__ ) ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF() ENDIF()
@ -305,8 +314,18 @@ ENDIF()
# cmake configuration files # cmake configuration files
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE) CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets.cmake" @ONLY IMMEDIATE)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-debug.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake" @ONLY IMMEDIATE)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-release.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake" @ONLY IMMEDIATE)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE) CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT}) #we should generated these scripts after CMake VERSION 3.0.2 using export(EXPORT ...) and write_basic_package_version_file(...)
INSTALL(FILES
"${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/assimpTargets.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake"
DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
FIND_PACKAGE( DirectX ) FIND_PACKAGE( DirectX )

View File

@ -30,6 +30,8 @@ One-off donations via PayPal:
Please check our Wiki as well: https://github.com/assimp/assimp/wiki Please check our Wiki as well: https://github.com/assimp/assimp/wiki
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
#### Supported file formats #### #### Supported file formats ####
__Importers__: __Importers__:
@ -113,7 +115,7 @@ __Exporters__:
- FBX ( experimental ) - FBX ( experimental )
### Building ### ### Building ###
Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do. 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.
### Ports ### ### Ports ###
* [Android](port/AndroidJNI/README.md) * [Android](port/AndroidJNI/README.md)

View File

@ -1,59 +1 @@
# - Find Assimp Installation include(${CMAKE_CURRENT_LIST_DIR}/assimpTargets.cmake)
#
# Users can set the following variables before calling the module:
# ASSIMP_DIR - The preferred installation prefix for searching for ASSIMP. Set by the user.
#
# ASSIMP_ROOT_DIR - the root directory where the installation can be found
# ASSIMP_CXX_FLAGS - extra flags for compilation
# ASSIMP_LINK_FLAGS - extra flags for linking
# ASSIMP_INCLUDE_DIRS - include directories
# ASSIMP_LIBRARY_DIRS - link directories
# ASSIMP_LIBRARIES - libraries to link plugins with
# ASSIMP_Boost_VERSION - the boost version assimp was compiled with
get_filename_component(ASSIMP_ROOT_DIR "@CMAKE_INSTALL_PREFIX@" REALPATH)
if( MSVC )
# in order to prevent DLL hell, each of the DLLs have to be suffixed with the major version and msvc prefix
if( MSVC70 OR MSVC71 )
set(MSVC_PREFIX "vc70")
elseif( MSVC80 )
set(MSVC_PREFIX "vc80")
elseif( MSVC90 )
set(MSVC_PREFIX "vc90")
elseif( MSVC10 )
set(MSVC_PREFIX "vc100")
elseif( MSVC11 )
set(MSVC_PREFIX "vc110")
elseif( MSVC12 )
set(MSVC_PREFIX "vc120")
elseif( MSVC14 )
set(MSVC_PREFIX "vc140")
else()
set(MSVC_PREFIX "vc150")
endif()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
else()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the openrave libraries" )
endif()
set( ASSIMP_CXX_FLAGS ) # dynamically linked library
set( ASSIMP_LINK_FLAGS "" )
set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@")
set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@")
set( ASSIMP_LIBRARIES assimp${ASSIMP_LIBRARY_SUFFIX})
set( ASSIMP_LIBRARIES ${ASSIMP_LIBRARIES}@CMAKE_DEBUG_POSTFIX@)
# for compatibility with pkg-config
set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
set(ASSIMP_LDFLAGS_OTHER "${ASSIMP_LINK_FLAGS}")
MARK_AS_ADVANCED(
ASSIMP_ROOT_DIR
ASSIMP_CXX_FLAGS
ASSIMP_LINK_FLAGS
ASSIMP_INCLUDE_DIRS
ASSIMP_LIBRARIES
ASSIMP_CFLAGS_OTHER
ASSIMP_LDFLAGS_OTHER
ASSIMP_LIBRARY_SUFFIX
)

View File

@ -1,7 +1,7 @@
prefix=@CMAKE_INSTALL_PREFIX@ prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@/ exec_prefix=@CMAKE_INSTALL_PREFIX@/
libdir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_LIB_INSTALL_DIR@ libdir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_LIB_INSTALL_DIR@
includedir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_INCLUDE_INSTALL_DIR@ includedir=@CMAKE_INSTALL_PREFIX@/../include/@ASSIMP_INCLUDE_INSTALL_DIR@
Name: @CMAKE_PROJECT_NAME@ Name: @CMAKE_PROJECT_NAME@
Description: Import various well-known 3D model formats in an uniform manner. Description: Import various well-known 3D model formats in an uniform manner.

View File

@ -0,0 +1,78 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Debug".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
if(MSVC)
if( MSVC70 OR MSVC71 )
set(MSVC_PREFIX "vc70")
elseif( MSVC80 )
set(MSVC_PREFIX "vc80")
elseif( MSVC90 )
set(MSVC_PREFIX "vc90")
elseif( MSVC10 )
set(MSVC_PREFIX "vc100")
elseif( MSVC11 )
set(MSVC_PREFIX "vc110")
elseif( MSVC12 )
set(MSVC_PREFIX "vc120")
elseif( MSVC14 )
set(MSVC_PREFIX "vc140")
else()
set(MSVC_PREFIX "vc150")
endif()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@")
set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_IMPORT_LIBRARY_SUFFIX@")
# Import target "assimp::assimp" for configuration "Debug"
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_IMPLIB_DEBUG "${_IMPORT_PREFIX}/lib/${importLibraryName}"
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/bin/${sharedLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${importLibraryName}")
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/bin/${sharedLibraryName}" )
else()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the openrave libraries" )
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${sharedLibraryName}" )
endif()
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
get_filename_component(ASSIMP_ROOT_DIR "@CMAKE_INSTALL_PREFIX@" REALPATH)
set( ASSIMP_CXX_FLAGS ) # dynamically linked library
set( ASSIMP_LINK_FLAGS "" )
set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@")
set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@")
set( ASSIMP_LIBRARIES ${sharedLibraryName})
# for compatibility with pkg-config
set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
set(ASSIMP_LDFLAGS_OTHER "${ASSIMP_LINK_FLAGS}")
MARK_AS_ADVANCED(
ASSIMP_ROOT_DIR
ASSIMP_CXX_FLAGS
ASSIMP_LINK_FLAGS
ASSIMP_INCLUDE_DIRS
ASSIMP_LIBRARIES
ASSIMP_CFLAGS_OTHER
ASSIMP_LDFLAGS_OTHER
ASSIMP_LIBRARY_SUFFIX
)

View File

@ -0,0 +1,75 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
if(MSVC)
if( MSVC70 OR MSVC71 )
set(MSVC_PREFIX "vc70")
elseif( MSVC80 )
set(MSVC_PREFIX "vc80")
elseif( MSVC90 )
set(MSVC_PREFIX "vc90")
elseif( MSVC10 )
set(MSVC_PREFIX "vc100")
elseif( MSVC11 )
set(MSVC_PREFIX "vc110")
elseif( MSVC12 )
set(MSVC_PREFIX "vc120")
elseif( MSVC14 )
set(MSVC_PREFIX "vc140")
else()
set(MSVC_PREFIX "vc150")
endif()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@")
set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_IMPORT_LIBRARY_SUFFIX@")
# Import target "assimp::assimp" for configuration "Release"
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/${importLibraryName}"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/${sharedLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${importLibraryName}")
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/bin/${sharedLibraryName}" )
else()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the openrave libraries" )
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${sharedLibraryName}" )
endif()
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
get_filename_component(ASSIMP_ROOT_DIR "@CMAKE_INSTALL_PREFIX@" REALPATH)
set( ASSIMP_CXX_FLAGS ) # dynamically linked library
set( ASSIMP_LINK_FLAGS "" )
set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@")
set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@")
set( ASSIMP_LIBRARIES ${sharedLibraryName})
# for compatibility with pkg-config
set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
set(ASSIMP_LDFLAGS_OTHER "${ASSIMP_LINK_FLAGS}")
MARK_AS_ADVANCED(
ASSIMP_ROOT_DIR
ASSIMP_CXX_FLAGS
ASSIMP_LINK_FLAGS
ASSIMP_INCLUDE_DIRS
ASSIMP_LIBRARIES
ASSIMP_CFLAGS_OTHER
ASSIMP_LDFLAGS_OTHER
ASSIMP_LIBRARY_SUFFIX
)

View File

@ -0,0 +1,101 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
message(FATAL_ERROR "CMake >= 2.6.0 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.6)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_targetsDefined)
set(_targetsNotDefined)
set(_expectedTargets)
foreach(_expectedTarget assimp::assimp)
list(APPEND _expectedTargets ${_expectedTarget})
if(NOT TARGET ${_expectedTarget})
list(APPEND _targetsNotDefined ${_expectedTarget})
endif()
if(TARGET ${_expectedTarget})
list(APPEND _targetsDefined ${_expectedTarget})
endif()
endforeach()
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT "${_targetsDefined}" STREQUAL "")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
endif()
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target assimp::assimp
add_library(assimp::assimp SHARED IMPORTED)
set_target_properties(assimp::assimp PROPERTIES
COMPATIBLE_INTERFACE_STRING "assimp_MAJOR_VERSION"
INTERFACE_assimp_MAJOR_VERSION "1"
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;${_IMPORT_PREFIX}/include"
#INTERFACE_LINK_LIBRARIES "TxtUtils::TxtUtils;MealyMachine::MealyMachine"
)
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.")
endif()
# Load information for each installed configuration.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/assimpTargets-*.cmake")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(target ${_IMPORT_CHECK_TARGETS} )
foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
if(NOT EXISTS "${file}" )
message(FATAL_ERROR "The imported target \"${target}\" references the file
\"${file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
unset(_IMPORT_CHECK_FILES_FOR_${target})
endforeach()
unset(_IMPORT_CHECK_TARGETS)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)

View File

@ -58,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace D3DS { namespace D3DS {
#include "./../include/assimp/Compiler/pushpack1.h" #include <assimp/Compiler/pushpack1.h>
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks /** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
@ -66,7 +66,7 @@ namespace D3DS {
*/ */
class Discreet3DS { class Discreet3DS {
private: private:
Discreet3DS() { Discreet3DS() AI_NO_EXCEPT {
// empty // empty
} }
@ -328,19 +328,17 @@ struct Face : public FaceWithSmoothingGroup
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure representing a texture */ /** Helper structure representing a texture */
struct Texture struct Texture {
{
//! Default constructor //! Default constructor
Texture() Texture() AI_NO_EXCEPT
: mOffsetU (0.0) : mOffsetU (0.0)
, mOffsetV (0.0) , mOffsetV (0.0)
, mScaleU (1.0) , mScaleU (1.0)
, mScaleV (1.0) , mScaleV (1.0)
, mRotation (0.0) , mRotation (0.0)
, mMapMode (aiTextureMapMode_Wrap) , mMapMode (aiTextureMapMode_Wrap)
, bPrivate() , bPrivate()
, iUVSrc (0) , iUVSrc (0) {
{
mTextureBlend = get_qnan(); mTextureBlend = get_qnan();
} }
@ -365,7 +363,7 @@ struct Texture
int iUVSrc; int iUVSrc;
}; };
#include "./../include/assimp/Compiler/poppack1.h" #include <assimp/Compiler/poppack1.h>
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure representing a 3ds material */ /** Helper structure representing a 3ds material */
@ -394,7 +392,7 @@ struct Material
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other) Material(Material &&other) AI_NO_EXCEPT
: mName(std::move(other.mName)) : mName(std::move(other.mName))
, mDiffuse(std::move(other.mDiffuse)) , mDiffuse(std::move(other.mDiffuse))
, mSpecularExponent(std::move(other.mSpecularExponent)) , mSpecularExponent(std::move(other.mSpecularExponent))
@ -418,7 +416,7 @@ struct Material
} }
Material &operator=(Material &&other) { Material &operator=(Material &&other) AI_NO_EXCEPT {
if (this == &other) { if (this == &other) {
return *this; return *this;
} }
@ -447,7 +445,7 @@ struct Material
} }
~Material() {} virtual ~Material() {}
//! Name of the material //! Name of the material

View File

@ -161,19 +161,21 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler) aiScene* pScene, IOSystem* pIOHandler)
{ {
StreamReaderLE stream(pIOHandler->Open(pFile,"rb")); StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
this->stream = &stream;
// We should have at least one chunk // We should have at least one chunk
if (stream.GetRemainingSize() < 16) { if (stream.GetRemainingSize() < 16) {
throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile); throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile);
} }
this->stream = &stream;
// Allocate our temporary 3DS representation // Allocate our temporary 3DS representation
mScene = new D3DS::Scene(); D3DS::Scene _scene;
mScene = &_scene;
// Initialize members // Initialize members
D3DS::Node _rootNode("UNNAMED");
mLastNodeIndex = -1; mLastNodeIndex = -1;
mCurrentNode = new D3DS::Node("UNNAMED"); mCurrentNode = &_rootNode;
mRootNode = mCurrentNode; mRootNode = mCurrentNode;
mRootNode->mHierarchyPos = -1; mRootNode->mHierarchyPos = -1;
mRootNode->mHierarchyIndex = -1; mRootNode->mHierarchyIndex = -1;
@ -193,7 +195,6 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
// file. // file.
for (auto &mesh : mScene->mMeshes) { for (auto &mesh : mScene->mMeshes) {
if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) { if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) {
delete mScene;
throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile); throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile);
} }
CheckIndices(mesh); CheckIndices(mesh);
@ -201,7 +202,7 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh); ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh);
} }
// Replace all occurrences of the default material with a // Replace all occurences of the default material with a
// valid material. Generate it if no material containing // valid material. Generate it if no material containing
// DEFAULT in its name has been found in the file // DEFAULT in its name has been found in the file
ReplaceDefaultMaterial(); ReplaceDefaultMaterial();
@ -218,10 +219,8 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
// Now apply the master scaling factor to the scene // Now apply the master scaling factor to the scene
ApplyMasterScale(pScene); ApplyMasterScale(pScene);
// Delete our internal scene representation and the root // Our internal scene representation and the root
// node, so the whole hierarchy will follow // node will be automatically deleted, so the whole hierarchy will follow
delete mRootNode;
delete mScene;
AI_DEBUG_INVALIDATE_PTR(mRootNode); AI_DEBUG_INVALIDATE_PTR(mRootNode);
AI_DEBUG_INVALIDATE_PTR(mScene); AI_DEBUG_INVALIDATE_PTR(mScene);

View File

@ -63,8 +63,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Header files, stdlib. // Header files, stdlib.
#include <set> #include <set>
namespace Assimp namespace Assimp {
{
/// \class AMFImporter /// \class AMFImporter
/// Class that holding scene graph which include: geometry, metadata, materials etc. /// Class that holding scene graph which include: geometry, metadata, materials etc.
/// ///
@ -99,100 +99,49 @@ namespace Assimp
/// new - <texmap> and children <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3> /// new - <texmap> and children <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3> /// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
/// ///
class AMFImporter : public BaseImporter class AMFImporter : public BaseImporter {
{
/***********************************************/
/******************** Types ********************/
/***********************************************/
private: private:
struct SPP_Material;// forward declaration
struct SPP_Material;// forward declaration /// \struct SPP_Composite
/// Data type for post-processing step. More suitable container for part of material's composition.
struct SPP_Composite {
SPP_Material* Material;///< Pointer to material - part of composition.
std::string Formula;///< Formula for calculating ratio of \ref Material.
};
/// \struct SPP_Composite /// \struct SPP_Material
/// Data type for postprocessing step. More suitable container for part of material's composition. /// Data type for post-processing step. More suitable container for material.
struct SPP_Composite struct SPP_Material {
{ std::string ID;///< Material ID.
SPP_Material* Material;///< Pointer to material - part of composition. std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material.
std::string Formula;///< Formula for calculating ratio of \ref Material. CAMFImporter_NodeElement_Color* Color;///< Color of material.
}; std::list<SPP_Composite> Composition;///< List of child materials if current material is composition of few another.
/// \struct SPP_Material /// Return color calculated for specified coordinate.
/// Data type for postprocessing step. More suitable container for material. /// \param [in] pX - "x" coordinate.
struct SPP_Material /// \param [in] pY - "y" coordinate.
{ /// \param [in] pZ - "z" coordinate.
std::string ID;///< Material ID. /// \return calculated color.
std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material. aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
CAMFImporter_NodeElement_Color* Color;///< Color of material. };
std::list<SPP_Composite> Composition;///< List of child materials if current material is composition of few another.
/// \fn aiColor4D GetColor(const float pX, const float pY, const float pZ) const /// Data type for post-processing step. More suitable container for texture.
/// Return color calculated for specified coordinate. struct SPP_Texture {
/// \param [in] pX - "x" coordinate. std::string ID;
/// \param [in] pY - "y" coordinate. size_t Width, Height, Depth;
/// \param [in] pZ - "z" coordinate. bool Tiled;
/// \return calculated color. char FormatHint[9];// 8 for string + 1 for terminator.
aiColor4D GetColor(const float pX, const float pY, const float pZ) const; uint8_t *Data;
}; };
/// \struct SPP_Texture /// Data type for post-processing step. Contain face data.
/// Data type for post-processing step. More suitable container for texture. struct SComplexFace {
struct SPP_Texture aiFace Face;///< Face vertices.
{ const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face.
std::string ID; const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
size_t Width, Height, Depth; };
bool Tiled;
char FormatHint[ 9 ];// 8 for string + 1 for terminator.
uint8_t *Data;
};
/// \struct SComplexFace
/// Data type for post-processing step. Contain face data.
struct SComplexFace
{
aiFace Face;///< Face vertices.
const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face.
const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
};
/***********************************************/
/****************** Constants ******************/
/***********************************************/
private:
static const aiImporterDesc Description;
/***********************************************/
/****************** Variables ******************/
/***********************************************/
private:
CAMFImporter_NodeElement* mNodeElement_Cur;///< Current element.
std::list<CAMFImporter_NodeElement*> mNodeElement_List;///< All elements of scene graph.
irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
std::string mUnit;
std::list<SPP_Material> mMaterial_Converted;///< List of converted materials for postprocessing step.
std::list<SPP_Texture> mTexture_Converted;///< List of converted textures for postprocessing step.
/***********************************************/
/****************** Functions ******************/
/***********************************************/
private:
/// \fn AMFImporter(const AMFImporter& pScene)
/// Disabled copy constructor.
AMFImporter(const AMFImporter& pScene);
/// \fn AMFImporter& operator=(const AMFImporter& pScene)
/// Disabled assign operator.
AMFImporter& operator=(const AMFImporter& pScene);
/// \fn void Clear()
/// Clear all temporary data. /// Clear all temporary data.
void Clear(); void Clear();
@ -200,7 +149,6 @@ private:
/************* Functions: find set *************/ /************* Functions: find set *************/
/***********************************************/ /***********************************************/
/// \fn bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, aiNode** pNode) const
/// Find specified node element in node elements list ( \ref mNodeElement_List). /// Find specified node element in node elements list ( \ref mNodeElement_List).
/// \param [in] pID - ID(name) of requested node element. /// \param [in] pID - ID(name) of requested node element.
/// \param [in] pType - type of node element. /// \param [in] pType - type of node element.
@ -208,7 +156,6 @@ private:
/// \return true - if the node element is found, else - false. /// \return true - if the node element is found, else - false.
bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const; bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const;
/// \fn bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const
/// Find requested aiNode in node list. /// Find requested aiNode in node list.
/// \param [in] pID - ID(name) of requested node. /// \param [in] pID - ID(name) of requested node.
/// \param [in] pNodeList - list of nodes where to find the node. /// \param [in] pNodeList - list of nodes where to find the node.
@ -216,15 +163,13 @@ private:
/// \return true - if the node is found, else - false. /// \return true - if the node is found, else - false.
bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const; bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const;
/// \fn bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const
/// Find material in list for converted materials. Use at postprocessing step. /// Find material in list for converted materials. Use at postprocessing step.
/// \param [in] pID - material ID. /// \param [in] pID - material ID.
/// \param [out] pConvertedMaterial - pointer to found converted material (\ref SPP_Material). /// \param [out] pConvertedMaterial - pointer to found converted material (\ref SPP_Material).
/// \return true - if the material is found, else - false. /// \return true - if the material is found, else - false.
bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const; bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const;
/// \fn bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A, uint32_t* pConvertedTextureIndex = nullptr) const /// Find texture in list of converted textures. Use at postprocessing step,
/// Find texture in list of converted textures. Use at postprocessing step,
/// \param [in] pID_R - ID of source "red" texture. /// \param [in] pID_R - ID of source "red" texture.
/// \param [in] pID_G - ID of source "green" texture. /// \param [in] pID_G - ID of source "green" texture.
/// \param [in] pID_B - ID of source "blue" texture. /// \param [in] pID_B - ID of source "blue" texture.
@ -235,11 +180,7 @@ private:
bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A, bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A,
uint32_t* pConvertedTextureIndex = nullptr) const; uint32_t* pConvertedTextureIndex = nullptr) const;
/***********************************************/
/********* Functions: postprocess set **********/
/***********************************************/
/// \fn void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray, std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const
/// Get data stored in <vertices> and place it to arrays. /// Get data stored in <vertices> and place it to arrays.
/// \param [in] pNodeElement - reference to node element which kept <object> data. /// \param [in] pNodeElement - reference to node element which kept <object> data.
/// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in <vertices>. /// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in <vertices>.
@ -248,7 +189,6 @@ private:
void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray, void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const; std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const;
/// \fn size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A)
/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new /// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
/// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it /// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
/// to converted textures list. /// to converted textures list.
@ -260,27 +200,23 @@ private:
/// \return index of the texture in array of the converted textures. /// \return index of the texture in array of the converted textures.
size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A); size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A);
/// \fn void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> > pOutputList_Separated)
/// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc). /// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc).
/// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after /// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after
/// processing. /// processing.
/// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing. /// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing.
void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated); void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated);
/// \fn void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const
/// Check if child elements of node element is metadata and add it to scene node. /// Check if child elements of node element is metadata and add it to scene node.
/// \param [in] pMetadataList - reference to list with collected metadata. /// \param [in] pMetadataList - reference to list with collected metadata.
/// \param [out] pSceneNode - scene node in which metadata will be added. /// \param [out] pSceneNode - scene node in which metadata will be added.
void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const; void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const;
/// \fn void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)
/// To create aiMesh and aiNode for it from <object>. /// To create aiMesh and aiNode for it from <object>.
/// \param [in] pNodeElement - reference to node element which kept <object> data. /// \param [in] pNodeElement - reference to node element which kept <object> data.
/// \param [out] pMeshList - reference to a list with all aiMesh of the scene. /// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
/// \param [out] pSceneNode - pointer to place where new aiNode will be created. /// \param [out] pSceneNode - pointer to place where new aiNode will be created.
void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode); void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode);
/// \fn void Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray, const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor, std::list<aiMesh*>& pMeshList, aiNode& pSceneNode)
/// Create mesh for every <volume> in <mesh>. /// Create mesh for every <volume> in <mesh>.
/// \param [in] pNodeElement - reference to node element which kept <mesh> data. /// \param [in] pNodeElement - reference to node element which kept <mesh> data.
/// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all <volume>'s. /// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all <volume>'s.
@ -294,27 +230,20 @@ private:
const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor, const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor,
std::list<aiMesh*>& pMeshList, aiNode& pSceneNode); std::list<aiMesh*>& pMeshList, aiNode& pSceneNode);
/// \fn void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial)
/// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material. /// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material.
/// \param [in] pMaterial - source CAMFImporter_NodeElement_Material. /// \param [in] pMaterial - source CAMFImporter_NodeElement_Material.
void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial); void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial);
/// \fn void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const
/// Create and add to aiNode's list new part of scene graph defined by <constellation>. /// Create and add to aiNode's list new part of scene graph defined by <constellation>.
/// \param [in] pConstellation - reference to <constellation> node. /// \param [in] pConstellation - reference to <constellation> node.
/// \param [out] pNodeList - reference to aiNode's list. /// \param [out] pNodeList - reference to aiNode's list.
void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const; void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const;
/// \fn void Postprocess_BuildScene()
/// Build Assimp scene graph in aiScene from collected data. /// Build Assimp scene graph in aiScene from collected data.
/// \param [out] pScene - pointer to aiScene where tree will be built. /// \param [out] pScene - pointer to aiScene where tree will be built.
void Postprocess_BuildScene(aiScene* pScene); void Postprocess_BuildScene(aiScene* pScene);
/***********************************************/
/************* Functions: throw set ************/
/***********************************************/
/// \fn void Throw_CloseNotFound(const std::string& pNode)
/// Call that function when close tag of node not found and exception must be raised. /// Call that function when close tag of node not found and exception must be raised.
/// E.g.: /// E.g.:
/// <amf> /// <amf>
@ -324,19 +253,16 @@ private:
/// \param [in] pNode - node name in which exception happened. /// \param [in] pNode - node name in which exception happened.
void Throw_CloseNotFound(const std::string& pNode); void Throw_CloseNotFound(const std::string& pNode);
/// \fn void Throw_IncorrectAttr(const std::string& pAttrName)
/// Call that function when attribute name is incorrect and exception must be raised. /// Call that function when attribute name is incorrect and exception must be raised.
/// \param [in] pAttrName - attribute name. /// \param [in] pAttrName - attribute name.
/// \throw DeadlyImportError. /// \throw DeadlyImportError.
void Throw_IncorrectAttr(const std::string& pAttrName); void Throw_IncorrectAttr(const std::string& pAttrName);
/// \fn void Throw_IncorrectAttrValue(const std::string& pAttrName)
/// Call that function when attribute value is incorrect and exception must be raised. /// Call that function when attribute value is incorrect and exception must be raised.
/// \param [in] pAttrName - attribute name. /// \param [in] pAttrName - attribute name.
/// \throw DeadlyImportError. /// \throw DeadlyImportError.
void Throw_IncorrectAttrValue(const std::string& pAttrName); void Throw_IncorrectAttrValue(const std::string& pAttrName);
/// \fn void Throw_MoreThanOnceDefined(const std::string& pNode, const std::string& pDescription)
/// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised. /// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised.
/// E.g.: /// E.g.:
/// <object> /// <object>
@ -348,204 +274,158 @@ private:
/// \param [in] pDescription - message about error. E.g. what the node defined while exception raised. /// \param [in] pDescription - message about error. E.g. what the node defined while exception raised.
void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription); void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription);
/// \fn void Throw_ID_NotFound(const std::string& pID) const
/// Call that function when referenced element ID are not found in graph and exception must be raised. /// Call that function when referenced element ID are not found in graph and exception must be raised.
/// \param [in] pID - ID of of element which not found. /// \param [in] pID - ID of of element which not found.
/// \throw DeadlyImportError. /// \throw DeadlyImportError.
void Throw_ID_NotFound(const std::string& pID) const; void Throw_ID_NotFound(const std::string& pID) const;
/***********************************************/
/************** Functions: LOG set *************/
/***********************************************/
/***********************************************/
/************** Functions: XML set *************/
/***********************************************/
/// \fn void XML_CheckNode_MustHaveChildren()
/// Check if current node have children: <node>...</node>. If not then exception will throwed. /// Check if current node have children: <node>...</node>. If not then exception will throwed.
void XML_CheckNode_MustHaveChildren(); void XML_CheckNode_MustHaveChildren();
/// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName)
/// Check if current node name is equal to pNodeName. /// Check if current node name is equal to pNodeName.
/// \param [in] pNodeName - name for checking. /// \param [in] pNodeName - name for checking.
/// return true if current node name is equal to pNodeName, else - false. /// return true if current node name is equal to pNodeName, else - false.
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; } bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
/// \fn void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
/// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node. /// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node.
/// \param [in] pParentNodeName - parent node name. Used for reporting. /// \param [in] pParentNodeName - parent node name. Used for reporting.
void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName); void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName);
/// \fn bool XML_SearchNode(const std::string& pNodeName)
/// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end. /// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end.
/// \param [in] pNodeName - requested node name. /// \param [in] pNodeName - requested node name.
/// return true - if node is found, else - false. /// return true - if node is found, else - false.
bool XML_SearchNode(const std::string& pNodeName); bool XML_SearchNode(const std::string& pNodeName);
/// \fn bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
/// Read attribute value. /// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \return read data. /// \return read data.
bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx); bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx);
/// \fn float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
/// Read attribute value. /// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \return read data. /// \return read data.
float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx); float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx);
/// \fn uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx)
/// Read attribute value. /// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set). /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \return read data. /// \return read data.
uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx); uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx);
/// \fn float XML_ReadNode_GetVal_AsFloat()
/// Read node value. /// Read node value.
/// \return read data. /// \return read data.
float XML_ReadNode_GetVal_AsFloat(); float XML_ReadNode_GetVal_AsFloat();
/// \fn uint32_t XML_ReadNode_GetVal_AsU32()
/// Read node value. /// Read node value.
/// \return read data. /// \return read data.
uint32_t XML_ReadNode_GetVal_AsU32(); uint32_t XML_ReadNode_GetVal_AsU32();
/// \fn void XML_ReadNode_GetVal_AsString(std::string& pValue)
/// Read node value. /// Read node value.
/// \return read data. /// \return read data.
void XML_ReadNode_GetVal_AsString(std::string& pValue); void XML_ReadNode_GetVal_AsString(std::string& pValue);
/***********************************************/
/******** Functions: parse set private *********/
/***********************************************/
/// \fn void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode)
/// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called. /// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called.
/// \param [in] pNode - new current node. /// \param [in] pNode - new current node.
void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode); void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode);
/// \fn void ParseHelper_Group_End()
/// This function must be called when exiting from grouping node. \ref ParseHelper_Group_Begin. /// This function must be called when exiting from grouping node. \ref ParseHelper_Group_Begin.
void ParseHelper_Node_Exit(); void ParseHelper_Node_Exit();
/// \fn void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
/// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it /// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it
/// must be converted to right form - "0.xxx". /// must be converted to right form - "0.xxx".
/// \param [in] pInStr - pointer to input string which can contain incorrect form of values. /// \param [in] pInStr - pointer to input string which can contain incorrect form of values.
/// \param [out[ pOutString - output string with right form of values. /// \param [out[ pOutString - output string with right form of values.
void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString); void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString);
/// \fn void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const
/// Decode Base64-encoded data. /// Decode Base64-encoded data.
/// \param [in] pInputBase64 - reference to input Base64-encoded string. /// \param [in] pInputBase64 - reference to input Base64-encoded string.
/// \param [out] pOutputData - reference to output array for decoded data. /// \param [out] pOutputData - reference to output array for decoded data.
void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const; void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const;
/// \fn void ParseNode_Root()
/// Parse <AMF> node of the file. /// Parse <AMF> node of the file.
void ParseNode_Root(); void ParseNode_Root();
/******** Functions: top nodes *********/
/// \fn void ParseNode_Constellation()
/// Parse <constellation> node of the file. /// Parse <constellation> node of the file.
void ParseNode_Constellation(); void ParseNode_Constellation();
/// \fn void ParseNode_Constellation()
/// Parse <instance> node of the file. /// Parse <instance> node of the file.
void ParseNode_Instance(); void ParseNode_Instance();
/// \fn void ParseNode_Material()
/// Parse <material> node of the file. /// Parse <material> node of the file.
void ParseNode_Material(); void ParseNode_Material();
/// \fn void ParseNode_Metadata()
/// Parse <metadata> node. /// Parse <metadata> node.
void ParseNode_Metadata(); void ParseNode_Metadata();
/// \fn void ParseNode_Object()
/// Parse <object> node of the file. /// Parse <object> node of the file.
void ParseNode_Object(); void ParseNode_Object();
/// \fn void ParseNode_Texture()
/// Parse <texture> node of the file. /// Parse <texture> node of the file.
void ParseNode_Texture(); void ParseNode_Texture();
/******** Functions: geometry nodes *********/
/// \fn void ParseNode_Coordinates()
/// Parse <coordinates> node of the file. /// Parse <coordinates> node of the file.
void ParseNode_Coordinates(); void ParseNode_Coordinates();
/// \fn void ParseNode_Edge()
/// Parse <edge> node of the file. /// Parse <edge> node of the file.
void ParseNode_Edge(); void ParseNode_Edge();
/// \fn void ParseNode_Mesh()
/// Parse <mesh> node of the file. /// Parse <mesh> node of the file.
void ParseNode_Mesh(); void ParseNode_Mesh();
/// \fn void ParseNode_Triangle()
/// Parse <triangle> node of the file. /// Parse <triangle> node of the file.
void ParseNode_Triangle(); void ParseNode_Triangle();
/// \fn void ParseNode_Vertex()
/// Parse <vertex> node of the file. /// Parse <vertex> node of the file.
void ParseNode_Vertex(); void ParseNode_Vertex();
/// \fn void ParseNode_Vertices()
/// Parse <vertices> node of the file. /// Parse <vertices> node of the file.
void ParseNode_Vertices(); void ParseNode_Vertices();
/// \fn void ParseNode_Volume()
/// Parse <volume> node of the file. /// Parse <volume> node of the file.
void ParseNode_Volume(); void ParseNode_Volume();
/******** Functions: material nodes *********/
/// \fn void ParseNode_Color()
/// Parse <color> node of the file. /// Parse <color> node of the file.
void ParseNode_Color(); void ParseNode_Color();
/// \fn void ParseNode_TexMap(const bool pUseOldName = false)
/// Parse <texmap> of <map> node of the file. /// Parse <texmap> of <map> node of the file.
/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>. /// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
void ParseNode_TexMap(const bool pUseOldName = false); void ParseNode_TexMap(const bool pUseOldName = false);
public: public:
/// \fn AMFImporter()
/// Default constructor. /// Default constructor.
AMFImporter() AMFImporter() AI_NO_EXCEPT
: mNodeElement_Cur(nullptr), mReader(nullptr) : mNodeElement_Cur(nullptr)
{} , mReader(nullptr) {
// empty
}
/// \fn ~AMFImporter()
/// Default destructor. /// Default destructor.
~AMFImporter(); ~AMFImporter();
/***********************************************/
/******** Functions: parse set, public *********/
/***********************************************/
/// \fn void ParseFile(const std::string& pFile, IOSystem* pIOHandler)
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph. /// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
/// Also exception can be throwed if trouble will found. /// Also exception can be thrown if trouble will found.
/// \param [in] pFile - name of file to be parsed. /// \param [in] pFile - name of file to be parsed.
/// \param [in] pIOHandler - pointer to IO helper object. /// \param [in] pIOHandler - pointer to IO helper object.
void ParseFile(const std::string& pFile, IOSystem* pIOHandler); void ParseFile(const std::string& pFile, IOSystem* pIOHandler);
/***********************************************/
/********* Functions: BaseImporter set *********/
/***********************************************/
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const; bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const;
void GetExtensionList(std::set<std::string>& pExtensionList); void GetExtensionList(std::set<std::string>& pExtensionList);
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
const aiImporterDesc* GetInfo ()const; const aiImporterDesc* GetInfo ()const;
};// class AMFImporter AMFImporter(const AMFImporter& pScene) = delete;
AMFImporter& operator=(const AMFImporter& pScene) = delete;
private:
static const aiImporterDesc Description;
CAMFImporter_NodeElement* mNodeElement_Cur;///< Current element.
std::list<CAMFImporter_NodeElement*> mNodeElement_List;///< All elements of scene graph.
irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
std::string mUnit;
std::list<SPP_Material> mMaterial_Converted;///< List of converted materials for postprocessing step.
std::list<SPP_Texture> mTexture_Converted;///< List of converted textures for postprocessing step.
};
}// namespace Assimp }// namespace Assimp

View File

@ -68,10 +68,9 @@ namespace Assimp
// Multi elements - No. // Multi elements - No.
// Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The // Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
// values can be specified as constants, or as a formula depending on the coordinates. // values can be specified as constants, or as a formula depending on the coordinates.
void AMFImporter::ParseNode_Color() void AMFImporter::ParseNode_Color() {
{ std::string profile;
std::string profile; CAMFImporter_NodeElement* ne;
CAMFImporter_NodeElement* ne;
// Read attributes for node <color>. // Read attributes for node <color>.
MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_LOOPBEG;
@ -98,15 +97,19 @@ CAMFImporter_NodeElement* ne;
MACRO_NODECHECK_LOOPEND("color"); MACRO_NODECHECK_LOOPEND("color");
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
// check that all components was defined // check that all components was defined
if(!(read_flag[0] && read_flag[1] && read_flag[2])) throw DeadlyImportError("Not all color components are defined."); if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
// check if <a> is absent. Then manually add "a == 1". throw DeadlyImportError("Not all color components are defined.");
if(!read_flag[3]) als.Color.a = 1; }
}// if(!mReader->isEmptyElement()) // check if <a> is absent. Then manually add "a == 1".
if (!read_flag[3]) {
als.Color.a = 1;
}
}
else else
{ {
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
}// if(!mReader->isEmptyElement()) else }
als.Composed = false; als.Composed = false;
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
@ -119,10 +122,9 @@ CAMFImporter_NodeElement* ne;
// An available material. // An available material.
// Multi elements - Yes. // Multi elements - Yes.
// Parent element - <amf>. // Parent element - <amf>.
void AMFImporter::ParseNode_Material() void AMFImporter::ParseNode_Material() {
{ std::string id;
std::string id; CAMFImporter_NodeElement* ne;
CAMFImporter_NodeElement* ne;
// Read attributes for node <color>. // Read attributes for node <color>.
MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_LOOPBEG;
@ -131,9 +133,11 @@ CAMFImporter_NodeElement* ne;
// create new object. // create new object.
ne = new CAMFImporter_NodeElement_Material(mNodeElement_Cur); ne = new CAMFImporter_NodeElement_Material(mNodeElement_Cur);
// and assign read data
// and assign read data
((CAMFImporter_NodeElement_Material*)ne)->ID = id; ((CAMFImporter_NodeElement_Material*)ne)->ID = id;
// Check for child nodes
// Check for child nodes
if(!mReader->isEmptyElement()) if(!mReader->isEmptyElement())
{ {
bool col_read = false; bool col_read = false;
@ -154,11 +158,11 @@ CAMFImporter_NodeElement* ne;
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
MACRO_NODECHECK_LOOPEND("material"); MACRO_NODECHECK_LOOPEND("material");
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
}// if(!mReader->isEmptyElement()) }
else else
{ {
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
}// if(!mReader->isEmptyElement()) else }
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
} }
@ -181,14 +185,13 @@ CAMFImporter_NodeElement* ne;
// Parent element - <amf>. // Parent element - <amf>.
void AMFImporter::ParseNode_Texture() void AMFImporter::ParseNode_Texture()
{ {
std::string id; std::string id;
uint32_t width = 0; uint32_t width = 0;
uint32_t height = 0; uint32_t height = 0;
uint32_t depth = 1; uint32_t depth = 1;
std::string type; std::string type;
bool tiled = false; bool tiled = false;
std::string enc64_data; std::string enc64_data;
CAMFImporter_NodeElement* ne;
// Read attributes for node <color>. // Read attributes for node <color>.
MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_LOOPBEG;
@ -201,20 +204,34 @@ CAMFImporter_NodeElement* ne;
MACRO_ATTRREAD_LOOPEND; MACRO_ATTRREAD_LOOPEND;
// create new texture object. // create new texture object.
ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur); CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur);
CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience
// Check for child nodes // Check for child nodes
if(!mReader->isEmptyElement()) XML_ReadNode_GetVal_AsString(enc64_data); if (!mReader->isEmptyElement()) {
XML_ReadNode_GetVal_AsString(enc64_data);
}
// check that all components was defined // check that all components was defined
if(id.empty()) throw DeadlyImportError("ID for texture must be defined."); if (id.empty()) {
if(width < 1) Throw_IncorrectAttrValue("width"); throw DeadlyImportError("ID for texture must be defined.");
if(height < 1) Throw_IncorrectAttrValue("height"); }
if(depth < 1) Throw_IncorrectAttrValue("depth"); if (width < 1) {
if(type != "grayscale") Throw_IncorrectAttrValue("type"); Throw_IncorrectAttrValue("width");
if(enc64_data.empty()) throw DeadlyImportError("Texture data not defined."); }
if (height < 1) {
Throw_IncorrectAttrValue("height");
}
if (depth < 1) {
Throw_IncorrectAttrValue("depth");
}
if (type != "grayscale") {
Throw_IncorrectAttrValue("type");
}
if (enc64_data.empty()) {
throw DeadlyImportError("Texture data not defined.");
}
// copy data // copy data
als.ID = id; als.ID = id;
als.Width = width; als.Width = width;
@ -222,8 +239,11 @@ CAMFImporter_NodeElement* ne;
als.Depth = depth; als.Depth = depth;
als.Tiled = tiled; als.Tiled = tiled;
ParseHelper_Decode_Base64(enc64_data, als.Data); ParseHelper_Decode_Base64(enc64_data, als.Data);
// check data size
if((width * height * depth) != als.Data.size()) throw DeadlyImportError("Texture has incorrect data size."); // check data size
if ((width * height * depth) != als.Data.size()) {
throw DeadlyImportError("Texture has incorrect data size.");
}
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
@ -243,10 +263,8 @@ CAMFImporter_NodeElement* ne;
// <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>. Old name: <u1>, <u2>, <u3>, <v1>, <v2>, <v3>. // <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>. Old name: <u1>, <u2>, <u3>, <v1>, <v2>, <v3>.
// Multi elements - No. // Multi elements - No.
// Texture coordinates for every vertex of triangle. // Texture coordinates for every vertex of triangle.
void AMFImporter::ParseNode_TexMap(const bool pUseOldName) void AMFImporter::ParseNode_TexMap(const bool pUseOldName) {
{ std::string rtexid, gtexid, btexid, atexid;
std::string rtexid, gtexid, btexid, atexid;
CAMFImporter_NodeElement* ne;
// Read attributes for node <color>. // Read attributes for node <color>.
MACRO_ATTRREAD_LOOPBEG; MACRO_ATTRREAD_LOOPBEG;
@ -257,7 +275,7 @@ CAMFImporter_NodeElement* ne;
MACRO_ATTRREAD_LOOPEND; MACRO_ATTRREAD_LOOPEND;
// create new texture coordinates object. // create new texture coordinates object.
ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur); CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur);
CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience
// check data // check data

View File

@ -62,7 +62,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// \class CAMFImporter_NodeElement /// \class CAMFImporter_NodeElement
/// Base class for elements of nodes. /// Base class for elements of nodes.
class CAMFImporter_NodeElement { class CAMFImporter_NodeElement {
public: public:
/// Define what data type contain node element. /// Define what data type contain node element.
enum EType { enum EType {
@ -96,15 +95,11 @@ public: /// Destructor, virtual..
// empty // empty
} }
private: /// Disabled copy constructor and co.
/// Disabled copy constructor. CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement) = delete;
CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement); CAMFImporter_NodeElement(CAMFImporter_NodeElement&&) = delete;
CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement) = delete;
/// Disabled assign operator. CAMFImporter_NodeElement() = delete;
CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement);
/// Disabled default constructor.
CAMFImporter_NodeElement();
protected: protected:
/// In constructor inheritor must set element type. /// In constructor inheritor must set element type.
@ -121,9 +116,7 @@ protected:
/// \struct CAMFImporter_NodeElement_Constellation /// \struct CAMFImporter_NodeElement_Constellation
/// A collection of objects or constellations with specific relative locations. /// A collection of objects or constellations with specific relative locations.
struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement {
{
/// \fn CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
@ -134,9 +127,7 @@ struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement
/// \struct CAMFImporter_NodeElement_Instance /// \struct CAMFImporter_NodeElement_Instance
/// Part of constellation. /// Part of constellation.
struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement {
{
/****************** Variables ******************/
std::string ObjectID;///< ID of object for instantiation. std::string ObjectID;///< ID of object for instantiation.
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to /// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
@ -147,237 +138,185 @@ struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement
/// instance of the object in the current constellation. Rotations shall be executed in order of x first, then y, then z. /// instance of the object in the current constellation. Rotations shall be executed in order of x first, then y, then z.
aiVector3D Rotation; aiVector3D Rotation;
/****************** Functions ******************/
/// \fn CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Instance, pParent) : CAMFImporter_NodeElement(ENET_Instance, pParent)
{} {}
};
};// struct CAMFImporter_NodeElement_Instance
/// \struct CAMFImporter_NodeElement_Metadata /// \struct CAMFImporter_NodeElement_Metadata
/// Structure that define metadata node. /// Structure that define metadata node.
struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement {
{
/****************** Variables ******************/
std::string Type;///< Type of "Value". std::string Type;///< Type of "Value".
std::string Value;///< Value. std::string Value;///< Value.
/****************** Functions ******************/
/// \fn CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Metadata, pParent) : CAMFImporter_NodeElement(ENET_Metadata, pParent)
{} {}
};
};// struct CAMFImporter_NodeElement_Metadata
/// \struct CAMFImporter_NodeElement_Root /// \struct CAMFImporter_NodeElement_Root
/// Structure that define root node. /// Structure that define root node.
struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement {
{
/****************** Variables ******************/
std::string Unit;///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron". std::string Unit;///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
std::string Version;///< Version of format. std::string Version;///< Version of format.
/****************** Functions ******************/
/// \fn CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Root, pParent) : CAMFImporter_NodeElement(ENET_Root, pParent)
{} {}
};
};// struct CAMFImporter_NodeElement_Root
/// \struct CAMFImporter_NodeElement_Color /// \struct CAMFImporter_NodeElement_Color
/// Structure that define object node. /// Structure that define object node.
struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement {
{ bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
/****************** Variables ******************/ std::string Color_Composed[4]; ///< By components formulas of composed color. [0..3] - RGBA.
aiColor4D Color; ///< Constant color.
std::string Profile; ///< The ICC color space used to interpret the three color channels r, g and b..
bool Composed;///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color. /// @brief Constructor.
std::string Color_Composed[4];///< By components formulas of composed color. [0..3] => RGBA. /// @param [in] pParent - pointer to parent node.
aiColor4D Color;///< Constant color.
std::string Profile;///< The ICC color space used to interpret the three color channels <r>, <g> and <b>..
/****************** Functions ******************/
/// \fn CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Color, pParent) : CAMFImporter_NodeElement(ENET_Color, pParent)
{} , Composed( false )
, Color()
};// struct CAMFImporter_NodeElement_Color , Profile() {
// empty
}
};
/// \struct CAMFImporter_NodeElement_Material /// \struct CAMFImporter_NodeElement_Material
/// Structure that define material node. /// Structure that define material node.
struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement {
{
/// \fn CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Material, pParent) : CAMFImporter_NodeElement(ENET_Material, pParent)
{} {}
};// struct CAMFImporter_NodeElement_Material };
/// \struct CAMFImporter_NodeElement_Object /// \struct CAMFImporter_NodeElement_Object
/// Structure that define object node. /// Structure that define object node.
struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement {
{
/// \fn CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent) /// Constructor.
/// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Object, pParent) : CAMFImporter_NodeElement(ENET_Object, pParent)
{} {}
};
};// struct CAMFImporter_NodeElement_Object
/// \struct CAMFImporter_NodeElement_Mesh /// \struct CAMFImporter_NodeElement_Mesh
/// Structure that define mesh node. /// Structure that define mesh node.
struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement {
{
/// \fn CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Mesh, pParent) : CAMFImporter_NodeElement(ENET_Mesh, pParent)
{} {}
};
};// struct CAMFImporter_NodeElement_Mesh
/// \struct CAMFImporter_NodeElement_Vertex /// \struct CAMFImporter_NodeElement_Vertex
/// Structure that define vertex node. /// Structure that define vertex node.
struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement {
{
/// \fn CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Vertex, pParent) : CAMFImporter_NodeElement(ENET_Vertex, pParent)
{} {}
};
};// struct CAMFImporter_NodeElement_Vertex
/// \struct CAMFImporter_NodeElement_Edge /// \struct CAMFImporter_NodeElement_Edge
/// Structure that define edge node. /// Structure that define edge node.
struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement {
{
/// \fn CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Edge, pParent) : CAMFImporter_NodeElement(ENET_Edge, pParent)
{} {}
};// struct CAMFImporter_NodeElement_Vertex };
/// \struct CAMFImporter_NodeElement_Vertices /// \struct CAMFImporter_NodeElement_Vertices
/// Structure that define vertices node. /// Structure that define vertices node.
struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement {
{
/// \fn CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Vertices, pParent) : CAMFImporter_NodeElement(ENET_Vertices, pParent)
{} {}
};
};// struct CAMFImporter_NodeElement_Vertices
/// \struct CAMFImporter_NodeElement_Volume /// \struct CAMFImporter_NodeElement_Volume
/// Structure that define volume node. /// Structure that define volume node.
struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement {
{
/****************** Variables ******************/
std::string MaterialID;///< Which material to use. std::string MaterialID;///< Which material to use.
std::string Type;///< What this volume describes can be “region” or “support”. If none specified, “object” is assumed. std::string Type;///< What this volume describes can be “region” or “support”. If none specified, “object” is assumed.
/****************** Functions ******************/
/// \fn CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Volume, pParent) : CAMFImporter_NodeElement(ENET_Volume, pParent)
{} {}
};
};// struct CAMFImporter_NodeElement_Volume
/// \struct CAMFImporter_NodeElement_Coordinates /// \struct CAMFImporter_NodeElement_Coordinates
/// Structure that define coordinates node. /// Structure that define coordinates node.
struct CAMFImporter_NodeElement_Coordinates : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Coordinates : public CAMFImporter_NodeElement
{ {
/****************** Variables ******************/
aiVector3D Coordinate;///< Coordinate. aiVector3D Coordinate;///< Coordinate.
/****************** Functions ******************/
/// \fn CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Coordinates, pParent) : CAMFImporter_NodeElement(ENET_Coordinates, pParent)
{} {}
};// struct CAMFImporter_NodeElement_Coordinates };
/// \struct CAMFImporter_NodeElement_TexMap /// \struct CAMFImporter_NodeElement_TexMap
/// Structure that define texture coordinates node. /// Structure that define texture coordinates node.
struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement {
{
/****************** Variables ******************/
aiVector3D TextureCoordinate[3];///< Texture coordinates. aiVector3D TextureCoordinate[3];///< Texture coordinates.
std::string TextureID_R;///< Texture ID for red color component. std::string TextureID_R;///< Texture ID for red color component.
std::string TextureID_G;///< Texture ID for green color component. std::string TextureID_G;///< Texture ID for green color component.
std::string TextureID_B;///< Texture ID for blue color component. std::string TextureID_B;///< Texture ID for blue color component.
std::string TextureID_A;///< Texture ID for alpha color component. std::string TextureID_A;///< Texture ID for alpha color component.
/****************** Functions ******************/
/// \fn CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_TexMap, pParent) : CAMFImporter_NodeElement(ENET_TexMap, pParent)
{} , TextureCoordinate{}
, TextureID_R()
};// struct CAMFImporter_NodeElement_TexMap , TextureID_G()
, TextureID_B()
, TextureID_A() {
// empty
}
};
/// \struct CAMFImporter_NodeElement_Triangle /// \struct CAMFImporter_NodeElement_Triangle
/// Structure that define triangle node. /// Structure that define triangle node.
struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement {
{
/****************** Variables ******************/
size_t V[3];///< Triangle vertices. size_t V[3];///< Triangle vertices.
/****************** Functions ******************/
/// \fn CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
/// Constructor. /// Constructor.
/// \param [in] pParent - pointer to parent node. /// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent) CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Triangle, pParent) : CAMFImporter_NodeElement(ENET_Triangle, pParent) {
{} // empty
}
};// struct CAMFImporter_NodeElement_Triangle };
/// Structure that define texture node. /// Structure that define texture node.
struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement { struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement {
@ -396,6 +335,6 @@ struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement {
, Tiled( false ){ , Tiled( false ){
// empty // empty
} }
};// struct CAMFImporter_NodeElement_Texture };
#endif // INCLUDED_AI_AMF_IMPORTER_NODE_H #endif // INCLUDED_AI_AMF_IMPORTER_NODE_H

View File

@ -71,21 +71,20 @@ struct Material : public D3DS::Material
//! Default constructor has been deleted //! Default constructor has been deleted
Material() = delete; Material() = delete;
//! Constructor with explicit name //! Constructor with explicit name
explicit Material(const std::string &name) explicit Material(const std::string &name)
: D3DS::Material(name) : D3DS::Material(name)
, pcInstance(NULL) , pcInstance(NULL)
, bNeed (false) , bNeed (false) {
{} // empty
}
Material(const Material &other) = default; Material(const Material &other) = default;
Material &operator=(const Material &other) = default; Material &operator=(const Material &other) = default;
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other) Material(Material &&other) AI_NO_EXCEPT
: D3DS::Material(std::move(other)) : D3DS::Material(std::move(other))
, avSubMaterials(std::move(other.avSubMaterials)) , avSubMaterials(std::move(other.avSubMaterials))
, pcInstance(std::move(other.pcInstance)) , pcInstance(std::move(other.pcInstance))
@ -95,7 +94,7 @@ struct Material : public D3DS::Material
} }
Material &operator=(Material &&other) { Material &operator=(Material &&other) AI_NO_EXCEPT {
if (this == &other) { if (this == &other) {
return *this; return *this;
} }
@ -127,19 +126,12 @@ struct Material : public D3DS::Material
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file face */ /** Helper structure to represent an ASE file face */
struct Face : public FaceWithSmoothingGroup struct Face : public FaceWithSmoothingGroup {
{
//! Default constructor. Initializes everything with 0 //! Default constructor. Initializes everything with 0
Face() Face() AI_NO_EXCEPT
{ : iMaterial(DEFAULT_MATINDEX)
mColorIndices[0] = mColorIndices[1] = mColorIndices[2] = 0; , iFace(0) {
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i) // empty
{
amUVIndices[i][0] = amUVIndices[i][1] = amUVIndices[i][2] = 0;
}
iMaterial = DEFAULT_MATINDEX;
iFace = 0;
} }
//! special value to indicate that no material index has //! special value to indicate that no material index has
@ -147,8 +139,6 @@ struct Face : public FaceWithSmoothingGroup
//! will replace this value later. //! will replace this value later.
static const unsigned int DEFAULT_MATINDEX = 0xFFFFFFFF; static const unsigned int DEFAULT_MATINDEX = 0xFFFFFFFF;
//! Indices into each list of texture coordinates //! Indices into each list of texture coordinates
unsigned int amUVIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS][3]; unsigned int amUVIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS][3];
@ -166,15 +156,15 @@ struct Face : public FaceWithSmoothingGroup
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file bone */ /** Helper structure to represent an ASE file bone */
struct Bone struct Bone {
{
//! Constructor //! Constructor
Bone() = delete; Bone() = delete;
//! Construction from an existing name //! Construction from an existing name
explicit Bone( const std::string& name) explicit Bone( const std::string& name)
: mName (name) : mName(name) {
{} // empty
}
//! Name of the bone //! Name of the bone
std::string mName; std::string mName;
@ -182,29 +172,22 @@ struct Bone
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file bone vertex */ /** Helper structure to represent an ASE file bone vertex */
struct BoneVertex struct BoneVertex {
{
//! Bone and corresponding vertex weight. //! Bone and corresponding vertex weight.
//! -1 for unrequired bones .... //! -1 for unrequired bones ....
std::vector<std::pair<int,float> > mBoneWeights; std::vector<std::pair<int,float> > mBoneWeights;
//! Position of the bone vertex.
//! MUST be identical to the vertex position
//aiVector3D mPosition;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file animation */ /** Helper structure to represent an ASE file animation */
struct Animation struct Animation {
{ enum Type {
enum Type
{
TRACK = 0x0, TRACK = 0x0,
BEZIER = 0x1, BEZIER = 0x1,
TCB = 0x2 TCB = 0x2
} mRotationType, mScalingType, mPositionType; } mRotationType, mScalingType, mPositionType;
Animation() Animation() AI_NO_EXCEPT
: mRotationType (TRACK) : mRotationType (TRACK)
, mScalingType (TRACK) , mScalingType (TRACK)
, mPositionType (TRACK) , mPositionType (TRACK)
@ -218,19 +201,16 @@ struct Animation
//! List of track scaling keyframes //! List of track scaling keyframes
std::vector< aiVectorKey > akeyScaling; std::vector< aiVectorKey > akeyScaling;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent the inheritance information of an ASE node */ /** Helper structure to represent the inheritance information of an ASE node */
struct InheritanceInfo struct InheritanceInfo {
{
//! Default constructor //! Default constructor
InheritanceInfo() InheritanceInfo() AI_NO_EXCEPT {
{ for ( size_t i=0; i<3; ++i ) {
// set the inheritance flag for all axes by default to true
for (unsigned int i = 0; i < 3;++i)
abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true; abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
}
} }
//! Inherit the parent's position?, axis order is x,y,z //! Inherit the parent's position?, axis order is x,y,z
@ -245,17 +225,19 @@ struct InheritanceInfo
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Represents an ASE file node. Base class for mesh, light and cameras */ /** Represents an ASE file node. Base class for mesh, light and cameras */
struct BaseNode struct BaseNode {
{ enum Type {
enum Type {Light, Camera, Mesh, Dummy} mType; Light,
Camera,
Mesh,
Dummy
} mType;
//! Construction from an existing name //! Construction from an existing name
BaseNode(Type _mType, const std::string &name) BaseNode(Type _mType, const std::string &name)
: mType (_mType) : mType (_mType)
, mName (name) , mName (name)
, mProcessed (false) , mProcessed (false) {
{
// Set mTargetPosition to qnan // Set mTargetPosition to qnan
const ai_real qnan = get_qnan(); const ai_real qnan = get_qnan();
mTargetPosition.x = qnan; mTargetPosition.x = qnan;
@ -291,24 +273,23 @@ struct BaseNode
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file mesh */ /** Helper structure to represent an ASE file mesh */
struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode {
{
//! Default constructor has been deleted //! Default constructor has been deleted
Mesh() = delete; Mesh() = delete;
//! Construction from an existing name //! Construction from an existing name
explicit Mesh(const std::string &name) explicit Mesh(const std::string &name)
: BaseNode (BaseNode::Mesh, name) : BaseNode( BaseNode::Mesh, name )
, mVertexColors()
, mBoneVertices()
, mBones()
, iMaterialIndex(Face::DEFAULT_MATINDEX) , iMaterialIndex(Face::DEFAULT_MATINDEX)
, bSkip (false) , bSkip (false) {
{ for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
// use 2 texture vertex components by default
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
this->mNumUVComponents[c] = 2; this->mNumUVComponents[c] = 2;
}
} }
//! List of all texture coordinate sets //! List of all texture coordinate sets
std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
@ -396,12 +377,11 @@ struct Camera : public BaseNode
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent an ASE helper object (dummy) */ /** Helper structure to represent an ASE helper object (dummy) */
struct Dummy : public BaseNode struct Dummy : public BaseNode {
{
//! Constructor //! Constructor
Dummy() Dummy() AI_NO_EXCEPT
: BaseNode (BaseNode::Dummy, "DUMMY") : BaseNode (BaseNode::Dummy, "DUMMY") {
{ // empty
} }
}; };
@ -416,12 +396,11 @@ struct Dummy : public BaseNode
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
/** \brief Class to parse ASE files /** \brief Class to parse ASE files
*/ */
class Parser class Parser {
{
private: private:
Parser() AI_NO_EXCEPT {
Parser() {} // empty
}
public: public:

File diff suppressed because it is too large Load Diff

View File

@ -46,6 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASSBINEXPORTER_H_INC #ifndef AI_ASSBINEXPORTER_H_INC
#define AI_ASSBINEXPORTER_H_INC #define AI_ASSBINEXPORTER_H_INC
// nothing really needed here - reserved for future use like properties #include <assimp/defs.h>
#endif // nothing really needed here - reserved for future use like properties
namespace Assimp {
void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/);
}
#endif // AI_ASSBINEXPORTER_H_INC

View File

@ -57,6 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/anim.h> #include <assimp/anim.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <memory>
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h> # include <zlib.h>
@ -79,16 +80,17 @@ static const aiImporterDesc desc = {
"assbin" "assbin"
}; };
const aiImporterDesc* AssbinImporter::GetInfo() const // -----------------------------------------------------------------------------------
{ const aiImporterDesc* AssbinImporter::GetInfo() const {
return &desc; return &desc;
} }
bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const // -----------------------------------------------------------------------------------
{ bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const {
IOStream * in = pIOHandler->Open(pFile); IOStream * in = pIOHandler->Open(pFile);
if (!in) if (nullptr == in) {
return false; return false;
}
char s[32]; char s[32];
in->Read( s, sizeof(char), 32 ); in->Read( s, sizeof(char), 32 );
@ -98,17 +100,19 @@ bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bo
return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0;
} }
// -----------------------------------------------------------------------------------
template <typename T> template <typename T>
T Read(IOStream * stream) T Read(IOStream * stream) {
{
T t; T t;
stream->Read( &t, sizeof(T), 1 ); size_t res = stream->Read( &t, sizeof(T), 1 );
if(res != 1)
throw DeadlyImportError("Unexpected EOF");
return t; return t;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiVector3D Read<aiVector3D>(IOStream * stream) aiVector3D Read<aiVector3D>(IOStream * stream) {
{
aiVector3D v; aiVector3D v;
v.x = Read<float>(stream); v.x = Read<float>(stream);
v.y = Read<float>(stream); v.y = Read<float>(stream);
@ -116,9 +120,9 @@ aiVector3D Read<aiVector3D>(IOStream * stream)
return v; return v;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiColor4D Read<aiColor4D>(IOStream * stream) aiColor4D Read<aiColor4D>(IOStream * stream) {
{
aiColor4D c; aiColor4D c;
c.r = Read<float>(stream); c.r = Read<float>(stream);
c.g = Read<float>(stream); c.g = Read<float>(stream);
@ -127,9 +131,9 @@ aiColor4D Read<aiColor4D>(IOStream * stream)
return c; return c;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiQuaternion Read<aiQuaternion>(IOStream * stream) aiQuaternion Read<aiQuaternion>(IOStream * stream) {
{
aiQuaternion v; aiQuaternion v;
v.w = Read<float>(stream); v.w = Read<float>(stream);
v.x = Read<float>(stream); v.x = Read<float>(stream);
@ -138,28 +142,29 @@ aiQuaternion Read<aiQuaternion>(IOStream * stream)
return v; return v;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiString Read<aiString>(IOStream * stream) aiString Read<aiString>(IOStream * stream) {
{
aiString s; aiString s;
stream->Read(&s.length,4,1); stream->Read(&s.length,4,1);
stream->Read(s.data,s.length,1); if(s.length)
stream->Read(s.data,s.length,1);
s.data[s.length] = 0; s.data[s.length] = 0;
return s; return s;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiVertexWeight Read<aiVertexWeight>(IOStream * stream) aiVertexWeight Read<aiVertexWeight>(IOStream * stream) {
{
aiVertexWeight w; aiVertexWeight w;
w.mVertexId = Read<unsigned int>(stream); w.mVertexId = Read<unsigned int>(stream);
w.mWeight = Read<float>(stream); w.mWeight = Read<float>(stream);
return w; return w;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream) aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream) {
{
aiMatrix4x4 m; aiMatrix4x4 m;
for (unsigned int i = 0; i < 4;++i) { for (unsigned int i = 0; i < 4;++i) {
for (unsigned int i2 = 0; i2 < 4;++i2) { for (unsigned int i2 = 0; i2 < 4;++i2) {
@ -169,76 +174,85 @@ aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
return m; return m;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiVectorKey Read<aiVectorKey>(IOStream * stream) aiVectorKey Read<aiVectorKey>(IOStream * stream) {
{
aiVectorKey v; aiVectorKey v;
v.mTime = Read<double>(stream); v.mTime = Read<double>(stream);
v.mValue = Read<aiVector3D>(stream); v.mValue = Read<aiVector3D>(stream);
return v; return v;
} }
// -----------------------------------------------------------------------------------
template <> template <>
aiQuatKey Read<aiQuatKey>(IOStream * stream) aiQuatKey Read<aiQuatKey>(IOStream * stream) {
{
aiQuatKey v; aiQuatKey v;
v.mTime = Read<double>(stream); v.mTime = Read<double>(stream);
v.mValue = Read<aiQuaternion>(stream); v.mValue = Read<aiQuaternion>(stream);
return v; return v;
} }
// -----------------------------------------------------------------------------------
template <typename T> template <typename T>
void ReadArray(IOStream * stream, T * out, unsigned int size) void ReadArray( IOStream *stream, T * out, unsigned int size) {
{ ai_assert( nullptr != stream );
for (unsigned int i=0; i<size; i++) out[i] = Read<T>(stream); ai_assert( nullptr != out );
for (unsigned int i=0; i<size; i++) {
out[i] = Read<T>(stream);
}
} }
template <typename T> void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n ) // -----------------------------------------------------------------------------------
{ template <typename T>
void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n ) {
// not sure what to do here, the data isn't really useful. // not sure what to do here, the data isn't really useful.
stream->Seek( sizeof(T) * n, aiOrigin_CUR ); stream->Seek( sizeof(T) * n, aiOrigin_CUR );
} }
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) { // -----------------------------------------------------------------------------------
uint32_t chunkID = Read<uint32_t>(stream); void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** onode, aiNode* parent ) {
(void)(chunkID); if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AINODE)
ai_assert(chunkID == ASSBIN_CHUNK_AINODE); throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
*node = new aiNode(); std::unique_ptr<aiNode> node(new aiNode());
(*node)->mName = Read<aiString>(stream); node->mName = Read<aiString>(stream);
(*node)->mTransformation = Read<aiMatrix4x4>(stream); node->mTransformation = Read<aiMatrix4x4>(stream);
(*node)->mNumChildren = Read<unsigned int>(stream); unsigned numChildren = Read<unsigned int>(stream);
(*node)->mNumMeshes = Read<unsigned int>(stream); unsigned numMeshes = Read<unsigned int>(stream);
unsigned int nb_metadata = Read<unsigned int>(stream); unsigned int nb_metadata = Read<unsigned int>(stream);
if(parent) { if(parent) {
(*node)->mParent = parent; node->mParent = parent;
} }
if ((*node)->mNumMeshes) { if (numMeshes)
(*node)->mMeshes = new unsigned int[(*node)->mNumMeshes]; {
for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) { node->mMeshes = new unsigned int[numMeshes];
(*node)->mMeshes[i] = Read<unsigned int>(stream); for (unsigned int i = 0; i < numMeshes; ++i) {
node->mMeshes[i] = Read<unsigned int>(stream);
node->mNumMeshes++;
} }
} }
if ((*node)->mNumChildren) { if (numChildren) {
(*node)->mChildren = new aiNode*[(*node)->mNumChildren]; node->mChildren = new aiNode*[numChildren];
for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) { for (unsigned int i = 0; i < numChildren; ++i) {
ReadBinaryNode( stream, &(*node)->mChildren[i], *node ); ReadBinaryNode( stream, &node->mChildren[i], node.get() );
node->mNumChildren++;
} }
} }
if ( nb_metadata > 0 ) { if ( nb_metadata > 0 ) {
(*node)->mMetaData = aiMetadata::Alloc(nb_metadata); node->mMetaData = aiMetadata::Alloc(nb_metadata);
for (unsigned int i = 0; i < nb_metadata; ++i) { for (unsigned int i = 0; i < nb_metadata; ++i) {
(*node)->mMetaData->mKeys[i] = Read<aiString>(stream); node->mMetaData->mKeys[i] = Read<aiString>(stream);
(*node)->mMetaData->mValues[i].mType = (aiMetadataType) Read<uint16_t>(stream); node->mMetaData->mValues[i].mType = (aiMetadataType) Read<uint16_t>(stream);
void* data( nullptr ); void* data = nullptr;
switch ((*node)->mMetaData->mValues[i].mType) { switch (node->mMetaData->mValues[i].mType) {
case AI_BOOL: case AI_BOOL:
data = new bool(Read<bool>(stream)); data = new bool(Read<bool>(stream));
break; break;
@ -267,17 +281,16 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* p
break; break;
} }
(*node)->mMetaData->mValues[i].mData = data; node->mMetaData->mValues[i].mData = data;
} }
} }
*onode = node.release();
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) {
{ if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIBONE)
uint32_t chunkID = Read<uint32_t>(stream); throw DeadlyImportError("Magic chunk identifiers are wrong!");
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
b->mName = Read<aiString>(stream); b->mName = Read<aiString>(stream);
@ -286,23 +299,23 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
// for the moment we write dumb min/max values for the bones, too. // for the moment we write dumb min/max values for the bones, too.
// maybe I'll add a better, hash-like solution later // maybe I'll add a better, hash-like solution later
if (shortened) if (shortened) {
{
ReadBounds(stream,b->mWeights,b->mNumWeights); ReadBounds(stream,b->mWeights,b->mNumWeights);
} // else write as usual } else {
else // else write as usual
{
b->mWeights = new aiVertexWeight[b->mNumWeights]; b->mWeights = new aiVertexWeight[b->mNumWeights];
ReadArray<aiVertexWeight>(stream,b->mWeights,b->mNumWeights); ReadArray<aiVertexWeight>(stream,b->mWeights,b->mNumWeights);
} }
} }
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) static bool fitsIntoUI16(unsigned int mNumVertices) {
{ return ( mNumVertices < (1u<<16) );
uint32_t chunkID = Read<uint32_t>(stream); }
(void)(chunkID); // -----------------------------------------------------------------------------------
ai_assert(chunkID == ASSBIN_CHUNK_AIMESH); void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) {
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMESH)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
mesh->mPrimitiveTypes = Read<unsigned int>(stream); mesh->mPrimitiveTypes = Read<unsigned int>(stream);
@ -314,70 +327,61 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
// first of all, write bits for all existent vertex components // first of all, write bits for all existent vertex components
unsigned int c = Read<unsigned int>(stream); unsigned int c = Read<unsigned int>(stream);
if (c & ASSBIN_MESH_HAS_POSITIONS) if (c & ASSBIN_MESH_HAS_POSITIONS) {
{
if (shortened) { if (shortened) {
ReadBounds(stream,mesh->mVertices,mesh->mNumVertices); ReadBounds(stream,mesh->mVertices,mesh->mNumVertices);
} // else write as usual } else {
else // else write as usual
{
mesh->mVertices = new aiVector3D[mesh->mNumVertices]; mesh->mVertices = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices); ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices);
} }
} }
if (c & ASSBIN_MESH_HAS_NORMALS) if (c & ASSBIN_MESH_HAS_NORMALS) {
{
if (shortened) { if (shortened) {
ReadBounds(stream,mesh->mNormals,mesh->mNumVertices); ReadBounds(stream,mesh->mNormals,mesh->mNumVertices);
} // else write as usual } else {
else // else write as usual
{
mesh->mNormals = new aiVector3D[mesh->mNumVertices]; mesh->mNormals = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mNormals,mesh->mNumVertices); ReadArray<aiVector3D>(stream,mesh->mNormals,mesh->mNumVertices);
} }
} }
if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) {
{
if (shortened) { if (shortened) {
ReadBounds(stream,mesh->mTangents,mesh->mNumVertices); ReadBounds(stream,mesh->mTangents,mesh->mNumVertices);
ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices); ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices);
} // else write as usual } else {
else // else write as usual
{
mesh->mTangents = new aiVector3D[mesh->mNumVertices]; mesh->mTangents = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices); ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices);
mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices); ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices);
} }
} }
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
{ if (!(c & ASSBIN_MESH_HAS_COLOR(n))) {
if (!(c & ASSBIN_MESH_HAS_COLOR(n)))
break; break;
}
if (shortened) if (shortened) {
{
ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices); ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices);
} // else write as usual } else {
else // else write as usual
{
mesh->mColors[n] = new aiColor4D[mesh->mNumVertices]; mesh->mColors[n] = new aiColor4D[mesh->mNumVertices];
ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices); ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices);
} }
} }
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
{ if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n))) {
if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n)))
break; break;
}
// write number of UV components // write number of UV components
mesh->mNumUVComponents[n] = Read<unsigned int>(stream); mesh->mNumUVComponents[n] = Read<unsigned int>(stream);
if (shortened) { if (shortened) {
ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices); ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
} // else write as usual } else {
else // else write as usual
{
mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
ReadArray<aiVector3D>(stream,mesh->mTextureCoords[n],mesh->mNumVertices); ReadArray<aiVector3D>(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
} }
@ -389,9 +393,8 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
// using Assimp's standard hashing function. // using Assimp's standard hashing function.
if (shortened) { if (shortened) {
Read<unsigned int>(stream); Read<unsigned int>(stream);
} } else {
else // else write as usual // else write as usual
{
// if there are less than 2^16 vertices, we can simply use 16 bit integers ... // if there are less than 2^16 vertices, we can simply use 16 bit integers ...
mesh->mFaces = new aiFace[mesh->mNumFaces]; mesh->mFaces = new aiFace[mesh->mNumFaces];
for (unsigned int i = 0; i < mesh->mNumFaces;++i) { for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
@ -402,12 +405,10 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
f.mIndices = new unsigned int[f.mNumIndices]; f.mIndices = new unsigned int[f.mNumIndices];
for (unsigned int a = 0; a < f.mNumIndices;++a) { for (unsigned int a = 0; a < f.mNumIndices;++a) {
if (mesh->mNumVertices < (1u<<16)) // Check if unsigned short ( 16 bit ) are big enought for the indices
{ if ( fitsIntoUI16( mesh->mNumVertices ) ) {
f.mIndices[a] = Read<uint16_t>(stream); f.mIndices[a] = Read<uint16_t>(stream);
} } else {
else
{
f.mIndices[a] = Read<unsigned int>(stream); f.mIndices[a] = Read<unsigned int>(stream);
} }
} }
@ -424,11 +425,10 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
} }
} }
void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) // -----------------------------------------------------------------------------------
{ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) {
uint32_t chunkID = Read<uint32_t>(stream); if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMATERIALPROPERTY)
(void)(chunkID); throw DeadlyImportError("Magic chunk identifiers are wrong!");
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
prop->mKey = Read<aiString>(stream); prop->mKey = Read<aiString>(stream);
@ -442,11 +442,9 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) {
{ if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMATERIAL)
uint32_t chunkID = Read<uint32_t>(stream); throw DeadlyImportError("Magic chunk identifiers are wrong!");
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream); mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream);
@ -465,11 +463,9 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) {
{ if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AINODEANIM)
uint32_t chunkID = Read<uint32_t>(stream); throw DeadlyImportError("Magic chunk identifiers are wrong!");
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
nd->mNodeName = Read<aiString>(stream); nd->mNodeName = Read<aiString>(stream);
@ -493,9 +489,8 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
if (shortened) { if (shortened) {
ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys); ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys);
} // else write as usual } else {
else // else write as usual
{
nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys); ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys);
} }
@ -504,22 +499,18 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
if (shortened) { if (shortened) {
ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys); ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys);
} // else write as usual } else {
else // else write as usual
{
nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
ReadArray<aiVectorKey>(stream,nd->mScalingKeys,nd->mNumScalingKeys); ReadArray<aiVectorKey>(stream,nd->mScalingKeys,nd->mNumScalingKeys);
} }
} }
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) {
{ if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIANIMATION)
uint32_t chunkID = Read<uint32_t>(stream); throw DeadlyImportError("Magic chunk identifiers are wrong!");
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
anim->mName = Read<aiString> (stream); anim->mName = Read<aiString> (stream);
@ -527,8 +518,7 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
anim->mTicksPerSecond = Read<double> (stream); anim->mTicksPerSecond = Read<double> (stream);
anim->mNumChannels = Read<unsigned int>(stream); anim->mNumChannels = Read<unsigned int>(stream);
if (anim->mNumChannels) if (anim->mNumChannels) {
{
anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ]; anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ];
for (unsigned int a = 0; a < anim->mNumChannels;++a) { for (unsigned int a = 0; a < anim->mNumChannels;++a) {
anim->mChannels[a] = new aiNodeAnim(); anim->mChannels[a] = new aiNodeAnim();
@ -537,11 +527,10 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
} }
} }
void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) // -----------------------------------------------------------------------------------
{ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) {
uint32_t chunkID = Read<uint32_t>(stream); if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AITEXTURE)
(void)(chunkID); throw DeadlyImportError("Magic chunk identifiers are wrong!");
ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
tex->mWidth = Read<unsigned int>(stream); tex->mWidth = Read<unsigned int>(stream);
@ -552,21 +541,17 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
if (!tex->mHeight) { if (!tex->mHeight) {
tex->pcData = new aiTexel[ tex->mWidth ]; tex->pcData = new aiTexel[ tex->mWidth ];
stream->Read(tex->pcData,1,tex->mWidth); stream->Read(tex->pcData,1,tex->mWidth);
} } else {
else {
tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ]; tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ];
stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4); stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4);
} }
} }
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) {
{ if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AILIGHT)
uint32_t chunkID = Read<uint32_t>(stream); throw DeadlyImportError("Magic chunk identifiers are wrong!");
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
l->mName = Read<aiString>(stream); l->mName = Read<aiString>(stream);
@ -586,15 +571,12 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
l->mAngleInnerCone = Read<float>(stream); l->mAngleInnerCone = Read<float>(stream);
l->mAngleOuterCone = Read<float>(stream); l->mAngleOuterCone = Read<float>(stream);
} }
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) {
{ if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AICAMERA)
uint32_t chunkID = Read<uint32_t>(stream); throw DeadlyImportError("Magic chunk identifiers are wrong!");
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
cam->mName = Read<aiString>(stream); cam->mName = Read<aiString>(stream);
@ -607,11 +589,10 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
cam->mAspect = Read<float>(stream); cam->mAspect = Read<float>(stream);
} }
void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) // -----------------------------------------------------------------------------------
{ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
uint32_t chunkID = Read<uint32_t>(stream); if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AISCENE)
(void)(chunkID); throw DeadlyImportError("Magic chunk identifiers are wrong!");
ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
/*uint32_t size =*/ Read<uint32_t>(stream); /*uint32_t size =*/ Read<uint32_t>(stream);
scene->mFlags = Read<unsigned int>(stream); scene->mFlags = Read<unsigned int>(stream);
@ -623,13 +604,13 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
scene->mNumCameras = Read<unsigned int>(stream); scene->mNumCameras = Read<unsigned int>(stream);
// Read node graph // Read node graph
scene->mRootNode = new aiNode[1]; //scene->mRootNode = new aiNode[1];
ReadBinaryNode( stream, &scene->mRootNode, (aiNode*)NULL ); ReadBinaryNode( stream, &scene->mRootNode, (aiNode*)NULL );
// Read all meshes // Read all meshes
if (scene->mNumMeshes) if (scene->mNumMeshes) {
{
scene->mMeshes = new aiMesh*[scene->mNumMeshes]; scene->mMeshes = new aiMesh*[scene->mNumMeshes];
memset(scene->mMeshes, 0, scene->mNumMeshes*sizeof(aiMesh*));
for (unsigned int i = 0; i < scene->mNumMeshes;++i) { for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
scene->mMeshes[i] = new aiMesh(); scene->mMeshes[i] = new aiMesh();
ReadBinaryMesh( stream,scene->mMeshes[i]); ReadBinaryMesh( stream,scene->mMeshes[i]);
@ -637,9 +618,9 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
// Read materials // Read materials
if (scene->mNumMaterials) if (scene->mNumMaterials) {
{
scene->mMaterials = new aiMaterial*[scene->mNumMaterials]; scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
memset(scene->mMaterials, 0, scene->mNumMaterials*sizeof(aiMaterial*));
for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
scene->mMaterials[i] = new aiMaterial(); scene->mMaterials[i] = new aiMaterial();
ReadBinaryMaterial(stream,scene->mMaterials[i]); ReadBinaryMaterial(stream,scene->mMaterials[i]);
@ -647,9 +628,9 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
// Read all animations // Read all animations
if (scene->mNumAnimations) if (scene->mNumAnimations) {
{
scene->mAnimations = new aiAnimation*[scene->mNumAnimations]; scene->mAnimations = new aiAnimation*[scene->mNumAnimations];
memset(scene->mAnimations, 0, scene->mNumAnimations*sizeof(aiAnimation*));
for (unsigned int i = 0; i < scene->mNumAnimations;++i) { for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
scene->mAnimations[i] = new aiAnimation(); scene->mAnimations[i] = new aiAnimation();
ReadBinaryAnim(stream,scene->mAnimations[i]); ReadBinaryAnim(stream,scene->mAnimations[i]);
@ -657,9 +638,9 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
// Read all textures // Read all textures
if (scene->mNumTextures) if (scene->mNumTextures) {
{
scene->mTextures = new aiTexture*[scene->mNumTextures]; scene->mTextures = new aiTexture*[scene->mNumTextures];
memset(scene->mTextures, 0, scene->mNumTextures*sizeof(aiTexture*));
for (unsigned int i = 0; i < scene->mNumTextures;++i) { for (unsigned int i = 0; i < scene->mNumTextures;++i) {
scene->mTextures[i] = new aiTexture(); scene->mTextures[i] = new aiTexture();
ReadBinaryTexture(stream,scene->mTextures[i]); ReadBinaryTexture(stream,scene->mTextures[i]);
@ -667,9 +648,9 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
// Read lights // Read lights
if (scene->mNumLights) if (scene->mNumLights) {
{
scene->mLights = new aiLight*[scene->mNumLights]; scene->mLights = new aiLight*[scene->mNumLights];
memset(scene->mLights, 0, scene->mNumLights*sizeof(aiLight*));
for (unsigned int i = 0; i < scene->mNumLights;++i) { for (unsigned int i = 0; i < scene->mNumLights;++i) {
scene->mLights[i] = new aiLight(); scene->mLights[i] = new aiLight();
ReadBinaryLight(stream,scene->mLights[i]); ReadBinaryLight(stream,scene->mLights[i]);
@ -677,9 +658,9 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
// Read cameras // Read cameras
if (scene->mNumCameras) if (scene->mNumCameras) {
{
scene->mCameras = new aiCamera*[scene->mNumCameras]; scene->mCameras = new aiCamera*[scene->mNumCameras];
memset(scene->mCameras, 0, scene->mNumCameras*sizeof(aiCamera*));
for (unsigned int i = 0; i < scene->mNumCameras;++i) { for (unsigned int i = 0; i < scene->mNumCameras;++i) {
scene->mCameras[i] = new aiCamera(); scene->mCameras[i] = new aiCamera();
ReadBinaryCamera(stream,scene->mCameras[i]); ReadBinaryCamera(stream,scene->mCameras[i]);
@ -688,16 +669,22 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
} }
void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) // -----------------------------------------------------------------------------------
{ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) {
IOStream * stream = pIOHandler->Open(pFile,"rb"); IOStream * stream = pIOHandler->Open(pFile,"rb");
if (!stream) if (nullptr == stream) {
return; return;
}
stream->Seek( 44, aiOrigin_CUR ); // signature // signature
stream->Seek( 44, aiOrigin_CUR );
unsigned int versionMajor = Read<unsigned int>(stream);
unsigned int versionMinor = Read<unsigned int>(stream);
if (versionMinor != ASSBIN_VERSION_MINOR || versionMajor != ASSBIN_VERSION_MAJOR) {
throw DeadlyImportError( "Invalid version, data format not compatible!" );
}
/*unsigned int versionMajor =*/ Read<unsigned int>(stream);
/*unsigned int versionMinor =*/ Read<unsigned int>(stream);
/*unsigned int versionRevision =*/ Read<unsigned int>(stream); /*unsigned int versionRevision =*/ Read<unsigned int>(stream);
/*unsigned int compileFlags =*/ Read<unsigned int>(stream); /*unsigned int compileFlags =*/ Read<unsigned int>(stream);
@ -711,17 +698,24 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
stream->Seek( 128, aiOrigin_CUR ); // options stream->Seek( 128, aiOrigin_CUR ); // options
stream->Seek( 64, aiOrigin_CUR ); // padding stream->Seek( 64, aiOrigin_CUR ); // padding
if (compressed) if (compressed) {
{
uLongf uncompressedSize = Read<uint32_t>(stream); uLongf uncompressedSize = Read<uint32_t>(stream);
uLongf compressedSize = static_cast<uLongf>(stream->FileSize() - stream->Tell()); uLongf compressedSize = static_cast<uLongf>(stream->FileSize() - stream->Tell());
unsigned char * compressedData = new unsigned char[ compressedSize ]; unsigned char * compressedData = new unsigned char[ compressedSize ];
stream->Read( compressedData, 1, compressedSize ); size_t len = stream->Read( compressedData, 1, compressedSize );
ai_assert(len == compressedSize);
unsigned char * uncompressedData = new unsigned char[ uncompressedSize ]; unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
uncompress( uncompressedData, &uncompressedSize, compressedData, compressedSize ); int res = uncompress( uncompressedData, &uncompressedSize, compressedData, len );
if(res != Z_OK)
{
delete [] uncompressedData;
delete [] compressedData;
pIOHandler->Close(stream);
throw DeadlyImportError("Zlib decompression failed.");
}
MemoryIOStream io( uncompressedData, uncompressedSize ); MemoryIOStream io( uncompressedData, uncompressedSize );
@ -729,9 +723,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
delete[] uncompressedData; delete[] uncompressedData;
delete[] compressedData; delete[] compressedData;
} } else {
else
{
ReadBinaryScene(stream,pScene); ReadBinaryScene(stream,pScene);
} }

View File

@ -70,32 +70,33 @@ namespace Assimp {
class AssbinImporter : public BaseImporter class AssbinImporter : public BaseImporter
{ {
private: private:
bool shortened; bool shortened;
bool compressed; bool compressed;
public: public:
virtual bool CanRead( virtual bool CanRead(
const std::string& pFile, const std::string& pFile,
IOSystem* pIOHandler, IOSystem* pIOHandler,
bool checkSig bool checkSig
) const; ) const;
virtual const aiImporterDesc* GetInfo() const; virtual const aiImporterDesc* GetInfo() const;
virtual void InternReadFile( virtual void InternReadFile(
const std::string& pFile, const std::string& pFile,
aiScene* pScene, aiScene* pScene,
IOSystem* pIOHandler IOSystem* pIOHandler
); );
void ReadBinaryScene( IOStream * stream, aiScene* pScene ); void ReadHeader();
void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent ); void ReadBinaryScene( IOStream * stream, aiScene* pScene );
void ReadBinaryMesh( IOStream * stream, aiMesh* mesh ); void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );
void ReadBinaryBone( IOStream * stream, aiBone* bone ); void ReadBinaryMesh( IOStream * stream, aiMesh* mesh );
void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat); void ReadBinaryBone( IOStream * stream, aiBone* bone );
void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop); void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat);
void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd); void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop);
void ReadBinaryAnim( IOStream * stream, aiAnimation* anim ); void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd);
void ReadBinaryTexture(IOStream * stream, aiTexture* tex); void ReadBinaryAnim( IOStream * stream, aiAnimation* anim );
void ReadBinaryLight( IOStream * stream, aiLight* l ); void ReadBinaryTexture(IOStream * stream, aiTexture* tex);
void ReadBinaryCamera( IOStream * stream, aiCamera* cam ); void ReadBinaryLight( IOStream * stream, aiLight* l );
void ReadBinaryCamera( IOStream * stream, aiCamera* cam );
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -50,13 +50,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/GenericProperty.h> #include <assimp/GenericProperty.h>
#include <assimp/Exceptional.h>
#include <assimp/BaseImporter.h>
#include "CInterfaceIOWrapper.h" #include "CInterfaceIOWrapper.h"
#include "Importer.h" #include "Importer.h"
#include <assimp/Exceptional.h>
#include "ScenePrivate.h" #include "ScenePrivate.h"
#include <assimp/BaseImporter.h>
#include <list> #include <list>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -107,7 +108,6 @@ namespace Assimp {
static std::mutex gLogStreamMutex; static std::mutex gLogStreamMutex;
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Custom LogStream implementation for the C-API // Custom LogStream implementation for the C-API
class LogToCallbackRedirector : public LogStream { class LogToCallbackRedirector : public LogStream {
@ -272,8 +272,6 @@ void aiReleaseImport( const aiScene* pScene)
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
// find the importer associated with this data // find the importer associated with this data
const ScenePrivateData* priv = ScenePriv(pScene); const ScenePrivateData* priv = ScenePriv(pScene);
if( !priv || !priv->mOrigImporter) { if( !priv || !priv->mOrigImporter) {

View File

@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <map>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
@ -461,6 +462,13 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
aiNodeAnim* nodeAnim = new aiNodeAnim; aiNodeAnim* nodeAnim = new aiNodeAnim;
anim->mChannels[a] = nodeAnim; anim->mChannels[a] = nodeAnim;
nodeAnim->mNodeName.Set( nodeName); nodeAnim->mNodeName.Set( nodeName);
std::map<BVHLoader::ChannelType, int> channelMap;
//Build map of channels
for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel)
{
channelMap[node.mChannels[channel]] = channel;
}
// translational part, if given // translational part, if given
if( node.mChannels.size() == 6) if( node.mChannels.size() == 6)
@ -472,16 +480,32 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
{ {
poskey->mTime = double( fr); poskey->mTime = double( fr);
// Now compute all translations in the right order // Now compute all translations
for( unsigned int channel = 0; channel < 3; ++channel) for(BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel +1))
{ {
switch( node.mChannels[channel]) //Find channel in node
{ std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break; if (mapIter == channelMap.end())
case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break; throw DeadlyImportError("Missing position channel in node " + nodeName);
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName ); else {
} int channelIdx = mapIter->second;
switch (channel) {
case Channel_PositionX:
poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
break;
case Channel_PositionY:
poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
break;
case Channel_PositionZ:
poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
break;
default:
break;
}
}
} }
++poskey; ++poskey;
} }
@ -497,12 +521,6 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
// rotation part. Always present. First find value offsets // rotation part. Always present. First find value offsets
{ {
unsigned int rotOffset = 0;
if( node.mChannels.size() == 6)
{
// Offset all further calculations
rotOffset = 3;
}
// Then create the number of rotation keys // Then create the number of rotation keys
nodeAnim->mNumRotationKeys = mAnimNumFrames; nodeAnim->mNumRotationKeys = mAnimNumFrames;
@ -512,20 +530,33 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
{ {
aiMatrix4x4 temp; aiMatrix4x4 temp;
aiMatrix3x3 rotMatrix; aiMatrix3x3 rotMatrix;
for (BVHLoader::ChannelType channel = Channel_RotationX; channel <= Channel_RotationZ; channel = (BVHLoader::ChannelType)(channel + 1))
{
//Find channel in node
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
for( unsigned int channel = 0; channel < 3; ++channel) if (mapIter == channelMap.end())
{ throw DeadlyImportError("Missing rotation channel in node " + nodeName);
// translate ZXY euler angels into a quaternion else {
const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f; int channelIdx = mapIter->second;
// translate ZXY euler angels into a quaternion
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
// Compute rotation transformations in the right order // Compute rotation transformations in the right order
switch (node.mChannels[rotOffset+channel]) switch (channel)
{ {
case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break; case Channel_RotationX:
case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); break; aiMatrix4x4::RotationX(angle, temp); rotMatrix *= aiMatrix3x3(temp);
case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break; break;
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName ); case Channel_RotationY:
} aiMatrix4x4::RotationY(angle, temp); rotMatrix *= aiMatrix3x3(temp);
break;
case Channel_RotationZ: aiMatrix4x4::RotationZ(angle, temp); rotMatrix *= aiMatrix3x3(temp);
break;
default:
break;
}
}
} }
rotkey->mTime = double( fr); rotkey->mTime = double( fr);

View File

@ -65,7 +65,7 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
BaseImporter::BaseImporter() BaseImporter::BaseImporter() AI_NO_EXCEPT
: m_progress() { : m_progress() {
// nothing to do here // nothing to do here
} }

View File

@ -53,7 +53,7 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
BaseProcess::BaseProcess() BaseProcess::BaseProcess() AI_NO_EXCEPT
: shared() : shared()
, progress() , progress()
{ {

View File

@ -211,20 +211,16 @@ private:
* should be executed. If the function returns true, the class' Execute() * should be executed. If the function returns true, the class' Execute()
* function is called subsequently. * function is called subsequently.
*/ */
class ASSIMP_API_WINONLY BaseProcess class ASSIMP_API_WINONLY BaseProcess {
{
friend class Importer; friend class Importer;
public: public:
/** Constructor to be privately used by Importer */ /** Constructor to be privately used by Importer */
BaseProcess(); BaseProcess() AI_NO_EXCEPT;
/** Destructor, private as well */ /** Destructor, private as well */
virtual ~BaseProcess(); virtual ~BaseProcess();
public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag. /** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with. A * @param pFlags The processing flags the importer was called with. A

View File

@ -405,7 +405,7 @@ bool Structure::ReadFieldPtrVector(vector<TOUT<T>>&out, const char* name, const
++db.stats().fields_read; ++db.stats().fields_read;
#endif #endif
return false; return true;
} }

View File

@ -1206,7 +1206,7 @@ aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj,
out->mUp = aiVector3D(0.f, 1.f, 0.f); out->mUp = aiVector3D(0.f, 1.f, 0.f);
out->mLookAt = aiVector3D(0.f, 0.f, -1.f); out->mLookAt = aiVector3D(0.f, 0.f, -1.f);
if (cam->sensor_x && cam->lens) { if (cam->sensor_x && cam->lens) {
out->mHorizontalFOV = std::atan2(cam->sensor_x, 2.f * cam->lens); out->mHorizontalFOV = 2.f * std::atan2(cam->sensor_x, 2.f * cam->lens);
} }
out->mClipPlaneNear = cam->clipsta; out->mClipPlaneNear = cam->clipsta;
out->mClipPlaneFar = cam->clipend; out->mClipPlaneFar = cam->clipend;

View File

@ -203,7 +203,7 @@ template <> void Structure :: Convert<Lamp> (
int temp = 0; int temp = 0;
ReadField<ErrorPolicy_Fail>(temp,"type",db); ReadField<ErrorPolicy_Fail>(temp,"type",db);
dest.type = static_cast<Assimp::Blender::Lamp::Type>(temp); dest.type = static_cast<Assimp::Blender::Lamp::Type>(temp);
ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db); ReadField<ErrorPolicy_Igno>(dest.flags,"flag",db);
ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db); ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db); ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
ReadField<ErrorPolicy_Warn>(dest.r,"r",db); ReadField<ErrorPolicy_Warn>(dest.r,"r",db);

View File

@ -191,6 +191,14 @@ SET( Common_SRCS
) )
SOURCE_GROUP(Common FILES ${Common_SRCS}) SOURCE_GROUP(Common FILES ${Common_SRCS})
SET( STEPParser_SRCS
Importer/STEPParser/STEPFileReader.h
Importer/STEPParser/STEPFileReader.cpp
Importer/STEPParser/STEPFileEncoding.cpp
Importer/STEPParser/STEPFileEncoding.h
)
SOURCE_GROUP(STEPParser FILES ${STEPParser_SRCS})
IF ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER ) IF ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER )
SET( C4D_SRCS SET( C4D_SRCS
C4DImporter.cpp C4DImporter.cpp
@ -487,11 +495,8 @@ ADD_ASSIMP_IMPORTER( IFC
Importer/IFC/IFCCurve.cpp Importer/IFC/IFCCurve.cpp
Importer/IFC/IFCBoolean.cpp Importer/IFC/IFCBoolean.cpp
Importer/IFC/IFCOpenings.cpp Importer/IFC/IFCOpenings.cpp
Importer/IFC/STEPFileReader.h
Importer/IFC/STEPFileReader.cpp
Importer/IFC/STEPFileEncoding.cpp
Importer/IFC/STEPFileEncoding.h
) )
if (ASSIMP_BUILD_IFC_IMPORTER) if (ASSIMP_BUILD_IFC_IMPORTER)
if (MSVC) if (MSVC)
set_source_files_properties(Importer/IFC/IFCReaderGen1_2x3.cpp Importer/IFC/IFCReaderGen2_2x3.cpp PROPERTIES COMPILE_FLAGS "/bigobj") set_source_files_properties(Importer/IFC/IFCReaderGen1_2x3.cpp Importer/IFC/IFCReaderGen2_2x3.cpp PROPERTIES COMPILE_FLAGS "/bigobj")
@ -505,7 +510,6 @@ ADD_ASSIMP_IMPORTER( XGL
XGLLoader.h XGLLoader.h
) )
ADD_ASSIMP_IMPORTER( FBX ADD_ASSIMP_IMPORTER( FBX
FBXImporter.cpp FBXImporter.cpp
FBXCompileConfig.h FBXCompileConfig.h
@ -558,6 +562,8 @@ SET( PostProcessing_SRCS
FindInvalidDataProcess.h FindInvalidDataProcess.h
FixNormalsStep.cpp FixNormalsStep.cpp
FixNormalsStep.h FixNormalsStep.h
DropFaceNormalsProcess.cpp
DropFaceNormalsProcess.h
GenFaceNormalsProcess.cpp GenFaceNormalsProcess.cpp
GenFaceNormalsProcess.h GenFaceNormalsProcess.h
GenVertexNormalsProcess.cpp GenVertexNormalsProcess.cpp
@ -721,12 +727,17 @@ ADD_ASSIMP_IMPORTER( MMD
MMDVmdParser.h MMDVmdParser.h
) )
SET( Step_SRCS ADD_ASSIMP_IMPORTER( STEP
STEPFile.h STEPFile.h
StepExporter.h Importer/StepFile/StepFileImporter.h
StepExporter.cpp Importer/StepFile/StepFileImporter.cpp
Importer/StepFile/StepFileGen1.cpp
Importer/StepFile/StepFileGen2.cpp
Importer/StepFile/StepFileGen3.cpp
Importer/StepFile/StepReaderGen.h
StepExporter.h
StepExporter.cpp
) )
SOURCE_GROUP( Step FILES ${Step_SRCS})
SET( Exporter_SRCS SET( Exporter_SRCS
Exporter.cpp Exporter.cpp
@ -878,6 +889,7 @@ SET( assimp_src
${Exporter_SRCS} ${Exporter_SRCS}
${PostProcessing_SRCS} ${PostProcessing_SRCS}
${MaterialSystem_SRCS} ${MaterialSystem_SRCS}
${STEPParser_SRCS}
${Step_SRCS} ${Step_SRCS}
# Model Support # Model Support
@ -910,6 +922,7 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER) ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
ADD_LIBRARY( assimp ${assimp_src} ) ADD_LIBRARY( assimp ${assimp_src} )
ADD_LIBRARY(assimp::assimp ALIAS assimp)
TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>

View File

@ -137,9 +137,7 @@ void COBImporter::SetupProperties(const Importer* /*pImp*/)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void COBImporter::InternReadFile( const std::string& pFile, void COBImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
aiScene* pScene, IOSystem* pIOHandler)
{
COB::Scene scene; COB::Scene scene;
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) ); std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) );

View File

@ -1533,7 +1533,23 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
// write transformation - we can directly put the matrix there // write transformation - we can directly put the matrix there
// TODO: (thom) decompose into scale - rot - quad to allow addressing it by animations afterwards // TODO: (thom) decompose into scale - rot - quad to allow addressing it by animations afterwards
const aiMatrix4x4& mat = pNode->mTransformation; aiMatrix4x4 mat = pNode->mTransformation;
// If this node is a Camera node, the camera coordinate system needs to be multiplied in.
// When importing from Collada, the mLookAt is set to 0, 0, -1, and the node transform is unchanged.
// When importing from a different format, mLookAt is set to 0, 0, 1. Therefore, the local camera
// coordinate system must be changed to matche the Collada specification.
for (size_t i = 0; i<mScene->mNumCameras; i++){
if (mScene->mCameras[i]->mName == pNode->mName){
aiMatrix4x4 sourceView;
mScene->mCameras[i]->GetCameraMatrix(sourceView);
aiMatrix4x4 colladaView;
colladaView.a1 = colladaView.c3 = -1; // move into -z space.
mat *= (sourceView * colladaView);
break;
}
}
// customized, sid should be 'matrix' to match with loader code. // customized, sid should be 'matrix' to match with loader code.
//mOutput << startstr << "<matrix sid=\"transform\">"; //mOutput << startstr << "<matrix sid=\"transform\">";

View File

@ -59,6 +59,25 @@ using namespace Assimp;
#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS #ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
namespace {
template <typename aiMeshType>
void flipUVs(aiMeshType* pMesh) {
if (pMesh == nullptr) { return; }
// mirror texture y coordinate
for (unsigned int tcIdx = 0; tcIdx < AI_MAX_NUMBER_OF_TEXTURECOORDS; tcIdx++) {
if (!pMesh->HasTextureCoords(tcIdx)) {
break;
}
for (unsigned int vIdx = 0; vIdx < pMesh->mNumVertices; vIdx++) {
pMesh->mTextureCoords[tcIdx][vIdx].y = 1.0f - pMesh->mTextureCoords[tcIdx][vIdx].y;
}
}
}
} // namespace
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
MakeLeftHandedProcess::MakeLeftHandedProcess() MakeLeftHandedProcess::MakeLeftHandedProcess()
@ -282,15 +301,9 @@ void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
// Converts a single mesh // Converts a single mesh
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh) void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
{ {
// mirror texture y coordinate flipUVs(pMesh);
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { for (unsigned int idx = 0; idx < pMesh->mNumAnimMeshes; idx++) {
if( !pMesh->HasTextureCoords( a ) ) { flipUVs(pMesh->mAnimMeshes[idx]);
break;
}
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
}
} }
} }

View File

@ -297,8 +297,9 @@ private:
return false; return false;
} }
//format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
const size_t len( strlen( color ) ); const size_t len( strlen( color ) );
if ( 9 != len ) { if ( 9 != len && 7 != len) {
return false; return false;
} }
@ -313,26 +314,28 @@ private:
++buf; ++buf;
comp[ 1 ] = *buf; comp[ 1 ] = *buf;
++buf; ++buf;
diffuse.r = static_cast<ai_real>( strtol( comp, NULL, 16 ) ); diffuse.r = static_cast<ai_real>( strtol( comp, NULL, 16 ) ) / ai_real(255.0);
comp[ 0 ] = *buf; comp[ 0 ] = *buf;
++buf; ++buf;
comp[ 1 ] = *buf; comp[ 1 ] = *buf;
++buf; ++buf;
diffuse.g = static_cast< ai_real >( strtol( comp, NULL, 16 ) ); diffuse.g = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / ai_real(255.0);
comp[ 0 ] = *buf; comp[ 0 ] = *buf;
++buf; ++buf;
comp[ 1 ] = *buf; comp[ 1 ] = *buf;
++buf; ++buf;
diffuse.b = static_cast< ai_real >( strtol( comp, NULL, 16 ) ); diffuse.b = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / ai_real(255.0);
if(7 == len)
return true;
comp[ 0 ] = *buf; comp[ 0 ] = *buf;
++buf; ++buf;
comp[ 1 ] = *buf; comp[ 1 ] = *buf;
++buf; ++buf;
diffuse.a = static_cast< ai_real >( strtol( comp, NULL, 16 ) ); diffuse.a = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / ai_real(255.0);
return true; return true;
} }
@ -416,8 +419,6 @@ private:
} //namespace D3MF } //namespace D3MF
static const std::string Extension = "3mf";
static const aiImporterDesc desc = { static const aiImporterDesc desc = {
"3mf Importer", "3mf Importer",
"", "",
@ -428,7 +429,7 @@ static const aiImporterDesc desc = {
0, 0,
0, 0,
0, 0,
Extension.c_str() "3mf"
}; };
D3MFImporter::D3MFImporter() D3MFImporter::D3MFImporter()
@ -442,7 +443,7 @@ D3MFImporter::~D3MFImporter() {
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const { bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension( GetExtension( filename ) ); const std::string extension( GetExtension( filename ) );
if(extension == Extension ) { if(extension == desc.mFileExtensions ) {
return true; return true;
} else if ( !extension.length() || checkSig ) { } else if ( !extension.length() || checkSig ) {
if ( nullptr == pIOHandler ) { if ( nullptr == pIOHandler ) {

View File

@ -55,28 +55,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
namespace Assimp { namespace Assimp {
namespace DXF { namespace DXF {
// read pairs of lines, parse group code and value and provide utilities // read pairs of lines, parse group code and value and provide utilities
// to convert the data to the target data type. // to convert the data to the target data type.
class LineReader // do NOT skip empty lines. In DXF files, they count as valid data.
{ class LineReader {
public: public:
LineReader(StreamReaderLE& reader) LineReader(StreamReaderLE& reader)
// do NOT skip empty lines. In DXF files, they count as valid data. : splitter(reader,false,true)
: splitter(reader,false,true) , groupcode( 0 )
, groupcode( 0 ) , value()
, value() , end() {
, end() // empty
{
} }
public:
// ----------------------------------------- // -----------------------------------------
bool Is(int gc, const char* what) const { bool Is(int gc, const char* what) const {
return groupcode == gc && !strcmp(what,value.c_str()); return groupcode == gc && !strcmp(what,value.c_str());
@ -102,8 +95,6 @@ public:
return !((bool)*this); return !((bool)*this);
} }
public:
// ----------------------------------------- // -----------------------------------------
unsigned int ValueAsUnsignedInt() const { unsigned int ValueAsUnsignedInt() const {
return strtoul10(value.c_str()); return strtoul10(value.c_str());
@ -119,8 +110,6 @@ public:
return fast_atof(value.c_str()); return fast_atof(value.c_str());
} }
public:
// ----------------------------------------- // -----------------------------------------
/** pseudo-iterator increment to advance to the next (groupcode/value) pair */ /** pseudo-iterator increment to advance to the next (groupcode/value) pair */
LineReader& operator++() { LineReader& operator++() {
@ -175,14 +164,12 @@ private:
int end; int end;
}; };
// represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed. // represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed.
struct PolyLine struct PolyLine {
{
PolyLine() PolyLine()
: flags() : flags() {
{} // empty
}
std::vector<aiVector3D> positions; std::vector<aiVector3D> positions;
std::vector<aiColor4D> colors; std::vector<aiColor4D> colors;
@ -194,14 +181,15 @@ struct PolyLine
std::string desc; std::string desc;
}; };
// reference to a BLOCK. Specifies its own coordinate system. // reference to a BLOCK. Specifies its own coordinate system.
struct InsertBlock struct InsertBlock {
{
InsertBlock() InsertBlock()
: scale(1.f,1.f,1.f) : pos()
, angle() , scale(1.f,1.f,1.f)
{} , angle()
, name() {
// empty
}
aiVector3D pos; aiVector3D pos;
aiVector3D scale; aiVector3D scale;
@ -228,9 +216,7 @@ struct FileData
std::vector<Block> blocks; std::vector<Block> blocks;
}; };
}
} // Namespace Assimp
}}
#endif #endif

View File

@ -63,16 +63,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
// AutoCAD Binary DXF<CR><LF><SUB><NULL> // AutoCAD Binary DXF<CR><LF><SUB><NULL>
#define AI_DXF_BINARY_IDENT ("AutoCAD Binary DXF\r\n\x1a\0") const std::string AI_DXF_BINARY_IDENT = std::string("AutoCAD Binary DXF\r\n\x1a\0");
#define AI_DXF_BINARY_IDENT_LEN (24) const size_t AI_DXF_BINARY_IDENT_LEN = 24u;
// default vertex color that all uncolored vertices will receive // default vertex color that all uncolored vertices will receive
#define AI_DXF_DEFAULT_COLOR aiColor4D(0.6f,0.6f,0.6f,0.6f) const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
// color indices for DXF - 16 are supported, the table is // color indices for DXF - 16 are supported, the table is
// taken directly from the DXF spec. // taken directly from the DXF spec.
static aiColor4D g_aclrDxfIndexColors[] = static aiColor4D g_aclrDxfIndexColors[] = {
{
aiColor4D (0.6f, 0.6f, 0.6f, 1.0f), aiColor4D (0.6f, 0.6f, 0.6f, 1.0f),
aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
@ -93,6 +92,10 @@ static aiColor4D g_aclrDxfIndexColors[] =
#define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0])) #define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
#define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC" #define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC"
static const int GroupCode_Name = 2;
static const int GroupCode_XComp = 10;
static const int GroupCode_YComp = 20;
static const int GroupCode_ZComp = 30;
static const aiImporterDesc desc = { static const aiImporterDesc desc = {
"Drawing Interchange Format (DXF) Importer", "Drawing Interchange Format (DXF) Importer",
@ -110,24 +113,27 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
DXFImporter::DXFImporter() DXFImporter::DXFImporter()
{} : BaseImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
DXFImporter::~DXFImporter() DXFImporter::~DXFImporter() {
{} // 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 DXFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const { bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool checkSig ) const {
const std::string& extension = GetExtension( pFile ); const std::string& extension = GetExtension( filename );
if ( extension == "dxf" ) { if ( extension == desc.mFileExtensions ) {
return true; return true;
} }
if ( extension.empty() || checkSig ) { if ( extension.empty() || checkSig ) {
static const char *pTokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" }; const char *pTokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 4, 32 ); return BaseImporter::SearchFileHeaderForToken(pIOHandler, filename, pTokens, 4, 32 );
} }
return false; return false;
@ -135,29 +141,25 @@ bool DXFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a list of all supported file extensions // Get a list of all supported file extensions
const aiImporterDesc* DXFImporter::GetInfo () const const aiImporterDesc* DXFImporter::GetInfo () const {
{
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void DXFImporter::InternReadFile( const std::string& pFile, void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene, IOSystem* pIOHandler) {
aiScene* pScene, std::shared_ptr<IOStream> file = std::shared_ptr<IOStream>( pIOHandler->Open( filename) );
IOSystem* pIOHandler)
{
std::shared_ptr<IOStream> file = std::shared_ptr<IOStream>( pIOHandler->Open( pFile) );
// Check whether we can read the file // Check whether we can read the file
if( file.get() == NULL) { if( file.get() == nullptr ) {
throw DeadlyImportError( "Failed to open DXF file " + pFile + ""); throw DeadlyImportError( "Failed to open DXF file " + filename + "");
} }
// check whether this is a binaray DXF file - we can't read binary DXF files :-( // Check whether this is a binary DXF file - we can't read binary DXF files :-(
char buff[AI_DXF_BINARY_IDENT_LEN+1] = {0}; char buff[AI_DXF_BINARY_IDENT_LEN+1] = {0};
file->Read(buff,AI_DXF_BINARY_IDENT_LEN,1); file->Read(buff,AI_DXF_BINARY_IDENT_LEN,1);
if (!strncmp(AI_DXF_BINARY_IDENT,buff,AI_DXF_BINARY_IDENT_LEN)) { if (0 == strncmp(AI_DXF_BINARY_IDENT.c_str(),buff,AI_DXF_BINARY_IDENT_LEN)) {
throw DeadlyImportError("DXF: Binary files are not supported at the moment"); throw DeadlyImportError("DXF: Binary files are not supported at the moment");
} }
@ -226,13 +228,11 @@ void DXFImporter::InternReadFile( const std::string& pFile,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) {
{
// the process of resolving all the INSERT statements can grow the // the process of resolving all the INSERT statements can grow the
// poly-count excessively, so log the original number. // poly-count excessively, so log the original number.
// XXX Option to import blocks as separate nodes? // XXX Option to import blocks as separate nodes?
if (!DefaultLogger::isNullLogger()) { if (!DefaultLogger::isNullLogger()) {
unsigned int vcount = 0, icount = 0; unsigned int vcount = 0, icount = 0;
for (const DXF::Block& bl : output.blocks) { for (const DXF::Block& bl : output.blocks) {
for (std::shared_ptr<const DXF::PolyLine> pl : bl.lines) { for (std::shared_ptr<const DXF::PolyLine> pl : bl.lines) {
@ -293,7 +293,7 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output)
} }
} }
if (!pScene->mNumMeshes) { if ( 0 == pScene->mNumMeshes) {
throw DeadlyImportError("DXF: this file contains no 3d data"); throw DeadlyImportError("DXF: this file contains no 3d data");
} }
@ -366,8 +366,7 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& blocks_by_name) void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& blocks_by_name) {
{
for (const DXF::InsertBlock& insert : bl.insertions) { for (const DXF::InsertBlock& insert : bl.insertions) {
// first check if the referenced blocks exists ... // first check if the referenced blocks exists ...
@ -407,8 +406,7 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/) void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/) {
{
// generate an almost-white default material. Reason: // generate an almost-white default material. Reason:
// the default vertex color is GREY, so we are // the default vertex color is GREY, so we are
// already at Assimp's usual default color. // already at Assimp's usual default color.
@ -433,8 +431,7 @@ void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/) void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/) {
{
// generate the output scene graph, which is just the root node with a single child for each layer. // generate the output scene graph, which is just the root node with a single child for each layer.
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("<DXF_ROOT>"); pScene->mRootNode->mName.Set("<DXF_ROOT>");
@ -488,17 +485,17 @@ void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output) {
while( !reader.End() && !reader.Is(0,"ENDBLK")) { while( !reader.End() && !reader.Is(0,"ENDBLK")) {
switch(reader.GroupCode()) { switch(reader.GroupCode()) {
case 2: case GroupCode_Name:
block.name = reader.Value(); block.name = reader.Value();
break; break;
case 10: case GroupCode_XComp:
block.base.x = reader.ValueAsFloat(); block.base.x = reader.ValueAsFloat();
break; break;
case 20: case GroupCode_YComp:
block.base.y = reader.ValueAsFloat(); block.base.y = reader.ValueAsFloat();
break; break;
case 30: case GroupCode_ZComp:
block.base.z = reader.ValueAsFloat(); block.base.z = reader.ValueAsFloat();
break; break;
} }
@ -525,9 +522,8 @@ void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output) {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output) void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output) {
{ // Push a new block onto the stack.
// push a new block onto the stack.
output.blocks.push_back( DXF::Block() ); output.blocks.push_back( DXF::Block() );
DXF::Block& block = output.blocks.back(); DXF::Block& block = output.blocks.back();
@ -557,27 +553,25 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
" inserted blocks in ENTITIES" ); " inserted blocks in ENTITIES" );
} }
void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output) void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output) {
{
output.blocks.back().insertions.push_back( DXF::InsertBlock() ); output.blocks.back().insertions.push_back( DXF::InsertBlock() );
DXF::InsertBlock& bl = output.blocks.back().insertions.back(); DXF::InsertBlock& bl = output.blocks.back().insertions.back();
while( !reader.End() && !reader.Is(0)) { while( !reader.End() && !reader.Is(0)) {
switch(reader.GroupCode()) switch(reader.GroupCode()) {
{
// name of referenced block // name of referenced block
case 2: case GroupCode_Name:
bl.name = reader.Value(); bl.name = reader.Value();
break; break;
// translation // translation
case 10: case GroupCode_XComp:
bl.pos.x = reader.ValueAsFloat(); bl.pos.x = reader.ValueAsFloat();
break; break;
case 20: case GroupCode_YComp:
bl.pos.y = reader.ValueAsFloat(); bl.pos.y = reader.ValueAsFloat();
break; break;
case 30: case GroupCode_ZComp:
bl.pos.z = reader.ValueAsFloat(); bl.pos.z = reader.ValueAsFloat();
break; break;
@ -704,8 +698,7 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
#define DXF_VERTEX_FLAG_HAS_POSITIONS 0x40 #define DXF_VERTEX_FLAG_HAS_POSITIONS 0x40
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& line) void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& line) {
{
unsigned int cnti = 0, flags = 0; unsigned int cnti = 0, flags = 0;
unsigned int indices[4]; unsigned int indices[4];
@ -718,8 +711,7 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
break; break;
} }
switch (reader.GroupCode()) switch (reader.GroupCode()) {
{
case 8: case 8:
// layer to which the vertex belongs to - assume that // layer to which the vertex belongs to - assume that
// this is always the layer the top-level poly-line // this is always the layer the top-level poly-line
@ -734,9 +726,17 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
break; break;
// VERTEX COORDINATES // VERTEX COORDINATES
case 10: out.x = reader.ValueAsFloat();break; case GroupCode_XComp:
case 20: out.y = reader.ValueAsFloat();break; out.x = reader.ValueAsFloat();
case 30: out.z = reader.ValueAsFloat();break; break;
case GroupCode_YComp:
out.y = reader.ValueAsFloat();
break;
case GroupCode_ZComp:
out.z = reader.ValueAsFloat();
break;
// POLYFACE vertex indices // POLYFACE vertex indices
case 71: case 71:
@ -770,6 +770,10 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
if (indices[i] == 0) { if (indices[i] == 0) {
ASSIMP_LOG_WARN("DXF: invalid vertex index, indices are one-based."); ASSIMP_LOG_WARN("DXF: invalid vertex index, indices are one-based.");
--line.counts.back(); --line.counts.back();
// Workaround to fix issue 2229
if (line.counts.back() == 0) {
line.counts.pop_back();
}
continue; continue;
} }
line.indices.push_back(indices[i]-1); line.indices.push_back(indices[i]-1);
@ -808,62 +812,74 @@ void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
break; break;
// x position of the first corner // x position of the first corner
case 10: vip[0].x = reader.ValueAsFloat(); case 10:
vip[0].x = reader.ValueAsFloat();
b[2] = true; b[2] = true;
break; break;
// y position of the first corner // y position of the first corner
case 20: vip[0].y = reader.ValueAsFloat(); case 20:
vip[0].y = reader.ValueAsFloat();
b[2] = true; b[2] = true;
break; break;
// z position of the first corner // z position of the first corner
case 30: vip[0].z = reader.ValueAsFloat(); case 30:
vip[0].z = reader.ValueAsFloat();
b[2] = true; b[2] = true;
break; break;
// x position of the second corner // x position of the second corner
case 11: vip[1].x = reader.ValueAsFloat(); case 11:
vip[1].x = reader.ValueAsFloat();
b[3] = true; b[3] = true;
break; break;
// y position of the second corner // y position of the second corner
case 21: vip[1].y = reader.ValueAsFloat(); case 21:
vip[1].y = reader.ValueAsFloat();
b[3] = true; b[3] = true;
break; break;
// z position of the second corner // z position of the second corner
case 31: vip[1].z = reader.ValueAsFloat(); case 31:
vip[1].z = reader.ValueAsFloat();
b[3] = true; b[3] = true;
break; break;
// x position of the third corner // x position of the third corner
case 12: vip[2].x = reader.ValueAsFloat(); case 12:
vip[2].x = reader.ValueAsFloat();
b[0] = true; b[0] = true;
break; break;
// y position of the third corner // y position of the third corner
case 22: vip[2].y = reader.ValueAsFloat(); case 22:
vip[2].y = reader.ValueAsFloat();
b[0] = true; b[0] = true;
break; break;
// z position of the third corner // z position of the third corner
case 32: vip[2].z = reader.ValueAsFloat(); case 32:
vip[2].z = reader.ValueAsFloat();
b[0] = true; b[0] = true;
break; break;
// x position of the fourth corner // x position of the fourth corner
case 13: vip[3].x = reader.ValueAsFloat(); case 13:
vip[3].x = reader.ValueAsFloat();
b[1] = true; b[1] = true;
break; break;
// y position of the fourth corner // y position of the fourth corner
case 23: vip[3].y = reader.ValueAsFloat(); case 23:
vip[3].y = reader.ValueAsFloat();
b[1] = true; b[1] = true;
break; break;
// z position of the fourth corner // z position of the fourth corner
case 33: vip[3].z = reader.ValueAsFloat(); case 33:
vip[3].z = reader.ValueAsFloat();
b[1] = true; b[1] = true;
break; break;

View File

@ -50,32 +50,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <map> #include <map>
namespace Assimp { namespace Assimp {
namespace DXF {
class LineReader; // Forward declarations
struct FileData; namespace DXF {
struct PolyLine; class LineReader;
struct Block; struct FileData;
struct InsertBlock; struct PolyLine;
struct Block;
typedef std::map<std::string, const DXF::Block*> BlockMap; struct InsertBlock;
}
typedef std::map<std::string, const DXF::Block*> BlockMap;
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** DXF importer implementation. /**
* * @brief DXF importer implementation.
*/ */
class DXFImporter : public BaseImporter class DXFImporter : public BaseImporter {
{
public: public:
DXFImporter(); DXFImporter();
~DXFImporter(); ~DXFImporter();
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. */
@ -83,7 +78,6 @@ public:
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details*/ * See #BaseImporter::GetInfo for the details*/

View File

@ -52,9 +52,7 @@ namespace Assimp {
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
/** @brief Internal default implementation of the #ProgressHandler interface. */ /** @brief Internal default implementation of the #ProgressHandler interface. */
class DefaultProgressHandler class DefaultProgressHandler : public ProgressHandler {
: public ProgressHandler {
virtual bool Update(float /*percentage*/) { virtual bool Update(float /*percentage*/) {
return false; return false;

View File

@ -0,0 +1,109 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
/** @file Implementation of the post processing step to drop face
* normals for all imported faces.
*/
#include "DropFaceNormalsProcess.h"
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Exceptional.h>
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
DropFaceNormalsProcess::DropFaceNormalsProcess()
{
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
DropFaceNormalsProcess::~DropFaceNormalsProcess()
{
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool DropFaceNormalsProcess::IsActive( unsigned int pFlags) const {
return (pFlags & aiProcess_DropNormals) != 0;
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void DropFaceNormalsProcess::Execute( aiScene* pScene) {
ASSIMP_LOG_DEBUG("DropFaceNormalsProcess begin");
if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
}
bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
bHas |= this->DropMeshFaceNormals( pScene->mMeshes[a]);
}
if (bHas) {
ASSIMP_LOG_INFO("DropFaceNormalsProcess finished. "
"Face normals have been removed");
} else {
ASSIMP_LOG_DEBUG("DropFaceNormalsProcess finished. "
"No normals were present");
}
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
bool DropFaceNormalsProcess::DropMeshFaceNormals (aiMesh* pMesh) {
if (NULL == pMesh->mNormals) {
return false;
}
delete[] pMesh->mNormals;
pMesh->mNormals = nullptr;
return true;
}

View File

@ -0,0 +1,86 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
----------------------------------------------------------------------
*/
/** @file Defines a post processing step to compute face normals for all loaded faces*/
#ifndef AI_DROPFACENORMALPROCESS_H_INC
#define AI_DROPFACENORMALPROCESS_H_INC
#include "BaseProcess.h"
#include <assimp/mesh.h>
namespace Assimp
{
// ---------------------------------------------------------------------------
/** The DropFaceNormalsProcess computes face normals for all faces of all meshes
*/
class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess
{
public:
DropFaceNormalsProcess();
~DropFaceNormalsProcess();
public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise
* combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not.
*/
bool IsActive( unsigned int pFlags) const;
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
*/
void Execute( aiScene* pScene);
private:
bool DropMeshFaceNormals(aiMesh* pcMesh);
};
} // end of namespace Assimp
#endif // !!AI_DROPFACENORMALPROCESS_H_INC

View File

@ -119,7 +119,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
} }
} }
aiTexel* imageContent = new aiTexel[1u + imageSize / sizeof(aiTexel)]; aiTexel* imageContent = new aiTexel[ 1ul + static_cast<unsigned long>( imageSize ) / sizeof(aiTexel)];
file.seekg(0, std::ios::beg); file.seekg(0, std::ios::beg);
file.read(reinterpret_cast<char*>(imageContent), imageSize); file.read(reinterpret_cast<char*>(imageContent), imageSize);

View File

@ -56,22 +56,22 @@ Here we implement only the C++ interface (Assimp::Exporter).
#include <assimp/BlobIOSystem.h> #include <assimp/BlobIOSystem.h>
#include <assimp/SceneCombiner.h> #include <assimp/SceneCombiner.h>
#include "BaseProcess.h" #include <assimp/DefaultIOSystem.h>
#include "Importer.h" // need this for GetPostProcessingStepInstanceList() #include <assimp/Exporter.hpp>
#include <assimp/mesh.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include "DefaultProgressHandler.h"
#include "BaseProcess.h"
#include "JoinVerticesProcess.h" #include "JoinVerticesProcess.h"
#include "MakeVerboseFormat.h" #include "MakeVerboseFormat.h"
#include "ConvertToLHProcess.h" #include "ConvertToLHProcess.h"
#include "PretransformVertices.h" #include "PretransformVertices.h"
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include "ScenePrivate.h" #include "ScenePrivate.h"
#include <memory>
#include <assimp/DefaultIOSystem.h> #include <memory>
#include <assimp/Exporter.hpp>
#include <assimp/mesh.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
namespace Assimp { namespace Assimp {
@ -188,10 +188,14 @@ Exporter::ExportFormatEntry gExporters[] =
class ExporterPimpl { class ExporterPimpl {
public: public:
ExporterPimpl() ExporterPimpl()
: blob() : blob()
, mIOSystem(new Assimp::DefaultIOSystem()) , mIOSystem(new Assimp::DefaultIOSystem())
, mIsDefaultIOHandler(true) , mIsDefaultIOHandler(true)
{ , mProgressHandler( nullptr )
, mIsDefaultProgressHandler( true )
, mPostProcessingSteps()
, mError()
, mExporters() {
GetPostProcessingStepInstanceList(mPostProcessingSteps); GetPostProcessingStepInstanceList(mPostProcessingSteps);
// grab all built-in exporters // grab all built-in exporters
@ -201,14 +205,14 @@ public:
} }
} }
~ExporterPimpl() ~ExporterPimpl() {
{
delete blob; delete blob;
// Delete all post-processing plug-ins // Delete all post-processing plug-ins
for( unsigned int a = 0; a < mPostProcessingSteps.size(); a++) { for( unsigned int a = 0; a < mPostProcessingSteps.size(); a++) {
delete mPostProcessingSteps[a]; delete mPostProcessingSteps[a];
} }
delete mProgressHandler;
} }
public: public:
@ -216,6 +220,10 @@ public:
std::shared_ptr< Assimp::IOSystem > mIOSystem; std::shared_ptr< Assimp::IOSystem > mIOSystem;
bool mIsDefaultIOHandler; bool mIsDefaultIOHandler;
/** The progress handler */
ProgressHandler *mProgressHandler;
bool mIsDefaultProgressHandler;
/** Post processing steps we can apply at the imported data. */ /** Post processing steps we can apply at the imported data. */
std::vector< BaseProcess* > mPostProcessingSteps; std::vector< BaseProcess* > mPostProcessingSteps;
@ -233,13 +241,12 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Exporter :: Exporter() Exporter :: Exporter()
: pimpl(new ExporterPimpl()) { : pimpl(new ExporterPimpl()) {
// empty pimpl->mProgressHandler = new DefaultProgressHandler();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Exporter::~Exporter() { Exporter::~Exporter() {
FreeBlob(); FreeBlob();
delete pimpl; delete pimpl;
} }
@ -259,12 +266,32 @@ bool Exporter::IsDefaultIOHandler() const {
return pimpl->mIsDefaultIOHandler; return pimpl->mIsDefaultIOHandler;
} }
// ------------------------------------------------------------------------------------------------
void Exporter::SetProgressHandler(ProgressHandler* pHandler) {
ai_assert(nullptr != pimpl);
if ( nullptr == pHandler) {
// Release pointer in the possession of the caller
pimpl->mProgressHandler = new DefaultProgressHandler();
pimpl->mIsDefaultProgressHandler = true;
return;
}
if (pimpl->mProgressHandler == pHandler) {
return;
}
delete pimpl->mProgressHandler;
pimpl->mProgressHandler = pHandler;
pimpl->mIsDefaultProgressHandler = false;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId, const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
unsigned int, const ExportProperties* /*pProperties*/ ) { unsigned int, const ExportProperties* /*pProperties*/ ) {
if (pimpl->blob) { if (pimpl->blob) {
delete pimpl->blob; delete pimpl->blob;
pimpl->blob = NULL; pimpl->blob = nullptr;
} }
std::shared_ptr<IOSystem> old = pimpl->mIOSystem; std::shared_ptr<IOSystem> old = pimpl->mIOSystem;
@ -273,7 +300,7 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) { if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
pimpl->mIOSystem = old; pimpl->mIOSystem = old;
return NULL; return nullptr;
} }
pimpl->blob = blobio->GetBlobChain(); pimpl->blob = blobio->GetBlobChain();
@ -295,6 +322,7 @@ bool IsVerboseFormat(const aiMesh* mesh) {
} }
} }
} }
return true; return true;
} }
@ -305,6 +333,7 @@ bool IsVerboseFormat(const aiScene* pScene) {
return false; return false;
} }
} }
return true; return true;
} }
@ -319,6 +348,8 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
// 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) || IsVerboseFormat(pScene);
pimpl->mProgressHandler->UpdateFileWrite(0, 4);
pimpl->mError = ""; pimpl->mError = "";
for (size_t i = 0; i < pimpl->mExporters.size(); ++i) { for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i]; const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i];
@ -326,9 +357,11 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
try { try {
// Always create a full copy of the scene. We might optimize this one day, // Always create a full copy of the scene. We might optimize this one day,
// but for now it is the most pragmatic way. // but for now it is the most pragmatic way.
aiScene* scenecopy_tmp = NULL; aiScene* scenecopy_tmp = nullptr;
SceneCombiner::CopyScene(&scenecopy_tmp,pScene); SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
pimpl->mProgressHandler->UpdateFileWrite(1, 4);
std::unique_ptr<aiScene> scenecopy(scenecopy_tmp); std::unique_ptr<aiScene> scenecopy(scenecopy_tmp);
const ScenePrivateData* const priv = ScenePriv(pScene); const ScenePrivateData* const priv = ScenePriv(pScene);
@ -375,6 +408,8 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
} }
} }
pimpl->mProgressHandler->UpdateFileWrite(2, 4);
if (pp) { if (pp) {
// the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout // the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout
{ {
@ -418,11 +453,13 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
} }
} }
ScenePrivateData* const privOut = ScenePriv(scenecopy.get()); ScenePrivateData* const privOut = ScenePriv(scenecopy.get());
ai_assert(privOut); ai_assert(nullptr != privOut);
privOut->mPPStepsApplied |= pp; privOut->mPPStepsApplied |= pp;
} }
pimpl->mProgressHandler->UpdateFileWrite(3, 4);
if(must_join_again) { if(must_join_again) {
JoinVerticesProcess proc; JoinVerticesProcess proc;
proc.Execute(scenecopy.get()); proc.Execute(scenecopy.get());
@ -430,6 +467,8 @@ 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); exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
pimpl->mProgressHandler->UpdateFileWrite(4, 4);
} catch (DeadlyExportError& err) { } catch (DeadlyExportError& err) {
pimpl->mError = err.what(); pimpl->mError = err.what();
return AI_FAILURE; return AI_FAILURE;
@ -452,7 +491,7 @@ const char* Exporter::GetErrorString() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Exporter::FreeBlob() { void Exporter::FreeBlob() {
delete pimpl->blob; delete pimpl->blob;
pimpl->blob = NULL; pimpl->blob = nullptr;
pimpl->mError = ""; pimpl->mError = "";
} }
@ -465,7 +504,7 @@ const aiExportDataBlob* Exporter::GetBlob() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiExportDataBlob* Exporter::GetOrphanedBlob() const { const aiExportDataBlob* Exporter::GetOrphanedBlob() const {
const aiExportDataBlob* tmp = pimpl->blob; const aiExportDataBlob* tmp = pimpl->blob;
pimpl->blob = NULL; pimpl->blob = nullptr;
return tmp; return tmp;
} }
@ -545,75 +584,63 @@ bool ExportProperties::SetPropertyString(const char* szName, const std::string&
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Set a configuration property // Set a configuration property
bool ExportProperties :: SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) bool ExportProperties::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) {
{
return SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value); return SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a configuration property // Get a configuration property
int ExportProperties :: GetPropertyInteger(const char* szName, int ExportProperties::GetPropertyInteger(const char* szName, int iErrorReturn /*= 0xffffffff*/) const {
int iErrorReturn /*= 0xffffffff*/) const
{
return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn); return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a configuration property // Get a configuration property
ai_real ExportProperties :: GetPropertyFloat(const char* szName, ai_real ExportProperties::GetPropertyFloat(const char* szName, ai_real iErrorReturn /*= 10e10*/) const {
ai_real iErrorReturn /*= 10e10*/) const
{
return GetGenericProperty<ai_real>(mFloatProperties,szName,iErrorReturn); return GetGenericProperty<ai_real>(mFloatProperties,szName,iErrorReturn);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a configuration property // Get a configuration property
const std::string ExportProperties :: GetPropertyString(const char* szName, const std::string ExportProperties::GetPropertyString(const char* szName,
const std::string& iErrorReturn /*= ""*/) const const std::string& iErrorReturn /*= ""*/) const {
{
return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn); return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
const aiMatrix4x4 ExportProperties :: GetPropertyMatrix(const char* szName, const aiMatrix4x4 ExportProperties::GetPropertyMatrix(const char* szName,
const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const {
{
return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn); return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
bool ExportProperties :: HasPropertyInteger(const char* szName) const bool ExportProperties::HasPropertyInteger(const char* szName) const {
{
return HasGenericProperty<int>(mIntProperties, szName); return HasGenericProperty<int>(mIntProperties, szName);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
bool ExportProperties :: HasPropertyBool(const char* szName) const bool ExportProperties::HasPropertyBool(const char* szName) const {
{
return HasGenericProperty<int>(mIntProperties, szName); return HasGenericProperty<int>(mIntProperties, szName);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
bool ExportProperties :: HasPropertyFloat(const char* szName) const bool ExportProperties::HasPropertyFloat(const char* szName) const {
{
return HasGenericProperty<ai_real>(mFloatProperties, szName); return HasGenericProperty<ai_real>(mFloatProperties, szName);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
bool ExportProperties :: HasPropertyString(const char* szName) const bool ExportProperties::HasPropertyString(const char* szName) const {
{
return HasGenericProperty<std::string>(mStringProperties, szName); return HasGenericProperty<std::string>(mStringProperties, szName);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
bool ExportProperties :: HasPropertyMatrix(const char* szName) const bool ExportProperties::HasPropertyMatrix(const char* szName) const {
{
return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName); return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName);
} }

View File

@ -73,7 +73,7 @@ using namespace Util;
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
Converter::Converter( aiScene* out, const Document& doc ) FBXConverter::FBXConverter( aiScene* out, const Document& doc )
: defaultMaterialIndex() : defaultMaterialIndex()
, out( out ) , out( out )
, doc( doc ) { , doc( doc ) {
@ -114,7 +114,7 @@ Converter::Converter( aiScene* out, const Document& doc )
} }
Converter::~Converter() { FBXConverter::~FBXConverter() {
std::for_each( meshes.begin(), meshes.end(), Util::delete_fun<aiMesh>() ); std::for_each( meshes.begin(), meshes.end(), Util::delete_fun<aiMesh>() );
std::for_each( materials.begin(), materials.end(), Util::delete_fun<aiMaterial>() ); std::for_each( materials.begin(), materials.end(), Util::delete_fun<aiMaterial>() );
std::for_each( animations.begin(), animations.end(), Util::delete_fun<aiAnimation>() ); std::for_each( animations.begin(), animations.end(), Util::delete_fun<aiAnimation>() );
@ -123,7 +123,7 @@ Converter::~Converter() {
std::for_each( textures.begin(), textures.end(), Util::delete_fun<aiTexture>() ); std::for_each( textures.begin(), textures.end(), Util::delete_fun<aiTexture>() );
} }
void Converter::ConvertRootNode() { void FBXConverter::ConvertRootNode() {
out->mRootNode = new aiNode(); out->mRootNode = new aiNode();
out->mRootNode->mName.Set( "RootNode" ); out->mRootNode->mName.Set( "RootNode" );
@ -131,7 +131,7 @@ void Converter::ConvertRootNode() {
ConvertNodes( 0L, *out->mRootNode ); ConvertNodes( 0L, *out->mRootNode );
} }
void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform ) { void FBXConverter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform ) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" ); const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" );
std::vector<aiNode*> nodes; std::vector<aiNode*> nodes;
@ -185,12 +185,8 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
} }
if ( !name_carrier ) { if ( !name_carrier ) {
NodeNameCache::const_iterator it( std::find( mNodeNames.begin(), mNodeNames.end(), original_name ) ); std::string old_original_name = original_name;
if ( it != mNodeNames.end() ) { GetUniqueName(old_original_name, original_name);
original_name = original_name + std::string( "001" );
}
mNodeNames.push_back( original_name );
nodes_chain.push_back( new aiNode( original_name ) ); nodes_chain.push_back( new aiNode( original_name ) );
} else { } else {
original_name = nodes_chain.back()->mName.C_Str(); original_name = nodes_chain.back()->mName.C_Str();
@ -282,7 +278,7 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
} }
void Converter::ConvertLights( const Model& model, const std::string &orig_name ) { void FBXConverter::ConvertLights( const Model& model, const std::string &orig_name ) {
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
for( const NodeAttribute* attr : node_attrs ) { for( const NodeAttribute* attr : node_attrs ) {
const Light* const light = dynamic_cast<const Light*>( attr ); const Light* const light = dynamic_cast<const Light*>( attr );
@ -292,7 +288,7 @@ void Converter::ConvertLights( const Model& model, const std::string &orig_name
} }
} }
void Converter::ConvertCameras( const Model& model, const std::string &orig_name ) { void FBXConverter::ConvertCameras( const Model& model, const std::string &orig_name ) {
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
for( const NodeAttribute* attr : node_attrs ) { for( const NodeAttribute* attr : node_attrs ) {
const Camera* const cam = dynamic_cast<const Camera*>( attr ); const Camera* const cam = dynamic_cast<const Camera*>( attr );
@ -302,7 +298,7 @@ void Converter::ConvertCameras( const Model& model, const std::string &orig_name
} }
} }
void Converter::ConvertLight( const Light& light, const std::string &orig_name ) { void FBXConverter::ConvertLight( const Light& light, const std::string &orig_name ) {
lights.push_back( new aiLight() ); lights.push_back( new aiLight() );
aiLight* const out_light = lights.back(); aiLight* const out_light = lights.back();
@ -379,7 +375,7 @@ void Converter::ConvertLight( const Light& light, const std::string &orig_name )
} }
} }
void Converter::ConvertCamera( const Camera& cam, const std::string &orig_name ) void FBXConverter::ConvertCamera( const Camera& cam, const std::string &orig_name )
{ {
cameras.push_back( new aiCamera() ); cameras.push_back( new aiCamera() );
aiCamera* const out_camera = cameras.back(); aiCamera* const out_camera = cameras.back();
@ -398,134 +394,120 @@ void Converter::ConvertCamera( const Camera& cam, const std::string &orig_name )
out_camera->mClipPlaneFar = cam.FarPlane(); out_camera->mClipPlaneFar = cam.FarPlane();
} }
static bool HasName( NodeNameCache &cache, const std::string &name ) { void FBXConverter::GetUniqueName( const std::string &name, std::string &uniqueName )
NodeNameCache::const_iterator it( std::find( cache.begin(), cache.end(), name ) ); {
return it != cache.end(); int i = 0;
uniqueName = name;
} while (mNodeNames.find(uniqueName) != mNodeNames.end())
void Converter::GetUniqueName( const std::string &name, std::string &uniqueName ) { {
if ( !HasName( mNodeNames, name ) ) {
uniqueName = name;
mNodeNames.push_back( uniqueName );
return;
}
int i( 0 );
std::string newName( name );
while ( HasName( mNodeNames, newName ) ) {
++i; ++i;
newName.clear();
newName += name;
std::stringstream ext; std::stringstream ext;
ext << std::setfill( '0' ) << std::setw( 3 ) << i; ext << name << std::setfill('0') << std::setw(3) << i;
newName += ext.str(); uniqueName = ext.str();
} }
uniqueName = newName; mNodeNames.insert(uniqueName);
mNodeNames.push_back( uniqueName );
} }
const char* Converter::NameTransformationComp( TransformationComp comp ) const char* FBXConverter::NameTransformationComp( TransformationComp comp ) {
{ switch ( comp ) {
switch ( comp ) case TransformationComp_Translation:
{ return "Translation";
case TransformationComp_Translation: case TransformationComp_RotationOffset:
return "Translation"; return "RotationOffset";
case TransformationComp_RotationOffset: case TransformationComp_RotationPivot:
return "RotationOffset"; return "RotationPivot";
case TransformationComp_RotationPivot: case TransformationComp_PreRotation:
return "RotationPivot"; return "PreRotation";
case TransformationComp_PreRotation: case TransformationComp_Rotation:
return "PreRotation"; return "Rotation";
case TransformationComp_Rotation: case TransformationComp_PostRotation:
return "Rotation"; return "PostRotation";
case TransformationComp_PostRotation: case TransformationComp_RotationPivotInverse:
return "PostRotation"; return "RotationPivotInverse";
case TransformationComp_RotationPivotInverse: case TransformationComp_ScalingOffset:
return "RotationPivotInverse"; return "ScalingOffset";
case TransformationComp_ScalingOffset: case TransformationComp_ScalingPivot:
return "ScalingOffset"; return "ScalingPivot";
case TransformationComp_ScalingPivot: case TransformationComp_Scaling:
return "ScalingPivot"; return "Scaling";
case TransformationComp_Scaling: case TransformationComp_ScalingPivotInverse:
return "Scaling"; return "ScalingPivotInverse";
case TransformationComp_ScalingPivotInverse: case TransformationComp_GeometricScaling:
return "ScalingPivotInverse"; return "GeometricScaling";
case TransformationComp_GeometricScaling: case TransformationComp_GeometricRotation:
return "GeometricScaling"; return "GeometricRotation";
case TransformationComp_GeometricRotation: case TransformationComp_GeometricTranslation:
return "GeometricRotation"; return "GeometricTranslation";
case TransformationComp_GeometricTranslation: case TransformationComp_GeometricScalingInverse:
return "GeometricTranslation"; return "GeometricScalingInverse";
case TransformationComp_GeometricScalingInverse: case TransformationComp_GeometricRotationInverse:
return "GeometricScalingInverse"; return "GeometricRotationInverse";
case TransformationComp_GeometricRotationInverse: case TransformationComp_GeometricTranslationInverse:
return "GeometricRotationInverse"; return "GeometricTranslationInverse";
case TransformationComp_GeometricTranslationInverse: case TransformationComp_MAXIMUM: // this is to silence compiler warnings
return "GeometricTranslationInverse"; default:
case TransformationComp_MAXIMUM: // this is to silence compiler warnings break;
default:
break;
} }
ai_assert( false ); ai_assert( false );
return NULL;
return nullptr;
} }
const char* Converter::NameTransformationCompProperty( TransformationComp comp ) const char* FBXConverter::NameTransformationCompProperty( TransformationComp comp ) {
{ switch ( comp ) {
switch ( comp ) case TransformationComp_Translation:
{ return "Lcl Translation";
case TransformationComp_Translation: case TransformationComp_RotationOffset:
return "Lcl Translation"; return "RotationOffset";
case TransformationComp_RotationOffset: case TransformationComp_RotationPivot:
return "RotationOffset"; return "RotationPivot";
case TransformationComp_RotationPivot: case TransformationComp_PreRotation:
return "RotationPivot"; return "PreRotation";
case TransformationComp_PreRotation: case TransformationComp_Rotation:
return "PreRotation"; return "Lcl Rotation";
case TransformationComp_Rotation: case TransformationComp_PostRotation:
return "Lcl Rotation"; return "PostRotation";
case TransformationComp_PostRotation: case TransformationComp_RotationPivotInverse:
return "PostRotation"; return "RotationPivotInverse";
case TransformationComp_RotationPivotInverse: case TransformationComp_ScalingOffset:
return "RotationPivotInverse"; return "ScalingOffset";
case TransformationComp_ScalingOffset: case TransformationComp_ScalingPivot:
return "ScalingOffset"; return "ScalingPivot";
case TransformationComp_ScalingPivot: case TransformationComp_Scaling:
return "ScalingPivot"; return "Lcl Scaling";
case TransformationComp_Scaling: case TransformationComp_ScalingPivotInverse:
return "Lcl Scaling"; return "ScalingPivotInverse";
case TransformationComp_ScalingPivotInverse: case TransformationComp_GeometricScaling:
return "ScalingPivotInverse"; return "GeometricScaling";
case TransformationComp_GeometricScaling: case TransformationComp_GeometricRotation:
return "GeometricScaling"; return "GeometricRotation";
case TransformationComp_GeometricRotation: case TransformationComp_GeometricTranslation:
return "GeometricRotation"; return "GeometricTranslation";
case TransformationComp_GeometricTranslation: case TransformationComp_GeometricScalingInverse:
return "GeometricTranslation"; return "GeometricScalingInverse";
case TransformationComp_GeometricScalingInverse: case TransformationComp_GeometricRotationInverse:
return "GeometricScalingInverse"; return "GeometricRotationInverse";
case TransformationComp_GeometricRotationInverse: case TransformationComp_GeometricTranslationInverse:
return "GeometricRotationInverse"; return "GeometricTranslationInverse";
case TransformationComp_GeometricTranslationInverse: case TransformationComp_MAXIMUM: // this is to silence compiler warnings
return "GeometricTranslationInverse"; break;
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
break;
} }
ai_assert( false ); ai_assert( false );
return NULL;
return nullptr;
} }
aiVector3D Converter::TransformationCompDefaultValue( TransformationComp comp ) aiVector3D FBXConverter::TransformationCompDefaultValue( TransformationComp comp )
{ {
// XXX a neat way to solve the never-ending special cases for scaling // XXX a neat way to solve the never-ending special cases for scaling
// would be to do everything in log space! // would be to do everything in log space!
return comp == TransformationComp_Scaling ? aiVector3D( 1.f, 1.f, 1.f ) : aiVector3D(); return comp == TransformationComp_Scaling ? aiVector3D( 1.f, 1.f, 1.f ) : aiVector3D();
} }
void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out ) void FBXConverter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out )
{ {
if ( mode == Model::RotOrder_SphericXYZ ) { if ( mode == Model::RotOrder_SphericXYZ ) {
FBXImporter::LogError( "Unsupported RotationMode: SphericXYZ" ); FBXImporter::LogError( "Unsupported RotationMode: SphericXYZ" );
@ -596,11 +578,15 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
default: default:
ai_assert( false ); ai_assert( false );
break;
} }
ai_assert( ( order[ 0 ] >= 0 ) && ( order[ 0 ] <= 2 ) ); ai_assert( order[ 0 ] >= 0 );
ai_assert( ( order[ 1 ] >= 0 ) && ( order[ 1 ] <= 2 ) ); ai_assert( order[ 0 ] <= 2 );
ai_assert( ( order[ 2 ] >= 0 ) && ( order[ 2 ] <= 2 ) ); ai_assert( order[ 1 ] >= 0 );
ai_assert( order[ 1 ] <= 2 );
ai_assert( order[ 2 ] >= 0 );
ai_assert( order[ 2 ] <= 2 );
if ( !is_id[ order[ 0 ] ] ) { if ( !is_id[ order[ 0 ] ] ) {
out = temp[ order[ 0 ] ]; out = temp[ order[ 0 ] ];
@ -615,7 +601,7 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
} }
} }
bool Converter::NeedsComplexTransformationChain( const Model& model ) bool FBXConverter::NeedsComplexTransformationChain( const Model& model )
{ {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
bool ok; bool ok;
@ -646,13 +632,13 @@ bool Converter::NeedsComplexTransformationChain( const Model& model )
return false; return false;
} }
std::string Converter::NameTransformationChainNode( const std::string& name, TransformationComp comp ) std::string FBXConverter::NameTransformationChainNode( const std::string& name, TransformationComp comp )
{ {
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp ); return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
} }
void Converter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes ) void FBXConverter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes,
{ std::vector<aiNode*>& post_output_nodes ) {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
const Model::RotOrder rot = model.RotationOrder(); const Model::RotOrder rot = model.RotationOrder();
@ -823,7 +809,7 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
} }
} }
void Converter::SetupNodeMetadata( const Model& model, aiNode& nd ) void FBXConverter::SetupNodeMetadata( const Model& model, aiNode& nd )
{ {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
DirectPropertyMap unparsedProperties = props.GetUnparsedProperties(); DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
@ -860,7 +846,7 @@ void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
} }
} }
void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform ) void FBXConverter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform )
{ {
const std::vector<const Geometry*>& geos = model.GetGeometry(); const std::vector<const Geometry*>& geos = model.GetGeometry();
@ -887,7 +873,7 @@ void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4&
} }
} }
std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> FBXConverter::ConvertMesh( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
std::vector<unsigned int> temp; std::vector<unsigned int> temp;
@ -922,7 +908,7 @@ std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, cons
return temp; return temp;
} }
aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd) aiMesh* FBXConverter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
{ {
aiMesh* const out_mesh = new aiMesh(); aiMesh* const out_mesh = new aiMesh();
meshes.push_back( out_mesh ); meshes.push_back( out_mesh );
@ -945,7 +931,7 @@ aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
return out_mesh; return out_mesh;
} }
unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model, unsigned int FBXConverter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
const MatIndexArray& mindices = mesh.GetMaterialIndices(); const MatIndexArray& mindices = mesh.GetMaterialIndices();
@ -1072,7 +1058,7 @@ unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, con
return static_cast<unsigned int>( meshes.size() - 1 ); return static_cast<unsigned int>( meshes.size() - 1 );
} }
std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> FBXConverter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
const MatIndexArray& mindices = mesh.GetMaterialIndices(); const MatIndexArray& mindices = mesh.GetMaterialIndices();
@ -1092,7 +1078,7 @@ std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometr
return indices; return indices;
} }
unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model, unsigned int FBXConverter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
MatIndexArray::value_type index, MatIndexArray::value_type index,
const aiMatrix4x4& node_global_transform, const aiMatrix4x4& node_global_transform,
aiNode& nd) aiNode& nd)
@ -1268,7 +1254,7 @@ unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, cons
return static_cast<unsigned int>( meshes.size() - 1 ); return static_cast<unsigned int>( meshes.size() - 1 );
} }
void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo, void FBXConverter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo,
const aiMatrix4x4& node_global_transform , const aiMatrix4x4& node_global_transform ,
unsigned int materialIndex, unsigned int materialIndex,
std::vector<unsigned int>* outputVertStartIndices ) std::vector<unsigned int>* outputVertStartIndices )
@ -1373,7 +1359,7 @@ void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeome
std::swap_ranges( bones.begin(), bones.end(), out->mBones ); std::swap_ranges( bones.begin(), bones.end(), out->mBones );
} }
void Converter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl, void FBXConverter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
std::vector<size_t>& out_indices, std::vector<size_t>& out_indices,
std::vector<size_t>& index_out_indices, std::vector<size_t>& index_out_indices,
std::vector<size_t>& count_out_indices, std::vector<size_t>& count_out_indices,
@ -1414,7 +1400,7 @@ void Converter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*mode
} }
} }
void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo, void FBXConverter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo,
MatIndexArray::value_type materialIndex ) MatIndexArray::value_type materialIndex )
{ {
// locate source materials for this mesh // locate source materials for this mesh
@ -1436,7 +1422,7 @@ void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const M
materials_converted[ mat ] = out->mMaterialIndex; materials_converted[ mat ] = out->mMaterialIndex;
} }
unsigned int Converter::GetDefaultMaterial() unsigned int FBXConverter::GetDefaultMaterial()
{ {
if ( defaultMaterialIndex ) { if ( defaultMaterialIndex ) {
return defaultMaterialIndex - 1; return defaultMaterialIndex - 1;
@ -1458,7 +1444,7 @@ unsigned int Converter::GetDefaultMaterial()
} }
unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeometry* const mesh ) unsigned int FBXConverter::ConvertMaterial( const Material& material, const MeshGeometry* const mesh )
{ {
const PropertyTable& props = material.Props(); const PropertyTable& props = material.Props();
@ -1493,7 +1479,7 @@ unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeo
return static_cast<unsigned int>( materials.size() - 1 ); return static_cast<unsigned int>( materials.size() - 1 );
} }
unsigned int Converter::ConvertVideo( const Video& video ) unsigned int FBXConverter::ConvertVideo( const Video& video )
{ {
// generate empty output texture // generate empty output texture
aiTexture* out_tex = new aiTexture(); aiTexture* out_tex = new aiTexture();
@ -1523,7 +1509,7 @@ unsigned int Converter::ConvertVideo( const Video& video )
return static_cast<unsigned int>( textures.size() - 1 ); return static_cast<unsigned int>( textures.size() - 1 );
} }
aiString Converter::GetTexturePath(const Texture* tex) aiString FBXConverter::GetTexturePath(const Texture* tex)
{ {
aiString path; aiString path;
path.Set(tex->RelativeFilename()); path.Set(tex->RelativeFilename());
@ -1563,7 +1549,7 @@ aiString Converter::GetTexturePath(const Texture* tex)
return path; return path;
} }
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, void FBXConverter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
const std::string& propName, const std::string& propName,
aiTextureType target, const MeshGeometry* const mesh ) aiTextureType target, const MeshGeometry* const mesh )
{ {
@ -1573,8 +1559,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
} }
const Texture* const tex = ( *it ).second; const Texture* const tex = ( *it ).second;
if ( tex != 0 ) if ( tex != nullptr ) {
{
aiString path = GetTexturePath(tex); aiString path = GetTexturePath(tex);
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 ); out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 );
@ -1681,7 +1666,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
} }
} }
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, void FBXConverter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
const std::string& propName, const std::string& propName,
aiTextureType target, const MeshGeometry* const mesh ) { aiTextureType target, const MeshGeometry* const mesh ) {
LayeredTextureMap::const_iterator it = layeredTextures.find( propName ); LayeredTextureMap::const_iterator it = layeredTextures.find( propName );
@ -1804,14 +1789,13 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextu
} }
} }
void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh ) void FBXConverter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh )
{ {
TrySetTextureProperties( out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE, mesh ); TrySetTextureProperties( out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
TrySetTextureProperties( out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh ); TrySetTextureProperties( out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh );
TrySetTextureProperties( out_mat, textures, "EmissiveColor", aiTextureType_EMISSIVE, mesh ); TrySetTextureProperties( out_mat, textures, "EmissiveFactor", aiTextureType_EMISSIVE, mesh );
TrySetTextureProperties( out_mat, textures, "SpecularColor", aiTextureType_SPECULAR, mesh );
TrySetTextureProperties( out_mat, textures, "SpecularFactor", aiTextureType_SPECULAR, mesh); TrySetTextureProperties( out_mat, textures, "SpecularFactor", aiTextureType_SPECULAR, mesh);
TrySetTextureProperties( out_mat, textures, "TransparentColor", aiTextureType_OPACITY, mesh ); TrySetTextureProperties( out_mat, textures, "TransparencyFactor", aiTextureType_OPACITY, mesh );
TrySetTextureProperties( out_mat, textures, "ReflectionColor", aiTextureType_REFLECTION, mesh ); TrySetTextureProperties( out_mat, textures, "ReflectionColor", aiTextureType_REFLECTION, mesh );
TrySetTextureProperties( out_mat, textures, "DisplacementColor", aiTextureType_DISPLACEMENT, mesh ); TrySetTextureProperties( out_mat, textures, "DisplacementColor", aiTextureType_DISPLACEMENT, mesh );
TrySetTextureProperties( out_mat, textures, "NormalMap", aiTextureType_NORMALS, mesh ); TrySetTextureProperties( out_mat, textures, "NormalMap", aiTextureType_NORMALS, mesh );
@ -1819,14 +1803,13 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& tex
TrySetTextureProperties( out_mat, textures, "ShininessExponent", aiTextureType_SHININESS, mesh ); TrySetTextureProperties( out_mat, textures, "ShininessExponent", aiTextureType_SHININESS, mesh );
} }
void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh ) void FBXConverter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh )
{ {
TrySetTextureProperties( out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
TrySetTextureProperties( out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh );
TrySetTextureProperties( out_mat, layeredTextures, "EmissiveColor", aiTextureType_EMISSIVE, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "EmissiveFactor", aiTextureType_EMISSIVE, mesh );
TrySetTextureProperties( out_mat, layeredTextures, "SpecularColor", aiTextureType_SPECULAR, mesh );
TrySetTextureProperties( out_mat, layeredTextures, "SpecularFactor", aiTextureType_SPECULAR, mesh); TrySetTextureProperties( out_mat, layeredTextures, "SpecularFactor", aiTextureType_SPECULAR, mesh);
TrySetTextureProperties( out_mat, layeredTextures, "TransparentColor", aiTextureType_OPACITY, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "TransparencyFactor", aiTextureType_OPACITY, mesh );
TrySetTextureProperties( out_mat, layeredTextures, "ReflectionColor", aiTextureType_REFLECTION, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "ReflectionColor", aiTextureType_REFLECTION, mesh );
TrySetTextureProperties( out_mat, layeredTextures, "DisplacementColor", aiTextureType_DISPLACEMENT, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "DisplacementColor", aiTextureType_DISPLACEMENT, mesh );
TrySetTextureProperties( out_mat, layeredTextures, "NormalMap", aiTextureType_NORMALS, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "NormalMap", aiTextureType_NORMALS, mesh );
@ -1834,7 +1817,7 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureM
TrySetTextureProperties( out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh );
} }
aiColor3D Converter::GetColorPropertyFactored( const PropertyTable& props, const std::string& colorName, aiColor3D FBXConverter::GetColorPropertyFactored( const PropertyTable& props, const std::string& colorName,
const std::string& factorName, bool& result, bool useTemplate ) const std::string& factorName, bool& result, bool useTemplate )
{ {
result = true; result = true;
@ -1859,13 +1842,13 @@ aiColor3D Converter::GetColorPropertyFactored( const PropertyTable& props, const
return aiColor3D( BaseColor.x, BaseColor.y, BaseColor.z ); return aiColor3D( BaseColor.x, BaseColor.y, BaseColor.z );
} }
aiColor3D Converter::GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName, aiColor3D FBXConverter::GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName,
bool& result ) bool& result )
{ {
return GetColorPropertyFactored( props, baseName + "Color", baseName + "Factor", result, true ); return GetColorPropertyFactored( props, baseName + "Color", baseName + "Factor", result, true );
} }
aiColor3D Converter::GetColorProperty( const PropertyTable& props, const std::string& colorName, aiColor3D FBXConverter::GetColorProperty( const PropertyTable& props, const std::string& colorName,
bool& result, bool useTemplate ) bool& result, bool useTemplate )
{ {
result = true; result = true;
@ -1878,7 +1861,7 @@ aiColor3D Converter::GetColorProperty( const PropertyTable& props, const std::st
return aiColor3D( ColorVec.x, ColorVec.y, ColorVec.z ); return aiColor3D( ColorVec.x, ColorVec.y, ColorVec.z );
} }
void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props ) void FBXConverter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props )
{ {
// Set shading properties. // Set shading properties.
// Modern FBX Files have two separate systems for defining these, // Modern FBX Files have two separate systems for defining these,
@ -1977,60 +1960,60 @@ void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyT
} }
double Converter::FrameRateToDouble( FileGlobalSettings::FrameRate fp, double customFPSVal ) double FBXConverter::FrameRateToDouble( FileGlobalSettings::FrameRate fp, double customFPSVal ) {
{
switch ( fp ) { switch ( fp ) {
case FileGlobalSettings::FrameRate_DEFAULT: case FileGlobalSettings::FrameRate_DEFAULT:
return 1.0; return 1.0;
case FileGlobalSettings::FrameRate_120: case FileGlobalSettings::FrameRate_120:
return 120.0; return 120.0;
case FileGlobalSettings::FrameRate_100: case FileGlobalSettings::FrameRate_100:
return 100.0; return 100.0;
case FileGlobalSettings::FrameRate_60: case FileGlobalSettings::FrameRate_60:
return 60.0; return 60.0;
case FileGlobalSettings::FrameRate_50: case FileGlobalSettings::FrameRate_50:
return 50.0; return 50.0;
case FileGlobalSettings::FrameRate_48: case FileGlobalSettings::FrameRate_48:
return 48.0; return 48.0;
case FileGlobalSettings::FrameRate_30: case FileGlobalSettings::FrameRate_30:
case FileGlobalSettings::FrameRate_30_DROP: case FileGlobalSettings::FrameRate_30_DROP:
return 30.0; return 30.0;
case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME: case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME:
case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME: case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME:
return 29.9700262; return 29.9700262;
case FileGlobalSettings::FrameRate_PAL: case FileGlobalSettings::FrameRate_PAL:
return 25.0; return 25.0;
case FileGlobalSettings::FrameRate_CINEMA: case FileGlobalSettings::FrameRate_CINEMA:
return 24.0; return 24.0;
case FileGlobalSettings::FrameRate_1000: case FileGlobalSettings::FrameRate_1000:
return 1000.0; return 1000.0;
case FileGlobalSettings::FrameRate_CINEMA_ND: case FileGlobalSettings::FrameRate_CINEMA_ND:
return 23.976; return 23.976;
case FileGlobalSettings::FrameRate_CUSTOM: case FileGlobalSettings::FrameRate_CUSTOM:
return customFPSVal; return customFPSVal;
case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings
break; break;
} }
ai_assert( false ); ai_assert( false );
return -1.0f; return -1.0f;
} }
void Converter::ConvertAnimations() void FBXConverter::ConvertAnimations()
{ {
// first of all determine framerate // first of all determine framerate
const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode(); const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode();
@ -2043,7 +2026,7 @@ void Converter::ConvertAnimations()
} }
} }
std::string Converter::FixNodeName( const std::string& name ) { std::string FBXConverter::FixNodeName( const std::string& name ) {
// strip Model:: prefix, avoiding ambiguities (i.e. don't strip if // strip Model:: prefix, avoiding ambiguities (i.e. don't strip if
// this causes ambiguities, well possible between empty identifiers, // this causes ambiguities, well possible between empty identifiers,
// such as "Model::" and ""). Make sure the behaviour is consistent // such as "Model::" and ""). Make sure the behaviour is consistent
@ -2056,7 +2039,7 @@ std::string Converter::FixNodeName( const std::string& name ) {
return name; return name;
} }
void Converter::ConvertAnimationStack( const AnimationStack& st ) void FBXConverter::ConvertAnimationStack( const AnimationStack& st )
{ {
const AnimationLayerList& layers = st.Layers(); const AnimationLayerList& layers = st.Layers();
if ( layers.empty() ) { if ( layers.empty() ) {
@ -2198,7 +2181,7 @@ static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>
#endif // ASSIMP_BUILD_DEBUG #endif // ASSIMP_BUILD_DEBUG
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims, void FBXConverter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
const std::string& fixed_name, const std::string& fixed_name,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
@ -2432,10 +2415,9 @@ void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
node_anim_chain_bits[ fixed_name ] = flags; node_anim_chain_bits[ fixed_name ] = flags;
} }
bool Converter::IsRedundantAnimationData( const Model& target, bool FBXConverter::IsRedundantAnimationData( const Model& target,
TransformationComp comp, TransformationComp comp,
const std::vector<const AnimationCurveNode*>& curves ) const std::vector<const AnimationCurveNode*>& curves ) {
{
ai_assert( curves.size() ); ai_assert( curves.size() );
// look for animation nodes with // look for animation nodes with
@ -2478,7 +2460,7 @@ bool Converter::IsRedundantAnimationData( const Model& target,
} }
aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name, aiNodeAnim* FBXConverter::GenerateRotationNodeAnim( const std::string& name,
const Model& target, const Model& target,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
@ -2508,7 +2490,7 @@ aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name, aiNodeAnim* FBXConverter::GenerateScalingNodeAnim( const std::string& name,
const Model& /*target*/, const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
@ -2538,16 +2520,14 @@ aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
aiNodeAnim* FBXConverter::GenerateTranslationNodeAnim( const std::string& name,
aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name, const Model& /*target*/,
const Model& /*target*/, const std::vector<const AnimationCurveNode*>& curves,
const std::vector<const AnimationCurveNode*>& curves, const LayerMap& layer_map,
const LayerMap& layer_map, int64_t start, int64_t stop,
int64_t start, int64_t stop, double& max_time,
double& max_time, double& min_time,
double& min_time, bool inverse ) {
bool inverse )
{
std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() ); std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
na->mNodeName.Set( name ); na->mNodeName.Set( name );
@ -2576,7 +2556,7 @@ aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name, aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim( const std::string& name,
const Model& target, const Model& target,
NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ], NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ],
NodeMap::const_iterator iter_end, NodeMap::const_iterator iter_end,
@ -2712,7 +2692,7 @@ aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop ) FBXConverter::KeyFrameListList FBXConverter::GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop )
{ {
KeyFrameListList inputs; KeyFrameListList inputs;
inputs.reserve( nodes.size() * 3 ); inputs.reserve( nodes.size() * 3 );
@ -2768,12 +2748,11 @@ Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const
} }
KeyTimeList Converter::GetKeyTimeList( const KeyFrameListList& inputs ) KeyTimeList FBXConverter::GetKeyTimeList( const KeyFrameListList& inputs ) {
{ ai_assert( !inputs.empty() );
ai_assert( inputs.size() );
// reserve some space upfront - it is likely that the keyframe lists // reserve some space upfront - it is likely that the key-frame lists
// have matching time values, so max(of all keyframe lists) should // have matching time values, so max(of all key-frame lists) should
// be a good estimate. // be a good estimate.
KeyTimeList keys; KeyTimeList keys;
@ -2817,17 +2796,15 @@ KeyTimeList Converter::GetKeyTimeList( const KeyFrameListList& inputs )
return keys; return keys;
} }
void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, void FBXConverter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
const aiVector3D& def_value, const aiVector3D& def_value,
double& max_time, double& max_time,
double& min_time ) double& min_time ) {
ai_assert( !keys.empty() );
{ ai_assert( nullptr != valOut );
ai_assert( keys.size() );
ai_assert( valOut );
std::vector<unsigned int> next_pos; std::vector<unsigned int> next_pos;
const size_t count = inputs.size(); const size_t count( inputs.size() );
next_pos.resize( inputs.size(), 0 ); next_pos.resize( inputs.size(), 0 );
@ -2838,6 +2815,9 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
const KeyFrameList& kfl = inputs[ i ]; const KeyFrameList& kfl = inputs[ i ];
const size_t ksize = std::get<0>(kfl)->size(); const size_t ksize = std::get<0>(kfl)->size();
if (ksize == 0) {
continue;
}
if ( ksize > next_pos[ i ] && std::get<0>(kfl)->at( next_pos[ i ] ) == time ) { if ( ksize > next_pos[ i ] && std::get<0>(kfl)->at( next_pos[ i ] ) == time ) {
++next_pos[ i ]; ++next_pos[ i ];
} }
@ -2872,14 +2852,14 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
} }
} }
void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, void FBXConverter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
const aiVector3D& def_value, const aiVector3D& def_value,
double& maxTime, double& maxTime,
double& minTime, double& minTime,
Model::RotOrder order ) Model::RotOrder order )
{ {
ai_assert( keys.size() ); ai_assert( !keys.empty() );
ai_assert( valOut ); ai_assert( nullptr != valOut );
std::unique_ptr<aiVectorKey[]> temp( new aiVectorKey[ keys.size() ] ); std::unique_ptr<aiVectorKey[]> temp( new aiVectorKey[ keys.size() ] );
InterpolateKeys( temp.get(), keys, inputs, def_value, maxTime, minTime ); InterpolateKeys( temp.get(), keys, inputs, def_value, maxTime, minTime );
@ -2910,7 +2890,7 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con
} }
} }
void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale, void FBXConverter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale,
aiVectorKey* out_translation, aiVectorKey* out_translation,
const KeyFrameListList& scaling, const KeyFrameListList& scaling,
const KeyFrameListList& translation, const KeyFrameListList& translation,
@ -2968,7 +2948,7 @@ void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey
} }
} }
aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order ) aiQuaternion FBXConverter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order )
{ {
aiMatrix4x4 m; aiMatrix4x4 m;
GetRotationMatrix( order, rot, m ); GetRotationMatrix( order, rot, m );
@ -2976,7 +2956,7 @@ aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrde
return aiQuaternion( aiMatrix3x3( m ) ); return aiQuaternion( aiMatrix3x3( m ) );
} }
void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/, void FBXConverter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
int64_t start, int64_t stop, int64_t start, int64_t stop,
double& maxTime, double& maxTime,
double& minTime ) double& minTime )
@ -2996,7 +2976,7 @@ void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const Animat
InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime ); InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime );
} }
void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, void FBXConverter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
const LayerMap& /*layers*/, const LayerMap& /*layers*/,
int64_t start, int64_t stop, int64_t start, int64_t stop,
double& maxTime, double& maxTime,
@ -3014,7 +2994,7 @@ void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const
InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime ); InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime );
} }
void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, void FBXConverter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
const LayerMap& /*layers*/, const LayerMap& /*layers*/,
int64_t start, int64_t stop, int64_t start, int64_t stop,
double& maxTime, double& maxTime,
@ -3034,7 +3014,7 @@ void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const Ani
} }
} }
void Converter::ConvertGlobalSettings() { void FBXConverter::ConvertGlobalSettings() {
if (nullptr == out) { if (nullptr == out) {
return; return;
} }
@ -3045,7 +3025,7 @@ void Converter::ConvertGlobalSettings() {
out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor); out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor);
} }
void Converter::TransferDataToScene() void FBXConverter::TransferDataToScene()
{ {
ai_assert( !out->mMeshes ); ai_assert( !out->mMeshes );
ai_assert( !out->mNumMeshes ); ai_assert( !out->mNumMeshes );
@ -3100,7 +3080,7 @@ void Converter::TransferDataToScene()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertToAssimpScene(aiScene* out, const Document& doc) void ConvertToAssimpScene(aiScene* out, const Document& doc)
{ {
Converter converter(out,doc); FBXConverter converter(out,doc);
} }
} // !FBX } // !FBX

View File

@ -68,7 +68,7 @@ namespace FBX {
class Document; class Document;
using NodeNameCache = std::vector<std::string>; using NodeNameCache = std::set<std::string>;
/** /**
* Convert a FBX #Document to #aiScene * Convert a FBX #Document to #aiScene
@ -78,7 +78,7 @@ using NodeNameCache = std::vector<std::string>;
void ConvertToAssimpScene(aiScene* out, const Document& doc); void ConvertToAssimpScene(aiScene* out, const Document& doc);
/** Dummy class to encapsulate the conversion process */ /** Dummy class to encapsulate the conversion process */
class Converter { class FBXConverter {
public: public:
/** /**
* The different parts that make up the final local transformation of a fbx-node * The different parts that make up the final local transformation of a fbx-node
@ -106,8 +106,8 @@ public:
}; };
public: public:
Converter(aiScene* out, const Document& doc); FBXConverter(aiScene* out, const Document& doc);
~Converter(); ~FBXConverter();
private: private:
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_AI_FBX_DOCUMENT_UTIL_H #ifndef INCLUDED_AI_FBX_DOCUMENT_UTIL_H
#define INCLUDED_AI_FBX_DOCUMENT_UTIL_H #define INCLUDED_AI_FBX_DOCUMENT_UTIL_H
#include "../include/assimp/defs.h" #include <assimp/defs.h>
#include <string> #include <string>
#include <memory> #include <memory>
#include "FBXDocument.h" #include "FBXDocument.h"

View File

@ -437,7 +437,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
// deal with this more elegantly and with less redundancy, but right // deal with this more elegantly and with less redundancy, but right
// now it seems unavoidable. // now it seems unavoidable.
if (MappingInformationType == "ByVertice" && isDirect) { if (MappingInformationType == "ByVertice" && isDirect) {
if (!HasElement(source, indexDataElementName)) { if (!HasElement(source, dataElementName)) {
return; return;
} }
std::vector<T> tempData; std::vector<T> tempData;

View File

@ -91,8 +91,10 @@ void FindDegeneratesProcess::SetupProperties(const Importer* pImp) {
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FindDegeneratesProcess::Execute( aiScene* pScene) { void FindDegeneratesProcess::Execute( aiScene* pScene) {
ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin"); ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){ for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
if (ExecuteOnMesh(pScene->mMeshes[i])) { {
//Do not process point cloud, ExecuteOnMesh works only with faces data
if ((pScene->mMeshes[i]->mPrimitiveTypes != aiPrimitiveType::aiPrimitiveType_POINT) && ExecuteOnMesh(pScene->mMeshes[i])) {
removeMesh(pScene, i); removeMesh(pScene, i);
--i; //the current i is removed, do not skip the next one --i; //the current i is removed, do not skip the next one
} }

View File

@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace HMP { namespace HMP {
#include "./../include/assimp/Compiler/pushpack1.h" #include <assimp/Compiler/pushpack1.h>
#include <stdint.h> #include <stdint.h>
// to make it easier for us, we test the magic word against both "endianesses" // to make it easier for us, we test the magic word against both "endianesses"
@ -131,7 +131,7 @@ struct Vertex_HMP7
int8_t normal_x,normal_y; int8_t normal_x,normal_y;
} PACK_STRUCT; } PACK_STRUCT;
#include "./../include/assimp/Compiler/poppack1.h" #include <assimp/Compiler/poppack1.h>
} //! namespace HMP } //! namespace HMP
} //! namespace Assimp } //! namespace Assimp

View File

@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MDLFILEHELPER2_H_INC #ifndef AI_MDLFILEHELPER2_H_INC
#define AI_MDLFILEHELPER2_H_INC #define AI_MDLFILEHELPER2_H_INC
#include "./../include/assimp/Compiler/pushpack1.h" #include <assimp/Compiler/pushpack1.h>
namespace Assimp { namespace Assimp {
namespace MDL { namespace MDL {
@ -141,7 +141,7 @@ struct Header_HL2 {
int32_t transitionindex; int32_t transitionindex;
} /* PACK_STRUCT */; } /* PACK_STRUCT */;
#include "./../include/assimp/Compiler/poppack1.h" #include <assimp/Compiler/poppack1.h>
} }
} // end namespaces } // end namespaces

View File

@ -178,7 +178,6 @@ Importer::~Importer()
{ {
// Delete all import plugins // Delete all import plugins
DeleteImporterInstanceList(pimpl->mImporter); DeleteImporterInstanceList(pimpl->mImporter);
aiReleaseDefaultMaterial();
// Delete all post-processing plug-ins // Delete all post-processing plug-ins
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)
@ -316,22 +315,19 @@ void Importer::SetIOHandler( IOSystem* pIOHandler)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get the currently set IO handler // Get the currently set IO handler
IOSystem* Importer::GetIOHandler() const IOSystem* Importer::GetIOHandler() const {
{
return pimpl->mIOHandler; return pimpl->mIOHandler;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Check whether a custom IO handler is currently set // Check whether a custom IO handler is currently set
bool Importer::IsDefaultIOHandler() const bool Importer::IsDefaultIOHandler() const {
{
return pimpl->mIsDefaultHandler; return pimpl->mIsDefaultHandler;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Supplies a custom progress handler to get regular callbacks during importing // Supplies a custom progress handler to get regular callbacks during importing
void Importer::SetProgressHandler ( ProgressHandler* pHandler ) void Importer::SetProgressHandler ( ProgressHandler* pHandler ) {
{
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
// If the new handler is zero, allocate a default implementation. // If the new handler is zero, allocate a default implementation.
if (!pHandler) if (!pHandler)
@ -352,15 +348,13 @@ void Importer::SetProgressHandler ( ProgressHandler* pHandler )
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get the currently set progress handler // Get the currently set progress handler
ProgressHandler* Importer::GetProgressHandler() const ProgressHandler* Importer::GetProgressHandler() const {
{
return pimpl->mProgressHandler; return pimpl->mProgressHandler;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Check whether a custom progress handler is currently set // Check whether a custom progress handler is currently set
bool Importer::IsDefaultProgressHandler() const bool Importer::IsDefaultProgressHandler() const {
{
return pimpl->mIsDefaultProgressHandler; return pimpl->mIsDefaultProgressHandler;
} }
@ -385,7 +379,6 @@ void Importer::FreeScene( )
{ {
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
delete pimpl->mScene; delete pimpl->mScene;
pimpl->mScene = NULL; pimpl->mScene = NULL;

View File

@ -120,11 +120,11 @@ public:
SharedPostProcessInfo* mPPShared; SharedPostProcessInfo* mPPShared;
/// The default class constructor. /// The default class constructor.
ImporterPimpl(); ImporterPimpl() AI_NO_EXCEPT;
}; };
inline inline
ImporterPimpl::ImporterPimpl() ImporterPimpl::ImporterPimpl() AI_NO_EXCEPT
: mIOHandler( nullptr ) : mIOHandler( nullptr )
, mIsDefaultHandler( false ) , mIsDefaultHandler( false )
, mProgressHandler( nullptr ) , mProgressHandler( nullptr )

View File

@ -317,7 +317,7 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid solid, TempMesh& result, ConversionData& conv) void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh& result, ConversionData& conv)
{ {
const Curve* const curve = Curve::Convert(*solid.Directrix, conv); const Curve* const curve = Curve::Convert(*solid.Directrix, conv);
if(!curve) { if(!curve) {

View File

@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
#include "IFCLoader.h" #include "IFCLoader.h"
#include "STEPFileReader.h" #include "../STEPParser/STEPFileReader.h"
#include "IFCUtil.h" #include "IFCUtil.h"
@ -134,7 +134,7 @@ IFCImporter::~IFCImporter()
bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{ {
const std::string& extension = GetExtension(pFile); const std::string& extension = GetExtension(pFile);
if (extension == "ifc" || extension == "ifczip" || extension == "stp" ) { if (extension == "ifc" || extension == "ifczip" ) {
return true; return true;
} else if ((!extension.length() || checkSig) && pIOHandler) { } else if ((!extension.length() || checkSig) && pIOHandler) {
// note: this is the common identification for STEP-encoded files, so // note: this is the common identification for STEP-encoded files, so

View File

@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include "AssimpPCH.h" #include "AssimpPCH.h"
#include "IFCReaderGen4.h" #include "IFCReaderGen_4.h"
namespace Assimp { namespace Assimp {
using namespace IFC; using namespace IFC;

View File

@ -85,16 +85,16 @@ STEP::TypeError::TypeError (const std::string& s,uint64_t entity /* = ENTITY_NOT
} }
static const char *ISO_Token = "ISO-10303-21;";
static const char *FILE_SCHEMA_Token = "FILE_SCHEMA";
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
{
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream)); std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
std::unique_ptr<STEP::DB> db = std::unique_ptr<STEP::DB>(new STEP::DB(reader)); std::unique_ptr<STEP::DB> db = std::unique_ptr<STEP::DB>(new STEP::DB(reader));
LineSplitter& splitter = db->GetSplitter(); LineSplitter &splitter = db->GetSplitter();
if (!splitter || *splitter != "ISO-10303-21;") { if (!splitter || *splitter != ISO_Token ) {
throw STEP::SyntaxError("expected magic token: ISO-10303-21",1); throw STEP::SyntaxError("expected magic token: " + std::string( ISO_Token ), 1);
} }
HeaderInfo& head = db->GetHeader(); HeaderInfo& head = db->GetHeader();
@ -109,7 +109,7 @@ STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream)
// want one-based line numbers for human readers, so +1 // want one-based line numbers for human readers, so +1
const uint64_t line = splitter.get_index()+1; const uint64_t line = splitter.get_index()+1;
if (s.substr(0,11) == "FILE_SCHEMA") { if (s.substr(0,11) == FILE_SCHEMA_Token) {
const char* sz = s.c_str()+11; const char* sz = s.c_str()+11;
SkipSpaces(sz,&sz); SkipSpaces(sz,&sz);
std::shared_ptr< const EXPRESS::DataType > schema = EXPRESS::DataType::Parse(sz); std::shared_ptr< const EXPRESS::DataType > schema = EXPRESS::DataType::Parse(sz);
@ -549,4 +549,3 @@ void STEP::LazyObject::LazyInit() const
// store the original id in the object instance // store the original id in the object instance
obj->SetID(id); obj->SetID(id);
} }

View File

@ -48,18 +48,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace STEP { namespace STEP {
// ### Parsing a STEP file is a twofold procedure ### // --------------------------------------------------------------------------
// -------------------------------------------------------------------------- /// @brief Parsing a STEP file is a twofold procedure.
// 1) read file header and return to caller, who checks if the /// 1) read file header and return to caller, who checks if the
// file is of a supported schema .. /// file is of a supported schema ..
DB* ReadFileHeader(std::shared_ptr<IOStream> stream); DB* ReadFileHeader(std::shared_ptr<IOStream> stream);
// --------------------------------------------------------------------------
// 2) read the actual file contents using a user-supplied set of /// 2) read the actual file contents using a user-supplied set of
// conversion functions to interpret the data. /// conversion functions to interpret the data.
void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const* types_to_track, size_t len, const char* const* inverse_indices_to_track, size_t len2); void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const* types_to_track, size_t len, const char* const* inverse_indices_to_track, size_t len2);
template <size_t N, size_t N2> inline void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
return ReadFile(db,scheme,arr,N,arr2,N2); /// @brief Helper to read a file.
} template <size_t N, size_t N2>
inline
void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
return ReadFile(db,scheme,arr,N,arr2,N2);
}
} // ! STEP } // ! STEP
} // ! Assimp } // ! Assimp

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
#include "StepFileImporter.h"
#include "../../Importer/STEPParser/STEPFileReader.h"
#include <assimp/importerdesc.h>
#include <assimp/DefaultIOSystem.h>
namespace Assimp {
namespace StepFile {
using namespace STEP;
static const aiImporterDesc desc = { "StepFile Importer",
"",
"",
"",
0,
0,
0,
0,
0,
"stp" };
StepFileImporter::StepFileImporter()
: BaseImporter() {
}
StepFileImporter::~StepFileImporter() {
}
bool StepFileImporter::CanRead(const std::string& file, IOSystem* pIOHandler, bool checkSig) const {
const std::string &extension = GetExtension(file);
if ( extension == "stp" || extension == "step" ) {
return true;
} else if ((!extension.length() || checkSig) && pIOHandler) {
const char* tokens[] = { "ISO-10303-21" };
const bool found(SearchFileHeaderForToken(pIOHandler, file, tokens, 1));
return found;
}
return false;
}
const aiImporterDesc *StepFileImporter::GetInfo() const {
return &desc;
}
static const std::string mode = "rb";
static const std::string StepFileSchema = "CONFIG_CONTROL_DESIGN";
void StepFileImporter::InternReadFile(const std::string &file, aiScene* pScene, IOSystem* pIOHandler) {
// Read file into memory
std::shared_ptr<IOStream> fileStream(pIOHandler->Open(file, mode));
if (!fileStream.get()) {
throw DeadlyImportError("Failed to open file " + file + ".");
}
std::unique_ptr<STEP::DB> db(STEP::ReadFileHeader(fileStream));
const STEP::HeaderInfo& head = static_cast<const STEP::DB&>(*db).GetHeader();
if (!head.fileSchema.size() || head.fileSchema != StepFileSchema) {
DeadlyImportError("Unrecognized file schema: " + head.fileSchema);
}
}
} // Namespace StepFile
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_STEP_IMPORTER

View File

@ -0,0 +1,69 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#pragma once
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
#include <assimp/BaseImporter.h>
namespace Assimp {
namespace StepFile {
class StepFileImporter : public BaseImporter {
public:
StepFileImporter();
~StepFileImporter();
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
const aiImporterDesc* GetInfo() const override;
protected:
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) override;
private:
};
} // Namespace StepFile
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_STEP_IMPORTER

File diff suppressed because it is too large Load Diff

View File

@ -197,6 +197,9 @@ corresponding preprocessor flag to selectively disable formats.
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER #ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
# include "MMDImporter.h" # include "MMDImporter.h"
#endif #endif
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
# include "Importer/StepFile/StepFileImporter.h"
#endif
namespace Assimp { namespace Assimp {
@ -352,6 +355,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER #ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
out.push_back( new MMDImporter() ); out.push_back( new MMDImporter() );
#endif #endif
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
out.push_back(new StepFile::StepFileImporter());
#endif
} }
/** will delete all registered importers. */ /** will delete all registered importers. */

View File

@ -113,14 +113,14 @@ enum PrePostBehaviour
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Data structure for a LWO animation keyframe /** \brief Data structure for a LWO animation keyframe
*/ */
struct Key struct Key {
{ Key() AI_NO_EXCEPT
Key() : time()
: time(), , value()
value(), , inter(IT_LINE)
inter (IT_LINE), , params() {
params() // empty
{} }
//! Current time //! Current time
double time; double time;
@ -144,17 +144,16 @@ struct Key
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Data structure for a LWO animation envelope /** \brief Data structure for a LWO animation envelope
*/ */
struct Envelope struct Envelope {
{ Envelope() AI_NO_EXCEPT
Envelope() : index()
: index() , type(EnvelopeType_Unknown)
, type (EnvelopeType_Unknown) , pre(PrePostBehaviour_Constant)
, pre (PrePostBehaviour_Constant) , post(PrePostBehaviour_Constant)
, post (PrePostBehaviour_Constant) , old_first(0)
, old_last(0) {
, old_first (0) // empty
, old_last (0) }
{}
//! Index of this envelope //! Index of this envelope
unsigned int index; unsigned int index;
@ -162,7 +161,7 @@ struct Envelope
//! Type of envelope //! Type of envelope
EnvelopeType type; EnvelopeType type;
//! Pre and post-behaviour //! Pre- and post-behavior
PrePostBehaviour pre,post; PrePostBehaviour pre,post;
//! Keyframes for this envelope //! Keyframes for this envelope

View File

@ -261,14 +261,14 @@ namespace LWO {
* \note We can't use the code in SmoothingGroups.inl here - the mesh * \note We can't use the code in SmoothingGroups.inl here - the mesh
* structures of 3DS/ASE and LWO are too different. * structures of 3DS/ASE and LWO are too different.
*/ */
struct Face : public aiFace struct Face : public aiFace {
{
//! Default construction //! Default construction
Face() Face() AI_NO_EXCEPT
: surfaceIndex (0) : surfaceIndex( 0 )
, smoothGroup (0) , smoothGroup( 0 )
, type (AI_LWO_FACE) , type( AI_LWO_FACE ) {
{} // empty
}
//! Construction from given type //! Construction from given type
explicit Face(uint32_t _type) explicit Face(uint32_t _type)

View File

@ -120,7 +120,7 @@ public:
{ {
unsigned int mBone; ///< Index of the bone unsigned int mBone; ///< Index of the bone
float mWeight; ///< Weight of that bone on this vertex float mWeight; ///< Weight of that bone on this vertex
Weight() Weight() AI_NO_EXCEPT
: mBone(0) : mBone(0)
, mWeight(0.0f) , mWeight(0.0f)
{ } { }

View File

@ -246,7 +246,7 @@ struct Vertex
uint16_t NORMAL; uint16_t NORMAL;
} /*PACK_STRUCT*/; } /*PACK_STRUCT*/;
#include "./../include/assimp/Compiler/poppack1.h" #include <assimp/Compiler/poppack1.h>
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
/** @brief Unpack a Q3 16 bit vector to its full float3 representation /** @brief Unpack a Q3 16 bit vector to its full float3 representation

View File

@ -125,7 +125,7 @@ enum AlphaTestFunc
*/ */
struct ShaderMapBlock struct ShaderMapBlock
{ {
ShaderMapBlock() ShaderMapBlock() AI_NO_EXCEPT
: blend_src (BLEND_NONE) : blend_src (BLEND_NONE)
, blend_dest (BLEND_NONE) , blend_dest (BLEND_NONE)
, alpha_test (AT_NONE) , alpha_test (AT_NONE)
@ -150,7 +150,7 @@ struct ShaderMapBlock
*/ */
struct ShaderDataBlock struct ShaderDataBlock
{ {
ShaderDataBlock() ShaderDataBlock() AI_NO_EXCEPT
: cull (CULL_CW) : cull (CULL_CW)
{} {}

View File

@ -46,9 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include "../include/assimp/types.h" #include <assimp/types.h>
#include "../include/assimp/mesh.h" #include <assimp/mesh.h>
#include "../include/assimp/anim.h" #include <assimp/anim.h>
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) #if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack(push,1) # pragma pack(push,1)

View File

@ -420,6 +420,9 @@ void MD5Importer::LoadMD5MeshFile ()
// generate unique vertices in our internal verbose format // generate unique vertices in our internal verbose format
MakeDataUnique(meshSrc); MakeDataUnique(meshSrc);
std::string name( meshSrc.mShader.C_Str() );
name += ".msh";
mesh->mName = name;
mesh->mNumVertices = (unsigned int) meshSrc.mVertices.size(); mesh->mNumVertices = (unsigned int) meshSrc.mVertices.size();
mesh->mVertices = new aiVector3D[mesh->mNumVertices]; mesh->mVertices = new aiVector3D[mesh->mNumVertices];
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
@ -471,7 +474,6 @@ void MD5Importer::LoadMD5MeshFile ()
MD5::ConvertQuaternion( boneSrc.mRotationQuat, boneSrc.mRotationQuatConverted ); MD5::ConvertQuaternion( boneSrc.mRotationQuat, boneSrc.mRotationQuatConverted );
} }
//unsigned int g = 0;
pv = mesh->mVertices; pv = mesh->mVertices;
for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) { for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) {
// compute the final vertex position from all single weights // compute the final vertex position from all single weights
@ -559,7 +561,9 @@ void MD5Importer::LoadMD5MeshFile ()
// set this also as material name // set this also as material name
mat->AddProperty(&meshSrc.mShader,AI_MATKEY_NAME); mat->AddProperty(&meshSrc.mShader,AI_MATKEY_NAME);
} }
else mat->AddProperty(&meshSrc.mShader,AI_MATKEY_TEXTURE_DIFFUSE(0)); else {
mat->AddProperty(&meshSrc.mShader, AI_MATKEY_TEXTURE_DIFFUSE(0));
}
mesh->mMaterialIndex = n++; mesh->mMaterialIndex = n++;
} }
#endif #endif

View File

@ -192,14 +192,14 @@ typedef std::vector< FrameDesc > FrameList;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Represents a vertex descriptor in a MD5 file /** Represents a vertex descriptor in a MD5 file
*/ */
struct VertexDesc struct VertexDesc {
{ VertexDesc() AI_NO_EXCEPT
VertexDesc() : mFirstWeight(0)
: mFirstWeight (0) , mNumWeights(0) {
, mNumWeights (0) // empty
{} }
//! UV cordinate of the vertex //! UV coordinate of the vertex
aiVector2D mUV; aiVector2D mUV;
//! Index of the first weight of the vertex in //! Index of the first weight of the vertex in

View File

@ -61,7 +61,6 @@ http://themdcfile.planetwolfenstein.gamespy.com/MDC_File_Format.pdf
namespace Assimp { namespace Assimp {
namespace MDC { namespace MDC {
// to make it easier for us, we test the magic word against both "endianesses" // to make it easier for us, we test the magic word against both "endianesses"
#define AI_MDC_MAGIC_NUMBER_BE AI_MAKE_MAGIC("CPDI") #define AI_MDC_MAGIC_NUMBER_BE AI_MAKE_MAGIC("CPDI")
#define AI_MDC_MAGIC_NUMBER_LE AI_MAKE_MAGIC("IDPC") #define AI_MDC_MAGIC_NUMBER_LE AI_MAKE_MAGIC("IDPC")
@ -79,8 +78,7 @@ namespace MDC {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Data structure for a MDC file's main header /** \brief Data structure for a MDC file's main header
*/ */
struct Header struct Header {
{
uint32_t ulIdent ; uint32_t ulIdent ;
uint32_t ulVersion ; uint32_t ulVersion ;
char ucName [ AI_MDC_MAXQPATH ] ; char ucName [ AI_MDC_MAXQPATH ] ;
@ -100,8 +98,7 @@ struct Header
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Data structure for a MDC file's surface header /** \brief Data structure for a MDC file's surface header
*/ */
struct Surface struct Surface {
{
uint32_t ulIdent ; uint32_t ulIdent ;
char ucName [ AI_MDC_MAXQPATH ] ; char ucName [ AI_MDC_MAXQPATH ] ;
uint32_t ulFlags ; uint32_t ulFlags ;
@ -118,23 +115,22 @@ struct Surface
uint32_t ulOffsetFrameBaseFrames ; uint32_t ulOffsetFrameBaseFrames ;
uint32_t ulOffsetFrameCompFrames ; uint32_t ulOffsetFrameCompFrames ;
uint32_t ulOffsetEnd; uint32_t ulOffsetEnd;
Surface() Surface() AI_NO_EXCEPT
: ulIdent(), : ulIdent()
ulFlags(), , ulFlags()
ulNumCompFrames(), , ulNumCompFrames()
ulNumBaseFrames(), , ulNumBaseFrames()
ulNumShaders(), , ulNumShaders()
ulNumVertices(), , ulNumVertices()
ulNumTriangles(), , ulNumTriangles()
ulOffsetTriangles(), , ulOffsetTriangles()
ulOffsetShaders(), , ulOffsetShaders()
ulOffsetTexCoords(), , ulOffsetTexCoords()
ulOffsetBaseVerts(), , ulOffsetBaseVerts()
ulOffsetCompVerts(), , ulOffsetCompVerts()
ulOffsetFrameBaseFrames(), , ulOffsetFrameBaseFrames()
ulOffsetFrameCompFrames(), , ulOffsetFrameCompFrames()
ulOffsetEnd() , ulOffsetEnd() {
{
ucName[AI_MDC_MAXQPATH-1] = '\0'; ucName[AI_MDC_MAXQPATH-1] = '\0';
} }
} PACK_STRUCT; } PACK_STRUCT;
@ -142,8 +138,7 @@ struct Surface
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Data structure for a MDC frame /** \brief Data structure for a MDC frame
*/ */
struct Frame struct Frame {
{
//! bounding box minimum coords //! bounding box minimum coords
aiVector3D bboxMin ; aiVector3D bboxMin ;
@ -163,24 +158,21 @@ struct Frame
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Data structure for a MDC triangle /** \brief Data structure for a MDC triangle
*/ */
struct Triangle struct Triangle {
{
uint32_t aiIndices[3]; uint32_t aiIndices[3];
} PACK_STRUCT; } PACK_STRUCT;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Data structure for a MDC texture coordinate /** \brief Data structure for a MDC texture coordinate
*/ */
struct TexturCoord struct TexturCoord {
{
float u,v; float u,v;
} PACK_STRUCT; } PACK_STRUCT;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Data structure for a MDC base vertex /** \brief Data structure for a MDC base vertex
*/ */
struct BaseVertex struct BaseVertex {
{
int16_t x,y,z; int16_t x,y,z;
uint16_t normal; uint16_t normal;
} PACK_STRUCT; } PACK_STRUCT;
@ -188,25 +180,20 @@ struct BaseVertex
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Data structure for a MDC compressed vertex /** \brief Data structure for a MDC compressed vertex
*/ */
struct CompressedVertex struct CompressedVertex {
{
uint8_t xd,yd,zd,nd; uint8_t xd,yd,zd,nd;
} PACK_STRUCT; } PACK_STRUCT;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Data structure for a MDC shader /** \brief Data structure for a MDC shader
*/ */
struct Shader struct Shader {
{
char ucName [ AI_MDC_MAXQPATH ] ; char ucName [ AI_MDC_MAXQPATH ] ;
uint32_t ulPath; uint32_t ulPath;
} PACK_STRUCT; } PACK_STRUCT;
#include <assimp/Compiler/poppack1.h> #include <assimp/Compiler/poppack1.h>
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Build a floating point vertex from the compressed data in MDC files /** Build a floating point vertex from the compressed data in MDC files
*/ */
@ -215,6 +202,7 @@ void BuildVertex(const Frame& frame,
const CompressedVertex& cvert, const CompressedVertex& cvert,
aiVector3D& vXYZOut, aiVector3D& vXYZOut,
aiVector3D& vNorOut); aiVector3D& vNorOut);
}} }
}
#endif // !! AI_MDCFILEHELPER_H_INC #endif // !! AI_MDCFILEHELPER_H_INC

View File

@ -434,10 +434,12 @@ void MDCImporter::InternReadFile(
else if (1 == pScene->mNumMeshes) else if (1 == pScene->mNumMeshes)
{ {
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode();
pScene->mRootNode->mName = pScene->mMeshes[0]->mName; if ( nullptr != pScene->mMeshes[0] ) {
pScene->mRootNode->mNumMeshes = 1; pScene->mRootNode->mName = pScene->mMeshes[0]->mName;
pScene->mRootNode->mMeshes = new unsigned int[1]; pScene->mRootNode->mNumMeshes = 1;
pScene->mRootNode->mMeshes[0] = 0; pScene->mRootNode->mMeshes = new unsigned int[1];
pScene->mRootNode->mMeshes[0] = 0;
}
} }
else else
{ {

View File

@ -709,7 +709,7 @@ struct GroupFrame
SimpleFrame *frames; SimpleFrame *frames;
} PACK_STRUCT; } PACK_STRUCT;
#include "./../include/assimp/Compiler/poppack1.h" #include <assimp/Compiler/poppack1.h>
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
/** \struct IntFace_MDL7 /** \struct IntFace_MDL7
@ -717,11 +717,9 @@ struct GroupFrame
*/ */
struct IntFace_MDL7 { struct IntFace_MDL7 {
// provide a constructor for our own convenience // provide a constructor for our own convenience
IntFace_MDL7() IntFace_MDL7() AI_NO_EXCEPT {
{ ::memset( mIndices, 0, sizeof(uint32_t) *3);
// set everything to zero ::memset( iMatIndex, 0, sizeof( unsigned int) *2);
mIndices[0] = mIndices[1] = mIndices[2] = 0;
iMatIndex[0] = iMatIndex[1] = 0;
} }
//! Vertex indices //! Vertex indices
@ -737,13 +735,11 @@ struct IntFace_MDL7 {
* which has been created from two single materials along with the * which has been created from two single materials along with the
* original material indices. * original material indices.
*/ */
struct IntMaterial_MDL7 struct IntMaterial_MDL7 {
{
// provide a constructor for our own convenience // provide a constructor for our own convenience
IntMaterial_MDL7() IntMaterial_MDL7() AI_NO_EXCEPT
{ : pcMat( nullptr ) {
pcMat = NULL; ::memset( iOldMatIndices, 0, sizeof(unsigned int) *2);
iOldMatIndices[0] = iOldMatIndices[1] = 0;
} }
//! Material instance //! Material instance
@ -761,7 +757,7 @@ struct IntMaterial_MDL7
struct IntBone_MDL7 : aiBone struct IntBone_MDL7 : aiBone
{ {
//! Default constructor //! Default constructor
IntBone_MDL7() : iParent (0xffff) IntBone_MDL7() AI_NO_EXCEPT : iParent (0xffff)
{ {
pkeyPositions.reserve(30); pkeyPositions.reserve(30);
pkeyScalings.reserve(30); pkeyScalings.reserve(30);
@ -806,12 +802,12 @@ struct IntFrameInfo_MDL7
struct IntGroupInfo_MDL7 struct IntGroupInfo_MDL7
{ {
//! Default constructor //! Default constructor
IntGroupInfo_MDL7() IntGroupInfo_MDL7() AI_NO_EXCEPT
: iIndex(0) : iIndex(0)
, pcGroup(NULL) , pcGroup(nullptr)
, pcGroupUVs(NULL) , pcGroupUVs(nullptr)
, pcGroupTris(NULL) , pcGroupTris(nullptr)
, pcGroupVerts(NULL) , pcGroupVerts(nullptr)
{} {}
//! Construction from an existing group header //! Construction from an existing group header
@ -843,7 +839,7 @@ struct IntGroupInfo_MDL7
//! Holds the data that belongs to a MDL7 mesh group //! Holds the data that belongs to a MDL7 mesh group
struct IntGroupData_MDL7 struct IntGroupData_MDL7
{ {
IntGroupData_MDL7() IntGroupData_MDL7() AI_NO_EXCEPT
: bNeed2UV(false) : bNeed2UV(false)
{} {}
@ -872,10 +868,9 @@ struct IntGroupData_MDL7
// ------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------
//! Holds data from an MDL7 file that is shared by all mesh groups //! Holds data from an MDL7 file that is shared by all mesh groups
struct IntSharedData_MDL7 struct IntSharedData_MDL7 {
{
//! Default constructor //! Default constructor
IntSharedData_MDL7() IntSharedData_MDL7() AI_NO_EXCEPT
: apcOutBones(), : apcOutBones(),
iNum() iNum()
{ {

View File

@ -413,8 +413,9 @@ void MDLImporter::InternReadFile_Quake1() {
#if 1 #if 1
// FIXME: the cast is wrong and cause a warning on clang 5.0 // FIXME: the cast is wrong and cause a warning on clang 5.0
// disable thi code for now, fix it later // disable this code for now, fix it later
ai_assert(false && "Bad pointer cast"); ai_assert(false && "Bad pointer cast");
pcFirstFrame = nullptr; // Workaround: msvc++ C4703 error
#else #else
BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames; BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames;
pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type); pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type);

View File

@ -72,18 +72,16 @@ using namespace std;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Default constructor // Default constructor
MMDImporter::MMDImporter() MMDImporter::MMDImporter()
: m_Buffer(), : m_Buffer()
// m_pRootObject( NULL ), , m_strAbsPath("") {
m_strAbsPath("") { DefaultIOSystem io;
DefaultIOSystem io; m_strAbsPath = io.getOsSeparator();
m_strAbsPath = io.getOsSeparator();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor. // Destructor.
MMDImporter::~MMDImporter() { MMDImporter::~MMDImporter() {
// delete m_pRootObject; // empty
// m_pRootObject = NULL;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -96,8 +94,7 @@ bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler,
} else // Check file Header } else // Check file Header
{ {
static const char *pTokens[] = {"PMX "}; static const char *pTokens[] = {"PMX "};
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 1);
1);
} }
} }
@ -354,8 +351,11 @@ aiMaterial *MMDImporter::CreateMaterial(const pmx::PmxMaterial *pMat,
float shininess = pMat->specularlity; float shininess = pMat->specularlity;
mat->AddProperty(&shininess, 1, AI_MATKEY_SHININESS_STRENGTH); mat->AddProperty(&shininess, 1, AI_MATKEY_SHININESS_STRENGTH);
aiString texture_path(pModel->textures[pMat->diffuse_texture_index]); if(pMat->diffuse_texture_index >= 0) {
mat->AddProperty(&texture_path, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); aiString texture_path(pModel->textures[pMat->diffuse_texture_index]);
mat->AddProperty(&texture_path, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
}
int mapping_uvwsrc = 0; int mapping_uvwsrc = 0;
mat->AddProperty(&mapping_uvwsrc, 1, mat->AddProperty(&mapping_uvwsrc, 1,
AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE, 0)); AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE, 0));

View File

@ -94,16 +94,15 @@ namespace pmx
if (encoding == 0) if (encoding == 0)
{ {
// UTF16 to UTF8 // UTF16 to UTF8
std::string result; const uint16_t* sourceStart = (uint16_t*)buffer.data();
const char* sourceStart = buffer.data();
const unsigned int targetSize = size * 3; // enough to encode const unsigned int targetSize = size * 3; // enough to encode
char* targetStart = new char[targetSize](); char *targetStart = new char[targetSize];
const char* targetReserved = targetStart; std::memset(targetStart, 0, targetSize * sizeof(char));
utf8::utf16to8( sourceStart, sourceStart + size, targetStart );
utf8::utf16to8( sourceStart, sourceStart + size/2, targetStart );
result.assign(targetReserved, targetStart - targetReserved); std::string result(targetStart);
delete[] targetReserved; delete [] targetStart;
return result; return result;
} }
else else
@ -475,7 +474,6 @@ namespace pmx
void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/) void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
{ {
// 未実装
std::cerr << "Not Implemented Exception" << std::endl; std::cerr << "Not Implemented Exception" << std::endl;
throw DeadlyImportError("MMD: Not Implemented Exception"); throw DeadlyImportError("MMD: Not Implemented Exception");
} }
@ -511,31 +509,27 @@ namespace pmx
void PmxModel::Read(std::istream *stream) void PmxModel::Read(std::istream *stream)
{ {
// マジック
char magic[4]; char magic[4];
stream->read((char*) magic, sizeof(char) * 4); stream->read((char*) magic, sizeof(char) * 4);
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20) if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
{ {
std::cerr << "invalid magic number." << std::endl; std::cerr << "invalid magic number." << std::endl;
throw DeadlyImportError("MMD: invalid magic number."); throw DeadlyImportError("MMD: invalid magic number.");
} }
// バージョン
stream->read((char*) &version, sizeof(float)); stream->read((char*) &version, sizeof(float));
if (version != 2.0f && version != 2.1f) if (version != 2.0f && version != 2.1f)
{ {
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl; std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but " + to_string(version)); throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but " + to_string(version));
} }
// ファイル設定
this->setting.Read(stream); this->setting.Read(stream);
// モデル情報
this->model_name = ReadString(stream, setting.encoding); this->model_name = ReadString(stream, setting.encoding);
this->model_english_name = ReadString(stream, setting.encoding); this->model_english_name = ReadString(stream, setting.encoding);
this->model_comment = ReadString(stream, setting.encoding); this->model_comment = ReadString(stream, setting.encoding);
this->model_english_comment = ReadString(stream, setting.encoding); this->model_english_comment = ReadString(stream, setting.encoding);
// 頂点 // read vertices
stream->read((char*) &vertex_count, sizeof(int)); stream->read((char*) &vertex_count, sizeof(int));
this->vertices = mmd::make_unique<PmxVertex []>(vertex_count); this->vertices = mmd::make_unique<PmxVertex []>(vertex_count);
for (int i = 0; i < vertex_count; i++) for (int i = 0; i < vertex_count; i++)
@ -543,7 +537,7 @@ namespace pmx
vertices[i].Read(stream, &setting); vertices[i].Read(stream, &setting);
} }
// // read indices
stream->read((char*) &index_count, sizeof(int)); stream->read((char*) &index_count, sizeof(int));
this->indices = mmd::make_unique<int []>(index_count); this->indices = mmd::make_unique<int []>(index_count);
for (int i = 0; i < index_count; i++) for (int i = 0; i < index_count; i++)
@ -551,7 +545,7 @@ namespace pmx
this->indices[i] = ReadIndex(stream, setting.vertex_index_size); this->indices[i] = ReadIndex(stream, setting.vertex_index_size);
} }
// テクスチャ // read texture names
stream->read((char*) &texture_count, sizeof(int)); stream->read((char*) &texture_count, sizeof(int));
this->textures = mmd::make_unique<std::string []>(texture_count); this->textures = mmd::make_unique<std::string []>(texture_count);
for (int i = 0; i < texture_count; i++) for (int i = 0; i < texture_count; i++)
@ -559,7 +553,7 @@ namespace pmx
this->textures[i] = ReadString(stream, setting.encoding); this->textures[i] = ReadString(stream, setting.encoding);
} }
// マテリアル // read materials
stream->read((char*) &material_count, sizeof(int)); stream->read((char*) &material_count, sizeof(int));
this->materials = mmd::make_unique<PmxMaterial []>(material_count); this->materials = mmd::make_unique<PmxMaterial []>(material_count);
for (int i = 0; i < material_count; i++) for (int i = 0; i < material_count; i++)
@ -567,7 +561,7 @@ namespace pmx
this->materials[i].Read(stream, &setting); this->materials[i].Read(stream, &setting);
} }
// ボーン // read bones
stream->read((char*) &this->bone_count, sizeof(int)); stream->read((char*) &this->bone_count, sizeof(int));
this->bones = mmd::make_unique<PmxBone []>(this->bone_count); this->bones = mmd::make_unique<PmxBone []>(this->bone_count);
for (int i = 0; i < this->bone_count; i++) for (int i = 0; i < this->bone_count; i++)
@ -575,7 +569,7 @@ namespace pmx
this->bones[i].Read(stream, &setting); this->bones[i].Read(stream, &setting);
} }
// モーフ // read morphs
stream->read((char*) &this->morph_count, sizeof(int)); stream->read((char*) &this->morph_count, sizeof(int));
this->morphs = mmd::make_unique<PmxMorph []>(this->morph_count); this->morphs = mmd::make_unique<PmxMorph []>(this->morph_count);
for (int i = 0; i < this->morph_count; i++) for (int i = 0; i < this->morph_count; i++)
@ -583,7 +577,7 @@ namespace pmx
this->morphs[i].Read(stream, &setting); this->morphs[i].Read(stream, &setting);
} }
// 表示枠 // read display frames
stream->read((char*) &this->frame_count, sizeof(int)); stream->read((char*) &this->frame_count, sizeof(int));
this->frames = mmd::make_unique<PmxFrame []>(this->frame_count); this->frames = mmd::make_unique<PmxFrame []>(this->frame_count);
for (int i = 0; i < this->frame_count; i++) for (int i = 0; i < this->frame_count; i++)
@ -591,7 +585,7 @@ namespace pmx
this->frames[i].Read(stream, &setting); this->frames[i].Read(stream, &setting);
} }
// 剛体 // read rigid bodies
stream->read((char*) &this->rigid_body_count, sizeof(int)); stream->read((char*) &this->rigid_body_count, sizeof(int));
this->rigid_bodies = mmd::make_unique<PmxRigidBody []>(this->rigid_body_count); this->rigid_bodies = mmd::make_unique<PmxRigidBody []>(this->rigid_body_count);
for (int i = 0; i < this->rigid_body_count; i++) for (int i = 0; i < this->rigid_body_count; i++)
@ -599,7 +593,7 @@ namespace pmx
this->rigid_bodies[i].Read(stream, &setting); this->rigid_bodies[i].Read(stream, &setting);
} }
// ジョイント // read joints
stream->read((char*) &this->joint_count, sizeof(int)); stream->read((char*) &this->joint_count, sizeof(int));
this->joints = mmd::make_unique<PmxJoint []>(this->joint_count); this->joints = mmd::make_unique<PmxJoint []>(this->joint_count);
for (int i = 0; i < this->joint_count; i++) for (int i = 0; i < this->joint_count; i++)

View File

@ -181,8 +181,7 @@ void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints,
ch->mParent = nd; ch->mParent = nd;
ch->mTransformation = aiMatrix4x4::Translation(joints[i].position,aiMatrix4x4()=aiMatrix4x4())* ch->mTransformation = aiMatrix4x4::Translation(joints[i].position,aiMatrix4x4()=aiMatrix4x4())*
// XXX actually, I don't *know* why we need the inverse here. Probably column vs. row order? aiMatrix4x4().FromEulerAnglesXYZ(joints[i].rotation);
aiMatrix4x4().FromEulerAnglesXYZ(joints[i].rotation).Transpose();
const aiMatrix4x4 abs = absTrafo*ch->mTransformation; const aiMatrix4x4 abs = absTrafo*ch->mTransformation;
for(unsigned int a = 0; a < mScene->mNumMeshes; ++a) { for(unsigned int a = 0; a < mScene->mNumMeshes; ++a) {
@ -639,11 +638,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
aiQuatKey& q = nd->mRotationKeys[nd->mNumRotationKeys++]; aiQuatKey& q = nd->mRotationKeys[nd->mNumRotationKeys++];
q.mTime = (*rot).time*animfps; q.mTime = (*rot).time*animfps;
q.mValue = aiQuaternion(aiMatrix3x3(aiMatrix4x4().FromEulerAnglesXYZ((*it).rotation)*
// XXX it seems our matrix&quaternion code has faults in its conversion routines -- aiMatrix4x4().FromEulerAnglesXYZ((*rot).value)));
// aiQuaternion(x,y,z) seems to besomething different as quat(matrix.fromeuler(x,y,z)).
q.mValue = aiQuaternion(aiMatrix3x3(aiMatrix4x4().FromEulerAnglesXYZ((*rot).value)*
aiMatrix4x4().FromEulerAnglesXYZ((*it).rotation)).Transpose());
} }
} }

View File

@ -194,12 +194,18 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
// data is given in ints, simply copy it // data is given in ints, simply copy it
unsigned int iWrite = 0; unsigned int iWrite = 0;
if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) { if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
iWrite = prop->mDataLength / sizeof(int32_t); iWrite = std::max(static_cast<unsigned int>(prop->mDataLength / sizeof(int32_t)), 1u);
if (pMax) { if (pMax) {
iWrite = std::min(*pMax,iWrite); ; iWrite = std::min(*pMax,iWrite);
} }
for (unsigned int a = 0; a < iWrite;++a) { if (1 == prop->mDataLength) {
pOut[a] = static_cast<int>(reinterpret_cast<int32_t*>(prop->mData)[a]); // bool type, 1 byte
*pOut = static_cast<int>(*prop->mData);
}
else {
for (unsigned int a = 0; a < iWrite;++a) {
pOut[a] = static_cast<int>(reinterpret_cast<int32_t*>(prop->mData)[a]);
}
} }
if (pMax) { if (pMax) {
*pMax = iWrite; *pMax = iWrite;
@ -387,26 +393,6 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
return AI_SUCCESS; return AI_SUCCESS;
} }
static aiMaterial *DefaultMaterial = nullptr;
// ------------------------------------------------------------------------------------------------
// Will return the default material.
aiMaterial *aiCreateAndRegisterDefaultMaterial() {
if (nullptr == DefaultMaterial) {
DefaultMaterial = new aiMaterial;
aiString s;
s.Set(AI_DEFAULT_MATERIAL_NAME);
DefaultMaterial->AddProperty(&s, AI_MATKEY_NAME);
}
return DefaultMaterial;
}
// ------------------------------------------------------------------------------------------------
// Will return the default material.
void aiReleaseDefaultMaterial() {
DefaultMaterial = nullptr;
}
static const unsigned int DefaultNumAllocated = 5; static const unsigned int DefaultNumAllocated = 5;

View File

@ -106,15 +106,23 @@ const aiImporterDesc* OFFImporter::GetInfo () const
return &desc; return &desc;
} }
// skip blank space, lines and comments
static void NextToken(const char **car, const char* end) {
SkipSpacesAndLineEnd(car);
while (*car < end && (**car == '#' || **car == '\n' || **car == '\r')) {
SkipLine(car);
SkipSpacesAndLineEnd(car);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void OFFImporter::InternReadFile( const std::string& pFile, void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
aiScene* pScene, IOSystem* pIOHandler)
{
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb")); std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) { if( file.get() == nullptr) {
throw DeadlyImportError( "Failed to open OFF file " + pFile + "."); throw DeadlyImportError( "Failed to open OFF file " + pFile + ".");
} }
@ -123,15 +131,61 @@ void OFFImporter::InternReadFile( const std::string& pFile,
TextFileToBuffer(file.get(),mBuffer2); TextFileToBuffer(file.get(),mBuffer2);
const char* buffer = &mBuffer2[0]; const char* buffer = &mBuffer2[0];
char line[4096]; // Proper OFF header parser. We only implement normal loading for now.
GetNextLine(buffer,line); bool hasTexCoord = false, hasNormals = false, hasColors = false;
if ('O' == line[0]) { bool hasHomogenous = false, hasDimension = false;
GetNextLine(buffer,line); // skip the 'OFF' line unsigned int dimensions = 3;
const char* car = buffer;
const char* end = buffer + mBuffer2.size();
NextToken(&car, end);
if (car < end - 2 && car[0] == 'S' && car[1] == 'T') {
hasTexCoord = true; car += 2;
}
if (car < end - 1 && car[0] == 'C') {
hasColors = true; car++;
}
if (car < end- 1 && car[0] == 'N') {
hasNormals = true; car++;
}
if (car < end - 1 && car[0] == '4') {
hasHomogenous = true; car++;
}
if (car < end - 1 && car[0] == 'n') {
hasDimension = true; car++;
}
if (car < end - 3 && car[0] == 'O' && car[1] == 'F' && car[2] == 'F') {
car += 3;
NextToken(&car, end);
} else {
// in case there is no OFF header (which is allowed by the
// specification...), then we might have unintentionally read an
// additional dimension from the primitive count fields
dimensions = 3;
hasHomogenous = false;
NextToken(&car, end);
// at this point the next token should be an integer number
if (car >= end - 1 || *car < '0' || *car > '9') {
throw DeadlyImportError("OFF: Header is invalid");
}
}
if (hasDimension) {
dimensions = strtoul10(car, &car);
NextToken(&car, end);
}
if (dimensions > 3) {
throw DeadlyImportError
("OFF: Number of vertex coordinates higher than 3 unsupported");
} }
const char* sz = line; SkipSpaces(&sz); NextToken(&car, end);
const unsigned int numVertices = strtoul10(sz,&sz);SkipSpaces(&sz); const unsigned int numVertices = strtoul10(car, &car);
const unsigned int numFaces = strtoul10(sz,&sz); NextToken(&car, end);
const unsigned int numFaces = strtoul10(car, &car);
NextToken(&car, end);
strtoul10(car, &car); // skip edge count
NextToken(&car, end);
if (!numVertices) { if (!numVertices) {
throw DeadlyImportError("OFF: There are no valid vertices"); throw DeadlyImportError("OFF: There are no valid vertices");
@ -147,91 +201,127 @@ void OFFImporter::InternReadFile( const std::string& pFile,
pScene->mMeshes[0] = mesh; pScene->mMeshes[0] = mesh;
mesh->mNumFaces = numFaces; mesh->mNumFaces = numFaces;
aiFace* faces = new aiFace [mesh->mNumFaces]; aiFace* faces = new aiFace[mesh->mNumFaces];
mesh->mFaces = faces; mesh->mFaces = faces;
std::vector<aiVector3D> tempPositions(numVertices); mesh->mNumVertices = numVertices;
mesh->mVertices = new aiVector3D[numVertices];
mesh->mNormals = hasNormals ? new aiVector3D[numVertices] : nullptr;
mesh->mColors[0] = hasColors ? new aiColor4D[numVertices] : nullptr;
if (hasTexCoord) {
mesh->mNumUVComponents[0] = 2;
mesh->mTextureCoords[0] = new aiVector3D[numVertices];
}
char line[4096];
buffer = car;
const char *sz = car;
// now read all vertex lines // now read all vertex lines
for (unsigned int i = 0; i< numVertices;++i) for (unsigned int i = 0; i < numVertices; ++i) {
{ if(!GetNextLine(buffer, line)) {
if(!GetNextLine(buffer,line))
{
ASSIMP_LOG_ERROR("OFF: The number of verts in the header is incorrect"); ASSIMP_LOG_ERROR("OFF: The number of verts in the header is incorrect");
break; break;
} }
aiVector3D& v = tempPositions[i]; aiVector3D& v = mesh->mVertices[i];
sz = line;
sz = line; SkipSpaces(&sz); // helper array to write a for loop over possible dimension values
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)v.x); SkipSpaces(&sz); ai_real* vec[3] = {&v.x, &v.y, &v.z};
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)v.y); SkipSpaces(&sz);
fast_atoreal_move<ai_real>(sz,(ai_real&)v.z); // stop at dimensions: this allows loading 1D or 2D coordinate vertices
for (unsigned int dim = 0; dim < dimensions; ++dim ) {
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz, *vec[dim]);
}
// if has homogenous coordinate, divide others by this one
if (hasHomogenous) {
SkipSpaces(&sz);
ai_real w = 1.;
sz = fast_atoreal_move<ai_real>(sz, w);
for (unsigned int dim = 0; dim < dimensions; ++dim ) {
*(vec[dim]) /= w;
}
}
// read optional normals
if (hasNormals) {
aiVector3D& n = mesh->mNormals[i];
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)n.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)n.y);
SkipSpaces(&sz);
fast_atoreal_move<ai_real>(sz,(ai_real&)n.z);
}
// reading colors is a pain because the specification says it can be
// integers or floats, and any number of them between 1 and 4 included,
// until the next comment or end of line
// in theory should be testing type !
if (hasColors) {
aiColor4D& c = mesh->mColors[0][i];
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)c.r);
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)c.g);
} else {
c.g = 0.;
}
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)c.b);
} else {
c.b = 0.;
}
if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)c.a);
} else {
c.a = 1.;
}
}
if (hasTexCoord) {
aiVector3D& t = mesh->mTextureCoords[0][i];
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)t.x);
SkipSpaces(&sz);
fast_atoreal_move<ai_real>(sz,(ai_real&)t.y);
}
} }
// load faces with their indices
// First find out how many vertices we'll need faces = mesh->mFaces;
const char* old = buffer; for (unsigned int i = 0; i < numFaces; ) {
for (unsigned int i = 0; i< mesh->mNumFaces;++i) if(!GetNextLine(buffer,line)) {
{
if(!GetNextLine(buffer,line))
{
ASSIMP_LOG_ERROR("OFF: The number of faces in the header is incorrect"); ASSIMP_LOG_ERROR("OFF: The number of faces in the header is incorrect");
break; break;
} }
sz = line;SkipSpaces(&sz); unsigned int idx;
faces->mNumIndices = strtoul10(sz,&sz); sz = line; SkipSpaces(&sz);
if(!(faces->mNumIndices) || faces->mNumIndices > 9) idx = strtoul10(sz,&sz);
{ if(!idx || idx > 9) {
ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed"); ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed");
--mesh->mNumFaces; --mesh->mNumFaces;
continue; continue;
} }
mesh->mNumVertices += faces->mNumIndices; faces->mNumIndices = idx;
++faces; faces->mIndices = new unsigned int[faces->mNumIndices];
} for (unsigned int m = 0; m < faces->mNumIndices;++m) {
if (!mesh->mNumVertices)
throw DeadlyImportError("OFF: There are no valid faces");
// allocate storage for the output vertices
std::vector<aiVector3D> verts;
verts.reserve(mesh->mNumVertices);
// second: now parse all face indices
buffer = old;
faces = mesh->mFaces;
for (unsigned int i = 0, p = 0; i< mesh->mNumFaces;)
{
if(!GetNextLine(buffer,line))break;
unsigned int idx;
sz = line;SkipSpaces(&sz);
idx = strtoul10(sz,&sz);
if(!(idx) || idx > 9)
continue;
faces->mIndices = new unsigned int [faces->mNumIndices];
for (unsigned int m = 0; m < faces->mNumIndices;++m)
{
SkipSpaces(&sz); SkipSpaces(&sz);
idx = strtoul10(sz,&sz); idx = strtoul10(sz,&sz);
if ((idx) >= numVertices) if (idx >= numVertices) {
{
ASSIMP_LOG_ERROR("OFF: Vertex index is out of range"); ASSIMP_LOG_ERROR("OFF: Vertex index is out of range");
idx = numVertices-1; idx = numVertices - 1;
} }
faces->mIndices[m] = p++; faces->mIndices[m] = idx;
verts.push_back(tempPositions[idx]);
} }
++i; ++i;
++faces; ++faces;
} }
if (mesh->mNumVertices != verts.size()) {
throw DeadlyImportError("OFF: Vertex count mismatch");
}
mesh->mVertices = new aiVector3D[verts.size()];
memcpy(mesh->mVertices, &verts[0], verts.size() * sizeof(aiVector3D));
// generate the output node graph // generate the output node graph
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("<OFFRoot>"); pScene->mRootNode->mName.Set("<OFFRoot>");
@ -248,8 +338,8 @@ void OFFImporter::InternReadFile( const std::string& pFile,
pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE); pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
pScene->mMaterials[0] = pcMat; pScene->mMaterials[0] = pcMat;
const int twosided =1; const int twosided = 1;
pcMat->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED); pcMat->AddProperty(&twosided, 1, AI_MATKEY_TWOSIDED);
} }
#endif // !! ASSIMP_BUILD_NO_OFF_IMPORTER #endif // !! ASSIMP_BUILD_NO_OFF_IMPORTER

View File

@ -105,7 +105,7 @@ bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler ,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiImporterDesc* ObjFileImporter::GetInfo () const { const aiImporterDesc* ObjFileImporter::GetInfo() const {
return &desc; return &desc;
} }
@ -210,22 +210,80 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
ai_assert(false); ai_assert(false);
} }
// Create nodes for the whole scene if (pModel->m_Objects.size() > 0) {
std::vector<aiMesh*> MeshArray;
for (size_t index = 0; index < pModel->m_Objects.size(); ++index ) {
createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray);
}
// Create mesh pointer buffer for this scene unsigned int meshCount = 0;
if (pScene->mNumMeshes > 0) { unsigned int childCount = 0;
pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
for (size_t index =0; index < MeshArray.size(); ++index ) { for(size_t index = 0; index < pModel->m_Objects.size(); ++index) {
pScene->mMeshes[ index ] = MeshArray[ index ]; if(pModel->m_Objects[index]) {
++childCount;
meshCount += (unsigned int)pModel->m_Objects[index]->m_Meshes.size();
}
} }
}
// Create all materials // Allocate space for the child nodes on the root node
createMaterials( pModel, pScene ); pScene->mRootNode->mChildren = new aiNode*[ childCount ];
// Create nodes for the whole scene
std::vector<aiMesh*> MeshArray;
MeshArray.reserve(meshCount);
for (size_t index = 0; index < pModel->m_Objects.size(); ++index) {
createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);
}
ai_assert(pScene->mRootNode->mNumChildren == childCount);
// Create mesh pointer buffer for this scene
if (pScene->mNumMeshes > 0) {
pScene->mMeshes = new aiMesh*[MeshArray.size()];
for (size_t index = 0; index < MeshArray.size(); ++index) {
pScene->mMeshes[index] = MeshArray[index];
}
}
// Create all materials
createMaterials(pModel, pScene);
}else {
if (pModel->m_Vertices.empty()){
return;
}
std::unique_ptr<aiMesh> mesh( new aiMesh );
mesh->mPrimitiveTypes = aiPrimitiveType_POINT;
unsigned int n = (unsigned int)pModel->m_Vertices.size();
mesh->mNumVertices = n;
mesh->mVertices = new aiVector3D[n];
memcpy(mesh->mVertices, pModel->m_Vertices.data(), n*sizeof(aiVector3D) );
if ( !pModel->m_Normals.empty() ) {
mesh->mNormals = new aiVector3D[n];
if (pModel->m_Normals.size() < n) {
throw DeadlyImportError("OBJ: vertex normal index out of range");
}
memcpy(mesh->mNormals, pModel->m_Normals.data(), n*sizeof(aiVector3D));
}
if ( !pModel->m_VertexColors.empty() ){
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
for (unsigned int i = 0; i < n; ++i) {
if (i < pModel->m_VertexColors.size() ) {
const aiVector3D& color = pModel->m_VertexColors[i];
mesh->mColors[0][i] = aiColor4D(color.x, color.y, color.z, 1.0);
}else {
throw DeadlyImportError("OBJ: vertex color index out of range");
}
}
}
pScene->mRootNode->mNumMeshes = 1;
pScene->mRootNode->mMeshes = new unsigned int[1];
pScene->mRootNode->mMeshes[0] = 0;
pScene->mMeshes = new aiMesh*[1];
pScene->mNumMeshes = 1;
pScene->mMeshes[0] = mesh.release();
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -246,9 +304,8 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
pNode->mName = pObject->m_strObjName; pNode->mName = pObject->m_strObjName;
// If we have a parent node, store it // If we have a parent node, store it
if( pParent != NULL ) { ai_assert( NULL != pParent );
appendChildToParentNode( pParent, pNode ); appendChildToParentNode( pParent, pNode );
}
for ( size_t i=0; i< pObject->m_Meshes.size(); ++i ) { for ( size_t i=0; i< pObject->m_Meshes.size(); ++i ) {
unsigned int meshId = pObject->m_Meshes[ i ]; unsigned int meshId = pObject->m_Meshes[ i ];
@ -401,8 +458,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
pMesh->mNumVertices = numIndices; pMesh->mNumVertices = numIndices;
if (pMesh->mNumVertices == 0) { if (pMesh->mNumVertices == 0) {
throw DeadlyImportError( "OBJ: no vertices" ); throw DeadlyImportError( "OBJ: no vertices" );
} else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) { } else if (pMesh->mNumVertices > AI_MAX_VERTICES) {
throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" ); throw DeadlyImportError( "OBJ: Too many vertices" );
} }
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
@ -452,7 +509,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
// Copy all vertex colors // Copy all vertex colors
if ( !pModel->m_VertexColors.empty()) if ( !pModel->m_VertexColors.empty())
{ {
const aiVector3D color = pModel->m_VertexColors[ vertex ]; const aiVector3D& color = pModel->m_VertexColors[ vertex ];
pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0); pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0);
} }
@ -729,25 +786,8 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
// Assign parent to child // Assign parent to child
pChild->mParent = pParent; pChild->mParent = pParent;
// If already children was assigned to the parent node, store them in a
std::vector<aiNode*> temp;
if (pParent->mChildren != NULL)
{
ai_assert( 0 != pParent->mNumChildren );
for (size_t index = 0; index < pParent->mNumChildren; index++)
{
temp.push_back(pParent->mChildren [ index ] );
}
delete [] pParent->mChildren;
}
// Copy node instances into parent node // Copy node instances into parent node
pParent->mNumChildren++; pParent->mNumChildren++;
pParent->mChildren = new aiNode*[ pParent->mNumChildren ];
for (size_t index = 0; index < pParent->mNumChildren-1; index++)
{
pParent->mChildren[ index ] = temp [ index ];
}
pParent->mChildren[ pParent->mNumChildren-1 ] = pChild; pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
} }

View File

@ -332,6 +332,11 @@ void ObjFileMtlImporter::getTexture() {
// Specular texture // Specular texture
out = & m_pModel->m_pCurrentMaterial->textureSpecular; out = & m_pModel->m_pCurrentMaterial->textureSpecular;
clampIndex = ObjFile::Material::TextureSpecularType; clampIndex = ObjFile::Material::TextureSpecularType;
} else if ( !ASSIMP_strincmp( pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size()) ) ||
!ASSIMP_strincmp( pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()) ) ) {
// Displacement texture
out = &m_pModel->m_pCurrentMaterial->textureDisp;
clampIndex = ObjFile::Material::TextureDispType;
} else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()) ) ) { } else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()) ) ) {
// Opacity texture // Opacity texture
out = & m_pModel->m_pCurrentMaterial->textureOpacity; out = & m_pModel->m_pCurrentMaterial->textureOpacity;
@ -354,11 +359,6 @@ void ObjFileMtlImporter::getTexture() {
// Reflection texture(s) // Reflection texture(s)
//Do nothing here //Do nothing here
return; return;
} else if ( !ASSIMP_strincmp( pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size()) ) ||
!ASSIMP_strincmp( pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()) ) ) {
// Displacement texture
out = &m_pModel->m_pCurrentMaterial->textureDisp;
clampIndex = ObjFile::Material::TextureDispType;
} else if ( !ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()) ) ) { } else if ( !ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()) ) ) {
// Specularity scaling (glossiness) // Specularity scaling (glossiness)
out = & m_pModel->m_pCurrentMaterial->textureSpecularity; out = & m_pModel->m_pCurrentMaterial->textureSpecularity;

View File

@ -67,20 +67,22 @@ namespace Assimp {
class OptimizeMeshesProcess : public BaseProcess class OptimizeMeshesProcess : public BaseProcess
{ {
public: public:
/// @brief The class constructor.
OptimizeMeshesProcess(); OptimizeMeshesProcess();
/// @brief The class destcructor,
~OptimizeMeshesProcess(); ~OptimizeMeshesProcess();
/** @brief Internal utility to store additional mesh info /** @brief Internal utility to store additional mesh info
*/ */
struct MeshInfo struct MeshInfo {
{ MeshInfo() AI_NO_EXCEPT
MeshInfo() : instance_cnt(0)
: instance_cnt (0) , vertex_format(0)
, vertex_format (0) , output_id(0xffffffff) {
, output_id (0xffffffff) // empty
{} }
//! Number of times this mesh is referenced //! Number of times this mesh is referenced
unsigned int instance_cnt; unsigned int instance_cnt;

View File

@ -209,7 +209,7 @@ enum EElementSemantic {
class Property { class Property {
public: public:
//! Default constructor //! Default constructor
Property() Property() AI_NO_EXCEPT
: eType (EDT_Int) : eType (EDT_Int)
, Semantic() , Semantic()
, bIsList(false) , bIsList(false)
@ -257,7 +257,7 @@ public:
class Element { class Element {
public: public:
//! Default constructor //! Default constructor
Element() Element() AI_NO_EXCEPT
: eSemantic (EEST_INVALID) : eSemantic (EEST_INVALID)
, NumOccur(0) { , NumOccur(0) {
// empty // empty
@ -297,8 +297,9 @@ class PropertyInstance
public: public:
//! Default constructor //! Default constructor
PropertyInstance () PropertyInstance() AI_NO_EXCEPT {
{} // empty
}
union ValueUnion union ValueUnion
{ {
@ -356,13 +357,13 @@ public:
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
/** \brief Class for an element instance in a PLY file /** \brief Class for an element instance in a PLY file
*/ */
class ElementInstance class ElementInstance {
{
public: public:
//! Default constructor //! Default constructor
ElementInstance () ElementInstance() AI_NO_EXCEPT
{} : alProperties() {
// empty
}
//! List of all parsed properties //! List of all parsed properties
std::vector< PropertyInstance > alProperties; std::vector< PropertyInstance > alProperties;
@ -386,8 +387,10 @@ class ElementInstanceList
public: public:
//! Default constructor //! Default constructor
ElementInstanceList () ElementInstanceList() AI_NO_EXCEPT
{} : alInstances() {
// empty
}
//! List of all element instances //! List of all element instances
std::vector< ElementInstance > alInstances; std::vector< ElementInstance > alInstances;
@ -411,8 +414,11 @@ class DOM
public: public:
//! Default constructor //! Default constructor
DOM() DOM() AI_NO_EXCEPT
{} : alElements()
, alElementData() {
}
//! Contains all elements of the file format //! Contains all elements of the file format

View File

@ -62,6 +62,9 @@ corresponding preprocessor flag to selectively disable steps.
#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS #ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
# include "TriangulateProcess.h" # include "TriangulateProcess.h"
#endif #endif
#ifndef ASSIMP_BUILD_NO_DROPFACENORMALS_PROCESS
# include "DropFaceNormalsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS #ifndef ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS
# include "GenFaceNormalsProcess.h" # include "GenFaceNormalsProcess.h"
#endif #endif
@ -200,6 +203,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS) #if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
out.push_back( new SplitLargeMeshesProcess_Triangle()); out.push_back( new SplitLargeMeshesProcess_Triangle());
#endif #endif
#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
out.push_back( new DropFaceNormalsProcess());
#endif
#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS) #if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
out.push_back( new GenFaceNormalsProcess()); out.push_back( new GenFaceNormalsProcess());
#endif #endif

View File

@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ASSIMP_Q3BSPFILEDATA_H_INC #define ASSIMP_Q3BSPFILEDATA_H_INC
#include <vector> #include <vector>
#include <string.h> //memset #include <string.h>
#include <string> #include <string>
namespace Assimp { namespace Assimp {
@ -77,25 +77,21 @@ struct sQ3BSPHeader {
}; };
/// Describes an entry. /// Describes an entry.
struct sQ3BSPLump struct sQ3BSPLump {
{
int iOffset; ///< Offset from start pointer of file int iOffset; ///< Offset from start pointer of file
int iSize; ///< Size of part int iSize; ///< Size of part
}; };
struct vec2f struct vec2f {
{
float x,y; float x,y;
}; };
struct vec3f struct vec3f {
{
float x, y, z; float x, y, z;
}; };
/// Vertex of a Q3 level /// Vertex of a Q3 level
struct sQ3BSPVertex struct sQ3BSPVertex {
{
vec3f vPosition; ///< Position of vertex vec3f vPosition; ///< Position of vertex
vec2f vTexCoord; ///< (u,v) Texturecoordinate of detailtexture vec2f vTexCoord; ///< (u,v) Texturecoordinate of detailtexture
vec2f vLightmap; ///< (u,v) Texturecoordinate of lightmap vec2f vLightmap; ///< (u,v) Texturecoordinate of lightmap
@ -104,8 +100,7 @@ struct sQ3BSPVertex
}; };
/// A face in bsp format info /// A face in bsp format info
struct sQ3BSPFace struct sQ3BSPFace {
{
int iTextureID; ///< Index in texture array int iTextureID; ///< Index in texture array
int iEffect; ///< Index in effect array (-1 = no effect) int iEffect; ///< Index in effect array (-1 = no effect)
int iType; ///< 1=Polygon, 2=Patch, 3=Mesh, 4=Billboard int iType; ///< 1=Polygon, 2=Patch, 3=Mesh, 4=Billboard

View File

@ -47,6 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Q3BSPFileParser.h" #include "Q3BSPFileParser.h"
#include "Q3BSPFileData.h" #include "Q3BSPFileData.h"
#include <assimp/DefaultLogger.hpp>
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h> # include <zlib.h>
#else #else
@ -82,39 +84,39 @@ using namespace Q3BSP;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Local function to create a material key name. // Local function to create a material key name.
static void createKey( int id1, int id2, std::string &rKey ) static void createKey( int id1, int id2, std::string &key ) {
{
std::ostringstream str; std::ostringstream str;
str << id1 << "." << id2; str << id1 << "." << id2;
rKey = str.str(); key = str.str();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Local function to extract the texture ids from a material key-name. // Local function to extract the texture ids from a material key-name.
static void extractIds( const std::string &rKey, int &rId1, int &rId2 ) static void extractIds( const std::string &key, int &id1, int &id2 ) {
{ id1 = -1;
rId1 = -1; id2 = -1;
rId2 = -1; if (key.empty()) {
if ( rKey.empty() )
return; return;
}
std::string::size_type pos = rKey.find( "." ); const std::string::size_type pos = key.find( "." );
if ( std::string::npos == pos ) if (std::string::npos == pos) {
return; return;
}
std::string tmp1 = rKey.substr( 0, pos ); std::string tmp1 = key.substr( 0, pos );
std::string tmp2 = rKey.substr( pos + 1, rKey.size() - pos - 1 ); std::string tmp2 = key.substr( pos + 1, key.size() - pos - 1 );
rId1 = atoi( tmp1.c_str() ); id1 = atoi( tmp1.c_str() );
rId2 = atoi( tmp2.c_str() ); id2 = atoi( tmp2.c_str() );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Local helper function to normalize filenames. // Local helper function to normalize filenames.
static void normalizePathName( const std::string &rPath, std::string &rNormalizedPath ) static void normalizePathName( const std::string &rPath, std::string &normalizedPath ) {
{ normalizedPath = "";
rNormalizedPath = ""; if (rPath.empty()) {
if ( rPath.empty() )
return; return;
}
#ifdef _WIN32 #ifdef _WIN32
std::string sep = "\\"; std::string sep = "\\";
@ -124,14 +126,11 @@ static void normalizePathName( const std::string &rPath, std::string &rNormalize
static const unsigned int numDelimiters = 2; static const unsigned int numDelimiters = 2;
const char delimiters[ numDelimiters ] = { '/', '\\' }; const char delimiters[ numDelimiters ] = { '/', '\\' };
rNormalizedPath = rPath; normalizedPath = rPath;
for (const char delimiter : delimiters) for (const char delimiter : delimiters) {
{ for ( size_t j=0; j<normalizedPath.size(); ++j ) {
for ( size_t j=0; j<rNormalizedPath.size(); j++ ) if ( normalizedPath[j] == delimiter ) {
{ normalizedPath[ j ] = sep[ 0 ];
if ( rNormalizedPath[j] == delimiter )
{
rNormalizedPath[ j ] = sep[ 0 ];
} }
} }
} }
@ -139,20 +138,19 @@ static void normalizePathName( const std::string &rPath, std::string &rNormalize
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor. // Constructor.
Q3BSPFileImporter::Q3BSPFileImporter() : Q3BSPFileImporter::Q3BSPFileImporter()
m_pCurrentMesh( NULL ), : m_pCurrentMesh( nullptr )
m_pCurrentFace( NULL ), , m_pCurrentFace(nullptr)
m_MaterialLookupMap(), , m_MaterialLookupMap()
mTextures() , mTextures() {
{
// empty // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor. // Destructor.
Q3BSPFileImporter::~Q3BSPFileImporter() { Q3BSPFileImporter::~Q3BSPFileImporter() {
m_pCurrentMesh = NULL; m_pCurrentMesh = nullptr;
m_pCurrentFace = NULL; m_pCurrentFace = nullptr;
// Clear face-to-material map // Clear face-to-material map
for ( FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it ) { for ( FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it ) {
@ -166,92 +164,80 @@ Q3BSPFileImporter::~Q3BSPFileImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if the loader can read this. // Returns true, if the loader can read this.
bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const {
{
if(!checkSig) { if(!checkSig) {
return SimpleExtensionCheck( rFile, "pk3", "bsp" ); return SimpleExtensionCheck( rFile, "pk3", "bsp" );
} }
// TODO perhaps add keyword based detection
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Adds extensions. // Adds extensions.
const aiImporterDesc* Q3BSPFileImporter::GetInfo () const const aiImporterDesc* Q3BSPFileImporter::GetInfo () const {
{
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Import method. // Import method.
void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* pIOHandler) void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* scene, IOSystem* ioHandler) {
{ Q3BSPZipArchive Archive( ioHandler, rFile );
Q3BSPZipArchive Archive( pIOHandler, rFile ); if ( !Archive.isOpen() ) {
if ( !Archive.isOpen() )
{
throw DeadlyImportError( "Failed to open file " + rFile + "." ); throw DeadlyImportError( "Failed to open file " + rFile + "." );
} }
std::string archiveName( "" ), mapName( "" ); std::string archiveName( "" ), mapName( "" );
separateMapName( rFile, archiveName, mapName ); separateMapName( rFile, archiveName, mapName );
if ( mapName.empty() ) if ( mapName.empty() ) {
{ if ( !findFirstMapInArchive( Archive, mapName ) ) {
if ( !findFirstMapInArchive( Archive, mapName ) )
{
return; return;
} }
} }
Q3BSPFileParser fileParser( mapName, &Archive ); Q3BSPFileParser fileParser( mapName, &Archive );
Q3BSPModel *pBSPModel = fileParser.getModel(); Q3BSPModel *pBSPModel = fileParser.getModel();
if ( NULL != pBSPModel ) if ( nullptr != pBSPModel ) {
{ CreateDataFromImport( pBSPModel, scene, &Archive );
CreateDataFromImport( pBSPModel, pScene, &Archive );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Separates the map name from the import name. // Separates the map name from the import name.
void Q3BSPFileImporter::separateMapName( const std::string &rImportName, std::string &rArchiveName, void Q3BSPFileImporter::separateMapName( const std::string &importName, std::string &archiveName, std::string &mapName ) {
std::string &rMapName ) archiveName = "";
{ mapName = "";
rArchiveName = ""; if (importName.empty()) {
rMapName = "";
if ( rImportName.empty() )
return;
std::string::size_type pos = rImportName.rfind( "," );
if ( std::string::npos == pos )
{
rArchiveName = rImportName;
return; return;
} }
rArchiveName = rImportName.substr( 0, pos ); const std::string::size_type pos = importName.rfind( "," );
rMapName = rImportName.substr( pos, rImportName.size() - pos - 1 ); if ( std::string::npos == pos ) {
archiveName = importName;
return;
}
archiveName = importName.substr( 0, pos );
mapName = importName.substr( pos, importName.size() - pos - 1 );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the first map in the map archive. // Returns the first map in the map archive.
bool Q3BSPFileImporter::findFirstMapInArchive( Q3BSPZipArchive &rArchive, std::string &rMapName ) bool Q3BSPFileImporter::findFirstMapInArchive( Q3BSPZipArchive &bspArchive, std::string &mapName ) {
{ mapName = "";
rMapName = "";
std::vector<std::string> fileList; std::vector<std::string> fileList;
rArchive.getFileList( fileList ); bspArchive.getFileList( fileList );
if ( fileList.empty() ) if (fileList.empty()) {
return false; return false;
}
for ( std::vector<std::string>::iterator it = fileList.begin(); it != fileList.end(); std::vector<std::string>::iterator it( fileList.begin() );
++it ) for ( ; it != fileList.end(); ++it ) {
{ const std::string::size_type pos = (*it).find( "maps/" );
std::string::size_type pos = (*it).find( "maps/" ); if ( std::string::npos != pos ) {
if ( std::string::npos != pos )
{
std::string::size_type extPos = (*it).find( ".bsp" ); std::string::size_type extPos = (*it).find( ".bsp" );
if ( std::string::npos != extPos ) if ( std::string::npos != extPos ) {
{ mapName = *it;
rMapName = *it;
return true; return true;
} }
} }
@ -263,14 +249,13 @@ bool Q3BSPFileImporter::findFirstMapInArchive( Q3BSPZipArchive &rArchive, std::s
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates the assimp specific data. // Creates the assimp specific data.
void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
Q3BSPZipArchive *pArchive ) Q3BSPZipArchive *pArchive ) {
{ if (nullptr == pModel || nullptr == pScene) {
if ( NULL == pModel || NULL == pScene )
return; return;
}
pScene->mRootNode = new aiNode; pScene->mRootNode = new aiNode;
if ( !pModel->m_ModelName.empty() ) if ( !pModel->m_ModelName.empty() ) {
{
pScene->mRootNode->mName.Set( pModel->m_ModelName ); pScene->mRootNode->mName.Set( pModel->m_ModelName );
} }
@ -287,47 +272,34 @@ void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, a
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates all assimp nodes. // Creates all assimp nodes.
void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
aiNode *pParent ) aiNode *pParent ) {
{ if ( nullptr == pModel ) {
ai_assert( NULL != pModel );
if ( NULL == pModel )
{
return; return;
} }
unsigned int matIdx = 0; unsigned int matIdx( 0 );
std::vector<aiMesh*> MeshArray; std::vector<aiMesh*> MeshArray;
std::vector<aiNode*> NodeArray; std::vector<aiNode*> NodeArray;
for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it ) for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it ) {
{
std::vector<Q3BSP::sQ3BSPFace*> *pArray = (*it).second; std::vector<Q3BSP::sQ3BSPFace*> *pArray = (*it).second;
size_t numVerts = countData( *pArray ); size_t numVerts = countData( *pArray );
if ( 0 != numVerts ) if ( 0 != numVerts ) {
{ aiMesh *pMesh( nullptr );
aiMesh* pMesh = new aiMesh; aiNode *pNode = CreateTopology( pModel, matIdx, *pArray, &pMesh );
aiNode *pNode = CreateTopology( pModel, matIdx, *pArray, pMesh ); if ( nullptr != pNode ) {
if ( NULL != pNode )
{
NodeArray.push_back( pNode ); NodeArray.push_back( pNode );
MeshArray.push_back( pMesh ); MeshArray.push_back( pMesh );
} }
else
{
delete pMesh;
}
} }
matIdx++; matIdx++;
} }
pScene->mNumMeshes = static_cast<unsigned int>( MeshArray.size() ); pScene->mNumMeshes = static_cast<unsigned int>( MeshArray.size() );
if ( pScene->mNumMeshes > 0 ) if ( pScene->mNumMeshes > 0 ) {
{
pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ]; pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
for ( size_t i = 0; i < MeshArray.size(); i++ ) for ( size_t i = 0; i < MeshArray.size(); i++ ) {
{
aiMesh *pMesh = MeshArray[ i ]; aiMesh *pMesh = MeshArray[ i ];
if ( NULL != pMesh ) if ( nullptr != pMesh ) {
{
pScene->mMeshes[ i ] = pMesh; pScene->mMeshes[ i ] = pMesh;
} }
} }
@ -335,8 +307,7 @@ void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* p
pParent->mNumChildren = static_cast<unsigned int>(MeshArray.size()); pParent->mNumChildren = static_cast<unsigned int>(MeshArray.size());
pParent->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren ]; pParent->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren ];
for ( size_t i=0; i<NodeArray.size(); i++ ) for ( size_t i=0; i<NodeArray.size(); i++ ) {
{
aiNode *pNode = NodeArray[ i ]; aiNode *pNode = NodeArray[ i ];
pNode->mParent = pParent; pNode->mParent = pParent;
pParent->mChildren[ i ] = pNode; pParent->mChildren[ i ] = pNode;
@ -346,54 +317,46 @@ void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* p
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates the topology. // Creates the topology.
aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel, aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int materialIdx,
unsigned int materialIdx, std::vector<sQ3BSPFace*> &rArray, aiMesh **pMesh ) {
std::vector<sQ3BSPFace*> &rArray,
aiMesh* pMesh )
{
size_t numVerts = countData( rArray ); size_t numVerts = countData( rArray );
if ( 0 == numVerts ) if ( 0 == numVerts ) {
{ return nullptr;
return NULL;
} }
size_t numFaces = countFaces( rArray ); size_t numFaces = countFaces( rArray );
if ( 0 == numFaces ) if ( 0 == numFaces ) {
{ return nullptr;
return NULL;
} }
aiMesh *mesh = new aiMesh;
size_t numTriangles = countTriangles( rArray ); size_t numTriangles = countTriangles( rArray );
pMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
pMesh->mFaces = new aiFace[ numTriangles ]; mesh->mFaces = new aiFace[ numTriangles ];
pMesh->mNumFaces = static_cast<unsigned int>(numTriangles); mesh->mNumFaces = static_cast<unsigned int>(numTriangles);
pMesh->mNumVertices = static_cast<unsigned int>(numVerts); mesh->mNumVertices = static_cast<unsigned int>(numVerts);
pMesh->mVertices = new aiVector3D[ numVerts ]; mesh->mVertices = new aiVector3D[ numVerts ];
pMesh->mNormals = new aiVector3D[ numVerts ]; mesh->mNormals = new aiVector3D[ numVerts ];
pMesh->mTextureCoords[ 0 ] = new aiVector3D[ numVerts ]; mesh->mTextureCoords[ 0 ] = new aiVector3D[ numVerts ];
pMesh->mTextureCoords[ 1 ] = new aiVector3D[ numVerts ]; mesh->mTextureCoords[ 1 ] = new aiVector3D[ numVerts ];
pMesh->mMaterialIndex = materialIdx; mesh->mMaterialIndex = materialIdx;
unsigned int faceIdx = 0; unsigned int faceIdx = 0;
unsigned int vertIdx = 0; unsigned int vertIdx = 0;
pMesh->mNumUVComponents[ 0 ] = 2; mesh->mNumUVComponents[ 0 ] = 2;
pMesh->mNumUVComponents[ 1 ] = 2; mesh->mNumUVComponents[ 1 ] = 2;
for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); ++it ) for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); ++it ) {
{
Q3BSP::sQ3BSPFace *pQ3BSPFace = *it; Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
ai_assert( NULL != pQ3BSPFace ); ai_assert( NULL != pQ3BSPFace );
if ( NULL == pQ3BSPFace ) if ( nullptr == pQ3BSPFace ) {
{
continue; continue;
} }
if ( pQ3BSPFace->iNumOfFaceVerts > 0 ) if ( pQ3BSPFace->iNumOfFaceVerts > 0 ) {
{ if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh ) {
if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh ) createTriangleTopology( pModel, pQ3BSPFace, mesh, faceIdx, vertIdx );
{
createTriangleTopology( pModel, pQ3BSPFace, pMesh, faceIdx, vertIdx );
} }
} }
} }
@ -401,79 +364,63 @@ aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel,
aiNode *pNode = new aiNode; aiNode *pNode = new aiNode;
pNode->mNumMeshes = 1; pNode->mNumMeshes = 1;
pNode->mMeshes = new unsigned int[ 1 ]; pNode->mMeshes = new unsigned int[ 1 ];
*pMesh = mesh;
return pNode; return pNode;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates the triangle topology from a face array. // Creates the triangle topology from a face array.
void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, sQ3BSPFace *pQ3BSPFace,
Q3BSP::sQ3BSPFace *pQ3BSPFace, aiMesh* pMesh, unsigned int &faceIdx, unsigned int &vertIdx ) {
aiMesh* pMesh, ai_assert( faceIdx < pMesh->mNumFaces );
unsigned int &rFaceIdx,
unsigned int &rVertIdx )
{
ai_assert( rFaceIdx < pMesh->mNumFaces );
m_pCurrentFace = getNextFace( pMesh, rFaceIdx ); m_pCurrentFace = getNextFace( pMesh, faceIdx );
ai_assert( NULL != m_pCurrentFace ); if ( nullptr == m_pCurrentFace ) {
if ( NULL == m_pCurrentFace )
{
return; return;
} }
m_pCurrentFace->mNumIndices = 3; m_pCurrentFace->mNumIndices = 3;
m_pCurrentFace->mIndices = new unsigned int[ m_pCurrentFace->mNumIndices ]; m_pCurrentFace->mIndices = new unsigned int[ m_pCurrentFace->mNumIndices ];
size_t idx = 0; size_t idx( 0 );
for ( size_t i = 0; i < (size_t) pQ3BSPFace->iNumOfFaceVerts; i++ ) for ( size_t i = 0; i < (size_t) pQ3BSPFace->iNumOfFaceVerts; ++i ) {
{
const size_t index = pQ3BSPFace->iVertexIndex + pModel->m_Indices[ pQ3BSPFace->iFaceVertexIndex + i ]; const size_t index = pQ3BSPFace->iVertexIndex + pModel->m_Indices[ pQ3BSPFace->iFaceVertexIndex + i ];
ai_assert( index < pModel->m_Vertices.size() ); if ( index >= pModel->m_Vertices.size() ) {
if ( index >= pModel->m_Vertices.size() )
{
continue; continue;
} }
sQ3BSPVertex *pVertex = pModel->m_Vertices[ index ]; sQ3BSPVertex *pVertex = pModel->m_Vertices[ index ];
ai_assert( NULL != pVertex ); if ( nullptr == pVertex ) {
if ( NULL == pVertex )
{
continue; continue;
} }
if (idx > 2) {
pMesh->mVertices[ rVertIdx ].Set( pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z );
pMesh->mNormals[ rVertIdx ].Set( pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z );
pMesh->mTextureCoords[ 0 ][ rVertIdx ].Set( pVertex->vTexCoord.x, pVertex->vTexCoord.y, 0.0f );
pMesh->mTextureCoords[ 1 ][ rVertIdx ].Set( pVertex->vLightmap.x, pVertex->vLightmap.y, 0.0f );
ai_assert( m_pCurrentFace );
m_pCurrentFace->mIndices[ idx ] = rVertIdx;
rVertIdx++;
idx++;
if ( idx > 2 )
{
idx = 0; idx = 0;
m_pCurrentFace = getNextFace( pMesh, rFaceIdx ); m_pCurrentFace = getNextFace(pMesh, faceIdx);
if ( NULL != m_pCurrentFace ) if (nullptr != m_pCurrentFace) {
{
m_pCurrentFace->mNumIndices = 3; m_pCurrentFace->mNumIndices = 3;
m_pCurrentFace->mIndices = new unsigned int[ 3 ]; m_pCurrentFace->mIndices = new unsigned int[3];
} }
} }
pMesh->mVertices[ vertIdx ].Set( pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z );
pMesh->mNormals[ vertIdx ].Set( pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z );
pMesh->mTextureCoords[ 0 ][ vertIdx ].Set( pVertex->vTexCoord.x, pVertex->vTexCoord.y, 0.0f );
pMesh->mTextureCoords[ 1 ][ vertIdx ].Set( pVertex->vLightmap.x, pVertex->vLightmap.y, 0.0f );
m_pCurrentFace->mIndices[ idx ] = vertIdx;
vertIdx++;
idx++;
} }
rFaceIdx--;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates all referenced materials. // Creates all referenced materials.
void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
Q3BSPZipArchive *pArchive ) Q3BSPZipArchive *pArchive ) {
{ if ( m_MaterialLookupMap.empty() ) {
if ( m_MaterialLookupMap.empty() )
{
return; return;
} }
@ -481,11 +428,9 @@ void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScen
aiString aiMatName; aiString aiMatName;
int textureId( -1 ), lightmapId( -1 ); int textureId( -1 ), lightmapId( -1 );
for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end();
++it ) ++it ) {
{ const std::string matName( it->first );
const std::string matName = (*it).first; if ( matName.empty() ) {
if ( matName.empty() )
{
continue; continue;
} }
@ -496,18 +441,16 @@ void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScen
extractIds( matName, textureId, lightmapId ); extractIds( matName, textureId, lightmapId );
// Adding the texture // Adding the texture
if ( -1 != textureId ) if ( -1 != textureId ) {
{
sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ]; sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ];
if ( NULL != pTexture ) if ( nullptr != pTexture ) {
{
std::string tmp( "*" ), texName( "" ); std::string tmp( "*" ), texName( "" );
tmp += pTexture->strName; tmp += pTexture->strName;
tmp += ".jpg"; tmp += ".jpg";
normalizePathName( tmp, texName ); normalizePathName( tmp, texName );
if ( !importTextureFromArchive( pModel, pArchive, pScene, pMatHelper, textureId ) ) if ( !importTextureFromArchive( pModel, pArchive, pScene, pMatHelper, textureId ) ) {
{ ASSIMP_LOG_ERROR("Cannot import texture from archive " + texName);
} }
} }
@ -526,17 +469,16 @@ void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScen
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Counts the number of referenced vertices. // Counts the number of referenced vertices.
size_t Q3BSPFileImporter::countData( const std::vector<sQ3BSPFace*> &rArray ) const size_t Q3BSPFileImporter::countData( const std::vector<sQ3BSPFace*> &faceArray ) const {
{ size_t numVerts( 0 );
size_t numVerts = 0; for ( std::vector<sQ3BSPFace*>::const_iterator it = faceArray.begin(); it != faceArray.end();
for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end();
++it ) ++it )
{ {
sQ3BSPFace *pQ3BSPFace = *it; sQ3BSPFace *pQ3BSPFace = *it;
if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh ) if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh )
{ {
Q3BSP::sQ3BSPFace *pQ3BSPFace = *it; Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
ai_assert( NULL != pQ3BSPFace ); ai_assert( nullptr != pQ3BSPFace );
numVerts += pQ3BSPFace->iNumOfFaceVerts; numVerts += pQ3BSPFace->iNumOfFaceVerts;
} }
} }
@ -582,8 +524,7 @@ size_t Q3BSPFileImporter::countTriangles( const std::vector<Q3BSP::sQ3BSPFace*>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates the faces-to-material map. // Creates the faces-to-material map.
void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel ) void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel ) {
{
std::string key( "" ); std::string key( "" );
std::vector<sQ3BSPFace*> *pCurFaceArray = NULL; std::vector<sQ3BSPFace*> *pCurFaceArray = NULL;
for ( size_t idx = 0; idx < pModel->m_Faces.size(); idx++ ) for ( size_t idx = 0; idx < pModel->m_Faces.size(); idx++ )
@ -593,8 +534,7 @@ void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel )
const int lightMapId = pQ3BSPFace->iLightmapID; const int lightMapId = pQ3BSPFace->iLightmapID;
createKey( texId, lightMapId, key ); createKey( texId, lightMapId, key );
FaceMapIt it = m_MaterialLookupMap.find( key ); FaceMapIt it = m_MaterialLookupMap.find( key );
if ( m_MaterialLookupMap.end() == it ) if ( m_MaterialLookupMap.end() == it ) {
{
pCurFaceArray = new std::vector<Q3BSP::sQ3BSPFace*>; pCurFaceArray = new std::vector<Q3BSP::sQ3BSPFace*>;
m_MaterialLookupMap[ key ] = pCurFaceArray; m_MaterialLookupMap[ key ] = pCurFaceArray;
} }
@ -602,8 +542,8 @@ void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel )
{ {
pCurFaceArray = (*it).second; pCurFaceArray = (*it).second;
} }
ai_assert( NULL != pCurFaceArray ); ai_assert( nullptr != pCurFaceArray );
if ( NULL != pCurFaceArray ) if (nullptr != pCurFaceArray )
{ {
pCurFaceArray->push_back( pQ3BSPFace ); pCurFaceArray->push_back( pQ3BSPFace );
} }
@ -612,32 +552,31 @@ void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel )
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the next face. // Returns the next face.
aiFace *Q3BSPFileImporter::getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx ) aiFace *Q3BSPFileImporter::getNextFace( aiMesh *mesh, unsigned int &faceIdx ) {
{ aiFace *face( nullptr );
aiFace *pFace( NULL ); if ( faceIdx < mesh->mNumFaces ) {
if ( rFaceIdx < pMesh->mNumFaces ) { face = &mesh->mFaces[ faceIdx ];
pFace = &pMesh->mFaces[ rFaceIdx ]; ++faceIdx;
rFaceIdx++;
} }
return pFace; return face;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports a texture file. // Imports a texture file.
bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel, bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *model,
Q3BSP::Q3BSPZipArchive *pArchive, aiScene*, Q3BSP::Q3BSPZipArchive *archive, aiScene*,
aiMaterial *pMatHelper, int textureId ) { aiMaterial *pMatHelper, int textureId ) {
if ( NULL == pArchive || NULL == pMatHelper ) { if (nullptr == archive || nullptr == pMatHelper ) {
return false; return false;
} }
if ( textureId < 0 || textureId >= static_cast<int>( pModel->m_Textures.size() ) ) { if ( textureId < 0 || textureId >= static_cast<int>( model->m_Textures.size() ) ) {
return false; return false;
} }
bool res = true; bool res = true;
sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ]; sQ3BSPTexture *pTexture = model->m_Textures[ textureId ];
if ( !pTexture ) { if ( !pTexture ) {
return false; return false;
} }
@ -647,8 +586,8 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode
supportedExtensions.push_back( ".png" ); supportedExtensions.push_back( ".png" );
supportedExtensions.push_back( ".tga" ); supportedExtensions.push_back( ".tga" );
std::string textureName, ext; std::string textureName, ext;
if ( expandFile( pArchive, pTexture->strName, supportedExtensions, textureName, ext ) ) { if ( expandFile( archive, pTexture->strName, supportedExtensions, textureName, ext ) ) {
IOStream *pTextureStream = pArchive->Open( textureName.c_str() ); IOStream *pTextureStream = archive->Open( textureName.c_str() );
if ( pTextureStream ) { if ( pTextureStream ) {
size_t texSize = pTextureStream->FileSize(); size_t texSize = pTextureStream->FileSize();
aiTexture *pTexture = new aiTexture; aiTexture *pTexture = new aiTexture;
@ -669,7 +608,7 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode
name.data[ 0 ] = '*'; name.data[ 0 ] = '*';
name.length = 1 + ASSIMP_itoa10( name.data + 1, static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(mTextures.size()) ); name.length = 1 + ASSIMP_itoa10( name.data + 1, static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(mTextures.size()) );
pArchive->Close( pTextureStream ); archive->Close( pTextureStream );
pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) ); pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
mTextures.push_back( pTexture ); mTextures.push_back( pTexture );
@ -691,19 +630,16 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode
bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
aiMaterial *pMatHelper, int lightmapId ) aiMaterial *pMatHelper, int lightmapId )
{ {
if ( NULL == pModel || NULL == pScene || NULL == pMatHelper ) if (nullptr == pModel || nullptr == pScene || nullptr == pMatHelper ) {
{
return false; return false;
} }
if ( lightmapId < 0 || lightmapId >= static_cast<int>( pModel->m_Lightmaps.size() ) ) if ( lightmapId < 0 || lightmapId >= static_cast<int>( pModel->m_Lightmaps.size() ) ) {
{
return false; return false;
} }
sQ3BSPLightmap *pLightMap = pModel->m_Lightmaps[ lightmapId ]; sQ3BSPLightmap *pLightMap = pModel->m_Lightmaps[ lightmapId ];
if ( NULL == pLightMap ) if (nullptr == pLightMap ) {
{
return false; return false;
} }
@ -715,8 +651,7 @@ bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene
::memcpy( pTexture->pcData, pLightMap->bLMapData, pTexture->mWidth ); ::memcpy( pTexture->pcData, pLightMap->bLMapData, pTexture->mWidth );
size_t p = 0; size_t p = 0;
for ( size_t i = 0; i < CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT; ++i ) for ( size_t i = 0; i < CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT; ++i ) {
{
pTexture->pcData[ i ].r = pLightMap->bLMapData[ p++ ]; pTexture->pcData[ i ].r = pLightMap->bLMapData[ p++ ];
pTexture->pcData[ i ].g = pLightMap->bLMapData[ p++ ]; pTexture->pcData[ i ].g = pLightMap->bLMapData[ p++ ];
pTexture->pcData[ i ].b = pLightMap->bLMapData[ p++ ]; pTexture->pcData[ i ].b = pLightMap->bLMapData[ p++ ];
@ -733,7 +668,6 @@ bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene
return true; return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Will search for a supported extension. // Will search for a supported extension.
bool Q3BSPFileImporter::expandFile( Q3BSP::Q3BSPZipArchive *pArchive, const std::string &rFilename, bool Q3BSPFileImporter::expandFile( Q3BSP::Q3BSPZipArchive *pArchive, const std::string &rFilename,

View File

@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <map> #include <map>
#include <string>
struct aiMesh; struct aiMesh;
struct aiNode; struct aiNode;
@ -53,6 +54,7 @@ struct aiMaterial;
struct aiTexture; struct aiTexture;
namespace Assimp { namespace Assimp {
namespace Q3BSP { namespace Q3BSP {
class Q3BSPZipArchive; class Q3BSPZipArchive;
struct Q3BSPModel; struct Q3BSPModel;
@ -71,12 +73,11 @@ public:
/// @brief Destructor. /// @brief Destructor.
~Q3BSPFileImporter(); ~Q3BSPFileImporter();
public:
/// @brief Returns whether the class can handle the format of the given file. /// @brief Returns whether the class can handle the format of the given file.
/// @remark See BaseImporter::CanRead() for details. /// @remark See BaseImporter::CanRead() for details.
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const; bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const;
private: protected:
typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*> FaceMap; typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*> FaceMap;
typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>* >::iterator FaceMapIt; typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>* >::iterator FaceMapIt;
typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*>::const_iterator FaceMapConstIt; typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*>::const_iterator FaceMapConstIt;
@ -88,7 +89,7 @@ private:
void CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive ); void CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive );
void CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiNode *pParent ); void CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiNode *pParent );
aiNode *CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int materialIdx, aiNode *CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int materialIdx,
std::vector<Q3BSP::sQ3BSPFace*> &rArray, aiMesh* pMesh ); std::vector<Q3BSP::sQ3BSPFace*> &rArray, aiMesh **pMesh );
void createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, Q3BSP::sQ3BSPFace *pQ3BSPFace, aiMesh* pMesh, unsigned int &rFaceIdx, void createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, Q3BSP::sQ3BSPFace *pQ3BSPFace, aiMesh* pMesh, unsigned int &rFaceIdx,
unsigned int &rVertIdx ); unsigned int &rVertIdx );
void createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive ); void createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive );
@ -115,5 +116,4 @@ private:
} // Namespace Assimp } // Namespace Assimp
#endif // ASSIMP_Q3BSPFILEIMPORTER_H_INC #endif // ASSIMP_Q3BSPFILEIMPORTER_H_INC

View File

@ -55,56 +55,51 @@ namespace Assimp {
using namespace Q3BSP; using namespace Q3BSP;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Q3BSPFileParser::Q3BSPFileParser( const std::string &rMapName, Q3BSPZipArchive *pZipArchive ) : Q3BSPFileParser::Q3BSPFileParser( const std::string &mapName, Q3BSPZipArchive *pZipArchive ) :
m_sOffset( 0 ), m_sOffset( 0 ),
m_Data(), m_Data(),
m_pModel( NULL ), m_pModel(nullptr),
m_pZipArchive( pZipArchive ) m_pZipArchive( pZipArchive )
{ {
ai_assert( NULL != m_pZipArchive ); ai_assert(nullptr != m_pZipArchive );
ai_assert( !rMapName.empty() ); ai_assert( !mapName.empty() );
if ( !readData( rMapName ) ) if ( !readData( mapName ) )
return; return;
m_pModel = new Q3BSPModel; m_pModel = new Q3BSPModel;
m_pModel->m_ModelName = rMapName; m_pModel->m_ModelName = mapName;
if ( !parseFile() ) if ( !parseFile() ) {
{
delete m_pModel; delete m_pModel;
m_pModel = NULL; m_pModel = nullptr;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Q3BSPFileParser::~Q3BSPFileParser() Q3BSPFileParser::~Q3BSPFileParser() {
{
delete m_pModel; delete m_pModel;
m_pModel = NULL; m_pModel = nullptr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Q3BSP::Q3BSPModel *Q3BSPFileParser::getModel() const Q3BSP::Q3BSPModel *Q3BSPFileParser::getModel() const {
{
return m_pModel; return m_pModel;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool Q3BSPFileParser::readData( const std::string &rMapName ) bool Q3BSPFileParser::readData( const std::string &rMapName ) {
{
if ( !m_pZipArchive->Exists( rMapName.c_str() ) ) if ( !m_pZipArchive->Exists( rMapName.c_str() ) )
return false; return false;
IOStream *pMapFile = m_pZipArchive->Open( rMapName.c_str() ); IOStream *pMapFile = m_pZipArchive->Open( rMapName.c_str() );
if ( NULL == pMapFile ) if ( nullptr == pMapFile )
return false; return false;
const size_t size = pMapFile->FileSize(); const size_t size = pMapFile->FileSize();
m_Data.resize( size ); m_Data.resize( size );
const size_t readSize = pMapFile->Read( &m_Data[0], sizeof( char ), size ); const size_t readSize = pMapFile->Read( &m_Data[0], sizeof( char ), size );
if ( readSize != size ) if ( readSize != size ) {
{
m_Data.clear(); m_Data.clear();
return false; return false;
} }
@ -114,10 +109,8 @@ bool Q3BSPFileParser::readData( const std::string &rMapName )
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool Q3BSPFileParser::parseFile() bool Q3BSPFileParser::parseFile() {
{ if ( m_Data.empty() ) {
if ( m_Data.empty() )
{
return false; return false;
} }
@ -129,7 +122,7 @@ bool Q3BSPFileParser::parseFile()
// Imports the dictionary of the level // Imports the dictionary of the level
getLumps(); getLumps();
// Conunt data and prepare model data // Count data and prepare model data
countLumps(); countLumps();
// Read in Vertices // Read in Vertices
@ -209,7 +202,7 @@ void Q3BSPFileParser::getVertices()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Q3BSPFileParser::getIndices() void Q3BSPFileParser::getIndices()
{ {
ai_assert( NULL != m_pModel ); ai_assert(nullptr != m_pModel );
sQ3BSPLump *lump = m_pModel->m_Lumps[ kMeshVerts ]; sQ3BSPLump *lump = m_pModel->m_Lumps[ kMeshVerts ];
size_t Offset = (size_t) lump->iOffset; size_t Offset = (size_t) lump->iOffset;
@ -221,7 +214,7 @@ void Q3BSPFileParser::getIndices()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Q3BSPFileParser::getFaces() void Q3BSPFileParser::getFaces()
{ {
ai_assert( NULL != m_pModel ); ai_assert(nullptr != m_pModel );
size_t Offset = m_pModel->m_Lumps[ kFaces ]->iOffset; size_t Offset = m_pModel->m_Lumps[ kFaces ]->iOffset;
for ( size_t idx = 0; idx < m_pModel->m_Faces.size(); idx++ ) for ( size_t idx = 0; idx < m_pModel->m_Faces.size(); idx++ )
@ -236,7 +229,7 @@ void Q3BSPFileParser::getFaces()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Q3BSPFileParser::getTextures() void Q3BSPFileParser::getTextures()
{ {
ai_assert( NULL != m_pModel ); ai_assert(nullptr != m_pModel );
size_t Offset = m_pModel->m_Lumps[ kTextures ]->iOffset; size_t Offset = m_pModel->m_Lumps[ kTextures ]->iOffset;
for ( size_t idx=0; idx < m_pModel->m_Textures.size(); idx++ ) for ( size_t idx=0; idx < m_pModel->m_Textures.size(); idx++ )
@ -251,7 +244,7 @@ void Q3BSPFileParser::getTextures()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Q3BSPFileParser::getLightMaps() void Q3BSPFileParser::getLightMaps()
{ {
ai_assert( NULL != m_pModel ); ai_assert(nullptr != m_pModel );
size_t Offset = m_pModel->m_Lumps[kLightmaps]->iOffset; size_t Offset = m_pModel->m_Lumps[kLightmaps]->iOffset;
for ( size_t idx=0; idx < m_pModel->m_Lightmaps.size(); idx++ ) for ( size_t idx=0; idx < m_pModel->m_Lightmaps.size(); idx++ )
@ -264,12 +257,10 @@ void Q3BSPFileParser::getLightMaps()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Q3BSPFileParser::getEntities() void Q3BSPFileParser::getEntities() {
{ const int size = m_pModel->m_Lumps[ kEntities ]->iSize;
int size = m_pModel->m_Lumps[ kEntities ]->iSize;
m_pModel->m_EntityData.resize( size ); m_pModel->m_EntityData.resize( size );
if ( size > 0 ) if ( size > 0 ) {
{
size_t Offset = m_pModel->m_Lumps[ kEntities ]->iOffset; size_t Offset = m_pModel->m_Lumps[ kEntities ]->iOffset;
memcpy( &m_pModel->m_EntityData[ 0 ], &m_Data[ Offset ], sizeof( char ) * size ); memcpy( &m_pModel->m_EntityData[ 0 ], &m_Data[ Offset ], sizeof( char ) * size );
} }

View File

@ -183,7 +183,7 @@ Q3BSPZipArchive::Q3BSPZipArchive(IOSystem* pIOHandler, const std::string& rFile)
m_ZipFileHandle = unzOpen2(rFile.c_str(), &mapping); m_ZipFileHandle = unzOpen2(rFile.c_str(), &mapping);
if(m_ZipFileHandle != NULL) { if(m_ZipFileHandle != nullptr) {
mapArchive(); mapArchive();
} }
} }
@ -197,26 +197,23 @@ Q3BSPZipArchive::~Q3BSPZipArchive() {
} }
m_ArchiveMap.clear(); m_ArchiveMap.clear();
if(m_ZipFileHandle != NULL) { if(m_ZipFileHandle != nullptr) {
unzClose(m_ZipFileHandle); unzClose(m_ZipFileHandle);
m_ZipFileHandle = NULL; m_ZipFileHandle = nullptr;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if the archive is already open. // Returns true, if the archive is already open.
bool Q3BSPZipArchive::isOpen() const { bool Q3BSPZipArchive::isOpen() const {
return (m_ZipFileHandle != NULL); return (m_ZipFileHandle != nullptr);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if the filename is part of the archive. // Returns true, if the filename is part of the archive.
bool Q3BSPZipArchive::Exists(const char* pFile) const { bool Q3BSPZipArchive::Exists(const char* pFile) const {
ai_assert(pFile != NULL);
bool exist = false; bool exist = false;
if (pFile != nullptr) {
if (pFile != NULL) {
std::string rFile(pFile); std::string rFile(pFile);
std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile); std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile);
@ -241,9 +238,9 @@ char Q3BSPZipArchive::getOsSeparator() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Opens a file, which is part of the archive. // Opens a file, which is part of the archive.
IOStream *Q3BSPZipArchive::Open(const char* pFile, const char* /*pMode*/) { IOStream *Q3BSPZipArchive::Open(const char* pFile, const char* /*pMode*/) {
ai_assert(pFile != NULL); ai_assert(pFile != nullptr);
IOStream* result = NULL; IOStream* result = nullptr;
std::map<std::string, ZipFile*>::iterator it = m_ArchiveMap.find(pFile); std::map<std::string, ZipFile*>::iterator it = m_ArchiveMap.find(pFile);
@ -258,7 +255,7 @@ IOStream *Q3BSPZipArchive::Open(const char* pFile, const char* /*pMode*/) {
// Close a filestream. // Close a filestream.
void Q3BSPZipArchive::Close(IOStream *pFile) { void Q3BSPZipArchive::Close(IOStream *pFile) {
(void)(pFile); (void)(pFile);
ai_assert(pFile != NULL); ai_assert(pFile != nullptr);
// We don't do anything in case the file would be opened again in the future // We don't do anything in case the file would be opened again in the future
} }
@ -277,7 +274,7 @@ void Q3BSPZipArchive::getFileList(std::vector<std::string> &rFileList) {
bool Q3BSPZipArchive::mapArchive() { bool Q3BSPZipArchive::mapArchive() {
bool success = false; bool success = false;
if(m_ZipFileHandle != NULL) { if(m_ZipFileHandle != nullptr) {
if(m_ArchiveMap.empty()) { if(m_ArchiveMap.empty()) {
// At first ensure file is already open // At first ensure file is already open
if(unzGoToFirstFile(m_ZipFileHandle) == UNZ_OK) { if(unzGoToFirstFile(m_ZipFileHandle) == UNZ_OK) {

View File

@ -1,141 +0,0 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2017, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** Small helper classes to optimize finding vertices close to a given location
*/
#ifndef AI_D3DSSPATIALSORT_H_INC
#define AI_D3DSSPATIALSORT_H_INC
#include <assimp/types.h>
#include <vector>
#include <stdint.h>
namespace Assimp {
// ----------------------------------------------------------------------------------
/** Specialized version of SpatialSort to support smoothing groups
* This is used in by the 3DS, ASE and LWO loaders. 3DS and ASE share their
* normal computation code in SmoothingGroups.inl, the LWO loader has its own
* implementation to handle all details of its file format correctly.
*/
// ----------------------------------------------------------------------------------
class ASSIMP_API SGSpatialSort
{
public:
SGSpatialSort();
// -------------------------------------------------------------------
/** Construction from a given face array, handling smoothing groups
* properly
*/
explicit SGSpatialSort(const std::vector<aiVector3D>& vPositions);
// -------------------------------------------------------------------
/** Add a vertex to the spatial sort
* @param vPosition Vertex position to be added
* @param index Index of the vrtex
* @param smoothingGroup SmoothingGroup for this vertex
*/
void Add(const aiVector3D& vPosition, unsigned int index,
unsigned int smoothingGroup);
// -------------------------------------------------------------------
/** Prepare the spatial sorter for use. This step runs in O(logn)
*/
void Prepare();
/** Destructor */
~SGSpatialSort();
// -------------------------------------------------------------------
/** Returns an iterator for all positions close to the given position.
* @param pPosition The position to look for vertices.
* @param pSG Only included vertices with at least one shared smooth group
* @param pRadius Maximal distance from the position a vertex may have
* to be counted in.
* @param poResults The container to store the indices of the found
* positions. Will be emptied by the call so it may contain anything.
* @param exactMatch Specifies whether smoothing groups are bit masks
* (false) or integral values (true). In the latter case, a vertex
* cannot belong to more than one smoothing group.
* @return An iterator to iterate over all vertices in the given area.
*/
// -------------------------------------------------------------------
void FindPositions( const aiVector3D& pPosition, uint32_t pSG,
float pRadius, std::vector<unsigned int>& poResults,
bool exactMatch = false) const;
protected:
/** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */
aiVector3D mPlaneNormal;
// -------------------------------------------------------------------
/** An entry in a spatially sorted position array. Consists of a
* vertex index, its position and its precalculated distance from
* the reference plane */
// -------------------------------------------------------------------
struct Entry
{
unsigned int mIndex; ///< The vertex referred by this entry
aiVector3D mPosition; ///< Position
uint32_t mSmoothGroups;
float mDistance; ///< Distance of this vertex to the sorting plane
Entry() { /** intentionally not initialized.*/ }
Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance,uint32_t pSG)
:
mIndex( pIndex),
mPosition( pPosition),
mSmoothGroups (pSG),
mDistance( pDistance)
{ }
bool operator < (const Entry& e) const { return mDistance < e.mDistance; }
};
// all positions, sorted by distance to the sorting plane
std::vector<Entry> mPositions;
};
} // end of namespace Assimp
#endif // AI_SPATIALSORT_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -62,17 +62,17 @@ struct aiNode;
// STL headers // STL headers
#include <vector> #include <vector>
namespace Assimp { namespace Assimp {
namespace SMD {
namespace SMD {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Data structure for a vertex in a SMD file /** Data structure for a vertex in a SMD file
*/ */
struct Vertex struct Vertex {
{ Vertex() AI_NO_EXCEPT
Vertex() : iParentNode(UINT_MAX) : iParentNode(UINT_MAX) {
{} // empty
}
//! Vertex position, normal and texture coordinate //! Vertex position, normal and texture coordinate
aiVector3D pos,nor,uv; aiVector3D pos,nor,uv;
@ -90,10 +90,12 @@ struct Vertex
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Data structure for a face in a SMD file /** Data structure for a face in a SMD file
*/ */
struct Face struct Face {
{ Face() AI_NO_EXCEPT
Face() : iTexture(0x0) : iTexture(0x0)
{} , avVertices{} {
// empty
}
//! Texture index for the face //! Texture index for the face
unsigned int iTexture; unsigned int iTexture;
@ -105,11 +107,12 @@ struct Face
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Data structure for a bone in a SMD file /** Data structure for a bone in a SMD file
*/ */
struct Bone struct Bone {
{
//! Default constructor //! Default constructor
Bone() : iParent(UINT_MAX), bIsUsed(false) Bone() AI_NO_EXCEPT
{ : iParent(UINT_MAX)
, bIsUsed(false) {
// empty
} }
//! Destructor //! Destructor
@ -124,12 +127,10 @@ struct Bone
uint32_t iParent; uint32_t iParent;
//! Animation of the bone //! Animation of the bone
struct Animation struct Animation {
{
//! Public default constructor //! Public default constructor
Animation() Animation() AI_NO_EXCEPT
: iFirstTimeKey() : iFirstTimeKey() {
{
asKeys.reserve(20); asKeys.reserve(20);
} }
@ -218,6 +219,7 @@ protected:
/** Parse the SMD file and create the output scene /** Parse the SMD file and create the output scene
*/ */
void ParseFile(); void ParseFile();
void ReadSmd(const std::string &pFile, IOSystem* pIOHandler);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse the triangles section of the SMD file /** Parse the triangles section of the SMD file
@ -288,13 +290,6 @@ protected:
*/ */
unsigned int GetTextureIndex(const std::string& filename); unsigned int GetTextureIndex(const std::string& filename);
// -------------------------------------------------------------------
/** Computes absolute bone transformations
* All output transformations are in worldspace.
*/
void ComputeAbsoluteBoneTransformations();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a line in the skeleton section /** Parse a line in the skeleton section
*/ */
@ -343,7 +338,9 @@ protected:
*/ */
void CreateOutputMeshes(); void CreateOutputMeshes();
void CreateOutputNodes(); void CreateOutputNodes();
void CreateOutputAnimations(); void CreateOutputAnimations(const std::string &pFile, IOSystem* pIOHandler);
void CreateOutputAnimation(int index, const std::string &name);
void GetAnimationFileList(const std::string &pFile, IOSystem* pIOHandler, std::vector<std::tuple<std::string, std::string>>& outList);
void CreateOutputMaterials(); void CreateOutputMaterials();
@ -412,6 +409,8 @@ private:
*/ */
unsigned int iLineNumber; unsigned int iLineNumber;
bool bLoadAnimationList = true;
bool noSkeletonMesh = false;
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -139,10 +139,10 @@ namespace STEP {
* error (i.e. an entity expects a string but receives a bool) occurs. * error (i.e. an entity expects a string but receives a bool) occurs.
* It is typically coupled with both an entity id and a line number.*/ * It is typically coupled with both an entity id and a line number.*/
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
struct TypeError : DeadlyImportError struct TypeError : DeadlyImportError {
{
enum { enum {
ENTITY_NOT_SPECIFIED = 0xffffffffffffffffLL ENTITY_NOT_SPECIFIED = 0xffffffffffffffffLL,
ENTITY_NOT_SPECIFIED_32 = 0x00000000ffffffff
}; };
TypeError (const std::string& s,uint64_t entity = ENTITY_NOT_SPECIFIED, uint64_t line = SyntaxError::LINE_NOT_SPECIFIED); TypeError (const std::string& s,uint64_t entity = ENTITY_NOT_SPECIFIED, uint64_t line = SyntaxError::LINE_NOT_SPECIFIED);
@ -164,7 +164,6 @@ namespace STEP {
class DataType class DataType
{ {
public: public:
typedef std::shared_ptr<const DataType> Out; typedef std::shared_ptr<const DataType> Out;
public: public:
@ -357,14 +356,25 @@ namespace STEP {
MemberList members; MemberList members;
}; };
class BINARY : public PrimitiveDataType<uint32_t> {
public:
BINARY(uint32_t val)
: PrimitiveDataType<uint32_t>(val) {
// empty
}
BINARY()
: PrimitiveDataType<uint32_t>(TypeError::ENTITY_NOT_SPECIFIED_32) {
// empty
}
};
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
/* Not exactly a full EXPRESS schema but rather a list of conversion functions /* Not exactly a full EXPRESS schema but rather a list of conversion functions
* to extract valid C++ objects out of a STEP file. Those conversion functions * to extract valid C++ objects out of a STEP file. Those conversion functions
* may, however, perform further schema validations. */ * may, however, perform further schema validations. */
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
class ConversionSchema class ConversionSchema {
{
public: public:
struct SchemaEntry { struct SchemaEntry {
SchemaEntry( const char *name, ConvertObjectProc func ) SchemaEntry( const char *name, ConvertObjectProc func )
@ -379,30 +389,27 @@ namespace STEP {
typedef std::map<std::string,ConvertObjectProc> ConverterMap; typedef std::map<std::string,ConvertObjectProc> ConverterMap;
public:
template <size_t N> template <size_t N>
explicit ConversionSchema( const SchemaEntry (& schemas)[N]) { explicit ConversionSchema( const SchemaEntry (& schemas)[N]) {
*this = schemas; *this = schemas;
} }
ConversionSchema() {} ConversionSchema() {
public: }
ConvertObjectProc GetConverterProc(const std::string& name) const { ConvertObjectProc GetConverterProc(const std::string& name) const {
ConverterMap::const_iterator it = converters.find(name); ConverterMap::const_iterator it = converters.find(name);
return it == converters.end() ? NULL : (*it).second; return it == converters.end() ? nullptr : (*it).second;
} }
bool IsKnownToken(const std::string& name) const { bool IsKnownToken(const std::string& name) const {
return converters.find(name) != converters.end(); return converters.find(name) != converters.end();
} }
const char* GetStaticStringForToken(const std::string& token) const { const char* GetStaticStringForToken(const std::string& token) const {
ConverterMap::const_iterator it = converters.find(token); ConverterMap::const_iterator it = converters.find(token);
return it == converters.end() ? NULL : (*it).first.c_str(); return it == converters.end() ? nullptr : (*it).first.c_str();
} }
@ -416,7 +423,6 @@ namespace STEP {
} }
private: private:
ConverterMap converters; ConverterMap converters;
}; };
} }
@ -451,8 +457,6 @@ namespace STEP {
// empty // empty
} }
public:
// utilities to simplify casting to concrete types // utilities to simplify casting to concrete types
template <typename T> template <typename T>
const T& To() const { const T& To() const {
@ -474,7 +478,6 @@ namespace STEP {
return dynamic_cast<T*>(this); return dynamic_cast<T*>(this);
} }
public:
uint64_t GetID() const { uint64_t GetID() const {
return id; return id;
} }
@ -501,9 +504,11 @@ namespace STEP {
/** CRTP shared base class for use by concrete entity implementation classes */ /** CRTP shared base class for use by concrete entity implementation classes */
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
template <typename TDerived, size_t arg_count> template <typename TDerived, size_t arg_count>
struct ObjectHelper : virtual Object struct ObjectHelper : virtual Object {
{ ObjectHelper()
ObjectHelper() : aux_is_derived(0) {} : aux_is_derived(0) {
// empty
}
static Object* Construct(const STEP::DB& db, const EXPRESS::LIST& params) { static Object* Construct(const STEP::DB& db, const EXPRESS::LIST& params) {
// make sure we don't leak if Fill() throws an exception // make sure we don't leak if Fill() throws an exception
@ -532,10 +537,16 @@ namespace STEP {
/** Class template used to represent OPTIONAL data members in the converted schema */ /** Class template used to represent OPTIONAL data members in the converted schema */
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
template <typename T> template <typename T>
struct Maybe struct Maybe {
{ Maybe()
Maybe() : have() {} : have() {
explicit Maybe(const T& ptr) : ptr(ptr), have(true) { // empty
}
explicit Maybe(const T& ptr)
: ptr(ptr)
, have(true) {
// empty
} }
@ -572,7 +583,6 @@ namespace STEP {
} }
private: private:
template <typename T2> friend struct InternGenericConvert; template <typename T2> friend struct InternGenericConvert;
operator T&() { operator T&() {
@ -587,16 +597,13 @@ namespace STEP {
/** A LazyObject is created when needed. Before this happens, we just keep /** A LazyObject is created when needed. Before this happens, we just keep
the text line that contains the object definition. */ the text line that contains the object definition. */
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
class LazyObject class LazyObject {
{
friend class DB; friend class DB;
public:
public:
LazyObject(DB& db, uint64_t id, uint64_t line, const char* type,const char* args); LazyObject(DB& db, uint64_t id, uint64_t line, const char* type,const char* args);
~LazyObject(); ~LazyObject();
public:
Object& operator * () { Object& operator * () {
if (!obj) { if (!obj) {
LazyInit(); LazyInit();
@ -654,38 +661,37 @@ namespace STEP {
} }
private: private:
void LazyInit() const; void LazyInit() const;
private: private:
mutable uint64_t id; mutable uint64_t id;
const char* const type; const char* const type;
DB& db; DB& db;
mutable const char* args; mutable const char* args;
mutable Object* obj; mutable Object* obj;
}; };
template <typename T> template <typename T>
inline bool operator==( std::shared_ptr<LazyObject> lo, T whatever ) { inline
bool operator==( std::shared_ptr<LazyObject> lo, T whatever ) {
return *lo == whatever; // XXX use std::forward if we have 0x return *lo == whatever; // XXX use std::forward if we have 0x
} }
template <typename T> template <typename T>
inline bool operator==( const std::pair<uint64_t, std::shared_ptr<LazyObject> >& lo, T whatever ) { inline
bool operator==( const std::pair<uint64_t, std::shared_ptr<LazyObject> >& lo, T whatever ) {
return *(lo.second) == whatever; // XXX use std::forward if we have 0x return *(lo.second) == whatever; // XXX use std::forward if we have 0x
} }
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
/** Class template used to represent lazily evaluated object references in the converted schema */ /** Class template used to represent lazily evaluated object references in the converted schema */
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
template <typename T> template <typename T>
struct Lazy struct Lazy {
{
typedef Lazy Out; typedef Lazy Out;
Lazy(const LazyObject* obj = NULL) : obj(obj) { Lazy(const LazyObject* obj = nullptr)
: obj(obj) {
// empty
} }
operator const T*() const { operator const T*() const {
@ -711,19 +717,15 @@ namespace STEP {
/** Class template used to represent LIST and SET data members in the converted schema */ /** Class template used to represent LIST and SET data members in the converted schema */
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
template <typename T, uint64_t min_cnt, uint64_t max_cnt=0uL> template <typename T, uint64_t min_cnt, uint64_t max_cnt=0uL>
struct ListOf : public std::vector<typename T::Out> struct ListOf : public std::vector<typename T::Out> {
{
typedef typename T::Out OutScalar; typedef typename T::Out OutScalar;
typedef ListOf Out; typedef ListOf Out;
ListOf() { ListOf() {
static_assert(min_cnt <= max_cnt || !max_cnt, "min_cnt <= max_cnt || !max_cnt"); static_assert(min_cnt <= max_cnt || !max_cnt, "min_cnt <= max_cnt || !max_cnt");
} }
}; };
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
template <typename TOut> template <typename TOut>
struct PickBaseType { struct PickBaseType {
@ -735,7 +737,8 @@ namespace STEP {
typedef EXPRESS::ENTITY Type; typedef EXPRESS::ENTITY Type;
}; };
template <> struct PickBaseType< std::shared_ptr< const EXPRESS::DataType > >; template<>
struct PickBaseType< std::shared_ptr< const EXPRESS::DataType > >;
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
template <typename T> template <typename T>
@ -743,8 +746,7 @@ namespace STEP {
void operator()(T& out, const std::shared_ptr< const EXPRESS::DataType >& in, const STEP::DB& /*db*/) { void operator()(T& out, const std::shared_ptr< const EXPRESS::DataType >& in, const STEP::DB& /*db*/) {
try{ try{
out = dynamic_cast< const typename PickBaseType<T>::Type& > ( *in ); out = dynamic_cast< const typename PickBaseType<T>::Type& > ( *in );
} } catch(std::bad_cast&) {
catch(std::bad_cast&) {
throw TypeError("type error reading literal field"); throw TypeError("type error reading literal field");
} }
} }
@ -817,7 +819,6 @@ namespace STEP {
return InternGenericConvertList<T1,N1,N2>()(a,b,db); return InternGenericConvertList<T1,N1,N2>()(a,b,db);
} }
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
/** Lightweight manager class that holds the map of all objects in a /** Lightweight manager class that holds the map of all objects in a
* STEP file. DB's are exclusively maintained by the functions in * STEP file. DB's are exclusively maintained by the functions in
@ -834,7 +835,6 @@ namespace STEP {
friend class LazyObject; friend class LazyObject;
public: public:
// objects indexed by ID - this can grow pretty large (i.e some hundred million // objects indexed by ID - this can grow pretty large (i.e some hundred million
// entries), so use raw pointers to avoid *any* overhead. // entries), so use raw pointers to avoid *any* overhead.
typedef std::map<uint64_t,const LazyObject* > ObjectMap; typedef std::map<uint64_t,const LazyObject* > ObjectMap;
@ -859,19 +859,16 @@ namespace STEP {
: reader(reader) : reader(reader)
, splitter(*reader,true,true) , splitter(*reader,true,true)
, evaluated_count() , evaluated_count()
, schema( NULL ) , schema( nullptr )
{} {}
public: public:
~DB() { ~DB() {
for(ObjectMap::value_type& o : objects) { for(ObjectMap::value_type& o : objects) {
delete o.second; delete o.second;
} }
} }
public:
uint64_t GetObjectCount() const { uint64_t GetObjectCount() const {
return objects.size(); return objects.size();
} }
@ -900,7 +897,6 @@ namespace STEP {
return refs; return refs;
} }
bool KeepInverseIndicesForType(const char* const type) const { bool KeepInverseIndicesForType(const char* const type) const {
return inv_whitelist.find(type) != inv_whitelist.end(); return inv_whitelist.find(type) != inv_whitelist.end();
} }
@ -912,7 +908,7 @@ namespace STEP {
if (it != objects.end()) { if (it != objects.end()) {
return (*it).second; return (*it).second;
} }
return NULL; return nullptr;
} }

View File

@ -214,11 +214,10 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// create a single default material, using a white diffuse color for consistency with // create a single default material, using a white diffuse color for consistency with
// other geometric types (e.g., PLY). // other geometric types (e.g., PLY).
aiMaterial* pcMat = aiCreateAndRegisterDefaultMaterial(); aiMaterial* pcMat = new aiMaterial();
/*aiMaterial* pcMat = new aiMaterial();
aiString s; aiString s;
s.Set(AI_DEFAULT_MATERIAL_NAME); s.Set(AI_DEFAULT_MATERIAL_NAME);
pcMat->AddProperty(&s, AI_MATKEY_NAME);*/ pcMat->AddProperty(&s, AI_MATKEY_NAME);
aiColor4D clrDiffuse(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0)); aiColor4D clrDiffuse(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0));
if (bMatClr) { if (bMatClr) {

View File

@ -56,7 +56,7 @@ class Importer;
struct ScenePrivateData { struct ScenePrivateData {
// The struct constructor. // The struct constructor.
ScenePrivateData(); ScenePrivateData() AI_NO_EXCEPT;
// Importer that originally loaded the scene though the C-API // Importer that originally loaded the scene though the C-API
// If set, this object is owned by this private data instance. // If set, this object is owned by this private data instance.
@ -74,7 +74,7 @@ struct ScenePrivateData {
}; };
inline inline
ScenePrivateData::ScenePrivateData() ScenePrivateData::ScenePrivateData() AI_NO_EXCEPT
: mOrigImporter( nullptr ) : mOrigImporter( nullptr )
, mPPStepsApplied( 0 ) , mPPStepsApplied( 0 )
, mIsCopy( false ) { , mIsCopy( false ) {

View File

@ -393,7 +393,7 @@ void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end()); newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
} }
delete pNode->mMeshes; delete [] pNode->mMeshes;
pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size()); pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size());
pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes); std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);

View File

@ -40,11 +40,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/**
/** @file Implementation of the SplitLargeMeshes postprocessing step * @file Implementation of the SplitLargeMeshes postprocessing step
*/ */
// internal headers of the post-processing framework // internal headers of the post-processing framework
#include "SplitLargeMeshes.h" #include "SplitLargeMeshes.h"
@ -52,61 +50,57 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle() SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle() {
{
LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES; LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SplitLargeMeshesProcess_Triangle::~SplitLargeMeshesProcess_Triangle() SplitLargeMeshesProcess_Triangle::~SplitLargeMeshesProcess_Triangle() {
{
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const {
{
return (pFlags & aiProcess_SplitLargeMeshes) != 0; return (pFlags & aiProcess_SplitLargeMeshes) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene) void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene) {
{ if (0xffffffff == this->LIMIT || nullptr == pScene ) {
if (0xffffffff == this->LIMIT)return; return;
}
ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle begin"); ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle begin");
std::vector<std::pair<aiMesh*, unsigned int> > avList; std::vector<std::pair<aiMesh*, unsigned int> > avList;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
this->SplitMesh(a, pScene->mMeshes[a],avList); this->SplitMesh(a, pScene->mMeshes[a],avList);
}
if (avList.size() != pScene->mNumMeshes) if (avList.size() != pScene->mNumMeshes) {
{
// it seems something has been split. rebuild the mesh list // it seems something has been split. rebuild the mesh list
delete[] pScene->mMeshes; delete[] pScene->mMeshes;
pScene->mNumMeshes = (unsigned int)avList.size(); pScene->mNumMeshes = (unsigned int)avList.size();
pScene->mMeshes = new aiMesh*[avList.size()]; pScene->mMeshes = new aiMesh*[avList.size()];
for (unsigned int i = 0; i < avList.size();++i) for (unsigned int i = 0; i < avList.size();++i) {
pScene->mMeshes[i] = avList[i].first; pScene->mMeshes[i] = avList[i].first;
}
// now we need to update all nodes // now we need to update all nodes
this->UpdateNode(pScene->mRootNode,avList); this->UpdateNode(pScene->mRootNode,avList);
ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Triangle finished. Meshes have been split"); ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
} } else {
else {
ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do"); ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup properties // Setup properties
void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp) void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp) {
{
// get the current value of the split property // get the current value of the split property
this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES); this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
} }
@ -114,17 +108,13 @@ void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Update a node after some meshes have been split // Update a node after some meshes have been split
void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode, void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode,
const std::vector<std::pair<aiMesh*, unsigned int> >& avList) const std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
{
// for every index in out list build a new entry // for every index in out list build a new entry
std::vector<unsigned int> aiEntries; std::vector<unsigned int> aiEntries;
aiEntries.reserve(pcNode->mNumMeshes + 1); aiEntries.reserve(pcNode->mNumMeshes + 1);
for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) {
{ for (unsigned int a = 0; a < avList.size();++a) {
for (unsigned int a = 0; a < avList.size();++a) if (avList[a].second == pcNode->mMeshes[i]) {
{
if (avList[a].second == pcNode->mMeshes[i])
{
aiEntries.push_back(a); aiEntries.push_back(a);
} }
} }
@ -135,26 +125,23 @@ void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode,
pcNode->mNumMeshes = (unsigned int)aiEntries.size(); pcNode->mNumMeshes = (unsigned int)aiEntries.size();
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes]; pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
for (unsigned int b = 0; b < pcNode->mNumMeshes;++b) for (unsigned int b = 0; b < pcNode->mNumMeshes;++b) {
pcNode->mMeshes[b] = aiEntries[b]; pcNode->mMeshes[b] = aiEntries[b];
}
// recusively update all other nodes // recusively update all other nodes
for (unsigned int i = 0; i < pcNode->mNumChildren;++i) for (unsigned int i = 0; i < pcNode->mNumChildren;++i) {
{
UpdateNode ( pcNode->mChildren[i], avList ); UpdateNode ( pcNode->mChildren[i], avList );
} }
return;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void SplitLargeMeshesProcess_Triangle::SplitMesh( void SplitLargeMeshesProcess_Triangle::SplitMesh(
unsigned int a, unsigned int a,
aiMesh* pMesh, aiMesh* pMesh,
std::vector<std::pair<aiMesh*, unsigned int> >& avList) std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
{ if (pMesh->mNumFaces > SplitLargeMeshesProcess_Triangle::LIMIT) {
if (pMesh->mNumFaces > SplitLargeMeshesProcess_Triangle::LIMIT)
{
ASSIMP_LOG_INFO("Mesh exceeds the triangle limit. It will be split ..."); ASSIMP_LOG_INFO("Mesh exceeds the triangle limit. It will be split ...");
// we need to split this mesh into sub meshes // we need to split this mesh into sub meshes
@ -165,8 +152,7 @@ void SplitLargeMeshesProcess_Triangle::SplitMesh(
const unsigned int iOutVertexNum = iOutFaceNum * 3; const unsigned int iOutVertexNum = iOutFaceNum * 3;
// now generate all submeshes // now generate all submeshes
for (unsigned int i = 0; i < iSubMeshes;++i) for (unsigned int i = 0; i < iSubMeshes;++i) {
{
aiMesh* pcMesh = new aiMesh; aiMesh* pcMesh = new aiMesh;
pcMesh->mNumFaces = iOutFaceNum; pcMesh->mNumFaces = iOutFaceNum;
pcMesh->mMaterialIndex = pMesh->mMaterialIndex; pcMesh->mMaterialIndex = pMesh->mMaterialIndex;
@ -174,8 +160,7 @@ void SplitLargeMeshesProcess_Triangle::SplitMesh(
// the name carries the adjacency information between the meshes // the name carries the adjacency information between the meshes
pcMesh->mName = pMesh->mName; pcMesh->mName = pMesh->mName;
if (i == iSubMeshes-1) if (i == iSubMeshes-1) {
{
pcMesh->mNumFaces = iOutFaceNum + ( pcMesh->mNumFaces = iOutFaceNum + (
pMesh->mNumFaces - iOutFaceNum * iSubMeshes); pMesh->mNumFaces - iOutFaceNum * iSubMeshes);
} }
@ -186,71 +171,62 @@ void SplitLargeMeshesProcess_Triangle::SplitMesh(
// get the total number of indices // get the total number of indices
unsigned int iCnt = 0; unsigned int iCnt = 0;
for (unsigned int p = iBase; p < pcMesh->mNumFaces + iBase;++p) for (unsigned int p = iBase; p < pcMesh->mNumFaces + iBase;++p) {
{
iCnt += pMesh->mFaces[p].mNumIndices; iCnt += pMesh->mFaces[p].mNumIndices;
} }
pcMesh->mNumVertices = iCnt; pcMesh->mNumVertices = iCnt;
// allocate storage // allocate storage
if (pMesh->mVertices != NULL) if (pMesh->mVertices != nullptr) {
pcMesh->mVertices = new aiVector3D[iCnt]; pcMesh->mVertices = new aiVector3D[iCnt];
}
if (pMesh->HasNormals()) if (pMesh->HasNormals()) {
pcMesh->mNormals = new aiVector3D[iCnt]; pcMesh->mNormals = new aiVector3D[iCnt];
}
if (pMesh->HasTangentsAndBitangents()) if (pMesh->HasTangentsAndBitangents()) {
{
pcMesh->mTangents = new aiVector3D[iCnt]; pcMesh->mTangents = new aiVector3D[iCnt];
pcMesh->mBitangents = new aiVector3D[iCnt]; pcMesh->mBitangents = new aiVector3D[iCnt];
} }
// texture coordinates // texture coordinates
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
{
pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c]; pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
if (pMesh->HasTextureCoords( c)) if (pMesh->HasTextureCoords( c)) {
{
pcMesh->mTextureCoords[c] = new aiVector3D[iCnt]; pcMesh->mTextureCoords[c] = new aiVector3D[iCnt];
} }
} }
// vertex colors // vertex colors
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
{ if (pMesh->HasVertexColors( c)) {
if (pMesh->HasVertexColors( c))
{
pcMesh->mColors[c] = new aiColor4D[iCnt]; pcMesh->mColors[c] = new aiColor4D[iCnt];
} }
} }
if (pMesh->HasBones()) if (pMesh->HasBones()) {
{
// assume the number of bones won't change in most cases // assume the number of bones won't change in most cases
pcMesh->mBones = new aiBone*[pMesh->mNumBones]; pcMesh->mBones = new aiBone*[pMesh->mNumBones];
// iterate through all bones of the mesh and find those which // iterate through all bones of the mesh and find those which
// need to be copied to the split mesh // need to be copied to the split mesh
std::vector<aiVertexWeight> avTempWeights; std::vector<aiVertexWeight> avTempWeights;
for (unsigned int p = 0; p < pcMesh->mNumBones;++p) for (unsigned int p = 0; p < pcMesh->mNumBones;++p) {
{
aiBone* const bone = pcMesh->mBones[p]; aiBone* const bone = pcMesh->mBones[p];
avTempWeights.clear(); avTempWeights.clear();
avTempWeights.reserve(bone->mNumWeights / iSubMeshes); avTempWeights.reserve(bone->mNumWeights / iSubMeshes);
for (unsigned int q = 0; q < bone->mNumWeights;++q) for (unsigned int q = 0; q < bone->mNumWeights;++q) {
{
aiVertexWeight& weight = bone->mWeights[q]; aiVertexWeight& weight = bone->mWeights[q];
if(weight.mVertexId >= iBase && weight.mVertexId < iBase + iOutVertexNum) if(weight.mVertexId >= iBase && weight.mVertexId < iBase + iOutVertexNum) {
{
avTempWeights.push_back(weight); avTempWeights.push_back(weight);
weight = avTempWeights.back(); weight = avTempWeights.back();
weight.mVertexId -= iBase; weight.mVertexId -= iBase;
} }
} }
if (!avTempWeights.empty()) if (!avTempWeights.empty()) {
{
// we'll need this bone. Copy it ... // we'll need this bone. Copy it ...
aiBone* pc = new aiBone(); aiBone* pc = new aiBone();
pcMesh->mBones[pcMesh->mNumBones++] = pc; pcMesh->mBones[pcMesh->mNumBones++] = pc;
@ -261,12 +237,12 @@ void SplitLargeMeshesProcess_Triangle::SplitMesh(
// no need to reallocate the array for the last submesh. // no need to reallocate the array for the last submesh.
// Here we can reuse the (large) source array, although // Here we can reuse the (large) source array, although
// we'll waste some memory // we'll waste some memory
if (iSubMeshes-1 == i) if (iSubMeshes-1 == i) {
{
pc->mWeights = bone->mWeights; pc->mWeights = bone->mWeights;
bone->mWeights = NULL; bone->mWeights = nullptr;
} else {
pc->mWeights = new aiVertexWeight[pc->mNumWeights];
} }
else pc->mWeights = new aiVertexWeight[pc->mNumWeights];
// copy the weights // copy the weights
::memcpy(pc->mWeights,&avTempWeights[0],sizeof(aiVertexWeight)*pc->mNumWeights); ::memcpy(pc->mWeights,&avTempWeights[0],sizeof(aiVertexWeight)*pc->mNumWeights);
@ -276,8 +252,7 @@ void SplitLargeMeshesProcess_Triangle::SplitMesh(
// (we will also need to copy the array of indices) // (we will also need to copy the array of indices)
unsigned int iCurrent = 0; unsigned int iCurrent = 0;
for (unsigned int p = 0; p < pcMesh->mNumFaces;++p) for (unsigned int p = 0; p < pcMesh->mNumFaces;++p) {
{
pcMesh->mFaces[p].mNumIndices = 3; pcMesh->mFaces[p].mNumIndices = 3;
// allocate a new array // allocate a new array
const unsigned int iTemp = p + iBase; const unsigned int iTemp = p + iBase;
@ -289,8 +264,7 @@ void SplitLargeMeshesProcess_Triangle::SplitMesh(
unsigned int* piOut = pcMesh->mFaces[p].mIndices = new unsigned int[iNumIndices]; unsigned int* piOut = pcMesh->mFaces[p].mIndices = new unsigned int[iNumIndices];
// need to update the output primitive types // need to update the output primitive types
switch (iNumIndices) switch (iNumIndices) {
{
case 1: case 1:
pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
break; break;
@ -305,38 +279,38 @@ void SplitLargeMeshesProcess_Triangle::SplitMesh(
} }
// and copy the contents of the old array, offset by current base // and copy the contents of the old array, offset by current base
for (unsigned int v = 0; v < iNumIndices;++v) for (unsigned int v = 0; v < iNumIndices;++v) {
{
unsigned int iIndex = pi[v]; unsigned int iIndex = pi[v];
unsigned int iIndexOut = iCurrent++; unsigned int iIndexOut = iCurrent++;
piOut[v] = iIndexOut; piOut[v] = iIndexOut;
// copy positions // copy positions
if (pMesh->mVertices != NULL) if (pMesh->mVertices != nullptr) {
pcMesh->mVertices[iIndexOut] = pMesh->mVertices[iIndex]; pcMesh->mVertices[iIndexOut] = pMesh->mVertices[iIndex];
}
// copy normals // copy normals
if (pMesh->HasNormals()) if (pMesh->HasNormals()) {
pcMesh->mNormals[iIndexOut] = pMesh->mNormals[iIndex]; pcMesh->mNormals[iIndexOut] = pMesh->mNormals[iIndex];
}
// copy tangents/bitangents // copy tangents/bitangents
if (pMesh->HasTangentsAndBitangents()) if (pMesh->HasTangentsAndBitangents()) {
{
pcMesh->mTangents[iIndexOut] = pMesh->mTangents[iIndex]; pcMesh->mTangents[iIndexOut] = pMesh->mTangents[iIndex];
pcMesh->mBitangents[iIndexOut] = pMesh->mBitangents[iIndex]; pcMesh->mBitangents[iIndexOut] = pMesh->mBitangents[iIndex];
} }
// texture coordinates // texture coordinates
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
{ if (pMesh->HasTextureCoords( c ) ) {
if (pMesh->HasTextureCoords( c))
pcMesh->mTextureCoords[c][iIndexOut] = pMesh->mTextureCoords[c][iIndex]; pcMesh->mTextureCoords[c][iIndexOut] = pMesh->mTextureCoords[c][iIndex];
}
} }
// vertex colors // vertex colors
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
{ if (pMesh->HasVertexColors( c)) {
if (pMesh->HasVertexColors( c))
pcMesh->mColors[c][iIndexOut] = pMesh->mColors[c][iIndex]; pcMesh->mColors[c][iIndexOut] = pMesh->mColors[c][iIndex];
}
} }
} }
} }
@ -347,51 +321,59 @@ void SplitLargeMeshesProcess_Triangle::SplitMesh(
// now delete the old mesh data // now delete the old mesh data
delete pMesh; delete pMesh;
} else {
avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
} }
else avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
return;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex() SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex() {
{
LIMIT = AI_SLM_DEFAULT_MAX_VERTICES; LIMIT = AI_SLM_DEFAULT_MAX_VERTICES;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
SplitLargeMeshesProcess_Vertex::~SplitLargeMeshesProcess_Vertex() SplitLargeMeshesProcess_Vertex::~SplitLargeMeshesProcess_Vertex() {
{
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const {
{
return (pFlags & aiProcess_SplitLargeMeshes) != 0; return (pFlags & aiProcess_SplitLargeMeshes) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene) void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene) {
{ if (0xffffffff == this->LIMIT || nullptr == pScene ) {
std::vector<std::pair<aiMesh*, unsigned int> > avList; return;
}
if (0xffffffff == this->LIMIT)return;
ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Vertex begin"); ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Vertex begin");
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
this->SplitMesh(a, pScene->mMeshes[a],avList);
if (avList.size() != pScene->mNumMeshes) std::vector<std::pair<aiMesh*, unsigned int> > avList;
{
//Check for point cloud first,
//Do not process point cloud, splitMesh works only with faces data
for (unsigned int a = 0; a < pScene->mNumMeshes; a++) {
if ( pScene->mMeshes[a]->mPrimitiveTypes == aiPrimitiveType_POINT ) {
return;
}
}
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a ) {
this->SplitMesh(a, pScene->mMeshes[a], avList);
}
if (avList.size() != pScene->mNumMeshes) {
// it seems something has been split. rebuild the mesh list // it seems something has been split. rebuild the mesh list
delete[] pScene->mMeshes; delete[] pScene->mMeshes;
pScene->mNumMeshes = (unsigned int)avList.size(); pScene->mNumMeshes = (unsigned int)avList.size();
pScene->mMeshes = new aiMesh*[avList.size()]; pScene->mMeshes = new aiMesh*[avList.size()];
for (unsigned int i = 0; i < avList.size();++i) for (unsigned int i = 0; i < avList.size();++i) {
pScene->mMeshes[i] = avList[i].first; pScene->mMeshes[i] = avList[i].first;
}
// now we need to update all nodes // now we need to update all nodes
SplitLargeMeshesProcess_Triangle::UpdateNode(pScene->mRootNode,avList); SplitLargeMeshesProcess_Triangle::UpdateNode(pScene->mRootNode,avList);
@ -403,20 +385,17 @@ void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup properties // Setup properties
void SplitLargeMeshesProcess_Vertex::SetupProperties( const Importer* pImp) void SplitLargeMeshesProcess_Vertex::SetupProperties( const Importer* pImp) {
{
this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES); this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void SplitLargeMeshesProcess_Vertex::SplitMesh( void SplitLargeMeshesProcess_Vertex::SplitMesh(
unsigned int a, unsigned int a,
aiMesh* pMesh, aiMesh* pMesh,
std::vector<std::pair<aiMesh*, unsigned int> >& avList) std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
{ if (pMesh->mNumVertices > SplitLargeMeshesProcess_Vertex::LIMIT) {
if (pMesh->mNumVertices > SplitLargeMeshesProcess_Vertex::LIMIT)
{
typedef std::vector< std::pair<unsigned int,float> > VertexWeightTable; typedef std::vector< std::pair<unsigned int,float> > VertexWeightTable;
// build a per-vertex weight list if necessary // build a per-vertex weight list if necessary
@ -426,7 +405,6 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
// determine the estimated size of a submesh // determine the estimated size of a submesh
// (this could be too large. Max waste is a single digit percentage) // (this could be too large. Max waste is a single digit percentage)
const unsigned int iSubMeshes = (pMesh->mNumVertices / SplitLargeMeshesProcess_Vertex::LIMIT) + 1; const unsigned int iSubMeshes = (pMesh->mNumVertices / SplitLargeMeshesProcess_Vertex::LIMIT) + 1;
//const unsigned int iOutVertexNum2 = pMesh->mNumVertices /iSubMeshes;
// create a std::vector<unsigned int> to indicate which vertices // create a std::vector<unsigned int> to indicate which vertices
// have already been copied // have already been copied
@ -439,11 +417,9 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
iEstimatedSize += iEstimatedSize >> 3; iEstimatedSize += iEstimatedSize >> 3;
// now generate all submeshes // now generate all submeshes
unsigned int iBase = 0; unsigned int iBase( 0 );
while (true) while (true) {
{
const unsigned int iOutVertexNum = SplitLargeMeshesProcess_Vertex::LIMIT; const unsigned int iOutVertexNum = SplitLargeMeshesProcess_Vertex::LIMIT;
aiMesh* pcMesh = new aiMesh; aiMesh* pcMesh = new aiMesh;
pcMesh->mNumVertices = 0; pcMesh->mNumVertices = 0;
pcMesh->mMaterialIndex = pMesh->mMaterialIndex; pcMesh->mMaterialIndex = pMesh->mMaterialIndex;
@ -452,18 +428,15 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
pcMesh->mName = pMesh->mName; pcMesh->mName = pMesh->mName;
typedef std::vector<aiVertexWeight> BoneWeightList; typedef std::vector<aiVertexWeight> BoneWeightList;
if (pMesh->HasBones()) if (pMesh->HasBones()) {
{
pcMesh->mBones = new aiBone*[pMesh->mNumBones]; pcMesh->mBones = new aiBone*[pMesh->mNumBones];
::memset(pcMesh->mBones,0,sizeof(void*)*pMesh->mNumBones); ::memset(pcMesh->mBones,0,sizeof(void*)*pMesh->mNumBones);
} }
// clear the temporary helper array // clear the temporary helper array
if (iBase) if (iBase) {
{
// we can't use memset here we unsigned int needn' be 32 bits // we can't use memset here we unsigned int needn' be 32 bits
for (auto &elem : avWasCopied) for (auto &elem : avWasCopied) {
{
elem = 0xffffffff; elem = 0xffffffff;
} }
} }
@ -472,50 +445,41 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
std::vector<aiFace> vFaces; std::vector<aiFace> vFaces;
// reserve enough storage for most cases // reserve enough storage for most cases
if (pMesh->HasPositions()) if (pMesh->HasPositions()) {
{
pcMesh->mVertices = new aiVector3D[iOutVertexNum]; pcMesh->mVertices = new aiVector3D[iOutVertexNum];
} }
if (pMesh->HasNormals()) if (pMesh->HasNormals()) {
{
pcMesh->mNormals = new aiVector3D[iOutVertexNum]; pcMesh->mNormals = new aiVector3D[iOutVertexNum];
} }
if (pMesh->HasTangentsAndBitangents()) if (pMesh->HasTangentsAndBitangents()) {
{
pcMesh->mTangents = new aiVector3D[iOutVertexNum]; pcMesh->mTangents = new aiVector3D[iOutVertexNum];
pcMesh->mBitangents = new aiVector3D[iOutVertexNum]; pcMesh->mBitangents = new aiVector3D[iOutVertexNum];
} }
for (unsigned int c = 0; pMesh->HasVertexColors(c);++c) for (unsigned int c = 0; pMesh->HasVertexColors(c);++c) {
{
pcMesh->mColors[c] = new aiColor4D[iOutVertexNum]; pcMesh->mColors[c] = new aiColor4D[iOutVertexNum];
} }
for (unsigned int c = 0; pMesh->HasTextureCoords(c);++c) for (unsigned int c = 0; pMesh->HasTextureCoords(c);++c) {
{
pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c]; pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
pcMesh->mTextureCoords[c] = new aiVector3D[iOutVertexNum]; pcMesh->mTextureCoords[c] = new aiVector3D[iOutVertexNum];
} }
vFaces.reserve(iEstimatedSize); vFaces.reserve(iEstimatedSize);
// (we will also need to copy the array of indices) // (we will also need to copy the array of indices)
while (iBase < pMesh->mNumFaces) while (iBase < pMesh->mNumFaces) {
{
// allocate a new array // allocate a new array
const unsigned int iNumIndices = pMesh->mFaces[iBase].mNumIndices; const unsigned int iNumIndices = pMesh->mFaces[iBase].mNumIndices;
// doesn't catch degenerates but is quite fast // doesn't catch degenerates but is quite fast
unsigned int iNeed = 0; unsigned int iNeed = 0;
for (unsigned int v = 0; v < iNumIndices;++v) for (unsigned int v = 0; v < iNumIndices;++v) {
{
unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v]; unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];
// check whether we do already have this vertex // check whether we do already have this vertex
if (0xFFFFFFFF == avWasCopied[iIndex]) if (0xFFFFFFFF == avWasCopied[iIndex]) {
{
iNeed++; iNeed++;
} }
} }
if (pcMesh->mNumVertices + iNeed > iOutVertexNum) if (pcMesh->mNumVertices + iNeed > iOutVertexNum) {
{
// don't use this face // don't use this face
break; break;
} }
@ -528,8 +492,7 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
rFace.mIndices = new unsigned int[iNumIndices]; rFace.mIndices = new unsigned int[iNumIndices];
// need to update the output primitive types // need to update the output primitive types
switch (rFace.mNumIndices) switch (rFace.mNumIndices) {
{
case 1: case 1:
pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
break; break;
@ -544,13 +507,11 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
} }
// and copy the contents of the old array, offset by current base // and copy the contents of the old array, offset by current base
for (unsigned int v = 0; v < iNumIndices;++v) for (unsigned int v = 0; v < iNumIndices;++v) {
{
unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v]; unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];
// check whether we do already have this vertex // check whether we do already have this vertex
if (0xFFFFFFFF != avWasCopied[iIndex]) if (0xFFFFFFFF != avWasCopied[iIndex]) {
{
rFace.mIndices[v] = avWasCopied[iIndex]; rFace.mIndices[v] = avWasCopied[iIndex];
continue; continue;
} }
@ -559,49 +520,38 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
pcMesh->mVertices[pcMesh->mNumVertices] = (pMesh->mVertices[iIndex]); pcMesh->mVertices[pcMesh->mNumVertices] = (pMesh->mVertices[iIndex]);
// copy normals // copy normals
if (pMesh->HasNormals()) if (pMesh->HasNormals()) {
{
pcMesh->mNormals[pcMesh->mNumVertices] = (pMesh->mNormals[iIndex]); pcMesh->mNormals[pcMesh->mNumVertices] = (pMesh->mNormals[iIndex]);
} }
// copy tangents/bitangents // copy tangents/bitangents
if (pMesh->HasTangentsAndBitangents()) if (pMesh->HasTangentsAndBitangents()) {
{
pcMesh->mTangents[pcMesh->mNumVertices] = (pMesh->mTangents[iIndex]); pcMesh->mTangents[pcMesh->mNumVertices] = (pMesh->mTangents[iIndex]);
pcMesh->mBitangents[pcMesh->mNumVertices] = (pMesh->mBitangents[iIndex]); pcMesh->mBitangents[pcMesh->mNumVertices] = (pMesh->mBitangents[iIndex]);
} }
// texture coordinates // texture coordinates
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
{ if (pMesh->HasTextureCoords( c)) {
if (pMesh->HasTextureCoords( c))
{
pcMesh->mTextureCoords[c][pcMesh->mNumVertices] = pMesh->mTextureCoords[c][iIndex]; pcMesh->mTextureCoords[c][pcMesh->mNumVertices] = pMesh->mTextureCoords[c][iIndex];
} }
} }
// vertex colors // vertex colors
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
{ if (pMesh->HasVertexColors( c)) {
if (pMesh->HasVertexColors( c))
{
pcMesh->mColors[c][pcMesh->mNumVertices] = pMesh->mColors[c][iIndex]; pcMesh->mColors[c][pcMesh->mNumVertices] = pMesh->mColors[c][iIndex];
} }
} }
// check whether we have bone weights assigned to this vertex // check whether we have bone weights assigned to this vertex
rFace.mIndices[v] = pcMesh->mNumVertices; rFace.mIndices[v] = pcMesh->mNumVertices;
if (avPerVertexWeights) if (avPerVertexWeights) {
{
VertexWeightTable& table = avPerVertexWeights[ pcMesh->mNumVertices ]; VertexWeightTable& table = avPerVertexWeights[ pcMesh->mNumVertices ];
if( !table.empty() ) if( !table.empty() ) {
{ for (VertexWeightTable::const_iterator iter = table.begin();
for (VertexWeightTable::const_iterator iter != table.end();++iter) {
iter = table.begin();
iter != table.end();++iter)
{
// allocate the bone weight array if necessary // allocate the bone weight array if necessary
BoneWeightList* pcWeightList = (BoneWeightList*)pcMesh->mBones[(*iter).first]; BoneWeightList* pcWeightList = (BoneWeightList*)pcMesh->mBones[(*iter).first];
if (!pcWeightList) if (nullptr == pcWeightList) {
{
pcMesh->mBones[(*iter).first] = (aiBone*)(pcWeightList = new BoneWeightList()); pcMesh->mBones[(*iter).first] = (aiBone*)(pcWeightList = new BoneWeightList());
} }
pcWeightList->push_back(aiVertexWeight(pcMesh->mNumVertices,(*iter).second)); pcWeightList->push_back(aiVertexWeight(pcMesh->mNumVertices,(*iter).second));
@ -612,26 +562,22 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
avWasCopied[iIndex] = pcMesh->mNumVertices; avWasCopied[iIndex] = pcMesh->mNumVertices;
pcMesh->mNumVertices++; pcMesh->mNumVertices++;
} }
iBase++; ++iBase;
if(pcMesh->mNumVertices == iOutVertexNum) if(pcMesh->mNumVertices == iOutVertexNum) {
{
// break here. The face is only added if it was complete // break here. The face is only added if it was complete
break; break;
} }
} }
// check which bones we'll need to create for this submesh // check which bones we'll need to create for this submesh
if (pMesh->HasBones()) if (pMesh->HasBones()) {
{
aiBone** ppCurrent = pcMesh->mBones; aiBone** ppCurrent = pcMesh->mBones;
for (unsigned int k = 0; k < pMesh->mNumBones;++k) for (unsigned int k = 0; k < pMesh->mNumBones;++k) {
{
// check whether the bone is existing // check whether the bone is existing
BoneWeightList* pcWeightList; BoneWeightList* pcWeightList;
if ((pcWeightList = (BoneWeightList*)pcMesh->mBones[k])) if ((pcWeightList = (BoneWeightList*)pcMesh->mBones[k])) {
{
aiBone* pcOldBone = pMesh->mBones[k]; aiBone* pcOldBone = pMesh->mBones[k];
aiBone* pcOut; aiBone* pcOut( nullptr );
*ppCurrent++ = pcOut = new aiBone(); *ppCurrent++ = pcOut = new aiBone();
pcOut->mName = aiString(pcOldBone->mName); pcOut->mName = aiString(pcOldBone->mName);
pcOut->mOffsetMatrix = pcOldBone->mOffsetMatrix; pcOut->mOffsetMatrix = pcOldBone->mOffsetMatrix;
@ -653,14 +599,14 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
pcMesh->mFaces = new aiFace[vFaces.size()]; pcMesh->mFaces = new aiFace[vFaces.size()];
pcMesh->mNumFaces = (unsigned int)vFaces.size(); pcMesh->mNumFaces = (unsigned int)vFaces.size();
for (unsigned int p = 0; p < pcMesh->mNumFaces;++p) for (unsigned int p = 0; p < pcMesh->mNumFaces;++p) {
pcMesh->mFaces[p] = vFaces[p]; pcMesh->mFaces[p] = vFaces[p];
}
// add the newly created mesh to the list // add the newly created mesh to the list
avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a)); avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a));
if (iBase == pMesh->mNumFaces) if (iBase == pMesh->mNumFaces) {
{
// have all faces ... finish the outer loop, too // have all faces ... finish the outer loop, too
break; break;
} }
@ -674,5 +620,4 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
return; return;
} }
avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a)); avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
return;
} }

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