Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

Commit e4a13e90 authored by Kenneth Vanhoey's avatar Kenneth Vanhoey
Browse files

Begin of decim with colors grad+opt

parent 3a4315bb
......@@ -41,19 +41,20 @@ namespace Decimation
enum ApproximatorType
{
A_QEM,
A_MidEdge,
A_CornerCutting,
A_TangentPredict1,
A_TangentPredict2,
A_NormalArea,
A_ColorNaive,
A_ColorQEMext,
A_Lightfield,
A_QEM = 0,
A_MidEdge = 1,
A_CornerCutting = 2,
A_TangentPredict1 = 3,
A_TangentPredict2 = 4,
A_NormalArea = 5,
A_ColorNaive = 6,
A_ColorQEMext = 7,
A_GeomColorOpt = 8,
A_Lightfield = 9,
// note: the following "h" prefix means that half-edges are prioritized instead of edges.
A_hHalfCollapse,
A_hQEM,
A_hLightfieldHalf
A_hHalfCollapse = 10,
A_hQEM = 11,
A_hLightfieldHalf = 12
} ;
template <typename PFP>
......@@ -164,13 +165,17 @@ public:
void saveApprox(Dart d)
{
for (unsigned int i = 0 ; i < m_attrV.size() ; ++i)
{
m_app[i] = m_approx[i][d] ;
}
}
void affectApprox(Dart d)
{
for (unsigned int i = 0 ; i < m_attrV.size() ; ++i)
{
m_attrV[i]->operator[](d) = m_app[i] ;
}
}
const T& getApprox(Dart d, unsigned int index = 0) const
......
......@@ -121,44 +121,43 @@ public:
void approximate(Dart d) ;
} ;
/*
template <typename PFP>
class Approximator_ColorQEMextHalfCollapse : public Approximator<PFP, typename PFP::VEC3>
class Approximator_GeomColOpt : public Approximator<PFP, typename PFP::VEC3, EDGE>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::REAL REAL ;
typedef typename PFP::VEC3 VEC3 ;
typedef Geom::Vector<6,REAL> VEC6 ;
protected:
VertexAttribute<Utils::QuadricNd<REAL,6> > m_quadric ;
VertexAttribute<Utils::Quadric<REAL> > m_quadric ;
VertexAttribute<VEC3> *m_position ;
VertexAttribute<VEC3> *m_color ;
public:
Approximator_ColorQEMextHalfCollapse(MAP& m, std::vector<VertexAttribute<VEC3>* >& attr, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3>(m, attr, pred)
Approximator_GeomColOpt(MAP& m, std::vector<VertexAttribute<VEC3>* >& attr, Predictor<PFP, VEC3>* pred = NULL) :
Approximator<PFP, VEC3, EDGE>(m, attr, pred)
{
assert(attr.size() > 1 || !"Approximator_ColorQEMext_HalfCollapse: there are not sufficient attributes provided") ;
assert(attr.size() > 1 || !"Approximator_GeomColOpt: there are not sufficient attributes provided") ;
m_position = this->m_attrV[0] ;
m_color = this->m_attrV[1] ;
}
~Approximator_ColorQEMextHalfCollapse()
~Approximator_GeomColOpt()
{}
ApproximatorType getType() const
{
return A_ColorQEMextHalfCollapse ;
return A_GeomColorOpt ;
}
bool init() ;
void approximate(Dart d) ;
} ;
*/
} //namespace Decimation
......
......@@ -165,6 +165,102 @@ void Approximator_ColorQEMext<PFP>::approximate(Dart d)
}
}
/************************************************************************************
* GEOM + COLOR OPTIMIZED ERROR METRIC *
************************************************************************************/
template <typename PFP>
bool Approximator_GeomColOpt<PFP>::init()
{
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 m_position->isValid() && m_color->isValid() ;
}
template <typename PFP>
void Approximator_GeomColOpt<PFP>::approximate(Dart d)
{
MAP& m = this->m_map ;
// get some darts
Dart dd = m.phi2(d) ;
// POSITION
Utils::Quadric<REAL> q1, q2 ;
if(!m_quadric.isValid()) // if the selector is not QEM, compute local error quadrics
{
// compute the error quadric associated to v1
Dart it = d ;
do
{
Utils::Quadric<REAL> q(this->m_attrV[0]->operator[](it), this->m_attrV[0]->operator[](m.phi1(it)), this->m_attrV[0]->operator[](m.phi_1(it))) ;
q1 += q ;
it = m.phi2_1(it) ;
} while(it != d) ;
// compute the error quadric associated to v2
it = dd ;
do
{
Utils::Quadric<REAL> q(this->m_attrV[0]->operator[](it), this->m_attrV[0]->operator[](m.phi1(it)), this->m_attrV[0]->operator[](m.phi_1(it))) ;
q2 += q ;
it = m.phi2_1(it) ;
} while(it != dd) ;
}
else // if the selector is QEM, use the error quadrics computed by the selector
{
q1 = m_quadric[d] ;
q2 = m_quadric[dd] ;
}
Utils::Quadric<REAL> quad ;
quad += q1 ; // compute the sum of the
quad += q2 ; // two vertices quadrics
VEC3 res ;
bool opt = quad.findOptimizedPos(res) ; // try to compute an optimized position for the contraction of this edge
const VEC3& p0 = this->m_attrV[0]->operator[](d) ; // let the new vertex lie
const VEC3& p1 = this->m_attrV[0]->operator[](dd) ; // on either one of the two endpoints
if(!opt)
{
VEC3 p12 = (p0 + p1) / 2.0f ; // or the middle of the edge
REAL e1 = quad(p0) ;
REAL e2 = quad(p1) ;
REAL e12 = quad(p12) ;
REAL minerr = std::min(std::min(e1, e2), e12) ; // consider only the one for
if(minerr == e12) this->m_approx[0][d] = p12 ; // which the error is minimal
else if(minerr == e1) this->m_approx[0][d] = p0 ;
else this->m_approx[0][d] = p1 ;
}
// copy res into m_approx
else
{
this->m_approx[0][d] = res ;
}
const VEC3& p = this->m_approx[0][d] ;
// COLOR
const VEC3& c1 = this->m_attrV[1]->operator[](d) ; // let the new vertex lie
const VEC3& c2 = this->m_attrV[1]->operator[](dd) ; // on either one of the two endpoints
VEC3 e = p1 - p0 ;
VEC3 e1 = p - p0 ;
const REAL normE1 = e1.normalize() ;
const REAL normE = e.normalize() ;
REAL ratio = (e * e1)*normE1/normE ;
ratio = std::max(REAL(0),std::min(REAL(1),ratio)) ;
this->m_approx[1][d] = ratio*c1 + (1-ratio)*c2 ;
}
} //namespace Decimation
}
......
......@@ -62,7 +62,7 @@ void decimate(
typename PFP::MAP& map,
SelectorType s,
ApproximatorType a,
std::vector<VertexAttribute<typename PFP::VEC3> *>& position,
std::vector<VertexAttribute<typename PFP::VEC3> *>& attribs,
unsigned int nbWantedVertices,
EdgeAttribute<typename PFP::REAL> *edgeErrors = NULL,
void (*callback_wrapper)(void*, const void*) = NULL, void *callback_object = NULL
......
......@@ -95,6 +95,13 @@ void decimate(
approximators.push_back(new Approximator_ColorQEMext<PFP>(map, attribs)) ;
}
break;
case A_GeomColorOpt :
{
// pos + col
assert(attribs.size() >= 2 || !"Decimate: A_GeomColorOpt --> not enough attribs provided") ;
approximators.push_back(new Approximator_GeomColOpt<PFP>(map, attribs)) ;
}
break ;
case A_hQEM :
// pos
approximators.push_back(new Approximator_QEMhalfEdge<PFP>(map, attribs)) ;
......@@ -190,23 +197,29 @@ void decimate(
case S_hLightfield :
selector = new HalfEdgeSelector_Lightfield<PFP>(map, position, approximators) ;
break ;
case S_hLightfieldExp :
selector = new HalfEdgeSelector_LightfieldExp<PFP>(map, position, approximators) ;
case S_hLightfieldAvgColor :
selector = new HalfEdgeSelector_LightfieldAvgColor<PFP>(map, position, approximators) ;
break ;
case S_hLightfieldKCL :
selector = new HalfEdgeSelector_LightfieldKCL<PFP>(map, position, approximators) ;
break ;
case S_hColorExperimental:
selector = new HalfEdgeSelector_ColorExperimental<PFP>(map, position, approximators, selected) ;
selector = new HalfEdgeSelector_ColorExperimental<PFP>(map, position, approximators) ;
break ;
case S_hColorGradient:
selector = new HalfEdgeSelector_ColorGradient<PFP>(map, position, approximators) ;
break ;
case S_hLFexperimental:
selector = new HalfEdgeSelector_LFexperimental<PFP>(map, position, approximators, selected) ;
selector = new HalfEdgeSelector_LFexperimental<PFP>(map, position, approximators) ;
break ;
case S_hLFgradient:
selector = new HalfEdgeSelector_LFgradient<PFP>(map, position, approximators) ;
break ;
case S_hColorPerFace:
selector = new HalfEdgeSelector_ColorPerFace<PFP>(map, position, approximators, selected) ;
selector = new HalfEdgeSelector_ColorPerFace<PFP>(map, position, approximators) ;
break ;
case S_hLFperFace:
selector = new HalfEdgeSelector_LFperFace<PFP>(map, position, approximators, selected) ;
selector = new HalfEdgeSelector_LFperFace<PFP>(map, position, approximators) ;
break ;
}
......
......@@ -701,7 +701,7 @@ private:
EdgeAttribute<EdgeInfo> edgeInfo ;
VertexAttribute<VEC3> m_pos, m_frameT, m_frameB, m_frameN ;
VertexAttribute<VEC3> m_pos, m_frameT, m_frameB, m_frameN, m_avgColor ;
std::vector<VertexAttribute<VEC3> > m_HF ;
int m_approxindex_pos, m_attrindex_pos ;
int m_approxindex_FN, m_attrindex_FN ;
......@@ -733,6 +733,8 @@ public:
edgeInfo = m.template addAttribute<EdgeInfo, EDGE>("edgeInfo") ;
m_quadricGeom = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
m_quadricHF = m.template getAttribute<Utils::QuadricHF<REAL>, EDGE>("HFquadric") ;
m_avgColor = m.template getAttribute<typename PFP::VEC3, VERTEX>("color") ;
assert(m_avgColor.isValid()) ;
}
~EdgeSelector_Lightfield()
{
......
......@@ -2533,10 +2533,15 @@ void EdgeSelector_Lightfield<PFP>::computeEdgeInfo(Dart d, EdgeInfo& einfo)
assert(m_quadricHF.isValid() | !"EdgeSelector_Lightfield<PFP>::computeEdgeInfo: quadricHF is not valid") ;
Utils::QuadricHF<REAL> quadHF = m_quadricHF[d] ;
assert(m_avgColor.isValid()) ;
VEC3 avgColDiff = m_avgColor[d] ;
avgColDiff -= m_avgColor[dd] ;
//std::cout << quadGeom(newPos) << " vs " << alpha/M_PI << " vs " << quadHF(newHF) << std::endl ;
// sum of QEM metric and frame orientation difference
const REAL& errG = quadGeom(newPos) ; // geom
const REAL& errAngle = alpha / M_PI ; // frame
//const REAL& errAngle = alpha / M_PI ; // frame
const REAL& errAngle = (alpha / M_PI) * avgColDiff.norm2() / 3. ; // avg color times covering area
const REAL& errLF = quadHF(newHF) ; // function coefficients
// Check if errated values appear
......@@ -2544,7 +2549,8 @@ void EdgeSelector_Lightfield<PFP>::computeEdgeInfo(Dart d, EdgeInfo& einfo)
einfo.valid = false ;
else
{
einfo.it = edges.insert(std::make_pair(std::max(errG + errAngle + errLF, REAL(0)), d)) ;
einfo.it = edges.insert(std::make_pair(std::max(errG, REAL(0)) + 10*(errAngle + errLF), d)) ;
//einfo.it = edges.insert(std::make_pair(errG+errLF+errAngle, d)) ;
einfo.valid = true ;
}
}
......
......@@ -166,16 +166,18 @@ public:
TraversorE<typename PFP::MAP> travE(this->m_map) ;
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
(*errors)[d] = -1 ;
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first ;
}
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{
(*errors)[d] = halfEdgeInfo[dd].it->first ;
}
if (!(halfEdgeInfo[d].valid || halfEdgeInfo[dd].valid))
(*errors)[d] = -1 ;
}
}
} ;
......@@ -259,16 +261,18 @@ public:
TraversorE<typename PFP::MAP> travE(this->m_map) ;
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
(*errors)[d] = -1 ;
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first ;
}
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{
(*errors)[d] = halfEdgeInfo[dd].it->first ;
}
if (!(halfEdgeInfo[d].valid || halfEdgeInfo[dd].valid))
(*errors)[d] = -1 ;
}
}
} ;
......@@ -277,7 +281,7 @@ public:
* HALF-EDGE LIGHTFIELD METRIC experimental *
*****************************************************************************************************************/
template <typename PFP>
class HalfEdgeSelector_LightfieldExp : public EdgeSelector<PFP>
class HalfEdgeSelector_LightfieldAvgColor : public EdgeSelector<PFP>
{
public:
typedef typename PFP::MAP MAP ;
......@@ -317,7 +321,7 @@ private:
void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;
public:
HalfEdgeSelector_LightfieldExp(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
HalfEdgeSelector_LightfieldAvgColor(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
EdgeSelector<PFP>(m, pos, approx),
m_approxindex_pos(-1),
m_attrindex_pos(-1),
......@@ -331,12 +335,12 @@ public:
m_avgColor = m.template getAttribute<typename PFP::VEC3, VERTEX>("color") ;
assert(m_avgColor.isValid()) ;
}
~HalfEdgeSelector_LightfieldExp()
~HalfEdgeSelector_LightfieldAvgColor()
{
this->m_map.removeAttribute(m_quadricGeom) ;
this->m_map.removeAttribute(halfEdgeInfo) ;
}
SelectorType getType() { return S_hLightfieldExp ; }
SelectorType getType() { return S_hLightfieldAvgColor ; }
bool init() ;
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
......@@ -354,16 +358,18 @@ public:
TraversorE<typename PFP::MAP> travE(this->m_map) ;
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
(*errors)[d] = -1 ;
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first ;
}
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{
(*errors)[d] = halfEdgeInfo[dd].it->first ;
}
if (!(halfEdgeInfo[d].valid || halfEdgeInfo[dd].valid))
(*errors)[d] = -1 ;
}
}
} ;
......@@ -460,17 +466,18 @@ public:
TraversorE<typename PFP::MAP> travE(this->m_map) ;
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
(*errors)[d] = -1 ;
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first ;
}
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{
(*errors)[dd] = halfEdgeInfo[dd].it->first ;
(*errors)[d] = halfEdgeInfo[dd].it->first ;
}
//m_avgColor[d] = VEC3(m_visualImportance[d]/6.,m_visualImportance[d]/6.,m_visualImportance[d]/6.) ;
if (!(halfEdgeInfo[d].valid || halfEdgeInfo[dd].valid))
(*errors)[d] = -1 ;
}
}
} ;
......@@ -513,7 +520,7 @@ private:
//void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;
void recomputeQuadric(const Dart d) ;
typename PFP::REAL computeExperimentalColorError(const Dart& v0, const Dart& v1) ;
typename PFP::VEC3 computeExperimentalColorError(const Dart& v0, const Dart& v1) ;
public:
......@@ -550,20 +557,114 @@ public:
TraversorE<typename PFP::MAP> travE(this->m_map) ;
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
(*errors)[d] = -1 ;
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first ;
}
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{
(*errors)[d] = halfEdgeInfo[dd].it->first ;
}
if (!(halfEdgeInfo[d].valid || halfEdgeInfo[dd].valid))
(*errors)[d] = -1 ;
}
}
} ;
/*****************************************************************************************************************
* HALF-EDGE COLOR GRADIENT ERR *
*****************************************************************************************************************/
template <typename PFP>
class HalfEdgeSelector_ColorGradient : public EdgeSelector<PFP>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::REAL REAL ;
typedef typename PFP::VEC3 VEC3 ;
private:
typedef struct
{
typename std::multimap<float,Dart>::iterator it ;
bool valid ;
static std::string CGoGNnameOfType() { return "ColorExperimentalHalfEdgeInfo" ; }
} QEMextColorHalfEdgeInfo ;
typedef NoMathIOAttribute<QEMextColorHalfEdgeInfo> HalfEdgeInfo ;
DartAttribute<HalfEdgeInfo> halfEdgeInfo ;
VertexAttribute<Utils::Quadric<REAL> > m_quadric ;
VertexAttribute<VEC3> m_pos, m_color ;
int m_approxindex_pos, m_attrindex_pos ;
int m_approxindex_color, m_attrindex_color ;
std::vector<Approximator<PFP, typename PFP::VEC3,DART>* > m_approx ;
std::multimap<float,Dart> halfEdges ;
typename std::multimap<float,Dart>::iterator cur ;
void initHalfEdgeInfo(Dart d) ;
void updateHalfEdgeInfo(Dart d) ;
void computeHalfEdgeInfo(Dart d, HalfEdgeInfo& einfo) ;
//void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;
void recomputeQuadric(const Dart d) ;
typename PFP::VEC3 computeGradientColorError(const Dart& v0, const Dart& v1) ;
public:
HalfEdgeSelector_ColorGradient(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx) :
EdgeSelector<PFP>(m, pos, approx),
m_approxindex_pos(-1),
m_attrindex_pos(-1),
m_approxindex_color(-1),
m_attrindex_color(-1)
{
halfEdgeInfo = m.template addAttribute<HalfEdgeInfo, DART>("halfEdgeInfo") ;
m_quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
}
~HalfEdgeSelector_ColorGradient()
{
this->m_map.removeAttribute(m_quadric) ;
this->m_map.removeAttribute(halfEdgeInfo) ;
}
SelectorType getType() { return S_hColorGradient ; }
bool init() ;
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() { }
void getEdgeErrors(EdgeAttribute<typename PFP::REAL> *errors)
{
assert(errors != NULL || !"EdgeSelector::setColorMap requires non null vertexattribute argument") ;
if (!errors->isValid())
std::cerr << "EdgeSelector::setColorMap requires valid edgeattribute argument" << std::endl ;
assert(halfEdgeInfo.isValid()) ;
TraversorE<typename PFP::MAP> travE(this->m_map) ;
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first ;
}
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{
(*errors)[d] = halfEdgeInfo[dd].it->first ;
}
if (!(halfEdgeInfo[d].valid || halfEdgeInfo[dd].valid))
(*errors)[d] = -1 ;
}
}
} ;
/*****************************************************************************************************************
* HALF-EDGE LF EXPERIMENTAL METRIC *
*****************************************************************************************************************/
......@@ -653,20 +754,128 @@ public:
TraversorE<typename PFP::MAP> travE(this->m_map) ;
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
(*errors)[d] = -1 ;
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first ;
}
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{
(*errors)[d] = halfEdgeInfo[dd].it->first ;
}
if (!(halfEdgeInfo[d].valid || halfEdgeInfo[dd].valid))
(*errors)[d] = -1 ;
}
}
} ;
/*****************************************************************************************************************
* HALF-EDGE LF EXPERIMENTAL METRIC *
*****************************************************************************************************************/
template <typename PFP>
class HalfEdgeSelector_LFgradient : public EdgeSelector<PFP>
{
public: