Point Set Shape Detection: save planar shapes to file - cgal

Although I don't know how to write C++ I am trying to use CGAL for trying to derive building shapes from LiDAR point clouds using Point Set Shape Detection. Using the examples I can read points and normals from a file, whereupon CGAL detects shapes. The program is set to detect only planar shapes.
I would like to save the planar shapes to a file, so that I can use them in other software. But I was unable to find examples of how that can be achieved. The test program I use is based on the efficient_RANSAC_parameters.cpp code. It has a part when it iterates through all detected shapes. Could it be possible to add something there that will write the planar shapes to a file? I see the OFF format is a popular and simple way (in CGAL) to save polygons to a file, so that could be a good candidate file format.

A colleague who does know how to write C++ has helped me with this problem. He came up with the following:
while (it != shapes.end()) {
if (Plane* plane = dynamic_cast<Plane*>(it->get()))
{
std::cout << "PLANE_" << count++ << "[" << std::endl;
const std::vector<size_t> indices = it->get()->indices_of_assigned_points();
std::vector<size_t>::const_iterator iti = indices.begin();
while (iti != indices.end()) {
// Retrieves point
Point_with_normal pw = *(points.begin() + (*iti));
Kernel::Point_3 p = pw.first;
std::cout << "POINT[" << p.x() << "," << p.y() << "," << p.z() << "]" << std::endl;
// Proceeds with next point.
iti++;
}
std::cout << "]" << std::endl;
}
// Proceeds with next detected shape.
it++;
}
This block can replace loop in the efficient_RANSAC_parameters.cpp example. The output looks like this:
PLANE_0[
POINT[34.96,584.49,0.47]
POINT[34.97,585.24,0.54]
POINT[34.88,584.51,0.49]
POINT[34.98,584.75,0.49]
]
That gives me something to work with. In my case, I use sed to transform this output to SQL insert queries that allow me to transfer the data to a relational database for further processing.

In the example in the user manual you can see that once you have a plane shape object
if(Plane* plane = dynamic_cast<Plane*>(it->get())){..} you can obtain from the plane shape object a CGAL::Plane_3, from which you can obtain a point and a normal, or the coefficients of the plane.

Related

[cgal]; 3D Delaunay Triangulation

I'm trying to do a 3D Delaunay Triangulation and I need to obtain the circumcenters of this triangulation. I've done it this way:
typedef CGAL::Delaunay_triangulation_3<K, Tds> Triangulation;
// Construct the triangulation in parallel
Triangulation T(V.begin(), V.end());
assert(T.is_valid());
centros.open("centros.txt");
//With this I would obtain the circumcenters of the triangulation?:
for (Triangulation::Finite_cells_iterator it = T.finite_cells_begin(); it != T.finite_cells_end(); it++)
{
cout << it->circumcenter() << " / " << T.dual(it) << endl;
}
However, I obtain centers way too far from my initial points, so I'm doubting if this is the correct way of obtainint the circumcenters of the spheres. Any help? Thanks.
Note that the circumcenter is not necessarily inside the tetrahedron. This is especially true if you have some elements that are well shaped.
See the following 2D Delaunay Triangulation of 4 points and the corresponding circumcircles:

Custom Delaunay Refinement with CGAL Delaunay3D

I want to perform a custom refinement strategy in a tetrahedral mesh.My input is a point cloud and I have tetrahedralized it using Delaunay 3D routine available in CGAL. The points have scalar values associated with it. Now I want to refine the tetrahedral mesh with this following strategy:
1. Get the maximum value among the vertices of each tetrahedra.
2. Get the value at the point that is going to be inserted (May be barycentre, weighted centroid or circumcenter).
3. If the difference is large enough add this point.
Any idea how to do this effectively? Note: I do not require 0-1 dimensional feature preservation.
I have already tried the above strategy. Let me show what I have done so far.
// Assume T is Delaunay_3D triangulation CGAL mesh and I have an oracle f that tells me what is the value at the point that is going to be inserted if conditions are met.
bool updated = true;
int it = 0;
while (updated)
{
updated = false;
std::vector<std::pair<Point, unsigned> > point_to_be_inserted;
for (auto cit = T.finite_cells_begin(); cit != T.finite_cells_end(); cit++)
{
Cell_handle c = cit;
Point v = Maximum valued vertex
Point q = Point that is going to be inserted
double val_at_new_pt = oracle(q, &pts, var);
double ratio = std::abs(max_val - val_at_new_pt) / max_val;
if (ratio > threshold) {
point_to_be_inserted.emplace_back(std::make_pair(q, new_pt_ind));
updated = true;
}
}
if (updated)
{
std::cout << "Total pts inserted in it: " << it << " " << point_to_be_inserted.size() << std::endl;
T.insert(point_to_be_inserted.begin(), point_to_be_inserted.end())
}
}
The problem is it is quite slow (each time iterating through all the cells). I am not finding any effective strategy to do the refinement locally. I tried using a queue but the cell_handles are getting messed up after I perform one iteration of refinement. I cannot have a map that tells me whether the tetrahedra is refined or not because each time after insertion of new points cell_handles are getting created. Any help will be appreciated. Thanks in advance.

How to access to the informations related to the facets of a convex hull in a dD triangulation?

I am rewriting codes that were using the class CGAL::Convex_hull_d, that is now deprecated. My need is to compute dynamically the convex hull of a set of points, and next to access to a a point and the normal of each facet.
The way to traverse the facets of a convex hull obtained by a triangulation is perfectly clear in the documentation, the problem is next to access to the informations related to the facets.
For the three-dimensional case, I have used the class CGAL::Delaunay_triangulation_3. After inserting points in the triangulation (called T), it is possible to obtain the convex hull using the CGAL::Surface_mesh class and the function CGAL::convex_hull_3_to_face_graph. Next, we can use facet iterators to traverse the facets, and next vertex iterators to access to the vertices of a facet. There is also a direct access to the normal to a facet using the function CGAL::Polygon_mesh_processing::compute_face_normal. This is described by the following portion of code.
Surface_mesh chull;
CGAL::convex_hull_3_to_face_graph(T,chull);
Surface_mesh::Face_range mesFaces = chull.faces();
Surface_mesh::Face_range::iterator debut,fin;
CGAL::Vertex_around_face_iterator<Surface_mesh> vbegin,vend;
debut = mesFaces.begin();
fin = mesFaces.end();
while(debut != fin)
{
Vector_3 p = CGAL::Polygon_mesh::compute_face_normal(*debut,chull);
std::cout << "Normal to the facet: (" << p[0] << "," << p[1] << "," << p[2] << ")" << std:endl;
boost::tie(vbegin,vend) = vertices_around_face(chull.halfedge(*debut),chull);
Point_3 po = chull.point(*vbegin);
std::cout << "One point of the facet: (" << po[0] << "," << po[1] << "," << po[2] << ")" << std:endl;
debut++;
}
However, the classes CGAL::Delaunay_Triangulation_3 and CGAL::Surface_mesh class cannot be used to compute the convex hull of a set of points with 4 dimensions. I have therefore considered the (recommended) use of dD Triangulation (in particular, the class CGAL::Triangulation). To traverse the facets of the convex hull is not a problem as a two full examples are given in the documention. Below, the first one is given.
{ int i=0;
typedef Triangulation::Full_cell_iterator Full_cell_iterator;
typedef Triangulation::Facet Facet;
for( Full_cell_iterator cit = t.full_cells_begin();cit != t.full_cells_end(); ++cit )
{
if( ! t.is_infinite(cit) )
continue;
Facet ft(cit, cit->index(t.infinite_vertex()));
++i;// |ft| is a facet of the convex hull
}
std::cout << "There are " << i << " facets on the convex hull."<< std::endl;
}
Here, the Facet ft is created but not used, the facets are only counted. I have not found a way to access to any information related to the facet in the documentation. My need would be the same as for the three-dimensional case.

How do I iterate through all the faces in a CGAL StraightSkeleton_2 / HalfedgeDS?

My goal is to take a polygon, find the straight skeleton, then turn each face into its own polygon.
I'm using the CGAL Create_straight_skeleton_2.cpp example as a starting point. I'm able to have it compute the skeleton and can iterate through the faces:
SsPtr iss = CGAL::create_interior_straight_skeleton_2(poly);
for( auto face = iss->faces_begin(); face != iss->faces_end(); ++face ) {
// How do I iterate through the vertexes?
}
But with a HalfedgeDSFace it looks like I can only call halfedge() for a HalfedgeDSHalfedge.
At that point I'm confused how to iterate through the vertexes in the face. Do I just treat it like a circular linked list and follow the next pointer until I get back to face->halfedge()?
Here's my first attempt at treating it like a circular linked list:
SsPtr iss = CGAL::create_interior_straight_skeleton_2(poly);
std::cout << "Faces:" << iss->size_of_faces() << std::endl;
for( auto face = iss->faces_begin(); face != iss->faces_end(); ++face ) {
std::cout << "Faces:" << iss->size_of_faces() << std::endl;
std::cout << "----" << std::endl;
do {
std::cout << edge->vertex()->point() << std::endl;
edge = edge->next();
} while (edge != face->halfedge());
}
But that seems to put an empty vertex in each face:
Faces:4
----
197.401 420.778
0 0
166.95 178.812
----
511.699 374.635
0 0
197.401 420.778
----
428.06 122.923
0 0
511.699 374.635
----
166.95 178.812
0 0
428.06 122.923
So the iteration is much as I'd expected:
// Each face
for( auto face = iss->faces_begin(); face != iss->faces_end(); ++face ) {
Ss::Halfedge_const_handle begin = face->halfedge();
Ss::Halfedge_const_handle edge = begin;
// Each vertex
do {
std::cout << edge->vertex()->point() << std::endl;
edge = edge->next();
} while (edge != begin);
}
The reason it wasn't working was the contour polygon I was using had a clockwise orientation. Once I reversed the order of the points I started getting valid data out of the faces.
For reference here's how you'd iterate over the vertexes in the contour:
// Pick a face and use the opposite edge to get on the contour.
Ss::Halfedge_const_handle begin = iss->faces_begin()->halfedge()->opposite();
Ss::Halfedge_const_handle edge = begin;
do {
std::cout << edge->vertex()->point() << std::endl;
// Iterate in the opposite direction.
edge = edge->prev();
} while (edge != begin);

writing output to a file in Graphchi

I wrote a shortest path code in Graphchi and I wanted to print the output of that in a file. I was trying to use the template shown in the examples but I get error if I use the sameway of writing to a file as in other examples.
I have got stuck here. As the output I just want to print (vertex id,its minimum distance from source).
How can i do that.
Here is example how you can output values of all vertices to the console. It is easy to modify it to write the output to a file. Note that if you can handle binary files, GraphChi already has the vertex values in a file: .B.vout, where is sizeof(VertexDataType).
1) You need to define a callback-function, which will take vertex id and value as parameter
class OutputVertexCallback : public VCallback<VertexDataType> {
public:
virtual void callback(vid_t vertex_id, VertexDataType &value) {
std::cout << vertex_id << "=" << value << std::endl;
}
};
2) Then you need to call foreach_vertices() as follows to get the output:
OutputVertexCallback callback;
foreach_vertices<VertexDataType>(filename, 0, engine.num_vertices(), callback);