Fix build and merged master.

pull/3892/head
Kim Kulling 2021-05-06 21:36:25 +02:00
commit 350f2ea1d3
1098 changed files with 72800 additions and 3960 deletions

3
.github/FUNDING.yml vendored
View File

@ -1,2 +1 @@
patreon: assimp
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4
open_collective: assimp

View File

@ -67,7 +67,13 @@ jobs:
uses: actions/checkout@v2
with:
repository: cpp-pm/polly
path: cmake/polly
path: cmake/polly
- name: Remove contrib directory for Hunter builds
if: contains(matrix.name, 'hunter')
uses: JesseTG/rm@v1.0.2
with:
path: contrib
- name: Cache DX SDK
id: dxcache

6
.gitignore vendored
View File

@ -18,6 +18,9 @@ build
*.VC.db-wal
*.VC.opendb
*.ipch
.vs/
out/
CMakeSettings.json
# Output
bin/
@ -113,3 +116,6 @@ tools/assimp_qt_viewer/moc_glview.cpp_parameters
tools/assimp_qt_viewer/moc_mainwindow.cpp
tools/assimp_qt_viewer/moc_mainwindow.cpp_parameters
tools/assimp_qt_viewer/ui_mainwindow.h
#Generated directory
generated/*

View File

@ -1,6 +1,6 @@
# Build Instructions
# Build / Install Instructions
## Build on all platforms using vcpkg
## Install on all platforms using vcpkg
You can download and install assimp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
```bash
git clone https://github.com/Microsoft/vcpkg.git
@ -11,6 +11,18 @@ You can download and install assimp using the [vcpkg](https://github.com/Microso
```
The assimp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Install on Ubuntu
You can install the Asset-Importer-Lib via apt:
```
sudo apt-get install assimp
```
## Install pyassimp
You need to have pip installed:
```
pip install pyassimp
```
## Manual build instructions
### Install CMake
@ -24,6 +36,12 @@ Make sure you have a working git-installation. Open a command prompt and clone t
```bash
git clone https://github.com/assimp/assimp.git
```
### Build from source:
```bash
cd assimp
cmake CMakeLists.txt
cmake --build .
```
### Build instructions for Windows with Visual-Studio

View File

@ -1,6 +1,6 @@
# Open Asset Import Library (assimp)
# ----------------------------------------------------------------------
# Copyright (c) 2006-2020, assimp team
# Copyright (c) 2006-2021, assimp team
#
# All rights reserved.
#
@ -38,7 +38,7 @@ SET(CMAKE_POLICY_DEFAULT_CMP0012 NEW)
SET(CMAKE_POLICY_DEFAULT_CMP0074 NEW)
SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW)
CMAKE_MINIMUM_REQUIRED( VERSION 3.0 )
CMAKE_MINIMUM_REQUIRED( VERSION 3.10 )
# Toggles the use of the hunter package manager
option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
@ -46,8 +46,8 @@ option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
IF(ASSIMP_HUNTER_ENABLED)
include("cmake/HunterGate.cmake")
HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.23.269.tar.gz"
SHA1 "64024b7b95b4c86d50ae05b926814448c93a70a0"
URL "https://github.com/cpp-pm/hunter/archive/v0.23.293.tar.gz"
SHA1 "e8e5470652db77149d9b38656db2a6c0b7642693"
)
add_definitions(-DASSIMP_USE_HUNTER)
@ -61,7 +61,6 @@ OPTION( BUILD_SHARED_LIBS
"Build package with shared libraries."
ON
)
OPTION( ASSIMP_BUILD_FRAMEWORK
"Build package as Mac OS X Framework bundle."
OFF
@ -133,9 +132,22 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH
)
IF ( WIN32 )
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW
"If the Assimp view tool is built. (requires DirectX)"
OFF )
# Use subset of Windows.h
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW
"If the Assimp view tool is built. (requires DirectX)"
OFF )
IF(MSVC)
OPTION( ASSIMP_INSTALL_PDB
"Install MSVC debug files."
ON )
IF(NOT (MSVC_VERSION LESS 1900))
# Multibyte character set is deprecated since at least MSVC2015 (possibly earlier)
ADD_DEFINITIONS( -DUNICODE -D_UNICODE )
ENDIF()
ENDIF()
ENDIF()
IF (IOS AND NOT ASSIMP_HUNTER_ENABLED)
@ -145,21 +157,6 @@ IF (IOS AND NOT ASSIMP_HUNTER_ENABLED)
ADD_DEFINITIONS(-DENABLE_BITCODE)
ENDIF ()
# Use subset of Windows.h
if (WIN32)
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
endif()
IF(MSVC)
OPTION( ASSIMP_INSTALL_PDB
"Install MSVC debug files."
ON
)
IF(NOT (MSVC_VERSION LESS 1900))
# Multibyte character set is deprecated since at least MSVC2015 (possibly earlier)
ADD_DEFINITIONS( -DUNICODE -D_UNICODE )
ENDIF()
ENDIF()
IF (ASSIMP_BUILD_FRAMEWORK)
SET (BUILD_SHARED_LIBS ON)
@ -455,6 +452,12 @@ IF(ASSIMP_HUNTER_ENABLED)
set(ZLIB_LIBRARIES ZLIB::zlib)
set(ASSIMP_BUILD_MINIZIP TRUE)
ELSE()
# If the zlib is already found outside, add an export in case assimpTargets can't find it.
IF( ZLIB_FOUND )
INSTALL( TARGETS zlib zlibstatic
EXPORT "${TARGETS_EXPORT_NAME}")
ENDIF()
IF ( NOT ASSIMP_BUILD_ZLIB )
FIND_PACKAGE(ZLIB)
ENDIF()
@ -570,6 +573,94 @@ ELSE ()
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
ENDIF ()
# Draco requires cmake 3.12
IF (DEFINED CMAKE_VERSION AND "${CMAKE_VERSION}" VERSION_LESS "3.12")
message(NOTICE "draco requires cmake 3.12 or newer, cmake is ${CMAKE_VERSION} . Draco is disabled")
SET ( ASSIMP_BUILD_DRACO OFF CACHE BOOL "Disabled: Draco requires newer cmake" FORCE )
ELSE()
OPTION ( ASSIMP_BUILD_DRACO "If the Draco libraries are to be built. Primarily for glTF" OFF )
IF ( ASSIMP_BUILD_DRACO )
# Primarily for glTF v2
# Enable Draco glTF feature set
set(DRACO_GLTF ON CACHE BOOL "" FORCE)
# Disable unnecessary or omitted components
set(DRACO_JS_GLUE OFF CACHE BOOL "" FORCE)
set(DRACO_WASM OFF CACHE BOOL "" FORCE)
set(DRACO_MAYA_PLUGIN OFF CACHE BOOL "" FORCE)
set(DRACO_UNITY_PLUGIN OFF CACHE BOOL "" FORCE)
set(DRACO_TESTS OFF CACHE BOOL "" FORCE)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(draco)
find_package(draco CONFIG REQUIRED)
set(draco_LIBRARIES draco::draco)
ELSE()
# Draco 1.4.1 has many warnings and will not build with /WX or -Werror
# See https://github.com/google/draco/issues/672
# and https://github.com/google/draco/issues/673
IF(MSVC)
set(DRACO_CXX_FLAGS "/W0")
ELSE()
list(APPEND DRACO_CXX_FLAGS
"-Wno-bool-compare"
"-Wno-comment"
"-Wno-maybe-uninitialized"
"-Wno-sign-compare"
"-Wno-unused-local-typedefs"
)
# Draco 1.4.1 does not explicitly export any symbols under GCC/clang
list(APPEND DRACO_CXX_FLAGS
"-fvisibility=default"
)
ENDIF()
# Don't build or install all of Draco by default
ADD_SUBDIRECTORY( "contrib/draco" EXCLUDE_FROM_ALL )
if(MSVC OR WIN32)
set(draco_LIBRARIES "draco")
else()
if(BUILD_SHARED_LIBS)
set(draco_LIBRARIES "draco_shared")
else()
set(draco_LIBRARIES "draco_static")
endif()
endif()
# Don't build the draco command-line tools by default
set_target_properties(draco_encoder draco_decoder PROPERTIES
EXCLUDE_FROM_ALL TRUE
EXCLUDE_FROM_DEFAULT_BUILD TRUE
)
# Do build the draco shared library
set_target_properties(${draco_LIBRARIES} PROPERTIES
EXCLUDE_FROM_ALL FALSE
EXCLUDE_FROM_DEFAULT_BUILD FALSE
)
TARGET_USE_COMMON_OUTPUT_DIRECTORY(${draco_LIBRARIES})
TARGET_USE_COMMON_OUTPUT_DIRECTORY(draco_encoder)
TARGET_USE_COMMON_OUTPUT_DIRECTORY(draco_decoder)
set(draco_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/draco/src")
# This is probably wrong
INSTALL( TARGETS ${draco_LIBRARIES}
EXPORT "${TARGETS_EXPORT_NAME}"
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
COMPONENT ${LIBASSIMP_COMPONENT}
INCLUDES DESTINATION include
)
ENDIF()
ENDIF()
ENDIF()
# Main assimp code
ADD_SUBDIRECTORY( code/ )
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
# The viewer for windows only
@ -583,7 +674,7 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
ENDIF ()
IF ( ASSIMP_BUILD_SAMPLES)
IF ( ASSIMP_BUILD_SAMPLES )
SET( SAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/samples )
SET( SAMPLES_SHARED_CODE_DIR ${SAMPLES_DIR}/SharedCode )
IF ( WIN32 )

25
Dockerfile 100644
View File

@ -0,0 +1,25 @@
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y \
git cmake build-essential software-properties-common
RUN add-apt-repository ppa:ubuntu-toolchain-r/test && apt-get update && apt-get install -y gcc-4.9 g++-4.9 && \
cd /usr/bin && \
rm gcc g++ cpp && \
ln -s gcc-4.9 gcc && \
ln -s g++-4.9 g++ && \
ln -s cpp-4.9 cpp
WORKDIR /opt
# Build Assimp
RUN git clone https://github.com/assimp/assimp.git /opt/assimp
WORKDIR /opt/assimp
RUN git checkout master \
&& mkdir build && cd build && \
cmake \
-DCMAKE_BUILD_TYPE=Release \
.. && \
make && make install

37
INSTALL
View File

@ -8,43 +8,10 @@ Getting the documentation
------------------------------
A regularly-updated copy is available at
http://assimp.sourceforge.net/lib_html/index.html
A CHM file is included in the SVN repos: ./doc/AssimpDoc_Html/AssimpDoc.chm.
To build the doxygen documentation on your own, follow these steps:
a) download & install latest doxygen
b) make sure doxygen is in the executable search path
c) navigate to ./doc
d) and run 'doxygen'
Open the generated HTML (AssimpDoc_Html/index.html) in the browser of your choice.
Windows only: To generate the CHM doc, install 'Microsoft HTML Workshop'
and configure the path to it in the DOXYFILE first.
https://assimp-docs.readthedocs.io/en/latest/
------------------------------
Building Assimp
------------------------------
More detailed build instructions can be found in the documentation,
this section is just for the inpatient among you.
CMake is the preferred build system for Assimp. The minimum required version
is 2.6. If you don't have it yet, downloads for CMake can be found on
http://www.cmake.org/.
For Unix:
1. mkdir build && cd build
2. cmake .. -G 'Unix Makefiles'
3. make -j4
For Windows:
1. Open a command prompt
2. mkdir build
3. cd build
4. cmake ..
5. cmake --build .
For iOS:
Just check the following project, which deploys a compiler toolchain for different iOS-versions: https://github.com/assimp/assimp/tree/master/port/iOS
Just check the build-instaructions which you can find here: https://github.com/assimp/assimp/blob/master/Build.md

View File

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

View File

@ -8,10 +8,10 @@ A library to import and export various 3d-model-formats including scene-post-pro
<img alt="Coverity Scan Build Status"
src="https://scan.coverity.com/projects/5607/badge.svg"/>
</a>
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/5be56faac64f46fc941ac890fb4febef)](https://www.codacy.com/app/kimkulling/assimp?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
<br>
@ -39,12 +39,13 @@ Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file.
### Ports ###
* [Android](port/AndroidJNI/README.md)
* [Python](port/PyAssimp/README.md)
* [.NET](https://github.com/assimp/assimp-net)
* [.NET](https://bitbucket.org/Starnick/assimpnet/src/master/)
* [Pascal](port/AssimpPascal/Readme.md)
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
* [Unity 3d Plugin](https://www.assetstore.unity3d.com/en/#!/content/91777)
* [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status))
* [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port.
* [Rust](https://github.com/jkvargas/russimp)
### Other tools ###
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
@ -75,9 +76,6 @@ For more information, visit [our website](http://assimp.org/). Or check out the
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)
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
@ -102,15 +100,6 @@ Become a financial contributor and help us sustain our community. [[Contribute](
<a href="https://opencollective.com/assimp"><img src="https://opencollective.com/assimp/individuals.svg?width=890"></a>
Monthly donations via Patreon:
<br>[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/assimp)
<br>
One-off donations via PayPal:
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
<br>
#### Organizations

View File

@ -1,81 +0,0 @@
# AppVeyor file
# http://www.appveyor.com/docs/appveyor-yml
# clone directory
clone_folder: c:\projects\assimp
clone_depth: 1
# branches to build
branches:
# whitelist
only:
- master
matrix:
fast_finish: true
image:
- Visual Studio 2013
#- Visual Studio 2015
#- Visual Studio 2017
- Visual Studio 2019
#- MinGW
platform:
- Win32
- x64
configuration: Release
install:
- set PATH=C:\Ruby24-x64\bin;%PATH%
- set CMAKE_DEFINES -DASSIMP_WERROR=ON
- if [%COMPILER%]==[MinGW] set PATH=C:\MinGW\bin;%PATH%
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2013" set CMAKE_GENERATOR_NAME=Visual Studio 12 2013
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2019" set CMAKE_GENERATOR_NAME=Visual Studio 16 2019
- cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%" -A %platform% .
# Rename sh.exe as sh.exe in PATH interferes with MinGW - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
- rename "C:\Program Files\Git\usr\bin\sh.exe" "sh2.exe"
- set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5"
- ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/5/7/b/57b2947c-7221-4f33-b35e-2fc78cb10df4/vc_redist.x64.exe -OutFile .\packaging\windows-innosetup\vc_redist.x64.exe
- ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/1/d/8/1d8137db-b5bb-4925-8c5d-927424a2e4de/vc_redist.x86.exe -OutFile .\packaging\windows-innosetup\vc_redist.x86.exe
cache:
- code\assimp.dir\%CONFIGURATION%
- contrib\zlib\zlibstatic.dir\%CONFIGURATION%
- contrib\zlib\zlib.dir\%CONFIGURATION%
- tools\assimp_cmd\assimp_cmd.dir\%CONFIGURATION%
- tools\assimp_view\assimp_viewer.dir\%CONFIGURATION%
- test\unit.dir\%CONFIGURATION%
- bin\.mtime_cache
before_build:
- echo NUMBER_OF_PROCESSORS=%NUMBER_OF_PROCESSORS%
- ruby scripts\AppVeyor\mtime_cache -g scripts\AppVeyor\cacheglobs.txt -c bin\.mtime_cache\cache.json
build_script:
cmake --build . --config Release -- /maxcpucount:2
after_build:
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" (
if "%platform%"=="x64" (
iscc packaging\windows-innosetup\script_x64.iss
) else (
iscc packaging\windows-innosetup\script_x86.iss
)
)
- 7z a assimp.7z bin\%CONFIGURATION%\* lib\%CONFIGURATION%\*
test_script:
- cmd: bin\%CONFIGURATION%\unit.exe --gtest_output=xml:testout.xml
on_finish:
- ps: (new-object net.webclient).UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\testout.xml))
artifacts:
- path: assimp.7z
name: assimp_lib

View File

@ -10,5 +10,9 @@ find_package(polyclipping CONFIG REQUIRED)
find_package(zip CONFIG REQUIRED)
find_package(pugixml CONFIG REQUIRED)
if(@ASSIMP_BUILD_DRACO@)
find_package(draco CONFIG REQUIRED)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
check_required_components("@PROJECT_NAME@")

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -212,7 +212,7 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
// Be sure this is only done for the first material
mBackgroundImage = std::string("");
mBackgroundImage = std::string();
}
// At first add the base ambient color of the scene to the material

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -102,13 +102,14 @@ private:
// preserves the mesh's given name if it has one. |index| is the index
// of the mesh in |aiScene::mMeshes|.
std::string GetMeshName(const aiMesh &mesh, unsigned int index, const aiNode &node) {
static const std::string underscore = "_";
static const char underscore = '_';
char postfix[10] = { 0 };
ASSIMP_itoa10(postfix, index);
std::string result = node.mName.C_Str();
if (mesh.mName.length > 0) {
result += underscore + mesh.mName.C_Str();
result += underscore;
result += mesh.mName.C_Str();
}
return result + underscore + postfix;
}
@ -444,7 +445,7 @@ void Discreet3DSExporter::WriteMeshes() {
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
writer.PutU2(count);
for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
const aiVector3D &v = trafo * mesh.mVertices[i];
const aiVector3D &v = mesh.mVertices[i];
writer.PutF4(v.x);
writer.PutF4(v.y);
writer.PutF4(v.z);
@ -506,11 +507,16 @@ void Discreet3DSExporter::WriteMeshes() {
// Transformation matrix by which the mesh vertices have been pre-transformed with.
{
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRMATRIX);
for (unsigned int r = 0; r < 4; ++r) {
// Store rotation 3x3 matrix row wise
for (unsigned int r = 0; r < 3; ++r) {
for (unsigned int c = 0; c < 3; ++c) {
writer.PutF4(trafo[r][c]);
}
}
// Store translation sub vector column wise
for (unsigned int r = 0; r < 3; ++r) {
writer.PutF4(trafo[r][3]);
}
}
}
}

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -61,20 +61,10 @@ namespace D3DS {
#include <assimp/Compiler/pushpack1.h>
// ---------------------------------------------------------------------------
/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
* and data structures.
/** Defines chunks and data structures.
*/
class Discreet3DS {
private:
Discreet3DS() AI_NO_EXCEPT {
// empty
}
namespace Discreet3DS {
~Discreet3DS() {
// empty
}
public:
//! data structure for a single chunk in a .3ds file
struct Chunk {
uint16_t Flag;
@ -314,7 +304,7 @@ public:
// camera sub-chunks
CHUNK_CAM_RANGES = 0x4720
};
};
}
// ---------------------------------------------------------------------------
/** Helper structure representing a 3ds mesh face */

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -164,7 +164,7 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
mRootNode->mHierarchyIndex = -1;
mRootNode->mParent = nullptr;
mMasterScale = 1.0f;
mBackgroundImage = "";
mBackgroundImage = std::string();
bHasBG = false;
bIsPrj = false;
@ -266,6 +266,7 @@ void Discreet3DSImporter::ParseMainChunk() {
case Discreet3DS::CHUNK_PRJ:
bIsPrj = true;
break;
case Discreet3DS::CHUNK_MAIN:
ParseEditorChunk();
break;
@ -323,7 +324,7 @@ void Discreet3DSImporter::ParseObjectChunk() {
case Discreet3DS::CHUNK_MAT_MATERIAL:
// Add a new material to the list
mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + to_string(mScene->mMaterials.size()))));
mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + ai_to_string(mScene->mMaterials.size()))));
ParseMaterialChunk();
break;

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -44,63 +44,66 @@ namespace Assimp {
namespace D3MF {
namespace XmlTag {
// Root tag
const char* const RootTag = "3MF";
// Meta-data
static const std::string meta = "metadata";
static const std::string meta_name = "name";
const char* const meta = "metadata";
const char* const meta_name = "name";
// Model-data specific tags
static const std::string model = "model";
static const std::string model_unit = "unit";
static const std::string metadata = "metadata";
static const std::string resources = "resources";
static const std::string object = "object";
static const std::string mesh = "mesh";
static const std::string components = "components";
static const std::string component = "component";
static const std::string vertices = "vertices";
static const std::string vertex = "vertex";
static const std::string triangles = "triangles";
static const std::string triangle = "triangle";
static const std::string x = "x";
static const std::string y = "y";
static const std::string z = "z";
static const std::string v1 = "v1";
static const std::string v2 = "v2";
static const std::string v3 = "v3";
static const std::string id = "id";
static const std::string pid = "pid";
static const std::string pindex = "pindex";
static const std::string p1 = "p1";
static const std::string name = "name";
static const std::string type = "type";
static const std::string build = "build";
static const std::string item = "item";
static const std::string objectid = "objectid";
static const std::string transform = "transform";
const char* const model = "model";
const char* const model_unit = "unit";
const char* const metadata = "metadata";
const char* const resources = "resources";
const char* const object = "object";
const char* const mesh = "mesh";
const char* const components = "components";
const char* const component = "component";
const char* const vertices = "vertices";
const char* const vertex = "vertex";
const char* const triangles = "triangles";
const char* const triangle = "triangle";
const char* const x = "x";
const char* const y = "y";
const char* const z = "z";
const char* const v1 = "v1";
const char* const v2 = "v2";
const char* const v3 = "v3";
const char* const id = "id";
const char* const pid = "pid";
const char* const pindex = "pindex";
const char* const p1 = "p1";
const char* const name = "name";
const char* const type = "type";
const char* const build = "build";
const char* const item = "item";
const char* const objectid = "objectid";
const char* const transform = "transform";
// Material definitions
static const std::string basematerials = "basematerials";
static const std::string basematerials_id = "id";
static const std::string basematerials_base = "base";
static const std::string basematerials_name = "name";
static const std::string basematerials_displaycolor = "displaycolor";
const char* const basematerials = "basematerials";
const char* const basematerials_id = "id";
const char* const basematerials_base = "base";
const char* const basematerials_name = "name";
const char* const basematerials_displaycolor = "displaycolor";
// Meta info tags
static const std::string CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
static const std::string ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
static const std::string SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
static const std::string SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
static const std::string RELS_RELATIONSHIP_CONTAINER = "Relationships";
static const std::string RELS_RELATIONSHIP_NODE = "Relationship";
static const std::string RELS_ATTRIB_TARGET = "Target";
static const std::string RELS_ATTRIB_TYPE = "Type";
static const std::string RELS_ATTRIB_ID = "Id";
static const std::string PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
static const std::string PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
static const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
static const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
static const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
}
const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
const char* const SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
const char* const SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
const char* const RELS_RELATIONSHIP_CONTAINER = "Relationships";
const char* const RELS_RELATIONSHIP_NODE = "Relationship";
const char* const RELS_ATTRIB_TARGET = "Target";
const char* const RELS_ATTRIB_TYPE = "Type";
const char* const RELS_ATTRIB_ID = "Id";
const char* const PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
const char* const PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
const char* const PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
const char* const PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
const char* const PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
}
} // Namespace D3MF
} // Namespace Assimp

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -237,7 +237,7 @@ void D3MFExporter::writeBaseMaterials() {
aiMaterial *mat = mScene->mMaterials[i];
aiString name;
if (mat->Get(AI_MATKEY_NAME, name) != aiReturn_SUCCESS) {
strName = "basemat_" + to_string(i);
strName = "basemat_" + ai_to_string(i);
} else {
strName = name.C_Str();
}
@ -248,7 +248,7 @@ void D3MFExporter::writeBaseMaterials() {
// rgbs %
if (color.r <= 1 && color.g <= 1 && color.b <= 1 && color.a <= 1) {
hexDiffuseColor = Rgba2Hex(
hexDiffuseColor = ai_rgba2hex(
(int)((ai_real)color.r) * 255,
(int)((ai_real)color.g) * 255,
(int)((ai_real)color.b) * 255,
@ -257,13 +257,13 @@ void D3MFExporter::writeBaseMaterials() {
} else {
hexDiffuseColor = "#";
tmp = DecimalToHexa((ai_real)color.r);
tmp = ai_decimal_to_hexa((ai_real)color.r);
hexDiffuseColor += tmp;
tmp = DecimalToHexa((ai_real)color.g);
tmp = ai_decimal_to_hexa((ai_real)color.g);
hexDiffuseColor += tmp;
tmp = DecimalToHexa((ai_real)color.b);
tmp = ai_decimal_to_hexa((ai_real)color.b);
hexDiffuseColor += tmp;
tmp = DecimalToHexa((ai_real)color.a);
tmp = ai_decimal_to_hexa((ai_real)color.a);
hexDiffuseColor += tmp;
}
} else {
@ -307,18 +307,26 @@ void D3MFExporter::writeMesh(aiMesh *mesh) {
return;
}
mModelOutput << "<" << XmlTag::mesh << ">" << std::endl;
mModelOutput << "<" << XmlTag::vertices << ">" << std::endl;
mModelOutput << "<"
<< XmlTag::mesh
<< ">" << "\n";
mModelOutput << "<"
<< XmlTag::vertices
<< ">" << "\n";
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
writeVertex(mesh->mVertices[i]);
}
mModelOutput << "</" << XmlTag::vertices << ">" << std::endl;
mModelOutput << "</"
<< XmlTag::vertices << ">"
<< "\n";
const unsigned int matIdx(mesh->mMaterialIndex);
writeFaces(mesh, matIdx);
mModelOutput << "</" << XmlTag::mesh << ">" << std::endl;
mModelOutput << "</"
<< XmlTag::mesh << ">"
<< "\n";
}
void D3MFExporter::writeVertex(const aiVector3D &pos) {
@ -334,27 +342,34 @@ void D3MFExporter::writeFaces(aiMesh *mesh, unsigned int matIdx) {
if (!mesh->HasFaces()) {
return;
}
mModelOutput << "<" << XmlTag::triangles << ">" << std::endl;
mModelOutput << "<"
<< XmlTag::triangles << ">"
<< "\n";
for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
aiFace &currentFace = mesh->mFaces[i];
mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[0] << "\" v2=\""
<< currentFace.mIndices[1] << "\" v3=\"" << currentFace.mIndices[2]
<< "\" pid=\"1\" p1=\"" + to_string(matIdx) + "\" />";
mModelOutput << std::endl;
<< "\" pid=\"1\" p1=\"" + ai_to_string(matIdx) + "\" />";
mModelOutput << "\n";
}
mModelOutput << "</" << XmlTag::triangles << ">";
mModelOutput << std::endl;
mModelOutput << "</"
<< XmlTag::triangles
<< ">";
mModelOutput << "\n";
}
void D3MFExporter::writeBuild() {
mModelOutput << "<" << XmlTag::build << ">" << std::endl;
mModelOutput << "<"
<< XmlTag::build
<< ">"
<< "\n";
for (size_t i = 0; i < mBuildItems.size(); ++i) {
mModelOutput << "<" << XmlTag::item << " objectid=\"" << i + 2 << "\"/>";
mModelOutput << std::endl;
mModelOutput << "\n";
}
mModelOutput << "</" << XmlTag::build << ">";
mModelOutput << std::endl;
mModelOutput << "\n";
}
void D3MFExporter::zipContentType(const std::string &filename) {

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -42,6 +42,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
#include "D3MFImporter.h"
#include "3MFXmlTags.h"
#include "D3MFOpcPackage.h"
#include <assimp/StringComparison.h>
#include <assimp/StringUtils.h>
@ -51,17 +53,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/fast_atof.h>
#include <cassert>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "3MFXmlTags.h"
#include "D3MFOpcPackage.h"
#include <assimp/fast_atof.h>
#include <iomanip>
#include <string.h>
namespace Assimp {
namespace D3MF {
@ -72,32 +72,39 @@ enum class ResourceType {
RT_Unknown
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
class Resource
{
class Resource {
public:
Resource(int id) :
mId(id) {}
virtual ~Resource() {}
int mId;
virtual ResourceType getType() {
Resource(int id) :
mId(id) {
// empty
}
virtual ~Resource() {
// empty
}
virtual ResourceType getType() const {
return ResourceType::RT_Unknown;
}
};
class BaseMaterials : public Resource {
public:
BaseMaterials(int id) :
Resource(id),
mMaterials(),
mMaterialIndex() {}
std::vector<aiMaterial *> mMaterials;
std::vector<unsigned int> mMaterialIndex;
virtual ResourceType getType() {
BaseMaterials(int id) :
Resource(id),
mMaterials(),
mMaterialIndex() {
// empty
}
~BaseMaterials() = default;
ResourceType getType() const override {
return ResourceType::RT_BaseMaterials;
}
};
@ -109,24 +116,26 @@ struct Component {
class Object : public Resource {
public:
std::vector<aiMesh*> mMeshes;
std::vector<aiMesh *> mMeshes;
std::vector<unsigned int> mMeshIndex;
std::vector<Component> mComponents;
std::string mName;
Object(int id) :
Resource(id),
mName (std::string("Object_") + to_string(id)){}
mName(std::string("Object_") + ai_to_string(id)) {
// empty
}
virtual ResourceType getType() {
~Object() = default;
ResourceType getType() const override {
return ResourceType::RT_Object;
}
};
class XmlSerializer {
public:
XmlSerializer(XmlParser *xmlParser) :
mResourcesDictionnary(),
mMaterialCount(0),
@ -136,7 +145,7 @@ public:
}
~XmlSerializer() {
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it ) {
delete it->second;
}
}
@ -146,28 +155,28 @@ public:
return;
}
scene->mRootNode = new aiNode("3MF");
scene->mRootNode = new aiNode(XmlTag::RootTag);
XmlNode node = mXmlParser->getRootNode().child("model");
XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
if (node.empty()) {
return;
}
XmlNode resNode = node.child("resources");
for (XmlNode currentNode = resNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentNodeName = currentNode.name();
if (currentNodeName == D3MF::XmlTag::object) {
ReadObject(currentNode);;
} else if (currentNodeName == D3MF::XmlTag::basematerials) {
XmlNode resNode = node.child(XmlTag::resources);
for (auto &currentNode : resNode.children()) {
const std::string currentNodeName = currentNode.name();
if (currentNodeName == XmlTag::object) {
ReadObject(currentNode);
} else if (currentNodeName == XmlTag::basematerials) {
ReadBaseMaterials(currentNode);
} else if (currentNodeName == D3MF::XmlTag::meta) {
} else if (currentNodeName == XmlTag::meta) {
ReadMetadata(currentNode);
}
}
XmlNode buildNode = node.child("build");
for (XmlNode currentNode = buildNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentNodeName = currentNode.name();
if (currentNodeName == D3MF::XmlTag::item) {
XmlNode buildNode = node.child(XmlTag::build);
for (auto &currentNode : buildNode.children()) {
const std::string currentNodeName = currentNode.name();
if (currentNodeName == XmlTag::item) {
int objectId = -1;
std::string transformationMatrixStr;
aiMatrix4x4 transformationMatrix;
@ -186,10 +195,9 @@ public:
}
}
// import the metadata
if (!mMetaData.empty()) {
const size_t numMeta(mMetaData.size());
const size_t numMeta = mMetaData.size();
scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
for (size_t i = 0; i < numMeta; ++i) {
aiString val(mMetaData[i].value);
@ -201,22 +209,22 @@ public:
scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
if (scene->mNumMeshes != 0) {
scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
if (it->second->getType() == ResourceType::RT_Object) {
Object *obj = static_cast<Object*>(it->second);
Object *obj = static_cast<Object *>(it->second);
ai_assert(nullptr != obj);
for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
}
}
}
}
// import the materials
scene->mNumMaterials = static_cast<unsigned int>(mMaterialCount);
scene->mNumMaterials = mMaterialCount;
if (scene->mNumMaterials != 0) {
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
for (unsigned int i = 0; i < baseMaterials->mMaterials.size(); ++i) {
@ -228,35 +236,36 @@ public:
}
private:
void addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform) {
ai_assert(nullptr != obj);
void addObjectToNode(aiNode* parent, Object* obj, aiMatrix4x4 nodeTransform) {
aiNode *sceneNode = new aiNode(obj->mName);
sceneNode->mNumMeshes = static_cast<unsigned int>(obj->mMeshes.size());
sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes];
std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes);
sceneNode->mTransformation = nodeTransform;
parent->addChildren(1, &sceneNode);
if (nullptr != parent) {
parent->addChildren(1, &sceneNode);
}
for (size_t i = 0; i < obj->mComponents.size(); ++i) {
Component c = obj->mComponents[i];
auto it = mResourcesDictionnary.find(c.mObjectId);
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
addObjectToNode(sceneNode, static_cast<Object*>(it->second), c.mTransformation);
addObjectToNode(sceneNode, static_cast<Object *>(it->second), c.mTransformation);
}
}
}
bool getNodeAttribute(const XmlNode& node, const std::string& attribute, std::string& value) {
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, std::string &value) {
pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str());
if (!objectAttribute.empty()) {
value = objectAttribute.as_string();
return true;
} else {
return false;
}
return false;
}
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
@ -265,9 +274,9 @@ private:
if (ret) {
value = std::atoi(strValue.c_str());
return true;
} else {
return false;
}
}
return false;
}
aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
@ -287,7 +296,7 @@ private:
}
}
if (currentNumber.size() > 0) {
float f = std::stof(currentNumber);
const float f = std::stof(currentNumber);
numbers.push_back(f);
}
@ -311,29 +320,26 @@ private:
transformMatrix.b4 = numbers[10];
transformMatrix.c4 = numbers[11];
transformMatrix.d4 = 1;
return transformMatrix;
}
void ReadObject(XmlNode &node) {
int id = -1, pid = -1, pindex = -1;
bool hasId = getNodeAttribute(node, D3MF::XmlTag::id, id);
//bool hasType = getNodeAttribute(node, D3MF::XmlTag::type, type); not used currently
bool hasPid = getNodeAttribute(node, D3MF::XmlTag::pid, pid);
bool hasPindex = getNodeAttribute(node, D3MF::XmlTag::pindex, pindex);
std::string idStr = to_string(id);
bool hasId = getNodeAttribute(node, XmlTag::id, id);
bool hasPid = getNodeAttribute(node, XmlTag::pid, pid);
bool hasPindex = getNodeAttribute(node, XmlTag::pindex, pindex);
if (!hasId) {
return;
}
Object *obj = new Object(id);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::mesh) {
auto mesh = ReadMesh(currentNode);
mesh->mName.Set(idStr);
mesh->mName.Set(ai_to_string(id));
if (hasPid) {
auto it = mResourcesDictionnary.find(pid);
@ -347,8 +353,9 @@ private:
obj->mMeshIndex.push_back(mMeshCount);
mMeshCount++;
} else if (currentName == D3MF::XmlTag::components) {
for (XmlNode currentSubNode = currentNode.first_child(); currentSubNode; currentSubNode = currentSubNode.next_sibling()) {
if (currentSubNode.name() == D3MF::XmlTag::component) {
for (XmlNode &currentSubNode : currentNode.children()) {
const std::string subNodeName = currentSubNode.name();
if (subNodeName == D3MF::XmlTag::component) {
int objectId = -1;
std::string componentTransformStr;
aiMatrix4x4 componentTransform;
@ -356,8 +363,9 @@ private:
componentTransform = parseTransformMatrix(componentTransformStr);
}
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId))
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) {
obj->mComponents.push_back({ objectId, componentTransform });
}
}
}
}
@ -369,21 +377,20 @@ private:
aiMesh *ReadMesh(XmlNode &node) {
aiMesh *mesh = new aiMesh();
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::vertices) {
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::vertices) {
ImportVertices(currentNode, mesh);
} else if (currentName == D3MF::XmlTag::triangles) {
} else if (currentName == XmlTag::triangles) {
ImportTriangles(currentNode, mesh);
}
}
return mesh;
}
void ReadMetadata(XmlNode &node) {
pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name.c_str());
pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name);
const std::string name = attribute.as_string();
const std::string value = node.value();
if (name.empty()) {
@ -398,9 +405,9 @@ private:
void ImportVertices(XmlNode &node, aiMesh *mesh) {
std::vector<aiVector3D> vertices;
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::vertex) {
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::vertex) {
vertices.push_back(ReadVertex(currentNode));
}
}
@ -412,29 +419,28 @@ private:
aiVector3D ReadVertex(XmlNode &node) {
aiVector3D vertex;
vertex.x = ai_strtof(node.attribute(D3MF::XmlTag::x.c_str()).as_string(), nullptr);
vertex.y = ai_strtof(node.attribute(D3MF::XmlTag::y.c_str()).as_string(), nullptr);
vertex.z = ai_strtof(node.attribute(D3MF::XmlTag::z.c_str()).as_string(), nullptr);
vertex.x = ai_strtof(node.attribute(XmlTag::x).as_string(), nullptr);
vertex.y = ai_strtof(node.attribute(XmlTag::y).as_string(), nullptr);
vertex.z = ai_strtof(node.attribute(XmlTag::z).as_string(), nullptr);
return vertex;
}
void ImportTriangles(XmlNode &node, aiMesh *mesh) {
std::vector<aiFace> faces;
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::triangle) {
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::triangle) {
aiFace face = ReadTriangle(currentNode);
faces.push_back(face);
int pid, p1;
int pid = 0, p1 = 0;
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
if (hasPid && hasP1) {
auto it = mResourcesDictionnary.find(pid);
if (it != mResourcesDictionnary.end())
{
if (it != mResourcesDictionnary.end()) {
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
@ -457,9 +463,9 @@ private:
face.mNumIndices = 3;
face.mIndices = new unsigned int[face.mNumIndices];
face.mIndices[0] = static_cast<unsigned int>(std::atoi(node.attribute(D3MF::XmlTag::v1.c_str()).as_string()));
face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(D3MF::XmlTag::v2.c_str()).as_string()));
face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(D3MF::XmlTag::v3.c_str()).as_string()));
face.mIndices[0] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v1).as_string()));
face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
return face;
}
@ -467,14 +473,14 @@ private:
void ReadBaseMaterials(XmlNode &node) {
int id = -1;
if (getNodeAttribute(node, D3MF::XmlTag::basematerials_id, id)) {
BaseMaterials* baseMaterials = new BaseMaterials(id);
BaseMaterials *baseMaterials = new BaseMaterials(id);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling())
{
if (currentNode.name() == D3MF::XmlTag::basematerials_base) {
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::basematerials_base) {
baseMaterials->mMaterialIndex.push_back(mMaterialCount);
baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id));
mMaterialCount++;
++mMaterialCount;
}
}
@ -488,7 +494,7 @@ private:
}
//format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
const size_t len(strlen(color));
const size_t len = strlen(color);
if (9 != len && 7 != len) {
return false;
}
@ -517,7 +523,7 @@ private:
}
void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
const char *color = node.attribute(D3MF::XmlTag::basematerials_displaycolor.c_str()).as_string();
const char *color = node.attribute(XmlTag::basematerials_displaycolor).as_string();
aiColor4D diffuse;
if (parseColor(color, diffuse)) {
mat->AddProperty<aiColor4D>(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
@ -531,7 +537,7 @@ private:
bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
std::string stdMaterialName;
std::string strId(to_string(basematerialsId));
const std::string strId(ai_to_string(basematerialsId));
stdMaterialName += "id";
stdMaterialName += strId;
stdMaterialName += "_";
@ -539,7 +545,7 @@ private:
stdMaterialName += std::string(name);
} else {
stdMaterialName += "basemat_";
stdMaterialName += to_string(mMaterialCount - basematerialsId);
stdMaterialName += ai_to_string(mMaterialCount - basematerialsId);
}
aiString assimpMaterialName(stdMaterialName);
@ -556,13 +562,15 @@ private:
std::string value;
};
std::vector<MetaEntry> mMetaData;
std::map<unsigned int, Resource*> mResourcesDictionnary;
std::map<unsigned int, Resource *> mResourcesDictionnary;
unsigned int mMaterialCount, mMeshCount;
XmlParser *mXmlParser;
};
} //namespace D3MF
using namespace D3MF;
static const aiImporterDesc desc = {
"3mf Importer",
"",
@ -596,7 +604,7 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
return false;
}
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
D3MFOpcPackage opcPackage(pIOHandler, filename);
return opcPackage.validate();
}
@ -612,11 +620,11 @@ const aiImporterDesc *D3MFImporter::GetInfo() const {
}
void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) {
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
D3MFOpcPackage opcPackage(pIOHandler, filename);
XmlParser xmlParser;
if (xmlParser.parse(opcPackage.RootStream())) {
D3MF::XmlSerializer xmlSerializer(&xmlParser);
XmlSerializer xmlSerializer(&xmlParser);
xmlSerializer.ImportXml(pScene);
}
}

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -47,9 +47,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
/// @brief The 3MF-importer class.
class D3MFImporter : public BaseImporter {
public:
// BaseImporter interface
D3MFImporter();
~D3MFImporter();
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -103,9 +103,9 @@ public:
std::string name = currentNode.name();
if (name == "Relationship") {
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID.c_str()).as_string();
relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE.c_str()).as_string();
relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET.c_str()).as_string();
relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID).as_string();
relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string();
relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string();
if (validateRels(relPtr)) {
m_relationShips.push_back(relPtr);
}
@ -156,7 +156,7 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
mRootStream = mZipArchive->Open(rootFile.c_str());
ai_assert(mRootStream != nullptr);
if (nullptr == mRootStream) {
throw DeadlyExportError("Cannot open root-file in archive : " + rootFile);
throw DeadlyImportError("Cannot open root-file in archive : " + rootFile);
}
} else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
@ -188,7 +188,7 @@ bool D3MFOpcPackage::validate() {
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
XmlParser xmlParser;
if (!xmlParser.parse(stream)) {
return "";
return std::string();
}
OpcPackageRelationshipReader reader(xmlParser);

View File

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

View File

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

View File

@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -117,16 +116,16 @@ public:
Mask = 0xf,
};
inline constexpr uint8_t GetType() const { return (flags & Mask); }
inline uint8_t GetType() const { return (flags & Mask); }
};
// Represents an AC3D object
struct Object {
Object() :
type(World),
name(""),
name(),
children(),
texture(""),
texture(),
texRepeat(1.f, 1.f),
texOffset(0.0f, 0.0f),
rotation(),

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -39,19 +39,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/// \file AMFImporter.cpp
/// \brief AMF-format files importer for Assimp: main algorithm implementation.
/// \date 2016
/// \author smal.root@gmail.com
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
// Header files, Assimp.
#include "AMFImporter.hpp"
#include "AMFImporter_Macro.hpp"
#include <assimp/DefaultIOSystem.h>
#include <assimp/fast_atof.h>
#include <assimp/StringUtils.h>
// Header files, stdlib.
#include <memory>
@ -306,13 +301,14 @@ void AMFImporter::ParseNode_Root() {
throw DeadlyImportError("Root node \"amf\" not found.");
}
XmlNode node = *root;
mUnit = node.attribute("unit").as_string();
mUnit = ai_tolower(std::string(node.attribute("unit").as_string()));
mVersion = node.attribute("version").as_string();
// Read attributes for node <amf>.
// Check attributes
if (!mUnit.empty()) {
if ((mUnit != "inch") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) {
if ((mUnit != "inch") && (mUnit != "millimeters") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) {
Throw_IncorrectAttrValue("unit", mUnit);
}
}
@ -407,20 +403,20 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
for (auto &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "deltax") {
als.Delta.x = (ai_real)std::atof(currentNode.value());
XmlParser::getValueAsFloat(currentNode, als.Delta.x);
} else if (currentName == "deltay") {
als.Delta.y = (ai_real)std::atof(currentNode.value());
XmlParser::getValueAsFloat(currentNode, als.Delta.y);
} else if (currentName == "deltaz") {
als.Delta.z = (ai_real)std::atof(currentNode.value());
XmlParser::getValueAsFloat(currentNode, als.Delta.z);
} else if (currentName == "rx") {
als.Delta.x = (ai_real)std::atof(currentNode.value());
XmlParser::getValueAsFloat(currentNode, als.Delta.x);
} else if (currentName == "ry") {
als.Delta.y = (ai_real)std::atof(currentNode.value());
XmlParser::getValueAsFloat(currentNode, als.Delta.y);
} else if (currentName == "rz") {
als.Delta.z = (ai_real)std::atof(currentNode.value());
XmlParser::getValueAsFloat(currentNode, als.Delta.z);
}
}
ParseHelper_Node_Exit();
@ -456,7 +452,7 @@ void AMFImporter::ParseNode_Object(XmlNode &node) {
// Check for child nodes
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
for (auto &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "color") {
ParseNode_Color(currentNode);
@ -521,10 +517,6 @@ bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool p
return false;
}
void AMFImporter::GetExtensionList(std::set<std::string> &pExtensionList) {
pExtensionList.insert("amf");
}
const aiImporterDesc *AMFImporter::GetInfo() const {
return &Description;
}

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -277,7 +277,6 @@ public:
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
void ParseHelper_Node_Exit();
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
void GetExtensionList(std::set<std::string> &pExtensionList);
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
const aiImporterDesc *GetInfo() const;
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -39,16 +39,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/// \file AMFImporter_Geometry.cpp
/// \brief Parsing data from geometry nodes.
/// \date 2016
/// \author smal.root@gmail.com
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
#include "AMFImporter.hpp"
#include "AMFImporter_Macro.hpp"
#include <assimp/ParsingUtils.h>
namespace Assimp {
@ -61,12 +54,12 @@ namespace Assimp {
void AMFImporter::ParseNode_Mesh(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// create new mesh object.
ne = new AMFMesh(mNodeElement_Cur);
// Check for child nodes
if (0 != ASSIMP_stricmp(node.name(), "mesh")) {
return;
}
// create new mesh object.
ne = new AMFMesh(mNodeElement_Cur);
bool found_verts = false, found_volumes = false;
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
@ -103,18 +96,18 @@ void AMFImporter::ParseNode_Vertices(XmlNode &node) {
// create new mesh object.
ne = new AMFVertices(mNodeElement_Cur);
// Check for child nodes
pugi::xml_node vertexNode = node.child("vertex");
if (!vertexNode.empty()) {
ParseHelper_Node_Enter(ne);
ParseNode_Vertex(vertexNode);
ParseHelper_Node_Exit();
} else {
if (node.empty()) {
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
} // if(!mReader->isEmptyElement()) else
return;
}
ParseHelper_Node_Enter(ne);
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "vertex") {
ParseNode_Vertex(currentNode);
}
}
ParseHelper_Node_Exit();
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
}
@ -166,27 +159,25 @@ void AMFImporter::ParseNode_Vertex(XmlNode &node) {
// X, Y, or Z coordinate, respectively, of a vertex position in space.
void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// create new color object.
ne = new AMFCoordinates(mNodeElement_Cur);
AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
if (!node.empty()) {
ne = new AMFCoordinates(mNodeElement_Cur);
ParseHelper_Node_Enter(ne);
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "X") {
// create new color object.
AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
const std::string &currentName = ai_tolower(currentNode.name());
if (currentName == "x") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.x);
} else if (currentName == "Y") {
} else if (currentName == "y") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.y);
} else if (currentName == "Z") {
} else if (currentName == "z") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.z);
}
}
ParseHelper_Node_Exit();
} else {
mNodeElement_Cur->Child.push_back(ne);
mNodeElement_Cur->Child.push_back(new AMFCoordinates(mNodeElement_Cur));
}
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
@ -194,7 +185,7 @@ void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
// <volume
// materialid="" - Which material to use.
// type="" - What this volume describes can be “region” or “support”. If none specified, “object” is assumed. If support, then the geometric
// type="" - What this volume describes can be "region" or "support". If none specified, "object" is assumed. If support, then the geometric
// requirements 1-8 listed in section 5 do not need to be maintained.
// >
// </volume>
@ -216,7 +207,7 @@ void AMFImporter::ParseNode_Volume(XmlNode &node) {
bool col_read = false;
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
for (auto &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == "color") {
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <volume>.");
@ -258,7 +249,8 @@ void AMFImporter::ParseNode_Triangle(XmlNode &node) {
bool col_read = false;
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
std::string v;
for (auto &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == "color") {
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <triangle>.");
@ -269,11 +261,14 @@ void AMFImporter::ParseNode_Triangle(XmlNode &node) {
} else if (currentName == "map") {
ParseNode_TexMap(currentNode, true);
} else if (currentName == "v1") {
als.V[0] = std::atoi(currentNode.value());
XmlParser::getValueAsString(currentNode, v);
als.V[0] = std::atoi(v.c_str());
} else if (currentName == "v2") {
als.V[1] = std::atoi(currentNode.value());
XmlParser::getValueAsString(currentNode, v);
als.V[1] = std::atoi(v.c_str());
} else if (currentName == "v3") {
als.V[2] = std::atoi(currentNode.value());
XmlParser::getValueAsString(currentNode, v);
als.V[2] = std::atoi(v.c_str());
}
}
ParseHelper_Node_Exit();

View File

@ -1,164 +0,0 @@
/*
---------------------------------------------------------------------------
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 AMFImporter_Macro.hpp
/// \brief Useful macrodefines.
/// \date 2016
/// \author smal.root@gmail.com
#pragma once
#ifndef AMFIMPORTER_MACRO_HPP_INCLUDED
#define AMFIMPORTER_MACRO_HPP_INCLUDED
/// \def MACRO_ATTRREAD_LOOPBEG
/// Begin of loop that read attributes values.
#define MACRO_ATTRREAD_LOOPBEG \
for(int idx = 0, idx_end = mReader->getAttributeCount(); idx < idx_end; idx++) \
{ \
std::string an(mReader->getAttributeName(idx));
/// \def MACRO_ATTRREAD_LOOPEND
/// End of loop that read attributes values.
#define MACRO_ATTRREAD_LOOPEND \
Throw_IncorrectAttr(an); \
}
/// \def MACRO_ATTRREAD_LOOPEND_WSKIP
/// End of loop that read attributes values. Difference from \ref MACRO_ATTRREAD_LOOPEND in that: current macro skip unknown attributes, but
/// \ref MACRO_ATTRREAD_LOOPEND throw an exception.
#define MACRO_ATTRREAD_LOOPEND_WSKIP \
continue; \
}
/// \def MACRO_ATTRREAD_CHECK_REF
/// Check current attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
/// "continue" will called.
/// \param [in] pAttrName - attribute name.
/// \param [out] pVarName - output variable name.
/// \param [in] pFunction - function which read attribute value and write it to pVarName.
#define MACRO_ATTRREAD_CHECK_REF(pAttrName, pVarName, pFunction) \
if(an == pAttrName) \
{ \
pFunction(idx, pVarName); \
continue; \
}
/// \def MACRO_ATTRREAD_CHECK_RET
/// Check current attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
/// If result was read then "continue" will called.
/// \param [in] pAttrName - attribute name.
/// \param [out] pVarName - output variable name.
/// \param [in] pFunction - function which read attribute value and write it to pVarName.
#define MACRO_ATTRREAD_CHECK_RET(pAttrName, pVarName, pFunction) \
if(an == pAttrName) \
{ \
pVarName = pFunction(idx); \
continue; \
}
/// \def MACRO_NODECHECK_LOOPBEGIN(pNodeName)
/// Begin of loop of parsing child nodes. Do not add ';' at end.
/// \param [in] pNodeName - current node name.
#define MACRO_NODECHECK_LOOPBEGIN(pNodeName) \
do { \
bool close_found = false; \
\
while(mReader->read()) \
{ \
if(mReader->getNodeType() == irr::io::EXN_ELEMENT) \
{
/// \def MACRO_NODECHECK_LOOPEND(pNodeName)
/// End of loop of parsing child nodes.
/// \param [in] pNodeName - current node name.
#define MACRO_NODECHECK_LOOPEND(pNodeName) \
XML_CheckNode_SkipUnsupported(pNodeName); \
}/* if(mReader->getNodeType() == irr::io::EXN_ELEMENT) */ \
else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) \
{ \
if(XML_CheckNode_NameEqual(pNodeName)) \
{ \
close_found = true; \
\
break; \
} \
}/* else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) */ \
}/* while(mReader->read()) */ \
\
if(!close_found) Throw_CloseNotFound(pNodeName); \
\
} while(false)
/// \def MACRO_NODECHECK_READCOMP_F
/// Check current node name and if it equal to requested then read value. Result write to output variable of type "float".
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
/// \param [in] pNodeName - node name.
/// \param [in, out] pReadFlag - read flag.
/// \param [out] pVarName - output variable name.
#define MACRO_NODECHECK_READCOMP_F(pNodeName, pReadFlag, pVarName) \
if(XML_CheckNode_NameEqual(pNodeName)) \
{ \
/* Check if field already read before. */ \
if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
/* Read color component and assign it to object. */ \
pVarName = XML_ReadNode_GetVal_AsFloat(); \
pReadFlag = true; \
continue; \
}
/// \def MACRO_NODECHECK_READCOMP_U32
/// Check current node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
/// \param [in] pNodeName - node name.
/// \param [in, out] pReadFlag - read flag.
/// \param [out] pVarName - output variable name.
#define MACRO_NODECHECK_READCOMP_U32(pNodeName, pReadFlag, pVarName) \
if(XML_CheckNode_NameEqual(pNodeName)) \
{ \
/* Check if field already read before. */ \
if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
/* Read color component and assign it to object. */ \
pVarName = XML_ReadNode_GetVal_AsU32(); \
pReadFlag = true; \
continue; \
}
#endif // AMFIMPORTER_MACRO_HPP_INCLUDED

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -65,48 +65,45 @@ namespace Assimp {
// Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
// values can be specified as constants, or as a formula depending on the coordinates.
void AMFImporter::ParseNode_Color(XmlNode &node) {
std::string profile = node.attribute("profile").as_string();
// create new color object.
AMFNodeElementBase *ne = new AMFColor(mNodeElement_Cur);
AMFColor& als = *((AMFColor*)ne);// alias for convenience
if (node.empty()) {
return;
}
als.Profile = profile;
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
bool read_flag[4] = { false, false, false, false };
for (pugi::xml_node &child : node.children()) {
std::string name = child.name();
if ( name == "r") {
read_flag[0] = true;
XmlParser::getValueAsFloat(child, als.Color.r);
} else if (name == "g") {
read_flag[1] = true;
XmlParser::getValueAsFloat(child, als.Color.g);
} else if (name == "b") {
read_flag[2] = true;
XmlParser::getValueAsFloat(child, als.Color.b);
} else if (name == "a") {
read_flag[3] = true;
XmlParser::getValueAsFloat(child, als.Color.a);
}
ParseHelper_Node_Exit();
const std::string &profile = node.attribute("profile").as_string();
bool read_flag[4] = { false, false, false, false };
AMFNodeElementBase *ne = new AMFColor(mNodeElement_Cur);
AMFColor &als = *((AMFColor *)ne); // alias for convenience
ParseHelper_Node_Enter(ne);
for (pugi::xml_node &child : node.children()) {
// create new color object.
als.Profile = profile;
const std::string &name = child.name();
if ( name == "r") {
read_flag[0] = true;
XmlParser::getValueAsFloat(child, als.Color.r);
} else if (name == "g") {
read_flag[1] = true;
XmlParser::getValueAsFloat(child, als.Color.g);
} else if (name == "b") {
read_flag[2] = true;
XmlParser::getValueAsFloat(child, als.Color.b);
} else if (name == "a") {
read_flag[3] = true;
XmlParser::getValueAsFloat(child, als.Color.a);
}
// check that all components was defined
if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
throw DeadlyImportError("Not all color components are defined.");
}
// check if <a> is absent. Then manually add "a == 1".
if (!read_flag[3]) {
als.Color.a = 1;
}
} else {
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
// check if <a> is absent. Then manually add "a == 1".
if (!read_flag[3]) {
als.Color.a = 1;
}
}
als.Composed = false;
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
ParseHelper_Node_Exit();
// check that all components was defined
if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
throw DeadlyImportError("Not all color components are defined.");
}
als.Composed = false;
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
}
// <material
@ -158,38 +155,36 @@ void AMFImporter::ParseNode_Material(XmlNode &node) {
// Multi elements - Yes.
// Parent element - <amf>.
void AMFImporter::ParseNode_Texture(XmlNode &node) {
std::string id = node.attribute("id").as_string();
uint32_t width = node.attribute("width").as_uint();
uint32_t height = node.attribute("height").as_uint();
uint32_t depth = node.attribute("depth").as_uint();
std::string type = node.attribute("type").as_string();
const std::string id = node.attribute("id").as_string();
const uint32_t width = node.attribute("width").as_uint();
const uint32_t height = node.attribute("height").as_uint();
uint32_t depth = node.attribute("depth").as_uint();
const std::string type = node.attribute("type").as_string();
bool tiled = node.attribute("tiled").as_bool();
// create new texture object.
AMFNodeElementBase *ne = new AMFTexture(mNodeElement_Cur);
AMFTexture& als = *((AMFTexture*)ne);// alias for convenience
if (node.empty()) {
return;
}
std::string enc64_data = node.value();
// Check for child nodes
// create new texture object.
AMFNodeElementBase *ne = new AMFTexture(mNodeElement_Cur);
AMFTexture& als = *((AMFTexture*)ne);// alias for convenience
std::string enc64_data;
XmlParser::getValueAsString(node, enc64_data);
// Check for child nodes
// check that all components was defined
if (id.empty()) {
throw DeadlyImportError("ID for texture must be defined.");
}
if (width < 1) {
throw DeadlyImportError("INvalid width for texture.");
throw DeadlyImportError("Invalid width for texture.");
}
if (height < 1) {
throw DeadlyImportError("Invalid height for texture.");
}
if (depth < 1) {
throw DeadlyImportError("Invalid depth for texture.");
}
if (type != "grayscale") {
throw DeadlyImportError("Invalid type for texture.");
}
@ -203,7 +198,9 @@ void AMFImporter::ParseNode_Texture(XmlNode &node) {
als.Depth = depth;
als.Tiled = tiled;
ParseHelper_Decode_Base64(enc64_data, als.Data);
if (depth == 0) {
depth = (uint32_t)(als.Data.size() / (width * height));
}
// check data size
if ((width * height * depth) != als.Data.size()) {
throw DeadlyImportError("Texture has incorrect data size.");
@ -233,20 +230,18 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
AMFTexMap &als = *((AMFTexMap *)ne); //
std::string rtexid, gtexid, btexid, atexid;
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "rtexid") {
XmlParser::getValueAsString(node, rtexid);
} else if (currentName == "gtexid") {
XmlParser::getValueAsString(node, gtexid);
} else if (currentName == "btexid") {
XmlParser::getValueAsString(node, btexid);
} else if (currentName == "atexid") {
XmlParser::getValueAsString(node, atexid);
for (pugi::xml_attribute &attr : node.attributes()) {
const std::string &currentAttr = attr.name();
if (currentAttr == "rtexid") {
rtexid = attr.as_string();
} else if (currentAttr == "gtexid") {
gtexid = attr.as_string();
} else if (currentAttr == "btexid") {
btexid = attr.as_string();
} else if (currentAttr == "atexid") {
atexid = attr.as_string();
}
}
ParseHelper_Node_Exit();
}
// create new texture coordinates object, alias for convenience
@ -256,7 +251,6 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
}
// Check for children nodes
//XML_CheckNode_MustHaveChildren();
if (node.children().begin() == node.children().end()) {
throw DeadlyImportError("Invalid children definition.");
}
@ -264,28 +258,31 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
bool read_flag[6] = { false, false, false, false, false, false };
if (!pUseOldName) {
for (pugi::xml_attribute &attr : node.attributes()) {
const std::string name = attr.name();
ParseHelper_Node_Enter(ne);
for ( XmlNode &currentNode : node.children()) {
const std::string &name = currentNode.name();
if (name == "utex1") {
read_flag[0] = true;
als.TextureCoordinate[0].x = attr.as_float();
XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].x);
} else if (name == "utex2") {
read_flag[1] = true;
als.TextureCoordinate[1].x = attr.as_float();
XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].x);
} else if (name == "utex3") {
read_flag[2] = true;
als.TextureCoordinate[2].x = attr.as_float();
XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].x);
} else if (name == "vtex1") {
read_flag[3] = true;
als.TextureCoordinate[0].y = attr.as_float();
XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].y);
} else if (name == "vtex2") {
read_flag[4] = true;
als.TextureCoordinate[1].y = attr.as_float();
XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].y);
} else if (name == "vtex3") {
read_flag[5] = true;
als.TextureCoordinate[0].y = attr.as_float();
XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].y);
}
}
ParseHelper_Node_Exit();
} else {
for (pugi::xml_attribute &attr : node.attributes()) {
const std::string name = attr.name();

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -240,7 +240,7 @@ struct AMFVertices : public AMFNodeElementBase {
/// Structure that define volume node.
struct AMFVolume : public AMFNodeElementBase {
std::string MaterialID; ///< Which material to use.
std::string Type; ///< What this volume describes can be “region” or “support”. If none specified, “object” is assumed.
std::string Type; ///< What this volume describes can be "region" or "support". If none specified, "object" is assumed.
/// Constructor.
/// \param [in] pParent - pointer to parent node.

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -62,12 +62,14 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
// Check if stored data are supported.
if (!Composition.empty()) {
throw DeadlyImportError("IME. GetColor for composition");
} else if (Color->Composed) {
throw DeadlyImportError("IME. GetColor, composed color");
} else {
tcol = Color->Color;
}
if (Color->Composed) {
throw DeadlyImportError("IME. GetColor, composed color");
}
tcol = Color->Color;
// Check if default color must be used
if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) {
tcol.r = 0.5f;
@ -79,13 +81,13 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
return tcol;
}
void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElement, std::vector<aiVector3D> &pVertexCoordinateArray,
void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &nodeElement, std::vector<aiVector3D> &vertexCoordinateArray,
std::vector<AMFColor *> &pVertexColorArray) const {
AMFVertices *vn = nullptr;
size_t col_idx;
// All data stored in "vertices", search for it.
for (AMFNodeElementBase *ne_child : pNodeElement.Child) {
for (AMFNodeElementBase *ne_child : nodeElement.Child) {
if (ne_child->Type == AMFNodeElementBase::ENET_Vertices) {
vn = (AMFVertices*)ne_child;
}
@ -97,7 +99,7 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElem
}
// all coordinates stored as child and we need to reserve space for future push_back's.
pVertexCoordinateArray.reserve(vn->Child.size());
vertexCoordinateArray.reserve(vn->Child.size());
// colors count equal vertices count.
pVertexColorArray.resize(vn->Child.size());
@ -112,7 +114,7 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElem
for (AMFNodeElementBase *vtx : vn_child->Child) {
if (vtx->Type == AMFNodeElementBase::ENET_Coordinates) {
pVertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate);
vertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate);
continue;
}
@ -329,8 +331,8 @@ void AMFImporter::Postprocess_AddMetadata(const AMFMetaDataArray &metadataList,
sceneNode.mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(metadataList.size()));
size_t meta_idx(0);
for (const AMFMetadata &metadata : metadataList) {
sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata.Type, aiString(metadata.Value));
for (const AMFMetadata *metadata : metadataList) {
sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata->Type, aiString(metadata->Value));
}
}
@ -426,10 +428,10 @@ void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const st
if (pBiggerThan != nullptr) {
bool found = false;
const size_t biggerThan = *pBiggerThan;
for (const SComplexFace &face : pFaceList) {
for (size_t idx_vert = 0; idx_vert < face.Face.mNumIndices; idx_vert++) {
if (face.Face.mIndices[idx_vert] > *pBiggerThan) {
if (face.Face.mIndices[idx_vert] > biggerThan) {
rv = face.Face.mIndices[idx_vert];
found = true;
break;
@ -873,7 +875,7 @@ nl_clean_loop:
pScene->mNumMaterials = static_cast<unsigned int>(mTexture_Converted.size());
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
for (const SPP_Texture &tex_convd : mTexture_Converted) {
const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + to_string(idx));
const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + ai_to_string(idx));
const int mode = aiTextureOp_Multiply;
const int repeat = tex_convd.Tiled ? 1 : 0;

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team

View File

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

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
@ -685,7 +685,7 @@ void Parser::ParseLV3MapBlock(Texture &map) {
// Files with 'None' as map name are produced by
// an Maja to ASE exporter which name I forgot ..
ASSIMP_LOG_WARN("ASE: Skipping invalid map entry");
map.mMapName = "";
map.mMapName = std::string();
}
continue;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -66,19 +66,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// zlib is needed for compressed blend files
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
#include <zlib.h>
#else
#include "../contrib/zlib/zlib.h"
#endif
# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
# else
# include "../contrib/zlib/zlib.h"
# endif
#endif
namespace Assimp {
template <>
const char *LogFunctions<BlenderImporter>::Prefix() {
static auto prefix = "BLEND: ";
return prefix;
}
} // namespace Assimp
using namespace Assimp;
@ -86,7 +88,7 @@ using namespace Assimp::Blender;
using namespace Assimp::Formatter;
static const aiImporterDesc blenderDesc = {
"Blender 3D Importer \nhttp://www.blender3d.org",
"Blender 3D Importer (http://www.blender3d.org)",
"",
"",
"No animation support yet",
@ -122,17 +124,12 @@ bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bo
return true;
}
else if ((!extension.length() || checkSig) && pIOHandler) {
if ((!extension.length() || checkSig) && pIOHandler) {
// note: this won't catch compressed files
return SearchFileHeaderForToken(pIOHandler, pFile, TokensForSearch, 1);
}
return false;
}
// ------------------------------------------------------------------------------------------------
// List all extensions handled by this loader
void BlenderImporter::GetExtensionList(std::set<std::string> &app) {
app.insert("blend");
return false;
}
// ------------------------------------------------------------------------------------------------
@ -252,7 +249,7 @@ void BlenderImporter::InternReadFile(const std::string &pFile,
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ParseBlendFile(FileDatabase &out, std::shared_ptr<IOStream> stream) {
out.reader = std::shared_ptr<StreamReaderAny>(new StreamReaderAny(stream, out.little));
out.reader = std::make_shared<StreamReaderAny>(stream, out.little);
DNAParser dna_reader(out);
const DNA *dna = nullptr;

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -110,7 +110,6 @@ public:
protected:
const aiImporterDesc* GetInfo () const;
void GetExtensionList(std::set<std::string>& app);
void SetupProperties(const Importer* pImp);
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
void ParseBlendFile(Blender::FileDatabase& out, std::shared_ptr<IOStream> stream);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
#include "AssetLib/COB/COBLoader.h"
#include "AssetLib/COB/COBScene.h"
#include "PostProcessing/ConvertToLHProcess.h"
@ -90,11 +91,15 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
COBImporter::COBImporter() {}
COBImporter::COBImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
COBImporter::~COBImporter() {}
COBImporter::~COBImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
@ -466,8 +471,9 @@ void COBImporter::UnsupportedChunk_Ascii(LineSplitter &splitter, const ChunkInfo
// missing the next line.
splitter.get_stream().IncPtr(nfo.size);
splitter.swallow_next_increment();
} else
} else {
ThrowException(error);
}
}
// ------------------------------------------------------------------------------------------------
@ -790,25 +796,12 @@ void COBImporter::ReadBitM_Ascii(Scene & /*out*/, LineSplitter &splitter, const
if (nfo.version > 1) {
return UnsupportedChunk_Ascii(splitter, nfo, "BitM");
}
/*
"\nThumbNailHdrSize %ld"
"\nThumbHeader: %02hx 02hx %02hx "
"\nColorBufSize %ld"
"\nColorBufZipSize %ld"
"\nZippedThumbnail: %02hx 02hx %02hx "
*/
const unsigned int head = strtoul10((++splitter)[1]);
if (head != sizeof(Bitmap::BitmapHeader)) {
ASSIMP_LOG_WARN("Unexpected ThumbNailHdrSize, skipping this chunk");
return;
}
/*union {
Bitmap::BitmapHeader data;
char opaq[sizeof Bitmap::BitmapHeader()];
};*/
// ReadHexOctets(opaq,head,(++splitter)[1]);
}
// ------------------------------------------------------------------------------------------------
@ -884,7 +877,10 @@ void COBImporter::ReadBinaryFile(Scene &out, StreamReaderLE *reader) {
while (1) {
std::string type;
type += reader->GetI1(), type += reader->GetI1(), type += reader->GetI1(), type += reader->GetI1();
type += reader->GetI1();
type += reader->GetI1();
type += reader->GetI1();
type += reader->GetI1();
ChunkInfo nfo;
nfo.version = reader->GetI2() * 10;
@ -906,14 +902,7 @@ void COBImporter::ReadBinaryFile(Scene &out, StreamReaderLE *reader) {
ReadCame_Binary(out, *reader, nfo);
} else if (type == "Mat1") {
ReadMat1_Binary(out, *reader, nfo);
}
/* else if (type == "Bone") {
ReadBone_Binary(out,*reader,nfo);
}
else if (type == "Chan") {
ReadChan_Binary(out,*reader,nfo);
}*/
else if (type == "Unit") {
} else if (type == "Unit") {
ReadUnit_Binary(out, *reader, nfo);
} else if (type == "OLay") {
// ignore layer index silently.
@ -923,8 +912,9 @@ void COBImporter::ReadBinaryFile(Scene &out, StreamReaderLE *reader) {
return UnsupportedChunk_Binary(*reader, nfo, type.c_str());
} else if (type == "END ") {
return;
} else
} else {
UnsupportedChunk_Binary(*reader, nfo, type.c_str());
}
}
}

View File

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

View File

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

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -129,7 +129,7 @@ inline std::string MakeUniqueId(const std::unordered_set<std::string> &idSet, co
// Select a number to append
size_t idnum = 1;
do {
result = idPrefix + '_' + to_string(idnum) + postfix;
result = idPrefix + '_' + ai_to_string(idnum) + postfix;
++idnum;
} while (!IsUniqueId(idSet, result));
}
@ -1017,7 +1017,7 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
// texture coords
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (mesh->HasTextureCoords(static_cast<unsigned int>(a))) {
WriteFloatArray(geometryId + "-tex" + to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
WriteFloatArray(geometryId + "-tex" + ai_to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
(ai_real *)mesh->mTextureCoords[a], mesh->mNumVertices);
}
}
@ -1025,7 +1025,7 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
// vertex colors
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (mesh->HasVertexColors(static_cast<unsigned int>(a)))
WriteFloatArray(geometryId + "-color" + to_string(a), FloatType_Color, (ai_real *)mesh->mColors[a], mesh->mNumVertices);
WriteFloatArray(geometryId + "-color" + ai_to_string(a), FloatType_Color, (ai_real *)mesh->mColors[a], mesh->mNumVertices);
}
// assemble vertex structure
@ -1724,7 +1724,7 @@ ColladaExporter::NameIdPair ColladaExporter::AddObjectIndexToMaps(AiObjectType t
case AiObjectType::Camera: idStr = std::string("camera_"); break;
case AiObjectType::Count: throw std::logic_error("ColladaExporter::AiObjectType::Count is not an object type");
}
idStr.append(to_string(index));
idStr.append(ai_to_string(index));
} else {
idStr = XMLIDEncode(name);
}

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -80,16 +80,16 @@ void ToCamelCase(std::string &text) {
return;
// Capitalise first character
auto it = text.begin();
(*it) = ToUpper(*it);
(*it) = ai_toupper(*it);
++it;
for (/*started above*/; it != text.end(); /*iterated below*/) {
if ((*it) == '_') {
it = text.erase(it);
if (it != text.end())
(*it) = ToUpper(*it);
(*it) = ai_toupper(*it);
} else {
// Make lower case
(*it) = ToLower(*it);
(*it) = ai_tolower(*it);
++it;
}
}

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/material.h>
#include <assimp/mesh.h>
#include <stdint.h>
#include <cstdint>
#include <map>
#include <set>
#include <vector>
@ -206,7 +206,8 @@ struct SemanticMappingTable {
std::string mMatName;
/// List of semantic map commands, grouped by effect semantic name
std::map<std::string, InputSemanticMapEntry> mMap;
using InputSemanticMap = std::map<std::string, InputSemanticMapEntry>;
InputSemanticMap mMap;
/// For std::find
bool operator==(const std::string &s) const {

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -63,6 +63,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
using namespace Assimp::Formatter;
using namespace Assimp::Collada;
static const aiImporterDesc desc = {
"Collada Importer",
@ -74,7 +75,7 @@ static const aiImporterDesc desc = {
3,
1,
5,
"dae zae"
"dae xml zae"
};
static const float kMillisecondsFromSeconds = 1000.f;
@ -271,7 +272,7 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
node->mTransformation = pParser.CalculateResultTransform(pNode->mTransforms);
// now resolve node instances
std::vector<const Collada::Node *> instances;
std::vector<const Node*> instances;
ResolveNodeInstances(pParser, pNode, instances);
// add children. first the *real* ones
@ -298,8 +299,8 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
// ------------------------------------------------------------------------------------------------
// Resolve node instances
void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Collada::Node *pNode,
std::vector<const Collada::Node *> &resolved) {
void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Node *pNode,
std::vector<const Node*> &resolved) {
// reserve enough storage
resolved.reserve(pNode->mNodeInstances.size());
@ -307,7 +308,7 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Col
for (const auto &nodeInst : pNode->mNodeInstances) {
// find the corresponding node in the library
const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find(nodeInst.mNode);
const Collada::Node *nd = itt == pParser.mNodeLibrary.end() ? nullptr : (*itt).second;
const Node *nd = itt == pParser.mNodeLibrary.end() ? nullptr : (*itt).second;
// FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632
// need to check for both name and ID to catch all. To avoid breaking valid files,
@ -326,13 +327,13 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Col
// ------------------------------------------------------------------------------------------------
// Resolve UV channels
void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler, const Collada::SemanticMappingTable &table) {
std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
void ColladaLoader::ApplyVertexToEffectSemanticMapping(Sampler &sampler, const SemanticMappingTable &table) {
SemanticMappingTable::InputSemanticMap::const_iterator it = table.mMap.find(sampler.mUVChannel);
if (it == table.mMap.end()) {
return;
}
if (it->second.mType != Collada::IT_Texcoord) {
if (it->second.mType != IT_Texcoord) {
ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping");
}
@ -341,8 +342,8 @@ void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler
// ------------------------------------------------------------------------------------------------
// Builds lights for the given node and references them
void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Collada::Node *pNode, aiNode *pTarget) {
for (const Collada::LightInstance &lid : pNode->mLights) {
void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
for (const LightInstance &lid : pNode->mLights) {
// find the referred light
ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find(lid.mLight);
if (srcLightIt == pParser.mLightLibrary.end()) {
@ -406,8 +407,8 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Colla
// ------------------------------------------------------------------------------------------------
// Builds cameras for the given node and references them
void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Collada::Node *pNode, aiNode *pTarget) {
for (const Collada::CameraInstance &cid : pNode->mCameras) {
void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
for (const CameraInstance &cid : pNode->mCameras) {
// find the referred light
ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find(cid.mCamera);
if (srcCameraIt == pParser.mCameraLibrary.end()) {
@ -461,15 +462,15 @@ void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Coll
// ------------------------------------------------------------------------------------------------
// Builds meshes for the given node and references them
void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Collada::Node *pNode, aiNode *pTarget) {
void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node *pNode, aiNode *pTarget) {
// accumulated mesh references by this node
std::vector<size_t> newMeshRefs;
newMeshRefs.reserve(pNode->mMeshes.size());
// add a mesh for each subgroup in each collada mesh
for (const Collada::MeshInstance &mid : pNode->mMeshes) {
const Collada::Mesh *srcMesh = nullptr;
const Collada::Controller *srcController = nullptr;
for (const MeshInstance &mid : pNode->mMeshes) {
const Mesh *srcMesh = nullptr;
const Controller *srcController = nullptr;
// find the referred mesh
ColladaParser::MeshLibrary::const_iterator srcMeshIt = pParser.mMeshLibrary.find(mid.mMeshOrController);
@ -503,7 +504,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Colla
// find material assigned to this submesh
std::string meshMaterial;
std::map<std::string, Collada::SemanticMappingTable>::const_iterator meshMatIt = mid.mMaterials.find(submesh.mMaterial);
std::map<std::string, SemanticMappingTable>::const_iterator meshMatIt = mid.mMaterials.find(submesh.mMaterial);
const Collada::SemanticMappingTable *table = nullptr;
if (meshMatIt != mid.mMaterials.end()) {
@ -557,7 +558,12 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Colla
faceStart += submesh.mNumFaces;
// assign the material index
dstMesh->mMaterialIndex = matIdx;
std::map<std::string, size_t>::const_iterator subMatIt = mMaterialIndexByName.find(submesh.mMaterial);
if (subMatIt != mMaterialIndexByName.end()) {
dstMesh->mMaterialIndex = static_cast<unsigned int>(subMatIt->second);
} else {
dstMesh->mMaterialIndex = matIdx;
}
if (dstMesh->mName.length == 0) {
dstMesh->mName = mid.mMeshOrController;
}
@ -586,15 +592,15 @@ aiMesh *ColladaLoader::findMesh(const std::string &meshid) {
return nullptr;
}
for (unsigned int i = 0; i < mMeshes.size(); ++i) {
if (std::string(mMeshes[i]->mName.data) == meshid) {
return mMeshes[i];
for (auto & mMeshe : mMeshes) {
if (std::string(mMeshe->mName.data) == meshid) {
return mMeshe;
}
}
for (unsigned int i = 0; i < mTargetMeshes.size(); ++i) {
if (std::string(mTargetMeshes[i]->mName.data) == meshid) {
return mTargetMeshes[i];
for (auto & mTargetMeshe : mTargetMeshes) {
if (std::string(mTargetMeshe->mName.data) == meshid) {
return mTargetMeshe;
}
}
@ -603,8 +609,8 @@ aiMesh *ColladaLoader::findMesh(const std::string &meshid) {
// ------------------------------------------------------------------------------------------------
// Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh
aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::Mesh *pSrcMesh, const Collada::SubMesh &pSubMesh,
const Collada::Controller *pSrcController, size_t pStartVertex, size_t pStartFace) {
aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrcMesh, const SubMesh &pSubMesh,
const Controller *pSrcController, size_t pStartVertex, size_t pStartFace) {
std::unique_ptr<aiMesh> dstMesh(new aiMesh);
if (useColladaName) {
@ -642,7 +648,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::M
std::copy(pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() + pStartVertex + numVertices, dstMesh->mBitangents);
}
// same for texturecoords, as many as we have
// same for texture coords, as many as we have
// empty slots are not allowed, need to pack and adjust UV indexes accordingly
for (size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices) {
@ -682,11 +688,11 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::M
// create morph target meshes if any
std::vector<aiMesh *> targetMeshes;
std::vector<float> targetWeights;
Collada::MorphMethod method = Collada::Normalized;
Collada::MorphMethod method = Normalized;
for (std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
for (std::map<std::string, Controller>::const_iterator it = pParser.mControllerLibrary.begin();
it != pParser.mControllerLibrary.end(); ++it) {
const Collada::Controller &c = it->second;
const Controller &c = it->second;
const Collada::Mesh *baseMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, c.mMeshId);
if (c.mType == Collada::Morph && baseMesh->mName == pSrcMesh->mName) {
@ -705,8 +711,8 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::M
throw DeadlyImportError("target weight data must not be textual ");
}
for (unsigned int i = 0; i < targetData.mStrings.size(); ++i) {
const Collada::Mesh *targetMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, targetData.mStrings.at(i));
for (const auto & mString : targetData.mStrings) {
const Mesh *targetMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, mString);
aiMesh *aimesh = findMesh(useColladaName ? targetMesh->mName : targetMesh->mId);
if (!aimesh) {
@ -718,12 +724,12 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::M
}
targetMeshes.push_back(aimesh);
}
for (unsigned int i = 0; i < weightData.mValues.size(); ++i) {
targetWeights.push_back(weightData.mValues.at(i));
for (float mValue : weightData.mValues) {
targetWeights.push_back(mValue);
}
}
}
if (targetMeshes.size() > 0 && targetWeights.size() == targetMeshes.size()) {
if (!targetMeshes.empty() && targetWeights.size() == targetMeshes.size()) {
std::vector<aiAnimMesh *> animMeshes;
for (unsigned int i = 0; i < targetMeshes.size(); ++i) {
aiMesh *targetMesh = targetMeshes.at(i);
@ -733,7 +739,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::M
animMesh->mName = targetMesh->mName;
animMeshes.push_back(animMesh);
}
dstMesh->mMethod = (method == Collada::Relative) ? aiMorphingMethod_MORPH_RELATIVE : aiMorphingMethod_MORPH_NORMALIZED;
dstMesh->mMethod = (method == Relative) ? aiMorphingMethod_MORPH_RELATIVE : aiMorphingMethod_MORPH_NORMALIZED;
dstMesh->mAnimMeshes = new aiAnimMesh *[animMeshes.size()];
dstMesh->mNumAnimMeshes = static_cast<unsigned int>(animMeshes.size());
for (unsigned int i = 0; i < animMeshes.size(); ++i) {
@ -757,18 +763,20 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::M
const Collada::Accessor &weightsAcc = pParser.ResolveLibraryReference(pParser.mAccessorLibrary, pSrcController->mWeightInputWeights.mAccessor);
const Collada::Data &weights = pParser.ResolveLibraryReference(pParser.mDataLibrary, weightsAcc.mSource);
if (!jointNames.mIsStringArray || jointMatrices.mIsStringArray || weights.mIsStringArray)
if (!jointNames.mIsStringArray || jointMatrices.mIsStringArray || weights.mIsStringArray) {
throw DeadlyImportError("Data type mismatch while resolving mesh joints");
}
// sanity check: we rely on the vertex weights always coming as pairs of BoneIndex-WeightIndex
if (pSrcController->mWeightInputJoints.mOffset != 0 || pSrcController->mWeightInputWeights.mOffset != 1)
if (pSrcController->mWeightInputJoints.mOffset != 0 || pSrcController->mWeightInputWeights.mOffset != 1) {
throw DeadlyImportError("Unsupported vertex_weight addressing scheme. ");
}
// create containers to collect the weights for each bone
size_t numBones = jointNames.mStrings.size();
std::vector<std::vector<aiVertexWeight>> dstBones(numBones);
// build a temporary array of pointers to the start of each vertex's weights
typedef std::vector<std::pair<size_t, size_t>> IndexPairVector;
using IndexPairVector = std::vector<std::pair<size_t, size_t>>;
std::vector<IndexPairVector::const_iterator> weightStartPerVertex;
weightStartPerVertex.resize(pSrcController->mWeightCounts.size(), pSrcController->mWeights.end());
@ -807,8 +815,8 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::M
// count the number of bones which influence vertices of the current submesh
size_t numRemainingBones = 0;
for (std::vector<std::vector<aiVertexWeight>>::const_iterator it = dstBones.begin(); it != dstBones.end(); ++it) {
if (it->size() > 0) {
for (const auto & dstBone : dstBones) {
if (!dstBone.empty()) {
++numRemainingBones;
}
}
@ -867,12 +875,12 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::M
// and replace the bone's name by the node's name so that the user can use the standard
// find-by-name method to associate nodes with bones.
const Collada::Node *bnode = FindNode(pParser.mRootNode, bone->mName.data);
if (!bnode) {
if (nullptr == bnode) {
bnode = FindNodeBySID(pParser.mRootNode, bone->mName.data);
}
// assign the name that we would have assigned for the source node
if (bnode) {
if (nullptr != bnode) {
bone->mName.Set(FindNameForNode(bnode));
} else {
ASSIMP_LOG_WARN_F("ColladaLoader::CreateMesh(): could not find corresponding node for joint \"", bone->mName.data, "\".");
@ -973,8 +981,8 @@ void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParse
std::set<std::string> animTargets;
animTargets.insert(templateAnim->mChannels[0]->mNodeName.C_Str());
bool collectedAnimationsHaveDifferentChannels = true;
for (size_t b = 0; b < collectedAnimIndices.size(); ++b) {
aiAnimation *srcAnimation = mAnims[collectedAnimIndices[b]];
for (unsigned long long collectedAnimIndice : collectedAnimIndices) {
aiAnimation *srcAnimation = mAnims[(int)collectedAnimIndice];
std::string channelName = std::string(srcAnimation->mChannels[0]->mNodeName.C_Str());
if (animTargets.find(channelName) == animTargets.end()) {
animTargets.insert(channelName);
@ -984,8 +992,9 @@ void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParse
}
}
if (!collectedAnimationsHaveDifferentChannels)
if (!collectedAnimationsHaveDifferentChannels) {
continue;
}
// if there are other animations which fit the template anim, combine all channels into a single anim
if (!collectedAnimIndices.empty()) {
@ -1032,16 +1041,18 @@ void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParse
// ------------------------------------------------------------------------------------------------
// Constructs the animations for the given source anim
void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParser, const Collada::Animation *pSrcAnim, const std::string &pPrefix) {
void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParser, const Animation *pSrcAnim, const std::string &pPrefix) {
std::string animName = pPrefix.empty() ? pSrcAnim->mName : pPrefix + "_" + pSrcAnim->mName;
// create nested animations, if given
for (std::vector<Collada::Animation *>::const_iterator it = pSrcAnim->mSubAnims.begin(); it != pSrcAnim->mSubAnims.end(); ++it)
StoreAnimations(pScene, pParser, *it, animName);
for (auto mSubAnim : pSrcAnim->mSubAnims) {
StoreAnimations(pScene, pParser, mSubAnim, animName);
}
// create animation channels, if any
if (!pSrcAnim->mChannels.empty())
if (!pSrcAnim->mChannels.empty()) {
CreateAnimation(pScene, pParser, pSrcAnim, animName);
}
}
struct MorphTimeValues {
@ -1057,7 +1068,7 @@ void insertMorphTimeValue(std::vector<MorphTimeValues> &values, float time, floa
MorphTimeValues::key k;
k.mValue = value;
k.mWeight = weight;
if (values.size() == 0 || time < values[0].mTime) {
if (values.empty() || time < values[0].mTime) {
MorphTimeValues val;
val.mTime = time;
val.mKeys.push_back(k);
@ -1083,13 +1094,13 @@ void insertMorphTimeValue(std::vector<MorphTimeValues> &values, float time, floa
return;
}
}
// should not get here
}
float getWeightAtKey(const std::vector<MorphTimeValues> &values, int key, unsigned int value) {
for (unsigned int i = 0; i < values[key].mKeys.size(); i++) {
if (values[key].mKeys[i].mValue == value)
return values[key].mKeys[i].mWeight;
static float getWeightAtKey(const std::vector<MorphTimeValues> &values, int key, unsigned int value) {
for (auto mKey : values[key].mKeys) {
if (mKey.mValue == value) {
return mKey.mWeight;
}
}
// no value at key found, try to interpolate if present at other keys. if not, return zero
// TODO: interpolation
@ -1098,7 +1109,7 @@ float getWeightAtKey(const std::vector<MorphTimeValues> &values, int key, unsign
// ------------------------------------------------------------------------------------------------
// Constructs the animation for the given source anim
void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParser, const Collada::Animation *pSrcAnim, const std::string &pName) {
void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParser, const Animation *pSrcAnim, const std::string &pName) {
// collect a list of animatable nodes
std::vector<const aiNode *> nodes;
CollectNodes(pScene->mRootNode, nodes);
@ -1106,23 +1117,23 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
std::vector<aiNodeAnim *> anims;
std::vector<aiMeshMorphAnim *> morphAnims;
for (std::vector<const aiNode *>::const_iterator nit = nodes.begin(); nit != nodes.end(); ++nit) {
for (auto node : nodes) {
// find all the collada anim channels which refer to the current node
std::vector<Collada::ChannelEntry> entries;
std::string nodeName = (*nit)->mName.data;
std::vector<ChannelEntry> entries;
std::string nodeName = node->mName.data;
// find the collada node corresponding to the aiNode
const Collada::Node *srcNode = FindNode(pParser.mRootNode, nodeName);
const Node *srcNode = FindNode(pParser.mRootNode, nodeName);
if (!srcNode) {
continue;
}
// now check all channels if they affect the current node
std::string targetID, subElement;
for (std::vector<Collada::AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
for (std::vector<AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
cit != pSrcAnim->mChannels.end(); ++cit) {
const Collada::AnimationChannel &srcChannel = *cit;
Collada::ChannelEntry entry;
const AnimationChannel &srcChannel = *cit;
ChannelEntry entry;
// we expect the animation target to be of type "nodeName/transformID.subElement". Ignore all others
// find the slash that separates the node name - there should be only one
@ -1137,24 +1148,28 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
entry.mChannel = &(*cit);
entry.mTargetId = srcChannel.mTarget.substr(targetPos + pSrcAnim->mName.length(),
srcChannel.mTarget.length() - targetPos - pSrcAnim->mName.length());
if (entry.mTargetId.front() == '-')
if (entry.mTargetId.front() == '-') {
entry.mTargetId = entry.mTargetId.substr(1);
}
entries.push_back(entry);
continue;
}
if (srcChannel.mTarget.find('/', slashPos + 1) != std::string::npos)
if (srcChannel.mTarget.find('/', slashPos + 1) != std::string::npos) {
continue;
}
targetID.clear();
targetID = srcChannel.mTarget.substr(0, slashPos);
if (targetID != srcNode->mID)
if (targetID != srcNode->mID) {
continue;
}
// find the dot that separates the transformID - there should be only one or zero
std::string::size_type dotPos = srcChannel.mTarget.find('.');
if (dotPos != std::string::npos) {
if (srcChannel.mTarget.find('.', dotPos + 1) != std::string::npos)
if (srcChannel.mTarget.find('.', dotPos + 1) != std::string::npos) {
continue;
}
entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1, dotPos - slashPos - 1);
@ -1171,7 +1186,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
else
ASSIMP_LOG_WARN_F("Unknown anim subelement <", subElement, ">. Ignoring");
} else {
// no subelement following, transformId is remaining string
// no sub-element following, transformId is remaining string
entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1);
}
@ -1222,11 +1237,11 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
entry.mTransformIndex = a;
if (entry.mTransformIndex == SIZE_MAX) {
if (entry.mTransformId.find("morph-weights") != std::string::npos) {
entry.mTargetId = entry.mTransformId;
entry.mTransformId = "";
} else
if (entry.mTransformId.find("morph-weights") == std::string::npos) {
continue;
}
entry.mTargetId = entry.mTransformId;
entry.mTransformId = std::string();
}
entry.mChannel = &(*cit);
@ -1234,21 +1249,22 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
}
// if there's no channel affecting the current node, we skip it
if (entries.empty())
if (entries.empty()) {
continue;
}
// resolve the data pointers for all anim channels. Find the minimum time while we're at it
ai_real startTime = ai_real(1e20), endTime = ai_real(-1e20);
for (std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it) {
Collada::ChannelEntry &e = *it;
for (ChannelEntry & e : entries) {
e.mTimeAccessor = &pParser.ResolveLibraryReference(pParser.mAccessorLibrary, e.mChannel->mSourceTimes);
e.mTimeData = &pParser.ResolveLibraryReference(pParser.mDataLibrary, e.mTimeAccessor->mSource);
e.mValueAccessor = &pParser.ResolveLibraryReference(pParser.mAccessorLibrary, e.mChannel->mSourceValues);
e.mValueData = &pParser.ResolveLibraryReference(pParser.mDataLibrary, e.mValueAccessor->mSource);
// time count and value count must match
if (e.mTimeAccessor->mCount != e.mValueAccessor->mCount)
if (e.mTimeAccessor->mCount != e.mValueAccessor->mCount) {
throw DeadlyImportError("Time count / value count mismatch in animation channel \"", e.mChannel->mTarget, "\".");
}
if (e.mTimeAccessor->mCount > 0) {
// find bounding times
@ -1266,18 +1282,18 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// and apply them to the transform chain. Then the node's present transformation can be calculated.
ai_real time = startTime;
while (1) {
for (std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it) {
Collada::ChannelEntry &e = *it;
for (ChannelEntry & e : entries) {
// find the keyframe behind the current point in time
size_t pos = 0;
ai_real postTime = 0.0;
while (1) {
if (pos >= e.mTimeAccessor->mCount)
if (pos >= e.mTimeAccessor->mCount) {
break;
}
postTime = ReadFloat(*e.mTimeAccessor, *e.mTimeData, pos, 0);
if (postTime >= time)
if (postTime >= time) {
break;
}
++pos;
}
@ -1285,8 +1301,9 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// read values from there
ai_real temp[16];
for (size_t c = 0; c < e.mValueAccessor->mSize; ++c)
for (size_t c = 0; c < e.mValueAccessor->mSize; ++c) {
temp[c] = ReadFloat(*e.mValueAccessor, *e.mValueData, pos, c);
}
// if not exactly at the key time, interpolate with previous value set
if (postTime > time && pos > 0) {
@ -1312,9 +1329,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// find next point in time to evaluate. That's the closest frame larger than the current in any channel
ai_real nextTime = ai_real(1e20);
for (std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it) {
Collada::ChannelEntry &channelElement = *it;
for (ChannelEntry & channelElement : entries) {
// find the next time value larger than the current
size_t pos = 0;
while (pos < channelElement.mTimeAccessor->mCount) {
@ -1329,7 +1344,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// https://github.com/assimp/assimp/issues/458
// Sub-sample axis-angle channels if the delta between two consecutive
// key-frame angles is >= 180 degrees.
if (transforms[channelElement.mTransformIndex].mType == Collada::TF_ROTATE && channelElement.mSubElement == 3 && pos > 0 && pos < channelElement.mTimeAccessor->mCount) {
if (transforms[channelElement.mTransformIndex].mType == TF_ROTATE && channelElement.mSubElement == 3 && pos > 0 && pos < channelElement.mTimeAccessor->mCount) {
const ai_real cur_key_angle = ReadFloat(*channelElement.mValueAccessor, *channelElement.mValueData, pos, 0);
const ai_real last_key_angle = ReadFloat(*channelElement.mValueAccessor, *channelElement.mValueData, pos - 1, 0);
const ai_real cur_key_time = ReadFloat(*channelElement.mTimeAccessor, *channelElement.mTimeData, pos, 0);
@ -1347,17 +1362,15 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
}
// no more keys on any channel after the current time -> we're done
if (nextTime > 1e19)
if (nextTime > 1e19) {
break;
}
// else construct next keyframe at this following time point
// else construct next key-frame at this following time point
time = nextTime;
}
}
// there should be some keyframes, but we aren't that fixated on valid input data
// ai_assert( resultTrafos.size() > 0);
// build an animation channel for the given node out of these trafo keys
if (!resultTrafos.empty()) {
aiNodeAnim *dstAnim = new aiNodeAnim;
@ -1386,16 +1399,16 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
}
if (!entries.empty() && entries.front().mTimeAccessor->mCount > 0) {
std::vector<Collada::ChannelEntry> morphChannels;
for (std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it) {
Collada::ChannelEntry &e = *it;
std::vector<ChannelEntry> morphChannels;
for (ChannelEntry & e : entries) {
// skip non-transform types
if (e.mTargetId.empty())
if (e.mTargetId.empty()) {
continue;
}
if (e.mTargetId.find("morph-weights") != std::string::npos)
if (e.mTargetId.find("morph-weights") != std::string::npos) {
morphChannels.push_back(e);
}
}
if (!morphChannels.empty()) {
// either 1) morph weight animation count should contain morph target count channels
@ -1407,13 +1420,14 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
std::vector<MorphTimeValues> morphTimeValues;
int morphAnimChannelIndex = 0;
for (std::vector<Collada::ChannelEntry>::iterator it = morphChannels.begin(); it != morphChannels.end(); ++it) {
Collada::ChannelEntry &e = *it;
for (ChannelEntry & e : morphChannels) {
std::string::size_type apos = e.mTargetId.find('(');
std::string::size_type bpos = e.mTargetId.find(')');
if (apos == std::string::npos || bpos == std::string::npos)
// unknown way to specify weight -> ignore this animation
// If unknown way to specify weight -> ignore this animation
if (apos == std::string::npos || bpos == std::string::npos) {
continue;
}
// weight target can be in format Weight_M_N, Weight_N, WeightN, or some other way
// we ignore the name and just assume the channels are in the right order
@ -1457,13 +1471,13 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
std::copy(morphAnims.begin(), morphAnims.end(), anim->mMorphMeshChannels);
}
anim->mDuration = 0.0f;
for (size_t a = 0; a < anims.size(); ++a) {
anim->mDuration = std::max(anim->mDuration, anims[a]->mPositionKeys[anims[a]->mNumPositionKeys - 1].mTime);
anim->mDuration = std::max(anim->mDuration, anims[a]->mRotationKeys[anims[a]->mNumRotationKeys - 1].mTime);
anim->mDuration = std::max(anim->mDuration, anims[a]->mScalingKeys[anims[a]->mNumScalingKeys - 1].mTime);
for (auto & a : anims) {
anim->mDuration = std::max(anim->mDuration, a->mPositionKeys[a->mNumPositionKeys - 1].mTime);
anim->mDuration = std::max(anim->mDuration, a->mRotationKeys[a->mNumRotationKeys - 1].mTime);
anim->mDuration = std::max(anim->mDuration, a->mScalingKeys[a->mNumScalingKeys - 1].mTime);
}
for (size_t a = 0; a < morphAnims.size(); ++a) {
anim->mDuration = std::max(anim->mDuration, morphAnims[a]->mKeys[morphAnims[a]->mNumKeys - 1].mTime);
for (auto & morphAnim : morphAnims) {
anim->mDuration = std::max(anim->mDuration, morphAnim->mKeys[morphAnim->mNumKeys - 1].mTime);
}
anim->mTicksPerSecond = 1000.0;
mAnims.push_back(anim);
@ -1472,10 +1486,12 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// ------------------------------------------------------------------------------------------------
// Add a texture to a material structure
void ColladaLoader::AddTexture(aiMaterial &mat, const ColladaParser &pParser,
const Collada::Effect &effect,
const Collada::Sampler &sampler,
aiTextureType type, unsigned int idx) {
void ColladaLoader::AddTexture(aiMaterial &mat,
const ColladaParser &pParser,
const Effect &effect,
const Sampler &sampler,
aiTextureType type,
unsigned int idx) {
// first of all, basic file name
const aiString name = FindFilenameForEffectTexture(pParser, effect, sampler.mName);
mat.AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, type, idx);
@ -1574,7 +1590,7 @@ void ColladaLoader::FillMaterials(const ColladaParser &pParser, aiScene * /*pSce
shadeMode = effect.mDoubleSided;
mat.AddProperty<int>(&shadeMode, 1, AI_MATKEY_TWOSIDED);
// wireframe?
// wire-frame?
shadeMode = effect.mWireframe;
mat.AddProperty<int>(&shadeMode, 1, AI_MATKEY_ENABLE_WIREFRAME);
@ -1652,12 +1668,12 @@ void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/)
for (ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin();
matIt != pParser.mMaterialLibrary.end(); ++matIt) {
const Collada::Material &material = matIt->second;
const Material &material = matIt->second;
// a material is only a reference to an effect
ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find(material.mEffect);
if (effIt == pParser.mEffectLibrary.end())
continue;
Collada::Effect &effect = effIt->second;
Effect &effect = effIt->second;
// create material
aiMaterial *mat = new aiMaterial;
@ -1666,7 +1682,7 @@ void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/)
// store the material
mMaterialIndexByName[matIt->first] = newMats.size();
newMats.push_back(std::pair<Collada::Effect *, aiMaterial *>(&effect, mat));
newMats.push_back(std::pair<Effect *, aiMaterial *>(&effect, mat));
}
// ScenePreprocessor generates a default material automatically if none is there.
// All further code here in this loader works well without a valid material so
@ -1674,17 +1690,16 @@ void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/)
}
// ------------------------------------------------------------------------------------------------
// Resolves the texture name for the given effect texture entry
// and loads the texture data
// Resolves the texture name for the given effect texture entry and loads the texture data
aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParser,
const Collada::Effect &pEffect, const std::string &pName) {
const Effect &pEffect, const std::string &pName) {
aiString result;
// recurse through the param references until we end up at an image
std::string name = pName;
while (1) {
// the given string is a param entry. Find it
Collada::Effect::ParamLibrary::const_iterator it = pEffect.mParams.find(name);
Effect::ParamLibrary::const_iterator it = pEffect.mParams.find(name);
// if not found, we're at the end of the recursion. The resulting string should be the image ID
if (it == pEffect.mParams.end())
break;
@ -1712,10 +1727,6 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
tex->mFilename.Set(imIt->second.mFileName.c_str());
result.Set(imIt->second.mFileName);
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
// result.data[0] = '*';
// result.length = 1 + ASSIMP_itoa10(result.data + 1, static_cast<unsigned int>(MAXLEN - 1), static_cast<int32_t>(mTextures.size()));
// setup format hint
if (imIt->second.mEmbeddedFormat.length() >= HINTMAXTEXTURELEN) {
ASSIMP_LOG_WARN("Collada: texture format hint is too long, truncating to 3 characters");
@ -1744,7 +1755,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
// ------------------------------------------------------------------------------------------------
// Reads a float value from an accessor and its data array.
ai_real ColladaLoader::ReadFloat(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex, size_t pOffset) const {
ai_real ColladaLoader::ReadFloat(const Accessor &pAccessor, const Data &pData, size_t pIndex, size_t pOffset) const {
size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
ai_assert(pos < pData.mValues.size());
return pData.mValues[pos];
@ -1752,7 +1763,7 @@ ai_real ColladaLoader::ReadFloat(const Collada::Accessor &pAccessor, const Colla
// ------------------------------------------------------------------------------------------------
// Reads a string value from an accessor and its data array.
const std::string &ColladaLoader::ReadString(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex) const {
const std::string &ColladaLoader::ReadString(const Accessor &pAccessor, const Data &pData, size_t pIndex) const {
size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset;
ai_assert(pos < pData.mStrings.size());
return pData.mStrings[pos];
@ -1769,12 +1780,12 @@ void ColladaLoader::CollectNodes(const aiNode *pNode, std::vector<const aiNode *
// ------------------------------------------------------------------------------------------------
// Finds a node in the collada scene by the given name
const Collada::Node *ColladaLoader::FindNode(const Collada::Node *pNode, const std::string &pName) const {
const Node *ColladaLoader::FindNode(const Node *pNode, const std::string &pName) const {
if (pNode->mName == pName || pNode->mID == pName)
return pNode;
for (size_t a = 0; a < pNode->mChildren.size(); ++a) {
const Collada::Node *node = FindNode(pNode->mChildren[a], pName);
for (auto a : pNode->mChildren) {
const Collada::Node *node = FindNode(a, pName);
if (node) {
return node;
}
@ -1785,7 +1796,7 @@ const Collada::Node *ColladaLoader::FindNode(const Collada::Node *pNode, const s
// ------------------------------------------------------------------------------------------------
// Finds a node in the collada scene by the given SID
const Collada::Node *ColladaLoader::FindNodeBySID(const Collada::Node *pNode, const std::string &pSID) const {
const Node *ColladaLoader::FindNodeBySID(const Node *pNode, const std::string &pSID) const {
if (nullptr == pNode) {
return nullptr;
}
@ -1794,8 +1805,8 @@ const Collada::Node *ColladaLoader::FindNodeBySID(const Collada::Node *pNode, co
return pNode;
}
for (size_t a = 0; a < pNode->mChildren.size(); ++a) {
const Collada::Node *node = FindNodeBySID(pNode->mChildren[a], pSID);
for (auto a : pNode->mChildren) {
const Collada::Node *node = FindNodeBySID(a, pSID);
if (node) {
return node;
}
@ -1807,7 +1818,7 @@ const Collada::Node *ColladaLoader::FindNodeBySID(const Collada::Node *pNode, co
// ------------------------------------------------------------------------------------------------
// Finds a proper unique name for a node derived from the collada-node's properties.
// The name must be unique for proper node-bone association.
std::string ColladaLoader::FindNameForNode(const Collada::Node *pNode) {
std::string ColladaLoader::FindNameForNode(const Node *pNode) {
// If explicitly requested, just use the collada name.
if (useColladaName) {
if (!pNode->mName.empty()) {

View File

@ -4,7 +4,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -45,8 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_COLLADALOADER_H_INC
#define AI_COLLADALOADER_H_INC
#include <assimp/BaseImporter.h>
#include "ColladaParser.h"
#include <assimp/BaseImporter.h>
struct aiNode;
struct aiCamera;
@ -54,28 +54,24 @@ struct aiLight;
struct aiTexture;
struct aiAnimation;
namespace Assimp
{
namespace Assimp {
struct ColladaMeshIndex
{
struct ColladaMeshIndex {
std::string mMeshID;
size_t mSubMesh;
std::string mMaterial;
ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial)
: mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial)
{ }
ColladaMeshIndex(const std::string &pMeshID, size_t pSubMesh, const std::string &pMaterial) :
mMeshID(pMeshID), mSubMesh(pSubMesh), mMaterial(pMaterial) {
ai_assert(!pMeshID.empty());
}
bool operator < (const ColladaMeshIndex& p) const
{
if( mMeshID == p.mMeshID)
{
if( mSubMesh == p.mSubMesh)
bool operator<(const ColladaMeshIndex &p) const {
if (mMeshID == p.mMeshID) {
if (mSubMesh == p.mSubMesh)
return mMaterial < p.mMaterial;
else
return mSubMesh < p.mSubMesh;
} else
{
} else {
return mMeshID < p.mMeshID;
}
}
@ -84,105 +80,102 @@ struct ColladaMeshIndex
/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
* more useless stuff, so I limited the data to what I think is useful for games.
*/
class ColladaLoader : public BaseImporter
{
class ColladaLoader : public BaseImporter {
public:
/// The class constructor.
ColladaLoader();
~ColladaLoader();
/// The class destructor.
~ColladaLoader() override;
public:
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
/// Returns whether the class can handle the format of the given file.
/// @see BaseImporter::CanRead() for more details.
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
protected:
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const override;
/// See #BaseImporter::GetInfo for the details
const aiImporterDesc *GetInfo() const override;
void SetupProperties(const Importer* pImp) override;
/// See #BaseImporter::SetupProperties for the details
void SetupProperties(const Importer *pImp) override;
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
/// See #BaseImporter::InternReadFile for the details
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
/** Recursively constructs a scene node for the given parser node and returns it. */
aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
aiNode *BuildHierarchy(const ColladaParser &pParser, const Collada::Node *pNode);
/** Resolve node instances */
void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
std::vector<const Collada::Node*>& resolved);
void ResolveNodeInstances(const ColladaParser &pParser, const Collada::Node *pNode,
std::vector<const Collada::Node *> &resolved);
/** Builds meshes for the given node and references them */
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget);
aiMesh *findMesh(const std::string& meshid);
void BuildMeshesForNode(const ColladaParser &pParser, const Collada::Node *pNode,
aiNode *pTarget);
aiMesh *findMesh(const std::string &meshid);
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace);
aiMesh *CreateMesh(const ColladaParser &pParser, const Collada::Mesh *pSrcMesh, const Collada::SubMesh &pSubMesh,
const Collada::Controller *pSrcController, size_t pStartVertex, size_t pStartFace);
/** Builds cameras for the given node and references them */
void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget);
void BuildCamerasForNode(const ColladaParser &pParser, const Collada::Node *pNode,
aiNode *pTarget);
/** Builds lights for the given node and references them */
void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget);
void BuildLightsForNode(const ColladaParser &pParser, const Collada::Node *pNode,
aiNode *pTarget);
/** Stores all meshes in the given scene */
void StoreSceneMeshes( aiScene* pScene);
void StoreSceneMeshes(aiScene *pScene);
/** Stores all materials in the given scene */
void StoreSceneMaterials( aiScene* pScene);
void StoreSceneMaterials(aiScene *pScene);
/** Stores all lights in the given scene */
void StoreSceneLights( aiScene* pScene);
void StoreSceneLights(aiScene *pScene);
/** Stores all cameras in the given scene */
void StoreSceneCameras( aiScene* pScene);
void StoreSceneCameras(aiScene *pScene);
/** Stores all textures in the given scene */
void StoreSceneTextures( aiScene* pScene);
void StoreSceneTextures(aiScene *pScene);
/** Stores all animations
* @param pScene target scene to store the anims
*/
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser);
void StoreAnimations(aiScene *pScene, const ColladaParser &pParser);
/** Stores all animations for the given source anim and its nested child animations
* @param pScene target scene to store the anims
* @param pSrcAnim the source animation to process
* @param pPrefix Prefix to the name in case of nested animations
*/
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pPrefix);
void StoreAnimations(aiScene *pScene, const ColladaParser &pParser, const Collada::Animation *pSrcAnim, const std::string &pPrefix);
/** Constructs the animation for the given source anim */
void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName);
void CreateAnimation(aiScene *pScene, const ColladaParser &pParser, const Collada::Animation *pSrcAnim, const std::string &pName);
/** Constructs materials from the collada material definitions */
void BuildMaterials( ColladaParser& pParser, aiScene* pScene);
void BuildMaterials(ColladaParser &pParser, aiScene *pScene);
/** Fill materials from the collada material definitions */
void FillMaterials( const ColladaParser& pParser, aiScene* pScene);
void FillMaterials(const ColladaParser &pParser, aiScene *pScene);
/** Resolve UV channel mappings*/
void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
const Collada::SemanticMappingTable& table);
void ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler,
const Collada::SemanticMappingTable &table);
/** Add a texture and all of its sampling properties to a material*/
void AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
const Collada::Effect& effect,
const Collada::Sampler& sampler,
aiTextureType type, unsigned int idx = 0);
void AddTexture(aiMaterial &mat, const ColladaParser &pParser,
const Collada::Effect &effect,
const Collada::Sampler &sampler,
aiTextureType type, unsigned int idx = 0);
/** Resolves the texture name for the given effect texture entry */
aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
const Collada::Effect& pEffect, const std::string& pName);
aiString FindFilenameForEffectTexture(const ColladaParser &pParser,
const Collada::Effect &pEffect, const std::string &pName);
/** Reads a float value from an accessor and its data array.
* @param pAccessor The accessor to use for reading
@ -191,7 +184,7 @@ protected:
* @param pOffset Offset into the element, for multipart elements such as vectors or matrices
* @return the specified value
*/
ai_real ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const;
ai_real ReadFloat(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex, size_t pOffset) const;
/** Reads a string value from an accessor and its data array.
* @param pAccessor The accessor to use for reading
@ -199,18 +192,18 @@ protected:
* @param pIndex The index of the element to retrieve
* @return the specified value
*/
const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const;
const std::string &ReadString(const Collada::Accessor &pAccessor, const Collada::Data &pData, size_t pIndex) const;
/** Recursively collects all nodes into the given array */
void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const;
void CollectNodes(const aiNode *pNode, std::vector<const aiNode *> &poNodes) const;
/** Finds a node in the collada scene by the given name */
const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const;
const Collada::Node *FindNode(const Collada::Node *pNode, const std::string &pName) const;
/** Finds a node in the collada scene by the given SID */
const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const;
const Collada::Node *FindNodeBySID(const Collada::Node *pNode, const std::string &pSID) const;
/** Finds a proper name for a node derived from the collada-node's properties */
std::string FindNameForNode( const Collada::Node* pNode);
std::string FindNameForNode(const Collada::Node *pNode);
protected:
/** Filename, for a verbose error message */
@ -223,25 +216,25 @@ protected:
std::map<std::string, size_t> mMaterialIndexByName;
/** Accumulated meshes for the target scene */
std::vector<aiMesh*> mMeshes;
std::vector<aiMesh *> mMeshes;
/** Accumulated morph target meshes */
std::vector<aiMesh*> mTargetMeshes;
std::vector<aiMesh *> mTargetMeshes;
/** Temporary material list */
std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats;
std::vector<std::pair<Collada::Effect *, aiMaterial *>> newMats;
/** Temporary camera list */
std::vector<aiCamera*> mCameras;
std::vector<aiCamera *> mCameras;
/** Temporary light list */
std::vector<aiLight*> mLights;
std::vector<aiLight *> mLights;
/** Temporary texture list */
std::vector<aiTexture*> mTextures;
std::vector<aiTexture *> mTextures;
/** Accumulated animations for the target scene */
std::vector<aiAnimation*> mAnims;
std::vector<aiAnimation *> mAnims;
bool noSkeletonMesh;
bool ignoreUpDirection;

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/light.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory>
using namespace Assimp;
using namespace Assimp::Collada;
@ -158,9 +159,9 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
if (colladaNode.empty()) {
return;
}
ReadContents(colladaNode);
// read embedded textures
// Read content and embedded textures
ReadContents(colladaNode);
if (zip_archive && zip_archive->isOpen()) {
ReadEmbeddedTextures(*zip_archive);
}
@ -169,11 +170,11 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
ColladaParser::~ColladaParser() {
for (NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it) {
delete it->second;
for (auto & it : mNodeLibrary) {
delete it.second;
}
for (MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it) {
delete it->second;
for (auto & it : mMeshLibrary) {
delete it.second;
}
}
@ -289,7 +290,7 @@ void ColladaParser::ReadContents(XmlNode &node) {
// Reads the structure of the file
void ColladaParser::ReadStructure(XmlNode &node) {
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = std::string(currentNode.name());
const std::string &currentName = currentNode.name();
if (currentName == "asset") {
ReadAssetInfo(currentNode);
} else if (currentName == "library_animations") {
@ -334,7 +335,7 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
const std::string &currentName = currentNode.name();
if (currentName == "unit") {
mUnitSize = 1.f;
XmlParser::getFloatAttribute(node, "meter", mUnitSize);
XmlParser::getRealAttribute(currentNode, "meter", mUnitSize);
} else if (currentName == "up_axis") {
std::string v;
if (!XmlParser::getValueAsString(currentNode, v)) {
@ -371,7 +372,7 @@ void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) {
return;
}
trim(v);
v = ai_trim(v);
aiString aistr;
aistr.Set(v);
@ -396,7 +397,7 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
std::string animName;
if (!XmlParser::getStdStrAttribute(node, "name", animName)) {
if (!XmlParser::getStdStrAttribute( node, "id", animName )) {
animName = std::string("animation_") + to_string(mAnimationClipLibrary.size());
animName = std::string("animation_") + ai_to_string(mAnimationClipLibrary.size());
}
}
@ -407,7 +408,7 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
const std::string &currentName = currentNode.name();
if (currentName == "instance_animation") {
std::string url;
readUrlAttribute(node, url);
readUrlAttribute(currentNode, url);
clip.second.push_back(url);
}
@ -419,8 +420,8 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
void ColladaParser::PostProcessControllers() {
std::string meshId;
for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it) {
meshId = it->second.mMeshId;
for (auto & it : mControllerLibrary) {
meshId = it.second.mMeshId;
if (meshId.empty()) {
continue;
}
@ -431,7 +432,7 @@ void ColladaParser::PostProcessControllers() {
findItr = mControllerLibrary.find(meshId);
}
it->second.mMeshId = meshId;
it.second.mMeshId = meshId;
}
}
@ -444,22 +445,19 @@ void ColladaParser::PostProcessRootAnimations() {
}
Animation temp;
for (AnimationClipLibrary::iterator it = mAnimationClipLibrary.begin(); it != mAnimationClipLibrary.end(); ++it) {
std::string clipName = it->first;
for (auto & it : mAnimationClipLibrary) {
std::string clipName = it.first;
Animation *clip = new Animation();
clip->mName = clipName;
temp.mSubAnims.push_back(clip);
for (std::vector<std::string>::iterator a = it->second.begin(); a != it->second.end(); ++a) {
std::string animationID = *a;
for (std::string animationID : it.second) {
AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
if (animation != mAnimationLibrary.end()) {
Animation *pSourceAnimation = animation->second;
pSourceAnimation->CollectChannelsRecursively(clip->mChannels);
}
}
@ -495,7 +493,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
// an <animation> element may be a container for grouping sub-elements or an animation channel
// this is the channel collection by ID, in case it has channels
using ChannelMap = std::map<std::string, AnimationChannel> ;
using ChannelMap = std::map<std::string, AnimationChannel>;
ChannelMap channels;
// this is the anim container in case we're a container
Animation *anim = nullptr;
@ -531,17 +529,17 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
// have it read into a channel
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
ReadAnimationSampler(currentNode, newChannel->second);
} else if (currentName == "channel") {
std::string source_name, target;
XmlParser::getStdStrAttribute(currentNode, "source", source_name);
XmlParser::getStdStrAttribute(currentNode, "target", target);
if (source_name[0] == '#') {
source_name = source_name.substr(1, source_name.size() - 1);
}
ChannelMap::iterator cit = channels.find(source_name);
if (cit != channels.end()) {
cit->second.mTarget = target;
}
}
} else if (currentName == "channel") {
std::string source_name, target;
XmlParser::getStdStrAttribute(currentNode, "source", source_name);
XmlParser::getStdStrAttribute(currentNode, "target", target);
if (source_name[0] == '#') {
source_name = source_name.substr(1, source_name.size() - 1);
}
ChannelMap::iterator cit = channels.find(source_name);
if (cit != channels.end()) {
cit->second.mTarget = target;
}
}
}
@ -554,8 +552,8 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
pParent->mSubAnims.push_back(anim);
}
for (ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it) {
anim->mChannels.push_back(it->second);
for (const auto & channel : channels) {
anim->mChannels.push_back(channel.second);
}
if (idAttr) {
@ -610,50 +608,62 @@ void ColladaParser::ReadControllerLibrary(XmlNode &node) {
if (currentName != "controller") {
continue;
}
std::string id = node.attribute("id").as_string();
mControllerLibrary[id] = Controller();
ReadController(node, mControllerLibrary[id]);
std::string id;
if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
mControllerLibrary[id] = Controller();
ReadController(currentNode, mControllerLibrary[id]);
}
}
}
// ------------------------------------------------------------------------------------------------
// Reads a controller into the given mesh structure
void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pController) {
void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controller) {
// initial values
pController.mType = Skin;
pController.mMethod = Normalized;
for (XmlNode &currentNode : node.children()) {
controller.mType = Skin;
controller.mMethod = Normalized;
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
//for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "morph") {
pController.mType = Morph;
pController.mMeshId = currentNode.attribute("source").as_string();
controller.mType = Morph;
controller.mMeshId = currentNode.attribute("source").as_string();
int methodIndex = currentNode.attribute("method").as_int();
if (methodIndex > 0) {
std::string method;
XmlParser::getValueAsString(currentNode, method);
if (method == "RELATIVE") {
pController.mMethod = Relative;
controller.mMethod = Relative;
}
}
} else if (currentName == "skin") {
pController.mMeshId = currentNode.attribute("source").as_string();
std::string id;
if (XmlParser::getStdStrAttribute(currentNode, "source", id)) {
controller.mMeshId = id.substr(1, id.size()-1);
}
} else if (currentName == "bind_shape_matrix") {
std::string v;
XmlParser::getValueAsString(currentNode, v);
const char *content = v.c_str();
for (unsigned int a = 0; a < 16; a++) {
SkipSpacesAndLineEnd(&content);
// read a number
content = fast_atoreal_move<ai_real>(content, pController.mBindShapeMatrix[a]);
content = fast_atoreal_move<ai_real>(content, controller.mBindShapeMatrix[a]);
// skip whitespace after it
SkipSpacesAndLineEnd(&content);
}
} else if (currentName == "source") {
ReadSource(currentNode);
} else if (currentName == "joints") {
ReadControllerJoints(currentNode, pController);
ReadControllerJoints(currentNode, controller);
} else if (currentName == "vertex_weights") {
ReadControllerWeights(currentNode, pController);
ReadControllerWeights(currentNode, controller);
} else if (currentName == "targets") {
for (XmlNode currentChildNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentChildName = currentChildNode.name();
@ -661,9 +671,9 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll
const char *semantics = currentChildNode.attribute("semantic").as_string();
const char *source = currentChildNode.attribute("source").as_string();
if (strcmp(semantics, "MORPH_TARGET") == 0) {
pController.mMorphTarget = source + 1;
controller.mMorphTarget = source + 1;
} else if (strcmp(semantics, "MORPH_WEIGHT") == 0) {
pController.mMorphWeight = source + 1;
controller.mMorphWeight = source + 1;
}
}
}
@ -701,6 +711,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
// Read vertex count from attributes and resize the array accordingly
int vertexCount=0;
XmlParser::getIntAttribute(node, "count", vertexCount);
pController.mWeightCounts.resize(vertexCount);
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
@ -726,7 +737,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <vertex_weights> data <input> element");
}
} else if (currentName == "vcount" && vertexCount > 0) {
const char *text = currentNode.value();
const char *text = currentNode.text().as_string();
size_t numWeights = 0;
for (std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
if (*text == 0) {
@ -763,18 +774,15 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
// ------------------------------------------------------------------------------------------------
// Reads the image library contents
void ColladaParser::ReadImageLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "image") {
std::string id = currentNode.attribute("id").as_string();
mImageLibrary[id] = Image();
// read on from there
ReadImage(currentNode, mImageLibrary[id]);
std::string id;
if (XmlParser::getStdStrAttribute( currentNode, "id", id )) {
mImageLibrary[id] = Image();
// read on from there
ReadImage(currentNode, mImageLibrary[id]);
}
}
}
}
@ -793,7 +801,7 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
if (!currentNode.empty()) {
// element content is filename - hopefully
const char *sz = currentNode.text().as_string();
if (sz) {
if (nullptr != sz) {
aiString filepath(sz);
UriDecodePath(filepath);
pImage.mFileName = filepath.C_Str();
@ -843,10 +851,6 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
// ------------------------------------------------------------------------------------------------
// Reads the material library
void ColladaParser::ReadMaterialLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
std::map<std::string, int> names;
for (XmlNode &currentNode : node.children()) {
std::string id = currentNode.attribute("id").as_string();
@ -873,10 +877,6 @@ void ColladaParser::ReadMaterialLibrary(XmlNode &node) {
// ------------------------------------------------------------------------------------------------
// Reads the light library
void ColladaParser::ReadLightLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "light") {
@ -891,10 +891,6 @@ void ColladaParser::ReadLightLibrary(XmlNode &node) {
// ------------------------------------------------------------------------------------------------
// Reads the camera library
void ColladaParser::ReadCameraLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "camera") {
@ -961,33 +957,33 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
SkipSpacesAndLineEnd(&content);
} else if (currentName == "constant_attenuation") {
XmlParser::getFloatAttribute(currentNode, "constant_attenuation", pLight.mAttConstant);
XmlParser::getRealAttribute(currentNode, "constant_attenuation", pLight.mAttConstant);
} else if (currentName == "linear_attenuation") {
XmlParser::getFloatAttribute(currentNode, "linear_attenuation", pLight.mAttLinear);
XmlParser::getRealAttribute(currentNode, "linear_attenuation", pLight.mAttLinear);
} else if (currentName == "quadratic_attenuation") {
XmlParser::getFloatAttribute(currentNode, "quadratic_attenuation", pLight.mAttQuadratic);
XmlParser::getRealAttribute(currentNode, "quadratic_attenuation", pLight.mAttQuadratic);
} else if (currentName == "falloff_angle") {
XmlParser::getFloatAttribute(currentNode, "falloff_angle", pLight.mFalloffAngle);
XmlParser::getRealAttribute(currentNode, "falloff_angle", pLight.mFalloffAngle);
} else if (currentName == "falloff_exponent") {
XmlParser::getFloatAttribute(currentNode, "falloff_exponent", pLight.mFalloffExponent);
XmlParser::getRealAttribute(currentNode, "falloff_exponent", pLight.mFalloffExponent);
}
// FCOLLADA extensions
// -------------------------------------------------------
else if (currentName == "outer_cone") {
XmlParser::getFloatAttribute(currentNode, "outer_cone", pLight.mOuterAngle);
XmlParser::getRealAttribute(currentNode, "outer_cone", pLight.mOuterAngle);
} else if (currentName == "penumbra_angle") { // ... and this one is even deprecated
XmlParser::getFloatAttribute(currentNode, "penumbra_angle", pLight.mPenumbraAngle);
XmlParser::getRealAttribute(currentNode, "penumbra_angle", pLight.mPenumbraAngle);
} else if (currentName == "intensity") {
XmlParser::getFloatAttribute(currentNode, "intensity", pLight.mIntensity);
XmlParser::getRealAttribute(currentNode, "intensity", pLight.mIntensity);
} else if (currentName == "falloff") {
XmlParser::getFloatAttribute(currentNode, "falloff", pLight.mOuterAngle);
XmlParser::getRealAttribute(currentNode, "falloff", pLight.mOuterAngle);
} else if (currentName == "hotspot_beam") {
XmlParser::getFloatAttribute(currentNode, "hotspot_beam", pLight.mFalloffAngle);
XmlParser::getRealAttribute(currentNode, "hotspot_beam", pLight.mFalloffAngle);
}
// OpenCOLLADA extensions
// -------------------------------------------------------
else if (currentName == "decay_falloff") {
XmlParser::getFloatAttribute(currentNode, "decay_falloff", pLight.mOuterAngle);
XmlParser::getRealAttribute(currentNode, "decay_falloff", pLight.mOuterAngle);
}
}
}
@ -1166,15 +1162,15 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
} else if (currentName == "mirrorV") {
XmlParser::getBoolAttribute(currentNode, currentName.c_str(), out.mMirrorV);
} else if (currentName == "repeatU") {
XmlParser::getFloatAttribute(currentNode, currentName.c_str(), out.mTransform.mScaling.x);
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mTransform.mScaling.x);
} else if (currentName == "repeatV") {
XmlParser::getFloatAttribute(currentNode, currentName.c_str(), out.mTransform.mScaling.y);
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mTransform.mScaling.y);
} else if (currentName == "offsetU") {
XmlParser::getFloatAttribute(currentNode, currentName.c_str(), out.mTransform.mTranslation.x);
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mTransform.mTranslation.x);
} else if (currentName == "offsetV") {
XmlParser::getFloatAttribute(currentNode, currentName.c_str(), out.mTransform.mTranslation.y);
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mTransform.mTranslation.y);
} else if (currentName == "rotateUV") {
XmlParser::getFloatAttribute(currentNode, currentName.c_str(), out.mTransform.mRotation);
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mTransform.mRotation);
} else if (currentName == "blend_mode") {
std::string v;
XmlParser::getValueAsString(currentNode, v);
@ -1194,14 +1190,14 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
// OKINO extensions
// -------------------------------------------------------
else if (currentName == "weighting") {
XmlParser::getFloatAttribute(currentNode, currentName.c_str(), out.mWeighting);
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mWeighting);
} else if (currentName == "mix_with_previous_layer") {
XmlParser::getFloatAttribute(currentNode, currentName.c_str(), out.mMixWithPrevious);
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mMixWithPrevious);
}
// MAX3D extensions
// -------------------------------------------------------
else if (currentName == "amount") {
XmlParser::getFloatAttribute(currentNode, currentName.c_str(), out.mWeighting);
XmlParser::getRealAttribute(currentNode, currentName.c_str(), out.mWeighting);
}
}
}
@ -1419,7 +1415,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
XmlParser::getUIntAttribute(node, "count", count);
std::string v;
XmlParser::getValueAsString(node, v);
trim(v);
v = ai_trim(v);
const char *content = v.c_str();
// read values and store inside an array in the data library
@ -1738,14 +1734,16 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
// and read all indices into a temporary array
std::vector<size_t> indices;
if (expectedPointCount > 0)
if (expectedPointCount > 0) {
indices.reserve(expectedPointCount * numOffsets);
}
if (pNumPrimitives > 0) // It is possible to not contain any indices
{
// It is possible to not contain any indices
if (pNumPrimitives > 0) {
std::string v;
XmlParser::getValueAsString(node, v);
const char *content = v.c_str();
SkipSpacesAndLineEnd(&content);
while (*content != 0) {
// read a value.
// Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways.
@ -1772,21 +1770,24 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
// find the data for all sources
for (std::vector<InputChannel>::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
InputChannel &input = *it;
if (input.mResolved)
if (input.mResolved) {
continue;
}
// find accessor
input.mResolved = &ResolveLibraryReference(mAccessorLibrary, input.mAccessor);
// resolve accessor's data pointer as well, if necessary
const Accessor *acc = input.mResolved;
if (!acc->mData)
if (!acc->mData) {
acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource);
}
}
// and the same for the per-index channels
for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
InputChannel &input = *it;
if (input.mResolved)
if (input.mResolved) {
continue;
}
// ignore vertex pointer, it doesn't refer to an accessor
if (input.mType == IT_Vertex) {
@ -1801,8 +1802,9 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
input.mResolved = &ResolveLibraryReference(mAccessorLibrary, input.mAccessor);
// resolve accessor's data pointer as well, if necessary
const Accessor *acc = input.mResolved;
if (!acc->mData)
if (!acc->mData) {
acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource);
}
}
// For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
@ -1884,11 +1886,13 @@ void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t n
ai_assert((baseOffset + numOffsets - 1) < indices.size());
// extract per-vertex channels using the global per-vertex offset
for (std::vector<InputChannel>::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it)
for (std::vector<InputChannel>::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
ExtractDataObjectFromChannel(*it, indices[baseOffset + perVertexOffset], pMesh);
}
// and extract per-index channels using there specified offset
for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it)
for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
ExtractDataObjectFromChannel(*it, indices[baseOffset + it->mOffset], pMesh);
}
// store the vertex-data index for later assignment of bone vertex weights
pMesh.mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]);
@ -1912,8 +1916,9 @@ void ColladaParser::ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset,
// Extracts a single object from an input channel and stores it in the appropriate mesh data array
void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, size_t pLocalIndex, Mesh &pMesh) {
// ignore vertex referrer - we handle them that separate
if (pInput.mType == IT_Vertex)
if (pInput.mType == IT_Vertex) {
return;
}
const Accessor &acc = *pInput.mResolved;
if (pLocalIndex >= acc.mCount) {
@ -1926,86 +1931,93 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
// assemble according to the accessors component sub-offset list. We don't care, yet,
// what kind of object exactly we're extracting here
ai_real obj[4];
for (size_t c = 0; c < 4; ++c)
for (size_t c = 0; c < 4; ++c) {
obj[c] = dataObject[acc.mSubOffset[c]];
}
// now we reinterpret it according to the type we're reading here
switch (pInput.mType) {
case IT_Position: // ignore all position streams except 0 - there can be only one position
if (pInput.mIndex == 0)
pMesh.mPositions.push_back(aiVector3D(obj[0], obj[1], obj[2]));
else
ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
break;
case IT_Normal:
// pad to current vertex count if necessary
if (pMesh.mNormals.size() < pMesh.mPositions.size() - 1)
pMesh.mNormals.insert(pMesh.mNormals.end(), pMesh.mPositions.size() - pMesh.mNormals.size() - 1, aiVector3D(0, 1, 0));
// ignore all normal streams except 0 - there can be only one normal
if (pInput.mIndex == 0)
pMesh.mNormals.push_back(aiVector3D(obj[0], obj[1], obj[2]));
else
ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
break;
case IT_Tangent:
// pad to current vertex count if necessary
if (pMesh.mTangents.size() < pMesh.mPositions.size() - 1)
pMesh.mTangents.insert(pMesh.mTangents.end(), pMesh.mPositions.size() - pMesh.mTangents.size() - 1, aiVector3D(1, 0, 0));
// ignore all tangent streams except 0 - there can be only one tangent
if (pInput.mIndex == 0)
pMesh.mTangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
else
ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
break;
case IT_Bitangent:
// pad to current vertex count if necessary
if (pMesh.mBitangents.size() < pMesh.mPositions.size() - 1)
pMesh.mBitangents.insert(pMesh.mBitangents.end(), pMesh.mPositions.size() - pMesh.mBitangents.size() - 1, aiVector3D(0, 0, 1));
// ignore all bitangent streams except 0 - there can be only one bitangent
if (pInput.mIndex == 0)
pMesh.mBitangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
else
ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
break;
case IT_Texcoord:
// up to 4 texture coord sets are fine, ignore the others
if (pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) {
// pad to current vertex count if necessary
if (pMesh.mTexCoords[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
pMesh.mTexCoords[pInput.mIndex].insert(pMesh.mTexCoords[pInput.mIndex].end(),
pMesh.mPositions.size() - pMesh.mTexCoords[pInput.mIndex].size() - 1, aiVector3D(0, 0, 0));
pMesh.mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2]));
if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */
pMesh.mNumUVComponents[pInput.mIndex] = 3;
} else {
ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping.");
}
break;
case IT_Color:
// up to 4 color sets are fine, ignore the others
if (pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) {
// pad to current vertex count if necessary
if (pMesh.mColors[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
pMesh.mColors[pInput.mIndex].insert(pMesh.mColors[pInput.mIndex].end(),
pMesh.mPositions.size() - pMesh.mColors[pInput.mIndex].size() - 1, aiColor4D(0, 0, 0, 1));
aiColor4D result(0, 0, 0, 1);
for (size_t i = 0; i < pInput.mResolved->mSize; ++i) {
result[static_cast<unsigned int>(i)] = obj[pInput.mResolved->mSubOffset[i]];
case IT_Position: // ignore all position streams except 0 - there can be only one position
if (pInput.mIndex == 0) {
pMesh.mPositions.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
}
pMesh.mColors[pInput.mIndex].push_back(result);
} else {
ASSIMP_LOG_ERROR("Collada: too many vertex color sets. Skipping.");
}
break;
case IT_Normal:
// pad to current vertex count if necessary
if (pMesh.mNormals.size() < pMesh.mPositions.size() - 1)
pMesh.mNormals.insert(pMesh.mNormals.end(), pMesh.mPositions.size() - pMesh.mNormals.size() - 1, aiVector3D(0, 1, 0));
break;
default:
// IT_Invalid and IT_Vertex
ai_assert(false && "shouldn't ever get here");
// ignore all normal streams except 0 - there can be only one normal
if (pInput.mIndex == 0) {
pMesh.mNormals.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
}
break;
case IT_Tangent:
// pad to current vertex count if necessary
if (pMesh.mTangents.size() < pMesh.mPositions.size() - 1)
pMesh.mTangents.insert(pMesh.mTangents.end(), pMesh.mPositions.size() - pMesh.mTangents.size() - 1, aiVector3D(1, 0, 0));
// ignore all tangent streams except 0 - there can be only one tangent
if (pInput.mIndex == 0) {
pMesh.mTangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
}
break;
case IT_Bitangent:
// pad to current vertex count if necessary
if (pMesh.mBitangents.size() < pMesh.mPositions.size() - 1) {
pMesh.mBitangents.insert(pMesh.mBitangents.end(), pMesh.mPositions.size() - pMesh.mBitangents.size() - 1, aiVector3D(0, 0, 1));
}
// ignore all bitangent streams except 0 - there can be only one bitangent
if (pInput.mIndex == 0) {
pMesh.mBitangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
} else {
ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
}
break;
case IT_Texcoord:
// up to 4 texture coord sets are fine, ignore the others
if (pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) {
// pad to current vertex count if necessary
if (pMesh.mTexCoords[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
pMesh.mTexCoords[pInput.mIndex].insert(pMesh.mTexCoords[pInput.mIndex].end(),
pMesh.mPositions.size() - pMesh.mTexCoords[pInput.mIndex].size() - 1, aiVector3D(0, 0, 0));
pMesh.mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2]));
if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) {
pMesh.mNumUVComponents[pInput.mIndex] = 3;
}
} else {
ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping.");
}
break;
case IT_Color:
// up to 4 color sets are fine, ignore the others
if (pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) {
// pad to current vertex count if necessary
if (pMesh.mColors[pInput.mIndex].size() < pMesh.mPositions.size() - 1)
pMesh.mColors[pInput.mIndex].insert(pMesh.mColors[pInput.mIndex].end(),
pMesh.mPositions.size() - pMesh.mColors[pInput.mIndex].size() - 1, aiColor4D(0, 0, 0, 1));
aiColor4D result(0, 0, 0, 1);
for (size_t i = 0; i < pInput.mResolved->mSize; ++i) {
result[static_cast<unsigned int>(i)] = obj[pInput.mResolved->mSubOffset[i]];
}
pMesh.mColors[pInput.mIndex].push_back(result);
} else {
ASSIMP_LOG_ERROR("Collada: too many vertex color sets. Skipping.");
}
break;
default:
// IT_Invalid and IT_Vertex
ai_assert(false && "shouldn't ever get here");
}
}

View File

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

View File

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

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team

View File

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

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -473,7 +473,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
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 DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", ai_to_string(version), ") of the FBX format. (", e.what(), ")");
}
throw;
}

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -62,16 +62,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP
# include <unordered_map>
# include <unordered_set>
# if _MSC_VER > 1600
# define fbx_unordered_map unordered_map
# define fbx_unordered_multimap unordered_multimap
# define fbx_unordered_set unordered_set
# define fbx_unordered_multiset unordered_multiset
# else
# if defined(_MSC_VER) && _MSC_VER <= 1600
# define fbx_unordered_map tr1::unordered_map
# define fbx_unordered_multimap tr1::unordered_multimap
# define fbx_unordered_set tr1::unordered_set
# define fbx_unordered_multiset tr1::unordered_multiset
# else
# define fbx_unordered_map unordered_map
# define fbx_unordered_multimap unordered_multimap
# define fbx_unordered_set unordered_set
# define fbx_unordered_multiset unordered_multiset
# endif
#endif

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -3440,7 +3440,7 @@ void FBXConverter::ConvertGlobalSettings() {
mSceneOut->mMetaData->Set(12, "TimeSpanStart", doc.GlobalSettings().TimeSpanStart());
mSceneOut->mMetaData->Set(13, "TimeSpanStop", doc.GlobalSettings().TimeSpanStop());
mSceneOut->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
mSceneOut->mMetaData->Set(15, AI_METADATA_SOURCE_FORMAT_VERSION, aiString(to_string(doc.FBXVersion())));
mSceneOut->mMetaData->Set(15, AI_METADATA_SOURCE_FORMAT_VERSION, aiString(ai_to_string(doc.FBXVersion())));
if (hasGenerator) {
mSceneOut->mMetaData->Set(16, AI_METADATA_SOURCE_GENERATOR, aiString(doc.Creator()));
}
@ -3454,42 +3454,42 @@ void FBXConverter::TransferDataToScene() {
// many C++ users seem to know this, so pointing it out to avoid
// confusion why this code works.
if (mMeshes.size()) {
if (!mMeshes.empty()) {
mSceneOut->mMeshes = new aiMesh *[mMeshes.size()]();
mSceneOut->mNumMeshes = static_cast<unsigned int>(mMeshes.size());
std::swap_ranges(mMeshes.begin(), mMeshes.end(), mSceneOut->mMeshes);
}
if (materials.size()) {
if (!materials.empty()) {
mSceneOut->mMaterials = new aiMaterial *[materials.size()]();
mSceneOut->mNumMaterials = static_cast<unsigned int>(materials.size());
std::swap_ranges(materials.begin(), materials.end(), mSceneOut->mMaterials);
}
if (animations.size()) {
if (!animations.empty()) {
mSceneOut->mAnimations = new aiAnimation *[animations.size()]();
mSceneOut->mNumAnimations = static_cast<unsigned int>(animations.size());
std::swap_ranges(animations.begin(), animations.end(), mSceneOut->mAnimations);
}
if (lights.size()) {
if (!lights.empty()) {
mSceneOut->mLights = new aiLight *[lights.size()]();
mSceneOut->mNumLights = static_cast<unsigned int>(lights.size());
std::swap_ranges(lights.begin(), lights.end(), mSceneOut->mLights);
}
if (cameras.size()) {
if (!cameras.empty()) {
mSceneOut->mCameras = new aiCamera *[cameras.size()]();
mSceneOut->mNumCameras = static_cast<unsigned int>(cameras.size());
std::swap_ranges(cameras.begin(), cameras.end(), mSceneOut->mCameras);
}
if (textures.size()) {
if (!textures.empty()) {
mSceneOut->mTextures = new aiTexture *[textures.size()]();
mSceneOut->mNumTextures = static_cast<unsigned int>(textures.size());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -426,7 +426,7 @@ void FBX::Node::WritePropertyNodeAscii(
char buffer[32];
FBX::Node node(name);
node.Begin(s, false, indent);
std::string vsize = to_string(v.size());
std::string vsize = ai_to_string(v.size());
// *<size> {
s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n");
// indent + 1
@ -462,7 +462,7 @@ void FBX::Node::WritePropertyNodeAscii(
char buffer[32];
FBX::Node node(name);
node.Begin(s, false, indent);
std::string vsize = to_string(v.size());
std::string vsize = ai_to_string(v.size());
// *<size> {
s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n");
// indent + 1

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -812,6 +812,18 @@ void FBXExporter::WriteDefinitions ()
// Geometry / FbxMesh
// <~~ aiMesh
count = mScene->mNumMeshes;
// Blendshapes are considered Geometry
int32_t bsDeformerCount=0;
for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
aiMesh* m = mScene->mMeshes[mi];
if (m->mNumAnimMeshes > 0) {
count+=m->mNumAnimMeshes;
bsDeformerCount+=m->mNumAnimMeshes; // One deformer per blendshape
bsDeformerCount++; // Plus one master blendshape deformer
}
}
if (count) {
n = FBX::Node("ObjectType", "Geometry");
n.AddChild("Count", count);
@ -978,7 +990,7 @@ void FBXExporter::WriteDefinitions ()
}
// Deformer
count = int32_t(count_deformers(mScene));
count = int32_t(count_deformers(mScene))+bsDeformerCount;
if (count) {
n = FBX::Node("ObjectType", "Deformer");
n.AddChild("Count", count);
@ -1363,6 +1375,7 @@ void FBXExporter::WriteObjects ()
n.End(outstream, binary, indent, true);
}
// aiMaterial
material_uids.clear();
for (size_t i = 0; i < mScene->mNumMaterials; ++i) {
@ -1697,6 +1710,100 @@ void FBXExporter::WriteObjects ()
}
}
// Blendshapes, if any
for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
const aiMesh* m = mScene->mMeshes[mi];
if (m->mNumAnimMeshes == 0) {
continue;
}
// make a deformer for this mesh
int64_t deformer_uid = generate_uid();
FBX::Node dnode("Deformer");
dnode.AddProperties(deformer_uid, m->mName.data + FBX::SEPARATOR + "Blendshapes", "BlendShape");
dnode.AddChild("Version", int32_t(101));
dnode.Dump(outstream, binary, indent);
// connect it
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
std::vector<int32_t> vertex_indices = vVertexIndice[mi];
for (unsigned int am = 0; am < m->mNumAnimMeshes; ++am) {
aiAnimMesh *pAnimMesh = m->mAnimMeshes[am];
std::string blendshape_name = pAnimMesh->mName.data;
// start the node record
FBX::Node bsnode("Geometry");
int64_t blendshape_uid = generate_uid();
mesh_uids.push_back(blendshape_uid);
bsnode.AddProperty(blendshape_uid);
bsnode.AddProperty(blendshape_name + FBX::SEPARATOR + "Blendshape");
bsnode.AddProperty("Shape");
bsnode.AddChild("Version", int32_t(100));
bsnode.Begin(outstream, binary, indent);
bsnode.DumpProperties(outstream, binary, indent);
bsnode.EndProperties(outstream, binary, indent);
bsnode.BeginChildren(outstream, binary, indent);
indent++;
if (pAnimMesh->HasPositions()) {
std::vector<int32_t>shape_indices;
std::vector<double>pPositionDiff;
std::vector<double>pNormalDiff;
for (unsigned int vt = 0; vt < vertex_indices.size(); ++vt) {
aiVector3D pDiff = (pAnimMesh->mVertices[vertex_indices[vt]] - m->mVertices[vertex_indices[vt]]);
if(pDiff.Length()>1e-8){
shape_indices.push_back(vertex_indices[vt]);
pPositionDiff.push_back(pDiff[0]);
pPositionDiff.push_back(pDiff[1]);
pPositionDiff.push_back(pDiff[2]);
if (pAnimMesh->HasNormals()) {
aiVector3D nDiff = (pAnimMesh->mNormals[vertex_indices[vt]] - m->mNormals[vertex_indices[vt]]);
pNormalDiff.push_back(nDiff[0]);
pNormalDiff.push_back(nDiff[1]);
pNormalDiff.push_back(nDiff[2]);
}
}
}
FBX::Node::WritePropertyNode(
"Indexes", shape_indices, outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"Vertices", pPositionDiff, outstream, binary, indent
);
if (pNormalDiff.size()>0) {
FBX::Node::WritePropertyNode(
"Normals", pNormalDiff, outstream, binary, indent
);
}
}
indent--;
bsnode.End(outstream, binary, indent, true);
// Add blendshape Channel Deformer
FBX::Node sdnode("Deformer");
const int64_t blendchannel_uid = generate_uid();
sdnode.AddProperties(
blendchannel_uid, blendshape_name + FBX::SEPARATOR + "SubDeformer", "BlendShapeChannel"
);
sdnode.AddChild("Version", int32_t(100));
sdnode.AddChild("DeformPercent", float_t(0.0));
FBX::Node p("Properties70");
p.AddP70numberA("DeformPercent", 0.0);
sdnode.AddChild(p);
// TODO: Normally just one weight per channel, adding stub for later development
std::vector<float>fFullWeights;
fFullWeights.push_back(100.);
sdnode.AddChild("FullWeights", fFullWeights);
sdnode.Dump(outstream, binary, indent);
connections.emplace_back("C", "OO", blendchannel_uid, deformer_uid);
connections.emplace_back("C", "OO", blendshape_uid, blendchannel_uid);
}
}
// bones.
//
// output structure:

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2021, assimp team
All rights reserved.
@ -54,18 +54,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ByteSwapper.h>
#include <assimp/ParsingUtils.h>
#include <algorithm> // std::transform
#include "FBXUtil.h"
namespace Assimp {
namespace FBX {
using namespace Util;
using namespace Util;
// ------------------------------------------------------------------------------------------------
Material::Material(uint64_t id, const Element& element, const Document& doc, const std::string& name)
: Object(id,element,name)
{
Material::Material(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
Object(id,element,name) {
const Scope& sc = GetRequiredScope(element);
const Element* const ShadingModel = sc["ShadingModel"];
@ -77,23 +75,21 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
if(ShadingModel) {
shading = ParseTokenAsString(GetRequiredToken(*ShadingModel,0));
}
else {
} else {
DOMWarning("shading mode not specified, assuming phong",&element);
shading = "phong";
}
std::string templateName;
// lower-case shading because Blender (for example) writes "Phong"
std::transform(shading.data(), shading.data() + shading.size(), std::addressof(shading[0]), Assimp::ToLower<char>);
for (size_t i = 0; i < shading.length(); ++i) {
shading[i] = static_cast<char>(tolower(shading[i]));
}
std::string templateName;
if(shading == "phong") {
templateName = "Material.FbxSurfacePhong";
}
else if(shading == "lambert") {
} else if(shading == "lambert") {
templateName = "Material.FbxSurfaceLambert";
}
else {
} else {
DOMWarning("shading mode not recognized: " + shading,&element);
}
@ -102,20 +98,19 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
// resolve texture links
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
for(const Connection* con : conns) {
// texture link to properties, not objects
if (!con->PropertyName().length()) {
if ( 0 == con->PropertyName().length()) {
continue;
}
const Object* const ob = con->SourceObject();
if(!ob) {
if(nullptr == ob) {
DOMWarning("failed to read source object for texture link, ignoring",&element);
continue;
}
const Texture* const tex = dynamic_cast<const Texture*>(ob);
if(!tex) {
if(nullptr == tex) {
const LayeredTexture* const layeredTexture = dynamic_cast<const LayeredTexture*>(ob);
if(!layeredTexture) {
DOMWarning("source object for texture link is not a texture or layered texture, ignoring",&element);
@ -128,9 +123,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
layeredTextures[prop] = layeredTexture;
((LayeredTexture*)layeredTexture)->fillTexture(doc);
}
else
{
} else {
const std::string& prop = con->PropertyName();
if (textures.find(prop) != textures.end()) {
DOMWarning("duplicate texture link: " + prop,&element);
@ -138,23 +131,20 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
textures[prop] = tex;
}
}
}
// ------------------------------------------------------------------------------------------------
Material::~Material()
{
Material::~Material() {
// empty
}
// ------------------------------------------------------------------------------------------------
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name)
: Object(id,element,name)
, uvScaling(1.0f,1.0f)
, media(0)
{
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
Object(id,element,name),
uvScaling(1.0f,1.0f),
media(0) {
const Scope& sc = GetRequiredScope(element);
const Element* const Type = sc["Type"];
@ -194,8 +184,7 @@ Texture::Texture(uint64_t id, const Element& element, const Document& doc, const
crop[1] = ParseTokenAsInt(GetRequiredToken(*Cropping,1));
crop[2] = ParseTokenAsInt(GetRequiredToken(*Cropping,2));
crop[3] = ParseTokenAsInt(GetRequiredToken(*Cropping,3));
}
else {
} else {
// vc8 doesn't support the crop() syntax in initialization lists
// (and vc9 WARNS about the new (i.e. compliant) behaviour).
crop[0] = crop[1] = crop[2] = crop[3] = 0;
@ -226,7 +215,7 @@ Texture::Texture(uint64_t id, const Element& element, const Document& doc, const
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
for(const Connection* con : conns) {
const Object* const ob = con->SourceObject();
if(!ob) {
if (nullptr == ob) {
DOMWarning("failed to read source object for texture link, ignoring",&element);
continue;
}
@ -240,46 +229,38 @@ Texture::Texture(uint64_t id, const Element& element, const Document& doc, const
}
Texture::~Texture()
{
Texture::~Texture() {
// empty
}
LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& /*doc*/, const std::string& name)
: Object(id,element,name)
,blendMode(BlendMode_Modulate)
,alpha(1)
{
LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& /*doc*/, const std::string& name) :
Object(id,element,name),
blendMode(BlendMode_Modulate),
alpha(1) {
const Scope& sc = GetRequiredScope(element);
const Element* const BlendModes = sc["BlendModes"];
const Element* const Alphas = sc["Alphas"];
if(BlendModes!=0)
{
if (nullptr != BlendModes) {
blendMode = (BlendMode)ParseTokenAsInt(GetRequiredToken(*BlendModes,0));
}
if(Alphas!=0)
{
if (nullptr != Alphas) {
alpha = ParseTokenAsFloat(GetRequiredToken(*Alphas,0));
}
}
LayeredTexture::~LayeredTexture()
{
LayeredTexture::~LayeredTexture() {
// empty
}
void LayeredTexture::fillTexture(const Document& doc)
{
void LayeredTexture::fillTexture(const Document& doc) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
for(size_t i = 0; i < conns.size();++i)
{
for(size_t i = 0; i < conns.size();++i) {
const Connection* con = conns.at(i);
const Object* const ob = con->SourceObject();
if(!ob) {
if (nullptr == ob) {
DOMWarning("failed to read source object for texture link, ignoring",&element);
continue;
}
@ -290,13 +271,11 @@ void LayeredTexture::fillTexture(const Document& doc)
}
}
// ------------------------------------------------------------------------------------------------
Video::Video(uint64_t id, const Element& element, const Document& doc, const std::string& name)
: Object(id,element,name)
, contentLength(0)
, content(0)
{
Video::Video(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
Object(id,element,name),
contentLength(0),
content(0) {
const Scope& sc = GetRequiredScope(element);
const Element* const Type = sc["Type"];
@ -324,52 +303,43 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
if (!token.IsBinary()) {
if (*data != '"') {
DOMError("embedded content is not surrounded by quotation marks", &element);
}
else {
} else {
size_t targetLength = 0;
auto numTokens = Content->Tokens().size();
// First time compute size (it could be large like 64Gb and it is good to allocate it once)
for (uint32_t tokenIdx = 0; tokenIdx < numTokens; ++tokenIdx)
{
for (uint32_t tokenIdx = 0; tokenIdx < numTokens; ++tokenIdx) {
const Token& dataToken = GetRequiredToken(*Content, tokenIdx);
size_t tokenLength = dataToken.end() - dataToken.begin() - 2; // ignore double quotes
const char* base64data = dataToken.begin() + 1;
const size_t outLength = Util::ComputeDecodedSizeBase64(base64data, tokenLength);
if (outLength == 0)
{
if (outLength == 0) {
DOMError("Corrupted embedded content found", &element);
}
targetLength += outLength;
}
if (targetLength == 0)
{
if (targetLength == 0) {
DOMError("Corrupted embedded content found", &element);
}
content = new uint8_t[targetLength];
contentLength = static_cast<uint64_t>(targetLength);
size_t dst_offset = 0;
for (uint32_t tokenIdx = 0; tokenIdx < numTokens; ++tokenIdx)
{
for (uint32_t tokenIdx = 0; tokenIdx < numTokens; ++tokenIdx) {
const Token& dataToken = GetRequiredToken(*Content, tokenIdx);
size_t tokenLength = dataToken.end() - dataToken.begin() - 2; // ignore double quotes
const char* base64data = dataToken.begin() + 1;
dst_offset += Util::DecodeBase64(base64data, tokenLength, content + dst_offset, targetLength - dst_offset);
}
if (targetLength != dst_offset)
{
if (targetLength != dst_offset) {
delete[] content;
contentLength = 0;
DOMError("Corrupted embedded content found", &element);
}
}
}
else if (static_cast<size_t>(token.end() - data) < 5) {
} else if (static_cast<size_t>(token.end() - data) < 5) {
DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element);
}
else if (*data != 'R') {
} else if (*data != 'R') {
DOMWarning("video content is not raw binary data, ignoring", &element);
}
else {
} else {
// read number of elements
uint32_t len = 0;
::memcpy(&len, data + 1, sizeof(len));
@ -380,8 +350,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
content = new uint8_t[len];
::memcpy(content, data + 5, len);
}
} catch (const runtime_error& runtimeError)
{
} catch (const runtime_error& runtimeError) {
//we don't need the content data for contents that has already been loaded
ASSIMP_LOG_VERBOSE_DEBUG_F("Caught exception in FBXMaterial (likely because content was already loaded): ",
runtimeError.what());
@ -392,14 +361,11 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
}
Video::~Video()
{
if(content) {
delete[] content;
}
Video::~Video() {
delete[] content;
}
} //!FBX
} //!Assimp
#endif
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER

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