mirror of
git://projects.qi-hardware.com/cae-tools.git
synced 2024-12-23 08:25:31 +02:00
53fe70950d
cameo encountered spurious aborts with the following message: terminate called after throwing an instance of 'CGAL::Precondition_exception what(): CGAL ERROR: precondition violation! Expr: is_simple_2(first, last, traits) File: /usr/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h Line: 420 These aborts come and go even if just the coordinate origin is slightly changed. Setting CGAL_POLYGON_NO_PRECONDITIONS in p2d_area_holes.cpp made them go away in some cases, but cameo could still run into an assertion violation (in CGAL). We now check all the polygons, outer boundary and holes, being sent to CGAL::create_interior_skeleton_and_offset_polygons_with_holes_2 for simplicity, and stop recursing if there is any hint of a problem. This seems to avoid trouble for now, but the issue deserves further investigation.
125 lines
3.1 KiB
C++
125 lines
3.1 KiB
C++
/*
|
|
* p2d_area_holes.cpp - Fill an area with holes
|
|
*
|
|
* Written 2012 by Werner Almesberger
|
|
* Copyright 2012 by Werner Almesberger
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*/
|
|
|
|
/*
|
|
* References:
|
|
* http://www.cgal.org/Manual/latest/examples/Straight_skeleton_2/
|
|
* Create_skeleton_and_offset_polygons_with_holes_2.cpp
|
|
* http://www.cgal.org/Manual/latest/examples/Straight_skeleton_2/print.h
|
|
*/
|
|
|
|
extern "C" {
|
|
#include <assert.h>
|
|
|
|
#include "poly2d.h"
|
|
}
|
|
|
|
/*
|
|
* @@@ Prevent spurious aborts with
|
|
*
|
|
* terminate called after throwing an instance of 'CGAL::Precondition_exception'
|
|
* what(): CGAL ERROR: precondition violation!
|
|
* Expr: is_simple_2(first, last, traits)
|
|
* File: /usr/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h
|
|
* Line: 420
|
|
*
|
|
* Note that we also need to check the polygons for simplicity in recurse_area,
|
|
* or this may still lead to assertion failures.
|
|
*/
|
|
|
|
#define CGAL_POLYGON_NO_PRECONDITIONS
|
|
|
|
#include "cgal_helper.h"
|
|
|
|
#include <vector>
|
|
#include <boost/shared_ptr.hpp>
|
|
|
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
|
#include <CGAL/Polygon_with_holes_2.h>
|
|
#include <CGAL/create_offset_polygons_from_polygon_with_holes_2.h>
|
|
|
|
|
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
|
|
|
typedef CGAL::Polygon_2<K> Polygon_2;
|
|
typedef CGAL::Polygon_with_holes_2<K> Polygon_with_holes;
|
|
|
|
typedef boost::shared_ptr<Polygon_with_holes> PolygonPtr;
|
|
|
|
typedef std::vector<PolygonPtr> PolygonPtrVector;
|
|
|
|
struct p2d *res = NULL, **last = &res, *np;
|
|
|
|
|
|
static void append_poly(Polygon_2 poly, struct p2d ***last)
|
|
{
|
|
**last = P2_to_p2d(poly);
|
|
*last = &(**last)->next;
|
|
}
|
|
|
|
|
|
static void recurse_area(Polygon_with_holes poly, double current,
|
|
double next, struct p2d ***last)
|
|
{
|
|
if (!poly.outer_boundary().is_simple())
|
|
return;
|
|
for (Polygon_with_holes::Hole_const_iterator
|
|
hit = poly.holes_begin();
|
|
hit != poly.holes_end(); ++hit)
|
|
if (!hit->is_simple())
|
|
return;
|
|
|
|
PolygonPtrVector tmp =
|
|
CGAL::create_interior_skeleton_and_offset_polygons_with_holes_2(
|
|
current, poly);
|
|
|
|
for (PolygonPtrVector::const_iterator pit = tmp.begin();
|
|
pit != tmp.end(); ++pit) {
|
|
append_poly((*pit)->outer_boundary(), last);
|
|
recurse_area(**pit, next, next, last);
|
|
|
|
for (Polygon_with_holes::Hole_const_iterator
|
|
hit = (*pit)->holes_begin();
|
|
hit != (*pit)->holes_end(); ++hit) {
|
|
append_poly(*hit, last);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
extern "C" void p2d_area_holes_append(const struct p2d *p,
|
|
const struct p2d *holes, double first, double next,
|
|
struct p2d ***last)
|
|
{
|
|
const struct p2d *h;
|
|
|
|
assert(p2d_is_closed(p));
|
|
Polygon_with_holes poly(p2d_to_P2(p, 1));
|
|
|
|
for (h = holes; h; h = h->next) {
|
|
assert(p2d_is_closed(h));
|
|
poly.add_hole(p2d_to_P2(h, 0));
|
|
}
|
|
|
|
recurse_area(poly, first, next, last);
|
|
}
|
|
|
|
|
|
extern "C" struct p2d *p2d_area_holes(const struct p2d *p,
|
|
const struct p2d *holes, double first, double next)
|
|
{
|
|
struct p2d *res = NULL, **last = &res;
|
|
|
|
p2d_area_holes_append(p, holes, first, next, &last);
|
|
return res;
|
|
}
|