MeshKit
1.0
|
00001 #include <assert.h> 00002 00003 #include "meshkit/MeshOp.hpp" 00004 #include "meshkit/MKCore.hpp" 00005 #include "meshkit/ModelEnt.hpp" 00006 00007 #include "lemon/adaptors.h" 00008 00009 #include <set> 00010 00011 namespace MeshKit 00012 { 00013 00014 MeshOp::MeshOp(const MeshOp &mesh_op) 00015 : GraphNode(mesh_op) 00016 { 00017 debugLevel=0; 00018 } 00019 00020 MeshOp::MeshOp(MKCore *mkcore, const MEntVector &me_vec) 00021 : GraphNode(mkcore) 00022 { 00023 debugLevel=0; 00024 if (!me_vec.empty()) { 00025 for (MEntVector::const_iterator vit = me_vec.begin(); vit != me_vec.end(); vit++) 00026 mentSelection[*vit]; 00027 } 00028 } 00029 00030 void MeshOp::setup_boundary() 00031 { 00032 // generic setup code; make sure there are MeshOp's for each of my bounding entities, and create 00033 // ones where necessary (based on default MeshOp for that dimension registered with MOF) 00034 00035 // use separate MeshOps by dimension, since there may be multiple dimension entities in mentSelection 00036 MeshOp *this_op[] = {NULL, NULL, NULL, NULL}; 00037 00038 for (MEntSelection::iterator mit = mentSelection.begin(); mit != mentSelection.end(); mit++) { 00039 ModelEnt *this_ent = (*mit).first; 00040 int dim = this_ent->dimension(); 00041 if (0 == dim) continue; 00042 if (this_ent->get_meshed_state()>=COMPLETE_MESH) 00043 continue; 00044 00045 MEntVector children; 00046 this_ent->get_adjacencies(dim-1, children); 00047 for (MEntVector::iterator chit = children.begin(); chit != children.end(); chit++) { 00048 if ((*chit)->is_meshops_list_empty()) { 00049 // no meshop, need to get one associated with this 00050 if (!this_op[dim-1]) { 00051 this_op[dim-1] = mk_core()->construct_meshop(dim-1); 00052 if (!this_op[dim-1]) throw Error(MK_MESHOP_NOT_FOUND, "No default meshop for this dimension."); 00053 } 00054 this_op[dim-1]->add_modelent(*chit); 00055 } 00056 } 00057 } 00058 00059 // VertexMesher should be inserted after root node to be done before other meshops 00060 // It is because the VertexMesher instance is only one 00061 if (this_op[0]) { 00062 mk_core()->insert_node(this_op[0], this, mk_core()->root_node()); 00063 } 00064 00065 for (int dim = 1; dim <= 3; dim++) { 00066 if (this_op[dim]) 00067 mk_core()->insert_node(this_op[dim], this); 00068 } 00069 } 00070 00071 // TODO: Split this into separate functions, one for ensuring dependence 00072 // on a list of meshops, and the other for doing it with boundary 00073 void MeshOp::ensure_facet_dependencies(bool recurse_to_facets) 00074 { 00075 std::set<MeshOp*> allFacetMOps; 00076 00077 for (MEntSelection::iterator mit = mentSelection.begin(); 00078 mit != mentSelection.end(); ++mit) 00079 { 00080 ModelEnt *aSelEnt = (*mit).first; 00081 int dim = aSelEnt->dimension(); 00082 if (dim == 0 || aSelEnt->get_meshed_state() >= COMPLETE_MESH) 00083 { 00084 continue; 00085 } 00086 00087 MEntVector facets; 00088 aSelEnt->get_adjacencies(dim - 1, facets); 00089 for (MEntVector::iterator facetItr = facets.begin(); 00090 facetItr != facets.end(); ++facetItr) 00091 { 00092 std::vector<MeshOp*> facetMOps; 00093 (*facetItr)->get_meshops(facetMOps); 00094 allFacetMOps.insert(facetMOps.begin(), facetMOps.end()); 00095 } 00096 } 00097 00098 00099 // if recursing, keep track of mops found so we can recurse on them 00100 std::vector<MeshOp*> mopsFound; 00101 00102 lemon::ReverseDigraph<lemon::ListDigraph> 00103 revGraph(this->get_graph()->get_graph()); 00104 lemon::Bfs<lemon::ReverseDigraph<lemon::ListDigraph> > rbfs(revGraph); 00105 rbfs.init(); 00106 rbfs.addSource(this->get_node()); 00107 while (!rbfs.emptyQueue() && !allFacetMOps.empty()) 00108 { 00109 lemon::ListDigraph::Node lemNode = rbfs.processNextNode(); 00110 MeshOp* mkMOp = this->get_graph()->get_meshop(lemNode); 00111 std::set<MeshOp*>::iterator opFoundItr = allFacetMOps.find(mkMOp); 00112 if (opFoundItr != allFacetMOps.end()) 00113 { 00114 if (recurse_to_facets) 00115 { 00116 mopsFound.push_back(mkMOp); 00117 } 00118 allFacetMOps.erase(opFoundItr); 00119 } 00120 } 00121 00122 // insert direct dependencies on MeshOps not found in the graph 00123 for (std::set<MeshOp*>::iterator mOpItr = allFacetMOps.begin(); 00124 mOpItr != allFacetMOps.end(); ++mOpItr) 00125 { 00126 this->get_graph()->add_arc(*mOpItr, this); 00127 } 00128 00129 if (recurse_to_facets) 00130 { 00131 // recurse to facets that this did not previously depend on 00132 for (std::set<MeshOp*>::iterator mOpItr = allFacetMOps.begin(); 00133 mOpItr != allFacetMOps.end(); ++mOpItr) 00134 { 00135 (*mOpItr)->ensure_facet_dependencies(true); 00136 } 00137 // recurse to facets that this already depended on 00138 for (std::vector<MeshOp*>::iterator mOpItr = mopsFound.begin(); 00139 mOpItr != mopsFound.end(); ++mOpItr) 00140 { 00141 (*mOpItr)->ensure_facet_dependencies(true); 00142 } 00143 } 00144 00145 return; 00146 } 00147 00148 bool MeshOp::canmesh_vertex(ModelEnt *model_ent) 00149 { 00150 return (model_ent->dimension() == 0); 00151 } 00152 00153 bool MeshOp::canmesh_edge(ModelEnt *model_ent) 00154 { 00155 return (model_ent->dimension() == 1); 00156 } 00157 00158 bool MeshOp::canmesh_face(ModelEnt *model_ent) 00159 { 00160 return (model_ent->dimension() == 2); 00161 } 00162 00163 bool MeshOp::canmesh_region(ModelEnt *model_ent) 00164 { 00165 return (model_ent->dimension() == 3); 00166 } 00167 00168 bool MeshOp::add_modelent(ModelEnt *model_ent) 00169 { 00170 MEntSelection::iterator sit = mentSelection.find(model_ent); 00171 if (sit != mentSelection.end()) return false; 00172 00173 mentSelection[model_ent]; 00174 00175 // add meshop back to model ent 00176 model_ent->add_meshop(this); 00177 00178 return true; 00179 } 00180 00181 bool MeshOp::remove_modelent(ModelEnt *model_ent) 00182 { 00183 MEntSelection::iterator sit = mentSelection.find(model_ent); 00184 if (sit != mentSelection.end()) { 00185 mentSelection.erase(sit); 00186 return true; 00187 } 00188 else return false; 00189 } 00190 00191 MeshOp::~MeshOp() 00192 { 00193 } 00194 00195 void MeshOp::mesh_types(std::vector<moab::EntityType> &mesh_types) 00196 { 00197 const moab::EntityType* types = mesh_types_arr(); 00198 for (int i = 0; types[i] != moab::MBMAXTYPE; ++i) 00199 mesh_types.push_back(types[i]); 00200 } 00201 00202 #ifdef HAVE_FBIGEOM 00203 void MeshOp::create_model_ents_from_previous_ops() 00204 { 00205 // model ents are empty so far... 00206 GraphNode * prevNode = other_node(in_arcs());// assumes one incoming edge!! 00207 00208 MeshOp * prevOp = reinterpret_cast<MeshOp*> (prevNode); 00209 std::string nameOp = prevNode->get_name(); 00210 00211 if (NULL==prevOp) 00212 return; 00213 // if the previous op is MBSplitOp or MBGeomOp, we know what to do 00214 if ( !(nameOp == "MBGeomOp" || nameOp == "MBSplitOp")) 00215 { 00216 return; // do not process yet other OPs 00217 } 00218 00219 00220 MEntSelection & mentsel = prevOp->me_selection(); 00221 if (mentsel.empty()) 00222 return; 00223 ModelEnt * firstMe = (*(mentsel.begin()) ).first; 00224 moab::Range prevModelSet = mentsel[firstMe]; 00225 00226 if (prevModelSet.size()!=1) 00227 return; 00228 00229 // this range has one set that can serve as basis for 00230 // mesh based geometry 00231 // the model ents have no model tag on the sets!! 00232 iGeom::EntitySetHandle rootSet = (iGeom::EntitySetHandle) prevModelSet[0]; 00233 00234 int latestGeomIndex = mk_core()->initialize_mesh_based_geometry(rootSet); 00235 00236 MEntVector model_ents; 00237 // get the model entities of dimension 2, created with the latest FBiGeom!!! 00238 mk_core()->get_entities_by_dimension(2, model_ents, latestGeomIndex); 00239 00240 // add it to the mentSelection!! 00241 if (model_ents.size()==0) 00242 return; // nothing to mesh .... could be an infinite loop maybe we should abort 00243 for (unsigned int i = 0; i<model_ents.size(); i++) 00244 { 00245 moab::Range rr = mentSelection[model_ents[i]]; 00246 rr.clear(); // just to use it , to avoid some warnings 00247 } 00248 00249 /*// redo the setup for the op, as we added more entities 00250 setup_this(); 00251 // we will have to also execute operations before this ... 00252 mk_core()->setup_and_execute();// will relaunch the whole execute// some are marked as 00253 // executed, so no worries*/ 00254 00255 } 00256 #endif 00257 00258 } 00259 00260