Merge branch 'enable_vs_warning_all' of https://github.com/assimp/assimp into enable_vs_warning_all

pull/3012/head
kimkulling 2020-03-11 10:15:25 +01:00
commit 69551e81ed
12 changed files with 375 additions and 436 deletions

View File

@ -155,12 +155,14 @@ void LWOImporter::InternReadFile(const std::string &pFile,
// Allocate storage and copy the contents of the file to a memory buffer // Allocate storage and copy the contents of the file to a memory buffer
std::vector<uint8_t> mBuffer(fileSize); std::vector<uint8_t> mBuffer(fileSize);
file->Read(&mBuffer[0], 1, fileSize); file->Read(&mBuffer[0], 1, fileSize);
this->mScene = pScene; mScene = pScene;
// Determine the type of the file // Determine the type of the file
uint32_t fileType; uint32_t fileType;
const char *sz = IFF::ReadHeader(&mBuffer[0], fileType); const char *sz = IFF::ReadHeader(&mBuffer[0], fileType);
if (sz) throw DeadlyImportError(sz); if (sz) {
throw DeadlyImportError(sz);
}
mFileBuffer = &mBuffer[0] + 12; mFileBuffer = &mBuffer[0] + 12;
fileSize -= 12; fileSize -= 12;
@ -194,18 +196,15 @@ void LWOImporter::InternReadFile(const std::string &pFile,
mIsLWO2 = false; mIsLWO2 = false;
mIsLXOB = false; mIsLXOB = false;
LoadLWOBFile(); LoadLWOBFile();
} } else if (AI_LWO_FOURCC_LWO2 == fileType) {
// New lightwave format // New lightwave format
else if (AI_LWO_FOURCC_LWO2 == fileType) {
mIsLXOB = false; mIsLXOB = false;
ASSIMP_LOG_INFO("LWO file format: LWO2 (>= LightWave 6)"); ASSIMP_LOG_INFO("LWO file format: LWO2 (>= LightWave 6)");
} } else if (AI_LWO_FOURCC_LXOB == fileType) {
// MODO file format // MODO file format
else if (AI_LWO_FOURCC_LXOB == fileType) {
mIsLXOB = true; mIsLXOB = true;
ASSIMP_LOG_INFO("LWO file format: LXOB (Modo)"); ASSIMP_LOG_INFO("LWO file format: LXOB (Modo)");
} }
// we don't know this format
else { else {
char szBuff[5]; char szBuff[5];
szBuff[0] = (char)(fileType >> 24u); szBuff[0] = (char)(fileType >> 24u);
@ -421,7 +420,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
// Compute normal vectors for the mesh - we can't use our GenSmoothNormal- // Compute normal vectors for the mesh - we can't use our GenSmoothNormal-
// Step here since it wouldn't handle smoothing groups correctly for LWO. // Step here since it wouldn't handle smoothing groups correctly for LWO.
// So we use a separate implementation. // So we use a separate implementation.
ComputeNormals(mesh, smoothingGroups, _mSurfaces[i]); ComputeNormals(mesh, smoothingGroups, _mSurfaces[j]);
} else { } else {
ASSIMP_LOG_DEBUG("LWO2: No need to compute normals, they're already there"); ASSIMP_LOG_DEBUG("LWO2: No need to compute normals, they're already there");
} }

View File

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

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -96,7 +95,7 @@ glTF2Importer::glTF2Importer() :
BaseImporter(), BaseImporter(),
meshOffsets(), meshOffsets(),
embeddedTexIdxs(), embeddedTexIdxs(),
mScene(NULL) { mScene(nullptr) {
// empty // empty
} }

View File

@ -51,11 +51,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_ANIM_H_INC #define AI_ANIM_H_INC
#ifdef __GNUC__ #ifdef __GNUC__
# pragma GCC system_header #pragma GCC system_header
#endif #endif
#include <assimp/types.h>
#include <assimp/quaternion.h> #include <assimp/quaternion.h>
#include <assimp/types.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -63,8 +63,7 @@ extern "C" {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** A time-value pair specifying a certain 3D vector for the given time. */ /** A time-value pair specifying a certain 3D vector for the given time. */
struct aiVectorKey struct aiVectorKey {
{
/** The time of this key */ /** The time of this key */
double mTime; double mTime;
@ -75,34 +74,33 @@ struct aiVectorKey
/// @brief The default constructor. /// @brief The default constructor.
aiVectorKey() AI_NO_EXCEPT aiVectorKey() AI_NO_EXCEPT
: mTime( 0.0 ) : mTime(0.0),
, mValue() { mValue() {
// empty // empty
} }
/// @brief Construction from a given time and key value. /// @brief Construction from a given time and key value.
aiVectorKey(double time, const aiVector3D& value) aiVectorKey(double time, const aiVector3D &value) :
: mTime( time ) mTime(time), mValue(value) {
, mValue( value ) {
// empty // empty
} }
typedef aiVector3D elem_type; typedef aiVector3D elem_type;
// Comparison operators. For use with std::find(); // Comparison operators. For use with std::find();
bool operator == (const aiVectorKey& rhs) const { bool operator==(const aiVectorKey &rhs) const {
return rhs.mValue == this->mValue; return rhs.mValue == this->mValue;
} }
bool operator != (const aiVectorKey& rhs ) const { bool operator!=(const aiVectorKey &rhs) const {
return rhs.mValue != this->mValue; return rhs.mValue != this->mValue;
} }
// Relational operators. For use with std::sort(); // Relational operators. For use with std::sort();
bool operator < (const aiVectorKey& rhs ) const { bool operator<(const aiVectorKey &rhs) const {
return mTime < rhs.mTime; return mTime < rhs.mTime;
} }
bool operator > (const aiVectorKey& rhs ) const { bool operator>(const aiVectorKey &rhs) const {
return mTime > rhs.mTime; return mTime > rhs.mTime;
} }
#endif // __cplusplus #endif // __cplusplus
@ -111,8 +109,7 @@ struct aiVectorKey
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** A time-value pair specifying a rotation for the given time. /** A time-value pair specifying a rotation for the given time.
* Rotations are expressed with quaternions. */ * Rotations are expressed with quaternions. */
struct aiQuatKey struct aiQuatKey {
{
/** The time of this key */ /** The time of this key */
double mTime; double mTime;
@ -121,32 +118,30 @@ struct aiQuatKey
#ifdef __cplusplus #ifdef __cplusplus
aiQuatKey() AI_NO_EXCEPT aiQuatKey() AI_NO_EXCEPT
: mTime( 0.0 ) : mTime(0.0),
, mValue() { mValue() {
// empty // empty
} }
/** Construction from a given time and key value */ /** Construction from a given time and key value */
aiQuatKey(double time, const aiQuaternion& value) aiQuatKey(double time, const aiQuaternion &value) :
: mTime (time) mTime(time), mValue(value) {}
, mValue (value)
{}
typedef aiQuaternion elem_type; typedef aiQuaternion elem_type;
// Comparison operators. For use with std::find(); // Comparison operators. For use with std::find();
bool operator == (const aiQuatKey& rhs ) const { bool operator==(const aiQuatKey &rhs) const {
return rhs.mValue == this->mValue; return rhs.mValue == this->mValue;
} }
bool operator != (const aiQuatKey& rhs ) const { bool operator!=(const aiQuatKey &rhs) const {
return rhs.mValue != this->mValue; return rhs.mValue != this->mValue;
} }
// Relational operators. For use with std::sort(); // Relational operators. For use with std::sort();
bool operator < (const aiQuatKey& rhs ) const { bool operator<(const aiQuatKey &rhs) const {
return mTime < rhs.mTime; return mTime < rhs.mTime;
} }
bool operator > (const aiQuatKey& rhs ) const { bool operator>(const aiQuatKey &rhs) const {
return mTime > rhs.mTime; return mTime > rhs.mTime;
} }
#endif #endif
@ -154,8 +149,7 @@ struct aiQuatKey
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Binds a anim-mesh to a specific point in time. */ /** Binds a anim-mesh to a specific point in time. */
struct aiMeshKey struct aiMeshKey {
{
/** The time of this key */ /** The time of this key */
double mTime; double mTime;
@ -168,32 +162,29 @@ struct aiMeshKey
#ifdef __cplusplus #ifdef __cplusplus
aiMeshKey() AI_NO_EXCEPT aiMeshKey() AI_NO_EXCEPT
: mTime(0.0) : mTime(0.0),
, mValue(0) mValue(0) {
{
} }
/** Construction from a given time and key value */ /** Construction from a given time and key value */
aiMeshKey(double time, const unsigned int value) aiMeshKey(double time, const unsigned int value) :
: mTime (time) mTime(time), mValue(value) {}
, mValue (value)
{}
typedef unsigned int elem_type; typedef unsigned int elem_type;
// Comparison operators. For use with std::find(); // Comparison operators. For use with std::find();
bool operator == (const aiMeshKey& o) const { bool operator==(const aiMeshKey &o) const {
return o.mValue == this->mValue; return o.mValue == this->mValue;
} }
bool operator != (const aiMeshKey& o) const { bool operator!=(const aiMeshKey &o) const {
return o.mValue != this->mValue; return o.mValue != this->mValue;
} }
// Relational operators. For use with std::sort(); // Relational operators. For use with std::sort();
bool operator < (const aiMeshKey& o) const { bool operator<(const aiMeshKey &o) const {
return mTime < o.mTime; return mTime < o.mTime;
} }
bool operator > (const aiMeshKey& o) const { bool operator>(const aiMeshKey &o) const {
return mTime > o.mTime; return mTime > o.mTime;
} }
@ -202,8 +193,7 @@ struct aiMeshKey
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Binds a morph anim mesh to a specific point in time. */ /** Binds a morph anim mesh to a specific point in time. */
struct aiMeshMorphKey struct aiMeshMorphKey {
{
/** The time of this key */ /** The time of this key */
double mTime; double mTime;
@ -214,20 +204,17 @@ struct aiMeshMorphKey
/** The number of values and weights */ /** The number of values and weights */
unsigned int mNumValuesAndWeights; unsigned int mNumValuesAndWeights;
#ifdef __cplusplus #ifdef __cplusplus
aiMeshMorphKey() AI_NO_EXCEPT aiMeshMorphKey() AI_NO_EXCEPT
: mTime(0.0) : mTime(0.0),
, mValues(nullptr) mValues(nullptr),
, mWeights(nullptr) mWeights(nullptr),
, mNumValuesAndWeights(0) mNumValuesAndWeights(0) {
{ }
} ~aiMeshMorphKey() {
~aiMeshMorphKey()
{
if (mNumValuesAndWeights && mValues && mWeights) { if (mNumValuesAndWeights && mValues && mWeights) {
delete [] mValues; delete[] mValues;
delete [] mWeights; delete[] mWeights;
} }
} }
#endif #endif
@ -237,25 +224,24 @@ struct aiMeshMorphKey
/** Defines how an animation channel behaves outside the defined time /** Defines how an animation channel behaves outside the defined time
* range. This corresponds to aiNodeAnim::mPreState and * range. This corresponds to aiNodeAnim::mPreState and
* aiNodeAnim::mPostState.*/ * aiNodeAnim::mPostState.*/
enum aiAnimBehaviour enum aiAnimBehaviour {
{
/** The value from the default node transformation is taken*/ /** The value from the default node transformation is taken*/
aiAnimBehaviour_DEFAULT = 0x0, aiAnimBehaviour_DEFAULT = 0x0,
/** The nearest key value is used without interpolation */ /** The nearest key value is used without interpolation */
aiAnimBehaviour_CONSTANT = 0x1, aiAnimBehaviour_CONSTANT = 0x1,
/** The value of the nearest two keys is linearly /** The value of the nearest two keys is linearly
* extrapolated for the current time value.*/ * extrapolated for the current time value.*/
aiAnimBehaviour_LINEAR = 0x2, aiAnimBehaviour_LINEAR = 0x2,
/** The animation is repeated. /** The animation is repeated.
* *
* If the animation key go from n to m and the current * If the animation key go from n to m and the current
* time is t, use the value at (t-n) % (|m-n|).*/ * time is t, use the value at (t-n) % (|m-n|).*/
aiAnimBehaviour_REPEAT = 0x3, aiAnimBehaviour_REPEAT = 0x3,
/** This value is not used, it is just here to force the /** This value is not used, it is just here to force the
* the compiler to map this enum to a 32 Bit integer */ * the compiler to map this enum to a 32 Bit integer */
#ifndef SWIG #ifndef SWIG
_aiAnimBehaviour_Force32Bit = INT_MAX _aiAnimBehaviour_Force32Bit = INT_MAX
@ -290,7 +276,7 @@ struct aiNodeAnim {
* *
* If there are position keys, there will also be at least one * If there are position keys, there will also be at least one
* scaling and one rotation key.*/ * scaling and one rotation key.*/
C_STRUCT aiVectorKey* mPositionKeys; C_STRUCT aiVectorKey *mPositionKeys;
/** The number of rotation keys */ /** The number of rotation keys */
unsigned int mNumRotationKeys; unsigned int mNumRotationKeys;
@ -301,7 +287,7 @@ struct aiNodeAnim {
* *
* If there are rotation keys, there will also be at least one * If there are rotation keys, there will also be at least one
* scaling and one position key. */ * scaling and one position key. */
C_STRUCT aiQuatKey* mRotationKeys; C_STRUCT aiQuatKey *mRotationKeys;
/** The number of scaling keys */ /** The number of scaling keys */
unsigned int mNumScalingKeys; unsigned int mNumScalingKeys;
@ -311,7 +297,7 @@ struct aiNodeAnim {
* *
* If there are scaling keys, there will also be at least one * If there are scaling keys, there will also be at least one
* position and one rotation key.*/ * position and one rotation key.*/
C_STRUCT aiVectorKey* mScalingKeys; C_STRUCT aiVectorKey *mScalingKeys;
/** Defines how the animation behaves before the first /** Defines how the animation behaves before the first
* key is encountered. * key is encountered.
@ -329,21 +315,21 @@ struct aiNodeAnim {
#ifdef __cplusplus #ifdef __cplusplus
aiNodeAnim() AI_NO_EXCEPT aiNodeAnim() AI_NO_EXCEPT
: mNumPositionKeys( 0 ) : mNumPositionKeys(0),
, mPositionKeys( nullptr ) mPositionKeys(nullptr),
, mNumRotationKeys( 0 ) mNumRotationKeys(0),
, mRotationKeys( nullptr ) mRotationKeys(nullptr),
, mNumScalingKeys( 0 ) mNumScalingKeys(0),
, mScalingKeys( nullptr ) mScalingKeys(nullptr),
, mPreState( aiAnimBehaviour_DEFAULT ) mPreState(aiAnimBehaviour_DEFAULT),
, mPostState( aiAnimBehaviour_DEFAULT ) { mPostState(aiAnimBehaviour_DEFAULT) {
// empty // empty
} }
~aiNodeAnim() { ~aiNodeAnim() {
delete [] mPositionKeys; delete[] mPositionKeys;
delete [] mRotationKeys; delete[] mRotationKeys;
delete [] mScalingKeys; delete[] mScalingKeys;
} }
#endif // __cplusplus #endif // __cplusplus
}; };
@ -354,8 +340,7 @@ struct aiNodeAnim {
* aiMesh::mAnimMeshes array. The purpose of aiMeshAnim is to * aiMesh::mAnimMeshes array. The purpose of aiMeshAnim is to
* define keyframes linking each mesh attachment to a particular * define keyframes linking each mesh attachment to a particular
* point in time. */ * point in time. */
struct aiMeshAnim struct aiMeshAnim {
{
/** Name of the mesh to be animated. An empty string is not allowed, /** Name of the mesh to be animated. An empty string is not allowed,
* animated meshes need to be named (not necessarily uniquely, * animated meshes need to be named (not necessarily uniquely,
* the name can basically serve as wild-card to select a group * the name can basically serve as wild-card to select a group
@ -366,17 +351,15 @@ struct aiMeshAnim
unsigned int mNumKeys; unsigned int mNumKeys;
/** Key frames of the animation. May not be NULL. */ /** Key frames of the animation. May not be NULL. */
C_STRUCT aiMeshKey* mKeys; C_STRUCT aiMeshKey *mKeys;
#ifdef __cplusplus #ifdef __cplusplus
aiMeshAnim() AI_NO_EXCEPT aiMeshAnim() AI_NO_EXCEPT
: mNumKeys() : mNumKeys(),
, mKeys() mKeys() {}
{}
~aiMeshAnim() ~aiMeshAnim() {
{
delete[] mKeys; delete[] mKeys;
} }
@ -385,8 +368,7 @@ struct aiMeshAnim
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Describes a morphing animation of a given mesh. */ /** Describes a morphing animation of a given mesh. */
struct aiMeshMorphAnim struct aiMeshMorphAnim {
{
/** Name of the mesh to be animated. An empty string is not allowed, /** Name of the mesh to be animated. An empty string is not allowed,
* animated meshes need to be named (not necessarily uniquely, * animated meshes need to be named (not necessarily uniquely,
* the name can basically serve as wildcard to select a group * the name can basically serve as wildcard to select a group
@ -397,17 +379,15 @@ struct aiMeshMorphAnim
unsigned int mNumKeys; unsigned int mNumKeys;
/** Key frames of the animation. May not be NULL. */ /** Key frames of the animation. May not be NULL. */
C_STRUCT aiMeshMorphKey* mKeys; C_STRUCT aiMeshMorphKey *mKeys;
#ifdef __cplusplus #ifdef __cplusplus
aiMeshMorphAnim() AI_NO_EXCEPT aiMeshMorphAnim() AI_NO_EXCEPT
: mNumKeys() : mNumKeys(),
, mKeys() mKeys() {}
{}
~aiMeshMorphAnim() ~aiMeshMorphAnim() {
{
delete[] mKeys; delete[] mKeys;
} }
@ -435,8 +415,7 @@ struct aiAnimation {
/** The node animation channels. Each channel affects a single node. /** The node animation channels. Each channel affects a single node.
* The array is mNumChannels in size. */ * The array is mNumChannels in size. */
C_STRUCT aiNodeAnim** mChannels; C_STRUCT aiNodeAnim **mChannels;
/** The number of mesh animation channels. Each channel affects /** The number of mesh animation channels. Each channel affects
* a single mesh and defines vertex-based animation. */ * a single mesh and defines vertex-based animation. */
@ -444,7 +423,7 @@ struct aiAnimation {
/** The mesh animation channels. Each channel affects a single mesh. /** The mesh animation channels. Each channel affects a single mesh.
* The array is mNumMeshChannels in size. */ * The array is mNumMeshChannels in size. */
C_STRUCT aiMeshAnim** mMeshChannels; C_STRUCT aiMeshAnim **mMeshChannels;
/** The number of mesh animation channels. Each channel affects /** The number of mesh animation channels. Each channel affects
* a single mesh and defines morphing animation. */ * a single mesh and defines morphing animation. */
@ -456,46 +435,45 @@ struct aiAnimation {
#ifdef __cplusplus #ifdef __cplusplus
aiAnimation() AI_NO_EXCEPT aiAnimation() AI_NO_EXCEPT
: mDuration(-1.) : mDuration(-1.),
, mTicksPerSecond(0.) mTicksPerSecond(0.),
, mNumChannels(0) mNumChannels(0),
, mChannels(nullptr) mChannels(nullptr),
, mNumMeshChannels(0) mNumMeshChannels(0),
, mMeshChannels(nullptr) mMeshChannels(nullptr),
, mNumMorphMeshChannels(0) mNumMorphMeshChannels(0),
, mMorphMeshChannels(nullptr) { mMorphMeshChannels(nullptr) {
// empty // empty
} }
~aiAnimation() { ~aiAnimation() {
// DO NOT REMOVE THIS ADDITIONAL CHECK // DO NOT REMOVE THIS ADDITIONAL CHECK
if ( mNumChannels && mChannels ) { if (mNumChannels && mChannels) {
for( unsigned int a = 0; a < mNumChannels; a++) { for (unsigned int a = 0; a < mNumChannels; a++) {
delete mChannels[ a ]; delete mChannels[a];
} }
delete [] mChannels; delete[] mChannels;
} }
if (mNumMeshChannels && mMeshChannels) { if (mNumMeshChannels && mMeshChannels) {
for( unsigned int a = 0; a < mNumMeshChannels; a++) { for (unsigned int a = 0; a < mNumMeshChannels; a++) {
delete mMeshChannels[a]; delete mMeshChannels[a];
} }
delete [] mMeshChannels; delete[] mMeshChannels;
} }
if (mNumMorphMeshChannels && mMorphMeshChannels) { if (mNumMorphMeshChannels && mMorphMeshChannels) {
for( unsigned int a = 0; a < mNumMorphMeshChannels; a++) { for (unsigned int a = 0; a < mNumMorphMeshChannels; a++) {
delete mMorphMeshChannels[a]; delete mMorphMeshChannels[a];
} }
delete [] mMorphMeshChannels; delete[] mMorphMeshChannels;
} }
} }
#endif // __cplusplus #endif // __cplusplus
}; };
#ifdef __cplusplus #ifdef __cplusplus
} }
/// @brief Some C++ utilities for inter- and extrapolation /// @brief Some C++ utilities for inter- and extrapolation
@ -509,72 +487,66 @@ namespace Assimp {
* types of the arguments. * types of the arguments.
*/ */
template <typename T> template <typename T>
struct Interpolator struct Interpolator {
{
// ------------------------------------------------------------------ // ------------------------------------------------------------------
/** @brief Get the result of the interpolation between a,b. /** @brief Get the result of the interpolation between a,b.
* *
* The interpolation algorithm depends on the type of the operands. * The interpolation algorithm depends on the type of the operands.
* aiQuaternion's and aiQuatKey's SLERP, the rest does a simple * aiQuaternion's and aiQuatKey's SLERP, the rest does a simple
* linear interpolation. */ * linear interpolation. */
void operator () (T& out,const T& a, const T& b, ai_real d) const { void operator()(T &anim_out, const T &a, const T &b, ai_real d) const {
out = a + (b-a)*d; anim_out = a + (b - a) * d;
} }
}; // ! Interpolator <T> }; // ! Interpolator <T>
//! @cond Never //! @cond Never
template <> template <>
struct Interpolator <aiQuaternion> { struct Interpolator<aiQuaternion> {
void operator () (aiQuaternion& out,const aiQuaternion& a, void operator()(aiQuaternion &out, const aiQuaternion &a,
const aiQuaternion& b, ai_real d) const const aiQuaternion &b, ai_real d) const {
{ aiQuaternion::Interpolate(out, a, b, d);
aiQuaternion::Interpolate(out,a,b,d);
} }
}; // ! Interpolator <aiQuaternion> }; // ! Interpolator <aiQuaternion>
template <> template <>
struct Interpolator <unsigned int> { struct Interpolator<unsigned int> {
void operator () (unsigned int& out,unsigned int a, void operator()(unsigned int &out, unsigned int a,
unsigned int b, ai_real d) const unsigned int b, ai_real d) const {
{ out = d > 0.5f ? b : a;
out = d>0.5f ? b : a;
} }
}; // ! Interpolator <aiQuaternion> }; // ! Interpolator <aiQuaternion>
template <> template <>
struct Interpolator<aiVectorKey> { struct Interpolator<aiVectorKey> {
void operator () (aiVector3D& out,const aiVectorKey& a, void operator()(aiVector3D &out, const aiVectorKey &a,
const aiVectorKey& b, ai_real d) const const aiVectorKey &b, ai_real d) const {
{
Interpolator<aiVector3D> ipl; Interpolator<aiVector3D> ipl;
ipl(out,a.mValue,b.mValue,d); ipl(out, a.mValue, b.mValue, d);
} }
}; // ! Interpolator <aiVectorKey> }; // ! Interpolator <aiVectorKey>
template <> template <>
struct Interpolator<aiQuatKey> { struct Interpolator<aiQuatKey> {
void operator () (aiQuaternion& out, const aiQuatKey& a, void operator()(aiQuaternion &out, const aiQuatKey &a,
const aiQuatKey& b, ai_real d) const const aiQuatKey &b, ai_real d) const {
{
Interpolator<aiQuaternion> ipl; Interpolator<aiQuaternion> ipl;
ipl(out,a.mValue,b.mValue,d); ipl(out, a.mValue, b.mValue, d);
} }
}; // ! Interpolator <aiQuatKey> }; // ! Interpolator <aiQuatKey>
template <> template <>
struct Interpolator<aiMeshKey> { struct Interpolator<aiMeshKey> {
void operator () (unsigned int& out, const aiMeshKey& a, void operator()(unsigned int &out, const aiMeshKey &a,
const aiMeshKey& b, ai_real d) const const aiMeshKey &b, ai_real d) const {
{
Interpolator<unsigned int> ipl; Interpolator<unsigned int> ipl;
ipl(out,a.mValue,b.mValue,d); ipl(out, a.mValue, b.mValue, d);
} }
}; // ! Interpolator <aiQuatKey> }; // ! Interpolator <aiQuatKey>
//! @endcond //! @endcond
} // ! end namespace Assimp } // namespace Assimp
#endif // __cplusplus #endif // __cplusplus

View File

@ -51,7 +51,7 @@ class TestProgressHandler : public ProgressHandler {
public: public:
TestProgressHandler() : TestProgressHandler() :
ProgressHandler(), ProgressHandler(),
mPercentage (0.f) { mPercentage(0.f) {
// empty // empty
} }
@ -60,6 +60,7 @@ public:
} }
bool Update(float percentage = -1.f) override { bool Update(float percentage = -1.f) override {
mPercentage = percentage;
return true; return true;
} }
float mPercentage; float mPercentage;

View File

@ -53,7 +53,6 @@ public:
virtual bool importerTest() { virtual bool importerTest() {
Assimp::Importer importer; Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/NFF/NFF/ManyEarthsNotJustOne.nff", 0); const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/NFF/NFF/ManyEarthsNotJustOne.nff", 0);
return true;
return nullptr != scene; return nullptr != scene;
} }
}; };

View File

@ -53,7 +53,6 @@ public:
virtual bool importerTest() { virtual bool importerTest() {
Assimp::Importer importer; Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/MDC/spider.mdc", 0); const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/MDC/spider.mdc", 0);
return true;
return nullptr != scene; return nullptr != scene;
} }
}; };

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -121,11 +119,11 @@ static const char *ObjModel_Issue1111 =
class utObjImportExport : public AbstractImportExportBase { class utObjImportExport : public AbstractImportExportBase {
protected: protected:
virtual void SetUp() { void SetUp() override {
m_im = new Assimp::Importer; m_im = new Assimp::Importer;
} }
virtual void TearDown() { void TearDown() override {
delete m_im; delete m_im;
m_im = nullptr; m_im = nullptr;
} }
@ -289,7 +287,7 @@ TEST_F(utObjImportExport, issue1923_vertex_color_Test) {
} }
TEST_F(utObjImportExport, issue1453_segfault) { TEST_F(utObjImportExport, issue1453_segfault) {
static const char *CurObjModel = static const char *curObjModel =
"v 0.0 0.0 0.0\n" "v 0.0 0.0 0.0\n"
"v 0.0 0.0 1.0\n" "v 0.0 0.0 1.0\n"
"v 0.0 1.0 0.0\n" "v 0.0 1.0 0.0\n"
@ -300,12 +298,12 @@ TEST_F(utObjImportExport, issue1453_segfault) {
"v 1.0 1.0 1.0\nB"; "v 1.0 1.0 1.0\nB";
Assimp::Importer myimporter; Assimp::Importer myimporter;
const aiScene *scene = myimporter.ReadFileFromMemory(CurObjModel, strlen(CurObjModel), aiProcess_ValidateDataStructure); const aiScene *scene = myimporter.ReadFileFromMemory(curObjModel, strlen(curObjModel), aiProcess_ValidateDataStructure);
EXPECT_EQ(nullptr, scene); EXPECT_EQ(nullptr, scene);
} }
TEST_F(utObjImportExport, relative_indices_Test) { TEST_F(utObjImportExport, relative_indices_Test) {
static const char *CurObjModel = static const char *curObjModel =
"v -0.500000 0.000000 0.400000\n" "v -0.500000 0.000000 0.400000\n"
"v -0.500000 0.000000 -0.800000\n" "v -0.500000 0.000000 -0.800000\n"
"v -0.500000 1.000000 -0.800000\n" "v -0.500000 1.000000 -0.800000\n"
@ -313,7 +311,7 @@ TEST_F(utObjImportExport, relative_indices_Test) {
"f -4 -3 -2 -1\nB"; "f -4 -3 -2 -1\nB";
Assimp::Importer myimporter; Assimp::Importer myimporter;
const aiScene *scene = myimporter.ReadFileFromMemory(CurObjModel, strlen(CurObjModel), aiProcess_ValidateDataStructure); const aiScene *scene = myimporter.ReadFileFromMemory(curObjModel, strlen(curObjModel), aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mNumMeshes, 1U); EXPECT_EQ(scene->mNumMeshes, 1U);
@ -328,14 +326,14 @@ TEST_F(utObjImportExport, relative_indices_Test) {
} }
TEST_F(utObjImportExport, homogeneous_coordinates_Test) { TEST_F(utObjImportExport, homogeneous_coordinates_Test) {
static const char *CurObjModel = static const char *curObjModel =
"v -0.500000 0.000000 0.400000 0.50000\n" "v -0.500000 0.000000 0.400000 0.50000\n"
"v -0.500000 0.000000 -0.800000 1.00000\n" "v -0.500000 0.000000 -0.800000 1.00000\n"
"v 0.500000 1.000000 -0.800000 0.5000\n" "v 0.500000 1.000000 -0.800000 0.5000\n"
"f 1 2 3\nB"; "f 1 2 3\nB";
Assimp::Importer myimporter; Assimp::Importer myimporter;
const aiScene *scene = myimporter.ReadFileFromMemory(CurObjModel, strlen(CurObjModel), aiProcess_ValidateDataStructure); const aiScene *scene = myimporter.ReadFileFromMemory(curObjModel, strlen(curObjModel), aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mNumMeshes, 1U); EXPECT_EQ(scene->mNumMeshes, 1U);
@ -351,31 +349,31 @@ TEST_F(utObjImportExport, homogeneous_coordinates_Test) {
} }
TEST_F(utObjImportExport, homogeneous_coordinates_divide_by_zero_Test) { TEST_F(utObjImportExport, homogeneous_coordinates_divide_by_zero_Test) {
static const char *CurObjModel = static const char *curObjModel =
"v -0.500000 0.000000 0.400000 0.\n" "v -0.500000 0.000000 0.400000 0.\n"
"v -0.500000 0.000000 -0.800000 1.00000\n" "v -0.500000 0.000000 -0.800000 1.00000\n"
"v 0.500000 1.000000 -0.800000 0.5000\n" "v 0.500000 1.000000 -0.800000 0.5000\n"
"f 1 2 3\nB"; "f 1 2 3\nB";
Assimp::Importer myimporter; Assimp::Importer myimporter;
const aiScene *scene = myimporter.ReadFileFromMemory(CurObjModel, strlen(CurObjModel), aiProcess_ValidateDataStructure); const aiScene *scene = myimporter.ReadFileFromMemory(curObjModel, strlen(curObjModel), aiProcess_ValidateDataStructure);
EXPECT_EQ(nullptr, scene); EXPECT_EQ(nullptr, scene);
} }
TEST_F(utObjImportExport, 0based_array_Test) { TEST_F(utObjImportExport, 0based_array_Test) {
static const char *CurObjModel = static const char *curObjModel =
"v -0.500000 0.000000 0.400000\n" "v -0.500000 0.000000 0.400000\n"
"v -0.500000 0.000000 -0.800000\n" "v -0.500000 0.000000 -0.800000\n"
"v -0.500000 1.000000 -0.800000\n" "v -0.500000 1.000000 -0.800000\n"
"f 0 1 2\nB"; "f 0 1 2\nB";
Assimp::Importer myImporter; Assimp::Importer myImporter;
const aiScene *scene = myImporter.ReadFileFromMemory(CurObjModel, strlen(CurObjModel), 0); const aiScene *scene = myImporter.ReadFileFromMemory(curObjModel, strlen(curObjModel), 0);
EXPECT_EQ(nullptr, scene); EXPECT_EQ(nullptr, scene);
} }
TEST_F(utObjImportExport, invalid_normals_uvs) { TEST_F(utObjImportExport, invalid_normals_uvs) {
static const char *CurObjModel = static const char *curObjModel =
"v -0.500000 0.000000 0.400000\n" "v -0.500000 0.000000 0.400000\n"
"v -0.500000 0.000000 -0.800000\n" "v -0.500000 0.000000 -0.800000\n"
"v -0.500000 1.000000 -0.800000\n" "v -0.500000 1.000000 -0.800000\n"
@ -384,12 +382,12 @@ TEST_F(utObjImportExport, invalid_normals_uvs) {
"f 1/1/1 1/1/1 2/2/2\nB"; "f 1/1/1 1/1/1 2/2/2\nB";
Assimp::Importer myImporter; Assimp::Importer myImporter;
const aiScene *scene = myImporter.ReadFileFromMemory(CurObjModel, strlen(CurObjModel), 0); const aiScene *scene = myImporter.ReadFileFromMemory(curObjModel, strlen(curObjModel), 0);
EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene);
} }
TEST_F(utObjImportExport, no_vt_just_vns) { TEST_F(utObjImportExport, no_vt_just_vns) {
static const char *CurObjModel = static const char *curObjModel =
"v 0 0 0\n" "v 0 0 0\n"
"v 0 0 0\n" "v 0 0 0\n"
"v 0 0 0\n" "v 0 0 0\n"
@ -417,7 +415,7 @@ TEST_F(utObjImportExport, no_vt_just_vns) {
"f 10/10 11/11 12/12\n"; "f 10/10 11/11 12/12\n";
Assimp::Importer myImporter; Assimp::Importer myImporter;
const aiScene *scene = myImporter.ReadFileFromMemory(CurObjModel, strlen(CurObjModel), 0); const aiScene *scene = myImporter.ReadFileFromMemory(curObjModel, strlen(curObjModel), 0);
EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene);
} }
@ -447,7 +445,7 @@ TEST_F(utObjImportExport, import_without_linend) {
} }
TEST_F(utObjImportExport, import_with_line_continuations) { TEST_F(utObjImportExport, import_with_line_continuations) {
static const char *ObjModel = static const char *curObjModel =
"v -0.5 -0.5 0.5\n" "v -0.5 -0.5 0.5\n"
"v -0.5 \\\n" "v -0.5 \\\n"
" -0.5 -0.5\n" " -0.5 -0.5\n"
@ -457,7 +455,7 @@ TEST_F(utObjImportExport, import_with_line_continuations) {
"f 1 2 3\n"; "f 1 2 3\n";
Assimp::Importer myImporter; Assimp::Importer myImporter;
const aiScene *scene = myImporter.ReadFileFromMemory(ObjModel, strlen(ObjModel), 0); const aiScene *scene = myImporter.ReadFileFromMemory(curObjModel, strlen(curObjModel), 0);
EXPECT_NE(nullptr, scene); EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mNumMeshes, 1U); EXPECT_EQ(scene->mNumMeshes, 1U);
@ -479,3 +477,4 @@ TEST_F(utObjImportExport, import_with_line_continuations) {
EXPECT_NEAR(vertices[2].y, 0.5f, threshold); EXPECT_NEAR(vertices[2].y, 0.5f, threshold);
EXPECT_NEAR(vertices[2].z, -0.5f, threshold); EXPECT_NEAR(vertices[2].z, -0.5f, threshold);
} }

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -112,11 +110,11 @@ TEST_F(TriangulateProcessTest, testTriangulation) {
std::vector<bool> ait(q,false); std::vector<bool> ait(q,false);
for (unsigned int i = 0, tt = q-2; i < tt; ++i,++m) { for (unsigned int i = 0, tt = q-2; i < tt; ++i,++m) {
const aiFace& curFace = pcMesh->mFaces[m]; aiFace& curFace = pcMesh->mFaces[m];
EXPECT_EQ(3U, curFace.mNumIndices); EXPECT_EQ(3U, curFace.mNumIndices);
for (unsigned int qqq = 0; qqq < curFace.mNumIndices; ++qqq) { for (unsigned int qqq = 0; qqq < curFace.mNumIndices; ++qqq) {
ait[face.mIndices[qqq]-idx] = true; ait[curFace.mIndices[qqq] - idx] = true;
} }
} }
for (std::vector<bool>::const_iterator it = ait.begin(); it != ait.end(); ++it) { for (std::vector<bool>::const_iterator it = ait.begin(); it != ait.end(); ++it) {
@ -139,3 +137,4 @@ TEST_F(TriangulateProcessTest, testTriangulation) {
// we should have no valid normal vectors now necause we aren't a pure polygon mesh // we should have no valid normal vectors now necause we aren't a pure polygon mesh
EXPECT_TRUE(pcMesh->mNormals == NULL); EXPECT_TRUE(pcMesh->mNormals == NULL);
} }

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -46,129 +44,122 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "Main.h" #include "Main.h"
#include <assimp/ParsingUtils.h>
#ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_EXPORT
const char* AICMD_MSG_EXPORT_HELP_E = const char *AICMD_MSG_EXPORT_HELP_E =
"assimp export <model> [<out>] [-f<h>] [common parameters]\n" "assimp export <model> [<out>] [-f<h>] [common parameters]\n"
"\t -f<h> Specify the file format. If omitted, the output format is \n" "\t -f<h> Specify the file format. If omitted, the output format is \n"
"\t\tderived from the file extension of the given output file \n" "\t\tderived from the file extension of the given output file \n"
"\t[See the assimp_cmd docs for a full list of all common parameters] \n" "\t[See the assimp_cmd docs for a full list of all common parameters] \n";
;
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
size_t GetMatchingFormat(const std::string& outf,bool byext=false) size_t GetMatchingFormat(const std::string &outf, bool byext = false) {
{ for (size_t i = 0, end = globalExporter->GetExportFormatCount(); i < end; ++i) {
for(size_t i = 0, end = globalExporter->GetExportFormatCount(); i < end; ++i) { const aiExportFormatDesc *const e = globalExporter->GetExportFormatDescription(i);
const aiExportFormatDesc* const e = globalExporter->GetExportFormatDescription(i); if (outf == (byext ? e->fileExtension : e->id)) {
if (outf == (byext ? e->fileExtension : e->id)) { return i;
return i; }
} }
} return SIZE_MAX;
return SIZE_MAX;
} }
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
int Assimp_Export(const char* const* params, unsigned int num) int Assimp_Export(const char *const *params, unsigned int num) {
{ const char *const invalid = "assimp export: Invalid number of arguments. See \'assimp export --help\'\n";
const char* const invalid = "assimp export: Invalid number of arguments. See \'assimp export --help\'\n"; if (num < 1) {
if (num < 1) { printf(invalid);
printf(invalid); return AssimpCmdError::InvalidNumberOfArguments;
return AssimpCmdError::InvalidNumberOfArguments; }
}
// --help // --help
if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) { if (!strcmp(params[0], "-h") || !strcmp(params[0], "--help") || !strcmp(params[0], "-?")) {
printf("%s",AICMD_MSG_EXPORT_HELP_E); printf("%s", AICMD_MSG_EXPORT_HELP_E);
return AssimpCmdError::Success; return AssimpCmdError::Success;
} }
std::string in = std::string(params[0]); std::string in = std::string(params[0]);
std::string out = (num > 1 ? std::string(params[1]) : "-"), outext; std::string out = (num > 1 ? std::string(params[1]) : "-"), outext;
// //
const std::string::size_type s = out.find_last_of('.'); const std::string::size_type s = out.find_last_of('.');
if (s != std::string::npos) { if (s != std::string::npos) {
outext = out.substr(s+1); outext = out.substr(s + 1);
out = out.substr(0,s); out = out.substr(0, s);
} }
// get import flags // get import flags
ImportData import; ImportData import;
ProcessStandardArguments(import,params+1,num-1); ProcessStandardArguments(import, params + 1, num - 1);
// process other flags // process other flags
std::string outf = ""; std::string outf = "";
for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i) { for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num; ++i) {
if (!params[i]) { if (!params[i]) {
continue; continue;
} }
if (!strncmp( params[i], "-f",2)) { if (!strncmp(params[i], "-f", 2)) {
if ( strncmp( params[ i ], "-fi",3 )) if (strncmp(params[i], "-fi", 3))
outf = std::string(params[i]+2); outf = std::string(params[i] + 2);
} } else if (!strncmp(params[i], "--format=", 9)) {
else if ( !strncmp( params[i], "--format=",9)) { outf = std::string(params[i] + 9);
outf = std::string(params[i]+9); }
} }
}
std::transform(outf.begin(),outf.end(),outf.begin(),::tolower); std::transform(outf.begin(), outf.end(), outf.begin(), Assimp::ToLower<char>);
// convert the output format to a format id // convert the output format to a format id
size_t outfi = GetMatchingFormat(outf); size_t outfi = GetMatchingFormat(outf);
if (outfi == SIZE_MAX) { if (outfi == SIZE_MAX) {
if (outf.length()) { if (outf.length()) {
printf("assimp export: warning, format id \'%s\' is unknown\n",outf.c_str()); printf("assimp export: warning, format id \'%s\' is unknown\n", outf.c_str());
} }
// retry to see if we know it as file extension // retry to see if we know it as file extension
outfi = GetMatchingFormat(outf,true); outfi = GetMatchingFormat(outf, true);
if (outfi == SIZE_MAX) { if (outfi == SIZE_MAX) {
// retry to see if we know the file extension of the output file // retry to see if we know the file extension of the output file
outfi = GetMatchingFormat(outext,true); outfi = GetMatchingFormat(outext, true);
if (outfi == SIZE_MAX) { if (outfi == SIZE_MAX) {
// still no match -> failure // still no match -> failure
printf("assimp export: no output format specified and I failed to guess it\n"); printf("assimp export: no output format specified and I failed to guess it\n");
return -23; return -23;
} }
} } else {
else { outext = outf;
outext = outf; }
} }
}
// if no output file is specified, take the file name from input file // if no output file is specified, take the file name from input file
if (out[0] == '-') { if (out[0] == '-') {
std::string::size_type pos = in.find_last_of('.'); std::string::size_type pos = in.find_last_of('.');
if (pos == std::string::npos) { if (pos == std::string::npos) {
pos = in.length(); pos = in.length();
} }
out = in.substr(0,s); out = in.substr(0, pos);
} }
const aiExportFormatDesc* const e = globalExporter->GetExportFormatDescription(outfi); const aiExportFormatDesc *const e = globalExporter->GetExportFormatDescription(outfi);
printf("assimp export: select file format: \'%s\' (%s)\n",e->id,e->description); printf("assimp export: select file format: \'%s\' (%s)\n", e->id, e->description);
// import the model // import the model
const aiScene* scene = ImportModel(import,in); const aiScene *scene = ImportModel(import, in);
if (!scene) { if (!scene) {
return AssimpCmdExportError::FailedToImportModel; return AssimpCmdExportError::FailedToImportModel;
} }
// derive the final file name // derive the final file name
out += "."+outext; out += "." + outext;
// and call the export routine // and call the export routine
if(!ExportModel(scene, import, out,e->id)) { if (!ExportModel(scene, import, out, e->id)) {
return AssimpCmdExportError::FailedToExportModel; return AssimpCmdExportError::FailedToExportModel;
} }
printf("assimp export: wrote output file: %s\n",out.c_str()); printf("assimp export: wrote output file: %s\n", out.c_str());
return AssimpCmdError::Success; return AssimpCmdError::Success;
} }
#endif // no export #endif // no export

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -46,94 +44,89 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "Main.h" #include "Main.h"
#include <assimp/fast_atof.h> #include <assimp/ParsingUtils.h>
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/fast_atof.h>
const char* AICMD_MSG_DUMP_HELP_E = static const char *AICMD_MSG_DUMP_HELP_E =
"assimp extract <model> [<out>] [-t<n>] [-f<fmt>] [-ba] [-s] [common parameters]\n" "assimp extract <model> [<out>] [-t<n>] [-f<fmt>] [-ba] [-s] [common parameters]\n"
"\t -ba Writes BMP's with alpha channel\n" "\t -ba Writes BMP's with alpha channel\n"
"\t -t<n> Zero-based index of the texture to be extracted \n" "\t -t<n> Zero-based index of the texture to be extracted \n"
"\t -f<f> Specify the file format if <out> is omitted \n" "\t -f<f> Specify the file format if <out> is omitted \n"
"\t[See the assimp_cmd docs for a full list of all common parameters] \n" "\t[See the assimp_cmd docs for a full list of all common parameters] \n"
"\t -cfast Fast post processing preset, runs just a few important steps \n" "\t -cfast Fast post processing preset, runs just a few important steps \n"
"\t -cdefault Default post processing: runs all recommended steps\n" "\t -cdefault Default post processing: runs all recommended steps\n"
"\t -cfull Fires almost all post processing steps \n" "\t -cfull Fires almost all post processing steps \n";
;
#define AI_EXTRACT_WRITE_BMP_ALPHA 0x1 #define AI_EXTRACT_WRITE_BMP_ALPHA 0x1
#include <assimp/Compiler/pushpack1.h> #include <assimp/Compiler/pushpack1.h>
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Data structure for the first header of a BMP // Data structure for the first header of a BMP
struct BITMAPFILEHEADER struct BITMAPFILEHEADER {
{ uint16_t bfType;
uint16_t bfType ; uint32_t bfSize;
uint32_t bfSize; uint16_t bfReserved1;
uint16_t bfReserved1 ; uint16_t bfReserved2;
uint16_t bfReserved2; uint32_t bfOffBits;
uint32_t bfOffBits;
} PACK_STRUCT; } PACK_STRUCT;
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Data structure for the second header of a BMP // Data structure for the second header of a BMP
struct BITMAPINFOHEADER struct BITMAPINFOHEADER {
{ int32_t biSize;
int32_t biSize; int32_t biWidth;
int32_t biWidth; int32_t biHeight;
int32_t biHeight; int16_t biPlanes;
int16_t biPlanes; int16_t biBitCount;
int16_t biBitCount; uint32_t biCompression;
uint32_t biCompression; int32_t biSizeImage;
int32_t biSizeImage; int32_t biXPelsPerMeter;
int32_t biXPelsPerMeter; int32_t biYPelsPerMeter;
int32_t biYPelsPerMeter; int32_t biClrUsed;
int32_t biClrUsed; int32_t biClrImportant;
int32_t biClrImportant;
// pixel data follows header // pixel data follows header
} PACK_STRUCT; } PACK_STRUCT;
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Data structure for the header of a TGA // Data structure for the header of a TGA
struct TGA_HEADER struct TGA_HEADER {
{ uint8_t identsize; // size of ID field that follows 18 byte header (0 usually)
uint8_t identsize; // size of ID field that follows 18 byte header (0 usually) uint8_t colourmaptype; // type of colour map 0=none, 1=has palette
uint8_t colourmaptype; // type of colour map 0=none, 1=has palette uint8_t imagetype; // type of image 0=none,1=indexed,2=rgb,3=gray,+8=rle packed
uint8_t imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
uint16_t colourmapstart; // first colour map entry in palette uint16_t colourmapstart; // first colour map entry in palette
uint16_t colourmaplength; // number of colours in palette uint16_t colourmaplength; // number of colors in palette
uint8_t colourmapbits; // number of bits per palette entry 15,16,24,32 uint8_t colourmapbits; // number of bits per palette entry 15,16,24,32
uint16_t xstart; // image x origin uint16_t xstart; // image x origin
uint16_t ystart; // image y origin uint16_t ystart; // image y origin
uint16_t width; // image width in pixels uint16_t width; // image width in pixels
uint16_t height; // image height in pixels uint16_t height; // image height in pixels
uint8_t bits; // image bits per pixel 8,16,24,32 uint8_t bits; // image bits per pixel 8,16,24,32
uint8_t descriptor; // image descriptor bits (vh flip bits) uint8_t descriptor; // image descriptor bits (vh flip bits)
// pixel data follows header // pixel data follows header
} PACK_STRUCT; } PACK_STRUCT;
#include <assimp/Compiler/poppack1.h> #include <assimp/Compiler/poppack1.h>
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Save a texture as bitmap // Save a texture as bitmap
int SaveAsBMP (FILE* file, const aiTexel* data, unsigned int width, unsigned int height, bool SaveAlpha = false) int SaveAsBMP(FILE *file, const aiTexel *data, unsigned int width, unsigned int height, bool SaveAlpha = false) {
{
if (!file || !data) { if (!file || !data) {
return 1; return 1;
} }
const unsigned int numc = (SaveAlpha ? 4 : 3); const unsigned int numc = (SaveAlpha ? 4 : 3);
unsigned char* buffer = new unsigned char[width*height*numc]; unsigned char *buffer = new unsigned char[width * height * numc];
for (unsigned int y = 0; y < height; ++y) { for (unsigned int y = 0; y < height; ++y) {
for (unsigned int x = 0; x < width; ++x) { for (unsigned int x = 0; x < width; ++x) {
unsigned char* s = &buffer[(y*width+x) * numc]; unsigned char *s = &buffer[(y * width + x) * numc];
const aiTexel* t = &data [ y*width+x]; const aiTexel *t = &data[y * width + x];
s[0] = t->b; s[0] = t->b;
s[1] = t->g; s[1] = t->g;
s[2] = t->r; s[2] = t->r;
@ -143,33 +136,33 @@ int SaveAsBMP (FILE* file, const aiTexel* data, unsigned int width, unsigned int
} }
BITMAPFILEHEADER header; BITMAPFILEHEADER header;
header.bfType = 'B' | (int('M') << 8u); header.bfType = 'B' | (int('M') << 8u);
header.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
header.bfSize = header.bfOffBits+width*height*numc; header.bfSize = header.bfOffBits + width * height * numc;
header.bfReserved1 = header.bfReserved2 = 0; header.bfReserved1 = header.bfReserved2 = 0;
fwrite(&header,sizeof(BITMAPFILEHEADER),1,file); fwrite(&header, sizeof(BITMAPFILEHEADER), 1, file);
BITMAPINFOHEADER info; BITMAPINFOHEADER info;
info.biSize = 40; info.biSize = 40;
info.biWidth = width; info.biWidth = width;
info.biHeight = height; info.biHeight = height;
info.biPlanes = 1; info.biPlanes = 1;
info.biBitCount = (int16_t) numc<<3; info.biBitCount = (int16_t)numc << 3;
info.biCompression = 0; info.biCompression = 0;
info.biSizeImage = width*height*numc; info.biSizeImage = width * height * numc;
info.biXPelsPerMeter = 1; // dummy info.biXPelsPerMeter = 1; // dummy
info.biYPelsPerMeter = 1; // dummy info.biYPelsPerMeter = 1; // dummy
info.biClrUsed = 0; info.biClrUsed = 0;
info.biClrImportant = 0; info.biClrImportant = 0;
fwrite(&info,sizeof(BITMAPINFOHEADER),1,file); fwrite(&info, sizeof(BITMAPINFOHEADER), 1, file);
unsigned char* temp = buffer+info.biSizeImage; unsigned char *temp = buffer + info.biSizeImage;
const unsigned int row = width*numc; const unsigned int row = width * numc;
for (int y = 0; temp -= row,y < info.biHeight;++y) { for (int y = 0; temp -= row, y < info.biHeight; ++y) {
fwrite(temp,row,1,file); fwrite(temp, row, 1, file);
} }
// delete the buffer // delete the buffer
@ -179,25 +172,24 @@ int SaveAsBMP (FILE* file, const aiTexel* data, unsigned int width, unsigned int
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Save a texture as tga // Save a texture as tga
int SaveAsTGA (FILE* file, const aiTexel* data, unsigned int width, unsigned int height) int SaveAsTGA(FILE *file, const aiTexel *data, unsigned int width, unsigned int height) {
{
if (!file || !data) { if (!file || !data) {
return 1; return 1;
} }
TGA_HEADER head; TGA_HEADER head;
memset(&head, 0, sizeof(head)); memset(&head, 0, sizeof(head));
head.bits = 32; head.bits = 32;
head.height = (uint16_t)height; head.height = (uint16_t)height;
head.width = (uint16_t)width; head.width = (uint16_t)width;
head.descriptor |= (1u<<5); head.descriptor |= (1u << 5);
head.imagetype = 2; // actually it's RGBA head.imagetype = 2; // actually it's RGBA
fwrite(&head,sizeof(TGA_HEADER),1,file); fwrite(&head, sizeof(TGA_HEADER), 1, file);
for (unsigned int y = 0; y < height; ++y) { for (unsigned int y = 0; y < height; ++y) {
for (unsigned int x = 0; x < width; ++x) { for (unsigned int x = 0; x < width; ++x) {
fwrite(data + y*width+x,4,1,file); fwrite(data + y * width + x, 4, 1, file);
} }
} }
@ -206,18 +198,15 @@ int SaveAsTGA (FILE* file, const aiTexel* data, unsigned int width, unsigned int
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Do the texture import for a given aiTexture // Do the texture import for a given aiTexture
int DoExport(const aiTexture* tx, FILE* p, const std::string& extension, int DoExport(const aiTexture *tx, FILE *p, const std::string &extension,
unsigned int flags) unsigned int flags) {
{
// export the image to the appropriate decoder // export the image to the appropriate decoder
if (extension == "bmp") { if (extension == "bmp") {
SaveAsBMP(p,tx->pcData,tx->mWidth,tx->mHeight, SaveAsBMP(p, tx->pcData, tx->mWidth, tx->mHeight,
(0 != (flags & AI_EXTRACT_WRITE_BMP_ALPHA))); (0 != (flags & AI_EXTRACT_WRITE_BMP_ALPHA)));
} } else if (extension == "tga") {
else if (extension == "tga") { SaveAsTGA(p, tx->pcData, tx->mWidth, tx->mHeight);
SaveAsTGA(p,tx->pcData,tx->mWidth,tx->mHeight); } else {
}
else {
printf("assimp extract: No available texture encoder found for %s\n", extension.c_str()); printf("assimp extract: No available texture encoder found for %s\n", extension.c_str());
return AssimpCmdExtractError::NoAvailableTextureEncoderFound; return AssimpCmdExtractError::NoAvailableTextureEncoderFound;
} }
@ -226,9 +215,8 @@ int DoExport(const aiTexture* tx, FILE* p, const std::string& extension,
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Implementation of the assimp extract utility // Implementation of the assimp extract utility
int Assimp_Extract (const char* const* params, unsigned int num) int Assimp_Extract(const char *const *params, unsigned int num) {
{ const char *const invalid = "assimp extract: Invalid number of arguments. See \'assimp extract --help\'\n";
const char* const invalid = "assimp extract: Invalid number of arguments. See \'assimp extract --help\'\n";
// assimp extract in out [options] // assimp extract in out [options]
if (num < 1) { if (num < 1) {
printf(invalid); printf(invalid);
@ -236,46 +224,39 @@ int Assimp_Extract (const char* const* params, unsigned int num)
} }
// --help // --help
if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) { if (!strcmp(params[0], "-h") || !strcmp(params[0], "--help") || !strcmp(params[0], "-?")) {
printf("%s",AICMD_MSG_DUMP_HELP_E); printf("%s", AICMD_MSG_DUMP_HELP_E);
return AssimpCmdError::Success; return AssimpCmdError::Success;
} }
std::string in = std::string(params[0]);
std::string in = std::string(params[0]);
std::string out = (num > 1 ? std::string(params[1]) : "-"); std::string out = (num > 1 ? std::string(params[1]) : "-");
// get import flags // get import flags
ImportData import; ImportData import;
ProcessStandardArguments(import,params+1,num-1); ProcessStandardArguments(import, params + 1, num - 1);
bool nosuffix = false; bool nosuffix = false;
unsigned int texIdx = 0xffffffff, flags = 0; unsigned int texIdx = 0xffffffff, flags = 0;
// process other flags // process other flags
std::string extension = "bmp"; std::string extension = "bmp";
for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i) { for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num; ++i) {
if (!params[i]) { if (!params[i]) {
continue; continue;
} }
if (!strncmp( params[i], "-f",2)) { if (!strncmp(params[i], "-f", 2)) {
extension = std::string(params[i]+2); extension = std::string(params[i] + 2);
} } else if (!strncmp(params[i], "--format=", 9)) {
else if ( !strncmp( params[i], "--format=",9)) { extension = std::string(params[i] + 9);
extension = std::string(params[i]+9); } else if (!strcmp(params[i], "--nosuffix") || !strcmp(params[i], "-s")) {
}
else if ( !strcmp( params[i], "--nosuffix") || !strcmp(params[i],"-s")) {
nosuffix = true; nosuffix = true;
} } else if (!strncmp(params[i], "--texture=", 10)) {
else if ( !strncmp( params[i], "--texture=",10)) { texIdx = Assimp::strtoul10(params[i] + 10);
texIdx = Assimp::strtoul10(params[i]+10); } else if (!strncmp(params[i], "-t", 2)) {
} texIdx = Assimp::strtoul10(params[i] + 2);
else if ( !strncmp( params[i], "-t",2)) { } else if (!strcmp(params[i], "-ba") || !strcmp(params[i], "--bmp-with-alpha")) {
texIdx = Assimp::strtoul10(params[i]+2);
}
else if ( !strcmp( params[i], "-ba") || !strcmp( params[i], "--bmp-with-alpha")) {
flags |= AI_EXTRACT_WRITE_BMP_ALPHA; flags |= AI_EXTRACT_WRITE_BMP_ALPHA;
} }
#if 0 #if 0
@ -286,7 +267,7 @@ int Assimp_Extract (const char* const* params, unsigned int num)
#endif #endif
} }
std::transform(extension.begin(),extension.end(),extension.begin(),::tolower); std::transform(extension.begin(), extension.end(), extension.begin(), Assimp::ToLower<char>);
if (out[0] == '-') { if (out[0] == '-') {
// take file name from input file // take file name from input file
@ -294,20 +275,20 @@ int Assimp_Extract (const char* const* params, unsigned int num)
if (s == std::string::npos) if (s == std::string::npos)
s = in.length(); s = in.length();
out = in.substr(0,s); out = in.substr(0, s);
} }
// take file extension from file name, if given // take file extension from file name, if given
std::string::size_type s = out.find_last_of('.'); std::string::size_type s = out.find_last_of('.');
if (s != std::string::npos) { if (s != std::string::npos) {
extension = out.substr(s+1,in.length()-(s+1)); extension = out.substr(s + 1, in.length() - (s + 1));
out = out.substr(0,s); out = out.substr(0, s);
} }
// import the main model // import the main model
const aiScene* scene = ImportModel(import,in); const aiScene *scene = ImportModel(import, in);
if (!scene) { if (!scene) {
printf("assimp extract: Unable to load input file %s\n",in.c_str()); printf("assimp extract: Unable to load input file %s\n", in.c_str());
return AssimpCmdError::FailedToLoadInputFile; return AssimpCmdError::FailedToLoadInputFile;
} }
@ -317,28 +298,27 @@ int Assimp_Extract (const char* const* params, unsigned int num)
// check whether the requested texture is existing // check whether the requested texture is existing
if (texIdx >= scene->mNumTextures) { if (texIdx >= scene->mNumTextures) {
::printf("assimp extract: Texture %i requested, but there are just %i textures\n", ::printf("assimp extract: Texture %i requested, but there are just %i textures\n",
texIdx, scene->mNumTextures); texIdx, scene->mNumTextures);
return AssimpCmdExtractError::TextureIndexIsOutOfRange; return AssimpCmdExtractError::TextureIndexIsOutOfRange;
} }
} } else {
else { ::printf("assimp extract: Exporting %i textures\n", scene->mNumTextures);
::printf("assimp extract: Exporting %i textures\n",scene->mNumTextures);
} }
// now write all output textures // now write all output textures
for (unsigned int i = 0; i < scene->mNumTextures;++i) { for (unsigned int i = 0; i < scene->mNumTextures; ++i) {
if (texIdx != 0xffffffff && texIdx != i) { if (texIdx != 0xffffffff && texIdx != i) {
continue; continue;
} }
const aiTexture* tex = scene->mTextures[i]; const aiTexture *tex = scene->mTextures[i];
std::string out_cpy = out, out_ext = extension; std::string out_cpy = out, out_ext = extension;
// append suffix if necessary - always if all textures are exported // append suffix if necessary - always if all textures are exported
if (!nosuffix || (texIdx == 0xffffffff)) { if (!nosuffix || (texIdx == 0xffffffff)) {
out_cpy.append ("_img"); out_cpy.append("_img");
char tmp[10]; char tmp[10];
Assimp::ASSIMP_itoa10(tmp,i); Assimp::ASSIMP_itoa10(tmp, i);
out_cpy.append(std::string(tmp)); out_cpy.append(std::string(tmp));
} }
@ -347,32 +327,34 @@ int Assimp_Extract (const char* const* params, unsigned int num)
// it to its native file format // it to its native file format
if (!tex->mHeight) { if (!tex->mHeight) {
printf("assimp extract: Texture %i is compressed (%s). Writing native file format.\n", printf("assimp extract: Texture %i is compressed (%s). Writing native file format.\n",
i,tex->achFormatHint); i, tex->achFormatHint);
// modify file extension // modify file extension
out_ext = std::string(tex->achFormatHint); out_ext = std::string(tex->achFormatHint);
} }
out_cpy.append("."+out_ext); out_cpy.append("." + out_ext);
// open output file // open output file
FILE* p = ::fopen(out_cpy.c_str(),"wb"); FILE *p = ::fopen(out_cpy.c_str(), "wb");
if (!p) { if (!p) {
printf("assimp extract: Unable to open output file %s\n",out_cpy.c_str()); printf("assimp extract: Unable to open output file %s\n", out_cpy.c_str());
return AssimpCmdError::FailedToOpenOutputFile; return AssimpCmdError::FailedToOpenOutputFile;
} }
int m; int m;
if (!tex->mHeight) { if (!tex->mHeight) {
m = (1 != fwrite(tex->pcData,tex->mWidth,1,p)) m = (1 != fwrite(tex->pcData, tex->mWidth, 1, p)) ?
? static_cast<int>(AssimpCmdError::Success) static_cast<int>(AssimpCmdError::Success) :
: static_cast<int>(AssimpCmdExtractError::FailedToExportCompressedTexture); static_cast<int>(AssimpCmdExtractError::FailedToExportCompressedTexture);
} else {
m = DoExport(tex, p, extension, flags);
} }
else m = DoExport(tex,p,extension,flags);
::fclose(p); ::fclose(p);
printf("assimp extract: Wrote texture %i to %s\n",i, out_cpy.c_str()); printf("assimp extract: Wrote texture %i to %s\n", i, out_cpy.c_str());
if (texIdx != 0xffffffff) if (texIdx != 0xffffffff) {
return m; return m;
} }
return AssimpCmdError::Success; return AssimpCmdError::Success;
} }

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -79,7 +77,7 @@ int Assimp_Dump(const char *const *params, unsigned int num) {
return AssimpCmdError::Success; return AssimpCmdError::Success;
} }
// assimp dump in out [options] // asssimp dump in out [options]
if (num < 1) { if (num < 1) {
printf("%s", fail); printf("%s", fail);
return AssimpCmdError::InvalidNumberOfArguments; return AssimpCmdError::InvalidNumberOfArguments;
@ -104,11 +102,13 @@ int Assimp_Dump(const char *const *params, unsigned int num) {
// process other flags // process other flags
for (unsigned int i = 1; i < num; ++i) { for (unsigned int i = 1; i < num; ++i) {
if (!params[i]) continue; if (!params[i]) {
continue;
}
if (!strcmp(params[i], "-b") || !strcmp(params[i], "--binary")) { if (!strcmp(params[i], "-b") || !strcmp(params[i], "--binary")) {
binary = true; binary = true;
} else if (!strcmp(params[i], "-s") || !strcmp(params[i], "--short")) { } else if (!strcmp(params[i], "-s") || !strcmp(params[i], "--short")) {
cur_shortened = true; shortened = true;
} else if (!strcmp(params[i], "-z") || !strcmp(params[i], "--compressed")) { } else if (!strcmp(params[i], "-z") || !strcmp(params[i], "--compressed")) {
compressed = true; compressed = true;
} }
@ -122,12 +122,12 @@ int Assimp_Dump(const char *const *params, unsigned int num) {
if (cur_out[0] == '-') { if (cur_out[0] == '-') {
// take file name from input file // take file name from input file
std::string::size_type s = in.find_last_of('.'); std::string::size_type pos = in.find_last_of('.');
if (s == std::string::npos) { if (pos == std::string::npos) {
s = in.length(); pos = in.length();
} }
cur_out = in.substr(0, s); cur_out = in.substr(0, pos);
cur_out.append((binary ? ".assbin" : ".assxml")); cur_out.append((binary ? ".assbin" : ".assxml"));
if (cur_shortened && binary) { if (cur_shortened && binary) {
cur_out.append(".regress"); cur_out.append(".regress");
@ -155,10 +155,10 @@ int Assimp_Dump(const char *const *params, unsigned int num) {
printf("%s", ("assimp dump: " + std::string(e.what())).c_str()); printf("%s", ("assimp dump: " + std::string(e.what())).c_str());
return AssimpCmdError::ExceptionWasRaised; return AssimpCmdError::ExceptionWasRaised;
} catch (...) { } catch (...) {
printf("assimp dump: An unknown exception occured.\n"); printf("assimp dump: An unknown exception occurred.\n");
return AssimpCmdError::ExceptionWasRaised; return AssimpCmdError::ExceptionWasRaised;
} }
printf("assimp dump: Wrote output dump %s\n", out.c_str()); printf("assimp dump: Wrote output dump %s\n", cur_out.c_str());
return AssimpCmdError::Success; return AssimpCmdError::Success;
} }