2

The task

is simple: I want to create a tetrahedral mesh and I want to add several features to it.

Example

As an input, take the file cube.off that can be found in CGAL-4.11/examples/Mesh_3/data. The features I would like to add (just the twelve edges of the cube) are saved in cube.edges:

2 -1 -1 -1 -1 1 -1
2 -1 -1 -1 1 -1 -1
2 -1 -1 -1 -1 -1 1
2 -1 1 -1 1 1 -1
2 -1 1 -1 -1 1 1
2 1 1 -1 1 -1 -1
2 1 1 -1 1 1 1
2 1 -1 -1 1 -1 1
2 -1 -1 1 -1 1 1
2 -1 -1 1 1 -1 1
2 -1 1 1 1 1 1
2 1 1 1 1 -1 1

MWE of the code:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Polyhedral_complex_mesh_domain_3.h>
#include <CGAL/make_mesh_3.h>

// From CGAL-4.11/examples/Mesh_3 but for simplicity copied to the current folder.
#include "read_polylines.h"

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Mesh_polyhedron_3<K>::type Polyhedron;
typedef CGAL::Polyhedral_complex_mesh_domain_3<K> Mesh_domain;
typedef CGAL::Sequential_tag Concurrency_tag;

typedef CGAL::Mesh_triangulation_3<Mesh_domain,CGAL::Default,Concurrency_tag>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<
  Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_segment_index> C3t3;
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;

typedef K::Point_3 Point;
typedef std::vector<std::vector<Point> > Polylines;

int main()
{
  // Read the (one) patch.
  std::vector<Polyhedron> patches(1);
  std::ifstream input("cube.off");
  input >> patches[0];
  const std::pair<int, int> incident_subdomains[] = { std::make_pair(1,0) };
  Mesh_domain domain(patches.begin(), patches.end(), incident_subdomains, incident_subdomains+1);

  // Read the features.
  std::string feature_edges="cube.edges";
  Polylines polylines;
  read_polylines<Point>(feature_edges.c_str(), polylines);
  domain.add_features(polylines.begin(), polylines.end());

  // Create the mesh.
  Mesh_criteria criteria(CGAL::parameters::edge_size = 0.25);
  C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria);

  // Write it (if it hasn't crashed before).
  std::ofstream medit_file("out.mesh");
  c3t3.output_to_medit(medit_file, false, true);
}

This (when compiled with the option -DCGAL_MESH_3_VERBOSE) crashes with the following error message:

Start volume scan...Scanning triangulation for bad cells (sequential)... terminate called after throwing an instance of 'CGAL::Assertion_exception'
  what():  CGAL ERROR: assertion violation!
Expr: patch_id > 0 && std::size_t(patch_id) < patch_id_to_polyhedron_id.size()
File: /yatmp/scr1/ya10813/cgal-install/include/CGAL/Polyhedral_complex_mesh_domain_3.h
Line: 457
Aborted

Question

What am I missing? It must be something really basic. CGAL is a very reliable library that works well on complex data; I don't believe that a cube with 12 edges is enough to stop it.

Things that I also tried

  • When I replace the line domain.add_features(polylines.begin(), polylines.end()); with domain.detect_features();, the program terminates correctly. The confusing part is that the detected features are exactly those that I am trying to add (I know that because I have made a function in Mesh_domain_with_polyline_features_3 that printed the edges for me; I can share it here if necessary).

  • When I use Polyhedral_mesh_domain_with_features_3 instead of Polyhedral_complex_mesh_domain_3, the program terminates correctly. The features seem to be preserved in the resulting geometry. However, it is just one patch (all of the triangles in out.mesh have the same last number, whereas I want them to have numbers 0 to 11 in this case). Edit: To achieve that, one would have to either use detect_features(); instead of add_features(...); or split the domain into patches and let CGAL create the complex from them. Thanks to @lrineau for the clarification.

  • I also tried splitting the domain into several patches first. However, then the boundaries of the patches change. Edit: One way to keep them is to add the patch boundaries as features.

  • Reversing the orientation of the surface (and swapping 0 and 1 in incident_subdomains): no visible change.

  • Changing the order of the feature lines in cube.edges: no visible change.

  • Linking with older version of Boost: no visible change.

1 Answers1

3

The class Polyhedral_complex_mesh_domain_3 is a new class added one year ago in CGAL-4.11. The problem you got is that it was never tested without calling domain.detect_features(), and the code has a bug: the data member patch_id_to_polyhedron_id is only filled in detect_features(). That explains why it works when you call detect_features() instead of add_features(..).

Edit: I have fixed that bug today, see the PR #3393 of CGAL. The fix will be in the future bug-fix releases CGAL-4.12.2 and CGAL-4.13.1.

lrineau
  • 6,036
  • 3
  • 34
  • 47
  • Excellent, I am really relieved to hear this. – another lisp ninja on a bike Oct 10 '18 at 09:08
  • I have a fix. I have modified my answer. In my opinion, you can accept it, now. – lrineau Oct 10 '18 at 14:06
  • Dear @lrineau, thank you a lot for the prompt bugfix. I recompiled and my program now terminates correctly. However, there is still a thing I am confused about: when I add the features like in the MWE, all triangles in `out.mesh` have the tag `2`. When I replace `add_features(...);` with `detect_features();`, the mesh looks the same but the triangles have tags `2` to `7` (consequently, medit shows it with 6 colours instead of one after pressing "e"). This is despite the fact that the detected features are the same as those that I manually add. Which behavior is correct? – another lisp ninja on a bike Oct 10 '18 at 14:35
  • 1
    `detect_features` detects sharp curves, but it also detect surface patches, and gives numbers to them. – lrineau Oct 11 '18 at 11:01
  • I see, I wrongly assumed that `add_features` does the same. Everything works now, thank you very much for your time. I was really getting desperate recently. (= – another lisp ninja on a bike Oct 11 '18 at 11:20
  • I have also slightly edited the question to clarify the patches. Hopefully it will be clearer to people who may stumble over it in future. – another lisp ninja on a bike Oct 11 '18 at 11:29
  • Dear @lrineau, is there any plan as to when will CGAL-4.13.1 be available? My computer is happy to work with the bugfix downloaded from github but porting my solution to other people's computers would be easier if I could refer to an official release. – another lisp ninja on a bike Jan 14 '19 at 16:48
  • @anotherlispninjaonabike I usually publish the bug-fix release (like 4.13.1) just before the next beta release (4.14-beta1). That should be within the next month. – lrineau Jan 15 '19 at 11:53