diff --git a/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.cc b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.cc
new file mode 100644
index 00000000..1082900b
--- /dev/null
+++ b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.cc
@@ -0,0 +1,99 @@
+/*===========================================================================*\
+ * *
+ * OpenMesh *
+ * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
+ * www.openmesh.org *
+ * *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenMesh. *
+ * *
+ * OpenMesh 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 3 of *
+ * the License, or (at your option) any later version with the *
+ * following exceptions: *
+ * *
+ * If other files instantiate templates or use macros *
+ * or inline functions from this file, or you compile this file and *
+ * link it with other files to produce an executable, this file does *
+ * not by itself cause the resulting executable to be covered by the *
+ * GNU Lesser General Public License. This exception does not however *
+ * invalidate any other reasons why the executable file might be *
+ * covered by the GNU Lesser General Public License. *
+ * *
+ * OpenMesh 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 LesserGeneral Public *
+ * License along with OpenMesh. If not, *
+ * see . *
+ * *
+\*===========================================================================*/
+
+/*===========================================================================*\
+ * *
+ * $Revision: 448 $ *
+ * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ *
+ * *
+\*===========================================================================*/
+
+/** \file ModEdgeLengthT.cc
+ */
+
+
+//=============================================================================
+//
+// CLASS ModEdgeLengthT - IMPLEMENTATION
+//
+//=============================================================================
+
+#define MB_MODEDGELENGTHT_C
+
+
+//== INCLUDES =================================================================
+
+#include "ModEdgeLengthT.hh"
+#include
+
+
+//== NAMESPACES ===============================================================
+
+namespace OpenMesh {
+namespace Decimater {
+
+
+//== IMPLEMENTATION ==========================================================
+
+
+template
+ModEdgeLengthT::
+ModEdgeLengthT(DecimaterT &_dec, float _edge_length, bool _is_binary)
+ : Base(_dec, _is_binary),
+ mesh_(Base::mesh())
+{
+ set_edge_length(_edge_length);
+}
+
+
+//-----------------------------------------------------------------------------
+
+
+template
+float
+ModEdgeLengthT::
+collapse_priority(const CollapseInfo& _ci)
+{
+ typename Mesh::Scalar sqr_length = (_ci.p0 - _ci.p1).sqrnorm();
+
+ return ((sqr_length <= sqr_edge_length_) ?
+ sqr_length :
+ float( Base::ILLEGAL_COLLAPSE ));
+}
+
+
+//=============================================================================
+}
+}
+//=============================================================================
diff --git a/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh
new file mode 100644
index 00000000..5362ffc6
--- /dev/null
+++ b/src/OpenMesh/Tools/Decimater/ModEdgeLengthT.hh
@@ -0,0 +1,118 @@
+/*===========================================================================*\
+ * *
+ * OpenMesh *
+ * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
+ * www.openmesh.org *
+ * *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenMesh. *
+ * *
+ * OpenMesh 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 3 of *
+ * the License, or (at your option) any later version with the *
+ * following exceptions: *
+ * *
+ * If other files instantiate templates or use macros *
+ * or inline functions from this file, or you compile this file and *
+ * link it with other files to produce an executable, this file does *
+ * not by itself cause the resulting executable to be covered by the *
+ * GNU Lesser General Public License. This exception does not however *
+ * invalidate any other reasons why the executable file might be *
+ * covered by the GNU Lesser General Public License. *
+ * *
+ * OpenMesh 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 LesserGeneral Public *
+ * License along with OpenMesh. If not, *
+ * see . *
+ * *
+\*===========================================================================*/
+
+/*===========================================================================*\
+ * *
+ * $Revision: 448 $ *
+ * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ *
+ * *
+\*===========================================================================*/
+
+/** \file ModEdgeLengthT.hh
+ */
+
+//=============================================================================
+//
+// CLASS ModEdgeLengthT
+//
+//=============================================================================
+
+
+#ifndef MB_MODEDGELENGTHT_HH
+#define MB_MODEDGELENGTHT_HH
+
+
+//== INCLUDES =================================================================
+
+#include
+#include
+
+
+//== NAMESPACES ===============================================================
+
+namespace OpenMesh {
+namespace Decimater {
+
+
+//== CLASS DEFINITION =========================================================
+
+
+template
+class ModEdgeLengthT : public ModBaseT
+{
+public:
+
+ DECIMATING_MODULE( ModEdgeLengthT, DecimaterT, EdgeLength );
+
+ /// Constructor
+ ModEdgeLengthT(DecimaterT& _dec,
+ float _edge_length = FLT_MAX,
+ bool _is_binary = true);
+
+
+ /// get edge_length
+ float edge_length() const { return edge_length_; }
+
+ /// set edge_length
+ void set_edge_length(float _f)
+ { edge_length_ = _f; sqr_edge_length_ = _f*_f; }
+
+
+ /** Compute priority:
+ Binary mode: Don't collapse edges longer then edge_length_
+ Cont. mode: Collapse smallest edge first, but
+ don't collapse edges longer as edge_length_
+ */
+ float collapse_priority(const CollapseInfo& _ci);
+
+
+private:
+
+ Mesh& mesh_;
+ typename Mesh::Scalar edge_length_, sqr_edge_length_;
+};
+
+
+//=============================================================================
+} // END_NS_DECIMATER
+} // END_NS_OPENMESH
+//=============================================================================
+#if defined(INCLUDE_TEMPLATES) && !defined(MB_MODEDGELENGTHT_C)
+#define MB_MODEDGELENGTHT_TEMPLATES
+#include "ModEdgeLengthT.cc"
+#endif
+//=============================================================================
+#endif // MB_MODEDGELENGTHT_HH defined
+//=============================================================================
+
diff --git a/src/OpenMesh/Tools/Decimater/ModHausdorffT.cc b/src/OpenMesh/Tools/Decimater/ModHausdorffT.cc
new file mode 100644
index 00000000..99b94a2c
--- /dev/null
+++ b/src/OpenMesh/Tools/Decimater/ModHausdorffT.cc
@@ -0,0 +1,272 @@
+/*===========================================================================*\
+ * *
+ * OpenMesh *
+ * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
+ * www.openmesh.org *
+ * *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenMesh. *
+ * *
+ * OpenMesh 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 3 of *
+ * the License, or (at your option) any later version with the *
+ * following exceptions: *
+ * *
+ * If other files instantiate templates or use macros *
+ * or inline functions from this file, or you compile this file and *
+ * link it with other files to produce an executable, this file does *
+ * not by itself cause the resulting executable to be covered by the *
+ * GNU Lesser General Public License. This exception does not however *
+ * invalidate any other reasons why the executable file might be *
+ * covered by the GNU Lesser General Public License. *
+ * *
+ * OpenMesh 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 LesserGeneral Public *
+ * License along with OpenMesh. If not, *
+ * see . *
+ * *
+\*===========================================================================*/
+
+/*===========================================================================*\
+ * *
+ * $Revision: 448 $ *
+ * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ *
+ * *
+\*===========================================================================*/
+
+/** \file ModHausdorffT.cc
+ */
+
+
+//=============================================================================
+//
+// CLASS ModHausdorffT - IMPLEMENTATION
+//
+//=============================================================================
+
+#define MB_MODHAUSDORFFT_C
+
+
+//== INCLUDES =================================================================
+
+#include "ModHausdorffT.hh"
+#include
+
+
+//== NAMESPACES ===============================================================
+
+namespace OpenMesh {
+namespace Decimater {
+
+
+//== IMPLEMENTATION ==========================================================
+
+
+template
+void
+ModHausdorffT::
+initialize()
+{
+ typename Mesh::FIter f_it(mesh_.faces_begin()), f_end(mesh_.faces_end());
+
+ for (; f_it!=f_end; ++f_it)
+ mesh_.property(points_, f_it).clear();
+}
+
+
+//-----------------------------------------------------------------------------
+
+
+template
+float
+ModHausdorffT::
+collapse_priority(const CollapseInfo& _ci)
+{
+ static Points points; points.clear();
+ std::vector faces; faces.reserve(20);
+ typename Mesh::VertexFaceIter vf_it;
+ typename Mesh::FaceHandle fh;
+ typename Mesh::Scalar sqr_tolerace = tolerance_*tolerance_;
+ typename Mesh::Point dummy;
+ typename Mesh::CFVIter fv_it;
+ bool ok;
+
+
+
+ // collect all points to be tested
+ // collect all faces to be tested against
+ for (vf_it=mesh_.vf_iter(_ci.v0); vf_it; ++vf_it) {
+ fh = vf_it.handle();
+
+ if (fh != _ci.fl && fh != _ci.fr)
+ faces.push_back(fh);
+
+ Points& pts = mesh_.property(points_, fh);
+ std::copy(pts.begin(), pts.end(), std::back_inserter(points));
+ }
+
+
+ // add point to be removed
+ points.push_back(_ci.p0);
+
+
+ // setup iterators
+ typename std::vector::iterator fh_it, fh_end(faces.end());
+ typename Points::const_iterator p_it, p_end(points.end());
+
+
+
+ // simulate collapse
+ mesh_.set_point(_ci.v0, _ci.p1);
+
+
+
+ // for each point: try to find a face such that error is < tolerance
+ ok = true;
+ for (p_it=points.begin(); ok && p_it!=p_end; ++p_it) {
+ ok = false;
+
+ for (fh_it=faces.begin(); !ok && fh_it!=fh_end; ++fh_it) {
+ const Point& p0 = mesh_.point(fv_it=mesh_.cfv_iter(*fh_it));
+ const Point& p1 = mesh_.point(++fv_it);
+ const Point& p2 = mesh_.point(++fv_it);
+
+ if ( ACG::Geometry::distPointTriangleSquared(*p_it, p0, p1, p2, dummy) <= sqr_tolerace)
+ ok = true;
+ }
+ }
+
+
+
+ // undo simulation changes
+ mesh_.set_point(_ci.v0, _ci.p0);
+
+
+
+ return ( ok ? Base::LEGAL_COLLAPSE : Base::ILLEGAL_COLLAPSE );
+}
+
+
+//-----------------------------------------------------------------------------
+
+
+template
+void
+ModHausdorffT::
+postprocess_collapse(const CollapseInfo& _ci)
+{
+ static Points points;
+ typename Mesh::VertexFaceIter vf_it;
+ FaceHandle fh;
+ std::vector faces;
+
+
+ // collect points & neighboring triangles
+
+ points.clear(); // it's static !
+ faces.reserve(20);
+
+
+ // collect active faces and their points
+ for (vf_it=mesh_.vf_iter(_ci.v1); vf_it; ++vf_it) {
+ fh = vf_it.handle();
+ faces.push_back(fh);
+
+ Points& pts = mesh_.property(points_, fh);
+ std::copy(pts.begin(), pts.end(), std::back_inserter(points));
+ pts.clear();
+ }
+ if (faces.empty()) return; // should not happen anyway...
+
+
+ // collect points of the 2 deleted faces
+ if ((fh=_ci.fl).is_valid()) {
+ Points& pts = mesh_.property(points_, fh);
+ std::copy(pts.begin(), pts.end(), std::back_inserter(points));
+ pts.clear();
+ }
+ if ((fh=_ci.fr).is_valid()) {
+ Points& pts = mesh_.property(points_, fh);
+ std::copy(pts.begin(), pts.end(), std::back_inserter(points));
+ pts.clear();
+ }
+
+
+ // add the deleted point
+ points.push_back(_ci.p0);
+
+
+
+
+ // setup iterators
+ typename std::vector::iterator fh_it, fh_end(faces.end());
+ typename Points::const_iterator p_it, p_end(points.end());
+
+
+
+ // re-distribute points
+ Scalar emin, e;
+ Point dummy;
+ typename Mesh::CFVIter fv_it;
+
+ for (p_it=points.begin(); p_it!=p_end; ++p_it) {
+ emin = FLT_MAX;
+
+ for (fh_it=faces.begin(); fh_it!=fh_end; ++fh_it) {
+ const Point& p0 = mesh_.point(fv_it=mesh_.cfv_iter(*fh_it));
+ const Point& p1 = mesh_.point(++fv_it);
+ const Point& p2 = mesh_.point(++fv_it);
+
+ e = ACG::Geometry::distPointTriangleSquared(*p_it, p0, p1, p2, dummy);
+ if (e < emin) {
+ emin = e;
+ fh = *fh_it;
+ }
+
+ }
+
+ mesh_.property(points_, fh).push_back(*p_it);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+
+
+template
+typename ModHausdorffT::Scalar
+ModHausdorffT::
+compute_sqr_error(FaceHandle _fh, const Point& _p) const
+{
+ typename Mesh::CFVIter fv_it = mesh_.cfv_iter(_fh);
+ const Point& p0 = mesh_.point(fv_it);
+ const Point& p1 = mesh_.point(++fv_it);
+ const Point& p2 = mesh_.point(++fv_it);
+
+ const Points& points = mesh_.property(points_, _fh);
+ typename Points::const_iterator p_it = points.begin();
+ typename Points::const_iterator p_end = points.end();
+
+ Point dummy;
+ Scalar e;
+ Scalar emax = ACG::Geometry::distPointTriangleSquared(_p, p0, p1, p2, dummy);
+
+ for (; p_it!=p_end; ++p_it) {
+ e = ACG::Geometry::distPointTriangleSquared(*p_it, p0, p1, p2, dummy);
+ if (e > emax)
+ emax = e;
+ }
+
+ return emax;
+}
+
+
+//=============================================================================
+}
+}
+//=============================================================================
diff --git a/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh b/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh
new file mode 100644
index 00000000..9aeca3ea
--- /dev/null
+++ b/src/OpenMesh/Tools/Decimater/ModHausdorffT.hh
@@ -0,0 +1,151 @@
+/*===========================================================================*\
+ * *
+ * OpenMesh *
+ * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
+ * www.openmesh.org *
+ * *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenMesh. *
+ * *
+ * OpenMesh 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 3 of *
+ * the License, or (at your option) any later version with the *
+ * following exceptions: *
+ * *
+ * If other files instantiate templates or use macros *
+ * or inline functions from this file, or you compile this file and *
+ * link it with other files to produce an executable, this file does *
+ * not by itself cause the resulting executable to be covered by the *
+ * GNU Lesser General Public License. This exception does not however *
+ * invalidate any other reasons why the executable file might be *
+ * covered by the GNU Lesser General Public License. *
+ * *
+ * OpenMesh 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 LesserGeneral Public *
+ * License along with OpenMesh. If not, *
+ * see . *
+ * *
+\*===========================================================================*/
+
+/*===========================================================================*\
+ * *
+ * $Revision: 448 $ *
+ * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ *
+ * *
+\*===========================================================================*/
+
+/** \file ModHausdorffT.hh
+ */
+
+
+//=============================================================================
+//
+// CLASS ModHausdorffT
+//
+//=============================================================================
+
+
+#ifndef MB_MODHAUSDORFFT_HH
+#define MB_MODHAUSDORFFT_HH
+
+
+//== INCLUDES =================================================================
+
+#include
+#include
+#include
+#include
+
+
+//== NAMESPACES ===============================================================
+
+namespace OpenMesh {
+namespace Decimater {
+
+
+//== CLASS DEFINITION =========================================================
+
+
+template
+class ModHausdorffT : public ModBaseT
+{
+public:
+
+ DECIMATING_MODULE( ModHausdorffT, DecimaterT, Roundness );
+
+ typedef typename Mesh::Scalar Scalar;
+ typedef typename Mesh::Point Point;
+ typedef typename Mesh::FaceHandle FaceHandle;
+ typedef std::vector Points;
+
+
+ /// Constructor
+ ModHausdorffT(DecimaterT& _dec,
+ Scalar _error_tolerance = FLT_MAX)
+ : Base(_dec, true),
+ mesh_(Base::mesh()),
+ tolerance_(_error_tolerance)
+ {
+ mesh_.add_property(points_);
+ }
+
+
+ /// Destructor
+ ~ModHausdorffT()
+ {
+ mesh_.remove_property(points_);
+ }
+
+
+ /// get max error tolerance
+ Scalar tolerance() const { return tolerance_; }
+
+ /// set max error tolerance
+ void set_tolerance(Scalar _e) { tolerance_ = _e; }
+
+
+ /// reset per-face point lists
+ virtual void initialize();
+
+
+ /// compute Hausdorff error for one-ring
+ virtual float collapse_priority(const CollapseInfo& _ci);
+
+
+ /// re-distribute points
+ virtual void postprocess_collapse(const CollapseInfo& _ci);
+
+
+
+private:
+
+ /// compute max error for face _fh w.r.t. its point list and _p
+ Scalar compute_sqr_error(FaceHandle _fh, const Point& _p) const;
+
+
+private:
+
+ Mesh& mesh_;
+ Scalar tolerance_;
+
+ OpenMesh::FPropHandleT points_;
+};
+
+
+//=============================================================================
+} // END_NS_DECIMATER
+} // END_NS_OPENMESH
+//=============================================================================
+#if defined(INCLUDE_TEMPLATES) && !defined(MB_MODHAUSDORFFT_C)
+#define MB_MODHAUSDORFFT_TEMPLATES
+#include "ModHausdorffT.cc"
+#endif
+//=============================================================================
+#endif // MB_MODHAUSDORFFT_HH defined
+//=============================================================================
+
diff --git a/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh b/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh
new file mode 100644
index 00000000..497ec52d
--- /dev/null
+++ b/src/OpenMesh/Tools/Decimater/ModNormalDeviationT.hh
@@ -0,0 +1,213 @@
+/*===========================================================================*\
+ * *
+ * OpenMesh *
+ * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
+ * www.openmesh.org *
+ * *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenMesh. *
+ * *
+ * OpenMesh 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 3 of *
+ * the License, or (at your option) any later version with the *
+ * following exceptions: *
+ * *
+ * If other files instantiate templates or use macros *
+ * or inline functions from this file, or you compile this file and *
+ * link it with other files to produce an executable, this file does *
+ * not by itself cause the resulting executable to be covered by the *
+ * GNU Lesser General Public License. This exception does not however *
+ * invalidate any other reasons why the executable file might be *
+ * covered by the GNU Lesser General Public License. *
+ * *
+ * OpenMesh 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 LesserGeneral Public *
+ * License along with OpenMesh. If not, *
+ * see . *
+ * *
+\*===========================================================================*/
+
+/*===========================================================================*\
+ * *
+ * $Revision: 448 $ *
+ * $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ *
+ * *
+\*===========================================================================*/
+
+/** \file ModNormalDeviationT.hh
+ */
+
+//=============================================================================
+//
+// CLASS ModNormalDeviationT
+//
+//=============================================================================
+
+
+#ifndef MB_MODNORMALDEVIATIONT_HH
+#define MB_MODNORMALDEVIATIONT_HH
+
+
+//== INCLUDES =================================================================
+
+#include
+#include
+#include
+
+
+//== NAMESPACES ===============================================================
+
+namespace OpenMesh {
+namespace Decimater {
+
+
+//== CLASS DEFINITION =========================================================
+
+
+
+template
+class ModNormalDeviationT : public ModBaseT< DecimaterT >
+{
+public:
+
+ DECIMATING_MODULE( ModNormalDeviationT, DecimaterT, NormalDeviation );
+
+ typedef typename Mesh::Scalar Scalar;
+ typedef typename Mesh::Point Point;
+ typedef typename Mesh::Normal Normal;
+ typedef typename Mesh::VertexHandle VertexHandle;
+ typedef typename Mesh::FaceHandle FaceHandle;
+ typedef typename Mesh::EdgeHandle EdgeHandle;
+ typedef ACG::Geometry::NormalConeT NormalCone;
+
+
+
+public:
+
+ /// Constructor
+ ModNormalDeviationT(DecimaterT& _dec, float _max_dev = 180.0)
+ : Base(_dec, true),
+ mesh_(Base::mesh())
+ {
+ set_normal_deviation(_max_dev);
+ mesh_.add_property(normal_cones_);
+ }
+
+
+ /// Destructor
+ ~ModNormalDeviationT() {
+ mesh_.add_property(normal_cones_);
+ }
+
+
+ /// Get normal deviation
+ Scalar normal_deviation() const {
+ return normal_deviation_ / M_PI * 180.0;
+ }
+
+ /// Set normal deviation
+ void set_normal_deviation(Scalar _s) {
+ normal_deviation_ = _s / 180.0 * M_PI;
+ }
+
+
+ /// Allocate and init normal cones
+ void initialize() {
+ if (!normal_cones_.is_valid())
+ mesh_.add_property(normal_cones_);
+
+ typename Mesh::FaceIter f_it = mesh_.faces_begin(),
+ f_end = mesh_.faces_end();
+
+ for (; f_it != f_end; ++f_it)
+ mesh_.property(normal_cones_, f_it) = NormalCone(mesh_.normal(f_it));
+ }
+
+
+ float collapse_priority(const CollapseInfo& _ci) {
+ // simulate collapse
+ mesh_.set_point(_ci.v0, _ci.p1);
+
+
+ typename Mesh::Scalar max_angle(0.0);
+ typename Mesh::ConstVertexFaceIter vf_it(mesh_, _ci.v0);
+ typename Mesh::FaceHandle fh, fhl, fhr;
+
+ if (_ci.v0vl.is_valid()) fhl = mesh_.face_handle(_ci.v0vl);
+ if (_ci.vrv0.is_valid()) fhr = mesh_.face_handle(_ci.vrv0);
+
+ for (; vf_it; ++vf_it) {
+ fh = vf_it.handle();
+ if (fh != _ci.fl && fh != _ci.fr) {
+ NormalCone nc = mesh_.property(normal_cones_, fh);
+
+ nc.merge(NormalCone(mesh_.calc_face_normal(fh)));
+ if (fh == fhl) nc.merge(mesh_.property(normal_cones_, _ci.fl));
+ if (fh == fhr) nc.merge(mesh_.property(normal_cones_, _ci.fr));
+
+ if (nc.angle() > max_angle) {
+ max_angle = nc.angle();
+ if (max_angle > 0.5*normal_deviation_)
+ break;
+ }
+ }
+ }
+
+
+ // undo simulation changes
+ mesh_.set_point(_ci.v0, _ci.p0);
+
+
+ return (max_angle < 0.5*normal_deviation_ ?
+ max_angle : float( Base::ILLEGAL_COLLAPSE ));
+ }
+
+
+ void postprocess_collapse(const CollapseInfo& _ci) {
+ // account for changed normals
+ typename Mesh::VertexFaceIter vf_it(mesh_, _ci.v1);
+ for (; vf_it; ++vf_it)
+ mesh_.property(normal_cones_, vf_it).
+ merge(NormalCone(mesh_.normal(vf_it)));
+
+
+ // normal cones of deleted triangles
+ typename Mesh::FaceHandle fh;
+
+ if (_ci.vlv1.is_valid()) {
+ fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(_ci.vlv1));
+ if (fh.is_valid())
+ mesh_.property(normal_cones_, fh).
+ merge(mesh_.property(normal_cones_, _ci.fl));
+ }
+
+ if (_ci.v1vr.is_valid()) {
+ fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(_ci.v1vr));
+ if (fh.is_valid())
+ mesh_.property(normal_cones_, fh).
+ merge(mesh_.property(normal_cones_, _ci.fr));
+ }
+ }
+
+
+
+private:
+
+ Mesh& mesh_;
+ Scalar normal_deviation_;
+ OpenMesh::FPropHandleT normal_cones_;
+};
+
+
+//=============================================================================
+} // END_NS_DECIMATER
+} // END_NS_OPENMESH
+//=============================================================================
+#endif // MB_MODNORMALDEVIATIONT_HH defined
+//=============================================================================
+