cgma
|
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