Commit 88f32610 authored by Pierre Kraemer's avatar Pierre Kraemer

filters almost OK with Traversors

parent f3502715
......@@ -24,6 +24,9 @@
#include "viewer.h"
#include "Algo/Filtering/bilateral.h"
#include "Algo/Filtering/average_normals.h"
Viewer::Viewer() :
m_renderStyle(FLAT),
m_drawVertices(false),
......@@ -198,6 +201,20 @@ void Viewer::importMesh(std::string& filename)
Algo::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
AttributeHandler<PFP::VEC3> position2 = myMap.addAttribute<PFP::VEC3>(VERTEX, "position2") ;
// for(unsigned int i = 0; i < 3; ++i)
// {
Algo::Filtering::filterVNBA<PFP>(myMap, 0.01f, 0.35f, position, position2, normal) ;
myMap.swapAttributes(position, position2) ;
Algo::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
// }
m_positionVBO->updateData(position) ;
m_normalVBO->updateData(normal) ;
......
......@@ -22,6 +22,7 @@
* *
*******************************************************************************/
#include "Topology/generic/traversorCell.h"
#include "Algo/Filtering/functors.h"
#include "Algo/Selection/collector.h"
......@@ -47,13 +48,11 @@ void filterAverageAttribute_OneRing(
FunctorAverage<T> fa(attIn) ;
Algo::Selection::Collector_OneRing<PFP> col(map) ;
CellMarker markV(map, VERTEX) ;
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorV<typename PFP::MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
if(select(d) && !markV.isMarked(d))
if(select(d))
{
markV.mark(d) ;
if (neigh & INSIDE)
col.collectAll(d) ;
else
......@@ -75,14 +74,15 @@ void filterAverageAttribute_OneRing(
break;
}
}
if (neigh & BORDER) col.applyOnBorder(fa) ;
if (neigh & BORDER)
col.applyOnBorder(fa) ;
attOut[d] = fa.getAverage() ;
}
}
}
template <typename PFP, typename T>
void filterAverageEdgesAttribute_WithinSphere(
void filterAverageVertexAttribute_WithinSphere(
typename PFP::MAP& map,
const AttributeHandler<T>& attIn,
AttributeHandler<T>& attOut,
......@@ -91,31 +91,38 @@ void filterAverageEdgesAttribute_WithinSphere(
typename PFP::REAL radius,
const FunctorSelect& select = SelectorTrue())
{
FunctorAverage<T> fa(attIn) ;
FunctorAverage<T> faInside(attIn) ;
FunctorAverageOnSphereBorder<PFP, T> faBorder(map, attIn, position) ;
Algo::Selection::Collector_WithinSphere<PFP> col(map, position, radius) ;
CellMarker markV(map, VERTEX) ;
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorV<typename PFP::MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
if(select(d) && !markV.isMarked(d))
if(select(d))
{
markV.mark(d) ;
if (neigh & INSIDE)
col.collectAll(d) ;
else
col.collectBorder(d) ;
fa.reset() ;
if (neigh & INSIDE) col.applyOnInsideEdges(fa) ;
if (neigh & BORDER) col.applyOnBorder(fa) ;
attOut[d] = fa.getAverage() ;
attOut[d] = T(0);
if (neigh & INSIDE){
faInside.reset() ;
col.applyOnInsideVertices(faInside) ;
attOut[d] += faInside.getSum();
}
if (neigh & BORDER){
faBorder.reset(position[d], radius);
col.applyOnBorder(faBorder) ;
attOut[d] += faBorder.getSum();
}
attOut[d] /= faInside.getCount() + faBorder.getCount() ;
}
}
}
template <typename PFP, typename T>
void filterAverageFacesAttribute_WithinSphere(
void filterAverageEdgeAttribute_WithinSphere(
typename PFP::MAP& map,
const AttributeHandler<T>& attIn,
AttributeHandler<T>& attOut,
......@@ -124,24 +131,21 @@ void filterAverageFacesAttribute_WithinSphere(
typename PFP::REAL radius,
const FunctorSelect& select = SelectorTrue())
{
FunctorAverage<T> fa(attIn) ;
Algo::Selection::Collector_WithinSphere<PFP> col(map, position, radius) ;
CellMarker markV(map, VERTEX) ;
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorV<typename PFP::MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
if(select(d) && !markV.isMarked(d))
if(select(d))
{
markV.mark(d) ;
if (neigh & INSIDE)
col.collectAll(d) ;
else
col.collectBorder(d) ;
fa.reset() ;
if (neigh & INSIDE) col.applyOnInsideFaces(fa) ;
if (neigh & INSIDE) col.applyOnInsideEdges(fa) ;
if (neigh & BORDER) col.applyOnBorder(fa) ;
attOut[d] = fa.getAverage() ;
}
......@@ -149,7 +153,7 @@ void filterAverageFacesAttribute_WithinSphere(
}
template <typename PFP, typename T>
void filterAverageVertexAttribute_WithinSphere(
void filterAverageFaceAttribute_WithinSphere(
typename PFP::MAP& map,
const AttributeHandler<T>& attIn,
AttributeHandler<T>& attOut,
......@@ -158,34 +162,23 @@ void filterAverageVertexAttribute_WithinSphere(
typename PFP::REAL radius,
const FunctorSelect& select = SelectorTrue())
{
FunctorAverage<T> faInside(attIn) ;
FunctorAverageOnSphereBorder<PFP, T> faBorder(map, attIn, position) ;
FunctorAverage<T> fa(attIn) ;
Algo::Selection::Collector_WithinSphere<PFP> col(map, position, radius) ;
CellMarker markV(map, VERTEX) ;
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorV<typename PFP::MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
if(select(d) && !markV.isMarked(d))
if(select(d))
{
markV.mark(d) ;
if (neigh & INSIDE)
col.collectAll(d) ;
else
col.collectBorder(d) ;
attOut[d] = T(0);
if (neigh & INSIDE){
faInside.reset() ;
col.applyOnInsideVertices(faInside) ;
attOut[d] += faInside.getSum();
}
if (neigh & BORDER){
faBorder.reset(position[d], radius);
col.applyOnBorder(faBorder) ;
attOut[d] += faBorder.getSum();
}
attOut[d] /= faInside.getCount() + faBorder.getCount() ;
fa.reset() ;
if (neigh & INSIDE) col.applyOnInsideFaces(fa) ;
if (neigh & BORDER) col.applyOnBorder(fa) ;
attOut[d] = fa.getAverage() ;
}
}
}
......
......@@ -22,7 +22,8 @@
* *
*******************************************************************************/
#include "Topology/generic/autoAttributeHandler.h"
#include "Topology/generic/traversorCell.h"
#include "Topology/generic/traversor2.h"
namespace CGoGN
{
......@@ -51,35 +52,31 @@ void computeNewPositionsFromFaceNormals(
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
CellMarker markV(map, VERTEX);
for (Dart d = map.begin(); d != map.end(); map.next(d))
TraversorV<typename PFP::MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
if(select(d) && !markV.isMarked(d))
if(select(d))
{
markV.mark(d);
// get pos of vertex
const VEC3& pos_d = position[d] ;
// traversal of vertices neighbourhood
VEC3 displ(0) ;
REAL sumAreas = 0 ;
Dart dd = d ;
do
Traversor2VF<typename PFP::MAP> tvf(map, d) ;
for(Dart it = tvf.begin(); it != tvf.end(); it = tvf.next())
{
sumAreas += faceArea[dd] ;
VEC3 vT = faceCentroid[dd] - pos_d ;
vT = (vT * faceNewNormal[dd]) * faceNormal[dd] ;
displ += faceArea[dd] * vT ;
dd = map.phi1(map.phi2(dd)) ;
} while(dd != d) ;
sumAreas += faceArea[it] ;
VEC3 vT = faceCentroid[it] - pos_d ;
vT = (vT * faceNewNormal[it]) * faceNormal[it] ;
displ += faceArea[it] * vT ;
}
displ /= sumAreas ;
position2[d] = pos_d + displ ;
}
}
}
template <typename PFP>
void filterAverageNormals(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue())
{
......@@ -97,37 +94,21 @@ void filterAverageNormals(typename PFP::MAP& map, const typename PFP::TVEC3& pos
AutoAttributeHandler<VEC3> faceNewNormal(map, FACE, "faceNewNormal") ;
// Compute new normals
CellMarker markF(map, FACE);
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorF<typename PFP::MAP> tf(map) ;
for(Dart d = tf.begin(); d != tf.end(); d = tf.next())
{
if(select(d) && !markF.isMarked(d))
if(select(d))
{
markF.mark(d);
REAL sumArea = 0 ;
VEC3 meanFilter(0) ;
// traversal of adjacent faces (by edges and vertices)
Dart d_n = map.phi1(d) ; // next dart in the face
Dart d_f = map.phi1(map.phi2(d_n)) ; // test dart for end of vertex turning
Dart e = map.phi2(d) ; // current dart for the traversal
Dart d_last = e ;
do
Traversor2FFaV<typename PFP::MAP> taf(map, d) ;
for(Dart it = taf.begin(); it != taf.end(); it = taf.next())
{
// get info from face embedding and sum
sumArea += faceArea[e] ;
meanFilter += faceArea[e] * faceNormal[e] ;
e = map.phi_1(e) ;
e = map.phi2(e) ;
if(e == d_f)
{
e = map.phi2(d_n) ;
d_n = map.phi1(d_n) ;
d_f = map.phi1(map.phi2(d_n)) ;
}
} while(e != d_last) ;
sumArea += faceArea[it] ;
meanFilter += faceArea[it] * faceNormal[it] ;
}
// finalize the computation of meanFilter normal
meanFilter /= sumArea ;
......@@ -160,13 +141,11 @@ void filterMMSE(typename PFP::MAP& map, float sigmaN2, const typename PFP::TVEC3
AutoAttributeHandler<VEC3> faceNewNormal(map, FACE, "faceNewNormal") ;
// Compute new normals
CellMarker markF(map,FACE);
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorF<typename PFP::MAP> tf(map) ;
for(Dart d = tf.begin(); d != tf.end(); d = tf.next())
{
if( select(d) && !markF.isMarked(d))
if( select(d))
{
markF.mark(d);
// traversal of neighbour vertices
REAL sumArea = 0 ;
REAL sigmaX2 = 0 ;
......@@ -176,31 +155,18 @@ void filterMMSE(typename PFP::MAP& map, float sigmaN2, const typename PFP::TVEC3
VEC3 meanFilter(0) ;
// traversal of adjacent faces (by edges and vertices)
Dart d_n = map.phi1(d) ; // next dart in the face
Dart d_f = map.phi1(map.phi2(d_n)) ; // test dart for end of vertex turning
Dart e = map.phi2(d) ; // current dart for the traversal
Dart d_last = e ;
do
Traversor2FFaV<typename PFP::MAP> taf(map, d) ;
for(Dart it = taf.begin(); it != taf.end(); it = taf.next())
{
// get info from face embedding and sum
REAL area = faceArea[e] ;
REAL area = faceArea[it] ;
sumArea += area ;
VEC3 normal = faceNormal[e] ;
VEC3 normal = faceNormal[it] ;
meanFilter += area * normal ;
sigmaX2 += area * normal[0] * normal[0] ;
sigmaY2 += area * normal[1] * normal[1] ;
sigmaZ2 += area * normal[2] * normal[2] ;
e = map.phi_1(e) ;
e = map.phi2(e) ;
if(e == d_f)
{
e = map.phi2(d_n) ;
d_n = map.phi1(d_n) ;
d_f = map.phi1(map.phi2(d_n)) ;
}
} while(e != d_last) ;
}
meanFilter /= sumArea ;
sigmaX2 /= sumArea ;
......@@ -267,13 +233,11 @@ void filterTNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, con
long nbAdapt = 0 ;
long nbSusan = 0 ;
CellMarker markF(map, FACE);
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorF<typename PFP::MAP> tf(map) ;
for(Dart d = tf.begin(); d != tf.end(); d = tf.next())
{
if( select(d) && !markF.isMarked(d))
if( select(d))
{
markF.mark(d);
const VEC3& normF = faceNormal[d] ;
// traversal of neighbour vertices
......@@ -286,20 +250,16 @@ void filterTNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, con
bool SUSANregion = false ;
// traversal of adjacent faces (by edges and vertices)
Dart d_n = map.phi1(d) ; // next dart in the face
Dart d_f = map.phi1(map.phi2(d_n)) ; // test dart for end of vertex turning
Dart e = map.phi2(d) ; // current dart for the traversal
Dart d_last = e ;
do
Traversor2FFaV<typename PFP::MAP> taf(map, d) ;
for(Dart it = taf.begin(); it != taf.end(); it = taf.next())
{
// get info from face embedding and sum
const VEC3& normal = faceNormal[e] ;
const VEC3& normal = faceNormal[it] ;
float angle = Geom::angle(normF, normal) ;
if(angle <= SUSANthreshold)
{
REAL area = faceArea[e] ;
REAL area = faceArea[it] ;
sumArea += area ;
meanFilter += area * normal ;
sigmaX2 += area * normal[0] * normal[0] ;
......@@ -307,18 +267,7 @@ void filterTNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, con
sigmaZ2 += area * normal[2] * normal[2] ;
}
else SUSANregion = true ;
e = map.phi_1(e) ;
e = map.phi2(e) ;
if(e == d_f)
{
e = map.phi2(d_n) ;
d_n = map.phi1(d_n) ;
d_f = map.phi1(map.phi2(d_n)) ;
}
} while(e != d_last) ;
}
if(SUSANregion)
++nbSusan ;
......@@ -407,13 +356,11 @@ void filterVNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, con
long nbAdapt = 0 ;
long nbSusan = 0 ;
CellMarker markV(map, VERTEX);
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorV<typename PFP::MAP> tv(map) ;
for(Dart d = tv.begin(); d != tv.end(); d = tv.next())
{
if( select(d) && !markV.isMarked(d))
if( select(d))
{
markV.mark(d) ;
const VEC3& normV = normal[d] ;
// traversal of neighbour vertices
......@@ -426,23 +373,15 @@ void filterVNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, con
bool SUSANregion = false ;
Dart dd = d ;
do
Traversor2VVaE<typename PFP::MAP> tav(map, d) ;
for(Dart it = tav.begin(); it != tav.end(); it = tav.next())
{
Dart e = map.phi2(dd) ;
const VEC3& neighborNormal = normal[e] ;
const VEC3& neighborNormal = normal[it] ;
float angle = Geom::angle(normV, neighborNormal) ;
if( angle <= SUSANthreshold )
{
REAL umbArea = 0 ;
Dart ee = e ;
do
{
umbArea += faceArea[ee] ;
ee = map.phi1(map.phi2(ee)) ;
} while(ee!=e) ;
vertexArea[e] = umbArea ;
REAL umbArea = Algo::Geometry::vertexOneRingArea<PFP>(map, it, position) ;
vertexArea[it] = umbArea ;
sumArea += umbArea ;
sigmaX2 += umbArea * neighborNormal[0] * neighborNormal[0] ;
......@@ -451,9 +390,7 @@ void filterVNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, con
meanFilter += neighborNormal * umbArea ;
}
else SUSANregion = true ;
dd = map.phi1(e) ;
} while(dd != d) ;
}
if(SUSANregion)
++nbSusan ;
......@@ -511,24 +448,22 @@ void filterVNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, con
}
// Compute face normals from vertex normals
CellMarker markF(map,FACE);
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorF<typename PFP::MAP> tf(map) ;
for(Dart d = tf.begin(); d != tf.end(); d = tf.next())
{
if (select(d) && !markF.isMarked(d))
if (select(d))
{
markF.mark(d);
VEC3 newNormal(0) ;
REAL totArea = 0 ;
Dart dd = d ;
do
{
VEC3 vNorm = vertexNewNormal[dd] ;
REAL area = vertexArea[dd] ;
Traversor2FV<typename PFP::MAP> tav(map, d) ;
for(Dart it = tav.begin(); it != tav.end(); it = tav.next())
{
VEC3 vNorm = vertexNewNormal[it] ;
REAL area = vertexArea[it] ;
totArea += area ;
vNorm *= area ;
newNormal += vNorm ;
dd = map.phi1(dd) ;
} while(dd != d) ;
}
newNormal.normalize() ;
faceNewNormal[d] = newNormal ;
}
......
......@@ -23,6 +23,7 @@
*******************************************************************************/
#include <math.h>
#include "Topology/generic/traversorCell.h"
namespace CGoGN
{
......@@ -33,7 +34,6 @@ namespace Algo
namespace Filtering
{
template <typename PFP>
void sigmaBilateral(typename PFP::MAP& map, const typename PFP::TVEC3& position, const typename PFP::TVEC3& normal, float& sigmaC, float& sigmaS, const FunctorSelect& select)
{
......@@ -43,27 +43,14 @@ void sigmaBilateral(typename PFP::MAP& map, const typename PFP::TVEC3& position,
float sumAngles = 0.0f ;
long nbEdges = 0 ;
CellMarker mv(map, VERTEX) ;
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorE<typename PFP::MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
if(select(d) && !mv.isMarked(d))
if(select(d))
{
mv.mark(d);
Dart dd = d ;
do
{
// compute length and angle if not yet computed
Dart e = map.phi2(dd) ;
if(!mv.isMarked(e))
{
sumLengths += Algo::Geometry::edgeLength<PFP>(map, dd, position) ;
sumAngles += Geom::angle(normal[d], normal[e]) ;
++nbEdges ;
}
// step to next face around vertex
dd = map.phi1(e) ;
} while(dd != d) ;
sumLengths += Algo::Geometry::edgeLength<PFP>(map, d, position) ;
sumAngles += Geom::angle(normal[d], normal[map.phi1(d)]) ;
++nbEdges ;
}
}
......@@ -80,30 +67,27 @@ void filterBilateral(typename PFP::MAP& map, const typename PFP::TVEC3& position
float sigmaC, sigmaS ;
sigmaBilateral<PFP>(map, position, normal, sigmaC, sigmaS, select) ;
CellMarker mv(map, VERTEX) ;
for(Dart d = map.begin(); d != map.end(); map.next(d))
TraversorV<typename PFP::MAP> t(map) ;
for(Dart d = t.begin(); d != t.end(); d = t.next())
{
if(select(d) && !mv.isMarked(d))
if(select(d))
{
mv.mark(d);
// get position & normal of vertex
const VEC3& pos_d = position[d] ;
const VEC3& normal_d = normal[d] ;
// traversal of neighbour vertices
// traversal of incident edges
float sum = 0.0f, normalizer = 0.0f ;
Dart dd = d ;
do
Traversor2VE<typename PFP::MAP> te(map, d) ;
for(Dart it = te.begin(); it != te.end(); it = te.next())
{
VEC3 vec = Algo::Geometry::vectorOutOfDart<PFP>(map, dd, position) ;
VEC3 vec = Algo::Geometry::vectorOutOfDart<PFP>(map, it, position) ;
float h = normal_d * vec ;
float t = vec.norm() ;
float wcs = exp( ( -1.0f * (t * t) / (2.0f * sigmaC * sigmaC) ) + ( -1.0f * (h * h) / (2.0f * sigmaS * sigmaS) ) ) ;
sum += wcs * h ;
normalizer += wcs ;
dd = map.phi1(map.phi2(dd)) ;
} while (dd != d) ;
}
position2[d] = pos_d + ((sum / normalizer) * normal_d) ;
}
......@@ -121,29 +105,26 @@ void filterSUSAN(typename PFP::MAP& map, float SUSANthreshold, const typename PF
long nbTot = 0 ;
long nbSusan = 0 ;
CellMarker mv(map, VERTEX);
for(Dart d = map.begin