From 45f74840d23663d9407bb3b3ee7dd039cd62ef2f Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Wed, 24 Apr 2013 17:38:14 +0200 Subject: [PATCH] update Volumic I/O --- include/Algo/Export/exportVol.h | 12 + include/Algo/Export/exportVol.hpp | 432 +++++++++++++++++++- include/Algo/Import/import.h | 11 +- include/Algo/Import/import2tables.h | 2 +- include/Algo/Import/importMSH.hpp | 478 ++++++++++++++++++++++ include/Algo/Import/importMesh.hpp | 18 + include/Algo/Import/importNodeEle.hpp | 83 ++-- include/Algo/Import/importObjTex.h | 28 +- include/Algo/Import/importObjTex.hpp | 54 ++- include/Algo/Import/importTet.hpp | 30 +- include/Algo/Import/importTs.hpp | 14 +- include/Algo/Import/importVTU.hpp | 553 ++++++++++++++++++++++++++ 12 files changed, 1648 insertions(+), 67 deletions(-) create mode 100644 include/Algo/Import/importMSH.hpp create mode 100644 include/Algo/Import/importVTU.hpp diff --git a/include/Algo/Export/exportVol.h b/include/Algo/Export/exportVol.h index f1522a62b..64192a010 100644 --- a/include/Algo/Export/exportVol.h +++ b/include/Algo/Export/exportVol.h @@ -52,6 +52,18 @@ template bool exportNAS(typename PFP::MAP& map, const VertexAttribute& position, const char* filename) ; +/** +* export the map into a vtu file (vtk unstructured grid) +* @param the_map map to be exported +* @param position the position container +* @param filename filename of ply file +* @param binary write in binary mode +* @return true +*/ +template +bool exportVTU(typename PFP::MAP& map, const VertexAttribute& position, const char* filename) ; + + /** * export the map into a .msh (gmesh file) * @param the_map map to be exported diff --git a/include/Algo/Export/exportVol.hpp b/include/Algo/Export/exportVol.hpp index 582d4c2ed..4d6603fbc 100644 --- a/include/Algo/Export/exportVol.hpp +++ b/include/Algo/Export/exportVol.hpp @@ -111,13 +111,6 @@ bool exportNAS(typename PFP::MAP& map, const VertexAttribute //CAS HEXAEDRIQUE (ordre 2 quad superposes, le premier en CCW) Dart e = d; Dart f = map.template phi<21121>(d); - hexa.push_back(indices[e]); - e = map.phi1(e); - hexa.push_back(indices[e]); - e = map.phi1(e); - hexa.push_back(indices[e]); - e = map.phi1(e); - hexa.push_back(indices[e]); hexa.push_back(indices[f]); e = map.phi_1(f); hexa.push_back(indices[f]); @@ -125,11 +118,18 @@ bool exportNAS(typename PFP::MAP& map, const VertexAttribute hexa.push_back(indices[f]); e = map.phi_1(f); hexa.push_back(indices[f]); + hexa.push_back(indices[e]); + e = map.phi1(e); + hexa.push_back(indices[e]); + e = map.phi1(e); + hexa.push_back(indices[e]); + e = map.phi1(e); + hexa.push_back(indices[e]); } if (degree == 4) { - //CAS HEXAEDRIQUE (ordre 2 quad superposes, le premier en CCW) + //CAS TETRAEDRIQUE (ordre 2 quad superposes, le premier en CCW) Dart e = d; tetra.push_back(indices[e]); e = map.phi1(e); @@ -145,8 +145,6 @@ bool exportNAS(typename PFP::MAP& map, const VertexAttribute unsigned int nbhexa = hexa.size()/8; unsigned int nbtetra = tetra.size()/4; - - fout << std::right; if (nbhexa!=0) { @@ -158,7 +156,7 @@ bool exportNAS(typename PFP::MAP& map, const VertexAttribute fout << "CHEXA "; fout << std::setw(8) << countCell++ << std::setw(8)<< 0; fout << std::setw(8) << hexa[8*i] << std::setw(8) << hexa[8*i+1] << std::setw(8) << hexa[8*i+2]; - fout << std::setw(8) << hexa[8*i+3] << std::setw(8) << hexa[8*i+4] << std::setw(8) << hexa[8*i+6] << "+"<< std::endl; + fout << std::setw(8) << hexa[8*i+3] << std::setw(8) << hexa[8*i+4] << std::setw(8) << hexa[8*i+5] << "+"<< std::endl; fout << "+ " << std::setw(8) << hexa[8*i+6] << std::setw(8) << hexa[8*i+7] << std::endl; } } @@ -177,10 +175,173 @@ bool exportNAS(typename PFP::MAP& map, const VertexAttribute } fout << "ENDDATA" << std::endl; + + fout.close(); return true; } + +template +bool exportVTU(typename PFP::MAP& map, const VertexAttribute& position, const char* filename) +{ + typedef typename PFP::MAP MAP; + typedef typename PFP::VEC3 VEC3; + + // open file + std::ofstream fout ; + fout.open(filename, std::ios::out) ; + + if (!fout.good()) + { + CGoGNerr << "Unable to open file " << filename << CGoGNendl ; + return false ; + } + + VertexAutoAttribute indices(map,"indices_vert"); + + + + + unsigned int count=0; + for (unsigned int i = position.begin(); i != position.end(); position.next(i)) + { + indices[i] = count++; + } + + + std::vector hexa; + std::vector tetra; + hexa.reserve(2048); + tetra.reserve(2048); + + TraversorW trav(map) ; + for(Dart d = trav.begin(); d != trav.end(); d = trav.next()) + { + unsigned int degree = 0 ; + + Traversor3WV twv(map, d) ; + for(Dart it = twv.begin(); it != twv.end(); it = twv.next()) + { + degree++; + } + + if (degree == 8) + { + //CAS HEXAEDRIQUE (ordre 2 quad superposes, le premier en CW) + Dart e = d; + Dart f = map.template phi<21121>(d); + hexa.push_back(indices[f]); + f = map.phi_1(f); + hexa.push_back(indices[f]); + f = map.phi_1(f); + hexa.push_back(indices[f]); + f = map.phi_1(f); + hexa.push_back(indices[f]); + hexa.push_back(indices[e]); + e = map.phi1(e); + hexa.push_back(indices[e]); + e = map.phi1(e); + hexa.push_back(indices[e]); + e = map.phi1(e); + hexa.push_back(indices[e]); + } + + if (degree == 4) + { + //CAS TETRAEDRIQUE + Dart e = d; + tetra.push_back(indices[e]); + e = map.phi1(e); + tetra.push_back(indices[e]); + e = map.phi1(e); + tetra.push_back(indices[e]); + e = map.template phi<211>(e); + tetra.push_back(indices[e]); + } + } + + unsigned int nbhexa = hexa.size()/8; + unsigned int nbtetra = tetra.size()/4; + + + fout << "" << std::endl; + fout << "" << std::endl; + fout << " " << std::endl; + fout << " " << std::endl; + fout << " " << std::endl; + fout << " " << std::endl; + + for (unsigned int i = position.begin(); i != position.end(); position.next(i)) + { + const VEC3& P = position[i]; + fout << " " << P[0]<< " " << P[1]<< " " << P[2] << std::endl; + } + + fout << " " << std::endl; + fout << " " << std::endl; + fout << " " << std::endl; + fout << " " << std::endl; + + if (nbhexa!=0) + { + for (unsigned int i=0; i" << std::endl; + fout << " " << std::endl; + fout << " "; + unsigned int offset = 0; + for (unsigned int i=0; i" << std::endl; + fout << " " << std::endl; + fout << " "; + for (unsigned int i=0; i" << std::endl; + fout << " " << std::endl; + fout << " " << std::endl; + fout << " " << std::endl; + fout << "" << std::endl; + + fout.close(); + return true; +} + + + template bool exportMSH(typename PFP::MAP& map, const VertexAttribute& position, const char* filename) { @@ -196,6 +357,104 @@ bool exportMSH(typename PFP::MAP& map, const VertexAttribute CGoGNerr << "Unable to open file " << filename << CGoGNendl ; return false ; } + + VertexAutoAttribute indices(map,"indices_vert"); + + fout << "$NOD" << std::endl; + fout << position.nbElements()<< std::endl; + unsigned int count=1; + for (unsigned int i = position.begin(); i != position.end(); position.next(i)) + { + const VEC3& P = position[i]; + fout << count << " " << P[0]<< " " << P[1]<< " " << P[2] << std::endl; + indices[i] = count++; + } + + + std::vector hexa; + std::vector tetra; + hexa.reserve(2048); + tetra.reserve(2048); + + TraversorW trav(map) ; + for(Dart d = trav.begin(); d != trav.end(); d = trav.next()) + { + unsigned int degree = 0 ; + + Traversor3WV twv(map, d) ; + for(Dart it = twv.begin(); it != twv.end(); it = twv.next()) + { + degree++; + } + + if (degree == 8) + { + //CAS HEXAEDRIQUE (ordre 2 quad superposes, le premier en CW) + Dart e = d; + Dart f = map.template phi<21121>(d); + hexa.push_back(indices[f]); + f = map.phi_1(f); + hexa.push_back(indices[f]); + f = map.phi_1(f); + hexa.push_back(indices[f]); + f = map.phi_1(f); + hexa.push_back(indices[f]); + hexa.push_back(indices[e]); + e = map.phi1(e); + hexa.push_back(indices[e]); + e = map.phi1(e); + hexa.push_back(indices[e]); + e = map.phi1(e); + hexa.push_back(indices[e]); + } + + if (degree == 4) + { + //CAS TETRAEDRIQUE + Dart e = d; + tetra.push_back(indices[e]); + e = map.phi1(e); + tetra.push_back(indices[e]); + e = map.phi1(e); + tetra.push_back(indices[e]); + e = map.template phi<211>(e); + tetra.push_back(indices[e]); + } + } + + fout << "$ENDNOD" << std::endl; + fout << "$ELM" << std::endl; + + unsigned int countCell=1; + unsigned int nbhexa = hexa.size()/8; + unsigned int nbtetra = tetra.size()/4; + + fout << (nbhexa+nbtetra) << std::endl; + if (nbhexa!=0) + { + for (unsigned int i=0; i CGoGNerr << "Unable to open file " << filename << CGoGNendl ; return false ; } + + VertexAutoAttribute indices(map,"indices_vert"); + + fout << position.nbElements()<< " vertices" < tetra; + tetra.reserve(2048); + + + unsigned int count=0; + for (unsigned int i = position.begin(); i != position.end(); position.next(i)) + { + indices[i] = count++; + } + + TraversorW trav(map) ; + for(Dart d = trav.begin(); d != trav.end(); d = trav.next()) + { + unsigned int degree = 0 ; + + Traversor3WV twv(map, d) ; + for(Dart it = twv.begin(); it != twv.end(); it = twv.next()) + { + degree++; + } + + if (degree == 4) + { + Dart e = d; + tetra.push_back(indices[e]); + e = map.phi_1(e); + tetra.push_back(indices[e]); + e = map.phi_1(e); + tetra.push_back(indices[e]); + e = map.template phi<211>(e); + tetra.push_back(indices[e]); + } + } + + unsigned int nbtetra = tetra.size()/4; + fout << nbtetra << " tets" << std::endl; + + for (unsigned int i = position.begin(); i != position.end(); position.next(i)) + { + const VEC3& P = position[i]; + fout << P[0]<< " " << P[1]<< " " << P[2] << std::endl; + } + + for (unsigned int i=0; i indices(map,"indices_vert"); + + fout << position.nbElements()<< " 3 0 0"< hexa; + std::vector tetra; + hexa.reserve(2048); + tetra.reserve(2048); + + TraversorW trav(map) ; + for(Dart d = trav.begin(); d != trav.end(); d = trav.next()) + { + unsigned int degree = 0 ; + + Traversor3WV twv(map, d) ; + for(Dart it = twv.begin(); it != twv.end(); it = twv.next()) + { + degree++; + } + +// if (degree == 8) +// { +// //CAS HEXAEDRIQUE (ordre 2 quad superposes, le premier en CW) +// Dart e = d; +// Dart f = map.template phi<21121>(d); +// hexa.push_back(indices[f]); +// e = map.phi_1(f); +// hexa.push_back(indices[f]); +// e = map.phi_1(f); +// hexa.push_back(indices[f]); +// e = map.phi_1(f); +// hexa.push_back(indices[f]); +// hexa.push_back(indices[e]); +// e = map.phi1(e); +// hexa.push_back(indices[e]); +// e = map.phi1(e); +// hexa.push_back(indices[e]); +// e = map.phi1(e); +// hexa.push_back(indices[e]); +// } + + if (degree == 4) + { + //CAS TETRAEDRIQUE + Dart e = d; + tetra.push_back(indices[e]); + e = map.phi1(e); + tetra.push_back(indices[e]); + e = map.phi1(e); + tetra.push_back(indices[e]); + e = map.template phi<211>(e); + tetra.push_back(indices[e]); + } + } + + unsigned int countCell=0; + unsigned int nbtetra = tetra.size()/4; + + foutEle << nbtetra << " 4 0" << std::endl; + + if (nbtetra != 0) + { + + for (unsigned int i=0; i bool importNodeWithELERegions(typename PFP::MAP& map, const std::string& filenameNode, const std::string& filenameELE, std::vector& attrNames); template -bool importTet(typename PFP::MAP& the_map, const std::string& filename, std::vector& attrNames, float scaleFactor = 1.0f, bool invertTetra=false); +bool importTet(typename PFP::MAP& the_map, const std::string& filename, std::vector& attrNames, float scaleFactor = 1.0f); template bool importMoka(typename PFP::MAP& the_gmap, const std::string& filename, std::vector& attrNames); @@ -118,6 +118,13 @@ bool importMoka(typename PFP::MAP& the_gmap, const std::string& filename, std::v template bool importTs(typename PFP::MAP& the_map, const std::string& filename, std::vector& attrNames, float scaleFactor = 1.0f); +template +bool importMSH(typename PFP::MAP& the_map, const std::string& filename, std::vector& attrNames, float scaleFactor = 1.0f); + +template +bool importVTU(typename PFP::MAP& the_map, const std::string& filename, std::vector& attrNames, float scaleFactor = 1.0f); + + } // Import } // Volume @@ -134,6 +141,8 @@ bool importTs(typename PFP::MAP& the_map, const std::string& filename, std::vect #include "Algo/Import/importMoka.hpp" #include "Algo/Import/importTs.hpp" #include "Algo/Import/importNodeEle.hpp" +#include "Algo/Import/importMSH.hpp" +#include "Algo/Import/importVTU.hpp" #include "Algo/Import/importChoupi.hpp" diff --git a/include/Algo/Import/import2tables.h b/include/Algo/Import/import2tables.h index 9e422d689..2676fcfe2 100644 --- a/include/Algo/Import/import2tables.h +++ b/include/Algo/Import/import2tables.h @@ -151,7 +151,7 @@ namespace Volume namespace Import { -enum ImportType { UNKNOWNVOLUME , TET, OFF, TS, MOKA, NODE}; +enum ImportType { UNKNOWNVOLUME , TET, OFF, TS, MOKA, NODE, MSH, VTU, NAS}; template class MeshTablesVolume diff --git a/include/Algo/Import/importMSH.hpp b/include/Algo/Import/importMSH.hpp new file mode 100644 index 000000000..54dee624d --- /dev/null +++ b/include/Algo/Import/importMSH.hpp @@ -0,0 +1,478 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include "Algo/Modelisation/polyhedron.h" +#include "Geometry/orientation.h" +#include + +namespace CGoGN +{ + +namespace Algo +{ + +namespace Volume +{ + +namespace Import +{ + +template +bool importMSH(typename PFP::MAP& map, const std::string& filename, std::vector& attrNames, float scaleFactor) +{ + typedef typename PFP::VEC3 VEC3; + + VertexAttribute position = map.template addAttribute("position") ; + attrNames.push_back(position.name()) ; + + AttributeContainer& container = map.template getAttributeContainer() ; + + unsigned int m_nbVertices = 0, m_nbVolumes = 0; + VertexAutoAttribute< NoMathIONameAttribute< std::vector > > vecDartsPerVertex(map, "incidents"); + + //open file + std::ifstream fp(filename.c_str(), std::ios::in); + if (!fp.good()) + { + CGoGNerr << "Unable to open file " << filename << CGoGNendl; + return false; + } + + std::string ligne; + unsigned int nbv=0; + //read $NODE + std::getline (fp, ligne); + + // reading number of vertices + std::getline (fp, ligne); + std::stringstream oss(ligne); + oss >> nbv; + + + //reading vertices +// std::vector verticesID; + std::map verticesMapID; + + +// verticesID.reserve(nbv); + for(unsigned int i = 0; i < nbv;++i) + { + do + { + std::getline (fp, ligne); + } while (ligne.size() == 0); + + std::stringstream oss(ligne); + unsigned int pipo; + float x,y,z; + oss >> pipo; + oss >> x; + oss >> y; + oss >> z; + // TODO : if required read other vertices attributes here + VEC3 pos(x*scaleFactor,y*scaleFactor,z*scaleFactor); + + unsigned int id = container.insertLine(); + position[id] = pos; + + verticesMapID.insert(std::pair(pipo,id)); +// verticesID.push_back(id); + } + + // ENNODE + std::getline (fp, ligne); + + m_nbVertices = nbv; + + + // ELM + std::getline (fp, ligne); + + // reading number of elements + std::getline (fp, ligne); + unsigned int nbe=0; + std::stringstream oss2(ligne); + oss2 >> nbe; + + std::vector tet; + tet.reserve(1000); + std::vector hexa; + tet.reserve(1000); + + bool invertVol = false; + + for(unsigned int i=0; i> pipo; + fp >> type_elm; + fp >> pipo; + fp >> pipo; + fp >> nb; + + if ((type_elm==4) && (nb==4)) + { + Geom::Vec4ui v; + + // test orientation of first tetra + if (i==0) + { + fp >> v[0]; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + + typename PFP::VEC3 P = position[verticesMapID[v[0]]]; + typename PFP::VEC3 A = position[verticesMapID[v[1]]]; + typename PFP::VEC3 B = position[verticesMapID[v[2]]]; + typename PFP::VEC3 C = position[verticesMapID[v[3]]]; + + if (Geom::testOrientation3D(P,A,B,C) == Geom::OVER) + { + invertVol=true; + unsigned int ui=v[0]; + v[0] = v[3]; + v[3] = v[2]; + v[2] = v[1]; + v[1] = ui; + } + } + else + { + if (invertVol) + { + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + fp >> v[0]; + } + else + { + fp >> v[0]; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + } + } + tet.push_back(v); + } + else + { + if ((type_elm==5) && (nb==8)) + { + std::cout << "HEXA: "<< i << std::endl; + Geom::Vec4ui v; + + if (i==0) + { + unsigned int last; + fp >> v[0]; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + fp >> last; + + typename PFP::VEC3 P = position[verticesMapID[last]]; + typename PFP::VEC3 A = position[verticesMapID[v[0]]]; + typename PFP::VEC3 B = position[verticesMapID[v[1]]]; + typename PFP::VEC3 C = position[verticesMapID[v[2]]]; + + if (Geom::testOrientation3D(P,A,B,C) == Geom::OVER) + { + + invertVol=true; + unsigned int ui = v[3]; + v[3] = v[0]; + v[0] = ui; + ui = v[2]; + v[2] = v[1]; + v[1] = ui; + hexa.push_back(v); + v[3] = last; + fp >> v[2]; + fp >> v[1]; + fp >> v[0]; + hexa.push_back(v); + } + else + { + hexa.push_back(v); + v[0] = last; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + hexa.push_back(v); + } + } + else + { + if (invertVol) + { + fp >> v[3]; + fp >> v[2]; + fp >> v[1]; + fp >> v[0]; + hexa.push_back(v); + fp >> v[3]; + fp >> v[2]; + fp >> v[1]; + fp >> v[0]; + hexa.push_back(v); + + } + else + { + fp >> v[0]; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + hexa.push_back(v); + fp >> v[0]; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + hexa.push_back(v); + } + } + } + else + { + for (unsigned int j=0; j> v; + } + } + } + } + + CGoGNout << "nb points = " << m_nbVertices ; + + + m_nbVolumes = 0; + + DartMarkerNoUnmark m(map) ; + + if (tet.size() > 0) + { + m_nbVolumes += tet.size(); + + //Read and embed all tetrahedrons + for(unsigned int i = 0; i < tet.size() ; ++i) + { + //start one tetra + // Geom::Vec4ui& pt = tet[i]; + Geom::Vec4ui pt; + + pt[0] = tet[i][0]; + pt[1] = tet[i][1]; + pt[2] = tet[i][2]; + pt[3] = tet[i][3]; + + Dart d = Surface::Modelisation::createTetrahedron(map,false); + + + // Embed three "base" vertices + for(unsigned int j = 0 ; j < 3 ; ++j) + { + FunctorSetEmb fsetemb(map, verticesMapID[pt[2-j]]); + map.template foreach_dart_of_orbit(d, fsetemb); + + //store darts per vertices to optimize reconstruction + Dart dd = d; + do + { + m.mark(dd) ; + vecDartsPerVertex[verticesMapID[pt[2-j]]].push_back(dd); + dd = map.phi1(map.phi2(dd)); + } while(dd != d); + + d = map.phi1(d); + } + + //Embed the last "top" vertex + d = map.phi_1(map.phi2(d)); + + FunctorSetEmb fsetemb(map, verticesMapID[pt[3]]); + map.template foreach_dart_of_orbit(d, fsetemb); + + //store darts per vertices to optimize reconstruction + Dart dd = d; + do + { + m.mark(dd) ; + vecDartsPerVertex[verticesMapID[pt[3]]].push_back(dd); + dd = map.phi1(map.phi2(dd)); + } while(dd != d); + + //end of tetra + } + CGoGNout << " / nb tetra = " << tet.size() << CGoGNendl; + + } + + if (hexa.size() > 0) + { + + m_nbVolumes += hexa.size()/2; + + //Read and embed all tetrahedrons + for(unsigned int i = 0; i < hexa.size()/2 ; ++i) + { + // one hexa + Geom::Vec4ui pt; + pt[0] = hexa[2*i][0]; + pt[1] = hexa[2*i][1]; + pt[2] = hexa[2*i][2]; + pt[3] = hexa[2*i][3]; + Geom::Vec4ui ppt; + ppt[0] = hexa[2*i+1][0]; + ppt[1] = hexa[2*i+1][1]; + ppt[2] = hexa[2*i+1][2]; + ppt[3] = hexa[2*i+1][3]; + + Dart d = Surface::Modelisation::createHexahedron(map,false); + + FunctorSetEmb fsetemb(map, verticesMapID[pt[0]]); + + map.template foreach_dart_of_orbit(d, fsetemb); + Dart dd = d; + vecDartsPerVertex[verticesMapID[pt[0]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[0]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[0]]].push_back(dd); m.mark(dd); + + d = map.phi1(d); + fsetemb.changeEmb(verticesMapID[pt[1]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[pt[1]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[1]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[1]]].push_back(dd); m.mark(dd); + + + d = map.phi1(d); + fsetemb.changeEmb(verticesMapID[pt[2]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[pt[2]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[2]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[2]]].push_back(dd); m.mark(dd); + + + d = map.phi1(d); + fsetemb.changeEmb(verticesMapID[pt[3]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[pt[3]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[3]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[3]]].push_back(dd); m.mark(dd); + + d = map.template phi<2112>(d); + fsetemb.changeEmb(verticesMapID[ppt[0]]); + + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[ppt[0]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[0]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[0]]].push_back(dd); m.mark(dd); + + d = map.phi_1(d); + fsetemb.changeEmb(verticesMapID[ppt[1]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[ppt[1]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[1]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[1]]].push_back(dd); m.mark(dd); + + d = map.phi_1(d); + fsetemb.changeEmb(verticesMapID[ppt[2]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[ppt[2]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[2]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[2]]].push_back(dd); m.mark(dd); + + d = map.phi_1(d); + fsetemb.changeEmb(verticesMapID[ppt[3]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[ppt[3]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[3]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[3]]].push_back(dd); m.mark(dd); + + //end of hexa + } + CGoGNout << " / nb hexa = " << hexa.size()/2 << CGoGNendl; + + } + + //Association des phi3 + unsigned int nbBoundaryFaces = 0 ; + for (Dart d = map.begin(); d != map.end(); map.next(d)) + { + if (m.isMarked(d)) + { + std::vector& vec = vecDartsPerVertex[map.phi1(d)]; + + Dart good_dart = NIL; + for(typename std::vector::iterator it = vec.begin(); it != vec.end() && good_dart == NIL; ++it) + { + if(map.template getEmbedding(map.phi1(*it)) == map.template getEmbedding(d) && + map.template getEmbedding(map.phi_1(*it)) == map.template getEmbedding(map.template phi<11>(d))) + { + good_dart = *it ; + } + } + + if (good_dart != NIL) + { + map.sewVolumes(d, good_dart, false); + m.template unmarkOrbit(d); + } + else + { + m.unmarkOrbit(d); + ++nbBoundaryFaces; + } + } + } + + if (nbBoundaryFaces > 0) + { + std::cout << "closing" << std::endl ; + map.closeMap(); + CGoGNout << "Map closed (" << nbBoundaryFaces << " boundary faces)" << CGoGNendl; + } + + fp.close(); + return true; +} + +} // namespace Import + +} + +} // namespace Algo + +} // namespace CGoGN diff --git a/include/Algo/Import/importMesh.hpp b/include/Algo/Import/importMesh.hpp index ce2831f23..75ae6cd97 100644 --- a/include/Algo/Import/importMesh.hpp +++ b/include/Algo/Import/importMesh.hpp @@ -530,11 +530,29 @@ bool importMesh(typename PFP::MAP& map, const std::string& filename, std::vector if ((filename.rfind(".ts") != std::string::npos) || (filename.rfind(".TS") != std::string::npos)) kind = TS; + if ((filename.rfind(".msh") != std::string::npos) || (filename.rfind(".MSH") != std::string::npos)) + kind = MSH; + + if ((filename.rfind(".vtu") != std::string::npos) || (filename.rfind(".VTU") != std::string::npos)) + kind = VTU; + + if ((filename.rfind(".nas") != std::string::npos) || (filename.rfind(".NAS") != std::string::npos)) + kind = NAS; + + switch (kind) { case TET: return importTet(map, filename, attrNames, 1.0f); break; + case MSH: + return importMSH(map, filename, attrNames, 1.0f); + break; + case VTU: + return importVTU(map, filename, attrNames, 1.0f); + break; + + case OFF: { size_t pos = filename.rfind("."); diff --git a/include/Algo/Import/importNodeEle.hpp b/include/Algo/Import/importNodeEle.hpp index e95b846d0..7f8e4dac8 100644 --- a/include/Algo/Import/importNodeEle.hpp +++ b/include/Algo/Import/importNodeEle.hpp @@ -23,6 +23,8 @@ *******************************************************************************/ #include "Algo/Modelisation/polyhedron.h" +#include "Geometry/orientation.h" + #include namespace CGoGN @@ -105,8 +107,10 @@ bool importNodeWithELERegions(typename PFP::MAP& map, const std::string& filenam //Reading vertices //Remaining lines: [point #] [x] [y] [z] [optional attributes] [optional boundary marker] - std::vector verticesID; - verticesID.reserve(m_nbVertices); +// std::vector verticesID; +// verticesID.reserve(m_nbVertices); + + std::map verticesMapID; for(unsigned int i = 0 ; i < m_nbVertices ; ++i) { @@ -130,14 +134,13 @@ bool importNodeWithELERegions(typename PFP::MAP& map, const std::string& filenam unsigned int id = container.insertLine(); position[id] = pos; - verticesID.push_back(id); +// verticesID.push_back(id); + verticesMapID.insert(std::pair(idv,id)); } - std::vector > vecDartPtrEmb; - vecDartPtrEmb.reserve(m_nbVertices); DartMarkerNoUnmark m(map) ; - + bool invertVol=false; //Read and embed tetrahedra TODO for(unsigned i = 0; i < m_nbVolumes ; ++i) { @@ -152,30 +155,52 @@ bool importNodeWithELERegions(typename PFP::MAP& map, const std::string& filenam Dart d = Surface::Modelisation::createTetrahedron(map,false); Geom::Vec4ui pt; -// oss >> pt[0]; -// --(pt[0]); -// oss >> pt[1]; -// --(pt[1]); -// oss >> pt[2]; -// --(pt[2]); -// oss >> pt[3]; -// --(pt[3]); - oss >> pt[1]; - --(pt[1]); - oss >> pt[2]; - --(pt[2]); - oss >> pt[3]; - --(pt[3]); - oss >> pt[0]; - --(pt[0]); - - //regions ? - //oss >> nbe; + + // test orientation of first tetra + if (i==0) + { + oss >> pt[0]; + oss >> pt[1]; + oss >> pt[2]; + oss >> pt[3]; + + typename PFP::VEC3 P = position[verticesMapID[pt[0]]]; + typename PFP::VEC3 A = position[verticesMapID[pt[1]]]; + typename PFP::VEC3 B = position[verticesMapID[pt[2]]]; + typename PFP::VEC3 C = position[verticesMapID[pt[3]]]; + + if (Geom::testOrientation3D(P,A,B,C) == Geom::OVER) + { + invertVol=true; + unsigned int ui=pt[0]; + pt[0] = pt[3]; + pt[3] = pt[2]; + pt[2] = pt[1]; + pt[1] = ui; + } + } + else + { + if (invertVol) + { + oss >> pt[1]; + oss >> pt[2]; + oss >> pt[3]; + oss >> pt[0]; + } + else + { + oss >> pt[0]; + oss >> pt[1]; + oss >> pt[2]; + oss >> pt[3]; + } + } // Embed three vertices for(unsigned int j = 0 ; j < 3 ; ++j) { - FunctorSetEmb fsetemb(map, verticesID[pt[2-j]]); + FunctorSetEmb fsetemb(map, verticesMapID[pt[2-j]]); map.template foreach_dart_of_orbit(d, fsetemb); //store darts per vertices to optimize reconstruction @@ -183,7 +208,7 @@ bool importNodeWithELERegions(typename PFP::MAP& map, const std::string& filenam do { m.mark(dd) ; - vecDartsPerVertex[pt[2-j]].push_back(dd); + vecDartsPerVertex[verticesMapID[pt[2-j]]].push_back(dd); dd = map.phi1(map.phi2(dd)); } while(dd != d); @@ -194,7 +219,7 @@ bool importNodeWithELERegions(typename PFP::MAP& map, const std::string& filenam //Embed the last vertex d = map.phi_1(map.phi2(d)); - FunctorSetEmb fsetemb(map, verticesID[pt[3]]); + FunctorSetEmb fsetemb(map, verticesMapID[pt[3]]); map.template foreach_dart_of_orbit(d, fsetemb); //store darts per vertices to optimize reconstruction @@ -202,7 +227,7 @@ bool importNodeWithELERegions(typename PFP::MAP& map, const std::string& filenam do { m.mark(dd) ; - vecDartsPerVertex[pt[3]].push_back(dd); + vecDartsPerVertex[verticesMapID[pt[3]]].push_back(dd); dd = map.phi1(map.phi2(dd)); } while(dd != d); diff --git a/include/Algo/Import/importObjTex.h b/include/Algo/Import/importObjTex.h index c3e26b23c..ab19c02f2 100644 --- a/include/Algo/Import/importObjTex.h +++ b/include/Algo/Import/importObjTex.h @@ -37,14 +37,24 @@ namespace Import { -struct MaterialOBJ +class MaterialOBJ { +public: + MaterialOBJ():textureDiffuse(NULL){} + ~MaterialOBJ() + { + if (textureDiffuse!=NULL) + delete textureDiffuse; + } + + std::string name; Geom::Vec3f ambiantColor; Geom::Vec3f diffuseColor; Geom::Vec3f specularColor; float shininess; - - // TODO add textures info + Geom::Vec3f transparentFilter; + float transparency; + Utils::Texture<2,Geom::Vec3uc>* textureDiffuse; }; @@ -60,12 +70,16 @@ protected: /// vector of group name std::vector m_groupNames; + std::vector m_groupMaterialNames; + std::vector m_groupMaterialID; + /// vector of material names - std::vector m_materialNames; + std::map m_materialNames; + /// vector of material struct - std::vector m_materials; +// std::vector m_materials; /// read face line with different indices v v/t v//n v/t/n short readObjLine(std::stringstream& oss, std::vector& indices); @@ -136,6 +150,8 @@ public: */ bool import(const std::string& filename, std::vector& attrNames); + + // Faire un handler ? /** * @brief getNormal @@ -176,7 +192,7 @@ public: * @brief read materials from files * @param filename name of file */ - void readMaterials(const std::string& filename); + void readMaterials(const std::string& filename, std::vector& materials); /** * @brief create simple VBO for separated triangles diff --git a/include/Algo/Import/importObjTex.hpp b/include/Algo/Import/importObjTex.hpp index 235a17d5b..36de0bbb7 100644 --- a/include/Algo/Import/importObjTex.hpp +++ b/include/Algo/Import/importObjTex.hpp @@ -36,6 +36,7 @@ namespace Surface namespace Import { + template OBJModel::OBJModel(typename PFP::MAP& map): m_map(map), @@ -69,12 +70,6 @@ inline Geom::Vec2f OBJModel::getTexCoord(Dart d) } -template -std::vector& OBJModel::getMaterialNames() -{ - return m_materialNames; -} - template void OBJModel::setPositionAttribute(VertexAttribute position) { @@ -97,9 +92,9 @@ void OBJModel::setTexCoordAttribute(VertexAttributetexcoord) template -void OBJModel::readMaterials(const std::string& filename) +void OBJModel::readMaterials(const std::string& filename, std::vector& materials) { - m_materials.resize(m_materialNames.size()); + materials.reserve(m_materialNames.size()); // open file std::ifstream fp(filename.c_str()); @@ -110,6 +105,7 @@ void OBJModel::readMaterials(const std::string& filename) } std::vector::iterator mit; + std::string ligne; std::string tag; fp >> tag; @@ -118,7 +114,8 @@ void OBJModel::readMaterials(const std::string& filename) std::getline (fp, ligne); if (tag == "newmtl") { - std::vector::iterator it = std::find(m_materialNames.begin(), m_materialNames.end(), ligne); + + std::map::iterator it = m_materialNames.find(ligne); if (it == m_materialNames.end()) { CGoGNerr << "Skipping material "<< ligne << CGoGNendl; @@ -130,8 +127,20 @@ void OBJModel::readMaterials(const std::string& filename) } else { - CGoGNerr << "Reading material "<< ligne << CGoGNendl; - mit = m_materials.begin() + (it - m_materialNames.begin()); + CGoGNout << "Reading material "<< ligne << CGoGNendl; + + if (materials.empty()) + { + materials.resize(1); + mit = materials.begin(); + } + else + { + materials.resize(materials.size()+1); + ++mit; + } + it->second = (mit-materials.begin()); + mit->name = ligne; } } else @@ -160,6 +169,17 @@ void OBJModel::readMaterials(const std::string& filename) { oss >> mit->shininess; } + if (tag == "Tf") + { + oss >> mit->transparentFilter[0]; + oss >> mit->transparentFilter[1]; + oss >> mit->transparentFilter[2]; + } + + if ((tag == "Tr") || (tag == "d")) + { + oss >> mit->transparency; + } if (tag == "map_Ka") // ambiant texture { @@ -167,7 +187,12 @@ void OBJModel::readMaterials(const std::string& filename) } if (tag == "map_Kd") // diffuse texture { - CGoGNerr << tag << " not yet supported in OBJ material reading" << CGoGNendl; + mit->textureDiffuse = new Utils::Texture<2,Geom::Vec3uc>(GL_UNSIGNED_BYTE); + std::string tname; + oss >> tname; + mit->textureDiffuse->load(tname); + CGoGNout << "Loading texture "<< tname << CGoGNendl; + } if (tag == "map_d") // opacity texture { @@ -204,6 +229,8 @@ bool OBJModel::generateBrowsers(std::vector& browsers) { MapBrowser* MBptr = new MapBrowserLinked(m_map,links); browsers.push_back(MBptr); +// std::string& matName = m_materialNames[i]; + m_groupMaterialID[i]= m_materialNames[m_groupMaterialNames[i]]; } for (Dart d=m_map.begin(); d!=m_map.end(); m_map.next(d)) @@ -706,7 +733,8 @@ bool OBJModel::import( const std::string& filename, std::vector> buf; - m_materialNames.push_back(buf); + m_materialNames.insert(std::pair(buf,-1)); + m_groupMaterialNames.push_back(buf); currentGroup++; } diff --git a/include/Algo/Import/importTet.hpp b/include/Algo/Import/importTet.hpp index 2c1b93afe..ecb3f686f 100644 --- a/include/Algo/Import/importTet.hpp +++ b/include/Algo/Import/importTet.hpp @@ -23,6 +23,7 @@ *******************************************************************************/ #include "Algo/Modelisation/polyhedron.h" +#include "Geometry/orientation.h" #include namespace CGoGN @@ -38,7 +39,7 @@ namespace Import { template -bool importTet(typename PFP::MAP& map, const std::string& filename, std::vector& attrNames, float scaleFactor, bool invertTetra) +bool importTet(typename PFP::MAP& map, const std::string& filename, std::vector& attrNames, float scaleFactor) { typedef typename PFP::VEC3 VEC3; @@ -102,6 +103,8 @@ bool importTet(typename PFP::MAP& map, const std::string& filename, std::vector< DartMarkerNoUnmark m(map) ; + + unsigned int invertTetra = 0; //Read and embed all tetrahedrons for(unsigned int i = 0; i < m_nbVolumes ; ++i) { @@ -119,6 +122,31 @@ bool importTet(typename PFP::MAP& map, const std::string& filename, std::vector< Dart d = Surface::Modelisation::createTetrahedron(map,false); Geom::Vec4ui pt; + + + if (i==0) + { + oss >> pt[0]; + oss >> pt[1]; + oss >> pt[2]; + oss >> pt[3]; + + typename PFP::VEC3 P = position[verticesID[pt[0]]]; + typename PFP::VEC3 A = position[verticesID[pt[1]]]; + typename PFP::VEC3 B = position[verticesID[pt[2]]]; + typename PFP::VEC3 C = position[verticesID[pt[3]]]; + + if (Geom::testOrientation3D(P,A,B,C) == Geom::OVER) + { + invertTetra=1; + unsigned int ui=pt[1]; + pt[1] = pt[2]; + pt[2] = ui; + } + } + + + oss >> pt[0]; oss >> pt[1+invertTetra]; oss >> pt[2-invertTetra]; diff --git a/include/Algo/Import/importTs.hpp b/include/Algo/Import/importTs.hpp index 86194fb63..c1b545324 100644 --- a/include/Algo/Import/importTs.hpp +++ b/include/Algo/Import/importTs.hpp @@ -23,7 +23,7 @@ *******************************************************************************/ #include "Algo/Modelisation/polyhedron.h" - +#include "Geometry/orientation.h" #include namespace CGoGN @@ -128,6 +128,18 @@ bool importTs(typename PFP::MAP& map, const std::string& filename, std::vector> pt[1]; oss >> pt[2]; oss >> pt[3]; + typename PFP::VEC3 P = position[verticesID[pt[0]]]; + typename PFP::VEC3 A = position[verticesID[pt[1]]]; + typename PFP::VEC3 B = position[verticesID[pt[2]]]; + typename PFP::VEC3 C = position[verticesID[pt[3]]]; + + if (Geom::testOrientation3D(P,A,B,C) == Geom::OVER) + { + unsigned int ui=pt[1]; + pt[1] = pt[2]; + pt[2] = ui; + } + //if regions are defined use this number oss >> nbe; //ignored here diff --git a/include/Algo/Import/importVTU.hpp b/include/Algo/Import/importVTU.hpp new file mode 100644 index 000000000..378f6ff22 --- /dev/null +++ b/include/Algo/Import/importVTU.hpp @@ -0,0 +1,553 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include "Algo/Modelisation/polyhedron.h" +#include "Geometry/orientation.h" + +#include +#include +#include + +#include + +namespace CGoGN +{ + +namespace Algo +{ + +namespace Volume +{ + +namespace Import +{ + +template +bool importVTU(typename PFP::MAP& map, const std::string& filename, std::vector& attrNames, float scaleFactor) +{ + typedef typename PFP::VEC3 VEC3; + + VertexAttribute position = map.template addAttribute("position") ; + attrNames.push_back(position.name()) ; + + AttributeContainer& container = map.template getAttributeContainer() ; + + unsigned int m_nbVertices = 0, m_nbVolumes = 0; + VertexAutoAttribute< NoMathIONameAttribute< std::vector > > vecDartsPerVertex(map, "incidents"); + + + xmlDocPtr doc = xmlReadFile(filename.c_str(), NULL, 0); + xmlNodePtr vtu_node = xmlDocGetRootElement(doc); + + + std::cout << " NAME "<name << std::endl; + + xmlChar *prop = xmlGetProp(vtu_node, BAD_CAST "type"); + std::cout << "type = "<< prop << std::endl; + + xmlNode* cur_node = vtu_node->children; + while (strcmp((char*)(cur_node->name),(char*)"UnstructuredGrid")!=0) + cur_node = cur_node->next; + + cur_node = cur_node->children; + while (strcmp((char*)(cur_node->name),(char*)"Piece")!=0) + cur_node = cur_node->next; + + prop = xmlGetProp(cur_node, BAD_CAST "NumberOfPoints"); + unsigned int nbp = atoi((char*)(prop)); + + prop = xmlGetProp(cur_node, BAD_CAST "NumberOfCells"); + unsigned int nbc = atoi((char*)(prop)); + + std::cout << "Number of points = "<< nbp<< std::endl; + std::cout << "Number of cells = "<< nbc<< std::endl; + + cur_node = cur_node->children; + while (strcmp((char*)(cur_node->name),(char*)"Points")!=0) + cur_node = cur_node->next; + + cur_node = cur_node->children; + while (strcmp((char*)(cur_node->name),(char*)"DataArray")!=0) + cur_node = cur_node->next; + + std::stringstream ss((char*)(xmlNodeGetContent(cur_node->children))); + + for (unsigned int i=0; i< nbp; ++i) + { + typename PFP::VEC3 P; + ss >> P[0]; ss >> P[1]; ss >> P[2]; + std::cout << P << std::endl; + } + +// for (xmlNode* x_node = cur_node->children; x_node!=NULL; x_node = x_node->next) +// { +// // float f = atof((char*)(xmlNodeGetContent(x_node))); +// std::cout << xmlNodeGetContent(x_node) << std::endl; +// } + +// for (xmlNode* cur_node = vtu_node->children; cur_node; cur_node = cur_node->next) +// { +// std::cout << " NAME "<name << std::endl; +// } +// cur_node = cur_node->children; +// std::cout << " NAME "<name << std::endl; + + xmlFreeDoc(doc); + return true; + + /* + if (strcmp((char*)(map_node->name),(char*)"CGoGN_Map")!=0) + { + std::cerr << "Wrong xml format: Root node != CGoGN_Map"<< std::endl; + return false; + } + + */ + + + //open file + std::ifstream fp(filename.c_str(), std::ios::in); + if (!fp.good()) + { + CGoGNerr << "Unable to open file " << filename << CGoGNendl; + return false; + } + + std::string ligne; + unsigned int nbv=0; + //read $NODE + std::getline (fp, ligne); + + // reading number of vertices + std::getline (fp, ligne); + std::stringstream oss(ligne); + oss >> nbv; + + + //reading vertices +// std::vector verticesID; + std::map verticesMapID; + + +// verticesID.reserve(nbv); + for(unsigned int i = 0; i < nbv;++i) + { + do + { + std::getline (fp, ligne); + } while (ligne.size() == 0); + + std::stringstream oss(ligne); + unsigned int pipo; + float x,y,z; + oss >> pipo; + oss >> x; + oss >> y; + oss >> z; + // TODO : if required read other vertices attributes here + VEC3 pos(x*scaleFactor,y*scaleFactor,z*scaleFactor); + + unsigned int id = container.insertLine(); + position[id] = pos; + + verticesMapID.insert(std::pair(pipo,id)); +// verticesID.push_back(id); + } + + // ENNODE + std::getline (fp, ligne); + + m_nbVertices = nbv; + + + // ELM + std::getline (fp, ligne); + + // reading number of elements + std::getline (fp, ligne); + unsigned int nbe=0; + std::stringstream oss2(ligne); + oss2 >> nbe; + + std::vector tet; + tet.reserve(1000); + std::vector hexa; + tet.reserve(1000); + + bool invertVol = false; + + for(unsigned int i=0; i> pipo; + fp >> type_elm; + fp >> pipo; + fp >> pipo; + fp >> nb; + + if ((type_elm==4) && (nb==4)) + { + Geom::Vec4ui v; + + // test orientation of first tetra + if (i==0) + { + fp >> v[0]; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + + typename PFP::VEC3 P = position[verticesMapID[v[0]]]; + typename PFP::VEC3 A = position[verticesMapID[v[1]]]; + typename PFP::VEC3 B = position[verticesMapID[v[2]]]; + typename PFP::VEC3 C = position[verticesMapID[v[3]]]; + + if (Geom::testOrientation3D(P,A,B,C) == Geom::OVER) + { + invertVol=true; + unsigned int ui=v[0]; + v[0] = v[3]; + v[3] = v[2]; + v[2] = v[1]; + v[1] = ui; + } + } + else + { + if (invertVol) + { + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + fp >> v[0]; + } + else + { + fp >> v[0]; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + } + } + tet.push_back(v); + } + else + { + if ((type_elm==5) && (nb==8)) + { + std::cout << "HEXA: "<< i << std::endl; + Geom::Vec4ui v; + + if (i==0) + { + unsigned int last; + fp >> v[0]; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + fp >> last; + + typename PFP::VEC3 P = position[verticesMapID[last]]; + typename PFP::VEC3 A = position[verticesMapID[v[0]]]; + typename PFP::VEC3 B = position[verticesMapID[v[1]]]; + typename PFP::VEC3 C = position[verticesMapID[v[2]]]; + + if (Geom::testOrientation3D(P,A,B,C) == Geom::OVER) + { + + invertVol=true; + unsigned int ui = v[3]; + v[3] = v[0]; + v[0] = ui; + ui = v[2]; + v[2] = v[1]; + v[1] = ui; + hexa.push_back(v); + v[3] = last; + fp >> v[2]; + fp >> v[1]; + fp >> v[0]; + hexa.push_back(v); + } + else + { + hexa.push_back(v); + v[0] = last; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + hexa.push_back(v); + } + } + else + { + if (invertVol) + { + fp >> v[3]; + fp >> v[2]; + fp >> v[1]; + fp >> v[0]; + hexa.push_back(v); + fp >> v[3]; + fp >> v[2]; + fp >> v[1]; + fp >> v[0]; + hexa.push_back(v); + + } + else + { + fp >> v[0]; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + hexa.push_back(v); + fp >> v[0]; + fp >> v[1]; + fp >> v[2]; + fp >> v[3]; + hexa.push_back(v); + } + } + } + else + { + for (unsigned int j=0; j> v; + } + } + } + } + + CGoGNout << "nb points = " << m_nbVertices ; + + + m_nbVolumes = 0; + + DartMarkerNoUnmark m(map) ; + + if (tet.size() > 0) + { + m_nbVolumes += tet.size(); + + //Read and embed all tetrahedrons + for(unsigned int i = 0; i < tet.size() ; ++i) + { + //start one tetra + // Geom::Vec4ui& pt = tet[i]; + Geom::Vec4ui pt; + + pt[0] = tet[i][0]; + pt[1] = tet[i][1]; + pt[2] = tet[i][2]; + pt[3] = tet[i][3]; + + Dart d = Surface::Modelisation::createTetrahedron(map,false); + + + // Embed three "base" vertices + for(unsigned int j = 0 ; j < 3 ; ++j) + { + FunctorSetEmb fsetemb(map, verticesMapID[pt[2-j]]); + map.template foreach_dart_of_orbit(d, fsetemb); + + //store darts per vertices to optimize reconstruction + Dart dd = d; + do + { + m.mark(dd) ; + vecDartsPerVertex[verticesMapID[pt[2-j]]].push_back(dd); + dd = map.phi1(map.phi2(dd)); + } while(dd != d); + + d = map.phi1(d); + } + + //Embed the last "top" vertex + d = map.phi_1(map.phi2(d)); + + FunctorSetEmb fsetemb(map, verticesMapID[pt[3]]); + map.template foreach_dart_of_orbit(d, fsetemb); + + //store darts per vertices to optimize reconstruction + Dart dd = d; + do + { + m.mark(dd) ; + vecDartsPerVertex[verticesMapID[pt[3]]].push_back(dd); + dd = map.phi1(map.phi2(dd)); + } while(dd != d); + + //end of tetra + } + CGoGNout << " / nb tetra = " << tet.size() << CGoGNendl; + + } + + if (hexa.size() > 0) + { + + m_nbVolumes += hexa.size()/2; + + //Read and embed all tetrahedrons + for(unsigned int i = 0; i < hexa.size()/2 ; ++i) + { + // one hexa + Geom::Vec4ui pt; + pt[0] = hexa[2*i][0]; + pt[1] = hexa[2*i][1]; + pt[2] = hexa[2*i][2]; + pt[3] = hexa[2*i][3]; + Geom::Vec4ui ppt; + ppt[0] = hexa[2*i+1][0]; + ppt[1] = hexa[2*i+1][1]; + ppt[2] = hexa[2*i+1][2]; + ppt[3] = hexa[2*i+1][3]; + + Dart d = Surface::Modelisation::createHexahedron(map,false); + + FunctorSetEmb fsetemb(map, verticesMapID[pt[0]]); + + map.template foreach_dart_of_orbit(d, fsetemb); + Dart dd = d; + vecDartsPerVertex[verticesMapID[pt[0]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[0]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[0]]].push_back(dd); m.mark(dd); + + d = map.phi1(d); + fsetemb.changeEmb(verticesMapID[pt[1]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[pt[1]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[1]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[1]]].push_back(dd); m.mark(dd); + + + d = map.phi1(d); + fsetemb.changeEmb(verticesMapID[pt[2]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[pt[2]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[2]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[2]]].push_back(dd); m.mark(dd); + + + d = map.phi1(d); + fsetemb.changeEmb(verticesMapID[pt[3]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[pt[3]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[3]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[pt[3]]].push_back(dd); m.mark(dd); + + d = map.template phi<2112>(d); + fsetemb.changeEmb(verticesMapID[ppt[0]]); + + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[ppt[0]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[0]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[0]]].push_back(dd); m.mark(dd); + + d = map.phi_1(d); + fsetemb.changeEmb(verticesMapID[ppt[1]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[ppt[1]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[1]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[1]]].push_back(dd); m.mark(dd); + + d = map.phi_1(d); + fsetemb.changeEmb(verticesMapID[ppt[2]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[ppt[2]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[2]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[2]]].push_back(dd); m.mark(dd); + + d = map.phi_1(d); + fsetemb.changeEmb(verticesMapID[ppt[3]]); + map.template foreach_dart_of_orbit(d, fsetemb); + dd = d; + vecDartsPerVertex[verticesMapID[ppt[3]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[3]]].push_back(dd); m.mark(dd); dd = map.phi1(map.phi2(dd)); + vecDartsPerVertex[verticesMapID[ppt[3]]].push_back(dd); m.mark(dd); + + //end of hexa + } + CGoGNout << " / nb hexa = " << hexa.size()/2 << CGoGNendl; + + } + + //Association des phi3 + unsigned int nbBoundaryFaces = 0 ; + for (Dart d = map.begin(); d != map.end(); map.next(d)) + { + if (m.isMarked(d)) + { + std::vector& vec = vecDartsPerVertex[map.phi1(d)]; + + Dart good_dart = NIL; + for(typename std::vector::iterator it = vec.begin(); it != vec.end() && good_dart == NIL; ++it) + { + if(map.template getEmbedding(map.phi1(*it)) == map.template getEmbedding(d) && + map.template getEmbedding(map.phi_1(*it)) == map.template getEmbedding(map.template phi<11>(d))) + { + good_dart = *it ; + } + } + + if (good_dart != NIL) + { + map.sewVolumes(d, good_dart, false); + m.template unmarkOrbit(d); + } + else + { + m.unmarkOrbit(d); + ++nbBoundaryFaces; + } + } + } + + if (nbBoundaryFaces > 0) + { + std::cout << "closing" << std::endl ; + map.closeMap(); + CGoGNout << "Map closed (" << nbBoundaryFaces << " boundary faces)" << CGoGNendl; + } + + fp.close(); + return true; +} + +} // namespace Import + +} + +} // namespace Algo + +} // namespace CGoGN -- GitLab