cgma
CompSurfFacets.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : CompSurfFacets.cpp
00003 //
00004 // Purpose       : Encapsulate facet date used to speed up composite surfaces
00005 //
00006 // Special Notes : 
00007 //
00008 // Creator       : Jason Kraftcheck
00009 //
00010 // Creation Date : 03/20/03
00011 //-------------------------------------------------------------------------
00012 
00013 #include "CompSurfFacets.hpp"
00014 #include "Surface.hpp"
00015 #include "GeometryQueryEngine.hpp"
00016 #include "GMem.hpp"
00017 #include "OctTree.hpp"
00018 #include "GfxDebug.hpp"
00019 
00020 #include "CubitFacetData.hpp"
00021 #include "CubitFacetEdgeData.hpp"
00022 #include "CubitPointData.hpp"
00023 #include "FacetEvalTool.hpp"
00024 #include "FacetDataUtil.hpp"
00025 #include "DLIList.hpp"
00026 
00027 
00028 CompSurfFacets::CompSurfFacets()
00029 {
00030   pointsConsolidated = false;
00031   facetEvalTool = NULL;
00032 }
00033 
00034 CompSurfFacets::~CompSurfFacets()
00035 {
00036   //delete the facetEvalTool...deletes the facets also
00037   if (facetEvalTool)
00038     delete facetEvalTool;
00039   facetEvalTool = NULL;
00040   
00041   //delete the facets not in the tool
00042   FacetDataUtil::delete_facets( facetsToIgnore );
00043 }
00044 
00045 CubitStatus CompSurfFacets::setup( const SurfPtrList& surface_data )
00046 {
00047   GMem gmem;
00048   DLIList<CubitFacet*> facet_list;
00049   DLIList<CubitPoint*> point_list;
00050 
00051   ignoreFlags.resize(surface_data.size());
00052 
00053   for ( unsigned int index = 0; index < surface_data.size(); index++ )
00054   {
00055     Surface* surface = surface_data[index];
00056     ignoreFlags[index] = 0;
00057 
00058     CubitStatus result = surface->get_geometry_query_engine()
00059       ->get_graphics( surface, &gmem, 5);
00060     if ( !result )
00061       return CUBIT_FAILURE; 
00062 
00063     //make the points
00064     DLIList<CubitPoint*> tmp_points;
00065     GPoint* g_itor = gmem.point_list();
00066     GPoint* g_end = g_itor + gmem.pointListCount;
00067     for ( ; g_itor != g_end; ++g_itor )
00068     {
00069       CubitPoint *new_point_ptr =
00070            new CubitPointData(g_itor->x, g_itor->y, g_itor->z); 
00071       tmp_points.append( new_point_ptr );
00072     }
00073 
00074     //make the facets
00075     int* f_itor = gmem.facet_list();
00076     int* f_end = f_itor + gmem.fListCount;
00077     int num_facets = 0;
00078 
00079     while ( f_itor != f_end )
00080     {
00081       int count = *f_itor++;
00082       assert( count == 3 );
00083       
00084       CubitPoint *facet_points[3];
00085 
00086       for (int i=0; i<count; i++ )
00087       {
00088         int index2 = *f_itor++;
00089         facet_points[i] = tmp_points[index2];
00090       }
00091 
00092       //skip degenerate facets
00093       if( facet_points[0] == facet_points[1] ||
00094           facet_points[0] == facet_points[2] ||
00095           facet_points[1] == facet_points[2] )
00096           continue;
00097       
00098       CubitFacet *facet = (CubitFacet*) new CubitFacetData( 
00099         facet_points[0], facet_points[1], facet_points[2] );
00100 
00101       facet_list.append( facet );
00102       allFacets.append( facet );
00103 
00104       facetToSurfaceMap.insert( std::map<CubitFacet*, int>::value_type( facet, index ) ); 
00105       num_facets++;
00106     }
00107     point_list += tmp_points;
00108     numFacetsPerSurface.append( num_facets );
00109   }
00110 
00111   //create a FacetEvalTool with the points and facets
00112   facetEvalTool = new FacetEvalTool();
00113   if ( CUBIT_SUCCESS != facetEvalTool->initialize( facet_list, point_list, -1, 0.707106 ) )
00114     return CUBIT_FAILURE;
00115   
00116   pointsConsolidated = false;
00117   return CUBIT_SUCCESS;
00118 }
00119 
00120 void CompSurfFacets::set_ignore_flag(DLIList<int> &indicies, int flag)
00121 {
00122   if( indicies.size() == 0 )
00123     return;
00124 
00125   DLIList<CubitFacet*> facets_to_use;
00126   facetsToIgnore.clean_out();
00127 
00128   int where_to_start = 0;
00129   int i;
00130   int num_ignore_flags = (int)ignoreFlags.size();
00131   assert(num_ignore_flags >= 0);
00132   for( i = 0; i < num_ignore_flags; i++ )
00133   {
00134     ignoreFlags[i] = 0;
00135     
00136     //should we ignore this one?
00137     int j;
00138     if( flag == 1 )
00139     {
00140       for( j=indicies.size(); j--; )
00141       {
00142         if( indicies.get_and_step() == i )
00143           ignoreFlags[i] = 1;
00144       }
00145     }
00146 
00147     int num_facets = numFacetsPerSurface[i];
00148 
00149     //put the ignored ones in a list to prevent memory leak 
00150     for( j=where_to_start; j<where_to_start+num_facets; j++ )
00151     {
00152       if( ignoreFlags[i] == 0 )
00153         facets_to_use.append( allFacets[j] );
00154       else
00155         facetsToIgnore.append( allFacets[j] );
00156     }
00157 
00158     where_to_start += numFacetsPerSurface[i];
00159   }
00160 
00161   //give these facets to the tool
00162   facetEvalTool->replace_facets( facets_to_use ); 
00163 
00164   //now reset the bounding box on the 
00165   facetEvalTool->reset_bounding_box();
00166 
00167 }
00168 
00169 int CompSurfFacets::get_ignore_flag(int index)
00170 {
00171    return ignoreFlags[index];
00172 }
00173 
00174 int CompSurfFacets::closest_index( const CubitVector& pos,
00175                                    CubitVector* closest_pos ) const
00176 {
00177   CubitFacet *closest_facet = facetEvalTool->closest_facet( pos );
00178  
00179   std::map<CubitFacet*, int>::const_iterator my_iter;
00180   my_iter = facetToSurfaceMap.find( closest_facet );
00181   
00182   int closest_index = -1;
00183 
00184   if( my_iter != facetToSurfaceMap.end() )
00185     closest_index = my_iter->second;
00186 
00187   if( closest_pos )
00188   {
00189     CubitPoint *pt1, *pt2;
00190     closest_facet->closest_point_trimmed( pos, *closest_pos, pt1, pt2 );
00191   }
00192 
00193   return closest_index;
00194 }
00195 
00196 int CompSurfFacets::closest_index( const CubitVector& pos,
00197                                    DLIList<int>& index_list,
00198                                    CubitVector* closest_pos ) 
00199 {
00200   //facets must be consolidated before calling this function
00201   //if not, you won't know if a position is on multiple
00202   //surfaces (on seam between 2 surfaces)
00203   if (!pointsConsolidated)
00204   {
00205     consolidate_points(GEOMETRY_RESABS);
00206     pointsConsolidated = true;
00207   }
00208 
00209   CubitFacet *closest_facet = facetEvalTool->closest_facet( pos );
00210   
00211   std::map<CubitFacet*, int>::const_iterator iter;
00212   iter = facetToSurfaceMap.find( closest_facet );
00213   
00214   int closest_index = -1;
00215 
00216   if( iter != facetToSurfaceMap.end() )
00217     closest_index = iter->second;
00218 
00219   index_list.append( closest_index );
00220 
00221   CubitVector tmp_closest_pos;
00222   CubitPoint *pt1, *pt2;
00223   closest_facet->closest_point_trimmed( pos, tmp_closest_pos, pt1, pt2 );
00224 
00225   if( closest_pos )
00226     *closest_pos = tmp_closest_pos;
00227  
00228   double tol_sq = GEOMETRY_RESABS*GEOMETRY_RESABS;
00229   double dist_sq = pos.distance_between_squared( tmp_closest_pos );  
00230   
00231   //if the closest distance is less than resabs, there could be more facets 
00232   //less then resabs away too....find them
00233   if( dist_sq < tol_sq )
00234   {
00235     //examine neighboring facets
00236     CubitPoint *point0, *point1, *point2;
00237     closest_facet->points( point0, point1, point2 ); 
00238    
00239     DLIList<CubitFacet*> neighbor_facets;
00240     point0->tris( neighbor_facets );
00241     point1->tris( neighbor_facets );
00242     point2->tris( neighbor_facets );
00243 
00244     neighbor_facets.uniquify_unordered();
00245     
00246     int k;
00247     for( k=neighbor_facets.size(); k--; )
00248     {
00249       CubitFacet *tmp_facet = neighbor_facets.get_and_step();
00250       tmp_facet->closest_point_trimmed( pos, tmp_closest_pos, pt1, pt2 );
00251      
00252       dist_sq = pos.distance_between_squared( tmp_closest_pos );  
00253       if( dist_sq < tol_sq )
00254       {
00255         iter = facetToSurfaceMap.find( tmp_facet );
00256         if( iter != facetToSurfaceMap.end() )
00257           index_list.append( iter->second );
00258       }
00259     }
00260   }
00261 
00262   index_list.uniquify_unordered();
00263   
00264   return index_list.size();
00265 }
00266 
00267 void CompSurfFacets::debug_draw_facets() const
00268 {
00269   int i;
00270   for( i=0; i<allFacets.size(); i++ )
00271     allFacets[i]->debug_draw( 4 );
00272 
00273   GfxDebug::flush();
00274 }
00275 
00276 void CompSurfFacets::consolidate_points( double tolerance )
00277 {
00278   DLIList<CubitFacet*> facet_list;
00279   facetEvalTool->get_facets( facet_list );
00280 
00281   //group the points by surface
00282   DLIList< DLIList<CubitFacet*>* > list_of_lists;
00283   int i;
00284   numFacetsPerSurface.reset();
00285   int index_into_facet_array = 0;
00286   for( i=0; i<numFacetsPerSurface.size(); i++ )
00287   {
00288     int num_facets = numFacetsPerSurface.get_and_step();
00289 
00290     if( ignoreFlags[i] == 0 )
00291     {
00292       DLIList<CubitFacet*>* tmp_facet_list = new DLIList<CubitFacet*>;
00293       int k;
00294       for(k=0; k<num_facets; k++ )
00295         tmp_facet_list->append( allFacets[index_into_facet_array+k] ); 
00296       list_of_lists.append( tmp_facet_list );
00297     }
00298     index_into_facet_array += num_facets;
00299   }
00300   
00301   int num_points_merged, num_edges_merged;
00302   DLIList<CubitPoint*> unmerged_points;
00303   FacetDataUtil::merge_coincident_vertices( list_of_lists, tolerance,
00304                                             num_points_merged, num_edges_merged,
00305                                             unmerged_points );
00306 
00307   //replace facets so points list get updates
00308   facetEvalTool->replace_facets( facet_list );
00309 
00310   //clean up
00311   for( i=list_of_lists.size(); i--; )
00312     delete list_of_lists.get_and_step();
00313 
00314   pointsConsolidated = true;
00315 }
00316 
00317 class CubitVectOctTreeEval {
00318 public:
00319 static inline const CubitVector& coordinates(CubitVector* p)
00320   { return *p; };
00321 };
00322 
00323 void CompSurfFacets::graphics( double tolerance, GMem& gmem )
00324 {
00325   if (!pointsConsolidated)
00326   {
00327     consolidate_points(tolerance);
00328     pointsConsolidated = true;
00329   }
00330   
00331   DLIList<CubitPoint*> point_list;
00332   DLIList<CubitFacet*> facet_list;
00333   facetEvalTool->get_points( point_list );
00334   facetEvalTool->get_facets( facet_list );
00335   point_list.reset();
00336   facet_list.reset();
00337 
00338   //mark all the points to -1
00339   int i;
00340   for( i=point_list.size(); i--; )
00341     point_list.get_and_step()->marked(-1);
00342 
00343   gmem.allocate_tri( facet_list.size() );
00344  
00345   int* f_itor = gmem.facet_list();
00346   DLIList<CubitPoint*> tmp_points;  
00347   int index = 0;
00348 
00349   for( i=facet_list.size(); i--; )
00350   {
00351     CubitFacet *tmp_facet = facet_list.get_and_step();
00352     CubitPoint *p0, *p1, *p2;
00353     tmp_facet->points(p0, p1, p2 );
00354 
00355     *(f_itor++) = 3;
00356 
00357     if( p0->marked() == -1 )
00358     {
00359       tmp_points.append( p0 ); 
00360       p0->marked( index ); 
00361       index++;
00362     }
00363     *(f_itor++) = p0->marked();
00364 
00365     if( p1->marked() == -1 )
00366     {
00367       tmp_points.append( p1 ); 
00368       p1->marked( index ); 
00369       index++;
00370     }
00371     *(f_itor++) = p1->marked();
00372 
00373     if( p2->marked() == -1 )
00374     {
00375       tmp_points.append( p2 ); 
00376       p2->marked( index ); 
00377       index++;
00378     }
00379     *(f_itor++) = p2->marked();
00380   }
00381 
00382 
00383   GPoint* g_itor = gmem.point_list();
00384   for( i=tmp_points.size(); i--; )
00385   {
00386     CubitPoint *tmp_point = tmp_points.get_and_step();
00387     g_itor->x = (float)tmp_point->x();
00388     g_itor->y = (float)tmp_point->y();
00389     g_itor->z = (float)tmp_point->z();
00390     g_itor++;
00391   }
00392   
00393   gmem.fListCount = (facet_list.size() * 4);
00394   gmem.pointListCount = tmp_points.size();
00395 }
00396 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines