this patch fixes multiple objects generation in OBJ reader if faces are prepended with 'usemtl' line

pull/709/head
Vitaly Ovchinnikov 2015-12-13 22:54:50 +13:00
parent 078dd0c08b
commit 6214fbfbbe
3 changed files with 85 additions and 24 deletions

View File

@ -457,15 +457,6 @@ void ObjFileParser::getFace(aiPrimitiveType type)
// Get values for a new material description // Get values for a new material description
void ObjFileParser::getMaterialDesc() void ObjFileParser::getMaterialDesc()
{ {
// Each material request a new object.
// Sometimes the object is already created (see 'o' tag by example), but it is not initialized !
// So, we create a new object only if the current on is already initialized !
if (m_pModel->m_pCurrent != NULL &&
( m_pModel->m_pCurrent->m_Meshes.size() > 1 ||
(m_pModel->m_pCurrent->m_Meshes.size() == 1 && m_pModel->m_Meshes[m_pModel->m_pCurrent->m_Meshes[0]]->m_Faces.size() != 0) )
)
m_pModel->m_pCurrent = NULL;
// Get next data for material data // Get next data for material data
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
if (m_DataIt == m_DataItEnd) { if (m_DataIt == m_DataItEnd) {
@ -477,25 +468,40 @@ void ObjFileParser::getMaterialDesc()
++m_DataIt; ++m_DataIt;
} }
// In some cases we should ignore this 'usemtl' command, this variable helps us to do so
bool skip = false;
// Get name // Get name
std::string strName(pStart, &(*m_DataIt)); std::string strName(pStart, &(*m_DataIt));
if ( strName.empty()) if (strName.empty())
return; skip = true;
// Search for material // If the current mesh has the same material, we simply ignore that 'usemtl' command
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strName ); // There is no need to create another object or even mesh here
if ( it == m_pModel->m_MaterialMap.end() ) { if (m_pModel->m_pCurrentMaterial && m_pModel->m_pCurrentMaterial->MaterialName == aiString(strName))
// Not found, use default material skip = true;
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping"); if (!skip)
} else { {
// Found, using detected material // Search for material
m_pModel->m_pCurrentMaterial = (*it).second; std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find(strName);
if ( needsNewMesh( strName )) if (it == m_pModel->m_MaterialMap.end())
{ {
createMesh( strName ); // Not found, use default material
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping");
strName = m_pModel->m_pDefaultMaterial->MaterialName.C_Str();
} }
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName ); else
{
// Found, using detected material
m_pModel->m_pCurrentMaterial = (*it).second;
}
if (needsNewMesh(strName))
createMesh();
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
} }
// Skip rest of line // Skip rest of line
@ -759,7 +765,7 @@ bool ObjFileParser::needsNewMesh( const std::string &rMaterialName )
bool newMat = false; bool newMat = false;
int matIdx = getMaterialIndex( rMaterialName ); int matIdx = getMaterialIndex( rMaterialName );
int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex; int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) || curMatIdx != matIdx ) if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) && curMatIdx != matIdx )
{ {
// New material -> only one material per mesh, so we need to create a new // New material -> only one material per mesh, so we need to create a new
// material // material

View File

@ -0,0 +1,11 @@
newmtl mtl
Ka 1.000 1.000 1.000
Kd 1.000 1.000 1.000
Ns 200.000
Ks 0.050 0.050 0.050
newmtl mtl2
Ka 1.000 1.000 1.000
Kd 1.000 1.000 1.000
Ns 16.000
Ks 0.375 0.375 0.375

View File

@ -0,0 +1,44 @@
mtllib cube_usemtl.mtl
g cube
v 0.0 0.0 0.0
v 0.0 0.0 1.0
v 0.0 1.0 0.0
v 0.0 1.0 1.0
v 1.0 0.0 0.0
v 1.0 0.0 1.0
v 1.0 1.0 0.0
v 1.0 1.0 1.0
vn 0.0 0.0 1.0
vn 0.0 0.0 -1.0
vn 0.0 1.0 0.0
vn 0.0 -1.0 0.0
vn 1.0 0.0 0.0
vn -1.0 0.0 0.0
usemtl mtl3
f 1//2 7//2 5//2
usemtl mtl3
f 1//2 3//2 7//2
usemtl mtl
f 1//6 4//6 3//6
usemtl mtl
f 1//6 2//6 4//6
usemtl mtl
f 3//3 8//3 7//3
usemtl mtl2
f 3//3 4//3 8//3
usemtl mtl2
f 5//5 7//5 8//5
usemtl mtl2
f 5//5 8//5 6//5
usemtl mtl2
f 1//4 5//4 6//4
usemtl mtl
f 1//4 6//4 2//4
usemtl mtl
f 2//1 6//1 8//1
usemtl mtl
f 2//1 8//1 4//1