How to get the remaining triangles after 2D alpha shape using CGAL? - cgal

From the CGAL documentation, one can create an alpha_shape_2 from a Delaunay triangulation:
CGAL::Alpha_shape_2< Dt, ExactAlphaComparisonTag >::Alpha_shape_2(Dt& dt, FT alpha = 0, Mode m = GENERAL)
However the operation destroys the triangulation.
In my problem I have a bunch of points which are triangulated. I need to identify the "right" triangles using the alpha shape algorithm. I already computed that myself from the delaunay triangulation (computing the circumcircle radius myself and so on), since I did not find a way to extract the remaining triangles from alpha_shape_2 (I can extract the edges of the alpha shape but not the inner triangles). Is it only possible using CGAL ?
For example in matlab (ouch) one can do:
shp = alphaShape(points.x,points.y);
shp.Alpha = alpha;
tri = alphaTriangulation(shp);
bf = boundaryFacets(shp);
Side question: what is the definition of the alpha value of cgal ? Mine is : r_c/h>alpha, where r_c is the triangle circumcircle radius and h and size parameter?

For the side question see this section. About your initial question I'm not sure to understand precisely what you want to get but you can iterate all the triangles and get their classification using the following code:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Alpha_shape_2.h>
#include <CGAL/Alpha_shape_vertex_base_2.h>
#include <CGAL/Alpha_shape_face_base_2.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_2 Point;
typedef CGAL::Alpha_shape_vertex_base_2<K> Vb;
typedef CGAL::Alpha_shape_face_base_2<K> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> Tds;
typedef CGAL::Delaunay_triangulation_2<K,Tds> Triangulation_2;
typedef CGAL::Alpha_shape_2<Triangulation_2> Alpha_shape_2;
int main()
{
std::vector<Point> points;
double alpha;
Alpha_shape_2 A(points.begin(), points.end(),
alpha,
Alpha_shape_2::GENERAL);
for (Alpha_shape_2::Finite_faces_iterator fit=A.finite_faces_begin();
fit!=A.finite_faces_end();++fit)
{
switch(A.classify(fit))
{
case Alpha_shape_2::REGULAR:
break;
case Alpha_shape_2::SINGULAR:
break;
case Alpha_shape_2::EXTERIOR:
break;
case Alpha_shape_2::INTERIOR:
break;
}
}
return 0;
}

Related

Constrained Delaunay with Info

I have this setup:
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_with_info_2<FIntPoint, K> Vb;
typedef CGAL::Constrained_triangulation_face_base_2<K> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
typedef CGAL::Exact_predicates_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds, Itag> Delaunay;
typedef Delaunay::Point Point;
typedef Delaunay::Vertex_handle VertexHandle;
FIntPoint is a struct with 2 integers.
My vertices belong to border triangles of 2 separate terrain-like 3D meshes. I triangulate these vertices in 2D to connect these meshes. The info I need for each vertex is (1) which mesh it belongs to and (2) its vertex index within that mesh, so that I know where this vertex came from after triangulation, as more information is tied to these indices.
In this illustration, you can see the 2 meshes and their border triangles. I want to stitch these together:
This is basically how I insert points, simplified:
Delaunay Triangulation;
for (...)
{
// Insert a triangle from one of my meshes
VertexHandle vh1 = Triangulation.insert(Point(a.Y, a.Z));
vh1->info() = FIntPoint(iA, iM);
VertexHandle vh2 = Triangulation.insert(Point(b.Y, b.Z));
vh2->info() = FIntPoint(iB, iM);
VertexHandle vh3 = Triangulation.insert(Point(c.Y, c.Z));
vh3->info() = FIntPoint(iC, iM);
// Add constraints to keep this triangle exactly how it was in the origin mesh
Triangulation.insert_constraint(vh1, vh2);
Triangulation.insert_constraint(vh2, vh3);
Triangulation.insert_constraint(vh3, vh1);
}
My problem now is that when I try to retrieve the info, it is missing/incorrect. I get values outside of the range I'm inserting them.
This happens only with the constraints. When I comment out the lines with insert_constraint, it works as expected.
for (auto itFace = Triangulation.finite_faces_begin(); itFace != Triangulation.finite_faces_end(); itFace++)
{
// Retrieve vertex info
auto& a = itFace->vertex(0)->info();
auto& b = itFace->vertex(1)->info();
auto& c = itFace->vertex(2)->info();
// ...
}
What am I doing wrong with the constraints?
Additionally, I want to limit the length of edges. I haven't attempted so add this limitation in my code yet, because I wanted to fix the described problem first. If you could provide an answer that includes a maximum edge length, that would be very helpful too.
Any help is appreciated. I've been sitting on this problem for a long time.

Using AABB_tree with multiple surface meshes

I'm trying to use CGAL's AABB_tree with multiple Surface_mesh and fail an odd assertion which makes me think it's trying to use the first surface mesh's vertices with the second mesh's indices or something similarly weird.
Before I file a bug, I'd like to validate that I'm not misunderstanding something.
Here's a minimally modified example. I'm using cube.off from: https://github.com/libigl/libigl/blob/master/tutorial/shared/cube.off and the Tetrahedron from CGAL's examples, but it seems to reproduce every time the second surface mesh I add has less vertices than the first mesh no matter what it is.
The assertion I'm failing is /usr/local/include/CGAL/Surface_mesh/Properties.h:178 - CGAL_assertion( idx < data.size() );
Using:
CGAL_VERSION 4.12
CGAL_VERSION_NR 1041201000
CGAL_SVN_REVISION 99999
CGAL_GIT_HASH f7c3c8212b56c0d6dae63787efc99093f4383415
#include <iostream>
#include <fstream>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point;
typedef K::Ray_3 Ray;
typedef CGAL::Surface_mesh<Point> Mesh;
typedef CGAL::AABB_face_graph_triangle_primitive<Mesh> Primitive;
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Tree;
typedef boost::optional<Tree::Intersection_and_primitive_id<Ray>::Type> Ray_intersection;
int main(int argc, char* argv[])
{
const char* filename1 = "cube.off";
const char* filename2 = "tetrahedron.off";
std::ifstream input1(filename1);
Mesh mesh1;
input1 >> mesh1;
std::ifstream input2(filename2);
Mesh mesh2;
input2 >> mesh2;
Tree tree;
tree.insert(faces(mesh1).first, faces(mesh1).second, mesh1);
tree.insert(faces(mesh2).first, faces(mesh2).second, mesh2);
tree.build(); // CGAL_assertion( idx < data.size() ) fails
return 0;
}
I repost my comment as an answer:
From my comment: Actually you can use this primitive but you need to set the template tag OneFaceGraphPerTree to CGAL::Tag_false.
See here

CGAL: k nearest neighbor periodic points

I want to find k nearest neighbors of a series of periodic points using Point_set_2, the following piece of code is the header files and related typedefs, in which I used periodic version of delaunay triangulation:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Periodic_2_Delaunay_triangulation_2.h>
#include <CGAL/Periodic_2_triangulation_traits_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Point_set_2.h>
#include <vector>
//******************************************************************
using namespace std;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Periodic_2_triangulation_traits_2<K> Gt;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned, 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> Delaunay;
typedef Delaunay::Iso_rectangle Iso_rectangle;
CGAL::Point_set_2<K,Tds> PSet;
typedef CGAL::Point_set_2<K,Tds>::Edge_iterator Edge_iterator;
typedef CGAL::Point_set_2<K,Tds>::Vertex_handle Vertex_handle;
typedef K::Point_2 Point_2;
typedef vector<pair<Point_2,unsigned> > Vector;
and these are from the main part of the program, in which according to the CGAL manual, I used Delaunay& T in the argument of the function nearest neighbor():
Vector points;
for(int iat = 0; iat < N_b; iat++)
{
points.push_back(make_pair(Point_2(r_b[iat][0],r_b[iat][1]),iat));
}
Iso_rectangle domain(0,0,L[0],L[1]);
Delaunay T(points.begin(), points.end(), domain);
PSet.insert(points.begin(),points.end());
vector<Vertex_handle>::const_iterator it;
vector<Vertex_handle> LV;
for(int iat = 0; iat < N_b; iat++)
{
Point_2 focal(r_b[iat][0], r_b[iat][1]);
PSet.nearest_neighbors(T, focal, nei_top+1, back_inserter(LV));
vector<Vertex_handle>::const_iterator it_begin = LV.begin()+1;
vector<Vertex_handle>::const_iterator it_end = LV.end();
for (it = it_begin; it != it_end; it++)
{
int jat = (*it)->info();
array1[iat]+= sin(theta[jat]-theta[iat]);
}
LV.clear();
}
points.clear();
but it gets a bunch of errors including this one:
OutputIterator nearest_neighbors(Point p, size_type k, OutputIterator res)
^
/usr/include/CGAL/Point_set_2.h:180:20: note: template argument deduction/substitution failed:
In manual, I see the Dt as an argument, but according to the error, such argument doesn't exists!

Do constrained refinement with CGAL isotropic_remeshing

I'd like to do refinement of eg a simple cube (from a .off); there are a few ways but the ones suitable for what I want to do next end up with 'wrinkles', ie the object shape gets distorted.
This way below promises to allow the boundaries (shape?) of the object to be preserved, permitting what you'd expect of refinement, to just add more edges and vertices:
http://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2isotropic_remeshing_example_8cpp-example.html
I want an edge constraint map (and if that isn't sufficient then I'll want a vertex constraint map as well) but can't figure out the template abstractions well enough. I tried an OpenMesh Constrained_edge_map from a different CGAL example, but that's too different and won't compile. What I'm asking for is an edge map and maybe a vertex map that I can feed to the call:
PMP::isotropic_remeshing(
faces(mesh),
target_edge_length,
mesh,
PMP::parameters::number_of_iterations(nb_iter)
.protect_constraints(true)//i.e. protect border, here
);
I'm using CGAL 4.8.1, the latest at time of writing. Thanks.
Here is a minimal example to remesh a triangulated cube:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/remesh.h>
#include <CGAL/Mesh_3/dihedral_angle_3.h>
#include <boost/foreach.hpp>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Mesh>::edge_descriptor edge_descriptor;
namespace PMP=CGAL::Polygon_mesh_processing;
int main(int, char* argv[])
{
std::ifstream input(argv[1]);
Mesh tmesh;
input >> tmesh;
double target_edge_length = 0.20;
unsigned int nb_iter = 10;
// give each vertex a name, the default is empty
Mesh::Property_map<edge_descriptor,bool> is_constrained =
tmesh.add_property_map<edge_descriptor,bool>("e:is_constrained",false).first;
//detect sharp features
BOOST_FOREACH(edge_descriptor e, edges(tmesh))
{
halfedge_descriptor hd = halfedge(e,tmesh);
if ( !is_border(e,tmesh) ){
double angle = CGAL::Mesh_3::dihedral_angle(tmesh.point(source(hd,tmesh)),
tmesh.point(target(hd,tmesh)),
tmesh.point(target(next(hd,tmesh),tmesh)),
tmesh.point(target(next(opposite(hd,tmesh),tmesh),tmesh)));
if ( CGAL::abs(angle)<100 )
is_constrained[e]=true;
}
}
//remesh
PMP::isotropic_remeshing(
faces(tmesh),
target_edge_length,
tmesh,
PMP::parameters::number_of_iterations(nb_iter)
.edge_is_constrained_map(is_constrained) );
std::ofstream out("out.off");
out << tmesh;
return 0;
}

Converting Surface_mesh to Nef_polyhedron_3

I'm trying to use CGAL to do some boolean operations on meshes.
How do I convert from Surface_mesh to Nef_polyhedron_3?
EDIT:
I've tried with this code, but I don't know how to continue...
#include <iostream>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
using namespace std;
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
int main()
{
Mesh m;
auto a = m.add_vertex(K::Point_3(0,0,0));
auto b = m.add_vertex(K::Point_3(0,0,0));
auto c = m.add_vertex(K::Point_3(0,0,0));
m.add_face(a,b,c);
Mesh::Halfedge_range range = m.halfedges();
for(Mesh::Halfedge_index hei : range)
{
// ??? <<--
std::cout << hei << std::endl;
}
return 0;
}
Thanks
I think the suggested way to do this is to use the 3d polyhedral surface package instead. The Nef 3 documentation describes the conversion between Polyhedron_3 and Nef_3. The only difference between the 3d polyhedral surface package and the surface mesh package is that, it is pointer based rather than index based.