00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00033 #ifndef _CONSTRAINED_DELAUNAY_TRIANGULATION_UTILS_CPP_
00034 #define _CONSTRAINED_DELAUNAY_TRIANGULATION_UTILS_CPP_
00035
00036 #include "constrained_delaunay_triangulation.h"
00037
00038
00047 bool class_constrained_delaunay_triangulation::equal(Point_2 p1, Point_2 p2)
00048 {
00049 if (p1.x()==p2.x() && p1.y()==p2.y())
00050 return true;
00051 else
00052 return false;
00053 }
00054
00063 bool class_constrained_delaunay_triangulation::equal_e(CGAL::Point_2<K_exact> p1, CGAL::Point_2<K_exact> p2)
00064 {
00065 if (CGAL::to_double(p1.x())==CGAL::to_double(p2.x()) && CGAL::to_double(p1.y())==CGAL::to_double(p2.y()))
00066 {
00067 return true;
00068 }
00069 else
00070 {
00071 return false;
00072 }
00073 }
00074
00080 int class_constrained_delaunay_triangulation::test_if_triangulation_is_valid(void)
00081 {
00082 if(debug)
00083 {
00084 ROS_INFO("Checking if triangulation is valid ...");
00085 bool ret = dt.is_valid(true, 1);
00086 if (ret==true)
00087 ROS_INFO("Finished Checking: triangulation is valid");
00088 else
00089 ROS_ERROR("Finished Checking: triangulation is not valid");
00090 }
00091 return 1;
00092 }
00093
00104 bool class_constrained_delaunay_triangulation::overlaps(Point_2* v0, Point_2* v1, Point_2* v2, Point_2* p)
00105 {
00106 CDT triang;
00107 triang.insert(*v0);
00108 triang.insert(*v1);
00109 triang.insert(*v2);
00110
00111 CDT::Locate_type lt;
00112 int li;
00113 triang.locate(*p, lt, li);
00114
00115 if (lt==CDT::FACE || lt==CDT::EDGE)
00116 return true;
00117 else
00118 return false;
00119 }
00120
00129 bool class_constrained_delaunay_triangulation::segments_intersect_not_at_endpoints(CGAL::Segment_2<K_exact> iseg1, CGAL::Segment_2<K_exact> iseg2)
00130 {
00131
00132
00133 if ((equal(iseg1.point(0), iseg2.point(0)) && equal(iseg1.point(1), iseg2.point(1))) ||
00134 (equal(iseg1.point(1), iseg2.point(0)) && equal(iseg1.point(0), iseg2.point(1)))
00135 )
00136 {
00137 if(debug>1) ROS_INFO("SEG_INTR: segments are the same");
00138 return false;
00139 }
00140 else
00141 {
00142
00143 CGAL::Point_2<K_exact> seg1_p0(iseg1.point(0).x(), iseg1.point(0).y());
00144 CGAL::Point_2<K_exact> seg1_p1(iseg1.point(1).x(), iseg1.point(1).y());
00145 CGAL::Segment_2<K_exact> seg1(seg1_p0, seg1_p1);
00146
00147 CGAL::Point_2<K_exact> seg2_p0(iseg2.point(0).x(), iseg2.point(0).y());
00148 CGAL::Point_2<K_exact> seg2_p1(iseg2.point(1).x(), iseg2.point(1).y());
00149 CGAL::Segment_2<K_exact> seg2(seg2_p0, seg2_p1);
00150
00151
00152 CGAL::Object result = CGAL::intersection(seg1, seg2);
00153 if (const CGAL::Point_2<K_exact> *ip = CGAL::object_cast<CGAL::Point_2<K_exact> >(&result))
00154 {
00155 if (equal_e(seg1.point(0), seg2.point(0)) || equal_e(seg1.point(0), seg2.point(1)) || equal_e(seg1.point(1), seg2.point(1)) || equal_e(seg1.point(1), seg2.point(0)))
00156
00157 {
00158 return false;
00159
00160
00161
00162
00163 }
00164 else
00165 {
00166 if(debug>1)ROS_INFO("SEG_INTR: point intersection and not at endpoints ip (%f, %f) seg1 p0 (%f %f) p1 (%f %f) seg2 p0(%f %f) p1(%f %f)", CGAL::to_double(ip->x()),CGAL::to_double( ip->y()),CGAL::to_double( seg1.point(0).x()),CGAL::to_double( seg1.point(0).y()),CGAL::to_double( seg1.point(1).x()), CGAL::to_double(seg1.point(1).y()), CGAL::to_double(seg2.point(0).x()),CGAL::to_double(seg2.point(0).y()),CGAL::to_double(seg2.point(1).x()),CGAL::to_double(seg2.point(1).y()));
00167 return true;
00168 }
00169 }
00170 else if(const CGAL::Segment_2<K_exact> *ip = CGAL::object_cast<CGAL::Segment_2<K_exact> >(&result))
00171 {
00172 if(debug>1) ROS_INFO("SEG_INTR: intersection on a segment");
00173 return true;
00174 }
00175 else
00176 {
00177 return false;
00178 }
00179
00180 }
00181
00182 return false;
00183 }
00184
00185
00191 bool class_constrained_delaunay_triangulation::is_degenerate(double x0, double y0, double z0,
00192 double x1, double y1, double z1,
00193 double x2, double y2, double z2)
00194 {
00195 CGAL::Point_2<K_exact> t0_p0(x0, y0);
00196 CGAL::Point_2<K_exact> t0_p1(x1,y1);
00197 CGAL::Point_2<K_exact> t0_p2(x2, y2);
00198
00199 CGAL::Triangle_2<K_exact>* t0;
00200
00201
00202 if ((CGAL::Triangle_2<K_exact>(t0_p0, t0_p1, t0_p2)).orientation()>0)
00203 t0 = new CGAL::Triangle_2<K_exact>(t0_p0, t0_p1, t0_p2);
00204 else
00205 t0 = new CGAL::Triangle_2<K_exact>(t0_p0, t0_p2, t0_p1);
00206
00207 if (t0->is_degenerate())
00208 return true;
00209 else
00210 return false;
00211 }
00212
00225 bool class_constrained_delaunay_triangulation::triangles_overlap(Point_2 it0_p0, Point_2 it0_p1, Point_2 it0_p2,
00226 Point_2 it1_p0, Point_2 it1_p1, Point_2 it1_p2)
00227 {
00228
00229 CGAL::Point_2<K_exact> t0_p0(it0_p0.x(), it0_p0.y());
00230 CGAL::Point_2<K_exact> t0_p1(it0_p1.x(), it0_p1.y());
00231 CGAL::Point_2<K_exact> t0_p2(it0_p2.x(), it0_p2.y());
00232
00233 CGAL::Point_2<K_exact> t1_p0(it1_p0.x(), it1_p0.y());
00234 CGAL::Point_2<K_exact> t1_p1(it1_p1.x(), it1_p1.y());
00235 CGAL::Point_2<K_exact> t1_p2(it1_p2.x(), it1_p2.y());
00236
00237 CGAL::Triangle_2<K_exact>* t0;
00238 CGAL::Triangle_2<K_exact>* t1;
00239
00240
00241
00242 if ((CGAL::Triangle_2<K_exact>(t0_p0, t0_p1, t0_p2)).orientation()>0)
00243 t0 = new CGAL::Triangle_2<K_exact>(t0_p0, t0_p1, t0_p2);
00244 else
00245 t0 = new CGAL::Triangle_2<K_exact>(t0_p0, t0_p2, t0_p1);
00246
00247
00248 if ((CGAL::Triangle_2<K_exact>(t1_p0, t1_p1, t1_p2)).orientation()>0)
00249 t1 = new CGAL::Triangle_2<K_exact>(t1_p0, t1_p1, t1_p2);
00250 else
00251 t1 = new CGAL::Triangle_2<K_exact>(t1_p0, t1_p2, t1_p1);
00252
00253
00254
00255
00256
00257
00258
00259 CGAL::Object result;
00260
00261 result = CGAL::intersection(*t0, *t1);
00262
00263 delete t0;
00264 delete t1;
00265 if (const CGAL::Triangle_2<K_exact> *itriangle = CGAL::object_cast<CGAL::Triangle_2<K_exact> >(&result))
00266 {
00267
00268 if(debug>1) ROS_WARN("intersection was a triangle");
00269 return true;
00270 }
00271 else if (const std::vector<CGAL::Point_2<K_exact> > *iptvector = CGAL::object_cast<std::vector<CGAL::Point_2<K_exact> > >(&result))
00272 {
00273
00274 if(debug>1) ROS_WARN("intersection was a pt vector");
00275 return true;
00276 }
00277 else
00278 {
00279
00280 if(debug>1) ROS_WARN("no_intr");
00281 return false;
00282 }
00283
00284 }
00285
00286 int class_constrained_delaunay_triangulation::printf_face_info(CDT::Face_handle fh)
00287 {
00288 if (fh->is_valid())
00289 {
00290 ROS_INFO("Face (%ld,%ld,%ld)\nv0(index%ld x=%f y=%f)\nv1 (index%ld x=%f y=%f)\nv2 (index%ld x=%f y=%f)\nprovenience %d; weight %f", fh->vertex(0)->info().index, fh->vertex(2)->info().index, fh->vertex(2)->info().index,fh->vertex(0)->info().index, CGAL::to_double(fh->vertex(0)->point().x()), CGAL::to_double(fh->vertex(0)->point().y()), fh->vertex(1)->info().index, CGAL::to_double(fh->vertex(1)->point().x()), CGAL::to_double(fh->vertex(1)->point().y()), fh->vertex(2)->info().index, CGAL::to_double(fh->vertex(2)->point().x()), CGAL::to_double(fh->vertex(2)->point().y()), fh->provenience, fh->weight);
00291
00292
00293 }
00294 else
00295 {
00296 ROS_WARN("Face handle is not valid");
00297 }
00298
00299 return 1;
00300 }
00301
00312 int class_constrained_delaunay_triangulation::get_seed_list_of_faces_for_tti(CDT::Face_handle fti, std::vector<CDT::Face_handle>* queue)
00313 {
00314
00315
00316
00317 queue->erase(queue->begin(), queue->end());
00318
00319
00320 CDT::Locate_type lt;
00321
00322 int li;
00323
00324
00325 if(debug) printf_face_info(fti);
00326
00327 Point_2 p((CGAL::to_double(fti->vertex(0)->point().x()) + CGAL::to_double(fti->vertex(1)->point().x()) + CGAL::to_double(fti->vertex(2)->point().x()))/3.,
00328 (CGAL::to_double(fti->vertex(0)->point().y()) + CGAL::to_double(fti->vertex(1)->point().y()) +CGAL::to_double(fti->vertex(2)->point().y()))/3.);
00329
00330 CDT::Face_handle fh;
00331
00332
00333
00334
00335 fh = dt.locate(p, lt, li);
00336
00337
00338
00339
00340 if (lt==CDT::OUTSIDE_AFFINE_HULL)
00341 {
00342 if(debug>1)ROS_INFO("seed point outside affine hull");
00343 }
00344 else if (lt==CDT::OUTSIDE_CONVEX_HULL)
00345 {
00346 queue->push_back(fh);
00347
00348
00349 CDT::Face_handle fh_tti_v0 = dt.locate(fti->vertex(0)->point(), lt, li);
00350 if(lt==CDT::FACE) queue->push_back(fh_tti_v0);
00351
00352
00353 CDT::Face_handle fh_tti_v1 = dt.locate(fti->vertex(1)->point(), lt, li);
00354 if(lt==CDT::FACE) queue->push_back(fh_tti_v1);
00355
00356
00357 CDT::Face_handle fh_tti_v2 = dt.locate(fti->vertex(2)->point(), lt, li);
00358 if(lt==CDT::FACE) queue->push_back(fh_tti_v2);
00359
00360
00361 if(debug>1) ROS_INFO("seed point outside convex hull.Added faces on vertices. Queue size = %d",(int)queue->size());
00362 }
00363 if(lt==CDT::FACE)
00364 {
00365 queue->push_back(fh);
00366 if(debug>1) ROS_INFO("seed point on face (%ld %ld %ld)", fh->vertex(0)->info().index, fh->vertex(1)->info().index, fh->vertex(2)->info().index);
00367 }
00368 else if(lt==CDT::EDGE)
00369 {
00370
00371 queue->push_back(fh);
00372 queue->push_back(fh->neighbor(li));
00373 if(debug>1) ROS_INFO("seed point in segment");
00374 }
00375 else if(lt==CDT::VERTEX)
00376 {
00377
00378 CDT::Face_circulator fc = dt.incident_faces(fh->vertex(li)), done(fc);
00379 if(fc!=0)
00380 {
00381 do
00382 {
00383 queue->push_back(fc);
00384 }
00385 while(++fc!=done);
00386 }
00387
00388 if(debug>1) ROS_INFO("seed point in vertex;");
00389 }
00390 else
00391 {
00392 if(debug)ROS_INFO("seed point not located no queue");
00393 }
00394
00395 return 1;
00396 }
00397
00398
00419 CDT::Face class_constrained_delaunay_triangulation::face(double x0, double y0, double z0, float rgb0,
00420 double x1, double y1, double z1, float rgb1,
00421 double x2, double y2, double z2, float rgb2,
00422 float face_weight, int provenience)
00423 {
00424 CDT::Vertex v0(Point_2(x0,y0));
00425 CDT::Vertex v1(Point_2(x1,y1));
00426 CDT::Vertex v2(Point_2(x2,y2));
00427 CDT::Vertex_handle vh0=&v0;
00428 CDT::Vertex_handle vh1=&v1;
00429 CDT::Vertex_handle vh2=&v2;
00430
00431 CDT::Face f(vh0,vh1,vh2);
00432 f.weight = face_weight;
00433 f.provenience = provenience;
00434 return f;
00435 }
00436
00437 int class_constrained_delaunay_triangulation::iterate_intersecting_faces(CDT::Face_handle fti, int predicate_number)
00438 {
00439
00440
00441 std::vector<CDT::Face_handle> queue;
00442
00443 get_seed_list_of_faces_for_tti(fti, &queue);
00444
00445
00446
00447 if(debug>1)ROS_INFO("Initial queue list has size %d" ,(int)queue.size());
00448
00449
00450 initialize_visited();
00451
00452
00453 for (size_t i=0; queue.size()>0; )
00454 {
00455
00456 if (queue[i]->visited==false)
00457 {
00458
00459
00460 if(dt.is_infinite(queue[i]))
00461 {
00462
00463 for (size_t k=0; k<3; ++k)
00464 {
00465 CDT::Face_handle nfh = queue[i]->neighbor(k);
00466 if (nfh->visited==false)
00467 {
00468 if(debug>1) ROS_INFO("propagating to neighbour %ld",k);
00469 queue.push_back(nfh);
00470 }
00471 }
00472 }
00473 else if (triangles_overlap(fti->vertex(0)->point(), fti->vertex(1)->point(), fti->vertex(2)->point(), queue[i]->vertex(0)->point(), queue[i]->vertex(1)->point(), queue[i]->vertex(2)->point()))
00474 {
00475
00476
00477 if (predicate_number==0)
00478 {
00479 if(predicate_should_add_face(fti, queue[i])==false)
00480 return 0;
00481 }
00482 else if (predicate_number==1)
00483 {
00484 if(predicate_remove_vertex(fti, queue[i])==false)
00485 return 0;
00486 }
00487 else if (predicate_number==2)
00488 {
00489 if(predicate_remove_intersecting_constraints(fti, queue[i])==false)
00490 return 0;
00491 }
00492
00493
00494 for (size_t k=0; k<3; ++k)
00495 {
00496 CDT::Face_handle nfh = queue[i]->neighbor(k);
00497 if (nfh->visited==false && !dt.is_infinite(nfh))
00498 {
00499 if(debug>1) ROS_INFO("propagating to neighbour %ld",k);
00500 queue.push_back(nfh);
00501 }
00502 }
00503 }
00504 }
00505
00506
00507 queue[i]->visited=true;
00508 queue.erase(queue.begin());
00509
00510 }
00511
00512
00513 return 1;
00514 }
00515
00536 int class_constrained_delaunay_triangulation::add_face_manager(double x0, double y0, double z0, float rgb0,
00537 double x1, double y1, double z1, float rgb1,
00538 double x2, double y2, double z2, float rgb2,
00539 float face_weight, int provenience)
00540 {
00541
00542 char str_seed_point[1024];
00543
00544
00545 std::vector<Point_2> tti_vertex;
00546 tti_vertex.push_back(Point_2(x0,y0));
00547 tti_vertex.push_back(Point_2(x1,y1));
00548 tti_vertex.push_back(Point_2(x2,y2));
00549
00550
00551 vector_faces.erase(vector_faces.begin(),vector_faces.end());
00552
00553 std::vector<CDT::Face_handle> queue;
00554
00555
00556
00557
00558
00559 if(debug>0)
00560 {
00561 std::string str;
00562 char tmp[1024];
00563 str+="___get_intersecting_faces_list___\n";
00564 str+=str_seed_point;
00565 sprintf(tmp,"\nShould visit %d faces:\n", (int)vector_faces.size());
00566 str+=tmp;
00567
00568 for (size_t i=0; i<vector_faces.size(); i++)
00569 {
00570
00571
00572 CDT::Face_handle fh = get_face_handle_from_t_face(&vector_faces[i]);
00573 if (fh==NULL)continue;
00574
00575
00576 sprintf(tmp,"Face(%ld,%ld,%ld), ", (get_face_handle_from_t_face(&vector_faces[i]))->vertex(0)->info().index, (get_face_handle_from_t_face(&vector_faces[i]))->vertex(1)->info().index, (get_face_handle_from_t_face(&vector_faces[i]))->vertex(2)->info().index);
00577 str+=tmp;
00578 }
00579 ROS_INFO("%s",str.c_str());
00580 }
00581
00582
00583
00584 pc_faces_visited.erase(pc_faces_visited.begin(), pc_faces_visited.end());
00585 for (size_t i=0; i<vector_faces.size(); i++)
00586 {
00587
00588 CDT::Face_handle fh = get_face_handle_from_t_face(&vector_faces[i]);
00589 if (fh==NULL)continue;
00590
00591
00592 pcl::PointXYZ pt;
00593 pt.x = (CGAL::to_double((get_face_handle_from_t_face(&vector_faces[i]))->vertex(0)->point().x()) + CGAL::to_double((get_face_handle_from_t_face(&vector_faces[i]))->vertex(1)->point().x()) + CGAL::to_double((get_face_handle_from_t_face(&vector_faces[i]))->vertex(2)->point().x()))/3;
00594 pt.y = (CGAL::to_double((get_face_handle_from_t_face(&vector_faces[i]))->vertex(0)->point().y()) + CGAL::to_double((get_face_handle_from_t_face(&vector_faces[i]))->vertex(1)->point().y()) + CGAL::to_double((get_face_handle_from_t_face(&vector_faces[i]))->vertex(2)->point().y()))/3;
00595 pt.z = (CGAL::to_double((get_face_handle_from_t_face(&vector_faces[i]))->vertex(0)->info().z) + CGAL::to_double((get_face_handle_from_t_face(&vector_faces[i]))->vertex(1)->info().z) + CGAL::to_double((get_face_handle_from_t_face(&vector_faces[i]))->vertex(2)->info().z))/3;
00596
00597
00598 pc_faces_visited.points.push_back(pt);
00599 }
00600 pcl_ros::transformPointCloud(pc_faces_visited, pc_faces_visited, transform.inverse());
00601
00602
00603 return 1;
00604 }
00605
00606 bool class_constrained_delaunay_triangulation::predicate_remove_vertex(CDT::Face_handle fti, CDT::Face_handle fh)
00607 {
00608 for (size_t i=0; i<3; ++i)
00609 {
00610 if (overlaps(&fti->vertex(0)->point(), &fti->vertex(1)->point(), &fti->vertex(2)->point(), &fh->vertex(i)->point()))
00611 {
00612 test_if_triangulation_is_valid();
00613
00614 if(dt.are_there_incident_constraints(fh->vertex(i)))
00615 {
00616 dt.remove_incident_constraints(fh->vertex(i));
00617 return 0;
00618 }
00619
00620 test_if_triangulation_is_valid();
00621 dt.remove(fh->vertex(i));
00622 test_if_triangulation_is_valid();
00623 return 0;
00624 }
00625 }
00626 return 1;
00627 }
00628
00629
00630 bool class_constrained_delaunay_triangulation::predicate_remove_intersecting_constraints(CDT::Face_handle fti, CDT::Face_handle fh)
00631 {
00632
00633 if (debug) ROS_WARN("Testing intr with face(%ld,%ld,%ld)",fh->vertex(0)->info().index, fh->vertex(1)->info().index, fh->vertex(2)->info().index);
00634
00635
00636 for (int i=0; i<3; i++)
00637 {
00638 int i1,i2;
00639 if (i==0) {i1=1; i2=2;}
00640 else if (i==1) {i1=0; i2=2;}
00641 else if (i==2) {i1=0; i2=1;}
00642
00643 CGAL::Segment_2<K_exact> seg_fti(fti->vertex(i1)->point(),fti->vertex(i2)->point());
00644
00645 for (int k=0; k<3; k++)
00646 {
00647 int k1,k2;
00648 if (k==0) {k1=1; k2=2;}
00649 else if (k==1) {k1=0; k2=2;}
00650 else if (k==2) {k1=0; k2=1;}
00651
00652 if (debug) ROS_INFO("testing intr with fh edge %ld - %ld",fh->vertex(k1)->info().index, fh->vertex(k2)->info().index);
00653
00654 CGAL::Segment_2<K_exact> s(dt.segment(fh,k));
00655
00656 if (segments_intersect_not_at_endpoints(seg_fti, s))
00657 {
00658 if(debug)ROS_INFO("Found an intersection for seg%d%d and mesh edge mv%ld-mv%ld",i1,i2, fh->vertex(k1)->info().index, fh->vertex(k2)->info().index);
00659 if (dt.is_constrained(CDT::Edge(fh,k)))
00660 {
00661
00662 dt.remove_constraint(fh,k);
00663 test_if_triangulation_is_valid();
00664 return 0;
00665 }
00666 }
00667 }
00668 }
00669
00670 test_if_triangulation_is_valid();
00671 return 1;
00672 }
00673
00674
00675 #endif
00676