title: Trouble when using Efficient_Ransac in CGAL
body: <p>I want to use the <a href="https://doc.cgal.org/latest/Point_set_shape_detection_3/index.html" rel="nofollow noreferrer">Efficient Ransac</a> implementation of CGAL, but whenever I try to set my own parameters, the algorithm doesn't detect any shape anymore.</p>
  
  <p>This work is related to the <a href="https://cgal.geometryfactory.com/CGAL/doc/master/Polygonal_surface_reconstruction/group__PkgPolygonalSurfaceReconstructionRef.html" rel="nofollow noreferrer">Polyfit implementation</a> in CGAL. I want to fine tune the plane detection to see the influence it has on the algorithm. When I use the standard call to <code>ransac.detect()</code>, it works perfectly. However, when I want to set my own <a href="https://doc.cgal.org/5.0/Shape_detection/structCGAL_1_1Shape__detection_1_1Efficient__RANSAC_1_1Parameters.html#ae01052ac79f6fb97c4023a8b8b04967d" rel="nofollow noreferrer">parameters</a> it just doesn't find any plane, even if I set them manually to the default values.</p>
  
  <p>Here is my code, strongly related to <a href="https://cgal.geometryfactory.com/CGAL/doc/master/Polygonal_surface_reconstruction/Polygonal_surface_reconstruction_2polyfit_example_without_input_planes_8cpp-example.html" rel="nofollow noreferrer">this example</a></p>
  
  <pre><code>#include &lt;CGAL/Exact_predicates_inexact_constructions_kernel.h&gt;
  #include &lt;CGAL/IO/read_xyz_points.h&gt;
  #include &lt;CGAL/IO/Writer_OFF.h&gt;
  #include &lt;CGAL/property_map.h&gt; 
  #include &lt;CGAL/Surface_mesh.h&gt;
  #include &lt;CGAL/Shape_detection/Efficient_RANSAC.h&gt;
  #include &lt;CGAL/Polygonal_surface_reconstruction.h&gt;
  
  #ifdef CGAL_USE_SCIP
  
  #include &lt;CGAL/SCIP_mixed_integer_program_traits.h&gt;
  typedef CGAL::SCIP_mixed_integer_program_traits&lt;double&gt;         MIP_Solver;
  
  #elif defined(CGAL_USE_GLPK)
  
  #include &lt;CGAL/GLPK_mixed_integer_program_traits.h&gt;
  typedef CGAL::GLPK_mixed_integer_program_traits&lt;double&gt;         MIP_Solver;
  
  #endif
  
  #if defined(CGAL_USE_GLPK) || defined(CGAL_USE_SCIP)
  #include &lt;CGAL/Timer.h&gt;
  #include &lt;fstream&gt;
  
  typedef CGAL::Exact_predicates_inexact_constructions_kernel         Kernel;
  
  typedef Kernel::Point_3                                             Point;
  typedef Kernel::Vector_3                                            Vector;
  
  // Point with normal, and plane index
  typedef boost::tuple&lt;Point, Vector, int&gt;                            PNI;
  typedef std::vector&lt;PNI&gt;                                            Point_vector;
  typedef CGAL::Nth_of_tuple_property_map&lt;0, PNI&gt;                     Point_map;
  typedef CGAL::Nth_of_tuple_property_map&lt;1, PNI&gt;                     Normal_map;
  typedef CGAL::Nth_of_tuple_property_map&lt;2, PNI&gt;                     Plane_index_map;
  
  typedef CGAL::Shape_detection::Efficient_RANSAC_traits&lt;Kernel, Point_vector, Point_map, Normal_map&gt;     Traits;
  
  typedef CGAL::Shape_detection::Efficient_RANSAC&lt;Traits&gt;             Efficient_ransac;
  typedef CGAL::Shape_detection::Plane&lt;Traits&gt;                        Plane;
  typedef CGAL::Shape_detection::Point_to_shape_index_map&lt;Traits&gt;     Point_to_shape_index_map;
  
  typedef CGAL::Polygonal_surface_reconstruction&lt;Kernel&gt;              Polygonal_surface_reconstruction;
  typedef CGAL::Surface_mesh&lt;Point&gt;                                   Surface_mesh;
  
  
  int main(int argc, char ** argv)
  {
  Point_vector points;
  
  // Loads point set from a file.
  const std::string &amp;input_file = argv[1];
  //const std::string input_file(input);
  std::ifstream input_stream(input_file.c_str());
  if (input_stream.fail()) {
      std::cerr &lt;&lt; "failed open file \'" &lt;&lt;input_file &lt;&lt; "\'" &lt;&lt; std::endl;
      return EXIT_FAILURE;
  }
  std::cout &lt;&lt; "Loading point cloud: " &lt;&lt; input_file &lt;&lt; "...";
  
  CGAL::Timer t;
  t.start();
  if (!input_stream ||
      !CGAL::read_xyz_points(input_stream,
          std::back_inserter(points),
          CGAL::parameters::point_map(Point_map()).normal_map(Normal_map())))
  {
      std::cerr &lt;&lt; "Error: cannot read file " &lt;&lt; input_file &lt;&lt; std::endl;
      return EXIT_FAILURE;
  }
  else
      std::cout &lt;&lt; " Done. " &lt;&lt; points.size() &lt;&lt; " points. Time: " &lt;&lt; t.time() &lt;&lt; " sec." &lt;&lt; std::endl;
  
  // Shape detection
  Efficient_ransac ransac;
  ransac.set_input(points);
  ransac.add_shape_factory&lt;Plane&gt;();
  
  std::cout &lt;&lt; "Extracting planes...";
  t.reset();
  
  // Set parameters for shape detection.
  Efficient_ransac::Parameters parameters;
  // Set probability to miss the largest primitive at each iteration.
  parameters.probability = 0.05;
  
  // Detect shapes with at least 500 points.
  parameters.min_points = 100;
  // Set maximum Euclidean distance between a point and a shape.
  parameters.epsilon = 0.01;
  
  // Set maximum Euclidean distance between points to be clustered.
  parameters.cluster_epsilon = 0.01;
  
  // Set maximum normal deviation.
  // 0.9 &lt; dot(surface_normal, point_normal); 
  parameters.normal_threshold = 0.9;   
  
  // Detect shapes.
  ransac.detect(parameters);
  //ransac.detect();
  
  Efficient_ransac::Plane_range planes = ransac.planes();
  std::size_t num_planes = planes.size();
  
  std::cout &lt;&lt; " Done. " &lt;&lt; num_planes &lt;&lt; " planes extracted. Time: " &lt;&lt; t.time() &lt;&lt; " sec." &lt;&lt; std::endl;
  
  // Stores the plane index of each point as the third element of the tuple.
  Point_to_shape_index_map shape_index_map(points, planes);
  for (std::size_t i = 0; i &lt; points.size(); ++i) {
      // Uses the get function from the property map that accesses the 3rd element of the tuple.
      int plane_index = get(shape_index_map, i);
      points[i].get&lt;2&gt;() = plane_index;
  }
  
  //////////////////////////////////////////////////////////////////////////
  
  std::cout &lt;&lt; "Generating candidate faces...";
  t.reset();
  
  Polygonal_surface_reconstruction algo(
      points,
      Point_map(),
      Normal_map(),
      Plane_index_map()
  );
  
  std::cout &lt;&lt; " Done. Time: " &lt;&lt; t.time() &lt;&lt; " sec." &lt;&lt; std::endl;
  
  //////////////////////////////////////////////////////////////////////////
  
  Surface_mesh model;
  
  std::cout &lt;&lt; "Reconstructing...";
  t.reset();
  
  if (!algo.reconstruct&lt;MIP_Solver&gt;(model)) {
      std::cerr &lt;&lt; " Failed: " &lt;&lt; algo.error_message() &lt;&lt; std::endl;
      return EXIT_FAILURE;
  }
  
  const std::string&amp; output_file(input_file+"_result.off");
  std::ofstream output_stream(output_file.c_str());
  if (output_stream &amp;&amp; CGAL::write_off(output_stream, model))
      std::cout &lt;&lt; " Done. Saved to " &lt;&lt; output_file &lt;&lt; ". Time: " &lt;&lt; t.time() &lt;&lt; " sec." &lt;&lt; std::endl;
  else {
      std::cerr &lt;&lt; " Failed saving file." &lt;&lt; std::endl;
      return EXIT_FAILURE;
  }
  
  //////////////////////////////////////////////////////////////////////////
  
  // Also stores the candidate faces as a surface mesh to a file
  Surface_mesh candidate_faces;
  algo.output_candidate_faces(candidate_faces);
  const std::string&amp; candidate_faces_file(input_file+"_candidate_faces.off");
  std::ofstream candidate_stream(candidate_faces_file.c_str());
  if (candidate_stream &amp;&amp; CGAL::write_off(candidate_stream, candidate_faces))
      std::cout &lt;&lt; "Candidate faces saved to " &lt;&lt; candidate_faces_file &lt;&lt; "." &lt;&lt; std::endl;
  
  return EXIT_SUCCESS;
  }
  
  
  #else
  
  int main(int, char**)
  {
  std::cerr &lt;&lt; "This test requires either GLPK or SCIP.\n";
  return EXIT_SUCCESS;
  }
  
  #endif  // defined(CGAL_USE_GLPK) || defined(CGAL_USE_SCIP)
  </code></pre>
  
  <p>When launched, I have the following message:</p>
  
  <pre><code>Loading point cloud: Scene1/test.xyz... Done. 169064 points. Time: 0.428 sec.
  Extracting planes... Done. 0 planes extracted. Time: 8.328 sec.
  Generating candidate faces... Done. Time: 0.028 sec.
  Reconstructing... Failed: at least 4 planes required to reconstruct a closed surface mesh (only 1 provided)
  </code></pre>
  
  <p>While I have this when launching the code the ransac detection function without parameters:</p>
  
  <pre><code>Loading point cloud: Scene1/test.xyz... Done. 169064 points. Time: 0.448 sec.
  Extracting planes... Done. 18 planes extracted. Time: 3.088 sec.
  Generating candidate faces... Done. Time: 94.536 sec.
  Reconstructing... Done. Saved to Scene1/test.xyz_result.off. Time: 30.28 sec.
  </code></pre>
  
  <p>Can someone help me setting my own parameters for the ransac shape detection?</p>