Commit 9780158b authored by Lionel Untereiner's avatar Lionel Untereiner

ajout sqrt3 + modif fonctions cartes

parent 059d7f9c
......@@ -728,6 +728,7 @@ void sqrt3Vol(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& posit
}
}
/*
TraversorV<typename PFP::MAP> tVg(map);
for(Dart dit = tVg.begin() ; dit != tVg.end() ; dit = tVg.next())
{
......@@ -741,7 +742,8 @@ void sqrt3Vol(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& posit
Dart vit = db ;
do
{
newP += position[map.phi_1(map.phi2(map.phi1(vit)))] ;
//newP += position[map.phi_1(map.phi2(map.phi1(vit)))] ;
newP += position[map.phi2(vit)];
++val ;
vit = map.phi2(map.phi_1(vit)) ;
} while(vit != db) ;
......@@ -753,7 +755,9 @@ void sqrt3Vol(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& posit
position[db] = newP ;
}
}
*/
/*
//
// edge-removal on all old boundary edges
//
......@@ -765,10 +769,13 @@ void sqrt3Vol(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& posit
m.unmarkOrbit<EDGE>(dit);
Dart d = map.phi2(map.phi3(map.findBoundaryFaceOfEdge(dit)));
Volume::Modelisation::Tetrahedralization::swapGen3To2<PFP>(map, d);
}
}
*/
// TraversorV<typename PFP::MAP> tVg(map,selected);
// for(Dart dit = tVg.begin() ; dit != tVg.end() ; dit = tVg.next())
// {
......
......@@ -564,6 +564,36 @@ public:
}
} ;
//template <typename PFP>
//bool isDartOfFaceAtLevel(typename PFP::MAP map, Dart d, unsigned int level)
//{
// unsigned int cur = map.getCurrentLevel();
// map.setCurrentLevel(level);
//// TraversorDartsOfOrbit<typename PFP::MAP, FACE> to(map,d);
//// for (Dart dit = to.begin(); dit != to.end(); dit = to.next())
//// {
//// if(d == dit)
//// {
//// map.setCurrentLevel(cur);
//// return true;
//// }
//// }
// Dart dit = d;
// do
// {
// if(d == dit)
// {
// map.setCurrentLevel(cur);
// return true;
// }
// dit = map.phi1(dit);
// }while(dit != d);
// map.setCurrentLevel(cur);
// return false;
//}
template <typename PFP>
class LerpSqrt3VolumeSynthesisFilter : public Algo::MR::Filter
{
......@@ -575,21 +605,115 @@ public:
LerpSqrt3VolumeSynthesisFilter(typename PFP::MAP& m, VertexAttribute<typename PFP::VEC3>& p) : m_map(m), m_position(p)
{}
Dart findDartOfCentralVertex(Dart d)
{
Dart olddart = NIL;
TraversorDartsOfOrbit<typename PFP::MAP, VOLUME> to(m_map,d);
for(Dart dit = to.begin() ; (olddart == NIL) && (dit != to.end()) ; dit = to.next())
{
m_map.incCurrentLevel();
unsigned int emb = m_map.template getEmbedding<VERTEX>(dit);
m_map.decCurrentLevel();
if(!m_map.isBoundaryMarked3(m_map.phi3(dit)))
{
if(emb == EMBNULL)
olddart = dit;
}
}
std::cout << "findDartOfCentralVertex = " << olddart << std::endl;
return olddart;
}
void operator() ()
{
// m_map.incCurrentLevel() ;
// unsigned int cur = m_map.getCurrentLevel();
// TraversorV<typename PFP::MAP> trav(m_map) ;
// for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
// {
// if(!m_map.isBoundaryVertex(d))
// {
// std::cout << "sommet" << std::endl;
// //search an old dart
// Dart olddart = NIL;
// TraversorDartsOfOrbit<typename PFP::MAP, VERTEX> to(m_map,d);
// for(Dart dit = to.begin() ; (olddart == NIL) && (dit != to.end()) ; dit = to.next())
// {
// if(m_map.getDartLevel(dit) == (cur - 1)) && isDartOfFaceAtLevel<PFP>(m_map,dit, cur-1))
// {
// olddart = dit;
// }
// }
// if(olddart != NIL)
// {
// std::cout << "olddart = " << olddart << std::endl;
// m_map.decCurrentLevel();
// typename PFP::VEC3 p = Algo::Surface::Geometry::volumeCentroid<PFP>(m_map, olddart, m_position);
// m_map.incCurrentLevel() ;
// m_position[d] = p;
// }
// }
// }
// m_map.decCurrentLevel() ;
// TraversorW<typename PFP::MAP> trav(m_map) ;
// for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
// {
// typename PFP::VEC3 p = Algo::Surface::Geometry::volumeCentroid<PFP>(m_map, d , m_position);
// m_map.incCurrentLevel() ;
// Dart midV = m_map.phi_1(m_map.phi2(d));
// m_position[midV] = p;
// //m_position[d] = p;
// m_map.decCurrentLevel() ;
// }
TraversorW<typename PFP::MAP> trav(m_map) ;
for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
{
typename PFP::VEC3 p = Algo::Surface::Geometry::volumeCentroid<PFP>(m_map, d, m_position);
Dart dit = d;
m_map.incCurrentLevel() ;
if(m_map.isBoundaryVolume(d))
{
dit = findDartOfCentralVertex(d);
}
typename PFP::VEC3 p = Algo::Surface::Geometry::volumeCentroid<PFP>(m_map, d, m_position);
Dart midV = m_map.phi_1(m_map.phi2(d));
//Dart midV = m_map.phi_1(d);
m_position[midV] = p;
//Dart midV = m_map.phi1(dit);
m_map.incCurrentLevel() ;
m_position[dit] = p;
m_map.decCurrentLevel() ;
}
TraversorF<typename PFP::MAP> tf(m_map);
for(Dart dit = tf.begin() ; dit != tf.end() ; dit = tf.next())
{
if(m_map.isBoundaryFace(dit))
{
typename PFP::VEC3 p = Algo::Surface::Geometry::faceCentroid<PFP>(m_map, dit, m_position);
m_map.incCurrentLevel();
Dart midF = m_map.phi_1(dit);
m_position[midF] = p;
m_map.decCurrentLevel();
}
}
}
} ;
......
......@@ -89,6 +89,10 @@ public:
void swapEdges(Dart d, Dart e);
Dart swap2To3(Dart d);
void swapGen3To2(Dart d);
/*! @name Level creation
*
*************************************************************************/
......@@ -110,6 +114,8 @@ public:
void addNewLevelSqrt3(bool embedNewVertices = false);
void addNewLevelSqrt3(bool embedNewVertices, VertexAttribute<typename PFP::VEC3> position);
//!
/*
*/
......
......@@ -130,12 +130,241 @@ void Map3MR<PFP>::splitSurfaceInVolume(std::vector<Dart>& vd, bool firstSideClos
}
}
template <typename PFP>
Dart Map3MR<PFP>::swap2To3(Dart d)
{
std::vector<Dart> edges;
Dart d2_1 = m_map.phi_1(m_map.phi2(d));
m_map.mergeVolumes(d,false);
//
// Cut the 1st tetrahedron
//
Dart stop = d2_1;
Dart dit = stop;
do
{
edges.push_back(dit);
dit = m_map.phi1(m_map.phi2(m_map.phi1(dit)));
}
while(dit != stop);
m_map.splitVolume(edges);
m_map.splitFace(m_map.alpha2(edges[0]), m_map.alpha2(edges[2]));
//
// Cut the 2nd tetrahedron
//
edges.clear();
stop = m_map.phi1(m_map.phi2(d2_1));
dit = stop;
do
{
edges.push_back(dit);
dit = m_map.phi1(m_map.phi2(m_map.phi1(dit)));
}
while(dit != stop);
m_map.splitVolumeWithFace(edges,m_map.phi_1(m_map.phi3(d)));
//m_map.splitVolume(edges);
return m_map.phi1(d2_1);
}
template <typename PFP>
void Map3MR<PFP>::swapGen3To2(Dart d)
{
unsigned int n = m_map.edgeDegree(d);
if(n >= 4)
{
Dart dit = d;
if(m_map.isBoundaryEdge(dit))
{
for(unsigned int i = 0 ; i < n - 2 ; ++i)
{
dit = m_map.phi2(swap2To3(dit));
}
//Volume::Modelisation::Tetrahedralization::swap2To2<PFP>(m_map, dit);
}
else
{
for(unsigned int i = 0 ; i < n - 4 ; ++i)
{
dit = m_map.phi2(swap2To3(dit));
}
//Volume::Modelisation::Tetrahedralization::swap4To4<PFP>(m_map, m_map.alpha2(dit));
}
}
else if (n == 3)
{
Dart dres = swap2To3(d);
//Volume::Modelisation::Tetrahedralization::swap2To2<PFP>(m_map, m_map.phi2(dres));
}
else // si (n == 2)
{
//Volume::Modelisation::Tetrahedralization::swap2To2<PFP>(m_map, d);
}
}
/************************************************************************
* Level creation *
************************************************************************/
inline double sqrt3_K(unsigned int n)
{
switch(n)
{
case 1: return 0.333333 ;
case 2: return 0.555556 ;
case 3: return 0.5 ;
case 4: return 0.444444 ;
case 5: return 0.410109 ;
case 6: return 0.388889 ;
case 7: return 0.375168 ;
case 8: return 0.365877 ;
case 9: return 0.359328 ;
case 10: return 0.354554 ;
case 11: return 0.350972 ;
case 12: return 0.348219 ;
default:
double t = cos((2.0*M_PI)/double(n)) ;
return (4.0 - t) / 9.0 ;
}
}
template <typename PFP>
void Map3MR<PFP>::addNewLevelSqrt3(bool embedNewVertices, VertexAttribute<typename PFP::VEC3> position)
{
m_map.pushLevel();
m_map.addLevelBack();
m_map.duplicateDarts(m_map.getMaxLevel());
m_map.setCurrentLevel(m_map.getMaxLevel());
DartMarkerStore m(m_map);
DartMarkerStore newBoundaryV(m_map);
//
// 1-4 flip of all tetrahedra
//
TraversorW<typename PFP::MAP> tW(m_map);
for(Dart dit = tW.begin() ; dit != tW.end() ; dit = tW.next())
{
Traversor3WF<typename PFP::MAP> tWF(m_map, dit);
for(Dart ditWF = tWF.begin() ; ditWF != tWF.end() ; ditWF = tWF.next())
{
if(!m_map.isBoundaryFace(ditWF) && !m.isMarked(ditWF))
m.markOrbit<FACE>(ditWF);
}
typename PFP::VEC3 volCenter(0.0);
volCenter += position[dit];
volCenter += position[m_map.phi1(dit)];
volCenter += position[m_map.phi_1(dit)];
volCenter += position[m_map.phi_1(m_map.phi2(dit))];
volCenter /= 4;
Dart dres = Volume::Modelisation::Tetrahedralization::flip1To4<PFP>(m_map, dit);
position[dres] = volCenter;
}
//
// 2-3 swap of all old interior faces
//
//TraversorF<typename PFP::MAP> tF(m_map);
for(Dart dit = m_map.begin() ; dit != m_map.end() ; m_map.next(dit))
{
if(m.isMarked(dit))
{
m.unmarkOrbit<FACE>(dit);
swap2To3(dit);
}
}
//
// 1-3 flip of all boundary tetrahedra
//
TraversorW<typename PFP::MAP> tWb(m_map);
for(Dart dit = tWb.begin() ; dit != tWb.end() ; dit = tWb.next())
{
if(m_map.isBoundaryVolume(dit))
{
Traversor3WE<typename PFP::MAP> tWE(m_map, dit);
for(Dart ditWE = tWE.begin() ; ditWE != tWE.end() ; ditWE = tWE.next())
{
if(m_map.isBoundaryEdge(ditWE) && !m.isMarked(ditWE))
m.markOrbit<EDGE>(ditWE);
}
typename PFP::VEC3 faceCenter(0.0);
faceCenter += position[dit];
faceCenter += position[m_map.phi1(dit)];
faceCenter += position[m_map.phi_1(dit)];
faceCenter /= 3;
Dart dres = Volume::Modelisation::Tetrahedralization::flip1To3<PFP>(m_map, dit);
position[dres] = faceCenter;
newBoundaryV.markOrbit<VERTEX>(dres);
}
}
/*
TraversorV<typename PFP::MAP> tVg(m_map);
for(Dart dit = tVg.begin() ; dit != tVg.end() ; dit = tVg.next())
{
if(m_map.isBoundaryVertex(dit) && !newBoundaryV.isMarked(dit))
{
Dart db = m_map.findBoundaryFaceOfVertex(dit);
typename PFP::VEC3 P = position[db] ;
typename PFP::VEC3 newP(0) ;
unsigned int val = 0 ;
Dart vit = db ;
do
{
newP += position[m_map.phi_1(m_map.phi2(m_map.phi1(vit)))] ;
++val ;
vit = m_map.phi2(m_map.phi_1(vit)) ;
} while(vit != db) ;
typename PFP::REAL K = sqrt3_K(val) ;
newP *= typename PFP::REAL(3) ;
newP -= typename PFP::REAL(val) * P ;
newP *= K / typename PFP::REAL(2 * val) ;
newP += (typename PFP::REAL(1) - K) * P ;
position[db] = newP ;
}
}
*/
//
// edge-removal on all old boundary edges
//
TraversorE<typename PFP::MAP> tE(m_map);
for(Dart dit = tE.begin() ; dit != tE.end() ; dit = tE.next())
{
if(m.isMarked(dit))
{
m.unmarkOrbit<EDGE>(dit);
Dart d = m_map.phi2(m_map.phi3(m_map.findBoundaryFaceOfEdge(dit)));
swapGen3To2(d);
}
}
m_map.setCurrentLevel(m_map.getMaxLevel());
m_map.popLevel() ;
}
template <typename PFP>
void Map3MR<PFP>::addNewLevelSqrt3(bool embedNewVertices)
{
/*
m_map.pushLevel();
m_map.addLevelBack();
......@@ -153,27 +382,27 @@ void Map3MR<PFP>::addNewLevelSqrt3(bool embedNewVertices)
Traversor3WF<typename PFP::MAP> tWF(m_map, dit);
for(Dart ditWF = tWF.begin() ; ditWF != tWF.end() ; ditWF = tWF.next())
{
if(!m_map.isBoundaryFace(ditWF))
if(!m_map.isBoundaryFace(ditWF) && !m.isMarked(ditWF))
m.markOrbit<FACE>(ditWF);
}
Algo::Volume::Modelisation::Tetrahedralization::flip1To4<PFP>(m_map, dit);
}
//
// 2-3 swap of all old interior faces
//
TraversorF<typename PFP::MAP> tF(m_map);
for(Dart dit = tF.begin() ; dit != tF.end() ; dit = tF.next())
{
if(m.isMarked(dit))
{
m.unmarkOrbit<FACE>(dit);
Algo::Volume::Modelisation::Tetrahedralization::swap2To3<PFP>(m_map, dit);
}
}
//
// 2-3 swap of all old interior faces
//
//TraversorF<typename PFP::MAP> tF(m_map);
for(Dart dit = m_map.begin() ; dit != m_map.end() ; m_map.next(dit))
{
if(m.isMarked(dit))
{
m.unmarkOrbit<FACE>(dit);
std::cout << "dit = " << dit << std::endl;
swap2To3(dit);
}
}
/*
//
// 1-3 flip of all boundary tetrahedra
//
......@@ -193,6 +422,7 @@ void Map3MR<PFP>::addNewLevelSqrt3(bool embedNewVertices)
}
}
//
// edge-removal on all old boundary edges
//
......@@ -203,14 +433,15 @@ void Map3MR<PFP>::addNewLevelSqrt3(bool embedNewVertices)
{
m.unmarkOrbit<EDGE>(dit);
Dart d = m_map.phi2(m_map.phi3(m_map.findBoundaryFaceOfEdge(dit)));
Algo::Volume::Modelisation::Tetrahedralization::swapGen3To2<PFP>(m_map, d);
//Algo::Volume::Modelisation::Tetrahedralization::swapGen3To2<PFP>(m_map, d);
swapGen3To2(d);
}
}
*/
m_map.setCurrentLevel(m_map.getMaxLevel());
m_map.popLevel() ;
*/
}
template <typename PFP>
......@@ -356,7 +587,7 @@ void Map3MR<PFP>::addNewLevelTetraOcta()
}
m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ;
}
}
}
m_map.popLevel() ;
}
......
......@@ -141,7 +141,7 @@ public:
* The attributes attached to the vertices of the face of d are kept on the resulting vertices
* The attributes attached to the edges of the face of d are kept on the resulting edges
*/
virtual bool mergeVolumes(Dart d, Dart e) ;
virtual bool mergeVolumes(Dart d, Dart e, bool deleteFace = true) ;
/**
*
......
......@@ -112,13 +112,17 @@ public:
//!
/*!
*/
virtual bool mergeVolumes(Dart d);
virtual bool mergeVolumes(Dart d, bool deleteFace = true);
//!
/*!
*/
virtual void splitVolume(std::vector<Dart>& vd);
//!
virtual void splitVolumeWithFace(std::vector<Dart>& vd, Dart d);
//!
/*!
*/
......
......@@ -301,7 +301,7 @@ public:
* @param e a dart of the second face
* @return true if the merge has been executed, false otherwise
*/
virtual bool mergeVolumes(Dart d, Dart e);
virtual bool mergeVolumes(Dart d, Dart e, bool deleteFace = true);
//! Split a surface into two disconnected surfaces along a edge path
/*! @param vd a vector of darts
......
......@@ -267,7 +267,7 @@ public:
//! Merge two volumes along their common oriented face
/*! @param d a dart of common face
*/
virtual bool mergeVolumes(Dart d);
virtual bool mergeVolumes(Dart d, bool deleteFace = true);
virtual bool mergeVolumes(Dart /*d*/, Dart /*e*/) { assert("use mergeVolumes(d,e) only in dimension 2");return false;}
......@@ -277,6 +277,11 @@ public:
*/
virtual void splitVolume(std::vector<Dart>& vd);
//! Split a volume into two volumes along a edge path and add the given face between
virtual void splitVolumeWithFace(std::vector<Dart>& vd, Dart d);
//! Collapse a volume (that is deleted) possibly merging its vertices
/*! \warning
* @param d a dart in the deleted volume
......
......@@ -518,7 +518,7 @@ bool EmbeddedMap2::mergeFaces(Dart d)
return false ;
}
bool EmbeddedMap2::mergeVolumes(Dart d, Dart e)
bool EmbeddedMap2::mergeVolumes(Dart d, Dart e, bool deleteFace)
{
std::vector<Dart> darts ;
std::vector<unsigned int> vEmb ;
......@@ -543,7 +543,7 @@ bool EmbeddedMap2::mergeVolumes(Dart d, Dart e)
fit = phi1(fit) ;
} while (fit != d) ;
if(Map2::mergeVolumes(d, e))
if(Map2::mergeVolumes(d, e, deleteFace))
{
for(unsigned int i = 0; i < darts.size(); ++i)
{
......
......@@ -426,11 +426,11 @@ void EmbeddedMap3::unsewVolumes(Dart d, bool withBoundary)
}
}
bool EmbeddedMap3::mergeVolumes(Dart d)
bool EmbeddedMap3::mergeVolumes(Dart d, bool deleteFace)
{
Dart d2 = phi2(d);
if(Map3::mergeVolumes(d))
if(Map3::mergeVolumes(d, deleteFace))
{
if (isOrbitEmbedded<VOLUME>())
{
......@@ -491,6 +491,57 @@ void EmbeddedMap3::splitVolume(std::vector<Dart>& vd)
}
}
//! Split a volume into two volumes along a edge path and add the given face between
void EmbeddedMap3::splitVolumeWithFace(std::vector<Dart>& vd, Dart d)
{
Map3::splitVolumeWithFace(vd,d);
// follow the edge path a second time to embed the vertex, edge and volume orbits
for(std::vector<Dart>::iterator it = vd.begin() ; it != vd.end() ; ++it)
{
Dart dit = *it;
Dart dit23 = phi3(phi2(dit));
// embed the vertex embedded from the origin volume to the new darts
if(isOrbitEmbedded<VERTEX>())
{
copyDartEmbedding<VERTEX>(dit23, dit);
copyDartEmbedding<VERTEX>(phi2(dit), phi1(dit));
}
// embed the edge embedded from the origin volume to the new darts
if(isOrbitEmbedded<EDGE2>())
{
setOrbitEmbeddingOnNewCell<EDGE2>(dit23) ;
copyCell<EDGE2>(dit23, dit) ;
copyDartEmbedding<EDGE2>(phi2(dit), dit);
}
// embed the edge embedded from the origin volume to the new darts
if(isOrbitEmbedded<EDGE>())
{
unsigned int eEmb = getEmbedding<EDGE>(dit) ;
setDartEmbedding<EDGE>(dit23, eEmb);
setDartEmbedding<EDGE>(phi2(dit), eEmb);