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:
19
Tools/ACGMakefile
Normal file
19
Tools/ACGMakefile
Normal file
@@ -0,0 +1,19 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS = Utils Decimater Subdivider VDPM Smoother
|
||||
|
||||
PACKAGES := math
|
||||
|
||||
PROJ_LIBS := OpenMesh/Core
|
||||
|
||||
CXXLIB_BUILD_LIB := yes
|
||||
|
||||
MODULES := cxxlib
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
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
|
||||
17
Tools/Kernel_OSG/ACGMakefile
Normal file
17
Tools/Kernel_OSG/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
|
||||
#==============================================================================
|
||||
209
Tools/Kernel_OSG/ArrayKernelT.hh
Normal file
209
Tools/Kernel_OSG/ArrayKernelT.hh
Normal file
@@ -0,0 +1,209 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS OSGArrayKernelT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef OPENMESH_KERNELOSG_ARRAY_KERNEL_HH
|
||||
#define OPENMEHS_KERNELOSG_ARRAY_KERNEL_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <vector>
|
||||
// --------------------
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/Utils/GenProg.hh>
|
||||
#include <OpenMesh/Core/Mesh/Kernels/ArrayKernel/ArrayKernelT.hh>
|
||||
// --------------------
|
||||
#include <OpenMesh/Tools/Kernel_OSG/AttribKernelT.hh>
|
||||
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Kernel_OSG {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** \ingroup mesh_kernels_group
|
||||
*
|
||||
* Mesh kernel using arrays for mesh item storage.
|
||||
*
|
||||
* This mesh kernel uses the OpenSG GeoProperties as container
|
||||
* to store the mesh items.
|
||||
*
|
||||
* \note You do not have to use this class directly, use the predefined
|
||||
* mesh-kernel combinations in \ref mesh_types_group.
|
||||
*/
|
||||
// \see OpenMesh::ArrayHandleT
|
||||
// \see \ref mesh_type
|
||||
|
||||
|
||||
template <class AttribKernel, class FinalMeshItems>
|
||||
class ArrayKernelT
|
||||
: public OpenMesh::ArrayKernelT<AttribKernel, FinalMeshItems>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ArrayKernelT<AttribKernel, FinalMeshItems> This;
|
||||
typedef OpenMesh::ArrayKernelT<AttribKernel, FinalMeshItems> Base;
|
||||
|
||||
// attributes
|
||||
// typedef typename Base::HasVertexNormals HasVertexNormals;
|
||||
// typedef typename Base::HasVertexColors HasVertexColors;
|
||||
// typedef typename Base::HasVertexTexCoords HasVertexTexCoords;
|
||||
// typedef typename Base::HasVertexStatus HasVertexStatus;
|
||||
typedef typename Base::HasPrevHalfedge HasPrevHalfedge;
|
||||
// typedef typename Base::HasEdgeStatus HasEdgeStatus;
|
||||
// typedef typename Base::HasFaceNormals HasFaceNormals;
|
||||
// typedef typename Base::HasFaceColors HasFaceColors;
|
||||
// typedef typename Base::HasFaceStatus HasFaceStatus;
|
||||
|
||||
// item types
|
||||
typedef typename FinalMeshItems::Vertex Vertex;
|
||||
typedef typename FinalMeshItems::Halfedge Halfedge;
|
||||
typedef typename FinalMeshItems::Edge Edge;
|
||||
typedef typename FinalMeshItems::Face Face;
|
||||
typedef typename FinalMeshItems::Point Point;
|
||||
typedef typename FinalMeshItems::Normal Normal;
|
||||
typedef typename FinalMeshItems::Color Color;
|
||||
typedef typename FinalMeshItems::TexCoord TexCoord;
|
||||
typedef typename FinalMeshItems::Scalar Scalar;
|
||||
|
||||
// // handles
|
||||
// typedef typename OpenMesh::VertexHandle VertexHandle;
|
||||
// typedef typename FinalMeshItems::HalfedgeHandle HalfedgeHandle;
|
||||
// typedef typename FinalMeshItems::EdgeHandle EdgeHandle;
|
||||
// typedef typename FinalMeshItems::FaceHandle FaceHandle;
|
||||
|
||||
// iterators
|
||||
typedef std::vector<Vertex> VertexContainer;
|
||||
typedef std::vector<Edge> EdgeContainer;
|
||||
typedef std::vector<Face> FaceContainer;
|
||||
typedef typename VertexContainer::iterator KernelVertexIter;
|
||||
typedef typename VertexContainer::const_iterator KernelConstVertexIter;
|
||||
typedef typename EdgeContainer::iterator KernelEdgeIter;
|
||||
typedef typename EdgeContainer::const_iterator KernelConstEdgeIter;
|
||||
typedef typename FaceContainer::iterator KernelFaceIter;
|
||||
typedef typename FaceContainer::const_iterator KernelConstFaceIter;
|
||||
|
||||
public:
|
||||
|
||||
ArrayKernelT() : Base()
|
||||
{ }
|
||||
|
||||
virtual ~ArrayKernelT()
|
||||
{ }
|
||||
|
||||
public: // replacements
|
||||
|
||||
void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh) {
|
||||
Base::set_halfedge_handle( _vh, _heh );
|
||||
}
|
||||
|
||||
void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh) {
|
||||
Base::set_halfedge_handle( _fh, _heh );
|
||||
osg_sync( _fh );
|
||||
}
|
||||
|
||||
void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh) {
|
||||
Base::set_next_halfedge_handle( _heh, _nheh );
|
||||
osg_sync( face_handle( _heh ) ); // ##Changed
|
||||
}
|
||||
|
||||
void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
|
||||
|
||||
protected:
|
||||
|
||||
bool osg_sync( FaceHandle _fh )
|
||||
{
|
||||
return _fh.is_valid()
|
||||
? osg_sync( _fh, typename Face::IsTriangle() )
|
||||
: false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool osg_sync( FaceHandle _fh, GenProg::Bool2Type<true> )
|
||||
{
|
||||
HalfedgeHandle hh( halfedge_handle(_fh) );
|
||||
if ( !hh.is_valid() ) return false;
|
||||
FaceHandle f1( _fh.idx() * 3 );
|
||||
set_face_indices( f1, to_vertex_handle(hh).idx() );
|
||||
|
||||
hh = next_halfedge_handle(hh);
|
||||
if ( !hh.is_valid() ) return false;
|
||||
FaceHandle f2( f1.idx()+1 );
|
||||
set_face_indices( f2, to_vertex_handle(hh).idx() );
|
||||
|
||||
hh = next_halfedge_handle(hh);
|
||||
if ( !hh.is_valid() ) return false;
|
||||
FaceHandle f3( f1.idx()+2 );
|
||||
set_face_indices( f3, to_vertex_handle(hh).idx() );
|
||||
|
||||
set_face_types ( _fh, GL_TRIANGLES );
|
||||
set_face_lengths( _fh, 3 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool osg_sync( FaceHandle _fh, GenProg::Bool2Type<false> )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <class AttribKernel, class FinalMeshItems>
|
||||
void
|
||||
ArrayKernelT<AttribKernel, FinalMeshItems>::
|
||||
garbage_collection(bool _v, bool _e, bool _f)
|
||||
{
|
||||
Base::garbage_collection(_v, _e, _f);
|
||||
for (size_t fidx=0; fidx < n_faces(); ++fidx)
|
||||
osg_sync( FaceHandle(fidx) );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Kernel_OSG
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_ARRAY_KERNEL_HH defined
|
||||
//=============================================================================
|
||||
638
Tools/Kernel_OSG/AttribKernelT.hh
Normal file
638
Tools/Kernel_OSG/AttribKernelT.hh
Normal file
@@ -0,0 +1,638 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#ifndef OPENMESH_KERNEL_OSG_ATTRIBKERNEL_HH
|
||||
#define OPENMESH_KENREL_OSG_ATTRIBKERNEL_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/Utils/GenProg.hh>
|
||||
#include <OpenMesh/Core/Attributes/Attributes.hh>
|
||||
// --------------------
|
||||
#include <OpenMesh/Tools/Kernel_OSG/PropertyT.hh>
|
||||
#include <OpenMesh/Tools/Kernel_OSG/PropertyKernel.hh>
|
||||
// --------------------
|
||||
#include <OpenSG/OSGGeometry.h>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Kernel_OSG {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/// This class adds the standard properties to the mesh type.
|
||||
template <class MeshItems>
|
||||
class AttribKernelT
|
||||
: public PropertyKernel< typename MeshItems::Face::IsTriangle >
|
||||
{
|
||||
protected:
|
||||
|
||||
typedef typename MeshItems::Face::IsTriangle IsTriMesh;
|
||||
typedef PropertyKernel< IsTriMesh > Base;
|
||||
|
||||
typedef typename Base::FPTypesHandle FPTypesHandle;
|
||||
typedef typename Base::FPLengthsHandle FPLengthsHandle;
|
||||
typedef typename Base::FIndicesHandle FIndicesHandle;
|
||||
|
||||
public:
|
||||
|
||||
//---------------------------------------------------------------- item types
|
||||
|
||||
typedef typename MeshItems::Vertex Vertex;
|
||||
typedef typename MeshItems::Halfedge Halfedge;
|
||||
typedef typename MeshItems::Edge Edge;
|
||||
typedef typename MeshItems::Face Face;
|
||||
|
||||
typedef typename MeshItems::Point Point;
|
||||
typedef typename MeshItems::Normal Normal;
|
||||
typedef typename MeshItems::Color Color;
|
||||
typedef typename MeshItems::TexCoord TexCoord;
|
||||
|
||||
typedef typename MeshItems::Scalar Scalar;
|
||||
|
||||
typedef Attributes::StatusInfo StatusInfo;
|
||||
|
||||
|
||||
enum Attribs {
|
||||
VAttribs = MeshItems::VAttribs,
|
||||
HAttribs = MeshItems::HAttribs,
|
||||
EAttribs = MeshItems::EAttribs,
|
||||
FAttribs = MeshItems::FAttribs,
|
||||
};
|
||||
|
||||
typedef GenProg::Bool2Type<(bool)(HAttribs & Attributes::PrevHalfedge)>
|
||||
HasPrevHalfedge;
|
||||
|
||||
//
|
||||
|
||||
typedef typename _t2vp< Point >::prop GeoPositions;
|
||||
typedef typename _t2vn< Normal >::prop GeoNormals;
|
||||
typedef typename _t2vc< Color >::prop GeoColors;
|
||||
typedef typename _t2vtc< TexCoord >::prop GeoTexCoords;
|
||||
|
||||
// typedef typename Base::GeoPTypes GeoPTypes;
|
||||
// typedef typename Base::GeoPLengths GeoPLengths;
|
||||
// typedef typename Base::GeoIndices GeoIndices;
|
||||
|
||||
//-------------------------------------------------- constructor / destructor
|
||||
|
||||
AttribKernelT() :
|
||||
|
||||
refcount_vnormals_(0),
|
||||
refcount_vcolors_(0),
|
||||
refcount_vtexcoords_(0),
|
||||
refcount_vstatus_(0),
|
||||
refcount_estatus_(0),
|
||||
refcount_hstatus_(0),
|
||||
refcount_fnormals_(0),
|
||||
refcount_fcolors_(0),
|
||||
refcount_fstatus_(0)
|
||||
|
||||
{
|
||||
points_ = add_vpositions( Point(), "v:points" );
|
||||
|
||||
face_types_ = add_fptypes();
|
||||
face_lengths_ = add_fplengths();
|
||||
face_indices_ = add_findices( face_types_, face_lengths_);
|
||||
|
||||
if (VAttribs & Attributes::Normal)
|
||||
request_vertex_normals();
|
||||
|
||||
if (VAttribs & Attributes::Color)
|
||||
request_vertex_colors();
|
||||
|
||||
if (VAttribs & Attributes::TexCoord)
|
||||
request_vertex_texcoords();
|
||||
|
||||
if (VAttribs & Attributes::Status)
|
||||
request_vertex_status();
|
||||
|
||||
if (EAttribs & Attributes::Status)
|
||||
request_edge_status();
|
||||
|
||||
if (FAttribs & Attributes::Normal)
|
||||
request_face_normals();
|
||||
|
||||
if (FAttribs & Attributes::Color)
|
||||
request_face_colors();
|
||||
|
||||
if (FAttribs & Attributes::Status)
|
||||
request_face_status();
|
||||
}
|
||||
|
||||
~AttribKernelT()
|
||||
{
|
||||
// should remove properties, but this will be done in
|
||||
// BaseKernel's destructor anyway...
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------- copy & assignement
|
||||
|
||||
AttribKernelT( const AttribKernelT& _rhs )
|
||||
: Base( _rhs )
|
||||
{
|
||||
operator=(_rhs);
|
||||
}
|
||||
|
||||
AttribKernelT& operator = ( const AttribKernelT& _rhs )
|
||||
{
|
||||
// remove old properties
|
||||
remove_property(points_);
|
||||
remove_property(vertex_normals_);
|
||||
remove_property(vertex_colors_);
|
||||
remove_property(vertex_texcoords_);
|
||||
remove_property(vertex_status_);
|
||||
remove_property(halfedge_status_);
|
||||
remove_property(edge_status_);
|
||||
remove_property(face_normals_);
|
||||
remove_property(face_colors_);
|
||||
remove_property(face_status_);
|
||||
|
||||
// parent deep-copies properties
|
||||
BaseKernel::operator=(_rhs);
|
||||
|
||||
// copy property handles
|
||||
points_ = _rhs.points_;
|
||||
vertex_normals_ = _rhs.vertex_normals_;
|
||||
vertex_colors_ = _rhs.vertex_colors_;
|
||||
vertex_texcoords_ = _rhs.vertex_texcoords_;
|
||||
vertex_status_ = _rhs.vertex_status_;
|
||||
halfedge_status_ = _rhs.halfedge_status_;
|
||||
edge_status_ = _rhs.edge_status_;
|
||||
face_normals_ = _rhs.face_normals_;
|
||||
face_colors_ = _rhs.face_colors_;
|
||||
face_status_ = _rhs.face_status_;
|
||||
|
||||
// copy ref-counts
|
||||
refcount_vnormals_ = _rhs.refcount_vnormals_;
|
||||
refcount_vcolors_ = _rhs.refcount_vcolors_;
|
||||
refcount_vtexcoords_ = _rhs.refcount_vtexcoords_;
|
||||
refcount_vstatus_ = _rhs.refcount_vstatus_;
|
||||
refcount_hstatus_ = _rhs.refcount_hstatus_;
|
||||
refcount_estatus_ = _rhs.refcount_estatus_;
|
||||
refcount_fnormals_ = _rhs.refcount_fnormals_;
|
||||
refcount_fcolors_ = _rhs.refcount_fcolors_;
|
||||
refcount_fstatus_ = _rhs.refcount_fstatus_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------ osg properties
|
||||
|
||||
//------------------------------ vertex property
|
||||
|
||||
typename GeoPositions::property_ptr_t osg_vpositions()
|
||||
{ return vpositions(points_).osg_ptr(); }
|
||||
|
||||
typename GeoNormals::property_ptr_t osg_vnormals()
|
||||
{ return vnormals(vertex_normals_).osg_ptr(); }
|
||||
|
||||
typename GeoColors::property_ptr_t osg_vcolors()
|
||||
{ return vcolors(vertex_colors_).osg_ptr(); }
|
||||
|
||||
typename GeoTexCoords::property_ptr_t osg_vtexcoords()
|
||||
{ return vtexcoords(vertex_texcoords_).osg_ptr(); }
|
||||
|
||||
//------------------------------ face property
|
||||
|
||||
GeoPTypes::property_ptr_t osg_ptypes()
|
||||
{ return fptypes( face_types_ ).osg_ptr(); }
|
||||
|
||||
GeoPLengths::property_ptr_t osg_plengths()
|
||||
{ return fplengths( face_lengths_ ).osg_ptr(); }
|
||||
|
||||
typename GeoIndices::property_ptr_t osg_indices()
|
||||
{ return findices( face_indices_ ).osg_ptr(); }
|
||||
|
||||
|
||||
//---------------------------------------- set osg geo property
|
||||
|
||||
//------------------------------ face property
|
||||
|
||||
void set_face_types( FaceHandle _fh, GeoPTypes::value_type _t)
|
||||
{ fptypes( face_types_, _fh ) = _t; }
|
||||
|
||||
void set_face_lengths( FaceHandle _fh, GeoPLengths::value_type _l)
|
||||
{ fplengths( face_lengths_, _fh ) = _l; }
|
||||
|
||||
void set_face_indices( FaceHandle _fh,
|
||||
typename GeoIndices::value_type _i)
|
||||
{ findices( face_indices_, _fh ) = _i; }
|
||||
|
||||
//--------------------------------------------------------- set/get properties
|
||||
|
||||
//---------------------------------------- points
|
||||
|
||||
const Point* points() const
|
||||
{ return vpositions( points_ ).data(); }
|
||||
|
||||
const Point& point(VertexHandle _vh) const
|
||||
{ return vpositions( points_, _vh); }
|
||||
|
||||
void set_point(VertexHandle _vh, const Point& _p)
|
||||
{ vpositions( points_, _vh ) = _p; }
|
||||
|
||||
|
||||
//---------------------------------------- vertex normals
|
||||
|
||||
const Normal* vertex_normals() const {
|
||||
return vnormals(vertex_normals_).data();
|
||||
}
|
||||
|
||||
const Normal& normal(VertexHandle _vh) const {
|
||||
return vnormals(vertex_normals_, _vh);
|
||||
}
|
||||
|
||||
void set_normal(VertexHandle _vh, const Normal& _n) {
|
||||
vnormals(vertex_normals_, _vh) = _n;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------- vertex colors
|
||||
|
||||
const Color* vertex_colors() const {
|
||||
return vcolors(vertex_colors_).data();
|
||||
}
|
||||
|
||||
const Color& color(VertexHandle _vh) const {
|
||||
return vcolors(vertex_colors_, _vh);
|
||||
}
|
||||
|
||||
void set_color(VertexHandle _vh, const Color& _c) {
|
||||
vcolors(vertex_colors_, _vh) = _c;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------- vertex texcoords
|
||||
|
||||
const TexCoord* texcoords() const {
|
||||
return vtexcoords(vertex_texcoords_).data();
|
||||
}
|
||||
|
||||
const TexCoord& texcoord(VertexHandle _vh) const {
|
||||
return vtexcoords(vertex_texcoords_, _vh);
|
||||
}
|
||||
|
||||
void set_texcoord(VertexHandle _vh, const TexCoord& _t) {
|
||||
vtexcoords(vertex_texcoords_, _vh) = _t;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------- vertex status
|
||||
|
||||
const StatusInfo& status(VertexHandle _vh) const {
|
||||
return property(vertex_status_, _vh);
|
||||
}
|
||||
|
||||
StatusInfo& status(VertexHandle _vh) {
|
||||
return property(vertex_status_, _vh);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------- edge status
|
||||
|
||||
const StatusInfo& status(HalfedgeHandle _eh) const {
|
||||
return property(halfedge_status_, _eh);
|
||||
}
|
||||
|
||||
StatusInfo& status(HalfedgeHandle _eh) {
|
||||
return property(halfedge_status_, _eh);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------- edge status
|
||||
|
||||
const StatusInfo& status(EdgeHandle _eh) const {
|
||||
return property(edge_status_, _eh);
|
||||
}
|
||||
|
||||
StatusInfo& status(EdgeHandle _eh) {
|
||||
return property(edge_status_, _eh);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------- face status
|
||||
|
||||
const StatusInfo& status(FaceHandle _fh) const {
|
||||
return property(face_status_, _fh);
|
||||
}
|
||||
|
||||
StatusInfo& status(FaceHandle _fh) {
|
||||
return property(face_status_, _fh);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------- face normals
|
||||
|
||||
const Normal& normal(FaceHandle _fh) const {
|
||||
return property(face_normals_, _fh);
|
||||
}
|
||||
|
||||
void set_normal(FaceHandle _fh, const Normal& _n) {
|
||||
property(face_normals_, _fh) = _n;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------- face colors
|
||||
|
||||
const Color& color(FaceHandle _fh) const {
|
||||
return property(face_colors_, _fh);
|
||||
}
|
||||
|
||||
void set_color(FaceHandle _fh, const Color& _c) {
|
||||
property(face_colors_, _fh) = _c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------ request / alloc properties
|
||||
|
||||
void request_vertex_normals() {
|
||||
if (!refcount_vnormals_++)
|
||||
vertex_normals_ = add_vnormals( Normal(), "v:normals" );
|
||||
}
|
||||
|
||||
void request_vertex_colors() {
|
||||
if (!refcount_vcolors_++)
|
||||
vertex_colors_ = add_vcolors( Color(), "v:colors" );
|
||||
}
|
||||
|
||||
void request_vertex_texcoords() {
|
||||
if (!refcount_vtexcoords_++)
|
||||
vertex_texcoords_ = add_vtexcoords( TexCoord(), "v:texcoords" );
|
||||
}
|
||||
|
||||
void request_vertex_status() {
|
||||
if (!refcount_vstatus_++)
|
||||
add_property( vertex_status_, "v:status" );
|
||||
}
|
||||
|
||||
void request_halfedge_status() {
|
||||
if (!refcount_hstatus_++)
|
||||
add_property( halfedge_status_, "h:status" );
|
||||
}
|
||||
|
||||
void request_edge_status() {
|
||||
if (!refcount_estatus_++)
|
||||
add_property( edge_status_, "e:status" );
|
||||
}
|
||||
|
||||
void request_face_normals() {
|
||||
if (!refcount_fnormals_++)
|
||||
add_property( face_normals_, "f:normals" );
|
||||
}
|
||||
|
||||
void request_face_colors() {
|
||||
if (!refcount_fcolors_++)
|
||||
add_property( face_colors_, "f:colors" );
|
||||
}
|
||||
|
||||
void request_face_status() {
|
||||
if (!refcount_fstatus_++)
|
||||
add_property( face_status_, "f:status" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------- release / free properties
|
||||
|
||||
void release_vertex_normals() {
|
||||
if ((refcount_vnormals_ > 0) && (! --refcount_vnormals_))
|
||||
remove_property(vertex_normals_);
|
||||
}
|
||||
|
||||
void release_vertex_colors() {
|
||||
if ((refcount_vcolors_ > 0) && (! --refcount_vcolors_))
|
||||
remove_property(vertex_colors_);
|
||||
}
|
||||
|
||||
void release_vertex_texcoords() {
|
||||
if ((refcount_vtexcoords_ > 0) && (! --refcount_vtexcoords_))
|
||||
remove_property(vertex_texcoords_);
|
||||
}
|
||||
|
||||
void release_vertex_status() {
|
||||
if ((refcount_vstatus_ > 0) && (! --refcount_vstatus_))
|
||||
remove_property(vertex_status_);
|
||||
}
|
||||
|
||||
void release_halfedge_status() {
|
||||
if ((refcount_hstatus_ > 0) && (! --refcount_hstatus_))
|
||||
remove_property(halfedge_status_);
|
||||
}
|
||||
|
||||
void release_edge_status() {
|
||||
if ((refcount_estatus_ > 0) && (! --refcount_estatus_))
|
||||
remove_property(edge_status_);
|
||||
}
|
||||
|
||||
void release_face_normals() {
|
||||
if ((refcount_fnormals_ > 0) && (! --refcount_fnormals_))
|
||||
remove_property(face_normals_);
|
||||
}
|
||||
|
||||
void release_face_colors() {
|
||||
if ((refcount_fcolors_ > 0) && (! --refcount_fcolors_))
|
||||
remove_property(face_colors_);
|
||||
}
|
||||
|
||||
void release_face_status() {
|
||||
if ((refcount_fstatus_ > 0) && (! --refcount_fstatus_))
|
||||
remove_property(face_status_);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------- static check for properties
|
||||
|
||||
typedef
|
||||
GenProg::Bool2Type<(bool)(VAttribs & Attributes::Normal)>
|
||||
HasVertexNormals;
|
||||
|
||||
typedef
|
||||
GenProg::Bool2Type<(bool)(VAttribs & Attributes::Color)>
|
||||
HasVertexColors;
|
||||
|
||||
typedef
|
||||
GenProg::Bool2Type<(bool)(VAttribs & Attributes::TexCoord)>
|
||||
HasVertexTexCoords;
|
||||
|
||||
typedef
|
||||
GenProg::Bool2Type<(bool)(VAttribs & Attributes::Status)>
|
||||
HasVertexStatus;
|
||||
|
||||
|
||||
typedef
|
||||
GenProg::Bool2Type<(bool)(HAttribs & Attributes::PrevHalfedge)>
|
||||
HasPrevHalfedge;
|
||||
|
||||
typedef
|
||||
GenProg::Bool2Type<(bool)(HAttribs & Attributes::Status)>
|
||||
HasHalfedgeStatus;
|
||||
|
||||
|
||||
typedef
|
||||
GenProg::Bool2Type<(bool)(EAttribs & Attributes::Status)>
|
||||
HasEdgeStatus;
|
||||
|
||||
|
||||
typedef
|
||||
GenProg::Bool2Type<(bool)(FAttribs & Attributes::Normal)>
|
||||
HasFaceNormals;
|
||||
|
||||
typedef
|
||||
GenProg::Bool2Type<(bool)(FAttribs & Attributes::Color)>
|
||||
HasFaceColors;
|
||||
|
||||
typedef
|
||||
GenProg::Bool2Type<(bool)(FAttribs & Attributes::Status)>
|
||||
HasFaceStatus;
|
||||
|
||||
|
||||
//---------------------------------------------- dynamic check for properties
|
||||
|
||||
bool has_vertex_normals() const { return vertex_normals_.is_valid(); }
|
||||
bool has_vertex_colors() const { return vertex_colors_.is_valid(); }
|
||||
bool has_vertex_texcoords() const { return vertex_texcoords_.is_valid(); }
|
||||
bool has_vertex_status() const { return vertex_status_.is_valid(); }
|
||||
bool has_edge_status() const { return edge_status_.is_valid(); }
|
||||
bool has_halfedge_status() const { return halfedge_status_.is_valid(); }
|
||||
bool has_face_normals() const { return face_normals_.is_valid(); }
|
||||
bool has_face_colors() const { return face_colors_.is_valid(); }
|
||||
bool has_face_status() const { return face_status_.is_valid(); }
|
||||
|
||||
static bool has_prev_halfedge() {
|
||||
return (HAttribs & Attributes::PrevHalfedge);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
osg::GeometryPtr createGeometryPtr()
|
||||
{
|
||||
using namespace osg;
|
||||
GeometryPtr geo=Geometry::create();
|
||||
return bind(geo) ? geo : NullFC;
|
||||
}
|
||||
|
||||
// create new geometry core from mesh
|
||||
bool bind( osg::GeometryPtr& _geo )
|
||||
{
|
||||
using namespace osg;
|
||||
|
||||
int Mask =
|
||||
Geometry::TypesFieldMask |
|
||||
Geometry::LengthsFieldMask |
|
||||
Geometry::IndicesFieldMask |
|
||||
Geometry::PositionsFieldMask;
|
||||
|
||||
if ( has_vertex_colors() )
|
||||
Mask |= Geometry::ColorsFieldMask;
|
||||
if ( has_vertex_normals() )
|
||||
Mask |= Geometry::NormalsFieldMask;
|
||||
if ( has_vertex_texcoords() )
|
||||
Mask |= Geometry::TexCoordsFieldMask;
|
||||
|
||||
// std::clog << "#ptypes : " << osg_ptypes()->getSize() << std::endl;
|
||||
// std::clog << "#plengths : " << osg_plengths()->getSize() << std::endl;
|
||||
// std::clog << "#indices : " << osg_indices()->getSize() << std::endl;
|
||||
// std::clog << "#points : " << osg_vpositions()->getSize() << std::endl;
|
||||
|
||||
beginEditCP( _geo, Mask );
|
||||
{
|
||||
addRefCP( osg_ptypes() );
|
||||
_geo->setTypes ( osg_ptypes() );
|
||||
addRefCP( osg_plengths() );
|
||||
_geo->setLengths ( osg_plengths() );
|
||||
addRefCP( osg_indices() );
|
||||
_geo->setIndices ( osg_indices() );
|
||||
addRefCP( osg_vpositions() );
|
||||
_geo->setPositions( osg_vpositions() );
|
||||
|
||||
if ( has_vertex_colors() )
|
||||
{
|
||||
addRefCP( osg_vcolors() );
|
||||
_geo->setColors ( osg_vcolors() );
|
||||
}
|
||||
if ( has_vertex_normals() )
|
||||
{
|
||||
addRefCP( osg_vnormals() );
|
||||
_geo->setNormals ( osg_vnormals() );
|
||||
}
|
||||
if ( has_vertex_texcoords() )
|
||||
{
|
||||
addRefCP( osg_vtexcoords() );
|
||||
_geo->setTexCoords( osg_vtexcoords() );
|
||||
}
|
||||
}
|
||||
endEditCP (_geo, Mask);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
VPropHandleT<Point> points_;
|
||||
VPropHandleT<Normal> vertex_normals_;
|
||||
VPropHandleT<Color> vertex_colors_;
|
||||
VPropHandleT<TexCoord> vertex_texcoords_;
|
||||
VPropHandleT<StatusInfo> vertex_status_;
|
||||
|
||||
FPTypesHandle face_types_;
|
||||
FPLengthsHandle face_lengths_;
|
||||
FIndicesHandle face_indices_;
|
||||
|
||||
EPropHandleT<StatusInfo> edge_status_;
|
||||
HPropHandleT<StatusInfo> halfedge_status_;
|
||||
|
||||
FPropHandleT<Normal> face_normals_;
|
||||
FPropHandleT<Color> face_colors_;
|
||||
FPropHandleT<StatusInfo> face_status_;
|
||||
|
||||
unsigned int refcount_vnormals_;
|
||||
unsigned int refcount_vcolors_;
|
||||
unsigned int refcount_vtexcoords_;
|
||||
unsigned int refcount_vstatus_;
|
||||
unsigned int refcount_estatus_;
|
||||
unsigned int refcount_hstatus_;
|
||||
unsigned int refcount_fnormals_;
|
||||
unsigned int refcount_fcolors_;
|
||||
unsigned int refcount_fstatus_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Kernel_OSG
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_KERNEL_OSG_ATTRIBKERNEL_HH defined
|
||||
//=============================================================================
|
||||
|
||||
249
Tools/Kernel_OSG/PropertyKernel.hh
Normal file
249
Tools/Kernel_OSG/PropertyKernel.hh
Normal file
@@ -0,0 +1,249 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#ifndef OPENMESH_KERNEL_OSG_PROPERTYKERNEL_HH
|
||||
#define OPENMESH_KENREL_OSG_PROPERTYKERNEL_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/Utils/Property.hh>
|
||||
#include <OpenMesh/Core/Mesh/Kernels/Common/BaseKernel.hh>
|
||||
// --------------------
|
||||
#include <OpenMesh/Tools/Kernel_OSG/PropertyT.hh>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Kernel_OSG {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Helper class, extending functionaliy of OpenMesh::BaseKernel to OpenSG
|
||||
* specific property adaptors.
|
||||
* \internal
|
||||
* \todo Follow coding convention and rename class to PropertyKernelT
|
||||
*/
|
||||
template < typename IsTriMesh >
|
||||
class PropertyKernel : public OpenMesh::BaseKernel
|
||||
{
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------- item types
|
||||
|
||||
typedef FPropHandleT<osg::UInt8> FPTypesHandle;
|
||||
typedef FPropHandleT<osg::UInt32> FPLengthsHandle;
|
||||
typedef FPropHandleT<osg::UInt32> FIndicesHandle;
|
||||
|
||||
typedef FP::GeoPTypesUI8 GeoPTypes;
|
||||
typedef FP::GeoPLengthsUI32 GeoPLengths;
|
||||
typedef FP::GeoIndicesUI32<IsTriMesh> GeoIndices;
|
||||
|
||||
// ------------------------------------------------- constructor / destructor
|
||||
|
||||
PropertyKernel() {}
|
||||
virtual ~PropertyKernel() { }
|
||||
|
||||
|
||||
protected: // ---------------------------------------------- add osg properties
|
||||
|
||||
// -------------------- vertex properties
|
||||
|
||||
template < typename T >
|
||||
VPropHandleT<T> add_vpositions( const T& _t, const std::string& _n )
|
||||
{ return VPropHandleT<T>(_add_vprop( new typename _t2vp<T>::prop(_n))); }
|
||||
|
||||
template < typename T >
|
||||
VPropHandleT<T> add_vnormals( const T& _t, const std::string& _n )
|
||||
{ return VPropHandleT<T>(_add_vprop( new typename _t2vn<T>::prop(_n) )); }
|
||||
|
||||
template < typename T >
|
||||
VPropHandleT<T> add_vcolors( const T& _t, const std::string& _n )
|
||||
{ return VPropHandleT<T>(_add_vprop( new typename _t2vc<T>::prop(_n) )); }
|
||||
|
||||
template < typename T >
|
||||
VPropHandleT<T> add_vtexcoords( const T& _t, const std::string& _n )
|
||||
{ return VPropHandleT<T>(_add_vprop( new typename _t2vtc<T>::prop(_n) )); }
|
||||
|
||||
|
||||
// -------------------- face properties
|
||||
|
||||
FPTypesHandle add_fptypes( )
|
||||
{ return FPTypesHandle(_add_fprop(new GeoPTypes)); }
|
||||
|
||||
FPLengthsHandle add_fplengths( )
|
||||
{ return FPLengthsHandle(_add_fprop(new GeoPLengths)); }
|
||||
|
||||
FIndicesHandle add_findices( FPTypesHandle _pht, FPLengthsHandle _phl )
|
||||
{
|
||||
GeoIndices *bp = new GeoIndices( fptypes(_pht), fplengths(_phl ) );
|
||||
return FIndicesHandle(_add_fprop( bp ) );
|
||||
}
|
||||
|
||||
protected: // ------------------------------------------- access osg properties
|
||||
|
||||
template < typename T >
|
||||
typename _t2vp<T>::prop& vpositions( VPropHandleT<T> _ph )
|
||||
{ return static_cast<typename _t2vp<T>::prop&>( _vprop( _ph ) ); }
|
||||
|
||||
template < typename T >
|
||||
const typename _t2vp<T>::prop& vpositions( VPropHandleT<T> _ph) const
|
||||
{ return static_cast<const typename _t2vp<T>::prop&>( _vprop( _ph ) ); }
|
||||
|
||||
|
||||
template < typename T >
|
||||
typename _t2vn<T>::prop& vnormals( VPropHandleT<T> _ph )
|
||||
{ return static_cast<typename _t2vn<T>::prop&>( _vprop( _ph ) ); }
|
||||
|
||||
template < typename T >
|
||||
const typename _t2vn<T>::prop& vnormals( VPropHandleT<T> _ph) const
|
||||
{ return static_cast<const typename _t2vn<T>::prop&>( _vprop( _ph ) ); }
|
||||
|
||||
|
||||
template < typename T >
|
||||
typename _t2vc<T>::prop& vcolors( VPropHandleT<T> _ph )
|
||||
{ return static_cast<typename _t2vc<T>::prop&>( _vprop( _ph ) ); }
|
||||
|
||||
template < typename T >
|
||||
const typename _t2vc<T>::prop& vcolors( VPropHandleT<T> _ph ) const
|
||||
{ return static_cast<const typename _t2vc<T>::prop&>( _vprop( _ph ) ); }
|
||||
|
||||
|
||||
template < typename T >
|
||||
typename _t2vtc<T>::prop& vtexcoords( VPropHandleT<T> _ph )
|
||||
{ return static_cast<typename _t2vtc<T>::prop&>( _vprop( _ph ) ); }
|
||||
|
||||
template < typename T >
|
||||
const typename _t2vtc<T>::prop& vtexcoords( VPropHandleT<T> _ph ) const
|
||||
{ return static_cast<const typename _t2vtc<T>::prop&>( _vprop( _ph ) ); }
|
||||
|
||||
|
||||
//
|
||||
GeoPTypes& fptypes( FPTypesHandle _ph )
|
||||
{ return static_cast<GeoPTypes&>( _fprop(_ph) ); }
|
||||
|
||||
const GeoPTypes& fptypes( FPTypesHandle _ph ) const
|
||||
{ return static_cast<const GeoPTypes&>( _fprop(_ph) ); }
|
||||
|
||||
|
||||
GeoPLengths& fplengths( FPLengthsHandle _ph )
|
||||
{ return static_cast<GeoPLengths&>( _fprop(_ph) ); }
|
||||
|
||||
const GeoPLengths& fplengths( FPLengthsHandle _ph ) const
|
||||
{ return static_cast<const GeoPLengths&>( _fprop(_ph) ); }
|
||||
|
||||
|
||||
GeoIndices& findices( FIndicesHandle _ph )
|
||||
{ return static_cast<GeoIndices&>( _fprop(_ph) ); }
|
||||
|
||||
const GeoIndices& findices( FIndicesHandle _ph ) const
|
||||
{ return static_cast<const GeoIndices&>( _fprop(_ph) ); }
|
||||
|
||||
|
||||
protected: // ------------------------------------ access osg property elements
|
||||
|
||||
template <typename T>
|
||||
T& vpositions( VPropHandleT<T> _ph, VertexHandle _vh )
|
||||
{ return vpositions(_ph)[_vh.idx()]; }
|
||||
|
||||
template <class T>
|
||||
const T& vpositions( VPropHandleT<T> _ph, VertexHandle _vh ) const
|
||||
{ return vpositions(_ph)[_vh.idx()]; }
|
||||
|
||||
|
||||
template < typename T>
|
||||
T& vnormals( VPropHandleT<T> _ph, VertexHandle _vh )
|
||||
{ return vnormals(_ph)[_vh.idx()]; }
|
||||
|
||||
template <class T>
|
||||
const T& vnormals( VPropHandleT<T> _ph, VertexHandle _vh ) const
|
||||
{ return vnormals(_ph)[_vh.idx()]; }
|
||||
|
||||
|
||||
template < typename T>
|
||||
T& vcolors( VPropHandleT<T> _ph, VertexHandle _vh )
|
||||
{ return vcolors(_ph)[_vh.idx()]; }
|
||||
|
||||
template <class T>
|
||||
const T& vcolors( VPropHandleT<T> _ph, VertexHandle _vh ) const
|
||||
{ return vcolors(_ph)[_vh.idx()]; }
|
||||
|
||||
|
||||
template < typename T>
|
||||
T& vtexcoords( VPropHandleT<T> _ph, VertexHandle _vh )
|
||||
{ return vtexcoords(_ph)[_vh.idx()]; }
|
||||
|
||||
template <class T>
|
||||
const T& vtexcoords( VPropHandleT<T> _ph, VertexHandle _vh ) const
|
||||
{ return vtexcoords(_ph)[_vh.idx()]; }
|
||||
|
||||
|
||||
// -------------------- access face property elements
|
||||
|
||||
FPTypesHandle::value_type&
|
||||
fptypes( FPTypesHandle _ph, FaceHandle _fh )
|
||||
{ return fptypes( _ph )[ _fh.idx()]; }
|
||||
|
||||
const FPTypesHandle::value_type&
|
||||
fptypes( FPTypesHandle _ph, FaceHandle _fh ) const
|
||||
{ return fptypes( _ph )[ _fh.idx()]; }
|
||||
|
||||
|
||||
FPLengthsHandle::value_type&
|
||||
fplengths( FPLengthsHandle _ph, FaceHandle _fh )
|
||||
{ return fplengths( _ph )[ _fh.idx()]; }
|
||||
|
||||
const FPLengthsHandle::value_type&
|
||||
fplengths( FPLengthsHandle _ph, FaceHandle _fh ) const
|
||||
{ return fplengths( _ph )[ _fh.idx()]; }
|
||||
|
||||
|
||||
FIndicesHandle::value_type&
|
||||
findices( FIndicesHandle _ph, FaceHandle _fh )
|
||||
{ return findices( _ph )[ _fh.idx()]; }
|
||||
|
||||
const FIndicesHandle::value_type&
|
||||
findices( FIndicesHandle _ph, FaceHandle _fh ) const
|
||||
{ return findices( _ph )[ _fh.idx()]; }
|
||||
|
||||
public:
|
||||
|
||||
void stats(void)
|
||||
{
|
||||
std::cout << "#V : " << n_vertices() << std::endl;
|
||||
std::cout << "#E : " << n_edges() << std::endl;
|
||||
std::cout << "#F : " << n_faces() << std::endl;
|
||||
property_stats();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Kernel_OSG
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_KERNEL_OSG_PROPERTYKERNEL_HH defined
|
||||
//=============================================================================
|
||||
|
||||
393
Tools/Kernel_OSG/PropertyT.hh
Normal file
393
Tools/Kernel_OSG/PropertyT.hh
Normal file
@@ -0,0 +1,393 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#ifndef OPENMESH_KERNEL_OSG_PROPERTYT_HH
|
||||
#define OPENMESH_KERNEL_OSG_PROPERTYT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/Attributes/Attributes.hh>
|
||||
#include <OpenMesh/Core/Mesh/Kernels/Common/BaseKernel.hh>
|
||||
#include <OpenMesh/Core/Utils/GenProg.hh>
|
||||
#include <OpenMesh/Core/Utils/Property.hh>
|
||||
//
|
||||
#include <OpenSG/OSGGeometry.h>
|
||||
//
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Kernel_OSG {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** Property adaptor for OpenSG GeoProperties
|
||||
*
|
||||
* This class bridges the interfaces of %OpenMesh properties and
|
||||
* OpenSG GeoProperties. The PropertyKernelT uses these adaptors to
|
||||
* add all necessary property functions to the kernel, while the
|
||||
* AttribKernelT extends the kernel with the standard properites.
|
||||
* Finally the ArrayKernelT completes the kernel build with a specialized
|
||||
* version of the garbage collections since the GeoIndices require
|
||||
* special handling.
|
||||
*
|
||||
* \attention Data will be shared with a geometry core when linking
|
||||
* a mesh with a OpenSG geometry node using Kernel_OSG::bind.
|
||||
* \internal
|
||||
*/
|
||||
template <typename GeoProperty>
|
||||
class oPropertyT : public BaseProperty
|
||||
{
|
||||
public:
|
||||
|
||||
// Type of the encapsulated OpenSG Geometry Property
|
||||
typedef GeoProperty property_t;
|
||||
typedef typename property_t::PtrType property_ptr_t;
|
||||
|
||||
typedef typename property_t::StoredFieldType field_t;
|
||||
typedef typename field_t::StoredType element_t;
|
||||
typedef typename field_t::StoredType value_type;
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
oPropertyT( property_ptr_t _geo_prop,
|
||||
const std::string& _name = "<unknown>" )
|
||||
: BaseProperty(_name), data_( _geo_prop )
|
||||
{
|
||||
osg_init_check();
|
||||
}
|
||||
|
||||
//
|
||||
oPropertyT( const std::string& _name = "<unknown>" )
|
||||
: BaseProperty(_name), data_(NULL)
|
||||
{
|
||||
data_ = property_t::create();
|
||||
|
||||
// make sure data_ is not null. In that case most probably
|
||||
// osg::osgInit() hasn't been executed!
|
||||
osg_init_check();
|
||||
}
|
||||
|
||||
///
|
||||
virtual ~oPropertyT()
|
||||
{ }
|
||||
|
||||
public:
|
||||
|
||||
oPropertyT& operator = (const oPropertyT& _rhs )
|
||||
{
|
||||
// Shallow copy! Remember, data_ is a osg pointer type, and the assign
|
||||
// operator makes a shallow copy!
|
||||
data_ = _rhs.data_;
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public: // interface BaseProperty
|
||||
|
||||
virtual void reserve(size_t _n) { data_->getField().reserve( _n ); }
|
||||
virtual void resize(size_t _n) { data_->resize( _n ); }
|
||||
virtual void push_back() { data_->resize( data_->size()+1 ); }
|
||||
virtual void swap(size_t _i0, size_t _i1)
|
||||
{ std::swap( data_->getField()[_i0], data_->getField()[_i1] ); }
|
||||
|
||||
virtual oPropertyT<property_t>* clone() const
|
||||
{
|
||||
oPropertyT<property_t> *dolly = new oPropertyT<property_t>();
|
||||
if (n_elements() > 0)
|
||||
{
|
||||
// OSGGeoProperty does not provide a deep copy
|
||||
dolly->resize(n_elements());
|
||||
element_t *begin = const_cast<element_t*>(data());
|
||||
element_t *end = begin+n_elements();
|
||||
element_t *dst = const_cast<element_t*>(dolly->data());
|
||||
std::copy( begin, end, dst );
|
||||
}
|
||||
return dolly;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual void set_persistent( bool _yn )
|
||||
{
|
||||
check_and_set_persistent<element_t>(_yn);
|
||||
}
|
||||
|
||||
virtual size_t n_elements() const
|
||||
{ return data_==osg::NullFC ? UnknownSize : data_->getSize(); }
|
||||
|
||||
virtual size_t element_size() const
|
||||
{ return UnknownSize; }
|
||||
|
||||
virtual size_t store( std::ostream& _ostr, bool _swap ) const
|
||||
{ return 0; }
|
||||
|
||||
virtual size_t restore( std::istream& _istr, bool _swap )
|
||||
{ return 0; }
|
||||
|
||||
|
||||
public: // OpenSG GeoPropertyInterface compatibility
|
||||
|
||||
void clear(void) { data_->clear(); }
|
||||
|
||||
|
||||
public: // access to OpenSG GeoProperty
|
||||
|
||||
property_ptr_t& osg_ptr()
|
||||
{ return data_; }
|
||||
|
||||
const property_ptr_t& osg_ptr() const
|
||||
{ return data_; }
|
||||
|
||||
|
||||
const element_t *data() const
|
||||
{ return &( (*this)[ 0 ] ); }
|
||||
|
||||
element_t& operator[](size_t idx)
|
||||
{ return data_->getField()[ idx ]; }
|
||||
|
||||
const element_t& operator[](size_t idx) const
|
||||
{ return data_->getField()[ idx ]; }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
property_ptr_t data_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void osg_init_check(void)
|
||||
{
|
||||
// make sure data_ is not null. In that case most probably
|
||||
// osg::osgInit() hasn't been executed!
|
||||
if ( data_ == osg::NullFC )
|
||||
throw std::logic_error("OpenSG Runtime Environment is not initialized: " \
|
||||
"Use osg::osgInit()");
|
||||
}
|
||||
|
||||
oPropertyT( const oPropertyT& );
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------- class ----
|
||||
|
||||
|
||||
// ------------------------------------------------------------ properties ----
|
||||
|
||||
/// OpenSG Vertex Properties Adaptors.
|
||||
namespace VP {
|
||||
|
||||
// ---------------------------------------- Positions
|
||||
/// \name GeoPositions
|
||||
//@{
|
||||
/// Adaptor for osg::GeoPositions
|
||||
typedef oPropertyT< osg::GeoPositions2d > GeoPositions2d;
|
||||
typedef oPropertyT< osg::GeoPositions2f > GeoPositions2f;
|
||||
typedef oPropertyT< osg::GeoPositions3d > GeoPositions3d;
|
||||
typedef oPropertyT< osg::GeoPositions3f > GeoPositions3f;
|
||||
typedef oPropertyT< osg::GeoPositions4d > GeoPositions4d;
|
||||
typedef oPropertyT< osg::GeoPositions4f > GeoPositions4f;
|
||||
//@}
|
||||
|
||||
// ---------------------------------------- Normals
|
||||
/// \name GeoNormals
|
||||
//@{
|
||||
/// Adaptor for osg::GeoNormals
|
||||
typedef oPropertyT< osg::GeoNormals3f > GeoNormals3f;
|
||||
//@}
|
||||
|
||||
// ---------------------------------------- TexCoords
|
||||
/// \name GeoTexCoords
|
||||
//@{
|
||||
/// Adaptor for osg::GeoTexCoords
|
||||
typedef oPropertyT< osg::GeoTexCoords1f > GeoTexCoords1f;
|
||||
typedef oPropertyT< osg::GeoTexCoords2f > GeoTexCoords2f;
|
||||
typedef oPropertyT< osg::GeoTexCoords3f > GeoTexCoords3f;
|
||||
//@}
|
||||
|
||||
// ---------------------------------------- Colors
|
||||
/// \name GeoColors
|
||||
//@{
|
||||
/// Adaptor for osg::GeoColors
|
||||
typedef oPropertyT< osg::GeoColors3f > GeoColors3f;
|
||||
typedef oPropertyT< osg::GeoColors3ub > GeoColors3ub;
|
||||
typedef oPropertyT< osg::GeoColors4f > GeoColors4f;
|
||||
typedef oPropertyT< osg::GeoColors4ub > GeoColors4ub;
|
||||
//@}
|
||||
|
||||
} // namespace VP
|
||||
|
||||
|
||||
/// OpenSG Face Properties Adaptors.
|
||||
namespace FP {
|
||||
|
||||
// ---------------------------------------- Types
|
||||
/// Adaptor for osg::GeoPTypesUI8
|
||||
typedef oPropertyT< osg::GeoPTypesUI8 > GeoPTypesUI8;
|
||||
|
||||
// ---------------------------------------- Lengths
|
||||
/// Adaptor for osg::GeoPLengthsUI32
|
||||
typedef oPropertyT< osg::GeoPLengthsUI32 > GeoPLengthsUI32;
|
||||
|
||||
// ---------------------------------------- Indices
|
||||
|
||||
typedef oPropertyT< osg::GeoIndicesUI32 > _GeoIndicesUI32;
|
||||
|
||||
/// Adaptor for osg::GeoIndicesUI32
|
||||
template < typename IsTriMesh >
|
||||
class GeoIndicesUI32 : public _GeoIndicesUI32
|
||||
{
|
||||
public: // ---------------------------------------- typedefs
|
||||
|
||||
typedef _GeoIndicesUI32 inherited_t;
|
||||
typedef typename inherited_t::property_ptr_t property_ptr_t;
|
||||
|
||||
public: // ---------------------------------------- ctor/dtor
|
||||
|
||||
GeoIndicesUI32( property_ptr_t _geo_prop,
|
||||
GeoPTypesUI8& _types,
|
||||
GeoPLengthsUI32& _lengths)
|
||||
: inherited_t( _geo_prop ), types_(_types), length_(_lengths)
|
||||
{ }
|
||||
|
||||
GeoIndicesUI32( GeoPTypesUI8& _types,
|
||||
GeoPLengthsUI32& _lengths)
|
||||
: inherited_t(), types_(_types), length_(_lengths)
|
||||
{ }
|
||||
|
||||
virtual ~GeoIndicesUI32()
|
||||
{ }
|
||||
|
||||
public: // ---------------------------------------- inherited
|
||||
|
||||
void swap(size_t _i0, size_t _i1) { _swap( _i0, _i1, IsTriMesh() ); }
|
||||
virtual void reserve(size_t _n) { _reserve( _n, IsTriMesh() ); }
|
||||
virtual void resize(size_t _n) { _resize( _n, IsTriMesh() ); }
|
||||
|
||||
protected: // ------------------------------------- swap
|
||||
|
||||
void _swap(size_t _i0, size_t _i1, GenProg::False )
|
||||
{
|
||||
omerr() << "Unsupported mesh type!" << std::endl;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void _swap(size_t _i0, size_t _i1, GenProg::True )
|
||||
{
|
||||
size_t j0 = _i0 + _i0 + _i0;
|
||||
size_t j1 = _i1 + _i1 + _i1;
|
||||
|
||||
inherited_t::swap( j0, j1 );
|
||||
inherited_t::swap( ++j0, ++j1 );
|
||||
inherited_t::swap( ++j0, ++j1 );
|
||||
}
|
||||
|
||||
virtual void _reserve(size_t _n, GenProg::True )
|
||||
{ inherited_t::reserve( _n + _n + _n ); }
|
||||
|
||||
virtual void _reserve(size_t _n, GenProg::False )
|
||||
{ assert( false ); }
|
||||
|
||||
virtual void _resize(size_t _n, GenProg::True )
|
||||
{ inherited_t::resize( _n + _n + _n ); }
|
||||
|
||||
virtual void _resize(size_t _n, GenProg::False )
|
||||
{ assert( false ); }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
GeoPTypesUI8 &types_;
|
||||
GeoPLengthsUI32 &length_;
|
||||
|
||||
};
|
||||
|
||||
} // namespace FP
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
|
||||
template <typename T> struct _t2vp;
|
||||
template <> struct _t2vp< osg::Pnt2f >
|
||||
{ typedef osg::GeoPositions2f type; typedef VP::GeoPositions2f prop; };
|
||||
|
||||
template <> struct _t2vp< osg::Pnt3f >
|
||||
{ typedef osg::GeoPositions3f type; typedef VP::GeoPositions3f prop; };
|
||||
|
||||
template <> struct _t2vp< osg::Pnt4f >
|
||||
{ typedef osg::GeoPositions4f type; typedef VP::GeoPositions4f prop; };
|
||||
|
||||
template <> struct _t2vp< osg::Pnt2d >
|
||||
{ typedef osg::GeoPositions2d type; typedef VP::GeoPositions2d prop; };
|
||||
template <> struct _t2vp< osg::Pnt3d >
|
||||
{ typedef osg::GeoPositions3d type; typedef VP::GeoPositions3d prop; };
|
||||
template <> struct _t2vp< osg::Pnt4d >
|
||||
{ typedef osg::GeoPositions4d type; typedef VP::GeoPositions4d prop; };
|
||||
|
||||
template <typename T> struct _t2vn;
|
||||
template <> struct _t2vn< osg::Vec3f >
|
||||
{ typedef osg::GeoNormals3f type; typedef VP::GeoNormals3f prop; };
|
||||
|
||||
template <typename T> struct _t2vc;
|
||||
template <> struct _t2vc< osg::Color3f >
|
||||
{ typedef osg::GeoColors3f type; typedef VP::GeoColors3f prop; };
|
||||
|
||||
template <> struct _t2vc< osg::Color4f >
|
||||
{ typedef osg::GeoColors4f type; typedef VP::GeoColors4f prop; };
|
||||
|
||||
template <> struct _t2vc< osg::Color3ub >
|
||||
{ typedef osg::GeoColors3ub type; typedef VP::GeoColors3ub prop; };
|
||||
|
||||
template <> struct _t2vc< osg::Color4ub >
|
||||
{ typedef osg::GeoColors4ub type; typedef VP::GeoColors3ub prop; };
|
||||
|
||||
template <typename T> struct _t2vtc;
|
||||
template <> struct _t2vtc< osg::Vec2f >
|
||||
{ typedef osg::GeoTexCoords2f type; typedef VP::GeoTexCoords2f prop; };
|
||||
|
||||
template <> struct _t2vtc< osg::Vec3f >
|
||||
{ typedef osg::GeoTexCoords3f type; typedef VP::GeoTexCoords3f prop; };
|
||||
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Kernel_OSG
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_PROPERTYT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
87
Tools/Kernel_OSG/Traits.hh
Normal file
87
Tools/Kernel_OSG/Traits.hh
Normal file
@@ -0,0 +1,87 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 Tools/Kernel_OSG/Traits.hh
|
||||
This file defines the default traits and some convenienve macros.
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS Traits
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_KERNEL_OSG_TRAITS_HH
|
||||
#define OPENMESH_KERNEL_OSG_TRAITS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <OpenMesh/Core/Mesh/Traits.hh>
|
||||
#include <OpenMesh/Tools/Kernel_OSG/VectorAdapter.hh>
|
||||
//
|
||||
#include <OpenSG/OSGGeometry.h>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Kernel_OSG {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Base class for all mesh traits using the OSGArrayKernelT.
|
||||
*
|
||||
* \see The Mesh docu section on \ref mesh_type.
|
||||
* \see Traits.hh for a list of macros for traits classes.
|
||||
*/
|
||||
struct Traits : DefaultTraits
|
||||
{
|
||||
typedef osg::Pnt3f Point;
|
||||
typedef osg::Color3ub Color;
|
||||
typedef osg::Vec3f Normal;
|
||||
typedef osg::Vec2f TexCoord;
|
||||
typedef osg::Vec3f::ValueType Scalar;
|
||||
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Kernel_OSG
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_TRAITS_HH defined
|
||||
//=============================================================================
|
||||
|
||||
99
Tools/Kernel_OSG/TriMesh_OSGArrayKernelT.hh
Normal file
99
Tools/Kernel_OSG/TriMesh_OSGArrayKernelT.hh
Normal file
@@ -0,0 +1,99 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS TriMesh_OSGArrayKernelT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef OPENMESH_KERNEL_OSG_TRIMESH_OSGARRAYKERNEL_HH
|
||||
#define OPENMESH_KERNEL_OSG_TRIMESH_OSGARRAYKERNEL_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
// --------------------
|
||||
#include <OpenMesh/Core/Mesh/TriMeshT.hh>
|
||||
#include <OpenMesh/Core/Mesh/Traits.hh>
|
||||
#include <OpenMesh/Core/Mesh/Kernels/ArrayKernel/ArrayKernelT.hh>
|
||||
#include <OpenMesh/Core/Mesh/Kernels/ArrayKernel/ArrayItems.hh>
|
||||
#include <OpenMesh/Core/Mesh/Kernels/Common/Handles.hh>
|
||||
#include <OpenMesh/Core/Mesh/Kernels/Common/FinalMeshItemsT.hh>
|
||||
// --------------------
|
||||
#include <OpenMesh/Tools/Kernel_OSG/VectorAdapter.hh>
|
||||
#include <OpenMesh/Tools/Kernel_OSG/Traits.hh>
|
||||
#include <OpenMesh/Tools/Kernel_OSG/ArrayKernelT.hh>
|
||||
// --------------------
|
||||
#include <OpenSG/OSGGeometry.h>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Kernel_OSG {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/// Helper class to create a TriMesh-type based on Kernel_OSG::ArrayKernelT
|
||||
template <class Traits>
|
||||
struct TriMesh_OSGArrayKernel_GeneratorT
|
||||
{
|
||||
typedef FinalMeshItemsT<ArrayItems, Traits, true> MeshItems;
|
||||
typedef AttribKernelT<MeshItems> AttribKernel;
|
||||
typedef ArrayKernelT<AttribKernel, MeshItems> MeshKernel;
|
||||
typedef TriMeshT<MeshKernel> Mesh;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** \ingroup mesh_types_group
|
||||
Triangle mesh based on the Kernel_OSG::ArrayKernelT.
|
||||
\see OpenMesh::TriMeshT
|
||||
\see OpenMesh::ArrayKernelT
|
||||
*/
|
||||
template <class Traits = Kernel_OSG::Traits>
|
||||
class TriMesh_OSGArrayKernelT
|
||||
: public TriMesh_OSGArrayKernel_GeneratorT<Traits>::Mesh
|
||||
{};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Kernel_OSG
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_KERNEL_OSG_TRIMESH_OSGARRAYKERNEL_HH
|
||||
//=============================================================================
|
||||
182
Tools/Kernel_OSG/VectorAdapter.hh
Normal file
182
Tools/Kernel_OSG/VectorAdapter.hh
Normal file
@@ -0,0 +1,182 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef OPENMESH_KERNEL_OSG_VECTORADAPTER_HH
|
||||
#define OPENMESH_KERNEL_OSG_VECTORADAPTER_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenSG/OSGGeometry.h>
|
||||
#include <OpenMesh/Core/Utils/vector_cast.hh>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
// ----------------------------------------------------------------- class ----
|
||||
|
||||
#define OSG_VECTOR_TRAITS( VecType ) \
|
||||
template <> struct vector_traits< VecType > { \
|
||||
typedef VecType vector_type; \
|
||||
typedef vector_type::ValueType value_type; \
|
||||
typedef GenProg::Int2Type< vector_type::_iSize > typed_size; \
|
||||
\
|
||||
static const size_t size_ = vector_type::_iSize; \
|
||||
static size_t size() { return size_; } \
|
||||
}
|
||||
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Pnt4f );
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Pnt3f );
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Pnt2f );
|
||||
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Vec4f );
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Vec3f );
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Vec2f );
|
||||
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Pnt4d );
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Pnt3d );
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Pnt2d );
|
||||
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Vec4d );
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Vec3d );
|
||||
|
||||
/// Vector traits for OpenSG vector type
|
||||
OSG_VECTOR_TRAITS( osg::Vec4ub );
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#define OSG_COLOR_TRAITS( VecType, N ) \
|
||||
template <> struct vector_traits< VecType > { \
|
||||
typedef VecType vector_type; \
|
||||
typedef vector_type::ValueType value_type; \
|
||||
typedef GenProg::Int2Type< N > typed_size; \
|
||||
\
|
||||
static const size_t size_ = N; \
|
||||
static size_t size() { return size_; } \
|
||||
}
|
||||
|
||||
|
||||
/// Vector traits for OpenSG color type
|
||||
OSG_COLOR_TRAITS( osg::Color3ub, 3 );
|
||||
/// Vector traits for OpenSG color type
|
||||
OSG_COLOR_TRAITS( osg::Color4ub, 4 );
|
||||
/// Vector traits for OpenSG color type
|
||||
OSG_COLOR_TRAITS( osg::Color3f, 3 );
|
||||
/// Vector traits for OpenSG color type
|
||||
OSG_COLOR_TRAITS( osg::Color4f, 4 );
|
||||
|
||||
#undef OSG_VECTOR_TRAITS
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
#if 1
|
||||
#define PNT2VEC_CASTER( DST, SRC ) \
|
||||
template <> struct vector_caster< DST, SRC > { \
|
||||
typedef DST dst_t; \
|
||||
typedef SRC src_t; \
|
||||
typedef const dst_t& return_type; \
|
||||
inline static return_type cast( const src_t& _src ) {\
|
||||
return _src.subZero(); \
|
||||
} \
|
||||
}
|
||||
|
||||
/// convert Pnt3f to Vec3f
|
||||
PNT2VEC_CASTER( osg::Vec3f, osg::Pnt3f );
|
||||
|
||||
/// convert Pnt4f to Vec4f
|
||||
PNT2VEC_CASTER( osg::Vec4f, osg::Pnt4f );
|
||||
|
||||
/// convert Pnt3d to Vec3d
|
||||
PNT2VEC_CASTER( osg::Vec3d, osg::Pnt3d );
|
||||
|
||||
/// convert Pnt4d to Vec4d
|
||||
PNT2VEC_CASTER( osg::Vec4d, osg::Pnt4d );
|
||||
|
||||
#undef PNT2VEC
|
||||
#else
|
||||
|
||||
template <>
|
||||
struct vector_caster< osg::Vec3f, osg::Pnt3f >
|
||||
{
|
||||
typedef osg::Vec3f dst_t;
|
||||
typedef osg::Pnt3f src_t;
|
||||
|
||||
typedef const dst_t& return_type;
|
||||
inline static return_type cast( const src_t& _src )
|
||||
{
|
||||
std::cout << "casting Pnt3f to Vec3f\n";
|
||||
return _src.subZero();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
// ----------------------------------------
|
||||
|
||||
//@{
|
||||
/// Adapter for osg vector member computing a scalar product
|
||||
inline
|
||||
osg::Vec3f::ValueType dot( const osg::Vec3f &_v1, const osg::Vec3f &_v2 )
|
||||
{ return _v1.dot(_v2); }
|
||||
|
||||
|
||||
inline
|
||||
osg::Vec3f::ValueType dot( const osg::Vec3f &_v1, const osg::Pnt3f &_v2 )
|
||||
{ return _v1.dot(_v2); }
|
||||
|
||||
|
||||
inline
|
||||
osg::Vec2f::ValueType dot( const osg::Vec2f &_v1, const osg::Vec2f &_v2 )
|
||||
{ return _v1.dot(_v2); }
|
||||
|
||||
|
||||
inline
|
||||
osg::Vec3f cross( const osg::Vec3f &_v1, const osg::Vec3f &_v2 )
|
||||
{ return _v1.cross(_v2); }
|
||||
//@}
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_VECTORADAPTER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
301
Tools/Kernel_OSG/bindT.hh
Normal file
301
Tools/Kernel_OSG/bindT.hh
Normal file
@@ -0,0 +1,301 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 bindT.hh
|
||||
|
||||
Bind an OpenMesh to a OpenSG geometry node. Be aware that due to
|
||||
this link the geometry node maybe modified. For instance triangle
|
||||
strips are converted to regular triangles.
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS Traits
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_KERNEL_OSG_BINDT_HH
|
||||
#define OPENMESH_KERNEL_OSG_BINDT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
//
|
||||
#include <OpenMesh/Core/Mesh/TriMeshT.hh>
|
||||
#include <OpenMesh/Core/Utils/color_cast.hh>
|
||||
#include <OpenMesh/Tools/Utils/GLConstAsString.hh>
|
||||
#include <OpenSG/OSGGeometry.h>
|
||||
//
|
||||
#include "color_cast.hh"
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Kernel_OSG {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
inline
|
||||
bool type_is_valid( unsigned char _t )
|
||||
{
|
||||
return _t == GL_TRIANGLES
|
||||
|| _t == GL_TRIANGLE_STRIP
|
||||
|| _t == GL_QUADS
|
||||
|| _t == GL_POLYGON;
|
||||
}
|
||||
|
||||
|
||||
/** Bind a OpenSG geometry to a mesh.
|
||||
*
|
||||
* \param _mesh The mesh object to bind the geometry to.
|
||||
* \param _geo The geometry object to bind.
|
||||
* \return true if the connection has been established else false.
|
||||
*/
|
||||
template < typename Mesh > inline
|
||||
bool bind( osg::GeometryPtr& _geo, Mesh& _mesh )
|
||||
{
|
||||
_geo = _mesh.createGeometryPtr();
|
||||
}
|
||||
|
||||
/** Bind a mesh object to geometry. The binder is able to handle
|
||||
* non-indexed and indexed geometry. Multi-indexed geometry is not
|
||||
* supported.
|
||||
*
|
||||
* \param _mesh The mesh object to bind.
|
||||
* \param _geo The geometry object to bind to.
|
||||
* \return true if the connection has been established else false.
|
||||
*/
|
||||
template < typename Mesh > inline
|
||||
bool bind( Mesh& _mesh, osg::GeometryPtr& _geo )
|
||||
{
|
||||
using namespace OpenMesh;
|
||||
using namespace osg;
|
||||
using namespace std;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
// pre-check if types are supported
|
||||
|
||||
GeoPTypesPtr types = _geo->getTypes();
|
||||
|
||||
if ( (size_t)count_if( types->getData(), types->getData()+types->size(),
|
||||
ptr_fun(type_is_valid) ) != (size_t)types->size() )
|
||||
return false;
|
||||
|
||||
// pre-check if it is a multi-indexed geometry, which is not supported!
|
||||
|
||||
if ( _geo->getIndexMapping().getSize() > 1 )
|
||||
{
|
||||
omerr << "OpenMesh::Kernel_OSG::bind(): Multi-indexed geometry is not supported!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// create shortcuts
|
||||
|
||||
GeoPLengthsPtr lengths = _geo->getLengths();
|
||||
GeoIndicesPtr indices = _geo->getIndices();
|
||||
GeoPositionsPtr pos = _geo->getPositions();
|
||||
GeoNormalsPtr normals = _geo->getNormals();
|
||||
GeoColorsPtr colors = _geo->getColors();
|
||||
|
||||
|
||||
// -------------------- now convert everything to polygon/triangles
|
||||
|
||||
size_t tidx, bidx; // types; base index into indices
|
||||
vector< VertexHandle > vhandles;
|
||||
|
||||
// ---------- initialize geometry
|
||||
|
||||
{
|
||||
VertexHandle vh;
|
||||
typedef typename Mesh::Color color_t;
|
||||
|
||||
bool bind_normal = (normals!=NullFC) && _mesh.has_vertex_normals();
|
||||
bool bind_color = (colors !=NullFC) && _mesh.has_vertex_colors();
|
||||
|
||||
for (bidx=0; bidx < pos->size(); ++bidx)
|
||||
{
|
||||
vh = _mesh.add_vertex( pos->getValue(bidx) );
|
||||
if ( bind_normal )
|
||||
_mesh.set_normal(vh, normals->getValue(bidx));
|
||||
if ( bind_color )
|
||||
_mesh.set_color(vh, color_cast<color_t>(colors->getValue(bidx)));
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- create topology
|
||||
|
||||
FaceHandle fh;
|
||||
|
||||
size_t max_bidx = indices != NullFC ? indices->size() : pos->size();
|
||||
|
||||
for (bidx=tidx=0; ok && tidx<types->size() && bidx < max_bidx; ++tidx)
|
||||
{
|
||||
switch( types->getValue(tidx) )
|
||||
{
|
||||
case GL_TRIANGLES:
|
||||
vhandles.resize(3);
|
||||
for(size_t lidx=0; lidx < lengths->getValue(tidx)-2; lidx+=3)
|
||||
{
|
||||
if (indices == NullFC ) {
|
||||
vhandles[0] = VertexHandle(bidx+lidx);
|
||||
vhandles[1] = VertexHandle(bidx+lidx+1);
|
||||
vhandles[2] = VertexHandle(bidx+lidx+2);
|
||||
}
|
||||
else {
|
||||
vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
|
||||
vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
|
||||
vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
|
||||
}
|
||||
|
||||
if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
|
||||
{
|
||||
// if fh is complex try swapped order
|
||||
swap(vhandles[2], vhandles[1]);
|
||||
fh = _mesh.add_face( vhandles );
|
||||
}
|
||||
ok = fh.is_valid();
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TRIANGLE_STRIP:
|
||||
vhandles.resize(3);
|
||||
for (size_t lidx=0; lidx < lengths->getValue(tidx)-2; ++lidx)
|
||||
{
|
||||
if (indices == NullFC ) {
|
||||
vhandles[0] = VertexHandle(bidx+lidx);
|
||||
vhandles[1] = VertexHandle(bidx+lidx+1);
|
||||
vhandles[2] = VertexHandle(bidx+lidx+2);
|
||||
}
|
||||
else {
|
||||
vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
|
||||
vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
|
||||
vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
|
||||
}
|
||||
|
||||
if (vhandles[0]!=vhandles[2] &&
|
||||
vhandles[0]!=vhandles[1] &&
|
||||
vhandles[1]!=vhandles[2])
|
||||
{
|
||||
// if fh is complex try swapped order
|
||||
bool swapped(false);
|
||||
|
||||
if (lidx % 2) // odd numbered triplet must be reordered
|
||||
swap(vhandles[2], vhandles[1]);
|
||||
|
||||
if ( !(fh = _mesh.add_face( vhandles )).is_valid() )
|
||||
{
|
||||
omlog << "OpenMesh::Kernel_OSG::bind(): complex entity!\n";
|
||||
|
||||
swap(vhandles[2], vhandles[1]);
|
||||
fh = _mesh.add_face( vhandles );
|
||||
swapped = true;
|
||||
}
|
||||
ok = fh.is_valid();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_QUADS:
|
||||
vhandles.resize(4);
|
||||
for(size_t nf=_mesh.n_faces(), lidx=0;
|
||||
lidx < lengths->getValue(tidx)-3; lidx+=4)
|
||||
{
|
||||
if (indices == NullFC ) {
|
||||
vhandles[0] = VertexHandle(bidx+lidx);
|
||||
vhandles[1] = VertexHandle(bidx+lidx+1);
|
||||
vhandles[2] = VertexHandle(bidx+lidx+2);
|
||||
vhandles[3] = VertexHandle(bidx+lidx+3);
|
||||
}
|
||||
else {
|
||||
vhandles[0] = VertexHandle(indices->getValue(bidx+lidx ) );
|
||||
vhandles[1] = VertexHandle(indices->getValue(bidx+lidx+1) );
|
||||
vhandles[2] = VertexHandle(indices->getValue(bidx+lidx+2) );
|
||||
vhandles[3] = VertexHandle(indices->getValue(bidx+lidx+3) );
|
||||
}
|
||||
|
||||
fh = _mesh.add_face( vhandles );
|
||||
ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==(nf+2)))
|
||||
|| fh.is_valid();
|
||||
nf = _mesh.n_faces();
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_POLYGON:
|
||||
{
|
||||
size_t ne = lengths->getValue(tidx);
|
||||
size_t nf = _mesh.n_faces();
|
||||
|
||||
vhandles.resize(ne);
|
||||
|
||||
for(size_t lidx=0; lidx < ne; ++lidx)
|
||||
vhandles[lidx] = (indices == NullFC)
|
||||
? VertexHandle(bidx+lidx)
|
||||
: VertexHandle(indices->getValue(bidx+lidx) );
|
||||
|
||||
fh = _mesh.add_face( vhandles );
|
||||
ok = ( Mesh::Face::is_triangle() && (_mesh.n_faces()==nf+ne-2) )
|
||||
|| fh.is_valid();
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cerr << "Warning! Skipping unsupported type "
|
||||
<< types->getValue(tidx) << " '"
|
||||
<< Utils::GLenum_as_string( types->getValue(tidx) ) << "'\n";
|
||||
}
|
||||
|
||||
// update base index into indices for next face type
|
||||
bidx += lengths->getValue(tidx);
|
||||
}
|
||||
|
||||
if (ok)
|
||||
ok=_mesh.bind(_geo);
|
||||
else
|
||||
_mesh.clear();
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Kernel_OSG
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_KERNEL_OSG_BINDT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
43
Tools/Kernel_OSG/color_cast.hh
Normal file
43
Tools/Kernel_OSG/color_cast.hh
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef OPENMESH_KERNEL_OSG_COLOR_CAST_HH
|
||||
#define OPENMESH_KERNEL_OSG_COLOR_CAST_HH
|
||||
|
||||
#include <algorithm>
|
||||
#include <OpenMesh/Core/Utils/color_cast.hh>
|
||||
#include <OpenSG/OSGGeometry.h>
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
/// Helper struct
|
||||
/// \internal
|
||||
template <>
|
||||
struct color_caster<osg::Color3ub,osg::Color3f>
|
||||
{
|
||||
typedef osg::Color3ub return_type;
|
||||
typedef unsigned char ub;
|
||||
|
||||
inline static return_type cast(const osg::Color3f& _src)
|
||||
{
|
||||
return return_type( (ub)std::min((_src[0]* 255.0f + 0.5f),255.0f),
|
||||
(ub)std::min((_src[1]* 255.0f + 0.5f),255.0f),
|
||||
(ub)std::min((_src[2]* 255.0f + 0.5f),255.0f) );
|
||||
}
|
||||
};
|
||||
|
||||
/// Helper struct
|
||||
/// \internal
|
||||
template <>
|
||||
struct color_caster<osg::Color3f,osg::Color3ub>
|
||||
{
|
||||
typedef osg::Color3f return_type;
|
||||
|
||||
inline static return_type cast(const osg::Color3ub& _src)
|
||||
{
|
||||
return return_type( (float)(_src[0] / 255.0f ),
|
||||
(float)(_src[1] / 255.0f ),
|
||||
(float)(_src[2] / 255.0f ) );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace OpenMesh
|
||||
|
||||
#endif // OPENMESH_KERNEL_OSG_COLOR_CAST_HH
|
||||
444
Tools/OpenMesh_Tools.vcproj
Executable file
444
Tools/OpenMesh_Tools.vcproj
Executable file
@@ -0,0 +1,444 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="OpenMesh_Tools"
|
||||
ProjectGUID="{682CF0FD-24AD-44AC-8438-A6BECD7ABE1C}"
|
||||
RootNamespace="OpenMesh_Tools"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="0"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;DEBUG;_USE_MATH_DEFINES"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="false"
|
||||
DisableLanguageExtensions="false"
|
||||
ForceConformanceInForLoopScope="true"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="1"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/Tools.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
AdditionalIncludeDirectories="..\.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_USE_MATH_DEFINES"
|
||||
StringPooling="false"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="false"
|
||||
DisableLanguageExtensions="false"
|
||||
ForceConformanceInForLoopScope="true"
|
||||
RuntimeTypeInfo="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/Tools.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Smoother"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Smoother\JacobiLaplaceSmootherT.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Smoother\JacobiLaplaceSmootherT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Smoother\LaplaceSmootherT.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Smoother\LaplaceSmootherT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Smoother\smooth_mesh.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Smoother\SmootherT.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Smoother\SmootherT.hh"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Utils"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Utils\Config.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\conio.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\conio.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\getopt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\getopt.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\GLConstAsString.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\Gnuplot.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\Gnuplot.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\HeapT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\MeshCheckerT.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\MeshCheckerT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\NumLimitsT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\StripifierT.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\StripifierT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\TestingFramework.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\Timer.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
DisableLanguageExtensions="false"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
DisableLanguageExtensions="false"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils\Timer.hh"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Decimater"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Decimater\CollapseInfoT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Decimater\DecimaterT.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Decimater\DecimaterT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Decimater\ModBaseT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Decimater\ModIndependentSetsT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Decimater\ModNormalFlippingT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Decimater\ModProgMeshT.cc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Decimater\ModProgMeshT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Decimater\ModQuadricT.cc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Decimater\ModQuadricT.hh"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Decimater\ModRoundnessT.hh"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
183
Tools/Smoother/JacobiLaplaceSmootherT.cc
Normal file
183
Tools/Smoother/JacobiLaplaceSmootherT.cc
Normal file
@@ -0,0 +1,183 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 JacobiLaplaceSmootherT.cc
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS JacobiLaplaceSmootherT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define OPENMESH_JACOBI_LAPLACE_SMOOTHERT_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Smoother {
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
JacobiLaplaceSmootherT<Mesh>::
|
||||
smooth(unsigned int _n)
|
||||
{
|
||||
if (Base::continuity() > Base::C0)
|
||||
{
|
||||
Base::mesh_.add_property(umbrellas_);
|
||||
if (Base::continuity() > Base::C1)
|
||||
Base::mesh_.add_property(squared_umbrellas_);
|
||||
}
|
||||
|
||||
LaplaceSmootherT<Mesh>::smooth(_n);
|
||||
|
||||
if (Base::continuity() > Base::C0)
|
||||
{
|
||||
Base::mesh_.remove_property(umbrellas_);
|
||||
if (Base::continuity() > Base::C1)
|
||||
Base::mesh_.remove_property(squared_umbrellas_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
JacobiLaplaceSmootherT<Mesh>::
|
||||
compute_new_positions_C0()
|
||||
{
|
||||
typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end());
|
||||
typename Mesh::CVVIter vv_it;
|
||||
typename Mesh::Normal u, p, zero(0,0,0);
|
||||
typename Mesh::Scalar w;
|
||||
|
||||
for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
{
|
||||
if (is_active(v_it))
|
||||
{
|
||||
// compute umbrella
|
||||
u = zero;
|
||||
for (vv_it=Base::mesh_.cvv_iter(v_it); vv_it; ++vv_it)
|
||||
{
|
||||
w = weight(Base::mesh_.edge_handle(vv_it.current_halfedge_handle()));
|
||||
u += vector_cast<typename Mesh::Normal>(Base::mesh_.point(vv_it)) * w;
|
||||
}
|
||||
u *= weight(v_it);
|
||||
u -= vector_cast<typename Mesh::Normal>(Base::mesh_.point(v_it));
|
||||
|
||||
// damping
|
||||
u *= 0.5;
|
||||
|
||||
// store new position
|
||||
p = vector_cast<typename Mesh::Normal>(Base::mesh_.point(v_it));
|
||||
p += u;
|
||||
set_new_position(v_it, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
JacobiLaplaceSmootherT<Mesh>::
|
||||
compute_new_positions_C1()
|
||||
{
|
||||
typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end());
|
||||
typename Mesh::CVVIter vv_it;
|
||||
typename Mesh::Normal u, uu, p, zero(0,0,0);
|
||||
typename Mesh::Scalar w, diag;
|
||||
|
||||
|
||||
// 1st pass: compute umbrellas
|
||||
for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
{
|
||||
u = zero;
|
||||
for (vv_it=Base::mesh_.cvv_iter(v_it); vv_it; ++vv_it)
|
||||
{
|
||||
w = weight(Base::mesh_.edge_handle(vv_it.current_halfedge_handle()));
|
||||
u -= vector_cast<typename Mesh::Normal>(Base::mesh_.point(vv_it))*w;
|
||||
}
|
||||
u *= weight(v_it);
|
||||
u += vector_cast<typename Mesh::Normal>(Base::mesh_.point(v_it));
|
||||
|
||||
Base::mesh_.property(umbrellas_, v_it) = u;
|
||||
}
|
||||
|
||||
|
||||
// 2nd pass: compute updates
|
||||
for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
{
|
||||
if (is_active(v_it))
|
||||
{
|
||||
uu = zero;
|
||||
diag = 0.0;
|
||||
for (vv_it=Base::mesh_.cvv_iter(v_it); vv_it; ++vv_it)
|
||||
{
|
||||
w = weight(Base::mesh_.edge_handle(vv_it.current_halfedge_handle()));
|
||||
uu -= Base::mesh_.property(umbrellas_, vv_it);
|
||||
diag += (w * weight(vv_it) + 1.0) * w;
|
||||
}
|
||||
uu *= weight(v_it);
|
||||
diag *= weight(v_it);
|
||||
uu += Base::mesh_.property(umbrellas_, v_it);
|
||||
if (diag) uu *= 1.0/diag;
|
||||
|
||||
// damping
|
||||
uu *= 0.25;
|
||||
|
||||
// store new position
|
||||
p = vector_cast<typename Mesh::Normal>(Base::mesh_.point(v_it));
|
||||
p -= uu;
|
||||
set_new_position(v_it, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Smoother
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
99
Tools/Smoother/JacobiLaplaceSmootherT.hh
Normal file
99
Tools/Smoother/JacobiLaplaceSmootherT.hh
Normal file
@@ -0,0 +1,99 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 JacobiLaplaceSmootherT.hh
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS JacobiLaplaceSmootherT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_JACOBI_LAPLACE_SMOOTHERT_HH
|
||||
#define OPENMESH_JACOBI_LAPLACE_SMOOTHERT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/Smoother/LaplaceSmootherT.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Smoother {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Laplacian Smoothing.
|
||||
*
|
||||
*/
|
||||
template <class Mesh>
|
||||
class JacobiLaplaceSmootherT : public LaplaceSmootherT<Mesh>
|
||||
{
|
||||
private:
|
||||
typedef LaplaceSmootherT<Mesh> Base;
|
||||
|
||||
public:
|
||||
|
||||
JacobiLaplaceSmootherT( Mesh& _mesh ) : LaplaceSmootherT<Mesh>(_mesh) {}
|
||||
|
||||
// override: alloc umbrellas
|
||||
void smooth(unsigned int _n);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void compute_new_positions_C0();
|
||||
virtual void compute_new_positions_C1();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
OpenMesh::VPropHandleT<typename Mesh::Normal> umbrellas_;
|
||||
OpenMesh::VPropHandleT<typename Mesh::Normal> squared_umbrellas_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Smoother
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_JACOBI_LAPLACE_SMOOTHERT_C)
|
||||
#define OPENMESH_JACOBI_LAPLACE_SMOOTHERT_TEMPLATES
|
||||
#include "JacobiLaplaceSmootherT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_JACOBI_LAPLACE_SMOOTHERT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
209
Tools/Smoother/LaplaceSmootherT.cc
Normal file
209
Tools/Smoother/LaplaceSmootherT.cc
Normal file
@@ -0,0 +1,209 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 LaplaceSmootherT.cc
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LaplaceSmootherT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define OPENMESH_LAPLACE_SMOOTHERT_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/Smoother/LaplaceSmootherT.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Smoother {
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
LaplaceSmootherT<Mesh>::
|
||||
LaplaceSmootherT(Mesh& _mesh)
|
||||
: SmootherT<Mesh>(_mesh)
|
||||
{
|
||||
// custom properties
|
||||
Base::mesh_.add_property(vertex_weights_);
|
||||
Base::mesh_.add_property(edge_weights_);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
LaplaceSmootherT<Mesh>::
|
||||
~LaplaceSmootherT()
|
||||
{
|
||||
// free custom properties
|
||||
Base::mesh_.remove_property(vertex_weights_);
|
||||
Base::mesh_.remove_property(edge_weights_);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
LaplaceSmootherT<Mesh>::
|
||||
initialize(Component _comp, Continuity _cont)
|
||||
{
|
||||
SmootherT<Mesh>::initialize(_comp, _cont);
|
||||
|
||||
// calculate weights
|
||||
switch (_comp)
|
||||
{
|
||||
case Base::Tangential:
|
||||
compute_weights(UniformWeighting);
|
||||
break;
|
||||
|
||||
|
||||
case Base::Normal:
|
||||
compute_weights(CotWeighting);
|
||||
break;
|
||||
|
||||
|
||||
case Base::Tangential_and_Normal:
|
||||
compute_weights(UniformWeighting);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
LaplaceSmootherT<Mesh>::
|
||||
compute_weights(LaplaceWeighting _weighting)
|
||||
{
|
||||
typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end());
|
||||
typename Mesh::EdgeIter e_it, e_end(Base::mesh_.edges_end());
|
||||
typename Mesh::HalfedgeHandle heh0, heh1, heh2;
|
||||
typename Mesh::VertexHandle v0, v1;
|
||||
const typename Mesh::Point *p0, *p1, *p2;
|
||||
typename Mesh::Normal d0, d1;
|
||||
typename Mesh::Scalar weight, lb(-1.0), ub(1.0);
|
||||
|
||||
|
||||
|
||||
// init vertex weights
|
||||
for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
Base::mesh_.property(vertex_weights_, v_it) = 0.0;
|
||||
|
||||
|
||||
|
||||
switch (_weighting)
|
||||
{
|
||||
// Uniform weighting
|
||||
case UniformWeighting:
|
||||
{
|
||||
for (e_it=Base::mesh_.edges_begin(); e_it!=e_end; ++e_it)
|
||||
{
|
||||
heh0 = Base::mesh_.halfedge_handle(e_it.handle(), 0);
|
||||
heh1 = Base::mesh_.halfedge_handle(e_it.handle(), 1);
|
||||
v0 = Base::mesh_.to_vertex_handle(heh0);
|
||||
v1 = Base::mesh_.to_vertex_handle(heh1);
|
||||
|
||||
Base::mesh_.property(edge_weights_, e_it) = 1.0;
|
||||
Base::mesh_.property(vertex_weights_, v0) += 1.0;
|
||||
Base::mesh_.property(vertex_weights_, v1) += 1.0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Cotangent weighting
|
||||
case CotWeighting:
|
||||
{
|
||||
for (e_it=Base::mesh_.edges_begin(); e_it!=e_end; ++e_it)
|
||||
{
|
||||
weight = 0.0;
|
||||
|
||||
heh0 = Base::mesh_.halfedge_handle(e_it.handle(), 0);
|
||||
v0 = Base::mesh_.to_vertex_handle(heh0);
|
||||
p0 = &Base::mesh_.point(v0);
|
||||
|
||||
heh1 = Base::mesh_.halfedge_handle(e_it.handle(), 1);
|
||||
v1 = Base::mesh_.to_vertex_handle(heh1);
|
||||
p1 = &Base::mesh_.point(v1);
|
||||
|
||||
heh2 = Base::mesh_.next_halfedge_handle(heh0);
|
||||
p2 = &Base::mesh_.point(Base::mesh_.to_vertex_handle(heh2));
|
||||
d0 = (*p0 - *p2); d0.normalize();
|
||||
d1 = (*p1 - *p2); d1.normalize();
|
||||
weight += 1.0 / tan(acos(std::max(lb, std::min(ub, dot(d0,d1) ))));
|
||||
|
||||
heh2 = Base::mesh_.next_halfedge_handle(heh1);
|
||||
p2 = &Base::mesh_.point(Base::mesh_.to_vertex_handle(heh2));
|
||||
d0 = (*p0 - *p2); d0.normalize();
|
||||
d1 = (*p1 - *p2); d1.normalize();
|
||||
weight += 1.0 / tan(acos(std::max(lb, std::min(ub, dot(d0,d1) ))));
|
||||
|
||||
Base::mesh_.property(edge_weights_, e_it) = weight;
|
||||
Base::mesh_.property(vertex_weights_, v0) += weight;
|
||||
Base::mesh_.property(vertex_weights_, v1) += weight;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// invert vertex weights:
|
||||
// before: sum of edge weights
|
||||
// after: one over sum of edge weights
|
||||
for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
{
|
||||
weight = Base::mesh_.property(vertex_weights_, v_it);
|
||||
if (weight)
|
||||
Base::mesh_.property(vertex_weights_, v_it) = 1.0 / weight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Smoother
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
113
Tools/Smoother/LaplaceSmootherT.hh
Normal file
113
Tools/Smoother/LaplaceSmootherT.hh
Normal file
@@ -0,0 +1,113 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 LaplaceSmootherT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LaplaceSmootherT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_LAPLACE_SMOOTHERT_HH
|
||||
#define OPENMESH_LAPLACE_SMOOTHERT_HH
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/Smoother/SmootherT.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Smoother {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/// Laplacian Smoothing.
|
||||
template <class Mesh>
|
||||
class LaplaceSmootherT : public SmootherT<Mesh>
|
||||
{
|
||||
private:
|
||||
typedef SmootherT<Mesh> Base;
|
||||
public:
|
||||
|
||||
typedef typename SmootherT<Mesh>::Component Component;
|
||||
typedef typename SmootherT<Mesh>::Continuity Continuity;
|
||||
typedef typename SmootherT<Mesh>::Scalar Scalar;
|
||||
typedef typename SmootherT<Mesh>::VertexHandle VertexHandle;
|
||||
typedef typename SmootherT<Mesh>::EdgeHandle EdgeHandle;
|
||||
|
||||
|
||||
LaplaceSmootherT( Mesh& _mesh );
|
||||
virtual ~LaplaceSmootherT();
|
||||
|
||||
|
||||
void initialize(Component _comp, Continuity _cont);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// misc helpers
|
||||
|
||||
Scalar weight(VertexHandle _vh) const
|
||||
{ return Base::mesh_.property(vertex_weights_, _vh); }
|
||||
|
||||
Scalar weight(EdgeHandle _eh) const
|
||||
{ return Base::mesh_.property(edge_weights_, _eh); }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
enum LaplaceWeighting { UniformWeighting, CotWeighting };
|
||||
void compute_weights(LaplaceWeighting _mode);
|
||||
|
||||
|
||||
OpenMesh::VPropHandleT<Scalar> vertex_weights_;
|
||||
OpenMesh::EPropHandleT<Scalar> edge_weights_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Smoother
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_LAPLACE_SMOOTHERT_C)
|
||||
#define OPENMESH_LAPLACE_SMOOTHERT_TEMPLATES
|
||||
#include "LaplaceSmootherT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_LAPLACE_SMOOTHERT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
394
Tools/Smoother/SmootherT.cc
Normal file
394
Tools/Smoother/SmootherT.cc
Normal file
@@ -0,0 +1,394 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 SmootherT.cc
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS SmootherT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define OPENMESH_SMOOTHERT_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/Utils/vector_cast.hh>
|
||||
#include <OpenMesh/Tools/Smoother/SmootherT.hh>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Smoother {
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
SmootherT<Mesh>::
|
||||
SmootherT(Mesh& _mesh)
|
||||
: mesh_(_mesh)
|
||||
{
|
||||
// request properties
|
||||
mesh_.request_vertex_status();
|
||||
mesh_.request_face_normals();
|
||||
mesh_.request_vertex_normals();
|
||||
|
||||
// custom properties
|
||||
mesh_.add_property(original_positions_);
|
||||
mesh_.add_property(original_normals_);
|
||||
mesh_.add_property(new_positions_);
|
||||
mesh_.add_property(is_active_);
|
||||
|
||||
|
||||
// default settings
|
||||
component_ = Tangential_and_Normal;
|
||||
continuity_ = C0;
|
||||
tolerance_ = -1.0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
SmootherT<Mesh>::
|
||||
~SmootherT()
|
||||
{
|
||||
// free properties
|
||||
mesh_.release_vertex_status();
|
||||
mesh_.release_face_normals();
|
||||
mesh_.release_vertex_normals();
|
||||
|
||||
// free custom properties
|
||||
mesh_.remove_property(original_positions_);
|
||||
mesh_.remove_property(original_normals_);
|
||||
mesh_.remove_property(new_positions_);
|
||||
mesh_.remove_property(is_active_);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
SmootherT<Mesh>::
|
||||
initialize(Component _comp, Continuity _cont)
|
||||
{
|
||||
typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end());
|
||||
|
||||
|
||||
// store smoothing settings
|
||||
component_ = _comp;
|
||||
continuity_ = _cont;
|
||||
|
||||
|
||||
// update normals
|
||||
mesh_.update_face_normals();
|
||||
mesh_.update_vertex_normals();
|
||||
|
||||
|
||||
// store original points & normals
|
||||
for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
{
|
||||
mesh_.property(original_positions_, v_it) = mesh_.point(v_it);
|
||||
mesh_.property(original_normals_, v_it) = mesh_.normal(v_it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
SmootherT<Mesh>::
|
||||
set_active_vertices()
|
||||
{
|
||||
typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end());
|
||||
|
||||
|
||||
// is something selected?
|
||||
bool nothing_selected(true);
|
||||
for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
if (mesh_.status(v_it).selected())
|
||||
{ nothing_selected = false; break; }
|
||||
|
||||
|
||||
// tagg all active vertices
|
||||
bool active;
|
||||
for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
{
|
||||
active = ((nothing_selected || mesh_.status(v_it).selected())
|
||||
&& !mesh_.is_boundary(v_it)
|
||||
&& !mesh_.status(v_it).locked());
|
||||
mesh_.property(is_active_, v_it) = active;
|
||||
}
|
||||
|
||||
|
||||
// C1: remove one ring of boundary vertices
|
||||
if (continuity_ == C1)
|
||||
{
|
||||
typename Mesh::VVIter vv_it;
|
||||
|
||||
for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
if (mesh_.is_boundary(v_it))
|
||||
for (vv_it=mesh_.vv_iter(v_it); vv_it; ++vv_it)
|
||||
mesh_.property(is_active_, vv_it) = false;
|
||||
}
|
||||
|
||||
|
||||
// C2: remove two rings of boundary vertices
|
||||
if (continuity_ == C2)
|
||||
{
|
||||
typename Mesh::VVIter vv_it;
|
||||
|
||||
for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
{
|
||||
mesh_.status(v_it).set_tagged(false);
|
||||
mesh_.status(v_it).set_tagged2(false);
|
||||
}
|
||||
|
||||
for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
if (mesh_.is_boundary(v_it))
|
||||
for (vv_it=mesh_.vv_iter(v_it); vv_it; ++vv_it)
|
||||
mesh_.status(v_it).set_tagged(true);
|
||||
|
||||
for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
if (mesh_.status(v_it).tagged())
|
||||
for (vv_it=mesh_.vv_iter(v_it); vv_it; ++vv_it)
|
||||
mesh_.status(v_it).set_tagged2(true);
|
||||
|
||||
for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
|
||||
{
|
||||
if (mesh_.status(v_it).tagged2())
|
||||
mesh_.property(is_active_, vv_it) = false;
|
||||
mesh_.status(v_it).set_tagged(false);
|
||||
mesh_.status(v_it).set_tagged2(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
SmootherT<Mesh>::
|
||||
set_relative_local_error(Scalar _err)
|
||||
{
|
||||
if (!mesh_.vertices_empty())
|
||||
{
|
||||
typename Mesh::VertexIter v_it(mesh_.vertices_begin()),
|
||||
v_end(mesh_.vertices_end());
|
||||
|
||||
|
||||
// compute bounding box
|
||||
Point bb_min, bb_max;
|
||||
bb_min = bb_max = mesh_.point(v_it);
|
||||
for (++v_it; v_it!=v_end; ++v_it)
|
||||
{
|
||||
bb_min.minimize(mesh_.point(v_it));
|
||||
bb_max.minimize(mesh_.point(v_it));
|
||||
}
|
||||
|
||||
|
||||
// abs. error = rel. error * bounding-diagonal
|
||||
set_absolute_error(_err * (bb_max-bb_min).norm());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
SmootherT<Mesh>::
|
||||
set_absolute_local_error(Scalar _err)
|
||||
{
|
||||
tolerance_ = _err;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
SmootherT<Mesh>::
|
||||
disable_local_error_check()
|
||||
{
|
||||
tolerance_ = -1.0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
SmootherT<Mesh>::
|
||||
smooth(unsigned int _n)
|
||||
{
|
||||
// mark active vertices
|
||||
set_active_vertices();
|
||||
|
||||
// smooth _n iterations
|
||||
while (_n--)
|
||||
{
|
||||
compute_new_positions();
|
||||
|
||||
if (component_ == Tangential)
|
||||
project_to_tangent_plane();
|
||||
|
||||
else if (tolerance_ >= 0.0)
|
||||
local_error_check();
|
||||
|
||||
move_points();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
SmootherT<Mesh>::
|
||||
compute_new_positions()
|
||||
{
|
||||
switch (continuity_)
|
||||
{
|
||||
case C0:
|
||||
compute_new_positions_C0();
|
||||
break;
|
||||
|
||||
case C1:
|
||||
compute_new_positions_C1();
|
||||
break;
|
||||
|
||||
case C2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
SmootherT<Mesh>::
|
||||
project_to_tangent_plane()
|
||||
{
|
||||
typename Mesh::VertexIter v_it(mesh_.vertices_begin()),
|
||||
v_end(mesh_.vertices_end());
|
||||
// Normal should be a vector type. In some environment a vector type
|
||||
// is different from point type, e.g. OpenSG!
|
||||
typename Mesh::Normal translation, normal;
|
||||
|
||||
|
||||
for (; v_it != v_end; ++v_it)
|
||||
{
|
||||
if (is_active(v_it))
|
||||
{
|
||||
translation = new_position(v_it)-orig_position(v_it);
|
||||
normal = orig_normal(v_it);
|
||||
normal *= dot(translation, normal);
|
||||
translation -= normal;
|
||||
translation += vector_cast<typename Mesh::Normal>(orig_position(v_it));
|
||||
set_new_position(v_it, translation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
SmootherT<Mesh>::
|
||||
local_error_check()
|
||||
{
|
||||
typename Mesh::VertexIter v_it(mesh_.vertices_begin()),
|
||||
v_end(mesh_.vertices_end());
|
||||
|
||||
typename Mesh::Normal translation;
|
||||
typename Mesh::Scalar s;
|
||||
|
||||
|
||||
for (; v_it != v_end; ++v_it)
|
||||
{
|
||||
if (is_active(v_it))
|
||||
{
|
||||
translation = new_position(v_it) - orig_position(v_it);
|
||||
|
||||
s = fabs(dot(translation, orig_normal(v_it)));
|
||||
|
||||
if (s > tolerance_)
|
||||
{
|
||||
translation *= (tolerance_ / s);
|
||||
translation += vector_cast<NormalType>(orig_position(v_it));
|
||||
set_new_position(v_it, translation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
SmootherT<Mesh>::
|
||||
move_points()
|
||||
{
|
||||
typename Mesh::VertexIter v_it(mesh_.vertices_begin()),
|
||||
v_end(mesh_.vertices_end());
|
||||
|
||||
for (; v_it != v_end; ++v_it)
|
||||
if (is_active(v_it))
|
||||
mesh_.set_point(v_it, mesh_.property(new_positions_, v_it));
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Smoother
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
188
Tools/Smoother/SmootherT.hh
Normal file
188
Tools/Smoother/SmootherT.hh
Normal file
@@ -0,0 +1,188 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 SmootherT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS SmootherT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SMOOTHER_SMOOTHERT_HH
|
||||
#define OPENMESH_SMOOTHER_SMOOTHERT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Core/Utils/Property.hh>
|
||||
#include <OpenMesh/Core/Utils/Noncopyable.hh>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Smoother {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Base class for smoothing algorithms.
|
||||
*/
|
||||
template <class Mesh>
|
||||
class SmootherT : private Utils::Noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename Mesh::Scalar Scalar;
|
||||
typedef typename Mesh::Point Point;
|
||||
typedef typename Mesh::Normal NormalType;
|
||||
typedef typename Mesh::VertexHandle VertexHandle;
|
||||
typedef typename Mesh::EdgeHandle EdgeHandle;
|
||||
|
||||
// initialize smoother
|
||||
enum Component {
|
||||
Tangential, ///< Smooth tangential direction
|
||||
Normal, ///< Smooth normal direction
|
||||
Tangential_and_Normal ///< Smooth tangential and normal direction
|
||||
};
|
||||
|
||||
enum Continuity {
|
||||
C0,
|
||||
C1,
|
||||
C2
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
// constructor & destructor
|
||||
SmootherT( Mesh& _mesh );
|
||||
virtual ~SmootherT();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/// Initialize smoother
|
||||
/// \param _comp Determine component to smooth
|
||||
/// \param _cont
|
||||
void initialize(Component _comp, Continuity _cont);
|
||||
|
||||
|
||||
//@{
|
||||
/// Set local error
|
||||
void set_relative_local_error(Scalar _err);
|
||||
void set_absolute_local_error(Scalar _err);
|
||||
void disable_local_error_check();
|
||||
//@}
|
||||
|
||||
|
||||
/// Do _n smoothing iterations
|
||||
virtual void smooth(unsigned int _n);
|
||||
|
||||
|
||||
|
||||
/// Find active vertices. Resets tagged status !
|
||||
void set_active_vertices();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// single steps of smoothing
|
||||
void compute_new_positions();
|
||||
void project_to_tangent_plane();
|
||||
void local_error_check();
|
||||
void move_points();
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// override these
|
||||
virtual void compute_new_positions_C0() = 0;
|
||||
virtual void compute_new_positions_C1() = 0;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// misc helpers
|
||||
|
||||
const Point& orig_position(VertexHandle _vh) const
|
||||
{ return mesh_.property(original_positions_, _vh); }
|
||||
|
||||
const NormalType& orig_normal(VertexHandle _vh) const
|
||||
{ return mesh_.property(original_normals_, _vh); }
|
||||
|
||||
const Point& new_position(VertexHandle _vh) const
|
||||
{ return mesh_.property(new_positions_, _vh); }
|
||||
|
||||
void set_new_position(VertexHandle _vh, const Point& _p)
|
||||
{ mesh_.property(new_positions_, _vh) = _p; }
|
||||
|
||||
bool is_active(VertexHandle _vh) const
|
||||
{ return mesh_.property(is_active_, _vh); }
|
||||
|
||||
Component component() const { return component_; }
|
||||
Continuity continuity() const { return continuity_; }
|
||||
|
||||
protected:
|
||||
|
||||
Mesh& mesh_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Scalar tolerance_;
|
||||
Scalar normal_deviation_;
|
||||
Component component_;
|
||||
Continuity continuity_;
|
||||
|
||||
OpenMesh::VPropHandleT<Point> original_positions_;
|
||||
OpenMesh::VPropHandleT<NormalType> original_normals_;
|
||||
OpenMesh::VPropHandleT<Point> new_positions_;
|
||||
OpenMesh::VPropHandleT<bool> is_active_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Smoother
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SMOOTHERT_C)
|
||||
#define OPENMESH_SMOOTHERT_TEMPLATES
|
||||
#include "SmootherT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SMOOTHER_SMOOTHERT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
92
Tools/Smoother/smooth_mesh.hh
Normal file
92
Tools/Smoother/smooth_mesh.hh
Normal file
@@ -0,0 +1,92 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SMOOTH_MESH_HH
|
||||
#define SMOOTH_MESH_HH
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/Utils/Property.hh>
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { //BEGIN_NS_OPENMESH
|
||||
|
||||
template <class _Mesh, class _PropertyHandle>
|
||||
void smooth_mesh_property(unsigned int _n_iters, _Mesh& _m, _PropertyHandle _pph)
|
||||
{
|
||||
typedef typename _PropertyHandle::Value Value;
|
||||
|
||||
std::vector<Value> temp_values(_m.n_vertices());
|
||||
|
||||
for (unsigned int i=0; i < _n_iters; ++i)
|
||||
{
|
||||
for ( typename _Mesh::ConstVertexIter cv_it = _m.vertices_begin();
|
||||
cv_it != _m.vertices_end(); ++cv_it)
|
||||
{
|
||||
unsigned int valence = 0;
|
||||
|
||||
Value& temp_value = temp_values[cv_it.handle().idx()];
|
||||
|
||||
temp_value.vectorize(0);
|
||||
|
||||
for ( typename _Mesh::ConstVertexVertexIter cvv_it = _m.cvv_iter(cv_it);
|
||||
cvv_it; ++cvv_it)
|
||||
{
|
||||
temp_value += _m.property(_pph,cvv_it);
|
||||
++valence;
|
||||
}
|
||||
if (valence > 0)
|
||||
{//guard against isolated vertices
|
||||
temp_value *= (typename Value::value_type)(1.0 / valence);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_value = _m.property(_pph, cv_it);
|
||||
}
|
||||
}
|
||||
|
||||
for ( typename _Mesh::ConstVertexIter cv_it = _m.vertices_begin();
|
||||
cv_it != _m.vertices_end(); ++cv_it)
|
||||
{
|
||||
_m.property(_pph,cv_it) = temp_values[cv_it.handle().idx()];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Mesh>
|
||||
void smooth_mesh(_Mesh& _m, uint _n_iters)
|
||||
{
|
||||
smooth_mesh_property(_n_iters, _m, _m.points_pph());
|
||||
}
|
||||
|
||||
};//namespace OpenMesh
|
||||
|
||||
#endif//SMOOTH_MESH_HH
|
||||
17
Tools/Subdivider/ACGMakefile
Normal file
17
Tools/Subdivider/ACGMakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS = $(call find-subdirs)
|
||||
|
||||
PACKAGES :=
|
||||
|
||||
PROJ_LIBS :=
|
||||
|
||||
MODULES := cxxlib
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
17
Tools/Subdivider/Adaptive/ACGMakefile
Normal file
17
Tools/Subdivider/Adaptive/ACGMakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS = $(call find-subdirs)
|
||||
|
||||
PACKAGES := qt glut opengl x11 math
|
||||
|
||||
PROJ_LIBS = OpenMesh/Core
|
||||
|
||||
MODULES := moc cxx
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
17
Tools/Subdivider/Adaptive/Composite/ACGMakefile
Normal file
17
Tools/Subdivider/Adaptive/Composite/ACGMakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
PACKAGES := math
|
||||
|
||||
PROJ_LIBS = OpenMesh/Core
|
||||
|
||||
MODULES := cxx
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
307
Tools/Subdivider/Adaptive/Composite/CompositeT.cc
Normal file
307
Tools/Subdivider/Adaptive/Composite/CompositeT.cc
Normal file
@@ -0,0 +1,307 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 Adaptive/Composite/CompositeT.cc
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS CompositeT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_CC
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Core/System/omstream.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh>
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Adaptive { // BEGIN_NS_UNIFORM
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template<class M>
|
||||
bool
|
||||
CompositeT<M> ::
|
||||
initialize( void )
|
||||
{
|
||||
typename Mesh::VertexIter v_it;
|
||||
typename Mesh::FaceIter f_it;
|
||||
typename Mesh::EdgeIter e_it;
|
||||
const typename Mesh::Point zero_point(0.0, 0.0, 0.0);
|
||||
|
||||
// ---------------------------------------- Init Vertices
|
||||
for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it)
|
||||
{
|
||||
mesh_.data(v_it).set_state(0);
|
||||
mesh_.data(v_it).set_final();
|
||||
mesh_.data(v_it).set_position(0, mesh_.point(v_it.handle()));
|
||||
}
|
||||
|
||||
// ---------------------------------------- Init Faces
|
||||
for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it)
|
||||
{
|
||||
mesh_.data(f_it).set_state(0);
|
||||
mesh_.data(f_it).set_final();
|
||||
mesh_.data(f_it).set_position(0, zero_point);
|
||||
}
|
||||
|
||||
// ---------------------------------------- Init Edges
|
||||
for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it)
|
||||
{
|
||||
mesh_.data(e_it).set_state(0);
|
||||
mesh_.data(e_it).set_final();
|
||||
mesh_.data(e_it).set_position(0, zero_point);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------- Init Rules
|
||||
|
||||
int n_subdiv_rules_ = 0;
|
||||
|
||||
|
||||
// look for subdivision rule(s)
|
||||
for (size_t i=0; i < n_rules(); ++i) {
|
||||
|
||||
if (rule_sequence_[i]->type()[0] == 'T' ||
|
||||
rule_sequence_[i]->type()[0] == 't')
|
||||
{
|
||||
++n_subdiv_rules_;
|
||||
subdiv_rule_ = rule_sequence_[i];
|
||||
subdiv_type_ = rule_sequence_[i]->subdiv_type();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check for correct number of subdivision rules
|
||||
assert(n_subdiv_rules_ == 1);
|
||||
|
||||
if (n_subdiv_rules_ != 1)
|
||||
{
|
||||
std::cerr << "Error! More than one subdivision rules not allowed!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for subdivision type
|
||||
assert(subdiv_type_ == 3 || subdiv_type_ == 4);
|
||||
|
||||
if (subdiv_type_ != 3 && subdiv_type_ != 4)
|
||||
{
|
||||
::omerr() << "Error! Unknown subdivision type in sequence!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set pointer to last rule
|
||||
// first_rule_ = rule_sequence_.front();
|
||||
// last_rule_ = rule_sequence_.back(); //[n_rules() - 1];
|
||||
|
||||
// set numbers and previous rule
|
||||
for (size_t i = 0; i < n_rules(); ++i)
|
||||
{
|
||||
rule_sequence_[i]->set_subdiv_type(subdiv_type_);
|
||||
rule_sequence_[i]->set_n_rules(n_rules());
|
||||
rule_sequence_[i]->set_number(i);
|
||||
rule_sequence_[i]->set_prev_rule(rule_sequence_[(i+n_rules()-1)%n_rules()]);
|
||||
rule_sequence_[i]->set_subdiv_rule(subdiv_rule_);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
#define MOBJ mesh_.deref
|
||||
#define TVH to_vertex_handle
|
||||
#define HEH halfedge_handle
|
||||
#define NHEH next_halfedge_handle
|
||||
#define PHEH prev_halfedge_handle
|
||||
#define OHEH opposite_halfedge_handle
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<class M>
|
||||
void CompositeT<M>::refine(typename Mesh::FaceHandle& _fh)
|
||||
{
|
||||
std::vector<typename Mesh::HalfedgeHandle> hh_vector;
|
||||
|
||||
// -------------------- calculate new level for faces and vertices
|
||||
int new_face_level =
|
||||
t_rule()->number() + 1 +
|
||||
((int)floor((float)(mesh_.data(_fh).state() - t_rule()->number() - 1)/n_rules()) + 1) * n_rules();
|
||||
|
||||
int new_vertex_level =
|
||||
new_face_level + l_rule()->number() - t_rule()->number();
|
||||
|
||||
// -------------------- store old vertices
|
||||
// !!! only triangle meshes supported!
|
||||
typename Mesh::VertexHandle vh[3];
|
||||
|
||||
vh[0] = mesh_.TVH(mesh_.HEH(_fh));
|
||||
vh[1] = mesh_.TVH(mesh_.NHEH(mesh_.HEH(_fh)));
|
||||
vh[2] = mesh_.TVH(mesh_.PHEH(mesh_.HEH(_fh)));
|
||||
|
||||
// save handles to incoming halfedges for getting the new vertices
|
||||
// after subdivision (1-4 split)
|
||||
if (subdiv_type_ == 4)
|
||||
{
|
||||
hh_vector.clear();
|
||||
|
||||
// green face
|
||||
if (mesh_.data(_fh).final())
|
||||
{
|
||||
typename Mesh::FaceHalfedgeIter fh_it(mesh_.fh_iter(_fh));
|
||||
|
||||
for (; fh_it; ++fh_it)
|
||||
{
|
||||
hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(fh_it.handle())));
|
||||
}
|
||||
}
|
||||
|
||||
// red face
|
||||
else
|
||||
{
|
||||
|
||||
typename Mesh::HalfedgeHandle red_hh(mesh_.data(_fh).red_halfedge());
|
||||
|
||||
hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(mesh_.NHEH(red_hh))));
|
||||
hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(mesh_.PHEH(mesh_.OHEH(red_hh)))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -------------------- Average rule before topo rule?
|
||||
if (t_rule()->number() > 0)
|
||||
t_rule()->prev_rule()->raise(_fh, new_face_level-1);
|
||||
|
||||
// -------------------- Apply topological operator first
|
||||
t_rule()->raise(_fh, new_face_level);
|
||||
|
||||
#if 0 // original code
|
||||
assert(MOBJ(_fh).state() >=
|
||||
subdiv_rule_->number()+1+(int) (MOBJ(_fh).state()/n_rules())*n_rules());
|
||||
#else // improved code (use % operation and avoid floating point division)
|
||||
assert( mesh_.data(_fh).state() >= ( t_rule()->number()+1+generation(_fh) ) );
|
||||
#endif
|
||||
|
||||
// raise new vertices to final levels
|
||||
if (subdiv_type_ == 3)
|
||||
{
|
||||
typename Mesh::VertexHandle new_vh(mesh_.TVH(mesh_.NHEH(mesh_.HEH(_fh))));
|
||||
|
||||
// raise new vertex to final level
|
||||
l_rule()->raise(new_vh, new_vertex_level);
|
||||
}
|
||||
|
||||
if (subdiv_type_ == 4)
|
||||
{
|
||||
typename Mesh::HalfedgeHandle hh;
|
||||
typename Mesh::VertexHandle new_vh;
|
||||
|
||||
while (!hh_vector.empty()) {
|
||||
|
||||
hh = hh_vector.back();
|
||||
hh_vector.pop_back();
|
||||
|
||||
// get new vertex
|
||||
new_vh = mesh_.TVH(mesh_.NHEH(hh));
|
||||
|
||||
// raise new vertex to final level
|
||||
l_rule()->raise(new_vh, new_vertex_level);
|
||||
}
|
||||
}
|
||||
|
||||
// raise old vertices to final position
|
||||
l_rule()->raise(vh[0], new_vertex_level);
|
||||
l_rule()->raise(vh[1], new_vertex_level);
|
||||
l_rule()->raise(vh[2], new_vertex_level);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<class M>
|
||||
void CompositeT<M>::refine(typename Mesh::VertexHandle& _vh)
|
||||
{
|
||||
// calculate next final level for vertex
|
||||
int new_vertex_state = generation(_vh) + l_rule()->number() + 1;
|
||||
|
||||
assert( new_vertex_state == mesh_.data(_vh).state()+1 );
|
||||
|
||||
// raise vertex to final position
|
||||
l_rule()->raise(_vh, new_vertex_state);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class M>
|
||||
std::string CompositeT<M>::rules_as_string(const std::string& _sep) const
|
||||
{
|
||||
std::string seq;
|
||||
typename RuleSequence::const_iterator it = rule_sequence_.begin();
|
||||
|
||||
if ( it != rule_sequence_.end() )
|
||||
{
|
||||
seq = (*it)->type();
|
||||
for (++it; it != rule_sequence_.end(); ++it )
|
||||
{
|
||||
seq += _sep;
|
||||
seq += (*it)->type();
|
||||
}
|
||||
}
|
||||
return seq;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
#undef MOBJ
|
||||
#undef TVH
|
||||
#undef HEH
|
||||
#undef NHEH
|
||||
#undef PHEH
|
||||
#undef OHEH
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
298
Tools/Subdivider/Adaptive/Composite/CompositeT.hh
Normal file
298
Tools/Subdivider/Adaptive/Composite/CompositeT.hh
Normal file
@@ -0,0 +1,298 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 Adaptive/Composite/CompositeT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS CompositeT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_HH
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh>
|
||||
// --------------------
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_SUBDIVIDER
|
||||
namespace Adaptive { // BEGIN_NS_ADAPTIVE
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
template <typename R> struct RuleHandleT;
|
||||
template <typename M> class RuleInterfaceT;
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Adaptive Composite Subdivision framework.
|
||||
*
|
||||
* The adaptive composite subdivision framework is based on the work
|
||||
* done by P. Oswald and P. Schroeder. This framework elevates the
|
||||
* uniform case of the composite scheme to the adaptive
|
||||
* setting.
|
||||
*
|
||||
* For details on the composite scheme refer to
|
||||
* - <a
|
||||
* href="http://cm.bell-labs.com/who/poswald/sqrt3.pdf">P. Oswald,
|
||||
* P. Schroeder "Composite primal/dual sqrt(3)-subdivision schemes",
|
||||
* CAGD 20, 3, 2003, 135--164</a>
|
||||
*
|
||||
* For details on the transition from uniform to adaptive composite
|
||||
* subdivision please refer to
|
||||
* - <a
|
||||
* href="http://www.eg.org/EG/DL/PE/OPENSG03/04sovakar.pdf>A. von Studnitz,
|
||||
* A. Sovakar, L. Kobbelt "API Design for Adaptive Subdivision
|
||||
* Schemes" OpenSG Symposium 2003</a>
|
||||
*
|
||||
* In the composite scheme a subdivision operator is created by
|
||||
* combining smaller "atomic" rules. Depending on the selection and
|
||||
* ordering of the operator many known subdivision schemes can be
|
||||
* created.
|
||||
*
|
||||
* Every rule inherits from RuleInterfaceT and is represented out of
|
||||
* the subdivider object by a RuleHandleT (as usual within
|
||||
* %OpenMesh). You can add rules using the CompositeT::add()
|
||||
* functions. The correct order of adding the rules is very
|
||||
* important, and furthermore not all rules get along with each other
|
||||
* very well. (Please read the given literature, especially the
|
||||
* paper by Oswald and Schr<68>der.)
|
||||
*
|
||||
* To use a composite subdivider first define a rule sequence
|
||||
* describing the order of execution of the rules. In the order the
|
||||
* rules habe been added they will be executed. E.g. the rules given
|
||||
* in operator notation have to added from right to left.
|
||||
*
|
||||
* After the rule sequence has been defined the subdivider has to be
|
||||
* intialized using CompositeT::initialize(). If everything went well,
|
||||
* use CompositeT::refine() to subdivide locally a face or vertex.
|
||||
*
|
||||
* \note Not all (topological) operators have been implemented!
|
||||
* \note Only triangle meshes are supported.
|
||||
* \note The rule sequence must begin with a topological operator.
|
||||
*
|
||||
* \see RuleInterfaceT, RuleHandleT
|
||||
*
|
||||
*/
|
||||
template <typename M> class CompositeT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef RuleInterfaceT<M> Rule;
|
||||
typedef M Mesh;
|
||||
typedef std::vector<Rule*> RuleSequence;
|
||||
|
||||
typedef typename M::VertexHandle VH;
|
||||
typedef typename M::FaceHandle FH;
|
||||
typedef typename M::EdgeHandle EH;
|
||||
typedef typename M::HalfedgeHandle HH;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
CompositeT(Mesh& _mesh)
|
||||
: subdiv_type_(0),
|
||||
subdiv_rule_(NULL), /*first_rule_(NULL), last_rule_(NULL),*/ mesh_(_mesh)
|
||||
{ }
|
||||
|
||||
///
|
||||
virtual ~CompositeT()
|
||||
{ cleanup(); }
|
||||
|
||||
|
||||
/// Reset \c self to state after the default constructor except of
|
||||
/// the mesh.
|
||||
void cleanup(void)
|
||||
{
|
||||
subdiv_type_ = 0;
|
||||
subdiv_rule_ = NULL;
|
||||
|
||||
std::for_each(rule_sequence_.begin(),
|
||||
rule_sequence_.end(), DeleteRule() );
|
||||
rule_sequence_.clear();
|
||||
}
|
||||
|
||||
|
||||
/// Initialize faces, edges, vertices, and rules
|
||||
bool initialize(void);
|
||||
|
||||
|
||||
/// Refine one face.
|
||||
void refine(typename Mesh::FaceHandle& _fh);
|
||||
|
||||
|
||||
/// Raise one vertex to next final level.
|
||||
void refine(typename Mesh::VertexHandle& _vh);
|
||||
|
||||
|
||||
/// Return subdivision split type (3 for 1-to-3 split, 4 for 1-to-4 split).
|
||||
int subdiv_type() { return subdiv_type_; }
|
||||
|
||||
|
||||
// Return subdivision rule.
|
||||
const Rule& subdiv_rule() const { return *subdiv_rule_; }
|
||||
|
||||
public:
|
||||
|
||||
/// \name Managing composite rules
|
||||
//*@
|
||||
|
||||
/** Add new rule to rule sequence by passing the type of the wanted
|
||||
* rule as template argument to the method.
|
||||
* \return Valid handle on success. Else it is invalid.
|
||||
*/
|
||||
template < typename R >
|
||||
RuleHandleT<R> add()
|
||||
{
|
||||
size_t idx = rule_sequence_.size();
|
||||
rule_sequence_.push_back( new R( mesh_ ) );
|
||||
return RuleHandleT<R>( (idx < rule_sequence_.size()) ? idx : -1 );
|
||||
}
|
||||
|
||||
/** Add new rule to rule sequence by passing an appropriate handle
|
||||
* to the method.
|
||||
* \return Valid handle on success. Else it is invalid.
|
||||
*/
|
||||
template < typename R >
|
||||
RuleHandleT<R>& add( RuleHandleT<R>& _rh )
|
||||
{
|
||||
return _rh = add< R >();
|
||||
}
|
||||
|
||||
/** Get rule in the rule sequence by a handle.
|
||||
*
|
||||
* \return The wanted rule if the handle is valid. The return value
|
||||
* is undefined if the handle is invalid!
|
||||
*/
|
||||
template < typename R >
|
||||
typename RuleHandleT<R>::Rule& rule( const RuleHandleT<R>& _rh )
|
||||
{
|
||||
typedef typename RuleHandleT<R>::Rule rule_t;
|
||||
assert( _rh.is_valid() );
|
||||
return *dynamic_cast<rule_t*>(rule_sequence_[ _rh.idx() ]);
|
||||
}
|
||||
|
||||
|
||||
/** Get rule (interface) by index
|
||||
*
|
||||
* \return The wanted rule if the handle is valid. The return value
|
||||
* is undefined if the handle is invalid!
|
||||
*/
|
||||
RuleInterfaceT<M>& rule( size_t _idx )
|
||||
{
|
||||
assert( _idx < n_rules() );
|
||||
return *rule_sequence_[ _idx ];
|
||||
}
|
||||
|
||||
/// Number of rules in the rule sequence
|
||||
size_t n_rules() const { return rule_sequence_.size(); }
|
||||
|
||||
/// Return the sequence as string
|
||||
std::string rules_as_string(const std::string& _sep= " * ") const;
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
/// The rule sequence
|
||||
const RuleSequence& rules() const { return rule_sequence_; }
|
||||
|
||||
protected: // helper
|
||||
|
||||
// get current generation from state
|
||||
state_t generation(state_t _s) { return _s-(_s % n_rules()); }
|
||||
state_t generation( VH _vh ) { return generation(mesh_.data(_vh).state()); }
|
||||
state_t generation( EH _eh ) { return generation(mesh_.data(_eh).state()); }
|
||||
state_t generation( FH _fh ) { return generation(mesh_.data(_fh).state()); }
|
||||
|
||||
private:
|
||||
|
||||
// short cuts
|
||||
Rule* t_rule() { return subdiv_rule_; }
|
||||
Rule* f_rule() { return rule_sequence_.front(); }
|
||||
Rule* l_rule() { return rule_sequence_.back(); }
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
RuleSequence rule_sequence_;
|
||||
|
||||
// Split type
|
||||
int subdiv_type_;
|
||||
|
||||
Rule *subdiv_rule_;
|
||||
// Rule *first_rule_;
|
||||
// Rule *last_rule_;
|
||||
|
||||
//
|
||||
Mesh &mesh_;
|
||||
|
||||
private: // helper
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
struct DeleteRule { void operator()( Rule* _r ) { delete _r; } };
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
CompositeT( const CompositeT& );
|
||||
CompositeT& operator = ( const CompositeT );
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_CC)
|
||||
# define OPENMESH_SUBDIVIDER_TEMPLATES
|
||||
# include "CompositeT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_HH defined
|
||||
//=============================================================================
|
||||
247
Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh
Normal file
247
Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh
Normal file
@@ -0,0 +1,247 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 Subdivider/Adaptive/Composite/CompositeTraits.hh
|
||||
Mesh traits for adaptive composite subdivider.
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS Traits
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITETRAITS_HH
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITETRAITS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <map>
|
||||
#include <OpenMesh/Core/Mesh/Traits.hh>
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Adaptive { // BEGIN_NS_UNIFORM
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Adaptive Composite Subdivision framework.
|
||||
*/
|
||||
|
||||
// typedef unsigned short state_t;
|
||||
// const state_t mask_final = 1 << ((sizeof(state_t)*8)-1);
|
||||
// const state_t mask_state = ~mask_final;
|
||||
|
||||
/** Mesh traits for adaptive composite subdivision
|
||||
*/
|
||||
struct CompositeTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
typedef int state_t; ///< External representation for intermediate state
|
||||
typedef bool final_t; ///< External representation for final flag
|
||||
|
||||
|
||||
/// Storage type for intermediate states and the final flag of a mesh entity.
|
||||
struct State
|
||||
{
|
||||
int state : 31;
|
||||
unsigned final : 1;
|
||||
};
|
||||
|
||||
// ---------------------------------------- attributes
|
||||
|
||||
// add face normals
|
||||
FaceAttributes( OpenMesh::Attributes::Normal );
|
||||
|
||||
// add vertex normals
|
||||
VertexAttributes( OpenMesh::Attributes::Normal );
|
||||
|
||||
// add previous halfedge handle
|
||||
HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );
|
||||
|
||||
// ---------------------------------------- items
|
||||
|
||||
FaceTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef typename Refs::HalfedgeHandle HalfedgeHandle;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
HalfedgeHandle red_halfedge_;
|
||||
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
// face state
|
||||
state_t state() const { return state_t(state_.state); }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
// face not final if divided (loop) or edge not flipped (sqrt(3))
|
||||
final_t final() const { return final_t(state_.final); }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// halfedge of dividing edge (red-green triangulation)
|
||||
const HalfedgeHandle& red_halfedge() const { return red_halfedge_; }
|
||||
void set_red_halfedge(const HalfedgeHandle& _h) { red_halfedge_ = _h; }
|
||||
|
||||
// position of face, depending on generation _i.
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
const Point position(const int& _i) {
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
return pos_map_[_i];
|
||||
else {
|
||||
|
||||
if (_i <= 0) {
|
||||
return Point(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class FaceTraits
|
||||
|
||||
|
||||
EdgeTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Refs::Scalar Scalar;
|
||||
|
||||
// Scalar weight_;
|
||||
|
||||
// state of edge
|
||||
state_t state() const { return state_t(state_.state); }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
// edge not final if dividing face (Loop) or edge not flipped (SQRT(3))
|
||||
final_t final() const { return final_t(state_.final); }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// position of edge, depending on generation _i.
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
|
||||
const Point position(const int& _i) {
|
||||
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
return pos_map_[_i];
|
||||
else
|
||||
{
|
||||
if (_i <= 0)
|
||||
{
|
||||
const Point zero_point(0.0, 0.0, 0.0);
|
||||
return zero_point;
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class EdgeTraits
|
||||
|
||||
|
||||
VertexTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
// state of vertex
|
||||
state_t state() const { return state_.state; }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
|
||||
// usually not needed by loop or sqrt(3)
|
||||
final_t final() const { return state_.final; }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// position of vertex, depending on generation _i. (not for display)
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
const Point position(const int& _i) {
|
||||
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
|
||||
return pos_map_[_i];
|
||||
|
||||
else {
|
||||
|
||||
if (_i <= 0) {
|
||||
|
||||
const Point zero_point(0.0, 0.0, 0.0);
|
||||
return zero_point;
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class VertexTraits
|
||||
}; // end class CompositeTraits
|
||||
|
||||
|
||||
// export items to namespace to maintain compatibility
|
||||
typedef CompositeTraits::state_t state_t;
|
||||
typedef CompositeTraits::final_t final_t;
|
||||
typedef CompositeTraits::State State;
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITETRAITS_HH defined
|
||||
//=============================================================================
|
||||
389
Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh
Normal file
389
Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh
Normal file
@@ -0,0 +1,389 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS RuleInterfaceT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <string>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh>
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_SUBDIVIDER
|
||||
namespace Adaptive { // BEGIN_NS_ADAPTIVE
|
||||
|
||||
|
||||
//== FORWARDS =================================================================
|
||||
|
||||
template <typename M> class CompositeT;
|
||||
template <typename M> class RuleInterfaceT;
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** Handle template for adaptive composite subdividion rules
|
||||
* \internal
|
||||
*
|
||||
* Use typed handle of a rule, e.g. Tvv3<MyMesh>::Handle.
|
||||
*/
|
||||
template < typename R >
|
||||
struct RuleHandleT : public BaseHandle
|
||||
{
|
||||
explicit RuleHandleT(int _idx=-1) : BaseHandle(_idx) {}
|
||||
typedef R Rule;
|
||||
|
||||
operator bool() const { return is_valid(); }
|
||||
|
||||
};
|
||||
|
||||
/** Defines the method type() (RuleInterfaceT::type()) and the
|
||||
* typedefs Self and Handle.
|
||||
*/
|
||||
#define COMPOSITE_RULE( classname, mesh_type ) \
|
||||
protected:\
|
||||
friend class CompositeT<mesh_type>; \
|
||||
public: \
|
||||
const char *type() const { return #classname; } \
|
||||
typedef classname<mesh_type> Self; \
|
||||
typedef RuleHandleT< Self > Handle
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Base class for adaptive composite subdivision rules
|
||||
* \see class CompositeT
|
||||
*/
|
||||
template <typename M> class RuleInterfaceT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef M Mesh;
|
||||
typedef RuleInterfaceT<M> Self;
|
||||
typedef RuleHandleT< Self > Rule;
|
||||
|
||||
typedef typename M::Scalar scalar_t;
|
||||
|
||||
protected:
|
||||
|
||||
/// Default constructor
|
||||
RuleInterfaceT(Mesh& _mesh) : mesh_(_mesh) {};
|
||||
|
||||
public:
|
||||
|
||||
/// Destructor
|
||||
virtual ~RuleInterfaceT() {};
|
||||
|
||||
|
||||
/// Returns the name of the rule.
|
||||
/// Use define COMPOSITE_RULE to overload this function in a derived class.
|
||||
virtual const char *type() const = 0;
|
||||
|
||||
public:
|
||||
|
||||
/// \name Raise item
|
||||
//@{
|
||||
/// Raise item to target state \c _target_state.
|
||||
virtual void raise(typename M::FaceHandle& _fh, state_t _target_state)
|
||||
{
|
||||
if (mesh_.data(_fh).state() < _target_state) {
|
||||
update(_fh, _target_state);
|
||||
mesh_.data(_fh).inc_state();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void raise(typename M::EdgeHandle& _eh, state_t _target_state)
|
||||
{
|
||||
if (mesh_.data(_eh).state() < _target_state) {
|
||||
update(_eh, _target_state);
|
||||
mesh_.data(_eh).inc_state();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void raise(typename M::VertexHandle& _vh, state_t _target_state)
|
||||
{
|
||||
if (mesh_.data(_vh).state() < _target_state) {
|
||||
update(_vh, _target_state);
|
||||
mesh_.data(_vh).inc_state();
|
||||
}
|
||||
}
|
||||
//@}
|
||||
|
||||
void update(typename M::FaceHandle& _fh, state_t _target_state)
|
||||
{
|
||||
typename M::FaceHandle opp_fh;
|
||||
|
||||
while (mesh_.data(_fh).state() < _target_state - 1) {
|
||||
prev_rule()->raise(_fh, _target_state - 1);
|
||||
}
|
||||
|
||||
// Don't use unflipped / unfinal faces!!!
|
||||
if (subdiv_type() == 3) {
|
||||
|
||||
if (mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh))).is_valid()) {
|
||||
|
||||
while (!mesh_.data(_fh).final()) {
|
||||
|
||||
opp_fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh)));
|
||||
|
||||
assert (mesh_.data(_fh).state() >=
|
||||
mesh_.data(opp_fh).state());
|
||||
|
||||
// different states: raise other face
|
||||
if (mesh_.data(_fh).state() > mesh_.data(opp_fh).state()){
|
||||
|
||||
// raise opposite face
|
||||
prev_rule()->raise(opp_fh, _target_state - 1);
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
// equal states
|
||||
|
||||
// flip edge
|
||||
// typename M::EdgeHandle eh(mesh_.edge_handle(mesh_.halfedge_handle(_fh)));
|
||||
|
||||
// if (mesh_.is_flip_ok(eh)) {
|
||||
|
||||
// std::cout << "Flipping Edge...\n";
|
||||
|
||||
// mesh_.flip(eh);
|
||||
|
||||
// mesh_.data(_fh).set_final();
|
||||
// mesh_.data(opp_fh).set_final();
|
||||
// }
|
||||
|
||||
// else {
|
||||
|
||||
// std::cout << "Flip not okay.\n";
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
// mesh_.data(_fh).set_final();
|
||||
}
|
||||
|
||||
// std::cout << "Raising Face to Level "
|
||||
// << _target_state
|
||||
// << " with "
|
||||
// << type()
|
||||
// << ".\n";
|
||||
|
||||
}
|
||||
|
||||
assert( subdiv_type() != 4 ||
|
||||
mesh_.data(_fh).final() ||
|
||||
_target_state%n_rules() == (subdiv_rule()->number() + 1)%n_rules() );
|
||||
|
||||
typename M::FaceEdgeIter fe_it;
|
||||
typename M::FaceVertexIter fv_it;
|
||||
typename M::EdgeHandle eh;
|
||||
typename M::VertexHandle vh;
|
||||
|
||||
std::vector<typename M::FaceHandle> face_vector;
|
||||
face_vector.clear();
|
||||
|
||||
if (_target_state > 1) {
|
||||
|
||||
for (fe_it = mesh_.fe_iter(_fh); fe_it; ++fe_it) {
|
||||
|
||||
eh = fe_it.handle();
|
||||
prev_rule()->raise(eh, _target_state - 1);
|
||||
}
|
||||
|
||||
for (fv_it = mesh_.fv_iter(_fh); fv_it; ++fv_it) {
|
||||
|
||||
vh = fv_it.handle();
|
||||
prev_rule()->raise(vh, _target_state - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void update(typename M::EdgeHandle& _eh, state_t _target_state)
|
||||
{
|
||||
state_t state(mesh_.data(_eh).state());
|
||||
|
||||
// raise edge to correct state
|
||||
if (state + 1 < _target_state && _target_state > 0) {
|
||||
|
||||
prev_rule()->raise(_eh, _target_state - 1);
|
||||
}
|
||||
|
||||
typename M::VertexHandle vh;
|
||||
typename M::FaceHandle fh;
|
||||
|
||||
if (_target_state > 1)
|
||||
{
|
||||
vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 0));
|
||||
prev_rule()->raise(vh, _target_state - 1);
|
||||
|
||||
vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 1));
|
||||
prev_rule()->raise(vh, _target_state - 1);
|
||||
|
||||
fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 0));
|
||||
if (fh.is_valid())
|
||||
prev_rule()->raise(fh, _target_state - 1);
|
||||
|
||||
fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 1));
|
||||
if (fh.is_valid())
|
||||
prev_rule()->raise(fh, _target_state - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void update(typename M::VertexHandle& _vh, state_t _target_state) {
|
||||
|
||||
state_t state(mesh_.data(_vh).state());
|
||||
|
||||
// raise vertex to correct state
|
||||
if (state + 1 < _target_state)
|
||||
{
|
||||
prev_rule()->raise(_vh, _target_state - 1);
|
||||
}
|
||||
|
||||
std::vector<typename M::HalfedgeHandle> halfedge_vector;
|
||||
halfedge_vector.clear();
|
||||
|
||||
typename M::VertexOHalfedgeIter voh_it;
|
||||
typename M::EdgeHandle eh;
|
||||
typename M::FaceHandle fh;
|
||||
|
||||
if (_target_state > 1)
|
||||
{
|
||||
|
||||
for (voh_it = mesh_.voh_iter(_vh); voh_it; ++voh_it) {
|
||||
halfedge_vector.push_back(voh_it.handle());
|
||||
}
|
||||
|
||||
while ( !halfedge_vector.empty() ) {
|
||||
eh = mesh_.edge_handle(halfedge_vector.back());
|
||||
halfedge_vector.pop_back();
|
||||
|
||||
prev_rule()->raise(eh, _target_state - 1);
|
||||
}
|
||||
|
||||
for (voh_it = mesh_.voh_iter(_vh); voh_it; ++voh_it) {
|
||||
halfedge_vector.push_back(voh_it.handle());
|
||||
}
|
||||
|
||||
while ( !halfedge_vector.empty() ) {
|
||||
fh = mesh_.face_handle(halfedge_vector.back());
|
||||
halfedge_vector.pop_back();
|
||||
|
||||
if (fh.is_valid())
|
||||
prev_rule()->raise(fh, _target_state - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/// Type of split operation, if it is a topological operator
|
||||
int subdiv_type() const { return subdiv_type_; }
|
||||
|
||||
|
||||
/// Position in rule sequence
|
||||
int number() const { return number_; }
|
||||
|
||||
/// \name Parameterization of rule
|
||||
//@{
|
||||
|
||||
/// Set coefficient - ignored by non-parameterized rules.
|
||||
virtual void set_coeff( scalar_t _coeff ) { coeff_ = _coeff; }
|
||||
|
||||
/// Get coefficient - ignored by non-parameterized rules.
|
||||
scalar_t coeff() const { return coeff_; }
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
void set_prev_rule(Self*& _p) { prev_rule_ = _p; }
|
||||
Self* prev_rule() { return prev_rule_; }
|
||||
|
||||
void set_subdiv_rule(Self*& _n) { subdiv_rule_ = _n; }
|
||||
Self* subdiv_rule() { return subdiv_rule_; }
|
||||
|
||||
void set_number(int _n) { number_ = _n; }
|
||||
|
||||
void set_n_rules(int _n) { n_rules_ = _n; }
|
||||
int n_rules() { return n_rules_; }
|
||||
|
||||
void set_subdiv_type(int _n)
|
||||
{ assert(_n == 3 || _n == 4); subdiv_type_ = _n; }
|
||||
|
||||
friend class CompositeT<M>;
|
||||
|
||||
protected:
|
||||
|
||||
Mesh& mesh_;
|
||||
|
||||
private:
|
||||
|
||||
Self* prev_rule_;
|
||||
Self* subdiv_rule_;
|
||||
|
||||
int subdiv_type_;
|
||||
int number_;
|
||||
int n_rules_;
|
||||
|
||||
scalar_t coeff_;
|
||||
|
||||
private: // Noncopyable
|
||||
|
||||
RuleInterfaceT(const RuleInterfaceT&);
|
||||
RuleInterfaceT& operator=(const RuleInterfaceT&);
|
||||
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH defined
|
||||
//=============================================================================
|
||||
|
||||
2015
Tools/Subdivider/Adaptive/Composite/RulesT.cc
Normal file
2015
Tools/Subdivider/Adaptive/Composite/RulesT.cc
Normal file
File diff suppressed because it is too large
Load Diff
525
Tools/Subdivider/Adaptive/Composite/RulesT.hh
Normal file
525
Tools/Subdivider/Adaptive/Composite/RulesT.hh
Normal file
@@ -0,0 +1,525 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 RulesT.hh
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Composite Subdivision and Averaging Rules
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_RULEST_HH
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_RULEST_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh>
|
||||
// -------------------- STL
|
||||
#include <vector>
|
||||
|
||||
|
||||
#if defined(OM_CC_MIPS) // avoid warnings
|
||||
# define MIPS_WARN_WA( Item ) \
|
||||
void raise(typename M:: ## Item ## Handle &_h, state_t _target_state ) \
|
||||
{ Inherited::raise(_h, _target_state); }
|
||||
#else
|
||||
# define MIPS_WARN_WA( Item )
|
||||
#endif
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_SUBDIVIDER
|
||||
namespace Adaptive { // BEGIN_NS_ADAPTIVE
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Adaptive Composite Subdivision framework.
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/** Topological composite rule Tvv,3 doing a 1-3 split of a face.
|
||||
*/
|
||||
template <class M> class Tvv3 : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( Tvv3, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
Tvv3(M& _mesh) : Inherited(_mesh) { Base::set_subdiv_type(3); };
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Topological composite rule Tvv,4 doing a 1-4 split of a face
|
||||
*/
|
||||
template <class M> class Tvv4 : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( Tvv4, M );
|
||||
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
public:
|
||||
typedef typename M::HalfedgeHandle HEH;
|
||||
typedef typename M::VertexHandle VH;
|
||||
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
Tvv4(M& _mesh) : Inherited(_mesh) { Base::set_subdiv_type(4); };
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
|
||||
private:
|
||||
|
||||
void split_edge(HEH& _hh, VH& _vh, state_t _target_state);
|
||||
void check_edge(const typename M::HalfedgeHandle& _hh,
|
||||
state_t _target_state);
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VF
|
||||
*/
|
||||
template <class M> class VF : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VF, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VF(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
MIPS_WARN_WA(Edge);
|
||||
MIPS_WARN_WA(Vertex);
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule FF
|
||||
*/
|
||||
template <class M> class FF : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( FF, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
FF(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
MIPS_WARN_WA(Edge ); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule FFc
|
||||
*/
|
||||
template <class M> class FFc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( FFc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
FFc(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
MIPS_WARN_WA(Edge ); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule FV
|
||||
*/
|
||||
template <class M> class FV : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( FV, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
FV(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule FVc
|
||||
*/
|
||||
template <class M> class FVc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( FVc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
FVc(M& _mesh) : Inherited(_mesh) { init_coeffs(50); }
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
|
||||
static void init_coeffs(size_t _max_valence);
|
||||
static const std::vector<double>& coeffs() { return coeffs_; }
|
||||
|
||||
double coeff( size_t _valence )
|
||||
{
|
||||
assert(_valence < coeffs_.size());
|
||||
return coeffs_[_valence];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static std::vector<double> coeffs_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VV
|
||||
*/
|
||||
template <class M> class VV : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VV, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VV(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VVc
|
||||
*/
|
||||
template <class M> class VVc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VVc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VVc(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VE
|
||||
*/
|
||||
template <class M> class VE : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VE, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VE(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VdE
|
||||
*/
|
||||
template <class M> class VdE : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VdE, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VdE(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VdEc
|
||||
*/
|
||||
template <class M> class VdEc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VdEc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VdEc(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule EV
|
||||
*/
|
||||
template <class M> class EV : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( EV, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
EV(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule EVc
|
||||
*/
|
||||
template <class M> class EVc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( EVc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
EVc(M& _mesh) : Inherited(_mesh) { init_coeffs(50); }
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
|
||||
static void init_coeffs(size_t _max_valence);
|
||||
static const std::vector<double>& coeffs() { return coeffs_; }
|
||||
|
||||
double coeff( size_t _valence )
|
||||
{
|
||||
assert(_valence < coeffs_.size());
|
||||
return coeffs_[_valence];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static std::vector<double> coeffs_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule EF
|
||||
*/
|
||||
template <class M> class EF : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( EF, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
EF(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
MIPS_WARN_WA(Edge ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule FE
|
||||
*/
|
||||
template <class M> class FE : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( FE, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
FE(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule EdE
|
||||
*/
|
||||
template <class M> class EdE : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( EdE, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
EdE(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule EdEc
|
||||
*/
|
||||
template <class M> class EdEc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( EdEc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
EdEc(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#undef MIPS_WARN_WA
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SUBDIVIDER_ADAPTIVE_RULEST_CC)
|
||||
# define OPENMESH_SUBDIVIDER_TEMPLATES
|
||||
# include "RulesT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_ADAPTIVE_RULEST_HH defined
|
||||
//=============================================================================
|
||||
|
||||
237
Tools/Subdivider/Adaptive/Composite/Traits.hh
Normal file
237
Tools/Subdivider/Adaptive/Composite/Traits.hh
Normal file
@@ -0,0 +1,237 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 Traits.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS Traits
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_TRAITS_HH
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_TRAITS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <map>
|
||||
#include <OpenMesh/Core/Mesh/Types/TriMesh_ArrayKernelT.hh>
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Adaptive { // BEGIN_NS_UNIFORM
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Adaptive Composite Subdivision framework.
|
||||
*/
|
||||
|
||||
// typedef unsigned short state_t;
|
||||
// const state_t mask_final = 1 << ((sizeof(state_t)*8)-1);
|
||||
// const state_t mask_state = ~mask_final;
|
||||
|
||||
typedef int state_t;
|
||||
typedef bool final_t;
|
||||
|
||||
struct State
|
||||
{
|
||||
int state : 31;
|
||||
unsigned final : 1;
|
||||
};
|
||||
|
||||
struct Traits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
|
||||
// add face normals
|
||||
FaceAttributes( OpenMesh::Attributes::Normal );
|
||||
|
||||
// add vertex normals
|
||||
VertexAttributes( OpenMesh::Attributes::Normal );
|
||||
|
||||
// add previous halfedge handle
|
||||
HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );
|
||||
|
||||
FaceTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef typename Refs::HalfedgeHandle HalfedgeHandle;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
HalfedgeHandle red_halfedge_;
|
||||
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
// face state
|
||||
state_t state() const { return state_t(state_.state); }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
// face not final if divided (loop) or edge not flipped (sqrt(3))
|
||||
final_t final() const { return final_t(state_.final); }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// halfedge of dividing edge (red-green triangulation)
|
||||
const HalfedgeHandle& red_halfedge() const { return red_halfedge_; }
|
||||
void set_red_halfedge(const HalfedgeHandle& _h) { red_halfedge_ = _h; }
|
||||
|
||||
// position of face, depending on generation _i.
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
const Point position(const int& _i) {
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
return pos_map_[_i];
|
||||
else {
|
||||
|
||||
if (_i <= 0) {
|
||||
const Point zero_point(0.0, 0.0, 0.0);
|
||||
return zero_point;
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class FaceTraits
|
||||
|
||||
|
||||
EdgeTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Refs::Scalar Scalar;
|
||||
|
||||
// Scalar weight_;
|
||||
|
||||
// state of edge
|
||||
state_t state() const { return state_t(state_.state); }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
// edge not final if dividing face (Loop) or edge not flipped (SQRT(3))
|
||||
final_t final() const { return final_t(state_.final); }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// position of edge, depending on generation _i.
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
const Point position(const int& _i) {
|
||||
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
{
|
||||
return pos_map_[_i];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_i <= 0)
|
||||
{
|
||||
const Point zero_point(0.0, 0.0, 0.0);
|
||||
return zero_point;
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class EdgeTraits
|
||||
|
||||
|
||||
VertexTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
// state of vertex
|
||||
state_t state() const { return state_.state; }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
|
||||
// usually not needed by loop or sqrt(3)
|
||||
final_t final() const { return state_.final; }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// position of vertex, depending on generation _i. (not for display)
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
const Point position(const int& _i) {
|
||||
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
|
||||
return pos_map_[_i];
|
||||
|
||||
else {
|
||||
|
||||
if (_i <= 0) {
|
||||
|
||||
const Point zero_point(0.0, 0.0, 0.0);
|
||||
return zero_point;
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class VertexTraits
|
||||
}; // end class Traits
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_ADAPTIVE_TRAITS_HH defined
|
||||
//=============================================================================
|
||||
17
Tools/Subdivider/Uniform/ACGMakefile
Normal file
17
Tools/Subdivider/Uniform/ACGMakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS = $(call find-subdirs)
|
||||
|
||||
PACKAGES :=
|
||||
|
||||
PROJ_LIBS :=
|
||||
|
||||
MODULES := cxxlib
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
17
Tools/Subdivider/Uniform/Composite/ACGMakefile
Normal file
17
Tools/Subdivider/Uniform/Composite/ACGMakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS = $(call find-subdirs)
|
||||
|
||||
PACKAGES :=
|
||||
|
||||
PROJ_LIBS :=
|
||||
|
||||
MODULES := cxxlib
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
1310
Tools/Subdivider/Uniform/Composite/CompositeT.cc
Normal file
1310
Tools/Subdivider/Uniform/Composite/CompositeT.cc
Normal file
File diff suppressed because it is too large
Load Diff
233
Tools/Subdivider/Uniform/Composite/CompositeT.hh
Normal file
233
Tools/Subdivider/Uniform/Composite/CompositeT.hh
Normal file
@@ -0,0 +1,233 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 Uniform/Composite/CompositeT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS CompositeT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITE_HH
|
||||
#define OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITE_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
// --------------------
|
||||
#include <OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh>
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Uniform { // BEGIN_NS_UNIFORM
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** This class provides the composite subdivision rules for the uniform case.
|
||||
*
|
||||
* To create a subdivider derive from this class and overload the functions
|
||||
* name() and apply_rules(). In the latter one call the wanted rules.
|
||||
*
|
||||
* For details on the composite scheme refer to
|
||||
* - <a
|
||||
* href="http://cm.bell-labs.com/who/poswald/sqrt3.pdf">P. Oswald,
|
||||
* P. Schroeder "Composite primal/dual sqrt(3)-subdivision schemes",
|
||||
* CAGD 20, 3, 2003, 135--164</a>
|
||||
|
||||
* \note Not all rules are implemented!
|
||||
* \see class Adaptive::CompositeT
|
||||
*/
|
||||
template <typename MeshType, typename RealType=float >
|
||||
class CompositeT : public SubdividerT< MeshType, RealType >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef RealType real_t;
|
||||
typedef MeshType mesh_t;
|
||||
typedef SubdividerT< mesh_t, real_t > parent_t;
|
||||
|
||||
public:
|
||||
|
||||
CompositeT(void) : parent_t(), p_mesh_(NULL) {}
|
||||
CompositeT(MeshType& _mesh) : parent_t(_mesh), p_mesh_(NULL) {};
|
||||
virtual ~CompositeT() { }
|
||||
|
||||
public: // inherited interface
|
||||
|
||||
virtual const char *name( void ) const = 0;
|
||||
|
||||
protected: // inherited interface
|
||||
|
||||
bool prepare( MeshType& _m );
|
||||
|
||||
bool subdivide( MeshType& _m, size_t _n )
|
||||
{
|
||||
assert( p_mesh_ == &_m );
|
||||
|
||||
while(_n--)
|
||||
{
|
||||
apply_rules();
|
||||
commit(_m);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
bool cleanup( MeshType& )
|
||||
#else
|
||||
bool cleanup( MeshType& _m )
|
||||
#endif
|
||||
{
|
||||
assert( p_mesh_ == &_m );
|
||||
p_mesh_=NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/// Assemble here the rule sequence, by calling the constructor
|
||||
/// of the wanted rules.
|
||||
virtual void apply_rules(void) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/// Move vertices to new positions after the rules have been applied
|
||||
/// to the mesh (called by subdivide()).
|
||||
void commit( MeshType &_m)
|
||||
{
|
||||
typename MeshType::VertexIter v_it;
|
||||
|
||||
for (v_it=_m.vertices_begin(); v_it != _m.vertices_end(); ++v_it)
|
||||
_m.set_point(v_it.handle(), _m.data(v_it).position());
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/// Abstract base class for coefficient functions
|
||||
struct Coeff
|
||||
{
|
||||
virtual ~Coeff() { }
|
||||
virtual double operator() (size_t _valence) = 0;
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
typedef typename MeshType::Scalar scalar_t;
|
||||
typedef typename MeshType::VertexHandle VertexHandle;
|
||||
typedef typename MeshType::FaceHandle FaceHandle;
|
||||
typedef typename MeshType::EdgeHandle EdgeHandle;
|
||||
typedef typename MeshType::HalfedgeHandle HalfedgeHandle;
|
||||
|
||||
/// \name Uniform composite subdivision rules
|
||||
//@{
|
||||
|
||||
|
||||
void Tvv3(); ///< Split Face, using Vertex information (1-3 split)
|
||||
void Tvv4(); ///< Split Face, using Vertex information (1-4 split)
|
||||
void Tfv(); ///< Split Face, using Face Information
|
||||
|
||||
void FF(); ///< Face to face averaging.
|
||||
void FFc(Coeff& _coeff); ///< Weighted face to face averaging.
|
||||
void FFc(scalar_t _c); ///< Weighted face to face averaging.
|
||||
|
||||
void FV(); ///< Face to vertex averaging.
|
||||
void FVc(Coeff& _coeff); ///< Weighted face to vertex Averaging with flaps
|
||||
void FVc(scalar_t _c); ///< Weighted face to vertex Averaging with flaps
|
||||
|
||||
void FE(); ///< Face to edge averaging.
|
||||
|
||||
void VF(); ///< Vertex to Face Averaging.
|
||||
void VFa(Coeff& _coeff); ///< Vertex to Face Averaging, weighted.
|
||||
void VFa(scalar_t _alpha); ///< Vertex to Face Averaging, weighted.
|
||||
|
||||
void VV(); ///< Vertex to vertex averaging.
|
||||
void VVc(Coeff& _coeff); ///< Vertex to vertex averaging, weighted.
|
||||
void VVc(scalar_t _c); ///< Vertex to vertex averaging, weighted.
|
||||
|
||||
void VE(); ///< VE Step (Vertex to Edge Averaging)
|
||||
|
||||
|
||||
void VdE(); ///< Vertex to edge averaging, using diamond of edges.
|
||||
void VdEc(scalar_t _c); ///< Weighted vertex to edge averaging, using diamond of edges
|
||||
|
||||
/// Weigthed vertex to edge averaging, using diamond of edges for
|
||||
/// irregular vertices.
|
||||
void VdEg(Coeff& _coeff);
|
||||
/// Weigthed vertex to edge averaging, using diamond of edges for
|
||||
/// irregular vertices.
|
||||
void VdEg(scalar_t _gamma);
|
||||
|
||||
void EF(); ///< Edge to face averaging.
|
||||
|
||||
void EV(); ///< Edge to vertex averaging.
|
||||
void EVc(Coeff& _coeff); ///< Weighted edge to vertex averaging.
|
||||
void EVc(scalar_t _c); ///< Weighted edge to vertex averaging.
|
||||
|
||||
void EdE(); ///< Edge to edge averaging w/ flap rule.
|
||||
void EdEc(scalar_t _c); ///< Weighted edge to edge averaging w/ flap rule.
|
||||
|
||||
|
||||
//@}
|
||||
|
||||
void corner_cutting(HalfedgeHandle _heh);
|
||||
|
||||
VertexHandle split_edge(HalfedgeHandle _heh);
|
||||
|
||||
private:
|
||||
|
||||
MeshType* p_mesh_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_UNIFORM
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITE_CC)
|
||||
#define OPENMESH_SUBDIVIDER_TEMPLATES
|
||||
#include "CompositeT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMPOSITET_HH defined
|
||||
//=============================================================================
|
||||
|
||||
150
Tools/Subdivider/Uniform/Composite/CompositeTraits.hh
Normal file
150
Tools/Subdivider/Uniform/Composite/CompositeTraits.hh
Normal file
@@ -0,0 +1,150 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 Uniform/Composite/CompositeTraits.hh
|
||||
Mesh traits for uniform composite subdivision.
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS Traits
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITETRAITS_HH
|
||||
#define OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITETRAITS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
//#include "Config.hh"
|
||||
// --------------------
|
||||
#include <OpenMesh/Core/Mesh/Traits.hh>
|
||||
#include <OpenMesh/Core/Mesh/Attributes.hh>
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Uniform { // BEGIN_NS_UNIFORM
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Uniform Composite Subdivision framework.
|
||||
*/
|
||||
|
||||
struct CompositeTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
FaceAttributes( OpenMesh::Attributes::Normal );
|
||||
|
||||
VertexAttributes( OpenMesh::Attributes::Normal );
|
||||
|
||||
//HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );
|
||||
|
||||
FaceTraits
|
||||
{
|
||||
private:
|
||||
typedef typename Refs::HalfedgeHandle HalfedgeHandle;
|
||||
typedef typename Refs::Scalar Scalar;
|
||||
typedef typename Refs::Point Point;
|
||||
HalfedgeHandle red_halfedge_handle_;
|
||||
unsigned int generation_;
|
||||
bool red_;
|
||||
Scalar quality_;
|
||||
Point midpoint_;
|
||||
Point position_;
|
||||
|
||||
public:
|
||||
const unsigned int& generation() { return generation_; }
|
||||
void set_generation(const unsigned int& _g) { generation_ = _g; }
|
||||
void inc_generation() { ++generation_; }
|
||||
void set_red() { red_ = 1; }
|
||||
void set_green() {red_ = 0; }
|
||||
bool is_red() { return red_; }
|
||||
bool is_green() { return !red_; }
|
||||
void set_red_halfedge_handle(HalfedgeHandle& _heh)
|
||||
{ red_halfedge_handle_ = _heh; }
|
||||
HalfedgeHandle& red_halfedge_handle() { return red_halfedge_handle_; }
|
||||
void set_quality(Scalar& _q) { quality_ = _q; }
|
||||
Scalar& quality() { return quality_; }
|
||||
const Point& midpoint() const { return midpoint_; }
|
||||
void set_midpoint(const Point& _p) { midpoint_ = _p; }
|
||||
const Point& position() const { return position_; }
|
||||
void set_position(const Point& _p) { position_ = _p; }
|
||||
};
|
||||
|
||||
EdgeTraits
|
||||
{
|
||||
private:
|
||||
typedef typename Refs::Point Point;
|
||||
typedef typename Refs::Scalar Scalar;
|
||||
Point midpoint_;
|
||||
Scalar length_;
|
||||
Point position_;
|
||||
public:
|
||||
const Point& midpoint() const { return midpoint_; }
|
||||
void set_midpoint(const Point& _vh) { midpoint_ = _vh; }
|
||||
const Scalar& length() const { return length_; }
|
||||
void set_length(const Scalar& _s) { length_ = _s; }
|
||||
const Point& position() const { return position_; }
|
||||
void set_position(const Point& _p) { position_ = _p; }
|
||||
};
|
||||
|
||||
VertexTraits
|
||||
{
|
||||
private:
|
||||
typedef typename Refs::Point Point;
|
||||
Point new_pos_;
|
||||
Point orig_pos_;
|
||||
Point position_;
|
||||
unsigned int generation_;
|
||||
public:
|
||||
const Point& new_pos() const { return new_pos_; }
|
||||
void set_new_pos(const Point& _p) { new_pos_ = _p; }
|
||||
const unsigned int& generation() const { return generation_; }
|
||||
void set_generation(const unsigned int& _i) { generation_ = _i; }
|
||||
const Point& orig_pos() const { return orig_pos_; }
|
||||
void set_orig_pos(const Point& _p) { orig_pos_ = _p; }
|
||||
const Point& position() const { return position_; }
|
||||
void set_position(const Point& _p) { position_ = _p; }
|
||||
};
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_UNIFORM
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITETRAITS_HH defined
|
||||
//=============================================================================
|
||||
|
||||
139
Tools/Subdivider/Uniform/CompositeLoopT.hh
Normal file
139
Tools/Subdivider/Uniform/CompositeLoopT.hh
Normal file
@@ -0,0 +1,139 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 CompositeLoopT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LoopT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITELOOPT_HH
|
||||
#define OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITELOOPT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "Composite/CompositeT.hh"
|
||||
#include "Composite/CompositeTraits.hh"
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Uniform { // BEGIN_NS_DECIMATER
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Uniform composite Loop subdivision algorithm
|
||||
*/
|
||||
template <class MeshType, class RealType=float>
|
||||
class CompositeLoopT : public CompositeT<MeshType, RealType>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef CompositeT<MeshType, RealType> Inherited;
|
||||
|
||||
public:
|
||||
|
||||
CompositeLoopT() : Inherited() {};
|
||||
CompositeLoopT(MeshType& _mesh) : Inherited(_mesh) {};
|
||||
~CompositeLoopT() {}
|
||||
|
||||
public:
|
||||
|
||||
const char *name() const { return "Uniform Composite Loop"; }
|
||||
|
||||
protected: // inherited interface
|
||||
|
||||
void apply_rules(void)
|
||||
{
|
||||
Inherited::Tvv4();
|
||||
Inherited::VdE();
|
||||
Inherited::EVc(coeffs_);
|
||||
Inherited::VdE();
|
||||
Inherited::EVc(coeffs_);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
typedef typename Inherited::Coeff Coeff;
|
||||
|
||||
|
||||
/** Helper struct
|
||||
* \internal
|
||||
*/
|
||||
struct EVCoeff : public Coeff
|
||||
{
|
||||
EVCoeff() : Coeff() { init(50); }
|
||||
|
||||
void init(size_t _max_valence)
|
||||
{
|
||||
weights_.resize(_max_valence);
|
||||
std::generate(weights_.begin(),
|
||||
weights_.end(), compute_weight() );
|
||||
}
|
||||
|
||||
double operator()(size_t _valence) { return weights_[_valence]; }
|
||||
|
||||
/// \internal
|
||||
struct compute_weight
|
||||
{
|
||||
compute_weight() : val_(0) { }
|
||||
|
||||
double operator()(void) // Loop weights for non-boundary vertices
|
||||
{
|
||||
// 1 3 2 * pi
|
||||
// - * ( --- + cos ( ------- ) )<29> - 1.0
|
||||
// 2 2 valence
|
||||
double f1 = 1.5 + cos(2.0*M_PI/val_++);
|
||||
return 0.5 * f1 * f1 - 1.0;
|
||||
}
|
||||
size_t val_;
|
||||
|
||||
};
|
||||
|
||||
std::vector<double> weights_;
|
||||
} coeffs_;
|
||||
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_UNIFORM
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITELOOPT_HH defined
|
||||
//=============================================================================
|
||||
135
Tools/Subdivider/Uniform/CompositeSqrt3T.hh
Normal file
135
Tools/Subdivider/Uniform/CompositeSqrt3T.hh
Normal file
@@ -0,0 +1,135 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 CompositeSqrt3T.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS SQRT3T
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITESQRT3T_HH
|
||||
#define OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITESQRT3T_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "Composite/CompositeT.hh"
|
||||
#include "Composite/CompositeTraits.hh"
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Uniform { // BEGIN_NS_UNIFORM
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Uniform composite sqrt(3) subdivision algorithm
|
||||
*/
|
||||
template <typename MeshType, typename RealType=float>
|
||||
class CompositeSqrt3T : public CompositeT<MeshType, RealType>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef CompositeT<MeshType, RealType> Inherited;
|
||||
|
||||
public:
|
||||
|
||||
CompositeSqrt3T() : Inherited() {};
|
||||
CompositeSqrt3T(MeshType& _mesh) : Inherited(_mesh) {};
|
||||
~CompositeSqrt3T() {}
|
||||
|
||||
public:
|
||||
|
||||
const char *name() const { return "Uniform Composite Sqrt3"; }
|
||||
|
||||
protected: // inherited interface
|
||||
|
||||
void apply_rules(void)
|
||||
{
|
||||
Inherited::Tvv3();
|
||||
Inherited::VF();
|
||||
Inherited::FF();
|
||||
Inherited::FVc(coeffs_);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
typedef typename Inherited::Coeff Coeff;
|
||||
|
||||
/** Helper class
|
||||
* \internal
|
||||
*/
|
||||
struct FVCoeff : public Coeff
|
||||
{
|
||||
FVCoeff() : Coeff() { init(50); }
|
||||
|
||||
void init(size_t _max_valence)
|
||||
{
|
||||
weights_.resize(_max_valence);
|
||||
std::generate(weights_.begin(),
|
||||
weights_.end(), compute_weight() );
|
||||
}
|
||||
|
||||
double operator()(size_t _valence) { return weights_[_valence]; }
|
||||
|
||||
/** \internal
|
||||
*/
|
||||
struct compute_weight
|
||||
{
|
||||
compute_weight() : val_(0) { }
|
||||
|
||||
double operator()(void) // sqrt(3) weights for non-boundary vertices
|
||||
{
|
||||
return 2.0/3.0 * (cos(2.0*M_PI/val_++)+1.0);
|
||||
}
|
||||
size_t val_;
|
||||
};
|
||||
|
||||
std::vector<double> weights_;
|
||||
|
||||
} coeffs_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_UNIFORM
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITESQRT3T_HH defined
|
||||
//=============================================================================
|
||||
451
Tools/Subdivider/Uniform/LoopT.hh
Normal file
451
Tools/Subdivider/Uniform/LoopT.hh
Normal file
@@ -0,0 +1,451 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 LoopT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LoopT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_UNIFORM_LOOPT_HH
|
||||
#define OPENMESH_SUBDIVIDER_UNIFORM_LOOPT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh>
|
||||
#include <OpenMesh/Core/Utils/vector_cast.hh>
|
||||
// -------------------- STL
|
||||
#include <vector>
|
||||
#if defined(OM_CC_MIPS)
|
||||
# include <math.h>
|
||||
#else
|
||||
# include <cmath>
|
||||
#endif
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Uniform { // BEGIN_NS_DECIMATER
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** %Uniform Loop subdivision algorithm.
|
||||
*
|
||||
* Implementation as described in
|
||||
*
|
||||
* C. T. Loop, "Smooth Subdivision Surfaces Based on Triangles",
|
||||
* M.S. Thesis, Department of Mathematics, University of Utah, August 1987.
|
||||
*
|
||||
*/
|
||||
template <typename MeshType, typename RealType = float>
|
||||
class LoopT : public SubdividerT<MeshType, RealType>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef RealType real_t;
|
||||
typedef MeshType mesh_t;
|
||||
typedef SubdividerT< mesh_t, real_t > parent_t;
|
||||
|
||||
typedef std::pair< real_t, real_t > weight_t;
|
||||
typedef std::vector< std::pair<real_t,real_t> > weights_t;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
LoopT(void) : parent_t(), _1over8( 1.0/8.0 ), _3over8( 3.0/8.0 )
|
||||
{ init_weights(); }
|
||||
|
||||
|
||||
LoopT( mesh_t& _m ) : parent_t(_m), _1over8( 1.0/8.0 ), _3over8( 3.0/8.0 )
|
||||
{ init_weights(); }
|
||||
|
||||
|
||||
~LoopT() {}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
const char *name() const { return "Uniform Loop"; }
|
||||
|
||||
|
||||
/// Pre-compute weights
|
||||
void init_weights(size_t _max_valence=50)
|
||||
{
|
||||
weights_.resize(_max_valence);
|
||||
std::generate(weights_.begin(), weights_.end(), compute_weight());
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
bool prepare( mesh_t& _m )
|
||||
{
|
||||
_m.add_property( vp_pos_ );
|
||||
_m.add_property( ep_pos_ );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool cleanup( mesh_t& _m )
|
||||
{
|
||||
_m.remove_property( vp_pos_ );
|
||||
_m.remove_property( ep_pos_ );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool subdivide( mesh_t& _m, size_t _n)
|
||||
{
|
||||
typename mesh_t::FaceIter fit, f_end;
|
||||
typename mesh_t::EdgeIter eit, e_end;
|
||||
typename mesh_t::VertexIter vit;
|
||||
|
||||
// Do _n subdivisions
|
||||
for (size_t i=0; i < _n; ++i)
|
||||
{
|
||||
// compute new positions for old vertices
|
||||
for ( vit = _m.vertices_begin();
|
||||
vit != _m.vertices_end(); ++vit)
|
||||
smooth( _m, vit.handle() );
|
||||
|
||||
|
||||
// Compute position for new vertices and store them in the edge property
|
||||
for (eit=_m.edges_begin(); eit != _m.edges_end(); ++eit)
|
||||
compute_midpoint( _m, eit.handle() );
|
||||
|
||||
|
||||
// Split each edge at midpoint and store precomputed positions (stored in
|
||||
// edge property ep_pos_) in the vertex property vp_pos_;
|
||||
|
||||
// Attention! Creating new edges, hence make sure the loop ends correctly.
|
||||
e_end = _m.edges_end();
|
||||
for (eit=_m.edges_begin(); eit != e_end; ++eit)
|
||||
split_edge(_m, eit.handle() );
|
||||
|
||||
|
||||
// Commit changes in topology and reconsitute consistency
|
||||
|
||||
// Attention! Creating new faces, hence make sure the loop ends correctly.
|
||||
f_end = _m.faces_end();
|
||||
for (fit = _m.faces_begin(); fit != f_end; ++fit)
|
||||
split_face(_m, fit.handle() );
|
||||
|
||||
|
||||
// Commit changes in geometry
|
||||
for ( vit = _m.vertices_begin();
|
||||
vit != _m.vertices_end(); ++vit)
|
||||
_m.set_point(vit, _m.property( vp_pos_, vit ) );
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUG)
|
||||
// Now we have an consistent mesh!
|
||||
assert( OpenMesh::Utils::MeshCheckerT<mesh_t>(_m).check() );
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// Helper functor to compute weights for Loop-subdivision
|
||||
/// \internal
|
||||
struct compute_weight
|
||||
{
|
||||
compute_weight() : valence(-1) { }
|
||||
weight_t operator() (void)
|
||||
{
|
||||
#if !defined(OM_CC_MIPS)
|
||||
using std::cos;
|
||||
#endif
|
||||
// 1
|
||||
// alpha(n) = ---- * (40 - ( 3 + 2 cos( 2 Pi / n ) )<29> )
|
||||
// 64
|
||||
|
||||
if (++valence)
|
||||
{
|
||||
double inv_v = 1.0/double(valence);
|
||||
double t = (3.0 + 2.0 * cos( 2.0 * M_PI * inv_v) );
|
||||
double alpha = (40.0 - t * t)/64.0;
|
||||
|
||||
return weight_t( 1.0-alpha, inv_v*alpha);
|
||||
}
|
||||
return weight_t(0.0, 0.0);
|
||||
}
|
||||
int valence;
|
||||
};
|
||||
|
||||
private: // topological modifiers
|
||||
|
||||
void split_face(mesh_t& _m, const typename mesh_t::FaceHandle& _fh)
|
||||
{
|
||||
typename mesh_t::HalfedgeHandle
|
||||
heh1(_m.halfedge_handle(_fh)),
|
||||
heh2(_m.next_halfedge_handle(_m.next_halfedge_handle(heh1))),
|
||||
heh3(_m.next_halfedge_handle(_m.next_halfedge_handle(heh2)));
|
||||
|
||||
// Cutting off every corner of the 6_gon
|
||||
corner_cutting( _m, heh1 );
|
||||
corner_cutting( _m, heh2 );
|
||||
corner_cutting( _m, heh3 );
|
||||
}
|
||||
|
||||
|
||||
void corner_cutting(mesh_t& _m, const typename mesh_t::HalfedgeHandle& _he)
|
||||
{
|
||||
// Define Halfedge Handles
|
||||
typename mesh_t::HalfedgeHandle
|
||||
heh1(_he),
|
||||
heh5(heh1),
|
||||
heh6(_m.next_halfedge_handle(heh1));
|
||||
|
||||
// Cycle around the polygon to find correct Halfedge
|
||||
for (; _m.next_halfedge_handle(_m.next_halfedge_handle(heh5)) != heh1;
|
||||
heh5 = _m.next_halfedge_handle(heh5))
|
||||
{}
|
||||
|
||||
typename mesh_t::VertexHandle
|
||||
vh1 = _m.to_vertex_handle(heh1),
|
||||
vh2 = _m.to_vertex_handle(heh5);
|
||||
|
||||
typename mesh_t::HalfedgeHandle
|
||||
heh2(_m.next_halfedge_handle(heh5)),
|
||||
heh3(_m.new_edge( vh1, vh2)),
|
||||
heh4(_m.opposite_halfedge_handle(heh3));
|
||||
|
||||
/* Intermediate result
|
||||
*
|
||||
* *
|
||||
* 5 /|\
|
||||
* /_ \
|
||||
* vh2> * *
|
||||
* /|\3 |\
|
||||
* /_ \|4 \
|
||||
* *----\*----\*
|
||||
* 1 ^ 6
|
||||
* vh1 (adjust_outgoing halfedge!)
|
||||
*/
|
||||
|
||||
// Old and new Face
|
||||
typename mesh_t::FaceHandle fh_old(_m.face_handle(heh6));
|
||||
typename mesh_t::FaceHandle fh_new(_m.new_face());
|
||||
|
||||
|
||||
// Re-Set Handles around old Face
|
||||
_m.set_next_halfedge_handle(heh4, heh6);
|
||||
_m.set_next_halfedge_handle(heh5, heh4);
|
||||
|
||||
_m.set_face_handle(heh4, fh_old);
|
||||
_m.set_face_handle(heh5, fh_old);
|
||||
_m.set_face_handle(heh6, fh_old);
|
||||
_m.set_halfedge_handle(fh_old, heh4);
|
||||
|
||||
// Re-Set Handles around new Face
|
||||
_m.set_next_halfedge_handle(heh1, heh3);
|
||||
_m.set_next_halfedge_handle(heh3, heh2);
|
||||
|
||||
_m.set_face_handle(heh1, fh_new);
|
||||
_m.set_face_handle(heh2, fh_new);
|
||||
_m.set_face_handle(heh3, fh_new);
|
||||
|
||||
_m.set_halfedge_handle(fh_new, heh1);
|
||||
}
|
||||
|
||||
|
||||
void split_edge(mesh_t& _m, const typename mesh_t::EdgeHandle& _eh)
|
||||
{
|
||||
typename mesh_t::HalfedgeHandle
|
||||
heh = _m.halfedge_handle(_eh, 0),
|
||||
opp_heh = _m.halfedge_handle(_eh, 1);
|
||||
|
||||
typename mesh_t::HalfedgeHandle new_heh, opp_new_heh, t_heh;
|
||||
typename mesh_t::VertexHandle vh;
|
||||
typename mesh_t::VertexHandle vh1(_m.to_vertex_handle(heh));
|
||||
typename mesh_t::Point zero(0,0,0);
|
||||
|
||||
// new vertex
|
||||
vh = _m.new_vertex( zero );
|
||||
|
||||
// memorize position, will be set later
|
||||
_m.property( vp_pos_, vh ) = _m.property( ep_pos_, _eh );
|
||||
|
||||
|
||||
// Re-link mesh entities
|
||||
if (_m.is_boundary(_eh))
|
||||
{
|
||||
for (t_heh = heh;
|
||||
_m.next_halfedge_handle(t_heh) != opp_heh;
|
||||
t_heh = _m.opposite_halfedge_handle(_m.next_halfedge_handle(t_heh)))
|
||||
{}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (t_heh = _m.next_halfedge_handle(opp_heh);
|
||||
_m.next_halfedge_handle(t_heh) != opp_heh;
|
||||
t_heh = _m.next_halfedge_handle(t_heh) )
|
||||
{}
|
||||
}
|
||||
|
||||
new_heh = _m.new_edge(vh, vh1);
|
||||
opp_new_heh = _m.opposite_halfedge_handle(new_heh);
|
||||
_m.set_vertex_handle( heh, vh );
|
||||
|
||||
_m.set_next_halfedge_handle(t_heh, opp_new_heh);
|
||||
_m.set_next_halfedge_handle(new_heh, _m.next_halfedge_handle(heh));
|
||||
_m.set_next_halfedge_handle(heh, new_heh);
|
||||
_m.set_next_halfedge_handle(opp_new_heh, opp_heh);
|
||||
|
||||
if (_m.face_handle(opp_heh).is_valid())
|
||||
{
|
||||
_m.set_face_handle(opp_new_heh, _m.face_handle(opp_heh));
|
||||
_m.set_halfedge_handle(_m.face_handle(opp_new_heh), opp_new_heh);
|
||||
}
|
||||
|
||||
_m.set_face_handle( new_heh, _m.face_handle(heh) );
|
||||
_m.set_halfedge_handle( vh, new_heh);
|
||||
_m.set_halfedge_handle( _m.face_handle(heh), heh );
|
||||
_m.set_halfedge_handle( vh1, opp_new_heh );
|
||||
|
||||
// Never forget this, when playing with the topology
|
||||
_m.adjust_outgoing_halfedge( vh );
|
||||
_m.adjust_outgoing_halfedge( vh1 );
|
||||
}
|
||||
|
||||
private: // geometry helper
|
||||
|
||||
void compute_midpoint(mesh_t& _m, const typename mesh_t::EdgeHandle& _eh)
|
||||
{
|
||||
#define V( X ) vector_cast< typename mesh_t::Normal >( X )
|
||||
typename mesh_t::HalfedgeHandle heh, opp_heh;
|
||||
|
||||
heh = _m.halfedge_handle( _eh, 0);
|
||||
opp_heh = _m.halfedge_handle( _eh, 1);
|
||||
|
||||
typename mesh_t::Point
|
||||
pos(_m.point(_m.to_vertex_handle(heh)));
|
||||
|
||||
pos += V( _m.point(_m.to_vertex_handle(opp_heh)) );
|
||||
|
||||
// boundary edge: just average vertex positions
|
||||
if (_m.is_boundary(_eh) )
|
||||
{
|
||||
pos *= 0.5;
|
||||
}
|
||||
else // inner edge: add neighbouring Vertices to sum
|
||||
{
|
||||
pos *= real_t(3.0);
|
||||
pos += V(_m.point(_m.to_vertex_handle(_m.next_halfedge_handle(heh))));
|
||||
pos += V(_m.point(_m.to_vertex_handle(_m.next_halfedge_handle(opp_heh))));
|
||||
pos *= _1over8;
|
||||
}
|
||||
_m.property( ep_pos_, _eh ) = pos;
|
||||
#undef V
|
||||
}
|
||||
|
||||
|
||||
void smooth(mesh_t& _m, const typename mesh_t::VertexHandle& _vh)
|
||||
{
|
||||
typename mesh_t::Point pos(0.0,0.0,0.0);
|
||||
|
||||
if (_m.is_boundary(_vh)) // if boundary: Point 1-6-1
|
||||
{
|
||||
typename mesh_t::HalfedgeHandle heh, prev_heh;
|
||||
heh = _m.halfedge_handle( _vh );
|
||||
|
||||
if ( heh.is_valid() )
|
||||
{
|
||||
assert( _m.is_boundary( _m.edge_handle( heh ) ) );
|
||||
|
||||
prev_heh = _m.prev_halfedge_handle( heh );
|
||||
|
||||
typename mesh_t::VertexHandle
|
||||
to_vh = _m.to_vertex_handle( heh ),
|
||||
from_vh = _m.from_vertex_handle( prev_heh );
|
||||
|
||||
// ( v_l + 6 v + v_r ) / 8
|
||||
pos = _m.point( _vh );
|
||||
pos *= real_t(6.0);
|
||||
pos += vector_cast< typename mesh_t::Normal >( _m.point( to_vh ) );
|
||||
pos += vector_cast< typename mesh_t::Normal >( _m.point( from_vh ) );
|
||||
pos *= _1over8;
|
||||
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else // inner vertex: (1-a) * p + a/n * Sum q, q in one-ring of p
|
||||
{
|
||||
typedef typename mesh_t::Normal Vec;
|
||||
typename mesh_t::VertexVertexIter vvit;
|
||||
size_t valence(0);
|
||||
|
||||
// Calculate Valence and sum up neighbour points
|
||||
for (vvit=_m.vv_iter(_vh); vvit; ++vvit) {
|
||||
++valence;
|
||||
pos += vector_cast< Vec >( _m.point(vvit) );
|
||||
}
|
||||
pos *= weights_[valence].second; // alpha(n)/n * Sum q, q in one-ring of p
|
||||
pos += weights_[valence].first
|
||||
* vector_cast<Vec>(_m.point(_vh)); // + (1-a)*p
|
||||
}
|
||||
|
||||
_m.property( vp_pos_, _vh ) = pos;
|
||||
}
|
||||
|
||||
private: // data
|
||||
|
||||
OpenMesh::VPropHandleT< typename mesh_t::Point > vp_pos_;
|
||||
OpenMesh::EPropHandleT< typename mesh_t::Point > ep_pos_;
|
||||
|
||||
weights_t weights_;
|
||||
|
||||
const real_t _1over8;
|
||||
const real_t _3over8;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_UNIFORM
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_UNIFORM_COMPOSITELOOPT_HH defined
|
||||
//=============================================================================
|
||||
507
Tools/Subdivider/Uniform/Sqrt3T.hh
Normal file
507
Tools/Subdivider/Uniform/Sqrt3T.hh
Normal file
@@ -0,0 +1,507 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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: 4083 $
|
||||
// $Date: 2008-12-29 15:29:38 +0100 (Mo, 29. Dez 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file Sqrt3T.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS Sqrt3T
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_UNIFORM_SQRT3T_HH
|
||||
#define OPENMESH_SUBDIVIDER_UNIFORM_SQRT3T_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/Mesh/Handles.hh>
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Uniform/SubdividerT.hh>
|
||||
#if defined(_DEBUG) || defined(DEBUG)
|
||||
// Makes life lot easier, when playing/messing around with low-level topology
|
||||
// changing methods of OpenMesh
|
||||
# include <OpenMesh/Tools/Utils/MeshCheckerT.hh>
|
||||
# define ASSERT_CONSISTENCY( T, m ) \
|
||||
assert(OpenMesh::Utils::MeshCheckerT<T>(m).check())
|
||||
#else
|
||||
# define ASSERT_CONSISTENCY( T, m )
|
||||
#endif
|
||||
// -------------------- STL
|
||||
#include <vector>
|
||||
#if defined(OM_CC_MIPS)
|
||||
# include <math.h>
|
||||
#else
|
||||
# include <cmath>
|
||||
#endif
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Uniform { // BEGIN_NS_DECIMATER
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** %Uniform Sqrt3 subdivision algorithm
|
||||
*
|
||||
* Implementation as described in
|
||||
*
|
||||
* L. Kobbelt, <a href="http://www-i8.informatik.rwth-aachen.de/publications/downloads/sqrt3.pdf">"Sqrt(3) subdivision"</a>, Proceedings of SIGGRAPH 2000.
|
||||
*/
|
||||
template <typename MeshType, typename RealType = float>
|
||||
class Sqrt3T : public SubdividerT< MeshType, RealType >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef RealType real_t;
|
||||
typedef MeshType mesh_t;
|
||||
typedef SubdividerT< mesh_t, real_t > parent_t;
|
||||
|
||||
typedef std::pair< real_t, real_t > weight_t;
|
||||
typedef std::vector< std::pair<real_t,real_t> > weights_t;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Sqrt3T(void) : parent_t(), _1over3( 1.0/3.0 ), _1over27( 1.0/27.0 )
|
||||
{ init_weights(); }
|
||||
|
||||
Sqrt3T(MeshType &_m) : parent_t(_m), _1over3( 1.0/3.0 ), _1over27( 1.0/27.0 )
|
||||
{ init_weights(); }
|
||||
|
||||
virtual ~Sqrt3T() {}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
const char *name() const { return "Uniform Sqrt3"; }
|
||||
|
||||
|
||||
/// Pre-compute weights
|
||||
void init_weights(size_t _max_valence=50)
|
||||
{
|
||||
weights_.resize(_max_valence);
|
||||
std::generate(weights_.begin(), weights_.end(), compute_weight());
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
bool prepare( MeshType& _m )
|
||||
{
|
||||
_m.request_edge_status();
|
||||
_m.add_property( vp_pos_ );
|
||||
_m.add_property( ep_nv_ );
|
||||
_m.add_property( mp_gen_ );
|
||||
_m.property( mp_gen_ ) = 0;
|
||||
|
||||
return _m.has_edge_status() && vp_pos_.is_valid()
|
||||
&& ep_nv_.is_valid() && mp_gen_.is_valid();
|
||||
}
|
||||
|
||||
|
||||
bool cleanup( MeshType& _m )
|
||||
{
|
||||
_m.release_edge_status();
|
||||
_m.remove_property( vp_pos_ );
|
||||
_m.remove_property( ep_nv_ );
|
||||
_m.remove_property( mp_gen_ );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool subdivide( MeshType& _m, size_t _n )
|
||||
{
|
||||
typename MeshType::VertexIter vit;
|
||||
typename MeshType::VertexVertexIter vvit;
|
||||
typename MeshType::EdgeIter eit;
|
||||
typename MeshType::FaceIter fit;
|
||||
typename MeshType::FaceVertexIter fvit;
|
||||
typename MeshType::VertexHandle vh;
|
||||
typename MeshType::HalfedgeHandle heh;
|
||||
typename MeshType::Point pos(0,0,0), zero(0,0,0);
|
||||
size_t &gen = _m.property( mp_gen_ );
|
||||
|
||||
for (size_t l=0; l<_n; ++l)
|
||||
{
|
||||
// tag existing edges
|
||||
for (eit=_m.edges_begin(); eit != _m.edges_end();++eit)
|
||||
{
|
||||
_m.status( eit ).set_tagged( true );
|
||||
if ( (gen%2) && _m.is_boundary(eit) )
|
||||
compute_new_boundary_points( _m, eit ); // *) creates new vertices
|
||||
}
|
||||
|
||||
// do relaxation of old vertices, but store new pos in property vp_pos_
|
||||
|
||||
for (vit=_m.vertices_begin(); vit!=_m.vertices_end(); ++vit)
|
||||
{
|
||||
if ( _m.is_boundary(vit) )
|
||||
{
|
||||
if ( gen%2 )
|
||||
{
|
||||
heh = _m.halfedge_handle(vit);
|
||||
if (heh.is_valid()) // skip isolated newly inserted vertices *)
|
||||
{
|
||||
typename OpenMesh::HalfedgeHandle
|
||||
prev_heh = _m.prev_halfedge_handle(heh);
|
||||
|
||||
assert( _m.is_boundary(heh ) );
|
||||
assert( _m.is_boundary(prev_heh) );
|
||||
|
||||
pos = _m.point(_m.to_vertex_handle(heh));
|
||||
pos += _m.point(_m.from_vertex_handle(prev_heh));
|
||||
pos *= real_t(4.0);
|
||||
|
||||
pos += real_t(19.0) * _m.point( vit );
|
||||
pos *= _1over27;
|
||||
|
||||
_m.property( vp_pos_, vit ) = pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
_m.property( vp_pos_, vit ) = _m.point( vit );
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t valence=0;
|
||||
|
||||
pos = zero;
|
||||
for ( vvit = _m.vv_iter(vit); vvit; ++vvit)
|
||||
{
|
||||
pos += _m.point( vvit );
|
||||
++valence;
|
||||
}
|
||||
pos *= weights_[ valence ].second;
|
||||
pos += weights_[ valence ].first * _m.point(vit);
|
||||
_m.property( vp_pos_, vit ) = pos;
|
||||
}
|
||||
}
|
||||
|
||||
// insert new vertices, but store pos in vp_pos_
|
||||
typename MeshType::FaceIter fend = _m.faces_end();
|
||||
for (fit = _m.faces_begin();fit != fend; ++fit)
|
||||
{
|
||||
if ( (gen%2) && _m.is_boundary(fit))
|
||||
{
|
||||
boundary_split( _m, fit );
|
||||
}
|
||||
else
|
||||
{
|
||||
fvit = _m.fv_iter( fit );
|
||||
pos = _m.point( fvit);
|
||||
pos += _m.point(++fvit);
|
||||
pos += _m.point(++fvit);
|
||||
pos *= _1over3;
|
||||
vh = _m.add_vertex( zero );
|
||||
_m.property( vp_pos_, vh ) = pos;
|
||||
_m.split( fit, vh );
|
||||
}
|
||||
}
|
||||
|
||||
// commit new positions (now iterating over all vertices)
|
||||
for (vit=_m.vertices_begin();vit != _m.vertices_end(); ++vit)
|
||||
_m.set_point(vit, _m.property( vp_pos_, vit ) );
|
||||
|
||||
// flip old edges
|
||||
for (eit=_m.edges_begin(); eit != _m.edges_end(); ++eit)
|
||||
if ( _m.status( eit ).tagged() && !_m.is_boundary( eit ) )
|
||||
_m.flip(eit);
|
||||
|
||||
// Now we have an consistent mesh!
|
||||
ASSERT_CONSISTENCY( MeshType, _m );
|
||||
|
||||
// increase generation by one
|
||||
++gen;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// Helper functor to compute weights for sqrt(3)-subdivision
|
||||
/// \internal
|
||||
struct compute_weight
|
||||
{
|
||||
compute_weight() : valence(-1) { }
|
||||
weight_t operator() (void)
|
||||
{
|
||||
#if !defined(OM_CC_MIPS)
|
||||
using std::cos;
|
||||
#endif
|
||||
if (++valence)
|
||||
{
|
||||
real_t alpha = (4.0-2.0*cos(2.0*M_PI / (double)valence))/9.0;
|
||||
return weight_t( real_t(1)-alpha, alpha/real_t(valence) );
|
||||
}
|
||||
return weight_t(0.0, 0.0);
|
||||
}
|
||||
int valence;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// Pre-compute location of new boundary points for odd generations
|
||||
// and store them in the edge property ep_nv_;
|
||||
void compute_new_boundary_points( MeshType& _m,
|
||||
const typename MeshType::EdgeHandle& _eh)
|
||||
{
|
||||
assert( _m.is_boundary(_eh) );
|
||||
|
||||
typename MeshType::HalfedgeHandle heh;
|
||||
typename MeshType::VertexHandle vh1, vh2, vh3, vh4, vhl, vhr;
|
||||
typename MeshType::Point zero(0,0,0), P1, P2, P3, P4;
|
||||
|
||||
/*
|
||||
// *---------*---------*
|
||||
// / \ / \ / \
|
||||
// / \ / \ / \
|
||||
// / \ / \ / \
|
||||
// / \ / \ / \
|
||||
// *---------*--#---#--*---------*
|
||||
//
|
||||
// ^ ^ ^ ^ ^ ^
|
||||
// P1 P2 pl pr P3 P4
|
||||
*/
|
||||
// get halfedge pointing from P3 to P2 (outer boundary halfedge)
|
||||
|
||||
heh = _m.halfedge_handle(_eh,
|
||||
_m.is_boundary(_m.halfedge_handle(_eh,1)));
|
||||
|
||||
assert( _m.is_boundary( _m.next_halfedge_handle( heh ) ) );
|
||||
assert( _m.is_boundary( _m.prev_halfedge_handle( heh ) ) );
|
||||
|
||||
vh1 = _m.to_vertex_handle( _m.next_halfedge_handle( heh ) );
|
||||
vh2 = _m.to_vertex_handle( heh );
|
||||
vh3 = _m.from_vertex_handle( heh );
|
||||
vh4 = _m.from_vertex_handle( _m.prev_halfedge_handle( heh ));
|
||||
|
||||
P1 = _m.point(vh1);
|
||||
P2 = _m.point(vh2);
|
||||
P3 = _m.point(vh3);
|
||||
P4 = _m.point(vh4);
|
||||
|
||||
vhl = _m.add_vertex(zero);
|
||||
vhr = _m.add_vertex(zero);
|
||||
|
||||
_m.property(vp_pos_, vhl ) = (P1 + 16.0f*P2 + 10.0f*P3) * _1over27;
|
||||
_m.property(vp_pos_, vhr ) = (10.0f*P2 + 16.0f*P3 + P4) * _1over27;
|
||||
_m.property(ep_nv_, _eh).first = vhl;
|
||||
_m.property(ep_nv_, _eh).second = vhr;
|
||||
}
|
||||
|
||||
|
||||
void boundary_split( MeshType& _m, const typename MeshType::FaceHandle& _fh )
|
||||
{
|
||||
assert( _m.is_boundary(_fh) );
|
||||
|
||||
typename MeshType::VertexHandle vhl, vhr;
|
||||
typename MeshType::FaceEdgeIter fe_it;
|
||||
typename MeshType::HalfedgeHandle heh;
|
||||
|
||||
// find boundary edge
|
||||
for( fe_it=_m.fe_iter( _fh ); fe_it && !_m.is_boundary( fe_it ); ++fe_it );
|
||||
|
||||
// use precomputed, already inserted but not linked vertices
|
||||
vhl = _m.property(ep_nv_, fe_it).first;
|
||||
vhr = _m.property(ep_nv_, fe_it).second;
|
||||
|
||||
/*
|
||||
// *---------*---------*
|
||||
// / \ / \ / \
|
||||
// / \ / \ / \
|
||||
// / \ / \ / \
|
||||
// / \ / \ / \
|
||||
// *---------*--#---#--*---------*
|
||||
//
|
||||
// ^ ^ ^ ^ ^ ^
|
||||
// P1 P2 pl pr P3 P4
|
||||
*/
|
||||
// get halfedge pointing from P2 to P3 (inner boundary halfedge)
|
||||
|
||||
heh = _m.halfedge_handle(fe_it,
|
||||
_m.is_boundary(_m.halfedge_handle(fe_it,0)));
|
||||
|
||||
typename MeshType::HalfedgeHandle pl_P3;
|
||||
|
||||
// split P2->P3 (heh) in P2->pl (heh) and pl->P3
|
||||
boundary_split( _m, heh, vhl ); // split edge
|
||||
pl_P3 = _m.next_halfedge_handle( heh ); // store next halfedge handle
|
||||
boundary_split( _m, heh ); // split face
|
||||
|
||||
// split pl->P3 in pl->pr and pr->P3
|
||||
boundary_split( _m, pl_P3, vhr );
|
||||
boundary_split( _m, pl_P3 );
|
||||
|
||||
assert( _m.is_boundary( vhl ) && _m.halfedge_handle(vhl).is_valid() );
|
||||
assert( _m.is_boundary( vhr ) && _m.halfedge_handle(vhr).is_valid() );
|
||||
}
|
||||
|
||||
void boundary_split(MeshType& _m,
|
||||
const typename MeshType::HalfedgeHandle& _heh,
|
||||
const typename MeshType::VertexHandle& _vh)
|
||||
{
|
||||
assert( _m.is_boundary( _m.edge_handle(_heh) ) );
|
||||
|
||||
typename MeshType::HalfedgeHandle
|
||||
heh(_heh),
|
||||
opp_heh( _m.opposite_halfedge_handle(_heh) ),
|
||||
new_heh, opp_new_heh;
|
||||
typename MeshType::VertexHandle to_vh(_m.to_vertex_handle(heh));
|
||||
typename MeshType::HalfedgeHandle t_heh;
|
||||
|
||||
/*
|
||||
* P5
|
||||
* *
|
||||
* /|\
|
||||
* / \
|
||||
* / \
|
||||
* / \
|
||||
* / \
|
||||
* /_ heh new \
|
||||
* *-----\*-----\*\-----*
|
||||
* ^ ^ t_heh
|
||||
* _vh to_vh
|
||||
*
|
||||
* P1 P2 P3 P4
|
||||
*/
|
||||
// Re-Setting Handles
|
||||
|
||||
// find halfedge point from P4 to P3
|
||||
for(t_heh = heh;
|
||||
_m.next_halfedge_handle(t_heh) != opp_heh;
|
||||
t_heh = _m.opposite_halfedge_handle(_m.next_halfedge_handle(t_heh)))
|
||||
{}
|
||||
|
||||
assert( _m.is_boundary( t_heh ) );
|
||||
|
||||
new_heh = _m.new_edge( _vh, to_vh );
|
||||
opp_new_heh = _m.opposite_halfedge_handle(new_heh);
|
||||
|
||||
// update halfedge connectivity
|
||||
|
||||
_m.set_next_halfedge_handle(t_heh, opp_new_heh); // P4-P3 -> P3-P2
|
||||
// P2-P3 -> P3-P5
|
||||
_m.set_next_halfedge_handle(new_heh, _m.next_halfedge_handle(heh));
|
||||
_m.set_next_halfedge_handle(heh, new_heh); // P1-P2 -> P2-P3
|
||||
_m.set_next_halfedge_handle(opp_new_heh, opp_heh); // P3-P2 -> P2-P1
|
||||
|
||||
// both opposite halfedges point to same face
|
||||
_m.set_face_handle(opp_new_heh, _m.face_handle(opp_heh));
|
||||
|
||||
// let heh finally point to new inserted vertex
|
||||
_m.set_vertex_handle(heh, _vh);
|
||||
|
||||
// let heh and new_heh point to same face
|
||||
_m.set_face_handle(new_heh, _m.face_handle(heh));
|
||||
|
||||
// let opp_new_heh be the new outgoing halfedge for to_vh
|
||||
// (replaces for opp_heh)
|
||||
_m.set_halfedge_handle( to_vh, opp_new_heh );
|
||||
|
||||
// let opp_heh be the outgoing halfedge for _vh
|
||||
_m.set_halfedge_handle( _vh, opp_heh );
|
||||
}
|
||||
|
||||
void boundary_split( MeshType& _m,
|
||||
const typename MeshType::HalfedgeHandle& _heh)
|
||||
{
|
||||
assert( _m.is_boundary( _m.opposite_halfedge_handle( _heh ) ) );
|
||||
|
||||
typename MeshType::HalfedgeHandle
|
||||
heh(_heh),
|
||||
n_heh(_m.next_halfedge_handle(heh));
|
||||
|
||||
typename MeshType::VertexHandle
|
||||
to_vh(_m.to_vertex_handle(heh));
|
||||
|
||||
typename MeshType::HalfedgeHandle
|
||||
heh2(_m.new_edge(to_vh,
|
||||
_m.to_vertex_handle(_m.next_halfedge_handle(n_heh)))),
|
||||
heh3(_m.opposite_halfedge_handle(heh2));
|
||||
|
||||
typename MeshType::FaceHandle
|
||||
new_fh(_m.new_face()),
|
||||
fh(_m.face_handle(heh));
|
||||
|
||||
// Relink (half)edges
|
||||
|
||||
#define set_next_heh set_next_halfedge_handle
|
||||
#define next_heh next_halfedge_handle
|
||||
|
||||
_m.set_face_handle(heh, new_fh);
|
||||
_m.set_face_handle(heh2, new_fh);
|
||||
_m.set_next_heh(heh2, _m.next_heh(_m.next_heh(n_heh)));
|
||||
_m.set_next_heh(heh, heh2);
|
||||
_m.set_face_handle( _m.next_heh(heh2), new_fh);
|
||||
|
||||
// _m.set_face_handle( _m.next_heh(_m.next_heh(heh2)), new_fh);
|
||||
|
||||
_m.set_next_heh(heh3, n_heh);
|
||||
_m.set_next_heh(_m.next_halfedge_handle(n_heh), heh3);
|
||||
_m.set_face_handle(heh3, fh);
|
||||
// _m.set_face_handle(n_heh, fh);
|
||||
|
||||
_m.set_halfedge_handle( fh, n_heh);
|
||||
_m.set_halfedge_handle(new_fh, heh);
|
||||
|
||||
#undef set_next_halfedge_handle
|
||||
#undef next_halfedge_handle
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
weights_t weights_;
|
||||
OpenMesh::VPropHandleT< typename MeshType::Point > vp_pos_;
|
||||
OpenMesh::EPropHandleT< std::pair< typename MeshType::VertexHandle,
|
||||
typename MeshType::VertexHandle> > ep_nv_;
|
||||
OpenMesh::MPropHandleT< size_t > mp_gen_;
|
||||
|
||||
const real_t _1over3;
|
||||
const real_t _1over27;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_UNIFORM
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_UNIFORM_SQRT3T_HH
|
||||
//=============================================================================
|
||||
179
Tools/Subdivider/Uniform/SubdividerT.hh
Normal file
179
Tools/Subdivider/Uniform/SubdividerT.hh
Normal file
@@ -0,0 +1,179 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 SubdividerT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS SubdividerT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_UNIFORM_SUDIVIDERT_HH
|
||||
#define OPENMESH_SUBDIVIDER_UNIFORM_SUDIVIDERT_HH
|
||||
|
||||
//== INCLUDE ==================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Core/Utils/Noncopyable.hh>
|
||||
#if defined(_DEBUG) || defined(DEBUG)
|
||||
// Makes life lot easier, when playing/messing around with low-level topology
|
||||
// changing methods of OpenMesh
|
||||
# include <OpenMesh/Tools/Utils/MeshCheckerT.hh>
|
||||
# define ASSERT_CONSISTENCY( T, m ) \
|
||||
assert(OpenMesh::Utils::MeshCheckerT<T>(m).check())
|
||||
#else
|
||||
# define ASSERT_CONSISTENCY( T, m )
|
||||
#endif
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Subdivider {
|
||||
namespace Uniform {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Abstract base class for uniform subdivision algorithms.
|
||||
*
|
||||
* A derived class must overload the following functions:
|
||||
* -# name()
|
||||
* -# prepare()
|
||||
* -# subdivide()
|
||||
* -# cleanup()
|
||||
*/
|
||||
template <typename MeshType, typename RealType=float>
|
||||
class SubdividerT : private Utils::Noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
typedef MeshType mesh_t;
|
||||
typedef RealType real_t;
|
||||
|
||||
public:
|
||||
|
||||
/// \name Constructors
|
||||
//@{
|
||||
/// Constructor to be used with interface 2
|
||||
/// \see attach(), operator()(size_t), detach()
|
||||
SubdividerT(void) : attached_(NULL) { }
|
||||
|
||||
/// Constructor to be used with interface 1 (calls attach())
|
||||
/// \see operator()( MeshType&, size_t )
|
||||
SubdividerT( MeshType &_m ) : attached_(NULL) { attach(_m); }
|
||||
|
||||
//@}
|
||||
|
||||
/// Descructor (calls detach())
|
||||
virtual ~SubdividerT()
|
||||
{ detach(); }
|
||||
|
||||
/// Return name of subdivision algorithm
|
||||
virtual const char *name( void ) const = 0;
|
||||
|
||||
|
||||
public: /// \name Interface 1
|
||||
|
||||
//@{
|
||||
/// Subdivide the mesh \c _m \c _n times.
|
||||
/// \see SubdividerT(MeshType&)
|
||||
bool operator () ( MeshType& _m, size_t _n )
|
||||
{
|
||||
return prepare(_m) && subdivide( _m, _n ) && cleanup( _m );
|
||||
}
|
||||
//@}
|
||||
|
||||
public: /// \name Interface 2
|
||||
//@{
|
||||
/// Attach mesh \c _m to self
|
||||
/// \see SubdividerT(), operator()(size_t), detach()
|
||||
bool attach( MeshType& _m )
|
||||
{
|
||||
if ( attached_ == &_m )
|
||||
return true;
|
||||
|
||||
detach();
|
||||
if (prepare( _m ))
|
||||
{
|
||||
attached_ = &_m;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Subdivide the attached \c _n times.
|
||||
/// \see SubdividerT(), attach(), detach()
|
||||
bool operator()( size_t _n )
|
||||
{
|
||||
return attached_ ? subdivide( *attached_, _n ) : false;
|
||||
}
|
||||
|
||||
/// Detach an eventually attached mesh.
|
||||
/// \see SubdividerT(), attach(), operator()(size_t)
|
||||
void detach(void)
|
||||
{
|
||||
if ( attached_ )
|
||||
{
|
||||
cleanup( *attached_ );
|
||||
attached_ = NULL;
|
||||
}
|
||||
}
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
/// \name Overload theses methods
|
||||
//@{
|
||||
/// Prepare mesh, e.g. add properties
|
||||
virtual bool prepare( MeshType& _m ) = 0;
|
||||
|
||||
/// Subdivide mesh \c _m \c _n times
|
||||
virtual bool subdivide( MeshType& _m, size_t _n ) = 0;
|
||||
|
||||
/// Cleanup mesh after usage, e.g. remove added properties
|
||||
virtual bool cleanup( MeshType& _m ) = 0;
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
MeshType *attached_;
|
||||
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Uniform
|
||||
} // namespace Subdivider
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_UNIFORM_SUBDIVIDERT_HH
|
||||
//=============================================================================
|
||||
31
Tools/Tools.pro
Normal file
31
Tools/Tools.pro
Normal file
@@ -0,0 +1,31 @@
|
||||
################################################################################
|
||||
#
|
||||
################################################################################
|
||||
|
||||
contains( OPENFLIPPER , OpenFlipper ){
|
||||
include( $$TOPDIR/qmake/all.include )
|
||||
} else {
|
||||
include( $$TOPDIR/OpenMesh/qmake/all.include )
|
||||
}
|
||||
|
||||
Library()
|
||||
|
||||
DIRECTORIES = . Decimater Smoother Subdivider/Adaptive/Composite \
|
||||
Subdivider/Uniform/Composite Subdivider/Uniform \
|
||||
Utils
|
||||
|
||||
INCLUDEPATH += ../..
|
||||
|
||||
win32 {
|
||||
DEFINES += _USE_MATH_DEFINES NOMINMAX
|
||||
CONFIG += static
|
||||
}
|
||||
|
||||
# Input
|
||||
HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh)
|
||||
SOURCES += $$getFilesFromDir($$DIRECTORIES,*.c)
|
||||
SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc)
|
||||
FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui)
|
||||
|
||||
|
||||
################################################################################
|
||||
17
Tools/Utils/ACGMakefile
Normal file
17
Tools/Utils/ACGMakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS = $(call find-subdirs)
|
||||
|
||||
PACKAGES :=
|
||||
|
||||
PROJ_LIBS :=
|
||||
|
||||
MODULES := cxxlib
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
57
Tools/Utils/Config.hh
Normal file
57
Tools/Utils/Config.hh
Normal file
@@ -0,0 +1,57 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 Tools/Utils/Config.hh
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_UTILS_CONFIG_HH
|
||||
#define OPENMESH_UTILS_CONFIG_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
#define BEGIN_NS_UTILS namespace Utils {
|
||||
#define END_NS_UTILS }
|
||||
|
||||
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_UTILS_CONFIG_HH defined
|
||||
//=============================================================================
|
||||
80
Tools/Utils/GLConstAsString.hh
Normal file
80
Tools/Utils/GLConstAsString.hh
Normal file
@@ -0,0 +1,80 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef OPENMESH_UTILS_GLCONSTASSTRING_HH
|
||||
#define OPENMESH_UTILS_GLCONSTASSTRING_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <GL/glut.h>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Utils {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
inline
|
||||
const char *GLenum_as_string( GLenum _m )
|
||||
{
|
||||
#define MODE(M) case M:return #M
|
||||
switch( _m )
|
||||
{
|
||||
MODE(GL_POINTS);
|
||||
MODE(GL_LINES);
|
||||
MODE(GL_LINE_STRIP);
|
||||
MODE(GL_LINE_LOOP);
|
||||
MODE(GL_TRIANGLES);
|
||||
MODE(GL_TRIANGLE_STRIP);
|
||||
MODE(GL_TRIANGLE_FAN);
|
||||
MODE(GL_QUADS);
|
||||
MODE(GL_QUAD_STRIP);
|
||||
MODE(GL_POLYGON);
|
||||
default: return "<unknown>";
|
||||
}
|
||||
#undef MODE
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Utils
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_UTILS_GLCONSTASSTRING_HH defined
|
||||
//=============================================================================
|
||||
|
||||
498
Tools/Utils/Gnuplot.cc
Normal file
498
Tools/Utils/Gnuplot.cc
Normal file
@@ -0,0 +1,498 @@
|
||||
////////////////////////////////////////////
|
||||
//
|
||||
// A C++ interface to gnuplot.
|
||||
//
|
||||
// This is a direct translation from the C interface
|
||||
// written by N. Devillard (which is available from
|
||||
// http://ndevilla.free.fr/gnuplot/).
|
||||
//
|
||||
// As in the C interface this uses pipes and so wont
|
||||
// run on a system that does'nt have POSIX pipe
|
||||
// support
|
||||
//
|
||||
// Rajarshi Guha
|
||||
// <rajarshi@presidency.com>
|
||||
//
|
||||
// 07/03/03
|
||||
//
|
||||
////////////////////////////////////////////
|
||||
|
||||
#include "Gnuplot.hh"
|
||||
#include <stdarg.h>
|
||||
#ifdef WIN32
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <fcntl.h> // X_OK
|
||||
# include <unistd.h> // access
|
||||
# define PATH_MAXNAMESZ 4096
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
|
||||
#if defined(WIN32)
|
||||
# define pclose _pclose
|
||||
# define popen _popen
|
||||
# define access _access
|
||||
# define ACCESS_OK 0
|
||||
# define PATH_SEP ";"
|
||||
# define MKTEMP_AND_CHECK_FAILED(name) (_mktemp(name) == NULL)
|
||||
#else
|
||||
# define ACCESS_OK X_OK
|
||||
# define PATH_SEP ":"
|
||||
# define MKTEMP_AND_CHECK_FAILED(name) (mkstemp(name) == -1)
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
/////////////////////////////
|
||||
//
|
||||
// A string tokenizer taken from
|
||||
// http://www.sunsite.ualberta.ca/
|
||||
// Documentation/Gnu/libstdc++-2.90.8/html/21_strings/stringtok_std_h.txt
|
||||
//
|
||||
/////////////////////////////
|
||||
|
||||
template <typename Container>
|
||||
void
|
||||
stringtok (Container &container, string const &in,
|
||||
const char * const delimiters = " \t\n")
|
||||
{
|
||||
const string::size_type len = in.length();
|
||||
|
||||
string::size_type i = 0;
|
||||
|
||||
while ( i < len )
|
||||
{
|
||||
// eat leading whitespace
|
||||
i = in.find_first_not_of (delimiters, i);
|
||||
if (i == string::npos)
|
||||
return; // nothing left but white space
|
||||
|
||||
// find the end of the token
|
||||
string::size_type j = in.find_first_of (delimiters, i);
|
||||
|
||||
// push token
|
||||
if (j == string::npos)
|
||||
{
|
||||
container.push_back (in.substr(i));
|
||||
return;
|
||||
} else
|
||||
container.push_back (in.substr(i, j-i));
|
||||
|
||||
// set up for next loop
|
||||
i = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef WIN32
|
||||
std::string Gnuplot::gnuplot_executable_ = "pgnuplot.exe";
|
||||
#else
|
||||
std::string Gnuplot::gnuplot_executable_ = "gnuplot";
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Gnuplot::Gnuplot(void)
|
||||
{
|
||||
init();
|
||||
set_style("points");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Gnuplot::Gnuplot(const string &style)
|
||||
{
|
||||
init();
|
||||
set_style(style);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Gnuplot::Gnuplot(const string &title,
|
||||
const string &style,
|
||||
const string &labelx, const string &labely,
|
||||
vector<double> x, vector<double> y)
|
||||
{
|
||||
init();
|
||||
|
||||
if (x.size() == 0 || y.size() == 0)
|
||||
throw GnuplotException("vectors too small");
|
||||
|
||||
if (style == "")
|
||||
this->set_style("lines");
|
||||
else
|
||||
this->set_style(style);
|
||||
|
||||
if (labelx == "")
|
||||
this->set_xlabel("X");
|
||||
else
|
||||
this->set_xlabel(labelx);
|
||||
if (labely == "")
|
||||
this->set_ylabel("Y");
|
||||
else
|
||||
this->set_ylabel(labely);
|
||||
|
||||
this->plot_xy(x,y,title);
|
||||
|
||||
cout << "Press enter to continue" << endl;
|
||||
while (getchar() != '\n'){}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Gnuplot::Gnuplot(const string &title, const string &style,
|
||||
const string &labelx, const string &labely,
|
||||
vector<double> x)
|
||||
{
|
||||
init();
|
||||
|
||||
if (x.size() == 0)
|
||||
throw GnuplotException("vector too small");
|
||||
if (!this->gnucmd)
|
||||
throw GnuplotException("Could'nt open connection to gnuplot");
|
||||
|
||||
if (style == "")
|
||||
this->set_style("lines");
|
||||
else
|
||||
this->set_style(style);
|
||||
|
||||
if (labelx == "")
|
||||
this->set_xlabel("X");
|
||||
else
|
||||
this->set_xlabel(labelx);
|
||||
if (labely == "")
|
||||
this->set_ylabel("Y");
|
||||
else
|
||||
this->set_ylabel(labely);
|
||||
|
||||
this->plot_x(x,title);
|
||||
|
||||
cout << "Press enter to continue" << endl;
|
||||
while (getchar() != '\n'){}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Gnuplot::~Gnuplot()
|
||||
{
|
||||
if ((this->to_delete).size() > 0)
|
||||
{
|
||||
for (size_t i = 0; i < this->to_delete.size(); i++)
|
||||
remove(this->to_delete[i].c_str());
|
||||
}
|
||||
|
||||
if (pclose(this->gnucmd) == -1)
|
||||
cerr << "Problem closing communication to gnuplot" << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool Gnuplot::get_program_path(const string pname)
|
||||
{
|
||||
list<string> ls;
|
||||
char *path;
|
||||
|
||||
path = getenv("PATH");
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
stringtok(ls, path, PATH_SEP);
|
||||
|
||||
for (list<string>::const_iterator i = ls.begin(); i != ls.end(); ++i)
|
||||
{
|
||||
string tmp = (*i) + "/" + pname;
|
||||
if ( access(tmp.c_str(), ACCESS_OK) == 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Gnuplot::reset_plot(void)
|
||||
{
|
||||
if (this->to_delete.size() > 0)
|
||||
{
|
||||
for (size_t i = 0; i < this->to_delete.size(); i++)
|
||||
remove(this->to_delete[i].c_str());
|
||||
}
|
||||
this->nplots = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Gnuplot::set_style(const string &stylestr)
|
||||
{
|
||||
if (stylestr != "lines" &&
|
||||
stylestr != "points" &&
|
||||
stylestr != "linespoints" &&
|
||||
stylestr != "impulses" &&
|
||||
stylestr != "dots" &&
|
||||
stylestr != "steps" &&
|
||||
stylestr != "errorbars" &&
|
||||
stylestr != "boxes" &&
|
||||
stylestr != "boxerrorbars")
|
||||
this->pstyle = string("points");
|
||||
else
|
||||
this->pstyle = stylestr;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Gnuplot::cmd(const char *_cmd, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char local_cmd[GP_CMD_SIZE];
|
||||
|
||||
va_start(ap, _cmd);
|
||||
vsprintf(local_cmd, _cmd, ap);
|
||||
va_end(ap);
|
||||
|
||||
strcat(local_cmd,"\n");
|
||||
fputs(local_cmd,this->gnucmd);
|
||||
fflush(this->gnucmd);
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Gnuplot::set_ylabel(const string &label)
|
||||
{
|
||||
ostringstream cmdstr;
|
||||
|
||||
cmdstr << "set xlabel \"" << label << "\"";
|
||||
this->cmd(cmdstr.str().c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Gnuplot::set_xlabel(const string &label)
|
||||
{
|
||||
ostringstream cmdstr;
|
||||
|
||||
cmdstr << "set xlabel \"" << label << "\"";
|
||||
this->cmd(cmdstr.str().c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Plots a linear equation (where you supply the
|
||||
// slope and intercept)
|
||||
//
|
||||
void Gnuplot::plot_slope(double a, double b, const string &title)
|
||||
{
|
||||
ostringstream stitle;
|
||||
ostringstream cmdstr;
|
||||
|
||||
if (title == "")
|
||||
stitle << "no title";
|
||||
else
|
||||
stitle << title;
|
||||
|
||||
if (this->nplots > 0)
|
||||
cmdstr << "replot " << a << " * x + " << b << " title \"" << stitle.str() << "\" with " << pstyle;
|
||||
else
|
||||
cmdstr << "plot " << a << " * x + " << b << " title \"" << stitle.str() << "\" with " << pstyle;
|
||||
this->cmd(cmdstr.str().c_str());
|
||||
this->nplots++;
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Plot an equation which is supplied as a string
|
||||
//
|
||||
void Gnuplot::plot_equation(const string &equation, const string &title)
|
||||
{
|
||||
string titlestr, plotstr;
|
||||
ostringstream cmdstr;
|
||||
|
||||
if (title == "")
|
||||
titlestr = "no title";
|
||||
else
|
||||
titlestr = title;
|
||||
|
||||
if (this->nplots > 0)
|
||||
plotstr = "replot";
|
||||
else
|
||||
plotstr = "plot";
|
||||
|
||||
cmdstr << plotstr << " " << equation << " " << "title \"" << titlestr << "\" with " << this->pstyle;
|
||||
this->cmd(cmdstr.str().c_str());
|
||||
this->nplots++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Gnuplot::plot_x(vector<double> d, const string &title)
|
||||
{
|
||||
ofstream tmp;
|
||||
ostringstream cmdstr;
|
||||
#ifdef WIN32
|
||||
char name[] = "gnuplotiXXXXXX";
|
||||
#else
|
||||
char name[] = "/tmp/gnuplotiXXXXXX";
|
||||
#endif
|
||||
|
||||
if (this->to_delete.size() == GP_MAX_TMP_FILES - 1)
|
||||
{
|
||||
cerr << "Maximum number of temporary files reached (" << GP_MAX_TMP_FILES << "): cannot open more files" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
//open temporary files for output
|
||||
#ifdef WIN32
|
||||
if ( _mktemp(name) == NULL)
|
||||
#else
|
||||
if ( mkstemp(name) == -1 )
|
||||
#endif
|
||||
{
|
||||
cerr << "Cannot create temporary file: exiting plot" << endl;
|
||||
return;
|
||||
}
|
||||
tmp.open(name);
|
||||
if (tmp.bad())
|
||||
{
|
||||
cerr << "Cannot create temorary file: exiting plot" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Save the temporary filename
|
||||
//
|
||||
this->to_delete.push_back(name);
|
||||
|
||||
//
|
||||
// write the data to file
|
||||
//
|
||||
for (size_t i = 0; i < d.size(); i++)
|
||||
tmp << d[i] << endl;
|
||||
tmp.flush();
|
||||
tmp.close();
|
||||
|
||||
//
|
||||
// command to be sent to gnuplot
|
||||
//
|
||||
cmdstr << ( (this->nplots > 0) ? "replot " : "plot ");
|
||||
|
||||
if (title.empty())
|
||||
cmdstr << "\"" << name << "\" with " << this->pstyle;
|
||||
else
|
||||
cmdstr << "\"" << name << "\" title \"" << title << "\" with "
|
||||
<< this->pstyle;
|
||||
|
||||
//
|
||||
// Do the actual plot
|
||||
//
|
||||
this->cmd(cmdstr.str().c_str());
|
||||
this->nplots++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Gnuplot::plot_xy(vector<double> x, vector<double> y, const string &title)
|
||||
{
|
||||
ofstream tmp;
|
||||
ostringstream cmdstr;
|
||||
#ifdef WIN32
|
||||
char name[] = "gnuplotiXXXXXX";
|
||||
#else
|
||||
char name[] = "/tmp/gnuplotiXXXXXX";
|
||||
#endif
|
||||
|
||||
// should raise an exception
|
||||
if (x.size() != y.size())
|
||||
return;
|
||||
|
||||
if ((this->to_delete).size() == GP_MAX_TMP_FILES - 1)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "Maximum number of temporary files reached ("
|
||||
<< GP_MAX_TMP_FILES << "): cannot open more files" << endl;
|
||||
throw GnuplotException( s.str() );
|
||||
}
|
||||
|
||||
//open temporary files for output
|
||||
//
|
||||
if (MKTEMP_AND_CHECK_FAILED(name))
|
||||
throw GnuplotException("Cannot create temporary file: exiting plot");
|
||||
|
||||
tmp.open(name);
|
||||
if (tmp.bad())
|
||||
throw GnuplotException("Cannot create temorary file: exiting plot");
|
||||
|
||||
// Save the temporary filename
|
||||
//
|
||||
this->to_delete.push_back(name);
|
||||
|
||||
// Write the data to file
|
||||
//
|
||||
size_t N = std::min(x.size(), y.size());
|
||||
for (size_t i = 0; i < N; i++)
|
||||
tmp << x[i] << " " << y[i] << endl;
|
||||
tmp.flush();
|
||||
tmp.close();
|
||||
|
||||
//
|
||||
// command to be sent to gnuplot
|
||||
//
|
||||
if (this->nplots > 0)
|
||||
cmdstr << "replot ";
|
||||
else cmdstr << "plot ";
|
||||
if (title == "")
|
||||
cmdstr << "\"" << name << "\" with " << this->pstyle;
|
||||
else
|
||||
cmdstr << "\"" << name << "\" title \"" << title << "\" with " << this->pstyle;
|
||||
|
||||
//
|
||||
// Do the actual plot
|
||||
//
|
||||
this->cmd(cmdstr.str().c_str());
|
||||
this->nplots++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Gnuplot::init()
|
||||
{
|
||||
if (!this->get_program_path(gnuplot_executable_))
|
||||
{
|
||||
this->valid = false;
|
||||
throw GnuplotException("Can't find gnuplot in your PATH");
|
||||
}
|
||||
|
||||
this->gnucmd = popen(gnuplot_executable_.c_str(),"w");
|
||||
if (!this->gnucmd)
|
||||
{
|
||||
this->valid = false;
|
||||
throw GnuplotException("Couldn't open connection to gnuplot");
|
||||
}
|
||||
this->nplots = 0;
|
||||
this->valid = true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
184
Tools/Utils/Gnuplot.hh
Normal file
184
Tools/Utils/Gnuplot.hh
Normal file
@@ -0,0 +1,184 @@
|
||||
////////////////////////////////////////////
|
||||
//
|
||||
// A C++ interface to gnuplot.
|
||||
//
|
||||
// This is a direct translation from the C interface
|
||||
// written by N. Devillard (which is available from
|
||||
// http://ndevilla.free.fr/gnuplot/).
|
||||
//
|
||||
// As in the C interface this uses pipes and so wont
|
||||
// run on a system that doesn't have POSIX pipe
|
||||
// support
|
||||
//
|
||||
// Rajarshi Guha
|
||||
// <rajarshi@presidency.com>
|
||||
//
|
||||
// 07/03/03
|
||||
//
|
||||
////////////////////////////////////////////
|
||||
//
|
||||
// A little correction for Win32 compatibility
|
||||
// and MS VC 6.0 done by V.Chyzhdzenka
|
||||
//
|
||||
// Notes:
|
||||
// 1. Added private method Gnuplot::init().
|
||||
// 2. Temporary file is created in th current
|
||||
// folder but not in /tmp.
|
||||
// 3. Added #indef WIN32 e.t.c. where is needed.
|
||||
// 4. Added private member m_sGNUPlotFileName is
|
||||
// a name of executed GNUPlot file.
|
||||
//
|
||||
// Viktor Chyzhdzenka
|
||||
// e-mail: chyzhdzenka@mail.ru
|
||||
//
|
||||
// 20/05/03
|
||||
//
|
||||
////////////////////////////////////////////
|
||||
|
||||
#ifndef _GNUPLOT_HH
|
||||
#define _GNUPLOT_HH
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
// #ifndef WIN32
|
||||
// # include <unistd.h>
|
||||
// #else
|
||||
// # pragma warning (disable : 4786) // Disable 4786 warning for MS VC 6.0
|
||||
// #endif
|
||||
#if defined(OM_CC_MIPS)
|
||||
# include <stdio.h>
|
||||
#else
|
||||
# include <cstdio>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef WIN32
|
||||
# define GP_MAX_TMP_FILES 27 //27 temporary files it's Microsoft restriction
|
||||
#else
|
||||
# define GP_MAX_TMP_FILES 64
|
||||
# define GP_TMP_NAME_SIZE 512
|
||||
# define GP_TITLE_SIZE 80
|
||||
#endif
|
||||
#define GP_CMD_SIZE 1024
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using namespace std;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Exception thrown by class Gnuplot
|
||||
class GnuplotException : public runtime_error
|
||||
{
|
||||
public:
|
||||
GnuplotException(const string &msg) : runtime_error(msg){}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** Utility class interfacing with Gnuplot.
|
||||
*
|
||||
* \note The plot will be visible as long as the object is not destructed.
|
||||
*
|
||||
* \author Rajarshi Guha (C++ API based on the C API by Nicolas Devillard)
|
||||
*
|
||||
* \see <a
|
||||
* href="http://ndevilla.free.fr/gnuplot/">http://ndevilla.free.fr/gnuplot/</a>
|
||||
* more information.
|
||||
*/
|
||||
class Gnuplot
|
||||
{
|
||||
private:
|
||||
|
||||
FILE *gnucmd;
|
||||
string pstyle;
|
||||
vector<string> to_delete;
|
||||
int nplots;
|
||||
bool get_program_path(const string);
|
||||
bool valid;
|
||||
|
||||
// Name of executed GNUPlot file
|
||||
static string gnuplot_executable_;
|
||||
|
||||
void init();
|
||||
|
||||
public:
|
||||
|
||||
/// \name Constructors
|
||||
//@{
|
||||
/// Default constructor.
|
||||
Gnuplot();
|
||||
|
||||
/// Set a style during construction.
|
||||
Gnuplot(const string & _style);
|
||||
|
||||
/// Constructor calling plot_xy().
|
||||
Gnuplot(const string & _title,
|
||||
const string & _style,
|
||||
const string & _xlabel,
|
||||
const string & _ylabel,
|
||||
vector<double> _x, vector<double> _y);
|
||||
|
||||
/// Constructor calling plot_x().
|
||||
Gnuplot(const string &_title,
|
||||
const string &_style,
|
||||
const string &_xlabel,
|
||||
const string &_ylabel,
|
||||
vector<double> _x);
|
||||
//@}
|
||||
|
||||
~Gnuplot();
|
||||
|
||||
/// Send a command to gnuplot (low-level function use by all plot functions.)
|
||||
void cmd(const char *_cmd, ...);
|
||||
|
||||
/// \name Gnuplot settings
|
||||
//@{
|
||||
void set_style(const string & _style); ///< set line style
|
||||
void set_ylabel(const string & _ylabel); ///< set x axis label
|
||||
void set_xlabel(const string & _xlabel); ///< set x axis label
|
||||
//@}
|
||||
|
||||
/// \name plot functions
|
||||
//@{
|
||||
|
||||
/// Plot a single vector
|
||||
void plot_x(vector<double> _x, const string &_title);
|
||||
|
||||
/// Plot x,y pairs
|
||||
void plot_xy(vector<double> _x, vector<double> _y, const string &_title);
|
||||
|
||||
/// Plot an equation of the form: y = ax + b
|
||||
/// You supply a and b
|
||||
void plot_slope(
|
||||
double _a,
|
||||
double _b,
|
||||
const string & _title
|
||||
);
|
||||
|
||||
/// Plot an equation supplied as a string
|
||||
void plot_equation(
|
||||
const string & _equation,
|
||||
const string & _title
|
||||
);
|
||||
|
||||
/// If multiple plots are present it will clear the plot area
|
||||
void reset_plot(void);
|
||||
|
||||
//@}
|
||||
|
||||
/// Is \c Self valid?
|
||||
bool is_valid(void) const { return valid; }
|
||||
|
||||
/// Is \c Self active, i.e. does it have an active plot?
|
||||
bool is_active(void) const { return this->nplots > 0; }
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif // _GNUPLOT_HH
|
||||
// ============================================================================
|
||||
|
||||
353
Tools/Utils/HeapT.hh
Normal file
353
Tools/Utils/HeapT.hh
Normal file
@@ -0,0 +1,353 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 HeapT.hh
|
||||
A generic heap class
|
||||
**/
|
||||
/** Martin, 26.12.2004:
|
||||
1) replaced resize(size()-1) with pop_back(), since the later is more efficient
|
||||
2) replaced interface_.set_heap_position(entry(0), -1); with reset_heap_position()
|
||||
3) added const modifier to various functions
|
||||
TODO: in the moment the heap does not conform to the HeapInterface specification,
|
||||
i.e., copies are passed instead of references. This is especially important
|
||||
for set_heap_position(), where the reference argument is non-const. The
|
||||
specification should be changed to reflect that the heap actually (only?)
|
||||
works when the heap entry is nothing more but a handle.
|
||||
TODO: change the specification of HeapInterface to make less(), greater() and
|
||||
get_heap_position() const. Needs changing DecimaterT. Might break
|
||||
someone's code.
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS HeapT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_UTILS_HEAPT_HH
|
||||
#define OPENMESH_UTILS_HEAPT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "Config.hh"
|
||||
#include <vector>
|
||||
#include <OpenMesh/Core/System/omstream.hh>
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Utils { // BEGIN_NS_UTILS
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** This class demonstrates the HeapInterface's interface. If you
|
||||
* want to build your customized heap you will have to specity a heap
|
||||
* interface class and use this class as a template parameter for the
|
||||
* class HeapT. This class defines the interface that this heap
|
||||
* interface has to implement.
|
||||
*
|
||||
* \see HeapT
|
||||
*/
|
||||
template <class HeapEntry>
|
||||
struct HeapInterfaceT
|
||||
{
|
||||
/// Comparison of two HeapEntry's: strict less
|
||||
bool less(const HeapEntry& _e1, const HeapEntry& _e2);
|
||||
|
||||
/// Comparison of two HeapEntry's: strict greater
|
||||
bool greater(const HeapEntry& _e1, const HeapEntry& _e2);
|
||||
|
||||
/// Get the heap position of HeapEntry _e
|
||||
int get_heap_position(const HeapEntry& _e);
|
||||
|
||||
/// Set the heap position of HeapEntry _e
|
||||
void set_heap_position(HeapEntry& _e, int _i);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** \class HeapT HeapT.hh <OSG/Utils/HeapT.hh>
|
||||
*
|
||||
* An efficient, highly customizable heap.
|
||||
*
|
||||
* The main difference (and performace boost) of this heap compared
|
||||
* to e.g. the heap of the STL is that here to positions of the
|
||||
* heap's elements are accessible from the elements themself.
|
||||
* Therefore if one changes the priority of an element one does not
|
||||
* have to remove and re-insert this element, but can just call the
|
||||
* update(HeapEntry) method.
|
||||
*
|
||||
* This heap class is parameterized by two template arguments:
|
||||
* \li the class \c HeapEntry, that will be stored in the heap
|
||||
* \li the HeapInterface telling the heap how to compare heap entries and
|
||||
* how to store the heap positions in the heap entries.
|
||||
*
|
||||
* As an example how to use the class see declaration of class
|
||||
* Decimater::DecimaterT.
|
||||
*
|
||||
* \see HeapInterfaceT
|
||||
*/
|
||||
|
||||
template <class HeapEntry, class HeapInterface=HeapEntry>
|
||||
class HeapT : private std::vector<HeapEntry>
|
||||
{
|
||||
private:
|
||||
typedef std::vector<HeapEntry> Base;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
HeapT() : HeapVector() {}
|
||||
|
||||
/// Construct with a given \c HeapIterface.
|
||||
HeapT(const HeapInterface& _interface)
|
||||
: HeapVector(), interface_(_interface)
|
||||
{}
|
||||
|
||||
/// Destructor.
|
||||
~HeapT(){};
|
||||
|
||||
|
||||
/// clear the heap
|
||||
void clear() { HeapVector::clear(); }
|
||||
|
||||
/// is heap empty?
|
||||
bool empty() const { return HeapVector::empty(); }
|
||||
|
||||
/// returns the size of heap
|
||||
unsigned int size() const { return HeapVector::size(); }
|
||||
|
||||
/// reserve space for _n entries
|
||||
void reserve(unsigned int _n) { HeapVector::reserve(_n); }
|
||||
|
||||
/// reset heap position to -1 (not in heap)
|
||||
void reset_heap_position(HeapEntry _h)
|
||||
{ interface_.set_heap_position(_h, -1); }
|
||||
|
||||
/// is an entry in the heap?
|
||||
bool is_stored(HeapEntry _h)
|
||||
{ return interface_.get_heap_position(_h) != -1; }
|
||||
|
||||
/// insert the entry _h
|
||||
void insert(HeapEntry _h)
|
||||
{
|
||||
push_back(_h);
|
||||
upheap(size()-1);
|
||||
}
|
||||
|
||||
/// get the first entry
|
||||
HeapEntry front() const
|
||||
{
|
||||
assert(!empty());
|
||||
return entry(0);
|
||||
}
|
||||
|
||||
/// delete the first entry
|
||||
void pop_front()
|
||||
{
|
||||
assert(!empty());
|
||||
reset_heap_position(entry(0));
|
||||
if (size() > 1)
|
||||
{
|
||||
entry(0, entry(size()-1));
|
||||
Base::pop_back();
|
||||
downheap(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Base::pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
/// remove an entry
|
||||
void remove(HeapEntry _h)
|
||||
{
|
||||
int pos = interface_.get_heap_position(_h);
|
||||
reset_heap_position(_h);
|
||||
|
||||
assert(pos != -1);
|
||||
assert((unsigned int) pos < size());
|
||||
|
||||
// last item ?
|
||||
if ((unsigned int) pos == size()-1)
|
||||
{
|
||||
Base::pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
entry(pos, entry(size()-1)); // move last elem to pos
|
||||
Base::pop_back();
|
||||
downheap(pos);
|
||||
upheap(pos);
|
||||
}
|
||||
}
|
||||
|
||||
/** update an entry: change the key and update the position to
|
||||
reestablish the heap property.
|
||||
*/
|
||||
void update(HeapEntry _h)
|
||||
{
|
||||
int pos = interface_.get_heap_position(_h);
|
||||
assert(pos != -1);
|
||||
assert((unsigned int)pos < size());
|
||||
downheap(pos);
|
||||
upheap(pos);
|
||||
}
|
||||
|
||||
/// check heap condition
|
||||
bool check()
|
||||
{
|
||||
bool ok(true);
|
||||
unsigned int i, j;
|
||||
for (i=0; i<size(); ++i)
|
||||
{
|
||||
if (((j=left(i))<size()) && interface_.greater(entry(i), entry(j)))
|
||||
{
|
||||
omerr() << "Heap condition violated\n";
|
||||
ok=false;
|
||||
}
|
||||
if (((j=right(i))<size()) && interface_.greater(entry(i), entry(j)))
|
||||
{
|
||||
omerr() << "Heap condition violated\n";
|
||||
ok=false;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Instance of HeapInterface
|
||||
HeapInterface interface_;
|
||||
|
||||
private:
|
||||
// typedef
|
||||
typedef std::vector<HeapEntry> HeapVector;
|
||||
|
||||
|
||||
/// Upheap. Establish heap property.
|
||||
void upheap(unsigned int _idx);
|
||||
|
||||
|
||||
/// Downheap. Establish heap property.
|
||||
void downheap(unsigned int _idx);
|
||||
|
||||
|
||||
/// Get the entry at index _idx
|
||||
inline HeapEntry entry(unsigned int _idx) const
|
||||
{
|
||||
assert(_idx < size());
|
||||
return (Base::operator[](_idx));
|
||||
}
|
||||
|
||||
|
||||
/// Set entry _h to index _idx and update _h's heap position.
|
||||
inline void entry(unsigned int _idx, HeapEntry _h)
|
||||
{
|
||||
assert(_idx < size());
|
||||
Base::operator[](_idx) = _h;
|
||||
interface_.set_heap_position(_h, _idx);
|
||||
}
|
||||
|
||||
|
||||
/// Get parent's index
|
||||
inline unsigned int parent(unsigned int _i) { return (_i-1)>>1; }
|
||||
/// Get left child's index
|
||||
inline unsigned int left(unsigned int _i) { return (_i<<1)+1; }
|
||||
/// Get right child's index
|
||||
inline unsigned int right(unsigned int _i) { return (_i<<1)+2; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template <class HeapEntry, class HeapInterface>
|
||||
void
|
||||
HeapT<HeapEntry, HeapInterface>::
|
||||
upheap(unsigned int _idx)
|
||||
{
|
||||
HeapEntry h = entry(_idx);
|
||||
unsigned int parentIdx;
|
||||
|
||||
while ((_idx>0) &&
|
||||
interface_.less(h, entry(parentIdx=parent(_idx))))
|
||||
{
|
||||
entry(_idx, entry(parentIdx));
|
||||
_idx = parentIdx;
|
||||
}
|
||||
|
||||
entry(_idx, h);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class HeapEntry, class HeapInterface>
|
||||
void
|
||||
HeapT<HeapEntry, HeapInterface>::
|
||||
downheap(unsigned int _idx)
|
||||
{
|
||||
HeapEntry h = entry(_idx);
|
||||
unsigned int childIdx;
|
||||
unsigned int s = size();
|
||||
|
||||
while(_idx < s)
|
||||
{
|
||||
childIdx = left(_idx);
|
||||
if (childIdx >= s) break;
|
||||
|
||||
if ((childIdx+1 < s) &&
|
||||
(interface_.less(entry(childIdx+1), entry(childIdx))))
|
||||
++childIdx;
|
||||
|
||||
if (interface_.less(h, entry(childIdx))) break;
|
||||
|
||||
entry(_idx, entry(childIdx));
|
||||
_idx = childIdx;
|
||||
}
|
||||
|
||||
entry(_idx, h);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_UTILS
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OSG_HEAP_HH defined
|
||||
//=============================================================================
|
||||
|
||||
222
Tools/Utils/MeshCheckerT.cc
Normal file
222
Tools/Utils/MeshCheckerT.cc
Normal file
@@ -0,0 +1,222 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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: 2433 $
|
||||
// $Date: 2008-08-27 13:43:05 +0200 (Mi, 27. Aug 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#define OPENMESH_MESHCHECKER_C
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <OpenMesh/Tools/Utils/MeshCheckerT.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ==============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Utils {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
bool
|
||||
MeshCheckerT<Mesh>::
|
||||
check(unsigned int _targets, std::ostream& _os)
|
||||
{
|
||||
bool ok(true);
|
||||
|
||||
|
||||
|
||||
//--- vertex checks ---
|
||||
|
||||
if (_targets & CHECK_VERTICES)
|
||||
{
|
||||
typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
|
||||
v_end(mesh_.vertices_end());
|
||||
typename Mesh::VertexHandle vh;
|
||||
typename Mesh::ConstVertexVertexIter vv_it;
|
||||
typename Mesh::HalfedgeHandle heh;
|
||||
unsigned int count;
|
||||
const unsigned int max_valence(10000);
|
||||
|
||||
|
||||
for (; v_it != v_end; ++v_it)
|
||||
{
|
||||
if (!is_deleted(v_it))
|
||||
{
|
||||
vh = v_it.handle();
|
||||
|
||||
|
||||
/* The outgoing halfedge of a boundary vertex has to be a
|
||||
boundary halfedge */
|
||||
heh = mesh_.halfedge_handle(vh);
|
||||
if (heh.is_valid() && !mesh_.is_boundary(heh))
|
||||
{
|
||||
for (typename Mesh::ConstVertexOHalfedgeIter vh_it(mesh_, vh);
|
||||
vh_it; ++vh_it)
|
||||
{
|
||||
if (mesh_.is_boundary(vh_it.handle()))
|
||||
{
|
||||
_os << "MeshChecker: vertex " << vh
|
||||
<< ": outgoing halfedge not on boundary error\n";
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// outgoing halfedge has to refer back to vertex
|
||||
if (mesh_.halfedge_handle(vh).is_valid() &&
|
||||
mesh_.from_vertex_handle(mesh_.halfedge_handle(vh)) != vh)
|
||||
{
|
||||
_os << "MeshChecker: vertex " << vh
|
||||
<< ": outgoing halfedge does not reference vertex\n";
|
||||
ok = false;
|
||||
}
|
||||
|
||||
|
||||
// check whether circulators are still in order
|
||||
vv_it = mesh_.cvv_iter(vh);
|
||||
for (count=0; vv_it && (count < max_valence); ++vv_it, ++count) {};
|
||||
if (count == max_valence)
|
||||
{
|
||||
_os << "MeshChecker: vertex " << vh
|
||||
<< ": ++circulator problem, one ring corrupt\n";
|
||||
ok = false;
|
||||
}
|
||||
vv_it = mesh_.cvv_iter(vh);
|
||||
for (count=0; vv_it && (count < max_valence); --vv_it, ++count) {};
|
||||
if (count == max_valence)
|
||||
{
|
||||
_os << "MeshChecker: vertex " << vh
|
||||
<< ": --circulator problem, one ring corrupt\n";
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--- halfedge checks ---
|
||||
|
||||
if (_targets & CHECK_EDGES)
|
||||
{
|
||||
typename Mesh::ConstHalfedgeIter h_it(mesh_.halfedges_begin()),
|
||||
h_end(mesh_.halfedges_end());
|
||||
typename Mesh::HalfedgeHandle hh, hstart, hhh;
|
||||
unsigned int count, n_halfedges = 2*mesh_.n_edges();
|
||||
|
||||
for (; h_it != h_end; ++h_it)
|
||||
{
|
||||
if (!is_deleted(mesh_.edge_handle(h_it.handle())))
|
||||
{
|
||||
hh = h_it.handle();
|
||||
|
||||
|
||||
// degenerated halfedge ?
|
||||
if (mesh_.from_vertex_handle(hh) == mesh_.to_vertex_handle(hh))
|
||||
{
|
||||
_os << "MeshChecker: halfedge " << hh
|
||||
<< ": to-vertex == from-vertex\n";
|
||||
ok = false;
|
||||
}
|
||||
|
||||
|
||||
// next <-> prev check
|
||||
if (mesh_.next_halfedge_handle(mesh_.prev_halfedge_handle(hh)) != hh)
|
||||
{
|
||||
_os << "MeshChecker: halfedge " << hh
|
||||
<< ": prev->next != this\n";
|
||||
ok = false;
|
||||
}
|
||||
|
||||
|
||||
// halfedges should form a cycle
|
||||
count=0; hstart=hhh=hh;
|
||||
do
|
||||
{
|
||||
hhh = mesh_.next_halfedge_handle(hhh);
|
||||
++count;
|
||||
} while (hhh != hstart && count < n_halfedges);
|
||||
|
||||
if (count == n_halfedges)
|
||||
{
|
||||
_os << "MeshChecker: halfedges starting from " << hh
|
||||
<< " do not form a cycle\n";
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--- face checks ---
|
||||
|
||||
if (_targets & CHECK_FACES)
|
||||
{
|
||||
typename Mesh::ConstFaceIter f_it(mesh_.faces_begin()),
|
||||
f_end(mesh_.faces_end());
|
||||
typename Mesh::FaceHandle fh;
|
||||
typename Mesh::ConstFaceHalfedgeIter fh_it;
|
||||
|
||||
for (; f_it != f_end; ++f_it)
|
||||
{
|
||||
if (!is_deleted(f_it))
|
||||
{
|
||||
fh = f_it.handle();
|
||||
|
||||
for (fh_it=mesh_.cfh_iter(fh); fh_it; ++fh_it)
|
||||
{
|
||||
if (mesh_.face_handle(fh_it.handle()) != fh)
|
||||
{
|
||||
_os << "MeshChecker: face " << fh
|
||||
<< ": its halfedge does not reference face\n";
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // naespace Utils
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
114
Tools/Utils/MeshCheckerT.hh
Normal file
114
Tools/Utils/MeshCheckerT.hh
Normal file
@@ -0,0 +1,114 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef OPENMESH_MESHCHECKER_HH
|
||||
#define OPENMESH_MESHCHECKER_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/System/omstream.hh>
|
||||
#include <OpenMesh/Core/Utils/GenProg.hh>
|
||||
#include <OpenMesh/Core/Mesh/Attributes.hh>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Utils {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Check integrity of mesh.
|
||||
*
|
||||
* This class provides several functions to check the integrity of a mesh.
|
||||
*/
|
||||
template <class Mesh>
|
||||
class MeshCheckerT
|
||||
{
|
||||
public:
|
||||
|
||||
/// constructor
|
||||
MeshCheckerT(const Mesh& _mesh) : mesh_(_mesh) {}
|
||||
|
||||
/// destructor
|
||||
~MeshCheckerT() {}
|
||||
|
||||
|
||||
/// what should be checked?
|
||||
enum CheckTargets
|
||||
{
|
||||
CHECK_EDGES = 1,
|
||||
CHECK_VERTICES = 2,
|
||||
CHECK_FACES = 4,
|
||||
CHECK_ALL = 255,
|
||||
};
|
||||
|
||||
|
||||
/// check it, return true iff ok
|
||||
bool check( unsigned int _targets=CHECK_ALL,
|
||||
std::ostream& _os= omerr());
|
||||
|
||||
|
||||
private:
|
||||
|
||||
bool is_deleted(typename Mesh::VertexHandle _vh)
|
||||
{ return (mesh_.has_vertex_status() ? mesh_.status(_vh).deleted() : false); }
|
||||
|
||||
bool is_deleted(typename Mesh::EdgeHandle _eh)
|
||||
{ return (mesh_.has_edge_status() ? mesh_.status(_eh).deleted() : false); }
|
||||
|
||||
bool is_deleted(typename Mesh::FaceHandle _fh)
|
||||
{ return (mesh_.has_face_status() ? mesh_.status(_fh).deleted() : false); }
|
||||
|
||||
|
||||
// ref to mesh
|
||||
const Mesh& mesh_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace Utils
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_MESHCHECKER_C)
|
||||
#define OPENMESH_MESHCHECKER_TEMPLATES
|
||||
#include "MeshCheckerT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_MESHCHECKER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
136
Tools/Utils/NumLimitsT.hh
Normal file
136
Tools/Utils/NumLimitsT.hh
Normal file
@@ -0,0 +1,136 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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: 4254 $
|
||||
// $Date: 2009-01-12 14:44:00 +0100 (Mo, 12. Jan 2009) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file NumLimitsT.hh
|
||||
Temporary solution until std::numeric_limits is standard.
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NumLimitsT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_UTILS_NUMLIMITS_HH
|
||||
#define OPENMESH_UTILS_NUMLIMITS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "Config.hh"
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
|
||||
|
||||
//== NAMESPEACES ==============================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Utils { // BEGIN_NS_UTILS
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** \class NumLimitsT NumLimitsT.hh <OpenMesh/Utils/NumLimitsT.hh
|
||||
|
||||
This class provides the maximum and minimum values a certain
|
||||
scalar type (\cint, \c float, or \double) can store. You can
|
||||
use it like this:
|
||||
\code
|
||||
#include <OpenMesh/Utils/NumLimitsT.hh>
|
||||
|
||||
int float_min = OpenMesh::NumLimitsT<float>::min();
|
||||
float double_max = OpenMesh::NumLimitsT<double>::max();
|
||||
\endcode
|
||||
|
||||
\note This functionality should be provided by
|
||||
std::numeric_limits. This template does not exist on gcc <=
|
||||
2.95.3. The class template NumLimitsT is just a workaround.
|
||||
**/
|
||||
template <typename Scalar>
|
||||
class NumLimitsT
|
||||
{
|
||||
public:
|
||||
/// Return the smallest \em absolte value a scalar type can store.
|
||||
static inline Scalar min() { return 0; }
|
||||
/// Return the maximum \em absolte value a scalar type can store.
|
||||
static inline Scalar max() { return 0; }
|
||||
|
||||
static inline bool is_float() { return false; }
|
||||
static inline bool is_integer() { return !NumLimitsT<Scalar>::is_float(); }
|
||||
static inline bool is_signed() { return true; }
|
||||
};
|
||||
|
||||
// is_float
|
||||
|
||||
template<>
|
||||
inline bool NumLimitsT<float>::is_float() { return true; }
|
||||
|
||||
template<>
|
||||
inline bool NumLimitsT<double>::is_float() { return true; }
|
||||
|
||||
template<>
|
||||
inline bool NumLimitsT<long double>::is_float() { return true; }
|
||||
|
||||
// is_signed
|
||||
|
||||
template<>
|
||||
inline bool NumLimitsT<unsigned char>::is_signed() { return false; }
|
||||
|
||||
template<>
|
||||
inline bool NumLimitsT<unsigned short>::is_signed() { return false; }
|
||||
|
||||
template<>
|
||||
inline bool NumLimitsT<unsigned int>::is_signed() { return false; }
|
||||
|
||||
template<>
|
||||
inline bool NumLimitsT<unsigned long>::is_signed() { return false; }
|
||||
|
||||
template<>
|
||||
inline bool NumLimitsT<unsigned long long>::is_signed() { return false; }
|
||||
|
||||
// min/max
|
||||
template<> inline int NumLimitsT<int>::min() { return INT_MIN; }
|
||||
template<> inline int NumLimitsT<int>::max() { return INT_MAX; }
|
||||
|
||||
template<> inline float NumLimitsT<float>::min() { return FLT_MIN; }
|
||||
template<> inline float NumLimitsT<float>::max() { return FLT_MAX; }
|
||||
|
||||
template<> inline double NumLimitsT<double>::min() { return DBL_MIN; }
|
||||
template<> inline double NumLimitsT<double>::max() { return DBL_MAX; }
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_UTILS
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_NUMLIMITS_HH defined
|
||||
//=============================================================================
|
||||
|
||||
253
Tools/Utils/StripifierT.cc
Normal file
253
Tools/Utils/StripifierT.cc
Normal file
@@ -0,0 +1,253 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2001-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) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS StripifierT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define OPENMESH_STRIPIFIERT_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/Utils/StripifierT.hh>
|
||||
#include <list>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
unsigned int
|
||||
StripifierT<Mesh>::
|
||||
stripify()
|
||||
{
|
||||
// preprocess: add new properties
|
||||
mesh_.add_property( processed_ );
|
||||
mesh_.add_property( used_ );
|
||||
mesh_.request_face_status();
|
||||
|
||||
|
||||
// build strips
|
||||
clear();
|
||||
build_strips();
|
||||
|
||||
|
||||
// postprocess: remove properties
|
||||
//mesh_.remove_property(processed_);
|
||||
//mesh_.remove_property(used_);
|
||||
//mesh_.release_face_status();
|
||||
|
||||
|
||||
return n_strips();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
StripifierT<Mesh>::
|
||||
build_strips()
|
||||
{
|
||||
Strip experiments[3];
|
||||
typename Mesh::HalfedgeHandle h[3];
|
||||
unsigned int best_idx, best_length, length;
|
||||
FaceHandles faces[3];
|
||||
typename FaceHandles::iterator fh_it, fh_end;
|
||||
typename Mesh::FaceIter f_it, f_end=mesh_.faces_end();
|
||||
|
||||
|
||||
|
||||
// init faces to be un-processed and un-used
|
||||
// deleted or hidden faces are marked processed
|
||||
if (mesh_.has_face_status())
|
||||
{
|
||||
for (f_it=mesh_.faces_begin(); f_it!=f_end; ++f_it)
|
||||
if (mesh_.status(f_it).hidden() || mesh_.status(f_it).deleted())
|
||||
processed(f_it) = used(f_it) = true;
|
||||
else
|
||||
processed(f_it) = used(f_it) = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (f_it=mesh_.faces_begin(); f_it!=f_end; ++f_it)
|
||||
processed(f_it) = used(f_it) = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (f_it=mesh_.faces_begin(); true; )
|
||||
{
|
||||
// find start face
|
||||
for (; f_it!=f_end; ++f_it)
|
||||
if (!processed(f_it))
|
||||
break;
|
||||
if (f_it==f_end) break; // stop if all have been processed
|
||||
|
||||
|
||||
// collect starting halfedges
|
||||
h[0] = mesh_.halfedge_handle(f_it.handle());
|
||||
h[1] = mesh_.next_halfedge_handle(h[0]);
|
||||
h[2] = mesh_.next_halfedge_handle(h[1]);
|
||||
|
||||
|
||||
// build 3 strips, take best one
|
||||
best_length = best_idx = 0;
|
||||
for (unsigned int i=0; i<3; ++i)
|
||||
{
|
||||
build_strip(h[i], experiments[i], faces[i]);
|
||||
if ((length = experiments[i].size()) > best_length)
|
||||
{
|
||||
best_length = length;
|
||||
best_idx = i;
|
||||
}
|
||||
|
||||
for (fh_it=faces[i].begin(), fh_end=faces[i].end();
|
||||
fh_it!=fh_end; ++fh_it)
|
||||
used(*fh_it) = false;
|
||||
}
|
||||
|
||||
|
||||
// update processed status
|
||||
fh_it = faces[best_idx].begin();
|
||||
fh_end = faces[best_idx].end();
|
||||
for (; fh_it!=fh_end; ++fh_it)
|
||||
processed(*fh_it) = true;
|
||||
|
||||
|
||||
|
||||
// add best strip to strip-list
|
||||
strips_.push_back(experiments[best_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Mesh>
|
||||
void
|
||||
StripifierT<Mesh>::
|
||||
build_strip(typename Mesh::HalfedgeHandle _start_hh,
|
||||
Strip& _strip,
|
||||
FaceHandles& _faces)
|
||||
{
|
||||
std::list<unsigned int> strip;
|
||||
typename Mesh::HalfedgeHandle hh;
|
||||
typename Mesh::FaceHandle fh;
|
||||
|
||||
|
||||
// reset face list
|
||||
_faces.clear();
|
||||
|
||||
|
||||
// init strip
|
||||
strip.push_back(mesh_.from_vertex_handle(_start_hh).idx());
|
||||
strip.push_back(mesh_.to_vertex_handle(_start_hh).idx());
|
||||
|
||||
|
||||
// walk along the strip: 1st direction
|
||||
hh = mesh_.prev_halfedge_handle(mesh_.opposite_halfedge_handle(_start_hh));
|
||||
while (1)
|
||||
{
|
||||
// go right
|
||||
hh = mesh_.next_halfedge_handle(hh);
|
||||
hh = mesh_.opposite_halfedge_handle(hh);
|
||||
hh = mesh_.next_halfedge_handle(hh);
|
||||
if (mesh_.is_boundary(hh)) break;
|
||||
fh = mesh_.face_handle(hh);
|
||||
if (processed(fh) || used(fh)) break;
|
||||
_faces.push_back(fh);
|
||||
used(fh) = true;
|
||||
strip.push_back(mesh_.to_vertex_handle(hh).idx());
|
||||
|
||||
// go left
|
||||
hh = mesh_.opposite_halfedge_handle(hh);
|
||||
hh = mesh_.next_halfedge_handle(hh);
|
||||
if (mesh_.is_boundary(hh)) break;
|
||||
fh = mesh_.face_handle(hh);
|
||||
if (processed(fh) || used(fh)) break;
|
||||
_faces.push_back(fh);
|
||||
used(fh) = true;
|
||||
strip.push_back(mesh_.to_vertex_handle(hh).idx());
|
||||
}
|
||||
|
||||
|
||||
// walk along the strip: 2nd direction
|
||||
bool flip(false);
|
||||
hh = mesh_.prev_halfedge_handle(_start_hh);
|
||||
while (1)
|
||||
{
|
||||
// go right
|
||||
hh = mesh_.next_halfedge_handle(hh);
|
||||
hh = mesh_.opposite_halfedge_handle(hh);
|
||||
hh = mesh_.next_halfedge_handle(hh);
|
||||
if (mesh_.is_boundary(hh)) break;
|
||||
fh = mesh_.face_handle(hh);
|
||||
if (processed(fh) || used(fh)) break;
|
||||
_faces.push_back(fh);
|
||||
used(fh) = true;
|
||||
strip.push_front(mesh_.to_vertex_handle(hh).idx());
|
||||
flip = true;
|
||||
|
||||
// go left
|
||||
hh = mesh_.opposite_halfedge_handle(hh);
|
||||
hh = mesh_.next_halfedge_handle(hh);
|
||||
if (mesh_.is_boundary(hh)) break;
|
||||
fh = mesh_.face_handle(hh);
|
||||
if (processed(fh) || used(fh)) break;
|
||||
_faces.push_back(fh);
|
||||
used(fh) = true;
|
||||
strip.push_front(mesh_.to_vertex_handle(hh).idx());
|
||||
flip = false;
|
||||
}
|
||||
|
||||
if (flip) strip.push_front(strip.front());
|
||||
|
||||
|
||||
|
||||
// copy final strip to _strip
|
||||
_strip.clear();
|
||||
_strip.reserve(strip.size());
|
||||
std::copy(strip.begin(), strip.end(), std::back_inserter(_strip));
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
141
Tools/Utils/StripifierT.hh
Normal file
141
Tools/Utils/StripifierT.hh
Normal file
@@ -0,0 +1,141 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2001-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) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS StripifierT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef OPENMESH_STRIPIFIERT_HH
|
||||
#define OPENMESH_STRIPIFIERT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <vector>
|
||||
#include <OpenMesh/Core/Utils/Property.hh>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
|
||||
/** \class StripifierT StripifierT.hh <OpenMesh/Tools/Utils/StripifierT.hh>
|
||||
This class decomposes a triangle mesh into several triangle strips.
|
||||
*/
|
||||
|
||||
template <class Mesh>
|
||||
class StripifierT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef unsigned int Index;
|
||||
typedef std::vector<Index> Strip;
|
||||
typedef typename Strip::const_iterator IndexIterator;
|
||||
typedef std::vector<Strip> Strips;
|
||||
typedef typename Strips::const_iterator StripsIterator;
|
||||
|
||||
|
||||
/// Default constructor
|
||||
StripifierT(Mesh& _mesh) : mesh_(_mesh) {}
|
||||
|
||||
/// Destructor
|
||||
~StripifierT() {}
|
||||
|
||||
|
||||
/// Compute triangle strips, returns number of strips
|
||||
unsigned int stripify();
|
||||
|
||||
/// delete all strips
|
||||
void clear() { Strips().swap(strips_); }
|
||||
|
||||
/// returns number of strips
|
||||
unsigned int n_strips() const { return strips_.size(); }
|
||||
|
||||
/// are strips computed?
|
||||
bool is_valid() const { return !strips_.empty(); }
|
||||
|
||||
/// Access strips
|
||||
StripsIterator begin() const { return strips_.begin(); }
|
||||
/// Access strips
|
||||
StripsIterator end() const { return strips_.end(); }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
typedef std::vector<typename Mesh::FaceHandle> FaceHandles;
|
||||
|
||||
|
||||
/// this method does the main work
|
||||
void build_strips();
|
||||
|
||||
/// build a strip from a given halfedge (in both directions)
|
||||
void build_strip(typename Mesh::HalfedgeHandle _start_hh,
|
||||
Strip& _strip,
|
||||
FaceHandles& _faces);
|
||||
|
||||
FPropHandleT<bool>::reference processed(typename Mesh::FaceHandle _fh) {
|
||||
return mesh_.property(processed_, _fh);
|
||||
}
|
||||
FPropHandleT<bool>::reference used(typename Mesh::FaceHandle _fh) {
|
||||
return mesh_.property(used_, _fh);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Mesh& mesh_;
|
||||
Strips strips_;
|
||||
FPropHandleT<bool> processed_, used_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_STRIPIFIERT_C)
|
||||
#define OPENMESH_STRIPIFIERT_TEMPLATES
|
||||
#include "StripifierT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_STRIPIFIERT_HH defined
|
||||
//=============================================================================
|
||||
330
Tools/Utils/TestingFramework.hh
Normal file
330
Tools/Utils/TestingFramework.hh
Normal file
@@ -0,0 +1,330 @@
|
||||
// ============================================================================
|
||||
// $Id: TestingFramework.hh,v 1.1.1.1 2006-10-25 16:14:15 habbecke Exp $
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef TESTINGFRAMEWORK_HH
|
||||
#define TESTINGFRAMEWORK_HH
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** \file TestingFramework.hh
|
||||
This file contains a little framework for test programms
|
||||
*/
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "Config.hh"
|
||||
#include <iosfwd>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <OpenMesh/Core/Utils/Noncopyable.hh>
|
||||
|
||||
// ------------------------------------------------------------- namespace ----
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Utils { // BEGIN_NS_UTILS
|
||||
|
||||
|
||||
// ----------------------------------------------------------------- class ----
|
||||
//
|
||||
// Usage Example
|
||||
//
|
||||
// #include <iostream>
|
||||
// #include <.../TestingFramework.hh>
|
||||
//
|
||||
// struct test_func : public TestingFramework::TestFunc
|
||||
// {
|
||||
// typedef test_func Self;
|
||||
//
|
||||
// // define ctor and copy-ctor
|
||||
// test_func( TestingFramework& _th, std::string _n ) : TestingFramework::TestFunc( _th, _n ) { }
|
||||
// test_func( Self& _cpy ) : TestingFramework::TestFunc(_cpy) { }
|
||||
//
|
||||
// // overload body()
|
||||
// void body()
|
||||
// {
|
||||
//
|
||||
// // Do the tests
|
||||
// // direct call to verify
|
||||
// verify( testResult, expectedResult, "additional information" );
|
||||
//
|
||||
// // or use the define TH_VERIFY. The test-expression will be used as the message string
|
||||
// TH_VERIFY( testResult, expectedResult );
|
||||
//
|
||||
// ...
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// int main(...)
|
||||
// {
|
||||
// TestingFramework testSuite(std::cout); // send output to stdout
|
||||
//
|
||||
// new test_func(testSuite); // create new test instance. It registers with testSuite.
|
||||
// return testSuite.run();
|
||||
// }
|
||||
//
|
||||
|
||||
//
|
||||
#define TH_VERIFY( expr, expt ) \
|
||||
verify( expr, expt, #expr )
|
||||
|
||||
//
|
||||
#define TH_VERIFY_X( expr, expt ) \
|
||||
verify_x( expr, expt, #expr )
|
||||
|
||||
/** Helper class for test programms.
|
||||
\internal
|
||||
*/
|
||||
class TestingFramework : Noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
typedef TestingFramework Self;
|
||||
typedef std::logic_error verify_error;
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
class TestFunc
|
||||
{
|
||||
public:
|
||||
TestFunc( TestingFramework& _th, const std::string& _n )
|
||||
: th_(_th), name_(_n)
|
||||
{
|
||||
th_.reg(this);
|
||||
}
|
||||
|
||||
virtual ~TestFunc()
|
||||
{ }
|
||||
|
||||
void operator() ( void )
|
||||
{
|
||||
prolog();
|
||||
try
|
||||
{
|
||||
body();
|
||||
}
|
||||
catch( std::exception& x )
|
||||
{
|
||||
std::cerr << "<<Error>>: Cannot proceed test due to failure of last"
|
||||
<< " test: " << x.what() << std::endl;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Fatal: cannot proceed test due to unknown error!"
|
||||
<< std::endl;
|
||||
}
|
||||
epilog();
|
||||
}
|
||||
|
||||
const TestingFramework& testHelper() const { return th_; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual void prolog(void)
|
||||
{
|
||||
begin(name_);
|
||||
}
|
||||
|
||||
virtual void body(void) = 0;
|
||||
|
||||
virtual void epilog(void)
|
||||
{
|
||||
end();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
TestingFramework& testHelper() { return th_; }
|
||||
|
||||
TestFunc( const TestFunc& _cpy ) : th_(_cpy.th_), name_(_cpy.name_) { }
|
||||
|
||||
|
||||
// Use the following method in prolog()
|
||||
TestFunc& begin(std::string _title, const std::string& _info = "")
|
||||
{ th_.begin(_title,_info); return *this; }
|
||||
|
||||
|
||||
// Use the following method in epilog()
|
||||
TestFunc& end(void)
|
||||
{ th_.end(); return *this; }
|
||||
|
||||
|
||||
// Use the followin methods in body()
|
||||
|
||||
template <typename ValueType>
|
||||
bool
|
||||
verify( const ValueType& _rc, const ValueType& _expected,
|
||||
std::string _info )
|
||||
{ return th_.verify( _rc, _expected, _info ); }
|
||||
|
||||
template <typename ValueType>
|
||||
void
|
||||
verify_x( const ValueType& _rc, const ValueType& _expected,
|
||||
std::string _info )
|
||||
{
|
||||
if ( !verify(_rc, _expected, _info) )
|
||||
throw verify_error(_info);
|
||||
}
|
||||
|
||||
TestFunc& info(const std::string& _info)
|
||||
{ th_.info(_info); return *this; }
|
||||
|
||||
TestFunc& info(const std::ostringstream& _ostr)
|
||||
{ th_.info(_ostr); return *this; }
|
||||
|
||||
private:
|
||||
TestFunc();
|
||||
|
||||
protected:
|
||||
TestingFramework& th_;
|
||||
std::string name_;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef TestFunc* TestFuncPtr;
|
||||
typedef std::vector<TestFuncPtr> TestSet;
|
||||
|
||||
public:
|
||||
|
||||
TestingFramework(std::ostream& _os)
|
||||
: errTotal_(0), errCount_(0),
|
||||
verifyTotal_(0), verifyCount_(0),
|
||||
testTotal_(0), testCount_(0),
|
||||
os_(_os)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
struct TestDeleter
|
||||
{
|
||||
void operator() (TestFuncPtr _tfptr) { delete _tfptr; }
|
||||
};
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
virtual ~TestingFramework()
|
||||
{
|
||||
std::for_each(tests_.begin(), tests_.end(), TestDeleter() );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
template <typename ValueType>
|
||||
bool verify(const ValueType& _rc,
|
||||
const ValueType& _expected,
|
||||
const std::string& _info)
|
||||
{
|
||||
++verifyTotal_;
|
||||
if ( _rc == _expected )
|
||||
{
|
||||
os_ << " " << _info << ", result: " << _rc << ", OK!" << std::endl;
|
||||
return true;
|
||||
}
|
||||
++errTotal_;
|
||||
os_ << " " << _info << ", result: " << _rc << " != " << _expected
|
||||
<< " <<ERROR>>" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Self& begin(std::string _title, const std::string& _info = "")
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
||||
testTitle_ = _title;
|
||||
errCount_ = errTotal_;
|
||||
++testTotal_;
|
||||
|
||||
ostr << _title;
|
||||
if ( !_info.empty() )
|
||||
ostr << " ["<< _info << "]";
|
||||
testTitle_ = ostr.str();
|
||||
os_ << "Begin " << testTitle_ << std::endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Self& end()
|
||||
{
|
||||
if (errorCount()==0)
|
||||
++testCount_;
|
||||
|
||||
os_ << "End " << testTitle_ << ": " << errorCount() << " Error(s)." << std::endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Self& info(const std::string& _info)
|
||||
{
|
||||
os_ << " + " << _info << std::endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Self& info(const std::ostringstream& _ostr)
|
||||
{
|
||||
os_ << " + " << _ostr.str() << std::endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t errorTotal() const { return errTotal_; }
|
||||
size_t errorCount() const { return errTotal_ - errCount_; }
|
||||
size_t verifyTotal() const { return verifyTotal_; }
|
||||
size_t verifyCount() const { return verifyTotal_ - verifyCount_; }
|
||||
size_t goodTotal() const { return verifyTotal() - errorTotal(); }
|
||||
size_t goodCount() const { return verifyCount() - errorCount(); }
|
||||
|
||||
size_t testTotal() const { return testTotal_; }
|
||||
size_t testCount() const { return testCount_; }
|
||||
|
||||
public:
|
||||
|
||||
int run(void)
|
||||
{
|
||||
os_ << "Test started\n";
|
||||
TestRunner executer;
|
||||
std::for_each(tests_.begin(), tests_.end(), executer );
|
||||
os_ << std::endl;
|
||||
os_ << "All tests completed" << std::endl
|
||||
<< " #Tests: " << testCount() << "/" << testTotal() << std::endl
|
||||
<< " #Errors: " << errorTotal() << "/" << verifyTotal() << std::endl;
|
||||
return errorTotal();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
struct TestRunner
|
||||
{
|
||||
void operator() (TestFuncPtr _tfptr) { (*_tfptr)(); }
|
||||
};
|
||||
#endif
|
||||
|
||||
int reg(TestFuncPtr _tfptr)
|
||||
{
|
||||
tests_.push_back(_tfptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
friend class TestFunc;
|
||||
|
||||
private:
|
||||
|
||||
size_t errTotal_;
|
||||
size_t errCount_;
|
||||
size_t verifyTotal_;
|
||||
size_t verifyCount_;
|
||||
size_t testTotal_; // #Tests
|
||||
size_t testCount_; // #Tests ohne Fehler
|
||||
|
||||
std::string testTitle_;
|
||||
std::ostream& os_;
|
||||
|
||||
TestSet tests_;
|
||||
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
} // END_NS_UTILS
|
||||
} // END_NS_OPENMESH
|
||||
// ============================================================================
|
||||
#endif // TESTINGFRMEWORK_HH
|
||||
// ============================================================================
|
||||
397
Tools/Utils/Timer.cc
Normal file
397
Tools/Utils/Timer.cc
Normal file
@@ -0,0 +1,397 @@
|
||||
// ============================================================================
|
||||
// $Id: Timer.cc,v 1.1.1.1 2006-10-25 16:14:15 habbecke Exp $
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
// ----------------------------------------------------------------------------
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#if defined(OM_CC_MIPS)
|
||||
# include <math.h>
|
||||
# include <stdio.h>
|
||||
#else
|
||||
# include <cmath>
|
||||
# include <cstdio>
|
||||
#endif
|
||||
#include "Timer.hh"
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------- namespace ----
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Utils {
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using namespace std;
|
||||
|
||||
// -------------------------------------------------------------- TimerImpl ----
|
||||
// just a base class for the implementation
|
||||
class TimerImpl
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
TimerImpl() { ; }
|
||||
virtual ~TimerImpl() { ; }
|
||||
|
||||
virtual void reset(void) = 0;
|
||||
virtual void start(void) = 0;
|
||||
virtual void stop(void) = 0;
|
||||
virtual void cont(void) = 0;
|
||||
virtual double seconds(void) const = 0;
|
||||
};
|
||||
|
||||
// compiler and os dependent implementation
|
||||
|
||||
// ------------------------------------------------------------- windows 32 ----
|
||||
#if defined(WIN32) && (defined(_MSC_VER) || defined(__INTEL_COMPILER))
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class TimerImplWin32 : public TimerImpl
|
||||
{
|
||||
protected:
|
||||
LARGE_INTEGER freq_;
|
||||
LARGE_INTEGER count_;
|
||||
LARGE_INTEGER start_;
|
||||
|
||||
public:
|
||||
TimerImplWin32(void);
|
||||
~TimerImplWin32(void) { ; }
|
||||
|
||||
virtual void reset(void);
|
||||
virtual void start(void);
|
||||
virtual void stop(void);
|
||||
virtual void cont(void);
|
||||
virtual double seconds(void) const;
|
||||
};
|
||||
|
||||
TimerImplWin32::TimerImplWin32(void)
|
||||
{
|
||||
if (QueryPerformanceFrequency(&freq_)==FALSE)
|
||||
throw std::runtime_error("Performance counter of of stock!");
|
||||
reset();
|
||||
}
|
||||
|
||||
void TimerImplWin32::reset(void)
|
||||
{
|
||||
memset(&count_,0,sizeof(count_));
|
||||
memset(&start_,0,sizeof(count_));
|
||||
}
|
||||
|
||||
void TimerImplWin32::start(void)
|
||||
{
|
||||
reset();
|
||||
QueryPerformanceCounter(&start_);
|
||||
}
|
||||
|
||||
void TimerImplWin32::stop(void)
|
||||
{
|
||||
LARGE_INTEGER stop_;
|
||||
|
||||
QueryPerformanceCounter(&stop_);
|
||||
count_.QuadPart += stop_.QuadPart - start_.QuadPart;
|
||||
}
|
||||
|
||||
void TimerImplWin32::cont(void)
|
||||
{
|
||||
QueryPerformanceCounter(&start_);
|
||||
}
|
||||
|
||||
double TimerImplWin32::seconds(void) const
|
||||
{
|
||||
return (double)count_.QuadPart/(double)freq_.QuadPart;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------- posix time ----
|
||||
#elif defined(__GNUC__) && defined(__POSIX__)
|
||||
|
||||
# include <time.h>
|
||||
|
||||
template <clockid_t N>
|
||||
class TimerImplPosix : public TimerImpl
|
||||
{
|
||||
public:
|
||||
TimerImplPosix() : id_(N), seconds_(0.0)
|
||||
{ }
|
||||
|
||||
~TimerImplPosix()
|
||||
{ }
|
||||
|
||||
virtual void reset(void) { seconds_ = 0.0; }
|
||||
|
||||
virtual void start(void) { seconds_ = 0.0; clock_gettime( id_, &start_ ); }
|
||||
virtual void stop(void)
|
||||
{
|
||||
timespec stop;
|
||||
clock_gettime( id_, &stop );
|
||||
seconds_ += ( stop.tv_sec - start_.tv_sec );
|
||||
seconds_ += ( (double(stop.tv_nsec-start_.tv_nsec)*1e-9) );
|
||||
}
|
||||
|
||||
virtual void cont(void) { clock_gettime( id_, &start_ ); }
|
||||
|
||||
virtual double seconds() const { return seconds_; }
|
||||
|
||||
protected:
|
||||
clockid_t id_;
|
||||
double seconds_;
|
||||
timespec start_;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------- gettimeofday ----
|
||||
#elif defined(__GNUC__) || (defined(__INTEL_COMPILER) && !defined(WIN32))
|
||||
|
||||
# include <sys/time.h>
|
||||
# include <sys/resource.h>
|
||||
# include <unistd.h>
|
||||
|
||||
class TimerImplGToD: public TimerImpl
|
||||
{
|
||||
public:
|
||||
TimerImplGToD() : seconds_(0.0)
|
||||
{ }
|
||||
|
||||
~TimerImplGToD()
|
||||
{ }
|
||||
|
||||
virtual void reset(void) { seconds_ = 0.0; }
|
||||
virtual void start(void) { seconds_ = 0.0; gettimeofday( &start_, &tz_ ); }
|
||||
|
||||
virtual void stop(void)
|
||||
{
|
||||
gettimeofday( &stop_, &tz_ );
|
||||
|
||||
seconds_ += (double)(stop_.tv_sec - start_.tv_sec);
|
||||
seconds_ += (double)(stop_.tv_usec- start_.tv_usec)*1e-6;
|
||||
}
|
||||
|
||||
virtual void cont(void) { gettimeofday( &start_, &tz_); }
|
||||
|
||||
virtual double seconds() const { return seconds_; }
|
||||
|
||||
private:
|
||||
|
||||
struct timeval start_, stop_;
|
||||
struct timezone tz_;
|
||||
|
||||
double seconds_;
|
||||
};
|
||||
|
||||
|
||||
#else // ---------------------------------------- standard implementation ----
|
||||
|
||||
#include <time.h>
|
||||
|
||||
static const unsigned long clockticks = CLOCKS_PER_SEC;
|
||||
|
||||
class TimerImplStd : public TimerImpl
|
||||
{
|
||||
public:
|
||||
TimerImplStd() : freq_(clockticks) { reset(); }
|
||||
~TimerImplStd() { ; }
|
||||
|
||||
virtual void reset(void) { count_ = 0; }
|
||||
virtual void start(void) { count_ = 0; start_ = clock(); }
|
||||
virtual void stop(void);
|
||||
virtual void cont(void) { start_ = clock(); }
|
||||
virtual double seconds(void) const { return (double)count_/(double)freq_; }
|
||||
|
||||
protected:
|
||||
unsigned long freq_;
|
||||
unsigned long count_;
|
||||
unsigned long start_;
|
||||
};
|
||||
|
||||
void TimerImplStd::stop(void)
|
||||
{
|
||||
unsigned long stop_ = clock();
|
||||
count_ += stop_-start_;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------- Timer ----
|
||||
|
||||
Timer::Timer(void)
|
||||
{
|
||||
#if defined(WIN32) && defined(_MSC_VER)
|
||||
impl_ = new TimerImplWin32;
|
||||
#elif defined(__GNUC__) && defined(__POSIX__)
|
||||
// CLOCK_REALTIME
|
||||
// CLOCK_MONOTONIC - ?
|
||||
// CLOCK_REALTIME_HR - RTlinux
|
||||
// CLOCK_MONOTONIC_HR - ?
|
||||
# if defined(CLOCK_REALTIME_HR)
|
||||
impl_ = new TimerImplPosix<CLOCK_REALTIME_HR>;
|
||||
# else
|
||||
impl_ = new TimerImplPosix<CLOCK_REALTIME>;
|
||||
# endif
|
||||
#elif defined(__GNUC__) || (defined(__INTEL_COMPILER) && !defined(WIN32))
|
||||
impl_ = new TimerImplGToD;
|
||||
#else
|
||||
impl_ = new TimerImplStd;
|
||||
#endif
|
||||
state_ = Stopped;
|
||||
}
|
||||
|
||||
Timer::~Timer(void)
|
||||
{
|
||||
delete impl_;
|
||||
state_ = Stopped;
|
||||
}
|
||||
|
||||
void Timer::reset(void)
|
||||
{
|
||||
state_ = Stopped;
|
||||
impl_->reset();
|
||||
}
|
||||
|
||||
void Timer::start(void)
|
||||
{
|
||||
state_ = Running;
|
||||
impl_->start();
|
||||
}
|
||||
|
||||
void Timer::stop(void)
|
||||
{
|
||||
impl_->stop();
|
||||
state_ = Stopped;
|
||||
}
|
||||
|
||||
void Timer::cont(void)
|
||||
{
|
||||
impl_->cont();
|
||||
state_ = Running;
|
||||
}
|
||||
|
||||
double Timer::seconds(void) const
|
||||
{
|
||||
return state_==Stopped ? impl_->seconds() : 0.0;
|
||||
}
|
||||
|
||||
std::string Timer::as_string(Timer::Format format)
|
||||
{
|
||||
if (state_ == Running)
|
||||
return "Running";
|
||||
return as_string(impl_->seconds(),format);
|
||||
}
|
||||
|
||||
std::string Timer::as_string(double seconds, Timer::Format format)
|
||||
{
|
||||
char string[32];
|
||||
|
||||
double fraction;
|
||||
double integer;
|
||||
unsigned long t;
|
||||
// double rest;
|
||||
short hour,min,sec;
|
||||
bool negative = false;
|
||||
|
||||
if ( seconds < 0 )
|
||||
{
|
||||
negative = true;
|
||||
seconds *= -1;
|
||||
}
|
||||
|
||||
fraction = modf(seconds,&integer);
|
||||
|
||||
t = (unsigned long)integer;
|
||||
|
||||
hour = short( t / 3600L );
|
||||
t %= 3600L;
|
||||
min = short( t / 60L );
|
||||
t %= 60L;
|
||||
sec = short( t );
|
||||
// rest = (double)t + fraction;
|
||||
|
||||
char *ptr = string;
|
||||
if (negative)
|
||||
*ptr++ = '-';
|
||||
|
||||
switch(format)
|
||||
{
|
||||
case Timer::Automatic:
|
||||
if (hour)
|
||||
ptr += sprintf(ptr,"%02dh:",hour);
|
||||
|
||||
if (min)
|
||||
ptr += sprintf(ptr,"%02dm:",min);
|
||||
else if (ptr>string && hour)
|
||||
ptr += sprintf(ptr,"00m:");
|
||||
|
||||
if (sec)
|
||||
ptr += sprintf(ptr,"%02d",sec);
|
||||
else if (ptr>string && min)
|
||||
ptr += sprintf(ptr,"00");
|
||||
|
||||
if (!hour && !min) // higher resolution necessary
|
||||
{
|
||||
if (ptr > string && sec)
|
||||
{
|
||||
sprintf(ptr,".%.3fs",fraction);
|
||||
ptr++;
|
||||
while(*(ptr+2))
|
||||
{
|
||||
*ptr = *(ptr+2);
|
||||
ptr++;
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
else if ( fraction * 1e2 > 0.1)
|
||||
sprintf(ptr,"%.3fcs",fraction*1.e2);
|
||||
else if ( fraction * 1e3 > 0.1)
|
||||
sprintf(ptr,"%.3fms",fraction*1.e3);
|
||||
else if ( fraction * 1e6 > 0.1)
|
||||
sprintf(ptr,"%.1f\xb5s",fraction*1.e6);
|
||||
else if ( fraction * 1e9 > 0.1)
|
||||
sprintf(ptr,"%.1fns",fraction*1.e9);
|
||||
else
|
||||
sprintf(ptr,"%.1fps",fraction*1.e12);
|
||||
} else // append a 's' for seconds!
|
||||
{
|
||||
ptr[0] = 's';
|
||||
ptr[1] = '\0';
|
||||
}
|
||||
break;
|
||||
case Timer::Long:
|
||||
ptr += sprintf(ptr,"%02dh:%02dm:%02d",hour,min,sec);
|
||||
sprintf(ptr,".%.12fs",fraction);
|
||||
ptr++;
|
||||
while(*(ptr+2))
|
||||
{
|
||||
*ptr = *(ptr+2);
|
||||
ptr++;
|
||||
}
|
||||
*ptr = '\0';
|
||||
break;
|
||||
case Timer::Hours:
|
||||
sprintf(ptr,"%02dh:%02dm:%02ds",hour,min,sec); break;
|
||||
case Timer::Minutes:
|
||||
ptr += sprintf(ptr,"%02dm:%02d", min, sec);
|
||||
sprintf(ptr,".%.2fs",fraction);
|
||||
ptr++;
|
||||
while(*(ptr+2))
|
||||
{
|
||||
*ptr = *(ptr+2);
|
||||
ptr++;
|
||||
}
|
||||
*ptr = '\0';
|
||||
break;
|
||||
case Timer::Seconds: sprintf(ptr,"%.3fs",seconds); break;
|
||||
case Timer::HSeconds: sprintf(ptr,"%.3fcs",seconds*1e2); break;
|
||||
case Timer::MSeconds: sprintf(ptr,"%.3fms",seconds*1e3); break;
|
||||
case Timer::MicroSeconds: sprintf(ptr,"%.1f\xb5s",seconds*1e6); break;
|
||||
case Timer::NanoSeconds: sprintf(ptr,"%.1fns",seconds*1e9); break;
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
} // END_NS_UTILS
|
||||
} // END_NS_OPENMESH
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif // DOXY_IGNORE_THIS
|
||||
// ============================================================================
|
||||
// end of file Timer.cc
|
||||
// ============================================================================
|
||||
|
||||
169
Tools/Utils/Timer.hh
Normal file
169
Tools/Utils/Timer.hh
Normal file
@@ -0,0 +1,169 @@
|
||||
// ============================================================================
|
||||
// $Id: Timer.hh,v 1.1.1.1 2006-10-25 16:14:15 habbecke Exp $
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef TIMER_HH
|
||||
#define TIMER_HH
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** \file Timer.hh
|
||||
A timer class
|
||||
*/
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
//
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#if defined(OM_CC_MIPS)
|
||||
# include <assert.h>
|
||||
#else
|
||||
# include <cassert>
|
||||
#endif
|
||||
|
||||
|
||||
// ------------------------------------------------------------- namespace ----
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Utils {
|
||||
|
||||
|
||||
// -------------------------------------------------------------- forwards ----
|
||||
|
||||
|
||||
class TimerImpl;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------- class ----
|
||||
|
||||
/** Timer class
|
||||
*/
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
|
||||
/// Formatting options for member Timer::as_string()
|
||||
enum Format {
|
||||
Automatic,
|
||||
Long,
|
||||
Hours,
|
||||
Minutes,
|
||||
Seconds,
|
||||
HSeconds,
|
||||
MSeconds,
|
||||
MicroSeconds,
|
||||
NanoSeconds
|
||||
};
|
||||
|
||||
Timer(void);
|
||||
~Timer(void);
|
||||
|
||||
/// Returns true if self is in a valid state!
|
||||
bool is_valid() const { return state_!=Invalid; }
|
||||
|
||||
bool is_stopped() const { return state_==Stopped; }
|
||||
|
||||
/// Reset the timer
|
||||
void reset(void);
|
||||
|
||||
/// Start measurement
|
||||
void start(void);
|
||||
|
||||
/// Stop measurement
|
||||
void stop(void);
|
||||
|
||||
/// Continue measurement
|
||||
void cont(void);
|
||||
|
||||
/// Give resolution of timer. Depends on the underlying measurement method.
|
||||
float resolution() const;
|
||||
|
||||
/// Returns measured time in seconds, if the timer is in state 'Stopped'
|
||||
double seconds(void) const;
|
||||
|
||||
/// Returns measured time in hundredth seconds, if the timer is in state 'Stopped'
|
||||
double hseconds(void) const { return seconds()*1e2; }
|
||||
|
||||
/// Returns measured time in milli seconds, if the timer is in state 'Stopped'
|
||||
double mseconds(void) const { return seconds()*1e3; }
|
||||
|
||||
/// Returns measured time in micro seconds, if the timer is in state 'Stopped'
|
||||
double useconds(void) const { return seconds()*1e6; }
|
||||
|
||||
/** Returns the measured time as a string. Use the format flags to specify
|
||||
a wanted resolution.
|
||||
*/
|
||||
std::string as_string(Format format = Automatic);
|
||||
|
||||
/** Returns a given measured time as a string. Use the format flags to
|
||||
specify a wanted resolution.
|
||||
*/
|
||||
static std::string as_string(double seconds, Format format = Automatic);
|
||||
|
||||
public:
|
||||
|
||||
//@{
|
||||
/// Compare timer values
|
||||
bool operator < (const Timer& t2) const
|
||||
{
|
||||
assert( is_stopped() && t2.is_stopped() );
|
||||
return (seconds() < t2.seconds());
|
||||
}
|
||||
|
||||
bool operator > (const Timer& t2) const
|
||||
{
|
||||
assert( is_stopped() && t2.is_stopped() );
|
||||
return (seconds() > t2.seconds());
|
||||
}
|
||||
|
||||
bool operator == (const Timer& t2) const
|
||||
{
|
||||
assert( is_stopped() && t2.is_stopped() );
|
||||
return (seconds() == t2.seconds());
|
||||
}
|
||||
|
||||
bool operator <= (const Timer& t2) const
|
||||
{
|
||||
assert( is_stopped() && t2.is_stopped() );
|
||||
return (seconds() <= t2.seconds());
|
||||
}
|
||||
|
||||
bool operator >=(const Timer& t2) const
|
||||
{
|
||||
assert( is_stopped() && t2.is_stopped() );
|
||||
return (seconds() >= t2.seconds());
|
||||
}
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
TimerImpl *impl_;
|
||||
|
||||
enum {
|
||||
Invalid = -1,
|
||||
Stopped = 0,
|
||||
Running = 1
|
||||
} state_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Write seconds to output stream.
|
||||
* Timer must be stopped before.
|
||||
* \relates Timer
|
||||
*/
|
||||
inline std::ostream& operator << (std::ostream& _o, const Timer& _t)
|
||||
{
|
||||
return (_o << _t.seconds());
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
} // END_NS_UTILS
|
||||
} // END_NS_OPENMESH
|
||||
// ============================================================================
|
||||
#endif
|
||||
// end of Timer.hh
|
||||
// ===========================================================================
|
||||
|
||||
183
Tools/Utils/conio.cc
Normal file
183
Tools/Utils/conio.cc
Normal file
@@ -0,0 +1,183 @@
|
||||
// ============================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Tools/Utils/conio.hh>
|
||||
|
||||
// ----------------------------------------------------------------- Win32 ----
|
||||
#ifdef WIN32
|
||||
|
||||
#include <conio.h>
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Utils {
|
||||
|
||||
int kbhit() { return ::kbhit(); }
|
||||
int getch() { return ::getch(); }
|
||||
int getche() { return ::getche(); }
|
||||
|
||||
} // Tools
|
||||
} // AS
|
||||
// ----------------------------------------------------------------- Other ----
|
||||
#else
|
||||
|
||||
// Based on code published by Floyd Davidson in a newsgroup.
|
||||
|
||||
#include <stdio.h> /* stdout, fflush() */
|
||||
#if !defined(POSIX_1003_1_2001)
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
#else
|
||||
# include <select.h> /* select() */
|
||||
#endif
|
||||
#include <termios.h> /* tcsetattr() */
|
||||
#include <sys/ioctl.h> /* ioctl() */
|
||||
#include <sys/time.h> /* struct timeval */
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace Utils {
|
||||
|
||||
#ifdef CTIME
|
||||
# undef CTIME
|
||||
#endif
|
||||
#define CTIME 1
|
||||
#define CMIN 1
|
||||
|
||||
|
||||
int kbhit(void)
|
||||
{
|
||||
int cnt = 0;
|
||||
int error;
|
||||
static struct termios Otty, Ntty;
|
||||
|
||||
tcgetattr(0, &Otty);
|
||||
Ntty = Otty;
|
||||
|
||||
Ntty.c_iflag = 0; /* input mode */
|
||||
Ntty.c_oflag = 0; /* output mode */
|
||||
Ntty.c_lflag &= ~ICANON; /* raw mode */
|
||||
Ntty.c_cc[VMIN] = CMIN; /* minimum chars to wait for */
|
||||
Ntty.c_cc[VTIME] = CTIME; /* minimum wait time */
|
||||
|
||||
if (0 == (error = tcsetattr(0, TCSANOW, &Ntty)))
|
||||
{
|
||||
struct timeval tv;
|
||||
error += ioctl(0, FIONREAD, &cnt);
|
||||
error += tcsetattr(0, TCSANOW, &Otty);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100; /* insert at least a minimal delay */
|
||||
select(1, NULL, NULL, NULL, &tv);
|
||||
}
|
||||
return (error == 0 ? cnt : -1 );
|
||||
}
|
||||
|
||||
|
||||
int getch(void)
|
||||
{
|
||||
char ch;
|
||||
int error;
|
||||
static struct termios Otty, Ntty;
|
||||
|
||||
fflush(stdout);
|
||||
tcgetattr(0, &Otty);
|
||||
Ntty = Otty;
|
||||
|
||||
Ntty.c_iflag = 0; // input mode
|
||||
Ntty.c_oflag = 0; // output mode
|
||||
Ntty.c_lflag &= ~ICANON; // line settings
|
||||
Ntty.c_lflag &= ~ECHO; // enable echo
|
||||
Ntty.c_cc[VMIN] = CMIN; // minimum chars to wait for
|
||||
Ntty.c_cc[VTIME] = CTIME; // minimum wait time
|
||||
|
||||
// Conditionals allow compiling with or without flushing pre-existing
|
||||
// existing buffered input before blocking.
|
||||
#if 1
|
||||
// use this to flush the input buffer before blocking for new input
|
||||
# define FLAG TCSAFLUSH
|
||||
#else
|
||||
// use this to return a char from the current input buffer, or block if
|
||||
// no input is waiting.
|
||||
# define FLAG TCSANOW
|
||||
#endif
|
||||
|
||||
if (0 == (error = tcsetattr(0, FLAG, &Ntty)))
|
||||
{
|
||||
error = read(0, &ch, 1 ); // get char from stdin
|
||||
error += tcsetattr(0, FLAG, &Otty); // restore old settings
|
||||
}
|
||||
return (error == 1 ? (int) ch : -1 );
|
||||
}
|
||||
|
||||
|
||||
int getche(void)
|
||||
{
|
||||
char ch;
|
||||
int error;
|
||||
static struct termios Otty, Ntty;
|
||||
|
||||
fflush(stdout);
|
||||
tcgetattr(0, &Otty);
|
||||
Ntty = Otty;
|
||||
|
||||
Ntty.c_iflag = 0; // input mode
|
||||
Ntty.c_oflag = 0; // output mode
|
||||
Ntty.c_lflag &= ~ICANON; // line settings
|
||||
Ntty.c_lflag |= ECHO; // enable echo
|
||||
Ntty.c_cc[VMIN] = CMIN; // minimum chars to wait for
|
||||
Ntty.c_cc[VTIME] = CTIME; // minimum wait time
|
||||
|
||||
// Conditionals allow compiling with or without flushing pre-existing
|
||||
// existing buffered input before blocking.
|
||||
#if 1
|
||||
// use this to flush the input buffer before blocking for new input
|
||||
# define FLAG TCSAFLUSH
|
||||
#else
|
||||
// use this to return a char from the current input buffer, or block if
|
||||
// no input is waiting.
|
||||
# define FLAG TCSANOW
|
||||
#endif
|
||||
|
||||
if (0 == (error = tcsetattr(0, FLAG, &Ntty))) {
|
||||
error = read(0, &ch, 1 ); // get char from stdin
|
||||
error += tcsetattr(0, FLAG, &Otty); // restore old settings
|
||||
}
|
||||
|
||||
return (error == 1 ? (int) ch : -1 );
|
||||
}
|
||||
|
||||
} // namespace Tools
|
||||
} // namespace AS
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif // System dependent parts
|
||||
// ============================================================================
|
||||
|
||||
//#define Test
|
||||
#if defined(Test)
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
char msg[] = "press key to continue...";
|
||||
char *ptr = msg, tmp;
|
||||
|
||||
while ( !OpenMesh::Utils::kbhit() )
|
||||
{
|
||||
tmp = *ptr;
|
||||
*ptr = islower(tmp) ? toupper(tmp) : tolower(tmp);
|
||||
printf("\r%s", msg); fflush(stdout);
|
||||
*ptr = (char)tmp;
|
||||
if (!*(++ptr))
|
||||
ptr = msg;
|
||||
usleep(20000);
|
||||
}
|
||||
|
||||
printf("\r%s.", msg); fflush(stdout);
|
||||
OpenMesh::Utils::getch();
|
||||
printf("\r%s..", msg); fflush(stdout);
|
||||
OpenMesh::Utils::getche();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // Test
|
||||
|
||||
// ============================================================================
|
||||
37
Tools/Utils/conio.hh
Normal file
37
Tools/Utils/conio.hh
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef OPENMESH_UTILS_CONIO_HH
|
||||
#define OPENMESH_UTILS_CONIO_HH
|
||||
// ----------------------------------------------------------------------------
|
||||
namespace OpenMesh {
|
||||
namespace Utils {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** Check if characters a pending in stdin.
|
||||
*
|
||||
* \return Number of characters available to read.
|
||||
*
|
||||
* \see getch(), getche()
|
||||
*/
|
||||
int kbhit(void);
|
||||
|
||||
|
||||
/** A blocking single character input from stdin
|
||||
*
|
||||
* \return Character, or -1 if an input error occurs.
|
||||
*
|
||||
* \see getche(), kbhit()
|
||||
*/
|
||||
int getch(void);
|
||||
|
||||
/** A blocking single character input from stdin with echo.
|
||||
*
|
||||
* \return Character, or -1 if an input error occurs.
|
||||
* \see getch(), kbhit()
|
||||
*/
|
||||
int getche(void);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
} // namespace Utils
|
||||
} // namespace OpenMesh
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif // OPENMESH_UTILS_CONIO_HH
|
||||
// ============================================================================
|
||||
116
Tools/Utils/getopt.c
Normal file
116
Tools/Utils/getopt.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "getopt.h"
|
||||
|
||||
int opterr = 1, /* if error message should be printed */
|
||||
optind = 1, /* index into parent argv vector */
|
||||
optopt, /* character checked for validity */
|
||||
optreset; /* reset getopt */
|
||||
char *optarg; /* argument associated with option */
|
||||
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG (int)':'
|
||||
#define EMSG ""
|
||||
|
||||
/*
|
||||
* getopt --
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt(int nargc, char * const *nargv, const char *ostr)
|
||||
{
|
||||
# define __progname nargv[0]
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
char *oli; /* option letter list index */
|
||||
|
||||
if (optreset || !*place) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
if (optind >= nargc || *(place = nargv[optind]) != '-') {
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
if (place[1] && *++place == '-') { /* found "--" */
|
||||
++optind;
|
||||
place = EMSG;
|
||||
return (-1);
|
||||
}
|
||||
} /* option letter okay? */
|
||||
if ((optopt = (int)*place++) == (int)':' ||
|
||||
!(oli = strchr(ostr, optopt))) {
|
||||
/*
|
||||
* if the user didn't specify '-' as an option,
|
||||
* assume it means -1.
|
||||
*/
|
||||
if (optopt == (int)'-')
|
||||
return (-1);
|
||||
if (!*place)
|
||||
++optind;
|
||||
if (opterr && *ostr != ':')
|
||||
(void)fprintf(stderr,
|
||||
"%s: illegal option -- %c\n", __progname, optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
if (*++oli != ':') { /* don't need argument */
|
||||
optarg = NULL;
|
||||
if (!*place)
|
||||
++optind;
|
||||
}
|
||||
else { /* need an argument */
|
||||
if (*place) /* no white space */
|
||||
optarg = place;
|
||||
else if (nargc <= ++optind) { /* no arg */
|
||||
place = EMSG;
|
||||
if (*ostr == ':')
|
||||
return (BADARG);
|
||||
if (opterr)
|
||||
(void)fprintf(stderr,
|
||||
"%s: option requires an argument -- %c\n",
|
||||
__progname, optopt);
|
||||
return (BADCH);
|
||||
}
|
||||
else /* white space */
|
||||
optarg = nargv[optind];
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return (optopt); /* dump back option letter */
|
||||
}
|
||||
|
||||
26
Tools/Utils/getopt.h
Normal file
26
Tools/Utils/getopt.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef _GETOPT_H_
|
||||
#define _GETOPT_H_
|
||||
|
||||
#include <OpenMesh/Core/System/compiler.hh>
|
||||
|
||||
#if defined(WIN32)
|
||||
#if defined(__cplusplus)
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern int opterr;
|
||||
extern int optind;
|
||||
extern int optopt;
|
||||
extern int optreset;
|
||||
extern char *optarg;
|
||||
|
||||
extern int getopt(int nargc, char * const *nargv, const char *ostr);
|
||||
|
||||
}
|
||||
|
||||
# endif
|
||||
#else
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H_ */
|
||||
18
Tools/VDPM/ACGMakefile
Normal file
18
Tools/VDPM/ACGMakefile
Normal file
@@ -0,0 +1,18 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
CXX_CFLAGS += -DQT_THREAD_SUPPORT
|
||||
|
||||
SUBDIRS = $(call find-subdirs)
|
||||
|
||||
PACKAGES := qt glut opengl x11 math
|
||||
|
||||
PROJ_LIBS = OpenMesh/Core
|
||||
|
||||
MODULES := cxxlib
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
102
Tools/VDPM/MeshTraits.hh
Normal file
102
Tools/VDPM/MeshTraits.hh
Normal file
@@ -0,0 +1,102 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS VDPMTraits
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef OPENMESH_VDPM_TRAITS_HH
|
||||
#define OPENMESH_VDPM_TRAITS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/Mesh/Traits.hh>
|
||||
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** \class MeshTraits MeshTraits.hh <OpenMesh/Tools/VDPM/MeshTraits.hh>
|
||||
|
||||
Mesh traits for View Dependent Progressive Meshes
|
||||
*/
|
||||
|
||||
struct MeshTraits : public DefaultTraits
|
||||
{
|
||||
VertexTraits
|
||||
{
|
||||
public:
|
||||
|
||||
VHierarchyNodeHandle vhierarchy_node_handle()
|
||||
{
|
||||
return node_handle_;
|
||||
}
|
||||
|
||||
void set_vhierarchy_node_handle(VHierarchyNodeHandle _node_handle)
|
||||
{
|
||||
node_handle_ = _node_handle;
|
||||
}
|
||||
|
||||
bool is_ancestor(const VHierarchyNodeIndex &_other)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
VHierarchyNodeHandle node_handle_;
|
||||
|
||||
};
|
||||
|
||||
VertexAttributes(OpenMesh::Attributes::Status |
|
||||
OpenMesh::Attributes::Normal);
|
||||
HalfedgeAttributes(OpenMesh::Attributes::PrevHalfedge);
|
||||
EdgeAttributes(OpenMesh::Attributes::Status);
|
||||
FaceAttributes(OpenMesh::Attributes::Status |
|
||||
OpenMesh::Attributes::Normal);
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_VDPM_TRAITS_HH defined
|
||||
//=============================================================================
|
||||
|
||||
72
Tools/VDPM/StreamingDef.hh
Normal file
72
Tools/VDPM/StreamingDef.hh
Normal file
@@ -0,0 +1,72 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef OPENMESH_VDPM_STREAMINGDEF_HH
|
||||
#define OPENMESH_VDPM_STREAMINGDEF_HH
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
#define VDPM_STREAMING_PORT 4096
|
||||
|
||||
#define DEBUG_COUT
|
||||
//#define QDATASTREAM
|
||||
|
||||
#ifdef DEBUG_COUT
|
||||
static bool debug_print_;
|
||||
static bool debug_print() { return debug_print_; }
|
||||
static void set_debug_print(bool flag) { debug_print_ = flag; }
|
||||
#endif
|
||||
|
||||
enum VDPMDownLinkStatus { kStarted, kFinished, kStartable };
|
||||
enum VDPMStreamingPhase { kBaseMesh, kVSplitHeader, kVSplits };
|
||||
enum VDPMClientMode { kStatic, kDynamic };
|
||||
enum VHierarchySearchMode { kBruteForce, kUseHashing };
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_VDPROGMESH_VDPMSTREAMINGDEF_HH defined
|
||||
//=============================================================================
|
||||
|
||||
|
||||
95
Tools/VDPM/VFront.cc
Normal file
95
Tools/VDPM/VFront.cc
Normal file
@@ -0,0 +1,95 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/VDPM/VFront.hh>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
VFront::VFront()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VFront::
|
||||
add(VHierarchyNodeHandle _node_handle)
|
||||
{
|
||||
front_location_[_node_handle.idx()] = front_.insert(front_.end(), _node_handle);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VFront::
|
||||
remove(VHierarchyNodeHandle _node_handle)
|
||||
{
|
||||
VHierarchyNodeHandleListIter node_it = front_location_[_node_handle.idx()];
|
||||
VHierarchyNodeHandleListIter next_it = front_.erase(node_it);
|
||||
front_location_[_node_handle.idx()] = front_.end();
|
||||
|
||||
if (front_it_ == node_it)
|
||||
front_it_ = next_it;
|
||||
}
|
||||
|
||||
bool
|
||||
VFront::
|
||||
is_active(VHierarchyNodeHandle _node_handle)
|
||||
{
|
||||
return (front_location_[_node_handle.idx()] != front_.end()) ? true : false;
|
||||
}
|
||||
|
||||
void
|
||||
VFront::
|
||||
init(VHierarchyNodeHandleContainer &_roots, unsigned int _n_details)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
front_location_.resize(_roots.size() + 2*_n_details);
|
||||
for (i=0; i<front_location_.size(); ++i)
|
||||
front_location_[i] = front_.end();
|
||||
|
||||
for (i=0; i<_roots.size(); ++i)
|
||||
add(_roots[i]);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
91
Tools/VDPM/VFront.hh
Normal file
91
Tools/VDPM/VFront.hh
Normal file
@@ -0,0 +1,91 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_VDPROGMESH_VFRONT_HH
|
||||
#define OPENMESH_VDPROGMESH_VFRONT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Tools/VDPM/VHierarchyNode.hh>
|
||||
#include <vector>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Active nodes in vertex hierarchy.
|
||||
\todo VFront documentation
|
||||
*/
|
||||
class VFront
|
||||
{
|
||||
private:
|
||||
|
||||
typedef VHierarchyNodeHandleList::iterator VHierarchyNodeHandleListIter;
|
||||
enum VHierarchyNodeStatus { kSplit, kActive, kCollapse };
|
||||
|
||||
VHierarchyNodeHandleList front_;
|
||||
VHierarchyNodeHandleListIter front_it_;
|
||||
std::vector<VHierarchyNodeHandleListIter> front_location_;
|
||||
|
||||
public:
|
||||
|
||||
VFront();
|
||||
|
||||
void clear() { front_.clear(); front_location_.clear(); }
|
||||
void begin() { front_it_ = front_.begin(); }
|
||||
bool end() { return (front_it_ == front_.end()) ? true : false; }
|
||||
void next() { ++front_it_; }
|
||||
int size() { return (int) front_.size(); }
|
||||
VHierarchyNodeHandle node_handle() { return *front_it_; }
|
||||
|
||||
void add(VHierarchyNodeHandle _node_handle);
|
||||
void remove(VHierarchyNodeHandle _node_handle);
|
||||
bool is_active(VHierarchyNodeHandle _node_handle);
|
||||
void init(VHierarchyNodeHandleContainer &_roots, unsigned int _n_details);
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_VDPROGMESH_VFRONT_HH defined
|
||||
//=============================================================================
|
||||
156
Tools/VDPM/VHierarchy.cc
Normal file
156
Tools/VDPM/VHierarchy.cc
Normal file
@@ -0,0 +1,156 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
VHierarchy::
|
||||
VHierarchy()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void
|
||||
VHierarchy::
|
||||
set_num_roots(unsigned int _n_roots)
|
||||
{
|
||||
n_roots_ = _n_roots;
|
||||
|
||||
tree_id_bits_ = 0;
|
||||
while (n_roots_ > ((unsigned int) 0x00000001 << tree_id_bits_))
|
||||
++tree_id_bits_;
|
||||
}
|
||||
|
||||
|
||||
VHierarchyNodeHandle
|
||||
VHierarchy::
|
||||
add_node()
|
||||
{
|
||||
return add_node(VHierarchyNode());
|
||||
}
|
||||
|
||||
VHierarchyNodeHandle
|
||||
VHierarchy::
|
||||
add_node(const VHierarchyNode &_node)
|
||||
{
|
||||
nodes_.push_back(_node);
|
||||
|
||||
return VHierarchyNodeHandle(nodes_.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VHierarchy::
|
||||
make_children(VHierarchyNodeHandle &_parent_handle)
|
||||
{
|
||||
VHierarchyNodeHandle lchild_handle = add_node();
|
||||
VHierarchyNodeHandle rchild_handle = add_node();
|
||||
|
||||
VHierarchyNode &parent = node(_parent_handle);
|
||||
VHierarchyNode &lchild = node(lchild_handle);
|
||||
VHierarchyNode &rchild = node(rchild_handle);
|
||||
|
||||
parent.set_children_handle(lchild_handle);
|
||||
lchild.set_parent_handle(_parent_handle);
|
||||
rchild.set_parent_handle(_parent_handle);
|
||||
|
||||
lchild.set_index(VHierarchyNodeIndex(parent.node_index().tree_id(tree_id_bits_), 2*parent.node_index().node_id(tree_id_bits_), tree_id_bits_));
|
||||
rchild.set_index(VHierarchyNodeIndex(parent.node_index().tree_id(tree_id_bits_), 2*parent.node_index().node_id(tree_id_bits_)+1, tree_id_bits_));
|
||||
}
|
||||
|
||||
VHierarchyNodeHandle
|
||||
VHierarchy::
|
||||
node_handle(VHierarchyNodeIndex _node_index)
|
||||
{
|
||||
if (_node_index.is_valid(tree_id_bits_) != true)
|
||||
return InvalidVHierarchyNodeHandle;
|
||||
|
||||
VHierarchyNodeHandle node_handle = root_handle(_node_index.tree_id(tree_id_bits_));
|
||||
unsigned int node_id = _node_index.node_id(tree_id_bits_);
|
||||
unsigned int flag = 0x80000000;
|
||||
|
||||
while (!(node_id & flag)) flag >>= 1;
|
||||
flag >>= 1;
|
||||
|
||||
while (flag > 0 && is_leaf_node(node_handle) != true)
|
||||
{
|
||||
if (node_id & flag) // 1: rchild
|
||||
{
|
||||
node_handle = rchild_handle(node_handle);
|
||||
}
|
||||
else // 0: lchild
|
||||
{
|
||||
node_handle = lchild_handle(node_handle);
|
||||
}
|
||||
flag >>= 1;
|
||||
}
|
||||
|
||||
return node_handle;
|
||||
}
|
||||
|
||||
bool
|
||||
VHierarchy::
|
||||
is_ancestor(VHierarchyNodeIndex _ancestor_index, VHierarchyNodeIndex _descendent_index)
|
||||
{
|
||||
if (_ancestor_index.tree_id(tree_id_bits_) != _descendent_index.tree_id(tree_id_bits_))
|
||||
return false;
|
||||
|
||||
unsigned int ancestor_node_id = _ancestor_index.node_id(tree_id_bits_);
|
||||
unsigned int descendent_node_id = _descendent_index.node_id(tree_id_bits_);
|
||||
|
||||
if (ancestor_node_id > descendent_node_id)
|
||||
return false;
|
||||
|
||||
while (descendent_node_id > 0)
|
||||
{
|
||||
if (ancestor_node_id == descendent_node_id)
|
||||
return true;
|
||||
descendent_node_id >>= 1; // descendent_node_id /= 2
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
170
Tools/VDPM/VHierarchy.hh
Normal file
170
Tools/VDPM/VHierarchy.hh
Normal file
@@ -0,0 +1,170 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_VDPROGMESH_VHIERARCHY_HH
|
||||
#define OPENMESH_VDPROGMESH_VHIERARCHY_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <vector>
|
||||
#include <OpenMesh/Tools/VDPM/VHierarchyNode.hh>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Keeps the vertex hierarchy build during analyzing a progressive mesh.
|
||||
*/
|
||||
class VHierarchy
|
||||
{
|
||||
public:
|
||||
|
||||
typedef unsigned int id_t; ///< Type for tree and node ids
|
||||
|
||||
private:
|
||||
|
||||
VHierarchyNodeContainer nodes_;
|
||||
unsigned int n_roots_;
|
||||
unsigned char tree_id_bits_; // node_id_bits_ = 32-tree_id_bits_;
|
||||
|
||||
public:
|
||||
|
||||
VHierarchy();
|
||||
|
||||
void clear() { nodes_.clear(); n_roots_ = 0; }
|
||||
unsigned char tree_id_bits() const { return tree_id_bits_; }
|
||||
unsigned int num_roots() const { return n_roots_; }
|
||||
unsigned int num_nodes() const { return nodes_.size(); }
|
||||
|
||||
VHierarchyNodeIndex generate_node_index(id_t _tree_id, id_t _node_id)
|
||||
{
|
||||
return VHierarchyNodeIndex(_tree_id, _node_id, tree_id_bits_);
|
||||
}
|
||||
|
||||
|
||||
void set_num_roots(unsigned int _n_roots);
|
||||
|
||||
VHierarchyNodeHandle root_handle(unsigned int i) const
|
||||
{
|
||||
return VHierarchyNodeHandle( (int)i );
|
||||
}
|
||||
|
||||
|
||||
const VHierarchyNode& node(VHierarchyNodeHandle _vhierarchynode_handle) const
|
||||
{
|
||||
return nodes_[_vhierarchynode_handle.idx()];
|
||||
}
|
||||
|
||||
|
||||
VHierarchyNode& node(VHierarchyNodeHandle _vhierarchynode_handle)
|
||||
{
|
||||
return nodes_[_vhierarchynode_handle.idx()];
|
||||
}
|
||||
|
||||
VHierarchyNodeHandle add_node();
|
||||
VHierarchyNodeHandle add_node(const VHierarchyNode &_node);
|
||||
|
||||
void make_children(VHierarchyNodeHandle &_parent_handle);
|
||||
|
||||
bool is_ancestor(VHierarchyNodeIndex _ancestor_index,
|
||||
VHierarchyNodeIndex _descendent_index);
|
||||
|
||||
bool is_leaf_node(VHierarchyNodeHandle _node_handle)
|
||||
{ return nodes_[_node_handle.idx()].is_leaf(); }
|
||||
|
||||
bool is_root_node(VHierarchyNodeHandle _node_handle)
|
||||
{ return nodes_[_node_handle.idx()].is_root(); }
|
||||
|
||||
|
||||
const OpenMesh::Vec3f& normal(VHierarchyNodeHandle _node_handle) const
|
||||
{
|
||||
return nodes_[_node_handle.idx()].normal();
|
||||
}
|
||||
|
||||
const VHierarchyNodeIndex&
|
||||
node_index(VHierarchyNodeHandle _node_handle) const
|
||||
{ return nodes_[_node_handle.idx()].node_index(); }
|
||||
|
||||
VHierarchyNodeIndex& node_index(VHierarchyNodeHandle _node_handle)
|
||||
{ return nodes_[_node_handle.idx()].node_index(); }
|
||||
|
||||
const VHierarchyNodeIndex&
|
||||
fund_lcut_index(VHierarchyNodeHandle _node_handle) const
|
||||
{ return nodes_[_node_handle.idx()].fund_lcut_index(); }
|
||||
|
||||
VHierarchyNodeIndex& fund_lcut_index(VHierarchyNodeHandle _node_handle)
|
||||
{ return nodes_[_node_handle.idx()].fund_lcut_index(); }
|
||||
|
||||
const VHierarchyNodeIndex&
|
||||
fund_rcut_index(VHierarchyNodeHandle _node_handle) const
|
||||
{ return nodes_[_node_handle.idx()].fund_rcut_index(); }
|
||||
|
||||
VHierarchyNodeIndex& fund_rcut_index(VHierarchyNodeHandle _node_handle)
|
||||
{ return nodes_[_node_handle.idx()].fund_rcut_index(); }
|
||||
|
||||
VertexHandle vertex_handle(VHierarchyNodeHandle _node_handle)
|
||||
{ return nodes_[_node_handle.idx()].vertex_handle(); }
|
||||
|
||||
VHierarchyNodeHandle parent_handle(VHierarchyNodeHandle _node_handle)
|
||||
{ return nodes_[_node_handle.idx()].parent_handle(); }
|
||||
|
||||
VHierarchyNodeHandle lchild_handle(VHierarchyNodeHandle _node_handle)
|
||||
{ return nodes_[_node_handle.idx()].lchild_handle(); }
|
||||
|
||||
VHierarchyNodeHandle rchild_handle(VHierarchyNodeHandle _node_handle)
|
||||
{ return nodes_[_node_handle.idx()].rchild_handle(); }
|
||||
|
||||
VHierarchyNodeHandle node_handle(VHierarchyNodeIndex _node_index);
|
||||
|
||||
private:
|
||||
|
||||
VHierarchyNodeHandle compute_dependency(VHierarchyNodeIndex index0,
|
||||
VHierarchyNodeIndex index1);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_VDPROGMESH_VHIERARCHY_HH defined
|
||||
//=============================================================================
|
||||
176
Tools/VDPM/VHierarchyNode.hh
Normal file
176
Tools/VDPM/VHierarchyNode.hh
Normal file
@@ -0,0 +1,176 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_VDPROGMESH_VHIERARCHYNODE_HH
|
||||
#define OPENMESH_VDPROGMESH_VHIERARCHYNODE_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <OpenMesh/Core/Geometry/VectorT.hh>
|
||||
#include <OpenMesh/Core/Mesh/Handles.hh>
|
||||
#include <OpenMesh/Tools/VDPM/VHierarchyNodeIndex.hh>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Handle for vertex hierarchy nodes
|
||||
*/
|
||||
struct VHierarchyNodeHandle : public BaseHandle
|
||||
{
|
||||
explicit VHierarchyNodeHandle(int _idx=-1) : BaseHandle(_idx) {}
|
||||
};
|
||||
|
||||
|
||||
/// Invalid handle
|
||||
static const VHierarchyNodeHandle InvalidVHierarchyNodeHandle;
|
||||
|
||||
|
||||
/** Vertex hierarchy node
|
||||
* \todo Complete documentation
|
||||
*/
|
||||
class VHierarchyNode
|
||||
{
|
||||
public:
|
||||
|
||||
VHierarchyNode() { }
|
||||
|
||||
/// Returns true, if node is root else false.
|
||||
bool is_root() const
|
||||
{ return (parent_handle_.is_valid() == false) ? true : false; }
|
||||
|
||||
/// Returns true, if node is leaf else false.
|
||||
bool is_leaf() const
|
||||
{ return (lchild_handle_.is_valid() == false) ? true : false; }
|
||||
|
||||
/// Returns parent handle.
|
||||
VHierarchyNodeHandle parent_handle() { return parent_handle_; }
|
||||
|
||||
/// Returns handle to left child.
|
||||
VHierarchyNodeHandle lchild_handle() { return lchild_handle_; }
|
||||
|
||||
/// Returns handle to right child.
|
||||
VHierarchyNodeHandle rchild_handle()
|
||||
{ return VHierarchyNodeHandle(lchild_handle_.idx()+1); }
|
||||
|
||||
void set_parent_handle(VHierarchyNodeHandle _parent_handle)
|
||||
{ parent_handle_ = _parent_handle; }
|
||||
|
||||
void set_children_handle(VHierarchyNodeHandle _lchild_handle)
|
||||
{ lchild_handle_ = _lchild_handle; }
|
||||
|
||||
VertexHandle vertex_handle() const { return vh_; }
|
||||
float radius() const { return radius_; }
|
||||
const OpenMesh::Vec3f& normal() const { return normal_; }
|
||||
float sin_square() const { return sin_square_; }
|
||||
float mue_square() const { return mue_square_; }
|
||||
float sigma_square() const { return sigma_square_; }
|
||||
|
||||
void set_vertex_handle(OpenMesh::VertexHandle _vh) { vh_ = _vh; }
|
||||
void set_radius(float _radius) { radius_ = _radius; }
|
||||
void set_normal(const OpenMesh::Vec3f &_normal) { normal_ = _normal; }
|
||||
|
||||
void set_sin_square(float _sin_square) { sin_square_ = _sin_square; }
|
||||
void set_mue_square(float _mue_square) { mue_square_ = _mue_square; }
|
||||
void set_sigma_square(float _sigma_square) { sigma_square_ = _sigma_square; }
|
||||
|
||||
void set_semi_angle(float _semi_angle)
|
||||
{ float f=sinf(_semi_angle); sin_square_ = f*f; }
|
||||
|
||||
void set_mue(float _mue) { mue_square_ = _mue * _mue; }
|
||||
void set_sigma(float _sigma) { sigma_square_ = _sigma * _sigma; }
|
||||
|
||||
const VHierarchyNodeIndex& node_index() const { return node_index_; }
|
||||
const VHierarchyNodeIndex& fund_lcut_index() const
|
||||
{ return fund_cut_node_index_[0]; }
|
||||
|
||||
const VHierarchyNodeIndex& fund_rcut_index() const
|
||||
{ return fund_cut_node_index_[1]; }
|
||||
|
||||
VHierarchyNodeIndex& node_index()
|
||||
{ return node_index_; }
|
||||
|
||||
VHierarchyNodeIndex& fund_lcut_index() { return fund_cut_node_index_[0]; }
|
||||
VHierarchyNodeIndex& fund_rcut_index() { return fund_cut_node_index_[1]; }
|
||||
|
||||
void set_index(const VHierarchyNodeIndex &_node_index)
|
||||
{ node_index_ = _node_index; }
|
||||
|
||||
void set_fund_lcut(const VHierarchyNodeIndex &_node_index)
|
||||
{ fund_cut_node_index_[0] = _node_index; }
|
||||
|
||||
void set_fund_rcut(const VHierarchyNodeIndex &_node_index)
|
||||
{ fund_cut_node_index_[1] = _node_index; }
|
||||
|
||||
private:
|
||||
VertexHandle vh_;
|
||||
float radius_;
|
||||
Vec3f normal_;
|
||||
float sin_square_;
|
||||
float mue_square_;
|
||||
float sigma_square_;
|
||||
|
||||
VHierarchyNodeHandle parent_handle_;
|
||||
VHierarchyNodeHandle lchild_handle_;
|
||||
|
||||
|
||||
VHierarchyNodeIndex node_index_;
|
||||
VHierarchyNodeIndex fund_cut_node_index_[2];
|
||||
};
|
||||
|
||||
/// Container for vertex hierarchy nodes
|
||||
typedef std::vector<VHierarchyNode> VHierarchyNodeContainer;
|
||||
|
||||
/// Container for vertex hierarchy node handles
|
||||
typedef std::vector<VHierarchyNodeHandle> VHierarchyNodeHandleContainer;
|
||||
|
||||
/// Container for vertex hierarchy node handles
|
||||
typedef std::list<VHierarchyNodeHandle> VHierarchyNodeHandleList;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namesapce VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_VDPROGMESH_VHIERARCHYNODE_HH defined
|
||||
//=============================================================================
|
||||
55
Tools/VDPM/VHierarchyNodeIndex.cc
Normal file
55
Tools/VDPM/VHierarchyNodeIndex.cc
Normal file
@@ -0,0 +1,55 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/VDPM/VHierarchyNodeIndex.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
const VHierarchyNodeIndex
|
||||
VHierarchyNodeIndex::InvalidIndex = VHierarchyNodeIndex();
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
|
||||
110
Tools/VDPM/VHierarchyNodeIndex.hh
Normal file
110
Tools/VDPM/VHierarchyNodeIndex.hh
Normal file
@@ -0,0 +1,110 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_VDPROGMESH_VHIERARCHYNODEINDEX_HH
|
||||
#define OPENMESH_VDPROGMESH_VHIERARCHYNODEINDEX_HH
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** Index of vertex hierarchy node
|
||||
*/
|
||||
|
||||
|
||||
class VHierarchyNodeIndex
|
||||
{
|
||||
private:
|
||||
unsigned int value_;
|
||||
|
||||
public:
|
||||
|
||||
static const VHierarchyNodeIndex InvalidIndex;
|
||||
|
||||
public:
|
||||
|
||||
VHierarchyNodeIndex()
|
||||
{ value_ = 0; }
|
||||
|
||||
VHierarchyNodeIndex(unsigned int _value)
|
||||
{ value_ = _value; }
|
||||
|
||||
VHierarchyNodeIndex(const VHierarchyNodeIndex &_other)
|
||||
{ value_ = _other.value_; }
|
||||
|
||||
VHierarchyNodeIndex(unsigned int _tree_id,
|
||||
unsigned int _node_id,
|
||||
unsigned short _tree_id_bits)
|
||||
{
|
||||
assert(_tree_id < ((unsigned int) 0x00000001 << _tree_id_bits));
|
||||
assert(_node_id < ((unsigned int) 0x00000001 << (32 - _tree_id_bits)));
|
||||
value_ = (_tree_id << (32 - _tree_id_bits)) | _node_id;
|
||||
}
|
||||
|
||||
bool is_valid(unsigned short _tree_id_bits) const
|
||||
{ return node_id(_tree_id_bits) != 0 ? true : false; }
|
||||
|
||||
unsigned int tree_id(unsigned short _tree_id_bits) const
|
||||
{ return value_ >> (32 - _tree_id_bits); }
|
||||
|
||||
unsigned int node_id(unsigned short _tree_id_bits) const
|
||||
{ return value_ & ((unsigned int) 0xFFFFFFFF >> _tree_id_bits); }
|
||||
|
||||
bool operator< (const VHierarchyNodeIndex &other) const
|
||||
{ return (value_ < other.value_) ? true : false; }
|
||||
|
||||
unsigned int value() const
|
||||
{ return value_; }
|
||||
};
|
||||
|
||||
|
||||
/// Container for vertex hierarchy node indices
|
||||
typedef std::vector<VHierarchyNodeIndex> VHierarchyNodeIndexContainer;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_VDPROGMESH_VHIERARCHYNODEINDEX_HH defined
|
||||
//=============================================================================
|
||||
188
Tools/VDPM/VHierarchyWindow.cc
Normal file
188
Tools/VDPM/VHierarchyWindow.cc
Normal file
@@ -0,0 +1,188 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/VDPM/VHierarchyWindow.hh>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <string.h>
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
VHierarchyWindow::
|
||||
VHierarchyWindow()
|
||||
{
|
||||
vhierarchy_ = NULL;
|
||||
buffer_ = NULL;
|
||||
|
||||
buffer_min_ = 0;
|
||||
buffer_max_ = 0;
|
||||
|
||||
window_min_ = 0;
|
||||
window_max_ = 0;
|
||||
current_pos_ = 0;
|
||||
|
||||
n_shift_ = 0;
|
||||
}
|
||||
|
||||
|
||||
VHierarchyWindow::
|
||||
VHierarchyWindow(VHierarchy &_vhierarchy)
|
||||
{
|
||||
vhierarchy_ = &_vhierarchy;
|
||||
buffer_ = NULL;
|
||||
}
|
||||
|
||||
|
||||
VHierarchyWindow::
|
||||
~VHierarchyWindow(void)
|
||||
{
|
||||
if (buffer_ != NULL)
|
||||
free(buffer_);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VHierarchyWindow::
|
||||
update_buffer(VHierarchyNodeHandle _node_handle)
|
||||
{
|
||||
if (underflow(_node_handle) != true && overflow(_node_handle) != true)
|
||||
return false;
|
||||
|
||||
// tightly update window_min_ & window_max_
|
||||
int none_zero_pos;
|
||||
for (none_zero_pos=buffer_size()-1; none_zero_pos >= 0; --none_zero_pos)
|
||||
{
|
||||
if (buffer_[none_zero_pos] != 0) break;
|
||||
}
|
||||
window_max_ = buffer_min_ + none_zero_pos + 1;
|
||||
for(none_zero_pos=0; none_zero_pos < buffer_size(); ++none_zero_pos)
|
||||
{
|
||||
if (buffer_[none_zero_pos] != 0) break;
|
||||
}
|
||||
window_min_ = buffer_min_ + none_zero_pos;
|
||||
|
||||
assert(window_min_ < window_max_);
|
||||
|
||||
while (underflow(_node_handle) == true) buffer_min_ /= 2;
|
||||
while (overflow(_node_handle) == true)
|
||||
{
|
||||
buffer_max_ *= 2;
|
||||
if (buffer_max_ > (int) vhierarchy_->num_nodes() / 8)
|
||||
buffer_max_ = (int) (1 + vhierarchy_->num_nodes() / 8);
|
||||
}
|
||||
|
||||
unsigned char *new_buffer = (unsigned char *) malloc(buffer_size());
|
||||
memset(new_buffer, 0, buffer_size());
|
||||
memcpy(&(new_buffer[window_min_-buffer_min_]),
|
||||
&(buffer_[none_zero_pos]),
|
||||
window_size());
|
||||
free(buffer_);
|
||||
buffer_ = new_buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VHierarchyWindow::init(VHierarchyNodeHandleContainer &_roots)
|
||||
{
|
||||
if (buffer_ != NULL)
|
||||
free(buffer_);
|
||||
|
||||
buffer_min_ = 0;
|
||||
buffer_max_ = _roots.size() / 8;
|
||||
if (_roots.size() % 8 > 0)
|
||||
++buffer_max_;
|
||||
|
||||
buffer_ = (unsigned char *) malloc(buffer_size());
|
||||
memset(buffer_, 0, buffer_size());
|
||||
|
||||
window_min_ = 0;
|
||||
window_max_= 0;
|
||||
current_pos_ = 0;
|
||||
n_shift_ = 0;
|
||||
|
||||
for (unsigned int i=0; i<_roots.size(); i++)
|
||||
{
|
||||
activate(VHierarchyNodeHandle((int) i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VHierarchyWindow::
|
||||
update_with_vsplit(VHierarchyNodeHandle _parent_handle)
|
||||
{
|
||||
VHierarchyNodeHandle
|
||||
lchild_handle = vhierarchy_->lchild_handle(_parent_handle),
|
||||
rchild_handle = vhierarchy_->rchild_handle(_parent_handle);
|
||||
|
||||
assert(is_active(_parent_handle) == true);
|
||||
assert(is_active(lchild_handle) != true);
|
||||
assert(is_active(rchild_handle) != true);
|
||||
|
||||
inactivate(_parent_handle);
|
||||
activate(rchild_handle);
|
||||
activate(lchild_handle);
|
||||
}
|
||||
|
||||
void
|
||||
VHierarchyWindow::
|
||||
update_with_ecol(VHierarchyNodeHandle _parent_handle)
|
||||
{
|
||||
VHierarchyNodeHandle
|
||||
lchild_handle = vhierarchy_->lchild_handle(_parent_handle),
|
||||
rchild_handle = vhierarchy_->rchild_handle(_parent_handle);
|
||||
|
||||
assert(is_active(_parent_handle) != true);
|
||||
assert(is_active(lchild_handle) == true);
|
||||
assert(is_active(rchild_handle) == true);
|
||||
|
||||
activate(_parent_handle);
|
||||
inactivate(rchild_handle);
|
||||
inactivate(lchild_handle);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
201
Tools/VDPM/VHierarchyWindow.hh
Normal file
201
Tools/VDPM/VHierarchyWindow.hh
Normal file
@@ -0,0 +1,201 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_VDPROGMESH_VHIERARCHYWINDOWS_HH
|
||||
#define OPENMESH_VDPROGMESH_VHIERARCHYWINDOWS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** \todo VHierarchyWindow documentation
|
||||
*/
|
||||
class VHierarchyWindow
|
||||
{
|
||||
private:
|
||||
|
||||
// reference of vertex hierarchy
|
||||
VHierarchy *vhierarchy_;
|
||||
|
||||
// bits buffer (byte units)
|
||||
unsigned char *buffer_;
|
||||
int buffer_min_;
|
||||
int buffer_max_;
|
||||
int current_pos_;
|
||||
|
||||
// window (byte units)
|
||||
int window_min_;
|
||||
int window_max_;
|
||||
|
||||
|
||||
// # of right shift (bit units)
|
||||
unsigned char n_shift_; // [0, 7]
|
||||
|
||||
unsigned char flag8(unsigned char n_shift) const
|
||||
{ return 0x80 >> n_shift; }
|
||||
|
||||
unsigned char flag8(VHierarchyNodeHandle _node_handle) const
|
||||
{
|
||||
assert(_node_handle.idx() >= 0);
|
||||
return 0x80 >> (unsigned int) (_node_handle.idx() % 8);
|
||||
}
|
||||
int byte_idx(VHierarchyNodeHandle _node_handle) const
|
||||
{
|
||||
assert(_node_handle.idx() >= 0);
|
||||
return _node_handle.idx() / 8;
|
||||
}
|
||||
int buffer_idx(VHierarchyNodeHandle _node_handle) const
|
||||
{ return byte_idx(_node_handle) - buffer_min_; }
|
||||
|
||||
bool before_window(VHierarchyNodeHandle _node_handle) const
|
||||
{ return (_node_handle.idx()/8 < window_min_) ? true : false; }
|
||||
|
||||
bool after_window(VHierarchyNodeHandle _node_handle) const
|
||||
{ return (_node_handle.idx()/8 < window_max_) ? false : true; }
|
||||
|
||||
bool underflow(VHierarchyNodeHandle _node_handle) const
|
||||
{ return (_node_handle.idx()/8 < buffer_min_) ? true : false; }
|
||||
|
||||
bool overflow(VHierarchyNodeHandle _node_handle) const
|
||||
{ return (_node_handle.idx()/8 < buffer_max_) ? false : true; }
|
||||
|
||||
bool update_buffer(VHierarchyNodeHandle _node_handle);
|
||||
|
||||
public:
|
||||
VHierarchyWindow();
|
||||
VHierarchyWindow(VHierarchy &_vhierarchy);
|
||||
~VHierarchyWindow(void);
|
||||
|
||||
void set_vertex_hierarchy(VHierarchy &_vhierarchy)
|
||||
{ vhierarchy_ = &_vhierarchy; }
|
||||
|
||||
void begin()
|
||||
{
|
||||
int new_window_min = window_min_;
|
||||
for (current_pos_=window_min_-buffer_min_;
|
||||
current_pos_ < window_size(); ++current_pos_)
|
||||
{
|
||||
if (buffer_[current_pos_] == 0)
|
||||
++new_window_min;
|
||||
else
|
||||
{
|
||||
n_shift_ = 0;
|
||||
while ((buffer_[current_pos_] & flag8(n_shift_)) == 0)
|
||||
++n_shift_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
window_min_ = new_window_min;
|
||||
}
|
||||
|
||||
void next()
|
||||
{
|
||||
++n_shift_;
|
||||
if (n_shift_ == 8)
|
||||
{
|
||||
n_shift_ = 0;
|
||||
++current_pos_;
|
||||
}
|
||||
|
||||
while (current_pos_ < window_max_-buffer_min_)
|
||||
{
|
||||
if (buffer_[current_pos_] != 0) // if the current byte has non-zero bits
|
||||
{
|
||||
while (n_shift_ != 8)
|
||||
{
|
||||
if ((buffer_[current_pos_] & flag8(n_shift_)) != 0)
|
||||
return; // find 1 bit in the current byte
|
||||
++n_shift_;
|
||||
}
|
||||
}
|
||||
n_shift_ = 0;
|
||||
++current_pos_;
|
||||
}
|
||||
}
|
||||
bool end() { return !(current_pos_ < window_max_-buffer_min_); }
|
||||
|
||||
int window_size() const { return window_max_ - window_min_; }
|
||||
int buffer_size() const { return buffer_max_ - buffer_min_; }
|
||||
|
||||
VHierarchyNodeHandle node_handle()
|
||||
{
|
||||
return VHierarchyNodeHandle(8*(buffer_min_+current_pos_) + (int)n_shift_);
|
||||
}
|
||||
|
||||
void activate(VHierarchyNodeHandle _node_handle)
|
||||
{
|
||||
update_buffer(_node_handle);
|
||||
buffer_[buffer_idx(_node_handle)] |= flag8(_node_handle);
|
||||
window_min_ = std::min(window_min_, byte_idx(_node_handle));
|
||||
window_max_ = std::max(window_max_, 1+byte_idx(_node_handle));
|
||||
}
|
||||
|
||||
|
||||
void inactivate(VHierarchyNodeHandle _node_handle)
|
||||
{
|
||||
if (is_active(_node_handle) != true) return;
|
||||
buffer_[buffer_idx(_node_handle)] ^= flag8(_node_handle);
|
||||
}
|
||||
|
||||
|
||||
bool is_active(VHierarchyNodeHandle _node_handle) const
|
||||
{
|
||||
if (before_window(_node_handle) == true ||
|
||||
after_window(_node_handle) == true)
|
||||
return false;
|
||||
return ((buffer_[buffer_idx(_node_handle)] & flag8(_node_handle)) > 0);
|
||||
}
|
||||
|
||||
void init(VHierarchyNodeHandleContainer &_roots);
|
||||
void update_with_vsplit(VHierarchyNodeHandle _parent_handle);
|
||||
void update_with_ecol(VHierarchyNodeHandle _parent_handle);
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_VDPROGMESH_VHIERARCHYWINDOWS_HH
|
||||
//=============================================================================
|
||||
|
||||
142
Tools/VDPM/ViewingParameters.cc
Normal file
142
Tools/VDPM/ViewingParameters.cc
Normal file
@@ -0,0 +1,142 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Tools/VDPM/ViewingParameters.hh>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
ViewingParameters::
|
||||
ViewingParameters()
|
||||
{
|
||||
fovy_ = 45.0f;
|
||||
aspect_ = 1.0f;
|
||||
tolerance_square_ = 0.001f;
|
||||
}
|
||||
|
||||
void
|
||||
ViewingParameters::
|
||||
update_viewing_configurations()
|
||||
{
|
||||
// |a11 a12 a13|-1 | a33a22-a32a23 -(a33a12-a32a13) a23a12-a22a13 |
|
||||
// |a21 a22 a23| = 1/DET*|-(a33a21-a31a23) a33a11-a31a13 -(a23a11-a21a13)|
|
||||
// |a31 a32 a33| | a32a21-a31a22 -(a32a11-a31a12) a22a11-a21a12 |
|
||||
// DET = a11(a33a22-a32a23)-a21(a33a12-a32a13)+a31(a23a12-a22a13)
|
||||
|
||||
float invdet;
|
||||
float a11, a12, a13, a21, a22, a23, a31, a32, a33;
|
||||
Vec3f inv_rot[3], trans;
|
||||
|
||||
a11 = (float) modelview_matrix_[0];
|
||||
a12 = (float) modelview_matrix_[4];
|
||||
a13 = (float) modelview_matrix_[8];
|
||||
trans[0] = (float) modelview_matrix_[12];
|
||||
|
||||
a21 = (float) modelview_matrix_[1];
|
||||
a22 = (float) modelview_matrix_[5];
|
||||
a23 = (float) modelview_matrix_[9];
|
||||
trans[1] = (float) modelview_matrix_[13];
|
||||
|
||||
a31 = (float) modelview_matrix_[2];
|
||||
a32 = (float) modelview_matrix_[6];
|
||||
a33 = (float) modelview_matrix_[10];
|
||||
trans[2] = (float) modelview_matrix_[14];
|
||||
|
||||
invdet=a11*(a33*a22-a32*a23) - a21*(a33*a12-a32*a13) + a31*(a23*a12-a22*a13);
|
||||
invdet= (float) 1.0/invdet;
|
||||
|
||||
(inv_rot[0])[0] = (a33*a22-a32*a23) * invdet;
|
||||
(inv_rot[0])[1] = -(a33*a12-a32*a13) * invdet;
|
||||
(inv_rot[0])[2] = (a23*a12-a22*a13) * invdet;
|
||||
(inv_rot[1])[0] = -(a33*a21-a31*a23) * invdet;
|
||||
(inv_rot[1])[1] = (a33*a11-a31*a13) * invdet;
|
||||
(inv_rot[1])[2] = -(a23*a11-a21*a13) * invdet;
|
||||
(inv_rot[2])[0] = (a32*a21-a31*a22) * invdet;
|
||||
(inv_rot[2])[1] = -(a32*a11-a31*a12) * invdet;
|
||||
(inv_rot[2])[2] = (a22*a11-a21*a12) * invdet;
|
||||
|
||||
eye_pos_ = - Vec3f(dot(inv_rot[0], trans),
|
||||
dot(inv_rot[1], trans),
|
||||
dot(inv_rot[2], trans));
|
||||
right_dir_ = Vec3f(a11, a12, a13);
|
||||
up_dir_ = Vec3f(a21, a22, a23);
|
||||
view_dir_ = - Vec3f(a31, a32, a33);
|
||||
|
||||
Vec3f normal[4];
|
||||
//float aspect = width() / height();
|
||||
float half_theta = fovy() * 0.5f;
|
||||
float half_phi = atanf(aspect() * tanf(half_theta));
|
||||
|
||||
float sin1 = sinf(half_theta);
|
||||
float cos1 = cosf(half_theta);
|
||||
float sin2 = sinf(half_phi);
|
||||
float cos2 = cosf(half_phi);
|
||||
|
||||
normal[0] = cos2 * right_dir_ + sin2 * view_dir_;
|
||||
normal[1] = -cos1 * up_dir_ - sin1 * view_dir_;
|
||||
normal[2] = -cos2 * right_dir_ + sin2 * view_dir_;
|
||||
normal[3] = cos1 * up_dir_ - sin1 * view_dir_;
|
||||
|
||||
for (int i=0; i<4; i++)
|
||||
frustum_plane_[i] = Plane3d(normal[i], eye_pos_);
|
||||
}
|
||||
|
||||
void
|
||||
ViewingParameters::
|
||||
PrintOut()
|
||||
{
|
||||
std::cout << " ModelView matrix: " << std::endl;
|
||||
std::cout << " |" << modelview_matrix_[0] << " " << modelview_matrix_[4] << " " << modelview_matrix_[8] << " " << modelview_matrix_[12] << "|" << std::endl;
|
||||
std::cout << " |" << modelview_matrix_[1] << " " << modelview_matrix_[5] << " " << modelview_matrix_[9] << " " << modelview_matrix_[13] << "|" << std::endl;
|
||||
std::cout << " |" << modelview_matrix_[2] << " " << modelview_matrix_[6] << " " << modelview_matrix_[10] << " " << modelview_matrix_[14] << "|" << std::endl;
|
||||
std::cout << " |" << modelview_matrix_[3] << " " << modelview_matrix_[7] << " " << modelview_matrix_[11] << " " << modelview_matrix_[15] << "|" << std::endl;
|
||||
std::cout << " Fovy: " << fovy_ << std::endl;
|
||||
std::cout << " Aspect: " << aspect_ << std::endl;
|
||||
std::cout << " Tolerance^2: " << tolerance_square_ << std::endl;
|
||||
std::cout << " Eye Pos: " << eye_pos_ << std::endl;
|
||||
std::cout << " Right dir: " << right_dir_ << std::endl;
|
||||
std::cout << " Up dir: " << up_dir_ << std::endl;
|
||||
std::cout << " View dir: " << view_dir_ << std::endl;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
124
Tools/VDPM/ViewingParameters.hh
Normal file
124
Tools/VDPM/ViewingParameters.hh
Normal file
@@ -0,0 +1,124 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2001-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. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_VDPROGMESH_VIEWINGPARAMETERS_HH
|
||||
#define OPENMESH_VDPROGMESH_VIEWINGPARAMETERS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/Geometry/VectorT.hh>
|
||||
#include <OpenMesh/Core/Geometry/Plane3d.hh>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace VDPM {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** \todo ViewerParameters documentation
|
||||
*/
|
||||
class ViewingParameters
|
||||
{
|
||||
private:
|
||||
double modelview_matrix_[16];
|
||||
float fovy_;
|
||||
float aspect_;
|
||||
float tolerance_square_;
|
||||
|
||||
Vec3f eye_pos_;
|
||||
Vec3f right_dir_;
|
||||
Vec3f up_dir_;
|
||||
Vec3f view_dir_;
|
||||
|
||||
Plane3d frustum_plane_[4];
|
||||
|
||||
public:
|
||||
|
||||
ViewingParameters();
|
||||
|
||||
void increase_tolerance() { tolerance_square_ *= 5.0f; }
|
||||
void decrease_tolerance() { tolerance_square_ /= 5.0f; }
|
||||
|
||||
float fovy() const { return fovy_; }
|
||||
float aspect() const { return aspect_; }
|
||||
float tolerance_square() const { return tolerance_square_; }
|
||||
|
||||
void set_fovy(float _fovy) { fovy_ = _fovy; }
|
||||
void set_aspect(float _aspect) { aspect_ = _aspect; }
|
||||
void set_tolerance_square(float _tolerance_square) { tolerance_square_ = _tolerance_square; }
|
||||
|
||||
const Vec3f& eye_pos() const { return eye_pos_; }
|
||||
const Vec3f& right_dir() const { return right_dir_; }
|
||||
const Vec3f& up_dir() const { return up_dir_; }
|
||||
const Vec3f& view_dir() const { return view_dir_; }
|
||||
Vec3f& eye_pos() { return eye_pos_; }
|
||||
Vec3f& right_dir() { return right_dir_; }
|
||||
Vec3f& up_dir() { return up_dir_; }
|
||||
Vec3f& view_dir() { return view_dir_; }
|
||||
|
||||
void frustum_planes( Plane3d _plane[4] )
|
||||
{
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
_plane[i] = frustum_plane_[i];
|
||||
}
|
||||
|
||||
void get_modelview_matrix(double _modelview_matrix[16])
|
||||
{
|
||||
for (unsigned int i=0; i<16; ++i)
|
||||
_modelview_matrix[i] = modelview_matrix_[i];
|
||||
}
|
||||
|
||||
void set_modelview_matrix(const double _modelview_matrix[16])
|
||||
{
|
||||
for (unsigned int i=0; i<16; ++i)
|
||||
modelview_matrix_[i] = _modelview_matrix[i];
|
||||
}
|
||||
|
||||
void update_viewing_configurations();
|
||||
|
||||
void PrintOut();
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace VDPM
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_VDPROGMESH_VIEWINGPARAMETERS_HH defined
|
||||
//=============================================================================
|
||||
|
||||
22
Tools/VDPM/xpm/fileopen.xpm
Normal file
22
Tools/VDPM/xpm/fileopen.xpm
Normal file
@@ -0,0 +1,22 @@
|
||||
/* XPM */
|
||||
static const char *fileopen[] = {
|
||||
" 16 13 5 1",
|
||||
". c #040404",
|
||||
"# c #808304",
|
||||
"a c None",
|
||||
"b c #f3f704",
|
||||
"c c #f3f7f3",
|
||||
"aaaaaaaaa...aaaa",
|
||||
"aaaaaaaa.aaa.a.a",
|
||||
"aaaaaaaaaaaaa..a",
|
||||
"a...aaaaaaaa...a",
|
||||
".bcb.......aaaaa",
|
||||
".cbcbcbcbc.aaaaa",
|
||||
".bcbcbcbcb.aaaaa",
|
||||
".cbcb...........",
|
||||
".bcb.#########.a",
|
||||
".cb.#########.aa",
|
||||
".b.#########.aaa",
|
||||
"..#########.aaaa",
|
||||
"...........aaaaa"
|
||||
};
|
||||
24
Tools/VDPM/xpm/fileprint.xpm
Normal file
24
Tools/VDPM/xpm/fileprint.xpm
Normal file
@@ -0,0 +1,24 @@
|
||||
/* XPM */
|
||||
static const char *fileprint[] = {
|
||||
" 16 14 6 1",
|
||||
". c #000000",
|
||||
"# c #848284",
|
||||
"a c #c6c3c6",
|
||||
"b c #ffff00",
|
||||
"c c #ffffff",
|
||||
"d c None",
|
||||
"ddddd.........dd",
|
||||
"dddd.cccccccc.dd",
|
||||
"dddd.c.....c.ddd",
|
||||
"ddd.cccccccc.ddd",
|
||||
"ddd.c.....c....d",
|
||||
"dd.cccccccc.a.a.",
|
||||
"d..........a.a..",
|
||||
".aaaaaaaaaa.a.a.",
|
||||
".............aa.",
|
||||
".aaaaaa###aa.a.d",
|
||||
".aaaaaabbbaa...d",
|
||||
".............a.d",
|
||||
"d.aaaaaaaaa.a.dd",
|
||||
"dd...........ddd"
|
||||
};
|
||||
22
Tools/VDPM/xpm/filesave.xpm
Normal file
22
Tools/VDPM/xpm/filesave.xpm
Normal file
@@ -0,0 +1,22 @@
|
||||
/* XPM */
|
||||
static const char *filesave[] = {
|
||||
" 14 14 4 1",
|
||||
". c #040404",
|
||||
"# c #808304",
|
||||
"a c #bfc2bf",
|
||||
"b c None",
|
||||
"..............",
|
||||
".#.aaaaaaaa.a.",
|
||||
".#.aaaaaaaa...",
|
||||
".#.aaaaaaaa.#.",
|
||||
".#.aaaaaaaa.#.",
|
||||
".#.aaaaaaaa.#.",
|
||||
".#.aaaaaaaa.#.",
|
||||
".##........##.",
|
||||
".############.",
|
||||
".##.........#.",
|
||||
".##......aa.#.",
|
||||
".##......aa.#.",
|
||||
".##......aa.#.",
|
||||
"b............."
|
||||
};
|
||||
Reference in New Issue
Block a user