Skip to Content.
Sympa Menu

cgal-discuss - How to derive from a CGAL kernel (was Re: [cgal-discuss] Segfault when customizing Point class used in triangulation)

Subject: CGAL users discussion list

List archive

How to derive from a CGAL kernel (was Re: [cgal-discuss] Segfault when customizing Point class used in triangulation)


Chronological Thread 
  • From: "Laurent Rineau (GeometryFactory)" <>
  • To: , MHOOO <>
  • Subject: How to derive from a CGAL kernel (was Re: [cgal-discuss] Segfault when customizing Point class used in triangulation)
  • Date: Fri, 26 Mar 2010 17:16:58 +0100
  • Organization: GeometryFactory

On Thursday 18 March 2010 19:11:35 MHOOO wrote:
> I would like to use a custom Point class with the CGAL constrained delaunay
> triangulation. However, with the following MyPoint class (which should
> behave the exact same as a CGAL::Point_2 no?) I get segmentation faults
> inside insert_constraint (with a backtrace of several thousands of function
> calls). It works perfectly if I set the Point_2 typedef inside MyKernel to
> CGAL::Exact_predicates_inexact_constructions_kernel::Point_2. What am I
> doing wrong?
>
> ----------------------------------------------------
> template<class P>
> struct MyPoint : public P {
> MyPoint() : P() {}
> MyPoint(const MyPoint& p) : P(p) {}
>
> MyPoint( int x, int y) : P(x,y) {}
> MyPoint( double x, double y) : P(x,y) {}
> };
>
> struct MyKernel : CGAL::Exact_predicates_inexact_constructions_kernel {
> typedef
> MyPoint<CGAL::Exact_predicates_inexact_constructions_kernel::Point_2>
> Point_2;
> };

Let's do:
typedef CGAL::Exact_predicates_inexact_constructions_kernel EPIC;


> typedef MyKernel K;
>
> typedef CGAL::Triangulation_vertex_base_2<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> CDT;
> typedef CDT::Point Point;

With the backtrace you gave us, I have understood what happened.

In CDT, there are intersections computed (if it happens that your input
constraints intersect). With your code, the type of object that is returned
by K::Intersect_2, when two segments intersects at a point, is a CGAL::Object
constructed with a EPIC::Point_2, and that type is different from the type
K::Point_2 (that is MyPoint<EPIC::Point_2>). For that reason, the Object
cannot be assigned (using CGAL::assign) to K::Point_2, and the CDT code
incorrectly believe that there are no intersections (and that incorrect
assumption gives the infinite loop, and eventually the segmentation fault
once
the stack overflows).

Compile the attachment essai.cpp and run it. You will find that the two
points
types are different.

To correctly derive from a CGAL kernel, you need to follow what is describes
in section "Extensible Kernel" of the user manual of chapter "2D and 3D
Geometry Kernel":
http://www.cgal.org/Manual/last/doc_html/cgal_manual/Kernel_23/Chapter_main.html#Section_11.5

In the attachment essai2.cpp, I show you how to proceed, and eventually show
that the two types are equal. With that piece of code to define your new
kernel, I think that you can try successfully to use the CDT with that
modified kernel.

--
Laurent Rineau, PhD
R&D Engineer at GeometryFactory http://www.geometryfactory.com/
Release Manager of the CGAL Project http://www.cgal.org/
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Simple_cartesian.h>
#include <iostream>

typedef CGAL::Exact_predicates_inexact_constructions_kernel EPIC;
typedef CGAL::Simple_cartesian<double> Inexact;

template<class P>
struct MyPoint : public P {
  MyPoint() : P() {}
  MyPoint(const MyPoint& p) : P(p) {}
  
  MyPoint( int x, int y) : P(x,y) {}
  MyPoint( double x, double y) : P(x,y) {}
};

template <class K_, class K_base>
class My_simple_cartesian_base 
  : public K_base::template Base<K_>::Type
{
  typedef typename K_base::template Base<K_>::Type   Old_kernel;

public:
  typedef MyPoint<typename Old_kernel::Point_2> Point_2;

  template <class Kernel2>
  struct Base {
    typedef My_simple_cartesian_base<Kernel2, K_base> Type; };
};

template <class FT>
struct My_simple_cartesian 
  : public CGAL::Type_equality_wrapper<
      My_simple_cartesian_base<My_simple_cartesian<FT>, CGAL::Simple_cartesian<FT> >,
      My_simple_cartesian<FT> >
{};

typedef My_simple_cartesian<double> My_inexact_kernel;
typedef CGAL::Filtered_kernel<My_inexact_kernel> K;

int main()
{
  K::Segment_2 seg1(K::Point_2(0, 0), K::Point_2(10, 0));
  K::Segment_2 seg2(K::Point_2(5, -5), K::Point_2(5, 5));

  CGAL::Object o = CGAL::intersection(seg1, seg2);

  std::cout << "\n\n" << o.type().name() << "\n";
  std::cout  << typeid(K::Point_2).name() << "\n\n";

  return 0;
}
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <iostream>

typedef CGAL::Exact_predicates_inexact_constructions_kernel EPIC;

template<class P>
struct MyPoint : public P {
  MyPoint() : P() {}
  MyPoint(const MyPoint& p) : P(p) {}
  
  MyPoint( int x, int y) : P(x,y) {}
  MyPoint( double x, double y) : P(x,y) {}
};

struct MyKernel : public EPIC {
  typedef MyPoint<EPIC::Point_2> Point_2;
};

typedef MyKernel K;

int main()
{
  K::Segment_2 seg1(K::Point_2(0, 0), K::Point_2(10, 0));
  K::Segment_2 seg2(K::Point_2(5, -5), K::Point_2(5, 5));

  CGAL::Object o = CGAL::intersection(seg1, seg2);

  std::cout << "\n\n" << o.type().name() << "\n";
  std::cout  << typeid(K::Point_2).name() << "\n\n";
  return 0;
}



Archive powered by MHonArc 2.6.16.

Top of Page