First checkin for OpenMesh 2.0
git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@2 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
17
Tools/Subdivider/Adaptive/ACGMakefile
Normal file
17
Tools/Subdivider/Adaptive/ACGMakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS = $(call find-subdirs)
|
||||
|
||||
PACKAGES := qt glut opengl x11 math
|
||||
|
||||
PROJ_LIBS = OpenMesh/Core
|
||||
|
||||
MODULES := moc cxx
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
17
Tools/Subdivider/Adaptive/Composite/ACGMakefile
Normal file
17
Tools/Subdivider/Adaptive/Composite/ACGMakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
PACKAGES := math
|
||||
|
||||
PROJ_LIBS = OpenMesh/Core
|
||||
|
||||
MODULES := cxx
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
307
Tools/Subdivider/Adaptive/Composite/CompositeT.cc
Normal file
307
Tools/Subdivider/Adaptive/Composite/CompositeT.cc
Normal file
@@ -0,0 +1,307 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file Adaptive/Composite/CompositeT.cc
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS CompositeT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_CC
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Core/System/omstream.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh>
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Adaptive { // BEGIN_NS_UNIFORM
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template<class M>
|
||||
bool
|
||||
CompositeT<M> ::
|
||||
initialize( void )
|
||||
{
|
||||
typename Mesh::VertexIter v_it;
|
||||
typename Mesh::FaceIter f_it;
|
||||
typename Mesh::EdgeIter e_it;
|
||||
const typename Mesh::Point zero_point(0.0, 0.0, 0.0);
|
||||
|
||||
// ---------------------------------------- Init Vertices
|
||||
for (v_it = mesh_.vertices_begin(); v_it != mesh_.vertices_end(); ++v_it)
|
||||
{
|
||||
mesh_.data(v_it).set_state(0);
|
||||
mesh_.data(v_it).set_final();
|
||||
mesh_.data(v_it).set_position(0, mesh_.point(v_it.handle()));
|
||||
}
|
||||
|
||||
// ---------------------------------------- Init Faces
|
||||
for (f_it = mesh_.faces_begin(); f_it != mesh_.faces_end(); ++f_it)
|
||||
{
|
||||
mesh_.data(f_it).set_state(0);
|
||||
mesh_.data(f_it).set_final();
|
||||
mesh_.data(f_it).set_position(0, zero_point);
|
||||
}
|
||||
|
||||
// ---------------------------------------- Init Edges
|
||||
for (e_it = mesh_.edges_begin(); e_it != mesh_.edges_end(); ++e_it)
|
||||
{
|
||||
mesh_.data(e_it).set_state(0);
|
||||
mesh_.data(e_it).set_final();
|
||||
mesh_.data(e_it).set_position(0, zero_point);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------- Init Rules
|
||||
|
||||
int n_subdiv_rules_ = 0;
|
||||
|
||||
|
||||
// look for subdivision rule(s)
|
||||
for (size_t i=0; i < n_rules(); ++i) {
|
||||
|
||||
if (rule_sequence_[i]->type()[0] == 'T' ||
|
||||
rule_sequence_[i]->type()[0] == 't')
|
||||
{
|
||||
++n_subdiv_rules_;
|
||||
subdiv_rule_ = rule_sequence_[i];
|
||||
subdiv_type_ = rule_sequence_[i]->subdiv_type();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check for correct number of subdivision rules
|
||||
assert(n_subdiv_rules_ == 1);
|
||||
|
||||
if (n_subdiv_rules_ != 1)
|
||||
{
|
||||
std::cerr << "Error! More than one subdivision rules not allowed!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for subdivision type
|
||||
assert(subdiv_type_ == 3 || subdiv_type_ == 4);
|
||||
|
||||
if (subdiv_type_ != 3 && subdiv_type_ != 4)
|
||||
{
|
||||
::omerr() << "Error! Unknown subdivision type in sequence!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set pointer to last rule
|
||||
// first_rule_ = rule_sequence_.front();
|
||||
// last_rule_ = rule_sequence_.back(); //[n_rules() - 1];
|
||||
|
||||
// set numbers and previous rule
|
||||
for (size_t i = 0; i < n_rules(); ++i)
|
||||
{
|
||||
rule_sequence_[i]->set_subdiv_type(subdiv_type_);
|
||||
rule_sequence_[i]->set_n_rules(n_rules());
|
||||
rule_sequence_[i]->set_number(i);
|
||||
rule_sequence_[i]->set_prev_rule(rule_sequence_[(i+n_rules()-1)%n_rules()]);
|
||||
rule_sequence_[i]->set_subdiv_rule(subdiv_rule_);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
#define MOBJ mesh_.deref
|
||||
#define TVH to_vertex_handle
|
||||
#define HEH halfedge_handle
|
||||
#define NHEH next_halfedge_handle
|
||||
#define PHEH prev_halfedge_handle
|
||||
#define OHEH opposite_halfedge_handle
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<class M>
|
||||
void CompositeT<M>::refine(typename Mesh::FaceHandle& _fh)
|
||||
{
|
||||
std::vector<typename Mesh::HalfedgeHandle> hh_vector;
|
||||
|
||||
// -------------------- calculate new level for faces and vertices
|
||||
int new_face_level =
|
||||
t_rule()->number() + 1 +
|
||||
((int)floor((float)(mesh_.data(_fh).state() - t_rule()->number() - 1)/n_rules()) + 1) * n_rules();
|
||||
|
||||
int new_vertex_level =
|
||||
new_face_level + l_rule()->number() - t_rule()->number();
|
||||
|
||||
// -------------------- store old vertices
|
||||
// !!! only triangle meshes supported!
|
||||
typename Mesh::VertexHandle vh[3];
|
||||
|
||||
vh[0] = mesh_.TVH(mesh_.HEH(_fh));
|
||||
vh[1] = mesh_.TVH(mesh_.NHEH(mesh_.HEH(_fh)));
|
||||
vh[2] = mesh_.TVH(mesh_.PHEH(mesh_.HEH(_fh)));
|
||||
|
||||
// save handles to incoming halfedges for getting the new vertices
|
||||
// after subdivision (1-4 split)
|
||||
if (subdiv_type_ == 4)
|
||||
{
|
||||
hh_vector.clear();
|
||||
|
||||
// green face
|
||||
if (mesh_.data(_fh).final())
|
||||
{
|
||||
typename Mesh::FaceHalfedgeIter fh_it(mesh_.fh_iter(_fh));
|
||||
|
||||
for (; fh_it; ++fh_it)
|
||||
{
|
||||
hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(fh_it.handle())));
|
||||
}
|
||||
}
|
||||
|
||||
// red face
|
||||
else
|
||||
{
|
||||
|
||||
typename Mesh::HalfedgeHandle red_hh(mesh_.data(_fh).red_halfedge());
|
||||
|
||||
hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(mesh_.NHEH(red_hh))));
|
||||
hh_vector.push_back(mesh_.PHEH(mesh_.OHEH(mesh_.PHEH(mesh_.OHEH(red_hh)))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -------------------- Average rule before topo rule?
|
||||
if (t_rule()->number() > 0)
|
||||
t_rule()->prev_rule()->raise(_fh, new_face_level-1);
|
||||
|
||||
// -------------------- Apply topological operator first
|
||||
t_rule()->raise(_fh, new_face_level);
|
||||
|
||||
#if 0 // original code
|
||||
assert(MOBJ(_fh).state() >=
|
||||
subdiv_rule_->number()+1+(int) (MOBJ(_fh).state()/n_rules())*n_rules());
|
||||
#else // improved code (use % operation and avoid floating point division)
|
||||
assert( mesh_.data(_fh).state() >= ( t_rule()->number()+1+generation(_fh) ) );
|
||||
#endif
|
||||
|
||||
// raise new vertices to final levels
|
||||
if (subdiv_type_ == 3)
|
||||
{
|
||||
typename Mesh::VertexHandle new_vh(mesh_.TVH(mesh_.NHEH(mesh_.HEH(_fh))));
|
||||
|
||||
// raise new vertex to final level
|
||||
l_rule()->raise(new_vh, new_vertex_level);
|
||||
}
|
||||
|
||||
if (subdiv_type_ == 4)
|
||||
{
|
||||
typename Mesh::HalfedgeHandle hh;
|
||||
typename Mesh::VertexHandle new_vh;
|
||||
|
||||
while (!hh_vector.empty()) {
|
||||
|
||||
hh = hh_vector.back();
|
||||
hh_vector.pop_back();
|
||||
|
||||
// get new vertex
|
||||
new_vh = mesh_.TVH(mesh_.NHEH(hh));
|
||||
|
||||
// raise new vertex to final level
|
||||
l_rule()->raise(new_vh, new_vertex_level);
|
||||
}
|
||||
}
|
||||
|
||||
// raise old vertices to final position
|
||||
l_rule()->raise(vh[0], new_vertex_level);
|
||||
l_rule()->raise(vh[1], new_vertex_level);
|
||||
l_rule()->raise(vh[2], new_vertex_level);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<class M>
|
||||
void CompositeT<M>::refine(typename Mesh::VertexHandle& _vh)
|
||||
{
|
||||
// calculate next final level for vertex
|
||||
int new_vertex_state = generation(_vh) + l_rule()->number() + 1;
|
||||
|
||||
assert( new_vertex_state == mesh_.data(_vh).state()+1 );
|
||||
|
||||
// raise vertex to final position
|
||||
l_rule()->raise(_vh, new_vertex_state);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class M>
|
||||
std::string CompositeT<M>::rules_as_string(const std::string& _sep) const
|
||||
{
|
||||
std::string seq;
|
||||
typename RuleSequence::const_iterator it = rule_sequence_.begin();
|
||||
|
||||
if ( it != rule_sequence_.end() )
|
||||
{
|
||||
seq = (*it)->type();
|
||||
for (++it; it != rule_sequence_.end(); ++it )
|
||||
{
|
||||
seq += _sep;
|
||||
seq += (*it)->type();
|
||||
}
|
||||
}
|
||||
return seq;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
#undef MOBJ
|
||||
#undef TVH
|
||||
#undef HEH
|
||||
#undef NHEH
|
||||
#undef PHEH
|
||||
#undef OHEH
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
298
Tools/Subdivider/Adaptive/Composite/CompositeT.hh
Normal file
298
Tools/Subdivider/Adaptive/Composite/CompositeT.hh
Normal file
@@ -0,0 +1,298 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file Adaptive/Composite/CompositeT.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS CompositeT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_HH
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh>
|
||||
// --------------------
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_SUBDIVIDER
|
||||
namespace Adaptive { // BEGIN_NS_ADAPTIVE
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
template <typename R> struct RuleHandleT;
|
||||
template <typename M> class RuleInterfaceT;
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Adaptive Composite Subdivision framework.
|
||||
*
|
||||
* The adaptive composite subdivision framework is based on the work
|
||||
* done by P. Oswald and P. Schroeder. This framework elevates the
|
||||
* uniform case of the composite scheme to the adaptive
|
||||
* setting.
|
||||
*
|
||||
* For details on the composite scheme refer to
|
||||
* - <a
|
||||
* href="http://cm.bell-labs.com/who/poswald/sqrt3.pdf">P. Oswald,
|
||||
* P. Schroeder "Composite primal/dual sqrt(3)-subdivision schemes",
|
||||
* CAGD 20, 3, 2003, 135--164</a>
|
||||
*
|
||||
* For details on the transition from uniform to adaptive composite
|
||||
* subdivision please refer to
|
||||
* - <a
|
||||
* href="http://www.eg.org/EG/DL/PE/OPENSG03/04sovakar.pdf>A. von Studnitz,
|
||||
* A. Sovakar, L. Kobbelt "API Design for Adaptive Subdivision
|
||||
* Schemes" OpenSG Symposium 2003</a>
|
||||
*
|
||||
* In the composite scheme a subdivision operator is created by
|
||||
* combining smaller "atomic" rules. Depending on the selection and
|
||||
* ordering of the operator many known subdivision schemes can be
|
||||
* created.
|
||||
*
|
||||
* Every rule inherits from RuleInterfaceT and is represented out of
|
||||
* the subdivider object by a RuleHandleT (as usual within
|
||||
* %OpenMesh). You can add rules using the CompositeT::add()
|
||||
* functions. The correct order of adding the rules is very
|
||||
* important, and furthermore not all rules get along with each other
|
||||
* very well. (Please read the given literature, especially the
|
||||
* paper by Oswald and Schr<68>der.)
|
||||
*
|
||||
* To use a composite subdivider first define a rule sequence
|
||||
* describing the order of execution of the rules. In the order the
|
||||
* rules habe been added they will be executed. E.g. the rules given
|
||||
* in operator notation have to added from right to left.
|
||||
*
|
||||
* After the rule sequence has been defined the subdivider has to be
|
||||
* intialized using CompositeT::initialize(). If everything went well,
|
||||
* use CompositeT::refine() to subdivide locally a face or vertex.
|
||||
*
|
||||
* \note Not all (topological) operators have been implemented!
|
||||
* \note Only triangle meshes are supported.
|
||||
* \note The rule sequence must begin with a topological operator.
|
||||
*
|
||||
* \see RuleInterfaceT, RuleHandleT
|
||||
*
|
||||
*/
|
||||
template <typename M> class CompositeT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef RuleInterfaceT<M> Rule;
|
||||
typedef M Mesh;
|
||||
typedef std::vector<Rule*> RuleSequence;
|
||||
|
||||
typedef typename M::VertexHandle VH;
|
||||
typedef typename M::FaceHandle FH;
|
||||
typedef typename M::EdgeHandle EH;
|
||||
typedef typename M::HalfedgeHandle HH;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
CompositeT(Mesh& _mesh)
|
||||
: subdiv_type_(0),
|
||||
subdiv_rule_(NULL), /*first_rule_(NULL), last_rule_(NULL),*/ mesh_(_mesh)
|
||||
{ }
|
||||
|
||||
///
|
||||
virtual ~CompositeT()
|
||||
{ cleanup(); }
|
||||
|
||||
|
||||
/// Reset \c self to state after the default constructor except of
|
||||
/// the mesh.
|
||||
void cleanup(void)
|
||||
{
|
||||
subdiv_type_ = 0;
|
||||
subdiv_rule_ = NULL;
|
||||
|
||||
std::for_each(rule_sequence_.begin(),
|
||||
rule_sequence_.end(), DeleteRule() );
|
||||
rule_sequence_.clear();
|
||||
}
|
||||
|
||||
|
||||
/// Initialize faces, edges, vertices, and rules
|
||||
bool initialize(void);
|
||||
|
||||
|
||||
/// Refine one face.
|
||||
void refine(typename Mesh::FaceHandle& _fh);
|
||||
|
||||
|
||||
/// Raise one vertex to next final level.
|
||||
void refine(typename Mesh::VertexHandle& _vh);
|
||||
|
||||
|
||||
/// Return subdivision split type (3 for 1-to-3 split, 4 for 1-to-4 split).
|
||||
int subdiv_type() { return subdiv_type_; }
|
||||
|
||||
|
||||
// Return subdivision rule.
|
||||
const Rule& subdiv_rule() const { return *subdiv_rule_; }
|
||||
|
||||
public:
|
||||
|
||||
/// \name Managing composite rules
|
||||
//*@
|
||||
|
||||
/** Add new rule to rule sequence by passing the type of the wanted
|
||||
* rule as template argument to the method.
|
||||
* \return Valid handle on success. Else it is invalid.
|
||||
*/
|
||||
template < typename R >
|
||||
RuleHandleT<R> add()
|
||||
{
|
||||
size_t idx = rule_sequence_.size();
|
||||
rule_sequence_.push_back( new R( mesh_ ) );
|
||||
return RuleHandleT<R>( (idx < rule_sequence_.size()) ? idx : -1 );
|
||||
}
|
||||
|
||||
/** Add new rule to rule sequence by passing an appropriate handle
|
||||
* to the method.
|
||||
* \return Valid handle on success. Else it is invalid.
|
||||
*/
|
||||
template < typename R >
|
||||
RuleHandleT<R>& add( RuleHandleT<R>& _rh )
|
||||
{
|
||||
return _rh = add< R >();
|
||||
}
|
||||
|
||||
/** Get rule in the rule sequence by a handle.
|
||||
*
|
||||
* \return The wanted rule if the handle is valid. The return value
|
||||
* is undefined if the handle is invalid!
|
||||
*/
|
||||
template < typename R >
|
||||
typename RuleHandleT<R>::Rule& rule( const RuleHandleT<R>& _rh )
|
||||
{
|
||||
typedef typename RuleHandleT<R>::Rule rule_t;
|
||||
assert( _rh.is_valid() );
|
||||
return *dynamic_cast<rule_t*>(rule_sequence_[ _rh.idx() ]);
|
||||
}
|
||||
|
||||
|
||||
/** Get rule (interface) by index
|
||||
*
|
||||
* \return The wanted rule if the handle is valid. The return value
|
||||
* is undefined if the handle is invalid!
|
||||
*/
|
||||
RuleInterfaceT<M>& rule( size_t _idx )
|
||||
{
|
||||
assert( _idx < n_rules() );
|
||||
return *rule_sequence_[ _idx ];
|
||||
}
|
||||
|
||||
/// Number of rules in the rule sequence
|
||||
size_t n_rules() const { return rule_sequence_.size(); }
|
||||
|
||||
/// Return the sequence as string
|
||||
std::string rules_as_string(const std::string& _sep= " * ") const;
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
/// The rule sequence
|
||||
const RuleSequence& rules() const { return rule_sequence_; }
|
||||
|
||||
protected: // helper
|
||||
|
||||
// get current generation from state
|
||||
state_t generation(state_t _s) { return _s-(_s % n_rules()); }
|
||||
state_t generation( VH _vh ) { return generation(mesh_.data(_vh).state()); }
|
||||
state_t generation( EH _eh ) { return generation(mesh_.data(_eh).state()); }
|
||||
state_t generation( FH _fh ) { return generation(mesh_.data(_fh).state()); }
|
||||
|
||||
private:
|
||||
|
||||
// short cuts
|
||||
Rule* t_rule() { return subdiv_rule_; }
|
||||
Rule* f_rule() { return rule_sequence_.front(); }
|
||||
Rule* l_rule() { return rule_sequence_.back(); }
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
RuleSequence rule_sequence_;
|
||||
|
||||
// Split type
|
||||
int subdiv_type_;
|
||||
|
||||
Rule *subdiv_rule_;
|
||||
// Rule *first_rule_;
|
||||
// Rule *last_rule_;
|
||||
|
||||
//
|
||||
Mesh &mesh_;
|
||||
|
||||
private: // helper
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
struct DeleteRule { void operator()( Rule* _r ) { delete _r; } };
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
CompositeT( const CompositeT& );
|
||||
CompositeT& operator = ( const CompositeT );
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_CC)
|
||||
# define OPENMESH_SUBDIVIDER_TEMPLATES
|
||||
# include "CompositeT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITET_HH defined
|
||||
//=============================================================================
|
||||
247
Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh
Normal file
247
Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh
Normal file
@@ -0,0 +1,247 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file Subdivider/Adaptive/Composite/CompositeTraits.hh
|
||||
Mesh traits for adaptive composite subdivider.
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS Traits
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITETRAITS_HH
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITETRAITS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <map>
|
||||
#include <OpenMesh/Core/Mesh/Traits.hh>
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Adaptive { // BEGIN_NS_UNIFORM
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Adaptive Composite Subdivision framework.
|
||||
*/
|
||||
|
||||
// typedef unsigned short state_t;
|
||||
// const state_t mask_final = 1 << ((sizeof(state_t)*8)-1);
|
||||
// const state_t mask_state = ~mask_final;
|
||||
|
||||
/** Mesh traits for adaptive composite subdivision
|
||||
*/
|
||||
struct CompositeTraits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
typedef int state_t; ///< External representation for intermediate state
|
||||
typedef bool final_t; ///< External representation for final flag
|
||||
|
||||
|
||||
/// Storage type for intermediate states and the final flag of a mesh entity.
|
||||
struct State
|
||||
{
|
||||
int state : 31;
|
||||
unsigned final : 1;
|
||||
};
|
||||
|
||||
// ---------------------------------------- attributes
|
||||
|
||||
// add face normals
|
||||
FaceAttributes( OpenMesh::Attributes::Normal );
|
||||
|
||||
// add vertex normals
|
||||
VertexAttributes( OpenMesh::Attributes::Normal );
|
||||
|
||||
// add previous halfedge handle
|
||||
HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );
|
||||
|
||||
// ---------------------------------------- items
|
||||
|
||||
FaceTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef typename Refs::HalfedgeHandle HalfedgeHandle;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
HalfedgeHandle red_halfedge_;
|
||||
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
// face state
|
||||
state_t state() const { return state_t(state_.state); }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
// face not final if divided (loop) or edge not flipped (sqrt(3))
|
||||
final_t final() const { return final_t(state_.final); }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// halfedge of dividing edge (red-green triangulation)
|
||||
const HalfedgeHandle& red_halfedge() const { return red_halfedge_; }
|
||||
void set_red_halfedge(const HalfedgeHandle& _h) { red_halfedge_ = _h; }
|
||||
|
||||
// position of face, depending on generation _i.
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
const Point position(const int& _i) {
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
return pos_map_[_i];
|
||||
else {
|
||||
|
||||
if (_i <= 0) {
|
||||
return Point(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class FaceTraits
|
||||
|
||||
|
||||
EdgeTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Refs::Scalar Scalar;
|
||||
|
||||
// Scalar weight_;
|
||||
|
||||
// state of edge
|
||||
state_t state() const { return state_t(state_.state); }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
// edge not final if dividing face (Loop) or edge not flipped (SQRT(3))
|
||||
final_t final() const { return final_t(state_.final); }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// position of edge, depending on generation _i.
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
|
||||
const Point position(const int& _i) {
|
||||
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
return pos_map_[_i];
|
||||
else
|
||||
{
|
||||
if (_i <= 0)
|
||||
{
|
||||
const Point zero_point(0.0, 0.0, 0.0);
|
||||
return zero_point;
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class EdgeTraits
|
||||
|
||||
|
||||
VertexTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
// state of vertex
|
||||
state_t state() const { return state_.state; }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
|
||||
// usually not needed by loop or sqrt(3)
|
||||
final_t final() const { return state_.final; }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// position of vertex, depending on generation _i. (not for display)
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
const Point position(const int& _i) {
|
||||
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
|
||||
return pos_map_[_i];
|
||||
|
||||
else {
|
||||
|
||||
if (_i <= 0) {
|
||||
|
||||
const Point zero_point(0.0, 0.0, 0.0);
|
||||
return zero_point;
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class VertexTraits
|
||||
}; // end class CompositeTraits
|
||||
|
||||
|
||||
// export items to namespace to maintain compatibility
|
||||
typedef CompositeTraits::state_t state_t;
|
||||
typedef CompositeTraits::final_t final_t;
|
||||
typedef CompositeTraits::State State;
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_ADAPTIVE_COMPOSITETRAITS_HH defined
|
||||
//=============================================================================
|
||||
389
Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh
Normal file
389
Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh
Normal file
@@ -0,0 +1,389 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS RuleInterfaceT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <string>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh>
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_SUBDIVIDER
|
||||
namespace Adaptive { // BEGIN_NS_ADAPTIVE
|
||||
|
||||
|
||||
//== FORWARDS =================================================================
|
||||
|
||||
template <typename M> class CompositeT;
|
||||
template <typename M> class RuleInterfaceT;
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** Handle template for adaptive composite subdividion rules
|
||||
* \internal
|
||||
*
|
||||
* Use typed handle of a rule, e.g. Tvv3<MyMesh>::Handle.
|
||||
*/
|
||||
template < typename R >
|
||||
struct RuleHandleT : public BaseHandle
|
||||
{
|
||||
explicit RuleHandleT(int _idx=-1) : BaseHandle(_idx) {}
|
||||
typedef R Rule;
|
||||
|
||||
operator bool() const { return is_valid(); }
|
||||
|
||||
};
|
||||
|
||||
/** Defines the method type() (RuleInterfaceT::type()) and the
|
||||
* typedefs Self and Handle.
|
||||
*/
|
||||
#define COMPOSITE_RULE( classname, mesh_type ) \
|
||||
protected:\
|
||||
friend class CompositeT<mesh_type>; \
|
||||
public: \
|
||||
const char *type() const { return #classname; } \
|
||||
typedef classname<mesh_type> Self; \
|
||||
typedef RuleHandleT< Self > Handle
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Base class for adaptive composite subdivision rules
|
||||
* \see class CompositeT
|
||||
*/
|
||||
template <typename M> class RuleInterfaceT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef M Mesh;
|
||||
typedef RuleInterfaceT<M> Self;
|
||||
typedef RuleHandleT< Self > Rule;
|
||||
|
||||
typedef typename M::Scalar scalar_t;
|
||||
|
||||
protected:
|
||||
|
||||
/// Default constructor
|
||||
RuleInterfaceT(Mesh& _mesh) : mesh_(_mesh) {};
|
||||
|
||||
public:
|
||||
|
||||
/// Destructor
|
||||
virtual ~RuleInterfaceT() {};
|
||||
|
||||
|
||||
/// Returns the name of the rule.
|
||||
/// Use define COMPOSITE_RULE to overload this function in a derived class.
|
||||
virtual const char *type() const = 0;
|
||||
|
||||
public:
|
||||
|
||||
/// \name Raise item
|
||||
//@{
|
||||
/// Raise item to target state \c _target_state.
|
||||
virtual void raise(typename M::FaceHandle& _fh, state_t _target_state)
|
||||
{
|
||||
if (mesh_.data(_fh).state() < _target_state) {
|
||||
update(_fh, _target_state);
|
||||
mesh_.data(_fh).inc_state();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void raise(typename M::EdgeHandle& _eh, state_t _target_state)
|
||||
{
|
||||
if (mesh_.data(_eh).state() < _target_state) {
|
||||
update(_eh, _target_state);
|
||||
mesh_.data(_eh).inc_state();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void raise(typename M::VertexHandle& _vh, state_t _target_state)
|
||||
{
|
||||
if (mesh_.data(_vh).state() < _target_state) {
|
||||
update(_vh, _target_state);
|
||||
mesh_.data(_vh).inc_state();
|
||||
}
|
||||
}
|
||||
//@}
|
||||
|
||||
void update(typename M::FaceHandle& _fh, state_t _target_state)
|
||||
{
|
||||
typename M::FaceHandle opp_fh;
|
||||
|
||||
while (mesh_.data(_fh).state() < _target_state - 1) {
|
||||
prev_rule()->raise(_fh, _target_state - 1);
|
||||
}
|
||||
|
||||
// Don't use unflipped / unfinal faces!!!
|
||||
if (subdiv_type() == 3) {
|
||||
|
||||
if (mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh))).is_valid()) {
|
||||
|
||||
while (!mesh_.data(_fh).final()) {
|
||||
|
||||
opp_fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh)));
|
||||
|
||||
assert (mesh_.data(_fh).state() >=
|
||||
mesh_.data(opp_fh).state());
|
||||
|
||||
// different states: raise other face
|
||||
if (mesh_.data(_fh).state() > mesh_.data(opp_fh).state()){
|
||||
|
||||
// raise opposite face
|
||||
prev_rule()->raise(opp_fh, _target_state - 1);
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
// equal states
|
||||
|
||||
// flip edge
|
||||
// typename M::EdgeHandle eh(mesh_.edge_handle(mesh_.halfedge_handle(_fh)));
|
||||
|
||||
// if (mesh_.is_flip_ok(eh)) {
|
||||
|
||||
// std::cout << "Flipping Edge...\n";
|
||||
|
||||
// mesh_.flip(eh);
|
||||
|
||||
// mesh_.data(_fh).set_final();
|
||||
// mesh_.data(opp_fh).set_final();
|
||||
// }
|
||||
|
||||
// else {
|
||||
|
||||
// std::cout << "Flip not okay.\n";
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
// mesh_.data(_fh).set_final();
|
||||
}
|
||||
|
||||
// std::cout << "Raising Face to Level "
|
||||
// << _target_state
|
||||
// << " with "
|
||||
// << type()
|
||||
// << ".\n";
|
||||
|
||||
}
|
||||
|
||||
assert( subdiv_type() != 4 ||
|
||||
mesh_.data(_fh).final() ||
|
||||
_target_state%n_rules() == (subdiv_rule()->number() + 1)%n_rules() );
|
||||
|
||||
typename M::FaceEdgeIter fe_it;
|
||||
typename M::FaceVertexIter fv_it;
|
||||
typename M::EdgeHandle eh;
|
||||
typename M::VertexHandle vh;
|
||||
|
||||
std::vector<typename M::FaceHandle> face_vector;
|
||||
face_vector.clear();
|
||||
|
||||
if (_target_state > 1) {
|
||||
|
||||
for (fe_it = mesh_.fe_iter(_fh); fe_it; ++fe_it) {
|
||||
|
||||
eh = fe_it.handle();
|
||||
prev_rule()->raise(eh, _target_state - 1);
|
||||
}
|
||||
|
||||
for (fv_it = mesh_.fv_iter(_fh); fv_it; ++fv_it) {
|
||||
|
||||
vh = fv_it.handle();
|
||||
prev_rule()->raise(vh, _target_state - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void update(typename M::EdgeHandle& _eh, state_t _target_state)
|
||||
{
|
||||
state_t state(mesh_.data(_eh).state());
|
||||
|
||||
// raise edge to correct state
|
||||
if (state + 1 < _target_state && _target_state > 0) {
|
||||
|
||||
prev_rule()->raise(_eh, _target_state - 1);
|
||||
}
|
||||
|
||||
typename M::VertexHandle vh;
|
||||
typename M::FaceHandle fh;
|
||||
|
||||
if (_target_state > 1)
|
||||
{
|
||||
vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 0));
|
||||
prev_rule()->raise(vh, _target_state - 1);
|
||||
|
||||
vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 1));
|
||||
prev_rule()->raise(vh, _target_state - 1);
|
||||
|
||||
fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 0));
|
||||
if (fh.is_valid())
|
||||
prev_rule()->raise(fh, _target_state - 1);
|
||||
|
||||
fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 1));
|
||||
if (fh.is_valid())
|
||||
prev_rule()->raise(fh, _target_state - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void update(typename M::VertexHandle& _vh, state_t _target_state) {
|
||||
|
||||
state_t state(mesh_.data(_vh).state());
|
||||
|
||||
// raise vertex to correct state
|
||||
if (state + 1 < _target_state)
|
||||
{
|
||||
prev_rule()->raise(_vh, _target_state - 1);
|
||||
}
|
||||
|
||||
std::vector<typename M::HalfedgeHandle> halfedge_vector;
|
||||
halfedge_vector.clear();
|
||||
|
||||
typename M::VertexOHalfedgeIter voh_it;
|
||||
typename M::EdgeHandle eh;
|
||||
typename M::FaceHandle fh;
|
||||
|
||||
if (_target_state > 1)
|
||||
{
|
||||
|
||||
for (voh_it = mesh_.voh_iter(_vh); voh_it; ++voh_it) {
|
||||
halfedge_vector.push_back(voh_it.handle());
|
||||
}
|
||||
|
||||
while ( !halfedge_vector.empty() ) {
|
||||
eh = mesh_.edge_handle(halfedge_vector.back());
|
||||
halfedge_vector.pop_back();
|
||||
|
||||
prev_rule()->raise(eh, _target_state - 1);
|
||||
}
|
||||
|
||||
for (voh_it = mesh_.voh_iter(_vh); voh_it; ++voh_it) {
|
||||
halfedge_vector.push_back(voh_it.handle());
|
||||
}
|
||||
|
||||
while ( !halfedge_vector.empty() ) {
|
||||
fh = mesh_.face_handle(halfedge_vector.back());
|
||||
halfedge_vector.pop_back();
|
||||
|
||||
if (fh.is_valid())
|
||||
prev_rule()->raise(fh, _target_state - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/// Type of split operation, if it is a topological operator
|
||||
int subdiv_type() const { return subdiv_type_; }
|
||||
|
||||
|
||||
/// Position in rule sequence
|
||||
int number() const { return number_; }
|
||||
|
||||
/// \name Parameterization of rule
|
||||
//@{
|
||||
|
||||
/// Set coefficient - ignored by non-parameterized rules.
|
||||
virtual void set_coeff( scalar_t _coeff ) { coeff_ = _coeff; }
|
||||
|
||||
/// Get coefficient - ignored by non-parameterized rules.
|
||||
scalar_t coeff() const { return coeff_; }
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
void set_prev_rule(Self*& _p) { prev_rule_ = _p; }
|
||||
Self* prev_rule() { return prev_rule_; }
|
||||
|
||||
void set_subdiv_rule(Self*& _n) { subdiv_rule_ = _n; }
|
||||
Self* subdiv_rule() { return subdiv_rule_; }
|
||||
|
||||
void set_number(int _n) { number_ = _n; }
|
||||
|
||||
void set_n_rules(int _n) { n_rules_ = _n; }
|
||||
int n_rules() { return n_rules_; }
|
||||
|
||||
void set_subdiv_type(int _n)
|
||||
{ assert(_n == 3 || _n == 4); subdiv_type_ = _n; }
|
||||
|
||||
friend class CompositeT<M>;
|
||||
|
||||
protected:
|
||||
|
||||
Mesh& mesh_;
|
||||
|
||||
private:
|
||||
|
||||
Self* prev_rule_;
|
||||
Self* subdiv_rule_;
|
||||
|
||||
int subdiv_type_;
|
||||
int number_;
|
||||
int n_rules_;
|
||||
|
||||
scalar_t coeff_;
|
||||
|
||||
private: // Noncopyable
|
||||
|
||||
RuleInterfaceT(const RuleInterfaceT&);
|
||||
RuleInterfaceT& operator=(const RuleInterfaceT&);
|
||||
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH defined
|
||||
//=============================================================================
|
||||
|
||||
2015
Tools/Subdivider/Adaptive/Composite/RulesT.cc
Normal file
2015
Tools/Subdivider/Adaptive/Composite/RulesT.cc
Normal file
File diff suppressed because it is too large
Load Diff
525
Tools/Subdivider/Adaptive/Composite/RulesT.hh
Normal file
525
Tools/Subdivider/Adaptive/Composite/RulesT.hh
Normal file
@@ -0,0 +1,525 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file RulesT.hh
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Composite Subdivision and Averaging Rules
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_RULEST_HH
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_RULEST_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.hh>
|
||||
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh>
|
||||
// -------------------- STL
|
||||
#include <vector>
|
||||
|
||||
|
||||
#if defined(OM_CC_MIPS) // avoid warnings
|
||||
# define MIPS_WARN_WA( Item ) \
|
||||
void raise(typename M:: ## Item ## Handle &_h, state_t _target_state ) \
|
||||
{ Inherited::raise(_h, _target_state); }
|
||||
#else
|
||||
# define MIPS_WARN_WA( Item )
|
||||
#endif
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_SUBDIVIDER
|
||||
namespace Adaptive { // BEGIN_NS_ADAPTIVE
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Adaptive Composite Subdivision framework.
|
||||
*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/** Topological composite rule Tvv,3 doing a 1-3 split of a face.
|
||||
*/
|
||||
template <class M> class Tvv3 : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( Tvv3, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
Tvv3(M& _mesh) : Inherited(_mesh) { Base::set_subdiv_type(3); };
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Topological composite rule Tvv,4 doing a 1-4 split of a face
|
||||
*/
|
||||
template <class M> class Tvv4 : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( Tvv4, M );
|
||||
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
public:
|
||||
typedef typename M::HalfedgeHandle HEH;
|
||||
typedef typename M::VertexHandle VH;
|
||||
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
Tvv4(M& _mesh) : Inherited(_mesh) { Base::set_subdiv_type(4); };
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
|
||||
private:
|
||||
|
||||
void split_edge(HEH& _hh, VH& _vh, state_t _target_state);
|
||||
void check_edge(const typename M::HalfedgeHandle& _hh,
|
||||
state_t _target_state);
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VF
|
||||
*/
|
||||
template <class M> class VF : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VF, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VF(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
MIPS_WARN_WA(Edge);
|
||||
MIPS_WARN_WA(Vertex);
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule FF
|
||||
*/
|
||||
template <class M> class FF : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( FF, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
FF(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
MIPS_WARN_WA(Edge ); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule FFc
|
||||
*/
|
||||
template <class M> class FFc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( FFc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
FFc(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
MIPS_WARN_WA(Edge ); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule FV
|
||||
*/
|
||||
template <class M> class FV : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( FV, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
FV(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule FVc
|
||||
*/
|
||||
template <class M> class FVc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( FVc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
FVc(M& _mesh) : Inherited(_mesh) { init_coeffs(50); }
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
|
||||
static void init_coeffs(size_t _max_valence);
|
||||
static const std::vector<double>& coeffs() { return coeffs_; }
|
||||
|
||||
double coeff( size_t _valence )
|
||||
{
|
||||
assert(_valence < coeffs_.size());
|
||||
return coeffs_[_valence];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static std::vector<double> coeffs_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VV
|
||||
*/
|
||||
template <class M> class VV : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VV, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VV(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VVc
|
||||
*/
|
||||
template <class M> class VVc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VVc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VVc(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VE
|
||||
*/
|
||||
template <class M> class VE : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VE, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VE(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VdE
|
||||
*/
|
||||
template <class M> class VdE : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VdE, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VdE(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule VdEc
|
||||
*/
|
||||
template <class M> class VdEc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( VdEc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
VdEc(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule EV
|
||||
*/
|
||||
template <class M> class EV : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( EV, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
EV(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule EVc
|
||||
*/
|
||||
template <class M> class EVc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( EVc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
EVc(M& _mesh) : Inherited(_mesh) { init_coeffs(50); }
|
||||
|
||||
void raise(typename M::VertexHandle& _vh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face); // avoid warning
|
||||
MIPS_WARN_WA(Edge); // avoid warning
|
||||
|
||||
static void init_coeffs(size_t _max_valence);
|
||||
static const std::vector<double>& coeffs() { return coeffs_; }
|
||||
|
||||
double coeff( size_t _valence )
|
||||
{
|
||||
assert(_valence < coeffs_.size());
|
||||
return coeffs_[_valence];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static std::vector<double> coeffs_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule EF
|
||||
*/
|
||||
template <class M> class EF : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( EF, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
EF(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::FaceHandle& _fh, state_t _target_state);
|
||||
MIPS_WARN_WA(Edge ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule FE
|
||||
*/
|
||||
template <class M> class FE : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( FE, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
FE(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule EdE
|
||||
*/
|
||||
template <class M> class EdE : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( EdE, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
EdE(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/** Composite rule EdEc
|
||||
*/
|
||||
template <class M> class EdEc : public RuleInterfaceT<M>
|
||||
{
|
||||
COMPOSITE_RULE( EdEc, M );
|
||||
private:
|
||||
typedef RuleInterfaceT<M> Base;
|
||||
|
||||
public:
|
||||
typedef RuleInterfaceT<M> Inherited;
|
||||
|
||||
EdEc(M& _mesh) : Inherited(_mesh) {}
|
||||
|
||||
void raise(typename M::EdgeHandle& _eh, state_t _target_state);
|
||||
MIPS_WARN_WA(Face ); // avoid warning
|
||||
MIPS_WARN_WA(Vertex); // avoid warning
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#undef MIPS_WARN_WA
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_SUBDIVIDER_ADAPTIVE_RULEST_CC)
|
||||
# define OPENMESH_SUBDIVIDER_TEMPLATES
|
||||
# include "RulesT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_ADAPTIVE_RULEST_HH defined
|
||||
//=============================================================================
|
||||
|
||||
237
Tools/Subdivider/Adaptive/Composite/Traits.hh
Normal file
237
Tools/Subdivider/Adaptive/Composite/Traits.hh
Normal file
@@ -0,0 +1,237 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// OpenMesh
|
||||
// Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen
|
||||
// www.openmesh.org
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// License
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, version 2.1.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Revision: 1802 $
|
||||
// $Date: 2008-05-19 11:55:07 +0200 (Mo, 19. Mai 2008) $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/** \file Traits.hh
|
||||
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS Traits
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_TRAITS_HH
|
||||
#define OPENMESH_SUBDIVIDER_ADAPTIVE_TRAITS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <map>
|
||||
#include <OpenMesh/Core/Mesh/Types/TriMesh_ArrayKernelT.hh>
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Subdivider { // BEGIN_NS_DECIMATER
|
||||
namespace Adaptive { // BEGIN_NS_UNIFORM
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** Adaptive Composite Subdivision framework.
|
||||
*/
|
||||
|
||||
// typedef unsigned short state_t;
|
||||
// const state_t mask_final = 1 << ((sizeof(state_t)*8)-1);
|
||||
// const state_t mask_state = ~mask_final;
|
||||
|
||||
typedef int state_t;
|
||||
typedef bool final_t;
|
||||
|
||||
struct State
|
||||
{
|
||||
int state : 31;
|
||||
unsigned final : 1;
|
||||
};
|
||||
|
||||
struct Traits : public OpenMesh::DefaultTraits
|
||||
{
|
||||
|
||||
// add face normals
|
||||
FaceAttributes( OpenMesh::Attributes::Normal );
|
||||
|
||||
// add vertex normals
|
||||
VertexAttributes( OpenMesh::Attributes::Normal );
|
||||
|
||||
// add previous halfedge handle
|
||||
HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );
|
||||
|
||||
FaceTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef typename Refs::HalfedgeHandle HalfedgeHandle;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
HalfedgeHandle red_halfedge_;
|
||||
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
// face state
|
||||
state_t state() const { return state_t(state_.state); }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
// face not final if divided (loop) or edge not flipped (sqrt(3))
|
||||
final_t final() const { return final_t(state_.final); }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// halfedge of dividing edge (red-green triangulation)
|
||||
const HalfedgeHandle& red_halfedge() const { return red_halfedge_; }
|
||||
void set_red_halfedge(const HalfedgeHandle& _h) { red_halfedge_ = _h; }
|
||||
|
||||
// position of face, depending on generation _i.
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
const Point position(const int& _i) {
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
return pos_map_[_i];
|
||||
else {
|
||||
|
||||
if (_i <= 0) {
|
||||
const Point zero_point(0.0, 0.0, 0.0);
|
||||
return zero_point;
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class FaceTraits
|
||||
|
||||
|
||||
EdgeTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Refs::Scalar Scalar;
|
||||
|
||||
// Scalar weight_;
|
||||
|
||||
// state of edge
|
||||
state_t state() const { return state_t(state_.state); }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
// edge not final if dividing face (Loop) or edge not flipped (SQRT(3))
|
||||
final_t final() const { return final_t(state_.final); }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// position of edge, depending on generation _i.
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
const Point position(const int& _i) {
|
||||
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
{
|
||||
return pos_map_[_i];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_i <= 0)
|
||||
{
|
||||
const Point zero_point(0.0, 0.0, 0.0);
|
||||
return zero_point;
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class EdgeTraits
|
||||
|
||||
|
||||
VertexTraits
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Refs::Point Point;
|
||||
typedef std::map<state_t, Point> PositionHistory;
|
||||
|
||||
State state_;
|
||||
|
||||
PositionHistory pos_map_;
|
||||
|
||||
public:
|
||||
|
||||
// state of vertex
|
||||
state_t state() const { return state_.state; }
|
||||
void set_state(const state_t _s) { state_.state = _s; }
|
||||
void inc_state() { ++state_.state; }
|
||||
|
||||
|
||||
// usually not needed by loop or sqrt(3)
|
||||
final_t final() const { return state_.final; }
|
||||
void set_final() { state_.final = true; }
|
||||
void set_not_final() { state_.final = false; }
|
||||
|
||||
// position of vertex, depending on generation _i. (not for display)
|
||||
void set_position(const int& _i, const Point& _p) { pos_map_[_i] = _p; }
|
||||
const Point position(const int& _i) {
|
||||
|
||||
if (pos_map_.find(_i) != pos_map_.end())
|
||||
|
||||
return pos_map_[_i];
|
||||
|
||||
else {
|
||||
|
||||
if (_i <= 0) {
|
||||
|
||||
const Point zero_point(0.0, 0.0, 0.0);
|
||||
return zero_point;
|
||||
}
|
||||
|
||||
return position(_i - 1);
|
||||
}
|
||||
}
|
||||
}; // end class VertexTraits
|
||||
}; // end class Traits
|
||||
|
||||
//=============================================================================
|
||||
} // END_NS_ADAPTIVE
|
||||
} // END_NS_SUBDIVIDER
|
||||
} // END_NS_OPENMESH
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_SUBDIVIDER_ADAPTIVE_TRAITS_HH defined
|
||||
//=============================================================================
|
||||
Reference in New Issue
Block a user