Commit f243d02b authored by untereiner's avatar untereiner

Adaptive Primal subdivision into Algo/Multiresolution/

parent a91ee675
......@@ -29,6 +29,7 @@
#include "Topology/generic/traversorCell.h"
#include "Topology/generic/traversor2.h"
#include "Container/attributeContainer.h"
#include "Algo/Decimation/selector.h"
#include "Algo/Decimation/edgeSelector.h"
......
......@@ -136,15 +136,20 @@ void Map2MR_PM<PFP>::createPM(Algo::Decimation::SelectorType s, Algo::Decimation
template <typename PFP>
void Map2MR_PM<PFP>::addNewLevel(unsigned int percentWantedVertices)
{
// level handling
m_map.pushLevel() ;
m_map.addLevelBack();
m_map.duplicateDarts(m_map.getMaxLevel());
m_map.setCurrentLevel(m_map.getMaxLevel());
unsigned int nbVertices = m_map.template getNbOrbits<VERTEX>() ;
unsigned int nbWantedVertices = nbVertices * percentWantedVertices / 100 ;
CGoGNout << " creating PM (" << nbVertices << " vertices).." << /* flush */ CGoGNendl ;
unsigned int nbDeletedVertex=0;
unsigned int percentWantedPerLevel = 20;
unsigned int nbWantedPerLevel = nbWantedVertices * percentWantedPerLevel / 100 ;
//create the new level
m_map.addLevelFront();
m_map.setCurrentLevel(0);
m_map.printMR();
DartMarkerStore me(m_map); //mark edges not to collapse
bool finished = false ;
Dart d ;
......@@ -153,39 +158,194 @@ void Map2MR_PM<PFP>::addNewLevel(unsigned int percentWantedVertices)
if(!m_selector->nextEdge(d))
break ;
--nbVertices ;
Dart d2 = m_map.phi2(m_map.phi_1(d)) ;
Dart dd2 = m_map.phi2(m_map.phi_1(m_map.phi2(d))) ;
for(typename std::vector<Algo::Decimation::ApproximatorGen<PFP>*>::iterator it = m_approximators.begin(); it != m_approximators.end(); ++it)
if(!me.isMarked(d))
{
(*it)->approximate(d) ; // compute approximated attributes with its associated detail
(*it)->saveApprox(d) ;
}
m_selector->updateBeforeCollapse(d) ; // update selector
//me.mark le 1 voisinage
Dart dt = d;
do
{
Dart dit = dt;
do
{
me.mark(m_map.phi1(dit));
me.mark(m_map.phi1(m_map.phi1(dit)));
dit = m_map.phi2(m_map.phi_1(dit));
}
while(dit != dt);
dt = m_map.phi1(dt);
}while(dt != d);
dt = m_map.phi2(d);
do
{
Dart dit = dt;
do
{
me.mark(m_map.phi1(dit));
me.mark(m_map.phi1(m_map.phi1(dit)));
dit = m_map.phi2(m_map.phi_1(dit));
}
while(dit != dt);
dt = m_map.phi1(dt);
}while(dt != m_map.phi2(d));
collapseEdge(d);
//incremente le dartLevel des brins des faces supprime
m_map.incDartLevel(d);
m_map.incDartLevel(m_map.phi1(d));
m_map.incDartLevel(m_map.phi_1(d));
m_map.incDartLevel(m_map.phi2(d));
m_map.incDartLevel(m_map.phi_1(m_map.phi2(d)));
m_map.incDartLevel(m_map.phi1(m_map.phi2(d)));
unsigned int newV = m_map.template embedNewCell<VERTEX>(d2) ;
unsigned int newE1 = m_map.template embedNewCell<EDGE>(d2) ;
unsigned int newE2 = m_map.template embedNewCell<EDGE>(dd2) ;
// vs->setApproxV(newV) ;
// vs->setApproxE1(newE1) ;
// vs->setApproxE2(newE2) ;
++nbDeletedVertex ;
for(typename std::vector<Algo::Decimation::ApproximatorGen<PFP>*>::iterator it = m_approximators.begin(); it != m_approximators.end(); ++it)
(*it)->affectApprox(d2); // affect data to the resulting vertex
Dart d2 = m_map.phi2(m_map.phi_1(d)) ;
Dart dd2 = m_map.phi2(m_map.phi_1(m_map.phi2(d))) ;
m_selector->updateAfterCollapse(d2, dd2) ; // update selector
m_selector->updateBeforeCollapse(d) ; // update selector
if(nbVertices <= nbWantedVertices)
finished = true ;
collapseEdge(d);
m_selector->updateAfterCollapse(d2, dd2) ; // update selector
if(nbDeletedVertex <= nbWantedPerLevel)
finished = true ;
}
}
m_map.popLevel();
CGoGNout << "..done (" << nbVertices << " vertices)" << CGoGNendl ;
CGoGNout << "..done (" << nbDeletedVertex << " vertices)" << CGoGNendl ;
m_map.printMR();
// DartMarkerStore me(m_map); //mark edges not to collapse
// DartMarkerStore mc(m_map); //mark darts to collapse
// std::vector<Dart> ec; //save a dart from edge to collapse
//
// for(Dart d = m_map.begin() ; d != m_map.end() ; m_map.next(d))
// {
// if(!me.isMarked(d))
// {
// Dart dt = d;
// do
// {
// Dart dit = dt;
// do
// {
// me.mark(m_map.phi1(dit));
// me.mark(m_map.phi1(m_map.phi1(dit)));
// dit = m_map.phi2(m_map.phi_1(dit));
// }
// while(dit != dt);
//
// dt = m_map.phi1(dt);
// }while(dt != d);
//
// dt = m_map.phi2(d);
// do
// {
// Dart dit = dt;
// do
// {
// me.mark(m_map.phi1(dit));
// me.mark(m_map.phi1(m_map.phi1(dit)));
// dit = m_map.phi2(m_map.phi_1(dit));
// }
// while(dit != dt);
//
// dt = m_map.phi1(dt);
// }while(dt != m_map.phi2(d));
//
//
// ec.push_back(d);
//
// mc.mark(d);
// mc.mark(m_map.phi1(d));
// mc.mark(m_map.phi_1(d));
// mc.mark(m_map.phi2(d));
// mc.mark(m_map.phi_1(m_map.phi2(d)));
// mc.mark(m_map.phi1(m_map.phi2(d)));
// }
// }
// //create the new level
// m_map.addLevelFront();
//
// AttributeContainer& cont = m_map.getMRAttributeContainer();
// AttributeMultiVector<unsigned int>* amv = m_map.getMRDartAttributeVector(m_map.getCurrentLevel());
// for(unsigned int i = cont.begin() ; i < cont.end() ; cont.next(i))
// {
// if(mc.isMarked((*amv)[i]) || (*amv)[i] == NULL)
// {
// //mrlevel++
// }
//
//
// //(*amv)[i] = MRNULL ;
// }
//
//
// for(std::vector<Dart>::iterator it = ec.begin() ; it != ec.end() ; ++it)
// {
//
// }
// // level handling
// m_map.pushLevel() ;
// m_map.addLevelBack();
// m_map.duplicateDarts(m_map.getMaxLevel());
// m_map.setCurrentLevel(m_map.getMaxLevel());
//
// unsigned int nbVertices = m_map.template getNbOrbits<VERTEX>() ;
// unsigned int nbWantedVertices = nbVertices * percentWantedVertices / 100 ;
// CGoGNout << " creating PM (" << nbVertices << " vertices).." << /* flush */ CGoGNendl ;
//
// bool finished = false ;
// Dart d ;
// while(!finished)
// {
// if(!m_selector->nextEdge(d))
// break ;
//
// --nbVertices ;
// Dart d2 = m_map.phi2(m_map.phi_1(d)) ;
// Dart dd2 = m_map.phi2(m_map.phi_1(m_map.phi2(d))) ;
//
// for(typename std::vector<Algo::Decimation::ApproximatorGen<PFP>*>::iterator it = m_approximators.begin(); it != m_approximators.end(); ++it)
// {
// (*it)->approximate(d) ; // compute approximated attributes with its associated detail
// (*it)->saveApprox(d) ;
// }
//
// m_selector->updateBeforeCollapse(d) ; // update selector
//
// collapseEdge(d);
//
// unsigned int newV = m_map.template embedNewCell<VERTEX>(d2) ;
// unsigned int newE1 = m_map.template embedNewCell<EDGE>(d2) ;
// unsigned int newE2 = m_map.template embedNewCell<EDGE>(dd2) ;
//// vs->setApproxV(newV) ;
//// vs->setApproxE1(newE1) ;
//// vs->setApproxE2(newE2) ;
//
// for(typename std::vector<Algo::Decimation::ApproximatorGen<PFP>*>::iterator it = m_approximators.begin(); it != m_approximators.end(); ++it)
// (*it)->affectApprox(d2); // affect data to the resulting vertex
//
// m_selector->updateAfterCollapse(d2, dd2) ; // update selector
//
// if(nbVertices <= nbWantedVertices)
// finished = true ;
// }
//
// m_map.popLevel();
//
// CGoGNout << "..done (" << nbVertices << " vertices)" << CGoGNendl ;
}
......@@ -193,21 +353,14 @@ template <typename PFP>
void Map2MR_PM<PFP>::collapseEdge(Dart d)
{
//duplication :
m_map.duplicateMRDart(m_map.phi2(m_map.phi1(d)));
m_map.duplicateMRDart(m_map.phi2(m_map.phi_1(d)));
m_map.duplicateMRDart(m_map.phi2(m_map.phi1(m_map.phi2(d))));
m_map.duplicateMRDart(m_map.phi2(m_map.phi_1(m_map.phi2(d))));
m_map.duplicateDart(m_map.phi2(m_map.phi1(d)));
m_map.duplicateDart(m_map.phi2(m_map.phi_1(d)));
m_map.duplicateDart(m_map.phi2(m_map.phi1(m_map.phi2(d))));
m_map.duplicateDart(m_map.phi2(m_map.phi_1(m_map.phi2(d))));
//effacer :
// m_map.unrefMRDart(m_map.phi1(m_map.phi2(d)));
// m_map.unrefMRDart(m_map.phi_1(m_map.phi2(d)));
// m_map.unrefMRDart(m_map.phi2(d));
//
// m_map.unrefMRDart(m_map.phi1(d));
// m_map.unrefMRDart(m_map.phi_1(d));
// m_map.unrefMRDart(d);
//m_map.collapseEdge(d);
m_map.collapseEdge(d);
m_map.extractTrianglePair(d);
}
......
......@@ -34,7 +34,6 @@
namespace CGoGN
{
}
namespace Algo
{
......@@ -124,19 +123,6 @@ public:
* SUBDIVISION *
***************************************************/
/**
* add a new resolution level
*/
void addNewLevel(bool embedNewVertices = true) ;
void propagateDartRelation(Dart d, AttributeMultiVector<Dart>* rel) ;
template <unsigned int ORBIT>
void propagateDartEmbedding(Dart d) ;
template <unsigned int ORBIT>
void propagateOrbitEmbedding(Dart d) ;
Dart cutEdge(Dart d) ;
void splitFace(Dart d, Dart e) ;
......@@ -155,7 +141,9 @@ public:
/**
* subdivide the face of d to the next level
*/
unsigned int subdivideFace(Dart d) ;
unsigned int subdivideFace(Dart d, bool triQuad = true) ;
unsigned int subdivideFace2(Dart d) ;
/**
* coarsen the face of d from the next level
......
......@@ -56,25 +56,25 @@ Map2MR<PFP>::Map2MR(typename PFP::MAP& map) :
template <typename PFP>
unsigned int Map2MR<PFP>::edgeLevel(Dart d)
{
assert(getDartLevel(d) <= getCurrentLevel() || !"edgeLevel : called with a dart inserted after current level") ;
assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"edgeLevel : called with a dart inserted after current level") ;
unsigned int ld = getDartLevel(d) ;
unsigned int ldd = getDartLevel(phi2(d)) ; // the level of an edge is the maximum of the
unsigned int ld = m_map.getDartLevel(d) ;
unsigned int ldd = m_map.getDartLevel(m_map.phi2(d)) ; // the level of an edge is the maximum of the
return ld > ldd ? ld : ldd ; // insertion levels of its two darts
}
template <typename PFP>
unsigned int Map2MR<PFP>::faceLevel(Dart d)
{
assert(getDartLevel(d) <= getCurrentLevel() || !"faceLevel : called with a dart inserted after current level") ;
assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"faceLevel : called with a dart inserted after current level") ;
if(getCurrentLevel() == 0)
if(m_map.getCurrentLevel() == 0)
return 0 ;
Dart it = d ;
unsigned int min1 = getDartLevel(it) ; // the level of a face is the second minimum of the
it = phi1(it) ;
unsigned int min2 = getDartLevel(it) ; // insertion levels of its darts
unsigned int min1 = m_map.getDartLevel(it) ; // the level of a face is the second minimum of the
it = m_map.phi1(it) ;
unsigned int min2 = m_map.getDartLevel(it) ; // insertion levels of its darts
if(min2 < min1)
{
......@@ -83,10 +83,10 @@ unsigned int Map2MR<PFP>::faceLevel(Dart d)
min2 = tmp ;
}
it = phi1(it) ;
it = m_map.phi1(it) ;
while(it != d)
{
unsigned int dl = getDartLevel(it) ;
unsigned int dl = m_map.getDartLevel(it) ;
if(dl < min2)
{
if(dl < min1)
......@@ -97,7 +97,7 @@ unsigned int Map2MR<PFP>::faceLevel(Dart d)
else
min2 = dl ;
}
it = phi1(it) ;
it = m_map.phi1(it) ;
}
return min2 ;
......@@ -106,32 +106,32 @@ unsigned int Map2MR<PFP>::faceLevel(Dart d)
template <typename PFP>
Dart Map2MR<PFP>::faceOrigin(Dart d)
{
assert(getDartLevel(d) <= getCurrentLevel() || !"faceOrigin : called with a dart inserted after current level") ;
assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"faceOrigin : called with a dart inserted after current level") ;
pushLevel() ;
m_map.pushLevel() ;
Dart p = d ;
unsigned int pLevel = getDartLevel(p) ;
unsigned int pLevel = m_map.getDartLevel(p) ;
while(pLevel > 0)
{
p = faceOldestDart(p) ;
pLevel = getDartLevel(p) ;
setCurrentLevel(pLevel) ;
p = m_map.faceOldestDart(p) ;
pLevel = m_map.getDartLevel(p) ;
m_map.setCurrentLevel(pLevel) ;
}
popLevel() ;
m_map.popLevel() ;
return p ;
}
template <typename PFP>
Dart Map2MR<PFP>::faceOldestDart(Dart d)
{
assert(getDartLevel(d) <= getCurrentLevel() || !"faceOldestDart : called with a dart inserted after current level") ;
assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"faceOldestDart : called with a dart inserted after current level") ;
Dart it = d ;
Dart oldest = it ;
unsigned int l_old = getDartLevel(oldest) ;
unsigned int l_old = m_map.getDartLevel(oldest) ;
do
{
unsigned int l = getDartLevel(it) ;
unsigned int l = m_map.getDartLevel(it) ;
if(l == 0)
return it ;
if(l < l_old)
......@@ -139,7 +139,7 @@ Dart Map2MR<PFP>::faceOldestDart(Dart d)
oldest = it ;
l_old = l ;
}
it = phi1(it) ;
it = m_map.phi1(it) ;
} while(it != d) ;
return oldest ;
}
......@@ -147,15 +147,15 @@ Dart Map2MR<PFP>::faceOldestDart(Dart d)
template <typename PFP>
bool Map2MR<PFP>::edgeIsSubdivided(Dart d)
{
assert(getDartLevel(d) <= getCurrentLevel() || !"edgeIsSubdivided : called with a dart inserted after current level") ;
assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"edgeIsSubdivided : called with a dart inserted after current level") ;
if(getCurrentLevel() == getMaxLevel())
if(m_map.getCurrentLevel() == m_map.getMaxLevel())
return false ;
Dart d2 = phi2(d) ;
incCurrentLevel() ;
Dart d2_l = phi2(d) ;
decCurrentLevel() ;
Dart d2 = m_map.phi2(d) ;
m_map.incCurrentLevel() ;
Dart d2_l = m_map.phi2(d) ;
m_map.decCurrentLevel() ;
if(d2 != d2_l)
return true ;
else
......@@ -165,22 +165,22 @@ bool Map2MR<PFP>::edgeIsSubdivided(Dart d)
template <typename PFP>
bool Map2MR<PFP>::edgeCanBeCoarsened(Dart d)
{
assert(getDartLevel(d) <= getCurrentLevel() || !"edgeCanBeCoarsened : called with a dart inserted after current level") ;
assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"edgeCanBeCoarsened : called with a dart inserted after current level") ;
if(edgeIsSubdivided(d))
{
bool subdOnce = true ;
bool degree2 = false ;
Dart d2 = phi2(d) ;
incCurrentLevel() ;
if(vertexDegree(phi1(d)) == 2)
Dart d2 = m_map.phi2(d) ;
m_map.incCurrentLevel() ;
if(m_map.vertexDegree(m_map.phi1(d)) == 2)
{
degree2 = true ;
if(edgeIsSubdivided(d) || edgeIsSubdivided(d2))
subdOnce = false ;
}
decCurrentLevel() ;
m_map.decCurrentLevel() ;
return degree2 && subdOnce ;
}
......@@ -191,75 +191,75 @@ bool Map2MR<PFP>::edgeCanBeCoarsened(Dart d)
template <typename PFP>
bool Map2MR<PFP>::faceIsSubdivided(Dart d)
{
assert(getDartLevel(d) <= getCurrentLevel() || !"faceIsSubdivided : called with a dart inserted after current level") ;
assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"faceIsSubdivided : called with a dart inserted after current level") ;
if(getCurrentLevel() == getMaxLevel())
if(m_map.getCurrentLevel() == m_map.getMaxLevel())
return false ;
unsigned int fLevel = faceLevel(d) ;
if(fLevel < getCurrentLevel()) // a face whose level in the current level map is lower than
if(fLevel < m_map.getCurrentLevel()) // a face whose level in the current level map is lower than
return false ; // the current level can not be subdivided to higher levels
bool subd = false ;
incCurrentLevel() ;
if(getDartLevel(phi1(phi1(d))) == getCurrentLevel())
m_map.incCurrentLevel() ;
if(m_map.getDartLevel(m_map.phi1(m_map.phi1(d))) == m_map.getCurrentLevel())
subd = true ;
decCurrentLevel() ;
m_map.decCurrentLevel() ;
return subd ;
}
template <typename PFP>
bool Map2MR<PFP>::faceIsSubdividedOnce(Dart d)
{
assert(getDartLevel(d) <= getCurrentLevel() || !"faceIsSubdividedOnce : called with a dart inserted after current level") ;
assert(m_map.getDartLevel(d) <= m_map.getCurrentLevel() || !"faceIsSubdividedOnce : called with a dart inserted after current level") ;
if(getCurrentLevel() == getMaxLevel())
if(m_map.getCurrentLevel() == m_map.getMaxLevel())
return false ;
unsigned int fLevel = faceLevel(d) ;
if(fLevel < getCurrentLevel()) // a face whose level in the current level map is lower than
if(fLevel < m_map.getCurrentLevel()) // a face whose level in the current level map is lower than
return false ; // the current level can not be subdivided to higher levels
unsigned int degree = 0 ;
bool subd = false ;
bool subdOnce = true ;
incCurrentLevel() ;
if(getDartLevel(phi1(phi1(d))) == getCurrentLevel())
m_map.incCurrentLevel() ;
if(m_map.getDartLevel(m_map.phi1(m_map.phi1(d))) == m_map.getCurrentLevel())
subd = true ;
decCurrentLevel() ;
m_map.decCurrentLevel() ;
if(subd)
{
incCurrentLevel() ;
m_map.incCurrentLevel() ;
if(getCurrentLevel() == getMaxLevel())
if(m_map.getCurrentLevel() == m_map.getMaxLevel())
{
decCurrentLevel() ;
m_map.decCurrentLevel() ;
return true ;
}
Dart fit = d ;
do
{
incCurrentLevel() ;
if(getDartLevel(phi1(phi1(fit))) == getCurrentLevel())
m_map.incCurrentLevel() ;
if(m_map.getDartLevel(m_map.phi1(m_map.phi1(fit))) == m_map.getCurrentLevel())
subdOnce = false ;
decCurrentLevel() ;
m_map.decCurrentLevel() ;
++degree ;
fit = phi1(fit) ;
fit = m_map.phi1(fit) ;
} while(subdOnce && fit != d) ;
if(degree == 3 && subdOnce)
{
Dart cf = phi2(phi1(d)) ;
incCurrentLevel() ;
if(getDartLevel(phi1(phi1(cf))) == getCurrentLevel())
Dart cf = m_map.phi2(m_map.phi1(d)) ;
m_map.incCurrentLevel() ;
if(m_map.getDartLevel(m_map.phi1(m_map.phi1(cf))) == m_map.getCurrentLevel())
subdOnce = false ;
decCurrentLevel() ;
m_map.decCurrentLevel() ;
}
decCurrentLevel() ;
m_map.decCurrentLevel() ;
return subdOnce ;
}
......@@ -272,280 +272,196 @@ bool Map2MR<PFP>::faceIsSubdividedOnce(Dart d)
***************************************************/
template <typename PFP>
void Map2MR<PFP>::addNewLevel(bool embedNewVertices)
Dart Map2MR<PFP>::cutEdge(Dart d)
{
addLevelBack() ;
}
Dart dd = m_map.phi2(d) ;
Dart d1 = m_map.phi1(d);
Dart dd1 = m_map.phi1(dd);
template <typename PFP>
void Map2MR<PFP>::propagateDartRelation(Dart d, AttributeMultiVector<Dart>* rel)
{
Dart dd = (*rel)[dartIndex(d)] ;
pushLevel() ;
for(unsigned int i = getCurrentLevel() + 1; i <= getMaxLevel(); ++i)
{
setCurrentLevel(i) ;
(*rel)[dartIndex(d)] = dd ;
}
popLevel() ;
}
m_map.duplicateDart(d);
m_map.duplicateDart(dd);
m_map.duplicateDart(d1);
m_map.duplicateDart(dd1);
template <typename PFP>
template <unsigned int ORBIT>
void Map2MR<PFP>::propagateDartEmbedding(Dart d)
{
unsigned int emb = getEmbedding<ORBIT>(d) ;
pushLevel() ;