MeshKit  1.0
MeshImprove.cpp
Go to the documentation of this file.
00001 #include "meshkit/MeshImprove.hpp"
00002 #include <iostream>
00003 #include <math.h>
00004 #include <map>
00005 
00006 //#include "SweepWrapper.hpp"
00007 #include "UntangleWrapper.hpp"
00008 #include "ShapeImprover.hpp"
00009 #include "SmartLaplacianSmoother.hpp"
00010 #include "SweepWrapper.hpp"
00011 #include "SmartLaplaceWrapper.hpp"
00012 #include "ShapeImprovementWrapper.hpp"
00013 
00014 #include "IdealWeightInverseMeanRatio.hpp"
00015 #include "QualityAssessor.hpp"
00016 #include "InstructionQueue.hpp"
00017 #include "TerminationCriterion.hpp"
00018 
00019 #include "LaplaceWrapper.hpp"
00020 #include "SizeAdaptShapeWrapper.hpp"
00021 #include "PaverMinEdgeLengthWrapper.hpp"
00022 #include "DeformingDomainWrapper.hpp"
00023 #include <MsqError.hpp>
00024 #include <ShapeImprovementWrapper.hpp>
00025 #include <MsqIMesh.hpp>
00026 #include <MsqIGeom.hpp>
00027 #ifdef HAVE_FBIGEOM
00028 #include "meshkit/MsqFBiGeom.hpp"
00029 #endif
00030 using namespace Mesquite;
00031 
00032 namespace MeshKit {
00033 
00034 MeshImprove::MeshImprove(MKCore* core, bool isLaplacian, bool isUntangle,
00035     bool isShapeImprove, bool isSizeAdapt, iGeom * ig_inst)
00036 {
00037   mk_core = core;
00038   IsLaplacian = isLaplacian;
00039   IsUntangle = isUntangle;
00040   IsShapeImprove = isShapeImprove;
00041   IsSizeAdapt = isSizeAdapt;
00042   if (ig_inst)
00043     igeom_inst = ig_inst;
00044   else
00045     igeom_inst = mk_core->igeom_instance();// it will pick the first one
00046 }
00047 
00048 void MeshImprove::SurfMeshImprove(iBase_EntityHandle surface,
00049     iBase_EntitySetHandle surfMesh, iBase_EntityType entity_type)
00050 {
00051 
00052   MsqError mError;
00053   const char* VERTEX_FIXED_TAG_NAME = "MesquiteVertexFixed";
00054 
00055   iBase_TagHandle fixed_tag = 0;
00056   iMesh::Error m_err = mk_core->imesh_instance()->getTagHandle(
00057       VERTEX_FIXED_TAG_NAME, fixed_tag);
00058   if (m_err) {
00059     m_err = mk_core->imesh_instance()->createTag(VERTEX_FIXED_TAG_NAME, 1,
00060         iBase_INTEGER, fixed_tag);
00061     IBERRCHK(m_err, "Trouble create the tag handle.");
00062   }
00063 
00064   MsqIMesh mesh_adapter(mk_core->imesh_instance()->instance(), surfMesh,
00065       entity_type, mError, &fixed_tag);
00066   cout << "error =" << mError << endl;
00067   if (mError)
00068     throw mError;
00069 
00070   //get all the vertices in surface mesh: entity_handles_out---quads     adj_entity_handles_out---vertices
00071   std::vector<iBase_EntityHandle> entity_handles_out, adj_entity_handles_out;
00072   std::vector<int> offsets_out, adj_entity_indices_out;
00073 
00074   m_err = mk_core->imesh_instance()->getAdjEntIndices(surfMesh, entity_type,
00075       iMesh_ALL_TOPOLOGIES, iBase_VERTEX, entity_handles_out,
00076       adj_entity_handles_out, adj_entity_indices_out, offsets_out);
00077   IBERRCHK(m_err, "Trouble get the adjacent entity indices.");
00078 
00079   cout << "number of faces is " << entity_handles_out.size() << endl;
00080   cout << "number of vertices is " << adj_entity_handles_out.size() << endl;
00081 
00082   //set fixed flag on all vertices
00083   std::vector<int> tag_data(adj_entity_handles_out.size(), 1);
00084   m_err = mk_core->imesh_instance()->setIntArrData(&adj_entity_handles_out[0],
00085       adj_entity_handles_out.size(), fixed_tag, &tag_data[0]);
00086   IBERRCHK(m_err, "Trouble set an array of int data for a list of vertices.");
00087 
00088   //clear fixed flag for vertices contained directly in set
00089   int count = -1;
00090   m_err
00091       = mk_core->imesh_instance()->getNumOfType(surfMesh, iBase_VERTEX, count);
00092   IBERRCHK(m_err, "Trouble get the number of vertices in the set.");
00093 
00094   adj_entity_handles_out.clear();
00095 
00096   cout << "Num of Vertices on the target surface is " << count << endl;
00097 
00098   m_err = mk_core->imesh_instance()->getEntities(surfMesh, iBase_VERTEX,
00099       iMesh_ALL_TOPOLOGIES, adj_entity_handles_out);
00100   IBERRCHK(m_err, "Trouble get the nodes from the mesh entity set.");
00101 
00102   tag_data.clear();
00103   tag_data.resize(adj_entity_handles_out.size(), 0);
00104 
00105   m_err = mk_core->imesh_instance()->setIntArrData(&adj_entity_handles_out[0],
00106       adj_entity_handles_out.size(), fixed_tag, &tag_data[0]);
00107   IBERRCHK(m_err, "Trouble set an array of int data for mesh nodes.");
00108 
00109   //Finally smooth the mesh
00110 
00111   //SweepWrapper smoother( 1e-6,  "COORDINATES_MAP");
00112   if (IsUntangle) {
00113     UntangleWrapper smoother;
00114     //smoother.set_cpu_time_limit(300);
00115     smoother.set_vertex_movement_limit_factor(0.001);
00116 
00117     if (surface) {
00118 #ifdef HAVE_FBIGEOM
00119       if (this->igeom_inst->isFBiGeom())
00120       {
00121         MsqFBiGeom fbgeom_adapter((FBiGeom *)igeom_inst, surface);
00122         smoother.run_instructions(&mesh_adapter, &fbgeom_adapter, mError);
00123         cout << "Mesquite error in fb surface mesh smoothing=" << mError << endl;
00124       }
00125       else
00126       {
00127 #endif
00128       MsqIGeom geom_adapter(mk_core->igeom_instance()->instance(), surface);
00129       smoother.run_instructions(&mesh_adapter, &geom_adapter, mError);
00130       cout << "Mesquite error in surface mesh smoothing=" << mError << endl;
00131 #ifdef HAVE_FBIGEOM
00132     }
00133 #endif
00134     } else {
00135       smoother.run_instructions(&mesh_adapter, mError);
00136       cout << "Mesquite error in surface mesh smoothing=" << mError << endl;
00137     }
00138   }
00139 
00140   //use the SmartLaplaceWrapper class the smooth the target surface mesh
00141   if (IsLaplacian) {
00142     LaplaceWrapper sl_smooth;
00143     TerminationCriterion terminate;
00144     terminate.write_iterations("mesquite.gpt", mError);
00145     if (surface) {
00146 #ifdef HAVE_FBIGEOM
00147       if (this->igeom_inst->isFBiGeom())
00148       {
00149         MsqFBiGeom fbgeom_adapter((FBiGeom *)igeom_inst, surface);
00150         sl_smooth.run_instructions(&mesh_adapter, &fbgeom_adapter, mError);
00151         cout << "Mesquite error in fb smart Laplacian surface mesh smoothing with the geometry domain=" << mError << endl;
00152       }
00153       else
00154       {
00155 #endif
00156       MsqIGeom geom_adapter(mk_core->igeom_instance()->instance(), surface);
00157       sl_smooth.run_instructions(&mesh_adapter, &geom_adapter, mError);
00158       cout
00159           << "Mesquite error in the smart Laplacian surface mesh smoothing with the geometry domain="
00160           << mError << endl;
00161 #ifdef HAVE_FBIGEOM
00162     }
00163 #endif
00164     } else {
00165       sl_smooth.run_instructions(&mesh_adapter, mError);
00166       cout
00167           << "Mesquite error in the smart Laplacian surface mesh smoothing without the geometry domain="
00168           << mError << endl;
00169     }
00170   }
00171 
00172   //use the ShapeImprover class to smooth the target surface mesh
00173   if (IsShapeImprove) {
00174     IdealWeightInverseMeanRatio extra_metric;
00175     ShapeImprovementWrapper smoother1;
00176     smoother1.quality_assessor().add_quality_assessment(&extra_metric);
00177     //smoother1.set_vertex_movement_limit_factor(0.01);
00178     //smoother1.set_cpu_time_limit(300);
00179     if (surface) {
00180 #ifdef HAVE_FBIGEOM
00181       if (this->igeom_inst->isFBiGeom())
00182       {
00183         MsqFBiGeom fbgeom_adapter((FBiGeom *)igeom_inst, surface);
00184         smoother1.run_instructions(&mesh_adapter, &fbgeom_adapter, mError);
00185         cout << "Mesquite error in ShapeImprover fb surface mesh smoothing=" << mError << endl;
00186       }
00187       else
00188       {
00189 #endif
00190       MsqIGeom geom_adapter(mk_core->igeom_instance()->instance(), surface);
00191       smoother1.run_instructions(&mesh_adapter, &geom_adapter, mError);
00192       cout << "Mesquite error in the ShapeImprover surface mesh smoothing="
00193           << mError << endl;
00194 #ifdef HAVE_FBIGEOM
00195     }
00196 #endif
00197     } else {
00198       smoother1.run_instructions(&mesh_adapter, mError);
00199       cout << "Mesquite error in the ShapeImprover surface mesh smoothing="
00200           << mError << endl;
00201     }
00202   }
00203 
00204   //Use the Minimum Edge-Length Improvement
00205 
00206   if (IsSizeAdapt) {
00207     SizeAdaptShapeWrapper Smooth_SizeAdapt(1.0e-2);
00208     if (surface) {
00209 #ifdef HAVE_FBIGEOM
00210       if (this->igeom_inst->isFBiGeom())
00211       {
00212         MsqFBiGeom fbgeom_adapter((FBiGeom *)igeom_inst, surface);
00213         Smooth_SizeAdapt.run_instructions(&mesh_adapter, &fbgeom_adapter, mError);
00214         cout << "Mesquite error in SizeAdaptShape fb surface mesh smoothing=" << mError << endl;
00215       }
00216       else
00217       {
00218 #endif
00219       MsqIGeom geom_adapter(mk_core->igeom_instance()->instance(), surface);
00220       Smooth_SizeAdapt.run_instructions(&mesh_adapter, &geom_adapter, mError);
00221       cout << "Mesquite error in the SizeAdaptShape surface mesh smoothing="
00222           << mError << endl;
00223 #ifdef HAVE_FBIGEOM
00224     }
00225 #endif
00226 
00227     } else {
00228       Smooth_SizeAdapt.run_instructions(&mesh_adapter, mError);
00229       cout << "Mesquite error in the SizeAdaptShape surface mesh smoothing="
00230           << mError << endl;
00231     }
00232   }
00233 
00234 }
00235 
00236 void MeshImprove::VolumeMeshImprove(iBase_EntitySetHandle volMesh,
00237     iBase_EntityType entity_type)
00238 {
00239 
00240   cout << "Volume smoothing is starting..." << endl;
00241 
00242   MsqError mError;
00243   const char* VERTEX_FIXED_TAG_NAME = "MesquiteVertexFixed";
00244 
00245   iBase_TagHandle fixed_tag = 0;
00246 
00247   iMesh::Error m_err = mk_core->imesh_instance()->getTagHandle(
00248       VERTEX_FIXED_TAG_NAME, fixed_tag);
00249   if (m_err) {
00250     m_err = mk_core->imesh_instance()->createTag(VERTEX_FIXED_TAG_NAME, 1,
00251         iBase_INTEGER, fixed_tag);
00252     IBERRCHK(m_err, "Trouble create a taghandle.");
00253   }
00254 
00255   MsqIMesh mesh_adapter(mk_core->imesh_instance()->instance(), volMesh,
00256       entity_type, mError, &fixed_tag);
00257   cout << "error =" << mError << endl;
00258   if (mError)
00259     throw mError;
00260 
00261   //get all the vertices in volume mesh
00262   int num_vtx, count;
00263   std::vector<iBase_EntityHandle> faces, verts;
00264   std::vector<int> indices, offsets;
00265 
00266   m_err = mk_core->imesh_instance()->getAdjEntIndices(volMesh, entity_type,
00267       iMesh_ALL_TOPOLOGIES, iBase_VERTEX, faces, verts, indices, offsets);
00268   IBERRCHK(m_err, "Trouble get the quads and nodes on the target surface.");
00269   num_vtx = verts.size();
00270 
00271   cout << "number of faces is " << faces.size() << endl;
00272   cout << "number of vertices is " << verts.size() << endl;
00273 
00274   //set fixed flag on all vertices
00275   vector<int> tag_data(num_vtx, 1);
00276   m_err = mk_core->imesh_instance()->setIntArrData(&verts[0], verts.size(),
00277       fixed_tag, &tag_data[0]);
00278   IBERRCHK(m_err, "Trouble set an array of int data for nodes on the target surface.");
00279 
00280   //clear fixed flag for vertices contained directly in set
00281   m_err = mk_core->imesh_instance()->getNumOfType(volMesh, iBase_VERTEX, count);
00282   IBERRCHK(m_err, "Trouble get the number of interior nodes on the target surface.");
00283 
00284   //get the interior mesh nodes on the target surface
00285   verts.clear();
00286   cout << "Num of Vertices on the target surface is " << count << endl;
00287 
00288   m_err = mk_core->imesh_instance()->getEntities(volMesh, iBase_VERTEX,
00289       iMesh_ALL_TOPOLOGIES, verts);
00290   IBERRCHK(m_err, "Trouble get the number of interior nodes on the target surface.");
00291 
00292   tag_data.clear();
00293   tag_data.resize(verts.size(), 0);
00294   m_err = mk_core->imesh_instance()->setIntArrData(&verts[0], verts.size(),
00295       fixed_tag, &tag_data[0]);
00296   IBERRCHK(m_err, "Trouble set the int data for interior nodes on the target surface.");
00297 
00298   //using the UntangleWrapper class to smooth the mesh with the inverted elements.
00299   UntangleWrapper smoother1;
00300 
00301   smoother1.set_cpu_time_limit(1000);
00302   smoother1.set_vertex_movement_limit_factor(0.001);
00303 
00304   smoother1.run_instructions(&mesh_adapter, mError);
00305 
00306   //Finally smooth the mesh
00307   //Use the ShapeImprover class to smooth the target surface mesh
00308   ShapeImprover smoother2;
00309   smoother2.set_cpu_time_limit(1000);
00310   smoother2.set_vertex_movement_limit_factor(0.001);
00311   smoother2.run_instructions(&mesh_adapter, mError);
00312   if (mError)
00313     cout << "Mesquite error in volume mesh smoothing is as follows\n" << mError
00314         << std::endl;
00315   /*
00316 
00317    SweepWrapper smoother3( 1e-6,  "COORDINATES_MAP");
00318    ShapeImprovementWrapper smoother2(mError);
00319 
00320 
00321    smoother2.run_instructions(&mesh_adapter, mError);
00322 
00323    if (mError)
00324    cout << "Mesquite error in volume mesh smoothing=" << mError << endl;
00325    */
00326 
00327 }
00328 
00329 MeshImprove::~MeshImprove()
00330 {
00331   cout << "It is over now in smoothing" << endl;
00332 }
00333 
00334 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines