$search
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2011, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Willow Garage, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 */ 00034 00038 #ifndef COLLISION_CHECKING_COLLISION_PRIMITIVE_H 00039 #define COLLISION_CHECKING_COLLISION_PRIMITIVE_H 00040 00041 #include "collision_checking/BVH_defs.h" 00042 #include "collision_checking/intersect.h" 00043 #include "collision_checking/BVH_model.h" 00044 #include "collision_checking/BVH_front.h" 00045 00047 namespace collision_checking 00048 { 00049 00051 struct BVHCollisionPair 00052 { 00054 int id1; 00055 00057 int id2; 00058 00060 BVH_REAL collide_time; 00061 00063 Vec3f normal; 00064 00066 Vec3f contact_point; 00067 00069 BVH_REAL penetration_depth; 00070 }; 00071 00073 struct BVH_CollideResult 00074 { 00076 int num_bv_tests; 00077 00079 int num_tri_tests; 00080 00082 int num_vf_tests; 00083 00085 int num_ee_tests; 00086 00088 BVH_REAL query_time_seconds; 00089 00094 int num_max_contacts; 00095 00096 BVH_CollideResult(); 00097 00098 ~BVH_CollideResult(); 00099 00101 void add(int id1, int id2, BVH_REAL time = 0); 00102 00103 void add(int id1, int id2, Vec3f contact_point, BVH_REAL penetration_depth, const Vec3f& normal, BVH_REAL time = 0); 00104 00106 int colliding() { return (num_pairs > 0); } 00107 00109 void resetRecord() 00110 { 00111 num_pairs = 0; 00112 num_bv_tests = 0; 00113 num_tri_tests = 0; 00114 num_vf_tests = 0; 00115 num_ee_tests = 0; 00116 } 00117 00119 int numPairs() const 00120 { 00121 return num_pairs; 00122 } 00123 00125 int id1(int i) const 00126 { 00127 return pairs[i].id1; 00128 } 00129 00131 int id2(int i) const 00132 { 00133 return pairs[i].id2; 00134 } 00135 00137 BVHCollisionPair* collidePairs() 00138 { 00139 return pairs; 00140 } 00141 00142 private: 00143 int num_pairs_allocated; 00144 int num_pairs; 00145 BVHCollisionPair* pairs; 00146 00147 void sizeTo(int n); 00148 }; 00149 00150 00152 template<typename BV> 00153 void collideRecurse(BVNode<BV>* tree1, BVNode<BV>* tree2, int b1, int b2, 00154 Vec3f* vertices1, Vec3f* vertices2, 00155 Triangle* tri_indices1, Triangle* tri_indices2, 00156 BVH_CollideResult* res, BVHFrontList* front_list = NULL) 00157 { 00158 BVNode<BV>* node1 = tree1 + b1; 00159 BVNode<BV>* node2 = tree2 + b2; 00160 00161 bool l1 = node1->isLeaf(); 00162 bool l2 = node2->isLeaf(); 00163 00164 if(l1 && l2) 00165 { 00166 if(front_list) front_list->push_back(BVHFrontNode(b1, b2)); 00167 00168 res->num_bv_tests++; 00169 if(!node1->overlap(*node2)) return; 00170 00171 res->num_tri_tests++; 00172 00173 const Triangle& tri_id1 = tri_indices1[-node1->first_child - 1]; 00174 const Triangle& tri_id2 = tri_indices2[-node2->first_child - 1]; 00175 00176 const Vec3f& p1 = vertices1[tri_id1[0]]; 00177 const Vec3f& p2 = vertices1[tri_id1[1]]; 00178 const Vec3f& p3 = vertices1[tri_id1[2]]; 00179 const Vec3f& q1 = vertices2[tri_id2[0]]; 00180 const Vec3f& q2 = vertices2[tri_id2[1]]; 00181 const Vec3f& q3 = vertices2[tri_id2[2]]; 00182 00183 BVH_REAL penetration; 00184 Vec3f normal; 00185 int n_contacts; 00186 Vec3f contacts[2]; 00187 00188 00189 if(res->num_max_contacts == 0) // only interested in collision or not 00190 { 00191 if(Intersect::intersect_Triangle(p1, p2, p3, q1, q2, q3)) 00192 { 00193 res->add(-node1->first_child - 1, -node2->first_child - 1); 00194 } 00195 } 00196 else // need compute the contact information 00197 { 00198 if(Intersect::intersect_Triangle(p1, p2, p3, q1, q2, q3, 00199 contacts, 00200 (unsigned int*)&n_contacts, 00201 &penetration, 00202 &normal)) 00203 { 00204 for(int i = 0; i < n_contacts; ++i) 00205 { 00206 if(res->num_max_contacts <= res->numPairs()) break; 00207 res->add(-node1->first_child - 1, -node2->first_child - 1, contacts[i], penetration, normal); 00208 } 00209 } 00210 00211 } 00212 00213 return; 00214 } 00215 00216 res->num_bv_tests++; 00217 if(!node1->overlap(*node2)) 00218 { 00219 if(front_list) front_list->push_back(BVHFrontNode(b1, b2)); 00220 return; 00221 } 00222 00223 BVH_REAL sz1 = node1->bv.size(); 00224 BVH_REAL sz2 = node2->bv.size(); 00225 00226 if(l2 || (!l1 && (sz1 > sz2))) 00227 { 00228 int c1 = node1->first_child; 00229 int c2 = c1 + 1; 00230 00231 collideRecurse(tree1, tree2, c1, b2, vertices1, vertices2, tri_indices1, tri_indices2, res, front_list); 00232 00233 if(res->numPairs() > 0 && ((res->num_max_contacts == 0) || (res->num_max_contacts <= res->numPairs()))) return; 00234 00235 collideRecurse(tree1, tree2, c2, b2, vertices1, vertices2, tri_indices1, tri_indices2, res, front_list); 00236 } 00237 else 00238 { 00239 int c1 = node2->first_child; 00240 int c2 = c1 + 1; 00241 00242 collideRecurse(tree1, tree2, b1, c1, vertices1, vertices2, tri_indices1, tri_indices2, res, front_list); 00243 00244 if(res->numPairs() > 0 && ((res->num_max_contacts == 0) || (res->num_max_contacts <= res->numPairs()))) return; 00245 00246 collideRecurse(tree1, tree2, b1, c2, vertices1, vertices2, tri_indices1, tri_indices2, res, front_list); 00247 } 00248 } 00249 00251 void collideRecurse(BVNode<OBB>* tree1, BVNode<OBB>* tree2, 00252 const Vec3f R[3], const Vec3f& T, 00253 int b1, int b2, 00254 Vec3f* vertices1, Vec3f* vertices2, 00255 Triangle* tri_indices1, Triangle* tri_indices2, 00256 BVH_CollideResult* res, BVHFrontList* front_list = NULL); 00257 00259 void collideRecurse(BVNode<RSS>* tree1, BVNode<RSS>* tree2, 00260 const Vec3f R[3], const Vec3f& T, 00261 int b1, int b2, 00262 Vec3f* vertices1, Vec3f* vertices2, 00263 Triangle* tri_indices1, Triangle* tri_indices2, 00264 BVH_CollideResult* res, BVHFrontList* front_list = NULL); 00265 00267 template<typename BV> 00268 void selfCollideRecurse(BVNode<BV>* tree, int b, 00269 Vec3f* vertices, Triangle* tri_indices, 00270 BVH_CollideResult* res, BVHFrontList* front_list = NULL) 00271 { 00272 BVNode<BV>* node = tree + b; 00273 bool l = node->isLeaf(); 00274 00275 if(l) return; 00276 00277 int c1 = node->first_child; 00278 int c2 = c1 + 1; 00279 00280 selfCollideRecurse(tree, c1, vertices, tri_indices, res, front_list); 00281 selfCollideRecurse(tree, c2, vertices, tri_indices, res, front_list); 00282 collideRecurse<BV>(tree, tree, c1, c2, vertices, vertices, tri_indices, tri_indices, res, front_list); 00283 } 00284 00286 template<typename BV> 00287 void continuousCollideRecurse(BVNode<BV>* tree1, BVNode<BV>* tree2, int b1, int b2, 00288 Vec3f* vertices1, Vec3f* vertices2, 00289 Vec3f* prev_vertices1, Vec3f* prev_vertices2, 00290 Triangle* tri_indices1, Triangle* tri_indices2, 00291 BVH_CollideResult* res, BVHFrontList* front_list = NULL) 00292 { 00293 BVNode<BV>* node1 = tree1 + b1; 00294 BVNode<BV>* node2 = tree2 + b2; 00295 00296 bool l1 = node1->isLeaf(); 00297 bool l2 = node2->isLeaf(); 00298 00299 if(l1 && l2) 00300 { 00301 if(front_list) front_list->push_back(BVHFrontNode(b1, b2)); 00302 00303 res->num_bv_tests++; 00304 if(!node1->overlap(*node2)) return; 00305 00306 00307 BVH_REAL collide_time = 2; 00308 Vec3f collide_pos; 00309 00310 if(tri_indices1 && tri_indices2) // both are triangle mesh 00311 { 00312 const Triangle& tri_id1 = tri_indices1[-node1->first_child - 1]; 00313 const Triangle& tri_id2 = tri_indices2[-node2->first_child - 1]; 00314 00315 Vec3f S0[3]; 00316 Vec3f S1[3]; 00317 Vec3f T0[3]; 00318 Vec3f T1[3]; 00319 00320 00321 for(int i = 0; i < 3; ++i) 00322 { 00323 S0[i] = prev_vertices1[tri_id1[i]]; 00324 S1[i] = vertices1[tri_id1[i]]; 00325 T0[i] = prev_vertices2[tri_id2[i]]; 00326 T1[i] = vertices2[tri_id2[i]]; 00327 } 00328 00329 BVH_REAL tmp; 00330 Vec3f tmpv; 00331 00332 // 6 VF checks 00333 for(int i = 0; i < 3; ++i) 00334 { 00335 res->num_vf_tests++; 00336 if(Intersect::intersect_VF(S0[0], S0[1], S0[2], T0[i], S1[0], S1[1], S1[2], T1[i], &tmp, &tmpv)) 00337 { 00338 if(collide_time > tmp) 00339 { 00340 collide_time = tmp; collide_pos = tmpv; 00341 } 00342 } 00343 00344 res->num_vf_tests++; 00345 if(Intersect::intersect_VF(T0[0], T0[1], T0[2], S0[i], T1[0], T1[1], T1[2], S1[i], &tmp, &tmpv)) 00346 { 00347 if(collide_time > tmp) 00348 { 00349 collide_time = tmp; collide_pos = tmpv; 00350 } 00351 } 00352 } 00353 00354 // 9 EE checks 00355 for(int i = 0; i < 3; ++i) 00356 { 00357 int S_id1 = i; 00358 int S_id2 = i + 1; 00359 if(S_id2 == 3) S_id2 = 0; 00360 for(int j = 0; j < 3; ++j) 00361 { 00362 int T_id1 = j; 00363 int T_id2 = j + 1; 00364 if(T_id2 == 3) T_id2 = 0; 00365 00366 res->num_ee_tests++; 00367 if(Intersect::intersect_EE(S0[S_id1], S0[S_id2], T0[T_id1], T0[T_id2], S1[S_id1], S1[S_id2], T1[T_id1], T1[T_id2], &tmp, &tmpv)) 00368 { 00369 if(collide_time > tmp) 00370 { 00371 collide_time = tmp; collide_pos = tmpv; 00372 } 00373 } 00374 } 00375 } 00376 00377 00378 } 00379 else if(tri_indices1) // the first is triangle mesh 00380 { 00381 BVH_REAL collide_time = 2; 00382 Vec3f collide_pos; 00383 00384 const Triangle& tri_id1 = tri_indices1[-node1->first_child - 1]; 00385 int vertex_id2 = -node2->first_child - 1; 00386 00387 Vec3f S0[3]; 00388 Vec3f S1[3]; 00389 00390 for(int i = 0; i < 3; ++i) 00391 { 00392 S0[i] = prev_vertices1[tri_id1[i]]; 00393 S1[i] = vertices1[tri_id1[i]]; 00394 } 00395 Vec3f& T0 = prev_vertices2[vertex_id2]; 00396 Vec3f& T1 = vertices2[vertex_id2]; 00397 00398 BVH_REAL tmp; 00399 Vec3f tmpv; 00400 00401 // 3 VF checks 00402 for(int i = 0; i < 3; ++i) 00403 { 00404 res->num_vf_tests++; 00405 if(Intersect::intersect_VF(S0[0], S0[1], S0[2], T0, S1[0], S1[1], S1[2], T1, &tmp, &tmpv)) 00406 { 00407 if(collide_time > tmp) 00408 { 00409 collide_time = tmp; collide_pos = tmpv; 00410 } 00411 } 00412 } 00413 00414 00415 } 00416 else if(tri_indices2) // the second is triangle mesh 00417 { 00418 BVH_REAL collide_time = 2; 00419 Vec3f collide_pos; 00420 00421 int vertex_id1 = -node1->first_child - 1; 00422 const Triangle& tri_id2 = tri_indices2[-node2->first_child - 1]; 00423 00424 Vec3f& S0 = prev_vertices1[vertex_id1]; 00425 Vec3f& S1 = vertices1[vertex_id1]; 00426 00427 Vec3f T0[3]; 00428 Vec3f T1[3]; 00429 for(int i = 0; i < 3; ++i) 00430 { 00431 T0[i] = prev_vertices2[tri_id2[i]]; 00432 T1[i] = vertices2[tri_id2[i]]; 00433 } 00434 00435 BVH_REAL tmp; 00436 Vec3f tmpv; 00437 00438 // 3 VF checks 00439 for(int i = 0; i < 3; ++i) 00440 { 00441 res->num_vf_tests++; 00442 if(Intersect::intersect_VF(T0[0], T0[1], T0[2], S0, T1[0], T1[1], T1[2], S1, &tmp, &tmpv)) 00443 { 00444 if(collide_time > tmp) 00445 { 00446 collide_time = tmp; collide_pos = tmpv; 00447 } 00448 } 00449 } 00450 00451 00452 } 00453 else // both are point clouds 00454 { 00455 // can not handle now! 00456 } 00457 00458 if(!(collide_time > 1)) // collision happens 00459 { 00460 res->add(-node1->first_child - 1, -node2->first_child - 1, collide_time); 00461 } 00462 00463 return; 00464 } 00465 00466 res->num_bv_tests++; 00467 if(!node1->overlap(*node2)) 00468 { 00469 if(front_list) front_list->push_back(BVHFrontNode(b1, b2)); 00470 return; 00471 } 00472 00473 BVH_REAL sz1 = node1->bv.size(); 00474 BVH_REAL sz2 = node2->bv.size(); 00475 00476 if(l2 || (!l1 && (sz1 > sz2))) 00477 { 00478 int c1 = node1->first_child; 00479 int c2 = c1 + 1; 00480 00481 continuousCollideRecurse(tree1, tree2, c1, b2, vertices1, vertices2, prev_vertices1, prev_vertices2, tri_indices1, tri_indices2, res, front_list); 00482 00483 continuousCollideRecurse(tree1, tree2, c2, b2, vertices1, vertices2, prev_vertices1, prev_vertices2, tri_indices1, tri_indices2, res, front_list); 00484 } 00485 else 00486 { 00487 int c1 = node2->first_child; 00488 int c2 = c1 + 1; 00489 00490 continuousCollideRecurse(tree1, tree2, b1, c1, vertices1, vertices2, prev_vertices1, prev_vertices2, tri_indices1, tri_indices2, res, front_list); 00491 00492 continuousCollideRecurse(tree1, tree2, b1, c2, vertices1, vertices2, prev_vertices1, prev_vertices2, tri_indices1, tri_indices2, res, front_list); 00493 } 00494 } 00495 00497 template<typename BV> 00498 void continuousSelfCollideRecurse(BVNode<BV>* tree, int b, 00499 Vec3f* vertices, Vec3f* prev_vertices, 00500 Triangle* tri_indices, 00501 BVH_CollideResult* res, BVHFrontList* front_list = NULL) 00502 { 00503 BVNode<BV>* node = tree + b; 00504 bool l = node->isLeaf(); 00505 00506 if(l) return; 00507 00508 int c1 = node->first_child; 00509 int c2 = c1 + 1; 00510 00511 continuousSelfCollideRecurse(tree, c1, vertices, prev_vertices, tri_indices, res, front_list); 00512 continuousSelfCollideRecurse(tree, c2, vertices, prev_vertices, tri_indices, res, front_list); 00513 continuousCollideRecurse<BV>(tree, tree, c1, c2, vertices, vertices, prev_vertices, prev_vertices, tri_indices, tri_indices, res, front_list); 00514 } 00515 00516 00518 template<typename BV> 00519 void propagateBVHFrontList(BVNode<BV>* tree1, BVNode<BV>* tree2, 00520 Vec3f* vertices1, Vec3f* vertices2, 00521 Triangle* tri_indices1, Triangle* tri_indices2, 00522 BVH_CollideResult* res, 00523 BVHFrontList* front_list) 00524 { 00525 BVHFrontList::iterator front_iter; 00526 BVHFrontList append; 00527 for(front_iter = front_list->begin(); front_iter != front_list->end(); ++front_iter) 00528 { 00529 int b1 = front_iter->left; 00530 int b2 = front_iter->right; 00531 BVNode<BV>* node1 = tree1 + b1; 00532 BVNode<BV>* node2 = tree2 + b2; 00533 00534 00535 bool l1 = node1->isLeaf(); 00536 bool l2 = node2->isLeaf(); 00537 00538 if(l1 & l2) 00539 { 00540 front_iter->valid = false; // the front node is no longer valid, in collideRecurse will add again. 00541 collideRecurse(tree1, tree2, b1, b2, vertices1, vertices2, tri_indices1, tri_indices2, res, &append); 00542 } 00543 else 00544 { 00545 res->num_bv_tests++; 00546 if(node1->overlap(*node2)) 00547 { 00548 front_iter->valid = false; // the front node is no longer valid 00549 00550 BVH_REAL sz1 = node1->bv.size(); 00551 BVH_REAL sz2 = node2->bv.size(); 00552 00553 if(l2 || (!l1 && (sz1 > sz2))) 00554 { 00555 int c1 = node1->first_child; 00556 int c2 = c1 + 1; 00557 00558 collideRecurse(tree1, tree2, c1, b2, vertices1, vertices2, tri_indices1, tri_indices2, res, &append); 00559 00560 collideRecurse(tree1, tree2, c2, b2, vertices1, vertices2, tri_indices1, tri_indices2, res, &append); 00561 } 00562 else 00563 { 00564 int c1 = node2->first_child; 00565 int c2 = c1 + 1; 00566 00567 collideRecurse(tree1, tree2, b1, c1, vertices1, vertices2, tri_indices1, tri_indices2, res, &append); 00568 00569 collideRecurse(tree1, tree2, b1, c2, vertices1, vertices2, tri_indices1, tri_indices2, res, &append); 00570 } 00571 } 00572 } 00573 } 00574 00575 00576 // clean the old front list (remove invalid node) 00577 for(front_iter = front_list->begin(); front_iter != front_list->end();) 00578 { 00579 if(!front_iter->valid) 00580 front_iter = front_list->erase(front_iter); 00581 else 00582 ++front_iter; 00583 } 00584 00585 for(front_iter = append.begin(); front_iter != append.end(); ++front_iter) 00586 { 00587 front_list->push_back(*front_iter); 00588 } 00589 } 00590 00592 void propagateBVHFrontList(BVNode<OBB>* tree1, BVNode<OBB>* tree2, 00593 Vec3f R[3], const Vec3f& T, 00594 Vec3f* vertices1, Vec3f* vertices2, 00595 Triangle* tri_indices1, Triangle* tri_indices2, 00596 BVH_CollideResult* res, 00597 BVHFrontList* front_list); 00598 00600 void propagateBVHFrontList(BVNode<RSS>* tree1, BVNode<RSS>* tree2, 00601 Vec3f R[3], const Vec3f& T, 00602 Vec3f* vertices1, Vec3f* vertices2, 00603 Triangle* tri_indices1, Triangle* tri_indices2, 00604 BVH_CollideResult* res, 00605 BVHFrontList* front_list); 00606 00608 template<typename BV> 00609 void continuousPropagateBVHFrontList(BVNode<BV>* tree1, BVNode<BV>* tree2, 00610 Vec3f* vertices1, Vec3f* vertices2, 00611 Vec3f* prev_vertices1, Vec3f* prev_vertices2, 00612 Triangle* tri_indices1, Triangle* tri_indices2, 00613 BVH_CollideResult* res, 00614 BVHFrontList* front_list) 00615 { 00616 BVHFrontList::iterator front_iter; 00617 BVHFrontList append; 00618 for(front_iter = front_list->begin(); front_iter != front_list->end(); ++front_iter) 00619 { 00620 int b1 = front_iter->left; 00621 int b2 = front_iter->right; 00622 BVNode<BV>* node1 = tree1 + b1; 00623 BVNode<BV>* node2 = tree2 + b2; 00624 00625 00626 bool l1 = node1->isLeaf(); 00627 bool l2 = node2->isLeaf(); 00628 00629 if(l1 & l2) 00630 { 00631 front_iter->valid = false; // the front node is no longer valid, in collideRecurse will add again. 00632 continuousCollideRecurse(tree1, tree2, b1, b2, vertices1, vertices2, prev_vertices1, prev_vertices2, tri_indices1, tri_indices2, res, &append); 00633 } 00634 else 00635 { 00636 res->num_bv_tests++; 00637 if(node1->overlap(*node2)) 00638 { 00639 front_iter->valid = false; // the front node is no longer valid 00640 00641 BVH_REAL sz1 = node1->bv.size(); 00642 BVH_REAL sz2 = node2->bv.size(); 00643 00644 if(l2 || (!l1 && (sz1 > sz2))) 00645 { 00646 int c1 = node1->first_child; 00647 int c2 = c1 + 1; 00648 00649 continuousCollideRecurse(tree1, tree2, c1, b2, vertices1, vertices2, prev_vertices1, prev_vertices2, tri_indices1, tri_indices2, res, &append); 00650 00651 continuousCollideRecurse(tree1, tree2, c2, b2, vertices1, vertices2, prev_vertices1, prev_vertices2, tri_indices1, tri_indices2, res, &append); 00652 } 00653 else 00654 { 00655 int c1 = node2->first_child; 00656 int c2 = c1 + 1; 00657 00658 continuousCollideRecurse(tree1, tree2, b1, c1, vertices1, vertices2, prev_vertices1, prev_vertices2, tri_indices1, tri_indices2, res, &append); 00659 00660 continuousCollideRecurse(tree1, tree2, b1, c2, vertices1, vertices2, prev_vertices1, prev_vertices2, tri_indices1, tri_indices2, res, &append); 00661 } 00662 } 00663 } 00664 } 00665 00666 00667 // clean the old front list (remove invalid node) 00668 for(front_iter = front_list->begin(); front_iter != front_list->end();) 00669 { 00670 if(!front_iter->valid) 00671 front_iter = front_list->erase(front_iter); 00672 else 00673 ++front_iter; 00674 } 00675 00676 for(front_iter = append.begin(); front_iter != append.end(); ++front_iter) 00677 { 00678 front_list->push_back(*front_iter); 00679 } 00680 } 00681 00682 } 00683 00684 #endif