cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : FacetLump.cpp 00003 // 00004 // Purpose : 00005 // 00006 // Creator : David White 00007 // 00008 // Creation Date : 7/18/2000 00009 // 00010 //------------------------------------------------------------------------- 00011 00012 // ********** BEGIN STANDARD INCLUDES ********** 00013 #include <assert.h> 00014 // ********** END STANDARD INCLUDES ********** 00015 00016 00017 // ********** BEGIN CUBIT INCLUDES ********** 00018 #include "FacetQueryEngine.hpp" 00019 #include "FacetLump.hpp" 00020 #include "CastTo.hpp" 00021 #include "Surface.hpp" 00022 #include "DLIList.hpp" 00023 #include "CubitFacet.hpp" 00024 #include "CubitPoint.hpp" 00025 #include "CubitVector.hpp" 00026 #include "CubitString.hpp" 00027 #include "ShellSM.hpp" 00028 #include "BodySM.hpp" 00029 #include "Body.hpp" 00030 00031 #include "FacetBody.hpp" 00032 #include "FacetShell.hpp" 00033 #include "FacetSurface.hpp" 00034 #include "FacetLoop.hpp" 00035 #include "FacetCoEdge.hpp" 00036 #include "FacetCurve.hpp" 00037 #include "FacetPoint.hpp" 00038 00039 // ********** END CUBIT INCLUDES ********** 00040 00041 // ********** BEGIN FORWARD DECLARATIONS ********** 00042 class RefVolume; 00043 // ********** END FORWARD DECLARATIONS ********** 00044 00045 // ********** BEGIN STATIC DECLARATIONS ********** 00046 // ********** END STATIC DECLARATIONS ********** 00047 00048 // ********** BEGIN PUBLIC FUNCTIONS ********** 00049 00050 //------------------------------------------------------------------------- 00051 // Purpose : The constructor with a pointer to the owning shells and body. 00052 // 00053 // Special Notes : 00054 // 00055 //------------------------------------------------------------------------- 00056 FacetLump::FacetLump(DLIList<ShellSM*> &shells, 00057 BodySM *body_ptr ) 00058 { 00059 myBodyPtr = body_ptr; 00060 myShells += shells; 00061 } 00062 00063 00064 FacetLump::~FacetLump() 00065 {} 00066 00067 //------------------------------------------------------------------------- 00068 // Purpose : The purpose of this function is to append a 00069 // attribute to the GE. The name is attached to the 00070 // underlying solid model entity this one points to. 00071 // 00072 // 00073 // Special Notes : 00074 // 00075 // Creator : Malcolm J. Panthaki 00076 // 00077 // Creation Date : 11/21/96 00078 //------------------------------------------------------------------------- 00079 void FacetLump::append_simple_attribute_virt(const CubitSimpleAttrib &csa) 00080 { attribSet.append_attribute(csa); } 00081 00082 //------------------------------------------------------------------------- 00083 // Purpose : The purpose of this function is to remove a simple 00084 // attribute attached to this geometry entity. The name is 00085 // removed from the underlying BODY this points to. 00086 // 00087 // Special Notes : 00088 // 00089 // Creator : David R. White 00090 // 00091 // Creation Date : 03/18/97 00092 //------------------------------------------------------------------------- 00093 void FacetLump::remove_simple_attribute_virt(const CubitSimpleAttrib &csa ) 00094 { attribSet.remove_attribute(csa); } 00095 00096 //------------------------------------------------------------------------- 00097 // Purpose : The purpose of this function is to remove all simple 00098 // attributes attached to this geometry entity. Also 00099 // removes lingering GTC attributes. 00100 // 00101 // 00102 // Special Notes : 00103 // 00104 // Creator : Greg Nielson 00105 // 00106 // Creation Date : 07/10/98 00107 //------------------------------------------------------------------------- 00108 void FacetLump::remove_all_simple_attribute_virt() 00109 { attribSet.remove_all_attributes(); } 00110 00111 //------------------------------------------------------------------------- 00112 // Purpose : The purpose of this function is to get the 00113 // attributes attached to this geometry entity. The name is 00114 // attached to the underlying BODY this points to. 00115 // 00116 // Special Notes : 00117 // 00118 //------------------------------------------------------------------------- 00119 CubitStatus FacetLump::get_simple_attribute(DLIList<CubitSimpleAttrib>& csa_list) 00120 { return attribSet.get_attributes( csa_list ); } 00121 00122 CubitStatus FacetLump::get_simple_attribute( const CubitString& name, 00123 DLIList<CubitSimpleAttrib>& csa_list ) 00124 { return attribSet.get_attributes( name, csa_list ); } 00125 00126 CubitStatus FacetLump::save_attribs( FILE *file_ptr ) 00127 { return attribSet.save_attributes( file_ptr ); } 00128 00129 CubitStatus FacetLump::restore_attribs( FILE *file_ptr, unsigned int endian ) 00130 { return attribSet.restore_attributes( file_ptr, endian ); } 00131 00132 00133 00134 00135 //------------------------------------------------------------------------- 00136 // Purpose : Get the bounding box of the object. 00137 // 00138 // Special Notes : 00139 // 00140 //------------------------------------------------------------------------- 00141 CubitBox FacetLump::bounding_box() const 00142 { 00143 CubitBox my_box, temp_box; 00144 DLIList<FacetSurface*> surfaces; 00145 int ii; 00146 const_cast<FacetLump*>(this)->get_surfaces(surfaces); 00147 if (surfaces.size() > 0) 00148 { 00149 Surface* surface = surfaces.get_and_step(); 00150 my_box = surface->bounding_box(); 00151 for ( ii = surfaces.size(); ii > 1; ii-- ) 00152 { 00153 surface = surfaces.get_and_step(); 00154 temp_box = surface->bounding_box(); 00155 //unite the boxes.. 00156 my_box |= temp_box; 00157 } 00158 } 00159 return my_box; 00160 } 00161 00162 //------------------------------------------------------------------------- 00163 // Purpose : Get geometry modeling engine: FacetGeometryEngine 00164 // 00165 // Special Notes : 00166 // 00167 //------------------------------------------------------------------------- 00168 GeometryQueryEngine* 00169 FacetLump::get_geometry_query_engine() const 00170 { 00171 return FacetQueryEngine::instance(); 00172 } 00173 00174 //------------------------------------------------------------------------- 00175 // Purpose : Returns the volume of the Lump 00176 // 00177 // Special Notes : 00178 // 00179 // Creator : 00180 // 00181 // Creation Date : 00182 //------------------------------------------------------------------------- 00183 double FacetLump::measure() 00184 { 00185 DLIList<CubitFacet*> bounding_facets; 00186 DLIList<CubitPoint*> bounding_points; 00187 DLIList<FacetSurface*> surfaces; 00188 Surface *curr_surface; 00189 FacetSurface *facet_surface; 00190 //if this is a sheet body... return 0.0 00191 00192 //Body *tmp_body = CAST_TO(myBodyPtr->topology_entity(), Body); 00193 if( is_sheet() ) 00194 return 0.0; 00195 00196 int ii; 00197 get_surfaces(surfaces); 00198 if (surfaces.size() > 0) 00199 { 00200 for ( ii = surfaces.size(); ii > 0; ii-- ) 00201 { 00202 curr_surface = surfaces.get_and_step(); 00203 facet_surface = CAST_TO(curr_surface, FacetSurface); 00204 if ( facet_surface == NULL ) 00205 { 00206 PRINT_ERROR("Facet lump has surfaces that aren't facets?"); 00207 return 1; 00208 } 00209 facet_surface->get_my_facets(bounding_facets, bounding_points); 00210 } 00211 } 00212 double volume, curr_facet_area, summation = 0.0; 00213 CubitFacet *curr_facet; 00214 CubitVector normal_of_curr_facet, vector_of_point; 00215 CubitPoint *point_1, *point_2, *point_3; 00216 00217 for( int jj = bounding_facets.size(); jj > 0; jj-- ) 00218 { 00219 curr_facet = bounding_facets.get_and_step(); 00220 curr_facet_area = curr_facet->area(); // Current facet's area 00221 00222 normal_of_curr_facet = curr_facet->normal(); // Current facet's normal 00223 00224 curr_facet->points(point_1, point_2, point_3); // Current facet's points 00225 00226 vector_of_point = point_1->coordinates(); // One point's vector 00227 00228 summation += ( double(vector_of_point % normal_of_curr_facet) * curr_facet_area); 00229 } 00230 00231 volume = summation / 3; 00232 00233 return volume; 00234 } 00235 void FacetLump::get_parents_virt(DLIList<TopologyBridge*> &bodies) 00236 { 00237 if (myBodyPtr != NULL ) 00238 bodies.append_unique(myBodyPtr); 00239 } 00240 00241 void FacetLump::get_children_virt(DLIList<TopologyBridge*> &shellsms) 00242 { 00243 int ii; 00244 for ( ii = myShells.size(); ii > 0; ii-- ) 00245 { 00246 shellsms.append_unique(myShells.get_and_step()); 00247 } 00248 } 00249 00250 void FacetLump::get_bodies( DLIList<FacetBody*>& result_list ) 00251 { 00252 FacetBody* body = dynamic_cast<FacetBody*>(myBodyPtr); 00253 if (body) 00254 result_list.append(body); 00255 } 00256 00257 void FacetLump::get_shells( DLIList<FacetShell*>& result_list ) 00258 { 00259 myShells.reset(); 00260 for ( int i = 0; i < myShells.size(); i++ ) 00261 if ( FacetShell* shell = dynamic_cast<FacetShell*>(myShells.next(i)) ) 00262 result_list.append(shell); 00263 } 00264 00265 void FacetLump::get_surfaces( DLIList<FacetSurface*>& result_list ) 00266 { 00267 DLIList<FacetShell*> shell_list; 00268 DLIList<FacetSurface*> tmp_list; 00269 get_shells(shell_list); 00270 shell_list.reset(); 00271 for ( int i = 0; i < shell_list.size(); i++ ) 00272 { 00273 tmp_list.clean_out(); 00274 shell_list.next(i)->get_surfaces( tmp_list ); 00275 result_list.merge_unique( tmp_list ); 00276 } 00277 } 00278 00279 00280 void FacetLump::get_coedges( DLIList<FacetCoEdge*>& result_list ) 00281 { 00282 DLIList<FacetSurface*> surface_list; 00283 get_surfaces( surface_list ); 00284 surface_list.reset(); 00285 for ( int i = 0; i < surface_list.size(); i++ ) 00286 surface_list.next(i)->get_coedges( result_list ); 00287 } 00288 00289 void FacetLump::get_curves( DLIList<FacetCurve*>& result_list ) 00290 { 00291 DLIList<FacetCoEdge*> coedge_list; 00292 get_coedges( coedge_list ); 00293 coedge_list.reset(); 00294 for ( int i = coedge_list.size(); i--; ) 00295 { 00296 FacetCoEdge* coedge = coedge_list.get_and_step(); 00297 FacetCurve* curve = dynamic_cast<FacetCurve*>(coedge->curve()); 00298 if (curve) 00299 result_list.append_unique(curve); 00300 } 00301 } 00302 00303 00304 void FacetLump::add_shell( FacetShell *shell ) 00305 { 00306 ShellSM* sm_ptr; 00307 sm_ptr = dynamic_cast<ShellSM*>(shell); 00308 00309 if( sm_ptr ) 00310 myShells.append( sm_ptr ); 00311 00312 shell->add_lump( this ); 00313 } 00314 00315 void FacetLump::remove_shell( FacetShell *shell ) 00316 { 00317 ShellSM* sm_ptr; 00318 sm_ptr = dynamic_cast<ShellSM*>(shell); 00319 00320 if( sm_ptr ) 00321 myShells.remove( sm_ptr ); 00322 00323 shell->remove_lump(); 00324 } 00325 00326 //------------------------------------------------------------------------- 00327 // Purpose : Tear down topology 00328 // 00329 // Special Notes : 00330 // 00331 // Creator : Jason Kraftcheck 00332 // 00333 // Creation Date : 09/29/03 00334 //------------------------------------------------------------------------- 00335 void FacetLump::disconnect_all_shells() 00336 { 00337 myShells.reset(); 00338 for (int i = myShells.size(); i--; ) 00339 { 00340 ShellSM* sm_ptr = myShells.get_and_step(); 00341 FacetShell* shell = dynamic_cast<FacetShell*>(sm_ptr); 00342 if (shell) 00343 { 00344 assert(shell->get_lump() == this); 00345 shell->remove_lump(); 00346 } 00347 } 00348 myShells.clean_out(); 00349 } 00350 00351 //------------------------------------------------------------------------- 00352 // Purpose : Calculate centroid 00353 // 00354 // Special Notes : 00355 // 00356 // Creator : Jason Kraftcheck 00357 // 00358 // Creation Date : 05/12/04 00359 //------------------------------------------------------------------------- 00360 #include "GfxDebug.hpp" 00361 CubitStatus FacetLump::mass_properties( CubitVector& centroid, double& volume ) 00362 { 00363 int i; 00364 00365 DLIList<FacetShell*> shells( myShells.size() ); 00366 CAST_LIST( myShells, shells, FacetShell ); 00367 assert( myShells.size() == shells.size() ); 00368 00369 DLIList<FacetSurface*> surfaces; 00370 DLIList<FacetShell*> surf_shells; 00371 get_surfaces( surfaces ); 00372 00373 DLIList<CubitFacet*> facets, surf_facets; 00374 DLIList<CubitPoint*> junk; 00375 DLIList<CubitSense> senses; 00376 for (i = surfaces.size(); i--; ) 00377 { 00378 FacetSurface* surf = surfaces.step_and_get(); 00379 surf_shells.clean_out(); 00380 surf->get_shells( surf_shells ); 00381 surf_shells.intersect( shells ); 00382 assert( surf_shells.size() ); 00383 CubitSense sense = surf->get_shell_sense( surf_shells.get() ); 00384 if (surf_shells.size() == 1 && CUBIT_UNKNOWN != sense) 00385 { 00386 surf_facets.clean_out(); 00387 junk.clean_out(); 00388 surf->get_my_facets( surf_facets, junk ); 00389 facets += surf_facets; 00390 00391 for (int j = surf_facets.size(); j--; ) 00392 senses.append(sense); 00393 } 00394 } 00395 00396 const CubitVector p0 = bounding_box().center(); 00397 CubitVector p1, p2, p3, normal; 00398 centroid.set( 0.0, 0.0, 0.0 ); 00399 volume = 0.0; 00400 00401 facets.reset(); 00402 senses.reset(); 00403 for (i = facets.size(); i--; ) 00404 { 00405 CubitFacet* facet = facets.get_and_step(); 00406 CubitSense sense = senses.get_and_step(); 00407 p1 = facet->point(0)->coordinates(); 00408 p2 = facet->point(1)->coordinates(); 00409 p3 = facet->point(2)->coordinates(); 00410 normal = (p3 - p1) * (p2 - p1); 00411 00412 double two_area = normal.length(); 00413 if (two_area > CUBIT_RESABS ) 00414 { 00415 if (CUBIT_REVERSED == sense) 00416 normal = -normal; 00417 00418 normal /= two_area; 00419 00420 double height = normal % (p0 - p1); 00421 double vol = two_area * height; 00422 00423 volume += vol; 00424 centroid += vol * (p0 + p1 + p2 + p3); 00425 } 00426 } 00427 00428 if (volume > CUBIT_RESABS) 00429 centroid /= 4.0 * volume; 00430 volume /= 6.0; 00431 return CUBIT_SUCCESS; 00432 } 00433 00434 CubitPointContainment FacetLump::point_containment( const CubitVector &point, 00435 double tolerance ) 00436 { 00437 CubitPointContainment pc_value; 00438 FacetShell *facet_shell; 00439 00440 int i; 00441 for(i=myShells.size(); i--;) 00442 { 00443 facet_shell = dynamic_cast<FacetShell*>(myShells.get_and_step()); 00444 pc_value = facet_shell->point_containment( point, tolerance ); 00445 if( pc_value == CUBIT_PNT_OUTSIDE ) 00446 return CUBIT_PNT_OUTSIDE; 00447 else if( pc_value == CUBIT_PNT_BOUNDARY ) 00448 return CUBIT_PNT_BOUNDARY; 00449 } 00450 00451 return CUBIT_PNT_INSIDE; 00452 00453 } 00454 00455 //Determine whether this lump is really a sheet (that is, sheet-body). 00456 CubitBoolean FacetLump::is_sheet( ) 00457 { 00458 FacetShell *facet_shell; 00459 int i; 00460 //if any of the shells are sheets, the body is assume to be a sheet 00461 // for our purposes... 00462 for(i=myShells.size(); i--;) 00463 { 00464 facet_shell = dynamic_cast<FacetShell*>(myShells.get_and_step()); 00465 if(facet_shell->is_sheet()){ 00466 return CUBIT_TRUE; 00467 } 00468 } 00469 return CUBIT_FALSE; 00470 } 00471