First checkin for OpenMesh 2.0
git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@2 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
17
Tools/Decimater/ACGMakefile
Normal file
17
Tools/Decimater/ACGMakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS = $(call find-subdirs)
|
||||
|
||||
PACKAGES := opensg boost
|
||||
|
||||
PROJ_LIBS := OpenMesh/Core
|
||||
|
||||
MODULES := cxxlib
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
168
Tools/Decimater/CollapseInfoT.hh
Normal file
168
Tools/Decimater/CollapseInfoT.hh
Normal file
@@ -0,0 +1,168 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file CollapseInfoT.hh
|
||||
Provides data class CollapseInfoT for storing all information
|
||||
about a halfedge collapse.
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// 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.
|
||||
|
||||
The class stores information about a halfedge collapse. The most
|
||||
important information is \c v0v1, \c v1v0, \c v0, \c v1, \c vl,
|
||||
\c vr, which you can lookup in the following image:
|
||||
\image html collapse_info.png
|
||||
\see ModProgMeshT::Info
|
||||
*/
|
||||
template <class Mesh>
|
||||
struct CollapseInfoT
|
||||
{
|
||||
public:
|
||||
/** Initializing constructor.
|
||||
*
|
||||
* Given a mesh and a halfedge handle of the halfedge to be collapsed
|
||||
* all important information of a halfedge collapse will be stored.
|
||||
* \param _mesh Mesh source
|
||||
* \param _heh Halfedge to collapse. The direction of the halfedge
|
||||
* defines the direction of the collapse, i.e. the from-vertex
|
||||
* will be removed and the to-vertex remains.
|
||||
*/
|
||||
CollapseInfoT(Mesh& _mesh, typename Mesh::HalfedgeHandle _heh);
|
||||
|
||||
Mesh& mesh;
|
||||
|
||||
typename Mesh::HalfedgeHandle v0v1; ///< Halfedge to be collapsed
|
||||
typename Mesh::HalfedgeHandle v1v0; ///< Reverse halfedge
|
||||
typename Mesh::VertexHandle v0; ///< Vertex to be removed
|
||||
typename Mesh::VertexHandle v1; ///< Remaining vertex
|
||||
typename Mesh::Point p0; ///< Position of removed vertex
|
||||
typename Mesh::Point p1; ///< Positions of remaining vertex
|
||||
typename Mesh::FaceHandle fl; ///< Left face
|
||||
typename Mesh::FaceHandle fr; ///< Right face
|
||||
typename Mesh::VertexHandle vl; ///< Left vertex
|
||||
typename Mesh::VertexHandle vr; ///< Right vertex
|
||||
//@{
|
||||
/** Outer remaining halfedge of diamond spanned by \c v0, \c v1,
|
||||
* \c vl, and \c vr
|
||||
*/
|
||||
typename Mesh::HalfedgeHandle vlv1, v0vl, vrv0, v1vr;
|
||||
//@}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// CollapseInfoT::CollapseInfoT( _mesh, _heh )
|
||||
//
|
||||
// Local configuration of halfedge collapse to be stored in CollapseInfoT:
|
||||
/*
|
||||
vl
|
||||
*
|
||||
/ \
|
||||
/ \
|
||||
/ fl \
|
||||
v0 *------>* v1
|
||||
\ fr /
|
||||
\ /
|
||||
\ /
|
||||
*
|
||||
vr
|
||||
*/
|
||||
// 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))
|
||||
|
||||
{
|
||||
// get vl
|
||||
if (fl.is_valid())
|
||||
{
|
||||
vlv1 = mesh.next_halfedge_handle(v0v1);
|
||||
v0vl = mesh.next_halfedge_handle(vlv1);
|
||||
vl = mesh.to_vertex_handle(vlv1);
|
||||
vlv1 = mesh.opposite_halfedge_handle(vlv1);
|
||||
v0vl = mesh.opposite_halfedge_handle(v0vl);
|
||||
}
|
||||
|
||||
|
||||
// get vr
|
||||
if (fr.is_valid())
|
||||
{
|
||||
vrv0 = mesh.next_halfedge_handle(v1v0);
|
||||
v1vr = mesh.next_halfedge_handle(vrv0);
|
||||
vr = mesh.to_vertex_handle(vrv0);
|
||||
vrv0 = mesh.opposite_halfedge_handle(vrv0);
|
||||
v1vr = mesh.opposite_halfedge_handle(v1vr);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_DECIMATER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_DECIMATER_COLLAPSEINFOT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
489
Tools/Decimater/DecimaterT.cc
Normal file
489
Tools/Decimater/DecimaterT.cc
Normal file
@@ -0,0 +1,489 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 2317 $
|
||||
// $Date: 2008-07-24 15:32:54 +0200 (Do, 24. Jul 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file DecimaterT.cc
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS DecimaterT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define OPENMESH_DECIMATER_DECIMATERT_CC
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>
|
||||
|
||||
#include <vector>
|
||||
#if defined(OM_CC_MIPS)
|
||||
# include <float.h>
|
||||
#else
|
||||
# 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)
|
||||
{
|
||||
// default properties
|
||||
mesh_.request_vertex_status();
|
||||
mesh_.request_edge_status();
|
||||
mesh_.request_face_status();
|
||||
mesh_.request_face_normals();
|
||||
|
||||
// private vertex properties
|
||||
mesh_.add_property( collapse_target_ );
|
||||
mesh_.add_property( priority_ );
|
||||
mesh_.add_property( heap_position_ );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
DecimaterT<Mesh>::
|
||||
~DecimaterT()
|
||||
{
|
||||
// default properties
|
||||
mesh_.release_vertex_status();
|
||||
mesh_.release_edge_status();
|
||||
mesh_.release_face_status();
|
||||
mesh_.release_face_normals();
|
||||
|
||||
// private vertex properties
|
||||
mesh_.remove_property(collapse_target_);
|
||||
mesh_.remove_property(priority_);
|
||||
mesh_.remove_property(heap_position_);
|
||||
|
||||
// dispose modules
|
||||
{
|
||||
typename ModuleList::iterator m_it, m_end = bmodules_.end();
|
||||
for( m_it=bmodules_.begin(); m_it!=m_end; ++m_it)
|
||||
delete *m_it;
|
||||
bmodules_.clear();
|
||||
if (cmodule_)
|
||||
delete cmodule_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
DecimaterT<Mesh>::
|
||||
info( std::ostream& _os )
|
||||
{
|
||||
typename ModuleList::iterator m_it, m_end = bmodules_.end();
|
||||
|
||||
_os << "binary modules: " << bmodules_.size() << std::endl;
|
||||
for( m_it=bmodules_.begin(); m_it!=m_end; ++m_it)
|
||||
_os << " " << (*m_it)->name() << std::endl;
|
||||
|
||||
_os << "priority module: "
|
||||
<< (cmodule_ ? cmodule_->name().c_str() : "<None>") << std::endl;
|
||||
_os << "is initialized : " << (initialized_ ? "yes" : "no") << std::endl;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
bool
|
||||
DecimaterT<Mesh>::
|
||||
initialize()
|
||||
{
|
||||
typename ModuleList::iterator m_it, m_end = bmodules_.end();
|
||||
|
||||
Module *quadric=NULL;
|
||||
|
||||
Module* origC = NULL;
|
||||
|
||||
// If already initialized, remember original cModule (priority module)
|
||||
// if no new cmodule is provided use old one
|
||||
if (initialized_)
|
||||
origC = cmodule_;
|
||||
|
||||
cmodule_ = NULL;
|
||||
|
||||
for (m_it=bmodules_.begin(); m_it != m_end; ++m_it)
|
||||
{
|
||||
if ( (*m_it)->name() == "Quadric")
|
||||
quadric = *m_it;
|
||||
|
||||
if ( ! (*m_it)->is_binary() )
|
||||
{
|
||||
if ( !cmodule_ ) // only one non-binary module allowed!
|
||||
cmodule_ = *m_it;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
(*m_it)->initialize();
|
||||
}
|
||||
|
||||
// If the decimater has already been initialized and we have no new cmodule,
|
||||
// use the old cmodule
|
||||
if ( initialized_ && !cmodule_ ) {
|
||||
cmodule_ = origC;
|
||||
cmodule_->initialize();
|
||||
}
|
||||
|
||||
if (!cmodule_) // one non-binary module is mandatory!
|
||||
{
|
||||
if (!quadric)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
cmodule_ = quadric; // let the quadric become the priority module
|
||||
}
|
||||
}
|
||||
|
||||
// If we do not reuse the original cmodule delete the new cmodule from the
|
||||
// binary module list
|
||||
if ( !initialized_ || (cmodule_ != origC) ) {
|
||||
m_it = std::find(bmodules_.begin(), bmodules_.end(), cmodule_ );
|
||||
bmodules_.erase( m_it );
|
||||
}
|
||||
|
||||
return initialized_ = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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())
|
||||
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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//--- feature test ---
|
||||
|
||||
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;
|
||||
|
||||
for (vv_it = mesh_.vv_iter(_ci.v0); vv_it; ++vv_it)
|
||||
mesh_.status(vv_it).set_tagged(false);
|
||||
|
||||
for (vv_it = mesh_.vv_iter(_ci.v1); vv_it; ++vv_it)
|
||||
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)
|
||||
return false;
|
||||
|
||||
// if both are invalid OR equal -> fail
|
||||
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
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
// only one one ring intersection
|
||||
if (_ci.vl.is_valid() && _ci.vr.is_valid())
|
||||
return false;
|
||||
}
|
||||
|
||||
// v0vl and v1vl must not both be boundary edges
|
||||
if (_ci.vl.is_valid() &&
|
||||
mesh_.is_boundary(_ci.vlv1) &&
|
||||
mesh_.is_boundary(_ci.v0v1))
|
||||
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))
|
||||
return false;
|
||||
|
||||
// there have to be at least 2 incident faces at v0
|
||||
if (mesh_.cw_rotated_halfedge_handle(
|
||||
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)
|
||||
{
|
||||
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)
|
||||
return -1.0; // ILLEGAL_COLLAPSE
|
||||
}
|
||||
return cmodule_->collapse_priority(_ci);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
heh = voh_it.handle();
|
||||
CollapseInfo ci(mesh_, heh);
|
||||
|
||||
if (is_collapse_legal(ci))
|
||||
{
|
||||
prio = collapse_priority(ci);
|
||||
if (prio >= 0.0 && prio < best_prio)
|
||||
{
|
||||
best_prio = prio;
|
||||
collapse_target = heh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// target found -> put vertex on heap
|
||||
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);
|
||||
}
|
||||
|
||||
// not valid -> remove from heap
|
||||
else
|
||||
{
|
||||
// std::clog << " n/a|removed" << std::endl;
|
||||
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)
|
||||
{
|
||||
typename ModuleList::iterator m_it, m_end = bmodules_.end();
|
||||
|
||||
for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
|
||||
(*m_it)->postprocess_collapse(_ci);
|
||||
|
||||
cmodule_->postprocess_collapse(_ci);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
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());
|
||||
typename Mesh::VertexHandle vp;
|
||||
typename Mesh::HalfedgeHandle v0v1;
|
||||
typename Mesh::VertexVertexIter vv_it;
|
||||
typename Mesh::VertexFaceIter vf_it;
|
||||
unsigned int n_collapses(0);
|
||||
|
||||
typedef std::vector<typename Mesh::VertexHandle> Support;
|
||||
typedef typename Support::iterator SupportIterator;
|
||||
|
||||
Support support(15);
|
||||
SupportIterator s_it, s_end;
|
||||
|
||||
|
||||
// check _n_collapses
|
||||
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() );
|
||||
if (!mesh_.status(v_it).deleted())
|
||||
heap_vertex( v_it.handle() );
|
||||
}
|
||||
|
||||
|
||||
// process heap
|
||||
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)
|
||||
{
|
||||
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
|
||||
//=============================================================================
|
||||
|
||||
282
Tools/Decimater/DecimaterT.hh
Normal file
282
Tools/Decimater/DecimaterT.hh
Normal file
@@ -0,0 +1,282 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file DecimaterT.hh
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS DecimaterT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_DECIMATER_DECIMATERT_HH
|
||||
#define OPENMESH_DECIMATER_DECIMATERT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <OpenMesh/Core/Utils/Property.hh>
|
||||
#include <OpenMesh/Tools/Utils/HeapT.hh>
|
||||
#include <OpenMesh/Tools/Decimater/ModBaseT.hh>
|
||||
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Decimater {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Decimater framework.
|
||||
\see BaseModT, \ref decimater_docu
|
||||
*/
|
||||
template < typename MeshT >
|
||||
class DecimaterT
|
||||
{
|
||||
public: //-------------------------------------------------------- public types
|
||||
|
||||
typedef DecimaterT< MeshT > Self;
|
||||
typedef MeshT Mesh;
|
||||
typedef CollapseInfoT<MeshT> CollapseInfo;
|
||||
typedef ModBaseT<Self> Module;
|
||||
typedef std::vector< Module* > ModuleList;
|
||||
|
||||
public: //------------------------------------------------------ public methods
|
||||
|
||||
/// Constructor
|
||||
DecimaterT( Mesh& _mesh );
|
||||
|
||||
/// Destructor
|
||||
~DecimaterT();
|
||||
|
||||
|
||||
/** Initialize decimater and decimating modules.
|
||||
|
||||
Return values:
|
||||
true ok
|
||||
false No ore more than one non-binary module exist. In that case
|
||||
the decimater is uninitialized!
|
||||
*/
|
||||
bool initialize();
|
||||
|
||||
|
||||
/// Returns whether decimater has been successfully initialized.
|
||||
bool is_initialized() const { return initialized_; }
|
||||
|
||||
|
||||
/// Print information about modules to _os
|
||||
void info( std::ostream& _os );
|
||||
|
||||
public: //--------------------------------------------------- module management
|
||||
|
||||
/// access mesh. used in modules.
|
||||
Mesh& mesh() { return mesh_; }
|
||||
|
||||
/// add module to decimater
|
||||
template < typename _Module >
|
||||
bool add( ModHandleT<_Module>& _mh )
|
||||
{
|
||||
if (_mh.is_valid())
|
||||
return false;
|
||||
|
||||
_mh.init( new _Module(*this) );
|
||||
bmodules_.push_back( _mh.module() );
|
||||
|
||||
initialized_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// remove module
|
||||
template < typename _Module >
|
||||
bool remove( ModHandleT<_Module>& _mh )
|
||||
{
|
||||
if (!_mh.is_valid())
|
||||
return false;
|
||||
|
||||
typename ModuleList::iterator it = std::find(bmodules_.begin(),
|
||||
bmodules_.end(),
|
||||
_mh.module() );
|
||||
|
||||
if ( it == bmodules_.end() ) // module not found
|
||||
return false;
|
||||
|
||||
delete *it;
|
||||
bmodules_.erase( it ); // finally remove from list
|
||||
_mh.clear();
|
||||
|
||||
initialized_ = false; // reset initialized state
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// get module referenced by handle _mh
|
||||
template < typename Module >
|
||||
Module& module( ModHandleT<Module>& _mh )
|
||||
{
|
||||
assert( _mh.is_valid() );
|
||||
return *_mh.module();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/** Decimate (perform _n_collapses collapses). Return number of
|
||||
performed collapses. If _n_collapses is not given reduce as
|
||||
much as possible */
|
||||
size_t decimate( size_t _n_collapses = 0 );
|
||||
|
||||
/// Decimate to target complexity, returns number of collapses
|
||||
size_t decimate_to( size_t _n_vertices )
|
||||
{
|
||||
return ( (_n_vertices < mesh().n_vertices()) ?
|
||||
decimate( mesh().n_vertices() - _n_vertices ) : 0 );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void update_modules(CollapseInfo& _ci)
|
||||
{
|
||||
typename ModuleList::iterator m_it, m_end = bmodules_.end();
|
||||
for (m_it = bmodules_.begin(); m_it != m_end; ++m_it)
|
||||
(*m_it)->postprocess_collapse(_ci);
|
||||
cmodule_->postprocess_collapse(_ci);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Mesh::VertexHandle VertexHandle;
|
||||
typedef typename Mesh::HalfedgeHandle HalfedgeHandle;
|
||||
|
||||
/// Heap interface
|
||||
class HeapInterface
|
||||
{
|
||||
public:
|
||||
|
||||
HeapInterface(Mesh& _mesh,
|
||||
VPropHandleT<float> _prio,
|
||||
VPropHandleT<int> _pos)
|
||||
: mesh_(_mesh), prio_(_prio), pos_(_pos)
|
||||
{ }
|
||||
|
||||
inline bool
|
||||
less( VertexHandle _vh0, VertexHandle _vh1 )
|
||||
{ return mesh_.property(prio_, _vh0) < mesh_.property(prio_, _vh1); }
|
||||
|
||||
inline bool
|
||||
greater( VertexHandle _vh0, VertexHandle _vh1 )
|
||||
{ return mesh_.property(prio_, _vh0) > mesh_.property(prio_, _vh1); }
|
||||
|
||||
inline int
|
||||
get_heap_position(VertexHandle _vh)
|
||||
{ return mesh_.property(pos_, _vh); }
|
||||
|
||||
inline void
|
||||
set_heap_position(VertexHandle _vh, int _pos)
|
||||
{ mesh_.property(pos_, _vh) = _pos; }
|
||||
|
||||
|
||||
private:
|
||||
Mesh& mesh_;
|
||||
VPropHandleT<float> prio_;
|
||||
VPropHandleT<int> pos_;
|
||||
};
|
||||
|
||||
typedef Utils::HeapT<VertexHandle, HeapInterface> DeciHeap;
|
||||
|
||||
|
||||
private: //---------------------------------------------------- private methods
|
||||
|
||||
/// Insert vertex in heap
|
||||
void heap_vertex(VertexHandle _vh);
|
||||
|
||||
/// Is an edge collapse legal? Performs topological test only.
|
||||
/// The method evaluates the status bit Locked, Deleted, and Feature.
|
||||
/// \attention The method temporarily sets the bit Tagged. After usage
|
||||
/// the bit will be disabled!
|
||||
bool is_collapse_legal(const CollapseInfo& _ci);
|
||||
|
||||
/// Calculate priority of an halfedge collapse (using the modules)
|
||||
float collapse_priority(const CollapseInfo& _ci);
|
||||
|
||||
/// Post-process a collapse
|
||||
void postprocess_collapse(CollapseInfo& _ci);
|
||||
|
||||
|
||||
|
||||
|
||||
private: //------------------------------------------------------- private data
|
||||
|
||||
|
||||
// reference to mesh
|
||||
Mesh& mesh_;
|
||||
|
||||
// heap
|
||||
std::auto_ptr<DeciHeap> heap_;
|
||||
|
||||
// list of modules
|
||||
ModuleList bmodules_;
|
||||
Module* cmodule_;
|
||||
|
||||
bool initialized_;
|
||||
|
||||
|
||||
// vertex properties
|
||||
VPropHandleT<HalfedgeHandle> collapse_target_;
|
||||
VPropHandleT<float> priority_;
|
||||
VPropHandleT<int> heap_position_;
|
||||
|
||||
|
||||
|
||||
private: // Noncopyable
|
||||
|
||||
DecimaterT(const Self&);
|
||||
Self& operator = (const Self&);
|
||||
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_DECIMATER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_DECIMATERT_CC)
|
||||
#define OPENMESH_DECIMATER_TEMPLATES
|
||||
#include "DecimaterT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_DECIMATER_DECIMATERT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
266
Tools/Decimater/ModBaseT.hh
Normal file
266
Tools/Decimater/ModBaseT.hh
Normal file
@@ -0,0 +1,266 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file ModBaseT.hh
|
||||
Base class for all decimation modules.
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ModBaseT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_DECIMATER_MODBASET_HH
|
||||
#define OPENMESH_DECIMATER_MODBASET_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/Utils/Noncopyable.hh>
|
||||
#include <OpenMesh/Tools/Decimater/CollapseInfoT.hh>
|
||||
#include <string>
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Decimater {
|
||||
|
||||
|
||||
//== FORWARD DECLARATIONS =====================================================
|
||||
|
||||
template <typename Mesh> class DecimaterT;
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Handle for mesh decimation modules
|
||||
\internal
|
||||
*/
|
||||
template <typename Module>
|
||||
class ModHandleT : private Utils::Noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ModHandleT<Module> Self;
|
||||
typedef Module module_type;
|
||||
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
ModHandleT() : mod_(NULL) {}
|
||||
|
||||
/// Destructor
|
||||
~ModHandleT() { /* don't delete mod_, since handle is not owner! */ }
|
||||
|
||||
/// Check handle status
|
||||
/// \return \c true, if handle is valid, else \c false.
|
||||
bool is_valid() const { return mod_ != NULL; }
|
||||
|
||||
private:
|
||||
|
||||
#if defined(OM_CC_MSVC)
|
||||
friend class DecimaterT;
|
||||
#else
|
||||
template <typename Mesh> friend class DecimaterT;
|
||||
#endif
|
||||
|
||||
void clear() { mod_ = NULL; }
|
||||
void init(Module* _m) { mod_ = _m; }
|
||||
Module* module() { return mod_; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Module* mod_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/// Macro that sets up the name() function
|
||||
/// \internal
|
||||
#define DECIMATER_MODNAME(_mod_name) \
|
||||
virtual const std::string& name() const { \
|
||||
static std::string _s_modname_(#_mod_name); return _s_modname_; \
|
||||
}
|
||||
|
||||
|
||||
/** Convenience macro, to be used in derived modules
|
||||
* The macro defines the types
|
||||
* - \c Handle, type of the module's handle.
|
||||
* - \c Base, type of ModBaseT<>.
|
||||
* - \c Mesh, type of the associated mesh passed by the decimater type.
|
||||
* - \c CollapseInfo, to your convenience
|
||||
* and uses DECIMATER_MODNAME() to define the name of the module.
|
||||
*
|
||||
* \param Classname The name of the derived class.
|
||||
* \param DecimaterT Pass here the decimater type, which is the
|
||||
* template parameter passed to ModBaseT.
|
||||
* \param Name Give the module a name.
|
||||
*/
|
||||
#define DECIMATING_MODULE(Classname, DecimaterT, Name) \
|
||||
typedef Classname < DecimaterT > Self; \
|
||||
typedef OpenMesh::Decimater::ModHandleT< Self > Handle; \
|
||||
typedef OpenMesh::Decimater::ModBaseT< DecimaterT > Base; \
|
||||
typedef typename Base::Mesh Mesh; \
|
||||
typedef typename Base::CollapseInfo CollapseInfo; \
|
||||
DECIMATER_MODNAME( Name )
|
||||
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Base class for all decimation modules.
|
||||
|
||||
Each module has to implement this interface.
|
||||
To build your own module you have to
|
||||
-# derive from this class.
|
||||
-# create the basic settings with DECIMATING_MODULE().
|
||||
-# override collapse_priority(), if necessary.
|
||||
-# override initialize(), if necessary.
|
||||
-# override postprocess_collapse(), if necessary.
|
||||
|
||||
A module has two major working modes:
|
||||
-# binary mode
|
||||
-# non-binary mode
|
||||
|
||||
In the binary mode collapse_priority() checks a constraint and
|
||||
returns LEGAL_COLLAPSE or ILLEGAL_COLLAPSE.
|
||||
|
||||
In the non-binary mode the module computes a float error value in
|
||||
the range [0, inf) and returns it. In the case a constraint has
|
||||
been set, e.g. the error must be lower than a upper bound, and the
|
||||
constraint is violated, collapse_priority() must return
|
||||
ILLEGAL_COLLAPSE.
|
||||
|
||||
\see collapse_priority()
|
||||
|
||||
\todo "Tutorial on building a custom decimation module."
|
||||
|
||||
*/
|
||||
template <typename DecimaterType>
|
||||
class ModBaseT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename DecimaterType::Mesh Mesh;
|
||||
typedef CollapseInfoT<Mesh> CollapseInfo;
|
||||
|
||||
enum {
|
||||
ILLEGAL_COLLAPSE = -1, ///< indicates an illegal collapse
|
||||
LEGAL_COLLAPSE = 0 ///< indicates a legal collapse
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
/// Default constructor
|
||||
/// \see \ref decimater_docu
|
||||
ModBaseT(DecimaterType& _dec, bool _is_binary)
|
||||
: dec_(_dec), is_binary_(_is_binary) {}
|
||||
|
||||
public:
|
||||
|
||||
/// Virtual desctructor
|
||||
virtual ~ModBaseT() { }
|
||||
|
||||
/// Set module's name (using DECIMATER_MODNAME macro)
|
||||
DECIMATER_MODNAME(ModBase);
|
||||
|
||||
|
||||
/// Returns true if criteria returns a binary value.
|
||||
bool is_binary(void) const { return is_binary_; }
|
||||
|
||||
/// Set whether module is binary or not.
|
||||
void set_binary(bool _b) { is_binary_ = _b; }
|
||||
|
||||
|
||||
public: // common interface
|
||||
|
||||
/// Initialize module-internal stuff
|
||||
virtual void initialize() { }
|
||||
|
||||
/** Return collapse priority.
|
||||
*
|
||||
* In the binary mode collapse_priority() checks a constraint and
|
||||
* returns LEGAL_COLLAPSE or ILLEGAL_COLLAPSE.
|
||||
*
|
||||
* In the non-binary mode the module computes a float error value in
|
||||
* the range [0, inf) and returns it. In the case a constraint has
|
||||
* been set, e.g. the error must be lower than a upper bound, and the
|
||||
* constraint is violated, collapse_priority() must return
|
||||
* ILLEGAL_COLLAPSE.
|
||||
*
|
||||
* \return Collapse priority in the range [0,inf),
|
||||
* \c LEGAL_COLLAPSE or \c ILLEGAL_COLLAPSE.
|
||||
*/
|
||||
virtual float collapse_priority(const CollapseInfoT<Mesh>& /* _ci */)
|
||||
{ return LEGAL_COLLAPSE; }
|
||||
|
||||
/** After _from_vh has been collapsed into _to_vh, this method
|
||||
will be called.
|
||||
*/
|
||||
virtual void postprocess_collapse(const CollapseInfoT<Mesh>& /* _ci */)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/// Access the mesh associated with the decimater.
|
||||
Mesh& mesh() { return dec_.mesh(); }
|
||||
|
||||
private:
|
||||
|
||||
// hide copy constructor & assignemnt
|
||||
ModBaseT(const ModBaseT& _cpy);
|
||||
ModBaseT& operator=(const ModBaseT& );
|
||||
|
||||
// reference to decimater
|
||||
DecimaterType &dec_;
|
||||
|
||||
bool is_binary_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Decimater
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_DECIMATER_MODBASE_HH defined
|
||||
//=============================================================================
|
||||
|
||||
97
Tools/Decimater/ModIndependentSetsT.hh
Normal file
97
Tools/Decimater/ModIndependentSetsT.hh
Normal file
@@ -0,0 +1,97 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file ModQuadricT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 );
|
||||
|
||||
/// Constructor
|
||||
ModIndependentSetsT( DecimaterType &_dec ) : Base(_dec, true) {}
|
||||
|
||||
|
||||
/// override
|
||||
void postprocess_collapse(const CollapseInfo& _ci)
|
||||
{
|
||||
typename Mesh::VertexVertexIter vv_it;
|
||||
|
||||
Base::mesh().status(_ci.v1).set_locked(true);
|
||||
vv_it = Base::mesh().vv_iter(_ci.v1);
|
||||
for (; vv_it; ++vv_it)
|
||||
Base::mesh().status(vv_it).set_locked(true);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/// hide this method
|
||||
void set_binary(bool _b) {}
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_DECIMATER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_TOOLS_MODINDEPENDENTSETST_HH defined
|
||||
//=============================================================================
|
||||
|
||||
175
Tools/Decimater/ModNormalFlippingT.hh
Normal file
175
Tools/Decimater/ModNormalFlippingT.hh
Normal file
@@ -0,0 +1,175 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file ModNormalFlippingT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ModNormalFlipping
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef OPENMESH_DECIMATER_MODNORMALFLIPPING_HH
|
||||
#define OPENMESH_DECIMATER_MODNORMALFLIPPING_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/Decimater/ModBaseT.hh>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Decimater { // BEGIN_NS_DECIMATER
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Decimating module to avoid flipping of faces.
|
||||
*
|
||||
* 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
|
||||
* collapse. The collapse will pass the test, if the deviation is below
|
||||
* a given threshold.
|
||||
*/
|
||||
template <typename DecimaterT>
|
||||
class ModNormalFlippingT : public ModBaseT< DecimaterT >
|
||||
{
|
||||
public:
|
||||
|
||||
DECIMATING_MODULE( ModNormalFlippingT, DecimaterT, NormalFlipping );
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
ModNormalFlippingT( DecimaterT &_dec) : Base(_dec, true)
|
||||
{
|
||||
set_max_normal_deviation( 90.0f );
|
||||
}
|
||||
|
||||
|
||||
~ModNormalFlippingT()
|
||||
{ }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/** Compute collapse priority due to angular deviation of face normals
|
||||
* before and after a collapse.
|
||||
*
|
||||
* -# 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.
|
||||
*
|
||||
* \param _ci The collapse description
|
||||
* \return LEGAL_COLLAPSE or ILLEGAL_COLLAPSE
|
||||
*
|
||||
* \see set_max_normal_deviation()
|
||||
*/
|
||||
float collapse_priority(const CollapseInfo& _ci)
|
||||
{
|
||||
// simulate collapse
|
||||
Base::mesh().set_point(_ci.v0, _ci.p1);
|
||||
|
||||
// check for flipping normals
|
||||
typename Mesh::ConstVertexFaceIter vf_it(Base::mesh(), _ci.v0);
|
||||
typename Mesh::FaceHandle fh;
|
||||
typename Mesh::Scalar c(1.0);
|
||||
|
||||
for (; vf_it; ++vf_it)
|
||||
{
|
||||
fh = vf_it.handle();
|
||||
if (fh != _ci.fl && fh != _ci.fr)
|
||||
{
|
||||
typename Mesh::Normal n1 = Base::mesh().normal(fh);
|
||||
typename Mesh::Normal n2 = Base::mesh().calc_face_normal(fh);
|
||||
|
||||
c = dot(n1, n2);
|
||||
|
||||
if (c < min_cos_)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// undo simulation changes
|
||||
Base::mesh().set_point(_ci.v0, _ci.p0);
|
||||
|
||||
return float( (c < min_cos_) ? Base::ILLEGAL_COLLAPSE : Base::LEGAL_COLLAPSE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
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
|
||||
* normal in degrees.
|
||||
*/
|
||||
void set_max_normal_deviation(float _f) {
|
||||
max_deviation_ = _f / 180.0 * M_PI;
|
||||
min_cos_ = cos(max_deviation_);
|
||||
}
|
||||
|
||||
/// \deprecated
|
||||
void set_normal_deviation(float _f)
|
||||
{ set_max_normal_deviation(_f); }
|
||||
|
||||
private:
|
||||
|
||||
// hide this method
|
||||
void set_binary(bool _b) {}
|
||||
|
||||
private:
|
||||
|
||||
// maximum normal deviation
|
||||
double max_deviation_, min_cos_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_DECIMATER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENACG_MODNORMALFLIPPING_HH defined
|
||||
//=============================================================================
|
||||
|
||||
173
Tools/Decimater/ModProgMeshT.cc
Normal file
173
Tools/Decimater/ModProgMeshT.cc
Normal file
@@ -0,0 +1,173 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file ModProgMeshT.cc
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ModProgMeshT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define OPENMESH_DECIMATER_MODPROGMESH_CC
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
// --------------------
|
||||
#include <OpenMesh/Core/Utils/vector_cast.hh>
|
||||
#include <OpenMesh/Core/IO/BinaryHelper.hh>
|
||||
#include <OpenMesh/Core/Utils/Endian.hh>
|
||||
// --------------------
|
||||
#include <OpenMesh/Tools/Decimater/ModProgMeshT.hh>
|
||||
|
||||
|
||||
//== NAMESPACE ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Decimater {
|
||||
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template <class DecimaterType>
|
||||
bool
|
||||
ModProgMeshT<DecimaterType>::
|
||||
write( const std::string& _ofname )
|
||||
{
|
||||
// sort vertices
|
||||
size_t i=0, N=Base::mesh().n_vertices(), n_base_vertices(0), n_base_faces(0);
|
||||
std::vector<typename Mesh::VertexHandle> vhandles(N);
|
||||
|
||||
|
||||
// base vertices
|
||||
typename Mesh::VertexIter
|
||||
v_it=Base::mesh().vertices_begin(),
|
||||
v_end=Base::mesh().vertices_end();
|
||||
|
||||
for (; v_it != v_end; ++v_it)
|
||||
if (!Base::mesh().status(v_it).deleted())
|
||||
{
|
||||
vhandles[i] = v_it.handle();
|
||||
Base::mesh().property( idx_, v_it ) = i;
|
||||
++i;
|
||||
}
|
||||
n_base_vertices = i;
|
||||
|
||||
|
||||
// deleted vertices
|
||||
typename InfoList::reverse_iterator
|
||||
r_it=pmi_.rbegin(), r_end=pmi_.rend();
|
||||
|
||||
for (; r_it!=r_end; ++r_it)
|
||||
{
|
||||
vhandles[i] = r_it->v0;
|
||||
Base::mesh().property( idx_, r_it->v0) = i;
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
// base faces
|
||||
typename Mesh::ConstFaceIter f_it = Base::mesh().faces_begin(),
|
||||
f_end = Base::mesh().faces_end();
|
||||
for (; f_it != f_end; ++f_it)
|
||||
if (!Base::mesh().status(f_it).deleted())
|
||||
++n_base_faces;
|
||||
|
||||
// ---------------------------------------- write progressive mesh
|
||||
|
||||
std::ofstream out( _ofname.c_str(), std::ios::binary );
|
||||
|
||||
if (!out)
|
||||
return false;
|
||||
|
||||
// always use little endian byte ordering
|
||||
bool swap = Endian::local() != Endian::LSB;
|
||||
|
||||
// write header
|
||||
out << "ProgMesh";
|
||||
IO::store( out, n_base_vertices, swap );
|
||||
IO::store( out, n_base_faces , swap );
|
||||
IO::store( out, pmi_.size() , swap );
|
||||
|
||||
Vec3f p;
|
||||
|
||||
// write base vertices
|
||||
for (i=0; i<n_base_vertices; ++i)
|
||||
{
|
||||
assert (!Base::mesh().status(vhandles[i]).deleted());
|
||||
p = vector_cast< Vec3f >( Base::mesh().point(vhandles[i]) );
|
||||
|
||||
IO::store( out, p, swap );
|
||||
}
|
||||
|
||||
|
||||
// write base faces
|
||||
for (f_it=Base::mesh().faces_begin(); f_it != f_end; ++f_it)
|
||||
{
|
||||
if (!Base::mesh().status(f_it).deleted())
|
||||
{
|
||||
typename Mesh::ConstFaceVertexIter fv_it(Base::mesh(), f_it.handle());
|
||||
|
||||
IO::store( out, Base::mesh().property( idx_, fv_it ) );
|
||||
IO::store( out, Base::mesh().property( idx_, ++fv_it ) );
|
||||
IO::store( out, Base::mesh().property( idx_, ++fv_it ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// write detail info
|
||||
for (r_it=pmi_.rbegin(); r_it!=r_end; ++r_it)
|
||||
{
|
||||
// store v0.pos, v1.idx, vl.idx, vr.idx
|
||||
IO::store( out, vector_cast<Vec3f>(Base::mesh().point(r_it->v0)));
|
||||
IO::store( out, Base::mesh().property( idx_, r_it->v1 ) );
|
||||
IO::store( out,
|
||||
r_it->vl.is_valid() ? Base::mesh().property(idx_, r_it->vl) : -1 );
|
||||
IO::store( out,
|
||||
r_it->vr.is_valid() ? Base::mesh().property(idx_, r_it->vr) : -1 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_DECIMATER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
|
||||
180
Tools/Decimater/ModProgMeshT.hh
Normal file
180
Tools/Decimater/ModProgMeshT.hh
Normal file
@@ -0,0 +1,180 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file ModProgMeshT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ModProgMeshT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_TOOLS_MODPROGMESHT_HH
|
||||
#define OPENMESH_TOOLS_MODPROGMESHT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/Decimater/ModBaseT.hh>
|
||||
#include <OpenMesh/Core/Utils/Property.hh>
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Decimater {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Collect progressive mesh information while decimating.
|
||||
*
|
||||
* The progressive mesh data is stored in an internal structure, which
|
||||
* can be evaluated after the decimation process and (!) before calling
|
||||
* the garbage collection of the decimated mesh.
|
||||
*/
|
||||
template <class DecimaterType>
|
||||
class ModProgMeshT : public ModBaseT<DecimaterType>
|
||||
{
|
||||
public:
|
||||
|
||||
DECIMATING_MODULE( ModProgMeshT, DecimaterType, ProgMesh );
|
||||
|
||||
/** Struct storing progressive mesh information
|
||||
* \see CollapseInfoT, ModProgMeshT
|
||||
*/
|
||||
struct Info
|
||||
{
|
||||
/// Initializing constructor copies appropriate handles from
|
||||
/// collapse information \c _ci.
|
||||
Info( const CollapseInfo& _ci )
|
||||
: v0(_ci.v0), v1(_ci.v1), vl(_ci.vl),vr(_ci.vr)
|
||||
{}
|
||||
|
||||
typename Mesh::VertexHandle v0; ///< See CollapseInfoT::v0
|
||||
typename Mesh::VertexHandle v1; ///< See CollapseInfoT::v1
|
||||
typename Mesh::VertexHandle vl; ///< See CollapseInfoT::vl
|
||||
typename Mesh::VertexHandle vr; ///< See CollapseInfoT::vr
|
||||
|
||||
};
|
||||
|
||||
/// Type of the list storing the progressive mesh info Info.
|
||||
typedef std::vector<Info> InfoList;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
ModProgMeshT( DecimaterType &_dec ) : Base(_dec, true)
|
||||
{
|
||||
Base::mesh().add_property( idx_ );
|
||||
}
|
||||
|
||||
|
||||
/// Destructor
|
||||
~ModProgMeshT()
|
||||
{
|
||||
Base::mesh().remove_property( idx_ );
|
||||
}
|
||||
|
||||
const InfoList& pmi() const
|
||||
{
|
||||
return pmi_;
|
||||
}
|
||||
|
||||
public: // inherited
|
||||
|
||||
|
||||
/// Stores collapse information in a queue.
|
||||
/// \see infolist()
|
||||
void postprocess_collapse(const CollapseInfo& _ci)
|
||||
{
|
||||
pmi_.push_back( Info( _ci ) );
|
||||
}
|
||||
|
||||
|
||||
bool is_binary(void) const { return true; }
|
||||
|
||||
|
||||
public: // specific methods
|
||||
|
||||
/** Write progressive mesh data to a file in proprietary binary format .pm.
|
||||
*
|
||||
* The methods uses the collected data to write a progressive mesh
|
||||
* file. It's a binary format with little endian byte ordering:
|
||||
*
|
||||
* - The first 8 bytes contain the word "ProgMesh".
|
||||
* - 32-bit int for the number of vertices \c NV in the base mesh.
|
||||
* - 32-bit int for the number of faces in the base mesh.
|
||||
* - 32-bit int for the number of halfedge collapses (now vertex splits)
|
||||
* - Positions of vertices of the base mesh (32-bit float triplets).<br>
|
||||
* \c [x,y,z][x,y,z]...
|
||||
* - Triplets of indices (32-bit int) for each triangle (index in the
|
||||
* list of vertices of the base mesh defined by the positions.<br>
|
||||
* \c [v0,v1,v2][v0,v1,v2]...
|
||||
* - For each collapse/split a detail information package made of
|
||||
* 3 32-bit floats for the positions of vertex \c v0, and 3 32-bit
|
||||
* int indices for \c v1, \c vl, and \c vr.
|
||||
* The index for \c vl or \c vr might be -1, if the face on this side
|
||||
* of the edge does not exists.
|
||||
*
|
||||
* \remark Write file before calling the garbage collection of the mesh.
|
||||
* \param _ofname Name of the file, where to write the progressive mesh
|
||||
* \return \c true on success of the operation, else \c false.
|
||||
*/
|
||||
bool write( const std::string& _ofname );
|
||||
/// Reference to collected information
|
||||
const InfoList& infolist() const { return pmi_; }
|
||||
|
||||
private:
|
||||
|
||||
// hide this method form user
|
||||
void set_binary(bool _b) {}
|
||||
|
||||
InfoList pmi_;
|
||||
VPropHandleT<int> idx_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_DECIMATER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODPROGMESH_CC)
|
||||
#define OSG_MODPROGMESH_TEMPLATES
|
||||
#include "ModProgMeshT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_TOOLS_PROGMESHT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
125
Tools/Decimater/ModQuadricT.cc
Normal file
125
Tools/Decimater/ModQuadricT.cc
Normal file
@@ -0,0 +1,125 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file ModQuadricT.cc
|
||||
Bodies of template member function.
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ModQuadric - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define OPENMESH_DECIMATER_MODQUADRIC_CC
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/Decimater/ModQuadricT.hh>
|
||||
|
||||
|
||||
//== NAMESPACE ===============================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Decimater { // BEGIN_NS_DECIMATER
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template<class DecimaterType>
|
||||
void
|
||||
ModQuadricT<DecimaterType>::
|
||||
initialize()
|
||||
{
|
||||
using Geometry::Quadricd;
|
||||
// alloc quadrics
|
||||
if (!quadrics_.is_valid())
|
||||
Base::mesh().add_property( quadrics_ );
|
||||
|
||||
// clear quadrics
|
||||
typename Mesh::VertexIter v_it = Base::mesh().vertices_begin(),
|
||||
v_end = Base::mesh().vertices_end();
|
||||
|
||||
for (; v_it != v_end; ++v_it)
|
||||
Base::mesh().property(quadrics_, v_it).clear();
|
||||
|
||||
// calc (normal weighted) quadric
|
||||
typename Mesh::FaceIter f_it = Base::mesh().faces_begin(),
|
||||
f_end = Base::mesh().faces_end();
|
||||
|
||||
typename Mesh::FaceVertexIter fv_it;
|
||||
typename Mesh::VertexHandle vh0, vh1, vh2;
|
||||
typedef Vec3d Vec3;
|
||||
double a,b,c,d, area;
|
||||
|
||||
for (; f_it != f_end; ++f_it)
|
||||
{
|
||||
fv_it = Base::mesh().fv_iter(f_it.handle());
|
||||
vh0 = fv_it.handle(); ++fv_it;
|
||||
vh1 = fv_it.handle(); ++fv_it;
|
||||
vh2 = fv_it.handle();
|
||||
|
||||
Vec3 v0, v1, v2;
|
||||
{
|
||||
using namespace OpenMesh;
|
||||
|
||||
v0 = vector_cast<Vec3>(Base::mesh().point(vh0));
|
||||
v1 = vector_cast<Vec3>(Base::mesh().point(vh1));
|
||||
v2 = vector_cast<Vec3>(Base::mesh().point(vh2));
|
||||
}
|
||||
|
||||
Vec3 n = (v1-v0) % (v2-v0);
|
||||
area = n.norm();
|
||||
if (area > FLT_MIN)
|
||||
{
|
||||
n /= area;
|
||||
area *= 0.5;
|
||||
}
|
||||
|
||||
a = n[0];
|
||||
b = n[1];
|
||||
c = n[2];
|
||||
d = -(vector_cast<Vec3>(Base::mesh().point(vh0))|n);
|
||||
|
||||
Quadricd q(a, b, c, d);
|
||||
q *= area;
|
||||
|
||||
Base::mesh().property(quadrics_, vh0) += q;
|
||||
Base::mesh().property(quadrics_, vh1) += q;
|
||||
Base::mesh().property(quadrics_, vh2) += q;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_DECIMATER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
178
Tools/Decimater/ModQuadricT.hh
Normal file
178
Tools/Decimater/ModQuadricT.hh
Normal file
@@ -0,0 +1,178 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ModQuadricT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OSG_MODQUADRIC_HH
|
||||
#define OSG_MODQUADRIC_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <float.h>
|
||||
#include <OpenMesh/Tools/Decimater/ModBaseT.hh>
|
||||
#include <OpenMesh/Core/Utils/Property.hh>
|
||||
#include <OpenMesh/Core/Utils/vector_cast.hh>
|
||||
#include <OpenMesh/Core/Geometry/QuadricT.hh>
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Decimater {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Mesh decimation module computing collapse priority based on error quadrics.
|
||||
*
|
||||
* This module can be used as a binary and non-binary module.
|
||||
*/
|
||||
template <class DecimaterType>
|
||||
class ModQuadricT : public ModBaseT<DecimaterType>
|
||||
{
|
||||
public:
|
||||
|
||||
// Defines the types Self, Handle, Base, Mesh, and CollapseInfo
|
||||
// and the memberfunction name()
|
||||
DECIMATING_MODULE( ModQuadricT, DecimaterType, Quadric );
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor
|
||||
* \internal
|
||||
*/
|
||||
ModQuadricT( DecimaterType &_dec )
|
||||
: Base(_dec, false)
|
||||
{
|
||||
unset_max_err();
|
||||
Base::mesh().add_property( quadrics_ );
|
||||
}
|
||||
|
||||
|
||||
/// Destructor
|
||||
virtual ~ModQuadricT()
|
||||
{
|
||||
Base::mesh().remove_property(quadrics_);
|
||||
}
|
||||
|
||||
|
||||
public: // inherited
|
||||
|
||||
/// Initalize the module and prepare the mesh for decimation.
|
||||
virtual void initialize(void);
|
||||
|
||||
/** Compute collapse priority based on error quadrics.
|
||||
*
|
||||
* \see ModBaseT::collapse_priority() for return values
|
||||
* \see set_max_err()
|
||||
*/
|
||||
virtual float collapse_priority(const CollapseInfo& _ci)
|
||||
{
|
||||
using namespace OpenMesh;
|
||||
|
||||
typedef Geometry::QuadricT<double> Q;
|
||||
|
||||
Q q = Base::mesh().property(quadrics_, _ci.v0);
|
||||
q += Base::mesh().property(quadrics_, _ci.v1);
|
||||
|
||||
double err = q(_ci.p1);
|
||||
|
||||
//min_ = std::min(err, min_);
|
||||
//max_ = std::max(err, max_);
|
||||
|
||||
//double err = q( p );
|
||||
|
||||
return float( (err < max_err_) ? err : float( Base::ILLEGAL_COLLAPSE ) );
|
||||
}
|
||||
|
||||
|
||||
/// Post-process halfedge collapse (accumulate quadrics)
|
||||
virtual void postprocess_collapse(const CollapseInfo& _ci)
|
||||
{
|
||||
Base::mesh().property(quadrics_, _ci.v1) +=
|
||||
Base::mesh().property(quadrics_, _ci.v0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public: // specific methods
|
||||
|
||||
/** Set maximum quadric error constraint and enable binary mode.
|
||||
* \param _err Maximum error allowed
|
||||
* \param _binary Let the module work in non-binary mode in spite of the
|
||||
* enabled constraint.
|
||||
* \see unset_max_err()
|
||||
*/
|
||||
void set_max_err(double _err, bool _binary=true)
|
||||
{
|
||||
max_err_ = _err;
|
||||
Base::set_binary(_binary);
|
||||
}
|
||||
|
||||
/// Unset maximum quadric error constraint and restore non-binary mode.
|
||||
/// \see set_max_err()
|
||||
void unset_max_err(void)
|
||||
{
|
||||
max_err_ = DBL_MAX;
|
||||
Base::set_binary(false);
|
||||
}
|
||||
|
||||
/// Return value of max. allowed error.
|
||||
double max_err() const { return max_err_; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// maximum quadric error
|
||||
double max_err_;
|
||||
|
||||
// this vertex property stores a quadric for each vertex
|
||||
VPropHandleT< Geometry::QuadricT<double> > quadrics_;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_DECIMATER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_DECIMATER_MODQUADRIC_CC)
|
||||
#define OSG_MODQUADRIC_TEMPLATES
|
||||
#include "ModQuadricT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OSG_MODQUADRIC_HH defined
|
||||
//=============================================================================
|
||||
|
||||
291
Tools/Decimater/ModRoundnessT.hh
Normal file
291
Tools/Decimater/ModRoundnessT.hh
Normal file
@@ -0,0 +1,291 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file ModRoundnessT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ModRoundnessT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_TOOLS_MODROUNDNESST_HH
|
||||
#define OPENMESH_TOOLS_MODROUNDNESST_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/Decimater/ModBaseT.hh>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(OM_CC_MSVC)
|
||||
# define OM_ENABLE_WARNINGS 4244
|
||||
# pragma warning(disable : OM_ENABLE_WARNINGS )
|
||||
#endif
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Decimater { // BEGIN_NS_DECIMATER
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Compute error value based on roundness criteria.
|
||||
*/
|
||||
template <class DecimaterType>
|
||||
class ModRoundnessT : public ModBaseT<DecimaterType>
|
||||
{
|
||||
public:
|
||||
DECIMATING_MODULE( ModRoundnessT, DecimaterType, Roundness );
|
||||
|
||||
public:
|
||||
|
||||
// typedefs
|
||||
typedef typename Mesh::Point Point;
|
||||
typedef typename vector_traits<Point>::value_type value_type;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
ModRoundnessT( DecimaterType &_dec ) :
|
||||
Base(_dec, false),
|
||||
min_r_(-1.0)
|
||||
{ }
|
||||
|
||||
/// Destructor
|
||||
~ModRoundnessT() { }
|
||||
|
||||
public: // inherited
|
||||
|
||||
/** Compute collapse priority due to roundness of triangle.
|
||||
*
|
||||
* The roundness is computed by dividing the radius of the
|
||||
* circumference by the length of the shortest edge. The result is
|
||||
* normalized.
|
||||
*
|
||||
* \return [0:1] or ILLEGAL_COLLAPSE in non-binary mode
|
||||
* \return LEGAL_COLLAPSE or ILLEGAL_COLLAPSE in binary mode
|
||||
* \see set_min_roundness()
|
||||
*/
|
||||
float collapse_priority(const CollapseInfo& _ci)
|
||||
{
|
||||
// using namespace OpenMesh;
|
||||
|
||||
typename Mesh::ConstVertexOHalfedgeIter voh_it(Base::mesh(), _ci.v0);
|
||||
double r;
|
||||
double priority = 0.0; //==LEGAL_COLLAPSE
|
||||
typename Mesh::FaceHandle fhC, fhB;
|
||||
Vec3f B,C;
|
||||
|
||||
if ( min_r_ < 0.0 ) // continues mode
|
||||
{
|
||||
C = vector_cast<Vec3f>(Base::mesh().point( Base::mesh().to_vertex_handle(voh_it)));
|
||||
fhC = Base::mesh().face_handle( voh_it.handle() );
|
||||
|
||||
for (++voh_it; voh_it; ++voh_it)
|
||||
{
|
||||
B = C;
|
||||
fhB = fhC;
|
||||
C = vector_cast<Vec3f>(Base::mesh().point(Base::mesh().to_vertex_handle(voh_it)));
|
||||
fhC = Base::mesh().face_handle( voh_it.handle() );
|
||||
|
||||
if ( fhB == _ci.fl || fhB == _ci.fr )
|
||||
continue;
|
||||
|
||||
// simulate collapse using position of v1
|
||||
r = roundness( vector_cast<Vec3f>(_ci.p1), B, C );
|
||||
|
||||
// return the maximum non-roundness
|
||||
priority = std::max( priority, (1.0-r) );
|
||||
|
||||
}
|
||||
}
|
||||
else // binary mode
|
||||
{
|
||||
C = vector_cast<Vec3f>(Base::mesh().point( Base::mesh().to_vertex_handle(voh_it)));
|
||||
fhC = Base::mesh().face_handle( voh_it.handle() );
|
||||
|
||||
for (++voh_it; voh_it && (priority==Base::LEGAL_COLLAPSE); ++voh_it)
|
||||
{
|
||||
B = C;
|
||||
fhB = fhC;
|
||||
C = vector_cast<Vec3f>(Base::mesh().point(Base::mesh().to_vertex_handle(voh_it)));
|
||||
fhC = Base::mesh().face_handle( voh_it.handle() );
|
||||
|
||||
if ( fhB == _ci.fl || fhB == _ci.fr )
|
||||
continue;
|
||||
|
||||
priority = ( (r=roundness( vector_cast<Vec3f>(_ci.p1), B, C )) < min_r_)
|
||||
? Base::ILLEGAL_COLLAPSE
|
||||
: Base::LEGAL_COLLAPSE;
|
||||
}
|
||||
}
|
||||
|
||||
return (float) priority;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public: // specific methods
|
||||
|
||||
void set_min_angle( float _angle, bool /* _binary=true */ )
|
||||
{
|
||||
assert( _angle > 0 && _angle < 60 );
|
||||
|
||||
_angle = float(M_PI * _angle /180.0);
|
||||
|
||||
Vec3f A,B,C;
|
||||
|
||||
A = Vec3f( 0, 0, 0);
|
||||
B = Vec3f( 2*cos(_angle), 0, 0);
|
||||
C = Vec3f( cos(_angle), sin(_angle), 0);
|
||||
|
||||
double r1 = roundness(A,B,C);
|
||||
|
||||
_angle = float(0.5 * ( M_PI - _angle ));
|
||||
|
||||
A = Vec3f( 0, 0, 0);
|
||||
B = Vec3f( 2*cos(_angle), 0, 0);
|
||||
C = Vec3f( cos(_angle), sin(_angle), 0);
|
||||
|
||||
double r2 = roundness(A,B,C);
|
||||
|
||||
set_min_roundness( value_type(std::min(r1,r2)), true );
|
||||
}
|
||||
|
||||
/** Set a minimum roundness value.
|
||||
* \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
|
||||
* and ILLEGAL_COLLAPSE else.
|
||||
*/
|
||||
void set_min_roundness( value_type _min_roundness, bool _binary=true )
|
||||
{
|
||||
assert( 0.0 <= _min_roundness && _min_roundness <= 1.0 );
|
||||
min_r_ = _min_roundness;
|
||||
Base::set_binary(_binary);
|
||||
}
|
||||
|
||||
/// Unset minimum value constraint and enable non-binary mode.
|
||||
void unset_min_roundness()
|
||||
{
|
||||
min_r_ = -1.0;
|
||||
Base::set_binary(false);
|
||||
}
|
||||
|
||||
// Compute a normalized roundness of a triangle ABC
|
||||
//
|
||||
// Having
|
||||
// A,B,C corner points of triangle
|
||||
// a,b,c the vectors BC,CA,AB
|
||||
// Area area of triangle
|
||||
//
|
||||
// then define
|
||||
//
|
||||
// radius of circumference
|
||||
// R := -----------------------
|
||||
// length of shortest edge
|
||||
//
|
||||
// ||a|| * ||b|| * ||c||
|
||||
// ---------------------
|
||||
// 4 * Area ||a|| * ||b|| * ||c||
|
||||
// = ----------------------- = -----------------------------------
|
||||
// min( ||a||,||b||,||c||) 4 * Area * min( ||a||,||b||,||c|| )
|
||||
//
|
||||
// ||a|| * ||b|| * ||c||
|
||||
// = -------------------------------------------------------
|
||||
// 4 * 1/2 * ||cross(B-A,C-A)|| * min( ||a||,||b||,||c|| )
|
||||
//
|
||||
// a'a * b'b * c'c
|
||||
// R<> = ----------------------------------------------------------
|
||||
// 4 * cross(B-A,C-A)'cross(B-A,C-A) * min( a'a, b'b, c'c )
|
||||
//
|
||||
// a'a * b'b * c'c
|
||||
// R = 1/2 * sqrt(---------------------------)
|
||||
// AA * min( a'a, b'b, c'c )
|
||||
//
|
||||
// At angle 60<36> R has it's minimum for all edge lengths = sqrt(1/3)
|
||||
//
|
||||
// Define normalized roundness
|
||||
//
|
||||
// nR := sqrt(1/3) / R
|
||||
//
|
||||
// AA * min( a'a, b'b, c'c )
|
||||
// = sqrt(4/3) * sqrt(---------------------------)
|
||||
// a'a * b'b * c'c
|
||||
//
|
||||
double roundness( const Vec3f& A, const Vec3f& B, const Vec3f &C )
|
||||
{
|
||||
const value_type epsilon = value_type(1e-15);
|
||||
|
||||
static const value_type sqrt43 = value_type(sqrt(4.0/3.0)); // 60<36>,a=b=c, **)
|
||||
|
||||
Vec3f vecAC = C-A;
|
||||
Vec3f vecAB = B-A;
|
||||
|
||||
// compute squared values to avoid sqrt-computations
|
||||
value_type aa = (B-C).sqrnorm();
|
||||
value_type bb = vecAC.sqrnorm();
|
||||
value_type cc = vecAB.sqrnorm();
|
||||
value_type AA = cross(vecAC,vecAB).sqrnorm(); // without factor 1/4 **)
|
||||
|
||||
if ( AA < epsilon )
|
||||
return 0.0;
|
||||
|
||||
double nom = AA * std::min( std::min(aa,bb),cc );
|
||||
double denom = aa * bb * cc;
|
||||
double nR = sqrt43 * sqrt(nom/denom);
|
||||
|
||||
return nR;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
value_type min_r_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_DECIMATER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#if defined(OM_CC_MSVC) && defined(OM_ENABLE_WARNINGS)
|
||||
# pragma warning(default : OM_ENABLE_WARNINGS)
|
||||
# undef OM_ENABLE_WARNINGS
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_TOOLS_PROGMESHT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
21
Tools/Decimater/calc-roundness.m
Normal file
21
Tools/Decimater/calc-roundness.m
Normal file
@@ -0,0 +1,21 @@
|
||||
# angle in degrees [0,60]
|
||||
#
|
||||
# compute roundness of first case
|
||||
|
||||
A = [ 0.0335717 0.0576863 -0.0503314 ]';
|
||||
B = [ 0.0325544 0.057614 -0.0504989 ]';
|
||||
C = [ 0.0323531 0.057051 -0.0504476 ]';
|
||||
|
||||
#
|
||||
vecAC=C-A;
|
||||
vecAB=B-A;
|
||||
|
||||
aa = norm(B-C)^2;
|
||||
bb = norm(vecAC)^2;
|
||||
cc = norm(vecAB)^2;
|
||||
AA = norm(cross(vecAC,vecAB))^2
|
||||
|
||||
nom = AA * min( aa, min(bb,cc) );
|
||||
denom = aa * bb * cc;
|
||||
nR1 = sqrt(4.0/3.0) * sqrt(nom/denom)
|
||||
|
||||
46
Tools/Decimater/roundness.m
Normal file
46
Tools/Decimater/roundness.m
Normal file
@@ -0,0 +1,46 @@
|
||||
# angle in degrees [0,60]
|
||||
# [replace :angle: with a value between 0 and 60]
|
||||
alpha_d = :angle:;
|
||||
|
||||
# compute roundness of first case
|
||||
|
||||
alpha = pi * alpha_d/180;
|
||||
|
||||
A = [ 0 0 0 ]';
|
||||
B = [ 2*cos(alpha) 0 0 ]';
|
||||
C = [ cos(alpha) sin(alpha) 0 ]';
|
||||
|
||||
#
|
||||
vecAC=C-A;
|
||||
vecAB=B-A;
|
||||
|
||||
aa = norm(B-C)^2;
|
||||
bb = norm(vecAC)^2;
|
||||
cc = norm(vecAB)^2;
|
||||
AA = norm(cross(vecAC,vecAB))^2;
|
||||
|
||||
nom = AA * min( aa, min(bb,cc) );
|
||||
denom = aa * bb * cc;
|
||||
nR1 = sqrt(4.0/3.0) * sqrt(nom/denom)
|
||||
|
||||
# compute roundness of 2nd case
|
||||
|
||||
alpha = pi * ((180-alpha_d)/2)/180;
|
||||
|
||||
A = [ 0 0 0 ]';
|
||||
B = [ 2*cos(alpha) 0 0 ]';
|
||||
C = [ cos(alpha) sin(alpha) 0 ]';
|
||||
|
||||
#
|
||||
vecAC=C-A;
|
||||
vecAB=B-A;
|
||||
|
||||
aa = norm(B-C)^2;
|
||||
bb = norm(vecAC)^2;
|
||||
cc = norm(vecAB)^2;
|
||||
AA = norm(cross(vecAC,vecAB))^2;
|
||||
|
||||
nom = AA * min( aa, min(bb,cc) );
|
||||
denom = aa * bb * cc;
|
||||
nR2 = sqrt(4.0/3.0) * sqrt(nom/denom)
|
||||
|
||||
8
Tools/Decimater/roundness.sh
Normal file
8
Tools/Decimater/roundness.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
i=0
|
||||
while ((i <= 60)); do
|
||||
cat roundness.m | perl -pe "s/:angle:/$i/" > tmp.m
|
||||
echo $i `octave -q tmp.m 2> /dev/null | grep -v "nR2" | perl -pe 's/^nR1 = (.*)$/\1/'`
|
||||
i=$((++i))
|
||||
done
|
||||
Reference in New Issue
Block a user