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:
Jan Möbius
2009-02-06 13:37:46 +00:00
parent c3321ebdd9
commit 97f515985d
417 changed files with 76182 additions and 0 deletions

19
Tools/ACGMakefile Normal file
View 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
#==============================================================================

View 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
#==============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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)

View 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)

View 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

View 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
#==============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
View 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
//=============================================================================

View 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
View 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>

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
View 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
View 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
//=============================================================================

View 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

View 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
#==============================================================================

View 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
#==============================================================================

View 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
#==============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

File diff suppressed because it is too large Load Diff

View 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
//=============================================================================

View 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
//=============================================================================

View 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
#==============================================================================

View 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
#==============================================================================

File diff suppressed because it is too large Load Diff

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
View 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
View 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
View 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
//=============================================================================

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
//=============================================================================

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
//=============================================================================

View 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
View 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
View 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
View 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
View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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
//=============================================================================

View 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"
};

View 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"
};

View 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............."
};