Line data Source code
1 : /*
2 : * Copyright (c) 2011-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__UG__grid_objects_2d__
34 : #define __H__UG__grid_objects_2d__
35 :
36 : #include "../grid/grid.h"
37 : #include "common/math/ugmath.h"
38 : #include "common/assert.h"
39 : #include "grid_objects_0d.h"
40 : #include "grid_objects_1d.h"
41 :
42 : namespace ug
43 : {
44 :
45 : ////////////////////////////////////////////////////////////////////////
46 : /// These numbers define where in the face-section-container a face will be stored.
47 : /** The order of the constants must not be changed! Algorithms may exist that rely on it.*/
48 : enum FaceContainerSections
49 : {
50 : CSFACE_NONE = -1,
51 : CSFACE_TRIANGLE = 0,
52 : CSFACE_QUADRILATERAL = 1,
53 : CSFACE_CONSTRAINED_TRIANGLE = 2,
54 : CSFACE_CONSTRAINED_QUADRILATERAL = 3,
55 : CSFACE_CONSTRAINING_TRIANGLE = 4,
56 : CSFACE_CONSTRAINING_QUADRILATERAL = 5,
57 :
58 : CSFACE_USER // always last
59 : };
60 :
61 :
62 : // predeclarations
63 : class Triangle;
64 : class Quadrilateral;
65 : class ConstrainedTriangle;
66 : class ConstrainedQuadrilateral;
67 : class ConstrainingTriangle;
68 : class ConstrainingQuadrilateral;
69 :
70 : ////////////////////////////////////////////////////////////////////////////////
71 : // NORMAL FACES
72 : ////////////////////////////////////////////////////////////////////////////////
73 :
74 : ////////////////////////////////////////////////////////////////////////
75 : // TriangleDescriptor
76 : /// only used to initialize a triangle. for all other tasks you should use FaceDescriptor.
77 : class UG_API TriangleDescriptor
78 : {
79 : public:
80 0 : TriangleDescriptor() {}
81 : TriangleDescriptor(const TriangleDescriptor& td);
82 : TriangleDescriptor(Vertex* v1, Vertex* v2, Vertex* v3);
83 :
84 : inline uint num_vertices() const {return 3;}
85 0 : inline void set_vertex(uint index, Vertex* v) {m_vertex[index] = v;}
86 1 : inline Vertex* vertex(size_t index) const {return m_vertex[index];}
87 :
88 : protected:
89 : Vertex* m_vertex[3];
90 : };
91 :
92 :
93 :
94 : ////////////////////////////////////////////////////////////////////////
95 : // CustomTriangle
96 : /// Concrete types share this base-type. It is not intended for direct use.
97 : /**
98 : * BaseClass has to be derived from Face (or simply should be Face).
99 : * The ConcreteTriangleType is used in methods like refine, etc. as the type
100 : * of newly created objects.
101 : *
102 : * RefTriType and RefQuadType are used to create new elements during refinement
103 : * operations.
104 : */
105 : template <class ConcreteTriangleType, class BaseClass,
106 : class RefTriType, class RefQuadType>
107 0 : class UG_API CustomTriangle : public BaseClass
108 : {
109 : public:
110 : static const size_t NUM_VERTICES = 3;
111 :
112 : public:
113 0 : CustomTriangle() {}
114 : CustomTriangle(const TriangleDescriptor& td);
115 : CustomTriangle(Vertex* v1, Vertex* v2, Vertex* v3);
116 :
117 0 : virtual GridObject* create_empty_instance() const {return new ConcreteTriangleType;}
118 0 : virtual ReferenceObjectID reference_object_id() const {return ROID_TRIANGLE;}
119 :
120 0 : virtual Vertex* vertex(size_t index) const {return m_vertices[index];}
121 1 : virtual Face::ConstVertexArray vertices() const {return m_vertices;}
122 2 : virtual size_t num_vertices() const {return 3;}
123 :
124 0 : virtual EdgeDescriptor edge_desc(int index) const
125 0 : {return EdgeDescriptor(m_vertices[index], m_vertices[(index+1) % 3]);}
126 :
127 3 : virtual void edge_desc(int index, EdgeDescriptor& edOut) const
128 3 : {edOut.set_vertices(m_vertices[index], m_vertices[(index+1) % 3]);}
129 :
130 : virtual std::pair<GridBaseObjectId, int> get_opposing_object(Vertex* vrt) const;
131 :
132 : /// Refines a Triangle by inserting new vertices. \sa Face::refine.
133 : virtual bool refine(std::vector<Face*>& vNewFacesOut,
134 : Vertex** newFaceVertexOut,
135 : Vertex** newEdgeVertices,
136 : Vertex* newFaceVertex = NULL,
137 : Vertex** pSubstituteVertices = NULL,
138 : int snapPointIndex = -1);
139 :
140 : virtual bool is_regular_ref_rule(int edgeMarks) const;
141 :
142 : virtual bool collapse_edge(std::vector<Face*>& vNewFacesOut,
143 : int edgeIndex, Vertex* newVertex,
144 : Vertex** pSubstituteVertices = NULL);
145 :
146 : virtual bool collapse_edges(std::vector<Face*>& vNewFacesOut,
147 : std::vector<Vertex*>& vNewEdgeVertices,
148 : Vertex** pSubstituteVertices = NULL);
149 :
150 : // BEGIN Depreciated
151 : virtual void create_faces_by_edge_split(int splitEdgeIndex,
152 : Vertex* newVertex,
153 : std::vector<Face*>& vNewFacesOut,
154 : Vertex** pSubstituteVertices = NULL);
155 :
156 : protected:
157 0 : virtual void set_vertex(uint index, Vertex* pVrt) {m_vertices[index] = pVrt;}
158 :
159 : protected:
160 : Vertex* m_vertices[3];
161 : };
162 :
163 :
164 :
165 : ////////////////////////////////////////////////////////////////////////
166 : // Triangle
167 : /// the most simple form of a face
168 : /**
169 : *
170 : * \ingroup lib_grid_grid_objects
171 : */
172 : class UG_API Triangle :
173 : public CustomTriangle<Triangle, Face, Triangle, Quadrilateral>
174 : {
175 : typedef CustomTriangle<Triangle, Face, Triangle, Quadrilateral> BaseClass;
176 : public:
177 : inline static bool type_match(GridObject* pObj) {return dynamic_cast<Triangle*>(pObj) != NULL;}
178 :
179 0 : Triangle() : BaseClass() {}
180 1 : Triangle(const TriangleDescriptor& td) : BaseClass(td) {}
181 0 : Triangle(Vertex* v1, Vertex* v2, Vertex* v3) : BaseClass(v1, v2, v3) {}
182 :
183 2 : virtual int container_section() const {return CSFACE_TRIANGLE;}
184 :
185 : protected:
186 3 : virtual Edge* create_edge(int index)
187 : {
188 3 : return new RegularEdge(m_vertices[index], m_vertices[(index+1) % 3]);
189 : }
190 : };
191 :
192 : template <>
193 : class geometry_traits<Triangle>
194 : {
195 : public:
196 : typedef GenericGridObjectIterator<Triangle*, FaceIterator> iterator;
197 : typedef ConstGenericGridObjectIterator<Triangle*, FaceIterator,
198 : ConstFaceIterator> const_iterator;
199 :
200 : typedef TriangleDescriptor Descriptor; ///< Faces can't be created directly
201 : typedef Face grid_base_object;
202 :
203 : enum
204 : {
205 : CONTAINER_SECTION = CSFACE_TRIANGLE,
206 : BASE_OBJECT_ID = FACE
207 : };
208 : static const ReferenceObjectID REFERENCE_OBJECT_ID = ROID_TRIANGLE;
209 : };
210 :
211 : typedef geometry_traits<Triangle>::iterator TriangleIterator;
212 : typedef geometry_traits<Triangle>::const_iterator ConstTriangleIterator;
213 :
214 :
215 :
216 : ////////////////////////////////////////////////////////////////////////
217 : // QuadrilateralDescriptor
218 : /// only used to initialize a quadrilateral. for all other tasks you should use FaceDescriptor.
219 : class UG_API QuadrilateralDescriptor
220 : {
221 : public:
222 : QuadrilateralDescriptor() {}
223 : QuadrilateralDescriptor(const QuadrilateralDescriptor& qd);
224 : QuadrilateralDescriptor(Vertex* v1, Vertex* v2, Vertex* v3, Vertex* v4);
225 :
226 : inline uint num_vertices() const {return 4;}
227 : inline void set_vertex(uint index, Vertex* v) {m_vertex[index] = v;}
228 0 : inline Vertex* vertex(size_t index) const {return m_vertex[index];}
229 :
230 : protected:
231 : Vertex* m_vertex[4];
232 : };
233 :
234 :
235 :
236 : ////////////////////////////////////////////////////////////////////////
237 : // CustomQuadrilateral
238 : /// Concrete types share this base-type. It is not intended for direct use.
239 : /**
240 : * BaseClass has to be derived from Face (or simply should be Face).
241 : * The ConcreteQuadrilateralType is used in methods like refine, etc. as the type
242 : * of newly created objects.
243 : *
244 : * RefTriType and RefQuadType are used to create new elements during refinement
245 : * operations.
246 : */
247 : template <class ConcreteQuadrilateralType, class BaseClass,
248 : class RefTriType, class RefQuadType>
249 0 : class UG_API CustomQuadrilateral : public BaseClass
250 : {
251 : public:
252 : static const size_t NUM_VERTICES = 4;
253 :
254 : public:
255 : using typename BaseClass::ConstVertexArray;
256 :
257 0 : CustomQuadrilateral() {}
258 : CustomQuadrilateral(const QuadrilateralDescriptor& qd);
259 : CustomQuadrilateral(Vertex* v1, Vertex* v2,
260 : Vertex* v3, Vertex* v4);
261 :
262 0 : virtual GridObject* create_empty_instance() const {return new ConcreteQuadrilateralType;}
263 0 : virtual ReferenceObjectID reference_object_id() const {return ROID_QUADRILATERAL;}
264 :
265 0 : virtual Vertex* vertex(size_t index) const {return m_vertices[index];}
266 0 : virtual Face::ConstVertexArray vertices() const {return m_vertices;}
267 0 : virtual size_t num_vertices() const {return 4;}
268 :
269 0 : virtual EdgeDescriptor edge_desc(int index) const
270 0 : {return EdgeDescriptor(m_vertices[index], m_vertices[(index+1) % 4]);}
271 :
272 0 : virtual void edge_desc(int index, EdgeDescriptor& edOut) const
273 0 : {edOut.set_vertices(m_vertices[index], m_vertices[(index+1) % 4]);}
274 :
275 :
276 : /// fills the edge-descriptor with the edge that lies opposed to the specified one
277 : /** If the specified edge is not part of the face, false is returned.*/
278 : virtual bool get_opposing_side(EdgeVertices* e, EdgeDescriptor& edOut) const;
279 :
280 : virtual std::pair<GridBaseObjectId, int> get_opposing_object(Vertex* vrt) const;
281 :
282 : /// Refines a Quadrilateral by inserting new vertices. \sa Face::refine.
283 : virtual bool refine(std::vector<Face*>& vNewFacesOut,
284 : Vertex** newFaceVertexOut,
285 : Vertex** newEdgeVertices,
286 : Vertex* newFaceVertex = NULL,
287 : Vertex** pSubstituteVertices = NULL,
288 : int snapPointIndex = -1);
289 :
290 : virtual bool is_regular_ref_rule(int edgeMarks) const;
291 :
292 : virtual bool collapse_edge(std::vector<Face*>& vNewFacesOut,
293 : int edgeIndex, Vertex* newVertex,
294 : Vertex** pSubstituteVertices = NULL);
295 :
296 : virtual bool collapse_edges(std::vector<Face*>& vNewFacesOut,
297 : std::vector<Vertex*>& vNewEdgeVertices,
298 : Vertex** pSubstituteVertices = NULL);
299 :
300 : // BEGIN Depreciated
301 : virtual void create_faces_by_edge_split(int splitEdgeIndex,
302 : Vertex* newVertex,
303 : std::vector<Face*>& vNewFacesOut,
304 : Vertex** pSubstituteVertices = NULL);
305 :
306 : protected:
307 0 : virtual void set_vertex(uint index, Vertex* pVrt) {m_vertices[index] = pVrt;}
308 :
309 : protected:
310 : Vertex* m_vertices[4];
311 : };
312 :
313 :
314 :
315 : ////////////////////////////////////////////////////////////////////////
316 : // Quadrilateral
317 : /// a face with four points.
318 : /**
319 : * \ingroup lib_grid_grid_objects
320 : */
321 : class UG_API Quadrilateral :
322 : public CustomQuadrilateral<Quadrilateral, Face, Triangle, Quadrilateral>
323 : {
324 : public:
325 : typedef CustomQuadrilateral<Quadrilateral, Face, Triangle, Quadrilateral>
326 : BaseClass;
327 :
328 : inline static bool type_match(GridObject* pObj)
329 : {return dynamic_cast<Quadrilateral*>(pObj) != NULL;}
330 :
331 0 : Quadrilateral() {}
332 0 : Quadrilateral(const QuadrilateralDescriptor& td) : BaseClass(td) {}
333 : Quadrilateral(Vertex* v1, Vertex* v2,
334 0 : Vertex* v3, Vertex* v4) : BaseClass(v1, v2, v3, v4) {}
335 :
336 0 : virtual int container_section() const {return CSFACE_QUADRILATERAL;}
337 :
338 : protected:
339 0 : virtual Edge* create_edge(int index)
340 : {
341 0 : return new RegularEdge(m_vertices[index], m_vertices[(index+1) % 4]);
342 : }
343 : };
344 :
345 : template <>
346 : class geometry_traits<Quadrilateral>
347 : {
348 : public:
349 : typedef GenericGridObjectIterator<Quadrilateral*, FaceIterator>
350 : iterator;
351 : typedef ConstGenericGridObjectIterator<Quadrilateral*, FaceIterator,
352 : ConstFaceIterator>
353 : const_iterator;
354 :
355 : typedef QuadrilateralDescriptor Descriptor; ///< Faces can't be created directly
356 : typedef Face grid_base_object;
357 :
358 : enum
359 : {
360 : CONTAINER_SECTION = CSFACE_QUADRILATERAL,
361 : BASE_OBJECT_ID = FACE
362 : };
363 : static const ReferenceObjectID REFERENCE_OBJECT_ID = ROID_QUADRILATERAL;
364 : };
365 :
366 : typedef geometry_traits<Quadrilateral>::iterator QuadrilateralIterator;
367 : typedef geometry_traits<Quadrilateral>::const_iterator ConstQuadrilateralIterator;
368 :
369 :
370 :
371 : ////////////////////////////////////////////////////////////////////////////////
372 : // CONSTRAINED FACES
373 : ////////////////////////////////////////////////////////////////////////////////
374 :
375 : ////////////////////////////////////////////////////////////////////////
376 : // ConstrainedFace
377 : /// This class stores the constraining object.
378 : /**
379 : * Please note, that the user is has to link and unlink constraining
380 : * objects manually.
381 : */
382 : class UG_API ConstrainedFace : public Face
383 : {
384 : public:
385 : inline static bool type_match(GridObject* pObj)
386 : {return dynamic_cast<ConstrainedFace*>(pObj) != NULL;}
387 :
388 0 : ConstrainedFace() : m_pConstrainingObject(NULL), m_parentBaseObjectId(-1) {}
389 0 : virtual ~ConstrainedFace()
390 0 : {
391 0 : if(m_pConstrainingObject)
392 0 : m_pConstrainingObject->remove_constraint_link(this);
393 0 : }
394 :
395 : inline void set_constraining_object(GridObject* pObj)
396 : {
397 0 : m_pConstrainingObject = pObj;
398 0 : if(pObj)
399 0 : m_parentBaseObjectId = pObj->base_object_id();
400 0 : }
401 :
402 0 : inline GridObject* get_constraining_object() {return m_pConstrainingObject;}
403 :
404 0 : inline int get_parent_base_object_id() {return m_parentBaseObjectId;}
405 0 : inline void set_parent_base_object_id(int id)
406 : {
407 0 : if((m_parentBaseObjectId != -1) && (m_parentBaseObjectId != id)){
408 0 : UG_THROW("Bad parent base object id specified! The given id"
409 : " has to match the id of the constraining object if that"
410 : " is present. Call this method only, if no constraining"
411 : " object has been set!");
412 : }
413 0 : m_parentBaseObjectId = id;
414 0 : }
415 :
416 0 : virtual bool is_constrained() const {return true;}
417 :
418 0 : virtual void remove_constraint_link(const Face* f)
419 : {
420 0 : if(m_pConstrainingObject == static_cast<const GridObject*>(f))
421 0 : m_pConstrainingObject = NULL;
422 0 : }
423 :
424 :
425 : protected:
426 : GridObject* m_pConstrainingObject;
427 : int m_parentBaseObjectId;
428 : };
429 :
430 :
431 : ////////////////////////////////////////////////////////////////////////
432 : // ConstrainedTriangle
433 : /// a triangle constrained by another object.
434 : /**
435 : * \ingroup lib_grid_grid_objects
436 : */
437 0 : class UG_API ConstrainedTriangle :
438 : public CustomTriangle <ConstrainedTriangle, ConstrainedFace,
439 : ConstrainedTriangle, ConstrainedQuadrilateral>
440 : {
441 : typedef CustomTriangle<ConstrainedTriangle, ConstrainedFace,
442 : ConstrainedTriangle, ConstrainedQuadrilateral>
443 : BaseTriangle;
444 :
445 : public:
446 : inline static bool type_match(GridObject* pObj) {return dynamic_cast<ConstrainedTriangle*>(pObj) != NULL;}
447 :
448 : ConstrainedTriangle() :
449 0 : BaseTriangle() {}
450 :
451 0 : ConstrainedTriangle(const TriangleDescriptor& td) :
452 0 : BaseTriangle(td) {}
453 :
454 0 : ConstrainedTriangle(Vertex* v1, Vertex* v2, Vertex* v3) :
455 0 : BaseTriangle(v1, v2, v3) {}
456 :
457 0 : virtual int container_section() const {return CSFACE_CONSTRAINED_TRIANGLE;}
458 :
459 : protected:
460 0 : virtual Edge* create_edge(int index)
461 : {
462 0 : return new ConstrainedEdge(m_vertices[index], m_vertices[(index+1) % 3]);
463 : }
464 : };
465 :
466 : template <>
467 : class geometry_traits<ConstrainedTriangle>
468 : {
469 : public:
470 : typedef GenericGridObjectIterator<ConstrainedTriangle*, FaceIterator>
471 : iterator;
472 : typedef ConstGenericGridObjectIterator<ConstrainedTriangle*, FaceIterator,
473 : ConstFaceIterator>
474 : const_iterator;
475 :
476 : typedef TriangleDescriptor Descriptor; ///< Faces can't be created directly
477 : typedef Face grid_base_object;
478 :
479 : enum
480 : {
481 : CONTAINER_SECTION = CSFACE_CONSTRAINED_TRIANGLE,
482 : BASE_OBJECT_ID = FACE
483 : };
484 : static const ReferenceObjectID REFERENCE_OBJECT_ID = ROID_TRIANGLE;
485 : };
486 :
487 : typedef geometry_traits<ConstrainedTriangle>::iterator ConstrainedTriangleIterator;
488 : typedef geometry_traits<ConstrainedTriangle>::const_iterator ConstConstrainedTriangleIterator;
489 :
490 :
491 :
492 : ////////////////////////////////////////////////////////////////////////
493 : // ConstrainedQuadrilateral
494 : /// a quadrilateral constrained by another object.
495 : /**
496 : * \ingroup lib_grid_grid_objects
497 : */
498 0 : class UG_API ConstrainedQuadrilateral :
499 : public CustomQuadrilateral <ConstrainedQuadrilateral, ConstrainedFace,
500 : ConstrainedTriangle, ConstrainedQuadrilateral>
501 : {
502 : typedef CustomQuadrilateral<ConstrainedQuadrilateral, ConstrainedFace,
503 : ConstrainedTriangle, ConstrainedQuadrilateral>
504 : BaseClass;
505 :
506 : public:
507 : inline static bool type_match(GridObject* pObj) {return dynamic_cast<ConstrainedQuadrilateral*>(pObj) != NULL;}
508 :
509 0 : ConstrainedQuadrilateral() : BaseClass() {}
510 0 : ConstrainedQuadrilateral(const QuadrilateralDescriptor& qd) : BaseClass(qd) {}
511 : ConstrainedQuadrilateral(Vertex* v1, Vertex* v2,
512 0 : Vertex* v3, Vertex* v4) : BaseClass(v1, v2, v3, v4) {}
513 :
514 0 : virtual int container_section() const {return CSFACE_CONSTRAINED_QUADRILATERAL;}
515 :
516 : protected:
517 0 : virtual Edge* create_edge(int index)
518 : {
519 0 : return new ConstrainedEdge(m_vertices[index], m_vertices[(index+1) % 4]);
520 : }
521 : };
522 :
523 :
524 : template <>
525 : class geometry_traits<ConstrainedQuadrilateral>
526 : {
527 : public:
528 : typedef GenericGridObjectIterator<ConstrainedQuadrilateral*, FaceIterator>
529 : iterator;
530 : typedef ConstGenericGridObjectIterator<ConstrainedQuadrilateral*,
531 : FaceIterator, ConstFaceIterator>
532 : const_iterator;
533 :
534 : typedef QuadrilateralDescriptor Descriptor; ///< Faces can't be created directly
535 : typedef Face grid_base_object;
536 :
537 : enum
538 : {
539 : CONTAINER_SECTION = CSFACE_CONSTRAINED_QUADRILATERAL,
540 : BASE_OBJECT_ID = FACE
541 : };
542 : static const ReferenceObjectID REFERENCE_OBJECT_ID = ROID_QUADRILATERAL;
543 : };
544 :
545 : typedef geometry_traits<ConstrainedQuadrilateral>::iterator ConstrainedQuadrilateralIterator;
546 : typedef geometry_traits<ConstrainedQuadrilateral>::const_iterator ConstConstrainedQuadrilateralIterator;
547 :
548 :
549 :
550 : ////////////////////////////////////////////////////////////////////////////////
551 : // CONSTRAINING FACES
552 : ////////////////////////////////////////////////////////////////////////////////
553 :
554 : ////////////////////////////////////////////////////////////////////////
555 : // ConstrainingFace
556 : /// This class is used to store constrained geometric objects.
557 : /**
558 : * Please note, that the user is has to link and unlink constrained
559 : * objects manually.
560 : */
561 : class UG_API ConstrainingFace : public Face
562 : {
563 :
564 : public:
565 : inline static bool type_match(GridObject* pObj) {return dynamic_cast<ConstrainingFace*>(pObj) != NULL;}
566 :
567 0 : virtual ~ConstrainingFace()
568 0 : {
569 0 : for(size_t i = 0; i < m_constrainedVertices.size(); ++i){
570 0 : m_constrainedVertices[i]->remove_constraint_link(this);
571 : }
572 :
573 0 : for(size_t i = 0; i < m_constrainedEdges.size(); ++i){
574 0 : m_constrainedEdges[i]->remove_constraint_link(this);
575 : }
576 :
577 0 : for(size_t i = 0; i < m_constrainedFaces.size(); ++i){
578 0 : m_constrainedFaces[i]->remove_constraint_link(this);
579 : }
580 0 : }
581 :
582 0 : virtual bool is_constraining() const {return true;}
583 :
584 : inline void add_constrained_object(Vertex* pObj)
585 : {
586 : UG_ASSERT(!is_constrained_object(pObj),
587 : "vertex is already registered at constraining face");
588 0 : m_constrainedVertices.push_back(pObj);
589 0 : }
590 :
591 : inline void add_constrained_object(Edge* pObj)
592 : {
593 : UG_ASSERT(!is_constrained_object(pObj),
594 : "edge is already registered at constraining face");
595 0 : m_constrainedEdges.push_back(pObj);
596 0 : }
597 :
598 : inline void add_constrained_object(Face* pObj)
599 : {
600 : UG_ASSERT(!is_constrained_object(pObj),
601 : "face is already registered at constraining face");
602 0 : m_constrainedFaces.push_back(pObj);
603 0 : }
604 :
605 : inline bool is_constrained_object(Vertex* vrt)
606 : {
607 0 : std::vector<Vertex*>::iterator iter = find(m_constrainedVertices.begin(),
608 : m_constrainedVertices.end(), vrt);
609 : return iter != m_constrainedVertices.end();
610 : }
611 :
612 : inline bool is_constrained_object(Edge* edge)
613 : {
614 0 : std::vector<Edge*>::iterator iter = find(m_constrainedEdges.begin(),
615 : m_constrainedEdges.end(), edge);
616 : return iter != m_constrainedEdges.end();
617 : }
618 :
619 : inline bool is_constrained_object(Face* face)
620 : {
621 0 : std::vector<Face*>::iterator iter = find(m_constrainedFaces.begin(),
622 : m_constrainedFaces.end(), face);
623 : return iter != m_constrainedFaces.end();
624 : }
625 :
626 0 : virtual void remove_constraint_link(const Vertex* vrt)
627 : {
628 0 : unconstrain_object(vrt);
629 0 : }
630 :
631 0 : virtual void remove_constraint_link(const Edge* e)
632 : {
633 0 : unconstrain_object(e);
634 0 : }
635 :
636 0 : virtual void remove_constraint_link(const Face* f)
637 : {
638 0 : unconstrain_object(f);
639 0 : }
640 :
641 0 : inline void unconstrain_object(const Vertex* vrt)
642 : {
643 0 : std::vector<Vertex*>::iterator iter = find(m_constrainedVertices.begin(),
644 : m_constrainedVertices.end(), vrt);
645 0 : if(iter != m_constrainedVertices.end())
646 0 : m_constrainedVertices.erase(iter);
647 0 : }
648 :
649 0 : inline void unconstrain_object(const Edge* edge)
650 : {
651 : std::vector<Edge*>::iterator iter
652 0 : = find(m_constrainedEdges.begin(),
653 : m_constrainedEdges.end(), edge);
654 :
655 0 : if(iter != m_constrainedEdges.end())
656 0 : m_constrainedEdges.erase(iter);
657 0 : }
658 :
659 0 : inline void unconstrain_object(const Face* face)
660 : {
661 0 : std::vector<Face*>::iterator iter = find(m_constrainedFaces.begin(),
662 : m_constrainedFaces.end(), face);
663 0 : if(iter != m_constrainedFaces.end())
664 0 : m_constrainedFaces.erase(iter);
665 0 : }
666 :
667 : inline void clear_constrained_vertices() {m_constrainedVertices.clear();}
668 : inline void clear_constrained_edges() {m_constrainedEdges.clear();}
669 : inline void clear_constrained_faces() {m_constrainedFaces.clear();}
670 : inline void clear_constrained_objects()
671 : {
672 : clear_constrained_vertices();
673 : clear_constrained_edges();
674 : clear_constrained_faces();
675 : }
676 :
677 : inline size_t num_constrained_vertices() const
678 : {return m_constrainedVertices.size();}
679 :
680 : inline size_t num_constrained_edges() const
681 : {return m_constrainedEdges.size();}
682 :
683 : inline size_t num_constrained_faces() const
684 : {return m_constrainedFaces.size();}
685 :
686 :
687 : template <class TElem> size_t num_constrained() const;
688 :
689 :
690 : inline Vertex* constrained_vertex(size_t ind) const
691 : {
692 : UG_ASSERT(ind < m_constrainedVertices.size(), "bad index.");
693 0 : return m_constrainedVertices[ind];
694 : }
695 :
696 : inline Edge* constrained_edge(size_t ind) const
697 : {
698 : UG_ASSERT(ind < m_constrainedEdges.size(), "bad index.");
699 0 : return m_constrainedEdges[ind];
700 : }
701 :
702 : inline Face* constrained_face(size_t ind) const
703 : {
704 : UG_ASSERT(ind < m_constrainedFaces.size(), "bad index.");
705 0 : return m_constrainedFaces[ind];
706 : }
707 :
708 : template <class TElem> TElem* constrained(size_t ind) const;
709 :
710 : protected:
711 : std::vector<Vertex*> m_constrainedVertices;
712 : std::vector<Edge*> m_constrainedEdges;
713 : std::vector<Face*> m_constrainedFaces;
714 : };
715 :
716 :
717 :
718 : ////////////////////////////////////////////////////////////////////////
719 : // ConstrainingTriangle
720 : /// a triangle constraining other objects.
721 : /**
722 : * \ingroup lib_grid_grid_objects
723 : */
724 : class UG_API ConstrainingTriangle :
725 : public CustomTriangle <ConstrainingTriangle, ConstrainingFace,
726 : ConstrainingTriangle, ConstrainingQuadrilateral>
727 : {
728 : typedef CustomTriangle<ConstrainingTriangle, ConstrainingFace,
729 : ConstrainingTriangle, ConstrainingQuadrilateral>
730 : BaseTriangle;
731 :
732 : public:
733 : inline static bool type_match(GridObject* pObj)
734 : {return dynamic_cast<ConstrainingTriangle*>(pObj) != NULL;}
735 :
736 0 : ConstrainingTriangle() :
737 0 : BaseTriangle() {reserve_memory();}
738 0 : ConstrainingTriangle(const TriangleDescriptor& td) :
739 0 : BaseTriangle(td) {reserve_memory();}
740 0 : ConstrainingTriangle(Vertex* v1, Vertex* v2, Vertex* v3) :
741 0 : BaseTriangle(v1, v2, v3) {reserve_memory();}
742 :
743 0 : virtual int container_section() const {return CSFACE_CONSTRAINING_TRIANGLE;}
744 :
745 : protected:
746 : void reserve_memory()
747 : {
748 0 : m_constrainedEdges.reserve(3);
749 0 : m_constrainedFaces.reserve(4);
750 0 : }
751 :
752 0 : virtual Edge* create_edge(int index)
753 : {
754 0 : return new RegularEdge(m_vertices[index], m_vertices[(index+1) % 3]);
755 : }
756 : };
757 :
758 : template <>
759 : class geometry_traits<ConstrainingTriangle>
760 : {
761 : public:
762 : typedef GenericGridObjectIterator<ConstrainingTriangle*, FaceIterator>
763 : iterator;
764 : typedef ConstGenericGridObjectIterator<ConstrainingTriangle*, FaceIterator,
765 : ConstFaceIterator>
766 : const_iterator;
767 :
768 : typedef TriangleDescriptor Descriptor; ///< Faces can't be created directly
769 : typedef Face grid_base_object;
770 :
771 : enum
772 : {
773 : CONTAINER_SECTION = CSFACE_CONSTRAINING_TRIANGLE,
774 : BASE_OBJECT_ID = FACE
775 : };
776 : static const ReferenceObjectID REFERENCE_OBJECT_ID = ROID_TRIANGLE;
777 : };
778 :
779 : typedef geometry_traits<ConstrainingTriangle>::iterator
780 : ConstrainingTriangleIterator;
781 : typedef geometry_traits<ConstrainingTriangle>::const_iterator
782 : ConstConstrainingTriangleIterator;
783 :
784 :
785 :
786 : ////////////////////////////////////////////////////////////////////////
787 : // ConstrainingQuadrilateral
788 : /// a quadrilateral constraining other objects.
789 : /**
790 : * \ingroup lib_grid_grid_objects
791 : */
792 : class UG_API ConstrainingQuadrilateral :
793 : public CustomQuadrilateral <ConstrainingQuadrilateral, ConstrainingFace,
794 : ConstrainingTriangle, ConstrainingQuadrilateral>
795 : {
796 : typedef CustomQuadrilateral<ConstrainingQuadrilateral, ConstrainingFace,
797 : ConstrainingTriangle, ConstrainingQuadrilateral>
798 : BaseClass;
799 :
800 : public:
801 : inline static bool type_match(GridObject* pObj) {return dynamic_cast<ConstrainingQuadrilateral*>(pObj) != NULL;}
802 :
803 0 : ConstrainingQuadrilateral() :
804 0 : BaseClass() {reserve_memory();}
805 0 : ConstrainingQuadrilateral(const QuadrilateralDescriptor& qd) :
806 0 : BaseClass(qd) {reserve_memory();}
807 0 : ConstrainingQuadrilateral(Vertex* v1, Vertex* v2,
808 : Vertex* v3, Vertex* v4) :
809 0 : BaseClass(v1, v2, v3, v4) {reserve_memory();}
810 :
811 0 : virtual int container_section() const {return CSFACE_CONSTRAINING_QUADRILATERAL;}
812 :
813 : protected:
814 0 : void reserve_memory()
815 : {
816 0 : m_constrainedVertices.reserve(1);
817 0 : m_constrainedEdges.reserve(4);
818 0 : m_constrainedFaces.reserve(4);
819 0 : }
820 :
821 0 : virtual Edge* create_edge(int index)
822 : {
823 0 : return new RegularEdge(m_vertices[index], m_vertices[(index+1) % 4]);
824 : }
825 : };
826 :
827 : template <>
828 : class geometry_traits<ConstrainingQuadrilateral>
829 : {
830 : public:
831 : typedef GenericGridObjectIterator<ConstrainingQuadrilateral*, FaceIterator>
832 : iterator;
833 :
834 : typedef ConstGenericGridObjectIterator<ConstrainingQuadrilateral*,
835 : FaceIterator, ConstFaceIterator>
836 : const_iterator;
837 :
838 : typedef QuadrilateralDescriptor Descriptor; ///< Faces can't be created directly
839 : typedef Face grid_base_object;
840 :
841 : enum
842 : {
843 : CONTAINER_SECTION = CSFACE_CONSTRAINING_QUADRILATERAL,
844 : BASE_OBJECT_ID = FACE
845 : };
846 : static const ReferenceObjectID REFERENCE_OBJECT_ID = ROID_QUADRILATERAL;
847 : };
848 :
849 : typedef geometry_traits<ConstrainingQuadrilateral>::iterator
850 : ConstrainingQuadrilateralIterator;
851 : typedef geometry_traits<ConstrainingQuadrilateral>::const_iterator
852 : ConstConstrainingQuadrilateralIterator;
853 :
854 :
855 : }// end of namespace
856 :
857 : #endif
|