MeshKit  1.0
SurfaceFacetMeshReader.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines