OpenMesh: OpenMesh/Tools/Subdivider/Adaptive/Composite/RuleInterfaceT.hh Source File

| OpenMesh

RuleInterfaceT.hh
1 /* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openmesh.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenMesh. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 * ========================================================================= */
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $Date$ *
46 * *
47 \*===========================================================================*/
48
49
50 //=============================================================================
51 //
52 // CLASS RuleInterfaceT
53 //
54 //=============================================================================
55
56 #ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH
57 #define OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH
58
59
60 //== INCLUDES =================================================================
61
62 #include <string>
63 #include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh>
64
65 //== NAMESPACE ================================================================
66
67 namespace OpenMesh { // BEGIN_NS_OPENMESH
68 namespace Subdivider { // BEGIN_NS_SUBDIVIDER
69 namespace Adaptive { // BEGIN_NS_ADAPTIVE
70
71
72 //== FORWARDS =================================================================
73
74 template <typename M> class CompositeT;
75 template <typename M> class RuleInterfaceT;
76
77 //== CLASS DEFINITION =========================================================
78
79
80 // ----------------------------------------------------------------------------
81
87 template < typename R >
88 struct RuleHandleT : public BaseHandle
89 {
90 explicit RuleHandleT(int _idx=-1) : BaseHandle(_idx) {}
91 typedef R Rule;
92
93 operator bool() const { return is_valid(); }
94
95 };
96
100 #define COMPOSITE_RULE( classname, mesh_type ) \
101 protected:\
102 friend class CompositeT<mesh_type>; \
103 public: \
104 const char *type() const { return #classname; } \
105 typedef classname<mesh_type> Self; \
106 typedef RuleHandleT< Self > Handle
107
108
109 // ----------------------------------------------------------------------------
113 template <typename M> class RuleInterfaceT
114 {
115 public:
116
117 typedef M Mesh;
118 typedef RuleInterfaceT<M> Self;
119 typedef RuleHandleT< Self > Rule;
120
121 typedef typename M::Scalar scalar_t;
122
123 protected:
124
126 RuleInterfaceT(Mesh& _mesh) : mesh_(_mesh) {};
127
128 public:
129
131 virtual ~RuleInterfaceT() {};
132
133
136 virtual const char *type() const = 0;
137
138 public:
139
141
142 virtual void raise(typename M::FaceHandle& _fh, state_t _target_state)
144 {
145 if (mesh_.data(_fh).state() < _target_state) {
146 update(_fh, _target_state);
147 mesh_.data(_fh).inc_state();
148 }
149 }
150
151 virtual void raise(typename M::EdgeHandle& _eh, state_t _target_state)
152 {
153 if (mesh_.data(_eh).state() < _target_state) {
154 update(_eh, _target_state);
155 mesh_.data(_eh).inc_state();
156 }
157 }
158
159 virtual void raise(typename M::VertexHandle& _vh, state_t _target_state)
160 {
161 if (mesh_.data(_vh).state() < _target_state) {
162 update(_vh, _target_state);
163 mesh_.data(_vh).inc_state();
164 }
165 }
167
168 void update(typename M::FaceHandle& _fh, state_t _target_state)
169 {
170 typename M::FaceHandle opp_fh;
171
172 while (mesh_.data(_fh).state() < _target_state - 1) {
173 prev_rule()->raise(_fh, _target_state - 1);
174 }
175
176 // Don't use unflipped / unfinal faces!!!
177 if (subdiv_type() == 3) {
178
179 if (mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh))).is_valid()) {
180
181 while (!mesh_.data(_fh).final()) {
182
183 opp_fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh)));
184
185 assert (mesh_.data(_fh).state() >=
186 mesh_.data(opp_fh).state());
187
188 // different states: raise other face
189 if (mesh_.data(_fh).state() > mesh_.data(opp_fh).state()){
190
191 // raise opposite face
192 prev_rule()->raise(opp_fh, _target_state - 1);
193 }
194
195 else {
196
197 // equal states
198
199 // flip edge
200 // typename M::EdgeHandle eh(mesh_.edge_handle(mesh_.halfedge_handle(_fh)));
201
202 // if (mesh_.is_flip_ok(eh)) {
203
204 // std::cout << "Flipping Edge...\n";
205
206 // mesh_.flip(eh);
207
208 // mesh_.data(_fh).set_final();
209 // mesh_.data(opp_fh).set_final();
210 // }
211
212 // else {
213
214 // std::cout << "Flip not okay.\n";
215 // }
216 }
217 }
218 }
219
220 else {
221
222 // mesh_.data(_fh).set_final();
223 }
224
225 // std::cout << "Raising Face to Level "
226 // << _target_state
227 // << " with "
228 // << type()
229 // << ".\n";
230
231 }
232
233 assert( subdiv_type() != 4 ||
234 mesh_.data(_fh).final() ||
235 _target_state%n_rules() == (subdiv_rule()->number() + 1)%n_rules() );
236
237 typename M::FaceEdgeIter fe_it;
238 typename M::FaceVertexIter fv_it;
239 typename M::EdgeHandle eh;
240 typename M::VertexHandle vh;
241
242 std::vector<typename M::FaceHandle> face_vector;
243 face_vector.clear();
244
245 if (_target_state > 1) {
246
247 for (fe_it = mesh_.fe_iter(_fh); fe_it.is_valid(); ++fe_it) {
248
249 eh = *fe_it;
250 prev_rule()->raise(eh, _target_state - 1);
251 }
252
253 for (fv_it = mesh_.fv_iter(_fh); fv_it.is_valid(); ++fv_it) {
254
255 vh = *fv_it;
256 prev_rule()->raise(vh, _target_state - 1);
257 }
258 }
259 }
260
261
262 void update(typename M::EdgeHandle& _eh, state_t _target_state)
263 {
264 state_t state(mesh_.data(_eh).state());
265
266 // raise edge to correct state
267 if (state + 1 < _target_state && _target_state > 0) {
268
269 prev_rule()->raise(_eh, _target_state - 1);
270 }
271
272 typename M::VertexHandle vh;
273 typename M::FaceHandle fh;
274
275 if (_target_state > 1)
276 {
277 vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 0));
278 prev_rule()->raise(vh, _target_state - 1);
279
280 vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 1));
281 prev_rule()->raise(vh, _target_state - 1);
282
283 fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 0));
284 if (fh.is_valid())
285 prev_rule()->raise(fh, _target_state - 1);
286
287 fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 1));
288 if (fh.is_valid())
289 prev_rule()->raise(fh, _target_state - 1);
290 }
291 }
292
293
294 void update(typename M::VertexHandle& _vh, state_t _target_state) {
295
296 state_t state(mesh_.data(_vh).state());
297
298 // raise vertex to correct state
299 if (state + 1 < _target_state)
300 {
301 prev_rule()->raise(_vh, _target_state - 1);
302 }
303
304 std::vector<typename M::HalfedgeHandle> halfedge_vector;
305 halfedge_vector.clear();
306
307 typename M::VertexOHalfedgeIter voh_it;
308 typename M::EdgeHandle eh;
309 typename M::FaceHandle fh;
310
311 if (_target_state > 1)
312 {
313
314 for (voh_it = mesh_.voh_iter(_vh); voh_it.is_valid(); ++voh_it) {
315 halfedge_vector.push_back(*voh_it);
316 }
317
318 while ( !halfedge_vector.empty() ) {
319 eh = mesh_.edge_handle(halfedge_vector.back());
320 halfedge_vector.pop_back();
321
322 prev_rule()->raise(eh, _target_state - 1);
323 }
324
325 for (voh_it = mesh_.voh_iter(_vh); voh_it.is_valid(); ++voh_it) {
326 halfedge_vector.push_back(*voh_it);
327 }
328
329 while ( !halfedge_vector.empty() ) {
330 fh = mesh_.face_handle(halfedge_vector.back());
331 halfedge_vector.pop_back();
332
333 if (fh.is_valid())
334 prev_rule()->raise(fh, _target_state - 1);
335 }
336 }
337 }
338
339 public:
340
341
343 int subdiv_type() const { return subdiv_type_; }
344
345
347 int number() const { return number_; }
348
350
351
353 virtual void set_coeff( scalar_t _coeff ) { coeff_ = _coeff; }
354
356 scalar_t coeff() const { return coeff_; }
357
359
360 protected:
361
362 void set_prev_rule(Self*& _p) { prev_rule_ = _p; }
363 Self* prev_rule() { return prev_rule_; }
364
365 void set_subdiv_rule(Self*& _n) { subdiv_rule_ = _n; }
366 Self* subdiv_rule() { return subdiv_rule_; }
367
368 void set_number(int _n) { number_ = _n; }
369
370 void set_n_rules(int _n) { n_rules_ = _n; }
371 int n_rules() { return n_rules_; }
372
373 void set_subdiv_type(int _n)
374 { assert(_n == 3 || _n == 4); subdiv_type_ = _n; }
375
376 friend class CompositeT<M>;
377
378 protected:
379
380 Mesh& mesh_;
381
382 private:
383
384 Self* prev_rule_;
385 Self* subdiv_rule_;
386
387 int subdiv_type_;
388 int number_;
389 int n_rules_;
390
391 scalar_t coeff_;
392
393 private: // Noncopyable
394
395 RuleInterfaceT(const RuleInterfaceT&);
396 RuleInterfaceT& operator=(const RuleInterfaceT&);
397
398 };
399
400 //=============================================================================
401 } // END_NS_ADAPTIVE
402 } // END_NS_SUBDIVIDER
403 } // END_NS_OPENMESH
404 //=============================================================================
405 #endif // OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH defined
406 //=============================================================================
407
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::number
int number() const
Position in rule sequence.
Definition: RuleInterfaceT.hh:347
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::subdiv_type
int subdiv_type() const
Type of split operation, if it is a topological operator.
Definition: RuleInterfaceT.hh:343
CompositeTraits.hh
Mesh traits for adaptive composite subdivider.
OpenMesh::Subdivider::Adaptive::CompositeT
Adaptive Composite Subdivision framework.
Definition: CompositeT.hh:138
OpenMesh::BaseHandle::is_valid
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:77
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:64
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::RuleInterfaceT
RuleInterfaceT(Mesh &_mesh)
Default constructor.
Definition: RuleInterfaceT.hh:126
OpenMesh::Subdivider::Adaptive::state_t
CompositeTraits::state_t state_t
Adaptive Composite Subdivision framework.
Definition: CompositeTraits.hh:255
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::coeff
scalar_t coeff() const
Get coefficient - ignored by non-parameterized rules.
Definition: RuleInterfaceT.hh:356
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::~RuleInterfaceT
virtual ~RuleInterfaceT()
Destructor.
Definition: RuleInterfaceT.hh:131
OpenMesh::Subdivider::Adaptive::RuleInterfaceT
Base class for adaptive composite subdivision rules.
Definition: CompositeT.hh:84
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::set_coeff
virtual void set_coeff(scalar_t _coeff)
Set coefficient - ignored by non-parameterized rules.
Definition: RuleInterfaceT.hh:353