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
Related
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.
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.
I am using periodic Delaunay triangulation in CGAL in my code, and producing for each vertex all neighboring vertices. For this I use Edge iterator, since in my case it will be much more faster than Vertex iterator.
Here is the code snippet,
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Periodic_2_triangulation_traits_2<Kernel> Gt;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned int, Gt> Vb;
typedef CGAL::Periodic_2_triangulation_face_base_2<Gt> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
typedef CGAL::Periodic_2_Delaunay_triangulation_2<Gt, Tds> Triangulation;
typedef Triangulation::Iso_rectangle Iso_rectangle;
typedef Triangulation::Edge_iterator Edge_iterator;
typedef Triangulation::Vertex_handle Vertex_handle;
typedef Triangulation::Point Point;
typedef vector<pair<Point, unsigned> > Vector_Paired;
Vector_Paired points;
Iso_rectangle domain(0,0,L,L);
for(int iat = 0; iat < N; iat++)
{
points.push_back(make_pair(Point(r_tot[iat][0],r_tot[iat][1]),iat));
}
Triangulation T(points.begin(), points.end(), domain);
for(Edge_iterator ei=T.finite_edges_begin(); ei!=T.finite_edges_end(); ei++)
{
Triangulation::Face& f = *(ei->first);
int ii = ei->second;
Vertex_handle vi = f.vertex(f.cw(ii));
Vertex_handle vj = f.vertex(f.ccw(ii));
int iat = vi->info();
int jat = vj->info();
VecInd[iat].push_back(jat);
VecInd[jat].push_back(iat);
}
But, sometimes instead of one special neighbors for each vertex I get 8 or 9 or ... copy of the same neighbor.
For example in VecInd which is a 2D vector containing neighboring indices I get some thing like this:
VecInd[0]=[2,2,2,2,4,4,4,...]
I couldn't find an example using edge iterator in CGAL website, and nothing related in stackoverflow.
I am wondering whether this implementation is correct? What should I add to my code in order to get one copy per each neighbor, I can use STL::sets, but I would like to know the source of problem.
Here is the answer that was posted on the CGAL-discuss mailing-list, by Mael:
If your point set is not geometrically well spaced, it's possible that the triangulation of these points do not form a simplicial complex over the flat torus (in other words, there are short cycles in the triangulation). In this case, the algorithm uses 8 copies of the triangulation to artificially create a simplicial complex. You can check if this is the case using the function is_triangulation_in_1_sheet() and read more about these mechanisms in the User Manual.
When copies are being used, iterating over the edges will indeed give you exactly what the underlying data structure has : 9 entities for each edge. To get unique ones, you can simply filter 8 out of the 9 by looking at the offset of the vertices of the edge. This is what is done in the iterator that returns unique periodic segments. Unfortunately, you want edges and this iterator converts directly to the geometry of the edge (the segment). Nevertheless, you can simply use the main filtering function from that iterator, that is: is_canonical(). This function will look at the offset of the two vertices of your edges, and keep only those that have at least one vertex in the first copy of the domain, which is enough to make it unique.
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.
I'm trying to implements projection, using a vertex shader.
Is there a way to have a separate vertex shader to handle set the gl_Position, and having another vertex shader to set the values required for the fragment shader?
The problem I have it that only the main() function of the first vertex shader is called.
Edit:
I found a way to make it work, by combining the shader sources instead of using multiple independant shaders. I'm not sure if this is the best way to do it, but it seems to work nicely.
main_shader.vsh
attribute vec4 src_color;
varying vec4 dst_color; // forward declaration
void transform(void);
void main(void)
{
dst_color = src_color;
transform();
}
transform_2d.vsh
attribute vec4 position;
void transform(void)
{
gl_Position = position;
}
Then use it as such:
char merged[2048];
strcat(merged, main_shader_src);
strcat(merged, transform_shader_src);
// create and compile shader with merged as source
in OpenGL ES, the only way is to concatenate shader sources, but in OpenGL, there are some interesting functions that allow you to do what you want:
GL_ARB_shader_subroutine (part of OpenGL 4.0 core)
- That does pretty much what you wanted
GL_ARB_separate_shader_objects (part of OpenGL 4.1 core)
- This extension allows you to use (mix) vertex and fragment shaders in different programs, so if you have one vertex shader and several fragment shaders (e.g. for different effects), then this extensions is for you.
I admit this is slightly offtopic, but i think it's good to know (also, might be useful for someone).