Merge branch 'master' into jdumas/ziplib

pull/4173/head
Jérémie Dumas 2021-11-12 10:13:21 -08:00 committed by GitHub
commit 57d22e4dbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
470 changed files with 16962 additions and 16048 deletions

1
.github/FUNDING.yml vendored
View File

@ -1 +1,2 @@
open_collective: assimp
patreon: 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.

3
.gitignore vendored
View File

@ -25,7 +25,7 @@ CMakeSettings.json
# Output
bin/
lib/
x64/
# QtCreator
CMakeLists.txt.user
@ -94,6 +94,7 @@ test/gtest/src/gtest-stamp/gtest-gitinfo.txt
test/gtest/src/gtest-stamp/gtest-gitclone-lastrun.txt
Assimp.opensdf
contrib/zlib/CTestTestfile.cmake
contrib/zlib/Debug/zlibstaticd.pdb
ipch/assimp_viewer-44bbbcd1/assimp_viewerd-ccc45335.ipch
bin64/assimp-vc140-mt.dll
bin64/assimp-vc140-mtd.dll

View File

@ -44,16 +44,16 @@ CMAKE_MINIMUM_REQUIRED( VERSION 3.10 )
option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
IF(ASSIMP_HUNTER_ENABLED)
include("cmake/HunterGate.cmake")
include("cmake-modules/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)
ENDIF()
PROJECT( Assimp VERSION 5.0.1 )
PROJECT(Assimp VERSION 5.1.0)
# All supported options ###############################################
@ -135,11 +135,11 @@ IF ( WIN32 )
# Use subset of Windows.h
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
IF(MSVC)
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW
"If the Assimp view tool is built. (requires DirectX)"
OFF )
IF(MSVC)
OPTION( ASSIMP_INSTALL_PDB
"Install MSVC debug files."
ON )
@ -267,7 +267,10 @@ ELSEIF(MSVC)
IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351)
ENDIF()
ADD_COMPILE_OPTIONS(/wd4244) #supress warning for double to float conversion if Double precission is activated
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 +337,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.
@ -395,14 +398,14 @@ set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
IF(ASSIMP_HUNTER_ENABLED)
set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
set(CMAKE_CONFIG_TEMPLATE_FILE "cmake/assimp-hunter-config.cmake.in")
set(CMAKE_CONFIG_TEMPLATE_FILE "cmake-modules/assimp-hunter-config.cmake.in")
set(NAMESPACE "${PROJECT_NAME}::")
set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
ELSE()
set(CONFIG_INSTALL_DIR "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
set(CMAKE_CONFIG_TEMPLATE_FILE "cmake/assimp-plain-config.cmake.in")
set(CMAKE_CONFIG_TEMPLATE_FILE "cmake-modules/assimp-plain-config.cmake.in")
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE)
set(NAMESPACE "${PROJECT_NAME_LOWERCASE}::")
set(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWERCASE}Targets")

View File

@ -42,7 +42,9 @@ Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file.
* [.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)
* [Javascript/Node.js Interface](https://github.com/kovacsv/assimpjs)
* [Unity 3d Plugin](https://ricardoreis.net/trilib-2/)
* [Unreal Engine Plugin](https://github.com/irajsb/UE4_Assimp/)
* [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)

View File

@ -1,17 +0,0 @@
# Find IrrXMl from irrlicht project
#
# Find LibIrrXML headers and library
#
# IRRXML_FOUND - IrrXML found
# IRRXML_INCLUDE_DIR - Headers location
# IRRXML_LIBRARY - IrrXML main library
find_path(IRRXML_INCLUDE_DIR irrXML.h
PATH_SUFFIXES include/irrlicht include/irrxml)
find_library(IRRXML_LIBRARY IrrXML)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(IrrXML REQUIRED_VARS IRRXML_INCLUDE_DIR IRRXML_LIBRARY)
mark_as_advanced(IRRXML_INCLUDE_DIR IRRXML_LIBRARY)

View File

@ -0,0 +1,19 @@
@PACKAGE_INIT@
find_package(RapidJSON CONFIG REQUIRED)
find_package(ZLIB CONFIG REQUIRED)
find_package(utf8cpp CONFIG REQUIRED)
find_package(minizip CONFIG REQUIRED)
find_package(openddlparser CONFIG REQUIRED)
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)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
check_required_components("@PROJECT_NAME@")

View File

@ -1,18 +0,0 @@
@PACKAGE_INIT@
find_package(RapidJSON CONFIG REQUIRED)
find_package(ZLIB CONFIG REQUIRED)
find_package(utf8cpp CONFIG REQUIRED)
find_package(minizip CONFIG REQUIRED)
find_package(openddlparser CONFIG REQUIRED)
find_package(poly2tri CONFIG REQUIRED)
find_package(polyclipping CONFIG REQUIRED)
find_package(zip CONFIG REQUIRED)
find_package(pugixml CONFIG REQUIRED)
if(@ASSIMP_BUILD_DRACO@)
find_package(draco CONFIG REQUIRED)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
check_required_components("@PROJECT_NAME@")

View File

@ -68,8 +68,8 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
unsigned int idx(NotSet);
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(static_cast<unsigned char>(*it)));
for (char & it : s) {
it = static_cast<char>(::tolower(static_cast<unsigned char>(it)));
}
if (std::string::npos == s.find("default")) continue;
@ -79,12 +79,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
mScene->mMaterials[i].mDiffuse.r !=
mScene->mMaterials[i].mDiffuse.b) continue;
if (mScene->mMaterials[i].sTexDiffuse.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexBump.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexOpacity.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexEmissive.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexSpecular.mMapName.length() != 0 ||
mScene->mMaterials[i].sTexShininess.mMapName.length() != 0) {
if (ContainsTextures(i)) {
continue;
}
idx = i;

View File

@ -56,8 +56,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory>
using namespace Assimp;
namespace Assimp {
using namespace D3DS;
namespace {
@ -330,6 +330,7 @@ void Discreet3DSExporter::WriteMaterials() {
case aiShadingMode_Blinn:
case aiShadingMode_CookTorrance:
case aiShadingMode_Fresnel:
case aiShadingMode_PBR_BRDF: // Possibly should be Discreet3DS::Metal in some cases but this is undocumented
shading_mode_out = Discreet3DS::Phong;
break;
@ -356,7 +357,10 @@ void Discreet3DSExporter::WriteMaterials() {
writer.PutI2(1);
}
WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE);
// Fallback to BASE_COLOR if no DIFFUSE
if (!WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE))
WriteTexture(mat, aiTextureType_BASE_COLOR, Discreet3DS::CHUNK_MAT_TEXTURE);
WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP);
WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP);
WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP);
@ -367,20 +371,21 @@ void Discreet3DSExporter::WriteMaterials() {
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type, uint16_t chunk_flags) {
// returns true if the texture existed
bool Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type, uint16_t chunk_flags) {
aiString path;
aiTextureMapMode map_mode[2] = {
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
};
ai_real blend = 1.0;
if (mat.GetTexture(type, 0, &path, nullptr, nullptr, &blend, nullptr, map_mode) != AI_SUCCESS || !path.length) {
return;
return false;
}
// TODO: handle embedded textures properly
if (path.data[0] == '*') {
ASSIMP_LOG_ERROR("Ignoring embedded texture for export: ", path.C_Str());
return;
return false;
}
ChunkWriter chunk(writer, chunk_flags);
@ -402,6 +407,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type
writer.PutU2(val);
}
// TODO: export texture transformation (i.e. UV offset, scale, rotation)
return true;
}
// ------------------------------------------------------------------------------------------------

View File

@ -73,7 +73,7 @@ public:
private:
void WriteMeshes();
void WriteMaterials();
void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags);
bool WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags);
void WriteFaceMaterialChunk(const aiMesh& mesh);
int WriteHierarchy(const aiNode& node, int level, int sibling_level);
void WriteString(const std::string& s);

View File

@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/light.h>
#include <assimp/material.h>
#include <assimp/qnan.h>
#include <stdio.h> //sprintf
#include <cstdio> //sprintf
namespace Assimp {
namespace D3DS {
@ -259,7 +259,7 @@ namespace Discreet3DS {
// Specifies the file name of a texture
CHUNK_MAPFILE = 0xA300,
// Specifies whether a materail requires two-sided rendering
// Specifies whether a material requires two-sided rendering
CHUNK_MAT_TWO_SIDE = 0xA081,
// ********************************************************************
@ -348,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
}
@ -366,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;
}
@ -461,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)),
@ -475,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
}
@ -488,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);
@ -502,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

@ -449,7 +449,7 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
// Read the lense angle
camera->mHorizontalFOV = AI_DEG_TO_RAD(stream->GetF4());
if (camera->mHorizontalFOV < 0.001f) {
camera->mHorizontalFOV = AI_DEG_TO_RAD(45.f);
camera->mHorizontalFOV = float(AI_DEG_TO_RAD(45.f));
}
// Now check for further subchunks

View File

@ -46,11 +46,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef AI_3DSIMPORTER_H_INC
#define AI_3DSIMPORTER_H_INC
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
#include <assimp/BaseImporter.h>
#include <assimp/types.h>
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
#include "3DSHelper.h"
#include <assimp/StreamReader.h>
@ -75,14 +75,14 @@ public:
* See BaseImporter::CanRead() for details.
*/
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool checkSig) const override;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
protected:
@ -90,14 +90,14 @@ protected:
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const;
const aiImporterDesc* GetInfo () const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
IOSystem* pIOHandler) override;
// -------------------------------------------------------------------
/** Converts a temporary material to the outer representation
@ -208,6 +208,15 @@ protected:
*/
void ReplaceDefaultMaterial();
bool ContainsTextures(unsigned int i) const {
return !mScene->mMaterials[i].sTexDiffuse.mMapName.empty() ||
!mScene->mMaterials[i].sTexBump.mMapName.empty() ||
!mScene->mMaterials[i].sTexOpacity.mMapName.empty() ||
!mScene->mMaterials[i].sTexEmissive.mMapName.empty() ||
!mScene->mMaterials[i].sTexSpecular.mMapName.empty() ||
!mScene->mMaterials[i].sTexShininess.mMapName.empty() ;
}
// -------------------------------------------------------------------
/** Convert the whole scene
*/

View File

@ -0,0 +1,165 @@
/*
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.
----------------------------------------------------------------------
*/
#pragma once
#include <assimp/vector3.h>
#include <assimp/matrix4x4.h>
#include <assimp/ParsingUtils.h>
#include <vector>
#include <string>
struct aiMaterial;
struct aiMesh;
namespace Assimp {
namespace D3MF {
enum class ResourceType {
RT_Object,
RT_BaseMaterials,
RT_EmbeddedTexture2D,
RT_Texture2DGroup,
RT_Unknown
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
class Resource {
public:
int mId;
Resource(int id) :
mId(id) {
// empty
}
virtual ~Resource() {
// empty
}
virtual ResourceType getType() const {
return ResourceType::RT_Unknown;
}
};
class EmbeddedTexture : public Resource {
public:
std::string mPath;
std::string mContentType;
std::string mTilestyleU;
std::string mTilestyleV;
std::vector<char> mBuffer;
EmbeddedTexture(int id) :
Resource(id),
mPath(),
mContentType(),
mTilestyleU(),
mTilestyleV() {
// empty
}
~EmbeddedTexture() = default;
ResourceType getType() const override {
return ResourceType::RT_EmbeddedTexture2D;
}
};
class Texture2DGroup : public Resource {
public:
std::vector<aiVector2D> mTex2dCoords;
int mTexId;
Texture2DGroup(int id) :
Resource(id),
mTexId(-1) {
// empty
}
~Texture2DGroup() = default;
ResourceType getType() const override {
return ResourceType::RT_Texture2DGroup;
}
};
class BaseMaterials : public Resource {
public:
std::vector<unsigned int> mMaterialIndex;
BaseMaterials(int id) :
Resource(id),
mMaterialIndex() {
// empty
}
~BaseMaterials() = default;
ResourceType getType() const override {
return ResourceType::RT_BaseMaterials;
}
};
struct Component {
int mObjectId;
aiMatrix4x4 mTransformation;
};
class Object : public Resource {
public:
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)) {
// empty
}
~Object() = default;
ResourceType getType() const override {
return ResourceType::RT_Object;
}
};
} // namespace D3MF
} // namespace Assimp

View File

@ -80,13 +80,21 @@ namespace XmlTag {
const char* const item = "item";
const char* const objectid = "objectid";
const char* const transform = "transform";
const char *const path = "path";
// Material definitions
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";
const char* const texture_2d = "m:texture2d";
const char *const texture_group = "m:texture2dgroup";
const char *const texture_content_type = "contenttype";
const char *const texture_tilestyleu = "tilestyleu";
const char *const texture_tilestylev = "tilestylev";
const char *const texture_2d_coord = "m:tex2coord";
const char *const texture_cuurd_u = "u";
const char *const texture_cuurd_v = "v";
// Meta info tags
const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";

View File

@ -40,6 +40,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
#include <memory>
#include <sstream>
#include <vector>
@ -58,8 +61,6 @@ class IOStream;
namespace D3MF {
#ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
struct OpcPackageRelationship;
@ -100,9 +101,11 @@ private:
std::vector<OpcPackageRelationship*> mRelations;
};
#endif // ASSIMP_BUILD_NO_3MF_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT
} // Namespace D3MF
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_3MF_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT

View File

@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "D3MFImporter.h"
#include "3MFXmlTags.h"
#include "D3MFOpcPackage.h"
#include "XmlSerializer.h"
#include <assimp/StringComparison.h>
#include <assimp/StringUtils.h>
@ -61,513 +62,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
#include <iomanip>
#include <string.h>
#include <cstring>
namespace Assimp {
namespace D3MF {
enum class ResourceType {
RT_Object,
RT_BaseMaterials,
RT_Unknown
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
class Resource {
public:
int mId;
Resource(int id) :
mId(id) {
// empty
}
virtual ~Resource() {
// empty
}
virtual ResourceType getType() const {
return ResourceType::RT_Unknown;
}
};
class BaseMaterials : public Resource {
public:
std::vector<aiMaterial *> mMaterials;
std::vector<unsigned int> mMaterialIndex;
BaseMaterials(int id) :
Resource(id),
mMaterials(),
mMaterialIndex() {
// empty
}
~BaseMaterials() = default;
ResourceType getType() const override {
return ResourceType::RT_BaseMaterials;
}
};
struct Component {
int mObjectId;
aiMatrix4x4 mTransformation;
};
class Object : public Resource {
public:
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)) {
// empty
}
~Object() = default;
ResourceType getType() const override {
return ResourceType::RT_Object;
}
};
class XmlSerializer {
public:
XmlSerializer(XmlParser *xmlParser) :
mResourcesDictionnary(),
mMaterialCount(0),
mMeshCount(0),
mXmlParser(xmlParser) {
// empty
}
~XmlSerializer() {
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it ) {
delete it->second;
}
}
void ImportXml(aiScene *scene) {
if (nullptr == scene) {
return;
}
scene->mRootNode = new aiNode(XmlTag::RootTag);
XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
if (node.empty()) {
return;
}
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 == XmlTag::meta) {
ReadMetadata(currentNode);
}
}
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;
getNodeAttribute(currentNode, D3MF::XmlTag::objectid, objectId);
bool hasTransform = getNodeAttribute(currentNode, D3MF::XmlTag::transform, transformationMatrixStr);
auto it = mResourcesDictionnary.find(objectId);
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
Object *obj = static_cast<Object *>(it->second);
if (hasTransform) {
transformationMatrix = parseTransformMatrix(transformationMatrixStr);
}
addObjectToNode(scene->mRootNode, obj, transformationMatrix);
}
}
}
// import the metadata
if (!mMetaData.empty()) {
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);
scene->mMetaData->Set(static_cast<unsigned int>(i), mMetaData[i].name, val);
}
}
// import the meshes
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) {
if (it->second->getType() == ResourceType::RT_Object) {
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 = mMaterialCount;
if (scene->mNumMaterials != 0) {
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
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) {
scene->mMaterials[baseMaterials->mMaterialIndex[i]] = baseMaterials->mMaterials[i];
}
}
}
}
}
private:
void addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform) {
ai_assert(nullptr != obj);
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;
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);
}
}
}
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;
}
return false;
}
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
std::string strValue;
bool ret = getNodeAttribute(node, attribute, strValue);
if (ret) {
value = std::atoi(strValue.c_str());
return true;
}
return false;
}
aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
// split the string
std::vector<float> numbers;
std::string currentNumber;
for (size_t i = 0; i < matrixStr.size(); ++i) {
const char c = matrixStr[i];
if (c == ' ') {
if (currentNumber.size() > 0) {
float f = std::stof(currentNumber);
numbers.push_back(f);
currentNumber.clear();
}
} else {
currentNumber.push_back(c);
}
}
if (currentNumber.size() > 0) {
const float f = std::stof(currentNumber);
numbers.push_back(f);
}
aiMatrix4x4 transformMatrix;
transformMatrix.a1 = numbers[0];
transformMatrix.b1 = numbers[1];
transformMatrix.c1 = numbers[2];
transformMatrix.d1 = 0;
transformMatrix.a2 = numbers[3];
transformMatrix.b2 = numbers[4];
transformMatrix.c2 = numbers[5];
transformMatrix.d2 = 0;
transformMatrix.a3 = numbers[6];
transformMatrix.b3 = numbers[7];
transformMatrix.c3 = numbers[8];
transformMatrix.d3 = 0;
transformMatrix.a4 = numbers[9];
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, 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.children()) {
const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::mesh) {
auto mesh = ReadMesh(currentNode);
mesh->mName.Set(ai_to_string(id));
if (hasPid) {
auto it = mResourcesDictionnary.find(pid);
if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
}
}
obj->mMeshes.push_back(mesh);
obj->mMeshIndex.push_back(mMeshCount);
mMeshCount++;
} else if (currentName == D3MF::XmlTag::components) {
for (XmlNode &currentSubNode : currentNode.children()) {
const std::string subNodeName = currentSubNode.name();
if (subNodeName == D3MF::XmlTag::component) {
int objectId = -1;
std::string componentTransformStr;
aiMatrix4x4 componentTransform;
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::transform, componentTransformStr)) {
componentTransform = parseTransformMatrix(componentTransformStr);
}
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) {
obj->mComponents.push_back({ objectId, componentTransform });
}
}
}
}
}
mResourcesDictionnary.insert(std::make_pair(id, obj));
}
aiMesh *ReadMesh(XmlNode &node) {
aiMesh *mesh = new aiMesh();
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::vertices) {
ImportVertices(currentNode, mesh);
} else if (currentName == XmlTag::triangles) {
ImportTriangles(currentNode, mesh);
}
}
return mesh;
}
void ReadMetadata(XmlNode &node) {
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()) {
return;
}
MetaEntry entry;
entry.name = name;
entry.value = value;
mMetaData.push_back(entry);
}
void ImportVertices(XmlNode &node, aiMesh *mesh) {
std::vector<aiVector3D> vertices;
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::vertex) {
vertices.push_back(ReadVertex(currentNode));
}
}
mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
}
aiVector3D ReadVertex(XmlNode &node) {
aiVector3D vertex;
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.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::triangle) {
aiFace face = ReadTriangle(currentNode);
faces.push_back(face);
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->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
}
// TODO: manage the separation into several meshes if the triangles of the mesh do not all refer to the same material
}
}
}
}
mesh->mNumFaces = static_cast<unsigned int>(faces.size());
mesh->mFaces = new aiFace[mesh->mNumFaces];
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
std::copy(faces.begin(), faces.end(), mesh->mFaces);
}
aiFace ReadTriangle(XmlNode &node) {
aiFace face;
face.mNumIndices = 3;
face.mIndices = new unsigned int[face.mNumIndices];
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;
}
void ReadBaseMaterials(XmlNode &node) {
int id = -1;
if (getNodeAttribute(node, D3MF::XmlTag::basematerials_id, id)) {
BaseMaterials *baseMaterials = new BaseMaterials(id);
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;
}
}
mResourcesDictionnary.insert(std::make_pair(id, baseMaterials));
}
}
bool parseColor(const char *color, aiColor4D &diffuse) {
if (nullptr == color) {
return false;
}
//format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
const size_t len = strlen(color);
if (9 != len && 7 != len) {
return false;
}
const char *buf(color);
if ('#' != buf[0]) {
return false;
}
char r[3] = { buf[1], buf[2], '\0' };
diffuse.r = static_cast<ai_real>(strtol(r, nullptr, 16)) / ai_real(255.0);
char g[3] = { buf[3], buf[4], '\0' };
diffuse.g = static_cast<ai_real>(strtol(g, nullptr, 16)) / ai_real(255.0);
char b[3] = { buf[5], buf[6], '\0' };
diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
if (7 == len)
return true;
char a[3] = { buf[7], buf[8], '\0' };
diffuse.a = static_cast<ai_real>(strtol(a, nullptr, 16)) / ai_real(255.0);
return true;
}
void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
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);
}
}
aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId) {
aiMaterial *material = new aiMaterial();
material->mNumProperties = 0;
std::string name;
bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
std::string stdMaterialName;
const std::string strId(ai_to_string(basematerialsId));
stdMaterialName += "id";
stdMaterialName += strId;
stdMaterialName += "_";
if (hasName) {
stdMaterialName += std::string(name);
} else {
stdMaterialName += "basemat_";
stdMaterialName += ai_to_string(mMaterialCount - basematerialsId);
}
aiString assimpMaterialName(stdMaterialName);
material->AddProperty(&assimpMaterialName, AI_MATKEY_NAME);
assignDiffuseColor(node, material);
return material;
}
private:
struct MetaEntry {
std::string name;
std::string value;
};
std::vector<MetaEntry> mMetaData;
std::map<unsigned int, Resource *> mResourcesDictionnary;
unsigned int mMaterialCount, mMeshCount;
XmlParser *mXmlParser;
};
} //namespace D3MF
using namespace D3MF;
@ -597,7 +94,9 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo
const std::string extension(GetExtension(filename));
if (extension == desc.mFileExtensions) {
return true;
} else if (!extension.length() || checkSig) {
}
if (!extension.length() || checkSig) {
if (nullptr == pIOHandler) {
return false;
}
@ -611,7 +110,7 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo
return false;
}
void D3MFImporter::SetupProperties(const Importer * /*pImp*/) {
void D3MFImporter::SetupProperties(const Importer*) {
// empty
}
@ -626,6 +125,15 @@ void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene,
if (xmlParser.parse(opcPackage.RootStream())) {
XmlSerializer xmlSerializer(&xmlParser);
xmlSerializer.ImportXml(pScene);
const std::vector<aiTexture*> &tex = opcPackage.GetEmbeddedTextures();
if (!tex.empty()) {
pScene->mNumTextures = static_cast<unsigned int>(tex.size());
pScene->mTextures = new aiTexture *[pScene->mNumTextures];
for (unsigned int i = 0; i < pScene->mNumTextures; ++i) {
pScene->mTextures[i] = tex[i];
}
}
}
}

View File

@ -4,7 +4,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,
@ -43,23 +42,50 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_D3MFLOADER_H_INCLUDED
#define AI_D3MFLOADER_H_INCLUDED
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
#include <assimp/BaseImporter.h>
namespace Assimp {
// ---------------------------------------------------------------------------
/// @brief The 3MF-importer class.
///
/// Implements the basic topology import and embedded textures.
// ---------------------------------------------------------------------------
class D3MFImporter : public BaseImporter {
public:
/// @brief The default class constructor.
D3MFImporter();
~D3MFImporter();
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
void SetupProperties(const Importer *pImp);
const aiImporterDesc *GetInfo() const;
/// @brief The class destructor.
~D3MFImporter() override;
/// @brief Performs the data format detection.
/// @param pFile The filename to check.
/// @param pIOHandler The used IO-System.
/// @param checkSig true for signature checking.
/// @return true for can be loaded, false for not.
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
/// @brief Not used
/// @param pImp Not used
void SetupProperties(const Importer *pImp) override;
/// @brief The importer description getter.
/// @return The info
const aiImporterDesc *GetInfo() const override;
protected:
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
/// @brief Internal read function, performs the file parsing.
/// @param pFile The filename
/// @param pScene The scene to load in.
/// @param pIOHandler The io-system
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
};
} // Namespace Assimp
#endif // #ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
#endif // AI_D3MFLOADER_H_INCLUDED

View File

@ -43,20 +43,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "D3MFOpcPackage.h"
#include <assimp/Exceptional.h>
#include <assimp/XmlParser.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/ai_assert.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/texture.h>
#include "3MFXmlTags.h"
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <map>
#include <memory>
#include <vector>
namespace Assimp {
@ -64,11 +63,12 @@ namespace Assimp {
namespace D3MF {
// ------------------------------------------------------------------------------------------------
typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
class OpcPackageRelationshipReader {
public:
OpcPackageRelationshipReader(XmlParser &parser) {
OpcPackageRelationshipReader(XmlParser &parser) :
m_relationShips() {
XmlNode root = parser.getRootNode();
ParseRootNode(root);
}
@ -91,6 +91,7 @@ public:
if (relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty()) {
return false;
}
return true;
}
@ -100,7 +101,7 @@ public:
}
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
std::string name = currentNode.name();
const std::string name = currentNode.name();
if (name == "Relationship") {
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID).as_string();
@ -116,11 +117,23 @@ public:
std::vector<OpcPackageRelationshipPtr> m_relationShips;
};
static bool IsEmbeddedTexture( const std::string &filename ) {
const std::string extension = BaseImporter::GetExtension(filename);
if (extension == "jpg" || extension == "png") {
std::string::size_type pos = filename.find("thumbnail");
if (pos == std::string::npos) {
return false;
}
return true;
}
return false;
}
// ------------------------------------------------------------------------------------------------
D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
mRootStream(nullptr),
mZipArchive() {
mZipArchive.reset(new ZipArchiveIOSystem(pIOHandler, rFile));
mZipArchive = new ZipArchiveIOSystem(pIOHandler, rFile);
if (!mZipArchive->isOpen()) {
throw DeadlyImportError("Failed to open file ", rFile, ".");
}
@ -136,12 +149,12 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
IOStream *fileStream = mZipArchive->Open(file.c_str());
if (nullptr == fileStream) {
ai_assert(fileStream != nullptr);
ASSIMP_LOG_ERROR("Filestream is nullptr.");
continue;
}
std::string rootFile = ReadPackageRootRelationship(fileStream);
if (rootFile.size() > 0 && rootFile[0] == '/') {
if (!rootFile.empty() && rootFile[0] == '/') {
rootFile = rootFile.substr(1);
if (rootFile[0] == '/') {
// deal with zip-bug
@ -158,9 +171,12 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
if (nullptr == mRootStream) {
throw DeadlyImportError("Cannot open root-file in archive : " + rootFile);
}
} else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
ASSIMP_LOG_WARN("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file);
} else if (IsEmbeddedTexture(file)) {
IOStream *fileStream = mZipArchive->Open(file.c_str());
LoadEmbeddedTextures(fileStream, file);
mZipArchive->Close(fileStream);
} else {
ASSIMP_LOG_WARN("Ignored file of unknown type: ", file);
}
@ -169,20 +185,25 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
D3MFOpcPackage::~D3MFOpcPackage() {
mZipArchive->Close(mRootStream);
delete mZipArchive;
}
IOStream *D3MFOpcPackage::RootStream() const {
return mRootStream;
}
static const std::string ModelRef = "3D/3dmodel.model";
const std::vector<aiTexture *> &D3MFOpcPackage::GetEmbeddedTextures() const {
return mEmbeddedTextures;
}
static const char *const ModelRef = "3D/3dmodel.model";
bool D3MFOpcPackage::validate() {
if (nullptr == mRootStream || nullptr == mZipArchive) {
return false;
}
return mZipArchive->Exists(ModelRef.c_str());
return mZipArchive->Exists(ModelRef);
}
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
@ -204,6 +225,31 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
return (*itr)->target;
}
void D3MFOpcPackage::LoadEmbeddedTextures(IOStream *fileStream, const std::string &filename) {
if (nullptr == fileStream) {
return;
}
const size_t size = fileStream->FileSize();
if (0 == size) {
return;
}
unsigned char *data = new unsigned char[size];
fileStream->Read(data, 1, size);
aiTexture *texture = new aiTexture;
std::string embName = "*" + filename;
texture->mFilename.Set(embName.c_str());
texture->mWidth = static_cast<unsigned int>(size);
texture->mHeight = 0;
texture->achFormatHint[0] = 'p';
texture->achFormatHint[1] = 'n';
texture->achFormatHint[2] = 'g';
texture->achFormatHint[3] = '\0';
texture->pcData = (aiTexel*) data;
mEmbeddedTextures.emplace_back(texture);
}
} // Namespace D3MF
} // Namespace Assimp

View File

@ -42,11 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef D3MFOPCPACKAGE_H
#define D3MFOPCPACKAGE_H
#include <assimp/IOSystem.hpp>
#include <memory>
#include <string>
#include <assimp/IOSystem.hpp>
struct aiTexture;
namespace Assimp {
class ZipArchiveIOSystem;
namespace D3MF {
@ -63,16 +66,19 @@ public:
~D3MFOpcPackage();
IOStream* RootStream() const;
bool validate();
const std::vector<aiTexture*> &GetEmbeddedTextures() const;
protected:
std::string ReadPackageRootRelationship(IOStream* stream);
void LoadEmbeddedTextures(IOStream *fileStream, const std::string &filename);
private:
IOStream* mRootStream;
std::unique_ptr<ZipArchiveIOSystem> mZipArchive;
ZipArchiveIOSystem *mZipArchive;
std::vector<aiTexture *> mEmbeddedTextures;
};
} // Namespace D3MF
} // Namespace Assimp
} // namespace D3MF
} // namespace Assimp
#endif // D3MFOPCPACKAGE_H

View File

@ -0,0 +1,593 @@
/*
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.
----------------------------------------------------------------------
*/
#include "XmlSerializer.h"
#include "D3MFOpcPackage.h"
#include "3MFXmlTags.h"
#include "3MFTypes.h"
#include <assimp/scene.h>
namespace Assimp {
namespace D3MF {
static const int IdNotSet = -1;
namespace {
static const size_t ColRGBA_Len = 9;
static const size_t ColRGB_Len = 7;
// format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
bool validateColorString(const char *color) {
const size_t len = strlen(color);
if (ColRGBA_Len != len && ColRGB_Len != len) {
return false;
}
return true;
}
aiFace ReadTriangle(XmlNode &node) {
aiFace face;
face.mNumIndices = 3;
face.mIndices = new unsigned int[face.mNumIndices];
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;
}
aiVector3D ReadVertex(XmlNode &node) {
aiVector3D vertex;
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;
}
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;
}
return false;
}
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
std::string strValue;
const bool ret = getNodeAttribute(node, attribute, strValue);
if (ret) {
value = std::atoi(strValue.c_str());
return true;
}
return false;
}
aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
// split the string
std::vector<float> numbers;
std::string currentNumber;
for (char c : matrixStr) {
if (c == ' ') {
if (!currentNumber.empty()) {
float f = std::stof(currentNumber);
numbers.push_back(f);
currentNumber.clear();
}
} else {
currentNumber.push_back(c);
}
}
if (!currentNumber.empty()) {
const float f = std::stof(currentNumber);
numbers.push_back(f);
}
aiMatrix4x4 transformMatrix;
transformMatrix.a1 = numbers[0];
transformMatrix.b1 = numbers[1];
transformMatrix.c1 = numbers[2];
transformMatrix.d1 = 0;
transformMatrix.a2 = numbers[3];
transformMatrix.b2 = numbers[4];
transformMatrix.c2 = numbers[5];
transformMatrix.d2 = 0;
transformMatrix.a3 = numbers[6];
transformMatrix.b3 = numbers[7];
transformMatrix.c3 = numbers[8];
transformMatrix.d3 = 0;
transformMatrix.a4 = numbers[9];
transformMatrix.b4 = numbers[10];
transformMatrix.c4 = numbers[11];
transformMatrix.d4 = 1;
return transformMatrix;
}
bool parseColor(const char *color, aiColor4D &diffuse) {
if (nullptr == color) {
return false;
}
if (!validateColorString(color)) {
return false;
}
if ('#' != color[0]) {
return false;
}
char r[3] = { color[1], color[2], '\0' };
diffuse.r = static_cast<ai_real>(strtol(r, nullptr, 16)) / ai_real(255.0);
char g[3] = { color[3], color[4], '\0' };
diffuse.g = static_cast<ai_real>(strtol(g, nullptr, 16)) / ai_real(255.0);
char b[3] = { color[5], color[6], '\0' };
diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
const size_t len = strlen(color);
if (ColRGB_Len == len) {
return true;
}
char a[3] = { color[7], color[8], '\0' };
diffuse.a = static_cast<ai_real>(strtol(a, nullptr, 16)) / ai_real(255.0);
return true;
}
void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
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);
}
}
} // namespace
XmlSerializer::XmlSerializer(XmlParser *xmlParser) :
mResourcesDictionnary(),
mMeshCount(0),
mXmlParser(xmlParser) {
ai_assert(nullptr != xmlParser);
}
XmlSerializer::~XmlSerializer() {
for (auto &it : mResourcesDictionnary) {
delete it.second;
}
}
void XmlSerializer::ImportXml(aiScene *scene) {
if (nullptr == scene) {
return;
}
scene->mRootNode = new aiNode(XmlTag::RootTag);
XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
if (node.empty()) {
return;
}
XmlNode resNode = node.child(XmlTag::resources);
for (auto &currentNode : resNode.children()) {
const std::string currentNodeName = currentNode.name();
if (currentNodeName == XmlTag::texture_2d) {
ReadEmbeddecTexture(currentNode);
} else if (currentNodeName == XmlTag::texture_group) {
ReadTextureGroup(currentNode);
} else if (currentNodeName == XmlTag::object) {
ReadObject(currentNode);
} else if (currentNodeName == XmlTag::basematerials) {
ReadBaseMaterials(currentNode);
} else if (currentNodeName == XmlTag::meta) {
ReadMetadata(currentNode);
}
}
StoreMaterialsInScene(scene);
XmlNode buildNode = node.child(XmlTag::build);
if (buildNode.empty()) {
return;
}
for (auto &currentNode : buildNode.children()) {
const std::string currentNodeName = currentNode.name();
if (currentNodeName == XmlTag::item) {
int objectId = IdNotSet;
std::string transformationMatrixStr;
aiMatrix4x4 transformationMatrix;
getNodeAttribute(currentNode, D3MF::XmlTag::objectid, objectId);
bool hasTransform = getNodeAttribute(currentNode, D3MF::XmlTag::transform, transformationMatrixStr);
auto it = mResourcesDictionnary.find(objectId);
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
Object *obj = static_cast<Object *>(it->second);
if (hasTransform) {
transformationMatrix = parseTransformMatrix(transformationMatrixStr);
}
addObjectToNode(scene->mRootNode, obj, transformationMatrix);
}
}
}
// import the metadata
if (!mMetaData.empty()) {
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);
scene->mMetaData->Set(static_cast<unsigned int>(i), mMetaData[i].name, val);
}
}
// import the meshes, materials are already stored
scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
if (scene->mNumMeshes != 0) {
scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
for (auto &it : mResourcesDictionnary) {
if (it.second->getType() == ResourceType::RT_Object) {
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];
}
}
}
}
}
void XmlSerializer::addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform) {
ai_assert(nullptr != obj);
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;
if (nullptr != parent) {
parent->addChildren(1, &sceneNode);
}
for (Assimp::D3MF::Component c : obj->mComponents) {
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);
}
}
}
void XmlSerializer::ReadObject(XmlNode &node) {
int id = IdNotSet, pid = IdNotSet, pindex = IdNotSet;
bool hasId = getNodeAttribute(node, XmlTag::id, id);
if (!hasId) {
return;
}
bool hasPid = getNodeAttribute(node, XmlTag::pid, pid);
bool hasPindex = getNodeAttribute(node, XmlTag::pindex, pindex);
Object *obj = new Object(id);
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == D3MF::XmlTag::mesh) {
auto mesh = ReadMesh(currentNode);
mesh->mName.Set(ai_to_string(id));
if (hasPid) {
auto it = mResourcesDictionnary.find(pid);
if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
}
}
obj->mMeshes.push_back(mesh);
obj->mMeshIndex.push_back(mMeshCount);
mMeshCount++;
} else if (currentName == D3MF::XmlTag::components) {
for (XmlNode &currentSubNode : currentNode.children()) {
const std::string subNodeName = currentSubNode.name();
if (subNodeName == D3MF::XmlTag::component) {
int objectId = IdNotSet;
std::string componentTransformStr;
aiMatrix4x4 componentTransform;
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::transform, componentTransformStr)) {
componentTransform = parseTransformMatrix(componentTransformStr);
}
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) {
obj->mComponents.push_back({ objectId, componentTransform });
}
}
}
}
}
mResourcesDictionnary.insert(std::make_pair(id, obj));
}
aiMesh *XmlSerializer::ReadMesh(XmlNode &node) {
if (node.empty()) {
return nullptr;
}
aiMesh *mesh = new aiMesh();
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::vertices) {
ImportVertices(currentNode, mesh);
} else if (currentName == XmlTag::triangles) {
ImportTriangles(currentNode, mesh);
}
}
return mesh;
}
void XmlSerializer::ReadMetadata(XmlNode &node) {
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()) {
return;
}
MetaEntry entry;
entry.name = name;
entry.value = value;
mMetaData.push_back(entry);
}
void XmlSerializer::ImportVertices(XmlNode &node, aiMesh *mesh) {
ai_assert(nullptr != mesh);
std::vector<aiVector3D> vertices;
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::vertex) {
vertices.push_back(ReadVertex(currentNode));
}
}
mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
}
void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
std::vector<aiFace> faces;
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::triangle) {
int pid = IdNotSet, p1 = IdNotSet;
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->second->getType() == ResourceType::RT_BaseMaterials) {
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
} else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
if (mesh->mTextureCoords[0] == nullptr) {
Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second);
const std::string name = ai_to_string(group->mTexId);
for (size_t i = 0; i < mMaterials.size(); ++i) {
if (name == mMaterials[i]->GetName().C_Str()) {
mesh->mMaterialIndex = static_cast<unsigned int>(i);
}
}
mesh->mTextureCoords[0] = new aiVector3D[group->mTex2dCoords.size()];
for (unsigned int i = 0; i < group->mTex2dCoords.size(); ++i) {
mesh->mTextureCoords[0][i] = aiVector3D(group->mTex2dCoords[i].x, group->mTex2dCoords[i].y, 0);
}
}
}
}
}
aiFace face = ReadTriangle(currentNode);
faces.push_back(face);
}
}
mesh->mNumFaces = static_cast<unsigned int>(faces.size());
mesh->mFaces = new aiFace[mesh->mNumFaces];
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
std::copy(faces.begin(), faces.end(), mesh->mFaces);
}
void XmlSerializer::ReadBaseMaterials(XmlNode &node) {
int id = IdNotSet;
if (getNodeAttribute(node, D3MF::XmlTag::id, id)) {
BaseMaterials *baseMaterials = new BaseMaterials(id);
for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::basematerials_base) {
baseMaterials->mMaterialIndex.push_back(static_cast<unsigned int>(mMaterials.size()));
mMaterials.push_back(readMaterialDef(currentNode, id));
}
}
mResourcesDictionnary.insert(std::make_pair(id, baseMaterials));
}
}
void XmlSerializer::ReadEmbeddecTexture(XmlNode &node) {
if (node.empty()) {
return;
}
std::string value;
EmbeddedTexture *tex2D = nullptr;
if (XmlParser::getStdStrAttribute(node, XmlTag::id, value)) {
tex2D = new EmbeddedTexture(atoi(value.c_str()));
}
if (nullptr == tex2D) {
return;
}
if (XmlParser::getStdStrAttribute(node, XmlTag::path, value)) {
tex2D->mPath = value;
}
if (XmlParser::getStdStrAttribute(node, XmlTag::texture_content_type, value)) {
tex2D->mContentType = value;
}
if (XmlParser::getStdStrAttribute(node, XmlTag::texture_tilestyleu, value)) {
tex2D->mTilestyleU = value;
}
if (XmlParser::getStdStrAttribute(node, XmlTag::texture_tilestylev, value)) {
tex2D->mTilestyleV = value;
}
mEmbeddedTextures.emplace_back(tex2D);
StoreEmbeddedTexture(tex2D);
}
void XmlSerializer::StoreEmbeddedTexture(EmbeddedTexture *tex) {
aiMaterial *mat = new aiMaterial;
aiString s;
s.Set(ai_to_string(tex->mId).c_str());
mat->AddProperty(&s, AI_MATKEY_NAME);
const std::string name = "*" + tex->mPath;
s.Set(name);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
aiColor3D col;
mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_DIFFUSE);
mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_AMBIENT);
mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_EMISSIVE);
mat->AddProperty<aiColor3D>(&col, 1, AI_MATKEY_COLOR_SPECULAR);
mMaterials.emplace_back(mat);
}
void XmlSerializer::ReadTextureCoords2D(XmlNode &node, Texture2DGroup *tex2DGroup) {
if (node.empty() || nullptr == tex2DGroup) {
return;
}
int id = IdNotSet;
if (XmlParser::getIntAttribute(node, "texid", id)) {
tex2DGroup->mTexId = id;
}
double value = 0.0;
for (XmlNode currentNode : node.children()) {
const std::string currentName = currentNode.name();
aiVector2D texCoord;
if (currentName == XmlTag::texture_2d_coord) {
XmlParser::getDoubleAttribute(currentNode, XmlTag::texture_cuurd_u, value);
texCoord.x = (ai_real)value;
XmlParser::getDoubleAttribute(currentNode, XmlTag::texture_cuurd_v, value);
texCoord.y = (ai_real)value;
tex2DGroup->mTex2dCoords.push_back(texCoord);
}
}
}
void XmlSerializer::ReadTextureGroup(XmlNode &node) {
if (node.empty()) {
return;
}
int id = IdNotSet;
if (!XmlParser::getIntAttribute(node, XmlTag::id, id)) {
return;
}
Texture2DGroup *group = new Texture2DGroup(id);
ReadTextureCoords2D(node, group);
mResourcesDictionnary.insert(std::make_pair(id, group));
}
aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basematerialsId) {
aiMaterial *material = new aiMaterial();
material->mNumProperties = 0;
std::string name;
bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
std::string stdMaterialName;
const std::string strId(ai_to_string(basematerialsId));
stdMaterialName += "id";
stdMaterialName += strId;
stdMaterialName += "_";
if (hasName) {
stdMaterialName += std::string(name);
} else {
stdMaterialName += "basemat_";
stdMaterialName += ai_to_string(mMaterials.size());
}
aiString assimpMaterialName(stdMaterialName);
material->AddProperty(&assimpMaterialName, AI_MATKEY_NAME);
assignDiffuseColor(node, material);
return material;
}
void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
if (nullptr == scene || mMaterials.empty()) {
return;
}
scene->mNumMaterials = static_cast<unsigned int>(mMaterials.size());
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
for (size_t i = 0; i < mMaterials.size(); ++i) {
scene->mMaterials[i] = mMaterials[i];
}
}
} // namespace D3MF
} // namespace Assimp

View File

@ -3,6 +3,7 @@ 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,
@ -37,22 +38,59 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#pragma once
#ifndef AI_DEFINES_H_INC
#define AI_DEFINES_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/XmlParser.h>
#include <assimp/mesh.h>
#include <vector>
#include <map>
// We need those constants, workaround for any platforms where nobody defined them yet
#if (!defined SIZE_MAX)
# define SIZE_MAX (~((size_t)0))
#endif
struct aiNode;
struct aiMesh;
struct aiMaterial;
#if (!defined UINT_MAX)
# define UINT_MAX (~((unsigned int)0))
#endif
namespace Assimp {
namespace D3MF {
#endif // AI_DEINES_H_INC
class Resource;
class D3MFOpcPackage;
class Object;
class Texture2DGroup;
class EmbeddedTexture;
class XmlSerializer {
public:
XmlSerializer(XmlParser *xmlParser);
~XmlSerializer();
void ImportXml(aiScene *scene);
private:
void addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform);
void ReadObject(XmlNode &node);
aiMesh *ReadMesh(XmlNode &node);
void ReadMetadata(XmlNode &node);
void ImportVertices(XmlNode &node, aiMesh *mesh);
void ImportTriangles(XmlNode &node, aiMesh *mesh);
void ReadBaseMaterials(XmlNode &node);
void ReadEmbeddecTexture(XmlNode &node);
void StoreEmbeddedTexture(EmbeddedTexture *tex);
void ReadTextureCoords2D(XmlNode &node, Texture2DGroup *tex2DGroup);
void ReadTextureGroup(XmlNode &node);
aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId);
void StoreMaterialsInScene(aiScene *scene);
private:
struct MetaEntry {
std::string name;
std::string value;
};
std::vector<MetaEntry> mMetaData;
std::vector<EmbeddedTexture *> mEmbeddedTextures;
std::vector<aiMaterial *> mMaterials;
std::map<unsigned int, Resource *> mResourcesDictionnary;
unsigned int mMeshCount;
XmlParser *mXmlParser;
};
} // namespace D3MF
} // namespace Assimp

View File

@ -63,7 +63,7 @@ namespace Assimp {
class AC3DImporter : public BaseImporter {
public:
AC3DImporter();
~AC3DImporter();
~AC3DImporter() override;
// Represents an AC3D material
struct Material {
@ -185,25 +185,25 @@ public:
* See BaseImporter::CanRead() for details.
*/
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details */
const aiImporterDesc *GetInfo() const;
const aiImporterDesc *GetInfo() const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details*/
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
IOSystem *pIOHandler) override;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.*/
void SetupProperties(const Importer *pImp);
void SetupProperties(const Importer *pImp) override;
private:
// -------------------------------------------------------------------

View File

@ -511,7 +511,7 @@ bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool p
}
if (extension.empty() || pCheckSig) {
const char *tokens[] = { "<amf" };
static const char * const tokens[] = { "<amf" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}

View File

@ -267,7 +267,7 @@ public:
AMFImporter() AI_NO_EXCEPT;
/// Default destructor.
~AMFImporter();
~AMFImporter() override;
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
/// Also exception can be thrown if trouble will found.
@ -276,9 +276,9 @@ public:
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
void ParseHelper_Node_Exit();
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
const aiImporterDesc *GetInfo() const;
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const override;
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
const aiImporterDesc *GetInfo() const override;
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;

View File

@ -48,15 +48,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_AI_AMF_IMPORTER_NODE_H
#define INCLUDED_AI_AMF_IMPORTER_NODE_H
// Header files, stdlib.
// Header files, Assimp.
#include <assimp/scene.h>
#include <assimp/types.h>
#include <list>
#include <string>
#include <vector>
// Header files, Assimp.
#include "assimp/scene.h"
#include "assimp/types.h"
/// \class CAMFImporter_NodeElement
/// Base class for elements of nodes.
class AMFNodeElementBase {

View File

@ -690,7 +690,7 @@ void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellatio
if (ne->Type == AMFNodeElementBase::ENET_Metadata) continue;
if (ne->Type != AMFNodeElementBase::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");
// create alias for conveniance
// create alias for convenience
AMFInstance &als = *((AMFInstance *)ne);
// find referenced object
if (!Find_ConvertedNode(als.ObjectID, nodeArray, &found_node)) Throw_ID_NotFound(als.ObjectID);

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,
@ -106,7 +104,7 @@ bool ASEImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
}
if ((!extension.length() || cs) && pIOHandler) {
const char *tokens[] = { "*3dsmax_asciiexport" };
static const char * const tokens[] = { "*3dsmax_asciiexport" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
@ -683,7 +681,7 @@ void ASEImporter::BuildNodes(std::vector<BaseNode *> &nodes) {
}
}
// Are there ane orphaned nodes?
// Are there any orphaned nodes?
if (!aiList.empty()) {
std::vector<aiNode *> apcNodes;
apcNodes.reserve(aiList.size() + pcScene->mRootNode->mNumChildren);

View File

@ -62,42 +62,37 @@ namespace Assimp {
class ASEImporter : public BaseImporter {
public:
ASEImporter();
~ASEImporter();
~ASEImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
*/
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const;
const aiImporterDesc* GetInfo () const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
IOSystem* pIOHandler) override;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer* pImp) override;
private:
// -------------------------------------------------------------------
/** Generate normal vectors basing on smoothing groups
* (in some cases the normal are already contained in the file)
@ -106,7 +101,6 @@ private:
*/
bool GenerateNormals(ASE::Mesh& mesh);
// -------------------------------------------------------------------
/** Create valid vertex/normal/UV/color/face lists.
* All elements are unique, faces have only one set of indices
@ -115,51 +109,43 @@ private:
*/
void BuildUniqueRepresentation(ASE::Mesh& mesh);
/** Create one-material-per-mesh meshes ;-)
* \param mesh Mesh to work with
* \param Receives the list of all created meshes
*/
void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut);
// -------------------------------------------------------------------
/** Convert a material to a aiMaterial object
* \param mat Input material
*/
void ConvertMaterial(ASE::Material& mat);
// -------------------------------------------------------------------
/** Setup the final material indices for each mesh
*/
void BuildMaterialIndices();
// -------------------------------------------------------------------
/** Build the node graph
*/
void BuildNodes(std::vector<ASE::BaseNode*>& nodes);
// -------------------------------------------------------------------
/** Build output cameras
*/
void BuildCameras();
// -------------------------------------------------------------------
/** Build output lights
*/
void BuildLights();
// -------------------------------------------------------------------
/** Build output animations
*/
void BuildAnimations(const std::vector<ASE::BaseNode*>& nodes);
// -------------------------------------------------------------------
/** Add sub nodes to a node
* \param pcParent parent node to be filled
@ -183,7 +169,6 @@ private:
void GenerateDefaultMaterial();
protected:
/** Parser instance */
ASE::Parser* mParser;

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,

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

@ -4,7 +4,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,
@ -43,16 +42,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file AssbinExporter.h
* ASSBIN Exporter Main Header
*/
#pragma once
#ifndef AI_ASSBINEXPORTER_H_INC
#define AI_ASSBINEXPORTER_H_INC
#include <assimp/defs.h>
#ifndef ASSIMP_BUILD_NO_EXPORT
// nothing really needed here - reserved for future use like properties
namespace Assimp {
void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/);
}
#endif
#endif // AI_ASSBINEXPORTER_H_INC

View File

@ -43,13 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "AssbinFileWriter.h"
#include "Common/assbin_chunks.h"
#include "PostProcessing/ProcessHelper.h"
#include <assimp/Exceptional.h>
#include <assimp/version.h>
#include <assimp/Exporter.hpp>
#include <assimp/IOStream.hpp>
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
@ -58,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../contrib/zlib/zlib.h"
#endif
#include <time.h>
#include <ctime>
#if _MSC_VER
#pragma warning(push)
@ -172,7 +170,7 @@ inline size_t Write<aiQuaternion>(IOStream *stream, const aiQuaternion &v) {
t += Write<float>(stream, v.z);
ai_assert(t == 16);
return 16;
return t;
}
// -----------------------------------------------------------------------------------
@ -277,7 +275,7 @@ public:
// empty
}
virtual ~AssbinChunkWriter() {
~AssbinChunkWriter() override {
if (container) {
container->Write(&magic, sizeof(uint32_t), 1);
container->Write(&cursor, sizeof(uint32_t), 1);
@ -288,26 +286,27 @@ public:
void *GetBufferPointer() { return buffer; }
// -------------------------------------------------------------------
virtual size_t Read(void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) {
size_t Read(void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) override {
return 0;
}
virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) {
aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) override {
return aiReturn_FAILURE;
}
virtual size_t Tell() const {
size_t Tell() const override {
return cursor;
}
virtual void Flush() {
void Flush() override {
// not implemented
}
virtual size_t FileSize() const {
size_t FileSize() const override {
return cursor;
}
// -------------------------------------------------------------------
virtual size_t Write(const void *pvBuffer, size_t pSize, size_t pCount) {
size_t Write(const void *pvBuffer, size_t pSize, size_t pCount) override {
pSize *= pCount;
if (cursor + pSize > cur_size) {
Grow(cursor + pSize);

View File

@ -406,7 +406,7 @@ void AssbinImporter::ReadBinaryMesh(IOStream *stream, aiMesh *mesh) {
f.mIndices = new unsigned int[f.mNumIndices];
for (unsigned int a = 0; a < f.mNumIndices; ++a) {
// Check if unsigned short ( 16 bit ) are big enought for the indices
// Check if unsigned short ( 16 bit ) are big enough for the indices
if (fitsIntoUI16(mesh->mNumVertices)) {
f.mIndices[a] = Read<uint16_t>(stream);
} else {

View File

@ -5,7 +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,
@ -74,17 +73,11 @@ private:
bool compressed;
public:
virtual bool CanRead(
const std::string& pFile,
IOSystem* pIOHandler,
bool checkSig
) const;
virtual const aiImporterDesc* GetInfo() const;
virtual void InternReadFile(
const std::string& pFile,
aiScene* pScene,
IOSystem* pIOHandler
);
bool CanRead(const std::string& pFile,
IOSystem* pIOHandler, bool checkSig) const override;
const aiImporterDesc* GetInfo() const override;
void InternReadFile(
const std::string& pFile,aiScene* pScene,IOSystem* pIOHandler) override;
void ReadHeader();
void ReadBinaryScene( IOStream * stream, aiScene* pScene );
void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );

View File

@ -41,12 +41,17 @@ public:
enum {
Flag_DoNotIndent = 0x1,
Flag_WriteSpecialFloats = 0x2,
Flag_SkipWhitespaces = 0x4
};
JSONWriter(Assimp::IOStream &out, unsigned int flags = 0u) :
out(out), first(), flags(flags) {
out(out), indent (""), newline("\n"), space(" "), buff (), first(false), flags(flags) {
// make sure that all formatting happens using the standard, C locale and not the user's current locale
buff.imbue(std::locale("C"));
if (flags & Flag_SkipWhitespaces) {
newline = "";
space = "";
}
}
~JSONWriter() {
@ -70,7 +75,7 @@ public:
void Key(const std::string &name) {
AddIndentation();
Delimit();
buff << '\"' + name + "\": ";
buff << '\"' + name + "\":" << space;
}
template <typename Literal>
@ -78,12 +83,12 @@ public:
AddIndentation();
Delimit();
LiteralToString(buff, name) << '\n';
LiteralToString(buff, name) << newline;
}
template <typename Literal>
void SimpleValue(const Literal &s) {
LiteralToString(buff, s) << '\n';
LiteralToString(buff, s) << newline;
}
void SimpleValue(const void *buffer, size_t len) {
@ -102,7 +107,7 @@ public:
}
}
buff << '\"' << cur_out << "\"\n";
buff << '\"' << cur_out << "\"" << newline;
delete[] cur_out;
}
@ -115,7 +120,7 @@ public:
}
}
first = true;
buff << "{\n";
buff << "{" << newline;
PushIndent();
}
@ -123,7 +128,7 @@ public:
PopIndent();
AddIndentation();
first = false;
buff << "}\n";
buff << "}" << newline;
}
void StartArray(bool is_element = false) {
@ -135,19 +140,19 @@ public:
}
}
first = true;
buff << "[\n";
buff << "[" << newline;
PushIndent();
}
void EndArray() {
PopIndent();
AddIndentation();
buff << "]\n";
buff << "]" << newline;
first = false;
}
void AddIndentation() {
if (!(flags & Flag_DoNotIndent)) {
if (!(flags & Flag_DoNotIndent) && !(flags & Flag_SkipWhitespaces)) {
buff << indent;
}
}
@ -156,7 +161,7 @@ public:
if (!first) {
buff << ',';
} else {
buff << ' ';
buff << space;
first = false;
}
}
@ -227,7 +232,9 @@ private:
private:
Assimp::IOStream &out;
std::string indent, newline;
std::string indent;
std::string newline;
std::string space;
std::stringstream buff;
bool first;
@ -765,7 +772,7 @@ void Write(JSONWriter &out, const aiScene &ai) {
out.EndObj();
}
void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *scene, const Assimp::ExportProperties *) {
void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *scene, const Assimp::ExportProperties *pProperties) {
std::unique_ptr<Assimp::IOStream> str(io->Open(file, "wt"));
if (!str) {
throw DeadlyExportError("could not open output file");
@ -782,7 +789,12 @@ void ExportAssimp2Json(const char *file, Assimp::IOSystem *io, const aiScene *sc
splitter.Execute(scenecopy_tmp);
// XXX Flag_WriteSpecialFloats is turned on by default, right now we don't have a configuration interface for exporters
JSONWriter s(*str, JSONWriter::Flag_WriteSpecialFloats);
unsigned int flags = JSONWriter::Flag_WriteSpecialFloats;
if (pProperties->GetPropertyBool("JSON_SKIP_WHITESPACES", false)) {
flags |= JSONWriter::Flag_SkipWhitespaces;
}
JSONWriter s(*str, flags);
Write(s, *scenecopy_tmp);
} catch (...) {

View File

@ -69,13 +69,12 @@ void MeshSplitter::UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh
for (unsigned int i = 0, end = pcNode->mNumChildren; i < end;++i) {
UpdateNode ( pcNode->mChildren[i], source_mesh_map );
}
return;
}
#define WAS_NOT_COPIED 0xffffffff
static const unsigned int WAS_NOT_COPIED = 0xffffffff;
typedef std::pair <unsigned int,float> PerVertexWeight;
typedef std::vector <PerVertexWeight> VertexWeightTable;
using PerVertexWeight = std::pair <unsigned int,float>;
using VertexWeightTable = std::vector <PerVertexWeight>;
// ------------------------------------------------------------------------------------------------
VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh) {
@ -89,7 +88,7 @@ VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh) {
aiBone* bone = pMesh->mBones[i];
for (unsigned int a = 0; a < bone->mNumWeights;++a) {
const aiVertexWeight& weight = bone->mWeights[a];
avPerVertexWeights[weight.mVertexId].push_back( std::make_pair(i,weight.mWeight) );
avPerVertexWeights[weight.mVertexId].emplace_back(i,weight.mWeight);
}
}
return avPerVertexWeights;
@ -100,7 +99,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
// TODO: should better use std::(multi)set for source_mesh_map.
if (in_mesh->mNumVertices <= LIMIT) {
source_mesh_map.push_back(std::make_pair(in_mesh,a));
source_mesh_map.emplace_back(in_mesh,a);
return;
}
@ -187,7 +186,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
break;
}
vFaces.push_back(aiFace());
vFaces.emplace_back();
aiFace& rFace = vFaces.back();
// setup face type and number of indices

View File

@ -24,10 +24,9 @@ struct aiNode;
/** Splits meshes of unique vertices into meshes with no more vertices than
* a given, configurable threshold value.
*/
class MeshSplitter
{
class MeshSplitter {
public:
unsigned int LIMIT;
void SetLimit(unsigned int l) {
LIMIT = l;
@ -37,8 +36,6 @@ public:
return LIMIT;
}
public:
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
@ -46,16 +43,10 @@ public:
*/
void Execute(aiScene *pScene);
private:
void UpdateNode(aiNode *pcNode, const std::vector<std::pair<aiMesh *, unsigned int>> &source_mesh_map);
void SplitMesh(unsigned int index, aiMesh *mesh, std::vector<std::pair<aiMesh *, unsigned int>> &source_mesh_map);
public:
unsigned int LIMIT;
};
#endif // INCLUDED_MESH_SPLITTER

View File

@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file AssxmlExporter.h
* ASSXML Exporter Main Header
*/
#pragma once
#ifndef AI_ASSXMLEXPORTER_H_INC
#define AI_ASSXMLEXPORTER_H_INC

View File

@ -168,7 +168,7 @@ static void WriteNode(const aiNode *node, IOStream *io, unsigned int depth) {
}
// -----------------------------------------------------------------------------------
// Some chuncks of text will need to be encoded for XML
// Some chunks of text will need to be encoded for XML
// http://stackoverflow.com/questions/5665231/most-efficient-way-to-escape-xml-html-in-c-string#5665377
static std::string encodeXML(const std::string &data) {
std::string buffer;
@ -601,7 +601,7 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
ioprintf(io, "\t\t<TextureCoords num=\"%u\" set=\"%u\" name=\"%s\" num_components=\"%u\"> \n",
mesh->mNumVertices,
a,
mesh->mTextureCoordsNames[a].C_Str(),
(mesh->HasTextureCoordsName(a) ? mesh->GetTextureCoordsName(a)->C_Str() : ""),
mesh->mNumUVComponents[a]);
if (!shortened) {

View File

@ -4,7 +4,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,
@ -43,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file AssxmlFileWriter.h
* @brief Declaration of Assxml file writer.
*/
#pragma once
#ifndef AI_ASSXMLFILEWRITER_H_INC
#define AI_ASSXMLFILEWRITER_H_INC

View File

@ -143,7 +143,7 @@ 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("Error in B3D file data: ", str);
#endif

View File

@ -4,7 +4,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,
@ -40,8 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Definition of the .b3d importer class. */
/**
* @file Definition of the .b3d importer class.
*/
#pragma once
#ifndef AI_B3DIMPORTER_H_INC
#define AI_B3DIMPORTER_H_INC
@ -62,14 +63,12 @@ namespace Assimp{
class B3DImporter : public BaseImporter{
public:
B3DImporter() = default;
virtual ~B3DImporter();
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
~B3DImporter() override;
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
protected:
virtual const aiImporterDesc* GetInfo () const;
virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
const aiImporterDesc* GetInfo () const override;
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
private:
@ -96,7 +95,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();
@ -113,7 +112,6 @@ private:
void ReadBB3D( aiScene *scene );
size_t _pos;
// unsigned _size;
std::vector<unsigned char> _buf;
std::vector<size_t> _stack;

View File

@ -100,7 +100,7 @@ bool BVHLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs)
return true;
if ((!extension.length() || cs) && pIOHandler) {
const char *tokens[] = { "HIERARCHY" };
static const char * const tokens[] = { "HIERARCHY" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
@ -178,7 +178,7 @@ void BVHLoader::ReadHierarchy(aiScene *pScene) {
}
// ------------------------------------------------------------------------------------------------
// Reads a node and recursively its childs and returns the created node;
// Reads a node and recursively its children and returns the created node;
aiNode *BVHLoader::ReadNode() {
// first token is name
std::string nodeName = GetNextToken();

View File

@ -112,7 +112,7 @@ protected:
/** Reads the hierarchy */
void ReadHierarchy(aiScene *pScene);
/** Reads a node and recursively its childs and returns the created node. */
/** Reads a node and recursively its children and returns the created node. */
aiNode *ReadNode();
/** Reads an end node and returns the created node. */

View File

@ -476,7 +476,7 @@ public:
* in BlenderScene.cpp and is machine-generated.
* Converters are used to quickly handle objects whose
* exact data type is a runtime-property and not yet
* known at compile time (consier Object::data).*/
* known at compile time (consider Object::data).*/
void RegisterConverters();
// --------------------------------------------------------

View File

@ -113,8 +113,8 @@ BlenderImporter::~BlenderImporter() {
delete modifier_cache;
}
static const char *Tokens[] = { "BLENDER" };
static const char *TokensForSearch[] = { "blender" };
static const char * const Tokens[] = { "BLENDER" };
static const char * const TokensForSearch[] = { "blender" };
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
@ -679,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) {

View File

@ -4,7 +4,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,
@ -43,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file BlenderLoader.h
* @brief Declaration of the Blender 3D (*.blend) importer class.
*/
#pragma once
#ifndef INCLUDED_AI_BLEND_LOADER_H
#define INCLUDED_AI_BLEND_LOADER_H
@ -60,15 +60,19 @@ namespace Assimp {
// TinyFormatter.h
namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter;
template <typename T, typename TR, typename A>
class basic_formatter;
typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>> format;
}
} // namespace Formatter
// BlenderDNA.h
namespace Blender {
class FileDatabase;
struct ElemBase;
}
} // namespace Blender
// BlenderScene.h
namespace Blender {
@ -80,38 +84,36 @@ namespace Assimp {
struct MTex;
struct Image;
struct Material;
}
} // namespace Blender
// BlenderIntermediate.h
namespace Blender {
struct ConversionData;
template <template <typename,typename> class TCLASS, typename T> struct TempArray;
}
template <template <typename, typename> class TCLASS, typename T>
struct TempArray;
} // namespace Blender
// BlenderModifier.h
namespace Blender {
class BlenderModifierShowcase;
class BlenderModifier;
}
} // namespace Blender
// -------------------------------------------------------------------------------------------
/** Load blenders official binary format. The actual file structure (the `DNA` how they
* call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
* conversion from intermediate format to aiScene. */
// -------------------------------------------------------------------------------------------
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
{
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter> {
public:
BlenderImporter();
~BlenderImporter();
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
~BlenderImporter() override;
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
protected:
const aiImporterDesc* GetInfo () const;
void SetupProperties(const Importer* pImp);
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
const aiImporterDesc *GetInfo() const override;
void SetupProperties(const Importer *pImp) override;
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
void ParseBlendFile(Blender::FileDatabase &out, std::shared_ptr<IOStream> stream);
void ExtractScene(Blender::Scene &out, const Blender::FileDatabase &file);
void ConvertBlendFile(aiScene *out, const Blender::Scene &in, const Blender::FileDatabase &file);
@ -120,52 +122,46 @@ private:
aiNode *ConvertNode(const Blender::Scene &in,
const Blender::Object *obj,
Blender::ConversionData &conv_info,
const aiMatrix4x4& parentTransform
);
const aiMatrix4x4 &parentTransform);
// --------------------
void ConvertMesh(const Blender::Scene &in,
const Blender::Object *obj,
const Blender::Mesh *mesh,
Blender::ConversionData &conv_data,
Blender::TempArray<std::vector,aiMesh>& temp
);
Blender::TempArray<std::vector, aiMesh> &temp);
// --------------------
aiLight *ConvertLight(const Blender::Scene &in,
const Blender::Object *obj,
const Blender::Lamp *mesh,
Blender::ConversionData& conv_data
);
Blender::ConversionData &conv_data);
// --------------------
aiCamera *ConvertCamera(const Blender::Scene &in,
const Blender::Object *obj,
const Blender::Camera *mesh,
Blender::ConversionData& conv_data
);
Blender::ConversionData &conv_data);
// --------------------
void BuildDefaultMaterial(
Blender::ConversionData& conv_data
);
Blender::ConversionData &conv_data);
// --------------------
void AddBlendParams(
aiMaterial *result,
const Blender::Material* source
);
const Blender::Material *source);
// --------------------
void BuildMaterials(
Blender::ConversionData& conv_data
);
Blender::ConversionData &conv_data);
// --------------------
void ResolveTexture(
aiMaterial *out,
const Blender::Material *mat,
const Blender::MTex *tex,
Blender::ConversionData& conv_data
);
Blender::ConversionData &conv_data);
// --------------------
void ResolveImage(
@ -173,31 +169,25 @@ private:
const Blender::Material *mat,
const Blender::MTex *tex,
const Blender::Image *img,
Blender::ConversionData& conv_data
);
Blender::ConversionData &conv_data);
// --------------------
void AddSentinelTexture(
aiMaterial *out,
const Blender::Material *mat,
const Blender::MTex *tex,
Blender::ConversionData& conv_data
);
Blender::ConversionData &conv_data);
private: // static stuff, mostly logging and error reporting.
// --------------------
static void CheckActualType(const Blender::ElemBase *dt,
const char* check
);
const char *check);
// --------------------
static void NotSupportedObjectType(const Blender::Object *obj,
const char* type
);
const char *type);
private:
Blender::BlenderModifierShowcase *modifier_cache;
}; // !class BlenderImporter

View File

@ -146,8 +146,14 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
ThrowException("failed to read document " + pFile);
}
// Generate the root-node
pScene->mRootNode = new aiNode("<C4DRoot>");
// convert left-handed to right-handed
pScene->mRootNode->mTransformation.a1 = 0.01f;
pScene->mRootNode->mTransformation.b2 = 0.01f;
pScene->mRootNode->mTransformation.c3 = -0.01f;
// first convert all materials
ReadMaterials(doc->GetFirstMaterial());

View File

@ -110,7 +110,7 @@ bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
}
else if ((!extension.length() || checkSig) && pIOHandler) {
const char *tokens[] = { "Caligary" };
static const char * const tokens[] = { "Caligary" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
@ -230,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));
@ -586,7 +586,7 @@ void COBImporter::ReadUnit_Ascii(Scene &out, LineSplitter &splitter, const Chunk
return;
}
// parent chunks preceede their childs, so we should have the
// parent chunks preceede their children, so we should have the
// corresponding chunk already.
for (std::shared_ptr<Node> &nd : out.nodes) {
if (nd->id == nfo.parent_id) {
@ -668,7 +668,7 @@ void COBImporter::ReadCame_Ascii(Scene &out, LineSplitter &splitter, const Chunk
ReadBasicNodeInfo_Ascii(msh, ++splitter, nfo);
// skip the next line, we don't know this differenciation between a
// skip the next line, we don't know this differentiation between a
// standard camera and a panoramic camera.
++splitter;
}
@ -1169,7 +1169,7 @@ void COBImporter::ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const
const chunk_guard cn(nfo, reader);
// parent chunks preceede their childs, so we should have the
// parent chunks preceede their children, so we should have the
// corresponding chunk already.
for (std::shared_ptr<Node> &nd : out.nodes) {
if (nd->id == nfo.parent_id) {

View File

@ -56,46 +56,44 @@ namespace Assimp {
// TinyFormatter.h
namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter;
template <typename T, typename TR, typename A>
class basic_formatter;
typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>> format;
}
} // namespace Formatter
// COBScene.h
namespace COB {
struct ChunkInfo;
struct Node;
struct Scene;
}
} // namespace COB
// -------------------------------------------------------------------------------------------
/** Importer class to load TrueSpace files (cob,scn) up to v6.
*
* Currently relatively limited, loads only ASCII files and needs more test coverage. */
// -------------------------------------------------------------------------------------------
class COBImporter : public BaseImporter
{
class COBImporter : public BaseImporter {
public:
COBImporter();
~COBImporter();
~COBImporter() override;
// --------------------
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// --------------------
const aiImporterDesc *GetInfo() const override;
// --------------------
const aiImporterDesc* GetInfo () const;
// --------------------
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer *pImp) override;
// --------------------
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler);
IOSystem *pIOHandler) override;
private:
// -------------------------------------------------------------------
/** Prepend 'COB: ' and throw msg.*/
AI_WONT_RETURN static void ThrowException(const std::string &msg) AI_WONT_RETURN_SUFFIX;
@ -113,7 +111,6 @@ private:
void ReadBinaryFile(COB::Scene &out, StreamReaderLE *stream);
// Conversion to Assimp output format
aiNode *BuildNodes(const COB::Node &root, const COB::Scene &scin, aiScene *fill);
private:
@ -122,7 +119,8 @@ private:
void UnsupportedChunk_Ascii(LineSplitter &splitter, const COB::ChunkInfo &nfo, const char *name);
void ReadChunkInfo_Ascii(COB::ChunkInfo &out, const LineSplitter &splitter);
void ReadBasicNodeInfo_Ascii(COB::Node &msh, LineSplitter &splitter, const COB::ChunkInfo &nfo);
template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
template <typename T>
void ReadFloat3Tuple_Ascii(T &fill, const char **in);
void ReadPolH_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadBitM_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
@ -134,7 +132,6 @@ private:
void ReadUnit_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
void ReadChan_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
// Binary file support
void UnsupportedChunk_Binary(StreamReaderLE &reader, const COB::ChunkInfo &nfo, const char *name);
@ -149,7 +146,6 @@ private:
void ReadGrou_Binary(COB::Scene &out, StreamReaderLE &reader, const COB::ChunkInfo &nfo);
void ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const COB::ChunkInfo &nfo);
}; // !class COBImporter
} // end of namespace Assimp

View File

@ -4,7 +4,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,
@ -43,16 +42,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file COBScene.h
* @brief Utilities for the COB importer.
*/
#pragma once
#ifndef INCLUDED_AI_COB_SCENE_H
#define INCLUDED_AI_COB_SCENE_H
#include <memory>
#include <deque>
#include <map>
#include <assimp/BaseImporter.h>
#include <assimp/material.h>
#include <deque>
#include <map>
namespace Assimp {
namespace COB {

View File

@ -99,7 +99,7 @@ bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
return true;
if ((checkSig || !extension.length()) && pIOHandler) {
const char* tokens[] = {"$Filename"};
static const char * const tokens[] = {"$Filename"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
}
return false;

View File

@ -4,7 +4,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,
@ -59,35 +58,32 @@ namespace Assimp {
* Link to file format specification:
* <max_8_dvd>\samples\Motion\Docs\CSM.rtf
*/
class CSMImporter : public BaseImporter
{
class CSMImporter : public BaseImporter {
public:
CSMImporter();
~CSMImporter();
~CSMImporter() override;
public:
// -------------------------------------------------------------------
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
const aiImporterDesc *GetInfo() const override;
// -------------------------------------------------------------------
const aiImporterDesc* GetInfo () const;
// -------------------------------------------------------------------
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer *pImp) override;
// -------------------------------------------------------------------
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler);
IOSystem *pIOHandler) override;
private:
bool noSkeletonMesh;
}; // end of class CSMImporter
} // end of namespace Assimp
#endif // AI_AC3DIMPORTER_H_INC

View File

@ -47,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ColladaParser.h"
#include <assimp/ColladaMetaData.h>
#include <assimp/CreateAnimMesh.h>
#include <assimp/Defines.h>
#include <assimp/ParsingUtils.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/ZipArchiveIOSystem.h>
@ -135,14 +134,15 @@ bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool
// XML - too generic, we need to open the file and search for typical keywords
if (extension == "xml" || !extension.length() || checkSig) {
/* If CanRead() is called in order to check whether we
* support a specific file extension in general pIOHandler
* might be nullptr and it's our duty to return true here.
*/
if (!pIOHandler) {
// If CanRead() is called in order to check whether we
// support a specific file extension in general pIOHandler
// might be nullptr and it's our duty to return true here.
if (nullptr == pIOHandler) {
return true;
}
static const char *tokens[] = { "<collada" };
static const char * const tokens[] = {
"<collada"
};
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
@ -573,7 +573,7 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
// now place all mesh references we gathered in the target node
pTarget->mNumMeshes = static_cast<unsigned int>(newMeshRefs.size());
if (newMeshRefs.size()) {
if (!newMeshRefs.empty()) {
struct UIntTypeConverter {
unsigned int operator()(const size_t &v) const {
return static_cast<unsigned int>(v);
@ -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));
@ -1682,7 +1686,7 @@ void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/)
// store the material
mMaterialIndexByName[matIt->first] = newMats.size();
newMats.push_back(std::pair<Effect *, aiMaterial *>(&effect, mat));
newMats.emplace_back(&effect, mat);
}
// ScenePreprocessor generates a default material automatically if none is there.
// All further code here in this loader works well without a valid material so

View File

@ -231,11 +231,7 @@ void ColladaParser::UriDecodePath(aiString &ss) {
// Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
// I need to filter it without destroying linux paths starting with "/somewhere"
#if defined(_MSC_VER)
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
#else
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
#endif
--ss.length;
::memmove(ss.data, ss.data + 1, ss.length);
ss.data[ss.length] = 0;
@ -453,7 +449,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()) {
@ -626,8 +622,6 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
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;
@ -920,7 +914,7 @@ void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
if (currentName == "instance_effect") {
std::string url;
readUrlAttribute(currentNode, url);
pMaterial.mEffect = url.c_str();
pMaterial.mEffect = url;
}
}
}
@ -1439,9 +1433,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
@ -1489,11 +1482,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")
@ -1674,11 +1666,8 @@ 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);
}
unsigned int attrSet = 0;
if (XmlParser::getUIntAttribute(node, "set", attrSet))
channel.mIndex = attrSet;
}
@ -2170,10 +2159,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
@ -2215,8 +2204,8 @@ void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::Seman
void ColladaParser::ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive) {
// Attempt to load any undefined Collada::Image in ImageLibrary
for (ImageLibrary::iterator it = mImageLibrary.begin(); it != mImageLibrary.end(); ++it) {
Collada::Image &image = (*it).second;
for (auto & it : mImageLibrary) {
Collada::Image &image = it.second;
if (image.mImageData.empty()) {
std::unique_ptr<IOStream> image_file(zip_archive.Open(image.mFileName.c_str()));

View File

@ -43,6 +43,7 @@
* @brief Defines the parser helper class for the collada loader
*/
#pragma once
#ifndef AI_COLLADAPARSER_H_INC
#define AI_COLLADAPARSER_H_INC

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.
@ -132,8 +130,8 @@ bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bo
}
if ( extension.empty() || checkSig ) {
const char *pTokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
return BaseImporter::SearchFileHeaderForToken(pIOHandler, filename, pTokens, 4, 32 );
static const char * const pTokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
return SearchFileHeaderForToken(pIOHandler, filename, pTokens, 4, 32 );
}
return false;
@ -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");
}

View File

@ -4,7 +4,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,
@ -43,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file DXFLoader.h
* @brief Declaration of the .dxf importer class.
*/
#pragma once
#ifndef AI_DXFLOADER_H_INCLUDED
#define AI_DXFLOADER_H_INCLUDED
@ -59,7 +59,7 @@ namespace DXF {
struct Block;
struct InsertBlock;
typedef std::map<std::string, const DXF::Block*> BlockMap;
using BlockMap = std::map<std::string, const DXF::Block*>;
}
// ---------------------------------------------------------------------------
@ -69,29 +69,26 @@ namespace DXF {
class DXFImporter : public BaseImporter {
public:
DXFImporter();
~DXFImporter();
~DXFImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details*/
const aiImporterDesc* GetInfo () const;
const aiImporterDesc* GetInfo () const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details */
void InternReadFile( const std::string& pFile,
aiScene* pScene,
IOSystem* pIOHandler);
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
private:
// -----------------------------------------------------
void SkipSection(DXF::LineReader& reader);

View File

@ -917,8 +917,10 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root
} else if (line) {
const std::vector<unsigned int> &indices = ConvertLine(*line, root_node);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
} else {
} else if (geo) {
FBXImporter::LogWarn("ignoring unrecognized geometry: ", geo->Name());
} else {
FBXImporter::LogWarn("skipping null geometry");
}
}
@ -1126,7 +1128,7 @@ 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->SetTextureCoordsName(i, aiString(mesh.GetTextureCoordChannelName(i)));
out_mesh->mNumUVComponents[i] = 2;
}
@ -1593,7 +1595,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("bone research: Indicies size: ", out_indices.size());
ASSIMP_LOG_DEBUG("bone research: Indices size: ", out_indices.size());
// lookup must be populated in case something goes wrong
// this also allocates bones to mesh instance outside
@ -1766,6 +1768,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();
@ -1885,6 +1888,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();
@ -2129,7 +2133,7 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
if (ok) {
out_mat->AddProperty(&Emissive, 1, AI_MATKEY_COLOR_EMISSIVE);
} else {
const aiColor3D &emissiveColor = GetColorPropertyFromMaterial(props, "Maya|emissive", ok);
const aiColor3D &emissiveColor = GetColorProperty(props, "Maya|emissive", ok);
if (ok) {
out_mat->AddProperty(&emissiveColor, 1, AI_MATKEY_COLOR_EMISSIVE);
}
@ -2216,7 +2220,7 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
}
// PBR material information
const aiColor3D &baseColor = GetColorPropertyFromMaterial(props, "Maya|base_color", ok);
const aiColor3D &baseColor = GetColorProperty(props, "Maya|base_color", ok);
if (ok) {
out_mat->AddProperty(&baseColor, 1, AI_MATKEY_BASE_COLOR);
}
@ -2324,6 +2328,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;
@ -2599,7 +2604,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();

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
}

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;
@ -688,7 +693,7 @@ private:
typedef std::vector<int64_t> KeyTimeList;
typedef std::vector<float> KeyValueList;
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefore) */
class AnimationCurve : public Object {
public:
AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);

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);
@ -1681,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?
@ -1691,11 +1702,14 @@ 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);
tnode.AddChild(p);
// can't easily detrmine which texture path will be correct,
// can't easily determine which texture path will be correct,
// so just store what we have in every field.
// these being incorrect is a common problem with FBX anyway.
tnode.AddChild("FileName", texture_path);
@ -1789,7 +1803,7 @@ void FBXExporter::WriteObjects ()
blendchannel_uid, blendshape_name + FBX::SEPARATOR + "SubDeformer", "BlendShapeChannel"
);
sdnode.AddChild("Version", int32_t(100));
sdnode.AddChild("DeformPercent", float_t(0.0));
sdnode.AddChild("DeformPercent", float(0.0));
FBX::Node p("Properties70");
p.AddP70numberA("DeformPercent", 0.0);
sdnode.AddChild(p);
@ -1901,7 +1915,7 @@ void FBXExporter::WriteObjects ()
// mark all parent nodes as skeleton as well,
// up until we find the root node,
// or else the node containing the mesh,
// or else the parent of a node containig the mesh.
// or else the parent of a node containing the mesh.
for (
const aiNode* parent = n->mParent;
parent && parent != mScene->mRootNode;
@ -2196,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
@ -2599,12 +2671,21 @@ void FBXExporter::WriteModelNodes(
na.Dump(outstream, binary, 1);
// and connect them
connections.emplace_back("C", "OO", node_attribute_uid, node_uid);
} else {
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
if (node->mNumMeshes > 1 || node == mScene->mRootNode) {
@ -2625,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>>()
);
}
}
@ -2647,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
const std::string &property_name, // "Lcl Translation" etc
int64_t layer_uid,
int64_t node_uid
) {
int64_t node_uid) {
FBX::Node n("AnimationCurveNode");
n.AddProperties(uid, name + FBX::SEPARATOR + "AnimCurveNode", "");
FBX::Node p("Properties70");
@ -2671,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;
@ -158,10 +158,9 @@ namespace Assimp
int64_t uid,
const std::string &name, // "T", "R", or "S"
aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc
const std::string &property_name, // "Lcl Translation" etc
int64_t animation_layer_uid,
int64_t node_uid
);
int64_t node_uid);
void WriteAnimationCurve(
StreamWriterLE& outstream,
double default_value,

View File

@ -108,7 +108,7 @@ bool FBXImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
else if ((!extension.length() || checkSig) && pIOHandler) {
// at least ASCII-FBX files usually have a 'FBX' somewhere in their head
const char *tokens[] = { "fbx" };
static const char * const tokens[] = { "fbx" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;

View File

@ -70,28 +70,29 @@ typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
public:
FBXImporter();
virtual ~FBXImporter();
~FBXImporter() override;
// --------------------
bool CanRead(const std::string &pFile,
IOSystem *pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// --------------------
const aiImporterDesc *GetInfo() const;
const aiImporterDesc *GetInfo() const override;
// --------------------
void SetupProperties(const Importer *pImp);
void SetupProperties(const Importer *pImp) override;
// --------------------
void InternReadFile(const std::string &pFile,
aiScene *pScene,
IOSystem *pIOHandler);
IOSystem *pIOHandler) override;
private:
FBX::ImportSettings settings;
}; // !class FBXImporter
} // end of namespace Assimp
#endif // !INCLUDED_AI_FBX_IMPORTER_H

View File

@ -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());

View File

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

View File

@ -192,6 +192,10 @@ Scope::Scope(Parser& parser,bool topLevel)
}
const std::string& str = n->StringContents();
if (str.empty()) {
ParseError("unexpected content: empty string.");
}
elements.insert(ElementMap::value_type(str,new_Element(*n,parser)));
// Element() should stop at the next Key token (or right after a Close token)
@ -642,8 +646,7 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
ai_assert(data == end);
uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
if (dataToRead != buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
@ -733,8 +736,7 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
ai_assert(data == end);
uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
if (dataToRead != buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
@ -816,8 +818,7 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
ai_assert(data == end);
uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
if (dataToRead != buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
@ -892,8 +893,7 @@ void ParseVectorDataArray(std::vector<int>& out, const Element& el)
ai_assert(data == end);
uint64_t dataToRead = static_cast<uint64_t>(count) * 4;
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
if (dataToRead != buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
@ -954,8 +954,7 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
ai_assert(data == end);
uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
if (dataToRead != buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
@ -1019,8 +1018,7 @@ void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
ai_assert(data == end);
uint64_t dataToRead = static_cast<uint64_t>(count) * 4;
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
if (dataToRead != buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
@ -1088,8 +1086,7 @@ void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el)
ai_assert(data == end);
uint64_t dataToRead = static_cast<uint64_t>(count) * 8;
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
if (dataToRead != buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
@ -1150,8 +1147,7 @@ void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el)
ai_assert(data == end);
uint64_t dataToRead = static_cast<uint64_t>(count) * 8;
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
if (dataToRead != buff.size()) {
ParseError("Invalid read size (binary)",&el);
}

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

@ -451,6 +451,7 @@ void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char *szC
// now we need to skip any other skins ...
for (unsigned int i = 1; i < iNumSkins; ++i) {
SizeCheck(szCursor + 3 * sizeof(uint32_t));
iType = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t);
iWidth = *((uint32_t *)szCursor);

View File

@ -4,7 +4,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,
@ -42,15 +41,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file HMPLoader.h
* @brief Declaration of the HMP importer class
*/
#pragma once
#ifndef AI_HMPLOADER_H_INCLUDED
#define AI_HMPLOADER_H_INCLUDED
// internal headers
#include <assimp/BaseImporter.h>
#include "AssetLib/MDL/MDLLoader.h"
// internal headers
#include "AssetLib/HMP/HMPFileData.h"
#include "AssetLib/MDL/MDLLoader.h"
namespace Assimp {
using namespace HMP;
@ -58,39 +57,31 @@ using namespace HMP;
// ---------------------------------------------------------------------------
/** Used to load 3D GameStudio HMP files (terrains)
*/
class HMPImporter : public MDLImporter
{
class HMPImporter : public MDLImporter {
public:
HMPImporter();
~HMPImporter();
public:
~HMPImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
*/
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const;
const aiImporterDesc *GetInfo() const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler);
protected:
IOSystem *pIOHandler) override;
// -------------------------------------------------------------------
/** Import a HMP4 file
@ -142,12 +133,8 @@ protected:
*/
void ReadFirstSkin(unsigned int iNumSkins, const unsigned char *szCursor,
const unsigned char **szCursorOut);
private:
};
} // end of namespace Assimp
#endif // AI_HMPIMPORTER_H_INC

View File

@ -48,7 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Common/PolyTools.h"
#include "PostProcessing/ProcessHelper.h"
#include <assimp/Defines.h>
#include <iterator>
#include <tuple>
@ -513,7 +512,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;

View File

@ -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>();

View File

@ -137,9 +137,8 @@ bool IFCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
// note: this is the common identification for STEP-encoded files, so
// it is only unambiguous as long as we don't support any further
// file formats with STEP as their encoding.
const char *tokens[] = { "ISO-10303-21" };
const bool found(SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1));
return found;
static const char * const tokens[] = { "ISO-10303-21" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
}

View File

@ -53,14 +53,18 @@ namespace Assimp {
// TinyFormatter.h
namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter;
template <typename T, typename TR, typename A>
class basic_formatter;
typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>> format;
}
} // namespace Formatter
namespace STEP {
class DB;
}
class DB;
}
// -------------------------------------------------------------------------------------------
/** Load the IFC format, which is an open specification to describe building and construction
@ -69,52 +73,12 @@ namespace Assimp {
See http://en.wikipedia.org/wiki/Industry_Foundation_Classes
*/
// -------------------------------------------------------------------------------------------
class IFCImporter : public BaseImporter, public LogFunctions<IFCImporter>
{
class IFCImporter : public BaseImporter, public LogFunctions<IFCImporter> {
public:
IFCImporter();
~IFCImporter();
public:
// --------------------
bool CanRead( const std::string& pFile,
IOSystem* pIOHandler,
bool checkSig
) const;
protected:
// --------------------
const aiImporterDesc* GetInfo () const;
// --------------------
void SetupProperties(const Importer* pImp);
// --------------------
void InternReadFile( const std::string& pFile,
aiScene* pScene,
IOSystem* pIOHandler
);
private:
public:
// loader settings, publicly accessible via their corresponding AI_CONFIG constants
struct Settings
{
Settings()
: skipSpaceRepresentations()
, useCustomTriangulation()
, skipAnnotations()
, conicSamplingAngle(10.f)
, cylindricalTessellation(32)
{}
struct Settings {
Settings() :
skipSpaceRepresentations(), useCustomTriangulation(), skipAnnotations(), conicSamplingAngle(10.f), cylindricalTessellation(32) {}
bool skipSpaceRepresentations;
bool useCustomTriangulation;
@ -123,9 +87,27 @@ public:
int cylindricalTessellation;
};
IFCImporter();
~IFCImporter() override;
// --------------------
bool CanRead(const std::string &pFile,
IOSystem *pIOHandler,
bool checkSig) const override;
protected:
// --------------------
const aiImporterDesc *GetInfo() const override;
// --------------------
void SetupProperties(const Importer *pImp) override;
// --------------------
void InternReadFile(const std::string &pFile,
aiScene *pScene,
IOSystem *pIOHandler) override;
private:
Settings settings;
}; // !class IFCImporter

View File

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

View File

@ -49,7 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssetLib/IFC/IFCUtil.h"
#include "Common/PolyTools.h"
#include "PostProcessing/ProcessHelper.h"
#include <assimp/Defines.h>
namespace Assimp {
namespace IFC {

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 {
@ -139,12 +141,8 @@ 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)
{
std::shared_ptr<TempMesh> profileMesh2D) :
solid(solid), extrusionDir(extrusionDir), profileMesh(std::move(profileMesh)), profileMesh2D(std::move(profileMesh2D)) {
}
// ------------------------------------------------------------------------------

View File

@ -106,7 +106,7 @@ bool IRRImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
if (nullptr == pIOHandler) {
return true;
}
const char *tokens[] = { "irr_scene" };
static const char * const tokens[] = { "irr_scene" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
@ -132,7 +132,7 @@ void IRRImporter::SetupProperties(const Importer *pImp) {
}
// ------------------------------------------------------------------------------------------------
// Build a mesh tha consists of a single squad (a side of a skybox)
// Build a mesh that consists of a single squad (a side of a skybox)
aiMesh *IRRImporter::BuildSingleQuadMesh(const SkyboxVertex &v1,
const SkyboxVertex &v2,
const SkyboxVertex &v3,

View File

@ -65,22 +65,21 @@ namespace Assimp {
class IRRImporter : public BaseImporter, public IrrlichtBase {
public:
IRRImporter();
~IRRImporter();
~IRRImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
*/
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
const aiImporterDesc* GetInfo () const;
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
void SetupProperties(const Importer* pImp);
const aiImporterDesc* GetInfo () const override;
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
void SetupProperties(const Importer* pImp) override;
private:
/** Data structure for a scene-graph node animator
*/
struct Animator {

View File

@ -101,7 +101,7 @@ bool IRRMeshImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bo
* must return true here.
*/
if (!pIOHandler) return true;
const char *tokens[] = { "irrmesh" };
static const char * const tokens[] = { "irrmesh" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;

View File

@ -63,28 +63,28 @@ namespace Assimp {
class IRRMeshImporter : public BaseImporter, public IrrlichtBase {
public:
IRRMeshImporter();
~IRRMeshImporter();
~IRRMeshImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
*/
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc *GetInfo() const;
const aiImporterDesc *GetInfo() const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
IOSystem *pIOHandler) override;
};
} // end of namespace Assimp

View File

@ -9,7 +9,7 @@
#include <assimp/BaseImporter.h>
#include <assimp/XmlParser.h>
#include <stdint.h>
#include <cstdint>
struct aiMaterial;

View File

@ -41,15 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Declaration of the LWO importer class. */
#pragma once
#ifndef AI_LWOLOADER_H_INCLUDED
#define AI_LWOLOADER_H_INCLUDED
#include <assimp/types.h>
#include <assimp/material.h>
#include <assimp/DefaultLogger.hpp>
#include "LWOFileData.h"
#include <assimp/BaseImporter.h>
#include <assimp/material.h>
#include <assimp/DefaultLogger.hpp>
#include <map>
@ -70,41 +69,38 @@ using namespace LWO;
* they aren't specific to one format version
*/
// ---------------------------------------------------------------------------
class LWOImporter : public BaseImporter
{
class LWOImporter : public BaseImporter {
public:
LWOImporter();
~LWOImporter();
~LWOImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
*/
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
bool checkSig) const override;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer *pImp) override;
protected:
// -------------------------------------------------------------------
// Get list of supported extensions
const aiImporterDesc* GetInfo () const;
const aiImporterDesc *GetInfo() const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler);
IOSystem *pIOHandler) override;
private:
// -------------------------------------------------------------------
/** Loads a LWO file in the older LWOB format (LW < 6)
*/
@ -115,7 +111,6 @@ private:
*/
void LoadLWO2File();
// -------------------------------------------------------------------
/** Parsing functions used for all file format versions
*/
@ -125,7 +120,6 @@ private:
inline uint16_t GetU2();
inline uint8_t GetU1();
// -------------------------------------------------------------------
/** Loads a surface chunk from an LWOB file
* @param size Maximum size to be read, in bytes.
@ -270,7 +264,6 @@ private:
*/
void ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat);
// -------------------------------------------------------------------
/** Get a list of all UV/VC channels required by a specific surface.
*
@ -337,7 +330,6 @@ private:
void ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &smoothingGroups,
const LWO::Surface &surface);
// -------------------------------------------------------------------
/** Setup a new texture after the corresponding chunk was
* encountered in the file.
@ -349,7 +341,6 @@ private:
unsigned int size);
protected:
/** true if the file is a LWO2 file*/
bool mIsLWO2;
@ -400,10 +391,8 @@ protected:
bool hasNamedLayer;
};
// ------------------------------------------------------------------------------------------------
inline
float LWOImporter::GetF4() {
inline float LWOImporter::GetF4() {
float f;
::memcpy(&f, mFileBuffer, 4);
mFileBuffer += 4;
@ -412,8 +401,7 @@ float LWOImporter::GetF4() {
}
// ------------------------------------------------------------------------------------------------
inline uint32_t LWOImporter::GetU4()
{
inline uint32_t LWOImporter::GetU4() {
uint32_t f;
::memcpy(&f, mFileBuffer, 4);
mFileBuffer += 4;
@ -422,8 +410,7 @@ inline uint32_t LWOImporter::GetU4()
}
// ------------------------------------------------------------------------------------------------
inline uint16_t LWOImporter::GetU2()
{
inline uint16_t LWOImporter::GetU2() {
uint16_t f;
::memcpy(&f, mFileBuffer, 2);
mFileBuffer += 2;
@ -432,43 +419,40 @@ inline uint16_t LWOImporter::GetU2()
}
// ------------------------------------------------------------------------------------------------
inline uint8_t LWOImporter::GetU1()
{
inline uint8_t LWOImporter::GetU1() {
return *mFileBuffer++;
}
// ------------------------------------------------------------------------------------------------
inline int LWOImporter::ReadVSizedIntLWO2(uint8_t*& inout)
{
inline int LWOImporter::ReadVSizedIntLWO2(uint8_t *&inout) {
int i;
int c = *inout;inout++;
if(c != 0xFF)
{
int c = *inout;
inout++;
if (c != 0xFF) {
i = c << 8;
c = *inout;inout++;
c = *inout;
inout++;
i |= c;
}
else
{
c = *inout;inout++;
} else {
c = *inout;
inout++;
i = c << 16;
c = *inout;inout++;
c = *inout;
inout++;
i |= c << 8;
c = *inout;inout++;
c = *inout;
inout++;
i |= c;
}
return i;
}
// ------------------------------------------------------------------------------------------------
inline void LWOImporter::GetS0(std::string& out,unsigned int max)
{
inline void LWOImporter::GetS0(std::string &out, unsigned int max) {
unsigned int iCursor = 0;
const char *sz = (const char *)mFileBuffer;
while (*mFileBuffer)
{
if (++iCursor > max)
{
while (*mFileBuffer) {
if (++iCursor > max) {
ASSIMP_LOG_WARN("LWO: Invalid file, string is is too long");
break;
}
@ -479,8 +463,6 @@ inline void LWOImporter::GetS0(std::string& out,unsigned int max)
mFileBuffer += (len & 0x1 ? 1 : 2);
}
} // end of namespace Assimp
#endif // AI_LWOIMPORTER_H_INCLUDED

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;

View File

@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file LWSLoader.h
* @brief Declaration of the LightWave scene importer class.
*/
#pragma once
#ifndef AI_LWSLOADER_H_INCLUDED
#define AI_LWSLOADER_H_INCLUDED
@ -53,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct aiImporterDesc;
namespace Assimp {
class BatchLoader;
class Importer;
class IOSystem;
@ -172,26 +174,26 @@ struct NodeDesc {
class LWSImporter : public BaseImporter {
public:
LWSImporter();
~LWSImporter();
~LWSImporter() override;
// -------------------------------------------------------------------
// Check whether we can read a specific file
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
// Get list of supported extensions
const aiImporterDesc *GetInfo() const;
const aiImporterDesc *GetInfo() const override;
// -------------------------------------------------------------------
// Import file into given scene data structure
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
IOSystem *pIOHandler) override;
// -------------------------------------------------------------------
// Setup import properties
void SetupProperties(const Importer *pImp);
void SetupProperties(const Importer *pImp) override;
private:
// -------------------------------------------------------------------
@ -226,9 +228,7 @@ private:
private:
bool configSpeedFlag;
IOSystem *io;
double first, last, fps;
bool noSkeletonMesh;
};

View File

@ -76,7 +76,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Currently supports static meshes, vertex colors, materials, textures
*
* For animation, it would require the following conversions:
* - aiNode (bones) -> m3d_t.bone (with parent id, position vector and oriantation quaternion)
* - aiNode (bones) -> m3d_t.bone (with parent id, position vector and orientation quaternion)
* - aiMesh.aiBone -> m3d_t.skin (per vertex, with bone id, weight pairs)
* - aiAnimation -> m3d_action (frame with timestamp and list of bone id, position, orientation
* triplets, instead of per bone timestamp + lists)

View File

@ -233,12 +233,12 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
ASSIMP_LOG_DEBUG("M3D: importMaterials ", mScene->mNumMaterials);
// add a default material as first
aiMaterial *mat = new aiMaterial;
mat->AddProperty(&name, AI_MATKEY_NAME);
aiMaterial *defaultMat = new aiMaterial;
defaultMat->AddProperty(&name, AI_MATKEY_NAME);
c.a = 1.0f;
c.b = c.g = c.r = 0.6f;
mat->AddProperty(&c, 1, AI_MATKEY_COLOR_DIFFUSE);
mScene->mMaterials[0] = mat;
defaultMat->AddProperty(&c, 1, AI_MATKEY_COLOR_DIFFUSE);
mScene->mMaterials[0] = defaultMat;
if (!m3d->nummaterial || !m3d->material) {
return;
@ -296,16 +296,16 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
}
// texture map properties
if (m->prop[j].type >= 128 && aiTxProps[k].pKey &&
// extra check, should never happen, do we have the refered texture?
// extra check, should never happen, do we have the referred texture?
m->prop[j].value.textureid < m3d->numtexture &&
m3d->texture[m->prop[j].value.textureid].name) {
name.Set(std::string(std::string(m3d->texture[m->prop[j].value.textureid].name) + ".png"));
mat->AddProperty(&name, aiTxProps[k].pKey, aiTxProps[k].type, aiTxProps[k].index);
newMat->AddProperty(&name, aiTxProps[k].pKey, aiTxProps[k].type, aiTxProps[k].index);
n = 0;
mat->AddProperty(&n, 1, _AI_MATKEY_UVWSRC_BASE, aiProps[k].type, aiProps[k].index);
newMat->AddProperty(&n, 1, _AI_MATKEY_UVWSRC_BASE, aiProps[k].type, aiProps[k].index);
}
}
mScene->mMaterials[i + 1] = mat;
mScene->mMaterials[i + 1] = newMat;
}
}
@ -474,7 +474,7 @@ void M3DImporter::importMeshes(const M3DWrapper &m3d) {
mScene->mMeshes = new aiMesh *[mScene->mNumMeshes];
std::copy(meshes->begin(), meshes->end(), mScene->mMeshes);
// create mesh indeces in root node
// create mesh indices in root node
mScene->mRootNode->mNumMeshes = static_cast<unsigned int>(meshes->size());
mScene->mRootNode->mMeshes = new unsigned int[meshes->size()];
for (i = 0; i < meshes->size(); i++) {
@ -655,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);
@ -688,7 +688,7 @@ void M3DImporter::calculateOffsetMatrix(aiNode *pNode, aiMatrix4x4 *m) {
// ------------------------------------------------------------------------------------------------
// because M3D has a global mesh, global vertex ids and stores materialid on the face, we need
// temporary lists to collect data for an aiMesh, which requires local arrays and local indeces
// temporary lists to collect data for an aiMesh, which requires local arrays and local indices
// this function fills up an aiMesh with those temporary lists
void M3DImporter::populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector<aiFace> *faces, std::vector<aiVector3D> *vertices,
std::vector<aiVector3D> *normals, std::vector<aiVector3D> *texcoords, std::vector<aiColor4D> *colors,

View File

@ -65,21 +65,20 @@ class M3DImporter : public BaseImporter {
public:
/// \brief Default constructor
M3DImporter();
~M3DImporter() override {}
public:
/// \brief Returns whether the class can handle the format of the given file.
/// \remark See BaseImporter::CanRead() for details.
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
private:
aiScene *mScene = nullptr; // the scene to import to
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
protected:
//! \brief Appends the supported extension.
const aiImporterDesc *GetInfo() const;
const aiImporterDesc *GetInfo() const override;
//! \brief File import implementation.
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
private:
void importMaterials(const M3DWrapper &m3d);
void importTextures(const M3DWrapper &m3d);
void importMeshes(const M3DWrapper &m3d);
@ -89,11 +88,14 @@ 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);
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);
private:
aiScene *mScene = nullptr; // the scene to import to
};
} // Namespace Assimp

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>
@ -55,44 +56,75 @@ 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
// 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);
/// Theclasss destructor.
~M3DWrapper();
/// Will reset the wrapper, all data will become nullptr.
void reset();
// Name
inline std::string Name() const {
if (m3d_) return std::string(m3d_->name);
// The Name access, empty string returned when no m3d instance.
std::string Name() const;
/// Executes a save.
unsigned char *Save(int quality, int flags, unsigned int &size);
/// Clearer
void ClearSave();
/// True for m3d instance exists.
explicit operator bool() const;
// Allow direct access to M3D API
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();
}
// Execute a save
unsigned char *Save(int quality, int flags, unsigned int &size);
void ClearSave();
inline M3DWrapper::operator bool() const {
return m3d_ != nullptr;
}
inline explicit operator bool() const { return m3d_ != nullptr; }
inline m3d_t *M3DWrapper::operator->() const {
return m3d_;
}
inline m3d_t *M3DWrapper::M3D() const {
return m3d_;
}
// Allow direct access to M3D API
inline m3d_t *operator->() const { return m3d_; }
inline m3d_t *M3D() const { return m3d_; }
};
} // namespace Assimp
#endif

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,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,
@ -43,13 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file MD2Loader.h
* @brief Declaration of the .MD2 importer class.
*/
#pragma once
#ifndef AI_MD2LOADER_H_INCLUDED
#define AI_MD2LOADER_H_INCLUDED
#include <assimp/BaseImporter.h>
#include <assimp/types.h>
#include <assimp/ByteSwapper.h>
#include "MD2FileData.h"
#include <assimp/BaseImporter.h>
#include <assimp/ByteSwapper.h>
#include <assimp/types.h>
struct aiNode;
@ -60,44 +60,37 @@ using namespace MD2;
// ---------------------------------------------------------------------------
/** Importer class for MD2
*/
class MD2Importer : public BaseImporter
{
class MD2Importer : public BaseImporter {
public:
MD2Importer();
~MD2Importer();
public:
~MD2Importer() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
bool checkSig) const override;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer *pImp) override;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const;
const aiImporterDesc *GetInfo() const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler);
IOSystem *pIOHandler) override;
// -------------------------------------------------------------------
/** Validate the header of the file
@ -105,7 +98,6 @@ protected:
void ValidateHeader();
protected:
/** Configuration option: frame to be loaded */
unsigned int configFrameID;

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