Commit 2cf8cf83 authored by Kenneth Vanhoey's avatar Kenneth Vanhoey

Merge cgogn:~sauvage/CGoGN

parents 07c46213 13636ac5
......@@ -43,6 +43,7 @@ enum ApproximatorType
A_CornerCutting,
A_TangentPredict1,
A_TangentPredict2,
A_NormalArea,
A_ColorNaive,
A_ColorQEMext,
A_Lightfield,
......
......@@ -65,6 +65,9 @@ void decimate(
case A_TangentPredict2 :
approximators.push_back(new Approximator_MidEdge<PFP>(map, attribs)) ;
break ;
case A_NormalArea :
approximators.push_back(new Approximator_NormalArea<PFP>(map, attribs)) ;
break ;
case A_hHalfCollapse :
approximators.push_back(new Approximator_HalfCollapse<PFP>(map, attribs)) ;
break ;
......
......@@ -32,6 +32,7 @@
#include "Utils/qem.h"
#include "Utils/quadricRGBfunctions.h"
#include "Algo/Geometry/curvature.h"
#include "Algo/Geometry/area.h"
namespace CGoGN
{
......@@ -297,6 +298,7 @@ private:
void initEdgeInfo(Dart d) ;
void updateEdgeInfo(Dart d) ;
void computeEdgeInfo(Dart d, EdgeInfo& einfo) ;
void computeEdgeMatrix(Dart d) ;
// void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;
public:
......
......@@ -781,7 +781,7 @@ bool EdgeSelector_NormalArea<PFP>::init()
{
if((*it)->getApproximatedAttributeName() == "position")
{
assert((*it)->getType() == A_MidEdge || !"Only MidEdge Approximator is valid") ;
// assert((*it)->getType() == A_MidEdge || (*it)->getType() == A_NormalArea || !"Only MidEdge and NormalArea Approximator are valid") ;
m_positionApproximator = reinterpret_cast<Approximator<PFP, VEC3,EDGE>* >(*it) ;
ok = true ;
}
......@@ -795,10 +795,11 @@ bool EdgeSelector_NormalArea<PFP>::init()
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) ;
computeEdgeMatrix(dit);
// 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())
......@@ -874,10 +875,7 @@ void EdgeSelector_NormalArea<PFP>::updateAfterCollapse(Dart d2, Dart dd2)
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) ;
computeEdgeMatrix(dit);
}
// update the multimap
......@@ -968,10 +966,35 @@ void EdgeSelector_NormalArea<PFP>::computeEdgeInfo(Dart d, EdgeInfo& einfo)
REAL err = av1 * (M1 * av1) + av2 * (M2 * av2);
/*
// TODO : test to normalize by area
// TODO : not border-safe
REAL area = 0.0;
Traversor2EEaV<MAP> ta (m,d);
for (Dart dita = ta.begin(); dita != ta.end(); dita=ta.next())
{
area += Algo::Geometry::triangleArea<PFP>(m,dita,this->m_position);
}
err /= area ; // résultats sensiblment identiques à ceux sans pris en compte de l'aire.
// err /= area*area ; // ca favorise la contraction des gros triangles : maillages très in-homogènes et qualité géométrique mauvaise
*/
einfo.it = edges.insert(std::make_pair(err, d)) ;
einfo.valid = true ;
}
template <typename PFP>
void EdgeSelector_NormalArea<PFP>::computeEdgeMatrix(Dart d)
{
const VEC3 e = Algo::Geometry::vectorOutOfDart<PFP>(this->m_map, d, this->m_position) ;
edgeMatrix[d].identity();
edgeMatrix[d] *= e.norm2();
edgeMatrix[d] -= Geom::transposed_vectors_mult(e,e) ;
// TODO : test : try to normalize by area
edgeMatrix[d] /= e.norm2(); // pas d'amélioration significative par rapport à la version sans normalisation
// edgeMatrix[d] /= e.norm2() * e.norm2(); // étonnament bon : sur certains maillages équivalant à la QEMml
}
/************************************************************************************
* CURVATURE *
************************************************************************************/
......
......@@ -26,6 +26,7 @@
#define __GEOMETRY_APPROXIMATOR_H__
#include "Algo/Decimation/approximator.h"
#include <Eigen/Dense>
namespace CGoGN
{
......@@ -144,6 +145,32 @@ public:
void approximate(Dart d) ;
} ;
template <typename PFP>
class Approximator_NormalArea : public Approximator<PFP, typename PFP::VEC3, EDGE>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
protected:
// VertexAttribute<Utils::Quadric<REAL> > m_quadric ;
EdgeAttribute<Geom::Matrix<3,3,REAL> > edgeMatrix ;
public:
Approximator_NormalArea(MAP& m, std::vector<VertexAttribute<VEC3>* > pos, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3, EDGE>(m, pos, pred)
{
assert(pos.size() > 0 || !"Approximator_NormalArea: attribute vector is empty") ;
}
~Approximator_NormalArea()
{}
ApproximatorType getType() const { return A_NormalArea ; }
bool init() ;
void approximate(Dart d) ;
} ;
} //namespace Decimation
} //namespace Algo
......
......@@ -368,6 +368,74 @@ void Approximator_CornerCutting<PFP>::approximate(Dart d)
}
}
/************************************************************************************
* NORMAL AREA METRIC *
************************************************************************************/
template <typename PFP>
bool Approximator_NormalArea<PFP>::init()
{
edgeMatrix = this->m_map.template getAttribute<Geom::Matrix<3,3,REAL>, EDGE>("NormalAreaMatrix") ;
assert(edgeMatrix.isValid());
// m_quadric = this->m_map.template getAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
// Does not require to be valid (if it is not, altenatives will be used).
if(this->m_predictor)
{
return false ;
}
return true ;
}
template <typename PFP>
void Approximator_NormalArea<PFP>::approximate(Dart d)
{
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();
}
const VEC3 & v1 = (*this->m_attrV[0])[d] ;
const VEC3 & v2 = (*this->m_attrV[0])[dd] ;
Eigen::Matrix3f A ;
A << M1(0,0)+M2(0,0) , M1(0,1)+M2(0,1) , M1(0,2)+M2(0,2) , M1(1,0)+M2(1,0) , M1(1,1)+M2(1,1) , M1(1,2)+M2(1,2) , M1(2,0)+M2(2,0) , M1(2,1)+M2(2,1) , M1(2,2)+M2(2,2) ;
VEC3 mb = M1*v1 + M2*v2 ;
Eigen::Vector3f b (mb[0],mb[1],mb[2]);
Eigen::LDLT<Eigen::Matrix3f> decompo (A);
Eigen::Vector3f x = decompo.solve(b);
this->m_approx[0][d] = VEC3 (x(0),x(1),x(2)) ;
}
} //namespace Decimation
} //namespace Algo
......
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