Commit 695d8500 authored by Pierre Kraemer's avatar Pierre Kraemer

update collector + filtering

parent fee3b1fc
......@@ -30,7 +30,7 @@ namespace CGoGN
namespace Algo
{
namespace Filters2D
namespace Filtering
{
/**
......@@ -48,7 +48,6 @@ void computeNewPositionsFromFaceNormals(
const typename PFP::TVEC3& faceNewNormal,
const FunctorSelect& select)
{
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
......@@ -70,9 +69,7 @@ void computeNewPositionsFromFaceNormals(
{
sumAreas += faceArea[dd] ;
VEC3 vT = faceCentroid[dd] - pos_d ;
const VEC3& normal = faceNewNormal[dd] ;
REAL scal = vT * normal ;
vT = scal * faceNormal[dd] ;
vT = (vT * faceNewNormal[dd]) * faceNormal[dd] ;
displ += faceArea[dd] * vT ;
dd = map.phi1(map.phi2(dd)) ;
} while(dd != d) ;
......@@ -84,9 +81,8 @@ void computeNewPositionsFromFaceNormals(
template <typename PFP>
void filterAverageNormals(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select)
void filterAverageNormals(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
......@@ -148,9 +144,8 @@ void filterAverageNormals(typename PFP::MAP& map, const typename PFP::TVEC3& pos
}
template <typename PFP>
void filterMMSE(typename PFP::MAP& map, float sigmaN2, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select)
void filterMMSE(typename PFP::MAP& map, float sigmaN2, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
......@@ -252,9 +247,8 @@ void filterMMSE(typename PFP::MAP& map, float sigmaN2, const typename PFP::TVEC3
}
template <typename PFP>
void filterTNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select)
void filterTNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
......@@ -392,9 +386,8 @@ void filterTNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, con
}
template <typename PFP>
void filterVNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select)
void filterVNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::MAP MAP ;
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
......@@ -550,7 +543,7 @@ void filterVNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, con
// CGoGNout <<" adaptive rate = "<< float(nbAdapt)/float(nbTot)<<CGoGNendl;
}
} //namespace Filters2D
} //namespace Filtering
} //namespace Algo
......
......@@ -22,20 +22,26 @@
* *
*******************************************************************************/
#include "Algo/Filtering/functors.h"
#include "Algo/Selection/collector.h"
namespace CGoGN
{
namespace Algo
{
namespace Filters2D
namespace Filtering
{
template <typename PFP>
void filterAverage(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select)
void filterAveragePositions(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::VEC3 VEC3 ;
FunctorAverage<typename PFP::MAP, typename PFP::VEC3> fa(map, position) ;
Algo::Selection::Collector_OneRing<PFP> c(map) ;
CellMarker markV(map, VERTEX);
for(Dart d = map.begin(); d != map.end(); map.next(d))
{
......@@ -43,30 +49,16 @@ void filterAverage(typename PFP::MAP& map, const typename PFP::TVEC3& position,
{
markV.mark(d);
// get position of vertex
const VEC3& pos_d = position[d] ;
// traversal of neighbour vertices
VEC3 l(0) ;
int nbE = 0 ;
Dart dd = d ;
do
{
Dart e = map.phi2(dd) ;
l += position[e] - pos_d ;
nbE++ ;
dd = map.phi1(e) ;
} while(dd != d) ;
l /= float(nbE) ;
position2[d] = pos_d + l ;
c.collectBorder(d) ;
fa.reset() ;
c.applyOnBorder(fa) ;
position2[d] = fa.getAverage() ;
}
}
}
} //namespace Filters2D
} // namespace Filtering
} //namespace Algo
} // namespace Algo
} //namespace CGoGN
} // namespace CGoGN
......@@ -30,7 +30,7 @@ namespace CGoGN
namespace Algo
{
namespace Filters2D
namespace Filtering
{
......@@ -57,8 +57,7 @@ void sigmaBilateral(typename PFP::MAP& map, const typename PFP::TVEC3& position,
Dart e = map.phi2(dd) ;
if(!mv.isMarked(e))
{
VEC3 vec = Algo::Geometry::vectorOutOfDart<PFP>(map, dd, position) ;
sumLengths += vec.norm() ;
sumLengths += Algo::Geometry::edgeLength<PFP>(map, dd, position) ;
sumAngles += Geom::angle(normal[d], normal[e]) ;
++nbEdges ;
}
......@@ -74,7 +73,7 @@ void sigmaBilateral(typename PFP::MAP& map, const typename PFP::TVEC3& position,
}
template <typename PFP>
void filterBilateral(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select)
void filterBilateral(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::VEC3 VEC3 ;
......@@ -112,7 +111,7 @@ void filterBilateral(typename PFP::MAP& map, const typename PFP::TVEC3& position
}
template <typename PFP>
void filterSUSAN(typename PFP::MAP& map, float SUSANthreshold, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select)
void filterSUSAN(typename PFP::MAP& map, float SUSANthreshold, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::VEC3 VEC3 ;
......@@ -171,7 +170,7 @@ void filterSUSAN(typename PFP::MAP& map, float SUSANthreshold, const typename PF
// CGoGNout <<" susan rate = "<< float(nbSusan)/float(nbTot)<<CGoGNendl;
}
} //namespace Filters2D
} //namespace Filtering
} //namespace Algo
......
......@@ -22,50 +22,43 @@
* *
*******************************************************************************/
#include "Algo/Filtering/functors.h"
#include "Algo/Selection/collector.h"
namespace CGoGN
{
namespace Algo
{
namespace Filters2D
namespace Filtering
{
template <typename PFP>
void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select)
void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::VEC3 VEC3 ;
FunctorAverage<typename PFP::MAP, typename PFP::VEC3> fa(map, position) ;
Algo::Selection::Collector_OneRing<PFP> c(map) ;
const float lambda = 0.6307 ;
const float mu = -0.6732 ;
CellMarkerNoUnmark mv(map, VERTEX);
CellMarkerNoUnmark mv(map, VERTEX) ;
for(Dart d = map.begin(); d != map.end(); map.next(d))
{
if(select(d) && !mv.isMarked(d))
{
mv.mark(d);
// get pos of vertex
const VEC3& pos_d = position[d] ;
// traversal of vertices neighborhood
VEC3 l(0) ;
int nbE = 0 ;
Dart dd = d ;
do
{
Dart e = map.phi2(dd) ;
l += position[e] - pos_d ;
nbE++ ;
dd = map.phi1(e) ;
} while(dd != d) ;
l /= float(nbE) ;
l *= lambda ;
position2[d] = pos_d + l ;
c.collectBorder(d) ;
fa.reset() ;
c.applyOnBorder(fa) ;
VEC3 p = position[d] ;
VEC3 displ = fa.getAverage() - p ;
displ *= lambda ;
position2[d] = p + displ ;
}
}
......@@ -76,31 +69,68 @@ void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typenam
{
mv.unmark(d);
// get pos of vertex
const VEC3& pos_d = position2[d] ;
c.collectBorder(d) ;
fa.reset() ;
c.applyOnBorder(fa) ;
VEC3 p = position2[d] ;
VEC3 displ = fa.getAverage() - p ;
displ *= mu ;
position[d] = p + displ ;
}
}
}
/**
* Taubin filter modified as proposed by [Lav09]
*/
template <typename PFP>
void filterTaubin_modified(typename PFP::MAP& map, typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::VEC3 VEC3 ;
FunctorAverage<typename PFP::MAP, typename PFP::VEC3> fa(map, position) ;
Algo::Selection::Collector_OneRing<PFP> c(map) ;
// traversal of vertices neighborhood
VEC3 l(0) ;
int nbE = 0 ;
Dart dd = d ;
do
const float lambda = 0.6307 ;
const float mu = -0.6732 ;
CellMarkerNoUnmark mv(map, VERTEX) ;
for(Dart d = map.begin(); d != map.end(); map.next(d))
{
if(select(d) && !mv.isMarked(d))
{
Dart e = map.phi2(dd) ;
l += position2[e] - pos_d ;
nbE++ ;
dd = map.phi1(e) ;
} while(dd != d) ;
mv.mark(d);
l /= float(nbE) ;
l *= mu ;
c.collectBorder(d) ;
fa.reset() ;
c.applyOnBorder(fa) ;
VEC3 p = position[d] ;
VEC3 displ = fa.getAverage() - p ;
displ *= lambda ;
position2[d] = p + displ ;
}
}
// unshrinking step
for(Dart d = map.begin(); d != map.end(); map.next(d))
{
if(select(d) && mv.isMarked(d))
{
mv.unmark(d);
position[d] = pos_d + l ;
c.collectBorder(d) ;
fa.reset() ;
c.applyOnBorder(fa) ;
VEC3 p = position2[d] ;
VEC3 displ = fa.getAverage() - p ;
displ *= mu ;
position[d] = p + displ ;
}
}
}
} //namespace Filters2D
} // namespace Filtering
} //namespace Algo
} // namespace Algo
} //namespace CGoGN
} // namespace CGoGN
......@@ -34,11 +34,11 @@ namespace CGoGN
namespace Algo
{
namespace Filters2D
namespace Filtering
{
template <typename PFP>
float computeHaussdorf(typename PFP::MAP& map, const typename PFP::TVEC3& originalPosition, const typename PFP::TVEC3& position2, const FunctorSelect& select)
float computeHaussdorf(typename PFP::MAP& map, const typename PFP::TVEC3& originalPosition, const typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::VEC3 VEC3 ;
......@@ -92,7 +92,7 @@ float computeHaussdorf(typename PFP::MAP& map, const typename PFP::TVEC3& origin
}
template <typename PFP>
void computeNoise(typename PFP::MAP& map, long amount, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select)
void computeNoise(typename PFP::MAP& map, long amount, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select = SelectorTrue())
{
typedef typename PFP::VEC3 VEC3 ;
......@@ -143,7 +143,7 @@ void computeNoise(typename PFP::MAP& map, long amount, const typename PFP::TVEC3
}
}
} //namespace Filters2D
} //namespace Filtering
} //namespace Algo
......
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2011, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.u-strasbg.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __FILTERS_2D__
#define __FILTERS_2D__
namespace CGoGN
{
namespace Algo
{
namespace Filters2D
{
enum Filters { AVERAGE, TAUBIN, BILATERAL, AVERAGE_NORMAL, MMSE, SUSAN, TNBA, VNBA } ;
/**
* Average filter need:
* vertex embedding with position & position2
*/
template <typename PFP>
void filterAverage(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue()) ;
/**
* Taubin filter need:
* vertex embedding with position & position2
*/
template <typename PFP>
void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue()) ;
/**
* bilateral filter need
* vertex embedding with: position & position2
*/
template <typename PFP>
void filterBilateral(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select = SelectorTrue()) ;
template <typename PFP>
void filterSUSAN(typename PFP::MAP& map, float SUSANthreshold, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select = SelectorTrue()) ;
/**
* Average normal filter need:
* vertex embedding with position & position2
* face embedding with normal, centroid & area
*/
template <typename PFP>
void filterAverageNormals(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue()) ;
/**
* MMSE filter need:
* vertex embedding with position & position2
* face embedding with normal, centroid & area
*/
template <typename PFP>
void filterMMSE(typename PFP::MAP& map, float sigmaN2, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue()) ;
template <typename PFP>
void filterTNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue()) ;
template <typename PFP>
void filterVNBA(typename PFP::MAP& map, float sigmaN2, float SUSANthreshold, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select = SelectorTrue()) ;
/**
* some useful tools
*/
template <typename PFP>
float computeHaussdorf(typename PFP::MAP& map, const typename PFP::TVEC3& originalPosition, const typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue()) ;
template <typename PFP>
void computeNoise(typename PFP::MAP& map, long amount, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const typename PFP::TVEC3& normal, const FunctorSelect& select = SelectorTrue()) ;
} //namespace Filters2D
} //namespace Algo
} //namespace CGoGN
#include "Algo/Filters2D/average.hpp"
#include "Algo/Filters2D/taubin.hpp"
#include "Algo/Filters2D/bilateral.hpp"
#include "Algo/Filters2D/average_normals.hpp"
#include "Algo/Filters2D/tools.hpp"
#endif
......@@ -340,12 +340,11 @@ void computeCurvatureVertex_NormalCycles(
typedef typename PFP::VEC3 VEC3 ;
typedef typename PFP::REAL REAL ;
Algo::Selection::Collector_WithinSphere<PFP> neigh(map, position) ;
neigh.init(dart, radius) ;
neigh.collect() ;
Algo::Selection::Collector_WithinSphere<PFP> neigh(map, position, radius) ;
neigh.collectAll(dart) ;
neigh.computeArea() ;
VEC3 center = position[neigh.getCenter()] ;
VEC3 center = position[dart] ;
typename PFP::MATRIX33 tensor(0) ;
......
......@@ -55,10 +55,8 @@ protected:
typedef typename PFP::REAL REAL;
typename PFP::MAP& map;
const typename PFP::TVEC3& position;
Dart centerDart;
REAL radius;
std::vector<Dart> insideVertices;
std::vector<Dart> insideEdges;
......@@ -66,15 +64,26 @@ protected:
std::vector<Dart> border;
public:
Collector(typename PFP::MAP& mymap, const typename PFP::TVEC3& myposition);
Collector(typename PFP::MAP& m);
virtual void init(Dart d, REAL r = 0) = 0;
inline void init(Dart d)
{
centerDart = d;
insideVertices.clear();
insideEdges.clear();
insideFaces.clear();
border.clear();
}
virtual void collect() = 0;
virtual void collectAll(Dart d) = 0;
virtual void collectBorder(Dart d) = 0;
bool apply(FunctorType& f);
bool applyOnInsideVertices(FunctorType& f);
bool applyOnInsideEdges(FunctorType& f);
bool applyOnInsideFaces(FunctorType& f);
bool applyOnBorder(FunctorType& f);
void sort()
inline void sort()
{
std::sort(insideVertices.begin(), insideVertices.end());
std::sort(insideEdges.begin(), insideEdges.end());
......@@ -82,21 +91,19 @@ public:
std::sort(border.begin(), border.end());
}
typename PFP::MAP& getMap() { return map; }
const AttributeHandler<typename PFP::VEC3>& getPosition() const { return position; }
inline typename PFP::MAP& getMap() { return map; }
Dart getCenter() const { return centerDart; }
REAL getRadius() const { return radius; }
inline Dart getCenterDart() const { return centerDart; }
const std::vector<Dart>& getInsideVertices() const { return insideVertices; }
const std::vector<Dart>& getInsideEdges() const { return insideEdges; }
const std::vector<Dart>& getInsideFaces() const { return insideFaces; }
const std::vector<Dart>& getBorder() const { return border; }
inline const std::vector<Dart>& getInsideVertices() const { return insideVertices; }
inline const std::vector<Dart>& getInsideEdges() const { return insideEdges; }
inline const std::vector<Dart>& getInsideFaces() const { return insideFaces; }
inline const std::vector<Dart>& getBorder() const { return border; }
unsigned int getNbInsideVertices() const { return insideVertices.size(); }
unsigned int getNbInsideEdges() const { return insideEdges.size(); }
unsigned int getNbInsideFaces() const { return insideFaces.size(); }
unsigned int getNbBorder() const { return border.size(); }
inline unsigned int getNbInsideVertices() const { return insideVertices.size(); }
inline unsigned int getNbInsideEdges() const { return insideEdges.size(); }
inline unsigned int getNbInsideFaces() const { return insideFaces.size(); }
inline unsigned int getNbBorder() const { return border.size(); }
template <typename PPFP>
friend std::ostream& operator<<(std::ostream &out, const Collector<PPFP>& c);
......@@ -117,11 +124,11 @@ template <typename PFP>
class Collector_OneRing : public Collector<PFP>
{
public:
Collector_OneRing(typename PFP::MAP& mymap, const typename PFP::TVEC3& myposition) :
Collector<PFP>(mymap, myposition)
Collector_OneRing(typename PFP::MAP& m) :
Collector<PFP>(m)
{}
void init(Dart d, typename PFP::REAL r = 0);
void collect();
void collectAll(Dart d);
void collectBorder(Dart d);
};
/*********************************************************
......@@ -137,17 +144,26 @@ template <typename PFP>
class Collector_WithinSphere : public Collector<PFP>
{
protected:
typename PFP::VEC3 centerPosition;
const typename PFP::TVEC3& position;
typename PFP::REAL radius;
typename PFP::REAL area;
public:
Collector_WithinSphere(typename PFP::MAP& mymap, const typename PFP::TVEC3& myposition) :
Collector<PFP>(mymap,myposition)
Collector_WithinSphere(typename PFP::MAP& m, const typename PFP::TVEC3& p, typename PFP::REAL r = 0) :
Collector<PFP>(m),
position(p),
radius(r),
area(0)
{}
void init(Dart d, typename PFP::REAL r = 0);
void collect();
inline void setRadius(typename PFP::REAL r) { radius = r; }
inline typename PFP::REAL getRadius() const { return radius; }
inline const typename PFP::TVEC3& getPosition() const { return position; }
void collectAll(Dart d);
void collectBorder(Dart d);
void computeArea();
typename PFP::REAL getArea() const { return area; }
inline typename PFP::REAL getArea() const { return area; }
};
} // namespace Selection
......