Branch data Line data Source code
1 : : #include "meshkit/iGeom.hpp"
2 : : #include "meshkit/iMesh.hpp"
3 : : #include "meshkit/iRel.hpp"
4 : : #include "moab/Core.hpp"
5 : : #include "MBiMesh.hpp"
6 : : #include "moab/CN.hpp"
7 : : #include "MBTagConventions.hpp"
8 : : #include "meshkit/MKCore.hpp"
9 : : #include "meshkit/NoOp.hpp"
10 : : #include "meshkit/ModelEnt.hpp"
11 : : #include "meshkit/SizingFunction.hpp"
12 : : #include "lemon/bfs.h"
13 : : #include "lemon/adaptors.h"
14 : : #include "MeshOpSet.hpp"
15 : : #include "meshkit/MeshOpProxy.hpp"
16 : : #include "meshkit/VertexMesher.hpp"
17 : : #if HAVE_FBIGEOM
18 : : #include "meshkit/FBiGeom.hpp"
19 : : // this is defined in moab library...
20 : : extern void FBiGeom_newGeomFromMesh( iMesh_Instance mesh, iBase_EntitySetHandle set,
21 : : const char *options, FBiGeom_Instance *geom,
22 : : int *err, int options_len);
23 : : #endif
24 : : namespace MeshKit
25 : : {
26 : :
27 : : // Declare these here rather than in a common header because
28 : : // we don't want to introduce any API dependences on anything
29 : : // outside of core/ beyond what is absolutely necessary (these
30 : : // two functions). And it is unlikely that the signature of
31 : : // these functions will ever change.
32 : : int register_algs_mesh_ops();
33 : : int register_extern_mesh_ops();
34 : :
35 : : // Call functions to register MeshOp classes. These two variables
36 : : // are checked in the MKCore constructor soley to ensure that they
37 : : // are not optimized away.
38 : 39 : const int have_algs_mesh_ops = register_algs_mesh_ops();
39 : 39 : const int have_extern_mesh_ops = register_extern_mesh_ops();
40 : :
41 : 0 : bool MeshOpProxy::can_mesh( ModelEnt* entity ) const
42 : 0 : { return true; }
43 : :
44 : 38 : MKCore::MKCore(iGeom *igeom, moab::Interface *moab, iMesh *imesh, iRel *irel,
45 : : bool construct_missing_ifaces)
46 [ + - ][ + - ]: 228 : : vertexMesher(NULL)
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + - # #
# # # # ]
47 : : {
48 : : // This error should never happen. The primary purpose of this
49 : : // check is to use the variables such that they are not optimized
50 : : // away, thus ensuring that registration actually happens.
51 [ + - ][ - + ]: 38 : if (!have_algs_mesh_ops || !have_extern_mesh_ops)
52 [ # # ]: 0 : throw Error(MK_MESHOP_NOT_FOUND, "Registration of mesh opts did not happen.");
53 : :
54 [ - + ]: 38 : if (igeom) {
55 [ # # ]: 0 : iGeomInstances.push_back(igeom);
56 [ # # ]: 0 : iCreatedIgeoms.push_back(false);
57 : : }
58 : :
59 [ - + ]: 38 : if (moab) {
60 [ # # ]: 0 : moabInstances.push_back(moab);
61 [ # # ]: 0 : iCreatedMoabs.push_back(false);
62 : : }
63 : :
64 [ - + ]: 38 : if (imesh) {
65 [ # # ]: 0 : iMeshInstances.push_back(imesh);
66 [ # # ]: 0 : iCreatedImeshs.push_back(false);
67 : : }
68 : :
69 [ - + ]: 38 : if (irel) {
70 [ # # ]: 0 : iRelInstances.push_back(irel);
71 [ # # ]: 0 : iCreatedIrels.push_back(false);
72 : : }
73 : :
74 : : // leave initialization of root/leaf nodes to hear (and not in MKGraph), so that we have an MKCore
75 : : // to pass to MeshOp's constructor
76 : : // make the leaf/root nodes, link them with an edge; don't need to initialize map to MeshOp, since
77 : : // by default that's NULL
78 [ + - ][ + - ]: 38 : rootNode = new NoOp(this);
79 [ + - ][ + - ]: 38 : leafNode = new NoOp(this);
80 : : //mkGraph.addArc(rootNode->get_node(), leafNode->get_node());
81 : :
82 [ + - ]: 38 : init(construct_missing_ifaces);
83 : :
84 [ + + ]: 190 : for (int i = 0; i < 4; ++i)
85 : 152 : defaultMeshOps[i] = 0;
86 [ # # ]: 38 : }
87 : :
88 [ + - ][ + + ]: 165 : MKCore::~MKCore()
89 : : {
90 : : // delete the graphnodes here, since they point back to me and depend on me being still here
91 : 21 : clear_graph();
92 : :
93 : : // delete the model entities, otherwise they would leak memory
94 : 21 : delete_model_entities();
95 : :
96 [ + + ]: 42 : for (unsigned int i = 0; i < iRelInstances.size(); i++)
97 [ + - ][ + - ]: 21 : if (iCreatedIrels[i]) delete iRelInstances[i];
98 : :
99 [ + + ]: 44 : for (unsigned int i = 0; i < iGeomInstances.size(); i++)
100 [ + + ][ + - ]: 23 : if (iCreatedIgeoms[i]) delete iGeomInstances[i];
101 : :
102 [ + + ]: 42 : for (unsigned int i = 0; i < moabInstances.size(); i++)
103 [ + - ][ + - ]: 21 : if (iCreatedMoabs[i]) delete moabInstances[i];
104 : :
105 [ + + ]: 42 : for (unsigned int i = 0; i < iMeshInstances.size(); i++)
106 [ + - ][ + - ]: 21 : if (iCreatedImeshs[i]) delete iMeshInstances[i];
107 : :
108 [ + + ]: 39 : for (std::vector<SizingFunction*>::iterator vit = sizingFunctions.begin(); vit != sizingFunctions.end(); vit++)
109 [ + + ][ + - ]: 18 : if (*vit) delete *vit;
110 : 21 : sizingFunctions.clear();
111 [ - + ]: 39 : }
112 : :
113 : 38 : void MKCore::init(bool construct_missing_ifaces)
114 : : {
115 : : iBase_ErrorType err;
116 : :
117 [ + - ][ + - ]: 38 : if (iGeomInstances.empty() && construct_missing_ifaces) {
[ + - ]
118 [ + - ][ + - ]: 38 : iGeomInstances.push_back(new iGeom());
119 : 38 : iCreatedIgeoms.push_back(true);
120 : : }
121 : :
122 [ + - ][ + - ]: 38 : if (moabInstances.empty() && construct_missing_ifaces) {
[ + - ]
123 [ + - ][ + - ]: 38 : moabInstances.push_back(new moab::Core());
124 : 38 : iCreatedMoabs.push_back(true);
125 : : }
126 : :
127 [ + - ][ + - ]: 38 : if (iMeshInstances.empty() && construct_missing_ifaces) {
[ + - ]
128 [ + - ][ + - ]: 38 : iMeshInstances.push_back(new iMesh((iMesh_Instance)new MBiMesh(moabInstances[0])));
[ + - ]
129 : 38 : iCreatedImeshs.push_back(true);
130 : : }
131 : :
132 [ + - ][ + - ]: 38 : if (iRelInstances.empty() && construct_missing_ifaces) {
[ + - ]
133 [ + - ][ + - ]: 38 : iRelInstances.push_back(new iRel());
134 : 38 : iCreatedIrels.push_back(true);
135 : : }
136 : :
137 [ + - ][ + - ]: 38 : if (iRelPairs.empty() && !iRelInstances.empty() && !iGeomInstances.empty() && !iMeshInstances.empty()) {
[ + - ][ + - ]
[ + - ]
138 : 38 : iRelPairs.resize(1);
139 : 38 : err = iRelInstances[0]->createPair(iGeomInstances[0]->instance(),
140 : : iRel::ENTITY, iRel::IGEOM_IFACE,
141 : : iRel::ACTIVE,
142 : 38 : iMeshInstances[0]->instance(),
143 : : iRel::SET, iRel::IMESH_IFACE,
144 : : iRel::ACTIVE,
145 : 76 : iRelPairs[0]);
146 : 38 : IBERRCHK(err, "Failure to create relation pair.");
147 : : // don't need to keep track of whether I created the pair, since it'll be deleted anyway when
148 : : // the iRel instance is deleted.
149 : :
150 : : // FIXME: need a better scheme for finding any existing relation pairs or inferring them from
151 : : // imported model(s)
152 : : }
153 : :
154 [ + - ][ + - ]: 38 : if (groupSetPairs.empty() && !iRelInstances.empty() && !iGeomInstances.empty() && !iMeshInstances.empty()) {
[ + - ][ + - ]
[ + - ]
155 : 38 : groupSetPairs.resize(1);
156 : 38 : err = iRelInstances[0]->createPair(iGeomInstances[0]->instance(),
157 : : iRel::SET, iRel::IGEOM_IFACE,
158 : : iRel::ACTIVE,
159 : 38 : iMeshInstances[0]->instance(),
160 : : iRel::SET, iRel::IMESH_IFACE,
161 : : iRel::ACTIVE,
162 : 76 : groupSetPairs[0]);
163 : 38 : IBERRCHK(err, "Failure to create relation pair.");
164 : : }
165 : :
166 [ + - ]: 38 : if (iGeomModelTags.empty()) {
167 : 38 : iGeomModelTags.resize(1);
168 : : // change the name of ModelEntity pointer tag, for iGeom, to
169 : : // differentiate from the tag with the same name in Moab
170 : : // for mesh-based geometry, the model ent tag from moab will conflict
171 : : // with igeom tag !!! "__MKModelEntityGeo" != "__MKModelEntity"
172 : 38 : err = iGeomInstances[0]->createTag("__MKModelEntityGeo", sizeof(MeshKit::ModelEnt*), iBase_BYTES,
173 : 38 : iGeomModelTags[0]);
174 : 38 : IBERRCHK(err, "Failure to create MKModelEnt tag in iGeom.");
175 : : }
176 : :
177 : : moab::ErrorCode rval;
178 [ + - ]: 38 : if (moabModelTags.empty()) {
179 : 38 : ModelEnt *null_me = NULL;
180 [ + - ]: 38 : moabModelTags.resize(1);
181 : : //rval = moabInstances[0]->tag_create("__MKModelEntity", sizeof(MeshKit::ModelEnt*), moab::MB_TAG_SPARSE,
182 : : // moab::MB_TYPE_OPAQUE, moabModelTags[0], &null_me);
183 [ + - ]: 38 : rval = moabInstances[0]->tag_get_handle("__MKModelEntity", sizeof(MeshKit::ModelEnt*), moab::MB_TYPE_OPAQUE,
184 [ + - ][ + - ]: 38 : moabModelTags[0], moab::MB_TAG_SPARSE|moab::MB_TAG_CREAT, &null_me);
185 [ - + ]: 38 : if (moab::MB_SUCCESS != rval)
186 [ # # ][ # # ]: 38 : MBERRCHK(rval, moab_instance());
[ # # ][ # # ]
[ # # ]
187 : : }
188 : :
189 [ + - ]: 38 : if (moabGeomDimTags.empty()) {
190 : : // moab geometry dimension tag
191 : 38 : moabGeomDimTags.resize(1);
192 : : //rval = moabInstances[0]->tag_create(GEOM_DIMENSION_TAG_NAME, sizeof(int), moab::MB_TAG_SPARSE,
193 : : // moab::MB_TYPE_INTEGER, moabGeomDimTags[0], 0, true);
194 : 38 : rval = moabInstances[0]->tag_get_handle(GEOM_DIMENSION_TAG_NAME, 1, moab::MB_TYPE_INTEGER, moabGeomDimTags[0],
195 : 38 : moab::MB_TAG_SPARSE|moab::MB_TAG_CREAT);
196 [ - + ]: 38 : if (moab::MB_SUCCESS != rval)
197 [ # # ][ # # ]: 38 : MBERRCHK(rval, moab_instance());
[ # # ][ # # ]
[ # # ]
198 : : }
199 : :
200 : : // moab global id tag
201 [ + - ]: 38 : if (moabIDTags.empty()) {
202 : 38 : moabIDTags.resize(1);
203 : 38 : rval = moabInstances[0]->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, moab::MB_TYPE_INTEGER, moabIDTags[0],
204 : 38 : moab::MB_TAG_DENSE|moab::MB_TAG_CREAT);
205 [ - + ]: 38 : if (moab::MB_SUCCESS != rval)
206 [ # # ][ # # ]: 38 : MBERRCHK(rval, moab_instance());
[ # # ][ # # ]
[ # # ]
207 : : }
208 : 38 : }
209 : :
210 : 5 : unsigned int MKCore::add_igeom_instance(iGeom * igeom)
211 : : {
212 : : iBase_ErrorType err;
213 [ + - ]: 5 : iGeomInstances.push_back(igeom);
214 : 5 : unsigned int index = iGeomInstances.size()-1;
215 [ + - ]: 5 : iGeomModelTags.resize(index+1);
216 : : // add the iGeomModelTag
217 : : // it could exist already
218 : : iGeom::TagHandle mkmodeltag;
219 [ + - ]: 5 : err = igeom->getTagHandle("__MKModelEntityGeo", mkmodeltag);
220 [ - + ]: 5 : if (iBase_SUCCESS == err)
221 : : {
222 [ # # ]: 0 : iGeomModelTags[index]= mkmodeltag;
223 : : }
224 : : else
225 : : {
226 : : err = igeom->createTag("__MKModelEntityGeo", sizeof(MeshKit::ModelEnt*), iBase_BYTES,
227 [ + - ][ + - ]: 5 : iGeomModelTags[index]);
228 [ + - ]: 5 : IBERRCHK(err, "Failure to create MKModelEnt tag in iGeom.");
229 : : }
230 : :
231 : :
232 : 5 : return index;
233 : : }
234 : :
235 : 54 : void MKCore::populate_model_ents(int geom_index,
236 : : int mesh_index,
237 : : int irel_index, bool only_geom)
238 : : {
239 : : // go through the geometry and mesh models (including geometry groups), and make sure they
240 : : // all have corresponding model entities; this
241 : :
242 [ + - ]: 54 : std::vector<iGeom::EntityHandle> ents;
243 [ + - ][ - + ]: 108 : std::vector<ModelEnt*> new_ents;
244 : : iBase_ErrorType err;
245 : : ModelEnt *this_me;
246 : :
247 [ + + ]: 54 : if (-1 != geom_index) {
248 [ + + ]: 265 : for (int dim = iBase_VERTEX; dim <= iBase_REGION; dim++) {
249 : : // get geometry entities
250 : 212 : ents.clear();
251 [ + - ][ + - ]: 212 : err = igeom_instance(geom_index)->getEntities(igeom_instance(geom_index)->getRootSet(),
252 [ + - ][ + - ]: 212 : (iBase_EntityType)dim, ents);
253 [ + - ]: 212 : IBERRCHK(err, "Failed to get entities from iGeom.");
254 : :
255 [ + - ][ + - ]: 1990 : for (std::vector<iGeom::EntityHandle>::iterator eit = ents.begin(); eit != ents.end(); eit++) {
[ + + ]
256 : : // get the modelent
257 : 1778 : this_me = NULL;
258 [ + - ][ + - ]: 1778 : err = igeom_instance(geom_index)->getData(*eit, iGeomModelTags[geom_index], &this_me);
[ + - ][ + - ]
259 [ + + ][ - + ]: 1778 : if (NULL == this_me || iBase_TAG_NOT_FOUND == err) {
260 : : // construct a new ModelEnt and set the geom ent to point to it
261 [ + - ][ + - ]: 1141 : this_me = new ModelEnt(this, *eit, geom_index, 0, mesh_index, irel_index);
[ + - ]
262 [ + - ]: 1141 : modelEnts[dim].push_back(this_me);
263 : :
264 : : //check whether there is the mesh related to this model entity
265 [ + + ]: 1141 : if (irel_index != -1) {
266 : : iMesh::EntitySetHandle msets;
267 [ + - ][ + - ]: 1096 : err = irel_pair(irel_index)->getEntSetRelation(this_me->geom_handle(), 0, msets);
[ + - ]
268 [ + - ]: 1096 : IBERRCHK(err, "Failed to get imesh entity set from model entity.");
269 : 1096 : int num = -1;
270 [ + - ][ + - ]: 1096 : err = imesh_instance(mesh_index)->getNumOfType(msets, (iBase_EntityType)dim, num);
271 [ + - ]: 1096 : IBERRCHK(err, "Failed to get the mesh entities.");
272 [ + + ]: 1096 : if (num > 0) {//there is the mesh related to this model entities
273 [ + - ]: 1096 : this_me->set_meshed_state(COMPLETE_MESH);
274 : : }
275 : : }
276 : : }
277 : : }
278 : : }
279 : :
280 [ + - ]: 53 : std::vector<iGeom::EntitySetHandle> gsets;
281 [ + - ][ + - ]: 53 : err = igeom_instance(geom_index)->getEntSets(igeom_instance(geom_index)->getRootSet(), -1, gsets);
[ + - ][ + - ]
282 [ + - ]: 53 : IBERRCHK(err, "Failed to get entity sets from iGeom.");
283 [ # # + - ]: 106 : for (std::vector<iGeom::EntitySetHandle>::iterator vit = gsets.begin();
[ - + ]
284 : 53 : vit != gsets.end(); vit++) {
285 : 0 : this_me = NULL;
286 [ # # ][ # # ]: 0 : err = igeom_instance(geom_index)->getEntSetData(*vit, iGeomModelTags[geom_index], &this_me);
[ # # ][ # # ]
287 [ # # ][ # # ]: 0 : if (NULL == this_me || iBase_TAG_NOT_FOUND == err) {
288 : : // construct a new ModelEnt and set the geom ent to point to it
289 [ # # ][ # # ]: 0 : this_me = new ModelEnt(this, *vit, geom_index, 0, mesh_index, irel_index);
[ # # ]
290 [ # # ]: 0 : modelEnts[4].push_back(this_me);
291 : : }
292 : 53 : }
293 : : }
294 : :
295 [ + - ][ + + ]: 54 : if (-1 != mesh_index && !only_geom) {
296 [ + - ]: 19 : moab::Tag dum_tag = moab_geom_dim_tag(mesh_index);
297 [ + - ]: 19 : moab::Range geom_sets;
298 [ + - ]: 19 : moab::ErrorCode rval = moab_instance(mesh_index)->get_entities_by_type_and_tag(0, MBENTITYSET, &dum_tag, NULL, 1,
299 [ + - ]: 19 : geom_sets);
300 [ - + ][ # # ]: 19 : MBERRCHK(rval, moab_instance(mesh_index));
[ # # ][ # # ]
[ # # ]
301 [ + - ][ + - ]: 388 : for (moab::Range::iterator rit = geom_sets.begin(); rit != geom_sets.end(); rit++) {
[ + - ][ + - ]
[ + + ]
302 : : // get the modelent
303 : 369 : this_me = NULL;
304 [ + - ][ + - ]: 369 : rval = moab_instance(mesh_index)->tag_get_data(moabModelTags[mesh_index], &(*rit), 1, &this_me);
[ + - ][ + - ]
305 [ + + ][ - + ]: 369 : if (NULL == this_me || MB_TAG_NOT_FOUND == rval) {
306 : : // construct a new ModelEnt and set the geom ent to point to it
307 [ + - ][ + - ]: 44 : this_me = new ModelEnt(this, (iGeom::EntityHandle)NULL, geom_index, *rit, mesh_index, irel_index);
[ + - ]
308 [ + - ]: 44 : int dim = this_me->dimension();
309 [ + - ]: 44 : modelEnts[dim].push_back(this_me);
310 : : }
311 : 19 : }
312 : : }
313 : : // if there are no model ents after parsing through geometry entities or mesh sets, create at least one
314 : : // model entity, with the existing mesh inside, and with a dimension decided upon the highest degree
315 : : // this is useful for loading a mesh for qslim, if there are no sets available to start with
316 [ + - ]: 54 : if (-1 != mesh_index) {
317 : : // first test if there are no ments so far
318 : 54 : int nments = 0;
319 [ + + ]: 324 : for (int k=0; k<5; k++)
320 : : {
321 : 270 : nments += modelEnts[k].size();
322 : : }
323 [ + + ]: 54 : if (nments > 0)
324 : 51 : return; // do not force creation of a model ent, we have at least one and we should be fine
325 : : // put all ents we have so far in one set
326 : : // we know that none of the sets we have so far is a geo set (we would have gotten at least
327 : : // one model ent)
328 : : // so, get all sets first
329 : : moab::ErrorCode rval;
330 [ + - ][ - + ]: 59 : for (int dimension=3; dimension >=1; dimension--)
331 : : {
332 [ + - ]: 5 : moab::Range ents;
333 [ + - ][ + - ]: 5 : rval = moab_instance(mesh_index)->get_entities_by_dimension(0, dimension, ents);
334 [ - + ][ # # ]: 5 : MBERRCHK(rval, moab_instance(mesh_index));
[ # # ][ # # ]
[ # # ]
335 [ + - ][ + + ]: 5 : if (ents.empty())
336 : 2 : continue;
337 : : // put all ents in one moab set, and create one ModelEnt with it, of given dimension
338 : : moab::EntityHandle newSet;
339 [ + - ][ + - ]: 3 : rval = moab_instance(mesh_index)->create_meshset(moab::MESHSET_SET, newSet);
340 [ - + ][ # # ]: 3 : MBERRCHK(rval, moab_instance(mesh_index));
[ # # ][ # # ]
[ # # ]
341 [ + - ][ + - ]: 3 : rval = moab_instance(mesh_index)->add_entities(newSet, ents);
342 [ - + ][ # # ]: 3 : MBERRCHK(rval, moab_instance(mesh_index));
[ # # ][ # # ]
[ # # ]
343 : : // also, set the geom dimension
344 [ + - ][ + - ]: 3 : rval = moab_instance(mesh_index)->tag_set_data(moab_geom_dim_tag(mesh_index), &newSet, 1, &dimension);
[ + - ]
345 [ - + ][ # # ]: 3 : MBERRCHK(rval, moab_instance(mesh_index));
[ # # ][ # # ]
[ # # ]
346 [ + - ][ + - ]: 3 : this_me = new ModelEnt(this, (iGeom::EntityHandle)NULL, geom_index, newSet, mesh_index, irel_index);
347 [ + - ]: 3 : modelEnts[dimension].push_back(this_me);
348 [ + + ]: 5 : return;// get out if we created one model ent
349 : 0 : }
350 : 54 : }
351 : : }
352 : :
353 : 7 : void MKCore::load_geometry_mesh(const char *geom_filename,
354 : : const char *mesh_filename,
355 : : const char *geom_options,
356 : : const char *mesh_options,
357 : : int geom_index,
358 : : int mesh_index,
359 : : int irel_index,
360 : : bool relate_too,
361 : : bool populate_too)
362 : : {
363 [ + - ]: 7 : if (geom_filename) {
364 : 7 : iBase_ErrorType err = igeom_instance(geom_index)->load(geom_filename, geom_options);
365 : 7 : IBERRCHK(err, "Failed to load geometry model.");
366 : : }
367 : :
368 [ + - ]: 7 : if (mesh_filename) {
369 : 7 : moab::ErrorCode rval = moabInstances[mesh_index]->load_file(mesh_filename, NULL, mesh_options);
370 [ - + ][ # # ]: 7 : MBERRCHK(rval, moab_instance());
[ # # ][ # # ]
[ # # ]
371 : : }
372 : :
373 [ + - ]: 7 : if (relate_too) {
374 [ - + ]: 7 : assert(irel_pair(irel_index));
375 : 7 : iRel::Error err = irel_pair(irel_index)->inferAllRelations();
376 : 7 : IBERRCHK(err, "Failed to infer relations.");
377 : : }
378 : :
379 [ + - ]: 7 : if (populate_too) {
380 : 7 : populate_model_ents(geom_index, mesh_index, irel_index);
381 : : }
382 : 7 : }
383 : :
384 : 34 : void MKCore::load_geometry(const char *filename, const char *options, int geom_index,
385 : : int mesh_index, int irel_index, bool relate_too, bool populate_too)
386 : : {
387 : 34 : iBase_ErrorType err = igeom_instance(geom_index)->load(filename, options);
388 : 34 : IBERRCHK(err, "Failed to load geometry model.");
389 : :
390 [ - + ]: 34 : if (relate_too) {
391 [ # # ]: 0 : assert(irel_pair(irel_index));
392 : 0 : iRel::Error err = irel_pair(irel_index)->inferAllRelations();
393 : 0 : IBERRCHK(err, "Failed to infer relations.");
394 : : }
395 : :
396 [ + - ]: 34 : if (populate_too) populate_model_ents(geom_index, mesh_index, irel_index, true);// only geometry
397 : 34 : }
398 : :
399 : 9 : void MKCore::load_mesh(const char *filename, const char *options,
400 : : int geom_index, int mesh_index, int irel_index,
401 : : bool relate_too, bool populate_too)
402 : : {
403 : 9 : moab::ErrorCode rval = moabInstances[mesh_index]->load_file(filename, NULL, options);
404 [ - + ][ # # ]: 9 : MBERRCHK(rval, moab_instance(mesh_index));
[ # # ][ # # ]
[ # # ]
405 : :
406 [ + + ]: 9 : if (relate_too) {
407 [ - + ]: 1 : assert(irel_pair(irel_index));
408 : 1 : iRel::Error err = irel_pair(irel_index)->inferAllRelations();
409 : 1 : IBERRCHK(err, "Failed to infer relations.");
410 : : }
411 : :
412 [ + + ]: 9 : if (populate_too) populate_model_ents(geom_index, mesh_index, irel_index);
413 : 9 : }
414 : :
415 : 0 : void MKCore::save_geometry(const char *filename, const char *options, int geom_index)
416 : : {
417 : 0 : iBase_ErrorType err = igeom_instance(geom_index)->save(filename, options);
418 : 0 : IBERRCHK(err, "Failed to save geometry model.");
419 : 0 : }
420 : :
421 : 39 : void MKCore::save_mesh(const char *filename, const char *options, int index)
422 : : {
423 : 39 : moab::ErrorCode rval = moab_instance(index)->write_file(filename, NULL, options);
424 [ - + ][ # # ]: 39 : MBERRCHK(rval, moab_instance(index));
[ # # ][ # # ]
[ # # ]
425 : 39 : }
426 : :
427 : 0 : void MKCore::save_mesh_from_model_ents(const char *filename,
428 : : MEntVector & ments, const char *options, int index)
429 : : {
430 : : // first, extract moab ent sets from the ments vector
431 [ # # ]: 0 : moab::Range output_sets;
432 [ # # ]: 0 : for (unsigned int i=0; i<ments.size(); i++)
433 : : {
434 : : moab::EntityHandle mset;
435 [ # # ][ # # ]: 0 : if ((mset = ments[i]->mesh_handle()))
[ # # ]
436 [ # # ]: 0 : output_sets.insert(mset);
437 : : }
438 [ # # ]: 0 : moab::ErrorCode rval = moab_instance(index)->write_file(
439 [ # # ]: 0 : filename, NULL, options, output_sets);
440 [ # # ][ # # ]: 0 : MBERRCHK(rval, moab_instance(index));
[ # # ][ # # ]
[ # # ]
441 : 0 : }
442 : :
443 : 74 : void MKCore::get_entities_by_dimension(int dim, MEntVector &model_ents,
444 : : int igindx)
445 : : {
446 : : // make sure the dimension is valid
447 [ + - ][ - + ]: 74 : if (dim < -1 || dim > 4)
448 [ # # ]: 0 : throw Error(MK_BAD_INPUT, "Invalid dimension requested");
449 : :
450 : 74 : int start = dim, end = dim;
451 [ - + ]: 74 : if (-1 == dim) {
452 : 0 : start = 0;
453 : 0 : end = 4;
454 : : }
455 [ + + ]: 148 : for (dim = start; dim <= end; dim++)
456 : : {
457 [ + - ]: 74 : if (igindx < 0)
458 : : {
459 : 74 : std::copy(modelEnts[dim].begin(), modelEnts[dim].end(), std::back_inserter(model_ents));
460 : : }
461 : : else
462 : : {
463 : : // retrieve only the model ents with the desired igeom index
464 [ # # ]: 0 : for (unsigned int i=0; i<modelEnts[dim].size(); i++)
465 : : {
466 [ # # ]: 0 : ModelEnt * ment = modelEnts[dim][i];
467 [ # # ][ # # ]: 0 : if (ment->iGeomIndex() == igindx)
468 : : {
469 [ # # ]: 0 : model_ents.push_back(ment);
470 : : }
471 : : }
472 : : }
473 : : }
474 : 74 : }
475 : :
476 : 0 : void MKCore::get_entities_by_handle(MEntVector &model_ents)
477 : : {
478 : 0 : get_entities_by_dimension( -1, model_ents);
479 : 0 : }
480 : :
481 : 38 : int MKCore::add_sizing_function(SizingFunction *sf)
482 : : {
483 : 38 : sizingFunctions.push_back(sf);
484 : 38 : return sizingFunctions.size()-1;
485 : : }
486 : :
487 : 34 : void MKCore::remove_sizing_function(int index, bool delete_too)
488 : : {
489 [ + - ][ - + ]: 34 : if (index >= (int)sizingFunctions.size() || !sizingFunctions[index])
[ - + ]
490 [ # # ]: 0 : throw Error(MK_BAD_INPUT, "No sizing function with that index.");
491 : :
492 [ - + ][ # # ]: 34 : if (delete_too) delete sizingFunctions[index];
493 : :
494 : 34 : sizingFunctions[index] = NULL;
495 : 34 : }
496 : :
497 : 0 : SizingFunction *MKCore::sizing_function(double size, bool create_if_missing)
498 : : {
499 [ # # ]: 0 : for (unsigned int i = 0; i < sizingFunctions.size(); i++)
500 [ # # ]: 0 : if (sizingFunctions[i]->size() == size) return sizingFunctions[i];
501 : :
502 : : // if we got here, either create one or return NULL
503 [ # # ]: 0 : if (!create_if_missing) return NULL;
504 : :
505 [ # # ]: 0 : return new SizingFunction(this, -1, size);
506 : : }
507 : :
508 : 1054 : void MKCore::register_meshop(MeshOpProxy* proxy)
509 : : {
510 : 1054 : MeshOpSet::instance().register_mesh_op(proxy);
511 : 1054 : }
512 : :
513 : 109 : MeshOpProxy* MKCore::meshop_proxy(const char *op_name)
514 : : {
515 : 109 : return MeshOpSet::instance().mesh_op(op_name);
516 : : }
517 : :
518 : 27 : MeshOpProxy* MKCore::meshop_proxy(unsigned index)
519 : : {
520 : 27 : return MeshOpSet::instance().mesh_op(index);
521 : : }
522 : :
523 : 1 : unsigned MKCore::num_meshops()
524 : : {
525 : 1 : return MeshOpSet::instance().mesh_ops().size();
526 : : }
527 : :
528 : 0 : unsigned int MKCore::meshop_index(const char *op_name)
529 : : {
530 : 0 : return MeshOpSet::instance().index(op_name);
531 : : }
532 : :
533 : 0 : void MKCore::set_default_meshop(const char *op_name, unsigned short dims)
534 : : {
535 : 0 : set_default_meshop( meshop_proxy( op_name ), dims );
536 : 0 : }
537 : :
538 : 0 : void MKCore::set_default_meshop(unsigned index, unsigned short dims)
539 : : {
540 : 0 : set_default_meshop( meshop_proxy( index ), dims );
541 : 0 : }
542 : :
543 : 26 : MeshOpProxy* MKCore::get_default_meshop( unsigned dimension )
544 : : {
545 : : // If default hasn't been explicity set, set it to the first
546 : : // available algorithm
547 [ + + ]: 26 : if (!defaultMeshOps[dimension]) {
548 : 10 : const MeshOpSet::OpList& list = MeshOpSet::instance().mesh_ops( dimension );
549 [ - + ]: 10 : if (list.empty())
550 [ # # ]: 0 : throw Error(MK_NOT_FOUND, "No MeshOp available for dimension %u", dimension);
551 : 10 : defaultMeshOps[dimension] = list.front();
552 : : }
553 : :
554 : 26 : return defaultMeshOps[dimension];
555 : : }
556 : :
557 : 0 : void MKCore::set_default_meshop(MeshOpProxy* mesh_op, unsigned short dims)
558 : : {
559 : : // check the specified dimension(s) against the types the meshop can mesh
560 [ # # ]: 0 : for (unsigned i = 0; i < 4; ++i)
561 [ # # ][ # # ]: 0 : if ((dims & (1u << i)) && !mesh_op->can_mesh(iBase_EntityType(i)))
[ # # ]
562 [ # # ]: 0 : throw Error(MK_BAD_INPUT, "Specified MeshOp type cannot generate elements of specified dimension.");
563 : :
564 : : // set as default for specified dimensions
565 [ # # ]: 0 : for (unsigned i = 0; i < 4; ++i)
566 [ # # ]: 0 : if (dims & (1u << i))
567 : 0 : defaultMeshOps[i] = mesh_op;
568 : 0 : }
569 : :
570 : 2 : void MKCore::meshop_by_mesh_type(moab::EntityType tp, std::vector<MeshOpProxy*> &ops)
571 : : {
572 : 2 : unsigned dim = moab::CN::Dimension(tp);
573 : 2 : const MeshOpSet::OpList& listOps = MeshOpSet::instance().mesh_ops( dim );
574 [ + - ][ + - ]: 16 : for (MeshOpSet::iterator i = listOps.begin(); i != listOps.end(); ++i) {
[ + + ]
575 [ + - ][ + - ]: 14 : const moab::EntityType* listTypes = (*i)->output_types();
576 [ + + ]: 36 : for (int j = 0; listTypes[j] != moab::MBMAXTYPE; ++j) {
577 [ + + ]: 28 : if (listTypes[j] == tp) {
578 [ + - ][ + - ]: 6 : ops.push_back(*i);
579 : 6 : break;
580 : : }
581 : : }
582 : : }
583 : 2 : }
584 : :
585 : 0 : void MKCore::meshop_by_dimension(int dim, std::vector<MeshOpProxy*> &ops)
586 : : {
587 : 0 : const MeshOpSet::OpList& list = MeshOpSet::instance().mesh_ops( dim );
588 : 0 : std::copy( list.begin(), list.end(), std::back_inserter(ops) );
589 : 0 : }
590 : :
591 : 0 : void MKCore::meshop_by_modelent(ModelEnt * const ent, std::vector<MeshOpProxy*> &ops)
592 : : {
593 : 0 : const MeshOpSet::OpList& list = MeshOpSet::instance().mesh_ops( ent->dimension() );
594 [ # # ][ # # ]: 0 : for (MeshOpSet::iterator i = list.begin(); i != list.end(); ++i)
[ # # ]
595 [ # # ][ # # ]: 0 : if ((*i)->can_mesh(ent))
[ # # ]
596 [ # # ][ # # ]: 0 : ops.push_back(*i);
597 : 0 : }
598 : :
599 : 106 : MeshOp *MKCore::construct_meshop(std::string op_name, const MEntVector &me_vec)
600 : : {
601 : 106 : return construct_meshop( meshop_proxy(op_name.c_str()), me_vec );
602 : : }
603 : :
604 : 89 : MeshOp *MKCore::construct_meshop(unsigned int dim, const MEntVector &me_vec)
605 : : {
606 [ + + ]: 89 : if (dim == 0) {
607 [ + + ]: 63 : if (!vertexMesher) {
608 [ + - ]: 32 : vertexMesher = new VertexMesher(this, me_vec);
609 [ + - ][ + - ]: 32 : vertexMesher->set_name("VertexMesher");
610 : : }
611 : : else
612 [ # # ][ + - ]: 31 : for (MEntVector::const_iterator i = me_vec.begin(); i != me_vec.end(); ++i)
[ - + ]
613 [ # # ][ # # ]: 0 : vertex_mesher()->add_modelent( *i );
[ # # ]
614 : 63 : return vertex_mesher();
615 : : }
616 : : else
617 : 89 : return construct_meshop( get_default_meshop(dim), me_vec );
618 : : }
619 : :
620 : 135 : MeshOp *MKCore::construct_meshop(MeshOpProxy* proxy, const MEntVector &me_vec)
621 : : {
622 : 135 : return proxy->create( this, me_vec );
623 : : }
624 : : #if HAVE_FBIGEOM
625 : : // this method takes the model from moab modelRootSet (0 by default means all)
626 : : // also, assumes the first moab instance from MKCore, and the first iMesh instance
627 : 1 : int MKCore::initialize_mesh_based_geometry(iBase_EntitySetHandle modelRootSet)
628 : : {
629 : : // initialize the FBiGeom, in a different way
630 [ + - ]: 1 : iMesh * imeshMK = imesh_instance(); // this is MeshKit::iMesh class
631 [ + - ]: 1 : iMesh_Instance mesh = imeshMK->instance();
632 : : FBiGeom_Instance geom;
633 : :
634 : : //iBase_EntitySetHandle root_set = reinterpret_cast<iBase_EntitySetHandle>(modelRootSet);
635 [ + - ]: 1 : std::string opts("SMOOTH;");
636 : : // new constructor
637 : : int err;
638 : : // this does the initialization of smoothing (heavy duty computation)
639 [ + - ]: 1 : FBiGeom_newGeomFromMesh(mesh, modelRootSet, opts.c_str(), &geom, &err, opts.length());
640 [ - + ]: 1 : if (err!=0)
641 : 0 : return -1; // error
642 [ + - ][ + - ]: 1 : FBiGeom * fbigeom = new FBiGeom(geom);
643 : :
644 [ + - ]: 1 : int index = add_igeom_instance((iGeom*)fbigeom);
645 : : // use this index to populate
646 [ + - ]: 1 : populate_model_ents(index, 0, -1, true);
647 : 1 : return index;
648 : :
649 : : }
650 : :
651 : 1 : void MKCore::remove_mesh_based_geometry(int index)
652 : : {
653 : : // first, check if the index does make sense
654 [ + - ][ - + ]: 1 : if (index <0 || index >= (int)iGeomInstances.size())
[ - + ]
655 [ # # ]: 0 : throw Error(MK_BAD_INPUT, "Specified index too big for FBiGeom.");
656 : 1 : FBiGeom * fbIGeom = reinterpret_cast<FBiGeom*>(iGeomInstances[index]);
657 : 1 : unsigned int sz = iGeomInstances.size();
658 [ + - ]: 1 : delete fbIGeom;
659 : 1 : fbIGeom = NULL;
660 [ - + ]: 1 : for (unsigned int i=index; i<sz-1; i++)
661 : : {
662 : 0 : iGeomInstances[i] = iGeomInstances[i+1];
663 : : }
664 : 1 : iGeomInstances.resize(sz-1);
665 : 1 : }
666 : : #endif
667 : :
668 : 27 : void MKCore::delete_model_entities()
669 : : {
670 : :
671 [ + - ]: 27 : std::vector<ModelEnt*> tmp_ents;
672 [ + + ]: 135 : for (int dim = 0; dim <= iBase_REGION; dim++) {
673 : 108 : unsigned int sz = modelEnts[dim].size();
674 [ + + ]: 747 : for (unsigned int i=0; i<sz; i++)
675 [ + - ][ + - ]: 639 : delete modelEnts[dim][i];
676 : 108 : modelEnts[dim].clear();
677 : 27 : }
678 : 27 : }
679 : :
680 : 6 : void MKCore::delete_all()
681 : : {
682 : : // clear mk, geometry and mesh
683 : 6 : clear_graph();
684 : 6 : delete_model_entities();
685 : 6 : moab_instance()->delete_mesh();
686 : 6 : igeom_instance()->deleteAll();
687 : 6 : }
688 : :
689 : 0 : void MKCore::create_mbg_model_entities(moab::EntityHandle modelRootSet, bool geometry)
690 : : {
691 [ # # ]: 0 : if (geometry)
692 : : {
693 : : //
694 : : }
695 : : else
696 : : {
697 [ # # ]: 0 : moab::Tag dum_tag = moab_geom_dim_tag();// default 0, no issues here
698 [ # # ]: 0 : moab::Range geom_sets;
699 : : // the enclosing set is the only difference from populate method above
700 [ # # ]: 0 : moab::ErrorCode rval = moab_instance()->get_entities_by_type_and_tag(modelRootSet, MBENTITYSET, &dum_tag, NULL, 1,
701 [ # # ]: 0 : geom_sets);
702 [ # # ][ # # ]: 0 : MBERRCHK(rval, moab_instance());
[ # # ][ # # ]
[ # # ]
703 [ # # ][ # # ]: 0 : for (moab::Range::iterator rit = geom_sets.begin(); rit != geom_sets.end(); rit++) {
[ # # ][ # # ]
[ # # ]
704 : : // get the modelent
705 : :
706 : : // construct a new ModelEnt and set the geom ent to point to it
707 : : // assume mesh index 0, as always, and no relations yet
708 [ # # ][ # # ]: 0 : ModelEnt * this_me = new ModelEnt(this, (iGeom::EntityHandle)NULL, 0, *rit, 0, -1);
[ # # ]
709 [ # # ]: 0 : int dim = this_me->dimension();// will get it from moab set, actually
710 [ # # ]: 0 : modelEnts[dim].push_back(this_me);
711 : 0 : }
712 : : }
713 : 0 : }
714 [ + - ][ + - ]: 156 : } // namespace meshkit
|