For example consider this code:
++
// https://doc.cgal.org/latest/Triangulation_2/index.html#Section_2D_Triangulations_Constrained_Delaunay
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <cassert>
#include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Exact_predicates_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, CGAL::Default, Itag> CDT;
typedef CDT::Point Point;
int
main( )
{
CDT cdt;
std::cout << "Inserting a grid of 5x5 constraints " << std::endl;
for (int i = 1; i < 6; ++i)
cdt.insert_constraint( Point(0,i), Point(6,i));
for (int j = 1; j < 6; ++j)
cdt.insert_constraint( Point(j,0), Point(j,6));
assert(cdt.is_valid());
int count = 0;
for (CDT::Finite_edges_iterator eit = cdt.finite_edges_begin();
eit != cdt.finite_edges_end();
++eit)
if (cdt.is_constrained(*eit)) ++count;
std::cout << "The number of resulting constrained edges is ";
std::cout << count << std::endl;
return 0;
}
I can compile this with
cgal_create_CMakeLists -s executable
cmake -DCGAL_DIR=/usr/lib64/cmake .
make
or with a plain
g++ -lCGAL -lgmp executable.cpp
I have used CGAL and BOOST some years ago from Ruby, which was some work, but I can not remember details currently. I think for Nim the ordinary wrapper approach with c2nim makes not much sense because CGAL is using so many C++ templates. So I guess I have to use emit and/or importcpp and compile the whole project to C++? Or maybe wrap the C++ code in plain C functions before calling it from Nim?
Yesterday I tried a very similar approach as I used for Ruby:
++
// g++ -c -lCGAL -lgmp cdt.cpp
// ar rvs cdt.a cdt.o
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
//#include <cassert>
//#include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Exact_predicates_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, CGAL::Default, Itag> CDT;
typedef CDT::Point Point;
extern "C" void *newCDT();
extern "C" void insertConstraint(CDT *cdt, double x0, double y0, double x1, double y1);
extern "C" int numConstraints(CDT *cdt);
void *newCDT()
{
CDT *cdt;
cdt = new CDT;
return cdt;
}
void insertConstraint(CDT *cdt, double x0, double y0, double x1, double y1)
{
cdt->insert_constraint( Point(x0, y0), Point(x1, y1));
}
int numConstraints(CDT *cdt)
{
int count = 0;
for (CDT::Finite_edges_iterator eit = cdt->finite_edges_begin();
eit != cdt->finite_edges_end();
++eit)
if (cdt->is_constrained(*eit)) ++count;
return count;
}
#nim cpp --passL:cdt.a --passL:-lCGAL --passL:-lgmp cdt.nim
type
CDT = ptr object
proc newCDT(): CDT {.importc.}
proc insertConstraint(cdt: CDT; x0, y0, x1, y1: cdouble) {.importc.}
proc numConstraints(cdt: CDT): cint {.importc.}
var cdt = newCDT()
for i in 1 ..< 6:
cdt.insertConstraint(0.cdouble, i.cdouble, 6.cdouble, i.cdouble)
for j in 1 ..< 6:
cdt.insertConstraint(j.cdouble, 0.cdouble, j.cdouble, 6.cdouble)
echo cdt.numConstraints
Seems to compile and work. I have to invoke nim compiler with cpp -- initially I assumed that cpp backand is not necessary due to extern "C"
g++ -c -lCGAL -lgmp cdt.cpp
ar rvs cdt.a cdt.o
nim cpp --passL:cdt.a --passL:-lCGAL --passL:-lgmp cdt.nim
I assume this will not work with llvm backend. Of course releasing memory with GC is still work in progress, for Triangulation data structure it is not really simple, because Triangulation is some sort of container, so objects can live inside triangulation and at the same time outside in Nim world. I think I did it wrong for Ruby some years ago -- never fixed, as it was working for me...