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

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