Commit ab864c18 authored by Sylvain Thery's avatar Sylvain Thery

Merge branch 'master' of ssh://cgogn/~cgogn/CGoGN

parents 269abf38 f9dee600
...@@ -49,6 +49,8 @@ ...@@ -49,6 +49,8 @@
#include "Algo/Render/GL2/topo3Render.h" #include "Algo/Render/GL2/topo3Render.h"
#include "Utils/Shaders/shaderSimpleColor.h" #include "Utils/Shaders/shaderSimpleColor.h"
#include "Utils/cgognStream.h" #include "Utils/cgognStream.h"
#include "Utils/drawer.h" #include "Utils/drawer.h"
......
...@@ -22,8 +22,12 @@ ...@@ -22,8 +22,12 @@
* * * *
*******************************************************************************/ *******************************************************************************/
#include "Algo/Filtering/functors.h" #ifndef __ALGO_BOOLEANOPERATOR_VERTICES_H__
#include "Algo/Selection/collector.h" #define __ALGO_BOOLEANOPERATOR_VERTICES_H__
#include "Geometry/basic.h"
#include "Geometry/inclusion.h"
#include "Geometry/orientation.h"
namespace CGoGN namespace CGoGN
{ {
...@@ -31,34 +35,21 @@ namespace CGoGN ...@@ -31,34 +35,21 @@ namespace CGoGN
namespace Algo namespace Algo
{ {
namespace Filtering namespace BooleanOperator
{ {
template <typename PFP> template <typename PFP>
void filterAveragePositions(typename PFP::MAP& map, const typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue()) void mergeVertex(typename PFP::MAP& map, const typename PFP::TVEC3& positions, Dart d, Dart e);
{
typedef typename PFP::VEC3 VEC3 ;
FunctorAverage<typename PFP::MAP, typename PFP::VEC3> fa(map, position) ; template <typename PFP>
Algo::Selection::Collector_OneRing<PFP> c(map) ; void mergeVertices(typename PFP::MAP& map, const typename PFP::TVEC3& positions);
CellMarker markV(map, VERTEX); }
for(Dart d = map.begin(); d != map.end(); map.next(d))
{
if(select(d) && !markV.isMarked(d))
{
markV.mark(d);
c.collectBorder(d) ;
fa.reset() ;
c.applyOnBorder(fa) ;
position2[d] = fa.getAverage() ;
}
}
} }
} // namespace Filtering }
} // namespace Algo #include "mergeVertices.hpp"
} // namespace CGoGN #endif
/*******************************************************************************
* 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 *
* *
*******************************************************************************/
namespace CGoGN
{
namespace Algo
{
namespace BooleanOperator
{
template <typename PFP>
void mergeVertex(typename PFP::MAP& map, const typename PFP::TVEC3& positions, Dart d, Dart e)
{
assert(Geom::arePointsEquals(positions[d],positions[e]) && !map.sameVertex(d,e));
Dart dd;
do
{
dd = map.alpha1(d);
map.removeEdgeFromVertex(dd);
Dart ee = e;
do
{
if(Geom::testOrientation2D(positions[map.phi1(dd)],positions[ee],positions[map.phi1(ee)])!=Geom::RIGHT
&& Geom::testOrientation2D(positions[map.phi1(dd)],positions[ee],positions[map.phi1(map.alpha1(ee))])==Geom::RIGHT)
{
break;
}
ee = map.alpha1(ee);
} while(ee != e);
map.insertEdgeInVertex(ee,dd);
} while(dd!=d);
}
template <typename PFP>
void mergeVertices(typename PFP::MAP& map, const typename PFP::TVEC3& positions)
{
for(Dart d = map.begin() ; d != map.end() ; map.next(d))
{
CellMarker vM(map,VERTEX);
vM.mark(d);
for(Dart dd = map.begin() ; dd != map.end() ; map.next(dd))
{
if(!vM.isMarked(dd))
{
vM.mark(dd);
if(Geom::arePointsEquals(positions[d],positions[dd]))
{
mergeVertex<PFP>(map,positions,d,dd);
}
}
}
}
}
}
}
}
...@@ -95,7 +95,7 @@ void exportMeshWire(std::ofstream& out, typename PFP::MAP& map, typename PFP::TV ...@@ -95,7 +95,7 @@ void exportMeshWire(std::ofstream& out, typename PFP::MAP& map, typename PFP::TV
if(position[dd][0]!=position[map.phi1(dd)][0] || position[dd][1]!=position[map.phi1(dd)][1] || position[dd][2]!=position[map.phi1(dd)][2]) { if(position[dd][0]!=position[map.phi1(dd)][0] || position[dd][1]!=position[map.phi1(dd)][1] || position[dd][2]!=position[map.phi1(dd)][2]) {
out << "cylinder{ " << std::endl; out << "cylinder{ " << std::endl;
out << "<" << position[dd][0] << "," << position[dd][2] << "," << position[dd][1] << ">," << std::endl; out << "<" << position[dd][0] << "," << position[dd][2] << "," << position[dd][1] << ">," << std::endl;
out << "<" << position[map.phi1(dd)][0] << "," << position[map.phi1(dd)][2] << "," << position[map.phi1(dd)][1] << ">, 0.5" << std::endl; out << "<" << position[map.phi1(dd)][0] << "," << position[map.phi1(dd)][2] << "," << position[map.phi1(dd)][1] << ">, 1.5" << std::endl;
out << "}" << std::endl; out << "}" << std::endl;
} }
dd = map.phi1(dd); dd = map.phi1(dd);
......
/*******************************************************************************
* 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 *
* *
*******************************************************************************/
#include "Algo/Filtering/functors.h"
#include "Algo/Selection/collector.h"
namespace CGoGN
{
namespace Algo
{
namespace Filtering
{
enum neighborhood { INSIDE = 1, BORDER = 2 };
template <typename PFP, typename T>
void filterAverageAttribute_OneRing(
typename PFP::MAP& map,
const AttributeHandler<T>& attIn,
AttributeHandler<T>& attOut,
int neigh,
const FunctorSelect& select = SelectorTrue())
{
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))
{
if(select(d) && !markV.isMarked(d))
{
markV.mark(d) ;
if (neigh & INSIDE)
col.collectAll(d) ;
else
col.collectBorder(d) ;
fa.reset() ;
if (neigh & INSIDE)
{
switch (attIn.getOrbit())
{
case VERTEX :
col.applyOnInsideVertices(fa) ;
break;
case EDGE :
col.applyOnInsideEdges(fa) ;
break;
case FACE :
col.applyOnInsideFaces(fa) ;
break;
}
}
if (neigh & BORDER) col.applyOnBorder(fa) ;
attOut[d] = fa.getAverage() ;
}
}
}
template <typename PFP, typename T>
void filterAverageEdgesAttribute_WithinSphere(
typename PFP::MAP& map,
const AttributeHandler<T>& attIn,
AttributeHandler<T>& attOut,
int neigh,
typename PFP::TVEC3 & position,
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))
{
if(select(d) && !markV.isMarked(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() ;
}
}
}
template <typename PFP, typename T>
void filterAverageFacesAttribute_WithinSphere(
typename PFP::MAP& map,
const AttributeHandler<T>& attIn,
AttributeHandler<T>& attOut,
int neigh,
typename PFP::TVEC3 & position,
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))
{
if(select(d) && !markV.isMarked(d))
{
markV.mark(d) ;
if (neigh & INSIDE)
col.collectAll(d) ;
else
col.collectBorder(d) ;
fa.reset() ;
if (neigh & INSIDE) col.applyOnInsideFaces(fa) ;
if (neigh & BORDER) col.applyOnBorder(fa) ;
attOut[d] = fa.getAverage() ;
}
}
}
template <typename PFP, typename T>
void filterAverageVertexAttribute_WithinSphere(
typename PFP::MAP& map,
const AttributeHandler<T>& attIn,
AttributeHandler<T>& attOut,
int neigh,
typename PFP::TVEC3 & position,
typename PFP::REAL radius,
const FunctorSelect& select = SelectorTrue())
{
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))
{
if(select(d) && !markV.isMarked(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() ;
}
}
}
} // namespace Filtering
} // namespace Algo
} // namespace CGoGN
/*******************************************************************************
* 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 __FILTERING_FUNCTORS_H__
#define __FILTERING_FUNCTORS_H__
#include "Topology/generic/functor.h"
#include "Algo/Geometry/intersection.h"
namespace CGoGN
{
namespace Algo
{
namespace Filtering
{
template <typename T>
class FunctorAverage : public virtual FunctorType
{
protected:
const AttributeHandler<T>& attr ;
T sum ;
unsigned int count ;
public:
FunctorAverage(const AttributeHandler<T>& a) : FunctorType(), attr(a), sum(0), count(0)
{}
bool operator()(Dart d)
{
sum += attr[d] ;
++count ;
return false ;
}
inline void reset() { sum = T(0) ; count = 0 ; }
inline T getSum() { return sum ; }
inline unsigned int getCount() { return count ; }
inline T getAverage() { return sum / typename T::DATA_TYPE(count) ; }
} ;
template <typename PFP, typename T>
class FunctorAverageOnSphereBorder : public FunctorMap<typename PFP::MAP>
{
typedef typename PFP::VEC3 VEC3;
protected:
const AttributeHandler<T>& attr ;
const AttributeHandler<VEC3>& position ;
VEC3 center;
typename PFP::REAL radius;
T sum ;
unsigned int count ;
public:
FunctorAverageOnSphereBorder(typename PFP::MAP& map, const AttributeHandler<T>& a, const AttributeHandler<VEC3>& p) :
FunctorMap<typename PFP::MAP>(map), attr(a), position(p), sum(0), count(0)
{
center = VEC3(0);
radius = 0;
}
bool operator()(Dart d)
{
typename PFP::REAL alpha = 0;
Algo::Geometry::intersectionSphereEdge<PFP>(this->m_map, center, radius, d, position, alpha);
sum += (1 - alpha) * attr[d] + alpha * attr[this->m_map.phi1(d)] ;
++count ;
return false ;
}
inline void reset(VEC3& c, typename PFP::REAL r) { center = c; radius = r; sum = T(0) ; count = 0 ; }
inline T getSum() { return sum ; }
inline unsigned int getCount() { return count ; }
inline T getAverage() { return sum / typename T::DATA_TYPE(count) ; }
} ;
} // namespace Filtering
} // namespace Algo
} // namespace CGoGN
#endif
...@@ -39,13 +39,14 @@ void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typenam ...@@ -39,13 +39,14 @@ void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typenam
{ {
typedef typename PFP::VEC3 VEC3 ; typedef typename PFP::VEC3 VEC3 ;
FunctorAverage<typename PFP::MAP, typename PFP::VEC3> fa(map, position) ;
Algo::Selection::Collector_OneRing<PFP> c(map) ; Algo::Selection::Collector_OneRing<PFP> c(map) ;
const float lambda = 0.6307 ; const float lambda = 0.6307 ;
const float mu = -0.6732 ; const float mu = -0.6732 ;
CellMarkerNoUnmark mv(map, VERTEX) ; CellMarkerNoUnmark mv(map, VERTEX) ;
FunctorAverage<VEC3> fa1(position) ;
for(Dart d = map.begin(); d != map.end(); map.next(d)) for(Dart d = map.begin(); d != map.end(); map.next(d))
{ {
if(select(d) && !mv.isMarked(d)) if(select(d) && !mv.isMarked(d))
...@@ -53,16 +54,18 @@ void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typenam ...@@ -53,16 +54,18 @@ void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typenam
mv.mark(d); mv.mark(d);
c.collectBorder(d) ; c.collectBorder(d) ;
fa.reset() ; fa1.reset() ;
c.applyOnBorder(fa) ; c.applyOnBorder(fa1) ;
VEC3 p = position[d] ; VEC3 p = position[d] ;
VEC3 displ = fa.getAverage() - p ; VEC3 displ = fa1.getAverage() - p ;
// VEC3 displ = (fa1.getSum() - p * fa1.getCount()) / fa1.getCount() ;
displ *= lambda ; displ *= lambda ;
position2[d] = p + displ ; position2[d] = p + displ ;
} }
} }
// unshrinking step // unshrinking step
FunctorAverage<VEC3> fa2(position2) ;
for(Dart d = map.begin(); d != map.end(); map.next(d)) for(Dart d = map.begin(); d != map.end(); map.next(d))
{ {
if(select(d) && mv.isMarked(d)) if(select(d) && mv.isMarked(d))
...@@ -70,10 +73,11 @@ void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typenam ...@@ -70,10 +73,11 @@ void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typenam
mv.unmark(d); mv.unmark(d);
c.collectBorder(d) ; c.collectBorder(d) ;
fa.reset() ; fa2.reset() ;
c.applyOnBorder(fa) ; c.applyOnBorder(fa2) ;
VEC3 p = position2[d] ; VEC3 p = position2[d] ;
VEC3 displ = fa.getAverage() - p ; VEC3 displ = fa2.getAverage() - p ;
// VEC3 displ = (fa2.getSum() - p * fa2.getCount()) / fa2.getCount() ;
displ *= mu ; displ *= mu ;
position[d] = p + displ ; position[d] = p + displ ;
} }
...@@ -84,16 +88,16 @@ void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typenam ...@@ -84,16 +88,16 @@ void filterTaubin(typename PFP::MAP& map, typename PFP::TVEC3& position, typenam
* Taubin filter modified as proposed by [Lav09] * Taubin filter modified as proposed by [Lav09]
*/ */
template <typename PFP> template <typename PFP>
void filterTaubin_modified(typename PFP::MAP& map, typename PFP::TVEC3& position, typename PFP::TVEC3& position2, const FunctorSelect& select = SelectorTrue()) void filterTaubin_modified(typename PFP::MAP& map, typename PFP::TVEC3& position, typename PFP::TVEC3& position2, typename PFP::REAL radius, const FunctorSelect& select = SelectorTrue())
{ {
typedef typename PFP::VEC3 VEC3 ; 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 lambda = 0.6307 ;
const float mu = -0.6732 ; const float mu = -0.6732 ;
FunctorAverageOnSphereBorder<PFP, typename PFP::VEC3> fa1(map, position, position) ;
Algo::Selection::Collector_WithinSphere<PFP> c1(map, position, radius) ;
CellMarkerNoUnmark mv(map, VERTEX) ; CellMarkerNoUnmark mv(map, VERTEX) ;
for(Dart d = map.begin(); d != map.end(); map.next(d)) for(Dart d = map.begin(); d != map.end(); map.next(d))
{ {
...@@ -101,30 +105,32 @@ void filterTaubin_modified(typename PFP::MAP& map, typename PFP::TVEC3& position ...@@ -101,30 +105,32 @@ void filterTaubin_modified(typename PFP::MAP& map, typename PFP::TVEC3& position
{ {
mv.mark(d); mv.mark(d);
c.collectBorder(d) ; c1.collectBorder(d) ;
fa.reset() ; VEC3 center = position[d] ;
c.applyOnBorder(fa) ; fa1.reset(center, radius) ;
VEC3 p = position[d] ; c1.applyOnBorder(fa1) ;
VEC3 displ = fa.getAverage() - p ; VEC3 displ = fa1.getAverage() - center ;