cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : FacetShell.cpp 00003 // 00004 // Purpose : 00005 // 00006 // Special Notes : 00007 // 00008 // Creator : David White 00009 // 00010 // Creation Date : 7/18/2000 00011 // 00012 //------------------------------------------------------------------------- 00013 00014 // ********** BEGIN STANDARD INCLUDES ********** 00015 #include <stddef.h> 00016 // ********** END STANDARD INCLUDES ********** 00017 00018 // ********** BEGIN CUBIT INCLUDES ********** 00019 #include "CastTo.hpp" 00020 #include "CubitUtil.hpp" 00021 00022 #include "FacetQueryEngine.hpp" 00023 #include "FacetShell.hpp" 00024 #include "ShellSM.hpp" 00025 #include "Lump.hpp" 00026 #include "Surface.hpp" 00027 00028 #include "FacetBody.hpp" 00029 #include "FacetLump.hpp" 00030 #include "FacetSurface.hpp" 00031 #include "FacetLoop.hpp" 00032 #include "FacetCoEdge.hpp" 00033 #include "FacetCurve.hpp" 00034 #include "FacetPoint.hpp" 00035 #include "FacetEvalTool.hpp" 00036 #include "CubitPoint.hpp" 00037 #include "CubitFacetEdge.hpp" 00038 #include "GfxDebug.hpp" 00039 00040 // ********** END CUBIT INCLUDES ********** 00041 00042 // ********** BEGIN STATIC DECLARATIONS ********** 00043 // ********** END STATIC DECLARATIONS ********** 00044 00045 // ********** BEGIN PUBLIC FUNCTIONS ********** 00046 00047 //------------------------------------------------------------------------- 00048 // Purpose : A constructor with a pointer to a SHELL. 00049 // 00050 // Special Notes : 00051 // 00052 //------------------------------------------------------------------------- 00053 FacetShell::FacetShell(Lump* my_lump, 00054 DLIList<Surface*> &my_surfs ) 00055 { 00056 myLump = my_lump; 00057 mySurfs += my_surfs; 00058 } 00059 00060 //------------------------------------------------------------------------- 00061 // Purpose : A constructor with list of surfaces. 00062 // 00063 // Special Notes : For use with save/restore 00064 // 00065 //------------------------------------------------------------------------- 00066 FacetShell::FacetShell( DLIList<Surface*> &my_surfs ) 00067 { 00068 myLump = NULL; 00069 mySurfs += my_surfs; 00070 } 00071 //------------------------------------------------------------------------- 00072 // Purpose : The destructor. 00073 // 00074 // Special Notes : 00075 // 00076 //------------------------------------------------------------------------- 00077 FacetShell::~FacetShell() 00078 {} 00079 00080 00081 //------------------------------------------------------------------------- 00082 // Purpose : Get geometry modeling engine: FacetQueryEngine 00083 // 00084 // Special Notes : 00085 // 00086 //------------------------------------------------------------------------- 00087 GeometryQueryEngine* 00088 FacetShell::get_geometry_query_engine() const 00089 { 00090 return FacetQueryEngine::instance(); 00091 } 00092 00093 void FacetShell::append_simple_attribute_virt(const CubitSimpleAttrib&) 00094 { 00095 } 00096 void FacetShell::remove_simple_attribute_virt(const CubitSimpleAttrib& ) 00097 { 00098 } 00099 void FacetShell::remove_all_simple_attribute_virt() 00100 { 00101 } 00102 CubitStatus FacetShell::get_simple_attribute(DLIList<CubitSimpleAttrib>&) 00103 { 00104 return CUBIT_FAILURE; 00105 } 00106 CubitStatus FacetShell::get_simple_attribute(const CubitString&, 00107 DLIList<CubitSimpleAttrib>&) 00108 { return CUBIT_FAILURE; } 00109 00110 /* 00111 void FacetShell::bodysms(DLIList<BodySM*> &bodies) 00112 { 00113 if (myLump) 00114 myLump->bodysms(bodies); 00115 } 00116 00117 void FacetShell::lumps(DLIList<Lump*> &lumps) 00118 { 00119 lumps.append_unique(myLump); 00120 } 00121 00122 void FacetShell::shellsms(DLIList<ShellSM*> &shellsms) 00123 { 00124 shellsms.append_unique(this); 00125 } 00126 00127 void FacetShell::surfaces(DLIList<Surface*> &surfaces) 00128 { 00129 int ii; 00130 for ( ii = mySurfs.size(); ii > 0; ii-- ) 00131 { 00132 surfaces.append_unique(mySurfs.get_and_step()); 00133 } 00134 } 00135 00136 void FacetShell::loopsms(DLIList<LoopSM*> &loopsms) 00137 { 00138 int ii; 00139 for ( ii = mySurfs.size(); ii > 0; ii-- ) 00140 { 00141 mySurfs.get_and_step()->loopsms(loopsms); 00142 } 00143 } 00144 00145 void FacetShell::curves(DLIList<Curve*> &curves) 00146 { 00147 int ii; 00148 for ( ii = mySurfs.size(); ii > 0; ii-- ) 00149 { 00150 mySurfs.get_and_step()->curves(curves); 00151 } 00152 } 00153 00154 void FacetShell::coedgesms(DLIList<CoEdgeSM*> &coedgesms) 00155 { 00156 int ii; 00157 for ( ii = mySurfs.size(); ii > 0; ii-- ) 00158 { 00159 mySurfs.get_and_step()->coedgesms(coedgesms); 00160 } 00161 } 00162 00163 void FacetShell::points(DLIList<Point*> &points) 00164 { 00165 int ii; 00166 for ( ii = mySurfs.size(); ii > 0; ii-- ) 00167 { 00168 mySurfs.get_and_step()->points(points); 00169 } 00170 } 00171 */ 00172 00173 void FacetShell::add_lump(Lump* lump_ptr) 00174 { 00175 assert(NULL == myLump); 00176 myLump = lump_ptr; 00177 } 00178 00179 00180 //------------------------------------------------------------------------- 00181 // Purpose : Query solid modeler topology 00182 // 00183 // Special Notes : 00184 // 00185 // Creator : Jason Kraftcheck 00186 // 00187 // Creation Date : 00188 //------------------------------------------------------------------------- 00189 void FacetShell::get_parents_virt( DLIList<TopologyBridge*>& parents ) 00190 { parents.append(myLump); } 00191 void FacetShell::get_children_virt( DLIList<TopologyBridge*>& children ) 00192 { CAST_LIST_TO_PARENT( mySurfs, children ); } 00193 00194 00195 void FacetShell::get_lumps( DLIList<FacetLump*>& result_list ) 00196 { 00197 FacetLump* lump = dynamic_cast<FacetLump*>(myLump); 00198 if (lump) 00199 result_list.append(lump); 00200 } 00201 00202 void FacetShell::get_surfaces( DLIList<FacetSurface*>& result_list ) 00203 { 00204 mySurfs.reset(); 00205 for ( int i = 0; i < mySurfs.size(); i++ ) 00206 if ( FacetSurface* surf = dynamic_cast<FacetSurface*>(mySurfs.next(i)) ) 00207 result_list.append_unique(surf); 00208 } 00209 00210 00211 void FacetShell::get_coedges( DLIList<FacetCoEdge*>& result_list ) 00212 { 00213 DLIList<FacetSurface*> surface_list; 00214 get_surfaces( surface_list ); 00215 surface_list.reset(); 00216 for ( int i = 0; i < surface_list.size(); i++ ) 00217 surface_list.next(i)->get_coedges( result_list ); 00218 } 00219 00220 void FacetShell::get_curves( DLIList<FacetCurve*>& result_list ) 00221 { 00222 DLIList<FacetCoEdge*> coedge_list; 00223 get_coedges( coedge_list ); 00224 coedge_list.reset(); 00225 for ( int i = coedge_list.size(); i--; ) 00226 { 00227 FacetCoEdge* coedge = coedge_list.get_and_step(); 00228 FacetCurve* curve = dynamic_cast<FacetCurve*>(coedge->curve()); 00229 if (curve) 00230 result_list.append_unique(curve); 00231 } 00232 } 00233 00234 //------------------------------------------------------------------------- 00235 // Purpose : Disconnect input surfaces from "this" shell 00236 // 00237 // Special Notes : 00238 // 00239 // Creator : Corey Ernst 00240 // 00241 // Creation Date : 08/31/04 00242 //------------------------------------------------------------------------- 00243 void FacetShell::disconnect_surfaces( DLIList<FacetSurface*> &surfs_to_disconnect ) 00244 { 00245 for (int i = surfs_to_disconnect.size(); i--; ) 00246 { 00247 FacetSurface* surface = surfs_to_disconnect.get_and_step(); 00248 if( mySurfs.move_to( dynamic_cast<Surface*>(surface) ) ) 00249 mySurfs.change_to(NULL); 00250 00251 if (surface) 00252 surface->remove_shell(this); 00253 } 00254 mySurfs.remove_all_with_value( NULL ); 00255 } 00256 00257 00258 //------------------------------------------------------------------------- 00259 // Purpose : Tear down topology 00260 // 00261 // Special Notes : 00262 // 00263 // Creator : Jason Kraftcheck 00264 // 00265 // Creation Date : 09/29/03 00266 //------------------------------------------------------------------------- 00267 void FacetShell::disconnect_all_surfaces() 00268 { 00269 mySurfs.reset(); 00270 for (int i = mySurfs.size(); i--; ) 00271 { 00272 Surface* sm_ptr = mySurfs.get_and_step(); 00273 FacetSurface* surface = dynamic_cast<FacetSurface*>(sm_ptr); 00274 if (surface) 00275 surface->remove_shell(this); 00276 } 00277 mySurfs.clean_out(); 00278 } 00279 00280 //------------------------------------------------------------------------- 00281 // Purpose : Flip surface-use sense 00282 // 00283 // Special Notes : 00284 // 00285 // Creator : Jason Kraftcheck 00286 // 00287 // Creation Date : 05/26/04 00288 //------------------------------------------------------------------------- 00289 void FacetShell::reverse() 00290 { 00291 for (int i = mySurfs.size(); i--; ) 00292 { 00293 FacetSurface* surf = dynamic_cast<FacetSurface*>(mySurfs.next(i)); 00294 CubitSense sense = surf->get_shell_sense( this ); 00295 assert( CUBIT_UNKNOWN != sense ); 00296 surf->set_shell_sense( this, CubitUtil::opposite_sense( sense ) ); 00297 } 00298 } 00299 00300 //------------------------------------------------------------------------- 00301 // Purpose : Actually flip the underlying surfaces 00302 // 00303 // Special Notes : 00304 // 00305 // Creator : Michael Brewer 00306 // 00307 // Creation Date : 03/22/05 00308 //------------------------------------------------------------------------- 00309 void FacetShell::reverse_surfaces() 00310 { 00311 for (int i = mySurfs.size(); i--; ) 00312 { 00313 FacetSurface* surf = dynamic_cast<FacetSurface*>(mySurfs.next(i)); 00314 surf->reverse_sense(); 00315 } 00316 } 00317 //------------------------------------------------------------------------- 00318 // Purpose : Determines if point is contained within shell 00319 // 00320 // Special Notes : If the shell is a void, it contains all points it doesn't enclose 00321 // 00322 // Creator : Corey Ernst 00323 // 00324 // Creation Date : 09/01/04 00325 //------------------------------------------------------------------------- 00326 CubitPointContainment FacetShell::point_containment( 00327 const CubitVector &input_point, 00328 double tolerance ) 00329 { 00330 //just to avoid crashes, make sure we have surfaces in this list. 00331 if(mySurfs.size() < 1){ 00332 return CUBIT_PNT_OUTSIDE; 00333 } 00334 CubitVector closest_location, point = input_point; 00335 FacetSurface *closest_surf = dynamic_cast<FacetSurface*>(mySurfs.get_and_step()); 00336 FacetSurface *tmp_surf; 00337 closest_surf->closest_point_trimmed( point, closest_location ); 00338 double shortest_dist = point.distance_between( closest_location ); 00339 00340 int i; 00341 //Look through all this shell's surfaces to find the closest 00342 //surface to input_point 00343 00344 for(i=mySurfs.size()-1; i--;) 00345 { 00346 CubitVector tmp_closest_location; 00347 tmp_surf = dynamic_cast<FacetSurface*>(mySurfs.get_and_step()); 00348 tmp_surf->closest_point_trimmed( point, tmp_closest_location ); 00349 00350 double tmp_shortest_dist = point.distance_between( tmp_closest_location ); 00351 if( tmp_shortest_dist < shortest_dist ) 00352 { 00353 closest_location = tmp_closest_location; 00354 closest_surf = tmp_surf; 00355 shortest_dist = tmp_shortest_dist; 00356 } 00357 } 00358 00359 if( tolerance < 0 ) 00360 tolerance = GEOMETRY_RESABS; 00361 00362 //determine if it's on the surface, inside or outside 00363 if( shortest_dist <= tolerance ) 00364 return CUBIT_PNT_BOUNDARY; 00365 00366 //find the closest facet on that surface to input_point 00367 CubitFacet *closest_facet = closest_surf->get_eval_tool()->closest_facet( closest_location ); 00368 00369 //get the coordinates of the closest point 00370 CubitPoint *pt1 = NULL; 00371 CubitPoint *pt2 = NULL; 00372 closest_facet->closest_point_trimmed( point, closest_location, pt1, pt2 ); 00373 00374 CubitVector normal; 00375 CubitPoint *on_point = NULL; 00376 //case 1: point is closest to an edge of the facet 00377 if( pt1 || pt2 ) 00378 { 00379 //only returned one, so the it is closest to a node 00380 if(!pt2){ 00381 on_point = pt1; 00382 } 00383 else if(!pt1){ 00384 on_point = pt2; 00385 } 00386 else{//double-check that we are not closest to a single node 00387 00388 if((pt1->coordinates().distance_between(closest_location)) <= tolerance ) 00389 on_point = pt1; 00390 else if((pt2->coordinates().distance_between(closest_location)) <= tolerance ) 00391 on_point = pt2; 00392 } 00393 00394 if( on_point ) 00395 { 00396 //get all facets that share this point 00397 DLIList<CubitFacet*> facets_sharing_point; 00398 on_point->facets( facets_sharing_point ); 00399 00400 for(i=facets_sharing_point.size(); i--; ) 00401 normal += facets_sharing_point.get_and_step()->normal(); 00402 00403 //average the normals of all these facets 00404 normal /= facets_sharing_point.size(); 00405 } 00406 else 00407 { 00408 //case 2: get the 2 normals of the 2 neighboring facets and average them 00409 int index; 00410 CubitFacetEdge *shared_facet_edge; 00411 shared_facet_edge = closest_facet->edge_from_pts( pt1, pt2, index); 00412 CubitFacet *other_facet = shared_facet_edge->other_facet( closest_facet ); 00413 if(!other_facet){ 00414 PRINT_ERROR("Edge is not connected to two facets.\n"); 00415 normal = closest_facet->normal(); 00416 } 00417 else{ 00418 normal = ( closest_facet->normal() + other_facet->normal() ) / 2; 00419 } 00420 } 00421 } 00422 else 00423 { 00424 //case 3: just get the normal of this facet 00425 normal = closest_facet->normal(); 00426 } 00427 00428 // if ( closest_surf->get_relative_surface_sense() == CUBIT_REVERSED ) 00429 // { 00430 // PRINT_WARNING("mbrewer: This shouldn't happen anymore.\n"); 00431 // normal = -1.0*( normal ); 00432 // } 00433 00434 ShellSM *shell_sm = static_cast<ShellSM*>(this); 00435 if( closest_surf->get_shell_sense( shell_sm ) == CUBIT_REVERSED ) 00436 { 00437 normal = -1.0*( normal ); 00438 } 00439 if( (point-closest_location)%(normal) > 0 ) 00440 return CUBIT_PNT_OUTSIDE; 00441 else 00442 return CUBIT_PNT_INSIDE; 00443 } 00444 00445 //Determine whether this shell is a sheet (ie, closed or not) 00446 CubitBoolean FacetShell::is_sheet() 00447 { 00448 //get a list of all the facets in the sheet 00449 DLIList<CubitFacet*> facet_list; 00450 int i; 00451 for (i = mySurfs.size(); i--; ) 00452 { 00453 FacetSurface* surf = dynamic_cast<FacetSurface*>(mySurfs.next(i)); 00454 surf->tris(facet_list); 00455 } 00456 //should be unique... doesn't hurt anything if it isn't 00457 //facet_list.uniquify_ordered(); 00458 CubitFacet* this_facet; 00459 CubitPoint* node_1; 00460 CubitPoint* node_2; 00461 CubitPoint* node_3; 00462 //if any of the facets don't have another facet across a given 00463 // edge... this is a sheet shell because it isn't closed. 00464 for (i = facet_list.size(); i--; ){ 00465 this_facet=facet_list.get_and_step(); 00466 if(!this_facet){ 00467 PRINT_ERROR("Unexpected NULL pointer."); 00468 return CUBIT_TRUE; 00469 } 00470 this_facet->tri_nodes(node_1,node_2,node_3); 00471 if(!this_facet->shared_facet( node_1, node_2 ) || 00472 !this_facet->shared_facet( node_1, node_3 ) || 00473 !this_facet->shared_facet( node_2, node_3 ) ){ 00474 return CUBIT_TRUE; 00475 } 00476 } 00477 //otherwise we made it through without finding a gap so it is close... 00478 // thus not a sheet. 00479 return CUBIT_FALSE; 00480 } 00481 00482 00483 00484 // ********** END PUBLIC FUNCTIONS ********** 00485 00486 // ********** BEGIN PROTECTED FUNCTIONS ********** 00487 // ********** END PROTECTED FUNCTIONS ********** 00488 00489 // ********** BEGIN PRIVATE FUNCTIONS ********** 00490 // ********** END PRIVATE FUNCTIONS ********** 00491 00492 // ********** BEGIN HELPER CLASSES ********** 00493 // ********** END HELPER CLASSES ********** 00494 00495 // ********** BEGIN EXTERN FUNCTIONS ********** 00496 // ********** END EXTERN FUNCTIONS ********** 00497 00498 // ********** BEGIN STATIC FUNCTIONS ********** 00499 // ********** END STATIC FUNCTIONS ********** 00500