Face_handle test_point_location(const Triangulation &t,
                                const Point &query,
                                const Triangulation::Locate_type &lt_in)
{
  Triangulation::Locate_type lt, lt2;
  int li, li2;
  Face_handle fh;
  CGAL::Bounded_side bs;
  CGAL::Oriented_side os;

  fh = t.locate(query, lt, li);
  CGAL_assertion(lt == lt_in);
  if (lt_in == Triangulation::EMPTY) {
    CGAL_assertion(fh == Face_handle());
    return fh;
  }

  bs = t.side_of_face(query, fh, lt2, li2);
  os = t.oriented_side(fh, query);
  CGAL_USE(bs);
  CGAL_USE(os);
  
  CGAL_assertion(lt2 == lt_in);

  switch (lt_in)
    {
    case Triangulation::VERTEX:
    case Triangulation::EDGE:
    {
      CGAL_assertion(fh != Face_handle());
      CGAL_assertion(bs == CGAL::ON_BOUNDARY);
      CGAL_assertion(os == CGAL::ON_ORIENTED_BOUNDARY);

      CGAL_assertion(li == li2);
      break;
    }
    case Triangulation::FACE:
    {
      CGAL_assertion(fh != Face_handle());
      CGAL_assertion(bs == CGAL::ON_BOUNDED_SIDE);
      CGAL_assertion(os == CGAL::ON_POSITIVE_SIDE);
      break;
    }
    case Triangulation::EMPTY:
    {
      // Handled above
      CGAL_assertion(false);
      break;
    }
    case Triangulation::OUTSIDE_CONVEX_HULL: CGAL_error();
    case Triangulation::OUTSIDE_AFFINE_HULL: CGAL_error();
    }

  return fh;
}
Beispiel #2
0
void test_isolated_vertex()
{
  Graph G;
  typedef boost::graph_traits< Graph > Traits;
  typedef typename Traits::vertex_descriptor vertex_descriptor;
  typedef typename Traits::halfedge_descriptor halfedge_descriptor;
  vertex_descriptor v = add_vertex(G);
  // the connectivity of v may be anything
  set_halfedge(v, Traits::null_halfedge(), G);
  halfedge_descriptor h = halfedge(v,G);
  CGAL_USE(h);
}
int main()
{
  Triangulation tr;
  int a, b, d;
  for (a=0;a!=4;a++)
    for (b=0;b!=4;b++)
      for (d=0;d!=4;d++)
	tr.insert(Point((a*b-d*a)*10 +a ,(a-b+d +5*b)*100,
			    a*a-d*d-b));
  Triangulation::Finite_cells_iterator cit=tr.finite_cells_begin();
  for(; cit != tr.finite_cells_end(); ++cit) {
    Point circum = tr.dual(cit);
    CGAL_USE(circum);
  }
  return 0;
}
Beispiel #4
0
void test_comparison_operators()
{
  typedef CGAL::MP_Float     RT;
  typedef CGAL::Quotient<RT> QT;

  RT r(1);
  QT q(1);

  q+q; q+r; r+q; q+1; 1+q;
  q-q; q-r; r-q; q-1; 1-q;
  q*q; q*r; r*q; q*1; 1*q;
  q/q; q/r; r/q; q/1; 1/q;
  -q;
  bool b; // avoid clang warning: equality comparison result unused [-Wunused-comparison]
  b = q<q; b = q<r; b = r<q; b = q<1; b = 1<q;
  b = q>q; b = q>r; b = r>q; b = q>1; b = 1>q;

  b = q<=q; b = q<=r; b = r<=q; b = q<=1; b = 1<=q;
  b = q>=q; b = q>=r; b = r>=q; b = q>=1; b = 1>=q;
  b = q==q; b = q==r; b = r==q; b = q==1; b = 1==q;
  b = q!=q; b = q!=r; b = r!=q; b = q!=1; b = 1!=q;
  CGAL_USE(b);
}
int main()
{
  Triangulation t;
  Face_handle fh;

  // Check the empty triangulation
  fh = test_point_location(t, Point(0.5, 0.5), Triangulation::EMPTY);
  CGAL_assertion(fh == Face_handle());

  // Insert the first point
  Point p0(0.5, 0.5);
  Vertex_handle vh0 = t.insert(p0);
  CGAL_assertion(t.is_valid(true));
  CGAL_USE(vh0);

  fh = test_point_location(t, p0, Triangulation::VERTEX);
  CGAL_assertion(fh->has_vertex(vh0));

  fh = test_point_location(t, p0 + Vector(0.1, 0.1), Triangulation::EDGE);
  CGAL_assertion(fh->has_vertex(vh0));

  fh = test_point_location(t, p0 + Vector(-0.1, -0.1), Triangulation::EDGE);
  CGAL_assertion(fh->has_vertex(vh0));

  fh = test_point_location(t, p0 + Vector(-0.2, -0.3), Triangulation::FACE);
  CGAL_assertion(fh->has_vertex(vh0));

  CGAL_assertion(t.is_valid(true));

  // Insert the second point on an edge
  Point p1(0.7, 0.7);
  Vertex_handle vh1 = t.insert(p1);
  CGAL_USE(vh1);
  CGAL_assertion(t.is_valid(true));

  fh = test_point_location(t, p0, Triangulation::VERTEX);
  CGAL_assertion(fh->has_vertex(vh0));

  fh = test_point_location(t, p1, Triangulation::VERTEX);
  CGAL_assertion(fh->has_vertex(vh1));

  fh = test_point_location(t, p0 + Vector(0.1, 0.1), Triangulation::EDGE);
  CGAL_assertion(fh->has_vertex(vh0));
  CGAL_assertion(fh->has_vertex(vh1));

  fh = test_point_location(t, p0 + Vector(-0.1, -0.1), Triangulation::EDGE);
  CGAL_assertion(fh->has_vertex(vh0));
  CGAL_assertion(!fh->has_vertex(vh1));

  fh = test_point_location(t, p1 + Vector(0.1, 0.1), Triangulation::EDGE);
  CGAL_assertion(!fh->has_vertex(vh0));
  CGAL_assertion(fh->has_vertex(vh1));

  fh = test_point_location(t, p0 + Vector(-0.02, -0.03), Triangulation::FACE);
  CGAL_assertion(fh->has_vertex(vh0));

  fh = test_point_location(t, p1 + Vector(-0.02, -0.03), Triangulation::FACE);
  CGAL_assertion(fh->has_vertex(vh1));

  CGAL_assertion(t.is_valid(true));

  // Insert the third point in a face
  Point p2(0.8, 0.6);
  Vertex_handle vh2 = t.insert(p2);
  CGAL_USE(vh2);
  CGAL_assertion(t.is_valid(true));

  fh = test_point_location(t, p0, Triangulation::VERTEX);
  CGAL_assertion(fh->has_vertex(vh0));
  fh = test_point_location(t, p1, Triangulation::VERTEX);
  CGAL_assertion(fh->has_vertex(vh1));
  fh = test_point_location(t, p2, Triangulation::VERTEX);
  CGAL_assertion(fh->has_vertex(vh2));

  fh = test_point_location(t, Point(0.6, 0.6), Triangulation::EDGE);
  CGAL_assertion(fh->has_vertex(vh0));
  CGAL_assertion(fh->has_vertex(vh1));

  test_point_location(t, Point(0.7, 0.6), Triangulation::FACE);
  test_point_location(t, p0 + Vector(-0.02, -0.03), Triangulation::FACE);
  test_point_location(t, p0 + Vector(0.02, -0.03), Triangulation::FACE);
  test_point_location(t, p0 + Vector(-0.02, 0.03), Triangulation::FACE);
  test_point_location(t, p0 + Vector(0.02, 0.03), Triangulation::FACE);

  return 0;
}
Beispiel #6
0
int
main(int,char*[])
{
  Triangulation t;

  t.insert(Point(0.1,0,1));
  t.insert(Point(1,0,1));
  t.insert(Point(0.2,0.2, 2));
  t.insert(Point(0,1,2));
  t.insert(Point(0,2,3));

  vertex_iterator vit, ve;
  // Associate indices to the vertices
  int index = 0;
  // boost::tie assigns the first and second element of the std::pair
  // returned by boost::vertices to the variables vit and ve
  for(boost::tie(vit,ve) = vertices(t); vit!=ve; ++vit ){
    vertex_descriptor  vd = *vit;
    if(! t.is_infinite(vd)){
      vertex_id_map[vd]= index++;
    }
  }

  std::cerr << index << " vertices" << std::endl;
  index = 0;
  face_iterator fit,fe;
  for(boost::tie(fit,fe) = faces(t); fit!= fe; ++fit){
    face_descriptor fd = *fit;
    halfedge_descriptor hd = halfedge(fd,t);
    halfedge_descriptor n = next(hd,t);
    
    halfedge_descriptor nn = next(n,t);
    if(next(nn,t) != hd){
      std::cerr << "the face is not a triangle" << std::endl;
    }
    
    ++index;
  }
  
  std::cerr << index << " faces" << std::endl;
  index = 0;

  edge_iterator eit,ee;
  for(boost::tie(eit,ee) = edges(t); eit!= ee; ++eit){
    edge_descriptor ed = *eit;
    vertex_descriptor vd = source(ed,t);
    CGAL_USE(vd);
    ++index;
  }

  std::cerr << index << " edges" << std::endl;
  index = 0;

  halfedge_iterator hit,he;
  for(boost::tie(hit,he) = halfedges(t); hit!= he; ++hit){
    halfedge_descriptor hd = *hit;
    vertex_descriptor vd = source(hd,t);
    CGAL_USE(vd);
    ++index;
  }
  std::cerr << index << " halfedges" << std::endl;

  std::cerr << num_vertices(t) << " " << num_edges(t) << " " << num_halfedges(t) << " " << num_faces(t) << std::endl;

  typedef boost::property_map<Triangulation, boost::vertex_point_t>::type Ppmap;
  Ppmap ppmap = get(boost::vertex_point, t);
 

  for(vertex_descriptor vd : vertices_around_target(*vertices(t).first, t)){
    std::cout <<  ppmap[vd] << std::endl;
  }


  ppmap[*(++vertices(t).first)] = Point(78,1,2);
  std::cout << " changed point of vertex " << ppmap[*(++vertices(t).first)] << std::endl;

  return 0;
}
Beispiel #7
0
void test_edge_collapse() 
{
  std::cerr << "test_edge_collapse" << std::endl;

  PointMassList points;
  //use the stair example for testing
  load_xy_file<PointMassList, Point>("data/stair-noise00.xy", points);

  Point_property_map point_pmap;
  Mass_property_map  mass_pmap;

  CGAL::Optimal_transportation_reconstruction_2<K, Point_property_map, Mass_property_map>
    otr2(points, point_pmap, mass_pmap);

  const Rt_2& rt2 = otr2.tds();

  FT min_priority = 1000;
  R_edge_2 contract_edge;
  for (Finite_edges_iterator ei = rt2.finite_edges_begin();
       ei != rt2.finite_edges_end(); ++ei) 
  {
    if (rt2.is_pinned(*ei) || rt2.is_target_cyclic(*ei))
      continue;
    
    R_edge_2 cur_r_edge;
    if(!otr2.create_pedge(*ei, cur_r_edge))
      continue;

    print_edge(cur_r_edge);

    if (cur_r_edge.priority() < min_priority && cur_r_edge.priority() > 0) 
    {
      min_priority = cur_r_edge.priority();
      contract_edge = cur_r_edge;
    }
  }

  R_edge_2 pedge;
  otr2.pick_edge(0, pedge);

  std::cout << "--------" << std::endl;
  print_edge(contract_edge);

  print_edge(pedge);

  std::cout << "--------" << std::endl;

  //test that the right edge was picked for collapsing
  // N.B.: it can be two different edges if several edges have the same
  // priority value.
  assert(CGAL::abs(pedge.priority() - contract_edge.priority())
         < pedge.priority()*1e-13);
  otr2.do_collapse(contract_edge.edge());

  bool found = false;
  for (Finite_edges_iterator ei = rt2.finite_edges_begin();
       ei != rt2.finite_edges_end(); ++ei) 
  {
    if (*ei == contract_edge.edge()) 
    {
      found = true;
      break;
    }
  }

  //test that the edge was collapsed
  assert(!found);
  CGAL_USE(found);
}
void test(const Cont &)
{
  // Testing if all types are provided.

  typename Cont::value_type              t0;
  typename Cont::reference               t1 = t0;      CGAL_USE(t1);
  typename Cont::const_reference         t2 = t0;      CGAL_USE(t2);
  typename Cont::pointer                 t3 = &t0;
  typename Cont::const_pointer           t4 = &t0;     CGAL_USE(t4);
  typename Cont::size_type               t5 = 0;       CGAL_USE(t5);
  typename Cont::difference_type         t6 = t3-t3;   CGAL_USE(t6);
  typename Cont::iterator                t7;           CGAL_USE(t7);
  typename Cont::const_iterator          t8;           CGAL_USE(t8);
  typename Cont::reverse_iterator        t9;           CGAL_USE(t9);
  typename Cont::const_reverse_iterator  t10;          CGAL_USE(t10);
  typename Cont::allocator_type          t15;

  std::cout << "Testing empty containers." << std::endl;

  Cont c0, c1;
  Cont c2(t15);
  Cont c3(c2);
  Cont c4;
  c4 = c2;

  typedef std::vector<typename Cont::value_type> Vect;
  Vect v0;
  const Cont c5(v0.begin(), v0.end());
  Cont c6(c5.begin(), c5.end());
  typename Cont::allocator_type Al;
  Cont c7(c0.begin(), c0.end(), Al);
  Cont c8;
  c8.insert(c0.rbegin(), c0.rend());

  // test conversion iterator-> const_iterator.
  typename Cont::const_iterator t16 = c5.begin();  CGAL_USE(t16);
  assert(t16 == c5.begin());

  assert(c0 == c1);
  assert(! (c0 < c1));

  assert(check_empty(c0));
  assert(check_empty(c1));
  assert(check_empty(c2));
  assert(check_empty(c3));
  assert(check_empty(c4));
  assert(check_empty(c5));
  assert(check_empty(c6));
  assert(check_empty(c7));
  assert(check_empty(c8));

  c1.swap(c0);

  assert(check_empty(c0));
  assert(check_empty(c1));

  c1.merge(c0);

  assert(check_empty(c0));
  assert(check_empty(c1));

  typename Cont::allocator_type  t20 = c0.get_allocator();

  std::cout << "Now filling some containers" << std::endl;

  Vect v1(10000);
  Cont c9(v1.begin(), v1.end());

  assert(c9.size() == v1.size());
  assert(c9.max_size() >= v1.size());
  assert(c9.capacity() >= c9.size());

  Cont c10 = c9;

  assert(c10 == c9);
  assert(c10.size() == v1.size());
  assert(c10.max_size() >= v1.size());
  assert(c10.capacity() >= c10.size());

  c9.clear();

  assert(check_empty(c9));
  assert(c9.capacity() >= c9.size());
  assert(c0 == c9);

  c9.merge(c10);
  c10.swap(c9);

  assert(check_empty(c9));
  assert(c9.capacity() >= c9.size());

  assert(c10.size() == v1.size());
  assert(c10.max_size() >= v1.size());
  assert(c10.capacity() >= c10.size());

  std::cout << "Testing insertion methods" << std::endl;

  c9.assign(c10.begin(), c10.end());

  assert(c9 == c10);

  c10.assign(c9.begin(), c9.end());

  assert(c9 == c10);

  c9.insert(c10.begin(), c10.end());

  assert(c9.size() == 2*v1.size());

  c9.clear();

  assert(c9 != c10);

  c9.insert(c10.begin(), c10.end());

  assert(c9.size() == v1.size());
  assert(c9 == c10);


  typename Cont::iterator it = c9.iterator_to(*c9.begin());
  assert(it == c9.begin());
  typename Cont::const_iterator cit = c9.iterator_to(const_cast<typename Cont::const_reference>(*c9.begin()));
  assert(cit == c9.begin());

  typename Cont::iterator s_it = Cont::s_iterator_to(*c9.begin());
  assert(s_it == c9.begin());
  typename Cont::const_iterator s_cit = Cont::s_iterator_to(const_cast<typename Cont::const_reference>(*c9.begin()));
  assert(s_cit == c9.begin());


  c10 = Cont();

  assert(check_empty(c10));

  for(typename Vect::const_iterator it = v1.begin(); it != v1.end(); ++it)
    c10.insert(*it);

  assert(c10.size() == v1.size());
  assert(c9 == c10);

  c9.erase(c9.begin());
  c9.erase(c9.begin());

  assert(c9.size() == v1.size() - 2);

  // test reserve
  /*Cont c11;
  c11.reserve(v1.size());
  for(typename Vect::const_iterator it = v1.begin(); it != v1.end(); ++it)
    c11.insert(*it);
  
  assert(c11.size() == v1.size());
  assert(c10 == c11);*/

  // owns() and owns_dereferencable().
  for(typename Cont::const_iterator it = c9.begin(), end = c9.end(); it != end; ++it) {
    assert(c9.owns(it));
    assert(c9.owns_dereferencable(it));
    assert(! c10.owns(it));
    assert(! c10.owns_dereferencable(it));
  }
  assert(c9.owns(c9.end()));
  assert(! c9.owns_dereferencable(c9.end()));


  c9.erase(c9.begin(), c9.end());

  assert(check_empty(c9));
  
  std::cout << "Testing parallel insertion" << std::endl;
  {
  Cont c11;
  Vect v11(1000000);
  std::vector<typename Cont::iterator> iterators(v11.size());
  tbb::parallel_for(
    tbb::blocked_range<size_t>( 0, v11.size() ),
    Insert_in_CCC_functor<Vect, Cont>(v11, c11, iterators)
  );
  assert(c11.size() == v11.size());
  
  std::cout << "Testing parallel erasure" << std::endl;
  tbb::parallel_for(
    tbb::blocked_range<size_t>( 0, v11.size() ),
    Erase_in_CCC_functor<Cont>(c11, iterators)
  );
  assert(c11.empty());
  }

  std::cout << "Testing parallel insertion AND erasure" << std::endl;
  {
  Cont c12;
  Vect v12(1000000);
  std::vector<tbb::atomic<bool> > free_elements(v12.size());
  for(typename std::vector<tbb::atomic<bool> >::iterator 
    it = free_elements.begin(), end = free_elements.end(); it != end; ++it) 
  {
    *it = true;
  }
    
  tbb::atomic<unsigned int> num_erasures; 
  num_erasures = 0;
  std::vector<typename Cont::iterator> iterators(v12.size());
  tbb::parallel_for(
    tbb::blocked_range<size_t>( 0, v12.size() ),
    Insert_and_erase_in_CCC_functor<Vect, Cont>(
      v12, c12, iterators, free_elements, num_erasures)
  );
  assert(c12.size() == v12.size() - num_erasures);
  }
}
void test_boundary_mesh()
{
  typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
  typedef CGAL::Polyhedron_3<Kernel, CGAL::Polyhedron_items_with_id_3> Polyhedron_3;
  typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Polyhedron_3> Traits;
  typedef Traits::Barycentric_coordinate Barycentric_coordinate;
  typedef Traits::FT FT;
  typedef Traits::Point_3 Point_3;
  typedef Traits::Triangle_3 Triangle_3;
  typedef boost::graph_traits<Polyhedron_3> Graph_traits;
  typedef Graph_traits::vertex_descriptor vertex_descriptor;
  typedef Graph_traits::vertex_iterator vertex_iterator;
  typedef Graph_traits::face_descriptor face_descriptor;
  typedef Graph_traits::face_iterator face_iterator;
  typedef CGAL::Surface_mesh_shortest_path<Traits> Surface_mesh_shortest_path;
  typedef boost::property_map<Polyhedron_3, CGAL::vertex_point_t>::type VPM;

  Traits traits;

  Traits::Construct_triangle_3_to_triangle_2_projection project_triangle_3_to_triangle_2(traits.construct_triangle_3_to_triangle_2_projection_object());
  CGAL_USE(project_triangle_3_to_triangle_2);
  Traits::Compute_squared_distance_3 compute_squared_distance_3(traits.compute_squared_distance_3_object());
  Traits::Construct_barycenter_3 construct_barycenter_3(traits.construct_barycenter_3_object());
  Traits::Construct_triangle_3_along_segment_2_flattening flatten_triangle_3_along_segment_2(traits.construct_triangle_3_along_segment_2_flattening_object());
  CGAL_USE(flatten_triangle_3_along_segment_2);
  Traits::Construct_barycentric_coordinate construct_barycentric_coordinate(traits.construct_barycentric_coordinate_object());

  struct Construct_barycenter_in_triangle_3
  {
    Traits::Construct_barycenter_3 m_cb3;

    Construct_barycenter_in_triangle_3(Traits::Construct_barycenter_3 cb3)
      : m_cb3(cb3)
    {
    }

    Point_3 operator() (const Triangle_3& t, const Barycentric_coordinate& b)
    {
      return m_cb3(t[0], b[0], t[1], b[1], t[2], b[2]);
    }
  } construct_barycenter_in_triangle_3(construct_barycenter_3);

  std::ifstream inFile("data/boundary_mesh.off");

  Polyhedron_3 P;

  inFile >> P;

  inFile.close();

  CGAL::set_halfedgeds_items_id(P);

  face_iterator startFace;
  face_iterator endFace;

  boost::tie(startFace, endFace) = CGAL::faces(P);

  vertex_iterator currentVertex;
  vertex_iterator endVertex;

  VPM vpm = CGAL::get(CGAL::vertex_point, P);

  vertex_descriptor vertexHandles[10];
  face_descriptor faceHandles[8];
  Point_3 vertexLocations[10];
  size_t currentVertexIndex = 0;

  for (boost::tie(currentVertex, endVertex) = CGAL::vertices(P); currentVertex != endVertex; ++currentVertex)
  {
    vertexHandles[currentVertexIndex] = *currentVertex;
    vertexLocations[currentVertexIndex] = vpm[*currentVertex];
    ++currentVertexIndex;
  }

  size_t currentFaceIndex = 0;

  for (face_iterator currentFace = startFace; currentFace != endFace; ++currentFace)
  {
    faceHandles[currentFaceIndex] = *currentFace;
    ++currentFaceIndex;
  }

  Barycentric_coordinate startLocation = construct_barycentric_coordinate(FT(0.1), FT(0.8), FT(0.1));

  typedef boost::property_map<Polyhedron_3, CGAL::face_external_index_t>::type FaceIndexMap;

  FaceIndexMap faceIndexMap(CGAL::get(CGAL::face_external_index, P));

  Surface_mesh_shortest_path shortestPaths(P, traits);
  //shortestPaths.m_debugOutput = true;
  shortestPaths.add_source_point(*startFace, startLocation);
  shortestPaths.build_sequence_tree();

  Triangle_3 firstTriangle(vertexLocations[1], vertexLocations[0], vertexLocations[2]);

  Point_3 locationInTriangle(construct_barycenter_in_triangle_3(firstTriangle, startLocation));

  FT dist0 = shortestPaths.shortest_distance_to_source_points(vertexHandles[0]).first;
  CHECK_CLOSE(dist0, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[0])), FT(0.000001));

  FT dist1 = shortestPaths.shortest_distance_to_source_points(vertexHandles[1]).first;
  CHECK_CLOSE(dist1, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[1])), FT(0.000001));

  FT dist2 = shortestPaths.shortest_distance_to_source_points(vertexHandles[2]).first;
  CHECK_CLOSE(dist2, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[2])), FT(0.000001));

  FT dist3 = shortestPaths.shortest_distance_to_source_points(vertexHandles[3]).first;
  CHECK_CLOSE(dist3, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[3])), FT(0.000001));

  FT dist4 = shortestPaths.shortest_distance_to_source_points(vertexHandles[4]).first;
  CHECK_CLOSE(dist4, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[1])) + CGAL::sqrt(compute_squared_distance_3(vertexLocations[1], vertexLocations[4])), FT(0.000001));

  FT dist5 = shortestPaths.shortest_distance_to_source_points(vertexHandles[5]).first;
  CHECK_CLOSE(dist5, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[3])) + CGAL::sqrt(compute_squared_distance_3(vertexLocations[3], vertexLocations[5])), FT(0.000001));

  Barycentric_coordinate somewhereElseInFirstTriangle = construct_barycentric_coordinate(0.8, 0.05, 0.15);

  FT distT0 = shortestPaths.shortest_distance_to_source_points(faceHandles[0], somewhereElseInFirstTriangle).first;
  CHECK_CLOSE(distT0, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, construct_barycenter_in_triangle_3(firstTriangle, somewhereElseInFirstTriangle))), FT(0.000001));

  Triangle_3 oneStepTriangle(vertexLocations[4], vertexLocations[1], vertexLocations[3]);
  Barycentric_coordinate locationInOneStepTriangle = construct_barycentric_coordinate(0.1, 0.8, 0.1);

  CGAL::test::Edge_sequence_collector<Traits> collector(P);
  shortestPaths.shortest_path_sequence_to_source_points(faceHandles[2], locationInOneStepTriangle, collector);

  FT distT2 = shortestPaths.shortest_distance_to_source_points(faceHandles[2], locationInOneStepTriangle).first;
  CHECK_CLOSE(distT2, dist1 + CGAL::sqrt(compute_squared_distance_3(vertexLocations[1], construct_barycenter_in_triangle_3(oneStepTriangle, locationInOneStepTriangle))), FT(0.00001));

  Triangle_3 twoStepTriangle(vertexLocations[6], vertexLocations[5], vertexLocations[7]);
  Barycentric_coordinate locationInTwoStepTriangle = construct_barycentric_coordinate(0.8, 0.1, 0.1);

  FT distT5 = shortestPaths.shortest_distance_to_source_points(faceHandles[5], locationInTwoStepTriangle).first;
  CHECK_CLOSE(distT5, dist3 + CGAL::sqrt(compute_squared_distance_3(vertexLocations[3], construct_barycenter_in_triangle_3(twoStepTriangle, locationInTwoStepTriangle))), FT(0.00001));

  Triangle_3 threeStepTriangle(vertexLocations[7], vertexLocations[5], vertexLocations[8]);
  Barycentric_coordinate locationInThreeStepTriangle = construct_barycentric_coordinate(0.2, 0.6, 0.2);

  FT distT6 = shortestPaths.shortest_distance_to_source_points(faceHandles[6], locationInThreeStepTriangle).first;
  CHECK_CLOSE(distT6, dist5 + CGAL::sqrt(compute_squared_distance_3(vertexLocations[5], construct_barycenter_in_triangle_3(threeStepTriangle, locationInThreeStepTriangle))), FT(0.00001));
}