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