Skip to content

Commit

Permalink
Merge branch 'master' into assbin_test
Browse files Browse the repository at this point in the history
  • Loading branch information
kimkulling authored Sep 11, 2018
2 parents ab5c100 + 07a8bac commit c1ed5e0
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 103 deletions.
2 changes: 0 additions & 2 deletions code/Assimp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,6 @@ void aiReleaseImport( const aiScene* pScene)

ASSIMP_BEGIN_EXCEPTION_REGION();

aiReleaseDefaultMaterial();

// find the importer associated with this data
const ScenePrivateData* priv = ScenePriv(pScene);
if( !priv || !priv->mOrigImporter) {
Expand Down
13 changes: 8 additions & 5 deletions code/D3MFImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,9 @@ class XmlSerializer {
return false;
}

//format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
const size_t len( strlen( color ) );
if ( 9 != len ) {
if ( 9 != len && 7 != len) {
return false;
}

Expand All @@ -313,26 +314,28 @@ class XmlSerializer {
++buf;
comp[ 1 ] = *buf;
++buf;
diffuse.r = static_cast<ai_real>( strtol( comp, NULL, 16 ) );
diffuse.r = static_cast<ai_real>( strtol( comp, NULL, 16 ) ) / 255.0;


comp[ 0 ] = *buf;
++buf;
comp[ 1 ] = *buf;
++buf;
diffuse.g = static_cast< ai_real >( strtol( comp, NULL, 16 ) );
diffuse.g = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / 255.0;

comp[ 0 ] = *buf;
++buf;
comp[ 1 ] = *buf;
++buf;
diffuse.b = static_cast< ai_real >( strtol( comp, NULL, 16 ) );
diffuse.b = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / 255.0;

if(7 == len)
return true;
comp[ 0 ] = *buf;
++buf;
comp[ 1 ] = *buf;
++buf;
diffuse.a = static_cast< ai_real >( strtol( comp, NULL, 16 ) );
diffuse.a = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / 255.0;

return true;
}
Expand Down
2 changes: 0 additions & 2 deletions code/Importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ Importer::~Importer()
{
// Delete all import plugins
DeleteImporterInstanceList(pimpl->mImporter);
aiReleaseDefaultMaterial();

// Delete all post-processing plug-ins
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)
Expand Down Expand Up @@ -385,7 +384,6 @@ void Importer::FreeScene( )
{
ASSIMP_BEGIN_EXCEPTION_REGION();

aiReleaseDefaultMaterial();
delete pimpl->mScene;
pimpl->mScene = NULL;

Expand Down
20 changes: 0 additions & 20 deletions code/MaterialSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,26 +387,6 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
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;

Expand Down
43 changes: 21 additions & 22 deletions code/ObjFileImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,29 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
}

if (pModel->m_Objects.size() > 0) {

unsigned int meshCount = 0;
unsigned int childCount = 0;

for(size_t index = 0; index < pModel->m_Objects.size(); ++index) {
if(pModel->m_Objects[index]) {
++childCount;
meshCount += (unsigned int)pModel->m_Objects[index]->m_Meshes.size();
}
}

// Allocate space for the child nodes on the root node
pScene->mRootNode->mChildren = new aiNode*[ childCount ];

// Create nodes for the whole scene
std::vector<aiMesh*> MeshArray;
MeshArray.reserve(meshCount);
for (size_t index = 0; index < pModel->m_Objects.size(); ++index) {
createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);
}

ai_assert(pScene->mRootNode->mNumChildren == childCount);

// Create mesh pointer buffer for this scene
if (pScene->mNumMeshes > 0) {
pScene->mMeshes = new aiMesh*[MeshArray.size()];
Expand Down Expand Up @@ -287,9 +304,8 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
pNode->mName = pObject->m_strObjName;

// If we have a parent node, store it
if( pParent != NULL ) {
appendChildToParentNode( pParent, pNode );
}
ai_assert( NULL != pParent );
appendChildToParentNode( pParent, pNode );

for ( size_t i=0; i< pObject->m_Meshes.size(); ++i ) {
unsigned int meshId = pObject->m_Meshes[ i ];
Expand Down Expand Up @@ -442,8 +458,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
pMesh->mNumVertices = numIndices;
if (pMesh->mNumVertices == 0) {
throw DeadlyImportError( "OBJ: no vertices" );
} else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" );
} else if (pMesh->mNumVertices > AI_MAX_VERTICES) {
throw DeadlyImportError( "OBJ: Too many vertices" );
}
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];

Expand Down Expand Up @@ -770,25 +786,8 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
// Assign parent to child
pChild->mParent = pParent;

// If already children was assigned to the parent node, store them in a
std::vector<aiNode*> temp;
if (pParent->mChildren != NULL)
{
ai_assert( 0 != pParent->mNumChildren );
for (size_t index = 0; index < pParent->mNumChildren; index++)
{
temp.push_back(pParent->mChildren [ index ] );
}
delete [] pParent->mChildren;
}

// Copy node instances into parent node
pParent->mNumChildren++;
pParent->mChildren = new aiNode*[ pParent->mNumChildren ];
for (size_t index = 0; index < pParent->mNumChildren-1; index++)
{
pParent->mChildren[ index ] = temp [ index ];
}
pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
}

Expand Down
5 changes: 2 additions & 3 deletions code/STLLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,10 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS

// create a single default material, using a white diffuse color for consistency with
// other geometric types (e.g., PLY).
aiMaterial* pcMat = aiCreateAndRegisterDefaultMaterial();
/*aiMaterial* pcMat = new aiMaterial();
aiMaterial* pcMat = new aiMaterial();
aiString s;
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));
if (bMatClr) {
Expand Down
20 changes: 0 additions & 20 deletions include/assimp/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -1565,26 +1565,6 @@ C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
unsigned int* flags /*= NULL*/);
#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
}
Expand Down
71 changes: 53 additions & 18 deletions port/PyAssimp/pyassimp/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ def make_tuple(ai_obj, type = None):

return res

# Returns unicode object for Python 2, and str object for Python 3.
def _convert_assimp_string(assimp_string):
try:
return unicode(assimp_string.data, errors='ignore')
except:
return str(assimp_string.data, errors='ignore')

# It is faster and more correct to have an init function for each assimp class
def _init_face(aiFace):
aiFace.indices = [aiFace.mIndices[i] for i in range(aiFace.mNumIndices)]
Expand Down Expand Up @@ -118,14 +125,9 @@ def _init(self, target = None, parent = None):
continue

if m == 'mName':
obj = self.mName
try:
uni = unicode(obj.data, errors='ignore')
except:
uni = str(obj.data, errors='ignore')
target.name = str( uni )
target.__class__.__repr__ = lambda x: str(x.__class__) + "(" + getattr(x, 'name','') + ")"
target.__class__.__str__ = lambda x: getattr(x, 'name', '')
target.name = str(_convert_assimp_string(self.mName))
target.__class__.__repr__ = lambda x: str(x.__class__) + "(" + getattr(x, 'name','') + ")"
target.__class__.__str__ = lambda x: getattr(x, 'name', '')
continue

name = m[1:].lower()
Expand Down Expand Up @@ -220,6 +222,9 @@ def _init(self, target = None, parent = None):
if isinstance(self, structs.Texture):
_finalize_texture(self, target)

if isinstance(self, structs.Metadata):
_finalize_metadata(self, target)


return self

Expand Down Expand Up @@ -412,6 +417,43 @@ def fillarray(name):
faces = [f.indices for f in target.faces]
setattr(target, 'faces', faces)

def _init_metadata_entry(entry):
from ctypes import POINTER, c_bool, c_int32, c_uint64, c_float, c_double, cast

entry.type = entry.mType
if entry.type == structs.MetadataEntry.AI_BOOL:
entry.data = cast(entry.mData, POINTER(c_bool)).contents.value
elif entry.type == structs.MetadataEntry.AI_INT32:
entry.data = cast(entry.mData, POINTER(c_int32)).contents.value
elif entry.type == structs.MetadataEntry.AI_UINT64:
entry.data = cast(entry.mData, POINTER(c_uint64)).contents.value
elif entry.type == structs.MetadataEntry.AI_FLOAT:
entry.data = cast(entry.mData, POINTER(c_float)).contents.value
elif entry.type == structs.MetadataEntry.AI_DOUBLE:
entry.data = cast(entry.mData, POINTER(c_double)).contents.value
elif entry.type == structs.MetadataEntry.AI_AISTRING:
assimp_string = cast(entry.mData, POINTER(structs.String)).contents
entry.data = _convert_assimp_string(assimp_string)
elif entry.type == structs.MetadataEntry.AI_AIVECTOR3D:
assimp_vector = cast(entry.mData, POINTER(structs.Vector3D)).contents
entry.data = make_tuple(assimp_vector)

return entry

def _finalize_metadata(metadata, target):
""" Building the metadata object is a bit specific.
Firstly, there are two separate arrays: one with metadata keys and one
with metadata values, and there are no corresponding mNum* attributes,
so the C arrays are not converted to Python arrays using the generic
code in the _init function.
Secondly, a metadata entry value has to be cast according to declared
metadata entry type.
"""
length = metadata.mNumProperties
setattr(target, 'keys', [str(_convert_assimp_string(metadata.mKeys[i])) for i in range(length)])
setattr(target, 'values', [_init_metadata_entry(metadata.mValues[i]) for i in range(length)])

class PropertyGetter(dict):
def __getitem__(self, key):
Expand Down Expand Up @@ -443,23 +485,16 @@ def _get_properties(properties, length):
for p in [properties[i] for i in range(length)]:
#the name
p = p.contents
try:
uni = unicode(p.mKey.data, errors='ignore')
except:
uni = str(p.mKey.data, errors='ignore')
key = (str(uni).split('.')[1], p.mSemantic)
key = str(_convert_assimp_string(p.mKey))
key = (key.split('.')[1], p.mSemantic)

#the data
from ctypes import POINTER, cast, c_int, c_float, sizeof
if p.mType == 1:
arr = cast(p.mData, POINTER(c_float * int(p.mDataLength/sizeof(c_float)) )).contents
value = [x for x in arr]
elif p.mType == 3: #string can't be an array
try:
uni = unicode(cast(p.mData, POINTER(structs.MaterialPropertyString)).contents.data, errors='ignore')
except:
uni = str(cast(p.mData, POINTER(structs.MaterialPropertyString)).contents.data, errors='ignore')
value = uni
value = _convert_assimp_string(cast(p.mData, POINTER(structs.MaterialPropertyString)).contents)

elif p.mType == 4:
arr = cast(p.mData, POINTER(c_int * int(p.mDataLength/sizeof(c_int)) )).contents
Expand Down
4 changes: 2 additions & 2 deletions port/PyAssimp/pyassimp/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ class Node(Structure):

# Metadata associated with this node or NULL if there is no metadata.
# Whether any metadata is generated depends on the source file format.
("mMetadata", POINTER(POINTER(Metadata))),
("mMetadata", POINTER(Metadata)),
]

class Light(Structure):
Expand Down Expand Up @@ -939,7 +939,7 @@ class Scene(Structure):
# This data contains global metadata which belongs to the scene like
# unit-conversions, versions, vendors or other model-specific data. This
# can be used to store format-specific metadata as well.
("mMetadata", POINTER(POINTER(Metadata))),
("mMetadata", POINTER(Metadata)),
]

assimp_structs_as_tuple = (Matrix4x4,
Expand Down
10 changes: 1 addition & 9 deletions test/unit/utMaterialSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,10 @@ TEST_F(MaterialSystemTest, testStringProperty) {
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();
aiMaterial *mat = new aiMaterial();
EXPECT_NE(nullptr, mat);

aiString name = mat->GetName();
Expand Down
14 changes: 14 additions & 0 deletions test/unit/utSTLImportExport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ TEST_F( utSTLImporterExporter, importSTLFromFileTest ) {
EXPECT_TRUE( importerTest() );
}


TEST_F(utSTLImporterExporter, test_multiple) {
// import same file twice, each with its own importer
// must work both times and not crash
Assimp::Importer importer1;
const aiScene *scene1 = importer1.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/Spider_ascii.stl", aiProcess_ValidateDataStructure );
EXPECT_NE(nullptr, scene1);

Assimp::Importer importer2;
const aiScene *scene2 = importer2.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/Spider_ascii.stl", aiProcess_ValidateDataStructure );
EXPECT_NE(nullptr, scene2);
}


TEST_F( utSTLImporterExporter, test_with_two_solids ) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_two_solids.stl", aiProcess_ValidateDataStructure );
Expand Down

0 comments on commit c1ed5e0

Please sign in to comment.