MeshKit  1.0
MBSplitOp.cpp
Go to the documentation of this file.
00001 /*
00002  * \file MBSplitOp.cpp
00003  *
00004  *  Created on: Oct 2, 2011
00005  *      Author: iulian
00006  */
00007 
00008 #include "meshkit/MBSplitOp.hpp"
00009 #include "meshkit/ModelEnt.hpp"
00010 
00011 #include "moab/Core.hpp"
00012 #include "meshkit/FBiGeom.hpp"
00013 #include "moab/FBEngine.hpp"
00014 
00015 // #include "meshkit/MBGeomOp.hpp"
00016 
00017 namespace MeshKit {
00018 
00019 //Entity Type initialization for splitting; no mesh output
00020 moab::EntityType MBSplitOp_tps[] = { moab::MBMAXTYPE }; // no mesh, really
00021 const moab::EntityType* MBSplitOp::output_types()
00022 {
00023   return MBSplitOp_tps;
00024 }
00025 
00026 MBSplitOp::MBSplitOp(MKCore *mk_core, const MEntVector &me_vec) :
00027   MeshScheme(mk_core, me_vec)
00028 {
00029   _globalId = -1;
00030   _direction[0]=_direction[1]=0.;
00031   _direction[2]=1.0;
00032   _closed = 1;
00033   _min_dot = 0.8;// acos(0.8)~= 36 degrees
00034 }
00035 
00036 MBSplitOp::~MBSplitOp()
00037 {
00038 }
00039 
00040 //set up the crop/split of a mesh based surface
00041 void MBSplitOp::set_options(int globalId, double dirx, double diry,
00042     double dirz, int closed, double min_dot)
00043 {
00044   _globalId = globalId;
00045   /*for (int i=0; i<nPoints*3; i++)
00046    _polyline.push_back(polyline[i]);*/
00047 
00048   _direction[0] = dirx;
00049   _direction[1] = diry;
00050   _direction[2] = dirz;
00051   _closed = closed;
00052   _min_dot = min_dot;
00053   return;
00054 }
00055 void MBSplitOp::add_points(double x, double y, double z)
00056 {
00057   _polyline.push_back(x);
00058   _polyline.push_back(y);
00059   _polyline.push_back(z);
00060   return;
00061 }
00062 // model entities should be created on mesh based geometry
00063 void MBSplitOp::setup_this()
00064 {
00065 
00066 }
00067 
00068 // it is not a true mesh operation, it is a geometry operation
00069 void MBSplitOp::execute_this()
00070 {
00071   if (mentSelection.empty())
00072   {
00073     // change of strategy: do not return, go to
00074     // previous operation, find the result  (either another split or
00075     // an initial MBGeomOp, get the Range of the first mapped entity)
00076     // this will be the input to create other "ModelEnt"s, (mesh based geo)
00077     // find previous operation:
00078     GraphNode * prevNode = other_node(in_arcs());
00079 
00080     MeshOp * prevOp = reinterpret_cast<MeshOp*> (prevNode);
00081     std::string nameOp = prevNode->get_name();// just for debugging
00082 
00083     if (NULL==prevOp)
00084       return;
00085 
00086     MEntSelection & mentsel = prevOp->me_selection();
00087     // ments[0]
00088     ModelEnt * firstMe = (*(mentsel.begin()) ).first;
00089     moab::Range prevModelSet = mentsel[firstMe];
00090 
00091     if (prevModelSet.size()!=1)
00092       return;
00093 
00094     // this range has one set that can serve as basis for
00095     // mesh based geometry
00096     // the model ents have no model tag on the sets!!
00097     MEntVector model_ents; // existing model ents of dimension 2
00098     // the new ones will be put in the mentSelection!!!
00099     mk_core()->get_entities_by_dimension(2, model_ents);
00100     // assume moab_instance 0
00101     mk_core()->create_mbg_model_entities(prevModelSet[0], false);
00102 
00103     MEntVector model_ent_new; // existing model ents of dimension 2
00104         // the new ones will be put in the mentSelection!!!
00105     MEntVector model_ents_new; // all model ents of dimension 2...
00106     mk_core()->get_entities_by_dimension(2, model_ents_new);
00107 
00108     for (unsigned int i = model_ents.size(); i<model_ents_new.size(); i++)
00109     {
00110       moab::Range rr = mentSelection[model_ents_new[i]];
00111       rr.clear(); // just to use it , to avoid some warnings
00112     }
00113     //return;
00114   }
00115 
00116   // go through the map, to find the set with the given globalId
00117   // find the set of dimension 2, with the global id matching
00118   MEntSelection::iterator mit;
00119 
00120   moab::Interface * MBI = mk_core()->moab_instance();
00121   moab::EntityHandle mset;
00122   moab::Tag gid = mk_core()->moab_global_id_tag();
00123   moab::ErrorCode rval;
00124   int id = -1;
00125   for (mit = mentSelection.begin(); mit != mentSelection.end(); mit++) {
00126     mset = (mit->first)->mesh_handle();
00127     // get the globalId tag
00128 
00129     rval = MBI->tag_get_data(gid, &mset, 1, &id);
00130     MBERRCHK(rval, MBI);
00131     if (_globalId == id)
00132       break;
00133   }
00134   if (id != _globalId) {
00135     std::cout << " the face not found, abort\n";
00136     return;
00137   }
00138   //
00139   // get the one and only model entity, which should be of dimension 2, and geometrize it
00140   // this should be the model entity handle
00141 
00142   iGeom::EntityHandle gent = (mit->first)->geom_handle();
00143   if (gent != 0) {
00144     std::cout << "geometry exists on the model ent; Abort.\n";
00145     return; //
00146   }
00147 
00148   moab::FBEngine * pFacet = new moab::FBEngine(MBI,
00149       NULL, true);
00150 
00151   rval = pFacet->Init();
00152   MBERRCHK(rval, MBI);
00153 
00154   // the mset will be split according to the rule
00155 
00156   moab::EntityHandle newFace;
00157   rval = pFacet->split_surface_with_direction(mset, _polyline, _direction, _closed, _min_dot,
00158       newFace);
00159 
00160   MBERRCHK(rval, MBI);
00161 
00162   // at the end of this, moab database will contain new gsets, for the split eometry
00163   // the old pFacet should be cleaned and deleted
00164   //
00165   pFacet->delete_smooth_tags();
00166   delete pFacet;// will trigger a cleanup , including deleting the
00167   // smooth faces, edges, and tags;
00168   // now, the moab db would be ready for another round, including meshing...
00169   // maybe not all surfaces need to be meshed, only the "result" new face
00170   // it will get a new id too;
00171 
00172   // the result of the split operation will be a set encompassing all the
00173   // gsets that form the current topological model
00174   // and the newFace + g children of it
00175   // the root model could be used for a new GeomTopoTool, as in
00176   //  new  GeomTopoTool(mb, true, newRootModel);
00177   moab::EntityHandle newRootModel;
00178   rval = MBI->create_meshset(moab::MESHSET_SET, newRootModel);
00179   MBERRCHK(rval, MBI);
00180   // add to this root model set all the moabEntSets from model ents in this
00181   // MeshOp, and all children of the newFace !!!
00182   // collect in newRootModel all gsets...
00183   // they should form a "correct" topo model; (check!)
00184   for (mit = mentSelection.begin(); mit != mentSelection.end(); mit++) {
00185     mset = (mit->first)->mesh_handle();
00186     // get all children of this set
00187     moab::Range children;
00188     rval = MBI->get_child_meshsets(mset, children, 0); // all children
00189     MBERRCHK(rval, MBI);
00190     children.insert(mset); // insert the current face too
00191     rval = MBI->add_entities(newRootModel, children);
00192     MBERRCHK(rval, MBI);
00193   }
00194   // add the new face children too
00195   moab::Range children;
00196   rval = MBI->get_child_meshsets(newFace, children, 0); // all children
00197   MBERRCHK(rval, MBI);
00198   children.insert(newFace);
00199   rval = MBI->add_entities(newRootModel, children);
00200   MBERRCHK(rval, MBI);
00201   // add to the mentSelection of first model entity
00202   ModelEnt * firstModelEnt = (mentSelection.begin())->first;
00203   mentSelection[firstModelEnt].insert(newRootModel);
00204   return;
00205 }
00206 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines