cgma
|
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 ¢roid, 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 ¢roid, 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 }