cgma
|
00001 //- Class: PointGridSearch 00002 //- Description: The PointGridSearch class is used to maintain a "bucket sort" of 00003 //- all mesh points used for rapid high performance nearest 00004 //- neighbor searches. The object contains a 3-dimensional 00005 //- array of point lists for each grid cell (i.e. box) containing 00006 //- points that lie within the grid cell. appropriate calls that 00007 //- return point, edge, face, and hex lists that lie in the 00008 //- neighborhood of an input mesh entity are provided. 00009 //- Owner: Jim Hipp 00010 //- Checked by: 00011 00012 #include <math.h> 00013 #include <assert.h> 00014 00015 #include "PointGridSearch.hpp" 00016 #include "MemoryManager.hpp" 00017 #include "DLIList.hpp" 00018 #include "CastTo.hpp" 00019 #include "CubitVector.hpp" 00020 #include "CubitPoint.hpp" 00021 #include "CubitFacet.hpp" 00022 #include "CpuTimer.hpp" 00023 #include "CubitMessage.hpp" 00024 #include "CubitBox.hpp" 00025 #include "TDCellIndex.hpp" 00026 #include "GeometryDefines.h" 00027 00028 const double GRID_EXTENSION = 0.1; 00029 00030 // 00031 // Constructor / Destructor ................................................... 00032 // 00033 PointGridSearch::PointGridSearch( DLIList<CubitPoint*> *point_list, 00034 DLIList<CubitFacet*> *facet_list, 00035 float grid_scale) 00036 { 00037 // find the geometric bounding range mesh 00038 assert( point_list && point_list->size() ); 00039 bounding_range( *point_list ); 00040 00041 //find an estimate of the cell size based on the average square distance 00042 //of the edges on the surface of the geometry 00043 00044 double grid_cell_size = 1.; 00045 00046 // edge lengths 00047 double sum = 0.0; 00048 int i; 00049 maxEdgeLength = CUBIT_DBL_MIN; 00050 assert( facet_list && facet_list->size()); 00051 for ( i = 0; i < facet_list->size(); i++) 00052 { 00053 CubitPoint *p1, *p2; 00054 facet_list->next(i)->get_edge_1(p1, p2); 00055 CubitVector temp = p2->coordinates() - p1->coordinates(); 00056 double tmp_lsqrd = temp.length_squared(); 00057 sum += tmp_lsqrd; 00058 } 00059 grid_cell_size = sqrt( sum / facet_list->size() ); 00060 00061 maxEdgeLength = grid_cell_size; 00062 // evaluate grid parameters 00063 CubitVector cell(1.0, 1.0, 1.0); 00064 double grid_cell_width = grid_scale * grid_cell_size; 00065 cell *= ( GRID_EXTENSION + 5.0 ) * grid_cell_width; 00066 gridRangeMinimum = boundingRangeMinimum - cell; 00067 gridRangeMaximum = boundingRangeMaximum + cell; 00068 00069 CubitVector range_width = gridRangeMaximum - gridRangeMinimum; 00070 00071 numberGridCellsX = (int) ceil(range_width.x() / grid_cell_width + 0.5); 00072 numberGridCellsY = (int) ceil(range_width.y() / grid_cell_width + 0.5); 00073 numberGridCellsZ = (int) ceil(range_width.z() / grid_cell_width + 0.5); 00074 numberGridCells = numberGridCellsX * numberGridCellsY * numberGridCellsZ; 00075 00076 gridCellWidth.x(range_width.x() / ((double) numberGridCellsX)); 00077 gridCellWidth.y(range_width.y() / ((double) numberGridCellsY)); 00078 gridCellWidth.z(range_width.z() / ((double) numberGridCellsZ)); 00079 00080 gridCellWidthInverse.x(1.0 / gridCellWidth.x()); 00081 gridCellWidthInverse.y(1.0 / gridCellWidth.y()); 00082 gridCellWidthInverse.z(1.0 / gridCellWidth.z()); 00083 00084 // allocate neighborhood list array 00085 neighborhoodList = new DLIList<CubitPoint*>* [numberGridCells]; 00086 assert(neighborhoodList != NULL); 00087 for ( i = 0; i < numberGridCells; i++) 00088 { 00089 neighborhoodList[i] = NULL; 00090 } 00091 } 00092 PointGridSearch::PointGridSearch(DLIList <CubitPoint*> &point_list, 00093 double grid_cell_size, 00094 double grid_scale) 00095 { 00096 // find the bounding range of the reference geometry 00097 bounding_range(point_list); 00098 if ( grid_cell_size < CUBIT_RESABS ) 00099 grid_cell_size = 00100 (boundingRangeMaximum - boundingRangeMinimum).length() / 5.; 00101 00102 CubitVector cell(1.0, 1.0, 1.0); 00103 double grid_cell_width = grid_scale * grid_cell_size; 00104 cell *= grid_cell_width; 00105 gridRangeMinimum = boundingRangeMinimum - cell; 00106 gridRangeMaximum = boundingRangeMaximum + cell; 00107 00108 CubitVector range_width = gridRangeMaximum - gridRangeMinimum; 00109 00110 numberGridCellsX = (int) ceil(range_width.x() / grid_cell_width + 0.5); 00111 numberGridCellsY = (int) ceil(range_width.y() / grid_cell_width + 0.5); 00112 numberGridCellsZ = (int) ceil(range_width.z() / grid_cell_width + 0.5); 00113 numberGridCells = numberGridCellsX * numberGridCellsY * numberGridCellsZ; 00114 00115 gridCellWidth.x(range_width.x() / ((double) numberGridCellsX)); 00116 gridCellWidth.y(range_width.y() / ((double) numberGridCellsY)); 00117 gridCellWidth.z(range_width.z() / ((double) numberGridCellsZ)); 00118 00119 gridCellWidthInverse.x(1.0 / gridCellWidth.x()); 00120 gridCellWidthInverse.y(1.0 / gridCellWidth.y()); 00121 gridCellWidthInverse.z(1.0 / gridCellWidth.z()); 00122 00123 // allocate neighborhood list array 00124 00125 neighborhoodList = new DLIList<CubitPoint*>* [numberGridCells]; 00126 assert(neighborhoodList != NULL); 00127 int i; 00128 for ( i = 0; i < numberGridCells; i++) 00129 { 00130 neighborhoodList[i] = NULL; 00131 } 00132 } 00133 PointGridSearch::~PointGridSearch() 00134 { 00135 // delete each DLIList<CubitPoint*> and the array of pointers containing them 00136 00137 // first, delete the tdcellindex for each point 00138 int i; 00139 for ( i = 0; i < numberGridCells; i++) { 00140 if (!neighborhoodList[i]) continue; 00141 for (int j = neighborhoodList[i]->size(); j > 0; j--) 00142 neighborhoodList[i]->get_and_step()->delete_TD(&TDCellIndex::is_cell_index); 00143 } 00144 00145 for (i = 0; i < numberGridCells; i++) 00146 delete neighborhoodList[i]; 00147 00148 delete [] neighborhoodList; 00149 } 00150 00151 // 00152 // Private Member Functions ................................................... 00153 // 00154 00155 void PointGridSearch::cell_from_range() 00156 { 00157 // Evaluate boundingCellMin and Max from the boundingRangeMin and Max 00158 // parameters 00159 00160 CubitVector range_vec = boundingRangeMinimum - gridRangeMinimum; 00161 boundingCellMinimumX = (int) (range_vec.x() * gridCellWidthInverse.x()); 00162 boundingCellMinimumY = (int) (range_vec.y() * gridCellWidthInverse.y()); 00163 boundingCellMinimumZ = (int) (range_vec.z() * gridCellWidthInverse.z()); 00164 00165 if (boundingCellMinimumX < 0) boundingCellMinimumX = 0; 00166 if (boundingCellMinimumY < 0) boundingCellMinimumY = 0; 00167 if (boundingCellMinimumZ < 0) boundingCellMinimumZ = 0; 00168 00169 range_vec = boundingRangeMaximum - gridRangeMinimum; 00170 boundingCellMaximumX = (int) (range_vec.x() * gridCellWidthInverse.x()); 00171 boundingCellMaximumY = (int) (range_vec.y() * gridCellWidthInverse.y()); 00172 boundingCellMaximumZ = (int) (range_vec.z() * gridCellWidthInverse.z()); 00173 00174 if (boundingCellMaximumX >= numberGridCellsX) 00175 boundingCellMaximumX = numberGridCellsX - 1; 00176 if (boundingCellMaximumY >= numberGridCellsY) 00177 boundingCellMaximumY = numberGridCellsY - 1; 00178 if (boundingCellMaximumZ >= numberGridCellsZ) 00179 boundingCellMaximumZ = numberGridCellsZ - 1; 00180 } 00181 00182 void PointGridSearch::bounding_range(DLIList<CubitPoint*>& point_list) 00183 { 00184 00185 if ( !point_list.size() ) 00186 return; 00187 00188 // initialize min and max range values to the first point coordinates 00189 boundingRangeMinimum = point_list.get()->coordinates(); 00190 boundingRangeMaximum = point_list.get_and_step()->coordinates(); 00191 00192 // find the min and max coordinates that completely encloses the 00193 // point list 00194 00195 for (int i = 1; i < point_list.size(); i++) 00196 bounding_range(point_list.get_and_step()); 00197 00198 } 00199 void PointGridSearch::bounding_range(DLIList<CubitFacet*>& facet_list) 00200 { 00201 int i, j; 00202 DLIList<CubitPoint*> point_list; 00203 for ( i = 0; i < facet_list.size(); i++) 00204 { 00205 CubitFacet* facet = facet_list.get_and_step(); 00206 00207 DLIList<CubitPoint*> temp_point_list; 00208 facet->points(temp_point_list); 00209 for (j = 0; j < temp_point_list.size(); j++) 00210 { 00211 CubitPoint* point = temp_point_list.get_and_step(); 00212 00213 if (!point->marked()) 00214 { 00215 point->marked(CUBIT_TRUE); 00216 point_list.append(point); 00217 } 00218 } 00219 } 00220 // unmark the found points 00221 00222 for (i = 0; i < point_list.size(); i++) 00223 { 00224 point_list.get_and_step()->marked(CUBIT_FALSE); 00225 } 00226 if ( !point_list.size() ) 00227 return; 00228 00229 // initialize min and max range values to the first point coordinates 00230 boundingRangeMinimum = point_list.get()->coordinates(); 00231 boundingRangeMaximum = point_list.get_and_step()->coordinates(); 00232 00233 // find the min and max coordinates that completely encloses the 00234 // point list 00235 00236 for (i = 1; i < point_list.size(); i++) 00237 bounding_range(point_list.get_and_step()); 00238 00239 } 00240 00241 // 00242 // Public Member Functions .................................................... 00243 // 00244 00245 void PointGridSearch::change_cell(CubitPoint* point) 00246 { 00247 int old_cell, current_cell; 00248 // if cell index has changed then swap lists 00249 ToolData* td_temp = point->get_TD( &TDCellIndex::is_cell_index); 00250 TDCellIndex* td_index = CAST_TO(td_temp, TDCellIndex); 00251 if (td_temp == NULL) { 00252 td_index = new TDCellIndex; 00253 assert( td_index != NULL ); 00254 point->add_TD(td_index); 00255 } 00256 old_cell = td_index->cell_index(); 00257 00258 current_cell = grid_cell_index(point); 00259 if (current_cell >= 0 && current_cell < numberGridCells) 00260 { 00261 if (current_cell != old_cell) 00262 { 00263 remove_point_from_cell(point, old_cell); 00264 add_point_to_cell(point, current_cell); 00265 td_index->cell_index(current_cell); 00266 } 00267 } 00268 } 00269 00270 int PointGridSearch::in_grid(const CubitVector& position) 00271 { 00272 CubitVector range_vec; 00273 int i, j, k, index; 00274 00275 range_vec = position - gridRangeMinimum; 00276 i = (int) (range_vec.x() * gridCellWidthInverse.x()); 00277 j = (int) (range_vec.y() * gridCellWidthInverse.y()); 00278 k = (int) (range_vec.z() * gridCellWidthInverse.z()); 00279 index = numberGridCellsX * (numberGridCellsY * k + j) + i; 00280 if(index >= 0 && index < numberGridCells) 00281 { 00282 return CUBIT_TRUE; 00283 } 00284 else 00285 { 00286 return CUBIT_FALSE; 00287 } 00288 } 00289 00290 void PointGridSearch::add_point(CubitPoint* point) 00291 { 00292 // append point to the appropriate list 00293 00294 int i = grid_cell_index(point); 00295 if (i < 0 || i > numberGridCells){ 00296 return; 00297 } 00298 00299 ToolData* td_temp = point->get_TD(&TDCellIndex::is_cell_index); 00300 TDCellIndex* td_index; 00301 00302 if(td_temp == NULL){ 00303 td_index = new TDCellIndex; 00304 assert(td_index != NULL); 00305 point->add_TD(td_index); 00306 td_index->cell_index(i); 00307 add_point_to_cell(point, i); 00308 } 00309 else{ // the tool data already exists, avoid multiple listings of point 00310 td_index = CAST_TO(td_temp, TDCellIndex); 00311 assert( td_index != NULL); 00312 int iold = td_index->cell_index(); 00313 00314 if(iold != i){ 00315 remove_point_from_cell(point,iold); 00316 td_index->cell_index(i); 00317 add_point_to_cell(point, i); 00318 } 00319 else{ // iold==i, so check whether the point is already on the list 00320 if (neighborhoodList[i] && neighborhoodList[i]->move_to(point)) return; 00321 else add_point_to_cell(point, i); 00322 } 00323 } 00324 } 00325 00326 void PointGridSearch::remove_point(CubitPoint* point) 00327 { 00328 // remove point from the appropriate list 00329 int index = -1; 00330 ToolData* td_temp = point->get_TD(&TDCellIndex::is_cell_index); 00331 if (!td_temp) 00332 return; 00333 TDCellIndex* td_index = CAST_TO(td_temp, TDCellIndex); 00334 if( td_index ){ 00335 index = td_index->cell_index(); 00336 point->delete_TD( &TDCellIndex::is_cell_index ); 00337 } 00338 remove_point_from_cell(point, index); 00339 } 00340 00341 void PointGridSearch::set_neighborhood_bounds(CubitVector& vec) 00342 { 00343 // set the range and cell min and max values for the vector 00344 00345 boundingRangeMinimum = vec; 00346 boundingRangeMaximum = vec; 00347 00348 cell_from_range(); 00349 } 00350 00351 void PointGridSearch::set_neighborhood_bounds(const CubitVector& center, 00352 double size) 00353 { 00354 // set the range and cell min and max values as a cube of breadth = 00355 // 2 * size centered at center 00356 00357 CubitVector search_extent_box(size, size, size); 00358 boundingRangeMinimum = center - search_extent_box; 00359 boundingRangeMaximum = center + search_extent_box; 00360 00361 cell_from_range(); 00362 } 00363 void PointGridSearch::set_neighborhood_bounds_max_edge(const CubitVector& center, 00364 double factor) 00365 { 00366 // set the range and cell min and max values as a cube of breadth = 00367 // 2 * size centered at center 00368 00369 CubitVector search_extent_box(maxEdgeLength*factor, 00370 maxEdgeLength*factor, 00371 maxEdgeLength*factor); 00372 boundingRangeMinimum = center - search_extent_box; 00373 boundingRangeMaximum = center + search_extent_box; 00374 00375 cell_from_range(); 00376 } 00377 00378 void PointGridSearch::set_neighborhood_bounds(CubitVector& center, double x, 00379 double y, double z) 00380 { 00381 // set the range and cell min and max values as a box of size 2x, 2y, and 00382 // 2z, centered at center 00383 00384 CubitVector search_extent_box(x, y, z); 00385 boundingRangeMinimum = center - search_extent_box; 00386 boundingRangeMaximum = center + search_extent_box; 00387 00388 cell_from_range(); 00389 } 00390 00391 void PointGridSearch::set_neighborhood_bounds(CubitVector& vec_1, 00392 CubitVector& vec_2) 00393 { 00394 // initialize min and max range values to the first vectors coordinates 00395 00396 boundingRangeMinimum = vec_1; 00397 boundingRangeMaximum = vec_1; 00398 00399 // find the range and cell min and max values for the two vectors 00400 00401 bounding_range(vec_2); 00402 cell_from_range(); 00403 } 00404 00405 void PointGridSearch::set_neighborhood_bounds(CubitPoint* point, CubitVector& vec) 00406 { 00407 // initialize min and max range values to the point coordinates 00408 00409 boundingRangeMinimum = point->coordinates(); 00410 boundingRangeMaximum = point->coordinates(); 00411 00412 // find the range and cell min and max values for the point and vector 00413 00414 bounding_range(vec); 00415 cell_from_range(); 00416 } 00417 00418 void PointGridSearch::set_neighborhood_bounds(CubitPoint* point) 00419 { 00420 // initialize min and max range values to the point coordinates 00421 00422 boundingRangeMinimum = point->coordinates(); 00423 boundingRangeMaximum = point->coordinates(); 00424 00425 // find the cell min and max values 00426 00427 cell_from_range(); 00428 } 00429 00430 void PointGridSearch::set_neighborhood_bounds(CubitPoint* point_1, CubitPoint* point_2) 00431 { 00432 // initialize min and max range values to the first point coordinates 00433 00434 boundingRangeMinimum = point_1->coordinates(); 00435 boundingRangeMaximum = point_1->coordinates(); 00436 00437 // find the range and cell min and max values for the two points 00438 00439 bounding_range(point_2); 00440 cell_from_range(); 00441 } 00442 00443 void PointGridSearch::set_neighborhood_bounds(DLIList<CubitPoint*>& point_list) 00444 { 00445 // find the range and cell min and max values for the point list 00446 00447 bounding_range(point_list); 00448 cell_from_range(); 00449 } 00450 00451 void PointGridSearch::set_neighborhood_bounds(CubitFacet* facet) 00452 { 00453 // find the points belonging to the face 00454 00455 DLIList<CubitPoint*> point_list; 00456 facet->points(point_list); 00457 00458 // find the bounding range and cell min and max values for the point list 00459 00460 bounding_range(point_list); 00461 cell_from_range(); 00462 } 00463 00464 void PointGridSearch::set_neighborhood_bounds(DLIList<CubitFacet*>& facet_list) 00465 { 00466 DLIList<CubitPoint*> point_list; 00467 00468 // find all points belonging to the faces in face_list 00469 int i; 00470 for ( i = 0; i < facet_list.size(); i++) 00471 { 00472 CubitFacet* facet = facet_list.get_and_step(); 00473 00474 DLIList<CubitPoint*> temp_point_list; 00475 facet->points(temp_point_list); 00476 for (int j = 0; j < temp_point_list.size(); j++) 00477 { 00478 CubitPoint* point = temp_point_list.get_and_step(); 00479 00480 if (!point->marked()) 00481 { 00482 point->marked(CUBIT_TRUE); 00483 point_list.append(point); 00484 } 00485 } 00486 } 00487 00488 // unmark the found points 00489 00490 for (i = 0; i < point_list.size(); i++) 00491 { 00492 point_list.get_and_step()->marked(CUBIT_FALSE); 00493 } 00494 00495 // find the bounding range and cell min and max values for the point list 00496 00497 bounding_range(point_list); 00498 cell_from_range(); 00499 } 00500 00501 void PointGridSearch::get_neighborhood_points( DLIList<CubitPoint*> &point_list ) 00502 { 00503 // retrieve points over the current bounding box range 00504 00505 point_list.clean_out(); 00506 00507 for (int k = boundingCellMinimumZ; k <= boundingCellMaximumZ; k++) 00508 { 00509 int kn = numberGridCellsY * k; 00510 for (int j = boundingCellMinimumY; j <= boundingCellMaximumY; j++) 00511 { 00512 int jn = numberGridCellsX * (kn + j); 00513 for (int i = boundingCellMinimumX; i <= boundingCellMaximumX; i++) 00514 { 00515 int in = jn + i; 00516 assert( in >= 0 && in < numberGridCells ); 00517 if (neighborhoodList[in]) 00518 { 00519 point_list += *(neighborhoodList[in]); 00520 } 00521 } 00522 } 00523 } 00524 } 00525 00526 template <typename X> 00527 struct sort_by_second 00528 { 00529 bool operator()(const X & a, const X & b) 00530 { 00531 return a.second < b.second; 00532 } 00533 }; 00534 00535 void PointGridSearch::get_neighborhood_points_sorted( 00536 DLIList<CubitPoint*> &point_list, 00537 const CubitVector& center, double cut_off) 00538 { 00539 point_list.clean_out(); 00540 DLIList<CubitPoint*> temp_point_list; 00541 int i; 00542 00543 for (int k = boundingCellMinimumZ; k <= boundingCellMaximumZ; k++) 00544 { 00545 int kn = numberGridCellsY * k; 00546 for (int j = boundingCellMinimumY; j <= boundingCellMaximumY; j++) 00547 { 00548 int jn = numberGridCellsX * (kn + j); 00549 for ( i = boundingCellMinimumX; i <= boundingCellMaximumX; i++) 00550 { 00551 int in = jn + i; 00552 if (neighborhoodList[in]) 00553 { 00554 temp_point_list += *(neighborhoodList[in]); 00555 } 00556 } 00557 } 00558 } 00559 00560 // evaluate point distance to center ... remove those larger than cut_off 00561 std::vector< std::pair<int, double> > sorted_index_list; 00562 CubitVector vec; 00563 cut_off *= cut_off; 00564 temp_point_list.reset(); 00565 for ( i = 0; i < temp_point_list.size(); i++) 00566 { 00567 vec = center - temp_point_list.get_and_step()->coordinates(); 00568 double distance = vec.length_squared(); 00569 if (distance < cut_off) 00570 { 00571 sorted_index_list.push_back( std::make_pair( i, distance ) ); 00572 } 00573 } 00574 00575 std::sort(sorted_index_list.begin(), sorted_index_list.end(), sort_by_second<std::pair<int, double> >()); 00576 temp_point_list.reset(); 00577 for ( size_t j = 0; j < sorted_index_list.size(); j++ ) 00578 { 00579 int index = sorted_index_list[j].first; 00580 point_list.append( temp_point_list.next( index ) ); 00581 } 00582 } 00583 00584 void PointGridSearch::get_neighborhood_facets( DLIList<CubitFacet*> &facet_list ) 00585 { 00586 // retrieve points over the current bounding box range 00587 00588 facet_list.clean_out(); 00589 DLIList<CubitPoint*> point_list; 00590 get_neighborhood_points( point_list ); 00591 00592 // retrieve all faces attached to the points in point_list 00593 00594 for (int i = 0; i < point_list.size(); i++) 00595 { 00596 CubitPoint* point = point_list.get_and_step(); 00597 00598 DLIList<CubitFacet*> temp_facet_list; 00599 point->facets(temp_facet_list); 00600 00601 for (int j = 0; j < temp_facet_list.size(); j++) 00602 { 00603 CubitFacet* facet = temp_facet_list.get_and_step(); 00604 00605 if (!facet->marked()) 00606 { 00607 facet->marked(CUBIT_TRUE); 00608 facet_list.append(facet); 00609 } 00610 } 00611 } 00612 00613 // unmark the found faces and return face_list 00614 00615 for (int m = 0; m < facet_list.size(); m++) 00616 { 00617 facet_list.get_and_step()->marked(CUBIT_FALSE); 00618 } 00619 00620 } 00621 00622 double PointGridSearch::fraction_empty_cells() 00623 { 00624 int empty_cell = 0; 00625 00626 for (int i = 0; i < numberGridCells; i++) 00627 { 00628 if (!neighborhoodList[i]) empty_cell++; 00629 } 00630 00631 return ((double) (empty_cell) / (double) (numberGridCells)); 00632 } 00633 00634 double PointGridSearch::average_points_per_occupied_cell() 00635 { 00636 int total_points = 0; 00637 int occupied_cells = 0; 00638 00639 for (int i = 0; i < numberGridCells; i++) 00640 { 00641 if (neighborhoodList[i]) 00642 { 00643 total_points += neighborhoodList[i]->size(); 00644 occupied_cells++; 00645 } 00646 } 00647 00648 return ((double) (total_points) / (double) (occupied_cells)); 00649 } 00650 00651 int PointGridSearch::total_points_in_grid_cells() 00652 { 00653 int total_points = 0; 00654 00655 for (int i = 0; i < numberGridCells; i++) 00656 { 00657 if (neighborhoodList[i]) 00658 { 00659 total_points += neighborhoodList[i]->size(); 00660 } 00661 } 00662 00663 return total_points; 00664 } 00665 00666 00667 void PointGridSearch::add_point_to_cell(CubitPoint* point, int i) 00668 { 00669 if (neighborhoodList[i]) 00670 { 00671 neighborhoodList[i]->append(point); 00672 } 00673 else 00674 { 00675 neighborhoodList[i] = new DLIList<CubitPoint*>; 00676 neighborhoodList[i]->append(point); 00677 } 00678 } 00679 void PointGridSearch::remove_point_from_cell(CubitPoint* point, int i) 00680 { 00681 if( i < 0 ) return; 00682 if (neighborhoodList[i]) 00683 { 00684 if (neighborhoodList[i]->move_to(point)) 00685 { 00686 neighborhoodList[i]->extract(); 00687 } 00688 if (!neighborhoodList[i]->size()) 00689 { 00690 delete neighborhoodList[i]; 00691 neighborhoodList[i] = NULL; 00692 } 00693 } 00694 } 00695