Branch data Line data Source code
1 : : /*
2 : : * \file MBSplitOp.cpp
3 : : *
4 : : * Created on: Oct 2, 2011
5 : : * Author: iulian
6 : : */
7 : :
8 : : #include "meshkit/MBSplitOp.hpp"
9 : : #include "meshkit/ModelEnt.hpp"
10 : :
11 : : #include "moab/Core.hpp"
12 : : #include "meshkit/FBiGeom.hpp"
13 : : #include "moab/FBEngine.hpp"
14 : :
15 : : // #include "meshkit/MBGeomOp.hpp"
16 : :
17 : : namespace MeshKit {
18 : :
19 : : //Entity Type initialization for splitting; no mesh output
20 : : moab::EntityType MBSplitOp_tps[] = { moab::MBMAXTYPE }; // no mesh, really
21 : 40 : const moab::EntityType* MBSplitOp::output_types()
22 : : {
23 : 40 : return MBSplitOp_tps;
24 : : }
25 : :
26 : 1 : MBSplitOp::MBSplitOp(MKCore *mk_core, const MEntVector &me_vec) :
27 [ + - ]: 1 : MeshScheme(mk_core, me_vec)
28 : : {
29 : 1 : _globalId = -1;
30 : 1 : _direction[0]=_direction[1]=0.;
31 : 1 : _direction[2]=1.0;
32 : 1 : _closed = 1;
33 : 1 : _min_dot = 0.8;// acos(0.8)~= 36 degrees
34 : 1 : }
35 : :
36 : 0 : MBSplitOp::~MBSplitOp()
37 : : {
38 [ # # ]: 0 : }
39 : :
40 : : //set up the crop/split of a mesh based surface
41 : 1 : void MBSplitOp::set_options(int globalId, double dirx, double diry,
42 : : double dirz, int closed, double min_dot)
43 : : {
44 : 1 : _globalId = globalId;
45 : : /*for (int i=0; i<nPoints*3; i++)
46 : : _polyline.push_back(polyline[i]);*/
47 : :
48 : 1 : _direction[0] = dirx;
49 : 1 : _direction[1] = diry;
50 : 1 : _direction[2] = dirz;
51 : 1 : _closed = closed;
52 : 1 : _min_dot = min_dot;
53 : 1 : return;
54 : : }
55 : 5 : void MBSplitOp::add_points(double x, double y, double z)
56 : : {
57 : 5 : _polyline.push_back(x);
58 : 5 : _polyline.push_back(y);
59 : 5 : _polyline.push_back(z);
60 : 5 : return;
61 : : }
62 : : // model entities should be created on mesh based geometry
63 : 1 : void MBSplitOp::setup_this()
64 : : {
65 : :
66 : 1 : }
67 : :
68 : : // it is not a true mesh operation, it is a geometry operation
69 : 1 : void MBSplitOp::execute_this()
70 : : {
71 [ - + ]: 1 : if (mentSelection.empty())
72 : : {
73 : : // change of strategy: do not return, go to
74 : : // previous operation, find the result (either another split or
75 : : // an initial MBGeomOp, get the Range of the first mapped entity)
76 : : // this will be the input to create other "ModelEnt"s, (mesh based geo)
77 : : // find previous operation:
78 [ # # ][ # # ]: 0 : GraphNode * prevNode = other_node(in_arcs());
79 : :
80 : 0 : MeshOp * prevOp = reinterpret_cast<MeshOp*> (prevNode);
81 [ # # ]: 0 : std::string nameOp = prevNode->get_name();// just for debugging
82 : :
83 [ # # ]: 0 : if (NULL==prevOp)
84 : 0 : return;
85 : :
86 [ # # ]: 0 : MEntSelection & mentsel = prevOp->me_selection();
87 : : // ments[0]
88 [ # # ]: 0 : ModelEnt * firstMe = (*(mentsel.begin()) ).first;
89 [ # # ][ # # ]: 0 : moab::Range prevModelSet = mentsel[firstMe];
[ # # ]
90 : :
91 [ # # ][ # # ]: 0 : if (prevModelSet.size()!=1)
92 : 0 : return;
93 : :
94 : : // this range has one set that can serve as basis for
95 : : // mesh based geometry
96 : : // the model ents have no model tag on the sets!!
97 [ # # ][ # # ]: 0 : MEntVector model_ents; // existing model ents of dimension 2
98 : : // the new ones will be put in the mentSelection!!!
99 [ # # ][ # # ]: 0 : mk_core()->get_entities_by_dimension(2, model_ents);
100 : : // assume moab_instance 0
101 [ # # ][ # # ]: 0 : mk_core()->create_mbg_model_entities(prevModelSet[0], false);
[ # # ]
102 : :
103 [ # # ]: 0 : MEntVector model_ent_new; // existing model ents of dimension 2
104 : : // the new ones will be put in the mentSelection!!!
105 [ # # ]: 0 : MEntVector model_ents_new; // all model ents of dimension 2...
106 [ # # ][ # # ]: 0 : mk_core()->get_entities_by_dimension(2, model_ents_new);
107 : :
108 [ # # ]: 0 : for (unsigned int i = model_ents.size(); i<model_ents_new.size(); i++)
109 : : {
110 [ # # ][ # # ]: 0 : moab::Range rr = mentSelection[model_ents_new[i]];
[ # # ]
111 [ # # ]: 0 : rr.clear(); // just to use it , to avoid some warnings
112 : 0 : }
113 : : //return;
114 : : }
115 : :
116 : : // go through the map, to find the set with the given globalId
117 : : // find the set of dimension 2, with the global id matching
118 [ + - ]: 1 : MEntSelection::iterator mit;
119 : :
120 [ + - ][ + - ]: 1 : moab::Interface * MBI = mk_core()->moab_instance();
121 : : moab::EntityHandle mset;
122 [ + - ][ + - ]: 1 : moab::Tag gid = mk_core()->moab_global_id_tag();
123 : : moab::ErrorCode rval;
124 : 1 : int id = -1;
125 [ # # ][ + - ]: 1 : for (mit = mentSelection.begin(); mit != mentSelection.end(); mit++) {
[ + - ]
126 [ + - ][ + - ]: 1 : mset = (mit->first)->mesh_handle();
127 : : // get the globalId tag
128 : :
129 [ + - ]: 1 : rval = MBI->tag_get_data(gid, &mset, 1, &id);
130 [ - + ][ # # ]: 1 : MBERRCHK(rval, MBI);
[ # # ][ # # ]
131 [ + - ]: 1 : if (_globalId == id)
132 : 1 : break;
133 : : }
134 [ - + ]: 1 : if (id != _globalId) {
135 [ # # ]: 0 : std::cout << " the face not found, abort\n";
136 : 0 : return;
137 : : }
138 : : //
139 : : // get the one and only model entity, which should be of dimension 2, and geometrize it
140 : : // this should be the model entity handle
141 : :
142 [ + - ][ + - ]: 1 : iGeom::EntityHandle gent = (mit->first)->geom_handle();
143 [ - + ]: 1 : if (gent != 0) {
144 [ # # ]: 0 : std::cout << "geometry exists on the model ent; Abort.\n";
145 : 0 : return; //
146 : : }
147 : :
148 : : moab::FBEngine * pFacet = new moab::FBEngine(MBI,
149 [ + - ][ + - ]: 1 : NULL, true);
150 : :
151 [ + - ]: 1 : rval = pFacet->Init();
152 [ - + ][ # # ]: 1 : MBERRCHK(rval, MBI);
[ # # ][ # # ]
153 : :
154 : : // the mset will be split according to the rule
155 : :
156 : : moab::EntityHandle newFace;
157 : : rval = pFacet->split_surface_with_direction(mset, _polyline, _direction, _closed, _min_dot,
158 [ + - ]: 1 : newFace);
159 : :
160 [ - + ][ # # ]: 1 : MBERRCHK(rval, MBI);
[ # # ][ # # ]
161 : :
162 : : // at the end of this, moab database will contain new gsets, for the split eometry
163 : : // the old pFacet should be cleaned and deleted
164 : : //
165 [ + - ]: 1 : pFacet->delete_smooth_tags();
166 [ + - ]: 1 : delete pFacet;// will trigger a cleanup , including deleting the
167 : : // smooth faces, edges, and tags;
168 : : // now, the moab db would be ready for another round, including meshing...
169 : : // maybe not all surfaces need to be meshed, only the "result" new face
170 : : // it will get a new id too;
171 : :
172 : : // the result of the split operation will be a set encompassing all the
173 : : // gsets that form the current topological model
174 : : // and the newFace + g children of it
175 : : // the root model could be used for a new GeomTopoTool, as in
176 : : // new GeomTopoTool(mb, true, newRootModel);
177 : : moab::EntityHandle newRootModel;
178 [ + - ]: 1 : rval = MBI->create_meshset(moab::MESHSET_SET, newRootModel);
179 [ - + ][ # # ]: 1 : MBERRCHK(rval, MBI);
[ # # ][ # # ]
180 : : // add to this root model set all the moabEntSets from model ents in this
181 : : // MeshOp, and all children of the newFace !!!
182 : : // collect in newRootModel all gsets...
183 : : // they should form a "correct" topo model; (check!)
184 [ + - ][ + - ]: 2 : for (mit = mentSelection.begin(); mit != mentSelection.end(); mit++) {
[ + + ]
185 [ + - ][ + - ]: 1 : mset = (mit->first)->mesh_handle();
186 : : // get all children of this set
187 [ + - ]: 1 : moab::Range children;
188 [ + - ]: 1 : rval = MBI->get_child_meshsets(mset, children, 0); // all children
189 [ - + ][ # # ]: 1 : MBERRCHK(rval, MBI);
[ # # ][ # # ]
190 [ + - ]: 1 : children.insert(mset); // insert the current face too
191 [ + - ]: 1 : rval = MBI->add_entities(newRootModel, children);
192 [ - + ][ # # ]: 1 : MBERRCHK(rval, MBI);
[ # # ][ # # ]
193 : 1 : }
194 : : // add the new face children too
195 [ + - ]: 1 : moab::Range children;
196 [ + - ]: 1 : rval = MBI->get_child_meshsets(newFace, children, 0); // all children
197 [ - + ][ # # ]: 1 : MBERRCHK(rval, MBI);
[ # # ][ # # ]
198 [ + - ]: 1 : children.insert(newFace);
199 [ + - ]: 1 : rval = MBI->add_entities(newRootModel, children);
200 [ - + ][ # # ]: 1 : MBERRCHK(rval, MBI);
[ # # ][ # # ]
201 : : // add to the mentSelection of first model entity
202 [ + - ]: 1 : ModelEnt * firstModelEnt = (mentSelection.begin())->first;
203 [ + - ][ + - ]: 1 : mentSelection[firstModelEnt].insert(newRootModel);
204 : 1 : return;
205 : : }
206 [ + - ][ + - ]: 156 : }
|