MeshKit
1.0
|
00001 #include "meshkit/iGeom.hpp" 00002 #include "meshkit/ModelEnt.hpp" 00003 #include "meshkit/SizingFunction.hpp" 00004 #include "meshkit/Error.hpp" 00005 #include "meshkit/MKCore.hpp" 00006 #include "meshkit/Types.hpp" 00007 #include "meshkit/VecUtil.hpp" 00008 #include "moab/GeomTopoTool.hpp" 00009 #include "moab/CN.hpp" 00010 #include "RefEntity.hpp" 00011 00012 namespace MeshKit 00013 { 00014 00015 ModelEnt::ModelEnt(MKCore *mk, 00016 iGeom::EntityHandle geom_ent, 00017 int geom_index, 00018 moab::EntityHandle mesh_ent, 00019 int mesh_index, 00020 int irel_index, 00021 int sizing_index) 00022 : mkCore(mk), igeomIndex(geom_index), meshIndex(mesh_index), irelIndex(irel_index), 00023 iGeomEnt(geom_ent), iGeomSet(NULL), 00024 moabEntSet(mesh_ent), sizingFunctionIndex(sizing_index), 00025 meshIntervals(-1), intervalFirmness(DEFAULT), constrainEven(false), 00026 meshedState(NO_MESH), iaVariable(NULL) 00027 { 00028 // mark the geometry entity with this modelEnt 00029 if (-1 != igeomIndex && geom_ent) { 00030 ModelEnt *dum_this = this; 00031 iGeom::Error err = igeom_instance()->setData(geom_ent, mkCore->igeom_model_tag(igeomIndex), &dum_this); 00032 IBERRCHK(err, "Failed to set iGeom ModelEnt tag."); 00033 } 00034 00035 if (!mesh_ent && geom_ent && -1 != meshIndex && -1 != irelIndex) { 00036 // get a corresponding mesh set handle, if any; create one if missing and have a meshIndex 00037 iBase_EntitySetHandle h; 00038 iRel::Error err = mkCore->irel_pair(irelIndex)->getEntSetRelation(geom_ent, false, h); 00039 if (iBase_SUCCESS == err) 00040 moabEntSet = reinterpret_cast<moab::EntityHandle>(h); 00041 else moabEntSet = 0; 00042 } 00043 00044 // if still no mesh entity and non-default mesh index, create one 00045 if (-1 != meshIndex && !moabEntSet) { 00046 // should have a geometry entity here 00047 assert(iGeomEnt || iGeomSet); 00048 create_mesh_set(); 00049 } 00050 00051 // if there's a mesh entity, set it to point here too 00052 if (moabEntSet && -1 != meshIndex) { 00053 ModelEnt *dum_this = this; 00054 moab::ErrorCode err = mkCore->moab_instance(meshIndex)->tag_set_data(mkCore->moab_model_tag(meshIndex), 00055 &moabEntSet, 1, &dum_this); 00056 IBERRCHK(err, "Failed to set moab ModelEnt tag."); 00057 } 00058 } 00059 00060 ModelEnt::ModelEnt(MKCore *mk, 00061 iGeom::EntitySetHandle geom_ent, 00062 int geom_index, 00063 moab::EntityHandle mesh_ent, 00064 int mesh_index, 00065 int irel_index, 00066 int sizing_index, 00067 IAVariable *ia_var) 00068 : mkCore(mk), igeomIndex(geom_index), meshIndex(mesh_index), irelIndex(irel_index), 00069 iGeomEnt(NULL), iGeomSet(geom_ent), 00070 moabEntSet(mesh_ent), sizingFunctionIndex(sizing_index), 00071 meshIntervals(-1), intervalFirmness(DEFAULT), constrainEven(false), 00072 meshedState(NO_MESH), iaVariable(ia_var) 00073 { 00074 // mark the geometry entity with this modelEnt 00075 if (-1 != igeomIndex && geom_ent) { 00076 ModelEnt *dum_this = this; 00077 iGeom::Error err = igeom_instance()->setEntSetData(geom_ent, 00078 mkCore->igeom_model_tag(igeomIndex), 00079 &dum_this); 00080 IBERRCHK(err, "Failed to set iGeom ModelSet tag."); 00081 } 00082 00083 if (!mesh_ent && geom_ent && -1 != meshIndex && -1 != irelIndex) { 00084 // get a corresponding mesh set handle, if any; create one if missing and have a meshIndex 00085 iBase_EntitySetHandle h; 00086 iRel::Error err = mkCore->group_set_pair(irelIndex)->getSetSetRelation(geom_ent, false, h); 00087 //IBERRCHK(err, "Failed to get mesh set handle for geometry entity set."); 00088 if(iBase_SUCCESS == err) moabEntSet = reinterpret_cast<moab::EntityHandle>(h); 00089 else moabEntSet=0; 00090 } 00091 00092 // if still no mesh entity and non-default mesh index, create one 00093 if (-1 != meshIndex && !moabEntSet) { 00094 // should have a geometry entity here 00095 assert(iGeomEnt || iGeomSet); 00096 create_mesh_set(); 00097 } 00098 00099 // if there's a mesh entity, set it to point here too 00100 if (moabEntSet && -1 != meshIndex) { 00101 ModelEnt *dum_this = this; 00102 moab::ErrorCode err = mkCore->moab_instance(meshIndex)->tag_set_data(mkCore->moab_model_tag(meshIndex), 00103 &moabEntSet, 1, &dum_this); 00104 IBERRCHK(err, "Failed to set moab ModelEnt tag."); 00105 } 00106 } 00107 00108 ModelEnt::~ModelEnt() 00109 { 00110 // if we delete the Model Entity, remove the tag on the gent that 00111 // was pointing to it (or set it to NULL) 00112 /*if (-1 != igeomIndex && iGeomEnt) { 00113 iGeom::Error err = igeom_instance()->rmvTag(iGeomEnt, 00114 mkCore->igeom_model_tag(igeomIndex)); 00115 IBERRCHK(err, "Failed to set iGeom ModelEnt tag."); 00116 } 00117 00118 if (-1 != igeomIndex && iGeomSet) { 00119 iGeom::Error err = igeom_instance()->rmvEntSetTag(iGeomSet, 00120 mkCore->igeom_model_tag(igeomIndex)); 00121 IBERRCHK(err, "Failed to set iGeom ModelSet tag."); 00122 }*/ 00123 // if we delete the Model Entity, remove the tag on the moabEntSet 00124 // that was pointing to it (set the value to NULL) 00125 if (moabEntSet && -1 != meshIndex) { 00126 moab::ErrorCode err = mkCore->moab_instance(meshIndex)->tag_delete_data( 00127 mkCore->moab_model_tag(meshIndex), &moabEntSet, 1); 00128 IBERRCHK(err, "Failed to set moab ModelEnt tag."); 00129 } 00130 } 00131 00132 void ModelEnt::sizing_function_index(int ind, bool children_too) 00133 { 00134 sizingFunctionIndex = ind; 00135 00136 // set on children too, if requested 00137 if (children_too && dimension() > 1) { 00138 MEntVector childrn; 00139 get_adjacencies(dimension()-1, childrn); 00140 for (MEntVector::iterator vit = childrn.begin(); vit != childrn.end(); vit++) 00141 (*vit)->sizing_function_index(ind, children_too); 00142 } 00143 } 00144 00145 void ModelEnt::create_mesh_set(int ordered_flag) 00146 { 00147 if (moabEntSet) 00148 throw Error(MK_FAILURE, "Tried to create meshset for an entity that already had one."); 00149 00150 else if (!iGeomEnt && !iGeomSet) 00151 throw Error(MK_FAILURE, "Tried to create ModelEnt missing a geometry entity or set."); 00152 00153 moab::EntitySetProperty ordered = moab::MESHSET_SET; 00154 00155 // need type for later 00156 iBase_EntityType this_tp = iBase_ALL_TYPES; 00157 iGeom::Error err; 00158 if (-1 > ordered_flag || 1 < ordered_flag) throw Error(MK_FAILURE, "Invalid value for ordered flag."); 00159 else if (iGeomSet) ordered = moab::MESHSET_ORDERED; 00160 else if (-1 == ordered_flag && iGeomEnt) { 00161 err = igeom_instance()->getEntType(iGeomEnt, this_tp); 00162 IBERRCHK(err, "Trouble getting entity type."); 00163 if (iBase_EDGE == this_tp) 00164 ordered = moab::MESHSET_ORDERED; 00165 } 00166 00167 // create the set 00168 moab::ErrorCode rval = mkCore->moab_instance(meshIndex)->create_meshset(ordered, moabEntSet); 00169 MBERRCHK(rval, mkCore->moab_instance()); 00170 00171 // set dimension tag and global id tag 00172 if (iBase_ALL_TYPES != this_tp) { 00173 rval = mkCore->moab_instance(meshIndex)->tag_set_data(mkCore->moab_geom_dim_tag(), &moabEntSet, 1, &this_tp); 00174 MBERRCHK(rval, mkCore->moab_instance()); 00175 // set the id tag; get it with id(); if it returns -1, set a value 0 00176 int id_from_geometry = id(); 00177 if (id_from_geometry==-1) 00178 id_from_geometry = 0; 00179 rval = mkCore->moab_instance(meshIndex)->tag_set_data(mkCore->moab_global_id_tag(), &moabEntSet, 1, &id_from_geometry); 00180 MBERRCHK(rval, mkCore->moab_instance()); 00181 } 00182 00183 // tag it with this ModelEnt 00184 ModelEnt *this_ptr = this; 00185 rval = mkCore->moab_instance()->tag_set_data(mkCore->moab_model_tag(), &moabEntSet, 1, &this_ptr); 00186 MBERRCHK(rval, mkCore->moab_instance()); 00187 00188 // tag it with geometry dimension 00189 int geom_dim = this_tp; 00190 rval = mkCore->moab_instance()->tag_set_data(mkCore->moab_geom_dim_tag(), &moabEntSet, 1, &geom_dim); 00191 MBERRCHK(rval, mkCore->moab_instance()); 00192 00193 // relate the mesh to the geom, only if iRelFlag is true 00194 if (-1 != irelIndex) 00195 { 00196 iRel::Error merr; 00197 if (iGeomEnt) { 00198 merr = mkCore->irel_pair(irelIndex)->setEntSetRelation(iGeomEnt, IBSH(moabEntSet)); 00199 } 00200 else { 00201 merr = mkCore->group_set_pair()->setSetSetRelation(iGeomSet, IBSH(moabEntSet)); 00202 } 00203 IBERRCHK(merr, "Failed to set iRel relation for a mesh set."); 00204 } 00205 00206 if (iGeomEnt) init_parents_children(); 00207 else if (iGeomSet) init_group_contents(); 00208 00209 // now do senses wrt lower-dimensional entities, which should be initialized by now 00210 if (iGeomEnt) 00211 set_downward_senses(); 00212 } 00213 00214 void ModelEnt::init_parents_children() 00215 { 00216 // get parents and children, and link to corresponding sets; don't do this for any missing mesh sets, 00217 // will get done when those sets get created 00218 assert(iGeomEnt); 00219 std::vector<iGeom::EntityHandle> geom_adjs; 00220 std::vector<iGeom::EntityHandle>::iterator vit; 00221 moab::EntityHandle mseth; 00222 //moab::GeomTopoTool gt(mkCore->moab_instance(meshIndex), false); 00223 iBase_EntityType this_tp; 00224 moab::ErrorCode rval; 00225 iGeom::Error err = igeom_instance()->getEntType(iGeomEnt, this_tp); 00226 IBERRCHK(err, "Trouble getting entity type."); 00227 if (this_tp < iBase_REGION) { 00228 err = igeom_instance()->getEntAdj(iGeomEnt, (iBase_EntityType)(this_tp+1), geom_adjs); 00229 IBERRCHK(err, "Trouble finding parent entities."); 00230 for (vit = geom_adjs.begin(); vit != geom_adjs.end(); vit++) { 00231 try {mseth = mesh_handle(*vit); 00232 } 00233 catch (Error err) { 00234 // just continue, will get this when parent gets created later 00235 continue; 00236 } 00237 if (mseth) { 00238 rval = mkCore->moab_instance(meshIndex)->add_parent_child(mseth, moabEntSet); 00239 MBERRCHK(rval, mkCore->moab_instance(meshIndex)); 00240 } 00241 } 00242 } 00243 00244 if (this_tp > iBase_VERTEX) { 00245 geom_adjs.clear(); 00246 err = igeom_instance()->getEntAdj(iGeomEnt, (iBase_EntityType)(this_tp-1), geom_adjs); 00247 IBERRCHK(err, "Trouble finding child entities."); 00248 for (vit = geom_adjs.begin(); vit != geom_adjs.end(); vit++) { 00249 // should definitely have a mesh handle here, error if not 00250 mseth = mesh_handle(*vit); 00251 if (mseth) { 00252 rval = mkCore->moab_instance(meshIndex)->add_parent_child(moabEntSet, mseth); 00253 MBERRCHK(rval, mkCore->moab_instance(meshIndex)); 00254 } 00255 } 00256 } 00257 } 00258 00259 void ModelEnt::init_group_contents() 00260 { 00261 // should only be calling this function if we have a geometry set and a mesh index 00262 assert(-1 != meshIndex && iGeomSet); 00263 00264 // get the geometry entities in this group and add the corresponding mesh entity sets 00265 std::vector<iGeom::EntityHandle> geom_adjs; 00266 std::vector<iGeom::EntityHandle>::iterator vit; 00267 moab::EntityHandle mseth; 00268 moab::ErrorCode rval; 00269 iGeom::Error err = igeom_instance()->getEntities(iGeomSet, iBase_ALL_TYPES, geom_adjs); 00270 IBERRCHK(err, "Trouble finding parent entities."); 00271 for (vit = geom_adjs.begin(); vit != geom_adjs.end(); vit++) { 00272 mseth = 0; 00273 try {mseth = mesh_handle(*vit); 00274 } 00275 catch (Error) { 00276 // just continue, will get this when parent gets created later 00277 continue; 00278 } 00279 if (mseth) { 00280 rval = mkCore->moab_instance(meshIndex)->add_entities(moabEntSet, &mseth, 1); 00281 MBERRCHK(rval, mkCore->moab_instance(meshIndex)); 00282 } 00283 } 00284 00285 // same for set members 00286 std::vector<iGeom::EntitySetHandle> geom_sadjs; 00287 std::vector<iGeom::EntitySetHandle>::iterator svit; 00288 err = igeom_instance()->getEntSets(iGeomSet, -1, geom_sadjs); 00289 IBERRCHK(err, "Trouble finding parent entities."); 00290 for (svit = geom_sadjs.begin(); svit != geom_sadjs.end(); svit++) { 00291 mseth = 0; 00292 try {mseth = mesh_handle(*svit); 00293 } 00294 catch (Error) { 00295 // just continue, will get this when parent gets created later 00296 continue; 00297 } 00298 if (mseth) { 00299 rval = mkCore->moab_instance(meshIndex)->add_entities(moabEntSet, &mseth, 1); 00300 MBERRCHK(rval, mkCore->moab_instance(meshIndex)); 00301 } 00302 } 00303 } 00304 00305 void ModelEnt::set_downward_senses() 00306 { 00307 // should have both mesh and geometry 00308 assert(iGeomEnt && moabEntSet && igeomIndex != -1 && meshIndex != -1); 00309 00310 // skip if vertex or edge 00311 if (dimension() <= 1) return; 00312 00313 int dim = dimension(); 00314 iGeom::Error err; 00315 MEntVector adjs; 00316 get_adjacencies(dim-1, adjs); 00317 00318 std::vector<int> senses; 00319 int dum_sense; 00320 std::vector<moab::EntityHandle> ments; 00321 moab::GeomTopoTool gt(mkCore->moab_instance(meshIndex)); 00322 for (MEntVector::iterator vit = adjs.begin(); vit != adjs.end(); vit++) { 00323 err = igeom_instance()->getSense((*vit)->geom_handle(), geom_handle(), dum_sense); 00324 IBERRCHK(err, "Problem getting senses."); 00325 moab::ErrorCode rval = gt.set_sense((*vit)->mesh_handle(), mesh_handle(), dum_sense); 00326 MBERRCHK(rval, mkCore->moab_instance(meshIndex)); 00327 } 00328 } 00329 00338 void ModelEnt::commit_mesh(moab::Range &mesh_ents, MeshedState mstate) 00339 { 00340 std::vector<moab::EntityHandle> ent_vec; 00341 std::copy(mesh_ents.begin(), mesh_ents.end(), std::back_inserter(ent_vec)); 00342 commit_mesh(&ent_vec[0], ent_vec.size(), mstate); 00343 } 00344 00351 void ModelEnt::commit_mesh(moab::EntityHandle *mesh_ents, 00352 int num_ents, 00353 MeshedState mstate) 00354 { 00355 assert(-1 != meshIndex); 00356 00357 // add them to the set 00358 moab::ErrorCode rval = mkCore->moab_instance(meshIndex)->add_entities(moabEntSet, mesh_ents, num_ents); 00359 MBERRCHK(rval, mkCore->moab_instance(meshIndex)); 00360 00361 meshedState = mstate; 00362 } 00363 00364 void ModelEnt::get_adjacencies(int dim, MEntVector &adjs) const 00365 { 00366 std::vector<iGeom::EntityHandle> gents; 00367 // this call assumes that we have geometry. Is that always true? 00368 // it would be possible to have ModelEnt without geometry (geometry handle null), 00369 // so then we should get adjacencies from mesh based geometry model. 00370 //we should really check if (igeomIndex>=0); 00371 iGeom::Error err = igeom_instance()->getEntAdj(geom_handle(), (iBase_EntityType)dim, gents); 00372 IBERRCHK(err, "Trouble getting geom adjacencies."); 00373 adjs.resize(gents.size()); 00374 iGeom::TagHandle mkmodeltag; 00375 err = igeom_instance()->getTagHandle("__MKModelEntityGeo", mkmodeltag); 00376 IBERRCHK(err, "Failed to get tag handle for model entity."); 00377 err = igeom_instance()->getArrData(&gents[0], adjs.size(), mkmodeltag, 00378 &adjs[0]); 00379 IBERRCHK(err, "Trouble getting ModelEnts for geom adjacencies."); 00380 } 00381 00382 int ModelEnt::dimension() const 00383 { 00384 if (iGeomEnt) { 00385 iBase_EntityType tp; 00386 iGeom::Error err = igeom_instance()->getEntType(iGeomEnt, tp); 00387 IBERRCHK(err, "Couldn't get geom entity type."); 00388 return (tp - iBase_VERTEX); 00389 } 00390 else if (moabEntSet) { 00391 int dim; 00392 moab::ErrorCode rval = moab_instance()->tag_get_data(mkCore->moab_geom_dim_tag(), &moabEntSet, 1, &dim); 00393 MBERRCHK(rval, moab_instance()); 00394 return dim; 00395 } 00396 else throw Error(MK_BAD_INPUT, "Couldn't get dimension for this ModelEnt."); 00397 } 00398 00399 double ModelEnt::measure() const 00400 { 00401 double meas; 00402 iGeom::Error err = igeom_instance()->measure(&iGeomEnt, 1, &meas); 00403 IBERRCHK(err, "Couldn't get geom entity measure."); 00404 return meas; 00405 } 00406 00407 double ModelEnt::measure_discrete() const 00408 { 00409 return measure(); 00410 } 00411 00412 void ModelEnt::evaluate(double x, double y, double z, 00413 double *close, 00414 double *direction, 00415 double *curvature1, 00416 double *curvature2) const 00417 { 00418 iGeom::Error err = iBase_SUCCESS; 00419 if (0 == dimension() || 3 == dimension()) { 00420 if (direction || curvature1 || curvature2) { 00421 MKERRCHK(Error(MK_BAD_INPUT), "Direction or curvature not available for entities of this type."); 00422 } 00423 else if (!close) { 00424 MKERRCHK(Error(MK_BAD_INPUT), "Must pass closest point pointer for output."); 00425 } 00426 } 00427 00428 if (0 == dimension()) { 00429 err = igeom_instance()->getVtxCoord(geom_handle(), close[0], close[1], close[2]); 00430 IBERRCHK(err, "Problem getting vertex coordinates."); 00431 return; 00432 } 00433 else if (3 == dimension()) { 00434 err = igeom_instance()->getEntClosestPt(geom_handle(), x, y, z, 00435 close[0], close[1], close[2]); 00436 IBERRCHK(err, "Problem getting closest point for this model entity."); 00437 } 00438 else { 00439 double cls[3], dir[3], curve1[3], curve2[3]; 00440 if (!close) close = cls; 00441 if (!direction) direction = dir; 00442 if (!curvature1) curvature1 = curve1; 00443 if (1 == dimension()) 00444 err = igeom_instance()->getEgEvalXYZ(geom_handle(), x, y, z, 00445 close[0], close[1], close[2], 00446 direction[0], direction[1], direction[2], 00447 curvature1[0], curvature1[1], curvature1[2]); 00448 else if (2 == dimension()) { 00449 if (!curvature2) curvature2 = curve2; 00450 err = igeom_instance()->getFcEvalXYZ(geom_handle(), x, y, z, 00451 close[0], close[1], close[2], 00452 direction[0], direction[1], direction[2], 00453 curvature1[0], curvature1[1], curvature1[2], 00454 curvature2[0], curvature2[1], curvature2[2]); 00455 } 00456 00457 IBERRCHK(err, "Couldn't evaluate model entity."); 00458 } 00459 } 00460 00461 int ModelEnt::id() const 00462 { 00463 // get a global id for this entity, if there is one 00464 if (geom_handle()) { 00465 iGeom::TagHandle gid_tag; 00466 iGeom::Error err = igeom_instance()->getTagHandle("GLOBAL_ID", gid_tag); 00467 if (iBase_SUCCESS == err) { 00468 int gid; 00469 err = igeom_instance()->getIntData(geom_handle(), gid_tag, gid); 00470 if (iBase_SUCCESS == err) return gid; 00471 } 00472 } 00473 00474 if (mesh_handle()) { 00475 moab::Tag gid_tag; 00476 00477 moab::ErrorCode err = mk_core()->moab_instance()->tag_get_handle("GLOBAL_ID", 00478 1, moab::MB_TYPE_INTEGER, 00479 gid_tag, moab::MB_TAG_SPARSE); 00480 if (moab::MB_SUCCESS == err) { 00481 int gid; 00482 moab::EntityHandle this_mesh = mesh_handle(); 00483 err = mk_core()->moab_instance()->tag_get_data(gid_tag, &this_mesh, 1, &gid); 00484 if (moab::MB_SUCCESS == err) return gid; 00485 } 00486 } 00487 00488 return -1; 00489 } 00490 00491 void ModelEnt::get_mesh(int dim, 00492 std::vector<moab::EntityHandle> &ments, 00493 bool bdy_too) 00494 { 00495 if (dim > dimension()) throw Error(MK_BAD_INPUT, "Called get_mesh for dimension %d on a %d-dimensional entity.", 00496 dim, dimension()); 00497 00498 if (!bdy_too || dim == dimension()) { 00499 // just owned entities, which will be in the set 00500 moab::ErrorCode rval = mk_core()->moab_instance()->get_entities_by_dimension(moabEntSet, dimension(), ments); 00501 MBERRCHK(rval, mkCore->moab_instance()); 00502 return; 00503 } 00504 00505 // filter out the cases where order matters and boundary is requested too 00506 else if (1 == dimension() && 0 == dim) { 00507 std::vector<moab::EntityHandle> tmp_edgevs, tmp_vvs; 00508 moab::ErrorCode rval = mk_core()->moab_instance()->get_entities_by_dimension(moabEntSet, 0, tmp_edgevs); 00509 MBERRCHK(rval, mkCore->moab_instance()); 00510 boundary(0, tmp_vvs); 00511 if (tmp_vvs.empty()) throw Error(MK_NOT_FOUND, "No mesh on bounding entity."); 00512 ments.push_back(tmp_vvs[0]); 00513 std::copy(tmp_edgevs.begin(), tmp_edgevs.end(), std::back_inserter(ments)); 00514 if (2 == tmp_vvs.size()) ments.push_back(tmp_vvs[1]); 00515 else if (1 == tmp_vvs.size()) ments.push_back(tmp_vvs[0]); 00516 return; 00517 } 00518 else { 00519 // remaining case is bdy_too=true and dim < dimension() 00520 // first, get dimension()-dimensional entities, then get dim-dimensional neighbors of those 00521 std::vector<moab::EntityHandle> tmp_ments; 00522 moab::ErrorCode rval = mk_core()->moab_instance()->get_entities_by_dimension(moabEntSet, dimension(), tmp_ments); 00523 MBERRCHK(rval, mkCore->moab_instance()); 00524 rval = mk_core()->moab_instance()->get_adjacencies(&tmp_ments[0], tmp_ments.size(), dim, false, ments, 00525 moab::Interface::UNION); 00526 MBERRCHK(rval, mkCore->moab_instance()); 00527 } 00528 } 00529 00530 void ModelEnt::boundary(int dim, 00531 std::vector<moab::EntityHandle> &bdy, 00532 std::vector<int> *senses, 00533 std::vector<int> *group_sizes) 00534 { 00535 MEntVector me_loop; 00536 std::vector<int> me_senses, me_group_sizes; 00537 boundary(dim, me_loop, &me_senses, &me_group_sizes); 00538 00539 MEntVector::iterator vit = me_loop.begin(); 00540 std::vector<int>::iterator sense_it = me_senses.begin(), grpsize_it = me_group_sizes.begin(); 00541 int gents_ctr = 0, first_ment = 0; 00542 00543 // packing into a single list, but need to keep track of loop/shell sizes; don't increment 00544 // grpsize_it here, just when we've done all the mes in this group 00545 for (vit = me_loop.begin(); vit != me_loop.end(); vit++, sense_it++) { 00546 std::vector<moab::EntityHandle> tmp_ments; 00547 (*vit)->get_mesh(dim, tmp_ments, true); 00548 if (*sense_it == SENSE_REVERSE) 00549 std::reverse(tmp_ments.begin(), tmp_ments.end()); 00550 if (2 == dimension() && 0 == dim) 00551 // assembling vertices on loops; don't do last, since that'll be the first of the 00552 // next edge 00553 std::copy(tmp_ments.begin(), tmp_ments.end()-1, std::back_inserter(bdy)); 00554 else 00555 std::copy(tmp_ments.begin(), tmp_ments.end(), std::back_inserter(bdy)); 00556 if (senses) { 00557 for (unsigned int i = 0; i < tmp_ments.size(); i++) senses->push_back(*sense_it); 00558 } 00559 if (group_sizes) { 00560 gents_ctr++; 00561 if (gents_ctr == *grpsize_it) { 00562 group_sizes->push_back(bdy.size()-first_ment); 00563 // first_ment will be the first element in the next group 00564 first_ment = bdy.size(); 00565 gents_ctr = 0; 00566 grpsize_it++; 00567 } // block at end of a given loop 00568 } // block updating group size 00569 } // over loop 00570 00571 } 00572 00573 void ModelEnt::boundary(int dim, 00574 MEntVector &entities, 00575 std::vector<int> *senses, 00576 std::vector<int> *group_sizes) 00577 { 00578 // for a given entity, return the bounding edges in the form of edge groups, 00579 // oriented ccw around surface 00580 int this_dim = dimension(); 00581 00582 // shouldn't be calling this function if we're a vertex 00583 if (this_dim == iBase_VERTEX) throw Error(MK_BAD_INPUT, "Shouldn't call this for a vertex."); 00584 else if (dim >= this_dim) throw Error(MK_BAD_INPUT, "Calling for boundary entities of equal or greater dimension.");; 00585 00586 // get (d-1)-adj ents & senses 00587 MEntVector tmp_ents; 00588 get_adjacencies(this_dim-1, tmp_ents); 00589 00590 // get out here if we're a curve 00591 if (1 == this_dim) { 00592 // it is important to order the vertices, especially for boundary 00593 // cases get_adjacency does not say anything about order 00594 if (tmp_ents.size() <= 1) // no worry 00595 { 00596 for (unsigned int i = 0; i < tmp_ents.size(); i++) { 00597 entities.push_back(tmp_ents[i]); 00598 if (senses) senses->push_back(SENSE_FORWARD); 00599 } 00600 } 00601 else 00602 { 00603 // we have at least 2 vertices; if more than 2, this is an error 00604 if (tmp_ents.size() > 2) 00605 throw Error(MK_FAILURE, " edge with too many vertices "); 00606 // we have now exactly 2 vertices; order them according to the 00607 // edge they come from 00608 int sense = 0; 00609 iGeom::Error rg = igeom_instance()->getEgVtxSense( geom_handle(),tmp_ents[0]->geom_handle(), 00610 tmp_ents[1]->geom_handle(), sense ); 00611 IBERRCHK(rg, "Trouble getting edge sense"); 00612 if (-1==sense) 00613 { 00614 // the vertices are reversed in adjacency list 00615 entities.push_back(tmp_ents[1]); 00616 entities.push_back(tmp_ents[0]); 00617 } 00618 else 00619 { 00620 // vertices are fine 00621 entities.push_back(tmp_ents[0]); 00622 entities.push_back(tmp_ents[1]); 00623 } 00624 if (senses) { 00625 senses->push_back(SENSE_FORWARD); 00626 senses->push_back(SENSE_FORWARD); 00627 } 00628 } 00629 return; // we need to get out, we treated a dim 1 entity 00630 } 00631 00632 // get adjacent entities into a sorted, mutable list 00633 MEntVector b_ents = tmp_ents; 00634 MEntSet dbl_curves, sgl_curves; 00635 00636 std::sort(b_ents.begin(), b_ents.end()); 00637 00638 while (!b_ents.empty()) { 00639 // get 1st in group 00640 00641 MEntVector group_stack, this_group; 00642 group_stack.push_back(b_ents.front()); 00643 00644 int current_senses_size = 0; 00645 if (senses) 00646 current_senses_size= senses->size(); 00647 // while there are still entities on the stack 00648 while (!group_stack.empty()) { 00649 00650 // pop one off & get its sense 00651 ModelEnt *this_entity = group_stack.back(); group_stack.pop_back(); 00652 00653 int this_sense; 00654 iGeom::Error err = 00655 igeom_instance()->getSense(this_entity->geom_handle(), geom_handle(), this_sense); 00656 IBERRCHK(err,"Error getting geometry sense"); 00657 00658 // if we already have this one, continue 00659 if ((0 != this_sense && 00660 std::find(this_group.begin(), this_group.end(), this_entity) != this_group.end()) || 00661 std::find(dbl_curves.begin(), dbl_curves.end(), this_entity) != dbl_curves.end()) 00662 continue; 00663 00664 // either way we need the d-2 entities 00665 MEntVector bridges; 00666 this_entity->get_adjacencies(dimension()-2, bridges); 00667 if (dimension()-2==0 && bridges.size()==2)// edge case; this_entity is an edge 00668 { 00669 // if the vertices are reversed, change them back 00670 int sense_vertices = 0; 00671 iGeom::Error rg = igeom_instance()->getEgVtxSense(this_entity->geom_handle(), 00672 bridges[0]->geom_handle(), 00673 bridges[1]->geom_handle(), sense_vertices ); 00674 IBERRCHK(rg, "Trouble getting edge sense"); 00675 if (-1==sense_vertices) 00676 { 00677 // reverse the order of bridges; 00678 // a better fix would be to have the bridges from get_adjacencies in order 00679 // this would mean that children of sets should be returned in the order they 00680 // were inserted as children (maybe too hard to control that) 00681 ModelEnt * tmp = bridges[0]; 00682 bridges[0] = bridges[1]; 00683 bridges[1] = tmp; 00684 } 00685 00686 } 00687 00688 // only remove from the list of candidates if it's not dual-sensed 00689 if (0 != this_sense) 00690 b_ents.erase(std::remove(b_ents.begin(), b_ents.end(), this_entity), b_ents.end()); 00691 00692 // if it's double-sensed and this is the first time we're seeing it, find the right sense 00693 else { 00694 assert(dimension() == 2); 00695 if (std::find(sgl_curves.begin(), sgl_curves.end(), this_entity) == sgl_curves.end()) { 00696 sgl_curves.insert(this_entity); 00697 if (!this_group.empty()) { 00698 ModelEnt *common_v = this_entity->shared_entity(this_group.back(), 0); 00699 if (common_v == bridges[0]) this_sense = 1; 00700 else if (common_v == bridges[1]) this_sense = -1; 00701 else assert(false); 00702 } 00703 // else, if this is the first one in the loop, just choose a sense 00704 else { 00705 this_sense = 1; 00706 } 00707 } 00708 else { 00709 // else this is the second time we're seeing it, move it to the dbl_curves list and remove 00710 // from the candidates list 00711 dbl_curves.insert(this_entity); 00712 sgl_curves.erase(this_entity); 00713 b_ents.erase(std::remove(b_ents.begin(), b_ents.end(), this_entity), b_ents.end()); 00714 if (senses) { 00715 // need to get the sense of the first appearance in list 00716 MEntVector::iterator vit = std::find(this_group.begin(), this_group.end(), this_entity); 00717 assert(vit != this_group.end()); 00718 int other_sense = (*senses)[current_senses_size + vit-this_group.begin()]; 00719 this_sense = SENSE_REVERSE*other_sense; 00720 } 00721 } 00722 } 00723 00724 // it's in the group; put on group & remove from untreated ones 00725 this_group.push_back(this_entity); 00726 if (senses) senses->push_back(this_sense); 00727 MEntVector tmp_from, tmp_adjs; 00728 00729 // if we're on a face and we're the first in a group, check sense of this first 00730 // edge; make sure "next" in loop sense is last on list 00731 if (2 == dimension() && this_group.size() == 1) { 00732 00733 // get vertex which we know is shared by the "right" next edge; first get the vertices 00734 // if sense of current edge is forward, it's the 2nd vertex we want, 00735 // otherwise the first 00736 if (1 == this_sense && bridges.size() > 1) tmp_from.push_back(bridges[1]); 00737 else tmp_from.push_back(bridges[0]); 00738 tmp_adjs = b_ents; 00739 get_adjs_bool(tmp_from, dimension()-1, tmp_adjs, INTERSECT); 00740 } 00741 else { 00742 std::copy(bridges.begin(), bridges.end(), std::back_inserter(tmp_from)); 00743 MEntVector tmp_adjs2; 00744 get_adjs_bool(tmp_from, dimension()-1, tmp_adjs2, UNION); 00745 std::sort(tmp_adjs2.begin(), tmp_adjs2.end()); 00746 tmp_adjs.resize(tmp_adjs2.size()); 00747 tmp_adjs.erase(std::set_intersection(b_ents.begin(), b_ents.end(), 00748 tmp_adjs2.begin(), tmp_adjs2.end(), 00749 tmp_adjs.begin()), tmp_adjs.end()); 00750 } 00751 00752 if (2 == dimension() && tmp_adjs.size() > 1) { 00753 // more than one adjacent edge - need to evaluate winding angle to find right one 00754 ModelEnt *next_ent = next_winding(this_entity, this_sense, tmp_adjs); 00755 if (NULL == next_ent) return; 00756 group_stack.push_back(next_ent); 00757 } 00758 else if (!tmp_adjs.empty()) 00759 std::copy(tmp_adjs.begin(), tmp_adjs.end(), std::back_inserter(group_stack)); 00760 } 00761 00762 // put group in group list 00763 std::copy(this_group.begin(), this_group.end(), std::back_inserter(entities)); 00764 if (group_sizes) group_sizes->push_back(this_group.size()); 00765 } 00766 } 00767 00768 ModelEnt *ModelEnt::shared_entity(ModelEnt *ent2, int to_dim) 00769 { 00770 // find the shared entity between the two entities of the prescribed dimension 00771 MEntVector from_ents(2), to_ents; 00772 from_ents[0] = this; 00773 from_ents[1] = ent2; 00774 try { 00775 get_adjs_bool(from_ents, to_dim, to_ents, INTERSECT, false); 00776 } 00777 catch (Error err) { 00778 if (err.error_code() != MK_SUCCESS || to_ents.empty()) return NULL; 00779 } 00780 00781 if (to_ents.size() > 1) throw Error(MK_MULTIPLE_FOUND, "Multiple shared entities found."); 00782 00783 return to_ents[0]; 00784 } 00785 00786 void ModelEnt::get_adjs_bool(MEntVector &from_ents, 00787 int to_dim, 00788 MEntVector &to_ents, 00789 BooleanType op_type, 00790 bool only_to_ents) 00791 { 00792 if (from_ents.empty()) { 00793 to_ents.clear(); 00794 return; 00795 } 00796 00797 MEntVector bridges; 00798 00799 MEntVector::iterator from_it = from_ents.begin(); 00800 if (to_ents.empty() && !only_to_ents && op_type == INTERSECT) { 00801 from_ents.front()->get_adjacencies(to_dim, bridges); 00802 std::copy(bridges.begin(), bridges.end(), std::back_inserter(to_ents)); 00803 from_it++; 00804 } 00805 00806 std::sort(to_ents.begin(), to_ents.end()); 00807 MEntVector result_ents(to_ents.size()); 00808 for (; from_it != from_ents.end(); from_it++) { 00809 bridges.clear(); 00810 (*from_it)->get_adjacencies(to_dim, bridges); 00811 if (op_type == INTERSECT) { 00812 std::sort(bridges.begin(), bridges.end()); 00813 result_ents.erase(std::set_intersection(to_ents.begin(), to_ents.end(), 00814 bridges.begin(), bridges.end(), 00815 result_ents.begin()), result_ents.end()); 00816 } 00817 else { 00818 std::copy(bridges.begin(), bridges.end(), std::back_inserter(result_ents)); 00819 } 00820 00821 to_ents = result_ents; 00822 } 00823 00824 if (op_type == UNION) 00825 std::sort(to_ents.begin(), to_ents.end()); 00826 00827 to_ents.erase(std::unique(to_ents.begin(), to_ents.end()), to_ents.end()); 00828 } 00829 00830 ModelEnt *ModelEnt::next_winding(ModelEnt *this_edge, 00831 int this_sense, 00832 MEntVector &tmp_adjs) 00833 { 00834 // given this_entity, a d-1 entity bounding gentity, and optional "next" 00835 // entities in tmp_adjs, find the next one based on windings around the shared 00836 // vertex 00837 00838 // first, get the shared vertex 00839 MEntVector verts; 00840 this_edge->get_adjacencies(0, verts); 00841 00842 ModelEnt *shared_vert = verts[0]; 00843 if (this_sense == 1 && verts.size() > 1) shared_vert = verts[1]; 00844 00845 // get locations just before the vertex, at the vertex, and just after the vertex 00846 double v1[3], v2[3], v3[3]; 00847 double umin, umax; 00848 igeom_instance()->getEntURange(this_edge->geom_handle(), umin, umax); 00849 double utgt; 00850 if (1 == this_sense) utgt = umin + 0.9 * (umax - umin); 00851 else utgt = umin + 0.1 * (umax - umin); 00852 igeom_instance()->getEntUtoXYZ(this_edge->geom_handle(), utgt, v1[0], v1[1], v1[2]); 00853 igeom_instance()->getVtxCoord(shared_vert->geom_handle(), v2[0], v2[1], v2[2]); 00854 double v21[] = {v1[0]-v2[0], v1[1]-v2[1], v1[2]-v2[2]}; 00855 VecUtil::normalize(v21); 00856 00857 // get the normal vector at the vertex 00858 double normal[3]; 00859 igeom_instance()->getEntNrmlXYZ(geom_handle(), v2[0], v2[1], v2[2], 00860 normal[0], normal[1], normal[2]); 00861 00862 // now loop over candidates, finding magnitude of swept angle 00863 ModelEnt *other = NULL; 00864 double angle = VecUtil::TWO_PI; 00865 bool is_adj; 00866 for (MEntVector::iterator vit = tmp_adjs.begin(); vit != tmp_adjs.end(); vit++) { 00867 // if we're here, we have multiple candidates, therefore don't choose the same one 00868 if (*vit == this_edge) 00869 continue; 00870 igeom_instance()->isEntAdj((*vit)->geom_handle(), shared_vert->geom_handle(), is_adj); 00871 if (!is_adj) 00872 continue; 00873 00874 // get param range 00875 igeom_instance()->getEntURange((*vit)->geom_handle(), umin, umax); 00876 // get sense 00877 int tmp_sense; 00878 igeom_instance()->getSense((*vit)->geom_handle(), geom_handle(), tmp_sense); 00879 if (1 == tmp_sense) utgt = umin + 0.1 * (umax - umin); 00880 else utgt = umin + 0.9 * (umax - umin); 00881 igeom_instance()->getEntUtoXYZ((*vit)->geom_handle(), utgt, v3[0], v3[1], v3[2]); 00882 double v23[] = {v3[0]-v2[0], v3[1]-v2[1], v3[2]-v2[2]}; 00883 VecUtil::normalize(v23); 00884 00885 VecUtil::cross(normal, v23, v1); 00886 00887 VecUtil::cross(v1, normal, v3); 00888 00889 double x = VecUtil::dot(v21, v3); 00890 double y = VecUtil::dot(v21, v1); 00891 00892 assert(x != 0.0 || y != 0.0); 00893 double this_angle = atan2(y, x); 00894 if (this_angle < 0.0) 00895 { 00896 this_angle += VecUtil::TWO_PI; 00897 } 00898 if (this_angle < angle) { 00899 other = *vit; 00900 angle = this_angle; 00901 } 00902 } 00903 00904 return other; 00905 } 00906 00907 void ModelEnt::boundary(int dim, 00908 moab::Range &ents) const 00909 { 00910 throw Error(MK_NOT_IMPLEMENTED, "Not implemented yet."); 00911 } 00912 00913 void ModelEnt::get_indexed_connect_coords(std::vector<moab::EntityHandle> &ents, 00914 std::vector<int> *senses, 00915 moab::Tag tagh, 00916 std::vector<int> &ents_as_ids, 00917 std::vector<double> &coords, 00918 moab::Range *verts_range, 00919 int start_index) 00920 { 00921 // if we need to, make a tag 00922 moab::ErrorCode rval; 00923 bool i_created_tag = false; 00924 if (0 == tagh) { 00925 //rval = mk_core()->moab_instance()->tag_create("__ModelEntidtag", sizeof(int), moab::MB_TAG_DENSE, 00926 // moab::MB_TYPE_INTEGER, tagh, NULL); 00927 rval = mk_core()->moab_instance()->tag_get_handle("__ModelEntidtag", 1, moab::MB_TYPE_INTEGER, tagh, 00928 moab::MB_TAG_DENSE|moab::MB_TAG_CREAT); 00929 MBERRCHK(rval, mkCore->moab_instance()); 00930 i_created_tag = true; 00931 } 00932 00933 // put entities into range, after clearing it 00934 moab::Range tmp_range, ents_range; 00935 if (!verts_range) verts_range = &tmp_range; 00936 verts_range->clear(); 00937 00938 std::copy(ents.begin(), ents.end(), moab::range_inserter(ents_range)); 00939 bool all_verts = (mkCore->moab_instance()->type_from_handle(*ents_range.begin()) == 00940 mkCore->moab_instance()->type_from_handle(*ents_range.begin()) && 00941 mkCore->moab_instance()->type_from_handle(*ents_range.begin()) == moab::MBVERTEX); 00942 00943 00944 // get connectivity of all ents and store in range 00945 if (!all_verts) { 00946 rval = mkCore->moab_instance()->get_connectivity(ents_range, *verts_range); 00947 MBERRCHK(rval, mkCore->moab_instance()); 00948 } 00949 else *verts_range = ents_range; 00950 00951 // resize index array, to max number of connectivity entries 00952 int max_numconnect = moab::CN::VerticesPerEntity(mkCore->moab_instance()->type_from_handle(*(ents_range.rbegin()))); 00953 ents_as_ids.resize(ents.size()*max_numconnect); 00954 00955 // temporarily store ids in ents_as_ids array, and set id tag 00956 assert(ents_as_ids.size() >= verts_range->size()); 00957 for (unsigned int i = 0; i < verts_range->size(); i++) ents_as_ids[i] = i+start_index; 00958 rval = mk_core()->moab_instance()->tag_set_data(tagh, *verts_range, &ents_as_ids[0]); 00959 MBERRCHK(rval, mkCore->moab_instance()); 00960 00961 // get ids into ids vector in connectivity or ents order 00962 if (all_verts) { 00963 rval = mk_core()->moab_instance()->tag_get_data(tagh, &ents[0], ents.size(), &ents_as_ids[0]); 00964 MBERRCHK(rval, mkCore->moab_instance()); 00965 ents_as_ids.resize(ents.size()); 00966 } 00967 else { 00968 // loop over entities 00969 std::vector<moab::EntityHandle> storage; 00970 const moab::EntityHandle *connect; 00971 int num_connect; 00972 unsigned int last = 0; 00973 for (unsigned int i = 0; i < ents.size(); i++) { 00974 // first, get connect vector 00975 mk_core()->moab_instance()->get_connectivity(ents[i], connect, num_connect, true, &storage); 00976 MBERRCHK(rval, mk_core()->moab_instance()); 00977 assert(ents_as_ids.size() >= last + num_connect); 00978 // next, get ids and put into ids vector 00979 rval = mk_core()->moab_instance()->tag_get_data(tagh, connect, num_connect, &ents_as_ids[last]); 00980 MBERRCHK(rval, mk_core()->moab_instance()); 00981 // reverse if necessary 00982 assert(!senses || (*senses)[i] != SENSE_BOTH); 00983 if (senses && (*senses)[i] == SENSE_REVERSE) std::reverse(&ents_as_ids[last], &ents_as_ids[last+num_connect]); 00984 // update last 00985 last += num_connect; 00986 } 00987 } 00988 00989 // get coords for range-ordered vertices 00990 coords.resize(3*verts_range->size()); 00991 rval = mk_core()->moab_instance()->get_coords(*verts_range, &coords[0]); 00992 MBERRCHK(rval, mk_core()->moab_instance()); 00993 00994 // delete the tag if I created it 00995 if (i_created_tag) { 00996 rval = mk_core()->moab_instance()->tag_delete(tagh); 00997 MBERRCHK(rval, mkCore->moab_instance()); 00998 } 00999 } 01000 01001 iGeom::EntityHandle ModelEnt::geom_handle(moab::EntityHandle ment) const 01002 { 01003 // use iRel to get this information or use model entity tag 01004 iBase_EntityHandle gent = 0; 01005 if (-1 != irelIndex) 01006 { 01007 Error err = mkCore->irel_pair(irelIndex)->getSetEntRelation(IBSH(ment), true, gent); 01008 MKERRCHK(err, "Failed to get geometry handle for mesh set."); 01009 return gent; 01010 } 01011 else 01012 { 01013 // use the model entity tag from moab instance... assume only one here 01014 //moab::Tag moabModelTag = mkCore->moab_model_tag(); 01015 ModelEnt *modelEnt = NULL; 01016 moab::ErrorCode rval = mkCore->moab_instance()->tag_get_data(mkCore->moab_model_tag(), &ment, 1, &modelEnt); 01017 MBERRCHK(rval, mkCore->moab_instance()); 01018 if (NULL == modelEnt) 01019 return gent;// still null 01020 return modelEnt->geom_handle(); 01021 } 01022 } 01023 01024 iGeom *ModelEnt::igeom_instance() const 01025 { 01026 if (-1 == igeomIndex) throw Error(MK_FAILURE, "No geometry instance associated with this ModelEnt."); 01027 return mkCore->igeom_instance(igeomIndex); 01028 } 01029 01030 moab::Interface *ModelEnt::moab_instance() const 01031 { 01032 if (-1 == meshIndex) throw Error(MK_FAILURE, "No moab instance associated with this ModelEnt."); 01033 return mkCore->moab_instance(meshIndex); 01034 } 01035 01036 moab::EntityHandle ModelEnt::mesh_handle(iGeom::EntityHandle gent) const 01037 { 01038 // use iRel to get this information or use model entity tag 01039 moab::EntityHandle ment = 0; 01040 if (-1 != irelIndex) 01041 { 01042 iBase_EntitySetHandle h; 01043 iRel::Error err = mkCore->irel_pair(irelIndex)->getEntSetRelation(gent, false, h); 01044 IBERRCHK(err, "Failed to get mesh set handle for geometry entity."); 01045 return reinterpret_cast<moab::EntityHandle>(h); 01046 } 01047 else 01048 { 01049 // if no irel, use the model entity tag from the igeom instance 01050 // 01051 if (!igeom_instance()) 01052 return ment;// NULL so far 01053 iGeom::TagHandle mkmodeltag; 01054 iBase_ErrorType err = igeom_instance()->getTagHandle("__MKModelEntityGeo", mkmodeltag); 01055 IBERRCHK(err, "Failed to get tag handle for model entity."); 01056 // now get the model entity 01057 ModelEnt * modelEnt = NULL; 01058 err = igeom_instance()->getData(gent, mkmodeltag, &modelEnt); 01059 if (NULL == modelEnt || iBase_TAG_NOT_FOUND == err) 01060 return ment;// still null 01061 return modelEnt->mesh_handle(); 01062 } 01063 01064 } 01065 01066 moab::EntityHandle ModelEnt::mesh_handle(iGeom::EntitySetHandle gent) const 01067 { 01068 // use iRel to get this information or use model entity tag 01069 moab::EntityHandle ment = 0; 01070 if (-1 != irelIndex) 01071 { 01072 iBase_EntitySetHandle h; 01073 iRel::Error err = mkCore->group_set_pair(irelIndex)->getSetSetRelation(gent, false, h); 01074 IBERRCHK(err, "Failed to get mesh set handle for geometry entity."); 01075 return reinterpret_cast<moab::EntityHandle>(h); 01076 } 01077 else 01078 { 01079 // if no irel, use the model entity tag from the igeom instance 01080 // 01081 if (-1 == igeomIndex) 01082 return ment;// NULL so far 01083 iGeom::TagHandle mkmodeltag; 01084 iBase_ErrorType err = igeom_instance()->getTagHandle("__MKModelEntityGeo", mkmodeltag); 01085 IBERRCHK(err, "Failed to get tag handle for model entity."); 01086 // now get the model entity 01087 ModelEnt * modelEnt = NULL; 01088 err = igeom_instance()->getEntSetData(gent, mkmodeltag, &modelEnt); 01089 if (NULL == modelEnt || iBase_TAG_NOT_FOUND == err) 01090 return ment;// still null 01091 return modelEnt->mesh_handle(); 01092 } 01093 01094 } 01095 01100 double ModelEnt::mesh_interval_size() const 01101 { 01102 if (-1 != sizing_function_index() && mk_core()->sizing_function(sizing_function_index()) && 01103 -1 != mk_core()->sizing_function(sizing_function_index())->size()) 01104 return mk_core()->sizing_function(sizing_function_index())->size(); 01105 01106 else if (1 == dimension() && -1 != mesh_intervals() && 0 != mesh_intervals()) 01107 return measure() / mesh_intervals(); 01108 01109 else return -1; 01110 } 01111 01112 } // namespace MeshKit 01113