Root/poly2d/p2d_area_holes.cpp

1/*
2 * p2d_area_holes.cpp - Fill an area with holes
3 *
4 * Written 2012, 2015 by Werner Almesberger
5 * Copyright 2012, 2015 by Werner Almesberger
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 */
12
13/*
14 * References:
15 * http://www.cgal.org/Manual/latest/examples/Straight_skeleton_2/
16 * Create_skeleton_and_offset_polygons_with_holes_2.cpp
17 * http://www.cgal.org/Manual/latest/examples/Straight_skeleton_2/print.h
18 */
19
20extern "C" {
21    #include <assert.h>
22
23    #include "poly2d.h"
24}
25
26/*
27 * @@@ Prevent spurious aborts with
28 *
29 * terminate called after throwing an instance of 'CGAL::Precondition_exception'
30 * what(): CGAL ERROR: precondition violation!
31 * Expr: is_simple_2(first, last, traits)
32 * File: /usr/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h
33 * Line: 420
34 *
35 * Note that we also need to check the polygons for simplicity in recurse_area,
36 * or this may still lead to assertion failures.
37 */
38
39#define CGAL_POLYGON_NO_PRECONDITIONS
40
41#include "cgal_helper.h"
42
43#include <vector>
44#include <boost/shared_ptr.hpp>
45
46#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
47#include <CGAL/Polygon_with_holes_2.h>
48#include <CGAL/create_offset_polygons_from_polygon_with_holes_2.h>
49
50
51typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
52
53typedef CGAL::Polygon_2<K> Polygon_2;
54typedef CGAL::Polygon_with_holes_2<K> Polygon_with_holes;
55
56typedef boost::shared_ptr<Polygon_with_holes> PolygonPtr;
57
58typedef std::vector<PolygonPtr> PolygonPtrVector;
59
60    struct p2d *res = NULL, **last = &res, *np;
61
62
63static void append_poly(Polygon_2 poly, struct p2d ***last)
64{
65    **last = P2_to_p2d(poly);
66    *last = &(**last)->next;
67}
68
69
70static void recurse_area(Polygon_with_holes poly, double current,
71    double next, struct p2d ***last)
72{
73    if (!poly.outer_boundary().is_simple())
74        return;
75    for (Polygon_with_holes::Hole_const_iterator hit = poly.holes_begin();
76        hit != poly.holes_end(); ++hit)
77        if (!hit->is_simple())
78            return;
79
80    PolygonPtrVector tmp =
81        CGAL::create_interior_skeleton_and_offset_polygons_with_holes_2(
82        current, poly);
83
84    for (PolygonPtrVector::const_iterator pit = tmp.begin();
85        pit != tmp.end(); ++pit) {
86        append_poly((*pit)->outer_boundary(), last);
87        recurse_area(**pit, next, next, last);
88
89        for (Polygon_with_holes::Hole_const_iterator
90            hit = (*pit)->holes_begin();
91            hit != (*pit)->holes_end(); ++hit) {
92            append_poly(*hit, last);
93        }
94    }
95}
96
97
98extern "C" void p2d_area_holes_append(const struct p2d *p,
99    const struct p2d *holes, double first, double next,
100    struct p2d ***last)
101{
102    const struct p2d *h;
103
104    assert(p2d_is_closed(p));
105    Polygon_with_holes poly(p2d_to_P2(p, 1));
106
107    for (h = holes; h; h = h->next) {
108        assert(p2d_is_closed(h));
109        poly.add_hole(p2d_to_P2(h, 0));
110    }
111
112    recurse_area(poly, first, next, last);
113}
114
115
116extern "C" struct p2d *p2d_area_holes(const struct p2d *p,
117    const struct p2d *holes, double first, double next)
118{
119    struct p2d *res = NULL, **last = &res;
120
121    p2d_area_holes_append(p, holes, first, next, &last);
122    return res;
123}
124

Archive Download this file

Branches:
master



interactive