cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : LocalToleranceTool.cpp 00003 // 00004 // Purpose : The tool used to calculate local tolerance at RefEntities (Vert, Curve, Surface, Volume) 00005 // 00006 // Special Notes : 00007 // 00008 // Creator : William Roshan Quadros 00009 // 00010 // Creation Date : 11/16/2010 00011 // 00012 //------------------------------------------------------------------------- 00013 00014 #include <string.h> 00015 #include <assert.h> 00016 #include <stdlib.h> 00017 #include <math.h> 00018 #include <sstream> 00019 #include <iostream> 00020 00021 #include "LocalToleranceTool.hpp" 00022 00023 #include "CubitDefines.h" 00024 #include "GeometryDefines.h" 00025 #include "GeometryQueryTool.hpp" 00026 #include "MergeTool.hpp" 00027 00028 #include "RefEntityFactory.hpp" 00029 #include "BodySM.hpp" 00030 #include "BasicTopologyEntity.hpp" 00031 00032 #include "RefEntity.hpp" 00033 #include "RefVertex.hpp" 00034 #include "RefEdge.hpp" 00035 #include "RefFace.hpp" 00036 #include "RefVolume.hpp" 00037 00038 00039 // Instance of static members 00040 LocalToleranceTool* LocalToleranceTool::instance_ = 0; 00041 00042 //=================================================================================== 00043 // Description: constructor 00044 // Notes: 00045 // Author: roshan 00046 // Date: 11/16/2010 00047 //=================================================================================== 00048 LocalToleranceTool::LocalToleranceTool() 00049 { 00050 00051 } 00052 00053 //=================================================================================== 00054 // Description: destructor 00055 // Notes: 00056 // Author: roshan 00057 // Date: 11/16/2010 00058 //=================================================================================== 00059 LocalToleranceTool::~LocalToleranceTool() 00060 { 00061 00062 } 00063 00064 //------------------------------------------------------------------------- 00065 // Purpose : Controls access and creation of the sole instance of this 00066 // class. 00067 // 00068 // Special Notes : 00069 // 00070 // Creator : William Roshan Quadros 00071 // 00072 // Creation Date : 11/16/2010 00073 //------------------------------------------------------------------------- 00074 00075 LocalToleranceTool* LocalToleranceTool::instance(void) 00076 { 00077 // Check to see if we have created an instance of the class 00078 // If not, proceed to create one. 00079 00080 //if (LocalToleranceTool::instance_ == 0) 00081 // { 00082 // LocalToleranceTool::instance_ = new LocalToleranceTool() ; 00083 00084 // 00085 // } 00086 00087 // Return the a pointer to the instance of the class. 00088 return NULL; //LocalToleranceTool::instance_ ; 00089 } 00090 00091 //------------------------------------------------------------------------- 00092 // Purpose : Deletes instance variable 00093 // 00094 // Special Notes : 00095 // 00096 // Creator : William Roshan Quadros 00097 // 00098 // Creation Date : 11/16/2010 00099 //------------------------------------------------------------------------- 00100 void LocalToleranceTool::delete_instance() 00101 { 00102 if( NULL != instance_ ) 00103 { 00104 delete instance_; 00105 instance_ = NULL; 00106 } 00107 } 00108 00109 //------------------------------------------------------------------------- 00110 // Purpose : calculates the local tolerances at all ref_entities of input bodies 00111 // 00112 // Special Notes : 00113 // 00114 // Creator : William Roshan Quadros 00115 // 00116 // Creation Date : 11/16/2010 00117 //------------------------------------------------------------------------- 00118 bool LocalToleranceTool::calculate_local_tolerances( DLIList<BodySM*> body_sm_list ) 00119 { 00120 bool rv = true; 00121 const double default_vert_local_tol = 0.001; 00122 const double default_edge_local_tol = 0.01; 00123 const double default_face_local_tol = 0.02; 00124 const double default_vol_local_tol = 0.03; 00125 int i; 00126 00127 // get all bodies 00128 DLIList<Body *> bodies; 00129 RefEntityFactory::instance()->bodies( bodies ); 00130 00131 // find all ref_vert in the bodies 00132 DLIList<RefVertex *> ref_verts; 00133 GeometryQueryTool::instance()->ref_vertices( ref_verts ); 00134 00135 // for now set default value in all ref_vert 00136 RefVertex *ref_vert; 00137 for( i = 0; i < ref_verts.size(); i++ ) 00138 { 00139 ref_vert = ref_verts.get_and_step(); 00140 ref_vert->local_tolerance( default_vert_local_tol ); 00141 } 00142 00143 // find all ref_edge in the bodies 00144 DLIList<RefEdge *> ref_edges; 00145 GeometryQueryTool::instance()->ref_edges( ref_edges ); 00146 00147 // for now set default value in all ref_edges 00148 RefEdge *ref_edge; 00149 for( i = 0; i < ref_edges.size(); i++ ) 00150 { 00151 ref_edge = ref_edges.get_and_step(); 00152 ref_edge->local_tolerance( default_edge_local_tol ); 00153 } 00154 00155 // find all ref_face in the bodies 00156 DLIList<RefFace *> ref_faces; 00157 GeometryQueryTool::instance()->ref_faces( ref_faces ); 00158 00159 // for now set default value in all ref_faces 00160 RefFace *ref_face; 00161 for( i = 0; i < ref_faces.size(); i++ ) 00162 { 00163 ref_face = ref_faces.get_and_step(); 00164 ref_face->local_tolerance( default_face_local_tol ); 00165 } 00166 00167 // find all ref_vol in the bodies 00168 DLIList<RefVolume *> ref_vols; 00169 GeometryQueryTool::instance()->ref_volumes( ref_vols ); 00170 00171 // for now set default value in all ref_vols 00172 RefVolume *ref_vol; 00173 for( i = 0; i < ref_vols.size(); i++ ) 00174 { 00175 ref_vol = ref_vols.get_and_step(); 00176 ref_vol->local_tolerance( default_vol_local_tol ); 00177 } 00178 00179 return rv; 00180 } 00181 00182 //------------------------------------------------------------------------- 00183 // Purpose : calculates the local tolerances automatically at all the ref_entities of input bodies 00184 // 00185 // Special Notes : 00186 // 00187 // Creator : William Roshan Quadros 00188 // 00189 // Creation Date : 11/16/2010 00190 //------------------------------------------------------------------------- 00191 bool LocalToleranceTool::calculate_local_tolerances_automatically( DLIList<BodySM*> body_sm_list ) 00192 { 00193 bool rv = true; 00194 00195 // find mergable surfaces 00196 double geom_factor = GeometryQueryTool::get_geometry_factor(); 00197 double merge_tolerance = geom_factor*GEOMETRY_RESABS; 00198 DLIList< DLIList<Surface*>*> lists_of_mergeable_surfaces; 00199 MergeTool::instance()->find_only_mergeable_surfaces ( body_sm_list, lists_of_mergeable_surfaces, merge_tolerance ); 00200 00201 00202 /* Pseudocode for future use 00203 // Map holding overlapping surface pairs 00204 overlapping_surfs_map; 00205 // Add all surfs to spatial tree 00206 SpatialTree.add(all_surfs); 00207 // Create array of all surfs sorted by surface area (smallest to largest) 00208 all_surf_array.sort(); 00209 // Loop through progressively larger merge tolerances 00210 for(cur_tol=.00001; cur_tol < .1; cur_tol *= 10.0) 00211 { 00212 // Each time array size may change because surfs have been removed. 00213 int num_surfs = all_surf_array.size(), i; 00214 for(i=0; i<num_surfs; i++) 00215 { 00216 cur_surf = all_surf_array[i]; 00217 // Get surfs that are close to the current surf. 00218 close_surfs = SpatialTree.get_close_surfs(cur_surf); 00219 // Keep a running total of overlap area so we know when current surf 00220 // is overlapping completely with other surfs. 00221 double overlap_area = 0.0; 00222 int j; 00223 // Loop over all of the close surfs and look for overlaps. 00224 for(j=close_surfs.size(); j>0; j--) 00225 { 00226 cur_close_surf = close_surfs.get_and_step(); 00227 // If there is already a map entry between these two surfs don't check them again. 00228 if(!overlapping_surfs_map.entry_exists(cur_surf, cur_close_surf)) 00229 { 00230 // Measure overlap for these two surfs at current tolerance 00231 cur_overlap = measure_overlap(cur_surf, cur_close_surf, cur_tol); 00232 if(cur_overlap > 0.0) 00233 { 00234 // add entry for these two surfs (at the current tol) 00235 overlapping_surfs_map.add_entry(cur_surf, cur_close_surf, cur_tol); 00236 // Update the overlapping area for cur_surf 00237 overlap_area += cur_overlap; 00238 // If overlapping area for cur_surf is all of cur_surf then we are done processing it. 00239 if(overlap_area == cur_surf.surface_area()) 00240 { 00241 // Remove cur_surf from all_surf_array 00242 // Remove cur_surf from SpatialTree (if this helps with efficiency) 00243 // jump out of processing of cur_surf 00244 j=0; 00245 } 00246 } 00247 } 00248 } 00249 } 00250 } 00251 */ 00252 return rv; 00253 } 00254 00255 //------------------------------------------------------------------------- 00256 // Purpose : debugging function to print local tolerances at all ref_entities of the input bodies 00257 // 00258 // Special Notes : 00259 // 00260 // Creator : William Roshan Quadros 00261 // 00262 // Creation Date : 11/16/2010 00263 //------------------------------------------------------------------------- 00264 bool LocalToleranceTool::print_local_tolerances( DLIList<BodySM*> body_sm_list ) 00265 { 00266 bool rv = true; 00267 int i; 00268 00269 // get all bodies 00270 DLIList<Body *> bodies; 00271 RefEntityFactory::instance()->bodies( bodies ); 00272 00273 // find all ref_vert in the bodies 00274 DLIList<RefVertex *> ref_verts; 00275 GeometryQueryTool::instance()->ref_vertices( ref_verts ); 00276 00277 // for now set default value in all ref_vert 00278 RefVertex *ref_vert; 00279 for( i = 0; i < ref_verts.size(); i++ ) 00280 { 00281 ref_vert = ref_verts.get_and_step(); 00282 PRINT_INFO( " vert id %d, local_tol %f \n", ref_vert->id(), ref_vert->local_tolerance() ); 00283 } 00284 00285 // find all ref_edge in the bodies 00286 DLIList<RefEdge *> ref_edges; 00287 GeometryQueryTool::instance()->ref_edges( ref_edges ); 00288 00289 // for now set default value in all ref_edges 00290 RefEdge *ref_edge; 00291 for( i = 0; i < ref_edges.size(); i++ ) 00292 { 00293 ref_edge = ref_edges.get_and_step(); 00294 PRINT_INFO( " edge id %d, local_tol %f \n", ref_edge->id(), ref_edge->local_tolerance() ); 00295 } 00296 00297 // find all ref_face in the bodies 00298 DLIList<RefFace *> ref_faces; 00299 GeometryQueryTool::instance()->ref_faces( ref_faces ); 00300 00301 // for now set default value in all ref_faces 00302 RefFace *ref_face; 00303 for( i = 0; i < ref_faces.size(); i++ ) 00304 { 00305 ref_face = ref_faces.get_and_step(); 00306 PRINT_INFO( " face id %d, local_tol %f \n", ref_face->id(), ref_face->local_tolerance() ); 00307 } 00308 00309 // find all ref_vol in the bodies 00310 DLIList<RefVolume *> ref_vols; 00311 GeometryQueryTool::instance()->ref_volumes( ref_vols ); 00312 00313 // for now set default value in all ref_vols 00314 RefVolume *ref_vol; 00315 for( i = 0; i < ref_vols.size(); i++ ) 00316 { 00317 ref_vol = ref_vols.get_and_step(); 00318 PRINT_INFO( " vol id %d, local_tol %f \n", ref_vol->id(), ref_vol->local_tolerance() ); 00319 } 00320 00321 return rv; 00322 } 00323