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:
@@ -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";
|
||||
|
||||
@@ -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.
|
||||
@@ -74,8 +70,7 @@ namespace Decimater {
|
||||
\see ModProgMeshT::Info
|
||||
*/
|
||||
template<class Mesh>
|
||||
struct CollapseInfoT
|
||||
{
|
||||
struct CollapseInfoT {
|
||||
public:
|
||||
/** Initializing constructor.
|
||||
*
|
||||
@@ -108,49 +103,38 @@ public:
|
||||
//@}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// CollapseInfoT::CollapseInfoT( _mesh, _heh )
|
||||
//
|
||||
// Local configuration of halfedge collapse to be stored in CollapseInfoT:
|
||||
/*
|
||||
vl
|
||||
/**
|
||||
* Local configuration of halfedge collapse to be stored in CollapseInfoT:
|
||||
*
|
||||
/ \
|
||||
/ \
|
||||
/ fl \
|
||||
v0 *------>* v1
|
||||
\ fr /
|
||||
\ /
|
||||
\ /
|
||||
* vl
|
||||
* *
|
||||
* / \
|
||||
* / \
|
||||
* / fl \
|
||||
* v0 *------>* v1
|
||||
* \ fr /
|
||||
* \ /
|
||||
* \ /
|
||||
* *
|
||||
* vr
|
||||
*
|
||||
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))
|
||||
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);
|
||||
|
||||
@@ -42,16 +42,13 @@
|
||||
/** \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)
|
||||
{
|
||||
DecimaterT<Mesh>::DecimaterT(Mesh& _mesh) :
|
||||
mesh_(_mesh), heap_(NULL), cmodule_(NULL), initialized_(false) {
|
||||
// default properties
|
||||
mesh_.request_vertex_status();
|
||||
mesh_.request_edge_status();
|
||||
@@ -95,14 +82,10 @@ DecimaterT( Mesh& _mesh )
|
||||
mesh_.add_property(heap_position_);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<class Mesh>
|
||||
DecimaterT<Mesh>::
|
||||
~DecimaterT()
|
||||
{
|
||||
DecimaterT<Mesh>::~DecimaterT() {
|
||||
// default properties
|
||||
mesh_.release_vertex_status();
|
||||
mesh_.release_edge_status();
|
||||
@@ -124,30 +107,23 @@ DecimaterT<Mesh>::
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<class Mesh>
|
||||
void
|
||||
DecimaterT<Mesh>::
|
||||
info( std::ostream& _os )
|
||||
{
|
||||
if(initialized_)
|
||||
{
|
||||
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()) {
|
||||
_os << "binary";
|
||||
@@ -162,17 +138,11 @@ info( std::ostream& _os )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<class Mesh>
|
||||
bool
|
||||
DecimaterT<Mesh>::
|
||||
initialize()
|
||||
{
|
||||
if(initialized_)
|
||||
{
|
||||
bool DecimaterT<Mesh>::initialize() {
|
||||
if (initialized_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -189,15 +159,13 @@ initialize()
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
@@ -220,8 +188,8 @@ 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();
|
||||
|
||||
@@ -234,18 +202,14 @@ initialize()
|
||||
return initialized_ = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Mesh>
|
||||
bool
|
||||
DecimaterT<Mesh>::is_collapse_legal(const CollapseInfo& _ci)
|
||||
{
|
||||
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))
|
||||
@@ -253,20 +217,17 @@ DecimaterT<Mesh>::is_collapse_legal(const CollapseInfo& _ci)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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,12 +363,9 @@ preprocess_collapse(CollapseInfo& _ci)
|
||||
cmodule_->preprocess_collapse(_ci);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class Mesh>
|
||||
size_t
|
||||
DecimaterT<Mesh>::decimate( size_t _n_collapses )
|
||||
{
|
||||
size_t DecimaterT<Mesh>::decimate(size_t _n_collapses) {
|
||||
if (!is_initialized())
|
||||
return 0;
|
||||
|
||||
@@ -454,93 +382,72 @@ 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)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
// 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 )
|
||||
{
|
||||
size_t DecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf) {
|
||||
if (!is_initialized())
|
||||
return 0;
|
||||
|
||||
@@ -562,95 +469,74 @@ 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)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
// 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_OPENMESH
|
||||
|
||||
@@ -42,37 +42,27 @@
|
||||
/** \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 )
|
||||
{
|
||||
typename ModAspectRatioT<DecimaterT>::Scalar ModAspectRatioT<DecimaterT>::aspectRatio(
|
||||
const Point& _v0, const Point& _v1, const Point& _v2) {
|
||||
Point d0 = _v0 - _v1;
|
||||
Point d1 = _v1 - _v2;
|
||||
|
||||
@@ -99,65 +89,45 @@ aspectRatio( const Point& _v0,
|
||||
return sqrt((maxl2 * maxl2) / a2);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<class DecimaterT>
|
||||
void
|
||||
ModAspectRatioT<DecimaterT>::
|
||||
initialize()
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,102 +42,105 @@
|
||||
/** \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>
|
||||
{
|
||||
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
|
||||
float collapse_priority(const CollapseInfo& _ci);
|
||||
// update roundness of one-ring
|
||||
void preprocess_collapse(const CollapseInfo& _ci);
|
||||
|
||||
/// Returns the collapse priority
|
||||
float collapse_priority(const CollapseInfo& _ci);
|
||||
|
||||
/// update aspect ratio 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 );
|
||||
Scalar aspectRatio(const Point& _v0, const Point& _v1, const Point& _v2);
|
||||
|
||||
private:
|
||||
|
||||
Mesh& mesh_;
|
||||
float min_roundness_;
|
||||
FPropHandleT<float> roundness_;
|
||||
float min_aspect_;
|
||||
FPropHandleT<float> aspect_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
}// 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
|
||||
//=============================================================================
|
||||
|
||||
|
||||
@@ -42,56 +42,40 @@
|
||||
/** \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())
|
||||
{
|
||||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
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:
|
||||
|
||||
Mesh& mesh_;
|
||||
typename Mesh::Scalar edge_length_, sqr_edge_length_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
}// 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
|
||||
//=============================================================================
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define MODHAUSDORFFT_C
|
||||
#define OPENMESH_DECIMATER_MODHAUSDORFFT_C
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
@@ -42,17 +42,14 @@
|
||||
/** \file ModHausdorffT.hh
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ModHausdorffT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef MODHAUSDORFFT_HH
|
||||
#define MODHAUSDORFFT_HH
|
||||
|
||||
#ifndef OPENMESH_DECIMATER_MODHAUSDORFFT_HH
|
||||
#define OPENMESH_DECIMATER_MODHAUSDORFFT_HH
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
@@ -61,19 +58,24 @@
|
||||
#include <vector>
|
||||
#include <float.h>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Decimater {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** \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>
|
||||
{
|
||||
class ModHausdorffT: public ModBaseT<DecimaterT> {
|
||||
public:
|
||||
|
||||
DECIMATING_MODULE( ModHausdorffT, DecimaterT, Roundness );
|
||||
@@ -83,59 +85,54 @@ 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:
|
||||
|
||||
/// 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:
|
||||
|
||||
Mesh& mesh_;
|
||||
@@ -144,16 +141,15 @@ private:
|
||||
OpenMesh::FPropHandleT<Points> points_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
}// 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
|
||||
//=============================================================================
|
||||
|
||||
|
||||
@@ -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>
|
||||
{
|
||||
class ModIndependentSetsT: public ModBaseT<DecimaterType> {
|
||||
public:
|
||||
DECIMATING_MODULE( ModIndependentSetsT, DecimaterType, IndependentSets );
|
||||
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,14 +86,12 @@ public:
|
||||
Base::mesh().status(vv_it).set_locked(true);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/// hide this method
|
||||
void set_binary(bool _b) { }
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
}// END_NS_DECIMATER
|
||||
} // END_NS_OPENMESH
|
||||
|
||||
@@ -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);
|
||||
@@ -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
|
||||
//=============================================================================
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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,7 +72,13 @@ 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>
|
||||
@@ -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 )
|
||||
@@ -297,6 +302,6 @@ private:
|
||||
# undef OM_ENABLE_WARNINGS
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_TOOLS_PROGMESHT_HH defined
|
||||
#endif // OPENMESH_DECIMATER_MODROUNDNESST_HH defined
|
||||
//=============================================================================
|
||||
|
||||
|
||||
Reference in New Issue
Block a user