MeshKit
1.0
|
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 }