MeshKit
1.0
|
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 }