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