Fix static-code findings,

pull/3012/head
Kim Kulling 2020-03-15 12:16:17 +01:00
parent 976091a6f6
commit 856ca9f2dd
7 changed files with 317 additions and 355 deletions

View File

@ -89,9 +89,12 @@ ObjFileMtlImporter::ObjFileMtlImporter(std::vector<char> &buffer,
m_DataIt(buffer.begin()), m_DataIt(buffer.begin()),
m_DataItEnd(buffer.end()), m_DataItEnd(buffer.end()),
m_pModel(pModel), m_pModel(pModel),
m_uiLine(0) { m_uiLine(0),
ai_assert(NULL != m_pModel); m_buffer() {
if (NULL == m_pModel->m_pDefaultMaterial) { 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 = new ObjFile::Material;
m_pModel->m_pDefaultMaterial->MaterialName.Set("default"); m_pModel->m_pDefaultMaterial->MaterialName.Set("default");
} }
@ -104,18 +107,6 @@ ObjFileMtlImporter::~ObjFileMtlImporter() {
// empty // empty
} }
// -------------------------------------------------------------------
// Private copy constructor
ObjFileMtlImporter::ObjFileMtlImporter(const ObjFileMtlImporter &) {
// empty
}
// -------------------------------------------------------------------
// Private copy constructor
ObjFileMtlImporter &ObjFileMtlImporter::operator=(const ObjFileMtlImporter &) {
return *this;
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Loads the material description // Loads the material description
void ObjFileMtlImporter::load() { void ObjFileMtlImporter::load() {
@ -227,15 +218,15 @@ void ObjFileMtlImporter::getColorRGBA(aiColor3D *pColor) {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Loads the kind of illumination model. // Loads the kind of illumination model.
void ObjFileMtlImporter::getIlluminationModel(int &illum_model) { void ObjFileMtlImporter::getIlluminationModel(int &illum_model) {
m_DataIt = CopyNextWord<DataArrayIt>(m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE); m_DataIt = CopyNextWord<DataArrayIt>(m_DataIt, m_DataItEnd, &m_buffer[0], BUFFERSIZE);
illum_model = atoi(m_buffer); illum_model = atoi(&m_buffer[0]);
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Loads a single float value. // Loads a single float value.
void ObjFileMtlImporter::getFloatValue(ai_real &value) { void ObjFileMtlImporter::getFloatValue(ai_real &value) {
m_DataIt = CopyNextWord<DataArrayIt>(m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE); m_DataIt = CopyNextWord<DataArrayIt>(m_DataIt, m_DataItEnd, &m_buffer[0], BUFFERSIZE);
value = (ai_real)fast_atof(m_buffer); value = (ai_real)fast_atof(&m_buffer[0]);
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------

View File

@ -65,19 +65,18 @@ public:
typedef std::vector<char>::iterator DataArrayIt; typedef std::vector<char>::iterator DataArrayIt;
typedef std::vector<char>::const_iterator ConstDataArrayIt; typedef std::vector<char>::const_iterator ConstDataArrayIt;
public: //! \brief The class default constructor
//! \brief Default constructor
ObjFileMtlImporter(std::vector<char> &buffer, const std::string &strAbsPath, ObjFileMtlImporter(std::vector<char> &buffer, const std::string &strAbsPath,
ObjFile::Model *pModel); ObjFile::Model *pModel);
//! \brief DEstructor //! \brief The class destructor
~ObjFileMtlImporter(); ~ObjFileMtlImporter();
ObjFileMtlImporter(const ObjFileMtlImporter &rOther) = delete;
ObjFileMtlImporter &operator=(const ObjFileMtlImporter &rOther) = delete;
private: private:
/// Copy constructor, empty. /// 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 /// Load the whole material description
void load(); void load();
/// Get color data. /// Get color data.
@ -104,7 +103,7 @@ private:
//! Current line in file //! Current line in file
unsigned int m_uiLine; unsigned int m_uiLine;
//! Helper buffer //! Helper buffer
char m_buffer[BUFFERSIZE]; std::vector<char> m_buffer;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -5,7 +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,
@ -47,12 +46,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER #ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
// internal headers // internal headers
#include "PlyLoader.h" # include "PlyLoader.h"
#include <assimp/IOStreamBuffer.h> # include <assimp/IOStreamBuffer.h>
#include <assimp/importerdesc.h> # include <assimp/importerdesc.h>
#include <assimp/scene.h> # include <assimp/scene.h>
#include <assimp/IOSystem.hpp> # include <assimp/IOSystem.hpp>
#include <memory> # include <memory>
using namespace ::Assimp; using namespace ::Assimp;
@ -87,7 +86,9 @@ inline const T &GetProperty(const std::vector<T> &props, int idx) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
PLYImporter::PLYImporter() : PLYImporter::PLYImporter() :
mBuffer(nullptr), pcDOM(nullptr), mGeneratedMesh(nullptr) { mBuffer(nullptr),
pcDOM(nullptr),
mGeneratedMesh(nullptr) {
// empty // empty
} }
@ -127,15 +128,15 @@ static bool isBigEndian(const char *szMe) {
// binary_little_endian // binary_little_endian
// binary_big_endian // binary_big_endian
bool isBigEndian(false); bool isBigEndian(false);
#if (defined AI_BUILD_BIG_ENDIAN) # if (defined AI_BUILD_BIG_ENDIAN)
if ('l' == *szMe || 'L' == *szMe) { if ('l' == *szMe || 'L' == *szMe) {
isBigEndian = true; isBigEndian = true;
} }
#else # else
if ('b' == *szMe || 'B' == *szMe) { if ('b' == *szMe || 'B' == *szMe) {
isBigEndian = true; isBigEndian = true;
} }
#endif // ! AI_BUILD_BIG_ENDIAN # endif // ! AI_BUILD_BIG_ENDIAN
return isBigEndian; return isBigEndian;
} }

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,
@ -46,9 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_PLYLOADER_H_INCLUDED #ifndef AI_PLYLOADER_H_INCLUDED
#define AI_PLYLOADER_H_INCLUDED #define AI_PLYLOADER_H_INCLUDED
#include "PlyParser.h"
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/types.h> #include <assimp/types.h>
#include "PlyParser.h"
#include <vector> #include <vector>
struct aiNode; struct aiNode;
@ -62,77 +61,72 @@ using namespace PLY;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Importer class to load the stanford PLY file format /** Importer class to load the stanford PLY file format
*/ */
class PLYImporter : public BaseImporter class PLYImporter : public BaseImporter {
{
public: public:
PLYImporter(); PLYImporter();
~PLYImporter(); ~PLYImporter();
public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
*/ */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const; bool checkSig) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Extract a vertex from the DOM /** Extract a vertex from the DOM
*/ */
void LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos); void LoadVertex(const PLY::Element *pcElement, const PLY::ElementInstance *instElement, unsigned int pos);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Extract a face from the DOM /** Extract a face from the DOM
*/ */
void LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos); void LoadFace(const PLY::Element *pcElement, const PLY::ElementInstance *instElement, unsigned int pos);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
*/ */
const aiImporterDesc* GetInfo () const; const aiImporterDesc *GetInfo() const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details * See BaseImporter::InternReadFile() for details
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler); IOSystem *pIOHandler);
protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Extract a material list from the DOM /** Extract a material list from the DOM
*/ */
void LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &defaultTexture, const bool pointsOnly); void LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &defaultTexture, const bool pointsOnly);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Static helper to parse a color from four single channels in /** Static helper to parse a color from four single channels in
*/ */
static void GetMaterialColor( static void GetMaterialColor(
const std::vector<PLY::PropertyInstance>& avList, const std::vector<PLY::PropertyInstance> &avList,
unsigned int aiPositions[4], unsigned int aiPositions[4],
PLY::EDataType aiTypes[4], PLY::EDataType aiTypes[4],
aiColor4D* clrOut); aiColor4D *clrOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Static helper to parse a color channel value. The input value /** Static helper to parse a color channel value. The input value
* is normalized to 0-1. * is normalized to 0-1.
*/ */
static ai_real NormalizeColorValue ( static ai_real NormalizeColorValue(
PLY::PropertyInstance::ValueUnion val, PLY::PropertyInstance::ValueUnion val,
PLY::EDataType eType); PLY::EDataType eType);
/** Buffer to hold the loaded file */ /** Buffer to hold the loaded file */
unsigned char* mBuffer; unsigned char *mBuffer;
/** Document object model representation extracted from the file */ /** Document object model representation extracted from the file */
PLY::DOM* pcDOM; PLY::DOM *pcDOM;
/** Mesh generated by loader */ /** Mesh generated by loader */
aiMesh* mGeneratedMesh; aiMesh *mGeneratedMesh;
}; };
} // end of namespace Assimp } // end of namespace Assimp

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,
@ -44,24 +42,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines a post processing step to search an importer's output /** @file Defines a post processing step to search an importer's output
for data that is obviously invalid */ for data that is obviously invalid */
#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS #ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
// internal headers // internal headers
#include "FindInvalidDataProcess.h" # include "FindInvalidDataProcess.h"
#include "ProcessHelper.h" # include "ProcessHelper.h"
#include <assimp/Exceptional.h> # include <assimp/Exceptional.h>
#include <assimp/qnan.h> # include <assimp/qnan.h>
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
FindInvalidDataProcess::FindInvalidDataProcess() FindInvalidDataProcess::FindInvalidDataProcess() :
: configEpsilon(0.0) configEpsilon(0.0), mIgnoreTexCoods(false) {
, mIgnoreTexCoods( false ){
// nothing to do here // nothing to do here
} }
@ -73,47 +68,47 @@ FindInvalidDataProcess::~FindInvalidDataProcess() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool FindInvalidDataProcess::IsActive( unsigned int pFlags) const { bool FindInvalidDataProcess::IsActive(unsigned int pFlags) const {
return 0 != (pFlags & aiProcess_FindInvalidData); return 0 != (pFlags & aiProcess_FindInvalidData);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup import configuration // Setup import configuration
void FindInvalidDataProcess::SetupProperties(const Importer* pImp) { void FindInvalidDataProcess::SetupProperties(const Importer *pImp) {
// Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY // Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY
configEpsilon = (0 != pImp->GetPropertyFloat(AI_CONFIG_PP_FID_ANIM_ACCURACY,0.f)); configEpsilon = (0 != pImp->GetPropertyFloat(AI_CONFIG_PP_FID_ANIM_ACCURACY, 0.f));
mIgnoreTexCoods = pImp->GetPropertyBool(AI_CONFIG_PP_FID_IGNORE_TEXTURECOORDS, false); mIgnoreTexCoods = pImp->GetPropertyBool(AI_CONFIG_PP_FID_IGNORE_TEXTURECOORDS, false);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Update mesh references in the node graph // Update mesh references in the node graph
void UpdateMeshReferences(aiNode* node, const std::vector<unsigned int>& meshMapping) { void UpdateMeshReferences(aiNode *node, const std::vector<unsigned int> &meshMapping) {
if (node->mNumMeshes) { if (node->mNumMeshes) {
unsigned int out = 0; unsigned int out = 0;
for (unsigned int a = 0; a < node->mNumMeshes;++a) { for (unsigned int a = 0; a < node->mNumMeshes; ++a) {
unsigned int ref = node->mMeshes[a]; unsigned int ref = node->mMeshes[a];
if (UINT_MAX != (ref = meshMapping[ref])) { if (UINT_MAX != (ref = meshMapping[ref])) {
node->mMeshes[out++] = ref; node->mMeshes[out++] = ref;
} }
} }
// just let the members that are unused, that's much cheaper // just let the members that are unused, that's much cheaper
// than a full array realloc'n'copy party ... // than a full array realloc'n'copy party ...
node->mNumMeshes = out; node->mNumMeshes = out;
if ( 0 == out ) { if (0 == out) {
delete[] node->mMeshes; delete[] node->mMeshes;
node->mMeshes = NULL; node->mMeshes = NULL;
} }
} }
// recursively update all children // recursively update all children
for (unsigned int i = 0; i < node->mNumChildren;++i) { for (unsigned int i = 0; i < node->mNumChildren; ++i) {
UpdateMeshReferences(node->mChildren[i],meshMapping); UpdateMeshReferences(node->mChildren[i], meshMapping);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FindInvalidDataProcess::Execute( aiScene* pScene) { void FindInvalidDataProcess::Execute(aiScene *pScene) {
ASSIMP_LOG_DEBUG("FindInvalidDataProcess begin"); ASSIMP_LOG_DEBUG("FindInvalidDataProcess begin");
bool out = false; bool out = false;
@ -121,32 +116,31 @@ void FindInvalidDataProcess::Execute( aiScene* pScene) {
unsigned int real = 0; unsigned int real = 0;
// Process meshes // Process meshes
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { for (unsigned int a = 0; a < pScene->mNumMeshes; a++) {
int result = ProcessMesh(pScene->mMeshes[a]); int result = ProcessMesh(pScene->mMeshes[a]);
if (0 == result ) { if (0 == result) {
out = true; out = true;
if (2 == result) {
// remove this mesh
delete pScene->mMeshes[a];
AI_DEBUG_INVALIDATE_PTR(pScene->mMeshes[a]);
meshMapping[a] = UINT_MAX;
continue;
}
} }
if (2 == result) {
// remove this mesh
delete pScene->mMeshes[a];
AI_DEBUG_INVALIDATE_PTR(pScene->mMeshes[a]);
meshMapping[a] = UINT_MAX;
continue;
}
pScene->mMeshes[real] = pScene->mMeshes[a]; pScene->mMeshes[real] = pScene->mMeshes[a];
meshMapping[a] = real++; meshMapping[a] = real++;
} }
// Process animations // Process animations
for (unsigned int animIdx = 0; animIdx < pScene->mNumAnimations; ++animIdx) { for (unsigned int animIdx = 0; animIdx < pScene->mNumAnimations; ++animIdx) {
ProcessAnimation(pScene->mAnimations[animIdx]); ProcessAnimation(pScene->mAnimations[animIdx]);
} }
if (out) {
if (out) { if (real != pScene->mNumMeshes) {
if ( real != pScene->mNumMeshes) {
if (!real) { if (!real) {
throw DeadlyImportError("No meshes remaining"); throw DeadlyImportError("No meshes remaining");
} }
@ -154,7 +148,7 @@ void FindInvalidDataProcess::Execute( aiScene* pScene) {
// we need to remove some meshes. // we need to remove some meshes.
// therefore we'll also need to remove all references // therefore we'll also need to remove all references
// to them from the scenegraph // to them from the scenegraph
UpdateMeshReferences(pScene->mRootNode,meshMapping); UpdateMeshReferences(pScene->mRootNode, meshMapping);
pScene->mNumMeshes = real; pScene->mNumMeshes = real;
} }
@ -166,35 +160,32 @@ void FindInvalidDataProcess::Execute( aiScene* pScene) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
inline inline const char *ValidateArrayContents(const T * /*arr*/, unsigned int /*size*/,
const char* ValidateArrayContents(const T* /*arr*/, unsigned int /*size*/, const std::vector<bool> & /*dirtyMask*/, bool /*mayBeIdentical = false*/, bool /*mayBeZero = true*/) {
const std::vector<bool>& /*dirtyMask*/, bool /*mayBeIdentical = false*/, bool /*mayBeZero = true*/)
{
return nullptr; return nullptr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <> template <>
inline inline const char *ValidateArrayContents<aiVector3D>(const aiVector3D *arr, unsigned int size,
const char* ValidateArrayContents<aiVector3D>(const aiVector3D* arr, unsigned int size, const std::vector<bool> &dirtyMask, bool mayBeIdentical, bool mayBeZero) {
const std::vector<bool>& dirtyMask, bool mayBeIdentical , bool mayBeZero ) {
bool b = false; bool b = false;
unsigned int cnt = 0; unsigned int cnt = 0;
for (unsigned int i = 0; i < size;++i) { for (unsigned int i = 0; i < size; ++i) {
if (dirtyMask.size() && dirtyMask[i]) { if (dirtyMask.size() && dirtyMask[i]) {
continue; continue;
} }
++cnt; ++cnt;
const aiVector3D& v = arr[i]; const aiVector3D &v = arr[i];
if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z)) { if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z)) {
return "INF/NAN was found in a vector component"; return "INF/NAN was found in a vector component";
} }
if (!mayBeZero && !v.x && !v.y && !v.z ) { if (!mayBeZero && !v.x && !v.y && !v.z) {
return "Found zero-length vector"; return "Found zero-length vector";
} }
if (i && v != arr[i-1])b = true; if (i && v != arr[i - 1]) b = true;
} }
if (cnt > 1 && !b && !mayBeIdentical) { if (cnt > 1 && !b && !mayBeIdentical) {
return "All vectors are identical"; return "All vectors are identical";
@ -204,12 +195,11 @@ const char* ValidateArrayContents<aiVector3D>(const aiVector3D* arr, unsigned in
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
inline inline bool ProcessArray(T *&in, unsigned int num, const char *name,
bool ProcessArray(T*& in, unsigned int num,const char* name, const std::vector<bool> &dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true) {
const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true) { const char *err = ValidateArrayContents(in, num, dirtyMask, mayBeIdentical, mayBeZero);
const char* err = ValidateArrayContents(in,num,dirtyMask,mayBeIdentical,mayBeZero); if (err) {
if (err) { ASSIMP_LOG_ERROR_F("FindInvalidDataProcess fails on mesh ", name, ": ", err);
ASSIMP_LOG_ERROR_F( "FindInvalidDataProcess fails on mesh ", name, ": ", err);
delete[] in; delete[] in;
in = NULL; in = NULL;
return true; return true;
@ -219,49 +209,46 @@ bool ProcessArray(T*& in, unsigned int num,const char* name,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
AI_FORCE_INLINE bool EpsilonCompare(const T& n, const T& s, ai_real epsilon); AI_FORCE_INLINE bool EpsilonCompare(const T &n, const T &s, ai_real epsilon);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE bool EpsilonCompare(ai_real n, ai_real s, ai_real epsilon) { AI_FORCE_INLINE bool EpsilonCompare(ai_real n, ai_real s, ai_real epsilon) {
return std::fabs(n-s)>epsilon; return std::fabs(n - s) > epsilon;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <> template <>
bool EpsilonCompare<aiVectorKey>(const aiVectorKey& n, const aiVectorKey& s, ai_real epsilon) { bool EpsilonCompare<aiVectorKey>(const aiVectorKey &n, const aiVectorKey &s, ai_real epsilon) {
return return EpsilonCompare(n.mValue.x, s.mValue.x, epsilon) &&
EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) && EpsilonCompare(n.mValue.y, s.mValue.y, epsilon) &&
EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) && EpsilonCompare(n.mValue.z, s.mValue.z, epsilon);
EpsilonCompare(n.mValue.z,s.mValue.z,epsilon);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <> template <>
bool EpsilonCompare<aiQuatKey>(const aiQuatKey& n, const aiQuatKey& s, ai_real epsilon) { bool EpsilonCompare<aiQuatKey>(const aiQuatKey &n, const aiQuatKey &s, ai_real epsilon) {
return return EpsilonCompare(n.mValue.x, s.mValue.x, epsilon) &&
EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) && EpsilonCompare(n.mValue.y, s.mValue.y, epsilon) &&
EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) && EpsilonCompare(n.mValue.z, s.mValue.z, epsilon) &&
EpsilonCompare(n.mValue.z,s.mValue.z,epsilon) && EpsilonCompare(n.mValue.w, s.mValue.w, epsilon);
EpsilonCompare(n.mValue.w,s.mValue.w,epsilon);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <typename T> template <typename T>
inline inline bool AllIdentical(T *in, unsigned int num, ai_real epsilon) {
bool AllIdentical(T* in, unsigned int num, ai_real epsilon) {
if (num <= 1) { if (num <= 1) {
return true; return true;
} }
if (fabs(epsilon) > 0.f) { if (fabs(epsilon) > 0.f) {
for (unsigned int i = 0; i < num-1;++i) { for (unsigned int i = 0; i < num - 1; ++i) {
if (!EpsilonCompare(in[i],in[i+1],epsilon)) { if (!EpsilonCompare(in[i], in[i + 1], epsilon)) {
return false; return false;
} }
} }
} else { } else {
for (unsigned int i = 0; i < num-1;++i) { for (unsigned int i = 0; i < num - 1; ++i) {
if (in[i] != in[i+1]) { if (in[i] != in[i + 1]) {
return false; return false;
} }
} }
@ -271,16 +258,16 @@ bool AllIdentical(T* in, unsigned int num, ai_real epsilon) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Search an animation for invalid content // Search an animation for invalid content
void FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim) { void FindInvalidDataProcess::ProcessAnimation(aiAnimation *anim) {
// Process all animation channels // Process all animation channels
for ( unsigned int a = 0; a < anim->mNumChannels; ++a ) { for (unsigned int a = 0; a < anim->mNumChannels; ++a) {
ProcessAnimationChannel( anim->mChannels[a]); ProcessAnimationChannel(anim->mChannels[a]);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) { void FindInvalidDataProcess::ProcessAnimationChannel(aiNodeAnim *anim) {
ai_assert( nullptr != anim ); ai_assert(nullptr != anim);
if (anim->mNumPositionKeys == 0 && anim->mNumRotationKeys == 0 && anim->mNumScalingKeys == 0) { if (anim->mNumPositionKeys == 0 && anim->mNumRotationKeys == 0 && anim->mNumScalingKeys == 0) {
ai_assert_entry(); ai_assert_entry();
return; return;
@ -290,7 +277,7 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) {
// we can remove al keys except one. // we can remove al keys except one.
// POSITIONS // POSITIONS
int i = 0; int i = 0;
if (anim->mNumPositionKeys > 1 && AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys,configEpsilon)) { if (anim->mNumPositionKeys > 1 && AllIdentical(anim->mPositionKeys, anim->mNumPositionKeys, configEpsilon)) {
aiVectorKey v = anim->mPositionKeys[0]; aiVectorKey v = anim->mPositionKeys[0];
// Reallocate ... we need just ONE element, it makes no sense to reuse the array // Reallocate ... we need just ONE element, it makes no sense to reuse the array
@ -301,7 +288,7 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) {
} }
// ROTATIONS // ROTATIONS
if (anim->mNumRotationKeys > 1 && AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys,configEpsilon)) { if (anim->mNumRotationKeys > 1 && AllIdentical(anim->mRotationKeys, anim->mNumRotationKeys, configEpsilon)) {
aiQuatKey v = anim->mRotationKeys[0]; aiQuatKey v = anim->mRotationKeys[0];
// Reallocate ... we need just ONE element, it makes no sense to reuse the array // Reallocate ... we need just ONE element, it makes no sense to reuse the array
@ -312,7 +299,7 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) {
} }
// SCALINGS // SCALINGS
if (anim->mNumScalingKeys > 1 && AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys,configEpsilon)) { if (anim->mNumScalingKeys > 1 && AllIdentical(anim->mScalingKeys, anim->mNumScalingKeys, configEpsilon)) {
aiVectorKey v = anim->mScalingKeys[0]; aiVectorKey v = anim->mScalingKeys[0];
// Reallocate ... we need just ONE element, it makes no sense to reuse the array // Reallocate ... we need just ONE element, it makes no sense to reuse the array
@ -321,22 +308,21 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) {
anim->mScalingKeys[0] = v; anim->mScalingKeys[0] = v;
i = 1; i = 1;
} }
if ( 1 == i ) { if (1 == i) {
ASSIMP_LOG_WARN("Simplified dummy tracks with just one key"); ASSIMP_LOG_WARN("Simplified dummy tracks with just one key");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Search a mesh for invalid contents // Search a mesh for invalid contents
int FindInvalidDataProcess::ProcessMesh(aiMesh* pMesh) int FindInvalidDataProcess::ProcessMesh(aiMesh *pMesh) {
{
bool ret = false; bool ret = false;
std::vector<bool> dirtyMask(pMesh->mNumVertices, pMesh->mNumFaces != 0); std::vector<bool> dirtyMask(pMesh->mNumVertices, pMesh->mNumFaces != 0);
// Ignore elements that are not referenced by vertices. // Ignore elements that are not referenced by vertices.
// (they are, for example, caused by the FindDegenerates step) // (they are, for example, caused by the FindDegenerates step)
for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) { for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) {
const aiFace& f = pMesh->mFaces[m]; const aiFace &f = pMesh->mFaces[m];
for (unsigned int i = 0; i < f.mNumIndices; ++i) { for (unsigned int i = 0; i < f.mNumIndices; ++i) {
dirtyMask[f.mIndices[i]] = false; dirtyMask[f.mIndices[i]] = false;
@ -372,19 +358,17 @@ int FindInvalidDataProcess::ProcessMesh(aiMesh* pMesh)
// they are invalid or not. // they are invalid or not.
// Normals and tangents are undefined for point and line faces. // Normals and tangents are undefined for point and line faces.
if (pMesh->mNormals || pMesh->mTangents) { if (pMesh->mNormals || pMesh->mTangents) {
if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes || if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes ||
aiPrimitiveType_LINE & pMesh->mPrimitiveTypes) aiPrimitiveType_LINE & pMesh->mPrimitiveTypes) {
{
if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes || if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes ||
aiPrimitiveType_POLYGON & pMesh->mPrimitiveTypes) aiPrimitiveType_POLYGON & pMesh->mPrimitiveTypes) {
{
// We need to update the lookup-table // We need to update the lookup-table
for (unsigned int m = 0; m < pMesh->mNumFaces;++m) { for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) {
const aiFace& f = pMesh->mFaces[ m ]; const aiFace &f = pMesh->mFaces[m];
if (f.mNumIndices < 3) { if (f.mNumIndices < 3) {
dirtyMask[f.mIndices[0]] = true; dirtyMask[f.mIndices[0]] = true;
if (f.mNumIndices == 2) { if (f.mNumIndices == 2) {
dirtyMask[f.mIndices[1]] = true; dirtyMask[f.mIndices[1]] = true;
@ -400,19 +384,21 @@ int FindInvalidDataProcess::ProcessMesh(aiMesh* pMesh)
} }
// Process mesh normals // Process mesh normals
if (pMesh->mNormals && ProcessArray(pMesh->mNormals,pMesh->mNumVertices, if (pMesh->mNormals && ProcessArray(pMesh->mNormals, pMesh->mNumVertices,
"normals",dirtyMask,true,false)) "normals", dirtyMask, true, false))
ret = true; ret = true;
// Process mesh tangents // Process mesh tangents
if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices,"tangents",dirtyMask)) { if (pMesh->mTangents && ProcessArray(pMesh->mTangents, pMesh->mNumVertices, "tangents", dirtyMask)) {
delete[] pMesh->mBitangents; pMesh->mBitangents = NULL; delete[] pMesh->mBitangents;
pMesh->mBitangents = NULL;
ret = true; ret = true;
} }
// Process mesh bitangents // Process mesh bitangents
if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices,"bitangents",dirtyMask)) { if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents, pMesh->mNumVertices, "bitangents", dirtyMask)) {
delete[] pMesh->mTangents; pMesh->mTangents = NULL; delete[] pMesh->mTangents;
pMesh->mTangents = NULL;
ret = true; ret = true;
} }
} }

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,
@ -48,14 +47,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Common/BaseProcess.h" #include "Common/BaseProcess.h"
#include <assimp/types.h>
#include <assimp/anim.h> #include <assimp/anim.h>
#include <assimp/types.h>
struct aiMesh; struct aiMesh;
class FindInvalidDataProcessTest; class FindInvalidDataProcessTest;
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The FindInvalidData post-processing step. It searches the mesh data /** The FindInvalidData post-processing step. It searches the mesh data
@ -70,31 +69,31 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// //
bool IsActive( unsigned int pFlags) const; bool IsActive(unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Setup import settings // Setup import settings
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer *pImp);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Run the step // Run the step
void Execute( aiScene* pScene); void Execute(aiScene *pScene);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post-processing step on the given mesh /** Executes the post-processing step on the given mesh
* @param pMesh The mesh to process. * @param pMesh The mesh to process.
* @return 0 - nothing, 1 - removed sth, 2 - please delete me */ * @return 0 - nothing, 1 - removed sth, 2 - please delete me */
int ProcessMesh( aiMesh* pMesh); int ProcessMesh(aiMesh *pMesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post-processing step on the given animation /** Executes the post-processing step on the given animation
* @param anim The animation to process. */ * @param anim The animation to process. */
void ProcessAnimation (aiAnimation* anim); void ProcessAnimation(aiAnimation *anim);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post-processing step on the given anim channel /** Executes the post-processing step on the given anim channel
* @param anim The animation channel to process.*/ * @param anim The animation channel to process.*/
void ProcessAnimationChannel (aiNodeAnim* anim); void ProcessAnimationChannel(aiNodeAnim *anim);
private: private:
ai_real configEpsilon; ai_real configEpsilon;

View File

@ -44,44 +44,44 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#pragma once #pragma once
#ifndef AI_TYPES_H_INC #ifndef AI_TYPES_H_INC
#define AI_TYPES_H_INC # define AI_TYPES_H_INC
#ifdef __GNUC__ # ifdef __GNUC__
# pragma GCC system_header # pragma GCC system_header
#endif # endif
// Some runtime headers // Some runtime headers
#include <sys/types.h> # include <limits.h>
#include <stddef.h> # include <stddef.h>
#include <string.h> # include <stdint.h>
#include <limits.h> # include <string.h>
#include <stdint.h> # include <sys/types.h>
// Our compile configuration // Our compile configuration
#include <assimp/defs.h> # include <assimp/defs.h>
// Some types moved to separate header due to size of operators // Some types moved to separate header due to size of operators
#include <assimp/vector3.h> # include <assimp/color4.h>
#include <assimp/vector2.h> # include <assimp/matrix3x3.h>
#include <assimp/color4.h> # include <assimp/matrix4x4.h>
#include <assimp/matrix3x3.h> # include <assimp/quaternion.h>
#include <assimp/matrix4x4.h> # include <assimp/vector2.h>
#include <assimp/quaternion.h> # include <assimp/vector3.h>
typedef int32_t ai_int32; typedef int32_t ai_int32;
typedef uint32_t ai_uint32; typedef uint32_t ai_uint32;
#ifdef __cplusplus # ifdef __cplusplus
#include <cstring> # include <cstring>
#include <new> // for std::nothrow_t # include <new> // for std::nothrow_t
#include <string> // for aiString::Set(const std::string&) # include <string> // for aiString::Set(const std::string&)
namespace Assimp { namespace Assimp {
//! @cond never //! @cond never
namespace Intern { namespace Intern {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** @brief Internal helper class to utilize our internal new/delete /** @brief Internal helper class to utilize our internal new/delete
* routines for allocating object of this and derived classes. * routines for allocating object of this and derived classes.
* *
* By doing this you can safely share class objects between Assimp * By doing this you can safely share class objects between Assimp
@ -92,66 +92,68 @@ namespace Intern {
* If it lies on a different heap than Assimp is working with, * If it lies on a different heap than Assimp is working with,
* the application is determined to crash. * the application is determined to crash.
*/ */
// -------------------------------------------------------------------- // --------------------------------------------------------------------
#ifndef SWIG # ifndef SWIG
struct ASSIMP_API AllocateFromAssimpHeap { struct ASSIMP_API AllocateFromAssimpHeap {
// http://www.gotw.ca/publications/mill15.htm // http://www.gotw.ca/publications/mill15.htm
// new/delete overload // new/delete overload
void *operator new ( size_t num_bytes) /* throw( std::bad_alloc ) */; void *operator new(size_t num_bytes) /* throw( std::bad_alloc ) */;
void *operator new ( size_t num_bytes, const std::nothrow_t& ) throw(); void *operator new(size_t num_bytes, const std::nothrow_t &) throw();
void operator delete ( void* data); void operator delete(void *data);
// array new/delete overload // array new/delete overload
void *operator new[] ( size_t num_bytes) /* throw( std::bad_alloc ) */; void *operator new[](size_t num_bytes) /* throw( std::bad_alloc ) */;
void *operator new[] ( size_t num_bytes, const std::nothrow_t& ) throw(); void *operator new[](size_t num_bytes, const std::nothrow_t &) throw();
void operator delete[] ( void* data); void operator delete[](void *data);
}; // struct AllocateFromAssimpHeap }; // struct AllocateFromAssimpHeap
#endif # endif
} // namespace Intern } // namespace Intern
//! @endcond //! @endcond
} // namespace Assimp } // namespace Assimp
extern "C" { extern "C" {
#endif # endif
/** Maximum dimension for strings, ASSIMP strings are zero terminated. */ /** Maximum dimension for strings, ASSIMP strings are zero terminated. */
#ifdef __cplusplus # ifdef __cplusplus
static const size_t MAXLEN = 1024; static const size_t MAXLEN = 1024;
#else # else
# define MAXLEN 1024 # define MAXLEN 1024
#endif # endif
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Represents a plane in a three-dimensional, euclidean space /** Represents a plane in a three-dimensional, euclidean space
*/ */
struct aiPlane { struct aiPlane {
#ifdef __cplusplus # ifdef __cplusplus
aiPlane () AI_NO_EXCEPT : a(0.f), b(0.f), c(0.f), d(0.f) {} aiPlane() AI_NO_EXCEPT : a(0.f), b(0.f), c(0.f), d(0.f) {}
aiPlane (ai_real _a, ai_real _b, ai_real _c, ai_real _d) aiPlane(ai_real _a, ai_real _b, ai_real _c, ai_real _d) :
: a(_a), b(_b), c(_c), d(_d) {} a(_a), b(_b), c(_c), d(_d) {}
aiPlane (const aiPlane& o) : a(o.a), b(o.b), c(o.c), d(o.d) {} aiPlane(const aiPlane &o) :
a(o.a), b(o.b), c(o.c), d(o.d) {}
#endif // !__cplusplus # endif // !__cplusplus
//! Plane equation //! Plane equation
ai_real a,b,c,d; ai_real a, b, c, d;
}; // !struct aiPlane }; // !struct aiPlane
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Represents a ray /** Represents a ray
*/ */
struct aiRay { struct aiRay {
#ifdef __cplusplus # ifdef __cplusplus
aiRay () AI_NO_EXCEPT {} aiRay() AI_NO_EXCEPT {}
aiRay (const aiVector3D& _pos, const aiVector3D& _dir) aiRay(const aiVector3D &_pos, const aiVector3D &_dir) :
: pos(_pos), dir(_dir) {} pos(_pos), dir(_dir) {}
aiRay (const aiRay& o) : pos (o.pos), dir (o.dir) {} aiRay(const aiRay &o) :
pos(o.pos), dir(o.dir) {}
#endif // !__cplusplus # endif // !__cplusplus
//! Position and direction of the ray //! Position and direction of the ray
C_STRUCT aiVector3D pos, dir; C_STRUCT aiVector3D pos, dir;
@ -160,55 +162,55 @@ struct aiRay {
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Represents a color in Red-Green-Blue space. /** Represents a color in Red-Green-Blue space.
*/ */
struct aiColor3D struct aiColor3D {
{ # ifdef __cplusplus
#ifdef __cplusplus aiColor3D() AI_NO_EXCEPT : r(0.0f), g(0.0f), b(0.0f) {}
aiColor3D () AI_NO_EXCEPT : r(0.0f), g(0.0f), b(0.0f) {} aiColor3D(ai_real _r, ai_real _g, ai_real _b) :
aiColor3D (ai_real _r, ai_real _g, ai_real _b) : r(_r), g(_g), b(_b) {} r(_r), g(_g), b(_b) {}
explicit aiColor3D (ai_real _r) : r(_r), g(_r), b(_r) {} explicit aiColor3D(ai_real _r) :
aiColor3D (const aiColor3D& o) : r(o.r), g(o.g), b(o.b) {} r(_r), g(_r), b(_r) {}
aiColor3D(const aiColor3D &o) :
r(o.r), g(o.g), b(o.b) {}
aiColor3D &operator=(const aiColor3D &o) { aiColor3D &operator=(const aiColor3D &o) {
r = o.r; r = o.r;
g = o.g; g = o.g;
b = o.b; b = o.b;
return *this; return *this;
} }
/** Component-wise comparison */
// TODO: add epsilon?
bool operator == (const aiColor3D& other) const
{return r == other.r && g == other.g && b == other.b;}
/** Component-wise inverse comparison */
// TODO: add epsilon?
bool operator != (const aiColor3D& other) const
{return r != other.r || g != other.g || b != other.b;}
/** Component-wise comparison */ /** Component-wise comparison */
// TODO: add epsilon? // TODO: add epsilon?
bool operator < (const aiColor3D& other) const { bool operator==(const aiColor3D &other) const { return r == other.r && g == other.g && b == other.b; }
return r < other.r || ( r == other.r && (g < other.g || (g == other.g && b < other.b ) ) );
/** Component-wise inverse comparison */
// TODO: add epsilon?
bool operator!=(const aiColor3D &other) const { return r != other.r || g != other.g || b != other.b; }
/** Component-wise comparison */
// TODO: add epsilon?
bool operator<(const aiColor3D &other) const {
return r < other.r || (r == other.r && (g < other.g || (g == other.g && b < other.b)));
} }
/** Component-wise addition */ /** Component-wise addition */
aiColor3D operator+(const aiColor3D& c) const { aiColor3D operator+(const aiColor3D &c) const {
return aiColor3D(r+c.r,g+c.g,b+c.b); return aiColor3D(r + c.r, g + c.g, b + c.b);
} }
/** Component-wise subtraction */ /** Component-wise subtraction */
aiColor3D operator-(const aiColor3D& c) const { aiColor3D operator-(const aiColor3D &c) const {
return aiColor3D(r-c.r,g-c.g,b-c.b); return aiColor3D(r - c.r, g - c.g, b - c.b);
} }
/** Component-wise multiplication */ /** Component-wise multiplication */
aiColor3D operator*(const aiColor3D& c) const { aiColor3D operator*(const aiColor3D &c) const {
return aiColor3D(r*c.r,g*c.g,b*c.b); return aiColor3D(r * c.r, g * c.g, b * c.b);
} }
/** Multiply with a scalar */ /** Multiply with a scalar */
aiColor3D operator*(ai_real f) const { aiColor3D operator*(ai_real f) const {
return aiColor3D(r*f,g*f,b*f); return aiColor3D(r * f, g * f, b * f);
} }
/** Access a specific color component */ /** Access a specific color component */
@ -217,12 +219,12 @@ struct aiColor3D
} }
/** Access a specific color component */ /** Access a specific color component */
ai_real& operator[](unsigned int i) { ai_real &operator[](unsigned int i) {
if ( 0 == i ) { if (0 == i) {
return r; return r;
} else if ( 1 == i ) { } else if (1 == i) {
return g; return g;
} else if ( 2 == i ) { } else if (2 == i) {
return b; return b;
} }
return r; return r;
@ -231,14 +233,14 @@ struct aiColor3D
/** Check whether a color is black */ /** Check whether a color is black */
bool IsBlack() const { bool IsBlack() const {
static const ai_real epsilon = ai_real(10e-3); static const ai_real epsilon = ai_real(10e-3);
return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon; return std::fabs(r) < epsilon && std::fabs(g) < epsilon && std::fabs(b) < epsilon;
} }
#endif // !__cplusplus # endif // !__cplusplus
//! Red, green and blue color values //! Red, green and blue color values
ai_real r, g, b; ai_real r, g, b;
}; // !struct aiColor3D }; // !struct aiColor3D
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Represents an UTF-8 string, zero byte terminated. /** Represents an UTF-8 string, zero byte terminated.
@ -261,99 +263,95 @@ struct aiColor3D
* (binary) length of such a string is limited to MAXLEN characters (including the * (binary) length of such a string is limited to MAXLEN characters (including the
* the terminating zero). * the terminating zero).
*/ */
struct aiString struct aiString {
{ # ifdef __cplusplus
#ifdef __cplusplus
/** Default constructor, the string is set to have zero length */ /** Default constructor, the string is set to have zero length */
aiString() AI_NO_EXCEPT aiString() AI_NO_EXCEPT
: length( 0 ) { : length(0) {
data[0] = '\0'; data[0] = '\0';
#ifdef ASSIMP_BUILD_DEBUG # ifdef ASSIMP_BUILD_DEBUG
// Debug build: overwrite the string on its full length with ESC (27) // Debug build: overwrite the string on its full length with ESC (27)
memset(data+1,27,MAXLEN-1); memset(data + 1, 27, MAXLEN - 1);
#endif # endif
} }
/** Copy constructor */ /** Copy constructor */
aiString(const aiString& rOther) aiString(const aiString &rOther) :
: length(rOther.length) length(rOther.length) {
{
// Crop the string to the maximum length // Crop the string to the maximum length
length = length>=MAXLEN?MAXLEN-1:length; length = length >= MAXLEN ? MAXLEN - 1 : length;
memcpy( data, rOther.data, length); memcpy(data, rOther.data, length);
data[length] = '\0'; data[length] = '\0';
} }
/** Constructor from std::string */ /** Constructor from std::string */
explicit aiString(const std::string& pString) : explicit aiString(const std::string &pString) :
length( (ai_uint32) pString.length()) length((ai_uint32)pString.length()) {
{ length = length >= MAXLEN ? MAXLEN - 1 : length;
length = length>=MAXLEN?MAXLEN-1:length; memcpy(data, pString.c_str(), length);
memcpy( data, pString.c_str(), length);
data[length] = '\0'; data[length] = '\0';
} }
/** Copy a std::string to the aiString */ /** Copy a std::string to the aiString */
void Set( const std::string& pString) { void Set(const std::string &pString) {
if( pString.length() > MAXLEN - 1) { if (pString.length() > MAXLEN - 1) {
return; return;
} }
length = (ai_uint32)pString.length(); length = (ai_uint32)pString.length();
memcpy( data, pString.c_str(), length); memcpy(data, pString.c_str(), length);
data[length] = 0; data[length] = 0;
} }
/** Copy a const char* to the aiString */ /** Copy a const char* to the aiString */
void Set( const char* sz) { void Set(const char *sz) {
const ai_int32 len = (ai_uint32) ::strlen(sz); const ai_int32 len = (ai_uint32)::strlen(sz);
if( len > (ai_int32)MAXLEN - 1) { if (len > (ai_int32)MAXLEN - 1) {
return; return;
} }
length = len; length = len;
memcpy( data, sz, len); memcpy(data, sz, len);
data[len] = 0; data[len] = 0;
} }
/** Assignment operator */ /** Assignment operator */
aiString& operator = (const aiString &rOther) { aiString &operator=(const aiString &rOther) {
if (this == &rOther) { if (this == &rOther) {
return *this; return *this;
} }
length = rOther.length;; length = rOther.length;
memcpy( data, rOther.data, length); ;
memcpy(data, rOther.data, length);
data[length] = '\0'; data[length] = '\0';
return *this; return *this;
} }
/** Assign a const char* to the string */ /** Assign a const char* to the string */
aiString& operator = (const char* sz) { aiString &operator=(const char *sz) {
Set(sz); Set(sz);
return *this; return *this;
} }
/** Assign a cstd::string to the string */ /** Assign a cstd::string to the string */
aiString& operator = ( const std::string& pString) { aiString &operator=(const std::string &pString) {
Set(pString); Set(pString);
return *this; return *this;
} }
/** Comparison operator */ /** Comparison operator */
bool operator==(const aiString& other) const { bool operator==(const aiString &other) const {
return (length == other.length && 0 == memcmp(data,other.data,length)); return (length == other.length && 0 == memcmp(data, other.data, length));
} }
/** Inverse comparison operator */ /** Inverse comparison operator */
bool operator!=(const aiString& other) const { bool operator!=(const aiString &other) const {
return (length != other.length || 0 != memcmp(data,other.data,length)); return (length != other.length || 0 != memcmp(data, other.data, length));
} }
/** Append a string to the string */ /** Append a string to the string */
void Append (const char* app) { void Append(const char *app) {
const ai_uint32 len = (ai_uint32) ::strlen(app); const ai_uint32 len = (ai_uint32)::strlen(app);
if (!len) { if (!len) {
return; return;
} }
@ -361,27 +359,27 @@ struct aiString
return; return;
} }
memcpy(&data[length],app,len+1); memcpy(&data[length], app, len + 1);
length += len; length += len;
} }
/** Clear the string - reset its length to zero */ /** Clear the string - reset its length to zero */
void Clear () { void Clear() {
length = 0; length = 0;
data[0] = '\0'; data[0] = '\0';
#ifdef ASSIMP_BUILD_DEBUG # ifdef ASSIMP_BUILD_DEBUG
// Debug build: overwrite the string on its full length with ESC (27) // Debug build: overwrite the string on its full length with ESC (27)
memset(data+1,27,MAXLEN-1); memset(data + 1, 27, MAXLEN - 1);
#endif # endif
} }
/** Returns a pointer to the underlying zero-terminated array of characters */ /** Returns a pointer to the underlying zero-terminated array of characters */
const char* C_Str() const { const char *C_Str() const {
return data; return data;
} }
#endif // !__cplusplus # endif // !__cplusplus
/** Binary length of the string excluding the terminal 0. This is NOT the /** Binary length of the string excluding the terminal 0. This is NOT the
* logical length of strings containing UTF-8 multi-byte sequences! It's * logical length of strings containing UTF-8 multi-byte sequences! It's
@ -390,15 +388,13 @@ struct aiString
/** String buffer. Size limit is MAXLEN */ /** String buffer. Size limit is MAXLEN */
char data[MAXLEN]; char data[MAXLEN];
} ; // !struct aiString }; // !struct aiString
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Standard return type for some library functions. /** Standard return type for some library functions.
* Rarely used, and if, mostly in the C API. * Rarely used, and if, mostly in the C API.
*/ */
typedef enum aiReturn typedef enum aiReturn {
{
/** Indicates that a function was successful */ /** Indicates that a function was successful */
aiReturn_SUCCESS = 0x0, aiReturn_SUCCESS = 0x0,
@ -416,19 +412,18 @@ typedef enum aiReturn
_AI_ENFORCE_ENUM_SIZE = 0x7fffffff _AI_ENFORCE_ENUM_SIZE = 0x7fffffff
/// @endcond /// @endcond
} aiReturn; // !enum aiReturn } aiReturn; // !enum aiReturn
// just for backwards compatibility, don't use these constants anymore // just for backwards compatibility, don't use these constants anymore
#define AI_SUCCESS aiReturn_SUCCESS # define AI_SUCCESS aiReturn_SUCCESS
#define AI_FAILURE aiReturn_FAILURE # define AI_FAILURE aiReturn_FAILURE
#define AI_OUTOFMEMORY aiReturn_OUTOFMEMORY # define AI_OUTOFMEMORY aiReturn_OUTOFMEMORY
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Seek origins (for the virtual file system API). /** Seek origins (for the virtual file system API).
* Much cooler than using SEEK_SET, SEEK_CUR or SEEK_END. * Much cooler than using SEEK_SET, SEEK_CUR or SEEK_END.
*/ */
enum aiOrigin enum aiOrigin {
{
/** Beginning of the file */ /** Beginning of the file */
aiOrigin_SET = 0x0, aiOrigin_SET = 0x0,
@ -451,8 +446,7 @@ enum aiOrigin
* Logging to these streams can be enabled with a single call to * Logging to these streams can be enabled with a single call to
* #LogStream::createDefaultStream. * #LogStream::createDefaultStream.
*/ */
enum aiDefaultLogStream enum aiDefaultLogStream {
{
/** Stream the log to a file */ /** Stream the log to a file */
aiDefaultLogStream_FILE = 0x1, aiDefaultLogStream_FILE = 0x1,
@ -475,33 +469,31 @@ enum aiDefaultLogStream
}; // !enum aiDefaultLogStream }; // !enum aiDefaultLogStream
// just for backwards compatibility, don't use these constants anymore // just for backwards compatibility, don't use these constants anymore
#define DLS_FILE aiDefaultLogStream_FILE # define DLS_FILE aiDefaultLogStream_FILE
#define DLS_STDOUT aiDefaultLogStream_STDOUT # define DLS_STDOUT aiDefaultLogStream_STDOUT
#define DLS_STDERR aiDefaultLogStream_STDERR # define DLS_STDERR aiDefaultLogStream_STDERR
#define DLS_DEBUGGER aiDefaultLogStream_DEBUGGER # define DLS_DEBUGGER aiDefaultLogStream_DEBUGGER
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** Stores the memory requirements for different components (e.g. meshes, materials, /** Stores the memory requirements for different components (e.g. meshes, materials,
* animations) of an import. All sizes are in bytes. * animations) of an import. All sizes are in bytes.
* @see Importer::GetMemoryRequirements() * @see Importer::GetMemoryRequirements()
*/ */
struct aiMemoryInfo struct aiMemoryInfo {
{ # ifdef __cplusplus
#ifdef __cplusplus
/** Default constructor */ /** Default constructor */
aiMemoryInfo() AI_NO_EXCEPT aiMemoryInfo() AI_NO_EXCEPT
: textures (0) : textures(0),
, materials (0) materials(0),
, meshes (0) meshes(0),
, nodes (0) nodes(0),
, animations (0) animations(0),
, cameras (0) cameras(0),
, lights (0) lights(0),
, total (0) total(0) {}
{}
#endif # endif
/** Storage allocated for texture data */ /** Storage allocated for texture data */
unsigned int textures; unsigned int textures;
@ -528,16 +520,16 @@ struct aiMemoryInfo
unsigned int total; unsigned int total;
}; // !struct aiMemoryInfo }; // !struct aiMemoryInfo
#ifdef __cplusplus # ifdef __cplusplus
} }
#endif //! __cplusplus # endif //! __cplusplus
// Include implementation files // Include implementation files
#include "vector2.inl" # include "color4.inl"
#include "vector3.inl" # include "matrix3x3.inl"
#include "color4.inl" # include "matrix4x4.inl"
#include "quaternion.inl" # include "quaternion.inl"
#include "matrix3x3.inl" # include "vector2.inl"
#include "matrix4x4.inl" # include "vector3.inl"
#endif // AI_TYPES_H_INC #endif // AI_TYPES_H_INC