CGAL - Boost create undirected graph - c++

I've created a 3D Volume mesh using Cgal's documentation and I was succesfully able to visualize my c3t3 (Complex 3 in triangulation 3) object. The mesh is composed of several connected components the number of which i want to find using boost.
Dealing with c2t3 (cimplex 2 in triangulation 3) in the past i iterated over the vertices of the, make pairs with a vertex_descriptor and then again iterate over the edges finding the vertices and by using add_edge i created the undirected graph and finally return the number of c.c.
Now, the c3t3 object only provides iterators about vertices nad cells (not edges - only can be implicitly found). Can you help me pass the c3t3 object to a graph structure of Boost?
So far i did:
for (Cell_iterator c_it=c3t3.cells_in_complex_begin(); c_it != c3t3.cells_in_complex_end(); ++c_it)
{
Vertex_descriptor vd1 = boost::add_vertex(graph);
Vertex_descriptor vd2 = boost::add_vertex(graph);
Vertex_descriptor vd3 = boost::add_vertex(graph);
Vertex_descriptor vd4 = boost::add_vertex(graph);
C3t3::Vertex_handle v0 = c_it->vertex(0);
C3t3::Vertex_handle v1 = c_it->vertex(1);
C3t3::Vertex_handle v2 = c_it->vertex(2);
C3t3::Vertex_handle v3 = c_it->vertex(3);
vertex_id_map.insert(std::make_pair(v0, vd1));
vertex_id_map.insert(std::make_pair(v1, vd2));
vertex_id_map.insert(std::make_pair(v2, vd3));
vertex_id_map.insert(std::make_pair(v3, vd4));
}
Now i have to create the edges but i don;t know where to find the correct edges correspond to my c3t3 object.. Thank you for your help in advance

CGAL provides "Boost Graph adapters" for many of its classes (at least for triangulations, arrangements and for polyhedral surfaces). See more details in CGAL BGL page.
Essentially all DCEL- or similar structures can be viewed as a combination of two graphs, "primary" for vertex-edge relationships and "dual" for cell-edge relationships; CGAL provides Boost graph adapters for both.
If this out-of-box graphs are not good for you, than you have to answer your central question: how do you iterate over edges of a given cell (i.e. over edges of the "dual" graph) or over edges of a given vertex (i.e. over edges of the "primal" graph).

Related

Find all neighbours of a certain primitive in a CGAL::Surface_mesh

I wrote a small raytracer (with CGAL::Surface_mesh Mesh) with tree acceleration in cgal. I would like to find all neighbours of a hit primitive.
Ray_intersection hit = tree.first_intersection(rays[y][x]);
if(hit)
{
const Point& point = boost::get<Point>(hit->first);
const Primitive_id& primitive_id = boost::get<Primitive_id>(hit->second);
//i need the neighbours of the hit primitive
}
How do I this? I found this documentation but it seems to work only for points not primitives:
https://doc.cgal.org/latest/Spatial_searching/index.html
And it searches for its euclidan distance not for being connected together.
Is there something like:
std::vector<Primitive_id&> ids = getNeighoursOfPrimive(primitive_id);
Like I said I am using CGAL::Surface_mesh Mesh for my mesh and their is only one mesh in the scene.
You can use the range returned by vertices_around_face() to get all vertices of a face, then for each vertex you can use the range returned by halfedges_around_target() to get one halfedge per face incident to that vertex (or you can do it by hand using a combinaison of next and opposite).

boost Kamada-Kawai spring layout vertices collision

I'm trying to layout a graph using boost Kamada-Kawai-spring-layout algorithm.The problem is that vertices collide with each other in some graphs.I add all edges with weight 1.0
add_edge(a,b,1.0,g);
then I layout the graph like this :
minstd_rand gen;
topology_type topo(gen,0,0,widht,height);
random_graph_layout(g,position,topo);
bool kamada=kamada_kawai_spring_layout(g,position,get(edge_weight,g),topo,side_length(width),kamada_kawai_done());
Some graphs work fine while other produce output like this
I think the layout is fine but the length of edges need to be increased but i don't know how
You can used boost::edge_length(e) instead of boost::side_length(s) in order to control the edge length on the graph
bool kamada=kamada_kawai_spring_layout(g,position,get(edge_weight,g),topo,boost::edge_length(length),kamada_kawai_done());

CGAL Scale-Space reconstruction with normals and colors

I am using CGAL for point cloud processing, and generating mesh out of it using Scale-Space reconstruction.
I recently require to save color and normal information. So, I used boost::tuple(Point_3, Vector_3, CGAL::Color) for filters: simplification, outlier removal and normal estimations/orientation. Now triangulating the cloud using Scale-Space reconstruction is only accepting vector of points, not the tuple I have created.
typedef CGAL::Scale_space_surface_reconstruction_3< Kernel > Reconstruction;
Reconstruction reconstruct;
reconstruct.insert( points.begin(), points.end());
//Error if points is defined as vector<PointNormalColorTuple>
//Works if points are vector<Point_3>
//There is no parameter in insert and reconstruct_surface, where I can define property map:
//CGAL::Nth_of_tuple_property_map<0,PointNormalColorTuple>()
I cannot copy data in a new vector<Point_3> as color information will be lost.
Any suggestions would be helpful.

To implement FlannBasedMatcher

I am doing a project on face recognition from video images.I extracted the features,now I need to compare the feature.So I found FlannBasedMatcher is a good method, also it is very fast.FlannBasedMatcher is already in the opencv (I am using opencv),but like to implement it myself with out any opencv help.Please help me to find what is exactly happening inside FlannBasedMatcher.Any response will be greatly appreciated.
Features are typically compared using some distance metrics such as Euclidian distance between features that are considered to be points in some multi-demnsional space; one can use the angle between two vectors (that is feature vectors) that is independent of vector scaling; one can use a Humming distance for comparing binary strings, etc. The best way depends on the structure and the meaning of your feature vector. For faces it can be an angle between two vectors expressed through a dot product.
Now, flann is used for finding nearest neighbors and as such is not directly related to feature comparison though it can help to speed up finding similar features that are worth comparison (flann=fast library for nearest neighbors). Thus you won’t need to search through all your vectors trying to select the one that has highest dot product with the query vector, but instead directly compare a given face (vector) with just a few closest faces (vectors).
Finally, addressing a previous answer, in some cases one can use sparse arrays instead of KD trees. They are part of openCV too but can be implented through hash tables or trees. In sparse arrays you can check indices of neighboring elements which is analogous to flann nearest neighbors. Of course, sparse arrays are more limited than flann - for example, they require an exhaustive search in the neighborhood to get a nearest neighbors list but this is still faster than global search. Here is an example:
int dims = 3;
int sz[] = {1000, 1000, 1000}; // memory efficient
SparseMat M3d(dims, sz, CV_32F);
Point3i idx_sparse;
Vec3f p;
//set the element of a sparse 3D Mat
M3d.ref<Vec3f>(idx_sparse.x, idx_sparse.y, idx_sparse.z) = p;
// iterate
SparseMatIterator it = M3d.begin();
SparseMatIterator it_end = M3d.end();
for (; it != it_end; ++it) {
// access existing element through iterator
Vec3f vec = it.value<Vec3f>();
// check neighbors if they exist
int* idx = it.node()->index;
idx[0]++; idx[1]--; idx[2]+=2;
if (M3d.find(idx) != M3d.end()) {
Vec3f vec = M3d.ref<Vec3f>(idx);
}
}
It is not that easy. You have to implement kd-tree with aproximated nearest neighbor search. It is described in paper "An Optimal Algorithm for Approximate Nearest
Neighbor Searching in Fixed Dimensions" by Arya et al.
If you don`t want to do it from the scratch and just want to get rid of OpenCV, you can take original FLANN implementation.

Kruskal's algorithm explanation

I was reading wikipeida and found Kruskal's Pseudocode as the following:
KRUSKAL(G):
foreach v ∈ G.V:
MAKE_SET(v)
G.E = sort(G.E)
i = 0
while (i != |V|-1):
pick the next (u, v) edge from sorted list of edges G.E
if (FIND_SET(u) != FIND_SET(v)):
UNION(u, v)
i = i + 1
I'm not quiet sure what FIND_SET() does, and Wikipedia has the follow description:
if that edge connects two different trees, then add it to the forest, combining two trees into a single tree.
So I guess it checks if two different trees are connected, but what does this really mean?
Initially, each vertex is in a set all by itself: There is a singleton set {v} for every vertex v. In the pseudo-code, these sets are the result of make_set(v).
For a given vertex v, the function find_set(v) gives you the set containing v.
The algorithm merges sets iteratively, so if {u}, {v} are singleton sets initially and there is an edge (u, v), then the algorithm replaces the two sets by their union {u, v}. Now both find_set(u) and find_set(v) will return that set.
The algorithm terminates after you've added |V| - 1 non-trivial edges, which is precisely the number of edges in a tree.
The find_set() is a common operation of a kind of data structure known as Union-Find. The idea of this data structure is to have disjoint sets (of vertex in your example).
In this algorithm I think that each set represents vertex that are connected.
So when you call find_set() passing a vertex, you will receive the element that represents that set of connected verxtex.
FIND_SET(x) finds the set associated with edge x, so that the comparison:
FIND_SET(u) != FIND_SET(v)
Ensures that u and v are not connected to the same thing. A useful way of thinking about it is that it finds the "values" of u and v where the values are in themselves sets.
The part about merging the forests has nothing to do with FIND_SET, but rather the next line:
UNION(u,v)
Which merges the two sets.
find_set(u)!=find_set(v)
signifies the basic property of spanning tree that is it does not make cycles.If they are equal then it shows there is a cycle in graph.
We basically make a forest (of minimum edge weights) through Kruskal algorithm and at each step checks whether it is making cycle or not.
Hope it helps :)