diff --git a/wrap/io_trimesh/import_dae.h b/wrap/io_trimesh/import_dae.h index 19e6377f..56c853cc 100644 --- a/wrap/io_trimesh/import_dae.h +++ b/wrap/io_trimesh/import_dae.h @@ -3,21 +3,17 @@ //importer for collada's files -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -//#include #include #include #include +#include + +#include +#include +#include + +#include +#include //#include @@ -44,7 +40,7 @@ namespace io { texturefile.clear(); } - FCDocument* doc; + QDomDocument* doc; std::vector texturefile; }; @@ -64,588 +60,1231 @@ namespace io { } }; -template -class ImporterDAE -{ - - -public: - - //merge all meshes in the collada's file in the templeted mesh m - //I assume the mesh - - enum DAEError + template + class ImporterDAE { - E_NOERROR, // 0 - E_CANTOPEN, // 1 - E_NOGEOMETRYLIBRARY, // 2 - E_NOMESH, // 3 - E_NOVERTEXPOSITION, // 4 - E_NO3DVERTEXPOSITION // 5 - }; - static const char *ErrorMsg(int error) - { - static const char * dae_error_msg[] = + + public: + + //merge all meshes in the collada's file in the templeted mesh m + //I assume the mesh + + enum DAEError { - "No errors", - "Can't open file", - "File without a geometry library", - "There isn't mesh in file", - "The meshes in file haven't the vertex position attribute", - "The importer assumes that the OpenMeshType uses a 3D point for the vertex position" + E_NOERROR, // 0 + E_CANTOPEN, // 1 + E_NOGEOMETRYLIBRARY, // 2 + E_NOMESH, // 3 + E_NOVERTEXPOSITION, // 4 + E_NO3DVERTEXPOSITION, // 5 + E_NO3DSCENE, // 6 + E_INCOMPATIBLECOLLADA141FORMAT, //7 + E_UNREFERENCEBLEDCOLLADAATTRIBUTE, // 8 + E_NOTRIANGLES }; - if(error>5 || error<0) return "Unknown error"; - else return dae_error_msg[error]; - }; - - 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()) + static const char *ErrorMsg(int error) { - delete doc; - doc = NULL; - return E_CANTOPEN; - } - FCDGeometryLibrary* geolib = doc->GetGeometryLibrary(); - if (geolib->IsEmpty()) - { - delete doc; - 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()) + static const char * dae_error_msg[] = { - delete doc; - return E_NOMESH; + "No errors", + "Can't open file", + "File without a geometry library", + "There isn't mesh in file", + "The meshes in file haven't the vertex position attribute", + "The importer assumes that the OpenMeshType uses a 3D point for the vertex position", + "There isn't any scene in Collada file", + "The input file is not compatible with COLLADA 1.41 standard format", + "Collada file is trying to referece an attribute that is not in the file", + "This version of Collada Importer support only triangular mesh file" + }; + + if(error>5 || error<0) return "Unknown error"; + else return dae_error_msg[error]; + }; + + //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()) + // { + // delete doc; + // doc = NULL; + // return E_CANTOPEN; + // } + // FCDGeometryLibrary* geolib = doc->GetGeometryLibrary(); + // if (geolib->IsEmpty()) + // { + // delete doc; + // 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; + // return E_NOMESH; + // } + // else + // { + // geomsh[ii] = geolib->GetEntity(ii)->GetMesh(); + // unsigned int offset = m.vert.size(); + // if (geomsh[ii]->GetFaceCount() > 0) + // { + // geomsh[ii]->Triangulate(); + // /*std::vector< std::vector > vt(m.face.size()); + // for(std::vector< std::vector >::iterator + // HGRD::Triangulate(*/ + // + // //geomsh[ii]->Get + // 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) + // { + // typename 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; + // return E_NOVERTEXPOSITION; + // } + + // //a single mesh may be composed by a variable numbers of polygons' subsets + // size_t pol = geomsh[ii]->GetPolygonsCount(); + + // //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; + // 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) + // { + // typename OpenMeshType::FaceIterator fi=vcg::tri::Allocator::AddFaces(m,1); + // assert(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(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(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"); + // 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,AdditionalInfo*& addinfo) + //{ + // AdditionalInfoDAE* inf = new AdditionalInfoDAE(); + // inf->dae = new InfoDAE(); + // InfoDAE* info = inf->dae; + // info->doc = new FCDocument(); + + // FUStatus st = info->doc->LoadFromFile(FUStringConversion::ToFString(filename)); + // if (st.IsFailure()) + // { + // delete info->doc; + // info->doc = NULL; + // return E_CANTOPEN; + // } + + // FCDGeometryLibrary* geolib = info->doc->GetGeometryLibrary(); + // if (geolib->IsEmpty()) return E_NOGEOMETRYLIBRARY; + // size_t n = geolib->GetEntityCount(); + // std::vector geomsh(n); + // + + // //it tests if there is at least a mesh in the collada file + // bool amesh = false; + + // //for any mesh in the collada file + // for(unsigned int ii = 0;ii < geomsh.size();++ii) + // { + // if (!geolib->GetEntity(ii)->IsMesh()) + // { + // amesh |= false; + // } + // else + // { + // amesh |= true; + // 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 info->doc; + // info->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 info->doc; + // info->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); + // + // //m.Enable( + + // if (isvalidtext) + // { + // FCDImageLibrary* imlib = NULL; + // imlib = info->doc->GetImageLibrary(); + // + // if (imlib != NULL) + // { + // info->texturefile.resize(imlib->GetEntityCount()); + // for(unsigned int gg = 0;gg < imlib->GetEntityCount();++gg) + // { + // FCDImage* img = imlib->GetEntity(gg); + // info->texturefile[gg] = FUStringConversion::ToString(img->GetFilename()); + // } + // } + // } + + // 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();*/ + // } + // } + // } + // } + // } + + // addinfo = inf; + // if (!amesh) + // { + // delete info->doc; + // info->doc = NULL; + // return E_NOMESH; + // } + // //doc->WriteToFile("PincoPalla.dae"); + // return E_NOERROR; + //} + + //static int Open(OpenMeshType& m,const char* filename,AdditionalInfo*& addinfo) + //{ + // AdditionalInfoDAE* inf = new AdditionalInfoDAE(); + // inf->dae = new InfoDAE(); + // InfoDAE* info = inf->dae; + // info->doc = new FCDocument(); + + // FUStatus st = info->doc->LoadFromFile(FUStringConversion::ToFString(filename)); + // if (st.IsFailure()) + // { + // delete info->doc; + // info->doc = NULL; + // return E_CANTOPEN; + // } + + // FCDGeometryLibrary* geolib = info->doc->GetGeometryLibrary(); + // if (geolib->IsEmpty()) return E_NOGEOMETRYLIBRARY; + // size_t n = geolib->GetEntityCount(); + // std::vector geomsh(n); + // + + // //it tests if there is at least a mesh in the collada file + // bool amesh = false; + + // //for any mesh in the collada file + // for(unsigned int ii = 0;ii < geomsh.size();++ii) + // { + // if (!geolib->GetEntity(ii)->IsMesh()) + // { + // amesh |= false; + // } + // else + // { + // amesh |= true; + // 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 info->doc; + // info->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 info->doc; + // info->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); + // + // //m.Enable( + + // if (isvalidtext) + // { + // FCDImageLibrary* imlib = NULL; + // imlib = info->doc->GetImageLibrary(); + // + // if (imlib != NULL) + // { + // info->texturefile.resize(imlib->GetEntityCount()); + // for(unsigned int gg = 0;gg < imlib->GetEntityCount();++gg) + // { + // FCDImage* img = imlib->GetEntity(gg); + // info->texturefile[gg] = FUStringConversion::ToString(img->GetFilename()); + // } + // } + // } + + // 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();*/ + // } + // } + // } + // } + // } + + // addinfo = inf; + // if (!amesh) + // { + // delete info->doc; + // info->doc = NULL; + // return E_NOMESH; + // } + // //doc->WriteToFile("PincoPalla.dae"); + // return E_NOERROR; + //} + + private: + enum VERT_SEMANTIC {V_POSITION = 0, V_NORMAL, V_TEXTURE, V_COLOR,V_INVALID_TOKEN}; + + enum FACE_SEMANTIC {F_VERTEX = 0, F_NORMAL, F_TEXTURE, F_COLOR, F_INVALID_TOKEN}; + + struct PolySet + { + QDomNode tessel; + std::vector > attr; + }; + + typedef std::pair VertSemSource; + + typedef std::pair AccessGeoInfo; + + static const VERT_SEMANTIC convertVertSemantic(const QString& sem) + { + if (sem == "POSITION") return V_POSITION; + else + if (sem == "NORMAL") return V_NORMAL; + else + if (sem == "TEXTURE") return V_TEXTURE; + else if (sem == "COLOR") return V_COLOR; + return V_INVALID_TOKEN; + } + + static const FACE_SEMANTIC convertFaceSemantic(const QString& sem) + { + if (sem == "VERTEX") return F_VERTEX; + else + if (sem == "NORMAL") return F_NORMAL; + else + if (sem == "TEXTURE") return F_TEXTURE; + else if (sem == "COLOR") return F_COLOR; + return F_INVALID_TOKEN; + } + + inline static const int posSemAttrInAttrArray(const std::vector >& arr,const FACE_SEMANTIC fs) + { + for(int ii = 0;ii < arr.size();++ii) + if (arr[ii].first == fs) return ii; + return -1; + } + + inline static void split(QStringList& tess,const QString& st,const char c) + { + tess = st.split(c); + if (tess.last() == "") tess.removeLast(); + } + + inline static void referenceToANodeAttribute(const QDomNode& n,const QString& attr,QString& url_st) + { + url_st = n.toElement().attribute(attr); + int sz = url_st.size() - 1; + url_st = url_st.right(sz); + assert(url_st.size() != 0); + } + + inline static QDomNode findNodeBySpecificAttributeValue(const QDomNode& n,const QString& tag,const QString& attrname,const QString& attrvalue) + { + QDomNode ndl = n.toElement(); + return findNodeBySpecificAttributeValue((QDomDocument&) ndl,tag,attrname,attrvalue); + } + + inline static QDomNode findNodeBySpecificAttributeValue(const QDomDocument& n,const QString& tag,const QString& attrname,const QString& attrvalue) + { + QDomNodeList ndl = n.elementsByTagName(tag); + int ndl_size = ndl.size(); + assert(ndl_size != 0); + int ind = 0; + while(ind < ndl_size) + { + if (ndl.at(ind).toElement().attribute(attrname) == attrvalue) + return ndl.at(ind); + ++ind; } - else + return QDomNode(); + } + + inline static bool isThereTag(const QDomNode& n,const QString& tagname) + { + QDomNode ndl = n.toElement(); + return isThereTag((QDomDocument&) n,tagname); + } + + inline static bool isThereTag(const QDomDocument& n,const QString& tagname) + { + return ((n.toElement().elementsByTagName(tagname).size() > 0)? true : false); + } + + + inline static QDomNode attributeSourcePerSimplex(const QDomNode& n,const QDomDocument& startpoint,const QString& sem) + { + QDomNodeList vertattr = n.toElement().elementsByTagName("input"); + for(int ind = 0;ind < vertattr.size();++ind) { - geomsh[ii] = geolib->GetEntity(ii)->GetMesh(); - unsigned int offset = m.vert.size(); - if (geomsh[ii]->GetFaceCount() > 0) + if (vertattr.at(ind).toElement().attribute("semantic") == sem) { - geomsh[ii]->Triangulate(); - /*std::vector< std::vector > vt(m.face.size()); - for(std::vector< std::vector >::iterator - HGRD::Triangulate(*/ + QString url; + referenceToANodeAttribute(vertattr.at(ind),"source",url); + return findNodeBySpecificAttributeValue(startpoint,"source","id",url); + } + } + return QDomNode(); + } + + inline static void valueStringList(QStringList& res,const QDomNode& srcnode,const QString& tag) + { + QDomNodeList list = srcnode.toElement().elementsByTagName(tag); + int list_size = list.size(); + assert(list_size == 1); + QString nd = list.at(0).firstChild().nodeValue(); + res = nd.split(" "); + if (res.last() == "") + res.removeLast(); + + } + + public: + static int Open(OpenMeshType& m,const char* filename,AdditionalInfo*& addinfo) + { + AdditionalInfoDAE* inf = new AdditionalInfoDAE(); + inf->dae = new InfoDAE(); + InfoDAE* info = inf->dae; + + QDomDocument* doc = new QDomDocument(filename); + QFile file(filename); + if (!file.open(QIODevice::ReadOnly)) + return E_CANTOPEN; + if (!doc->setContent(&file)) + { + file.close(); + return E_CANTOPEN; + } + file.close(); + + info->doc = doc; + QDomNodeList& scenes = info->doc->elementsByTagName("scene"); + int scn_size = scenes.size(); + if (scn_size == 0) + return E_NO3DSCENE; + + //Is there geometry in the file? + bool geoinst_found = false; + //for each scene in COLLADA FILE + for(int scn = 0;scn < scn_size;++scn) + { + QDomNodeList& instscenes = scenes.at(scn).toElement().elementsByTagName("instance_visual_scene"); + int instscn_size = instscenes.size(); + if (instscn_size == 0) + return E_INCOMPATIBLECOLLADA141FORMAT; + + //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; - //geomsh[ii]->Get - 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) + //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 + for(int chdind = 0; chdind < visscn_child.size();++chdind) { - FloatList& flst = src->GetSourceData(); - unsigned int str = src->GetSourceStride(); - assert(flst.size() % str == 0); - for(unsigned int cont = 0;cont < flst.size();cont += str) + QDomNodeList& geoinst = visscn_child.at(chdind).toElement().elementsByTagName("instance_geometry"); + int geoinst_size = geoinst.size(); + if (geoinst_size != 0) { - typename 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; - return E_NOVERTEXPOSITION; - } - - //a single mesh may be composed by a variable numbers of polygons' subsets - size_t pol = geomsh[ii]->GetPolygonsCount(); - - //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; - 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) - { - typename OpenMeshType::FaceIterator fi=vcg::tri::Allocator::AddFaces(m,1); - assert(pos->indices[ind] < m.vert.size()); - fi->V(0) = &m.vert[offset + pos->indices[ind]]; - - size_t dimn = norm->indices.size(); - if (isvalidnorm) + 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!!!!!!!!!!!!!!!!!!!!!! + for(int geoinst_ind = 0;geoinst_ind < geoinst_size;++geoinst_ind) { - //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; - } + QString geo_url; + referenceToANodeAttribute(geoinst.at(geoinst_ind),"url",geo_url); - if (isvalidtext) - { - for(unsigned int hh = 0; hh < tet.size();++hh) + QDomNode geo = findNodeBySpecificAttributeValue(geolib.at(0),"geometry","id",geo_url); + if (geo.isNull()) + return E_UNREFERENCEBLEDCOLLADAATTRIBUTE; + + + if (isThereTag(geo,"mesh")) { - //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]); - } - } + /*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; - 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(); - } + 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); - ++ind; - assert(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; - } + QDomNode srcnodenorm = attributeSourcePerSimplex(vertices.at(0),*(info->doc),"NORMAL"); + QStringList geosrcvertnorm; + if (!srcnodenorm.isNull()) + valueStringList(geosrcvertnorm,srcnodenorm,"float_array"); - 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]); - } - } + QDomNode srcnodetext = attributeSourcePerSimplex(vertices.at(0),*(info->doc),"TEXCOORD"); + QStringList geosrcverttext; + if (!srcnodetext.isNull()) + valueStringList(geosrcverttext,srcnodetext,"float_array"); - ++ind; - assert(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]); - } - } + 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::Color4(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; - if (isvalidnorm) fi->N() = ((fi->V(1)->P() - fi->V(0)->P()) ^ (fi->V(2)->P() - fi->V(0)->P())).Normalize(); + for(int tript = 0; tript < tripatch_size;++tript) + { + + int nfcatt = tripatch.at(tript).toElement().elementsByTagName("input").size(); - /*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();*/ + QStringList face; + valueStringList(face,tripatch.at(tript),"p"); + int face_size = face.size(); + int offsetface = (int)m.face.size(); + 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; + + } + } + } + } } } } } + + if (!geoinst_found) + return E_NOGEOMETRYLIBRARY; + return E_NOERROR; } - //doc->WriteToFile("PincoPalla.dae"); - 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,AdditionalInfo*& addinfo) - { - AdditionalInfoDAE* inf = new AdditionalInfoDAE(); - inf->dae = new InfoDAE(); - InfoDAE* info = inf->dae; - info->doc = new FCDocument(); - - FUStatus st = info->doc->LoadFromFile(FUStringConversion::ToFString(filename)); - if (st.IsFailure()) + static bool LoadMask(const char * filename, AdditionalInfoDAE &addinfo) { - delete info->doc; - info->doc = NULL; - return E_CANTOPEN; - } + std::ifstream stream(filename); + if (stream.fail()) + return false; - FCDGeometryLibrary* geolib = info->doc->GetGeometryLibrary(); - if (geolib->IsEmpty()) return E_NOGEOMETRYLIBRARY; - size_t n = geolib->GetEntityCount(); - std::vector geomsh(n); - + stream.seekg (0, std::ios::end); + int length = stream.tellg(); + if (length == 0) return false; + stream.seekg (0, std::ios::beg); - //it tests if there is at least a mesh in the collada file - bool amesh = false; + bool bHasPerWedgeTexCoord = false; + bool bHasPerWedgeNormal = false; + bool bUsingMaterial = false; + bool bHasPerVertexColor = false; + bool bHasPerFaceColor = false; - //for any mesh in the collada file - for(unsigned int ii = 0;ii < geomsh.size();++ii) - { - if (!geolib->GetEntity(ii)->IsMesh()) + 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()) { - amesh |= false; + delete info->doc; + info->doc = NULL; + return false; } - else + + bool amesh = false; + + //for any mesh in the collada file + for(unsigned int ii = 0;ii < geomsh.size();++ii) { - amesh |= true; - geomsh[ii] = geolib->GetEntity(ii)->GetMesh(); - unsigned int offset = m.vert.size(); - if (geomsh[ii]->GetFaceCount() > 0) + if (!geolib->GetEntity(ii)->IsMesh()) { - 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 info->doc; - info->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 info->doc; - info->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); - - //m.Enable( - - if (isvalidtext) - { - FCDImageLibrary* imlib = NULL; - imlib = info->doc->GetImageLibrary(); - - if (imlib != NULL) - { - info->texturefile.resize(imlib->GetEntityCount()); - for(unsigned int gg = 0;gg < imlib->GetEntityCount();++gg) - { - FCDImage* img = imlib->GetEntity(gg); - info->texturefile[gg] = FUStringConversion::ToString(img->GetFilename()); - } - } - } - - 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();*/ - } - } + amesh |= false; } - } - } - - addinfo = inf; - if (!amesh) - { - delete info->doc; - info->doc = NULL; - return E_NOMESH; - } - //doc->WriteToFile("PincoPalla.dae"); - return E_NOERROR; - } - - 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; - - 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()) - { - delete info->doc; - info->doc = NULL; - return false; - } - - bool amesh = false; - - //for any mesh in the collada file - for(unsigned int ii = 0;ii < geomsh.size();++ii) - { - if (!geolib->GetEntity(ii)->IsMesh()) - { - amesh |= false; - } - else - { - amesh |= true; - geomsh[ii] = geolib->GetEntity(ii)->GetMesh(); - - unsigned int ver; - if (geomsh[ii]->GetFaceCount() > 0) + else { - 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); - ver = flst.size() / str; - numvert += flst.size() / str; - } - else - { - delete info->doc; - info->doc = NULL; - return false; - } + amesh |= true; + geomsh[ii] = geolib->GetEntity(ii)->GetMesh(); - size_t pol = geomsh[ii]->GetPolygonsCount(); - - for(unsigned int pset = 0; pset < pol;++pset) + unsigned int ver; + if (geomsh[ii]->GetFaceCount() > 0) { - FCDGeometryMesh* tmp = geomsh[ii]; - FCDGeometryPolygonsInput* pos = tmp->GetPolygons(pset)->FindInput(FUDaeGeometryInput::POSITION); - if ((pos == NULL) || (pos->GetSource()->GetSourceStride() != 3)) + 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); + ver = flst.size() / str; + numvert += flst.size() / str; + } + else { delete info->doc; info->doc = NULL; return false; } - //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; + 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)) + { + delete info->doc; + info->doc = NULL; + return false; + } + //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; + return true; } - inf.nvert = - addinfo = inf; - return true; - } }; } }