Commit 60beb9e6 authored by untereiner's avatar untereiner
Browse files

volumetric sqrt(3) subdivision refinements

parent 61df65ee
......@@ -28,6 +28,7 @@
#include <math.h>
#include <vector>
#include "Geometry/plane_3d.h"
#include "Algo/Modelisation/tetrahedralization.h"
namespace CGoGN
{
......
......@@ -640,8 +640,12 @@ void sqrt3Vol(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& posit
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);
Traversor3WF<typename PFP::MAP> tWF(map, dit);
for(Dart ditWF = tWF.begin() ; ditWF != tWF.end() ; ditWF = tWF.next())
{
if(!map.isBoundaryFace(ditWF))
m.markOrbit<FACE>(ditWF);
}
Algo::Modelisation::Tetrahedralization::flip1To4<PFP>(map, dit, position);
}
......@@ -667,6 +671,13 @@ void sqrt3Vol(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& posit
{
if(map.isBoundaryVolume(dit))
{
Traversor3WE<typename PFP::MAP> tWE(map, dit);
for(Dart ditWE = tWE.begin() ; ditWE != tWE.end() ; ditWE = tWE.next())
{
if(map.isBoundaryEdge(ditWE))
m.markOrbit<EDGE>(ditWE);
}
Algo::Modelisation::Tetrahedralization::flip1To3<PFP>(map, dit, position);
}
}
......@@ -674,6 +685,19 @@ void sqrt3Vol(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& posit
//
// edge-removal on all old boundary edges
//
TraversorE<typename PFP::MAP> tE(map,selected);
for(Dart dit = tE.begin() ; dit != tE.end() ; dit = tE.next())
{
if(m.isMarked(dit))
{
m.unmarkOrbit<EDGE>(dit);
//std::cout << " nb F of E : " << map.template degree<typename PFP::MAP,EDGE,FACE>(dit) << std::endl;
Dart d = map.phi2(map.phi3(map.findBoundaryFaceOfEdge(dit)));
Algo::Modelisation::Tetrahedralization::swapGen3To2<PFP>(map, d);
}
}
}
......
......@@ -25,6 +25,7 @@
#ifndef __TETRAHEDRALIZATION_H__
#define __TETRAHEDRALIZATION_H__
namespace CGoGN
{
......@@ -37,22 +38,22 @@ namespace Modelisation
namespace Tetrahedralization
{
/**
* subdivide a hexahedron into 5 tetrahedron
*/
template <typename PFP>
void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d);
/**
* WARNING : assume all volumes to be hexahedrons
* subdivide a hexahedron mesh into a tetrahedron mesh
*/
template <typename PFP>
void hexahedronsToTetrahedrons(typename PFP::MAP& map);
template <typename PFP>
void tetrahedrizeVolume(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position);
///**
//* subdivide a hexahedron into 5 tetrahedron
//*/
//template <typename PFP>
//void hexahedronToTetrahedron(typename PFP::MAP& map, Dart d);
//
///**
//* WARNING : assume all volumes to be hexahedrons
//* subdivide a hexahedron mesh into a tetrahedron mesh
//*/
//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 *
......@@ -123,6 +124,20 @@ Dart swap2To3(typename PFP::MAP& map, Dart d);
template <typename PFP>
Dart swap5To4(typename PFP::MAP& map, Dart d);
//!
/*!
* called edge removal (equivalent to G32)
*/
template <typename PFP>
void swapGen3To2(typename PFP::MAP& map, Dart d);
//!
/*!
* called multi-face removal (equivalent to G23 )
*/
template <typename PFP>
void swapGen2To3(typename PFP::MAP& map, Dart d);
/************************************************************************************************
* Flip Functions *
************************************************************************************************/
......
......@@ -38,157 +38,157 @@ namespace Modelisation
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);
}
template <typename PFP>
void hexahedronsToTetrahedrons(typename PFP::MAP& map)
{
TraversorV<typename PFP::MAP> tv(map);
//for each vertex
for(Dart d = tv.begin() ; d != tv.end() ; d = tv.next())
{
bool vertToTet=true;
std::vector<Dart> dov;
dov.reserve(32);
FunctorStore fs(dov);
map.foreach_dart_of_vertex(d,fs);
CellMarkerStore<VOLUME> cmv(map);
//check if all vertices degree is equal to 3 (= no direct adjacent vertex has been split)
for(std::vector<Dart>::iterator it=dov.begin();vertToTet && it!=dov.end();++it)
{
if(!cmv.isMarked(*it) && !map.isBoundaryMarked(*it))
{
cmv.mark(*it);
vertToTet = (map.phi1(map.phi2(map.phi1(map.phi2(map.phi1(map.phi2(*it))))))==*it); //degree = 3
}
}
//if ok : create tetrahedrons around the vertex
if(vertToTet)
{
for(std::vector<Dart>::iterator it=dov.begin();it!=dov.end();++it)
{
if(cmv.isMarked(*it) && !map.isBoundaryMarked(*it))
{
cmv.unmark(*it);
cut3Ear<PFP>(map,*it);
}
}
}
}
}
template <typename PFP>
void tetrahedrizeVolume(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position)
{
//mark bad edges
DartMarkerStore mBadEdge(map);
std::vector<Dart> vEdge;
vEdge.reserve(1024);
// unsignzed int i = 0;
unsigned int nbEdges = map.template getNbOrbits<EDGE>();
unsigned int i = 0;
for(Dart dit = map.begin() ; dit != map.end() ; map.next(dit))
{
//check if this edge is an "ear-edge"
if(!mBadEdge.isMarked(dit))
{
++i;
std::cout << i << " / " << nbEdges << std::endl;
//search three positions
typename PFP::VEC3 tris1[3];
tris1[0] = position[dit];
tris1[1] = position[map.phi_1(dit)];
tris1[2] = position[map.phi_1(map.phi2(dit))];
//search if the triangle formed by these three points intersect the rest of the mesh (intersection triangle/triangle)
TraversorF<typename PFP::MAP> travF(map);
for(Dart ditF = travF.begin() ; ditF != travF.end() ; ditF = travF.next())
{
//get vertices position
typename PFP::VEC3 tris2[3];
tris2[0] = position[ditF];
tris2[1] = position[map.phi1(ditF)];
tris2[2] = position[map.phi_1(ditF)];
bool intersection = false;
for (unsigned int i = 0; i < 3 && !intersection; ++i)
{
typename PFP::VEC3 inter;
intersection = Geom::intersectionSegmentTriangle(tris1[i], tris1[(i+1)%3], tris2[0], tris2[1], tris2[2], inter);
}
if(!intersection)
{
for (unsigned int i = 0; i < 3 && !intersection; ++i)
{
typename PFP::VEC3 inter;
intersection = Geom::intersectionSegmentTriangle(tris2[i], tris2[(i+1)%3], tris1[0], tris1[1], tris1[2], inter);
}
}
//std::cout << "intersection ? " << (intersection ? "true" : "false") << std::endl;
if(intersection)
{
mBadEdge.markOrbit<EDGE>(dit);
}
else //cut a tetrahedron
{
vEdge.push_back(dit);
}
//
// if(i == 16)
// return;
}
}
}
std::cout << "nb edges to split = " << vEdge.size() << std::endl;
i = 0;
for(std::vector<Dart>::iterator it = vEdge.begin() ; it != vEdge.end() ; ++it)
{
++i;
std::cout << i << " / " << vEdge.size() << std::endl;
Dart dit = *it;
//std::cout << "cut cut " << std::endl;
std::vector<Dart> vPath;
vPath.push_back(map.phi1(dit));
vPath.push_back(map.phi1(map.phi2(map.phi_1(dit))));
vPath.push_back(map.phi_1(map.phi2(dit)));
map.splitVolume(vPath);
map.splitFace(map.phi2(map.phi1(dit)), map.phi2(map.phi1(map.phi2(dit))));
}
std::cout << "finished " << std::endl;
}
//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))));
//
// Algo::Modelisation::cut3Ear<PFP>(map,d1);
// Algo::Modelisation::cut3Ear<PFP>(map,d2);
// Algo::Modelisation::cut3Ear<PFP>(map,d3);
// Algo::Modelisation::cut3Ear<PFP>(map,d4);
//}
//
//template <typename PFP>
//void hexahedronsToTetrahedrons(typename PFP::MAP& map)
//{
// TraversorV<typename PFP::MAP> tv(map);
//
// //for each vertex
// for(Dart d = tv.begin() ; d != tv.end() ; d = tv.next())
// {
// bool vertToTet=true;
// std::vector<Dart> dov;
// dov.reserve(32);
// FunctorStore fs(dov);
// map.foreach_dart_of_vertex(d,fs);
// CellMarkerStore<VOLUME> cmv(map);
//
// //check if all vertices degree is equal to 3 (= no direct adjacent vertex has been split)
// for(std::vector<Dart>::iterator it=dov.begin();vertToTet && it!=dov.end();++it)
// {
// if(!cmv.isMarked(*it) && !map.isBoundaryMarked(*it))
// {
// cmv.mark(*it);
// vertToTet = (map.phi1(map.phi2(map.phi1(map.phi2(map.phi1(map.phi2(*it))))))==*it); //degree = 3
// }
// }
//
// //if ok : create tetrahedrons around the vertex
// if(vertToTet)
// {
// for(std::vector<Dart>::iterator it=dov.begin();it!=dov.end();++it)
// {
// if(cmv.isMarked(*it) && !map.isBoundaryMarked(*it))
// {
// cmv.unmark(*it);
// cut3Ear<PFP>(map,*it);
// }
// }
// }
// }
//}
//
//template <typename PFP>
//void tetrahedrizeVolume(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& position)
//{
// //mark bad edges
// DartMarkerStore mBadEdge(map);
//
// std::vector<Dart> vEdge;
// vEdge.reserve(1024);
//
//// unsignzed int i = 0;
//
// unsigned int nbEdges = map.template getNbOrbits<EDGE>();
// unsigned int i = 0;
//
// for(Dart dit = map.begin() ; dit != map.end() ; map.next(dit))
// {
// //check if this edge is an "ear-edge"
// if(!mBadEdge.isMarked(dit))
// {
// ++i;
// std::cout << i << " / " << nbEdges << std::endl;
//
// //search three positions
// typename PFP::VEC3 tris1[3];
// tris1[0] = position[dit];
// tris1[1] = position[map.phi_1(dit)];
// tris1[2] = position[map.phi_1(map.phi2(dit))];
//
// //search if the triangle formed by these three points intersect the rest of the mesh (intersection triangle/triangle)
// TraversorF<typename PFP::MAP> travF(map);
// for(Dart ditF = travF.begin() ; ditF != travF.end() ; ditF = travF.next())
// {
// //get vertices position
// typename PFP::VEC3 tris2[3];
// tris2[0] = position[ditF];
// tris2[1] = position[map.phi1(ditF)];
// tris2[2] = position[map.phi_1(ditF)];
//
// bool intersection = false;
//
// for (unsigned int i = 0; i < 3 && !intersection; ++i)
// {
// typename PFP::VEC3 inter;
// intersection = Geom::intersectionSegmentTriangle(tris1[i], tris1[(i+1)%3], tris2[0], tris2[1], tris2[2], inter);
// }
//
// if(!intersection)
// {
// for (unsigned int i = 0; i < 3 && !intersection; ++i)
// {
// typename PFP::VEC3 inter;
// intersection = Geom::intersectionSegmentTriangle(tris2[i], tris2[(i+1)%3], tris1[0], tris1[1], tris1[2], inter);
// }
// }
//
// //std::cout << "intersection ? " << (intersection ? "true" : "false") << std::endl;
//
// if(intersection)
// {
// mBadEdge.markOrbit<EDGE>(dit);
// }
// else //cut a tetrahedron
// {
// vEdge.push_back(dit);
// }
//
//
////
//// if(i == 16)
//// return;
// }
// }
// }
//
// std::cout << "nb edges to split = " << vEdge.size() << std::endl;
// i = 0;
// for(std::vector<Dart>::iterator it = vEdge.begin() ; it != vEdge.end() ; ++it)
// {
// ++i;
// std::cout << i << " / " << vEdge.size() << std::endl;
//
// Dart dit = *it;
//
// //std::cout << "cut cut " << std::endl;
// std::vector<Dart> vPath;
//
// vPath.push_back(map.phi1(dit));
// vPath.push_back(map.phi1(map.phi2(map.phi_1(dit))));
// vPath.push_back(map.phi_1(map.phi2(dit)));
//
// map.splitVolume(vPath);
//
// map.splitFace(map.phi2(map.phi1(dit)), map.phi2(map.phi1(map.phi2(dit))));
// }
//
// std::cout << "finished " << std::endl;
//}
/************************************************************************************************
......@@ -271,7 +271,6 @@ bool isTetrahedralization(typename PFP::MAP& map, const FunctorSelect& selected)
* swap functions *
***********************************************************************************************/
//ok
template <typename PFP>
Dart swap2To2(typename PFP::MAP& map, Dart d)
{
......@@ -282,21 +281,20 @@ Dart swap2To2(typename PFP::MAP& map, Dart d)
map.mergeFaces(map.phi1(d2_1));
map.splitFace(d2_1, map.phi1(map.phi1(d2_1)));
Dart stop = map.phi_1(d2_1);
Dart dit = stop;
do
{
edges.push_back(dit);
dit = map.phi1(map.phi2(map.phi1(dit)));
}
while(dit != stop);
Dart stop = map.phi_1(d2_1);
Dart dit = stop;
do
{
edges.push_back(dit);
dit = map.phi1(map.phi2(map.phi1(dit)));
}
while(dit != stop);
map.splitVolume(edges);
map.splitVolume(edges);
return map.phi2(stop);
}
//ok
template <typename PFP>
void swap4To4(typename PFP::MAP& map, Dart d)
{
......@@ -404,6 +402,54 @@ Dart swap5To4(typename PFP::MAP& map, Dart d)
return t1;
}
template <typename PFP>
void swapGen3To2(typename PFP::MAP& map, Dart d)
{
unsigned int n = map.edgeDegree(d);
if(n >= 4)
{
Dart dit = d;
if(map.isBoundaryEdge(dit))
{
for(unsigned int i = 0 ; i < n - 2 ; ++i)
{
dit = map.phi2(Algo::Modelisation::Tetrahedralization::swap2To3<PFP>(map, dit));
}
Algo::Modelisation::Tetrahedralization::swap2To2<PFP>(map, dit);
}
else
{
for(unsigned int i = 0 ; i < n - 4 ; ++i)
{
dit = map.phi2(Algo::Modelisation::Tetrahedralization::swap2To3<PFP>(map, dit));
}
Algo::Modelisation::Tetrahedralization::swap4To4<PFP>(map, map.alpha2(dit));
}
}
else if (n == 3)
{
Dart dres = Algo::Modelisation::Tetrahedralization::swap2To3<PFP>(map, d);
Algo::Modelisation::Tetrahedralization::swap2To2<PFP>(map, map.phi2(dres));
}
else // si (n == 2)
{
Algo::Modelisation::Tetrahedralization::swap2To2<PFP>(map, d);
}
}
template <typename PFP>
void swapGen2To3(typename PFP::MAP& map, Dart d)
{
//- a single 2-3 swap, followed by n − 3 3-2 swaps, or
//– a single 4-4 swap, followed by n − 4 3-2 swaps.
}
/************************************************************************************************
* Flip Functions *
************************************************************************************************/
......@@ -528,23 +574,29 @@ Dart edgeBisection(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP:
position[e] += position[f];
position[e] *= 0.5;
map.splitFace(e, map.phi1(map.phi1(e)));
Dart stop = map.alpha2(e);
Dart dit = stop;
std::vector<Dart> edges;
Dart dit = e;
do
{
map.splitFace(dit, map.phi1(map.phi1(dit)));
edges.clear();
Dart dit3 = map.phi3(dit);
edges.push_back(map.phi1(dit3));
edges.push_back(map.phi1(map.phi2(map.phi1(edges[0]))));
edges.push_back(map.phi_1(map.phi2(dit3)));
map.splitVolume(edges);
dit = map.alpha2(dit);
}
while(dit != e);
dit = e;
std::vector<Dart> edges;
do
{
if(!map.isBoundaryMarked(dit))
{
edges.push_back(map.phi_1(dit));
edges.push_back(map.phi_1(map.phi2(map.phi_1(edges[0]))));
edges.push_back(map.phi1(map.phi2(dit)));
map.splitVolume(edges);
edges.clear();
}
dit = map.alpha2(dit);
}while(dit != stop);
}
while(dit != e);
return e;
}
......
......@@ -551,7 +551,7 @@ void Map2::splitSurface(std::vector<Dart>& vd, bool firstSideClosed, bool second
//unsew the edge path
for(std::vector<Dart>::iterator it = vd.begin() ; it != vd.end() ; ++it)
{
if(!Map2::isBoundaryEdge(*it))
//if(!Map2::isBoundaryEdge(*it))
unsewFaces(*it) ;
}
......
......@@ -940,7 +940,8 @@ unsigned int Map3::edgeDegree(Dart d)
Dart it = d;
do
{
++deg;
if(!isBoundaryMarked(it))
++deg;
it = alpha2(it);
} while(it != d);
return deg;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment