diff --git a/Apps/Examples/simpleGMap2.cpp b/Apps/Examples/simpleGMap2.cpp index adb28790ae67c6c0eab13f8fdcf48fbecf31c204..e86d936feee9e44193bcdf9032b810893a712808 100644 --- a/Apps/Examples/simpleGMap2.cpp +++ b/Apps/Examples/simpleGMap2.cpp @@ -31,7 +31,7 @@ SimpleGMap2::SimpleGMap2() { position = myMap.addAttribute(VERTEX, "position"); - Dart d = Algo::Modelisation::Polyhedron::createTetra(myMap); + Dart d = Algo::Modelisation::createTetrahedron(myMap); position[d] = VEC3(0,0,0); position[myMap.phi1(d)] = VEC3(10,0,15); position[myMap.phi_1(d)] = VEC3(10,20,15); diff --git a/Apps/Tuto/tuto3.cpp b/Apps/Tuto/tuto3.cpp index 6f62d56be1f871978341de75de1dfcadfa36ce30..1edc11c27f8ec4c7891d9a25be7d28dd39eb58ee 100644 --- a/Apps/Tuto/tuto3.cpp +++ b/Apps/Tuto/tuto3.cpp @@ -123,7 +123,7 @@ void MyQT::traverseMap() void MyQT::createMap() { - Dart d1 = Algo::Modelisation::Polyhedron::createTetra(myMap); + Dart d1 = Algo::Modelisation::createTetrahedron(myMap); Dart d2 = d1; diff --git a/Apps/Tuto/tuto4.cpp b/Apps/Tuto/tuto4.cpp index bea40039c0a9f019832b9fcbe4ec18ac5b3c40bc..7de4f8fc67c1f79df078609d231721048b81ae02 100644 --- a/Apps/Tuto/tuto4.cpp +++ b/Apps/Tuto/tuto4.cpp @@ -126,7 +126,7 @@ void MyQT::traverseMap() void MyQT::createMap() { - Dart d1 = Algo::Modelisation::Polyhedron::createHexa(myMap); + Dart d1 = Algo::Modelisation::createHexahedron(myMap); Dart d2 = d1; diff --git a/include/Algo/ImplicitHierarchicalMesh/ihm3.h b/include/Algo/ImplicitHierarchicalMesh/ihm3.h index 1e69fa60e8ef33b5ab0cb006c3a77bd1bf73e2f8..97a66a4012520a588628484e9fe55d3dfbbff77d 100644 --- a/include/Algo/ImplicitHierarchicalMesh/ihm3.h +++ b/include/Algo/ImplicitHierarchicalMesh/ihm3.h @@ -59,6 +59,8 @@ public: ~ImplicitHierarchicalMap3() ; + void update_topo_shortcuts(); + //! /*! * diff --git a/include/Algo/ImplicitHierarchicalMesh/ihm3.hpp b/include/Algo/ImplicitHierarchicalMesh/ihm3.hpp index efe2f4e0c3cdbc2386ee6d2fbf70f26d588242d1..80fb02834191b72352617cf4d151a811f80bf6e9 100644 --- a/include/Algo/ImplicitHierarchicalMesh/ihm3.hpp +++ b/include/Algo/ImplicitHierarchicalMesh/ihm3.hpp @@ -63,6 +63,16 @@ AttributeHandler_IHM ImplicitHierarchicalMap3::getAttribute(unsigned int orbi return AttributeHandler_IHM(this, h.getDataVector()) ; } + +inline void ImplicitHierarchicalMap3::update_topo_shortcuts() +{ + Map3::update_topo_shortcuts(); + m_dartLevel = Map3::getAttribute(DART, "dartLevel") ; + m_faceId = Map3::getAttribute(DART, "faceId") ; + m_edgeId = Map3::getAttribute(DART, "edgeId") ; +} + + /*************************************************** * MAP TRAVERSAL * ***************************************************/ diff --git a/include/Algo/ImplicitHierarchicalMesh/subdivision3.hpp b/include/Algo/ImplicitHierarchicalMesh/subdivision3.hpp index 11ce326808a9352b0dccc14ce28b75398111f58a..2e89b50d95647cad50551d53e1244ca9ef83c9ee 100644 --- a/include/Algo/ImplicitHierarchicalMesh/subdivision3.hpp +++ b/include/Algo/ImplicitHierarchicalMesh/subdivision3.hpp @@ -279,39 +279,12 @@ Dart subdivideVolumeClassic(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& std::vector newEdges; //save darts from inner edges newEdges.reserve(50); -// DartMarker mSplitted(map); -// -// int i = 0; //Second step : deconnect each corner, close each hole, subdivide each new face into 3 for (std::vector::iterator edge = oldEdges.begin(); edge != oldEdges.end(); ++edge) { -// std::vector v ; -// Dart e = map.beginSplittingPath(*edge, mSplitted); -// -// std::cout << "e = " << e << "plop" << std::endl; -// -// //Tous les brins ont deja ete decousus, il n'y a pas de chemin d'arete a construire -// if(e == NIL) -// { -// return NIL; -// } -// else -// { -// map.constructSplittingPath(e, v, mSplitted); -// } -// -// std::cout << std::endl; -// for(std::vector::iterator it = v.begin() ; it != v.end() ; ++it) -// std::cout << *it << std::endl; -// std::cout << std::endl; -// -// i++; -// if(i == 2) -// return NIL; Dart e = *edge; - std::vector v ; do @@ -323,11 +296,6 @@ Dart subdivideVolumeClassic(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& } while(e != *edge); -// std::cout << "begin" << std::endl; -// for(std::vector::iterator it = v.begin() ; it != v.end() ; ++it) -// std::cout << *it << std::endl; -// std::cout << "finished" << std::endl; - map.splitVolume(v) ; Dart old = map.phi2(map.phi1(*edge)); @@ -410,10 +378,11 @@ Dart subdivideVolumeClassic(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& } template -Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position) +Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position) { assert(map.getDartLevel(d) <= map.getCurrentLevel() || !"Access to a dart introduced after current level") ; assert(!map.volumeIsSubdivided(d) || !"Trying to subdivide an already subdivided volume") ; + assert(!map.neighborhoodLevelDiffersByOne(d) || !"Trying to subdivide a volume with neighborhood Level difference greater than 1"); unsigned int vLevel = map.volumeLevel(d); Dart old = map.volumeOldestDart(d); @@ -440,7 +409,7 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos //Store the edges before the cutEdge std::vector oldEdges; - oldEdges.reserve(512); + oldEdges.reserve(20); mf.markOrbit(FACE, old) ; @@ -476,13 +445,9 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos /* * Subdivision */ - //Store the darts from quadrangulated faces - std::vector > subdividedfacesQ; - subdividedfacesQ.reserve(25); - - std::vector > subdividedfacesT; - subdividedfacesT.reserve(25); - + //type 'q' : quad et plus + //type 't' : tri + std::vector > > subdividedfaces; //First step : subdivide edges and faces //creates a i+1 edge level and i+1 face level @@ -501,8 +466,6 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos unsigned int fLevel = map.faceLevel(d) + 1; //puisque dans tous les cas, la face est subdivisee map.setCurrentLevel(fLevel) ; - - //test si la face est triangulaire ou non if(map.phi1(map.phi1(map.phi1(d))) == d) { @@ -511,7 +474,8 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos Dart e = cf; do { - subdividedfacesT.push_back(std::pair(e,map.phi2(e))); + std::pair pd(e,map.phi2(e)); + subdividedfaces.push_back(std::pair > ('t',pd)); e = map.phi1(e); }while (e != cf); } @@ -522,7 +486,8 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos Dart e = cf; do { - subdividedfacesQ.push_back(std::pair(e,map.phi2(e))); + std::pair pd(e,map.phi2(e)); + subdividedfaces.push_back(std::pair >('q',pd)); e = map.phi2(map.phi1(e)); }while (e != cf); @@ -530,6 +495,7 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos } map.setCurrentLevel(cur); + } map.setCurrentLevel(vLevel + 1) ; // go to the next level to perform volume subdivision @@ -537,17 +503,22 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos std::vector newEdges; //save darts from inner edges newEdges.reserve(50); + bool istet = true; + bool ishex = false; + //Second step : deconnect each corner, close each hole, subdivide each new face into 3 for (std::vector::iterator edge = oldEdges.begin(); edge != oldEdges.end(); ++edge) { Dart e = *edge; - std::vector v ; + Dart f1 = map.phi1(*edge); + //Dart f2 = map.phi2(f1); + do { if(map.phi1(map.phi1(map.phi1(e))) != e) - v.push_back(map.phi1(map.phi1(e))); //remplacer par une boucle qui découd toute la face et non juste une face carre (jusqu'a phi_1(e)) + v.push_back(map.phi1(map.phi1(e))); v.push_back(map.phi1(e)); @@ -557,230 +528,98 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos map.splitVolume(v) ; - //degree du sommet exterieur - unsigned int cornerDegree = map.Map2::vertexDegree(*edge); - - //tourner autour du sommet pour connaitre le brin d'un sommet de valence < cornerDegree - bool found = false; - Dart stop = e; - do - { - - if(map.Map2::vertexDegree(map.phi2(map.phi1(e))) < cornerDegree) - { - stop = map.phi2(map.phi1(e)); - found = true; - } - - e = map.phi2(map.phi_1(e)); - } - while(!found && e != *edge); - - //si il existe un sommet de degre inferieur au degree du coin - if(found) - { - //chercher le brin de faible degree suivant - bool found2 = false; - Dart dd = map.phi1(stop); - - do - { - if(map.Map2::vertexDegree(dd) < cornerDegree) - found2 = true; - else - dd = map.phi1(dd); - } - while(!found2); - - //cas de la pyramide - if(dd == stop) - { - //std::cout << "pyramide" << std::endl; - map.splitFace(dd, map.phi1(map.phi1(dd))); - } - else - { - map.splitFace(dd, stop); - - //calcul de la taille des faces de chaque cote de stop - if(!( (map.Map2::faceDegree(map.phi_1(stop)) == 3 && map.Map2::faceDegree(map.phi2(map.phi_1(stop))) == 4) || - (map.Map2::faceDegree(map.phi_1(stop)) == 4 && map.Map2::faceDegree(map.phi2(map.phi_1(stop))) == 3) )) - { - //std::cout << "octaedre ou hexaedre" << std::endl; - - Dart ne = map.phi_1(stop) ; - map.cutEdge(ne); - position[map.phi1(ne)] = volCenter; - stop = map.phi2(map.phi1(ne)); - - bool finished = false; - Dart it = map.phi2(ne); - - do - { - //chercher le brin de faible degree suivant - bool found2 = false; - Dart dd = map.phi1(it); - - do - { - if(dd == stop) - finished = true; - else if(map.Map2::vertexDegree(dd) < cornerDegree) - found2 = true; - else - dd = map.phi1(dd); - } - while(!found2 & !finished); - - if(found2) - { - map.splitFace(it,dd); - } - - it = map.phi_1(dd); - - if(it == stop) - finished = true; - - } - while(!finished); - - } - else - { - //std::cout << "prisme" << std::endl; - //tester si besoin de fermer f2 (par exemple pas besoin pour hexa... mais pour tet, octa, prisme oui) - //map.closeHole(f2); - } - - } - - } - //sinon cas du tetraedre - else - { - //std::cout << "tetraedre" << std::endl; - //tester si besoin de fermer f2 (par exemple pas besoin pour hexa... mais pour tet, octa, prisme oui) - //map.closeHole(f2); - } - - } - - - - - //std::cout << "1ere etape finished" << std::endl; - - CellMarker mtf(map, FACE); - - //Etape 2 - for (std::vector >::iterator edges = subdividedfacesT.begin(); edges != subdividedfacesT.end(); ++edges) - { -// Dart f1 = (*edges).first; - Dart f2 = (*edges).second; - - //si ce n'est pas un tetrahedre - if( !( (map.Map2::faceDegree(f2) == 3 && map.Map2::faceDegree(map.phi2(f2)) == 3 && - map.Map2::faceDegree(map.phi2(map.phi_1(f2))) == 3) && map.Map2::vertexDegree(f2) == 3)) - { - - //map.deleteVolume(map.phi3(map.phi2(map.phi1(oldEdges.front())))); -// if(!mtf.isMarked(f1)) -// { -// mtf.mark(f1); -// -// map.closeHole(f1); -// -// if(map.Map2::faceDegree(map.phi2(f2)) == 3) -// { -// //std::cout << "ajout d'un tetraedre" << std::endl; -// Dart x = Algo::Modelisation::trianguleFace(map, map.phi2(f1)); -// position[x] = volCenter; -// } -// else -// { -// //std::cout << "ajout d'un prisme" << std::endl; -// //Dart x = Algo::Modelisation::extrudeFace(map,position,map.phi2(f1),5.0); -// Dart c = Algo::Modelisation::trianguleFace(map, map.phi2(f1)); +// //fonction qui calcule le degree max des faces atour d'un sommet +// unsigned int fdeg = map.faceDegree(map.phi2(f1)); // -// Dart cc = c; -// // cut edges -// do -// { +// if(fdeg > 4) +// { +// std::cout << "> 4" << std::endl; // -// typename PFP::VEC3 p1 = position[cc] ; -// typename PFP::VEC3 p2 = position[map.phi1(cc)] ; +// ishex = true; // -// map.cutEdge(cc); +// Dart old = map.phi2(map.phi1(e)); +// Dart dd = map.phi1(map.phi1(old)) ; +// map.splitFace(old,dd) ; // -// position[map.phi1(cc)] = (p1 + p2) * typename PFP::REAL(0.5) ; +// Dart ne = map.phi1(map.phi1(old)) ; // -// cc = map.phi2(map.phi_1(cc)); -// }while (cc != c); +// map.cutEdge(ne); +// position[map.phi1(ne)] = volCenter; //plonger a la fin de la boucle ???? +// newEdges.push_back(ne); +// newEdges.push_back(map.phi1(ne)); // -// // cut faces -// do -// { -// Dart d1 = map.phi1(cc); -// Dart d2 = map.phi_1(cc); -// map.splitFace(d1,d2); -// cc = map.phi2(map.phi_1(cc));//map.Map2::alpha1(cc); -// }while (cc != c); // -// //merge central faces by removing edges -// bool notFinished=true; -// do -// { -// Dart d1 = map.Map2::alpha1(cc); -// if (d1 == cc) // last edge is pending edge inside of face -// notFinished = false; -// map.deleteFace(cc); -// cc = d1; -// } while (notFinished); +// Dart stop = map.phi2(map.phi1(ne)); +// ne = map.phi2(ne); +// do +// { +// dd = map.phi1(map.phi1(map.phi1(ne))); // +// //A Verifier !! +// map.splitFace(ne, dd) ; // -// map.closeHole(map.phi1(map.phi1(map.phi2(f1)))); +// newEdges.push_back(map.phi1(dd)); // -// } +// ne = map.phi2(map.phi_1(ne)); +// dd = map.phi1(map.phi1(dd)); // } - - } - } - - //std::cout << "2e etape finished" << std::endl; - - -// { -// //Third step : 3-sew internal faces -// for (std::vector >::iterator it = subdividedfacesT.begin(); it != subdividedfacesT.end(); ++it) +// while(dd != stop); +// } +// else if(fdeg > 3) // { -// Dart f1 = (*it).first; -// Dart f2 = (*it).second; +// std::cout << "> 3" << std::endl; // +// //map.closeHole(f2); +// //map.sewVolumes(map.phi2(f1),map.phi2(f2)); +// istet = false; // +// Dart old = map.phi2(map.phi1(*edge)); +// Dart dd = map.phi1(old) ; +// map.splitFace(old,dd) ; // -// if(map.phi3(map.phi2(f1)) == map.phi2(f1) && map.phi3(map.phi2(f2)) == map.phi2(f2)) -// { -// if(map.getEmbedding(VERTEX, map.phi_1(map.phi2(f2))) == map.getEmbedding(VERTEX, map.phi_1(map.phi2(f1)))) -// { -// map.Map3::sewVolumes(map.phi2(f2), map.phi2(f1)); -// } -// else -// { +// Dart ne = map.phi1(old); // -// //id pour toutes les faces interieures -// map.sewVolumes(map.phi2(f2), map.phi2(f1)); +// map.cutEdge(ne); +// position[map.phi1(ne)] = volCenter; //plonger a la fin de la boucle ???? +// newEdges.push_back(ne); +// newEdges.push_back(map.phi1(ne)); // +// Dart stop = map.phi2(map.phi1(ne)); +// ne = map.phi2(ne); +// do +// { +// dd = map.phi1(map.phi1(ne)); // -// } +// map.splitFace(ne, dd) ; // -// //Fais a la couture !!!!! -// unsigned int idface = map.getNewFaceId(); -// map.setFaceId(map.phi2(f1),idface, FACE); +// newEdges.push_back(map.phi1(dd)); +// +// ne = map.phi2(map.phi_1(ne)); +// dd = map.phi1(dd); // } +// while(dd != stop); +// } +// else +// { +// //map.closeHole(f2); +// //map.sewVolumes(map.phi2(f1),map.phi2(f2)); +// +// unsigned int idface = map.getNewFaceId(); +// map.setFaceId(map.phi2(f1),idface, FACE); +// } + + } + + if(ishex) + { + map.deleteVolume(map.phi3(map.phi2(map.phi1(oldEdges.front())))); // +// //Third step : 3-sew internal faces +// for (std::vector >::iterator it = subdividedfaces.begin(); it != subdividedfaces.end(); ++it) +// { +// Dart f1 = (*it).first; +// Dart f2 = (*it).second; // // //FAIS a la couture !!!!!!! // //id pour toutes les aretes exterieurs des faces quadrangulees @@ -802,81 +641,121 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos // mne.markOrbit(EDGE, *it); // } // } -// } -// + + } + + if(!istet) + { + for (std::vector::iterator edge = oldEdges.begin(); edge != oldEdges.end(); ++edge) + { + //Dart e = *edge; + + Dart x = map.phi_1(map.phi2(map.phi1(*edge))); + Dart f = x; + + do + { + Dart f3 = map.phi3(f); + Dart tmp = map.phi_1(map.phi2(map.phi_1(map.phi2(map.phi_1(f3))))); + + map.unsewFaces(f3); + map.unsewFaces(tmp); + map.sewFaces(f3, tmp); + + unsigned int idface = map.getNewFaceId(); + map.setFaceId(map.phi2(f3),idface, FACE); + + + f = map.phi2(map.phi_1(f)); + }while(f != x); + + } + + } + + + + + // { -// //Third step : 3-sew internal faces -// for (std::vector >::iterator it = subdividedfacesQ.begin(); it != subdividedfacesQ.end(); ++it) -// { -// Dart f1 = (*it).first; -// Dart f2 = (*it).second; +// //Third step : 3-sew internal faces +// for (std::vector >::iterator it = subdividedfacesT.begin(); it != subdividedfacesT.end(); ++it) +// { +// Dart f1 = (*it).first; +// Dart f2 = (*it).second; // -// if(map.phi3(map.phi2(f1)) == map.phi2(f1) && map.phi3(map.phi2(f2)) == map.phi2(f2)) -// { -// //id pour toutes les faces interieures -// map.sewVolumes(map.phi2(f2), map.phi2(f1)); +// //FAIS a la couture !!!!!!! +// //id pour toutes les aretes exterieurs des faces quadrangulees +// unsigned int idedge = map.getEdgeId(f1); +// map.setEdgeId(map.phi2(f1), idedge, DART); +// map.setEdgeId( map.phi2(f2), idedge, DART); // -// //Fais a la couture !!!!! -// unsigned int idface = map.getNewFaceId(); -// map.setFaceId(map.phi2(f1),idface, FACE); -// } +// } // -// //FAIS a la couture !!!!!!! -// //id pour toutes les aretes exterieurs des faces quadrangulees -// unsigned int idedge = map.getEdgeId(f1); -// map.setEdgeId(map.phi2(f1), idedge, DART); -// map.setEdgeId( map.phi2(f2), idedge, DART); -// } -// //LA copie de L'id est a gerer avec le sewVolumes normalement !!!!!! -// //id pour les aretes interieurs : (i.e. 16 pour un octa) -// DartMarker mne(map); -// for(std::vector::iterator it = newEdges.begin() ; it != newEdges.end() ; ++it) +// //LA copie de L'id est a gerer avec le sewVolumes normalement !!!!!! +// //id pour les aretes interieurs : (i.e. 16 pour un octa) +// DartMarker mne(map); +// for(std::vector::iterator it = newEdges.begin() ; it != newEdges.end() ; ++it) +// { +// if(!mne.isMarked(*it)) // { -// if(!mne.isMarked(*it)) -// { -// unsigned int idedge = map.getNewEdgeId(); -// map.setEdgeId(*it, idedge, EDGE); -// mne.markOrbit(EDGE, *it); -// } +// unsigned int idedge = map.getNewEdgeId(); +// map.setEdgeId(*it, idedge, EDGE); +// mne.markOrbit(EDGE, *it); // } // } +// } // -// //cas tordu pour le prisme -// for (std::vector >::iterator it = subdividedfacesT.begin(); it != subdividedfacesT.end(); ++it) +// { +// //Third step : 3-sew internal faces +// for (std::vector >::iterator it = subdividedfacesQ.begin(); it != subdividedfacesQ.end(); ++it) // { // Dart f1 = (*it).first; // Dart f2 = (*it).second; // -// if( !(map.Map2::faceDegree(f2) == 3 && map.Map2::faceDegree(map.phi2(f2)) == 3 && -// map.Map2::faceDegree(map.phi2(map.phi1(f2))) == 3 && map.Map2::faceDegree(map.phi2(map.phi_1(f2))) == 3)) +// if(map.phi3(map.phi2(f1)) == map.phi2(f1) && map.phi3(map.phi2(f2)) == map.phi2(f2)) // { +// //id pour toutes les faces interieures +// map.sewVolumes(map.phi2(f1), map.phi2(f2)); // +// //Fais a la couture !!!!! +// unsigned int idface = map.getNewFaceId(); +// map.setFaceId(map.phi2(f1),idface, FACE); +// } // -// if(map.phi2(map.phi1(map.phi1(map.phi2(f1)))) == map.phi3(map.phi2(map.phi1(map.phi1(map.phi2(f1))))) && -// map.phi2(map.phi3(map.phi2(map.phi3(map.phi2(map.phi3(map.phi2(map.phi2(map.phi1(map.phi1(map.phi2(f1))))))))))) == -// map.phi3(map.phi2(map.phi3(map.phi2(map.phi3(map.phi2(map.phi3(map.phi2(map.phi2(map.phi1(map.phi1(map.phi2(f1)))))))))))) -// ) -// { -// map.sewVolumes(map.phi2(map.phi1(map.phi1(map.phi2(f1)))), -// map.phi2(map.phi3(map.phi2(map.phi3(map.phi2(map.phi3(map.phi1(map.phi1(map.phi2(f1)))))))))); -// } +// //FAIS a la couture !!!!!!! +// //id pour toutes les aretes exterieurs des faces quadrangulees +// unsigned int idedge = map.getEdgeId(f1); +// map.setEdgeId(map.phi2(f1), idedge, DART); +// map.setEdgeId( map.phi2(f2), idedge, DART); +// } // +// //LA copie de L'id est a gerer avec le sewVolumes normalement !!!!!! +// //id pour les aretes interieurs : (i.e. 6 pour un hexa) +// DartMarker mne(map); +// for(std::vector::iterator it = newEdges.begin() ; it != newEdges.end() ; ++it) +// { +// if(!mne.isMarked(*it)) +// { +// unsigned int idedge = map.getNewEdgeId(); +// map.setEdgeId(*it, idedge, EDGE); +// mne.markOrbit(EDGE, *it); // } +// } // } map.setCurrentLevel(cur) ; - return subdividedfacesQ.begin()->first; +// return subdividedfacesQ.begin()->first; + return NIL; } - template -Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position) +Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position) { assert(map.getDartLevel(d) <= map.getCurrentLevel() || !"Access to a dart introduced after current level") ; assert(!map.volumeIsSubdivided(d) || !"Trying to subdivide an already subdivided volume") ; - assert(!map.neighborhoodLevelDiffersByOne(d) || !"Trying to subdivide a volume with neighborhood Level difference greater than 1"); unsigned int vLevel = map.volumeLevel(d); Dart old = map.volumeOldestDart(d); @@ -903,7 +782,7 @@ Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positi //Store the edges before the cutEdge std::vector oldEdges; - oldEdges.reserve(20); + oldEdges.reserve(512); mf.markOrbit(FACE, old) ; @@ -964,8 +843,6 @@ Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positi unsigned int fLevel = map.faceLevel(d) + 1; //puisque dans tous les cas, la face est subdivisee map.setCurrentLevel(fLevel) ; - - //test si la face est triangulaire ou non if(map.phi1(map.phi1(map.phi1(d))) == d) { @@ -993,7 +870,6 @@ Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positi } map.setCurrentLevel(cur); - } map.setCurrentLevel(vLevel + 1) ; // go to the next level to perform volume subdivision @@ -1001,212 +877,338 @@ Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positi std::vector newEdges; //save darts from inner edges newEdges.reserve(50); - bool istet = true; - //Second step : deconnect each corner, close each hole, subdivide each new face into 3 for (std::vector::iterator edge = oldEdges.begin(); edge != oldEdges.end(); ++edge) { Dart e = *edge; - Dart f1 = map.phi1(*edge); - Dart f2 = map.phi2(f1); + std::vector v ; do { if(map.phi1(map.phi1(map.phi1(e))) != e) - map.unsewFaces(map.phi1(map.phi1(e))); - - map.unsewFaces(map.phi1(e)); + v.push_back(map.phi1(map.phi1(e))); //remplacer par une boucle qui découd toute la face et non juste une face carre (jusqu'a phi_1(e)) + v.push_back(map.phi1(e)); e = map.phi2(map.phi_1(e)); } while(e != *edge); - map.closeHole(f1); - - - //fonction qui calcule le degree max des faces atour d'un sommet - unsigned int fdeg = map.faceDegree(map.phi2(f1)); + map.splitVolume(v) ; + //degree du sommet exterieur + unsigned int cornerDegree = map.Map2::vertexDegree(*edge); - if(fdeg > 4) + //tourner autour du sommet pour connaitre le brin d'un sommet de valence < cornerDegree + bool found = false; + Dart stop = e; + do { - Dart old = map.phi2(map.phi1(e)); - Dart dd = map.phi1(map.phi1(old)) ; - map.splitFace(old,dd) ; - Dart ne = map.phi1(map.phi1(old)) ; + if(map.Map2::vertexDegree(map.phi2(map.phi1(e))) < cornerDegree) + { + stop = map.phi2(map.phi1(e)); + found = true; + } - map.cutEdge(ne); - position[map.phi1(ne)] = volCenter; //plonger a la fin de la boucle ???? - newEdges.push_back(ne); - newEdges.push_back(map.phi1(ne)); + e = map.phi2(map.phi_1(e)); + } + while(!found && e != *edge); + //si il existe un sommet de degre inferieur au degree du coin + if(found) + { + //chercher le brin de faible degree suivant + bool found2 = false; + Dart dd = map.phi1(stop); - Dart stop = map.phi2(map.phi1(ne)); - ne = map.phi2(ne); do { - dd = map.phi1(map.phi1(map.phi1(ne))); + if(map.Map2::vertexDegree(dd) < cornerDegree) + found2 = true; + else + dd = map.phi1(dd); + } + while(!found2); - //A Verifier !! - map.splitFace(ne, dd) ; + //cas de la pyramide + if(dd == stop) + { + //std::cout << "pyramide" << std::endl; + map.splitFace(dd, map.phi1(map.phi1(dd))); + } + else + { + map.splitFace(dd, stop); - newEdges.push_back(map.phi1(dd)); + //calcul de la taille des faces de chaque cote de stop + if(!( (map.Map2::faceDegree(map.phi_1(stop)) == 3 && map.Map2::faceDegree(map.phi2(map.phi_1(stop))) == 4) || + (map.Map2::faceDegree(map.phi_1(stop)) == 4 && map.Map2::faceDegree(map.phi2(map.phi_1(stop))) == 3) )) + { + //std::cout << "octaedre ou hexaedre" << std::endl; - ne = map.phi2(map.phi_1(ne)); - dd = map.phi1(map.phi1(dd)); - } - while(dd != stop); - } - else if(fdeg > 3) - { - map.closeHole(f2); - map.sewVolumes(map.phi2(f1),map.phi2(f2)); + Dart ne = map.phi_1(stop) ; + map.cutEdge(ne); + position[map.phi1(ne)] = volCenter; + stop = map.phi2(map.phi1(ne)); - istet = false; - Dart old = map.phi2(map.phi1(*edge)); - Dart dd = map.phi1(old) ; - map.splitFace(old,dd) ; + bool finished = false; + Dart it = map.phi2(ne); + + do + { + //chercher le brin de faible degree suivant + bool found2 = false; + Dart dd = map.phi1(it); + + do + { + if(dd == stop) + finished = true; + else if(map.Map2::vertexDegree(dd) < cornerDegree) + found2 = true; + else + dd = map.phi1(dd); + } + while(!found2 & !finished); - Dart ne = map.phi1(old); + if(found2) + { + map.splitFace(it,dd); + } - map.cutEdge(ne); - position[map.phi1(ne)] = volCenter; //plonger a la fin de la boucle ???? - newEdges.push_back(ne); - newEdges.push_back(map.phi1(ne)); + it = map.phi_1(dd); - Dart stop = map.phi2(map.phi1(ne)); - ne = map.phi2(ne); - do - { - dd = map.phi1(map.phi1(ne)); + if(it == stop) + finished = true; - map.splitFace(ne, dd) ; + } + while(!finished); - newEdges.push_back(map.phi1(dd)); + } + else + { + //std::cout << "prisme" << std::endl; + //tester si besoin de fermer f2 (par exemple pas besoin pour hexa... mais pour tet, octa, prisme oui) + //map.closeHole(f2); + } - ne = map.phi2(map.phi_1(ne)); - dd = map.phi1(dd); } - while(dd != stop); + } + //sinon cas du tetraedre else { - map.closeHole(f2); - map.sewVolumes(map.phi2(f1),map.phi2(f2)); - - unsigned int idface = map.getNewFaceId(); - map.setFaceId(map.phi2(f1),idface, FACE); + //std::cout << "tetraedre" << std::endl; + //tester si besoin de fermer f2 (par exemple pas besoin pour hexa... mais pour tet, octa, prisme oui) + //map.closeHole(f2); } } - if(!istet) - { - for (std::vector::iterator edge = oldEdges.begin(); edge != oldEdges.end(); ++edge) - { - Dart e = *edge; - - Dart x = map.phi_1(map.phi2(map.phi1(*edge))); - Dart f = x; - - do - { - Dart f3 = map.phi3(f); - Dart tmp = map.phi_1(map.phi2(map.phi_1(map.phi2(map.phi_1(f3))))); - - map.unsewFaces(f3); - map.unsewFaces(tmp); - map.sewFaces(f3, tmp); - - unsigned int idface = map.getNewFaceId(); - map.setFaceId(map.phi2(f3),idface, FACE); - f = map.phi2(map.phi_1(f)); - }while(f != x); - } + //std::cout << "1ere etape finished" << std::endl; - } + CellMarker mtf(map, FACE); + //Etape 2 + for (std::vector >::iterator edges = subdividedfacesT.begin(); edges != subdividedfacesT.end(); ++edges) { - //Third step : 3-sew internal faces - for (std::vector >::iterator it = subdividedfacesT.begin(); it != subdividedfacesT.end(); ++it) - { - Dart f1 = (*it).first; - Dart f2 = (*it).second; - - //FAIS a la couture !!!!!!! - //id pour toutes les aretes exterieurs des faces quadrangulees - unsigned int idedge = map.getEdgeId(f1); - map.setEdgeId(map.phi2(f1), idedge, DART); - map.setEdgeId( map.phi2(f2), idedge, DART); - - } +// Dart f1 = (*edges).first; + Dart f2 = (*edges).second; - //LA copie de L'id est a gerer avec le sewVolumes normalement !!!!!! - //id pour les aretes interieurs : (i.e. 16 pour un octa) - DartMarker mne(map); - for(std::vector::iterator it = newEdges.begin() ; it != newEdges.end() ; ++it) - { - if(!mne.isMarked(*it)) + //si ce n'est pas un tetrahedre + if( !( (map.Map2::faceDegree(f2) == 3 && map.Map2::faceDegree(map.phi2(f2)) == 3 && + map.Map2::faceDegree(map.phi2(map.phi_1(f2))) == 3) && map.Map2::vertexDegree(f2) == 3)) { - unsigned int idedge = map.getNewEdgeId(); - map.setEdgeId(*it, idedge, EDGE); - mne.markOrbit(EDGE, *it); - } - } - } - { - //Third step : 3-sew internal faces - for (std::vector >::iterator it = subdividedfacesQ.begin(); it != subdividedfacesQ.end(); ++it) - { - Dart f1 = (*it).first; - Dart f2 = (*it).second; + //map.deleteVolume(map.phi3(map.phi2(map.phi1(oldEdges.front())))); - if(map.phi3(map.phi2(f1)) == map.phi2(f1) && map.phi3(map.phi2(f2)) == map.phi2(f2)) - { - //id pour toutes les faces interieures - map.sewVolumes(map.phi2(f1), map.phi2(f2)); +// if(!mtf.isMarked(f1)) +// { +// mtf.mark(f1); +// +// map.closeHole(f1); +// +// if(map.Map2::faceDegree(map.phi2(f2)) == 3) +// { +// //std::cout << "ajout d'un tetraedre" << std::endl; +// Dart x = Algo::Modelisation::trianguleFace(map, map.phi2(f1)); +// position[x] = volCenter; +// } +// else +// { +// //std::cout << "ajout d'un prisme" << std::endl; +// //Dart x = Algo::Modelisation::extrudeFace(map,position,map.phi2(f1),5.0); +// Dart c = Algo::Modelisation::trianguleFace(map, map.phi2(f1)); +// +// Dart cc = c; +// // cut edges +// do +// { +// +// typename PFP::VEC3 p1 = position[cc] ; +// typename PFP::VEC3 p2 = position[map.phi1(cc)] ; +// +// map.cutEdge(cc); +// +// position[map.phi1(cc)] = (p1 + p2) * typename PFP::REAL(0.5) ; +// +// cc = map.phi2(map.phi_1(cc)); +// }while (cc != c); +// +// // cut faces +// do +// { +// Dart d1 = map.phi1(cc); +// Dart d2 = map.phi_1(cc); +// map.splitFace(d1,d2); +// cc = map.phi2(map.phi_1(cc));//map.Map2::alpha1(cc); +// }while (cc != c); +// +// //merge central faces by removing edges +// bool notFinished=true; +// do +// { +// Dart d1 = map.Map2::alpha1(cc); +// if (d1 == cc) // last edge is pending edge inside of face +// notFinished = false; +// map.deleteFace(cc); +// cc = d1; +// } while (notFinished); +// +// +// map.closeHole(map.phi1(map.phi1(map.phi2(f1)))); +// +// } +// } - //Fais a la couture !!!!! - unsigned int idface = map.getNewFaceId(); - map.setFaceId(map.phi2(f1),idface, FACE); } - - //FAIS a la couture !!!!!!! - //id pour toutes les aretes exterieurs des faces quadrangulees - unsigned int idedge = map.getEdgeId(f1); - map.setEdgeId(map.phi2(f1), idedge, DART); - map.setEdgeId( map.phi2(f2), idedge, DART); } - //LA copie de L'id est a gerer avec le sewVolumes normalement !!!!!! - //id pour les aretes interieurs : (i.e. 6 pour un hexa) - DartMarker mne(map); - for(std::vector::iterator it = newEdges.begin() ; it != newEdges.end() ; ++it) - { - if(!mne.isMarked(*it)) - { - unsigned int idedge = map.getNewEdgeId(); - map.setEdgeId(*it, idedge, EDGE); - mne.markOrbit(EDGE, *it); - } - } - } + //std::cout << "2e etape finished" << std::endl; + + +// { +// //Third step : 3-sew internal faces +// for (std::vector >::iterator it = subdividedfacesT.begin(); it != subdividedfacesT.end(); ++it) +// { +// Dart f1 = (*it).first; +// Dart f2 = (*it).second; +// +// +// +// if(map.phi3(map.phi2(f1)) == map.phi2(f1) && map.phi3(map.phi2(f2)) == map.phi2(f2)) +// { +// if(map.getEmbedding(VERTEX, map.phi_1(map.phi2(f2))) == map.getEmbedding(VERTEX, map.phi_1(map.phi2(f1)))) +// { +// map.Map3::sewVolumes(map.phi2(f2), map.phi2(f1)); +// } +// else +// { +// +// //id pour toutes les faces interieures +// map.sewVolumes(map.phi2(f2), map.phi2(f1)); +// +// +// } +// +// //Fais a la couture !!!!! +// unsigned int idface = map.getNewFaceId(); +// map.setFaceId(map.phi2(f1),idface, FACE); +// } +// +// +// //FAIS a la couture !!!!!!! +// //id pour toutes les aretes exterieurs des faces quadrangulees +// unsigned int idedge = map.getEdgeId(f1); +// map.setEdgeId(map.phi2(f1), idedge, DART); +// map.setEdgeId( map.phi2(f2), idedge, DART); +// +// } +// +// //LA copie de L'id est a gerer avec le sewVolumes normalement !!!!!! +// //id pour les aretes interieurs : (i.e. 16 pour un octa) +// DartMarker mne(map); +// for(std::vector::iterator it = newEdges.begin() ; it != newEdges.end() ; ++it) +// { +// if(!mne.isMarked(*it)) +// { +// unsigned int idedge = map.getNewEdgeId(); +// map.setEdgeId(*it, idedge, EDGE); +// mne.markOrbit(EDGE, *it); +// } +// } +// } +// +// { +// //Third step : 3-sew internal faces +// for (std::vector >::iterator it = subdividedfacesQ.begin(); it != subdividedfacesQ.end(); ++it) +// { +// Dart f1 = (*it).first; +// Dart f2 = (*it).second; +// +// if(map.phi3(map.phi2(f1)) == map.phi2(f1) && map.phi3(map.phi2(f2)) == map.phi2(f2)) +// { +// //id pour toutes les faces interieures +// map.sewVolumes(map.phi2(f2), map.phi2(f1)); +// +// //Fais a la couture !!!!! +// unsigned int idface = map.getNewFaceId(); +// map.setFaceId(map.phi2(f1),idface, FACE); +// } +// +// //FAIS a la couture !!!!!!! +// //id pour toutes les aretes exterieurs des faces quadrangulees +// unsigned int idedge = map.getEdgeId(f1); +// map.setEdgeId(map.phi2(f1), idedge, DART); +// map.setEdgeId( map.phi2(f2), idedge, DART); +// } +// //LA copie de L'id est a gerer avec le sewVolumes normalement !!!!!! +// //id pour les aretes interieurs : (i.e. 16 pour un octa) +// DartMarker mne(map); +// for(std::vector::iterator it = newEdges.begin() ; it != newEdges.end() ; ++it) +// { +// if(!mne.isMarked(*it)) +// { +// unsigned int idedge = map.getNewEdgeId(); +// map.setEdgeId(*it, idedge, EDGE); +// mne.markOrbit(EDGE, *it); +// } +// } +// } +// +// //cas tordu pour le prisme +// for (std::vector >::iterator it = subdividedfacesT.begin(); it != subdividedfacesT.end(); ++it) +// { +// Dart f1 = (*it).first; +// Dart f2 = (*it).second; +// +// if( !(map.Map2::faceDegree(f2) == 3 && map.Map2::faceDegree(map.phi2(f2)) == 3 && +// map.Map2::faceDegree(map.phi2(map.phi1(f2))) == 3 && map.Map2::faceDegree(map.phi2(map.phi_1(f2))) == 3)) +// { +// +// +// if(map.phi2(map.phi1(map.phi1(map.phi2(f1)))) == map.phi3(map.phi2(map.phi1(map.phi1(map.phi2(f1))))) && +// map.phi2(map.phi3(map.phi2(map.phi3(map.phi2(map.phi3(map.phi2(map.phi2(map.phi1(map.phi1(map.phi2(f1))))))))))) == +// map.phi3(map.phi2(map.phi3(map.phi2(map.phi3(map.phi2(map.phi3(map.phi2(map.phi2(map.phi1(map.phi1(map.phi2(f1)))))))))))) +// ) +// { +// map.sewVolumes(map.phi2(map.phi1(map.phi1(map.phi2(f1)))), +// map.phi2(map.phi3(map.phi2(map.phi3(map.phi2(map.phi3(map.phi1(map.phi1(map.phi2(f1)))))))))); +// } +// +// } +// } map.setCurrentLevel(cur) ; return subdividedfacesQ.begin()->first; } - - - /************************************************************************************************ * Simplification * ************************************************************************************************/ diff --git a/include/Algo/Import/import2tables.h b/include/Algo/Import/import2tables.h index 896dfb7967c9080747b05409e2e668149151c4fd..22273f38993ac362dfee50bd90eaa6ccfc1cf732 100644 --- a/include/Algo/Import/import2tables.h +++ b/include/Algo/Import/import2tables.h @@ -57,7 +57,7 @@ namespace Import namespace ImportVolumique { - enum ImportType { UNKNOWNVOLUME ,TET ,TRIANBGZ ,PLY }; + enum ImportType { UNKNOWNVOLUME ,TET ,TRIANBGZ ,PLY ,OFF, OBJ }; } diff --git a/include/Algo/Import/importMesh.hpp b/include/Algo/Import/importMesh.hpp index 4da9a8796f68fce5fe51c826ff50ef0f29c9e28b..3941d9cdfe746c8889b69469c65e452ec8272114 100644 --- a/include/Algo/Import/importMesh.hpp +++ b/include/Algo/Import/importMesh.hpp @@ -25,6 +25,7 @@ #include "Topology/generic/attributeHandler.h" #include "Topology/generic/autoAttributeHandler.h" #include "Container/fakeAttribute.h" +#include "Algo/Modelisation/polyhedron.h" namespace CGoGN { @@ -128,6 +129,111 @@ bool importMesh(typename PFP::MAP& map, MeshTablesSurface& mts) return true ; } + +template +bool importMeshSToV(typename PFP::MAP& map, MeshTablesSurface& mts, float dist) +{ + AutoAttributeHandler< NoMathIONameAttribute< std::vector > > vecDartsPerVertex(map, VERTEX, "incidents"); + unsigned nbf = mts.getNbFaces(); + int index = 0; + // buffer for tempo faces (used to remove degenerated edges) + std::vector edgesBuffer; + edgesBuffer.reserve(16); + + DartMarkerNoUnmark m(map) ; + + AttributeHandler position = map.template getAttribute(VERTEX, "position"); + std::vector backEdgesBuffer(mts.getNbVertices(), EMBNULL); + + // for each face of table -> create a prism + for(unsigned int i = 0; i < nbf; ++i) + { + // store face in buffer, removing degenerated edges + unsigned int nbe = mts.getNbEdgesFace(i); + edgesBuffer.clear(); + unsigned int prec = EMBNULL; + for (unsigned int j = 0; j < nbe; ++j) + { + unsigned int em = mts.getEmbIdx(index++); + if (em != prec) + { + prec = em; + edgesBuffer.push_back(em); + } + } + // check first/last vertices + if (edgesBuffer.front() == edgesBuffer.back()) + edgesBuffer.pop_back(); + + // create only non degenerated faces + nbe = edgesBuffer.size(); + if (nbe > 2) + { + Dart d = Algo::Modelisation::createPrism(map, nbe); + + //Embed the base faces + for (unsigned int j = 0; j < nbe; ++j) + { + unsigned int em = edgesBuffer[j]; // get embedding + + if(backEdgesBuffer[em] == EMBNULL) + { + unsigned int emn = map.newCell(VERTEX); + map.copyCell(VERTEX, emn, em); + backEdgesBuffer[em] = emn; + position[emn] += typename PFP::VEC3(0,0,dist); + } + + FunctorSetEmb fsetemb(map, VERTEX, em); + foreach_dart_of_orbit_in_parent(&map, VERTEX, d, fsetemb) ; + + //Embed the other base face + Dart d2 = map.phi1(map.phi1(map.phi2(d))); + unsigned int em2 = backEdgesBuffer[em]; + FunctorSetEmb fsetemb2(map, VERTEX, em2); + foreach_dart_of_orbit_in_parent(&map, VERTEX, d2, fsetemb2) ; + + m.mark(d) ; // mark on the fly to unmark on second loop + vecDartsPerVertex[em].push_back(d); // store incident darts for fast adjacency reconstruction + d = map.phi1(d); + } + + } + } + + // reconstruct neighbourhood + unsigned int nbBoundaryEdges = 0; + for (Dart d = map.begin(); d != map.end(); map.next(d)) + { + if (m.isMarked(d)) + { + // darts incident to end vertex of edge + std::vector& vec = vecDartsPerVertex[map.phi1(d)]; + + unsigned int embd = map.getEmbedding(VERTEX, d); + Dart good_dart = NIL; + for (typename std::vector::iterator it = vec.begin(); it != vec.end() && good_dart == NIL; ++it) + { + if (map.getEmbedding(VERTEX, map.phi1(*it)) == embd) + good_dart = *it; + } + + if (good_dart != NIL) + { + map.sewVolumes(map.phi2(d), map.phi2(good_dart), false); + m.unmarkOrbit(EDGE, d); + } + else + { + m.unmark(d); + ++nbBoundaryEdges; + } + } + } + + return true ; +} + template bool importMesh(typename PFP::MAP& map, MeshTablesVolume& mtv) { @@ -441,179 +547,40 @@ bool importMesh(typename PFP::MAP& map, const std::string& filename, std::vector return importMesh(map, mts); } -/* + template bool importMesh(typename PFP::MAP& map, const std::string& filename, std::vector& attrNames, ImportVolumique::ImportType kind) { - MeshTablesVolume mtv(map); + float dist = 5.0f; - if(!mtv.importMesh(filename, attrNames, kind)) - return false; + if(kind == ImportVolumique::OBJ) + { + MeshTablesSurface mts(map); - return importMesh(map, mtv); -} -*/ -// -// -// -// AutoAttributeHandler< NoMathIONameAttribute< std::vector > > vecDartsPerVertex(map, VERTEX, "incidents"); -// -// -// // Attributes container for vertex orbit -// AttributeContainer& vertexContainer = map.getAttributeContainer(VERTEX); -// -// AttributeHandler positions(idPositions,map); -// -// MeshTablesSurface mts(vertexContainer, positions); -// -// if (!mts.importMesh(filename,kind)) -// return false; -// -// // marker for phi2 reconstruction -// m = map.getNewMarker(); -// -// unsigned nbf = mts.getNbFaces(); -// int index = 0; -// // buffer for tempo faces (used to remove degenerated edges) -// std::vector edgesBuffer; -// edgesBuffer.reserve(8); -// -// // for each face of table -// for(unsigned int i = 0; i < nbf; ++i) -// { -// // store face in buffer, removing degenerated edges -// unsigned int nbe = mts.getNbEdgesFace(i); -// edgesBuffer.clear(); -// unsigned int prec=EMBNULL; -// for (unsigned int j=0; j2) -// { -// Dart d = map.newFace(nbe); -// for (unsigned int j=0; j(map, mts, dist); + + } + else + return false; +// else // { -// if (map.isMarkedDart(d, m)) -// { -// // darts incident to end vertex of edge -// std::vector& vec = vecDartsPerVertex[map.phi1(d)]; +// MeshTablesVolume mtv(map); // -// unsigned int embd = map.getEmbedding(VERTEX, d); -// unsigned int nbf=0; -// Dart good_dart; -// for (typename std::vector::iterator it = vec.begin(); it != vec.end(); ++it) -// { -// if ( map.getEmbedding(VERTEX,map.phi1(*it))==embd) -// { -// good_dart = *it; -// nbf++; -// } -// } // -// if (nbf==1) -// { -// if (good_dart == map.phi2(good_dart)) -// { -// map.sewFaces(d, good_dart); -// map.unmarkOrbit(EDGE, d, m); -// } -// } -// else -// { -// ++nbnm; -// } -// } -// } -// -// -//// return true; +// if(!mtv.importMesh(filename, attrNames, kind)) +// return false; // -// if (nbnm > 0) -// { -// if (closeObject) -// { -// Marker mb = map.closeMap(true); -//// // for all vertices -//// for (unsigned int index = 0; index < vecDartsEmb.size(); ++index) -//// { -//// // if vertex is on boundary -//// if (vecEmbNbFp[index] > 0) -//// { -//// // find first dart that is sewed to boundary -//// std::vector& vd = vecDartsEmb[index]; -//// typename std::vector::iterator jt = vd.begin(); -//// while (!map.isMarkedDart(*jt, m)) -//// jt++; -//// unsigned int P = map.getEmbedding(VERTEX, *jt); -//// // while vertex if a "non manifold point" -//// while (vecEmbNbFp[index] > 1) -//// { -//// Dart e = map.phi2(*jt); -//// // turn in boundary until we find same embedding -//// do -//// { -//// e = map.phi1(e); -//// // embedding of boundary darts on the fly -//// unsigned int emb = map.getEmbedding(VERTEX, map.phi1(map.phi2(e))); -//// map.setDartEmbedding(VERTEX, e, emb); -//// } while (map.getEmbedding(VERTEX, map.phi2(e)) != P); -//// // separate the face -//// map.phi1sew(map.phi2(*jt), e); -//// vecEmbNbFp[index]--; -//// } -//// // copy embedding of vertex of boundary of last face -//// Dart e = map.phi2(*jt); -//// Dart d = e; -//// if (map.getEmbedding(VERTEX, d) == EMBNULL) -//// { -//// do -//// { -//// unsigned int emb = map.getEmbedding(VERTEX, map.phi1(map.phi2(d))); -//// map.setDartEmbedding(VERTEX, d, emb); -//// d = map.phi1(d); -//// } while (d != e); -//// } -//// } -//// } -// map.unmarkAll(m); -// map.releaseMarker(m); -// m = mb; -// } -// else -// { -// CGoGNout << "Warning " << nbnm << " darts with phi2 fix points" << CGoGNendl; -// } +// return importMesh(map, mtv); // } -// -// return true; -//} +} + } // namespace Import diff --git a/include/Algo/Import/importTet.hpp b/include/Algo/Import/importTet.hpp index c624a4897b7a841c4901bdf3553e087d36be2e83..df32f58d366f865658df2644fffa0c19b4022d88 100644 --- a/include/Algo/Import/importTet.hpp +++ b/include/Algo/Import/importTet.hpp @@ -114,7 +114,7 @@ bool importTet(typename PFP::MAP& map, const std::string& filename, std::vector< oss >> nbe; //number of vertices = 4 assert(nbe == 4); - Dart d = Algo::Modelisation::Polyhedron::createPolyhedron(map, 4); + Dart d = Algo::Modelisation::createTetrahedron(map); Geom::Vec4ui pt; oss >> pt[0]; diff --git a/include/Algo/Import/importTs.hpp b/include/Algo/Import/importTs.hpp index 817f200718cf74bf641d160e2add253cab5b03d2..fc4b6c9c2f9cf11da4b6be5c6ed04bd690d4f28d 100644 --- a/include/Algo/Import/importTs.hpp +++ b/include/Algo/Import/importTs.hpp @@ -132,7 +132,7 @@ bool importTs(typename PFP::MAP& map, const std::string& filename, std::vector::createTetra(map); - Dart d = Algo::Modelisation::Polyhedron::createPolyhedron(map,4); + Dart d = Algo::Modelisation::createTetrahedron(map); Geom::Vec4ui pt; oss >> pt[0]; oss >> pt[1]; diff --git a/include/Algo/Modelisation/polyhedron.h b/include/Algo/Modelisation/polyhedron.h index f65c3ef55da9832faaa4a4aef2f864b71f4acc55..b2bd13058562daf4e10dd1b0487fee2c9006b50a 100644 --- a/include/Algo/Modelisation/polyhedron.h +++ b/include/Algo/Modelisation/polyhedron.h @@ -42,7 +42,7 @@ namespace Algo namespace Modelisation { -enum { NONE,GRID, CUBE, CYLINDER, CONE, SPHERE, TORE, COMPOSED }; +enum { NONE, GRID, CUBE, CYLINDER, CONE, SPHERE, TORE, COMPOSED }; /** * sudivide the all quads of primtive into 2 triangles @@ -70,6 +70,64 @@ enum { NONE,GRID, CUBE, CYLINDER, CONE, SPHERE, TORE, COMPOSED }; template void explodPolyhedron(typename PFP::MAP& map, Dart d, typename PFP::TVEC3 position); + + + + + +/** + * create a n-sided pyramid + */ +template +Dart createPyramid(typename PFP::MAP& map, unsigned int nbSides); + +/** + * create a n-sided prism + */ +template +Dart createPrism(typename PFP::MAP& map, unsigned int nbSides); + +/** + * create a n-sided diamond + */ +template +Dart createDiamond(typename PFP::MAP& map, unsigned int nbSides); + + + + +/** + * create a tetrahedron + */ +template +Dart createTetrahedron(typename PFP::MAP& map); + +/** + * create a hexahedron + */ +template +Dart createHexahedron(typename PFP::MAP& map); + +/** + * create a 3-sided prism + */ +template +Dart createTriangularPrism(typename PFP::MAP& map); + +/** + * create a 3-sided pyramid + */ +template +Dart createQuadrangularPyramid(typename PFP::MAP& map); + +/** + * create 4-sided diamond (i.e. an octahedron) + */ +template +Dart createOctahedron(typename PFP::MAP& map); + + + /** * class of geometric Polyhedron * It alloaw the creation of: @@ -82,7 +140,6 @@ void explodPolyhedron(typename PFP::MAP& map, Dart d, typename PFP::TVEC3 positi * * Topological creation methods are separated from embedding to * easily allow specific embedding. - */ template class Polyhedron @@ -167,30 +224,6 @@ public: */ Polyhedron(const Polyhedron& p1, const Polyhedron& p2); - /** - * create simple simple polyhedron (not handled by Polyhedron object) - */ - static Dart createPolyhedron(typename PFP::MAP& the_map, unsigned int nbFaces); - - /** - * create simple simple tetrahedron (not handled by Polyhedron object) - */ - static Dart createTetra(typename PFP::MAP& the_map); - - /** - * create simple simple pyramid (not handled by Polyhedron object) - */ - static Dart createPyra(typename PFP::MAP& the_map); - - /** - * create simple simple hexaedron (not handled by Polyhedron object) - */ - static Dart createHexa(typename PFP::MAP& the_map); - - /** - * create simple simple prism (not handled by Polyhedron object) - */ - static Dart createPrism(typename PFP::MAP& the_map); /* * get the reference dart diff --git a/include/Algo/Modelisation/polyhedron.hpp b/include/Algo/Modelisation/polyhedron.hpp index f7a6efc5defd73fa0c543796a227041a5a3bb132..92a7d77d18d3094e2e067975944ad9bbc6dfaa8c 100644 --- a/include/Algo/Modelisation/polyhedron.hpp +++ b/include/Algo/Modelisation/polyhedron.hpp @@ -31,6 +31,170 @@ namespace Algo namespace Modelisation { +/** + * create a n-sided pyramid + */ +template +Dart createPyramid(typename PFP::MAP& map, unsigned int n) +{ + Dart dres = Dart::nil(); + std::vector m_tableVertDarts; + m_tableVertDarts.reserve(n); + + // creation of triangles around circunference and storing vertices + for (unsigned int i = 0; i < n; ++i) + { + Dart d = map.newFace(3, false); + m_tableVertDarts.push_back(d); + } + + // sewing the triangles + for (unsigned int i = 0; i < n-1; ++i) + { + Dart d = m_tableVertDarts[i]; + d = map.phi_1(d); + Dart e = m_tableVertDarts[i+1]; + e = map.phi1(e); + map.sewFaces(d, e, false); + } + //sewing the last with the first + map.sewFaces(map.phi1(m_tableVertDarts[0]), map.phi_1(m_tableVertDarts[n-1]), false); + + //sewing the bottom face + Dart d1 = map.newFace(n, false); + dres = d1; + for(unsigned int i = 0; i < n ; ++i) + { + map.sewFaces(m_tableVertDarts[i], d1, false); + d1 = map.phi1(d1); + } + + //return a dart from the base + return dres; +} + +/** + * create a n-sided prism + */ +template +Dart createPrism(typename PFP::MAP& map, unsigned int n) +{ + Dart dres = Dart::nil(); + unsigned int nb = n*2; + std::vector m_tableVertDarts; + m_tableVertDarts.reserve(nb); + + // creation of quads around circunference and storing vertices + for (unsigned int i = 0; i < n; ++i) + { + Dart d = map.newFace(4, false); + m_tableVertDarts.push_back(d); + } + + // storing a dart from the vertex pointed by phi1(phi1(d)) + for (unsigned int i = 0; i < n; ++i) + { + m_tableVertDarts.push_back(map.phi1(map.phi1(m_tableVertDarts[i]))); + } + + // sewing the quads + for (unsigned int i = 0; i < n-1; ++i) + { + Dart d = m_tableVertDarts[i]; + d = map.phi_1(d); + Dart e = m_tableVertDarts[i+1]; + e = map.phi1(e); + map.sewFaces(d, e, false); + } + //sewing the last with the first + map.sewFaces(map.phi1(m_tableVertDarts[0]), map.phi_1(m_tableVertDarts[n-1]), false); + + //sewing the top & bottom faces + Dart d1 = map.newFace(n, false); + Dart d2 = map.newFace(n, false); + dres = d1; + for(unsigned int i = 0; i < n ; ++i) + { + map.sewFaces(m_tableVertDarts[i], d1, false); + map.sewFaces(m_tableVertDarts[n+i], d2, false); + d1 = map.phi1(d1); + d2 = map.phi_1(d2); + } + + //return a dart from the base + return dres; +} + +/** + * create a n-sided diamond + */ +template +Dart createDiamond(typename PFP::MAP& map, unsigned int nbSides) +{ + Dart res = Dart::nil(); + + Dart firstP = createPyramid(map,nbSides); + Dart secondP = createPyramid(map,nbSides); + + res = map.phi2(firstP); + + map.sewVolumes(firstP, secondP); + map.mergeVolumes(firstP); + + return res; +} + + + +/** + * create a 3-sided prism + */ +template +Dart createTriangularPrism(typename PFP::MAP& map) +{ + return createPrism(map, 3); +} + +/** + * create a hexahedron + */ +template +Dart createHexahedron(typename PFP::MAP& map) +{ + return createPrism(map, 4); +} + +/** + * create a tetrahedron + */ +template +Dart createTetrahedron(typename PFP::MAP& map) +{ + return createPyramid(map, 3); +} + +/** + * create a 4-sided pyramid + */ +template +Dart createQuadrangularPyramid(typename PFP::MAP& map) +{ + return createPyramid(map, 4); +} + +/** + * create an octahedron (i.e. 4-sided diamond) + */ +template +Dart createOctahedron(typename PFP::MAP& map) +{ + return createDiamond(map,4); +} + + + + + template void explodPolyhedron(typename PFP::MAP& map, Dart d, typename PFP::TVEC3 position) { @@ -160,125 +324,6 @@ Polyhedron::Polyhedron(const Polyhedron& p1, const Polyhedron& p2 m_center = center / typename PFP::REAL(m_tableVertDarts.size()); } -template -Dart Polyhedron::createTetra(typename PFP::MAP& the_map) -{ - Dart base = the_map.newFace(3, false); - - Dart side1 = the_map.newFace(3, false); - the_map.sewFaces(base, side1, false); - - Dart side2 = the_map.newFace(3, false); - the_map.sewFaces(the_map.phi1(base), side2, false); - the_map.sewFaces(the_map.phi_1(side1), the_map.phi1(side2), false); - - Dart side3 = the_map.newFace(3, false); - the_map.sewFaces(the_map.phi_1(base), side3, false); - the_map.sewFaces(the_map.phi_1(side2), the_map.phi1(side3), false); - - the_map.sewFaces(the_map.phi_1(side3), the_map.phi1(side1), false); - - return base; -} - -template -Dart Polyhedron::createPyra(typename PFP::MAP& the_map) -{ - Dart base = the_map.newFace(4, false); - - Dart side1 = the_map.newFace(3, false); - the_map.sewFaces(base, side1, false); - - Dart side2 = the_map.newFace(3, false); - the_map.sewFaces(the_map.phi1(base), side2, false); - the_map.sewFaces(the_map.phi_1(side1), the_map.phi1(side2), false); - - Dart side3 = the_map.newFace(3, false); - the_map.sewFaces(the_map.phi1(the_map.phi1(base)), side3, false); - the_map.sewFaces(the_map.phi_1(side2), the_map.phi1(side3), false); - - Dart side4 = the_map.newFace(3, false); - the_map.sewFaces(the_map.phi_1(base), side4, false); - the_map.sewFaces(the_map.phi_1(side3), the_map.phi1(side4), false); - - the_map.sewFaces(the_map.phi_1(side4), the_map.phi1(side1), false); - - return base; -} - -template -Dart Polyhedron::createHexa(typename PFP::MAP& the_map) -{ - Dart base = the_map.newFace(4, false); - - Dart side1 = the_map.newFace(4, false); - the_map.sewFaces(base, side1, false); - - Dart side2 = the_map.newFace(4, false); - the_map.sewFaces(the_map.phi1(base), side2, false); - the_map.sewFaces(the_map.phi_1(side1), the_map.phi1(side2), false); - - Dart side3 = the_map.newFace(4, false); - the_map.sewFaces(the_map.phi1(the_map.phi1(base)), side3, false); - the_map.sewFaces(the_map.phi_1(side2), the_map.phi1(side3), false); - - Dart side4 = the_map.newFace(4, false); - the_map.sewFaces(the_map.phi_1(base), side4, false); - the_map.sewFaces(the_map.phi_1(side3), the_map.phi1(side4), false); - - the_map.sewFaces(the_map.phi_1(side4), the_map.phi1(side1), false); - - Dart top = the_map.newFace(4, false); - the_map.sewFaces(top, the_map.phi1(the_map.phi1(side1)), false); - the_map.sewFaces(the_map.phi_1(top), the_map.phi1(the_map.phi1(side2)), false); - the_map.sewFaces(the_map.phi1(the_map.phi1(top)), the_map.phi1(the_map.phi1(side3)), false); - the_map.sewFaces(the_map.phi1(top), the_map.phi1(the_map.phi1(side4)), false); - - return base; -} - -template -Dart Polyhedron::createPrism(typename PFP::MAP& the_map) -{ - Dart base = the_map.newFace(3, false); - - Dart side1 = the_map.newFace(4, false); - the_map.sewFaces(base, side1, false); - - Dart side2 = the_map.newFace(4, false); - the_map.sewFaces(the_map.phi1(base), side2, false); - the_map.sewFaces(the_map.phi_1(side1), the_map.phi1(side2), false); - - Dart side3 = the_map.newFace(4, false); - the_map.sewFaces(the_map.phi1(the_map.phi1(base)), side3, false); - the_map.sewFaces(the_map.phi_1(side2), the_map.phi1(side3), false); - - the_map.sewFaces(the_map.phi_1(side3), the_map.phi1(side1), false); - - Dart top = the_map.newFace(3, false); - the_map.sewFaces(top, the_map.phi1(the_map.phi1(side1)), false); - the_map.sewFaces(the_map.phi_1(top), the_map.phi1(the_map.phi1(side2)), false); - the_map.sewFaces(the_map.phi1(top), the_map.phi1(the_map.phi1(side3)), false); - - return base; -} - -template -Dart Polyhedron::createPolyhedron(typename PFP::MAP& the_map, unsigned int n) -{ - Dart d; - switch (n) - { - case 4 : d = createTetra(the_map); - break; - case 5 : d = createPyra(the_map); - break; - case 6 : d = createHexa(the_map); - break; - } - return d; -} - template Dart Polyhedron::grid_topo(unsigned int x, unsigned int y) { diff --git a/include/Algo/Modelisation/subdivision.hpp b/include/Algo/Modelisation/subdivision.hpp index 08574a3efc8a4449a2caa968a678ca05387ab8f6..aeb8b914dd5341dbd00b5ba3b1a0d4de62822ff5 100644 --- a/include/Algo/Modelisation/subdivision.hpp +++ b/include/Algo/Modelisation/subdivision.hpp @@ -46,6 +46,10 @@ Dart trianguleFace(typename PFP::MAP& map, Dart d) if (map.phi1(d1) == d) CGoGNout << "Warning: triangulation of a face with only two edges" << CGoGNendl; + std::cout << "d = " << d << std::endl; + std::cout << "map.phi1(d) = " << map.phi1(d) << std::endl; + std::cout << "map.phi_1(d) = " << map.phi_1(d) << std::endl; + map.splitFace(d, d1) ; map.cutEdge(map.phi_1(d)) ; Dart x = map.phi2(map.phi_1(d)) ; diff --git a/src/Topology/map/embeddedMap3.cpp b/src/Topology/map/embeddedMap3.cpp index c529321bf5d0167fdc1ca21f4dfb853b8411cdc7..bbd957b2a075158b416193d54057635d51f7d271 100644 --- a/src/Topology/map/embeddedMap3.cpp +++ b/src/Topology/map/embeddedMap3.cpp @@ -412,6 +412,19 @@ bool EmbeddedMap3::check() std::cout << "Check: embedding begin" << std::endl ; + std::cout << "nb vertex orbits : " << getNbOrbits(VERTEX) << std::endl ; + std::cout << "nb vertex cells : " << m_attribs[VERTEX].size() << std::endl ; + + std::cout << "nb edge orbits : " << getNbOrbits(EDGE) << std::endl ; + std::cout << "nb edge cells : " << m_attribs[EDGE].size() << std::endl ; + + std::cout << "nb face orbits : " << getNbOrbits(FACE) << std::endl ; + std::cout << "nb face cells : " << m_attribs[FACE].size() << std::endl ; + + std::cout << "nb volume orbits : " << getNbOrbits(VOLUME) << std::endl ; + std::cout << "nb volume cells : " << m_attribs[VOLUME].size() << std::endl ; + + for(Dart d = begin(); d != end(); next(d)) { if(isOrbitEmbedded(VERTEX)) @@ -466,18 +479,6 @@ bool EmbeddedMap3::check() std::cout << "Check: embedding ok" << std::endl ; - std::cout << "nb vertex orbits : " << getNbOrbits(VERTEX) << std::endl ; - std::cout << "nb vertex cells : " << m_attribs[VERTEX].size() << std::endl ; - - std::cout << "nb edge orbits : " << getNbOrbits(EDGE) << std::endl ; - std::cout << "nb edge cells : " << m_attribs[EDGE].size() << std::endl ; - - std::cout << "nb face orbits : " << getNbOrbits(FACE) << std::endl ; - std::cout << "nb face cells : " << m_attribs[FACE].size() << std::endl ; - - std::cout << "nb volume orbits : " << getNbOrbits(VOLUME) << std::endl ; - std::cout << "nb volume cells : " << m_attribs[VOLUME].size() << std::endl ; - return true ; } diff --git a/src/Topology/map/map3.cpp b/src/Topology/map/map3.cpp index 9f9316e18022790bd0d31421d890c3f59fa1e39f..4f68a3f39c83e1976acde702c8007e41c15d9c33 100644 --- a/src/Topology/map/map3.cpp +++ b/src/Topology/map/map3.cpp @@ -475,7 +475,7 @@ bool Map3::mergeVolumes(Dart d) void Map3::splitVolume(std::vector& vd) { - //assert(checkSimpleOrientedPath(vd)) ; + assert(checkSimpleOrientedPath(vd)) ; Dart e = vd.front(); Dart e2 = phi2(e); @@ -489,6 +489,7 @@ void Map3::splitVolume(std::vector& vd) //sew the two connected components Map3::sewVolumes(phi2(e), phi2(e2), false); + //Map3::sewVolumes(phi2(e), e2, false); } /*! @name Topological Queries