Branch data Line data Source code
1 : : #include "meshkit/CESets.hpp"
2 : :
3 : : #include <cassert>
4 : : #include <cstdlib>
5 : : #include <cstring>
6 : : #include <iMesh_extensions.h>
7 : :
8 : : #include <meshkit/Error.hpp>
9 : :
10 : : namespace MeshKit {
11 : :
12 : 34 : CESets::~CESets()
13 : : {
14 : 17 : std::vector<tag_data>::iterator i;
15 [ + + ]: 32 : for (i = tags_.begin(); i != tags_.end(); ++i)
16 : 15 : free(i->value);
17 : 17 : }
18 : :
19 : 15 : void CESets::add_tag(iMesh::TagHandle tag_handle, const char *value)
20 : : {
21 [ - + ]: 15 : assert(tag_handle != NULL);
22 : 15 : char *tmp = NULL;
23 : :
24 [ - + ]: 15 : if (value) {
25 : : int tag_size;
26 [ # # ][ # # ]: 0 : IBERRCHK(mesh_->getTagSizeBytes(tag_handle, tag_size), *mesh_);
27 : :
28 : 0 : tmp = static_cast<char*>(malloc(tag_size));
29 : 0 : memcpy(tmp, value, tag_size);
30 : : }
31 : :
32 [ + - ]: 15 : tags_.push_back(tag_data(tag_handle, tmp));
33 : 15 : }
34 : :
35 : 15 : void CESets::add_tag(const std::string &tag_name, const char *value)
36 : : {
37 : : iMesh::TagHandle tag_handle;
38 [ + - ][ + - ]: 15 : IBERRCHK(mesh_->getTagHandle(tag_name.c_str(), tag_handle), *mesh_);
39 [ + - ]: 15 : add_tag(tag_handle, value);
40 : 15 : }
41 : :
42 : 14 : void CESets::update_tagged_sets()
43 : : {
44 : : int err;
45 [ + - ]: 14 : iMesh::EntitySetHandle root_set = mesh_->getRootSet();
46 : :
47 : 14 : std::vector<tag_data>::const_iterator tag;
48 [ + - ][ + - ]: 28 : for (tag = tags_.begin(); tag != tags_.end(); ++tag) {
[ + - ][ + + ]
49 : 14 : iMesh::EntitySetHandle *tmp_sets = NULL;
50 : 14 : int tmp_sets_alloc = 0, tmp_sets_size;
51 [ + - ]: 14 : iMesh_getEntSetsByTagsRec(mesh_->instance(), root_set, &tag->tag,
52 [ + - ][ # # ]: 14 : (tag->value ? &tag->value : NULL), 1, false,
53 [ - + ][ + - ]: 28 : &tmp_sets, &tmp_sets_alloc, &tmp_sets_size, &err);
[ + - ]
54 [ + - ]: 14 : IBERRCHK(err, *mesh_);
55 [ + - ]: 14 : sets_.insert(tmp_sets, tmp_sets+tmp_sets_size);
56 : 14 : free(tmp_sets);
57 : : }
58 : 14 : }
59 : :
60 : 7 : void link_expand_sets(const CESets &ce_sets, iMesh::TagHandle local_tag)
61 : : {
62 [ + - ]: 7 : CESets::set_iterator set;
63 [ + - ][ + - ]: 19 : for (set = ce_sets.sbegin(); set != ce_sets.send(); ++set) {
[ + - ][ + - ]
[ + + ]
64 [ + - ][ + - ]: 12 : IBERRCHK(ce_sets.imesh_instance()->setEntSetESHData(*set, local_tag, *set),
[ + - ][ + - ]
[ + - ]
65 [ + - ]: 12 : *ce_sets.imesh_instance());
66 : : }
67 : 7 : }
68 : :
69 : : /**\brief Get the entities copied from a set
70 : : *
71 : : * Given a set and a tag, return the values of the tag set on entities from that
72 : : * set (i.e. the copied entities).
73 : : * \param mesh the iMesh instance handle
74 : : * \param set the set containing the entities we want
75 : : * \param local_tag the tag relating source and target entities
76 : : * \param ents a vector which will hold our copied entities
77 : : */
78 : : static
79 : 49 : void get_copied_ents(iMesh *mesh, iMesh::EntitySetHandle set,
80 : : iMesh::TagHandle local_tag,
81 : : std::vector<iMesh::EntityHandle> &ents)
82 : : {
83 [ + - ]: 49 : std::vector<iMesh::EntityHandle> tmp_ents;
84 [ + - ]: 49 : IBERRCHK(mesh->getEntities(set, iBase_ALL_TYPES, iMesh_ALL_TOPOLOGIES,
85 [ + - ]: 49 : tmp_ents), *mesh);
86 : :
87 [ + - ]: 49 : ents.reserve(tmp_ents.size());
88 : :
89 : : // get copied entities
90 [ + + ]: 152 : for (size_t i = 0; i < tmp_ents.size(); i++) {
91 : : iMesh::EntityHandle eh_tag;
92 [ + - ][ + - ]: 103 : iMesh::Error err = mesh->getEHData(tmp_ents[i], local_tag, eh_tag);
93 [ + + ][ + - ]: 103 : if (err == iBase_SUCCESS && eh_tag)
94 [ + - ]: 64 : ents.push_back(eh_tag);
95 : 49 : }
96 : 49 : }
97 : :
98 : : /**\brief Create a copy set if one doesn't exist yet
99 : : *
100 : : * Given a source set and a tag, create a destination (copy) set unless one
101 : : * already exists.
102 : : * \param mesh the iMesh instance handle
103 : : * \param local_tag the tag relating source and target sets
104 : : * \param src the source set
105 : : * \param dest the destination set
106 : : */
107 : : static
108 : 34 : void get_dest_set(iMesh *mesh, iMesh::TagHandle local_tag,
109 : : iMesh::EntitySetHandle src, iMesh::EntitySetHandle &dest)
110 : : {
111 : : iMesh::Error err;
112 : :
113 : 34 : err = mesh->getEntSetESHData(src, local_tag, dest);
114 : :
115 [ + + ]: 34 : if (err != iBase_SUCCESS) {
116 : 8 : IBERRCHK(mesh->createEntSet(false, dest), *mesh);
117 : 8 : IBERRCHK(mesh->setEntSetESHData(src, local_tag, dest), *mesh);
118 : : }
119 : 34 : }
120 : :
121 : : /**\brief Add copied entities/sets recursively
122 : : *
123 : : * Helper function for process_ce_sets. This adds any entities directly
124 : : * contained in the current set to the dest set and then loops through the
125 : : * contained sets and adds the children if they are also CE sets. If not, it
126 : : * adds the entities in the child set and recurses down a level.
127 : : * \param mesh the iMesh instance handle
128 : : * \param src the source set
129 : : * \param current the child set to examine (start with current == src)
130 : : * \param cesets the copy or expand sets to operate on
131 : : * \param local_tag the tag relating source and target sets
132 : : */
133 : : static
134 : 49 : void process_ce_subsets(iMesh *mesh, iMesh::EntitySetHandle src,
135 : : iMesh::EntitySetHandle current,
136 : : const std::set<iMesh::EntitySetHandle> &cesets,
137 : : iMesh::TagHandle local_tag)
138 : : {
139 : : iMesh::EntitySetHandle dest;
140 : :
141 : : // First, add entities directly contained in this set.
142 [ + - ]: 49 : std::vector<iMesh::EntityHandle> tmp_tags;
143 [ + - ]: 49 : get_copied_ents(mesh, current, local_tag, tmp_tags);
144 : :
145 [ + + ]: 49 : if (!tmp_tags.empty()) {
146 [ + - ]: 34 : get_dest_set(mesh, local_tag, src, dest);
147 [ + - ][ + - ]: 34 : IBERRCHK(mesh->addEntArrToSet(&tmp_tags[0], tmp_tags.size(), dest), *mesh);
[ + - ]
148 : : }
149 : :
150 : : // Next, start looking at children.
151 [ + - ]: 98 : std::vector<iMesh::EntitySetHandle> children;
152 [ + - ][ + - ]: 49 : IBERRCHK(mesh->getEntSets(current, 0, children), *mesh);
153 : :
154 [ + + ]: 57 : for (size_t i = 0; i < children.size(); i++) {
155 : :
156 : : // If this child set is one of our cesets, add just the set...
157 [ + - ][ + - ]: 8 : if (cesets.find(children[i]) != cesets.end()) {
[ + - ][ - + ]
158 [ # # ]: 0 : get_dest_set(mesh, local_tag, src, dest);
159 [ # # ]: 0 : if (src == dest) continue;
160 : :
161 [ # # ][ # # ]: 0 : IBERRCHK(mesh->addEntSet(children[i], dest), *mesh);
[ # # ]
162 : : }
163 : :
164 : : // ... otherwise, add the entities and recurse into the next level of
165 : : // children.
166 : : else {
167 [ + - ][ + - ]: 8 : process_ce_subsets(mesh, src, children[i], cesets, local_tag);
168 : : }
169 : 49 : }
170 : 49 : }
171 : :
172 : : // xxx - still need to do unique tags
173 : : // - for each unique tag
174 : : // . if this set has the tag, add/append to get unique value
175 : 32 : void process_ce_sets(iMesh *mesh,
176 : : const std::set<iMesh::EntitySetHandle> &cesets,
177 : : iMesh::TagHandle local_tag)
178 : : {
179 [ + - ]: 32 : std::set<iMesh::EntitySetHandle>::const_iterator src;
180 [ + - ][ + - ]: 73 : for (src = cesets.begin(); src != cesets.end(); ++src)
[ + + ]
181 [ + - ][ + - ]: 41 : process_ce_subsets(mesh, *src, *src, cesets, local_tag);
[ + - ]
182 : 32 : }
183 : :
184 : 4 : void tag_copy_sets(iMesh *mesh, iMesh::TagHandle copyTag,
185 : : const std::set<iMesh::EntitySetHandle> ©Sets,
186 : : iMesh::TagHandle tag, const char *tag_val)
187 : : {
188 : : iMesh::Error err;
189 : :
190 : : int tag_size;
191 [ + - ][ + - ]: 4 : IBERRCHK(mesh->getTagSizeBytes(tag, tag_size), *mesh);
192 : :
193 : : // allocate temp space for tag value
194 [ + - ]: 4 : std::vector<char> value(tag_size);
195 : :
196 : : // for each orig copy set with this tag, copy it to its copy
197 [ + - ]: 4 : std::set<iMesh::EntitySetHandle>::iterator set;
198 [ + - ][ + - ]: 12 : for (set = copySets.begin(); set != copySets.end(); ++set) {
[ + + ]
199 : : // get the tag value
200 [ + - ][ + - ]: 8 : err = mesh->getEntSetData(*set, tag, &value[0]);
[ + - ]
201 [ - + ]: 8 : if (err == iBase_TAG_NOT_FOUND)
202 : 5 : continue;
203 [ + - ]: 8 : IBERRCHK(err, *mesh);
204 : :
205 : : // compare to tag value if necessary
206 [ - + ][ # # ]: 8 : if (tag_val && strncmp(tag_val, &value[0], tag_size))
[ # # ][ - + ]
207 : 0 : continue;
208 : :
209 : : // if we got here, we should set the tag on the copy; get the copy
210 : : iMesh::EntitySetHandle copy_set;
211 [ + - ][ + - ]: 8 : err = mesh->getEntSetESHData(*set, copyTag, copy_set);
212 [ + + ]: 8 : if (err == iBase_TAG_NOT_FOUND)
213 : 5 : continue;
214 [ + - ]: 3 : IBERRCHK(err, *mesh);
215 : :
216 [ + - ][ + - ]: 3 : if (copy_set != *set)
217 [ + - ][ + - ]: 3 : IBERRCHK(mesh->setEntSetData(copy_set, tag, &value[0]), *mesh);
[ + - ]
218 : 4 : }
219 : 4 : }
220 : :
221 : 10 : void tag_copy_sets(const CESets &ce_sets, iMesh::TagHandle local_tag,
222 : : iMesh::TagHandle copy_tag)
223 : : {
224 : : // set the copy tag on all copied sets
225 [ + - ][ + - ]: 23 : for (CESets::const_set_iterator set = ce_sets.sbegin(); set != ce_sets.send();
[ + - ][ + - ]
[ + + ]
226 : : ++set) {
227 : : iMesh::Error err;
228 : : iMesh::EntityHandle eh;
229 [ + - ][ + - ]: 13 : err = ce_sets.imesh_instance()->getEntSetEHData(*set, local_tag, eh);
[ + - ]
230 [ + + ]: 13 : if (err == iBase_SUCCESS) {
231 [ + - ][ + - ]: 8 : IBERRCHK(ce_sets.imesh_instance()->setEntSetEHData(*set, copy_tag, eh),
[ + - ][ + - ]
232 [ + - ]: 8 : *ce_sets.imesh_instance());
233 : : }
234 : : }
235 : :
236 : : // tag the newly-created sets
237 [ + - ][ + - ]: 28 : for (CESets::const_tag_iterator tag = ce_sets.tbegin();
[ + - ][ + + ]
238 [ + - ]: 14 : tag != ce_sets.tend(); ++tag) {
239 [ + - ]: 4 : tag_copy_sets(ce_sets.imesh_instance(), copy_tag, ce_sets.sets(),
240 [ + - ][ + - ]: 8 : tag->tag, tag->value);
[ + - ][ + - ]
241 : : }
242 : 10 : }
243 : :
244 [ + - ][ + - ]: 156 : } // namespace MeshKit
|