MeshKit
1.0
|
00001 00002 00003 #include "meshkit/MKCore.hpp" 00004 #include "meshkit/SurfaceFacetMeshReader.hpp" 00005 #include "meshkit/CurveFacetMeshReader.hpp" 00006 #include "meshkit/ModelEnt.hpp" 00007 #include <iostream> 00008 #include <iGeom.h> 00009 #include <cmath> 00010 00011 #include "moab/Core.hpp" 00012 00013 00014 namespace MeshKit 00015 { 00016 00017 // Output mesh types for this class 00018 moab::EntityType SurfaceFacetMeshReader_types[] = {moab::MBVERTEX, moab::MBEDGE, moab::MBTRI, moab::MBMAXTYPE}; 00019 const moab::EntityType* SurfaceFacetMeshReader::output_types() 00020 { return SurfaceFacetMeshReader_types; } 00021 00022 SurfaceFacetMeshReader::SurfaceFacetMeshReader(MKCore *mk_core, const MEntVector &ments) 00023 : MeshScheme(mk_core, ments) 00024 { 00025 mk = mk_core; 00026 } 00027 00028 SurfaceFacetMeshReader::~SurfaceFacetMeshReader() 00029 { 00030 } 00031 00032 void SurfaceFacetMeshReader::setup_this() 00033 { 00034 //set the faceting parameters to default values if they are not already set 00035 00036 //set the faceting tolerance 00037 if(!facet_tol) facet_tol = 1e-4; 00038 00039 //set the geom_resabs value 00040 if(!geom_res) geom_res = 1e-6; 00041 00042 //create a solid curve mesher 00043 CurveFacetMeshReader *cfmr = (CurveFacetMeshReader*) mk_core()->construct_meshop("CurveFacetMeshReader"); 00044 00045 //set the parameters of the curvemesher to match those of the surface mesher 00046 cfmr->set_mesh_params(facet_tol,geom_res); 00047 00048 for(MEntSelection::iterator mit = mentSelection.begin(); mit != mentSelection.end(); mit++) 00049 { 00050 ModelEnt *me = mit->first; 00051 //do an initial check that the model entity is of the correct dimension 00052 if(me->dimension() != 2) 00053 { 00054 std::cout << "Found a model entity with an incorrect dimension for this mesher" << std::endl; 00055 mentSelection.erase(mit); 00056 continue; 00057 } 00058 00059 //make sure that the model entity's children have been meshed 00060 MEntVector children; 00061 me->get_adjacencies(1, children); 00062 //std::cout << "Number of children found: " << children.size() << std::endl; 00063 00064 for(MEntVector::iterator j = children.begin(); j != children.end(); j++) 00065 { 00066 ModelEnt *child = *j; 00067 if(child->is_meshops_list_empty()) cfmr-> add_modelent(child); 00068 } 00069 00070 } 00071 00072 //have the children be meshed first 00073 mk_core()->insert_node(cfmr, this, mk_core()->root_node()); 00074 00075 } 00076 00077 void SurfaceFacetMeshReader::execute_this() 00078 { 00079 00080 for(MEntSelection::iterator mit = mentSelection.begin(); mit !=mentSelection.end(); mit++) 00081 { 00082 ModelEnt *me = mit->first; 00083 00084 //---------------------------------// 00085 // FACET // 00086 //---------------------------------// 00087 facet(me); 00088 00089 me->set_meshed_state(COMPLETE_MESH); 00090 } 00091 } 00092 00093 void SurfaceFacetMeshReader::facet(ModelEnt *surf) 00094 { 00095 00096 iGeom::EntityHandle h = surf->geom_handle(); 00097 iMesh::EntitySetHandle sh = IBSH(surf->mesh_handle()); 00098 00099 //get the facets for this surface/ ref_face 00100 std::vector<double> pnts; 00101 std::vector<int> conn; 00102 iGeom::Error errval = mk->igeom_instance()->getFacets(h,facet_tol,pnts,conn); 00103 if (errval != iBase_SUCCESS) throw Error(MK_FAILURE, "Unable get the facets of the surface."); 00104 00105 //create vector for keeping track of the vertices 00106 std::vector<iBase_EntityHandle> verts; 00107 00108 // loop over the facet points 00109 for(unsigned int j=0; j<pnts.size(); j+=3) 00110 { 00111 //create a new vertex handle 00112 iBase_EntityHandle v; 00113 mk->imesh_instance()->createVtx(pnts[j],pnts[j+1],pnts[j+2],v); 00114 verts.push_back(v); 00115 } 00116 00117 00118 // get the geometric vertices of the surface and merge them into the mesh by 00119 // a proximity check 00120 00121 //get the geometric vertices 00122 MEntVector geom_verts; 00123 surf->get_adjacencies(0,geom_verts); 00124 unsigned int matches = 0; 00125 00126 //loop over all the vertices we've created 00127 for(unsigned int j=0; j<verts.size() ; j++) 00128 { 00129 //loop over all geometric vertices adjacent to this surface 00130 for(unsigned int k=0; k<geom_verts.size(); k++) 00131 { 00132 // if thhe current vert is within the geom_res proximity of a geometric vert 00133 if(vtx2vtx_dist(geom_verts[k]->geom_handle(),verts[j]) < geom_res) 00134 { 00135 //replace the vertex with the geometric vertex 00136 00137 //capture vert to remove from the list 00138 iMesh::EntityHandle vert_to_del = verts[j]; 00139 00140 //replace the vertex with the geom vertex in the vector 00141 std::vector<moab::EntityHandle> dum_handle; 00142 geom_verts[k]->get_mesh(0, dum_handle); 00143 verts[j] = IBEH(dum_handle[0]); 00144 00145 //delete the former vertex 00146 mk_core()->imesh_instance()->deleteEnt(vert_to_del); 00147 00148 matches++; 00149 } 00150 } 00151 } 00152 00153 //now check that we have matched the correct number of vertices 00154 if (matches != geom_verts.size()) 00155 { 00156 if(matches > geom_verts.size()) std::cout << "Warning: coincident vertices in surface " << surf->id() << std::endl; 00157 if(matches < geom_verts.size()) std::cout << "Warning: one or more geom vertices could not be matched in surface " << surf->id() << std::endl; 00158 } 00159 00160 //vector for keeping track of the triangles 00161 std::vector<iBase_EntityHandle> tris; 00162 00163 //loop over the connectivity 00164 for(int j = 0; j < (int)conn.size()-2; j+=3) 00165 { 00166 //get the appropriate points for a triangle and add them to a vector 00167 std::vector<iBase_EntityHandle> tri_verts; 00168 tri_verts.push_back(verts[conn[j]]); 00169 tri_verts.push_back(verts[conn[j+1]]); 00170 tri_verts.push_back(verts[conn[j+2]]); 00171 00172 //create a new triangle handle 00173 iBase_EntityHandle t; 00174 mk->imesh_instance()->createEnt(iMesh_TRIANGLE, &tri_verts[0], 3, t); 00175 tri_verts.clear(); 00176 tris.push_back(t); 00177 } 00178 //std::cout << "Created " << tris.size() << " triangles" << std::endl; 00179 00180 //add verticess and edges to the entity set 00181 mk->imesh_instance()->addEntArrToSet(&verts[0], verts.size(), sh); 00182 mk->imesh_instance()->addEntArrToSet(&tris[0], tris.size(), sh); 00183 00184 } 00185 00186 void SurfaceFacetMeshReader::set_mesh_params(double faceting_tolerance, double geom_resabs) 00187 { 00188 //Assign the faceting values if they are passed into the function 00189 if(faceting_tolerance) facet_tol = faceting_tolerance; 00190 if(geom_resabs) geom_res = geom_resabs; 00191 } 00192 00193 double SurfaceFacetMeshReader::vtx2vtx_dist(iGeom::EntityHandle vtx1, iMesh::EntityHandle vtx2) 00194 { 00195 00196 double x1,y1,z1; 00197 double x2,y2,z2; 00198 00199 mk_core()->igeom_instance()->getVtxCoord(vtx1, x1, y1, z1); 00200 mk_core()->imesh_instance()->getVtxCoord(vtx2, x2, y2, z2); 00201 00202 double dist = pow((x1-x2),2) + pow((y1-y2),2) + pow((z1-z2),2); 00203 00204 return sqrt(dist); 00205 } 00206 00207 }