CGAL / cgal

The public CGAL repository, see the README below
https://github.com/CGAL/cgal#readme
Other
4.93k stars 1.38k forks source link

2D Arrangements Observer Notification Related to Aggregated Insertion Function #97

Closed myirci closed 9 years ago

myirci commented 9 years ago

Hello,

When incremental global insertion function is used to insert curves into an arrangement, the observer attached to that Arrangement gives notifications as expected. However, when aggregated global insertion function is used to insert curves into an arrangement, the notifications for edge splitting does not work. I've tested this with both segments Bézier arrangements. Below is a very simple program which displays the issue for segments arrangement.

#include <vector>
#include <CGAL/Cartesian.h>
#include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/Arr_observer.h>

typedef CGAL::Quotient<CGAL::MP_Float>       Number_type;
typedef CGAL::Cartesian<Number_type>         Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel>   Traits_2;
typedef Traits_2::Point_2                    Point_2;
typedef Traits_2::X_monotone_curve_2         Segment_2;
typedef CGAL::Arrangement_2<Traits_2>        Arrangement_2; 

class observer : public CGAL::Arr_observer<Arrangement_2> {
public:
    observer (Arrangement_2& arr) : CGAL::Arr_observer<Arrangement_2> (arr) { }

    virtual void before_split_edge(Halfedge_handle heh, Vertex_handle vh, const X_monotone_curve_2& c1, const X_monotone_curve_2& c2) {
        std::cout << "before_split_edge: " << std::endl;
    }
    virtual void after_split_edge(Halfedge_handle he1, Halfedge_handle he2) {
        std::cout << "after_split_edge" << std::endl;
    }
    virtual void before_split_face (Face_handle fh, Halfedge_handle e) {
        std::cout << "before_split_face" << std::endl;
    }
    virtual void after_split_face(Face_handle fh1, Face_handle fh2, bool is_hole) {
        std::cout << "after_split_face" << std::endl;
    }
};

int main () {
    Arrangement_2 arrangement1;
    Arrangement_2 arrangement2;
    observer ob1(arrangement1);
    observer ob2(arrangement2);

    Point_2 pt1(1,1), pt2(4,1), pt3(4,4), pt4(1,4);
    Segment_2 s1(pt1, pt2), s2(pt2, pt3), s3(pt3, pt4), s4(pt4, pt1), s5(pt1, pt3), s6(pt4, pt2);

    // INCREMENTAL INSERTION
    std::cout << "************************************************" << std::endl;
    CGAL::insert(arrangement1, s1);
    CGAL::insert(arrangement1, s2);
    CGAL::insert(arrangement1, s3);
    CGAL::insert(arrangement1, s4);
    CGAL::insert(arrangement1, s5);
    CGAL::insert(arrangement1, s6);
    std::cout << "************************************************" << std::endl;
    // AGGREGATE INSERTION
    std::vector segments { s1, s2, s3, s4, s5, s6 };
    CGAL::insert(arrangement2, segments.begin(), segments.end());
    std::cout << "************************************************" << std::endl;
    return 0;
}

And the output of this program is:

************************************************
before_split_face
after_split_face
before_split_face
after_split_face
before_split_edge: 
after_split_edge
before_split_face
after_split_face
before_split_face
after_split_face
************************************************
before_split_face
after_split_face
before_split_face
after_split_face
before_split_face
after_split_face
before_split_face
after_split_face
************************************************

Observe that before_split_edge and after_split_edge is not called when aggregated insert function is used.

Regards, Murat Yirci

efifogel commented 9 years ago

Hi Murat,

Right, and before_split_edge * and after_split_edge *are not expected to be called when aggregated insert function is used. The events are different for the two methods. When inserting using a sweep, the curves are intersected before they are actually inserted, so an edge split does not occur.

Add the notification functions bellow, and it will become clear to you.

virtual void before_create_vertex(const Point_2& p) { std::cout << "beforecreate_vertex: " << p << std::endl; } virtual void before_create_edge (const X_monotone_curve_2& c, Vertexhandle /* v1 /, Vertexhandle / v2 */) { std::cout << "beforecreate_edge: " << c << std::endl; }

Efi


//) o /__ // (__ ( ( ( (/ (/-(-'(/ /

On Thu, May 28, 2015 at 5:53 PM, myirci notifications@github.com wrote:

Hello,

When incremental global insertion function is used to insert curves into an arrangement, the observer attached to that Arrangement gives notifications as expected. However, when aggregated global insertion function is used to insert curves into an arrangement, the notifications for edge splitting does not work. I've tested this with both segments Bézier arrangements. Below is a very simple program which displays the issue for segments arrangement.

include

include <CGAL/Cartesian.h>

include <CGAL/Quotient.h>

include <CGAL/MP_Float.h>

include <CGAL/Arr_segment_traits_2.h>

include <CGAL/Arrangement_2.h>

include <CGAL/Arr_observer.h>

typedef CGAL::QuotientCGAL::MP_Float Number_type; typedef CGAL::Cartesian Kernel; typedef CGAL::Arr_segment_traits_2 Traits_2; typedef Traits_2::Point_2 Point_2; typedef Traits_2::X_monotone_curve_2 Segment_2; typedef CGAL::Arrangement_2 Arrangement_2;

class observer : public CGAL::Arr_observer { public: observer (Arrangement_2& arr) : CGAL::Arr_observer (arr) { }

virtual void before_split_edge(Halfedge_handle heh, Vertex_handle vh, const X_monotone_curve_2& c1, const X_monotone_curve_2& c2) {
    std::cout << "before_split_edge: " << std::endl;
}
virtual void after_split_edge(Halfedge_handle he1, Halfedge_handle he2) {
    std::cout << "after_split_edge" << std::endl;
}
virtual void before_split_face (Face_handle fh, Halfedge_handle e) {
    std::cout << "before_split_face" << std::endl;
}
virtual void after_split_face(Face_handle fh1, Face_handle fh2, bool is_hole) {
    std::cout << "after_split_face" << std::endl;
}

};

int main () { Arrangement_2 arrangement1; Arrangement_2 arrangement2; observer ob1(arrangement1); observer ob2(arrangement2);

Point_2 pt1(1,1), pt2(4,1), pt3(4,4), pt4(1,4);
Segment_2 s1(pt1, pt2), s2(pt2, pt3), s3(pt3, pt4), s4(pt4, pt1), s5(pt1, pt3), s6(pt4, pt2);

// INCREMENTAL INSERTION
std::cout << "************************************************" << std::endl;
CGAL::insert(arrangement1, s1);
CGAL::insert(arrangement1, s2);
CGAL::insert(arrangement1, s3);
CGAL::insert(arrangement1, s4);
CGAL::insert(arrangement1, s5);
CGAL::insert(arrangement1, s6);
std::cout << "************************************************" << std::endl;
// AGGREGATE INSERTION
std::vector segments { s1, s2, s3, s4, s5, s6 };
CGAL::insert(arrangement2, segments.begin(), segments.end());
std::cout << "************************************************" << std::endl;
return 0;

}

And the output of this program is:


before_split_face after_split_face before_split_face after_split_face before_split_edge: after_split_edge before_split_face after_split_face before_split_face after_split_face


before_split_face after_split_face before_split_face after_split_face before_split_face after_split_face before_split_face after_split_face


Observe that before_split_edge * and after_split_edge * is not called when aggregated insert function is used.

Regards, Murat Yirci

— Reply to this email directly or view it on GitHub https://github.com/CGAL/cgal/issues/97.

myirci commented 9 years ago

Hi Efi,

Thank you very much for your explanation. It's clear for me now.

Murat