diff --git a/wrap/io_trimesh/export_dae.h b/wrap/io_trimesh/export_dae.h index 24bd98e7..5e272dcf 100644 --- a/wrap/io_trimesh/export_dae.h +++ b/wrap/io_trimesh/export_dae.h @@ -12,6 +12,80 @@ namespace io { template class ExporterDAE : public UtilDAE { +private: + static void CreateVertInput(QDomDocument& doc,QDomNode& vert,const QString& attr,const QString& ref) + { + QDomElement vinp_pos = doc.createElement("input"); + vinp_pos.setAttribute("semantic",attr); + vinp_pos.setAttribute("source",ref); + vert.appendChild(vinp_pos); + } + + static void CreateFaceInput(QDomDocument& doc,QDomNode& tri,const QString& attr,const QString& ref,const int offset) + { + QDomElement tinp_vert = doc.createElement("input"); + tinp_vert.setAttribute("offset",QString::number(offset)); + tinp_vert.setAttribute("semantic",attr); + tinp_vert.setAttribute("source",ref); + tri.appendChild(tinp_vert); + } + + static void CreateSource(QDomDocument& doc,QDomNode& meshnode,const QString& attr,const QDomText& val,int nvert) + { + int nel; + std::vector coord; + if ((attr == "positions") || (attr == "normals") || (attr == "wnornals")) + { + nel = 3; + coord.push_back("X"); + coord.push_back("Y"); + coord.push_back("Z"); + } + else + { + if (attr == "colors") + { + nel = 4; + coord.push_back("R"); + coord.push_back("G"); + coord.push_back("B"); + coord.push_back("A"); + } + else + { + nel = 2; + coord.push_back("U"); + coord.push_back("V"); + } + } + QDomElement srcnmnode = doc.createElement("source"); + srcnmnode.setAttribute("id","vcg-mesh-"+attr); + srcnmnode.setAttribute("name","vcg-mesh-"+attr); + + QDomElement arraynmnode = doc.createElement("float_array"); + arraynmnode.setAttribute("id","vcg-mesh-"+attr+"-array"); + arraynmnode.setAttribute("count",QString::number(nvert * nel)); + + QDomElement technode2 = doc.createElement("technique_common"); + QDomElement accnode2 = doc.createElement("accessor"); + accnode2.setAttribute("source","#vcg-mesh-"+attr+"-array"); + accnode2.setAttribute("count",QString::number(nvert)); + accnode2.setAttribute("stride",QString::number(nel)); + + for(int jj = 0; jj < nel;++jj) + { + QDomElement parxnode2 = doc.createElement("param"); + parxnode2.setAttribute("name",coord[jj]); + parxnode2.setAttribute("type","float"); + accnode2.appendChild(parxnode2); + } + + technode2.appendChild(accnode2); + arraynmnode.appendChild(val); + srcnmnode.appendChild(arraynmnode); + srcnmnode.appendChild(technode2); + meshnode.appendChild(srcnmnode); + } public: static int Save(SaveMeshType &m, const char * filename) { @@ -39,14 +113,17 @@ public: arrayposnode.setAttribute("id","vcg-mesh-positions-array"); QString arrp; + arrp.reserve(10 * m.vert.size()); QString arrn; + arrn.reserve(10 * m.vert.size()); + int nvert = 0; for(SaveMeshType::VertexIterator it = m.vert.begin();it != m.vert.end();++it) { if (!(it->IsD())) { - arrp.append(QString::number(it->P().X()) + " " +QString::number(it->P().Y()) + " " + QString::number(it->P().Z()) + " "); - arrn.append(QString::number(it->N().X()) + " " + QString::number(it->N().Y()) + " " + QString::number(it->N().Z())+ " "); + arrp.append(QString::number(it->P().X()).append(" ").append(QString::number(it->P().Y())).append(" ").append(QString::number(it->P().Z())).append(" ")); + arrn.append(QString::number(it->P().X()).append(" ").append(QString::number(it->P().Y())).append(" ").append(QString::number(it->P().Z())).append(" ")); ++nvert; } } @@ -140,6 +217,7 @@ public: QDomElement poly = doc.createElement("p"); QString triangles_tess; int nface = 0; + triangles_tess.reserve(10*m.face.size()); for(SaveMeshType::FaceIterator itf = m.face.begin();itf != m.face.end();++itf) { if (!(itf->IsD())) @@ -149,7 +227,7 @@ public: int ind_v = (*itf).V(ii) - &(m.vert[0]); if (triangles_tess == "") triangles_tess = QString::number(ind_v); - else triangles_tess = triangles_tess + " " + QString::number(ind_v); + else triangles_tess.append(" ").append(QString::number(ind_v)); } ++nface; } @@ -206,7 +284,7 @@ public: } - static int Save(SaveMeshType &m, const char * filename,AdditionalInfo*& in) + static int Save(SaveMeshType &m, const char * filename,AdditionalInfo*& in, const int &mask = -1) { /*unsigned int ncomp = sizeof(SaveMeshType::CoordType) / sizeof(SaveMeshType::ScalarType);*/ assert(in != NULL); @@ -262,120 +340,92 @@ public: QDomElement meshnode = info->doc->createElement("mesh"); - QDomElement srcposnode = info->doc->createElement("source"); - srcposnode.setAttribute("id","vcg-mesh-positions"); - srcposnode.setAttribute("name","vcg-mesh-positions"); - - QDomElement arrayposnode = info->doc->createElement("float_array"); - arrayposnode.setAttribute("id","vcg-mesh-positions-array"); QString arrp; - arrp.reserve(8 * m.vert.size()); + arrp.reserve(10 * 3 * m.vert.size()); QString arrn; - arrn.reserve(8 * m.vert.size()); + if(mask & vcg::tri::io::Mask::IOM_VERTNORMAL | mask & vcg::tri::io::Mask::IOM_WEDGNORMAL) + arrn.reserve(10 * 3 * m.vert.size()); + QString arrt; + if(mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD) + arrt.reserve(10 * 2 * m.vert.size()); + QString arrc; + if(mask & vcg::tri::io::Mask::IOM_VERTCOLOR) + arrc.reserve(5 * 4 * m.vert.size()); int nvert = 0; for(SaveMeshType::VertexIterator it = m.vert.begin();it != m.vert.end();++it) { if (!(it->IsD())) { - arrp.append(QString::number(it->P().X()) + " " +QString::number(it->P().Y()) + " " + QString::number(it->P().Z()) + " "); - arrn.append(QString::number(it->N().X()) + " " + QString::number(it->N().Y()) + " " + QString::number(it->N().Z())+ " "); - //arrp.append(QString::number(it->P().X()).append(" ").append(QString::number(it->P().Y())).append(" ").append(QString::number(it->P().Z())).append(" ")); - //arrp.append(QString::number(it->N().X()).append(" ").append(QString::number(it->N().Y())).append(" ").append(QString::number(it->N().Z())).append(" ")); + arrp.append(QString::number(it->P().X()).append(" ").append(QString::number(it->P().Y())).append(" ").append(QString::number(it->P().Z())).append(" ")); + if(mask & vcg::tri::io::Mask::IOM_VERTNORMAL) + arrn.append(QString::number(it->N().X()).append(" ").append(QString::number(it->N().Y())).append(" ").append(QString::number(it->N().Z())).append(" ")); + if(mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD) + arrt.append(QString::number(it->T().u()).append(" ").append(QString::number(it->T().v())).append(" ")); + if(mask & vcg::tri::io::Mask::IOM_VERTCOLOR) + arrc.append(QString::number(it->C().X()).append(" ").append(QString::number(it->C().Y())).append(" ").append(QString::number(it->C().Z())).append(" ").append(QString::number(it->C().W())).append(" ")); ++nvert; } } - arrayposnode.setAttribute("count",QString::number(nvert * 3)); + QDomText ap = info->doc->createTextNode(arrp); - - QDomElement technode = info->doc->createElement("technique_common"); - QDomElement accnode = info->doc->createElement("accessor"); - accnode.setAttribute("source","#vcg-mesh-positions-array"); - accnode.setAttribute("count",QString::number(nvert)); - accnode.setAttribute("stride","3"); + CreateSource(*(info->doc),meshnode,"positions",ap,nvert); - QDomElement parxnode = info->doc->createElement("param"); - parxnode.setAttribute("name","X"); - parxnode.setAttribute("type","float"); - QDomElement parynode = info->doc->createElement("param"); - parynode.setAttribute("name","Y"); - parynode.setAttribute("type","float"); - QDomElement parznode = info->doc->createElement("param"); - parznode.setAttribute("name","Z"); - parznode.setAttribute("type","float"); + if(mask & vcg::tri::io::Mask::IOM_VERTNORMAL | mask & vcg::tri::io::Mask::IOM_WEDGNORMAL) + { + QDomText an = info->doc->createTextNode(arrn); + CreateSource(*(info->doc),meshnode,"normals",an,nvert); + } - accnode.appendChild(parxnode); - accnode.appendChild(parynode); - accnode.appendChild(parznode); - technode.appendChild(accnode); - arrayposnode.appendChild(ap); - srcposnode.appendChild(arrayposnode); - srcposnode.appendChild(technode); - - meshnode.appendChild(srcposnode); - - QDomElement srcnmnode = info->doc->createElement("source"); - srcnmnode.setAttribute("id","vcg-mesh-normals"); - srcnmnode.setAttribute("name","vcg-mesh-normals"); + if(mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD) + { + QDomText at = info->doc->createTextNode(arrt); + CreateSource(*(info->doc),meshnode,"textcoords",at,nvert); + } - QDomElement arraynmnode = info->doc->createElement("float_array"); - arraynmnode.setAttribute("id","vcg-mesh-normals-array"); - arraynmnode.setAttribute("count",QString::number(nvert * 3)); - - QDomElement technode2 = info->doc->createElement("technique_common"); - QDomElement accnode2 = info->doc->createElement("accessor"); - accnode2.setAttribute("source","#vcg-mesh-normals-array"); - accnode2.setAttribute("count",QString::number(nvert)); - accnode2.setAttribute("stride","3"); - - QDomElement parxnode2 = info->doc->createElement("param"); - parxnode2.setAttribute("name","X"); - parxnode2.setAttribute("type","float"); - QDomElement parynode2 = info->doc->createElement("param"); - parynode2.setAttribute("name","Y"); - parynode2.setAttribute("type","float"); - QDomElement parznode2 = info->doc->createElement("param"); - parznode2.setAttribute("name","Z"); - parznode2.setAttribute("type","float"); - - QDomText an = info->doc->createTextNode(arrn); - - - accnode2.appendChild(parxnode2); - accnode2.appendChild(parynode2); - accnode2.appendChild(parznode2); - technode2.appendChild(accnode2); - arraynmnode.appendChild(an); - srcnmnode.appendChild(arraynmnode); - srcnmnode.appendChild(technode2); - - meshnode.appendChild(srcnmnode); + if(mask & vcg::tri::io::Mask::IOM_VERTCOLOR) + { + QDomText ac = info->doc->createTextNode(arrc); + CreateSource(*(info->doc),meshnode,"colors",ac,nvert); + } QDomElement vert = info->doc->createElement("vertices"); vert.setAttribute("id","vcg-mesh-vertices"); - QDomElement vinp_pos = info->doc->createElement("input"); - vinp_pos.setAttribute("semantic","POSITION"); - vinp_pos.setAttribute("source","#vcg-mesh-positions"); - QDomElement vinp_nm = info->doc->createElement("input"); - vinp_nm.setAttribute("semantic","NORMAL"); - vinp_nm.setAttribute("source","#vcg-mesh-normals"); - - vert.appendChild(vinp_pos); - vert.appendChild(vinp_nm); - + CreateVertInput(*(info->doc),vert,"POSITION","#vcg-mesh-positions"); + if(mask & vcg::tri::io::Mask::IOM_VERTNORMAL) + CreateVertInput(*(info->doc),vert,"NORMAL","#vcg-mesh-normals"); + if(mask & vcg::tri::io::Mask::IOM_VERTCOLOR) + CreateVertInput(*(info->doc),vert,"COLOR","#vcg-mesh-colors"); + if(mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD) + CreateVertInput(*(info->doc),vert,"TEXCOORD","#vcg-mesh-normals"); meshnode.appendChild(vert); QDomElement tri = info->doc->createElement("triangles"); - QDomElement tinp_vert = info->doc->createElement("input"); - tinp_vert.setAttribute("offset","0"); - tinp_vert.setAttribute("semantic","VERTEX"); - tinp_vert.setAttribute("source","#vcg-mesh-vertices"); + CreateFaceInput(*(info->doc),tri,"VERTEX","#vcg-mesh-vertices",0); QDomElement poly = info->doc->createElement("p"); - QString triangles_tess; int nface = 0; - triangles_tess.reserve(9*m.face.size()); + int nattr = 1; + + QString triangles_wn; + if (mask & MeshModel::IOM_WEDGNORMAL) + { + triangles_wn.reserve(3* 10 * m.face.size()); + CreateFaceInput(*(info->doc),tri,"NORMAL","#vcg-mesh-wnormals",nattr); + ++nattr; + } + QString triangles_wt; + if (mask & MeshModel::IOM_WEDGTEXCOORD) + { + triangles_wt.reserve(2 * 10 * m.face.size()); + CreateFaceInput(*(info->doc),tri,"TEXCOORD","#vcg-mesh-wtext",nattr); + ++nattr; + } + QString triangles_tess; + triangles_tess.reserve(nattr * 3 * 10 * m.face.size()); + int wn = 0; + int wt = 0; for(SaveMeshType::FaceIterator itf = m.face.begin();itf != m.face.end();++itf) { if (!(itf->IsD())) @@ -385,212 +435,236 @@ public: int ind_v = (*itf).V(ii) - &(m.vert[0]); if (triangles_tess == "") triangles_tess = QString::number(ind_v); - else triangles_tess = triangles_tess.append(" ").append(QString::number(ind_v)); + else triangles_tess.append(" ").append(QString::number(ind_v)); + if (mask & MeshModel::IOM_WEDGNORMAL) + { + triangles_tess.append(" ").append(QString::number(wn)); + ++wn; + triangles_wn.append(QString::number((*itf).WN(ii).X()).append(" ").append(QString::number((*itf).WN(ii).Y())).append(" ").append(QString::number((*itf).WN(ii).Z())).append(" ")); + } + + if (mask & MeshModel::IOM_WEDGTEXCOORD) + { + triangles_tess.append(" ").append(QString::number(wt)); + ++wt; + triangles_wt.append(QString::number((*itf).WT(ii).u()).append(" ").append(QString::number((*itf).WT(ii).v())).append(" ")); + } } ++nface; } } + tri.setAttribute("count",nface); + if (mask & MeshModel::IOM_WEDGNORMAL) + { + QDomText wnt = info->doc->createTextNode(triangles_wn); + CreateSource(*(info->doc),meshnode,"wnormals",wnt,nface * 3); + } + + if (mask & MeshModel::IOM_WEDGTEXCOORD) + { + QDomText wtt = info->doc->createTextNode(triangles_wt); + CreateSource(*(info->doc),meshnode,"wtext",wtt,nface * 3); + } QDomText tri_list = info->doc->createTextNode(triangles_tess); poly.appendChild(tri_list); - tri.appendChild(tinp_vert); tri.appendChild(poly); meshnode.appendChild(tri); geonode.appendChild(meshnode); geolib.at(0).appendChild(geonode); } - else - { - removeChildNode(scenelst,"instance_visual_scene"); - for(int vsscn = 0;vsscn < scenelst.size();++vsscn) - { - QString url = scenelst.at(vsscn).toElement().attribute("url"); - } + //else + //{ + // removeChildNode(scenelst,"instance_visual_scene"); + // for(int vsscn = 0;vsscn < scenelst.size();++vsscn) + // { + // QString url = scenelst.at(vsscn).toElement().attribute("url"); + // } - QDomElement vsnode = info->doc->createElement("instance_visual_scene"); - vsnode.setAttribute("url","#vcg-scene-node"); - scenelst.at(0).appendChild(vsnode); + // QDomElement vsnode = info->doc->createElement("instance_visual_scene"); + // vsnode.setAttribute("url","#vcg-scene-node"); + // scenelst.at(0).appendChild(vsnode); - - int vsscene_size = vsscene.size(); - assert(vsscene.size() == 1); - removeChildNode(vsscene,"visual_scene","id","vcg-scene-node"); - QDomElement vslnode = info->doc->createElement("visual_scene"); - vslnode.setAttribute("id","vcg-scene-node"); - vslnode.setAttribute("name","vcg-untitled"); + // + // int vsscene_size = vsscene.size(); + // assert(vsscene.size() == 1); + // removeChildNode(vsscene,"visual_scene","id","vcg-scene-node"); + // QDomElement vslnode = info->doc->createElement("visual_scene"); + // vslnode.setAttribute("id","vcg-scene-node"); + // vslnode.setAttribute("name","vcg-untitled"); - QDomElement vcgnode = info->doc->createElement("node"); - vcgnode.setAttribute("id","vcg-node"); - vcgnode.setAttribute("name","vcg-untitled"); + // QDomElement vcgnode = info->doc->createElement("node"); + // vcgnode.setAttribute("id","vcg-node"); + // vcgnode.setAttribute("name","vcg-untitled"); - /*QDomNodeList instgeo = info->doc->elementsByTagName("instance_geometry"); - for(int jj = 0;jj < instgeo.size();++jj) - { - if (!instgeo.at(jj).isNull()) - { - QDomNode par = instegeo.at(jj).parent(); - par - }*/ + // /*QDomNodeList instgeo = info->doc->elementsByTagName("instance_geometry"); + // for(int jj = 0;jj < instgeo.size();++jj) + // { + // if (!instgeo.at(jj).isNull()) + // { + // QDomNode par = instegeo.at(jj).parent(); + // par + // }*/ - QDomElement vcginst = info->doc->createElement("instance_geometry"); - vcginst.setAttribute("url","#vcg-mesh-lib"); - vcgnode.appendChild(vcginst); - vslnode.appendChild(vcgnode); - vsscene.at(0).appendChild(vslnode); + // QDomElement vcginst = info->doc->createElement("instance_geometry"); + // vcginst.setAttribute("url","#vcg-mesh-lib"); + // vcgnode.appendChild(vcginst); + // vslnode.appendChild(vcgnode); + // vsscene.at(0).appendChild(vslnode); - QDomNodeList geolib = info->doc->elementsByTagName("library_geometries"); - assert(geolib.size() == 1); - //removeChildNode(geolib.at(0)); - - /*QDomElement mshnode; - mshnode.setTagName("mesh");*/ - - removeChildNode(geolib.at(0),"geometry","id","vcg-mesh-lib"); - QDomElement geonode = info->doc->createElement("geometry"); - geonode.setAttribute("id","vcg-mesh-lib"); - geonode.setAttribute("name","vcg-mesh"); - - QDomElement meshnode = info->doc->createElement("mesh"); - - QDomElement srcposnode = info->doc->createElement("source"); - srcposnode.setAttribute("id","vcg-mesh-positions"); - srcposnode.setAttribute("name","vcg-mesh-positions"); + // QDomNodeList geolib = info->doc->elementsByTagName("library_geometries"); + // assert(geolib.size() == 1); + // //removeChildNode(geolib.at(0)); + // + // /*QDomElement mshnode; + // mshnode.setTagName("mesh");*/ + // + // removeChildNode(geolib.at(0),"geometry","id","vcg-mesh-lib"); + // QDomElement geonode = info->doc->createElement("geometry"); + // geonode.setAttribute("id","vcg-mesh-lib"); + // geonode.setAttribute("name","vcg-mesh"); + // + // QDomElement meshnode = info->doc->createElement("mesh"); + // + // QDomElement srcposnode = info->doc->createElement("source"); + // srcposnode.setAttribute("id","vcg-mesh-positions"); + // srcposnode.setAttribute("name","vcg-mesh-positions"); - QDomElement arrayposnode = info->doc->createElement("float_array"); - arrayposnode.setAttribute("id","vcg-mesh-positions-array"); - - QString arrp; - arrp.reserve(8 * m.vert.size()); - QString arrn; - arrn.reserve(8 * m.vert.size()); - int nvert = 0; - for(SaveMeshType::VertexIterator it = m.vert.begin();it != m.vert.end();++it) - { - if (!(it->IsD())) - { - arrp.append(QString::number(it->P().X()) + " " +QString::number(it->P().Y()) + " " + QString::number(it->P().Z()) + " "); - arrn.append(QString::number(it->N().X()) + " " + QString::number(it->N().Y()) + " " + QString::number(it->N().Z())+ " "); - //arrp.append(QString::number(it->P().X()).append(" ").append(QString::number(it->P().Y())).append(" ").append(QString::number(it->P().Z())).append(" ")); - //arrp.append(QString::number(it->N().X()).append(" ").append(QString::number(it->N().Y())).append(" ").append(QString::number(it->N().Z())).append(" ")); - ++nvert; - } - } - arrayposnode.setAttribute("count",QString::number(nvert * 3)); - QDomText ap = info->doc->createTextNode(arrp); + // QDomElement arrayposnode = info->doc->createElement("float_array"); + // arrayposnode.setAttribute("id","vcg-mesh-positions-array"); + // + // QString arrp; + // arrp.reserve(10 * m.vert.size()); + // QString arrn; + // arrn.reserve(10 * m.vert.size()); + // int nvert = 0; + // for(SaveMeshType::VertexIterator it = m.vert.begin();it != m.vert.end();++it) + // { + // if (!(it->IsD())) + // { + // //arrp.append(QString::number(it->P().X()) + " " +QString::number(it->P().Y()) + " " + QString::number(it->P().Z()) + " "); + // //arrn.append(QString::number(it->N().X()) + " " + QString::number(it->N().Y()) + " " + QString::number(it->N().Z())+ " "); + // arrp.append(QString::number(it->P().X()).append(" ").append(QString::number(it->P().Y())).append(" ").append(QString::number(it->P().Z())).append(" ")); + // arrp.append(QString::number(it->N().X()).append(" ").append(QString::number(it->N().Y())).append(" ").append(QString::number(it->N().Z())).append(" ")); + // ++nvert; + // } + // } + // arrayposnode.setAttribute("count",QString::number(nvert * 3)); + // QDomText ap = info->doc->createTextNode(arrp); - QDomElement technode = info->doc->createElement("technique_common"); - QDomElement accnode = info->doc->createElement("accessor"); - accnode.setAttribute("source","#vcg-mesh-positions-array"); - accnode.setAttribute("count",QString::number(nvert)); - accnode.setAttribute("stride","3"); - - QDomElement parxnode = info->doc->createElement("param"); - parxnode.setAttribute("name","X"); - parxnode.setAttribute("type","float"); - QDomElement parynode = info->doc->createElement("param"); - parynode.setAttribute("name","Y"); - parynode.setAttribute("type","float"); - QDomElement parznode = info->doc->createElement("param"); - parznode.setAttribute("name","Z"); - parznode.setAttribute("type","float"); + // QDomElement technode = info->doc->createElement("technique_common"); + // QDomElement accnode = info->doc->createElement("accessor"); + // accnode.setAttribute("source","#vcg-mesh-positions-array"); + // accnode.setAttribute("count",QString::number(nvert)); + // accnode.setAttribute("stride","3"); + // + // QDomElement parxnode = info->doc->createElement("param"); + // parxnode.setAttribute("name","X"); + // parxnode.setAttribute("type","float"); + // QDomElement parynode = info->doc->createElement("param"); + // parynode.setAttribute("name","Y"); + // parynode.setAttribute("type","float"); + // QDomElement parznode = info->doc->createElement("param"); + // parznode.setAttribute("name","Z"); + // parznode.setAttribute("type","float"); - accnode.appendChild(parxnode); - accnode.appendChild(parynode); - accnode.appendChild(parznode); - technode.appendChild(accnode); - arrayposnode.appendChild(ap); - srcposnode.appendChild(arrayposnode); - srcposnode.appendChild(technode); - - meshnode.appendChild(srcposnode); - - QDomElement srcnmnode = info->doc->createElement("source"); - srcnmnode.setAttribute("id","vcg-mesh-normals"); - srcnmnode.setAttribute("name","vcg-mesh-normals"); + // accnode.appendChild(parxnode); + // accnode.appendChild(parynode); + // accnode.appendChild(parznode); + // technode.appendChild(accnode); + // arrayposnode.appendChild(ap); + // srcposnode.appendChild(arrayposnode); + // srcposnode.appendChild(technode); + // + // meshnode.appendChild(srcposnode); + // + // QDomElement srcnmnode = info->doc->createElement("source"); + // srcnmnode.setAttribute("id","vcg-mesh-normals"); + // srcnmnode.setAttribute("name","vcg-mesh-normals"); - QDomElement arraynmnode = info->doc->createElement("float_array"); - arraynmnode.setAttribute("id","vcg-mesh-normals-array"); - arraynmnode.setAttribute("count",QString::number(nvert * 3)); + // QDomElement arraynmnode = info->doc->createElement("float_array"); + // arraynmnode.setAttribute("id","vcg-mesh-normals-array"); + // arraynmnode.setAttribute("count",QString::number(nvert * 3)); - QDomElement technode2 = info->doc->createElement("technique_common"); - QDomElement accnode2 = info->doc->createElement("accessor"); - accnode2.setAttribute("source","#vcg-mesh-normals-array"); - accnode2.setAttribute("count",QString::number(nvert)); - accnode2.setAttribute("stride","3"); - - QDomElement parxnode2 = info->doc->createElement("param"); - parxnode2.setAttribute("name","X"); - parxnode2.setAttribute("type","float"); - QDomElement parynode2 = info->doc->createElement("param"); - parynode2.setAttribute("name","Y"); - parynode2.setAttribute("type","float"); - QDomElement parznode2 = info->doc->createElement("param"); - parznode2.setAttribute("name","Z"); - parznode2.setAttribute("type","float"); + // QDomElement technode2 = info->doc->createElement("technique_common"); + // QDomElement accnode2 = info->doc->createElement("accessor"); + // accnode2.setAttribute("source","#vcg-mesh-normals-array"); + // accnode2.setAttribute("count",QString::number(nvert)); + // accnode2.setAttribute("stride","3"); + // + // QDomElement parxnode2 = info->doc->createElement("param"); + // parxnode2.setAttribute("name","X"); + // parxnode2.setAttribute("type","float"); + // QDomElement parynode2 = info->doc->createElement("param"); + // parynode2.setAttribute("name","Y"); + // parynode2.setAttribute("type","float"); + // QDomElement parznode2 = info->doc->createElement("param"); + // parznode2.setAttribute("name","Z"); + // parznode2.setAttribute("type","float"); - QDomText an = info->doc->createTextNode(arrn); - + // QDomText an = info->doc->createTextNode(arrn); + // - accnode2.appendChild(parxnode2); - accnode2.appendChild(parynode2); - accnode2.appendChild(parznode2); - technode2.appendChild(accnode2); - arraynmnode.appendChild(an); - srcnmnode.appendChild(arraynmnode); - srcnmnode.appendChild(technode2); - - meshnode.appendChild(srcnmnode); + // accnode2.appendChild(parxnode2); + // accnode2.appendChild(parynode2); + // accnode2.appendChild(parznode2); + // technode2.appendChild(accnode2); + // arraynmnode.appendChild(an); + // srcnmnode.appendChild(arraynmnode); + // srcnmnode.appendChild(technode2); + // + // meshnode.appendChild(srcnmnode); - QDomElement vert = info->doc->createElement("vertices"); - vert.setAttribute("id","vcg-mesh-vertices"); - QDomElement vinp_pos = info->doc->createElement("input"); - vinp_pos.setAttribute("semantic","POSITION"); - vinp_pos.setAttribute("source","#vcg-mesh-positions"); - QDomElement vinp_nm = info->doc->createElement("input"); - vinp_nm.setAttribute("semantic","NORMAL"); - vinp_nm.setAttribute("source","#vcg-mesh-normals"); + // QDomElement vert = info->doc->createElement("vertices"); + // vert.setAttribute("id","vcg-mesh-vertices"); + // QDomElement vinp_pos = info->doc->createElement("input"); + // vinp_pos.setAttribute("semantic","POSITION"); + // vinp_pos.setAttribute("source","#vcg-mesh-positions"); + // QDomElement vinp_nm = info->doc->createElement("input"); + // vinp_nm.setAttribute("semantic","NORMAL"); + // vinp_nm.setAttribute("source","#vcg-mesh-normals"); - vert.appendChild(vinp_pos); - vert.appendChild(vinp_nm); + // vert.appendChild(vinp_pos); + // vert.appendChild(vinp_nm); - meshnode.appendChild(vert); - - QDomElement tri = info->doc->createElement("triangles"); - + // meshnode.appendChild(vert); + // + // QDomElement tri = info->doc->createElement("triangles"); + // - QDomElement tinp_vert = info->doc->createElement("input"); - tinp_vert.setAttribute("offset","0"); - tinp_vert.setAttribute("semantic","VERTEX"); - tinp_vert.setAttribute("source","#vcg-mesh-vertices"); - QDomElement poly = info->doc->createElement("p"); - QString triangles_tess; - int nface = 0; - triangles_tess.reserve(9*m.face.size()); - for(SaveMeshType::FaceIterator itf = m.face.begin();itf != m.face.end();++itf) - { - if (!(itf->IsD())) - { - for(unsigned int ii = 0;ii < 3;++ii) - { - int ind_v = (*itf).V(ii) - &(m.vert[0]); - if (triangles_tess == "") - triangles_tess = QString::number(ind_v); - else triangles_tess = triangles_tess.append(" ").append(QString::number(ind_v)); - } - ++nface; - } - } - tri.setAttribute("count",nface); + // QDomElement tinp_vert = info->doc->createElement("input"); + // tinp_vert.setAttribute("offset","0"); + // tinp_vert.setAttribute("semantic","VERTEX"); + // tinp_vert.setAttribute("source","#vcg-mesh-vertices"); + // QDomElement poly = info->doc->createElement("p"); + // QString triangles_tess; + // int nface = 0; + // triangles_tess.reserve(10*m.face.size()); + // for(SaveMeshType::FaceIterator itf = m.face.begin();itf != m.face.end();++itf) + // { + // if (!(itf->IsD())) + // { + // for(unsigned int ii = 0;ii < 3;++ii) + // { + // int ind_v = (*itf).V(ii) - &(m.vert[0]); + // if (triangles_tess == "") + // triangles_tess = QString::number(ind_v); + // else triangles_tess.append(" ").append(QString::number(ind_v)); + // } + // ++nface; + // } + // } + // tri.setAttribute("count",nface); - QDomText tri_list = info->doc->createTextNode(triangles_tess); - poly.appendChild(tri_list); - tri.appendChild(tinp_vert); - tri.appendChild(poly); - meshnode.appendChild(tri); - geonode.appendChild(meshnode); - geolib.at(0).appendChild(geonode); - } + // QDomText tri_list = info->doc->createTextNode(triangles_tess); + // poly.appendChild(tri_list); + // tri.appendChild(tinp_vert); + // tri.appendChild(poly); + // meshnode.appendChild(tri); + // geonode.appendChild(meshnode); + // geolib.at(0).appendChild(geonode); + //} QString st = info->doc->toString(); QFile file(filename); @@ -610,15 +684,17 @@ public: //capability |= MeshModel::IOM_CAMERA; //vert - //capability |= MeshModel::IOM_VERTTEXCOORD; + capability |= MeshModel::IOM_VERTNORMAL; + capability |= MeshModel::IOM_VERTTEXCOORD; + capability |= MeshModel::IOM_VERTCOLOR; + //capability |= MeshModel:: + ////face + ////capability |= MeshModel::IOM_FACEFLAGS; + ////capability |= MeshModel::IOM_FACECOLOR; + //capability |= MeshModel::IOM_FACENORMAL; - //face - capability |= MeshModel::IOM_FACEFLAGS; - //capability |= MeshModel::IOM_FACECOLOR; - capability |= MeshModel::IOM_FACENORMAL; - - //wedg - //capability |= MeshModel::IOM_WEDGTEXCOORD; + ////wedg + capability |= MeshModel::IOM_WEDGTEXCOORD; capability |= MeshModel::IOM_WEDGNORMAL; return capability; diff --git a/wrap/io_trimesh/import_dae.h b/wrap/io_trimesh/import_dae.h index dba32ddb..265e9bc9 100644 --- a/wrap/io_trimesh/import_dae.h +++ b/wrap/io_trimesh/import_dae.h @@ -343,120 +343,143 @@ namespace io { return E_NOERROR; } - static bool LoadMask(const char * filename, AdditionalInfoDAE &addinfo) + static bool LoadMask(const char * filename, AdditionalInfoDAE*& addinfo) { - std::ifstream stream(filename); - if (stream.fail()) - return false; - - stream.seekg (0, std::ios::end); - int length = stream.tellg(); - if (length == 0) return false; - stream.seekg (0, std::ios::beg); - bool bHasPerWedgeTexCoord = false; bool bHasPerWedgeNormal = false; - bool bUsingMaterial = false; bool bHasPerVertexColor = false; bool bHasPerFaceColor = false; - + bool bHasPerVertexNormal = false; + bool bHasPerVertexText = false; + AdditionalInfoDAE* inf = new AdditionalInfoDAE(); inf->dae = new InfoDAE(); InfoDAE* info = inf->dae; - info->doc = new FCDocument(); - unsigned int numvert = 0; - unsigned int numtriang = 0; - - unsigned int mask = 0; - - FCDGeometryLibrary* geolib = info->doc->GetGeometryLibrary(); - if (geolib->IsEmpty()) return false; - size_t n = geolib->GetEntityCount(); - std::vector geomsh(n); - - - FUStatus st = info->doc->LoadFromFile(FUStringConversion::ToFString(filename)); - if (st.IsFailure()) + QDomDocument* doc = new QDomDocument(filename); + QFile file(filename); + if (!file.open(QIODevice::ReadOnly)) + return E_CANTOPEN; + if (!doc->setContent(&file)) { - delete info->doc; - info->doc = NULL; - return false; + file.close(); + return E_CANTOPEN; } + file.close(); + - bool amesh = false; + info->doc = doc; + + QDomNodeList& scenes = info->doc->elementsByTagName("scene"); + int scn_size = scenes.size(); + - //for any mesh in the collada file - for(unsigned int ii = 0;ii < geomsh.size();++ii) + //Is there geometry in the file? + bool geoinst_found = false; + //for each scene in COLLADA FILE + for(int scn = 0;scn < scn_size;++scn) { - if (!geolib->GetEntity(ii)->IsMesh()) - { - amesh |= false; - } - else - { - amesh |= true; - geomsh[ii] = geolib->GetEntity(ii)->GetMesh(); + QDomNodeList& instscenes = scenes.at(scn).toElement().elementsByTagName("instance_visual_scene"); + int instscn_size = instscenes.size(); + if (instscn_size == 0) + return E_INCOMPATIBLECOLLADA141FORMAT; - unsigned int ver; - if (geomsh[ii]->GetFaceCount() > 0) + //for each scene instance in a COLLADA scene + for(int instscn = 0;instscn < instscn_size; ++instscn) + { + QString libscn_url; + referenceToANodeAttribute(instscenes.at(instscn),"url",libscn_url); + QDomNode nd = QDomNode(*(info->doc)); + QDomNode visscn = findNodeBySpecificAttributeValue(*(info->doc),"visual_scene","id",libscn_url); + if(visscn.isNull()) + return E_UNREFERENCEBLEDCOLLADAATTRIBUTE; + + //for each node in the libscn_url visual scene + 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) { - geomsh[ii]->Triangulate(); - - size_t dim = geomsh[ii]->GetFaceVertexCount() / geomsh[ii]->GetFaceCount(); - assert(dim == 3); - //MyMesh* msh = new MyMesh(); - //size_t nattr = geomsh[ii]->GetSourceCount(); - //FCDGeometrySourceList& srclst = geomsh[ii]->GetVertexSources(); - - FCDGeometrySource* src; - if ((src = geomsh[ii]->GetPositionSource()) != NULL) + QDomNodeList& geoinst = visscn_child.at(chdind).toElement().elementsByTagName("instance_geometry"); + int geoinst_size = geoinst.size(); + if (geoinst_size != 0) { - FloatList& flst = src->GetSourceData(); - unsigned int str = src->GetSourceStride(); - assert(flst.size() % str == 0); - ver = flst.size() / str; - numvert += flst.size() / str; - } - else - { - delete info->doc; - info->doc = NULL; - return false; - } - - size_t pol = geomsh[ii]->GetPolygonsCount(); - - for(unsigned int pset = 0; pset < pol;++pset) - { - FCDGeometryMesh* tmp = geomsh[ii]; - FCDGeometryPolygonsInput* pos = tmp->GetPolygons(pset)->FindInput(FUDaeGeometryInput::POSITION); - if ((pos == NULL) || (pos->GetSource()->GetSourceStride() != 3)) + + geoinst_found |= true; + QDomNodeList& geolib = info->doc->elementsByTagName("library_geometries"); + int geolib_size = geolib.size(); + assert(geolib_size == 1); + //!!!!!!!!!!!!!!!!!here will be the code for geometry transformations!!!!!!!!!!!!!!!!!!!!!! + info->numvert = 0; + info->numface = 0; + for(int geoinst_ind = 0;geoinst_ind < geoinst_size;++geoinst_ind) { - delete info->doc; - info->doc = NULL; - return false; + QString geo_url; + referenceToANodeAttribute(geoinst.at(geoinst_ind),"url",geo_url); + + QDomNode geo = findNodeBySpecificAttributeValue(geolib.at(0),"geometry","id",geo_url); + if (geo.isNull()) + return E_UNREFERENCEBLEDCOLLADAATTRIBUTE; + + QDomNodeList vertlist = geo.toElement().elementsByTagName("vertices"); + + for(int vert = 0;vert < vertlist.size();++vert) + { + QDomNode no; + no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","POSITION"); + QString srcurl; + referenceToANodeAttribute(no,"source",srcurl); + no = findNodeBySpecificAttributeValue(geo,"source","id",srcurl); + QDomNodeList fa = no.toElement().elementsByTagName("float_array"); + assert(fa.size() == 1); + info->numvert += (fa.at(0).toElement().attribute("count").toInt() / 3); + no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","COLOR"); + if (!no.isNull()) + bHasPerVertexColor = true; + no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","NORMAL"); + if (!no.isNull()) + bHasPerVertexNormal = true; + no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","TEXCOORD"); + if (!no.isNull()) + bHasPerVertexText = true; + } + + QDomNodeList facelist = geo.toElement().elementsByTagName("triangles"); + for(int face = 0;face < facelist.size();++face) + { + info->numface += facelist.at(face).toElement().attribute("count").toInt() ; + QDomNode no; + no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","NORMAL"); + if (!no.isNull()) + bHasPerWedgeNormal = true; + no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","TEXCOORD"); + if (!no.isNull()) + bHasPerWedgeTexCoord = true; + } } - //unsigned int hi = pos->indices[1]; - - FCDGeometryPolygonsInputList normlist; - tmp->GetPolygons(pset)->FindInputs(FUDaeGeometryInput::NORMAL,normlist); - FCDGeometryPolygonsInputList tet; - tmp->GetPolygons(pset)->FindInputs(FUDaeGeometryInput::TEXCOORD,tet); - - for(unsigned int kk = 0; kk < tet.size();++kk) - if ((normlist[0]->GetSource()->GetSourceData().size() == ver * 3 * 3) && (!bHasPerWedgeNormal)) - bHasPerWedgeNormal = true; - - for(unsigned int kk = 0; kk < tet.size();++kk) - if ((tet[kk]->GetSource()->GetSourceData().size() == ver * 3 * 2) && (!bHasPerTexCoord)) - bHasPerTexCoord = true; } } } } - inf.nvert = - addinfo = inf; + + info->mask = 0; + + if (bHasPerWedgeTexCoord) + info->mask |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD; + if (bHasPerWedgeNormal) + info->mask |= vcg::tri::io::Mask::IOM_WEDGNORMAL; + if (bHasPerVertexColor) + info->mask |= vcg::tri::io::Mask::IOM_VERTCOLOR; + if (bHasPerFaceColor) + info->mask |= vcg::tri::io::Mask::IOM_FACECOLOR; + if (bHasPerVertexNormal) + info->mask |= vcg::tri::io::Mask::IOM_VERTNORMAL; + if (bHasPerVertexText) + info->mask |= vcg::tri::io::Mask::IOM_VERTTEXCOORD; + + delete (info->doc); + addinfo = inf; return true; } }; diff --git a/wrap/io_trimesh/util_dae.h b/wrap/io_trimesh/util_dae.h index ed1aa9df..baa896d8 100644 --- a/wrap/io_trimesh/util_dae.h +++ b/wrap/io_trimesh/util_dae.h @@ -5,6 +5,8 @@ #include #include +#include + #include #include #include