Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
CGoGN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
KennethVanhoey
CGoGN
Commits
3f03bce5
Commit
3f03bce5
authored
Feb 19, 2013
by
Thery Sylvain
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of cgogn:~vanhoey/CGoGN
parents
e61959de
23f82746
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1032 additions
and
41 deletions
+1032
-41
include/Algo/Decimation/decimation.hpp
include/Algo/Decimation/decimation.hpp
+6
-0
include/Algo/Decimation/halfEdgeSelector.h
include/Algo/Decimation/halfEdgeSelector.h
+192
-0
include/Algo/Decimation/halfEdgeSelector.hpp
include/Algo/Decimation/halfEdgeSelector.hpp
+831
-40
include/Algo/Decimation/selector.h
include/Algo/Decimation/selector.h
+3
-1
No files found.
include/Algo/Decimation/decimation.hpp
View file @
3f03bce5
...
...
@@ -202,6 +202,12 @@ void decimate(
case
S_hLFexperimental
:
selector
=
new
HalfEdgeSelector_LFexperimental
<
PFP
>
(
map
,
position
,
approximators
,
selected
)
;
break
;
case
S_hColorPerFace
:
selector
=
new
HalfEdgeSelector_ColorPerFace
<
PFP
>
(
map
,
position
,
approximators
,
selected
)
;
break
;
case
S_hLFperFace
:
selector
=
new
HalfEdgeSelector_LFperFace
<
PFP
>
(
map
,
position
,
approximators
,
selected
)
;
break
;
}
for
(
typename
std
::
vector
<
ApproximatorGen
<
PFP
>*>::
iterator
it
=
approximators
.
begin
();
it
!=
approximators
.
end
();
++
it
)
...
...
include/Algo/Decimation/halfEdgeSelector.h
View file @
3f03bce5
...
...
@@ -667,6 +667,198 @@ public:
}
}
;
/*****************************************************************************************************************
* HALF-EDGE COLOR PER FACE *
*****************************************************************************************************************/
template
<
typename
PFP
>
class
HalfEdgeSelector_ColorPerFace
:
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
"ColorPerFaceHalfEdgeInfo"
;
}
}
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
::
REAL
computeExperimentalColorError
(
const
Dart
&
v0
,
const
Dart
&
v1
)
;
public:
HalfEdgeSelector_ColorPerFace
(
MAP
&
m
,
VertexAttribute
<
typename
PFP
::
VEC3
>&
pos
,
std
::
vector
<
ApproximatorGen
<
PFP
>*>&
approx
,
const
FunctorSelect
&
select
=
allDarts
)
:
EdgeSelector
<
PFP
>
(
m
,
pos
,
approx
,
select
),
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_ColorPerFace
()
{
this
->
m_map
.
removeAttribute
(
m_quadric
)
;
this
->
m_map
.
removeAttribute
(
halfEdgeInfo
)
;
}
SelectorType
getType
()
{
return
S_hColorPerFace
;
}
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
())
{
(
*
errors
)[
d
]
=
-
1
;
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
;
}
}
}
}
;
/*****************************************************************************************************************
* HALF-EDGE LF PER FACE *
*****************************************************************************************************************/
template
<
typename
PFP
>
class
HalfEdgeSelector_LFperFace
:
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
"LightfieldPerFaceHalfEdgeInfo"
;
}
}
LightfieldHalfEdgeInfo
;
typedef
NoMathIOAttribute
<
LightfieldHalfEdgeInfo
>
HalfEdgeInfo
;
DartAttribute
<
HalfEdgeInfo
>
halfEdgeInfo
;
VertexAttribute
<
Utils
::
Quadric
<
REAL
>
>
m_quadric
;
VertexAttribute
<
REAL
>
m_visualImportance
;
VertexAttribute
<
VEC3
>
m_avgColor
;
int
m_approxindex_pos
,
m_attrindex_pos
;
int
m_approxindex_FT
,
m_attrindex_FT
;
int
m_approxindex_FB
,
m_attrindex_FB
;
int
m_approxindex_FN
,
m_attrindex_FN
;
std
::
vector
<
unsigned
int
>
m_approxindex_HF
,
m_attrindex_HF
;
unsigned
int
m_K
;
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
)
;
REAL
computeLightfieldError
(
const
Dart
&
v0
,
const
Dart
&
v1
)
;
REAL
computeSquaredLightfieldDifference
(
const
Dart
&
d1
,
const
Dart
&
d2
)
;
public:
HalfEdgeSelector_LFperFace
(
MAP
&
m
,
VertexAttribute
<
typename
PFP
::
VEC3
>&
pos
,
std
::
vector
<
ApproximatorGen
<
PFP
>*>&
approx
,
const
FunctorSelect
&
select
=
allDarts
)
:
EdgeSelector
<
PFP
>
(
m
,
pos
,
approx
,
select
),
m_approxindex_pos
(
-
1
),
m_attrindex_pos
(
-
1
),
m_approxindex_FT
(
-
1
),
m_attrindex_FT
(
-
1
),
m_approxindex_FB
(
-
1
),
m_attrindex_FB
(
-
1
),
m_approxindex_FN
(
-
1
),
m_attrindex_FN
(
-
1
),
m_K
(
0
)
{
halfEdgeInfo
=
m
.
template
addAttribute
<
HalfEdgeInfo
,
DART
>(
"halfEdgeInfo"
)
;
m_quadric
=
m
.
template
addAttribute
<
Utils
::
Quadric
<
REAL
>,
VERTEX
>
(
"QEMquadric"
)
;
m_avgColor
=
m
.
template
getAttribute
<
typename
PFP
::
VEC3
,
VERTEX
>(
"color"
)
;
assert
(
m_avgColor
.
isValid
())
;
}
~
HalfEdgeSelector_LFperFace
()
{
this
->
m_map
.
removeAttribute
(
m_quadric
)
;
this
->
m_map
.
removeAttribute
(
halfEdgeInfo
)
;
}
SelectorType
getType
()
{
return
S_hLFperFace
;
}
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
())
{
(
*
errors
)[
d
]
=
-
1
;
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
;
}
}
}
}
;
}
// namespace Decimation
...
...
include/Algo/Decimation/halfEdgeSelector.hpp
View file @
3f03bce5
...
...
@@ -2120,13 +2120,13 @@ void HalfEdgeSelector_ColorExperimental<PFP>::computeHalfEdgeInfo(Dart d, HalfEd
// New position
const VEC3& newPos = this->m_approx[m_approxindex_pos]->getApprox(d,m_attrindex_pos) ; // get newPos
// New normal
const VEC3& newColor = this->m_approx[m_approxindex_color]->getApprox(d,m_attrindex_color) ; // get new color
//
const VEC3& newColor = this->m_approx[m_approxindex_color]->getApprox(d,m_attrindex_color) ; // get new color
const Dart& v0 = dd ;
const Dart& v1 = d ;
assert(newPos == m_pos[v1]) ;
assert(
newColor
== m_color[v1]) ;
assert(
this->m_approx[m_approxindex_color]->getApprox(d,m_attrindex_color)
== m_color[v1]) ;
// Compute errors
// Position
...
...
@@ -2138,9 +2138,10 @@ void HalfEdgeSelector_ColorExperimental<PFP>::computeHalfEdgeInfo(Dart d, HalfEd
// sum of QEM metric and frame orientation difference
const REAL& err =
quadGeom(newPos) + // geom
computeExperimentalColorError(v0,v1) // color
10*
computeExperimentalColorError(v0,v1) // color
;
//std::cout << quadGeom(newPos) / computeExperimentalColorError(v0,v1) << std::endl ;
//std::cout << quadGeom(newPos)/computeExperimentalColorError(v0,v1) << std::endl ;
// Check if errated values appear
if (err < -1e-6)
...
...
@@ -2158,7 +2159,7 @@ HalfEdgeSelector_ColorExperimental<PFP>::computeExperimentalColorError(const Dar
{
MAP& m = this->m_map ;
Traversor2VF<MAP> tf(m,v0) ;
Traversor2VF<MAP> tf(m,v0) ;
// all faces around vertex v0
const unsigned int& v1_vertexId = m.template getEmbedding<VERTEX>(v1) ;
const VEC3& P0 = m_pos[v0] ;
...
...
@@ -2166,58 +2167,66 @@ HalfEdgeSelector_ColorExperimental<PFP>::computeExperimentalColorError(const Dar
const VEC3& c0 = m_color[v0] ;
const VEC3& c1 = m_color[v1] ;
REAL res = 0 ;
REAL res1 = 0, res2 = 0 ;
unsigned int count1 = 0, count2 = 0 ;
for (Dart fi = tf.begin() ; fi != tf.end() ; fi = tf.next())
{
const Dart& vi = m.phi1(fi) ;
const Dart& vj = m.phi_1(fi) ;
const VEC3& Pi =
m_pos
[vi] ;
const VEC3& Pj =
m_pos
[vj] ;
const VEC3& Pi =
this->m_position
[vi] ;
const VEC3& Pj =
this->m_position
[vj] ;
const VEC3& ci = m_color[vi] ;
const VEC3& cj = m_color[vj] ;
const VEC3 PiP0 = P0 - Pi ;
const VEC3 PjP0 = P0 - Pj ;
const VEC3 PiPj = Pj - Pi ;
const VEC3 Pi_P0 = P0 - Pi ;
//const VEC3 PjP0 = P0 - Pj ;
const VEC3 Pi_Pj = Pj - Pi ;
const REAL b = Pi_Pj.norm() ;
const VEC3 P0pr
im = Pi + (PiP0 * PiPj)*Pi
Pj ;
const VEC3 P0
P0prim = P0prim
- P0 ;
const REAL h0 = P0
P0prim
.norm() ;
const VEC3 P0pr
oj2D = Pi + (Pi_P0 * Pi_Pj)*Pi_
Pj ;
const VEC3 P0
_P0proj2D = P0proj2D
- P0 ;
const REAL h0 = P0
_P0proj2D
.norm() ;
const VEC3 coldiff01 = c1 - c0 ;
res += coldiff01.norm() * PiPj.norm() * h0 / (6. * sqrt(3)) ;
res1 += coldiff01.norm() * b * h0 / (6. * sqrt(3)) ;
++count1 ;
// test if v1 is adjacent to this face
bool adjacent = false ;
Traversor2FV<MAP> tv(m,fi) ;
for (Dart v = tv.begin() ; v != tv.end() ; v = tv.next())
{
if (v1_vertexId == m.template getEmbedding<VERTEX>(v))
adjacent = true ;
adjacent |= v1_vertexId == m.template getEmbedding<VERTEX>(v) ;
}
// if v1 is not adjacent to this face
if (!adjacent)
{
const VEC3 PiP1 = P0 - Pi ;
const VEC3 PjP1 = P0 - Pj ;
const VEC3 P1proj3D = P1 ;
const VEC3 Pi_P1 = P1proj3D - Pi ;
//const VEC3 PjP1 = newP1 - Pj ;
const VEC3 P1pr
im = Pi + (PiP1 * PiPj)*Pi
Pj ;
const VEC3 P1
P1prim = P1prim - P1
;
const REAL h1 = P1
P1prim
.norm() ;
const VEC3 P1pr
oj2D = Pi + (Pi_P1 * Pi_Pj)*Pi_
Pj ;
const VEC3 P1
proj2D_P1proj3D = P1proj2D - P1proj3D
;
const REAL h1 = P1
proj2D_P1proj3D
.norm() ;
const VEC3 coldiff0i = ci - c0 ;
const VEC3 coldiff1i = ci - c1 ;
const VEC3 coldiff0j = cj - c0 ;
const VEC3 coldiff1j = cj - c1 ;
res += (coldiff0i.norm() + coldiff0j.norm() + coldiff1i.norm() + coldiff1j.norm()) * PiPj.norm() * std::fabs(h1 - h0) / (6. * sqrt(3)) ;
res2 += (coldiff0i.norm() + coldiff0j.norm() + coldiff1i.norm() + coldiff1j.norm())
* b * std::fabs(h1 - h0)
/ (12. * sqrt(3)) ;
++count2 ;
}
}
return res ;
assert(count1-2==count2) ;
return res1 / count1 + res2 / count2 ;
}
/************************************************************************************
...
...
@@ -2510,7 +2519,7 @@ void HalfEdgeSelector_LFexperimental<PFP>::computeHalfEdgeInfo(Dart d, HalfEdgeI
// sum of QEM metric
const REAL& err =
quadGeom(newPos) + // geom
100*computeLightfieldError(v0,v1) // lf
100
0
*computeLightfieldError(v0,v1) // lf
;
//std::cout << computeLightfieldError(v0,v1) / quadGeom(newPos) << std::endl ;
...
...
@@ -2536,7 +2545,8 @@ HalfEdgeSelector_LFexperimental<PFP>::computeLightfieldError(const Dart& v0, con
const VEC3& P0 = this->m_position[v0] ;
const VEC3& P1 = this->m_position[v1] ;
REAL res = 0 ;
REAL res1 = 0, res2 = 0 ;
unsigned int count = 0 ;
for (Dart fi = tf.begin() ; fi != tf.end() ; fi = tf.next())
{
const Dart& vi = m.phi1(fi) ;
...
...
@@ -2545,16 +2555,17 @@ HalfEdgeSelector_LFexperimental<PFP>::computeLightfieldError(const Dart& v0, con
const VEC3& Pi = this->m_position[vi] ;
const VEC3& Pj = this->m_position[vj] ;
const VEC3 PiP0 = P0 - Pi ;
const VEC3 PjP0 = P0 - Pj ;
const VEC3 PiPj = Pj - Pi ;
const VEC3 Pi_P0 = P0 - Pi ;
//const VEC3 PjP0 = P0 - Pj ;
const VEC3 Pi_Pj = Pj - Pi ;
const REAL b = Pi_Pj.norm() ;
const VEC3 P0pr
im = Pi + (PiP0 * PiPj)*Pi
Pj ;
const VEC3 P0
P0prim = P0prim
- P0 ;
const REAL h0 = P0
P0prim
.norm() ;
const VEC3 P0pr
oj2D = Pi + (Pi_P0 * Pi_Pj)*Pi_
Pj ;
const VEC3 P0
_P0proj2D = P0proj2D
- P0 ;
const REAL h0 = P0
_P0proj2D
.norm() ;
const REAL lfdiff01 = computeSquaredLightfieldDifference(v0,v1) ;
res
+= lfdiff01 * PiPj.norm() * h0 / 6.
;
res
1 += lfdiff01 * b * h0 / (6.*sqrt(3))
;
// test if v1 is adjacent to this face
bool adjacent = false ;
...
...
@@ -2568,23 +2579,25 @@ HalfEdgeSelector_LFexperimental<PFP>::computeLightfieldError(const Dart& v0, con
// if v1 is not adjacent to this face
if (!adjacent)
{
const VEC3 PiP1 = P0 - Pi ;
const VEC3 PjP1 = P0 - Pj ;
const VEC3 P1proj3D = P1 ;
const VEC3 Pi_P1 = P1proj3D - Pi ;
//const VEC3 PjP1 = newP1 - Pj ;
const VEC3 P1pr
im = Pi + (PiP1 * PiPj)*Pi
Pj ;
const VEC3 P1
P1prim = P1prim - P1
;
const REAL h1 = P1
P1prim
.norm() ;
const VEC3 P1pr
oj2D = Pi + (Pi_P1 * Pi_Pj)*Pi_
Pj ;
const VEC3 P1
proj2D_P1proj3D = P1proj2D - P1proj3D
;
const REAL h1 = P1
proj2D_P1proj3D
.norm() ;
const REAL lfdiff0i = computeSquaredLightfieldDifference(vi,v0) ;
const REAL lfdiff1i = computeSquaredLightfieldDifference(vi,v1) ;
const REAL lfdiff0j = computeSquaredLightfieldDifference(vj,v0) ;
const REAL lfdiff1j = computeSquaredLightfieldDifference(vj,v1) ;
res
+= (lfdiff0i + lfdiff0j + lfdiff1i + lfdiff1j) * PiPj.norm() * std::fabs(h1 - h0) / 6.
;
res
2 += (lfdiff0i + lfdiff0j + lfdiff1i + lfdiff1j) * b * std::fabs(h1 - h0) / (12.*sqrt(3))
;
}
++count ;
}
return res ;
return res
1 / count + res2 / (count-2)
;
}
template <typename PFP>
...
...
@@ -2652,6 +2665,784 @@ typename PFP::REAL HalfEdgeSelector_LFexperimental<PFP>::computeSquaredLightfiel
}
/************************************************************************************
* COLOR PER FACE *
************************************************************************************/
template <typename PFP>
bool HalfEdgeSelector_ColorPerFace<PFP>::init()
{
MAP& m = this->m_map ;
// Verify availability of required approximators
unsigned int ok = 0 ;
for (unsigned int approxindex = 0 ; approxindex < this->m_approximators.size() ; ++approxindex)
{
assert(this->m_approximators[approxindex]->getType() == A_hQEM
|| this->m_approximators[approxindex]->getType() == A_hHalfCollapse
|| !"Approximator for selector (HalfEdgeSelector_ColorExperimental) must be of a half-edge approximator") ;
bool saved = false ;
for (unsigned int attrindex = 0 ; attrindex < this->m_approximators[approxindex]->getNbApproximated() ; ++ attrindex)
{
// constraint : 2 approximators in specific order
if(ok == 0 && this->m_approximators[approxindex]->getApproximatedAttributeName(attrindex) == "position")
{
++ok ;
m_approxindex_pos = approxindex ;
m_attrindex_pos = attrindex ;
m_pos = this->m_position ;
if (!saved)
{
m_approx.push_back(reinterpret_cast<Approximator<PFP, VEC3, DART>* >(this->m_approximators[approxindex])) ;
saved = true ;
}
}
else if(ok == 1 && this->m_approximators[approxindex]->getApproximatedAttributeName(attrindex) == "color")
{
++ok ;
m_approxindex_color = approxindex ;
m_attrindex_color = attrindex ;
m_color = m.template getAttribute<typename PFP::VEC3, VERTEX>("color") ;
assert(m_color.isValid() || !"EdgeSelector_QEMextColor: color attribute is not valid") ;
if (!saved)
{
m_approx.push_back(reinterpret_cast<Approximator<PFP, VEC3, DART>* >(this->m_approximators[approxindex])) ;
saved = true ;
}
}
}
}
if(ok != 2)
return false ;
CellMarker<VERTEX> vMark(m) ;
for(Dart d = m.begin(); d != m.end(); m.next(d))
{
if(!vMark.isMarked(d))
{
Utils::Quadric<REAL> q ; // create one quadric
m_quadric[d] = q ; // per vertex
vMark.mark(d) ;
}
}
DartMarker mark(m) ;
for(Dart d = m.begin(); d != m.end(); m.next(d))
{
if(!mark.isMarked(d))
{
Dart d1 = m.phi1(d) ; // for each triangle,
Dart d_1 = m.phi_1(d) ; // initialize the quadric of the triangle
Utils::Quadric<REAL> q(this->m_position[d], this->m_position[d1], this->m_position[d_1]) ;
m_quadric[d] += q ; // and add the contribution of
m_quadric[d1] += q ; // this quadric to the ones
m_quadric[d_1] += q ; // of the 3 incident vertices
mark.markOrbit<FACE>(d) ;
}
}
// Init multimap for each Half-edge
halfEdges.clear() ;
for(Dart d = m.begin(); d != m.end(); m.next(d))
{
initHalfEdgeInfo(d) ; // init the edges with their optimal info
} // and insert them in the multimap according to their error
cur = halfEdges.begin() ; // init the current edge to the first one
return true ;
}
template <typename PFP>
bool HalfEdgeSelector_ColorPerFace<PFP>::nextEdge(Dart& d)
{
if(cur == halfEdges.end() || halfEdges.empty())
return false ;
d = (*cur).second ;
return true ;
}
template <typename PFP>
void HalfEdgeSelector_ColorPerFace<PFP>::updateBeforeCollapse(Dart d)
{
MAP& m = this->m_map ;
const Dart& v0 = m.phi1(d) ;
Traversor2VVaE<MAP> tv(m,v0) ;
for (Dart v = tv.begin() ; v != tv.end() ; v = tv.next())
{
Traversor2VE<MAP> te(m,v) ;
for (Dart he = te.begin() ; he != te.end() ; he = te.next())
{
HalfEdgeInfo* edgeE = &(halfEdgeInfo[he]) ;
if(edgeE->valid)
{
edgeE->valid = false ;
halfEdges.erase(edgeE->it) ;
}
Dart de = m.phi2(he) ;
edgeE = &(halfEdgeInfo[de]) ;
if(edgeE->valid)
{
edgeE->valid = false ;
halfEdges.erase(edgeE->it) ;
}
}
}
}
/**
* Update quadric of a vertex
* Discards quadrics of d and assigns freshly calculated
* quadrics depending on the actual planes surrounding d
* @param dart d
*/
template <typename PFP>
void HalfEdgeSelector_ColorPerFace<PFP>::recomputeQuadric(const Dart d)
{
Dart dFront,dBack ;
Dart dInit = d ;
// Init Front
dFront = dInit ;
m_quadric[d].zero() ;
do {
// Make step
dBack = this->m_map.phi1(dFront) ;
dFront = this->m_map.phi2_1(dFront) ;
if (this->m_map.phi2(dFront) != dFront) { // if dFront is no border
m_quadric[d] += Utils::Quadric<REAL>(this->m_position[d],this->m_position[dBack],this->m_position[this->m_map.phi1(dFront)]) ;
}
} while(dFront != dInit) ;
}
template <typename PFP>
void HalfEdgeSelector_ColorPerFace<PFP>::updateAfterCollapse(Dart d2, Dart dd2)
{
MAP& m = this->m_map ;
const Dart& v1 = d2 ;
recomputeQuadric(v1) ;
Traversor2VVaE<MAP> tv(m,v1) ;
for (Dart v = tv.begin() ; v != tv.end() ; v = tv.next())
{
recomputeQuadric(v) ;
}
for (Dart v = tv.begin() ; v != tv.end() ; v = tv.next())
{
Traversor2VE<MAP> te(m,v) ;
for (Dart e = te.begin() ; e != te.end() ; e = te.next())
{
updateHalfEdgeInfo(e) ;
updateHalfEdgeInfo(m.phi2(e)) ;
}
}
cur = halfEdges.begin() ; // set the current edge to the first one
}
template <typename PFP>
void HalfEdgeSelector_ColorPerFace<PFP>::initHalfEdgeInfo(Dart d)
{
MAP& m = this->m_map ;
HalfEdgeInfo heinfo ;
if(m.edgeCanCollapse(d))
computeHalfEdgeInfo(d, heinfo) ;
else
heinfo.valid = false ;
halfEdgeInfo[d] = heinfo ;
}
template <typename PFP>
void HalfEdgeSelector_ColorPerFace<PFP>::updateHalfEdgeInfo(Dart d)
{
MAP& m = this->m_map ;
HalfEdgeInfo& heinfo = halfEdgeInfo[d] ;
if(!heinfo.valid && m.edgeCanCollapse(d))
computeHalfEdgeInfo(d, heinfo) ;