CGAL / cgal

The public CGAL repository, see the README below
https://github.com/CGAL/cgal#readme
Other
5.01k stars 1.39k forks source link

Surface_mesh_shortest_path method adds multiple source points and an error is reported #8499

Open wanghao-98 opened 1 month ago

wanghao-98 commented 1 month ago

The first time I tried to run a program with multiple source points, it was normal, but after a day or two, I ran it again and I got an error, in the middle I added VTK-related code, I thought there was a conflict between the two, but when I removed the VTK, the code still didn't work. The code is the first simple example given officially.

  std::vector<vertex_descriptor> sources;
  sources.push_back(*(vertices(tmesh).begin() + 95));
  sources.push_back(*(vertices(tmesh).begin() + 96));
  sources.push_back(*(vertices(tmesh).begin() + 97));
  shortest_paths.add_source_points(sources.begin(), sources.end());

It is okay for each of these points to run individually, but it is not possible to run with multiple points. After debugging, it is found that an error is reported in the following statement:

    auto result = shortest_paths.shortest_distance_to_source_points(*(vit));
    std::cout << result.first << std::endl;

The error is as follows:

terminate called after throwing an instance of 'CGAL::Assertion_exception'
  what():  CGAL ERROR: assertion violation!
Expr: !node->is_null_face()
File: /usr/local/include/CGAL/Surface_mesh_shortest_path/Surface_mesh_shortest_path.h
Line: 1474
Abandoned (core dumped)

Exclusion of possible problems

  1. Grid data The data is triangular grid data, and there is no self-intersection and other phenomena image

  2. It is not the influence of boundary points, and it cannot be run even after testing the internal point ID

Attach the full code:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Surface_mesh_shortest_path.h>
#include <CGAL/Random.h>
#include <boost/lexical_cast.hpp>
#include <cstdlib>
#include <iostream>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Surface_mesh<Kernel::Point_3> Triangle_mesh;
typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Triangle_mesh> Traits;
typedef CGAL::Surface_mesh_shortest_path<Traits> Surface_mesh_shortest_path;
typedef boost::graph_traits<Triangle_mesh> Graph_traits;
typedef Graph_traits::vertex_iterator vertex_iterator;
typedef Graph_traits::face_iterator face_iterator;
int main(int argc, char **argv)
{
  const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("../data/surface.obj");
  Triangle_mesh tmesh;
  if (!CGAL::IO::read_polygon_mesh(filename, tmesh) ||
      !CGAL::is_triangle_mesh(tmesh))
  {
    std::cerr << "Invalid input file." << std::endl;
    return EXIT_FAILURE;
  }
  // pick up a random face
  const unsigned int randSeed = argc > 2 ? boost::lexical_cast<unsigned int>(argv[2]) : 7915421;
  CGAL::Random rand(randSeed);
  const int target_face_index = rand.get_int(0, static_cast<int>(num_faces(tmesh)));
  face_iterator face_it = faces(tmesh).first;
  std::advance(face_it, target_face_index);
  // ... and define a barycentric coordinates inside the face
  Traits::Barycentric_coordinates face_location = {{0.25, 0.5, 0.25}};
  // construct a shortest path query object and add a source point
  Surface_mesh_shortest_path shortest_paths(tmesh);
  // shortest_paths.add_source_point(*face_it, face_location);
  shortest_paths.add_source_point(*(vertices(tmesh).begin() + 95));
  shortest_paths.add_source_point(*(vertices(tmesh).begin() + 96));
  shortest_paths.add_source_point(*(vertices(tmesh).begin() + 97));

  // For all vertices in the tmesh, compute the points of
  // the shortest path to the source point and write them
  // into a file readable using the CGAL Polyhedron demo
  // std::ofstream output("../data/shortest_paths_with_id.polylines.txt");
  vertex_iterator vit, vit_end;
  for (boost::tie(vit, vit_end) = vertices(tmesh);
       vit != vit_end; ++vit)
  {
    // std::vector<Traits::Point_3> points;
    // shortest_paths.shortest_path_points_to_source_points(*vit, std::back_inserter(points));
    auto result = shortest_paths.shortest_distance_to_source_points(*(vit));
    std::cout << result.first << std::endl;
  }
  return 0;
}
afabri commented 1 month ago

please run google translate on your text. 请翻译成英文

MaelRL commented 1 week ago

Can you please also share the data?