Merge pull request #3 from assimp/master

Merge Master Branch To My Branch
pull/4001/head
xiaohunqupo 2021-07-28 16:17:51 +08:00 committed by GitHub
commit 9923cd0e06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
290 changed files with 8156 additions and 11953 deletions

1
.github/FUNDING.yml vendored
View File

@ -1,2 +1 @@
patreon: assimp
open_collective: assimp

View File

@ -1,8 +1,8 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
title: 'Bug:'
labels: 'Bug'
assignees: ''
---
@ -23,16 +23,10 @@ A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
**Platform (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -2,7 +2,7 @@
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
labels: 'Feature-Request'
assignees: ''
---

View File

@ -0,0 +1,25 @@
---
name: Technical debt
about: Create a report to help us to fix and detect tech debts
title: ''
labels: 'Techdebt'
assignees: ''
---
**Describe the technical debt**
A clear and concise description of what the tech debt is about.
**Better solution**
A clear and concise description of what you would expect.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

5
.gitignore vendored
View File

@ -25,7 +25,7 @@ CMakeSettings.json
# Output
bin/
lib/
x64/
# QtCreator
CMakeLists.txt.user
@ -116,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

@ -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.293.tar.gz"
SHA1 "e8e5470652db77149d9b38656db2a6c0b7642693"
URL "https://github.com/cpp-pm/hunter/archive/v0.23.311.tar.gz"
SHA1 "1a82b9b73055879181cb1466b2ab5d48ee8ae410"
)
add_definitions(-DASSIMP_USE_HUNTER)
@ -268,6 +268,8 @@ ELSEIF(MSVC)
ADD_COMPILE_OPTIONS(/wd4351)
ENDIF()
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_STANDARD 11)
@ -334,9 +336,9 @@ INCLUDE (FindPkgMacros)
INCLUDE (PrecompiledHeader)
# Set Assimp project output directory variables.
SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for runtime output files")
SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for library output files")
SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib" CACHE STRING "Path for archive output files")
# Macro used to set the output directories of a target to the
# respective Assimp output directories.
@ -454,7 +456,7 @@ IF(ASSIMP_HUNTER_ENABLED)
ELSE()
# If the zlib is already found outside, add an export in case assimpTargets can't find it.
IF( ZLIB_FOUND )
INSTALL( TARGETS zlib
INSTALL( TARGETS zlib zlibstatic
EXPORT "${TARGETS_EXPORT_NAME}")
ENDIF()
@ -527,12 +529,12 @@ ENDIF()
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL
"Build the C4D importer, which relies on the non-free Melange SDK."
"Build the C4D importer, which relies on the non-free Cineware SDK."
)
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
IF ( MSVC )
SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/includes")
SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/includes")
# pick the correct prebuilt library
IF(MSVC15)
@ -551,22 +553,23 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
)
ENDIF()
SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/libraries/win")
SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/libraries/win")
SET(C4D_DEBUG_LIBRARIES
"${C4D_LIB_BASE_PATH}/melangelib${C4D_LIB_POSTFIX}/melangelib_debug.lib"
"${C4D_LIB_BASE_PATH}/cinewarelib${C4D_LIB_POSTFIX}/cinewarelib_debug.lib"
"${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_debug.lib"
)
SET(C4D_RELEASE_LIBRARIES
"${C4D_LIB_BASE_PATH}/melangelib${C4D_LIB_POSTFIX}/melangelib_release.lib"
"${C4D_LIB_BASE_PATH}/cinewarelib${C4D_LIB_POSTFIX}/cinewarelib_release.lib"
"${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_release.lib"
)
# winsock and winmm are necessary dependencies of melange (this is undocumented, but true.)
# winsock and winmm are necessary (and undocumented) dependencies of Cineware SDK because
# it can be used to communicate with a running Cinema 4D instance
SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib)
ELSE ()
MESSAGE( FATAL_ERROR
"C4D is currently only available on Windows with melange SDK installed in contrib/Melange"
"C4D is currently only available on Windows with Cineware SDK installed in contrib/Cineware"
)
ENDIF ()
ELSE ()

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,10 +39,10 @@ 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)
* [Unity 3d Plugin](https://ricardoreis.net/trilib-2/)
* [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)
@ -66,9 +66,9 @@ Open Asset Import Library is implemented in C++. The directory structure looks l
The source code is organized in the following way:
code/Common The base implementation for importers and the infrastructure
code/PostProcessing The post-processing steps
code/<FormatName> Implementation for import and export for the format
code/Common The base implementation for importers and the infrastructure
code/PostProcessing The post-processing steps
code/AssetLib/<FormatName> Implementation for import and export for the format
### Where to get help ###
For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
@ -76,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>
@ -103,9 +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)
#### Organizations

View File

@ -9,6 +9,7 @@ find_package(poly2tri CONFIG REQUIRED)
find_package(polyclipping CONFIG REQUIRED)
find_package(zip CONFIG REQUIRED)
find_package(pugixml CONFIG REQUIRED)
find_package(stb CONFIG REQUIRED)
if(@ASSIMP_BUILD_DRACO@)
find_package(draco CONFIG REQUIRED)

View File

@ -69,7 +69,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
std::string s = mScene->mMaterials[i].mName;
for (std::string::iterator it = s.begin(); it != s.end(); ++it) {
*it = static_cast<char>(::tolower(*it));
*it = static_cast<char>(::tolower(static_cast<unsigned char>(*it)));
}
if (std::string::npos == s.find("default")) continue;
@ -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

@ -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;
}
@ -378,7 +379,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type
// TODO: handle embedded textures properly
if (path.data[0] == '*') {
ASSIMP_LOG_ERROR("Ignoring embedded texture for export: " + std::string(path.C_Str()));
ASSIMP_LOG_ERROR("Ignoring embedded texture for export: ", path.C_Str());
return;
}
@ -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

@ -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 */
@ -358,16 +348,16 @@ struct Texture {
// empty
}
Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(std::move(other.mTextureBlend)),
Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(other.mTextureBlend),
mMapName(std::move(other.mMapName)),
mOffsetU(std::move(other.mOffsetU)),
mOffsetV(std::move(other.mOffsetV)),
mScaleU(std::move(other.mScaleU)),
mScaleV(std::move(other.mScaleV)),
mRotation(std::move(other.mRotation)),
mMapMode(std::move(other.mMapMode)),
bPrivate(std::move(other.bPrivate)),
iUVSrc(std::move(other.iUVSrc)) {
mOffsetU(other.mOffsetU),
mOffsetV(other.mOffsetV),
mScaleU(other.mScaleU),
mScaleV(other.mScaleV),
mRotation(other.mRotation),
mMapMode(other.mMapMode),
bPrivate(other.bPrivate),
iUVSrc(other.iUVSrc) {
// empty
}
@ -376,16 +366,16 @@ struct Texture {
return *this;
}
mTextureBlend = std::move(other.mTextureBlend);
mTextureBlend = other.mTextureBlend;
mMapName = std::move(other.mMapName);
mOffsetU = std::move(other.mOffsetU);
mOffsetV = std::move(other.mOffsetV);
mScaleU = std::move(other.mScaleU);
mScaleV = std::move(other.mScaleV);
mRotation = std::move(other.mRotation);
mMapMode = std::move(other.mMapMode);
bPrivate = std::move(other.bPrivate);
iUVSrc = std::move(other.iUVSrc);
mOffsetU = other.mOffsetU;
mOffsetV = other.mOffsetV;
mScaleU = other.mScaleU;
mScaleV = other.mScaleV;
mRotation = other.mRotation;
mMapMode = other.mMapMode;
bPrivate = other.bPrivate;
iUVSrc = other.iUVSrc;
return *this;
}
@ -471,13 +461,13 @@ struct Material {
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
mDiffuse(std::move(other.mDiffuse)),
mSpecularExponent(std::move(other.mSpecularExponent)),
mShininessStrength(std::move(other.mShininessStrength)),
mSpecular(std::move(other.mSpecular)),
mAmbient(std::move(other.mAmbient)),
mShading(std::move(other.mShading)),
mTransparency(std::move(other.mTransparency)),
mDiffuse(other.mDiffuse),
mSpecularExponent(other.mSpecularExponent),
mShininessStrength(other.mShininessStrength),
mSpecular(other.mSpecular),
mAmbient(other.mAmbient),
mShading(other.mShading),
mTransparency(other.mTransparency),
sTexDiffuse(std::move(other.sTexDiffuse)),
sTexOpacity(std::move(other.sTexOpacity)),
sTexSpecular(std::move(other.sTexSpecular)),
@ -485,10 +475,10 @@ struct Material {
sTexBump(std::move(other.sTexBump)),
sTexEmissive(std::move(other.sTexEmissive)),
sTexShininess(std::move(other.sTexShininess)),
mBumpHeight(std::move(other.mBumpHeight)),
mEmissive(std::move(other.mEmissive)),
mBumpHeight(other.mBumpHeight),
mEmissive(other.mEmissive),
sTexAmbient(std::move(other.sTexAmbient)),
mTwoSided(std::move(other.mTwoSided)) {
mTwoSided(other.mTwoSided) {
// empty
}
@ -498,13 +488,13 @@ struct Material {
}
mName = std::move(other.mName);
mDiffuse = std::move(other.mDiffuse);
mSpecularExponent = std::move(other.mSpecularExponent);
mShininessStrength = std::move(other.mShininessStrength),
mSpecular = std::move(other.mSpecular);
mAmbient = std::move(other.mAmbient);
mShading = std::move(other.mShading);
mTransparency = std::move(other.mTransparency);
mDiffuse = other.mDiffuse;
mSpecularExponent = other.mSpecularExponent;
mShininessStrength = other.mShininessStrength,
mSpecular = other.mSpecular;
mAmbient = other.mAmbient;
mShading = other.mShading;
mTransparency = other.mTransparency;
sTexDiffuse = std::move(other.sTexDiffuse);
sTexOpacity = std::move(other.sTexOpacity);
sTexSpecular = std::move(other.sTexSpecular);
@ -512,10 +502,10 @@ struct Material {
sTexBump = std::move(other.sTexBump);
sTexEmissive = std::move(other.sTexEmissive);
sTexShininess = std::move(other.sTexShininess);
mBumpHeight = std::move(other.mBumpHeight);
mEmissive = std::move(other.mEmissive);
mBumpHeight = other.mBumpHeight;
mEmissive = other.mEmissive;
sTexAmbient = std::move(other.sTexAmbient);
mTwoSided = std::move(other.mTwoSided);
mTwoSided = other.mTwoSided;
return *this;
}

View File

@ -143,7 +143,13 @@ void Discreet3DSImporter::SetupProperties(const Importer * /*pImp*/) {
// Imports the given file into the given scene structure.
void Discreet3DSImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) {
StreamReaderLE theStream(pIOHandler->Open(pFile, "rb"));
auto theFile = pIOHandler->Open(pFile, "rb");
if (!theFile) {
throw DeadlyImportError("3DS: Could not open ", pFile);
}
StreamReaderLE theStream(theFile);
// We should have at least one chunk
if (theStream.GetRemainingSize() < 16) {
@ -164,7 +170,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;
@ -299,7 +305,7 @@ void Discreet3DSImporter::ParseEditorChunk() {
// print the version number
char buff[10];
ASSIMP_itoa10(buff, stream->GetI2());
ASSIMP_LOG_INFO_F(std::string("3DS file format version: "), buff);
ASSIMP_LOG_INFO("3DS file format version: ", buff);
} break;
};
ASSIMP_3DS_END_CHUNK();
@ -928,7 +934,7 @@ void Discreet3DSImporter::ParseFaceChunk() {
}
}
if (0xcdcdcdcd == idx) {
ASSIMP_LOG_ERROR_F("3DS: Unknown material: ", sz);
ASSIMP_LOG_ERROR("3DS: Unknown material: ", sz);
}
// Now continue and read all material indices

View File

@ -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

@ -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=\"" + ai_to_string(matIdx) + "\" />";
mModelOutput << std::endl;
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

@ -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_") + ai_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 = ai_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 = 0, 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(ai_to_string(basematerialsId));
const std::string strId(ai_to_string(basematerialsId));
stdMaterialName += "id";
stdMaterialName += strId;
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

@ -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

@ -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,13 +156,13 @@ 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) {
ASSIMP_LOG_WARN_F("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file);
ASSIMP_LOG_WARN("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file);
} else {
ASSIMP_LOG_WARN_F("Ignored file of unknown type: ", file);
ASSIMP_LOG_WARN("Ignored file of unknown type: ", file);
}
}
}
@ -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

@ -116,7 +116,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name
buffer = AcSkipToNextToken(buffer);
if (0 != name_length) {
if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) {
ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " + std::string(name) + " was expected.");
ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected.");
return buffer;
}
buffer += name_length + 1;
@ -492,7 +492,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
default:
// Coerce unknowns to a polygon and warn
ASSIMP_LOG_WARN_F("AC3D: The type flag of a surface is unknown: ", (*it).flags);
ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown: ", (*it).flags);
(*it).flags &= ~(Surface::Mask);
// fallthrough
@ -690,7 +690,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
if (object.subDiv) {
if (configEvalSubdivision) {
std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: " + object.name);
ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: ", object.name);
std::vector<aiMesh *> cpy(meshes.size() - oldm, nullptr);
div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true);
@ -698,7 +698,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
// previous meshes are deleted vy Subdivide().
} else {
ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: " + object.name);
ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: ", object.name);
}
}
}
@ -782,7 +782,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
unsigned int version = HexDigitToDecimal(buffer[4]);
char msg[3];
ASSIMP_itoa10(msg, 3, version);
ASSIMP_LOG_INFO_F("AC3D file format version: ", msg);
ASSIMP_LOG_INFO("AC3D file format version: ", msg);
std::vector<Material> materials;
materials.reserve(5);

View File

@ -116,16 +116,16 @@ public:
Mask = 0xf,
};
inline const 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

@ -39,16 +39,10 @@ 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>
@ -211,7 +205,7 @@ void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::s
}
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
return (isalnum(pChar) || (pChar == '+') || (pChar == '/'));
return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/'));
}
void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector<uint8_t> &pOutputData) const {
@ -274,7 +268,8 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
mXmlParser = new XmlParser();
if (!mXmlParser->parse(file.get())) {
delete mXmlParser;
throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
mXmlParser = nullptr;
throw DeadlyImportError("Failed to create XML reader for file ", pFile, ".");
}
// Start reading, search for root tag <amf>
@ -307,14 +302,14 @@ void AMFImporter::ParseNode_Root() {
throw DeadlyImportError("Root node \"amf\" not found.");
}
XmlNode node = *root;
mUnit = ai_str_tolower(std::string(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);
}
}
@ -409,20 +404,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();
@ -458,7 +453,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);
@ -523,10 +518,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

@ -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

@ -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 {
@ -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.
@ -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-2021, 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

@ -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,11 +155,11 @@ 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();
if (node.empty()) {
@ -174,22 +171,20 @@ void AMFImporter::ParseNode_Texture(XmlNode &node) {
AMFTexture& als = *((AMFTexture*)ne);// alias for convenience
std::string enc64_data = node.value();
// Check for child nodes
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

@ -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;
}
@ -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;

View File

@ -614,7 +614,7 @@ void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
node->mNumChildren++;
// What we did is so great, it is at least worth a debug message
ASSIMP_LOG_VERBOSE_DEBUG("ASE: Generating separate target node (" + snode->mName + ")");
ASSIMP_LOG_VERBOSE_DEBUG("ASE: Generating separate target node (", snode->mName, ")");
}
}

View File

@ -498,6 +498,12 @@ void Parser::ParseLV1MaterialListBlock() {
ParseLV2MaterialBlock(sMat);
continue;
}
if( iDepth == 1 ){
// CRUDE HACK: support missing brace after "Ascii Scene Exporter v2.51"
LogWarning("Missing closing brace in material list");
--filePtr;
return;
}
}
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
}
@ -671,7 +677,7 @@ void Parser::ParseLV3MapBlock(Texture &map) {
if (!ParseString(temp, "*MAP_CLASS"))
SkipToNextToken();
if (temp != "Bitmap" && temp != "Normal Bump") {
ASSIMP_LOG_WARN_F("ASE: Skipping unknown map type: ", temp);
ASSIMP_LOG_WARN("ASE: Skipping unknown map type: ", temp);
parsePath = false;
}
continue;
@ -685,7 +691,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;
@ -1119,7 +1125,7 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode &mesh) {
"this is no spot light or target camera");
}
} else {
ASSIMP_LOG_ERROR("ASE: Unknown node transformation: " + temp);
ASSIMP_LOG_ERROR("ASE: Unknown node transformation: ", temp);
// mode = 0
}
continue;

View File

@ -95,8 +95,8 @@ struct Material : public D3DS::Material {
Material(Material &&other) AI_NO_EXCEPT
: D3DS::Material(std::move(other)),
avSubMaterials(std::move(other.avSubMaterials)),
pcInstance(std::move(other.pcInstance)),
bNeed(std::move(other.bNeed)) {
pcInstance(other.pcInstance),
bNeed(other.bNeed) {
other.pcInstance = nullptr;
}
@ -108,8 +108,8 @@ struct Material : public D3DS::Material {
//D3DS::Material::operator=(std::move(other));
avSubMaterials = std::move(other.avSubMaterials);
pcInstance = std::move(other.pcInstance);
bNeed = std::move(other.bNeed);
pcInstance = other.pcInstance;
bNeed = other.bNeed;
other.pcInstance = nullptr;

View File

@ -671,7 +671,7 @@ void AssbinImporter::ReadBinaryScene(IOStream *stream, aiScene *scene) {
void AssbinImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
IOStream *stream = pIOHandler->Open(pFile, "rb");
if (nullptr == stream) {
return;
throw DeadlyImportError("ASSBIN: Could not open ", pFile);
}
// signature

View File

@ -598,8 +598,11 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
if (!mesh->mTextureCoords[a])
break;
ioprintf(io, "\t\t<TextureCoords num=\"%u\" set=\"%u\" num_components=\"%u\"> \n", mesh->mNumVertices,
a, mesh->mNumUVComponents[a]);
ioprintf(io, "\t\t<TextureCoords num=\"%u\" set=\"%u\" name=\"%s\" num_components=\"%u\"> \n",
mesh->mNumVertices,
a,
mesh->mTextureCoordsNames[a].C_Str(),
mesh->mNumUVComponents[a]);
if (!shortened) {
if (mesh->mNumUVComponents[a] == 3) {

View File

@ -143,9 +143,9 @@ AI_WONT_RETURN void B3DImporter::Oops() {
}
// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void B3DImporter::Fail(string str) {
AI_WONT_RETURN void B3DImporter::Fail(const string &str) {
#ifdef DEBUG_B3D
ASSIMP_LOG_ERROR_F("Error in B3D file data: ", str);
ASSIMP_LOG_ERROR("Error in B3D file data: ", str);
#endif
throw DeadlyImportError("B3D Importer - error in B3D file data: ", str);
}
@ -233,7 +233,7 @@ string B3DImporter::ReadChunk() {
tag += char(ReadByte());
}
#ifdef DEBUG_B3D
ASSIMP_LOG_DEBUG_F("ReadChunk: ", tag);
ASSIMP_LOG_DEBUG("ReadChunk: ", tag);
#endif
unsigned sz = (unsigned)ReadInt();
_stack.push_back(_pos + sz);
@ -397,7 +397,7 @@ void B3DImporter::ReadTRIS(int v0) {
matid = 0;
} else if (matid < 0 || matid >= (int)_materials.size()) {
#ifdef DEBUG_B3D
ASSIMP_LOG_ERROR_F("material id=", matid);
ASSIMP_LOG_ERROR("material id=", matid);
#endif
Fail("Bad material id");
}
@ -417,7 +417,7 @@ void B3DImporter::ReadTRIS(int v0) {
int i2 = ReadInt() + v0;
if (i0 < 0 || i0 >= (int)_vertices.size() || i1 < 0 || i1 >= (int)_vertices.size() || i2 < 0 || i2 >= (int)_vertices.size()) {
#ifdef DEBUG_B3D
ASSIMP_LOG_ERROR_F("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2);
ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2);
#endif
Fail("Bad triangle index");
continue;

View File

@ -96,7 +96,7 @@ private:
};
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Fail(const std::string &str) AI_WONT_RETURN_SUFFIX;
void ReadTEXS();
void ReadBRUS();

View File

@ -359,7 +359,7 @@ void BVHLoader::ReadMotion(aiScene * /*pScene*/) {
std::string BVHLoader::GetNextToken() {
// skip any preceding whitespace
while (mReader != mBuffer.end()) {
if (!isspace(*mReader))
if (!isspace((unsigned char)*mReader))
break;
// count lines
@ -372,7 +372,7 @@ std::string BVHLoader::GetNextToken() {
// collect all chars till the next whitespace. BVH is easy in respect to that.
std::string token;
while (mReader != mBuffer.end()) {
if (isspace(*mReader))
if (isspace((unsigned char)*mReader))
break;
token.push_back(*mReader);

View File

@ -198,9 +198,9 @@ void DNAParser::Parse() {
s.size = offset;
}
ASSIMP_LOG_DEBUG_F("BlenderDNA: Got ", dna.structures.size(), " structures with totally ", fields, " fields");
ASSIMP_LOG_DEBUG("BlenderDNA: Got ", dna.structures.size(), " structures with totally ", fields, " fields");
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
#if ASSIMP_BUILD_BLENDER_DEBUG_DNA
dna.DumpToFile();
#endif
@ -208,7 +208,7 @@ void DNAParser::Parse() {
dna.RegisterConverters();
}
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
#if ASSIMP_BUILD_BLENDER_DEBUG_DNA
#include <fstream>
// ------------------------------------------------------------------------------------------------
@ -237,7 +237,7 @@ void DNA ::DumpToFile() {
ASSIMP_LOG_INFO("BlenderDNA: Dumped dna to dna.txt");
}
#endif
#endif // ASSIMP_BUILD_BLENDER_DEBUG_DNA
// ------------------------------------------------------------------------------------------------
/*static*/ void DNA ::ExtractArraySize(

View File

@ -59,6 +59,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ASSIMP_BUILD_BLENDER_DEBUG
#endif
// set this to non-zero to dump BlenderDNA stuff to dna.txt.
// you could set it on the assimp build command line too without touching it here.
// !!! please make sure this is set to 0 in the repo !!!
#ifndef ASSIMP_BUILD_BLENDER_DEBUG_DNA
#define ASSIMP_BUILD_BLENDER_DEBUG_DNA 0
#endif
// #define ASSIMP_BUILD_BLENDER_NO_STATS
namespace Assimp {
@ -495,7 +502,7 @@ public:
const Structure &structure,
const FileDatabase &db) const;
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
#if ASSIMP_BUILD_BLENDER_DEBUG_DNA
// --------------------------------------------------------
/** Dump the DNA to a text file. This is for debugging purposes.
* The output file is `dna.txt` in the current working folder*/

View File

@ -565,7 +565,7 @@ template <> bool Structure :: ResolvePointer<std::shared_ptr,ElemBase>(std::shar
// this might happen if DNA::RegisterConverters hasn't been called so far
// or if the target type is not contained in `our` DNA.
out.reset();
ASSIMP_LOG_WARN_F( "Failed to find a converter for the `",s.name,"` structure" );
ASSIMP_LOG_WARN( "Failed to find a converter for the `",s.name,"` structure" );
return false;
}

View File

@ -88,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",
@ -132,12 +132,6 @@ bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bo
return false;
}
// ------------------------------------------------------------------------------------------------
// List all extensions handled by this loader
void BlenderImporter::GetExtensionList(std::set<std::string> &app) {
app.insert("blend");
}
// ------------------------------------------------------------------------------------------------
// Loader registry entry
const aiImporterDesc *BlenderImporter::GetInfo() const {
@ -241,9 +235,9 @@ void BlenderImporter::InternReadFile(const std::string &pFile,
stream->Read(magic, 3, 1);
magic[3] = '\0';
LogInfo((format(), "Blender version is ", magic[0], ".", magic + 1,
LogInfo("Blender version is ", magic[0], ".", magic + 1,
" (64bit: ", file.i64bit ? "true" : "false",
", little endian: ", file.little ? "true" : "false", ")"));
", little endian: ", file.little ? "true" : "false", ")");
ParseBlendFile(file, stream);
@ -316,7 +310,7 @@ void BlenderImporter::ExtractScene(Scene &out, const FileDatabase &file) {
ss.Convert(out, file);
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
ASSIMP_LOG_INFO_F(
ASSIMP_LOG_INFO(
"(Stats) Fields read: ", file.stats().fields_read,
", pointers resolved: ", file.stats().pointers_resolved,
", cache hits: ", file.stats().cache_hits,
@ -426,9 +420,9 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M
--s;
}
curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower(s[1]);
curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower(s[2]);
curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower(s[3]);
curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower((unsigned char)s[1]);
curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower((unsigned char)s[2]);
curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower((unsigned char)s[3]);
curTex->achFormatHint[3] = '\0';
// tex->mHeight = 0;
@ -440,7 +434,7 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M
curTex->pcData = reinterpret_cast<aiTexel *>(ch);
LogInfo("Reading embedded texture, original file was " + std::string(img->name));
LogInfo("Reading embedded texture, original file was ", img->name);
} else {
name = aiString(img->name);
}
@ -522,7 +516,7 @@ void BlenderImporter::ResolveTexture(aiMaterial *out, const Material *mat, const
case Tex::Type_POINTDENSITY:
case Tex::Type_VOXELDATA:
LogWarn(std::string("Encountered a texture with an unsupported type: ") + dispnam);
LogWarn("Encountered a texture with an unsupported type: ", dispnam);
AddSentinelTexture(out, mat, tex, conv_data);
break;
@ -685,7 +679,7 @@ void BlenderImporter::BuildMaterials(ConversionData &conv_data) {
BuildDefaultMaterial(conv_data);
for (std::shared_ptr<Material> mat : conv_data.materials_raw) {
for (const std::shared_ptr<Material> &mat : conv_data.materials_raw) {
// reset per material global counters
for (size_t i = 0; i < sizeof(conv_data.next_texture) / sizeof(conv_data.next_texture[0]); ++i) {
@ -758,7 +752,7 @@ void BlenderImporter::CheckActualType(const ElemBase *dt, const char *check) {
// ------------------------------------------------------------------------------------------------
void BlenderImporter::NotSupportedObjectType(const Object *obj, const char *type) {
LogWarn((format(), "Object `", obj->id.name, "` - type is unsupported: `", type, "`, skipping"));
LogWarn("Object `", obj->id.name, "` - type is unsupported: `", type, "`, skipping");
}
// ------------------------------------------------------------------------------------------------

View File

@ -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

@ -90,7 +90,7 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_d
const Structure *s = conv_data.db.dna.Get(cur->dna_type);
if (!s) {
ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ", cur->dna_type);
ASSIMP_LOG_WARN("BlendModifier: could not resolve DNA name: ", cur->dna_type);
continue;
}
@ -132,7 +132,7 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_d
}
}
if (curgod) {
ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ", dat.name);
ASSIMP_LOG_WARN("Couldn't find a handler for modifier: ", dat.name);
}
}
@ -140,7 +140,7 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_d
// object, we still can't say whether our modifier implementations were
// able to fully do their job.
if (ful) {
ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ", cnt, " of ", ful, " modifiers on `", orig_object.id.name,
ASSIMP_LOG_DEBUG("BlendModifier: found handlers for ", cnt, " of ", ful, " modifiers on `", orig_object.id.name,
"`, check log messages above for errors");
}
}
@ -248,7 +248,7 @@ void BlenderModifier_Mirror ::DoIt(aiNode &out, ConversionData &conv_data, const
out.mMeshes = nind;
out.mNumMeshes *= 2;
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `",
ASSIMP_LOG_INFO("BlendModifier: Applied the `Mirror` modifier to `",
orig_object.id.name, "`");
}
@ -277,7 +277,7 @@ void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data,
break;
default:
ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ", mir.subdivType);
ASSIMP_LOG_WARN("BlendModifier: Unrecognized subdivision algorithm: ", mir.subdivType);
return;
};
@ -292,7 +292,7 @@ void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data,
subd->Subdivide(meshes, out.mNumMeshes, tempmeshes.get(), std::max(mir.renderLevels, mir.levels), true);
std::copy(tempmeshes.get(), tempmeshes.get() + out.mNumMeshes, meshes);
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
ASSIMP_LOG_INFO("BlendModifier: Applied the `Subdivision` modifier to `",
orig_object.id.name, "`");
}

View File

@ -86,7 +86,7 @@ public:
const Scene& /*in*/,
const Object& /*orig_object*/
) {
ASSIMP_LOG_INFO_F("This modifier is not supported, skipping: ",orig_modifier.dna_type );
ASSIMP_LOG_INFO("This modifier is not supported, skipping: ",orig_modifier.dna_type );
return;
}
};

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,
@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#include "C4DImporter.h"
#include <assimp/TinyFormatter.h>
#include <memory>
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
@ -65,7 +64,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "c4d_file.h"
#include "default_alien_overloads.h"
using namespace melange;
namespace {
aiString aiStringFrom(cineware::String const & cinestring) {
aiString result;
cinestring.GetCString(result.data, MAXLEN-1);
result.length = static_cast<ai_uint32>(cinestring.GetLength());
return result;
}
}
using namespace Assimp;
using namespace cineware;
// overload this function and fill in your own unique data
void GetWriterInfo(int &id, String &appname) {
@ -73,9 +84,6 @@ void GetWriterInfo(int &id, String &appname) {
appname = "Open Asset Import Library";
}
using namespace Assimp;
using namespace Assimp::Formatter;
namespace Assimp {
template<> const char* LogFunctions<C4DImporter>::Prefix() {
static auto prefix = "C4D: ";
@ -97,17 +105,6 @@ static const aiImporterDesc desc = {
};
// ------------------------------------------------------------------------------------------------
C4DImporter::C4DImporter()
: BaseImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
C4DImporter::~C4DImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
const std::string& extension = GetExtension(pFile);
@ -125,11 +122,6 @@ const aiImporterDesc* C4DImporter::GetInfo () const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
void C4DImporter::SetupProperties(const Importer* /*pImp*/) {
// nothing to be done for the moment
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
@ -199,8 +191,8 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// ------------------------------------------------------------------------------------------------
bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) {
// based on Melange sample code (C4DImportExport.cpp)
bool C4DImporter::ReadShader(aiMaterial* out, BaseShader* shader) {
// based on Cineware sample code (C4DImportExport.cpp)
while(shader) {
if(shader->GetType() == Xlayer) {
BaseContainer* container = shader->GetDataInstance();
@ -242,13 +234,11 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) {
lsl = lsl->GetNext();
}
} else if ( shader->GetType() == Xbitmap ) {
aiString path;
shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1);
path.length = ::strlen(path.data);
auto const path = aiStringFrom(shader->GetFileName().GetString());
out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
return true;
} else {
LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType())));
LogWarn("ignoring shader type: ", GetObjectTypeName(shader->GetType()));
}
shader = shader->GetNext();
}
@ -257,18 +247,15 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) {
}
// ------------------------------------------------------------------------------------------------
void C4DImporter::ReadMaterials(melange::BaseMaterial* mat) {
// based on Melange sample code
void C4DImporter::ReadMaterials(BaseMaterial* mat) {
// based on Cineware sample code
while (mat) {
const String& name = mat->GetName();
if (mat->GetType() == Mmaterial) {
aiMaterial* out = new aiMaterial();
material_mapping[mat] = static_cast<unsigned int>(materials.size());
materials.push_back(out);
aiString ai_name;
name.GetCString(ai_name.data, MAXLEN-1);
ai_name.length = ::strlen(ai_name.data);
auto const ai_name = aiStringFrom(mat->GetName());
out->AddProperty(&ai_name, AI_MATKEY_NAME);
Material& m = dynamic_cast<Material&>(*mat);
@ -294,7 +281,7 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat) {
ReadShader(out, shader);
}
} else {
LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType())));
LogWarn("ignoring plugin material: ", GetObjectTypeName(mat->GetType()));
}
mat = mat->GetNext();
}
@ -305,19 +292,15 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
ai_assert(parent != nullptr );
std::vector<aiNode*> nodes;
// based on Melange sample code
// based on Cineware sample code
while (object) {
const String& name = object->GetName();
const LONG type = object->GetType();
const Matrix& ml = object->GetMl();
aiString string;
name.GetCString(string.data, MAXLEN-1);
string.length = ::strlen(string.data);
aiNode* const nd = new aiNode();
nd->mParent = parent;
nd->mName = string;
nd->mName = aiStringFrom(object->GetName());
nd->mTransformation.a1 = ml.v1.x;
nd->mTransformation.b1 = ml.v1.y;
@ -352,7 +335,7 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
meshes.push_back(mesh);
}
} else {
LogWarn("ignoring object: " + std::string(GetObjectTypeName(type)));
LogWarn("ignoring object: ", GetObjectTypeName(type));
}
RecurseHierarchy(object->GetDown(), nd);
@ -370,7 +353,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
ai_assert(object != nullptr);
ai_assert( object->GetType() == Opolygon );
// based on Melange sample code
// based on Cineware sample code
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
ai_assert(polyObject != nullptr);
@ -618,4 +601,3 @@ unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) {
}
#endif // ASSIMP_BUILD_NO_C4D_IMPORTER

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,
@ -56,8 +56,8 @@ struct aiMaterial;
struct aiImporterDesc;
namespace melange {
class BaseObject; // c4d_file.h
namespace cineware {
class BaseObject;
class PolygonObject;
class BaseMaterial;
class BaseShader;
@ -71,43 +71,34 @@ namespace Assimp {
}
// -------------------------------------------------------------------------------------------
/** Importer class to load Cinema4D files using the Melange library to be obtained from
* www.plugincafe.com
/** Importer class to load Cinema4D files using the Cineware library to be obtained from
* https://developers.maxon.net
*
* Note that Melange is not free software. */
* Note that Cineware is not free software. */
// -------------------------------------------------------------------------------------------
class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> {
public:
C4DImporter();
~C4DImporter();
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool CanRead( const std::string& pFile, IOSystem*, bool checkSig) const override;
protected:
// --------------------
const aiImporterDesc* GetInfo () const;
const aiImporterDesc* GetInfo () const override;
// --------------------
void SetupProperties(const Importer* pImp);
// --------------------
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
void InternReadFile( const std::string& pFile, aiScene*, IOSystem* ) override;
private:
void ReadMaterials(melange::BaseMaterial* mat);
void RecurseHierarchy(melange::BaseObject* object, aiNode* parent);
aiMesh* ReadMesh(melange::BaseObject* object);
unsigned int ResolveMaterial(melange::PolygonObject* obj);
void ReadMaterials(cineware::BaseMaterial* mat);
void RecurseHierarchy(cineware::BaseObject* object, aiNode* parent);
aiMesh* ReadMesh(cineware::BaseObject* object);
unsigned int ResolveMaterial(cineware::PolygonObject* obj);
bool ReadShader(aiMaterial* out, melange::BaseShader* shader);
bool ReadShader(aiMaterial* out, cineware::BaseShader* shader);
std::vector<aiMesh*> meshes;
std::vector<aiMaterial*> materials;
typedef std::map<melange::BaseMaterial*, unsigned int> MaterialMap;
typedef std::map<cineware::BaseMaterial*, unsigned int> MaterialMap;
MaterialMap material_mapping;
}; // !class C4DImporter

View File

@ -137,7 +137,13 @@ void COBImporter::SetupProperties(const Importer * /*pImp*/) {
// Imports the given file into the given scene structure.
void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
COB::Scene scene;
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE(pIOHandler->Open(pFile, "rb")));
auto file = pIOHandler->Open(pFile, "rb");
if (!file) {
ThrowException("Could not open " + pFile);
}
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE(file));
// check header
char head[32];
@ -146,7 +152,7 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
ThrowException("Could not found magic id: `Caligari`");
}
ASSIMP_LOG_INFO_F("File format tag: ", std::string(head + 9, 6));
ASSIMP_LOG_INFO("File format tag: ", std::string(head + 9, 6));
if (head[16] != 'L') {
ThrowException("File is big-endian, which is not supported");
}
@ -224,7 +230,7 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
// ------------------------------------------------------------------------------------------------
void ConvertTexture(std::shared_ptr<Texture> tex, aiMaterial *out, aiTextureType type) {
void ConvertTexture(const std::shared_ptr<Texture> &tex, aiMaterial *out, aiTextureType type) {
const aiString path(tex->path);
out->AddProperty(&path, AI_MATKEY_TEXTURE(type, 0));
out->AddProperty(&tex->transform, 1, AI_MATKEY_UVTRANSFORM(type, 0));
@ -295,8 +301,7 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi
}
std::unique_ptr<const Material> defmat;
if (!min) {
ASSIMP_LOG_VERBOSE_DEBUG(format() << "Could not resolve material index "
<< reflist.first << " - creating default material for this slot");
ASSIMP_LOG_VERBOSE_DEBUG("Could not resolve material index ", reflist.first, " - creating default material for this slot");
defmat.reset(min = new Material());
}
@ -521,7 +526,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk
++splitter;
if (!splitter.match_start("mat# ")) {
ASSIMP_LOG_WARN_F("Expected `mat#` line in `Mat1` chunk ", nfo.id);
ASSIMP_LOG_WARN("Expected `mat#` line in `Mat1` chunk ", nfo.id);
return;
}
@ -533,7 +538,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk
++splitter;
if (!splitter.match_start("shader: ")) {
ASSIMP_LOG_WARN_F("Expected `mat#` line in `Mat1` chunk ", nfo.id);
ASSIMP_LOG_WARN("Expected `mat#` line in `Mat1` chunk ", nfo.id);
return;
}
std::string shader = std::string(splitter[1]);
@ -544,12 +549,12 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk
} else if (shader == "phong") {
mat.shader = Material::PHONG;
} else if (shader != "flat") {
ASSIMP_LOG_WARN_F("Unknown value for `shader` in `Mat1` chunk ", nfo.id);
ASSIMP_LOG_WARN("Unknown value for `shader` in `Mat1` chunk ", nfo.id);
}
++splitter;
if (!splitter.match_start("rgb ")) {
ASSIMP_LOG_WARN_F("Expected `rgb` line in `Mat1` chunk ", nfo.id);
ASSIMP_LOG_WARN("Expected `rgb` line in `Mat1` chunk ", nfo.id);
}
const char *rgb = splitter[1];
@ -557,7 +562,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk
++splitter;
if (!splitter.match_start("alpha ")) {
ASSIMP_LOG_WARN_F("Expected `alpha` line in `Mat1` chunk ", nfo.id);
ASSIMP_LOG_WARN("Expected `alpha` line in `Mat1` chunk ", nfo.id);
}
const char *tokens[10];
@ -577,7 +582,7 @@ void COBImporter::ReadUnit_Ascii(Scene &out, LineSplitter &splitter, const Chunk
}
++splitter;
if (!splitter.match_start("Units ")) {
ASSIMP_LOG_WARN_F("Expected `Units` line in `Unit` chunk ", nfo.id);
ASSIMP_LOG_WARN("Expected `Units` line in `Unit` chunk ", nfo.id);
return;
}
@ -588,12 +593,12 @@ void COBImporter::ReadUnit_Ascii(Scene &out, LineSplitter &splitter, const Chunk
const unsigned int t = strtoul10(splitter[1]);
nd->unit_scale = t >= sizeof(units) / sizeof(units[0]) ? (
ASSIMP_LOG_WARN_F(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) :
ASSIMP_LOG_WARN(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) :
units[t];
return;
}
}
ASSIMP_LOG_WARN_F("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
}
// ------------------------------------------------------------------------------------------------
@ -622,13 +627,13 @@ void COBImporter::ReadLght_Ascii(Scene &out, LineSplitter &splitter, const Chunk
} else if (splitter.match_start("Spot ")) {
msh.ltype = Light::SPOT;
} else {
ASSIMP_LOG_WARN_F("Unknown kind of light source in `Lght` chunk ", nfo.id, " : ", *splitter);
ASSIMP_LOG_WARN("Unknown kind of light source in `Lght` chunk ", nfo.id, " : ", *splitter);
msh.ltype = Light::SPOT;
}
++splitter;
if (!splitter.match_start("color ")) {
ASSIMP_LOG_WARN_F("Expected `color` line in `Lght` chunk ", nfo.id);
ASSIMP_LOG_WARN("Expected `color` line in `Lght` chunk ", nfo.id);
}
const char *rgb = splitter[1];
@ -636,14 +641,14 @@ void COBImporter::ReadLght_Ascii(Scene &out, LineSplitter &splitter, const Chunk
SkipSpaces(&rgb);
if (strncmp(rgb, "cone angle", 10) != 0) {
ASSIMP_LOG_WARN_F("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id);
ASSIMP_LOG_WARN("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id);
}
SkipSpaces(rgb + 10, &rgb);
msh.angle = fast_atof(&rgb);
SkipSpaces(&rgb);
if (strncmp(rgb, "inner angle", 11) != 0) {
ASSIMP_LOG_WARN_F("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
ASSIMP_LOG_WARN("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
}
SkipSpaces(rgb + 11, &rgb);
msh.inner_angle = fast_atof(&rgb);
@ -1027,7 +1032,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const
mat.type = Material::METAL;
break;
default:
ASSIMP_LOG_ERROR_F("Unrecognized shader type in `Mat1` chunk with id ", nfo.id);
ASSIMP_LOG_ERROR("Unrecognized shader type in `Mat1` chunk with id ", nfo.id);
mat.type = Material::FLAT;
}
@ -1042,7 +1047,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const
mat.autofacet = Material::SMOOTH;
break;
default:
ASSIMP_LOG_ERROR_F("Unrecognized faceting mode in `Mat1` chunk with id ", nfo.id);
ASSIMP_LOG_ERROR("Unrecognized faceting mode in `Mat1` chunk with id ", nfo.id);
mat.autofacet = Material::FACETED;
}
mat.autofacet_angle = static_cast<float>(reader.GetI1());
@ -1170,13 +1175,13 @@ void COBImporter::ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const
if (nd->id == nfo.parent_id) {
const unsigned int t = reader.GetI2();
nd->unit_scale = t >= sizeof(units) / sizeof(units[0]) ? (
ASSIMP_LOG_WARN_F(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) :
ASSIMP_LOG_WARN(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id), 1.f) :
units[t];
return;
}
}
ASSIMP_LOG_WARN_F("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
}
#endif // ASSIMP_BUILD_NO_COB_IMPORTER

View File

@ -75,7 +75,7 @@ static const aiImporterDesc desc = {
3,
1,
5,
"dae zae"
"dae xml zae"
};
static const float kMillisecondsFromSeconds = 1000.f;
@ -317,7 +317,7 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Nod
nd = FindNode(pParser.mRootNode, nodeInst.mNode);
}
if (nullptr == nd) {
ASSIMP_LOG_ERROR_F("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode);
ASSIMP_LOG_ERROR("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode);
} else {
// attach this node to the list of children
resolved.push_back(nd);
@ -347,7 +347,7 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node
// find the referred light
ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find(lid.mLight);
if (srcLightIt == pParser.mLightLibrary.end()) {
ASSIMP_LOG_WARN_F("Collada: Unable to find light for ID \"", lid.mLight, "\". Skipping.");
ASSIMP_LOG_WARN("Collada: Unable to find light for ID \"", lid.mLight, "\". Skipping.");
continue;
}
const Collada::Light *srcLight = &srcLightIt->second;
@ -412,7 +412,7 @@ void ColladaLoader::BuildCamerasForNode(const ColladaParser &pParser, const Node
// find the referred light
ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find(cid.mCamera);
if (srcCameraIt == pParser.mCameraLibrary.end()) {
ASSIMP_LOG_WARN_F("Collada: Unable to find camera for ID \"", cid.mCamera, "\". Skipping.");
ASSIMP_LOG_WARN("Collada: Unable to find camera for ID \"", cid.mCamera, "\". Skipping.");
continue;
}
const Collada::Camera *srcCamera = &srcCameraIt->second;
@ -486,7 +486,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
}
if (nullptr == srcMesh) {
ASSIMP_LOG_WARN_F("Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping.");
ASSIMP_LOG_WARN("Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping.");
continue;
}
} else {
@ -511,7 +511,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
table = &meshMatIt->second;
meshMaterial = table->mMatName;
} else {
ASSIMP_LOG_WARN_F("Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <",
ASSIMP_LOG_WARN("Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <",
mid.mMeshOrController, ">.");
if (!mid.mMaterials.empty()) {
meshMaterial = mid.mMaterials.begin()->second.mMatName;
@ -619,6 +619,10 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
dstMesh->mName = pSrcMesh->mId;
}
if (pSrcMesh->mPositions.empty()) {
return dstMesh.release();
}
// count the vertices addressed by its faces
const size_t numVertices = std::accumulate(pSrcMesh->mFaceSize.begin() + pStartFace,
pSrcMesh->mFaceSize.begin() + pStartFace + pSubMesh.mNumFaces, size_t(0));
@ -883,7 +887,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
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, "\".");
ASSIMP_LOG_WARN("ColladaLoader::CreateMesh(): could not find corresponding node for joint \"", bone->mName.data, "\".");
}
// and insert bone
@ -1184,7 +1188,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
else if (subElement == "Z")
entry.mSubElement = 2;
else
ASSIMP_LOG_WARN_F("Unknown anim subelement <", subElement, ">. Ignoring");
ASSIMP_LOG_WARN("Unknown anim subelement <", subElement, ">. Ignoring");
} else {
// no sub-element following, transformId is remaining string
entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1);
@ -1241,7 +1245,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
continue;
}
entry.mTargetId = entry.mTransformId;
entry.mTransformId = "";
entry.mTransformId = std::string();
}
entry.mChannel = &(*cit);
@ -1711,7 +1715,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
// find the image referred by this name in the image library of the scene
ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find(name);
if (imIt == pParser.mImageLibrary.end()) {
ASSIMP_LOG_WARN_F("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\".");
ASSIMP_LOG_WARN("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\".");
//set default texture file name
result.Set(name + ".jpg");

View File

@ -71,7 +71,7 @@ static void ReportWarning(const char *msg, ...) {
ai_assert(iLen > 0);
va_end(args);
ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer, iLen));
ASSIMP_LOG_WARN("Validation warning: ", std::string(szBuffer, iLen));
}
static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) {
@ -170,10 +170,10 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
ColladaParser::~ColladaParser() {
for (auto & it : mNodeLibrary) {
for (auto &it : mNodeLibrary) {
delete it.second;
}
for (auto & it : mMeshLibrary) {
for (auto &it : mMeshLibrary) {
delete it.second;
}
}
@ -234,7 +234,7 @@ void ColladaParser::UriDecodePath(aiString &ss) {
#if defined(_MSC_VER)
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
#else
if (ss.data[0] == '/' && isalpha(ss.data[1]) && ss.data[2] == ':') {
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
#endif
--ss.length;
::memmove(ss.data, ss.data + 1, ss.length);
@ -396,7 +396,7 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
std::string animName;
if (!XmlParser::getStdStrAttribute(node, "name", animName)) {
if (!XmlParser::getStdStrAttribute( node, "id", animName )) {
if (!XmlParser::getStdStrAttribute(node, "id", animName)) {
animName = std::string("animation_") + ai_to_string(mAnimationClipLibrary.size());
}
}
@ -420,7 +420,7 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
void ColladaParser::PostProcessControllers() {
std::string meshId;
for (auto & it : mControllerLibrary) {
for (auto &it : mControllerLibrary) {
meshId = it.second.mMeshId;
if (meshId.empty()) {
continue;
@ -445,7 +445,7 @@ void ColladaParser::PostProcessRootAnimations() {
}
Animation temp;
for (auto & it : mAnimationClipLibrary) {
for (auto &it : mAnimationClipLibrary) {
std::string clipName = it.first;
Animation *clip = new Animation();
@ -453,7 +453,7 @@ void ColladaParser::PostProcessRootAnimations() {
temp.mSubAnims.push_back(clip);
for (std::string animationID : it.second) {
for (const std::string &animationID : it.second) {
AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
if (animation != mAnimationLibrary.end()) {
@ -529,7 +529,7 @@ 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);
@ -552,7 +552,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
pParent->mSubAnims.push_back(anim);
}
for (const auto & channel : channels) {
for (const auto &channel : channels) {
anim->mChannels.push_back(channel.second);
}
@ -623,12 +623,9 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
controller.mType = Skin;
controller.mMethod = Normalized;
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
//for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "morph") {
controller.mType = Morph;
@ -645,7 +642,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
} else if (currentName == "skin") {
std::string id;
if (XmlParser::getStdStrAttribute(currentNode, "source", id)) {
controller.mMeshId = id.substr(1, id.size()-1);
controller.mMeshId = id.substr(1, id.size() - 1);
}
} else if (currentName == "bind_shape_matrix") {
std::string v;
@ -699,7 +696,7 @@ void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pCo
} else if (strcmp(attrSemantic, "INV_BIND_MATRIX") == 0) {
pController.mJointOffsetMatrixSource = attrSource;
} else {
throw DeadlyImportError("Unknown semantic \"" , attrSemantic , "\" in <joints> data <input> element");
throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <joints> data <input> element");
}
}
}
@ -709,7 +706,7 @@ void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pCo
// Reads the joint weights for the given controller
void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) {
// Read vertex count from attributes and resize the array accordingly
int vertexCount=0;
int vertexCount = 0;
XmlParser::getIntAttribute(node, "count", vertexCount);
pController.mWeightCounts.resize(vertexCount);
@ -724,7 +721,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
// local URLS always start with a '#'. We don't support global URLs
if (attrSource[0] != '#') {
throw DeadlyImportError( "Unsupported URL format in \"", attrSource, "\" in source attribute of <vertex_weights> data <input> element");
throw DeadlyImportError("Unsupported URL format in \"", attrSource, "\" in source attribute of <vertex_weights> data <input> element");
}
channel.mAccessor = attrSource + 1;
@ -778,7 +775,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) {
const std::string &currentName = currentNode.name();
if (currentName == "image") {
std::string id;
if (XmlParser::getStdStrAttribute( currentNode, "id", id )) {
if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
mImageLibrary[id] = Image();
// read on from there
ReadImage(currentNode, mImageLibrary[id]);
@ -908,7 +905,7 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) {
if (!name.empty()) {
cam.mName = name;
}
ReadCamera(currentNode, cam);
ReadCamera(currentNode, cam);
}
}
}
@ -929,8 +926,7 @@ void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
// ------------------------------------------------------------------------------------------------
// Reads a light entry into the given light
void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
@ -991,10 +987,8 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
// ------------------------------------------------------------------------------------------------
// Reads a camera entry into the given light
void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) {
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
if (currentName == "orthographic") {
@ -1050,11 +1044,10 @@ void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) {
// ------------------------------------------------------------------------------------------------
// Reads an COMMON effect profile
void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect) {
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
const std::string currentName = currentNode.name();
if (currentName == "newparam") {
// save ID
std::string sid = currentNode.attribute("sid").as_string();
@ -1145,10 +1138,9 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
if (node.empty()) {
return;
}
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
// MAYA extensions
@ -1208,10 +1200,9 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
if (node.empty()) {
return;
}
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNode currentNode;
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
if (currentName == "color") {
@ -1273,8 +1264,7 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
return;
}
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
@ -1360,8 +1350,7 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
return;
}
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
@ -1370,8 +1359,8 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
} else if (currentName == "vertices") {
ReadVertexData(currentNode, pMesh);
} else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" ||
currentName == "polygons" || currentName == "polylist" || currentName == "trifans" ||
currentName == "tristrips") {
currentName == "polygons" || currentName == "polylist" || currentName == "trifans" ||
currentName == "tristrips") {
ReadIndexData(currentNode, pMesh);
}
}
@ -1386,8 +1375,7 @@ void ColladaParser::ReadSource(XmlNode &node) {
std::string sourceID;
XmlParser::getStdStrAttribute(node, "id", sourceID);
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
@ -1449,9 +1437,8 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
throw DeadlyImportError("Expected more values while reading float_array contents.");
}
ai_real value;
// read a number
//SkipSpacesAndLineEnd(&content);
ai_real value;
content = fast_atoreal_move<ai_real>(content, value);
data.mValues.push_back(value);
// skip whitespace after it
@ -1490,8 +1477,7 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
acc.mSource = source.c_str() + 1; // ignore the leading '#'
acc.mSize = 0; // gets incremented with every param
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
@ -1500,11 +1486,10 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
std::string name;
if (XmlParser::hasAttribute(currentNode, "name")) {
XmlParser::getStdStrAttribute(currentNode, "name", name);
//name = mReader->getAttributeValue(attrName);
// analyse for common type components and store it's sub-offset in the corresponding field
/* Cartesian coordinates */
// Cartesian coordinates
if (name == "X")
acc.mSubOffset[0] = acc.mParams.size();
else if (name == "Y")
@ -1608,8 +1593,7 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
ai_assert(primType != Prim_Invalid);
// also a number of <input> elements, but in addition a <p> primitive collection and probably index counts for all primitives
XmlNodeIterator xmlIt(node);
xmlIt.collectChildrenPreOrder(node);
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name();
@ -1686,12 +1670,9 @@ void ColladaParser::ReadInputChannel(XmlNode &node, std::vector<InputChannel> &p
// read set if texture coordinates
if (channel.mType == IT_Texcoord || channel.mType == IT_Color) {
int attrSet = -1;
if (XmlParser::hasAttribute(node, "set")) {
XmlParser::getIntAttribute(node, "set", attrSet);
}
channel.mIndex = attrSet;
unsigned int attrSet = 0;
if (XmlParser::getUIntAttribute(node, "set", attrSet))
channel.mIndex = attrSet;
}
// store, if valid type
@ -1716,20 +1697,20 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
// determine the expected number of indices
size_t expectedPointCount = 0;
switch (pPrimType) {
case Prim_Polylist: {
for (size_t i : pVCount)
expectedPointCount += i;
break;
}
case Prim_Lines:
expectedPointCount = 2 * pNumPrimitives;
break;
case Prim_Triangles:
expectedPointCount = 3 * pNumPrimitives;
break;
default:
// other primitive types don't state the index count upfront... we need to guess
break;
case Prim_Polylist: {
for (size_t i : pVCount)
expectedPointCount += i;
break;
}
case Prim_Lines:
expectedPointCount = 2 * pNumPrimitives;
break;
case Prim_Triangles:
expectedPointCount = 3 * pNumPrimitives;
break;
default:
// other primitive types don't state the index count upfront... we need to guess
break;
}
// and read all indices into a temporary array
@ -1739,7 +1720,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
}
// It is possible to not contain any indices
if (pNumPrimitives > 0) {
if (pNumPrimitives > 0) {
std::string v;
XmlParser::getValueAsString(node, v);
const char *content = v.c_str();
@ -1937,87 +1918,87 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
// 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:
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.mNormals.size() < pMesh.mPositions.size() - 1)
pMesh.mNormals.insert(pMesh.mNormals.end(), pMesh.mPositions.size() - pMesh.mNormals.size() - 1, aiVector3D(0, 1, 0));
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));
// 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");
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;
}
break;
case IT_Tangent:
} 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.mTangents.size() < pMesh.mPositions.size() - 1)
pMesh.mTangents.insert(pMesh.mTangents.end(), pMesh.mPositions.size() - pMesh.mTangents.size() - 1, aiVector3D(1, 0, 0));
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));
// 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));
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.");
}
// 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");
break;
default:
// IT_Invalid and IT_Vertex
ai_assert(false && "shouldn't ever get here");
}
}
@ -2182,10 +2163,10 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
// read as many parameters and store in the transformation
for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
// skip whitespace before the number
SkipSpacesAndLineEnd(&content);
// read a number
content = fast_atoreal_move<ai_real>(content, tf.f[a]);
// skip whitespace after it
SkipSpacesAndLineEnd(&content);
}
// place the transformation at the queue of the node
@ -2400,7 +2381,7 @@ Collada::InputType ColladaParser::GetTypeForSemantic(const std::string &semantic
else if (semantic == "TANGENT" || semantic == "TEXTANGENT")
return IT_Tangent;
ASSIMP_LOG_WARN_F("Unknown vertex input type \"", semantic, "\". Ignoring.");
ASSIMP_LOG_WARN("Unknown vertex input type \"", semantic, "\". Ignoring.");
return IT_Invalid;
}

View File

@ -135,7 +135,7 @@ public:
for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++);
splitter++;
ASSIMP_LOG_VERBOSE_DEBUG((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
ASSIMP_LOG_VERBOSE_DEBUG("DXF: skipped over control group (",cnt," lines)");
}
} catch(std::logic_error&) {
ai_assert(!splitter);

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -63,11 +61,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
// AutoCAD Binary DXF<CR><LF><SUB><NULL>
const std::string AI_DXF_BINARY_IDENT = std::string("AutoCAD Binary DXF\r\n\x1a\0");
const size_t AI_DXF_BINARY_IDENT_LEN = 24u;
static constexpr char AI_DXF_BINARY_IDENT[] = "AutoCAD Binary DXF\r\n\x1a";
static constexpr size_t AI_DXF_BINARY_IDENT_LEN = sizeof AI_DXF_BINARY_IDENT;
// default vertex color that all uncolored vertices will receive
const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
// color indices for DXF - 16 are supported, the table is
// taken directly from the DXF spec.
@ -156,10 +154,10 @@ void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene,
}
// Check whether this is a binary DXF file - we can't read binary DXF files :-(
char buff[AI_DXF_BINARY_IDENT_LEN+1] = {0};
char buff[AI_DXF_BINARY_IDENT_LEN] = {0};
file->Read(buff,AI_DXF_BINARY_IDENT_LEN,1);
if (0 == strncmp(AI_DXF_BINARY_IDENT.c_str(),buff,AI_DXF_BINARY_IDENT_LEN)) {
if (0 == memcmp(AI_DXF_BINARY_IDENT,buff,AI_DXF_BINARY_IDENT_LEN)) {
throw DeadlyImportError("DXF: Binary files are not supported at the moment");
}
@ -202,7 +200,7 @@ void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene,
// comments
else if (reader.Is(999)) {
ASSIMP_LOG_INFO_F("DXF Comment: ", reader.Value());
ASSIMP_LOG_INFO("DXF Comment: ", reader.Value());
}
// don't read past the official EOF sign
@ -241,7 +239,7 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) {
}
}
ASSIMP_LOG_VERBOSE_DEBUG_F("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount);
ASSIMP_LOG_VERBOSE_DEBUG("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount);
}
if (! output.blocks.size() ) {
@ -372,7 +370,7 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
// first check if the referenced blocks exists ...
const DXF::BlockMap::const_iterator it = blocks_by_name.find(insert.name);
if (it == blocks_by_name.end()) {
ASSIMP_LOG_ERROR_F("DXF: Failed to resolve block reference: ", insert.name,"; skipping" );
ASSIMP_LOG_ERROR("DXF: Failed to resolve block reference: ", insert.name,"; skipping" );
continue;
}
@ -473,7 +471,7 @@ void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) {
++reader;
}
ASSIMP_LOG_VERBOSE_DEBUG_F("DXF: got ", output.blocks.size()," entries in BLOCKS" );
ASSIMP_LOG_VERBOSE_DEBUG("DXF: got ", output.blocks.size()," entries in BLOCKS" );
}
// ------------------------------------------------------------------------------------------------
@ -549,7 +547,7 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
++reader;
}
ASSIMP_LOG_VERBOSE_DEBUG_F( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(),
ASSIMP_LOG_VERBOSE_DEBUG( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(),
" inserted blocks in ENTITIES" );
}
@ -654,7 +652,7 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
//}
if (vguess && line.positions.size() != vguess) {
ASSIMP_LOG_WARN_F("DXF: unexpected vertex count in polymesh: ",
ASSIMP_LOG_WARN("DXF: unexpected vertex count in polymesh: ",
line.positions.size(),", expected ", vguess );
}
@ -670,7 +668,7 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
// to set the 71 and 72 fields, respectively, to valid values.
// So just fire a warning.
if (iguess && line.counts.size() != iguess) {
ASSIMP_LOG_WARN_F( "DXF: unexpected face count in polymesh: ", line.counts.size(),", expected ", iguess );
ASSIMP_LOG_WARN( "DXF: unexpected face count in polymesh: ", line.counts.size(),", expected ", iguess );
}
}
else if (!line.indices.size() && !line.counts.size()) {

View File

@ -459,7 +459,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
/*Result ignored*/ ReadByte(input, cursor, input + length);
/*Result ignored*/ ReadByte(input, cursor, input + length);
const uint32_t version = ReadWord(input, cursor, input + length);
ASSIMP_LOG_DEBUG_F("FBX version: ", version);
ASSIMP_LOG_DEBUG("FBX version: ", version);
const bool is64bits = version >= 7500;
const char *end = input + length;
try

View File

@ -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

@ -811,7 +811,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
// we need to generate a full node chain to accommodate for assimp's
// lack to express pivots and offsets.
if ((chainBits & chainMaskComplex) && doc.Settings().preservePivots) {
FBXImporter::LogInfo("generating full transformation chain for node: " + name);
FBXImporter::LogInfo("generating full transformation chain for node: ", name);
// query the anim_chain_bits dictionary to find out which chain elements
// have associated node animation channels. These can not be dropped
@ -918,7 +918,7 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root
const std::vector<unsigned int> &indices = ConvertLine(*line, root_node);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
} else {
FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name());
FBXImporter::LogWarn("ignoring unrecognized geometry: ", geo->Name());
}
}
@ -944,7 +944,7 @@ FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *
const std::vector<aiVector3D> &vertices = mesh.GetVertices();
const std::vector<unsigned int> &faces = mesh.GetFaceIndexCounts();
if (vertices.empty() || faces.empty()) {
FBXImporter::LogWarn("ignoring empty geometry: " + mesh.Name());
FBXImporter::LogWarn("ignoring empty geometry: ", mesh.Name());
return temp;
}
@ -971,7 +971,7 @@ std::vector<unsigned int> FBXConverter::ConvertLine(const LineGeometry &line, ai
const std::vector<aiVector3D> &vertices = line.GetVertices();
const std::vector<int> &indices = line.GetIndices();
if (vertices.empty() || indices.empty()) {
FBXImporter::LogWarn("ignoring empty line: " + line.Name());
FBXImporter::LogWarn("ignoring empty line: ", line.Name());
return temp;
}
@ -1126,6 +1126,8 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
*out_uv++ = aiVector3D(v.x, v.y, 0.0f);
}
out_mesh->mTextureCoordsNames[i] = mesh.GetTextureCoordChannelName(i);
out_mesh->mNumUVComponents[i] = 2;
}
@ -1542,10 +1544,10 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
aiBone *bone = nullptr;
if (bone_map.count(deformer_name)) {
ASSIMP_LOG_VERBOSE_DEBUG_F("retrieved bone from lookup ", bone_name.C_Str(), ". Deformer:", deformer_name);
ASSIMP_LOG_VERBOSE_DEBUG("retrieved bone from lookup ", bone_name.C_Str(), ". Deformer:", deformer_name);
bone = bone_map[deformer_name];
} else {
ASSIMP_LOG_VERBOSE_DEBUG_F("created new bone ", bone_name.C_Str(), ". Deformer: ", deformer_name);
ASSIMP_LOG_VERBOSE_DEBUG("created new bone ", bone_name.C_Str(), ". Deformer: ", deformer_name);
bone = new aiBone();
bone->mName = bone_name;
@ -1591,7 +1593,7 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
bone_map.insert(std::pair<const std::string, aiBone *>(deformer_name, bone));
}
ASSIMP_LOG_DEBUG_F("bone research: Indicies size: ", out_indices.size());
ASSIMP_LOG_DEBUG("bone research: Indicies size: ", out_indices.size());
// lookup must be populated in case something goes wrong
// this also allocates bones to mesh instance outside
@ -1764,6 +1766,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap
// XXX handle all kinds of UV transformations
uvTrafo.mScaling = tex->UVScaling();
uvTrafo.mTranslation = tex->UVTranslation();
uvTrafo.mRotation = tex->UVRotation();
out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, 0);
const PropertyTable &props = tex->Props();
@ -1815,14 +1818,14 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap
}
}
if (index == -1) {
FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material");
continue;
}
if (uvIndex == -1) {
uvIndex = index;
} else {
FBXImporter::LogWarn("the UV channel named " + uvSet +
FBXImporter::LogWarn("the UV channel named ", uvSet,
" appears at different positions in meshes, results will be wrong");
}
}
@ -1839,7 +1842,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap
}
}
if (index == -1) {
FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material");
}
if (uvIndex == -1) {
@ -1848,7 +1851,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap
}
if (uvIndex == -1) {
FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel");
FBXImporter::LogWarn("failed to resolve UV channel ", uvSet, ", using first UV channel");
uvIndex = 0;
}
}
@ -1883,6 +1886,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex
// XXX handle all kinds of UV transformations
uvTrafo.mScaling = tex->UVScaling();
uvTrafo.mTranslation = tex->UVTranslation();
uvTrafo.mRotation = tex->UVRotation();
out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, texIndex);
const PropertyTable &props = tex->Props();
@ -1934,14 +1938,14 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex
}
}
if (index == -1) {
FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material");
continue;
}
if (uvIndex == -1) {
uvIndex = index;
} else {
FBXImporter::LogWarn("the UV channel named " + uvSet +
FBXImporter::LogWarn("the UV channel named ", uvSet,
" appears at different positions in meshes, results will be wrong");
}
}
@ -1958,7 +1962,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex
}
}
if (index == -1) {
FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material");
}
if (uvIndex == -1) {
@ -1967,7 +1971,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex
}
if (uvIndex == -1) {
FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel");
FBXImporter::LogWarn("failed to resolve UV channel ", uvSet, ", using first UV channel");
uvIndex = 0;
}
}
@ -2126,7 +2130,12 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
const aiColor3D &Emissive = GetColorPropertyFromMaterial(props, "Emissive", ok);
if (ok) {
out_mat->AddProperty(&Emissive, 1, AI_MATKEY_COLOR_EMISSIVE);
}
} else {
const aiColor3D &emissiveColor = GetColorPropertyFromMaterial(props, "Maya|emissive", ok);
if (ok) {
out_mat->AddProperty(&emissiveColor, 1, AI_MATKEY_COLOR_EMISSIVE);
}
}
const aiColor3D &Ambient = GetColorPropertyFromMaterial(props, "Ambient", ok);
if (ok) {
@ -2207,6 +2216,52 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
if (ok) {
out_mat->AddProperty(&DispFactor, 1, "$mat.displacementscaling", 0, 0);
}
// PBR material information
const aiColor3D &baseColor = GetColorPropertyFromMaterial(props, "Maya|base_color", ok);
if (ok) {
out_mat->AddProperty(&baseColor, 1, AI_MATKEY_BASE_COLOR);
}
const float useColorMap = PropertyGet<float>(props, "Maya|use_color_map", ok);
if (ok) {
out_mat->AddProperty(&useColorMap, 1, AI_MATKEY_USE_COLOR_MAP);
}
const float useMetallicMap = PropertyGet<float>(props, "Maya|use_metallic_map", ok);
if (ok) {
out_mat->AddProperty(&useMetallicMap, 1, AI_MATKEY_USE_METALLIC_MAP);
}
const float metallicFactor = PropertyGet<float>(props, "Maya|metallic", ok);
if (ok) {
out_mat->AddProperty(&metallicFactor, 1, AI_MATKEY_METALLIC_FACTOR);
}
const float useRoughnessMap = PropertyGet<float>(props, "Maya|use_roughness_map", ok);
if (ok) {
out_mat->AddProperty(&useRoughnessMap, 1, AI_MATKEY_USE_ROUGHNESS_MAP);
}
const float roughnessFactor = PropertyGet<float>(props, "Maya|roughness", ok);
if (ok) {
out_mat->AddProperty(&roughnessFactor, 1, AI_MATKEY_ROUGHNESS_FACTOR);
}
const float useEmissiveMap = PropertyGet<float>(props, "Maya|use_emissive_map", ok);
if (ok) {
out_mat->AddProperty(&useEmissiveMap, 1, AI_MATKEY_USE_EMISSIVE_MAP);
}
const float emissiveIntensity = PropertyGet<float>(props, "Maya|emissive_intensity", ok);
if (ok) {
out_mat->AddProperty(&emissiveIntensity, 1, AI_MATKEY_EMISSIVE_INTENSITY);
}
const float useAOMap = PropertyGet<float>(props, "Maya|use_ao_map", ok);
if (ok) {
out_mat->AddProperty(&useAOMap, 1, AI_MATKEY_USE_AO_MAP);
}
}
void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTable &props, const TextureMap &_textures, const MeshGeometry *const mesh) {
@ -2271,6 +2326,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
// XXX handle all kinds of UV transformations
uvTrafo.mScaling = tex->UVScaling();
uvTrafo.mTranslation = tex->UVTranslation();
uvTrafo.mRotation = tex->UVRotation();
out_mat->AddProperty(&uvTrafo, 1, (name + "|uvtrafo").c_str(), aiTextureType_UNKNOWN, 0);
int uvIndex = 0;
@ -2319,14 +2375,14 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
}
}
if (index == -1) {
FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material");
continue;
}
if (uvIndex == -1) {
uvIndex = index;
} else {
FBXImporter::LogWarn("the UV channel named " + uvSet + " appears at different positions in meshes, results will be wrong");
FBXImporter::LogWarn("the UV channel named ", uvSet, " appears at different positions in meshes, results will be wrong");
}
}
} else {
@ -2342,7 +2398,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
}
}
if (index == -1) {
FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material");
FBXImporter::LogWarn("did not find UV channel named ", uvSet, " in a mesh using this material");
}
if (uvIndex == -1) {
@ -2351,7 +2407,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
}
if (uvIndex == -1) {
FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel");
FBXImporter::LogWarn("failed to resolve UV channel ", uvSet, ", using first UV channel");
uvIndex = 0;
}
}
@ -2546,7 +2602,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
anim->mMorphMeshChannels = new aiMeshMorphAnim *[numMorphMeshChannels];
anim->mNumMorphMeshChannels = numMorphMeshChannels;
unsigned int i = 0;
for (auto morphAnimIt : morphAnimDatas) {
for (const auto &morphAnimIt : morphAnimDatas) {
morphAnimData *animData = morphAnimIt.second;
unsigned int numKeys = static_cast<unsigned int>(animData->size());
aiMeshMorphAnim *meshMorphAnim = new aiMeshMorphAnim();
@ -2574,7 +2630,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
// empty animations would fail validation, so drop them
delete anim;
animations.pop_back();
FBXImporter::LogInfo("ignoring empty AnimationStack (using IK?): " + name);
FBXImporter::LogInfo("ignoring empty AnimationStack (using IK?): ", name);
return;
}
@ -2707,13 +2763,13 @@ void FBXConverter::GenerateNodeAnimations(std::vector<aiNodeAnim *> &node_anims,
ai_assert(node);
if (node->TargetProperty().empty()) {
FBXImporter::LogWarn("target property for animation curve not set: " + node->Name());
FBXImporter::LogWarn("target property for animation curve not set: ", node->Name());
continue;
}
curve_node = node;
if (node->Curves().empty()) {
FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode: " + node->Name());
FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode: ", node->Name());
continue;
}
@ -2748,7 +2804,7 @@ void FBXConverter::GenerateNodeAnimations(std::vector<aiNodeAnim *> &node_anims,
if (doc.Settings().optimizeEmptyAnimationCurves &&
IsRedundantAnimationData(target, comp, (chain[i]->second))) {
FBXImporter::LogVerboseDebug("dropping redundant animation channel for node " + target.Name());
FBXImporter::LogVerboseDebug("dropping redundant animation channel for node ", target.Name());
continue;
}

View File

@ -57,9 +57,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp>
#include <memory>
#include <functional>
#include <map>
#include <memory>
#include <utility>
namespace Assimp {
namespace FBX {
@ -248,10 +249,8 @@ Object::~Object()
}
// ------------------------------------------------------------------------------------------------
FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props)
: props(props)
, doc(doc)
{
FileGlobalSettings::FileGlobalSettings(const Document &doc, std::shared_ptr<const PropertyTable> props) :
props(std::move(props)), doc(doc) {
// empty
}
@ -312,7 +311,7 @@ void Document::ReadHeader() {
const Scope& shead = *ehead->Compound();
fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0));
ASSIMP_LOG_DEBUG_F("FBX Version: ", fbxVersion);
ASSIMP_LOG_DEBUG("FBX Version: ", fbxVersion);
// While we may have some success with newer files, we don't support
// the older 6.n fbx format

View File

@ -500,6 +500,10 @@ public:
return uvScaling;
}
const ai_real &UVRotation() const {
return uvRotation;
}
const PropertyTable& Props() const {
ai_assert(props.get());
return *props.get();
@ -517,6 +521,7 @@ public:
private:
aiVector2D uvTrans;
aiVector2D uvScaling;
ai_real uvRotation;
std::string type;
std::string relativeFileName;

View File

@ -79,7 +79,7 @@ void DOMError(const std::string& message, const Element* element /*= nullptr*/)
void DOMWarning(const std::string& message, const Token& token)
{
if(DefaultLogger::get()) {
ASSIMP_LOG_WARN_F("FBX-DOM", Util::GetTokenText(&token), message);
ASSIMP_LOG_WARN("FBX-DOM", Util::GetTokenText(&token), message);
}
}
@ -91,7 +91,7 @@ void DOMWarning(const std::string& message, const Element* element /*= nullptr*/
return;
}
if(DefaultLogger::get()) {
ASSIMP_LOG_WARN("FBX-DOM: " + message);
ASSIMP_LOG_WARN("FBX-DOM: ", message);
}
}

View File

@ -144,9 +144,8 @@ void FBX::Node::AddP70time(
// public member functions for writing nodes to stream
void FBX::Node::Dump(
std::shared_ptr<Assimp::IOStream> outfile,
bool binary, int indent
) {
const std::shared_ptr<Assimp::IOStream> &outfile,
bool binary, int indent) {
if (binary) {
Assimp::StreamWriterLE outstream(outfile);
DumpBinary(outstream);

View File

@ -157,9 +157,8 @@ public: // member functions for writing data to a file or stream
// write the full node to the given file or stream
void Dump(
std::shared_ptr<Assimp::IOStream> outfile,
bool binary, int indent
);
const std::shared_ptr<Assimp::IOStream> &outfile,
bool binary, int indent);
void Dump(Assimp::StreamWriterLE &s, bool binary, int indent);
// these other functions are for writing data piece by piece.

View File

@ -541,10 +541,17 @@ void FBXExporter::WriteReferences ()
// (before any actual data is written)
// ---------------------------------------------------------------
size_t count_nodes(const aiNode* n) {
size_t count = 1;
size_t count_nodes(const aiNode* n, const aiNode* root) {
size_t count;
if (n == root) {
count = n->mNumMeshes; // (not counting root node)
} else if (n->mNumMeshes > 1) {
count = n->mNumMeshes + 1;
} else {
count = 1;
}
for (size_t i = 0; i < n->mNumChildren; ++i) {
count += count_nodes(n->mChildren[i]);
count += count_nodes(n->mChildren[i], root);
}
return count;
}
@ -714,7 +721,7 @@ void FBXExporter::WriteDefinitions ()
// Model / FbxNode
// <~~ node hierarchy
count = int32_t(count_nodes(mScene->mRootNode)) - 1; // (not counting root node)
count = int32_t(count_nodes(mScene->mRootNode, mScene->mRootNode));
if (count) {
n = FBX::Node("ObjectType", "Model");
n.AddChild("Count", count);
@ -812,6 +819,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 +997,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 +1382,7 @@ void FBXExporter::WriteObjects ()
n.End(outstream, binary, indent, true);
}
// aiMaterial
material_uids.clear();
for (size_t i = 0; i < mScene->mNumMaterials; ++i) {
@ -1668,6 +1688,10 @@ void FBXExporter::WriteObjects ()
// link the image data to the texture
connections.emplace_back("C", "OO", image_uid, texture_uid);
aiUVTransform trafo;
unsigned int max = sizeof(aiUVTransform);
aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE, 0), (ai_real *)&trafo, &max);
// now write the actual texture node
FBX::Node tnode("Texture");
// TODO: some way to determine texture name?
@ -1678,6 +1702,9 @@ void FBXExporter::WriteObjects ()
tnode.AddChild("Version", int32_t(202));
tnode.AddChild("TextureName", texture_name);
FBX::Node p("Properties70");
p.AddP70vectorA("Translation", trafo.mTranslation[0], trafo.mTranslation[1], 0.0);
p.AddP70vectorA("Rotation", 0, 0, trafo.mRotation);
p.AddP70vectorA("Scaling", trafo.mScaling[0], trafo.mScaling[1], 0.0);
p.AddP70enum("CurrentTextureBlendMode", 0); // TODO: verify
//p.AddP70string("UVSet", ""); // TODO: how should this work?
p.AddP70bool("UseMaterial", 1);
@ -1697,6 +1724,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:
@ -2089,7 +2210,65 @@ void FBXExporter::WriteObjects ()
bpnode.Dump(outstream, binary, indent);
}*/
// TODO: cameras, lights
// lights
indent = 1;
lights_uids.clear();
for (size_t li = 0; li < mScene->mNumLights; ++li) {
aiLight* l = mScene->mLights[li];
int64_t uid = generate_uid();
const std::string lightNodeAttributeName = l->mName.C_Str() + FBX::SEPARATOR + "NodeAttribute";
FBX::Node lna("NodeAttribute");
lna.AddProperties(uid, lightNodeAttributeName, "Light");
FBX::Node lnap("Properties70");
// Light color.
lnap.AddP70colorA("Color", l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b);
// TODO Assimp light description is quite concise and do not handle light intensity.
// Default value to 1000W.
lnap.AddP70numberA("Intensity", 1000);
// FBXLight::EType conversion
switch (l->mType) {
case aiLightSource_POINT:
lnap.AddP70enum("LightType", 0);
break;
case aiLightSource_DIRECTIONAL:
lnap.AddP70enum("LightType", 1);
break;
case aiLightSource_SPOT:
lnap.AddP70enum("LightType", 2);
lnap.AddP70numberA("InnerAngle", AI_RAD_TO_DEG(l->mAngleInnerCone));
lnap.AddP70numberA("OuterAngle", AI_RAD_TO_DEG(l->mAngleOuterCone));
break;
// TODO Assimp do not handle 'area' nor 'volume' lights, but FBX does.
/*case aiLightSource_AREA:
lnap.AddP70enum("LightType", 3);
lnap.AddP70enum("AreaLightShape", 0); // 0=Rectangle, 1=Sphere
break;
case aiLightSource_VOLUME:
lnap.AddP70enum("LightType", 4);
break;*/
default:
break;
}
// Did not understood how to configure the decay so disabling attenuation.
lnap.AddP70enum("DecayType", 0);
// Dump to FBX stream
lna.AddChild(lnap);
lna.AddChild("TypeFlags", FBX::FBXExportProperty("Light"));
lna.AddChild("GeometryVersion", FBX::FBXExportProperty(int32_t(124)));
lna.Dump(outstream, binary, indent);
// Store name and uid (will be used later when parsing scene nodes)
lights_uids[l->mName.C_Str()] = uid;
}
// TODO: cameras
// write nodes (i.e. model hierarchy)
// start at root node
@ -2493,10 +2672,19 @@ void FBXExporter::WriteModelNodes(
// and connect them
connections.emplace_back("C", "OO", node_attribute_uid, node_uid);
} else {
// generate a null node so we can add children to it
WriteModelNode(
outstream, binary, node, node_uid, "Null", transform_chain
);
const auto& lightIt = lights_uids.find(node->mName.C_Str());
if(lightIt != lights_uids.end()) {
// Node has a light connected to it.
WriteModelNode(
outstream, binary, node, node_uid, "Light", transform_chain
);
connections.emplace_back("C", "OO", lightIt->second, node_uid);
} else {
// generate a null node so we can add children to it
WriteModelNode(
outstream, binary, node, node_uid, "Null", transform_chain
);
}
}
// if more than one child mesh, make nodes for each mesh
@ -2518,17 +2706,14 @@ void FBXExporter::WriteModelNodes(
],
new_node_uid
);
// write model node
FBX::Node m("Model");
aiNode new_node;
// take name from mesh name, if it exists
std::string name = mScene->mMeshes[node->mMeshes[i]]->mName.C_Str();
name += FBX::SEPARATOR + "Model";
m.AddProperties(new_node_uid, name, "Mesh");
m.AddChild("Version", int32_t(232));
FBX::Node p("Properties70");
p.AddP70enum("InheritType", 1);
m.AddChild(p);
m.Dump(outstream, binary, 1);
new_node.mName = mScene->mMeshes[node->mMeshes[i]]->mName;
// write model node
WriteModelNode(
outstream, binary, &new_node, new_node_uid, "Mesh", std::vector<std::pair<std::string,aiVector3D>>()
);
}
}
@ -2540,16 +2725,14 @@ void FBXExporter::WriteModelNodes(
}
}
void FBXExporter::WriteAnimationCurveNode(
StreamWriterLE& outstream,
int64_t uid,
const std::string& name, // "T", "R", or "S"
aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc
int64_t layer_uid,
int64_t node_uid
) {
StreamWriterLE &outstream,
int64_t uid,
const std::string &name, // "T", "R", or "S"
aiVector3D default_value,
const std::string &property_name, // "Lcl Translation" etc
int64_t layer_uid,
int64_t node_uid) {
FBX::Node n("AnimationCurveNode");
n.AddProperties(uid, name + FBX::SEPARATOR + "AnimCurveNode", "");
FBX::Node p("Properties70");
@ -2564,7 +2747,6 @@ void FBXExporter::WriteAnimationCurveNode(
this->connections.emplace_back("C", "OP", uid, node_uid, property_name);
}
void FBXExporter::WriteAnimationCurve(
StreamWriterLE& outstream,
double default_value,

View File

@ -63,10 +63,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct aiScene;
struct aiNode;
//struct aiMaterial;
struct aiLight;
namespace Assimp
{
namespace Assimp {
class IOSystem;
class IOStream;
class ExportProperties;
@ -95,6 +94,7 @@ namespace Assimp
std::vector<int64_t> mesh_uids;
std::vector<int64_t> material_uids;
std::map<const aiNode*,int64_t> node_uids;
std::map<std::string,int64_t> lights_uids;
// this crude unique-ID system is actually fine
int64_t last_uid = 999999;
@ -154,14 +154,13 @@ namespace Assimp
FBX::TransformInheritance ti_type=FBX::TransformInheritance_RSrs
);
void WriteAnimationCurveNode(
StreamWriterLE& outstream,
int64_t uid,
const std::string& name, // "T", "R", or "S"
aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc
int64_t animation_layer_uid,
int64_t node_uid
);
StreamWriterLE &outstream,
int64_t uid,
const std::string &name, // "T", "R", or "S"
aiVector3D default_value,
const std::string &property_name, // "Lcl Translation" etc
int64_t animation_layer_uid,
int64_t node_uid);
void WriteAnimationCurve(
StreamWriterLE& outstream,
double default_value,

View File

@ -82,7 +82,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
// lower-case shading because Blender (for example) writes "Phong"
for (size_t i = 0; i < shading.length(); ++i) {
shading[i] = static_cast<char>(tolower(shading[i]));
shading[i] = static_cast<char>(tolower(static_cast<unsigned char>(shading[i])));
}
std::string templateName;
if(shading == "phong") {
@ -210,6 +210,11 @@ Texture::Texture(uint64_t id, const Element& element, const Document& doc, const
uvTrans.y = trans.y;
}
const aiVector3D &rotation = PropertyGet<aiVector3D>(*props, "Rotation", ok);
if (ok) {
uvRotation = rotation.z;
}
// resolve video links
if(doc.Settings().readTextures) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
@ -352,7 +357,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
}
} 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): ",
ASSIMP_LOG_VERBOSE_DEBUG("Caught exception in FBXMaterial (likely because content was already loaded): ",
runtimeError.what());
}
}

View File

@ -307,8 +307,8 @@ void MeshGeometry::ReadLayerElement(const Scope& layerElement)
}
}
FBXImporter::LogError(Formatter::format("failed to resolve vertex layer element: ")
<< type << ", index: " << typedIndex);
FBXImporter::LogError("failed to resolve vertex layer element: ",
type, ", index: ", typedIndex);
}
// ------------------------------------------------------------------------------------------------
@ -324,13 +324,13 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
if (type == "LayerElementUV") {
if(index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
FBXImporter::LogError(Formatter::format("ignoring UV layer, maximum number of UV channels exceeded: ")
<< index << " (limit is " << AI_MAX_NUMBER_OF_TEXTURECOORDS << ")" );
FBXImporter::LogError("ignoring UV layer, maximum number of UV channels exceeded: ",
index, " (limit is ", AI_MAX_NUMBER_OF_TEXTURECOORDS, ")" );
return;
}
const Element* Name = source["Name"];
m_uvNames[index] = "";
m_uvNames[index] = std::string();
if(Name) {
m_uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0));
}
@ -402,8 +402,8 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
}
else if (type == "LayerElementColor") {
if(index >= AI_MAX_NUMBER_OF_COLOR_SETS) {
FBXImporter::LogError(Formatter::format("ignoring vertex color layer, maximum number of color sets exceeded: ")
<< index << " (limit is " << AI_MAX_NUMBER_OF_COLOR_SETS << ")" );
FBXImporter::LogError("ignoring vertex color layer, maximum number of color sets exceeded: ",
index, " (limit is ", AI_MAX_NUMBER_OF_COLOR_SETS, ")" );
return;
}
@ -449,8 +449,8 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
if (tempData.size() != mapping_offsets.size()) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByVertice mapping: ")
<< tempData.size() << ", expected " << mapping_offsets.size());
FBXImporter::LogError("length of input data unexpected for ByVertice mapping: ",
tempData.size(), ", expected ", mapping_offsets.size());
return;
}
@ -470,8 +470,8 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
if (uvIndices.size() != vertex_count) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByVertice mapping: ")
<< uvIndices.size() << ", expected " << vertex_count);
FBXImporter::LogError("length of input data unexpected for ByVertice mapping: ",
uvIndices.size(), ", expected ", vertex_count);
return;
}
@ -493,8 +493,8 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
if (tempData.size() != vertex_count) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
<< tempData.size() << ", expected " << vertex_count
FBXImporter::LogError("length of input data unexpected for ByPolygon mapping: ",
tempData.size(), ", expected ", vertex_count
);
return;
}
@ -508,9 +508,15 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
std::vector<int> uvIndices;
ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
if (uvIndices.size() > vertex_count) {
FBXImporter::LogWarn("trimming length of input array for ByPolygonVertex mapping: ",
uvIndices.size(), ", expected ", vertex_count);
uvIndices.resize(vertex_count);
}
if (uvIndices.size() != vertex_count) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygonVertex mapping: ")
<< uvIndices.size() << ", expected " << vertex_count);
FBXImporter::LogError("length of input data unexpected for ByPolygonVertex mapping: ",
uvIndices.size(), ", expected ", vertex_count);
return;
}
@ -531,8 +537,8 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
}
}
else {
FBXImporter::LogError(Formatter::format("ignoring vertex data channel, access type not implemented: ")
<< MappingInformationType << "," << ReferenceInformationType);
FBXImporter::LogError("ignoring vertex data channel, access type not implemented: ",
MappingInformationType, ",", ReferenceInformationType);
}
}
@ -598,15 +604,15 @@ void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out,
}
// ------------------------------------------------------------------------------------------------
static const std::string BinormalIndexToken = "BinormalIndex";
static const std::string BinormalsIndexToken = "BinormalsIndex";
static const char * BinormalIndexToken = "BinormalIndex";
static const char * BinormalsIndexToken = "BinormalsIndex";
void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source,
const std::string& MappingInformationType,
const std::string& ReferenceInformationType)
{
const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal";
const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken.c_str() : BinormalIndexToken.c_str();
const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken : BinormalIndexToken;
ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType,
str,
strIdx,
@ -636,10 +642,10 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
if (MappingInformationType == "AllSame") {
// easy - same material for all faces
if (materials_out.empty()) {
FBXImporter::LogError(Formatter::format("expected material index, ignoring"));
FBXImporter::LogError("expected material index, ignoring");
return;
} else if (materials_out.size() > 1) {
FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one"));
FBXImporter::LogWarn("expected only a single material index, ignoring all except the first one");
materials_out.clear();
}
@ -649,14 +655,14 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
materials_out.resize(face_count);
if(materials_out.size() != face_count) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
<< materials_out.size() << ", expected " << face_count
FBXImporter::LogError("length of input data unexpected for ByPolygon mapping: ",
materials_out.size(), ", expected ", face_count
);
return;
}
} else {
FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ")
<< MappingInformationType << "," << ReferenceInformationType);
FBXImporter::LogError("ignoring material assignments, access type not implemented: ",
MappingInformationType, ",", ReferenceInformationType);
}
}
// ------------------------------------------------------------------------------------------------

View File

@ -462,7 +462,7 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token";
return "";
return std::string();
}
if(t.IsBinary())
@ -470,7 +470,7 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
const char* data = t.begin();
if (data[0] != 'S') {
err_out = "failed to parse S(tring), unexpected data type (binary)";
return "";
return std::string();
}
// read string length
@ -484,13 +484,13 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
const size_t length = static_cast<size_t>(t.end() - t.begin());
if(length < 2) {
err_out = "token is too short to hold a string";
return "";
return std::string();
}
const char* s = t.begin(), *e = t.end() - 1;
if (*s != '\"' || *e != '\"') {
err_out = "expected double quoted string";
return "";
return std::string();
}
return std::string(s+1,length-2);

View File

@ -52,6 +52,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXDocumentUtil.h"
#include "FBXProperties.h"
#include <utility>
namespace Assimp {
namespace FBX {
@ -131,7 +133,7 @@ Property* ReadTypedProperty(const Element& element)
ParseTokenAsFloat(*tok[6]))
);
}
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) {
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"float") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) {
checkTokenCount(tok, 5);
return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
}
@ -155,7 +157,7 @@ std::string PeekPropertyName(const Element& element)
ai_assert(element.KeyToken().StringContents() == "P");
const TokenList& tok = element.Tokens();
if(tok.size() < 4) {
return "";
return std::string();
}
return ParseTokenAsString(*tok[0]);
@ -172,10 +174,8 @@ PropertyTable::PropertyTable()
}
// ------------------------------------------------------------------------------------------------
PropertyTable::PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps)
: templateProps(templateProps)
, element(&element)
{
PropertyTable::PropertyTable(const Element &element, std::shared_ptr<const PropertyTable> templateProps) :
templateProps(std::move(templateProps)), element(&element) {
const Scope& scope = GetRequiredScope(element);
for(const ElementMap::value_type& v : scope.Elements()) {
if(v.first != "P") {
@ -199,7 +199,6 @@ PropertyTable::PropertyTable(const Element& element, std::shared_ptr<const Prope
}
}
// ------------------------------------------------------------------------------------------------
PropertyTable::~PropertyTable()
{

View File

@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssetLib/HMP/HMPLoader.h"
#include "AssetLib/MD2/MD2FileData.h"
#include <assimp/StringUtils.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
@ -151,13 +152,11 @@ void HMPImporter::InternReadFile(const std::string &pFile,
InternReadFile_HMP7();
} else {
// Print the magic word to the logger
char szBuffer[5];
szBuffer[0] = ((char *)&iMagic)[0];
szBuffer[1] = ((char *)&iMagic)[1];
szBuffer[2] = ((char *)&iMagic)[2];
szBuffer[3] = ((char *)&iMagic)[3];
szBuffer[4] = '\0';
std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic));
delete[] mBuffer;
mBuffer = nullptr;
// We're definitely unable to load this file
throw DeadlyImportError("Unknown HMP subformat ", pFile,
". Magic word (", szBuffer, ") is not known");

View File

@ -513,7 +513,7 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
}
// we got a list of in-out-combinations of intersections. That should be an even number of intersections, or
// we're fucked.
// we are facing a non-recoverable error.
if ((intersections.size() & 1) != 0) {
IFCImporter::LogWarn("Odd number of intersections, can't work with that. Omitting half space boundary check.");
continue;
@ -715,7 +715,7 @@ void ProcessBoolean(const Schema_2x3::IfcBooleanResult &boolean, TempMesh &resul
// DIFFERENCE
if (const Schema_2x3::IfcBooleanResult *const clip = boolean.ToPtr<Schema_2x3::IfcBooleanResult>()) {
if (clip->Operator != "DIFFERENCE") {
IFCImporter::LogWarn("encountered unsupported boolean operator: " + (std::string)clip->Operator);
IFCImporter::LogWarn("encountered unsupported boolean operator: ", (std::string)clip->Operator);
return;
}
@ -756,7 +756,7 @@ void ProcessBoolean(const Schema_2x3::IfcBooleanResult &boolean, TempMesh &resul
ProcessBooleanExtrudedAreaSolidDifference(as, result, first_operand, conv);
}
} else {
IFCImporter::LogWarn("skipping unknown IfcBooleanResult entity, type is " + boolean.GetClassName());
IFCImporter::LogWarn("skipping unknown IfcBooleanResult entity, type is ", boolean.GetClassName());
}
}

View File

@ -216,7 +216,7 @@ void ProcessConnectedFaceSet(const Schema_2x3::IfcConnectedFaceSet& fset, TempMe
}
}
else {
IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is " + bound.Bound->GetClassName());
IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is ", bound.Bound->GetClassName());
continue;
}
@ -729,7 +729,7 @@ void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept, TempMesh&
ProcessRevolvedAreaSolid(*rev,meshout,conv);
}
else {
IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is " + swept.GetClassName());
IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is ", swept.GetClassName());
}
}
@ -740,7 +740,7 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
bool fix_orientation = false;
std::shared_ptr< TempMesh > meshtmp = std::make_shared<TempMesh>();
if(const Schema_2x3::IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<Schema_2x3::IfcShellBasedSurfaceModel>()) {
for(std::shared_ptr<const Schema_2x3::IfcShell> shell :shellmod->SbsmBoundary) {
for (const std::shared_ptr<const Schema_2x3::IfcShell> &shell : shellmod->SbsmBoundary) {
try {
const ::Assimp::STEP::EXPRESS::ENTITY& e = shell->To<::Assimp::STEP::EXPRESS::ENTITY>();
const Schema_2x3::IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<Schema_2x3::IfcConnectedFaceSet>();
@ -781,7 +781,7 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
return false;
}
else {
IFCImporter::LogWarn("skipping unknown IfcGeometricRepresentationItem entity, type is " + geo.GetClassName());
IFCImporter::LogWarn("skipping unknown IfcGeometricRepresentationItem entity, type is ", geo.GetClassName());
return false;
}

View File

@ -115,7 +115,7 @@ static const aiImporterDesc desc = {
0,
0,
0,
"ifc ifczip stp"
"ifc ifczip step stp"
};
// ------------------------------------------------------------------------------------------------
@ -243,12 +243,12 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
if (!DefaultLogger::isNullLogger()) {
LogDebug("File schema is \'" + head.fileSchema + '\'');
LogDebug("File schema is \'", head.fileSchema, '\'');
if (head.timestamp.length()) {
LogDebug("Timestamp \'" + head.timestamp + '\'');
LogDebug("Timestamp \'", head.timestamp, '\'');
}
if (head.app.length()) {
LogDebug("Application/Exporter identline is \'" + head.app + '\'');
LogDebug("Application/Exporter identline is \'", head.app, '\'');
}
}
@ -315,7 +315,7 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// this must be last because objects are evaluated lazily as we process them
if (!DefaultLogger::isNullLogger()) {
LogDebug((Formatter::format(), "STEP: evaluated ", db->GetEvaluatedObjectCount(), " object records"));
LogDebug("STEP: evaluated ", db->GetEvaluatedObjectCount(), " object records");
}
}
@ -403,7 +403,7 @@ void ResolveObjectPlacement(aiMatrix4x4 &m, const Schema_2x3::IfcObjectPlacement
m = tmpM * m;
}
} else {
IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is " + place.GetClassName());
IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is ", place.GetClassName());
}
}
@ -438,7 +438,7 @@ bool ProcessMappedItem(const Schema_2x3::IfcMappedItem &mapped, aiNode *nd_src,
bool got = false;
for (const Schema_2x3::IfcRepresentationItem &item : repr.Items) {
if (!ProcessRepresentationItem(item, localmatid, meshes, conv)) {
IFCImporter::LogWarn("skipping mapped entity of type " + item.GetClassName() + ", no representations could be generated");
IFCImporter::LogWarn("skipping mapped entity of type ", item.GetClassName(), ", no representations could be generated");
} else
got = true;
}
@ -567,7 +567,7 @@ typedef std::map<std::string, std::string> Metadata;
// ------------------------------------------------------------------------------------------------
void ProcessMetadata(const Schema_2x3::ListOf<Schema_2x3::Lazy<Schema_2x3::IfcProperty>, 1, 0> &set, ConversionData &conv, Metadata &properties,
const std::string &prefix = "",
const std::string &prefix = std::string(),
unsigned int nest = 0) {
for (const Schema_2x3::IfcProperty &property : set) {
const std::string &key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name;
@ -618,7 +618,7 @@ void ProcessMetadata(const Schema_2x3::ListOf<Schema_2x3::Lazy<Schema_2x3::IfcPr
ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1);
}
} else {
properties[key] = "";
properties[key] = std::string();
}
}
}
@ -856,7 +856,7 @@ void ProcessSpatialStructures(ConversionData &conv) {
if (!prod) {
continue;
}
IFCImporter::LogVerboseDebug("looking at spatial structure `" + (prod->Name ? prod->Name.Get() : "unnamed") + "`" + (prod->ObjectType ? " which is of type " + prod->ObjectType.Get() : ""));
IFCImporter::LogVerboseDebug("looking at spatial structure `", (prod->Name ? prod->Name.Get() : "unnamed"), "`", (prod->ObjectType ? " which is of type " + prod->ObjectType.Get() : ""));
// the primary sites are referenced by an IFCRELAGGREGATES element which assigns them to the IFCPRODUCT
const STEP::DB::RefMap &refs = conv.db.GetRefs();

View File

@ -64,7 +64,7 @@ static int ConvertShadingMode(const std::string& name) {
else if (name == "PHONG") {
return aiShadingMode_Phong;
}
IFCImporter::LogWarn("shading mode "+name+" not recognized by Assimp, using Phong instead");
IFCImporter::LogWarn("shading mode ", name, " not recognized by Assimp, using Phong instead");
return aiShadingMode_Phong;
}
@ -75,7 +75,7 @@ static void FillMaterial(aiMaterial* mat,const IFC::Schema_2x3::IfcSurfaceStyle*
mat->AddProperty(&name,AI_MATKEY_NAME);
// now see which kinds of surface information are present
for(std::shared_ptr< const IFC::Schema_2x3::IfcSurfaceStyleElementSelect > sel2 : surf->Styles) {
for (const std::shared_ptr<const IFC::Schema_2x3::IfcSurfaceStyleElementSelect> &sel2 : surf->Styles) {
if (const IFC::Schema_2x3::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::Schema_2x3::IfcSurfaceStyleShading>(conv.db)) {
aiColor4D col_base,col;
@ -124,7 +124,7 @@ static void FillMaterial(aiMaterial* mat,const IFC::Schema_2x3::IfcSurfaceStyle*
}
}
}
}
}
}
}
@ -134,7 +134,7 @@ unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionDat
for(;range.first != range.second; ++range.first) {
if(const IFC::Schema_2x3::IfcStyledItem* const styled = conv.db.GetObject((*range.first).second)->ToPtr<IFC::Schema_2x3::IfcStyledItem>()) {
for(const IFC::Schema_2x3::IfcPresentationStyleAssignment& as : styled->Styles) {
for(std::shared_ptr<const IFC::Schema_2x3::IfcPresentationStyleSelect> sel : as.Styles) {
for (const std::shared_ptr<const IFC::Schema_2x3::IfcPresentationStyleSelect> &sel : as.Styles) {
if( const IFC::Schema_2x3::IfcSurfaceStyle* const surf = sel->ResolveSelectPtr<IFC::Schema_2x3::IfcSurfaceStyle>(conv.db) ) {
// try to satisfy from cache
@ -145,7 +145,7 @@ unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionDat
// not found, create new material
const std::string side = static_cast<std::string>(surf->Side);
if( side != "BOTH" ) {
IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: " + side);
IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: ", side);
}
std::unique_ptr<aiMaterial> mat(new aiMaterial());

View File

@ -68,7 +68,7 @@ bool ProcessCurve(const Schema_2x3::IfcCurve& curve, TempMesh& meshout, Convers
{
std::unique_ptr<const Curve> cv(Curve::Convert(curve,conv));
if (!cv) {
IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is " + curve.GetClassName());
IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is ", curve.GetClassName());
return false;
}
@ -78,7 +78,7 @@ bool ProcessCurve(const Schema_2x3::IfcCurve& curve, TempMesh& meshout, Convers
bc->SampleDiscrete(meshout);
}
catch(const CurveError& cv) {
IFCImporter::LogError(cv.mStr + " (error occurred while processing curve)");
IFCImporter::LogError(cv.mStr, " (error occurred while processing curve)");
return false;
}
meshout.mVertcnt.push_back(static_cast<unsigned int>(meshout.mVerts.size()));
@ -152,7 +152,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
meshout.mVertcnt.push_back(12);
}
else {
IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is " + def.GetClassName());
IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is ", def.GetClassName());
return;
}
@ -174,7 +174,7 @@ bool ProcessProfile(const Schema_2x3::IfcProfileDef& prof, TempMesh& meshout, Co
ProcessParametrizedProfile(*cparam,meshout,conv);
}
else {
IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is " + prof.GetClassName());
IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is ", prof.GetClassName());
return false;
}
meshout.RemoveAdjacentDuplicates();

View File

@ -506,7 +506,7 @@ IfcFloat ConvertSIPrefix(const std::string& prefix)
return 1e-18f;
}
else {
IFCImporter::LogError("Unrecognized SI prefix: " + prefix);
IFCImporter::LogError("Unrecognized SI prefix: ", prefix);
return 1;
}
}

View File

@ -54,6 +54,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/mesh.h>
#include <assimp/material.h>
#include <utility>
struct aiNode;
namespace Assimp {
@ -137,14 +139,10 @@ struct TempOpening
}
// ------------------------------------------------------------------------------
TempOpening(const IFC::Schema_2x3::IfcSolidModel* solid,IfcVector3 extrusionDir,
std::shared_ptr<TempMesh> profileMesh,
std::shared_ptr<TempMesh> profileMesh2D)
: solid(solid)
, extrusionDir(extrusionDir)
, profileMesh(profileMesh)
, profileMesh2D(profileMesh2D)
{
TempOpening(const IFC::Schema_2x3::IfcSolidModel *solid, IfcVector3 extrusionDir,
std::shared_ptr<TempMesh> profileMesh,
std::shared_ptr<TempMesh> profileMesh2D) :
solid(solid), extrusionDir(extrusionDir), profileMesh(std::move(profileMesh)), profileMesh2D(std::move(profileMesh2D)) {
}
// ------------------------------------------------------------------------------

View File

@ -639,7 +639,7 @@ void IRRImporter::GenerateGraph(Node *root, aiNode *rootOut, aiScene *scene,
// graph we're currently building
aiScene *localScene = batch.GetImport(root->id);
if (!localScene) {
ASSIMP_LOG_ERROR("IRR: Unable to load external file: " + root->meshPath);
ASSIMP_LOG_ERROR("IRR: Unable to load external file: ", root->meshPath);
break;
}
attach.push_back(AttachmentInfo(localScene, rootOut));
@ -859,13 +859,13 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open IRR file " + pFile + "");
throw DeadlyImportError("Failed to open IRR file ", pFile);
}
// Construct the irrXML parser
XmlParser st;
if (!st.parse( file.get() )) {
return;
throw DeadlyImportError("XML parse error while loading IRR file ", pFile);
}
pugi::xml_node rootElement = st.getRootNode();
@ -963,7 +963,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
ASSIMP_LOG_ERROR("IRR: Billboards are not supported by Assimp");
nd = new Node(Node::DUMMY);
} else {
ASSIMP_LOG_WARN("IRR: Found unknown node: " + std::string(attrib.name()));
ASSIMP_LOG_WARN("IRR: Found unknown node: ", attrib.name());
/* We skip the contents of nodes we don't know.
* We parse the transformation and all animators
@ -1181,7 +1181,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
lights.pop_back();
curNode->type = Node::DUMMY;
ASSIMP_LOG_ERROR("Ignoring light of unknown type: " + prop.value);
ASSIMP_LOG_ERROR("Ignoring light of unknown type: ", prop.value);
}
} else if ((prop.name == "Mesh" && Node::MESH == curNode->type) ||
Node::ANIMMESH == curNode->type) {
@ -1225,7 +1225,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
} else if (prop.value == "followSpline") {
curAnim->type = Animator::FOLLOW_SPLINE;
} else {
ASSIMP_LOG_WARN("IRR: Ignoring unknown animator: " + prop.value);
ASSIMP_LOG_WARN("IRR: Ignoring unknown animator: ", prop.value);
curAnim->type = Animator::UNKNOWN;
}

View File

@ -135,12 +135,12 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == NULL)
throw DeadlyImportError("Failed to open IRRMESH file " + pFile + "");
throw DeadlyImportError("Failed to open IRRMESH file ", pFile);
// Construct the irrXML parser
XmlParser parser;
if (!parser.parse( file.get() )) {
return;
throw DeadlyImportError("XML parse error while loading IRRMESH file ", pFile);
}
XmlNode root = parser.getRootNode();

View File

@ -260,7 +260,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) {
prop.value == "parallaxmap_trans_add") {
matFlags = AI_IRRMESH_MAT_normalmap_ta;
} else {
ASSIMP_LOG_WARN("IRRMat: Unrecognized material type: " + prop.value);
ASSIMP_LOG_WARN("IRRMat: Unrecognized material type: ", prop.value);
}
}

View File

@ -242,7 +242,7 @@ LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned i
else
{
// procedural or gradient, not supported
ASSIMP_LOG_ERROR_F("LWOB: Unsupported legacy texture: ", type);
ASSIMP_LOG_ERROR("LWOB: Unsupported legacy texture: ", type);
}
return tex;

View File

@ -502,7 +502,7 @@ struct Surface {
Surface() :
mColor(0.78431f, 0.78431f, 0.78431f), bDoubleSided(false), mDiffuseValue(1.f), mSpecularValue(0.f), mTransparency(0.f), mGlossiness(0.4f), mLuminosity(0.f), mColorHighlights(0.f), mMaximumSmoothAngle(0.f) // 0 == not specified, no smoothing
,
mVCMap(""),
mVCMap(),
mVCMapType(AI_LWO_RGBA),
mIOR(1.f) // vakuum
,

View File

@ -961,7 +961,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
switch (type) {
case AI_LWO_TXUV:
if (dims != 2) {
ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'" + name + "\' with !2 components");
ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'", name, "\' with !2 components");
return;
}
base = FindEntry(mCurLayer->mUVChannels, name, perPoly);
@ -969,7 +969,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
case AI_LWO_WGHT:
case AI_LWO_MNVW:
if (dims != 1) {
ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'" + name + "\' with !1 components");
ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'", name, "\' with !1 components");
return;
}
base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels : mCurLayer->mSWeightChannels), name, perPoly);
@ -977,7 +977,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
case AI_LWO_RGB:
case AI_LWO_RGBA:
if (dims != 3 && dims != 4) {
ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'" + name + "\' with a dimension > 4 or < 3");
ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'", name, "\' with a dimension > 4 or < 3");
return;
}
base = FindEntry(mCurLayer->mVColorChannels, name, perPoly);
@ -1006,7 +1006,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
if (name == "APS.Level") {
// XXX handle this (seems to be subdivision-related).
}
ASSIMP_LOG_WARN_F("LWO2: Skipping unknown VMAP/VMAD channel \'", name, "\'");
ASSIMP_LOG_WARN("LWO2: Skipping unknown VMAP/VMAD channel \'", name, "\'");
return;
};
base->Allocate((unsigned int)mCurLayer->mTempPoints.size());
@ -1026,7 +1026,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs;
if (idx >= numPoints) {
ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAP/VMAD entry \'", name, "\', vertex index is out of range");
ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAP/VMAD entry \'", name, "\', vertex index is out of range");
mFileBuffer += base->dims << 2u;
continue;
}
@ -1036,7 +1036,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
// we have already a VMAP entry for this vertex - thus
// we need to duplicate the corresponding polygon.
if (polyIdx >= numFaces) {
ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAD entry \'", name, "\', polygon index is out of range");
ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAD entry \'", name, "\', polygon index is out of range");
mFileBuffer += base->dims << 2u;
continue;
}
@ -1076,7 +1076,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
CreateNewEntry(mCurLayer->mNormals, srcIdx);
}
if (!had) {
ASSIMP_LOG_WARN_F("LWO2: Failure evaluating VMAD entry \'", name, "\', vertex index wasn't found in that polygon");
ASSIMP_LOG_WARN("LWO2: Failure evaluating VMAD entry \'", name, "\', vertex index wasn't found in that polygon");
ai_assert(had);
}
}

View File

@ -335,7 +335,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) {
m = aiShadingMode_Fresnel;
break;
} else {
ASSIMP_LOG_WARN_F("LWO2: Unknown surface shader: ", shader.functionName);
ASSIMP_LOG_WARN("LWO2: Unknown surface shader: ", shader.functionName);
}
}
if (surf.mMaximumSmoothAngle <= 0.0)
@ -711,7 +711,7 @@ void LWOImporter::LoadLWO2Surface(unsigned int size) {
}
}
if (derived.size()) {
ASSIMP_LOG_WARN("LWO2: Unable to find source surface: " + derived);
ASSIMP_LOG_WARN("LWO2: Unable to find source surface: ", derived);
}
}

View File

@ -318,7 +318,7 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
} else {
++s;
}
std::string::size_type t = src.path.substr(s).find_last_of(".");
std::string::size_type t = src.path.substr(s).find_last_of('.');
nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)", src.path.substr(s).substr(0, t).c_str(), combined);
return;
@ -346,7 +346,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<Attachm
if (src.path.length()) {
obj = batch.GetImport(src.id);
if (!obj) {
ASSIMP_LOG_ERROR("LWS: Failed to read external file " + src.path);
ASSIMP_LOG_ERROR("LWS: Failed to read external file ", src.path);
} else {
if (obj->mRootNode->mNumChildren == 1) {
@ -538,7 +538,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// get file format version and print to log
++it;
unsigned int version = strtoul10((*it).tokens[0].c_str());
ASSIMP_LOG_INFO("LWS file format version is " + (*it).tokens[0]);
ASSIMP_LOG_INFO("LWS file format version is ", (*it).tokens[0]);
first = 0.;
last = 60.;
fps = 25.; // seems to be a good default frame rate

View File

@ -88,7 +88,7 @@ struct NodeDesc {
id(),
number(0),
parent(0),
name(""),
name(),
isPivotSet(false),
lightColor(1.f, 1.f, 1.f),
lightIntensity(1.f),

View File

@ -294,21 +294,17 @@ void ExportSceneM3D(
// Worker function for exporting a scene to ASCII A3D.
// Prototyped and registered in Exporter.cpp
void ExportSceneM3DA(
const char *,
IOSystem *,
const aiScene *,
const ExportProperties *
const char *pFile,
IOSystem *pIOSystem,
const aiScene *pScene,
const ExportProperties *pProperties
) {
#ifdef M3D_ASCII
// initialize the exporter
M3DExporter exporter(pScene, pProperties);
// perform ascii export
exporter.doExport(pFile, pIOSystem, true);
#else
throw DeadlyExportError("Assimp configured without M3D_ASCII support");
#endif
}
// ------------------------------------------------------------------------------------------------

View File

@ -95,11 +95,7 @@ static const aiImporterDesc desc = {
0,
0,
0,
#ifdef M3D_ASCII
"m3d a3d"
#else
"m3d"
#endif
};
namespace Assimp {
@ -119,9 +115,7 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
const std::string extension = GetExtension(pFile);
if (extension == "m3d"
#ifdef M3D_ASCII
|| extension == "a3d"
#endif
)
return true;
else if (!extension.length() || checkSig) {
@ -137,13 +131,11 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
*/
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
unsigned char data[4];
if (4 != pStream->Read(data, 1, 4)) {
if (!pStream || 4 != pStream->Read(data, 1, 4)) {
return false;
}
return !memcmp(data, "3DMO", 4) /* bin */
#ifdef M3D_ASCII
|| !memcmp(data, "3dmo", 4) /* ASCII */
#endif
;
}
return false;
@ -176,12 +168,10 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys
if (!memcmp(buffer.data(), "3DMO", 4) && memcmp(buffer.data() + 4, &fileSize, 4)) {
throw DeadlyImportError("Bad binary header in file ", file, ".");
}
#ifdef M3D_ASCII
// make sure there's a terminator zero character, as input must be ASCIIZ
if (!memcmp(buffer.data(), "3dmo", 4)) {
buffer.push_back(0);
}
#endif
// Get the path for external assets
std::string folderName("./");
@ -194,7 +184,7 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys
}
//DefaultLogger::create("/dev/stderr", Logger::VERBOSE);
ASSIMP_LOG_DEBUG_F("M3D: loading ", file);
ASSIMP_LOG_DEBUG("M3D: loading ", file);
// let the C SDK do the hard work for us
M3DWrapper m3d(pIOHandler, buffer);
@ -210,7 +200,7 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys
pScene->mRootNode->mNumChildren = 0;
mScene = pScene;
ASSIMP_LOG_DEBUG("M3D: root node " + m3d.Name());
ASSIMP_LOG_DEBUG("M3D: root node ", m3d.Name());
// now we just have to fill up the Assimp structures in pScene
importMaterials(m3d);
@ -240,7 +230,7 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
mScene->mNumMaterials = m3d->nummaterial + 1;
mScene->mMaterials = new aiMaterial *[mScene->mNumMaterials];
ASSIMP_LOG_DEBUG_F("M3D: importMaterials ", mScene->mNumMaterials);
ASSIMP_LOG_DEBUG("M3D: importMaterials ", mScene->mNumMaterials);
// add a default material as first
aiMaterial *mat = new aiMaterial;
@ -335,7 +325,7 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) {
ai_assert(m3d);
mScene->mNumTextures = m3d->numtexture;
ASSIMP_LOG_DEBUG_F("M3D: importTextures ", mScene->mNumTextures);
ASSIMP_LOG_DEBUG("M3D: importTextures ", mScene->mNumTextures);
if (!m3d->numtexture || !m3d->texture) {
return;
@ -390,7 +380,7 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) {
// individually. In assimp there're per mesh vertex and UV lists, and they must be
// indexed simultaneously.
void M3DImporter::importMeshes(const M3DWrapper &m3d) {
ASSIMP_LOG_DEBUG_F("M3D: importMeshes ", m3d->numface);
ASSIMP_LOG_DEBUG("M3D: importMeshes ", m3d->numface);
if (!m3d->numface || !m3d->face || !m3d->numvertex || !m3d->vertex) {
return;
@ -509,7 +499,7 @@ void M3DImporter::importBones(const M3DWrapper &m3d, unsigned int parentid, aiNo
ai_assert(mScene != nullptr);
ai_assert(m3d);
ASSIMP_LOG_DEBUG_F("M3D: importBones ", m3d->numbone, " parentid ", (int)parentid);
ASSIMP_LOG_DEBUG("M3D: importBones ", m3d->numbone, " parentid ", (int)parentid);
if (!m3d->numbone || !m3d->bone) {
return;
@ -550,7 +540,7 @@ void M3DImporter::importAnimations(const M3DWrapper &m3d) {
mScene->mNumAnimations = m3d->numaction;
ASSIMP_LOG_DEBUG_F("M3D: importAnimations ", mScene->mNumAnimations);
ASSIMP_LOG_DEBUG("M3D: importAnimations ", mScene->mNumAnimations);
if (!m3d->numaction || !m3d->action || !m3d->numbone || !m3d->bone || !m3d->vertex) {
return;
@ -665,7 +655,7 @@ void M3DImporter::convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned in
// ------------------------------------------------------------------------------------------------
// find a node by name
aiNode *M3DImporter::findNode(aiNode *pNode, aiString name) {
aiNode *M3DImporter::findNode(aiNode *pNode, const aiString &name) {
ai_assert(pNode != nullptr);
ai_assert(mScene != nullptr);
@ -713,7 +703,7 @@ void M3DImporter::populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector
ai_assert(vertexids != nullptr);
ai_assert(m3d);
ASSIMP_LOG_DEBUG_F("M3D: populateMesh numvertices ", vertices->size(), " numfaces ", faces->size(),
ASSIMP_LOG_DEBUG("M3D: populateMesh numvertices ", vertices->size(), " numfaces ", faces->size(),
" numnormals ", normals->size(), " numtexcoord ", texcoords->size(), " numbones ", m3d->numbone);
if (vertices->size() && faces->size()) {

View File

@ -89,8 +89,8 @@ private:
// helper functions
aiColor4D mkColor(uint32_t c);
void convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned int posid, unsigned int orientid);
aiNode *findNode(aiNode *pNode, aiString name);
void calculateOffsetMatrix(aiNode *pNode, aiMatrix4x4 *m);
aiNode *findNode(aiNode *pNode, const aiString &name);
void calculateOffsetMatrix(aiNode *pNode, aiMatrix4x4 *m);
void populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector<aiFace> *faces, std::vector<aiVector3D> *verteces,
std::vector<aiVector3D> *normals, std::vector<aiVector3D> *texcoords, std::vector<aiColor4D> *colors,
std::vector<unsigned int> *vertexids);

View File

@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef AI_M3DWRAPPER_H_INC
#define AI_M3DWRAPPER_H_INC
#if !(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER) || !ASSIMP_BUILD_NO_M3D_IMPORTER
#include <memory>
@ -54,46 +55,76 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Assimp specific M3D configuration. Comment out these defines to remove functionality
//#define ASSIMP_USE_M3D_READFILECB
//#define M3D_ASCII
// Share stb_image's PNG loader with other importers/exporters instead of bringing our own copy.
#define STBI_ONLY_PNG
#include <stb/stb_image.h>
#include "m3d.h"
namespace Assimp {
class IOSystem;
/// brief The M3D-Wrapper, provudes c++ access to the data.
class M3DWrapper {
m3d_t *m3d_ = nullptr;
unsigned char *saved_output_ = nullptr;
public:
// Construct an empty M3D model
/// Construct an empty M3D model
explicit M3DWrapper();
// Construct an M3D model from provided buffer
// NOTE: The m3d.h SDK function does not mark the data as const. Have assumed it does not write.
// BUG: SECURITY: The m3d.h SDK cannot be informed of the buffer size. BUFFER OVERFLOW IS CERTAIN
/// Construct an M3D model from provided buffer
/// @note The m3d.h SDK function does not mark the data as const. Have assumed it does not write.
/// BUG: SECURITY: The m3d.h SDK cannot be informed of the buffer size. BUFFER OVERFLOW IS CERTAIN
explicit M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer);
~M3DWrapper();
/// Theclasss destructor.
~M3DWrapper();
void reset();
/// Will reset the wrapper, all data will become nullptr.
void reset();
// Name
inline std::string Name() const {
if (m3d_) return std::string(m3d_->name);
return std::string();
}
// The Name access, empty string returned when no m3d instance.
std::string Name() const;
// Execute a save
/// Executes a save.
unsigned char *Save(int quality, int flags, unsigned int &size);
/// Clearer
void ClearSave();
inline explicit operator bool() const { return m3d_ != nullptr; }
/// True for m3d instance exists.
explicit operator bool() const;
// Allow direct access to M3D API
inline m3d_t *operator->() const { return m3d_; }
inline m3d_t *M3D() const { return m3d_; }
m3d_t *operator->() const;
m3d_t *M3D() const;
private:
m3d_t *m3d_ = nullptr;
unsigned char *saved_output_ = nullptr;
};
inline std::string M3DWrapper::Name() const {
if (nullptr != m3d_) {
if (nullptr != m3d_->name) {
return std::string(m3d_->name);
}
}
return std::string();
}
inline M3DWrapper::operator bool() const {
return m3d_ != nullptr;
}
inline m3d_t *M3DWrapper::operator->() const {
return m3d_;
}
inline m3d_t *M3DWrapper::M3D() const {
return m3d_;
}
} // namespace Assimp
#endif

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/StringUtils.h>
#include <memory>
@ -148,46 +149,39 @@ void MD2Importer::ValidateHeader( )
if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
{
char szBuffer[5];
szBuffer[0] = ((char*)&m_pcHeader->magic)[0];
szBuffer[1] = ((char*)&m_pcHeader->magic)[1];
szBuffer[2] = ((char*)&m_pcHeader->magic)[2];
szBuffer[3] = ((char*)&m_pcHeader->magic)[3];
szBuffer[4] = '\0';
throw DeadlyImportError("Invalid MD2 magic word: should be IDP2, the "
"magic word found is " + std::string(szBuffer));
throw DeadlyImportError("Invalid MD2 magic word: expected IDP2, found ",
ai_str_toprintable((char *)&m_pcHeader->magic, 4));
}
// check file format version
if (m_pcHeader->version != 8)
ASSIMP_LOG_WARN( "Unsupported md2 file version. Continuing happily ...");
ASSIMP_LOG_WARN( "Unsupported MD2 file version. Continuing happily ...");
// check some values whether they are valid
if (0 == m_pcHeader->numFrames)
throw DeadlyImportError( "Invalid md2 file: NUM_FRAMES is 0");
throw DeadlyImportError( "Invalid MD2 file: NUM_FRAMES is 0");
if (m_pcHeader->offsetEnd > (uint32_t)fileSize)
throw DeadlyImportError( "Invalid md2 file: File is too small");
throw DeadlyImportError( "Invalid MD2 file: File is too small");
if (m_pcHeader->numSkins > AI_MAX_ALLOC(MD2::Skin)) {
throw DeadlyImportError("Invalid MD2 header: too many skins, would overflow");
throw DeadlyImportError("Invalid MD2 header: Too many skins, would overflow");
}
if (m_pcHeader->numVertices > AI_MAX_ALLOC(MD2::Vertex)) {
throw DeadlyImportError("Invalid MD2 header: too many vertices, would overflow");
throw DeadlyImportError("Invalid MD2 header: Too many vertices, would overflow");
}
if (m_pcHeader->numTexCoords > AI_MAX_ALLOC(MD2::TexCoord)) {
throw DeadlyImportError("Invalid MD2 header: too many texcoords, would overflow");
throw DeadlyImportError("Invalid MD2 header: Too many texcoords, would overflow");
}
if (m_pcHeader->numTriangles > AI_MAX_ALLOC(MD2::Triangle)) {
throw DeadlyImportError("Invalid MD2 header: too many triangles, would overflow");
throw DeadlyImportError("Invalid MD2 header: Too many triangles, would overflow");
}
if (m_pcHeader->numFrames > AI_MAX_ALLOC(MD2::Frame)) {
throw DeadlyImportError("Invalid MD2 header: too many frames, would overflow");
throw DeadlyImportError("Invalid MD2 header: Too many frames, would overflow");
}
// -1 because Frame already contains one
@ -199,7 +193,7 @@ void MD2Importer::ValidateHeader( )
m_pcHeader->offsetFrames + m_pcHeader->numFrames * frameSize >= fileSize ||
m_pcHeader->offsetEnd > fileSize)
{
throw DeadlyImportError("Invalid MD2 header: some offsets are outside the file");
throw DeadlyImportError("Invalid MD2 header: Some offsets are outside the file");
}
if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
@ -210,7 +204,7 @@ void MD2Importer::ValidateHeader( )
ASSIMP_LOG_WARN("The model contains more vertices than Quake 2 supports");
if (m_pcHeader->numFrames <= configFrameID )
throw DeadlyImportError("The requested frame is not existing the file");
throw DeadlyImportError("MD2: The requested frame (", configFrameID, ") does not exist in the file");
}
// ------------------------------------------------------------------------------------------------
@ -433,10 +427,6 @@ void MD2Importer::InternReadFile( const std::string& pFile,
aiVector3D& vNormal = pcMesh->mNormals[iCurrent];
LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal);
// flip z and y to become right-handed
std::swap((float&)vNormal.z,(float&)vNormal.y);
std::swap((float&)vec.z,(float&)vec.y);
if (m_pcHeader->numTexCoords) {
// validate texture coordinates
iIndex = pcTriangles[i].textureIndices[c];
@ -454,7 +444,15 @@ void MD2Importer::InternReadFile( const std::string& pFile,
}
pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent;
}
// flip the face order
std::swap( pScene->mMeshes[0]->mFaces[i].mIndices[0], pScene->mMeshes[0]->mFaces[i].mIndices[2] );
}
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(
1.f, 0.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, -1.f, 0.f, 0.f,
0.f, 0.f, 0.f, 1.f);
}
#endif // !! ASSIMP_BUILD_NO_MD2_IMPORTER

View File

@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_MDL_NORMALTABLE_H_INC
float g_avNormals[162][3] = {
const float g_avNormals[162][3] = {
{ -0.525731f, 0.000000f, 0.850651f },
{ -0.442863f, 0.238856f, 0.864188f },
{ -0.295242f, 0.000000f, 0.955423f },

View File

@ -101,7 +101,7 @@ Q3Shader::BlendFunc StringToBlendFunc(const std::string &m) {
if (m == "GL_ONE_MINUS_DST_COLOR") {
return Q3Shader::BLEND_GL_ONE_MINUS_DST_COLOR;
}
ASSIMP_LOG_ERROR("Q3Shader: Unknown blend function: " + m);
ASSIMP_LOG_ERROR("Q3Shader: Unknown blend function: ", m);
return Q3Shader::BLEND_NONE;
}
@ -112,7 +112,7 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
if (!file.get())
return false; // if we can't access the file, don't worry and return
ASSIMP_LOG_INFO_F("Loading Quake3 shader file ", pFile);
ASSIMP_LOG_INFO("Loading Quake3 shader file ", pFile);
// read file in memory
const size_t s = file->FileSize();
@ -196,11 +196,11 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
// 'cull' specifies culling behaviour for the model
else if (TokenMatchI(buff, "cull", 4)) {
SkipSpaces(&buff);
if (!ASSIMP_strincmp(buff, "back", 4)) {
if (!ASSIMP_strincmp(buff, "back", 4)) { // render face's backside, does not function in Q3 engine (bug)
curData->cull = Q3Shader::CULL_CCW;
} else if (!ASSIMP_strincmp(buff, "front", 5)) {
} else if (!ASSIMP_strincmp(buff, "front", 5)) { // is not valid keyword in Q3, but occurs in shaders
curData->cull = Q3Shader::CULL_CW;
} else if (!ASSIMP_strincmp(buff, "none", 4) || !ASSIMP_strincmp(buff, "disable", 7)) {
} else if (!ASSIMP_strincmp(buff, "none", 4) || !ASSIMP_strincmp(buff, "twosided", 8) || !ASSIMP_strincmp(buff, "disable", 7)) {
curData->cull = Q3Shader::CULL_NONE;
} else {
ASSIMP_LOG_ERROR("Q3Shader: Unrecognized cull mode");
@ -226,7 +226,7 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
if (!file.get())
return false; // if we can't access the file, don't worry and return
ASSIMP_LOG_INFO("Loading Quake3 skin file " + pFile);
ASSIMP_LOG_INFO("Loading Quake3 skin file ", pFile);
// read file in memory
const size_t s = file->FileSize();
@ -450,6 +450,9 @@ void MD3Importer::SetupProperties(const Importer *pImp) {
// AI_CONFIG_IMPORT_MD3_SKIN_NAME
configSkinFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SKIN_NAME, "default"));
// AI_CONFIG_IMPORT_MD3_LOAD_SHADERS
configLoadShaders = (pImp->GetPropertyBool(AI_CONFIG_IMPORT_MD3_LOAD_SHADERS, true));
// AI_CONFIG_IMPORT_MD3_SHADER_SRC
configShaderFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SHADER_SRC, ""));
@ -483,8 +486,9 @@ void MD3Importer::ReadShader(Q3Shader::ShaderData &fill) const {
// If no specific dir or file is given, use our default search behaviour
if (!configShaderFile.length()) {
if (!Q3Shader::LoadShader(fill, path + "..\\..\\..\\scripts\\" + model_file + ".shader", mIOHandler)) {
Q3Shader::LoadShader(fill, path + "..\\..\\..\\scripts\\" + filename + ".shader", mIOHandler);
const char sep = mIOHandler->getOsSeparator();
if (!Q3Shader::LoadShader(fill, path + ".." + sep + ".." + sep + ".." + sep + "scripts" + sep + model_file + ".shader", mIOHandler)) {
Q3Shader::LoadShader(fill, path + ".." + sep + ".." + sep + ".." + sep + "scripts" + sep + filename + ".shader", mIOHandler);
}
} else {
// If the given string specifies a file, load this file.
@ -702,7 +706,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
filename = mFile.substr(s), path = mFile.substr(0, s);
for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) {
*it = static_cast<char>(tolower(*it));
*it = static_cast<char>(tolower(static_cast<unsigned char>(*it)));
}
// Load multi-part model file, if necessary
@ -780,7 +784,9 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// And check whether we can locate a shader file for this model
Q3Shader::ShaderData shaders;
ReadShader(shaders);
if (configLoadShaders){
ReadShader(shaders);
}
// Adjust all texture paths in the shader
const char *header_name = pcHeader->NAME;
@ -851,7 +857,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (it != skins.textures.end()) {
texture_name = &*(_texture_name = (*it).second).begin();
ASSIMP_LOG_VERBOSE_DEBUG_F("MD3: Assigning skin texture ", (*it).second, " to surface ", pcSurfaces->NAME);
ASSIMP_LOG_VERBOSE_DEBUG("MD3: Assigning skin texture ", (*it).second, " to surface ", pcSurfaces->NAME);
(*it).resolved = true; // mark entry as resolved
}
@ -862,7 +868,12 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
std::string convertedPath;
if (texture_name) {
ConvertPath(texture_name, header_name, convertedPath);
if (configLoadShaders){
ConvertPath(texture_name, header_name, convertedPath);
}
else{
convertedPath = texture_name;
}
}
const Q3Shader::ShaderDataBlock *shader = nullptr;
@ -880,9 +891,9 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (dit != shaders.blocks.end()) {
// We made it!
shader = &*dit;
ASSIMP_LOG_INFO("Found shader record for " + without_ext);
ASSIMP_LOG_INFO("Found shader record for ", without_ext);
} else {
ASSIMP_LOG_WARN("Unable to find shader record for " + without_ext);
ASSIMP_LOG_WARN("Unable to find shader record for ", without_ext);
}
}
@ -985,8 +996,8 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[index].U;
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - pcUVs[index].V;
}
// Flip face order if necessary
if (!shader || shader->cull == Q3Shader::CULL_CW) {
// Flip face order normally, unless shader is backfacing
if (!(shader && shader->cull == Q3Shader::CULL_CCW)) {
std::swap(pcMesh->mFaces[i].mIndices[2], pcMesh->mFaces[i].mIndices[1]);
}
++pcTriangles;
@ -1000,7 +1011,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (!DefaultLogger::isNullLogger()) {
for (std::list<Q3Shader::SkinData::TextureEntry>::const_iterator it = skins.textures.begin(); it != skins.textures.end(); ++it) {
if (!(*it).resolved) {
ASSIMP_LOG_ERROR_F("MD3: Failed to match skin ", (*it).first, " to surface ", (*it).second);
ASSIMP_LOG_ERROR("MD3: Failed to match skin ", (*it).first, " to surface ", (*it).second);
}
}
}

View File

@ -297,6 +297,9 @@ protected:
/** Configuration option: name of skin file to be read */
std::string configSkinFile;
/** Configuration option: whether to load shaders */
bool configLoadShaders;
/** Configuration option: name or path of shader */
std::string configShaderFile;

View File

@ -345,7 +345,7 @@ void MD5Importer::LoadMD5MeshFile() {
// Check whether we can read from the file
if (file.get() == nullptr || !file->FileSize()) {
ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + filename);
ASSIMP_LOG_WARN("Failed to access MD5MESH file: ", filename);
return;
}
mHadMD5Mesh = true;
@ -567,7 +567,7 @@ void MD5Importer::LoadMD5AnimFile() {
// Check whether we can read from the file
if (!file.get() || !file->FileSize()) {
ASSIMP_LOG_WARN("Failed to read MD5ANIM file: " + pFile);
ASSIMP_LOG_WARN("Failed to read MD5ANIM file: ", pFile);
return;
}

View File

@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp>
#include <assimp/StringUtils.h>
#include <memory>
@ -143,16 +144,8 @@ void MDCImporter::ValidateHeader() {
if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE) {
char szBuffer[5];
szBuffer[0] = ((char *)&pcHeader->ulIdent)[0];
szBuffer[1] = ((char *)&pcHeader->ulIdent)[1];
szBuffer[2] = ((char *)&pcHeader->ulIdent)[2];
szBuffer[3] = ((char *)&pcHeader->ulIdent)[3];
szBuffer[4] = '\0';
throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
"magic word found is " +
std::string(szBuffer));
throw DeadlyImportError("Invalid MDC magic word: expected IDPC, found ",
ai_str_toprintable((char *)&pcHeader->ulIdent, 4));
}
if (pcHeader->ulVersion != AI_MDC_VERSION) {
@ -250,7 +243,7 @@ void MDCImporter::InternReadFile(
// get the number of valid surfaces
BE_NCONST MDC::Surface *pcSurface, *pcSurface2;
pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface;
pcSurface = pcSurface2 = reinterpret_cast<BE_NCONST MDC::Surface *>(mBuffer + pcHeader->ulOffsetSurfaces);
unsigned int iNumShaders = 0;
for (unsigned int i = 0; i < pcHeader->ulNumSurfaces; ++i) {
// validate the surface header
@ -260,7 +253,7 @@ void MDCImporter::InternReadFile(
++pScene->mNumMeshes;
}
iNumShaders += pcSurface2->ulNumShaders;
pcSurface2 = new ((int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface;
pcSurface2 = reinterpret_cast<BE_NCONST MDC::Surface *>((BE_NCONST int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd);
}
aszShaders.reserve(iNumShaders);
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
@ -405,7 +398,7 @@ void MDCImporter::InternReadFile(
pcFaceCur->mIndices[2] = iOutIndex + 0;
}
pcSurface = new ((int8_t *)pcSurface + pcSurface->ulOffsetEnd) MDC::Surface;
pcSurface = reinterpret_cast<BE_NCONST MDC::Surface *>((BE_NCONST int8_t *)pcSurface + pcSurface->ulOffsetEnd);
}
// create a flat node graph with a root node and one child for each surface
@ -465,6 +458,13 @@ void MDCImporter::InternReadFile(
pcMat->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
}
}
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(
1.f, 0.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, -1.f, 0.f, 0.f,
0.f, 0.f, 0.f, 1.f);
}
#endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER

View File

@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define MDC_NORMAL_TABLE_INCLUDED
/* mdc decoding normal table */
float mdcNormals[ 256 ][ 3 ] =
const float mdcNormals[ 256 ][ 3 ] =
{
{ 1.000000f, 0.000000f, 0.000000f },
{ 0.980785f, 0.195090f, 0.000000f },

View File

@ -57,6 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iomanip>
#include <sstream>
#include <map>
#ifdef MDL_HALFLIFE_LOG_WARN_HEADER
#undef MDL_HALFLIFE_LOG_WARN_HEADER
@ -868,7 +869,7 @@ void HL1MDLLoader::read_meshes() {
scene_mesh->mNormals[v] = bind_pose_normals[pTrivert->normindex];
scene_mesh->mTextureCoords[0][v] = aiVector3D(
pTrivert->s * texcoords_s_scale,
pTrivert->t * texcoords_t_scale, 0);
pTrivert->t * -texcoords_t_scale, 0);
}
// Add face and indices.
@ -879,9 +880,9 @@ void HL1MDLLoader::read_meshes() {
aiFace *face = &scene_mesh->mFaces[f];
face->mNumIndices = 3;
face->mIndices = new unsigned int[3];
face->mIndices[0] = mesh_faces[f].v0;
face->mIndices[0] = mesh_faces[f].v2;
face->mIndices[1] = mesh_faces[f].v1;
face->mIndices[2] = mesh_faces[f].v2;
face->mIndices[2] = mesh_faces[f].v0;
}
// Add mesh bones.
@ -1342,7 +1343,7 @@ bool HL1MDLLoader::get_num_blend_controllers(const int num_blend_animations, int
return true;
default:
num_blend_controllers = 0;
ASSIMP_LOG_WARN(MDL_HALFLIFE_LOG_HEADER "Unsupported number of blend animations (" + std::to_string(num_blend_animations) + ")");
ASSIMP_LOG_WARN(MDL_HALFLIFE_LOG_HEADER "Unsupported number of blend animations (", num_blend_animations, ")");
return false;
}
}

View File

@ -95,7 +95,7 @@ void UniqueNameGenerator::make_unique(std::vector<std::string> &names) {
auto generate_unique_name = [&](const std::string &base_name) -> std::string {
auto *duplicate_info = &names_to_duplicates[base_name];
std::string new_name = "";
std::string new_name;
bool found_identical_name;
bool tried_with_base_name_only = false;

View File

@ -199,6 +199,7 @@ void MDLImporter::InternReadFile(const std::string &pFile,
const uint32_t iMagicWord = *((uint32_t *)mBuffer);
// Determine the file subtype and call the appropriate member function
bool is_half_life = false;
// Original Quake1 format
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) {
@ -240,6 +241,7 @@ void MDLImporter::InternReadFile(const std::string &pFile,
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) {
iGSFileVersion = 0;
is_half_life = true;
HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer;
if (pHeader->version == AI_MDL_HL1_VERSION) {
@ -252,12 +254,22 @@ void MDLImporter::InternReadFile(const std::string &pFile,
} else {
// print the magic word to the log file
throw DeadlyImportError("Unknown MDL subformat ", pFile,
". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known");
". Magic word (", ai_str_toprintable((const char *)&iMagicWord, sizeof(iMagicWord)), ") is not known");
}
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
if (is_half_life){
// Now rotate the whole scene 90 degrees around the z and x axes to convert to internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(
0.f, -1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
-1.f, 0.f, 0.f, 0.f,
0.f, 0.f, 0.f, 1.f);
}
else {
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
}
DeleteBufferAndCleanup();
} catch (...) {

View File

@ -75,7 +75,7 @@ using namespace std;
// Default constructor
MMDImporter::MMDImporter() :
m_Buffer(),
m_strAbsPath("") {
m_strAbsPath() {
DefaultIOSystem io;
m_strAbsPath = io.getOsSeparator();
}

View File

@ -91,7 +91,7 @@ namespace pmx
std::vector<char> buffer;
if (size == 0)
{
return std::string("");
return std::string();
}
buffer.reserve(size);
stream->read((char*) buffer.data(), size);
@ -478,8 +478,7 @@ namespace pmx
void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
{
std::cerr << "Not Implemented Exception" << std::endl;
throw DeadlyImportError("MMD: Not Implemented Exception");
throw DeadlyImportError("MMD: Soft Body support is not implemented.");
}
void PmxModel::Init()
@ -516,15 +515,13 @@ namespace pmx
char magic[4];
stream->read((char*) magic, sizeof(char) * 4);
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
{
std::cerr << "invalid magic number." << std::endl;
throw DeadlyImportError("MMD: invalid magic number.");
{
throw DeadlyImportError("MMD: Invalid magic number.");
}
stream->read((char*) &version, sizeof(float));
if (version != 2.0f && version != 2.1f)
{
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but ", ai_to_string(version));
throw DeadlyImportError("MMD: Unsupported version (must be 2.0 or 2.1): ", ai_to_string(version));
}
this->setting.Read(stream);

View File

@ -215,7 +215,12 @@ void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints, ai
void MS3DImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
auto file = pIOHandler->Open(pFile, "rb");
if (!file)
throw DeadlyImportError("MS3D: Could not open ", pFile);
StreamReaderLE stream(file);
// CanRead() should have done this already
char head[10];
@ -382,7 +387,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
}
const std::string& s = std::string(reinterpret_cast<char*>(stream.GetPtr()),len);
ASSIMP_LOG_DEBUG_F("MS3D: Model comment: ", s);
ASSIMP_LOG_DEBUG("MS3D: Model comment: ", s);
}
if(stream.GetRemainingSize() > 4 && inrange((stream >> subversion,subversion),1u,3u)) {
@ -500,7 +505,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
}
TempTriangle& t = triangles[g.triangles[i]];
TempTriangle& t = triangles[g.triangles[j]];
f.mIndices = new unsigned int[f.mNumIndices=3];
for (unsigned int k = 0; k < 3; ++k,++n) {
@ -508,7 +513,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
}
const TempVertex& v = vertices[t.indices[i]];
const TempVertex& v = vertices[t.indices[k]];
for(unsigned int a = 0; a < 4; ++a) {
if (v.bone_id[a] != UINT_MAX) {
if (v.bone_id[a] >= joints.size()) {
@ -524,9 +529,9 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
// collect vertex components
m->mVertices[n] = v.pos;
m->mNormals[n] = t.normals[i];
m->mTextureCoords[0][n] = aiVector3D(t.uv[i].x,1.f-t.uv[i].y,0.0);
f.mIndices[i] = n;
m->mNormals[n] = t.normals[k];
m->mTextureCoords[0][n] = aiVector3D(t.uv[k].x,1.f-t.uv[k].y,0.0);
f.mIndices[k] = n;
}
}

View File

@ -116,7 +116,13 @@ void NDOImporter::SetupProperties(const Importer* /*pImp*/)
void NDOImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
StreamReaderBE reader(pIOHandler->Open( pFile, "rb"));
auto file = pIOHandler->Open( pFile, "rb");
if (!file) {
throw DeadlyImportError("Nendo: Could not open ", pFile);
}
StreamReaderBE reader(file);
// first 9 bytes are nendo file format ("nendo 1.n")
const char* head = (const char*)reader.GetPtr();
@ -141,7 +147,7 @@ void NDOImporter::InternReadFile( const std::string& pFile,
ASSIMP_LOG_INFO("NDO file format is 1.2");
}
else {
ASSIMP_LOG_WARN_F( "Unrecognized nendo file format version, continuing happily ... :", (head+6));
ASSIMP_LOG_WARN( "Unrecognized nendo file format version, continuing happily ... :", (head+6));
}
reader.IncPtr(2); /* skip flags */

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