Fill holes in 3d mesh from image segmentation with CGAL or something else? - mesh

I got some segmented image data from a CT scan of a body part in .raw file format. Segmentation was performed in Amira.
In CGAL, I created an .inr file, read this, then meshed this with certain mesh criteria:
typedef CGAL::Labeled_mesh_domain_3<K> Mesh_domain;
typedef CGAL::Mesh_triangulation_3<Mesh_domain,CGAL::Default,Concurrency_tag>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
(...)
Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(inr_image);
Mesh_criteria criteria(facet_angle=fangle, facet_size=fsize, facet_distance=fdist,
cell_radius_edge_ratio=creratio, cell_size=csize);
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria, lloyd());
I could create a 3d tetrahedral mesh (.vtu) with CGAL for finite element stuff which works fine.
BUT: Unfortunately the final mesh contains too much "holes" between the different tissue types and that's... very bad. So my question is: Is there a way to fill these holes with CGAL? I am open for other ways, too, because it won't be possible to segment the huge amount of data again (this was not done by me).
Thanks a lot, any help appreciated.

Related

CGAL AABB tree do_intersect floating point error

I am using CGAL for a project of mine. I create a AABB tree out of a mesh file (.off). First I extract Polyhedron from my mesh, then I get the triangles and finally I insert them in the tree.
All of this went smoothly.
The problem is when I use the do_intersect function of the tree.
Given two points, A and B, I would like to know if the ray or segment connecting the two insersect with something.
Most of the time this works properly, sometimes I get the floating point error. 'sometimes' means with a very few subsets of points.
Is there a reason for this?
Here there is a snippet of my code:
glm::vec3 pointA, pointB; // assume this are filled with some values
// the elements inside points above are floats.
Point_3 pA(pointA.x, pointA.y, pointA.z);
Point_3 pB(pointB.x, pointB.y, pointB.z);
Segment segment_query(pA, pB);
my_tree->do_intersect(segment_query); // here sometimes crashes
Before anybody asks pointB is a specific point on the surface of the mesh and it does not give any problems with most of points so I would assume the error is not related to it. Instead pointA is somewhere in the space.
Thank you for you answers.

Does CGAL 3D mesh generation require condition except closed manifold?

I'm trying to triangulate given coronary artery model(please refer image and file).
At first, I've tried to triangulate them using 3D constrained Delaunay triangulation in TetGen engine, but it appears that TetGen didn't generate them in all time. I've tried about 40 models with closed boundary, but only half of them was successful.
As an alternative, I found that CGAL 3D mesh generation will generate similar mesh based on Delaunay triangulation(of course, it's different from 3D constrained Delaunay triangulation).
I also tested it for 40 models which is same dataset used in TetGen test, but it appears that only 1/4 of them were successful. It is weird because even less models were processed than in TetGen test.
Is there are any condition for CGAL mesh generation except closed manifold condition(no boundary & manifold)? Here is the code I've used in my test case. It is almost same to example code from CGAL website.
// Create input polyhedron
Polyhedron polyhedron;
std::ifstream input(fileName.str());
input >> polyhedron;
// Create domain
Mesh_domain domain(polyhedron);
// Mesh criteria (no cell_size set)
Mesh_criteria criteria(facet_angle = 25, facet_size = 0.15, facet_distance = 0.008,
cell_radius_edge_ratio = 3);
// Mesh generation
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria, no_perturb(), no_exude());
findMinAndMax();
cout << "Polygon finish: " << c3t3.number_of_cells_in_complex() << endl;
Here is one of CA model which was used in test case.
The image of CA model
Also, I want to preserve given model triangles in generated mesh like constrained Delaunay triangulation. Is there are any way that generate mesh without specific criteria?
Please let me know if you want to know more.
The problem is that the mesh generator does not construct a good enough initial point set. The current strategy is to shoot rays in random directions from the center of the bounding box of your object. Alternatively one might either take a random sample of points on the surface, or random rays shot from the points on the skeleton. I've put you a hacky solution on github. The first argument is your mesh, the second the grid cell size in order to sample points on the mesh.

Cutting an open Polyhedron3 with another open Polyhedron3

Given 2 open Polyhedron3 made of triangles in CGAL, I want to cut the first one with the second one. That is, all intersecting triangle facets from poly2 should cut facets from poly1 and create new edges (and faces) in poly1 following the path of intersection. In the end, I need the list of edges/half edges which are part of the intersection path.
I'm using a typedef CGAL::Simple_cartesian Kernel.
While this looks like a boolean operation, it's not because there's no 'inside' or 'outside' for open meshes. The way I tried to implement it is:
build an AABB for mesh 1 (to be cut)
find intersecting faces from mesh1 cut by the first triangle of mesh 2
compute intersection infos using cgal : this returns the intersection description, but with some problems:
cgal will sometimes return 'wrong' intersections (for exemple, segments of 0 length)
the first mesh is not cut in the operation. Given the intersection description, I have to cut triangles myself (unless there's a function I've overlooked in cgal to cut a face/triangle given an intersection). This is not a trivial problem, as there are lots of corner cases
repeat with next face of poly2
My algorithm sorts of works, but I sometimes have problems : path not closed, small numerical accuracy problem, and it's not very fast.
So here's (at last) my question : what would be the recommended way to implement such an operation in a robust way ? Which kernel would you recommend?
Following sloriot comment, I've spent some time playing with the code of the CGAL polyhedron demo. Indeed it contains a plugin corefinement which does what I want. I've not finished integrating all changes in my own code base but I believe I can mark this question as answered.
All thanks to SLoriot for his suggestion!
Pascal

Reconstruct surface from 3D triangular meshes

I have a 3D model, which consists of the 3D triangular meshes. I want to partition the meshes into different groups. Each group represents a surface, such as a planar face, cylindrical surface. This is something like surface recognition/reconstruction.
The input is a set of 3D triangular meshes. The output is the mesh segmentations per surface.
Is there any library meets my requirement?
If you want to go into lots of mesh processing, then the point cloud library is a good idea, but I'd also suggest CGAL: http://www.cgal.org for more algorithms and loads of structures aimed at meshes.
Lastly, the problem you describe is most easily solved on your own:
enumerate all vertices
enumerate all polygons
create an array of ints with the size of the number of vertices in your "big" mesh, initialize with 0.
create an array of ints with the size of the number of polygons in your "big" mesh, initialize with 0.
initialize a counter to 0
for each polygon in your mesh, look at its vertices and the value that each has in the array.
if the values for each vertex are zero, increase counter and assign to each of the values in the vertex array and polygon array correspondingly.
if not, relabel all vertices and polygons with a higher number to the smallest, non-zero number.
The relabeling can be done quickly with a look up table.
This might save you lots of issues interfacing your code to some library you're not really interested in.
You should have a look at the PCL library, it has all these features and much more: http://pointclouds.org/

Retrieve index of nearest surface-points returned from CGAL's surface_neighbor_coordinates_3

I (relatively new to CGAL and not a C++ expert) am trying to extract the index of the nearest-neighbor 3D points returned from CGAL's surface_neighbor_coordinates_3 (which searches a 2D mesh comprised of 3D points to find natural-neighbors of a provided query-point) in this CGAL example. In other examples (3D interpolation with 3D meshes), I have been able to do this by adding info to vertex handles in the triangulation data structure. In the linked example, I simply wish to retrieve the indices of returned coords with respect to where the points in coords reside index-wise within the input list of points.
The other call-options for surface_neighbor_coordinates_3 seem to suggest this may be possible by passing-in an existing triangulation (with perhaps its info-augmented triangulation-data-structure). However, I'm not sure how to specify the info-augmented Delaunay_triangulation_3 for the case of a 2D mesh consisting of 3D points. I'm experimenting with it (using advancing-front triangulations to 2D-mesh my 3D points) but would like to know if there's some easier way to use the native capabilities of surface_neighbor_coordinates_3 if one only seeks to also have an info field associated with the returned points.
Any help would be greatly appreciated ... this has stumped me for a week.