Sébastien Loriot and Sylvain Pion
78.1 | Introduction | ||||
78.2 | CGAL Ipelets | ||||
78.3 | Example | ||||
78.4 | Installation of the Demo Ipelets | ||||
78.5 | Design and Implementation History |
The Ipe extensible drawing editor (http://tclab.kaist.ac.kr/ipe/) [Sch95, Che09] is a tool used by computational geometry researchers to produce 2D figures for inclusion in articles or presentations. The extensible adjective sheds a light on an important feature: the possibility for users to write small extensions (called ipelets) to interface any algorithm with Ipe. This feature is especially interesting to produce illustrations in a paper describing a new algorithm. This package provides one class that eases the writing of ipelets based on Cgal, reducing the needed knowledge of the API of Ipe. This class is designed to fulfill most of the needs to implement an ipelet for a 2D Cgal algorithm. In addition, this package comes with more than ten complete examples of ipelets: alpha-shape, arrangements, Voronoi diagrams, convex hulls, Hilbert curve, k-order Delaunay, 2D mesh, Minkowski sum, polygon partition, random generators, triangulations
The class CGAL::Ipelet_base derives from the class Ipelets from Ipe and has one template parameter indicating which kernel must be used within the ipelet. In practice, we recommend to use either CGAL::Exact_predicate_exact_constructions_kernel or CGAL::Exact_predicate_inexact_construction_kernel.
Two main methods are provided by the CGAL::Ipelet_base class. The first one, read_active_objects retrieves all primitives selected in Ipe when calling an ipelet, and converts them into equivalent Cgal objects. The second method, draw_in_ipe draws Cgal objects in the Ipe window. These functions handle basic objects such as points, segments, polygons, circles and circular arcs.
The registration of an ipelet into Ipe can be done using the macro CGAL_IPELET. CGAL_IPELET(ipelet_class_name) must follow the definition of the ipelet class, in the same file source file.
The following example shows how the class CGAL::Ipelet_base can be used to easily interface the Cgal 2D Delaunay triangulation with Ipe.
File: demo/CGAL_ipelets/simple_triangulation.cpp
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Delaunay_triangulation_2.h> #include <CGAL/CGAL_Ipelet_base.h> namespace my_triangulation{ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Delaunay_triangulation_2<Kernel> Delaunay; //Function names of the ipelet const std::string labels[] = { "Delaunay","Help" }; //Help message associated to the first function const std::string hmsg[] = { "Draw a Delaunay triangulation of a set of points" }; class Triangulation_ipelet : public CGAL::Ipelet_base<Kernel,2>{ public: //declare an ipelet called CGAL Delaunay, with 2 functions (including help message). Triangulation_ipelet() :CGAL::Ipelet_base<Kernel,2>("CGAL Delaunay",labels,hmsg){} void protected_run(int); }; //function called when using the ipelet. void Triangulation_ipelet::protected_run(int fn) { switch (fn){ case 1: show_help();//print an help message return; default: std::list<Point_2> pt_lst; //Recovering points using output iterator of type //Dispatch_or_drop_output_iterator read_active_objects( CGAL::dispatch_or_drop_output<Point_2>(std::back_inserter(pt_lst)) ); if (pt_lst.empty()) { print_error_message("No mark selected"); return; } Delaunay dt; dt.insert(pt_lst.begin(),pt_lst.end()); //draw the triangulation. draw_in_ipe(dt); }; } }//namespace my_triangulation //register the ipelet in Ipe CGAL_IPELET(my_triangulation::Triangulation_ipelet)