MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "SmartLaplacianSmoother.hpp" 00002 #include "PatchData.hpp" 00003 #include "MsqVertex.hpp" 00004 #include "MsqMeshEntity.hpp" 00005 00006 namespace MBMesquite 00007 { 00008 00009 size_t SmartLaplacianSmoother::num_inverted( PatchData& pd, MsqError& err ) 00010 { 00011 size_t result = 0; 00012 int inverted, junk; 00013 for( size_t i = 0; i < pd.num_elements(); ++i ) 00014 { 00015 pd.element_by_index( i ).check_element_orientation( pd, inverted, junk, err ); 00016 MSQ_ERRZERO( err ); 00017 if( inverted ) ++result; 00018 } 00019 return result; 00020 } 00021 00022 std::string SmartLaplacianSmoother::get_name() const 00023 { 00024 return "SmartLaplacianSmoother"; 00025 } 00026 00027 SmartLaplacianSmoother::~SmartLaplacianSmoother() {} 00028 00029 void SmartLaplacianSmoother::optimize_vertex_positions( PatchData& pd, MsqError& err ) 00030 { 00031 assert( pd.num_free_vertices() == 1 ); 00032 const size_t center_vtx_index = 0; 00033 const size_t init_inverted = num_inverted( pd, err );MSQ_ERRRTN( err ); 00034 00035 adjVtxList.clear(); 00036 pd.get_adjacent_vertex_indices( center_vtx_index, adjVtxList, err );MSQ_ERRRTN( err ); 00037 00038 if( adjVtxList.empty() ) return; 00039 00040 const MsqVertex* verts = pd.get_vertex_array( err ); 00041 const size_t n = adjVtxList.size(); 00042 00043 const Vector3D orig_pos = verts[center_vtx_index]; 00044 Vector3D new_pos = verts[adjVtxList[0]]; 00045 for( size_t i = 1; i < n; ++i ) 00046 new_pos += verts[adjVtxList[i]]; 00047 new_pos *= 1.0 / n; 00048 pd.set_vertex_coordinates( new_pos, center_vtx_index, err ); 00049 pd.snap_vertex_to_domain( center_vtx_index, err );MSQ_ERRRTN( err ); 00050 const size_t new_inverted = num_inverted( pd, err );MSQ_ERRRTN( err ); 00051 if( new_inverted > init_inverted ) pd.set_vertex_coordinates( orig_pos, center_vtx_index, err ); 00052 } 00053 00054 } // namespace MBMesquite