MeshKit
1.0
|
00001 #include "meshkit/iGeom.hpp" 00002 #include "meshkit/iMesh.hpp" 00003 #include "meshkit/iRel.hpp" 00004 #include "moab/Core.hpp" 00005 #include "MBiMesh.hpp" 00006 #include "moab/CN.hpp" 00007 #include "MBTagConventions.hpp" 00008 #include "meshkit/MKCore.hpp" 00009 #include "meshkit/NoOp.hpp" 00010 #include "meshkit/ModelEnt.hpp" 00011 #include "meshkit/SizingFunction.hpp" 00012 #include "lemon/bfs.h" 00013 #include "lemon/adaptors.h" 00014 #include "MeshOpSet.hpp" 00015 #include "meshkit/MeshOpProxy.hpp" 00016 #include "meshkit/VertexMesher.hpp" 00017 #if HAVE_FBIGEOM 00018 #include "meshkit/FBiGeom.hpp" 00019 // this is defined in moab library... 00020 extern void FBiGeom_newGeomFromMesh( iMesh_Instance mesh, iBase_EntitySetHandle set, 00021 const char *options, FBiGeom_Instance *geom, 00022 int *err, int options_len); 00023 #endif 00024 namespace MeshKit 00025 { 00026 00027 // Declare these here rather than in a common header because 00028 // we don't want to introduce any API dependences on anything 00029 // outside of core/ beyond what is absolutely necessary (these 00030 // two functions). And it is unlikely that the signature of 00031 // these functions will ever change. 00032 int register_algs_mesh_ops(); 00033 int register_extern_mesh_ops(); 00034 00035 // Call functions to register MeshOp classes. These two variables 00036 // are checked in the MKCore constructor soley to ensure that they 00037 // are not optimized away. 00038 const int have_algs_mesh_ops = register_algs_mesh_ops(); 00039 const int have_extern_mesh_ops = register_extern_mesh_ops(); 00040 00041 bool MeshOpProxy::can_mesh( ModelEnt* entity ) const 00042 { return true; } 00043 00044 MKCore::MKCore(iGeom *igeom, moab::Interface *moab, iMesh *imesh, iRel *irel, 00045 bool construct_missing_ifaces) 00046 : vertexMesher(NULL) 00047 { 00048 // This error should never happen. The primary purpose of this 00049 // check is to use the variables such that they are not optimized 00050 // away, thus ensuring that registration actually happens. 00051 if (!have_algs_mesh_ops || !have_extern_mesh_ops) 00052 throw Error(MK_MESHOP_NOT_FOUND, "Registration of mesh opts did not happen."); 00053 00054 if (igeom) { 00055 iGeomInstances.push_back(igeom); 00056 iCreatedIgeoms.push_back(false); 00057 } 00058 00059 if (moab) { 00060 moabInstances.push_back(moab); 00061 iCreatedMoabs.push_back(false); 00062 } 00063 00064 if (imesh) { 00065 iMeshInstances.push_back(imesh); 00066 iCreatedImeshs.push_back(false); 00067 } 00068 00069 if (irel) { 00070 iRelInstances.push_back(irel); 00071 iCreatedIrels.push_back(false); 00072 } 00073 00074 // leave initialization of root/leaf nodes to hear (and not in MKGraph), so that we have an MKCore 00075 // to pass to MeshOp's constructor 00076 // make the leaf/root nodes, link them with an edge; don't need to initialize map to MeshOp, since 00077 // by default that's NULL 00078 rootNode = new NoOp(this); 00079 leafNode = new NoOp(this); 00080 //mkGraph.addArc(rootNode->get_node(), leafNode->get_node()); 00081 00082 init(construct_missing_ifaces); 00083 00084 for (int i = 0; i < 4; ++i) 00085 defaultMeshOps[i] = 0; 00086 } 00087 00088 MKCore::~MKCore() 00089 { 00090 // delete the graphnodes here, since they point back to me and depend on me being still here 00091 clear_graph(); 00092 00093 // delete the model entities, otherwise they would leak memory 00094 delete_model_entities(); 00095 00096 for (unsigned int i = 0; i < iRelInstances.size(); i++) 00097 if (iCreatedIrels[i]) delete iRelInstances[i]; 00098 00099 for (unsigned int i = 0; i < iGeomInstances.size(); i++) 00100 if (iCreatedIgeoms[i]) delete iGeomInstances[i]; 00101 00102 for (unsigned int i = 0; i < moabInstances.size(); i++) 00103 if (iCreatedMoabs[i]) delete moabInstances[i]; 00104 00105 for (unsigned int i = 0; i < iMeshInstances.size(); i++) 00106 if (iCreatedImeshs[i]) delete iMeshInstances[i]; 00107 00108 for (std::vector<SizingFunction*>::iterator vit = sizingFunctions.begin(); vit != sizingFunctions.end(); vit++) 00109 if (*vit) delete *vit; 00110 sizingFunctions.clear(); 00111 } 00112 00113 void MKCore::init(bool construct_missing_ifaces) 00114 { 00115 iBase_ErrorType err; 00116 00117 if (iGeomInstances.empty() && construct_missing_ifaces) { 00118 iGeomInstances.push_back(new iGeom()); 00119 iCreatedIgeoms.push_back(true); 00120 } 00121 00122 if (moabInstances.empty() && construct_missing_ifaces) { 00123 moabInstances.push_back(new moab::Core()); 00124 iCreatedMoabs.push_back(true); 00125 } 00126 00127 if (iMeshInstances.empty() && construct_missing_ifaces) { 00128 iMeshInstances.push_back(new iMesh((iMesh_Instance)new MBiMesh(moabInstances[0]))); 00129 iCreatedImeshs.push_back(true); 00130 } 00131 00132 if (iRelInstances.empty() && construct_missing_ifaces) { 00133 iRelInstances.push_back(new iRel()); 00134 iCreatedIrels.push_back(true); 00135 } 00136 00137 if (iRelPairs.empty() && !iRelInstances.empty() && !iGeomInstances.empty() && !iMeshInstances.empty()) { 00138 iRelPairs.resize(1); 00139 err = iRelInstances[0]->createPair(iGeomInstances[0]->instance(), 00140 iRel::ENTITY, iRel::IGEOM_IFACE, 00141 iRel::ACTIVE, 00142 iMeshInstances[0]->instance(), 00143 iRel::SET, iRel::IMESH_IFACE, 00144 iRel::ACTIVE, 00145 iRelPairs[0]); 00146 IBERRCHK(err, "Failure to create relation pair."); 00147 // don't need to keep track of whether I created the pair, since it'll be deleted anyway when 00148 // the iRel instance is deleted. 00149 00150 // FIXME: need a better scheme for finding any existing relation pairs or inferring them from 00151 // imported model(s) 00152 } 00153 00154 if (groupSetPairs.empty() && !iRelInstances.empty() && !iGeomInstances.empty() && !iMeshInstances.empty()) { 00155 groupSetPairs.resize(1); 00156 err = iRelInstances[0]->createPair(iGeomInstances[0]->instance(), 00157 iRel::SET, iRel::IGEOM_IFACE, 00158 iRel::ACTIVE, 00159 iMeshInstances[0]->instance(), 00160 iRel::SET, iRel::IMESH_IFACE, 00161 iRel::ACTIVE, 00162 groupSetPairs[0]); 00163 IBERRCHK(err, "Failure to create relation pair."); 00164 } 00165 00166 if (iGeomModelTags.empty()) { 00167 iGeomModelTags.resize(1); 00168 // change the name of ModelEntity pointer tag, for iGeom, to 00169 // differentiate from the tag with the same name in Moab 00170 // for mesh-based geometry, the model ent tag from moab will conflict 00171 // with igeom tag !!! "__MKModelEntityGeo" != "__MKModelEntity" 00172 err = iGeomInstances[0]->createTag("__MKModelEntityGeo", sizeof(MeshKit::ModelEnt*), iBase_BYTES, 00173 iGeomModelTags[0]); 00174 IBERRCHK(err, "Failure to create MKModelEnt tag in iGeom."); 00175 } 00176 00177 moab::ErrorCode rval; 00178 if (moabModelTags.empty()) { 00179 ModelEnt *null_me = NULL; 00180 moabModelTags.resize(1); 00181 //rval = moabInstances[0]->tag_create("__MKModelEntity", sizeof(MeshKit::ModelEnt*), moab::MB_TAG_SPARSE, 00182 // moab::MB_TYPE_OPAQUE, moabModelTags[0], &null_me); 00183 rval = moabInstances[0]->tag_get_handle("__MKModelEntity", sizeof(MeshKit::ModelEnt*), moab::MB_TYPE_OPAQUE, 00184 moabModelTags[0], moab::MB_TAG_SPARSE|moab::MB_TAG_CREAT, &null_me); 00185 if (moab::MB_SUCCESS != rval) 00186 MBERRCHK(rval, moab_instance()); 00187 } 00188 00189 if (moabGeomDimTags.empty()) { 00190 // moab geometry dimension tag 00191 moabGeomDimTags.resize(1); 00192 //rval = moabInstances[0]->tag_create(GEOM_DIMENSION_TAG_NAME, sizeof(int), moab::MB_TAG_SPARSE, 00193 // moab::MB_TYPE_INTEGER, moabGeomDimTags[0], 0, true); 00194 rval = moabInstances[0]->tag_get_handle(GEOM_DIMENSION_TAG_NAME, 1, moab::MB_TYPE_INTEGER, moabGeomDimTags[0], 00195 moab::MB_TAG_SPARSE|moab::MB_TAG_CREAT); 00196 if (moab::MB_SUCCESS != rval) 00197 MBERRCHK(rval, moab_instance()); 00198 } 00199 00200 // moab global id tag 00201 if (moabIDTags.empty()) { 00202 moabIDTags.resize(1); 00203 rval = moabInstances[0]->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, moab::MB_TYPE_INTEGER, moabIDTags[0], 00204 moab::MB_TAG_DENSE|moab::MB_TAG_CREAT); 00205 if (moab::MB_SUCCESS != rval) 00206 MBERRCHK(rval, moab_instance()); 00207 } 00208 } 00209 00210 unsigned int MKCore::add_igeom_instance(iGeom * igeom) 00211 { 00212 iBase_ErrorType err; 00213 iGeomInstances.push_back(igeom); 00214 unsigned int index = iGeomInstances.size()-1; 00215 iGeomModelTags.resize(index+1); 00216 // add the iGeomModelTag 00217 // it could exist already 00218 iGeom::TagHandle mkmodeltag; 00219 err = igeom->getTagHandle("__MKModelEntityGeo", mkmodeltag); 00220 if (iBase_SUCCESS == err) 00221 { 00222 iGeomModelTags[index]= mkmodeltag; 00223 } 00224 else 00225 { 00226 err = igeom->createTag("__MKModelEntityGeo", sizeof(MeshKit::ModelEnt*), iBase_BYTES, 00227 iGeomModelTags[index]); 00228 IBERRCHK(err, "Failure to create MKModelEnt tag in iGeom."); 00229 } 00230 00231 00232 return index; 00233 } 00234 00235 void MKCore::populate_model_ents(int geom_index, 00236 int mesh_index, 00237 int irel_index, bool only_geom) 00238 { 00239 // go through the geometry and mesh models (including geometry groups), and make sure they 00240 // all have corresponding model entities; this 00241 00242 std::vector<iGeom::EntityHandle> ents; 00243 std::vector<ModelEnt*> new_ents; 00244 iBase_ErrorType err; 00245 ModelEnt *this_me; 00246 00247 if (-1 != geom_index) { 00248 for (int dim = iBase_VERTEX; dim <= iBase_REGION; dim++) { 00249 // get geometry entities 00250 ents.clear(); 00251 err = igeom_instance(geom_index)->getEntities(igeom_instance(geom_index)->getRootSet(), 00252 (iBase_EntityType)dim, ents); 00253 IBERRCHK(err, "Failed to get entities from iGeom."); 00254 00255 for (std::vector<iGeom::EntityHandle>::iterator eit = ents.begin(); eit != ents.end(); eit++) { 00256 // get the modelent 00257 this_me = NULL; 00258 err = igeom_instance(geom_index)->getData(*eit, iGeomModelTags[geom_index], &this_me); 00259 if (NULL == this_me || iBase_TAG_NOT_FOUND == err) { 00260 // construct a new ModelEnt and set the geom ent to point to it 00261 this_me = new ModelEnt(this, *eit, geom_index, 0, mesh_index, irel_index); 00262 modelEnts[dim].push_back(this_me); 00263 00264 //check whether there is the mesh related to this model entity 00265 if (irel_index != -1) { 00266 iMesh::EntitySetHandle msets; 00267 err = irel_pair(irel_index)->getEntSetRelation(this_me->geom_handle(), 0, msets); 00268 IBERRCHK(err, "Failed to get imesh entity set from model entity."); 00269 int num = -1; 00270 err = imesh_instance(mesh_index)->getNumOfType(msets, (iBase_EntityType)dim, num); 00271 IBERRCHK(err, "Failed to get the mesh entities."); 00272 if (num > 0) {//there is the mesh related to this model entities 00273 this_me->set_meshed_state(COMPLETE_MESH); 00274 } 00275 } 00276 } 00277 } 00278 } 00279 00280 std::vector<iGeom::EntitySetHandle> gsets; 00281 err = igeom_instance(geom_index)->getEntSets(igeom_instance(geom_index)->getRootSet(), -1, gsets); 00282 IBERRCHK(err, "Failed to get entity sets from iGeom."); 00283 for (std::vector<iGeom::EntitySetHandle>::iterator vit = gsets.begin(); 00284 vit != gsets.end(); vit++) { 00285 this_me = NULL; 00286 err = igeom_instance(geom_index)->getEntSetData(*vit, iGeomModelTags[geom_index], &this_me); 00287 if (NULL == this_me || iBase_TAG_NOT_FOUND == err) { 00288 // construct a new ModelEnt and set the geom ent to point to it 00289 this_me = new ModelEnt(this, *vit, geom_index, 0, mesh_index, irel_index); 00290 modelEnts[4].push_back(this_me); 00291 } 00292 } 00293 } 00294 00295 if (-1 != mesh_index && !only_geom) { 00296 moab::Tag dum_tag = moab_geom_dim_tag(mesh_index); 00297 moab::Range geom_sets; 00298 moab::ErrorCode rval = moab_instance(mesh_index)->get_entities_by_type_and_tag(0, MBENTITYSET, &dum_tag, NULL, 1, 00299 geom_sets); 00300 MBERRCHK(rval, moab_instance(mesh_index)); 00301 for (moab::Range::iterator rit = geom_sets.begin(); rit != geom_sets.end(); rit++) { 00302 // get the modelent 00303 this_me = NULL; 00304 rval = moab_instance(mesh_index)->tag_get_data(moabModelTags[mesh_index], &(*rit), 1, &this_me); 00305 if (NULL == this_me || MB_TAG_NOT_FOUND == rval) { 00306 // construct a new ModelEnt and set the geom ent to point to it 00307 this_me = new ModelEnt(this, (iGeom::EntityHandle)NULL, geom_index, *rit, mesh_index, irel_index); 00308 int dim = this_me->dimension(); 00309 modelEnts[dim].push_back(this_me); 00310 } 00311 } 00312 } 00313 // if there are no model ents after parsing through geometry entities or mesh sets, create at least one 00314 // model entity, with the existing mesh inside, and with a dimension decided upon the highest degree 00315 // this is useful for loading a mesh for qslim, if there are no sets available to start with 00316 if (-1 != mesh_index) { 00317 // first test if there are no ments so far 00318 int nments = 0; 00319 for (int k=0; k<5; k++) 00320 { 00321 nments += modelEnts[k].size(); 00322 } 00323 if (nments > 0) 00324 return; // do not force creation of a model ent, we have at least one and we should be fine 00325 // put all ents we have so far in one set 00326 // we know that none of the sets we have so far is a geo set (we would have gotten at least 00327 // one model ent) 00328 // so, get all sets first 00329 moab::ErrorCode rval; 00330 for (int dimension=3; dimension >=1; dimension--) 00331 { 00332 moab::Range ents; 00333 rval = moab_instance(mesh_index)->get_entities_by_dimension(0, dimension, ents); 00334 MBERRCHK(rval, moab_instance(mesh_index)); 00335 if (ents.empty()) 00336 continue; 00337 // put all ents in one moab set, and create one ModelEnt with it, of given dimension 00338 moab::EntityHandle newSet; 00339 rval = moab_instance(mesh_index)->create_meshset(moab::MESHSET_SET, newSet); 00340 MBERRCHK(rval, moab_instance(mesh_index)); 00341 rval = moab_instance(mesh_index)->add_entities(newSet, ents); 00342 MBERRCHK(rval, moab_instance(mesh_index)); 00343 // also, set the geom dimension 00344 rval = moab_instance(mesh_index)->tag_set_data(moab_geom_dim_tag(mesh_index), &newSet, 1, &dimension); 00345 MBERRCHK(rval, moab_instance(mesh_index)); 00346 this_me = new ModelEnt(this, (iGeom::EntityHandle)NULL, geom_index, newSet, mesh_index, irel_index); 00347 modelEnts[dimension].push_back(this_me); 00348 return;// get out if we created one model ent 00349 } 00350 } 00351 } 00352 00353 void MKCore::load_geometry_mesh(const char *geom_filename, 00354 const char *mesh_filename, 00355 const char *geom_options, 00356 const char *mesh_options, 00357 int geom_index, 00358 int mesh_index, 00359 int irel_index, 00360 bool relate_too, 00361 bool populate_too) 00362 { 00363 if (geom_filename) { 00364 iBase_ErrorType err = igeom_instance(geom_index)->load(geom_filename, geom_options); 00365 IBERRCHK(err, "Failed to load geometry model."); 00366 } 00367 00368 if (mesh_filename) { 00369 moab::ErrorCode rval = moabInstances[mesh_index]->load_file(mesh_filename, NULL, mesh_options); 00370 MBERRCHK(rval, moab_instance()); 00371 } 00372 00373 if (relate_too) { 00374 assert(irel_pair(irel_index)); 00375 iRel::Error err = irel_pair(irel_index)->inferAllRelations(); 00376 IBERRCHK(err, "Failed to infer relations."); 00377 } 00378 00379 if (populate_too) { 00380 populate_model_ents(geom_index, mesh_index, irel_index); 00381 } 00382 } 00383 00384 void MKCore::load_geometry(const char *filename, const char *options, int geom_index, 00385 int mesh_index, int irel_index, bool relate_too, bool populate_too) 00386 { 00387 iBase_ErrorType err = igeom_instance(geom_index)->load(filename, options); 00388 IBERRCHK(err, "Failed to load geometry model."); 00389 00390 if (relate_too) { 00391 assert(irel_pair(irel_index)); 00392 iRel::Error err = irel_pair(irel_index)->inferAllRelations(); 00393 IBERRCHK(err, "Failed to infer relations."); 00394 } 00395 00396 if (populate_too) populate_model_ents(geom_index, mesh_index, irel_index, true);// only geometry 00397 } 00398 00399 void MKCore::load_mesh(const char *filename, const char *options, 00400 int geom_index, int mesh_index, int irel_index, 00401 bool relate_too, bool populate_too) 00402 { 00403 moab::ErrorCode rval = moabInstances[mesh_index]->load_file(filename, NULL, options); 00404 MBERRCHK(rval, moab_instance(mesh_index)); 00405 00406 if (relate_too) { 00407 assert(irel_pair(irel_index)); 00408 iRel::Error err = irel_pair(irel_index)->inferAllRelations(); 00409 IBERRCHK(err, "Failed to infer relations."); 00410 } 00411 00412 if (populate_too) populate_model_ents(geom_index, mesh_index, irel_index); 00413 } 00414 00415 void MKCore::save_geometry(const char *filename, const char *options, int geom_index) 00416 { 00417 iBase_ErrorType err = igeom_instance(geom_index)->save(filename, options); 00418 IBERRCHK(err, "Failed to save geometry model."); 00419 } 00420 00421 void MKCore::save_mesh(const char *filename, const char *options, int index) 00422 { 00423 moab::ErrorCode rval = moab_instance(index)->write_file(filename, NULL, options); 00424 MBERRCHK(rval, moab_instance(index)); 00425 } 00426 00427 void MKCore::save_mesh_from_model_ents(const char *filename, 00428 MEntVector & ments, const char *options, int index) 00429 { 00430 // first, extract moab ent sets from the ments vector 00431 moab::Range output_sets; 00432 for (unsigned int i=0; i<ments.size(); i++) 00433 { 00434 moab::EntityHandle mset; 00435 if ((mset = ments[i]->mesh_handle())) 00436 output_sets.insert(mset); 00437 } 00438 moab::ErrorCode rval = moab_instance(index)->write_file( 00439 filename, NULL, options, output_sets); 00440 MBERRCHK(rval, moab_instance(index)); 00441 } 00442 00443 void MKCore::get_entities_by_dimension(int dim, MEntVector &model_ents, 00444 int igindx) 00445 { 00446 // make sure the dimension is valid 00447 if (dim < -1 || dim > 4) 00448 throw Error(MK_BAD_INPUT, "Invalid dimension requested"); 00449 00450 int start = dim, end = dim; 00451 if (-1 == dim) { 00452 start = 0; 00453 end = 4; 00454 } 00455 for (dim = start; dim <= end; dim++) 00456 { 00457 if (igindx < 0) 00458 { 00459 std::copy(modelEnts[dim].begin(), modelEnts[dim].end(), std::back_inserter(model_ents)); 00460 } 00461 else 00462 { 00463 // retrieve only the model ents with the desired igeom index 00464 for (unsigned int i=0; i<modelEnts[dim].size(); i++) 00465 { 00466 ModelEnt * ment = modelEnts[dim][i]; 00467 if (ment->iGeomIndex() == igindx) 00468 { 00469 model_ents.push_back(ment); 00470 } 00471 } 00472 } 00473 } 00474 } 00475 00476 void MKCore::get_entities_by_handle(MEntVector &model_ents) 00477 { 00478 get_entities_by_dimension( -1, model_ents); 00479 } 00480 00481 int MKCore::add_sizing_function(SizingFunction *sf) 00482 { 00483 sizingFunctions.push_back(sf); 00484 return sizingFunctions.size()-1; 00485 } 00486 00487 void MKCore::remove_sizing_function(int index, bool delete_too) 00488 { 00489 if (index >= (int)sizingFunctions.size() || !sizingFunctions[index]) 00490 throw Error(MK_BAD_INPUT, "No sizing function with that index."); 00491 00492 if (delete_too) delete sizingFunctions[index]; 00493 00494 sizingFunctions[index] = NULL; 00495 } 00496 00497 SizingFunction *MKCore::sizing_function(double size, bool create_if_missing) 00498 { 00499 for (unsigned int i = 0; i < sizingFunctions.size(); i++) 00500 if (sizingFunctions[i]->size() == size) return sizingFunctions[i]; 00501 00502 // if we got here, either create one or return NULL 00503 if (!create_if_missing) return NULL; 00504 00505 return new SizingFunction(this, -1, size); 00506 } 00507 00508 void MKCore::register_meshop(MeshOpProxy* proxy) 00509 { 00510 MeshOpSet::instance().register_mesh_op(proxy); 00511 } 00512 00513 MeshOpProxy* MKCore::meshop_proxy(const char *op_name) 00514 { 00515 return MeshOpSet::instance().mesh_op(op_name); 00516 } 00517 00518 MeshOpProxy* MKCore::meshop_proxy(unsigned index) 00519 { 00520 return MeshOpSet::instance().mesh_op(index); 00521 } 00522 00523 unsigned MKCore::num_meshops() 00524 { 00525 return MeshOpSet::instance().mesh_ops().size(); 00526 } 00527 00528 unsigned int MKCore::meshop_index(const char *op_name) 00529 { 00530 return MeshOpSet::instance().index(op_name); 00531 } 00532 00533 void MKCore::set_default_meshop(const char *op_name, unsigned short dims) 00534 { 00535 set_default_meshop( meshop_proxy( op_name ), dims ); 00536 } 00537 00538 void MKCore::set_default_meshop(unsigned index, unsigned short dims) 00539 { 00540 set_default_meshop( meshop_proxy( index ), dims ); 00541 } 00542 00543 MeshOpProxy* MKCore::get_default_meshop( unsigned dimension ) 00544 { 00545 // If default hasn't been explicity set, set it to the first 00546 // available algorithm 00547 if (!defaultMeshOps[dimension]) { 00548 const MeshOpSet::OpList& list = MeshOpSet::instance().mesh_ops( dimension ); 00549 if (list.empty()) 00550 throw Error(MK_NOT_FOUND, "No MeshOp available for dimension %u", dimension); 00551 defaultMeshOps[dimension] = list.front(); 00552 } 00553 00554 return defaultMeshOps[dimension]; 00555 } 00556 00557 void MKCore::set_default_meshop(MeshOpProxy* mesh_op, unsigned short dims) 00558 { 00559 // check the specified dimension(s) against the types the meshop can mesh 00560 for (unsigned i = 0; i < 4; ++i) 00561 if ((dims & (1u << i)) && !mesh_op->can_mesh(iBase_EntityType(i))) 00562 throw Error(MK_BAD_INPUT, "Specified MeshOp type cannot generate elements of specified dimension."); 00563 00564 // set as default for specified dimensions 00565 for (unsigned i = 0; i < 4; ++i) 00566 if (dims & (1u << i)) 00567 defaultMeshOps[i] = mesh_op; 00568 } 00569 00570 void MKCore::meshop_by_mesh_type(moab::EntityType tp, std::vector<MeshOpProxy*> &ops) 00571 { 00572 unsigned dim = moab::CN::Dimension(tp); 00573 const MeshOpSet::OpList& listOps = MeshOpSet::instance().mesh_ops( dim ); 00574 for (MeshOpSet::iterator i = listOps.begin(); i != listOps.end(); ++i) { 00575 const moab::EntityType* listTypes = (*i)->output_types(); 00576 for (int j = 0; listTypes[j] != moab::MBMAXTYPE; ++j) { 00577 if (listTypes[j] == tp) { 00578 ops.push_back(*i); 00579 break; 00580 } 00581 } 00582 } 00583 } 00584 00585 void MKCore::meshop_by_dimension(int dim, std::vector<MeshOpProxy*> &ops) 00586 { 00587 const MeshOpSet::OpList& list = MeshOpSet::instance().mesh_ops( dim ); 00588 std::copy( list.begin(), list.end(), std::back_inserter(ops) ); 00589 } 00590 00591 void MKCore::meshop_by_modelent(ModelEnt * const ent, std::vector<MeshOpProxy*> &ops) 00592 { 00593 const MeshOpSet::OpList& list = MeshOpSet::instance().mesh_ops( ent->dimension() ); 00594 for (MeshOpSet::iterator i = list.begin(); i != list.end(); ++i) 00595 if ((*i)->can_mesh(ent)) 00596 ops.push_back(*i); 00597 } 00598 00599 MeshOp *MKCore::construct_meshop(std::string op_name, const MEntVector &me_vec) 00600 { 00601 return construct_meshop( meshop_proxy(op_name.c_str()), me_vec ); 00602 } 00603 00604 MeshOp *MKCore::construct_meshop(unsigned int dim, const MEntVector &me_vec) 00605 { 00606 if (dim == 0) { 00607 if (!vertexMesher) { 00608 vertexMesher = new VertexMesher(this, me_vec); 00609 vertexMesher->set_name("VertexMesher"); 00610 } 00611 else 00612 for (MEntVector::const_iterator i = me_vec.begin(); i != me_vec.end(); ++i) 00613 vertex_mesher()->add_modelent( *i ); 00614 return vertex_mesher(); 00615 } 00616 else 00617 return construct_meshop( get_default_meshop(dim), me_vec ); 00618 } 00619 00620 MeshOp *MKCore::construct_meshop(MeshOpProxy* proxy, const MEntVector &me_vec) 00621 { 00622 return proxy->create( this, me_vec ); 00623 } 00624 #if HAVE_FBIGEOM 00625 // this method takes the model from moab modelRootSet (0 by default means all) 00626 // also, assumes the first moab instance from MKCore, and the first iMesh instance 00627 int MKCore::initialize_mesh_based_geometry(iBase_EntitySetHandle modelRootSet) 00628 { 00629 // initialize the FBiGeom, in a different way 00630 iMesh * imeshMK = imesh_instance(); // this is MeshKit::iMesh class 00631 iMesh_Instance mesh = imeshMK->instance(); 00632 FBiGeom_Instance geom; 00633 00634 //iBase_EntitySetHandle root_set = reinterpret_cast<iBase_EntitySetHandle>(modelRootSet); 00635 std::string opts("SMOOTH;"); 00636 // new constructor 00637 int err; 00638 // this does the initialization of smoothing (heavy duty computation) 00639 FBiGeom_newGeomFromMesh(mesh, modelRootSet, opts.c_str(), &geom, &err, opts.length()); 00640 if (err!=0) 00641 return -1; // error 00642 FBiGeom * fbigeom = new FBiGeom(geom); 00643 00644 int index = add_igeom_instance((iGeom*)fbigeom); 00645 // use this index to populate 00646 populate_model_ents(index, 0, -1, true); 00647 return index; 00648 00649 } 00650 00651 void MKCore::remove_mesh_based_geometry(int index) 00652 { 00653 // first, check if the index does make sense 00654 if (index <0 || index >= (int)iGeomInstances.size()) 00655 throw Error(MK_BAD_INPUT, "Specified index too big for FBiGeom."); 00656 FBiGeom * fbIGeom = reinterpret_cast<FBiGeom*>(iGeomInstances[index]); 00657 unsigned int sz = iGeomInstances.size(); 00658 delete fbIGeom; 00659 fbIGeom = NULL; 00660 for (unsigned int i=index; i<sz-1; i++) 00661 { 00662 iGeomInstances[i] = iGeomInstances[i+1]; 00663 } 00664 iGeomInstances.resize(sz-1); 00665 } 00666 #endif 00667 00668 void MKCore::delete_model_entities() 00669 { 00670 00671 std::vector<ModelEnt*> tmp_ents; 00672 for (int dim = 0; dim <= iBase_REGION; dim++) { 00673 unsigned int sz = modelEnts[dim].size(); 00674 for (unsigned int i=0; i<sz; i++) 00675 delete modelEnts[dim][i]; 00676 modelEnts[dim].clear(); 00677 } 00678 } 00679 00680 void MKCore::delete_all() 00681 { 00682 // clear mk, geometry and mesh 00683 clear_graph(); 00684 delete_model_entities(); 00685 moab_instance()->delete_mesh(); 00686 igeom_instance()->deleteAll(); 00687 } 00688 00689 void MKCore::create_mbg_model_entities(moab::EntityHandle modelRootSet, bool geometry) 00690 { 00691 if (geometry) 00692 { 00693 // 00694 } 00695 else 00696 { 00697 moab::Tag dum_tag = moab_geom_dim_tag();// default 0, no issues here 00698 moab::Range geom_sets; 00699 // the enclosing set is the only difference from populate method above 00700 moab::ErrorCode rval = moab_instance()->get_entities_by_type_and_tag(modelRootSet, MBENTITYSET, &dum_tag, NULL, 1, 00701 geom_sets); 00702 MBERRCHK(rval, moab_instance()); 00703 for (moab::Range::iterator rit = geom_sets.begin(); rit != geom_sets.end(); rit++) { 00704 // get the modelent 00705 00706 // construct a new ModelEnt and set the geom ent to point to it 00707 // assume mesh index 0, as always, and no relations yet 00708 ModelEnt * this_me = new ModelEnt(this, (iGeom::EntityHandle)NULL, 0, *rit, 0, -1); 00709 int dim = this_me->dimension();// will get it from moab set, actually 00710 modelEnts[dim].push_back(this_me); 00711 } 00712 } 00713 } 00714 } // namespace meshkit