Is there any C++ library (for Linux) for repairing the non-manifold meshes and converting it to manifold geometry? - mesh

I have the segmentation results from one algorithm, however, the generated triangle surface is not manifold geometry. I am asking this question here if there is any C++ library that can be used for converting the non-manifold geometry to manifold surfaces?
PS, I have already cleaned the result by filling the holes, but it seems that there are still some non-smoothed parts and holes.
Thanks

If there is any C++ library that can be used for converting the non-manifold geometry to manifold surfaces?
Yes, there is CGAL, the Computational Geometry Algorithms Library.
In CGAL, a polygon mesh is considered to have the topology of a 2-manifold.
And when the faces of a polygon mesh are given but the connectivity is unknown, this set of faces is called a polygon soup. That is to say, all the triangles of your surface will be treated separately.
To convert a non-manifold surface into manifold, you can first load your data into a polygon soup.
Then convert it into a polygon mesh using the function polygon_soup_to_polygon_mesh. The following code snippet from CGAL gives an example:
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Polyhedron_3<K, CGAL::Polyhedron_items_with_id_3> Polyhedron;
std::ifstream input(filename);
std::vector<K::Point_3> points;
std::vector<std::vector<std::size_t> > polygons;
if(!input || !CGAL::read_OFF(input, points, polygons) || points.empty())
{
std::cerr << "Cannot open file " << std::endl;
return EXIT_FAILURE;
}
CGAL::Polygon_mesh_processing::orient_polygon_soup(points, polygons);
Polyhedron mesh;
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, polygons, mesh);
Or you can try to repair the surface mesh as depicted in here.

Related

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

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.

CGAL static AABB tree to intersect many spheres with rays

I would like to use CGAL's AABB Tree to compute intersection between many static spheres and rays. I am fairly new to CGAL and might need some guidance.
As there does not seem to be direct support for spheres in the AABB tree, I think need to complement the functionality by creating AABB_sphere_primitive. Is that the only thing that is needed to get something like AABB_tree/AABB_triangle_3_example.cpp, with spheres instead of triangles? Do I need to also define an analogue of Point_from_triangle_3_iterator_property_map?
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;
typedef K::Point_3 Point;
typedef K::Plane_3 Plane;
typedef K::Sphere_3 Sphere; // <-- this is done already
typedef std::list<Sphere>::iterator Iterator;
typedef CGAL::AABB_sphere_primitive<K,Iterator> Primitive; // <---- must be defined newly
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Tree;
The routine for intersection between sphere and ray is already implemented somewhere (Spherical_kernel_intersections.h?) and will be used?
Thanks for pointers.
You need to provide a new primitive type that is a model of the concept AABBPrimitive. Basically you can copy/paste the implementation of CGAL::AABB_triangle_primitive and adapt it to the case of a sphere.
The next tricky part is to provide the intersection predicate for a ray and a sphere as required by the AABBTraits concept.
If you are not looking for exact predicates, you can simply using the distance of the center of the sphere to the support line of the ray + the direction of the center of the sphere with reference to the source of the ray.
If you want exact predicates, the class Filtered_predicate can help you make your predicate robust.

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.

CGAL 3D Delaunay Triangulation - First Vertex is Origin?

I am performing a 3D Delaunay Triangulation of points sampled from a sphere, and I am looking at the vertices of the resultant triangulation essentially by doing this:
for(Delaunay_Vertex_iter p = T.vertices_begin(); p != T.vertices_end(); p++){
std::cout << p->point() << endl;
}
While T.number_of_vertices() == 270, I get 271 vertices, the first one being the origin (0, 0, 0). Why?
This is the infinite vertex, which has unspecified coordinates and happens to be the origin here. You should iterate using finite_vertices_begin()/finite_vertices_end() instead.
See http://doc.cgal.org/latest/Triangulation_3/ for information about the infinite vertex.
This can well happen, since floating point numbers are inherently NOT exactly on unit spheres. Hence, the data type or your kernel and the proximity of your sampling affects the results.
You can use CGAL's spherical kernel for the 3D case or the implementation described in:
https://stackoverflow.com/a/45240506/4994003
to avoid precision issues for the general dD case.

Triangulating Polyhedron faces in CGAL

Having an arbitrary polyhedron in CGAL (one that can be convex, concave or, even, have holes) how can I triangulate its faces so that I can create OpenGL Buffers for rendering?
I have seen the convex_hull_3() returns a polyhedron that has triangulated faces, but it won't do what I want for arbitrary polyhedrons.
The header file <CGAL/triangulate_polyhedron.h> contains a non-documented function
template <typename Polyhedron>
void triangulate_polyhedron(Polyhedron& p)
that is working with CGAL::Exact_predicates_inexact_constructions_kernel for example.
The Polygon Mesh Processing package provides the function CGAL::Polygon_mesh_processing::triangulate_faces with multiple overloads. The simplest thing to do would be
typedef CGAL::Simple_cartesian<float> Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron_3;
Polyhedron_3 polyhedron = load_my_polyhedron();
CGAL::Polygon_mesh_processing::triangulate_faces(polyhedron);
After that, all faces in polyhedron are triangles.
The function modifies the model in-place, so one has to use a HalfedgeDS that supports removal. This is the default, but, for example, HalfedgeDS_vector won't do.
See also an official example that uses Surface_mesh instead of Polyhedron_3:
Polygon_mesh_processing/triangulate_faces_example.cpp