cgma
RefVolume.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : RefVolume.cpp
00003 //
00004 // Purpose       : This file contains the implementation of the class 
00005 //                 RefVolume. 
00006 //
00007 // Special Notes :
00008 //
00009 // Creator       : 
00010 //
00011 // Creation Date : 
00012 //
00013 // Owner         : 
00014 //-------------------------------------------------------------------------
00015 
00016 #include <stdio.h>
00017 #include <string.h>
00018 #include <math.h>
00019 #include <assert.h>
00020 
00021 #include "CubitDefines.h"
00022 #include "CubitMessage.hpp"
00023 #include "CubitBox.hpp"
00024 
00025 #include "Body.hpp"
00026 #include "RefVolume.hpp"
00027 #include "RefFace.hpp"
00028 #include "RefEdge.hpp"
00029 #include "RefVertex.hpp"
00030 #include "CoVolume.hpp"
00031 #include "Shell.hpp"
00032 
00033 // tools
00034 #include "RefEntityFactory.hpp"
00035 #include "GeometryQueryTool.hpp"
00036 #include "ModelQueryEngine.hpp"
00037 
00038 // lists
00039 #include "DLIList.hpp"
00040 
00041 #include "Lump.hpp"
00042 
00043 //-------------------------------------------------------------------------
00044 // Purpose       : Constructor with a pointer to a Lump 
00045 //
00046 // Special Notes :
00047 //
00048 // Creator       : Xuchen Liu
00049 //
00050 // Creation Date : 07/11/96
00051 //-------------------------------------------------------------------------
00052 RefVolume::RefVolume(Lump* lumpPtr)
00053 {
00054    // Set the GeometryEntity pointer
00055    if (lumpPtr != NULL)
00056    {
00057       set_geometry_entity_ptr(lumpPtr) ;
00058 
00059       // Commented-out code from Phil Tuchinsky for FUTURE meshing
00060       //   from a surface mesh with no solid model.
00061       //
00062 //    hasGeometry = CUBIT_TRUE;
00063 //
00064       // initialize the surface mesh entity lists exactly once
00065 //    nodes_boundary  ( surfaceNodes );
00066 //    edges_inclusive ( surfaceEdges );
00067 //    faces_inclusive ( surfaceFaces );
00068    }
00069    else
00070    {
00071       PRINT_ERROR("In the RefVolume(Lump*) constructor\n");
00072       PRINT_ERROR("       Input Lump pointer is NULL\n");
00073       assert(CUBIT_FALSE);
00074    }
00075    
00076    // Initialize the member data
00077    initialize();
00078 }
00079 
00080 //-------------------------------------------------------------------------
00081 // Purpose       : The destructor.
00082 //
00083 // Special Notes :
00084 //
00085 // Creator       : Raikanta Sahu
00086 //
00087 // Creation Date : 10/22/96
00088 //-------------------------------------------------------------------------
00089 RefVolume::~RefVolume()
00090 {
00091 }
00092 
00093 //-------------------------------------------------------------------------
00094 // Purpose       : Return a pointer to the Lump associated with a volume.
00095 //
00096 // Special Notes :
00097 //
00098 // Creator       : Xuechen Liu
00099 //
00100 // Creation Date : 08/02/96
00101 //-------------------------------------------------------------------------
00102 
00103 Lump* RefVolume::get_lump_ptr() 
00104 {
00105   return CAST_TO(get_geometry_entity_ptr(), Lump);
00106 }
00107 
00108 Lump const* RefVolume::get_lump_ptr() const 
00109 {
00110   return CAST_TO(get_geometry_entity_ptr(), Lump);
00111 }
00112 
00113 //-------------------------------------------------------------------------
00114 // Purpose       : Get parent Body
00115 //
00116 // Special Notes : 
00117 //
00118 // Creator       : Jason Kraftcheck
00119 //
00120 // Creation Date : 02/11/03
00121 //-------------------------------------------------------------------------
00122 Body* RefVolume::get_body_ptr()
00123 {
00124   SenseEntity* co_volume_ptr = get_first_sense_entity_ptr();
00125   
00126   if (!co_volume_ptr                  // no covolume 
00127     || co_volume_ptr->next_on_bte() ) // multiple covolumes )
00128   {
00129     PRINT_ERROR("%s:%d RefVolume %d has other than one parent CoVolume.\n"
00130                 "This is a BUG -- please report it.\n",
00131                 __FILE__, __LINE__, id() );
00132     return 0;
00133   }
00134   
00135   return dynamic_cast<Body*>(co_volume_ptr->get_grouping_entity_ptr());
00136 }
00137 
00138 int RefVolume::genus() 
00139 {
00140   int i;
00141   DLIList<RefFace*> faces;
00142   ref_faces(faces);
00143   int gs = 0;
00144   for (i = faces.size(); i > 0; i--)
00145     gs += faces.get_and_step()->genus();
00146   
00147   return 1 - (num_ref_vertices() - num_ref_edges() + faces.size() - gs)/2;
00148 }
00149 
00150 CubitVector RefVolume::center_point()
00151 {
00152   return bounding_box().center();
00153 }
00154 
00155 int RefVolume::dimension() const
00156 {
00157   return 3;
00158 }
00159 
00160 CubitStatus RefVolume::mass_properties( CubitVector &centroid, double &volume )
00161 {
00162   DLIList<Body*> bodies;
00163   this->bodies( bodies );
00164   if( bodies.get()->is_sheet_body() )
00165   {
00166     centroid.set(0,0,0);
00167     volume = 0;
00168     return CUBIT_SUCCESS;
00169   }
00170   else
00171   {
00172     Lump *lump = get_lump_ptr();
00173     return lump->mass_properties( centroid, volume );
00174   }
00175 }
00176 
00177 CubitStatus RefVolume::mass_properties( CubitVector  principal_axes[3], 
00178                                         CubitVector &principal_moments, 
00179                                         CubitVector &centroid, 
00180                                         double &volume )
00181 {
00182   DLIList<Body*> bodies;
00183   this->bodies( bodies );
00184   if( bodies.get()->is_sheet_body() )
00185   {
00186     centroid.set(0,0,0);
00187     volume = 0;
00188     return CUBIT_SUCCESS;
00189   }
00190   else
00191   {
00192     Lump *lump = get_lump_ptr();
00193     return lump->mass_properties( principal_axes, principal_moments, centroid, volume );
00194   }
00195 }
00196 
00197 CubitString RefVolume::measure_label()
00198 {
00199   return "volume";
00200 }
00201 
00202 // Draws each surface in the volume
00203 /*
00204 void RefVolume::draw_my_faces ( int color )
00205 {
00206    DLIList<RefFace*> ref_face_list;
00207    int i;
00208 
00209    if (color == CUBIT_DEFAULT_COLOR_INDEX)
00210       color = this->color();
00211    ref_faces ( ref_face_list );
00212    ref_face_list.reset();
00213    for (i = 0; i < ref_face_list.size(); i++ )
00214       ref_face_list.get_and_step()->draw(color);
00215 }
00216 */
00217 
00218 //-------------------------------------------------------------------------
00219 // Purpose       : Initializes member data
00220 //
00221 // Special Notes :
00222 //
00223 // Creator       : Malcolm J. Panthaki
00224 //
00225 // Creation Date : 10/07/96
00226 //-------------------------------------------------------------------------
00227 void RefVolume::initialize()
00228 {
00229    // Set the Entity and Block IDs for this new RefVolume
00230    GeometryEntity* geom_ptr = get_geometry_entity_ptr();
00231    int saved_id = geom_ptr->get_saved_id();
00232    if ( !saved_id || RefEntityFactory::instance()->get_ref_volume(saved_id) )
00233    {
00234      saved_id =  RefEntityFactory::instance()->next_ref_volume_id();
00235      geom_ptr->set_saved_id(saved_id);
00236    }
00237    entityId = saved_id;
00238 
00239      // read and initialize attributes
00240    auto_read_cubit_attrib();
00241    auto_actuate_cubit_attrib();
00242 
00243      // Assign a default entity name
00244    assign_default_name();   
00245 }
00246 
00247 // unmark this face, and
00248 // recursively unmark all other marked faces sharing an edge with this face.
00249 void unmark_component( RefFace *face )
00250 {
00251   assert( face->marked() );
00252   face->marked( CUBIT_FALSE );
00253   DLIList<RefEdge*> edges;
00254   face->ref_edges( edges );
00255   DLIList<RefFace*> edge_faces;
00256   RefEdge *edge;
00257   for ( int e = edges.size(); e--; ) 
00258   {
00259     edge = edges.get_and_step();
00260     edge_faces.clean_out();
00261     edge->ref_faces( edge_faces );
00262     for ( int f = edge_faces.size(); f--; ) 
00263     {
00264       face = edge_faces.get_and_step();
00265       if ( face->marked() )
00266          unmark_component( face );
00267     }
00268   }
00269 }
00270 
00271 int RefVolume::num_boundary_components() 
00272 {
00273   // get all the surfaces
00274   // march from one to the next, using shared-ref_edge connectivity
00275   
00276   int num_components = 0;
00277   DLIList<RefFace*> face_list;
00278   ref_faces( face_list );
00279 
00280   // mark them as belonging to this volume and not seen yet.
00281   int i;
00282   RefFace *face;
00283   for( i = face_list.size(); i--; )
00284   {
00285     face = face_list.get_and_step();
00286     face->marked( CUBIT_FALSE );
00287   }
00288   
00289   for ( i = face_list.size(); i--; ) 
00290   {
00291     face = face_list.get_and_step();
00292     assert( !face->marked() );
00293     face->marked( CUBIT_TRUE );
00294   }
00295 
00296   for ( i = face_list.size(); i--; ) 
00297   {
00298     face = face_list.get_and_step();
00299     if ( face->marked() ) 
00300     {
00301       num_components++;
00302       unmark_component( face );      
00303     }
00304   }
00305   return num_components;
00306 }
00307 
00308 CubitBoolean RefVolume::about_spatially_equal( 
00309     RefVolume* ref_vol_ptr_2,double tolerance_factor)
00310 {
00311      // Get rid of the trivial case...
00312    if( this == ref_vol_ptr_2)
00313    {
00314       return CUBIT_TRUE;
00315    }
00316 
00317    DLIList<RefEdge*> ref_edge_list_1, ref_edge_list_2;
00318    this->ref_edges( ref_edge_list_1 );
00319    ref_vol_ptr_2->ref_edges( ref_edge_list_2 );
00320       
00321         //compare the size of the two lists.
00322    if ( ref_edge_list_1.size() != ref_edge_list_2.size() )
00323      return CUBIT_FALSE;
00324       
00325    DLIList<RefFace*> ref_face_list_1, ref_face_list_2;
00326    this->ref_faces( ref_face_list_1 );
00327    ref_vol_ptr_2->ref_faces( ref_face_list_2 );
00328       
00329         //compare the size of the two lists.
00330    if ( ref_face_list_1.size() != ref_face_list_2.size() )
00331      return CUBIT_FALSE;
00332       
00333    
00334      //This compare precedure does the following :
00335      //   1. Test the bounding boxes of the 2 volumes for equality;
00336         
00337    CubitBox box_1 = this->bounding_box();
00338    CubitBox box_2 = ref_vol_ptr_2->bounding_box();
00339 
00340    CubitBoolean passes_b_box = CUBIT_FALSE;
00341 
00342        // This test checks to see that the min and max vectors of the
00343        // bounding boxes are within 10% of the length of the bbox diagonal.
00344        // Note that this assumes the default values of resabs=1e-6 and
00345        // tolerance_factor=500
00346 
00347    CubitVector tol_vect(
00348       CUBIT_MIN(box_1.x_range(), box_2.x_range()),
00349       CUBIT_MIN(box_1.y_range(), box_2.y_range()),
00350       CUBIT_MIN(box_1.z_range(), box_2.z_range()) );
00351    tol_vect *= 200.0 * tolerance_factor * GEOMETRY_RESABS;
00352    if( tol_vect.x() < GEOMETRY_RESABS )
00353       tol_vect.x(GEOMETRY_RESABS);
00354    if( tol_vect.y() < GEOMETRY_RESABS )
00355       tol_vect.y(GEOMETRY_RESABS);
00356    if( tol_vect.z() < GEOMETRY_RESABS )
00357       tol_vect.z(GEOMETRY_RESABS);
00358    
00359    if((fabs(box_1.minimum().x() - box_2.minimum().x()) < tol_vect.x()) &&
00360       (fabs(box_1.maximum().x() - box_2.maximum().x()) < tol_vect.x()) &&
00361       (fabs(box_1.minimum().y() - box_2.minimum().y()) < tol_vect.y()) &&
00362       (fabs(box_1.maximum().y() - box_2.maximum().y()) < tol_vect.y()) &&
00363       (fabs(box_1.minimum().z() - box_2.minimum().z()) < tol_vect.z()) &&
00364       (fabs(box_1.maximum().z() - box_2.maximum().z()) < tol_vect.z())) 
00365    {
00366      passes_b_box = CUBIT_TRUE;
00367    }
00368    
00369    return passes_b_box;
00370 }    
00371 
00372 //-------------------------------------------------------------------------
00373 // Purpose       : Check if all shells are sheets
00374 //
00375 // Special Notes : 
00376 //
00377 // Creator       : Jason Kraftcheck
00378 //
00379 // Creation Date : 01/15/04
00380 //-------------------------------------------------------------------------
00381 CubitBoolean RefVolume::is_sheet()
00382 {
00383   DLIList<Shell*> shells;
00384   this->shells(shells);
00385   while (shells.size())
00386     if (!shells.pop()->is_sheet())
00387       return CUBIT_FALSE;
00388   return CUBIT_TRUE;
00389 }
00390   
00391 int RefVolume::validate()
00392 {
00393      //- This function determines whether the entity is valid.
00394      //- Several types of checks can be done, 
00395    int error = 0;
00396 
00397      // Perform general RefEntity checks (measure > 0)
00398    error += RefEntity::validate();
00399 
00400      // Pass through to surface and add in its validation
00401    Lump *lump = this->get_lump_ptr();
00402 
00403      // check surface ptr
00404    if (lump != NULL) {
00405         // Check underlying surface
00406        DLIList <TopologyEntity*> bad_entities;
00407       error += lump->validate(entity_name(), bad_entities);
00408    } else {
00409       PRINT_WARNING("\tWARNING: Null underlying volume for %s, (%s %d)\n",
00410                     entity_name().c_str(), class_name(), id());
00411       error++;
00412    }
00413    return error;
00414 }
00415 
00416 void RefVolume::get_parent_ref_entities(DLIList<RefEntity*>& entity_list)
00417 {
00418 
00419   // First get the type of RefEntity that is a child of "this" one
00420   DagType parent_type = get_parent_ref_entity_type();;
00421 
00422   DLIList<TopologyEntity*> tempList ;
00423 
00424   CubitStatus result = ModelQueryEngine::instance()->
00425       query_model( *this, parent_type, tempList );
00426   if (result == CUBIT_FAILURE)
00427   {
00428     PRINT_ERROR("In RefEntity::get_parent_ref_entities\n");
00429     PRINT_ERROR("       Query failed for unknown reason.\n");
00430     return;
00431   }
00432 
00433   entity_list.clean_out();
00434   for(int i=0; i<tempList.size(); i++)
00435   {
00436     entity_list.append(static_cast<ParentType*>(tempList[i]));
00437   }
00438 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines