OpenMesh
OpenMesh/Tools/Decimater/ModNormalDeviationT.hh
Go to the documentation of this file.
00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                               OpenMesh                                    *
00004  *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openmesh.org                                *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------*
00008  *  This file is part of OpenMesh.                                           *
00009  *                                                                           *
00010  *  OpenMesh is free software: you can redistribute it and/or modify         *
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenMesh is distributed in the hope that it will be useful,              *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenMesh.  If not,                                    *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/
00034 
00035 /*===========================================================================*\
00036  *                                                                           *
00037  *   $Revision: 448 $                                                        *
00038  *   $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $                   *
00039  *                                                                           *
00040 \*===========================================================================*/
00041 
00045 //=============================================================================
00046 //
00047 //  CLASS ModNormalDeviationT
00048 //
00049 //=============================================================================
00050 
00051 
00052 #ifndef OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH
00053 #define OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH
00054 
00055 
00056 //== INCLUDES =================================================================
00057 
00058 #include <OpenMesh/Tools/Decimater/ModBaseT.hh>
00059 #include <OpenMesh/Core/Utils/Property.hh>
00060 #include <OpenMesh/Core/Geometry/NormalConeT.hh>
00061 
00062 
00063 //== NAMESPACES ===============================================================
00064 
00065 namespace OpenMesh  {
00066 namespace Decimater {
00067 
00068 
00069 //== CLASS DEFINITION =========================================================
00070 
00071 
00086 template <class DecimaterT>
00087 class ModNormalDeviationT : public ModBaseT< DecimaterT >
00088 {
00089 public:
00090    
00091   DECIMATING_MODULE( ModNormalDeviationT, DecimaterT, NormalDeviation );
00092 
00093   typedef typename Mesh::Scalar                     Scalar;
00094   typedef typename Mesh::Point                      Point;
00095   typedef typename Mesh::Normal                     Normal;
00096   typedef typename Mesh::VertexHandle               VertexHandle;
00097   typedef typename Mesh::FaceHandle                 FaceHandle;
00098   typedef typename Mesh::EdgeHandle                 EdgeHandle;
00099   typedef NormalConeT<Scalar>                       NormalCone;
00100 
00101 
00102 
00103 public:
00104 
00106   ModNormalDeviationT(DecimaterT& _dec, float _max_dev = 180.0) 
00107   : Base(_dec, true), mesh_(Base::mesh())
00108   {
00109     set_normal_deviation(_max_dev);
00110     mesh_.add_property(normal_cones_);
00111   }
00112 
00113 
00115   ~ModNormalDeviationT() {
00116     mesh_.add_property(normal_cones_);
00117   }
00118 
00119 
00121   Scalar normal_deviation() const {
00122     return normal_deviation_ / M_PI * 180.0;
00123   }
00124 
00126   void set_normal_deviation(Scalar _s) {
00127     normal_deviation_ = _s / 180.0 * M_PI;
00128   }
00129 
00130 
00132   void  initialize() {
00133     if (!normal_cones_.is_valid())
00134       mesh_.add_property(normal_cones_);
00135 
00136     typename Mesh::FaceIter f_it  = mesh_.faces_begin(),
00137         f_end = mesh_.faces_end();
00138 
00139     for (; f_it != f_end; ++f_it)
00140       mesh_.property(normal_cones_, f_it) = NormalCone(mesh_.normal(f_it));
00141   }
00142 
00157   float collapse_priority(const CollapseInfo& _ci) {
00158     // simulate collapse
00159     mesh_.set_point(_ci.v0, _ci.p1);
00160 
00161 
00162     typename Mesh::Scalar               max_angle(0.0);
00163     typename Mesh::ConstVertexFaceIter  vf_it(mesh_, _ci.v0);
00164     typename Mesh::FaceHandle           fh, fhl, fhr;
00165 
00166     if (_ci.v0vl.is_valid())  fhl = mesh_.face_handle(_ci.v0vl);
00167     if (_ci.vrv0.is_valid())  fhr = mesh_.face_handle(_ci.vrv0);
00168 
00169     for (; vf_it; ++vf_it) {
00170       fh = vf_it.handle();
00171       if (fh != _ci.fl && fh != _ci.fr) {
00172         NormalCone nc = mesh_.property(normal_cones_, fh);
00173 
00174         nc.merge(NormalCone(mesh_.calc_face_normal(fh)));
00175         if (fh == fhl) nc.merge(mesh_.property(normal_cones_, _ci.fl));
00176         if (fh == fhr) nc.merge(mesh_.property(normal_cones_, _ci.fr));
00177 
00178         if (nc.angle() > max_angle) {
00179           max_angle = nc.angle();
00180           if (max_angle > 0.5 * normal_deviation_)
00181             break;
00182         }
00183       }
00184     }
00185 
00186 
00187     // undo simulation changes
00188     mesh_.set_point(_ci.v0, _ci.p0);
00189 
00190 
00191     return (max_angle < 0.5 * normal_deviation_ ? max_angle : float( Base::ILLEGAL_COLLAPSE ));
00192   }
00193 
00194 
00195   void  postprocess_collapse(const CollapseInfo& _ci) {
00196     // account for changed normals
00197     typename Mesh::VertexFaceIter vf_it(mesh_, _ci.v1);
00198     for (; vf_it; ++vf_it)
00199       mesh_.property(normal_cones_, vf_it).
00200       merge(NormalCone(mesh_.normal(vf_it)));
00201 
00202 
00203     // normal cones of deleted triangles
00204     typename Mesh::FaceHandle fh;
00205 
00206     if (_ci.vlv1.is_valid()) {
00207       fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(_ci.vlv1));
00208       if (fh.is_valid())
00209         mesh_.property(normal_cones_, fh).
00210         merge(mesh_.property(normal_cones_, _ci.fl));
00211     }
00212 
00213     if (_ci.v1vr.is_valid()) {
00214       fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(_ci.v1vr));
00215       if (fh.is_valid())
00216         mesh_.property(normal_cones_, fh).
00217         merge(mesh_.property(normal_cones_, _ci.fr));
00218     }
00219   }
00220 
00221 
00222 
00223 private:
00224 
00225   Mesh&                               mesh_;
00226   Scalar                              normal_deviation_;
00227   OpenMesh::FPropHandleT<NormalCone>  normal_cones_;
00228 };
00229 
00230 
00231 //=============================================================================
00232 } // END_NS_DECIMATER
00233 } // END_NS_OPENMESH
00234 //=============================================================================
00235 #endif // OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH defined
00236 //=============================================================================
00237 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines