diff --git a/wrap/io_trimesh/import_dae.h b/wrap/io_trimesh/import_dae.h index c3c223c9..a000b6e0 100644 --- a/wrap/io_trimesh/import_dae.h +++ b/wrap/io_trimesh/import_dae.h @@ -4,7 +4,7 @@ //importer for collada's files #include -#include +//#include #include #include #include @@ -58,15 +58,22 @@ public: static int Open(OpenMeshType& m,const char* filename) { - assert(filename!=0); FCDocument* doc = new FCDocument(); FUStatus st = doc->LoadFromFile(FUStringConversion::ToFString(filename)); - if (st.IsFailure()) + if (st.IsFailure()) + { + delete doc; + doc = NULL; return E_CANTOPEN; + } FCDGeometryLibrary* geolib = doc->GetGeometryLibrary(); - if (geolib->IsEmpty()) return E_NOGEOMETRYLIBRARY; + if (geolib->IsEmpty()) + { + delete doc; + return E_NOGEOMETRYLIBRARY; + } size_t n = geolib->GetEntityCount(); std::vector geomsh(n); @@ -76,6 +83,7 @@ public: { if (!geolib->GetEntity(ii)->IsMesh()) { + delete doc; return E_NOMESH; } else @@ -109,7 +117,11 @@ public: } } - else return E_NOVERTEXPOSITION; + else + { + delete doc; + return E_NOVERTEXPOSITION; + } //a single mesh may be composed by a variable numbers of polygons' subsets size_t pol = geomsh[ii]->GetPolygonsCount(); @@ -119,26 +131,32 @@ public: { FCDGeometryMesh* tmp = geomsh[ii]; FCDGeometryPolygonsInput* pos = tmp->GetPolygons(pset)->FindInput(FUDaeGeometryInput::POSITION); - if ((pos == NULL) || (pos->source->GetSourceStride() != 3)) return E_NO3DVERTEXPOSITION; + if ((pos == NULL) || (pos->source->GetSourceStride() != 3)) + { + delete doc; + return E_NO3DVERTEXPOSITION; + } //unsigned int hi = pos->indices[1]; FCDGeometryPolygonsInput* norm = tmp->GetPolygons(pset)->FindInput(FUDaeGeometryInput::NORMAL); //unsigned int li = norm->indices[1]; FCDGeometryPolygonsInput* text = tmp->GetPolygons(pset)->FindInput(FUDaeGeometryInput::TEXCOORD); - bool isvalidwnorm = (m.HasPerWedgeNormal()) && (norm != NULL) && (norm->source->GetSourceStride() == 3); - bool isvalidnorm = (m.HasPerVertexNormal()) && (norm != NULL) && (norm->source->GetSourceStride() == 3); - bool isvalidtext = (HasPerWedgeTexture(m)) && (text != NULL) && (text->source->GetSourceStride() == 2); + bool isvalidwnorm = (m.HasPerWedgeNormal()) && (norm != NULL) && (norm->GetSource()->GetSourceStride() == 3); + bool isvalidnorm = (m.HasPerVertexNormal()) && (norm != NULL) && (norm->GetSource()->GetSourceStride() == 3); + bool isvalidtext = (HasPerWedgeTexture(m)) && (text != NULL) && (text->GetSource()->GetSourceStride() == 2); FCDGeometryPolygonsInputList normlist; tmp->GetPolygons(pset)->FindInputs(FUDaeGeometryInput::NORMAL,normlist); FCDGeometryPolygonsInputList tet; tmp->GetPolygons(pset)->FindInputs(FUDaeGeometryInput::TEXCOORD,tet); + + unsigned int offset = m.face.size(); for(unsigned int ind = 0;ind < pos->indices.size();++ind) { typename OpenMeshType::FaceIterator fi=vcg::tri::Allocator::AddFaces(m,1); assert(pos->indices[ind] < m.vert.size()); - fi->V(0) = &m.vert[pos->indices[ind]]; + fi->V(0) = &m.vert[offset + pos->indices[ind]]; size_t dimn = norm->indices.size(); if (isvalidnorm) @@ -146,7 +164,7 @@ public: //assert(norm->indices[ind] * 3 < norm->source->GetSourceData().size()); UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(normlist[0]); //fi->V(0)->N() += vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); - fi->V(0)->N() += vcg::Point3f(normlist[0]->source->GetSourceData()[(*ls)[ind] * 2],normlist[0]->source->GetSourceData()[(*ls)[ind] * 2 + 1],normlist[0]->source->GetSourceData()[(*ls)[ind] * 2 + 2]); + fi->V(0)->N() += vcg::Point3f(normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 2]); //++fi->V(0)->incidentfaces; } @@ -156,20 +174,20 @@ public: { //NON CAMBIARE!!!!E' L'unico modo in cui restituisce gli indici corretti quando c'e' piu' di un insieme con la stessa semantica!! UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(tet[hh]); - fi->WT(0).t(hh) = vcg::Point2f(tet[hh]->source->GetSourceData()[(*ls)[ind] * 2],tet[hh]->source->GetSourceData()[(*ls)[ind] * 2 + 1]); + fi->WT(0).t(hh) = vcg::Point2f(tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2],tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1]); } } if (isvalidwnorm) { - fi->WN(0) = vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); - fi->WN(1) = vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind + 1] * 3],norm->source->GetSourceData()[norm->indices[ind + 1] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind + 1] * 3 + 2]).Normalize(); - fi->WN(2) = vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind + 2] * 3],norm->source->GetSourceData()[norm->indices[ind + 2] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind + 2] * 3 + 2]).Normalize(); + fi->WN(0) = vcg::Point3f(norm->GetSource()->GetSourceData()[norm->indices[ind] * 3],norm->GetSource()->GetSourceData()[norm->indices[ind] * 3 + 1],norm->GetSource()->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); + fi->WN(1) = vcg::Point3f(norm->GetSource()->GetSourceData()[norm->indices[ind + 1] * 3],norm->GetSource()->GetSourceData()[norm->indices[ind + 1] * 3 + 1],norm->GetSource()->GetSourceData()[norm->indices[ind + 1] * 3 + 2]).Normalize(); + fi->WN(2) = vcg::Point3f(norm->GetSource()->GetSourceData()[norm->indices[ind + 2] * 3],norm->GetSource()->GetSourceData()[norm->indices[ind + 2] * 3 + 1],norm->GetSource()->GetSourceData()[norm->indices[ind + 2] * 3 + 2]).Normalize(); } ++ind; assert(pos->indices[ind] < m.vert.size()); - fi->V(1) = &m.vert[pos->indices[ind]]; + fi->V(1) = &m.vert[offset + pos->indices[ind]]; if (isvalidnorm) { @@ -177,7 +195,7 @@ public: //fi->V(1)->N() += vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(normlist[0]); //fi->V(0)->N() += vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); - fi->V(1)->N() += vcg::Point3f(normlist[0]->source->GetSourceData()[(*ls)[ind] * 2],normlist[0]->source->GetSourceData()[(*ls)[ind] * 2 + 1],normlist[0]->source->GetSourceData()[(*ls)[ind] * 2 + 2]); + fi->V(1)->N() += vcg::Point3f(normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 2]); //++fi->V(1)->incidentfaces; } @@ -187,13 +205,13 @@ public: for(unsigned int hh = 0; hh < tet.size();++hh) { UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(tet[hh]); - fi->WT(1).t(hh) = vcg::Point2f(tet[hh]->source->GetSourceData()[(*ls)[ind] * 2],tet[hh]->source->GetSourceData()[(*ls)[ind] * 2 + 1]); + fi->WT(1).t(hh) = vcg::Point2f(tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2],tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1]); } } ++ind; assert(pos->indices[ind] < m.vert.size()); - fi->V(2) = &m.vert[pos->indices[ind]]; + fi->V(2) = &m.vert[offset + pos->indices[ind]]; if (isvalidnorm) { @@ -201,7 +219,7 @@ public: //fi->V(2)->N() += vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(normlist[0]); //fi->V(0)->N() += vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); - fi->V(2)->N() += vcg::Point3f(normlist[0]->source->GetSourceData()[(*ls)[ind] * 2],normlist[0]->source->GetSourceData()[(*ls)[ind] * 2 + 1],normlist[0]->source->GetSourceData()[(*ls)[ind] * 2 + 2]); + fi->V(2)->N() += vcg::Point3f(normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 2]); //++fi->V(2)->incidentfaces; } @@ -210,7 +228,7 @@ public: for(unsigned int hh = 0; hh < tet.size();++hh) { UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(tet[hh]); - fi->WT(2).t(hh) = vcg::Point2f(tet[hh]->source->GetSourceData()[(*ls)[ind] * 2],tet[hh]->source->GetSourceData()[(*ls)[ind] * 2 + 1]); + fi->WT(2).t(hh) = vcg::Point2f(tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2],tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1]); } } @@ -238,6 +256,204 @@ public: delete doc; return E_NOERROR; } + + /*this open function should be used when you want to maintain the Collada's XML tree. If the file will correctly opened + doc argument in the function's signiture will contain the pointer to XML tree otherwise a NULL pointer*/ + + static int Open(OpenMeshType& m,const char* filename,FCDocument** doc) + { + (*doc) = new FCDocument(); + + FUStatus st = (*doc)->LoadFromFile(FUStringConversion::ToFString(filename)); + if (st.IsFailure()) + { + delete *doc; + *doc = NULL; + return E_CANTOPEN; + } + + FCDGeometryLibrary* geolib = (*doc)->GetGeometryLibrary(); + if (geolib->IsEmpty()) return E_NOGEOMETRYLIBRARY; + size_t n = geolib->GetEntityCount(); + std::vector geomsh(n); + + //for any mesh in the collada file + + for(unsigned int ii = 0;ii < geomsh.size();++ii) + { + if (!geolib->GetEntity(ii)->IsMesh()) + { + delete *doc; + *doc = NULL; + return E_NOMESH; + } + else + { + geomsh[ii] = geolib->GetEntity(ii)->GetMesh(); + unsigned int offset = m.vert.size(); + if (geomsh[ii]->GetFaceCount() > 0) + { + 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) + { + FloatList& flst = src->GetSourceData(); + unsigned int str = src->GetSourceStride(); + assert(flst.size() % str == 0); + for(unsigned int cont = 0;cont < flst.size();cont += str) + { + OpenMeshType::VertexIterator vi=vcg::tri::Allocator::AddVertices(m,1); + vi->P()= vcg::Point3f(flst[cont],flst[cont + 1],flst[cont + 2]); + vi->N() = vcg::Point3f(0.0,0.0,0.0); + } + } + else + { + delete *doc; + *doc = NULL; + return E_NOVERTEXPOSITION; + } + + //a single mesh may be composed by a variable numbers of polygons' subsets + size_t pol = geomsh[ii]->GetPolygonsCount(); + + //unsigned int offset = m.vert.size(); + + //for any polygons' subset in a single mesh + 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)) + { + delete *doc; + *doc = NULL; + return E_NO3DVERTEXPOSITION; + } + //unsigned int hi = pos->indices[1]; + FCDGeometryPolygonsInput* norm = tmp->GetPolygons(pset)->FindInput(FUDaeGeometryInput::NORMAL); + //unsigned int li = norm->indices[1]; + FCDGeometryPolygonsInput* text = tmp->GetPolygons(pset)->FindInput(FUDaeGeometryInput::TEXCOORD); + + bool isvalidwnorm = (m.HasPerWedgeNormal()) && (norm != NULL) && (norm->GetSource()->GetSourceStride() == 3); + bool isvalidnorm = (m.HasPerVertexNormal()) && (norm != NULL) && (norm->GetSource()->GetSourceStride() == 3); + bool isvalidtext = (HasPerWedgeTexture(m)) && (text != NULL) && (text->GetSource()->GetSourceStride() == 2); + + FCDGeometryPolygonsInputList normlist; + tmp->GetPolygons(pset)->FindInputs(FUDaeGeometryInput::NORMAL,normlist); + FCDGeometryPolygonsInputList tet; + tmp->GetPolygons(pset)->FindInputs(FUDaeGeometryInput::TEXCOORD,tet); + + for(unsigned int ind = 0;ind < pos->indices.size();++ind) + { + OpenMeshType::FaceIterator fi=vcg::tri::Allocator::AddFaces(m,1); + assert(offset + pos->indices[ind] < m.vert.size()); + fi->V(0) = &m.vert[offset + pos->indices[ind]]; + + //size_t dimn = norm->indices.size(); + if (isvalidnorm) + { + //assert(norm->indices[ind] * 3 < norm->source->GetSourceData().size()); + UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(normlist[0]); + //fi->V(0)->N() += vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); + fi->V(0)->N() += vcg::Point3f(normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 2]); + //++fi->V(0)->incidentfaces; + } + + if (isvalidtext) + { + for(unsigned int hh = 0; hh < tet.size();++hh) + { + //NON CAMBIARE!!!!E' L'unico modo in cui restituisce gli indici corretti quando c'e' piu' di un insieme con la stessa semantica!! + UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(tet[hh]); + fi->WT(0).t(hh) = vcg::Point2f(tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2],tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1]); + } + } + + if (isvalidwnorm) + { + fi->WN(0) = vcg::Point3f(norm->GetSource()->GetSourceData()[norm->indices[ind] * 3],norm->GetSource()->GetSourceData()[norm->indices[ind] * 3 + 1],norm->GetSource()->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); + fi->WN(1) = vcg::Point3f(norm->GetSource()->GetSourceData()[norm->indices[ind + 1] * 3],norm->GetSource()->GetSourceData()[norm->indices[ind + 1] * 3 + 1],norm->GetSource()->GetSourceData()[norm->indices[ind + 1] * 3 + 2]).Normalize(); + fi->WN(2) = vcg::Point3f(norm->GetSource()->GetSourceData()[norm->indices[ind + 2] * 3],norm->GetSource()->GetSourceData()[norm->indices[ind + 2] * 3 + 1],norm->GetSource()->GetSourceData()[norm->indices[ind + 2] * 3 + 2]).Normalize(); + } + + ++ind; + assert(offset + pos->indices[ind] < m.vert.size()); + fi->V(1) = &m.vert[offset + pos->indices[ind]]; + + if (isvalidnorm) + { + //assert(norm->indices[ind] * 3 < norm->source->GetSourceData().size()); + //fi->V(1)->N() += vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); + UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(normlist[0]); + //fi->V(0)->N() += vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); + fi->V(1)->N() += vcg::Point3f(normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 2]); + + //++fi->V(1)->incidentfaces; + } + + if (isvalidtext) + { + for(unsigned int hh = 0; hh < tet.size();++hh) + { + UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(tet[hh]); + fi->WT(1).t(hh) = vcg::Point2f(tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2],tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1]); + } + } + + ++ind; + assert(offset + pos->indices[ind] < m.vert.size()); + fi->V(2) = &m.vert[offset + pos->indices[ind]]; + + if (isvalidnorm) + { + //assert(norm->indices[ind] * 3 < norm->source->GetSourceData().size()); + //fi->V(2)->N() += vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); + UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(normlist[0]); + //fi->V(0)->N() += vcg::Point3f(norm->source->GetSourceData()[norm->indices[ind] * 3],norm->source->GetSourceData()[norm->indices[ind] * 3 + 1],norm->source->GetSourceData()[norm->indices[ind] * 3 + 2]).Normalize(); + fi->V(2)->N() += vcg::Point3f(normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1],normlist[0]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 2]); + //++fi->V(2)->incidentfaces; + } + + if (isvalidtext) + { + for(unsigned int hh = 0; hh < tet.size();++hh) + { + UInt32List* ls = tmp->GetPolygons(pset)->FindIndices(tet[hh]); + fi->WT(2).t(hh) = vcg::Point2f(tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2],tet[hh]->GetSource()->GetSourceData()[(*ls)[ind] * 2 + 1]); + } + } + + if (isvalidnorm) fi->N() = ((fi->V(1)->P() - fi->V(0)->P()) ^ (fi->V(2)->P() - fi->V(0)->P())).Normalize(); + + /*FCDGeometryPolygonsInput* posa = tmp->GetPolygons(pset)->FindInput(FUDaeGeometryInput::POSITION); + FloatList& list = posa->source->GetSourceData(); + int dim = list.size(); + list[0] = -100.0;*/ + } + //vm.push_back(msh); + + if (isvalidnorm) + { + vcg::tri::UpdateNormals::PerVertexNormalized(m); + /*for(MyMesh::VertexIterator vit = msh->vert.begin(); vit != msh->vert.end();++vit) + vit->N() = (vit->N() / vit->incidentfaces).Normalize();*/ + } + } + } + } + } + + //doc->WriteToFile("PincoPalla.dae"); + return E_NOERROR; + } }; }