Documentation for decimater modules, updated decimater, more modules

git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@460 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
Jan Möbius
2011-11-16 09:45:08 +00:00
parent bbf5e47a82
commit d4487aaa79
15 changed files with 698 additions and 817 deletions

View File

@@ -64,6 +64,10 @@
#include <OpenMesh/Tools/Utils/getopt.h>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>
#include <OpenMesh/Tools/Decimater/ModAspectRatioT.hh>
#include <OpenMesh/Tools/Decimater/ModEdgeLengthT.hh>
#include <OpenMesh/Tools/Decimater/ModHausdorffT.hh>
#include <OpenMesh/Tools/Decimater/ModNormalDeviationT.hh>
#include <OpenMesh/Tools/Decimater/ModNormalFlippingT.hh>
#include <OpenMesh/Tools/Decimater/ModQuadricT.hh>
#include <OpenMesh/Tools/Decimater/ModProgMeshT.hh>
@@ -116,12 +120,16 @@ struct DecOptions
CmdOption<bool> decorate_name;
CmdOption<float> n_collapses;
CmdOption<float> Q; // Quadrics
CmdOption<float> NF; // Normal Flipping
CmdOption<bool> IS; // Independent Sets
CmdOption<std::string> PM; // Progressive Mesh
CmdOption<float> R; // Roundness
CmdOption<float> AR; // Aspect ratio
CmdOption<float> EL; // Edge length
CmdOption<float> HD; // Hausdorff distance
CmdOption<bool> IS; // Independent Sets
CmdOption<float> ND; // Normal deviation
CmdOption<float> NF; // Normal flipping
CmdOption<std::string> PM; // Progressive Mesh
CmdOption<float> Q; // Quadrics
CmdOption<float> R; // Roundness
template <typename T>
bool init( CmdOption<T>& _o, const std::string& _val )
@@ -160,15 +168,18 @@ struct DecOptions
strip(name);
strip(value);
if (name == "Q") return init(Q, value);
if (name == "AR") return init(AR, value);
if (name == "EL") return init(EL, value);
if (name == "HD") return init(HD, value);
if (name == "IS") return init(IS, value);
if (name == "ND") return init(ND, value);
if (name == "NF") return init(NF, value);
if (name == "PM") return init(PM, value);
if (name == "IS") return init(IS, value);
if (name == "Q") return init(Q, value);
if (name == "R") return init(R, value);
return false;
}
std::string& strip(std::string & line)
{
std::string::size_type pos = 0;
@@ -238,11 +249,69 @@ decimate(const std::string &_ifname,
// ---- 1 - create decimater instance
Decimater decimater( mesh );
// ---- 2 - registrate modules
// ---- 2 - register modules
if (gverbose)
clog << " registrate modules" << endl;
clog << " register modules" << endl;
typename OpenMesh::Decimater::ModAspectRatioT<Decimater>::Handle modAR;
if (_opt.AR.is_enabled())
{
decimater.add(modAR);
if (_opt.AR.has_value())
decimater.module( modAR ).set_aspect_ratio( _opt.AR ) ;
}
typename OpenMesh::Decimater::ModEdgeLengthT<Decimater>::Handle modEL;
if (_opt.EL.is_enabled())
{
decimater.add(modEL);
if (_opt.EL.has_value())
decimater.module( modEL ).set_edge_length( _opt.EL ) ;
}
typename OpenMesh::Decimater::ModHausdorffT <Decimater>::Handle modHD;
if (_opt.HD.is_enabled())
{
decimater.add(modHD);
if (_opt.HD.has_value())
decimater.module( modHD ).set_tolerance( _opt.HD ) ;
}
typename OpenMesh::Decimater::ModIndependentSetsT<Decimater>::Handle modIS;
if ( _opt.IS.is_enabled() )
decimater.add(modIS);
typename OpenMesh::Decimater::ModNormalDeviationT<Decimater>::Handle modND;
if (_opt.ND.is_enabled())
{
decimater.add(modND);
if (_opt.ND.has_value())
decimater.module( modND ).set_normal_deviation( _opt.ND );
}
typename OpenMesh::Decimater::ModNormalFlippingT<Decimater>::Handle modNF;
if (_opt.NF.is_enabled())
{
decimater.add(modNF);
if (_opt.NF.has_value())
decimater.module( modNF ).set_max_normal_deviation( _opt.NF );
}
typename OpenMesh::Decimater::ModProgMeshT<Decimater>::Handle modPM;
if ( _opt.PM.is_enabled() )
decimater.add(modPM);
typename OpenMesh::Decimater::ModQuadricT<Decimater>::Handle modQ;
if (_opt.Q.is_enabled())
@@ -252,27 +321,6 @@ decimate(const std::string &_ifname,
decimater.module( modQ ).set_max_err( _opt.Q );
}
typename OpenMesh::Decimater::ModNormalFlippingT<Decimater>::Handle modNF;
if (_opt.NF.is_enabled())
{
decimater.add(modNF);
if (_opt.NF.has_value())
decimater.module( modNF ).set_normal_deviation( _opt.NF );
}
typename OpenMesh::Decimater::ModProgMeshT<Decimater>::Handle modPM;
if ( _opt.PM.is_enabled() )
decimater.add(modPM);
typename OpenMesh::Decimater::ModIndependentSetsT<Decimater>::Handle modIS;
if ( _opt.IS.is_enabled() )
decimater.add(modIS);
typename OpenMesh::Decimater::ModRoundnessT<Decimater>::Handle modR;
if ( _opt.R.is_enabled() )
@@ -475,26 +523,25 @@ void usage_and_exit(int xcode)
}
std::cerr << std::endl;
if (xcode)
{
if (xcode) {
std::cerr << "Error " << xcode << ": " << errmsg << std::endl << std::endl;
}
std::cerr << "Usage: decimator [Options] -i input-file -o output-file\n"
<< " Decimating a mesh using quadrics and normal flipping.\n"
<< std::endl;
std::cerr << "Options\n"
<< std::endl;
<< " Decimating a mesh using quadrics and normal flipping.\n" << std::endl;
std::cerr << "Options\n" << std::endl;
std::cerr << " -M \"{Module-Name}[:Value]}\"\n"
<< " Use named module with eventually given parameterization\n"
<< std::endl;
<< " Use named module with eventually given parameterization\n" << std::endl;
std::cerr << " -n <N>\n"
<< " N >= 1: do N halfedge collapses.\n"
<< " N <=-1: decimate down to |N| vertices.\n"
<< " 0 < N < 1: decimate down to N%.\n"
<< std::endl;
<< " 0 < N < 1: decimate down to N%.\n" << std::endl;
std::cerr << std::endl;
std::cerr << "Modules:\n\n";
std::cerr << " AR[:ratio] - ModAspectRatio\n";
std::cerr << " EL[:legth] - ModEdgeLength\n";
std::cerr << " HD[:distance] - ModHausdorff\n";
std::cerr << " IS - ModIndependentSets\n";
std::cerr << " ND[:angle] - ModNormalDeviation\n";
std::cerr << " NF[:angle] - ModNormalFlipping\n";
std::cerr << " PM[:file name] - ModProgMesh\n";
std::cerr << " Q[:error] - ModQuadric\n";

View File

@@ -30,14 +30,14 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
\*===========================================================================*/
/** \file CollapseInfoT.hh
Provides data class CollapseInfoT for storing all information
@@ -49,20 +49,16 @@
// STRUCT CollpaseInfoT
//
//=============================================================================
#ifndef OPENMESH_DECIMATER_COLLAPSEINFOT_HH
#define OPENMESH_DECIMATER_COLLAPSEINFOT_HH
//== INCLUDES =================================================================
//== NAMESPACE ================================================================
namespace OpenMesh {
namespace Decimater {
//== CLASS DEFINITION =========================================================
/** Stores information about a halfedge collapse.
@@ -73,10 +69,9 @@ namespace Decimater {
\image html collapse_info.png
\see ModProgMeshT::Info
*/
template <class Mesh>
struct CollapseInfoT
{
public:
template<class Mesh>
struct CollapseInfoT {
public:
/** Initializing constructor.
*
* Given a mesh and a halfedge handle of the halfedge to be collapsed
@@ -108,49 +103,38 @@ public:
//@}
};
//-----------------------------------------------------------------------------
// CollapseInfoT::CollapseInfoT( _mesh, _heh )
//
// Local configuration of halfedge collapse to be stored in CollapseInfoT:
/*
vl
*
/ \
/ \
/ fl \
v0 *------>* v1
\ fr /
\ /
\ /
*
vr
/**
* Local configuration of halfedge collapse to be stored in CollapseInfoT:
*
* vl
* *
* / \
* / \
* / fl \
* v0 *------>* v1
* \ fr /
* \ /
* \ /
* *
* vr
*
*
* @param _mesh Reference to mesh
* @param _heh The halfedge (v0 -> v1) defining the collapse
*/
// Parameters:
// _mesh Reference to mesh
// _heh The halfedge (v0 -> v1) defining the collapse
//
template <class Mesh>
inline
CollapseInfoT<Mesh>::
CollapseInfoT(Mesh& _mesh, typename Mesh::HalfedgeHandle _heh) :
mesh(_mesh),
v0v1(_heh),
v1v0(_mesh.opposite_halfedge_handle(v0v1)),
v0(_mesh.to_vertex_handle(v1v0)),
v1(_mesh.to_vertex_handle(v0v1)),
p0(_mesh.point(v0)),
p1(_mesh.point(v1)),
fl(_mesh.face_handle(v0v1)),
fr(_mesh.face_handle(v1v0))
template<class Mesh>
inline CollapseInfoT<Mesh>::CollapseInfoT(Mesh& _mesh,
typename Mesh::HalfedgeHandle _heh) :
mesh(_mesh), v0v1(_heh), v1v0(_mesh.opposite_halfedge_handle(v0v1)), v0(
_mesh.to_vertex_handle(v1v0)), v1(_mesh.to_vertex_handle(v0v1)), p0(
_mesh.point(v0)), p1(_mesh.point(v1)), fl(_mesh.face_handle(v0v1)), fr(
_mesh.face_handle(v1v0))
{
// get vl
if (fl.is_valid())
{
if (fl.is_valid()) {
vlv1 = mesh.next_halfedge_handle(v0v1);
v0vl = mesh.next_halfedge_handle(vlv1);
vl = mesh.to_vertex_handle(vlv1);
@@ -158,10 +142,8 @@ CollapseInfoT(Mesh& _mesh, typename Mesh::HalfedgeHandle _heh) :
v0vl = mesh.opposite_halfedge_handle(v0vl);
}
// get vr
if (fr.is_valid())
{
if (fr.is_valid()) {
vrv0 = mesh.next_halfedge_handle(v1v0);
v1vr = mesh.next_halfedge_handle(vrv0);
vr = mesh.to_vertex_handle(vrv0);
@@ -171,7 +153,7 @@ CollapseInfoT(Mesh& _mesh, typename Mesh::HalfedgeHandle _heh) :
}
//=============================================================================
} // END_NS_DECIMATER
}// END_NS_DECIMATER
} // END_NS_OPENMESH
//=============================================================================
#endif // OPENMESH_DECIMATER_COLLAPSEINFOT_HH defined

View File

@@ -30,28 +30,25 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
\*===========================================================================*/
/** \file DecimaterT.cc
*/
//=============================================================================
//
// CLASS DecimaterT - IMPLEMENTATION
//
//=============================================================================
#define OPENMESH_DECIMATER_DECIMATERT_CC
//== INCLUDES =================================================================
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>
@@ -63,26 +60,16 @@
# include <cfloat>
#endif
//== NAMESPACE ===============================================================
namespace OpenMesh {
namespace Decimater {
//== IMPLEMENTATION ==========================================================
template <class Mesh>
DecimaterT<Mesh>::
DecimaterT( Mesh& _mesh )
: mesh_(_mesh),
heap_(NULL),
cmodule_(NULL),
initialized_(false)
{
template<class Mesh>
DecimaterT<Mesh>::DecimaterT(Mesh& _mesh) :
mesh_(_mesh), heap_(NULL), cmodule_(NULL), initialized_(false) {
// default properties
mesh_.request_vertex_status();
mesh_.request_edge_status();
@@ -90,19 +77,15 @@ DecimaterT( Mesh& _mesh )
mesh_.request_face_normals();
// private vertex properties
mesh_.add_property( collapse_target_ );
mesh_.add_property( priority_ );
mesh_.add_property( heap_position_ );
mesh_.add_property(collapse_target_);
mesh_.add_property(priority_);
mesh_.add_property(heap_position_);
}
//-----------------------------------------------------------------------------
template <class Mesh>
DecimaterT<Mesh>::
~DecimaterT()
{
template<class Mesh>
DecimaterT<Mesh>::~DecimaterT() {
// default properties
mesh_.release_vertex_status();
mesh_.release_edge_status();
@@ -118,40 +101,33 @@ DecimaterT<Mesh>::
{
set_uninitialized();
typename ModuleList::iterator m_it, m_end = all_modules_.end();
for( m_it=all_modules_.begin(); m_it!=m_end; ++m_it)
for (m_it = all_modules_.begin(); m_it != m_end; ++m_it)
delete *m_it;
all_modules_.clear();
}
}
//-----------------------------------------------------------------------------
template <class Mesh>
void
DecimaterT<Mesh>::
info( std::ostream& _os )
{
if(initialized_)
{
template<class Mesh>
void DecimaterT<Mesh>::info(std::ostream& _os) {
if (initialized_) {
_os << "initialized : yes" << std::endl;
_os << "binary modules: " << bmodules_.size() << std::endl;
for( ModuleListIterator m_it=bmodules_.begin(); m_it!=bmodules_.end(); ++m_it)
{
for (ModuleListIterator m_it = bmodules_.begin(); m_it != bmodules_.end();
++m_it) {
_os << " " << (*m_it)->name() << std::endl;
}
_os << "priority module: " << cmodule_->name().c_str() << std::endl;
}
else {
} else {
_os << "initialized : no" << std::endl;
_os << "available modules: " << all_modules_.size() << std::endl;
for( ModuleListIterator m_it=all_modules_.begin(); m_it!=all_modules_.end(); ++m_it)
{
for (ModuleListIterator m_it = all_modules_.begin();
m_it != all_modules_.end(); ++m_it) {
_os << " " << (*m_it)->name() << " : ";
if((*m_it)->is_binary()) {
if ((*m_it)->is_binary()) {
_os << "binary";
if((*m_it)->name() == "Quadric") {
if ((*m_it)->name() == "Quadric") {
_os << " and priority (special treatment)";
}
} else {
@@ -162,17 +138,11 @@ info( std::ostream& _os )
}
}
//-----------------------------------------------------------------------------
template <class Mesh>
bool
DecimaterT<Mesh>::
initialize()
{
if(initialized_)
{
template<class Mesh>
bool DecimaterT<Mesh>::initialize() {
if (initialized_) {
return true;
}
@@ -187,17 +157,15 @@ initialize()
// priority module explicitly.
// find the priority module: either the only non-binary module in the list, or "Quadric"
Module *quadric=NULL;
Module *pmodule=NULL;
for (ModuleListIterator m_it=all_modules_.begin(), m_end=all_modules_.end(); m_it != m_end; ++m_it)
{
if ( (*m_it)->name() == "Quadric")
Module *quadric = NULL;
Module *pmodule = NULL;
for (ModuleListIterator m_it = all_modules_.begin(), m_end =
all_modules_.end(); m_it != m_end; ++m_it) {
if ((*m_it)->name() == "Quadric")
quadric = *m_it;
if ( !(*m_it)->is_binary() )
{
if(pmodule)
{
if (!(*m_it)->is_binary()) {
if (pmodule) {
// only one priority module allowed!
set_uninitialized();
return false;
@@ -207,11 +175,11 @@ initialize()
}
// Quadric is used as default priority module (even if it is set to be binary)
if(!pmodule && quadric) {
if (!pmodule && quadric) {
pmodule = quadric;
}
if(!pmodule) {
if (!pmodule) {
// At least one priority module required
set_uninitialized();
return false;
@@ -220,12 +188,12 @@ initialize()
// set pmodule as the current priority module
cmodule_ = pmodule;
for(ModuleListIterator m_it=all_modules_.begin(), m_end=all_modules_.end(); m_it != m_end; ++m_it)
{
for (ModuleListIterator m_it = all_modules_.begin(), m_end =
all_modules_.end(); m_it != m_end; ++m_it) {
// every module gets initialized
(*m_it)->initialize();
if(*m_it != pmodule) {
if (*m_it != pmodule) {
// all other modules are binary, and go into bmodules_ list
bmodules_.push_back(*m_it);
}
@@ -234,39 +202,32 @@ initialize()
return initialized_ = true;
}
//-----------------------------------------------------------------------------
template <class Mesh>
bool
DecimaterT<Mesh>::is_collapse_legal(const CollapseInfo& _ci)
{
template<class Mesh>
bool DecimaterT<Mesh>::is_collapse_legal(const CollapseInfo& _ci) {
// std::clog << "DecimaterT<>::is_collapse_legal()\n";
// locked ? deleted ?
if (mesh_.status(_ci.v0).locked() ||
mesh_.status(_ci.v0).deleted())
if (mesh_.status(_ci.v0).locked() || mesh_.status(_ci.v0).deleted())
return false;
/*
/*
if (!mesh_.is_collapse_ok(_ci.v0v1))
{
return false;
}
*/
if (_ci.vl.is_valid() && _ci.vr.is_valid() &&
mesh_.find_halfedge(_ci.vl, _ci.vr).is_valid() &&
mesh_.valence(_ci.vl) == 3 && mesh_.valence(_ci.vr) == 3)
{
*/
if (_ci.vl.is_valid() && _ci.vr.is_valid()
&& mesh_.find_halfedge(_ci.vl, _ci.vr).is_valid()
&& mesh_.valence(_ci.vl) == 3 && mesh_.valence(_ci.vr) == 3) {
return false;
}
//--- feature test ---
if (mesh_.status(_ci.v0).feature() &&
!mesh_.status(mesh_.edge_handle(_ci.v0v1)).feature())
if (mesh_.status(_ci.v0).feature()
&& !mesh_.status(mesh_.edge_handle(_ci.v0v1)).feature())
return false;
//--- test one ring intersection ---
typename Mesh::VertexVertexIter vv_it;
@@ -278,24 +239,19 @@ DecimaterT<Mesh>::is_collapse_legal(const CollapseInfo& _ci)
mesh_.status(vv_it).set_tagged(true);
for (vv_it = mesh_.vv_iter(_ci.v0); vv_it; ++vv_it)
if (mesh_.status(vv_it).tagged() &&
vv_it.handle() != _ci.vl &&
vv_it.handle() != _ci.vr)
if (mesh_.status(vv_it).tagged() && vv_it.handle() != _ci.vl
&& vv_it.handle() != _ci.vr)
return false;
// if both are invalid OR equal -> fail
if (_ci.vl == _ci.vr) return false;
if (_ci.vl == _ci.vr)
return false;
//--- test boundary cases ---
if (mesh_.is_boundary(_ci.v0))
{
if (!mesh_.is_boundary(_ci.v1))
{// don't collapse a boundary vertex to an inner one
if (mesh_.is_boundary(_ci.v0)) {
if (!mesh_.is_boundary(_ci.v1)) { // don't collapse a boundary vertex to an inner one
return false;
}
else
{// edge between two boundary vertices has to be a boundary edge
} else { // edge between two boundary vertices has to be a boundary edge
if (!(mesh_.is_boundary(_ci.v0v1) || mesh_.is_boundary(_ci.v1v0)))
return false;
}
@@ -305,15 +261,13 @@ DecimaterT<Mesh>::is_collapse_legal(const CollapseInfo& _ci)
}
// v0vl and v1vl must not both be boundary edges
if (_ci.vl.is_valid() &&
mesh_.is_boundary(_ci.vlv1) &&
mesh_.is_boundary(_ci.v0vl))
if (_ci.vl.is_valid() && mesh_.is_boundary(_ci.vlv1)
&& mesh_.is_boundary(_ci.v0vl))
return false;
// v0vr and v1vr must not be both boundary edges
if (_ci.vr.is_valid() &&
mesh_.is_boundary(_ci.vrv0) &&
mesh_.is_boundary(_ci.v1vr))
if (_ci.vr.is_valid() && mesh_.is_boundary(_ci.vrv0)
&& mesh_.is_boundary(_ci.v1vr))
return false;
// there have to be at least 2 incident faces at v0
@@ -321,55 +275,41 @@ DecimaterT<Mesh>::is_collapse_legal(const CollapseInfo& _ci)
mesh_.cw_rotated_halfedge_handle(_ci.v0v1)) == _ci.v0v1)
return false;
// collapse passed all tests -> ok
return true;
}
//-----------------------------------------------------------------------------
template <class Mesh>
float
DecimaterT<Mesh>::collapse_priority(const CollapseInfo& _ci)
{
template<class Mesh>
float DecimaterT<Mesh>::collapse_priority(const CollapseInfo& _ci) {
typename ModuleList::iterator m_it, m_end = bmodules_.end();
for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
{
if ( (*m_it)->collapse_priority(_ci) < 0.0)
for (m_it = bmodules_.begin(); m_it != m_end; ++m_it) {
if ((*m_it)->collapse_priority(_ci) < 0.0)
return ModBaseT<DecimaterT<Mesh> >::ILLEGAL_COLLAPSE;
}
return cmodule_->collapse_priority(_ci);
}
//-----------------------------------------------------------------------------
template <class Mesh>
void
DecimaterT<Mesh>::heap_vertex(VertexHandle _vh)
{
template<class Mesh>
void DecimaterT<Mesh>::heap_vertex(VertexHandle _vh) {
// std::clog << "heap_vertex: " << _vh << std::endl;
float prio, best_prio(FLT_MAX);
typename Mesh::HalfedgeHandle heh, collapse_target;
// find best target in one ring
typename Mesh::VertexOHalfedgeIter voh_it(mesh_, _vh);
for (; voh_it; ++voh_it)
{
for (; voh_it; ++voh_it) {
heh = voh_it.handle();
CollapseInfo ci(mesh_, heh);
if (is_collapse_legal(ci))
{
if (is_collapse_legal(ci)) {
prio = collapse_priority(ci);
if (prio >= 0.0 && prio < best_prio)
{
if (prio >= 0.0 && prio < best_prio) {
best_prio = prio;
collapse_target = heh;
}
@@ -377,36 +317,32 @@ DecimaterT<Mesh>::heap_vertex(VertexHandle _vh)
}
// target found -> put vertex on heap
if (collapse_target.is_valid())
{
if (collapse_target.is_valid()) {
// std::clog << " added|updated" << std::endl;
mesh_.property(collapse_target_, _vh) = collapse_target;
mesh_.property(priority_, _vh) = best_prio;
if (heap_->is_stored(_vh)) heap_->update(_vh);
else heap_->insert(_vh);
if (heap_->is_stored(_vh))
heap_->update(_vh);
else
heap_->insert(_vh);
}
// not valid -> remove from heap
else
{
else {
// std::clog << " n/a|removed" << std::endl;
if (heap_->is_stored(_vh)) heap_->remove(_vh);
if (heap_->is_stored(_vh))
heap_->remove(_vh);
mesh_.property(collapse_target_, _vh) = collapse_target;
mesh_.property(priority_, _vh) = -1;
}
}
//-----------------------------------------------------------------------------
template <class Mesh>
void
DecimaterT<Mesh>::
postprocess_collapse(CollapseInfo& _ci)
{
template<class Mesh>
void DecimaterT<Mesh>::postprocess_collapse(CollapseInfo& _ci) {
typename ModuleList::iterator m_it, m_end = bmodules_.end();
for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
@@ -415,15 +351,10 @@ postprocess_collapse(CollapseInfo& _ci)
cmodule_->postprocess_collapse(_ci);
}
//-----------------------------------------------------------------------------
template <class Mesh>
void
DecimaterT<Mesh>::
preprocess_collapse(CollapseInfo& _ci)
{
template<class Mesh>
void DecimaterT<Mesh>::preprocess_collapse(CollapseInfo& _ci) {
typename ModuleList::iterator m_it, m_end = bmodules_.end();
for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
@@ -432,13 +363,10 @@ preprocess_collapse(CollapseInfo& _ci)
cmodule_->preprocess_collapse(_ci);
}
//-----------------------------------------------------------------------------
template <class Mesh>
size_t
DecimaterT<Mesh>::decimate( size_t _n_collapses )
{
if ( !is_initialized() )
template<class Mesh>
size_t DecimaterT<Mesh>::decimate(size_t _n_collapses) {
if (!is_initialized())
return 0;
typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end());
@@ -454,94 +382,73 @@ DecimaterT<Mesh>::decimate( size_t _n_collapses )
Support support(15);
SupportIterator s_it, s_end;
// check _n_collapses
if (!_n_collapses) _n_collapses = mesh_.n_vertices();
if (!_n_collapses)
_n_collapses = mesh_.n_vertices();
// initialize heap
HeapInterface HI(mesh_, priority_, heap_position_);
heap_ = std::auto_ptr<DeciHeap>(new DeciHeap(HI));
heap_->reserve(mesh_.n_vertices());
for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it)
{
heap_->reset_heap_position( v_it.handle() );
for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) {
heap_->reset_heap_position(v_it.handle());
if (!mesh_.status(v_it).deleted())
heap_vertex( v_it.handle() );
heap_vertex(v_it.handle());
}
// process heap
while ((!heap_->empty()) && (n_collapses < _n_collapses))
{
while ((!heap_->empty()) && (n_collapses < _n_collapses)) {
// get 1st heap entry
vp = heap_->front();
v0v1 = mesh_.property(collapse_target_, vp);
heap_->pop_front();
// setup collapse info
CollapseInfo ci(mesh_, v0v1);
// check topological correctness AGAIN !
if (!is_collapse_legal(ci))
continue;
// store support (= one ring of *vp)
vv_it = mesh_.vv_iter(ci.v0);
support.clear();
for (; vv_it; ++vv_it)
support.push_back(vv_it.handle());
// perform collapse
mesh_.collapse(v0v1);
++n_collapses;
// update triangle normals
vf_it = mesh_.vf_iter(ci.v1);
for (; vf_it; ++vf_it)
if (!mesh_.status(vf_it).deleted())
mesh_.set_normal(vf_it, mesh_.calc_face_normal(vf_it.handle()));
// post-process collapse
postprocess_collapse(ci);
// update heap (former one ring of decimated vertex)
for (s_it = support.begin(), s_end = support.end();
s_it != s_end; ++s_it)
{
for (s_it = support.begin(), s_end = support.end(); s_it != s_end; ++s_it) {
assert(!mesh_.status(*s_it).deleted());
heap_vertex(*s_it);
}
}
// delete heap
heap_.reset();
// DON'T do garbage collection here! It's up to the application.
return n_collapses;
}
//-----------------------------------------------------------------------------
template <class Mesh>
size_t
DecimaterT<Mesh>::
decimate_to_faces( size_t _nv, size_t _nf )
{
if ( !is_initialized() )
template<class Mesh>
size_t DecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf) {
if (!is_initialized())
return 0;
if (_nv >= mesh_.n_vertices() || _nf >= mesh_.n_faces())
@@ -562,97 +469,76 @@ decimate_to_faces( size_t _nv, size_t _nf )
Support support(15);
SupportIterator s_it, s_end;
// initialize heap
HeapInterface HI(mesh_, priority_, heap_position_);
heap_ = std::auto_ptr<DeciHeap>(new DeciHeap(HI));
heap_->reserve(mesh_.n_vertices());
for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it)
{
heap_->reset_heap_position( v_it.handle() );
for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) {
heap_->reset_heap_position(v_it.handle());
if (!mesh_.status(v_it).deleted())
heap_vertex( v_it.handle() );
heap_vertex(v_it.handle());
}
// process heap
while ((!heap_->empty()) && (_nv < nv) && (_nf < nf))
{
while ((!heap_->empty()) && (_nv < nv) && (_nf < nf)) {
// get 1st heap entry
vp = heap_->front();
v0v1 = mesh_.property(collapse_target_, vp);
heap_->pop_front();
// setup collapse info
CollapseInfo ci(mesh_, v0v1);
// check topological correctness AGAIN !
if (!is_collapse_legal(ci))
continue;
// store support (= one ring of *vp)
vv_it = mesh_.vv_iter(ci.v0);
support.clear();
for (; vv_it; ++vv_it)
support.push_back(vv_it.handle());
// adjust complexity in advance (need boundary status)
++n_collapses;
--nv;
if (mesh_.is_boundary(ci.v0v1) ||
mesh_.is_boundary(ci.v1v0))
if (mesh_.is_boundary(ci.v0v1) || mesh_.is_boundary(ci.v1v0))
--nf;
else nf -= 2;
else
nf -= 2;
// pre-processing
preprocess_collapse(ci);
// perform collapse
mesh_.collapse(v0v1);
// update triangle normals
vf_it = mesh_.vf_iter(ci.v1);
for (; vf_it; ++vf_it)
if (!mesh_.status(vf_it).deleted())
mesh_.set_normal(vf_it, mesh_.calc_face_normal(vf_it.handle()));
// post-process collapse
postprocess_collapse(ci);
// update heap (former one ring of decimated vertex)
for (s_it = support.begin(), s_end = support.end();
s_it != s_end; ++s_it)
{
for (s_it = support.begin(), s_end = support.end(); s_it != s_end; ++s_it) {
assert(!mesh_.status(*s_it).deleted());
heap_vertex(*s_it);
}
}
// delete heap
heap_.reset();
// DON'T do garbage collection here! It's up to the application.
return n_collapses;
}
//=============================================================================
} // END_NS_DECIMATER
}// END_NS_DECIMATER
} // END_NS_OPENMESH
//=============================================================================

View File

@@ -30,59 +30,49 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 448 $ *
* $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ *
* *
\*===========================================================================*/
\*===========================================================================*/
/** \file ModAspectRatioT.cc
*/
//=============================================================================
//
// CLASS ModAspectRatioT - IMPLEMENTATION
//
//=============================================================================
#define MB_MODASPECTRATIOT_C
#define OPENMESH_DECIMATER_MODASPECTRATIOT_C
//== INCLUDES =================================================================
#include "ModAspectRatioT.hh"
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace Decimater {
//== IMPLEMENTATION ==========================================================
template <class DecimaterT>
typename ModAspectRatioT<DecimaterT>::Scalar
ModAspectRatioT<DecimaterT>::
aspectRatio( const Point& _v0,
const Point& _v1,
const Point& _v2 )
{
template<class DecimaterT>
typename ModAspectRatioT<DecimaterT>::Scalar ModAspectRatioT<DecimaterT>::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)
if ((l2 = d1.sqrnorm()) > maxl2)
maxl2 = l2;
// keep searching for the max squared edge length
d1 = _v2 - _v0;
if ((l2=d1.sqrnorm()) > maxl2)
if ((l2 = d1.sqrnorm()) > maxl2)
maxl2 = l2;
// squared area of the parallelogram spanned by d0 and d1
@@ -96,68 +86,48 @@ aspectRatio( const Point& _v0,
// returns the length of the longest edge
// divided by its corresponding height
return sqrt( (maxl2 * maxl2) / a2 );
return sqrt((maxl2 * maxl2) / a2);
}
//-----------------------------------------------------------------------------
template <class DecimaterT>
void
ModAspectRatioT<DecimaterT>::
initialize()
{
template<class DecimaterT>
void ModAspectRatioT<DecimaterT>::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));
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);
mesh_.property(aspect_, f_it) = 1.0 / aspectRatio(p0, p1, p2);
}
}
//-----------------------------------------------------------------------------
template <class DecimaterT>
void
ModAspectRatioT<DecimaterT>::
preprocess_collapse(const CollapseInfo& _ci)
{
template<class DecimaterT>
void ModAspectRatioT<DecimaterT>::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)
{
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));
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);
mesh_.property(aspect_, fh) = 1.0 / aspectRatio(p0, p1, p2);
}
}
}
//-----------------------------------------------------------------------------
template <class DecimaterT>
float
ModAspectRatioT<DecimaterT>::
collapse_priority(const CollapseInfo& _ci)
{
template<class DecimaterT>
float ModAspectRatioT<DecimaterT>::collapse_priority(const CollapseInfo& _ci) {
typename Mesh::VertexHandle v2, v3;
typename Mesh::FaceHandle fh;
const typename Mesh::Point *p1(&_ci.p1), *p2, *p3;
@@ -167,8 +137,7 @@ collapse_priority(const CollapseInfo& _ci)
v3 = vv_it.handle();
p3 = &mesh_.point(v3);
while (vv_it)
{
while (vv_it) {
v2 = v3;
p2 = p3;
@@ -178,34 +147,32 @@ collapse_priority(const CollapseInfo& _ci)
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)
if (fh.is_valid()) {
// aspect before
if ((r0 = mesh_.property(aspect_, fh)) < r0_min)
r0_min = r0;
// roundness after
// aspect after
if (!(v2 == _ci.v1 || v3 == _ci.v1))
if ((r1 = 1.0/aspectRatio(*p1, *p2, *p3)) < r1_min)
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_aspect_)) ? Base::LEGAL_COLLAPSE :
Base::ILLEGAL_COLLAPSE;
if (Base::is_binary())
{
return ((r1_min > r0_min) || (r1_min > min_roundness_)) ? 0.0 : -1.0;
}
else
{
} else {
if (r1_min > r0_min)
return 1.0 - r1_min;
else
return (r1_min > min_roundness_) ? 2.0 - r1_min : -1.0;
return
(r1_min > min_aspect_) ? 2.0 - r1_min : float(Base::ILLEGAL_COLLAPSE);
}
}
//=============================================================================
}
}

View File

@@ -30,114 +30,117 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* $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
#ifndef OPENMESH_DECIMATER_MODASPECTRATIOT_HH
#define OPENMESH_DECIMATER_MODASPECTRATIOT_HH
//== INCLUDES =================================================================
#include <OpenMesh/Tools/Decimater/ModBaseT.hh>
#include <OpenMesh/Core/Utils/Property.hh>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace Decimater {
//== CLASS DEFINITION =========================================================
/** \brief Use aspect ratio to control decimation
*
* This module computes the aspect ratio.
*
* In binary mode, the collapse is legal if:
* - The aspect ratio after the collapse is greater
* - The aspect ratio after the collapse is greater than the given minimum
*
* In continuous mode the collapse is illegal if:
* - The aspect ratio after the collapse is smaller than the given minimum
*
*
*/
template<class DecimaterT>
class ModAspectRatioT: public ModBaseT<DecimaterT> {
public:
template <class DecimaterT>
class ModAspectRatioT : public ModBaseT<DecimaterT>
{
public:
DECIMATING_MODULE( ModAspectRatioT, DecimaterT, Roundness );
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_ );
/// constructor
ModAspectRatioT(DecimaterT& _dec, float _min_aspect = 5.0, bool _is_binary =
true) :
Base(_dec, _is_binary), mesh_(Base::mesh()), min_aspect_(
1.0 / _min_aspect) {
mesh_.add_property(aspect_);
}
// destructor
~ModAspectRatioT()
{
mesh_.remove_property( roundness_ );
/// destructor
~ModAspectRatioT() {
mesh_.remove_property(aspect_);
}
/// get aspect ratio
float aspect_ratio() const {
return 1.0 / min_aspect_;
}
/// set aspect ratio
void set_aspect_ratio(float _f) {
min_aspect_ = 1.0 / _f;
}
/// 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
/// precompute face aspect ratio
void initialize();
// blabla
/// Returns the collapse priority
float collapse_priority(const CollapseInfo& _ci);
// update roundness of one-ring
/// update aspect ratio of one-ring
void preprocess_collapse(const CollapseInfo& _ci);
private:
private:
/** \brief return aspect ratio (length/height) of triangle
*
*/
Scalar aspectRatio( const Point& _v0,
const Point& _v1,
const Point& _v2 );
Scalar aspectRatio(const Point& _v0, const Point& _v1, const Point& _v2);
private:
private:
Mesh& mesh_;
float min_roundness_;
FPropHandleT<float> roundness_;
float min_aspect_;
FPropHandleT<float> aspect_;
};
//=============================================================================
} // END_NS_DECIMATER
}// END_NS_DECIMATER
} // END_NS_OPENMESH
//=============================================================================
#if defined(INCLUDE_TEMPLATES) && !defined(MB_MODASPECTRATIOT_C)
#define MODASPECTRATIOT_TEMPLATES
#if defined(INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODASPECTRATIOT_C)
#define OPENMESH_DECIMATER_MODASPECTRATIOT_TEMPLATES
#include "ModAspectRatioT.cc"
#endif
//=============================================================================
#endif // MB_MODASPECTRATIOT_HH defined
#endif // OPENMESH_DECIMATER_MODASPECTRATIOT_HH defined
//=============================================================================

View File

@@ -30,68 +30,52 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 448 $ *
* $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ *
* *
\*===========================================================================*/
\*===========================================================================*/
/** \file ModEdgeLengthT.cc
*/
//=============================================================================
//
// CLASS ModEdgeLengthT - IMPLEMENTATION
//
//=============================================================================
#define MODEDGELENGTHT_C
#define OPENMESH_DECIMATER_MODEDGELENGTHT_C
//== INCLUDES =================================================================
#include "ModEdgeLengthT.hh"
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace Decimater {
//== IMPLEMENTATION ==========================================================
template <class DecimaterT>
ModEdgeLengthT<DecimaterT>::
ModEdgeLengthT(DecimaterT &_dec, float _edge_length, bool _is_binary)
: Base(_dec, _is_binary),
mesh_(Base::mesh())
{
template<class DecimaterT>
ModEdgeLengthT<DecimaterT>::ModEdgeLengthT(DecimaterT &_dec, float _edge_length,
bool _is_binary) :
Base(_dec, _is_binary), mesh_(Base::mesh()) {
set_edge_length(_edge_length);
}
//-----------------------------------------------------------------------------
template <class DecimaterT>
float
ModEdgeLengthT<DecimaterT>::
collapse_priority(const CollapseInfo& _ci)
{
template<class DecimaterT>
float ModEdgeLengthT<DecimaterT>::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 ));
return ( (sqr_length <= sqr_edge_length_) ? sqr_length : float(Base::ILLEGAL_COLLAPSE));
}
//=============================================================================
}
}

View File

@@ -30,14 +30,14 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 448 $ *
* $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ *
* *
\*===========================================================================*/
\*===========================================================================*/
/** \file ModEdgeLengthT.hh
*/
@@ -47,47 +47,50 @@
// CLASS ModEdgeLengthT
//
//=============================================================================
#ifndef MODEDGELENGTHT_HH
#define MODEDGELENGTHT_HH
#ifndef OPENMESH_DECIMATER_MODEDGELENGTHT_HH
#define OPENMESH_DECIMATER_MODEDGELENGTHT_HH
//== INCLUDES =================================================================
#include <OpenMesh/Tools/Decimater/ModBaseT.hh>
#include <float.h>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace Decimater {
//== CLASS DEFINITION =========================================================
/** \brief Use edge length to control decimation
*
* This module computes the edge length.
*
* In binary and continuous mode, the collapse is legal if:
* - The length after the collapse is lower than the given tolerance
*
*/
template<class DecimaterT>
class ModEdgeLengthT: public ModBaseT<DecimaterT> {
public:
template <class DecimaterT>
class ModEdgeLengthT : public ModBaseT<DecimaterT>
{
public:
DECIMATING_MODULE( ModEdgeLengthT, DecimaterT, EdgeLength );
DECIMATING_MODULE( ModEdgeLengthT, DecimaterT, EdgeLength )
;
/// Constructor
ModEdgeLengthT(DecimaterT& _dec,
float _edge_length = FLT_MAX,
ModEdgeLengthT(DecimaterT& _dec, float _edge_length = FLT_MAX,
bool _is_binary = true);
/// get edge_length
float edge_length() const { return 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; }
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_
@@ -96,23 +99,21 @@ public:
*/
float collapse_priority(const CollapseInfo& _ci);
private:
private:
Mesh& mesh_;
typename Mesh::Scalar edge_length_, sqr_edge_length_;
};
//=============================================================================
} // END_NS_DECIMATER
}// END_NS_DECIMATER
} // END_NS_OPENMESH
//=============================================================================
#if defined(INCLUDE_TEMPLATES) && !defined(MODEDGELENGTHT_C)
#if defined(INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODEDGELENGTHT_C)
#define MODEDGELENGTHT_TEMPLATES
#include "ModEdgeLengthT.cc"
#endif
//=============================================================================
#endif // MODEDGELENGTHT_HH defined
#endif // OPENMESH_DECIMATER_MODEDGELENGTHT_HH defined
//=============================================================================

View File

@@ -49,7 +49,7 @@
//
//=============================================================================
#define MODHAUSDORFFT_C
#define OPENMESH_DECIMATER_MODHAUSDORFFT_C
//== INCLUDES =================================================================

View File

@@ -30,29 +30,26 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: 448 $ *
* $Date: 2011-11-04 13:59:37 +0100 (Fri, 04 Nov 2011) $ *
* *
\*===========================================================================*/
\*===========================================================================*/
/** \file ModHausdorffT.hh
*/
//=============================================================================
//
// CLASS ModHausdorffT
//
//=============================================================================
#ifndef MODHAUSDORFFT_HH
#define MODHAUSDORFFT_HH
#ifndef OPENMESH_DECIMATER_MODHAUSDORFFT_HH
#define OPENMESH_DECIMATER_MODHAUSDORFFT_HH
//== INCLUDES =================================================================
@@ -61,20 +58,25 @@
#include <vector>
#include <float.h>
//== NAMESPACES ===============================================================
namespace OpenMesh {
namespace Decimater {
//== CLASS DEFINITION =========================================================
template <class DecimaterT>
class ModHausdorffT : public ModBaseT<DecimaterT>
{
public:
/** \brief Use Hausdorff distance to control decimation
*
* This module computes the aspect ratio.
*
* In binary mode, the collapse is legal if:
* - The distance after the collapse is lower than the given tolerance
*
* No continuous mode
*/
template<class DecimaterT>
class ModHausdorffT: public ModBaseT<DecimaterT> {
public:
DECIMATING_MODULE( ModHausdorffT, DecimaterT, Roundness );
@@ -83,60 +85,55 @@ public:
typedef typename Mesh::FaceHandle FaceHandle;
typedef std::vector<Point> Points;
/// Constructor
ModHausdorffT(DecimaterT& _dec,
Scalar _error_tolerance = FLT_MAX)
: Base(_dec, true),
mesh_(Base::mesh()),
tolerance_(_error_tolerance)
{
ModHausdorffT(DecimaterT& _dec, Scalar _error_tolerance = FLT_MAX) :
Base(_dec, true), mesh_(Base::mesh()), tolerance_(_error_tolerance) {
mesh_.add_property(points_);
}
/// Destructor
~ModHausdorffT()
{
~ModHausdorffT() {
mesh_.remove_property(points_);
}
/// get max error tolerance
Scalar tolerance() const { return tolerance_; }
Scalar tolerance() const {
return tolerance_;
}
/// set max error tolerance
void set_tolerance(Scalar _e) { tolerance_ = _e; }
void set_tolerance(Scalar _e) {
tolerance_ = _e;
}
/// reset per-face point lists
virtual void initialize();
/** \brief compute Hausdorff error for one-ring
*
* This mod only allows collapses if the Hausdorff distance
* after a collapse is lower than the given tolerance.
*
*
* @param _ci Collapse info data
* @return Binary return, if collapse is legal or illegal
*/
/// compute Hausdorff error for one-ring
virtual float collapse_priority(const CollapseInfo& _ci);
/// re-distribute points
virtual void postprocess_collapse(const CollapseInfo& _ci);
private:
private:
/// squared distance from point _p to triangle (_v0, _v1, _v2)
Scalar distPointTriangleSquared( const Point& _p,
const Point& _v0,
const Point& _v1,
const Point& _v2,
Point& _nearestPoint );
Scalar distPointTriangleSquared(const Point& _p, const Point& _v0,
const Point& _v1, const Point& _v2, Point& _nearestPoint);
/// 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:
private:
Mesh& mesh_;
Scalar tolerance_;
@@ -144,16 +141,15 @@ private:
OpenMesh::FPropHandleT<Points> points_;
};
//=============================================================================
} // END_NS_DECIMATER
}// END_NS_DECIMATER
} // END_NS_OPENMESH
//=============================================================================
#if defined(INCLUDE_TEMPLATES) && !defined(MODHAUSDORFFT_C)
#define MODHAUSDORFFT_TEMPLATES
#if defined(INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODHAUSDORFFT_C)
#define OPENMESH_DECIMATER_MODHAUSDORFFT_TEMPLATES
#include "ModHausdorffT.cc"
#endif
//=============================================================================
#endif // MODHAUSDORFFT_HH defined
#endif // OPENMESH_DECIMATER_MODHAUSDORFFT_HH defined
//=============================================================================

View File

@@ -30,14 +30,14 @@
* License along with OpenMesh. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
\*===========================================================================*/
/** \file ModQuadricT.hh
@@ -48,41 +48,36 @@
// CLASS ModQuadricT
//
//=============================================================================
#ifndef OPENMESH_TOOLS_MODINDEPENDENTSETST_HH
#define OPENMESH_TOOLS_MODINDEPENDENTSETST_HH
//== INCLUDES =================================================================
#include <OpenMesh/Tools/Decimater/ModBaseT.hh>
//== NAMESPACE ================================================================
namespace OpenMesh { // BEGIN_NS_OPENMESH
namespace Decimater { // BEGIN_NS_DECIMATER
//== CLASS DEFINITION =========================================================
/** Lock one-ring around remaining vertex after a collapse to prevent
* further collapses of halfedges incident to the one-ring vertices.
*/
template <class DecimaterType>
class ModIndependentSetsT : public ModBaseT<DecimaterType>
{
public:
DECIMATING_MODULE( ModIndependentSetsT, DecimaterType, IndependentSets );
template<class DecimaterType>
class ModIndependentSetsT: public ModBaseT<DecimaterType> {
public:
DECIMATING_MODULE( ModIndependentSetsT, DecimaterType, IndependentSets )
;
/// Constructor
ModIndependentSetsT( DecimaterType &_dec ) : Base(_dec, true) {}
ModIndependentSetsT(DecimaterType &_dec) :
Base(_dec, true) {
}
/// override
void postprocess_collapse(const CollapseInfo& _ci)
{
void postprocess_collapse(const CollapseInfo& _ci) {
typename Mesh::VertexVertexIter vv_it;
Base::mesh().status(_ci.v1).set_locked(true);
@@ -91,16 +86,14 @@ public:
Base::mesh().status(vv_it).set_locked(true);
}
private:
private:
/// hide this method
void set_binary(bool _b) {}
void set_binary(bool _b) { }
};
//=============================================================================
} // END_NS_DECIMATER
}// END_NS_DECIMATER
} // END_NS_OPENMESH
//=============================================================================
#endif // OPENMESH_TOOLS_MODINDEPENDENTSETST_HH defined

View File

@@ -49,15 +49,15 @@
//=============================================================================
#ifndef MODNORMALDEVIATIONT_HH
#define MODNORMALDEVIATIONT_HH
#ifndef OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH
#define OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH
//== INCLUDES =================================================================
#include <OpenMesh/Tools/Decimater/ModBaseT.hh>
#include <OpenMesh/Core/Utils/Property.hh>
#include <ACG/Geometry/Types/NormalConeT.hh>
#include <OpenMesh/Core/Geometry/NormalConeT.hh>
//== NAMESPACES ===============================================================
@@ -69,7 +69,20 @@ namespace Decimater {
//== CLASS DEFINITION =========================================================
/** \brief Use Normal deviation to control decimation
*
* The module tracks the normals while decimating
* a normal cone consisting of all normals of the
* faces collapsed together is computed and if
* a collapse would increase the size of
* the cone to a value greater than the given value
* the collapse will be illegal.
*
* In binary and mode, the collapse is legal if:
* - The normal deviation after the collapse is lower than the given value
*
* In continuous mode the maximal deviation is returned
*/
template <class DecimaterT>
class ModNormalDeviationT : public ModBaseT< DecimaterT >
{
@@ -83,7 +96,7 @@ public:
typedef typename Mesh::VertexHandle VertexHandle;
typedef typename Mesh::FaceHandle FaceHandle;
typedef typename Mesh::EdgeHandle EdgeHandle;
typedef ACG::Geometry::NormalConeT<Scalar> NormalCone;
typedef NormalConeT<Scalar> NormalCone;
@@ -91,8 +104,7 @@ public:
/// Constructor
ModNormalDeviationT(DecimaterT& _dec, float _max_dev = 180.0)
: Base(_dec, true),
mesh_(Base::mesh())
: Base(_dec, true), mesh_(Base::mesh())
{
set_normal_deviation(_max_dev);
mesh_.add_property(normal_cones_);
@@ -105,12 +117,12 @@ public:
}
/// Get normal deviation
/// Get normal deviation ( 0 .. 360 )
Scalar normal_deviation() const {
return normal_deviation_ / M_PI * 180.0;
}
/// Set normal deviation
/// Set normal deviation ( 0 .. 360 )
void set_normal_deviation(Scalar _s) {
normal_deviation_ = _s / 180.0 * M_PI;
}
@@ -128,7 +140,20 @@ public:
mesh_.property(normal_cones_, f_it) = NormalCone(mesh_.normal(f_it));
}
/** \brief Control normals when Decimating
*
* Binary and Cont. mode.
*
* The module tracks the normals while decimating
* a normal cone consisting of all normals of the
* faces collapsed together is computed and if
* a collapse would increase the size of
* the cone to a value greater than the given value
* the collapse will be illegal.
*
* @param _ci Collapse info data
* @return Half of the normal cones size (radius in radians)
*/
float collapse_priority(const CollapseInfo& _ci) {
// simulate collapse
mesh_.set_point(_ci.v0, _ci.p1);
@@ -152,7 +177,7 @@ public:
if (nc.angle() > max_angle) {
max_angle = nc.angle();
if (max_angle > 0.5*normal_deviation_)
if (max_angle > 0.5 * normal_deviation_)
break;
}
}
@@ -163,8 +188,7 @@ public:
mesh_.set_point(_ci.v0, _ci.p0);
return (max_angle < 0.5*normal_deviation_ ?
max_angle : float( Base::ILLEGAL_COLLAPSE ));
return (max_angle < 0.5 * normal_deviation_ ? max_angle : float( Base::ILLEGAL_COLLAPSE ));
}
@@ -208,6 +232,6 @@ private:
} // END_NS_DECIMATER
} // END_NS_OPENMESH
//=============================================================================
#endif // MODNORMALDEVIATIONT_HH defined
#endif // OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH defined
//=============================================================================

View File

@@ -70,7 +70,7 @@ namespace Decimater { // BEGIN_NS_DECIMATER
*
* This module can be used only as a binary module. The criterion
* of allowing/disallowing the collapse is the angular deviation between
* the face normal of the orignal faces and normals of the faces after the
* the face normal of the original faces and normals of the faces after the
* collapse. The collapse will pass the test, if the deviation is below
* a given threshold.
*/
@@ -102,8 +102,8 @@ public:
* -# Compute for each adjacent face of \c _ci.v0 the face
* normal if the collpase would be executed.
*
* -# Prevent the collapse, if the angle between the original and the
* new normal is below a given threshold.
* -# Prevent the collapse, if the cosine of the angle between the
* original and the new normal is below a given threshold.
*
* \param _ci The collapse description
* \return LEGAL_COLLAPSE or ILLEGAL_COLLAPSE
@@ -148,9 +148,6 @@ public:
/// get normal deviation
float max_normal_deviation() const { return max_deviation_ / M_PI * 180.0; }
/// \deprecated
float normal_deviation() const { return max_normal_deviation(); }
/** Set normal deviation
*
* Set the maximum angular deviation of the orignal normal and the new
@@ -161,10 +158,6 @@ public:
min_cos_ = cos(max_deviation_);
}
/// \deprecated
void set_normal_deviation(float _f)
{ set_max_normal_deviation(_f); }
private:
// hide this method

View File

@@ -68,7 +68,7 @@ namespace Decimater {
//== CLASS DEFINITION =========================================================
/** Mesh decimation module computing collapse priority based on error quadrics.
/** \brief Mesh decimation module computing collapse priority based on error quadrics.
*
* This module can be used as a binary and non-binary module.
*/

View File

@@ -49,8 +49,8 @@
//
//=============================================================================
#ifndef OPENMESH_TOOLS_MODROUNDNESST_HH
#define OPENMESH_TOOLS_MODROUNDNESST_HH
#ifndef OPENMESH_DECIMATER_MODROUNDNESST_HH
#define OPENMESH_DECIMATER_MODROUNDNESST_HH
//== INCLUDES =================================================================
@@ -72,21 +72,27 @@ namespace Decimater { // BEGIN_NS_DECIMATER
//== CLASS DEFINITION =========================================================
/** Compute error value based on roundness criteria.
/** \brief Use Roundness of triangles to control decimation
*
*
* In binary and mode, the collapse is legal if:
* - The roundness after the collapse is greater than the given value
*
* In continuous mode the roundness after the collapse is returned
*/
template <class DecimaterType>
class ModRoundnessT : public ModBaseT<DecimaterType>
{
public:
public:
DECIMATING_MODULE( ModRoundnessT, DecimaterType, Roundness );
public:
public:
// typedefs
typedef typename Mesh::Point Point;
typedef typename vector_traits<Point>::value_type value_type;
public:
public:
/// Constructor
ModRoundnessT( DecimaterType &_dec ) :
@@ -97,7 +103,7 @@ public:
/// Destructor
~ModRoundnessT() { }
public: // inherited
public: // inherited
/** Compute collapse priority due to roundness of triangle.
*
@@ -111,7 +117,7 @@ public: // inherited
*/
float collapse_priority(const CollapseInfo& _ci)
{
// using namespace OpenMesh;
// using namespace OpenMesh;
typename Mesh::ConstVertexOHalfedgeIter voh_it(Base::mesh(), _ci.v0);
double r;
@@ -158,8 +164,7 @@ public: // inherited
continue;
priority = ( (r=roundness( vector_cast<Vec3f>(_ci.p1), B, C )) < min_r_)
? Base::ILLEGAL_COLLAPSE
: Base::LEGAL_COLLAPSE;
? Base::ILLEGAL_COLLAPSE : Base::LEGAL_COLLAPSE;
}
}
@@ -199,7 +204,7 @@ public: // specific methods
* \param _min_roundness in range (0,1)
* \param _binary Set true, if the binary mode should be enabled,
* else false. In latter case the collapse_priority()
* returns a float value if the constrain does not apply
* returns a float value if the constraint does not apply
* and ILLEGAL_COLLAPSE else.
*/
void set_min_roundness( value_type _min_roundness, bool _binary=true )
@@ -282,7 +287,7 @@ public: // specific methods
return nR;
}
private:
private:
value_type min_r_;
};
@@ -297,6 +302,6 @@ private:
# undef OM_ENABLE_WARNINGS
#endif
//=============================================================================
#endif // OPENMESH_TOOLS_PROGMESHT_HH defined
#endif // OPENMESH_DECIMATER_MODROUNDNESST_HH defined
//=============================================================================