diff --git a/wrap/io_trimesh/import_dae.h b/wrap/io_trimesh/import_dae.h index 40844517..9b690d4e 100644 --- a/wrap/io_trimesh/import_dae.h +++ b/wrap/io_trimesh/import_dae.h @@ -12,11 +12,228 @@ namespace io { template class ImporterDAE : public UtilDAE { + + private: + static int LoadMesh(OpenMeshType& m,InfoDAE* info,const QDomNode& geo) + { + if (isThereTag(geo,"mesh")) + { + /*QDomNodeList geosrc = geo.toElement().elementsByTagName("source"); + int geosrc_size = geosrc.size(); + if (geosrc_size < 1) + return E_NOVERTEXPOSITION;*/ + + QDomNodeList vertices = geo.toElement().elementsByTagName("vertices"); + int vertices_size = vertices.size(); + if (vertices_size != 1) + return E_INCOMPATIBLECOLLADA141FORMAT; + + QDomNode srcnode = attributeSourcePerSimplex(vertices.at(0),*(info->doc),"POSITION"); + if (srcnode.isNull()) + return E_NOVERTEXPOSITION; + + QStringList geosrcposarr; + valueStringList(geosrcposarr,srcnode,"float_array"); + + int geosrcposarr_size = geosrcposarr.size(); + if ((geosrcposarr_size % 3) != 0) + return E_CANTOPEN; + int nvert = geosrcposarr_size / 3; + size_t offset = m.vert.size(); + vcg::tri::Allocator::AddVertices(m,nvert); + + QDomNode srcnodenorm = attributeSourcePerSimplex(vertices.at(0),*(info->doc),"NORMAL"); + QStringList geosrcvertnorm; + if (!srcnodenorm.isNull()) + valueStringList(geosrcvertnorm,srcnodenorm,"float_array"); + + QDomNode srcnodetext = attributeSourcePerSimplex(vertices.at(0),*(info->doc),"TEXCOORD"); + QStringList geosrcverttext; + if (!srcnodetext.isNull()) + valueStringList(geosrcverttext,srcnodetext,"float_array"); + + QDomNode srcnodecolor = attributeSourcePerSimplex(vertices.at(0),*(info->doc),"COLOR"); + QStringList geosrcvertcol; + if (!srcnodecolor.isNull()) + valueStringList(geosrcvertcol,srcnodecolor,"float_array"); + + int ii = 0; + for(size_t vv = offset;vv < m.vert.size();++vv) + { + assert((ii * 3 < geosrcposarr_size) && (ii * 3 + 1 < geosrcposarr_size) && (ii * 3 + 2 < geosrcposarr_size)); + m.vert[vv].P() = vcg::Point3f(geosrcposarr[ii * 3].toFloat(),geosrcposarr[ii * 3 + 1].toFloat(),geosrcposarr[ii * 3 + 2].toFloat()); + + if (!srcnodenorm.isNull()) + { + assert((ii * 3 < geosrcvertnorm.size()) && (ii * 3 + 1 < geosrcvertnorm.size()) && (ii * 3 + 2 < geosrcvertnorm.size())); + m.vert[vv].N() = vcg::Point3f(geosrcvertnorm[ii * 3].toFloat(),geosrcvertnorm[ii * 3 + 1].toFloat(),geosrcvertnorm[ii * 3 + 2].toFloat()); + } + + /*if (!srcnodecolor.isNull()) + { + assert((ii * 4 < geosrcvertcol.size()) && (ii * 4 + 1 < geosrcvertcol.size()) && (ii * 4 + 2 < geosrcvertcol.size()) && (ii * 4 + 1 < geosrcvertcol.size())); + m.vert[vv].C() = vcg::Color4b(geosrcvertcol[ii * 4].toFloat(),geosrcvertcol[ii * 4 + 1].toFloat(),geosrcvertcol[ii * 4 + 2].toFloat(),geosrcvertcol[ii * 4 + 3].toFloat()); + }*/ + + if (!srcnodetext.isNull()) + { + assert((ii * 2 < geosrcverttext.size()) && (ii * 2 + 1 < geosrcverttext.size())); + m.vert[vv].T() = vcg::TCoord2(); + m.vert[vv].T().u() = geosrcverttext[ii * 2].toFloat(); + m.vert[vv].T().v() = geosrcverttext[ii * 2 + 1].toFloat(); + } + ++ii; + } + + QDomNodeList tripatch = geo.toElement().elementsByTagName("triangles"); + int tripatch_size = tripatch.size(); + if (tripatch_size == 0) + return E_NOTRIANGLES; + + for(int tript = 0; tript < tripatch_size;++tript) + { + + int nfcatt = tripatch.at(tript).toElement().elementsByTagName("input").size(); + + QStringList face; + valueStringList(face,tripatch.at(tript),"p"); + int face_size = face.size(); + int offsetface = (int)m.face.size(); + if (face_size == 0) return E_NOMESH; + vcg::tri::Allocator::AddFaces(m,face_size / (nfcatt * 3)); + QDomNode wnsrc = QDomNode(); + QStringList wn; + wnsrc = findNodeBySpecificAttributeValue(tripatch.at(tript),"input","semantic","NORMAL"); + int offnm; + if (!wnsrc.isNull()) + { + offnm = wnsrc.toElement().attribute("offset").toInt(); + QDomNode sn = attributeSourcePerSimplex(tripatch.at(tript),*(info->doc),"NORMAL"); + valueStringList(wn,sn,"float_array"); + } + + QDomNode wtsrc = QDomNode(); + QStringList wt; + wtsrc = findNodeBySpecificAttributeValue(tripatch.at(tript),"input","semantic","TEXCOORD"); + int offtx; + if (!wtsrc.isNull()) + { + offtx = wtsrc.toElement().attribute("offset").toInt(); + QDomNode st = attributeSourcePerSimplex(tripatch.at(tript),*(info->doc),"TEXCOORD"); + valueStringList(wt,st,"float_array"); + } + + QDomNode wcsrc = QDomNode(); + QStringList wc; + wcsrc = findNodeBySpecificAttributeValue(tripatch.at(tript),"input","semantic","COLOR"); + int offcl; + if (!wcsrc.isNull()) + { + offcl = wcsrc.toElement().attribute("offset").toInt(); + QDomNode sc = attributeSourcePerSimplex(tripatch.at(tript),*(info->doc),"COLOR"); + valueStringList(wc,sc,"float_array"); + } + + int jj = 0; + //int dd = m.face.size(); + for(int ff = offsetface;ff < (int) m.face.size();++ff) + { + int indvt = face.at(jj).toInt(); + assert(indvt + offset < m.vert.size()); + m.face[ff].V(0) = &(m.vert[indvt + offset]); + + int indnm; + if (!wnsrc.isNull()) + { + indnm = face.at(jj + offnm).toInt(); + assert(indnm * 3 < wn.size()); + m.face[ff].WN(0) = vcg::Point3f(wn.at(indnm * 3).toFloat(),wn.at(indnm * 3 + 1).toFloat(),wn.at(indnm * 3 + 2).toFloat()); + } + + int indtx; + if (!wtsrc.isNull()) + { + indtx = face.at(jj + offtx).toInt(); + assert(indtx * 2 < wt.size()); + m.face[ff].WT(0) = vcg::TCoord2(); + m.face[ff].WT(0).u() = wt.at(indtx * 2).toFloat(); + m.face[ff].WT(0).v() = wt.at(indtx * 2 + 1).toFloat(); + } + + /*int indcl; + if (!wcsrc.isNull()) + { + indcl = face.at(jj + offcl).toInt(); + assert(indcl * 4 < wc.size()); + m.face[ff].WC(0) = vcg::Color4b(wc.at(indcl * 4).toFloat(),wc.at(indcl * 4 + 1).toFloat(),wc.at(indcl * 4 + 2).toFloat(),wc.at(indcl * 4 + 3).toFloat()); + }*/ + jj += nfcatt; + + indvt = face.at(jj).toInt(); + assert(indvt + offset < m.vert.size()); + m.face[ff].V(1) = &(m.vert[indvt + offset]); + if (!wnsrc.isNull()) + { + indnm = face.at(jj + offnm).toInt(); + assert(indnm * 3 < wn.size()); + m.face[ff].WN(1) = vcg::Point3f(wn.at(indnm * 3).toFloat(),wn.at(indnm * 3 + 1).toFloat(),wn.at(indnm * 3 + 2).toFloat()); + } + + if (!wtsrc.isNull()) + { + indtx = face.at(jj + offtx).toInt(); + assert(indtx * 2 < wt.size()); + m.face[ff].WT(1) = vcg::TCoord2(); + m.face[ff].WT(1).u() = wt.at(indtx * 2).toFloat(); + m.face[ff].WT(1).v() = wt.at(indtx * 2 + 1).toFloat(); + } + + /*if (!wcsrc.isNull()) + { + indcl = face.at(jj + offcl).toInt(); + assert(indcl * 4 < wc.size()); + m.face[ff].WC(1) = vcg::Color4b(wc.at(indcl * 4).toFloat(),wc.at(indcl * 4 + 1).toFloat(),wc.at(indcl * 4 + 2).toFloat(),wc.at(indcl * 4 + 3).toFloat()); + }*/ + jj += nfcatt; + + indvt = face.at(jj).toInt(); + assert(indvt + offset < m.vert.size()); + m.face[ff].V(2) = &(m.vert[indvt + offset]); + if (!wnsrc.isNull()) + { + indnm = face.at(jj + offnm).toInt(); + assert(indnm * 3 < wn.size()); + m.face[ff].WN(2) = vcg::Point3f(wn.at(indnm * 3).toFloat(),wn.at(indnm * 3 + 1).toFloat(),wn.at(indnm * 3 + 2).toFloat()); + } + + if (!wtsrc.isNull()) + { + indtx = face.at(jj + offtx).toInt(); + assert(indtx * 2 < wt.size()); + m.face[ff].WT(2) = vcg::TCoord2(); + m.face[ff].WT(2).u() = wt.at(indtx * 2).toFloat(); + m.face[ff].WT(2).v() = wt.at(indtx * 2 + 1).toFloat(); + } + + /*if (!wcsrc.isNull()) + { + indcl = face.at(jj + offcl).toInt(); + assert(indcl * 4 < wc.size()); + m.face[ff].WC(2) = vcg::Color4b(wc.at(indcl * 4).toFloat(),wc.at(indcl * 4 + 1).toFloat(),wc.at(indcl * 4 + 2).toFloat(),wc.at(indcl * 4 + 3).toFloat()); + }*/ + jj += nfcatt; + + } + } + return E_NOERROR; + } + else return E_NOMESH; + } public: //merge all meshes in the collada's file in the templeted mesh m //I assume the mesh - + static int Open(OpenMeshType& m,const char* filename,AdditionalInfo*& addinfo) { AdditionalInfoDAE* inf = new AdditionalInfoDAE(); @@ -64,6 +281,7 @@ namespace io { QDomNodeList& visscn_child = visscn.childNodes(); //for each direct child of a libscn_url visual scene find if there is some geometry instance + int problem = 0; for(int chdind = 0; chdind < visscn_child.size();++chdind) { QDomNodeList& geoinst = visscn_child.at(chdind).toElement().elementsByTagName("instance_geometry"); @@ -83,218 +301,8 @@ namespace io { QDomNode geo = findNodeBySpecificAttributeValue(geolib.at(0),"geometry","id",geo_url); if (geo.isNull()) return E_UNREFERENCEBLEDCOLLADAATTRIBUTE; - - - if (isThereTag(geo,"mesh")) - { - /*QDomNodeList geosrc = geo.toElement().elementsByTagName("source"); - int geosrc_size = geosrc.size(); - if (geosrc_size < 1) - return E_NOVERTEXPOSITION;*/ - - QDomNodeList vertices = geo.toElement().elementsByTagName("vertices"); - int vertices_size = vertices.size(); - if (vertices_size != 1) - return E_INCOMPATIBLECOLLADA141FORMAT; - - QDomNode srcnode = attributeSourcePerSimplex(vertices.at(0),*(info->doc),"POSITION"); - if (srcnode.isNull()) - return E_NOVERTEXPOSITION; - - QStringList geosrcposarr; - valueStringList(geosrcposarr,srcnode,"float_array"); - - int geosrcposarr_size = geosrcposarr.size(); - if ((geosrcposarr_size % 3) != 0) - return E_CANTOPEN; - int nvert = geosrcposarr_size / 3; - size_t offset = m.vert.size(); - vcg::tri::Allocator::AddVertices(m,nvert); - - QDomNode srcnodenorm = attributeSourcePerSimplex(vertices.at(0),*(info->doc),"NORMAL"); - QStringList geosrcvertnorm; - if (!srcnodenorm.isNull()) - valueStringList(geosrcvertnorm,srcnodenorm,"float_array"); - - QDomNode srcnodetext = attributeSourcePerSimplex(vertices.at(0),*(info->doc),"TEXCOORD"); - QStringList geosrcverttext; - if (!srcnodetext.isNull()) - valueStringList(geosrcverttext,srcnodetext,"float_array"); - - QDomNode srcnodecolor = attributeSourcePerSimplex(vertices.at(0),*(info->doc),"COLOR"); - QStringList geosrcvertcol; - if (!srcnodecolor.isNull()) - valueStringList(geosrcvertcol,srcnodecolor,"float_array"); - - int ii = 0; - for(size_t vv = offset;vv < m.vert.size();++vv) - { - assert((ii * 3 < geosrcposarr_size) && (ii * 3 + 1 < geosrcposarr_size) && (ii * 3 + 2 < geosrcposarr_size)); - m.vert[vv].P() = vcg::Point3f(geosrcposarr[ii * 3].toFloat(),geosrcposarr[ii * 3 + 1].toFloat(),geosrcposarr[ii * 3 + 2].toFloat()); - - if (!srcnodenorm.isNull()) - { - assert((ii * 3 < geosrcvertnorm.size()) && (ii * 3 + 1 < geosrcvertnorm.size()) && (ii * 3 + 2 < geosrcvertnorm.size())); - m.vert[vv].N() = vcg::Point3f(geosrcvertnorm[ii * 3].toFloat(),geosrcvertnorm[ii * 3 + 1].toFloat(),geosrcvertnorm[ii * 3 + 2].toFloat()); - } - - /*if (!srcnodecolor.isNull()) - { - assert((ii * 4 < geosrcvertcol.size()) && (ii * 4 + 1 < geosrcvertcol.size()) && (ii * 4 + 2 < geosrcvertcol.size()) && (ii * 4 + 1 < geosrcvertcol.size())); - m.vert[vv].C() = vcg::Color4b(geosrcvertcol[ii * 4].toFloat(),geosrcvertcol[ii * 4 + 1].toFloat(),geosrcvertcol[ii * 4 + 2].toFloat(),geosrcvertcol[ii * 4 + 3].toFloat()); - }*/ - - if (!srcnodetext.isNull()) - { - assert((ii * 2 < geosrcverttext.size()) && (ii * 2 + 1 < geosrcverttext.size())); - m.vert[vv].T() = vcg::TCoord2(); - m.vert[vv].T().u() = geosrcverttext[ii * 2].toFloat(); - m.vert[vv].T().v() = geosrcverttext[ii * 2 + 1].toFloat(); - } - ++ii; - } - - QDomNodeList tripatch = geo.toElement().elementsByTagName("triangles"); - int tripatch_size = tripatch.size(); - if (tripatch_size == 0) - return E_NOTRIANGLES; - - for(int tript = 0; tript < tripatch_size;++tript) - { - - int nfcatt = tripatch.at(tript).toElement().elementsByTagName("input").size(); - - QStringList face; - valueStringList(face,tripatch.at(tript),"p"); - int face_size = face.size(); - int offsetface = (int)m.face.size(); - if (face_size == 0) return E_NOMESH; - vcg::tri::Allocator::AddFaces(m,face_size / (nfcatt * 3)); - QDomNode wnsrc = QDomNode(); - QStringList wn; - wnsrc = findNodeBySpecificAttributeValue(tripatch.at(tript),"input","semantic","NORMAL"); - int offnm; - if (!wnsrc.isNull()) - { - offnm = wnsrc.toElement().attribute("offset").toInt(); - QDomNode sn = attributeSourcePerSimplex(tripatch.at(tript),*(info->doc),"NORMAL"); - valueStringList(wn,sn,"float_array"); - } - - QDomNode wtsrc = QDomNode(); - QStringList wt; - wtsrc = findNodeBySpecificAttributeValue(tripatch.at(tript),"input","semantic","TEXCOORD"); - int offtx; - if (!wtsrc.isNull()) - { - offtx = wtsrc.toElement().attribute("offset").toInt(); - QDomNode st = attributeSourcePerSimplex(tripatch.at(tript),*(info->doc),"TEXCOORD"); - valueStringList(wt,st,"float_array"); - } - - QDomNode wcsrc = QDomNode(); - QStringList wc; - wcsrc = findNodeBySpecificAttributeValue(tripatch.at(tript),"input","semantic","COLOR"); - int offcl; - if (!wcsrc.isNull()) - { - offcl = wcsrc.toElement().attribute("offset").toInt(); - QDomNode sc = attributeSourcePerSimplex(tripatch.at(tript),*(info->doc),"COLOR"); - valueStringList(wc,sc,"float_array"); - } - - int jj = 0; - //int dd = m.face.size(); - for(int ff = offsetface;ff < (int) m.face.size();++ff) - { - int indvt = face.at(jj).toInt(); - assert(indvt + offset < m.vert.size()); - m.face[ff].V(0) = &(m.vert[indvt + offset]); - - int indnm; - if (!wnsrc.isNull()) - { - indnm = face.at(jj + offnm).toInt(); - assert(indnm * 3 < wn.size()); - m.face[ff].WN(0) = vcg::Point3f(wn.at(indnm * 3).toFloat(),wn.at(indnm * 3 + 1).toFloat(),wn.at(indnm * 3 + 2).toFloat()); - } - - int indtx; - if (!wtsrc.isNull()) - { - indtx = face.at(jj + offtx).toInt(); - assert(indtx * 2 < wt.size()); - m.face[ff].WT(0) = vcg::TCoord2(); - m.face[ff].WT(0).u() = wt.at(indtx * 2).toFloat(); - m.face[ff].WT(0).v() = wt.at(indtx * 2 + 1).toFloat(); - } - - /*int indcl; - if (!wcsrc.isNull()) - { - indcl = face.at(jj + offcl).toInt(); - assert(indcl * 4 < wc.size()); - m.face[ff].WC(0) = vcg::Color4b(wc.at(indcl * 4).toFloat(),wc.at(indcl * 4 + 1).toFloat(),wc.at(indcl * 4 + 2).toFloat(),wc.at(indcl * 4 + 3).toFloat()); - }*/ - jj += nfcatt; - - indvt = face.at(jj).toInt(); - assert(indvt + offset < m.vert.size()); - m.face[ff].V(1) = &(m.vert[indvt + offset]); - if (!wnsrc.isNull()) - { - indnm = face.at(jj + offnm).toInt(); - assert(indnm * 3 < wn.size()); - m.face[ff].WN(1) = vcg::Point3f(wn.at(indnm * 3).toFloat(),wn.at(indnm * 3 + 1).toFloat(),wn.at(indnm * 3 + 2).toFloat()); - } - - if (!wtsrc.isNull()) - { - indtx = face.at(jj + offtx).toInt(); - assert(indtx * 2 < wt.size()); - m.face[ff].WT(1) = vcg::TCoord2(); - m.face[ff].WT(1).u() = wt.at(indtx * 2).toFloat(); - m.face[ff].WT(1).v() = wt.at(indtx * 2 + 1).toFloat(); - } - - /*if (!wcsrc.isNull()) - { - indcl = face.at(jj + offcl).toInt(); - assert(indcl * 4 < wc.size()); - m.face[ff].WC(1) = vcg::Color4b(wc.at(indcl * 4).toFloat(),wc.at(indcl * 4 + 1).toFloat(),wc.at(indcl * 4 + 2).toFloat(),wc.at(indcl * 4 + 3).toFloat()); - }*/ - jj += nfcatt; - - indvt = face.at(jj).toInt(); - assert(indvt + offset < m.vert.size()); - m.face[ff].V(2) = &(m.vert[indvt + offset]); - if (!wnsrc.isNull()) - { - indnm = face.at(jj + offnm).toInt(); - assert(indnm * 3 < wn.size()); - m.face[ff].WN(2) = vcg::Point3f(wn.at(indnm * 3).toFloat(),wn.at(indnm * 3 + 1).toFloat(),wn.at(indnm * 3 + 2).toFloat()); - } - - if (!wtsrc.isNull()) - { - indtx = face.at(jj + offtx).toInt(); - assert(indtx * 2 < wt.size()); - m.face[ff].WT(2) = vcg::TCoord2(); - m.face[ff].WT(2).u() = wt.at(indtx * 2).toFloat(); - m.face[ff].WT(2).v() = wt.at(indtx * 2 + 1).toFloat(); - } - - /*if (!wcsrc.isNull()) - { - indcl = face.at(jj + offcl).toInt(); - assert(indcl * 4 < wc.size()); - m.face[ff].WC(2) = vcg::Color4b(wc.at(indcl * 4).toFloat(),wc.at(indcl * 4 + 1).toFloat(),wc.at(indcl * 4 + 2).toFloat(),wc.at(indcl * 4 + 3).toFloat()); - }*/ - jj += nfcatt; - - } - } - } + problem |= LoadMesh(m,info,geo); + if (problem) return problem; } } } @@ -302,7 +310,19 @@ namespace io { } if (!geoinst_found) - return E_NOGEOMETRYLIBRARY; + { + QDomNodeList& geolib = info->doc->elementsByTagName("library_geometries"); + int geolib_size = geolib.size(); + assert(geolib_size == 1); + QDomNodeList& geochild = geolib.at(0).childNodes(); + int geochild_size = geochild.size(); + int problem = 0; + for(int chd = 0;chd < geochild_size;++chd) + { + problem |= LoadMesh(m,info,geochild.at(chd)); + if (problem) return problem; + } + } addinfo = inf; return E_NOERROR; }