Commit 3a528102 authored by untereiner's avatar untereiner
Browse files

Tetrahedra swaps: 2-3, 3-2, 2-2, 4-4, 5-4

Tetrahedra flips: 1-3, 1-4
Tetrahedra edge bisection
parent 8ea0bcc9
......@@ -95,6 +95,9 @@ void catmullClarkVol(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>
catmullClarkVol<PFP, VertexAttribute<typename PFP::VEC3>, typename PFP::VEC3>(map, position, selected);
}
template <typename PFP>
void sqrt3Vol(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position, const FunctorSelect& selected = allDarts);
} // namespace Modelisation
} // namespace Algo
......
......@@ -626,10 +626,57 @@ void catmullClarkVol(typename PFP::MAP& map, EMBV& attributs, const FunctorSelec
// {
// map.embedOrbit<VERTEX>(map.phi2(map.phi1(d)), map.getEmbedding<VERTEX>(map.phi2(map.phi1(d))));
// }
}
template <typename PFP>
void sqrt3Vol(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position, const FunctorSelect& selected)
{
DartMarkerStore m(map);
//
// 1-4 flip of all tetrahedra
//
TraversorW<typename PFP::MAP> tW(map,selected);
for(Dart dit = tW.begin() ; dit != tW.end() ; dit = tW.next())
{
if(!map.isBoundaryFace(dit))
m.markOrbit<VOLUME>(dit);
Algo::Modelisation::Tetrahedralization::flip1To4<PFP>(map, dit, position);
}
//
// 2-3 swap of all old interior faces
//
TraversorF<typename PFP::MAP> tF(map,selected);
for(Dart dit = tF.begin() ; dit != tF.end() ; dit = tF.next())
{
if(m.isMarked(dit))
{
m.unmarkOrbit<FACE>(dit);
Algo::Modelisation::Tetrahedralization::swap2To3<PFP>(map, dit);
}
}
//
// 1-3 flip of all boundary tetrahedra
//
TraversorW<typename PFP::MAP> tWb(map,selected);
for(Dart dit = tWb.begin() ; dit != tWb.end() ; dit = tWb.next())
{
if(map.isBoundaryVolume(dit))
{
Algo::Modelisation::Tetrahedralization::flip1To3<PFP>(map, dit, position);
}
}
//
// edge-removal on all old boundary edges
//
}
} //namespace Modelisation
} //namespace Algo
......
......@@ -50,96 +50,107 @@ void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d);
template <typename PFP>
void hexahedronsToTetrahedrons(typename PFP::MAP& map);
template <typename PFP>
void tetrahedrizeVolume(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position);
/************************************************************************************************
* Collapse / Split Operators
* Collapse / Split Operators *
************************************************************************************************/
//!
/*!
*
*/
template <typename PFP>
Dart splitVertex(typename PFP::MAP& map, std::vector<Dart>& vd);
/************************************************************************************************
* Tetrahedron functions *
* Tetrahedron functions *
************************************************************************************************/
/**
* test if the volume is a tetrahedron
* @param map
* @param a dart from the volume
//!
/*!
*
*/
template <typename PFP>
bool isTetrahedron(typename PFP::MAP& the_map, Dart d, unsigned int thread=0);
/**
* test if a mesh (or submesh) is a tetrahedral mesh
* @param map
* @param selected
//!
/*!
*
*/
template <typename PFP>
bool isTetrahedralization(typename PFP::MAP& map, const FunctorSelect& selected = allDarts);
/************************************************************************************************
* Swap Functions *
* Swap Functions *
************************************************************************************************/
/**
* Swap a configuration of 2 Tetrahedron to another one
* @param map
* @param d a dart from the face between the two tetahedron to swap
//!
/*!
*
* TODO ajouter image
*/
template <typename PFP>
void swap2To2(typename PFP::MAP& map, Dart d);
Dart swap2To2(typename PFP::MAP& map, Dart d);
/**
//!
/*!
*
*/
template <typename PFP>
void swap4To4(typename PFP::MAP& map, Dart d);
/**
* Swap a configuration of 3 tetrahedron to another one with 2 tetrahedron
* @param map
* @param d
*
* TODO ajouter image
//!
/*!
*
*/
template <typename PFP>
void swap3To2(typename PFP::MAP& map, Dart d);
Dart swap3To2(typename PFP::MAP& map, Dart d);
/**
//!
/*!
*
*/
template <typename PFP>
Dart swap2To3(typename PFP::MAP& map, Dart d);
/**
//!
/*!
*
*/
template <typename PFP>
void swap5To4(typename PFP::MAP& the_map, Dart d, VertexAttribute<typename PFP::VEC3>& positions);
Dart swap5To4(typename PFP::MAP& map, Dart d);
/************************************************************************************************
* Flip Functions *
* Flip Functions *
************************************************************************************************/
/*
//!
/*!
*
*/
template <typename PFP>
void flip1To4(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP::VEC3>& position);
Dart flip1To4(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP::VEC3>& position);
/**
//!
/*!
*
*/
template <typename PFP>
Dart flip1To3(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP::VEC3>& position);
/************************************************************************************************
* Bisection Functions *
************************************************************************************************/
//!
/*!
*
*/
template <typename PFP>
void edgeBisection(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP::VEC3>& position);
Dart edgeBisection(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP::VEC3>& position);
} // namespace Tetrahedralization
......
......@@ -24,6 +24,7 @@
#include "Algo/Modelisation/subdivision3.h"
#include "Topology/generic/traversor3.h"
#include "Algo/Modelisation/subdivision.h"
namespace CGoGN
{
......@@ -227,9 +228,9 @@ Dart splitVertex(typename PFP::MAP& map, std::vector<Dart>& vd)
return dres;
}
/************************************************************************************************
* Tetrahedron functions *
************************************************************************************************/
/*************************************************************************************************
* Tetrahedron functions *
*************************************************************************************************/
template <typename PFP>
bool isTetrahedron(typename PFP::MAP& the_map, Dart d, unsigned int thread)
......@@ -256,8 +257,8 @@ bool isTetrahedron(typename PFP::MAP& the_map, Dart d, unsigned int thread)
template <typename PFP>
bool isTetrahedralization(typename PFP::MAP& map, const FunctorSelect& selected)
{
TraversorV<typename PFP::MAP> travV(map, selected);
for(Dart dit = travV.begin() ; dit != travV.end() ; dit = travV.next())
TraversorW<typename PFP::MAP> travW(map, selected);
for(Dart dit = travW.begin() ; dit != travW.end() ; dit = travW.next())
{
if(!isTetrahedron<PFP>(map, dit))
return false;
......@@ -266,159 +267,39 @@ bool isTetrahedralization(typename PFP::MAP& map, const FunctorSelect& selected)
return true;
}
/************************************************************************************************
* Topological functions *
************************************************************************************************/
//sew a face into the edge
template <typename PFP>
Dart linkIntoEdge(typename PFP::MAP& map, Dart d, Dart e)
{
Dart e2 = map.phi2(e);
Dart d3 = map.phi3(d);
//Decoud les 2 brins
map.unsewFaces(e);
//Coudre la nouvelle face au milieu de l'ancienne arête
map.sewFaces(e2,d3);
map.sewFaces(e,d);
map.setDartEmbedding<VERTEX>(d, map.getEmbedding<VERTEX>(e2)) ;
map.setDartEmbedding<VERTEX>(d3, map.getEmbedding<VERTEX>(e)) ;
return e2;
}
//unsew a face from the edge
template <typename PFP>
void unlinkFromEdge(typename PFP::MAP& map, Dart d)
{
Dart d3 = map.phi3(d);
// if(map.isOrbitEmbedded<VERTEX>())
// {
// //Si la face n'est pas libre en phi2
// if(map.phi2(d) != d && map.phi2(d3) != d3)
// {
// unsigned int dVEmb = map.getEmbedding<VERTEX>(d) ;
// if(dVEmb != EMBNULL)
// {
// map.embedOrbit<VERTEX>(d, dVEmb) ;
// map.setDartEmbedding<VERTEX>(d, EMBNULL) ;
// }
//
// unsigned int d3VEmb = map.getEmbedding<VERTEX>(d3) ;
// if(d3VEmb != EMBNULL)
// {
// map.embedOrbit<VERTEX>(d3, d3VEmb) ;
// map.setDartEmbedding<VERTEX>(d3, EMBNULL) ;
// }
// }
// //Si la face est libre en phi2
// else
// {
//
// }
// }
Dart e2 = map.phi2(d3);
Dart d2 = map.phi2(d);
map.unsewFaces(e2);
map.unsewFaces(d2);
map.sewFaces(d2,e2);
}
template <typename PFP>
void unlinkFace(typename PFP::MAP& map, Dart d)
{
Dart e = d;
do
{
unlinkFromEdge<PFP>(map, e);
e = map.phi1(e);
}
while (e != d);
}
template <typename PFP>
void insertFace(typename PFP::MAP& map, Dart d, Dart nF)
{
Dart dd = d;
Dart nFd = nF;
do {
//TODO linkIntoEdge
Dart d2 = map.phi2(dd);
map.unsewFaces(dd);
map.sewFaces(dd,nFd);
map.sewFaces(d2,map.phi3(nFd));
map.setDartEmbedding<VERTEX>(nFd, map.getEmbedding<VERTEX>(d2)) ;
map.setDartEmbedding<VERTEX>(map.phi3(nFd), map.getEmbedding<VERTEX>(dd)) ;
dd = map.phi_1(map.phi2(map.phi_1(dd)));
nFd = map.phi1(nFd);
} while (nFd != nF);
}
/***********************************************************************************************
* swap functions *
***********************************************************************************************/
//ok
template <typename PFP>
void swap2To2(typename PFP::MAP& map, Dart d)
Dart swap2To2(typename PFP::MAP& map, Dart d)
{
//save a dart from a non-modifed-face of one tetrahedron
Dart r = map.phi2(d);
//detach common face from tetrahedron from the rest of the faces
unlinkFace<PFP>(map, d);
std::vector<Dart> edges;
//flip the middle edge
map.flipEdge(r);
Dart e = map.phi2(r);
Dart d2_1 = map.phi_1(map.phi2(d));
map.mergeVolumes(d);
map.mergeFaces(map.phi1(d2_1));
map.splitFace(d2_1, map.phi1(map.phi1(d2_1)));
unsigned int dVEmb = map.getEmbedding<VERTEX>(r) ;
if(dVEmb != EMBNULL)
{
map.setDartEmbedding<VERTEX>(map.phi_1(r), dVEmb) ;
map.setDartEmbedding<VERTEX>(r, EMBNULL) ;
}
unsigned int eVEmb = map.getEmbedding<VERTEX>(e) ;
if(eVEmb != EMBNULL)
Dart stop = map.phi_1(d2_1);
Dart dit = stop;
do
{
map.setDartEmbedding<VERTEX>(map.phi_1(e), eVEmb) ;
map.setDartEmbedding<VERTEX>(e, EMBNULL) ;
edges.push_back(dit);
dit = map.phi1(map.phi2(map.phi1(dit)));
}
while(dit != stop);
//insert the face in the flipped edge
insertFace<PFP>(map, r, d);
Dart dd = d;
do {
Dart e = map.phi2(dd);
Dart e2= map.phi2(map.phi3(dd));
map.setDartEmbedding<VERTEX>(dd, map.getEmbedding<VERTEX>(e2)) ;
map.setDartEmbedding<VERTEX>(map.phi3(dd), map.getEmbedding<VERTEX>(e)) ;
dd = map.phi1(dd);
} while( dd!=d);
map.splitVolume(edges);
return map.phi2(stop);
}
//ok
template <typename PFP>
void swap4To4(typename PFP::MAP& map, Dart d)
{
//!! 4 decouture inutile, seule l'intersection du centre doit etre decousu puis recousu
Dart e = map.phi2(map.phi3(d));
Dart dd = map.phi2(d);
......@@ -426,80 +307,36 @@ void swap4To4(typename PFP::MAP& map, Dart d)
map.unsewVolumes(d);
map.unsewVolumes(map.phi2(map.phi3(dd)));
Algo::Modelisation::Tetrahedralization::swap2To2<PFP>(map, dd);
Algo::Modelisation::Tetrahedralization::swap2To2<PFP>(map, e);
Dart d1 = Algo::Modelisation::Tetrahedralization::swap2To2<PFP>(map, dd);
Dart d2 = Algo::Modelisation::Tetrahedralization::swap2To2<PFP>(map, e);
//sew middle darts so that they do not cross
map.sewVolumes(d,map.phi2(map.phi3(e)));
map.sewVolumes(map.phi2(map.phi3(dd)),map.phi2(e));
map.sewVolumes(map.phi2(d1),map.phi2(map.phi3(d2)));
map.sewVolumes(map.phi2(map.phi3(d1)),map.phi2(d2));
}
template <typename PFP>
void swap3To2(typename PFP::MAP& map, Dart d)
Dart swap3To2(typename PFP::MAP& map, Dart d)
{
Dart en1 = map.phi_1(map.phi2(d));
Dart en2 = map.phi1(d);
Dart fi = map.phi2(en1);
//Decouture de la premiere face
unlinkFromEdge<PFP>(map, map.phi2(en1));
unlinkFromEdge<PFP>(map, map.phi2(en2));
//Decouture de la seconde face
en1 = map.phi1(map.phi2(en1));
en2 = map.phi_1(map.phi2(en2));
unlinkFromEdge<PFP>(map, map.phi2(en1));
unlinkFromEdge<PFP>(map, map.phi2(en2));
//Decouture de la troisieme face
en1 = map.phi1(map.phi2(en1));
en2 = map.phi_1(map.phi2(en2));
unlinkFromEdge<PFP>(map, map.phi2(en1));
unlinkFromEdge<PFP>(map, map.phi2(en2));
//Faces interieurs
Dart fi2 = map.phi2(map.phi1(fi));
Dart fi3 = map.phi2(map.phi3(map.phi1(fi)));
map.deleteFace(fi);
map.deleteFace(fi2);
map.deleteFace(fi3);
//Couture de cette face au milieu des 2 tetraedres
Dart f = map.newFace(3);
Dart fprim = map.newFace(3);
map.sewVolumes(f,fprim);
// Dart en = linkIntoEdge(f,d);
Dart ff=f;
Dart en= d;
do {
Dart e2 = map.phi2(en);
Dart d3 = map.phi3(ff);
map.unsewFaces(en);
map.sewFaces(e2,d3);
map.sewFaces(en,ff);
std::vector<Dart> edges;
en = map.phi_1(map.phi2(map.phi_1(en)));
ff = map.phi1(ff);
} while(ff!=f);
Dart dd = d;
do {
Dart e = map.phi2(map.phi3(map.phi2(dd)));
unsigned int eVEmb = map.getEmbedding<VERTEX>(e) ;
unsigned int ddVEmb = map.getEmbedding<VERTEX>(dd) ;
map.setDartEmbedding<VERTEX>(map.phi2(dd), eVEmb) ;
map.setDartEmbedding<VERTEX>(map.phi2(e), ddVEmb) ;
Dart stop = map.phi_1(map.phi2(map.phi1(d)));
Dart d2 = map.phi2(d);
Dart d21 = map.phi1(d2);
map.mergeVolumes(d);
map.mergeFaces(d2);
map.mergeVolumes(d21);
dd = map.phi1(map.phi2(map.phi1(dd)));
} while( dd!=d);
Dart dit = stop;
do
{
edges.push_back(dit);
dit = map.phi1(map.phi2(map.phi1(dit)));
}
while(dit != stop);
map.splitVolume(edges);
return map.phi3(stop);
}
//[precond] le brin doit venir d'une face partagé par 2 tetraèdres
......@@ -507,160 +344,181 @@ void swap3To2(typename PFP::MAP& map, Dart d)
template <typename PFP>
Dart swap2To3(typename PFP::MAP& map, Dart d)
{
Dart e = map.phi1(map.phi2(map.phi3(d)));
unsigned int p1 = map.getEmbedding<VERTEX>(map.phi_1(map.phi2(d))) ;
unsigned int p2 = map.getEmbedding<VERTEX>(map.phi2(map.phi1(map.phi2(map.phi3(d))))) ;
//détachement des demi-faces du milieu
//garde la relation volumique qui les lies
//relie les faces de bords des 2 tetraèdres
//renvoie le brin de base d'un des 2 tétraèdres
unlinkFace<PFP>(map, d);
//Couture de la premiere face
Dart en1 = linkIntoEdge<PFP>(map,d,e);
Dart en2 = linkIntoEdge<PFP>(map, map.phi1(d), map.phi_1(map.phi2(map.phi_1(e))));
map.setDartEmbedding<VERTEX>(map.phi_1(d), p1);
map.setDartEmbedding<VERTEX>(map.phi1(map.phi3(d)), p2);
///Couture de la seconde face
en1 = map.phi1(map.phi1(en1));
en2 = map.phi_1(map.phi_1(en2));
Dart f1 = map.newFace(3);
Dart f1prim = map.newFace(3);
map.sewVolumes(f1,f1prim);
en1 = linkIntoEdge<PFP>(map, f1,en1);
en2 = linkIntoEdge<PFP>(map, map.phi1(f1),en2);
map.setDartEmbedding<VERTEX>(map.phi_1(f1), p1);
map.setDartEmbedding<VERTEX>(map.phi1(map.phi3(f1)), p2);
///Couture de la troisieme face
en1 = map.phi1(map.phi1(en1));
en2 = map.phi_1(map.phi_1(en2));
Dart f2 = map.newFace(3);
Dart f2prim = map.newFace(3);
map.sewVolumes(f2,f2prim);
en1 = linkIntoEdge<PFP>(map, f2,en1);
en2 = linkIntoEdge<PFP>(map, map.phi1(f2),en2);
//couture des 3 faces du milieu
map.sewFaces(map.phi_1(d), map.phi1(map.phi3(f2)));
map.sewFaces(map.phi1(map.phi3(d)), map.phi_1(f1));
map.sewFaces(map.phi1(map.phi3(f1)), map.phi_1(f2));
map.setDartEmbedding<VERTEX>(map.phi_1(f2), p1);
map.setDartEmbedding<VERTEX>(map.phi1(map.phi3(f2)), p2);
return map.phi_1(d);
}
template <typename PFP>
void swap5To4(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP::VEC3>& positions)
{
}
/************************************************************************************************
* Flip Functions *
************************************************************************************************/
std::vector<Dart> edges;
Dart d2_1 = map.phi_1(map.phi2(d));
map.mergeVolumes(d);
template <typename PFP>
void flip1To4(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP::VEC3