closes https://github.com/assimp/assimp/issues/104: deal with more solids in one STL file.

This commit is contained in:
Kim Kulling
2017-11-06 22:30:07 +01:00
parent 02b042d78e
commit 9a9f18bbed
2 changed files with 86 additions and 60 deletions

View File

@@ -200,17 +200,17 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
if (IsBinarySTL(mBuffer, fileSize)) {
bMatClr = LoadBinaryFile();
} else if (IsAsciiSTL(mBuffer, fileSize)) {
LoadASCIIFile();
LoadASCIIFile( pScene->mRootNode );
} else {
throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
}
// add all created meshes to the single node
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
/*pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
pScene->mRootNode->mMeshes[i] = i;
*/
// create a single default material, using a white diffuse color for consistency with
// other geometric types (e.g., PLY).
aiMaterial* pcMat = new aiMaterial();
@@ -231,11 +231,12 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
pScene->mMaterials = new aiMaterial*[1];
pScene->mMaterials[0] = pcMat;
}
// ------------------------------------------------------------------------------------------------
// Read an ASCII STL file
void STLImporter::LoadASCIIFile()
{
void STLImporter::LoadASCIIFile( aiNode *root ) {
std::vector<aiMesh*> meshes;
std::vector<aiNode*> nodes;
const char* sz = mBuffer;
const char* bufferEnd = mBuffer + fileSize;
std::vector<aiVector3D> positionBuffer;
@@ -247,12 +248,15 @@ void STLImporter::LoadASCIIFile()
positionBuffer.reserve(sizeEstimate);
normalBuffer.reserve(sizeEstimate);
while (IsAsciiSTL(sz, static_cast<unsigned int>(bufferEnd - sz)))
{
while (IsAsciiSTL(sz, static_cast<unsigned int>(bufferEnd - sz))) {
std::vector<unsigned int> meshIndices;
aiMesh* pMesh = new aiMesh();
pMesh->mMaterialIndex = 0;
meshIndices.push_back( meshes.size() );
meshes.push_back(pMesh);
aiNode *node = new aiNode;
node->mParent = root;
nodes.push_back( node );
SkipSpaces(&sz);
ai_assert(!IsLineEnd(sz));
@@ -265,20 +269,21 @@ void STLImporter::LoadASCIIFile()
size_t temp;
// setup the name of the node
if ((temp = (size_t)(sz-szMe))) {
if ((temp = (size_t)(sz-szMe))) {
if (temp >= MAXLEN) {
throw DeadlyImportError( "STL: Node name too long" );
}
pScene->mRootNode->mName.length = temp;
memcpy(pScene->mRootNode->mName.data,szMe,temp);
pScene->mRootNode->mName.data[temp] = '\0';
std::string name( szMe, temp );
node->mName.Set( name.c_str() );
//pScene->mRootNode->mName.length = temp;
//memcpy(pScene->mRootNode->mName.data,szMe,temp);
//pScene->mRootNode->mName.data[temp] = '\0';
} else {
pScene->mRootNode->mName.Set("<STL_ASCII>");
}
else pScene->mRootNode->mName.Set("<STL_ASCII>");
unsigned int faceVertexCounter = 3;
for ( ;; )
{
for ( ;; ) {
// go to the next token
if(!SkipSpacesAndLineEnd(&sz))
{
@@ -300,9 +305,7 @@ void STLImporter::LoadASCIIFile()
SkipSpaces(&sz);
if (strncmp(sz,"normal",6)) {
DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
}
else
{
} else {
if (sz[6] == '\0') {
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
}
@@ -316,16 +319,11 @@ void STLImporter::LoadASCIIFile()
normalBuffer.push_back(*vn);
normalBuffer.push_back(*vn);
}
}
// vertex 1.50000 1.50000 0.00000
else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
{
} else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6))) { // vertex 1.50000 1.50000 0.00000
if (faceVertexCounter >= 3) {
DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
++sz;
}
else
{
} else {
if (sz[6] == '\0') {
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
}
@@ -340,17 +338,14 @@ void STLImporter::LoadASCIIFile()
sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->z );
faceVertexCounter++;
}
}
else if (!::strncmp(sz,"endsolid",8)) {
} else if (!::strncmp(sz,"endsolid",8)) {
do {
++sz;
} while (!::IsLineEnd(*sz));
SkipSpacesAndLineEnd(&sz);
// finished!
break;
}
// else skip the whole identifier
else {
} else { // else skip the whole identifier
do {
++sz;
} while (!::IsSpaceOrNewLine(*sz));
@@ -380,13 +375,22 @@ void STLImporter::LoadASCIIFile()
// now copy faces
addFacesToMesh(pMesh);
// assign the meshes to the current node
pushMeshesToNode( meshIndices, node );
}
// now add the loaded meshes
pScene->mNumMeshes = (unsigned int)meshes.size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
for (size_t i = 0; i < meshes.size(); i++)
{
pScene->mMeshes[i] = meshes[i];
for (size_t i = 0; i < meshes.size(); i++) {
pScene->mMeshes[ i ] = meshes[i];
}
root->mNumChildren = nodes.size();
root->mChildren = new aiNode*[ root->mNumChildren ];
for ( size_t i=0; i<nodes.size(); ++i ) {
root->mChildren[ i ] = nodes[ i ];
}
}
@@ -513,4 +517,18 @@ bool STLImporter::LoadBinaryFile()
return false;
}
void STLImporter::pushMeshesToNode( std::vector<unsigned int> &meshIndices, aiNode *node ) {
ai_assert( nullptr != node );
if ( meshIndices.empty() ) {
return;
}
node->mNumMeshes = static_cast<unsigned int>( meshIndices.size() );
node->mMeshes = new unsigned int[ meshIndices.size() ];
for ( size_t i=0; i<meshIndices.size(); ++i ) {
node->mMeshes[ i ] = meshIndices[ i ];
}
meshIndices.clear();
}
#endif // !! ASSIMP_BUILD_NO_STL_IMPORTER