Merge branch 'master' into pugi_xml

pull/2966/head
Kim Kulling 2020-09-25 21:00:09 +02:00
commit d6892b3f58
161 changed files with 12572 additions and 1672 deletions

View File

@ -8,30 +8,39 @@ on:
jobs:
job:
name: ${{ matrix.os }}-${{ matrix.cxx }}-build-and-test
name: ${{ matrix.name }}-build-and-test
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
name: [ubuntu-gcc, macos-clang, windows-msvc, ubuntu-clang]
name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++, ubuntu-gcc-hunter, macos-clang-hunter, windows-msvc-hunter]
# For Windows msvc, for Linux and macOS let's use the clang compiler, use gcc for Linux.
include:
- name: windows-msvc
- name: windows-latest-cl.exe
os: windows-latest
cxx: cl.exe
cc: cl.exe
- name: ubuntu-clang
- name: ubuntu-latest-clang++
os: ubuntu-latest
cxx: clang++
cc: clang
- name: macos-clang
- name: macos-latest-clang++
os: macos-latest
cxx: clang++
cc: clang
- name: ubuntu-gcc
- name: ubuntu-latest-g++
os: ubuntu-latest
cxx: g++
cc: gcc
- name: ubuntu-gcc-hunter
os: ubuntu-latest
toolchain: ninja-gcc-cxx17-fpic
- name: macos-clang-hunter
os: macos-latest
toolchain: ninja-clang-cxx17-fpic
- name: windows-msvc-hunter
os: windows-latest
toolchain: ninja-vs-win64-cxx17
steps:
- uses: actions/checkout@v2
@ -40,20 +49,75 @@ jobs:
- uses: ilammy/msvc-dev-cmd@v1
- uses: lukka/set-shell-env@v1
- name: Set Compiler Environment
if: "!endsWith(matrix.name, 'hunter')"
uses: lukka/set-shell-env@v1
with:
CXX: ${{ matrix.cxx }}
CC: ${{ matrix.cc }}
- name: Set Compiler Environment for Hunter on Windows
if: startsWith(matrix.name, 'windows') && endsWith(matrix.name, 'hunter')
uses: lukka/set-shell-env@v1
with:
VS160COMNTOOLS: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools
- name: Checkout Hunter toolchains
if: endsWith(matrix.name, 'hunter')
uses: actions/checkout@v2
with:
repository: cpp-pm/polly
path: cmake/polly
- name: Cache DX SDK
id: dxcache
if: contains(matrix.name, 'windows')
uses: actions/cache@v2
with:
path: '${{ github.workspace }}/DX_SDK'
key: ${{ runner.os }}-DX_SDK
restore-keys: |
${{ runner.os }}-DX_SDK
- name: Download DXSetup
if: contains(matrix.name, 'windows') && steps.dxcache.outputs.cache-hit != 'true'
run: |
curl -s -o DXSDK_Jun10.exe --location https://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe
cmd.exe /c start /wait .\DXSDK_Jun10.exe /U /O /F /S /P "${{ github.workspace }}\DX_SDK"
- name: Set Windows specific CMake arguments
if: contains(matrix.name, 'windows')
id: windows_extra_cmake_args
run: echo "::set-output name=args::-DASSIMP_BUILD_ASSIMP_TOOLS=1 -DASSIMP_BUILD_ASSIMP_VIEW=1"
- name: Set Hunter specific CMake arguments
if: contains(matrix.name, 'hunter')
id: hunter_extra_cmake_args
run: echo "::set-output name=args::-DBUILD_SHARED_LIBS=OFF -DASSIMP_HUNTER_ENABLED=ON -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/cmake/polly/${{ matrix.toolchain }}.cmake"
- name: configure and build
uses: lukka/run-cmake@v2
env:
DXSDK_DIR: '${{ github.workspace }}/DX_SDK'
with:
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt'
cmakeAppendedArgs: '-GNinja -DCMAKE_BUILD_TYPE=Release'
cmakeAppendedArgs: '-GNinja -DCMAKE_BUILD_TYPE=Release ${{ steps.windows_extra_cmake_args.outputs.args }} ${{ steps.hunter_extra_cmake_args.outputs.args }}'
buildWithCMakeArgs: '-- -v'
buildDirectory: '${{ github.workspace }}/build/'
- name: Exclude certain tests in Hunter specific builds
if: contains(matrix.name, 'hunter')
id: hunter_extra_test_args
run: echo "::set-output name=args::--gtest_filter=-utOpenGEXImportExport.Importissue1340_EmptyCameraObject:utColladaZaeImportExport.importBlenFromFileTest"
- name: test
run: cd build/bin && ./unit
run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
shell: bash
- uses: actions/upload-artifact@v2
if: matrix.name == 'windows-msvc'
with:
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
path: build/bin

View File

@ -35,6 +35,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#----------------------------------------------------------------------
SET(CMAKE_POLICY_DEFAULT_CMP0074 NEW)
SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW)
CMAKE_MINIMUM_REQUIRED( VERSION 3.0 )
@ -44,8 +45,8 @@ option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
IF(ASSIMP_HUNTER_ENABLED)
include("cmake/HunterGate.cmake")
HunterGate(
URL "https://github.com/ruslo/hunter/archive/v0.23.176.tar.gz"
SHA1 "2e9ae973d028660b735ac4c6142725ca36a0048a"
URL "https://github.com/cpp-pm/hunter/archive/v0.23.269.tar.gz"
SHA1 "64024b7b95b4c86d50ae05b926814448c93a70a0"
)
add_definitions(-DASSIMP_USE_HUNTER)
@ -254,7 +255,11 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
SET(LIBSTDC++_LIBRARIES -lstdc++)
ELSEIF(MSVC)
# enable multi-core compilation with MSVC
ADD_COMPILE_OPTIONS(/MP /bigobj /W4 /WX )
IF( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) # clang-cl
ADD_COMPILE_OPTIONS(/bigobj /W4 /WX )
ELSE() # msvc
ADD_COMPILE_OPTIONS(/MP /bigobj /W4 /WX)
ENDIF()
# disable "elements of array '' will be default initialized" warning on MSVC2013
IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351)
@ -318,26 +323,27 @@ ENDIF()
IF (ASSIMP_UBSAN)
MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
ENDIF()
INCLUDE (FindPkgMacros)
INCLUDE (PrecompiledHeader)
# If this is an in-source build (CMAKE_SOURCE_DIR == CMAKE_BINARY_DIR),
# write the library/executable files to the respective directories in the
# source tree. During an out-of-source build, however, do not litter this
# directory, since that is probably what the user wanted to avoid.
IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" )
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" )
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" )
ELSE()
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
ENDIF ()
# Set Assimp project output directory variables.
SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
# Macro used to set the output directories of a target to the
# respective Assimp output directories.
MACRO(TARGET_USE_COMMON_OUTPUT_DIRECTORY target)
set_target_properties(${target} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${ASSIMP_RUNTIME_OUTPUT_DIRECTORY}
LIBRARY_OUTPUT_DIRECTORY ${ASSIMP_LIBRARY_OUTPUT_DIRECTORY}
ARCHIVE_OUTPUT_DIRECTORY ${ASSIMP_ARCHIVE_OUTPUT_DIRECTORY}
)
ENDMACRO()
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
@ -354,6 +360,34 @@ IF (NOT TARGET uninstall)
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
ENDIF()
# cmake configuration files
if(${BUILD_SHARED_LIBS})
set(BUILD_LIB_TYPE SHARED)
else()
set(BUILD_LIB_TYPE STATIC)
endif()
IF( UNIX )
# Use GNUInstallDirs for Unix predefined directories
INCLUDE(GNUInstallDirs)
SET( ASSIMP_LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR})
SET( ASSIMP_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
SET( ASSIMP_BIN_INSTALL_DIR ${CMAKE_INSTALL_BINDIR})
ELSE()
# Cache these to allow the user to override them on non-Unix platforms
SET( ASSIMP_LIB_INSTALL_DIR "lib" CACHE STRING
"Path the built library files are installed to." )
SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE STRING
"Path the header files are installed to." )
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE STRING
"Path the tool executables are installed to." )
SET(CMAKE_INSTALL_FULL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/${ASSIMP_INCLUDE_INSTALL_DIR})
SET(CMAKE_INSTALL_FULL_LIBDIR ${CMAKE_INSTALL_PREFIX}/${ASSIMP_LIB_INSTALL_DIR})
SET(CMAKE_INSTALL_FULL_BINDIR ${CMAKE_INSTALL_PREFIX}/${ASSIMP_BIN_INSTALL_DIR})
ENDIF()
IF(ASSIMP_HUNTER_ENABLED)
set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
set(INCLUDE_INSTALL_DIR "include")
@ -392,34 +426,6 @@ IF(ASSIMP_HUNTER_ENABLED)
DESTINATION "${CONFIG_INSTALL_DIR}"
)
ELSE()
# cmake configuration files
if(${BUILD_SHARED_LIBS})
set(BUILD_LIB_TYPE SHARED)
else()
set(BUILD_LIB_TYPE STATIC)
endif()
IF( UNIX )
# Use GNUInstallDirs for Unix predefined directories
INCLUDE(GNUInstallDirs)
SET( ASSIMP_LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR})
SET( ASSIMP_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
SET( ASSIMP_BIN_INSTALL_DIR ${CMAKE_INSTALL_BINDIR})
ELSE()
# Cache these to allow the user to override them on non-Unix platforms
SET( ASSIMP_LIB_INSTALL_DIR "lib" CACHE STRING
"Path the built library files are installed to." )
SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE STRING
"Path the header files are installed to." )
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE STRING
"Path the tool executables are installed to." )
SET(CMAKE_INSTALL_FULL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/${ASSIMP_INCLUDE_INSTALL_DIR})
SET(CMAKE_INSTALL_FULL_LIBDIR ${CMAKE_INSTALL_PREFIX}/${ASSIMP_LIB_INSTALL_DIR})
SET(CMAKE_INSTALL_FULL_BINDIR ${CMAKE_INSTALL_PREFIX}/${ASSIMP_BIN_INSTALL_DIR})
ENDIF()
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)
IF (is_multi_config)
@ -671,7 +677,8 @@ if(WIN32)
ENDIF()
IF(MSVC_TOOLSET_VERSION)
set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
SET(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
SET(ASSIMP_MSVC_VERSION ${MCVS_PREFIX})
ELSE()
IF(MSVC12)
SET(ASSIMP_MSVC_VERSION "vc120")

View File

@ -4,8 +4,6 @@ A library to import and export various 3d-model-formats including scene-post-pro
### Current project status ###
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
<a href="https://scan.coverity.com/projects/5607">
<img alt="Coverity Scan Build Status"
src="https://scan.coverity.com/projects/5607/badge.svg"/>
@ -72,7 +70,7 @@ The source code is organized in the following way:
For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
(CHMs for Windows are included in some release packages and should be located right here in the root folder).
If the docs don't solve your problem, ask on [StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
If the docs don't solve your problem, ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
For development discussions, there is also a (very low-volume) mailing list, _assimp-discussions_
[(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)

View File

@ -1,4 +1,4 @@
# Copyright (c) 2013-2018, Ruslan Baratov
# Copyright (c) 2013-2019, Ruslan Baratov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -60,7 +60,7 @@ option(HUNTER_STATUS_PRINT "Print working status" ON)
option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
set(HUNTER_WIKI "https://github.com/ruslo/hunter/wiki")
set(HUNTER_ERROR_PAGE "https://docs.hunter.sh/en/latest/reference/errors")
function(hunter_gate_status_print)
if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
@ -79,9 +79,9 @@ function(hunter_gate_status_debug)
endif()
endfunction()
function(hunter_gate_wiki wiki_page)
message("------------------------------ WIKI -------------------------------")
message(" ${HUNTER_WIKI}/${wiki_page}")
function(hunter_gate_error_page error_page)
message("------------------------------ ERROR ------------------------------")
message(" ${HUNTER_ERROR_PAGE}/${error_page}.html")
message("-------------------------------------------------------------------")
message("")
message(FATAL_ERROR "")
@ -94,14 +94,13 @@ function(hunter_gate_internal_error)
endforeach()
message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
message("")
hunter_gate_wiki("error.internal")
hunter_gate_error_page("error.internal")
endfunction()
function(hunter_gate_fatal_error)
cmake_parse_arguments(hunter "" "WIKI" "" "${ARGV}")
string(COMPARE EQUAL "${hunter_WIKI}" "" have_no_wiki)
if(have_no_wiki)
hunter_gate_internal_error("Expected wiki")
cmake_parse_arguments(hunter "" "ERROR_PAGE" "" "${ARGV}")
if("${hunter_ERROR_PAGE}" STREQUAL "")
hunter_gate_internal_error("Expected ERROR_PAGE")
endif()
message("")
foreach(x ${hunter_UNPARSED_ARGUMENTS})
@ -109,11 +108,11 @@ function(hunter_gate_fatal_error)
endforeach()
message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
message("")
hunter_gate_wiki("${hunter_WIKI}")
hunter_gate_error_page("${hunter_ERROR_PAGE}")
endfunction()
function(hunter_gate_user_error)
hunter_gate_fatal_error(${ARGV} WIKI "error.incorrect.input.data")
hunter_gate_fatal_error(${ARGV} ERROR_PAGE "error.incorrect.input.data")
endfunction()
function(hunter_gate_self root version sha1 result)
@ -195,7 +194,7 @@ function(hunter_gate_detect_root)
hunter_gate_fatal_error(
"Can't detect HUNTER_ROOT"
WIKI "error.detect.hunter.root"
ERROR_PAGE "error.detect.hunter.root"
)
endfunction()
@ -214,7 +213,7 @@ function(hunter_gate_download dir)
"Settings:"
" HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
" HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
WIKI "error.run.install"
ERROR_PAGE "error.run.install"
)
endif()
string(COMPARE EQUAL "${dir}" "" is_bad)
@ -400,7 +399,7 @@ macro(HunterGate)
hunter_gate_fatal_error(
"Please set HunterGate *before* 'project' command. "
"Detected project: ${PROJECT_NAME}"
WIKI "error.huntergate.before.project"
ERROR_PAGE "error.huntergate.before.project"
)
endif()
@ -470,7 +469,7 @@ macro(HunterGate)
"HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
"Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
"(Use at your own risk!)"
WIKI "error.spaces.in.hunter.root"
ERROR_PAGE "error.spaces.in.hunter.root"
)
endif()
endif()

View File

@ -2,7 +2,7 @@
find_package(RapidJSON CONFIG REQUIRED)
find_package(ZLIB CONFIG REQUIRED)
find_package(utf8 CONFIG REQUIRED)
find_package(utf8cpp CONFIG REQUIRED)
find_package(irrXML CONFIG REQUIRED)
find_package(minizip CONFIG REQUIRED)
find_package(openddlparser CONFIG REQUIRED)

View File

@ -290,12 +290,18 @@ void Discreet3DSExporter::WriteMaterials() {
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
WriteColor(color);
}
if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
WriteColor(color);
}
float f;
if (mat.Get(AI_MATKEY_OPACITY, f) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TRANSPARENCY);
WritePercentChunk(1.0f - f);
}
if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) {
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
WriteColor(color);
@ -333,7 +339,6 @@ void Discreet3DSExporter::WriteMaterials() {
writer.PutU2(static_cast<uint16_t>(shading_mode_out));
}
float f;
if (mat.Get(AI_MATKEY_SHININESS, f) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS);
WritePercentChunk(f);

View File

@ -321,9 +321,10 @@ public:
struct Face : public FaceWithSmoothingGroup {
};
#ifdef _WIN32
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4315)
#endif
#endif // _MSC_VER
// ---------------------------------------------------------------------------
/** Helper structure representing a texture */
@ -412,6 +413,10 @@ struct Texture {
#include <assimp/Compiler/poppack1.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif // _MSC_VER
// ---------------------------------------------------------------------------
/** Helper structure representing a 3ds material */
struct Material {

View File

@ -147,7 +147,7 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
// We should have at least one chunk
if (theStream.GetRemainingSize() < 16) {
throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile);
throw DeadlyImportError("3DS file is either empty or corrupt: ", pFile);
}
this->stream = &theStream;
@ -178,7 +178,7 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
// file.
for (auto &mesh : mScene->mMeshes) {
if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) {
throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile);
throw DeadlyImportError("3DS file contains faces but no vertices: ", pFile);
}
CheckIndices(mesh);
MakeUnique(mesh);

View File

@ -122,7 +122,7 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
mZipArchive() {
mZipArchive.reset(new ZipArchiveIOSystem(pIOHandler, rFile));
if (!mZipArchive->isOpen()) {
throw DeadlyImportError("Failed to open file " + rFile + ".");
throw DeadlyImportError("Failed to open file ", rFile, ".");
}
std::vector<std::string> fileList;
@ -198,7 +198,7 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
});
if (itr == reader.m_relationShips.end()) {
throw DeadlyImportError("Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
}
return (*itr)->target;

View File

@ -471,26 +471,33 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
++node->mNumMeshes;
}
switch ((*it).flags & 0xf) {
switch ((*it).GetType()) {
// closed line
case 0x1:
case Surface::ClosedLine:
needMat[idx].first += (unsigned int)(*it).entries.size();
needMat[idx].second += (unsigned int)(*it).entries.size() << 1u;
break;
// unclosed line
case 0x2:
case Surface::OpenLine:
needMat[idx].first += (unsigned int)(*it).entries.size() - 1;
needMat[idx].second += ((unsigned int)(*it).entries.size() - 1) << 1u;
break;
// 0 == polygon, else unknown
default:
if ((*it).flags & 0xf) {
ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown");
(*it).flags &= ~(0xf);
}
// triangle strip
case Surface::TriangleStrip:
needMat[idx].first += (unsigned int)(*it).entries.size() - 2;
needMat[idx].second += ((unsigned int)(*it).entries.size() - 2) * 3;
break;
default:
// Coerce unknowns to a polygon and warn
ASSIMP_LOG_WARN_F("AC3D: The type flag of a surface is unknown: ", (*it).flags);
(*it).flags &= ~(Surface::Mask);
// fallthrough
// polygon
case Surface::Polygon:
// the number of faces increments by one, the number
// of vertices by surface.numref.
needMat[idx].first++;
@ -546,8 +553,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
const Surface &src = *it;
// closed polygon
unsigned int type = (*it).flags & 0xf;
if (!type) {
uint8_t type = (*it).GetType();
if (type == Surface::Polygon) {
aiFace &face = *faces++;
face.mNumIndices = (unsigned int)src.entries.size();
if (0 != face.mNumIndices) {
@ -570,13 +577,71 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
}
}
}
} else if (type == Surface::TriangleStrip) {
for (unsigned int i = 0; i < (unsigned int)src.entries.size() - 2; ++i) {
const Surface::SurfaceEntry &entry1 = src.entries[i];
const Surface::SurfaceEntry &entry2 = src.entries[i + 1];
const Surface::SurfaceEntry &entry3 = src.entries[i + 2];
// skip degenerate triangles
if (object.vertices[entry1.first] == object.vertices[entry2.first] ||
object.vertices[entry1.first] == object.vertices[entry3.first] ||
object.vertices[entry2.first] == object.vertices[entry3.first]) {
mesh->mNumFaces--;
mesh->mNumVertices -= 3;
continue;
}
aiFace &face = *faces++;
face.mNumIndices = 3;
face.mIndices = new unsigned int[face.mNumIndices];
face.mIndices[0] = cur++;
face.mIndices[1] = cur++;
face.mIndices[2] = cur++;
if (!(i & 1)) {
*vertices++ = object.vertices[entry1.first] + object.translation;
if (uv) {
uv->x = entry1.second.x;
uv->y = entry1.second.y;
++uv;
}
*vertices++ = object.vertices[entry2.first] + object.translation;
if (uv) {
uv->x = entry2.second.x;
uv->y = entry2.second.y;
++uv;
}
} else {
*vertices++ = object.vertices[entry2.first] + object.translation;
if (uv) {
uv->x = entry2.second.x;
uv->y = entry2.second.y;
++uv;
}
*vertices++ = object.vertices[entry1.first] + object.translation;
if (uv) {
uv->x = entry1.second.x;
uv->y = entry1.second.y;
++uv;
}
}
if (static_cast<unsigned>(vertices - mesh->mVertices) >= mesh->mNumVertices) {
throw DeadlyImportError("AC3D: Invalid number of vertices");
}
*vertices++ = object.vertices[entry3.first] + object.translation;
if (uv) {
uv->x = entry3.second.x;
uv->y = entry3.second.y;
++uv;
}
}
} else {
it2 = (*it).entries.begin();
// either a closed or an unclosed line
unsigned int tmp = (unsigned int)(*it).entries.size();
if (0x2 == type) --tmp;
if (Surface::OpenLine == type) --tmp;
for (unsigned int m = 0; m < tmp; ++m) {
aiFace &face = *faces++;
@ -599,7 +664,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
++uv;
}
if (0x1 == type && tmp - 1 == m) {
if (Surface::ClosedLine == type && tmp - 1 == m) {
// if this is a closed line repeat its beginning now
it2 = (*it).entries.begin();
} else
@ -697,7 +762,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open AC3D file " + pFile + ".");
throw DeadlyImportError("Failed to open AC3D file ", pFile, ".");
}
// allocate storage and copy the contents of the file to a memory buffer

View File

@ -69,7 +69,10 @@ public:
// Represents an AC3D material
struct Material {
Material() :
rgb(0.6f, 0.6f, 0.6f), spec(1.f, 1.f, 1.f), shin(0.f), trans(0.f) {}
rgb(0.6f, 0.6f, 0.6f),
spec(1.f, 1.f, 1.f),
shin(0.f),
trans(0.f) {}
// base color of the material
aiColor3D rgb;
@ -96,18 +99,43 @@ public:
// Represents an AC3D surface
struct Surface {
Surface() :
mat(0), flags(0) {}
mat(0),
flags(0) {}
unsigned int mat, flags;
typedef std::pair<unsigned int, aiVector2D> SurfaceEntry;
std::vector<SurfaceEntry> entries;
// Type is low nibble of flags
enum Type : uint8_t {
Polygon = 0x0,
ClosedLine = 0x1,
OpenLine = 0x2,
TriangleStrip = 0x4, // ACC extension (TORCS and Speed Dreams)
Mask = 0xf,
};
inline constexpr uint8_t GetType() const { return (flags & Mask); }
};
// Represents an AC3D object
struct Object {
Object() :
type(World), name(""), children(), texture(""), texRepeat(1.f, 1.f), texOffset(0.0f, 0.0f), rotation(), translation(), vertices(), surfaces(), numRefs(0), subDiv(0), crease() {}
type(World),
name(""),
children(),
texture(""),
texRepeat(1.f, 1.f),
texOffset(0.0f, 0.0f),
rotation(),
translation(),
vertices(),
surfaces(),
numRefs(0),
subDiv(0),
crease() {}
// Type description
enum Type {

View File

@ -170,7 +170,7 @@ void AMFImporter::Throw_MoreThanOnceDefined(const std::string &nodeName, const s
}
void AMFImporter::Throw_ID_NotFound(const std::string &pID) const {
throw DeadlyImportError("Not found node with name \"" + pID + "\".");
throw DeadlyImportError("Not found node with name \"", pID, "\".");
}
/*********************************************************************************************************************************************/
@ -267,7 +267,7 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open AMF file " + pFile + ".");
throw DeadlyImportError("Failed to open AMF file ", pFile, ".");
}
mXmlParser = new XmlParser();
@ -409,7 +409,7 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
bool read_flag[6] = { false, false, false, false, false, false };
std::string currentName = currentNode.name();
const std::string &currentName = currentNode.name();
if (currentName == "deltax") {
read_flag[0] = true;
als.Delta.x = (ai_real)std::atof(currentNode.value());
@ -446,8 +446,7 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
// Multi elements - Yes.
// Parent element - <amf>.
void AMFImporter::ParseNode_Object(XmlNode &node) {
AMFNodeElementBase *ne(nullptr);
AMFNodeElementBase *ne = nullptr;
// Read attributes for node <object>.
std::string id = node.attribute("id").as_string();
@ -466,7 +465,7 @@ void AMFImporter::ParseNode_Object(XmlNode &node) {
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string currentName = currentNode.name();
const std::string &currentName = currentNode.name();
if (currentName == "color") {
ParseNode_Color(currentNode);
col_read = true;
@ -523,9 +522,8 @@ bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool p
return true;
}
if (!extension.length() || pCheckSig) {
if (extension.empty() || pCheckSig) {
const char *tokens[] = { "<amf" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}

View File

@ -137,7 +137,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open ASE file " + pFile + ".");
throw DeadlyImportError("Failed to open ASE file ", pFile, ".");
}
// Allocate storage and copy the contents of the file to a memory buffer

View File

@ -60,10 +60,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <time.h>
#ifdef _WIN32
#if _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4706)
#endif // _WIN32
#endif // _MSC_VER
namespace Assimp {
@ -825,8 +825,8 @@ void DumpSceneToAssbin(
AssbinFileWriter fileWriter(shortened, compressed);
fileWriter.WriteBinaryDump(pFile, cmd, pIOSystem, pScene);
}
#ifdef _WIN32
#if _MSC_VER
#pragma warning(pop)
#endif // _WIN32
#endif // _MSC_VER
} // end of namespace Assimp

View File

@ -8,9 +8,9 @@ For details, see http://sourceforge.net/projects/libb64
#ifndef BASE64_CENCODE_H
#define BASE64_CENCODE_H
#ifdef _WIN32
#ifdef _MSC_VER
#pragma warning(disable : 4127 )
#endif // _WIN32
#endif // _MSC_VER
typedef enum
{

View File

@ -119,7 +119,7 @@ void B3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open B3D file " + pFile + ".");
throw DeadlyImportError("Failed to open B3D file ", pFile, ".");
}
// check whether the .b3d file is large enough to contain
@ -147,7 +147,7 @@ AI_WONT_RETURN void B3DImporter::Fail(string str) {
#ifdef DEBUG_B3D
ASSIMP_LOG_ERROR_F("Error in B3D file data: ", str);
#endif
throw DeadlyImportError("B3D Importer - error in B3D file data: " + str);
throw DeadlyImportError("B3D Importer - error in B3D file data: ", str);
}
// ------------------------------------------------------------------------------------------------

View File

@ -71,6 +71,13 @@ static const aiImporterDesc desc = {
"bvh"
};
// ------------------------------------------------------------------------------------------------
// Aborts the file reading with an exception
template<typename... T>
AI_WONT_RETURN void BVHLoader::ThrowException(T&&... args) {
throw DeadlyImportError(mFileName, ":", mLine, " - ", args...);
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
BVHLoader::BVHLoader() :
@ -118,7 +125,7 @@ void BVHLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IOSyst
// read file into memory
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open file " + pFile + ".");
throw DeadlyImportError("Failed to open file ", pFile, ".");
}
size_t fileSize = file->FileSize();
@ -176,12 +183,12 @@ aiNode *BVHLoader::ReadNode() {
// first token is name
std::string nodeName = GetNextToken();
if (nodeName.empty() || nodeName == "{")
ThrowException(format() << "Expected node name, but found \"" << nodeName << "\".");
ThrowException("Expected node name, but found \"", nodeName, "\".");
// then an opening brace should follow
std::string openBrace = GetNextToken();
if (openBrace != "{")
ThrowException(format() << "Expected opening brace \"{\", but found \"" << openBrace << "\".");
ThrowException("Expected opening brace \"{\", but found \"", openBrace, "\".");
// Create a node
aiNode *node = new aiNode(nodeName);
@ -211,7 +218,7 @@ aiNode *BVHLoader::ReadNode() {
siteToken.clear();
siteToken = GetNextToken();
if (siteToken != "Site")
ThrowException(format() << "Expected \"End Site\" keyword, but found \"" << token << " " << siteToken << "\".");
ThrowException("Expected \"End Site\" keyword, but found \"", token, " ", siteToken, "\".");
aiNode *child = ReadEndSite(nodeName);
child->mParent = node;
@ -221,7 +228,7 @@ aiNode *BVHLoader::ReadNode() {
break;
} else {
// everything else is a parse error
ThrowException(format() << "Unknown keyword \"" << token << "\".");
ThrowException("Unknown keyword \"", token, "\".");
}
}
@ -242,7 +249,7 @@ aiNode *BVHLoader::ReadEndSite(const std::string &pParentName) {
// check opening brace
std::string openBrace = GetNextToken();
if (openBrace != "{")
ThrowException(format() << "Expected opening brace \"{\", but found \"" << openBrace << "\".");
ThrowException("Expected opening brace \"{\", but found \"", openBrace, "\".");
// Create a node
aiNode *node = new aiNode("EndSite_" + pParentName);
@ -261,7 +268,7 @@ aiNode *BVHLoader::ReadEndSite(const std::string &pParentName) {
break;
} else {
// everything else is a parse error
ThrowException(format() << "Unknown keyword \"" << token << "\".");
ThrowException("Unknown keyword \"", token, "\".");
}
}
@ -307,7 +314,7 @@ void BVHLoader::ReadNodeChannels(BVHLoader::Node &pNode) {
else if (channelToken == "Zrotation")
pNode.mChannels.push_back(Channel_RotationZ);
else
ThrowException(format() << "Invalid channel specifier \"" << channelToken << "\".");
ThrowException("Invalid channel specifier \"", channelToken, "\".");
}
}
@ -317,7 +324,7 @@ void BVHLoader::ReadMotion(aiScene * /*pScene*/) {
// Read number of frames
std::string tokenFrames = GetNextToken();
if (tokenFrames != "Frames:")
ThrowException(format() << "Expected frame count \"Frames:\", but found \"" << tokenFrames << "\".");
ThrowException("Expected frame count \"Frames:\", but found \"", tokenFrames, "\".");
float numFramesFloat = GetNextTokenAsFloat();
mAnimNumFrames = (unsigned int)numFramesFloat;
@ -326,7 +333,7 @@ void BVHLoader::ReadMotion(aiScene * /*pScene*/) {
std::string tokenDuration1 = GetNextToken();
std::string tokenDuration2 = GetNextToken();
if (tokenDuration1 != "Frame" || tokenDuration2 != "Time:")
ThrowException(format() << "Expected frame duration \"Frame Time:\", but found \"" << tokenDuration1 << " " << tokenDuration2 << "\".");
ThrowException("Expected frame duration \"Frame Time:\", but found \"", tokenDuration1, " ", tokenDuration2, "\".");
mAnimTickDuration = GetNextTokenAsFloat();
@ -393,17 +400,11 @@ float BVHLoader::GetNextTokenAsFloat() {
ctoken = fast_atoreal_move<float>(ctoken, result);
if (ctoken != token.c_str() + token.length())
ThrowException(format() << "Expected a floating point number, but found \"" << token << "\".");
ThrowException("Expected a floating point number, but found \"", token, "\".");
return result;
}
// ------------------------------------------------------------------------------------------------
// Aborts the file reading with an exception
AI_WONT_RETURN void BVHLoader::ThrowException(const std::string &pError) {
throw DeadlyImportError(format() << mFileName << ":" << mLine << " - " << pError);
}
// ------------------------------------------------------------------------------------------------
// Constructs an animation for the motion data and stores it in the given scene
void BVHLoader::CreateAnimation(aiScene *pScene) {
@ -453,7 +454,7 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
if (mapIter == channelMap.end())
throw DeadlyImportError("Missing position channel in node " + nodeName);
throw DeadlyImportError("Missing position channel in node ", nodeName);
else {
int channelIdx = mapIter->second;
switch (channel) {

View File

@ -134,7 +134,8 @@ protected:
float GetNextTokenAsFloat();
/** Aborts the file reading with an exception */
AI_WONT_RETURN void ThrowException(const std::string &pError) AI_WONT_RETURN_SUFFIX;
template<typename... T>
AI_WONT_RETURN void ThrowException(T&&... args) AI_WONT_RETURN_SUFFIX;
/** Constructs an animation for the motion data and stores it in the given scene */
void CreateAnimation(aiScene *pScene);

View File

@ -149,7 +149,7 @@ bool isValidCustomDataType(const int cdtype) {
bool readCustomData(std::shared_ptr<ElemBase> &out, const int cdtype, const size_t cnt, const FileDatabase &db) {
if (!isValidCustomDataType(cdtype)) {
throw Error((Formatter::format(), "CustomData.type ", cdtype, " out of index"));
throw Error("CustomData.type ", cdtype, " out of index");
}
const CustomDataTypeDescription cdtd = customDataTypeDescriptions[cdtype];

View File

@ -130,9 +130,7 @@ void DNAParser::Parse() {
uint16_t n = stream.GetI2();
if (n >= types.size()) {
throw DeadlyImportError((format(),
"BlenderDNA: Invalid type index in structure name", n,
" (there are only ", types.size(), " entries)"));
throw DeadlyImportError("BlenderDNA: Invalid type index in structure name", n, " (there are only ", types.size(), " entries)");
}
// maintain separate indexes
@ -151,9 +149,7 @@ void DNAParser::Parse() {
uint16_t j = stream.GetI2();
if (j >= types.size()) {
throw DeadlyImportError((format(),
"BlenderDNA: Invalid type index in structure field ", j,
" (there are only ", types.size(), " entries)"));
throw DeadlyImportError("BlenderDNA: Invalid type index in structure field ", j, " (there are only ", types.size(), " entries)");
}
s.fields.push_back(Field());
Field &f = s.fields.back();
@ -164,9 +160,7 @@ void DNAParser::Parse() {
j = stream.GetI2();
if (j >= names.size()) {
throw DeadlyImportError((format(),
"BlenderDNA: Invalid name index in structure field ", j,
" (there are only ", names.size(), " entries)"));
throw DeadlyImportError("BlenderDNA: Invalid name index in structure field ", j, " (there are only ", names.size(), " entries)");
}
f.name = names[j];
@ -188,9 +182,7 @@ void DNAParser::Parse() {
if (*f.name.rbegin() == ']') {
const std::string::size_type rb = f.name.find('[');
if (rb == std::string::npos) {
throw DeadlyImportError((format(),
"BlenderDNA: Encountered invalid array declaration ",
f.name));
throw DeadlyImportError("BlenderDNA: Encountered invalid array declaration ", f.name);
}
f.flags |= FieldFlag_Array;

View File

@ -83,9 +83,10 @@ class ObjectCache;
* ancestry. */
// -------------------------------------------------------------------------------
struct Error : DeadlyImportError {
Error(const std::string &s) :
DeadlyImportError(s) {
// empty
template<typename... T>
explicit Error(T&&... args)
: DeadlyImportError(args...)
{
}
};

View File

@ -57,9 +57,7 @@ const Field& Structure :: operator [] (const std::string& ss) const
{
std::map<std::string, size_t>::const_iterator it = indices.find(ss);
if (it == indices.end()) {
throw Error((Formatter::format(),
"BlendDNA: Did not find a field named `",ss,"` in structure `",name,"`"
));
throw Error("BlendDNA: Did not find a field named `",ss,"` in structure `",name,"`");
}
return fields[(*it).second];
@ -76,9 +74,7 @@ const Field* Structure :: Get (const std::string& ss) const
const Field& Structure :: operator [] (const size_t i) const
{
if (i >= fields.size()) {
throw Error((Formatter::format(),
"BlendDNA: There is no field with index `",i,"` in structure `",name,"`"
));
throw Error("BlendDNA: There is no field with index `",i,"` in structure `",name,"`");
}
return fields[i];
@ -109,9 +105,7 @@ void Structure :: ReadFieldArray(T (& out)[M], const char* name, const FileDatab
// is the input actually an array?
if (!(f.flags & FieldFlag_Array)) {
throw Error((Formatter::format(),"Field `",name,"` of structure `",
this->name,"` ought to be an array of size ",M
));
throw Error("Field `",name,"` of structure `",this->name,"` ought to be an array of size ",M);
}
db.reader->IncPtr(f.offset);
@ -148,9 +142,9 @@ void Structure :: ReadFieldArray2(T (& out)[M][N], const char* name, const FileD
// is the input actually an array?
if (!(f.flags & FieldFlag_Array)) {
throw Error((Formatter::format(),"Field `",name,"` of structure `",
throw Error("Field `",name,"` of structure `",
this->name,"` ought to be an array of size ",M,"*",N
));
);
}
db.reader->IncPtr(f.offset);
@ -195,8 +189,8 @@ bool Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabas
// sanity check, should never happen if the genblenddna script is right
if (!(f->flags & FieldFlag_Pointer)) {
throw Error((Formatter::format(),"Field `",name,"` of structure `",
this->name,"` ought to be a pointer"));
throw Error("Field `",name,"` of structure `",
this->name,"` ought to be a pointer");
}
db.reader->IncPtr(f->offset);
@ -241,8 +235,8 @@ bool Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
#ifdef _DEBUG
// sanity check, should never happen if the genblenddna script is right
if ((FieldFlag_Pointer|FieldFlag_Pointer) != (f->flags & (FieldFlag_Pointer|FieldFlag_Pointer))) {
throw Error((Formatter::format(),"Field `",name,"` of structure `",
this->name,"` ought to be a pointer AND an array"));
throw Error("Field `",name,"` of structure `",
this->name,"` ought to be a pointer AND an array");
}
#endif // _DEBUG
@ -322,8 +316,8 @@ bool Structure::ReadCustomDataPtr(std::shared_ptr<ElemBase>&out, int cdtype, con
// sanity check, should never happen if the genblenddna script is right
if (!(f->flags & FieldFlag_Pointer)) {
throw Error((Formatter::format(), "Field `", name, "` of structure `",
this->name, "` ought to be a pointer"));
throw Error("Field `", name, "` of structure `",
this->name, "` ought to be a pointer");
}
db.reader->IncPtr(f->offset);
@ -369,8 +363,8 @@ bool Structure::ReadFieldPtrVector(vector<TOUT<T>>&out, const char* name, const
// sanity check, should never happen if the genblenddna script is right
if (!(f->flags & FieldFlag_Pointer)) {
throw Error((Formatter::format(), "Field `", name, "` of structure `",
this->name, "` ought to be a pointer"));
throw Error("Field `", name, "` of structure `",
this->name, "` ought to be a pointer");
}
db.reader->IncPtr(f->offset);
@ -428,9 +422,9 @@ bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const Fil
// and check if it matches the type which we expect.
const Structure& ss = db.dna[block->dna_index];
if (ss != s) {
throw Error((Formatter::format(),"Expected target to be of type `",s.name,
throw Error("Expected target to be of type `",s.name,
"` but seemingly it is a `",ss.name,"` instead"
));
);
}
// try to retrieve the object from the cache
@ -614,16 +608,14 @@ const FileBlockHead* Structure :: LocateFileBlockForAddress(const Pointer & ptrv
if (it == db.entries.end()) {
// this is crucial, pointers may not be invalid.
// this is either a corrupted file or an attempted attack.
throw DeadlyImportError((Formatter::format(),"Failure resolving pointer 0x",
std::hex,ptrval.val,", no file block falls into this address range"
));
throw DeadlyImportError("Failure resolving pointer 0x",
std::hex,ptrval.val,", no file block falls into this address range");
}
if (ptrval.val >= (*it).address.val + (*it).size) {
throw DeadlyImportError((Formatter::format(),"Failure resolving pointer 0x",
throw DeadlyImportError("Failure resolving pointer 0x",
std::hex,ptrval.val,", nearest file block starting at 0x",
(*it).address.val," ends at 0x",
(*it).address.val + (*it).size
));
(*it).address.val + (*it).size);
}
return &*it;
}
@ -676,7 +668,7 @@ template <typename T> inline void ConvertDispatcher(T& out, const Structure& in,
out = static_cast<T>(db.reader->GetF8());
}
else {
throw DeadlyImportError("Unknown source for conversion to primitive data type: "+in.name);
throw DeadlyImportError("Unknown source for conversion to primitive data type: ", in.name);
}
}
@ -784,9 +776,7 @@ const Structure& DNA :: operator [] (const std::string& ss) const
{
std::map<std::string, size_t>::const_iterator it = indices.find(ss);
if (it == indices.end()) {
throw Error((Formatter::format(),
"BlendDNA: Did not find a structure named `",ss,"`"
));
throw Error("BlendDNA: Did not find a structure named `",ss,"`");
}
return structures[(*it).second];
@ -803,9 +793,7 @@ const Structure* DNA :: Get (const std::string& ss) const
const Structure& DNA :: operator [] (const size_t i) const
{
if (i >= structures.size()) {
throw Error((Formatter::format(),
"BlendDNA: There is no structure with index `",i,"`"
));
throw Error("BlendDNA: There is no structure with index `",i,"`");
}
return structures[i];

View File

@ -748,9 +748,8 @@ void BlenderImporter::BuildMaterials(ConversionData &conv_data) {
void BlenderImporter::CheckActualType(const ElemBase *dt, const char *check) {
ai_assert(dt);
if (strcmp(dt->dna_type, check)) {
ThrowException((format(),
"Expected object at ", std::hex, dt, " to be of type `", check,
"`, but it claims to be a `", dt->dna_type, "`instead"));
ThrowException("Expected object at ", std::hex, dt, " to be of type `", check,
"`, but it claims to be a `", dt->dna_type, "`instead");
}
}

View File

@ -386,7 +386,14 @@ void BlenderTessellatorP2T::ReferencePoints( std::vector< Blender::PointP2T >& p
// ------------------------------------------------------------------------------------------------
inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& point ) const
{
#if defined __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Winvalid-offsetof"
#endif // __clang__
unsigned int pointOffset = offsetof( PointP2T, point2D );
#if defined __clang__
# pragma clang diagnostic pop
#endif
PointP2T& pointStruct = *reinterpret_cast< PointP2T* >( reinterpret_cast< char* >( &point ) - pointOffset );
if ( pointStruct.magic != static_cast<int>( BLEND_TESS_MAGIC ) )
{
@ -394,7 +401,6 @@ inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& poi
}
return pointStruct;
}
// ------------------------------------------------------------------------------------------------
void BlenderTessellatorP2T::MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const
{

View File

@ -125,7 +125,7 @@ void COBImporter::SetupProperties(const Importer * /*pImp*/) {
// ------------------------------------------------------------------------------------------------
/*static*/ AI_WONT_RETURN void COBImporter::ThrowException(const std::string &msg) {
throw DeadlyImportError("COB: " + msg);
throw DeadlyImportError("COB: ", msg);
}
// ------------------------------------------------------------------------------------------------

View File

@ -128,7 +128,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
// Check whether we can read from the file
if( file.get() == nullptr) {
throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
throw DeadlyImportError( "Failed to open CSM file ", pFile, ".");
}
// allocate storage and copy the contents of the file to a memory buffer

View File

@ -1245,7 +1245,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// time count and value count must match
if (e.mTimeAccessor->mCount != e.mValueAccessor->mCount)
throw DeadlyImportError(format() << "Time count / value count mismatch in animation channel \"" << e.mChannel->mTarget << "\".");
throw DeadlyImportError("Time count / value count mismatch in animation channel \"", e.mChannel->mTarget, "\".");
if (e.mTimeAccessor->mCount > 0) {
// find bounding times
@ -1462,7 +1462,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
for (size_t a = 0; a < morphAnims.size(); ++a) {
anim->mDuration = std::max(anim->mDuration, morphAnims[a]->mKeys[morphAnims[a]->mNumKeys - 1].mTime);
}
anim->mTicksPerSecond = 1;
anim->mTicksPerSecond = 1000.0;
mAnims.push_back(anim);
}
}

View File

@ -101,24 +101,24 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
std::string dae_filename = ReadZaeManifest(*zip_archive);
if (dae_filename.empty()) {
ThrowException(std::string("Invalid ZAE"));
throw DeadlyImportError("Invalid ZAE");
}
daefile.reset(zip_archive->Open(dae_filename.c_str()));
if (daefile == nullptr) {
ThrowException(std::string("Invalid ZAE manifest: '") + std::string(dae_filename) + std::string("' is missing"));
throw DeadlyImportError("Invalid ZAE manifest: '", dae_filename, "' is missing");
}
} else {
// attempt to open the file directly
daefile.reset(pIOHandler->Open(pFile));
if (daefile.get() == nullptr) {
throw DeadlyImportError("Failed to open file '" + pFile + "'.");
throw DeadlyImportError("Failed to open file '", pFile, "'.");
}
}
// generate a XML reader for it
if (!mXmlParser.parse(daefile.get())) {
ThrowException("Unable to read file, malformed XML");
throw DeadlyImportError("Unable to read file, malformed XML");
}
// start reading
XmlNode node = mXmlParser.getRootNode();
@ -391,7 +391,7 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
if (url) {
const std::string urlName = url.as_string();
if (urlName[0] != '#') {
ThrowException("Unknown reference format");
throw DeadlyImportError("Unknown reference format");
}
clip.second.push_back(url.as_string());
}
@ -430,7 +430,6 @@ void ColladaParser::PostProcessRootAnimations() {
}
Animation temp;
for (AnimationClipLibrary::iterator it = mAnimationClipLibrary.begin(); it != mAnimationClipLibrary.end(); ++it) {
std::string clipName = it->first;
@ -568,8 +567,9 @@ void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChanne
if (XmlParser::hasAttribute(currentNode, "source")) {
XmlParser::getStdStrAttribute(currentNode, "source", sourceAttr);
const char *source = sourceAttr.c_str();
if (source[0] != '#')
ThrowException("Unsupported URL format");
if (source[0] != '#') {
throw DeadlyImportError("Unsupported URL format");
}
source++;
if (semantic == "INPUT")
@ -671,7 +671,7 @@ void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pCo
const char *attrSemantic = currentNode.attribute("semantic").as_string();
const char *attrSource = currentNode.attribute("source").as_string();
if (attrSource[0] != '#') {
ThrowException(format() << "Unsupported URL format in \"" << attrSource << "\" in source attribute of <joints> data <input> element");
throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of <joints> data <input> element");
}
++attrSource;
// parse source URL to corresponding source
@ -680,7 +680,7 @@ void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pCo
} else if (strcmp(attrSemantic, "INV_BIND_MATRIX") == 0) {
pController.mJointOffsetMatrixSource = attrSource;
} else {
ThrowException(format() << "Unknown semantic \"" << attrSemantic << "\" in <joints> data <input> element");
throw DeadlyImportError("Unknown semantic \"" , attrSemantic , "\" in <joints> data <input> element");
}
}
}
@ -704,7 +704,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
// local URLS always start with a '#'. We don't support global URLs
if (attrSource[0] != '#') {
ThrowException(format() << "Unsupported URL format in \"" << attrSource << "\" in source attribute of <vertex_weights> data <input> element");
throw DeadlyImportError( "Unsupported URL format in \"", attrSource, "\" in source attribute of <vertex_weights> data <input> element");
}
channel.mAccessor = attrSource + 1;
@ -714,14 +714,14 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
} else if (strcmp(attrSemantic, "WEIGHT") == 0) {
pController.mWeightInputWeights = channel;
} else {
ThrowException(format() << "Unknown semantic \"" << attrSemantic << "\" in <vertex_weights> data <input> element");
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <vertex_weights> data <input> element");
}
} else if (currentName == "vcount" && vertexCount > 0) {
const char *text = currentNode.value();
size_t numWeights = 0;
for (std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
if (*text == 0) {
ThrowException("Out of data while reading <vcount>");
throw DeadlyImportError("Out of data while reading <vcount>");
}
*it = strtoul10(text, &text);
@ -737,12 +737,13 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
const char *text = stdText.c_str();
for (std::vector<std::pair<size_t, size_t>>::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) {
if (text == 0) {
ThrowException("Out of data while reading <vertex_weights>");
throw DeadlyImportError("Out of data while reading <vertex_weights>");
}
it->first = strtoul10(text, &text);
SkipSpacesAndLineEnd(&text);
if (*text == 0)
ThrowException("Out of data while reading <vertex_weights>");
if (*text == 0) {
throw DeadlyImportError("Out of data while reading <vertex_weights>");
}
it->second = strtoul10(text, &text);
SkipSpacesAndLineEnd(&text);
}
@ -925,7 +926,7 @@ void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
if (currentName == "instance_effect") {
const char *url = currentNode.attribute("url").as_string();
if (url[0] != '#') {
ThrowException("Unknown reference format");
throw DeadlyImportError("Unknown reference format");
}
pMaterial.mEffect = url + 1;
}
@ -1300,8 +1301,9 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
// surface ID is given inside <instance_image> tags
std::string url;
XmlParser::getStdStrAttribute(currentNode, "url", url);
if (url[0] != '#')
ThrowException("Unsupported URL format in instance_image");
if (url[0] != '#') {
throw DeadlyImportError("Unsupported URL format in instance_image");
}
pParam.mType = Param_Sampler;
pParam.mReference = url.c_str() + 1;
}
@ -1426,8 +1428,9 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
std::string s;
for (unsigned int a = 0; a < count; a++) {
if (*content == 0)
ThrowException("Expected more values while reading IDREF_array contents.");
if (*content == 0) {
throw DeadlyImportError("Expected more values while reading IDREF_array contents.");
}
s.clear();
while (!IsSpaceOrNewLine(*content))
@ -1440,8 +1443,9 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
data.mValues.reserve(count);
for (unsigned int a = 0; a < count; a++) {
if (*content == 0)
ThrowException("Expected more values while reading float_array contents.");
if (*content == 0) {
throw DeadlyImportError("Expected more values while reading float_array contents.");
}
ai_real value;
// read a number
@ -1461,9 +1465,10 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
// read accessor attributes
std::string source;
XmlParser::getStdStrAttribute(node, "source", source);
if (source[0] != '#')
ThrowException(format() << "Unknown reference format in url \"" << source << "\" in source attribute of <accessor> element.");
int count;
if (source[0] != '#') {
throw DeadlyImportError("Unknown reference format in url \"", source, "\" in source attribute of <accessor> element.");
}
int count = 0;
XmlParser::getIntAttribute(node, "count", count);
unsigned int offset = 0;
@ -1561,7 +1566,7 @@ void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) {
if (currentName == "input") {
ReadInputChannel(currentNode, pMesh.mPerVertexData);
} else {
ThrowException(format() << "Unexpected sub element <" << currentName << "> in tag <vertices>");
throw DeadlyImportError("Unexpected sub element <", currentName, "> in tag <vertices>");
}
}
}
@ -1628,8 +1633,9 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
const char *content = v.c_str();
vcount.reserve(numPrimitives);
for (unsigned int a = 0; a < numPrimitives; a++) {
if (*content == 0)
ThrowException("Expected more values while reading <vcount> contents.");
if (*content == 0) {
throw DeadlyImportError("Expected more values while reading <vcount> contents.");
}
// read a number
vcount.push_back((size_t)strtoul10(content, &content));
// skip whitespace after it
@ -1647,7 +1653,7 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
} else if (currentName == "ph") {
// skip
} else {
ThrowException(format() << "Unexpected sub element <" << currentName << "> in tag <" << elementName << ">");
throw DeadlyImportError("Unexpected sub element <", currentName, "> in tag <", elementName, ">");
}
}
@ -1671,17 +1677,14 @@ void ColladaParser::ReadInputChannel(XmlNode &node, std::vector<InputChannel> &p
// read semantic
std::string semantic;
XmlParser::getStdStrAttribute(node, "semantic", semantic);
//int attrSemantic = GetAttribute("semantic");
//std::string semantic = mReader->getAttributeValue(attrSemantic);
channel.mType = GetTypeForSemantic(semantic);
// read source
std::string source;
XmlParser::getStdStrAttribute(node, "source", source);
//int attrSource = GetAttribute("source");
//const char *source = mReader->getAttributeValue(attrSource);
if (source[0] != '#')
ThrowException(format() << "Unknown reference format in url \"" << source << "\" in source attribute of <input> element.");
if (source[0] != '#') {
throw DeadlyImportError("Unknown reference format in url \"", source, "\" in source attribute of <input> element.");
}
channel.mAccessor = source.c_str() + 1; // skipping the leading #, hopefully the remaining text is the accessor ID only
// read index offset, if per-index <input>
@ -1763,11 +1766,13 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
// HACK: We just fix this number since SketchUp 15.3.331 writes the wrong 'count' for 'lines'
ReportWarning("Expected different index count in <p> element, %zu instead of %zu.", indices.size(), expectedPointCount * numOffsets);
pNumPrimitives = (indices.size() / numOffsets) / 2;
} else
ThrowException("Expected different index count in <p> element.");
} else {
throw DeadlyImportError("Expected different index count in <p> element.");
}
} else if (expectedPointCount == 0 && (indices.size() % numOffsets) != 0)
ThrowException("Expected different index count in <p> element.");
} else if (expectedPointCount == 0 && (indices.size() % numOffsets) != 0) {
throw DeadlyImportError("Expected different index count in <p> element.");
}
// find the data for all sources
for (std::vector<InputChannel>::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
@ -1791,8 +1796,9 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
// ignore vertex pointer, it doesn't refer to an accessor
if (input.mType == IT_Vertex) {
// warn if the vertex channel does not refer to the <vertices> element in the same mesh
if (input.mAccessor != pMesh.mVertexID)
ThrowException("Unsupported vertex referencing scheme.");
if (input.mAccessor != pMesh.mVertexID) {
throw DeadlyImportError("Unsupported vertex referencing scheme.");
}
continue;
}
@ -1859,7 +1865,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
break;
default:
// LineStrip is not supported due to expected index unmangling
ThrowException("Unsupported primitive type.");
throw DeadlyImportError("Unsupported primitive type.");
break;
}
@ -1915,8 +1921,9 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
return;
const Accessor &acc = *pInput.mResolved;
if (pLocalIndex >= acc.mCount)
ThrowException(format() << "Invalid data index (" << pLocalIndex << "/" << acc.mCount << ") in primitive specification");
if (pLocalIndex >= acc.mCount) {
throw DeadlyImportError("Invalid data index (", pLocalIndex, "/", acc.mCount, ") in primitive specification");
}
// get a pointer to the start of the data object referred to by the accessor and the local index
const ai_real *dataObject = &(acc.mData->mValues[0]) + acc.mOffset + pLocalIndex * acc.mStride;
@ -2121,8 +2128,9 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
if (XmlParser::hasAttribute(currentNode, "url")) {
std::string url;
XmlParser::getStdStrAttribute(currentNode, "url", url);
if (url[0] != '#')
ThrowException("Unknown reference format in <instance_light> element");
if (url[0] != '#') {
throw DeadlyImportError("Unknown reference format in <instance_light> element");
}
pNode->mLights.push_back(LightInstance());
pNode->mLights.back().mLight = url.c_str() + 1;
@ -2133,7 +2141,7 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
std::string url;
XmlParser::getStdStrAttribute(currentNode, "url", url);
if (url[0] != '#') {
ThrowException("Unknown reference format in <instance_camera> element");
throw DeadlyImportError("Unknown reference format in <instance_camera> element");
}
pNode->mCameras.push_back(CameraInstance());
pNode->mCameras.back().mCamera = url.c_str() + 1;
@ -2237,8 +2245,9 @@ void ColladaParser::ReadNodeGeometry(XmlNode &node, Node *pNode) {
// referred mesh is given as an attribute of the <instance_geometry> element
std::string url;
XmlParser::getStdStrAttribute(node, "url", url);
if (url[0] != '#')
ThrowException("Unknown reference format");
if (url[0] != '#') {
throw DeadlyImportError("Unknown reference format");
}
Collada::MeshInstance instance;
instance.mMeshOrController = url.c_str() + 1; // skipping the leading #
@ -2277,32 +2286,27 @@ void ColladaParser::ReadScene(XmlNode &node) {
const std::string currentName = currentNode.name();
if (currentName == "instance_visual_scene") {
// should be the first and only occurrence
if (mRootNode)
ThrowException("Invalid scene containing multiple root nodes in <instance_visual_scene> element");
if (mRootNode) {
throw DeadlyImportError("Invalid scene containing multiple root nodes in <instance_visual_scene> element");
}
// read the url of the scene to instance. Should be of format "#some_name"
std::string url;
XmlParser::getStdStrAttribute(currentNode, "url", url);
if (url[0] != '#') {
ThrowException("Unknown reference format in <instance_visual_scene> element");
throw DeadlyImportError("Unknown reference format in <instance_visual_scene> element");
}
// find the referred scene, skip the leading #
NodeLibrary::const_iterator sit = mNodeLibrary.find(url.c_str() + 1);
if (sit == mNodeLibrary.end()) {
ThrowException("Unable to resolve visual_scene reference \"" + std::string(url) + "\" in <instance_visual_scene> element.");
throw DeadlyImportError("Unable to resolve visual_scene reference \"", std::string(url), "\" in <instance_visual_scene> element.");
}
mRootNode = sit->second;
}
}
}
// ------------------------------------------------------------------------------------------------
// Aborts the file reading with an exception
AI_WONT_RETURN void ColladaParser::ThrowException(const std::string &pError) const {
throw DeadlyImportError(format() << "Collada: " << mFileName << " - " << pError);
}
void ColladaParser::ReportWarning(const char *msg, ...) {
ai_assert(nullptr != msg);

View File

@ -243,8 +243,6 @@ protected:
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
protected:
/** Aborts the file reading with an exception */
AI_WONT_RETURN void ThrowException(const std::string &pError) const AI_WONT_RETURN_SUFFIX;
void ReportWarning(const char *msg, ...);
/** Calculates the resulting transformation from all the given transform steps */
@ -348,8 +346,9 @@ protected:
template <typename Type>
const Type &ColladaParser::ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const {
typename std::map<std::string, Type>::const_iterator it = pLibrary.find(pURL);
if (it == pLibrary.end())
ThrowException(Formatter::format() << "Unable to resolve library reference \"" << pURL << "\".");
if (it == pLibrary.end()) {
throw DeadlyImportError("Unable to resolve library reference \"", pURL, "\".");
}
return it->second;
}

View File

@ -152,7 +152,7 @@ void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene,
// Check whether we can read the file
if( file.get() == nullptr ) {
throw DeadlyImportError( "Failed to open DXF file " + filename + "");
throw DeadlyImportError( "Failed to open DXF file ", filename, "");
}
// Check whether this is a binary DXF file - we can't read binary DXF files :-(

View File

@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Exceptional.h>
#include <assimp/ByteSwapper.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/StringUtils.h>
namespace Assimp {
namespace FBX {
@ -126,7 +127,7 @@ namespace {
AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset)
{
throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset));
throw DeadlyImportError("FBX-Tokenize", Util::GetOffsetText(offset), message);
}
@ -456,11 +457,21 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
ASSIMP_LOG_DEBUG_F("FBX version: ", version);
const bool is64bits = version >= 7500;
const char *end = input + length;
while (cursor < end ) {
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
break;
try
{
while (cursor < end ) {
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
break;
}
}
}
catch (const DeadlyImportError& e)
{
if (!is64bits && (length > std::numeric_limits<std::uint32_t>::max())) {
throw DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", to_string(version), ") of the FBX format. (", e.what(), ")");
}
throw;
}
}
} // !FBX

View File

@ -1988,6 +1988,7 @@ void FBXConverter::SetTextureProperties(aiMaterial *out_mat, const TextureMap &_
TrySetTextureProperties(out_mat, _textures, "ShininessExponent", aiTextureType_SHININESS, mesh);
TrySetTextureProperties(out_mat, _textures, "TransparencyFactor", aiTextureType_OPACITY, mesh);
TrySetTextureProperties(out_mat, _textures, "EmissiveFactor", aiTextureType_EMISSIVE, mesh);
TrySetTextureProperties(out_mat, _textures, "ReflectionFactor", aiTextureType_METALNESS, mesh);
//Maya counterparts
TrySetTextureProperties(out_mat, _textures, "Maya|DiffuseTexture", aiTextureType_DIFFUSE, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|NormalTexture", aiTextureType_NORMALS, mesh);

View File

@ -61,7 +61,7 @@ namespace Util {
// signal DOM construction error, this is always unrecoverable. Throws DeadlyImportError.
void DOMError(const std::string& message, const Token& token)
{
throw DeadlyImportError(Util::AddTokenText("FBX-DOM",message,&token));
throw DeadlyImportError("FBX-DOM", Util::GetTokenText(&token), message);
}
// ------------------------------------------------------------------------------------------------
@ -70,7 +70,7 @@ void DOMError(const std::string& message, const Element* element /*= nullptr*/)
if(element) {
DOMError(message,element->KeyToken());
}
throw DeadlyImportError("FBX-DOM " + message);
throw DeadlyImportError("FBX-DOM ", message);
}
@ -79,7 +79,7 @@ void DOMError(const std::string& message, const Element* element /*= nullptr*/)
void DOMWarning(const std::string& message, const Token& token)
{
if(DefaultLogger::get()) {
ASSIMP_LOG_WARN(Util::AddTokenText("FBX-DOM",message,&token));
ASSIMP_LOG_WARN_F("FBX-DOM", Util::GetTokenText(&token), message);
}
}

View File

@ -400,6 +400,65 @@ void FBXExporter::WriteHeaderExtension ()
);
}
// WriteGlobalSettings helpers
void WritePropInt(const aiScene* scene, FBX::Node& p, const std::string& key, int defaultValue)
{
int value;
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, value)) {
p.AddP70int(key, value);
} else {
p.AddP70int(key, defaultValue);
}
}
void WritePropDouble(const aiScene* scene, FBX::Node& p, const std::string& key, double defaultValue)
{
double value;
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, value)) {
p.AddP70double(key, value);
} else {
// fallback lookup float instead
float floatValue;
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, floatValue)) {
p.AddP70double(key, (double)floatValue);
} else {
p.AddP70double(key, defaultValue);
}
}
}
void WritePropEnum(const aiScene* scene, FBX::Node& p, const std::string& key, int defaultValue)
{
int value;
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, value)) {
p.AddP70enum(key, value);
} else {
p.AddP70enum(key, defaultValue);
}
}
void WritePropColor(const aiScene* scene, FBX::Node& p, const std::string& key, const aiVector3D& defaultValue)
{
aiVector3D value;
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, value)) {
// ai_real can be float or double, cast to avoid warnings
p.AddP70color(key, (double)value.x, (double)value.y, (double)value.z);
} else {
p.AddP70color(key, (double)defaultValue.x, (double)defaultValue.y, (double)defaultValue.z);
}
}
void WritePropString(const aiScene* scene, FBX::Node& p, const std::string& key, const std::string& defaultValue)
{
aiString value; // MetaData doesn't hold std::string
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, value)) {
p.AddP70string(key, value.C_Str());
} else {
p.AddP70string(key, defaultValue);
}
}
void FBXExporter::WriteGlobalSettings ()
{
if (!binary) {
@ -409,26 +468,26 @@ void FBXExporter::WriteGlobalSettings ()
gs.AddChild("Version", int32_t(1000));
FBX::Node p("Properties70");
p.AddP70int("UpAxis", 1);
p.AddP70int("UpAxisSign", 1);
p.AddP70int("FrontAxis", 2);
p.AddP70int("FrontAxisSign", 1);
p.AddP70int("CoordAxis", 0);
p.AddP70int("CoordAxisSign", 1);
p.AddP70int("OriginalUpAxis", 1);
p.AddP70int("OriginalUpAxisSign", 1);
p.AddP70double("UnitScaleFactor", 1.0);
p.AddP70double("OriginalUnitScaleFactor", 1.0);
p.AddP70color("AmbientColor", 0.0, 0.0, 0.0);
p.AddP70string("DefaultCamera", "Producer Perspective");
p.AddP70enum("TimeMode", 11);
p.AddP70enum("TimeProtocol", 2);
p.AddP70enum("SnapOnFrameMode", 0);
WritePropInt(mScene, p, "UpAxis", 1);
WritePropInt(mScene, p, "UpAxisSign", 1);
WritePropInt(mScene, p, "FrontAxis", 2);
WritePropInt(mScene, p, "FrontAxisSign", 1);
WritePropInt(mScene, p, "CoordAxis", 0);
WritePropInt(mScene, p, "CoordAxisSign", 1);
WritePropInt(mScene, p, "OriginalUpAxis", 1);
WritePropInt(mScene, p, "OriginalUpAxisSign", 1);
WritePropDouble(mScene, p, "UnitScaleFactor", 1.0);
WritePropDouble(mScene, p, "OriginalUnitScaleFactor", 1.0);
WritePropColor(mScene, p, "AmbientColor", aiVector3D((ai_real)0.0, (ai_real)0.0, (ai_real)0.0));
WritePropString(mScene, p,"DefaultCamera", "Producer Perspective");
WritePropEnum(mScene, p, "TimeMode", 11);
WritePropEnum(mScene, p, "TimeProtocol", 2);
WritePropEnum(mScene, p, "SnapOnFrameMode", 0);
p.AddP70time("TimeSpanStart", 0); // TODO: animation support
p.AddP70time("TimeSpanStop", FBX::SECOND); // TODO: animation support
p.AddP70double("CustomFrameRate", -1.0);
WritePropDouble(mScene, p, "CustomFrameRate", -1.0);
p.AddP70("TimeMarker", "Compound", "", ""); // not sure what this is
p.AddP70int("CurrentTimeMarker", -1);
WritePropInt(mScene, p, "CurrentTimeMarker", -1);
gs.AddChild(p);
gs.Dump(outfile, binary, 0);

View File

@ -141,7 +141,10 @@ void FBXImporter::SetupProperties(const Importer *pImp) {
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
auto streamCloser = [&](IOStream *pStream) {
pIOHandler->Close(pStream);
};
std::unique_ptr<IOStream, decltype(streamCloser)> stream(pIOHandler->Open(pFile, "rb"), streamCloser);
if (!stream) {
ThrowException("Could not open file for reading");
}

View File

@ -73,7 +73,7 @@ namespace {
AI_WONT_RETURN void ParseError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ParseError(const std::string& message, const Token& token)
{
throw DeadlyImportError(Util::AddTokenText("FBX-Parser",message,&token));
throw DeadlyImportError("FBX-Parser", Util::GetTokenText(&token), message);
}
// ------------------------------------------------------------------------------------------------
@ -83,7 +83,7 @@ namespace {
if(element) {
ParseError(message,element->KeyToken());
}
throw DeadlyImportError("FBX-Parser " + message);
throw DeadlyImportError("FBX-Parser ", message);
}

View File

@ -90,7 +90,7 @@ namespace {
AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int line, unsigned int column) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int line, unsigned int column)
{
throw DeadlyImportError(Util::AddLineAndColumn("FBX-Tokenize",message,line,column));
throw DeadlyImportError("FBX-Tokenize", Util::GetLineAndColumnText(line,column), message);
}

View File

@ -86,32 +86,30 @@ const char* TokenTypeString(TokenType t)
// ------------------------------------------------------------------------------------------------
std::string AddOffset(const std::string& prefix, const std::string& text, size_t offset)
std::string GetOffsetText(size_t offset)
{
return static_cast<std::string>( (Formatter::format() << prefix << " (offset 0x" << std::hex << offset << ") " << text) );
return static_cast<std::string>( Formatter::format() << " (offset 0x" << std::hex << offset << ") " );
}
// ------------------------------------------------------------------------------------------------
std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column)
std::string GetLineAndColumnText(unsigned int line, unsigned int column)
{
return static_cast<std::string>( (Formatter::format() << prefix << " (line " << line << " << col " << column << ") " << text) );
return static_cast<std::string>( Formatter::format() << " (line " << line << " << col " << column << ") " );
}
// ------------------------------------------------------------------------------------------------
std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok)
std::string GetTokenText(const Token* tok)
{
if(tok->IsBinary()) {
return static_cast<std::string>( (Formatter::format() << prefix <<
return static_cast<std::string>( Formatter::format() <<
" (" << TokenTypeString(tok->Type()) <<
", offset 0x" << std::hex << tok->Offset() << ") " <<
text) );
", offset 0x" << std::hex << tok->Offset() << ") " );
}
return static_cast<std::string>( (Formatter::format() << prefix <<
return static_cast<std::string>( Formatter::format() <<
" (" << TokenTypeString(tok->Type()) <<
", line " << tok->Line() <<
", col " << tok->Column() << ") " <<
text) );
", col " << tok->Column() << ") " );
}
// Generated by this formula: T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;

View File

@ -73,31 +73,24 @@ const char* TokenTypeString(TokenType t);
/** Format log/error messages using a given offset in the source binary file
*
* @param prefix Message prefix to be preprended to the location info.
* @param text Message text
* @param line Line index, 1-based
* @param column Column index, 1-based
* @return A string of the following format: {prefix} (offset 0x{offset}) {text}*/
std::string AddOffset(const std::string& prefix, const std::string& text, size_t offset);
* @param offset offset within the file
* @return A string of the following format: " (offset 0x{offset}) "*/
std::string GetOffsetText(size_t offset);
/** Format log/error messages using a given line location in the source file.
*
* @param prefix Message prefix to be preprended to the location info.
* @param text Message text
* @param line Line index, 1-based
* @param column Column index, 1-based
* @return A string of the following format: {prefix} (line {line}, col {column}) {text}*/
std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column);
* @return A string of the following format: " (line {line}, col {column}) "*/
std::string GetLineAndColumnText(unsigned int line, unsigned int column);
/** Format log/error messages using a given cursor token.
*
* @param prefix Message prefix to be preprended to the location info.
* @param text Message text
* @param tok Token where parsing/processing stopped
* @return A string of the following format: {prefix} ({token-type}, line {line}, col {column}) {text}*/
std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok);
* @return A string of the following format: " ({token-type}, line {line}, col {column}) "*/
std::string GetTokenText(const Token* tok);
/** Decode a single Base64-encoded character.
*

View File

@ -115,7 +115,7 @@ void HMPImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open HMP file " + pFile + ".");
throw DeadlyImportError("Failed to open HMP file ", pFile, ".");
}
// Check whether the HMP file is large enough to contain
@ -159,8 +159,8 @@ void HMPImporter::InternReadFile(const std::string &pFile,
szBuffer[4] = '\0';
// We're definitely unable to load this file
throw DeadlyImportError("Unknown HMP subformat " + pFile +
". Magic word (" + szBuffer + ") is not known");
throw DeadlyImportError("Unknown HMP subformat ", pFile,
". Magic word (", szBuffer, ") is not known");
}
// Set the AI_SCENE_FLAGS_TERRAIN bit

View File

@ -45,6 +45,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "IFCReaderGen_2x3.h"
#if _MSC_VER
# pragma warning(push)
# pragma warning(disable : 4702)
#endif // _MSC_VER
namespace Assimp {
using namespace ::Assimp::IFC;
@ -3165,4 +3170,8 @@ template <> size_t GenericFill<IfcLightSourceDirectional>(const DB& db, const LI
} // ! STEP
} // ! Assimp
#if _MSC_VER
# pragma warning(pop)
#endif // _MSC_VER
#endif

View File

@ -43,6 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "IFCReaderGen_2x3.h"
#if _MSC_VER
# pragma warning(push)
# pragma warning(disable : 4702)
#endif // _MSC_VER
namespace Assimp {
using namespace IFC;
using namespace ::Assimp::IFC::Schema_2x3;
@ -1915,4 +1920,8 @@ template <> size_t GenericFill<IfcConditionCriterion>(const DB& db, const LIST&
} // ! STEP
} // ! Assimp
#if _MSC_VER
# pragma warning(pop)
#endif // _MSC_VER
#endif

View File

@ -45,9 +45,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssetLib/Step/STEPFile.h"
#ifdef _WIN32
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning( disable : 4512 )
#endif // _WIN32
#endif // _MSC_VER
namespace Assimp {
namespace IFC {
@ -4372,4 +4373,8 @@ namespace STEP {
} //! STEP
} //! Assimp
#ifdef _MSC_VER
# pragma warning(pop)
#endif // _MSC_VER
#endif // INCLUDED_IFC_READER_GEN_H

View File

@ -145,7 +145,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open LWO file " + pFile + ".");
throw DeadlyImportError("Failed to open LWO file ", pFile, ".");
}
if ((this->fileSize = (unsigned int)file->FileSize()) < 12) {
@ -212,7 +212,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
szBuff[2] = (char)(fileType >> 8u);
szBuff[3] = (char)(fileType);
szBuff[4] = '\0';
throw DeadlyImportError(std::string("Unknown LWO sub format: ") + szBuff);
throw DeadlyImportError("Unknown LWO sub format: ", szBuff);
}
if (AI_LWO_FOURCC_LWOB != fileType) {
@ -232,7 +232,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
}
if (configLayerName.length() && !hasNamedLayer) {
throw DeadlyImportError("LWO2: Unable to find the requested layer: " + configLayerName);
throw DeadlyImportError("LWO2: Unable to find the requested layer: ", configLayerName);
}
}

View File

@ -502,7 +502,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open LWS file " + pFile + ".");
throw DeadlyImportError("Failed to open LWS file ", pFile, ".");
}
// Allocate storage and copy the contents of the file to a memory buffer

View File

@ -160,21 +160,21 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys
// Read file into memory
std::unique_ptr<IOStream> pStream(pIOHandler->Open(file, "rb"));
if (!pStream.get()) {
throw DeadlyImportError("Failed to open file " + file + ".");
throw DeadlyImportError("Failed to open file ", file, ".");
}
// Get the file-size and validate it, throwing an exception when fails
size_t fileSize = pStream->FileSize();
if (fileSize < 8) {
throw DeadlyImportError("M3D-file " + file + " is too small.");
throw DeadlyImportError("M3D-file ", file, " is too small.");
}
std::vector<unsigned char> buffer(fileSize);
if (fileSize != pStream->Read(buffer.data(), 1, fileSize)) {
throw DeadlyImportError("Failed to read the file " + file + ".");
throw DeadlyImportError("Failed to read the file ", file, ".");
}
// extra check for binary format's first 8 bytes. Not done for the ASCII variant
if (!memcmp(buffer.data(), "3DMO", 4) && memcmp(buffer.data() + 4, &fileSize, 4)) {
throw DeadlyImportError("Bad binary header in file " + file + ".");
throw DeadlyImportError("Bad binary header in file ", file, ".");
}
#ifdef M3D_ASCII
// make sure there's a terminator zero character, as input must be ASCIIZ
@ -200,7 +200,7 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys
M3DWrapper m3d(pIOHandler, buffer);
if (!m3d) {
throw DeadlyImportError("Unable to parse " + file + " as M3D.");
throw DeadlyImportError("Unable to parse ", file, " as M3D.");
}
// create the root node

File diff suppressed because it is too large Load Diff

View File

@ -222,7 +222,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MD2 file " + pFile + "");
throw DeadlyImportError("Failed to open MD2 file ", pFile, "");
}
// check whether the md3 file is large enough to contain

View File

@ -715,7 +715,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MD3 file " + pFile + ".");
throw DeadlyImportError("Failed to open MD3 file ", pFile, ".");
}
// Check whether the md3 file is large enough to contain the header

View File

@ -675,7 +675,7 @@ void MD5Importer::LoadMD5CameraFile() {
// Check whether we can read from the file
if (!file.get() || !file->FileSize()) {
throw DeadlyImportError("Failed to read MD5CAMERA file: " + pFile);
throw DeadlyImportError("Failed to read MD5CAMERA file: ", pFile);
}
mHadMD5Camera = true;
LoadFileIntoMemory(file.get());

View File

@ -219,7 +219,7 @@ void MDCImporter::InternReadFile(
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDC file " + pFile + ".");
throw DeadlyImportError("Failed to open MDC file ", pFile, ".");
}
// check whether the mdc file is large enough to contain the file header

View File

@ -68,9 +68,9 @@ namespace Assimp {
namespace MDL {
namespace HalfLife {
#ifdef _WIN32
# pragma warning(disable : 4706)
#endif // _WIN32
#ifdef _MSC_VER
# pragma warning(disable : 4706)
#endif // _MSC_VER
// ------------------------------------------------------------------------------------------------
HL1MDLLoader::HL1MDLLoader(

View File

@ -218,12 +218,12 @@ private:
template <typename MDLFileHeader>
void HL1MDLLoader::load_file_into_buffer(const std::string &file_path, unsigned char *&buffer) {
if (!io_->Exists(file_path))
throw DeadlyImportError("Missing file " + DefaultIOSystem::fileName(file_path) + ".");
throw DeadlyImportError("Missing file ", DefaultIOSystem::fileName(file_path), ".");
std::unique_ptr<IOStream> file(io_->Open(file_path));
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDL file " + DefaultIOSystem::fileName(file_path) + ".");
throw DeadlyImportError("Failed to open MDL file ", DefaultIOSystem::fileName(file_path), ".");
}
const size_t file_size = file->FileSize();

View File

@ -167,7 +167,7 @@ void MDLImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDL file " + pFile + ".");
throw DeadlyImportError("Failed to open MDL file ", pFile, ".");
}
// This should work for all other types of MDL files, too ...
@ -251,8 +251,8 @@ void MDLImporter::InternReadFile(const std::string &pFile,
}
} else {
// print the magic word to the log file
throw DeadlyImportError("Unknown MDL subformat " + pFile +
". Magic word (" + std::string((char *)&iMagicWord, 4) + ") is not known");
throw DeadlyImportError("Unknown MDL subformat ", pFile,
". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known");
}
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system

View File

@ -111,7 +111,7 @@ void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
// Read file by istream
std::filebuf fb;
if (!fb.open(file, std::ios::in | std::ios::binary)) {
throw DeadlyImportError("Failed to open file " + file + ".");
throw DeadlyImportError("Failed to open file ", file, ".");
}
std::istream fileStream(&fb);
@ -122,7 +122,7 @@ void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
fileStream.seekg(0, fileStream.beg);
if (fileSize < sizeof(pmx::PmxModel)) {
throw DeadlyImportError(file + " is too small.");
throw DeadlyImportError(file, " is too small.");
}
pmx::PmxModel model;

View File

@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MMDPmxParser.h"
#include <assimp/StringUtils.h>
#ifdef ASSIMP_USE_HUNTER
# include <utf8/utf8.h>
# include <utf8.h>
#else
# include "../contrib/utf8cpp/source/utf8.h"
#endif
@ -524,7 +524,7 @@ namespace pmx
if (version != 2.0f && version != 2.1f)
{
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);

View File

@ -229,7 +229,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream.CopyAndAdvance(head,10);
stream >> version;
if (strncmp(head,"MS3D000000",10)) {
throw DeadlyImportError("Not a MS3D file, magic string MS3D000000 not found: "+pFile);
throw DeadlyImportError("Not a MS3D file, magic string MS3D000000 not found: ", pFile);
}
if (version != 4) {

View File

@ -96,7 +96,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
#define AI_NFF_PARSE_FLOAT(f) \
SkipSpaces(&sz); \
if (!::IsLineEnd(*sz)) sz = fast_atoreal_move<float>(sz, (float &)f);
if (!::IsLineEnd(*sz)) sz = fast_atoreal_move<ai_real>(sz, (ai_real &)f);
// ------------------------------------------------------------------------------------------------
#define AI_NFF_PARSE_TRIPLE(v) \
@ -214,7 +214,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (!file.get())
throw DeadlyImportError("Failed to open NFF file " + pFile + ".");
throw DeadlyImportError("Failed to open NFF file ", pFile, ".");
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
@ -233,7 +233,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// camera parameters
aiVector3D camPos, camUp(0.f, 1.f, 0.f), camLookAt(0.f, 0.f, 1.f);
float angle = 45.f;
ai_real angle = 45.f;
aiVector2D resolution;
bool hasCam = false;
@ -262,7 +262,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// check whether this is the NFF2 file format
if (TokenMatch(buffer, "nff", 3)) {
const float qnan = get_qnan();
const ai_real qnan = get_qnan();
const aiColor4D cQNAN = aiColor4D(qnan, 0.f, 0.f, 1.f);
const aiVector3D vQNAN = aiVector3D(qnan, 0.f, 0.f);
@ -706,7 +706,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
}
// 'f' - shading information block
else if (TokenMatch(sz, "f", 1)) {
float d;
ai_real d;
// read the RGB colors
AI_NFF_PARSE_TRIPLE(s.color);
@ -856,7 +856,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// read the two center points and the respective radii
aiVector3D center1, center2;
float radius1 = 0.f, radius2 = 0.f;
ai_real radius1 = 0.f, radius2 = 0.f;
AI_NFF_PARSE_TRIPLE(center1);
AI_NFF_PARSE_FLOAT(radius1);
@ -874,7 +874,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
curMesh.dir = center2 - center1;
curMesh.center = center1 + curMesh.dir / (ai_real)2.0;
float f;
ai_real f;
if ((f = curMesh.dir.Length()) < 10e-3f) {
ASSIMP_LOG_ERROR("NFF: Cone height is close to zero");
continue;

View File

@ -113,14 +113,14 @@ private:
{}
aiColor3D color,diffuse,specular,ambient,emissive;
float refracti;
ai_real refracti;
std::string texFile;
// For NFF2
bool twoSided;
bool shaded;
float opacity, shininess;
ai_real opacity, shininess;
std::string name;
@ -155,7 +155,7 @@ private:
{}
aiVector3D position;
float intensity;
ai_real intensity;
aiColor3D color;
};

View File

@ -123,7 +123,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// Check whether we can read from the file
if( file.get() == nullptr) {
throw DeadlyImportError( "Failed to open OFF file " + pFile + ".");
throw DeadlyImportError( "Failed to open OFF file ", pFile, ".");
}
// allocate storage and copy the contents of the file to a memory buffer

View File

@ -109,9 +109,12 @@ const aiImporterDesc *ObjFileImporter::GetInfo() const {
void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) {
// Read file into memory
static const std::string mode = "rb";
std::unique_ptr<IOStream> fileStream(pIOHandler->Open(file, mode));
auto streamCloser = [&](IOStream *pStream) {
pIOHandler->Close(pStream);
};
std::unique_ptr<IOStream, decltype(streamCloser)> fileStream(pIOHandler->Open(file, mode), streamCloser);
if (!fileStream.get()) {
throw DeadlyImportError("Failed to open file " + file + ".");
throw DeadlyImportError("Failed to open file ", file, ".");
}
// Get the file-size and validate it, throwing an exception when fails

View File

@ -187,8 +187,8 @@ Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream) {
/// @todo Check what we can actually support.
std::string version = serializer.ReadLine();
if (version != MESH_VERSION_1_8) {
throw DeadlyExportError(Formatter::format() << "Mesh version " << version << " not supported by this importer. Run OgreMeshUpgrader tool on the file and try again."
<< " Supported versions: " << MESH_VERSION_1_8);
throw DeadlyExportError("Mesh version ", version, " not supported by this importer. Run OgreMeshUpgrader tool on the file and try again.",
" Supported versions: ", MESH_VERSION_1_8);
}
Mesh *mesh = new Mesh();
@ -471,7 +471,7 @@ void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh) {
uint16_t submeshIndex = Read<uint16_t>();
SubMesh *submesh = mesh->GetSubMesh(submeshIndex);
if (!submesh) {
throw DeadlyImportError(Formatter::format() << "Ogre Mesh does not include submesh " << submeshIndex << " referenced in M_SUBMESH_NAME_TABLE_ELEMENT. Invalid mesh file.");
throw DeadlyImportError("Ogre Mesh does not include submesh ", submeshIndex, " referenced in M_SUBMESH_NAME_TABLE_ELEMENT. Invalid mesh file.");
}
submesh->name = ReadLine();
@ -788,7 +788,7 @@ MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHand
IOStream *f = pIOHandler->Open(filename, "rb");
if (!f) {
throw DeadlyImportError("Failed to open skeleton file " + filename);
throw DeadlyImportError("Failed to open skeleton file ", filename);
}
return MemoryStreamReaderPtr(new MemoryStreamReader(f));
@ -803,8 +803,8 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton) {
// This deserialization supports both versions of the skeleton spec
std::string version = ReadLine();
if (version != SKELETON_VERSION_1_8 && version != SKELETON_VERSION_1_1) {
throw DeadlyExportError(Formatter::format() << "Skeleton version " << version << " not supported by this importer."
<< " Supported versions: " << SKELETON_VERSION_1_8 << " and " << SKELETON_VERSION_1_1);
throw DeadlyExportError("Skeleton version ", version, " not supported by this importer.",
" Supported versions: ", SKELETON_VERSION_1_8, " and ", SKELETON_VERSION_1_1);
}
ASSIMP_LOG_VERBOSE_DEBUG("Reading Skeleton");
@ -871,7 +871,7 @@ void OgreBinarySerializer::ReadBone(Skeleton *skeleton) {
// Bone indexes need to start from 0 and be contiguous
if (bone->id != skeleton->bones.size()) {
throw DeadlyImportError(Formatter::format() << "Ogre Skeleton bone indexes not contiguous. Error at bone index " << bone->id);
throw DeadlyImportError("Ogre Skeleton bone indexes not contiguous. Error at bone index ", bone->id);
}
ASSIMP_LOG_VERBOSE_DEBUG_F(" ", bone->id, " ", bone->name);
@ -889,7 +889,7 @@ void OgreBinarySerializer::ReadBoneParent(Skeleton *skeleton) {
if (child && parent)
parent->AddChild(child);
else
throw DeadlyImportError(Formatter::format() << "Failed to find bones for parenting: Child id " << childId << " for parent id " << parentId);
throw DeadlyImportError("Failed to find bones for parenting: Child id ", childId, " for parent id ", parentId);
}
void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton) {
@ -926,7 +926,7 @@ void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, A
uint16_t boneId = Read<uint16_t>();
Bone *bone = dest->parentSkeleton->BoneById(boneId);
if (!bone) {
throw DeadlyImportError(Formatter::format() << "Cannot read animation track, target bone " << boneId << " not in target Skeleton");
throw DeadlyImportError("Cannot read animation track, target bone ", boneId, " not in target Skeleton");
}
VertexAnimationTrack track;

View File

@ -91,7 +91,7 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
// Open source file
IOStream *f = pIOHandler->Open(pFile, "rb");
if (!f) {
throw DeadlyImportError("Failed to open file " + pFile);
throw DeadlyImportError("Failed to open file ", pFile);
}
// Binary .mesh import

View File

@ -476,7 +476,7 @@ void SubMesh::Reset(){
aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent) {
if (operationType != OT_TRIANGLE_LIST) {
throw DeadlyImportError(Formatter::format() << "Only mesh operation type OT_TRIANGLE_LIST is supported. Found " << operationType);
throw DeadlyImportError("Only mesh operation type OT_TRIANGLE_LIST is supported. Found ", operationType);
}
aiMesh *dest = new aiMesh();
@ -944,7 +944,7 @@ void Bone::AddChild(Bone *bone) {
if (!bone)
return;
if (bone->IsParented())
throw DeadlyImportError("Attaching child Bone that is already parented: " + bone->name);
throw DeadlyImportError("Attaching child Bone that is already parented: ", bone->name);
bone->parent = this;
bone->parentId = id;
@ -963,7 +963,7 @@ void Bone::CalculateWorldMatrixAndDefaultPose(Skeleton *skeleton) {
for (auto boneId : children) {
Bone *child = skeleton->BoneById(boneId);
if (!child) {
throw DeadlyImportError(Formatter::format() << "CalculateWorldMatrixAndDefaultPose: Failed to find child bone " << boneId << " for parent " << id << " " << name);
throw DeadlyImportError("CalculateWorldMatrixAndDefaultPose: Failed to find child bone ", boneId, " for parent ", id, " ", name);
}
child->CalculateWorldMatrixAndDefaultPose(skeleton);
}
@ -983,7 +983,7 @@ aiNode *Bone::ConvertToAssimpNode(Skeleton *skeleton, aiNode *parentNode) {
for (size_t i = 0, len = children.size(); i < len; ++i) {
Bone *child = skeleton->BoneById(children[i]);
if (!child) {
throw DeadlyImportError(Formatter::format() << "ConvertToAssimpNode: Failed to find child bone " << children[i] << " for parent " << id << " " << name);
throw DeadlyImportError("ConvertToAssimpNode: Failed to find child bone ", children[i], " for parent ", id, " ", name);
}
node->mChildren[i] = child->ConvertToAssimpNode(skeleton, node);
}
@ -1022,7 +1022,7 @@ aiNodeAnim *VertexAnimationTrack::ConvertToAssimpAnimationNode(Skeleton *skeleto
Bone *bone = skeleton->BoneByName(boneName);
if (!bone) {
throw DeadlyImportError("VertexAnimationTrack::ConvertToAssimpAnimationNode: Failed to find bone " + boneName + " from parent Skeleton");
throw DeadlyImportError("VertexAnimationTrack::ConvertToAssimpAnimationNode: Failed to find bone ", boneName, " from parent Skeleton");
}
// Keyframes

View File

@ -60,9 +60,9 @@ namespace Ogre {
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) {
if (!error.empty()) {
throw DeadlyImportError(error + " in node '" + nodeName + "' and attribute '" + name + "'");
throw DeadlyImportError(error, " in node '", nodeName, "' and attribute '", name, "'");
} else {
throw DeadlyImportError("Attribute '" + name + "' does not exist in node '" + nodeName + "'");
throw DeadlyImportError("Attribute '", name, "' does not exist in node '", nodeName, "'");
}
}
@ -321,18 +321,18 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(XmlNode &node, VertexDataXml *d
// Sanity checks
if (dest->positions.size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->positions.size() << " positions when should have read " << dest->count);
throw DeadlyImportError("Read only ", dest->positions.size(), " positions when should have read ", dest->count);
}
if (normals && dest->normals.size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->normals.size() << " normals when should have read " << dest->count);
throw DeadlyImportError("Read only ", dest->normals.size(), " normals when should have read ", dest->count);
}
if (tangents && dest->tangents.size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->tangents.size() << " tangents when should have read " << dest->count);
throw DeadlyImportError("Read only ", dest->tangents.size(), " tangents when should have read ", dest->count);
}
for (unsigned int i = 0; i < dest->uvs.size(); ++i) {
if (dest->uvs[i].size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->uvs[i].size()
<< " uvs for uv index " << i << " when should have read " << dest->count);
throw DeadlyImportError("Read only ", dest->uvs[i].size(),
" uvs for uv index ", i, " when should have read ", dest->count);
}
}
}
@ -389,7 +389,7 @@ void OgreXmlSerializer::ReadSubMesh(XmlNode &node, MeshXml *mesh) {
if (submesh->indexData->faces.size() == submesh->indexData->faceCount) {
ASSIMP_LOG_VERBOSE_DEBUG_F(" - Faces ", submesh->indexData->faceCount);
} else {
throw DeadlyImportError(Formatter::format() << "Read only " << submesh->indexData->faces.size() << " faces when should have read " << submesh->indexData->faceCount);
throw DeadlyImportError("Read only ", submesh->indexData->faces.size(), " faces when should have read ", submesh->indexData->faceCount);
}
} else if (currentName == nnGeometry) {
if (submesh->usesSharedVertexData) {
@ -515,7 +515,7 @@ XmlParserPtr OgreXmlSerializer::OpenXmlParser(Assimp::IOSystem *pIOHandler, cons
std::unique_ptr<IOStream> file(pIOHandler->Open(filename));
if (!file.get()) {
throw DeadlyImportError("Failed to open skeleton file " + filename);
throw DeadlyImportError("Failed to open skeleton file ", filename);
}
XmlParserPtr xmlParser = XmlParserPtr(new XmlParser);
@ -568,7 +568,7 @@ void OgreXmlSerializer::ReadAnimations(XmlNode &node, Skeleton *skeleton) {
ReadAnimationTracks(currentChildNode, anim);
skeleton->animations.push_back(anim);
} else {
throw DeadlyImportError(Formatter::format() << "No <tracks> found in <animation> " << anim->name);
throw DeadlyImportError( "No <tracks> found in <animation> ", anim->name);
}
}
}
@ -588,7 +588,7 @@ void OgreXmlSerializer::ReadAnimationTracks(XmlNode &node, Animation *dest) {
ReadAnimationKeyFrames(currentChildNode, dest, &track);
dest->tracks.push_back(track);
} else {
throw DeadlyImportError(Formatter::format() << "No <keyframes> found in <track> " << dest->name);
throw DeadlyImportError( "No <keyframes> found in <track> ", dest->name);
}
}
@ -657,7 +657,7 @@ void OgreXmlSerializer::ReadBoneHierarchy(XmlNode &node, Skeleton *skeleton) {
if (bone && parent) {
parent->AddChild(bone);
} else {
throw DeadlyImportError("Failed to find bones for parenting: Child " + name + " for parent " + parentName);
throw DeadlyImportError("Failed to find bones for parenting: Child ", name, " for parent ", parentName);
}
}
}
@ -704,7 +704,7 @@ void OgreXmlSerializer::ReadBones(XmlNode &node, Skeleton *skeleton) {
bone->rotation = aiQuaternion(axis, angle);
} else {
throw DeadlyImportError(Formatter::format() << "No axis specified for bone rotation in bone " << bone->id);
throw DeadlyImportError( "No axis specified for bone rotation in bone ", bone->id);
}
}
} else if (currentChildName == nnScale) {
@ -736,7 +736,7 @@ void OgreXmlSerializer::ReadBones(XmlNode &node, Skeleton *skeleton) {
ASSIMP_LOG_VERBOSE_DEBUG_F(" ", b->id, " ", b->name);
if (b->id != static_cast<uint16_t>(i)) {
throw DeadlyImportError(Formatter::format() << "Bone ids are not in sequence starting from 0. Missing index " << i);
throw DeadlyImportError("Bone ids are not in sequence starting from 0. Missing index ", i);
}
}
}

View File

@ -302,7 +302,7 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce
// open source file
IOStream *file = pIOHandler->Open( filename, "rb" );
if( !file ) {
throw DeadlyImportError( "Failed to open file " + filename );
throw DeadlyImportError( "Failed to open file ", filename );
}
std::vector<char> buffer;

View File

@ -151,13 +151,13 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
const std::string mode = "rb";
std::unique_ptr<IOStream> fileStream(pIOHandler->Open(pFile, mode));
if (!fileStream.get()) {
throw DeadlyImportError("Failed to open file " + pFile + ".");
throw DeadlyImportError("Failed to open file ", pFile, ".");
}
// Get the file-size
const size_t fileSize(fileStream->FileSize());
if (0 == fileSize) {
throw DeadlyImportError("File " + pFile + " is empty.");
throw DeadlyImportError("File ", pFile, " is empty.");
}
IOStreamBuffer<char> streamedBuffer(1024 * 1024);

View File

@ -180,7 +180,7 @@ const aiImporterDesc *Q3BSPFileImporter::GetInfo() const {
void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene, IOSystem *ioHandler) {
ZipArchiveIOSystem Archive(ioHandler, rFile);
if (!Archive.isOpen()) {
throw DeadlyImportError("Failed to open file " + rFile + ".");
throw DeadlyImportError("Failed to open file ", rFile, ".");
}
std::string archiveName(""), mapName("");

View File

@ -110,13 +110,12 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
// The header is 22 bytes large
if (stream.GetRemainingSize() < 22)
throw DeadlyImportError("File is either empty or corrupt: " + pFile);
throw DeadlyImportError("File is either empty or corrupt: ", pFile);
// Check the file's signature
if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) &&
ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) {
throw DeadlyImportError("Not a Quick3D file. Signature string is: " +
std::string((const char *)stream.GetPtr(), 8));
throw DeadlyImportError("Not a Quick3D file. Signature string is: ", std::string((const char *)stream.GetPtr(), 8));
}
// Print the file format version

View File

@ -101,7 +101,7 @@ void RAWImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open RAW file " + pFile + ".");
throw DeadlyImportError("Failed to open RAW file ", pFile, ".");
}
// allocate storage and copy the contents of the file to a memory buffer

View File

@ -59,7 +59,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StreamReader.h>
#include <assimp/TinyFormatter.h>
#ifdef ASSIMP_USE_HUNTER
#include <utf8/utf8.h>
#include <utf8.h>
#else
//# include "../contrib/ConvertUTF/ConvertUTF.h"
#include "../contrib/utf8cpp/source/utf8.h"
@ -808,7 +808,7 @@ void SIBImporter::InternReadFile(const std::string &pFile,
// We should have at least one chunk
if (stream.GetRemainingSize() < 16)
throw DeadlyImportError("SIB file is either empty or corrupt: " + pFile);
throw DeadlyImportError("SIB file is either empty or corrupt: ", pFile);
SIB sib;

View File

@ -695,7 +695,7 @@ void SMDImporter::ReadSmd(const std::string &pFile, IOSystem* pIOHandler) {
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open SMD/VTA file " + pFile + ".");
throw DeadlyImportError("Failed to open SMD/VTA file ", pFile, ".");
}
iFileSize = (unsigned int)file->FileSize();

View File

@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "STEPFileEncoding.h"
#include <assimp/fast_atof.h>
#ifdef ASSIMP_USE_HUNTER
# include <utf8/utf8.h>
# include <utf8.h>
#else
# include <contrib/utf8cpp/source/utf8.h>
#endif

View File

@ -181,7 +181,7 @@ void STLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open STL file " + pFile + ".");
throw DeadlyImportError("Failed to open STL file ", pFile, ".");
}
mFileSize = (unsigned int)file->FileSize();
@ -207,7 +207,7 @@ void STLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
} else if (IsAsciiSTL(mBuffer, mFileSize)) {
LoadASCIIFile(mScene->mRootNode);
} else {
throw DeadlyImportError("Failed to determine STL storage representation for " + pFile + ".");
throw DeadlyImportError("Failed to determine STL storage representation for ", pFile, ".");
}
// create a single default material, using a white diffuse color for consistency with

View File

@ -54,10 +54,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp>
#ifdef _WIN32
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable : 4127 4456 4245 4512 )
#endif // _WIN32
#endif // _MSC_VER
//
#if _MSC_VER > 1500 || (defined __GNUC___)
@ -130,8 +130,8 @@ namespace STEP {
* coupled with a line number. */
// -------------------------------------------------------------------------------
struct SyntaxError : DeadlyImportError {
enum {
LINE_NOT_SPECIFIED = 0xffffffffffffffffLL
enum : uint64_t {
LINE_NOT_SPECIFIED = 0xfffffffffffffffLL
};
SyntaxError(const std::string &s, uint64_t line = LINE_NOT_SPECIFIED);
@ -143,8 +143,8 @@ struct SyntaxError : DeadlyImportError {
* It is typically coupled with both an entity id and a line number.*/
// -------------------------------------------------------------------------------
struct TypeError : DeadlyImportError {
enum {
ENTITY_NOT_SPECIFIED = 0xffffffffffffffffLL,
enum : uint64_t {
ENTITY_NOT_SPECIFIED = 0xffffffffffffffffUL,
ENTITY_NOT_SPECIFIED_32 = 0x00000000ffffffff
};
@ -727,7 +727,7 @@ struct InternGenericConvert<Maybe<T>> {
}
};
#ifdef _WIN32
#if _MSC_VER > 1920
#pragma warning(push)
#pragma warning(disable : 4127)
#endif // _WIN32
@ -960,9 +960,9 @@ private:
const EXPRESS::ConversionSchema *schema;
};
#ifdef _WIN32
#ifdef _MSC_VER
#pragma warning(pop)
#endif // _WIN32
#endif // _MSC_VER
} // namespace STEP

View File

@ -121,7 +121,7 @@ void TerragenImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file == nullptr)
throw DeadlyImportError("Failed to open TERRAGEN TERRAIN file " + pFile + ".");
throw DeadlyImportError("Failed to open TERRAGEN TERRAIN file ", pFile, ".");
// Construct a stream reader to read all data in the correct endianness
StreamReaderLE reader(file);

View File

@ -114,7 +114,7 @@ void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, I
// read file into memory
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
if ( file.get() == nullptr ) {
throw DeadlyImportError( "Failed to open file " + pFile + "." );
throw DeadlyImportError( "Failed to open file ", pFile, "." );
}
static const size_t MinSize = 16;

View File

@ -82,6 +82,17 @@ static void dummy_free(void * /*opaque*/, void *address) {
#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
// ------------------------------------------------------------------------------------------------
// Throws an exception with a line number and the given text.
template<typename... T>
AI_WONT_RETURN void XFileParser::ThrowException(T&&... args) {
if (mIsBinaryFormat) {
throw DeadlyImportError(args...);
} else {
throw DeadlyImportError("Line ", mLineNumber, ": ", args...);
}
}
// ------------------------------------------------------------------------------------------------
// Constructor. Creates a data structure out of the XFile given in the memory block.
XFileParser::XFileParser(const std::vector<char> &pBuffer) :
@ -122,13 +133,13 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
mIsBinaryFormat = true;
compressed = true;
} else
ThrowException(format() << "Unsupported xfile format '" << mP[8] << mP[9] << mP[10] << mP[11] << "'");
ThrowException("Unsupported xfile format '", mP[8], mP[9], mP[10], mP[11], "'");
// float size
mBinaryFloatSize = (unsigned int)(mP[12] - 48) * 1000 + (unsigned int)(mP[13] - 48) * 100 + (unsigned int)(mP[14] - 48) * 10 + (unsigned int)(mP[15] - 48);
if (mBinaryFloatSize != 32 && mBinaryFloatSize != 64)
ThrowException(format() << "Unknown float size " << mBinaryFloatSize << " specified in xfile header.");
ThrowException("Unknown float size ", mBinaryFloatSize, " specified in xfile header.");
// The x format specifies size in bits, but we work in bytes
mBinaryFloatSize /= 8;
@ -864,7 +875,7 @@ void XFileParser::ParseDataObjectAnimationKey(AnimBone *pAnimBone) {
}
default:
ThrowException(format() << "Unknown key type " << keyType << " in animation.");
ThrowException("Unknown key type ", keyType, " in animation.");
break;
} // end switch
@ -1355,16 +1366,6 @@ aiColor3D XFileParser::ReadRGB() {
return color;
}
// ------------------------------------------------------------------------------------------------
// Throws an exception with a line number and the given text.
AI_WONT_RETURN void XFileParser::ThrowException(const std::string &pText) {
if (mIsBinaryFormat) {
throw DeadlyImportError(pText);
} else {
throw DeadlyImportError(format() << "Line " << mLineNumber << ": " << pText);
}
}
// ------------------------------------------------------------------------------------------------
// Filters the imported hierarchy for some degenerated cases that some exporters produce.
void XFileParser::FilterHierarchy(XFile::Node *pNode) {

View File

@ -133,7 +133,8 @@ protected:
aiColor4D ReadRGBA();
/** Throws an exception with a line number and the given text. */
AI_WONT_RETURN void ThrowException( const std::string& pText) AI_WONT_RETURN_SUFFIX;
template<typename... T>
AI_WONT_RETURN void ThrowException(T&&... args) AI_WONT_RETURN_SUFFIX;
/**
* @brief Filters the imported hierarchy for some degenerated cases that some exporters produce.

View File

@ -155,99 +155,37 @@ void X3DImporter::ParseFile(const std::string &file, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> fileStream(pIOHandler->Open(file, mode));
if (!fileStream.get()) {
throw DeadlyImportError("Failed to open file " + file + ".");
}
}
}
/*********************************************************************************************************************************************/
/************************************************************ Functions: find set ************************************************************/
/*********************************************************************************************************************************************/
bool X3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const {
const std::string extension = GetExtension(pFile);
if ((extension == "x3d") || (extension == "x3db")) {
return true;
}
if (!extension.length() || pCheckSig) {
const char *tokens[] = { "DOCTYPE X3D PUBLIC", "http://www.web3d.org/specifications/x3d" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 2);
bool X3DImporter::CanRead( const std::string &pFile, IOSystem * /*pIOHandler*/, bool checkSig ) const {
if (checkSig) {
std::string::size_type pos = pFile.find_last_of(".x3d");
if (pos != std::string::npos) {
return true;
}
}
return false;
}
void X3DImporter::GetExtensionList(std::set<std::string> &pExtensionList) {
pExtensionList.insert("x3d");
pExtensionList.insert("x3db");
void X3DImporter::GetExtensionList( std::set<std::string> &extensionList ) {
extensionList.insert("x3d");
}
void X3DImporter::InternReadFile( const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler ) {
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
if (!stream) {
throw DeadlyImportError("Could not open file for reading");
}
pScene->mRootNode = new aiNode(pFile);
}
const aiImporterDesc *X3DImporter::GetInfo() const {
return &Description;
}
void X3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
mpIOHandler = pIOHandler;
Clear(); // delete old graph.
std::string::size_type slashPos = pFile.find_last_of("\\/");
pIOHandler->PushDirectory(slashPos == std::string::npos ? std::string() : pFile.substr(0, slashPos + 1));
ParseFile(pFile, pIOHandler);
pIOHandler->PopDirectory();
if (NodeElement_List.empty())
return;
//
// Assimp use static arrays of objects for fast speed of rendering. That's good, but need some additional operations/
// We know that geometry objects(meshes) are stored in <Shape>, also in <Shape>-><Appearance> materials(in Assimp logical view)
// are stored. So at first we need to count how meshes and materials are stored in scene graph.
//
// at first creating root node for aiScene.
pScene->mRootNode = new aiNode;
pScene->mRootNode->mParent = nullptr;
pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
//search for root node element
mNodeElementCur = NodeElement_List.front();
while (mNodeElementCur->Parent != nullptr)
mNodeElementCur = mNodeElementCur->Parent;
{ // fill aiScene with objects.
std::list<aiMesh *> mesh_list;
std::list<aiMaterial *> mat_list;
std::list<aiLight *> light_list;
// create nodes tree
// Postprocess_BuildNode(*mNodeElementCur, *pScene->mRootNode, mesh_list, mat_list, light_list);
// copy needed data to scene
if (!mesh_list.empty()) {
std::list<aiMesh *>::const_iterator it = mesh_list.begin();
pScene->mNumMeshes = static_cast<unsigned int>(mesh_list.size());
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
for (size_t i = 0; i < pScene->mNumMeshes; i++)
pScene->mMeshes[i] = *it++;
}
if (!mat_list.empty()) {
std::list<aiMaterial *>::const_iterator it = mat_list.begin();
pScene->mNumMaterials = static_cast<unsigned int>(mat_list.size());
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
for (size_t i = 0; i < pScene->mNumMaterials; i++)
pScene->mMaterials[i] = *it++;
}
if (!light_list.empty()) {
std::list<aiLight *>::const_iterator it = light_list.begin();
pScene->mNumLights = static_cast<unsigned int>(light_list.size());
pScene->mLights = new aiLight *[pScene->mNumLights];
for (size_t i = 0; i < pScene->mNumLights; i++)
pScene->mLights[i] = *it++;
}
}
}
} // namespace Assimp
}
#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER

View File

@ -1,4 +1,4 @@
/*
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GLTFASSET_H_INC
#define GLTFASSET_H_INC
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
#include <assimp/Exceptional.h>
@ -60,19 +60,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm>
#include <stdexcept>
#ifndef RAPIDJSON_HAS_STDSTRING
#define RAPIDJSON_HAS_STDSTRING 1
#endif
#if (__GNUC__ == 8 && __GNUC_MINOR__ >= 0)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
#define RAPIDJSON_NOMEMBERITERATORCLASS
#endif
#include <rapidjson/rapidjson.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>

View File

@ -57,10 +57,10 @@ namespace glTF {
namespace {
#ifdef _WIN32
#if _MSC_VER
# pragma warning(push)
# pragma warning(disable : 4706)
#endif // _WIN32
#endif // _MSC_VER
//
// JSON Value reading helpers
@ -235,15 +235,15 @@ Ref<T> LazyDict<T>::Get(const char *id) {
// read it from the JSON object
if (!mDict) {
throw DeadlyImportError("GLTF: Missing section \"" + std::string(mDictId) + "\"");
throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
}
Value::MemberIterator obj = mDict->FindMember(id);
if (obj == mDict->MemberEnd()) {
throw DeadlyImportError("GLTF: Missing object with id \"" + std::string(id) + "\" in \"" + mDictId + "\"");
throw DeadlyImportError("GLTF: Missing object with id \"", id, "\" in \"", mDictId, "\"");
}
if (!obj->value.IsObject()) {
throw DeadlyImportError("GLTF: Object with id \"" + std::string(id) + "\" is not a JSON object");
throw DeadlyImportError("GLTF: Object with id \"", id, "\" is not a JSON object");
}
// create an instance of the given type
@ -317,13 +317,13 @@ inline void Buffer::Read(Value &obj, Asset &r) {
this->mData.reset(data, std::default_delete<uint8_t[]>());
if (statedLength > 0 && this->byteLength != statedLength) {
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
" bytes, but found " + to_string(dataURI.dataLength));
throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", to_string(statedLength),
" bytes, but found ", to_string(dataURI.dataLength));
}
} else { // assume raw data
if (statedLength != dataURI.dataLength) {
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
" bytes, but found " + to_string(dataURI.dataLength));
throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", to_string(statedLength),
" bytes, but found ", to_string(dataURI.dataLength));
}
this->mData.reset(new uint8_t[dataURI.dataLength], std::default_delete<uint8_t[]>());
@ -339,9 +339,9 @@ inline void Buffer::Read(Value &obj, Asset &r) {
delete file;
if (!ok)
throw DeadlyImportError("GLTF: error while reading referenced file \"" + std::string(uri) + "\"");
throw DeadlyImportError("GLTF: error while reading referenced file \"", uri, "\"");
} else {
throw DeadlyImportError("GLTF: could not open referenced file \"" + std::string(uri) + "\"");
throw DeadlyImportError("GLTF: could not open referenced file \"", uri, "\"");
}
}
}
@ -372,8 +372,8 @@ inline void Buffer::EncodedRegion_Mark(const size_t pOffset, const size_t pEncod
char val[val_size];
ai_snprintf(val, val_size, "%llu", (long long)pOffset);
throw DeadlyImportError(std::string("GLTF: incorrect offset value (") + val + ") for marking encoded region.");
ai_snprintf(val, val_size, AI_SIZEFMT, pOffset);
throw DeadlyImportError("GLTF: incorrect offset value (", val, ") for marking encoded region.");
}
// Check length
@ -382,8 +382,8 @@ inline void Buffer::EncodedRegion_Mark(const size_t pOffset, const size_t pEncod
char val[val_size];
ai_snprintf(val, val_size, "%llu, %llu", (long long)pOffset, (long long)pEncodedData_Length);
throw DeadlyImportError(std::string("GLTF: encoded region with offset/length (") + val + ") is out of range.");
ai_snprintf(val, val_size, AI_SIZEFMT "/" AI_SIZEFMT, pOffset, pEncodedData_Length);
throw DeadlyImportError("GLTF: encoded region with offset/length (", val, ") is out of range.");
}
// Add new region
@ -403,7 +403,7 @@ inline void Buffer::EncodedRegion_SetCurrent(const std::string &pID) {
}
}
throw DeadlyImportError("GLTF: EncodedRegion with ID: \"" + pID + "\" not found.");
throw DeadlyImportError("GLTF: EncodedRegion with ID: \"", pID, "\" not found.");
}
inline bool Buffer::ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t *pReplace_Data, const size_t pReplace_Count) {
@ -836,8 +836,8 @@ inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
if (json_extensions == nullptr) goto mr_skip_extensions;
for (Value::MemberIterator it_memb = json_extensions->MemberBegin(); it_memb != json_extensions->MemberEnd(); it_memb++) {
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
for (Value::MemberIterator it_memb = json_extensions->MemberBegin(); it_memb != json_extensions->MemberEnd(); it_memb++) {
if (it_memb->name.GetString() == std::string("Open3DGC-compression")) {
// Search for compressed data.
// Compressed data contain description of part of "buffer" which is encoded. This part must be decoded and
@ -851,7 +851,7 @@ inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
/************** Read data from JSON-document **************/
#define MESH_READ_COMPRESSEDDATA_MEMBER(pFieldName, pOut) \
if (!ReadMember(*comp_data, pFieldName, pOut)) { \
throw DeadlyImportError(std::string("GLTF: \"compressedData\" must has \"") + pFieldName + "\"."); \
throw DeadlyImportError("GLTF: \"compressedData\" must has \"", pFieldName, "\"."); \
}
const char *mode_str;
@ -880,18 +880,18 @@ inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
else if (strcmp(mode_str, "ascii") == 0)
ext_o3dgc->Binary = false;
else
throw DeadlyImportError(std::string("GLTF: for compressed data supported modes is: \"ascii\", \"binary\". Not the: \"") + mode_str + "\".");
throw DeadlyImportError("GLTF: for compressed data supported modes is: \"ascii\", \"binary\". Not the: \"", mode_str, "\".");
/************************ Decoding ************************/
Decode_O3DGC(*ext_o3dgc, pAsset_Root);
Extension.push_back(ext_o3dgc); // store info in mesh extensions list.
} // if(it_memb->name.GetString() == "Open3DGC-compression")
else
#endif
{
throw DeadlyImportError(std::string("GLTF: Unknown mesh extension: \"") + it_memb->name.GetString() + "\".");
throw DeadlyImportError("GLTF: Unknown mesh extension: \"", it_memb->name.GetString(), "\".");
}
} // for(Value::MemberIterator it_memb = json_extensions->MemberBegin(); it_memb != json_extensions->MemberEnd(); json_extensions++)
#endif
mr_skip_extensions:
@ -923,24 +923,24 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
size_t size_coordindex = ifs.GetNCoordIndex() * 3; // See float attributes note.
if (primitives[0].indices->count != size_coordindex)
throw DeadlyImportError("GLTF: Open3DGC. Compressed indices count (" + to_string(size_coordindex) +
") not equal to uncompressed (" + to_string(primitives[0].indices->count) + ").");
throw DeadlyImportError("GLTF: Open3DGC. Compressed indices count (", to_string(size_coordindex),
") not equal to uncompressed (", to_string(primitives[0].indices->count), ").");
size_coordindex *= sizeof(IndicesType);
// Coordinates
size_t size_coord = ifs.GetNCoord(); // See float attributes note.
if (primitives[0].attributes.position[0]->count != size_coord)
throw DeadlyImportError("GLTF: Open3DGC. Compressed positions count (" + to_string(size_coord) +
") not equal to uncompressed (" + to_string(primitives[0].attributes.position[0]->count) + ").");
throw DeadlyImportError("GLTF: Open3DGC. Compressed positions count (", to_string(size_coord),
") not equal to uncompressed (", to_string(primitives[0].attributes.position[0]->count), ").");
size_coord *= 3 * sizeof(float);
// Normals
size_t size_normal = ifs.GetNNormal(); // See float attributes note.
if (primitives[0].attributes.normal[0]->count != size_normal)
throw DeadlyImportError("GLTF: Open3DGC. Compressed normals count (" + to_string(size_normal) +
") not equal to uncompressed (" + to_string(primitives[0].attributes.normal[0]->count) + ").");
throw DeadlyImportError("GLTF: Open3DGC. Compressed normals count (", to_string(size_normal),
") not equal to uncompressed (", to_string(primitives[0].attributes.normal[0]->count), ").");
size_normal *= 3 * sizeof(float);
// Additional attributes.
@ -961,8 +961,8 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
// Check situation when encoded data contain texture coordinates but primitive not.
if (idx_texcoord < primitives[0].attributes.texcoord.size()) {
if (primitives[0].attributes.texcoord[idx]->count != tval)
throw DeadlyImportError("GLTF: Open3DGC. Compressed texture coordinates count (" + to_string(tval) +
") not equal to uncompressed (" + to_string(primitives[0].attributes.texcoord[idx]->count) + ").");
throw DeadlyImportError("GLTF: Open3DGC. Compressed texture coordinates count (", to_string(tval),
") not equal to uncompressed (", to_string(primitives[0].attributes.texcoord[idx]->count), ").");
idx_texcoord++;
} else {
@ -971,7 +971,7 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
break;
default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))));
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: ", to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))));
}
tval *= ifs.GetFloatAttributeDim(static_cast<unsigned long>(idx)) * sizeof(o3dgc::Real); // After checking count of objects we can get size of array.
@ -990,7 +990,7 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
break;
default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx))));
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: ", to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx))));
}
tval *= ifs.GetIntAttributeDim(static_cast<unsigned long>(idx)) * sizeof(long); // See float attributes note.
@ -1025,7 +1025,7 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
break;
default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))));
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: ", to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))));
}
}
@ -1039,7 +1039,7 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
// ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint)));
default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx))));
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: ", to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx))));
}
}
@ -1231,7 +1231,7 @@ inline void AssetMetadata::Read(Document &doc) {
}
if (version.empty() || version[0] != '1') {
throw DeadlyImportError("GLTF: Unsupported glTF version: " + version);
throw DeadlyImportError("GLTF: Unsupported glTF version: ", version);
}
}
@ -1309,7 +1309,7 @@ inline void Asset::Load(const std::string &pFile, bool isBinary) {
if (doc.HasParseError()) {
char buffer[32];
ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
throw DeadlyImportError(std::string("GLTF: JSON parse error, offset ") + buffer + ": " + GetParseError_En(doc.GetParseError()));
throw DeadlyImportError("GLTF: JSON parse error, offset ", buffer, ": ", GetParseError_En(doc.GetParseError()));
}
if (!doc.IsObject()) {
@ -1412,8 +1412,8 @@ inline std::string Asset::FindUniqueID(const std::string &str, const char *suffi
return id;
}
#ifdef _WIN32
#if _MSC_VER
# pragma warning(pop)
#endif // WIN32
#endif // _MSC_VER
} // namespace glTF

View File

@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GLTFASSETWRITER_H_INC
#define GLTFASSETWRITER_H_INC
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
#include "glTFAsset.h"

View File

@ -43,10 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rapidjson/writer.h>
#include <rapidjson/prettywriter.h>
#ifdef _WIN32
#if _MSC_VER
# pragma warning(push)
# pragma warning( disable : 4706)
#endif // _WIN32
#endif // _MSC_VER
namespace glTF {
@ -305,11 +305,11 @@ namespace glTF {
Value json_extensions;
json_extensions.SetObject();
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
for(Mesh::SExtension* ptr_ext : m.Extension)
{
switch(ptr_ext->Type)
{
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
case Mesh::SExtension::EType::Compression_Open3DGC:
{
Value json_comp_data;
@ -339,11 +339,11 @@ namespace glTF {
}
break;
#endif
default:
throw DeadlyImportError("GLTF: Can not write mesh: unknown mesh extension, only Open3DGC is supported.");
}// switch(ptr_ext->Type)
}// for(Mesh::SExtension* ptr_ext : m.Extension)
#endif
// Add extensions to mesh
obj.AddMember("extensions", json_extensions, w.mAl);
@ -707,7 +707,7 @@ namespace glTF {
w.WriteObjects(d);
}
#ifdef _WIN32
#if _MSC_VER
# pragma warning(pop)
#endif // _WIN32

View File

@ -38,6 +38,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#include "AssetLib/glTF/glTFCommon.h"
namespace glTFCommon {
@ -187,3 +189,5 @@ bool ParseDataURI(const char *const_uri, size_t uriLen, DataURI &out) {
} // namespace Util
} // namespace glTFCommon
#endif

View File

@ -52,8 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
#define RAPIDJSON_HAS_STDSTRING 1
#define RAPIDJSON_NOMEMBERITERATORCLASS
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <rapidjson/rapidjson.h>
@ -190,10 +188,10 @@ inline void CopyValue(const glTFCommon::mat4 &v, aiMatrix4x4 &o) {
o.d4 = v[15];
}
#ifdef _WIN32
#if _MSC_VER
# pragma warning(push)
# pragma warning(disable : 4310)
#endif // _WIN32
#endif // _MSC_VER
inline std::string getCurrentAssetDir(const std::string &pFile) {
std::string path = pFile;
@ -204,9 +202,9 @@ inline std::string getCurrentAssetDir(const std::string &pFile) {
return path;
}
#ifdef _WIN32
#if _MSC_VER
# pragma warning(pop)
#endif // _WIN32
#endif // _MSC_VER
namespace Util {

View File

@ -525,6 +525,12 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buf
delete[] vertexJointData;
}
#if defined(__has_warning)
#if __has_warning("-Wunused-but-set-variable")
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif
#endif
void glTFExporter::ExportMeshes()
{
// Not for
@ -536,10 +542,12 @@ void glTFExporter::ExportMeshes()
// Variables needed for compression. BEGIN.
// Indices, not pointers - because pointer to buffer is changing while writing to it.
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
size_t idx_srcdata_begin = 0; // Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer.
size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals.
std::vector<size_t> idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer.
size_t idx_srcdata_ind;// Index of begin of coordinates indices array in buffer.
#endif
std::vector<size_t> idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer.
bool comp_allow;// Point that data of current mesh can be compressed.
// Variables needed for compression. END.
@ -609,13 +617,17 @@ void glTFExporter::ExportMeshes()
/******************* Vertices ********************/
// If compression is used then you need parameters of uncompressed region: begin and size. At this step "begin" is stored.
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
if(comp_allow) idx_srcdata_begin = b->byteLength;
#endif
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (v) p.attributes.position.push_back(v);
/******************** Normals ********************/
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
if(comp_allow && (aim->mNormals != 0)) idx_srcdata_normal = b->byteLength;// Store index of normals array.
#endif
Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (n) p.attributes.normal.push_back(n);
@ -640,7 +652,9 @@ void glTFExporter::ExportMeshes()
}
/*************** Vertices indices ****************/
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
idx_srcdata_ind = b->byteLength;// Store index of indices array.
#endif
if (aim->mNumFaces > 0) {
std::vector<IndicesType> indices;
@ -677,7 +691,7 @@ void glTFExporter::ExportMeshes()
{
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
// Only one type of compression supported at now - Open3DGC.
//
//
o3dgc::BinaryStream bs;
o3dgc::SC3DMCEncoder<IndicesType> encoder;
o3dgc::IndexedFaceSet<IndicesType> comp_o3dgc_ifs;
@ -793,6 +807,12 @@ void glTFExporter::ExportMeshes()
}
}
#if defined(__has_warning)
#if __has_warning("-Wunused-but-set-variable")
#pragma GCC diagnostic pop
#endif
#endif
/*
* Export the root node of the node hierarchy.
* Calls ExportNode for all children.

View File

@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_GLTFEXPORTER_H_INC
#define AI_GLTFEXPORTER_H_INC
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
#if !defined(ASSIMP_BUILD_NO_GLTF_EXPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_EXPORTER)
#include <assimp/types.h>
#include <assimp/material.h>

View File

@ -1,4 +1,4 @@
/*
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
#include "AssetLib/glTF/glTFImporter.h"
#include "AssetLib/glTF/glTFAsset.h"
@ -215,8 +215,8 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
// Check if mesh extensions is used
if (mesh.Extension.size() > 0) {
for (Mesh::SExtension *cur_ext : mesh.Extension) {
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
for (Mesh::SExtension *cur_ext : mesh.Extension) {
if (cur_ext->Type == Mesh::SExtension::EType::Compression_Open3DGC) {
// Limitations for meshes when using Open3DGC-compression.
// It's a current limitation of sp... Specification have not this part still - about mesh compression. Why only one primitive?
@ -233,12 +233,12 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
buf->EncodedRegion_SetCurrent(mesh.id);
} else
#endif
{
throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"" + to_string(cur_ext->Type) +
throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"", to_string(cur_ext->Type),
"\"), only Open3DGC is supported.");
}
}
#endif
} // if(mesh.Extension.size() > 0)
meshOffsets.push_back(k);

View File

@ -1,4 +1,4 @@
/*
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GLTF2ASSET_H_INC
#define GLTF2ASSET_H_INC
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_IMPORTER)
#include <assimp/Exceptional.h>
@ -62,19 +62,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
#ifndef RAPIDJSON_HAS_STDSTRING
#define RAPIDJSON_HAS_STDSTRING 1
#endif
#if (__GNUC__ == 8 && __GNUC_MINOR__ >= 0)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
#define RAPIDJSON_NOMEMBERITERATORCLASS
#endif
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <rapidjson/rapidjson.h>
@ -202,7 +194,7 @@ inline unsigned int ComponentTypeSize(ComponentType t) {
case ComponentType_UNSIGNED_BYTE:
return 1;
default:
throw DeadlyImportError("GLTF: Unsupported Component Type " + to_string(t));
throw DeadlyImportError("GLTF: Unsupported Component Type ", to_string(t));
}
}
@ -406,6 +398,8 @@ struct Accessor : public Object {
void ExtractData(T *&outData);
void WriteData(size_t count, const void *src_buffer, size_t src_stride);
void WriteSparseValues(size_t count, const void *src_data, size_t src_dataStride);
void WriteSparseIndices(size_t count, const void *src_idx, size_t src_idxStride);
//! Helper class to iterate the data
class Indexer {
@ -802,7 +796,7 @@ struct CustomExtension : public Object {
Nullable<std::vector<CustomExtension>> mValues;
operator bool() const {
return Size();
return Size() != 0;
}
size_t Size() const {
@ -1066,6 +1060,7 @@ public:
} extensionsRequired;
AssetMetadata asset;
Value* extras = nullptr;
// Dictionaries for each type of object

View File

@ -269,21 +269,21 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
// read it from the JSON object
if (!mDict) {
throw DeadlyImportError("GLTF: Missing section \"" + std::string(mDictId) + "\"");
throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
}
if (!mDict->IsArray()) {
throw DeadlyImportError("GLTF: Field is not an array \"" + std::string(mDictId) + "\"");
throw DeadlyImportError("GLTF: Field is not an array \"", mDictId, "\"");
}
Value &obj = (*mDict)[i];
if (!obj.IsObject()) {
throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object");
throw DeadlyImportError("GLTF: Object at index \"", to_string(i), "\" is not a JSON object");
}
if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" has recursive reference to itself");
throw DeadlyImportError("GLTF: Object at index \"", to_string(i), "\" has recursive reference to itself");
}
mRecursiveReferenceCheck.insert(i);
@ -381,13 +381,13 @@ inline void Buffer::Read(Value &obj, Asset &r) {
this->mData.reset(data, std::default_delete<uint8_t[]>());
if (statedLength > 0 && this->byteLength != statedLength) {
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
" bytes, but found " + to_string(dataURI.dataLength));
throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", to_string(statedLength),
" bytes, but found ", to_string(dataURI.dataLength));
}
} else { // assume raw data
if (statedLength != dataURI.dataLength) {
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
" bytes, but found " + to_string(dataURI.dataLength));
throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", to_string(statedLength),
" bytes, but found ", to_string(dataURI.dataLength));
}
this->mData.reset(new uint8_t[dataURI.dataLength], std::default_delete<uint8_t[]>());
@ -403,9 +403,9 @@ inline void Buffer::Read(Value &obj, Asset &r) {
delete file;
if (!ok)
throw DeadlyImportError("GLTF: error while reading referenced file \"" + std::string(uri) + "\"");
throw DeadlyImportError("GLTF: error while reading referenced file \"", uri, "\"");
} else {
throw DeadlyImportError("GLTF: could not open referenced file \"" + std::string(uri) + "\"");
throw DeadlyImportError("GLTF: could not open referenced file \"", uri, "\"");
}
}
}
@ -436,8 +436,8 @@ inline void Buffer::EncodedRegion_Mark(const size_t pOffset, const size_t pEncod
char val[val_size];
ai_snprintf(val, val_size, "%llu", (long long)pOffset);
throw DeadlyImportError(std::string("GLTF: incorrect offset value (") + val + ") for marking encoded region.");
ai_snprintf(val, val_size, AI_SIZEFMT, pOffset);
throw DeadlyImportError("GLTF: incorrect offset value (", val, ") for marking encoded region.");
}
// Check length
@ -446,8 +446,8 @@ inline void Buffer::EncodedRegion_Mark(const size_t pOffset, const size_t pEncod
char val[val_size];
ai_snprintf(val, val_size, "%llu, %llu", (long long)pOffset, (long long)pEncodedData_Length);
throw DeadlyImportError(std::string("GLTF: encoded region with offset/length (") + val + ") is out of range.");
ai_snprintf(val, val_size, AI_SIZEFMT "/" AI_SIZEFMT, pOffset, pEncodedData_Length);
throw DeadlyImportError("GLTF: encoded region with offset/length (", val, ") is out of range.");
}
// Add new region
@ -467,7 +467,7 @@ inline void Buffer::EncodedRegion_SetCurrent(const std::string &pID) {
}
}
throw DeadlyImportError("GLTF: EncodedRegion with ID: \"" + pID + "\" not found.");
throw DeadlyImportError("GLTF: EncodedRegion with ID: \"", pID, "\" not found.");
}
inline bool Buffer::ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t *pReplace_Data, const size_t pReplace_Count) {
@ -731,8 +731,14 @@ void Accessor::ExtractData(T *&outData) {
const size_t stride = bufferView && bufferView->byteStride ? bufferView->byteStride : elemSize;
const size_t targetElemSize = sizeof(T);
ai_assert(elemSize <= targetElemSize);
ai_assert(count * stride <= (bufferView ? bufferView->byteLength : sparse->data.size()));
if (elemSize > targetElemSize) {
throw DeadlyImportError("GLTF: elemSize > targetElemSize");
}
if (count*stride > (bufferView ? bufferView->byteLength : sparse->data.size())) {
throw DeadlyImportError("GLTF: count*stride out of range");
}
outData = new T[count];
if (stride == elemSize && targetElemSize == elemSize) {
@ -757,6 +763,33 @@ inline void Accessor::WriteData(size_t _count, const void *src_buffer, size_t sr
CopyData(_count, src, src_stride, dst, dst_stride);
}
inline void Accessor::WriteSparseValues(size_t _count, const void *src_data, size_t src_dataStride) {
if (!sparse)
return;
// values
uint8_t *value_buffer_ptr = sparse->values->buffer->GetPointer();
size_t value_offset = sparse->valuesByteOffset + sparse->values->byteOffset;
size_t value_dst_stride = GetNumComponents() * GetBytesPerComponent();
const uint8_t *value_src = reinterpret_cast<const uint8_t *>(src_data);
uint8_t *value_dst = reinterpret_cast<uint8_t *>(value_buffer_ptr + value_offset);
ai_assert(value_dst + _count * value_dst_stride <= value_buffer_ptr + sparse->values->buffer->byteLength);
CopyData(_count, value_src, src_dataStride, value_dst, value_dst_stride);
}
inline void Accessor::WriteSparseIndices(size_t _count, const void *src_idx, size_t src_idxStride) {
if (!sparse)
return;
// indices
uint8_t *indices_buffer_ptr = sparse->indices->buffer->GetPointer();
size_t indices_offset = sparse->indicesByteOffset + sparse->indices->byteOffset;
size_t indices_dst_stride = 1 * sizeof(unsigned short);
const uint8_t *indices_src = reinterpret_cast<const uint8_t *>(src_idx);
uint8_t *indices_dst = reinterpret_cast<uint8_t *>(indices_buffer_ptr + indices_offset);
ai_assert(indices_dst + _count * indices_dst_stride <= indices_buffer_ptr + sparse->indices->buffer->byteLength);
CopyData(_count, indices_src, src_idxStride, indices_dst, indices_dst_stride);
}
inline Accessor::Indexer::Indexer(Accessor &acc) :
accessor(acc),
data(acc.GetPointer()),
@ -1015,10 +1048,10 @@ inline int Compare(const char *attr, const char (&str)[N]) {
return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
}
#ifdef _WIN32
#if _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4706)
#endif // _WIN32
#endif // _MSC_VER
inline bool GetAttribVector(Mesh::Primitive &p, const char *attr, Mesh::AccessorList *&v, int &pos) {
if ((pos = Compare(attr, "POSITION"))) {
@ -1287,6 +1320,8 @@ inline void Node::Read(Value &obj, Asset &r) {
}
}
// Do not retrieve a skin here, just take a reference, to avoid infinite recursion
// Skins will be properly loaded later
Value *curSkin = FindUInt(obj, "skin");
if (nullptr != curSkin) {
this->skin = r.skins.Get(curSkin->GetUint());
@ -1429,7 +1464,7 @@ inline void AssetMetadata::Read(Document &doc) {
}
if (version.empty() || version[0] != '2') {
throw DeadlyImportError("GLTF: Unsupported glTF version: " + version);
throw DeadlyImportError("GLTF: Unsupported glTF version: ", version);
}
}
@ -1541,7 +1576,7 @@ inline void Asset::Load(const std::string &pFile, bool isBinary) {
if (doc.HasParseError()) {
char buffer[32];
ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
throw DeadlyImportError(std::string("GLTF: JSON parse error, offset ") + buffer + ": " + GetParseError_En(doc.GetParseError()));
throw DeadlyImportError("GLTF: JSON parse error, offset ", buffer, ": ", GetParseError_En(doc.GetParseError()));
}
if (!doc.IsObject()) {
@ -1584,7 +1619,6 @@ inline void Asset::Load(const std::string &pFile, bool isBinary) {
}
}
// Read skins after nodes have been loaded to avoid infinite recursion
if (Value *skinsArray = FindArray(doc, "skins")) {
for (unsigned int i = 0; i < skinsArray->Size(); ++i) {
skins.Retrieve(i);
@ -1695,8 +1729,8 @@ inline std::string Asset::FindUniqueID(const std::string &str, const char *suffi
return id;
}
#ifdef _WIN32
#pragma warning(pop)
#endif // _WIN32
#if _MSC_VER
# pragma warning(pop)
#endif // _MSC_VER
} // namespace glTF2

View File

@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GLTF2ASSETWRITER_H_INC
#define GLTF2ASSETWRITER_H_INC
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_IMPORTER)
#include "glTF2Asset.h"

View File

@ -1,4 +1,4 @@
/*
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
@ -107,21 +107,47 @@ namespace glTF2 {
inline void Write(Value& obj, Accessor& a, AssetWriter& w)
{
obj.AddMember("bufferView", a.bufferView->index, w.mAl);
obj.AddMember("byteOffset", (unsigned int)a.byteOffset, w.mAl);
if (a.bufferView) {
obj.AddMember("bufferView", a.bufferView->index, w.mAl);
obj.AddMember("byteOffset", (unsigned int)a.byteOffset, w.mAl);
Value vTmpMax, vTmpMin;
if (a.componentType == ComponentType_FLOAT) {
obj.AddMember("max", MakeValue(vTmpMax, a.max, w.mAl), w.mAl);
obj.AddMember("min", MakeValue(vTmpMin, a.min, w.mAl), w.mAl);
} else {
obj.AddMember("max", MakeValueCast<int64_t>(vTmpMax, a.max, w.mAl), w.mAl);
obj.AddMember("min", MakeValueCast<int64_t>(vTmpMin, a.min, w.mAl), w.mAl);
}
}
obj.AddMember("componentType", int(a.componentType), w.mAl);
obj.AddMember("count", (unsigned int)a.count, w.mAl);
obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl);
Value vTmpMax, vTmpMin;
if (a.componentType == ComponentType_FLOAT) {
obj.AddMember("max", MakeValue(vTmpMax, a.max, w.mAl), w.mAl);
obj.AddMember("min", MakeValue(vTmpMin, a.min, w.mAl), w.mAl);
} else {
obj.AddMember("max", MakeValueCast<int64_t>(vTmpMax, a.max, w.mAl), w.mAl);
obj.AddMember("min", MakeValueCast<int64_t>(vTmpMin, a.min, w.mAl), w.mAl);
}
if (a.sparse) {
Value sparseValue;
sparseValue.SetObject();
//count
sparseValue.AddMember("count", (unsigned int)a.sparse->count, w.mAl);
//indices
Value indices;
indices.SetObject();
indices.AddMember("bufferView", a.sparse->indices->index, w.mAl);
indices.AddMember("byteOffset", (unsigned int)a.sparse->indicesByteOffset, w.mAl);
indices.AddMember("componentType", int(a.sparse->indicesType), w.mAl);
sparseValue.AddMember("indices", indices, w.mAl);
//values
Value values;
values.SetObject();
values.AddMember("bufferView", a.sparse->values->index, w.mAl);
values.AddMember("byteOffset", (unsigned int)a.sparse->valuesByteOffset, w.mAl);
sparseValue.AddMember("values", values, w.mAl);
obj.AddMember("sparse", sparseValue, w.mAl);
}
}
inline void Write(Value& obj, Animation& a, AssetWriter& w)
@ -616,6 +642,10 @@ namespace glTF2 {
if (mAsset.scene) {
mDoc.AddMember("scene", mAsset.scene->index, mAl);
}
if(mAsset.extras) {
mDoc.AddMember("extras", *mAsset.extras, mAl);
}
}
inline void AssetWriter::WriteFile(const char* path)
@ -709,10 +739,13 @@ namespace glTF2 {
// Binary chunk
//
int GLB_Chunk_count = 1;
uint32_t binaryChunkLength = 0;
if (bodyBuffer->byteLength > 0) {
binaryChunkLength = (bodyBuffer->byteLength + 3) & ~3; // Round up to next multiple of 4
//auto curPaddingLength = binaryChunkLength - bodyBuffer->byteLength;
auto curPaddingLength = binaryChunkLength - bodyBuffer->byteLength;
++GLB_Chunk_count;
GLB_Chunk binaryChunk;
binaryChunk.chunkLength = binaryChunkLength;
@ -727,7 +760,7 @@ namespace glTF2 {
if (outfile->Write(bodyBuffer->GetPointer(), 1, bodyBuffer->byteLength) != bodyBuffer->byteLength) {
throw DeadlyExportError("Failed to write body data!");
}
if (paddingLength && outfile->Write(&padding, 1, paddingLength) != paddingLength) {
if (curPaddingLength && outfile->Write(&padding, 1, paddingLength) != paddingLength) {
throw DeadlyExportError("Failed to write body data padding!");
}
}
@ -742,7 +775,7 @@ namespace glTF2 {
header.version = 2;
AI_SWAP4(header.version);
header.length = uint32_t(sizeof(GLB_Header) + 2 * sizeof(GLB_Chunk) + jsonChunkLength + binaryChunkLength);
header.length = uint32_t(sizeof(GLB_Header) + GLB_Chunk_count * sizeof(GLB_Chunk) + jsonChunkLength + binaryChunkLength);
AI_SWAP4(header.length);
outfile->Seek(0, aiOrigin_SET);

View File

@ -1,4 +1,4 @@
/*
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
@ -115,7 +115,14 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai
ExportScene();
ExportAnimations();
// export extras
if(mProperties->HasPropertyCallback("extras"))
{
std::function<void*(void*)> ExportExtras = mProperties->GetPropertyCallback("extras");
mAsset->extras = (rapidjson::Value*)ExportExtras(0);
}
AssetWriter writer(*mAsset);
if (isBinary) {
@ -214,6 +221,158 @@ inline void SetAccessorRange(ComponentType compType, Ref<Accessor> acc, void* da
}
}
// compute the (data-dataBase), store the non-zero data items
template <typename T>
size_t NZDiff(void *data, void *dataBase, size_t count, unsigned int numCompsIn, unsigned int numCompsOut, void *&outputNZDiff, void *&outputNZIdx) {
std::vector<T> vNZDiff;
std::vector<unsigned short> vNZIdx;
size_t totalComps = count * numCompsIn;
T *bufferData_ptr = static_cast<T *>(data);
T *bufferData_end = bufferData_ptr + totalComps;
T *bufferBase_ptr = static_cast<T *>(dataBase);
// Search and set extreme values.
for (short idx = 0; bufferData_ptr < bufferData_end; idx += 1, bufferData_ptr += numCompsIn) {
bool bNonZero = false;
//for the data, check any component Non Zero
for (unsigned int j = 0; j < numCompsOut; j++) {
double valueData = bufferData_ptr[j];
double valueBase = bufferBase_ptr ? bufferBase_ptr[j] : 0;
if ((valueData - valueBase) != 0) {
bNonZero = true;
break;
}
}
//all zeros, continue
if (!bNonZero)
continue;
//non zero, store the data
for (unsigned int j = 0; j < numCompsOut; j++) {
T valueData = bufferData_ptr[j];
T valueBase = bufferBase_ptr ? bufferBase_ptr[j] : 0;
vNZDiff.push_back(valueData - valueBase);
}
vNZIdx.push_back(idx);
}
//avoid all-0, put 1 item
if (vNZDiff.size() == 0) {
for (unsigned int j = 0; j < numCompsOut; j++)
vNZDiff.push_back(0);
vNZIdx.push_back(0);
}
//process data
outputNZDiff = new T[vNZDiff.size()];
memcpy(outputNZDiff, vNZDiff.data(), vNZDiff.size() * sizeof(T));
outputNZIdx = new unsigned short[vNZIdx.size()];
memcpy(outputNZIdx, vNZIdx.data(), vNZIdx.size() * sizeof(unsigned short));
return vNZIdx.size();
}
inline size_t NZDiff(ComponentType compType, void *data, void *dataBase, size_t count, unsigned int numCompsIn, unsigned int numCompsOut, void *&nzDiff, void *&nzIdx) {
switch (compType) {
case ComponentType_SHORT:
return NZDiff<short>(data, dataBase, count, numCompsIn, numCompsOut, nzDiff, nzIdx);
case ComponentType_UNSIGNED_SHORT:
return NZDiff<unsigned short>(data, dataBase, count, numCompsIn, numCompsOut, nzDiff, nzIdx);
case ComponentType_UNSIGNED_INT:
return NZDiff<unsigned int>(data, dataBase, count, numCompsIn, numCompsOut, nzDiff, nzIdx);
case ComponentType_FLOAT:
return NZDiff<float>(data, dataBase, count, numCompsIn, numCompsOut, nzDiff, nzIdx);
case ComponentType_BYTE:
return NZDiff<int8_t>(data, dataBase, count, numCompsIn, numCompsOut, nzDiff, nzIdx);
case ComponentType_UNSIGNED_BYTE:
return NZDiff<uint8_t>(data, dataBase, count, numCompsIn, numCompsOut, nzDiff, nzIdx);
}
return 0;
}
inline Ref<Accessor> ExportDataSparse(Asset &a, std::string &meshName, Ref<Buffer> &buffer,
size_t count, void *data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, BufferViewTarget target = BufferViewTarget_NONE, void *dataBase = 0) {
if (!count || !data) {
return Ref<Accessor>();
}
unsigned int numCompsIn = AttribType::GetNumComponents(typeIn);
unsigned int numCompsOut = AttribType::GetNumComponents(typeOut);
unsigned int bytesPerComp = ComponentTypeSize(compType);
// accessor
Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
// if there is a basic data vector
if (dataBase) {
size_t base_offset = buffer->byteLength;
size_t base_padding = base_offset % bytesPerComp;
base_offset += base_padding;
size_t base_length = count * numCompsOut * bytesPerComp;
buffer->Grow(base_length + base_padding);
Ref<BufferView> bv = a.bufferViews.Create(a.FindUniqueID(meshName, "view"));
bv->buffer = buffer;
bv->byteOffset = base_offset;
bv->byteLength = base_length; //! The target that the WebGL buffer should be bound to.
bv->byteStride = 0;
bv->target = target;
acc->bufferView = bv;
acc->WriteData(count, dataBase, numCompsIn * bytesPerComp);
}
acc->byteOffset = 0;
acc->componentType = compType;
acc->count = count;
acc->type = typeOut;
if (data) {
void *nzDiff = 0, *nzIdx = 0;
size_t nzCount = NZDiff(compType, data, dataBase, count, numCompsIn, numCompsOut, nzDiff, nzIdx);
acc->sparse.reset(new Accessor::Sparse);
acc->sparse->count = nzCount;
//indices
unsigned int bytesPerIdx = sizeof(unsigned short);
size_t indices_offset = buffer->byteLength;
size_t indices_padding = indices_offset % bytesPerIdx;
indices_offset += indices_padding;
size_t indices_length = nzCount * 1 * bytesPerIdx;
buffer->Grow(indices_length + indices_padding);
Ref<BufferView> indicesBV = a.bufferViews.Create(a.FindUniqueID(meshName, "view"));
indicesBV->buffer = buffer;
indicesBV->byteOffset = indices_offset;
indicesBV->byteLength = indices_length;
indicesBV->byteStride = 0;
acc->sparse->indices = indicesBV;
acc->sparse->indicesType = ComponentType_UNSIGNED_SHORT;
acc->sparse->indicesByteOffset = 0;
acc->WriteSparseIndices(nzCount, nzIdx, 1 * bytesPerIdx);
//values
size_t values_offset = buffer->byteLength;
size_t values_padding = values_offset % bytesPerComp;
values_offset += values_padding;
size_t values_length = nzCount * numCompsOut * bytesPerComp;
buffer->Grow(values_length + values_padding);
Ref<BufferView> valuesBV = a.bufferViews.Create(a.FindUniqueID(meshName, "view"));
valuesBV->buffer = buffer;
valuesBV->byteOffset = values_offset;
valuesBV->byteLength = values_length;
valuesBV->byteStride = 0;
acc->sparse->values = valuesBV;
acc->sparse->valuesByteOffset = 0;
acc->WriteSparseValues(nzCount, nzDiff, numCompsIn * bytesPerComp);
//clear
delete[] (char*)nzDiff;
delete[] (char*)nzIdx;
}
return acc;
}
inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& buffer,
size_t count, void* data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, BufferViewTarget target = BufferViewTarget_NONE)
{
@ -824,6 +983,10 @@ void glTF2Exporter::ExportMeshes()
/*************** Targets for blendshapes ****************/
if (aim->mNumAnimMeshes > 0) {
bool bUseSparse = this->mProperties->HasPropertyBool("GLTF2_SPARSE_ACCESSOR_EXP") &&
this->mProperties->GetPropertyBool("GLTF2_SPARSE_ACCESSOR_EXP");
bool bIncludeNormal = this->mProperties->HasPropertyBool("GLTF2_TARGET_NORMAL_EXP") &&
this->mProperties->GetPropertyBool("GLTF2_TARGET_NORMAL_EXP");
bool bExportTargetNames = this->mProperties->HasPropertyBool("GLTF2_TARGETNAMES_EXP") &&
this->mProperties->GetPropertyBool("GLTF2_TARGETNAMES_EXP");
@ -832,7 +995,6 @@ void glTF2Exporter::ExportMeshes()
aiAnimMesh *pAnimMesh = aim->mAnimMeshes[am];
if (bExportTargetNames)
m->targetNames.push_back(pAnimMesh->mName.data);
// position
if (pAnimMesh->HasPositions()) {
// NOTE: in gltf it is the diff stored
@ -840,9 +1002,16 @@ void glTF2Exporter::ExportMeshes()
for (unsigned int vt = 0; vt < pAnimMesh->mNumVertices; ++vt) {
pPositionDiff[vt] = pAnimMesh->mVertices[vt] - aim->mVertices[vt];
}
Ref<Accessor> vec = ExportData(*mAsset, meshId, b,
pAnimMesh->mNumVertices, pPositionDiff,
AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
Ref<Accessor> vec;
if (bUseSparse) {
vec = ExportDataSparse(*mAsset, meshId, b,
pAnimMesh->mNumVertices, pPositionDiff,
AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
} else {
vec = ExportData(*mAsset, meshId, b,
pAnimMesh->mNumVertices, pPositionDiff,
AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
}
if (vec) {
p.targets[am].position.push_back(vec);
}
@ -850,14 +1019,21 @@ void glTF2Exporter::ExportMeshes()
}
// normal
if (pAnimMesh->HasNormals()) {
if (pAnimMesh->HasNormals() && bIncludeNormal) {
aiVector3D *pNormalDiff = new aiVector3D[pAnimMesh->mNumVertices];
for (unsigned int vt = 0; vt < pAnimMesh->mNumVertices; ++vt) {
pNormalDiff[vt] = pAnimMesh->mNormals[vt] - aim->mNormals[vt];
}
Ref<Accessor> vec = ExportData(*mAsset, meshId, b,
pAnimMesh->mNumVertices, pNormalDiff,
AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
Ref<Accessor> vec;
if (bUseSparse) {
vec = ExportDataSparse(*mAsset, meshId, b,
pAnimMesh->mNumVertices, pNormalDiff,
AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
} else {
vec = ExportData(*mAsset, meshId, b,
pAnimMesh->mNumVertices, pNormalDiff,
AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
}
if (vec) {
p.targets[am].normal.push_back(vec);
}

View File

@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_GLTF2EXPORTER_H_INC
#define AI_GLTF2EXPORTER_H_INC
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_IMPORTER)
#include <assimp/types.h>
#include <assimp/material.h>

View File

@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_IMPORTER)
#include "AssetLib/glTF2/glTF2Importer.h"
#include "PostProcessing/MakeVerboseFormat.h"
@ -298,25 +298,37 @@ void glTF2Importer::ImportMaterials(glTF2::Asset &r) {
}
}
static inline void SetFace(aiFace &face, int a) {
face.mNumIndices = 1;
face.mIndices = new unsigned int[1];
face.mIndices[0] = a;
static inline void SetFaceAndAdvance1(aiFace*& face, unsigned int numVertices, unsigned int a) {
if (a >= numVertices) {
return;
}
face->mNumIndices = 1;
face->mIndices = new unsigned int[1];
face->mIndices[0] = a;
++face;
}
static inline void SetFace(aiFace &face, int a, int b) {
face.mNumIndices = 2;
face.mIndices = new unsigned int[2];
face.mIndices[0] = a;
face.mIndices[1] = b;
static inline void SetFaceAndAdvance2(aiFace*& face, unsigned int numVertices, unsigned int a, unsigned int b) {
if ((a >= numVertices) || (b >= numVertices)) {
return;
}
face->mNumIndices = 2;
face->mIndices = new unsigned int[2];
face->mIndices[0] = a;
face->mIndices[1] = b;
++face;
}
static inline void SetFace(aiFace &face, int a, int b, int c) {
face.mNumIndices = 3;
face.mIndices = new unsigned int[3];
face.mIndices[0] = a;
face.mIndices[1] = b;
face.mIndices[2] = c;
static inline void SetFaceAndAdvance3(aiFace*& face, unsigned int numVertices, unsigned int a, unsigned int b, unsigned int c) {
if ((a >= numVertices) || (b >= numVertices) || (c >= numVertices)) {
return;
}
face->mNumIndices = 3;
face->mIndices = new unsigned int[3];
face->mIndices[0] = a;
face->mIndices[1] = b;
face->mIndices[2] = c;
++face;
}
#ifdef ASSIMP_BUILD_DEBUG
@ -335,7 +347,7 @@ static inline bool CheckValidFacesIndices(aiFace *faces, unsigned nFaces, unsign
void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
ASSIMP_LOG_DEBUG_F("Importing ", r.meshes.Size(), " meshes");
std::vector<aiMesh *> meshes;
std::vector<std::unique_ptr<aiMesh>> meshes;
unsigned int k = 0;
meshOffsets.clear();
@ -350,7 +362,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
Mesh::Primitive &prim = mesh.primitives[p];
aiMesh *aim = new aiMesh();
meshes.push_back(aim);
meshes.push_back(std::unique_ptr<aiMesh>(aim));
aim->mName = mesh.name.empty() ? mesh.id : mesh.name;
@ -486,6 +498,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
}
aiFace *faces = nullptr;
aiFace *facePtr = nullptr;
size_t nFaces = 0;
if (prim.indices) {
@ -497,9 +510,9 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
switch (prim.mode) {
case PrimitiveMode_POINTS: {
nFaces = count;
faces = new aiFace[nFaces];
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; ++i) {
SetFace(faces[i], data.GetUInt(i));
SetFaceAndAdvance1(facePtr, aim->mNumVertices, data.GetUInt(i));
}
break;
}
@ -510,9 +523,9 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
count = nFaces * 2;
}
faces = new aiFace[nFaces];
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1));
}
break;
}
@ -520,13 +533,13 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
case PrimitiveMode_LINE_LOOP:
case PrimitiveMode_LINE_STRIP: {
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
faces = new aiFace[nFaces];
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1));
facePtr = faces = new aiFace[nFaces];
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1));
for (unsigned int i = 2; i < count; ++i) {
SetFace(faces[i - 1], faces[i - 2].mIndices[1], data.GetUInt(i));
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i - 1), data.GetUInt(i));
}
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(static_cast<int>(count) - 1), faces[0].mIndices[0]);
}
break;
}
@ -537,33 +550,33 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
count = nFaces * 3;
}
faces = new aiFace[nFaces];
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
}
break;
}
case PrimitiveMode_TRIANGLE_STRIP: {
nFaces = count - 2;
faces = new aiFace[nFaces];
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < nFaces; ++i) {
//The ordering is to ensure that the triangles are all drawn with the same orientation
if ((i + 1) % 2 == 0) {
//For even n, vertices n + 1, n, and n + 2 define triangle n
SetFace(faces[i], data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2));
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2));
} else {
//For odd n, vertices n, n+1, and n+2 define triangle n
SetFace(faces[i], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
}
}
break;
}
case PrimitiveMode_TRIANGLE_FAN:
nFaces = count - 2;
faces = new aiFace[nFaces];
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
facePtr = faces = new aiFace[nFaces];
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
for (unsigned int i = 1; i < nFaces; ++i) {
SetFace(faces[i], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i + 2));
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(i + 1), data.GetUInt(i + 2));
}
break;
}
@ -575,9 +588,9 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
switch (prim.mode) {
case PrimitiveMode_POINTS: {
nFaces = count;
faces = new aiFace[nFaces];
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; ++i) {
SetFace(faces[i], i);
SetFaceAndAdvance1(facePtr, aim->mNumVertices, i);
}
break;
}
@ -588,9 +601,9 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
count = (unsigned int)nFaces * 2;
}
faces = new aiFace[nFaces];
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], i, i + 1);
SetFaceAndAdvance2(facePtr, aim->mNumVertices, i, i + 1);
}
break;
}
@ -598,13 +611,13 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
case PrimitiveMode_LINE_LOOP:
case PrimitiveMode_LINE_STRIP: {
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
faces = new aiFace[nFaces];
SetFace(faces[0], 0, 1);
facePtr = faces = new aiFace[nFaces];
SetFaceAndAdvance2(facePtr, aim->mNumVertices, 0, 1);
for (unsigned int i = 2; i < count; ++i) {
SetFace(faces[i - 1], faces[i - 2].mIndices[1], i);
SetFaceAndAdvance2(facePtr, aim->mNumVertices, i - 1, i);
}
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
SetFaceAndAdvance2(facePtr, aim->mNumVertices, count - 1, 0);
}
break;
}
@ -615,42 +628,50 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
count = (unsigned int)nFaces * 3;
}
faces = new aiFace[nFaces];
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], i, i + 1, i + 2);
SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2);
}
break;
}
case PrimitiveMode_TRIANGLE_STRIP: {
nFaces = count - 2;
faces = new aiFace[nFaces];
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < nFaces; ++i) {
//The ordering is to ensure that the triangles are all drawn with the same orientation
if ((i + 1) % 2 == 0) {
//For even n, vertices n + 1, n, and n + 2 define triangle n
SetFace(faces[i], i + 1, i, i + 2);
SetFaceAndAdvance3(facePtr, aim->mNumVertices, i + 1, i, i + 2);
} else {
//For odd n, vertices n, n+1, and n+2 define triangle n
SetFace(faces[i], i, i + 1, i + 2);
SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2);
}
}
break;
}
case PrimitiveMode_TRIANGLE_FAN:
nFaces = count - 2;
faces = new aiFace[nFaces];
SetFace(faces[0], 0, 1, 2);
facePtr = faces = new aiFace[nFaces];
SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, 1, 2);
for (unsigned int i = 1; i < nFaces; ++i) {
SetFace(faces[i], faces[0].mIndices[0], faces[i - 1].mIndices[2], i + 2);
SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, i + 1, i + 2);
}
break;
}
}
if (nullptr != faces) {
if (faces) {
aim->mFaces = faces;
aim->mNumFaces = static_cast<unsigned int>(nFaces);
ai_assert(CheckValidFacesIndices(faces, static_cast<unsigned>(nFaces), aim->mNumVertices));
const unsigned int actualNumFaces = static_cast<unsigned int>(facePtr - faces);
if (actualNumFaces < nFaces) {
ASSIMP_LOG_WARN("Some faces had out-of-range indices. Those faces were dropped.");
}
if (actualNumFaces == 0)
{
throw DeadlyImportError("Mesh \"", aim->mName.C_Str(), "\" has no faces");
}
aim->mNumFaces = actualNumFaces;
ai_assert(CheckValidFacesIndices(faces, actualNumFaces, aim->mNumVertices));
}
if (prim.material) {

View File

@ -200,6 +200,7 @@ SET( Common_SRCS
Common/simd.cpp
Common/material.cpp
Common/AssertHandler.cpp
Common/Exceptional.cpp
)
SOURCE_GROUP(Common FILES ${Common_SRCS})
@ -884,7 +885,7 @@ ENDIF()
# utf8
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(utf8)
find_package(utf8 CONFIG REQUIRED)
find_package(utf8cpp CONFIG REQUIRED)
ELSE()
# utf8 is header-only, so Assimp doesn't need to do anything.
ENDIF()
@ -1039,6 +1040,8 @@ IF(ASSIMP_HUNTER_ENABLED)
ELSE()
INCLUDE_DIRECTORIES( "../contrib/rapidjson/include" )
INCLUDE_DIRECTORIES( "../contrib" )
ADD_DEFINITIONS( -DRAPIDJSON_HAS_STDSTRING=1 )
ADD_DEFINITIONS( -DRAPIDJSON_NOMEMBERITERATORCLASS )
ENDIF()
# VC2010 fixes
@ -1051,7 +1054,7 @@ endif()
ADD_DEFINITIONS( -DASSIMP_BUILD_DLL_EXPORT )
if ( MSVC )
IF( MSVC OR "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC") # clang with MSVC ABI
ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
endif ()
@ -1121,6 +1124,8 @@ ENDIF ()
ADD_LIBRARY( assimp ${assimp_src} )
ADD_LIBRARY(assimp::assimp ALIAS assimp)
TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp)
# enable warnings as errors ########################################
IF (MSVC)
TARGET_COMPILE_OPTIONS(assimp PRIVATE /WX)
@ -1144,7 +1149,7 @@ IF(ASSIMP_HUNTER_ENABLED)
minizip::minizip
ZLIB::zlib
RapidJSON::rapidjson
utf8::utf8
utf8cpp
zip::zip
pugixml::pugixml
)

View File

@ -130,10 +130,11 @@ aiScene *BaseImporter::ReadFile(Importer *pImp, const std::string &pFile, IOSyst
// passes scale into ScaleProcess
UpdateImporterScale(pImp);
} catch (const std::exception &err) {
} catch( const std::exception &err ) {
// extract error description
m_ErrorText = err.what();
ASSIMP_LOG_ERROR(m_ErrorText);
ASSIMP_LOG_ERROR(err.what());
m_Exception = std::current_exception();
return nullptr;
}
@ -343,7 +344,7 @@ std::string BaseImporter::GetExtension(const std::string &file) {
}
#ifdef ASSIMP_USE_HUNTER
#include <utf8/utf8.h>
#include <utf8.h>
#else
#include "../contrib/utf8cpp/source/utf8.h"
#endif

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -52,27 +50,32 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
namespace {
template <size_t sizeOfPointer>
size_t select_ftell(FILE *file) {
inline size_t select_ftell(FILE *file) {
return ::ftell(file);
}
template <size_t sizeOfPointer>
int select_fseek(FILE *file, int64_t offset, int origin) {
inline int select_fseek(FILE *file, int64_t offset, int origin) {
return ::fseek(file, static_cast<long>(offset), origin);
}
#if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
template <>
size_t select_ftell<8>(FILE *file) {
inline size_t select_ftell<8>(FILE *file) {
return (size_t)::_ftelli64(file);
}
template <>
int select_fseek<8>(FILE *file, int64_t offset, int origin) {
inline int select_fseek<8>(FILE *file, int64_t offset, int origin) {
return ::_fseeki64(file, offset, origin);
}
#endif
#endif // #if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
} // namespace
// ----------------------------------------------------------------------------------
@ -100,7 +103,6 @@ size_t DefaultIOStream::Write(const void *pvBuffer,
size_t pCount) {
ai_assert(nullptr != pvBuffer);
ai_assert(0 != pSize);
ai_assert(0 != pCount);
return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0);
}

View File

@ -0,0 +1,52 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, 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 Exceptional.cpp
Implementations of the exception classes.
*/
#include <assimp/Exceptional.h>
#include <assimp/TinyFormatter.h>
DeadlyErrorBase::DeadlyErrorBase(Assimp::Formatter::format f) :
runtime_error(std::string(f)){}

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