cgma
PartitionShell.cpp
Go to the documentation of this file.
00001 #include "PartitionShell.hpp"
00002 #include "PartitionLump.hpp"
00003 #include "PartitionSurface.hpp"
00004 #include "VirtualQueryEngine.hpp"
00005 #include "CubitFacetData.hpp"
00006 
00007 PartitionShell::PartitionShell( )
00008   : myLump(0), lumpNext(0), firstCoSurf(0)
00009   { }
00010 
00011 PartitionShell::~PartitionShell()
00012 {
00013   assert( !myLump );
00014   remove_all_surfaces();
00015 }
00016 
00017 CubitStatus PartitionShell::add( PartitionCoSurf* cosurf )
00018 {
00019   if( cosurf->myShell || cosurf->shellNext )
00020   {
00021     assert(!cosurf->myShell && !cosurf->shellNext);
00022     return CUBIT_FAILURE;
00023   }
00024   
00025   cosurf->myShell = this;
00026   cosurf->shellNext = firstCoSurf;
00027   firstCoSurf = cosurf;
00028   return CUBIT_SUCCESS;
00029 }
00030 
00031 CubitStatus PartitionShell::remove( PartitionCoSurf* cosurf )
00032 {
00033   if( cosurf->myShell != this )
00034   {
00035     assert( cosurf->myShell == this );
00036     return CUBIT_FAILURE;
00037   }
00038   
00039   if( cosurf == firstCoSurf )
00040   {
00041     firstCoSurf->shellNext = cosurf->shellNext;
00042     firstCoSurf = firstCoSurf->shellNext;
00043   }
00044   else
00045   {
00046     PartitionCoSurf* prev = firstCoSurf;
00047     while( prev && prev->shellNext != cosurf )
00048       prev = prev->shellNext;
00049     
00050     if( !prev ) { assert(0); return CUBIT_FAILURE; }
00051   
00052     prev->shellNext = cosurf->shellNext;
00053   }
00054   
00055   cosurf->myShell = 0;
00056   cosurf->shellNext = 0;
00057   return CUBIT_SUCCESS;
00058 }
00059 
00060 PartitionCoSurf* PartitionShell::add( PartitionSurface* surf, CubitSense sense )
00061 {
00062   PartitionCoSurf* new_cos = new PartitionCoSurf( sense );
00063   if( !surf->add(new_cos) || !this->add(new_cos) )
00064   {
00065     delete new_cos;
00066     new_cos = 0;
00067   }
00068   return new_cos;
00069 }
00070 
00071 PartitionCoSurf* PartitionShell::find_first( const PartitionSurface* surf ) const
00072 {
00073   PartitionCoSurf* cos = firstCoSurf;
00074   while( cos && cos->get_surface() != surf )
00075     cos = cos->shellNext;
00076   return cos;
00077 }
00078 PartitionCoSurf* PartitionShell::find_next( const PartitionCoSurf* prev ) const
00079 {
00080   PartitionCoSurf* cos = prev->shellNext;
00081   while( cos && cos->get_surface() != prev->get_surface() )
00082     cos = cos->shellNext;
00083   return cos;
00084 }
00085 CubitSense PartitionShell::find_sense( const PartitionSurface* surf ) const
00086 {
00087   PartitionCoSurf* cos = find_first( surf );
00088   if( ! cos )
00089     return CUBIT_UNKNOWN;
00090   
00091   CubitSense result = cos->sense();
00092   while( (cos = find_next( cos )) )
00093     if( cos->sense() != result )
00094       return CUBIT_UNKNOWN;
00095   
00096   return result;
00097 }
00098 
00099 
00100 
00101 
00102 void PartitionShell::remove_all_surfaces( DLIList<PartitionSurface*>* list )
00103 {
00104   while( PartitionCoSurf* cosurf = firstCoSurf )
00105   {
00106     if( cosurf->get_surface() )
00107     {
00108       if( list ) 
00109         list->append( cosurf->get_surface() );
00110       cosurf->get_surface()->remove( cosurf );
00111     }
00112     remove( cosurf );
00113     delete cosurf;
00114   }
00115   
00116   if( list )
00117     list->uniquify_ordered();
00118 }
00119 
00120 void PartitionShell::get_parents_virt( DLIList<TopologyBridge*>& parents )
00121 {
00122   if( myLump )
00123     parents.append( myLump );
00124 }
00125 
00126 void PartitionShell::get_children_virt( DLIList<TopologyBridge*>& children )
00127 {
00128   PartitionCoSurf* cos = 0;
00129   while( (cos = next_co_surface( cos )) )
00130     if( cos->get_surface() )
00131       children.append_unique( cos->get_surface() );
00132 }
00133 
00134 int PartitionShell::layer() const { return get_lump()->layer(); }
00135 
00136 GeometryQueryEngine* PartitionShell::get_geometry_query_engine() const
00137 {
00138   return VirtualQueryEngine::instance();
00139 }
00140 
00141 void PartitionShell::append_simple_attribute_virt( const CubitSimpleAttrib& )
00142   { }
00143 void PartitionShell::remove_simple_attribute_virt( const CubitSimpleAttrib& )
00144   { }
00145 void PartitionShell::remove_all_simple_attribute_virt() 
00146   { }
00147 CubitStatus PartitionShell::get_simple_attribute( DLIList<CubitSimpleAttrib>& )
00148   { return CUBIT_FAILURE; }
00149 CubitStatus PartitionShell::get_simple_attribute( const CubitString&,
00150                                                  DLIList<CubitSimpleAttrib>& )
00151 { return CUBIT_FAILURE; }
00152 
00153 void PartitionShell::print_debug_info( const char* /*prefix*/ ) const
00154 {
00155 }
00156 
00157 //-------------------------------------------------------------------------
00158 // Purpose       : Determine point containment.
00159 //
00160 // Special Notes : 
00161 //
00162 // Creator       : Jason Kraftcheck
00163 //
00164 // Creation Date : 02/23/03
00165 //-------------------------------------------------------------------------
00166 CubitPointContainment PartitionShell::point_containment( const CubitVector& pt )
00167 {
00168     // Find closest cosurface to passed point
00169   PartitionCoSurf* cosurf = 0;
00170   PartitionCoSurf* closest = 0;
00171   double dist_to_closest = CUBIT_DBL_MAX;
00172   CubitVector pt_on_surface;
00173   while( (cosurf = next_co_surface(cosurf)) )
00174   {
00175     PartitionSurface* surf = cosurf->get_surface();
00176     
00177       // Ignore surfaces that occur more than once in the 
00178       // shell.
00179     bool skip = false;
00180     PartitionCoSurf* surf_cosurf = 0;
00181     while( (surf_cosurf = surf->next_co_surface(surf_cosurf)) )
00182     {
00183       if( surf_cosurf->get_shell() == this && surf_cosurf != cosurf )
00184       {
00185         skip = true;
00186         break;
00187       }
00188     }
00189     
00190     if( skip )
00191       continue;
00192     
00193     surf->closest_point_trimmed( pt, pt_on_surface );
00194     double dist_sqr = (pt - pt_on_surface).length_squared();
00195     if( dist_sqr < dist_to_closest )
00196     {
00197       closest = cosurf;
00198       dist_to_closest = dist_sqr;
00199     }
00200   }
00201   
00202   if( !closest )
00203     return CUBIT_PNT_UNKNOWN;  // already printed error messages above
00204   
00205   if( dist_to_closest < (GEOMETRY_RESABS*GEOMETRY_RESABS) ) // point is on shell
00206     return CUBIT_PNT_BOUNDARY;
00207   
00208   CubitVector normal;
00209   closest->get_surface()->closest_point_trimmed( pt, pt_on_surface );
00210   closest->get_surface()->closest_point( pt_on_surface, 0, &normal );
00211   if( closest->sense() == CUBIT_REVERSED )
00212     normal *= -1.0;
00213   
00214   pt_on_surface -= pt;
00215   if ( pt_on_surface.length_squared() < GEOMETRY_RESABS*GEOMETRY_RESABS )
00216     return CUBIT_PNT_BOUNDARY;
00217   
00218   return (normal % pt_on_surface) > 0.0 ? CUBIT_PNT_INSIDE : CUBIT_PNT_OUTSIDE;
00219 }
00220 
00221 bool PartitionShell::is_nonmanifold( PartitionSurface* surf ) const
00222 {
00223   int count = 0;
00224   PartitionCoSurf* cosurf = 0;
00225   while ((cosurf = surf->next_co_surface( cosurf )))
00226     if (cosurf->get_shell() == this)
00227       count++;
00228   
00229   return count != 1;
00230 }
00231 
00232 CubitStatus PartitionShell::mass_properties( CubitVector& centroid, 
00233                                              double& volume )
00234 {
00235   PartitionCoSurf* cosurf = 0;
00236   DLIList<CubitFacetData*> facets;
00237   CubitVector p1, p2, p3, normal;
00238   const CubitVector p0(0.0, 0.0, 0.0);
00239   centroid.set(0.0, 0.0, 0.0 );
00240   volume = 0.0;
00241   
00242   while ((cosurf = next_co_surface( cosurf )))
00243   {
00244     if (is_nonmanifold( cosurf->get_surface() ))
00245       continue;
00246     
00247     facets.clean_out();
00248     cosurf->get_surface()->get_facet_data( facets );
00249     
00250     for (int i = facets.size(); i--; )
00251     {
00252       CubitFacet* facet = facets.step_and_get();
00253       p1 = facet->point(0)->coordinates();
00254       p2 = facet->point(1)->coordinates();
00255       p3 = facet->point(2)->coordinates();
00256       normal = (p3 - p1) * (p2 - p1);
00257   
00258       double two_area = normal.length();
00259       if (two_area > CUBIT_RESABS )
00260       {
00261         if (cosurf->sense() == CUBIT_REVERSED)
00262           normal = -normal;
00263         
00264         normal /= two_area;
00265         
00266         double height = normal % (p0 - p1);
00267         double vol = two_area * height;
00268         
00269         volume += vol;
00270         centroid += vol * (p0 + p1 + p2 + p3);
00271       }
00272     }
00273   }
00274   
00275   if (volume > CUBIT_RESABS)
00276     centroid /= 4.0 * volume;
00277   volume /= 6.0;
00278   return CUBIT_SUCCESS;
00279 }
00280   
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines