| 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
45 //=============================================================================
46 //
47 // CLASS RuleInterfaceT
48 //
49 //=============================================================================
50
51 #ifndef OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH
52 #define OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH
53
54
55 //== INCLUDES =================================================================
56
57 #include <string>
58 #include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeTraits.hh>
59
60 //== NAMESPACE ================================================================
61
62 namespace OpenMesh { // BEGIN_NS_OPENMESH
63 namespace Subdivider { // BEGIN_NS_SUBDIVIDER
64 namespace Adaptive { // BEGIN_NS_ADAPTIVE
65
66
67 //== FORWARDS =================================================================
68
69 template <typename M> class CompositeT;
70 template <typename M> class RuleInterfaceT;
71
72 //== CLASS DEFINITION =========================================================
73
74
75 // ----------------------------------------------------------------------------
76
82 template < typename R >
83 struct RuleHandleT : public BaseHandle
84 {
85 explicit RuleHandleT(int _idx=-1) : BaseHandle(_idx) {}
86 typedef R Rule;
87
88 operator bool() const { return is_valid(); }
89
90 };
91
95 #define COMPOSITE_RULE( classname, mesh_type ) \
96 protected:\
97 friend class CompositeT<mesh_type>; \
98 public: \
99 const char *type() const override { return #classname; } \
100 typedef classname<mesh_type> Self; \
101 typedef RuleHandleT< Self > Handle
102
103
104 // ----------------------------------------------------------------------------
108 template <typename M> class RuleInterfaceT
109 {
110 public:
111
112 typedef M Mesh;
113 typedef RuleInterfaceT<M> Self;
114 typedef RuleHandleT< Self > Rule;
115
116 typedef typename M::Scalar scalar_t;
117
118 protected:
119
121 RuleInterfaceT(Mesh& _mesh) : mesh_(_mesh),prev_rule_(nullptr),subdiv_rule_(nullptr),subdiv_type_(0),number_(0),n_rules_(0) {};
122
123 public:
124
126 virtual ~RuleInterfaceT() {};
127
128
131 virtual const char *type() const = 0;
132
133 public:
134
136
137 virtual void raise(typename M::FaceHandle& _fh, state_t _target_state)
139 {
140 if (mesh_.data(_fh).state() < _target_state) {
141 update(_fh, _target_state);
142 mesh_.data(_fh).inc_state();
143 }
144 }
145
146 virtual void raise(typename M::EdgeHandle& _eh, state_t _target_state)
147 {
148 if (mesh_.data(_eh).state() < _target_state) {
149 update(_eh, _target_state);
150 mesh_.data(_eh).inc_state();
151 }
152 }
153
154 virtual void raise(typename M::VertexHandle& _vh, state_t _target_state)
155 {
156 if (mesh_.data(_vh).state() < _target_state) {
157 update(_vh, _target_state);
158 mesh_.data(_vh).inc_state();
159 }
160 }
162
163 void update(typename M::FaceHandle& _fh, state_t _target_state)
164 {
165 typename M::FaceHandle opp_fh;
166
167 while (mesh_.data(_fh).state() < _target_state - 1) {
168 prev_rule()->raise(_fh, _target_state - 1);
169 }
170
171 // Don't use unflipped / unfinal faces!!!
172 if (subdiv_type() == 3) {
173
174 if (mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh))).is_valid()) {
175
176 while (!mesh_.data(_fh).final()) {
177
178 opp_fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(mesh_.halfedge_handle(_fh)));
179
180 assert (mesh_.data(_fh).state() >=
181 mesh_.data(opp_fh).state());
182
183 // different states: raise other face
184 if (mesh_.data(_fh).state() > mesh_.data(opp_fh).state()){
185
186 // raise opposite face
187 prev_rule()->raise(opp_fh, _target_state - 1);
188 }
189
190 else {
191
192 // equal states
193
194 // flip edge
195 // typename M::EdgeHandle eh(mesh_.edge_handle(mesh_.halfedge_handle(_fh)));
196
197 // if (mesh_.is_flip_ok(eh)) {
198
199 // std::cout << "Flipping Edge...\n";
200
201 // mesh_.flip(eh);
202
203 // mesh_.data(_fh).set_final();
204 // mesh_.data(opp_fh).set_final();
205 // }
206
207 // else {
208
209 // std::cout << "Flip not okay.\n";
210 // }
211 }
212 }
213 }
214
215 else {
216
217 // mesh_.data(_fh).set_final();
218 }
219
220 // std::cout << "Raising Face to Level "
221 // << _target_state
222 // << " with "
223 // << type()
224 // << ".\n";
225
226 }
227
228 assert( subdiv_type() != 4 ||
229 mesh_.data(_fh).final() ||
230 _target_state%n_rules() == (subdiv_rule()->number() + 1)%n_rules() );
231
232 typename M::FaceEdgeIter fe_it;
233 typename M::FaceVertexIter fv_it;
234 typename M::EdgeHandle eh;
235 typename M::VertexHandle vh;
236
237 std::vector<typename M::FaceHandle> face_vector;
238 face_vector.clear();
239
240 if (_target_state > 1) {
241
242 for (fe_it = mesh_.fe_iter(_fh); fe_it.is_valid(); ++fe_it) {
243
244 eh = *fe_it;
245 prev_rule()->raise(eh, _target_state - 1);
246 }
247
248 for (fv_it = mesh_.fv_iter(_fh); fv_it.is_valid(); ++fv_it) {
249
250 vh = *fv_it;
251 prev_rule()->raise(vh, _target_state - 1);
252 }
253 }
254 }
255
256
257 void update(typename M::EdgeHandle& _eh, state_t _target_state)
258 {
259 state_t state(mesh_.data(_eh).state());
260
261 // raise edge to correct state
262 if (state + 1 < _target_state && _target_state > 0) {
263
264 prev_rule()->raise(_eh, _target_state - 1);
265 }
266
267 typename M::VertexHandle vh;
268 typename M::FaceHandle fh;
269
270 if (_target_state > 1)
271 {
272 vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 0));
273 prev_rule()->raise(vh, _target_state - 1);
274
275 vh = mesh_.to_vertex_handle(mesh_.halfedge_handle(_eh, 1));
276 prev_rule()->raise(vh, _target_state - 1);
277
278 fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 0));
279 if (fh.is_valid())
280 prev_rule()->raise(fh, _target_state - 1);
281
282 fh = mesh_.face_handle(mesh_.halfedge_handle(_eh, 1));
283 if (fh.is_valid())
284 prev_rule()->raise(fh, _target_state - 1);
285 }
286 }
287
288
289 void update(typename M::VertexHandle& _vh, state_t _target_state) {
290
291 state_t state(mesh_.data(_vh).state());
292
293 // raise vertex to correct state
294 if (state + 1 < _target_state)
295 {
296 prev_rule()->raise(_vh, _target_state - 1);
297 }
298
299 std::vector<typename M::HalfedgeHandle> halfedge_vector;
300 halfedge_vector.clear();
301
302 typename M::VertexOHalfedgeIter voh_it;
303 typename M::EdgeHandle eh;
304 typename M::FaceHandle fh;
305
306 if (_target_state > 1)
307 {
308
309 for (voh_it = mesh_.voh_iter(_vh); voh_it.is_valid(); ++voh_it) {
310 halfedge_vector.push_back(*voh_it);
311 }
312
313 while ( !halfedge_vector.empty() ) {
314 eh = mesh_.edge_handle(halfedge_vector.back());
315 halfedge_vector.pop_back();
316
317 prev_rule()->raise(eh, _target_state - 1);
318 }
319
320 for (voh_it = mesh_.voh_iter(_vh); voh_it.is_valid(); ++voh_it) {
321 halfedge_vector.push_back(*voh_it);
322 }
323
324 while ( !halfedge_vector.empty() ) {
325 fh = mesh_.face_handle(halfedge_vector.back());
326 halfedge_vector.pop_back();
327
328 if (fh.is_valid())
329 prev_rule()->raise(fh, _target_state - 1);
330 }
331 }
332 }
333
334 public:
335
336
338 int subdiv_type() const { return subdiv_type_; }
339
340
342 int number() const { return number_; }
343
345
346
348 virtual void set_coeff( scalar_t _coeff ) { coeff_ = _coeff; }
349
351 scalar_t coeff() const { return coeff_; }
352
354
355 protected:
356
357 void set_prev_rule(Self*& _p) { prev_rule_ = _p; }
358 Self* prev_rule() { return prev_rule_; }
359
360 void set_subdiv_rule(Self*& _n) { subdiv_rule_ = _n; }
361 Self* subdiv_rule() const { return subdiv_rule_; }
362
363 void set_number(int _n) { number_ = _n; }
364
365 void set_n_rules(int _n) { n_rules_ = _n; }
366 int n_rules() const { return n_rules_; }
367
368 void set_subdiv_type(int _n)
369 { assert(_n == 3 || _n == 4); subdiv_type_ = _n; }
370
371 friend class CompositeT<M>;
372
373 protected:
374
375 Mesh& mesh_;
376
377 private:
378
379 Self* prev_rule_;
380 Self* subdiv_rule_;
381
382 int subdiv_type_;
383 int number_;
384 int n_rules_;
385
386 scalar_t coeff_;
387
388 private: // Noncopyable
389
390 RuleInterfaceT(const RuleInterfaceT&);
391 RuleInterfaceT& operator=(const RuleInterfaceT&);
392
393 };
394
395 //=============================================================================
396 } // END_NS_ADAPTIVE
397 } // END_NS_SUBDIVIDER
398 } // END_NS_OPENMESH
399 //=============================================================================
400 #endif // OPENMESH_SUBDIVIDER_ADAPTIVE_RULEINTERFACET_HH defined
401 //=============================================================================
402
OpenMesh::Subdivider::Adaptive::CompositeT
Adaptive Composite Subdivision framework.
Definition: CompositeT.hh:133
CompositeTraits.hh
Mesh traits for adaptive composite subdivider.
OpenMesh::Subdivider::Adaptive::state_t
CompositeTraits::state_t state_t
Adaptive Composite Subdivision framework.
Definition: CompositeTraits.hh:250
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::set_coeff
virtual void set_coeff(scalar_t _coeff)
Set coefficient - ignored by non-parameterized rules.
Definition: RuleInterfaceT.hh:348
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::number
int number() const
Position in rule sequence.
Definition: RuleInterfaceT.hh:342
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::RuleInterfaceT
RuleInterfaceT(Mesh &_mesh)
Default constructor.
Definition: RuleInterfaceT.hh:121
OpenMesh::BaseHandle::is_valid
bool is_valid() const
The handle is valid iff the index is not negative.
Definition: Handles.hh:72
OpenMesh::Subdivider::Adaptive::RuleInterfaceT
Base class for adaptive composite subdivision rules.
Definition: CompositeT.hh:79
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::subdiv_type
int subdiv_type() const
Type of split operation, if it is a topological operator.
Definition: RuleInterfaceT.hh:338
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::coeff
scalar_t coeff() const
Get coefficient - ignored by non-parameterized rules.
Definition: RuleInterfaceT.hh:351
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
OpenMesh::Subdivider::Adaptive::RuleInterfaceT::~RuleInterfaceT
virtual ~RuleInterfaceT()
Destructor.
Definition: RuleInterfaceT.hh:126