You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-20 14:45:44 +00:00
Replace Clipper1 library by Clipper2 library
This commit is contained in:
@@ -360,12 +360,6 @@ Copyright: 1998-2010, Gilles Vollant
|
|||||||
2009-2010, Mathias Svensson
|
2009-2010, Mathias Svensson
|
||||||
License: Zlib
|
License: Zlib
|
||||||
|
|
||||||
Files: ./thirdparty/misc/clipper.cpp
|
|
||||||
./thirdparty/misc/clipper.hpp
|
|
||||||
Comment: Clipper
|
|
||||||
Copyright: 2010-2017, Angus Johnson
|
|
||||||
License: BSL-1.0
|
|
||||||
|
|
||||||
Files: ./thirdparty/misc/cubemap_coeffs.h
|
Files: ./thirdparty/misc/cubemap_coeffs.h
|
||||||
Comment: Fast Filtering of Reflection Probes
|
Comment: Fast Filtering of Reflection Probes
|
||||||
Copyright: 2016, Activision Publishing, Inc.
|
Copyright: 2016, Activision Publishing, Inc.
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ thirdparty_misc_sources = [
|
|||||||
# C++ sources
|
# C++ sources
|
||||||
"pcg.cpp",
|
"pcg.cpp",
|
||||||
"polypartition.cpp",
|
"polypartition.cpp",
|
||||||
"clipper.cpp",
|
|
||||||
"smolv.cpp",
|
"smolv.cpp",
|
||||||
]
|
]
|
||||||
thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
|
thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
|
||||||
|
|||||||
@@ -30,12 +30,12 @@
|
|||||||
|
|
||||||
#include "geometry_2d.h"
|
#include "geometry_2d.h"
|
||||||
|
|
||||||
#include "thirdparty/misc/clipper.hpp"
|
#include "thirdparty/clipper2/include/clipper2/clipper.h"
|
||||||
#include "thirdparty/misc/polypartition.h"
|
#include "thirdparty/misc/polypartition.h"
|
||||||
#define STB_RECT_PACK_IMPLEMENTATION
|
#define STB_RECT_PACK_IMPLEMENTATION
|
||||||
#include "thirdparty/misc/stb_rect_pack.h"
|
#include "thirdparty/misc/stb_rect_pack.h"
|
||||||
|
|
||||||
#define SCALE_FACTOR 100000.0 // Based on CMP_EPSILON.
|
#define PRECISION 5 // Based on CMP_EPSILON.
|
||||||
|
|
||||||
Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(const Vector<Point2> &polygon) {
|
Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(const Vector<Point2> &polygon) {
|
||||||
Vector<Vector<Vector2>> decomp;
|
Vector<Vector<Vector2>> decomp;
|
||||||
@@ -196,58 +196,59 @@ void Geometry2D::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_re
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector<Vector<Point2>> Geometry2D::_polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open) {
|
Vector<Vector<Point2>> Geometry2D::_polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open) {
|
||||||
using namespace ClipperLib;
|
using namespace Clipper2Lib;
|
||||||
|
|
||||||
ClipType op = ctUnion;
|
ClipType op = ClipType::Union;
|
||||||
|
|
||||||
switch (p_op) {
|
switch (p_op) {
|
||||||
case OPERATION_UNION:
|
case OPERATION_UNION:
|
||||||
op = ctUnion;
|
op = ClipType::Union;
|
||||||
break;
|
break;
|
||||||
case OPERATION_DIFFERENCE:
|
case OPERATION_DIFFERENCE:
|
||||||
op = ctDifference;
|
op = ClipType::Difference;
|
||||||
break;
|
break;
|
||||||
case OPERATION_INTERSECTION:
|
case OPERATION_INTERSECTION:
|
||||||
op = ctIntersection;
|
op = ClipType::Intersection;
|
||||||
break;
|
break;
|
||||||
case OPERATION_XOR:
|
case OPERATION_XOR:
|
||||||
op = ctXor;
|
op = ClipType::Xor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Path path_a, path_b;
|
|
||||||
|
|
||||||
// Need to scale points (Clipper's requirement for robust computation).
|
PathD path_a(p_polypath_a.size());
|
||||||
for (int i = 0; i != p_polypath_a.size(); ++i) {
|
for (int i = 0; i != p_polypath_a.size(); ++i) {
|
||||||
path_a << IntPoint(p_polypath_a[i].x * (real_t)SCALE_FACTOR, p_polypath_a[i].y * (real_t)SCALE_FACTOR);
|
path_a[i] = PointD(p_polypath_a[i].x, p_polypath_a[i].y);
|
||||||
}
|
}
|
||||||
|
PathD path_b(p_polypath_b.size());
|
||||||
for (int i = 0; i != p_polypath_b.size(); ++i) {
|
for (int i = 0; i != p_polypath_b.size(); ++i) {
|
||||||
path_b << IntPoint(p_polypath_b[i].x * (real_t)SCALE_FACTOR, p_polypath_b[i].y * (real_t)SCALE_FACTOR);
|
path_b[i] = PointD(p_polypath_b[i].x, p_polypath_b[i].y);
|
||||||
}
|
}
|
||||||
Clipper clp;
|
|
||||||
clp.AddPath(path_a, ptSubject, !is_a_open); // Forward compatible with Clipper 10.0.0.
|
|
||||||
clp.AddPath(path_b, ptClip, true); // Polylines cannot be set as clip.
|
|
||||||
|
|
||||||
Paths paths;
|
ClipperD clp(PRECISION); // Scale points up internally to attain the desired precision.
|
||||||
|
clp.PreserveCollinear(false); // Remove redundant vertices.
|
||||||
|
if (is_a_open) {
|
||||||
|
clp.AddOpenSubject({ path_a });
|
||||||
|
} else {
|
||||||
|
clp.AddSubject({ path_a });
|
||||||
|
}
|
||||||
|
clp.AddClip({ path_b });
|
||||||
|
|
||||||
|
PathsD paths;
|
||||||
|
|
||||||
if (is_a_open) {
|
if (is_a_open) {
|
||||||
PolyTree tree; // Needed to populate polylines.
|
PolyTreeD tree; // Needed to populate polylines.
|
||||||
clp.Execute(op, tree);
|
clp.Execute(op, FillRule::EvenOdd, tree, paths);
|
||||||
OpenPathsFromPolyTree(tree, paths);
|
|
||||||
} else {
|
} else {
|
||||||
clp.Execute(op, paths); // Works on closed polygons only.
|
clp.Execute(op, FillRule::EvenOdd, paths); // Works on closed polygons only.
|
||||||
}
|
}
|
||||||
// Have to scale points down now.
|
|
||||||
Vector<Vector<Point2>> polypaths;
|
Vector<Vector<Point2>> polypaths;
|
||||||
|
for (PathsD::size_type i = 0; i < paths.size(); ++i) {
|
||||||
|
const PathD &path = paths[i];
|
||||||
|
|
||||||
for (Paths::size_type i = 0; i < paths.size(); ++i) {
|
|
||||||
Vector<Vector2> polypath;
|
Vector<Vector2> polypath;
|
||||||
|
for (PathsD::size_type j = 0; j < path.size(); ++j) {
|
||||||
const Path &scaled_path = paths[i];
|
polypath.push_back(Point2(static_cast<real_t>(path[j].x), static_cast<real_t>(path[j].y)));
|
||||||
|
|
||||||
for (Paths::size_type j = 0; j < scaled_path.size(); ++j) {
|
|
||||||
polypath.push_back(Point2(
|
|
||||||
static_cast<real_t>(scaled_path[j].X) / (real_t)SCALE_FACTOR,
|
|
||||||
static_cast<real_t>(scaled_path[j].Y) / (real_t)SCALE_FACTOR));
|
|
||||||
}
|
}
|
||||||
polypaths.push_back(polypath);
|
polypaths.push_back(polypath);
|
||||||
}
|
}
|
||||||
@@ -255,67 +256,61 @@ Vector<Vector<Point2>> Geometry2D::_polypaths_do_operation(PolyBooleanOperation
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector<Vector<Point2>> Geometry2D::_polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
|
Vector<Vector<Point2>> Geometry2D::_polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
|
||||||
using namespace ClipperLib;
|
using namespace Clipper2Lib;
|
||||||
|
|
||||||
JoinType jt = jtSquare;
|
JoinType jt = JoinType::Square;
|
||||||
|
|
||||||
switch (p_join_type) {
|
switch (p_join_type) {
|
||||||
case JOIN_SQUARE:
|
case JOIN_SQUARE:
|
||||||
jt = jtSquare;
|
jt = JoinType::Square;
|
||||||
break;
|
break;
|
||||||
case JOIN_ROUND:
|
case JOIN_ROUND:
|
||||||
jt = jtRound;
|
jt = JoinType::Round;
|
||||||
break;
|
break;
|
||||||
case JOIN_MITER:
|
case JOIN_MITER:
|
||||||
jt = jtMiter;
|
jt = JoinType::Miter;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
EndType et = etClosedPolygon;
|
EndType et = EndType::Polygon;
|
||||||
|
|
||||||
switch (p_end_type) {
|
switch (p_end_type) {
|
||||||
case END_POLYGON:
|
case END_POLYGON:
|
||||||
et = etClosedPolygon;
|
et = EndType::Polygon;
|
||||||
break;
|
break;
|
||||||
case END_JOINED:
|
case END_JOINED:
|
||||||
et = etClosedLine;
|
et = EndType::Joined;
|
||||||
break;
|
break;
|
||||||
case END_BUTT:
|
case END_BUTT:
|
||||||
et = etOpenButt;
|
et = EndType::Butt;
|
||||||
break;
|
break;
|
||||||
case END_SQUARE:
|
case END_SQUARE:
|
||||||
et = etOpenSquare;
|
et = EndType::Square;
|
||||||
break;
|
break;
|
||||||
case END_ROUND:
|
case END_ROUND:
|
||||||
et = etOpenRound;
|
et = EndType::Round;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ClipperOffset co(2.0, 0.25f * (real_t)SCALE_FACTOR); // Defaults from ClipperOffset.
|
|
||||||
Path path;
|
|
||||||
|
|
||||||
// Need to scale points (Clipper's requirement for robust computation).
|
PathD polypath(p_polypath.size());
|
||||||
for (int i = 0; i != p_polypath.size(); ++i) {
|
for (int i = 0; i != p_polypath.size(); ++i) {
|
||||||
path << IntPoint(p_polypath[i].x * (real_t)SCALE_FACTOR, p_polypath[i].y * (real_t)SCALE_FACTOR);
|
polypath[i] = PointD(p_polypath[i].x, p_polypath[i].y);
|
||||||
}
|
}
|
||||||
co.AddPath(path, jt, et);
|
|
||||||
|
|
||||||
Paths paths;
|
// Inflate/deflate.
|
||||||
co.Execute(paths, p_delta * (real_t)SCALE_FACTOR); // Inflate/deflate.
|
PathsD paths = InflatePaths({ polypath }, p_delta, jt, et, 2.0, PRECISION, 0.0);
|
||||||
|
// Here the miter_limit = 2.0 and arc_tolerance = 0.0 are Clipper2 defaults,
|
||||||
|
// and the PRECISION is used to scale points up internally, to attain the desired precision.
|
||||||
|
|
||||||
// Have to scale points down now.
|
|
||||||
Vector<Vector<Point2>> polypaths;
|
Vector<Vector<Point2>> polypaths;
|
||||||
|
for (PathsD::size_type i = 0; i < paths.size(); ++i) {
|
||||||
|
const PathD &path = paths[i];
|
||||||
|
|
||||||
for (Paths::size_type i = 0; i < paths.size(); ++i) {
|
Vector<Vector2> polypath2;
|
||||||
Vector<Vector2> polypath;
|
for (PathsD::size_type j = 0; j < path.size(); ++j) {
|
||||||
|
polypath2.push_back(Point2(static_cast<real_t>(path[j].x), static_cast<real_t>(path[j].y)));
|
||||||
const Path &scaled_path = paths[i];
|
|
||||||
|
|
||||||
for (Paths::size_type j = 0; j < scaled_path.size(); ++j) {
|
|
||||||
polypath.push_back(Point2(
|
|
||||||
static_cast<real_t>(scaled_path[j].X) / (real_t)SCALE_FACTOR,
|
|
||||||
static_cast<real_t>(scaled_path[j].Y) / (real_t)SCALE_FACTOR));
|
|
||||||
}
|
}
|
||||||
polypaths.push_back(polypath);
|
polypaths.push_back(polypath2);
|
||||||
}
|
}
|
||||||
return polypaths;
|
return polypaths;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,9 @@
|
|||||||
#include "scene/gui/menu_button.h"
|
#include "scene/gui/menu_button.h"
|
||||||
#include "scene/gui/panel.h"
|
#include "scene/gui/panel.h"
|
||||||
#include "scene/gui/view_panner.h"
|
#include "scene/gui/view_panner.h"
|
||||||
#include "thirdparty/misc/clipper.hpp"
|
#include "thirdparty/clipper2/include/clipper2/clipper.h"
|
||||||
|
|
||||||
|
#define PRECISION 1
|
||||||
|
|
||||||
void Sprite2DEditor::_node_removed(Node *p_node) {
|
void Sprite2DEditor::_node_removed(Node *p_node) {
|
||||||
if (p_node == node) {
|
if (p_node == node) {
|
||||||
@@ -59,58 +61,39 @@ void Sprite2DEditor::edit(Sprite2D *p_sprite) {
|
|||||||
node = p_sprite;
|
node = p_sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PRECISION 10.0
|
|
||||||
|
|
||||||
Vector<Vector2> expand(const Vector<Vector2> &points, const Rect2i &rect, float epsilon = 2.0) {
|
Vector<Vector2> expand(const Vector<Vector2> &points, const Rect2i &rect, float epsilon = 2.0) {
|
||||||
int size = points.size();
|
int size = points.size();
|
||||||
ERR_FAIL_COND_V(size < 2, Vector<Vector2>());
|
ERR_FAIL_COND_V(size < 2, Vector<Vector2>());
|
||||||
|
|
||||||
ClipperLib::Path subj;
|
Clipper2Lib::PathD subj(points.size());
|
||||||
ClipperLib::PolyTree solution;
|
|
||||||
ClipperLib::PolyTree out;
|
|
||||||
|
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
subj << ClipperLib::IntPoint(points[i].x * PRECISION, points[i].y * PRECISION);
|
subj[i] = Clipper2Lib::PointD(points[i].x, points[i].y);
|
||||||
}
|
|
||||||
ClipperLib::ClipperOffset co;
|
|
||||||
co.AddPath(subj, ClipperLib::jtMiter, ClipperLib::etClosedPolygon);
|
|
||||||
co.Execute(solution, epsilon * PRECISION);
|
|
||||||
|
|
||||||
ClipperLib::PolyNode *p = solution.GetFirst();
|
|
||||||
|
|
||||||
ERR_FAIL_NULL_V(p, points);
|
|
||||||
|
|
||||||
while (p->IsHole()) {
|
|
||||||
p = p->GetNext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//turn the result into simply polygon (AKA, fix overlap)
|
Clipper2Lib::PathsD solution = Clipper2Lib::InflatePaths({ subj }, epsilon, Clipper2Lib::JoinType::Miter, Clipper2Lib::EndType::Polygon, 2.0, PRECISION, 0.0);
|
||||||
|
// Here the miter_limit = 2.0 and arc_tolerance = 0.0 are Clipper2 defaults,
|
||||||
|
// and PRECISION is used to scale points up internally, to attain the desired precision.
|
||||||
|
|
||||||
//clamp into the specified rect
|
ERR_FAIL_COND_V(solution.size() == 0, points);
|
||||||
ClipperLib::Clipper cl;
|
|
||||||
cl.StrictlySimple(true);
|
// Clamp into the specified rect.
|
||||||
cl.AddPath(p->Contour, ClipperLib::ptSubject, true);
|
Clipper2Lib::RectD clamp(rect.position.x,
|
||||||
//create the clipping rect
|
rect.position.y,
|
||||||
ClipperLib::Path clamp;
|
rect.position.x + rect.size.width,
|
||||||
clamp.push_back(ClipperLib::IntPoint(0, 0));
|
rect.position.y + rect.size.height);
|
||||||
clamp.push_back(ClipperLib::IntPoint(rect.size.width * PRECISION, 0));
|
Clipper2Lib::PathsD out = Clipper2Lib::RectClip(clamp, solution[0], PRECISION);
|
||||||
clamp.push_back(ClipperLib::IntPoint(rect.size.width * PRECISION, rect.size.height * PRECISION));
|
// Here PRECISION is used to scale points up internally, to attain the desired precision.
|
||||||
clamp.push_back(ClipperLib::IntPoint(0, rect.size.height * PRECISION));
|
|
||||||
cl.AddPath(clamp, ClipperLib::ptClip, true);
|
ERR_FAIL_COND_V(out.size() == 0, points);
|
||||||
cl.Execute(ClipperLib::ctIntersection, out);
|
|
||||||
|
const Clipper2Lib::PathD &p2 = out[0];
|
||||||
|
|
||||||
Vector<Vector2> outPoints;
|
Vector<Vector2> outPoints;
|
||||||
ClipperLib::PolyNode *p2 = out.GetFirst();
|
|
||||||
ERR_FAIL_NULL_V(p2, points);
|
|
||||||
|
|
||||||
while (p2->IsHole()) {
|
int lasti = p2.size() - 1;
|
||||||
p2 = p2->GetNext();
|
Vector2 prev = Vector2(p2[lasti].x, p2[lasti].y);
|
||||||
}
|
for (uint64_t i = 0; i < p2.size(); i++) {
|
||||||
|
Vector2 cur = Vector2(p2[i].x, p2[i].y);
|
||||||
int lasti = p2->Contour.size() - 1;
|
|
||||||
Vector2 prev = Vector2(p2->Contour[lasti].X / PRECISION, p2->Contour[lasti].Y / PRECISION);
|
|
||||||
for (uint64_t i = 0; i < p2->Contour.size(); i++) {
|
|
||||||
Vector2 cur = Vector2(p2->Contour[i].X / PRECISION, p2->Contour[i].Y / PRECISION);
|
|
||||||
if (cur.distance_to(prev) > 0.5) {
|
if (cur.distance_to(prev) > 0.5) {
|
||||||
outPoints.push_back(cur);
|
outPoints.push_back(cur);
|
||||||
prev = cur;
|
prev = cur;
|
||||||
|
|||||||
@@ -711,12 +711,12 @@ TEST_CASE("[Geometry2D] Clip polyline with polygon") {
|
|||||||
r = Geometry2D::clip_polyline_with_polygon(l, p);
|
r = Geometry2D::clip_polyline_with_polygon(l, p);
|
||||||
REQUIRE_MESSAGE(r.size() == 2, "There should be 2 resulting clipped lines.");
|
REQUIRE_MESSAGE(r.size() == 2, "There should be 2 resulting clipped lines.");
|
||||||
REQUIRE_MESSAGE(r[0].size() == 3, "The resulting clipped line should have 3 vertices.");
|
REQUIRE_MESSAGE(r[0].size() == 3, "The resulting clipped line should have 3 vertices.");
|
||||||
CHECK(r[0][0].is_equal_approx(Vector2(160, 320)));
|
CHECK(r[0][0].is_equal_approx(Vector2(121.412682, 225.038757)));
|
||||||
CHECK(r[0][1].is_equal_approx(Vector2(122, 250)));
|
CHECK(r[0][1].is_equal_approx(Vector2(122, 250)));
|
||||||
CHECK(r[0][2].is_equal_approx(Vector2(121.412682, 225.038757)));
|
CHECK(r[0][2].is_equal_approx(Vector2(160, 320)));
|
||||||
REQUIRE_MESSAGE(r[1].size() == 2, "The resulting clipped line should have 2 vertices.");
|
REQUIRE_MESSAGE(r[1].size() == 2, "The resulting clipped line should have 2 vertices.");
|
||||||
CHECK(r[1][0].is_equal_approx(Vector2(53.07737, 116.143021)));
|
CHECK(r[1][0].is_equal_approx(Vector2(55, 70)));
|
||||||
CHECK(r[1][1].is_equal_approx(Vector2(55, 70)));
|
CHECK(r[1][1].is_equal_approx(Vector2(53.07737, 116.143021)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
4661
thirdparty/misc/clipper.cpp
vendored
4661
thirdparty/misc/clipper.cpp
vendored
File diff suppressed because it is too large
Load Diff
406
thirdparty/misc/clipper.hpp
vendored
406
thirdparty/misc/clipper.hpp
vendored
@@ -1,406 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* *
|
|
||||||
* Author : Angus Johnson *
|
|
||||||
* Version : 6.4.2 *
|
|
||||||
* Date : 27 February 2017 *
|
|
||||||
* Website : http://www.angusj.com *
|
|
||||||
* Copyright : Angus Johnson 2010-2017 *
|
|
||||||
* *
|
|
||||||
* License: *
|
|
||||||
* Use, modification & distribution is subject to Boost Software License Ver 1. *
|
|
||||||
* http://www.boost.org/LICENSE_1_0.txt *
|
|
||||||
* *
|
|
||||||
* Attributions: *
|
|
||||||
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
|
|
||||||
* "A generic solution to polygon clipping" *
|
|
||||||
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
|
|
||||||
* http://portal.acm.org/citation.cfm?id=129906 *
|
|
||||||
* *
|
|
||||||
* Computer graphics and geometric modeling: implementation and algorithms *
|
|
||||||
* By Max K. Agoston *
|
|
||||||
* Springer; 1 edition (January 4, 2005) *
|
|
||||||
* http://books.google.com/books?q=vatti+clipping+agoston *
|
|
||||||
* *
|
|
||||||
* See also: *
|
|
||||||
* "Polygon Offsetting by Computing Winding Numbers" *
|
|
||||||
* Paper no. DETC2005-85513 pp. 565-575 *
|
|
||||||
* ASME 2005 International Design Engineering Technical Conferences *
|
|
||||||
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
|
|
||||||
* September 24-28, 2005 , Long Beach, California, USA *
|
|
||||||
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
|
|
||||||
* *
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef clipper_hpp
|
|
||||||
#define clipper_hpp
|
|
||||||
|
|
||||||
#define CLIPPER_VERSION "6.4.2"
|
|
||||||
|
|
||||||
//use_int32: When enabled 32bit ints are used instead of 64bit ints. This
|
|
||||||
//improve performance but coordinate values are limited to the range +/- 46340
|
|
||||||
//#define use_int32
|
|
||||||
|
|
||||||
//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
|
|
||||||
//#define use_xyz
|
|
||||||
|
|
||||||
//use_lines: Enables line clipping. Adds a very minor cost to performance.
|
|
||||||
#define use_lines
|
|
||||||
|
|
||||||
//use_deprecated: Enables temporary support for the obsolete functions
|
|
||||||
//#define use_deprecated
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <list>
|
|
||||||
#include <set>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <ostream>
|
|
||||||
#include <functional>
|
|
||||||
#include <queue>
|
|
||||||
|
|
||||||
namespace ClipperLib {
|
|
||||||
|
|
||||||
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
|
|
||||||
enum PolyType { ptSubject, ptClip };
|
|
||||||
//By far the most widely used winding rules for polygon filling are
|
|
||||||
//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
|
|
||||||
//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
|
|
||||||
//see http://glprogramming.com/red/chapter11.html
|
|
||||||
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
|
|
||||||
|
|
||||||
#ifdef use_int32
|
|
||||||
typedef int cInt;
|
|
||||||
static cInt const loRange = 0x7FFF;
|
|
||||||
static cInt const hiRange = 0x7FFF;
|
|
||||||
#else
|
|
||||||
typedef signed long long cInt;
|
|
||||||
static cInt const loRange = 0x3FFFFFFF;
|
|
||||||
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
|
|
||||||
typedef signed long long long64; //used by Int128 class
|
|
||||||
typedef unsigned long long ulong64;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct IntPoint {
|
|
||||||
cInt X;
|
|
||||||
cInt Y;
|
|
||||||
#ifdef use_xyz
|
|
||||||
cInt Z;
|
|
||||||
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
|
|
||||||
#else
|
|
||||||
IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
friend inline bool operator== (const IntPoint& a, const IntPoint& b)
|
|
||||||
{
|
|
||||||
return a.X == b.X && a.Y == b.Y;
|
|
||||||
}
|
|
||||||
friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
|
|
||||||
{
|
|
||||||
return a.X != b.X || a.Y != b.Y;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
typedef std::vector< IntPoint > Path;
|
|
||||||
typedef std::vector< Path > Paths;
|
|
||||||
|
|
||||||
inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;}
|
|
||||||
inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;}
|
|
||||||
|
|
||||||
std::ostream& operator <<(std::ostream &s, const IntPoint &p);
|
|
||||||
std::ostream& operator <<(std::ostream &s, const Path &p);
|
|
||||||
std::ostream& operator <<(std::ostream &s, const Paths &p);
|
|
||||||
|
|
||||||
struct DoublePoint
|
|
||||||
{
|
|
||||||
double X;
|
|
||||||
double Y;
|
|
||||||
DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
|
|
||||||
DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifdef use_xyz
|
|
||||||
typedef void (*ZFillCallback)(IntPoint& e1bot, IntPoint& e1top, IntPoint& e2bot, IntPoint& e2top, IntPoint& pt);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
|
|
||||||
enum JoinType {jtSquare, jtRound, jtMiter};
|
|
||||||
enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
|
|
||||||
|
|
||||||
class PolyNode;
|
|
||||||
typedef std::vector< PolyNode* > PolyNodes;
|
|
||||||
|
|
||||||
class PolyNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PolyNode();
|
|
||||||
virtual ~PolyNode(){};
|
|
||||||
Path Contour;
|
|
||||||
PolyNodes Childs;
|
|
||||||
PolyNode* Parent;
|
|
||||||
PolyNode* GetNext() const;
|
|
||||||
bool IsHole() const;
|
|
||||||
bool IsOpen() const;
|
|
||||||
int ChildCount() const;
|
|
||||||
private:
|
|
||||||
//PolyNode& operator =(PolyNode& other);
|
|
||||||
unsigned Index; //node index in Parent.Childs
|
|
||||||
bool m_IsOpen;
|
|
||||||
JoinType m_jointype;
|
|
||||||
EndType m_endtype;
|
|
||||||
PolyNode* GetNextSiblingUp() const;
|
|
||||||
void AddChild(PolyNode& child);
|
|
||||||
friend class Clipper; //to access Index
|
|
||||||
friend class ClipperOffset;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PolyTree: public PolyNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~PolyTree(){ Clear(); };
|
|
||||||
PolyNode* GetFirst() const;
|
|
||||||
void Clear();
|
|
||||||
int Total() const;
|
|
||||||
private:
|
|
||||||
//PolyTree& operator =(PolyTree& other);
|
|
||||||
PolyNodes AllNodes;
|
|
||||||
friend class Clipper; //to access AllNodes
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Orientation(const Path &poly);
|
|
||||||
double Area(const Path &poly);
|
|
||||||
int PointInPolygon(const IntPoint &pt, const Path &path);
|
|
||||||
|
|
||||||
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
|
|
||||||
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
|
|
||||||
void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);
|
|
||||||
|
|
||||||
void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
|
|
||||||
void CleanPolygon(Path& poly, double distance = 1.415);
|
|
||||||
void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
|
|
||||||
void CleanPolygons(Paths& polys, double distance = 1.415);
|
|
||||||
|
|
||||||
void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed);
|
|
||||||
void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed);
|
|
||||||
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution);
|
|
||||||
|
|
||||||
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
|
|
||||||
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
|
|
||||||
void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);
|
|
||||||
|
|
||||||
void ReversePath(Path& p);
|
|
||||||
void ReversePaths(Paths& p);
|
|
||||||
|
|
||||||
struct IntRect { cInt left; cInt top; cInt right; cInt bottom; };
|
|
||||||
|
|
||||||
//enums that are used internally ...
|
|
||||||
enum EdgeSide { esLeft = 1, esRight = 2};
|
|
||||||
|
|
||||||
//forward declarations (for stuff used internally) ...
|
|
||||||
struct TEdge;
|
|
||||||
struct IntersectNode;
|
|
||||||
struct LocalMinimum;
|
|
||||||
struct OutPt;
|
|
||||||
struct OutRec;
|
|
||||||
struct Join;
|
|
||||||
|
|
||||||
typedef std::vector < OutRec* > PolyOutList;
|
|
||||||
typedef std::vector < TEdge* > EdgeList;
|
|
||||||
typedef std::vector < Join* > JoinList;
|
|
||||||
typedef std::vector < IntersectNode* > IntersectList;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//ClipperBase is the ancestor to the Clipper class. It should not be
|
|
||||||
//instantiated directly. This class simply abstracts the conversion of sets of
|
|
||||||
//polygon coordinates into edge objects that are stored in a LocalMinima list.
|
|
||||||
class ClipperBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ClipperBase();
|
|
||||||
virtual ~ClipperBase();
|
|
||||||
virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
|
|
||||||
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
|
|
||||||
virtual void Clear();
|
|
||||||
IntRect GetBounds();
|
|
||||||
bool PreserveCollinear() {return m_PreserveCollinear;};
|
|
||||||
void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
|
|
||||||
protected:
|
|
||||||
void DisposeLocalMinimaList();
|
|
||||||
TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
|
|
||||||
virtual void Reset();
|
|
||||||
TEdge* ProcessBound(TEdge* E, bool IsClockwise);
|
|
||||||
void InsertScanbeam(const cInt Y);
|
|
||||||
bool PopScanbeam(cInt &Y);
|
|
||||||
bool LocalMinimaPending();
|
|
||||||
bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin);
|
|
||||||
OutRec* CreateOutRec();
|
|
||||||
void DisposeAllOutRecs();
|
|
||||||
void DisposeOutRec(PolyOutList::size_type index);
|
|
||||||
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
|
|
||||||
void DeleteFromAEL(TEdge *e);
|
|
||||||
void UpdateEdgeIntoAEL(TEdge *&e);
|
|
||||||
|
|
||||||
typedef std::vector<LocalMinimum> MinimaList;
|
|
||||||
MinimaList::iterator m_CurrentLM;
|
|
||||||
MinimaList m_MinimaList;
|
|
||||||
|
|
||||||
bool m_UseFullRange;
|
|
||||||
EdgeList m_edges;
|
|
||||||
bool m_PreserveCollinear;
|
|
||||||
bool m_HasOpenPaths;
|
|
||||||
PolyOutList m_PolyOuts;
|
|
||||||
TEdge *m_ActiveEdges;
|
|
||||||
|
|
||||||
typedef std::priority_queue<cInt> ScanbeamList;
|
|
||||||
ScanbeamList m_Scanbeam;
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class Clipper : public virtual ClipperBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Clipper(int initOptions = 0);
|
|
||||||
bool Execute(ClipType clipType,
|
|
||||||
Paths &solution,
|
|
||||||
PolyFillType fillType = pftEvenOdd);
|
|
||||||
bool Execute(ClipType clipType,
|
|
||||||
Paths &solution,
|
|
||||||
PolyFillType subjFillType,
|
|
||||||
PolyFillType clipFillType);
|
|
||||||
bool Execute(ClipType clipType,
|
|
||||||
PolyTree &polytree,
|
|
||||||
PolyFillType fillType = pftEvenOdd);
|
|
||||||
bool Execute(ClipType clipType,
|
|
||||||
PolyTree &polytree,
|
|
||||||
PolyFillType subjFillType,
|
|
||||||
PolyFillType clipFillType);
|
|
||||||
bool ReverseSolution() { return m_ReverseOutput; };
|
|
||||||
void ReverseSolution(bool value) {m_ReverseOutput = value;};
|
|
||||||
bool StrictlySimple() {return m_StrictSimple;};
|
|
||||||
void StrictlySimple(bool value) {m_StrictSimple = value;};
|
|
||||||
//set the callback function for z value filling on intersections (otherwise Z is 0)
|
|
||||||
#ifdef use_xyz
|
|
||||||
void ZFillFunction(ZFillCallback zFillFunc);
|
|
||||||
#endif
|
|
||||||
protected:
|
|
||||||
virtual bool ExecuteInternal();
|
|
||||||
private:
|
|
||||||
JoinList m_Joins;
|
|
||||||
JoinList m_GhostJoins;
|
|
||||||
IntersectList m_IntersectList;
|
|
||||||
ClipType m_ClipType;
|
|
||||||
typedef std::list<cInt> MaximaList;
|
|
||||||
MaximaList m_Maxima;
|
|
||||||
TEdge *m_SortedEdges;
|
|
||||||
bool m_ExecuteLocked;
|
|
||||||
PolyFillType m_ClipFillType;
|
|
||||||
PolyFillType m_SubjFillType;
|
|
||||||
bool m_ReverseOutput;
|
|
||||||
bool m_UsingPolyTree;
|
|
||||||
bool m_StrictSimple;
|
|
||||||
#ifdef use_xyz
|
|
||||||
ZFillCallback m_ZFill; //custom callback
|
|
||||||
#endif
|
|
||||||
void SetWindingCount(TEdge& edge);
|
|
||||||
bool IsEvenOddFillType(const TEdge& edge) const;
|
|
||||||
bool IsEvenOddAltFillType(const TEdge& edge) const;
|
|
||||||
void InsertLocalMinimaIntoAEL(const cInt botY);
|
|
||||||
void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
|
|
||||||
void AddEdgeToSEL(TEdge *edge);
|
|
||||||
bool PopEdgeFromSEL(TEdge *&edge);
|
|
||||||
void CopyAELToSEL();
|
|
||||||
void DeleteFromSEL(TEdge *e);
|
|
||||||
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
|
|
||||||
bool IsContributing(const TEdge& edge) const;
|
|
||||||
bool IsTopHorz(const cInt XPos);
|
|
||||||
void DoMaxima(TEdge *e);
|
|
||||||
void ProcessHorizontals();
|
|
||||||
void ProcessHorizontal(TEdge *horzEdge);
|
|
||||||
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
|
|
||||||
OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
|
|
||||||
OutRec* GetOutRec(int idx);
|
|
||||||
void AppendPolygon(TEdge *e1, TEdge *e2);
|
|
||||||
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
|
|
||||||
OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
|
|
||||||
OutPt* GetLastOutPt(TEdge *e);
|
|
||||||
bool ProcessIntersections(const cInt topY);
|
|
||||||
void BuildIntersectList(const cInt topY);
|
|
||||||
void ProcessIntersectList();
|
|
||||||
void ProcessEdgesAtTopOfScanbeam(const cInt topY);
|
|
||||||
void BuildResult(Paths& polys);
|
|
||||||
void BuildResult2(PolyTree& polytree);
|
|
||||||
void SetHoleState(TEdge *e, OutRec *outrec);
|
|
||||||
void DisposeIntersectNodes();
|
|
||||||
bool FixupIntersectionOrder();
|
|
||||||
void FixupOutPolygon(OutRec &outrec);
|
|
||||||
void FixupOutPolyline(OutRec &outrec);
|
|
||||||
bool IsHole(TEdge *e);
|
|
||||||
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
|
|
||||||
void FixHoleLinkage(OutRec &outrec);
|
|
||||||
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
|
|
||||||
void ClearJoins();
|
|
||||||
void ClearGhostJoins();
|
|
||||||
void AddGhostJoin(OutPt *op, const IntPoint offPt);
|
|
||||||
bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
|
|
||||||
void JoinCommonEdges();
|
|
||||||
void DoSimplePolygons();
|
|
||||||
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
|
|
||||||
void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec);
|
|
||||||
void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec);
|
|
||||||
#ifdef use_xyz
|
|
||||||
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class ClipperOffset
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
|
|
||||||
~ClipperOffset();
|
|
||||||
void AddPath(const Path& path, JoinType joinType, EndType endType);
|
|
||||||
void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
|
|
||||||
void Execute(Paths& solution, double delta);
|
|
||||||
void Execute(PolyTree& solution, double delta);
|
|
||||||
void Clear();
|
|
||||||
double MiterLimit;
|
|
||||||
double ArcTolerance;
|
|
||||||
private:
|
|
||||||
Paths m_destPolys;
|
|
||||||
Path m_srcPoly;
|
|
||||||
Path m_destPoly;
|
|
||||||
std::vector<DoublePoint> m_normals;
|
|
||||||
double m_delta, m_sinA, m_sin, m_cos;
|
|
||||||
double m_miterLim, m_StepsPerRad;
|
|
||||||
IntPoint m_lowest;
|
|
||||||
PolyNode m_polyNodes;
|
|
||||||
|
|
||||||
void FixOrientations();
|
|
||||||
void DoOffset(double delta);
|
|
||||||
void OffsetPoint(int j, int& k, JoinType jointype);
|
|
||||||
void DoSquare(int j, int k);
|
|
||||||
void DoMiter(int j, int k, double r);
|
|
||||||
void DoRound(int j, int k);
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class clipperException : public std::exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
clipperException(const char* description): m_descr(description) {}
|
|
||||||
virtual ~clipperException() throw() {}
|
|
||||||
virtual const char* what() const throw() {return m_descr.c_str();}
|
|
||||||
private:
|
|
||||||
std::string m_descr;
|
|
||||||
};
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
} //ClipperLib namespace
|
|
||||||
|
|
||||||
#endif //clipper_hpp
|
|
||||||
|
|
||||||
|
|
||||||
154
thirdparty/misc/patches/clipper-exceptions.patch
vendored
154
thirdparty/misc/patches/clipper-exceptions.patch
vendored
@@ -1,154 +0,0 @@
|
|||||||
diff --git a/thirdparty/misc/clipper.cpp b/thirdparty/misc/clipper.cpp
|
|
||||||
index 8c3a59c4ca..c67045d113 100644
|
|
||||||
--- a/thirdparty/misc/clipper.cpp
|
|
||||||
+++ b/thirdparty/misc/clipper.cpp
|
|
||||||
@@ -48,6 +48,38 @@
|
|
||||||
#include <ostream>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
+//Explicitly disables exceptions handling for target platform
|
|
||||||
+//#define CLIPPER_NOEXCEPTION
|
|
||||||
+
|
|
||||||
+#define CLIPPER_THROW(exception) std::abort()
|
|
||||||
+#define CLIPPER_TRY if(true)
|
|
||||||
+#define CLIPPER_CATCH(exception) if(false)
|
|
||||||
+
|
|
||||||
+#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
|
|
||||||
+ #ifndef CLIPPER_NOEXCEPTION
|
|
||||||
+ #undef CLIPPER_THROW
|
|
||||||
+ #define CLIPPER_THROW(exception) throw exception
|
|
||||||
+ #undef CLIPPER_TRY
|
|
||||||
+ #define CLIPPER_TRY try
|
|
||||||
+ #undef CLIPPER_CATCH
|
|
||||||
+ #define CLIPPER_CATCH(exception) catch(exception)
|
|
||||||
+ #endif
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+//Optionally allows to override exception macros
|
|
||||||
+#if defined(CLIPPER_THROW_USER)
|
|
||||||
+ #undef CLIPPER_THROW
|
|
||||||
+ #define CLIPPER_THROW CLIPPER_THROW_USER
|
|
||||||
+#endif
|
|
||||||
+#if defined(CLIPPER_TRY_USER)
|
|
||||||
+ #undef CLIPPER_TRY
|
|
||||||
+ #define CLIPPER_TRY CLIPPER_TRY_USER
|
|
||||||
+#endif
|
|
||||||
+#if defined(CLIPPER_CATCH_USER)
|
|
||||||
+ #undef CLIPPER_CATCH
|
|
||||||
+ #define CLIPPER_CATCH CLIPPER_CATCH_USER
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
namespace ClipperLib {
|
|
||||||
|
|
||||||
static double const pi = 3.141592653589793238;
|
|
||||||
@@ -898,7 +930,7 @@ void RangeTest(const IntPoint& Pt, bool& useFullRange)
|
|
||||||
if (useFullRange)
|
|
||||||
{
|
|
||||||
if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange)
|
|
||||||
- throw clipperException("Coordinate outside allowed range");
|
|
||||||
+ CLIPPER_THROW(clipperException("Coordinate outside allowed range"));
|
|
||||||
}
|
|
||||||
else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange)
|
|
||||||
{
|
|
||||||
@@ -1046,10 +1078,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
|
|
||||||
{
|
|
||||||
#ifdef use_lines
|
|
||||||
if (!Closed && PolyTyp == ptClip)
|
|
||||||
- throw clipperException("AddPath: Open paths must be subject.");
|
|
||||||
+ CLIPPER_THROW(clipperException("AddPath: Open paths must be subject."));
|
|
||||||
#else
|
|
||||||
if (!Closed)
|
|
||||||
- throw clipperException("AddPath: Open paths have been disabled.");
|
|
||||||
+ CLIPPER_THROW(clipperException("AddPath: Open paths have been disabled."));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int highI = (int)pg.size() -1;
|
|
||||||
@@ -1062,7 +1094,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
|
|
||||||
|
|
||||||
bool IsFlat = true;
|
|
||||||
//1. Basic (first) edge initialization ...
|
|
||||||
- try
|
|
||||||
+ CLIPPER_TRY
|
|
||||||
{
|
|
||||||
edges[1].Curr = pg[1];
|
|
||||||
RangeTest(pg[0], m_UseFullRange);
|
|
||||||
@@ -1075,10 +1107,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
|
|
||||||
InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- catch(...)
|
|
||||||
+ CLIPPER_CATCH(...)
|
|
||||||
{
|
|
||||||
delete [] edges;
|
|
||||||
- throw; //range test fails
|
|
||||||
+ CLIPPER_THROW(); //range test fails
|
|
||||||
}
|
|
||||||
TEdge *eStart = &edges[0];
|
|
||||||
|
|
||||||
@@ -1442,7 +1474,7 @@ void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
|
|
||||||
void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e)
|
|
||||||
{
|
|
||||||
if (!e->NextInLML)
|
|
||||||
- throw clipperException("UpdateEdgeIntoAEL: invalid call");
|
|
||||||
+ CLIPPER_THROW(clipperException("UpdateEdgeIntoAEL: invalid call"));
|
|
||||||
|
|
||||||
e->NextInLML->OutIdx = e->OutIdx;
|
|
||||||
TEdge* AelPrev = e->PrevInAEL;
|
|
||||||
@@ -1510,7 +1542,7 @@ bool Clipper::Execute(ClipType clipType, Paths &solution,
|
|
||||||
{
|
|
||||||
if( m_ExecuteLocked ) return false;
|
|
||||||
if (m_HasOpenPaths)
|
|
||||||
- throw clipperException("Error: PolyTree struct is needed for open path clipping.");
|
|
||||||
+ CLIPPER_THROW(clipperException("Error: PolyTree struct is needed for open path clipping."));
|
|
||||||
m_ExecuteLocked = true;
|
|
||||||
solution.resize(0);
|
|
||||||
m_SubjFillType = subjFillType;
|
|
||||||
@@ -1560,7 +1592,7 @@ void Clipper::FixHoleLinkage(OutRec &outrec)
|
|
||||||
bool Clipper::ExecuteInternal()
|
|
||||||
{
|
|
||||||
bool succeeded = true;
|
|
||||||
- try {
|
|
||||||
+ CLIPPER_TRY {
|
|
||||||
Reset();
|
|
||||||
m_Maxima = MaximaList();
|
|
||||||
m_SortedEdges = 0;
|
|
||||||
@@ -1583,7 +1615,7 @@ bool Clipper::ExecuteInternal()
|
|
||||||
InsertLocalMinimaIntoAEL(botY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- catch(...)
|
|
||||||
+ CLIPPER_CATCH(...)
|
|
||||||
{
|
|
||||||
succeeded = false;
|
|
||||||
}
|
|
||||||
@@ -2827,18 +2859,18 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
|
|
||||||
bool Clipper::ProcessIntersections(const cInt topY)
|
|
||||||
{
|
|
||||||
if( !m_ActiveEdges ) return true;
|
|
||||||
- try {
|
|
||||||
+ CLIPPER_TRY {
|
|
||||||
BuildIntersectList(topY);
|
|
||||||
size_t IlSize = m_IntersectList.size();
|
|
||||||
if (IlSize == 0) return true;
|
|
||||||
if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList();
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
- catch(...)
|
|
||||||
+ CLIPPER_CATCH(...)
|
|
||||||
{
|
|
||||||
m_SortedEdges = 0;
|
|
||||||
DisposeIntersectNodes();
|
|
||||||
- throw clipperException("ProcessIntersections error");
|
|
||||||
+ CLIPPER_THROW(clipperException("ProcessIntersections error"));
|
|
||||||
}
|
|
||||||
m_SortedEdges = 0;
|
|
||||||
return true;
|
|
||||||
@@ -3002,7 +3034,7 @@ void Clipper::DoMaxima(TEdge *e)
|
|
||||||
DeleteFromAEL(eMaxPair);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
- else throw clipperException("DoMaxima error");
|
|
||||||
+ else CLIPPER_THROW(clipperException("DoMaxima error"));
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user