diff --git a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc new file mode 100644 index 0000000000000000000000000000000000000000..1d2db21eb2d6aa66cebb477ecc0fe1cc62138d2d --- /dev/null +++ b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.cc @@ -0,0 +1,212 @@ +/*===========================================================================*\ + * * + * 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 ModAspectRatioT.cc + */ + + +//============================================================================= +// +// CLASS ModAspectRatioT - IMPLEMENTATION +// +//============================================================================= + +#define MB_MODASPECTRATIOT_C + + +//== INCLUDES ================================================================= + +#include "ModAspectRatioT.hh" + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace Decimater { + + +//== IMPLEMENTATION ========================================================== + + +template +typename ModAspectRatioT::Scalar +ModAspectRatioT:: +aspectRatio( const Point& _v0, + const Point& _v1, + const Point& _v2 ) +{ + Point d0 = _v0 - _v1; + Point d1 = _v1 - _v2; + + // finds the max squared edge length + Scalar l2, maxl2 = d0.sqrnorm(); + if ((l2=d1.sqrnorm()) > maxl2) + maxl2 = l2; + // keep searching for the max squared edge length + d1 = _v2 - _v0; + if ((l2=d1.sqrnorm()) > maxl2) + maxl2 = l2; + + // squared area of the parallelogram spanned by d0 and d1 + Scalar a2 = (d0 % d1).sqrnorm(); + + // the area of the triangle would be + // sqrt(a2)/2 or length * height / 2 + // aspect ratio = length / height + // = length * length / (2*area) + // = length * length / sqrt(a2) + + // returns the length of the longest edge + // divided by its corresponding height + return sqrt( (maxl2 * maxl2) / a2 ); +} + + +//----------------------------------------------------------------------------- + + +template +void +ModAspectRatioT:: +initialize() +{ + typename Mesh::FaceIter f_it, f_end(mesh_.faces_end()); + typename Mesh::FVIter fv_it; + + for (f_it=mesh_.faces_begin(); f_it!=f_end; ++f_it) + { + typename Mesh::Point& p0 = mesh_.point(fv_it=mesh_.fv_iter(f_it)); + typename Mesh::Point& p1 = mesh_.point(++fv_it); + typename Mesh::Point& p2 = mesh_.point(++fv_it); + + mesh_.property(roundness_, f_it) = + 1.0/aspectRatio(p0, p1, p2); + } +} + + +//----------------------------------------------------------------------------- + + +template +void +ModAspectRatioT:: +preprocess_collapse(const CollapseInfo& _ci) +{ + typename Mesh::FaceHandle fh; + typename Mesh::FVIter fv_it; + + for (typename Mesh::VFIter vf_it=mesh_.vf_iter(_ci.v0); vf_it; ++vf_it) + { + fh = vf_it.handle(); + if (fh != _ci.fl && fh != _ci.fr) + { + typename Mesh::Point& p0 = mesh_.point(fv_it=mesh_.fv_iter(fh)); + typename Mesh::Point& p1 = mesh_.point(++fv_it); + typename Mesh::Point& p2 = mesh_.point(++fv_it); + + mesh_.property(roundness_, fh) = + 1.0/aspectRatio(p0, p1, p2); + } + } +} + + +//----------------------------------------------------------------------------- + + +template +float +ModAspectRatioT:: +collapse_priority(const CollapseInfo& _ci) +{ + typename Mesh::VertexHandle v2, v3; + typename Mesh::FaceHandle fh; + const typename Mesh::Point *p1(&_ci.p1), *p2, *p3; + typename Mesh::Scalar r0, r1, r0_min(1.0), r1_min(1.0); + typename Mesh::CVVIter vv_it(mesh_, _ci.v0); + + v3 = vv_it.handle(); + p3 = &mesh_.point(v3); + + while (vv_it) + { + v2 = v3; + p2 = p3; + + v3 = (++vv_it).handle(); + p3 = &mesh_.point(v3); + + fh = mesh_.face_handle(vv_it.current_halfedge_handle()); + + // if not boundary + if (fh.is_valid()) + { + // roundness before + if ((r0 = mesh_.property(roundness_,fh)) < r0_min) + r0_min = r0; + + // roundness after + if (!(v2 == _ci.v1 || v3 == _ci.v1)) + if ((r1 = 1.0/aspectRatio(*p1, *p2, *p3)) < r1_min) + r1_min = r1; + } + } + + + if (Base::is_binary()) + { + return ((r1_min > r0_min) || (r1_min > min_roundness_)) ? 0.0 : -1.0; + } + else + { + if (r1_min > r0_min) + return 1.0 - r1_min; + else + return (r1_min > min_roundness_) ? 2.0 - r1_min : -1.0; + } +} + + +//============================================================================= +} +} +//============================================================================= diff --git a/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh new file mode 100644 index 0000000000000000000000000000000000000000..772d2fe6a782d1bf7cc2971333fa9241d147cea1 --- /dev/null +++ b/src/OpenMesh/Tools/Decimater/ModAspectRatioT.hh @@ -0,0 +1,143 @@ +/*===========================================================================*\ + * * + * 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 ModAspectRatioT.hh + */ + + +//============================================================================= +// +// CLASS ModAspectRatioT +// +//============================================================================= + + +#ifndef MODASPECTRATIOT_HH +#define MODASPECTRATIOT_HH + + +//== INCLUDES ================================================================= + +#include +#include + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { +namespace Decimater { + + +//== CLASS DEFINITION ========================================================= + + +template +class ModAspectRatioT : public ModBaseT +{ +public: + + DECIMATING_MODULE( ModAspectRatioT, DecimaterT, Roundness ); + + typedef typename Mesh::Scalar Scalar; + typedef typename Mesh::Point Point; + + // constructor + ModAspectRatioT(DecimaterT& _dec, + float _min_roundness = 5.0, + bool _is_binary = true) + : Base(_dec, _is_binary), + mesh_(Base::mesh()), + min_roundness_(1.0/_min_roundness) + { + mesh_.add_property( roundness_ ); + } + + + // destructor + ~ModAspectRatioT() + { + mesh_.remove_property( roundness_ ); + } + + + + /// get roundness + float roundness() const { return 1.0/min_roundness_; } + /// set roundness + void set_roundness(float _f) { min_roundness_ = 1.0/_f; } + + // precompute face roundness + void initialize(); + // blabla + float collapse_priority(const CollapseInfo& _ci); + // update roundness of one-ring + void preprocess_collapse(const CollapseInfo& _ci); + + +private: + + /** \brief return aspect ratio (length/height) of triangle + * + */ + Scalar aspectRatio( const Point& _v0, + const Point& _v1, + const Point& _v2 ); + +private: + + Mesh& mesh_; + float min_roundness_; + FPropHandleT roundness_; +}; + + +//============================================================================= +} // END_NS_DECIMATER +} // END_NS_OPENMESH +//============================================================================= +#if defined(INCLUDE_TEMPLATES) && !defined(MB_MODASPECTRATIOT_C) +#define MODASPECTRATIOT_TEMPLATES +#include "ModAspectRatioT.cc" +#endif +//============================================================================= +#endif // MB_MODASPECTRATIOT_HH defined +//============================================================================= +