diff --git a/wrap/io_trimesh/import_dae.h b/wrap/io_trimesh/import_dae.h index b4e0e09b..0dcaaa6f 100644 --- a/wrap/io_trimesh/import_dae.h +++ b/wrap/io_trimesh/import_dae.h @@ -397,14 +397,33 @@ namespace io { } // ind_txt = indexTextureByImgNode(*(info.doc),txt_node); } - int faceAttributeNum = triNodeList.at(tript).toElement().elementsByTagName("input").size(); + int triangleNumber = triNodeList.at(tript).toElement().attribute("count").toInt(); + + // A triangle can have multiple inputs that share a common offset. Therefore it's + // not sufficient to take the number of input to derive the stride from triangle to + // triangle. Instead, this heuristic uses the maximal offset found among inputs. + QDomNodeList attributes = triNodeList.at(tript).toElement().elementsByTagName("input"); + int numTriangleAttributeIndices = 0; + for (int i = 0; i < attributes.size(); ++i) { + QDomNode attr = attributes.at(i); + int offset = attr.toElement().attribute("offset", "-1").toInt(); + numTriangleAttributeIndices = std::max(numTriangleAttributeIndices, offset+1); + } QStringList face; valueStringList(face,triNodeList.at(tript),"p"); + + // Ensure that the

array size is consistent with the number of triangles and the + // exprected stride. + if (face.size() != 3 * triangleNumber * numTriangleAttributeIndices) { + QDEBUG("********* ERROR triangle count is inconsistent with input offsets and face index list"); + return E_INCOMPATIBLECOLLADA141FORMAT; + } + int offsetface = (int)m.face.size(); if (face.size() != 0) { - vcg::tri::Allocator::AddFaces(m,face.size() / (faceAttributeNum * 3)); + vcg::tri::Allocator::AddFaces(m, triangleNumber); WedgeAttribute wa; FindStandardWedgeAttributes(wa,triNodeList.at(tript),*(info.doc)); @@ -430,7 +449,7 @@ namespace io { WedgeTextureAttribute(m,face,ind_txt,wa.wt,wa.wtsrc,ff,jj + wa.offtx,tt,wa.stridetx); } - jj += faceAttributeNum; + jj += numTriangleAttributeIndices; } if( ! ( (m.face[ff].V(0) != m.face[ff].V(1)) && (m.face[ff].V(0) != m.face[ff].V(2)) && @@ -589,8 +608,13 @@ namespace io { } } - if (isTri && tripatch.isEmpty()) + if (isTri && tripatch.isEmpty()) { tripatch=polylist; + // Clear the polylist. Otherwise faces are loaded twice, once by + // LoadTriangularMesh and another time by LoadPolygonalListMesh. + polylist = QDomNodeList(); + } + if (tripatch.isEmpty() && polypatch.isEmpty() && polylist.isEmpty()) return E_NOPOLYGONALMESH;