cgma
BoundingBoxTool.cpp
Go to the documentation of this file.
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 &center,
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 &center,
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 &center,
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines