Merge pull request #2069 from assimp/issue_1724

closes https://github.com/assimp/assimp/issues/1724: add default mate…
pull/2068/head^2
Kim Kulling 2018-07-25 16:30:38 +02:00 committed by GitHub
commit 4a60190c52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 148 additions and 52 deletions

View File

@ -272,6 +272,8 @@ void aiReleaseImport( const aiScene* pScene)
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
// find the importer associated with this data // find the importer associated with this data
const ScenePrivateData* priv = ScenePriv(pScene); const ScenePrivateData* priv = ScenePriv(pScene);
if( !priv || !priv->mOrigImporter) { if( !priv || !priv->mOrigImporter) {

View File

@ -178,6 +178,7 @@ Importer::~Importer()
{ {
// Delete all import plugins // Delete all import plugins
DeleteImporterInstanceList(pimpl->mImporter); DeleteImporterInstanceList(pimpl->mImporter);
aiReleaseDefaultMaterial();
// Delete all post-processing plug-ins // Delete all post-processing plug-ins
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)
@ -383,6 +384,8 @@ bool _ValidateFlags(unsigned int pFlags)
void Importer::FreeScene( ) void Importer::FreeScene( )
{ {
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
delete pimpl->mScene; delete pimpl->mScene;
pimpl->mScene = NULL; pimpl->mScene = NULL;

View File

@ -63,9 +63,9 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
unsigned int index, unsigned int index,
const aiMaterialProperty** pPropOut) const aiMaterialProperty** pPropOut)
{ {
ai_assert (pMat != NULL); ai_assert( pMat != NULL );
ai_assert (pKey != NULL); ai_assert( pKey != NULL );
ai_assert (pPropOut != NULL); ai_assert( pPropOut != NULL );
/* Just search for a property with exactly this name .. /* Just search for a property with exactly this name ..
* could be improved by hashing, but it's possibly * could be improved by hashing, but it's possibly
@ -76,7 +76,7 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
if (prop /* just for safety ... */ if (prop /* just for safety ... */
&& 0 == strcmp( prop->mKey.data, pKey ) && 0 == strcmp( prop->mKey.data, pKey )
&& (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wildcard, but this is undocumented :-) */ && (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wild-card, but this is undocumented :-) */
&& (UINT_MAX == index || prop->mIndex == index)) && (UINT_MAX == index || prop->mIndex == index))
{ {
*pPropOut = pMat->mProperties[i]; *pPropOut = pMat->mProperties[i];
@ -96,8 +96,8 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
ai_real* pOut, ai_real* pOut,
unsigned int* pMax) unsigned int* pMax)
{ {
ai_assert (pOut != NULL); ai_assert( pOut != NULL );
ai_assert (pMat != NULL); ai_assert( pMat != NULL );
const aiMaterialProperty* prop; const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop); aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
@ -182,8 +182,8 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
int* pOut, int* pOut,
unsigned int* pMax) unsigned int* pMax)
{ {
ai_assert (pOut != NULL); ai_assert( pOut != NULL );
ai_assert (pMat != NULL); ai_assert( pMat != NULL );
const aiMaterialProperty* prop; const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop); aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop);
@ -314,7 +314,7 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get the number of textures on a particular texture stack // Get the number of textures on a particular texture stack
ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat, unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
C_ENUM aiTextureType type) C_ENUM aiTextureType type)
{ {
ai_assert (pMat != NULL); ai_assert (pMat != NULL);
@ -347,12 +347,14 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
unsigned int* flags /*= NULL*/ unsigned int* flags /*= NULL*/
) )
{ {
ai_assert(NULL != mat && NULL != path); ai_assert( NULL != mat );
ai_assert( NULL != path );
// Get the path to the texture // 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; return AI_FAILURE;
} }
// Determine mapping type // Determine mapping type
int mapping_ = static_cast<int>(aiTextureMapping_UV); int mapping_ = static_cast<int>(aiTextureMapping_UV);
aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index), &mapping_); aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index), &mapping_);
@ -381,15 +383,37 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
if (flags){ if (flags){
aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags); aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags);
} }
return AI_SUCCESS; return AI_SUCCESS;
} }
static aiMaterial *DefaultMaterial = nullptr;
// ------------------------------------------------------------------------------------------------
// Will return the default material.
aiMaterial *aiCreateAndRegisterDefaultMaterial() {
if (nullptr == DefaultMaterial) {
DefaultMaterial = new aiMaterial;
aiString s;
s.Set(AI_DEFAULT_MATERIAL_NAME);
DefaultMaterial->AddProperty(&s, AI_MATKEY_NAME);
}
return DefaultMaterial;
}
// ------------------------------------------------------------------------------------------------
// Will return the default material.
void aiReleaseDefaultMaterial() {
DefaultMaterial = nullptr;
}
static const unsigned int DefaultNumAllocated = 5; static const unsigned int DefaultNumAllocated = 5;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Construction. Actually the one and only way to get an aiMaterial instance // Construction. Actually the one and only way to get an aiMaterial instance
aiMaterial::aiMaterial() aiMaterial::aiMaterial()
: mProperties( NULL ) : mProperties( nullptr )
, mNumProperties( 0 ) , mNumProperties( 0 )
, mNumAllocated( DefaultNumAllocated ) { , mNumAllocated( DefaultNumAllocated ) {
// Allocate 5 entries by default // Allocate 5 entries by default
@ -404,12 +428,20 @@ aiMaterial::~aiMaterial()
delete[] mProperties; delete[] mProperties;
} }
// ------------------------------------------------------------------------------------------------
aiString aiMaterial::GetName() {
aiString name;
Get(AI_MATKEY_NAME, name);
return name;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void aiMaterial::Clear() void aiMaterial::Clear()
{ {
for (unsigned int i = 0; i < mNumProperties;++i) { for ( unsigned int i = 0; i < mNumProperties; ++i ) {
// delete this entry // delete this entry
delete mProperties[i]; delete mProperties[ i ];
AI_DEBUG_INVALIDATE_PTR(mProperties[i]); AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
} }
mNumProperties = 0; mNumProperties = 0;
@ -418,11 +450,9 @@ void aiMaterial::Clear()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiReturn aiMaterial::RemoveProperty (const char* pKey,unsigned int type, aiReturn aiMaterial::RemoveProperty ( const char* pKey,unsigned int type, unsigned int index )
unsigned int index
)
{ {
ai_assert(NULL != pKey); ai_assert( nullptr != pKey );
for (unsigned int i = 0; i < mNumProperties;++i) { for (unsigned int i = 0; i < mNumProperties;++i) {
aiMaterialProperty* prop = mProperties[i]; aiMaterialProperty* prop = mProperties[i];
@ -454,17 +484,18 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
aiPropertyTypeInfo pType aiPropertyTypeInfo pType
) )
{ {
ai_assert (pInput != NULL); ai_assert( pInput != NULL );
ai_assert (pKey != NULL); ai_assert( pKey != NULL );
ai_assert (0 != pSizeInBytes); ai_assert( 0 != pSizeInBytes );
if ( 0 == pSizeInBytes ) { if ( 0 == pSizeInBytes ) {
} }
// first search the list whether there is already an entry with this key // first search the list whether there is already an entry with this key
unsigned int iOutIndex = UINT_MAX; unsigned int iOutIndex( UINT_MAX );
for (unsigned int i = 0; i < mNumProperties;++i) { for ( unsigned int i = 0; i < mNumProperties; ++i ) {
aiMaterialProperty* prop = mProperties[i]; aiMaterialProperty *prop( mProperties[ i ] );
if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) && if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) &&
prop->mSemantic == type && prop->mIndex == index){ prop->mSemantic == type && prop->mIndex == index){
@ -516,6 +547,7 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
} }
// push back ... // push back ...
mProperties[mNumProperties++] = pcNew; mProperties[mNumProperties++] = pcNew;
return AI_SUCCESS; return AI_SUCCESS;
} }

View File

@ -84,8 +84,6 @@ static const std::string BumpOption = "-bm";
static const std::string ChannelOption = "-imfchan"; static const std::string ChannelOption = "-imfchan";
static const std::string TypeOption = "-type"; static const std::string TypeOption = "-type";
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Constructor // Constructor
ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer, ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,

View File

@ -90,6 +90,9 @@ static bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
return expectedBinaryFileSize == fileSize; return expectedBinaryFileSize == fileSize;
} }
static const size_t BufferSize = 500;
static const char UnicodeBoundary = 127;
// An ascii STL buffer will begin with "solid NAME", where NAME is optional. // An ascii STL buffer will begin with "solid NAME", where NAME is optional.
// Note: The "solid NAME" check is necessary, but not sufficient, to determine // Note: The "solid NAME" check is necessary, but not sufficient, to determine
// if the buffer is ASCII; a binary header could also begin with "solid NAME". // if the buffer is ASCII; a binary header could also begin with "solid NAME".
@ -108,10 +111,10 @@ static bool IsAsciiSTL(const char* buffer, unsigned int fileSize) {
bool isASCII( strncmp( buffer, "solid", 5 ) == 0 ); bool isASCII( strncmp( buffer, "solid", 5 ) == 0 );
if( isASCII ) { if( isASCII ) {
// A lot of importers are write solid even if the file is binary. So we have to check for ASCII-characters. // A lot of importers are write solid even if the file is binary. So we have to check for ASCII-characters.
if( fileSize >= 500 ) { if( fileSize >= BufferSize) {
isASCII = true; isASCII = true;
for( unsigned int i = 0; i < 500; i++ ) { for( unsigned int i = 0; i < BufferSize; i++ ) {
if( buffer[ i ] > 127 ) { if( buffer[ i ] > UnicodeBoundary) {
isASCII = false; isASCII = false;
break; break;
} }
@ -211,10 +214,11 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// create a single default material, using a white diffuse color for consistency with // create a single default material, using a white diffuse color for consistency with
// other geometric types (e.g., PLY). // other geometric types (e.g., PLY).
aiMaterial* pcMat = new aiMaterial(); aiMaterial* pcMat = aiCreateAndRegisterDefaultMaterial();
/*aiMaterial* pcMat = new aiMaterial();
aiString s; aiString s;
s.Set(AI_DEFAULT_MATERIAL_NAME); s.Set(AI_DEFAULT_MATERIAL_NAME);
pcMat->AddProperty(&s, AI_MATKEY_NAME); pcMat->AddProperty(&s, AI_MATKEY_NAME);*/
aiColor4D clrDiffuse(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0)); aiColor4D clrDiffuse(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0));
if (bMatClr) { if (bMatClr) {

View File

@ -55,12 +55,8 @@ namespace Assimp {
class Importer; class Importer;
struct ScenePrivateData { struct ScenePrivateData {
ScenePrivateData() // The struct constructor.
: mOrigImporter( nullptr ) ScenePrivateData();
, mPPStepsApplied( 0 )
, mIsCopy( false ) {
// empty
}
// Importer that originally loaded the scene though the C-API // Importer that originally loaded the scene though the C-API
// If set, this object is owned by this private data instance. // If set, this object is owned by this private data instance.
@ -77,6 +73,14 @@ struct ScenePrivateData {
bool mIsCopy; bool mIsCopy;
}; };
inline
ScenePrivateData::ScenePrivateData()
: mOrigImporter( nullptr )
, mPPStepsApplied( 0 )
, mIsCopy( false ) {
// empty
}
// Access private data stored in the scene // Access private data stored in the scene
inline inline
ScenePrivateData* ScenePriv(aiScene* in) { ScenePrivateData* ScenePriv(aiScene* in) {

View File

@ -150,9 +150,11 @@ ASSIMP_API aiScene::~aiScene() {
delete mMeshes[a]; delete mMeshes[a];
delete [] mMeshes; delete [] mMeshes;
if (mNumMaterials && mMaterials) if (mNumMaterials && mMaterials) {
for( unsigned int a = 0; a < mNumMaterials; a++) for (unsigned int a = 0; a < mNumMaterials; ++a ) {
delete mMaterials[a]; delete mMaterials[ a ];
}
}
delete [] mMaterials; delete [] mMaterials;
if (mNumAnimations && mAnimations) if (mNumAnimations && mAnimations)

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2012, assimp team Copyright (c) 2006-2018, assimp team
All rights reserved. All rights reserved.

View File

@ -612,12 +612,13 @@ struct aiMaterialProperty
, mIndex( 0 ) , mIndex( 0 )
, mDataLength( 0 ) , mDataLength( 0 )
, mType( aiPTI_Float ) , mType( aiPTI_Float )
, mData( NULL ) , mData(nullptr) {
{ // empty
} }
~aiMaterialProperty() { ~aiMaterialProperty() {
delete[] mData; delete[] mData;
mData = nullptr;
} }
#endif #endif
@ -651,6 +652,14 @@ public:
aiMaterial(); aiMaterial();
~aiMaterial(); ~aiMaterial();
// -------------------------------------------------------------------
/**
* @brief Returns the name of the material.
* @return The name of the material.
*/
// -------------------------------------------------------------------
aiString GetName();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Retrieve an array of Type values with a specific key /** @brief Retrieve an array of Type values with a specific key
* from the material * from the material
@ -1556,10 +1565,32 @@ C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
unsigned int* flags /*= NULL*/); unsigned int* flags /*= NULL*/);
#endif // !#ifdef __cplusplus #endif // !#ifdef __cplusplus
// ---------------------------------------------------------------------------
/** @brief Helper function to get all values pertaining to a particular
* texture slot from a material structure.
*
* @return Pointer showing to the default material.
*/
// ---------------------------------------------------------------------------
#ifdef __cplusplus
ASSIMP_API aiMaterial *aiCreateAndRegisterDefaultMaterial(void);
#else
C_STRUCT aiMaterial *aiCreateAndRegisterDefaultMaterial(void);
#endif // !#ifdef __cplusplus
// ---------------------------------------------------------------------------
/**
* @brief Helper function to release the default material instance, the
* instance will not be destroyed.
*/
// ---------------------------------------------------------------------------
ASSIMP_API void aiReleaseDefaultMaterial();
#ifdef __cplusplus #ifdef __cplusplus
} }
#include "material.inl" #include "material.inl"
#endif //!__cplusplus #endif //!__cplusplus
#endif //!!AI_MATERIAL_H_INC #endif //!!AI_MATERIAL_H_INC

View File

@ -130,7 +130,7 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
return AI_FAILURE; return AI_FAILURE;
} }
::memcpy(&pOut,prop->mData,sizeof(Type)); ::memcpy( &pOut, prop->mData, sizeof( Type ) );
} }
return ret; return ret;
} }

View File

@ -120,8 +120,7 @@ TEST_F(MaterialSystemTest, testColorProperty)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
TEST_F(MaterialSystemTest, testStringProperty) TEST_F(MaterialSystemTest, testStringProperty) {
{
aiString s; aiString s;
s.Set("Hello, this is a small test"); s.Set("Hello, this is a small test");
this->pcMat->AddProperty(&s,"testKey6"); this->pcMat->AddProperty(&s,"testKey6");
@ -129,3 +128,24 @@ TEST_F(MaterialSystemTest, testStringProperty)
EXPECT_EQ(AI_SUCCESS, pcMat->Get("testKey6",0,0,s)); EXPECT_EQ(AI_SUCCESS, pcMat->Get("testKey6",0,0,s));
EXPECT_STREQ("Hello, this is a small test", s.data); EXPECT_STREQ("Hello, this is a small test", s.data);
} }
// ------------------------------------------------------------------------------------------------
TEST_F(MaterialSystemTest, testDefaultMaterialAccess) {
aiMaterial *mat = aiCreateAndRegisterDefaultMaterial();
EXPECT_NE(nullptr, mat);
aiReleaseDefaultMaterial();
delete mat;
}
// ------------------------------------------------------------------------------------------------
TEST_F(MaterialSystemTest, testMaterialNameAccess) {
aiMaterial *mat = aiCreateAndRegisterDefaultMaterial();
EXPECT_NE(nullptr, mat);
aiString name = mat->GetName();
const int retValue(strncmp(name.C_Str(), AI_DEFAULT_MATERIAL_NAME, name.length));
EXPECT_EQ(0, retValue );
delete mat;
}

View File

@ -63,7 +63,7 @@ public:
} }
}; };
TEST_F( utSTLImporterExporter, importXFromFileTest ) { TEST_F( utSTLImporterExporter, importSTLFromFileTest ) {
EXPECT_TRUE( importerTest() ); EXPECT_TRUE( importerTest() );
} }