Line data Source code
1 : /*
2 : * Copyright (c) 2010-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__LIBGRID__SUBSET_HANDLER_INTERFACE__
34 : #define __H__LIBGRID__SUBSET_HANDLER_INTERFACE__
35 :
36 : #include <list>
37 : #include <string>
38 : #include <vector>
39 : #include <map>
40 : #include "lib_grid/grid/grid.h"
41 : #include "lib_grid/common_attachments.h"
42 : #include "common/util/variant.h"
43 :
44 : namespace ug
45 : {
46 : ////////////////////////////////////////////////////////////////////////
47 : // predeclarations
48 : class ISubsetHandler;
49 :
50 : /** \ingroup lib_grid_tools
51 : * \{ */
52 :
53 : ////////////////////////////////////////////////////////////////////////
54 : // SubsetHandlerElements
55 : /// Use these constants to specify which elements shall be supported by a SubsetHandler.
56 : /**
57 : * You may combine the constants using or-operations.
58 : */
59 : enum SubsetHandlerElements
60 : {
61 : SHE_NONE = 0,
62 : SHE_VERTEX = 1,
63 : SHE_EDGE = 1<<1,
64 : SHE_FACE = 1<<2,
65 : SHE_VOLUME = 1 << 3,
66 : SHE_ALL = SHE_VERTEX | SHE_EDGE | SHE_FACE | SHE_VOLUME
67 : };
68 :
69 : ////////////////////////////////////////////////////////////////////////
70 : // SubsetState
71 : /// The SubsetState is not yet really used inside of libGrid.
72 : /**
73 : * The main reason why a SubsetState is introduced, is that
74 : * applications that use libGrid need a mechanism to store
75 : * information in a subset.
76 : * It would be a good idea to think about an attachment-like system
77 : * for subsets.
78 : */
79 : enum SubsetState
80 : {
81 : SS_NONE = 0,
82 : SS_USER_STATE = 1 << 16
83 : };
84 :
85 : ////////////////////////////////////////////////////////////////////////
86 : // SubsetInfo
87 : /// a struct that holds information associated with subsets.
88 : /**
89 : * The subset info can be used to store additional information with each subset.
90 : * On the one hand it features some often used entries like name and color,
91 : * on the other hand it features a property system, which allows to associate
92 : * custom properties with each subset. Note that the property system isn't that
93 : * fast, that it should be frequently used in performance critical sections of
94 : * the code.
95 : */
96 0 : struct SubsetInfo
97 : {
98 : SubsetInfo();
99 : std::string name;
100 : int materialIndex;///< mostly ignored.
101 : vector4 color;
102 : uint subsetState;///< an or-combination of SubsetState flags.
103 :
104 : typedef std::map<std::string, Variant> PropertyMap;
105 : /// custom properties can be stored in this map.
106 : /** One should access it through set_property and get_property.*/
107 : PropertyMap m_propertyMap;
108 :
109 : /// associate a property with the given name
110 : /** \{ */
111 : void set_property(const char* name, Variant prop);
112 : void set_property(const std::string& name, Variant prop);
113 : /** \} */
114 :
115 : /// retrieve the property with the given name
116 : /** You may optionally specify a default value, which will be returned if the
117 : * entry is not found.
118 : * \{ */
119 : Variant get_property(const char* name, Variant defaultValue = Variant()) const;
120 : Variant get_property(const std::string& name, Variant defaultValue = Variant()) const;
121 : /** \} */
122 : };
123 :
124 : /*
125 : ////////////////////////////////////////////////////////////////////////
126 : // specialization of attachment_traits for Vertex
127 : template<>
128 : class attachment_traits<Vertex*, ISubsetHandler>
129 : {
130 : public:
131 : typedef Vertex*& ElemRef;
132 : typedef Vertex* ElemPtr;
133 : typedef const Vertex* ConstElemPtr;
134 : typedef ISubsetHandler* ElemHandlerPtr;
135 : typedef const ISubsetHandler* ConstElemHandlerPtr;
136 :
137 : static inline void invalidate_entry(ElemHandlerPtr pHandler, ElemRef elem) {elem = NULL;}
138 : static inline bool entry_is_invalid(ElemHandlerPtr pHandler, ElemRef elem) {return elem != NULL;}
139 : static inline uint get_data_index(ElemHandlerPtr pHandler, ConstElemPtr elem);
140 : static inline void set_data_index(ElemHandlerPtr pHandler, ElemPtr elem, uint index);
141 : };
142 :
143 : // specialization of attachment_traits for Edge
144 : template<>
145 : class attachment_traits<Edge*, ISubsetHandler>
146 : {
147 : public:
148 : typedef Edge*& ElemRef;
149 : typedef Edge* ElemPtr;
150 : typedef const Edge* ConstElemPtr;
151 : typedef ISubsetHandler* ElemHandlerPtr;
152 : typedef const ISubsetHandler* ConstElemHandlerPtr;
153 :
154 : static inline void invalidate_entry(ElemHandlerPtr pHandler, ElemRef elem) {elem = NULL;}
155 : static inline bool entry_is_invalid(ElemHandlerPtr pHandler, ElemRef elem) {return elem != NULL;}
156 : static inline uint get_data_index(ElemHandlerPtr pHandler, ConstElemPtr elem);
157 : static inline void set_data_index(ElemHandlerPtr pHandler, ElemPtr elem, uint index);
158 : };
159 :
160 : // specialization of attachment_traits for Face
161 : template<>
162 : class attachment_traits<Face*, ISubsetHandler>
163 : {
164 : public:
165 : typedef Face*& ElemRef;
166 : typedef Face* ElemPtr;
167 : typedef const Face* ConstElemPtr;
168 : typedef ISubsetHandler* ElemHandlerPtr;
169 : typedef const ISubsetHandler* ConstElemHandlerPtr;
170 :
171 : static inline void invalidate_entry(ElemHandlerPtr pHandler, ElemRef elem) {elem = NULL;}
172 : static inline bool entry_is_invalid(ElemHandlerPtr pHandler, ElemRef elem) {return elem != NULL;}
173 : static inline uint get_data_index(ElemHandlerPtr pHandler, ConstElemPtr elem);
174 : static inline void set_data_index(ElemHandlerPtr pHandler, ElemPtr elem, uint index);
175 : };
176 :
177 : // specialization of attachment_traits for Volume
178 : template<>
179 : class attachment_traits<Volume*, ISubsetHandler>
180 : {
181 : public:
182 : typedef Volume*& ElemRef;
183 : typedef Volume* ElemPtr;
184 : typedef const Volume* ConstElemPtr;
185 : typedef ISubsetHandler* ElemHandlerPtr;
186 : typedef const ISubsetHandler* ConstElemHandlerPtr;
187 :
188 : static inline void invalidate_entry(ElemHandlerPtr pHandler, ElemRef elem) {elem = NULL;}
189 : static inline bool entry_is_invalid(ElemHandlerPtr pHandler, ElemRef elem) {return elem != NULL;}
190 : static inline uint get_data_index(ElemHandlerPtr pHandler, ConstElemPtr elem);
191 : static inline void set_data_index(ElemHandlerPtr pHandler, ElemPtr elem, uint index);
192 : };
193 : */
194 :
195 : ////////////////////////////////////////////////////////////////////////
196 : // ISubsetHandler
197 : /** A derived class has to implement the following public methods:
198 : * <code>
199 : * virtual void assign_subset(Vertex* elem, int subsetIndex)
200 : * virtual void assign_subset(Edge* elem, int subsetIndex)
201 : * virtual void assign_subset(Face* elem, int subsetIndex)
202 : * virtual void assign_subset(Volume* elem, int subsetIndex)
203 : * </code>
204 : *
205 : * In those methods
206 : * Derived classes have to store the objects that are selected for
207 : * a subset in a ISubsetHandler::SectionContainer. Note that multiple
208 : * SectionContainers per subset may be used.
209 : *
210 : * A SubsetHandler also supports subset-attachments.
211 : * That means that you can attach data to the elements of a subset.
212 : * Use attach_to_vertices, attach_to_edges, ... to attach data to
213 : * the elements of the subset.
214 : * use ISubsetHandler::VertexAttachmentAccessor, ... to access the
215 : * attached data.
216 : * Please note that you may only use a subset-attachment-accessor
217 : * with elements that are contained in the subset for which the
218 : * accessor has been created.
219 : *
220 : * Subset-attachments currently do not support pass-on behaviours.
221 : */
222 : class UG_API ISubsetHandler : public GridObserver
223 : {/*
224 : friend class attachment_traits<Vertex*, ISubsetHandler>;
225 : friend class attachment_traits<Edge*, ISubsetHandler>;
226 : friend class attachment_traits<Face*, ISubsetHandler>;
227 : friend class attachment_traits<Volume*, ISubsetHandler>;*/
228 :
229 : public:/*
230 : typedef AttachmentPipe<Vertex*, ISubsetHandler> VertexAttachmentPipe;
231 : typedef AttachmentPipe<Edge*, ISubsetHandler> EdgeAttachmentPipe;
232 : typedef AttachmentPipe<Face*, ISubsetHandler> FaceAttachmentPipe;
233 : typedef AttachmentPipe<Volume*, ISubsetHandler> VolumeAttachmentPipe;*/
234 :
235 : /// The traits class holds some important types for each element-type
236 : template <class TElem>
237 : struct traits{
238 : typedef typename geometry_traits<TElem>::iterator iterator;
239 : typedef typename geometry_traits<TElem>::const_iterator const_iterator;
240 : };
241 :
242 : public:
243 : /// pass an or-combination of SubsetHandlerElements to supportedElements.
244 : /** supportedElements define the elements on which the SubsetHandler works.
245 : * Default is SHE_ALL (all element-types).*/
246 : ISubsetHandler(uint supportedElements = SHE_ALL);
247 :
248 : /// pass a grid and an or-combination of SubsetHandlerElements to supportedElements.
249 : /** supportedElements define the elements on which the SubsetHandler works.
250 : * Default is SHE_ALL (all element-types).*/
251 : ISubsetHandler(Grid& grid, uint supportedElements = SHE_ALL);
252 :
253 : /** The destructor automatically unregisters the subset-handler from the grid.
254 : * on deregistration erase_subset_lists of the derived class will be called.*/
255 : virtual ~ISubsetHandler();
256 :
257 : /// assigns subsets based on the subsets in the given subset-handler
258 : /** Elements of this handler will be assigned to subsets based on their
259 : * order in the underlying grids.
260 : * The underlying grid of this handler will not be changed. This is particularly
261 : * useful if you just copied a grid and if you now want to copy the subsets
262 : * in the associated subset-handlers.
263 : *
264 : * Please note, that attachments are not copied in the current version.*/
265 : ISubsetHandler& operator = (const ISubsetHandler& sh);
266 :
267 : /// returns a pointer to the grid on which the subset-handler works.
268 : /** returns NULL if no grid is assigned.*/
269 : Grid* grid() const;
270 :
271 : /// returns true if the given element-types are supported.
272 : /** pass an or-combination of constants enumerated in SubsetHandlerElements.*/
273 : bool elements_are_supported(uint shElements) const;
274 :
275 : /// set the type of elements that shall be handled by the SubsetHandler.
276 : /** Pass an or-combination of constants enumerated in SubsetHandlerElements.
277 : * \sa SubsetHandler::enable_element_support*/
278 : void set_supported_elements(uint shElements);
279 :
280 : /// enable support for element-types. Does not invalidate previous settings.
281 : /** pass an or-combination of constants enumerated in SubsetHandlerElements.*/
282 : void enable_element_support(uint shElements);
283 :
284 : /// disable support for element-types.
285 : /** pass an or-combination of constants enumerated in SubsetHandlerElements.*/
286 : void disable_element_support(uint shElements);
287 :
288 : /** new elements will be automatically assigned to this subset.
289 : * set this to a negative value to avoid automatic assignment (-1 by default).
290 : * only used if subset_inheritance is disabled or if no parent is specified.*/
291 : void set_default_subset_index(int subsetIndex);
292 0 : inline int get_default_subset_index() {return m_defaultSubsetIndex;}
293 :
294 : /** if enabled, newly created elements derive their subset-index from their parents.
295 : * Enabled by default.
296 : * If enabled, the default subset index will be ignored if a parent is specified
297 : * on element creation.*/
298 : void enable_subset_inheritance(bool bEnable);
299 0 : inline bool subset_inheritance_enabled() {return m_bSubsetInheritanceEnabled;}
300 :
301 : /** restricts subset inheritance so that new elements derive their
302 : * subset index only from parents with the same base-type.
303 : * Disabled by default.
304 : * NOTE: strict inheritance only has an effect if
305 : * subset inheritance is enabled.*/
306 : void enable_strict_inheritance(bool bEnable);
307 : inline bool strict_inheritance_enabled() {return m_bStrictInheritanceEnabled;}
308 :
309 : /// if the subset with the given index does not yet exist, it will be created.
310 : /** All subsets in between num_subsets and index will be created, too.*/
311 : inline void subset_required(int index);
312 :
313 : /// throws an error if the given index is equal or higher than num_subsets.
314 : inline void subset_required(int index) const;
315 :
316 : /// returns the number of subset-infos (return value is int, since SubsetIndices are of type int)
317 0 : inline int num_subsets() const {return (int)m_subsetInfos.size();}
318 :
319 : /// returns the name of a subset
320 : const char* get_subset_name(int subsetIndex) const;
321 :
322 : /// sets the name of a subset
323 : void set_subset_name(const char* name, int subsetIndex);
324 :
325 : ////////////////////////////////
326 : /** if the subset at subsetIndex does not yet exist, it will be created.*/
327 : void set_subset_info(int subsetIndex, const SubsetInfo& subsetInfo);
328 :
329 : /** if the subset at subsetIndex does not yet exist, it will be created.*/
330 : SubsetInfo& subset_info(int subsetIndex);
331 :
332 : /** Be careful: queried subset has to exist! Check with num_subsets()*/
333 : const SubsetInfo& subset_info(int subsetIndex) const;
334 :
335 : /// sets the default subset-info. Used when initializing new subset-infos.
336 : void set_default_subset_info(const SubsetInfo& defSI);
337 :
338 : ////////////////////////////////
339 : // clear methods
340 : void clear();
341 : void clear_subset(int subsetIndex);
342 : void clear_subsets();
343 :
344 :
345 : /// inserts a subset at the given index. Moves all other subsets 1 index higher.
346 : void insert_subset(int subsetIndex);///< changes subset-indices of other subsets.
347 : /// erases the subset at the given index. Assigns -1 to all entries. Moves all other subsets 1 index up.
348 : void erase_subset(int subsetIndex);///< changes subset-indices of other subsets.
349 : /// Swaps the given subsets,
350 : void swap_subsets(int subsetIndex1, int subsetIndex2);
351 : /// Moves the subset from index From to index To. Moves all subsets between indexFrom+1 and indexTo in the opposite direction.
352 : void move_subset(int indexFrom, int indexTo);///< changes subset indices of other subsets.
353 : /// Joins two subsets into a new one. Optionally erases the old subsets, if they are no longer used.
354 : void join_subsets(int targetSub, int sub1, int sub2, bool eraseUnusedSubs);
355 :
356 : template <class TIterator>
357 : void assign_subset(TIterator iterBegin, TIterator iterEnd, int subsetIndex);
358 :
359 : int get_subset_index(GridObject* elem) const;
360 : inline int get_subset_index(Vertex* elem) const;
361 : inline int get_subset_index(Edge* elem) const;
362 : inline int get_subset_index(Face* elem) const;
363 : inline int get_subset_index(Volume* elem) const;
364 :
365 : /// returns the index of the first subset with the given name.
366 : /** If no subset with the given name exists, -1 is returned.
367 : *
368 : * This method takes O(NumSubsets) time.*/
369 : int get_subset_index(const char* name) const;
370 :
371 : // grid callbacks
372 : //virtual void registered_at_grid(Grid* grid);
373 : //virtual void unregistered_from_grid(Grid* grid);
374 : virtual void grid_to_be_destroyed(Grid* grid);
375 : virtual void elements_to_be_cleared(Grid* grid);
376 :
377 : // element callbacks
378 : virtual void vertex_created(Grid* grid, Vertex* vrt,
379 : GridObject* pParent = NULL,
380 : bool replacesParent = false);
381 :
382 : virtual void edge_created(Grid* grid, Edge* e,
383 : GridObject* pParent = NULL,
384 : bool replacesParent = false);
385 :
386 : virtual void face_created(Grid* grid, Face* f,
387 : GridObject* pParent = NULL,
388 : bool replacesParent = false);
389 :
390 : virtual void volume_created(Grid* grid, Volume* vol,
391 : GridObject* pParent = NULL,
392 : bool replacesParent = false);
393 :
394 : virtual void vertex_to_be_erased(Grid* grid, Vertex* vrt,
395 : Vertex* replacedBy = NULL);
396 :
397 : virtual void edge_to_be_erased(Grid* grid, Edge* e,
398 : Edge* replacedBy = NULL);
399 :
400 : virtual void face_to_be_erased(Grid* grid, Face* f,
401 : Face* replacedBy = NULL);
402 :
403 : virtual void volume_to_be_erased(Grid* grid, Volume* vol,
404 : Volume* replacedBy = NULL);
405 :
406 : virtual void vertices_to_be_merged(Grid* grid, Vertex* target,
407 : Vertex* elem1, Vertex* elem2);
408 :
409 : virtual void edges_to_be_merged(Grid* grid, Edge* target,
410 : Edge* elem1, Edge* elem2);
411 :
412 : virtual void faces_to_be_merged(Grid* grid, Face* target,
413 : Face* elem1, Face* elem2);
414 :
415 : virtual void volumes_to_be_merged(Grid* grid, Volume* target,
416 : Volume* elem1, Volume* elem2);
417 :
418 : // Virtual methods for derived classes
419 : /** The implementation in a derived class should store the element in a list
420 : * and call subset_assigned with the iterators position and the subset-index.
421 : * The iterator can later be retrieved with get_list_iterator(...).
422 : * The index can be retrieved with get_subset_index(...).*/
423 : virtual void assign_subset(Vertex* elem, int subsetIndex) = 0;
424 :
425 : /** The implementation in a derived class should store the element in a list
426 : * and call subset_assigned with the iterators position and the subset-index.
427 : * The iterator can later be retrieved with get_list_iterator(...).
428 : * The index can be retrieved with get_subset_index(...).*/
429 : virtual void assign_subset(Edge* elem, int subsetIndex) = 0;
430 :
431 : /** The implementation in a derived class should store the element in a list
432 : * and call subset_assigned with the iterators position and the subset-index.
433 : * The iterator can later be retrieved with get_list_iterator(...).
434 : * The index can be retrieved with get_subset_index(...).*/
435 : virtual void assign_subset(Face* elem, int subsetIndex) = 0;
436 :
437 : /** The implementation in a derived class should store the element in a list
438 : * and call subset_assigned with the iterators position and the subset-index.
439 : * The iterator can later be retrieved with get_list_iterator(...).
440 : * The index can be retrieved with get_subset_index(...).*/
441 : virtual void assign_subset(Volume* elem, int subsetIndex) = 0;
442 :
443 : /** Forwards the call to the assign_subset method for the specific type
444 : * (e.g. Vertex, Edge, Face, Volume).*/
445 : virtual void assign_subset(GridObject* elem, int subsetIndex);
446 :
447 : /// collects all vertices that are in the given subset.
448 : /** Please note: This method should only be used, if the begin and end methods
449 : * of derived classes are not available.*/
450 : //virtual size_t collect_subset_elements(std::vector<Vertex*>& vrtsOut,
451 : // int subsetIndex) const = 0;
452 :
453 : /// collects all edges that are in the given subset.
454 : /** Please note: This method should only be used, if the begin and end methods
455 : * of derived classes are not available.*/
456 : //virtual size_t collect_subset_elements(std::vector<Edge*>& edgesOut,
457 : // int subsetIndex) const = 0;
458 :
459 : /// collects all faces that are in the given subset.
460 : /** Please note: This method should only be used, if the begin and end methods
461 : * of derived classes are not available.*/
462 : //virtual size_t collect_subset_elements(std::vector<Face*>& facesOut,
463 : // int subsetIndex) const = 0;
464 :
465 : /// collects all volumes that are in the given subset.
466 : /** Please note: This method should only be used, if the begin and end methods
467 : * of derived classes are not available.*/
468 : //virtual size_t collect_subset_elements(std::vector<Volume*>& volsOut,
469 : // int subsetIndex) const = 0;
470 :
471 : /// returns true if the subset contains vertices
472 : virtual bool contains_vertices(int subsetIndex) const = 0;
473 :
474 : /// returns true if the subset contains edges
475 : virtual bool contains_edges(int subsetIndex) const = 0;
476 :
477 : /// returns true if the subset contains faces
478 : virtual bool contains_faces(int subsetIndex) const = 0;
479 :
480 : /// returns true if the subset contains volumes
481 : virtual bool contains_volumes(int subsetIndex) const = 0;
482 :
483 : /// Returns the geometric object collection for the given subset.
484 : /** Note that the GOC may contain multiple levels.*/
485 : virtual GridObjectCollection
486 : get_grid_objects_in_subset(int subsetInd) const = 0;
487 :
488 : ////////////////////////////////
489 : // attachments
490 :
491 : /// enable subset-attachment support
492 : /** if subset-attachments are enabled you may attach data to the elements
493 : * of a subset. This is useful if you want to store different data in the
494 : * elements of different subsets.*/
495 : //void enable_subset_attachments(bool bEnable);
496 :
497 : /// returns true if subset-attachments are enabled.
498 : /*inline bool subset_attachments_are_enabled() {return m_bSubsetAttachmentsEnabled;};
499 :
500 : inline uint get_attachment_data_index(const Vertex* v) const {return m_aaDataIndVRT[v];}
501 : inline uint get_attachment_data_index(const Edge* e) const {return m_aaDataIndEDGE[e];}
502 : inline uint get_attachment_data_index(const Face* f) const {return m_aaDataIndFACE[f];}
503 : inline uint get_attachment_data_index(const Volume* v) const {return m_aaDataIndVOL[v];}
504 : */
505 : /// attach with unspecified default value.
506 : /** Pass either Vertex, Edge, Face or Volume as TGeomObjClass.*/
507 : /*template <class TGeomObjClass>
508 : inline void attach_to(IAttachment& attachment, int subsetIndex);
509 : */
510 : /// attach with specified default value
511 : /** Pass either Vertex, Edge, Face or Volume as TGeomObjClass.*/
512 : /*template <class TGeomObjClass, class TAttachment>
513 : void attach_to_dv(TAttachment& attachment, int subsetIndex,
514 : const typename TAttachment::ValueType& defaultValue);
515 : */
516 : // detach
517 : /** Pass either Vertex, Edge, Face or Volume as TGeomObjClass.*/
518 : /*template <class TGeomObjClass>
519 : void detach_from(IAttachment& attachment, int subsetIndex);
520 : */
521 : ////////////////////////////////
522 : // attachments helper
523 : // attach with attachments default pass-on behaviour
524 : /*inline void attach_to_vertices(IAttachment& attachment, int subsetIndex) {attach_to<Vertex>(attachment, subsetIndex);}
525 : inline void attach_to_edges(IAttachment& attachment, int subsetIndex) {attach_to<Edge>(attachment, subsetIndex);}
526 : inline void attach_to_faces(IAttachment& attachment, int subsetIndex) {attach_to<Face>(attachment, subsetIndex);}
527 : inline void attach_to_volumes(IAttachment& attachment, int subsetIndex) {attach_to<Volume>(attachment, subsetIndex);}
528 : */
529 : // attach with default value and attachments default pass-on behaviour
530 : /*template <class TAttachment>
531 : inline void attach_to_vertices_dv(TAttachment& attachment, int subsetIndex, const typename TAttachment::ValueType& defaultValue) {attach_to_dv<Vertex>(attachment, subsetIndex, defaultValue);}
532 : template <class TAttachment>
533 : inline void attach_to_edges_dv(TAttachment& attachment, int subsetIndex, const typename TAttachment::ValueType& defaultValue) {attach_to_dv<Edge>(attachment, subsetIndex, defaultValue);}
534 : template <class TAttachment>
535 : inline void attach_to_faces_dv(TAttachment& attachment, int subsetIndex, const typename TAttachment::ValueType& defaultValue) {attach_to_dv<Face>(attachment, subsetIndex, defaultValue);}
536 : template <class TAttachment>
537 : inline void attach_to_volumes_dv(TAttachment& attachment, int subsetIndex, const typename TAttachment::ValueType& defaultValue) {attach_to_dv<Volume>(attachment, subsetIndex, defaultValue);}
538 : */
539 : // detach
540 : /*inline void detach_from_vertices(IAttachment& attachment, int subsetIndex) {detach_from<Vertex>(attachment, subsetIndex);}
541 : inline void detach_from_edges(IAttachment& attachment, int subsetIndex) {detach_from<Edge>(attachment, subsetIndex);}
542 : inline void detach_from_faces(IAttachment& attachment, int subsetIndex) {detach_from<Face>(attachment, subsetIndex);}
543 : inline void detach_from_volumes(IAttachment& attachment, int subsetIndex) {detach_from<Volume>(attachment, subsetIndex);}
544 : */
545 : /// returns the attachment data container for elements of type TGeomObj for the given subset.
546 : /** Use the data-container with care! You should never clear or resize it.
547 : *
548 : * Valid types for TGeomObj are Vertex, Edge, Face and Volume.
549 : * call it like this (let sh be an instance of ISubsetHandler):
550 : * sh.get_attachment_data_container<Vertex>(aSomeAttachment, someSubsetIndex);*/
551 : /*template <class TGeomObj, class TAttachment>
552 : inline typename TAttachment::ContainerType*
553 : get_attachment_data_container(TAttachment& attachment, int subsetIndex);
554 : */
555 : protected:
556 : typedef Grid::traits<Vertex>::AttachedElementList AttachedVertexList;
557 : typedef Grid::traits<Edge>::AttachedElementList AttachedEdgeList;
558 : typedef Grid::traits<Face>::AttachedElementList AttachedFaceList;
559 : typedef Grid::traits<Volume>::AttachedElementList AttachedVolumeList;
560 :
561 : typedef Grid::traits<Vertex>::SectionContainer VertexSectionContainer;
562 : typedef Grid::traits<Edge>::SectionContainer EdgeSectionContainer;
563 : typedef Grid::traits<Face>::SectionContainer FaceSectionContainer;
564 : typedef Grid::traits<Volume>::SectionContainer VolumeSectionContainer;
565 :
566 : protected:
567 : /// selects elements based on the selection in the srcHandler
568 : /** WARNING: This method calls virtual functions. Be careful when using it
569 : * in a constructor.*/
570 : void assign_subset_handler(const ISubsetHandler& sh);
571 :
572 : /// set the grid on which the subset-handler shall work.
573 : /** The subset-handler can only work on one grid at a time.
574 : * It is crucial that assign_grid methods of derived classes call
575 : * this method.
576 : *
577 : * Please note: sine set_grid calls virtual methods it shouldn't
578 : * be invoked from any constructors / destructors.*/
579 : void set_grid(Grid* grid);
580 :
581 : /// sets the subset-indices of all elements of m_pGrid to -1.
582 : /** Use with care! Only indices are affected. The elements are not
583 : * removed from any lists.
584 : * pass an or-combination of constants enumerated in SubsetHandlerElements.*/
585 : void reset_subset_indices(uint shElements = SHE_ALL);
586 :
587 : /// creates all required infos (and pipes) up to the given index.
588 : void create_required_subsets(int index);
589 :
590 : inline void subset_assigned(Vertex* v, int subsetIndex);
591 : inline void subset_assigned(Edge* e, int subsetIndex);
592 : inline void subset_assigned(Face* f, int subsetIndex);
593 : inline void subset_assigned(Volume* v, int subsetIndex);
594 :
595 : /** alters the subset index only. Suited as a helper for methods like
596 : * change_subset_indices or reset_subset_indices.
597 : * WARNING: This method only alters the index but does not actually
598 : * move the element to another subset. Use assign_subset instead for this task.*/
599 0 : inline void alter_subset_index(Vertex* v, int subsetIndex) {m_aaSubsetIndexVRT[v] = subsetIndex;}
600 : /** alters the subset index only. Suited as a helper for methods like
601 : * change_subset_indices or reset_subset_indices.
602 : * WARNING: This method only alters the index but does not actually
603 : * move the element to another subset. Use assign_subset instead for this task.*/
604 0 : inline void alter_subset_index(Edge* e, int subsetIndex) {m_aaSubsetIndexEDGE[e] = subsetIndex;}
605 : /** alters the subset index only. Suited as a helper for methods like
606 : * change_subset_indices or reset_subset_indices.
607 : * WARNING: This method only alters the index but does not actually
608 : * move the element to another subset. Use assign_subset instead for this task.*/
609 0 : inline void alter_subset_index(Face* f, int subsetIndex) {m_aaSubsetIndexFACE[f] = subsetIndex;}
610 : /** alters the subset index only. Suited as a helper for methods like
611 : * change_subset_indices or reset_subset_indices.
612 : * WARNING: This method only alters the index but does not actually
613 : * move the element to another subset. Use assign_subset instead for this task.*/
614 0 : inline void alter_subset_index(Volume* v, int subsetIndex) {m_aaSubsetIndexVOL[v] = subsetIndex;}
615 :
616 : virtual void erase_subset_lists() = 0;
617 :
618 : virtual void clear_subset_lists(int index) = 0;
619 :
620 : virtual void change_subset_indices(int indOld, int indNew) = 0;
621 :
622 :
623 : /// add a subset if required - so that the subset with maxIndex exists.
624 : virtual void add_required_subset_lists(int maxIndex) = 0;
625 :
626 : /// erase the subset-lists but do not touch the subset-indices.
627 : virtual void erase_subset_lists(int index) = 0;
628 :
629 : /// swap the subset-lists but do not touch the subset-indices.
630 : virtual void swap_subset_lists(int ind1, int ind2) = 0;
631 :
632 : /// move the subset-lists but do not touch the subset-indices.
633 : virtual void move_subset_lists(int indexFrom, int indexTo) = 0;
634 :
635 : /// join the subset-lists but do not touch the subset-indices.
636 : virtual void join_subset_lists(int target, int src1, int src2) = 0;
637 :
638 : /// helper for GridObserver callbacks.
639 : template <class TElem>
640 : void elems_to_be_merged(Grid* grid, TElem* target,
641 : TElem* elem1, TElem* elem2);
642 :
643 : ////////////////////////////////
644 : // attachments
645 : /*inline void set_attachment_data_index(Vertex* v, uint index) {m_aaDataIndVRT[v] = index;}
646 : inline void set_attachment_data_index(Edge* e, uint index) {m_aaDataIndEDGE[e] = index;}
647 : inline void set_attachment_data_index(Face* f, uint index) {m_aaDataIndFACE[f] = index;}
648 : inline void set_attachment_data_index(Volume* v, uint index) {m_aaDataIndVOL[v] = index;}
649 :
650 : void resize_attachment_pipes(size_t newSize);
651 : void clear_attachment_pipes(int subsetIndex);
652 : void clear_attachment_pipes();
653 :
654 : template <class TGeomObj>
655 : inline AttachmentPipe<TGeomObj*, ISubsetHandler>&
656 : get_attachment_pipe(int subsetIndex);
657 : */
658 : ////////////////////////////////
659 : // virtual methods for attachments
660 : /// this method is called by ISubsetHandler when attachment_support has been enabled.
661 : /** derived classes have to implement this method.
662 : * during this method they have to call register_at_pipe for all elements
663 : * that are contained in one of the subsets.
664 : * WARNING: This method is crucial for the attachment system.
665 : * You should never call it yourself.*/
666 : //virtual void register_subset_elements_at_pipe() = 0;
667 :
668 : /// this method should be called during \sa register_subset_elements_at_pipe.
669 : /** WARNING: This method is crucial for the attachment system.
670 : * You should only call it during \sa register_subset_elements_at_pipe
671 : * Only call this method for elements that are contained in a subset.*/
672 : //inline void register_at_pipe(Vertex* elem) {m_vertexAttachmentPipes[get_subset_index(elem)]->register_element(elem);}
673 :
674 : /// this method should be called x \sa register_subset_elements_at_pipe.
675 : /** WARNING: This method is crucial for the attachment system.
676 : * You should only call it during \sa register_subset_elements_at_pipe
677 : * Only call this method for elements that are contained in a subset.*/
678 : //inline void register_at_pipe(Edge* elem) {m_edgeAttachmentPipes[get_subset_index(elem)]->register_element(elem);}
679 :
680 : /// this method should be called during \sa register_subset_elements_at_pipe.
681 : /** WARNING: This method is crucial for the attachment system.
682 : * You should only call it during \sa register_subset_elements_at_pipe
683 : * Only call this method for elements that are contained in a subset.*/
684 : //inline void register_at_pipe(Face* elem) {m_faceAttachmentPipes[get_subset_index(elem)]->register_element(elem);}
685 :
686 : /// this method should be called during \sa register_subset_elements_at_pipe.
687 : /** WARNING: This method is crucial for the attachment system.
688 : * You should only call it during \sa register_subset_elements_at_pipe
689 : * Only call this method for elements that are contained in a subset.*/
690 : //inline void register_at_pipe(Volume* elem) {m_volumeAttachmentPipes[get_subset_index(elem)]->register_element(elem);}
691 :
692 : public:
693 : /// attachment accessor grants access to data associated with elements of a subset.
694 : /** Valid types for TGeomObj are Vertex, Edge, Face and Volume*/
695 : /*template <class TGeomObj, class TAttachment>
696 : class AttachmentAccessor : public ug::AttachmentAccessor<TGeomObj*, TAttachment, ISubsetHandler>
697 : {
698 : protected:
699 : typedef ug::AttachmentAccessor<TGeomObj*, TAttachment, ISubsetHandler> BaseClass;
700 :
701 : public:
702 : AttachmentAccessor() {}
703 : AttachmentAccessor(const AttachmentAccessor& aa) : BaseClass(aa) {}
704 : AttachmentAccessor(ISubsetHandler& sh, TAttachment& a, int subsetIndex) : BaseClass(sh.get_attachment_pipe<TGeomObj>(subsetIndex), a) {}
705 :
706 : inline void access(ISubsetHandler& sh, TAttachment& a, int subsetIndex)
707 : {BaseClass::access(sh.get_attachment_pipe<TGeomObj>(subsetIndex), a);}
708 : };*/
709 :
710 :
711 : /// the multi-subset-attachment-accessor allows to access an attachment that has been attached to multiple subsets.
712 : /** Note that this accessor is slower than the normal attachment-accessors.
713 : * If subsets are added to the subset-handler or attachments are added/removed,
714 : * you should not rely on the accessor to still work properly.
715 : * Call access() in that case to re-validate him.*/
716 : /*
717 : template <class TAttachmet, class TGeomBaseObj>
718 : class MultiSubsetAttachmentAccessor
719 : {
720 : //TODO: implement this!
721 : };
722 : */
723 : private:
724 : ISubsetHandler(const ISubsetHandler& sh) {};
725 :
726 : protected:
727 : typedef AInt ASubsetIndex;
728 : //typedef Attachment<uint> ADataIndex;
729 : typedef std::vector<SubsetInfo> SubsetInfoVec;
730 : /*typedef std::vector<VertexAttachmentPipe*> VertexAttachmentPipeVec;
731 : typedef std::vector<EdgeAttachmentPipe*> EdgeAttachmentPipeVec;
732 : typedef std::vector<FaceAttachmentPipe*> FaceAttachmentPipeVec;
733 : typedef std::vector<VolumeAttachmentPipe*> VolumeAttachmentPipeVec;*/
734 :
735 : protected:
736 : Grid* m_pGrid;
737 : /*VertexAttachmentPipeVec m_vertexAttachmentPipes;
738 : EdgeAttachmentPipeVec m_edgeAttachmentPipes;
739 : FaceAttachmentPipeVec m_faceAttachmentPipes;
740 : VolumeAttachmentPipeVec m_volumeAttachmentPipes;*/
741 :
742 : SubsetInfoVec m_subsetInfos;
743 : SubsetInfo m_defaultSubsetInfo;
744 : uint m_supportedElements;
745 :
746 : ASubsetIndex m_aSubsetIndex;
747 : //ADataIndex m_aDataIndex;
748 :
749 : int m_defaultSubsetIndex;
750 : bool m_bSubsetInheritanceEnabled;
751 : bool m_bStrictInheritanceEnabled;
752 : //bool m_bSubsetAttachmentsEnabled;
753 :
754 : Grid::VertexAttachmentAccessor<ASubsetIndex> m_aaSubsetIndexVRT;
755 : Grid::EdgeAttachmentAccessor<ASubsetIndex> m_aaSubsetIndexEDGE;
756 : Grid::FaceAttachmentAccessor<ASubsetIndex> m_aaSubsetIndexFACE;
757 : Grid::VolumeAttachmentAccessor<ASubsetIndex> m_aaSubsetIndexVOL;
758 : /*
759 : Grid::VertexAttachmentAccessor<ADataIndex> m_aaDataIndVRT;
760 : Grid::EdgeAttachmentAccessor<ADataIndex> m_aaDataIndEDGE;
761 : Grid::FaceAttachmentAccessor<ADataIndex> m_aaDataIndFACE;
762 : Grid::VolumeAttachmentAccessor<ADataIndex> m_aaDataIndVOL;*/
763 : };
764 :
765 : /** \} */
766 :
767 : }// end of namespace
768 :
769 : ////////////////////////////////////////////////
770 : // include implementation
771 : #include "subset_handler_interface_impl.hpp"
772 :
773 : #endif
|