MeshKit  1.0
ModelEnt.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines