OpenMesh
RuleInterfaceT.hh
1 /*===========================================================================*\
2  * *
3  * OpenMesh *
4  * Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
5  * www.openmesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenMesh. *
9  * *
10  * OpenMesh is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenMesh is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36  * *
37  * $Revision: 990 $ *
38  * $Date: 2014-02-05 10:01:07 +0100 (Mi, 05 Feb 2014) $ *
39  * *
40 \*===========================================================================*/
41 
42 
43 //=============================================================================
44 //
45 // CLASS RuleInterfaceT
46 //
47 //=============================================================================
48 
49 #ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH
50 #define OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH
51 
52 
53 //== INCLUDES =================================================================
54 
55 #include <string>
57 
58 //== NAMESPACE ================================================================
59 
60 namespace OpenMesh { // BEGIN_NS_OPENMESH
61 namespace Subdivider { // BEGIN_NS_SUBDIVIDER
62 namespace Adaptive { // BEGIN_NS_ADAPTIVE
63 
64 
65 //== FORWARDS =================================================================
66 
67 template <typename M> class CompositeT;
68 template <typename M> class RuleInterfaceT;
69 
70 //== CLASS DEFINITION =========================================================
71 
72 
73 // ----------------------------------------------------------------------------
74 
80 template < typename R >
81 struct RuleHandleT : public BaseHandle
82 {
83  explicit RuleHandleT(int _idx=-1) : BaseHandle(_idx) {}
84  typedef R Rule;
85 
86  operator bool() const { return is_valid(); }
87 
88 };
89 
93 #define COMPOSITE_RULE( classname, mesh_type ) \
94  protected:\
95  friend class CompositeT<mesh_type>; \
96  public: \
97  const char *type() const { return #classname; } \
98  typedef classname<mesh_type> Self; \
99  typedef RuleHandleT< Self > Handle
100 
101 
102 // ----------------------------------------------------------------------------
106 template <typename M> class RuleInterfaceT
107 {
108 public:
109 
110  typedef M Mesh;
111  typedef RuleInterfaceT<M> Self;
112  typedef RuleHandleT< Self > Rule;
113 
114  typedef typename M::Scalar scalar_t;
115 
116 protected:
117 
119  RuleInterfaceT(Mesh& _mesh) : mesh_(_mesh) {};
120 
121 public:
122 
124  virtual ~RuleInterfaceT() {};
125 
126 
129  virtual const char *type() const = 0;
130 
131 public:
132 
134 
135  virtual void raise(typename M::FaceHandle& _fh, state_t _target_state)
137  {
138  if (mesh_.data(_fh).state() < _target_state) {
139  update(_fh, _target_state);
140  mesh_.data(_fh).inc_state();
141  }
142  }
143 
144  virtual void raise(typename M::EdgeHandle& _eh, state_t _target_state)
145  {
146  if (mesh_.data(_eh).state() < _target_state) {
147  update(_eh, _target_state);
148  mesh_.data(_eh).inc_state();
149  }
150  }
151 
152  virtual void raise(typename M::VertexHandle& _vh, state_t _target_state)
153  {
154  if (mesh_.data(_vh).state() < _target_state) {
155  update(_vh, _target_state);
156  mesh_.data(_vh).inc_state();
157  }
158  }
160 
161  void update(typename M::FaceHandle& _fh, state_t _target_state)
162  {
163  typename M::FaceHandle opp_fh;
164 
165  while (mesh_.data(_fh).state() < _target_state - 1) {
166  prev_rule()->raise(_fh, _target_state - 1);
167  }
168 
169  // Don't use unflipped / unfinal faces!!!
170  if (subdiv_type() == 3) {
171 
172  if (mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh))).is_valid()) {
173 
174  while (!mesh_.data(_fh).final()) {
175 
176  opp_fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh)));
177 
178  assert (mesh_.data(_fh).state() >=
179  mesh_.data(opp_fh).state());
180 
181  // different states: raise other face
182  if (mesh_.data(_fh).state() > mesh_.data(opp_fh).state()){
183 
184  // raise opposite face
185  prev_rule()->raise(opp_fh, _target_state - 1);
186  }
187 
188  else {
189 
190  // equal states
191 
192  // flip edge
193  // typename M::EdgeHandle eh(mesh_.edge_handle(mesh_.halfedge_handle(_fh)));
194 
195  // if (mesh_.is_flip_ok(eh)) {
196 
197  // std::cout << "Flipping Edge...\n";
198 
199  // mesh_.flip(eh);
200 
201  // mesh_.data(_fh).set_final();
202  // mesh_.data(opp_fh).set_final();
203  // }
204 
205  // else {
206 
207  // std::cout << "Flip not okay.\n";
208  // }
209  }
210  }
211  }
212 
213  else {
214 
215  // mesh_.data(_fh).set_final();
216  }
217 
218  // std::cout << "Raising Face to Level "
219  // << _target_state
220  // << " with "
221  // << type()
222  // << ".\n";
223 
224  }
225 
226  assert( subdiv_type() != 4 ||
227  mesh_.data(_fh).final() ||
228  _target_state%n_rules() == (subdiv_rule()->number() + 1)%n_rules() );
229 
230  typename M::FaceEdgeIter fe_it;
231  typename M::FaceVertexIter fv_it;
232  typename M::EdgeHandle eh;
233  typename M::VertexHandle vh;
234 
235  std::vector<typename M::FaceHandle> face_vector;
236  face_vector.clear();
237 
238  if (_target_state > 1) {
239 
240  for (fe_it = mesh_.fe_iter(_fh); fe_it.is_valid(); ++fe_it) {
241 
242  eh = *fe_it;
243  prev_rule()->raise(eh, _target_state - 1);
244  }
245 
246  for (fv_it = mesh_.fv_iter(_fh); fv_it.is_valid(); ++fv_it) {
247 
248  vh = *fv_it;
249  prev_rule()->raise(vh, _target_state - 1);
250  }
251  }
252  }
253 
254 
255  void update(typename M::EdgeHandle& _eh, state_t _target_state)
256  {
257  state_t state(mesh_.data(_eh).state());
258 
259  // raise edge to correct state
260  if (state + 1 < _target_state && _target_state > 0) {
261 
262  prev_rule()->raise(_eh, _target_state - 1);
263  }
264 
265  typename M::VertexHandle vh;
266  typename M::FaceHandle fh;
267 
268  if (_target_state > 1)
269  {
270  vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 0));
271  prev_rule()->raise(vh, _target_state - 1);
272 
273  vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 1));
274  prev_rule()->raise(vh, _target_state - 1);
275 
276  fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 0));
277  if (fh.is_valid())
278  prev_rule()->raise(fh, _target_state - 1);
279 
280  fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 1));
281  if (fh.is_valid())
282  prev_rule()->raise(fh, _target_state - 1);
283  }
284  }
285 
286 
287  void update(typename M::VertexHandle& _vh, state_t _target_state) {
288 
289  state_t state(mesh_.data(_vh).state());
290 
291  // raise vertex to correct state
292  if (state + 1 < _target_state)
293  {
294  prev_rule()->raise(_vh, _target_state - 1);
295  }
296 
297  std::vector<typename M::HalfedgeHandle> halfedge_vector;
298  halfedge_vector.clear();
299 
300  typename M::VertexOHalfedgeIter voh_it;
301  typename M::EdgeHandle eh;
302  typename M::FaceHandle fh;
303 
304  if (_target_state > 1)
305  {
306 
307  for (voh_it = mesh_.voh_iter(_vh); voh_it.is_valid(); ++voh_it) {
308  halfedge_vector.push_back(*voh_it);
309  }
310 
311  while ( !halfedge_vector.empty() ) {
312  eh = mesh_.edge_handle(halfedge_vector.back());
313  halfedge_vector.pop_back();
314 
315  prev_rule()->raise(eh, _target_state - 1);
316  }
317 
318  for (voh_it = mesh_.voh_iter(_vh); voh_it.is_valid(); ++voh_it) {
319  halfedge_vector.push_back(*voh_it);
320  }
321 
322  while ( !halfedge_vector.empty() ) {
323  fh = mesh_.face_handle(halfedge_vector.back());
324  halfedge_vector.pop_back();
325 
326  if (fh.is_valid())
327  prev_rule()->raise(fh, _target_state - 1);
328  }
329  }
330  }
331 
332 public:
333 
334 
336  int subdiv_type() const { return subdiv_type_; }
337 
338 
340  int number() const { return number_; }
341 
343 
344 
346  virtual void set_coeff( scalar_t _coeff ) { coeff_ = _coeff; }
347 
349  scalar_t coeff() const { return coeff_; }
350 
352 
353 protected:
354 
355  void set_prev_rule(Self*& _p) { prev_rule_ = _p; }
356  Self* prev_rule() { return prev_rule_; }
357 
358  void set_subdiv_rule(Self*& _n) { subdiv_rule_ = _n; }
359  Self* subdiv_rule() { return subdiv_rule_; }
360 
361  void set_number(int _n) { number_ = _n; }
362 
363  void set_n_rules(int _n) { n_rules_ = _n; }
364  int n_rules() { return n_rules_; }
365 
366  void set_subdiv_type(int _n)
367  { assert(_n == 3 || _n == 4); subdiv_type_ = _n; }
368 
369  friend class CompositeT<M>;
370 
371 protected:
372 
373  Mesh& mesh_;
374 
375 private:
376 
377  Self* prev_rule_;
378  Self* subdiv_rule_;
379 
380  int subdiv_type_;
381  int number_;
382  int n_rules_;
383 
384  scalar_t coeff_;
385 
386 private: // Noncopyable
387 
389  RuleInterfaceT& operator=(const RuleInterfaceT&);
390 
391 };
392 
393 //=============================================================================
394 } // END_NS_ADAPTIVE
395 } // END_NS_SUBDIVIDER
396 } // END_NS_OPENMESH
397 //=============================================================================
398 #endif // OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH defined
399 //=============================================================================
400 
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:70
Mesh traits for adaptive composite subdivider.
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:56
CompositeTraits::state_t state_t
Adaptive Composite Subdivision framework.
Definition: CompositeTraits.hh:248
virtual void raise(typename M::FaceHandle &_fh, state_t _target_state)
Raise item to target state _target_state.
Definition: RuleInterfaceT.hh:136
virtual const char * type() const =0
Returns the name of the rule.
virtual void set_coeff(scalar_t _coeff)
Set coefficient - ignored by non-parameterized rules.
Definition: RuleInterfaceT.hh:346
int number() const
Position in rule sequence.
Definition: RuleInterfaceT.hh:340
RuleInterfaceT(Mesh &_mesh)
Default constructor.
Definition: RuleInterfaceT.hh:119
virtual ~RuleInterfaceT()
Destructor.
Definition: RuleInterfaceT.hh:124
scalar_t coeff() const
Get coefficient - ignored by non-parameterized rules.
Definition: RuleInterfaceT.hh:349
int subdiv_type() const
Type of split operation, if it is a topological operator.
Definition: RuleInterfaceT.hh:336

acg pic Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .