update assimp to 5.2.3 Bugfix-Release

This commit is contained in:
AzaezelX 2022-04-26 11:56:24 -05:00
parent 3f796d2a06
commit f297476092
1150 changed files with 165834 additions and 112019 deletions

View file

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2019, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@ -44,77 +44,73 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the material system of the library
*/
#include <assimp/Hash.h>
#include <assimp/fast_atof.h>
#include <assimp/ParsingUtils.h>
#include "MaterialSystem.h"
#include <assimp/types.h>
#include <assimp/Hash.h>
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/material.h>
#include <assimp/types.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Macros.h>
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Get a specific property from a material
aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
unsigned int index,
const aiMaterialProperty** pPropOut)
{
ai_assert( pMat != NULL );
ai_assert( pKey != NULL );
ai_assert( pPropOut != NULL );
aiReturn aiGetMaterialProperty(const aiMaterial *pMat,
const char *pKey,
unsigned int type,
unsigned int index,
const aiMaterialProperty **pPropOut) {
ai_assert(pMat != nullptr);
ai_assert(pKey != nullptr);
ai_assert(pPropOut != nullptr);
/* Just search for a property with exactly this name ..
* could be improved by hashing, but it's possibly
* no worth the effort (we're bound to C structures,
* thus std::map or derivates are not applicable. */
for ( unsigned int i = 0; i < pMat->mNumProperties; ++i ) {
aiMaterialProperty* prop = pMat->mProperties[i];
for (unsigned int i = 0; i < pMat->mNumProperties; ++i) {
aiMaterialProperty *prop = pMat->mProperties[i];
if (prop /* just for safety ... */
&& 0 == strcmp( prop->mKey.data, pKey )
&& (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wild-card, but this is undocumented :-) */
&& (UINT_MAX == index || prop->mIndex == index))
{
&& 0 == strcmp(prop->mKey.data, pKey) && (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wild-card, but this is undocumented :-) */
&& (UINT_MAX == index || prop->mIndex == index)) {
*pPropOut = pMat->mProperties[i];
return AI_SUCCESS;
}
}
*pPropOut = NULL;
*pPropOut = nullptr;
return AI_FAILURE;
}
// ------------------------------------------------------------------------------------------------
// Get an array of floating-point values from the material.
aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
unsigned int index,
ai_real* pOut,
unsigned int* pMax)
{
ai_assert( pOut != nullptr );
ai_assert( pMat != nullptr );
aiReturn aiGetMaterialFloatArray(const aiMaterial *pMat,
const char *pKey,
unsigned int type,
unsigned int index,
ai_real *pOut,
unsigned int *pMax) {
ai_assert(pOut != nullptr);
ai_assert(pMat != nullptr);
const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
if ( nullptr == prop) {
const aiMaterialProperty *prop;
aiGetMaterialProperty(pMat, pKey, type, index, (const aiMaterialProperty **)&prop);
if (nullptr == prop) {
return AI_FAILURE;
}
// data is given in floats, convert to ai_real
unsigned int iWrite = 0;
if( aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
if (aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
iWrite = prop->mDataLength / sizeof(float);
if (pMax) {
iWrite = std::min(*pMax,iWrite); ;
iWrite = std::min(*pMax, iWrite);
;
}
for (unsigned int a = 0; a < iWrite; ++a) {
pOut[ a ] = static_cast<ai_real> ( reinterpret_cast<float*>(prop->mData)[a] );
pOut[a] = static_cast<ai_real>(reinterpret_cast<float *>(prop->mData)[a]);
}
if (pMax) {
@ -122,26 +118,28 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
}
}
// data is given in doubles, convert to float
else if( aiPTI_Double == prop->mType) {
else if (aiPTI_Double == prop->mType) {
iWrite = prop->mDataLength / sizeof(double);
if (pMax) {
iWrite = std::min(*pMax,iWrite); ;
iWrite = std::min(*pMax, iWrite);
;
}
for (unsigned int a = 0; a < iWrite;++a) {
pOut[a] = static_cast<ai_real> ( reinterpret_cast<double*>(prop->mData)[a] );
for (unsigned int a = 0; a < iWrite; ++a) {
pOut[a] = static_cast<ai_real>(reinterpret_cast<double *>(prop->mData)[a]);
}
if (pMax) {
*pMax = iWrite;
}
}
// data is given in ints, convert to float
else if( aiPTI_Integer == prop->mType) {
else if (aiPTI_Integer == prop->mType) {
iWrite = prop->mDataLength / sizeof(int32_t);
if (pMax) {
iWrite = std::min(*pMax,iWrite); ;
iWrite = std::min(*pMax, iWrite);
;
}
for (unsigned int a = 0; a < iWrite;++a) {
pOut[a] = static_cast<ai_real> ( reinterpret_cast<int32_t*>(prop->mData)[a] );
for (unsigned int a = 0; a < iWrite; ++a) {
pOut[a] = static_cast<ai_real>(reinterpret_cast<int32_t *>(prop->mData)[a]);
}
if (pMax) {
*pMax = iWrite;
@ -154,16 +152,16 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
}
// strings are zero-terminated with a 32 bit length prefix, so this is safe
const char *cur = prop->mData + 4;
ai_assert( prop->mDataLength >= 5 );
ai_assert( !prop->mData[ prop->mDataLength - 1 ] );
for ( unsigned int a = 0; ;++a) {
cur = fast_atoreal_move<ai_real>(cur,pOut[a]);
if ( a==iWrite-1 ) {
ai_assert(prop->mDataLength >= 5);
ai_assert(!prop->mData[prop->mDataLength - 1]);
for (unsigned int a = 0;; ++a) {
cur = fast_atoreal_move<ai_real>(cur, pOut[a]);
if (a == iWrite - 1) {
break;
}
if ( !IsSpace(*cur) ) {
ASSIMP_LOG_ERROR("Material property" + std::string(pKey) +
" is a string; failed to parse a float array out of it.");
if (!IsSpace(*cur)) {
ASSIMP_LOG_ERROR("Material property", pKey,
" is a string; failed to parse a float array out of it.");
return AI_FAILURE;
}
}
@ -177,36 +175,34 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
// ------------------------------------------------------------------------------------------------
// Get an array if integers from the material
aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
unsigned int index,
int* pOut,
unsigned int* pMax)
{
ai_assert( pOut != NULL );
ai_assert( pMat != NULL );
aiReturn aiGetMaterialIntegerArray(const aiMaterial *pMat,
const char *pKey,
unsigned int type,
unsigned int index,
int *pOut,
unsigned int *pMax) {
ai_assert(pOut != nullptr);
ai_assert(pMat != nullptr);
const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop);
const aiMaterialProperty *prop;
aiGetMaterialProperty(pMat, pKey, type, index, (const aiMaterialProperty **)&prop);
if (!prop) {
return AI_FAILURE;
}
// data is given in ints, simply copy it
unsigned int iWrite = 0;
if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
if (aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
iWrite = std::max(static_cast<unsigned int>(prop->mDataLength / sizeof(int32_t)), 1u);
if (pMax) {
iWrite = std::min(*pMax,iWrite);
iWrite = std::min(*pMax, iWrite);
}
if (1 == prop->mDataLength) {
// bool type, 1 byte
*pOut = static_cast<int>(*prop->mData);
}
else {
for (unsigned int a = 0; a < iWrite;++a) {
pOut[a] = static_cast<int>(reinterpret_cast<int32_t*>(prop->mData)[a]);
} else {
for (unsigned int a = 0; a < iWrite; ++a) {
pOut[a] = static_cast<int>(reinterpret_cast<int32_t *>(prop->mData)[a]);
}
}
if (pMax) {
@ -214,35 +210,36 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
}
}
// data is given in floats convert to int
else if( aiPTI_Float == prop->mType) {
else if (aiPTI_Float == prop->mType) {
iWrite = prop->mDataLength / sizeof(float);
if (pMax) {
iWrite = std::min(*pMax,iWrite); ;
iWrite = std::min(*pMax, iWrite);
;
}
for (unsigned int a = 0; a < iWrite;++a) {
pOut[a] = static_cast<int>(reinterpret_cast<float*>(prop->mData)[a]);
for (unsigned int a = 0; a < iWrite; ++a) {
pOut[a] = static_cast<int>(reinterpret_cast<float *>(prop->mData)[a]);
}
if (pMax) {
*pMax = iWrite;
}
}
// it is a string ... no way to read something out of this
else {
else {
if (pMax) {
iWrite = *pMax;
}
// strings are zero-terminated with a 32 bit length prefix, so this is safe
const char *cur = prop->mData+4;
ai_assert( prop->mDataLength >= 5 );
ai_assert( !prop->mData[ prop->mDataLength - 1 ] );
for (unsigned int a = 0; ;++a) {
pOut[a] = strtol10(cur,&cur);
if(a==iWrite-1) {
const char *cur = prop->mData + 4;
ai_assert(prop->mDataLength >= 5);
ai_assert(!prop->mData[prop->mDataLength - 1]);
for (unsigned int a = 0;; ++a) {
pOut[a] = strtol10(cur, &cur);
if (a == iWrite - 1) {
break;
}
if(!IsSpace(*cur)) {
ASSIMP_LOG_ERROR("Material property" + std::string(pKey) +
" is a string; failed to parse an integer array out of it.");
if (!IsSpace(*cur)) {
ASSIMP_LOG_ERROR("Material property", pKey,
" is a string; failed to parse an integer array out of it.");
return AI_FAILURE;
}
}
@ -256,14 +253,13 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
// ------------------------------------------------------------------------------------------------
// Get a color (3 or 4 floats) from the material
aiReturn aiGetMaterialColor(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
unsigned int index,
aiColor4D* pOut)
{
aiReturn aiGetMaterialColor(const aiMaterial *pMat,
const char *pKey,
unsigned int type,
unsigned int index,
aiColor4D *pOut) {
unsigned int iMax = 4;
const aiReturn eRet = aiGetMaterialFloatArray(pMat,pKey,type,index,(ai_real*)pOut,&iMax);
const aiReturn eRet = aiGetMaterialFloatArray(pMat, pKey, type, index, (ai_real *)pOut, &iMax);
// if no alpha channel is defined: set it to 1.0
if (3 == iMax) {
@ -274,47 +270,43 @@ aiReturn aiGetMaterialColor(const aiMaterial* pMat,
}
// ------------------------------------------------------------------------------------------------
// Get a aiUVTransform (4 floats) from the material
aiReturn aiGetMaterialUVTransform(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
unsigned int index,
aiUVTransform* pOut)
{
unsigned int iMax = 4;
return aiGetMaterialFloatArray(pMat,pKey,type,index,(ai_real*)pOut,&iMax);
// Get a aiUVTransform (5 floats) from the material
aiReturn aiGetMaterialUVTransform(const aiMaterial *pMat,
const char *pKey,
unsigned int type,
unsigned int index,
aiUVTransform *pOut) {
unsigned int iMax = 5;
return aiGetMaterialFloatArray(pMat, pKey, type, index, (ai_real *)pOut, &iMax);
}
// ------------------------------------------------------------------------------------------------
// Get a string from the material
aiReturn aiGetMaterialString(const aiMaterial* pMat,
const char* pKey,
unsigned int type,
unsigned int index,
aiString* pOut)
{
ai_assert (pOut != NULL);
aiReturn aiGetMaterialString(const aiMaterial *pMat,
const char *pKey,
unsigned int type,
unsigned int index,
aiString *pOut) {
ai_assert(pOut != nullptr);
const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**)&prop);
const aiMaterialProperty *prop;
aiGetMaterialProperty(pMat, pKey, type, index, (const aiMaterialProperty **)&prop);
if (!prop) {
return AI_FAILURE;
}
if( aiPTI_String == prop->mType) {
ai_assert(prop->mDataLength>=5);
if (aiPTI_String == prop->mType) {
ai_assert(prop->mDataLength >= 5);
// The string is stored as 32 but length prefix followed by zero-terminated UTF8 data
pOut->length = static_cast<unsigned int>(*reinterpret_cast<uint32_t*>(prop->mData));
pOut->length = static_cast<unsigned int>(*reinterpret_cast<uint32_t *>(prop->mData));
ai_assert( pOut->length+1+4==prop->mDataLength );
ai_assert( !prop->mData[ prop->mDataLength - 1 ] );
memcpy(pOut->data,prop->mData+4,pOut->length+1);
}
else {
ai_assert(pOut->length + 1 + 4 == prop->mDataLength);
ai_assert(!prop->mData[prop->mDataLength - 1]);
memcpy(pOut->data, prop->mData + 4, pOut->length + 1);
} else {
// TODO - implement lexical cast as well
ASSIMP_LOG_ERROR("Material property" + std::string(pKey) +
" was found, but is no string" );
ASSIMP_LOG_ERROR("Material property", pKey, " was found, but is no string");
return AI_FAILURE;
}
return AI_SUCCESS;
@ -322,102 +314,94 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat,
// ------------------------------------------------------------------------------------------------
// Get the number of textures on a particular texture stack
unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
C_ENUM aiTextureType type)
{
ai_assert (pMat != NULL);
unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial *pMat, C_ENUM aiTextureType type) {
ai_assert(pMat != nullptr);
// Textures are always stored with ascending indices (ValidateDS provides a check, so we don't need to do it again)
unsigned int max = 0;
for (unsigned int i = 0; i < pMat->mNumProperties;++i) {
aiMaterialProperty* prop = pMat->mProperties[i];
for (unsigned int i = 0; i < pMat->mNumProperties; ++i) {
aiMaterialProperty *prop = pMat->mProperties[i];
if ( prop /* just a sanity check ... */
&& 0 == strcmp( prop->mKey.data, _AI_MATKEY_TEXTURE_BASE )
&& prop->mSemantic == type) {
if (prop /* just a sanity check ... */
&& 0 == strcmp(prop->mKey.data, _AI_MATKEY_TEXTURE_BASE) && static_cast<aiTextureType>(prop->mSemantic) == type) {
max = std::max(max,prop->mIndex+1);
max = std::max(max, prop->mIndex + 1);
}
}
return max;
}
// ------------------------------------------------------------------------------------------------
aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
aiTextureType type,
unsigned int index,
C_STRUCT aiString* path,
aiTextureMapping* _mapping /*= NULL*/,
unsigned int* uvindex /*= NULL*/,
ai_real* blend /*= NULL*/,
aiTextureOp* op /*= NULL*/,
aiTextureMapMode* mapmode /*= NULL*/,
unsigned int* flags /*= NULL*/
)
{
ai_assert( NULL != mat );
ai_assert( NULL != path );
aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial *mat,
aiTextureType type,
unsigned int index,
C_STRUCT aiString *path,
aiTextureMapping *_mapping /*= nullptr*/,
unsigned int *uvindex /*= nullptr*/,
ai_real *blend /*= nullptr*/,
aiTextureOp *op /*= nullptr*/,
aiTextureMapMode *mapmode /*= nullptr*/,
unsigned int *flags /*= nullptr*/
) {
ai_assert(nullptr != mat);
ai_assert(nullptr != path);
// Get the path to the texture
if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) {
if (AI_SUCCESS != aiGetMaterialString(mat, AI_MATKEY_TEXTURE(type, index), path)) {
return AI_FAILURE;
}
// Determine mapping type
int mapping_ = static_cast<int>(aiTextureMapping_UV);
aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index), &mapping_);
aiGetMaterialInteger(mat, AI_MATKEY_MAPPING(type, index), &mapping_);
aiTextureMapping mapping = static_cast<aiTextureMapping>(mapping_);
if (_mapping)
*_mapping = mapping;
// Get UV index
if (aiTextureMapping_UV == mapping && uvindex) {
aiGetMaterialInteger(mat,AI_MATKEY_UVWSRC(type,index),(int*)uvindex);
if (aiTextureMapping_UV == mapping && uvindex) {
aiGetMaterialInteger(mat, AI_MATKEY_UVWSRC(type, index), (int *)uvindex);
}
// Get blend factor
if (blend) {
aiGetMaterialFloat(mat,AI_MATKEY_TEXBLEND(type,index),blend);
if (blend) {
aiGetMaterialFloat(mat, AI_MATKEY_TEXBLEND(type, index), blend);
}
// Get texture operation
if (op){
aiGetMaterialInteger(mat,AI_MATKEY_TEXOP(type,index),(int*)op);
if (op) {
aiGetMaterialInteger(mat, AI_MATKEY_TEXOP(type, index), (int *)op);
}
// Get texture mapping modes
if (mapmode) {
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U(type,index),(int*)&mapmode[0]);
aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V(type,index),(int*)&mapmode[1]);
if (mapmode) {
aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_U(type, index), (int *)&mapmode[0]);
aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_V(type, index), (int *)&mapmode[1]);
}
// Get texture flags
if (flags){
aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags);
if (flags) {
aiGetMaterialInteger(mat, AI_MATKEY_TEXFLAGS(type, index), (int *)flags);
}
return AI_SUCCESS;
}
static const unsigned int DefaultNumAllocated = 5;
// ------------------------------------------------------------------------------------------------
// Construction. Actually the one and only way to get an aiMaterial instance
aiMaterial::aiMaterial()
: mProperties( nullptr )
, mNumProperties( 0 )
, mNumAllocated( DefaultNumAllocated ) {
aiMaterial::aiMaterial() :
mProperties(nullptr), mNumProperties(0), mNumAllocated(DefaultNumAllocated) {
// Allocate 5 entries by default
mProperties = new aiMaterialProperty*[ DefaultNumAllocated ];
mProperties = new aiMaterialProperty *[DefaultNumAllocated];
}
// ------------------------------------------------------------------------------------------------
aiMaterial::~aiMaterial()
{
aiMaterial::~aiMaterial() {
Clear();
delete[] mProperties;
}
// ------------------------------------------------------------------------------------------------
aiString aiMaterial::GetName() {
aiString aiMaterial::GetName() const {
aiString name;
Get(AI_MATKEY_NAME, name);
@ -425,11 +409,10 @@ aiString aiMaterial::GetName() {
}
// ------------------------------------------------------------------------------------------------
void aiMaterial::Clear()
{
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
void aiMaterial::Clear() {
for (unsigned int i = 0; i < mNumProperties; ++i) {
// delete this entry
delete mProperties[ i ];
delete mProperties[i];
AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
}
mNumProperties = 0;
@ -438,23 +421,21 @@ void aiMaterial::Clear()
}
// ------------------------------------------------------------------------------------------------
aiReturn aiMaterial::RemoveProperty ( const char* pKey,unsigned int type, unsigned int index )
{
ai_assert( nullptr != pKey );
aiReturn aiMaterial::RemoveProperty(const char *pKey, unsigned int type, unsigned int index) {
ai_assert(nullptr != pKey);
for (unsigned int i = 0; i < mNumProperties;++i) {
aiMaterialProperty* prop = mProperties[i];
for (unsigned int i = 0; i < mNumProperties; ++i) {
aiMaterialProperty *prop = mProperties[i];
if (prop && !strcmp( prop->mKey.data, pKey ) &&
prop->mSemantic == type && prop->mIndex == index)
{
if (prop && !strcmp(prop->mKey.data, pKey) &&
prop->mSemantic == type && prop->mIndex == index) {
// Delete this entry
delete mProperties[i];
// collapse the array behind --.
--mNumProperties;
for (unsigned int a = i; a < mNumProperties;++a) {
mProperties[a] = mProperties[a+1];
for (unsigned int a = i; a < mNumProperties; ++a) {
mProperties[a] = mProperties[a + 1];
}
return AI_SUCCESS;
}
@ -464,29 +445,27 @@ aiReturn aiMaterial::RemoveProperty ( const char* pKey,unsigned int type, unsign
}
// ------------------------------------------------------------------------------------------------
aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
unsigned int pSizeInBytes,
const char* pKey,
unsigned int type,
unsigned int index,
aiPropertyTypeInfo pType
)
{
ai_assert( pInput != NULL );
ai_assert( pKey != NULL );
ai_assert( 0 != pSizeInBytes );
if ( 0 == pSizeInBytes ) {
aiReturn aiMaterial::AddBinaryProperty(const void *pInput,
unsigned int pSizeInBytes,
const char *pKey,
unsigned int type,
unsigned int index,
aiPropertyTypeInfo pType) {
ai_assert(pInput != nullptr);
ai_assert(pKey != nullptr);
ai_assert(0 != pSizeInBytes);
if (0 == pSizeInBytes) {
return AI_FAILURE;
}
// first search the list whether there is already an entry with this key
unsigned int iOutIndex( UINT_MAX );
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
aiMaterialProperty *prop( mProperties[ i ] );
unsigned int iOutIndex(UINT_MAX);
for (unsigned int i = 0; i < mNumProperties; ++i) {
aiMaterialProperty *prop(mProperties[i]);
if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) &&
prop->mSemantic == type && prop->mIndex == index){
if (prop /* just for safety */ && !strcmp(prop->mKey.data, pKey) &&
prop->mSemantic == type && prop->mIndex == index) {
delete mProperties[i];
iOutIndex = i;
@ -494,7 +473,7 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
}
// Allocate a new material property
aiMaterialProperty* pcNew = new aiMaterialProperty();
aiMaterialProperty *pcNew = new aiMaterialProperty();
// .. and fill it
pcNew->mType = pType;
@ -503,32 +482,32 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
pcNew->mDataLength = pSizeInBytes;
pcNew->mData = new char[pSizeInBytes];
memcpy (pcNew->mData,pInput,pSizeInBytes);
memcpy(pcNew->mData, pInput, pSizeInBytes);
pcNew->mKey.length = ::strlen(pKey);
ai_assert ( MAXLEN > pcNew->mKey.length);
strcpy( pcNew->mKey.data, pKey );
pcNew->mKey.length = static_cast<ai_uint32>(::strlen(pKey));
ai_assert(MAXLEN > pcNew->mKey.length);
strcpy(pcNew->mKey.data, pKey);
if (UINT_MAX != iOutIndex) {
if (UINT_MAX != iOutIndex) {
mProperties[iOutIndex] = pcNew;
return AI_SUCCESS;
}
// resize the array ... double the storage allocated
if (mNumProperties == mNumAllocated) {
if (mNumProperties == mNumAllocated) {
const unsigned int iOld = mNumAllocated;
mNumAllocated *= 2;
aiMaterialProperty** ppTemp;
aiMaterialProperty **ppTemp;
try {
ppTemp = new aiMaterialProperty*[mNumAllocated];
} catch (std::bad_alloc&) {
ppTemp = new aiMaterialProperty *[mNumAllocated];
} catch (std::bad_alloc &) {
delete pcNew;
return AI_OUTOFMEMORY;
}
// just copy all items over; then replace the old array
memcpy (ppTemp,mProperties,iOld * sizeof(void*));
memcpy(ppTemp, mProperties, iOld * sizeof(void *));
delete[] mProperties;
mProperties = ppTemp;
@ -540,80 +519,82 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
}
// ------------------------------------------------------------------------------------------------
aiReturn aiMaterial::AddProperty (const aiString* pInput,
const char* pKey,
unsigned int type,
unsigned int index)
{
ai_assert(sizeof(ai_uint32)==4);
aiReturn aiMaterial::AddProperty(const aiString *pInput,
const char *pKey,
unsigned int type,
unsigned int index) {
ai_assert(sizeof(ai_uint32) == 4);
return AddBinaryProperty(pInput,
static_cast<unsigned int>(pInput->length+1+4),
pKey,
type,
index,
aiPTI_String);
static_cast<unsigned int>(pInput->length + 1 + 4),
pKey,
type,
index,
aiPTI_String);
}
// ------------------------------------------------------------------------------------------------
uint32_t Assimp::ComputeMaterialHash(const aiMaterial* mat, bool includeMatName /*= false*/)
{
uint32_t Assimp::ComputeMaterialHash(const aiMaterial *mat, bool includeMatName /*= false*/) {
uint32_t hash = 1503; // magic start value, chosen to be my birthday :-)
for ( unsigned int i = 0; i < mat->mNumProperties; ++i ) {
aiMaterialProperty* prop;
for (unsigned int i = 0; i < mat->mNumProperties; ++i) {
aiMaterialProperty *prop;
// Exclude all properties whose first character is '?' from the hash
// See doc for aiMaterialProperty.
if ((prop = mat->mProperties[i]) && (includeMatName || prop->mKey.data[0] != '?')) {
prop = mat->mProperties[i];
if (nullptr != prop && (includeMatName || prop->mKey.data[0] != '?')) {
hash = SuperFastHash(prop->mKey.data,(unsigned int)prop->mKey.length,hash);
hash = SuperFastHash(prop->mData,prop->mDataLength,hash);
hash = SuperFastHash(prop->mKey.data, (unsigned int)prop->mKey.length, hash);
hash = SuperFastHash(prop->mData, prop->mDataLength, hash);
// Combine the semantic and the index with the hash
hash = SuperFastHash((const char*)&prop->mSemantic,sizeof(unsigned int),hash);
hash = SuperFastHash((const char*)&prop->mIndex,sizeof(unsigned int),hash);
hash = SuperFastHash((const char *)&prop->mSemantic, sizeof(unsigned int), hash);
hash = SuperFastHash((const char *)&prop->mIndex, sizeof(unsigned int), hash);
}
}
return hash;
}
// ------------------------------------------------------------------------------------------------
void aiMaterial::CopyPropertyList(aiMaterial* pcDest,
const aiMaterial* pcSrc
)
{
ai_assert(NULL != pcDest);
ai_assert(NULL != pcSrc);
void aiMaterial::CopyPropertyList(aiMaterial *const pcDest,
const aiMaterial *pcSrc) {
ai_assert(nullptr != pcDest);
ai_assert(nullptr != pcSrc);
ai_assert(pcDest->mNumProperties <= pcDest->mNumAllocated);
ai_assert(pcSrc->mNumProperties <= pcSrc->mNumAllocated);
unsigned int iOldNum = pcDest->mNumProperties;
const unsigned int iOldNum = pcDest->mNumProperties;
pcDest->mNumAllocated += pcSrc->mNumAllocated;
pcDest->mNumProperties += pcSrc->mNumProperties;
aiMaterialProperty** pcOld = pcDest->mProperties;
pcDest->mProperties = new aiMaterialProperty*[pcDest->mNumAllocated];
const unsigned int numAllocated = pcDest->mNumAllocated;
aiMaterialProperty **pcOld = pcDest->mProperties;
pcDest->mProperties = new aiMaterialProperty *[numAllocated];
if (iOldNum && pcOld) {
for (unsigned int i = 0; i < iOldNum;++i) {
ai_assert(!iOldNum || pcOld);
ai_assert(iOldNum < numAllocated);
if (iOldNum && pcOld) {
for (unsigned int i = 0; i < iOldNum; ++i) {
pcDest->mProperties[i] = pcOld[i];
}
}
if ( pcOld ) {
if (pcOld) {
delete[] pcOld;
}
for (unsigned int i = iOldNum; i< pcDest->mNumProperties;++i) {
aiMaterialProperty* propSrc = pcSrc->mProperties[i];
for (unsigned int i = iOldNum; i < pcDest->mNumProperties; ++i) {
aiMaterialProperty *propSrc = pcSrc->mProperties[i];
// search whether we have already a property with this name -> if yes, overwrite it
aiMaterialProperty* prop;
for ( unsigned int q = 0; q < iOldNum; ++q ) {
aiMaterialProperty *prop;
for (unsigned int q = 0; q < iOldNum; ++q) {
prop = pcDest->mProperties[q];
if (prop /* just for safety */ && prop->mKey == propSrc->mKey && prop->mSemantic == propSrc->mSemantic
&& prop->mIndex == propSrc->mIndex) {
if (prop /* just for safety */ && prop->mKey == propSrc->mKey && prop->mSemantic == propSrc->mSemantic && prop->mIndex == propSrc->mIndex) {
delete prop;
// collapse the whole array ...
memmove(&pcDest->mProperties[q],&pcDest->mProperties[q+1],i-q);
memmove(&pcDest->mProperties[q], &pcDest->mProperties[q + 1], i - q);
i--;
pcDest->mNumProperties--;
}
@ -628,6 +609,6 @@ void aiMaterial::CopyPropertyList(aiMaterial* pcDest,
prop->mIndex = propSrc->mIndex;
prop->mData = new char[propSrc->mDataLength];
memcpy(prop->mData,propSrc->mData,prop->mDataLength);
memcpy(prop->mData, propSrc->mData, prop->mDataLength);
}
}