Commit a1b6ef07 authored by Sauvage's avatar Sauvage

decimation : ajout du critere Normal Area

parent 3b5c2a93
......@@ -157,6 +157,9 @@ void decimate(
case S_Curvature :
selector = new EdgeSelector_Curvature<PFP>(map, position, approximators, selected) ;
break ;
case S_NormalArea :
selector = new EdgeSelector_NormalArea<PFP>(map, position, approximators, selected) ;
break ;
case S_MinDetail :
selector = new EdgeSelector_MinDetail<PFP>(map, position, approximators, selected) ;
break ;
......
......@@ -268,6 +268,60 @@ public:
void updateWithoutCollapse() { }
} ;
template <typename PFP>
class EdgeSelector_NormalArea : public EdgeSelector<PFP>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
private:
typedef struct
{
typename std::multimap<float,Dart>::iterator it ;
bool valid ;
static std::string CGoGNnameOfType() { return "NormalAreaEdgeInfo" ; }
} NormalAreaEdgeInfo ;
typedef NoMathIOAttribute<NormalAreaEdgeInfo> EdgeInfo ;
EdgeAttribute<EdgeInfo> edgeInfo ;
EdgeAttribute<Geom::Matrix<3,3,REAL> > edgeMatrix ;
std::multimap<float,Dart> edges ;
typename std::multimap<float,Dart>::iterator cur ;
Approximator<PFP, typename PFP::VEC3, EDGE>* m_positionApproximator ;
void initEdgeInfo(Dart d) ;
void updateEdgeInfo(Dart d) ;
void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;
// void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;
public:
EdgeSelector_NormalArea(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select) :
EdgeSelector<PFP>(m, pos, approx, select),
m_positionApproximator(NULL)
{
edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
edgeMatrix = m.template addAttribute<Geom::Matrix<3,3,REAL>, EDGE>("NormalAreaMatrix") ;
}
~EdgeSelector_NormalArea()
{
this->m_map.removeAttribute(edgeMatrix) ;
this->m_map.removeAttribute(edgeInfo) ;
}
SelectorType getType() { return S_NormalArea ; }
bool init() ;
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() { }
} ;
template <typename PFP>
class EdgeSelector_Curvature : public EdgeSelector<PFP>
{
......
......@@ -727,6 +727,198 @@ void EdgeSelector_QEMml<PFP>::computeEdgeInfo(Dart d, EdgeInfo& einfo)
einfo.valid = true ;
}
/************************************************************************************
* Metric based on Face Normal and Area deviation *
************************************************************************************/
template <typename PFP>
bool EdgeSelector_NormalArea<PFP>::init()
{
MAP& m = this->m_map ;
bool ok = false ;
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = this->m_approximators.begin();
it != this->m_approximators.end() && !ok;
++it)
{
if((*it)->getApproximatedAttributeName() == "position")
{
assert((*it)->getType() == A_MidEdge || !"Only MidEdge Approximator is valid") ;
m_positionApproximator = reinterpret_cast<Approximator<PFP, VEC3,EDGE>* >(*it) ;
ok = true ;
}
}
if(!ok)
return false ;
edges.clear() ;
TraversorE<MAP> travE(m);
for(Dart dit = travE.begin() ; dit != travE.end() ; dit = travE.next())
{
const VEC3 e = Algo::Geometry::vectorOutOfDart<PFP>(m, dit, this->m_position) ;
edgeMatrix[dit].identity();
edgeMatrix[dit] *= e.norm2();
edgeMatrix[dit] -= Geom::transposed_vectors_mult(e,e) ;
}
for(Dart dit = travE.begin() ; dit != travE.end() ; dit = travE.next())
{
initEdgeInfo(dit) ; // init "edgeInfo" and "edges"
}
cur = edges.begin() ; // init the current edge to the first one
return true ;
}
template <typename PFP>
bool EdgeSelector_NormalArea<PFP>::nextEdge(Dart& d)
{
if(cur == edges.end() || edges.empty())
return false ;
d = (*cur).second ;
return true ;
}
template <typename PFP>
void EdgeSelector_NormalArea<PFP>::updateBeforeCollapse(Dart d)
{
MAP& m = this->m_map ;
assert(!m.isBoundaryEdge(d));
EdgeInfo& edgeE = edgeInfo[d] ;
if(edgeE.valid)
{ edges.erase(edgeE.it) ; edgeE.valid = false;}
edgeE = edgeInfo[m.phi1(d)] ;
if(edgeE.valid) // remove all
{ edges.erase(edgeE.it) ; edgeE.valid = false;}
edgeE = edgeInfo[m.phi_1(d)] ; // the concerned edges
if(edgeE.valid)
{ edges.erase(edgeE.it) ; edgeE.valid = false;}
// from the multimap
Dart dd = m.phi2(d) ;
edgeE = edgeInfo[m.phi1(dd)] ;
if(edgeE.valid)
{ edges.erase(edgeE.it) ; edgeE.valid = false;}
edgeE = edgeInfo[m.phi_1(dd)] ;
if(edgeE.valid)
{ edges.erase(edgeE.it) ; edgeE.valid = false;}
}
template <typename PFP>
void EdgeSelector_NormalArea<PFP>::updateAfterCollapse(Dart d2, Dart dd2)
{
MAP& m = this->m_map ;
// update the edge matrices
Traversor2VE<MAP> te (m,d2);
for(Dart dit = te.begin() ; dit != te.end() ; dit = te.next())
{
const VEC3 e = Algo::Geometry::vectorOutOfDart<PFP>(m, dit, this->m_position) ;
edgeMatrix[dit].identity();
edgeMatrix[dit] *= e.norm2();
edgeMatrix[dit] -= Geom::transposed_vectors_mult(e,e) ;
}
// update the multimap
Traversor2VVaE<MAP> tv (m,d2);
CellMarker<EDGE> eMark (m);
for(Dart dit = tv.begin() ; dit != tv.end() ; dit = tv.next())
{
Traversor2VE<MAP> te2 (m,dit);
for(Dart dit2 = te2.begin() ; dit2 != te2.end() ; dit2 = te2.next())
{
if (!eMark.isMarked(dit2))
{
updateEdgeInfo(dit2) ;
eMark.mark(dit2);
}
}
}
cur = edges.begin() ; // set the current edge to the first one
}
template <typename PFP>
void EdgeSelector_NormalArea<PFP>::initEdgeInfo(Dart d)
{
MAP& m = this->m_map ;
EdgeInfo einfo ;
if(m.edgeCanCollapse(d))
computeEdgeInfo(d, einfo) ;
else
einfo.valid = false ;
edgeInfo[d] = einfo ;
}
template <typename PFP>
void EdgeSelector_NormalArea<PFP>::updateEdgeInfo(Dart d)
{
MAP& m = this->m_map ;
EdgeInfo& einfo = edgeInfo[d] ;
if(einfo.valid)
edges.erase(einfo.it) ; // remove the edge from the multimap
if(m.edgeCanCollapse(d))
computeEdgeInfo(d, einfo) ;
else
einfo.valid = false ;
}
template <typename PFP>
void EdgeSelector_NormalArea<PFP>::computeEdgeInfo(Dart d, EdgeInfo& einfo)
{
MAP& m = this->m_map ;
Dart dd = m.phi2(d);
Geom::Matrix33f M1; // init zero included
Geom::Matrix33f M2; // init zero included
assert(! m.isBoundaryEdge(d));
Traversor2VF<MAP> td (m,d);
Dart it = td.begin();
it = td.next();
Dart it2 = td.next();
while( it2 != td.end())
{
M1 += edgeMatrix[m.phi1(it)];
it = it2;
it2 = td.next();
}
Traversor2VF<MAP> tdd (m,dd);
it = tdd.begin();
it = tdd.next();
it2 = tdd.next();
while( it2 != tdd.end())
{
M2 += edgeMatrix[m.phi1(it)];
it = it2;
it2 = tdd.next();
}
m_positionApproximator->approximate(d) ;
const VEC3& a = m_positionApproximator->getApprox(d) ;
const VEC3 av1 = a - this->m_position[d] ;
const VEC3 av2 = a - this->m_position[dd] ;
REAL err = av1 * (M1 * av1) + av2 * (M2 * av2);
einfo.it = edges.insert(std::make_pair(err, d)) ;
einfo.valid = true ;
}
/************************************************************************************
* CURVATURE *
************************************************************************************/
......
......@@ -43,6 +43,7 @@ enum SelectorType
S_QEMml,
S_MinDetail,
S_Curvature,
S_NormalArea,
S_ColorNaive,
S_QEMextColor,
S_Lightfield,
......
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