Merge branch 'master' into cmake_targets_determine_lib_path

pull/3035/head
Kim Kulling 2020-03-24 11:56:17 +01:00 committed by GitHub
commit fb32072391
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
245 changed files with 23171 additions and 22416 deletions

View File

@ -70,8 +70,8 @@ IncludeCategories:
- Regex: '^<.*'
Priority: 3
# IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true
IndentPPDirectives: AfterHash
IndentCaseLabels: false
#IndentPPDirectives: AfterHash
IndentWidth: 4
# IndentWrappedFunctionNames: false
# JavaScriptQuotes: Leave

22
.github/workflows/ccpp.yml vendored 100644
View File

@ -0,0 +1,22 @@
name: C/C++ CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build-ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: configure
run: cmake CMakeLists.txt
- name: build
run: cmake --build .
- name: test
run: cd bin && ./unit

View File

@ -39,9 +39,9 @@ SET(CMAKE_POLICY_DEFAULT_CMP0074 NEW)
CMAKE_MINIMUM_REQUIRED( VERSION 3.0 )
# Toggles the use of the hunter package manager
option(HUNTER_ENABLED "Enable Hunter package manager support" OFF)
option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
include("cmake/HunterGate.cmake")
HunterGate(
URL "https://github.com/ruslo/hunter/archive/v0.23.176.tar.gz"
@ -60,7 +60,7 @@ OPTION( BUILD_SHARED_LIBS
ON
)
OPTION( BUILD_FRAMEWORK
OPTION( ASSIMP_BUILD_FRAMEWORK
"Build package as Mac OS X Framework bundle."
OFF
)
@ -101,7 +101,7 @@ OPTION ( ASSIMP_COVERALLS
OFF
)
OPTION( ASSIMP_INSTALL
"DIsable this if you want to use assimp as a submodule."
"Disable this if you want to use assimp as a submodule."
ON
)
OPTION ( ASSIMP_ERROR_MAX
@ -120,25 +120,25 @@ OPTION ( ASSIMP_UBSAN
"Enable Undefined Behavior sanitizer."
OFF
)
OPTION ( SYSTEM_IRRXML
OPTION ( ASSIMP_SYSTEM_IRRXML
"Use system installed Irrlicht/IrrXML library."
OFF
)
OPTION ( BUILD_DOCS
OPTION ( ASSIMP_BUILD_DOCS
"Build documentation using Doxygen."
OFF
)
OPTION( INJECT_DEBUG_POSTFIX
OPTION( ASSIMP_INJECT_DEBUG_POSTFIX
"Inject debug postfix in .a/.so/.dll lib names"
ON
)
OPTION ( IGNORE_GIT_HASH
OPTION ( ASSIMP_IGNORE_GIT_HASH
"Don't call git to get the hash."
OFF
)
IF (IOS AND NOT HUNTER_ENABLED)
IF (IOS AND NOT ASSIMP_HUNTER_ENABLED)
IF (NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Release")
ENDIF ()
@ -161,7 +161,7 @@ IF(MSVC)
ENDIF()
ENDIF()
IF (BUILD_FRAMEWORK)
IF (ASSIMP_BUILD_FRAMEWORK)
SET (BUILD_SHARED_LIBS ON)
MESSAGE(STATUS "Framework bundle building enabled")
ENDIF()
@ -181,12 +181,12 @@ SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VER
SET (ASSIMP_SOVERSION 5)
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
if(NOT HUNTER_ENABLED)
if(NOT ASSIMP_HUNTER_ENABLED)
# Enable C++11 support globally
set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
endif()
IF(NOT IGNORE_GIT_HASH)
IF(NOT ASSIMP_IGNORE_GIT_HASH)
# Get the current working branch
EXECUTE_PROCESS(
COMMAND git rev-parse --abbrev-ref HEAD
@ -245,7 +245,7 @@ ENDIF()
# Grouped compiler settings
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
IF(NOT HUNTER_ENABLED)
IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_FLAGS "-fPIC -std=c++0x ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
ENDIF()
@ -255,15 +255,14 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
SET(LIBSTDC++_LIBRARIES -lstdc++)
ELSEIF(MSVC)
# enable multi-core compilation with MSVC
ADD_COMPILE_OPTIONS(/MP)
ADD_COMPILE_OPTIONS( /bigobj )
ADD_COMPILE_OPTIONS(/MP /bigobj /W4 /WX )
# disable "elements of array '' will be default initialized" warning on MSVC2013
IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351)
ENDIF()
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
IF(NOT HUNTER_ENABLED)
IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
ENDIF()
@ -275,7 +274,7 @@ ELSEIF( CMAKE_COMPILER_IS_MINGW )
ELSEIF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.3)
message(WARNING "MinGW is old, if you experience errors, update MinGW.")
ENDIF()
IF(NOT HUNTER_ENABLED)
IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
ENDIF()
@ -284,7 +283,7 @@ ELSEIF( CMAKE_COMPILER_IS_MINGW )
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF()
IF ( IOS AND NOT HUNTER_ENABLED)
IF ( IOS AND NOT ASSIMP_HUNTER_ENABLED)
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
@ -361,7 +360,7 @@ SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE STRING
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
IF (INJECT_DEBUG_POSTFIX AND (is_multi_config OR CMAKE_BUILD_TYPE STREQUAL "Debug"))
IF (ASSIMP_INJECT_DEBUG_POSTFIX AND (is_multi_config OR CMAKE_BUILD_TYPE STREQUAL "Debug"))
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools")
ELSE()
SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Debug Postfix for lib, samples and tools")
@ -374,7 +373,7 @@ IF (NOT TARGET uninstall)
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
ENDIF()
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
set(INCLUDE_INSTALL_DIR "include")
@ -441,18 +440,18 @@ ELSE()
DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
ENDIF()
IF( BUILD_DOCS )
IF( ASSIMP_BUILD_DOCS )
ADD_SUBDIRECTORY(doc)
ENDIF()
# Look for system installed irrXML
IF ( SYSTEM_IRRXML )
IF ( ASSIMP_SYSTEM_IRRXML )
FIND_PACKAGE( IrrXML REQUIRED )
ENDIF()
# Search for external dependencies, and build them from source if not found
# Search for zlib
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(ZLIB)
find_package(ZLIB CONFIG REQUIRED)
@ -576,7 +575,7 @@ ELSE ()
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
ENDIF ()
IF(NOT HUNTER_ENABLED)
IF(NOT ASSIMP_HUNTER_ENABLED)
ADD_SUBDIRECTORY(contrib)
ENDIF()

View File

@ -2,6 +2,7 @@ Open Asset Import Library (assimp)
==================================
A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
### Current project status ###
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
<a href="https://scan.coverity.com/projects/5607">

View File

@ -80,7 +80,7 @@ namespace {
{
chunk_start_pos = writer.GetCurrentPos();
writer.PutU2(chunk_type);
writer.PutU4(CHUNK_SIZE_NOT_SET);
writer.PutU4((uint32_t)CHUNK_SIZE_NOT_SET);
}
~ChunkWriter() {
@ -193,21 +193,21 @@ Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr<IOStream> &outfile, co
CollectTrafos(scene->mRootNode, trafos);
CollectMeshes(scene->mRootNode, meshes);
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAIN);
ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_MAIN);
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_OBJMESH);
WriteMaterials();
WriteMeshes();
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);
ChunkWriter curChunk1(writer, Discreet3DS::CHUNK_MASTER_SCALE);
writer.PutF4(1.0f);
}
}
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_KEYFRAMER);
WriteHierarchy(*scene->mRootNode, -1, -1);
}
}
@ -223,9 +223,9 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling
{
// 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_TRACKINFO);
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
// Assimp node names are unique and distinct from all mesh-node
// names we generate; thus we can use them as-is
@ -237,7 +237,7 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling
int16_t hierarchy_pos = static_cast<int16_t>(seq);
if (sibling_level != -1) {
hierarchy_pos = sibling_level;
hierarchy_pos =(uint16_t) sibling_level;
}
// Write the hierarchy position
@ -262,7 +262,7 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling
const unsigned int mesh_idx = node.mMeshes[i];
const aiMesh& mesh = *scene->mMeshes[mesh_idx];
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRACKINFO);
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
WriteString(GetMeshName(mesh, mesh_idx, node));
@ -279,7 +279,7 @@ int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling
void Discreet3DSExporter::WriteMaterials()
{
for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL);
ChunkWriter curRootChunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL);
const aiMaterial& mat = *scene->mMaterials[i];
{
@ -290,22 +290,22 @@ void Discreet3DSExporter::WriteMaterials()
aiColor3D color;
if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE);
WriteColor(color);
}
if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
WriteColor(color);
}
if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
WriteColor(color);
}
if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
WriteColor(color);
}
@ -389,14 +389,14 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type
ChunkWriter chunk(writer, chunk_flags);
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPFILE);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAPFILE);
WriteString(path);
}
WritePercentChunk(blend);
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING);
uint16_t val = 0; // WRAP
if (map_mode[0] == aiTextureMapMode_Mirror) {
val = 0x2;
@ -447,7 +447,7 @@ void Discreet3DSExporter::WriteMeshes()
// Vertices in world space
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_VERTLIST);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_VERTLIST);
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
writer.PutU2(count);
@ -461,7 +461,7 @@ void Discreet3DSExporter::WriteMeshes()
// UV coordinates
if (mesh.HasTextureCoords(0)) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPLIST);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAPLIST);
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
writer.PutU2(count);
@ -474,7 +474,7 @@ void Discreet3DSExporter::WriteMeshes()
// Faces (indices)
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACELIST);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_FACELIST);
ai_assert(mesh.mNumFaces <= 0xffff);
@ -513,7 +513,7 @@ void Discreet3DSExporter::WriteMeshes()
// Transformation matrix by which the mesh vertices have been pre-transformed with.
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRMATRIX);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_TRMATRIX);
for (unsigned int r = 0; r < 4; ++r) {
for (unsigned int c = 0; c < 3; ++c) {
writer.PutF4(trafo[r][c]);
@ -526,7 +526,7 @@ void Discreet3DSExporter::WriteMeshes()
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh)
{
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACEMAT);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_FACEMAT);
const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex);
WriteString(name);
@ -559,7 +559,7 @@ void Discreet3DSExporter::WriteString(const aiString& s) {
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteColor(const aiColor3D& color) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_RGBF);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_RGBF);
writer.PutF4(color.r);
writer.PutF4(color.g);
writer.PutF4(color.b);
@ -567,13 +567,13 @@ void Discreet3DSExporter::WriteColor(const aiColor3D& color) {
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WritePercentChunk(float f) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTF);
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_PERCENTF);
writer.PutF4(f);
}
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WritePercentChunk(double f) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTD);
ChunkWriter ccurChunkhunk(writer, Discreet3DS::CHUNK_PERCENTD);
writer.PutF8(f);
}

View File

@ -45,14 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_3DSFILEHELPER_H_INC
#define AI_3DSFILEHELPER_H_INC
#include <assimp/SpatialSort.h>
#include <assimp/SmoothingGroups.h>
#include <assimp/SpatialSort.h>
#include <assimp/StringUtils.h>
#include <assimp/qnan.h>
#include <assimp/material.h>
#include <assimp/anim.h>
#include <assimp/camera.h>
#include <assimp/light.h>
#include <assimp/anim.h>
#include <assimp/material.h>
#include <assimp/qnan.h>
#include <stdio.h> //sprintf
namespace Assimp {
@ -81,11 +81,9 @@ public:
uint32_t Size;
} PACK_STRUCT;
//! Used for shading field in material3ds structure
//! From AutoDesk 3ds SDK
typedef enum
{
typedef enum {
// translated to gouraud shading with wireframe active
Wire = 0x0,
@ -109,8 +107,7 @@ public:
} shadetype3ds;
// Flags for animated keys
enum
{
enum {
KEY_USE_TENS = 0x1,
KEY_USE_CONT = 0x2,
KEY_USE_BIAS = 0x4,
@ -118,8 +115,7 @@ public:
KEY_USE_EASE_FROM = 0x10
};
enum
{
enum {
// ********************************************************************
// Basic chunks which can be found everywhere in the file
@ -322,26 +318,77 @@ public:
// ---------------------------------------------------------------------------
/** Helper structure representing a 3ds mesh face */
struct Face : public FaceWithSmoothingGroup
{
struct Face : public FaceWithSmoothingGroup {
};
#ifdef _WIN32
# pragma warning(disable : 4315)
#endif
// ---------------------------------------------------------------------------
/** Helper structure representing a texture */
struct Texture {
//! Default constructor
Texture() AI_NO_EXCEPT
: mOffsetU (0.0)
, mOffsetV (0.0)
, mScaleU (1.0)
, mScaleV (1.0)
, mRotation (0.0)
, mMapMode (aiTextureMapMode_Wrap)
, bPrivate()
, iUVSrc (0) {
: mTextureBlend(0.0f),
mMapName(),
mOffsetU(0.0),
mOffsetV(0.0),
mScaleU(1.0),
mScaleV(1.0),
mRotation(0.0),
mMapMode(aiTextureMapMode_Wrap),
bPrivate(),
iUVSrc(0) {
mTextureBlend = get_qnan();
}
Texture(const Texture &other) :
mTextureBlend(other.mTextureBlend),
mMapName(other.mMapName),
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
}
Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(std::move(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)) {
// empty
}
Texture &operator=(Texture &&other) AI_NO_EXCEPT {
if (this == &other) {
return *this;
}
mTextureBlend = std::move(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);
return *this;
}
//! Specifies the blend factor for the texture
ai_real mTextureBlend;
@ -367,55 +414,59 @@ struct Texture {
// ---------------------------------------------------------------------------
/** Helper structure representing a 3ds material */
struct Material
{
struct Material {
//! Default constructor has been deleted
Material() = delete;
//! Constructor with explicit name
explicit Material(const std::string &name)
: mName(name)
, mDiffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
, mSpecularExponent ( ai_real( 0.0 ) )
, mShininessStrength ( ai_real( 1.0 ) )
, mShading(Discreet3DS::Gouraud)
, mTransparency ( ai_real( 1.0 ) )
, mBumpHeight ( ai_real( 1.0 ) )
, mTwoSided (false)
{
Material() :
mName(),
mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
mSpecularExponent(ai_real(0.0)),
mShininessStrength(ai_real(1.0)),
mShading(Discreet3DS::Gouraud),
mTransparency(ai_real(1.0)),
mBumpHeight(ai_real(1.0)),
mTwoSided(false) {
// empty
}
//! Constructor with explicit name
explicit Material(const std::string &name) :
mName(name),
mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
mSpecularExponent(ai_real(0.0)),
mShininessStrength(ai_real(1.0)),
mShading(Discreet3DS::Gouraud),
mTransparency(ai_real(1.0)),
mBumpHeight(ai_real(1.0)),
mTwoSided(false) {
// empty
}
Material(const Material &other) = default;
Material &operator=(const Material &other) = default;
//! 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))
, sTexDiffuse(std::move(other.sTexDiffuse))
, sTexOpacity(std::move(other.sTexOpacity))
, sTexSpecular(std::move(other.sTexSpecular))
, sTexReflective(std::move(other.sTexReflective))
, 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))
, sTexAmbient(std::move(other.sTexAmbient))
, mTwoSided(std::move(other.mTwoSided))
{
: 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)),
sTexDiffuse(std::move(other.sTexDiffuse)),
sTexOpacity(std::move(other.sTexOpacity)),
sTexSpecular(std::move(other.sTexSpecular)),
sTexReflective(std::move(other.sTexReflective)),
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)),
sTexAmbient(std::move(other.sTexAmbient)),
mTwoSided(std::move(other.mTwoSided)) {
}
Material &operator=(Material &&other) AI_NO_EXCEPT {
if (this == &other) {
return *this;
@ -444,9 +495,9 @@ struct Material
return *this;
}
virtual ~Material() {}
virtual ~Material() {
// empty
}
//! Name of the material
std::string mName;
@ -491,18 +542,15 @@ struct Material
// ---------------------------------------------------------------------------
/** Helper structure to represent a 3ds file mesh */
struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
{
struct Mesh : public MeshWithSmoothingGroups<D3DS::Face> {
//! Default constructor has been deleted
Mesh() = delete;
//! Constructor with explicit name
explicit Mesh(const std::string &name)
: mName(name)
{
explicit Mesh(const std::string &name) :
mName(name) {
}
//! Name of the mesh
std::string mName;
@ -519,53 +567,39 @@ struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
// ---------------------------------------------------------------------------
/** Float key - quite similar to aiVectorKey and aiQuatKey. Both are in the
C-API, so it would be difficult to make them a template. */
struct aiFloatKey
{
struct aiFloatKey {
double mTime; ///< The time of this key
ai_real mValue; ///< The value of this key
#ifdef __cplusplus
// time is not compared
bool operator == (const aiFloatKey& o) const
{return o.mValue == this->mValue;}
bool operator==(const aiFloatKey &o) const { return o.mValue == this->mValue; }
bool operator != (const aiFloatKey& o) const
{return o.mValue != this->mValue;}
bool operator!=(const aiFloatKey &o) const { return o.mValue != this->mValue; }
// Only time is compared. This operator is defined
// for use with std::sort
bool operator < (const aiFloatKey& o) const
{return mTime < o.mTime;}
bool operator<(const aiFloatKey &o) const { return mTime < o.mTime; }
bool operator > (const aiFloatKey& o) const
{return mTime > o.mTime;}
bool operator>(const aiFloatKey &o) const { return mTime > o.mTime; }
#endif
};
// ---------------------------------------------------------------------------
/** Helper structure to represent a 3ds file node */
struct Node
{
struct Node {
Node() = delete;
explicit Node(const std::string &name)
: mParent(NULL)
, mName(name)
, mInstanceNumber(0)
, mHierarchyPos (0)
, mHierarchyIndex (0)
, mInstanceCount (1)
{
explicit Node(const std::string &name) :
mParent(NULL), mName(name), mInstanceNumber(0), mHierarchyPos(0), mHierarchyIndex(0), mInstanceCount(1) {
aRotationKeys.reserve(20);
aPositionKeys.reserve(20);
aScalingKeys.reserve(20);
}
~Node()
{
~Node() {
for (unsigned int i = 0; i < mChildren.size(); ++i)
delete mChildren[i];
}
@ -600,7 +634,6 @@ struct Node
//! Scaling keys loaded from the file
std::vector<aiVectorKey> aScalingKeys;
// For target lights (spot lights and directional lights):
// The position of the target
std::vector<aiVectorKey> aTargetPositionKeys;
@ -616,8 +649,7 @@ struct Node
//! Add a child node, setup the right parent node for it
//! \param pc Node to be 'adopted'
inline Node& push_back(Node* pc)
{
inline Node &push_back(Node *pc) {
mChildren.push_back(pc);
pc->mParent = this;
return *this;
@ -625,8 +657,7 @@ struct Node
};
// ---------------------------------------------------------------------------
/** Helper structure analogue to aiScene */
struct Scene
{
struct Scene {
//! List of all materials loaded
//! NOTE: 3ds references materials globally
std::vector<Material> mMaterials;
@ -645,7 +676,6 @@ struct Scene
// Node* pcRootNode;
};
} // end of namespace D3DS
} // end of namespace Assimp

View File

@ -158,13 +158,13 @@ void Discreet3DSImporter::SetupProperties(const Importer* /*pImp*/)
void Discreet3DSImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
StreamReaderLE theStream(pIOHandler->Open(pFile,"rb"));
// We should have at least one chunk
if (stream.GetRemainingSize() < 16) {
if (theStream.GetRemainingSize() < 16) {
throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile);
}
this->stream = &stream;
this->stream = &theStream;
// Allocate our temporary 3DS representation
D3DS::Scene _scene;
@ -599,16 +599,19 @@ void Discreet3DSImporter::InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCur
// ------------------------------------------------------------------------------------------------
// Find a node with a specific name in the import hierarchy
D3DS::Node* FindNode(D3DS::Node* root, const std::string& name)
{
if (root->mName == name)
D3DS::Node* FindNode(D3DS::Node* root, const std::string& name) {
if (root->mName == name) {
return root;
}
for (std::vector<D3DS::Node*>::iterator it = root->mChildren.begin();it != root->mChildren.end(); ++it) {
D3DS::Node* nd;
if (( nd = FindNode(*it,name)))
D3DS::Node *nd = FindNode(*it, name);
if (nullptr != nd) {
return nd;
}
return NULL;
}
return nullptr;
}
// ------------------------------------------------------------------------------------------------

View File

@ -256,13 +256,13 @@ void D3MFExporter::writeBaseMaterials() {
tmp.clear();
hexDiffuseColor = "#";
tmp = DecimalToHexa( color.r );
tmp = DecimalToHexa( (ai_real) color.r );
hexDiffuseColor += tmp;
tmp = DecimalToHexa( color.g );
tmp = DecimalToHexa((ai_real)color.g);
hexDiffuseColor += tmp;
tmp = DecimalToHexa( color.b );
tmp = DecimalToHexa((ai_real)color.b);
hexDiffuseColor += tmp;
tmp = DecimalToHexa( color.a );
tmp = DecimalToHexa((ai_real)color.a);
hexDiffuseColor += tmp;
} else {
hexDiffuseColor = "#FFFFFFFF";

View File

@ -1,4 +1,3 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
@ -6,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -44,25 +41,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the AC3D importer class */
#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
// internal headers
#include "ACLoader.h"
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/Subdivision.h>
#include "Common/Importer.h"
#include <assimp/BaseImporter.h>
#include <assimp/Importer.hpp>
#include <assimp/ParsingUtils.h>
#include <assimp/Subdivision.h>
#include <assimp/config.h>
#include <assimp/fast_atof.h>
#include <assimp/importerdesc.h>
#include <assimp/light.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/material.h>
#include <assimp/scene.h>
#include <assimp/config.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/importerdesc.h>
#include <assimp/Importer.hpp>
#include <memory>
using namespace Assimp;
@ -82,83 +77,82 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// skip to the next token
#define AI_AC_SKIP_TO_NEXT_TOKEN() \
if (!SkipSpaces(&buffer)) \
{ \
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL"); \
continue; \
inline const char *AcSkipToNextToken(const char *buffer) {
if (!SkipSpaces(&buffer)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL");
}
return buffer;
}
// ------------------------------------------------------------------------------------------------
// read a string (may be enclosed in double quotation marks). buffer must point to "
#define AI_AC_GET_STRING(out) \
if (*buffer == '\0') { \
throw DeadlyImportError("AC3D: Unexpected EOF in string"); \
} \
++buffer; \
const char* sz = buffer; \
while ('\"' != *buffer) \
{ \
if (IsLineEnd( *buffer )) \
{ \
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string"); \
out = "ERROR"; \
break; \
} \
++buffer; \
} \
if (IsLineEnd( *buffer ))continue; \
out = std::string(sz,(unsigned int)(buffer-sz)); \
inline const char *AcGetString(const char *buffer, std::string &out) {
if (*buffer == '\0') {
throw DeadlyImportError("AC3D: Unexpected EOF in string");
}
++buffer;
const char *sz = buffer;
while ('\"' != *buffer) {
if (IsLineEnd(*buffer)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string");
out = "ERROR";
break;
}
++buffer;
}
if (IsLineEnd(*buffer)) {
return buffer;
}
out = std::string(sz, (unsigned int)(buffer - sz));
++buffer;
return buffer;
}
// ------------------------------------------------------------------------------------------------
// read 1 to n floats prefixed with an optional predefined identifier
#define AI_AC_CHECKED_LOAD_FLOAT_ARRAY(name,name_length,num,out) \
AI_AC_SKIP_TO_NEXT_TOKEN(); \
if (name_length) \
{ \
if (strncmp(buffer,name,name_length) || !IsSpace(buffer[name_length])) \
{ \
ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " name " was expected."); \
continue; \
} \
buffer += name_length+1; \
} \
for (unsigned int i = 0; i < num;++i) \
{ \
AI_AC_SKIP_TO_NEXT_TOKEN(); \
buffer = fast_atoreal_move<float>(buffer,((float*)out)[i]); \
template <class T>
inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name, size_t name_length, size_t num, T *out) {
buffer = AcSkipToNextToken(buffer);
if (0 != name_length) {
if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) {
ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " + std::string(name) + " was expected.");
return buffer;
}
buffer += name_length + 1;
}
for (unsigned int _i = 0; _i < num; ++_i) {
buffer = AcSkipToNextToken(buffer);
buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]);
}
return buffer;
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
AC3DImporter::AC3DImporter()
: buffer(),
AC3DImporter::AC3DImporter() :
buffer(),
configSplitBFCull(),
configEvalSubdivision(),
mNumMeshes(),
mLights(),
lights(),
groups(),
polys(),
worlds()
{
mLightsCounter(0),
mGroupsCounter(0),
mPolysCounter(0),
mWorldsCounter(0) {
// nothing to be done here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
AC3DImporter::~AC3DImporter()
{
AC3DImporter::~AC3DImporter() {
// nothing to be done here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool AC3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
std::string extension = GetExtension(pFile);
// fixme: are acc and ac3d *really* used? Some sources say they are
@ -174,23 +168,20 @@ bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------
// Loader meta information
const aiImporterDesc* AC3DImporter::GetInfo () const
{
const aiImporterDesc *AC3DImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Get a pointer to the next line from the file
bool AC3DImporter::GetNextLine( )
{
bool AC3DImporter::GetNextLine() {
SkipLine(&buffer);
return SkipSpaces(&buffer);
}
// ------------------------------------------------------------------------------------------------
// Parse an object section in an AC file
void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
{
void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
if (!TokenMatch(buffer, "OBJECT", 6))
return;
@ -202,8 +193,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
Object &obj = objects.back();
aiLight *light = NULL;
if (!ASSIMP_strincmp(buffer,"light",5))
{
if (!ASSIMP_strincmp(buffer, "light", 5)) {
// This is a light source. Add it to the list
mLights->push_back(light = new aiLight());
@ -219,83 +209,57 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
ASSIMP_LOG_DEBUG("AC3D: Light source encountered");
obj.type = Object::Light;
}
else if (!ASSIMP_strincmp(buffer,"group",5))
{
} else if (!ASSIMP_strincmp(buffer, "group", 5)) {
obj.type = Object::Group;
}
else if (!ASSIMP_strincmp(buffer,"world",5))
{
} else if (!ASSIMP_strincmp(buffer, "world", 5)) {
obj.type = Object::World;
}
else obj.type = Object::Poly;
while (GetNextLine())
{
if (TokenMatch(buffer,"kids",4))
{
} else
obj.type = Object::Poly;
while (GetNextLine()) {
if (TokenMatch(buffer, "kids", 4)) {
SkipSpaces(&buffer);
unsigned int num = strtoul10(buffer, &buffer);
GetNextLine();
if (num)
{
if (num) {
// load the children of this object recursively
obj.children.reserve(num);
for (unsigned int i = 0; i < num; ++i)
LoadObjectSection(obj.children);
}
return;
}
else if (TokenMatch(buffer,"name",4))
{
} else if (TokenMatch(buffer, "name", 4)) {
SkipSpaces(&buffer);
AI_AC_GET_STRING(obj.name);
buffer = AcGetString(buffer, obj.name);
// If this is a light source, we'll also need to store
// the name of the node in it.
if (light)
{
if (light) {
light->mName.Set(obj.name);
}
}
else if (TokenMatch(buffer,"texture",7))
{
} else if (TokenMatch(buffer, "texture", 7)) {
SkipSpaces(&buffer);
AI_AC_GET_STRING(obj.texture);
}
else if (TokenMatch(buffer,"texrep",6))
{
buffer = AcGetString(buffer, obj.texture);
} else if (TokenMatch(buffer, "texrep", 6)) {
SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texRepeat);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat);
if (!obj.texRepeat.x || !obj.texRepeat.y)
obj.texRepeat = aiVector2D(1.f, 1.f);
}
else if (TokenMatch(buffer,"texoff",6))
{
} else if (TokenMatch(buffer, "texoff", 6)) {
SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texOffset);
}
else if (TokenMatch(buffer,"rot",3))
{
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texOffset);
} else if (TokenMatch(buffer, "rot", 3)) {
SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,9,&obj.rotation);
}
else if (TokenMatch(buffer,"loc",3))
{
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 9, &obj.rotation);
} else if (TokenMatch(buffer, "loc", 3)) {
SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&obj.translation);
}
else if (TokenMatch(buffer,"subdiv",6))
{
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &obj.translation);
} else if (TokenMatch(buffer, "subdiv", 6)) {
SkipSpaces(&buffer);
obj.subDiv = strtoul10(buffer, &buffer);
}
else if (TokenMatch(buffer,"crease",6))
{
} else if (TokenMatch(buffer, "crease", 6)) {
SkipSpaces(&buffer);
obj.crease = fast_atof(buffer);
}
else if (TokenMatch(buffer,"numvert",7))
{
} else if (TokenMatch(buffer, "numvert", 7)) {
SkipSpaces(&buffer);
unsigned int t = strtoul10(buffer, &buffer);
@ -303,41 +267,32 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
}
obj.vertices.reserve(t);
for (unsigned int i = 0; i < t;++i)
{
if (!GetNextLine())
{
for (unsigned int i = 0; i < t; ++i) {
if (!GetNextLine()) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet");
break;
}
else if (!IsNumeric(*buffer))
{
} else if (!IsNumeric(*buffer)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet");
--buffer; // make sure the line is processed a second time
break;
}
obj.vertices.push_back(aiVector3D());
aiVector3D &v = obj.vertices.back();
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&v.x);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x);
}
}
else if (TokenMatch(buffer,"numsurf",7))
{
} else if (TokenMatch(buffer, "numsurf", 7)) {
SkipSpaces(&buffer);
bool Q3DWorkAround = false;
const unsigned int t = strtoul10(buffer, &buffer);
obj.surfaces.reserve(t);
for (unsigned int i = 0; i < t;++i)
{
for (unsigned int i = 0; i < t; ++i) {
GetNextLine();
if (!TokenMatch(buffer,"SURF",4))
{
if (!TokenMatch(buffer, "SURF", 4)) {
// FIX: this can occur for some files - Quick 3D for
// example writes no surf chunks
if (!Q3DWorkAround)
{
if (!Q3DWorkAround) {
ASSIMP_LOG_WARN("AC3D: SURF token was expected");
ASSIMP_LOG_DEBUG("Continuing with Quick3D Workaround enabled");
}
@ -351,24 +306,17 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
Surface &surf = obj.surfaces.back();
surf.flags = strtoul_cppstyle(buffer);
while (1)
{
if(!GetNextLine())
{
while (1) {
if (!GetNextLine()) {
throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete");
}
if (TokenMatch(buffer,"mat",3))
{
if (TokenMatch(buffer, "mat", 3)) {
SkipSpaces(&buffer);
surf.mat = strtoul10(buffer);
}
else if (TokenMatch(buffer,"refs",4))
{
} else if (TokenMatch(buffer, "refs", 4)) {
// --- see fix notes above
if (Q3DWorkAround)
{
if (!surf.entries.empty())
{
if (Q3DWorkAround) {
if (!surf.entries.empty()) {
buffer -= 6;
break;
}
@ -380,10 +328,8 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
obj.numRefs += m;
for (unsigned int k = 0; k < m; ++k)
{
if(!GetNextLine())
{
for (unsigned int k = 0; k < m; ++k) {
if (!GetNextLine()) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: surface references are incomplete");
break;
}
@ -392,12 +338,9 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
entry.first = strtoul10(buffer, &buffer);
SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&entry.second);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &entry.second);
}
}
else
{
} else {
--buffer; // make sure the line is processed a second time
break;
}
@ -412,24 +355,20 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
// Convert a material from AC3DImporter::Material to aiMaterial
void AC3DImporter::ConvertMaterial(const Object &object,
const Material &matSrc,
aiMaterial& matDest)
{
aiMaterial &matDest) {
aiString s;
if (matSrc.name.length())
{
if (matSrc.name.length()) {
s.Set(matSrc.name);
matDest.AddProperty(&s, AI_MATKEY_NAME);
}
if (object.texture.length())
{
if (object.texture.length()) {
s.Set(object.texture);
matDest.AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
// UV transformation
if (1.f != object.texRepeat.x || 1.f != object.texRepeat.y ||
object.texOffset.x || object.texOffset.y)
{
object.texOffset.x || object.texOffset.y) {
aiUVTransform transform;
transform.mScaling = object.texRepeat;
transform.mTranslation = object.texOffset;
@ -442,13 +381,13 @@ void AC3DImporter::ConvertMaterial(const Object& object,
matDest.AddProperty<aiColor3D>(&matSrc.emis, 1, AI_MATKEY_COLOR_EMISSIVE);
matDest.AddProperty<aiColor3D>(&matSrc.spec, 1, AI_MATKEY_COLOR_SPECULAR);
int n;
if (matSrc.shin)
{
int n = -1;
if (matSrc.shin) {
n = aiShadingMode_Phong;
matDest.AddProperty<float>(&matSrc.shin, 1, AI_MATKEY_SHININESS);
} else {
n = aiShadingMode_Gouraud;
}
else n = aiShadingMode_Gouraud;
matDest.AddProperty<int>(&n, 1, AI_MATKEY_SHADING_MODEL);
float f = 1.f - matSrc.trans;
@ -461,14 +400,11 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
std::vector<aiMesh *> &meshes,
std::vector<aiMaterial *> &outMaterials,
const std::vector<Material> &materials,
aiNode* parent)
{
aiNode *parent) {
aiNode *node = new aiNode();
node->mParent = parent;
if (object.vertices.size())
{
if (!object.surfaces.size() || !object.numRefs)
{
if (object.vertices.size()) {
if (!object.surfaces.size() || !object.numRefs) {
/* " An object with 7 vertices (no surfaces, no materials defined).
This is a good way of getting point data into AC3D.
The Vertex->create convex-surface/object can be used on these
@ -488,8 +424,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
aiFace *faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
aiVector3D *verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
for (unsigned int i = 0; i < mesh->mNumVertices;++i,++faces,++verts)
{
for (unsigned int i = 0; i < mesh->mNumVertices; ++i, ++faces, ++verts) {
*verts = object.vertices[i];
faces->mNumIndices = 1;
faces->mIndices = new unsigned int[1];
@ -502,9 +437,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
mesh->mMaterialIndex = 0;
outMaterials.push_back(new aiMaterial());
ConvertMaterial(object, materials[0], *outMaterials.back());
}
else
{
} else {
// need to generate one or more meshes for this object.
// find out how many different materials we have
typedef std::pair<unsigned int, unsigned int> IntPair;
@ -514,53 +447,46 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
std::vector<Surface>::iterator it, end = object.surfaces.end();
std::vector<Surface::SurfaceEntry>::iterator it2, end2;
for (it = object.surfaces.begin(); it != end; ++it)
{
for (it = object.surfaces.begin(); it != end; ++it) {
unsigned int idx = (*it).mat;
if (idx >= needMat.size())
{
if (idx >= needMat.size()) {
ASSIMP_LOG_ERROR("AC3D: material index is out of range");
idx = 0;
}
if ((*it).entries.empty())
{
if ((*it).entries.empty()) {
ASSIMP_LOG_WARN("AC3D: surface her zero vertex references");
}
// validate all vertex indices to make sure we won't crash here
for (it2 = (*it).entries.begin(),
end2 = (*it).entries.end(); it2 != end2; ++it2)
{
if ((*it2).first >= object.vertices.size())
{
end2 = (*it).entries.end();
it2 != end2; ++it2) {
if ((*it2).first >= object.vertices.size()) {
ASSIMP_LOG_WARN("AC3D: Invalid vertex reference");
(*it2).first = 0;
}
}
if (!needMat[idx].first)++node->mNumMeshes;
if (!needMat[idx].first) {
++node->mNumMeshes;
}
switch ((*it).flags & 0xf)
{
switch ((*it).flags & 0xf) {
// closed line
case 0x1:
needMat[idx].first += (unsigned int)(*it).entries.size();
needMat[idx].second += (unsigned int)(*it).entries.size() << 1u;
break;
// unclosed line
case 0x2:
needMat[idx].first += (unsigned int)(*it).entries.size() - 1;
needMat[idx].second += ((unsigned int)(*it).entries.size() - 1) << 1u;
break;
// 0 == polygon, else unknown
default:
if ((*it).flags & 0xf)
{
if ((*it).flags & 0xf) {
ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown");
(*it).flags &= ~(0xf);
}
@ -575,16 +501,17 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
unsigned int mat = 0;
const size_t oldm = meshes.size();
for (MatTable::const_iterator cit = needMat.begin(), cend = needMat.end();
cit != cend; ++cit, ++mat)
{
if (!(*cit).first)continue;
cit != cend; ++cit, ++mat) {
if (!(*cit).first) {
continue;
}
// allocate a new aiMesh object
*pip++ = (unsigned int)meshes.size();
aiMesh *mesh = new aiMesh();
meshes.push_back(mesh);
mesh->mMaterialIndex = (unsigned int)outMaterials.size();
mesh->mMaterialIndex = static_cast<unsigned int>(outMaterials.size());
outMaterials.push_back(new aiMaterial());
ConvertMaterial(object, materials[mat], *outMaterials.back());
@ -609,28 +536,23 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
// allocate UV coordinates, but only if the texture name for the
// surface is not empty
aiVector3D *uv = NULL;
if(object.texture.length())
{
if (object.texture.length()) {
uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
mesh->mNumUVComponents[0] = 2;
}
for (it = object.surfaces.begin(); it != end; ++it)
{
if (mat == (*it).mat)
{
for (it = object.surfaces.begin(); it != end; ++it) {
if (mat == (*it).mat) {
const Surface &src = *it;
// closed polygon
unsigned int type = (*it).flags & 0xf;
if (!type)
{
if (!type) {
aiFace &face = *faces++;
if((face.mNumIndices = (unsigned int)src.entries.size()))
{
face.mNumIndices = (unsigned int)src.entries.size();
if (0 != face.mNumIndices) {
face.mIndices = new unsigned int[face.mNumIndices];
for (unsigned int i = 0; i < face.mNumIndices;++i,++vertices)
{
for (unsigned int i = 0; i < face.mNumIndices; ++i, ++vertices) {
const Surface::SurfaceEntry &entry = src.entries[i];
face.mIndices[i] = cur++;
@ -640,27 +562,22 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
}
*vertices = object.vertices[entry.first] + object.translation;
// copy texture coordinates
if (uv)
{
if (uv) {
uv->x = entry.second.x;
uv->y = entry.second.y;
++uv;
}
}
}
}
else
{
} else {
it2 = (*it).entries.begin();
// either a closed or an unclosed line
unsigned int tmp = (unsigned int)(*it).entries.size();
if (0x2 == type) --tmp;
for (unsigned int m = 0; m < tmp;++m)
{
for (unsigned int m = 0; m < tmp; ++m) {
aiFace &face = *faces++;
face.mNumIndices = 2;
@ -676,26 +593,22 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
*vertices++ = object.vertices[(*it2).first];
// copy texture coordinates
if (uv)
{
if (uv) {
uv->x = (*it2).second.x;
uv->y = (*it2).second.y;
++uv;
}
if (0x1 == type && tmp-1 == m)
{
if (0x1 == type && tmp - 1 == m) {
// if this is a closed line repeat its beginning now
it2 = (*it).entries.begin();
}
else ++it2;
} else
++it2;
// second point
*vertices++ = object.vertices[(*it2).first];
if (uv)
{
if (uv) {
uv->x = (*it2).second.x;
uv->y = (*it2).second.y;
++uv;
@ -719,10 +632,8 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
std::copy(cpy.begin(), cpy.end(), meshes.begin() + oldm);
// previous meshes are deleted vy Subdivide().
}
else {
ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: "
+object.name);
} else {
ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: " + object.name);
}
}
}
@ -730,47 +641,41 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
if (object.name.length())
node->mName.Set(object.name);
else
{
else {
// generate a name depending on the type of the node
switch (object.type)
{
switch (object.type) {
case Object::Group:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i",groups++);
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i", mGroupsCounter++);
break;
case Object::Poly:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i",polys++);
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i", mPolysCounter++);
break;
case Object::Light:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i",lights++);
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i", mLightsCounter++);
break;
// there shouldn't be more than one world, but we don't care
case Object::World:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i",worlds++);
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i", mWorldsCounter++);
break;
}
}
// setup the local transformation matrix of the object
// compute the transformation offset to the parent node
node->mTransformation = aiMatrix4x4(object.rotation);
if (object.type == Object::Group || !object.numRefs)
{
if (object.type == Object::Group || !object.numRefs) {
node->mTransformation.a4 = object.translation.x;
node->mTransformation.b4 = object.translation.y;
node->mTransformation.c4 = object.translation.z;
}
// add children to the object
if (object.children.size())
{
if (object.children.size()) {
node->mNumChildren = (unsigned int)object.children.size();
node->mChildren = new aiNode *[node->mNumChildren];
for (unsigned int i = 0; i < node->mNumChildren;++i)
{
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
node->mChildren[i] = ConvertObjectSection(object.children[i], meshes, outMaterials, materials, node);
}
}
@ -779,8 +684,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
}
// ------------------------------------------------------------------------------------------------
void AC3DImporter::SetupProperties(const Importer* pImp)
{
void AC3DImporter::SetupProperties(const Importer *pImp) {
configSplitBFCull = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL, 1) ? true : false;
configEvalSubdivision = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION, 1) ? true : false;
}
@ -788,13 +692,13 @@ void AC3DImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void AC3DImporter::InternReadFile(const std::string &pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
aiScene *pScene, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL)
if ( file.get() == nullptr ) {
throw DeadlyImportError("Failed to open AC3D file " + pFile + ".");
}
// allocate storage and copy the contents of the file to a memory buffer
std::vector<char> mBuffer2;
@ -803,7 +707,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
buffer = &mBuffer2[0];
mNumMeshes = 0;
lights = polys = worlds = groups = 0;
mLightsCounter = mPolysCounter = mWorldsCounter = mGroupsCounter = 0;
if (::strncmp(buffer, "AC3D", 4)) {
throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found");
@ -824,39 +728,34 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
std::vector<aiLight *> lights;
mLights = &lights;
while (GetNextLine())
{
if (TokenMatch(buffer,"MATERIAL",8))
{
while (GetNextLine()) {
if (TokenMatch(buffer, "MATERIAL", 8)) {
materials.push_back(Material());
Material &mat = materials.back();
// manually parse the material ... sscanf would use the buldin atof ...
// Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f
AI_AC_SKIP_TO_NEXT_TOKEN();
if ('\"' == *buffer)
{
AI_AC_GET_STRING(mat.name);
AI_AC_SKIP_TO_NEXT_TOKEN();
buffer = AcSkipToNextToken(buffer);
if ('\"' == *buffer) {
buffer = AcGetString(buffer, mat.name);
buffer = AcSkipToNextToken(buffer);
}
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("rgb",3,3,&mat.rgb);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("amb",3,3,&mat.amb);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("emis",4,3,&mat.emis);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("spec",4,3,&mat.spec);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("shi",3,1,&mat.shin);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("trans",5,1,&mat.trans);
buffer = TAcCheckedLoadFloatArray(buffer, "rgb", 3, 3, &mat.rgb);
buffer = TAcCheckedLoadFloatArray(buffer, "amb", 3, 3, &mat.amb);
buffer = TAcCheckedLoadFloatArray(buffer, "emis", 4, 3, &mat.emis);
buffer = TAcCheckedLoadFloatArray(buffer, "spec", 4, 3, &mat.spec);
buffer = TAcCheckedLoadFloatArray(buffer, "shi", 3, 1, &mat.shin);
buffer = TAcCheckedLoadFloatArray(buffer, "trans", 5, 1, &mat.trans);
}
LoadObjectSection(rootObjects);
}
if (rootObjects.empty() || !mNumMeshes)
{
if (rootObjects.empty() || !mNumMeshes) {
throw DeadlyImportError("AC3D: No meshes have been loaded");
}
if (materials.empty())
{
if (materials.empty()) {
ASSIMP_LOG_WARN("AC3D: No material has been found");
materials.push_back(Material());
}
@ -872,21 +771,22 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
Object *root;
if (1 == rootObjects.size())
root = &rootObjects[0];
else
{
else {
root = new Object();
}
// now convert the imported stuff to our output data structure
pScene->mRootNode = ConvertObjectSection(*root, meshes, omaterials, materials);
if (1 != rootObjects.size())delete root;
if (1 != rootObjects.size()) {
delete root;
}
if (!::strncmp( pScene->mRootNode->mName.data, "Node", 4))
if (!::strncmp(pScene->mRootNode->mName.data, "Node", 4)) {
pScene->mRootNode->mName.Set("<AC3DWorld>");
}
// copy meshes
if (meshes.empty())
{
if (meshes.empty()) {
throw DeadlyImportError("An unknown error occurred during converting");
}
pScene->mNumMeshes = (unsigned int)meshes.size();
@ -900,8 +800,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
// copy lights
pScene->mNumLights = (unsigned int)lights.size();
if (lights.size())
{
if (lights.size()) {
pScene->mLights = new aiLight *[lights.size()];
::memcpy(pScene->mLights, &lights[0], lights.size() * sizeof(void *));
}

View File

@ -68,8 +68,6 @@ public:
AC3DImporter();
~AC3DImporter();
// Represents an AC3D material
struct Material
{
@ -245,8 +243,6 @@ private:
aiMaterial& matDest);
private:
// points to the next data line
const char* buffer;
@ -268,7 +264,7 @@ private:
std::vector<aiLight*>* mLights;
// name counters
unsigned int lights, groups, polys, worlds;
unsigned int mLightsCounter, mGroupsCounter, mPolysCounter, mWorldsCounter;
};
} // end of namespace Assimp

View File

@ -465,7 +465,7 @@ std::list<unsigned int> mesh_idx;
{
auto VertexIndex_GetMinimal = [](const std::list<SComplexFace>& pFaceList, const size_t* pBiggerThan) -> size_t
{
size_t rv;
size_t rv=0;
if(pBiggerThan != nullptr)
{

View File

@ -80,7 +80,18 @@ struct Material : public D3DS::Material
}
Material(const Material &other) = default;
Material &operator=(const Material &other) = default;
Material &operator=(const Material &other) {
if (this == &other) {
return *this;
}
avSubMaterials = other.avSubMaterials;
pcInstance = other.pcInstance;
bNeed = other.bNeed;
return *this;
}
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
@ -99,7 +110,7 @@ struct Material : public D3DS::Material
return *this;
}
D3DS::Material::operator=(std::move(other));
//D3DS::Material::operator=(std::move(other));
avSubMaterials = std::move(other.avSubMaterials);
pcInstance = std::move(other.pcInstance);

View File

@ -49,8 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssbinFileWriter.h"
#include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/IOSystem.hpp>
namespace Assimp {

View File

@ -48,10 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Common/assbin_chunks.h"
#include "PostProcessing/ProcessHelper.h"
#include <assimp/version.h>
#include <assimp/IOStream.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/Exceptional.h>
#include <assimp/version.h>
#include <assimp/Exporter.hpp>
#include <assimp/IOStream.hpp>
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
@ -61,6 +61,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <time.h>
#ifdef _WIN32
# pragma warning(push)
# pragma warning(disable : 4706)
#endif // _WIN32
namespace Assimp {
template <typename T>
@ -71,8 +76,7 @@ size_t Write(IOStream * stream, const T& v) {
// -----------------------------------------------------------------------------------
// Serialize an aiString
template <>
inline
size_t Write<aiString>(IOStream * stream, const aiString& s) {
inline size_t Write<aiString>(IOStream *stream, const aiString &s) {
const size_t s2 = (uint32_t)s.length;
stream->Write(&s, 4, 1);
stream->Write(s.data, s2, 1);
@ -83,8 +87,7 @@ size_t Write<aiString>(IOStream * stream, const aiString& s) {
// -----------------------------------------------------------------------------------
// Serialize an unsigned int as uint32_t
template <>
inline
size_t Write<unsigned int>(IOStream * stream, const unsigned int& w) {
inline size_t Write<unsigned int>(IOStream *stream, const unsigned int &w) {
const uint32_t t = (uint32_t)w;
if (w > t) {
// this shouldn't happen, integers in Assimp data structures never exceed 2^32
@ -99,8 +102,7 @@ size_t Write<unsigned int>(IOStream * stream, const unsigned int& w) {
// -----------------------------------------------------------------------------------
// Serialize an unsigned int as uint16_t
template <>
inline
size_t Write<uint16_t>(IOStream * stream, const uint16_t& w) {
inline size_t Write<uint16_t>(IOStream *stream, const uint16_t &w) {
static_assert(sizeof(uint16_t) == 2, "sizeof(uint16_t)==2");
stream->Write(&w, 2, 1);
@ -110,8 +112,7 @@ size_t Write<uint16_t>(IOStream * stream, const uint16_t& w) {
// -----------------------------------------------------------------------------------
// Serialize a float
template <>
inline
size_t Write<float>(IOStream * stream, const float& f) {
inline size_t Write<float>(IOStream *stream, const float &f) {
static_assert(sizeof(float) == 4, "sizeof(float)==4");
stream->Write(&f, 4, 1);
@ -121,8 +122,7 @@ size_t Write<float>(IOStream * stream, const float& f) {
// -----------------------------------------------------------------------------------
// Serialize a double
template <>
inline
size_t Write<double>(IOStream * stream, const double& f) {
inline size_t Write<double>(IOStream *stream, const double &f) {
static_assert(sizeof(double) == 8, "sizeof(double)==8");
stream->Write(&f, 8, 1);
@ -132,8 +132,7 @@ size_t Write<double>(IOStream * stream, const double& f) {
// -----------------------------------------------------------------------------------
// Serialize a vec3
template <>
inline
size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v) {
inline size_t Write<aiVector3D>(IOStream *stream, const aiVector3D &v) {
size_t t = Write<float>(stream, v.x);
t += Write<float>(stream, v.y);
t += Write<float>(stream, v.z);
@ -144,8 +143,7 @@ size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v) {
// -----------------------------------------------------------------------------------
// Serialize a color value
template <>
inline
size_t Write<aiColor3D>(IOStream * stream, const aiColor3D& v) {
inline size_t Write<aiColor3D>(IOStream *stream, const aiColor3D &v) {
size_t t = Write<float>(stream, v.r);
t += Write<float>(stream, v.g);
t += Write<float>(stream, v.b);
@ -156,8 +154,7 @@ size_t Write<aiColor3D>(IOStream * stream, const aiColor3D& v) {
// -----------------------------------------------------------------------------------
// Serialize a color value
template <>
inline
size_t Write<aiColor4D>(IOStream * stream, const aiColor4D& v) {
inline size_t Write<aiColor4D>(IOStream *stream, const aiColor4D &v) {
size_t t = Write<float>(stream, v.r);
t += Write<float>(stream, v.g);
t += Write<float>(stream, v.b);
@ -169,8 +166,7 @@ size_t Write<aiColor4D>(IOStream * stream, const aiColor4D& v) {
// -----------------------------------------------------------------------------------
// Serialize a quaternion
template <>
inline
size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v) {
inline size_t Write<aiQuaternion>(IOStream *stream, const aiQuaternion &v) {
size_t t = Write<float>(stream, v.w);
t += Write<float>(stream, v.x);
t += Write<float>(stream, v.y);
@ -183,8 +179,7 @@ size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v) {
// -----------------------------------------------------------------------------------
// Serialize a vertex weight
template <>
inline
size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v) {
inline size_t Write<aiVertexWeight>(IOStream *stream, const aiVertexWeight &v) {
size_t t = Write<unsigned int>(stream, v.mVertexId);
return t + Write<float>(stream, v.mWeight);
@ -193,8 +188,7 @@ size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v) {
// -----------------------------------------------------------------------------------
// Serialize a mat4x4
template <>
inline
size_t Write<aiMatrix4x4>(IOStream * stream, const aiMatrix4x4& m) {
inline size_t Write<aiMatrix4x4>(IOStream *stream, const aiMatrix4x4 &m) {
for (unsigned int i = 0; i < 4; ++i) {
for (unsigned int i2 = 0; i2 < 4; ++i2) {
Write<float>(stream, m[i][i2]);
@ -207,8 +201,7 @@ size_t Write<aiMatrix4x4>(IOStream * stream, const aiMatrix4x4& m) {
// -----------------------------------------------------------------------------------
// Serialize an aiVectorKey
template <>
inline
size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v) {
inline size_t Write<aiVectorKey>(IOStream *stream, const aiVectorKey &v) {
const size_t t = Write<double>(stream, v.mTime);
return t + Write<aiVector3D>(stream, v.mValue);
}
@ -216,15 +209,13 @@ size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v) {
// -----------------------------------------------------------------------------------
// Serialize an aiQuatKey
template <>
inline
size_t Write<aiQuatKey>(IOStream * stream, const aiQuatKey& v) {
inline size_t Write<aiQuatKey>(IOStream *stream, const aiQuatKey &v) {
const size_t t = Write<double>(stream, v.mTime);
return t + Write<aiQuaternion>(stream, v.mValue);
}
template <typename T>
inline
size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) {
inline size_t WriteBounds(IOStream *stream, const T *in, unsigned int size) {
T minc, maxc;
ArrayBounds(in, size, minc, maxc);
@ -235,10 +226,10 @@ size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) {
// We use this to write out non-byte arrays so that we write using the specializations.
// This way we avoid writing out extra bytes that potentially come from struct alignment.
template <typename T>
inline
size_t WriteArray(IOStream * stream, const T* in, unsigned int size) {
inline size_t WriteArray(IOStream *stream, const T *in, unsigned int size) {
size_t n = 0;
for (unsigned int i=0; i<size; i++) n += Write<T>(stream,in[i]);
for (unsigned int i = 0; i < size; i++)
n += Write<T>(stream, in[i]);
return n;
}
@ -253,10 +244,8 @@ size_t WriteArray(IOStream * stream, const T* in, unsigned int size) {
* and the chunk contents to the container stream. This allows relatively easy chunk
* chunk construction, even recursively.
*/
class AssbinChunkWriter : public IOStream
{
class AssbinChunkWriter : public IOStream {
private:
uint8_t *buffer;
uint32_t magic;
IOStream *container;
@ -264,8 +253,7 @@ private:
private:
// -------------------------------------------------------------------
void Grow(size_t need = 0)
{
void Grow(size_t need = 0) {
size_t new_size = std::max(initial, std::max(need, cur_size + (cur_size >> 1)));
const uint8_t *const old = buffer;
@ -280,14 +268,17 @@ private:
}
public:
AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096)
: buffer(NULL), magic(magic), container(container), cur_size(0), cursor(0), initial(initial)
{
AssbinChunkWriter(IOStream *container, uint32_t magic, size_t initial = 4096) :
buffer(NULL),
magic(magic),
container(container),
cur_size(0),
cursor(0),
initial(initial) {
// empty
}
virtual ~AssbinChunkWriter()
{
virtual ~AssbinChunkWriter() {
if (container) {
container->Write(&magic, sizeof(uint32_t), 1);
container->Write(&cursor, sizeof(uint32_t), 1);
@ -328,7 +319,6 @@ public:
return pCount;
}
};
// ----------------------------------------------------------------------------------
@ -337,16 +327,14 @@ public:
*
* This class writes an .assbin file, and is responsible for the file layout.
*/
class AssbinFileWriter
{
class AssbinFileWriter {
private:
bool shortened;
bool compressed;
protected:
// -----------------------------------------------------------------------------------
void WriteBinaryNode( IOStream * container, const aiNode* node)
{
void WriteBinaryNode(IOStream *container, const aiNode *node) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODE);
unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
@ -371,7 +359,7 @@ protected:
void *value = node->mMetaData->mValues[i].mData;
Write<aiString>(&chunk, key);
Write<uint16_t>(&chunk, type);
Write<uint16_t>(&chunk, (uint16_t)type);
switch (type) {
case AI_BOOL:
@ -405,8 +393,7 @@ protected:
}
// -----------------------------------------------------------------------------------
void WriteBinaryTexture(IOStream * container, const aiTexture* tex)
{
void WriteBinaryTexture(IOStream *container, const aiTexture *tex) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AITEXTURE);
Write<unsigned int>(&chunk, tex->mWidth);
@ -417,17 +404,14 @@ protected:
if (!shortened) {
if (!tex->mHeight) {
chunk.Write(tex->pcData, 1, tex->mWidth);
}
else {
} else {
chunk.Write(tex->pcData, 1, tex->mWidth * tex->mHeight * 4);
}
}
}
// -----------------------------------------------------------------------------------
void WriteBinaryBone(IOStream * container, const aiBone* b)
{
void WriteBinaryBone(IOStream *container, const aiBone *b) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIBONE);
Write<aiString>(&chunk, b->mName);
@ -439,12 +423,12 @@ protected:
if (shortened) {
WriteBounds(&chunk, b->mWeights, b->mNumWeights);
} // else write as usual
else WriteArray<aiVertexWeight>(&chunk,b->mWeights,b->mNumWeights);
else
WriteArray<aiVertexWeight>(&chunk, b->mWeights, b->mNumWeights);
}
// -----------------------------------------------------------------------------------
void WriteBinaryMesh(IOStream * container, const aiMesh* mesh)
{
void WriteBinaryMesh(IOStream *container, const aiMesh *mesh) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMESH);
Write<unsigned int>(&chunk, mesh->mPrimitiveTypes);
@ -483,13 +467,15 @@ protected:
if (shortened) {
WriteBounds(&chunk, mesh->mVertices, mesh->mNumVertices);
} // else write as usual
else WriteArray<aiVector3D>(&chunk,mesh->mVertices,mesh->mNumVertices);
else
WriteArray<aiVector3D>(&chunk, mesh->mVertices, mesh->mNumVertices);
}
if (mesh->mNormals) {
if (shortened) {
WriteBounds(&chunk, mesh->mNormals, mesh->mNumVertices);
} // else write as usual
else WriteArray<aiVector3D>(&chunk,mesh->mNormals,mesh->mNumVertices);
else
WriteArray<aiVector3D>(&chunk, mesh->mNormals, mesh->mNumVertices);
}
if (mesh->mTangents && mesh->mBitangents) {
if (shortened) {
@ -508,7 +494,8 @@ protected:
if (shortened) {
WriteBounds(&chunk, mesh->mColors[n], mesh->mNumVertices);
} // else write as usual
else WriteArray<aiColor4D>(&chunk,mesh->mColors[n],mesh->mNumVertices);
else
WriteArray<aiColor4D>(&chunk, mesh->mColors[n], mesh->mNumVertices);
}
for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++n) {
if (!mesh->mTextureCoords[n])
@ -520,7 +507,8 @@ protected:
if (shortened) {
WriteBounds(&chunk, mesh->mTextureCoords[n], mesh->mNumVertices);
} // else write as usual
else WriteArray<aiVector3D>(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
else
WriteArray<aiVector3D>(&chunk, mesh->mTextureCoords[n], mesh->mNumVertices);
}
// write faces. There are no floating-point calculations involved
@ -530,7 +518,6 @@ protected:
if (shortened) {
unsigned int processed = 0;
for (unsigned int job; (job = std::min(mesh->mNumFaces - processed, 512u)); processed += job) {
uint32_t hash = 0;
for (unsigned int a = 0; a < job; ++a) {
@ -545,21 +532,21 @@ protected:
}
Write<unsigned int>(&chunk, hash);
}
}
else // else write as usual
} else // else write as usual
{
// if there are less than 2^16 vertices, we can simply use 16 bit integers ...
for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
const aiFace &f = mesh->mFaces[i];
static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
Write<uint16_t>(&chunk,f.mNumIndices);
Write<uint16_t>(&chunk, static_cast<uint16_t>(f.mNumIndices));
for (unsigned int a = 0; a < f.mNumIndices; ++a) {
if (mesh->mNumVertices < (1u << 16)) {
Write<uint16_t>(&chunk,f.mIndices[a]);
Write<uint16_t>(&chunk, static_cast<uint16_t>(f.mIndices[a]));
} else {
Write<unsigned int>(&chunk, f.mIndices[a]);
}
else Write<unsigned int>(&chunk,f.mIndices[a]);
}
}
}
@ -574,8 +561,7 @@ protected:
}
// -----------------------------------------------------------------------------------
void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop)
{
void WriteBinaryMaterialProperty(IOStream *container, const aiMaterialProperty *prop) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMATERIALPROPERTY);
Write<aiString>(&chunk, prop->mKey);
@ -588,8 +574,7 @@ protected:
}
// -----------------------------------------------------------------------------------
void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat)
{
void WriteBinaryMaterial(IOStream *container, const aiMaterial *mat) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIMATERIAL);
Write<unsigned int>(&chunk, mat->mNumProperties);
@ -599,8 +584,7 @@ protected:
}
// -----------------------------------------------------------------------------------
void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd)
{
void WriteBinaryNodeAnim(IOStream *container, const aiNodeAnim *nd) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODEANIM);
Write<aiString>(&chunk, nd->mNodeName);
@ -615,28 +599,29 @@ protected:
WriteBounds(&chunk, nd->mPositionKeys, nd->mNumPositionKeys);
} // else write as usual
else WriteArray<aiVectorKey>(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);
else
WriteArray<aiVectorKey>(&chunk, nd->mPositionKeys, nd->mNumPositionKeys);
}
if (nd->mRotationKeys) {
if (shortened) {
WriteBounds(&chunk, nd->mRotationKeys, nd->mNumRotationKeys);
} // else write as usual
else WriteArray<aiQuatKey>(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);
else
WriteArray<aiQuatKey>(&chunk, nd->mRotationKeys, nd->mNumRotationKeys);
}
if (nd->mScalingKeys) {
if (shortened) {
WriteBounds(&chunk, nd->mScalingKeys, nd->mNumScalingKeys);
} // else write as usual
else WriteArray<aiVectorKey>(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);
else
WriteArray<aiVectorKey>(&chunk, nd->mScalingKeys, nd->mNumScalingKeys);
}
}
// -----------------------------------------------------------------------------------
void WriteBinaryAnim( IOStream * container, const aiAnimation* anim )
{
void WriteBinaryAnim(IOStream *container, const aiAnimation *anim) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AIANIMATION);
Write<aiString>(&chunk, anim->mName);
@ -651,8 +636,7 @@ protected:
}
// -----------------------------------------------------------------------------------
void WriteBinaryLight( IOStream * container, const aiLight* l )
{
void WriteBinaryLight(IOStream *container, const aiLight *l) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AILIGHT);
Write<aiString>(&chunk, l->mName);
@ -672,12 +656,10 @@ protected:
Write<float>(&chunk, l->mAngleInnerCone);
Write<float>(&chunk, l->mAngleOuterCone);
}
}
// -----------------------------------------------------------------------------------
void WriteBinaryCamera( IOStream * container, const aiCamera* cam )
{
void WriteBinaryCamera(IOStream *container, const aiCamera *cam) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AICAMERA);
Write<aiString>(&chunk, cam->mName);
@ -691,8 +673,7 @@ protected:
}
// -----------------------------------------------------------------------------------
void WriteBinaryScene( IOStream * container, const aiScene* scene)
{
void WriteBinaryScene(IOStream *container, const aiScene *scene) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AISCENE);
// basic scene information
@ -725,7 +706,6 @@ protected:
WriteBinaryAnim(&chunk, anim);
}
// write all textures
for (unsigned int i = 0; i < scene->mNumTextures; ++i) {
const aiTexture *mesh = scene->mTextures[i];
@ -743,19 +723,16 @@ protected:
const aiCamera *cam = scene->mCameras[i];
WriteBinaryCamera(&chunk, cam);
}
}
public:
AssbinFileWriter(bool shortened, bool compressed)
: shortened(shortened), compressed(compressed)
{
AssbinFileWriter(bool shortened, bool compressed) :
shortened(shortened), compressed(compressed) {
}
// -----------------------------------------------------------------------------------
// Write a binary model dump
void WriteBinaryDump(const char* pFile, const char* cmd, IOSystem* pIOSystem, const aiScene* pScene)
{
void WriteBinaryDump(const char *pFile, const char *cmd, IOSystem *pIOSystem, const aiScene *pScene) {
IOStream *out = pIOSystem->Open(pFile, "wb");
if (!out)
throw std::runtime_error("Unable to open output file " + std::string(pFile) + '\n');
@ -813,8 +790,7 @@ public:
// Up to here the data is uncompressed. For compressed files, the rest
// is compressed using standard DEFLATE from zlib.
if (compressed)
{
if (compressed) {
AssbinChunkWriter uncompressedStream(NULL, 0);
WriteBinaryScene(&uncompressedStream, pScene);
@ -823,8 +799,7 @@ public:
uint8_t *compressedBuffer = new uint8_t[compressedSize];
int res = compress2(compressedBuffer, &compressedSize, (const Bytef *)uncompressedStream.GetBufferPointer(), uncompressedSize, 9);
if (res != Z_OK)
{
if (res != Z_OK) {
delete[] compressedBuffer;
throw DeadlyExportError("Compression failed.");
}
@ -833,15 +808,12 @@ public:
out->Write(compressedBuffer, sizeof(char), compressedSize);
delete[] compressedBuffer;
}
else
{
} else {
WriteBinaryScene(out, pScene);
}
CloseIOStream();
}
catch (...) {
} catch (...) {
CloseIOStream();
throw;
}
@ -854,5 +826,8 @@ void DumpSceneToAssbin(
AssbinFileWriter fileWriter(shortened, compressed);
fileWriter.WriteBinaryDump(pFile, cmd, pIOSystem, pScene);
}
#ifdef _WIN32
# pragma warning(pop)
#endif // _WIN32
} // end of namespace Assimp

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -53,10 +51,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Assbin/AssbinLoader.h"
#include "Common/assbin_chunks.h"
#include <assimp/MemoryIOWrapper.h>
#include <assimp/mesh.h>
#include <assimp/anim.h>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/mesh.h>
#include <assimp/scene.h>
#include <memory>
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
@ -105,8 +103,9 @@ template <typename T>
T Read(IOStream *stream) {
T t;
size_t res = stream->Read(&t, sizeof(T), 1);
if(res != 1)
if (res != 1) {
throw DeadlyImportError("Unexpected EOF");
}
return t;
}
@ -114,9 +113,9 @@ T Read(IOStream * stream) {
template <>
aiVector3D Read<aiVector3D>(IOStream *stream) {
aiVector3D v;
v.x = Read<float>(stream);
v.y = Read<float>(stream);
v.z = Read<float>(stream);
v.x = Read<ai_real>(stream);
v.y = Read<ai_real>(stream);
v.z = Read<ai_real>(stream);
return v;
}
@ -124,10 +123,10 @@ aiVector3D Read<aiVector3D>(IOStream * stream) {
template <>
aiColor4D Read<aiColor4D>(IOStream *stream) {
aiColor4D c;
c.r = Read<float>(stream);
c.g = Read<float>(stream);
c.b = Read<float>(stream);
c.a = Read<float>(stream);
c.r = Read<ai_real>(stream);
c.g = Read<ai_real>(stream);
c.b = Read<ai_real>(stream);
c.a = Read<ai_real>(stream);
return c;
}
@ -135,10 +134,10 @@ aiColor4D Read<aiColor4D>(IOStream * stream) {
template <>
aiQuaternion Read<aiQuaternion>(IOStream *stream) {
aiQuaternion v;
v.w = Read<float>(stream);
v.x = Read<float>(stream);
v.y = Read<float>(stream);
v.z = Read<float>(stream);
v.w = Read<ai_real>(stream);
v.x = Read<ai_real>(stream);
v.y = Read<ai_real>(stream);
v.z = Read<ai_real>(stream);
return v;
}
@ -147,9 +146,11 @@ template <>
aiString Read<aiString>(IOStream *stream) {
aiString s;
stream->Read(&s.length, 4, 1);
if(s.length)
if (s.length) {
stream->Read(s.data, s.length, 1);
}
s.data[s.length] = 0;
return s;
}
@ -158,7 +159,7 @@ template <>
aiVertexWeight Read<aiVertexWeight>(IOStream *stream) {
aiVertexWeight w;
w.mVertexId = Read<unsigned int>(stream);
w.mWeight = Read<float>(stream);
w.mWeight = Read<ai_real>(stream);
return w;
}
@ -168,7 +169,7 @@ aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream) {
aiMatrix4x4 m;
for (unsigned int i = 0; i < 4; ++i) {
for (unsigned int i2 = 0; i2 < 4; ++i2) {
m[i][i2] = Read<float>(stream);
m[i][i2] = Read<ai_real>(stream);
}
}
return m;
@ -228,8 +229,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** onode, aiNode*
node->mParent = parent;
}
if (numMeshes)
{
if (numMeshes) {
node->mMeshes = new unsigned int[numMeshes];
for (unsigned int i = 0; i < numMeshes; ++i) {
node->mMeshes[i] = Read<unsigned int>(stream);
@ -263,7 +263,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** onode, aiNode*
data = new uint64_t(Read<uint64_t>(stream));
break;
case AI_FLOAT:
data = new float(Read<float>(stream));
data = new ai_real(Read<ai_real>(stream));
break;
case AI_DOUBLE:
data = new double(Read<double>(stream));
@ -312,6 +312,7 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) {
static bool fitsIntoUI16(unsigned int mNumVertices) {
return (mNumVertices < (1u << 16));
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryMesh(IOStream *stream, aiMesh *mesh) {
if (Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMESH)
@ -448,10 +449,8 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) {
/*uint32_t size =*/Read<uint32_t>(stream);
mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream);
if (mat->mNumProperties)
{
if (mat->mProperties)
{
if (mat->mNumProperties) {
if (mat->mProperties) {
delete[] mat->mProperties;
}
mat->mProperties = new aiMaterialProperty *[mat->mNumProperties];
@ -666,7 +665,6 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
ReadBinaryCamera(stream, scene->mCameras[i]);
}
}
}
// -----------------------------------------------------------------------------------
@ -709,8 +707,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
unsigned char *uncompressedData = new unsigned char[uncompressedSize];
int res = uncompress(uncompressedData, &uncompressedSize, compressedData, (uLong)len);
if(res != Z_OK)
{
if (res != Z_OK) {
delete[] uncompressedData;
delete[] compressedData;
pIOHandler->Close(stream);

View File

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

View File

@ -91,20 +91,20 @@ public:
base64_encodestate s;
base64_init_encodestate(&s);
char* const out = new char[std::max(len * 2, static_cast<size_t>(16u))];
const int n = base64_encode_block(reinterpret_cast<const char*>(buffer), static_cast<int>(len), out, &s);
out[n + base64_encode_blockend(out + n, &s)] = '\0';
char* const cur_out = new char[std::max(len * 2, static_cast<size_t>(16u))];
const int n = base64_encode_block(reinterpret_cast<const char *>(buffer), static_cast<int>(len), cur_out, &s);
cur_out[n + base64_encode_blockend(cur_out + n, &s)] = '\0';
// base64 encoding may add newlines, but JSON strings may not contain 'real' newlines
// (only escaped ones). Remove any newlines in out.
for (char* cur = out; *cur; ++cur) {
for (char *cur = cur_out; *cur; ++cur) {
if (*cur == '\n') {
*cur = ' ';
}
}
buff << '\"' << out << "\"\n";
delete[] out;
buff << '\"' << cur_out << "\"\n";
delete[] cur_out;
}
void StartObj(bool is_element = false) {
@ -464,8 +464,8 @@ void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) {
case aiPTI_Float:
if (prop->mDataLength / sizeof(float) > 1) {
out.StartArray();
for (unsigned int i = 0; i < prop->mDataLength / sizeof(float); ++i) {
out.Element(reinterpret_cast<float*>(prop->mData)[i]);
for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(float); ++ii) {
out.Element(reinterpret_cast<float*>(prop->mData)[ii]);
}
out.EndArray();
}
@ -477,8 +477,8 @@ void Write(JSONWriter& out, const aiMaterial& ai, bool is_elem = true) {
case aiPTI_Integer:
if (prop->mDataLength / sizeof(int) > 1) {
out.StartArray();
for (unsigned int i = 0; i < prop->mDataLength / sizeof(int); ++i) {
out.Element(reinterpret_cast<int*>(prop->mData)[i]);
for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(int); ++ii) {
out.Element(reinterpret_cast<int*>(prop->mData)[ii]);
}
out.EndArray();
} else {

View File

@ -373,25 +373,25 @@ void WriteDump(const char* pFile, const char* cmd, const aiScene* scene, IOStrea
ioprintf(io," size=\"%i\">\n\t\t\t\t",
static_cast<int>(prop->mDataLength/sizeof(float)));
for (unsigned int p = 0; p < prop->mDataLength/sizeof(float);++p) {
ioprintf(io,"%f ",*((float*)(prop->mData+p*sizeof(float))));
for (unsigned int pp = 0; pp < prop->mDataLength/sizeof(float);++pp) {
ioprintf(io,"%f ",*((float*)(prop->mData+pp*sizeof(float))));
}
}
else if (prop->mType == aiPTI_Integer) {
ioprintf(io," size=\"%i\">\n\t\t\t\t",
static_cast<int>(prop->mDataLength/sizeof(int)));
for (unsigned int p = 0; p < prop->mDataLength/sizeof(int);++p) {
ioprintf(io,"%i ",*((int*)(prop->mData+p*sizeof(int))));
for (unsigned int pp = 0; pp < prop->mDataLength/sizeof(int);++pp) {
ioprintf(io,"%i ",*((int*)(prop->mData+pp*sizeof(int))));
}
}
else if (prop->mType == aiPTI_Buffer) {
ioprintf(io," size=\"%i\">\n\t\t\t\t",
static_cast<int>(prop->mDataLength));
for (unsigned int p = 0; p < prop->mDataLength;++p) {
ioprintf(io,"%2x ",prop->mData[p]);
if (p && 0 == p%30) {
for (unsigned int pp = 0; pp< prop->mDataLength;++pp) {
ioprintf(io,"%2x ",prop->mData[pp]);
if (pp && 0 == pp%30) {
ioprintf(io,"\n\t\t\t\t");
}
}

View File

@ -155,37 +155,38 @@ AI_WONT_RETURN void B3DImporter::Fail( string str ){
// ------------------------------------------------------------------------------------------------
int B3DImporter::ReadByte(){
if( _pos<_buf.size() ) {
return _buf[_pos++];
if (_pos > _buf.size()) {
Fail("EOF");
}
Fail( "EOF" );
return 0;
return _buf[_pos++];
}
// ------------------------------------------------------------------------------------------------
int B3DImporter::ReadInt(){
if( _pos+4<=_buf.size() ){
if (_pos + 4 > _buf.size()) {
Fail("EOF");
}
int n;
memcpy(&n, &_buf[_pos], 4);
_pos+=4;
return n;
}
Fail( "EOF" );
return 0;
}
// ------------------------------------------------------------------------------------------------
float B3DImporter::ReadFloat() {
if( _pos+4<=_buf.size() ){
if (_pos + 4 > _buf.size()) {
Fail("EOF");
}
float n;
memcpy(&n, &_buf[_pos], 4);
_pos+=4;
return n;
}
Fail( "EOF" );
return 0.0f;
}
// ------------------------------------------------------------------------------------------------
aiVector2D B3DImporter::ReadVec2(){
@ -214,6 +215,9 @@ aiQuaternion B3DImporter::ReadQuat(){
// ------------------------------------------------------------------------------------------------
string B3DImporter::ReadString(){
if (_pos > _buf.size()) {
Fail("EOF");
}
string str;
while( _pos<_buf.size() ){
char c=(char)ReadByte();
@ -222,7 +226,6 @@ string B3DImporter::ReadString(){
}
str+=c;
}
Fail( "EOF" );
return string();
}
@ -247,7 +250,7 @@ void B3DImporter::ExitChunk(){
}
// ------------------------------------------------------------------------------------------------
unsigned B3DImporter::ChunkSize(){
size_t B3DImporter::ChunkSize(){
return _stack.back()-_pos;
}
// ------------------------------------------------------------------------------------------------
@ -356,12 +359,12 @@ void B3DImporter::ReadVRTS(){
}
int sz = 12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4);
int n_verts=ChunkSize()/sz;
size_t n_verts = ChunkSize()/sz;
int v0=static_cast<int>(_vertices.size());
_vertices.resize( v0+n_verts );
for( int i=0;i<n_verts;++i ){
for( unsigned int i=0;i<n_verts;++i ){
Vertex &v=_vertices[v0+i];
memset( v.bones,0,sizeof(v.bones) );
@ -377,13 +380,13 @@ void B3DImporter::ReadVRTS(){
ReadQuat(); //skip v 4bytes...
}
for( int i=0;i<_tcsets;++i ){
for( int j=0;j<_tcsets;++j ){
float t[4]={0,0,0,0};
for( int j=0;j<_tcsize;++j ){
t[j]=ReadFloat();
for( int k=0;k<_tcsize;++k ){
t[k]=ReadFloat();
}
t[1] = 1 - t[1];
if( !i ) {
if( !j ) {
v.texcoords = aiVector3D( t[0],t[1],t[2] );
}
}
@ -408,10 +411,10 @@ void B3DImporter::ReadTRIS(int v0) {
mesh->mNumFaces = 0;
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
int n_tris = ChunkSize() / 12;
size_t n_tris = ChunkSize() / 12;
aiFace *face = mesh->mFaces = new aiFace[n_tris];
for (int i = 0; i < n_tris; ++i) {
for (unsigned int i = 0; i < n_tris; ++i) {
int i0 = ReadInt() + v0;
int i1 = ReadInt() + v0;
int i2 = ReadInt() + v0;
@ -463,7 +466,7 @@ void B3DImporter::ReadBONE(int id) {
Vertex &v = _vertices[vertex];
for (int i = 0; i < 4; ++i) {
if (!v.weights[i]) {
v.bones[i] = id;
v.bones[i] = static_cast<unsigned char>(id);
v.weights[i] = weight;
break;
}
@ -547,24 +550,24 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
vector<aiNode*> children;
while( ChunkSize() ){
string t=ReadChunk();
if( t=="MESH" ){
const string chunk = ReadChunk();
if (chunk == "MESH") {
unsigned int n= static_cast<unsigned int>(_meshes.size());
ReadMESH();
for( unsigned int i=n;i<static_cast<unsigned int>(_meshes.size());++i ){
meshes.push_back( i );
}
}else if( t=="BONE" ){
} else if (chunk == "BONE") {
ReadBONE( nodeid );
}else if( t=="ANIM" ){
} else if (chunk == "ANIM") {
ReadANIM();
}else if( t=="KEYS" ){
} else if (chunk == "KEYS") {
if( !nodeAnim ){
nodeAnim.reset(new aiNodeAnim);
nodeAnim->mNodeName=node->mName;
}
ReadKEYS( nodeAnim.get() );
}else if( t=="NODE" ){
} else if (chunk == "NODE") {
aiNode *child=ReadNODE( node );
children.push_back( child );
}
@ -613,12 +616,12 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
}
while( ChunkSize() ){
string t=ReadChunk();
if( t=="TEXS" ){
const string chunk = ReadChunk();
if (chunk == "TEXS") {
ReadTEXS();
}else if( t=="BRUS" ){
} else if (chunk == "BRUS") {
ReadBRUS();
}else if( t=="NODE" ){
} else if (chunk == "NODE") {
ReadNODE( 0 );
}
ExitChunk();
@ -656,37 +659,40 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
vector< vector<aiVertexWeight> > vweights( _nodes.size() );
for( int i=0;i<n_verts;i+=3 ){
for( int j=0;j<3;++j ){
Vertex &v=_vertices[face->mIndices[j]];
for (int vertIdx = 0; vertIdx < n_verts; vertIdx += 3) {
for (int faceIndex = 0; faceIndex < 3; ++faceIndex) {
Vertex &v = _vertices[face->mIndices[faceIndex]];
*mv++=v.vertex;
if( mn ) *mn++=v.normal;
if( mc ) *mc++=v.texcoords;
face->mIndices[j]=i+j;
face->mIndices[faceIndex] = vertIdx + faceIndex;
for( int k=0;k<4;++k ){
if( !v.weights[k] ) break;
if( !v.weights[k] )
break;
int bone = v.bones[k];
float weight = v.weights[k];
vweights[bone].push_back( aiVertexWeight(i+j,weight) );
vweights[bone].push_back(aiVertexWeight(vertIdx + faceIndex, weight));
}
}
++face;
}
vector<aiBone*> bones;
for(size_t i=0;i<vweights.size();++i ){
vector<aiVertexWeight> &weights=vweights[i];
if( !weights.size() ) continue;
for (size_t weightIndx = 0; weightIndx < vweights.size(); ++weightIndx) {
vector<aiVertexWeight> &weights = vweights[weightIndx];
if (!weights.size()) {
continue;
}
aiBone *bone = new aiBone;
bones.push_back( bone );
aiNode *bnode=_nodes[i];
aiNode *bnode = _nodes[weightIndx];
bone->mName = bnode->mName;
bone->mNumWeights = static_cast<unsigned int>(weights.size());

View File

@ -82,7 +82,7 @@ private:
std::string ReadString();
std::string ReadChunk();
void ExitChunk();
unsigned ChunkSize();
size_t ChunkSize();
template<class T>
T *to_array( const std::vector<T> &v );
@ -112,10 +112,10 @@ private:
void ReadBB3D( aiScene *scene );
unsigned _pos;
size_t _pos;
// unsigned _size;
std::vector<unsigned char> _buf;
std::vector<unsigned> _stack;
std::vector<size_t> _stack;
std::vector<std::string> _textures;
std::vector<std::unique_ptr<aiMaterial> > _materials;

View File

@ -429,7 +429,7 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
name.length = 1+ ASSIMP_itoa10(name.data+1,static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(conv_data.textures->size()));
conv_data.textures->push_back(new aiTexture());
aiTexture* tex = conv_data.textures->back();
aiTexture* curTex = conv_data.textures->back();
// usually 'img->name' will be the original file name of the embedded textures,
// so we can extract the file extension from it.
@ -439,19 +439,19 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
--s;
}
tex->achFormatHint[0] = s+1>e ? '\0' : ::tolower( s[1] );
tex->achFormatHint[1] = s+2>e ? '\0' : ::tolower( s[2] );
tex->achFormatHint[2] = s+3>e ? '\0' : ::tolower( s[3] );
tex->achFormatHint[3] = '\0';
curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower(s[1]);
curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower(s[2]);
curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower(s[3]);
curTex->achFormatHint[3] = '\0';
// tex->mHeight = 0;
tex->mWidth = img->packedfile->size;
uint8_t* ch = new uint8_t[tex->mWidth];
curTex->mWidth = img->packedfile->size;
uint8_t *ch = new uint8_t[curTex->mWidth];
conv_data.db.reader->SetCurrentPos(static_cast<size_t>( img->packedfile->data->val));
conv_data.db.reader->CopyAndAdvance(ch,tex->mWidth);
conv_data.db.reader->CopyAndAdvance(ch, curTex->mWidth);
tex->pcData = reinterpret_cast<aiTexel*>(ch);
curTex->pcData = reinterpret_cast<aiTexel *>(ch);
LogInfo("Reading embedded texture, original file was "+std::string(img->name));
} else {
@ -1078,9 +1078,9 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
const aiFace& f = out->mFaces[out->mNumFaces++];
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
vo->x = v->uv[i][0];
vo->y = v->uv[i][1];
for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
vo->x = v->uv[j][0];
vo->y = v->uv[j][1];
}
}
@ -1098,8 +1098,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
vo->x = uv.uv[0];
vo->y = uv.uv[1];
}
}
else {
} else {
// create textureCoords for every mapped tex
for (uint32_t m = 0; m < itMatTexUvMapping->second.size(); ++m) {
const MLoopUV *tm = itMatTexUvMapping->second[m];
@ -1139,9 +1138,9 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
const aiFace& f = out->mFaces[out->mNumFaces++];
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
vo->x = v->uv[i][0];
vo->y = v->uv[i][1];
for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
vo->x = v->uv[j][0];
vo->y = v->uv[j][1];
}
}
}

View File

@ -57,7 +57,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
using namespace Assimp::Blender;
template <typename T> BlenderModifier* god() {
template <typename T>
BlenderModifier *god() {
return new T();
}
@ -71,14 +72,12 @@ static const fpCreateModifier creators[] = {
};
// ------------------------------------------------------------------------------------------------
struct SharedModifierData : ElemBase
{
struct SharedModifierData : ElemBase {
ModifierData modifier;
};
// ------------------------------------------------------------------------------------------------
void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object )
{
void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_data, const Scene &in, const Object &orig_object) {
size_t cnt = 0u, ful = 0u;
// NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
@ -146,19 +145,15 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_d
}
}
// ------------------------------------------------------------------------------------------------
bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
{
bool BlenderModifier_Mirror ::IsActive(const ModifierData &modin) {
return modin.type == ModifierData::eModifierType_Mirror;
}
// ------------------------------------------------------------------------------------------------
void BlenderModifier_Mirror ::DoIt(aiNode &out, ConversionData &conv_data, const ElemBase &orig_modifier,
const Scene & /*in*/,
const Object& orig_object )
{
const Object &orig_object) {
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const MirrorModifierData &mir = static_cast<const MirrorModifierData &>(orig_modifier);
ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
@ -178,39 +173,46 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
if (mir.mirror_ob) {
const aiVector3D center(mir.mirror_ob->obmat[3][0], mir.mirror_ob->obmat[3][1], mir.mirror_ob->obmat[3][2]);
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mVertices[i];
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mVertices[j];
v.x = center.x + xs * (center.x - v.x);
v.y = center.y + ys * (center.y - v.y);
v.z = center.z + zs * (center.z - v.z);
}
}
else {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mVertices[i];
v.x *= xs;v.y *= ys;v.z *= zs;
} else {
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mVertices[j];
v.x *= xs;
v.y *= ys;
v.z *= zs;
}
}
if (mesh->mNormals) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mNormals[i];
v.x *= xs;v.y *= ys;v.z *= zs;
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mNormals[j];
v.x *= xs;
v.y *= ys;
v.z *= zs;
}
}
if (mesh->mTangents) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mTangents[i];
v.x *= xs;v.y *= ys;v.z *= zs;
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mTangents[j];
v.x *= xs;
v.y *= ys;
v.z *= zs;
}
}
if (mesh->mBitangents) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mBitangents[i];
v.x *= xs;v.y *= ys;v.z *= zs;
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mBitangents[j];
v.x *= xs;
v.y *= ys;
v.z *= zs;
}
}
@ -218,16 +220,17 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mTextureCoords[n][i];
v.x *= us;v.y *= vs;
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mTextureCoords[n][j];
v.x *= us;
v.y *= vs;
}
}
// Only reverse the winding order if an odd number of axes were mirrored.
if (xs * ys * zs < 0) {
for( unsigned int i = 0; i < mesh->mNumFaces; i++) {
aiFace& face = mesh->mFaces[i];
for (unsigned int j = 0; j < mesh->mNumFaces; ++j ) {
aiFace &face = mesh->mFaces[j];
for (unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi)
std::swap(face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]);
}
@ -250,23 +253,20 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
}
// ------------------------------------------------------------------------------------------------
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
{
bool BlenderModifier_Subdivision ::IsActive(const ModifierData &modin) {
return modin.type == ModifierData::eModifierType_Subsurf;
}
// ------------------------------------------------------------------------------------------------
void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data, const ElemBase &orig_modifier,
const Scene & /*in*/,
const Object& orig_object )
{
const Object &orig_object) {
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const SubsurfModifierData &mir = static_cast<const SubsurfModifierData &>(orig_modifier);
ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
Subdivider::Algorithm algo;
switch (mir.subdivType)
{
switch (mir.subdivType) {
case SubsurfModifierData::TYPE_CatmullClarke:
algo = Subdivider::CATMULL_CLARKE;
break;

View File

@ -861,15 +861,15 @@ if ((CMAKE_COMPILER_IS_MINGW) AND (CMAKE_BUILD_TYPE MATCHES Debug))
SET_SOURCE_FILES_PROPERTIES(Importer/StepFile/StepFileGen1.cpp PROPERTIES STATIC_LIBRARY_FLAGS -Os )
endif()
ADD_ASSIMP_IMPORTER( STEP
Step/STEPFile.h
Importer/StepFile/StepFileImporter.h
Importer/StepFile/StepFileImporter.cpp
Importer/StepFile/StepFileGen1.cpp
Importer/StepFile/StepFileGen2.cpp
Importer/StepFile/StepFileGen3.cpp
Importer/StepFile/StepReaderGen.h
)
#ADD_ASSIMP_IMPORTER( STEP
# Step/STEPFile.h
# Importer/StepFile/StepFileImporter.h
# Importer/StepFile/StepFileImporter.cpp
# Importer/StepFile/StepFileGen1.cpp
# Importer/StepFile/StepFileGen2.cpp
# Importer/StepFile/StepFileGen3.cpp
# Importer/StepFile/StepReaderGen.h
#)
if ((NOT ASSIMP_NO_EXPORT) OR (NOT ASSIMP_EXPORTERS_ENABLED STREQUAL ""))
SET( Exporter_SRCS
@ -886,7 +886,7 @@ SET( Extra_SRCS
SOURCE_GROUP( Extra FILES ${Extra_SRCS})
# irrXML
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(irrXML)
find_package(irrXML CONFIG REQUIRED)
ELSE()
@ -894,7 +894,7 @@ ELSE()
ENDIF()
# utf8
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(utf8)
find_package(utf8 CONFIG REQUIRED)
ELSE()
@ -902,7 +902,7 @@ ELSE()
ENDIF()
# polyclipping
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(polyclipping)
find_package(polyclipping CONFIG REQUIRED)
ELSE()
@ -914,7 +914,7 @@ ELSE()
ENDIF()
# poly2tri
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(poly2tri)
find_package(poly2tri CONFIG REQUIRED)
ELSE()
@ -935,7 +935,7 @@ ELSE()
ENDIF()
# minizip/unzip
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(minizip)
find_package(minizip CONFIG REQUIRED)
ELSE()
@ -950,7 +950,7 @@ ELSE()
ENDIF()
# zip (https://github.com/kuba--/zip)
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(zip)
find_package(zip CONFIG REQUIRED)
ELSE()
@ -971,7 +971,7 @@ ELSE()
ENDIF()
# openddlparser
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(openddlparser)
find_package(openddlparser CONFIG REQUIRED)
ELSE()
@ -994,7 +994,7 @@ ELSE()
ENDIF()
# Open3DGC
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
# Nothing to do, not available in Hunter yet.
ELSE()
SET ( open3dgc_SRCS
@ -1035,7 +1035,7 @@ ENDIF()
# RT-extensions is used in "contrib/Open3DGC/o3dgcTimer.h" for collecting statistics. Pointed file
# has implementation for different platforms: WIN32, __MACH__ and other ("else" block).
FIND_PACKAGE(RT QUIET)
IF (NOT HUNTER_ENABLED AND (RT_FOUND OR MSVC))
IF (NOT ASSIMP_HUNTER_ENABLED AND (RT_FOUND OR MSVC))
SET( ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC 1 )
ADD_DEFINITIONS( -DASSIMP_IMPORTER_GLTF_USE_OPEN3DGC=1 )
ELSE ()
@ -1045,7 +1045,7 @@ ELSE ()
ENDIF ()
# RapidJSON
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(RapidJSON)
find_package(RapidJSON CONFIG REQUIRED)
ELSE()
@ -1068,7 +1068,7 @@ if ( MSVC )
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
endif ()
IF(NOT HUNTER_ENABLED)
IF(NOT ASSIMP_HUNTER_ENABLED)
if (UNZIP_FOUND)
SET (unzip_compile_SRCS "")
else ()
@ -1118,7 +1118,7 @@ SET( assimp_src
)
ADD_DEFINITIONS( -DOPENDDLPARSER_BUILD )
IF(NOT HUNTER_ENABLED)
IF(NOT ASSIMP_HUNTER_ENABLED)
INCLUDE_DIRECTORIES(
${IRRXML_INCLUDE_DIR}
../contrib/openddlparser/include
@ -1139,7 +1139,7 @@ TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC
$<INSTALL_INTERFACE:include>
)
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
TARGET_LINK_LIBRARIES(assimp
PUBLIC
polyclipping::polyclipping
@ -1212,7 +1212,7 @@ SET_TARGET_PROPERTIES( assimp PROPERTIES
)
if (APPLE)
if (BUILD_FRAMEWORK)
if (ASSIMP_BUILD_FRAMEWORK)
SET_TARGET_PROPERTIES( assimp PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION C
@ -1232,7 +1232,7 @@ ENDIF()
# Build against external unzip, or add ../contrib/unzip so
# assimp can #include "unzip.h"
IF(NOT HUNTER_ENABLED)
IF(NOT ASSIMP_HUNTER_ENABLED)
if (UNZIP_FOUND)
INCLUDE_DIRECTORIES(${UNZIP_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(assimp ${UNZIP_LIBRARIES})
@ -1246,7 +1246,7 @@ IF (RT_FOUND AND ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC)
TARGET_LINK_LIBRARIES(assimp ${RT_LIBRARY})
ENDIF ()
IF(HUNTER_ENABLED)
IF(ASSIMP_HUNTER_ENABLED)
INSTALL( TARGETS assimp
EXPORT "${TARGETS_EXPORT_NAME}"
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}

View File

@ -1015,8 +1015,8 @@ void COBImporter::ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const
// XXX backface culling flag is 0x10 in flags
// hole?
bool hole;
if ((hole = (reader.GetI1() & 0x08) != 0)) {
bool hole = (reader.GetI1() & 0x08) != 0;
if ( hole ) {
// XXX Basically this should just work fine - then triangulator
// should output properly triangulated data even for polygons
// with holes. Test data specific to COB is needed to confirm it.

View File

@ -75,10 +75,10 @@ struct Face
// ------------------
/** COB chunk header information */
const unsigned int NO_SIZE = UINT_MAX;
struct ChunkInfo
{
enum {NO_SIZE=UINT_MAX};
ChunkInfo ()
: id (0)
, parent_id (0)

View File

@ -1335,32 +1335,34 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
PushTag();
std::string node_idstr;
std::string cur_node_idstr;
for (size_t a = 0; a < anim->mNumChannels; ++a) {
const aiNodeAnim * nodeAnim = anim->mChannels[a];
// sanity check
if ( nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys ) continue;
if (nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys) {
continue;
}
{
node_idstr.clear();
node_idstr += nodeAnim->mNodeName.data;
node_idstr += std::string( "_matrix-input" );
cur_node_idstr.clear();
cur_node_idstr += nodeAnim->mNodeName.data;
cur_node_idstr += std::string("_matrix-input");
std::vector<ai_real> frames;
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
frames.push_back(static_cast<ai_real>(nodeAnim->mPositionKeys[i].mTime));
}
WriteFloatArray( node_idstr , FloatType_Time, (const ai_real*) frames.data(), frames.size());
WriteFloatArray(cur_node_idstr, FloatType_Time, (const ai_real *)frames.data(), frames.size());
frames.clear();
}
{
node_idstr.clear();
cur_node_idstr.clear();
node_idstr += nodeAnim->mNodeName.data;
node_idstr += std::string("_matrix-output");
cur_node_idstr += nodeAnim->mNodeName.data;
cur_node_idstr += std::string("_matrix-output");
std::vector<ai_real> keyframes;
keyframes.reserve(nodeAnim->mNumPositionKeys * 16);
@ -1385,7 +1387,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
}
}
WriteFloatArray( node_idstr, FloatType_Mat4x4, (const ai_real*) keyframes.data(), keyframes.size() / 16);
WriteFloatArray(cur_node_idstr, FloatType_Mat4x4, (const ai_real *)keyframes.data(), keyframes.size() / 16);
}
{
@ -1401,16 +1403,16 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
}
}
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-interpolation");
std::string arrayId = XMLIDEncode(node_idstr) + "-array";
const std::string cur_node_idstr2 = nodeAnim->mNodeName.data + std::string("_matrix-interpolation");
std::string arrayId = XMLIDEncode(cur_node_idstr2) + "-array";
mOutput << startstr << "<source id=\"" << XMLIDEncode(node_idstr) << "\">" << endstr;
mOutput << startstr << "<source id=\"" << XMLIDEncode(cur_node_idstr2) << "\">" << endstr;
PushTag();
// source array
mOutput << startstr << "<Name_array id=\"" << arrayId << "\" count=\"" << names.size() << "\"> ";
for( size_t a = 0; a < names.size(); ++a ) {
mOutput << names[a] << " ";
for( size_t aa = 0; aa < names.size(); ++aa ) {
mOutput << names[aa] << " ";
}
mOutput << "</Name_array>" << endstr;
@ -1672,13 +1674,13 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
PushTag();
mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLIDEncode(materials[mesh->mMaterialIndex].name) << "\">" << endstr;
PushTag();
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
for( size_t aa = 0; aa < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++aa )
{
if( mesh->HasTextureCoords( static_cast<unsigned int>(a) ) )
if( mesh->HasTextureCoords( static_cast<unsigned int>(aa) ) )
// semantic as in <texture texcoord=...>
// input_semantic as in <input semantic=...>
// input_set as in <input set=...>
mOutput << startstr << "<bind_vertex_input semantic=\"CHANNEL" << a << "\" input_semantic=\"TEXCOORD\" input_set=\"" << a << "\"/>" << endstr;
mOutput << startstr << "<bind_vertex_input semantic=\"CHANNEL" << aa << "\" input_semantic=\"TEXCOORD\" input_set=\"" << aa << "\"/>" << endstr;
}
PopTag();
mOutput << startstr << "</instance_material>" << endstr;

View File

@ -714,8 +714,8 @@ void ColladaParser::ReadAnimation(Collada::Animation* pParent)
else if (IsElement("sampler"))
{
// read the ID to assign the corresponding collada channel afterwards.
int indexID = GetAttribute("id");
std::string id = mReader->getAttributeValue(indexID);
int indexId = GetAttribute("id");
std::string id = mReader->getAttributeValue(indexId);
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
// have it read into a channel
@ -3339,13 +3339,12 @@ void ColladaParser::TestClosing(const char* pName) {
// Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes
int ColladaParser::GetAttribute(const char* pAttr) const {
int index = TestAttribute(pAttr);
if (index != -1) {
return index;
if (index == -1) {
ThrowException(format() << "Expected attribute \"" << pAttr << "\" for element <" << mReader->getNodeName() << ">.");
}
// attribute not found -> throw an exception
ThrowException(format() << "Expected attribute \"" << pAttr << "\" for element <" << mReader->getNodeName() << ">.");
return -1;
return index;
}
// ------------------------------------------------------------------------------------------------

View File

@ -146,7 +146,7 @@ aiScene* BaseImporter::ReadFile(Importer* pImp, const std::string& pFile, IOSyst
}
// ------------------------------------------------------------------------------------------------
void BaseImporter::SetupProperties(const Importer* pImp)
void BaseImporter::SetupProperties(const Importer* )
{
// the default implementation does nothing
}

View File

@ -70,7 +70,7 @@ namespace
template<>
size_t select_ftell<8>(FILE* file)
{
return ::_ftelli64(file);
return (size_t)::_ftelli64(file);
}
template<>

View File

@ -44,15 +44,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StringComparison.h>
#include <assimp/DefaultIOSystem.h>
#include <assimp/DefaultIOStream.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/DefaultIOSystem.h>
#include <assimp/ai_assert.h>
#include <stdlib.h>
#include <assimp/DefaultLogger.hpp>
#ifdef __unix__
#include <sys/param.h>
# include <stdlib.h>
# include <sys/param.h>
#endif
#ifdef _WIN32
@ -62,8 +62,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
#ifdef _WIN32
static std::wstring Utf8ToWide(const char* in)
{
static std::wstring Utf8ToWide(const char *in) {
int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0);
// size includes terminating null; std::wstring adds null automatically
std::wstring out(static_cast<size_t>(size) - 1, L'\0');
@ -71,8 +70,7 @@ static std::wstring Utf8ToWide(const char* in)
return out;
}
static std::string WideToUtf8(const wchar_t* in)
{
static std::string WideToUtf8(const wchar_t *in) {
int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr);
// size includes terminating null; std::string adds null automatically
std::string out(static_cast<size_t>(size) - 1, '\0');
@ -83,8 +81,7 @@ static std::string WideToUtf8(const wchar_t* in)
// ------------------------------------------------------------------------------------------------
// Tests for the existence of a file at the given path.
bool DefaultIOSystem::Exists(const char* pFile) const
{
bool DefaultIOSystem::Exists(const char *pFile) const {
#ifdef _WIN32
struct __stat64 filestat;
if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) {
@ -92,18 +89,19 @@ bool DefaultIOSystem::Exists(const char* pFile) const
}
#else
FILE *file = ::fopen(pFile, "rb");
if (!file)
if (!file) {
return false;
}
::fclose(file);
#endif
return true;
}
// ------------------------------------------------------------------------------------------------
// Open a new file with a given path.
IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode)
{
IOStream *DefaultIOSystem::Open(const char *strFile, const char *strMode) {
ai_assert(strFile != nullptr);
ai_assert(strMode != nullptr);
FILE *file;
@ -112,23 +110,22 @@ IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode)
#else
file = ::fopen(strFile, strMode);
#endif
if (!file)
if (!file) {
return nullptr;
}
return new DefaultIOStream(file, strFile);
}
// ------------------------------------------------------------------------------------------------
// Closes the given file and releases all resources associated with it.
void DefaultIOSystem::Close(IOStream* pFile)
{
void DefaultIOSystem::Close(IOStream *pFile) {
delete pFile;
}
// ------------------------------------------------------------------------------------------------
// Returns the operation specific directory separator
char DefaultIOSystem::getOsSeparator() const
{
char DefaultIOSystem::getOsSeparator() const {
#ifndef _WIN32
return '/';
#else
@ -138,15 +135,13 @@ char DefaultIOSystem::getOsSeparator() const
// ------------------------------------------------------------------------------------------------
// IOSystem default implementation (ComparePaths isn't a pure virtual function)
bool IOSystem::ComparePaths(const char* one, const char* second) const
{
bool IOSystem::ComparePaths(const char *one, const char *second) const {
return !ASSIMP_stricmp(one, second);
}
// ------------------------------------------------------------------------------------------------
// Convert a relative path into an absolute path
inline static std::string MakeAbsolutePath(const char* in)
{
inline static std::string MakeAbsolutePath(const char *in) {
ai_assert(in);
std::string out;
#ifdef _WIN32
@ -173,8 +168,7 @@ inline static std::string MakeAbsolutePath(const char* in)
// ------------------------------------------------------------------------------------------------
// DefaultIOSystem's more specialized implementation
bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const
{
bool DefaultIOSystem::ComparePaths(const char *one, const char *second) const {
// chances are quite good both paths are formatted identically,
// so we can hopefully return here already
if (!ASSIMP_stricmp(one, second))
@ -187,8 +181,7 @@ bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const
}
// ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::fileName(const std::string& path)
{
std::string DefaultIOSystem::fileName(const std::string &path) {
std::string ret = path;
std::size_t last = ret.find_last_of("\\/");
if (last != std::string::npos) ret = ret.substr(last + 1);
@ -196,8 +189,7 @@ std::string DefaultIOSystem::fileName(const std::string& path)
}
// ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::completeBaseName(const std::string& path)
{
std::string DefaultIOSystem::completeBaseName(const std::string &path) {
std::string ret = fileName(path);
std::size_t pos = ret.find_last_of('.');
if (pos != std::string::npos) ret = ret.substr(0, pos);
@ -205,8 +197,7 @@ std::string DefaultIOSystem::completeBaseName(const std::string& path)
}
// ------------------------------------------------------------------------------------------------
std::string DefaultIOSystem::absolutePath(const std::string& path)
{
std::string DefaultIOSystem::absolutePath(const std::string &path) {
std::string ret = path;
std::size_t last = ret.find_last_of("\\/");
if (last != std::string::npos) ret = ret.substr(0, last);

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -76,6 +74,11 @@ Here we implement only the C++ interface (Assimp::Exporter).
namespace Assimp {
#ifdef _WIN32
# pragma warning( disable : 4800 )
#endif // _WIN32
// PostStepRegistry.cpp
void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -200,9 +198,9 @@ corresponding preprocessor flag to selectively disable formats.
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
# include "M3D/M3DImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
# include "Importer/StepFile/StepFileImporter.h"
#endif
//#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
//# include "Importer/StepFile/StepFileImporter.h"
//#endif
namespace Assimp {
@ -361,9 +359,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
out.push_back( new MMDImporter() );
#endif
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
out.push_back(new StepFile::StepFileImporter());
#endif
//#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
// out.push_back(new StepFile::StepFileImporter());
//#endif
}
/** will delete all registered importers. */

View File

@ -53,6 +53,10 @@ using namespace Assimp;
# define CHAR_BIT 8
#endif
#ifdef _WIN32
# pragma warning(disable : 4127)
#endif // _WIN32
// ------------------------------------------------------------------------------------------------
// Constructs a spatially sorted representation from the given position array.
SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions,

View File

@ -53,6 +53,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
void mydummy() {}
#ifdef _WIN32
# pragma warning( disable : 4709 )
#endif // _WIN32
// ------------------------------------------------------------------------------------------------
/** Subdivider stub class to implement the Catmull-Clarke subdivision algorithm. The
* implementation is basing on recursive refinement. Directly evaluating the result is also

View File

@ -42,9 +42,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Actually just a dummy, used by the compiler to build the precompiled header.
#include <assimp/version.h>
#include <assimp/scene.h>
#include "ScenePrivate.h"
#include <assimp/scene.h>
#include <assimp/version.h>
#include "revision.h"
@ -57,8 +57,7 @@ static const char* LEGAL_INFORMATION =
"(c) 2006-2020, assimp team\n"
"License under the terms and conditions of the 3-clause BSD license\n"
"http://assimp.org\n"
;
"http://assimp.org\n";
// ------------------------------------------------------------------------------------------------
// Get legal string
@ -119,23 +118,8 @@ ASSIMP_API const char *aiGetBranchName() {
}
// ------------------------------------------------------------------------------------------------
ASSIMP_API aiScene::aiScene()
: mFlags(0)
, mRootNode(nullptr)
, mNumMeshes(0)
, mMeshes(nullptr)
, mNumMaterials(0)
, mMaterials(nullptr)
, mNumAnimations(0)
, mAnimations(nullptr)
, mNumTextures(0)
, mTextures(nullptr)
, mNumLights(0)
, mLights(nullptr)
, mNumCameras(0)
, mCameras(nullptr)
, mMetaData(nullptr)
, mPrivate(new Assimp::ScenePrivateData()) {
ASSIMP_API aiScene::aiScene() :
mFlags(0), mRootNode(nullptr), mNumMeshes(0), mMeshes(nullptr), mNumMaterials(0), mMaterials(nullptr), mNumAnimations(0), mAnimations(nullptr), mNumTextures(0), mTextures(nullptr), mNumLights(0), mLights(nullptr), mNumCameras(0), mCameras(nullptr), mMetaData(nullptr), mPrivate(new Assimp::ScenePrivateData()) {
// empty
}
@ -184,4 +168,3 @@ ASSIMP_API aiScene::~aiScene() {
delete static_cast<Assimp::ScenePrivateData *>(mPrivate);
}

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -44,8 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Zip File I/O implementation for #Importer
*/
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/BaseImporter.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/ai_assert.h>
@ -59,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
namespace Assimp {
// ----------------------------------------------------------------
// Wraps an existing Assimp::IOSystem for unzip
class IOSystem2Unzip {
@ -79,12 +79,10 @@ namespace Assimp {
const char *mode_fopen = nullptr;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) {
mode_fopen = "rb";
}
else {
} else {
if (mode & ZLIB_FILEFUNC_MODE_EXISTING) {
mode_fopen = "r+b";
}
else {
} else {
if (mode & ZLIB_FILEFUNC_MODE_CREATE) {
mode_fopen = "wb";
}
@ -176,6 +174,7 @@ namespace Assimp {
class ZipFile : public IOStream {
friend class ZipFileInfo;
explicit ZipFile(size_t size);
public:
virtual ~ZipFile();
@ -193,11 +192,9 @@ namespace Assimp {
std::unique_ptr<uint8_t[]> m_Buffer;
};
// ----------------------------------------------------------------
// Info about a read-only file inside a ZIP
class ZipFileInfo
{
class ZipFileInfo {
public:
explicit ZipFileInfo(unzFile zip_handle, size_t size);
@ -209,8 +206,8 @@ namespace Assimp {
unz_file_pos_s m_ZipFilePos;
};
ZipFileInfo::ZipFileInfo(unzFile zip_handle, size_t size)
: m_Size(size) {
ZipFileInfo::ZipFileInfo(unzFile zip_handle, size_t size) :
m_Size(size) {
ai_assert(m_Size != 0);
// Workaround for MSVC 2013 - C2797
m_ZipFilePos.num_of_file = 0;
@ -229,8 +226,7 @@ namespace Assimp {
ZipFile *zip_file = new ZipFile(m_Size);
if (unzReadCurrentFile(zip_handle, zip_file->m_Buffer.get(), static_cast<unsigned int>(m_Size)) != static_cast<int>(m_Size))
{
if (unzReadCurrentFile(zip_handle, zip_file->m_Buffer.get(), static_cast<unsigned int>(m_Size)) != static_cast<int>(m_Size)) {
// Failed, release the memory
delete zip_file;
zip_file = nullptr;
@ -240,8 +236,8 @@ namespace Assimp {
return zip_file;
}
ZipFile::ZipFile(size_t size)
: m_Size(size) {
ZipFile::ZipFile(size_t size) :
m_Size(size) {
ai_assert(m_Size != 0);
m_Buffer = std::unique_ptr<uint8_t[]>(new uint8_t[m_Size]);
}
@ -256,8 +252,7 @@ namespace Assimp {
// Clip down to file size
size_t byteSize = pSize * pCount;
if ((byteSize + m_SeekPtr) > m_Size)
{
if ((byteSize + m_SeekPtr) > m_Size) {
pCount = (m_Size - m_SeekPtr) / pSize;
byteSize = pSize * pCount;
if (byteSize == 0)
@ -276,8 +271,7 @@ namespace Assimp {
}
aiReturn ZipFile::Seek(size_t pOffset, aiOrigin pOrigin) {
switch (pOrigin)
{
switch (pOrigin) {
case aiOrigin_SET: {
if (pOffset > m_Size) return aiReturn_FAILURE;
m_SeekPtr = pOffset;
@ -335,8 +329,9 @@ namespace Assimp {
ZipArchiveIOSystem::Implement::Implement(IOSystem *pIOHandler, const char *pFilename, const char *pMode) {
ai_assert(strcmp(pMode, "r") == 0);
ai_assert(pFilename != nullptr);
if (pFilename[0] == 0)
if (pFilename[0] == 0 || nullptr == pMode) {
return;
}
zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler);
m_ZipFileHandle = unzOpen2(pFilename, &mapping);
@ -421,8 +416,7 @@ namespace Assimp {
inline void ReplaceAll(std::string &data, const std::string &before, const std::string &after) {
size_t pos = data.find(before);
while (pos != std::string::npos)
{
while (pos != std::string::npos) {
data.replace(pos, before.size(), after);
pos = data.find(before, pos + after.size());
}
@ -430,15 +424,13 @@ namespace Assimp {
inline void ReplaceAllChar(std::string &data, const char before, const char after) {
size_t pos = data.find(before);
while (pos != std::string::npos)
{
while (pos != std::string::npos) {
data[pos] = after;
pos = data.find(before, pos + 1);
}
}
void ZipArchiveIOSystem::Implement::SimplifyFilename(std::string& filename)
{
void ZipArchiveIOSystem::Implement::SimplifyFilename(std::string &filename) {
ReplaceAllChar(filename, '\\', '/');
// Remove all . and / from the beginning of the path
@ -450,8 +442,7 @@ namespace Assimp {
static const std::string relative("/../");
const size_t relsize = relative.size() - 1;
pos = filename.find(relative);
while (pos != std::string::npos)
{
while (pos != std::string::npos) {
// Previous slash
size_t prevpos = filename.rfind('/', pos - 1);
if (prevpos == pos)
@ -463,15 +454,14 @@ namespace Assimp {
}
}
ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem* pIOHandler, const char* pFilename, const char* pMode)
: pImpl(new Implement(pIOHandler, pFilename, pMode)) {
ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem *pIOHandler, const char *pFilename, const char *pMode) :
pImpl(new Implement(pIOHandler, pFilename, pMode)) {
}
// ----------------------------------------------------------------
// The ZipArchiveIO
ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem* pIOHandler, const std::string& rFilename, const char* pMode)
: pImpl(new Implement(pIOHandler, rFilename.c_str(), pMode))
{
ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem *pIOHandler, const std::string &rFilename, const char *pMode) :
pImpl(new Implement(pIOHandler, rFilename.c_str(), pMode)) {
}
ZipArchiveIOSystem::~ZipArchiveIOSystem() {
@ -498,8 +488,7 @@ namespace Assimp {
IOStream *ZipArchiveIOSystem::Open(const char *pFilename, const char *pMode) {
ai_assert(pFilename != nullptr);
for (size_t i = 0; pMode[i] != 0; ++i)
{
for (size_t i = 0; pMode[i] != 0; ++i) {
ai_assert(pMode[i] != 'w');
if (pMode[i] == 'w')
return nullptr;
@ -534,4 +523,4 @@ namespace Assimp {
return isZipArchive(pIOHandler, rFilename.c_str());
}
}
} // namespace Assimp

View File

@ -48,8 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
namespace Assimp {
namespace FBX
{
namespace FBX {
const std::string NULL_RECORD = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
@ -80,8 +80,8 @@ namespace FBX
TransformInheritance_MAX // end-of-enum sentinel
};
}
}
} // namespace FBX
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // AI_FBXCOMMON_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -189,8 +189,7 @@ private:
const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------
std::vector<unsigned int> ConvertLine(const LineGeometry& line, const Model& model,
aiNode *parent, aiNode *root_node);
std::vector<unsigned int> ConvertLine(const LineGeometry& line, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent);
@ -220,17 +219,15 @@ private:
* - outputVertStartIndices is only used when a material index is specified, it gives for
* each output vertex the DOM index it maps to.
*/
void ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
aiNode *parent = NULL, aiNode *root_node = NULL,
unsigned int materialIndex = NO_MATERIAL_SEPARATION,
void ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
aiNode *parent = NULL, unsigned int materialIndex = NO_MATERIAL_SEPARATION,
std::vector<unsigned int> *outputVertStartIndices = NULL);
// lookup
static const aiNode* GetNodeByName( const aiString& name, aiNode *current_node );
// ------------------------------------------------------------------------------------------------
void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
aiNode *parent, aiNode *root_node);
aiNode *parent );
// ------------------------------------------------------------------------------------------------
void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@ -437,7 +434,7 @@ private:
// 0: not assigned yet, others: index is value - 1
unsigned int defaultMaterialIndex;
std::vector<aiMesh*> meshes;
std::vector<aiMesh*> mMeshes;
std::vector<aiMaterial*> materials;
std::vector<aiAnimation*> animations;
std::vector<aiLight*> lights;
@ -467,9 +464,9 @@ private:
double anim_fps;
aiScene* const out;
aiScene* const mSceneOut;
const FBX::Document& doc;
bool mRemoveEmptyBones;
static void BuildBoneList(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
std::vector<aiBone*>& bones);

View File

@ -428,8 +428,8 @@ void Document::ReadPropertyTemplates()
const ElementCollection otypes = sdefs.GetCollection("ObjectType");
for(ElementMap::const_iterator it = otypes.first; it != otypes.second; ++it) {
const Element& el = *(*it).second;
const Scope* sc = el.Compound();
if(!sc) {
const Scope* curSc = el.Compound();
if (!curSc) {
DOMWarning("expected nested scope in ObjectType, ignoring",&el);
continue;
}
@ -442,24 +442,24 @@ void Document::ReadPropertyTemplates()
const std::string& oname = ParseTokenAsString(*tok[0]);
const ElementCollection templs = sc->GetCollection("PropertyTemplate");
for(ElementMap::const_iterator it = templs.first; it != templs.second; ++it) {
const Element& el = *(*it).second;
const Scope* sc = el.Compound();
if(!sc) {
const ElementCollection templs = curSc->GetCollection("PropertyTemplate");
for (ElementMap::const_iterator elemIt = templs.first; elemIt != templs.second; ++elemIt) {
const Element &innerEl = *(*elemIt).second;
const Scope *innerSc = innerEl.Compound();
if (!innerSc) {
DOMWarning("expected nested scope in PropertyTemplate, ignoring",&el);
continue;
}
const TokenList& tok = el.Tokens();
if(tok.empty()) {
const TokenList &curTok = innerEl.Tokens();
if (curTok.empty()) {
DOMWarning("expected name for PropertyTemplate element, ignoring",&el);
continue;
}
const std::string& pname = ParseTokenAsString(*tok[0]);
const std::string &pname = ParseTokenAsString(*curTok[0]);
const Element* Properties70 = (*sc)["Properties70"];
const Element *Properties70 = (*innerSc)["Properties70"];
if(Properties70) {
std::shared_ptr<const PropertyTable> props = std::make_shared<const PropertyTable>(
*Properties70,std::shared_ptr<const PropertyTable>(static_cast<const PropertyTable*>(NULL))
@ -529,8 +529,8 @@ const std::vector<const AnimationStack*>& Document::AnimationStacks() const
animationStacksResolved.reserve(animationStacks.size());
for(uint64_t id : animationStacks) {
LazyObject* const lazy = GetObject(id);
const AnimationStack* stack;
if(!lazy || !(stack = lazy->Get<AnimationStack>())) {
const AnimationStack *stack = lazy->Get<AnimationStack>();
if(!lazy || nullptr == stack ) {
DOMWarning("failed to read AnimationStack object");
continue;
}

View File

@ -62,90 +62,81 @@ namespace Assimp {
// so they are specified with an 'A' suffix.
void FBX::Node::AddP70int(
const std::string& name, int32_t value
const std::string& cur_name, int32_t value
) {
FBX::Node n("P");
n.AddProperties(name, "int", "Integer", "", value);
n.AddProperties(cur_name, "int", "Integer", "", value);
AddChild(n);
}
void FBX::Node::AddP70bool(
const std::string& name, bool value
const std::string& cur_name, bool value
) {
FBX::Node n("P");
n.AddProperties(name, "bool", "", "", int32_t(value));
n.AddProperties(cur_name, "bool", "", "", int32_t(value));
AddChild(n);
}
void FBX::Node::AddP70double(
const std::string& name, double value
) {
const std::string &cur_name, double value) {
FBX::Node n("P");
n.AddProperties(name, "double", "Number", "", value);
n.AddProperties(cur_name, "double", "Number", "", value);
AddChild(n);
}
void FBX::Node::AddP70numberA(
const std::string& name, double value
) {
const std::string &cur_name, double value) {
FBX::Node n("P");
n.AddProperties(name, "Number", "", "A", value);
n.AddProperties(cur_name, "Number", "", "A", value);
AddChild(n);
}
void FBX::Node::AddP70color(
const std::string& name, double r, double g, double b
) {
const std::string &cur_name, double r, double g, double b) {
FBX::Node n("P");
n.AddProperties(name, "ColorRGB", "Color", "", r, g, b);
n.AddProperties(cur_name, "ColorRGB", "Color", "", r, g, b);
AddChild(n);
}
void FBX::Node::AddP70colorA(
const std::string& name, double r, double g, double b
) {
const std::string &cur_name, double r, double g, double b) {
FBX::Node n("P");
n.AddProperties(name, "Color", "", "A", r, g, b);
n.AddProperties(cur_name, "Color", "", "A", r, g, b);
AddChild(n);
}
void FBX::Node::AddP70vector(
const std::string& name, double x, double y, double z
) {
const std::string &cur_name, double x, double y, double z) {
FBX::Node n("P");
n.AddProperties(name, "Vector3D", "Vector", "", x, y, z);
n.AddProperties(cur_name, "Vector3D", "Vector", "", x, y, z);
AddChild(n);
}
void FBX::Node::AddP70vectorA(
const std::string& name, double x, double y, double z
) {
const std::string &cur_name, double x, double y, double z) {
FBX::Node n("P");
n.AddProperties(name, "Vector", "", "A", x, y, z);
n.AddProperties(cur_name, "Vector", "", "A", x, y, z);
AddChild(n);
}
void FBX::Node::AddP70string(
const std::string& name, const std::string& value
) {
const std::string &cur_name, const std::string &value) {
FBX::Node n("P");
n.AddProperties(name, "KString", "", "", value);
n.AddProperties(cur_name, "KString", "", "", value);
AddChild(n);
}
void FBX::Node::AddP70enum(
const std::string& name, int32_t value
) {
const std::string &cur_name, int32_t value) {
FBX::Node n("P");
n.AddProperties(name, "enum", "", "", value);
n.AddProperties(cur_name, "enum", "", "", value);
AddChild(n);
}
void FBX::Node::AddP70time(
const std::string& name, int64_t value
) {
const std::string &cur_name, int64_t value) {
FBX::Node n("P");
n.AddProperties(name, "KTime", "Time", "", value);
n.AddProperties(cur_name, "KTime", "Time", "", value);
AddChild(n);
}

View File

@ -944,7 +944,9 @@ void FBXExporter::WriteDefinitions ()
FBX::Node defs("Definitions");
defs.AddChild("Version", int32_t(100));
defs.AddChild("Count", int32_t(total_count));
for (auto &n : object_nodes) { defs.AddChild(n); }
for (auto &on : object_nodes) {
defs.AddChild(on);
}
defs.Dump(outfile, binary, 0);
}
@ -1119,10 +1121,10 @@ void FBXExporter::WriteObjects ()
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
const aiVector3D &n = m->mNormals[f.mIndices[pvi]];
normal_data.push_back(n.x);
normal_data.push_back(n.y);
normal_data.push_back(n.z);
const aiVector3D &curN = m->mNormals[f.mIndices[pvi]];
normal_data.push_back(curN.x);
normal_data.push_back(curN.y);
normal_data.push_back(curN.z);
}
}
FBX::Node::WritePropertyNode(
@ -1226,14 +1228,14 @@ void FBXExporter::WriteObjects ()
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
const aiVector3D &uv =
const aiVector3D &curUv =
m->mTextureCoords[uvi][f.mIndices[pvi]];
auto elem = index_by_uv.find(uv);
auto elem = index_by_uv.find(curUv);
if (elem == index_by_uv.end()) {
index_by_uv[uv] = index;
index_by_uv[curUv] = index;
uv_indices.push_back(index);
for (unsigned int x = 0; x < m->mNumUVComponents[uvi]; ++x) {
uv_data.push_back(uv[x]);
uv_data.push_back(curUv[x]);
}
++index;
} else {
@ -2246,7 +2248,7 @@ const std::map<std::string,std::pair<std::string,char>> transform_types = {
// write a single model node to the stream
void FBXExporter::WriteModelNode(
StreamWriterLE& outstream,
bool binary,
bool,
const aiNode* node,
int64_t node_uid,
const std::string& type,
@ -2299,16 +2301,13 @@ void FBXExporter::WriteModelNode(
err << item.first;
throw DeadlyExportError(err.str());
}
const std::string &name = elem->second.first;
const std::string &cur_name = elem->second.first;
const aiVector3D &v = item.second;
if (name.compare(0, 4, "Lcl ") == 0) {
if (cur_name.compare(0, 4, "Lcl ") == 0) {
// special handling for animatable properties
p.AddP70(
name, name, "", "A",
double(v.x), double(v.y), double(v.z)
);
p.AddP70( cur_name, cur_name, "", "A", double(v.x), double(v.y), double(v.z) );
} else {
p.AddP70vector(name, v.x, v.y, v.z);
p.AddP70vector(cur_name, v.x, v.y, v.z);
}
}
}

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -53,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXDocumentUtil.h"
#include "FBXProperties.h"
#include <assimp/ByteSwapper.h>
#include <assimp/ParsingUtils.h>
#include <algorithm> // std::transform
#include "FBXUtil.h"
@ -86,7 +86,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
std::string templateName;
// lower-case shading because Blender (for example) writes "Phong"
std::transform(shading.begin(), shading.end(), shading.begin(), ::tolower);
std::transform(shading.begin(), shading.end(), shading.begin(), Assimp::ToLower<char>);
if(shading == "phong") {
templateName = "Material.FbxSurfacePhong";
}

View File

@ -46,11 +46,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
#include "FBXParser.h"
#include "FBXMeshGeometry.h"
#include "FBXDocument.h"
#include "FBXImporter.h"
#include "FBXDocumentUtil.h"
#include "FBXImporter.h"
#include "FBXMeshGeometry.h"
#include "FBXParser.h"
namespace Assimp {
namespace FBX {
@ -58,10 +58,8 @@ namespace FBX {
using namespace Util;
// ------------------------------------------------------------------------------------------------
Model::Model(uint64_t id, const Element& element, const Document& doc, const std::string& name)
: Object(id,element,name)
, shading("Y")
{
Model::Model(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
Object(id, element, name), shading("Y") {
const Scope &sc = GetRequiredScope(element);
const Element *const Shading = sc["Shading"];
const Element *const Culling = sc["Culling"];
@ -79,14 +77,11 @@ Model::Model(uint64_t id, const Element& element, const Document& doc, const std
}
// ------------------------------------------------------------------------------------------------
Model::~Model()
{
Model::~Model() {
}
// ------------------------------------------------------------------------------------------------
void Model::ResolveLinks(const Element& element, const Document& doc)
{
void Model::ResolveLinks(const Element&, const Document &doc) {
const char *const arr[] = { "Geometry", "Material", "NodeAttribute" };
// resolve material
@ -132,8 +127,7 @@ void Model::ResolveLinks(const Element& element, const Document& doc)
}
// ------------------------------------------------------------------------------------------------
bool Model::IsNull() const
{
bool Model::IsNull() const {
const std::vector<const NodeAttribute *> &attrs = GetAttributes();
for (const NodeAttribute *att : attrs) {
@ -146,8 +140,7 @@ bool Model::IsNull() const
return false;
}
} //!FBX
} //!Assimp
} // namespace FBX
} // namespace Assimp
#endif

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -49,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdint.h>
#include <map>
#include <memory>
#include <vector>
#include <assimp/LogAux.h>
#include <assimp/fast_atof.h>
@ -126,7 +126,7 @@ public:
const Element* operator[] (const std::string& index) const {
ElementMap::const_iterator it = elements.find(index);
return it == elements.end() ? NULL : (*it).second;
return it == elements.end() ? nullptr : (*it).second;
}
const Element* FindElementCaseInsensitive(const std::string& elementName) const {

View File

@ -209,21 +209,25 @@ DirectPropertyMap PropertyTable::GetUnparsedProperties() const
DirectPropertyMap result;
// Loop through all the lazy properties (which is all the properties)
for(const LazyPropertyMap::value_type& element : lazyProps) {
for(const LazyPropertyMap::value_type& currentElement : lazyProps) {
// Skip parsed properties
if (props.end() != props.find(element.first)) continue;
if (props.end() != props.find(currentElement.first)) {
continue;
}
// Read the element's value.
// Wrap the naked pointer (since the call site is required to acquire ownership)
// std::unique_ptr from C++11 would be preferred both as a wrapper and a return value.
std::shared_ptr<Property> prop = std::shared_ptr<Property>(ReadTypedProperty(*element.second));
std::shared_ptr<Property> prop = std::shared_ptr<Property>(ReadTypedProperty(*currentElement.second));
// Element could not be read. Skip it.
if (!prop) continue;
if (!prop) {
continue;
}
// Add to result
result[element.first] = prop;
result[currentElement.first] = prop;
}
return result;

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXCompileConfig.h"
#include <assimp/ai_assert.h>
#include <assimp/defs.h>
#include <vector>
#include <string>

View File

@ -118,11 +118,11 @@ void HMPImporter::InternReadFile( const std::string& pFile,
aiScene* _pScene, IOSystem* _pIOHandler)
{
pScene = _pScene;
pIOHandler = _pIOHandler;
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
mIOHandler = _pIOHandler;
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile));
// Check whether we can read from the file
if( file.get() == NULL)
if( file.get() == nullptr)
throw DeadlyImportError( "Failed to open HMP file " + pFile + ".");
// Check whether the HMP file is large enough to contain

View File

@ -285,11 +285,11 @@ public:
out.mVerts.reserve(out.mVerts.size() + cnt);
for(const CurveEntry& entry : curves) {
const size_t cnt = out.mVerts.size();
const size_t curCnt = out.mVerts.size();
entry.first->SampleDiscrete(out);
if (!entry.second && cnt != out.mVerts.size()) {
std::reverse(out.mVerts.begin()+cnt,out.mVerts.end());
if (!entry.second && curCnt != out.mVerts.size()) {
std::reverse(out.mVerts.begin() + curCnt, out.mVerts.end());
}
}
}
@ -329,8 +329,8 @@ public:
have_param = true;
break;
}
else if (const Schema_2x3::IfcCartesianPoint* const r = sel->ResolveSelectPtr<Schema_2x3::IfcCartesianPoint>(conv.db)) {
ConvertCartesianPoint(point,*r);
else if (const Schema_2x3::IfcCartesianPoint* const curR = sel->ResolveSelectPtr<Schema_2x3::IfcCartesianPoint>(conv.db)) {
ConvertCartesianPoint(point, *curR);
have_point = true;
}
}
@ -346,8 +346,8 @@ public:
have_param = true;
break;
}
else if (const Schema_2x3::IfcCartesianPoint* const r = sel->ResolveSelectPtr<Schema_2x3::IfcCartesianPoint>(conv.db)) {
ConvertCartesianPoint(point,*r);
else if (const Schema_2x3::IfcCartesianPoint* const curR = sel->ResolveSelectPtr<Schema_2x3::IfcCartesianPoint>(conv.db)) {
ConvertCartesianPoint(point, *curR);
have_point = true;
}
}

View File

@ -101,7 +101,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
return;
}
ai_assert(std::count(inmesh.mVertcnt.begin(), inmesh.mVertcnt.end(), 0) == 0);
ai_assert(std::count(inmesh.mVertcnt.begin(), inmesh.mVertcnt.end(), 0u) == 0);
typedef std::vector<unsigned int>::const_iterator face_iter;
@ -379,7 +379,7 @@ void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh&
IfcVector3 q;
bool take_any = false;
for (unsigned int i = 0; i < 2; ++i, take_any = true) {
for (unsigned int j = 0; j < 2; ++j, take_any = true) {
if ((last_dir == 0 || take_any) && std::abs(d.x) > 1e-6) {
q.y = startvec.y;
q.z = startvec.z;

View File

@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the Industry Foundation Classes loader.
*/
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include <iterator>
@ -59,24 +58,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#endif
#include "IFCLoader.h"
#include "../STEPParser/STEPFileReader.h"
#include "IFCLoader.h"
#include "IFCUtil.h"
#include <assimp/MemoryIOWrapper.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/Importer.hpp>
#include <assimp/importerdesc.h>
namespace Assimp {
template<> const char* LogFunctions<IFCImporter>::Prefix()
{
template <>
const char *LogFunctions<IFCImporter>::Prefix() {
static auto prefix = "IFC: ";
return prefix;
}
}
} // namespace Assimp
using namespace Assimp;
using namespace Assimp::Formatter;
@ -98,7 +96,6 @@ using namespace Assimp::IFC;
namespace {
// forward declarations
void SetUnits(ConversionData &conv);
void SetCoordinateSpace(ConversionData &conv);
@ -106,7 +103,7 @@ void ProcessSpatialStructures(ConversionData& conv);
void MakeTreeRelative(ConversionData &conv);
void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType &dt, ConversionData &conv);
} // anon
} // namespace
static const aiImporterDesc desc = {
"Industry Foundation Classes (IFC) Importer",
@ -121,22 +118,18 @@ static const aiImporterDesc desc = {
"ifc ifczip stp"
};
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
IFCImporter::IFCImporter()
{}
IFCImporter::IFCImporter() {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
IFCImporter::~IFCImporter()
{
IFCImporter::~IFCImporter() {
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool IFCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string &extension = GetExtension(pFile);
if (extension == "ifc" || extension == "ifczip") {
return true;
@ -153,15 +146,13 @@ bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------
// List all extensions handled by this loader
const aiImporterDesc* IFCImporter::GetInfo () const
{
const aiImporterDesc *IFCImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader
void IFCImporter::SetupProperties(const Importer* pImp)
{
void IFCImporter::SetupProperties(const Importer *pImp) {
settings.skipSpaceRepresentations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS, true);
settings.useCustomTriangulation = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION, true);
settings.conicSamplingAngle = std::min(std::max((float)pImp->GetPropertyFloat(AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE, AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE), 5.0f), 120.0f);
@ -169,17 +160,14 @@ void IFCImporter::SetupProperties(const Importer* pImp)
settings.skipAnnotations = true;
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void IFCImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
{
void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile));
if (!stream) {
ThrowException("Could not open file for reading");
}
// if this is a ifczip file, decompress its contents first
if (GetExtension(pFile) == "ifczip") {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
@ -225,22 +213,19 @@ void IFCImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
free(buffer);
} while (read > 0);
size_t filesize = fileInfo.uncompressed_size;
if (total == 0 || size_t(total) != filesize)
{
if (total == 0 || size_t(total) != filesize) {
delete[] buff;
ThrowException("Failed to decompress IFC ZIP file");
}
unzCloseCurrentFile(zip);
stream.reset(new MemoryIOStream(buff, fileInfo.uncompressed_size, true));
break;
if (unzGoToNextFile(zip) == UNZ_END_OF_LIST_OF_FILE) {
ThrowException("Found no IFC file member in IFCZIP file (1)");
}
break;
} while (true);
}
else {
} else {
ThrowException("Found no IFC file member in IFCZIP file (2)");
}
@ -336,10 +321,8 @@ void IFCImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
namespace {
// ------------------------------------------------------------------------------------------------
void ConvertUnit(const Schema_2x3::IfcNamedUnit& unit,ConversionData& conv)
{
void ConvertUnit(const Schema_2x3::IfcNamedUnit &unit, ConversionData &conv) {
if (const Schema_2x3::IfcSIUnit *const si = unit.ToPtr<Schema_2x3::IfcSIUnit>()) {
if (si->UnitType == "LENGTHUNIT") {
conv.len_scale = si->Prefix ? ConvertSIPrefix(si->Prefix) : 1.f;
@ -350,15 +333,13 @@ void ConvertUnit(const Schema_2x3::IfcNamedUnit& unit,ConversionData& conv)
IFCImporter::LogWarn("expected base unit for angles to be radian");
}
}
}
else if(const Schema_2x3::IfcConversionBasedUnit* const convu = unit.ToPtr<Schema_2x3::IfcConversionBasedUnit>()) {
} else if (const Schema_2x3::IfcConversionBasedUnit *const convu = unit.ToPtr<Schema_2x3::IfcConversionBasedUnit>()) {
if (convu->UnitType == "PLANEANGLEUNIT") {
try {
conv.angle_scale = convu->ConversionFactor->ValueComponent->To<::Assimp::STEP::EXPRESS::REAL>();
ConvertUnit(*convu->ConversionFactor->UnitComponent, conv);
IFCImporter::LogDebug("got units used for angles");
}
catch(std::bad_cast&) {
} catch (std::bad_cast &) {
IFCImporter::LogError("skipping unknown IfcConversionBasedUnit.ValueComponent entry - expected REAL");
}
}
@ -366,8 +347,7 @@ void ConvertUnit(const Schema_2x3::IfcNamedUnit& unit,ConversionData& conv)
}
// ------------------------------------------------------------------------------------------------
void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType& dt,ConversionData& conv)
{
void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType &dt, ConversionData &conv) {
try {
const ::Assimp::STEP::EXPRESS::ENTITY &e = dt.To<::Assimp::STEP::EXPRESS::ENTITY>();
@ -377,26 +357,22 @@ void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType& dt,ConversionData& con
}
ConvertUnit(unit, conv);
}
catch(std::bad_cast&) {
} catch (std::bad_cast &) {
// not entity, somehow
IFCImporter::LogError("skipping unknown IfcUnit entry - expected entity");
}
}
// ------------------------------------------------------------------------------------------------
void SetUnits(ConversionData& conv)
{
void SetUnits(ConversionData &conv) {
// see if we can determine the coordinate space used to express.
for (size_t i = 0; i < conv.proj.UnitsInContext->Units.size(); ++i) {
ConvertUnit(*conv.proj.UnitsInContext->Units[i], conv);
}
}
// ------------------------------------------------------------------------------------------------
void SetCoordinateSpace(ConversionData& conv)
{
void SetCoordinateSpace(ConversionData &conv) {
const Schema_2x3::IfcRepresentationContext *fav = NULL;
for (const Schema_2x3::IfcRepresentationContext &v : conv.proj.RepresentationContexts) {
fav = &v;
@ -413,10 +389,8 @@ void SetCoordinateSpace(ConversionData& conv)
}
}
// ------------------------------------------------------------------------------------------------
void ResolveObjectPlacement(aiMatrix4x4& m, const Schema_2x3::IfcObjectPlacement& place, ConversionData& conv)
{
void ResolveObjectPlacement(aiMatrix4x4 &m, const Schema_2x3::IfcObjectPlacement &place, ConversionData &conv) {
if (const Schema_2x3::IfcLocalPlacement *const local = place.ToPtr<Schema_2x3::IfcLocalPlacement>()) {
IfcMatrix4 tmp;
ConvertAxisPlacement(tmp, *local->RelativePlacement, conv);
@ -424,19 +398,17 @@ void ResolveObjectPlacement(aiMatrix4x4& m, const Schema_2x3::IfcObjectPlacement
m = static_cast<aiMatrix4x4>(tmp);
if (local->PlacementRelTo) {
aiMatrix4x4 tmp;
ResolveObjectPlacement(tmp,local->PlacementRelTo.Get(),conv);
m = tmp * m;
aiMatrix4x4 tmpM;
ResolveObjectPlacement(tmpM, local->PlacementRelTo.Get(), conv);
m = tmpM * m;
}
}
else {
} else {
IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is " + place.GetClassName());
}
}
// ------------------------------------------------------------------------------------------------
bool ProcessMappedItem(const Schema_2x3::IfcMappedItem& mapped, aiNode* nd_src, std::vector< aiNode* >& subnodes_src, unsigned int matid, ConversionData& conv)
{
bool ProcessMappedItem(const Schema_2x3::IfcMappedItem &mapped, aiNode *nd_src, std::vector<aiNode *> &subnodes_src, unsigned int matid, ConversionData &conv) {
// insert a custom node here, the carthesian transform operator is simply a conventional transformation matrix
std::unique_ptr<aiNode> nd(new aiNode());
nd->mName.Set("IfcMappedItem");
@ -467,8 +439,8 @@ bool ProcessMappedItem(const Schema_2x3::IfcMappedItem& mapped, aiNode* nd_src,
for (const Schema_2x3::IfcRepresentationItem &item : repr.Items) {
if (!ProcessRepresentationItem(item, localmatid, meshes, conv)) {
IFCImporter::LogWarn("skipping mapped entity of type " + item.GetClassName() + ", no representations could be generated");
}
else got = true;
} else
got = true;
}
if (!got) {
@ -504,7 +476,6 @@ struct RateRepresentationPredicate {
return 0;
}
const std::string &name = r->RepresentationIdentifier.Get();
if (name == "MappedRepresentation") {
if (!r->Items.empty()) {
@ -557,8 +528,7 @@ struct RateRepresentationPredicate {
};
// ------------------------------------------------------------------------------------------------
void ProcessProductRepresentation(const Schema_2x3::IfcProduct& el, aiNode* nd, std::vector< aiNode* >& subnodes, ConversionData& conv)
{
void ProcessProductRepresentation(const Schema_2x3::IfcProduct &el, aiNode *nd, std::vector<aiNode *> &subnodes, ConversionData &conv) {
if (!el.Representation) {
return;
}
@ -581,8 +551,7 @@ void ProcessProductRepresentation(const Schema_2x3::IfcProduct& el, aiNode* nd,
for (const Schema_2x3::IfcRepresentationItem &item : repr->Items) {
if (const Schema_2x3::IfcMappedItem *const geo = item.ToPtr<Schema_2x3::IfcMappedItem>()) {
res = ProcessMappedItem(*geo, nd, subnodes, matid, conv) || res;
}
else {
} else {
res = ProcessRepresentationItem(item, matid, meshes, conv) || res;
}
}
@ -607,22 +576,19 @@ void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::Ifc
if (const ::Assimp::STEP::EXPRESS::STRING *str = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::STRING>()) {
std::string value = static_cast<std::string>(*str);
properties[key] = value;
}
else if (const ::Assimp::STEP::EXPRESS::REAL* val = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
float value = static_cast<float>(*val);
} else if (const ::Assimp::STEP::EXPRESS::REAL *val1 = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
float value = static_cast<float>(*val1);
std::stringstream s;
s << value;
properties[key] = s.str();
}
else if (const ::Assimp::STEP::EXPRESS::INTEGER* val = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) {
int64_t value = static_cast<int64_t>(*val);
} else if (const ::Assimp::STEP::EXPRESS::INTEGER *val2 = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) {
int64_t curValue = static_cast<int64_t>(*val2);
std::stringstream s;
s << value;
s << curValue;
properties[key] = s.str();
}
}
}
else if (const Schema_2x3::IfcPropertyListValue* const listValue = property.ToPtr<Schema_2x3::IfcPropertyListValue>()) {
} else if (const Schema_2x3::IfcPropertyListValue *const listValue = property.ToPtr<Schema_2x3::IfcPropertyListValue>()) {
std::stringstream ss;
ss << "[";
unsigned index = 0;
@ -631,13 +597,11 @@ void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::Ifc
if (const ::Assimp::STEP::EXPRESS::STRING *str = v->ToPtr<::Assimp::STEP::EXPRESS::STRING>()) {
std::string value = static_cast<std::string>(*str);
ss << "'" << value << "'";
}
else if (const ::Assimp::STEP::EXPRESS::REAL* val = v->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
float value = static_cast<float>(*val);
} else if (const ::Assimp::STEP::EXPRESS::REAL *val1 = v->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
float value = static_cast<float>(*val1);
ss << value;
}
else if (const ::Assimp::STEP::EXPRESS::INTEGER* val = v->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) {
int64_t value = static_cast<int64_t>(*val);
} else if (const ::Assimp::STEP::EXPRESS::INTEGER *val2 = v->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) {
int64_t value = static_cast<int64_t>(*val2);
ss << value;
}
if (index + 1 < listValue->ListValues.size()) {
@ -647,25 +611,20 @@ void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::Ifc
}
ss << "]";
properties[key] = ss.str();
}
else if (const Schema_2x3::IfcComplexProperty* const complexProp = property.ToPtr<Schema_2x3::IfcComplexProperty>()) {
} else if (const Schema_2x3::IfcComplexProperty *const complexProp = property.ToPtr<Schema_2x3::IfcComplexProperty>()) {
if (nest > 2) { // mostly arbitrary limit to prevent stack overflow vulnerabilities
IFCImporter::LogError("maximum nesting level for IfcComplexProperty reached, skipping this property.");
}
else {
} else {
ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1);
}
}
else {
} else {
properties[key] = "";
}
}
}
// ------------------------------------------------------------------------------------------------
void ProcessMetadata(uint64_t relDefinesByPropertiesID, ConversionData& conv, Metadata& properties)
{
void ProcessMetadata(uint64_t relDefinesByPropertiesID, ConversionData &conv, Metadata &properties) {
if (const Schema_2x3::IfcRelDefinesByProperties *const pset = conv.db.GetObject(relDefinesByPropertiesID)->ToPtr<Schema_2x3::IfcRelDefinesByProperties>()) {
if (const Schema_2x3::IfcPropertySet *const set = conv.db.GetObject(pset->RelatingPropertyDefinition->GetID())->ToPtr<Schema_2x3::IfcPropertySet>()) {
ProcessMetadata(set->HasProperties, conv, properties);
@ -790,7 +749,6 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const Schema_2x3::IfcProduct& el
nd_aggr->mNumChildren = 1;
nd_aggr->mChildren = new aiNode *[1]();
nd_aggr->mChildren[0] = ndnew;
if (openings_local.size()) {
@ -872,11 +830,9 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const Schema_2x3::IfcProduct& el
}
// ------------------------------------------------------------------------------------------------
void ProcessSpatialStructures(ConversionData& conv)
{
void ProcessSpatialStructures(ConversionData &conv) {
// XXX add support for multiple sites (i.e. IfcSpatialStructureElements with composition == COMPLEX)
// process all products in the file. it is reasonable to assume that a
// file that is relevant for us contains at least a site or a building.
const STEP::DB::ObjectMapByType &map = conv.db.GetObjectsByType();
@ -939,8 +895,7 @@ void ProcessSpatialStructures(ConversionData& conv)
if (nb_nodes == 1) {
conv.out->mRootNode = nodes[0];
}
else if (nb_nodes > 1) {
} else if (nb_nodes > 1) {
conv.out->mRootNode = new aiNode("Root");
conv.out->mRootNode->mParent = NULL;
conv.out->mRootNode->mNumChildren = static_cast<unsigned int>(nb_nodes);
@ -953,15 +908,13 @@ void ProcessSpatialStructures(ConversionData& conv)
conv.out->mRootNode->mChildren[i] = node;
}
}
else {
} else {
IFCImporter::ThrowException("failed to determine primary site element");
}
}
// ------------------------------------------------------------------------------------------------
void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined)
{
void MakeTreeRelative(aiNode *start, const aiMatrix4x4 &combined) {
// combined is the parent's absolute transformation matrix
const aiMatrix4x4 old = start->mTransformation;
@ -976,13 +929,10 @@ void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined)
}
// ------------------------------------------------------------------------------------------------
void MakeTreeRelative(ConversionData& conv)
{
void MakeTreeRelative(ConversionData &conv) {
MakeTreeRelative(conv.out->mRootNode, IfcMatrix4());
}
} // !anon
} // namespace
#endif

View File

@ -294,7 +294,7 @@ void InsertWindowContours(const ContourVector& contours,
const IfcFloat epsilon = diag/1000.f;
// walk through all contour points and find those that lie on the BB corner
size_t last_hit = -1, very_first_hit = -1;
size_t last_hit = (size_t)-1, very_first_hit = (size_t)-1;
IfcVector2 edge;
for(size_t n = 0, e=0, size = contour.size();; n=(n+1)%size, ++e) {
@ -330,7 +330,7 @@ void InsertWindowContours(const ContourVector& contours,
const size_t old = curmesh.mVerts.size();
size_t cnt = last_hit > n ? size-(last_hit-n) : n-last_hit;
for(size_t a = last_hit, e = 0; e <= cnt; a=(a+1)%size, ++e) {
for(size_t a = last_hit, ee = 0; ee <= cnt; a=(a+1)%size, ++ee) {
// hack: this is to fix cases where opening contours are self-intersecting.
// Clipper doesn't produce such polygons, but as soon as we're back in
// our brave new floating-point world, very small distances are consumed

View File

@ -45,6 +45,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "code/Step/STEPFile.h"
#ifdef _WIN32
# pragma warning( disable : 4512 )
#endif // _WIN32
namespace Assimp {
namespace IFC {
namespace Schema_2x3 {

View File

@ -362,8 +362,9 @@ void TempMesh::FixupFaceOrientation()
{
std::reverse(mVerts.begin() + nbvsi, mVerts.begin() + nbvsi + nbvc);
std::reverse(neighbour.begin() + nbvsi, neighbour.begin() + nbvsi + nbvc);
for( size_t a = 0; a < nbvc - 1; ++a )
std::swap(neighbour[nbvsi + a], neighbour[nbvsi + a + 1]);
for (size_t aa = 0; aa < nbvc - 1; ++aa) {
std::swap(neighbour[nbvsi + aa], neighbour[nbvsi + aa + 1]);
}
}
// either way we're done with the neighbour. Mark it as done and continue checking from there recursively

View File

@ -50,12 +50,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/TinyFormatter.h>
#include <assimp/fast_atof.h>
#include <memory>
#include <functional>
using namespace Assimp;
namespace EXPRESS = STEP::EXPRESS;
#include <functional>
namespace EXPRESS = STEP::EXPRESS;
// ------------------------------------------------------------------------------------------------
std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = "")
@ -127,8 +126,8 @@ STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
if (list->GetSize() > 1) {
ASSIMP_LOG_WARN(AddLineNumber("multiple schemas currently not supported",line));
}
const EXPRESS::STRING* string( nullptr );
if (!list->GetSize() || !(string=dynamic_cast<const EXPRESS::STRING*>( (*list)[0].get() ))) {
const EXPRESS::STRING *string = dynamic_cast<const EXPRESS::STRING *>((*list)[0].get());
if (!list->GetSize() || nullptr == string ) {
throw STEP::SyntaxError("expected FILE_SCHEMA to contain a single string literal",line);
}
head.fileSchema = *string;
@ -539,7 +538,7 @@ void STEP::LazyObject::LazyInit() const {
}
const char* acopy = args;
std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,(uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
delete[] args;
args = NULL;

View File

@ -225,7 +225,7 @@ namespace {
, SchemaEntry("presentation_representation_select",NULL )
, SchemaEntry("presentation_size_assignment_select",NULL )
, SchemaEntry("presentation_style_select",NULL )
, SchemaEntry("presented_item_select",NULL )
//, SchemaEntry("presented_item_select",NULL )
, SchemaEntry("pressure_measure",NULL )
, SchemaEntry("product_definition_or_assembly_relationship",NULL )
, SchemaEntry("product_definition_or_breakdown_element_usage",NULL )
@ -397,7 +397,7 @@ namespace {
, SchemaEntry("applied_organizational_project_assignment",&STEP::ObjectHelper<applied_organizational_project_assignment,1>::Construct )
, SchemaEntry("person_and_organization_assignment",&STEP::ObjectHelper<person_and_organization_assignment,2>::Construct )
, SchemaEntry("applied_person_and_organization_assignment",&STEP::ObjectHelper<applied_person_and_organization_assignment,1>::Construct )
, SchemaEntry("presented_item",&STEP::ObjectHelper<presented_item,0>::Construct )
//, SchemaEntry("presented_item",&STEP::ObjectHelper<presented_item,0>::Construct )
, SchemaEntry("applied_presented_item",&STEP::ObjectHelper<applied_presented_item,1>::Construct )
, SchemaEntry("security_classification_assignment",&STEP::ObjectHelper<security_classification_assignment,1>::Construct )
, SchemaEntry("applied_security_classification_assignment",&STEP::ObjectHelper<applied_security_classification_assignment,1>::Construct )
@ -1014,7 +1014,7 @@ namespace {
, SchemaEntry("presentation_size",&STEP::ObjectHelper<NotImplemented,0>::Construct )
, SchemaEntry("presentation_style_assignment",&STEP::ObjectHelper<presentation_style_assignment,1>::Construct )
, SchemaEntry("presentation_style_by_context",&STEP::ObjectHelper<presentation_style_by_context,1>::Construct )
, SchemaEntry("presented_item_representation",&STEP::ObjectHelper<NotImplemented,0>::Construct )
//, SchemaEntry("presented_item_representation",&STEP::ObjectHelper<NotImplemented,0>::Construct )
, SchemaEntry("pressure_measure_with_unit",&STEP::ObjectHelper<pressure_measure_with_unit,0>::Construct )
, SchemaEntry("pressure_unit",&STEP::ObjectHelper<pressure_unit,0>::Construct )
, SchemaEntry("procedural_representation",&STEP::ObjectHelper<procedural_representation,0>::Construct )
@ -1311,11 +1311,11 @@ void StepFile::GetSchema(EXPRESS::ConversionSchema& out)
namespace STEP {
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<NotImplemented>(const STEP::DB& db, const LIST& params, NotImplemented* in)
/*template <> size_t GenericFill<NotImplemented>(const STEP::DB& db, const LIST& params, NotImplemented* in)
{
return 0;
}
*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<measure_with_unit>(const DB& db, const LIST& params, measure_with_unit* in)
{
@ -1359,8 +1359,7 @@ template <> size_t GenericFill<absorbed_dose_unit>(const DB& db, const LIST& par
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to absorbed_dose_unit"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<abstract_variable>(const DB& db, const LIST& params, abstract_variable* in)
{
template <> size_t GenericFill<abstract_variable>(const DB&, const LIST&, abstract_variable*) {
size_t base = 0;
return base;
}
@ -1680,7 +1679,7 @@ template <> size_t GenericFill<amount_of_substance_unit>(const DB& db, const LIS
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to amount_of_substance_unit"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<angle_direction_reference>(const DB& db, const LIST& params, angle_direction_reference* in)
template <> size_t GenericFill<angle_direction_reference>(const DB&, const LIST&, angle_direction_reference*)
{
size_t base = 0;
return base;

View File

@ -452,11 +452,11 @@ template <> size_t GenericFill<applied_person_and_organization_assignment>(const
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<presented_item>(const DB& db, const LIST& params, presented_item* in)
/*template <> size_t GenericFill<presented_item>(const DB& db, const LIST& params, presented_item* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<applied_presented_item>(const DB& db, const LIST& params, applied_presented_item* in)
{
@ -642,11 +642,11 @@ template <> size_t GenericFill<atomic_formula>(const DB& db, const LIST& params,
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to atomic_formula"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<attribute_assertion>(const DB& db, const LIST& params, attribute_assertion* in)
/*template <> size_t GenericFill<attribute_assertion>(const DB& db, const LIST& params, attribute_assertion* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<attribute_language_assignment>(const DB& db, const LIST& params, attribute_language_assignment* in)
{
@ -683,11 +683,11 @@ template <> size_t GenericFill<attribute_value_assignment>(const DB& db, const L
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<auxiliary_geometric_representation_item>(const DB& db, const LIST& params, auxiliary_geometric_representation_item* in)
/*template <> size_t GenericFill<auxiliary_geometric_representation_item>(const DB& db, const LIST& params, auxiliary_geometric_representation_item* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<placement>(const DB& db, const LIST& params, placement* in)
{
@ -946,7 +946,7 @@ template <> size_t GenericFill<back_chaining_rule>(const DB& db, const LIST& par
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to back_chaining_rule"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<back_chaining_rule_body>(const DB& db, const LIST& params, back_chaining_rule_body* in)
/*template <> size_t GenericFill<back_chaining_rule_body>(const DB& db, const LIST& params, back_chaining_rule_body* in)
{
size_t base = 0;
return base;
@ -956,7 +956,7 @@ template <> size_t GenericFill<colour>(const DB& db, const LIST& params, colour*
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<background_colour>(const DB& db, const LIST& params, background_colour* in)
{
@ -987,11 +987,11 @@ template <> size_t GenericFill<bezier_surface>(const DB& db, const LIST& params,
if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to bezier_surface"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<generic_expression>(const DB& db, const LIST& params, generic_expression* in)
/*template <> size_t GenericFill<generic_expression>(const DB& db, const LIST& params, generic_expression* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<binary_generic_expression>(const DB& db, const LIST& params, binary_generic_expression* in)
{
@ -1004,11 +1004,11 @@ template <> size_t GenericFill<binary_generic_expression>(const DB& db, const LI
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<binary_numeric_expression>(const DB& db, const LIST& params, binary_numeric_expression* in)
/*template <> size_t GenericFill<binary_numeric_expression>(const DB& db, const LIST& params, binary_numeric_expression* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<binary_representation_item>(const DB& db, const LIST& params, binary_representation_item* in)
{
@ -1071,11 +1071,11 @@ template <> size_t GenericFill<boolean_literal>(const DB& db, const LIST& params
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<boolean_representation_item>(const DB& db, const LIST& params, boolean_representation_item* in)
/*template <> size_t GenericFill<boolean_representation_item>(const DB& db, const LIST& params, boolean_representation_item* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<boolean_result>(const DB& db, const LIST& params, boolean_result* in)
{
@ -1128,7 +1128,7 @@ template <> size_t GenericFill<boundary_curve>(const DB& db, const LIST& params,
if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to boundary_curve"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<bounded_pcurve>(const DB& db, const LIST& params, bounded_pcurve* in)
/*template <> size_t GenericFill<bounded_pcurve>(const DB& db, const LIST& params, bounded_pcurve* in)
{
size_t base = 0;
return base;
@ -1144,7 +1144,7 @@ template <> size_t GenericFill<founded_item>(const DB& db, const LIST& params, f
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<box_domain>(const DB& db, const LIST& params, box_domain* in)
{
@ -1218,11 +1218,11 @@ template <> size_t GenericFill<breakdown_element_group_assignment>(const DB& db,
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<breakdown_element_realization>(const DB& db, const LIST& params, breakdown_element_realization* in)
/*template <> size_t GenericFill<breakdown_element_realization>(const DB& db, const LIST& params, breakdown_element_realization* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<breakdown_element_usage>(const DB& db, const LIST& params, breakdown_element_usage* in)
{
@ -1784,11 +1784,11 @@ template <> size_t GenericFill<characteristic_type>(const DB& db, const LIST& pa
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to characteristic_type"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<characterized_class>(const DB& db, const LIST& params, characterized_class* in)
/*template <> size_t GenericFill<characterized_class>(const DB& db, const LIST& params, characterized_class* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<characterized_object>(const DB& db, const LIST& params, characterized_object* in)
{
@ -1947,6 +1947,7 @@ template <> size_t GenericFill<colour_rgb>(const DB& db, const LIST& params, col
} while (0);
return base;
}
/*
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<common_datum>(const DB& db, const LIST& params, common_datum* in)
{
@ -1958,7 +1959,7 @@ template <> size_t GenericFill<comparison_expression>(const DB& db, const LIST&
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<complex_clause>(const DB& db, const LIST& params, complex_clause* in)
{
@ -2792,7 +2793,7 @@ template <> size_t GenericFill<cylindricity_tolerance>(const DB& db, const LIST&
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to cylindricity_tolerance"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<date_representation_item>(const DB& db, const LIST& params, date_representation_item* in)
/*template <> size_t GenericFill<date_representation_item>(const DB& db, const LIST& params, date_representation_item* in)
{
size_t base = 0;
return base;
@ -2802,7 +2803,7 @@ template <> size_t GenericFill<date_time_representation_item>(const DB& db, cons
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<dated_effectivity>(const DB& db, const LIST& params, dated_effectivity* in)
{

View File

@ -98,11 +98,11 @@ template <> size_t GenericFill<dimension_pair>(const DB& db, const LIST& params,
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to dimension_pair"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<dimension_text_associativity>(const DB& db, const LIST& params, dimension_text_associativity* in)
/*template <> size_t GenericFill<dimension_text_associativity>(const DB& db, const LIST& params, dimension_text_associativity* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<dimensional_location_with_path>(const DB& db, const LIST& params, dimensional_location_with_path* in)
{
@ -160,11 +160,11 @@ template <> size_t GenericFill<direction>(const DB& db, const LIST& params, dire
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<document_file>(const DB& db, const LIST& params, document_file* in)
/*template <> size_t GenericFill<document_file>(const DB& db, const LIST& params, document_file* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<document_identifier>(const DB& db, const LIST& params, document_identifier* in)
{
@ -347,11 +347,11 @@ template <> size_t GenericFill<draughting_model_item_association>(const DB& db,
if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to draughting_model_item_association"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<pre_defined_colour>(const DB& db, const LIST& params, pre_defined_colour* in)
/*template <> size_t GenericFill<pre_defined_colour>(const DB& db, const LIST& params, pre_defined_colour* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<draughting_pre_defined_colour>(const DB& db, const LIST& params, draughting_pre_defined_colour* in)
{
@ -461,11 +461,11 @@ template <> size_t GenericFill<draughting_text_literal_with_delineation>(const D
if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to draughting_text_literal_with_delineation"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<presentation_set>(const DB& db, const LIST& params, presentation_set* in)
/*template <> size_t GenericFill<presentation_set>(const DB& db, const LIST& params, presentation_set* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<drawing_revision>(const DB& db, const LIST& params, drawing_revision* in)
{
@ -592,11 +592,11 @@ template <> size_t GenericFill<edge_curve>(const DB& db, const LIST& params, edg
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<edge_loop>(const DB& db, const LIST& params, edge_loop* in)
/*template <> size_t GenericFill<edge_loop>(const DB& db, const LIST& params, edge_loop* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<electric_charge_measure_with_unit>(const DB& db, const LIST& params, electric_charge_measure_with_unit* in)
{
@ -711,11 +711,11 @@ template <> size_t GenericFill<enum_reference_prefix>(const DB& db, const LIST&
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to enum_reference_prefix"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<evaluated_characteristic>(const DB& db, const LIST& params, evaluated_characteristic* in)
/*template <> size_t GenericFill<evaluated_characteristic>(const DB& db, const LIST& params, evaluated_characteristic* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<evaluated_degenerate_pcurve>(const DB& db, const LIST& params, evaluated_degenerate_pcurve* in)
{
@ -867,11 +867,11 @@ template <> size_t GenericFill<explicit_procedural_shape_representation_relation
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to explicit_procedural_shape_representation_relationship"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<expression_conversion_based_unit>(const DB& db, const LIST& params, expression_conversion_based_unit* in)
/*template <> size_t GenericFill<expression_conversion_based_unit>(const DB& db, const LIST& params, expression_conversion_based_unit* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<extension>(const DB& db, const LIST& params, extension* in)
{
@ -903,35 +903,35 @@ template <> size_t GenericFill<external_class_library>(const DB& db, const LIST&
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to external_class_library"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_class>(const DB& db, const LIST& params, externally_defined_class* in)
/*template <> size_t GenericFill<externally_defined_class>(const DB& db, const LIST& params, externally_defined_class* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_colour>(const DB& db, const LIST& params, externally_defined_colour* in)
/*template <> size_t GenericFill<externally_defined_colour>(const DB& db, const LIST& params, externally_defined_colour* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_context_dependent_unit>(const DB& db, const LIST& params, externally_defined_context_dependent_unit* in)
/*template <> size_t GenericFill<externally_defined_context_dependent_unit>(const DB& db, const LIST& params, externally_defined_context_dependent_unit* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_conversion_based_unit>(const DB& db, const LIST& params, externally_defined_conversion_based_unit* in)
/*template <> size_t GenericFill<externally_defined_conversion_based_unit>(const DB& db, const LIST& params, externally_defined_conversion_based_unit* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_currency>(const DB& db, const LIST& params, externally_defined_currency* in)
/*template <> size_t GenericFill<externally_defined_currency>(const DB& db, const LIST& params, externally_defined_currency* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_item>(const DB& db, const LIST& params, externally_defined_item* in)
{
@ -957,7 +957,7 @@ template <> size_t GenericFill<externally_defined_curve_font>(const DB& db, cons
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to externally_defined_curve_font"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_dimension_definition>(const DB& db, const LIST& params, externally_defined_dimension_definition* in)
/*template <> size_t GenericFill<externally_defined_dimension_definition>(const DB& db, const LIST& params, externally_defined_dimension_definition* in)
{
size_t base = 0;
return base;
@ -979,7 +979,7 @@ template <> size_t GenericFill<externally_defined_marker>(const DB& db, const LI
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<picture_representation_item>(const DB& db, const LIST& params, picture_representation_item* in)
{
@ -993,7 +993,7 @@ template <> size_t GenericFill<externally_defined_picture_representation_item>(c
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to externally_defined_picture_representation_item"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_representation_item>(const DB& db, const LIST& params, externally_defined_representation_item* in)
/*template <> size_t GenericFill<externally_defined_representation_item>(const DB& db, const LIST& params, externally_defined_representation_item* in)
{
size_t base = 0;
return base;
@ -1003,7 +1003,7 @@ template <> size_t GenericFill<externally_defined_string>(const DB& db, const LI
{
size_t base = GenericFill(db, params, static_cast<externally_defined_representation_item*>(in));
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_symbol>(const DB& db, const LIST& params, externally_defined_symbol* in)
{
@ -1029,11 +1029,11 @@ template <> size_t GenericFill<externally_defined_tile>(const DB& db, const LIST
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to externally_defined_tile"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<externally_defined_tile_style>(const DB& db, const LIST& params, externally_defined_tile_style* in)
/*template <> size_t GenericFill<externally_defined_tile_style>(const DB& db, const LIST& params, externally_defined_tile_style* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<swept_area_solid>(const DB& db, const LIST& params, swept_area_solid* in)
{
@ -1358,11 +1358,11 @@ template <> size_t GenericFill<forward_chaining_rule>(const DB& db, const LIST&
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to forward_chaining_rule"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<forward_chaining_rule_premise>(const DB& db, const LIST& params, forward_chaining_rule_premise* in)
/*template <> size_t GenericFill<forward_chaining_rule_premise>(const DB& db, const LIST& params, forward_chaining_rule_premise* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<frequency_measure_with_unit>(const DB& db, const LIST& params, frequency_measure_with_unit* in)
{
@ -1454,11 +1454,11 @@ template <> size_t GenericFill<geometric_item_specific_usage>(const DB& db, cons
if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to geometric_item_specific_usage"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<geometric_model_element_relationship>(const DB& db, const LIST& params, geometric_model_element_relationship* in)
/*template <> size_t GenericFill<geometric_model_element_relationship>(const DB& db, const LIST& params, geometric_model_element_relationship* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<representation_context>(const DB& db, const LIST& params, representation_context* in)
{
@ -1633,11 +1633,11 @@ template <> size_t GenericFill<indirectly_selected_elements>(const DB& db, const
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<indirectly_selected_shape_elements>(const DB& db, const LIST& params, indirectly_selected_shape_elements* in)
/*template <> size_t GenericFill<indirectly_selected_shape_elements>(const DB& db, const LIST& params, indirectly_selected_shape_elements* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<inductance_measure_with_unit>(const DB& db, const LIST& params, inductance_measure_with_unit* in)
{
@ -1674,11 +1674,11 @@ template <> size_t GenericFill<instance_usage_context_assignment>(const DB& db,
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<instanced_feature>(const DB& db, const LIST& params, instanced_feature* in)
/*template <> size_t GenericFill<instanced_feature>(const DB& db, const LIST& params, instanced_feature* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<literal_number>(const DB& db, const LIST& params, literal_number* in)
{
@ -1698,11 +1698,11 @@ template <> size_t GenericFill<int_literal>(const DB& db, const LIST& params, in
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to int_literal"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<integer_representation_item>(const DB& db, const LIST& params, integer_representation_item* in)
/*template <> size_t GenericFill<integer_representation_item>(const DB& db, const LIST& params, integer_representation_item* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<surface_curve>(const DB& db, const LIST& params, surface_curve* in)
{
@ -1734,11 +1734,11 @@ template <> size_t GenericFill<intersection_curve>(const DB& db, const LIST& par
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to intersection_curve"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<interval_expression>(const DB& db, const LIST& params, interval_expression* in)
/*template <> size_t GenericFill<interval_expression>(const DB& db, const LIST& params, interval_expression* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<iso4217_currency>(const DB& db, const LIST& params, iso4217_currency* in)
{
@ -1746,11 +1746,11 @@ template <> size_t GenericFill<iso4217_currency>(const DB& db, const LIST& param
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to iso4217_currency"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<known_source>(const DB& db, const LIST& params, known_source* in)
/*template <> size_t GenericFill<known_source>(const DB& db, const LIST& params, known_source* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<laid_defined_transformation>(const DB& db, const LIST& params, laid_defined_transformation* in)
{
@ -1943,11 +1943,11 @@ template <> size_t GenericFill<logical_literal>(const DB& db, const LIST& params
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<logical_representation_item>(const DB& db, const LIST& params, logical_representation_item* in)
/*template <> size_t GenericFill<logical_representation_item>(const DB&, const LIST& params, logical_representation_item* )
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<loop>(const DB& db, const LIST& params, loop* in)
{
@ -2105,11 +2105,11 @@ template <> size_t GenericFill<material_property_representation>(const DB& db, c
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<measure_representation_item>(const DB& db, const LIST& params, measure_representation_item* in)
/*template <> size_t GenericFill<measure_representation_item>(const DB& db, const LIST& params, measure_representation_item* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_context>(const DB& db, const LIST& params, product_context* in)
{
@ -2165,11 +2165,11 @@ template <> size_t GenericFill<mechanical_design_shaded_presentation_representat
if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to mechanical_design_shaded_presentation_representation"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<min_and_major_ply_orientation_basis>(const DB& db, const LIST& params, min_and_major_ply_orientation_basis* in)
/*template <> size_t GenericFill<min_and_major_ply_orientation_basis>(const DB& db, const LIST& params, min_and_major_ply_orientation_basis* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<modified_geometric_tolerance>(const DB& db, const LIST& params, modified_geometric_tolerance* in)
{
@ -2211,11 +2211,11 @@ template <> size_t GenericFill<multi_language_attribute_assignment>(const DB& db
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<multiple_arity_boolean_expression>(const DB& db, const LIST& params, multiple_arity_boolean_expression* in)
/*template <> size_t GenericFill<multiple_arity_boolean_expression>(const DB& db, const LIST& params, multiple_arity_boolean_expression* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<multiple_arity_generic_expression>(const DB& db, const LIST& params, multiple_arity_generic_expression* in)
{
@ -2228,11 +2228,11 @@ template <> size_t GenericFill<multiple_arity_generic_expression>(const DB& db,
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<multiple_arity_numeric_expression>(const DB& db, const LIST& params, multiple_arity_numeric_expression* in)
/*template <> size_t GenericFill<multiple_arity_numeric_expression>(const DB& db, const LIST& params, multiple_arity_numeric_expression* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<next_assembly_usage_occurrence>(const DB& db, const LIST& params, next_assembly_usage_occurrence* in)
{
@ -2533,11 +2533,11 @@ template <> size_t GenericFill<parametric_representation_context>(const DB& db,
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to parametric_representation_context"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<partial_document_with_structured_text_representation_assignment>(const DB& db, const LIST& params, partial_document_with_structured_text_representation_assignment* in)
/*template <> size_t GenericFill<partial_document_with_structured_text_representation_assignment>(const DB& db, const LIST& params, partial_document_with_structured_text_representation_assignment* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<pcurve>(const DB& db, const LIST& params, pcurve* in)
{
@ -2591,11 +2591,11 @@ template <> size_t GenericFill<perpendicularity_tolerance>(const DB& db, const L
if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to perpendicularity_tolerance"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<person_and_organization_address>(const DB& db, const LIST& params, person_and_organization_address* in)
/*template <> size_t GenericFill<person_and_organization_address>(const DB& db, const LIST& params, person_and_organization_address* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<personal_address>(const DB& db, const LIST& params, personal_address* in)
{
@ -2715,11 +2715,11 @@ template <> size_t GenericFill<ply_laminate_table>(const DB& db, const LIST& par
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to ply_laminate_table"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<point_and_vector>(const DB& db, const LIST& params, point_and_vector* in)
/*template <> size_t GenericFill<point_and_vector>(const DB& db, const LIST& params, point_and_vector* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<point_on_curve>(const DB& db, const LIST& params, point_on_curve* in)
{
@ -2758,11 +2758,11 @@ template <> size_t GenericFill<point_on_surface>(const DB& db, const LIST& param
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<point_path>(const DB& db, const LIST& params, point_path* in)
/*template <> size_t GenericFill<point_path>(const DB& db, const LIST& params, point_path* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<point_replica>(const DB& db, const LIST& params, point_replica* in)
{
@ -2904,11 +2904,11 @@ template <> size_t GenericFill<pre_defined_marker>(const DB& db, const LIST& par
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to pre_defined_marker"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<pre_defined_point_marker_symbol>(const DB& db, const LIST& params, pre_defined_point_marker_symbol* in)
/*template <> size_t GenericFill<pre_defined_point_marker_symbol>(const DB& db, const LIST& params, pre_defined_point_marker_symbol* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<pre_defined_surface_condition_symbol>(const DB& db, const LIST& params, pre_defined_surface_condition_symbol* in)
{
@ -3002,7 +3002,7 @@ template <> size_t GenericFill<procedural_representation_sequence>(const DB& db,
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<procedural_shape_representation>(const DB& db, const LIST& params, procedural_shape_representation* in)
/*template <> size_t GenericFill<procedural_shape_representation>(const DB& db, const LIST& params, procedural_shape_representation* in)
{
size_t base = 0;
return base;
@ -3012,7 +3012,7 @@ template <> size_t GenericFill<procedural_shape_representation_sequence>(const D
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_category>(const DB& db, const LIST& params, product_category* in)
{
@ -3033,11 +3033,11 @@ template <> size_t GenericFill<product_category>(const DB& db, const LIST& param
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_class>(const DB& db, const LIST& params, product_class* in)
/*template <> size_t GenericFill<product_class>(const DB& db, const LIST& params, product_class* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_concept_context>(const DB& db, const LIST& params, product_concept_context* in)
{
@ -3131,11 +3131,11 @@ template <> size_t GenericFill<product_definition_with_associated_documents>(con
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_identification>(const DB& db, const LIST& params, product_identification* in)
/*template <> size_t GenericFill<product_identification>(const DB& db, const LIST& params, product_identification* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_material_composition_relationship>(const DB& db, const LIST& params, product_material_composition_relationship* in)
{
@ -3174,11 +3174,11 @@ template <> size_t GenericFill<product_related_product_category>(const DB& db, c
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<product_specification>(const DB& db, const LIST& params, product_specification* in)
/*template <> size_t GenericFill<product_specification>(const DB& db, const LIST& params, product_specification* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<tolerance_zone_definition>(const DB& db, const LIST& params, tolerance_zone_definition* in)
{
@ -3289,11 +3289,11 @@ template <> size_t GenericFill<radius_dimension>(const DB& db, const LIST& param
if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to radius_dimension"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<range_characteristic>(const DB& db, const LIST& params, range_characteristic* in)
/*template <> size_t GenericFill<range_characteristic>(const DB& db, const LIST& params, range_characteristic* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<ratio_unit>(const DB& db, const LIST& params, ratio_unit* in)
{
@ -3318,11 +3318,11 @@ template <> size_t GenericFill<rational_b_spline_surface>(const DB& db, const LI
if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to rational_b_spline_surface"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<rational_representation_item>(const DB& db, const LIST& params, rational_representation_item* in)
/*template <> size_t GenericFill<rational_representation_item>(const DB& db, const LIST& params, rational_representation_item* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<real_literal>(const DB& db, const LIST& params, real_literal* in)
{
@ -3330,11 +3330,11 @@ template <> size_t GenericFill<real_literal>(const DB& db, const LIST& params, r
if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to real_literal"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<real_representation_item>(const DB& db, const LIST& params, real_representation_item* in)
/*template <> size_t GenericFill<real_representation_item>(const DB& db, const LIST& params, real_representation_item* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<rectangular_composite_surface>(const DB& db, const LIST& params, rectangular_composite_surface* in)
{
@ -3410,11 +3410,11 @@ template <> size_t GenericFill<relative_event_occurrence>(const DB& db, const LI
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<rep_item_group>(const DB& db, const LIST& params, rep_item_group* in)
/*template <> size_t GenericFill<rep_item_group>(const DB& db, const LIST& params, rep_item_group* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<reparametrised_composite_curve_segment>(const DB& db, const LIST& params, reparametrised_composite_curve_segment* in)
{
@ -3449,11 +3449,11 @@ template <> size_t GenericFill<requirement_assigned_object>(const DB& db, const
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<requirement_assignment>(const DB& db, const LIST& params, requirement_assignment* in)
/*template <> size_t GenericFill<requirement_assignment>(const DB& db, const LIST& params, requirement_assignment* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<requirement_source>(const DB& db, const LIST& params, requirement_source* in)
{
@ -3891,7 +3891,7 @@ template <> size_t GenericFill<shell_based_wireframe_shape_representation>(const
if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to shell_based_wireframe_shape_representation"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<si_absorbed_dose_unit>(const DB& db, const LIST& params, si_absorbed_dose_unit* in)
/*template <> size_t GenericFill<si_absorbed_dose_unit>(const DB& db, const LIST& params, si_absorbed_dose_unit* in)
{
size_t base = 0;
return base;
@ -3991,7 +3991,7 @@ template <> size_t GenericFill<si_resistance_unit>(const DB& db, const LIST& par
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<si_unit>(const DB& db, const LIST& params, si_unit* in)
{
@ -4010,7 +4010,7 @@ template <> size_t GenericFill<si_unit>(const DB& db, const LIST& params, si_uni
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<simple_boolean_expression>(const DB& db, const LIST& params, simple_boolean_expression* in)
/*template <> size_t GenericFill<simple_boolean_expression>(const DB& db, const LIST& params, simple_boolean_expression* in)
{
size_t base = 0;
return base;
@ -4026,7 +4026,7 @@ template <> size_t GenericFill<slash_expression>(const DB& db, const LIST& param
{
size_t base = GenericFill(db, params, static_cast<binary_numeric_expression*>(in));
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<smeared_material_definition>(const DB& db, const LIST& params, smeared_material_definition* in)
{
@ -5450,11 +5450,11 @@ template <> size_t GenericFill<unary_generic_expression>(const DB& db, const LIS
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<unary_numeric_expression>(const DB& db, const LIST& params, unary_numeric_expression* in)
/*template <> size_t GenericFill<unary_numeric_expression>(const DB& db, const LIST& params, unary_numeric_expression* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<uncertainty_assigned_representation>(const DB& db, const LIST& params, uncertainty_assigned_representation* in)
{
@ -5508,7 +5508,7 @@ template <> size_t GenericFill<usage_association>(const DB& db, const LIST& para
if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to usage_association"); } return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<user_defined_curve_font>(const DB& db, const LIST& params, user_defined_curve_font* in)
/*template <> size_t GenericFill<user_defined_curve_font>(const DB& db, const LIST& params, user_defined_curve_font* in)
{
size_t base = 0;
return base;
@ -5524,7 +5524,7 @@ template <> size_t GenericFill<user_defined_terminator_symbol>(const DB& db, con
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<user_selected_shape_elements>(const DB& db, const LIST& params, user_selected_shape_elements* in)
{
@ -5549,11 +5549,11 @@ template <> size_t GenericFill<value_representation_item>(const DB& db, const LI
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<variable_semantics>(const DB& db, const LIST& params, variable_semantics* in)
/*template <> size_t GenericFill<variable_semantics>(const DB& db, const LIST& params, variable_semantics* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<variational_representation_item>(const DB& db, const LIST& params, variational_representation_item* in)
{
@ -5577,11 +5577,11 @@ template <> size_t GenericFill<vector>(const DB& db, const LIST& params, vector*
return base;
}
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<vector_style>(const DB& db, const LIST& params, vector_style* in)
/*template <> size_t GenericFill<vector_style>(const DB& db, const LIST& params, vector_style* in)
{
size_t base = 0;
return base;
}
}*/
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<velocity_measure_with_unit>(const DB& db, const LIST& params, velocity_measure_with_unit* in)
{

View File

@ -93,7 +93,7 @@ const aiImporterDesc *StepFileImporter::GetInfo() const {
static const std::string mode = "rb";
static const std::string StepFileSchema = "CONFIG_CONTROL_DESIGN";
void StepFileImporter::InternReadFile(const std::string &file, aiScene* pScene, IOSystem* pIOHandler) {
void StepFileImporter::InternReadFile(const std::string &file, aiScene*, IOSystem* pIOHandler) {
// Read file into memory
std::shared_ptr<IOStream> fileStream(pIOHandler->Open(file, mode));
if (!fileStream.get()) {

View File

@ -45,6 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "code/Step/STEPFile.h"
#ifdef _WIN32
# pragma warning( disable : 4512 )
#endif // _WIN32
namespace Assimp {
namespace StepFile {
using namespace STEP;
@ -404,7 +407,7 @@ namespace StepFile {
// C++ wrapper type for presentation_style_select
typedef SELECT presentation_style_select;
// C++ wrapper type for presented_item_select
typedef SELECT presented_item_select;
//typedef SELECT presented_item_select;
// C++ wrapper type for pressure_measure
typedef REAL pressure_measure;
// C++ wrapper type for product_definition_or_assembly_relationship
@ -545,7 +548,7 @@ namespace StepFile {
struct absorbed_dose_measure_with_unit;
struct derived_unit;
struct absorbed_dose_unit;
struct abstract_variable;
//struct abstract_variable;
struct acceleration_measure_with_unit;
struct acceleration_unit;
struct action;
@ -646,7 +649,7 @@ namespace StepFile {
struct applied_organizational_project_assignment;
struct person_and_organization_assignment;
struct applied_person_and_organization_assignment;
struct presented_item;
//struct presented_item;
struct applied_presented_item;
struct security_classification_assignment;
struct applied_security_classification_assignment;

View File

@ -185,10 +185,12 @@ void AnimResolver::UpdateAnimRangeSetup()
for (unsigned int i = 0; i < num; ++i) {
m = n+old_size*(i+1);
std::copy(n,n+old_size,m);
if ((*it).pre == LWO::PrePostBehaviour_Oscillate && (reverse = !reverse))
const bool res = ((*it).pre == LWO::PrePostBehaviour_Oscillate);
reverse = !reverse;
if (res && reverse ) {
std::reverse(m,m+old_size-1);
}
}
// update time values
n = (*it).keys.end() - (old_size+1);
@ -533,7 +535,7 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
// ------------------------------------------------------------------------------------------------
// Extract animation channel
void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int flags /*= 0*/)
void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int /*= 0*/)
{
*out = NULL;

View File

@ -45,24 +45,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the LWO importer class
*/
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
// internal headers
#include "LWO/LWOLoader.h"
#include "PostProcessing/ProcessHelper.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include "PostProcessing/ProcessHelper.h"
#include <assimp/StringComparison.h>
#include <assimp/SGSpatialSort.h>
#include <assimp/ByteSwapper.h>
#include <assimp/IOSystem.hpp>
#include <assimp/SGSpatialSort.h>
#include <assimp/StringComparison.h>
#include <assimp/importerdesc.h>
#include <assimp/IOSystem.hpp>
#include <memory>
#include <sstream>
#include <iomanip>
#include <map>
#include <memory>
#include <sstream>
using namespace Assimp;
@ -81,8 +80,8 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
LWOImporter::LWOImporter()
: mIsLWO2(),
LWOImporter::LWOImporter() :
mIsLWO2(),
mIsLXOB(),
mLayers(),
mCurLayer(),
@ -91,22 +90,23 @@ LWOImporter::LWOImporter()
mSurfaces(),
mFileBuffer(),
fileSize(),
pScene(),
mScene(nullptr),
configSpeedFlag(),
configLayerIndex(),
hasNamedLayer()
{}
hasNamedLayer() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
LWOImporter::~LWOImporter()
{}
LWOImporter::~LWOImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
const std::string extension = GetExtension(pFile);
bool LWOImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(file);
if (extension == "lwo" || extension == "lxo") {
return true;
}
@ -117,15 +117,14 @@ bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
tokens[0] = AI_LWO_FOURCC_LWOB;
tokens[1] = AI_LWO_FOURCC_LWO2;
tokens[2] = AI_LWO_FOURCC_LXOB;
return CheckMagicToken(pIOHandler,pFile,tokens,3,8);
return CheckMagicToken(pIOHandler, file, tokens, 3, 8);
}
return false;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties
void LWOImporter::SetupProperties(const Importer* pImp)
{
void LWOImporter::SetupProperties(const Importer *pImp) {
configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED, 0) ? true : false);
configLayerIndex = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, UINT_MAX);
configLayerName = pImp->GetPropertyString(AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, "");
@ -133,8 +132,7 @@ void LWOImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Get list of file extensions
const aiImporterDesc* LWOImporter::GetInfo () const
{
const aiImporterDesc *LWOImporter::GetInfo() const {
return &desc;
}
@ -142,26 +140,29 @@ const aiImporterDesc* LWOImporter::GetInfo () const
// Imports the given file into the given scene structure.
void LWOImporter::InternReadFile(const std::string &pFile,
aiScene *pScene,
IOSystem* pIOHandler)
{
IOSystem *pIOHandler) {
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL)
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open LWO file " + pFile + ".");
}
if((this->fileSize = (unsigned int)file->FileSize()) < 12)
if ((this->fileSize = (unsigned int)file->FileSize()) < 12) {
throw DeadlyImportError("LWO: The file is too small to contain the IFF header");
}
// Allocate storage and copy the contents of the file to a memory buffer
std::vector<uint8_t> mBuffer(fileSize);
file->Read(&mBuffer[0], 1, fileSize);
this->pScene = pScene;
mScene = pScene;
// Determine the type of the file
uint32_t fileType;
const char *sz = IFF::ReadHeader(&mBuffer[0], fileType);
if (sz)throw DeadlyImportError(sz);
if (sz) {
throw DeadlyImportError(sz);
}
mFileBuffer = &mBuffer[0] + 12;
fileSize -= 12;
@ -186,7 +187,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mLayers->push_back(Layer());
mCurLayer = &mLayers->back();
mCurLayer->mName = "<LWODefault>";
mCurLayer->mIndex = -1;
mCurLayer->mIndex = (uint16_t) -1;
// old lightwave file format (prior to v6)
if (AI_LWO_FOURCC_LWOB == fileType) {
@ -195,20 +196,16 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mIsLWO2 = false;
mIsLXOB = false;
LoadLWOBFile();
}
} else if (AI_LWO_FOURCC_LWO2 == fileType) {
// New lightwave format
else if (AI_LWO_FOURCC_LWO2 == fileType) {
mIsLXOB = false;
ASSIMP_LOG_INFO("LWO file format: LWO2 (>= LightWave 6)");
}
} else if (AI_LWO_FOURCC_LXOB == fileType) {
// MODO file format
else if (AI_LWO_FOURCC_LXOB == fileType) {
mIsLXOB = true;
ASSIMP_LOG_INFO("LWO file format: LXOB (Modo)");
}
// we don't know this format
else
{
else {
char szBuff[5];
szBuff[0] = (char)(fileType >> 24u);
szBuff[1] = (char)(fileType >> 16u);
@ -235,8 +232,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
}
if (configLayerName.length() && !hasNamedLayer) {
throw DeadlyImportError("LWO2: Unable to find the requested layer: "
+ configLayerName);
throw DeadlyImportError("LWO2: Unable to find the requested layer: " + configLayerName);
}
}
@ -271,8 +267,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
}
unsigned int idx = (*it).surfaceIndex;
if (idx >= mTags->size())
{
if (idx >= mTags->size()) {
ASSIMP_LOG_WARN("LWO: Invalid face surface index");
idx = UINT_MAX;
}
@ -291,8 +286,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
if (UINT_MAX == iDefaultSurface) {
pSorted.erase(pSorted.end() - 1);
}
for (unsigned int p = 0,i = 0;i < mSurfaces->size();++i) {
SortedRep& sorted = pSorted[i];
for (unsigned int p = 0, j = 0; j < mSurfaces->size(); ++j) {
SortedRep &sorted = pSorted[j];
if (sorted.empty())
continue;
@ -307,9 +302,9 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mesh->mNumVertices += layer.mFaces[*it].mNumIndices;
}
aiVector3D *nrm = NULL, * pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
aiVector3D *nrm = nullptr, *pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
aiFace *pf = mesh->mFaces = new aiFace[mesh->mNumFaces];
mesh->mMaterialIndex = i;
mesh->mMaterialIndex = j;
// find out which vertex color channels and which texture coordinate
// channels are really required by the material attached to this mesh
@ -325,8 +320,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
}
#endif
FindUVChannels(_mSurfaces[i],sorted,layer,vUVChannelIndices);
FindVCChannels(_mSurfaces[i],sorted,layer,vVColorIndices);
FindUVChannels(_mSurfaces[j], sorted, layer, vUVChannelIndices);
FindVCChannels(_mSurfaces[j], sorted, layer, vVColorIndices);
// allocate storage for UV and CV channels
aiVector3D *pvUV[AI_MAX_NUMBER_OF_TEXTURECOORDS];
@ -341,8 +336,9 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mesh->mNumUVComponents[0] = 2;
}
if (layer.mNormals.name.length())
if (layer.mNormals.name.length()) {
nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
}
aiColor4D *pvVC[AI_MAX_NUMBER_OF_COLOR_SETS];
for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS; ++mui) {
@ -415,7 +411,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
}
pf->mIndices = face.mIndices;
pf->mNumIndices = face.mNumIndices;
unsigned int** p = (unsigned int**)&face.mIndices;*p = NULL; // HACK: make sure it won't be deleted
unsigned int **facePtr = (unsigned int **)&face.mIndices;
*facePtr = nullptr; // HACK: make sure it won't be deleted
pf++;
}
@ -423,9 +420,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// Compute normal vectors for the mesh - we can't use our GenSmoothNormal-
// Step here since it wouldn't handle smoothing groups correctly for LWO.
// So we use a separate implementation.
ComputeNormals(mesh,smoothingGroups,_mSurfaces[i]);
}
else {
ComputeNormals(mesh, smoothingGroups, _mSurfaces[j]);
} else {
ASSIMP_LOG_DEBUG("LWO2: No need to compute normals, they're already there");
}
++p;
@ -470,8 +466,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------
void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &smoothingGroups,
const LWO::Surface& surface)
{
const LWO::Surface &surface) {
// Allocate output storage
mesh->mNormals = new aiVector3D[mesh->mNumVertices];
@ -510,11 +505,9 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
// Now generate the spatial sort tree
SGSpatialSort sSort;
std::vector<unsigned int>::const_iterator it = smoothingGroups.begin();
for( begin = mesh->mFaces; begin != end; ++begin, ++it)
{
for (begin = mesh->mFaces; begin != end; ++begin, ++it) {
aiFace &face = *begin;
for (unsigned int i = 0; i < face.mNumIndices;++i)
{
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
unsigned int tt = face.mIndices[i];
sSort.Add(mesh->mVertices[tt], tt, *it);
}
@ -532,14 +525,12 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
for (begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
const aiFace &face = *begin;
unsigned int *beginIdx = face.mIndices, *const endIdx = face.mIndices + face.mNumIndices;
for (; beginIdx != endIdx; ++beginIdx)
{
for (; beginIdx != endIdx; ++beginIdx) {
unsigned int idx = *beginIdx;
sSort.FindPositions(mesh->mVertices[idx], *it, posEpsilon, poResult, true);
std::vector<unsigned int>::const_iterator a, end = poResult.end();
aiVector3D vNormals;
for (a = poResult.begin();a != end;++a) {
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
const aiVector3D &v = faceNormals[*a];
if (v * faceNormals[idx] < fLimit)
continue;
@ -555,21 +546,19 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
for (begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
const aiFace &face = *begin;
unsigned int *beginIdx = face.mIndices, *const endIdx = face.mIndices + face.mNumIndices;
for (; beginIdx != endIdx; ++beginIdx)
{
for (; beginIdx != endIdx; ++beginIdx) {
unsigned int idx = *beginIdx;
if (vertexDone[idx])
continue;
sSort.FindPositions(mesh->mVertices[idx], *it, posEpsilon, poResult, true);
std::vector<unsigned int>::const_iterator a, end = poResult.end();
aiVector3D vNormals;
for (a = poResult.begin();a != end;++a) {
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
const aiVector3D &v = faceNormals[*a];
vNormals += v;
}
vNormals.Normalize();
for (a = poResult.begin();a != end;++a) {
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
mesh->mNormals[*a] = vNormals;
vertexDone[*a] = true;
}
@ -579,10 +568,9 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
{
void LWOImporter::GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes) {
// now generate the final nodegraph - generate a root node and attach children
aiNode* root = pScene->mRootNode = new aiNode();
aiNode *root = mScene->mRootNode = new aiNode();
root->mName.Set("<LWORoot>");
//Set parent of all children, inserting pivots
@ -622,7 +610,7 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
}
//Set children of all parents
apcNodes[-1] = root;
apcNodes[(uint16_t)-1] = root;
for (auto itMapParentNodes = apcNodes.begin(); itMapParentNodes != apcNodes.end(); ++itMapParentNodes) {
for (auto itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
@ -640,28 +628,27 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
}
}
if (!pScene->mRootNode->mNumChildren)
if (!mScene->mRootNode->mNumChildren)
throw DeadlyImportError("LWO: Unable to build a valid node graph");
// Remove a single root node with no meshes assigned to it ...
if (1 == pScene->mRootNode->mNumChildren) {
aiNode* pc = pScene->mRootNode->mChildren[0];
pc->mParent = pScene->mRootNode->mChildren[0] = NULL;
delete pScene->mRootNode;
pScene->mRootNode = pc;
if (1 == mScene->mRootNode->mNumChildren) {
aiNode *pc = mScene->mRootNode->mChildren[0];
pc->mParent = mScene->mRootNode->mChildren[0] = nullptr;
delete mScene->mRootNode;
mScene->mRootNode = pc;
}
// convert the whole stuff to RH with CCW winding
MakeLeftHandedProcess maker;
maker.Execute(pScene);
maker.Execute(mScene);
FlipWindingOrderProcess flipper;
flipper.Execute(pScene);
flipper.Execute(mScene);
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::ResolveTags()
{
void LWOImporter::ResolveTags() {
// --- this function is used for both LWO2 and LWOB
mMapping->resize(mTags->size(), UINT_MAX);
for (unsigned int a = 0; a < mTags->size(); ++a) {
@ -680,8 +667,7 @@ void LWOImporter::ResolveTags()
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::ResolveClips()
{
void LWOImporter::ResolveClips() {
for (unsigned int i = 0; i < mClips.size(); ++i) {
Clip &clip = mClips[i];
@ -707,8 +693,7 @@ void LWOImporter::ResolveClips()
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::AdjustTexturePath(std::string& out)
{
void LWOImporter::AdjustTexturePath(std::string &out) {
// --- this function is used for both LWO2 and LWOB
if (!mIsLWO2 && ::strstr(out.c_str(), "(sequence)")) {
@ -725,16 +710,13 @@ void LWOImporter::AdjustTexturePath(std::string& out)
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOTags(unsigned int size)
{
void LWOImporter::LoadLWOTags(unsigned int size) {
// --- this function is used for both LWO2 and LWOB
const char *szCur = (const char *)mFileBuffer, *szLast = szCur;
const char *const szEnd = szLast + size;
while (szCur < szEnd)
{
if (!(*szCur))
{
while (szCur < szEnd) {
if (!(*szCur)) {
const size_t len = (size_t)(szCur - szLast);
// FIX: skip empty-sized tags
if (len)
@ -747,27 +729,24 @@ void LWOImporter::LoadLWOTags(unsigned int size)
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOPoints(unsigned int length)
{
void LWOImporter::LoadLWOPoints(unsigned int length) {
// --- this function is used for both LWO2 and LWOB but for
// LWO2 we need to allocate 25% more storage - it could be we'll
// need to duplicate some points later.
const size_t vertexLen = 12;
if ((length % vertexLen) != 0)
{
if ((length % vertexLen) != 0) {
throw DeadlyImportError("LWO2: Points chunk length is not multiple of vertexLen (12)");
}
unsigned int regularSize = (unsigned int)mCurLayer->mTempPoints.size() + length / 12;
if (mIsLWO2)
{
if (mIsLWO2) {
mCurLayer->mTempPoints.reserve(regularSize + (regularSize >> 2u));
mCurLayer->mTempPoints.resize(regularSize);
// initialize all point referrers with the default values
mCurLayer->mPointReferrers.reserve(regularSize + (regularSize >> 2u));
mCurLayer->mPointReferrers.resize(regularSize, UINT_MAX);
}
else mCurLayer->mTempPoints.resize( regularSize );
} else
mCurLayer->mTempPoints.resize(regularSize);
// perform endianness conversions
#ifndef AI_BUILD_BIG_ENDIAN
@ -778,20 +757,19 @@ void LWOImporter::LoadLWOPoints(unsigned int length)
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Polygons(unsigned int length)
{
void LWOImporter::LoadLWO2Polygons(unsigned int length) {
LE_NCONST uint16_t *const end = (LE_NCONST uint16_t *)(mFileBuffer + length);
const uint32_t type = GetU4();
// Determine the type of the polygons
switch (type)
{
switch (type) {
// read unsupported stuff too (although we won't process it)
case AI_LWO_MBAL:
ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (METABALL)");
break;
case AI_LWO_CURV:
ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (SPLINE)");;
ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (SPLINE)");
;
break;
// These are ok with no restrictions
@ -814,8 +792,7 @@ void LWOImporter::LoadLWO2Polygons(unsigned int length)
CountVertsAndFacesLWO2(iNumVertices, iNumFaces, cursor, end);
// allocate the output array and copy face indices
if (iNumFaces)
{
if (iNumFaces) {
cursor = (uint16_t *)mFileBuffer;
mCurLayer->mFaces.resize(iNumFaces, LWO::Face(type));
@ -826,10 +803,8 @@ void LWOImporter::LoadLWO2Polygons(unsigned int length)
// ------------------------------------------------------------------------------------------------
void LWOImporter::CountVertsAndFacesLWO2(unsigned int &verts, unsigned int &faces,
uint16_t*& cursor, const uint16_t* const end, unsigned int max)
{
while (cursor < end && max--)
{
uint16_t *&cursor, const uint16_t *const end, unsigned int max) {
while (cursor < end && max--) {
uint16_t numIndices;
::memcpy(&numIndices, cursor++, 2);
AI_LSWAP2(numIndices);
@ -838,8 +813,7 @@ void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& face
verts += numIndices;
++faces;
for(uint16_t i = 0; i < numIndices; i++)
{
for (uint16_t i = 0; i < numIndices; i++) {
ReadVSizedIntLWO2((uint8_t *&)cursor);
}
}
@ -848,10 +822,8 @@ void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& face
// ------------------------------------------------------------------------------------------------
void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator &it,
uint16_t *&cursor,
const uint16_t* const end)
{
while (cursor < end)
{
const uint16_t *const end) {
while (cursor < end) {
LWO::Face &face = *it++;
uint16_t numIndices;
::memcpy(&numIndices, cursor++, 2);
@ -861,24 +833,20 @@ void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator& it,
if (face.mNumIndices) /* byte swapping has already been done */
{
face.mIndices = new unsigned int[face.mNumIndices];
for(unsigned int i = 0; i < face.mNumIndices; i++)
{
for (unsigned int i = 0; i < face.mNumIndices; i++) {
face.mIndices[i] = ReadVSizedIntLWO2((uint8_t *&)cursor) + mCurLayer->mPointIDXOfs;
if(face.mIndices[i] > mCurLayer->mTempPoints.size())
{
if (face.mIndices[i] > mCurLayer->mTempPoints.size()) {
ASSIMP_LOG_WARN("LWO2: Failure evaluating face record, index is out of range");
face.mIndices[i] = (unsigned int)mCurLayer->mTempPoints.size() - 1;
}
}
}
else throw DeadlyImportError("LWO2: Encountered invalid face record with zero indices");
} else
throw DeadlyImportError("LWO2: Encountered invalid face record with zero indices");
}
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
{
void LWOImporter::LoadLWO2PolygonTags(unsigned int length) {
LE_NCONST uint8_t *const end = mFileBuffer + length;
AI_LWO_VALIDATE_CHUNK_LENGTH(length, PTAG, 4);
@ -887,8 +855,7 @@ void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
if (type != AI_LWO_SURF && type != AI_LWO_SMGP)
return;
while (mFileBuffer < end)
{
while (mFileBuffer < end) {
unsigned int i = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
unsigned int j = GetU2();
@ -911,8 +878,7 @@ void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
// ------------------------------------------------------------------------------------------------
template <class T>
VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPoly)
{
VMapEntry *FindEntry(std::vector<T> &list, const std::string &name, bool perPoly) {
for (auto &elem : list) {
if (elem.name == name) {
if (!perPoly) {
@ -929,8 +895,7 @@ VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPol
// ------------------------------------------------------------------------------------------------
template <class T>
inline void CreateNewEntry(T& chan, unsigned int srcIdx)
{
inline void CreateNewEntry(T &chan, unsigned int srcIdx) {
if (!chan.name.length())
return;
@ -943,8 +908,7 @@ inline void CreateNewEntry(T& chan, unsigned int srcIdx)
// ------------------------------------------------------------------------------------------------
template <class T>
inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
{
inline void CreateNewEntry(std::vector<T> &list, unsigned int srcIdx) {
for (auto &elem : list) {
CreateNewEntry(elem, srcIdx);
}
@ -952,8 +916,7 @@ inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
// ------------------------------------------------------------------------------------------------
inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry *base, unsigned int numRead,
unsigned int idx, float* data)
{
unsigned int idx, float *data) {
ai_assert(NULL != data);
LWO::ReferrerList &refList = mCurLayer->mPointReferrers;
unsigned int i;
@ -972,8 +935,7 @@ inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int
}
// ------------------------------------------------------------------------------------------------
inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, unsigned int destIdx)
{
inline void AddToSingleLinkedList(ReferrerList &refList, unsigned int srcIdx, unsigned int destIdx) {
if (UINT_MAX == refList[srcIdx]) {
refList[srcIdx] = destIdx;
return;
@ -983,8 +945,7 @@ inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, un
// ------------------------------------------------------------------------------------------------
// Load LWO2 vertex map
void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
{
void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
LE_NCONST uint8_t *const end = mFileBuffer + length;
AI_LWO_VALIDATE_CHUNK_LENGTH(length, VMAP, 6);
@ -997,12 +958,10 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
std::string name;
GetS0(name, length);
switch (type)
{
switch (type) {
case AI_LWO_TXUV:
if (dims != 2) {
ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'"
+ name + "\' with !2 components");
ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'" + name + "\' with !2 components");
return;
}
base = FindEntry(mCurLayer->mUVChannels, name, perPoly);
@ -1010,18 +969,15 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
case AI_LWO_WGHT:
case AI_LWO_MNVW:
if (dims != 1) {
ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'"
+ name + "\' with !1 components");
ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'" + name + "\' with !1 components");
return;
}
base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels
: mCurLayer->mSWeightChannels),name,perPoly);
base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels : mCurLayer->mSWeightChannels), name, perPoly);
break;
case AI_LWO_RGB:
case AI_LWO_RGBA:
if (dims != 3 && dims != 4) {
ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'"
+ name + "\' with a dimension > 4 or < 3");
ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'" + name + "\' with a dimension > 4 or < 3");
return;
}
base = FindEntry(mCurLayer->mVColorChannels, name, perPoly);
@ -1096,8 +1052,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
do {
if (tmp == srcIdx)
break;
}
while ((tmp = refList[tmp]) != UINT_MAX);
} while ((tmp = refList[tmp]) != UINT_MAX);
if (tmp == UINT_MAX) {
continue;
}
@ -1138,8 +1093,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
// ------------------------------------------------------------------------------------------------
// Load LWO2 clip
void LWOImporter::LoadLWO2Clip(unsigned int length)
{
void LWOImporter::LoadLWO2Clip(unsigned int length) {
AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 10);
mClips.push_back(LWO::Clip());
@ -1149,8 +1103,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
clip.idx = GetU4();
IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
switch (head.type)
{
switch (head.type) {
case AI_LWO_STIL:
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, STIL, 1);
@ -1163,9 +1116,12 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, ISEQ, 16);
// Image sequence. We'll later take the first.
{
uint8_t digits = GetU1(); mFileBuffer++;
int16_t offset = GetU2(); mFileBuffer+=4;
int16_t start = GetU2(); mFileBuffer+=4;
uint8_t digits = GetU1();
mFileBuffer++;
int16_t offset = GetU2();
mFileBuffer += 4;
int16_t start = GetU2();
mFileBuffer += 4;
std::string s;
std::ostringstream ss;
@ -1209,8 +1165,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
// ------------------------------------------------------------------------------------------------
// Load envelope description
void LWOImporter::LoadLWO2Envelope(unsigned int length)
{
void LWOImporter::LoadLWO2Envelope(unsigned int length) {
LE_NCONST uint8_t *const end = mFileBuffer + length;
AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4);
@ -1223,18 +1178,15 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
// It looks like there might be an extra U4 right after the index,
// at least in modo (LXOB) files: we'll ignore it if it's zero,
// otherwise it represents the start of a subchunk, so we backtrack.
if (mIsLXOB)
{
if (mIsLXOB) {
uint32_t extra = GetU4();
if (extra)
{
if (extra) {
mFileBuffer -= 4;
}
}
// ... and read all subchunks
while (true)
{
while (true) {
if (mFileBuffer + 6 >= end) break;
LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -1242,8 +1194,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
throw DeadlyImportError("LWO2: Invalid envelope chunk length");
uint8_t *const next = mFileBuffer + head.length;
switch (head.type)
{
switch (head.type) {
// Type & representation of the envelope
case AI_LWO_TYPE:
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, TYPE, 2);
@ -1267,8 +1218,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
break;
// keyframe
case AI_LWO_KEY:
{
case AI_LWO_KEY: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, KEY, 8);
envelope.keys.push_back(LWO::Key());
@ -1280,27 +1230,31 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
}
// interval interpolation
case AI_LWO_SPAN:
{
case AI_LWO_SPAN: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SPAN, 4);
if (envelope.keys.size() < 2)
ASSIMP_LOG_WARN("LWO2: Unexpected SPAN chunk");
else {
LWO::Key &key = envelope.keys.back();
switch (GetU4())
{
switch (GetU4()) {
case AI_LWO_STEP:
key.inter = LWO::IT_STEP;break;
key.inter = LWO::IT_STEP;
break;
case AI_LWO_LINE:
key.inter = LWO::IT_LINE;break;
key.inter = LWO::IT_LINE;
break;
case AI_LWO_TCB:
key.inter = LWO::IT_TCB;break;
key.inter = LWO::IT_TCB;
break;
case AI_LWO_HERM:
key.inter = LWO::IT_HERM;break;
key.inter = LWO::IT_HERM;
break;
case AI_LWO_BEZI:
key.inter = LWO::IT_BEZI;break;
key.inter = LWO::IT_BEZI;
break;
case AI_LWO_BEZ2:
key.inter = LWO::IT_BEZ2;break;
key.inter = LWO::IT_BEZ2;
break;
default:
ASSIMP_LOG_WARN("LWO2: Unknown interval interpolation mode");
};
@ -1321,19 +1275,16 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
// ------------------------------------------------------------------------------------------------
// Load file - master function
void LWOImporter::LoadLWO2File()
{
void LWOImporter::LoadLWO2File() {
bool skip = false;
LE_NCONST uint8_t *const end = mFileBuffer + fileSize;
unsigned int iUnnamed = 0;
while (true)
{
while (true) {
if (mFileBuffer + sizeof(IFF::ChunkHeader) > end) break;
const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
if (mFileBuffer + head.length > end)
{
if (mFileBuffer + head.length > end) {
throw DeadlyImportError("LWO2: Chunk length points behind the file");
break;
}
@ -1344,11 +1295,9 @@ void LWOImporter::LoadLWO2File()
continue;
}
switch (head.type)
{
switch (head.type) {
// new layer
case AI_LWO_LAYR:
{
case AI_LWO_LAYR: {
// add a new layer to the list ....
mLayers->push_back(LWO::Layer());
LWO::Layer &layer = mLayers->back();
@ -1362,8 +1311,8 @@ void LWOImporter::LoadLWO2File()
// Continue loading this layer or ignore it? Check the layer index property
if (UINT_MAX != configLayerIndex && (configLayerIndex - 1) != layer.mIndex) {
skip = true;
}
else skip = false;
} else
skip = false;
// pivot point
mFileBuffer += 2; /* unknown */
@ -1382,13 +1331,14 @@ void LWOImporter::LoadLWO2File()
// load this layer or ignore it? Check the layer name property
if (configLayerName.length() && configLayerName != layer.mName) {
skip = true;
}
else hasNamedLayer = true;
} else
hasNamedLayer = true;
// optional: parent of this layer
if (mFileBuffer + 2 <= next)
layer.mParent = GetU2();
else layer.mParent = -1;
else
layer.mParent = (uint16_t) -1;
// Set layer skip parameter
layer.skip = skip;
@ -1397,8 +1347,7 @@ void LWOImporter::LoadLWO2File()
}
// vertex list
case AI_LWO_PNTS:
{
case AI_LWO_PNTS: {
if (skip)
break;
@ -1409,25 +1358,23 @@ void LWOImporter::LoadLWO2File()
}
// vertex tags
case AI_LWO_VMAD:
if (mCurLayer->mFaces.empty())
{
if (mCurLayer->mFaces.empty()) {
ASSIMP_LOG_WARN("LWO2: Unexpected VMAD chunk");
break;
}
// --- intentionally no break here
case AI_LWO_VMAP:
{
case AI_LWO_VMAP: {
if (skip)
break;
if (mCurLayer->mTempPoints.empty())
ASSIMP_LOG_WARN("LWO2: Unexpected VMAP chunk");
else LoadLWO2VertexMap(head.length,head.type == AI_LWO_VMAD);
else
LoadLWO2VertexMap(head.length, head.type == AI_LWO_VMAD);
break;
}
// face list
case AI_LWO_POLS:
{
case AI_LWO_POLS: {
if (skip)
break;
@ -1437,8 +1384,7 @@ void LWOImporter::LoadLWO2File()
break;
}
// polygon tags
case AI_LWO_PTAG:
{
case AI_LWO_PTAG: {
if (skip)
break;
@ -1450,8 +1396,7 @@ void LWOImporter::LoadLWO2File()
break;
}
// list of tags
case AI_LWO_TAGS:
{
case AI_LWO_TAGS: {
if (!mTags->empty()) {
ASSIMP_LOG_WARN("LWO2: SRFS chunk encountered twice");
} else {
@ -1461,22 +1406,19 @@ void LWOImporter::LoadLWO2File()
}
// surface chunk
case AI_LWO_SURF:
{
case AI_LWO_SURF: {
LoadLWO2Surface(head.length);
break;
}
// clip chunk
case AI_LWO_CLIP:
{
case AI_LWO_CLIP: {
LoadLWO2Clip(head.length);
break;
}
// envelope chunk
case AI_LWO_ENVL:
{
case AI_LWO_ENVL: {
LoadLWO2Envelope(head.length);
break;
}

View File

@ -76,9 +76,6 @@ public:
LWOImporter();
~LWOImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
@ -86,7 +83,6 @@ public:
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
@ -389,7 +385,7 @@ protected:
unsigned int fileSize;
/** Output scene */
aiScene* pScene;
aiScene* mScene;
/** Configuration option: speed flag set? */
bool configSpeedFlag;
@ -406,8 +402,8 @@ protected:
// ------------------------------------------------------------------------------------------------
inline float LWOImporter::GetF4()
{
inline
float LWOImporter::GetF4() {
float f;
::memcpy(&f, mFileBuffer, 4);
mFileBuffer += 4;

View File

@ -43,30 +43,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the material oart of the LWO importer class */
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
// internal headers
#include "LWOLoader.h"
#include <assimp/ByteSwapper.h>
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
template <class T>
T lerp(const T& one, const T& two, float val)
{
T lerp(const T &one, const T &two, float val) {
return one + (two - one) * val;
}
// ------------------------------------------------------------------------------------------------
// Convert a lightwave mapping mode to our's
inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
{
switch (in)
{
inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in) {
switch (in) {
case LWO::Texture::REPEAT:
return aiTextureMapMode_Wrap;
@ -84,8 +78,7 @@ inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
}
// ------------------------------------------------------------------------------------------------
bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTextureType type)
{
bool LWOImporter::HandleTextures(aiMaterial *pcMat, const TextureList &in, aiTextureType type) {
ai_assert(NULL != pcMat);
unsigned int cur = 0, temp = 0;
@ -101,9 +94,8 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
// as they are, the GenUVcoords step will compute UV
// channels if they're not there.
aiTextureMapping mapping;
switch (texture.mapMode)
{
aiTextureMapping mapping = aiTextureMapping_OTHER;
switch (texture.mapMode) {
case LWO::Texture::Planar:
mapping = aiTextureMapping_PLANE;
break;
@ -120,8 +112,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
ASSIMP_LOG_ERROR("LWO2: Unsupported texture mapping: FrontProjection");
mapping = aiTextureMapping_OTHER;
break;
case LWO::Texture::UV:
{
case LWO::Texture::UV: {
if (UINT_MAX == texture.mRealUVIndex) {
// We have no UV index for this texture, so we can't display it
continue;
@ -132,8 +123,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_UVWSRC(type, cur));
mapping = aiTextureMapping_UV;
}
break;
} break;
default:
ai_assert(false);
};
@ -178,7 +168,6 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
if ((*clip).idx == temp) {
candidate = clip;
}
}
if (candidate == end) {
ASSIMP_LOG_ERROR("LWO2: Clip index is out of bounds");
@ -191,8 +180,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
s.Set("$texture.png");
//continue;
}
else {
} else {
if (Clip::UNSUPPORTED == (*candidate).type) {
ASSIMP_LOG_ERROR("LWO2: Clip type is not supported");
continue;
@ -207,9 +195,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
}
pcMat->AddProperty(&flags, 1, AI_MATKEY_TEXFLAGS(type, cur));
}
}
else
{
} else {
std::string ss = texture.mFileName;
if (!ss.length()) {
ASSIMP_LOG_WARN("LWOB: Empty file name");
@ -224,8 +210,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
pcMat->AddProperty<float>(&texture.mStrength, 1, AI_MATKEY_TEXBLEND(type, cur));
// add the blend operation
switch (texture.blendType)
{
switch (texture.blendType) {
case LWO::Texture::Normal:
case LWO::Texture::Multiply:
temp = (unsigned int)aiTextureOp_Multiply;
@ -247,7 +232,6 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
default:
temp = (unsigned int)aiTextureOp_Multiply;
ASSIMP_LOG_WARN("LWO2: Unsupported texture blend mode: alpha or displacement");
}
// Setup texture operation
pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_TEXOP(type, cur));
@ -270,8 +254,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
{
void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) {
// copy the name of the surface
aiString st;
st.Set(surf.mName);
@ -285,28 +268,26 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
pcMat->AddProperty(&surf.mBumpIntensity, 1, AI_MATKEY_BUMPSCALING);
aiShadingMode m;
if (surf.mSpecularValue && surf.mGlossiness)
{
if (surf.mSpecularValue && surf.mGlossiness) {
float fGloss;
if (mIsLWO2) {
fGloss = std::pow(surf.mGlossiness * ai_real(10.0) + ai_real(2.0), ai_real(2.0));
}
else
{
} else {
if (16.0 >= surf.mGlossiness)
fGloss = 6.0;
else if (64.0 >= surf.mGlossiness)
fGloss = 20.0;
else if (256.0 >= surf.mGlossiness)
fGloss = 50.0;
else fGloss = 80.0;
else
fGloss = 80.0;
}
pcMat->AddProperty(&surf.mSpecularValue, 1, AI_MATKEY_SHININESS_STRENGTH);
pcMat->AddProperty(&fGloss, 1, AI_MATKEY_SHININESS);
m = aiShadingMode_Phong;
}
else m = aiShadingMode_Gouraud;
} else
m = aiShadingMode_Gouraud;
// specular color
aiColor3D clr = lerp(aiColor3D(1.0, 1.0, 1.0), surf.mColor, surf.mColorHighlights);
@ -330,7 +311,6 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
pcMat->AddProperty(&def, 1, AI_MATKEY_BLEND_FUNC);
}
// ADD TEXTURES to the material
// TODO: find out how we can handle COLOR textures correctly...
bool b = HandleTextures(pcMat, surf.mColorTextures, aiTextureType_DIFFUSE);
@ -349,15 +329,12 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
m = aiShadingMode_Toon;
break;
}
else if (shader.functionName == "LW_RealFresnel" || shader.functionName == "LW_FastFresnel") {
} else if (shader.functionName == "LW_RealFresnel" || shader.functionName == "LW_FastFresnel") {
ASSIMP_LOG_INFO("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel");
m = aiShadingMode_Fresnel;
break;
}
else
{
} else {
ASSIMP_LOG_WARN_F("LWO2: Unknown surface shader: ", shader.functionName);
}
}
@ -377,8 +354,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
// ------------------------------------------------------------------------------------------------
char LWOImporter::FindUVChannels(LWO::TextureList &list,
LWO::Layer& /*layer*/,LWO::UVChannel& uv, unsigned int next)
{
LWO::Layer & /*layer*/, LWO::UVChannel &uv, unsigned int next) {
char ret = 0;
for (auto &texture : list) {
@ -391,11 +367,9 @@ char LWOImporter::FindUVChannels(LWO::TextureList& list,
ret = 1;
// got it.
if (texture.mRealUVIndex == UINT_MAX || texture.mRealUVIndex == next)
{
if (texture.mRealUVIndex == UINT_MAX || texture.mRealUVIndex == next) {
texture.mRealUVIndex = next;
}
else {
} else {
// channel mismatch. need to duplicate the material.
ASSIMP_LOG_WARN("LWO: Channel mismatch, would need to duplicate surface [design bug]");
@ -409,8 +383,7 @@ char LWOImporter::FindUVChannels(LWO::TextureList& list,
// ------------------------------------------------------------------------------------------------
void LWOImporter::FindUVChannels(LWO::Surface &surf,
LWO::SortedRep &sorted, LWO::Layer &layer,
unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS])
{
unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS]) {
unsigned int next = 0, extra = 0, num_extra = 0;
// Check whether we have an UV entry != 0 for one of the faces in 'sorted'
@ -429,10 +402,10 @@ void LWOImporter::FindUVChannels(LWO::Surface& surf,
if (extra >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
ASSIMP_LOG_ERROR("LWO: Maximum number of UV channels for "
"this mesh reached. Skipping channel \'" + uv.name + "\'");
"this mesh reached. Skipping channel \'" +
uv.name + "\'");
}
else {
} else {
// Search through all textures assigned to 'surf' and look for this UV channel
char had = 0;
had |= FindUVChannels(surf.mColorTextures, layer, uv, next);
@ -474,8 +447,7 @@ void LWOImporter::FindUVChannels(LWO::Surface& surf,
// ------------------------------------------------------------------------------------------------
void LWOImporter::FindVCChannels(const LWO::Surface &surf, LWO::SortedRep &sorted, const LWO::Layer &layer,
unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS])
{
unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS]) {
unsigned int next = 0;
// Check whether we have an vc entry != 0 for one of the faces in 'sorted'
@ -489,8 +461,7 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
}
out[0] = i;
++next;
}
else {
} else {
for (LWO::SortedRep::iterator it = sorted.begin(); it != sorted.end(); ++it) {
const LWO::Face &face = layer.mFaces[*it];
@ -502,10 +473,10 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) {
ASSIMP_LOG_ERROR("LWO: Maximum number of vertex color channels for "
"this mesh reached. Skipping channel \'" + vc.name + "\'");
"this mesh reached. Skipping channel \'" +
vc.name + "\'");
}
else {
} else {
out[next++] = i;
}
it = sorted.end() - 1;
@ -521,11 +492,9 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
{
void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture &tex) {
LE_NCONST uint8_t *const end = mFileBuffer + size;
while (true)
{
while (true) {
if (mFileBuffer + 6 >= end) break;
LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -533,8 +502,7 @@ void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
throw DeadlyImportError("LWO2: Invalid SURF.BLOCK chunk length");
uint8_t *const next = mFileBuffer + head.length;
switch (head.type)
{
switch (head.type) {
case AI_LWO_PROJ:
tex.mapMode = (Texture::MappingMode)GetU2();
break;
@ -563,37 +531,32 @@ void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture& tex )
{
void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture &tex) {
// --- not supported at the moment
ASSIMP_LOG_ERROR("LWO2: Found procedural texture, this is not supported");
tex.bCanUse = false;
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture& tex )
{
void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture &tex) {
// --- not supported at the moment
ASSIMP_LOG_ERROR("LWO2: Found gradient texture, this is not supported");
tex.bCanUse = false;
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
{
void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture &tex) {
LE_NCONST uint8_t *const end = mFileBuffer + size;
// get the ordinal string
GetS0(tex.ordinal, size);
// we could crash later if this is an empty string ...
if (!tex.ordinal.length())
{
if (!tex.ordinal.length()) {
ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string");
tex.ordinal = "\x00";
}
while (true)
{
while (true) {
if (mFileBuffer + 6 >= end) break;
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -601,8 +564,7 @@ void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
throw DeadlyImportError("LWO2: Invalid texture header chunk length");
uint8_t *const next = mFileBuffer + head.length;
switch (head.type)
{
switch (head.type) {
case AI_LWO_CHAN:
tex.type = GetU4();
break;
@ -619,8 +581,7 @@ void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsigned int size )
{
void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader *head, unsigned int size) {
ai_assert(!mSurfaces->empty());
LWO::Surface &surf = mSurfaces->back();
LWO::Texture tex;
@ -630,8 +591,7 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
size -= head->length + 6;
// now get the exact type of the texture
switch (head->type)
{
switch (head->type) {
case AI_LWO_PROC:
LoadLWO2Procedural(size, tex);
break;
@ -644,22 +604,28 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
// get the destination channel
TextureList *listRef = NULL;
switch (tex.type)
{
switch (tex.type) {
case AI_LWO_COLR:
listRef = &surf.mColorTextures;break;
listRef = &surf.mColorTextures;
break;
case AI_LWO_DIFF:
listRef = &surf.mDiffuseTextures;break;
listRef = &surf.mDiffuseTextures;
break;
case AI_LWO_SPEC:
listRef = &surf.mSpecularTextures;break;
listRef = &surf.mSpecularTextures;
break;
case AI_LWO_GLOS:
listRef = &surf.mGlossinessTextures;break;
listRef = &surf.mGlossinessTextures;
break;
case AI_LWO_BUMP:
listRef = &surf.mBumpTextures;break;
listRef = &surf.mBumpTextures;
break;
case AI_LWO_TRAN:
listRef = &surf.mOpacityTextures;break;
listRef = &surf.mOpacityTextures;
break;
case AI_LWO_REFL:
listRef = &surf.mReflectionTextures;break;
listRef = &surf.mReflectionTextures;
break;
default:
ASSIMP_LOG_WARN("LWO2: Encountered unknown texture type");
return;
@ -676,8 +642,7 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, unsigned int size )
{
void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader * /*head*/, unsigned int size) {
LE_NCONST uint8_t *const end = mFileBuffer + size;
ai_assert(!mSurfaces->empty());
@ -688,15 +653,13 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
GetS0(shader.ordinal, size);
// we could crash later if this is an empty string ...
if (!shader.ordinal.length())
{
if (!shader.ordinal.length()) {
ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string");
shader.ordinal = "\x00";
}
// read the header
while (true)
{
while (true) {
if (mFileBuffer + 6 >= end) break;
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -704,8 +667,7 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
throw DeadlyImportError("LWO2: Invalid shader header chunk length");
uint8_t *const next = mFileBuffer + head.length;
switch (head.type)
{
switch (head.type) {
case AI_LWO_ENAB:
shader.enabled = GetU2() ? true : false;
break;
@ -727,8 +689,7 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Surface(unsigned int size)
{
void LWOImporter::LoadLWO2Surface(unsigned int size) {
LE_NCONST uint8_t *const end = mFileBuffer + size;
mSurfaces->push_back(LWO::Surface());
@ -741,19 +702,20 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
GetS0(derived, (unsigned int)(end - mFileBuffer));
if (derived.length()) {
// yes, find this surface
for (SurfaceList::iterator it = mSurfaces->begin(), end = mSurfaces->end()-1; it != end; ++it) {
for (SurfaceList::iterator it = mSurfaces->begin(), itEnd = mSurfaces->end() - 1; it != itEnd; ++it) {
if ((*it).mName == derived) {
// we have it ...
surf = *it;
derived.clear();break;
derived.clear();
break;
}
}
if (derived.size())
if (derived.size()) {
ASSIMP_LOG_WARN("LWO2: Unable to find source surface: " + derived);
}
}
while (true)
{
while (true) {
if (mFileBuffer + 6 >= end)
break;
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -762,11 +724,9 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
throw DeadlyImportError("LWO2: Invalid surface chunk length");
uint8_t *const next = mFileBuffer + head.length;
switch (head.type)
{
switch (head.type) {
// diffuse color
case AI_LWO_COLR:
{
case AI_LWO_COLR: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, COLR, 12);
surf.mColor.r = GetF4();
surf.mColor.g = GetF4();
@ -774,22 +734,19 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
break;
}
// diffuse strength ... hopefully
case AI_LWO_DIFF:
{
case AI_LWO_DIFF: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, DIFF, 4);
surf.mDiffuseValue = GetF4();
break;
}
// specular strength ... hopefully
case AI_LWO_SPEC:
{
case AI_LWO_SPEC: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SPEC, 4);
surf.mSpecularValue = GetF4();
break;
}
// transparency
case AI_LWO_TRAN:
{
case AI_LWO_TRAN: {
// transparency explicitly disabled?
if (surf.mTransparency == 10e10f)
break;
@ -799,65 +756,56 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
break;
}
// additive transparency
case AI_LWO_ADTR:
{
case AI_LWO_ADTR: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, ADTR, 4);
surf.mAdditiveTransparency = GetF4();
break;
}
// wireframe mode
case AI_LWO_LINE:
{
case AI_LWO_LINE: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, LINE, 2);
if (GetU2() & 0x1)
surf.mWireframe = true;
break;
}
// glossiness
case AI_LWO_GLOS:
{
case AI_LWO_GLOS: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, GLOS, 4);
surf.mGlossiness = GetF4();
break;
}
// bump intensity
case AI_LWO_BUMP:
{
case AI_LWO_BUMP: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, BUMP, 4);
surf.mBumpIntensity = GetF4();
break;
}
// color highlights
case AI_LWO_CLRH:
{
case AI_LWO_CLRH: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, CLRH, 4);
surf.mColorHighlights = GetF4();
break;
}
// index of refraction
case AI_LWO_RIND:
{
case AI_LWO_RIND: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, RIND, 4);
surf.mIOR = GetF4();
break;
}
// polygon sidedness
case AI_LWO_SIDE:
{
case AI_LWO_SIDE: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SIDE, 2);
surf.bDoubleSided = (3 == GetU2());
break;
}
// maximum smoothing angle
case AI_LWO_SMAN:
{
case AI_LWO_SMAN: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SMAN, 4);
surf.mMaximumSmoothAngle = std::fabs(GetF4());
break;
}
// vertex color channel to be applied to the surface
case AI_LWO_VCOL:
{
case AI_LWO_VCOL: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, VCOL, 12);
surf.mDiffuseValue *= GetF4(); // strength
ReadVSizedIntLWO2(mFileBuffer); // skip envelope
@ -868,13 +816,11 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
break;
}
// surface bock entry
case AI_LWO_BLOK:
{
case AI_LWO_BLOK: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, BLOK, 4);
IFF::SubChunkHeader head2 = IFF::LoadSubChunk(mFileBuffer);
switch (head2.type)
{
switch (head2.type) {
case AI_LWO_PROC:
case AI_LWO_GRAD:
case AI_LWO_IMAP:

View File

@ -45,22 +45,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the LWS importer class
*/
#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
#include "LWS/LWSLoader.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include "Common/Importer.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/SceneCombiner.h>
#include <assimp/GenericProperty.h>
#include <assimp/ParsingUtils.h>
#include <assimp/SceneCombiner.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <assimp/fast_atof.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory>
@ -81,8 +80,7 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Recursive parsing of LWS files
void LWS::Element::Parse (const char*& buffer)
{
void LWS::Element::Parse(const char *&buffer) {
for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
// begin of a new element with children
@ -91,8 +89,7 @@ void LWS::Element::Parse (const char*& buffer)
++buffer;
SkipSpaces(&buffer);
sub = true;
}
else if (*buffer == '}')
} else if (*buffer == '}')
return;
children.push_back(Element());
@ -100,12 +97,12 @@ void LWS::Element::Parse (const char*& buffer)
// copy data line - read token per token
const char *cur = buffer;
while (!IsSpaceOrNewLine(*buffer)) ++buffer;
while (!IsSpaceOrNewLine(*buffer))
++buffer;
children.back().tokens[0] = std::string(cur, (size_t)(buffer - cur));
SkipSpaces(&buffer);
if (children.back().tokens[0] == "Plugin")
{
if (children.back().tokens[0] == "Plugin") {
ASSIMP_LOG_DEBUG("LWS: Skipping over plugin-specific data");
// strange stuff inside Plugin/Endplugin blocks. Needn't
@ -120,7 +117,8 @@ void LWS::Element::Parse (const char*& buffer)
}
cur = buffer;
while (!IsLineEnd(*buffer)) ++buffer;
while (!IsLineEnd(*buffer))
++buffer;
children.back().tokens[1] = std::string(cur, (size_t)(buffer - cur));
// parse more elements recursively
@ -131,28 +129,25 @@ void LWS::Element::Parse (const char*& buffer)
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
LWSImporter::LWSImporter()
: configSpeedFlag(),
LWSImporter::LWSImporter() :
configSpeedFlag(),
io(),
first(),
last(),
fps(),
noSkeletonMesh()
{
noSkeletonMesh() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
LWSImporter::~LWSImporter()
{
LWSImporter::~LWSImporter() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool checkSig) const
{
bool LWSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(pFile);
if (extension == "lws" || extension == "mot")
return true;
@ -169,15 +164,13 @@ bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool c
// ------------------------------------------------------------------------------------------------
// Get list of file extensions
const aiImporterDesc* LWSImporter::GetInfo () const
{
const aiImporterDesc *LWSImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties
void LWSImporter::SetupProperties(const Importer* pImp)
{
void LWSImporter::SetupProperties(const Importer *pImp) {
// AI_CONFIG_FAVOUR_SPEED
configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED, 0));
@ -198,15 +191,15 @@ void LWSImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Read an envelope description
void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
{
void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
if (dad.children.empty()) {
ASSIMP_LOG_ERROR("LWS: Envelope descriptions must not be empty");
return;
}
// reserve enough storage
std::list< LWS::Element >::const_iterator it = dad.children.begin();;
std::list<LWS::Element>::const_iterator it = dad.children.begin();
;
fill.keys.reserve(strtoul10(it->tokens[1].c_str()));
for (++it; it != dad.children.end(); ++it) {
@ -255,8 +248,7 @@ void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
SkipSpaces(&c);
c = fast_atoreal_move<float>(c, key.params[i]);
}
}
else if ((*it).tokens[0] == "Behaviors") {
} else if ((*it).tokens[0] == "Behaviors") {
SkipSpaces(&c);
fill.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c);
@ -271,8 +263,7 @@ void LWSImporter::ReadEnvelope_Old(
std::list<LWS::Element>::const_iterator &it,
const std::list<LWS::Element>::const_iterator &end,
LWS::NodeDesc &nodes,
unsigned int /*version*/)
{
unsigned int /*version*/) {
unsigned int num, sub_num;
if (++it == end) goto unexpected_end;
@ -311,8 +302,7 @@ unexpected_end:
// ------------------------------------------------------------------------------------------------
// Setup a nice name for a node
void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src)
{
void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
const unsigned int combined = src.number | ((unsigned int)src.type) << 28u;
// the name depends on the type. We break LWS's strange naming convention
@ -323,7 +313,8 @@ void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src)
std::string::size_type s = src.path.find_last_of("\\/");
if (s == std::string::npos)
s = 0;
else ++s;
else
++s;
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);
@ -339,8 +330,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
BatchLoader &batch,
aiCamera **&camOut,
aiLight **&lightOut,
std::vector<aiNodeAnim*>& animOut)
{
std::vector<aiNodeAnim *> &animOut) {
// Setup a very cryptic name for the node, we want the user to be happy
SetupNodeName(nd, src);
aiNode *ndAnim = nd;
@ -354,8 +344,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
obj = batch.GetImport(src.id);
if (!obj) {
ASSIMP_LOG_ERROR("LWS: Failed to read external file " + src.path);
}
else {
} else {
if (obj->mRootNode->mNumChildren == 1) {
//If the pivot is not set for this layer, get it from the external object
@ -418,11 +407,10 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
lit->mAngleInnerCone = (float)AI_DEG_TO_RAD(src.lightConeAngle);
lit->mAngleOuterCone = lit->mAngleInnerCone + (float)AI_DEG_TO_RAD(src.lightEdgeAngle);
}
else if (src.lightType == 1) { /* directional light source */
} else if (src.lightType == 1) { /* directional light source */
lit->mType = aiLightSource_DIRECTIONAL;
}
else lit->mType = aiLightSource_POINT;
} else
lit->mType = aiLightSource_POINT;
// fixme: no proper handling of light falloffs yet
if (src.lightFalloffType == 1)
@ -471,15 +459,13 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
// ------------------------------------------------------------------------------------------------
// Determine the exact location of a LWO file
std::string LWSImporter::FindLWOFile(const std::string& in)
{
std::string LWSImporter::FindLWOFile(const std::string &in) {
// insert missing directory separator if necessary
std::string tmp;
if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
{
if (in.length() > 3 && in[1] == ':' && in[2] != '\\' && in[2] != '/') {
tmp = in[0] + (std::string(":\\") + in.substr(2));
}
else tmp = in;
} else
tmp = in;
if (io->Exists(tmp)) {
return in;
@ -503,7 +489,6 @@ std::string LWSImporter::FindLWOFile(const std::string& in)
return test;
}
// return original path, maybe the IOsystem knows better
return tmp;
}
@ -511,8 +496,7 @@ std::string LWSImporter::FindLWOFile(const std::string& in)
// ------------------------------------------------------------------------------------------------
// Read file into given scene data structure
void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler)
{
IOSystem *pIOHandler) {
io = pIOHandler;
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
@ -526,7 +510,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
TextFileToBuffer(file.get(), mBuffer);
// Parse the file structure
LWS::Element root; const char* dummy = &mBuffer[0];
LWS::Element root;
const char *dummy = &mBuffer[0];
root.Parse(dummy);
// Construct a Batchimporter to read more files recursively
@ -594,8 +579,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID
SkipSpaces(&c);
d.number = strtoul16(c, &c) & AI_LWS_MASK;
}
else d.number = cur_object++;
} else
d.number = cur_object++;
// and add the file to the import list
SkipSpaces(&c);
@ -616,8 +601,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
SkipSpaces(&c);
}
else d.number = cur_object++;
} else
d.number = cur_object++;
std::string path = FindLWOFile(c);
d.id = batch.AddLoadRequest(path, 0, NULL);
@ -634,8 +619,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
SkipSpaces(&c);
}
else d.number = cur_object++;
} else
d.number = cur_object++;
d.name = c;
nodes.push_back(d);
@ -695,11 +680,13 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty())
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'Pre/PostBehavior'");
else {
for (std::list<LWO::Envelope>::iterator it = nodes.back().channels.begin(); it != nodes.back().channels.end(); ++it) {
for (std::list<LWO::Envelope>::iterator envelopeIt = nodes.back().channels.begin(); envelopeIt != nodes.back().channels.end(); ++envelopeIt) {
// two ints per envelope
LWO::Envelope& env = *it;
env.pre = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c);
env.post = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c);
LWO::Envelope &env = *envelopeIt;
env.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c);
env.post = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c);
}
}
}
@ -708,7 +695,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty())
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentItem\'");
else nodes.back().parent = strtoul16(c,&c);
else
nodes.back().parent = strtoul16(c, &c);
}
// 'ParentObject': deprecated one for older formats
else if (version < 3 && (*it).tokens[0] == "ParentObject") {
@ -728,8 +716,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
}
else d.number = cur_camera++;
} else
d.number = cur_camera++;
nodes.push_back(d);
num_camera++;
@ -739,7 +727,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'CameraName\'");
else nodes.back().name = c;
else
nodes.back().name = c;
}
// 'AddLight': add a light to the scenegraph
else if ((*it).tokens[0] == "AddLight") {
@ -750,8 +739,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
}
else d.number = cur_light++;
} else
d.number = cur_light++;
nodes.push_back(d);
num_light++;
@ -761,14 +750,16 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightName\'");
else nodes.back().name = c;
else
nodes.back().name = c;
}
// 'LightIntensity': set intensity of currently active light
else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightIntensity\'");
else fast_atoreal_move<float>(c, nodes.back().lightIntensity );
else
fast_atoreal_move<float>(c, nodes.back().lightIntensity);
}
// 'LightType': set type of currently active light
@ -776,7 +767,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightType\'");
else nodes.back().lightType = strtoul10(c);
else
nodes.back().lightType = strtoul10(c);
}
// 'LightFalloffType': set falloff type of currently active light
@ -784,7 +776,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightFalloffType\'");
else nodes.back().lightFalloffType = strtoul10(c);
else
nodes.back().lightFalloffType = strtoul10(c);
}
// 'LightConeAngle': set cone angle of currently active light
@ -792,7 +785,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightConeAngle\'");
else nodes.back().lightConeAngle = fast_atof(c);
else
nodes.back().lightConeAngle = fast_atof(c);
}
// 'LightEdgeAngle': set area where we're smoothing from min to max intensity
@ -800,7 +794,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightEdgeAngle\'");
else nodes.back().lightEdgeAngle = fast_atof(c);
else
nodes.back().lightEdgeAngle = fast_atof(c);
}
// 'LightColor': set color of currently active light
@ -834,32 +829,33 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
}
// resolve parenting
for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
// check whether there is another node which calls us a parent
for (std::list<LWS::NodeDesc>::iterator dit = nodes.begin(); dit != nodes.end(); ++dit) {
if (dit != it && *it == (*dit).parent) {
if (dit != ndIt && *ndIt == (*dit).parent) {
if ((*dit).parent_resolved) {
// fixme: it's still possible to produce an overflow due to cross references ..
ASSIMP_LOG_ERROR("LWS: Found cross reference in scene-graph");
continue;
}
(*it).children.push_back(&*dit);
(*dit).parent_resolved = &*it;
ndIt->children.push_back(&*dit);
(*dit).parent_resolved = &*ndIt;
}
}
}
// find out how many nodes have no parent yet
unsigned int no_parent = 0;
for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
if (!(*it).parent_resolved)
for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
if (!ndIt->parent_resolved) {
++no_parent;
}
if (!no_parent)
}
if (!no_parent) {
throw DeadlyImportError("LWS: Unable to find scene root node");
}
// Load all subsequent files
batch.LoadAll();
@ -884,14 +880,14 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
nd->mName.Set("<LWSRoot>");
nd->mChildren = new aiNode *[no_parent];
for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
if (!(*it).parent_resolved) {
for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
if (!ndIt->parent_resolved) {
aiNode *ro = nd->mChildren[nd->mNumChildren++] = new aiNode();
ro->mParent = nd;
// ... and build the scene graph. If we encounter object nodes,
// add then to our attachment table.
BuildGraph(ro,*it, attach, batch, cams, lights, anims);
BuildGraph(ro, *ndIt, attach, batch, cams, lights, anims);
}
}
@ -920,7 +916,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// OK ... finally build the output graph
SceneCombiner::MergeScenes(&pScene, master, attach,
AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES | (!configSpeedFlag ? (
AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) : 0));
AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) :
0));
// Check flags
if (!pScene->mNumMeshes || !pScene->mNumMaterials) {
@ -931,7 +928,6 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
SkeletonMeshBuilder builder(pScene);
}
}
}
#endif // !! ASSIMP_BUILD_NO_LWS_IMPORTER

View File

@ -64,9 +64,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Exporter.hpp>
#include <assimp/IOSystem.hpp>
#include "M3DWrapper.h"
#include "M3DExporter.h"
#include "M3DMaterials.h"
#include "M3DWrapper.h"
// RESOURCES:
// https://gitlab.com/bztsrc/model3d/blob/master/docs/m3d_format.md
@ -132,13 +132,13 @@ void addProp(m3dm_t *m, uint8_t type, uint32_t value) {
// ------------------------------------------------------------------------------------------------
// convert aiString to identifier safe C string. This is a duplication of _m3d_safestr
char *SafeStr(aiString str, bool isStrict)
{
char *SafeStr(aiString str, bool isStrict) {
char *s = (char *)&str.data;
char *d, *ret;
int i, len;
for(len = str.length + 1; *s && (*s == ' ' || *s == '\t'); s++, len--);
for (len = str.length + 1; *s && (*s == ' ' || *s == '\t'); s++, len--)
;
if (len > 255) len = 255;
ret = (char *)M3D_MALLOC(len + 1);
if (!ret) {
@ -147,7 +147,8 @@ char *SafeStr(aiString str, bool isStrict)
for (i = 0, d = ret; i < len && *s && *s != '\r' && *s != '\n'; s++, d++, i++) {
*d = isStrict && (*s == ' ' || *s == '\t' || *s == '/' || *s == '\\') ? '_' : (*s == '\t' ? ' ' : *s);
}
for(; d > ret && (*(d-1) == ' ' || *(d-1) == '\t'); d--);
for (; d > ret && (*(d - 1) == ' ' || *(d - 1) == '\t'); d--)
;
*d = 0;
return ret;
}
@ -290,10 +291,10 @@ void ExportSceneM3D(
// Worker function for exporting a scene to ASCII A3D.
// Prototyped and registered in Exporter.cpp
void ExportSceneM3DA(
const char *pFile,
IOSystem *pIOSystem,
const aiScene *pScene,
const ExportProperties *pProperties
const char *,
IOSystem*,
const aiScene*,
const ExportProperties *
) {
#ifdef M3D_ASCII

View File

@ -56,9 +56,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Importer.hpp>
#include <memory>
#include "M3DWrapper.h"
#include "M3DImporter.h"
#include "M3DMaterials.h"
#include "M3DWrapper.h"
// RESOURCES:
// https://gitlab.com/bztsrc/model3d/blob/master/docs/m3d_format.md
@ -256,9 +256,9 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
for (i = 0; i < m3d->nummaterial; i++) {
m = &m3d->material[i];
aiMaterial *mat = new aiMaterial;
aiMaterial *newMat = new aiMaterial;
name.Set(std::string(m->name));
mat->AddProperty(&name, AI_MATKEY_NAME);
newMat->AddProperty(&name, AI_MATKEY_NAME);
for (j = 0; j < m->numprop; j++) {
// look up property type
// 0 - 127 scalar values,
@ -271,29 +271,36 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
break;
}
// should never happen, but be safe than sorry
if (k == 256) continue;
if (k == 256)
continue;
// scalar properties
if (m->prop[j].type < 128 && aiProps[k].pKey) {
switch (m3d_propertytypes[k].format) {
case m3dpf_color:
c = mkColor(m->prop[j].value.color);
mat->AddProperty(&c, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
newMat->AddProperty(&c, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
break;
case m3dpf_float:
f = m->prop[j].value.fnum;
mat->AddProperty(&f, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
newMat->AddProperty(&f, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
break;
default:
n = m->prop[j].value.num;
if (m->prop[j].type == m3dp_il) {
switch (n) {
case 0: n = aiShadingMode_NoShading; break;
case 2: n = aiShadingMode_Phong; break;
default: n = aiShadingMode_Gouraud; break;
case 0:
n = aiShadingMode_NoShading;
break;
case 2:
n = aiShadingMode_Phong;
break;
default:
n = aiShadingMode_Gouraud;
break;
}
}
mat->AddProperty(&n, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
newMat->AddProperty(&n, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
break;
}
}
@ -403,7 +410,6 @@ void M3DImporter::importMeshes(const M3DWrapper &m3d) {
ai_assert(m3d);
ai_assert(mScene->mRootNode != nullptr);
for (i = 0; i < m3d->numface; i++) {
// we must switch mesh if material changes
if (lastMat != m3d->face[i].materialid) {

View File

@ -100,6 +100,10 @@ M3DWrapper::M3DWrapper() {
}
M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) {
if (nullptr == pIOHandler) {
ai_assert(nullptr != pIOHandler);
}
#ifdef ASSIMP_USE_M3D_READFILECB
// pass this IOHandler to the C callback in a thread-local pointer
m3dimporter_pIOHandler = pIOHandler;

File diff suppressed because it is too large Load Diff

View File

@ -45,21 +45,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the MD5 importer class
*/
#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
// internal headers
#include <assimp/RemoveComments.h>
#include "MD5Loader.h"
#include <assimp/MathFunctions.h>
#include <assimp/RemoveComments.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/StringComparison.h>
#include <assimp/fast_atof.h>
#include <assimp/MathFunctions.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp>
#include <memory>
using namespace Assimp;
@ -67,7 +66,6 @@ using namespace Assimp;
// Minimum weight value. Weights inside [-n ... n] are ignored
#define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>()
static const aiImporterDesc desc = {
"Doom 3 / MD5 Mesh Importer",
"",
@ -83,28 +81,20 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MD5Importer::MD5Importer()
: mIOHandler()
, mBuffer()
, fileSize()
, iLineNumber()
, pScene()
, pIOHandler()
, bHadMD5Mesh()
, bHadMD5Anim()
, bHadMD5Camera()
, configNoAutoLoad (false)
{}
MD5Importer::MD5Importer() :
mIOHandler(nullptr), mBuffer(), fileSize(), iLineNumber(), pScene(), bHadMD5Mesh(), bHadMD5Anim(), bHadMD5Camera(), configNoAutoLoad(false) {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MD5Importer::~MD5Importer()
{}
MD5Importer::~MD5Importer() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(pFile);
if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera")
@ -121,15 +111,13 @@ bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------
// Get list of all supported extensions
const aiImporterDesc* MD5Importer::GetInfo () const
{
const aiImporterDesc *MD5Importer::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup import properties
void MD5Importer::SetupProperties(const Importer* pImp)
{
void MD5Importer::SetupProperties(const Importer *pImp) {
// AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD
configNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD, 0));
}
@ -137,9 +125,8 @@ void MD5Importer::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void MD5Importer::InternReadFile(const std::string &pFile,
aiScene* _pScene, IOSystem* _pIOHandler)
{
pIOHandler = _pIOHandler;
aiScene *_pScene, IOSystem *pIOHandler) {
mIOHandler = pIOHandler;
pScene = _pScene;
bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
@ -151,25 +138,21 @@ void MD5Importer::InternReadFile( const std::string& pFile,
try {
if (extension == "md5camera") {
LoadMD5CameraFile();
}
else if (configNoAutoLoad || extension == "md5anim") {
} else if (configNoAutoLoad || extension == "md5anim") {
// determine file extension and process just *one* file
if (extension.length() == 0) {
throw DeadlyImportError("Failure, need file extension to determine MD5 part type");
}
if (extension == "md5anim") {
LoadMD5AnimFile();
}
else if (extension == "md5mesh") {
} else if (extension == "md5mesh") {
LoadMD5MeshFile();
}
}
else {
} else {
LoadMD5MeshFile();
LoadMD5AnimFile();
}
}
catch ( ... ) { // std::exception, Assimp::DeadlyImportError
} catch (...) { // std::exception, Assimp::DeadlyImportError
UnloadFileFromMemory();
throw;
}
@ -194,8 +177,7 @@ void MD5Importer::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------
// Load a file into a memory buffer
void MD5Importer::LoadFileIntoMemory (IOStream* file)
{
void MD5Importer::LoadFileIntoMemory(IOStream *file) {
// unload the previous buffer, if any
UnloadFileFromMemory();
@ -217,8 +199,7 @@ void MD5Importer::LoadFileIntoMemory (IOStream* file)
// ------------------------------------------------------------------------------------------------
// Unload the current memory buffer
void MD5Importer::UnloadFileFromMemory ()
{
void MD5Importer::UnloadFileFromMemory() {
// delete the file buffer
delete[] mBuffer;
mBuffer = NULL;
@ -227,8 +208,7 @@ void MD5Importer::UnloadFileFromMemory ()
// ------------------------------------------------------------------------------------------------
// Build unique vertices
void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
{
void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
std::vector<bool> abHad(meshSrc.mVertices.size(), false);
// allocate enough storage to keep the output structures
@ -252,8 +232,8 @@ void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
// generate a new vertex
meshSrc.mVertices[iNewIndex] = meshSrc.mVertices[face.mIndices[i]];
face.mIndices[i] = iNewIndex++;
}
else abHad[face.mIndices[i]] = true;
} else
abHad[face.mIndices[i]] = true;
}
// swap face order
std::swap(face.mIndices[0], face.mIndices[2]);
@ -262,8 +242,7 @@ void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
// ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5MESH
void MD5Importer::AttachChilds_Mesh(int iParentID,aiNode* piParent, BoneList& bones)
{
void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones) {
ai_assert(NULL != piParent && !piParent->mNumChildren);
// First find out how many children we'll have
@ -313,8 +292,7 @@ void MD5Importer::AttachChilds_Mesh(int iParentID,aiNode* piParent, BoneList& bo
// ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5ANIM
void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList& bones,const aiNodeAnim** node_anims)
{
void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneList &bones, const aiNodeAnim **node_anims) {
ai_assert(NULL != piParent && !piParent->mNumChildren);
// First find out how many children we'll have
@ -327,8 +305,7 @@ void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList
piParent->mChildren = new aiNode *[piParent->mNumChildren];
for (int i = 0; i < (int)bones.size(); ++i) {
// (avoid infinite recursion)
if (iParentID != i && bones[i].mParentIndex == iParentID)
{
if (iParentID != i && bones[i].mParentIndex == iParentID) {
aiNode *pc;
// setup a new node
*piParent->mChildren++ = pc = new aiNode();
@ -337,7 +314,8 @@ void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList
// get the corresponding animation channel and its first frame
const aiNodeAnim **cur = node_anims;
while ((**cur).mNodeName != pc->mName)++cur;
while ((**cur).mNodeName != pc->mName)
++cur;
aiMatrix4x4::Translation((**cur).mPositionKeys[0].mValue, pc->mTransformation);
pc->mTransformation = pc->mTransformation * aiMatrix4x4((**cur).mRotationKeys[0].mValue.GetMatrix());
@ -353,13 +331,12 @@ void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList
// ------------------------------------------------------------------------------------------------
// Load a MD5MESH file
void MD5Importer::LoadMD5MeshFile ()
{
void MD5Importer::LoadMD5MeshFile() {
std::string pFile = mFile + "md5mesh";
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL || !file->FileSize()) {
if (file.get() == nullptr || !file->FileSize()) {
ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + pFile);
return;
}
@ -442,8 +419,7 @@ void MD5Importer::LoadMD5MeshFile ()
::memset(piCount, 0, sizeof(unsigned int) * meshParser.mJoints.size());
for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w)
{
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
/* FIX for some invalid exporters */
if (!(weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON))
@ -458,8 +434,7 @@ void MD5Importer::LoadMD5MeshFile ()
if (mesh->mNumBones) // just for safety
{
mesh->mBones = new aiBone *[mesh->mNumBones];
for (unsigned int q = 0,h = 0; q < meshParser.mJoints.size();++q)
{
for (unsigned int q = 0, h = 0; q < meshParser.mJoints.size(); ++q) {
if (!piCount[q]) continue;
aiBone *p = mesh->mBones[h] = new aiBone();
p->mNumWeights = piCount[q];
@ -561,8 +536,7 @@ void MD5Importer::LoadMD5MeshFile ()
// set this also as material name
mat->AddProperty(&meshSrc.mShader, AI_MATKEY_NAME);
}
else {
} else {
mat->AddProperty(&meshSrc.mShader, AI_MATKEY_TEXTURE_DIFFUSE(0));
}
mesh->mMaterialIndex = n++;
@ -572,10 +546,9 @@ void MD5Importer::LoadMD5MeshFile ()
// ------------------------------------------------------------------------------------------------
// Load an MD5ANIM file
void MD5Importer::LoadMD5AnimFile ()
{
void MD5Importer::LoadMD5AnimFile() {
std::string pFile = mFile + "md5anim";
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if (!file.get() || !file->FileSize()) {
@ -594,8 +567,7 @@ void MD5Importer::LoadMD5AnimFile ()
if (animParser.mAnimatedBones.empty() || animParser.mFrames.empty() ||
animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) {
ASSIMP_LOG_ERROR("MD5ANIM: No frames or animated bones loaded");
}
else {
} else {
bHadMD5Anim = true;
pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations = 1];
@ -622,14 +594,12 @@ void MD5Importer::LoadMD5AnimFile ()
// now process all values in there ... read all joints
MD5::BaseFrameDesc *pcBaseFrame = &animParser.mBaseFrames[0];
for (AnimBoneList::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end(); ++iter2,
++pcAnimNode,++pcBaseFrame)
{
++pcAnimNode, ++pcBaseFrame) {
if ((*iter2).iFirstKeyIndex >= (*iter).mValues.size()) {
// Allow for empty frames
if ((*iter2).iFlags != 0) {
throw DeadlyImportError("MD5: Keyframe index is out of range");
}
continue;
}
@ -644,16 +614,16 @@ void MD5Importer::LoadMD5AnimFile ()
for (unsigned int i = 0; i < 3; ++i) {
if ((*iter2).iFlags & (1u << i)) {
vKey->mValue[i] = *fpCur++;
}
else vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
} else
vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
}
// orientation component
for (unsigned int i = 0; i < 3; ++i) {
if ((*iter2).iFlags & (8u << i)) {
vTemp[i] = *fpCur++;
}
else vTemp[i] = pcBaseFrame->vRotationQuat[i];
} else
vTemp[i] = pcBaseFrame->vRotationQuat[i];
}
MD5::ConvertQuaternion(vTemp, qKey->mValue);
@ -683,10 +653,9 @@ void MD5Importer::LoadMD5AnimFile ()
// ------------------------------------------------------------------------------------------------
// Load an MD5CAMERA file
void MD5Importer::LoadMD5CameraFile ()
{
void MD5Importer::LoadMD5CameraFile() {
std::string pFile = mFile + "md5camera";
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if (!file.get() || !file->FileSize()) {
@ -727,8 +696,7 @@ void MD5Importer::LoadMD5CameraFile ()
if (!cuts.size()) {
cuts.push_back(0);
cuts.push_back(static_cast<unsigned int>(frames.size() - 1));
}
else {
} else {
cuts.insert(cuts.begin(), 0);
if (cuts.back() < frames.size() - 1)

View File

@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file MD5Loader.h
* @brief Definition of the .MD5 importer class.
* http://www.modwiki.net/wiki/MD5_(file_format)
@ -48,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MD5LOADER_H_INCLUDED
#define AI_MD5LOADER_H_INCLUDED
#include <assimp/BaseImporter.h>
#include "MD5Parser.h"
#include <assimp/BaseImporter.h>
#include <assimp/types.h>
@ -64,15 +63,11 @@ using namespace Assimp::MD5;
// ---------------------------------------------------------------------------
/** Importer class for the MD5 file format
*/
class MD5Importer : public BaseImporter
{
class MD5Importer : public BaseImporter {
public:
MD5Importer();
~MD5Importer();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
@ -81,7 +76,6 @@ public:
bool checkSig) const;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
@ -102,9 +96,6 @@ protected:
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
protected:
// -------------------------------------------------------------------
/** Load a *.MD5MESH file.
*/
@ -154,7 +145,6 @@ protected:
void LoadFileIntoMemory(IOStream *pFile);
void UnloadFileFromMemory();
/** IOSystem to be used to access files */
IOSystem *mIOHandler;
@ -174,9 +164,6 @@ protected:
/** Scene to be filled */
aiScene *pScene;
/** (Custom) I/O handler implementation */
IOSystem* pIOHandler;
/** true if a MD5MESH file has already been parsed */
bool bHadMD5Mesh;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -43,7 +41,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the MDC importer class */
#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
// internal headers
@ -51,11 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MD3/MD3FileData.h"
#include "MDC/MDCNormalTable.h" // shouldn't be included by other units
#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp>
#include <memory>
@ -80,8 +77,7 @@ void MDC::BuildVertex(const Frame& frame,
const BaseVertex &bvert,
const CompressedVertex &cvert,
aiVector3D &vXYZOut,
aiVector3D& vNorOut)
{
aiVector3D &vNorOut) {
// compute the position
const float xd = (cvert.xd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
const float yd = (cvert.yd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
@ -98,26 +94,27 @@ void MDC::BuildVertex(const Frame& frame,
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MDCImporter::MDCImporter()
: configFrameID(),
MDCImporter::MDCImporter() :
configFrameID(),
pcHeader(),
mBuffer(),
fileSize()
{
fileSize() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MDCImporter::~MDCImporter()
{
MDCImporter::~MDCImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool MDCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(pFile);
if (extension == "mdc")
if (extension == "mdc") {
return true;
}
// if check for extension is not enough, check for the magic tokens
if (!extension.length() || checkSig) {
@ -129,15 +126,13 @@ bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
}
// ------------------------------------------------------------------------------------------------
const aiImporterDesc* MDCImporter::GetInfo () const
{
const aiImporterDesc *MDCImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Validate the header of the given MDC file
void MDCImporter::ValidateHeader()
{
void MDCImporter::ValidateHeader() {
AI_SWAP4(this->pcHeader->ulVersion);
AI_SWAP4(this->pcHeader->ulFlags);
AI_SWAP4(this->pcHeader->ulNumFrames);
@ -147,8 +142,7 @@ void MDCImporter::ValidateHeader()
AI_SWAP4(this->pcHeader->ulOffsetBorderFrames);
if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE)
{
pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE) {
char szBuffer[5];
szBuffer[0] = ((char *)&pcHeader->ulIdent)[0];
szBuffer[1] = ((char *)&pcHeader->ulIdent)[1];
@ -157,7 +151,8 @@ void MDCImporter::ValidateHeader()
szBuffer[4] = '\0';
throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
"magic word found is " + std::string( szBuffer ));
"magic word found is " +
std::string(szBuffer));
}
if (pcHeader->ulVersion != AI_MDC_VERSION) {
@ -165,8 +160,7 @@ void MDCImporter::ValidateHeader()
}
if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize ||
pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize)
{
pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize) {
throw DeadlyImportError("Some of the offset values in the MDC header are invalid "
"and point to something behind the file.");
}
@ -178,8 +172,7 @@ void MDCImporter::ValidateHeader()
// ------------------------------------------------------------------------------------------------
// Validate the header of a given MDC file surface
void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
{
void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface *pcSurf) {
AI_SWAP4(pcSurf->ulFlags);
AI_SWAP4(pcSurf->ulNumCompFrames);
AI_SWAP4(pcSurf->ulNumBaseFrames);
@ -202,8 +195,7 @@ void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
pcSurf->ulOffsetTexCoords + pcSurf->ulNumVertices * sizeof(MDC::TexturCoord) > iMax ||
pcSurf->ulOffsetShaders + pcSurf->ulNumShaders * sizeof(MDC::Shader) > iMax ||
pcSurf->ulOffsetFrameBaseFrames + pcSurf->ulNumBaseFrames * 2 > iMax ||
(pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2 > iMax))
{
(pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2 > iMax)) {
throw DeadlyImportError("Some of the offset values in the MDC surface header "
"are invalid and point somewhere behind the file.");
}
@ -211,8 +203,7 @@ void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
// ------------------------------------------------------------------------------------------------
// Setup configuration properties
void MDCImporter::SetupProperties(const Importer* pImp)
{
void MDCImporter::SetupProperties(const Importer *pImp) {
// The AI_CONFIG_IMPORT_MDC_KEYFRAME option overrides the
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
if (static_cast<unsigned int>(-1) == (configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDC_KEYFRAME, -1))) {
@ -223,18 +214,19 @@ void MDCImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void MDCImporter::InternReadFile(
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
{
const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
// Check whether we can read from the file
if( file.get() == NULL)
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDC file " + pFile + ".");
}
// check whether the mdc file is large enough to contain the file header
fileSize = (unsigned int)file->FileSize();
if( fileSize < sizeof(MDC::Header))
fileSize = static_cast<unsigned int>(file->FileSize());
if (fileSize < sizeof(MDC::Header)) {
throw DeadlyImportError("MDC File is too small.");
}
std::vector<unsigned char> mBuffer2(fileSize);
file->Read(&mBuffer2[0], 1, fileSize);
@ -260,12 +252,13 @@ void MDCImporter::InternReadFile(
BE_NCONST MDC::Surface *pcSurface, *pcSurface2;
pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface;
unsigned int iNumShaders = 0;
for (unsigned int i = 0; i < pcHeader->ulNumSurfaces;++i)
{
for (unsigned int i = 0; i < pcHeader->ulNumSurfaces; ++i) {
// validate the surface header
this->ValidateSurfaceHeader(pcSurface2);
if (pcSurface2->ulNumVertices && pcSurface2->ulNumTriangles)++pScene->mNumMeshes;
if (pcSurface2->ulNumVertices && pcSurface2->ulNumTriangles) {
++pScene->mNumMeshes;
}
iNumShaders += pcSurface2->ulNumShaders;
pcSurface2 = new ((int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface;
}
@ -273,13 +266,13 @@ void MDCImporter::InternReadFile(
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
// necessary that we don't crash if an exception occurs
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
pScene->mMeshes[i] = NULL;
}
// now read all surfaces
unsigned int iDefaultMatIndex = UINT_MAX;
for (unsigned int i = 0, iNum = 0; i < pcHeader->ulNumSurfaces;++i)
{
for (unsigned int i = 0, iNum = 0; i < pcHeader->ulNumSurfaces; ++i) {
if (!pcSurface->ulNumVertices || !pcSurface->ulNumTriangles) continue;
aiMesh *pcMesh = pScene->mMeshes[iNum++] = new aiMesh();
@ -287,12 +280,10 @@ void MDCImporter::InternReadFile(
pcMesh->mNumVertices = pcMesh->mNumFaces * 3;
// store the name of the surface for use as node name.
pcMesh->mName.Set(std::string(pcSurface->ucName
, strnlen(pcSurface->ucName, AI_MDC_MAXQPATH - 1)));
pcMesh->mName.Set(std::string(pcSurface->ucName, strnlen(pcSurface->ucName, AI_MDC_MAXQPATH - 1)));
// go to the first shader in the file. ignore the others.
if (pcSurface->ulNumShaders)
{
if (pcSurface->ulNumShaders) {
const MDC::Shader *pcShader = (const MDC::Shader *)((int8_t *)pcSurface + pcSurface->ulOffsetShaders);
pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
@ -301,13 +292,13 @@ void MDCImporter::InternReadFile(
::strnlen(pcShader->ucName, sizeof(pcShader->ucName))));
}
// need to create a default material
else if (UINT_MAX == iDefaultMatIndex)
{
else if (UINT_MAX == iDefaultMatIndex) {
pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
aszShaders.push_back(std::string());
}
// otherwise assign a reference to the default material
else pcMesh->mMaterialIndex = iDefaultMatIndex;
else
pcMesh->mMaterialIndex = iDefaultMatIndex;
// allocate output storage for the mesh
aiVector3D *pcVertCur = pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
@ -316,36 +307,32 @@ void MDCImporter::InternReadFile(
aiFace *pcFaceCur = pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
// create all vertices/faces
BE_NCONST MDC::Triangle* pcTriangle = (BE_NCONST MDC::Triangle*)
((int8_t*)pcSurface+pcSurface->ulOffsetTriangles);
BE_NCONST MDC::Triangle *pcTriangle = (BE_NCONST MDC::Triangle *)((int8_t *)pcSurface + pcSurface->ulOffsetTriangles);
BE_NCONST MDC::TexturCoord* const pcUVs = (BE_NCONST MDC::TexturCoord*)
((int8_t*)pcSurface+pcSurface->ulOffsetTexCoords);
BE_NCONST MDC::TexturCoord *const pcUVs = (BE_NCONST MDC::TexturCoord *)((int8_t *)pcSurface + pcSurface->ulOffsetTexCoords);
// get a pointer to the uncompressed vertices
int16_t iOfs = *((int16_t *)((int8_t *)pcSurface +
pcSurface->ulOffsetFrameBaseFrames) + this->configFrameID);
pcSurface->ulOffsetFrameBaseFrames) +
this->configFrameID);
AI_SWAP2(iOfs);
BE_NCONST MDC::BaseVertex* const pcVerts = (BE_NCONST MDC::BaseVertex*)
((int8_t*)pcSurface+pcSurface->ulOffsetBaseVerts) +
BE_NCONST MDC::BaseVertex *const pcVerts = (BE_NCONST MDC::BaseVertex *)((int8_t *)pcSurface + pcSurface->ulOffsetBaseVerts) +
((int)iOfs * pcSurface->ulNumVertices * 4);
// do the main swapping stuff ...
#if (defined AI_BUILD_BIG_ENDIAN)
// swap all triangles
for (unsigned int i = 0; i < pcSurface->ulNumTriangles;++i)
{
for (unsigned int i = 0; i < pcSurface->ulNumTriangles; ++i) {
AI_SWAP4(pcTriangle[i].aiIndices[0]);
AI_SWAP4(pcTriangle[i].aiIndices[1]);
AI_SWAP4(pcTriangle[i].aiIndices[2]);
}
// swap all vertices
for (unsigned int i = 0; i < pcSurface->ulNumVertices*pcSurface->ulNumBaseFrames;++i)
{
for (unsigned int i = 0; i < pcSurface->ulNumVertices * pcSurface->ulNumBaseFrames; ++i) {
AI_SWAP2(pcVerts->normal);
AI_SWAP2(pcVerts->x);
AI_SWAP2(pcVerts->y);
@ -353,8 +340,7 @@ void MDCImporter::InternReadFile(
}
// swap all texture coordinates
for (unsigned int i = 0; i < pcSurface->ulNumVertices;++i)
{
for (unsigned int i = 0; i < pcSurface->ulNumVertices; ++i) {
AI_SWAP4(pcUVs->u);
AI_SWAP4(pcUVs->v);
}
@ -365,44 +351,37 @@ void MDCImporter::InternReadFile(
int16_t *mdcCompVert = NULL;
// access compressed frames for large frame numbers, but never for the first
if( this->configFrameID && pcSurface->ulNumCompFrames > 0 )
{
if (this->configFrameID && pcSurface->ulNumCompFrames > 0) {
mdcCompVert = (int16_t *)((int8_t *)pcSurface + pcSurface->ulOffsetFrameCompFrames) + this->configFrameID;
AI_SWAP2P(mdcCompVert);
if( *mdcCompVert >= 0 )
{
if (*mdcCompVert >= 0) {
pcCVerts = (const MDC::CompressedVertex *)((int8_t *)pcSurface +
pcSurface->ulOffsetCompVerts) + *mdcCompVert * pcSurface->ulNumVertices;
}
else mdcCompVert = NULL;
pcSurface->ulOffsetCompVerts) +
*mdcCompVert * pcSurface->ulNumVertices;
} else
mdcCompVert = NULL;
}
// copy all faces
for (unsigned int iFace = 0; iFace < pcSurface->ulNumTriangles; ++iFace,
++pcTriangle,++pcFaceCur)
{
++pcTriangle, ++pcFaceCur) {
const unsigned int iOutIndex = iFace * 3;
pcFaceCur->mNumIndices = 3;
pcFaceCur->mIndices = new unsigned int[3];
for (unsigned int iIndex = 0; iIndex < 3; ++iIndex,
++pcVertCur,++pcUVCur,++pcNorCur)
{
++pcVertCur, ++pcUVCur, ++pcNorCur) {
uint32_t quak = pcTriangle->aiIndices[iIndex];
if (quak >= pcSurface->ulNumVertices)
{
if (quak >= pcSurface->ulNumVertices) {
ASSIMP_LOG_ERROR("MDC vertex index is out of range");
quak = pcSurface->ulNumVertices - 1;
}
// compressed vertices?
if (mdcCompVert)
{
if (mdcCompVert) {
MDC::BuildVertex(*pcFrame, pcVerts[quak], pcCVerts[quak],
*pcVertCur, *pcNorCur);
}
else
{
} else {
// copy position
pcVertCur->x = pcVerts[quak].x * AI_MDC_BASE_SCALING;
pcVertCur->y = pcVerts[quak].y * AI_MDC_BASE_SCALING;
@ -432,8 +411,7 @@ void MDCImporter::InternReadFile(
// create a flat node graph with a root node and one child for each surface
if (!pScene->mNumMeshes)
throw DeadlyImportError("Invalid MDC file: File contains no valid mesh");
else if (1 == pScene->mNumMeshes)
{
else if (1 == pScene->mNumMeshes) {
pScene->mRootNode = new aiNode();
if (nullptr != pScene->mMeshes[0]) {
pScene->mRootNode->mName = pScene->mMeshes[0]->mName;
@ -441,15 +419,12 @@ void MDCImporter::InternReadFile(
pScene->mRootNode->mMeshes = new unsigned int[1];
pScene->mRootNode->mMeshes[0] = 0;
}
}
else
{
} else {
pScene->mRootNode = new aiNode();
pScene->mRootNode->mNumChildren = pScene->mNumMeshes;
pScene->mRootNode->mChildren = new aiNode *[pScene->mNumMeshes];
pScene->mRootNode->mName.Set("<root>");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
{
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
aiNode *pcNode = pScene->mRootNode->mChildren[i] = new aiNode();
pcNode->mParent = pScene->mRootNode;
pcNode->mName = pScene->mMeshes[i]->mName;
@ -462,8 +437,7 @@ void MDCImporter::InternReadFile(
// create materials
pScene->mNumMaterials = (unsigned int)aszShaders.size();
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
{
for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
aiMaterial *pcMat = new aiMaterial();
pScene->mMaterials[i] = pcMat;
@ -477,14 +451,15 @@ void MDCImporter::InternReadFile(
clr.b = clr.g = clr.r = 0.05f;
pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
if (name.length())clr.b = clr.g = clr.r = 1.0f;
else clr.b = clr.g = clr.r = 0.6f;
if (name.length())
clr.b = clr.g = clr.r = 1.0f;
else
clr.b = clr.g = clr.r = 0.6f;
pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
pcMat->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
if (name.length())
{
if (name.length()) {
aiString path;
path.Set(name);
pcMat->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));

View File

@ -68,6 +68,10 @@ namespace Assimp {
namespace MDL {
namespace HalfLife {
#ifdef _WIN32
# pragma warning(disable : 4706)
#endif // _WIN32
// ------------------------------------------------------------------------------------------------
HL1MDLLoader::HL1MDLLoader(
aiScene *scene,
@ -817,25 +821,25 @@ void HL1MDLLoader::read_meshes() {
mesh_faces.reserve(num_faces);
if (is_triangle_fan) {
for (int i = 0; i < num_faces; ++i) {
for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) {
mesh_faces.push_back(HL1MeshFace{
tricmds[0],
tricmds[i + 1],
tricmds[i + 2] });
tricmds[faceIdx + 1],
tricmds[faceIdx + 2] });
}
} else {
for (int i = 0; i < num_faces; ++i) {
for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) {
if (i & 1) {
// Preserve winding order.
mesh_faces.push_back(HL1MeshFace{
tricmds[i + 1],
tricmds[i],
tricmds[i + 2] });
tricmds[faceIdx + 1],
tricmds[faceIdx],
tricmds[faceIdx + 2] });
} else {
mesh_faces.push_back(HL1MeshFace{
tricmds[i],
tricmds[i + 1],
tricmds[i + 2] });
tricmds[faceIdx],
tricmds[faceIdx + 1],
tricmds[faceIdx + 2] });
}
}
}
@ -1122,10 +1126,10 @@ void HL1MDLLoader::read_sequence_infos() {
aiNode *blend_controller_node = blend_controllers_node->mChildren[j] = new aiNode();
blend_controller_node->mParent = blend_controllers_node;
aiMetadata *md = blend_controller_node->mMetaData = aiMetadata::Alloc(3);
md->Set(0, "Start", pseqdesc->blendstart[j]);
md->Set(1, "End", pseqdesc->blendend[j]);
md->Set(2, "MotionFlags", pseqdesc->blendtype[j]);
aiMetadata *metaData = blend_controller_node->mMetaData = aiMetadata::Alloc(3);
metaData->Set(0, "Start", pseqdesc->blendstart[j]);
metaData->Set(1, "End", pseqdesc->blendend[j]);
metaData->Set(2, "MotionFlags", pseqdesc->blendtype[j]);
}
}
}
@ -1151,10 +1155,10 @@ void HL1MDLLoader::read_sequence_infos() {
aiNode *pEvent = pEventsNode->mChildren[j] = new aiNode();
pEvent->mParent = pEventsNode;
aiMetadata *md = pEvent->mMetaData = aiMetadata::Alloc(3);
md->Set(0, "Frame", pevent->frame);
md->Set(1, "ScriptEvent", pevent->event);
md->Set(2, "Options", aiString(pevent->options));
aiMetadata *metaData = pEvent->mMetaData = aiMetadata::Alloc(3);
metaData->Set(0, "Frame", pevent->frame);
metaData->Set(1, "ScriptEvent", pevent->event);
metaData->Set(2, "Options", aiString(pevent->options));
}
}

View File

@ -68,7 +68,7 @@ struct HL1MeshTrivert {
normindex(normindex),
s(s),
t(t),
localindex() {
localindex(localindex) {
}
HL1MeshTrivert(const Trivert &a) :

View File

@ -49,17 +49,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
#include "MDL/MDLLoader.h"
#include "MDL/MDLDefaultColorMap.h"
#include "MD2/MD2FileData.h"
#include "MDL/HalfLife/HL1MDLLoader.h"
#include "MDL/MDLDefaultColorMap.h"
#include <assimp/qnan.h>
#include <assimp/StringUtils.h>
#include <assimp/Importer.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/importerdesc.h>
#include <assimp/qnan.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h>
#include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp>
#include <memory>
@ -91,13 +91,8 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MDLImporter::MDLImporter()
: configFrameID()
, mBuffer()
, iGSFileVersion()
, pIOHandler()
, pScene()
, iFileSize() {
MDLImporter::MDLImporter() :
configFrameID(), mBuffer(), iGSFileVersion(), mIOHandler(nullptr), pScene(), iFileSize() {
// empty
}
@ -130,8 +125,7 @@ bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------
// Setup configuration properties
void MDLImporter::SetupProperties(const Importer* pImp)
{
void MDLImporter::SetupProperties(const Importer *pImp) {
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDL_KEYFRAME, -1);
// The
@ -159,22 +153,20 @@ void MDLImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Get a list of all supported extensions
const aiImporterDesc* MDLImporter::GetInfo () const
{
const aiImporterDesc *MDLImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void MDLImporter::InternReadFile(const std::string &pFile,
aiScene* _pScene, IOSystem* _pIOHandler)
{
aiScene *_pScene, IOSystem *pIOHandler) {
pScene = _pScene;
pIOHandler = _pIOHandler;
mIOHandler = pIOHandler;
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
// Check whether we can read from the file
if( file.get() == NULL) {
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDL file " + pFile + ".");
}
@ -191,7 +183,7 @@ void MDLImporter::InternReadFile( const std::string& pFile,
delete[] mBuffer;
mBuffer = nullptr;
}
AI_DEBUG_INVALIDATE_PTR(pIOHandler);
AI_DEBUG_INVALIDATE_PTR(mIOHandler);
AI_DEBUG_INVALIDATE_PTR(pScene);
};
@ -246,23 +238,18 @@ void MDLImporter::InternReadFile( const std::string& pFile,
}
// IDST/IDSQ Format (CS:S/HL^2, etc ...)
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
{
AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) {
iGSFileVersion = 0;
HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer;
if (pHeader->version == AI_MDL_HL1_VERSION)
{
if (pHeader->version == AI_MDL_HL1_VERSION) {
ASSIMP_LOG_DEBUG("MDL subtype: Half-Life 1/Goldsrc Engine, magic word is IDST/IDSQ");
InternReadFile_HL1(pFile, iMagicWord);
}
else
{
} else {
ASSIMP_LOG_DEBUG("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ");
InternReadFile_HL2();
}
}
else {
} else {
// print the magic word to the log file
throw DeadlyImportError("Unknown MDL subformat " + pFile +
". Magic word (" + std::string((char *)&iMagicWord, 4) + ") is not known");
@ -281,10 +268,8 @@ void MDLImporter::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------
// Check whether we're still inside the valid file range
void MDLImporter::SizeCheck(const void* szPos)
{
if (!szPos || (const unsigned char*)szPos > this->mBuffer + this->iFileSize)
{
void MDLImporter::SizeCheck(const void *szPos) {
if (!szPos || (const unsigned char *)szPos > this->mBuffer + this->iFileSize) {
throw DeadlyImportError("Invalid MDL file. The file is too small "
"or contains invalid data.");
}
@ -292,22 +277,25 @@ void MDLImporter::SizeCheck(const void* szPos)
// ------------------------------------------------------------------------------------------------
// Just for debugging purposes
void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int iLine)
{
void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int iLine) {
ai_assert(NULL != szFile);
if (!szPos || (const unsigned char*)szPos > mBuffer + iFileSize)
{
if (!szPos || (const unsigned char *)szPos > mBuffer + iFileSize) {
// remove a directory if there is one
const char *szFilePtr = ::strrchr(szFile, '\\');
if (!szFilePtr) {
if(!(szFilePtr = ::strrchr(szFile,'/')))
szFilePtr = ::strrchr(szFile, '/');
if (nullptr == szFilePtr) {
szFilePtr = szFile;
}
if (szFilePtr)++szFilePtr;
}
if (szFilePtr) {
++szFilePtr;
}
char szBuffer[1024];
::sprintf(szBuffer, "Invalid MDL file. The file is too small "
"or contains invalid data (File: %s Line: %u)",szFilePtr,iLine);
"or contains invalid data (File: %s Line: %u)",
szFilePtr, iLine);
throw DeadlyImportError(szBuffer);
}
@ -315,8 +303,7 @@ void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int
// ------------------------------------------------------------------------------------------------
// Validate a quake file header
void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
{
void MDLImporter::ValidateHeader_Quake1(const MDL::Header *pcHeader) {
// some values may not be NULL
if (!pcHeader->num_frames)
throw DeadlyImportError("[Quake 1 MDL] There are no frames in the file");
@ -328,8 +315,7 @@ void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
throw DeadlyImportError("[Quake 1 MDL] There are no triangles in the file");
// check whether the maxima are exceeded ...however, this applies for Quake 1 MDLs only
if (!this->iGSFileVersion)
{
if (!this->iGSFileVersion) {
if (pcHeader->num_verts > AI_MDL_MAX_VERTS)
ASSIMP_LOG_WARN("Quake 1 MDL model has more than AI_MDL_MAX_VERTS vertices");
@ -350,8 +336,7 @@ void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
#ifdef AI_BUILD_BIG_ENDIAN
// ------------------------------------------------------------------------------------------------
void FlipQuakeHeader(BE_NCONST MDL::Header* pcHeader)
{
void FlipQuakeHeader(BE_NCONST MDL::Header *pcHeader) {
AI_SWAP4(pcHeader->ident);
AI_SWAP4(pcHeader->version);
AI_SWAP4(pcHeader->boundingradius);
@ -360,8 +345,7 @@ void FlipQuakeHeader(BE_NCONST MDL::Header* pcHeader)
AI_SWAP4(pcHeader->num_skins);
AI_SWAP4(pcHeader->num_tris);
AI_SWAP4(pcHeader->num_verts);
for (unsigned int i = 0; i < 3;++i)
{
for (unsigned int i = 0; i < 3; ++i) {
AI_SWAP4(pcHeader->scale[i]);
AI_SWAP4(pcHeader->translate[i]);
}
@ -450,15 +434,13 @@ void MDLImporter::InternReadFile_Quake1() {
VALIDATE_FILE_SIZE((const unsigned char *)(pcVertices + pcHeader->num_verts));
#ifdef AI_BUILD_BIG_ENDIAN
for (int i = 0; i<pcHeader->num_verts;++i)
{
for (int i = 0; i < pcHeader->num_verts; ++i) {
AI_SWAP4(pcTexCoords[i].onseam);
AI_SWAP4(pcTexCoords[i].s);
AI_SWAP4(pcTexCoords[i].t);
}
for (int i = 0; i<pcHeader->num_tris;++i)
{
for (int i = 0; i < pcHeader->num_tris; ++i) {
AI_SWAP4(pcTriangles[i].facesfront);
AI_SWAP4(pcTriangles[i].vertex[0]);
AI_SWAP4(pcTriangles[i].vertex[1]);
@ -492,20 +474,17 @@ void MDLImporter::InternReadFile_Quake1() {
// now iterate through all triangles
unsigned int iCurrent = 0;
for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i)
{
for (unsigned int i = 0; i < (unsigned int)pcHeader->num_tris; ++i) {
pcMesh->mFaces[i].mIndices = new unsigned int[3];
pcMesh->mFaces[i].mNumIndices = 3;
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent)
{
for (unsigned int c = 0; c < 3; ++c, ++iCurrent) {
pcMesh->mFaces[i].mIndices[c] = iCurrent;
// read vertices
unsigned int iIndex = pcTriangles->vertex[c];
if (iIndex >= (unsigned int)pcHeader->num_verts)
{
if (iIndex >= (unsigned int)pcHeader->num_verts) {
iIndex = pcHeader->num_verts - 1;
ASSIMP_LOG_WARN("Index overflow in Q1-MDL vertex list.");
}
@ -537,7 +516,6 @@ void MDLImporter::InternReadFile_Quake1() {
// Scale s and t to range from 0.0 to 1.0
pcMesh->mTextureCoords[0][iCurrent].x = (s + 0.5f) / pcHeader->skinwidth;
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - (t + 0.5f) / pcHeader->skinheight;
}
pcMesh->mFaces[i].mIndices[0] = iTemp + 2;
pcMesh->mFaces[i].mIndices[1] = iTemp + 1;
@ -549,8 +527,7 @@ void MDLImporter::InternReadFile_Quake1() {
// ------------------------------------------------------------------------------------------------
// Setup material properties for Quake and older GameStudio files
void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
{
void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1() {
const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer;
// allocate ONE material
@ -573,8 +550,7 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
pScene->mTextures = NULL;
pScene->mNumTextures = 0;
}
else {
} else {
clr.b = clr.a = clr.g = clr.r = 1.0f;
aiString szString;
::memcpy(szString.data, AI_MAKE_EMBEDDED_TEXNAME(0), 3);
@ -586,15 +562,16 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
pcHelper->AddProperty<aiColor4D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
pcHelper->AddProperty<aiColor4D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
clr.r *= 0.05f;clr.g *= 0.05f;
clr.b *= 0.05f;clr.a = 1.0f;
clr.r *= 0.05f;
clr.g *= 0.05f;
clr.b *= 0.05f;
clr.a = 1.0f;
pcHelper->AddProperty<aiColor4D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
}
// ------------------------------------------------------------------------------------------------
// Read a MDL 3,4,5 file
void MDLImporter::InternReadFile_3DGS_MDL345( )
{
void MDLImporter::InternReadFile_3DGS_MDL345() {
ai_assert(NULL != pScene);
// the header of MDL 3/4/5 is nearly identical to the original Quake1 header
@ -618,19 +595,16 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
AI_SWAP4(pcSkin->group);
// create one output image
unsigned int iSkip = i ? UINT_MAX : 0;
if (5 <= iGSFileVersion)
{
if (5 <= iGSFileVersion) {
// MDL5 format could contain MIPmaps
CreateTexture_3DGS_MDL5((unsigned char *)pcSkin + sizeof(uint32_t),
pcSkin->group, &iSkip);
}
else {
} else {
CreateTexture_3DGS_MDL4((unsigned char *)pcSkin + sizeof(uint32_t),
pcSkin->group, &iSkip);
}
// need to skip one image
szCurrent += iSkip + sizeof(uint32_t);
}
// get a pointer to the texture coordinates
BE_NCONST MDL::TexCoord_MDL3 *pcTexCoords = (BE_NCONST MDL::TexCoord_MDL3 *)szCurrent;
@ -816,8 +790,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
aiVector3D &vOut,
const MDL::TexCoord_MDL3 *pcSrc,
unsigned int iIndex)
{
unsigned int iIndex) {
ai_assert(NULL != pcSrc);
const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer;
@ -843,8 +816,7 @@ void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
// ------------------------------------------------------------------------------------------------
// Compute UV coordinates for a MDL5 file
void MDLImporter::CalculateUVCoordinates_MDL5()
{
void MDLImporter::CalculateUVCoordinates_MDL5() {
const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer;
if (pcHeader->num_skins && this->pScene->mNumTextures) {
const aiTexture *pcTex = this->pScene->mTextures[0];
@ -859,8 +831,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
piPtr += 3;
iHeight = (unsigned int)*piPtr++;
iWidth = (unsigned int)*piPtr;
if (!iHeight || !iWidth)
{
if (!iHeight || !iWidth) {
ASSIMP_LOG_WARN("Either the width or the height of the "
"embedded DDS texture is zero. Unable to compute final texture "
"coordinates. The texture coordinates remain in their original "
@ -868,8 +839,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
iWidth = 1;
iHeight = 1;
}
}
else {
} else {
iWidth = pcTex->mWidth;
iHeight = pcTex->mHeight;
}
@ -878,8 +848,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
const float fWidth = (float)iWidth;
const float fHeight = (float)iHeight;
aiMesh *pcMesh = this->pScene->mMeshes[0];
for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
{
for (unsigned int i = 0; i < pcMesh->mNumVertices; ++i) {
pcMesh->mTextureCoords[0][i].x /= fWidth;
pcMesh->mTextureCoords[0][i].y /= fHeight;
pcMesh->mTextureCoords[0][i].y = 1.0f - pcMesh->mTextureCoords[0][i].y; // DX to OGL
@ -890,8 +859,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
// ------------------------------------------------------------------------------------------------
// Validate the header of a MDL7 file
void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader)
{
void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7 *pcHeader) {
ai_assert(NULL != pcHeader);
// There are some fixed sizes ...
@ -916,8 +884,7 @@ void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader)
// ------------------------------------------------------------------------------------------------
// resolve bone animation matrices
void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
{
void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7 **apcOutBones) {
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
const MDL::Bone_MDL7 *pcBones = (const MDL::Bone_MDL7 *)(pcHeader + 1);
ai_assert(NULL != apcOutBones);
@ -979,8 +946,7 @@ void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
// no real name for our poor bone is specified :-(
pcOutBone->mName.length = ai_snprintf(pcOutBone->mName.data, MAXLEN,
"UnnamedBone_%i", iBone);
}
else {
} else {
// Make sure we won't run over the buffer's end if there is no
// terminal 0 character (however the documentation says there
// should be one)
@ -1005,15 +971,13 @@ void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
// ------------------------------------------------------------------------------------------------
// read bones from a MDL7 file
MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
{
MDL::IntBone_MDL7 **MDLImporter::LoadBones_3DGS_MDL7() {
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
if (pcHeader->bones_num) {
// validate the size of the bone data structure in the file
if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS != pcHeader->bone_stc_size &&
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size &&
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size)
{
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size) {
ASSIMP_LOG_WARN("Unknown size of bone data structure");
return NULL;
}
@ -1032,8 +996,7 @@ MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
// ------------------------------------------------------------------------------------------------
// read faces from a MDL7 file
void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7 &groupInfo,
MDL::IntGroupData_MDL7& groupData)
{
MDL::IntGroupData_MDL7 &groupData) {
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
MDL::Triangle_MDL7 *pcGroupTris = groupInfo.pcGroupTris;
@ -1051,7 +1014,7 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
unsigned int iIndex = pcGroupTris->v_index[c];
if (iIndex > (unsigned int)groupInfo.pcGroup->numverts) {
// (we might need to read this section a second time - to process frame vertices correctly)
pcGroupTris->v_index[c] = iIndex = groupInfo.pcGroup->numverts-1;
pcGroupTris->v_index[c] = (uint16_t) (iIndex = groupInfo.pcGroup->numverts - 1 );
ASSIMP_LOG_WARN("Index overflow in MDL7 vertex list");
}
@ -1066,7 +1029,8 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
// if we have bones, save the index
if (!groupData.aiBones.empty()) {
groupData.aiBones[iOutIndex] = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,
iIndex,pcHeader->mainvertex_stc_size).vertindex;
iIndex, pcHeader->mainvertex_stc_size)
.vertindex;
}
// now read the normal vector
@ -1079,12 +1043,13 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
AI_SWAP4(vNormal.y);
vNormal.z = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts, iIndex, pcHeader->mainvertex_stc_size).norm[2];
AI_SWAP4(vNormal.z);
}
else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
} else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
// read the normal vector from Quake2's smart table
aiVector3D &vNormal = groupData.vNormals[iOutIndex];
MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts, iIndex,
pcHeader->mainvertex_stc_size) .norm162index,vNormal);
pcHeader->mainvertex_stc_size)
.norm162index,
vNormal);
}
// validate and process the first uv coordinate set
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV) {
@ -1158,8 +1123,7 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
MDL::IntGroupData_MDL7 &groupData,
MDL::IntSharedData_MDL7 &shared,
const unsigned char *szCurrent,
const unsigned char** szCurrentOut)
{
const unsigned char **szCurrentOut) {
ai_assert(nullptr != szCurrent);
ai_assert(nullptr != szCurrentOut);
@ -1219,11 +1183,12 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
AI_SWAP4(vNormal.y);
vNormal.z = _AI_MDL7_ACCESS_VERT(pcFrameVertices, qq, pcHeader->framevertex_stc_size).norm[2];
AI_SWAP4(vNormal.z);
}
else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
} else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
// read the normal vector from Quake2's smart table
MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(pcFrameVertices, qq,
pcHeader->framevertex_stc_size) .norm162index,vNormal);
pcHeader->framevertex_stc_size)
.norm162index,
vNormal);
}
// FIXME: O(n^2) at the moment ...
@ -1241,7 +1206,8 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
}
// get the next triangle in the list
pcGroupTris = (BE_NCONST MDL::Triangle_MDL7 *)((const char *)
pcGroupTris + pcHeader->triangle_stc_size);
pcGroupTris +
pcHeader->triangle_stc_size);
}
}
}
@ -1260,8 +1226,7 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
void MDLImporter::SortByMaterials_3DGS_MDL7(
const MDL::IntGroupInfo_MDL7 &groupInfo,
MDL::IntGroupData_MDL7 &groupData,
MDL::IntSplitGroupData_MDL7& splitGroupData)
{
MDL::IntSplitGroupData_MDL7 &splitGroupData) {
const unsigned int iNumMaterials = (unsigned int)splitGroupData.shared.pcMats.size();
if (!groupData.bNeed2UV) {
// if we don't need a second set of texture coordinates there is no reason to keep it in memory ...
@ -1284,13 +1249,10 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
// one skin assigned. No warning in this case
if (0xFFFFFFFF != groupData.pcFaces[iFace].iMatIndex[0])
ASSIMP_LOG_WARN("Index overflow in MDL7 material list [#0]");
} else
splitGroupData.aiSplit[groupData.pcFaces[iFace].iMatIndex[0]]->push_back(iFace);
}
else splitGroupData.aiSplit[groupData.pcFaces[iFace].
iMatIndex[0]]->push_back(iFace);
}
}
else
{
} else {
// we need to build combined materials for each combination of
std::vector<MDL::IntMaterial_MDL7> avMats;
avMats.reserve(iNumMaterials * 2);
@ -1358,8 +1320,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
splitGroupData.shared.pcMats.resize(avMats.size());
for (unsigned int o = 0; o < avMats.size(); ++o)
splitGroupData.shared.pcMats[o] = avMats[o].pcMat;
}
else {
} else {
// This might result in redundant materials ...
splitGroupData.shared.pcMats.resize(iNumMaterials + avMats.size());
for (unsigned int o = iNumMaterials; o < avMats.size(); ++o)
@ -1375,8 +1336,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
// ------------------------------------------------------------------------------------------------
// Read a MDL7 file
void MDLImporter::InternReadFile_3DGS_MDL7( )
{
void MDLImporter::InternReadFile_3DGS_MDL7() {
ai_assert(NULL != pScene);
MDL::IntSharedData_MDL7 sharedData;
@ -1454,7 +1414,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
// read all skins
sharedData.pcMats.reserve(sharedData.pcMats.size() + groupInfo.pcGroup->numskins);
sharedData.abNeedMaterials.resize(sharedData.abNeedMaterials.size() +
groupInfo.pcGroup->numskins,false);
groupInfo.pcGroup->numskins,
false);
for (unsigned int iSkin = 0; iSkin < (unsigned int)groupInfo.pcGroup->numskins; ++iSkin) {
ParseSkinLump_3DGS_MDL7(szCurrent, &szCurrent, sharedData.pcMats);
@ -1508,8 +1469,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
MDL::IntSplitGroupData_MDL7 splitGroupData(sharedData, avOutList[iGroup]);
MDL::IntGroupData_MDL7 groupData;
if (groupInfo.pcGroup->numtris && groupInfo.pcGroup->numverts)
{
if (groupInfo.pcGroup->numtris && groupInfo.pcGroup->numverts) {
// build output vectors
const unsigned int iNumVertices = groupInfo.pcGroup->numtris * 3;
groupData.vPositions.resize(iNumVertices);
@ -1541,8 +1501,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
if (!splitGroupData.aiSplit[qq]->empty())
sharedData.abNeedMaterials[qq] = true;
}
}
else ASSIMP_LOG_WARN("[3DGS MDL7] Mesh group consists of 0 "
} else
ASSIMP_LOG_WARN("[3DGS MDL7] Mesh group consists of 0 "
"vertices or faces. It will be skipped.");
// process all frames and generate output meshes
@ -1557,7 +1517,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
for (uint32_t i = 0; i < pcHeader->groups_num; ++i)
pScene->mNumMeshes += (unsigned int)avOutList[i].size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; {
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
{
unsigned int p = 0, q = 0;
for (uint32_t i = 0; i < pcHeader->groups_num; ++i) {
for (unsigned int a = 0; a < avOutList[i].size(); ++a) {
@ -1600,8 +1561,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
pcOldRoot->mChildren[0] = NULL;
delete pcOldRoot;
pScene->mRootNode->mParent = NULL;
}
else pScene->mRootNode->mName.Set("<mesh_root>");
} else
pScene->mRootNode->mName.Set("<mesh_root>");
delete[] avOutList;
delete[] aszGroupNameBuffer;
@ -1622,7 +1583,8 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
// add bones to the nodegraph
AddBonesToNodeGraph_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
sharedData.apcOutBones,pc,0xffff);
sharedData.apcOutBones,
pc, 0xffff);
// this steps build a valid output animation
BuildOutputAnims_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
@ -1632,19 +1594,16 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
// ------------------------------------------------------------------------------------------------
// Copy materials
void MDLImporter::CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared)
{
void MDLImporter::CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared) {
pScene->mNumMaterials = (unsigned int)shared.pcMats.size();
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
for (unsigned int i = 0; i < pScene->mNumMaterials; ++i)
pScene->mMaterials[i] = shared.pcMats[i];
}
// ------------------------------------------------------------------------------------------------
// Process material references
void MDLImporter::HandleMaterialReferences_3DGS_MDL7()
{
void MDLImporter::HandleMaterialReferences_3DGS_MDL7() {
// search for referrer materials
for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
int iIndex = 0;
@ -1675,16 +1634,14 @@ void MDLImporter::HandleMaterialReferences_3DGS_MDL7()
void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
const MDL::IntGroupInfo_MDL7 &groupInfo,
IntFrameInfo_MDL7 &frame,
MDL::IntSharedData_MDL7& shared)
{
MDL::IntSharedData_MDL7 &shared) {
const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
// only the first group contains bone animation keys
if (frame.pcFrame->transmatrix_count) {
if (!groupInfo.iIndex) {
// skip all frames vertices. We can't support them
const MDL::BoneTransform_MDL7* pcBoneTransforms = (const MDL::BoneTransform_MDL7*)
(((const char*)frame.pcFrame) + pcHeader->frame_stc_size +
const MDL::BoneTransform_MDL7 *pcBoneTransforms = (const MDL::BoneTransform_MDL7 *)(((const char *)frame.pcFrame) + pcHeader->frame_stc_size +
frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size);
// read all transformation matrices
@ -1692,16 +1649,13 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
if (pcBoneTransforms->bone_index >= pcHeader->bones_num) {
ASSIMP_LOG_WARN("Index overflow in frame area. "
"Unable to parse this bone transformation");
}
else {
} else {
AddAnimationBoneTrafoKey_3DGS_MDL7(frame.iIndex,
pcBoneTransforms, shared.apcOutBones);
}
pcBoneTransforms = (const MDL::BoneTransform_MDL7*)(
(const char*)pcBoneTransforms + pcHeader->bonetrans_stc_size);
pcBoneTransforms = (const MDL::BoneTransform_MDL7 *)((const char *)pcBoneTransforms + pcHeader->bonetrans_stc_size);
}
}
else {
} else {
ASSIMP_LOG_WARN("Ignoring animation keyframes in groups != 0");
}
}
@ -1710,8 +1664,7 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
// ------------------------------------------------------------------------------------------------
// Attach bones to the output nodegraph
void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7 **apcBones,
aiNode* pcParent,uint16_t iParentIndex)
{
aiNode *pcParent, uint16_t iParentIndex) {
ai_assert(NULL != apcBones && NULL != pcParent);
// get a pointer to the header ...
@ -1742,8 +1695,7 @@ void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBon
// ------------------------------------------------------------------------------------------------
// Build output animations
void MDLImporter::BuildOutputAnims_3DGS_MDL7(
const MDL::IntBone_MDL7** apcBonesOut)
{
const MDL::IntBone_MDL7 **apcBonesOut) {
ai_assert(NULL != apcBonesOut);
const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)mBuffer;
@ -1755,7 +1707,9 @@ void MDLImporter::BuildOutputAnims_3DGS_MDL7(
// get the last frame ... (needn't be equal to pcHeader->frames_num)
for (size_t qq = 0; qq < apcBonesOut[i]->pkeyPositions.size(); ++qq) {
pcAnim->mDuration = std::max(pcAnim->mDuration, (double)
apcBonesOut[i]->pkeyPositions[qq].mTime);
apcBonesOut[i]
->pkeyPositions[qq]
.mTime);
}
++pcAnim->mNumChannels;
}
@ -1793,15 +1747,14 @@ void MDLImporter::BuildOutputAnims_3DGS_MDL7(
pScene->mNumAnimations = 1;
pScene->mAnimations = new aiAnimation *[1];
pScene->mAnimations[0] = pcAnim;
}
else delete pcAnim;
} else
delete pcAnim;
}
// ------------------------------------------------------------------------------------------------
void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
const MDL::BoneTransform_MDL7 *pcBoneTransforms,
MDL::IntBone_MDL7** apcBonesOut)
{
MDL::IntBone_MDL7 **apcBonesOut) {
ai_assert(NULL != pcBoneTransforms);
ai_assert(NULL != apcBonesOut);
@ -1844,8 +1797,7 @@ void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
// Construct output meshes
void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
MDL::IntGroupData_MDL7 &groupData,
MDL::IntSplitGroupData_MDL7& splitGroupData)
{
MDL::IntSplitGroupData_MDL7 &splitGroupData) {
const MDL::IntSharedData_MDL7 &shared = splitGroupData.shared;
// get a pointer to the header ...
@ -1910,7 +1862,7 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
std::vector<std::vector<unsigned int>> aaiVWeightList;
aaiVWeightList.resize(iNumOutBones);
int iCurrent = 0;
int iCurrentWeight = 0;
for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces; ++iFace) {
unsigned int iSrcFace = splitGroupData.aiSplit[i]->operator[](iFace);
const MDL::IntFace_MDL7 &oldFace = groupData.pcFaces[iSrcFace];
@ -1924,9 +1876,9 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
"The bone index of a vertex exceeds the allowed range. ");
iBone = iNumOutBones - 1;
}
aaiVWeightList[ iBone ].push_back ( iCurrent );
aaiVWeightList[iBone].push_back(iCurrentWeight);
}
++iCurrent;
++iCurrentWeight;
}
}
// now check which bones are required ...
@ -1937,8 +1889,7 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
}
pcMesh->mBones = new aiBone *[pcMesh->mNumBones];
iCurrent = 0;
for (std::vector<std::vector<unsigned int> >::const_iterator k = aaiVWeightList.begin();k!= aaiVWeightList.end();++k,++iCurrent)
{
for (std::vector<std::vector<unsigned int>>::const_iterator k = aaiVWeightList.begin(); k != aaiVWeightList.end(); ++k, ++iCurrent) {
if ((*k).empty())
continue;
@ -1968,8 +1919,7 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
void MDLImporter::JoinSkins_3DGS_MDL7(
aiMaterial *pcMat1,
aiMaterial *pcMat2,
aiMaterial* pcMatOut)
{
aiMaterial *pcMatOut) {
ai_assert(NULL != pcMat1 && NULL != pcMat2 && NULL != pcMatOut);
// first create a full copy of the first skin property set
@ -1991,8 +1941,7 @@ void MDLImporter::JoinSkins_3DGS_MDL7(
// ------------------------------------------------------------------------------------------------
// Read a Half-life 1 MDL
void MDLImporter::InternReadFile_HL1(const std::string& pFile, const uint32_t iMagicWord)
{
void MDLImporter::InternReadFile_HL1(const std::string &pFile, const uint32_t iMagicWord) {
// We can't correctly load an MDL from a MDL "sequence" file.
if (iMagicWord == AI_MDL_MAGIC_NUMBER_BE_HL2b || iMagicWord == AI_MDL_MAGIC_NUMBER_LE_HL2b)
throw DeadlyImportError("Impossible to properly load a model from an MDL sequence file.");
@ -2000,7 +1949,7 @@ void MDLImporter::InternReadFile_HL1(const std::string& pFile, const uint32_t iM
// Read the MDL file.
HalfLife::HL1MDLLoader loader(
pScene,
pIOHandler,
mIOHandler,
mBuffer,
pFile,
mHL1ImportSettings);
@ -2008,8 +1957,7 @@ void MDLImporter::InternReadFile_HL1(const std::string& pFile, const uint32_t iM
// ------------------------------------------------------------------------------------------------
// Read a half-life 2 MDL
void MDLImporter::InternReadFile_HL2( )
{
void MDLImporter::InternReadFile_HL2() {
//const MDL::Header_HL2* pcHeader = (const MDL::Header_HL2*)this->mBuffer;
throw DeadlyImportError("HL2 MDLs are not implemented");
}

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -58,7 +57,6 @@ struct aiTexture;
namespace Assimp {
using namespace MDL;
// --------------------------------------------------------------------------------------
@ -436,7 +434,7 @@ protected:
unsigned int iGSFileVersion;
/** Output I/O handler. used to load external lmp files */
IOSystem* pIOHandler;
IOSystem* mIOHandler;
/** Output scene to be filled */
aiScene* pScene;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -43,38 +41,34 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the material part of the MDL importer class */
#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
// internal headers
#include "MDLLoader.h"
#include "MDLDefaultColorMap.h"
#include <assimp/StringUtils.h>
#include <assimp/texture.h>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include "MDLLoader.h"
#include <assimp/Defines.h>
#include <assimp/StringUtils.h>
#include <assimp/qnan.h>
#include <assimp/scene.h>
#include <assimp/texture.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory>
using namespace Assimp;
static aiTexel *const bad_texel = reinterpret_cast<aiTexel *>(SIZE_MAX);
// ------------------------------------------------------------------------------------------------
// Find a suitable palette file or take the default one
void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
{
void MDLImporter::SearchPalette(const unsigned char **pszColorMap) {
// now try to find the color map in the current directory
IOStream* pcStream = pIOHandler->Open(configPalette,"rb");
IOStream *pcStream = mIOHandler->Open(configPalette, "rb");
const unsigned char *szColorMap = (const unsigned char *)::g_aclrDefaultColorMap;
if(pcStream)
{
if (pcStream->FileSize() >= 768)
{
if (pcStream) {
if (pcStream->FileSize() >= 768) {
size_t len = 256 * 3;
unsigned char *colorMap = new unsigned char[len];
szColorMap = colorMap;
@ -83,24 +77,23 @@ void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
"It will be used to decode embedded textures in palletized formats.");
}
delete pcStream;
pcStream = NULL;
pcStream = nullptr;
}
*pszColorMap = szColorMap;
}
// ------------------------------------------------------------------------------------------------
// Free the palette again
void MDLImporter::FreePalette(const unsigned char* szColorMap)
{
if (szColorMap != (const unsigned char*)::g_aclrDefaultColorMap)
void MDLImporter::FreePalette(const unsigned char *szColorMap) {
if (szColorMap != (const unsigned char *)::g_aclrDefaultColorMap) {
delete[] szColorMap;
}
}
// ------------------------------------------------------------------------------------------------
// Check whether we can replace a texture with a single color
aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
{
ai_assert(NULL != pcTexture);
aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture *pcTexture) {
ai_assert(nullptr != pcTexture);
aiColor4D clrOut;
clrOut.r = get_qnan();
@ -111,17 +104,14 @@ aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
const aiTexel *pcTexel = pcTexture->pcData + 1;
const aiTexel *const pcTexelEnd = &pcTexture->pcData[iNumPixels];
while (pcTexel != pcTexelEnd)
{
if (*pcTexel != *(pcTexel-1))
{
pcTexel = NULL;
while (pcTexel != pcTexelEnd) {
if (*pcTexel != *(pcTexel - 1)) {
pcTexel = nullptr;
break;
}
++pcTexel;
}
if (pcTexel)
{
if (pcTexel) {
clrOut.r = pcTexture->pcData->r / 255.0f;
clrOut.g = pcTexture->pcData->g / 255.0f;
clrOut.b = pcTexture->pcData->b / 255.0f;
@ -132,8 +122,7 @@ aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
// ------------------------------------------------------------------------------------------------
// Read a texture from a MDL3 file
void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
{
void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char *szData) {
const MDL::Header *pcHeader = (const MDL::Header *)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function
VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
@ -150,8 +139,7 @@ void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
this->SearchPalette(&szColorMap);
// copy texture data
for (unsigned int i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
{
for (unsigned int i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
const unsigned char val = szData[i];
const unsigned char *sz = &szColorMap[val * 3];
@ -172,21 +160,18 @@ void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
pScene->mTextures[this->pScene->mNumTextures] = pcNew;
pScene->mNumTextures++;
delete[] pc;
return;
}
// ------------------------------------------------------------------------------------------------
// Read a texture from a MDL4 file
void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char *szData,
unsigned int iType,
unsigned int* piSkip)
{
ai_assert(NULL != piSkip);
unsigned int *piSkip) {
ai_assert(nullptr != piSkip);
const MDL::Header *pcHeader = (const MDL::Header *)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function
if (iType == 1 || iType > 3)
{
if (iType == 1 || iType > 3) {
ASSIMP_LOG_ERROR("Unsupported texture file format");
return;
}
@ -202,16 +187,12 @@ void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
ParseTextureColorData(szData, iType, piSkip, pcNew);
// store the texture
if (!bNoRead)
{
if (!this->pScene->mNumTextures)
{
if (!bNoRead) {
if (!this->pScene->mNumTextures) {
pScene->mNumTextures = 1;
pScene->mTextures = new aiTexture *[1];
pScene->mTextures[0] = pcNew;
}
else
{
} else {
aiTexture **pc = pScene->mTextures;
pScene->mTextures = new aiTexture *[pScene->mNumTextures + 1];
for (unsigned int i = 0; i < this->pScene->mNumTextures; ++i)
@ -220,9 +201,8 @@ void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
pScene->mNumTextures++;
delete[] pc;
}
}
else {
pcNew->pcData = NULL;
} else {
pcNew->pcData = nullptr;
delete pcNew;
}
return;
@ -233,8 +213,7 @@ void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
void MDLImporter::ParseTextureColorData(const unsigned char *szData,
unsigned int iType,
unsigned int *piSkip,
aiTexture* pcNew)
{
aiTexture *pcNew) {
const bool do_read = bad_texel != pcNew->pcData;
// allocate storage for the texture image
@ -244,16 +223,13 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
// R5G6B5 format (with or without MIPs)
// ****************************************************************
if (2 == iType || 10 == iType)
{
if (2 == iType || 10 == iType) {
VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 2);
// copy texture data
unsigned int i;
if (do_read)
{
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
{
if (do_read) {
for (i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
MDL::RGB565 val = ((MDL::RGB565 *)szData)[i];
AI_SWAP2(val);
@ -262,29 +238,26 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
pcNew->pcData[i].g = (unsigned char)val.g << 2;
pcNew->pcData[i].b = (unsigned char)val.r << 3;
}
} else {
i = pcNew->mWidth * pcNew->mHeight;
}
else i = pcNew->mWidth*pcNew->mHeight;
*piSkip = i * 2;
// apply MIP maps
if (10 == iType)
{
if (10 == iType) {
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
VALIDATE_FILE_SIZE(szData + *piSkip);
}
}
// ARGB4 format (with or without MIPs)
// ****************************************************************
else if (3 == iType || 11 == iType)
{
else if (3 == iType || 11 == iType) {
VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 4);
// copy texture data
unsigned int i;
if (do_read)
{
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
{
if (do_read) {
for (i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
MDL::ARGB4 val = ((MDL::ARGB4 *)szData)[i];
AI_SWAP2(val);
@ -293,29 +266,25 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
pcNew->pcData[i].g = (unsigned char)val.g << 4;
pcNew->pcData[i].b = (unsigned char)val.b << 4;
}
}
else i = pcNew->mWidth*pcNew->mHeight;
} else
i = pcNew->mWidth * pcNew->mHeight;
*piSkip = i * 2;
// apply MIP maps
if (11 == iType)
{
if (11 == iType) {
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
VALIDATE_FILE_SIZE(szData + *piSkip);
}
}
// RGB8 format (with or without MIPs)
// ****************************************************************
else if (4 == iType || 12 == iType)
{
else if (4 == iType || 12 == iType) {
VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 3);
// copy texture data
unsigned int i;
if (do_read)
{
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
{
if (do_read) {
for (i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
const unsigned char *_szData = &szData[i * 3];
pcNew->pcData[i].a = 0xFF;
@ -323,30 +292,25 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
pcNew->pcData[i].g = *_szData++;
pcNew->pcData[i].r = *_szData;
}
}
else i = pcNew->mWidth*pcNew->mHeight;
} else
i = pcNew->mWidth * pcNew->mHeight;
// apply MIP maps
*piSkip = i * 3;
if (12 == iType)
{
if (12 == iType) {
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) * 3;
VALIDATE_FILE_SIZE(szData + *piSkip);
}
}
// ARGB8 format (with ir without MIPs)
// ****************************************************************
else if (5 == iType || 13 == iType)
{
else if (5 == iType || 13 == iType) {
VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight * 4);
// copy texture data
unsigned int i;
if (do_read)
{
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
{
if (do_read) {
for (i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
const unsigned char *_szData = &szData[i * 4];
pcNew->pcData[i].b = *_szData++;
@ -354,32 +318,29 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
pcNew->pcData[i].r = *_szData++;
pcNew->pcData[i].a = *_szData;
}
} else {
i = pcNew->mWidth * pcNew->mHeight;
}
else i = pcNew->mWidth*pcNew->mHeight;
// apply MIP maps
*piSkip = i << 2;
if (13 == iType)
{
if (13 == iType) {
*piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2;
}
}
// palletized 8 bit texture. As for Quake 1
// ****************************************************************
else if (0 == iType)
{
else if (0 == iType) {
VALIDATE_FILE_SIZE(szData + pcNew->mWidth * pcNew->mHeight);
// copy texture data
unsigned int i;
if (do_read)
{
if (do_read) {
const unsigned char *szColorMap;
SearchPalette(&szColorMap);
for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
{
for (i = 0; i < pcNew->mWidth * pcNew->mHeight; ++i) {
const unsigned char val = szData[i];
const unsigned char *sz = &szColorMap[val * 3];
@ -390,8 +351,8 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
}
this->FreePalette(szColorMap);
}
else i = pcNew->mWidth*pcNew->mHeight;
} else
i = pcNew->mWidth * pcNew->mHeight;
*piSkip = i;
// FIXME: Also support for MIP maps?
@ -402,8 +363,7 @@ void MDLImporter::ParseTextureColorData(const unsigned char* szData,
// Get a texture from a MDL5 file
void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char *szData,
unsigned int iType,
unsigned int* piSkip)
{
unsigned int *piSkip) {
ai_assert(NULL != piSkip);
bool bNoRead = *piSkip == UINT_MAX;
@ -429,14 +389,12 @@ void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
// however, one can easily try out what MED does if you have
// a model with a DDS texture and export it to MDL5 ...
// yeah, it embedds the DDS file.
if (6 == iType)
{
if (6 == iType) {
// this is a compressed texture in DDS format
*piSkip = pcNew->mWidth;
VALIDATE_FILE_SIZE(szData + *piSkip);
if (!bNoRead)
{
if (!bNoRead) {
// place a hint and let the application know that this is a DDS file
pcNew->mHeight = 0;
pcNew->achFormatHint[0] = 'd';
@ -447,25 +405,19 @@ void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
pcNew->pcData = (aiTexel *)new unsigned char[pcNew->mWidth];
::memcpy(pcNew->pcData, szData, pcNew->mWidth);
}
}
else
{
} else {
// parse the color data of the texture
ParseTextureColorData(szData, iType, piSkip, pcNew);
}
*piSkip += sizeof(uint32_t) * 2;
if (!bNoRead)
{
if (!bNoRead) {
// store the texture
if (!this->pScene->mNumTextures)
{
if (!this->pScene->mNumTextures) {
pScene->mNumTextures = 1;
pScene->mTextures = new aiTexture *[1];
pScene->mTextures[0] = pcNew;
}
else
{
} else {
aiTexture **pc = pScene->mTextures;
pScene->mTextures = new aiTexture *[pScene->mNumTextures + 1];
for (unsigned int i = 0; i < pScene->mNumTextures; ++i)
@ -475,8 +427,7 @@ void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
pScene->mNumTextures++;
delete[] pc;
}
}
else {
} else {
pcNew->pcData = NULL;
delete pcNew;
}
@ -491,24 +442,19 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
aiMaterial *pcMatOut,
unsigned int iType,
unsigned int iWidth,
unsigned int iHeight)
{
unsigned int iHeight) {
std::unique_ptr<aiTexture> pcNew;
// get the type of the skin
unsigned int iMasked = (unsigned int)(iType & 0xF);
if (0x1 == iMasked)
{
if (0x1 == iMasked) {
// ***** REFERENCE TO ANOTHER SKIN INDEX *****
int referrer = (int)iWidth;
pcMatOut->AddProperty<int>(&referrer, 1, AI_MDL7_REFERRER_MATERIAL);
}
else if (0x6 == iMasked)
{
} else if (0x6 == iMasked) {
// ***** EMBEDDED DDS FILE *****
if (1 != iHeight)
{
if (1 != iHeight) {
ASSIMP_LOG_WARN("Found a reference to an embedded DDS texture, "
"but texture height is not equal to 1, which is not supported by MED");
}
@ -526,12 +472,9 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
pcNew->pcData = (aiTexel *)new unsigned char[pcNew->mWidth];
memcpy(pcNew->pcData, szCurrent, pcNew->mWidth);
szCurrent += iWidth;
}
else if (0x7 == iMasked)
{
} else if (0x7 == iMasked) {
// ***** REFERENCE TO EXTERNAL FILE *****
if (1 != iHeight)
{
if (1 != iHeight) {
ASSIMP_LOG_WARN("Found a reference to an external texture, "
"but texture height is not equal to 1, which is not supported by MED");
}
@ -547,22 +490,17 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// place this as diffuse texture
pcMatOut->AddProperty(&szFile, AI_MATKEY_TEXTURE_DIFFUSE(0));
}
else if (iMasked || !iType || (iType && iWidth && iHeight))
{
} else if (iMasked || !iType || (iType && iWidth && iHeight)) {
pcNew.reset(new aiTexture());
if (!iHeight || !iWidth)
{
if (!iHeight || !iWidth) {
ASSIMP_LOG_WARN("Found embedded texture, but its width "
"an height are both 0. Is this a joke?");
// generate an empty chess pattern
pcNew->mWidth = pcNew->mHeight = 8;
pcNew->pcData = new aiTexel[64];
for (unsigned int x = 0; x < 8;++x)
{
for (unsigned int y = 0; y < 8;++y)
{
for (unsigned int x = 0; x < 8; ++x) {
for (unsigned int y = 0; y < 8; ++y) {
const bool bSet = ((0 == x % 2 && 0 != y % 2) ||
(0 != x % 2 && 0 == y % 2));
@ -571,9 +509,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
pc->a = 0xFF;
}
}
}
else
{
} else {
// it is a standard color texture. Fill in width and height
// and call the same function we used for loading MDL5 files
@ -592,12 +528,13 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// texture instead of material colors ... posssible they have
// been converted to MDL7 from other formats, such as MDL5
aiColor4D clrTexture;
if (pcNew)clrTexture = ReplaceTextureWithColor(pcNew.get());
else clrTexture.r = get_qnan();
if (pcNew)
clrTexture = ReplaceTextureWithColor(pcNew.get());
else
clrTexture.r = get_qnan();
// check whether a material definition is contained in the skin
if (iType & AI_MDL7_SKINTYPE_MATERIAL)
{
if (iType & AI_MDL7_SKINTYPE_MATERIAL) {
BE_NCONST MDL::Material_MDL7 *pcMatIn = (BE_NCONST MDL::Material_MDL7 *)szCurrent;
szCurrent = (unsigned char *)(pcMatIn + 1);
VALIDATE_FILE_SIZE(szCurrent);
@ -605,8 +542,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
aiColor3D clrTemp;
#define COLOR_MULTIPLY_RGB() \
if (is_not_qnan(clrTexture.r)) \
{ \
if (is_not_qnan(clrTexture.r)) { \
clrTemp.r *= clrTexture.r; \
clrTemp.g *= clrTexture.g; \
clrTemp.b *= clrTexture.b; \
@ -666,31 +602,26 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// read phong power
int iShadingMode = (int)aiShadingMode_Gouraud;
AI_SWAP4(pcMatIn->Power);
if (0.0f != pcMatIn->Power)
{
if (0.0f != pcMatIn->Power) {
iShadingMode = (int)aiShadingMode_Phong;
// pcMatIn is packed, we can't form pointers to its members
float power = pcMatIn->Power;
pcMatOut->AddProperty<float>(&power, 1, AI_MATKEY_SHININESS);
}
pcMatOut->AddProperty<int>(&iShadingMode, 1, AI_MATKEY_SHADING_MODEL);
}
else if (is_not_qnan(clrTexture.r))
{
} else if (is_not_qnan(clrTexture.r)) {
pcMatOut->AddProperty<aiColor4D>(&clrTexture, 1, AI_MATKEY_COLOR_DIFFUSE);
pcMatOut->AddProperty<aiColor4D>(&clrTexture, 1, AI_MATKEY_COLOR_SPECULAR);
}
// if the texture could be replaced by a single material color
// we don't need the texture anymore
if (is_not_qnan(clrTexture.r))
{
if (is_not_qnan(clrTexture.r)) {
pcNew.reset();
}
// If an ASCII effect description (HLSL?) is contained in the file,
// we can simply ignore it ...
if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
{
if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF) {
VALIDATE_FILE_SIZE(szCurrent);
int32_t iMe = *((int32_t *)szCurrent);
AI_SWAP4(iMe);
@ -700,29 +631,24 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// If an embedded texture has been loaded setup the corresponding
// data structures in the aiScene instance
if (pcNew && pScene->mNumTextures <= 999)
{
if (pcNew && pScene->mNumTextures <= 999) {
// place this as diffuse texture
char szCurrent[5];
ai_snprintf(szCurrent,5,"*%i",this->pScene->mNumTextures);
char current[5];
ai_snprintf(current, 5, "*%i", this->pScene->mNumTextures);
aiString szFile;
const size_t iLen = strlen((const char*)szCurrent);
::memcpy(szFile.data,(const char*)szCurrent,iLen+1);
const size_t iLen = strlen((const char *)current);
::memcpy(szFile.data, (const char *)current, iLen + 1);
szFile.length = (ai_uint32)iLen;
pcMatOut->AddProperty(&szFile, AI_MATKEY_TEXTURE_DIFFUSE(0));
// store the texture
if (!pScene->mNumTextures)
{
if (!pScene->mNumTextures) {
pScene->mNumTextures = 1;
pScene->mTextures = new aiTexture *[1];
pScene->mTextures[0] = pcNew.release();
}
else
{
} else {
aiTexture **pc = pScene->mTextures;
pScene->mTextures = new aiTexture *[pScene->mNumTextures + 1];
for (unsigned int i = 0; i < pScene->mNumTextures; ++i) {
@ -745,24 +671,18 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7(
const unsigned char **szCurrentOut,
unsigned int iType,
unsigned int iWidth,
unsigned int iHeight)
{
unsigned int iHeight) {
// get the type of the skin
const unsigned int iMasked = (unsigned int)(iType & 0xF);
if (0x6 == iMasked)
{
if (0x6 == iMasked) {
szCurrent += iWidth;
}
if (0x7 == iMasked)
{
const size_t iLen = ::strlen((const char*)szCurrent);
if (0x7 == iMasked) {
const size_t iLen = std::strlen((const char *)szCurrent);
szCurrent += iLen + 1;
}
else if (iMasked || !iType)
{
if (iMasked || !iType || (iType && iWidth && iHeight))
{
} else if (iMasked || !iType) {
if (iMasked || !iType || (iType && iWidth && iHeight)) {
// ParseTextureColorData(..., aiTexture::pcData == bad_texel) will simply
// return the size of the color data in bytes in iSkip
unsigned int iSkip = 0;
@ -774,7 +694,7 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7(
ParseTextureColorData(szCurrent, iMasked, &iSkip, &tex);
// FIX: Important, otherwise the destructor will crash
tex.pcData = NULL;
tex.pcData = nullptr;
// skip length of texture data
szCurrent += iSkip;
@ -782,16 +702,14 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7(
}
// check whether a material definition is contained in the skin
if (iType & AI_MDL7_SKINTYPE_MATERIAL)
{
if (iType & AI_MDL7_SKINTYPE_MATERIAL) {
BE_NCONST MDL::Material_MDL7 *pcMatIn = (BE_NCONST MDL::Material_MDL7 *)szCurrent;
szCurrent = (unsigned char *)(pcMatIn + 1);
}
// if an ASCII effect description (HLSL?) is contained in the file,
// we can simply ignore it ...
if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
{
if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF) {
int32_t iMe = *((int32_t *)szCurrent);
AI_SWAP4(iMe);
szCurrent += sizeof(char) * iMe + sizeof(int32_t);
@ -803,10 +721,9 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7(
void MDLImporter::ParseSkinLump_3DGS_MDL7(
const unsigned char *szCurrent,
const unsigned char **szCurrentOut,
std::vector<aiMaterial*>& pcMats)
{
ai_assert(NULL != szCurrent);
ai_assert(NULL != szCurrentOut);
std::vector<aiMaterial *> &pcMats) {
ai_assert(nullptr != szCurrent);
ai_assert(nullptr != szCurrentOut);
*szCurrentOut = szCurrent;
BE_NCONST MDL::Skin_MDL7 *pcSkin = (BE_NCONST MDL::Skin_MDL7 *)szCurrent;
@ -825,8 +742,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
pcSkin->typ, pcSkin->width, pcSkin->height);
// place the name of the skin in the material
if (pcSkin->texture_name[0])
{
if (pcSkin->texture_name[0]) {
// the 0 termination could be there or not - we can't know
aiString szFile;
::memcpy(szFile.data, pcSkin->texture_name, sizeof(pcSkin->texture_name));

View File

@ -199,9 +199,9 @@ namespace vmd
stream->write((char*)&ik_count, sizeof(int));
for (int i = 0; i < ik_count; i++)
{
const VmdIkEnable& ik_enable = this->ik_enable.at(i);
stream->write(ik_enable.ik_name.c_str(), 20);
stream->write((char*)&ik_enable.enable, sizeof(uint8_t));
const VmdIkEnable& ik_enable_ref = this->ik_enable.at(i);
stream->write(ik_enable_ref.ik_name.c_str(), 20);
stream->write((char *)&ik_enable_ref.enable, sizeof(uint8_t));
}
}
};

View File

@ -261,19 +261,19 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
TempTriangle& t = triangles[i];
stream.IncPtr(2);
for (unsigned int i = 0; i < 3; ++i) {
t.indices[i] = stream.GetI2();
for (unsigned int j = 0; j < 3; ++j) {
t.indices[j] = stream.GetI2();
}
for (unsigned int i = 0; i < 3; ++i) {
ReadVector(stream,t.normals[i]);
for (unsigned int j = 0; j < 3; ++j) {
ReadVector(stream,t.normals[j]);
}
for (unsigned int i = 0; i < 3; ++i) {
stream >> (float&)(t.uv[i].x); // see note in ReadColor()
for (unsigned int j = 0; j < 3; ++j) {
stream >> (float&)(t.uv[j].x); // see note in ReadColor()
}
for (unsigned int i = 0; i < 3; ++i) {
stream >> (float&)(t.uv[i].y);
for (unsigned int j = 0; j < 3; ++j) {
stream >> (float&)(t.uv[j].y);
}
t.sg = stream.GetI1();
@ -296,8 +296,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream >> num;
t.triangles.resize(num);
for (unsigned int i = 0; i < num; ++i) {
t.triangles[i] = stream.GetI2();
for (unsigned int j = 0; j < num; ++j) {
t.triangles[j] = stream.GetI2();
}
t.mat = stream.GetI1();
if (t.mat == UINT_MAX) {
@ -309,8 +309,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream >> mat;
std::vector<TempMaterial> materials(mat);
for (unsigned int i = 0;i < mat; ++i) {
TempMaterial& t = materials[i];
for (unsigned int j = 0;j < mat; ++j) {
TempMaterial& t = materials[j];
stream.CopyAndAdvance(t.name,32);
t.name[32] = '\0';
@ -338,8 +338,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream >> joint;
std::vector<TempJoint> joints(joint);
for(unsigned int i = 0; i < joint; ++i) {
TempJoint& j = joints[i];
for(unsigned int ii = 0; ii < joint; ++ii) {
TempJoint& j = joints[ii];
stream.IncPtr(1);
stream.CopyAndAdvance(j.name,32);
@ -494,17 +494,17 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
typedef std::map<unsigned int,unsigned int> BoneSet;
BoneSet mybones;
for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) {
aiFace& f = m->mFaces[i];
if (g.triangles[i]>triangles.size()) {
for (unsigned int j = 0,n = 0; j < m->mNumFaces; ++j) {
aiFace& f = m->mFaces[j];
if (g.triangles[j]>triangles.size()) {
throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
}
TempTriangle& t = triangles[g.triangles[i]];
f.mIndices = new unsigned int[f.mNumIndices=3];
for (unsigned int i = 0; i < 3; ++i,++n) {
if (t.indices[i]>vertices.size()) {
for (unsigned int k = 0; k < 3; ++k,++n) {
if (t.indices[k]>vertices.size()) {
throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
}
@ -545,11 +545,11 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
}
// .. and collect bone weights
for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) {
TempTriangle& t = triangles[g.triangles[i]];
for (unsigned int j = 0,n = 0; j < m->mNumFaces; ++j) {
TempTriangle& t = triangles[g.triangles[j]];
for (unsigned int i = 0; i < 3; ++i,++n) {
const TempVertex& v = vertices[t.indices[i]];
for (unsigned int k = 0; k < 3; ++k,++n) {
const TempVertex& v = vertices[t.indices[k]];
for(unsigned int a = 0; a < 4; ++a) {
const unsigned int bone = v.bone_id[a];
if(bone==UINT_MAX){

View File

@ -332,8 +332,7 @@ unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
aiMaterialProperty* prop = pMat->mProperties[i];
if ( prop /* just a sanity check ... */
&& 0 == strcmp( prop->mKey.data, _AI_MATKEY_TEXTURE_BASE )
&& prop->mSemantic == type) {
&& 0 == strcmp(prop->mKey.data, _AI_MATKEY_TEXTURE_BASE) && static_cast < aiTextureType>(prop->mSemantic) == type) {
max = std::max(max,prop->mIndex+1);
}
@ -562,7 +561,8 @@ uint32_t Assimp::ComputeMaterialHash(const aiMaterial* mat, bool includeMatName
// Exclude all properties whose first character is '?' from the hash
// See doc for aiMaterialProperty.
if ((prop = mat->mProperties[i]) && (includeMatName || prop->mKey.data[0] != '?')) {
prop = mat->mProperties[ i ];
if ( nullptr != prop && (includeMatName || prop->mKey.data[0] != '?')) {
hash = SuperFastHash(prop->mKey.data,(unsigned int)prop->mKey.length,hash);
hash = SuperFastHash(prop->mData,prop->mDataLength,hash);

File diff suppressed because it is too large Load Diff

View File

@ -185,8 +185,8 @@ private:
// for spheres, cones and cylinders: center point of the object
aiVector3D center, radius, dir;
char name[128];
static const size_t MaxNameLen = 128;
char name[MaxNameLen];
std::vector<aiVector3D> vertices, normals, uvs;
std::vector<unsigned int> faces;

View File

@ -86,7 +86,7 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
// ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to Wavefront OBJ without the material file. Prototyped and registered in Exporter.cpp
void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties) {
void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* ) {
// invoke the exporter
ObjExporter exporter(pFile, pScene, true);

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -44,10 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJ_FILEDATA_H_INC
# define OBJ_FILEDATA_H_INC
#include <vector>
#include <map>
#include <assimp/types.h>
# include <assimp/mesh.h>
# include <assimp/types.h>
# include <map>
# include <vector>
namespace Assimp {
namespace ObjFile {
@ -75,12 +74,8 @@ struct Face {
Material *m_pMaterial;
//! \brief Default constructor
Face( aiPrimitiveType pt = aiPrimitiveType_POLYGON)
: m_PrimitiveType( pt )
, m_vertices()
, m_normals()
, m_texturCoords()
, m_pMaterial( 0L ) {
Face(aiPrimitiveType pt = aiPrimitiveType_POLYGON) :
m_PrimitiveType(pt), m_vertices(), m_normals(), m_texturCoords(), m_pMaterial(0L) {
// empty
}
@ -181,14 +176,13 @@ struct Material {
aiColor3D transparent;
//! Constructor
Material()
: diffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) )
, alpha (ai_real( 1.0 ) )
, shineness ( ai_real( 0.0) )
, illumination_model (1)
, ior ( ai_real( 1.0 ) )
, transparent( ai_real( 1.0), ai_real (1.0), ai_real(1.0)) {
Material() :
diffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
alpha(ai_real(1.0)),
shineness(ai_real(0.0)),
illumination_model(1),
ior(ai_real(1.0)),
transparent(ai_real(1.0), ai_real(1.0), ai_real(1.0)) {
std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false);
}
@ -220,20 +214,15 @@ struct Mesh {
bool m_hasVertexColors;
/// Constructor
explicit Mesh( const std::string &name )
: m_name( name )
, m_pMaterial(NULL)
, m_uiNumIndices(0)
, m_uiMaterialIndex( NoMaterial )
, m_hasNormals(false) {
explicit Mesh(const std::string &name) :
m_name(name), m_pMaterial(NULL), m_uiNumIndices(0), m_uiMaterialIndex(NoMaterial), m_hasNormals(false) {
memset(m_uiUVCoordinates, 0, sizeof(unsigned int) * AI_MAX_NUMBER_OF_TEXTURECOORDS);
}
/// Destructor
~Mesh() {
for (std::vector<Face *>::iterator it = m_Faces.begin();
it != m_Faces.end(); ++it)
{
it != m_Faces.end(); ++it) {
delete *it;
}
}
@ -292,8 +281,7 @@ struct Model {
m_pGroupFaceIDs(NULL),
m_strActiveGroup(""),
m_TextureCoordDim(0),
m_pCurrentMesh(NULL)
{
m_pCurrentMesh(NULL) {
// empty
}

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -44,16 +42,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
#include "ObjFileImporter.h"
#include "ObjFileParser.h"
#include "ObjFileData.h"
#include <assimp/IOStreamBuffer.h>
#include <memory>
#include "ObjFileParser.h"
#include <assimp/DefaultIOSystem.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/IOStreamBuffer.h>
#include <assimp/ai_assert.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
#include <memory>
static const aiImporterDesc desc = {
"Wavefront Object Importer",
@ -76,10 +74,8 @@ using namespace std;
// ------------------------------------------------------------------------------------------------
// Default constructor
ObjFileImporter::ObjFileImporter()
: m_Buffer()
, m_pRootObject( nullptr )
, m_strAbsPath( std::string(1, DefaultIOSystem().getOsSeparator()) ) {}
ObjFileImporter::ObjFileImporter() :
m_Buffer(), m_pRootObject(nullptr), m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {}
// ------------------------------------------------------------------------------------------------
// Destructor.
@ -255,8 +251,7 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
// Creates all nodes of the model
aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile::Object *pObject,
aiNode *pParent, aiScene *pScene,
std::vector<aiMesh*> &MeshArray )
{
std::vector<aiMesh *> &MeshArray) {
ai_assert(NULL != pModel);
if (NULL == pObject) {
return NULL;
@ -334,8 +329,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
pMesh->mName.Set(pObjMesh->m_name);
}
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
{
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
ObjFile::Face *const inp = pObjMesh->m_Faces[index];
ai_assert(NULL != inp);
@ -374,8 +368,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
f.mIndices = new unsigned int[2];
}
continue;
}
else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
} else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
for (size_t i = 0; i < inp->m_vertices.size(); ++i) {
aiFace &f = pMesh->mFaces[outIndex++];
uiIdxCount += f.mNumIndices = 1;
@ -437,8 +430,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
// Allocate buffer for texture coordinates
if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] )
{
if (!pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0]) {
pMesh->mNumUVComponents[0] = pModel->m_TextureCoordDim;
pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices];
}
@ -463,34 +455,26 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
// Copy all normals
if (normalsok && !pModel->m_Normals.empty() && vertexIndex < sourceFace->m_normals.size()) {
const unsigned int normal = sourceFace->m_normals.at(vertexIndex);
if ( normal >= pModel->m_Normals.size() )
{
if (normal >= pModel->m_Normals.size()) {
normalsok = false;
}
else
{
} else {
pMesh->mNormals[newIndex] = pModel->m_Normals[normal];
}
}
// Copy all vertex colors
if ( !pModel->m_VertexColors.empty())
{
if (!pModel->m_VertexColors.empty()) {
const aiVector3D &color = pModel->m_VertexColors[vertex];
pMesh->mColors[0][newIndex] = aiColor4D(color.x, color.y, color.z, 1.0);
}
// Copy all texture coordinates
if ( uvok && !pModel->m_TextureCoord.empty() && vertexIndex < sourceFace->m_texturCoords.size())
{
if (uvok && !pModel->m_TextureCoord.empty() && vertexIndex < sourceFace->m_texturCoords.size()) {
const unsigned int tex = sourceFace->m_texturCoords.at(vertexIndex);
if ( tex >= pModel->m_TextureCoord.size() )
{
if (tex >= pModel->m_TextureCoord.size()) {
uvok = false;
}
else
{
} else {
const aiVector3D &coord3d = pModel->m_TextureCoord[tex];
pMesh->mTextureCoords[0][newIndex] = aiVector3D(coord3d.x, coord3d.y, coord3d.z);
}
@ -530,22 +514,19 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
pDestFace[-1].mIndices[1] = newIndex;
}
}
else if (last) {
} else if (last) {
outIndex++;
}
++newIndex;
}
}
if (!normalsok)
{
if (!normalsok) {
delete[] pMesh->mNormals;
pMesh->mNormals = nullptr;
}
if (!uvok)
{
if (!uvok) {
delete[] pMesh->mTextureCoords[0];
pMesh->mTextureCoords[0] = nullptr;
}
@ -553,17 +534,14 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
// ------------------------------------------------------------------------------------------------
// Counts all stored meshes
void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes)
{
void ObjFileImporter::countObjects(const std::vector<ObjFile::Object *> &rObjects, int &iNumMeshes) {
iNumMeshes = 0;
if (rObjects.empty())
return;
iNumMeshes += static_cast<unsigned int>(rObjects.size());
for (auto object: rObjects)
{
if (!object->m_SubObjects.empty())
{
for (auto object : rObjects) {
if (!object->m_SubObjects.empty()) {
countObjects(object->m_SubObjects, iNumMeshes);
}
}
@ -595,8 +573,7 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
}
pScene->mMaterials = new aiMaterial *[numMaterials];
for ( unsigned int matIndex = 0; matIndex < numMaterials; matIndex++ )
{
for (unsigned int matIndex = 0; matIndex < numMaterials; matIndex++) {
// Store material name
std::map<std::string, ObjFile::Material *>::const_iterator it;
it = pModel->m_MaterialMap.find(pModel->m_MaterialLib[matIndex]);
@ -611,8 +588,7 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
// convert illumination model
int sm = 0;
switch (pCurrentMaterial->illumination_model)
{
switch (pCurrentMaterial->illumination_model) {
case 0:
sm = aiShadingMode_NoShading;
break;
@ -644,71 +620,58 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
// Adding textures
const int uvwIndex = 0;
if ( 0 != pCurrentMaterial->texture.length )
{
if (0 != pCurrentMaterial->texture.length) {
mat->AddProperty(&pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_DIFFUSE(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureDiffuseType])
{
if (pCurrentMaterial->clamp[ObjFile::Material::TextureDiffuseType]) {
addTextureMappingModeProperty(mat, aiTextureType_DIFFUSE);
}
}
if ( 0 != pCurrentMaterial->textureAmbient.length )
{
if (0 != pCurrentMaterial->textureAmbient.length) {
mat->AddProperty(&pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_AMBIENT(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureAmbientType])
{
if (pCurrentMaterial->clamp[ObjFile::Material::TextureAmbientType]) {
addTextureMappingModeProperty(mat, aiTextureType_AMBIENT);
}
}
if ( 0 != pCurrentMaterial->textureEmissive.length )
{
if (0 != pCurrentMaterial->textureEmissive.length) {
mat->AddProperty(&pCurrentMaterial->textureEmissive, AI_MATKEY_TEXTURE_EMISSIVE(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_EMISSIVE(0));
}
if ( 0 != pCurrentMaterial->textureSpecular.length )
{
if (0 != pCurrentMaterial->textureSpecular.length) {
mat->AddProperty(&pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_SPECULAR(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularType])
{
if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularType]) {
addTextureMappingModeProperty(mat, aiTextureType_SPECULAR);
}
}
if ( 0 != pCurrentMaterial->textureBump.length )
{
if (0 != pCurrentMaterial->textureBump.length) {
mat->AddProperty(&pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_HEIGHT(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType])
{
if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType]) {
addTextureMappingModeProperty(mat, aiTextureType_HEIGHT);
}
}
if ( 0 != pCurrentMaterial->textureNormal.length )
{
if (0 != pCurrentMaterial->textureNormal.length) {
mat->AddProperty(&pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_NORMALS(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType])
{
if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType]) {
addTextureMappingModeProperty(mat, aiTextureType_NORMALS);
}
}
if( 0 != pCurrentMaterial->textureReflection[0].length )
{
if (0 != pCurrentMaterial->textureReflection[0].length) {
ObjFile::Material::TextureType type = 0 != pCurrentMaterial->textureReflection[1].length ?
ObjFile::Material::TextureReflectionCubeTopType :
ObjFile::Material::TextureReflectionSphereType;
unsigned count = type == ObjFile::Material::TextureReflectionSphereType ? 1 : 6;
for( unsigned i = 0; i < count; i++ )
{
for (unsigned i = 0; i < count; i++) {
mat->AddProperty(&pCurrentMaterial->textureReflection[i], AI_MATKEY_TEXTURE_REFLECTION(i));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_REFLECTION(i));
@ -717,32 +680,26 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
}
}
if ( 0 != pCurrentMaterial->textureDisp.length )
{
if (0 != pCurrentMaterial->textureDisp.length) {
mat->AddProperty(&pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_DISPLACEMENT(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureDispType])
{
if (pCurrentMaterial->clamp[ObjFile::Material::TextureDispType]) {
addTextureMappingModeProperty(mat, aiTextureType_DISPLACEMENT);
}
}
if ( 0 != pCurrentMaterial->textureOpacity.length )
{
if (0 != pCurrentMaterial->textureOpacity.length) {
mat->AddProperty(&pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_OPACITY(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureOpacityType])
{
if (pCurrentMaterial->clamp[ObjFile::Material::TextureOpacityType]) {
addTextureMappingModeProperty(mat, aiTextureType_OPACITY);
}
}
if ( 0 != pCurrentMaterial->textureSpecularity.length )
{
if (0 != pCurrentMaterial->textureSpecularity.length) {
mat->AddProperty(&pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_SHININESS(0));
if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularityType])
{
if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularityType]) {
addTextureMappingModeProperty(mat, aiTextureType_SHININESS);
}
}
@ -758,8 +715,7 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
// ------------------------------------------------------------------------------------------------
// Appends this node to the parent node
void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
{
void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) {
// Checking preconditions
ai_assert(NULL != pParent);
ai_assert(NULL != pChild);

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -54,7 +53,7 @@ namespace Assimp {
namespace ObjFile {
struct Object;
struct Model;
}
} // namespace ObjFile
// ------------------------------------------------------------------------------------------------
/// \class ObjFileImporter

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -41,16 +39,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
#include <stdlib.h>
#include "ObjFileMtlImporter.h"
#include "ObjTools.h"
#include "ObjFileData.h"
#include <assimp/fast_atof.h>
#include "ObjTools.h"
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/material.h>
#include <stdlib.h>
#include <assimp/DefaultLogger.hpp>
namespace Assimp {
@ -92,11 +89,12 @@ ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
m_DataIt(buffer.begin()),
m_DataItEnd(buffer.end()),
m_pModel(pModel),
m_uiLine( 0 )
{
ai_assert( NULL != m_pModel );
if ( NULL == m_pModel->m_pDefaultMaterial )
{
m_uiLine(0),
m_buffer() {
ai_assert(nullptr != m_pModel);
m_buffer.resize(BUFFERSIZE);
std::fill(m_buffer.begin(), m_buffer.end(), '\0');
if (nullptr == m_pModel->m_pDefaultMaterial) {
m_pModel->m_pDefaultMaterial = new ObjFile::Material;
m_pModel->m_pDefaultMaterial->MaterialName.Set("default");
}
@ -105,65 +103,39 @@ ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
// -------------------------------------------------------------------
// Destructor
ObjFileMtlImporter::~ObjFileMtlImporter()
{
ObjFileMtlImporter::~ObjFileMtlImporter() {
// empty
}
// -------------------------------------------------------------------
// Private copy constructor
ObjFileMtlImporter::ObjFileMtlImporter(const ObjFileMtlImporter & )
{
// empty
}
// -------------------------------------------------------------------
// Private copy constructor
ObjFileMtlImporter &ObjFileMtlImporter::operator = ( const ObjFileMtlImporter & )
{
return *this;
}
// -------------------------------------------------------------------
// Loads the material description
void ObjFileMtlImporter::load()
{
void ObjFileMtlImporter::load() {
if (m_DataIt == m_DataItEnd)
return;
while ( m_DataIt != m_DataItEnd )
{
switch (*m_DataIt)
{
while (m_DataIt != m_DataItEnd) {
switch (*m_DataIt) {
case 'k':
case 'K':
{
case 'K': {
++m_DataIt;
if (*m_DataIt == 'a') // Ambient color
{
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->ambient);
}
else if (*m_DataIt == 'd') // Diffuse color
} else if (*m_DataIt == 'd') // Diffuse color
{
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->diffuse);
}
else if (*m_DataIt == 's')
{
} else if (*m_DataIt == 's') {
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->specular);
}
else if (*m_DataIt == 'e')
{
} else if (*m_DataIt == 'e') {
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->emissive);
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
}
break;
case 'T':
{
} break;
case 'T': {
++m_DataIt;
if (*m_DataIt == 'f') // Material transmission
{
@ -171,10 +143,8 @@ void ObjFileMtlImporter::load()
getColorRGBA(&m_pModel->m_pCurrentMaterial->transparent);
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
}
break;
case 'd':
{
} break;
case 'd': {
if (*(m_DataIt + 1) == 'i' && *(m_DataIt + 2) == 's' && *(m_DataIt + 3) == 'p') {
// A displacement map
getTexture();
@ -184,15 +154,12 @@ void ObjFileMtlImporter::load()
getFloatValue(m_pModel->m_pCurrentMaterial->alpha);
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
}
}
break;
} break;
case 'N':
case 'n':
{
case 'n': {
++m_DataIt;
switch(*m_DataIt)
{
switch (*m_DataIt) {
case 's': // Specular exponent
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
@ -206,8 +173,7 @@ void ObjFileMtlImporter::load()
break;
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
}
break;
} break;
case 'm': // Texture
case 'b': // quick'n'dirty - for 'bump' sections
@ -215,30 +181,25 @@ void ObjFileMtlImporter::load()
{
getTexture();
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
}
break;
} break;
case 'i': // Illumination model
{
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
getIlluminationModel(m_pModel->m_pCurrentMaterial->illumination_model);
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
}
break;
} break;
default:
{
default: {
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
}
break;
} break;
}
}
}
// -------------------------------------------------------------------
// Loads a color definition
void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor )
{
void ObjFileMtlImporter::getColorRGBA(aiColor3D *pColor) {
ai_assert(NULL != pColor);
ai_real r(0.0), g(0.0), b(0.0);
@ -256,24 +217,21 @@ void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor )
// -------------------------------------------------------------------
// Loads the kind of illumination model.
void ObjFileMtlImporter::getIlluminationModel( int &illum_model )
{
m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
illum_model = atoi(m_buffer);
void ObjFileMtlImporter::getIlluminationModel(int &illum_model) {
m_DataIt = CopyNextWord<DataArrayIt>(m_DataIt, m_DataItEnd, &m_buffer[0], BUFFERSIZE);
illum_model = atoi(&m_buffer[0]);
}
// -------------------------------------------------------------------
// Loads a single float value.
void ObjFileMtlImporter::getFloatValue( ai_real &value )
{
m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
value = (ai_real) fast_atof(m_buffer);
void ObjFileMtlImporter::getFloatValue(ai_real &value) {
m_DataIt = CopyNextWord<DataArrayIt>(m_DataIt, m_DataItEnd, &m_buffer[0], BUFFERSIZE);
value = (ai_real)fast_atof(&m_buffer[0]);
}
// -------------------------------------------------------------------
// Creates a material from loaded data.
void ObjFileMtlImporter::createMaterial()
{
void ObjFileMtlImporter::createMaterial() {
std::string line;
while (!IsLineEnd(*m_DataIt)) {
line += *m_DataIt;
@ -398,90 +356,57 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
// If there is any more texture option
while (!isEndOfBuffer(m_DataIt, m_DataItEnd) && *m_DataIt == '-')
{
while (!isEndOfBuffer(m_DataIt, m_DataItEnd) && *m_DataIt == '-') {
const char *pPtr(&(*m_DataIt));
//skip option key and value
int skipToken = 1;
if (!ASSIMP_strincmp(pPtr, ClampOption.c_str(), static_cast<unsigned int>(ClampOption.size())))
{
if (!ASSIMP_strincmp(pPtr, ClampOption.c_str(), static_cast<unsigned int>(ClampOption.size()))) {
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
char value[3];
CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value));
if (!ASSIMP_strincmp(value, "on", 2))
{
if (!ASSIMP_strincmp(value, "on", 2)) {
clamp = true;
}
skipToken = 2;
}
else if( !ASSIMP_strincmp( pPtr, TypeOption.c_str(), static_cast<unsigned int>(TypeOption.size()) ) )
{
} else if (!ASSIMP_strincmp(pPtr, TypeOption.c_str(), static_cast<unsigned int>(TypeOption.size()))) {
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
char value[12];
CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value));
if( !ASSIMP_strincmp( value, "cube_top", 8 ) )
{
if (!ASSIMP_strincmp(value, "cube_top", 8)) {
clampIndex = ObjFile::Material::TextureReflectionCubeTopType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[0];
}
else if( !ASSIMP_strincmp( value, "cube_bottom", 11 ) )
{
} else if (!ASSIMP_strincmp(value, "cube_bottom", 11)) {
clampIndex = ObjFile::Material::TextureReflectionCubeBottomType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[1];
}
else if( !ASSIMP_strincmp( value, "cube_front", 10 ) )
{
} else if (!ASSIMP_strincmp(value, "cube_front", 10)) {
clampIndex = ObjFile::Material::TextureReflectionCubeFrontType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[2];
}
else if( !ASSIMP_strincmp( value, "cube_back", 9 ) )
{
} else if (!ASSIMP_strincmp(value, "cube_back", 9)) {
clampIndex = ObjFile::Material::TextureReflectionCubeBackType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[3];
}
else if( !ASSIMP_strincmp( value, "cube_left", 9 ) )
{
} else if (!ASSIMP_strincmp(value, "cube_left", 9)) {
clampIndex = ObjFile::Material::TextureReflectionCubeLeftType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[4];
}
else if( !ASSIMP_strincmp( value, "cube_right", 10 ) )
{
} else if (!ASSIMP_strincmp(value, "cube_right", 10)) {
clampIndex = ObjFile::Material::TextureReflectionCubeRightType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[5];
}
else if( !ASSIMP_strincmp( value, "sphere", 6 ) )
{
} else if (!ASSIMP_strincmp(value, "sphere", 6)) {
clampIndex = ObjFile::Material::TextureReflectionSphereType;
out = &m_pModel->m_pCurrentMaterial->textureReflection[0];
}
skipToken = 2;
}
else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size()))
|| !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size()))
|| !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size()))
|| !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size()))
|| !ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size()))
|| !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size())))
{
} else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) {
skipToken = 2;
}
else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), static_cast<unsigned int>(ModifyMapOption.size())))
{
} else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), static_cast<unsigned int>(ModifyMapOption.size()))) {
skipToken = 3;
}
else if ( !ASSIMP_strincmp(pPtr, OffsetOption.c_str(), static_cast<unsigned int>(OffsetOption.size()))
|| !ASSIMP_strincmp(pPtr, ScaleOption.c_str(), static_cast<unsigned int>(ScaleOption.size()))
|| !ASSIMP_strincmp(pPtr, TurbulenceOption.c_str(), static_cast<unsigned int>(TurbulenceOption.size()))
)
{
} else if (!ASSIMP_strincmp(pPtr, OffsetOption.c_str(), static_cast<unsigned int>(OffsetOption.size())) || !ASSIMP_strincmp(pPtr, ScaleOption.c_str(), static_cast<unsigned int>(ScaleOption.size())) || !ASSIMP_strincmp(pPtr, TurbulenceOption.c_str(), static_cast<unsigned int>(TurbulenceOption.size()))) {
skipToken = 4;
}
for (int i = 0; i < skipToken; ++i)
{
for (int i = 0; i < skipToken; ++i) {
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
}
}

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -41,9 +40,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJFILEMTLIMPORTER_H_INC
#define OBJFILEMTLIMPORTER_H_INC
#include <vector>
#include <string>
#include <assimp/defs.h>
#include <string>
#include <vector>
struct aiColor3D;
struct aiString;
@ -53,34 +52,31 @@ namespace Assimp {
namespace ObjFile {
struct Model;
struct Material;
}
} // namespace ObjFile
/**
* @class ObjFileMtlImporter
* @brief Loads the material description from a mtl file.
*/
class ObjFileMtlImporter
{
class ObjFileMtlImporter {
public:
static const size_t BUFFERSIZE = 2048;
typedef std::vector<char> DataArray;
typedef std::vector<char>::iterator DataArrayIt;
typedef std::vector<char>::const_iterator ConstDataArrayIt;
public:
//! \brief Default constructor
//! \brief The class default constructor
ObjFileMtlImporter(std::vector<char> &buffer, const std::string &strAbsPath,
ObjFile::Model *pModel);
//! \brief DEstructor
//! \brief The class destructor
~ObjFileMtlImporter();
ObjFileMtlImporter(const ObjFileMtlImporter &rOther) = delete;
ObjFileMtlImporter &operator=(const ObjFileMtlImporter &rOther) = delete;
private:
/// Copy constructor, empty.
ObjFileMtlImporter(const ObjFileMtlImporter &rOther);
/// \brief Assignment operator, returns only a reference of this instance.
ObjFileMtlImporter &operator = (const ObjFileMtlImporter &rOther);
/// Load the whole material description
void load();
/// Get color data.
@ -107,7 +103,7 @@ private:
//! Current line in file
unsigned int m_uiLine;
//! Helper buffer
char m_buffer[BUFFERSIZE];
std::vector<char> m_buffer;
};
// ------------------------------------------------------------------------------------------------

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -43,14 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
#include "ObjFileParser.h"
#include "ObjFileData.h"
#include "ObjFileMtlImporter.h"
#include "ObjTools.h"
#include "ObjFileData.h"
#include <assimp/ParsingUtils.h>
#include <assimp/BaseImporter.h>
#include <assimp/DefaultIOSystem.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/ParsingUtils.h>
#include <assimp/material.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
#include <cstdlib>
#include <memory>
@ -60,29 +58,30 @@ namespace Assimp {
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
ObjFileParser::ObjFileParser()
: m_DataIt()
, m_DataItEnd()
, m_pModel( nullptr )
, m_uiLine( 0 )
, m_pIO( nullptr )
, m_progress( nullptr )
, m_originalObjFileName() {
// empty
}
ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName,
IOSystem *io, ProgressHandler* progress,
std::string originalObjFileName) :
ObjFileParser::ObjFileParser() :
m_DataIt(),
m_DataItEnd(),
m_pModel(nullptr),
m_uiLine(0),
m_buffer(),
m_pIO(nullptr),
m_progress(nullptr),
m_originalObjFileName() {
std::fill_n(m_buffer, Buffersize, '\0');
}
ObjFileParser::ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::string &modelName,
IOSystem *io, ProgressHandler *progress,
const std::string &originalObjFileName) :
m_DataIt(),
m_DataItEnd(),
m_pModel(nullptr),
m_uiLine(0),
m_buffer(),
m_pIO(io),
m_progress(progress),
m_originalObjFileName(std::move(originalObjFileName))
{
std::fill_n(m_buffer, Buffersize,0);
m_originalObjFileName(originalObjFileName) {
std::fill_n(m_buffer, Buffersize, '\0');
// Create the model instance to store all the data
m_pModel.reset(new ObjFile::Model());
@ -98,8 +97,7 @@ ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::str
parseFile(streamBuffer);
}
ObjFileParser::~ObjFileParser()
{
ObjFileParser::~ObjFileParser() {
}
void ObjFileParser::setBuffer(std::vector<char> &buffer) {
@ -161,23 +159,18 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
++m_DataIt;
getVector3(m_pModel->m_Normals);
}
}
break;
} break;
case 'p': // Parse a face, line or point statement
case 'l':
case 'f':
{
getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l'
? aiPrimitiveType_LINE : aiPrimitiveType_POINT));
}
break;
case 'f': {
getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l' ? aiPrimitiveType_LINE : aiPrimitiveType_POINT));
} break;
case '#': // Parse a comment
{
getComment();
}
break;
} break;
case 'u': // Parse a material desc. setter
{
@ -189,12 +182,10 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
if (nextSpace != std::string::npos)
name = name.substr(0, nextSpace);
if(name == "usemtl")
{
if (name == "usemtl") {
getMaterialDesc();
}
}
break;
} break;
case 'm': // Parse a material library or merging group ('mg')
{
@ -212,33 +203,27 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
getMaterialLib();
else
goto pf_skip_line;
}
break;
} break;
case 'g': // Parse group name
{
getGroupName();
}
break;
} break;
case 's': // Parse group number
{
getGroupNumber();
}
break;
} break;
case 'o': // Parse object name
{
getObjectName();
}
break;
} break;
default:
{
default: {
pf_skip_line:
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
}
break;
} break;
}
}
}
@ -497,7 +482,6 @@ void ObjFileParser::getFace( aiPrimitiveType type ) {
delete face;
throw DeadlyImportError("OBJ: Invalid face indice");
}
}
m_DataIt += iStep;
}
@ -691,16 +675,13 @@ void ObjFileParser::getNewMaterial() {
}
// -------------------------------------------------------------------
int ObjFileParser::getMaterialIndex( const std::string &strMaterialName )
{
int ObjFileParser::getMaterialIndex(const std::string &strMaterialName) {
int mat_index = -1;
if (strMaterialName.empty()) {
return mat_index;
}
for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index)
{
if ( strMaterialName == m_pModel->m_MaterialLib[ index ])
{
for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index) {
if (strMaterialName == m_pModel->m_MaterialLib[index]) {
mat_index = (int)index;
break;
}
@ -729,14 +710,11 @@ void ObjFileParser::getGroupName() {
createObject(groupName);
// New group name, creating a new entry
if (it == m_pModel->m_Groups.end())
{
if (it == m_pModel->m_Groups.end()) {
std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
m_pModel->m_Groups[groupName] = pFaceIDArray;
m_pModel->m_pGroupFaceIDs = (pFaceIDArray);
}
else
{
} else {
m_pModel->m_pGroupFaceIDs = (*it).second;
}
m_pModel->m_strActiveGroup = groupName;
@ -746,8 +724,7 @@ void ObjFileParser::getGroupName() {
// -------------------------------------------------------------------
// Not supported
void ObjFileParser::getGroupNumber()
{
void ObjFileParser::getGroupNumber() {
// Not used
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
@ -755,8 +732,7 @@ void ObjFileParser::getGroupNumber()
// -------------------------------------------------------------------
// Not supported
void ObjFileParser::getGroupNumberAndResolution()
{
void ObjFileParser::getGroupNumberAndResolution() {
// Not used
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
@ -765,8 +741,7 @@ void ObjFileParser::getGroupNumberAndResolution()
// -------------------------------------------------------------------
// Stores values for a new object instance, name will be used to
// identify it.
void ObjFileParser::getObjectName()
{
void ObjFileParser::getObjectName() {
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
if (m_DataIt == m_DataItEnd) {
return;
@ -777,18 +752,15 @@ void ObjFileParser::getObjectName()
}
std::string strObjectName(pStart, &(*m_DataIt));
if (!strObjectName.empty())
{
if (!strObjectName.empty()) {
// Reset current object
m_pModel->m_pCurrent = NULL;
// Search for actual object
for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->m_Objects.begin();
it != m_pModel->m_Objects.end();
++it)
{
if ((*it)->m_strObjName == strObjectName)
{
++it) {
if ((*it)->m_strObjName == strObjectName) {
m_pModel->m_pCurrent = *it;
break;
}
@ -803,8 +775,7 @@ void ObjFileParser::getObjectName()
}
// -------------------------------------------------------------------
// Creates a new object instance
void ObjFileParser::createObject(const std::string &objName)
{
void ObjFileParser::createObject(const std::string &objName) {
ai_assert(NULL != m_pModel);
m_pModel->m_pCurrent = new ObjFile::Object;
@ -813,8 +784,7 @@ void ObjFileParser::createObject(const std::string &objName)
createMesh(objName);
if( m_pModel->m_pCurrentMaterial )
{
if (m_pModel->m_pCurrentMaterial) {
m_pModel->m_pCurrentMesh->m_uiMaterialIndex =
getMaterialIndex(m_pModel->m_pCurrentMaterial->MaterialName.data);
m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial;
@ -822,40 +792,32 @@ void ObjFileParser::createObject(const std::string &objName)
}
// -------------------------------------------------------------------
// Creates a new mesh
void ObjFileParser::createMesh( const std::string &meshName )
{
void ObjFileParser::createMesh(const std::string &meshName) {
ai_assert(NULL != m_pModel);
m_pModel->m_pCurrentMesh = new ObjFile::Mesh(meshName);
m_pModel->m_Meshes.push_back(m_pModel->m_pCurrentMesh);
unsigned int meshId = static_cast<unsigned int>(m_pModel->m_Meshes.size() - 1);
if ( NULL != m_pModel->m_pCurrent )
{
if (NULL != m_pModel->m_pCurrent) {
m_pModel->m_pCurrent->m_Meshes.push_back(meshId);
}
else
{
} else {
ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance.");
}
}
// -------------------------------------------------------------------
// Returns true, if a new mesh must be created.
bool ObjFileParser::needsNewMesh( const std::string &materialName )
{
bool ObjFileParser::needsNewMesh(const std::string &materialName) {
// If no mesh data yet
if (m_pModel->m_pCurrentMesh == nullptr)
{
if (m_pModel->m_pCurrentMesh == nullptr) {
return true;
}
bool newMat = false;
int matIdx = getMaterialIndex(materialName);
int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
if ( curMatIdx != int(ObjFile::Mesh::NoMaterial)
&& curMatIdx != matIdx
if (curMatIdx != int(ObjFile::Mesh::NoMaterial) && curMatIdx != matIdx
// no need create a new mesh if no faces in current
// lets say 'usemtl' goes straight after 'g'
&& !m_pModel->m_pCurrentMesh->m_Faces.empty() )
{
&& !m_pModel->m_pCurrentMesh->m_Faces.empty()) {
// New material -> only one material per mesh, so we need to create a new
// material
newMat = true;
@ -865,8 +827,7 @@ bool ObjFileParser::needsNewMesh( const std::string &materialName )
// -------------------------------------------------------------------
// Shows an error in parsing process.
void ObjFileParser::reportErrorTokenInFace()
{
void ObjFileParser::reportErrorTokenInFace() {
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
ASSIMP_LOG_ERROR("OBJ: Not supported token in face description detected");
}

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -42,14 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJ_FILEPARSER_H_INC
#define OBJ_FILEPARSER_H_INC
#include <vector>
#include <string>
#include <map>
#include <memory>
#include <assimp/IOStreamBuffer.h>
#include <assimp/mesh.h>
#include <assimp/vector2.h>
#include <assimp/vector3.h>
#include <assimp/mesh.h>
#include <assimp/IOStreamBuffer.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
namespace Assimp {
@ -59,7 +58,7 @@ namespace ObjFile {
struct Material;
struct Point3;
struct Point2;
}
} // namespace ObjFile
class ObjFileImporter;
class IOSystem;
@ -78,7 +77,7 @@ public:
/// @brief The default constructor.
ObjFileParser();
/// @brief Constructor with data array.
ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem* io, ProgressHandler* progress, std::string originalObjFileName);
ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem *io, ProgressHandler *progress, const std::string &originalObjFileName);
/// @brief Destructor
~ObjFileParser();
/// @brief If you want to load in-core data.
@ -86,6 +85,9 @@ public:
/// @brief Model getter.
ObjFile::Model *GetModel() const;
ObjFileParser(const ObjFileParser&) = delete;
ObjFileParser &operator=(const ObjFileParser& ) = delete;
protected:
/// Parse the loaded file
void parseFile(IOStreamBuffer<char> &streamBuffer);
@ -137,8 +139,6 @@ protected:
private:
// Copy and assignment constructor should be private
// because the class contains pointer to allocated memory
ObjFileParser(const ObjFileParser& rhs);
ObjFileParser& operator=(const ObjFileParser& rhs);
/// Default material name
static const std::string DEFAULT_MATERIAL;

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -46,8 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJ_TOOLS_H_INC
#define OBJ_TOOLS_H_INC
#include <assimp/fast_atof.h>
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <vector>
namespace Assimp {
@ -59,12 +58,9 @@ namespace Assimp {
*/
template <class char_t>
inline bool isEndOfBuffer(char_t it, char_t end) {
if ( it == end )
{
if (it == end) {
return true;
}
else
{
} else {
--end;
}
return (it == end);
@ -76,10 +72,8 @@ inline bool isEndOfBuffer( char_t it, char_t end ) {
* @return Pointer to next space
*/
template <class Char_T>
inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
{
while ( !isEndOfBuffer( pBuffer, pEnd ) )
{
inline Char_T getNextWord(Char_T pBuffer, Char_T pEnd) {
while (!isEndOfBuffer(pBuffer, pEnd)) {
if (!IsSpaceOrNewLine(*pBuffer) || IsLineEnd(*pBuffer)) {
//if ( *pBuffer != '\\' )
break;
@ -95,10 +89,8 @@ inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
* @return Pointer to next token
*/
template <class Char_T>
inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
{
while ( !isEndOfBuffer( pBuffer, pEnd ) )
{
inline Char_T getNextToken(Char_T pBuffer, Char_T pEnd) {
while (!isEndOfBuffer(pBuffer, pEnd)) {
if (IsSpaceOrNewLine(*pBuffer))
break;
pBuffer++;
@ -138,8 +130,7 @@ inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) {
* @return Current-iterator with new position
*/
template <class char_t>
inline char_t getName( char_t it, char_t end, std::string &name )
{
inline char_t getName(char_t it, char_t end, std::string &name) {
name = "";
if (isEndOfBuffer(it, end)) {
return end;
@ -175,21 +166,18 @@ inline char_t getName( char_t it, char_t end, std::string &name )
* @return Current-iterator with new position
*/
template <class char_t>
inline char_t getNameNoSpace( char_t it, char_t end, std::string &name )
{
inline char_t getNameNoSpace(char_t it, char_t end, std::string &name) {
name = "";
if (isEndOfBuffer(it, end)) {
return end;
}
char *pStart = &(*it);
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it )
&& !IsSpaceOrNewLine( *it ) ) {
while (!isEndOfBuffer(it, end) && !IsLineEnd(*it) && !IsSpaceOrNewLine(*it)) {
++it;
}
while( isEndOfBuffer( it, end ) || IsLineEnd( *it )
|| IsSpaceOrNewLine( *it ) ) {
while (isEndOfBuffer(it, end) || IsLineEnd(*it) || IsSpaceOrNewLine(*it)) {
--it;
}
++it;
@ -216,12 +204,10 @@ inline char_t getNameNoSpace( char_t it, char_t end, std::string &name )
* @return Current-iterator with new position
*/
template <class char_t>
inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length )
{
inline char_t CopyNextWord(char_t it, char_t end, char *pBuffer, size_t length) {
size_t index = 0;
it = getNextWord<char_t>(it, end);
while( !IsSpaceOrNewLine( *it ) && !isEndOfBuffer( it, end ) )
{
while (!IsSpaceOrNewLine(*it) && !isEndOfBuffer(it, end)) {
pBuffer[index] = *it;
index++;
if (index == length - 1)
@ -239,8 +225,7 @@ inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length
* @return Current-iterator with new position
*/
template <class char_t>
inline char_t getFloat( char_t it, char_t end, ai_real &value )
{
inline char_t getFloat(char_t it, char_t end, ai_real &value) {
static const size_t BUFFERSIZE = 1024;
char buffer[BUFFERSIZE];
it = CopyNextWord<char_t>(it, end, buffer, BUFFERSIZE);
@ -257,15 +242,13 @@ inline char_t getFloat( char_t it, char_t end, ai_real &value )
*/
template <class string_type>
unsigned int tokenize(const string_type &str, std::vector<string_type> &tokens,
const string_type& delimiters )
{
const string_type &delimiters) {
// Skip delimiters at beginning.
typename string_type::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
typename string_type::size_type pos = str.find_first_of(delimiters, lastPos);
while ( string_type::npos != pos || string_type::npos != lastPos )
{
while (string_type::npos != pos || string_type::npos != lastPos) {
// Found a token, add it to the vector.
string_type tmp = str.substr(lastPos, pos - lastPos);
if (!tmp.empty() && ' ' != tmp[0])
@ -282,10 +265,11 @@ unsigned int tokenize( const string_type& str, std::vector<string_type>& tokens,
}
template <class string_type>
string_type trim_whitespaces(string_type str)
{
while (!str.empty() && IsSpace(str[0])) str.erase(0);
while (!str.empty() && IsSpace(str[str.length() - 1])) str.erase(str.length() - 1);
string_type trim_whitespaces(string_type str) {
while (!str.empty() && IsSpace(str[0]))
str.erase(0);
while (!str.empty() && IsSpace(str[str.length() - 1]))
str.erase(str.length() - 1);
return str;
}

View File

@ -41,22 +41,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "OgreBinarySerializer.h"
#include "OgreXmlSerializer.h"
#include "OgreParsingUtils.h"
#include "OgreXmlSerializer.h"
#include <assimp/TinyFormatter.h>
#include <assimp/DefaultLogger.hpp>
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
// Define as 1 to get verbose logging.
#define OGRE_BINARY_SERIALIZER_DEBUG 0
namespace Assimp
{
namespace Ogre
{
namespace Assimp {
namespace Ogre {
const std::string MESH_VERSION_1_8 = "[MeshSerializer_v1.8]";
const std::string SKELETON_VERSION_1_8 = "[Serializer_v1.80]";
@ -69,70 +66,58 @@ const long MSTREAM_BONE_SIZE_WITHOUT_SCALE = MSTREAM_OVERHEAD_S
const long MSTREAM_KEYFRAME_SIZE_WITHOUT_SCALE = MSTREAM_OVERHEAD_SIZE + (sizeof(float) * 8);
template <>
inline bool OgreBinarySerializer::Read<bool>()
{
inline bool OgreBinarySerializer::Read<bool>() {
return (m_reader->GetU1() > 0);
}
template <>
inline char OgreBinarySerializer::Read<char>()
{
inline char OgreBinarySerializer::Read<char>() {
return static_cast<char>(m_reader->GetU1());
}
template <>
inline uint8_t OgreBinarySerializer::Read<uint8_t>()
{
inline uint8_t OgreBinarySerializer::Read<uint8_t>() {
return m_reader->GetU1();
}
template <>
inline uint16_t OgreBinarySerializer::Read<uint16_t>()
{
inline uint16_t OgreBinarySerializer::Read<uint16_t>() {
return m_reader->GetU2();
}
template <>
inline uint32_t OgreBinarySerializer::Read<uint32_t>()
{
inline uint32_t OgreBinarySerializer::Read<uint32_t>() {
return m_reader->GetU4();
}
template <>
inline float OgreBinarySerializer::Read<float>()
{
inline float OgreBinarySerializer::Read<float>() {
return m_reader->GetF4();
}
void OgreBinarySerializer::ReadBytes(char *dest, size_t numBytes)
{
void OgreBinarySerializer::ReadBytes(char *dest, size_t numBytes) {
ReadBytes(static_cast<void *>(dest), numBytes);
}
void OgreBinarySerializer::ReadBytes(uint8_t *dest, size_t numBytes)
{
void OgreBinarySerializer::ReadBytes(uint8_t *dest, size_t numBytes) {
ReadBytes(static_cast<void *>(dest), numBytes);
}
void OgreBinarySerializer::ReadBytes(void *dest, size_t numBytes)
{
void OgreBinarySerializer::ReadBytes(void *dest, size_t numBytes) {
m_reader->CopyAndAdvance(dest, numBytes);
}
uint8_t *OgreBinarySerializer::ReadBytes(size_t numBytes)
{
uint8_t *OgreBinarySerializer::ReadBytes(size_t numBytes) {
uint8_t *bytes = new uint8_t[numBytes];
ReadBytes(bytes, numBytes);
return bytes;
}
void OgreBinarySerializer::ReadVector(aiVector3D &vec)
{
void OgreBinarySerializer::ReadVector(aiVector3D &vec) {
m_reader->CopyAndAdvance(&vec.x, sizeof(float) * 3);
}
void OgreBinarySerializer::ReadQuaternion(aiQuaternion &quat)
{
void OgreBinarySerializer::ReadQuaternion(aiQuaternion &quat) {
float temp[4];
m_reader->CopyAndAdvance(temp, sizeof(float) * 4);
quat.x = temp[0];
@ -141,24 +126,20 @@ void OgreBinarySerializer::ReadQuaternion(aiQuaternion &quat)
quat.w = temp[3];
}
bool OgreBinarySerializer::AtEnd() const
{
bool OgreBinarySerializer::AtEnd() const {
return (m_reader->GetRemainingSize() == 0);
}
std::string OgreBinarySerializer::ReadString(size_t len)
{
std::string OgreBinarySerializer::ReadString(size_t len) {
std::string str;
str.resize(len);
ReadBytes(&str[0], len);
return str;
}
std::string OgreBinarySerializer::ReadLine()
{
std::string OgreBinarySerializer::ReadLine() {
std::string str;
while(!AtEnd())
{
while (!AtEnd()) {
char c = Read<char>();
if (c == '\n')
break;
@ -167,30 +148,25 @@ std::string OgreBinarySerializer::ReadLine()
return str;
}
uint16_t OgreBinarySerializer::ReadHeader(bool readLen)
{
uint16_t OgreBinarySerializer::ReadHeader(bool readLen) {
uint16_t id = Read<uint16_t>();
if (readLen)
m_currentLen = Read<uint32_t>();
#if (OGRE_BINARY_SERIALIZER_DEBUG == 1)
if (id != HEADER_CHUNK_ID)
{
ASSIMP_LOG_DEBUG(Formatter::format() << (assetMode == AM_Mesh
? MeshHeaderToString(static_cast<MeshChunkId>(id)) : SkeletonHeaderToString(static_cast<SkeletonChunkId>(id))));
if (id != HEADER_CHUNK_ID) {
ASSIMP_LOG_DEBUG(Formatter::format() << (assetMode == AM_Mesh ? MeshHeaderToString(static_cast<MeshChunkId>(id)) : SkeletonHeaderToString(static_cast<SkeletonChunkId>(id))));
}
#endif
return id;
}
void OgreBinarySerializer::RollbackHeader()
{
void OgreBinarySerializer::RollbackHeader() {
m_reader->IncPtr(-MSTREAM_OVERHEAD_SIZE);
}
void OgreBinarySerializer::SkipBytes(size_t numBytes)
{
void OgreBinarySerializer::SkipBytes(size_t numBytes) {
#if (OGRE_BINARY_SERIALIZER_DEBUG == 1)
ASSIMP_LOG_DEBUG_F("Skipping ", numBytes, " bytes");
#endif
@ -200,8 +176,7 @@ void OgreBinarySerializer::SkipBytes(size_t numBytes)
// Mesh
Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream)
{
Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream) {
OgreBinarySerializer serializer(stream, OgreBinarySerializer::AM_Mesh);
uint16_t id = serializer.ReadHeader(false);
@ -211,20 +186,16 @@ Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream)
/// @todo Check what we can actually support.
std::string version = serializer.ReadLine();
if (version != MESH_VERSION_1_8)
{
if (version != MESH_VERSION_1_8) {
throw DeadlyExportError(Formatter::format() << "Mesh version " << version << " not supported by this importer. Run OgreMeshUpgrader tool on the file and try again."
<< " Supported versions: " << MESH_VERSION_1_8);
}
Mesh *mesh = new Mesh();
while (!serializer.AtEnd())
{
while (!serializer.AtEnd()) {
id = serializer.ReadHeader();
switch(id)
{
case M_MESH:
{
switch (id) {
case M_MESH: {
serializer.ReadMesh(mesh);
break;
}
@ -233,15 +204,13 @@ Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream)
return mesh;
}
void OgreBinarySerializer::ReadMesh(Mesh *mesh)
{
void OgreBinarySerializer::ReadMesh(Mesh *mesh) {
mesh->hasSkeletalAnimations = Read<bool>();
ASSIMP_LOG_DEBUG("Reading Mesh");
ASSIMP_LOG_DEBUG_F(" - Skeletal animations: ", mesh->hasSkeletalAnimations ? "true" : "false");
if (!AtEnd())
{
if (!AtEnd()) {
uint16_t id = ReadHeader();
while (!AtEnd() &&
(id == M_GEOMETRY ||
@ -254,63 +223,50 @@ void OgreBinarySerializer::ReadMesh(Mesh *mesh)
id == M_EDGE_LISTS ||
id == M_POSES ||
id == M_ANIMATIONS ||
id == M_TABLE_EXTREMES))
{
switch(id)
{
case M_GEOMETRY:
{
id == M_TABLE_EXTREMES)) {
switch (id) {
case M_GEOMETRY: {
mesh->sharedVertexData = new VertexData();
ReadGeometry(mesh->sharedVertexData);
break;
}
case M_SUBMESH:
{
case M_SUBMESH: {
ReadSubMesh(mesh);
break;
}
case M_MESH_SKELETON_LINK:
{
case M_MESH_SKELETON_LINK: {
ReadMeshSkeletonLink(mesh);
break;
}
case M_MESH_BONE_ASSIGNMENT:
{
case M_MESH_BONE_ASSIGNMENT: {
ReadBoneAssignment(mesh->sharedVertexData);
break;
}
case M_MESH_LOD:
{
case M_MESH_LOD: {
ReadMeshLodInfo(mesh);
break;
}
case M_MESH_BOUNDS:
{
case M_MESH_BOUNDS: {
ReadMeshBounds(mesh);
break;
}
case M_SUBMESH_NAME_TABLE:
{
case M_SUBMESH_NAME_TABLE: {
ReadSubMeshNames(mesh);
break;
}
case M_EDGE_LISTS:
{
case M_EDGE_LISTS: {
ReadEdgeList(mesh);
break;
}
case M_POSES:
{
case M_POSES: {
ReadPoses(mesh);
break;
}
case M_ANIMATIONS:
{
case M_ANIMATIONS: {
ReadAnimations(mesh);
break;
}
case M_TABLE_EXTREMES:
{
case M_TABLE_EXTREMES: {
ReadMeshExtremes(mesh);
break;
}
@ -326,8 +282,7 @@ void OgreBinarySerializer::ReadMesh(Mesh *mesh)
NormalizeBoneWeights(mesh->sharedVertexData);
}
void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh)
{
void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh) {
// Assimp does not acknowledge LOD levels as far as I can see it. This info is just skipped.
// @todo Put this stuff to scene/mesh custom properties. If manual mesh the app can use the information.
ReadLine(); // strategy name
@ -335,8 +290,7 @@ void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh)
bool manual = Read<bool>();
/// @note Main mesh is considered as LOD 0, start from index 1.
for (size_t i=1; i<numLods; ++i)
{
for (size_t i = 1; i < numLods; ++i) {
uint16_t id = ReadHeader();
if (id != M_MESH_LOD_USAGE) {
throw DeadlyImportError("M_MESH_LOD does not contain a M_MESH_LOD_USAGE for each LOD level");
@ -344,19 +298,15 @@ void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh)
m_reader->IncPtr(sizeof(float)); // user value
if (manual)
{
if (manual) {
id = ReadHeader();
if (id != M_MESH_LOD_MANUAL) {
throw DeadlyImportError("Manual M_MESH_LOD_USAGE does not contain M_MESH_LOD_MANUAL");
}
ReadLine(); // manual mesh name (ref to another mesh)
}
else
{
for(size_t si=0, silen=mesh->NumSubMeshes(); si<silen; ++si)
{
} else {
for (size_t si = 0, silen = mesh->NumSubMeshes(); si < silen; ++si) {
id = ReadHeader();
if (id != M_MESH_LOD_GENERATED) {
throw DeadlyImportError("Generated M_MESH_LOD_USAGE does not contain M_MESH_LOD_GENERATED");
@ -365,8 +315,7 @@ void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh)
uint32_t indexCount = Read<uint32_t>();
bool is32bit = Read<bool>();
if (indexCount > 0)
{
if (indexCount > 0) {
uint32_t len = indexCount * (is32bit ? sizeof(uint32_t) : sizeof(uint16_t));
m_reader->IncPtr(len);
}
@ -375,27 +324,23 @@ void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh)
}
}
void OgreBinarySerializer::ReadMeshSkeletonLink(Mesh *mesh)
{
void OgreBinarySerializer::ReadMeshSkeletonLink(Mesh *mesh) {
mesh->skeletonRef = ReadLine();
}
void OgreBinarySerializer::ReadMeshBounds(Mesh * /*mesh*/)
{
void OgreBinarySerializer::ReadMeshBounds(Mesh * /*mesh*/) {
// Skip bounds, not compatible with Assimp.
// 2x float vec3 + 1x float sphere radius
SkipBytes(sizeof(float) * 7);
}
void OgreBinarySerializer::ReadMeshExtremes(Mesh * /*mesh*/)
{
void OgreBinarySerializer::ReadMeshExtremes(Mesh * /*mesh*/) {
// Skip extremes, not compatible with Assimp.
size_t numBytes = m_currentLen - MSTREAM_OVERHEAD_SIZE;
SkipBytes(numBytes);
}
void OgreBinarySerializer::ReadBoneAssignment(VertexData *dest)
{
void OgreBinarySerializer::ReadBoneAssignment(VertexData *dest) {
if (!dest) {
throw DeadlyImportError("Cannot read bone assignments, vertex data is null.");
}
@ -408,8 +353,7 @@ void OgreBinarySerializer::ReadBoneAssignment(VertexData *dest)
dest->boneAssignments.push_back(ba);
}
void OgreBinarySerializer::ReadSubMesh(Mesh *mesh)
{
void OgreBinarySerializer::ReadSubMesh(Mesh *mesh) {
uint16_t id = 0;
SubMesh *submesh = new SubMesh();
@ -425,8 +369,7 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh)
ASSIMP_LOG_DEBUG_F(" - Uses shared geometry: ", submesh->usesSharedVertexData ? "true" : "false");
// Index buffer
if (submesh->indexData->count > 0)
{
if (submesh->indexData->count > 0) {
uint32_t numBytes = submesh->indexData->count * (submesh->indexData->is32bit ? sizeof(uint32_t) : sizeof(uint16_t));
uint8_t *indexBuffer = ReadBytes(numBytes);
submesh->indexData->buffer = MemoryStreamPtr(new Assimp::MemoryIOStream(indexBuffer, numBytes, true));
@ -437,8 +380,7 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh)
}
// Vertex buffer if not referencing the shared geometry
if (!submesh->usesSharedVertexData)
{
if (!submesh->usesSharedVertexData) {
id = ReadHeader();
if (id != M_GEOMETRY) {
throw DeadlyImportError("M_SUBMESH does not contain M_GEOMETRY, but shader geometry is set to false");
@ -449,28 +391,22 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh)
}
// Bone assignment, submesh operation and texture aliases
if (!AtEnd())
{
if (!AtEnd()) {
id = ReadHeader();
while (!AtEnd() &&
(id == M_SUBMESH_OPERATION ||
id == M_SUBMESH_BONE_ASSIGNMENT ||
id == M_SUBMESH_TEXTURE_ALIAS))
{
switch(id)
{
case M_SUBMESH_OPERATION:
{
id == M_SUBMESH_TEXTURE_ALIAS)) {
switch (id) {
case M_SUBMESH_OPERATION: {
ReadSubMeshOperation(submesh);
break;
}
case M_SUBMESH_BONE_ASSIGNMENT:
{
case M_SUBMESH_BONE_ASSIGNMENT: {
ReadBoneAssignment(submesh->vertexData);
break;
}
case M_SUBMESH_TEXTURE_ALIAS:
{
case M_SUBMESH_TEXTURE_ALIAS: {
ReadSubMeshTextureAlias(submesh);
break;
}
@ -489,8 +425,7 @@ void OgreBinarySerializer::ReadSubMesh(Mesh *mesh)
mesh->subMeshes.push_back(submesh);
}
void OgreBinarySerializer::NormalizeBoneWeights(VertexData *vertexData) const
{
void OgreBinarySerializer::NormalizeBoneWeights(VertexData *vertexData) const {
if (!vertexData || vertexData->boneAssignments.empty())
return;
@ -503,18 +438,14 @@ void OgreBinarySerializer::NormalizeBoneWeights(VertexData *vertexData) const
Some exporters won't care if the sum of all bone weights
for a single vertex equals 1 or not, so validate here. */
const float epsilon = 0.05f;
for (const uint32_t vertexIndex : influencedVertices)
{
for (const uint32_t vertexIndex : influencedVertices) {
float sum = 0.0f;
for (VertexBoneAssignmentList::const_iterator baIter=vertexData->boneAssignments.begin(), baEnd=vertexData->boneAssignments.end(); baIter != baEnd; ++baIter)
{
for (VertexBoneAssignmentList::const_iterator baIter = vertexData->boneAssignments.begin(), baEnd = vertexData->boneAssignments.end(); baIter != baEnd; ++baIter) {
if (baIter->vertexIndex == vertexIndex)
sum += baIter->weight;
}
if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon)))
{
for (auto &boneAssign : vertexData->boneAssignments)
{
if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon))) {
for (auto &boneAssign : vertexData->boneAssignments) {
if (boneAssign.vertexIndex == vertexIndex)
boneAssign.weight /= sum;
}
@ -522,26 +453,21 @@ void OgreBinarySerializer::NormalizeBoneWeights(VertexData *vertexData) const
}
}
void OgreBinarySerializer::ReadSubMeshOperation(SubMesh *submesh)
{
void OgreBinarySerializer::ReadSubMeshOperation(SubMesh *submesh) {
submesh->operationType = static_cast<SubMesh::OperationType>(Read<uint16_t>());
}
void OgreBinarySerializer::ReadSubMeshTextureAlias(SubMesh *submesh)
{
void OgreBinarySerializer::ReadSubMeshTextureAlias(SubMesh *submesh) {
submesh->textureAliasName = ReadLine();
submesh->textureAliasRef = ReadLine();
}
void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh)
{
void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh) {
uint16_t id = 0;
if (!AtEnd())
{
if (!AtEnd()) {
id = ReadHeader();
while (!AtEnd() && id == M_SUBMESH_NAME_TABLE_ELEMENT)
{
while (!AtEnd() && id == M_SUBMESH_NAME_TABLE_ELEMENT) {
uint16_t submeshIndex = Read<uint16_t>();
SubMesh *submesh = mesh->GetSubMesh(submeshIndex);
if (!submesh) {
@ -559,28 +485,22 @@ void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh)
}
}
void OgreBinarySerializer::ReadGeometry(VertexData *dest)
{
void OgreBinarySerializer::ReadGeometry(VertexData *dest) {
dest->count = Read<uint32_t>();
ASSIMP_LOG_DEBUG_F(" - Reading geometry of ", dest->count, " vertices");
if (!AtEnd())
{
if (!AtEnd()) {
uint16_t id = ReadHeader();
while (!AtEnd() &&
(id == M_GEOMETRY_VERTEX_DECLARATION ||
id == M_GEOMETRY_VERTEX_BUFFER))
{
switch(id)
{
case M_GEOMETRY_VERTEX_DECLARATION:
{
id == M_GEOMETRY_VERTEX_BUFFER)) {
switch (id) {
case M_GEOMETRY_VERTEX_DECLARATION: {
ReadGeometryVertexDeclaration(dest);
break;
}
case M_GEOMETRY_VERTEX_BUFFER:
{
case M_GEOMETRY_VERTEX_BUFFER: {
ReadGeometryVertexBuffer(dest);
break;
}
@ -594,13 +514,10 @@ void OgreBinarySerializer::ReadGeometry(VertexData *dest)
}
}
void OgreBinarySerializer::ReadGeometryVertexDeclaration(VertexData *dest)
{
if (!AtEnd())
{
void OgreBinarySerializer::ReadGeometryVertexDeclaration(VertexData *dest) {
if (!AtEnd()) {
uint16_t id = ReadHeader();
while (!AtEnd() && id == M_GEOMETRY_VERTEX_ELEMENT)
{
while (!AtEnd() && id == M_GEOMETRY_VERTEX_ELEMENT) {
ReadGeometryVertexElement(dest);
if (!AtEnd())
@ -611,8 +528,7 @@ void OgreBinarySerializer::ReadGeometryVertexDeclaration(VertexData *dest)
}
}
void OgreBinarySerializer::ReadGeometryVertexElement(VertexData *dest)
{
void OgreBinarySerializer::ReadGeometryVertexElement(VertexData *dest) {
VertexElement element;
element.source = Read<uint16_t>();
element.type = static_cast<VertexElement::Type>(Read<uint16_t>());
@ -626,8 +542,7 @@ void OgreBinarySerializer::ReadGeometryVertexElement(VertexData *dest)
dest->vertexElements.push_back(element);
}
void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest)
{
void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest) {
uint16_t bindIndex = Read<uint16_t>();
uint16_t vertexSize = Read<uint16_t>();
@ -645,20 +560,16 @@ void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest)
ASSIMP_LOG_DEBUG_F(" - Read vertex buffer for source ", bindIndex, " of ", numBytes, " bytes");
}
void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/)
{
void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/) {
// Assimp does not acknowledge LOD levels as far as I can see it. This info is just skipped.
if (!AtEnd())
{
if (!AtEnd()) {
uint16_t id = ReadHeader();
while (!AtEnd() && id == M_EDGE_LIST_LOD)
{
while (!AtEnd() && id == M_EDGE_LIST_LOD) {
m_reader->IncPtr(sizeof(uint16_t)); // lod index
bool manual = Read<bool>();
if (!manual)
{
if (!manual) {
m_reader->IncPtr(sizeof(uint8_t));
uint32_t numTriangles = Read<uint32_t>();
uint32_t numEdgeGroups = Read<uint32_t>();
@ -666,16 +577,14 @@ void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/)
size_t skipBytes = (sizeof(uint32_t) * 8 + sizeof(float) * 4) * numTriangles;
m_reader->IncPtr(skipBytes);
for (size_t i=0; i<numEdgeGroups; ++i)
{
uint16_t id = ReadHeader();
if (id != M_EDGE_GROUP)
for (size_t i = 0; i < numEdgeGroups; ++i) {
uint16_t curId = ReadHeader();
if (curId != M_EDGE_GROUP)
throw DeadlyImportError("M_EDGE_GROUP not found in M_EDGE_LIST_LOD");
m_reader->IncPtr(sizeof(uint32_t) * 3);
uint32_t numEdges = Read<uint32_t>();
for (size_t j=0; j<numEdges; ++j)
{
for (size_t j = 0; j < numEdges; ++j) {
m_reader->IncPtr(sizeof(uint32_t) * 6 + sizeof(uint8_t));
}
}
@ -689,13 +598,10 @@ void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/)
}
}
void OgreBinarySerializer::ReadPoses(Mesh *mesh)
{
if (!AtEnd())
{
void OgreBinarySerializer::ReadPoses(Mesh *mesh) {
if (!AtEnd()) {
uint16_t id = ReadHeader();
while (!AtEnd() && id == M_POSE)
{
while (!AtEnd() && id == M_POSE) {
Pose *pose = new Pose();
pose->name = ReadLine();
pose->target = Read<uint16_t>();
@ -713,13 +619,10 @@ void OgreBinarySerializer::ReadPoses(Mesh *mesh)
}
}
void OgreBinarySerializer::ReadPoseVertices(Pose *pose)
{
if (!AtEnd())
{
void OgreBinarySerializer::ReadPoseVertices(Pose *pose) {
if (!AtEnd()) {
uint16_t id = ReadHeader();
while (!AtEnd() && id == M_POSE_VERTEX)
{
while (!AtEnd() && id == M_POSE_VERTEX) {
Pose::Vertex v;
v.index = Read<uint32_t>();
ReadVector(v.offset);
@ -736,13 +639,10 @@ void OgreBinarySerializer::ReadPoseVertices(Pose *pose)
}
}
void OgreBinarySerializer::ReadAnimations(Mesh *mesh)
{
if (!AtEnd())
{
void OgreBinarySerializer::ReadAnimations(Mesh *mesh) {
if (!AtEnd()) {
uint16_t id = ReadHeader();
while (!AtEnd() && id == M_ANIMATION)
{
while (!AtEnd() && id == M_ANIMATION) {
Animation *anim = new Animation(mesh);
anim->name = ReadLine();
anim->length = Read<float>();
@ -759,13 +659,10 @@ void OgreBinarySerializer::ReadAnimations(Mesh *mesh)
}
}
void OgreBinarySerializer::ReadAnimation(Animation *anim)
{
if (!AtEnd())
{
void OgreBinarySerializer::ReadAnimation(Animation *anim) {
if (!AtEnd()) {
uint16_t id = ReadHeader();
if (id == M_ANIMATION_BASEINFO)
{
if (id == M_ANIMATION_BASEINFO) {
anim->baseName = ReadLine();
anim->baseTime = Read<float>();
@ -773,8 +670,7 @@ void OgreBinarySerializer::ReadAnimation(Animation *anim)
id = ReadHeader();
}
while (!AtEnd() && id == M_ANIMATION_TRACK)
{
while (!AtEnd() && id == M_ANIMATION_TRACK) {
VertexAnimationTrack track;
track.type = static_cast<VertexAnimationTrack::Type>(Read<uint16_t>());
track.target = Read<uint16_t>();
@ -791,17 +687,13 @@ void OgreBinarySerializer::ReadAnimation(Animation *anim)
}
}
void OgreBinarySerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *track)
{
if (!AtEnd())
{
void OgreBinarySerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *track) {
if (!AtEnd()) {
uint16_t id = ReadHeader();
while (!AtEnd() &&
(id == M_ANIMATION_MORPH_KEYFRAME ||
id == M_ANIMATION_POSE_KEYFRAME))
{
if (id == M_ANIMATION_MORPH_KEYFRAME)
{
id == M_ANIMATION_POSE_KEYFRAME)) {
if (id == M_ANIMATION_MORPH_KEYFRAME) {
MorphKeyFrame kf;
kf.timePos = Read<float>();
bool hasNormals = Read<bool>();
@ -814,17 +706,13 @@ void OgreBinarySerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimati
kf.buffer = MemoryStreamPtr(new Assimp::MemoryIOStream(morphBuffer, numBytes, true));
track->morphKeyFrames.push_back(kf);
}
else if (id == M_ANIMATION_POSE_KEYFRAME)
{
} else if (id == M_ANIMATION_POSE_KEYFRAME) {
PoseKeyFrame kf;
kf.timePos = Read<float>();
if (!AtEnd())
{
if (!AtEnd()) {
id = ReadHeader();
while (!AtEnd() && id == M_ANIMATION_POSE_REF)
{
while (!AtEnd() && id == M_ANIMATION_POSE_REF) {
PoseRef pr;
pr.index = Read<uint16_t>();
pr.influence = Read<float>();
@ -850,15 +738,13 @@ void OgreBinarySerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimati
// Skeleton
bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
{
bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh) {
if (!mesh || mesh->skeletonRef.empty())
return false;
// Highly unusual to see in read world cases but support
// binary mesh referencing a XML skeleton file.
if (EndsWith(mesh->skeletonRef, ".skeleton.xml", false))
{
if (EndsWith(mesh->skeletonRef, ".skeleton.xml", false)) {
OgreXmlSerializer::ImportSkeleton(pIOHandler, mesh);
return false;
}
@ -874,8 +760,7 @@ bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *me
return true;
}
bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh)
{
bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh) {
if (!mesh || mesh->skeletonRef.empty())
return false;
@ -890,16 +775,13 @@ bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml
return true;
}
MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename)
{
if (!EndsWith(filename, ".skeleton", false))
{
MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename) {
if (!EndsWith(filename, ".skeleton", false)) {
ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file.");
return MemoryStreamReaderPtr();
}
if (!pIOHandler->Exists(filename))
{
if (!pIOHandler->Exists(filename)) {
ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh.");
return MemoryStreamReaderPtr();
}
@ -912,8 +794,7 @@ MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHand
return MemoryStreamReaderPtr(new MemoryStreamReader(f));
}
void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
{
void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton) {
uint16_t id = ReadHeader(false);
if (id != HEADER_CHUNK_ID) {
throw DeadlyExportError("Invalid Ogre Skeleton file header.");
@ -921,8 +802,7 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
// This deserialization supports both versions of the skeleton spec
std::string version = ReadLine();
if (version != SKELETON_VERSION_1_8 && version != SKELETON_VERSION_1_1)
{
if (version != SKELETON_VERSION_1_8 && version != SKELETON_VERSION_1_1) {
throw DeadlyExportError(Formatter::format() << "Skeleton version " << version << " not supported by this importer."
<< " Supported versions: " << SKELETON_VERSION_1_8 << " and " << SKELETON_VERSION_1_1);
}
@ -932,20 +812,15 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
bool firstBone = true;
bool firstAnim = true;
while (!AtEnd())
{
while (!AtEnd()) {
id = ReadHeader();
switch(id)
{
case SKELETON_BLENDMODE:
{
switch (id) {
case SKELETON_BLENDMODE: {
skeleton->blendMode = static_cast<Skeleton::BlendMode>(Read<uint16_t>());
break;
}
case SKELETON_BONE:
{
if (firstBone)
{
case SKELETON_BONE: {
if (firstBone) {
ASSIMP_LOG_DEBUG(" - Bones");
firstBone = false;
}
@ -953,15 +828,12 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
ReadBone(skeleton);
break;
}
case SKELETON_BONE_PARENT:
{
case SKELETON_BONE_PARENT: {
ReadBoneParent(skeleton);
break;
}
case SKELETON_ANIMATION:
{
if (firstAnim)
{
case SKELETON_ANIMATION: {
if (firstAnim) {
ASSIMP_LOG_DEBUG(" - Animations");
firstAnim = false;
}
@ -969,8 +841,7 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
ReadSkeletonAnimation(skeleton);
break;
}
case SKELETON_ANIMATION_LINK:
{
case SKELETON_ANIMATION_LINK: {
ReadSkeletonAnimationLink(skeleton);
break;
}
@ -978,16 +849,14 @@ void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
}
// Calculate bone matrices for root bones. Recursively calculates their children.
for (size_t i=0, len=skeleton->bones.size(); i<len; ++i)
{
for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
Bone *bone = skeleton->bones[i];
if (!bone->IsParented())
bone->CalculateWorldMatrixAndDefaultPose(skeleton);
}
}
void OgreBinarySerializer::ReadBone(Skeleton *skeleton)
{
void OgreBinarySerializer::ReadBone(Skeleton *skeleton) {
Bone *bone = new Bone();
bone->name = ReadLine();
bone->id = Read<uint16_t>();
@ -1010,8 +879,7 @@ void OgreBinarySerializer::ReadBone(Skeleton *skeleton)
skeleton->bones.push_back(bone);
}
void OgreBinarySerializer::ReadBoneParent(Skeleton *skeleton)
{
void OgreBinarySerializer::ReadBoneParent(Skeleton *skeleton) {
uint16_t childId = Read<uint16_t>();
uint16_t parentId = Read<uint16_t>();
@ -1024,17 +892,14 @@ void OgreBinarySerializer::ReadBoneParent(Skeleton *skeleton)
throw DeadlyImportError(Formatter::format() << "Failed to find bones for parenting: Child id " << childId << " for parent id " << parentId);
}
void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton)
{
void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton) {
Animation *anim = new Animation(skeleton);
anim->name = ReadLine();
anim->length = Read<float>();
if (!AtEnd())
{
if (!AtEnd()) {
uint16_t id = ReadHeader();
if (id == SKELETON_ANIMATION_BASEINFO)
{
if (id == SKELETON_ANIMATION_BASEINFO) {
anim->baseName = ReadLine();
anim->baseTime = Read<float>();
@ -1042,8 +907,7 @@ void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton)
id = ReadHeader();
}
while (!AtEnd() && id == SKELETON_ANIMATION_TRACK)
{
while (!AtEnd() && id == SKELETON_ANIMATION_TRACK) {
ReadSkeletonAnimationTrack(skeleton, anim);
if (!AtEnd())
@ -1058,8 +922,7 @@ void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton)
ASSIMP_LOG_DEBUG_F(" ", anim->name, " (", anim->length, " sec, ", anim->tracks.size(), " tracks)");
}
void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, Animation *dest)
{
void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, Animation *dest) {
uint16_t boneId = Read<uint16_t>();
Bone *bone = dest->parentSkeleton->BoneById(boneId);
if (!bone) {
@ -1071,8 +934,7 @@ void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, A
track.boneName = bone->name;
uint16_t id = ReadHeader();
while (!AtEnd() && id == SKELETON_ANIMATION_TRACK_KEYFRAME)
{
while (!AtEnd() && id == SKELETON_ANIMATION_TRACK_KEYFRAME) {
ReadSkeletonAnimationKeyFrame(&track);
if (!AtEnd())
@ -1084,8 +946,7 @@ void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, A
dest->tracks.push_back(track);
}
void OgreBinarySerializer::ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *dest)
{
void OgreBinarySerializer::ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *dest) {
TransformKeyFrame keyframe;
keyframe.timePos = Read<float>();
@ -1100,14 +961,13 @@ void OgreBinarySerializer::ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *d
dest->transformKeyFrames.push_back(keyframe);
}
void OgreBinarySerializer::ReadSkeletonAnimationLink(Skeleton * /*skeleton*/)
{
void OgreBinarySerializer::ReadSkeletonAnimationLink(Skeleton * /*skeleton*/) {
// Skip bounds, not compatible with Assimp.
ReadLine(); // skeleton name
SkipBytes(sizeof(float) * 3); // scale
}
} // Ogre
} // Assimp
} // namespace Ogre
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER

View File

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

View File

@ -206,8 +206,8 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
aiMaterial *material = new aiMaterial();
m_textures.clear();
aiString ts(materialName);
material->AddProperty(&ts, AI_MATKEY_NAME);
aiString matName(materialName);
material->AddProperty(&matName, AI_MATKEY_NAME);
// The stringstream will push words from a line until newline.
// It will also trim whitespace from line start and between words.
@ -279,14 +279,14 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
else if (linePart=="$colormap")
{
ss >> linePart;
aiString ts(linePart);
material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
aiString cm(linePart);
material->AddProperty(&cm, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
}
else if (linePart=="$normalmap")
{
ss >> linePart;
aiString ts(linePart);
material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
aiString nm(linePart);
material->AddProperty(&nm, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
}
else if (linePart=="$shininess_strength")
{

View File

@ -46,26 +46,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
#include <assimp/ParsingUtils.h>
#include <functional>
#include <algorithm>
#include <stdint.h>
#include <sstream>
#include <algorithm>
#include <cctype>
#include <functional>
#include <sstream>
namespace Assimp {
namespace Ogre {
/// Returns a lower cased copy of @s.
static AI_FORCE_INLINE
std::string ToLower(std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
static AI_FORCE_INLINE std::string ToLower(const std::string &s) {
std::string lower(s);
std::transform(lower.begin(), lower.end(), lower.begin(), Assimp::ToLower<char>);
return lower;
}
/// Returns if @c s ends with @c suffix. If @c caseSensitive is false, both strings will be lower cased before matching.
static AI_FORCE_INLINE
bool EndsWith(const std::string &s, const std::string &suffix, bool caseSensitive = true) {
static AI_FORCE_INLINE bool EndsWith( const std::string &s, const std::string &suffix, bool caseSensitive = true) {
if (s.empty() || suffix.empty()) {
return false;
} else if (s.length() < suffix.length()) {
@ -86,7 +85,8 @@ bool EndsWith(const std::string &s, const std::string &suffix, bool caseSensitiv
/// Trim from start
static AI_FORCE_INLINE
std::string &TrimLeft(std::string &s, bool newlines = true) {
std::string &
TrimLeft(std::string &s, bool newlines = true) {
if (!newlines) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpace<char>(c); }));
} else {
@ -97,7 +97,8 @@ std::string &TrimLeft(std::string &s, bool newlines = true) {
/// Trim from end
static AI_FORCE_INLINE
std::string &TrimRight(std::string &s, bool newlines = true) {
std::string &
TrimRight(std::string &s, bool newlines = true) {
if (!newlines) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](char c) { return !Assimp::IsSpace<char>(c); }).base(), s.end());
} else {
@ -108,13 +109,15 @@ std::string &TrimRight(std::string &s, bool newlines = true) {
/// Trim from both ends
static AI_FORCE_INLINE
std::string &Trim(std::string &s, bool newlines = true) {
std::string &
Trim(std::string &s, bool newlines = true) {
return TrimLeft(TrimRight(s, newlines), newlines);
}
/// Skips a line from current @ss position until a newline. Returns the skipped part.
static AI_FORCE_INLINE
std::string SkipLine(std::stringstream &ss) {
std::string
SkipLine(std::stringstream &ss) {
std::string skipped;
getline(ss, skipped);
return skipped;
@ -123,14 +126,15 @@ std::string SkipLine(std::stringstream &ss) {
/// Skips a line and reads next element from @c ss to @c nextElement.
/** @return Skipped line content until newline. */
static AI_FORCE_INLINE
std::string NextAfterNewLine(std::stringstream &ss, std::string &nextElement) {
std::string
NextAfterNewLine(std::stringstream &ss, std::string &nextElement) {
std::string skipped = SkipLine(ss);
ss >> nextElement;
return skipped;
}
} // Ogre
} // Assimp
} // namespace Ogre
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
#endif // AI_OGREPARSINGUTILS_H_INC

View File

@ -53,140 +53,94 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Define as 1 to get verbose logging.
#define OGRE_XML_SERIALIZER_DEBUG 0
namespace Assimp
{
namespace Ogre
{
namespace Assimp {
namespace Ogre {
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader* reader, const std::string &name, const std::string &error)
{
if (!error.empty())
{
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader *reader, const std::string &name, const std::string &error) {
if (!error.empty()) {
throw DeadlyImportError(error + " in node '" + std::string(reader->getNodeName()) + "' and attribute '" + name + "'");
}
else
{
} else {
throw DeadlyImportError("Attribute '" + name + "' does not exist in node '" + std::string(reader->getNodeName()) + "'");
}
}
template <>
int32_t OgreXmlSerializer::ReadAttribute<int32_t>(const char *name) const
{
if (HasAttribute(name))
{
int32_t OgreXmlSerializer::ReadAttribute<int32_t>(const char *name) const {
if (!HasAttribute(name)) {
ThrowAttibuteError(m_reader, name);
}
return static_cast<int32_t>(m_reader->getAttributeValueAsInt(name));
}
else
{
ThrowAttibuteError(m_reader, name);
return 0;
}
}
template <>
uint32_t OgreXmlSerializer::ReadAttribute<uint32_t>(const char *name) const
{
if (HasAttribute(name))
{
/** @note This is hackish. But we are never expecting unsigned values that go outside the
int32_t range. Just monitor for negative numbers and kill the import. */
int32_t temp = ReadAttribute<int32_t>(name);
if (temp >= 0)
{
return static_cast<uint32_t>(temp);
uint32_t OgreXmlSerializer::ReadAttribute<uint32_t>(const char *name) const {
if (!HasAttribute(name)) {
ThrowAttibuteError(m_reader, name);
}
else
{
// @note This is hackish. But we are never expecting unsigned values that go outside the
// int32_t range. Just monitor for negative numbers and kill the import.
int32_t temp = ReadAttribute<int32_t>(name);
if (temp < 0) {
ThrowAttibuteError(m_reader, name, "Found a negative number value where expecting a uint32_t value");
}
}
else
{
ThrowAttibuteError(m_reader, name);
}
return 0;
return static_cast<uint32_t>(temp);
}
template <>
uint16_t OgreXmlSerializer::ReadAttribute<uint16_t>(const char *name) const
{
if (HasAttribute(name))
{
uint16_t OgreXmlSerializer::ReadAttribute<uint16_t>(const char *name) const {
if (!HasAttribute(name)) {
ThrowAttibuteError(m_reader, name);
}
return static_cast<uint16_t>(ReadAttribute<uint32_t>(name));
}
else
{
ThrowAttibuteError(m_reader, name);
}
return 0;
}
template <>
float OgreXmlSerializer::ReadAttribute<float>(const char *name) const
{
if (HasAttribute(name))
{
float OgreXmlSerializer::ReadAttribute<float>(const char *name) const {
if (!HasAttribute(name)) {
ThrowAttibuteError(m_reader, name);
}
return m_reader->getAttributeValueAsFloat(name);
}
else
{
ThrowAttibuteError(m_reader, name);
return 0;
}
}
template <>
std::string OgreXmlSerializer::ReadAttribute<std::string>(const char *name) const
{
std::string OgreXmlSerializer::ReadAttribute<std::string>(const char *name) const {
const char *value = m_reader->getAttributeValue(name);
if (value)
{
if (nullptr == value) {
ThrowAttibuteError(m_reader, name);
}
return std::string(value);
}
else
{
ThrowAttibuteError(m_reader, name);
return "";
}
}
template <>
bool OgreXmlSerializer::ReadAttribute<bool>(const char *name) const
{
bool OgreXmlSerializer::ReadAttribute<bool>(const char *name) const {
std::string value = Ogre::ToLower(ReadAttribute<std::string>(name));
if (ASSIMP_stricmp(value, "true") == 0)
{
if (ASSIMP_stricmp(value, "true") == 0) {
return true;
}
else if (ASSIMP_stricmp(value, "false") == 0)
{
} else if (ASSIMP_stricmp(value, "false") == 0) {
return false;
}
else
{
} else {
ThrowAttibuteError(m_reader, name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
return false;
}
}
bool OgreXmlSerializer::HasAttribute(const char *name) const
{
bool OgreXmlSerializer::HasAttribute(const char *name) const {
return (m_reader->getAttributeValue(name) != 0);
}
std::string &OgreXmlSerializer::NextNode()
{
do
{
if (!m_reader->read())
{
std::string &OgreXmlSerializer::NextNode() {
do {
if (!m_reader->read()) {
m_currentNodeName = "";
return m_currentNodeName;
}
}
while(m_reader->getNodeType() != irr::io::EXN_ELEMENT);
} while (m_reader->getNodeType() != irr::io::EXN_ELEMENT);
CurrentNodeName(true);
#if (OGRE_XML_SERIALIZER_DEBUG == 1)
@ -195,20 +149,17 @@ std::string &OgreXmlSerializer::NextNode()
return m_currentNodeName;
}
bool OgreXmlSerializer::CurrentNodeNameEquals(const std::string &name) const
{
bool OgreXmlSerializer::CurrentNodeNameEquals(const std::string &name) const {
return (ASSIMP_stricmp(m_currentNodeName, name) == 0);
}
std::string OgreXmlSerializer::CurrentNodeName(bool forceRead)
{
std::string OgreXmlSerializer::CurrentNodeName(bool forceRead) {
if (forceRead)
m_currentNodeName = std::string(m_reader->getNodeName());
return m_currentNodeName;
}
std::string &OgreXmlSerializer::SkipCurrentNode()
{
std::string &OgreXmlSerializer::SkipCurrentNode() {
#if (OGRE_XML_SERIALIZER_DEBUG == 1)
ASSIMP_LOG_DEBUG("Skipping node <" + m_currentNodeName + ">");
#endif
@ -330,26 +281,18 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
m_currentNodeName == nnSubMeshNames ||
m_currentNodeName == nnExtremes ||
m_currentNodeName == nnPoses ||
m_currentNodeName == nnAnimations)
{
if (m_currentNodeName == nnSharedGeometry)
{
m_currentNodeName == nnAnimations) {
if (m_currentNodeName == nnSharedGeometry) {
mesh->sharedVertexData = new VertexDataXml();
ReadGeometry(mesh->sharedVertexData);
}
else if (m_currentNodeName == nnSubMeshes)
{
} else if (m_currentNodeName == nnSubMeshes) {
NextNode();
while (m_currentNodeName == nnSubMesh) {
ReadSubMesh(mesh);
}
}
else if (m_currentNodeName == nnBoneAssignments)
{
} else if (m_currentNodeName == nnBoneAssignments) {
ReadBoneAssignments(mesh->sharedVertexData);
}
else if (m_currentNodeName == nnSkeletonLink)
{
} else if (m_currentNodeName == nnSkeletonLink) {
mesh->skeletonRef = ReadAttribute<std::string>("name");
ASSIMP_LOG_DEBUG_F("Read skeleton link ", mesh->skeletonRef);
NextNode();
@ -360,8 +303,7 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
}
}
void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest)
{
void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest) {
dest->count = ReadAttribute<uint32_t>("vertexcount");
ASSIMP_LOG_DEBUG_F(" - Reading geometry of ", dest->count, " vertices");
@ -371,8 +313,7 @@ void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest)
}
}
void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
{
void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest) {
bool positions = (HasAttribute("positions") && ReadAttribute<bool>("positions"));
bool normals = (HasAttribute("normals") && ReadAttribute<bool>("normals"));
bool tangents = (HasAttribute("tangents") && ReadAttribute<bool>("tangents"));
@ -383,23 +324,19 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
throw DeadlyImportError("Vertex buffer does not contain positions!");
}
if (positions)
{
if (positions) {
ASSIMP_LOG_DEBUG(" - Contains positions");
dest->positions.reserve(dest->count);
}
if (normals)
{
if (normals) {
ASSIMP_LOG_DEBUG(" - Contains normals");
dest->normals.reserve(dest->count);
}
if (tangents)
{
if (tangents) {
ASSIMP_LOG_DEBUG(" - Contains tangents");
dest->tangents.reserve(dest->count);
}
if (uvs > 0)
{
if (uvs > 0) {
ASSIMP_LOG_DEBUG_F(" - Contains ", uvs, " texture coords");
dest->uvs.resize(uvs);
for (size_t i = 0, len = dest->uvs.size(); i < len; ++i) {
@ -420,42 +357,33 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
m_currentNodeName == nnBinormal ||
m_currentNodeName == nnTexCoord ||
m_currentNodeName == nnColorDiffuse ||
m_currentNodeName == nnColorSpecular)
{
m_currentNodeName == nnColorSpecular) {
if (m_currentNodeName == nnVertex) {
NextNode();
}
/// @todo Implement nnBinormal, nnColorDiffuse and nnColorSpecular
if (positions && m_currentNodeName == nnPosition)
{
if (positions && m_currentNodeName == nnPosition) {
aiVector3D pos;
pos.x = ReadAttribute<float>(anX);
pos.y = ReadAttribute<float>(anY);
pos.z = ReadAttribute<float>(anZ);
dest->positions.push_back(pos);
}
else if (normals && m_currentNodeName == nnNormal)
{
} else if (normals && m_currentNodeName == nnNormal) {
aiVector3D normal;
normal.x = ReadAttribute<float>(anX);
normal.y = ReadAttribute<float>(anY);
normal.z = ReadAttribute<float>(anZ);
dest->normals.push_back(normal);
}
else if (tangents && m_currentNodeName == nnTangent)
{
} else if (tangents && m_currentNodeName == nnTangent) {
aiVector3D tangent;
tangent.x = ReadAttribute<float>(anX);
tangent.y = ReadAttribute<float>(anY);
tangent.z = ReadAttribute<float>(anZ);
dest->tangents.push_back(tangent);
}
else if (uvs > 0 && m_currentNodeName == nnTexCoord)
{
for(auto &uvs : dest->uvs)
{
} else if (uvs > 0 && m_currentNodeName == nnTexCoord) {
for (auto &curUvs : dest->uvs) {
if (m_currentNodeName != nnTexCoord) {
throw DeadlyImportError("Vertex buffer declared more UVs than can be found in a vertex");
}
@ -463,47 +391,31 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
aiVector3D uv;
uv.x = ReadAttribute<float>("u");
uv.y = (ReadAttribute<float>("v") * -1) + 1; // Flip UV from Ogre to Assimp form
uvs.push_back(uv);
curUvs.push_back(uv);
NextNode();
}
// Continue main loop as above already read next node
continue;
}
else
{
} else {
/// @todo Remove this stuff once implemented. We only want to log warnings once per element.
bool warn = true;
if (m_currentNodeName == nnBinormal)
{
if (warnBinormal)
{
if (m_currentNodeName == nnBinormal) {
if (warnBinormal) {
warnBinormal = false;
}
else
{
} else {
warn = false;
}
}
else if (m_currentNodeName == nnColorDiffuse)
{
if (warnColorDiffuse)
{
} else if (m_currentNodeName == nnColorDiffuse) {
if (warnColorDiffuse) {
warnColorDiffuse = false;
}
else
{
} else {
warn = false;
}
}
else if (m_currentNodeName == nnColorSpecular)
{
if (warnColorSpecular)
{
} else if (m_currentNodeName == nnColorSpecular) {
if (warnColorSpecular) {
warnColorSpecular = false;
}
else
{
} else {
warn = false;
}
}
@ -526,8 +438,7 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
if (tangents && dest->tangents.size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->tangents.size() << " tangents when should have read " << dest->count);
}
for(unsigned int i=0; i<dest->uvs.size(); ++i)
{
for (unsigned int i = 0; i < dest->uvs.size(); ++i) {
if (dest->uvs[i].size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->uvs[i].size()
<< " uvs for uv index " << i << " when should have read " << dest->count);
@ -535,8 +446,7 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
}
}
void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
{
void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh) {
static const char *anMaterial = "material";
static const char *anUseSharedVertices = "usesharedvertices";
static const char *anCount = "count";
@ -568,16 +478,13 @@ void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
while (m_currentNodeName == nnFaces ||
m_currentNodeName == nnGeometry ||
m_currentNodeName == nnTextures ||
m_currentNodeName == nnBoneAssignments)
{
if (m_currentNodeName == nnFaces)
{
m_currentNodeName == nnBoneAssignments) {
if (m_currentNodeName == nnFaces) {
submesh->indexData->faceCount = ReadAttribute<uint32_t>(anCount);
submesh->indexData->faces.reserve(submesh->indexData->faceCount);
NextNode();
while(m_currentNodeName == nnFace)
{
while (m_currentNodeName == nnFace) {
aiFace face;
face.mNumIndices = 3;
face.mIndices = new unsigned int[3];
@ -622,8 +529,7 @@ void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
mesh->subMeshes.push_back(submesh);
}
void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
{
void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest) {
if (!dest) {
throw DeadlyImportError("Cannot read bone assignments, vertex data is null.");
}
@ -635,8 +541,7 @@ void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
std::set<uint32_t> influencedVertices;
NextNode();
while(m_currentNodeName == nnVertexBoneAssignment)
{
while (m_currentNodeName == nnVertexBoneAssignment) {
VertexBoneAssignment ba;
ba.vertexIndex = ReadAttribute<uint32_t>(anVertexIndex);
ba.boneIndex = ReadAttribute<uint16_t>(anBoneIndex);
@ -652,18 +557,14 @@ void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
Some exporters won't care if the sum of all bone weights
for a single vertex equals 1 or not, so validate here. */
const float epsilon = 0.05f;
for (const uint32_t vertexIndex : influencedVertices)
{
for (const uint32_t vertexIndex : influencedVertices) {
float sum = 0.0f;
for (VertexBoneAssignmentList::const_iterator baIter=dest->boneAssignments.begin(), baEnd=dest->boneAssignments.end(); baIter != baEnd; ++baIter)
{
for (VertexBoneAssignmentList::const_iterator baIter = dest->boneAssignments.begin(), baEnd = dest->boneAssignments.end(); baIter != baEnd; ++baIter) {
if (baIter->vertexIndex == vertexIndex)
sum += baIter->weight;
}
if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon)))
{
for (auto &boneAssign : dest->boneAssignments)
{
if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon))) {
for (auto &boneAssign : dest->boneAssignments) {
if (boneAssign.vertexIndex == vertexIndex)
boneAssign.weight /= sum;
}
@ -675,15 +576,13 @@ void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
// Skeleton
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh)
{
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh) {
if (!mesh || mesh->skeletonRef.empty())
return false;
// Highly unusual to see in read world cases but support
// XML mesh referencing a binary skeleton file.
if (EndsWith(mesh->skeletonRef, ".skeleton", false))
{
if (EndsWith(mesh->skeletonRef, ".skeleton", false)) {
if (OgreBinarySerializer::ImportSkeleton(pIOHandler, mesh))
return true;
@ -705,8 +604,7 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *me
return true;
}
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
{
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh) {
if (!mesh || mesh->skeletonRef.empty())
return false;
@ -721,16 +619,13 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
return true;
}
XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename)
{
if (!EndsWith(filename, ".skeleton.xml", false))
{
XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename) {
if (!EndsWith(filename, ".skeleton.xml", false)) {
ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file.");
return XmlReaderPtr();
}
if (!pIOHandler->Exists(filename))
{
if (!pIOHandler->Exists(filename)) {
ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh.");
return XmlReaderPtr();
}
@ -748,8 +643,7 @@ XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const s
return reader;
}
void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
{
void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton) {
if (NextNode() != nnSkeleton) {
throw DeadlyImportError("Root node is <" + m_currentNodeName + "> expecting <skeleton>");
}
@ -758,8 +652,7 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
// Optional blend mode from root node
if (HasAttribute("blendmode")) {
skeleton->blendMode = (ToLower(ReadAttribute<std::string>("blendmode")) == "cumulative"
? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
skeleton->blendMode = (ToLower(ReadAttribute<std::string>("blendmode")) == "cumulative" ? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
}
NextNode();
@ -768,8 +661,7 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
while (m_currentNodeName == nnBones ||
m_currentNodeName == nnBoneHierarchy ||
m_currentNodeName == nnAnimations ||
m_currentNodeName == nnAnimationLinks)
{
m_currentNodeName == nnAnimationLinks) {
if (m_currentNodeName == nnBones)
ReadBones(skeleton);
else if (m_currentNodeName == nnBoneHierarchy)
@ -781,8 +673,7 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
}
}
void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
{
void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton) {
if (skeleton->bones.empty()) {
throw DeadlyImportError("Cannot read <animations> for a Skeleton without bones");
}
@ -790,8 +681,7 @@ void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
ASSIMP_LOG_DEBUG(" - Animations");
NextNode();
while(m_currentNodeName == nnAnimation)
{
while (m_currentNodeName == nnAnimation) {
Animation *anim = new Animation(skeleton);
anim->name = ReadAttribute<std::string>("name");
anim->length = ReadAttribute<float>("length");
@ -807,11 +697,9 @@ void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
}
}
void OgreXmlSerializer::ReadAnimationTracks(Animation *dest)
{
void OgreXmlSerializer::ReadAnimationTracks(Animation *dest) {
NextNode();
while(m_currentNodeName == nnTrack)
{
while (m_currentNodeName == nnTrack) {
VertexAnimationTrack track;
track.type = VertexAnimationTrack::VAT_TRANSFORM;
track.boneName = ReadAttribute<std::string>("bone");
@ -826,27 +714,21 @@ void OgreXmlSerializer::ReadAnimationTracks(Animation *dest)
}
}
void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *dest)
{
void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *dest) {
const aiVector3D zeroVec(0.f, 0.f, 0.f);
NextNode();
while(m_currentNodeName == nnKeyFrame)
{
while (m_currentNodeName == nnKeyFrame) {
TransformKeyFrame keyframe;
keyframe.timePos = ReadAttribute<float>("time");
NextNode();
while(m_currentNodeName == nnTranslate || m_currentNodeName == nnRotate || m_currentNodeName == nnScale)
{
if (m_currentNodeName == nnTranslate)
{
while (m_currentNodeName == nnTranslate || m_currentNodeName == nnRotate || m_currentNodeName == nnScale) {
if (m_currentNodeName == nnTranslate) {
keyframe.position.x = ReadAttribute<float>(anX);
keyframe.position.y = ReadAttribute<float>(anY);
keyframe.position.z = ReadAttribute<float>(anZ);
}
else if (m_currentNodeName == nnRotate)
{
} else if (m_currentNodeName == nnRotate) {
float angle = ReadAttribute<float>("angle");
if (NextNode() != nnAxis) {
@ -857,17 +739,14 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationT
axis.x = ReadAttribute<float>(anX);
axis.y = ReadAttribute<float>(anY);
axis.z = ReadAttribute<float>(anZ);
if (axis.Equal(zeroVec))
{
if (axis.Equal(zeroVec)) {
axis.x = 1.0f;
if (angle != 0) {
ASSIMP_LOG_WARN_F("Found invalid a key frame with a zero rotation axis in animation: ", anim->name);
}
}
keyframe.rotation = aiQuaternion(axis, angle);
}
else if (m_currentNodeName == nnScale)
{
} else if (m_currentNodeName == nnScale) {
keyframe.scale.x = ReadAttribute<float>(anX);
keyframe.scale.y = ReadAttribute<float>(anY);
keyframe.scale.z = ReadAttribute<float>(anZ);
@ -880,14 +759,12 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationT
}
}
void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton)
{
void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton) {
if (skeleton->bones.empty()) {
throw DeadlyImportError("Cannot read <bonehierarchy> for a Skeleton without bones");
}
while(NextNode() == nnBoneParent)
{
while (NextNode() == nnBoneParent) {
const std::string name = ReadAttribute<std::string>("bone");
const std::string parentName = ReadAttribute<std::string>("parent");
@ -901,29 +778,25 @@ void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton)
}
// Calculate bone matrices for root bones. Recursively calculates their children.
for (size_t i=0, len=skeleton->bones.size(); i<len; ++i)
{
for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
Bone *bone = skeleton->bones[i];
if (!bone->IsParented())
bone->CalculateWorldMatrixAndDefaultPose(skeleton);
}
}
static bool BoneCompare(Bone *a, Bone *b)
{
static bool BoneCompare(Bone *a, Bone *b) {
ai_assert(nullptr != a);
ai_assert(nullptr != b);
return (a->id < b->id);
}
void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
{
void OgreXmlSerializer::ReadBones(Skeleton *skeleton) {
ASSIMP_LOG_DEBUG(" - Bones");
NextNode();
while(m_currentNodeName == nnBone)
{
while (m_currentNodeName == nnBone) {
Bone *bone = new Bone();
bone->id = ReadAttribute<uint16_t>("id");
bone->name = ReadAttribute<std::string>("name");
@ -931,16 +804,12 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
NextNode();
while (m_currentNodeName == nnPosition ||
m_currentNodeName == nnRotation ||
m_currentNodeName == nnScale)
{
if (m_currentNodeName == nnPosition)
{
m_currentNodeName == nnScale) {
if (m_currentNodeName == nnPosition) {
bone->position.x = ReadAttribute<float>(anX);
bone->position.y = ReadAttribute<float>(anY);
bone->position.z = ReadAttribute<float>(anZ);
}
else if (m_currentNodeName == nnRotation)
{
} else if (m_currentNodeName == nnRotation) {
float angle = ReadAttribute<float>("angle");
if (NextNode() != nnAxis) {
@ -953,17 +822,12 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
axis.z = ReadAttribute<float>(anZ);
bone->rotation = aiQuaternion(axis, angle);
}
else if (m_currentNodeName == nnScale)
{
} else if (m_currentNodeName == nnScale) {
/// @todo Implement taking scale into account in matrix/pose calculations!
if (HasAttribute("factor"))
{
if (HasAttribute("factor")) {
float factor = ReadAttribute<float>("factor");
bone->scale.Set(factor, factor, factor);
}
else
{
} else {
if (HasAttribute(anX))
bone->scale.x = ReadAttribute<float>(anX);
if (HasAttribute(anY))
@ -985,8 +849,7 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
// Validate that bone indexes are not skipped.
/** @note Left this from original authors code, but not sure if this is strictly necessary
as per the Ogre skeleton spec. It might be more that other (later) code in this imported does not break. */
for (size_t i=0, len=skeleton->bones.size(); i<len; ++i)
{
for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
Bone *b = skeleton->bones[i];
ASSIMP_LOG_DEBUG_F(" ", b->id, " ", b->name);
@ -996,7 +859,7 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
}
}
} // Ogre
} // Assimp
} // namespace Ogre
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER

View File

@ -1212,8 +1212,8 @@ void OpenGEXImporter::resolveReferences() {
if( RefInfo::MeshRef == currentRefInfo->m_type ) {
for( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) {
const std::string &name( currentRefInfo->m_Names[ i ] );
ReferenceMap::const_iterator it( m_mesh2refMap.find( name ) );
if( m_mesh2refMap.end() != it ) {
ReferenceMap::const_iterator curIt( m_mesh2refMap.find( name ) );
if (m_mesh2refMap.end() != curIt) {
unsigned int meshIdx = static_cast<unsigned int>(m_mesh2refMap[ name ]);
node->mMeshes[ i ] = meshIdx;
}
@ -1221,8 +1221,8 @@ void OpenGEXImporter::resolveReferences() {
} else if( RefInfo::MaterialRef == currentRefInfo->m_type ) {
for ( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) {
const std::string name( currentRefInfo->m_Names[ i ] );
ReferenceMap::const_iterator it( m_material2refMap.find( name ) );
if ( m_material2refMap.end() != it ) {
ReferenceMap::const_iterator curIt(m_material2refMap.find(name));
if (m_material2refMap.end() != curIt) {
if ( nullptr != m_currentMesh ) {
unsigned int matIdx = static_cast< unsigned int >( m_material2refMap[ name ] );
if ( m_currentMesh->mMaterialIndex != 0 ) {

View File

@ -5,7 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -49,10 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers
#include "PlyLoader.h"
#include <assimp/IOStreamBuffer.h>
#include <memory>
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <memory>
using namespace ::Assimp;
@ -69,29 +68,27 @@ static const aiImporterDesc desc = {
"ply"
};
// ------------------------------------------------------------------------------------------------
// Internal stuff
namespace {
// ------------------------------------------------------------------------------------------------
// Checks that property index is within range
template <class T>
inline
const T &GetProperty(const std::vector<T> &props, int idx) {
inline const T &GetProperty(const std::vector<T> &props, int idx) {
if (static_cast<size_t>(idx) >= props.size()) {
throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
}
return props[idx];
}
}
} // namespace
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
PLYImporter::PLYImporter()
: mBuffer(nullptr)
, pcDOM(nullptr)
, mGeneratedMesh(nullptr) {
PLYImporter::PLYImporter() :
mBuffer(nullptr),
pcDOM(nullptr),
mGeneratedMesh(nullptr) {
// empty
}
@ -108,11 +105,15 @@ bool PLYImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool c
if (extension == "ply") {
return true;
} else if (!extension.length() || checkSig) {
}
if (!extension.length() || checkSig) {
if (!pIOHandler) {
return true;
}
static const char* tokens[] = { "ply" };
static const char *tokens[] = {
"ply"
};
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
@ -397,19 +398,25 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
bool haveColor = false;
if (0xFFFFFFFF != aiColors[0]) {
cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[0]).avList.front(), aiColorsTypes[0]);
aiColors[0])
.avList.front(),
aiColorsTypes[0]);
haveColor = true;
}
if (0xFFFFFFFF != aiColors[1]) {
cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[1]).avList.front(), aiColorsTypes[1]);
aiColors[1])
.avList.front(),
aiColorsTypes[1]);
haveColor = true;
}
if (0xFFFFFFFF != aiColors[2]) {
cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[2]).avList.front(), aiColorsTypes[2]);
aiColors[2])
.avList.front(),
aiColorsTypes[2]);
haveColor = true;
}
@ -418,7 +425,9 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
cOut.a = 1.0;
} else {
cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[3]).avList.front(), aiColorsTypes[3]);
aiColors[3])
.avList.front(),
aiColorsTypes[3]);
haveColor = true;
}
@ -474,7 +483,6 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
}
}
// ------------------------------------------------------------------------------------------------
// Convert a color component to [0...1]
ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val, PLY::EDataType eType) {
@ -684,44 +692,50 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance> &avList,
unsigned int aiPositions[4],
PLY::EDataType aiTypes[4],
aiColor4D* clrOut)
{
aiColor4D *clrOut) {
ai_assert(NULL != clrOut);
if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
else
{
if (0xFFFFFFFF == aiPositions[0])
clrOut->r = 0.0f;
else {
clrOut->r = NormalizeColorValue(GetProperty(avList,
aiPositions[0]).avList.front(), aiTypes[0]);
aiPositions[0])
.avList.front(),
aiTypes[0]);
}
if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
else
{
if (0xFFFFFFFF == aiPositions[1])
clrOut->g = 0.0f;
else {
clrOut->g = NormalizeColorValue(GetProperty(avList,
aiPositions[1]).avList.front(), aiTypes[1]);
aiPositions[1])
.avList.front(),
aiTypes[1]);
}
if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
else
{
if (0xFFFFFFFF == aiPositions[2])
clrOut->b = 0.0f;
else {
clrOut->b = NormalizeColorValue(GetProperty(avList,
aiPositions[2]).avList.front(), aiTypes[2]);
aiPositions[2])
.avList.front(),
aiTypes[2]);
}
// assume 1.0 for the alpha channel ifit is not set
if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
else
{
if (0xFFFFFFFF == aiPositions[3])
clrOut->a = 1.0f;
else {
clrOut->a = NormalizeColorValue(GetProperty(avList,
aiPositions[3]).avList.front(), aiTypes[3]);
aiPositions[3])
.avList.front(),
aiTypes[3]);
}
}
// ------------------------------------------------------------------------------------------------
// Extract a material from the PLY DOM
void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &defaultTexture, const bool pointsOnly)
{
void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &defaultTexture, const bool pointsOnly) {
ai_assert(NULL != pvOut);
// diffuse[4], specular[4], ambient[4]
@ -749,102 +763,74 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
// search in the DOM for a vertex entry
unsigned int _i = 0;
for (std::vector<PLY::Element>::const_iterator i = this->pcDOM->alElements.begin();
i != this->pcDOM->alElements.end(); ++i, ++_i)
{
if (PLY::EEST_Material == (*i).eSemantic)
{
i != this->pcDOM->alElements.end(); ++i, ++_i) {
if (PLY::EEST_Material == (*i).eSemantic) {
pcList = &this->pcDOM->alElementData[_i];
// now check whether which coordinate sets are available
unsigned int _a = 0;
for (std::vector<PLY::Property>::const_iterator
a = (*i).alProperties.begin();
a != (*i).alProperties.end(); ++a, ++_a)
{
a != (*i).alProperties.end(); ++a, ++_a) {
if ((*a).bIsList) continue;
// pohng specularity -----------------------------------
if (PLY::EST_PhongPower == (*a).Semantic)
{
if (PLY::EST_PhongPower == (*a).Semantic) {
iPhong = _a;
ePhong = (*a).eType;
}
// general opacity -----------------------------------
if (PLY::EST_Opacity == (*a).Semantic)
{
if (PLY::EST_Opacity == (*a).Semantic) {
iOpacity = _a;
eOpacity = (*a).eType;
}
// diffuse color channels -----------------------------------
if (PLY::EST_DiffuseRed == (*a).Semantic)
{
if (PLY::EST_DiffuseRed == (*a).Semantic) {
aaiPositions[0][0] = _a;
aaiTypes[0][0] = (*a).eType;
}
else if (PLY::EST_DiffuseGreen == (*a).Semantic)
{
} else if (PLY::EST_DiffuseGreen == (*a).Semantic) {
aaiPositions[0][1] = _a;
aaiTypes[0][1] = (*a).eType;
}
else if (PLY::EST_DiffuseBlue == (*a).Semantic)
{
} else if (PLY::EST_DiffuseBlue == (*a).Semantic) {
aaiPositions[0][2] = _a;
aaiTypes[0][2] = (*a).eType;
}
else if (PLY::EST_DiffuseAlpha == (*a).Semantic)
{
} else if (PLY::EST_DiffuseAlpha == (*a).Semantic) {
aaiPositions[0][3] = _a;
aaiTypes[0][3] = (*a).eType;
}
// specular color channels -----------------------------------
else if (PLY::EST_SpecularRed == (*a).Semantic)
{
else if (PLY::EST_SpecularRed == (*a).Semantic) {
aaiPositions[1][0] = _a;
aaiTypes[1][0] = (*a).eType;
}
else if (PLY::EST_SpecularGreen == (*a).Semantic)
{
} else if (PLY::EST_SpecularGreen == (*a).Semantic) {
aaiPositions[1][1] = _a;
aaiTypes[1][1] = (*a).eType;
}
else if (PLY::EST_SpecularBlue == (*a).Semantic)
{
} else if (PLY::EST_SpecularBlue == (*a).Semantic) {
aaiPositions[1][2] = _a;
aaiTypes[1][2] = (*a).eType;
}
else if (PLY::EST_SpecularAlpha == (*a).Semantic)
{
} else if (PLY::EST_SpecularAlpha == (*a).Semantic) {
aaiPositions[1][3] = _a;
aaiTypes[1][3] = (*a).eType;
}
// ambient color channels -----------------------------------
else if (PLY::EST_AmbientRed == (*a).Semantic)
{
else if (PLY::EST_AmbientRed == (*a).Semantic) {
aaiPositions[2][0] = _a;
aaiTypes[2][0] = (*a).eType;
}
else if (PLY::EST_AmbientGreen == (*a).Semantic)
{
} else if (PLY::EST_AmbientGreen == (*a).Semantic) {
aaiPositions[2][1] = _a;
aaiTypes[2][1] = (*a).eType;
}
else if (PLY::EST_AmbientBlue == (*a).Semantic)
{
} else if (PLY::EST_AmbientBlue == (*a).Semantic) {
aaiPositions[2][2] = _a;
aaiTypes[2][2] = (*a).eType;
}
else if (PLY::EST_AmbientAlpha == (*a).Semantic)
{
} else if (PLY::EST_AmbientAlpha == (*a).Semantic) {
aaiPositions[2][3] = _a;
aaiTypes[2][3] = (*a).eType;
}
}
break;
}
else if (PLY::EEST_TextureFile == (*i).eSemantic)
{
} else if (PLY::EEST_TextureFile == (*i).eSemantic) {
defaultTexture = (*i).szName;
}
}
@ -895,21 +881,17 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
//default texture
if (!defaultTexture.empty())
{
if (!defaultTexture.empty()) {
const aiString name(defaultTexture.c_str());
pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
}
if (!pointsOnly)
{
const int two_sided = 1;
if (!pointsOnly) {
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
}
//set to wireframe, so when using this material info we can switch to points rendering
if (pointsOnly)
{
if (pointsOnly) {
const int wireframe = 1;
pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
}
@ -917,9 +899,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
// add the newly created material instance to the list
pvOut->push_back(pcHelper);
}
}
else
{
} else {
// generate a default material
aiMaterial *pcHelper = new aiMaterial();
@ -938,22 +918,19 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
// The face order is absolutely undefined for PLY, so we have to
// use two-sided rendering to be sure it's ok.
if (!pointsOnly)
{
if (!pointsOnly) {
const int two_sided = 1;
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
}
//default texture
if (!defaultTexture.empty())
{
if (!defaultTexture.empty()) {
const aiString name(defaultTexture.c_str());
pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
}
//set to wireframe, so when using this material info we can switch to points rendering
if (pointsOnly)
{
if (pointsOnly) {
const int wireframe = 1;
pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
}

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -46,9 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_PLYLOADER_H_INCLUDED
#define AI_PLYLOADER_H_INCLUDED
#include "PlyParser.h"
#include <assimp/BaseImporter.h>
#include <assimp/types.h>
#include "PlyParser.h"
#include <vector>
struct aiNode;
@ -62,14 +61,11 @@ using namespace PLY;
// ---------------------------------------------------------------------------
/** Importer class to load the stanford PLY file format
*/
class PLYImporter : public BaseImporter
{
class PLYImporter : public BaseImporter {
public:
PLYImporter();
~PLYImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
@ -88,7 +84,6 @@ public:
void LoadFace(const PLY::Element *pcElement, const PLY::ElementInstance *instElement, unsigned int pos);
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
@ -102,7 +97,6 @@ protected:
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
protected:
// -------------------------------------------------------------------
/** Extract a material list from the DOM
*/

View File

@ -62,7 +62,7 @@ bool ArmaturePopulate::IsActive(unsigned int pFlags) const {
return (pFlags & aiProcess_PopulateArmatureData) != 0;
}
void ArmaturePopulate::SetupProperties(const Importer *pImp) {
void ArmaturePopulate::SetupProperties(const Importer *) {
// do nothing
}
@ -162,9 +162,9 @@ void ArmaturePopulate::BuildNodeList(const aiNode *current_node,
// A bone stack allows us to have multiple armatures, with the same bone names
// A bone stack allows us also to retrieve bones true transform even with
// duplicate names :)
void ArmaturePopulate::BuildBoneStack(aiNode *current_node,
void ArmaturePopulate::BuildBoneStack(aiNode *,
const aiNode *root_node,
const aiScene *scene,
const aiScene*,
const std::vector<aiBone *> &bones,
std::map<aiBone *, aiNode *> &bone_stack,
std::vector<aiNode *> &node_stack) {

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