How can I use customized vertices (vertex with info) for triangulation on sphere in CGAL? - cgal

I want to use customized vertices for triangulation on sphere.
In user manual, customized vertices can be used for 2D triangulation like this:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned, K> Vb;
typedef CGAL::Triangulation_data_structure_2<Vb> Tds;
typedef CGAL::Delaunay_triangulation_2<K, Tds> Delaunay;
typedef Delaunay::Point Point;
int main() {
std::vector<std::pair<Point, unsigned>> points;
Delaunay dt;
dt.insert(points.begin(), points.end());
return 0;
}
I want to use customized vertices for Delaunay triangulation on sphere too, but couldn't find ways to use it.
What I want to do is like this:
CGAL::Delaunay_triangulation_on_sphere_2<Traits> dtos;
std::vector<std::pair<Point, unsigned>> points;
dtos.insert(points.begin(), points.end());
I tried using Triangulation_on_sphere_vertex_base_with_info_2 which is created based on Triangulation_on_sphere_vertex_base_2 referring to "Triangulation_vertex_base_with info_2.h" file, but it doesn't work.
Any help would be greatly appreciated.
Thank you for reading.
Following Mael's suggestion, I wrote a code below but failed to compile. What should I fix? Thank you so much for your reply.
#include <vector>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_on_sphere_vertex_base_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Delaunay_triangulation_on_sphere_traits_2.h>
#include <CGAL/Delaunay_triangulation_on_sphere_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_on_sphere_traits_2<K> Traits;
typedef CGAL::Triangulation_on_sphere_vertex_base_2<Traits> Vbb;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned, Traits, Vbb> Vb;
typedef CGAL::Triangulation_on_sphere_face_base_2<Traits> Cb;
typedef CGAL::Triangulation_data_structure_2<Vb, Cb> Tds;
typedef CGAL::Delaunay_triangulation_on_sphere_2<Traits, Tds> DToS2;
typedef DToS2::Point_3 Point;
int main() {
std::vector<std::pair<Point, unsigned>> points;
points.emplace_back(Point(-1, 0, 0), 0);
points.emplace_back(Point(0, -1, 0), 1);
points.emplace_back(Point(0, 0, -1), 2);
points.emplace_back(Point(1, 0, 0), 3);
points.emplace_back(Point(0, 1, 0), 4);
points.emplace_back(Point(0, 0, 1), 5);
DToS2 dt;
dt.insert(points.begin(), points.end());
return 0;
}
Here is build output:
>------ Build All started: Project: kitti2discarto, Configuration: x64-Release ------
[1/2] Building CXX object CMakeFiles\kitti2discarto.dir\main.cpp.obj
FAILED: CMakeFiles/kitti2discarto.dir/main.cpp.obj
C:\PROGRA~1\MICROS~2\2022\ENTERP~1\VC\Tools\MSVC\1431~1.311\bin\Hostx64\x64\cl.exe /nologo /TP -DBOOST_ALL_DYN_LINK=1 -DBOOST_ALL_NO_LIB -DCGAL_USE_GMPXX=1 -DDISABLE_QHULL -DGLOG_NO_ABBREVIATED_SEVERITIES -DNOMINMAX -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NO_DEBUG -DQT_WIDGETS_LIB -D_CRT_SECURE_NO_WARNINGS -D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING -D_USE_MATH_DEFINES -D__SSE2__ -D__SSE3__ -D__SSE4_1__ -D__SSE4_2__ -D__SSE__ -D__SSSE3__ -external:I C:\vcpkg\installed\x64-windows\include -external:I C:\vcpkg\installed\x64-windows\include\eigen3 -external:I C:\vcpkg\installed\x64-windows\include\openni2 -external:I C:\vcpkg\installed\x64-windows\include\vtk-9.0 -external:I C:\vcpkg\installed\x64-windows\include\qt5 -external:I C:\vcpkg\installed\x64-windows\include\qt5\QtWidgets -external:I C:\vcpkg\installed\x64-windows\include\qt5\QtGui -external:I C:\vcpkg\installed\x64-windows\include\qt5\QtCore -external:I C:\vcpkg\installed\x64-windows\tools\qt5\mkspecs\win32-msvc -external:W0 /std:c++20 /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MD /Zi /O2 /Ob1 /DNDEBUG /bigobj -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS /fp:strict /fp:except- /bigobj /showIncludes /FoCMakeFiles\kitti2discarto.dir\main.cpp.obj /FdCMakeFiles\kitti2discarto.dir\ /FS -c C:\Users\User\workspace\kitti2discarto\kitti2discarto\main.cpp
C:\vcpkg\installed\x64-windows\include\CGAL\Delaunay_triangulation_on_sphere_2.h(635): error C2338: (std::is_same<typename std::iterator_traits<InputIterator>::value_type, Point>::value)
C:\Users\User\workspace\kitti2discarto\kitti2discarto\main.cpp(28): note: see reference to function template instantiation 'unsigned __int64 CGAL::Delaunay_triangulation_on_sphere_2<Traits,Tds>::insert<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>>(InputIterator,InputIterator,void *)' being compiled
with
[
_Ty=std::pair<Point,unsigned int>,
InputIterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::pair<Point,unsigned int>>>>
]
C:\Users\User\workspace\kitti2discarto\kitti2discarto\main.cpp(28): note: see reference to function template instantiation 'unsigned __int64 CGAL::Delaunay_triangulation_on_sphere_2<Traits,Tds>::insert<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>>(InputIterator,InputIterator,void *)' being compiled
with
[
_Ty=std::pair<Point,unsigned int>,
InputIterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::pair<Point,unsigned int>>>>
]
C:\vcpkg\installed\x64-windows\include\CGAL\Delaunay_triangulation_on_sphere_2.h(636): error C2338: !(std::is_same<Point, Point_3>::value)
ninja: build stopped: subcommand failed.
Build All failed.
Sharing the results:
This is an example made according to Mael's comments. It works fine!
#include <isotream>
#include <vector>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_on_sphere_vertex_base_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Delaunay_triangulation_on_sphere_traits_2.h>
#include <CGAL/Delaunay_triangulation_on_sphere_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_on_sphere_traits_2<K> Traits;
typedef CGAL::Triangulation_on_sphere_vertex_base_2<Traits> Vbb;
typedef CGAL::Triangulation_vertex_base_with_info_2<size_t, Traits, Vbb> Vb;
typedef CGAL::Triangulation_on_sphere_face_base_2<Traits> Cb;
typedef CGAL::Triangulation_data_structure_2<Vb, Cb> Tds;
typedef CGAL::Delaunay_triangulation_on_sphere_2<Traits, Tds> DToS2;
typedef DToS2::Point_3 Point;
typedef DToS2::Vertex_handle VH;
int main() {
std::vector<Point> points;
points.emplace_back(-1, 0, 0);
points.emplace_back(0, -1, 0);
points.emplace_back(0, 0, -1);
points.emplace_back(1, 0, 0);
points.emplace_back(0, 1, 0);
points.emplace_back(0, 0, 1);
Traits traits(Point(0, 0, 0), 1);
DToS2 dt(traits);
for (size_t i = 0; i < points.size(); i++) {
const VH vh = dt.insert(points[i]);
if (vh != VH()) vh->info() = i;
}
for (DToS2::Finite_faces_iterator face_itr = dt.finite_faces_begin(); face_itr != dt.finite_faces_end(); face_itr++) {
std::cout << face_itr->vertex(0)->info() << ", " << face_itr->vertex(1)->info() << ", " << face_itr->vertex(2)->info() << std::endl;
}
return 0;
}

You can combine vertex bases like this
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_on_sphere_traits_2<K> Traits;
typedef CGAL::Triangulation_on_sphere_vertex_base_2<Traits> Vbb;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned, Traits, Vbb> Vb;
typedef CGAL::Triangulation_on_sphere_face_base_2<Traits> Cb;
typedef CGAL::Triangulation_data_structure_2<Vb, Cb> Tds;
typedef CGAL::Delaunay_triangulation_on_sphere_2<Traits, Tds> DToS2;

Related

why CGAL mesh simplification takes so long

I try to use triangulated surface mesh simplification of cgal. I used Garland&Heckbert Simplification to simplify my mesh, but it tooks so long. My data has 50000 nv, 165883 ne and 109521 nf, which needs almost 30mins with 0.2 stop_ratio. Is the runtime cost reasonable?
I also check whether the input mesh is valid by using CGAL::is_valid_polygon_mesh. It is valid.
how can i solve this problem?
Thank you so much...
the runtime cost of mesh with 165883 edges
the runtime cost of mesh with 8282 edges
enter code here
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
#include "gltf-loader.h"
#define TINYGLTF_NO_STB_IMAGE_WRITE
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "tiny_gltf.h"
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/draw_surface_mesh.h>
#include <CGAL/draw_polygon_2.h>
#include <CGAL/Polygon_mesh_processing/repair.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Bounded_normal_change_placement.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/GarlandHeckbert_policies.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Polygon_mesh_processing/stitch_borders.h>
#include <chrono>
#include <vector>
using namespace example;
namespace PMP = CGAL::Polygon_mesh_processing;
namespace NP = CGAL::parameters;
//typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> CGAL_Mesh;
typedef CGAL_Mesh::Vertex_index vertex_descriptor;
typedef CGAL_Mesh::Face_index face_descriptor;
namespace SMS = CGAL::Surface_mesh_simplification;
CGAL_Mesh inital_mesh;
const char* filename = "C:\\Users\\Administrator\\source\\repos\\CMakeProject4\\CMakeProject4\\input.off";
if (!PMP::IO::read_polygon_mesh(filename, inital_mesh) || CGAL::is_empty(inital_mesh))
{
std::cerr << "Invalid input." << std::endl;
return 1;
}
std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();
double stop_ratio = 0.2;
std::cout << "start edge collages." << std::endl;
SMS::Count_ratio_stop_predicate<CGAL_Mesh> stop(stop_ratio);
typedef typename SMS::GarlandHeckbert_policies<CGAL_Mesh, K> GH_policies;
typedef typename GH_policies::Get_cost GH_cost;
typedef typename GH_policies::Get_placement GH_placement;
typedef SMS::Bounded_normal_change_placement<GH_placement> Bounded_GH_placement;
bool check_mesh = CGAL::is_valid_polygon_mesh(inital_mesh);
std::cout << "vaild or in valid" <<check_mesh<< std::endl;
GH_policies gh_policies(inital_mesh);
const GH_cost& gh_cost = gh_policies.get_cost();
const GH_placement& gh_placement = gh_policies.get_placement();
Bounded_GH_placement placement(gh_placement);
std::cout << "Input mesh has " << num_vertices(inital_mesh) << " nv "<< num_edges(inital_mesh) << " ne "
<< num_faces(inital_mesh) << " nf" << std::endl;
/*internal::cgal_enable_sms_trace = true;*/
int r = SMS::edge_collapse(inital_mesh, stop,
CGAL::parameters::get_cost(gh_cost)
.get_placement(placement));

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: get the info of nearest neighbors

I am using the Point_set_2 data structure in order to find k nearest neighbors of a query point, I want to retrieve the index of neighbors; I used the following code, but it->info() produces errors!
I have also seen this post, but for me the priority is using Point_set_2 method:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Point_set_2.h>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned, K> Vb;
typedef CGAL::Triangulation_data_structure_2<Vb> Tds;
typedef CGAL::Delaunay_triangulation_2<K, Tds> Delaunay;
//typedef Delaunay::Point Point;
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;
CGAL::Point_set_2<K,Tds> PSet;
int main()
{
std::vector< std::pair<Point_2,unsigned> > points;
points.push_back( std::make_pair(Point_2(0,0),0) );
points.push_back( std::make_pair(Point_2(1,0),1) );
points.push_back( std::make_pair(Point_2(0,1),2) );
points.push_back( std::make_pair(Point_2(14,4),3) );
points.push_back( std::make_pair(Point_2(2,2),4) );
points.push_back( std::make_pair(Point_2(-4,0),5) );
PSet.insert(points.begin(),points.end());
// init
Point_2 actual(30,45,10);
// nearest neighbor ...
Vertex_handle v = PSet.nearest_neighbor(actual);
std::cout << "Nearest neighbor:" << v->point() << "\n";
// k nearest neighbors ...
std::vector<Vertex_handle> L;
std::vector<Vertex_handle>::const_iterator it;
PSet.nearest_neighbors(actual,5, std::back_inserter(L));
std::cout << "actual point: " << actual << "\n";
for (it=L.begin();it != L.end(); it++)
std::cout << it->info() << "\n";
return 0;
}
A Vertex_handle is roughly equivalent of a pointer. To access it data member you have to either dereference it or use the -> operator.
If you have a vector of Vertex_handle, then iterator are over Vertex_handle
which means that you have to dereference the iterator to access the Vertex_handle. You should write (*it)->info().
Maybe the confusion came from the fact that the iterators of the triangulation are implicitly convertible to the handle types.

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!

retrieve the index of point in CGAL

In the following code, a delaunay triangulation is made from an N dimensional array named points. Every element of this array has an index associated with it. For every vertex of the triangulation the nearest vertex is found correctly (without using the libraray: CGAL/Triangulation_vertex_base...). Now, I want to retrieve the index of each neighbor point with ->info(), but the way I've implemented that leads to error! How can I do that?
#include <vector>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
using namespace std();
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned int, Kernel> Vb;
typedef CGAL::Triangulation_data_structure_2<Vb> Tds;
typedef CGAL::Delaunay_triangulation_2<Kernel, Tds> Triangulation;
typedef Triangulation::Edge_iterator Edge_iterator;
typedef Triangulation::Point Point;
typedef Triangulation::Vertex_handle Vertex_handle;
typedef Triangulation::Vertex_circulator Vertex_circulator;
typedef Kernel::Point_2 Point_2;
typedef std::vector<std::pair<Point_2, unsigned> > Vector;
const int N = 16;
int main(){
Vector points;
points.reserve(N);
.... {Some part of code which assignes values to dir[N][2]}
for (int i = 0; i < N; i++)
points.push_back(make_pair(Point_2(dir[i][0], dir[i][1]), i));\\ I want each point to have an index
Triangulation T;
T.insert(points.begin(), points.end());
cout << T.number_of_vertices() <<endl;
for(int i = 0; i < N; i++){
Vertex_handle handle = T.nearest_vertex(points[i]);
cout<<"incidents: \n" <<endl;
cout << handle->point() <<endl<<endl;
Vertex_circulator circulator = T.incident_vertices(handle), done(circulator);
do
{
if( !T.is_infinite ( circulator))
cout << circulator->point() << endl;
cout << circulator->point()->info()<<endl;
} while(++circulator != done);
}
return 0;}
edit: It seems that the origin of the error is primarily because of using the following kernel: typedef CGAL::Delaunay_triangulation_2 Triangulation;
error: no matching function for call to CGAL::Delaunay_triangulation_2 > >::nearest_vertex(std::pair, unsigned int>&)’
edit 2: when I print the output in two different lines, weired number(96) appears:
The code:
cout<<circulator->point()<<endl;
cout<<circulator->info()<<endl;
output(total number of points, 4):
3.26675 0.733887
2
96
2.02307 0.718587
1
2.33861 1.68862
3
when I print the information in one line, the number 96 disappears;
cout<<circulator->point()<<"\t"<<circulator->info()<<endl;
3.26675 0.733887 2
2.02307 0.718587 1
2.33861 1.68862 3