Commit 22a1e9b7 authored by untereiner's avatar untereiner

Ajout d'un algo de subdiv volumique generalise + neighborhoodLevelDiffersByOne

parent 38e72f5d
......@@ -264,6 +264,10 @@ public:
*/
bool volumeIsSubdividedOnce(Dart d);
/**
*
*/
bool neighborhoodLevelDiffersByOne(Dart d);
} ;
......
......@@ -53,6 +53,9 @@ Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positi
template <typename PFP>
Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position);
template <typename PFP>
Dart subdivideVolumeOld(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position);
//template <typename PFP>
//void subdivideLoop(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position);
......
......@@ -168,9 +168,6 @@ void subdivideFace(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position
map.setCurrentLevel(cur) ;
}
template <typename PFP>
Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position)
{
......@@ -364,10 +361,6 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos
{
std::cout << "pyramide" << std::endl;
map.splitFace(dd, map.phi1(map.phi1(dd)));
//tester si besoin de fermer f2 (par exemple pas besoin pour hexa... mais pour tet, octa, prisme oui)
//map.closeHole(f2);
//retenir un truc pour le sew/unsew final de l'octa au milieu
}
else
{
......@@ -452,7 +445,7 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos
// //if(Algo::Modelisation::Tetrahedron::isTetrahedron<PFP>(map,f2))
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)
{
{ //cas du tetrahedre
std::cout << "ajout d'une face" << std::endl;
......@@ -534,108 +527,119 @@ Dart subdivideVolumeGen(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& pos
std::cout << "2e etape finished" << std::endl;
{
//Third step : 3-sew internal faces
for (std::vector<std::pair<Dart,Dart> >::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 !!!!!
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<Dart>::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<std::pair<Dart,Dart> >::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<Dart>::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);
}
}
}
for (std::vector<std::pair<Dart,Dart> >::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.phi3(map.phi2(map.phi3(map.phi2(map.phi3(map.phi1(map.phi1(map.phi2(f1))))))))),
map.phi2(map.phi1(map.phi1(map.phi2(f1)))));
}
}
}
// {
// //Third step : 3-sew internal faces
// for (std::vector<std::pair<Dart,Dart> >::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<Dart>::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<std::pair<Dart,Dart> >::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<Dart>::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<std::pair<Dart,Dart> >::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) ;
......@@ -651,6 +655,7 @@ Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positi
{
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);
......@@ -800,6 +805,7 @@ Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positi
map.closeHole(f1);
//fonction qui calcule le degree max des faces atour d'un sommet
unsigned int fdeg = map.faceDegree(map.phi2(f1));
......@@ -868,7 +874,7 @@ Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positi
else
{
map.closeHole(f2);
//map.sewVolumes(map.phi2(f1),map.phi2(f2));
map.sewVolumes(map.phi2(f1),map.phi2(f2));
unsigned int idface = map.getNewFaceId();
map.setFaceId(map.phi2(f1),idface, FACE);
......@@ -978,203 +984,201 @@ Dart subdivideVolume(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& positi
}
//template <typename PFP>
//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") ;
//
// unsigned int vLevel = map.volumeLevel(d);
// Dart old = map.volumeOldestDart(d);
//
// unsigned int cur = map.getCurrentLevel();
// map.setCurrentLevel(vLevel);
//
//
// /*
// * au niveau du volume courant i
// * stockage d'un brin de chaque face de celui-ci
// * avec calcul du centroid
// */
//
// DartMarkerStore mf(map); // Lock a face marker to save one dart per face
// CellMarker mv(map, VERTEX);
//
// typename PFP::VEC3 volCenter;
// unsigned count = 0 ;
//
// //Store faces that are traversed and start with the face of d
// std::vector<Dart> visitedFaces;
// visitedFaces.reserve(20);
// visitedFaces.push_back(old);
//
// //Store the edges before the cutEdge
// std::vector<Dart> oldEdges;
// oldEdges.reserve(20);
//
// mf.markOrbit(FACE, old) ;
//
// for(std::vector<Dart>::iterator face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
// {
// Dart e = *face ;
// do
// {
// //add one old edge per vertex to the old edge list
// //compute volume centroid
// if(!mv.isMarked(e))
// {
// mv.mark(e);
// volCenter += position[e];
// ++count;
// oldEdges.push_back(e);
// }
//
// // add all face neighbours to the table
// Dart ee = map.phi2(e) ;
// if(!mf.isMarked(ee)) // not already marked
// {
// visitedFaces.push_back(ee) ;
// mf.markOrbit(FACE, ee) ;
// }
//
// e = map.phi1(e) ;
// } while(e != *face) ;
// }
//
// volCenter /= typename PFP::REAL(count) ;
//
// /*
// * Subdivision
// */
//
// //Store the darts from quadrangulated faces
// std::vector<std::pair<Dart,Dart> > subdividedfaces;
// subdividedfaces.reserve(25);
//
// //First step : subdivide edges and faces
// //creates a i+1 edge level and i+1 face level
// for (std::vector<Dart>::iterator face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
// {
// Dart d = *face;
//
// //if needed subdivide face
// if(!map.faceIsSubdivided(d))
// Algo::IHM::subdivideFace<PFP>(map, d, position);
//
// //save a dart from the subdivided face
// unsigned int cur = map.getCurrentLevel() ;
//
// unsigned int fLevel = map.faceLevel(d) + 1; //puisque dans tous les cas, la face est subdivisee
// map.setCurrentLevel(fLevel) ;
//
//
// //le brin est forcement du niveau cur
// Dart cf = map.phi1(d);
// Dart e = cf;
// do
// {
// subdividedfaces.push_back(std::pair<Dart,Dart>(e,map.phi2(e)));
// e = map.phi2(map.phi1(e));
// }while (e != cf);
//
// map.setCurrentLevel(cur);
// }
//
// map.setCurrentLevel(vLevel + 1) ; // go to the next level to perform volume subdivision
//
// std::vector<Dart> newEdges; //save darts from inner edges
// newEdges.reserve(50);
//
// //Second step : deconnect each corner, close each hole, subdivide each new face into 3
// for (std::vector<Dart>::iterator edge = oldEdges.begin(); edge != oldEdges.end(); ++edge)
// {
// Dart e = *edge;
//
// Dart f1 = map.phi1(*edge);
//
// do
// {
// map.unsewFaces(map.phi1(map.phi1(e)));
//
// //TODO utile ?
// //if(map.phi2(map.phi1(e)) != map.phi1(e))
// map.unsewFaces(map.phi1(e));
//
// e = map.phi2(map.phi_1(e));
// }
// while(e != *edge);
//
// map.closeHole(f1);
//
// 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)) ;
//
// 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(map.phi1(ne)));
//
// //A Verifier !!
// map.splitFace(ne, dd) ;
//
// newEdges.push_back(map.phi1(dd));
//
// ne = map.phi2(map.phi_1(ne));
// dd = map.phi1(map.phi1(dd));
// }
// while(dd != stop);
// }
//
// //Third step : 3-sew internal faces
// for (std::vector<std::pair<Dart,Dart> >::iterator it = subdividedfaces.begin(); it != subdividedfaces.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(f1), map.phi2(f2));
//
// //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<Dart>::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 subdividedfaces.begin()->first;
//}
template <typename PFP>
Dart subdivideVolumeOld(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") ;
unsigned int vLevel = map.volumeLevel(d);
Dart old = map.volumeOldestDart(d);
unsigned int cur = map.getCurrentLevel();
map.setCurrentLevel(vLevel);
/*
* au niveau du volume courant i
* stockage d'un brin de chaque face de celui-ci
* avec calcul du centroid
*/
DartMarkerStore mf(map); // Lock a face marker to save one dart per face
CellMarker mv(map, VERTEX);
typename PFP::VEC3 volCenter;
unsigned count = 0 ;
//Store faces that are traversed and start with the face of d
std::vector<Dart> visitedFaces;
visitedFaces.reserve(20);
visitedFaces.push_back(old);
//Store the edges before the cutEdge
std::vector<Dart> oldEdges;
oldEdges.reserve(20);
mf.markOrbit(FACE, old) ;
for(std::vector<Dart>::iterator face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
{
Dart e = *face ;
do
{
//add one old edge per vertex to the old edge list
//compute volume centroid
if(!mv.isMarked(e))
{
mv.mark(e);
volCenter += position[e];
++count;
oldEdges.push_back(e);
}
// add all face neighbours to the table
Dart ee = map.phi2(e) ;
if(!mf.isMarked(ee)) // not already marked
{
visitedFaces.push_back(ee) ;
mf.markOrbit(FACE, ee) ;
}
e = map.phi1(e) ;
} while(e != *face) ;
}
volCenter /= typename PFP::REAL(count) ;
/*
* Subdivision
*/
//Store the darts from quadrangulated faces
std::vector<std::pair<Dart,Dart> > subdividedfaces;
subdividedfaces.reserve(25);
//First step : subdivide edges and faces
//creates a i+1 edge level and i+1 face level
for (std::vector<Dart>::iterator face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
{
Dart d = *face;
//if needed subdivide face
if(!map.faceIsSubdivided(d))
Algo::IHM::subdivideFace<PFP>(map, d, position);
//save a dart from the subdivided face
unsigned int cur = map.getCurrentLevel() ;
unsigned int fLevel = map.faceLevel(d) + 1; //puisque dans tous les cas, la face est subdivisee
map.setCurrentLevel(fLevel) ;
//le brin est forcement du niveau cur
Dart cf = map.phi1(d);
Dart e = cf;
do
{
subdividedfaces.push_back(std::pair<Dart,Dart>(e,map.phi2(e)));
e = map.phi2(map.phi1(e));
}while (e != cf);
map.setCurrentLevel(cur);
}
map.setCurrentLevel(vLevel + 1) ; // go to the next level to perform volume subdivision
std::vector<Dart> newEdges; //save darts from inner edges
newEdges.reserve(50);
//Second step : deconnect each corner, close each hole, subdivide each new face into 3
for (std::vector<Dart>::iterator edge = oldEdges.begin(); edge != oldEdges.end(); ++edge)
{
Dart e = *edge;
Dart f1 = map.phi1(*edge);
do
{
map.unsewFaces(map.phi1(map.phi1(e)));
map.unsewFaces(map.phi1(e));
e = map.phi2(map.phi_1(e));
}
while(e != *edge);
map.closeHole(f1);
Dart old = map.phi2(map.phi1(e));
Dart dd = map.phi1(map.phi1(old)) ;