OpenMesh

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
RuleInterfaceT.hh
1 /*===========================================================================*\
2 * *
3 * OpenMesh *
4 * Copyright (C) 2001-2012 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: 736 $ *
38 * $Date: 2012-10-08 09:30:49 +0200 (Mo, 08 Okt 2012) $ *
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>
56 #include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh>
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
136 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; ++fe_it) {
241
242 eh = fe_it.handle();
243 prev_rule()->raise(eh, _target_state - 1);
244 }
245
246 for (fv_it = mesh_.fv_iter(_fh); fv_it; ++fv_it) {
247
248 vh = fv_it.handle();
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; ++voh_it) {
308 halfedge_vector.push_back(voh_it.handle());
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; ++voh_it) {
319 halfedge_vector.push_back(voh_it.handle());
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
388 RuleInterfaceT(const RuleInterfaceT&);
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