Branch data Line data Source code
1 : : #include "meshkit/MergeMesh.hpp"
2 : :
3 : : #include <algorithm>
4 : : #include <cstdlib>
5 : : #include <cstring>
6 : : #include <functional>
7 : : #include <string>
8 : : #include <vector>
9 : : #include <cassert>
10 : : #include <iostream>
11 : :
12 : : #include "moab/Skinner.hpp"
13 : : #include "moab/AdaptiveKDTree.hpp"
14 : : #include "moab/Range.hpp"
15 : : #include "moab/CartVect.hpp"
16 : :
17 : : namespace MeshKit
18 : : {
19 : : // static registration of this mesh scheme
20 : : moab::EntityType MergeMesh_tps[] = { moab::MBVERTEX,
21 : : moab::MBEDGE,
22 : : moab::MBTRI,
23 : : moab::MBHEX,
24 : : moab::MBMAXTYPE};
25 : :
26 : 40 : const moab::EntityType* MergeMesh::output_types()
27 : 40 : { return MergeMesh_tps; }
28 : :
29 : 1 : MergeMesh::MergeMesh(MKCore *mkcore, const MEntVector &me_vec)
30 : : : MeshScheme(mkcore, me_vec),
31 [ + - ][ + - ]: 1 : imeshImpl(mkcore->imesh_instance()), mbImpl (mkcore->moab_instance())
[ + - ]
32 : : {
33 : 1 : mergeTol = 1e-4;
34 : 1 : updateSets = 0;
35 : 1 : doMerge = 1;
36 : 1 : mergeTag = NULL;
37 : 1 : }
38 : :
39 : 3 : MergeMesh::~MergeMesh()
40 : : {
41 [ + - ]: 1 : if (mbMergeTag) mbImpl->tag_delete(mbMergeTag);
42 [ - + ]: 2 : }
43 : :
44 : 0 : bool MergeMesh::add_modelent(ModelEnt *model_ent)
45 : : {
46 : 0 : return MeshOp::add_modelent(model_ent);
47 : : }
48 : :
49 : 1 : void MergeMesh::set_merge_params(double merge_tol, int updatesets,
50 : : int domerge, iBase_TagHandle merge_tag)
51 : : {
52 : 1 : mergeTol = merge_tol;
53 : 1 : updateSets = updatesets;
54 : 1 : doMerge = domerge;
55 : 1 : mergeTag = merge_tag;
56 : 1 : }
57 : :
58 : 1 : void MergeMesh::setup_this()
59 : : {
60 : 1 : std::cout << "IN SETUPTHIS MERGEMESH " << std::endl;
61 : :
62 : 1 : }
63 : :
64 : 1 : void MergeMesh::execute_this()
65 : : {
66 [ + - ][ + - ]: 1 : std::cout << "IN EXTHIS MERGEMESH " << std::endl;
67 : :
68 [ + - ]: 1 : std::vector<iBase_EntityHandle> ents(mentSelection.size());
69 : 1 : int dim = 3;
70 [ # # + - ]: 2 : for (MEntSelection::iterator mit = mentSelection.begin();
[ - + ]
71 : 1 : mit != mentSelection.end(); mit++) {
72 [ # # ]: 0 : ModelEnt *me = mit->first;
73 [ # # ]: 0 : dim = me->dimension();
74 : : }
75 : :
76 [ + - ]: 1 : if(dim == 3){
77 : : imeshImpl->getEntities(0, iBase_REGION, iMesh_ALL_TOPOLOGIES,
78 [ + - ]: 1 : ents);
79 : : }
80 [ # # ]: 0 : else if (dim == 2){
81 : : imeshImpl->getEntities(0, iBase_FACE, iMesh_ALL_TOPOLOGIES,
82 [ # # ]: 0 : ents);
83 : : }
84 [ + - ]: 1 : merge_entities(&ents[0], ents.size(), mergeTol, doMerge, updateSets,
85 [ + - ]: 1 : mergeTag);
86 : 1 : }
87 : :
88 : 1 : void MergeMesh::merge_entities(iBase_EntityHandle *elems,
89 : : int elems_size,
90 : : const double merge_tol,
91 : : const int do_merge,
92 : : const int update_sets,
93 : : iBase_TagHandle merge_tag)
94 : : {
95 : 1 : mergeTol = merge_tol;
96 : 1 : mergeTolSq = merge_tol*merge_tol;
97 : :
98 [ + - ]: 1 : moab::Range tmp_elems;
99 [ + - ]: 1 : tmp_elems.insert((moab::EntityHandle*)elems, (moab::EntityHandle*)elems + elems_size);
100 : : moab::ErrorCode result = merge_entities(tmp_elems, do_merge, update_sets,
101 [ + - ]: 1 : (moab::Tag)merge_tag);
102 [ - + ]: 1 : if (moab::MB_SUCCESS != result)
103 : 1 : exit(0);
104 : 1 : }
105 : :
106 : 0 : void MergeMesh::perform_merge(iBase_TagHandle merge_tag)
107 : : {
108 : : // put into a range
109 : 0 : moab::ErrorCode result = perform_merge((moab::Tag) merge_tag);
110 [ # # ]: 0 : if (moab::MB_SUCCESS != result)
111 : 0 : exit(0);
112 : 0 : }
113 : :
114 : 1 : moab::ErrorCode MergeMesh::merge_entities(moab::Range &elems,
115 : : const int do_merge,
116 : : const int update_sets,
117 : : moab::Tag merge_tag)
118 : : {
119 : : // get the skin of the entities
120 [ + - ]: 1 : moab::Skinner skinner(mbImpl);
121 [ + - ]: 2 : moab::Range skin_range;
122 [ + - ]: 1 : moab::ErrorCode result = skinner.find_skin(0, elems, 0, skin_range);
123 [ - + ]: 1 : if (moab::MB_SUCCESS != result) return result;
124 : :
125 : : // create a tag to mark merged-to entity; reuse tree_root
126 : 1 : moab::EntityHandle tree_root = 0;
127 [ + - ]: 1 : if (0 == merge_tag) {
128 : : //result = mbImpl->tag_create("__merge_tag", sizeof(moab::EntityHandle),
129 : : // MB_TAG_DENSE, MB_TYPE_HANDLE,
130 : : // mbMergeTag, &tree_root);
131 : : result = mbImpl->tag_get_handle("__merge_tag", 1, moab::MB_TYPE_HANDLE,
132 : : mbMergeTag, moab::MB_TAG_DENSE|moab::MB_TAG_CREAT,
133 [ + - ]: 1 : &tree_root);
134 [ - + ]: 1 : if (moab::MB_SUCCESS != result) return result;
135 : : }
136 : 0 : else mbMergeTag = merge_tag;
137 : :
138 : : // build a kd tree with the vertices
139 [ + - ]: 2 : moab::AdaptiveKDTree kd(mbImpl);
140 [ + - ]: 1 : result = kd.build_tree(skin_range, &tree_root);
141 [ - + ]: 1 : if (moab::MB_SUCCESS != result) return result;
142 : :
143 : : // find matching vertices, mark them
144 [ + - ]: 1 : result = find_merged_to(kd, tree_root, mbMergeTag);
145 [ - + ]: 1 : if (moab::MB_SUCCESS != result) return result;
146 : :
147 : : // merge them if requested
148 [ + - ]: 1 : if (do_merge) {
149 [ + - ]: 1 : result = perform_merge(mbMergeTag);
150 [ - + ]: 1 : if (moab::MB_SUCCESS != result) return result;
151 : : }
152 : :
153 : 2 : return moab::MB_SUCCESS;
154 : : }
155 : :
156 : 1 : moab::ErrorCode MergeMesh::perform_merge(moab::Tag merge_tag)
157 : : {
158 [ + - ][ - + ]: 1 : if (deadEnts.size()==0){
159 [ # # ][ # # ]: 0 : std::cout << "\nWarning: Geometries don't have a common face; Nothing to merge" << std::endl;
160 : 0 : return moab::MB_SUCCESS; //nothing to merge carry on with the program
161 : : }
162 [ + - ][ + - ]: 1 : if (mbImpl->type_from_handle(*deadEnts.rbegin()) != moab::MBVERTEX)
[ + - ][ - + ]
163 : 0 : return moab::MB_FAILURE;
164 : :
165 [ + - ][ + - ]: 1 : std::vector<moab::EntityHandle> merge_tag_val(deadEnts.size());
166 [ + - ][ + - ]: 1 : moab::ErrorCode result = mbImpl->tag_get_data(merge_tag, deadEnts, &merge_tag_val[0]);
167 [ - + ]: 1 : if (moab::MB_SUCCESS != result) return result;
168 : :
169 [ + - ]: 1 : moab::Range::iterator rit;
170 : : unsigned int i;
171 [ + - ][ + - ]: 10 : for (rit = deadEnts.begin(), i = 0; rit != deadEnts.end(); rit++, i++) {
[ + - ][ + - ]
[ + + ]
172 [ + - ][ - + ]: 9 : assert(merge_tag_val[i]);
173 [ + - ][ + - ]: 9 : result = mbImpl->merge_entities(merge_tag_val[i], *rit, false, false);
[ + - ]
174 [ - + ]: 9 : if (moab::MB_SUCCESS != result) return result;
175 : : }
176 : :
177 [ + - ]: 1 : return mbImpl->delete_entities(deadEnts);
178 : : }
179 : :
180 : 1 : moab::ErrorCode MergeMesh::find_merged_to(moab::AdaptiveKDTree & tree, moab::EntityHandle &tree_root, moab::Tag merge_tag)
181 : : {
182 [ + - ]: 1 : moab::AdaptiveKDTreeIter iter;
183 : : //moab::AdaptiveKDTree tree(mbImpl);
184 : :
185 : : // evaluate vertices in this leaf
186 [ + - ][ + - ]: 2 : moab::Range leaf_range, leaf_range2;
187 [ + - ]: 2 : std::vector<moab::EntityHandle> sorted_leaves;
188 [ + - ]: 2 : std::vector<double> coords;
189 [ + - ][ + - ]: 2 : std::vector<moab::EntityHandle> merge_tag_val, leaves_out;
190 : :
191 [ + - ]: 1 : moab::ErrorCode result = tree.get_tree_iterator(tree_root, iter);
192 [ - + ]: 1 : if (moab::MB_SUCCESS != result) return result;
193 [ + + ]: 17 : while (result == moab::MB_SUCCESS) {
194 [ + - ][ + - ]: 16 : sorted_leaves.push_back( iter.handle() );
195 [ + - ]: 16 : result = iter.step();
196 : : }
197 [ - + ]: 1 : if (result != moab::MB_ENTITY_NOT_FOUND)
198 : 0 : return result;
199 [ + - ]: 1 : std::sort( sorted_leaves.begin(), sorted_leaves.end() );
200 : :
201 : 1 : std::vector<moab::EntityHandle>::iterator it;
202 [ + - ][ + - ]: 17 : for (it = sorted_leaves.begin(); it != sorted_leaves.end(); ++it) {
[ + + ]
203 : :
204 [ + - ]: 16 : leaf_range.clear();
205 [ + - ][ + - ]: 16 : result = mbImpl->get_entities_by_handle(*it, leaf_range);
206 [ - + ]: 16 : if (moab::MB_SUCCESS != result) return result;
207 [ + - ][ + - ]: 16 : coords.resize(3*leaf_range.size());
208 [ + - ][ + - ]: 16 : merge_tag_val.resize(leaf_range.size());
209 [ + - ][ + - ]: 16 : result = mbImpl->get_coords(leaf_range, &coords[0]);
210 [ - + ]: 16 : if (moab::MB_SUCCESS != result) return result;
211 [ + - ][ + - ]: 16 : result = mbImpl->tag_get_data(merge_tag, leaf_range, &merge_tag_val[0]);
212 [ - + ]: 16 : if (moab::MB_SUCCESS != result) return result;
213 [ + - ]: 16 : moab::Range::iterator rit;
214 : : unsigned int i;
215 : 16 : bool inleaf_merged, outleaf_merged = false;
216 [ + - ]: 16 : unsigned int lr_size = leaf_range.size();
217 : :
218 [ + - ][ + - ]: 160 : for (i = 0, rit = leaf_range.begin(); i != lr_size; rit++, i++) {
[ + + ]
219 [ + - ][ + + ]: 144 : if (0 != merge_tag_val[i]) continue;
220 [ + - ][ + - ]: 112 : moab::CartVect from(&coords[3*i]);
221 : 112 : inleaf_merged = false;
222 : :
223 : : // check close-by leaves too
224 : 112 : leaves_out.clear();
225 [ + - ]: 112 : result = tree.distance_search( from.array(), mergeTol,
226 [ + - ]: 112 : leaves_out);
227 [ + - ]: 112 : leaf_range2.clear();
228 [ + - + - ]: 976 : for (std::vector<moab::EntityHandle>::iterator vit = leaves_out.begin();
[ + + ]
229 : 488 : vit != leaves_out.end(); vit++) {
230 [ + - ][ + - ]: 376 : if (*vit > *it) { // if we haven't visited this leaf yet in the outer loop
[ + + ]
231 [ + - ][ + - ]: 132 : result = mbImpl->get_entities_by_handle(*vit, leaf_range2, moab::Interface::UNION);
232 [ - + ]: 132 : if (moab::MB_SUCCESS != result) return result;
233 : : }
234 : : }
235 [ + - ][ + + ]: 112 : if (!leaf_range2.empty()) {
236 [ + - ][ + - ]: 69 : coords.resize(3*(lr_size+leaf_range2.size()));
237 [ + - ][ + - ]: 69 : merge_tag_val.resize(lr_size+leaf_range2.size());
238 [ + - ][ + - ]: 69 : result = mbImpl->get_coords(leaf_range2, &coords[3*lr_size]);
239 [ - + ]: 69 : if (moab::MB_SUCCESS != result) return result;
240 [ + - ][ + - ]: 69 : result = mbImpl->tag_get_data(merge_tag, leaf_range2, &merge_tag_val[lr_size]);
241 [ - + ]: 69 : if (moab::MB_SUCCESS != result) return result;
242 : 69 : outleaf_merged = false;
243 : : }
244 : :
245 : : // check other verts in this leaf
246 [ + + ]: 1809 : for (unsigned int j = i+1; j < merge_tag_val.size(); j++) {
247 : 1160 : moab::EntityHandle to_ent = j >= lr_size ? leaf_range2[j-lr_size] :
248 [ + + ][ + - ]: 1697 : leaf_range[j];
[ + - ]
249 : :
250 [ + - ][ + + ]: 1697 : if (*rit == to_ent) continue;
251 : :
252 [ + - ][ + - ]: 1628 : if ((from - moab::CartVect(&coords[3*j])).length_squared() < mergeTolSq) {
[ + - ][ + - ]
[ + + ]
253 [ + - ][ + - ]: 55 : merge_tag_val[j] = *rit;
254 [ + + ]: 55 : if (j < lr_size){
255 : 32 : inleaf_merged = true;}
256 : : else{
257 : 23 : outleaf_merged = true;}
258 : :
259 [ + - ]: 55 : deadEnts.insert(to_ent);
260 : : }
261 : :
262 : : }
263 [ + + ]: 112 : if (outleaf_merged) {
264 [ + - ][ + - ]: 23 : result = mbImpl->tag_set_data(merge_tag, leaf_range2, &merge_tag_val[leaf_range.size()]);
[ + - ]
265 [ - + ]: 23 : if (moab::MB_SUCCESS != result) return result;
266 : 23 : outleaf_merged = false;
267 : : }
268 [ + + ]: 112 : if (inleaf_merged) {
269 [ + - ][ + - ]: 32 : result = mbImpl->tag_set_data(merge_tag, leaf_range, &merge_tag_val[0]);
270 [ - + ]: 112 : if (moab::MB_SUCCESS != result) return result;
271 : : }
272 : :
273 : : }
274 : : }
275 : 2 : return moab::MB_SUCCESS;
276 : : }
277 [ + - ][ + - ]: 156 : }
|