cgma
|
00001 //- Class: BoundingBoxTool 00002 //- Description: Class for bounding boxes (primarily for "tight" bounding boxes) 00003 //- Owner: Steve Storm 00004 //- Created: 06-October-2000 00005 00006 #include "CubitBox.hpp" 00007 #include "Body.hpp" 00008 #include "RefVolume.hpp" 00009 #include "RefFace.hpp" 00010 #include "RefEdge.hpp" 00011 #include "RefVertex.hpp" 00012 #include "RefGroup.hpp" 00013 00014 #include "BoundingBoxTool.hpp" 00015 #include "AnalyticGeometryTool.hpp" 00016 #include "GMem.hpp" 00017 00018 #include "GeometryQueryEngine.hpp" 00019 00020 #include "DLIList.hpp" 00021 00022 #include "SettingHandler.hpp" 00023 00024 CubitBoolean BoundingBoxTool::useTriangles = CUBIT_TRUE; 00025 CubitBoolean BoundingBoxTool::useCurves = CUBIT_FALSE; 00026 CubitBoolean BoundingBoxTool::useVertices = CUBIT_FALSE; 00027 00028 BoundingBoxTool::BoundingBoxTool() 00029 {} 00030 00031 // Destructor 00032 BoundingBoxTool::~BoundingBoxTool() 00033 {} 00034 00035 CubitStatus 00036 BoundingBoxTool::get_tight_bounding_box( DLIList<RefEntity*> &ref_entity_list, 00037 CubitVector ¢er, 00038 CubitVector axes[3], 00039 CubitVector &extension, 00040 double ang_facet_tol, 00041 double abs_facet_tol ) 00042 { 00043 DLIList<CubitVector*> vec_list; 00044 00045 // Expand out groups in the list 00046 DLIList<RefEntity*> ref_entity_list_expanded = ref_entity_list; 00047 expand_groups_in_list( ref_entity_list_expanded ); 00048 00049 // Get the facet points from all the objects in the list 00050 append_ref_entity_points( ref_entity_list_expanded, vec_list, ang_facet_tol, abs_facet_tol ); 00051 00052 // Get the smallest box that fits around the points making up the facetted geometry 00053 AnalyticGeometryTool::instance()->get_tight_bounding_box( vec_list, center, 00054 axes, extension ); 00055 00056 // Free memory 00057 for( int i=0; i<vec_list.size(); i++ ) 00058 { 00059 CubitVector* cubit_vector_ptr = 00060 vec_list.get_and_step(); 00061 delete cubit_vector_ptr; 00062 } 00063 00064 return CUBIT_SUCCESS; 00065 } 00066 00067 CubitStatus 00068 BoundingBoxTool::get_axis_bounding_box( DLIList<RefEntity*> &ref_entity_list, 00069 CubitVector ¢er, 00070 CubitVector axes[3], 00071 CubitVector &extension ) 00072 { 00073 CubitBoolean bounding_box_found = CUBIT_FALSE; 00074 CubitBox bounding_box; 00075 00076 // Expand out groups in the list 00077 DLIList<RefEntity*> ref_entity_list_expanded = ref_entity_list; 00078 expand_groups_in_list( ref_entity_list_expanded ); 00079 00080 ref_entity_list_expanded.reset(); 00081 for( int i = ref_entity_list_expanded.size(); i>0; i-- ) 00082 { 00083 RefEntity* ref_entity_ptr = ref_entity_list_expanded.get_and_step(); 00084 if( bounding_box_found == CUBIT_FALSE ) 00085 { 00086 bounding_box = ref_entity_ptr->bounding_box(); 00087 bounding_box_found = CUBIT_TRUE; 00088 } 00089 else { 00090 bounding_box |= ref_entity_ptr->bounding_box(); 00091 } 00092 } 00093 00094 axes[0].set( 1.0, 0.0, 0.0 ); 00095 axes[1].set( 0.0, 1.0, 0.0 ); 00096 axes[2].set( 0.0, 0.0, 1.0 ); 00097 00098 if( bounding_box_found ) 00099 { 00100 extension.set( bounding_box.x_range()/2.0, bounding_box.y_range()/2.0, 00101 bounding_box.z_range()/2.0 ); 00102 center = bounding_box.center(); 00103 } 00104 else 00105 { 00106 extension.set( 0.0, 0.0, 0.0 ); 00107 center.set( 0.0, 0.0, 0.0 ); 00108 } 00109 00110 return CUBIT_SUCCESS; 00111 } 00112 00113 CubitStatus 00114 BoundingBoxTool::append_ref_entity_points( DLIList<RefEntity*> &ref_entity_list, 00115 DLIList<CubitVector*> &vec_list, 00116 double ang_facet_tol, double abs_facet_tol ) 00117 { 00118 DLIList<Body*> body_list; 00119 CAST_LIST( ref_entity_list, body_list, Body ); 00120 if( body_list.size() ) 00121 append_body_points( body_list, vec_list, ang_facet_tol, abs_facet_tol ); 00122 00123 DLIList<RefVolume*> vol_list; 00124 CAST_LIST( ref_entity_list, vol_list, RefVolume ); 00125 if( vol_list.size() ) 00126 append_volume_points( vol_list, vec_list, ang_facet_tol, abs_facet_tol ); 00127 00128 DLIList<RefFace*> surface_list; 00129 CAST_LIST( ref_entity_list, surface_list, RefFace ); 00130 if( surface_list.size() ) 00131 append_surface_points( surface_list, vec_list, ang_facet_tol, abs_facet_tol ); 00132 00133 DLIList<RefEdge*> curve_list; 00134 CAST_LIST( ref_entity_list, curve_list, RefEdge ); 00135 if( curve_list.size() ) 00136 append_curve_points( curve_list, vec_list ); 00137 00138 DLIList<RefVertex*> vertex_list; 00139 CAST_LIST( ref_entity_list, vertex_list, RefVertex ); 00140 if( vertex_list.size() ) 00141 append_vertex_points( vertex_list, vec_list ); 00142 00143 return CUBIT_SUCCESS; 00144 } 00145 00146 CubitStatus 00147 BoundingBoxTool::append_body_points( DLIList<Body*> &body_list, 00148 DLIList<CubitVector*> &vec_list, 00149 double ang_tol, double abs_tol ) 00150 { 00151 int i; 00152 Body *body_ptr; 00153 DLIList<RefFace*> ref_face_list; 00154 00155 body_list.reset(); 00156 for( i=0; i<body_list.size(); i++ ) 00157 { 00158 body_ptr = body_list.get_and_step(); 00159 00160 DLIList<RefFace*> ref_face_list_tmp; 00161 body_ptr->ref_faces( ref_face_list_tmp ); 00162 00163 ref_face_list.merge_unique( ref_face_list_tmp ); 00164 } 00165 00166 append_surface_points( ref_face_list, vec_list, ang_tol, abs_tol); 00167 00168 return CUBIT_SUCCESS; 00169 } 00170 00171 CubitStatus 00172 BoundingBoxTool::append_volume_points( DLIList<RefVolume*> &vol_list, 00173 DLIList<CubitVector*> &vec_list, 00174 double ang_tol, double abs_tol ) 00175 { 00176 int i; 00177 RefVolume *vol_ptr; 00178 DLIList<RefFace*> ref_face_list; 00179 00180 vol_list.reset(); 00181 for( i=0; i<vol_list.size(); i++ ) 00182 { 00183 vol_ptr = vol_list.get_and_step(); 00184 00185 DLIList<RefFace*> ref_face_list_tmp; 00186 vol_ptr->ref_faces( ref_face_list_tmp ); 00187 00188 ref_face_list.merge_unique( ref_face_list_tmp ); 00189 } 00190 00191 append_surface_points( ref_face_list, vec_list, ang_tol, abs_tol); 00192 00193 return CUBIT_SUCCESS; 00194 } 00195 00196 CubitStatus 00197 BoundingBoxTool::append_surface_points( DLIList<RefFace*> &ref_face_list, 00198 DLIList<CubitVector*> &vec_list, 00199 double ang_tol, double abs_tol) 00200 { 00201 int i; 00202 RefFace *ref_face_ptr; 00203 DLIList<RefEdge*> ref_edge_list; 00204 DLIList<RefVertex*> ref_vertex_list; 00205 00206 ref_face_list.reset(); 00207 for( i=0; i<ref_face_list.size(); i++ ) 00208 { 00209 ref_face_ptr = ref_face_list.get_and_step(); 00210 00211 if( useTriangles == CUBIT_TRUE ) 00212 { 00213 int num_pnt; 00214 GMem *g_mem = new GMem; 00215 00216 ref_face_ptr->get_graphics( *g_mem, (int)ang_tol, abs_tol ); 00217 num_pnt = g_mem->pointListCount; 00218 00219 GPoint* point_list = g_mem->point_list(); 00220 //int num_pnts = g_mem->point_list_size(); 00221 int y; 00222 for( y=0; y<num_pnt; y++ ) 00223 { 00224 CubitVector* cubit_vector_ptr = new CubitVector( 00225 point_list[y].x, point_list[y].y, point_list[y].z ); 00226 vec_list.append( cubit_vector_ptr ); 00227 } 00228 delete g_mem; 00229 } 00230 00231 if( useCurves == CUBIT_TRUE ) 00232 { 00233 // Grab the curves from the surface 00234 DLIList<RefEdge*> ref_edge_list_tmp; 00235 ref_face_ptr->ref_edges( ref_edge_list_tmp ); 00236 ref_edge_list.merge_unique( ref_edge_list_tmp ); 00237 } 00238 00239 // Only need vertices if both surfaces and curves are false 00240 if( useTriangles == CUBIT_FALSE && useCurves == CUBIT_FALSE && 00241 useVertices == CUBIT_TRUE ) 00242 { 00243 // Grab the vertices from the surface 00244 DLIList<RefVertex*> ref_vertex_list_tmp; 00245 ref_face_ptr->ref_vertices( ref_vertex_list_tmp ); 00246 ref_vertex_list.merge_unique( ref_vertex_list_tmp ); 00247 } 00248 } 00249 00250 if( useCurves == CUBIT_TRUE ) 00251 append_curve_points( ref_edge_list, vec_list ); 00252 00253 if( useTriangles == CUBIT_FALSE && useCurves == CUBIT_FALSE && 00254 useVertices == CUBIT_TRUE ) 00255 append_vertex_points( ref_vertex_list, vec_list ); 00256 00257 return CUBIT_SUCCESS; 00258 } 00259 00260 CubitStatus 00261 BoundingBoxTool::append_curve_points( DLIList<RefEdge*> &ref_edge_list, 00262 DLIList<CubitVector*> &vec_list ) 00263 { 00264 // First grab all the vertices and append their coordinates to vec_list. 00265 // Then do the curves, but just put inside points in. This avoids duplicate 00266 // points at the vertices. 00267 00268 int i; 00269 RefEdge *ref_edge_ptr; 00270 DLIList<RefVertex*> ref_vertex_list; 00271 ref_edge_list.reset(); 00272 for( i=0; i<ref_edge_list.size(); i++ ) 00273 { 00274 ref_edge_ptr = ref_edge_list.get_and_step(); 00275 DLIList<RefVertex*> ref_vertex_list_temp; 00276 ref_edge_ptr->ref_vertices( ref_vertex_list_temp ); 00277 ref_vertex_list.merge_unique( ref_vertex_list_temp ); 00278 } 00279 append_vertex_points( ref_vertex_list, vec_list ); 00280 00281 // Now add the *inside* curve points 00282 00283 int j, num_pnts; 00284 ref_edge_list.reset(); 00285 for( i=0; i<ref_edge_list.size(); i++ ) 00286 { 00287 ref_edge_ptr = ref_edge_list.get_and_step(); 00288 GMem *g_mem = new GMem; 00289 00290 ref_edge_ptr->get_graphics( *g_mem ); 00291 num_pnts = g_mem->pointListCount; 00292 00293 GPoint* point_list = g_mem->point_list(); 00294 00295 for( j=1; j<num_pnts-1; j++ ) 00296 { 00297 CubitVector* cubit_vector_ptr = new CubitVector( 00298 point_list[j].x, point_list[j].y, point_list[j].z ); 00299 vec_list.append( cubit_vector_ptr ); 00300 } 00301 delete g_mem; 00302 } 00303 00304 return CUBIT_SUCCESS; 00305 } 00306 00307 CubitStatus 00308 BoundingBoxTool::append_vertex_points( DLIList<RefVertex*> &ref_vertex_list, 00309 DLIList<CubitVector*> &vec_list ) 00310 { 00311 int i; 00312 RefVertex *ref_vertex_ptr; 00313 ref_vertex_list.reset(); 00314 for( i=0; i<ref_vertex_list.size(); i++ ) 00315 { 00316 ref_vertex_ptr = ref_vertex_list.get_and_step(); 00317 CubitVector coords = ref_vertex_ptr->coordinates(); 00318 CubitVector* cubit_vector_ptr = new CubitVector( coords ); 00319 vec_list.append( cubit_vector_ptr ); 00320 } 00321 return CUBIT_SUCCESS; 00322 } 00323 00324 00325 CubitStatus 00326 BoundingBoxTool::get_corner_points( CubitVector ¢er, 00327 CubitVector axes[3], 00328 CubitVector &extension, 00329 CubitVector& p1, CubitVector& p2, 00330 CubitVector& p3, CubitVector& p4, 00331 CubitVector& p5, CubitVector& p6, 00332 CubitVector& p7, CubitVector& p8) 00333 { 00334 double x = extension.x(); double y = extension.y(); double z = extension.z(); 00335 00336 // Front, Bottom, Left 00337 center.next_point( -axes[0], x, p1 ); p1.next_point( -axes[1], y, p1 ); 00338 p1.next_point( axes[2], z, p1 ); 00339 00340 // Front, Top, Left 00341 center.next_point( -axes[0], x, p2 ); p2.next_point( axes[1], y, p2 ); 00342 p2.next_point( axes[2], z, p2 ); 00343 00344 // Front, Top, Right 00345 center.next_point( axes[0], x, p3 ); p3.next_point( axes[1], y, p3 ); 00346 p3.next_point( axes[2], z, p3 ); 00347 00348 // Front, Bottom, Right 00349 center.next_point( axes[0], x, p4 ); p4.next_point( -axes[1], y, p4 ); 00350 p4.next_point( axes[2], z, p4 ); 00351 00352 // Back, Bottom, Left 00353 center.next_point( -axes[0], x, p5 ); p5.next_point( -axes[1], y, p5 ); 00354 p5.next_point( -axes[2], z, p5 ); 00355 00356 // Back, Top, Left 00357 center.next_point( -axes[0], x, p6 ); p6.next_point( axes[1], y, p6 ); 00358 p6.next_point( -axes[2], z, p6 ); 00359 00360 // Back, Top, Right 00361 center.next_point( axes[0], x, p7 ); p7.next_point( axes[1], y, p7 ); 00362 p7.next_point( -axes[2], z, p7 ); 00363 00364 // Back, Bottom, Right 00365 center.next_point( axes[0], x, p8 ); p8.next_point( -axes[1], y, p8 ); 00366 p8.next_point( -axes[2], z, p8 ); 00367 00368 return CUBIT_SUCCESS; 00369 } 00370 00371 00372 //Initialize all settings in this class 00373 void BoundingBoxTool::initialize_settings() 00374 { 00375 00376 SettingHandler::instance()->add_setting("Tight Surface", 00377 BoundingBoxTool::set_use_triangles_setting, 00378 BoundingBoxTool::get_use_triangles_setting ); 00379 00380 SettingHandler::instance()->add_setting("Tight Curve", 00381 BoundingBoxTool::set_use_curves_setting, 00382 BoundingBoxTool::get_use_curves_setting); 00383 00384 SettingHandler::instance()->add_setting("Tight Vertex", 00385 BoundingBoxTool::set_use_vertices_setting, 00386 BoundingBoxTool::get_use_vertices_setting); 00387 00388 00389 } 00390 00391 00392 00393 CubitBoolean 00394 BoundingBoxTool::expand_groups_in_list( DLIList<RefEntity*> &ref_entity_list ) 00395 { 00396 CubitBoolean group_found = CUBIT_FALSE; 00397 // just have to step through original entity_list, not the expanded list 00398 for (int i = ref_entity_list.size(); i>0; i--) 00399 { 00400 RefEntity *entity = ref_entity_list.get(); 00401 RefGroup *group = CAST_TO( entity, RefGroup ); 00402 if ( group ) 00403 { 00404 ref_entity_list.remove(); 00405 group->expand_group( ref_entity_list ); 00406 group_found = CUBIT_TRUE; 00407 } 00408 else 00409 ref_entity_list.step(); 00410 } 00411 return group_found; 00412 } 00413 00414 00415 int BoundingBoxTool::get_use_triangles_setting() 00416 {return useTriangles;} 00417 00418 void BoundingBoxTool::set_use_triangles_setting( int val ) 00419 {useTriangles = (val) ? CUBIT_TRUE : CUBIT_FALSE;} 00420 00421 int BoundingBoxTool::get_use_curves_setting() 00422 {return useCurves;} 00423 00424 void BoundingBoxTool::set_use_curves_setting( int val ) 00425 {useCurves = (val) ? CUBIT_TRUE : CUBIT_FALSE;} 00426 00427 int BoundingBoxTool::get_use_vertices_setting() 00428 {return useVertices;} 00429 00430 void BoundingBoxTool::set_use_vertices_setting( int val ) 00431 {useVertices = (val) ? CUBIT_TRUE : CUBIT_FALSE;} 00432 00433 00434 CubitBoolean BoundingBoxTool::get_use_triangles() 00435 {return useTriangles;} 00436 00437 void BoundingBoxTool::set_use_triangles( CubitBoolean val ) 00438 {useTriangles=val;} 00439 00440 CubitBoolean BoundingBoxTool::get_use_curves() 00441 {return useCurves;} 00442 00443 void BoundingBoxTool::set_use_curves( CubitBoolean val ) 00444 {useCurves=val;} 00445 00446 CubitBoolean BoundingBoxTool::get_use_vertices() 00447 {return useVertices;} 00448 00449 void BoundingBoxTool::set_use_vertices( CubitBoolean val ) 00450 {useVertices=val;} 00451 00452