Commit 09100dc0 authored by Thomas's avatar Thomas

Merge branch 'master' of cgogn.u-strasbg.fr:~untereiner/CGoGN

parents 584a38ff d2282716
......@@ -25,9 +25,6 @@
#ifndef __IMPLICIT_HIERARCHICAL_MAP3__
#define __IMPLICIT_HIERARCHICAL_MAP3__
//#include "Topology/map/map3.h"
//#include "Topology/generic/embeddedMap3.h"
//#include "Container/attributeContainer.h"
#include "Topology/map/embeddedMap3.h"
namespace CGoGN
......
......@@ -120,262 +120,6 @@ template <typename PFP>
void Sqrt3Subdivision(typename PFP::MAP& map, typename PFP::TVEC3& position, const FunctorSelect& selected = SelectorTrue()) ;
/*
* volume subdivision scheme
*/
template <typename PFP, typename EMBV, typename EMB>
void hexaCutVolume(typename PFP::MAP& map, Dart d, EMBV& attributs);
template <typename PFP>
void splitVolumes(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position);
// TODO a mettre ailleurs ?
//
///**
// * create a tetra based on the two triangles that have a common dart and phi2(dart)
// * return a new dart inside the tetra
// */
//template<typename PFP>
//Dart extractTetra(typename PFP::MAP& the_map, Dart d)
//{
//
//
// Dart e = the_map.phi2(d);
//
// //create the new faces
// Dart dd = the_map.newFace(3);
// Dart ee = the_map.newFace(3);
//
// //update their sew
// the_map.sewFaces(dd,ee);
// the_map.sewFaces(the_map.phi3(dd),the_map.phi3(ee));
//
// //add the two new faces in the mesh to obtain a tetra
// Dart s2d = the_map.phi2(the_map.phi_1(d));
// the_map.unsewFaces(the_map.phi_1(d));
// the_map.sewFaces(the_map.phi_1(d),the_map.phi_1(dd));
// the_map.sewFaces(s2d,the_map.phi3(the_map.phi_1(dd)));
//
// Dart s2e = the_map.phi2(the_map.phi_1(e));
// the_map.unsewFaces(the_map.phi_1(e));
// the_map.sewFaces(the_map.phi_1(e),the_map.phi_1(ee));
// the_map.sewFaces(s2e,the_map.phi3(the_map.phi_1(ee)));
//
// Dart ss2d = the_map.phi2(the_map.phi1(d));
// the_map.unsewFaces(the_map.phi1(d));
// the_map.sewFaces(the_map.phi1(d),the_map.phi1(ee));
// the_map.sewFaces(ss2d,the_map.phi3(the_map.phi1(ee)));
//
// Dart ss2e = the_map.phi2(the_map.phi1(e));
// the_map.unsewFaces(the_map.phi1(e));
// the_map.sewFaces(the_map.phi1(e),the_map.phi1(dd));
// the_map.sewFaces(ss2e,the_map.phi3(the_map.phi1(dd)));
//
//
//
// //embed the coords
// the_map.setVertexEmb(d,the_map.getVertexEmb(d));
// the_map.setVertexEmb(e,the_map.getVertexEmb(e));
// the_map.setVertexEmb(the_map.phi_1(d),the_map.getVertexEmb(the_map.phi_1(d)));
// the_map.setVertexEmb(the_map.phi_1(e),the_map.getVertexEmb(the_map.phi_1(e)));
//
// return dd;
//}
//
///**
// * tetrahedrization of the volume
// * @param the map
// * @param a dart of the volume
// * @param true if the faces are in CCW order
// * @return success of the tetrahedrization
// */
//template<typename PFP>
//bool smartVolumeTetrahedrization(typename PFP::MAP& the_map, Dart d, bool CCW=true)
//{
//
// typedef typename PFP::EMB EMB;
//
// bool ret=true;
//
// if (!the_map.isTetrahedron(d))
// {
// //only works on a 3-map
// assert(Dart::nbInvolutions()>=2 || "cannot be applied on this map, nbInvolutions must be at least 2");
//
// if (Geometry::isConvex<PFP>(the_map,d,CCW))
// {
// the_map.tetrahedrizeVolume(d);
// }
// else
// {
//
// //get all the dart of the volume
// std::vector<Dart> vStore;
// FunctorStore fs(vStore);
// the_map.foreach_dart_of_volume(d,fs);
//
// if (vStore.size()==0)
// {
// if (the_map.phi1(d)==d)
// CGoGNout << "plop" << CGoGNendl;
// if (the_map.phi2(d)==d)
// CGoGNout << "plip" << CGoGNendl;
//
// CGoGNout << the_map.getVertexEmb(d)->getPosition() << CGoGNendl;
// CGoGNout << "tiens tiens, c'est etrange" << CGoGNendl;
// }
// //prepare the list of embeddings of the current volume
// std::vector<EMB *> lstEmb;
//
// //get a marker
// DartMarker m(the_map);
//
// //all the darts from a vertex that can generate a tetra (3 adjacent faces)
// std::vector<Dart> allowTetra;
//
// //all the darts that are not in otherTetra
// std::vector<Dart> otherTetra;
//
// //for each dart of the volume
// for (typename std::vector<Dart>::iterator it = vStore.begin() ; it != vStore.end() ; ++it )
// {
// Dart e = *it;
// //if the vertex is not treated
// if (!m.isMarked(e))
// {
// //store the embedding
// lstEmb.push_back(reinterpret_cast<EMB*>(the_map.getVertexEmb(e)));
// Dart ee=e;
//
// //count the number of adjacent faces and mark the darts
// int nbe=0;
// do
// {
// nbe++;
// m.markOrbit(DART,e);
// ee=the_map.phi1(the_map.phi2(ee));
// }
// while (ee!=e);
//
// //if 3 adjacents faces, we can create a tetra on this vertex
// if (nbe==3)
// allowTetra.push_back(e);
// else
// otherTetra.push_back(e);
// }
// }
//
// //we haven't created a tetra yet
// bool decoupe=false;
//
// //if we have vertex that can be base
// if (allowTetra.size()!=0)
// {
// //foreach possible vertex while we haven't done any cut
// for (typename std::vector<Dart>::iterator it=allowTetra.begin();it!=allowTetra.end() && !decoupe ;++it)
// {
// //get the dart
// Dart s=*it;
// //store the emb
// std::vector<EMB*> lstCurEmb;
// lstCurEmb.push_back(reinterpret_cast<EMB*>(the_map.getVertexEmb(s)));
// lstCurEmb.push_back(reinterpret_cast<EMB*>(the_map.getVertexEmb(the_map.phi1(s))));
// lstCurEmb.push_back(reinterpret_cast<EMB*>(the_map.getVertexEmb(the_map.phi_1(s))));
// lstCurEmb.push_back(reinterpret_cast<EMB*>(the_map.getVertexEmb(the_map.phi_1(the_map.phi2(s)))));
//
// //store the coords of the point
// gmtl::Vec3f points[4];
// for (int i=0;i<4;++i)
// {
// points[i] = lstCurEmb[i]->getPosition();
// }
//
// //test if the future tetra is well oriented (concave case)
// if (Geometry::isTetrahedronWellOriented(points,CCW))
// {
// //test if we haven't any point inside the future tetra
// bool isEmpty=true;
// for (typename std::vector<EMB *>::iterator iter = lstEmb.begin() ; iter != lstEmb.end() && isEmpty ; ++iter)
// {
// //we don't test the vertex that composes the new tetra
// if (std::find(lstCurEmb.begin(),lstCurEmb.end(),*iter)==lstCurEmb.end())
// {
// isEmpty = !Geometry::isPointInTetrahedron(points, (*iter)->getPosition(), CCW);
// }
// }
//
// //if no point inside the new tetra
// if (isEmpty)
// {
// //cut the spike to make a tet
// Dart dRes = the_map.cutSpike(*it);
// decoupe=true;
// //and continue with the rest of the volume
// ret = ret && smartVolumeTetrahedrization<PFP>(the_map,the_map.phi3(dRes),CCW);
// }
// }
// }
// }
//
// if (!decoupe)
// {
// //foreach other vertex while we haven't done any cut
// for (typename std::vector<Dart>::iterator it=otherTetra.begin();it!=otherTetra.end() && !decoupe ;++it)
// {
// //get the dart
// Dart s=*it;
// //store the emb
// std::vector<EMB*> lstCurEmb;
// lstCurEmb.push_back(reinterpret_cast<EMB*>(the_map.getVertexEmb(s)));
// lstCurEmb.push_back(reinterpret_cast<EMB*>(the_map.getVertexEmb(the_map.phi1(s))));
// lstCurEmb.push_back(reinterpret_cast<EMB*>(the_map.getVertexEmb(the_map.phi_1(s))));
// lstCurEmb.push_back(reinterpret_cast<EMB*>(the_map.getVertexEmb(the_map.phi_1(the_map.phi2(s)))));
//
// //store the coords of the point
// gmtl::Vec3f points[4];
// for (int i=0;i<4;++i)
// {
// points[i] = lstCurEmb[i]->getPosition();
// }
//
// //test if the future tetra is well oriented (concave case)
// if (Geometry::isTetrahedronWellOriented(points,CCW))
// {
// //test if we haven't any point inside the future tetra
// bool isEmpty=true;
// for (typename std::vector<EMB *>::iterator iter = lstEmb.begin() ; iter != lstEmb.end() && isEmpty ; ++iter)
// {
// //we don't test the vertex that composes the new tetra
// if (std::find(lstCurEmb.begin(),lstCurEmb.end(),*iter)==lstCurEmb.end())
// {
// isEmpty = !Geometry::isPointInTetrahedron(points, (*iter)->getPosition(), CCW);
// }
// }
//
// //if no point inside the new tetra
// if (isEmpty)
// {
// //cut the spike to make a tet
// Dart dRes = extractTetra<PFP>(the_map,*it);
// decoupe=true;
// //and continue with the rest of the volume
// smartVolumeTetrahedrization<PFP>(the_map,the_map.phi3(dRes),CCW);
// }
// }
// }
// }
//
// if (!decoupe)
// ret=false;
// }
// }
// return ret;
//}
} // namespace Modelisation
} // namespace Algo
......
......@@ -645,257 +645,6 @@ void Sqrt3Subdivision(typename PFP::MAP& map, typename PFP::TVEC3& position, con
}
}
template <typename PFP, typename EMBV, typename EMB>
void hexaCutVolume(typename PFP::MAP& map, Dart d, EMBV& attributs)
{
DartMarker mf(map) ; //mark face
DartMarker me(map) ; //mark edge
DartMarkerStore mark(map); // Lock a marker
// compute volume centroid
EMB volCenter = Algo::Geometry::volumeCentroidGen<PFP,EMBV,EMB>(map, d, attributs);
//Store faces that are traversed and start with the face of d
std::vector<Dart> visitedFaces;
visitedFaces.reserve(100);
visitedFaces.push_back(d);
std::vector<Dart>::iterator face;
//Store the edges before the cutEdge
std::vector<Dart> oldEdges;
oldEdges.reserve(100);
std::vector<Dart>::iterator edge;
//Store a dart from a each face
std::vector<Dart> faces;
faces.reserve(100);
//Store the darts from quadrangulated faces
std::vector<Dart> quadfaces;
quadfaces.reserve(100);
// First pass : for every face added to the list save a dart
for (face = visitedFaces.begin(); face != visitedFaces.end(); ++face)
{
if (!mark.isMarked(*face)) // Face has not been visited yet
{
faces.push_back(*face);
Dart dNext = *face ;
do
{
mark.mark(dNext); // Mark
oldEdges.push_back(dNext);
Dart adj = map.phi2(dNext); // Get adjacent face
if (adj != dNext && !mark.isMarked(adj))
visitedFaces.push_back(adj); // Add it
dNext = map.phi1(dNext);
} while(dNext != *face);
}
}
//Second pass : cut the edges && quadrangule the faces
for (face = faces.begin(); face != faces.end(); ++face)
{
Dart dNext = *face;
//parcours de la face pour couper les aretes
do
{
Dart d = dNext;
dNext = map.phi1(dNext);
if(!me.isMarked(d))
{
Dart f = map.phi1(d);
map.cutEdge(d);
Dart e = map.phi1(d);
attributs[e] = attributs[d];
attributs[e] += attributs[f];
attributs[e] *= 0.5;
me.markOrbit(EDGE, d);
me.markOrbit(EDGE, e);
}
}while (dNext != *face);
//quadrangulation
EMB center = Algo::Geometry::faceCentroidGen<PFP,EMBV,EMB>(map, *face, attributs); // compute center
Dart cf = Algo::Modelisation::quadranguleFace<PFP>(map, *face); // quadrangule the face
attributs[cf] = center; // affect the data to the central vertex
Dart e = cf;
do
{
quadfaces.push_back(e);
quadfaces.push_back(map.phi2(e));
e = map.phi2(map.phi_1(e));
}while (e != cf);
}
DartMarker moe(map) ; //mark edge
//Third pass : deconnect the corners
for (edge = oldEdges.begin(); edge != oldEdges.end(); ++edge)
{
map.unsewFaces(map.phi1(*edge));
moe.markOrbit(DART,map.phi1(*edge));
}
//Thourth pass : close the hole
for (edge = oldEdges.begin(); edge != oldEdges.end(); ++edge)
{
if(moe.isMarked(map.phi1(*edge)))
{
map.closeHole(map.phi1(*edge));
moe.unmark(map.phi1(*edge));
moe.unmark(map.phi1(map.phi2(map.phi_1(*edge))));
moe.unmark(map.phi1(map.phi1(map.phi2(*edge))));
Dart cf = Algo::Modelisation::quadranguleFace<PFP>(map, map.phi1(map.phi2(map.phi1(*edge)))); // quadrangule the face
attributs[cf] = volCenter; // affect the data to the central vertex
}
}
moe.unmarkAll();
//Fifth pass : traversal to phi3 sewing
std::vector<Dart>::iterator nvol;
for (nvol = quadfaces.begin(); nvol != quadfaces.end(); nvol = nvol + 2)
{
map.sewVolumes(map.phi2(*nvol), map.phi2(*(nvol+1)));
}
// // Compute edge points
// for (edge = oldEdges.begin(); edge != oldEdges.end(); ++edge)
// {
// Dart x = *edge;
// // other side of the edge
// Dart y = map.phi2(x);
// if (y != x)
// {
// Dart f1 = map.phi_1(x);
// Dart f2 = map.phi2(map.phi1(y));
// EMB temp = AttribOps::zero<EMB,PFP>();
// temp = attributs[f1];
// temp += attributs[f2]; // E' = (V0+V1+F1+F2)/4
// temp *= 0.25;
// attributs[x] *= 0.5;
// attributs[x] += temp;
// }
// // else nothing to do point already in the middle of segment
// }
//
// // Compute vertex points
// for (face = faces.begin(); face != faces.end(); ++face)
// {
// //m0.unmark(*face);
//
// EMB temp = AttribOps::zero<EMB,PFP>();
// EMB temp2 = AttribOps::zero<EMB,PFP>();
//
// unsigned int n = 0;
// Dart x = *face;
// do
// {
// Dart m = map.phi1(x);
// Dart f = map.phi2(m);
// Dart v = map.template phi<11>(f);
//
// temp += attributs[f];
// temp2 += attributs[v];
//
// ++n;
// x = map.alpha1(x);
// } while (x != *face);
//
// EMB emcp = attributs[*face];
// emcp *= double((n-2)*n); // V' = (n-2)/n*V + 1/n2 *(F+E)
// emcp += temp;
// emcp += temp2;
// emcp /= double(n*n);
//
// attributs[*face] = emcp ;
// }
}
template <typename PFP>
void splitVolumes(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position)
{
//Cut the edges
DartMarker me(map, EDGE);
for(Dart d = map.begin(); d != map.end(); map.next(d))
{
if(!me.isMarked(d))
{
// Cut the edge
Dart dd = map.phi2(d) ;
typename PFP::VEC3 p1 = position[d] ;
typename PFP::VEC3 p2 = position[map.phi1(d)] ;
map.cutEdge(d) ;
position[map.phi1(d)] = (p1 + p2) * typename PFP::REAL(0.5) ;
me.markOrbit(EDGE, d);
me.markOrbit(EDGE, map.phi1(d));
}
}
DartMarker mf(map, FACE);
for(Dart d = map.begin(); d != map.end(); map.next(d))
{
if(!mf.isMarked(d))
{
mf.markOrbit(FACE, d);
}
}
// //and split the faces
//
// //Insert the middleFaces
//
// // first cut the edges (if they are not already)
// Dart t = d;
// do
// {
// if(!map.edgeIsSubdivided(map.phi1(map.phi2(t))))
// Algo::IHM::subdivideEdge<PFP>(map, map.phi1(map.phi2(t)), position) ;
// t = map.phi1(t);
// }
// while(t != d);
//
// Dart neighboordVolume = map.phi1(map.phi1(map.phi2(d)));
//
// //Split the faces and open the midlle
// do
// {
// Dart t2 = map.phi2(t);
//
// Dart face2 = map.phi1(map.phi1(t2));
// map.splitFace(map.phi_1(t2), face2);
// map.unsewFaces(map.phi1(map.phi1(t2)));
//
// t = map.phi1(t);
// }
// while(t != d);
//
//
// map.closeHole(map.phi1(map.phi1(map.phi2(d))));
// map.closeHole(map.phi_1(neighboordVolume));
// map.sewVolumes(map.phi2(map.phi1(map.phi1(map.phi2(d)))), map.phi2(map.phi_1(neighboordVolume)));
}
} // namespace Modelisation
} // namespace Algo
......
......@@ -22,8 +22,8 @@
* *
*******************************************************************************/
#ifndef __SUBDIVISION3MAP_H__
#define __SUBDIVISION3MAP_H__
#ifndef __SUBDIVISION3_H__
#define __SUBDIVISION3_H__
#include <math.h>
#include <vector>
......@@ -45,12 +45,7 @@ namespace Modelisation
template <typename PFP>
Dart cut3Ear(typename PFP::MAP& map, Dart d);
/**
* subdivide a hexahedron into 5 tetrahedron
* @param d dart of the hexahedron
*/
template <typename PFP>
void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d);
/**
* catmull clark volumic : do not move the original vertices
......@@ -74,7 +69,7 @@ void catmullClarkVol(typename PFP::MAP& map, typename PFP::TVEC3& position, cons
} // namespace CGoGN
#include "Algo/Modelisation/subdivision3map.hpp"
#include "Algo/Modelisation/subdivision3.hpp"
#endif
......
......@@ -82,19 +82,7 @@ Dart cut3Ear(typename PFP::MAP& map, Dart d)
return map.phi2(dRing);
}
template <typename PFP>
void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d)
{
Dart d1 = d;
Dart d2 = map.phi1(map.phi1(d));
Dart d3 = map.phi_1(map.phi2(d));
Dart d4 = map.phi1(map.phi1(map.phi2(map.phi_1(d3))));
cut3Ear<PFP>(map,d1);
cut3Ear<PFP>(map,d2);
cut3Ear<PFP>(map,d3);
cut3Ear<PFP>(map,d4);
}
template <typename PFP, typename EMBV, typename EMB>
void catmullClarkVol(typename PFP::MAP& map, EMBV& attributs, const FunctorSelect& selected)
......@@ -261,6 +249,7 @@ void catmullClarkVol(typename PFP::MAP& map, EMBV& attributs, const FunctorSelec
}
}
} //namespace Modelisation
} //namespace Algo
......
......@@ -22,8 +22,8 @@
* *
*******************************************************************************/
#ifndef __TETRAHEDRON_H__
#define __TETRAHEDRON_H__
#ifndef __TETRAHEDRALIZATION_H__
#define __TETRAHEDRALIZATION_H__
namespace CGoGN
{
......@@ -34,9 +34,16 @@ namespace Algo
namespace Modelisation
{
namespace Tetrahedron
namespace Tetrahedralization
{
/**
* subdivide a hexahedron into 5 tetrahedron
* @param d dart of the hexahedron
*/
template <typename PFP>
void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d);
/************************************************************************************************
* Tetrahedron functions *
************************************************************************************************/
......@@ -116,12 +123,12 @@ template <typename PFP>
void edgeBisection(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position);
} //end namespace Tetrahedron
} //end namespace Tetrahedralization
} //end namespace Modelisation
} //end namespace Algo
} //end namespace CGoGN
#include "Algo/Modelisation/tetrahedron.hpp"
#include "Algo/Modelisation/tetrahedralization.hpp"
#endif
......@@ -33,8 +33,23 @@ namespace Algo
namespace Modelisation
{
namespace Tetrahedron
namespace Tetrahedralization
{
template <typename PFP>
void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d)
{
Dart d1 = d;
Dart d2 = map.phi1(map.phi1(d));
Dart d3 = map.phi_1(map.phi2(d));
Dart d4 = map.phi1(map.phi1(map.phi2(map.phi_1(d3))));
cut3Ear<PFP>(map,d1);
cut3Ear<PFP>(map,d2);
cut3Ear<PFP>(map,d3);
cut3Ear<PFP>(map,d4);
}
/************************************************************************************************
* Tetrahedron functions *
************************************************************************************************/
......@@ -633,7 +648,250 @@ void edgeBisection(typename PFP::MAP& map, Dart d, typename PFP::TVEC3& position
}
}//end namespace Tetrahedron
//
///**
// * create a tetra based on the two triangles that have a common dart and phi2(dart)
// * return a new dart inside the tetra
// */
//template<typename PFP>
//Dart extractTetra(typename PFP::MAP& the_map, Dart d)
//{
//
//
// Dart e = the_map.phi2(d);
//