Branch data Line data Source code
1 : : #include <assert.h>
2 : :
3 : : #include "meshkit/MeshOp.hpp"
4 : : #include "meshkit/MKCore.hpp"
5 : : #include "meshkit/ModelEnt.hpp"
6 : :
7 : : #include "lemon/adaptors.h"
8 : :
9 : : #include <set>
10 : :
11 : : namespace MeshKit
12 : : {
13 : :
14 : 0 : MeshOp::MeshOp(const MeshOp &mesh_op)
15 [ # # ]: 0 : : GraphNode(mesh_op)
16 : : {
17 : 0 : debugLevel=0;
18 : 0 : }
19 : :
20 : 245 : MeshOp::MeshOp(MKCore *mkcore, const MEntVector &me_vec)
21 [ + - ]: 245 : : GraphNode(mkcore)
22 : : {
23 : 245 : debugLevel=0;
24 [ + + ]: 245 : if (!me_vec.empty()) {
25 [ + - ][ + - ]: 260 : for (MEntVector::const_iterator vit = me_vec.begin(); vit != me_vec.end(); vit++)
[ + + ]
26 [ + - ][ + - ]: 165 : mentSelection[*vit];
27 : : }
28 : 245 : }
29 : :
30 : 29 : void MeshOp::setup_boundary()
31 : : {
32 : : // generic setup code; make sure there are MeshOp's for each of my bounding entities, and create
33 : : // ones where necessary (based on default MeshOp for that dimension registered with MOF)
34 : :
35 : : // use separate MeshOps by dimension, since there may be multiple dimension entities in mentSelection
36 : 29 : MeshOp *this_op[] = {NULL, NULL, NULL, NULL};
37 : :
38 [ + - ][ + - ]: 102 : for (MEntSelection::iterator mit = mentSelection.begin(); mit != mentSelection.end(); mit++) {
[ + + ]
39 [ + - ]: 73 : ModelEnt *this_ent = (*mit).first;
40 [ + - ]: 73 : int dim = this_ent->dimension();
41 [ - + ]: 74 : if (0 == dim) continue;
42 [ + - ][ + + ]: 73 : if (this_ent->get_meshed_state()>=COMPLETE_MESH)
43 : 1 : continue;
44 : :
45 [ + - ]: 72 : MEntVector children;
46 [ + - ]: 72 : this_ent->get_adjacencies(dim-1, children);
47 [ + - ][ + - ]: 434 : for (MEntVector::iterator chit = children.begin(); chit != children.end(); chit++) {
[ + + ]
48 [ + - ][ + - ]: 362 : if ((*chit)->is_meshops_list_empty()) {
[ + + ]
49 : : // no meshop, need to get one associated with this
50 [ + + ]: 227 : if (!this_op[dim-1]) {
51 [ + - ][ + - ]: 26 : this_op[dim-1] = mk_core()->construct_meshop(dim-1);
[ + - ]
52 [ - + ][ # # ]: 26 : if (!this_op[dim-1]) throw Error(MK_MESHOP_NOT_FOUND, "No default meshop for this dimension.");
53 : : }
54 [ + - ][ + - ]: 227 : this_op[dim-1]->add_modelent(*chit);
55 : : }
56 : : }
57 : 72 : }
58 : :
59 : : // VertexMesher should be inserted after root node to be done before other meshops
60 : : // It is because the VertexMesher instance is only one
61 [ - + ]: 29 : if (this_op[0]) {
62 [ # # ][ # # ]: 0 : mk_core()->insert_node(this_op[0], this, mk_core()->root_node());
[ # # ][ # # ]
63 : : }
64 : :
65 [ + + ]: 116 : for (int dim = 1; dim <= 3; dim++) {
66 [ + + ]: 87 : if (this_op[dim])
67 [ + - ][ + - ]: 26 : mk_core()->insert_node(this_op[dim], this);
68 : : }
69 : 29 : }
70 : :
71 : : // TODO: Split this into separate functions, one for ensuring dependence
72 : : // on a list of meshops, and the other for doing it with boundary
73 : 29 : void MeshOp::ensure_facet_dependencies(bool recurse_to_facets)
74 : : {
75 [ + - ]: 29 : std::set<MeshOp*> allFacetMOps;
76 : :
77 [ + - + - ]: 200 : for (MEntSelection::iterator mit = mentSelection.begin();
[ + + ]
78 : 100 : mit != mentSelection.end(); ++mit)
79 : : {
80 [ + - ]: 71 : ModelEnt *aSelEnt = (*mit).first;
81 [ + - ]: 71 : int dim = aSelEnt->dimension();
82 [ + - ][ + - ]: 71 : if (dim == 0 || aSelEnt->get_meshed_state() >= COMPLETE_MESH)
[ + + ][ + + ]
83 : : {
84 : 1 : continue;
85 : : }
86 : :
87 [ + - ]: 70 : MEntVector facets;
88 [ + - ]: 70 : aSelEnt->get_adjacencies(dim - 1, facets);
89 [ + - + - ]: 764 : for (MEntVector::iterator facetItr = facets.begin();
[ + + ]
90 : 382 : facetItr != facets.end(); ++facetItr)
91 : : {
92 [ + - ]: 312 : std::vector<MeshOp*> facetMOps;
93 [ + - ][ + - ]: 312 : (*facetItr)->get_meshops(facetMOps);
94 [ + - ]: 312 : allFacetMOps.insert(facetMOps.begin(), facetMOps.end());
95 : 312 : }
96 : 70 : }
97 : :
98 : :
99 : : // if recursing, keep track of mops found so we can recurse on them
100 [ + - ]: 58 : std::vector<MeshOp*> mopsFound;
101 : :
102 : : lemon::ReverseDigraph<lemon::ListDigraph>
103 [ + - ][ + - ]: 29 : revGraph(this->get_graph()->get_graph());
[ + - ]
104 [ + - ]: 58 : lemon::Bfs<lemon::ReverseDigraph<lemon::ListDigraph> > rbfs(revGraph);
105 [ + - ]: 29 : rbfs.init();
106 [ + - ][ + - ]: 29 : rbfs.addSource(this->get_node());
107 [ + - ][ + + ]: 122 : while (!rbfs.emptyQueue() && !allFacetMOps.empty())
[ + + ][ + + ]
108 : : {
109 [ + - ]: 93 : lemon::ListDigraph::Node lemNode = rbfs.processNextNode();
110 [ + - ][ + - ]: 93 : MeshOp* mkMOp = this->get_graph()->get_meshop(lemNode);
111 [ + - ]: 93 : std::set<MeshOp*>::iterator opFoundItr = allFacetMOps.find(mkMOp);
112 [ + - ][ + + ]: 93 : if (opFoundItr != allFacetMOps.end())
113 : : {
114 [ - + ]: 54 : if (recurse_to_facets)
115 : : {
116 [ # # ]: 0 : mopsFound.push_back(mkMOp);
117 : : }
118 [ + - ]: 93 : allFacetMOps.erase(opFoundItr);
119 : : }
120 : : }
121 : :
122 : : // insert direct dependencies on MeshOps not found in the graph
123 [ + - + - ]: 86 : for (std::set<MeshOp*>::iterator mOpItr = allFacetMOps.begin();
[ + + ]
124 : 43 : mOpItr != allFacetMOps.end(); ++mOpItr)
125 : : {
126 [ + - ][ + - ]: 14 : this->get_graph()->add_arc(*mOpItr, this);
[ + - ]
127 : : }
128 : :
129 [ - + ]: 29 : if (recurse_to_facets)
130 : : {
131 : : // recurse to facets that this did not previously depend on
132 [ # # # # ]: 0 : for (std::set<MeshOp*>::iterator mOpItr = allFacetMOps.begin();
[ # # ]
133 : 0 : mOpItr != allFacetMOps.end(); ++mOpItr)
134 : : {
135 [ # # ][ # # ]: 0 : (*mOpItr)->ensure_facet_dependencies(true);
136 : : }
137 : : // recurse to facets that this already depended on
138 [ # # # # ]: 0 : for (std::vector<MeshOp*>::iterator mOpItr = mopsFound.begin();
[ # # ]
139 : 0 : mOpItr != mopsFound.end(); ++mOpItr)
140 : : {
141 [ # # ][ # # ]: 0 : (*mOpItr)->ensure_facet_dependencies(true);
142 : : }
143 : : }
144 : :
145 : 58 : return;
146 : : }
147 : :
148 : 0 : bool MeshOp::canmesh_vertex(ModelEnt *model_ent)
149 : : {
150 : 0 : return (model_ent->dimension() == 0);
151 : : }
152 : :
153 : 0 : bool MeshOp::canmesh_edge(ModelEnt *model_ent)
154 : : {
155 : 0 : return (model_ent->dimension() == 1);
156 : : }
157 : :
158 : 0 : bool MeshOp::canmesh_face(ModelEnt *model_ent)
159 : : {
160 : 0 : return (model_ent->dimension() == 2);
161 : : }
162 : :
163 : 0 : bool MeshOp::canmesh_region(ModelEnt *model_ent)
164 : : {
165 : 0 : return (model_ent->dimension() == 3);
166 : : }
167 : :
168 : 544 : bool MeshOp::add_modelent(ModelEnt *model_ent)
169 : : {
170 [ + - ]: 544 : MEntSelection::iterator sit = mentSelection.find(model_ent);
171 [ + - ][ - + ]: 544 : if (sit != mentSelection.end()) return false;
172 : :
173 [ + - ]: 544 : mentSelection[model_ent];
174 : :
175 : : // add meshop back to model ent
176 [ + - ]: 544 : model_ent->add_meshop(this);
177 : :
178 : 544 : return true;
179 : : }
180 : :
181 : 0 : bool MeshOp::remove_modelent(ModelEnt *model_ent)
182 : : {
183 [ # # ]: 0 : MEntSelection::iterator sit = mentSelection.find(model_ent);
184 [ # # ][ # # ]: 0 : if (sit != mentSelection.end()) {
185 [ # # ]: 0 : mentSelection.erase(sit);
186 : 0 : return true;
187 : : }
188 : 0 : else return false;
189 : : }
190 : :
191 : 318 : MeshOp::~MeshOp()
192 : : {
193 [ - + ]: 159 : }
194 : :
195 : 0 : void MeshOp::mesh_types(std::vector<moab::EntityType> &mesh_types)
196 : : {
197 : 0 : const moab::EntityType* types = mesh_types_arr();
198 [ # # ]: 0 : for (int i = 0; types[i] != moab::MBMAXTYPE; ++i)
199 : 0 : mesh_types.push_back(types[i]);
200 : 0 : }
201 : :
202 : : #ifdef HAVE_FBIGEOM
203 : 0 : void MeshOp::create_model_ents_from_previous_ops()
204 : : {
205 : : // model ents are empty so far...
206 [ # # ][ # # ]: 0 : GraphNode * prevNode = other_node(in_arcs());// assumes one incoming edge!!
207 : :
208 : 0 : MeshOp * prevOp = reinterpret_cast<MeshOp*> (prevNode);
209 [ # # ]: 0 : std::string nameOp = prevNode->get_name();
210 : :
211 [ # # ]: 0 : if (NULL==prevOp)
212 : 0 : return;
213 : : // if the previous op is MBSplitOp or MBGeomOp, we know what to do
214 [ # # ][ # # ]: 0 : if ( !(nameOp == "MBGeomOp" || nameOp == "MBSplitOp"))
[ # # ][ # # ]
[ # # ]
215 : : {
216 : 0 : return; // do not process yet other OPs
217 : : }
218 : :
219 : :
220 [ # # ]: 0 : MEntSelection & mentsel = prevOp->me_selection();
221 [ # # ]: 0 : if (mentsel.empty())
222 : 0 : return;
223 [ # # ]: 0 : ModelEnt * firstMe = (*(mentsel.begin()) ).first;
224 [ # # ][ # # ]: 0 : moab::Range prevModelSet = mentsel[firstMe];
[ # # ]
225 : :
226 [ # # ][ # # ]: 0 : if (prevModelSet.size()!=1)
227 : 0 : return;
228 : :
229 : : // this range has one set that can serve as basis for
230 : : // mesh based geometry
231 : : // the model ents have no model tag on the sets!!
232 [ # # ]: 0 : iGeom::EntitySetHandle rootSet = (iGeom::EntitySetHandle) prevModelSet[0];
233 : :
234 [ # # ][ # # ]: 0 : int latestGeomIndex = mk_core()->initialize_mesh_based_geometry(rootSet);
235 : :
236 [ # # ][ # # ]: 0 : MEntVector model_ents;
237 : : // get the model entities of dimension 2, created with the latest FBiGeom!!!
238 [ # # ][ # # ]: 0 : mk_core()->get_entities_by_dimension(2, model_ents, latestGeomIndex);
239 : :
240 : : // add it to the mentSelection!!
241 [ # # ]: 0 : if (model_ents.size()==0)
242 : 0 : return; // nothing to mesh .... could be an infinite loop maybe we should abort
243 [ # # ][ # # ]: 0 : for (unsigned int i = 0; i<model_ents.size(); i++)
244 : : {
245 [ # # ][ # # ]: 0 : moab::Range rr = mentSelection[model_ents[i]];
[ # # ]
246 [ # # ]: 0 : rr.clear(); // just to use it , to avoid some warnings
247 : 0 : }
248 : :
249 : : /*// redo the setup for the op, as we added more entities
250 : : setup_this();
251 : : // we will have to also execute operations before this ...
252 : : mk_core()->setup_and_execute();// will relaunch the whole execute// some are marked as
253 : : // executed, so no worries*/
254 : :
255 : : }
256 : : #endif
257 : :
258 [ + - ][ + - ]: 156 : }
259 : :
260 : :
|