From 5760dbb67f4968e4832506bd7d187815fe3d2828 Mon Sep 17 00:00:00 2001 From: skyrpex Date: Wed, 30 Oct 2013 22:17:24 +0100 Subject: [PATCH] Merge with v6.0.0 --- Beziers/Beziers.cs | 666 -- Beziers/Beziers.pas | 899 -- Beziers/beziers.cpp | 729 -- Beziers/beziers.hpp | 60 - C#/ConsoleDemo/ConsoleDemo/Program.cs | 100 +- C#/GuiDemo/GuiDemo/Form1.cs | 59 +- C#/clipper_library/clipper.cs | 7876 +++++++++-------- Curves/CurvesDemo/CurvesDemo.csproj | 110 + Curves/CurvesDemo/CurvesDemo.sln | 30 + Curves/CurvesDemo/Form1.Designer.cs | 609 ++ Curves/CurvesDemo/Form1.cs | 834 ++ Curves/CurvesDemo/Form1.resx | 135 + Curves/CurvesDemo/MultiPaths.cs | 1777 ++++ Curves/CurvesDemo/Program.cs | 20 + Curves/CurvesDemo/Properties/AssemblyInfo.cs | 36 + .../Properties/Resources.Designer.cs | 63 + Curves/CurvesDemo/Properties/Resources.resx | 117 + Curves/CurvesDemo/app.config | 3 + .../bin/Debug/Clipper_Curves_Demo.exe | Bin 0 -> 119808 bytes Curves/CurvesDemo/bin/Debug/paths.txt | 2 + Curves/CurvesDemo/clipper.cs | 4808 ++++++++++ Delphi/agg demo/about_agg.txt | 1 - Delphi/agg demo/agg_conv_clipper.pas | 343 - Delphi/agg demo/clipper_test.dpr | 975 -- Delphi/agg demo/clipper_test.exe | Bin 247296 -> 0 bytes Delphi/cairo demo/CairoClipperDemo1.dpr | 4 +- Delphi/cairo demo/cairo_clipper.pas | 8 +- Delphi/clipper.pas | 3695 +++++--- Delphi/main demo/GR32_Misc.pas | 2 +- Delphi/main demo/main.dfm | 5 +- Delphi/main demo/main.pas | 78 +- Documentation/Docs/Overview/Changes.htm | 983 +- Documentation/Docs/Overview/Deprecated.htm | 162 + Documentation/Docs/Overview/Example.htm | 56 +- Documentation/Docs/Overview/FAQ.htm | 66 +- Documentation/Docs/Overview/License.htm | 2 +- Documentation/Docs/Overview/Rounding.htm | 10 +- Documentation/Docs/Overview/_Body.htm | 28 +- .../Classes/Clipper/Methods/Constructor.htm | 95 + .../Classes/Clipper/Methods/Execute.htm | 28 +- ...{ForceSimple.htm => PreserveCollinear.htm} | 21 +- .../Clipper/Properties/ReverseSolution.htm | 4 +- .../Clipper/Properties/StrictlySimple.htm | 88 + .../Clipper/Properties/ZFillFunction.htm | 88 + .../ClipperLib/Classes/Clipper/_Body.htm | 33 +- .../Classes/ClipperBase/Methods/AddPath.htm | 95 + .../Classes/ClipperBase/Methods/AddPaths.htm | 93 + .../ClipperBase/Methods/AddPolygon.htm | 92 - .../ClipperBase/Methods/AddPolygons.htm | 90 - .../Classes/ClipperBase/Methods/Clear.htm | 2 +- .../Classes/ClipperBase/Methods/GetBounds.htm | 2 +- .../ClipperLib/Classes/ClipperBase/_Body.htm | 19 +- .../Classes/PolyNode/Methods/GetNext.htm | 2 +- .../PolyNode/Properties/ChildCount.htm | 2 +- .../Classes/PolyNode/Properties/Childs.htm | 2 +- .../Classes/PolyNode/Properties/Contour.htm | 10 +- .../Classes/PolyNode/Properties/IsHole.htm | 2 +- .../Classes/PolyNode/Properties/IsOpen.htm | 72 + .../Classes/PolyNode/Properties/Parent.htm | 2 +- .../ClipperLib/Classes/PolyNode/_Body.htm | 17 +- .../Classes/PolyTree/Methods/Clear.htm | 2 +- .../Classes/PolyTree/Methods/GetFirst.htm | 2 +- .../Classes/PolyTree/Properties/Total.htm | 2 +- .../ClipperLib/Classes/PolyTree/_Body.htm | 25 +- .../{Routines => Functions}/Area.htm | 12 +- .../{Routines => Functions}/CleanPolygon.htm | 20 +- .../ClipperLib/Functions/CleanPolygons.htm | 87 + .../Functions/ClosedPathsFromPolyTree.htm | 71 + .../MinkowskiDiff.htm} | 27 +- .../ClipperLib/Functions/MinkowskiSum.htm | 73 + .../OffsetPaths.htm} | 26 +- .../Functions/OpenPathsFromPolyTree.htm | 71 + .../{Routines => Functions}/Orientation.htm | 18 +- .../ClipperLib/Functions/PolyTreeToPaths.htm | 71 + .../ReversePath.htm} | 16 +- .../ReversePaths.htm} | 14 +- .../SimplifyPolygon.htm | 12 +- .../SimplifyPolygons.htm | 14 +- .../Units/ClipperLib/PreProcessor/Defines.htm | 70 + .../ClipperLib/Routines/OffsetPolygons.htm | 91 - .../Docs/Units/ClipperLib/Types/CInt.htm | 70 + .../Docs/Units/ClipperLib/Types/ClipType.htm | 17 +- .../Docs/Units/ClipperLib/Types/EndType.htm | 12 +- .../Units/ClipperLib/Types/ExPolygons.htm | 204 - .../Units/ClipperLib/Types/InitOptions.htm | 75 + .../Docs/Units/ClipperLib/Types/IntPoint.htm | 12 +- .../Docs/Units/ClipperLib/Types/IntRect.htm | 10 +- .../Docs/Units/ClipperLib/Types/JoinType.htm | 8 +- .../Types/{Polygon.htm => Path.htm} | 16 +- .../Types/{Polygons.htm => Paths.htm} | 16 +- .../Units/ClipperLib/Types/PolyFillType.htm | 14 +- .../Docs/Units/ClipperLib/Types/PolyType.htm | 4 +- .../Types/{long64.htm => ZFillCallback.htm} | 16 +- Documentation/Docs/Units/ClipperLib/_Body.htm | 100 +- Documentation/Docs/_Body.htm | 67 +- Documentation/Html_Docs.zip | Bin 683537 -> 0 bytes Documentation/Images/common_edges.png | Bin 0 -> 66132 bytes Documentation/Images/endtypes.png | Bin 0 -> 8551 bytes Documentation/Images/jointypes.png | Bin 6693 -> 7899 bytes Documentation/Images/jointypes2.png | Bin 5662 -> 0 bytes Documentation/Images/line_clipping.png | Bin 0 -> 40765 bytes Documentation/Images/line_clipping2.png | Bin 0 -> 25061 bytes Documentation/Images/linesdemo.png | Bin 0 -> 42798 bytes Documentation/Images/minkowski.png | Bin 0 -> 4871 bytes Documentation/Images/minkowski2.png | Bin 0 -> 2248 bytes Documentation/Images/polyline_offset.png | Bin 8016 -> 0 bytes Documentation/Images/polylines.png | Bin 4836 -> 0 bytes Documentation/Images/zfill.png | Bin 0 -> 5762 bytes .../scripts/shBrushCSharp.js | 5 + Documentation/Scripts/menu_data.js | 6 +- Documentation/clipper.chm | Bin 361748 -> 507124 bytes README | 35 +- cpp/CMakeLists.txt | 4 +- cpp/clipper.cpp | 4306 +++++---- cpp/clipper.hpp | 318 +- cpp/cpp_agg/agg_conv_clipper.h | 42 +- cpp/cpp_cairo/cairo_clipper.cpp | 12 +- cpp/cpp_cairo/cairo_clipper.hpp | 4 +- cpp/cpp_cairo/main.cpp | 16 +- cpp/cpp_console/Debug/clip.txt | 6 - cpp/cpp_console/Debug/subj.txt | 13 - cpp/cpp_console/File1.cpp | 458 - cpp/cpp_console/clipper.cbproj | 147 - cpp/cpp_opengl/clipper_demo.exe | Bin 208384 -> 219136 bytes cpp/cpp_opengl/clipper_demo.vcxproj | 7 +- cpp/cpp_opengl/main.cpp | 251 +- cpp/cpp_opengl/menu.res | Bin 1352 -> 1352 bytes python/clipper.py | 479 +- 128 files changed, 20869 insertions(+), 12815 deletions(-) delete mode 100644 Beziers/Beziers.cs delete mode 100644 Beziers/Beziers.pas delete mode 100644 Beziers/beziers.cpp delete mode 100644 Beziers/beziers.hpp create mode 100644 Curves/CurvesDemo/CurvesDemo.csproj create mode 100644 Curves/CurvesDemo/CurvesDemo.sln create mode 100644 Curves/CurvesDemo/Form1.Designer.cs create mode 100644 Curves/CurvesDemo/Form1.cs create mode 100644 Curves/CurvesDemo/Form1.resx create mode 100644 Curves/CurvesDemo/MultiPaths.cs create mode 100644 Curves/CurvesDemo/Program.cs create mode 100644 Curves/CurvesDemo/Properties/AssemblyInfo.cs create mode 100644 Curves/CurvesDemo/Properties/Resources.Designer.cs create mode 100644 Curves/CurvesDemo/Properties/Resources.resx create mode 100644 Curves/CurvesDemo/app.config create mode 100644 Curves/CurvesDemo/bin/Debug/Clipper_Curves_Demo.exe create mode 100644 Curves/CurvesDemo/bin/Debug/paths.txt create mode 100644 Curves/CurvesDemo/clipper.cs delete mode 100644 Delphi/agg demo/about_agg.txt delete mode 100644 Delphi/agg demo/agg_conv_clipper.pas delete mode 100644 Delphi/agg demo/clipper_test.dpr delete mode 100644 Delphi/agg demo/clipper_test.exe create mode 100644 Documentation/Docs/Overview/Deprecated.htm create mode 100644 Documentation/Docs/Units/ClipperLib/Classes/Clipper/Methods/Constructor.htm rename Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/{ForceSimple.htm => PreserveCollinear.htm} (58%) create mode 100644 Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/StrictlySimple.htm create mode 100644 Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ZFillFunction.htm create mode 100644 Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPath.htm create mode 100644 Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPaths.htm delete mode 100644 Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPolygon.htm delete mode 100644 Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPolygons.htm create mode 100644 Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/IsOpen.htm rename Documentation/Docs/Units/ClipperLib/{Routines => Functions}/Area.htm (74%) rename Documentation/Docs/Units/ClipperLib/{Routines => Functions}/CleanPolygon.htm (56%) create mode 100644 Documentation/Docs/Units/ClipperLib/Functions/CleanPolygons.htm create mode 100644 Documentation/Docs/Units/ClipperLib/Functions/ClosedPathsFromPolyTree.htm rename Documentation/Docs/Units/ClipperLib/{Routines/CleanPolygons.htm => Functions/MinkowskiDiff.htm} (57%) create mode 100644 Documentation/Docs/Units/ClipperLib/Functions/MinkowskiSum.htm rename Documentation/Docs/Units/ClipperLib/{Routines/OffsetPolyLines.htm => Functions/OffsetPaths.htm} (58%) create mode 100644 Documentation/Docs/Units/ClipperLib/Functions/OpenPathsFromPolyTree.htm rename Documentation/Docs/Units/ClipperLib/{Routines => Functions}/Orientation.htm (66%) create mode 100644 Documentation/Docs/Units/ClipperLib/Functions/PolyTreeToPaths.htm rename Documentation/Docs/Units/ClipperLib/{Routines/ReversePolygon.htm => Functions/ReversePath.htm} (80%) rename Documentation/Docs/Units/ClipperLib/{Routines/ReversePolygons.htm => Functions/ReversePaths.htm} (81%) rename Documentation/Docs/Units/ClipperLib/{Routines => Functions}/SimplifyPolygon.htm (65%) rename Documentation/Docs/Units/ClipperLib/{Routines => Functions}/SimplifyPolygons.htm (57%) create mode 100644 Documentation/Docs/Units/ClipperLib/PreProcessor/Defines.htm delete mode 100644 Documentation/Docs/Units/ClipperLib/Routines/OffsetPolygons.htm create mode 100644 Documentation/Docs/Units/ClipperLib/Types/CInt.htm delete mode 100644 Documentation/Docs/Units/ClipperLib/Types/ExPolygons.htm create mode 100644 Documentation/Docs/Units/ClipperLib/Types/InitOptions.htm rename Documentation/Docs/Units/ClipperLib/Types/{Polygon.htm => Path.htm} (59%) rename Documentation/Docs/Units/ClipperLib/Types/{Polygons.htm => Paths.htm} (57%) rename Documentation/Docs/Units/ClipperLib/Types/{long64.htm => ZFillCallback.htm} (67%) delete mode 100644 Documentation/Html_Docs.zip create mode 100644 Documentation/Images/common_edges.png create mode 100644 Documentation/Images/endtypes.png delete mode 100644 Documentation/Images/jointypes2.png create mode 100644 Documentation/Images/line_clipping.png create mode 100644 Documentation/Images/line_clipping2.png create mode 100644 Documentation/Images/linesdemo.png create mode 100644 Documentation/Images/minkowski.png create mode 100644 Documentation/Images/minkowski2.png delete mode 100644 Documentation/Images/polyline_offset.png delete mode 100644 Documentation/Images/polylines.png create mode 100644 Documentation/Images/zfill.png delete mode 100644 cpp/cpp_console/Debug/clip.txt delete mode 100644 cpp/cpp_console/Debug/subj.txt delete mode 100644 cpp/cpp_console/File1.cpp delete mode 100644 cpp/cpp_console/clipper.cbproj diff --git a/Beziers/Beziers.cs b/Beziers/Beziers.cs deleted file mode 100644 index 017bf28..0000000 --- a/Beziers/Beziers.cs +++ /dev/null @@ -1,666 +0,0 @@ -/******************************************************************************* -* * -* Author : Angus Johnson * -* Version : 1.0 * -* Date : 27 August 2013 * -* Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2013 * -* * -* License: * -* Use, modification & distribution is subject to Boost Software License Ver 1. * -* http://www.boost.org/LICENSE_1_0.txt * -* * -*******************************************************************************/ - -using System; -using System.Collections.Generic; -using ClipperLib; - -namespace BezierLib -{ - - using Path = List; - using Paths = List>; - - public enum BezierType { CubicBezier, QuadBezier }; - - public class BezierList - { - private const double DefaultPrecision = 0.5; - private List m_Beziers = new List(); - - public BezierList(double precision = DefaultPrecision) - { - Precision = (precision <= 0 ? DefaultPrecision : precision); - } - //------------------------------------------------------------------------------ - - public void AddPath(Path ctrlPts, BezierType bezType) - { - Bezier bezier = new Bezier(ctrlPts, bezType, (ushort)m_Beziers.Count, Precision); - m_Beziers.Add(bezier); - } - //------------------------------------------------------------------------------ - - public void AddPaths(Paths ctrlPts, BezierType bezType) - { - int minCnt = (bezType == BezierType.CubicBezier ? 4 : 3); - foreach (Path p in ctrlPts) - { - if (p.Count < minCnt) continue; - Bezier bezier = new Bezier(p, bezType, (ushort)m_Beziers.Count, Precision); - m_Beziers.Add(bezier); - } - } - //------------------------------------------------------------------------------ - - public void Clear() - { - m_Beziers.Clear(); - } - //------------------------------------------------------------------------------ - - public double Precision { get; set; } - //------------------------------------------------------------------------------ - - public BezierType GetBezierType(int index) - { - if (index < 0 || index >= m_Beziers.Count) - throw new BezierException("BezierList: index out of range."); - return m_Beziers[index].beziertype; - } - //------------------------------------------------------------------------------ - - public Path GetCtrlPts(int index) - { - if (index < 0 || index >= m_Beziers.Count) - throw new BezierException("BezierList: index out of range."); - Path result = new Path(m_Beziers[index].path); - return result; - } - //------------------------------------------------------------------------------ - - public Path GetFlattenedPath(int index) - { - if (index < 0 || index >= m_Beziers.Count) - throw new BezierException("BezierList: index out of range."); - Path result = new Path(m_Beziers[index].FlattenedPath()); - return result; - } - //------------------------------------------------------------------------------ - - public Paths GetFlattenedPaths() - { - Paths result = new Paths(m_Beziers.Count); - foreach (Bezier b in m_Beziers) - result.Add(b.FlattenedPath()); - return result; - } - //------------------------------------------------------------------------------ - - public static Path Flatten(Path path, BezierType bezType, double precision = DefaultPrecision) - { - if (path.Count < 4) return new Path(); - Bezier b = new Bezier(path, bezType, 0, precision); - return b.FlattenedPath(); - } - //------------------------------------------------------------------------------ - - public static Paths Flatten(Paths paths, BezierType bezType, double precision = DefaultPrecision) - { - int minCnt = (bezType == BezierType.CubicBezier ? 4 : 3); - Paths result = new Paths(paths.Count); - for (int i = 0; i < paths.Count; i++) - { - if (paths[i].Count < minCnt) continue; - Bezier b = new Bezier(paths[i], bezType, 0, precision); - result.Add(b.FlattenedPath()); - } - return result; - } - //------------------------------------------------------------------------------ - - private static IntPoint MidPoint(IntPoint p1, IntPoint p2) - { - IntPoint result = new IntPoint((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2, 0); - return result; - } - //------------------------------------------------------------------------------ - - public static Path CSplineToCBezier(Path cSpline) - { - int len = cSpline.Count; - if (len < 4) return new Path(); - if (len % 2 != 0) len--; - int i = (len / 2) - 1; - Path result = new Path(i * 3 + 1); - result.Add(cSpline[0]); - result.Add(cSpline[1]); - result.Add(cSpline[2]); - i = 3; - int lenMin1 = len - 1; - while (i < lenMin1) - { - result.Add(MidPoint(cSpline[i - 1], cSpline[i])); - result.Add(cSpline[i]); - result.Add(cSpline[i + 1]); - i += 2; - } - result.Add(cSpline[lenMin1]); - return result; - } - //------------------------------------------------------------------------------ - - public static Path QSplineToQBezier(Path qSpline) - { - int len = qSpline.Count; - if (len < 3) return new Path(); - if (len % 2 == 0) len--; - int i = len - 2; - Path result = new Path(i * 2 + 1); - result.Add(qSpline[0]); - result.Add(qSpline[1]); - i = 2; - int lenMin1 = len - 1; - while (i < lenMin1) - { - result.Add(MidPoint(qSpline[i - 1], qSpline[i])); - result.Add(qSpline[i++]); - } - result.Add(qSpline[lenMin1]); - return result; - } - //------------------------------------------------------------------------------ - - public Path Reconstruct(Int64 z1, Int64 z2) - { - Path result = new Path(); - UInt16 seg, refId; - BezierType beztype; - Bezier.UnMakeZ(z1, out beztype, out seg, out refId); //nb: just need refId - if (refId >= 0 && refId < m_Beziers.Count) - result = m_Beziers[refId].Reconstruct(z1, z2); - return result; - } - //------------------------------------------------------------------------------ - - } - - internal class Bezier - { - internal const double half = 0.5; - private int reference; - internal BezierType beziertype; - internal Path path = new Path(); //path of Control Pts - //segments: ie supports poly-beziers (ie before flattening) with up to 16,383 segments - internal List segments = new List(); - - internal static Int64 MakeZ(BezierType beziertype, UInt16 seg, UInt16 refId, UInt32 idx) - { - UInt32 hi = (UInt32)((UInt16)beziertype << 30 | seg << 16 | (refId + 1)); - return (Int64)((UInt64)hi << 32 | idx); - } - //------------------------------------------------------------------------------ - - internal static UInt32 UnMakeZ(Int64 zval, - out BezierType beziertype, out UInt16 seg, out UInt16 refId) - { - UInt32 vals = (UInt32)((UInt64)zval >> 32); //the top 32 bits => vals - beziertype = (BezierType)((vals >> 30) & 0x1); - seg = (UInt16)((vals >> 16) & 0x3FFF); - refId = (UInt16)((vals & 0xFFFF) - 1); - return (UInt32)(zval & 0xFFFFFFFF); - } - //------------------------------------------------------------------------------ - - internal class IntNode - { - internal int val; - internal IntNode next; - internal IntNode prev; - internal IntNode(int val) { this.val = val;} - } - - internal IntNode InsertInt(IntNode insertAfter, int val) - { - IntNode result = new IntNode(val); - result.next = insertAfter.next; - result.prev = insertAfter; - if (insertAfter.next != null) - insertAfter.next.prev = result; - insertAfter.next = result; - return result; - } - //------------------------------------------------------------------------------ - - internal IntNode GetFirstIntNode(IntNode current) - { - if (current == null) return null; - IntNode result = current; - while (result.prev != null) - result = result.prev; - //now skip the very first (dummy) node ... - return result.next; - } - //------------------------------------------------------------------------------ - - internal DoublePoint MidPoint(IntPoint ip1, IntPoint ip2) - { - return new DoublePoint((double)(ip1.X + ip2.X) / 2, (double)(ip1.Y + ip2.Y) / 2); - } - //------------------------------------------------------------------------------ - - internal UInt32 GetMostSignificantBit(UInt32 v) //index is zero based - { - UInt32[] b = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; - Int32[] s = {0x1, 0x2, 0x4, 0x8, 0x10}; - Int32 result = 0; - for (int i = 4; i >= 0; --i) - if ((v & b[i]) != 0) - { - v = v >> s[i]; - result = result | s[i]; - } - return (UInt32)result; - } - //------------------------------------------------------------------------------ - - internal bool IsBitSet(UInt32 val, Int32 index) - { - return (val & (1 << (int)index)) != 0; - } - //------------------------------------------------------------------------------ - - internal bool Odd(Int32 val) - { - return (val % 2) != 0; - } - //------------------------------------------------------------------------------ - - internal bool Even(Int32 val) - { - return (val % 2) == 0; - } - //------------------------------------------------------------------------------ - - internal static Int64 Round(double value) - { - return value < 0 ? (Int64)(value - 0.5) : (Int64)(value + 0.5); - } - - //------------------------------------------------------------------------------ - //------------------------------------------------------------------------------ - - internal class Segment - { - internal BezierType beziertype; - internal UInt16 RefID; - internal UInt16 SegID; - internal UInt32 Index; - internal DoublePoint[] Ctrls = new DoublePoint[4]; - internal Segment[] Childs = new Segment[2]; - internal Segment(UInt16 refID, UInt16 segID, UInt32 idx) - { - this.RefID = refID; - this.SegID = segID; - this.Index = idx; - } - - internal void GetFlattenedPath(Path path, bool init) - { - if (init) - { - Int64 Z = MakeZ(beziertype, SegID, RefID, Index); - path.Add(new IntPoint(Round(Ctrls[0].X), Round(Ctrls[0].Y), Z)); - } - - if (Childs[0] == null) - { - int CtrlIdx = (beziertype == BezierType.CubicBezier ? 3: 2); - Int64 Z = MakeZ(beziertype, SegID, RefID, Index); - path.Add(new IntPoint(Round(Ctrls[CtrlIdx].X), Round(Ctrls[CtrlIdx].Y), Z)); - } - else - { - Childs[0].GetFlattenedPath(path, false); - Childs[1].GetFlattenedPath(path, false); - } - } - - internal void AddCtrlPtsToPath(Path ctrlPts) - { - int firstDelta = (ctrlPts.Count == 0 ? 0 : 1); - switch (beziertype) - { - case BezierType.CubicBezier: - for (int i = firstDelta; i < 4; ++i) - { - ctrlPts.Add(new IntPoint( - Round(Ctrls[i].X), Round(Ctrls[i].Y))); - } - break; - case BezierType.QuadBezier: - for (int i = firstDelta; i < 3; ++i) - { - ctrlPts.Add(new IntPoint( - Round(Ctrls[i].X), Round(Ctrls[i].Y))); - } - break; - } - } - - } //end Segment - //------------------------------------------------------------------------------ - - private class CubicBez : Segment - { - internal CubicBez(DoublePoint pt1, DoublePoint pt2, DoublePoint pt3, DoublePoint pt4, - UInt16 refID, UInt16 segID, UInt32 idx, double precision): base(refID, segID, idx) - { - - beziertype = BezierType.CubicBezier; - Ctrls[0] = pt1; Ctrls[1] = pt2; Ctrls[2] = pt3; Ctrls[3] = pt4; - //assess curve flatness: - //http://groups.google.com/group/comp.graphics.algorithms/tree/browse_frm/thread/d85ca902fdbd746e - if (Math.Abs(pt1.X + pt3.X - 2*pt2.X) + Math.Abs(pt2.X + pt4.X - 2*pt3.X) + - Math.Abs(pt1.Y + pt3.Y - 2*pt2.Y) + Math.Abs(pt2.Y + pt4.Y - 2*pt3.Y) < precision) - return; - - //if not at maximum precision then (recursively) create sub-segments ... - //, p23, p34, p123, p234, p1234; - DoublePoint p12 = new DoublePoint((pt1.X + pt2.X) * half, (pt1.Y + pt2.Y) * half); - DoublePoint p23 = new DoublePoint((pt2.X + pt3.X) * half, (pt2.Y + pt3.Y) * half); - DoublePoint p34 = new DoublePoint((pt3.X + pt4.X) * half, (pt3.Y + pt4.Y) * half); - DoublePoint p123 = new DoublePoint((p12.X + p23.X) * half, (p12.Y + p23.Y) * half); - DoublePoint p234 = new DoublePoint((p23.X + p34.X) * half, (p23.Y + p34.Y) * half); - DoublePoint p1234 = new DoublePoint((p123.X + p234.X) * half, (p123.Y + p234.Y) * half); - idx = idx << 1; - Childs[0] = new CubicBez(pt1, p12, p123, p1234, refID, segID, idx, precision); - Childs[1] = new CubicBez(p1234, p234, p34, pt4, refID, segID, idx +1, precision); - } //end CubicBez constructor - } //end CubicBez - - private class QuadBez : Segment - { - internal QuadBez(DoublePoint pt1, DoublePoint pt2, DoublePoint pt3, - UInt16 refID, UInt16 segID, UInt32 idx, double precision): base(refID, segID, idx) - { - - beziertype = BezierType.QuadBezier; - Ctrls[0] = pt1; Ctrls[1] = pt2; Ctrls[2] = pt3; - //assess curve flatness: - if (Math.Abs(pt1.X + pt3.X - 2*pt2.X) + Math.Abs(pt1.Y + pt3.Y - 2*pt2.Y) < precision) return; - - //if not at maximum precision then (recursively) create sub-segments ... - //DoublePoint p12, p23, p123; - DoublePoint p12 = new DoublePoint((pt1.X + pt2.X) * half, (pt1.Y + pt2.Y) * half); - DoublePoint p23 = new DoublePoint((pt2.X + pt3.X) * half, (pt2.Y + pt3.Y) * half); - DoublePoint p123 = new DoublePoint((p12.X + p23.X) * half, (p12.Y + p23.Y) * half); - idx = idx << 1; - Childs[0] = new QuadBez(pt1, p12, p123, refID, segID, idx, precision); - Childs[1] = new QuadBez(p123, p23, pt3, refID, segID, idx +1, precision); - } //end QuadBez constructor - } //end QuadBez - //------------------------------------------------------------------------------ - - Bezier() { } - //------------------------------------------------------------------------------ - - ~Bezier() { Clear(); } - //------------------------------------------------------------------------------ - - internal void Clear() - { - segments.Clear(); - } - //------------------------------------------------------------------------------ - - internal Bezier(Path ctrlPts, BezierType beztype, UInt16 refID, double precision) - { - SetCtrlPoints(ctrlPts, beztype, refID, precision); - } - //------------------------------------------------------------------------------ - - internal void SetCtrlPoints(Path ctrlPts, BezierType beztype, UInt16 refID, double precision) - { - //clean up any existing data ... - segments.Clear(); - - this.beziertype = beztype; - this.reference = refID; - this.path = ctrlPts; - int highpts = ctrlPts.Count - 1; - - switch( beztype ) - { - case BezierType.CubicBezier: - if (highpts < 3) throw new BezierException("CubicBezier: insuffient control points."); - else highpts -= highpts % 3; - break; - case BezierType.QuadBezier: - if (highpts < 2) throw new BezierException("QuadBezier: insuffient control points."); - else highpts -= highpts % 2; - break; - default: throw new BezierException("Unsupported bezier type"); - } - - //now for each segment in the poly-bezier create a binary tree structure - //and add it to SegmentList ... - switch( beztype ) - { - case BezierType.CubicBezier: - for (UInt16 i = 0; i < ((UInt16)highpts / 3); ++i) - { - Segment s = new CubicBez( - new DoublePoint(ctrlPts[i*3]), - new DoublePoint(ctrlPts[i*3+1]), - new DoublePoint(ctrlPts[i*3+2]), - new DoublePoint(ctrlPts[i*3+3]), - refID, i, 1, precision); - segments.Add(s); - } - break; - case BezierType.QuadBezier: - for (UInt16 i = 0; i < ((UInt16)highpts / 2); ++i) - { - Segment s = new QuadBez( - new DoublePoint(ctrlPts[i*2]), - new DoublePoint(ctrlPts[i*2+1]), - new DoublePoint(ctrlPts[i*2+2]), - refID, i, 1, precision); - segments.Add(s); - } - break; - } - } - //------------------------------------------------------------------------------ - - internal Path FlattenedPath() - { - Path path = new Path(); - for (int i = 0; i < segments.Count; i++) - segments[i].GetFlattenedPath(path, i == 0); - IntPoint pt = path[0]; - pt.Z = (Int64)((UInt64)pt.Z | 0x8000000000000000); //StartOfPath flag - path[0] = pt; - return path; - } - - //------------------------------------------------------------------------------ - - internal Path Reconstruct(Int64 startZ, Int64 endZ) - { - Path out_poly = new Path(); - if (endZ == startZ) return out_poly; - - bool reversed = false; - if (endZ < 0) - { - Int64 tmp = startZ; - startZ = endZ; - endZ = tmp; - reversed = true; - } - - BezierType bt1, bt2; - UInt16 seg1, seg2; - UInt16 ref1, ref2; - startZ = UnMakeZ(startZ, out bt1, out seg1, out ref1); - endZ = UnMakeZ(endZ, out bt2, out seg2, out ref2); - - if (bt1 != beziertype || bt1 != bt2 || - ref1 != reference || ref1 != ref2) return out_poly; - - if (seg1 >= segments.Count || seg2 >= segments.Count) return out_poly; - - if (seg1 > seg2) - { - UInt16 i = seg1; - seg1 = seg2; - seg2 = i; - Int64 tmp = startZ; - startZ = endZ; - endZ = tmp; - } - - //do further checks for reversal, in case reversal within a single segment ... - if (!reversed && seg1 == seg2 && startZ != 1 && endZ != 1) - { - UInt32 i = GetMostSignificantBit((uint)startZ); - UInt32 j = GetMostSignificantBit((uint)endZ); - UInt32 k = Math.Max(i, j); - //nb: we must compare Node indexes at the same level ... - i = (uint)startZ << (int)(k - i); - j = (uint)endZ << (int)(k - j); - if (i > j) - { - Int64 tmp = startZ; - startZ = endZ; - endZ = tmp; - reversed = true; - } - } - - while (seg1 <= seg2) - { - //create a dummy first IntNode for the Int List ... - IntNode intList = new IntNode(0); - IntNode intCurr = intList; - - if (seg1 != seg2) - ReconstructInternal(seg1, (uint)startZ, 1, intCurr); - else - ReconstructInternal(seg1, (uint)startZ, (uint)endZ, intCurr); - - //IntList now contains the indexes of one or a series of sub-segments - //that together define part of or the whole of the original segment. - //We now append these sub-segments to the new list of control points ... - - intCurr = intList.next; //nb: skips the dummy IntNode - while (intCurr != null) - { - Segment s = segments[seg1]; - UInt32 j = (UInt32)intCurr.val; - Int32 k = (Int32)GetMostSignificantBit(j) - 1; - while (k >= 0) - { - if (s.Childs[0] == null) break; - if (IsBitSet(j, k--)) - s = s.Childs[1]; - else - s = s.Childs[0]; - } - s.AddCtrlPtsToPath(out_poly); - intCurr = intCurr.next; - } //while - - intList = null; - seg1++; - startZ = 1; - } - if (reversed) out_poly.Reverse(); - return out_poly; - } - //------------------------------------------------------------------------------ - - internal void ReconstructInternal(UInt16 segIdx, UInt32 startIdx, UInt32 endIdx, IntNode intCurr) - { - //get the maximum level ... - UInt32 L1 = GetMostSignificantBit(startIdx); - UInt32 L2 = GetMostSignificantBit(endIdx); - UInt32 Level = Math.Max(L1, L2); - - if (Level == 0) - { - InsertInt(intCurr, 1); - return; - } - - int L, R; - //Right marker (R): EndIdx projected onto the bottom level ... - if (endIdx == 1) - { - R = (1 << (int)((Level +1))) - 1; - } else - { - int k = (int)(Level - L2); - R = ((int)endIdx << k) + (1 << k) - 1; - } - - if (startIdx == 1) //special case - { - //Left marker (L) is bottom left of the binary tree ... - L = (1 << (int)Level); - L1 = Level; - } else - { - //For any given Z value, its corresponding X & Y coords (created by - //FlattenPath using De Casteljau's algorithm) refered to the ctrl[3] coords - //of many tiny polybezier segments. Since ctrl[3] coords are identical to - //ctrl[0] coords in the following node, we can safely increment StartIdx ... - L = (int)startIdx + 1; - if (L == (1 << (int)(Level + 1))) return; //loops around tree so already at the end - } - - //now get blocks of nodes from the LEFT ... - int j = (int)(Level - L1); - do - { - //while next level up then down-right doesn't exceed L2 do ... - while (Even(L) && ((L << j) + (1 << (j + 1)) - 1 <= R)) - { - L = (L >> 1); //go up a level - j++; - } - intCurr = InsertInt(intCurr, L); //nb: updates IntCurrent - L++; - } while (L != (3 << (int)(Level - j - 1)) && //ie crosses the ditch in the middle - (L << j) + (1 << j) < R); //or L is now over or to the right of R - - L = (L << j); - - //now get blocks of nodes from the RIGHT ... - j = 0; - if (R >= L) - do - { - while (Odd(R) && ((R-1) << j >= L)) - { - R = R >> 1; //go up a level - j++; - } - InsertInt(intCurr, R); //nb: doesn't update IntCurrent - R--; - } while (R != (3 << (int)(Level - j)) -1 && ((R << j) > L)); - - } - //------------------------------------------------------------------------------ - - } //end Bezier - //------------------------------------------------------------------------------ - - class BezierException : Exception - { - public BezierException(string description) : base(description){} - } -} diff --git a/Beziers/Beziers.pas b/Beziers/Beziers.pas deleted file mode 100644 index fec8697..0000000 --- a/Beziers/Beziers.pas +++ /dev/null @@ -1,899 +0,0 @@ -unit Beziers; - -(******************************************************************************* -* * -* Author : Angus Johnson * -* Version : 1.0 * -* Date : 27 August 2013 * -* Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2013 * -* * -* License: * -* Use, modification & distribution is subject to Boost Software License Ver 1. * -* http://www.boost.org/LICENSE_1_0.txt * -* * -*******************************************************************************) - -interface - -uses - Windows, Messages, SysUtils, Classes, Math, clipper; - -const - DefaultPrecision = 0.5; - -type - //TBezierType: a parameter of TBezier's constructor - TBezierType = (CubicBezier, QuadBezier); - - //The TPath structure is defined in Clipper.pas ... - //TPath = Array of TIntPoint; - //TIntPoint = record X,Y,Z: Int64; end; - - TBezierList = class - private - FList: TList; - FPrecision: Double; - public - constructor Create(Precision: Double = DefaultPrecision); - destructor Destroy; override; - - procedure AddPath(const CtrlPts: TPath; BezType: TBezierType); - procedure AddPaths(const CtrlPts: TPaths; BezType: TBezierType); - procedure Clear; - - function GetCtrlPts(index: Integer): TPath; - function GetBezierType(index: Integer): TBezierType; - function GetFlattenedPath(index: Integer): TPath; - function GetFlattenedPaths(): TPaths; - - class function Flatten(path: TPath; BezType: TBezierType; - Precision: Double = DefaultPrecision): TPath; overload; - class function Flatten(paths: TPaths; BezType: TBezierType; - Precision: Double = DefaultPrecision): TPaths; overload; - - class function CSplineToCBezier(CubicSpline: TPath): TPath; - class function QSplineToQBezier(QuadSpline: TPath): TPath; - - function Reconstruct(Z1, Z2: Int64): TPath; //Control points again. - property Precision: Double read FPrecision write FPrecision; - end; - -implementation - -{$IF CompilerVersion >= 20} - {$DEFINE INLINING} -{$IFEND} - -resourcestring - rsInvalidBezierPointCount = 'TBezier: invalid number of control points.'; - rsInvalidBezierType = 'TBezier: invalid type.'; - rsIndexRange = 'TBezierList: index out of range'; - rsZMemberDisabled = 'TBezierList: Z member of TIntPoint is disabled.'; - -const - half = 0.5; - -type - - //IntNode: used internally only - PIntNode = ^TIntNode; - TIntNode = record - Val: Integer; - Next: PIntNode; - Prev: PIntNode; - end; - - //TBezier: Flattens poly-bezier curves, and later reconstructs them. - //The FlattenedPath method stores data in the Z members of the returned - //TPath structure and this is used for bezier reconstruction. - //Any two Z values (of the IntPoints returned by the FlattenedPath method) - //are sufficient to allow reconstruction of part or all of the original curve. - - TBezier = class - private - Reference : Integer; - FBezierType: TBezierType; - FCtrlPoints: TPath; - //supports poly-beziers (ie before flattening) with up to 16,383 segments - SegmentList: TList; - procedure ReconstructInternal(SegIdx: Integer; - StartIdx, EndIdx: Int64; IntCurrent: PIntNode); - public - constructor Create; overload; - constructor Create( - const CtrlPts: TPath; //CtrlPts: Bezier control points - BezType: TBezierType; //CubicBezier or QuadBezier ... - Ref: Word; //Ref: user supplied identifier; - Precision: Double //Precision of flattened path - ); overload; - destructor Destroy; override; - procedure Clear; - procedure SetCtrlPoints(const CtrlPts: TPath; - BezType: TBezierType; Ref: Word; Precision: Double = 0.25); - function FlattenedPath: TPath; - //Reconstruct: returns a list of Bezier control points using the - //information provided in the startZ and endZ parameters (together with - //the object's stored data) ... - function Reconstruct(startZ, endZ: Int64): TPath; //Control points again. - property BezierType: TBezierType read FBezierType write FBezierType; - property CtrlPoints: TPath read FCtrlPoints; - end; - - TSegment = class - protected - BezierType: TBezierType; - RefID, SegID: Word; - Index: Cardinal; - Ctrls: array [0..3] of TDoublePoint; - Childs: array [0..1] of TSegment; - procedure GetFlattenedPath(var Path: TPath; - var Cnt: Integer; Init: Boolean); overload; - procedure AddCtrlPtsToPath(var path: TPath; var currCnt: Integer); - public - constructor Create(Ref, Seg, Idx: Cardinal); overload; virtual; - destructor Destroy; override; - end; - - TCubicBez = class(TSegment) - public - constructor Create(const Pt1, Pt2, Pt3, Pt4: TDoublePoint; - Ref, Seg, Idx: Cardinal; Precision: Double); overload; virtual; - end; - - TQuadBez = class(TSegment) - public - constructor Create(const Pt1, Pt2, Pt3: TDoublePoint; - Ref, Seg, Idx: Cardinal; Precision: Double); overload; - end; - -//------------------------------------------------------------------------------ -// Miscellaneous helper functions ... -//------------------------------------------------------------------------------ - -//nb. The format (high to low) of the 64bit Z value returned in the path ... -//Flg (2): Flags StartOfPath and BezierType (CubicBezier, QuadBezier) -//Seg (14): segment index since a bezier may consist of multiple segments -//Ref (16): reference value passed to TBezier owner object -//Idx (32): binary index to sub-segment containing control points - -function MakeZ(BezierType: TBezierType; - Seg, Ref, Idx: Integer): Int64; //{$IFDEF INLINING} inline; {$ENDIF} -begin - //nb: StartOfPath flag (bit63) is set separately - Int64Rec(Result).Lo := Idx; - Int64Rec(Result).Hi := Byte(BezierType) shl 30 or (Seg shl 16) or (Ref +1); -end; -//------------------------------------------------------------------------------ - -function UnMakeZ(ZVal: Int64; - out BezierType: TBezierType; out Seg, Ref: Integer): Integer; -begin - Result := Integer(Int64Rec(ZVal).Lo); - BezierType := TBezierType((ZVal shr 62) and $1); - Ref := (Int64Rec(ZVal).Hi and $FFFF) -1; - Seg := Int64Rec(ZVal).Hi shr 16 and $3FFF; -end; -//------------------------------------------------------------------------------ - -function InsertInt(InsertAfter: PIntNode; Val: Integer): PIntNode; -begin - new(Result); - Result.Val := Val; - Result.Next := InsertAfter.Next; - Result.Prev := InsertAfter; - if assigned(InsertAfter.Next) then - InsertAfter.Next.Prev := Result; - InsertAfter.Next := Result; -end; -//------------------------------------------------------------------------------ - -function GetFirstIntNode(Current: PIntNode): PIntNode; -begin - Result := Current; - if not assigned(Result) then Exit; - while assigned(Result.Prev) do - Result := Result.Prev; - //now skip the very first (dummy) node ... - Result := Result.Next; -end; -//------------------------------------------------------------------------------ - -procedure DisposeIntNodes(IntNodes: PIntNode); -var - IntNode: PIntNode; -begin - if not assigned(IntNodes) then Exit; - while assigned(IntNodes.Prev) do - IntNodes := IntNodes.Prev; - - repeat - IntNode := IntNodes; - IntNodes := IntNodes.Next; - Dispose(IntNode); - until not assigned(IntNodes); -end; -//------------------------------------------------------------------------------ - -procedure AppendToPath(var Path: TPath; - var Cnt: Integer; const Pt: TIntPoint); overload; -const - buffSize = 128; -begin - if Cnt mod buffSize = 0 then - SetLength(Path, Length(Path) + buffSize); - Path[Cnt] := Pt; - Inc(Cnt); -end; -//------------------------------------------------------------------------------ - -function DoublePoint(const Ip: TIntPoint): TDoublePoint; {$IFDEF INLINING} inline; {$ENDIF} -begin - Result.X := Ip.X; - Result.Y := Ip.Y; -end; -//------------------------------------------------------------------------------ - -function GetMostSignificantBit(v: cardinal): cardinal; //index is zero based -var - i: cardinal; -const - b: array [0..4] of cardinal = ($2, $C, $F0, $FF00, $FFFF0000); - s: array [0..4] of cardinal = (1, 2, 4, 8, 16); -begin - result := 0; - for i := 4 downto 0 do - if (v and b[i] <> 0) then - begin - v := v shr s[i]; - result := result or s[i]; - end; -end; -//------------------------------------------------------------------------------ - -function IsBitSet(val, index: cardinal): boolean; {$IFDEF INLINING} inline; {$ENDIF} -begin - result := val and (1 shl index) <> 0; -end; - -//------------------------------------------------------------------------------ - -function MidPoint(const Pt1, Pt2: TIntPoint): TIntPoint; {$IFDEF INLINING} inline; {$ENDIF} -begin - Result.X := (Pt1.X + Pt2.X) div 2; - Result.Y := (Pt1.Y + Pt2.Y) div 2; - Result.Z := 0; -end; - -//------------------------------------------------------------------------------ -// TBezierList methods ... -//------------------------------------------------------------------------------ - -constructor TBezierList.Create(Precision: Double); -begin - if (sizeof(TIntPoint) <> sizeof(cInt) * 3) then - raise Exception.Create(rsZMemberDisabled); - - if Precision <= 0 then Precision := DefaultPrecision; - FPrecision := Precision; - FList := TList.Create; -end; -//------------------------------------------------------------------------------ - -destructor TBezierList.Destroy; -begin - Clear; - FList.Free; -end; -//------------------------------------------------------------------------------ - -procedure TBezierList.AddPath(const CtrlPts: TPath; BezType: TBezierType); -var - NewBez: TBezier; -begin - NewBez := TBezier.Create(CtrlPts, BezType, FList.Count, FPrecision); - FList.Add(NewBez); -end; -//------------------------------------------------------------------------------ - -procedure TBezierList.AddPaths(const CtrlPts: TPaths; BezType: TBezierType); -var - I, MinLen: Integer; - NewBez: TBezier; -begin - if (bezType = CubicBezier) then MinLen := 4 else MinLen := 3; - for I := 0 to high(ctrlPts) do - begin - if length(CtrlPts[I]) < MinLen then continue; - NewBez := TBezier.Create(CtrlPts[I], BezType, FList.Count, FPrecision); - FList.Add(NewBez); - end; -end; -//------------------------------------------------------------------------------ - -procedure TBezierList.Clear; -var - i: Integer; -begin - for i := 0 to FList.Count -1 do - TBezier(FList[i]).Free; - FList.Clear; -end; -//------------------------------------------------------------------------------ - -function TBezierList.GetCtrlPts(index: Integer): TPath; -begin - if (index < 0) or (index >= FList.Count) then - raise Exception.Create(rsIndexRange); - result := TBezier(FList[index]).CtrlPoints; -end; -//------------------------------------------------------------------------------ - -function TBezierList.GetBezierType(index: Integer): TBezierType; -begin - if (index < 0) or (index >= FList.Count) then - raise Exception.Create(rsIndexRange); - result := TBezier(FList[index]).BezierType; -end; -//------------------------------------------------------------------------------ - -function TBezierList.GetFlattenedPath(index: Integer): TPath; -begin - if (index < 0) or (index >= FList.Count) then - raise Exception.Create(rsIndexRange); - result := TBezier(FList[index]).FlattenedPath; -end; -//------------------------------------------------------------------------------ - -function TBezierList.GetFlattenedPaths(): TPaths; -var - I: Integer; -begin - SetLength(result, FList.Count); - for I := 0 to FList.Count -1 do - result[I] := TBezier(FList[I]).FlattenedPath; -end; -//------------------------------------------------------------------------------ - -function TBezierList.Reconstruct(Z1, Z2: Int64): TPath; -var - Seg, Ref: Integer; - BezType: TBezierType; -begin - UnMakeZ(Z1, BezType, Seg, Ref); //UnMakeZ() here just for Ref - if (Ref >= 0) and (Ref < FList.Count) then - result := TBezier(FList[Ref]).Reconstruct(Z1, Z2) else - result := nil; -end; -//------------------------------------------------------------------------------ - -class function TBezierList.Flatten(path: TPath; - BezType: TBezierType; Precision: Double): TPath; -begin - with TBezier.Create(path, BezType, 0, Precision) do - try - Result := FlattenedPath; - finally - Free; - end; -end; -//------------------------------------------------------------------------------ - -class function TBezierList.Flatten(paths: TPaths; - BezType: TBezierType; Precision: Double = DefaultPrecision): TPaths; -var - I, MinLen: Integer; -begin - if (bezType = CubicBezier) then MinLen := 4 else MinLen := 3; - SetLength(Result, length(paths)); - for I := 0 to high(paths) do - begin - if Length(paths[I]) < MinLen then - result[I] := nil - else - with TBezier.Create(paths[I], BezType, I, Precision) do - try - Result[I] := FlattenedPath; - finally - Free; - end; - end; -end; -//------------------------------------------------------------------------------ - -class function TBezierList.CSplineToCBezier(CubicSpline: TPath): TPath; -var - I, J, Len, LenMin1: Integer; -begin - Result := nil; - Len := Length(CubicSpline); - if Len < 4 then Exit; - if Odd(Len) then Dec(Len); - I := (Len div 2) - 1; - SetLength(Result, I * 3 + 1); - Result[0] := CubicSpline[0]; - Result[1] := CubicSpline[1]; - Result[2] := CubicSpline[2]; - I := 3; J := 3; - LenMin1 := Len - 1; - while I < LenMin1 do - begin - Result[J] := MidPoint(CubicSpline[I-1], CubicSpline[I]); - Result[J+1] := CubicSpline[I]; - Result[J+2] := CubicSpline[I+1]; - Inc(I, 2); Inc(J, 3); - end; - Result[J] := CubicSpline[LenMin1]; -end; -//------------------------------------------------------------------------------ - -class function TBezierList.QSplineToQBezier(QuadSpline: TPath): TPath; -var - I, J, Len, LenMin1: Integer; -begin - Result := nil; - Len := Length(QuadSpline); - if Len < 3 then Exit; - if not Odd(Len) then Dec(Len); - I := Len - 2; - SetLength(Result, I * 2 + 1); - Result[0] := QuadSpline[0]; - Result[1] := QuadSpline[1]; - I := 2; J := 2; - LenMin1 := Len - 1; - while I < LenMin1 do - begin - Result[J] := MidPoint(QuadSpline[I-1], QuadSpline[I]); - Result[J+1] := QuadSpline[I]; - Inc(I); Inc(J, 2); - end; - Result[J] := QuadSpline[LenMin1]; -end; - -//------------------------------------------------------------------------------ -// TSegment methods ... -//------------------------------------------------------------------------------ - -constructor TSegment.Create(Ref, Seg, Idx: Cardinal); -begin - RefID := Ref; SegID := Seg; Index := Idx; - childs[0] := nil; - childs[1] := nil; -end; -//------------------------------------------------------------------------------ - -destructor TSegment.Destroy; -begin - FreeAndNil(childs[0]); - FreeAndNil(childs[1]); - inherited; -end; -//------------------------------------------------------------------------------ - -procedure TSegment.GetFlattenedPath(var Path: TPath; - var Cnt: Integer; Init: Boolean); -var - Z: Int64; - CtrlIdx: Integer; -begin - if Init then - begin - Z := MakeZ(BezierType, SegID, RefID, Index); - AppendToPath(Path, Cnt, IntPoint(Round(ctrls[0].X), Round(ctrls[0].Y), Z)); - end; - - if not assigned(childs[0]) then - begin - case BezierType of - CubicBezier: CtrlIdx := 3; - else CtrlIdx := 2; - end; - Z := MakeZ(BezierType, SegID, RefID, Index); - AppendToPath(Path, Cnt, - IntPoint(Round(ctrls[CtrlIdx].X), Round(ctrls[CtrlIdx].Y), Z)); - end else - begin - childs[0].GetFlattenedPath(Path, Cnt, False); - childs[1].GetFlattenedPath(Path, Cnt, False); - end; -end; -//------------------------------------------------------------------------------ - -procedure TSegment.AddCtrlPtsToPath(var path: TPath; var currCnt: Integer); -var - I, Len, FirstDelta: Integer; -const - buffSize = 128; -begin - Len := Length(path); - if currCnt + 4 >= Len then - SetLength(path, Len + buffSize); - - if currCnt = 0 then - FirstDelta := 0 else - FirstDelta := 1; - - case BezierType of - CubicBezier: - for I := FirstDelta to 3 do - begin - path[currCnt].X := Round(ctrls[I].X); - path[currCnt].Y := Round(ctrls[I].Y); - Inc(currCnt); - end; - QuadBezier: - for I := FirstDelta to 2 do - begin - path[currCnt].X := Round(ctrls[I].X); - path[currCnt].Y := Round(ctrls[I].Y); - Inc(currCnt); - end; - end; -end; - -//------------------------------------------------------------------------------ -// TQuadBez methods ... -//------------------------------------------------------------------------------ - -constructor TQuadBez.Create(const Pt1, Pt2, Pt3: TDoublePoint; - Ref, Seg, Idx: Cardinal; Precision: Double); -var - p12, p23, p123: TDoublePoint; -begin - inherited Create(Ref, Seg, Idx); - BezierType := QuadBezier; - ctrls[0] := Pt1; ctrls[1] := Pt2; ctrls[2] := Pt3; - //assess curve flatness: - if abs(pt1.x + pt3.x - 2*pt2.x) + abs(pt1.y + pt3.y - 2*pt2.y) < Precision then - Exit; - - //if not at maximum precision then (recursively) create sub-segments ... - p12.X := (Pt1.X + Pt2.X) * half; - p12.Y := (Pt1.Y + Pt2.Y) * half; - p23.X := (Pt2.X + Pt3.X) * half; - p23.Y := (Pt2.Y + Pt3.Y) * half; - p123.X := (p12.X + p23.X) * half; - p123.Y := (p12.Y + p23.Y) * half; - Idx := Idx shl 1; - Childs[0] := TQuadBez.Create(Pt1, p12, p123, Ref, Seg, Idx, Precision); - Childs[1] := TQuadBez.Create(p123, p23, pt3, Ref, Seg, Idx +1, Precision); -end; - -//------------------------------------------------------------------------------ -// TCubicBez methods ... -//------------------------------------------------------------------------------ - -constructor TCubicBez.Create(const Pt1, Pt2, Pt3, Pt4: TDoublePoint; - Ref, Seg, Idx: Cardinal; Precision: Double); -var - p12, p23, p34, p123, p234, p1234: TDoublePoint; -begin - inherited Create(Ref, Seg, Idx); - BezierType := CubicBezier; - ctrls[0] := Pt1; ctrls[1] := Pt2; ctrls[2] := Pt3; ctrls[3] := Pt4; - //assess curve flatness: - //http://groups.google.com/group/comp.graphics.algorithms/tree/browse_frm/thread/d85ca902fdbd746e - if abs(Pt1.x + Pt3.x - 2*Pt2.x) + abs(Pt2.x + Pt4.x - 2*Pt3.x) + - abs(Pt1.y + Pt3.y - 2*Pt2.y) + abs(Pt2.y + Pt4.y - 2*Pt3.y) < Precision then - Exit; - - //if not at maximum precision then (recursively) create sub-segments ... - p12.X := (Pt1.X + Pt2.X) * half; - p12.Y := (Pt1.Y + Pt2.Y) * half; - p23.X := (Pt2.X + Pt3.X) * half; - p23.Y := (Pt2.Y + Pt3.Y) * half; - p34.X := (Pt3.X + Pt4.X) * half; - p34.Y := (Pt3.Y + Pt4.Y) * half; - p123.X := (p12.X + p23.X) * half; - p123.Y := (p12.Y + p23.Y) * half; - p234.X := (p23.X + p34.X) * half; - p234.Y := (p23.Y + p34.Y) * half; - p1234.X := (p123.X + p234.X) * half; - p1234.Y := (p123.Y + p234.Y) * half; - Idx := Idx shl 1; - Childs[0] := TCubicBez.Create(Pt1, p12, p123, p1234, Ref, Seg, Idx, Precision); - Childs[1] := TCubicBez.Create(p1234, p234, p34, Pt4, Ref, Seg, Idx +1, Precision); -end; - -//------------------------------------------------------------------------------ -// TBezier methods ... -//------------------------------------------------------------------------------ - -constructor TBezier.Create; -begin - SegmentList := TList.Create; -end; -//------------------------------------------------------------------------------ - -constructor TBezier.Create(const CtrlPts: TPath; - BezType: TBezierType; Ref: Word; Precision: Double); -begin - Create; - SetCtrlPoints(CtrlPts, BezType, Ref, Precision); -end; -//------------------------------------------------------------------------------ - -procedure TBezier.SetCtrlPoints(const CtrlPts: TPath; - BezType: TBezierType; Ref: Word; Precision: Double); -var - I, HighPts: Integer; - Segment: TSegment; -begin - //clean up any existing data ... - Clear; - HighPts := High(CtrlPts); - - BezierType := BezType; - case BezType of - CubicBezier: - if (HighPts < 3) then raise Exception.Create(rsInvalidBezierPointCount) - else Dec(HighPts, HighPts mod 3); - QuadBezier: - if (HighPts < 2) then raise Exception.Create(rsInvalidBezierPointCount) - else Dec(HighPts, HighPts mod 2); - - else raise Exception.Create(rsInvalidBezierType); - end; - - FCtrlPoints := CtrlPts; - Reference := Ref; - if Precision <= 0 then Precision := DefaultPrecision; - - //now for each segment in the poly-bezier create a binary tree structure - //and add it to SegmentList ... - case BezType of - CubicBezier: - for I := 0 to (HighPts div 3) -1 do - begin - Segment := TCubicBez.Create( - DoublePoint(CtrlPts[I*3]), - DoublePoint(CtrlPts[I*3+1]), - DoublePoint(CtrlPts[I*3+2]), - DoublePoint(CtrlPts[I*3+3]), - Ref, I, 1, Precision); - SegmentList.Add(Segment); - end; - QuadBezier: - for I := 0 to (HighPts div 2) -1 do - begin - Segment := TQuadBez.Create( - DoublePoint(CtrlPts[I*2]), - DoublePoint(CtrlPts[I*2+1]), - DoublePoint(CtrlPts[I*2+2]), - Ref, I, 1, Precision); - SegmentList.Add(Segment); - end; - end; -end; -//------------------------------------------------------------------------------ - -procedure TBezier.Clear; -var - I: Integer; -begin - FCtrlPoints := nil; - for I := 0 to SegmentList.Count -1 do - TObject(SegmentList[I]).Free; - SegmentList.Clear; -end; -//------------------------------------------------------------------------------ - -destructor TBezier.Destroy; -begin - Clear; - SegmentList.Free; - inherited; -end; -//------------------------------------------------------------------------------ - -function TBezier.FlattenedPath: TPath; -var - I, Cnt: Integer; -begin - Result := Nil; - if SegmentList.Count = 0 then Exit; - Cnt := 0; - for I := 0 to SegmentList.Count -1 do - TSegment(SegmentList[I]).GetFlattenedPath(Result, Cnt, Cnt = 0); - Result[0].Z := Result[0].Z or $8000000000000000; //StartOfPath flag - SetLength(Result, Cnt); -end; -//------------------------------------------------------------------------------ - -function TBezier.Reconstruct(startZ, endZ: Int64): TPath; -var - I, J, K, Seg1, Seg2, Cnt: Integer; - I64: Int64; - BezType1, BezType2: TBezierType; - IntList, IntCurrent: PIntNode; - Segment: TSegment; - Reversed: Boolean; -begin - //precondition: startZ <> endZ - result := nil; - if startZ = endZ then Exit; - - //StartOfPath subSegID is converted to +1 once any reversal has been sorted. - //if endZ has the StartOfPath flag then reverse path ... - if endZ < 0 then - begin - I64 := startZ; - startZ := endZ; - endZ := I64; - Reversed := true; - end - else - Reversed := false; - - //'startZ' and 'endZ' are now converted into subSegIDs ... - startZ := UnMakeZ(startZ, BezType1, Seg1, I); - endZ := UnMakeZ(endZ, BezType2, Seg2, J); - - if (BezType1 <> BezierType) or (BezType1 <> BezType2) or - (Reference <> I) or (I <> J) or - (Seg1 < 0) or (Seg1 >= SegmentList.Count) or - (Seg2 < 0) or (Seg2 >= SegmentList.Count) then - begin - Exit; - end; - - //check orientation because it's much simpler to temporarily unreverse when - //the startIdx and endIdx are reversed ... - if (Seg1 > Seg2) then - begin - I := Seg1; - Seg1 := Seg2; - Seg2 := I; - I := startZ; - startZ := endZ; - endZ := I; - Reversed := true; - end; - - //do further checks for reversal, in case reversal within a single segment. - //nb: when endZ == 1 or startZ == 1 then reversal managed above. - if not Reversed and (Seg1 = Seg2) and - (startZ <> 1) and (endZ <> 1) then - begin - I := GetMostSignificantBit(startZ); - J := GetMostSignificantBit(endZ); - K := Max(I, J); - //nb: we must compare Node indexes at the same level ... - I := startZ shl (K - I); - J := endZ shl (K - J); - if I > J then - begin - K := startZ; - startZ := endZ; - endZ := K; - Reversed := True; - end; - end; - - Cnt := 0; - while Seg1 <= Seg2 do - begin - IntList := nil; - try - //create a dummy first IntNode for the Int List ... - New(IntList); - IntList.Val := 0; - IntList.Next := nil; - IntList.Prev := nil; - IntCurrent := IntList; - - if Seg1 <> Seg2 then - ReconstructInternal(Seg1, startZ, 1, IntCurrent) else - ReconstructInternal(Seg1, startZ, endZ, IntCurrent); - - //IntList now contains the indexes of one or a series of sub-segments - //that together define part of or the whole of the original segment. - //We now append these sub-segments to the new list of control points ... - - IntCurrent := IntList.Next; //nb: skips the dummy IntNode - while assigned(IntCurrent) do - begin - Segment := TSegment(SegmentList[Seg1]); - J := IntCurrent.Val; - K := GetMostSignificantBit(J); - Dec(K); - while K >= 0 do - begin - if not assigned(Segment.childs[0]) then break; - if IsBitSet(J, K) then - Segment := Segment.childs[1] else - Segment := Segment.childs[0]; - Dec(K); - end; - Segment.AddCtrlPtsToPath(Result, Cnt); - IntCurrent := IntCurrent.Next; - end; //while assigned(IntCurrent); - - finally - DisposeIntNodes(IntList); - end; - inc(Seg1); - startZ := 1; - end; - SetLength(Result, Cnt); - if Reversed then - Result := Clipper.ReversePolygon(Result); -end; -//------------------------------------------------------------------------------ - -procedure TBezier.ReconstructInternal(SegIdx: Integer; - StartIdx, EndIdx: Int64; IntCurrent: PIntNode); -var - Level, L1, L2, L, R, J: Cardinal; -begin - //get the maximum level ... - L1 := GetMostSignificantBit(StartIdx); - L2 := GetMostSignificantBit(EndIdx); - Level := Max(L1, L2); - - if Level = 0 then - begin - InsertInt(IntCurrent, 1); - Exit; - end; - - //Right marker (R): EndIdx projected onto the bottom level ... - if (EndIdx = 1) then - begin - R := 1 shl (Level +1) - 1; - end else - begin - J := (Level - L2); - R := (EndIdx shl J) + (1 shl J) -1; - end; - - if (StartIdx = 1) then //special case - begin - //Left marker (L) is bottom left of the binary tree ... - L := 1 shl Level; - L1 := Level; - end else - begin - //For any given Z value, its corresponding X & Y coords (created by - //FlattenPath using De Casteljau's algorithm) refered to the ctrl[3] coords - //of many tiny polybezier segments. Since ctrl[3] coords are identical to - //ctrl[0] coords in the following node, we can safely increment StartIdx ... - L := StartIdx +1; - if L = 1 shl (Level +1) then Exit; //loops around tree so already at the end - end; - - //L ====> R; at Level = Max(L1, L2) - - //now get blocks of nodes from the LEFT ... - J := Level - L1; - repeat - //while next level up then down-right doesn't exceed L2 do ... - while not Odd(L) and ((L shl J) + (1 shl (J + 1)) - 1 <= R) do - begin - L := L shr 1; //go up a level - Inc(J); - end; - IntCurrent := InsertInt(IntCurrent, L); //nb: updates IntCurrent - Inc(L); - until (L = 3 shl (Level - J - 1)) or //ie crosses the ditch in the middle - ((L shl J) + (1 shl J) >= R); //or L is now over or to the right of R - - L := (L shl J); - - //now get blocks of nodes from the RIGHT ... - J := 0; - if R >= L then - repeat - while Odd(R) and ((R - 1) shl J >= L) do - begin - R := R shr 1; //go up a level - Inc(J); - end; - InsertInt(IntCurrent, R); //nb: doesn't update IntCurrent - Dec(R); - until (Integer(R) = (3 shl (Level - J)) -1) or //ie crosses the ditch - (R shl J <= L); -end; -//------------------------------------------------------------------------------ - -end. diff --git a/Beziers/beziers.cpp b/Beziers/beziers.cpp deleted file mode 100644 index 343fd32..0000000 --- a/Beziers/beziers.cpp +++ /dev/null @@ -1,729 +0,0 @@ -/******************************************************************************* -* * -* Author : Angus Johnson * -* Version : 1.0 * -* Date : 27 August 2013 * -* Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2013 * -* * -* License: * -* Use, modification & distribution is subject to Boost Software License Ver 1. * -* http://www.boost.org/LICENSE_1_0.txt * -* * -*******************************************************************************/ - -#include -#include "clipper.hpp" -#include "beziers.hpp" - -namespace BezierLib { - - - struct IntNode{ - int val; - IntNode* next; - IntNode* prev; - IntNode(int _val): val(_val), next(0), prev(0){}; - }; - - const double half = 0.5; - - //------------------------------------------------------------------------------ - // Miscellaneous helper functions ... - //------------------------------------------------------------------------------ - - //nb. The format (high to low) of the 64bit Z value returned in the path ... - //Typ (2): either CubicBezier, QuadBezier - //Seg (14): segment index since a bezier may consist of multiple segments - //Ref (16): reference value passed to TBezier owner object - //Idx (32): binary index to sub-segment containing control points - - inline cInt MakeZ(BezierType beziertype, unsigned short seg, unsigned short ref, unsigned idx) - { - unsigned hi = beziertype << 30 | seg << 16 | (ref +1); - return (cInt)hi << 32 | idx; - }; - //------------------------------------------------------------------------------ - - unsigned UnMakeZ(cInt zval, BezierType& beziertype, unsigned short& seg, unsigned short& ref) - { - unsigned vals = zval >> 32; //the top 32 bits => vals - beziertype = BezierType((vals >> 30) & 0x1); - seg = (vals >> 16) & 0x3FFF; - ref = (vals & 0xFFFF) -1; - return zval & 0xFFFFFFFF; - }; - //------------------------------------------------------------------------------ - - IntNode* InsertInt(IntNode* insertAfter, int val) - { - IntNode* result = new IntNode(val); - result->next = insertAfter->next; - result->prev = insertAfter; - if (insertAfter->next) - insertAfter->next->prev = result; - insertAfter->next = result; - return result; - } - //------------------------------------------------------------------------------ - - IntNode* GetFirstIntNode(IntNode* current) - { - if (!current) return 0; - IntNode* result = current; - while (result->prev) - result = result->prev; - //now skip the very first (dummy) node ... - return result->next; - } - //------------------------------------------------------------------------------ - - void DisposeIntNodes(IntNode* intnodes) - { - if (!intnodes) return; - while (intnodes->prev) - intnodes = intnodes->prev; - - do { - IntNode* intnode = intnodes; - intnodes = intnodes->next; - delete intnode; - } while (intnodes); - } - //------------------------------------------------------------------------------ - - inline IntPoint MidPoint(const IntPoint& pt1, const IntPoint& pt2) - { - return IntPoint((pt1.X + pt2.X)/2, (pt1.Y + pt2.Y)/2); - } - //------------------------------------------------------------------------------ - - unsigned GetMostSignificantBit(unsigned v) //index is zero based - { - const unsigned b[5] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; - const unsigned s[5] = {0x1, 0x2, 0x4, 0x8, 0x10}; - unsigned result = 0; - for (int i = 4; i >= 0; --i) - if ((v & b[i]) != 0) - { - v = v >> s[i]; - result = result | s[i]; - } - return result; - }; - //------------------------------------------------------------------------------ - - inline bool IsBitSet(unsigned val, unsigned index) - { - return (val & (1 << index)) != 0; - }; - //------------------------------------------------------------------------------ - - inline bool Odd(const unsigned val) - { - return (val % 2) != 0; - }; - //------------------------------------------------------------------------------ - - inline bool Even(const unsigned val) - { - return (val % 2) == 0; - }; - //------------------------------------------------------------------------------ - - inline cInt Round(double val) - { - return (val < 0) ? static_cast(val - 0.5) : static_cast(val + 0.5); - } - - //------------------------------------------------------------------------------ - // Segment class - //------------------------------------------------------------------------------ - - class Segment - { - public: - BezierType beziertype; - unsigned short RefID; - unsigned short SegID; - unsigned Index; - DoublePoint Ctrls[4]; - Segment* Childs[2]; - - Segment(unsigned short ref, unsigned short seg, unsigned idx): - RefID(ref), SegID(seg), Index(idx) { - Childs[0] = 0; - Childs[1] = 0; - }; - //-------------------------------------------------------------------------- - - ~Segment() - { - if (Childs[0]) delete Childs[0]; - if (Childs[1]) delete Childs[1]; - } - //-------------------------------------------------------------------------- - - void GetFlattenedPath(Path& path, bool init) - { - if (init) - { - cInt Z = MakeZ(beziertype, SegID, RefID, Index); - path.push_back(IntPoint(Round(Ctrls[0].X), Round(Ctrls[0].Y), Z)); - } - - if (!Childs[0]) - { - int CtrlIdx = 3; - if (beziertype == QuadBezier) CtrlIdx = 2; - cInt Z = MakeZ(beziertype, SegID, RefID, Index); - path.push_back(IntPoint(Round(Ctrls[CtrlIdx].X), Round(Ctrls[CtrlIdx].Y), Z)); - } else - { - Childs[0]->GetFlattenedPath(path, false); - Childs[1]->GetFlattenedPath(path, false); - } - } - //-------------------------------------------------------------------------- - - void AddCtrlPtsToPath(Path& ctrlPts) - { - int firstDelta = (ctrlPts.empty() ? 0 : 1); - switch (beziertype) - { - case CubicBezier: - for (int i = firstDelta; i < 4; ++i) - { - ctrlPts.push_back(IntPoint( - Round(Ctrls[i].X), Round(Ctrls[i].Y))); - } - break; - case QuadBezier: - for (int i = firstDelta; i < 3; ++i) - { - ctrlPts.push_back(IntPoint( - Round(Ctrls[i].X), Round(Ctrls[i].Y))); - } - break; - } - } - //-------------------------------------------------------------------------- - }; - - //------------------------------------------------------------------------------ - // CubicBez class - //------------------------------------------------------------------------------ - - class CubicBez: public Segment - { - public: - CubicBez(const DoublePoint& pt1, const DoublePoint& pt2, - const DoublePoint& pt3, const DoublePoint& pt4, - unsigned short ref, unsigned short seg, unsigned idx, double precision): Segment(ref, seg, idx) - { - - beziertype = CubicBezier; - Ctrls[0] = pt1; Ctrls[1] = pt2; Ctrls[2] = pt3; Ctrls[3] = pt4; - //assess curve flatness: - //http://groups.google.com/group/comp.graphics.algorithms/tree/browse_frm/thread/d85ca902fdbd746e - if (abs(pt1.X + pt3.X - 2*pt2.X) + abs(pt2.X + pt4.X - 2*pt3.X) + - abs(pt1.Y + pt3.Y - 2*pt2.Y) + abs(pt2.Y + pt4.Y - 2*pt3.Y) < precision) - return; - - //if not at maximum precision then (recursively) create sub-segments ... - DoublePoint p12, p23, p34, p123, p234, p1234; - p12.X = (pt1.X + pt2.X) * half; - p12.Y = (pt1.Y + pt2.Y) * half; - p23.X = (pt2.X + pt3.X) * half; - p23.Y = (pt2.Y + pt3.Y) * half; - p34.X = (pt3.X + pt4.X) * half; - p34.Y = (pt3.Y + pt4.Y) * half; - p123.X = (p12.X + p23.X) * half; - p123.Y = (p12.Y + p23.Y) * half; - p234.X = (p23.X + p34.X) * half; - p234.Y = (p23.Y + p34.Y) * half; - p1234.X = (p123.X + p234.X) * half; - p1234.Y = (p123.Y + p234.Y) * half; - idx = idx << 1; - Childs[0] = new CubicBez(pt1, p12, p123, p1234, ref, seg, idx, precision); - Childs[1] = new CubicBez(p1234, p234, p34, pt4, ref, seg, idx +1, precision); - } - }; - - //------------------------------------------------------------------------------ - // QuadBez class - //------------------------------------------------------------------------------ - - class QuadBez: public Segment - { - public: - QuadBez(const DoublePoint& pt1, const DoublePoint& pt2, const DoublePoint& pt3, - unsigned short ref, unsigned short seg, unsigned idx, double precision): Segment(ref, seg, idx) - { - beziertype = QuadBezier; - Ctrls[0] = pt1; Ctrls[1] = pt2; Ctrls[2] = pt3; - //assess curve flatness: - if (std::abs(pt1.X + pt3.X - 2*pt2.X) + abs(pt1.Y + pt3.Y - 2*pt2.Y) < precision) - return; - - //if not at maximum precision then (recursively) create sub-segments ... - DoublePoint p12, p23, p123; - p12.X = (pt1.X + pt2.X) * half; - p12.Y = (pt1.Y + pt2.Y) * half; - p23.X = (pt2.X + pt3.X) * half; - p23.Y = (pt2.Y + pt3.Y) * half; - p123.X = (p12.X + p23.X) * half; - p123.Y = (p12.Y + p23.Y) * half; - idx = idx << 1; - Childs[0] = new QuadBez(pt1, p12, p123, ref, seg, idx, precision); - Childs[1] = new QuadBez(p123, p23, pt3, ref, seg, idx +1, precision); - } - }; - - //------------------------------------------------------------------------------ - // Bezier class - //------------------------------------------------------------------------------ - - class BezierList; //forward - - class Bezier - { - private: - int m_ref; - BezierType m_beztype; - Path m_path; - std::vector< Segment* > segments; - public: - - friend class BezierList; - - Bezier(){}; - - Bezier( - const Path& ctrlPts, //CtrlPts: Bezier control points - BezierType beztype, //CubicBezier or QuadBezier ... - short ref, //Ref: user supplied identifier; - double precision) //Precision of flattened path - { - SetCtrlPoints(ctrlPts, beztype, ref, precision); - }; - //-------------------------------------------------------------------------- - - ~Bezier() - { - Clear(); - }; - //-------------------------------------------------------------------------- - - void Clear() - { - for (size_t i = 0; i < segments.size(); ++i) - delete segments[i]; - segments.resize(0); - }; - //-------------------------------------------------------------------------- - - void SetCtrlPoints(const Path& ctrlPts, - BezierType beztype, unsigned short ref, double precision) - { - //clean up any existing data ... - Clear(); - size_t highpts = ctrlPts.size() -1; - m_beztype = beztype; - m_ref = ref; - m_path = ctrlPts; - - switch( beztype ) - { - case CubicBezier: - if (highpts < 3) throw "CubicBezier: insuffient control points."; - else highpts -= highpts % 3; - break; - case QuadBezier: - if (highpts < 2) throw "QuadBezier: insuffient control points."; - else highpts -= highpts % 2; - break; - default: throw "Unsupported bezier type"; - } - - //now for each segment in the poly-bezier create a binary tree structure - //and add it to SegmentList ... - switch( beztype ) - { - case CubicBezier: - for (int i = 0; i < ((int)highpts / 3); ++i) - { - Segment* s = new CubicBez( - DoublePoint(ctrlPts[i*3]), - DoublePoint(ctrlPts[i*3+1]), - DoublePoint(ctrlPts[i*3+2]), - DoublePoint(ctrlPts[i*3+3]), - ref, i, 1, precision); - segments.push_back(s); - } - break; - case QuadBezier: - for (int i = 0; i < ((int)highpts / 2); ++i) - { - Segment* s = new QuadBez( - DoublePoint(ctrlPts[i*2]), - DoublePoint(ctrlPts[i*2+1]), - DoublePoint(ctrlPts[i*2+2]), - ref, i, 1, precision); - segments.push_back(s); - } - break; - } - } - //-------------------------------------------------------------------------- - - void FlattenedPath(Path& out_poly) - { - out_poly.resize(0); - for (size_t i = 0; i < segments.size(); ++i) - segments[i]->GetFlattenedPath(out_poly, i == 0); - out_poly[0].Z = (out_poly[0].Z | 0x8000000000000000); //StartOfPath flag - } - //-------------------------------------------------------------------------- - - void Reconstruct(cInt startZ, cInt endZ, Path& out_poly) - { - out_poly.resize(0); - if (endZ == startZ) return; - - bool reversed = false; - if (endZ < 0) - { - cInt tmp = startZ; - startZ = endZ; - endZ = tmp; - reversed = true; - } - - BezierType bt1, bt2; - unsigned short seg1, seg2; - unsigned short ref1, ref2; - startZ = UnMakeZ(startZ, bt1, seg1, ref1); - endZ = UnMakeZ(endZ, bt2, seg2, ref2); - - if (bt1 != m_beztype || bt1 != bt2 || - ref1 != m_ref || ref1 != ref2) return; - - if (seg1 >= segments.size() || seg2 >= segments.size()) return; - - if (seg1 > seg2) - { - unsigned i = seg1; - seg1 = seg2; - seg2 = i; - cInt tmp = startZ; - startZ = endZ; - endZ = tmp; - } - - //do further checks for reversal, in case reversal within a single segment ... - if (!reversed && seg1 == seg2 && startZ != 1 && endZ != 1) - { - unsigned i = GetMostSignificantBit((unsigned)startZ); - unsigned j = GetMostSignificantBit((unsigned)endZ); - unsigned k = std::max(i, j); - //nb: we must compare Node indexes at the same level ... - i = (unsigned)startZ << (k - i); - j = (unsigned)endZ << (k - j); - if (i > j) - { - cInt tmp = startZ; - startZ = endZ; - endZ = tmp; - reversed = true; - } - } - - while (seg1 <= seg2) - { - //create a dummy first IntNode for the Int List ... - IntNode* intList = new IntNode(0); - IntNode* intCurr = intList; - - if (seg1 != seg2) - ReconstructInternal(seg1, (unsigned)startZ, 1, intCurr); - else - ReconstructInternal(seg1, (unsigned)startZ, (unsigned)endZ, intCurr); - - //IntList now contains the indexes of one or a series of sub-segments - //that together define part of or the whole of the original segment. - //We now append these sub-segments to the new list of control points ... - - intCurr = intList->next; //nb: skips the dummy IntNode - while (intCurr) - { - Segment* s = segments[seg1]; - int j = intCurr->val; - int k = GetMostSignificantBit(j) -1; - while (k >= 0) - { - if (!s->Childs[0]) break; - if (IsBitSet(j, k--)) - s = s->Childs[1]; - else - s = s->Childs[0]; - } - s->AddCtrlPtsToPath(out_poly); - intCurr = intCurr->next; - } //while - - DisposeIntNodes(intList); - seg1++; - startZ = 1; - } - if (reversed) - ReversePolygon(out_poly); - } - //-------------------------------------------------------------------------- - - void ReconstructInternal(unsigned short segIdx, - unsigned startIdx, unsigned endIdx, IntNode* intCurr) - { - //get the maximum level ... - unsigned L1 = GetMostSignificantBit(startIdx); - unsigned L2 = GetMostSignificantBit(endIdx); - int Level = std::max(L1, L2); - - if (Level == 0) - { - InsertInt(intCurr, 1); - return; - } - - int L, R; - //Right marker (R): EndIdx projected onto the bottom level ... - if (endIdx == 1) - { - R = (1 << (Level +1)) - 1; - } else - { - int j = (Level - L2); - R = (endIdx << j) + (1 << j) -1; - } - - if (startIdx == 1) //special case - { - //Left marker (L) is bottom left of the binary tree ... - L = (1 << Level); - L1 = Level; - } else - { - //For any given Z value, its corresponding X & Y coords (created by - //FlattenPath using De Casteljau's algorithm) refered to the ctrl[3] coords - //of many tiny polybezier segments. Since ctrl[3] coords are identical to - //ctrl[0] coords in the following node, we can safely increment StartIdx ... - L = startIdx +1; - if (L == (1 << (Level +1))) return; //loops around tree so already at the end - } - - //now get blocks of nodes from the LEFT ... - int j = Level - L1; - do - { - //while next level up then down-right doesn't exceed L2 do ... - while (Even(L) && ((L << j) + (1 << (j + 1)) - 1 <= R)) - { - L = (L >> 1); //go up a level - j++; - } - intCurr = InsertInt(intCurr, L); //nb: updates IntCurrent - L++; - } while (L != (3 << (Level - j - 1)) && //ie middle not crossed - (L << j) + (1 << j) < R); //and levelled L < R - - L = (L << j); - - //now get blocks of nodes from the RIGHT ... - j = 0; - if (R >= L) - do - { - while (Odd(R) && ((R-1) << j >= L)) - { - R = R >> 1; //go up a level - j++; - } - InsertInt(intCurr, R); //nb: doesn't update IntCurrent - R--; - } while (R != (3 << (Level - j)) -1 && ((R << j) > L)); - } - //-------------------------------------------------------------------------- - }; - - //------------------------------------------------------------------------------ - // BezierList class - //------------------------------------------------------------------------------ - - BezierList::BezierList(double precision) - { - if (precision <= 0) precision = DefaultPrecision; - m_Precision = precision; - } - //------------------------------------------------------------------------------ - - BezierList::~BezierList() - { - Clear(); - } - //------------------------------------------------------------------------------ - - void BezierList::AddPath(const Path ctrlPts, BezierType bezType) - { - Bezier* NewBez = new Bezier(ctrlPts, bezType, m_Beziers.size(), m_Precision); - m_Beziers.push_back(NewBez); - } - //------------------------------------------------------------------------------ - - void BezierList::AddPaths(const Paths ctrlPts, BezierType bezType) - { - size_t minCnt = (bezType == CubicBezier ? 4 : 3); - for (size_t i = 0; i < ctrlPts.size(); ++i) - { - if (ctrlPts[i].size() < minCnt) continue; - Bezier* NewBez = new Bezier(ctrlPts[i], bezType, m_Beziers.size(), m_Precision); - m_Beziers.push_back(NewBez); - } - } - //------------------------------------------------------------------------------ - - void BezierList::Clear() - { - for (size_t i = 0; i < m_Beziers.size(); ++i) - delete m_Beziers[i]; - m_Beziers.clear(); - } - //------------------------------------------------------------------------------ - - void BezierList::GetCtrlPts(int index, Path& path) - { - if (index < 0 || index >= (int)m_Beziers.size()) - throw "BezierList: index out of range"; - path = m_Beziers[index]->m_path; - } - //------------------------------------------------------------------------------ - - BezierType BezierList::GetBezierType(int index) - { - if (index < 0 || index >= (int)m_Beziers.size()) - throw "BezierList: index out of range"; - return m_Beziers[index]->m_beztype; - } - //------------------------------------------------------------------------------ - - void BezierList::GetFlattenedPath(int index, Path& path) - { - if (index < 0 || index >= (int)m_Beziers.size()) - throw "BezierList: index out of range"; - m_Beziers[index]->FlattenedPath(path); - } - //------------------------------------------------------------------------------ - - void BezierList::GetFlattenedPaths(Paths& paths) - { - paths.clear(); - paths.resize(m_Beziers.size()); - for (size_t i = 0; i < m_Beziers.size(); ++i) - m_Beziers[i]->FlattenedPath(paths[i]); - } - //------------------------------------------------------------------------------ - - void BezierList::Flatten(const Path& in_path, - Path& out_path, BezierType bezType, double precision) - { - out_path.clear(); - size_t minCnt = (bezType == CubicBezier ? 4 : 3); - if (in_path.size() < minCnt) return; - Bezier b(in_path, bezType, 0, precision); - b.FlattenedPath(out_path); - } - //------------------------------------------------------------------------------ - - void BezierList::Flatten(const Paths& in_paths, - Paths& out_paths, BezierType bezType, double precision) - { - out_paths.clear(); - out_paths.resize(in_paths.size()); - size_t minCnt = (bezType == CubicBezier ? 4 : 3); - for (size_t i = 0; i < in_paths.size(); ++i) - { - if (in_paths[i].size() < minCnt) continue; - Bezier b(in_paths[i], bezType, 0, precision); - b.FlattenedPath(out_paths[i]); - } - } - //------------------------------------------------------------------------------ - - void BezierList::CSplineToCBezier(const Path& in_path, Path& out_path) - { - out_path.clear(); - size_t len = in_path.size(); - if (len < 4) return; - if (len % 2 != 0) len--; - size_t i = (len / 2) - 1; - out_path.reserve(i * 3 + 1); - out_path.push_back(in_path[0]); - out_path.push_back(in_path[1]); - out_path.push_back(in_path[2]); - i = 3; - size_t lenMin1 = len - 1; - while (i < lenMin1) - { - out_path.push_back(MidPoint(in_path[i-1], in_path[i])); - out_path.push_back(in_path[i++]); - out_path.push_back(in_path[i++]); - } - out_path.push_back(in_path[lenMin1]); - } - //------------------------------------------------------------------------------ - - void BezierList::QSplineToQBezier(const Path& in_path, Path& out_path) - { - out_path.clear(); - size_t len = in_path.size(); - if (len < 3) return; - if (len % 2 == 0) len--; - size_t i = len - 2; - out_path.reserve(i * 2 + 1); - out_path.push_back(in_path[0]); - out_path.push_back(in_path[1]); - i = 2; - size_t lenMin1 = len - 1; - while (i < lenMin1) - { - out_path.push_back(MidPoint(in_path[i-1], in_path[i])); - out_path.push_back(in_path[i++]); - } - out_path.push_back(in_path[lenMin1]); - } - //------------------------------------------------------------------------------ - - void BezierList::Reconstruct(cInt z1, cInt z2, Path& path) - { - unsigned short seg, ref; - BezierType beztype; - UnMakeZ(z1, beztype, seg, ref); //UnMakeZ() here just for ref - if (ref >= 0 && ref < m_Beziers.size()) - m_Beziers[ref]->Reconstruct(z1, z2, path); - else - path.clear(); - } - //------------------------------------------------------------------------------ - - double BezierList::Precision() - { - return m_Precision; - } - //------------------------------------------------------------------------------ - - void BezierList::Precision(double value) - { - m_Precision = value; - } - //------------------------------------------------------------------------------ - -} //end namespace \ No newline at end of file diff --git a/Beziers/beziers.hpp b/Beziers/beziers.hpp deleted file mode 100644 index 47c0bf0..0000000 --- a/Beziers/beziers.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* -* * -* Author : Angus Johnson * -* Version : 1.0 * -* Date : 27 August 2013 * -* Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2013 * -* * -* License: * -* Use, modification & distribution is subject to Boost Software License Ver 1. * -* http://www.boost.org/LICENSE_1_0.txt * -* * -*******************************************************************************/ - -#ifndef beziers_hpp -#define beziers_hpp - -#include -#include "clipper.hpp" - -namespace BezierLib { - - using namespace ClipperLib; - - enum BezierType {CubicBezier, QuadBezier}; - const double DefaultPrecision = 0.5; - - class Bezier; - - class BezierList - { - private: - std::vector m_Beziers; - double m_Precision; - public: - BezierList(double precision = DefaultPrecision); - ~BezierList(); - void AddPath(const Path ctrlPts, BezierType bezType); - void AddPaths(const Paths ctrlPts, BezierType bezType); - void Clear(); - - void GetCtrlPts(int index, Path& path); - BezierType GetBezierType(int index); - void GetFlattenedPath(int index, Path& path); - void GetFlattenedPaths(Paths& paths); - - static void Flatten(const Path& in_path, Path& out_path, - BezierType bezType, double precision = DefaultPrecision); - static void Flatten(const Paths& in_paths, Paths& out_paths, - BezierType bezType, double precision = DefaultPrecision); - static void CSplineToCBezier(const Path& in_path, Path& out_path); - static void QSplineToQBezier(const Path& in_path, Path& out_path); - - void Reconstruct(cInt z1, cInt z2, Path& path); - double Precision(); - void Precision(double value); - }; - -} //BezierLib namespace -#endif //bezier_hpp diff --git a/C#/ConsoleDemo/ConsoleDemo/Program.cs b/C#/ConsoleDemo/ConsoleDemo/Program.cs index 344414d..83f056c 100644 --- a/C#/ConsoleDemo/ConsoleDemo/Program.cs +++ b/C#/ConsoleDemo/ConsoleDemo/Program.cs @@ -10,8 +10,8 @@ namespace ClipperTest1 { - using Polygon = List; - using Polygons = List>; + using Path = List; + using Paths = List>; class Program { @@ -53,7 +53,7 @@ public StyleInfo() public class PolyInfo { - public Polygons polygons; + public Paths polygons; public StyleInfo si; } @@ -74,7 +74,7 @@ public SVGBuilder() style = new StyleInfo(); } - public void AddPolygons(Polygons poly) + public void AddPaths(Paths poly) { if (poly.Count == 0) return; PolyInfo pi = new PolyInfo(); @@ -107,7 +107,7 @@ public Boolean SaveToFile(string filename, double scale = 1.0, int margin = 10) for ( ; i < PolyInfoList.Count; i++ ) { - foreach (Polygon pg in PolyInfoList[i].polygons) + foreach (Path pg in PolyInfoList[i].polygons) foreach (IntPoint pt in pg) { if (pt.X < rec.left) rec.left = pt.X; @@ -135,7 +135,7 @@ public Boolean SaveToFile(string filename, double scale = 1.0, int margin = 10) foreach (PolyInfo pi in PolyInfoList) { writer.Write(" \n\n"); - foreach (Polygon p in pi.polygons) + foreach (Path p in pi.polygons) { foreach (IntPoint pt in p) { @@ -185,7 +185,7 @@ public Boolean SaveToFile(string filename, double scale = 1.0, int margin = 10) //////////////////////////////////////////////// - static bool LoadFromFile(string filename, Polygons ppg, int dec_places, int xOffset = 0, int yOffset = 0) + static bool LoadFromFile(string filename, Paths ppg, int dec_places, int xOffset = 0, int yOffset = 0) { double scaling; scaling = Math.Pow(10, dec_places); @@ -203,7 +203,7 @@ static bool LoadFromFile(string filename, Polygons ppg, int dec_places, int xOff { if ((line = sr.ReadLine()) == null) return false; if (!Int32.TryParse(line, out vertCnt) || vertCnt < 0) return false; - Polygon pg = new Polygon(vertCnt); + Path pg = new Path(vertCnt); ppg.Add(pg); if (scaling > 0.999 & scaling < 1.001) for (int j = 0; j < vertCnt; j++) @@ -240,13 +240,13 @@ static bool LoadFromFile(string filename, Polygons ppg, int dec_places, int xOff } //////////////////////////////////////////////// - static void SaveToFile(string filename, Polygons ppg, int dec_places) + static void SaveToFile(string filename, Paths ppg, int dec_places) { double scaling = Math.Pow(10, dec_places); StreamWriter writer = new StreamWriter(filename); if (writer == null) return; writer.Write("{0}\r\n", ppg.Count); - foreach (Polygon pg in ppg) + foreach (Path pg in ppg) { writer.Write("{0}\r\n", pg.Count); foreach (IntPoint ip in pg) @@ -273,10 +273,10 @@ static void OutputFileFormat() //////////////////////////////////////////////// - static Polygon IntsToPolygon(int[] ints) + static Path IntsToPolygon(int[] ints) { int len1 = ints.Length /2; - Polygon result = new Polygon(len1); + Path result = new Path(len1); for (int i = 0; i < len1; i++) result.Add(new IntPoint(ints[i * 2], ints[i * 2 +1])); return result; @@ -284,9 +284,9 @@ static Polygon IntsToPolygon(int[] ints) //////////////////////////////////////////////// - static Polygon MakeRandomPolygon(Random r, int maxWidth, int maxHeight, int edgeCount, Int64 scale = 1) + static Path MakeRandomPolygon(Random r, int maxWidth, int maxHeight, int edgeCount, Int64 scale = 1) { - Polygon result = new Polygon(edgeCount); + Path result = new Path(edgeCount); for (int i = 0; i < edgeCount; i++) { result.Add(new IntPoint(r.Next(maxWidth)*scale, r.Next(maxHeight)*scale)); @@ -297,34 +297,34 @@ static Polygon MakeRandomPolygon(Random r, int maxWidth, int maxHeight, int edg static void Main(string[] args) { - ////quick test with random polygons ... - //Polygons ss = new Polygons(1), cc = new Polygons(1), sss = new Polygons(); - //Random r = new Random((int)DateTime.Now.Ticks); - //int scale = 1000000000; //tests 128bit math - //ss.Add(MakeRandomPolygon(r, 400, 350, 9, scale)); - //cc.Add(MakeRandomPolygon(r, 400, 350, 9, scale)); - //Clipper cpr = new Clipper(); - //cpr.AddPolygons(ss, PolyType.ptSubject); - //cpr.AddPolygons(cc, PolyType.ptClip); - //cpr.Execute(ClipType.ctUnion, sss, PolyFillType.pftNonZero, PolyFillType.pftNonZero); - //sss = Clipper.OffsetPolygons(sss, -5.0*scale, JoinType.jtMiter, 4); - //SVGBuilder svg1 = new SVGBuilder(); - //svg1.style.brushClr = Color.FromArgb(0x20, 0, 0, 0x9c); - //svg1.style.penClr = Color.FromArgb(0xd3, 0xd3, 0xda); - //svg1.AddPolygons(ss); - //svg1.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0); - //svg1.style.penClr = Color.FromArgb(0xff, 0xa0, 0x7a); - //svg1.AddPolygons(cc); - //svg1.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c); - //svg1.style.penClr = Color.FromArgb(0, 0x33, 0); - //svg1.AddPolygons(sss); - //svg1.SaveToFile("solution.svg", 1.0/scale); - //return; - - if (args.Length < 5) + ////quick test with random polygons ... + //Paths ss = new Paths(1), cc = new Paths(1), sss = new Paths(); + //Random r = new Random((int)DateTime.Now.Ticks); + //int scale = 1000000000; //tests 128bit math + //ss.Add(MakeRandomPolygon(r, 400, 350, 9, scale)); + //cc.Add(MakeRandomPolygon(r, 400, 350, 9, scale)); + //Clipper cpr = new Clipper(); + //cpr.AddPaths(ss, PolyType.ptSubject, true); + //cpr.AddPaths(cc, PolyType.ptClip, true); + //cpr.Execute(ClipType.ctUnion, sss, PolyFillType.pftNonZero, PolyFillType.pftNonZero); + //sss = Clipper.OffsetPolygons(sss, -5.0 * scale, JoinType.jtMiter, 4); + //SVGBuilder svg1 = new SVGBuilder(); + //svg1.style.brushClr = Color.FromArgb(0x20, 0, 0, 0x9c); + //svg1.style.penClr = Color.FromArgb(0xd3, 0xd3, 0xda); + //svg1.AddPaths(ss); + //svg1.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0); + //svg1.style.penClr = Color.FromArgb(0xff, 0xa0, 0x7a); + //svg1.AddPaths(cc); + //svg1.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c); + //svg1.style.penClr = Color.FromArgb(0, 0x33, 0); + //svg1.AddPaths(sss); + //svg1.SaveToFile("solution.svg", 1.0 / scale); + //return; + + if (args.Length < 5) { string appname = System.Environment.GetCommandLineArgs()[0]; - appname = Path.GetFileName(appname); + appname = System.IO.Path.GetFileName(appname); Console.WriteLine(""); Console.WriteLine("Usage:"); Console.WriteLine(" {0} CLIPTYPE s_file c_file INPUT_DEC_PLACES SVG_SCALE [S_FILL, C_FILL]", appname); @@ -401,8 +401,8 @@ static void Main(string[] args) } } - Polygons subjs = new Polygons(); - Polygons clips = new Polygons(); + Paths subjs = new Paths(); + Paths clips = new Paths(); if (!LoadFromFile(subjFilename, subjs, decimal_places)) { Console.WriteLine("Error processing subject polygons file - {0} ", subjFilename); @@ -418,11 +418,11 @@ static void Main(string[] args) Console.WriteLine("wait ..."); Clipper cp = new Clipper(); - cp.AddPolygons(subjs, PolyType.ptSubject); - cp.AddPolygons(clips, PolyType.ptClip); + cp.AddPaths(subjs, PolyType.ptSubject, true); + cp.AddPaths(clips, PolyType.ptClip, true); - Polygons solution = new Polygons(); - //Polygons solution = new Polygons(); + Paths solution = new Paths(); + //Paths solution = new Paths(); if (cp.Execute(ct, solution, pftSubj, pftClip)) { SaveToFile("solution.txt", solution, decimal_places); @@ -432,13 +432,13 @@ static void Main(string[] args) SVGBuilder svg = new SVGBuilder(); svg.style.brushClr = Color.FromArgb(0x20, 0, 0, 0x9c); svg.style.penClr = Color.FromArgb(0xd3, 0xd3, 0xda); - svg.AddPolygons(subjs); + svg.AddPaths(subjs); svg.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0); svg.style.penClr = Color.FromArgb(0xff, 0xa0, 0x7a); - svg.AddPolygons(clips); + svg.AddPaths(clips); svg.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c); svg.style.penClr = Color.FromArgb(0, 0x33, 0); - svg.AddPolygons(solution); + svg.AddPaths(solution); svg.SaveToFile("solution.svg", svg_scale); Console.WriteLine("finished!"); diff --git a/C#/GuiDemo/GuiDemo/Form1.cs b/C#/GuiDemo/GuiDemo/Form1.cs index b8e5984..e565ca1 100644 --- a/C#/GuiDemo/GuiDemo/Form1.cs +++ b/C#/GuiDemo/GuiDemo/Form1.cs @@ -1,4 +1,6 @@ -using System; +//#define UsePolyTree + +using System; using System.Diagnostics; using System.Text; using System.Collections.Generic; @@ -12,10 +14,8 @@ using System.Globalization; using ClipperLib; - namespace WindowsFormsApplication1 { - using Polygon = List; using Polygons = List>; @@ -29,14 +29,15 @@ public partial class Form1 : Form private Polygons subjects; private Polygons clips; private Polygons solution; + private PolyTree solutionTree; //Here we are scaling all coordinates up by 100 when they're passed to Clipper //via Polygon (or Polygons) objects because Clipper no longer accepts floating //point values. Likewise when Clipper returns a solution in a Polygons object, //we need to scale down these returned values by the same amount before displaying. - private int scale = 100; //or 1 or 10 or 10000 etc for lesser or greater precision. + private float scale = 100; //or 1 or 10 or 10000 etc for lesser or greater precision. - //--------------------------------------------------------------------- + //------------------------------------------------------------------------------ //--------------------------------------------------------------------- //a very simple class that builds an SVG file with any number of @@ -209,9 +210,9 @@ public Boolean SaveToFile(string filename, double scale = 1.0, int margin = 10) //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ - static private System.Drawing.PointF[] PolygonToPointFArray(Polygon pg, int scale) + static private PointF[] PolygonToPointFArray(Polygon pg, float scale) { - System.Drawing.PointF[] result = new System.Drawing.PointF[pg.Count]; + PointF[] result = new PointF[pg.Count]; for (int i = 0; i < pg.Count; ++i) { result[i].X = (float)pg[i].X / scale; @@ -221,6 +222,16 @@ static private System.Drawing.PointF[] PolygonToPointFArray(Polygon pg, int scal } //--------------------------------------------------------------------- + //static public Polygon IntArrayToPolygon(int[] ints) + //{ + // int cnt = ints.Length / 2; + // Polygon result = new Polygon(cnt); + // for (int i = 0; i < cnt; i++) + // result.Add(new IntPoint(ints[i * 2], ints[i * 2 + 1])); + // return result; + //} + //--------------------------------------------------------------------- + public Form1() { InitializeComponent(); @@ -275,7 +286,7 @@ private void GenerateAustPlusRandomEllipses(int count) const int ellipse_size = 100, margin = 10; for (int i = 0; i < count; ++i) { - int w = pictureBox1.ClientRectangle.Width - ellipse_size - margin *2; + int w = pictureBox1.ClientRectangle.Width - ellipse_size - margin * 2; int h = pictureBox1.ClientRectangle.Height - ellipse_size - margin * 2 - statusStrip1.Height; pt.X = rand.Next(w) + margin; @@ -296,8 +307,8 @@ private IntPoint GenerateRandomPoint(int l, int t, int r, int b, Random rand) { int Q = 10; IntPoint newPt = new IntPoint(); - newPt.X = (rand.Next(r / Q) * Q + l + 10) * scale; - newPt.Y = (rand.Next(b / Q) * Q + t + 10) * scale; + newPt.X = (Int64)Math.Round((rand.Next(r / Q) * Q + l + 10) * scale); + newPt.Y = (Int64)Math.Round((rand.Next(b / Q) * Q + t + 10) * scale); return newPt; } //--------------------------------------------------------------------- @@ -445,15 +456,23 @@ private void DrawBitmap(bool justClip = false) //do the clipping ... if ((clips.Count > 0 || subjects.Count > 0) && !rbNone.Checked) - { + { Polygons solution2 = new Polygons(); Clipper c = new Clipper(); c.AddPolygons(subjects, PolyType.ptSubject); c.AddPolygons(clips, PolyType.ptClip); solution.Clear(); +#if UsePolyTree + bool succeeded = c.Execute(GetClipType(), solutionTree, GetPolyFillType(), GetPolyFillType()); + //nb: we aren't doing anything useful here with solutionTree except to show + //that it works. Convert PolyTree back to Polygons structure ... + Clipper.PolyTreeToPolygons(solutionTree, solution); +#else bool succeeded = c.Execute(GetClipType(), solution, GetPolyFillType(), GetPolyFillType()); +#endif if (succeeded) { + //SaveToFile("solution", solution); myBrush.Color = Color.Black; path.Reset(); @@ -464,10 +483,14 @@ private void DrawBitmap(bool justClip = false) path.FillMode = FillMode.Winding; //or for something fancy ... + if (nudOffset.Value != 0) - solution2 = Clipper.OffsetPolygons(solution, (double)nudOffset.Value * scale, JoinType.jtMiter); + { + solution2 = Clipper.OffsetPolygons(solution, (double)nudOffset.Value * scale, JoinType.jtRound); + } else solution2 = new Polygons(solution); + foreach (Polygon pg in solution2) { PointF[] pts = PolygonToPointFArray(pg, scale); @@ -505,7 +528,7 @@ private void DrawBitmap(bool justClip = false) StringFormat rtStringFormat = new StringFormat(); rtStringFormat.Alignment = StringAlignment.Far; rtStringFormat.LineAlignment = StringAlignment.Near; - Rectangle rec = new Rectangle(pictureBox1.ClientSize.Width - 108, + Rectangle rec = new Rectangle(pictureBox1.ClientSize.Width - 108, pictureBox1.ClientSize.Height - 116, 104, 106); newgraphic.FillRectangle(new SolidBrush(Color.FromArgb(196, Color.WhiteSmoke)), rec); newgraphic.DrawRectangle(myPen, rec); @@ -532,10 +555,19 @@ private void DrawBitmap(bool justClip = false) newgraphic.DrawString((union_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new Point(0, 10)); newgraphic.DrawString("---------", f, b, rec, rtStringFormat); + + lftStringFormat.Dispose(); + rtStringFormat.Dispose(); + f.Dispose(); + b.Dispose(); } //end if succeeded } //end if something to clip pictureBox1.Image = mybitmap; + + myBrush.Dispose(); + myPen.Dispose(); + path.Dispose(); newgraphic.Dispose(); Cursor.Current = Cursors.Default; } @@ -551,6 +583,7 @@ private void Form1_Load(object sender, EventArgs e) subjects = new Polygons(); clips = new Polygons(); solution = new Polygons(); + solutionTree = new PolyTree(); toolStripStatusLabel1.Text = "Tip: Use the mouse-wheel (or +,-,0) to adjust the offset of the solution polygons."; diff --git a/C#/clipper_library/clipper.cs b/C#/clipper_library/clipper.cs index 6e06b63..f664731 100644 --- a/C#/clipper_library/clipper.cs +++ b/C#/clipper_library/clipper.cs @@ -1,8 +1,8 @@ /******************************************************************************* * * * Author : Angus Johnson * -* Version : 5.1.6 * -* Date : 23 May 2013 * +* Version : 6.0.0 * +* Date : 30 October 2013 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2013 * * * @@ -38,3891 +38,4771 @@ * * *******************************************************************************/ +//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 performance. +//#define use_xyz + +//UseLines: Enables line clipping. Adds a very minor cost to performance. +//#define use_lines + +//When enabled, code developed with earlier versions of Clipper +//(ie prior to ver 6) should compile without changes. +//In a future update, this compatibility code will be removed. +#define use_deprecated + + using System; using System.Collections.Generic; -//using System.Text; //for Int128.AsString() & StringBuilder -//using System.IO; //streamReader & StreamWriter +//using System.Text; //for Int128.AsString() & StringBuilder +//using System.IO; //debugging with streamReader & StreamWriter +//using System.Windows.Forms; //debugging to clipboard namespace ClipperLib { - - using Polygon = List; - using Polygons = List>; - //------------------------------------------------------------------------------ - // PolyTree & PolyNode classes - //------------------------------------------------------------------------------ +#if use_int32 + using cInt = Int32; +#else + using cInt = Int64; +#endif - public class PolyTree : PolyNode - { - internal List m_AllPolys = new List(); + using Path = List; + using Paths = List>; - ~PolyTree() - { - Clear(); - } - - public void Clear() - { - for (int i = 0; i < m_AllPolys.Count; i++) - m_AllPolys[i] = null; - m_AllPolys.Clear(); - m_Childs.Clear(); - } - - public PolyNode GetFirst() - { - if (m_Childs.Count > 0) - return m_Childs[0]; - else - return null; - } +#if use_deprecated + using Polygon = List; + using Polygons = List>; +#endif - public int Total - { - get { return m_AllPolys.Count; } - } + public struct DoublePoint + { + public double X; + public double Y; + public DoublePoint(double x = 0, double y = 0) + { + this.X = x; this.Y = y; } - - public class PolyNode + public DoublePoint(DoublePoint dp) + { + this.X = dp.X; this.Y = dp.Y; + } + public DoublePoint(IntPoint ip) { - internal PolyNode m_Parent; - internal Polygon m_polygon = new Polygon(); - internal int m_Index; - internal List m_Childs = new List(); + this.X = ip.X; this.Y = ip.Y; + } + }; - private bool IsHoleNode() - { - bool result = true; - PolyNode node = m_Parent; - while (node != null) - { - result = !result; - node = node.m_Parent; - } - return result; - } - public int ChildCount - { - get { return m_Childs.Count; } - } + //------------------------------------------------------------------------------ + // PolyTree & PolyNode classes + //------------------------------------------------------------------------------ - public Polygon Contour - { - get { return m_polygon; } - } + public class PolyTree : PolyNode + { + internal List m_AllPolys = new List(); - internal void AddChild(PolyNode Child) - { - int cnt = m_Childs.Count; - m_Childs.Add(Child); - Child.m_Parent = this; - Child.m_Index = cnt; - } + ~PolyTree() + { + Clear(); + } + + public void Clear() + { + for (int i = 0; i < m_AllPolys.Count; i++) + m_AllPolys[i] = null; + m_AllPolys.Clear(); + m_Childs.Clear(); + } + + public PolyNode GetFirst() + { + if (m_Childs.Count > 0) + return m_Childs[0]; + else + return null; + } - public PolyNode GetNext() - { - if (m_Childs.Count > 0) - return m_Childs[0]; - else - return GetNextSiblingUp(); - } - - internal PolyNode GetNextSiblingUp() - { - if (m_Parent == null) - return null; - else if (m_Index == m_Parent.m_Childs.Count - 1) - return m_Parent.GetNextSiblingUp(); - else - return m_Parent.m_Childs[m_Index + 1]; - } + public int Total + { + get { return m_AllPolys.Count; } + } - public List Childs - { - get { return m_Childs; } - } + } + + public class PolyNode + { + internal PolyNode m_Parent; + internal Path m_polygon = new Path(); + internal int m_Index; + internal List m_Childs = new List(); + + private bool IsHoleNode() + { + bool result = true; + PolyNode node = m_Parent; + while (node != null) + { + result = !result; + node = node.m_Parent; + } + return result; + } + + public int ChildCount + { + get { return m_Childs.Count; } + } + + public Path Contour + { + get { return m_polygon; } + } + + internal void AddChild(PolyNode Child) + { + int cnt = m_Childs.Count; + m_Childs.Add(Child); + Child.m_Parent = this; + Child.m_Index = cnt; + } + + public PolyNode GetNext() + { + if (m_Childs.Count > 0) + return m_Childs[0]; + else + return GetNextSiblingUp(); + } + + internal PolyNode GetNextSiblingUp() + { + if (m_Parent == null) + return null; + else if (m_Index == m_Parent.m_Childs.Count - 1) + return m_Parent.GetNextSiblingUp(); + else + return m_Parent.m_Childs[m_Index + 1]; + } + + public List Childs + { + get { return m_Childs; } + } + + public PolyNode Parent + { + get { return m_Parent; } + } + + public bool IsHole + { + get { return IsHoleNode(); } + } + + public bool IsOpen { get; set; } + } + + + //------------------------------------------------------------------------------ + // Int128 struct (enables safe math on signed 64bit integers) + // eg Int128 val1((Int64)9223372036854775807); //ie 2^63 -1 + // Int128 val2((Int64)9223372036854775807); + // Int128 val3 = val1 * val2; + // val3.ToString => "85070591730234615847396907784232501249" (8.5e+37) + //------------------------------------------------------------------------------ + + internal struct Int128 + { + private Int64 hi; + private UInt64 lo; + + public Int128(Int64 _lo) + { + lo = (UInt64)_lo; + if (_lo < 0) hi = -1; + else hi = 0; + } - public PolyNode Parent - { - get { return m_Parent; } - } + public Int128(Int64 _hi, UInt64 _lo) + { + lo = _lo; + hi = _hi; + } - public bool IsHole - { - get { return IsHoleNode(); } - } + public Int128(Int128 val) + { + hi = val.hi; + lo = val.lo; } - - //------------------------------------------------------------------------------ - // Int128 struct (enables safe math on signed 64bit integers) - // eg Int128 val1((Int64)9223372036854775807); //ie 2^63 -1 - // Int128 val2((Int64)9223372036854775807); - // Int128 val3 = val1 * val2; - // val3.ToString => "85070591730234615847396907784232501249" (8.5e+37) - //------------------------------------------------------------------------------ + public bool IsNegative() + { + return hi < 0; + } - internal struct Int128 + public static bool operator ==(Int128 val1, Int128 val2) { - private Int64 hi; - private UInt64 lo; + if ((object)val1 == (object)val2) return true; + else if ((object)val1 == null || (object)val2 == null) return false; + return (val1.hi == val2.hi && val1.lo == val2.lo); + } - public Int128(Int64 _lo) - { - lo = (UInt64)_lo; - if (_lo < 0) hi = -1; - else hi = 0; - } + public static bool operator !=(Int128 val1, Int128 val2) + { + return !(val1 == val2); + } - public Int128(Int64 _hi, UInt64 _lo) - { - lo = _lo; - hi = _hi; - } - - public Int128(Int128 val) - { - hi = val.hi; - lo = val.lo; - } + public override bool Equals(System.Object obj) + { + if (obj == null || !(obj is Int128)) + return false; + Int128 i128 = (Int128)obj; + return (i128.hi == hi && i128.lo == lo); + } - public bool IsNegative() - { - return hi < 0; - } + public override int GetHashCode() + { + return hi.GetHashCode() ^ lo.GetHashCode(); + } - public static bool operator ==(Int128 val1, Int128 val2) - { - if ((object)val1 == (object)val2) return true; - else if ((object)val1 == null || (object)val2 == null) return false; - return (val1.hi == val2.hi && val1.lo == val2.lo); - } + public static bool operator >(Int128 val1, Int128 val2) + { + if (val1.hi != val2.hi) + return val1.hi > val2.hi; + else + return val1.lo > val2.lo; + } - public static bool operator!= (Int128 val1, Int128 val2) - { - return !(val1 == val2); - } + public static bool operator <(Int128 val1, Int128 val2) + { + if (val1.hi != val2.hi) + return val1.hi < val2.hi; + else + return val1.lo < val2.lo; + } - public override bool Equals(System.Object obj) - { - if (obj == null || !(obj is Int128)) - return false; - Int128 i128 = (Int128)obj; - return (i128.hi == hi && i128.lo == lo); - } + public static Int128 operator +(Int128 lhs, Int128 rhs) + { + lhs.hi += rhs.hi; + lhs.lo += rhs.lo; + if (lhs.lo < rhs.lo) lhs.hi++; + return lhs; + } - public override int GetHashCode() - { - return hi.GetHashCode() ^ lo.GetHashCode(); - } + public static Int128 operator -(Int128 lhs, Int128 rhs) + { + return lhs + -rhs; + } - public static bool operator> (Int128 val1, Int128 val2) - { - if (val1.hi != val2.hi) - return val1.hi > val2.hi; - else - return val1.lo > val2.lo; - } + public static Int128 operator -(Int128 val) + { + if (val.lo == 0) + return new Int128(-val.hi, 0); + else + return new Int128(~val.hi, ~val.lo + 1); + } - public static bool operator< (Int128 val1, Int128 val2) - { - if (val1.hi != val2.hi) - return val1.hi < val2.hi; - else - return val1.lo < val2.lo; - } + //nb: Constructing two new Int128 objects every time we want to multiply longs + //is slow. So, although calling the Int128Mul method doesn't look as clean, the + //code runs significantly faster than if we'd used the * operator. - public static Int128 operator+ (Int128 lhs, Int128 rhs) - { - lhs.hi += rhs.hi; - lhs.lo += rhs.lo; - if (lhs.lo < rhs.lo) lhs.hi++; - return lhs; - } + public static Int128 Int128Mul(Int64 lhs, Int64 rhs) + { + bool negate = (lhs < 0) != (rhs < 0); + if (lhs < 0) lhs = -lhs; + if (rhs < 0) rhs = -rhs; + UInt64 int1Hi = (UInt64)lhs >> 32; + UInt64 int1Lo = (UInt64)lhs & 0xFFFFFFFF; + UInt64 int2Hi = (UInt64)rhs >> 32; + UInt64 int2Lo = (UInt64)rhs & 0xFFFFFFFF; + + //nb: see comments in clipper.pas + UInt64 a = int1Hi * int2Hi; + UInt64 b = int1Lo * int2Lo; + UInt64 c = int1Hi * int2Lo + int1Lo * int2Hi; + + UInt64 lo; + Int64 hi; + hi = (Int64)(a + (c >> 32)); + + unchecked { lo = (c << 32) + b; } + if (lo < b) hi++; + Int128 result = new Int128(hi, lo); + return negate ? -result : result; + } - public static Int128 operator- (Int128 lhs, Int128 rhs) - { - return lhs + -rhs; - } + public static Int128 operator /(Int128 lhs, Int128 rhs) + { + if (rhs.lo == 0 && rhs.hi == 0) + throw new ClipperException("Int128: divide by zero"); - public static Int128 operator -(Int128 val) - { - if (val.lo == 0) - return new Int128(-val.hi, 0); - else - return new Int128(~val.hi, ~val.lo +1); - } + bool negate = (rhs.hi < 0) != (lhs.hi < 0); + if (lhs.hi < 0) lhs = -lhs; + if (rhs.hi < 0) rhs = -rhs; - //nb: Constructing two new Int128 objects every time we want to multiply longs - //is slow. So, although calling the Int128Mul method doesn't look as clean, the - //code runs significantly faster than if we'd used the * operator. - - public static Int128 Int128Mul(Int64 lhs, Int64 rhs) + if (rhs < lhs) + { + Int128 result = new Int128(0); + Int128 cntr = new Int128(1); + while (rhs.hi >= 0 && !(rhs > lhs)) { - bool negate = (lhs < 0) != (rhs < 0); - if (lhs < 0) lhs = -lhs; - if (rhs < 0) rhs = -rhs; - UInt64 int1Hi = (UInt64)lhs >> 32; - UInt64 int1Lo = (UInt64)lhs & 0xFFFFFFFF; - UInt64 int2Hi = (UInt64)rhs >> 32; - UInt64 int2Lo = (UInt64)rhs & 0xFFFFFFFF; - - //nb: see comments in clipper.pas - UInt64 a = int1Hi * int2Hi; - UInt64 b = int1Lo * int2Lo; - UInt64 c = int1Hi * int2Lo + int1Lo * int2Hi; + rhs.hi <<= 1; + if ((Int64)rhs.lo < 0) rhs.hi++; + rhs.lo <<= 1; - UInt64 lo; - Int64 hi; - hi = (Int64)(a + (c >> 32)); - - unchecked { lo = (c << 32) + b; } - if (lo < b) hi++; - Int128 result = new Int128(hi, lo); - return negate ? -result : result; + cntr.hi <<= 1; + if ((Int64)cntr.lo < 0) cntr.hi++; + cntr.lo <<= 1; } + rhs.lo >>= 1; + if ((rhs.hi & 1) == 1) + rhs.lo |= 0x8000000000000000; + rhs.hi = (Int64)((UInt64)rhs.hi >> 1); - public static Int128 operator /(Int128 lhs, Int128 rhs) - { - if (rhs.lo == 0 && rhs.hi == 0) - throw new ClipperException("Int128: divide by zero"); - - bool negate = (rhs.hi < 0) != (lhs.hi < 0); - if (lhs.hi < 0) lhs = -lhs; - if (rhs.hi < 0) rhs = -rhs; - - if (rhs < lhs) - { - Int128 result = new Int128(0); - Int128 cntr = new Int128(1); - while (rhs.hi >= 0 && !(rhs > lhs)) - { - rhs.hi <<= 1; - if ((Int64)rhs.lo < 0) rhs.hi++; - rhs.lo <<= 1; - - cntr.hi <<= 1; - if ((Int64)cntr.lo < 0) cntr.hi++; - cntr.lo <<= 1; - } - rhs.lo >>= 1; - if ((rhs.hi & 1) == 1) - rhs.lo |= 0x8000000000000000; - rhs.hi = (Int64)((UInt64)rhs.hi >> 1); + cntr.lo >>= 1; + if ((cntr.hi & 1) == 1) + cntr.lo |= 0x8000000000000000; + cntr.hi >>= 1; - cntr.lo >>= 1; - if ((cntr.hi & 1) == 1) - cntr.lo |= 0x8000000000000000; - cntr.hi >>= 1; + while (cntr.hi != 0 || cntr.lo != 0) + { + if (!(lhs < rhs)) + { + lhs -= rhs; + result.hi |= cntr.hi; + result.lo |= cntr.lo; + } + rhs.lo >>= 1; + if ((rhs.hi & 1) == 1) + rhs.lo |= 0x8000000000000000; + rhs.hi >>= 1; + + cntr.lo >>= 1; + if ((cntr.hi & 1) == 1) + cntr.lo |= 0x8000000000000000; + cntr.hi >>= 1; + } + return negate ? -result : result; + } + else if (rhs == lhs) + return new Int128(1); + else + return new Int128(0); + } - while (cntr.hi != 0 || cntr.lo != 0) - { - if (!(lhs < rhs)) - { - lhs -= rhs; - result.hi |= cntr.hi; - result.lo |= cntr.lo; - } - rhs.lo >>= 1; - if ((rhs.hi & 1) == 1) - rhs.lo |= 0x8000000000000000; - rhs.hi >>= 1; - - cntr.lo >>= 1; - if ((cntr.hi & 1) == 1) - cntr.lo |= 0x8000000000000000; - cntr.hi >>= 1; - } - return negate ? -result : result; - } - else if (rhs == lhs) - return new Int128(1); - else - return new Int128(0); - } + public double ToDouble() + { + const double shift64 = 18446744073709551616.0; //2^64 + if (hi < 0) + { + if (lo == 0) + return (double)hi * shift64; + else + return -(double)(~lo + ~hi * shift64); + } + else + return (double)(lo + hi * shift64); + } - public double ToDouble() - { - const double shift64 = 18446744073709551616.0; //2^64 - if (hi < 0) - { - if (lo == 0) - return (double)hi * shift64; - else - return -(double)(~lo + ~hi * shift64); - } - else - return (double)(lo + hi * shift64); - } + }; - }; + //------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ - //------------------------------------------------------------------------------ - //------------------------------------------------------------------------------ - - public struct IntPoint + public struct IntPoint + { + public cInt X; + public cInt Y; +#if use_xyz + public cInt Z; + + public IntPoint(cInt x, cInt y, cInt z = 0) { - public Int64 X; - public Int64 Y; - - public IntPoint(Int64 X, Int64 Y) - { - this.X = X; this.Y = Y; - } - - public IntPoint(IntPoint pt) - { - this.X = pt.X; this.Y = pt.Y; - } + this.X = x; this.Y = y; this.Z = z; } - - public struct IntRect + + public IntPoint(double x, double y, double z = 0) { - public Int64 left; - public Int64 top; - public Int64 right; - public Int64 bottom; - - public IntRect(Int64 l, Int64 t, Int64 r, Int64 b) - { - this.left = l; this.top = t; - this.right = r; this.bottom = b; - } + this.X = (cInt)x; this.Y = (cInt)y; this.Z = (cInt)z; } - - public enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; - public 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 - public enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; - public enum JoinType { jtSquare, jtRound, jtMiter }; - public enum EndType { etClosed, etButt, etSquare, etRound}; - - - [Flags] - internal enum EdgeSide { esLeft = 1, esRight = 2 }; - [Flags] - internal enum Protects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 }; - internal enum Direction { dRightToLeft, dLeftToRight }; - internal class TEdge { - public Int64 xbot; - public Int64 ybot; - public Int64 xcurr; - public Int64 ycurr; - public Int64 xtop; - public Int64 ytop; - public double dx; - public Int64 deltaX; - public Int64 deltaY; - public PolyType polyType; - public EdgeSide side; - public int windDelta; //1 or -1 depending on winding direction - public int windCnt; - public int windCnt2; //winding count of the opposite polytype - public int outIdx; - public TEdge next; - public TEdge prev; - public TEdge nextInLML; - public TEdge nextInAEL; - public TEdge prevInAEL; - public TEdge nextInSEL; - public TEdge prevInSEL; - }; - - internal class IntersectNode + public IntPoint(DoublePoint dp) { - public TEdge edge1; - public TEdge edge2; - public IntPoint pt; - public IntersectNode next; - }; + this.X = (cInt)dp.X; this.Y = (cInt)dp.Y; this.Z = 0; + } - internal class LocalMinima + public IntPoint(IntPoint pt) { - public Int64 Y; - public TEdge leftBound; - public TEdge rightBound; - public LocalMinima next; - }; - - internal class Scanbeam + this.X = pt.X; this.Y = pt.Y; this.Z = pt.Z; + } +#else + public IntPoint(cInt X, cInt Y) + { + this.X = X; this.Y = Y; + } + public IntPoint(double x, double y) { - public Int64 Y; - public Scanbeam next; - }; + this.X = (cInt)x; this.Y = (cInt)y; + } - internal class OutRec + public IntPoint(IntPoint pt) { - public int idx; - public bool isHole; - public OutRec FirstLeft; //see comments in clipper.pas - public OutPt pts; - public OutPt bottomPt; - public PolyNode polyNode; - }; - - internal class OutPt + this.X = pt.X; this.Y = pt.Y; + } +#endif + + public static bool operator ==(IntPoint a, IntPoint b) { - public int idx; - public IntPoint pt; - public OutPt next; - public OutPt prev; - }; + return a.X == b.X && a.Y == b.Y; + } - internal class JoinRec + public static bool operator !=(IntPoint a, IntPoint b) { - public IntPoint pt1a; - public IntPoint pt1b; - public int poly1Idx; - public IntPoint pt2a; - public IntPoint pt2b; - public int poly2Idx; - }; - - internal class HorzJoinRec + return a.X != b.X || a.Y != b.Y; + } + + public override bool Equals(object obj) { - public TEdge edge; - public int savedIdx; - }; + if (obj == null) return false; + if (obj is IntPoint) + { + IntPoint a = (IntPoint)obj; + return (X == a.X) && (Y == a.Y); + } + else return false; + } - public class ClipperBase + public override int GetHashCode() { - protected const double horizontal = -3.4E+38; - internal const Int64 loRange = 0x3FFFFFFF; - internal const Int64 hiRange = 0x3FFFFFFFFFFFFFFFL; + //simply prevents a compiler warning + return base.GetHashCode(); + } +} - internal LocalMinima m_MinimaList; - internal LocalMinima m_CurrentLM; - internal List> m_edges = new List>(); - internal bool m_UseFullRange; - //------------------------------------------------------------------------------ + public struct IntRect + { + public cInt left; + public cInt top; + public cInt right; + public cInt bottom; - protected static bool PointsEqual(IntPoint pt1, IntPoint pt2) - { - return ( pt1.X == pt2.X && pt1.Y == pt2.Y ); + public IntRect(cInt l, cInt t, cInt r, cInt b) + { + this.left = l; this.top = t; + this.right = r; this.bottom = b; + } + public IntRect(IntRect ir) + { + this.left = ir.left; this.top = ir.top; + this.right = ir.right; this.bottom = ir.bottom; + } + } + + public enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; + public 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 + public enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; + public enum JoinType { jtSquare, jtRound, jtMiter }; + public enum EndType { etClosed, etButt, etSquare, etRound}; + + internal enum EdgeSide {esLeft, esRight}; + internal enum Direction {dRightToLeft, dLeftToRight}; + + internal class TEdge { + public IntPoint Bot; + public IntPoint Curr; + public IntPoint Top; + public IntPoint Delta; + public double Dx; + public PolyType PolyTyp; + public EdgeSide Side; + public int WindDelta; //1 or -1 depending on winding direction + public int WindCnt; + public int WindCnt2; //winding count of the opposite polytype + public int OutIdx; + public TEdge Next; + public TEdge Prev; + public TEdge NextInLML; + public TEdge NextInAEL; + public TEdge PrevInAEL; + public TEdge NextInSEL; + public TEdge PrevInSEL; + }; + + internal class IntersectNode + { + public TEdge Edge1; + public TEdge Edge2; + public IntPoint Pt; + public IntersectNode Next; + }; + + internal class LocalMinima + { + public cInt Y; + public TEdge LeftBound; + public TEdge RightBound; + public LocalMinima Next; + }; + + internal class Scanbeam + { + public cInt Y; + public Scanbeam Next; + }; + + internal class OutRec + { + public int Idx; + public bool IsHole; + public bool IsOpen; + public OutRec FirstLeft; //see comments in clipper.pas + public OutPt Pts; + public OutPt BottomPt; + public PolyNode PolyNode; + }; + + internal class OutPt + { + public int Idx; + public IntPoint Pt; + public OutPt Next; + public OutPt Prev; + }; + + internal class Join + { + public OutPt OutPt1; + public OutPt OutPt2; + public IntPoint OffPt; + }; + + public class ClipperBase + { + protected const double horizontal = -3.4E+38; + protected const int Skip = -2; + protected const int Unassigned = -1; + protected const double tolerance = 1.0E-20; + internal static bool near_zero(double val){return (val > -tolerance) && (val < tolerance);} + +#if use_int32 + internal const cInt loRange = 46340; + internal const cInt hiRange = 46340; +#else + internal const cInt loRange = 0x3FFFFFFF; + internal const cInt hiRange = 0x3FFFFFFFFFFFFFFFL; +#endif + + internal LocalMinima m_MinimaList; + internal LocalMinima m_CurrentLM; + internal List> m_edges = new List>(); + internal bool m_UseFullRange; + internal bool m_HasOpenPaths; + + //------------------------------------------------------------------------------ + + public bool PreserveCollinear + { + get; + set; + } + //------------------------------------------------------------------------------ + + internal static bool IsHorizontal(TEdge e) + { + return e.Delta.Y == 0; + } + //------------------------------------------------------------------------------ + + internal bool PointIsVertex(IntPoint pt, OutPt pp) + { + OutPt pp2 = pp; + do + { + if (pp2.Pt == pt) return true; + pp2 = pp2.Next; + } + while (pp2 != pp); + return false; + } + //------------------------------------------------------------------------------ + + internal bool PointOnLineSegment(IntPoint pt, + IntPoint linePt1, IntPoint linePt2, bool UseFullRange) + { + if (UseFullRange) + return ((pt.X == linePt1.X) && (pt.Y == linePt1.Y)) || + ((pt.X == linePt2.X) && (pt.Y == linePt2.Y)) || + (((pt.X > linePt1.X) == (pt.X < linePt2.X)) && + ((pt.Y > linePt1.Y) == (pt.Y < linePt2.Y)) && + ((Int128.Int128Mul((pt.X - linePt1.X), (linePt2.Y - linePt1.Y)) == + Int128.Int128Mul((linePt2.X - linePt1.X), (pt.Y - linePt1.Y))))); + else + return ((pt.X == linePt1.X) && (pt.Y == linePt1.Y)) || + ((pt.X == linePt2.X) && (pt.Y == linePt2.Y)) || + (((pt.X > linePt1.X) == (pt.X < linePt2.X)) && + ((pt.Y > linePt1.Y) == (pt.Y < linePt2.Y)) && + ((pt.X - linePt1.X) * (linePt2.Y - linePt1.Y) == + (linePt2.X - linePt1.X) * (pt.Y - linePt1.Y))); + } + //------------------------------------------------------------------------------ + + internal bool PointOnPolygon(IntPoint pt, OutPt pp, bool UseFullRange) + { + OutPt pp2 = pp; + while (true) + { + if (PointOnLineSegment(pt, pp2.Pt, pp2.Next.Pt, UseFullRange)) + return true; + pp2 = pp2.Next; + if (pp2 == pp) break; } - //------------------------------------------------------------------------------ + return false; + } + //------------------------------------------------------------------------------ - internal bool PointIsVertex(IntPoint pt, OutPt pp) + internal bool PointInPolygon(IntPoint pt, OutPt pp, bool UseFullRange) + { + OutPt pp2 = pp; + bool result = false; + if (UseFullRange) + { + do + { + if (((pp2.Pt.Y > pt.Y) != (pp2.Prev.Pt.Y > pt.Y)) && + (new Int128(pt.X - pp2.Pt.X) < + Int128.Int128Mul(pp2.Prev.Pt.X - pp2.Pt.X, pt.Y - pp2.Pt.Y) / + new Int128(pp2.Prev.Pt.Y - pp2.Pt.Y))) result = !result; + pp2 = pp2.Next; + } + while (pp2 != pp); + } + else { - OutPt pp2 = pp; do { - if (PointsEqual(pp2.pt, pt)) return true; - pp2 = pp2.next; + //http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html + if (((pp2.Pt.Y > pt.Y) != (pp2.Prev.Pt.Y > pt.Y)) && + ((pt.X - pp2.Pt.X) < (pp2.Prev.Pt.X - pp2.Pt.X) * (pt.Y - pp2.Pt.Y) / + (pp2.Prev.Pt.Y - pp2.Pt.Y))) result = !result; + pp2 = pp2.Next; } while (pp2 != pp); - return false; - } - //------------------------------------------------------------------------------ - - internal bool PointOnLineSegment(IntPoint pt, - IntPoint linePt1, IntPoint linePt2, bool UseFullInt64Range) - { - if (UseFullInt64Range) - return ((pt.X == linePt1.X) && (pt.Y == linePt1.Y)) || - ((pt.X == linePt2.X) && (pt.Y == linePt2.Y)) || - (((pt.X > linePt1.X) == (pt.X < linePt2.X)) && - ((pt.Y > linePt1.Y) == (pt.Y < linePt2.Y)) && - ((Int128.Int128Mul((pt.X - linePt1.X), (linePt2.Y - linePt1.Y)) == - Int128.Int128Mul((linePt2.X - linePt1.X), (pt.Y - linePt1.Y))))); - else - return ((pt.X == linePt1.X) && (pt.Y == linePt1.Y)) || - ((pt.X == linePt2.X) && (pt.Y == linePt2.Y)) || - (((pt.X > linePt1.X) == (pt.X < linePt2.X)) && - ((pt.Y > linePt1.Y) == (pt.Y < linePt2.Y)) && - ((pt.X - linePt1.X) * (linePt2.Y - linePt1.Y) == - (linePt2.X - linePt1.X) * (pt.Y - linePt1.Y))); } - //------------------------------------------------------------------------------ - - internal bool PointOnPolygon(IntPoint pt, OutPt pp, bool UseFullInt64Range) - { - OutPt pp2 = pp; - while (true) + return result; + } + //------------------------------------------------------------------------------ + + internal static bool SlopesEqual(TEdge e1, TEdge e2, bool UseFullRange) + { + if (UseFullRange) + return Int128.Int128Mul(e1.Delta.Y, e2.Delta.X) == + Int128.Int128Mul(e1.Delta.X, e2.Delta.Y); + else return (cInt)(e1.Delta.Y) * (e2.Delta.X) == + (cInt)(e1.Delta.X) * (e2.Delta.Y); + } + //------------------------------------------------------------------------------ + + protected static bool SlopesEqual(IntPoint pt1, IntPoint pt2, + IntPoint pt3, bool UseFullRange) + { + if (UseFullRange) + return Int128.Int128Mul(pt1.Y - pt2.Y, pt2.X - pt3.X) == + Int128.Int128Mul(pt1.X - pt2.X, pt2.Y - pt3.Y); + else return + (cInt)(pt1.Y - pt2.Y) * (pt2.X - pt3.X) - (cInt)(pt1.X - pt2.X) * (pt2.Y - pt3.Y) == 0; + } + //------------------------------------------------------------------------------ + + protected static bool SlopesEqual(IntPoint pt1, IntPoint pt2, + IntPoint pt3, IntPoint pt4, bool UseFullRange) + { + if (UseFullRange) + return Int128.Int128Mul(pt1.Y - pt2.Y, pt3.X - pt4.X) == + Int128.Int128Mul(pt1.X - pt2.X, pt3.Y - pt4.Y); + else return + (cInt)(pt1.Y - pt2.Y) * (pt3.X - pt4.X) - (cInt)(pt1.X - pt2.X) * (pt3.Y - pt4.Y) == 0; + } + //------------------------------------------------------------------------------ + + internal ClipperBase() //constructor (nb: no external instantiation) + { + m_MinimaList = null; + m_CurrentLM = null; + m_UseFullRange = false; + m_HasOpenPaths = false; + } + //------------------------------------------------------------------------------ + + public virtual void Clear() + { + DisposeLocalMinimaList(); + for (int i = 0; i < m_edges.Count; ++i) { - if (PointOnLineSegment(pt, pp2.pt, pp2.next.pt, UseFullInt64Range)) - return true; - pp2 = pp2.next; - if (pp2 == pp) break; + for (int j = 0; j < m_edges[i].Count; ++j) m_edges[i][j] = null; + m_edges[i].Clear(); } - return false; - } - //------------------------------------------------------------------------------ + m_edges.Clear(); + m_UseFullRange = false; + m_HasOpenPaths = false; + } + //------------------------------------------------------------------------------ + + private void DisposeLocalMinimaList() + { + while( m_MinimaList != null ) + { + LocalMinima tmpLm = m_MinimaList.Next; + m_MinimaList = null; + m_MinimaList = tmpLm; + } + m_CurrentLM = null; + } + //------------------------------------------------------------------------------ + + void RangeTest(IntPoint Pt, ref bool useFullRange) + { + if (useFullRange) + { + if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) + throw new ClipperException("Coordinate outside allowed range"); + } + else if (Pt.X > loRange || Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) + { + useFullRange = true; + RangeTest(Pt, ref useFullRange); + } + } + //------------------------------------------------------------------------------ + + private void InitEdge(TEdge e, TEdge eNext, + TEdge ePrev, IntPoint pt) + { + e.Next = eNext; + e.Prev = ePrev; + e.Curr = pt; + e.OutIdx = Unassigned; + } + //------------------------------------------------------------------------------ + + private void InitEdge2(TEdge e, PolyType polyType) + { + if (e.Curr.Y >= e.Next.Curr.Y) + { + e.Bot = e.Curr; + e.Top = e.Next.Curr; + } + else + { + e.Top = e.Curr; + e.Bot = e.Next.Curr; + } + SetDx(e); + e.PolyTyp = polyType; + } + //------------------------------------------------------------------------------ + + public bool AddPath(Path pg, PolyType polyType, bool Closed) + { +#if use_lines + if (!Closed && polyType == PolyType.ptClip) + throw new ClipperException("AddPath: Open paths must be subject."); +#else + if (!Closed) + throw new ClipperException("AddPath: Open paths have been disabled."); +#endif + + int highI = (int)pg.Count - 1; + bool ClosedOrSemiClosed = (highI > 0) && (Closed || (pg[0] == pg[highI])); + while (highI > 0 && (pg[highI] == pg[0])) --highI; + while (highI > 0 && (pg[highI] == pg[highI - 1])) --highI; + if ((Closed && highI < 2) || (!Closed && highI < 1)) return false; + + //create a new edge array ... + List edges = new List(highI+1); + for (int i = 0; i <= highI; i++) edges.Add(new TEdge()); + + //1. Basic initialization of Edges ... + try + { + edges[1].Curr = pg[1]; + RangeTest(pg[0], ref m_UseFullRange); + RangeTest(pg[highI], ref m_UseFullRange); + InitEdge(edges[0], edges[1], edges[highI], pg[0]); + InitEdge(edges[highI], edges[0], edges[highI - 1], pg[highI]); + for (int i = highI - 1; i >= 1; --i) + { + RangeTest(pg[i], ref m_UseFullRange); + InitEdge(edges[i], edges[i + 1], edges[i - 1], pg[i]); + } + } + catch + { + return false; //almost certainly a vertex has exceeded range + }; - internal bool PointInPolygon(IntPoint pt, OutPt pp, bool UseFulllongRange) - { - OutPt pp2 = pp; - bool result = false; - if (UseFulllongRange) + TEdge eStart = edges[0]; + if (!ClosedOrSemiClosed) eStart.Prev.OutIdx = Skip; + + //2. Remove duplicate vertices, and collinear edges (when closed) ... + TEdge E = eStart, eLoopStop = eStart; + for (;;) { - do + if (E.Curr == E.Next.Curr) + { + //nb if E.OutIdx == Skip, it would have been semiOpen + if (E == eStart) eStart = E.Next; + E = RemoveEdge(E); + eLoopStop = E; + continue; + } + if (E.Prev == E.Next) + break; //only two vertices + else if ((ClosedOrSemiClosed || + (E.Prev.OutIdx != Skip && E.OutIdx != Skip && + E.Next.OutIdx != Skip)) && + SlopesEqual(E.Prev.Curr, E.Curr, E.Next.Curr, m_UseFullRange)) + { + //All collinear edges are allowed for open paths but in closed paths + //inner vertices of adjacent collinear edges are removed. However if the + //PreserveCollinear property has been enabled, only overlapping collinear + //edges (ie spikes) are removed from closed paths. + if (Closed && (!PreserveCollinear || + !Pt2IsBetweenPt1AndPt3(E.Prev.Curr, E.Curr, E.Next.Curr))) { - if ((((pp2.pt.Y <= pt.Y) && (pt.Y < pp2.prev.pt.Y)) || - ((pp2.prev.pt.Y <= pt.Y) && (pt.Y < pp2.pt.Y))) && - new Int128(pt.X - pp2.pt.X) < - Int128.Int128Mul(pp2.prev.pt.X - pp2.pt.X, pt.Y - pp2.pt.Y) / - new Int128(pp2.prev.pt.Y - pp2.pt.Y)) - result = !result; - pp2 = pp2.next; + if (E == eStart) eStart = E.Next; + E = RemoveEdge(E); + E = E.Prev; + eLoopStop = E; + continue; } - while (pp2 != pp); + } + E = E.Next; + if (E == eLoopStop) break; } - else + + if ((!Closed && (E == E.Next)) || (Closed && (E.Prev == E.Next))) + return false; + m_edges.Add(edges); + + if (!Closed) + m_HasOpenPaths = true; + + //3. Do final Init and also find the 'highest' Edge. (nb: since I'm much + //more familiar with positive downwards Y axes, 'highest' here will be + //the Edge with the *smallest* Top.Y.) + TEdge eHighest = eStart; + E = eStart; + do + { + InitEdge2(E, polyType); + if (E.Top.Y < eHighest.Top.Y) eHighest = E; + E = E.Next; + } + while (E != eStart); + + //4. build the local minima list ... + if (AllHorizontal(E)) + { + if (ClosedOrSemiClosed) + E.Prev.OutIdx = Skip; + AscendToMax(ref E, false, false); + return true; + } + + //if eHighest is also the Skip then it's a natural break, otherwise + //make sure eHighest is positioned so we're either at a top horizontal or + //just starting to head down one edge of the polygon + E = eStart.Prev; //EStart.Prev == Skip edge + if (E.Prev == E.Next) + eHighest = E.Next; + else if (!ClosedOrSemiClosed && E.Top.Y == eHighest.Top.Y) + { + if ((IsHorizontal(E) || IsHorizontal(E.Next)) && + E.Next.Bot.Y == eHighest.Top.Y) + eHighest = E.Next; + else if (SharedVertWithPrevAtTop(E)) eHighest = E; + else if (E.Top == E.Prev.Top) eHighest = E.Prev; + else eHighest = E.Next; + } else { - do + E = eHighest; + while (IsHorizontal(eHighest) || + (eHighest.Top == eHighest.Next.Top) || + (eHighest.Top == eHighest.Next.Bot)) //next is high horizontal + { + eHighest = eHighest.Next; + if (eHighest == E) { - if ((((pp2.pt.Y <= pt.Y) && (pt.Y < pp2.prev.pt.Y)) || - ((pp2.prev.pt.Y <= pt.Y) && (pt.Y < pp2.pt.Y))) && - (pt.X - pp2.pt.X < (pp2.prev.pt.X - pp2.pt.X) * (pt.Y - pp2.pt.Y) / - (pp2.prev.pt.Y - pp2.pt.Y))) result = !result; - pp2 = pp2.next; + while (IsHorizontal(eHighest) || !SharedVertWithPrevAtTop(eHighest)) + eHighest = eHighest.Next; + break; //avoids potential endless loop } - while (pp2 != pp); + } } - return result; + E = eHighest; + do + E = AddBoundsToLML(E, Closed); + while (E != eHighest); + return true; + } + //------------------------------------------------------------------------------ + + public bool AddPaths(Paths ppg, PolyType polyType, bool closed) + { + bool result = false; + for (int i = 0; i < ppg.Count; ++i) + if (AddPath(ppg[i], polyType, closed)) result = true; + return result; + } + //------------------------------------------------------------------------------ + +#if use_deprecated + public bool AddPolygon(Path pg, PolyType polyType) + { + return AddPath(pg, polyType, true); + } + //------------------------------------------------------------------------------ + + public bool AddPolygons(Paths ppg, PolyType polyType) + { + bool result = false; + for (int i = 0; i < ppg.Count; ++i) + if (AddPath(ppg[i], polyType, true)) result = true; + return result; + } + //------------------------------------------------------------------------------ +#endif + + internal bool Pt2IsBetweenPt1AndPt3(IntPoint pt1, IntPoint pt2, IntPoint pt3) + { + if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2)) return false; + else if (pt1.X != pt3.X) return (pt2.X > pt1.X) == (pt2.X < pt3.X); + else return (pt2.Y > pt1.Y) == (pt2.Y < pt3.Y); + } + //------------------------------------------------------------------------------ + + TEdge RemoveEdge(TEdge e) + { + //removes e from double_linked_list (but without removing from memory) + e.Prev.Next = e.Next; + e.Next.Prev = e.Prev; + TEdge result = e.Next; + e.Prev = null; //flag as removed (see ClipperBase.Clear) + return result; + } + //------------------------------------------------------------------------------ + + TEdge GetLastHorz(TEdge Edge) + { + TEdge result = Edge; + while (result.OutIdx != Skip && result.Next != Edge && IsHorizontal(result.Next)) + result = result.Next; + return result; + } + //------------------------------------------------------------------------------ + + bool SharedVertWithPrevAtTop(TEdge Edge) + { + TEdge E = Edge; + bool result = true; + while (E.Prev != Edge) + { + if (E.Top == E.Prev.Top) + { + if (E.Bot == E.Prev.Bot) + {E = E.Prev; continue;} + else result = true; + } + else result = false; + break; + } + while (E != Edge) + { + result = !result; + E = E.Next; } - //------------------------------------------------------------------------------ + return result; + } + //------------------------------------------------------------------------------ - internal static bool SlopesEqual(TEdge e1, TEdge e2, bool UseFullRange) + bool SharedVertWithNextIsBot(TEdge Edge) + { + bool result = true; + TEdge E = Edge; + while (E.Prev != Edge) { - if (UseFullRange) - return Int128.Int128Mul(e1.deltaY, e2.deltaX) == - Int128.Int128Mul(e1.deltaX, e2.deltaY); - else return (Int64)(e1.deltaY) * (e2.deltaX) == - (Int64)(e1.deltaX) * (e2.deltaY); + bool A = (E.Next.Bot == E.Bot); + bool B = (E.Prev.Bot == E.Bot); + if (A != B) + { + result = A; + break; + } + A = (E.Next.Top == E.Top); + B = (E.Prev.Top == E.Top); + if (A != B) + { + result = B; + break; + } + E = E.Prev; + } + while (E != Edge) + { + result = !result; + E = E.Next; + } + return result; + } + //------------------------------------------------------------------------------ + + bool MoreBelow(TEdge Edge) + { + //Edge is Skip heading down. + TEdge E = Edge; + if (IsHorizontal(E)) + { + while (IsHorizontal(E.Next)) E = E.Next; + return E.Next.Bot.Y > E.Bot.Y; + } + else if (IsHorizontal(E.Next)) + { + while (IsHorizontal(E.Next)) E = E.Next; + return E.Next.Bot.Y > E.Bot.Y; + } + else return (E.Bot == E.Next.Top); + } + //------------------------------------------------------------------------------ + + bool JustBeforeLocMin(TEdge Edge) + { + //Edge is Skip and was heading down. + TEdge E = Edge; + if (IsHorizontal(E)) + { + while (IsHorizontal(E.Next)) E = E.Next; + return E.Next.Top.Y < E.Bot.Y; + } + else return SharedVertWithNextIsBot(E); + } + //------------------------------------------------------------------------------ + + bool MoreAbove(TEdge Edge) + { + if (IsHorizontal(Edge)) + { + Edge = GetLastHorz(Edge); + return (Edge.Next.Top.Y < Edge.Top.Y); + } + else if (IsHorizontal(Edge.Next)) + { + Edge = GetLastHorz(Edge.Next); + return (Edge.Next.Top.Y < Edge.Top.Y); + } + else + return (Edge.Next.Top.Y < Edge.Top.Y); + } + //------------------------------------------------------------------------------ + + bool AllHorizontal(TEdge Edge) + { + if (!IsHorizontal(Edge)) return false; + TEdge E = Edge.Next; + while (E != Edge) + { + if (!IsHorizontal(E)) return false; + else E = E.Next; + } + return true; + } + //------------------------------------------------------------------------------ + + private void SetDx(TEdge e) + { + e.Delta.X = (e.Top.X - e.Bot.X); + e.Delta.Y = (e.Top.Y - e.Bot.Y); + if (e.Delta.Y == 0) e.Dx = horizontal; + else e.Dx = (double)(e.Delta.X) / (e.Delta.Y); + } + //--------------------------------------------------------------------------- + + void DoMinimaLML(TEdge E1, TEdge E2, bool IsClosed) + { + if (E1 == null) + { + if (E2 == null) return; + LocalMinima NewLm = new LocalMinima(); + NewLm.Next = null; + NewLm.Y = E2.Bot.Y; + NewLm.LeftBound = null; + E2.WindDelta = 0; + NewLm.RightBound = E2; + InsertLocalMinima(NewLm); + } else + { + //E and E.Prev are now at a local minima ... + LocalMinima NewLm = new LocalMinima(); + NewLm.Y = E1.Bot.Y; + NewLm.Next = null; + if (IsHorizontal(E2)) //Horz. edges never start a Left bound + { + if (E2.Bot.X != E1.Bot.X) ReverseHorizontal(E2); + NewLm.LeftBound = E1; + NewLm.RightBound = E2; + } else if (E2.Dx < E1.Dx) + { + NewLm.LeftBound = E1; + NewLm.RightBound = E2; + } else + { + NewLm.LeftBound = E2; + NewLm.RightBound = E1; + } + NewLm.LeftBound.Side = EdgeSide.esLeft; + NewLm.RightBound.Side = EdgeSide.esRight; + //set the winding state of the first edge in each bound + //(it'll be copied to subsequent edges in the bound) ... + if (!IsClosed) NewLm.LeftBound.WindDelta = 0; + else if (NewLm.LeftBound.Next == NewLm.RightBound) NewLm.LeftBound.WindDelta = -1; + else NewLm.LeftBound.WindDelta = 1; + NewLm.RightBound.WindDelta = -NewLm.LeftBound.WindDelta; + InsertLocalMinima(NewLm); + } + } + //---------------------------------------------------------------------- + + TEdge DescendToMin(ref TEdge E) + { + //PRECONDITION: STARTING EDGE IS A VALID DESCENDING EDGE. + //Starting at the top of one bound we progress to the bottom where there's + //A local minima. We go to the top of the Next bound. These two bounds + //form the left and right (or right and left) bounds of the local minima. + TEdge EHorz; + E.NextInLML = null; + if (IsHorizontal(E)) + { + EHorz = E; + while (IsHorizontal(EHorz.Next)) EHorz = EHorz.Next; + if (EHorz.Bot!= EHorz.Next.Top) + ReverseHorizontal(E); + } + for (;;) + { + E = E.Next; + if (E.OutIdx == Skip) break; + else if (IsHorizontal(E)) + { + //nb: proceed through horizontals when approaching from their right, + // but break on horizontal minima if approaching from their left. + // This ensures 'local minima' are always on the left of horizontals. + + //look ahead is required in case of multiple consec. horizontals + EHorz = GetLastHorz(E); + if(EHorz == E.Prev || //horizontal line + (EHorz.Next.Top.Y < E.Top.Y && //bottom horizontal + EHorz.Next.Bot.X > E.Prev.Bot.X)) //approaching from the left + break; + if (E.Top.X != E.Prev.Bot.X) ReverseHorizontal(E); + if (EHorz.OutIdx == Skip) EHorz = EHorz.Prev; + while (E != EHorz) + { + E.NextInLML = E.Prev; + E = E.Next; + if (E.Top.X != E.Prev.Bot.X) ReverseHorizontal(E); + } + } + else if (E.Bot.Y == E.Prev.Bot.Y) break; + E.NextInLML = E.Prev; } - //------------------------------------------------------------------------------ + return E.Prev; + } + //---------------------------------------------------------------------- - protected static bool SlopesEqual(IntPoint pt1, IntPoint pt2, - IntPoint pt3, bool UseFullRange) + void AscendToMax(ref TEdge E, bool Appending, bool IsClosed) + { + if (E.OutIdx == Skip) { - if (UseFullRange) - return Int128.Int128Mul(pt1.Y - pt2.Y, pt2.X - pt3.X) == - Int128.Int128Mul(pt1.X - pt2.X, pt2.Y - pt3.Y); - else return - (Int64)(pt1.Y - pt2.Y) * (pt2.X - pt3.X) - (Int64)(pt1.X - pt2.X) * (pt2.Y - pt3.Y) == 0; + E = E.Next; + if (!MoreAbove(E.Prev)) return; } - //------------------------------------------------------------------------------ - protected static bool SlopesEqual(IntPoint pt1, IntPoint pt2, - IntPoint pt3, IntPoint pt4, bool UseFullRange) + if (IsHorizontal(E) && Appending && + (E.Bot != E.Prev.Bot)) + ReverseHorizontal(E); + //now process the ascending bound .... + TEdge EStart = E; + for (;;) { - if (UseFullRange) - return Int128.Int128Mul(pt1.Y - pt2.Y, pt3.X - pt4.X) == - Int128.Int128Mul(pt1.X - pt2.X, pt3.Y - pt4.Y); - else return - (Int64)(pt1.Y - pt2.Y) * (pt3.X - pt4.X) - (Int64)(pt1.X - pt2.X) * (pt3.Y - pt4.Y) == 0; + if (E.Next.OutIdx == Skip || + ((E.Next.Top.Y == E.Top.Y) && !IsHorizontal(E.Next))) break; + E.NextInLML = E.Next; + E = E.Next; + if (IsHorizontal(E) && (E.Bot.X != E.Prev.Top.X)) + ReverseHorizontal(E); } - //------------------------------------------------------------------------------ - internal ClipperBase() //constructor (nb: no external instantiation) + if (!Appending) { - m_MinimaList = null; - m_CurrentLM = null; - m_UseFullRange = false; + if (EStart.OutIdx == Skip) EStart = EStart.Next; + if (EStart != E.Next) + DoMinimaLML(null, EStart, IsClosed); } - //------------------------------------------------------------------------------ + E = E.Next; + } + //---------------------------------------------------------------------- - //destructor - commented out since I gather this impedes the GC - //~ClipperBase() - //{ - // Clear(); - //} - //------------------------------------------------------------------------------ + TEdge AddBoundsToLML(TEdge E, bool Closed) + { + //Starting at the top of one bound we progress to the bottom where there's + //A local minima. We then go to the top of the Next bound. These two bounds + //form the left and right (or right and left) bounds of the local minima. - public virtual void Clear() + TEdge B; + bool AppendMaxima; + //do minima ... + if (E.OutIdx == Skip) { - DisposeLocalMinimaList(); - for (int i = 0; i < m_edges.Count; ++i) - { - for (int j = 0; j < m_edges[i].Count; ++j) m_edges[i][j] = null; - m_edges[i].Clear(); - } - m_edges.Clear(); - m_UseFullRange = false; + if (MoreBelow(E)) + { + E = E.Next; + B = DescendToMin(ref E); + } + else + B = null; } - //------------------------------------------------------------------------------ + else + B = DescendToMin(ref E); - private void DisposeLocalMinimaList() + if (E.OutIdx == Skip) //nb: may be BEFORE, AT or just THRU LM { - while( m_MinimaList != null ) - { - LocalMinima tmpLm = m_MinimaList.next; - m_MinimaList = null; - m_MinimaList = tmpLm; - } - m_CurrentLM = null; + //do minima before Skip... + DoMinimaLML(null, B, Closed); //store what we've got so far (if anything) + AppendMaxima = false; + //finish off any minima ... + if (E.Bot != E.Prev.Bot && MoreBelow(E)) + { + E = E.Next; + B = DescendToMin(ref E); + DoMinimaLML(B, E, Closed); + AppendMaxima = true; + } + else if (JustBeforeLocMin(E)) + E = E.Next; } - //------------------------------------------------------------------------------ - - public bool AddPolygons(Polygons ppg, PolyType polyType) + else { - bool result = false; - for (int i = 0; i < ppg.Count; ++i) - if (AddPolygon(ppg[i], polyType)) result = true; - return result; + DoMinimaLML(B, E, Closed); + AppendMaxima = true; } - //------------------------------------------------------------------------------ - void RangeTest(IntPoint pt, ref Int64 maxrange) + //now do maxima ... + AscendToMax(ref E, AppendMaxima, Closed); + + if (E.OutIdx == Skip && (E.Top != E.Prev.Top)) //may be BEFORE, AT or just AFTER maxima { - if (pt.X > maxrange) + //finish off any maxima ... + if (MoreAbove(E)) { - if (pt.X > hiRange) - throw new ClipperException("Coordinate exceeds range bounds"); - else maxrange = hiRange; + E = E.Next; + AscendToMax(ref E, false, Closed); } - if (pt.Y > maxrange) + else if (E.Top == E.Next.Top || (IsHorizontal(E.Next) && (E.Top == E.Next.Bot))) + E = E.Next; //ie just before Maxima + } + return E; + } + //------------------------------------------------------------------------------ + + private void InsertLocalMinima(LocalMinima newLm) + { + if( m_MinimaList == null ) + { + m_MinimaList = newLm; + } + else if( newLm.Y >= m_MinimaList.Y ) + { + newLm.Next = m_MinimaList; + m_MinimaList = newLm; + } else + { + LocalMinima tmpLm = m_MinimaList; + while( tmpLm.Next != null && ( newLm.Y < tmpLm.Next.Y ) ) + tmpLm = tmpLm.Next; + newLm.Next = tmpLm.Next; + tmpLm.Next = newLm; + } + } + //------------------------------------------------------------------------------ + + protected void PopLocalMinima() + { + if (m_CurrentLM == null) return; + m_CurrentLM = m_CurrentLM.Next; + } + //------------------------------------------------------------------------------ + + private void ReverseHorizontal(TEdge e) + { + //swap horizontal edges' top and bottom x's so they follow the natural + //progression of the bounds - ie so their xbots will align with the + //adjoining lower edge. [Helpful in the ProcessHorizontal() method.] + cInt tmp = e.Top.X; + e.Top.X = e.Bot.X; + e.Bot.X = tmp; +#if use_xyz + tmp = e.Top.Z; + e.Top.Z = e.Bot.Z; + e.Bot.Z = tmp; +#endif + } + //------------------------------------------------------------------------------ + + protected virtual void Reset() + { + m_CurrentLM = m_MinimaList; + if (m_CurrentLM == null) return; //ie nothing to process + + //reset all edges ... + LocalMinima lm = m_MinimaList; + while (lm != null) + { + TEdge e = lm.LeftBound; + if (e != null) { - if (pt.Y > hiRange) - throw new ClipperException("Coordinate exceeds range bounds"); - else maxrange = hiRange; + e.Curr = e.Bot; + e.Side = EdgeSide.esLeft; + if (e.OutIdx != Skip) + e.OutIdx = Unassigned; } - } - //------------------------------------------------------------------------------ - - public bool AddPolygon(Polygon pg, PolyType polyType) - { - int len = pg.Count; - if (len < 3) return false; - Int64 maxVal; - if (m_UseFullRange) maxVal = hiRange; else maxVal = loRange; - RangeTest(pg[0], ref maxVal); - - Polygon p = new Polygon(len); - p.Add(new IntPoint(pg[0].X, pg[0].Y)); - int j = 0; - for (int i = 1; i < len; ++i) - { - RangeTest(pg[i], ref maxVal); - if (PointsEqual(p[j], pg[i])) continue; - else if (j > 0 && SlopesEqual(p[j-1], p[j], pg[i], maxVal == hiRange)) - { - if (PointsEqual(p[j-1], pg[i])) j--; - } else j++; - if (j < p.Count) - p[j] = pg[i]; else - p.Add(new IntPoint(pg[i].X, pg[i].Y)); - } - if (j < 2) return false; - m_UseFullRange = maxVal == hiRange; - - len = j+1; - while (len > 2) - { - //nb: test for point equality before testing slopes ... - if (PointsEqual(p[j], p[0])) j--; - else if (PointsEqual(p[0], p[1]) || SlopesEqual(p[j], p[0], p[1], m_UseFullRange)) - p[0] = p[j--]; - else if (SlopesEqual(p[j - 1], p[j], p[0], m_UseFullRange)) j--; - else if (SlopesEqual(p[0], p[1], p[2], m_UseFullRange)) - { - for (int i = 2; i <= j; ++i) p[i - 1] = p[i]; - j--; - } - else break; - len--; - } - if (len < 3) return false; - - //create a new edge array ... - List edges = new List(len); - for (int i = 0; i < len; i++) edges.Add(new TEdge()); - m_edges.Add(edges); - - //convert vertices to a double-linked-list of edges and initialize ... - edges[0].xcurr = p[0].X; - edges[0].ycurr = p[0].Y; - InitEdge(edges[len-1], edges[0], edges[len-2], p[len-1], polyType); - for (int i = len-2; i > 0; --i) - InitEdge(edges[i], edges[i+1], edges[i-1], p[i], polyType); - InitEdge(edges[0], edges[1], edges[len-1], p[0], polyType); - - //reset xcurr & ycurr and find 'eHighest' (given the Y axis coordinates - //increase downward so the 'highest' edge will have the smallest ytop) ... - TEdge e = edges[0]; - TEdge eHighest = e; - do - { - e.xcurr = e.xbot; - e.ycurr = e.ybot; - if (e.ytop < eHighest.ytop) eHighest = e; - e = e.next; - } - while ( e != edges[0]); - - //make sure eHighest is positioned so the following loop works safely ... - if (eHighest.windDelta > 0) eHighest = eHighest.next; - if (eHighest.dx == horizontal) eHighest = eHighest.next; + e = lm.RightBound; + e.Curr = e.Bot; + e.Side = EdgeSide.esRight; + if (e.OutIdx != Skip) + e.OutIdx = Unassigned; - //finally insert each local minima ... - e = eHighest; - do { - e = AddBoundsToLML(e); - } - while( e != eHighest ); - return true; + lm = lm.Next; } - //------------------------------------------------------------------------------ + } + //------------------------------------------------------------------------------ - private void InitEdge(TEdge e, TEdge eNext, - TEdge ePrev, IntPoint pt, PolyType polyType) - { - e.next = eNext; - e.prev = ePrev; - e.xcurr = pt.X; - e.ycurr = pt.Y; - if (e.ycurr >= e.next.ycurr) - { - e.xbot = e.xcurr; - e.ybot = e.ycurr; - e.xtop = e.next.xcurr; - e.ytop = e.next.ycurr; - e.windDelta = 1; - } else + public IntRect GetBounds() + { + IntRect result = new IntRect(); + LocalMinima lm = m_MinimaList; + if (lm == null) return result; + result.left = lm.LeftBound.Bot.X; + result.top = lm.LeftBound.Bot.Y; + result.right = lm.LeftBound.Bot.X; + result.bottom = lm.LeftBound.Bot.Y; + while (lm != null) { - e.xtop = e.xcurr; - e.ytop = e.ycurr; - e.xbot = e.next.xcurr; - e.ybot = e.next.ycurr; - e.windDelta = -1; + if (lm.LeftBound.Bot.Y > result.bottom) + result.bottom = lm.LeftBound.Bot.Y; + TEdge e = lm.LeftBound; + for (; ; ) + { + TEdge bottomE = e; + while (e.NextInLML != null) + { + if (e.Bot.X < result.left) result.left = e.Bot.X; + if (e.Bot.X > result.right) result.right = e.Bot.X; + e = e.NextInLML; + } + if (e.Bot.X < result.left) result.left = e.Bot.X; + if (e.Bot.X > result.right) result.right = e.Bot.X; + if (e.Top.X < result.left) result.left = e.Top.X; + if (e.Top.X > result.right) result.right = e.Top.X; + if (e.Top.Y < result.top) result.top = e.Top.Y; + + if (bottomE == lm.LeftBound) e = lm.RightBound; + else break; + } + lm = lm.Next; } - SetDx(e); - e.polyType = polyType; - e.outIdx = -1; - } - //------------------------------------------------------------------------------ - - private void SetDx(TEdge e) + return result; + } + + } //end ClipperBase + + public class Clipper : ClipperBase + { + //InitOptions that can be passed to the constructor ... + public const int ioReverseSolution = 1; + public const int ioStrictlySimple = 2; + public const int ioPreserveCollinear = 4; + + private List m_PolyOuts; + private ClipType m_ClipType; + private Scanbeam m_Scanbeam; + private TEdge m_ActiveEdges; + private TEdge m_SortedEdges; + private IntersectNode m_IntersectNodes; + private bool m_ExecuteLocked; + private PolyFillType m_ClipFillType; + private PolyFillType m_SubjFillType; + private List m_Joins; + private List m_GhostJoins; + private bool m_UsingPolyTree; +#if use_xyz + public delegate void TZFillCallback(IntPoint vert1, IntPoint vert2, ref IntPoint intersectPt); + public TZFillCallback ZFillFunction { get; set; } +#endif + public Clipper(int InitOptions = 0): base() //constructor + { + m_Scanbeam = null; + m_ActiveEdges = null; + m_SortedEdges = null; + m_IntersectNodes = null; + m_ExecuteLocked = false; + m_UsingPolyTree = false; + m_PolyOuts = new List(); + m_Joins = new List(); + m_GhostJoins = new List(); + ReverseSolution = (ioReverseSolution & InitOptions) != 0; + StrictlySimple = (ioStrictlySimple & InitOptions) != 0; + PreserveCollinear = (ioPreserveCollinear & InitOptions) != 0; +#if use_xyz + ZFillFunction = null; +#endif + } + //------------------------------------------------------------------------------ + + public override void Clear() + { + if (m_edges.Count == 0) return; //avoids problems with ClipperBase destructor + DisposeAllPolyPts(); + base.Clear(); + } + //------------------------------------------------------------------------------ + + void DisposeScanbeamList() + { + while ( m_Scanbeam != null ) { + Scanbeam sb2 = m_Scanbeam.Next; + m_Scanbeam = null; + m_Scanbeam = sb2; + } + } + //------------------------------------------------------------------------------ + + protected override void Reset() + { + base.Reset(); + m_Scanbeam = null; + m_ActiveEdges = null; + m_SortedEdges = null; + DisposeAllPolyPts(); + LocalMinima lm = m_MinimaList; + while (lm != null) + { + InsertScanbeam(lm.Y); + lm = lm.Next; + } + } + //------------------------------------------------------------------------------ + + public bool ReverseSolution + { + get; + set; + } + //------------------------------------------------------------------------------ + + public bool StrictlySimple + { + get; + set; + } + //------------------------------------------------------------------------------ + + private void InsertScanbeam(cInt Y) + { + if( m_Scanbeam == null ) { - e.deltaX = (e.xtop - e.xbot); - e.deltaY = (e.ytop - e.ybot); - if (e.deltaY == 0) e.dx = horizontal; - else e.dx = (double)(e.deltaX) / (e.deltaY); + m_Scanbeam = new Scanbeam(); + m_Scanbeam.Next = null; + m_Scanbeam.Y = Y; } - //--------------------------------------------------------------------------- - - TEdge AddBoundsToLML(TEdge e) + else if( Y > m_Scanbeam.Y ) { - //Starting at the top of one bound we progress to the bottom where there's - //a local minima. We then go to the top of the next bound. These two bounds - //form the left and right (or right and left) bounds of the local minima. - e.nextInLML = null; - e = e.next; - for (;;) + Scanbeam newSb = new Scanbeam(); + newSb.Y = Y; + newSb.Next = m_Scanbeam; + m_Scanbeam = newSb; + } else + { + Scanbeam sb2 = m_Scanbeam; + while( sb2.Next != null && ( Y <= sb2.Next.Y ) ) sb2 = sb2.Next; + if( Y == sb2.Y ) return; //ie ignores duplicates + Scanbeam newSb = new Scanbeam(); + newSb.Y = Y; + newSb.Next = sb2.Next; + sb2.Next = newSb; + } + } + //------------------------------------------------------------------------------ + + public bool Execute(ClipType clipType, Paths solution, + PolyFillType subjFillType, PolyFillType clipFillType) + { + if (m_ExecuteLocked) return false; + if (m_HasOpenPaths) throw + new ClipperException("Error: PolyTree struct is need for open path clipping."); + + m_ExecuteLocked = true; + solution.Clear(); + m_SubjFillType = subjFillType; + m_ClipFillType = clipFillType; + m_ClipType = clipType; + m_UsingPolyTree = false; + bool succeeded = ExecuteInternal(); + //build the return polygons ... + if (succeeded) BuildResult(solution); + m_ExecuteLocked = false; + return succeeded; + } + //------------------------------------------------------------------------------ + + public bool Execute(ClipType clipType, PolyTree polytree, + PolyFillType subjFillType, PolyFillType clipFillType) + { + if (m_ExecuteLocked) return false; + m_ExecuteLocked = true; + m_SubjFillType = subjFillType; + m_ClipFillType = clipFillType; + m_ClipType = clipType; + m_UsingPolyTree = true; + bool succeeded = ExecuteInternal(); + //build the return polygons ... + if (succeeded) BuildResult2(polytree); + m_ExecuteLocked = false; + return succeeded; + } + //------------------------------------------------------------------------------ + + public bool Execute(ClipType clipType, Paths solution) + { + return Execute(clipType, solution, + PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); + } + //------------------------------------------------------------------------------ + + public bool Execute(ClipType clipType, PolyTree polytree) + { + return Execute(clipType, polytree, + PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); + } + //------------------------------------------------------------------------------ + + internal void FixHoleLinkage(OutRec outRec) + { + //skip if an outermost polygon or + //already already points to the correct FirstLeft ... + if (outRec.FirstLeft == null || + (outRec.IsHole != outRec.FirstLeft.IsHole && + outRec.FirstLeft.Pts != null)) return; + + OutRec orfl = outRec.FirstLeft; + while (orfl != null && ((orfl.IsHole == outRec.IsHole) || orfl.Pts == null)) + orfl = orfl.FirstLeft; + outRec.FirstLeft = orfl; + } + //------------------------------------------------------------------------------ + + private bool ExecuteInternal() + { + try + { + Reset(); + if (m_CurrentLM == null) return false; + + cInt botY = PopScanbeam(); + do { - if ( e.dx == horizontal ) - { - //nb: proceed through horizontals when approaching from their right, - // but break on horizontal minima if approaching from their left. - // This ensures 'local minima' are always on the left of horizontals. - if (e.next.ytop < e.ytop && e.next.xbot > e.prev.xbot) break; - if (e.xtop != e.prev.xbot) SwapX(e); - e.nextInLML = e.prev; - } - else if (e.ycurr == e.prev.ycurr) break; - else e.nextInLML = e.prev; - e = e.next; + InsertLocalMinimaIntoAEL(botY); + m_GhostJoins.Clear(); + ProcessHorizontals(false); + if (m_Scanbeam == null) break; + cInt topY = PopScanbeam(); + if (!ProcessIntersections(botY, topY)) return false; + ProcessEdgesAtTopOfScanbeam(topY); + botY = topY; + } while (m_Scanbeam != null || m_CurrentLM != null); + + //fix orientations ... + for (int i = 0; i < m_PolyOuts.Count; i++) + { + OutRec outRec = m_PolyOuts[i]; + if (outRec.Pts == null || outRec.IsOpen) continue; + if ((outRec.IsHole ^ ReverseSolution) == (Area(outRec) > 0)) + ReversePolyPtLinks(outRec.Pts); } - //e and e.prev are now at a local minima ... - LocalMinima newLm = new LocalMinima(); - newLm.next = null; - newLm.Y = e.prev.ybot; + JoinCommonEdges(); - if ( e.dx == horizontal ) //horizontal edges never start a left bound - { - if (e.xbot != e.prev.xbot) SwapX(e); - newLm.leftBound = e.prev; - newLm.rightBound = e; - } else if (e.dx < e.prev.dx) + for (int i = 0; i < m_PolyOuts.Count; i++) { - newLm.leftBound = e.prev; - newLm.rightBound = e; - } else - { - newLm.leftBound = e; - newLm.rightBound = e.prev; + OutRec outRec = m_PolyOuts[i]; + if (outRec.Pts != null && !outRec.IsOpen) + FixupOutPolygon(outRec); } - newLm.leftBound.side = EdgeSide.esLeft; - newLm.rightBound.side = EdgeSide.esRight; - InsertLocalMinima( newLm ); - for (;;) + if (StrictlySimple) DoSimplePolygons(); + return true; + } + //catch { return false; } + finally + { + m_Joins.Clear(); + m_GhostJoins.Clear(); + } + } + //------------------------------------------------------------------------------ + + private cInt PopScanbeam() + { + cInt Y = m_Scanbeam.Y; + Scanbeam sb2 = m_Scanbeam; + m_Scanbeam = m_Scanbeam.Next; + sb2 = null; + return Y; + } + //------------------------------------------------------------------------------ + + private void DisposeAllPolyPts(){ + for (int i = 0; i < m_PolyOuts.Count; ++i) DisposeOutRec(i); + m_PolyOuts.Clear(); + } + //------------------------------------------------------------------------------ + + void DisposeOutRec(int index) + { + OutRec outRec = m_PolyOuts[index]; + if (outRec.Pts != null) DisposeOutPts(outRec.Pts); + outRec = null; + m_PolyOuts[index] = null; + } + //------------------------------------------------------------------------------ + + private void DisposeOutPts(OutPt pp) + { + if (pp == null) return; + OutPt tmpPp = null; + pp.Prev.Next = null; + while (pp != null) { - if ( e.next.ytop == e.ytop && e.next.dx != horizontal ) break; - e.nextInLML = e.next; - e = e.next; - if ( e.dx == horizontal && e.xbot != e.prev.xtop) SwapX(e); + tmpPp = pp; + pp = pp.Next; + tmpPp = null; } - return e.next; + } + //------------------------------------------------------------------------------ + + private void AddJoin(OutPt Op1, OutPt Op2, IntPoint OffPt) + { + Join j = new Join(); + j.OutPt1 = Op1; + j.OutPt2 = Op2; + j.OffPt = OffPt; + m_Joins.Add(j); + } + //------------------------------------------------------------------------------ + + private void AddGhostJoin(OutPt Op, IntPoint OffPt) + { + Join j = new Join(); + j.OutPt1 = Op; + j.OffPt = OffPt; + m_GhostJoins.Add(j); + } + //------------------------------------------------------------------------------ + +#if use_xyz + internal void SetZ(ref IntPoint pt, TEdge e) + { + pt.Z = 0; + if (ZFillFunction != null) + { + //put the 'preferred' point as first parameter ... + if (e.OutIdx < 0) + ZFillFunction(e.Bot, e.Top, ref pt); //outside a path so presume entering + else + ZFillFunction(e.Top, e.Bot, ref pt); //inside a path so presume exiting } - //------------------------------------------------------------------------------ + } + //------------------------------------------------------------------------------ +#endif - private void InsertLocalMinima(LocalMinima newLm) + private void InsertLocalMinimaIntoAEL(cInt botY) + { + while( m_CurrentLM != null && ( m_CurrentLM.Y == botY ) ) { - if( m_MinimaList == null ) + TEdge lb = m_CurrentLM.LeftBound; + TEdge rb = m_CurrentLM.RightBound; + PopLocalMinima(); + + OutPt Op1 = null; + if (lb == null) { - m_MinimaList = newLm; + InsertEdgeIntoAEL(rb, null); + SetWindingCount(rb); + if (IsContributing(rb)) + Op1 = AddOutPt(rb, rb.Bot); } - else if( newLm.Y >= m_MinimaList.Y ) - { - newLm.next = m_MinimaList; - m_MinimaList = newLm; - } else + else { - LocalMinima tmpLm = m_MinimaList; - while( tmpLm.next != null && ( newLm.Y < tmpLm.next.Y ) ) - tmpLm = tmpLm.next; - newLm.next = tmpLm.next; - tmpLm.next = newLm; - } - } - //------------------------------------------------------------------------------ + InsertEdgeIntoAEL(lb, null); + InsertEdgeIntoAEL(rb, lb); + SetWindingCount(lb); + rb.WindCnt = lb.WindCnt; + rb.WindCnt2 = lb.WindCnt2; + if (IsContributing(lb)) + Op1 = AddLocalMinPoly(lb, rb, lb.Bot); - protected void PopLocalMinima() - { - if (m_CurrentLM == null) return; - m_CurrentLM = m_CurrentLM.next; - } - //------------------------------------------------------------------------------ + InsertScanbeam(lb.Top.Y); + } - private void SwapX(TEdge e) - { - //swap horizontal edges' top and bottom x's so they follow the natural - //progression of the bounds - ie so their xbots will align with the - //adjoining lower edge. [Helpful in the ProcessHorizontal() method.] - e.xcurr = e.xtop; - e.xtop = e.xbot; - e.xbot = e.xcurr; - } - //------------------------------------------------------------------------------ + if (IsHorizontal(rb)) + AddEdgeToSEL(rb); + else + InsertScanbeam( rb.Top.Y ); - protected virtual void Reset() - { - m_CurrentLM = m_MinimaList; + if (lb == null) continue; - //reset all edges ... - LocalMinima lm = m_MinimaList; - while (lm != null) + //if output polygons share an Edge with a horizontal rb, they'll need joining later ... + if (Op1 != null && IsHorizontal(rb) && + m_GhostJoins.Count > 0 && rb.WindDelta != 0) + { + for (int i = 0; i < m_GhostJoins.Count; i++) { - TEdge e = lm.leftBound; - while (e != null) - { - e.xcurr = e.xbot; - e.ycurr = e.ybot; - e.side = EdgeSide.esLeft; - e.outIdx = -1; - e = e.nextInLML; - } - e = lm.rightBound; - while (e != null) - { - e.xcurr = e.xbot; - e.ycurr = e.ybot; - e.side = EdgeSide.esRight; - e.outIdx = -1; - e = e.nextInLML; - } - lm = lm.next; + //if the horizontal Rb and a 'ghost' horizontal overlap, then convert + //the 'ghost' join to a real join ready for later ... + Join j = m_GhostJoins[i]; + if (HorzSegmentsOverlap(j.OutPt1.Pt, j.OffPt, rb.Bot, rb.Top)) + AddJoin(j.OutPt1, Op1, j.OffPt); } - return; - } - //------------------------------------------------------------------------------ + } - public IntRect GetBounds() - { - IntRect result = new IntRect(); - LocalMinima lm = m_MinimaList; - if (lm == null) return result; - result.left = lm.leftBound.xbot; - result.top = lm.leftBound.ybot; - result.right = lm.leftBound.xbot; - result.bottom = lm.leftBound.ybot; - while (lm != null) + if (lb.OutIdx >= 0 && lb.PrevInAEL != null && + lb.PrevInAEL.Curr.X == lb.Bot.X && + lb.PrevInAEL.OutIdx >= 0 && + SlopesEqual(lb.PrevInAEL, lb, m_UseFullRange) && + lb.WindDelta != 0 && lb.PrevInAEL.WindDelta != 0) + { + OutPt Op2 = AddOutPt(lb.PrevInAEL, lb.Bot); + AddJoin(Op1, Op2, lb.Top); + } + + if( lb.NextInAEL != rb ) + { + + if (rb.OutIdx >= 0 && rb.PrevInAEL.OutIdx >= 0 && + SlopesEqual(rb.PrevInAEL, rb, m_UseFullRange) && + rb.WindDelta != 0 && rb.PrevInAEL.WindDelta != 0) { - if (lm.leftBound.ybot > result.bottom) - result.bottom = lm.leftBound.ybot; - TEdge e = lm.leftBound; - for (; ; ) - { - TEdge bottomE = e; - while (e.nextInLML != null) - { - if (e.xbot < result.left) result.left = e.xbot; - if (e.xbot > result.right) result.right = e.xbot; - e = e.nextInLML; - } - if (e.xbot < result.left) result.left = e.xbot; - if (e.xbot > result.right) result.right = e.xbot; - if (e.xtop < result.left) result.left = e.xtop; - if (e.xtop > result.right) result.right = e.xtop; - if (e.ytop < result.top) result.top = e.ytop; - - if (bottomE == lm.leftBound) e = lm.rightBound; - else break; - } - lm = lm.next; + OutPt Op2 = AddOutPt(rb.PrevInAEL, rb.Bot); + AddJoin(Op1, Op2, rb.Top); } - return result; - } - - } //ClipperBase - public class Clipper : ClipperBase - { - private List m_PolyOuts; - private ClipType m_ClipType; - private Scanbeam m_Scanbeam; - private TEdge m_ActiveEdges; - private TEdge m_SortedEdges; - private IntersectNode m_IntersectNodes; - private bool m_ExecuteLocked; - private PolyFillType m_ClipFillType; - private PolyFillType m_SubjFillType; - private List m_Joins; - private List m_HorizJoins; - private bool m_ReverseOutput; - private bool m_ForceSimple; - private bool m_UsingPolyTree; - - public Clipper() - { - m_Scanbeam = null; - m_ActiveEdges = null; - m_SortedEdges = null; - m_IntersectNodes = null; - m_ExecuteLocked = false; - m_UsingPolyTree = false; - m_PolyOuts = new List(); - m_Joins = new List(); - m_HorizJoins = new List(); - m_ReverseOutput = false; - m_ForceSimple = false; - } - //------------------------------------------------------------------------------ - - //destructor - commented out since I gather this impedes the GC - //~Clipper() //destructor - //{ - // Clear(); - // DisposeScanbeamList(); - //} - //------------------------------------------------------------------------------ - - public override void Clear() - { - if (m_edges.Count == 0) return; //avoids problems with ClipperBase destructor - DisposeAllPolyPts(); - base.Clear(); - } - //------------------------------------------------------------------------------ - - void DisposeScanbeamList() - { - while ( m_Scanbeam != null ) { - Scanbeam sb2 = m_Scanbeam.next; - m_Scanbeam = null; - m_Scanbeam = sb2; + TEdge e = lb.NextInAEL; + if (e != null) + while (e != rb) + { + //nb: For calculating winding counts etc, IntersectEdges() assumes + //that param1 will be to the right of param2 ABOVE the intersection ... + IntersectEdges(rb, e, lb.Curr); //order important here + e = e.NextInAEL; + } } } - //------------------------------------------------------------------------------ + } + //------------------------------------------------------------------------------ - protected override void Reset() + private void InsertEdgeIntoAEL(TEdge edge, TEdge startEdge) + { + if (m_ActiveEdges == null) { - base.Reset(); - m_Scanbeam = null; - m_ActiveEdges = null; - m_SortedEdges = null; - DisposeAllPolyPts(); - LocalMinima lm = m_MinimaList; - while (lm != null) - { - InsertScanbeam(lm.Y); - lm = lm.next; - } + edge.PrevInAEL = null; + edge.NextInAEL = null; + m_ActiveEdges = edge; } - //------------------------------------------------------------------------------ - - public bool ReverseSolution + else if (startEdge == null && E2InsertsBeforeE1(m_ActiveEdges, edge)) { - get { return m_ReverseOutput; } - set { m_ReverseOutput = value; } + edge.PrevInAEL = null; + edge.NextInAEL = m_ActiveEdges; + m_ActiveEdges.PrevInAEL = edge; + m_ActiveEdges = edge; } - //------------------------------------------------------------------------------ - - public bool ForceSimple + else { - get { return m_ForceSimple; } - set { m_ForceSimple = value; } + if (startEdge == null) startEdge = m_ActiveEdges; + while (startEdge.NextInAEL != null && + !E2InsertsBeforeE1(startEdge.NextInAEL, edge)) + startEdge = startEdge.NextInAEL; + edge.NextInAEL = startEdge.NextInAEL; + if (startEdge.NextInAEL != null) startEdge.NextInAEL.PrevInAEL = edge; + edge.PrevInAEL = startEdge; + startEdge.NextInAEL = edge; } - //------------------------------------------------------------------------------ - - private void InsertScanbeam(Int64 Y) - { - if( m_Scanbeam == null ) + } + //---------------------------------------------------------------------- + + private bool E2InsertsBeforeE1(TEdge e1, TEdge e2) + { + if (e2.Curr.X == e1.Curr.X) { - m_Scanbeam = new Scanbeam(); - m_Scanbeam.next = null; - m_Scanbeam.Y = Y; + if (e2.Top.Y > e1.Top.Y) + return e2.Top.X < TopX(e1, e2.Top.Y); + else return e1.Top.X > TopX(e2, e1.Top.Y); } - else if( Y > m_Scanbeam.Y ) + else return e2.Curr.X < e1.Curr.X; + } + //------------------------------------------------------------------------------ + + private bool IsEvenOddFillType(TEdge edge) + { + if (edge.PolyTyp == PolyType.ptSubject) + return m_SubjFillType == PolyFillType.pftEvenOdd; + else + return m_ClipFillType == PolyFillType.pftEvenOdd; + } + //------------------------------------------------------------------------------ + + private bool IsEvenOddAltFillType(TEdge edge) + { + if (edge.PolyTyp == PolyType.ptSubject) + return m_ClipFillType == PolyFillType.pftEvenOdd; + else + return m_SubjFillType == PolyFillType.pftEvenOdd; + } + //------------------------------------------------------------------------------ + + private bool IsContributing(TEdge edge) + { + PolyFillType pft, pft2; + if (edge.PolyTyp == PolyType.ptSubject) { - Scanbeam newSb = new Scanbeam(); - newSb.Y = Y; - newSb.next = m_Scanbeam; - m_Scanbeam = newSb; - } else + pft = m_SubjFillType; + pft2 = m_ClipFillType; + } + else { - Scanbeam sb2 = m_Scanbeam; - while( sb2.next != null && ( Y <= sb2.next.Y ) ) sb2 = sb2.next; - if( Y == sb2.Y ) return; //ie ignores duplicates - Scanbeam newSb = new Scanbeam(); - newSb.Y = Y; - newSb.next = sb2.next; - sb2.next = newSb; + pft = m_ClipFillType; + pft2 = m_SubjFillType; } - } - //------------------------------------------------------------------------------ - - public bool Execute(ClipType clipType, Polygons solution, - PolyFillType subjFillType, PolyFillType clipFillType) - { - if (m_ExecuteLocked) return false; - m_ExecuteLocked = true; - solution.Clear(); - m_SubjFillType = subjFillType; - m_ClipFillType = clipFillType; - m_ClipType = clipType; - m_UsingPolyTree = false; - bool succeeded = ExecuteInternal(); - //build the return polygons ... - if (succeeded) BuildResult(solution); - m_ExecuteLocked = false; - return succeeded; - } - //------------------------------------------------------------------------------ - - public bool Execute(ClipType clipType, PolyTree polytree, - PolyFillType subjFillType, PolyFillType clipFillType) - { - if (m_ExecuteLocked) return false; - m_ExecuteLocked = true; - m_SubjFillType = subjFillType; - m_ClipFillType = clipFillType; - m_ClipType = clipType; - m_UsingPolyTree = true; - bool succeeded = ExecuteInternal(); - //build the return polygons ... - if (succeeded) BuildResult2(polytree); - m_ExecuteLocked = false; - return succeeded; - } - //------------------------------------------------------------------------------ - - public bool Execute(ClipType clipType, Polygons solution) - { - return Execute(clipType, solution, - PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); - } - //------------------------------------------------------------------------------ - - public bool Execute(ClipType clipType, PolyTree polytree) - { - return Execute(clipType, polytree, - PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); - } - //------------------------------------------------------------------------------ - - internal void FixHoleLinkage(OutRec outRec) - { - //skip if an outermost polygon or - //already already points to the correct FirstLeft ... - if (outRec.FirstLeft == null || - (outRec.isHole != outRec.FirstLeft.isHole && - outRec.FirstLeft.pts != null)) return; - OutRec orfl = outRec.FirstLeft; - while (orfl != null && ((orfl.isHole == outRec.isHole) || orfl.pts == null)) - orfl = orfl.FirstLeft; - outRec.FirstLeft = orfl; - } - //------------------------------------------------------------------------------ + switch (pft) + { + case PolyFillType.pftEvenOdd: + //return false if a subj line has been flagged as inside a subj polygon + if (edge.WindDelta == 0 && edge.WindCnt != 1) return false; + break; + case PolyFillType.pftNonZero: + if (Math.Abs(edge.WindCnt) != 1) return false; + break; + case PolyFillType.pftPositive: + if (edge.WindCnt != 1) return false; + break; + default: //PolyFillType.pftNegative + if (edge.WindCnt != -1) return false; + break; + } - private bool ExecuteInternal() - { - bool succeeded; - try - { - Reset(); - if (m_CurrentLM == null) return true; - Int64 botY = PopScanbeam(); - do + switch (m_ClipType) + { + case ClipType.ctIntersection: + switch (pft2) { - InsertLocalMinimaIntoAEL(botY); - m_HorizJoins.Clear(); - ProcessHorizontals(); - Int64 topY = PopScanbeam(); - succeeded = ProcessIntersections(botY, topY); - if (!succeeded) break; - ProcessEdgesAtTopOfScanbeam(topY); - botY = topY; - } while (m_Scanbeam != null || m_CurrentLM != null); - } - catch { succeeded = false; } - - if (succeeded) - { - //tidy up output polygons and fix orientations where necessary ... - for (int i = 0; i < m_PolyOuts.Count; i++) + case PolyFillType.pftEvenOdd: + case PolyFillType.pftNonZero: + return (edge.WindCnt2 != 0); + case PolyFillType.pftPositive: + return (edge.WindCnt2 > 0); + default: + return (edge.WindCnt2 < 0); + } + case ClipType.ctUnion: + switch (pft2) { - OutRec outRec = m_PolyOuts[i]; - if (outRec.pts == null) continue; - FixupOutPolygon(outRec); - if (outRec.pts == null) continue; - if ((outRec.isHole ^ m_ReverseOutput) == (Area(outRec, m_UseFullRange) > 0)) - ReversePolyPtLinks(outRec.pts); + case PolyFillType.pftEvenOdd: + case PolyFillType.pftNonZero: + return (edge.WindCnt2 == 0); + case PolyFillType.pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); } - JoinCommonEdges(); - if (m_ForceSimple) DoSimplePolygons(); - } - m_Joins.Clear(); - m_HorizJoins.Clear(); - return succeeded; - } - //------------------------------------------------------------------------------ + case ClipType.ctDifference: + if (edge.PolyTyp == PolyType.ptSubject) + switch (pft2) + { + case PolyFillType.pftEvenOdd: + case PolyFillType.pftNonZero: + return (edge.WindCnt2 == 0); + case PolyFillType.pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + else + switch (pft2) + { + case PolyFillType.pftEvenOdd: + case PolyFillType.pftNonZero: + return (edge.WindCnt2 != 0); + case PolyFillType.pftPositive: + return (edge.WindCnt2 > 0); + default: + return (edge.WindCnt2 < 0); + } + case ClipType.ctXor: + if (edge.WindDelta == 0) //XOr always contributing unless open + switch (pft2) + { + case PolyFillType.pftEvenOdd: + case PolyFillType.pftNonZero: + return (edge.WindCnt2 == 0); + case PolyFillType.pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + else + return true; + } + return true; + } + //------------------------------------------------------------------------------ - private Int64 PopScanbeam() + private void SetWindingCount(TEdge edge) + { + TEdge e = edge.PrevInAEL; + //find the edge of the same polytype that immediately preceeds 'edge' in AEL + while (e != null && ((e.PolyTyp != edge.PolyTyp) || (e.WindDelta == 0))) e = e.PrevInAEL; + if (e == null) { - Int64 Y = m_Scanbeam.Y; - Scanbeam sb2 = m_Scanbeam; - m_Scanbeam = m_Scanbeam.next; - sb2 = null; - return Y; - } - //------------------------------------------------------------------------------ - - private void DisposeAllPolyPts(){ - for (int i = 0; i < m_PolyOuts.Count; ++i) DisposeOutRec(i); - m_PolyOuts.Clear(); + edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); + edge.WindCnt2 = 0; + e = m_ActiveEdges; //ie get ready to calc WindCnt2 } - //------------------------------------------------------------------------------ - - void DisposeOutRec(int index) + else if (edge.WindDelta == 0 && m_ClipType != ClipType.ctUnion) { - OutRec outRec = m_PolyOuts[index]; - if (outRec.pts != null) DisposeOutPts(outRec.pts); - outRec = null; - m_PolyOuts[index] = null; + edge.WindCnt = 1; + edge.WindCnt2 = e.WindCnt2; + e = e.NextInAEL; //ie get ready to calc WindCnt2 } - //------------------------------------------------------------------------------ - - private void DisposeOutPts(OutPt pp) + else if (IsEvenOddFillType(edge)) { - if (pp == null) return; - OutPt tmpPp = null; - pp.prev.next = null; - while (pp != null) + //EvenOdd filling ... + if (edge.WindDelta == 0) + { + //are we inside a subj polygon ... + bool Inside = true; + TEdge e2 = e.PrevInAEL; + while (e2 != null) { - tmpPp = pp; - pp = pp.next; - tmpPp = null; + if (e2.PolyTyp == e.PolyTyp && e2.WindDelta != 0) + Inside = !Inside; + e2 = e2.PrevInAEL; } + edge.WindCnt = (Inside ? 0 : 1); + } + else + { + edge.WindCnt = edge.WindDelta; + } + edge.WindCnt2 = e.WindCnt2; + e = e.NextInAEL; //ie get ready to calc WindCnt2 } - //------------------------------------------------------------------------------ - - private void AddJoin(TEdge e1, TEdge e2, int e1OutIdx, int e2OutIdx) + else { - JoinRec jr = new JoinRec(); - if (e1OutIdx >= 0) - jr.poly1Idx = e1OutIdx; else - jr.poly1Idx = e1.outIdx; - jr.pt1a = new IntPoint(e1.xcurr, e1.ycurr); - jr.pt1b = new IntPoint(e1.xtop, e1.ytop); - if (e2OutIdx >= 0) - jr.poly2Idx = e2OutIdx; else - jr.poly2Idx = e2.outIdx; - jr.pt2a = new IntPoint(e2.xcurr, e2.ycurr); - jr.pt2b = new IntPoint(e2.xtop, e2.ytop); - m_Joins.Add(jr); + //nonZero, Positive or Negative filling ... + if (e.WindCnt * e.WindDelta < 0) + { + //prev edge is 'decreasing' WindCount (WC) toward zero + //so we're outside the previous polygon ... + if (Math.Abs(e.WindCnt) > 1) + { + //outside prev poly but still inside another. + //when reversing direction of prev poly use the same WC + if (e.WindDelta * edge.WindDelta < 0) edge.WindCnt = e.WindCnt; + //otherwise continue to 'decrease' WC ... + else edge.WindCnt = e.WindCnt + edge.WindDelta; + } + else + //now outside all polys of same polytype so set own WC ... + edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); + } + else + { + //prev edge is 'increasing' WindCount (WC) away from zero + //so we're inside the previous polygon ... + if (edge.WindDelta == 0) + edge.WindCnt = (e.WindCnt < 0 ? e.WindCnt - 1 : e.WindCnt + 1); + //if wind direction is reversing prev then use same WC + else if (e.WindDelta * edge.WindDelta < 0) + edge.WindCnt = e.WindCnt; + //otherwise add to WC ... + else edge.WindCnt = e.WindCnt + edge.WindDelta; + } + edge.WindCnt2 = e.WindCnt2; + e = e.NextInAEL; //ie get ready to calc WindCnt2 } - //------------------------------------------------------------------------------ - private void AddHorzJoin(TEdge e, int idx) + //update WindCnt2 ... + if (IsEvenOddAltFillType(edge)) { - HorzJoinRec hj = new HorzJoinRec(); - hj.edge = e; - hj.savedIdx = idx; - m_HorizJoins.Add(hj); + //EvenOdd filling ... + while (e != edge) + { + if (e.WindDelta != 0) + edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0); + e = e.NextInAEL; + } } - //------------------------------------------------------------------------------ - - private void InsertLocalMinimaIntoAEL(Int64 botY) + else { - while( m_CurrentLM != null && ( m_CurrentLM.Y == botY ) ) + //nonZero, Positive or Negative filling ... + while (e != edge) { - TEdge lb = m_CurrentLM.leftBound; - TEdge rb = m_CurrentLM.rightBound; - - InsertEdgeIntoAEL( lb ); - InsertScanbeam( lb.ytop ); - InsertEdgeIntoAEL( rb ); - - if (IsEvenOddFillType(lb)) - { - lb.windDelta = 1; - rb.windDelta = 1; - } - else - { - rb.windDelta = -lb.windDelta; - } - SetWindingCount(lb); - rb.windCnt = lb.windCnt; - rb.windCnt2 = lb.windCnt2; + edge.WindCnt2 += e.WindDelta; + e = e.NextInAEL; + } + } + } + //------------------------------------------------------------------------------ - if( rb.dx == horizontal ) - { - //nb: only rightbounds can have a horizontal bottom edge - AddEdgeToSEL( rb ); - InsertScanbeam( rb.nextInLML.ytop ); - } - else - InsertScanbeam( rb.ytop ); + private void AddEdgeToSEL(TEdge edge) + { + //SEL pointers in PEdge are reused to build a list of horizontal edges. + //However, we don't need to worry about order with horizontal edge processing. + if (m_SortedEdges == null) + { + m_SortedEdges = edge; + edge.PrevInSEL = null; + edge.NextInSEL = null; + } + else + { + edge.NextInSEL = m_SortedEdges; + edge.PrevInSEL = null; + m_SortedEdges.PrevInSEL = edge; + m_SortedEdges = edge; + } + } + //------------------------------------------------------------------------------ - if( IsContributing(lb) ) - AddLocalMinPoly(lb, rb, new IntPoint(lb.xcurr, m_CurrentLM.Y)); + private void CopyAELToSEL() + { + TEdge e = m_ActiveEdges; + m_SortedEdges = e; + while (e != null) + { + e.PrevInSEL = e.PrevInAEL; + e.NextInSEL = e.NextInAEL; + e = e.NextInAEL; + } + } + //------------------------------------------------------------------------------ + + private void SwapPositionsInAEL(TEdge edge1, TEdge edge2) + { + //check that one or other edge hasn't already been removed from AEL ... + if (edge1.NextInAEL == edge1.PrevInAEL || + edge2.NextInAEL == edge2.PrevInAEL) return; + + if (edge1.NextInAEL == edge2) + { + TEdge next = edge2.NextInAEL; + if (next != null) + next.PrevInAEL = edge1; + TEdge prev = edge1.PrevInAEL; + if (prev != null) + prev.NextInAEL = edge2; + edge2.PrevInAEL = prev; + edge2.NextInAEL = edge1; + edge1.PrevInAEL = edge2; + edge1.NextInAEL = next; + } + else if (edge2.NextInAEL == edge1) + { + TEdge next = edge1.NextInAEL; + if (next != null) + next.PrevInAEL = edge2; + TEdge prev = edge2.PrevInAEL; + if (prev != null) + prev.NextInAEL = edge1; + edge1.PrevInAEL = prev; + edge1.NextInAEL = edge2; + edge2.PrevInAEL = edge1; + edge2.NextInAEL = next; + } + else + { + TEdge next = edge1.NextInAEL; + TEdge prev = edge1.PrevInAEL; + edge1.NextInAEL = edge2.NextInAEL; + if (edge1.NextInAEL != null) + edge1.NextInAEL.PrevInAEL = edge1; + edge1.PrevInAEL = edge2.PrevInAEL; + if (edge1.PrevInAEL != null) + edge1.PrevInAEL.NextInAEL = edge1; + edge2.NextInAEL = next; + if (edge2.NextInAEL != null) + edge2.NextInAEL.PrevInAEL = edge2; + edge2.PrevInAEL = prev; + if (edge2.PrevInAEL != null) + edge2.PrevInAEL.NextInAEL = edge2; + } - //if any output polygons share an edge, they'll need joining later ... - if (rb.outIdx >= 0 && rb.dx == horizontal) - { - for (int i = 0; i < m_HorizJoins.Count; i++) - { - IntPoint pt = new IntPoint(), pt2 = new IntPoint(); //used as dummy params. - HorzJoinRec hj = m_HorizJoins[i]; - //if horizontals rb and hj.edge overlap, flag for joining later ... - if (GetOverlapSegment(new IntPoint(hj.edge.xbot, hj.edge.ybot), - new IntPoint(hj.edge.xtop, hj.edge.ytop), - new IntPoint(rb.xbot, rb.ybot), - new IntPoint(rb.xtop, rb.ytop), - ref pt, ref pt2)) - AddJoin(hj.edge, rb, hj.savedIdx, -1); - } - } + if (edge1.PrevInAEL == null) + m_ActiveEdges = edge1; + else if (edge2.PrevInAEL == null) + m_ActiveEdges = edge2; + } + //------------------------------------------------------------------------------ + + private void SwapPositionsInSEL(TEdge edge1, TEdge edge2) + { + if (edge1.NextInSEL == null && edge1.PrevInSEL == null) + return; + if (edge2.NextInSEL == null && edge2.PrevInSEL == null) + return; + + if (edge1.NextInSEL == edge2) + { + TEdge next = edge2.NextInSEL; + if (next != null) + next.PrevInSEL = edge1; + TEdge prev = edge1.PrevInSEL; + if (prev != null) + prev.NextInSEL = edge2; + edge2.PrevInSEL = prev; + edge2.NextInSEL = edge1; + edge1.PrevInSEL = edge2; + edge1.NextInSEL = next; + } + else if (edge2.NextInSEL == edge1) + { + TEdge next = edge1.NextInSEL; + if (next != null) + next.PrevInSEL = edge2; + TEdge prev = edge2.PrevInSEL; + if (prev != null) + prev.NextInSEL = edge1; + edge1.PrevInSEL = prev; + edge1.NextInSEL = edge2; + edge2.PrevInSEL = edge1; + edge2.NextInSEL = next; + } + else + { + TEdge next = edge1.NextInSEL; + TEdge prev = edge1.PrevInSEL; + edge1.NextInSEL = edge2.NextInSEL; + if (edge1.NextInSEL != null) + edge1.NextInSEL.PrevInSEL = edge1; + edge1.PrevInSEL = edge2.PrevInSEL; + if (edge1.PrevInSEL != null) + edge1.PrevInSEL.NextInSEL = edge1; + edge2.NextInSEL = next; + if (edge2.NextInSEL != null) + edge2.NextInSEL.PrevInSEL = edge2; + edge2.PrevInSEL = prev; + if (edge2.PrevInSEL != null) + edge2.PrevInSEL.NextInSEL = edge2; + } + if (edge1.PrevInSEL == null) + m_SortedEdges = edge1; + else if (edge2.PrevInSEL == null) + m_SortedEdges = edge2; + } + //------------------------------------------------------------------------------ - if( lb.nextInAEL != rb ) - { - if (rb.outIdx >= 0 && rb.prevInAEL.outIdx >= 0 && - SlopesEqual(rb.prevInAEL, rb, m_UseFullRange)) - AddJoin(rb, rb.prevInAEL, -1, -1); - TEdge e = lb.nextInAEL; - IntPoint pt = new IntPoint(lb.xcurr, lb.ycurr); - while( e != rb ) + private void AddLocalMaxPoly(TEdge e1, TEdge e2, IntPoint pt) + { + AddOutPt(e1, pt); + if (e1.OutIdx == e2.OutIdx) + { + e1.OutIdx = Unassigned; + e2.OutIdx = Unassigned; + } + else if (e1.OutIdx < e2.OutIdx) + AppendPolygon(e1, e2); + else + AppendPolygon(e2, e1); + } + //------------------------------------------------------------------------------ + + private OutPt AddLocalMinPoly(TEdge e1, TEdge e2, IntPoint pt) + { + OutPt result; + TEdge e, prevE; + if (IsHorizontal(e2) || (e1.Dx > e2.Dx)) + { + result = AddOutPt(e1, pt); + e2.OutIdx = e1.OutIdx; + e1.Side = EdgeSide.esLeft; + e2.Side = EdgeSide.esRight; + e = e1; + if (e.PrevInAEL == e2) + prevE = e2.PrevInAEL; + else + prevE = e.PrevInAEL; + } + else + { + result = AddOutPt(e2, pt); + e1.OutIdx = e2.OutIdx; + e1.Side = EdgeSide.esRight; + e2.Side = EdgeSide.esLeft; + e = e2; + if (e.PrevInAEL == e1) + prevE = e1.PrevInAEL; + else + prevE = e.PrevInAEL; + } + + if (prevE != null && prevE.OutIdx >= 0 && + (TopX(prevE, pt.Y) == TopX(e, pt.Y)) && + SlopesEqual(e, prevE, m_UseFullRange) && + (e.WindDelta != 0) && (prevE.WindDelta != 0)) + { + OutPt outPt = AddOutPt(prevE, pt); + AddJoin(result, outPt, e.Top); + } + return result; + } + //------------------------------------------------------------------------------ + + private OutRec CreateOutRec() + { + OutRec result = new OutRec(); + result.Idx = Unassigned; + result.IsHole = false; + result.IsOpen = false; + result.FirstLeft = null; + result.Pts = null; + result.BottomPt = null; + result.PolyNode = null; + m_PolyOuts.Add(result); + result.Idx = m_PolyOuts.Count - 1; + return result; + } + //------------------------------------------------------------------------------ + + private OutPt AddOutPt(TEdge e, IntPoint pt) + { + bool ToFront = (e.Side == EdgeSide.esLeft); + if( e.OutIdx < 0 ) + { + OutRec outRec = CreateOutRec(); + outRec.IsOpen = (e.WindDelta == 0); + OutPt newOp = new OutPt(); + outRec.Pts = newOp; + newOp.Idx = outRec.Idx; + newOp.Pt = pt; + newOp.Next = newOp; + newOp.Prev = newOp; + if (!outRec.IsOpen) + SetHoleState(e, outRec); +#if use_xyz + if (pt == e.Bot) + newOp.Pt = e.Bot; + else if (pt == e.Top) + newOp.Pt = e.Top; + else + SetZ(ref newOp.Pt, e); +#endif + e.OutIdx = outRec.Idx; //nb: do this after SetZ ! + return newOp; + } else + { + OutRec outRec = m_PolyOuts[e.OutIdx]; + //OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most' + OutPt op = outRec.Pts; + if (ToFront && pt == op.Pt) return op; + else if (!ToFront && pt == op.Prev.Pt) return op.Prev; + + OutPt newOp = new OutPt(); + newOp.Idx = outRec.Idx; + newOp.Pt = pt; + newOp.Next = op; + newOp.Prev = op.Prev; + newOp.Prev.Next = newOp; + op.Prev = newOp; + if (ToFront) outRec.Pts = newOp; +#if use_xyz + if (pt == e.Bot) + newOp.Pt = e.Bot; + else if (pt == e.Top) + newOp.Pt = e.Top; + else + SetZ(ref newOp.Pt, e); +#endif + return newOp; + } + } + //------------------------------------------------------------------------------ + + internal void SwapPoints(ref IntPoint pt1, ref IntPoint pt2) + { + IntPoint tmp = new IntPoint(pt1); + pt1 = pt2; + pt2 = tmp; + } + //------------------------------------------------------------------------------ + + private bool HorzSegmentsOverlap( + IntPoint Pt1a, IntPoint Pt1b, IntPoint Pt2a, IntPoint Pt2b) + { + //precondition: both segments are horizontal + if ((Pt1a.X > Pt2a.X) == (Pt1a.X < Pt2b.X)) return true; + else if ((Pt1b.X > Pt2a.X) == (Pt1b.X < Pt2b.X)) return true; + else if ((Pt2a.X > Pt1a.X) == (Pt2a.X < Pt1b.X)) return true; + else if ((Pt2b.X > Pt1a.X) == (Pt2b.X < Pt1b.X)) return true; + else if ((Pt1a.X == Pt2a.X) && (Pt1b.X == Pt2b.X)) return true; + else if ((Pt1a.X == Pt2b.X) && (Pt1b.X == Pt2a.X)) return true; + else return false; + } + //------------------------------------------------------------------------------ + + private OutPt InsertPolyPtBetween(OutPt p1, OutPt p2, IntPoint pt) + { + OutPt result = new OutPt(); + result.Pt = pt; + if (p2 == p1.Next) + { + p1.Next = result; + p2.Prev = result; + result.Next = p2; + result.Prev = p1; + } else + { + p2.Next = result; + p1.Prev = result; + result.Next = p1; + result.Prev = p2; + } + return result; + } + //------------------------------------------------------------------------------ + + private void SetHoleState(TEdge e, OutRec outRec) + { + bool isHole = false; + TEdge e2 = e.PrevInAEL; + while (e2 != null) + { + if (e2.OutIdx >= 0) { - if(e == null) - throw new ClipperException("InsertLocalMinimaIntoAEL: missing rightbound!"); - //nb: For calculating winding counts etc, IntersectEdges() assumes - //that param1 will be to the right of param2 ABOVE the intersection ... - IntersectEdges( rb , e , pt , Protects.ipNone); //order important here - e = e.nextInAEL; + isHole = !isHole; + if (outRec.FirstLeft == null) + outRec.FirstLeft = m_PolyOuts[e2.OutIdx]; } + e2 = e2.PrevInAEL; + } + if (isHole) outRec.IsHole = true; + } + //------------------------------------------------------------------------------ + + private double GetDx(IntPoint pt1, IntPoint pt2) + { + if (pt1.Y == pt2.Y) return horizontal; + else return (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y); + } + //--------------------------------------------------------------------------- + + private bool FirstIsBottomPt(OutPt btmPt1, OutPt btmPt2) + { + OutPt p = btmPt1.Prev; + while ((p.Pt == btmPt1.Pt) && (p != btmPt1)) p = p.Prev; + double dx1p = Math.Abs(GetDx(btmPt1.Pt, p.Pt)); + p = btmPt1.Next; + while ((p.Pt == btmPt1.Pt) && (p != btmPt1)) p = p.Next; + double dx1n = Math.Abs(GetDx(btmPt1.Pt, p.Pt)); + + p = btmPt2.Prev; + while ((p.Pt == btmPt2.Pt) && (p != btmPt2)) p = p.Prev; + double dx2p = Math.Abs(GetDx(btmPt2.Pt, p.Pt)); + p = btmPt2.Next; + while ((p.Pt == btmPt2.Pt) && (p != btmPt2)) p = p.Next; + double dx2n = Math.Abs(GetDx(btmPt2.Pt, p.Pt)); + return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); + } + //------------------------------------------------------------------------------ + + private OutPt GetBottomPt(OutPt pp) + { + OutPt dups = null; + OutPt p = pp.Next; + while (p != pp) + { + if (p.Pt.Y > pp.Pt.Y) + { + pp = p; + dups = null; + } + else if (p.Pt.Y == pp.Pt.Y && p.Pt.X <= pp.Pt.X) + { + if (p.Pt.X < pp.Pt.X) + { + dups = null; + pp = p; + } else + { + if (p.Next != pp && p.Prev != pp) dups = p; } - PopLocalMinima(); } + p = p.Next; } - //------------------------------------------------------------------------------ - - private void InsertEdgeIntoAEL(TEdge edge) + if (dups != null) { - edge.prevInAEL = null; - edge.nextInAEL = null; - if (m_ActiveEdges == null) + //there appears to be at least 2 vertices at bottomPt so ... + while (dups != p) { - m_ActiveEdges = edge; + if (!FirstIsBottomPt(p, dups)) pp = dups; + dups = dups.Next; + while (dups.Pt != pp.Pt) dups = dups.Next; } - else if( E2InsertsBeforeE1(m_ActiveEdges, edge) ) + } + return pp; + } + //------------------------------------------------------------------------------ + + private OutRec GetLowermostRec(OutRec outRec1, OutRec outRec2) + { + //work out which polygon fragment has the correct hole state ... + if (outRec1.BottomPt == null) + outRec1.BottomPt = GetBottomPt(outRec1.Pts); + if (outRec2.BottomPt == null) + outRec2.BottomPt = GetBottomPt(outRec2.Pts); + OutPt bPt1 = outRec1.BottomPt; + OutPt bPt2 = outRec2.BottomPt; + if (bPt1.Pt.Y > bPt2.Pt.Y) return outRec1; + else if (bPt1.Pt.Y < bPt2.Pt.Y) return outRec2; + else if (bPt1.Pt.X < bPt2.Pt.X) return outRec1; + else if (bPt1.Pt.X > bPt2.Pt.X) return outRec2; + else if (bPt1.Next == bPt1) return outRec2; + else if (bPt2.Next == bPt2) return outRec1; + else if (FirstIsBottomPt(bPt1, bPt2)) return outRec1; + else return outRec2; + } + //------------------------------------------------------------------------------ + + bool Param1RightOfParam2(OutRec outRec1, OutRec outRec2) + { + do { - edge.nextInAEL = m_ActiveEdges; - m_ActiveEdges.prevInAEL = edge; - m_ActiveEdges = edge; + outRec1 = outRec1.FirstLeft; + if (outRec1 == outRec2) return true; + } while (outRec1 != null); + return false; + } + //------------------------------------------------------------------------------ + + private OutRec GetOutRec(int idx) + { + OutRec outrec = m_PolyOuts[idx]; + while (outrec != m_PolyOuts[outrec.Idx]) + outrec = m_PolyOuts[outrec.Idx]; + return outrec; + } + //------------------------------------------------------------------------------ + + private void AppendPolygon(TEdge e1, TEdge e2) + { + //get the start and ends of both output polygons ... + OutRec outRec1 = m_PolyOuts[e1.OutIdx]; + OutRec outRec2 = m_PolyOuts[e2.OutIdx]; + + OutRec holeStateRec; + if (Param1RightOfParam2(outRec1, outRec2)) + holeStateRec = outRec2; + else if (Param1RightOfParam2(outRec2, outRec1)) + holeStateRec = outRec1; + else + holeStateRec = GetLowermostRec(outRec1, outRec2); + + OutPt p1_lft = outRec1.Pts; + OutPt p1_rt = p1_lft.Prev; + OutPt p2_lft = outRec2.Pts; + OutPt p2_rt = p2_lft.Prev; + + EdgeSide side; + //join e2 poly onto e1 poly and delete pointers to e2 ... + if( e1.Side == EdgeSide.esLeft ) + { + if (e2.Side == EdgeSide.esLeft) + { + //z y x a b c + ReversePolyPtLinks(p2_lft); + p2_lft.Next = p1_lft; + p1_lft.Prev = p2_lft; + p1_rt.Next = p2_rt; + p2_rt.Prev = p1_rt; + outRec1.Pts = p2_rt; } else { - TEdge e = m_ActiveEdges; - while (e.nextInAEL != null && !E2InsertsBeforeE1(e.nextInAEL, edge)) - e = e.nextInAEL; - edge.nextInAEL = e.nextInAEL; - if (e.nextInAEL != null) e.nextInAEL.prevInAEL = edge; - edge.prevInAEL = e; - e.nextInAEL = edge; + //x y z a b c + p2_rt.Next = p1_lft; + p1_lft.Prev = p2_rt; + p2_lft.Prev = p1_rt; + p1_rt.Next = p2_lft; + outRec1.Pts = p2_lft; } - } - //---------------------------------------------------------------------- - - private bool E2InsertsBeforeE1(TEdge e1, TEdge e2) + side = EdgeSide.esLeft; + } else { - if (e2.xcurr == e1.xcurr) - { - if (e2.ytop > e1.ytop) - return e2.xtop < TopX(e1, e2.ytop); - else return e1.xtop > TopX(e2, e1.ytop); - } - else return e2.xcurr < e1.xcurr; + if (e2.Side == EdgeSide.esRight) + { + //a b c z y x + ReversePolyPtLinks( p2_lft ); + p1_rt.Next = p2_rt; + p2_rt.Prev = p1_rt; + p2_lft.Next = p1_lft; + p1_lft.Prev = p2_lft; + } else + { + //a b c x y z + p1_rt.Next = p2_lft; + p2_lft.Prev = p1_rt; + p1_lft.Prev = p2_rt; + p2_rt.Next = p1_lft; + } + side = EdgeSide.esRight; } - //------------------------------------------------------------------------------ - private bool IsEvenOddFillType(TEdge edge) + outRec1.BottomPt = null; + if (holeStateRec == outRec2) { - if (edge.polyType == PolyType.ptSubject) - return m_SubjFillType == PolyFillType.pftEvenOdd; - else - return m_ClipFillType == PolyFillType.pftEvenOdd; + if (outRec2.FirstLeft != outRec1) + outRec1.FirstLeft = outRec2.FirstLeft; + outRec1.IsHole = outRec2.IsHole; } - //------------------------------------------------------------------------------ + outRec2.Pts = null; + outRec2.BottomPt = null; - private bool IsEvenOddAltFillType(TEdge edge) - { - if (edge.polyType == PolyType.ptSubject) - return m_ClipFillType == PolyFillType.pftEvenOdd; - else - return m_SubjFillType == PolyFillType.pftEvenOdd; - } - //------------------------------------------------------------------------------ - - private bool IsContributing(TEdge edge) - { - PolyFillType pft, pft2; - if (edge.polyType == PolyType.ptSubject) - { - pft = m_SubjFillType; - pft2 = m_ClipFillType; - } - else - { - pft = m_ClipFillType; - pft2 = m_SubjFillType; - } + outRec2.FirstLeft = outRec1; - switch (pft) - { - case PolyFillType.pftEvenOdd: - case PolyFillType.pftNonZero: - if (Math.Abs(edge.windCnt) != 1) return false; - break; - case PolyFillType.pftPositive: - if (edge.windCnt != 1) return false; - break; - default: //PolyFillType.pftNegative - if (edge.windCnt != -1) return false; - break; - } + int OKIdx = e1.OutIdx; + int ObsoleteIdx = e2.OutIdx; - switch (m_ClipType) - { - case ClipType.ctIntersection: - switch (pft2) - { - case PolyFillType.pftEvenOdd: - case PolyFillType.pftNonZero: - return (edge.windCnt2 != 0); - case PolyFillType.pftPositive: - return (edge.windCnt2 > 0); - default: - return (edge.windCnt2 < 0); - } - case ClipType.ctUnion: - switch (pft2) - { - case PolyFillType.pftEvenOdd: - case PolyFillType.pftNonZero: - return (edge.windCnt2 == 0); - case PolyFillType.pftPositive: - return (edge.windCnt2 <= 0); - default: - return (edge.windCnt2 >= 0); - } - case ClipType.ctDifference: - if (edge.polyType == PolyType.ptSubject) - switch (pft2) - { - case PolyFillType.pftEvenOdd: - case PolyFillType.pftNonZero: - return (edge.windCnt2 == 0); - case PolyFillType.pftPositive: - return (edge.windCnt2 <= 0); - default: - return (edge.windCnt2 >= 0); - } - else - switch (pft2) - { - case PolyFillType.pftEvenOdd: - case PolyFillType.pftNonZero: - return (edge.windCnt2 != 0); - case PolyFillType.pftPositive: - return (edge.windCnt2 > 0); - default: - return (edge.windCnt2 < 0); - } - } - return true; - } - //------------------------------------------------------------------------------ + e1.OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly + e2.OutIdx = Unassigned; - private void SetWindingCount(TEdge edge) + TEdge e = m_ActiveEdges; + while( e != null ) { - TEdge e = edge.prevInAEL; - //find the edge of the same polytype that immediately preceeds 'edge' in AEL - while (e != null && e.polyType != edge.polyType) - e = e.prevInAEL; - if (e == null) - { - edge.windCnt = edge.windDelta; - edge.windCnt2 = 0; - e = m_ActiveEdges; //ie get ready to calc windCnt2 - } - else if (IsEvenOddFillType(edge)) + if( e.OutIdx == ObsoleteIdx ) + { + e.OutIdx = OKIdx; + e.Side = side; + break; + } + e = e.NextInAEL; + } + outRec2.Idx = outRec1.Idx; + } + //------------------------------------------------------------------------------ + + private void ReversePolyPtLinks(OutPt pp) + { + if (pp == null) return; + OutPt pp1; + OutPt pp2; + pp1 = pp; + do + { + pp2 = pp1.Next; + pp1.Next = pp1.Prev; + pp1.Prev = pp2; + pp1 = pp2; + } while (pp1 != pp); + } + //------------------------------------------------------------------------------ + + private static void SwapSides(TEdge edge1, TEdge edge2) + { + EdgeSide side = edge1.Side; + edge1.Side = edge2.Side; + edge2.Side = side; + } + //------------------------------------------------------------------------------ + + private static void SwapPolyIndexes(TEdge edge1, TEdge edge2) + { + int outIdx = edge1.OutIdx; + edge1.OutIdx = edge2.OutIdx; + edge2.OutIdx = outIdx; + } + //------------------------------------------------------------------------------ + + private void IntersectEdges(TEdge e1, TEdge e2, IntPoint pt, bool protect = false) + { + //e1 will be to the left of e2 BELOW the intersection. Therefore e1 is before + //e2 in AEL except when e1 is being inserted at the intersection point ... + + bool e1stops = !protect && e1.NextInLML == null && + e1.Top.X == pt.X && e1.Top.Y == pt.Y; + bool e2stops = !protect && e2.NextInLML == null && + e2.Top.X == pt.X && e2.Top.Y == pt.Y; + bool e1Contributing = (e1.OutIdx >= 0); + bool e2Contributing = (e2.OutIdx >= 0); + +#if use_lines + //if either edge is on an OPEN path ... + if (e1.WindDelta == 0 || e2.WindDelta == 0) + { + //ignore subject-subject open path intersections UNLESS they + //are both open paths, AND they are both 'contributing maximas' ... + if (e1.WindDelta == 0 && e2.WindDelta == 0) { - //even-odd filling ... - edge.windCnt = 1; - edge.windCnt2 = e.windCnt2; - e = e.nextInAEL; //ie get ready to calc windCnt2 + if ((e1stops || e2stops) && e1Contributing && e2Contributing) + AddLocalMaxPoly(e1, e2, pt); } - else + //if intersecting a subj line with a subj poly ... + else if (e1.PolyTyp == e2.PolyTyp && + e1.WindDelta != e2.WindDelta && m_ClipType == ClipType.ctUnion) { - //nonZero filling ... - if (e.windCnt * e.windDelta < 0) - { - if (Math.Abs(e.windCnt) > 1) - { - if (e.windDelta * edge.windDelta < 0) - edge.windCnt = e.windCnt; - else - edge.windCnt = e.windCnt + edge.windDelta; - } - else - edge.windCnt = e.windCnt + e.windDelta + edge.windDelta; - } - else + if (e1.WindDelta == 0) + { + if (e2Contributing) { - if (Math.Abs(e.windCnt) > 1 && e.windDelta * edge.windDelta < 0) - edge.windCnt = e.windCnt; - else if (e.windCnt + edge.windDelta == 0) - edge.windCnt = e.windCnt; - else - edge.windCnt = e.windCnt + edge.windDelta; + AddOutPt(e1, pt); + if (e1Contributing) e1.OutIdx = Unassigned; } - edge.windCnt2 = e.windCnt2; - e = e.nextInAEL; //ie get ready to calc windCnt2 - } - - //update windCnt2 ... - if (IsEvenOddAltFillType(edge)) - { - //even-odd filling ... - while (e != edge) + } + else + { + if (e1Contributing) { - edge.windCnt2 = (edge.windCnt2 == 0) ? 1 : 0; - e = e.nextInAEL; + AddOutPt(e2, pt); + if (e2Contributing) e2.OutIdx = Unassigned; } + } } - else + else if (e1.PolyTyp != e2.PolyTyp) { - //nonZero filling ... - while (e != edge) - { - edge.windCnt2 += e.windDelta; - e = e.nextInAEL; - } + if ((e1.WindDelta == 0) && Math.Abs(e2.WindCnt) == 1 && + (m_ClipType != ClipType.ctUnion || e2.WindCnt2 == 0)) + { + AddOutPt(e1, pt); + if (e1Contributing) e1.OutIdx = Unassigned; + } + else if ((e2.WindDelta == 0) && (Math.Abs(e1.WindCnt) == 1) && + (m_ClipType != ClipType.ctUnion || e1.WindCnt2 == 0)) + { + AddOutPt(e2, pt); + if (e2Contributing) e2.OutIdx = Unassigned; + } } - } - //------------------------------------------------------------------------------ - private void AddEdgeToSEL(TEdge edge) - { - //SEL pointers in PEdge are reused to build a list of horizontal edges. - //However, we don't need to worry about order with horizontal edge processing. - if (m_SortedEdges == null) - { - m_SortedEdges = edge; - edge.prevInSEL = null; - edge.nextInSEL = null; - } - else - { - edge.nextInSEL = m_SortedEdges; - edge.prevInSEL = null; - m_SortedEdges.prevInSEL = edge; - m_SortedEdges = edge; - } - } - //------------------------------------------------------------------------------ + if (e1stops) + if (e1.OutIdx < 0) DeleteFromAEL(e1); + else throw new ClipperException("Error intersecting polylines"); + if (e2stops) + if (e2.OutIdx < 0) DeleteFromAEL(e2); + else throw new ClipperException("Error intersecting polylines"); + return; + } +#endif - private void CopyAELToSEL() - { - TEdge e = m_ActiveEdges; - m_SortedEdges = e; - while (e != null) - { - e.prevInSEL = e.prevInAEL; - e.nextInSEL = e.nextInAEL; - e = e.nextInAEL; - } - } - //------------------------------------------------------------------------------ + //update winding counts... + //assumes that e1 will be to the Right of e2 ABOVE the intersection + if (e1.PolyTyp == e2.PolyTyp) + { + if (IsEvenOddFillType(e1)) + { + int oldE1WindCnt = e1.WindCnt; + e1.WindCnt = e2.WindCnt; + e2.WindCnt = oldE1WindCnt; + } + else + { + if (e1.WindCnt + e2.WindDelta == 0) e1.WindCnt = -e1.WindCnt; + else e1.WindCnt += e2.WindDelta; + if (e2.WindCnt - e1.WindDelta == 0) e2.WindCnt = -e2.WindCnt; + else e2.WindCnt -= e1.WindDelta; + } + } + else + { + if (!IsEvenOddFillType(e2)) e1.WindCnt2 += e2.WindDelta; + else e1.WindCnt2 = (e1.WindCnt2 == 0) ? 1 : 0; + if (!IsEvenOddFillType(e1)) e2.WindCnt2 -= e1.WindDelta; + else e2.WindCnt2 = (e2.WindCnt2 == 0) ? 1 : 0; + } - private void SwapPositionsInAEL(TEdge edge1, TEdge edge2) - { - if (edge1.nextInAEL == edge2) - { - TEdge next = edge2.nextInAEL; - if (next != null) - next.prevInAEL = edge1; - TEdge prev = edge1.prevInAEL; - if (prev != null) - prev.nextInAEL = edge2; - edge2.prevInAEL = prev; - edge2.nextInAEL = edge1; - edge1.prevInAEL = edge2; - edge1.nextInAEL = next; - } - else if (edge2.nextInAEL == edge1) - { - TEdge next = edge1.nextInAEL; - if (next != null) - next.prevInAEL = edge2; - TEdge prev = edge2.prevInAEL; - if (prev != null) - prev.nextInAEL = edge1; - edge1.prevInAEL = prev; - edge1.nextInAEL = edge2; - edge2.prevInAEL = edge1; - edge2.nextInAEL = next; - } - else - { - TEdge next = edge1.nextInAEL; - TEdge prev = edge1.prevInAEL; - edge1.nextInAEL = edge2.nextInAEL; - if (edge1.nextInAEL != null) - edge1.nextInAEL.prevInAEL = edge1; - edge1.prevInAEL = edge2.prevInAEL; - if (edge1.prevInAEL != null) - edge1.prevInAEL.nextInAEL = edge1; - edge2.nextInAEL = next; - if (edge2.nextInAEL != null) - edge2.nextInAEL.prevInAEL = edge2; - edge2.prevInAEL = prev; - if (edge2.prevInAEL != null) - edge2.prevInAEL.nextInAEL = edge2; - } + PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2; + if (e1.PolyTyp == PolyType.ptSubject) + { + e1FillType = m_SubjFillType; + e1FillType2 = m_ClipFillType; + } + else + { + e1FillType = m_ClipFillType; + e1FillType2 = m_SubjFillType; + } + if (e2.PolyTyp == PolyType.ptSubject) + { + e2FillType = m_SubjFillType; + e2FillType2 = m_ClipFillType; + } + else + { + e2FillType = m_ClipFillType; + e2FillType2 = m_SubjFillType; + } - if (edge1.prevInAEL == null) - m_ActiveEdges = edge1; - else if (edge2.prevInAEL == null) - m_ActiveEdges = edge2; - } - //------------------------------------------------------------------------------ + int e1Wc, e2Wc; + switch (e1FillType) + { + case PolyFillType.pftPositive: e1Wc = e1.WindCnt; break; + case PolyFillType.pftNegative: e1Wc = -e1.WindCnt; break; + default: e1Wc = Math.Abs(e1.WindCnt); break; + } + switch (e2FillType) + { + case PolyFillType.pftPositive: e2Wc = e2.WindCnt; break; + case PolyFillType.pftNegative: e2Wc = -e2.WindCnt; break; + default: e2Wc = Math.Abs(e2.WindCnt); break; + } - private void SwapPositionsInSEL(TEdge edge1, TEdge edge2) - { - if (edge1.nextInSEL == null && edge1.prevInSEL == null) - return; - if (edge2.nextInSEL == null && edge2.prevInSEL == null) - return; + if (e1Contributing && e2Contributing) + { + if ( e1stops || e2stops || + (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || + (e1.PolyTyp != e2.PolyTyp && m_ClipType != ClipType.ctXor)) + AddLocalMaxPoly(e1, e2, pt); + else + { + AddOutPt(e1, pt); + AddOutPt(e2, pt); + SwapSides(e1, e2); + SwapPolyIndexes(e1, e2); + } + } + else if (e1Contributing) + { + if (e2Wc == 0 || e2Wc == 1) + { + AddOutPt(e1, pt); + SwapSides(e1, e2); + SwapPolyIndexes(e1, e2); + } - if (edge1.nextInSEL == edge2) - { - TEdge next = edge2.nextInSEL; - if (next != null) - next.prevInSEL = edge1; - TEdge prev = edge1.prevInSEL; - if (prev != null) - prev.nextInSEL = edge2; - edge2.prevInSEL = prev; - edge2.nextInSEL = edge1; - edge1.prevInSEL = edge2; - edge1.nextInSEL = next; - } - else if (edge2.nextInSEL == edge1) - { - TEdge next = edge1.nextInSEL; - if (next != null) - next.prevInSEL = edge2; - TEdge prev = edge2.prevInSEL; - if (prev != null) - prev.nextInSEL = edge1; - edge1.prevInSEL = prev; - edge1.nextInSEL = edge2; - edge2.prevInSEL = edge1; - edge2.nextInSEL = next; - } - else - { - TEdge next = edge1.nextInSEL; - TEdge prev = edge1.prevInSEL; - edge1.nextInSEL = edge2.nextInSEL; - if (edge1.nextInSEL != null) - edge1.nextInSEL.prevInSEL = edge1; - edge1.prevInSEL = edge2.prevInSEL; - if (edge1.prevInSEL != null) - edge1.prevInSEL.nextInSEL = edge1; - edge2.nextInSEL = next; - if (edge2.nextInSEL != null) - edge2.nextInSEL.prevInSEL = edge2; - edge2.prevInSEL = prev; - if (edge2.prevInSEL != null) - edge2.prevInSEL.nextInSEL = edge2; - } + } + else if (e2Contributing) + { + if (e1Wc == 0 || e1Wc == 1) + { + AddOutPt(e2, pt); + SwapSides(e1, e2); + SwapPolyIndexes(e1, e2); + } + } + else if ( (e1Wc == 0 || e1Wc == 1) && + (e2Wc == 0 || e2Wc == 1) && !e1stops && !e2stops ) + { + //neither edge is currently contributing ... + cInt e1Wc2, e2Wc2; + switch (e1FillType2) + { + case PolyFillType.pftPositive: e1Wc2 = e1.WindCnt2; break; + case PolyFillType.pftNegative: e1Wc2 = -e1.WindCnt2; break; + default: e1Wc2 = Math.Abs(e1.WindCnt2); break; + } + switch (e2FillType2) + { + case PolyFillType.pftPositive: e2Wc2 = e2.WindCnt2; break; + case PolyFillType.pftNegative: e2Wc2 = -e2.WindCnt2; break; + default: e2Wc2 = Math.Abs(e2.WindCnt2); break; + } - if (edge1.prevInSEL == null) - m_SortedEdges = edge1; - else if (edge2.prevInSEL == null) - m_SortedEdges = edge2; - } - //------------------------------------------------------------------------------ + if (e1.PolyTyp != e2.PolyTyp) + AddLocalMinPoly(e1, e2, pt); + else if (e1Wc == 1 && e2Wc == 1) + switch (m_ClipType) + { + case ClipType.ctIntersection: + if (e1Wc2 > 0 && e2Wc2 > 0) + AddLocalMinPoly(e1, e2, pt); + break; + case ClipType.ctUnion: + if (e1Wc2 <= 0 && e2Wc2 <= 0) + AddLocalMinPoly(e1, e2, pt); + break; + case ClipType.ctDifference: + if (((e1.PolyTyp == PolyType.ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || + ((e1.PolyTyp == PolyType.ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) + AddLocalMinPoly(e1, e2, pt); + break; + case ClipType.ctXor: + AddLocalMinPoly(e1, e2, pt); + break; + } + else + SwapSides(e1, e2); + } + if ((e1stops != e2stops) && + ((e1stops && (e1.OutIdx >= 0)) || (e2stops && (e2.OutIdx >= 0)))) + { + SwapSides(e1, e2); + SwapPolyIndexes(e1, e2); + } - private void AddLocalMaxPoly(TEdge e1, TEdge e2, IntPoint pt) - { - AddOutPt(e1, pt); - if (e1.outIdx == e2.outIdx) - { - e1.outIdx = -1; - e2.outIdx = -1; - } - else if (e1.outIdx < e2.outIdx) - AppendPolygon(e1, e2); - else - AppendPolygon(e2, e1); - } - //------------------------------------------------------------------------------ + //finally, delete any non-contributing maxima edges ... + if (e1stops) DeleteFromAEL(e1); + if (e2stops) DeleteFromAEL(e2); + } + //------------------------------------------------------------------------------ + + private void DeleteFromAEL(TEdge e) + { + TEdge AelPrev = e.PrevInAEL; + TEdge AelNext = e.NextInAEL; + if (AelPrev == null && AelNext == null && (e != m_ActiveEdges)) + return; //already deleted + if (AelPrev != null) + AelPrev.NextInAEL = AelNext; + else m_ActiveEdges = AelNext; + if (AelNext != null) + AelNext.PrevInAEL = AelPrev; + e.NextInAEL = null; + e.PrevInAEL = null; + } + //------------------------------------------------------------------------------ + + private void DeleteFromSEL(TEdge e) + { + TEdge SelPrev = e.PrevInSEL; + TEdge SelNext = e.NextInSEL; + if (SelPrev == null && SelNext == null && (e != m_SortedEdges)) + return; //already deleted + if (SelPrev != null) + SelPrev.NextInSEL = SelNext; + else m_SortedEdges = SelNext; + if (SelNext != null) + SelNext.PrevInSEL = SelPrev; + e.NextInSEL = null; + e.PrevInSEL = null; + } + //------------------------------------------------------------------------------ + + private void UpdateEdgeIntoAEL(ref TEdge e) + { + if (e.NextInLML == null) + throw new ClipperException("UpdateEdgeIntoAEL: invalid call"); + TEdge AelPrev = e.PrevInAEL; + TEdge AelNext = e.NextInAEL; + e.NextInLML.OutIdx = e.OutIdx; + if (AelPrev != null) + AelPrev.NextInAEL = e.NextInLML; + else m_ActiveEdges = e.NextInLML; + if (AelNext != null) + AelNext.PrevInAEL = e.NextInLML; + e.NextInLML.Side = e.Side; + e.NextInLML.WindDelta = e.WindDelta; + e.NextInLML.WindCnt = e.WindCnt; + e.NextInLML.WindCnt2 = e.WindCnt2; + e = e.NextInLML; + e.Curr = e.Bot; + e.PrevInAEL = AelPrev; + e.NextInAEL = AelNext; + if (!IsHorizontal(e)) InsertScanbeam(e.Top.Y); + } + //------------------------------------------------------------------------------ + + private void ProcessHorizontals(bool isTopOfScanbeam) + { + TEdge horzEdge = m_SortedEdges; + while (horzEdge != null) + { + DeleteFromSEL(horzEdge); + ProcessHorizontal(horzEdge, isTopOfScanbeam); + horzEdge = m_SortedEdges; + } + } + //------------------------------------------------------------------------------ + + void GetHorzDirection(TEdge HorzEdge, out Direction Dir, out cInt Left, out cInt Right) + { + if (HorzEdge.Bot.X < HorzEdge.Top.X) + { + Left = HorzEdge.Bot.X; + Right = HorzEdge.Top.X; + Dir = Direction.dLeftToRight; + } else + { + Left = HorzEdge.Top.X; + Right = HorzEdge.Bot.X; + Dir = Direction.dRightToLeft; + } + } + //------------------------------------------------------------------------ + + void PrepareHorzJoins(TEdge horzEdge, bool isTopOfScanbeam) + { + //get the last Op for this horizontal edge + //the point may be anywhere along the horizontal ... + OutPt outPt = m_PolyOuts[horzEdge.OutIdx].Pts; + if (horzEdge.Side != EdgeSide.esLeft) outPt = outPt.Prev; + + //First, match up overlapping horizontal edges (eg when one polygon's + //intermediate horz edge overlaps an intermediate horz edge of another, or + //when one polygon sits on top of another) ... + for (int i = 0; i < m_GhostJoins.Count; ++i) + { + Join j = m_GhostJoins[i]; + if (HorzSegmentsOverlap(j.OutPt1.Pt, j.OffPt, horzEdge.Bot, horzEdge.Top)) + AddJoin(j.OutPt1, outPt, j.OffPt); + } + //Also, since horizontal edges at the top of one SB are often removed from + //the AEL before we process the horizontal edges at the bottom of the next, + //we need to create 'ghost' Join records of 'contrubuting' horizontals that + //we can compare with horizontals at the bottom of the next SB. + if (isTopOfScanbeam) + if (outPt.Pt == horzEdge.Top) + AddGhostJoin(outPt, horzEdge.Bot); + else + AddGhostJoin(outPt, horzEdge.Top); + } + //------------------------------------------------------------------------------ + + private void ProcessHorizontal(TEdge horzEdge, bool isTopOfScanbeam) + { + Direction dir; + cInt horzLeft, horzRight; - private void AddLocalMinPoly(TEdge e1, TEdge e2, IntPoint pt) + GetHorzDirection(horzEdge, out dir, out horzLeft, out horzRight); + + TEdge eLastHorz = horzEdge, eMaxPair = null; + while (eLastHorz.NextInLML != null && IsHorizontal(eLastHorz.NextInLML)) + eLastHorz = eLastHorz.NextInLML; + if (eLastHorz.NextInLML == null) + eMaxPair = GetMaximaPair(eLastHorz); + + for (;;) { - TEdge e, prevE; - if (e2.dx == horizontal || (e1.dx > e2.dx)) - { - AddOutPt(e1, pt); - e2.outIdx = e1.outIdx; - e1.side = EdgeSide.esLeft; - e2.side = EdgeSide.esRight; - e = e1; - if (e.prevInAEL == e2) - prevE = e2.prevInAEL; - else - prevE = e.prevInAEL; - } - else + bool IsLastHorz = (horzEdge == eLastHorz); + TEdge e = GetNextInAEL(horzEdge, dir); + while(e != null) + { + //Break if we've got to the end of an intermediate horizontal edge ... + //nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal. + if (e.Curr.X == horzEdge.Top.X && horzEdge.NextInLML != null && + e.Dx < horzEdge.NextInLML.Dx) break; + + TEdge eNext = GetNextInAEL(e, dir); //saves eNext for later + + if ((dir == Direction.dLeftToRight && e.Curr.X <= horzRight) || + (dir == Direction.dRightToLeft && e.Curr.X >= horzLeft)) { - AddOutPt(e2, pt); - e1.outIdx = e2.outIdx; - e1.side = EdgeSide.esRight; - e2.side = EdgeSide.esLeft; - e = e2; - if (e.prevInAEL == e1) - prevE = e1.prevInAEL; + //so far we're still in range of the horizontal Edge but make sure + //we're at the last of consec. horizontals when matching with eMaxPair + if(e == eMaxPair && IsLastHorz) + { + if (horzEdge.OutIdx >= 0 && horzEdge.WindDelta != 0) + PrepareHorzJoins(horzEdge, isTopOfScanbeam); + if (dir == Direction.dLeftToRight) + IntersectEdges(horzEdge, e, e.Top); else - prevE = e.prevInAEL; + IntersectEdges(e, horzEdge, e.Top); + if (eMaxPair.OutIdx >= 0) throw + new ClipperException("ProcessHorizontal error"); + return; + } + else if(dir == Direction.dLeftToRight) + { + IntPoint Pt = new IntPoint(e.Curr.X, horzEdge.Curr.Y); + IntersectEdges(horzEdge, e, Pt, true); + } + else + { + IntPoint Pt = new IntPoint(e.Curr.X, horzEdge.Curr.Y); + IntersectEdges(e, horzEdge, Pt, true); + } + SwapPositionsInAEL(horzEdge, e); } + else if ((dir == Direction.dLeftToRight && e.Curr.X >= horzRight) || + (dir == Direction.dRightToLeft && e.Curr.X <= horzLeft)) break; + e = eNext; + } //end while - if (prevE != null && prevE.outIdx >= 0 && - (TopX(prevE, pt.Y) == TopX(e, pt.Y)) && - SlopesEqual(e, prevE, m_UseFullRange)) - AddJoin(e, prevE, -1, -1); + if (horzEdge.OutIdx >= 0 && horzEdge.WindDelta != 0) + PrepareHorzJoins(horzEdge, isTopOfScanbeam); - } - //------------------------------------------------------------------------------ + if (horzEdge.NextInLML != null && IsHorizontal(horzEdge.NextInLML)) + { + UpdateEdgeIntoAEL(ref horzEdge); + if (horzEdge.OutIdx >= 0) AddOutPt(horzEdge, horzEdge.Bot); + GetHorzDirection(horzEdge, out dir, out horzLeft, out horzRight); + } else + break; + } //end for (;;) - private OutRec CreateOutRec() + if(horzEdge.NextInLML != null) { - OutRec result = new OutRec(); - result.idx = -1; - result.isHole = false; - result.FirstLeft = null; - result.pts = null; - result.bottomPt = null; - result.polyNode = null; - m_PolyOuts.Add(result); - result.idx = m_PolyOuts.Count - 1; - return result; + if(horzEdge.OutIdx >= 0) + { + OutPt op1 = AddOutPt( horzEdge, horzEdge.Top); + UpdateEdgeIntoAEL(ref horzEdge); + if (horzEdge.WindDelta == 0) return; + //nb: HorzEdge is no longer horizontal here + TEdge ePrev = horzEdge.PrevInAEL; + TEdge eNext = horzEdge.NextInAEL; + if (ePrev != null && ePrev.Curr.X == horzEdge.Bot.X && + ePrev.Curr.Y == horzEdge.Bot.Y && ePrev.WindDelta != 0 && + (ePrev.OutIdx >= 0 && ePrev.Curr.Y > ePrev.Top.Y && + SlopesEqual(horzEdge, ePrev, m_UseFullRange))) + { + OutPt op2 = AddOutPt(ePrev, horzEdge.Bot); + AddJoin(op1, op2, horzEdge.Top); + } + else if (eNext != null && eNext.Curr.X == horzEdge.Bot.X && + eNext.Curr.Y == horzEdge.Bot.Y && eNext.WindDelta != 0 && + eNext.OutIdx >= 0 && eNext.Curr.Y > eNext.Top.Y && + SlopesEqual(horzEdge, eNext, m_UseFullRange)) + { + OutPt op2 = AddOutPt(eNext, horzEdge.Bot); + AddJoin(op1, op2, horzEdge.Top); + } + } + else + UpdateEdgeIntoAEL(ref horzEdge); } - //------------------------------------------------------------------------------ - - private void AddOutPt(TEdge e, IntPoint pt) + else if (eMaxPair != null) { - bool ToFront = (e.side == EdgeSide.esLeft); - if( e.outIdx < 0 ) + if (eMaxPair.OutIdx >= 0) { - OutRec outRec = CreateOutRec(); - e.outIdx = outRec.idx; - OutPt op = new OutPt(); - outRec.pts = op; - op.pt = pt; - op.idx = outRec.idx; - op.next = op; - op.prev = op; - SetHoleState(e, outRec); + if (dir == Direction.dLeftToRight) + IntersectEdges(horzEdge, eMaxPair, horzEdge.Top); + else + IntersectEdges(eMaxPair, horzEdge, horzEdge.Top); + if (eMaxPair.OutIdx >= 0) throw + new ClipperException("ProcessHorizontal error"); } else { - OutRec outRec = m_PolyOuts[e.outIdx]; - OutPt op = outRec.pts, op2; - if (ToFront && PointsEqual(pt, op.pt) || - (!ToFront && PointsEqual(pt, op.prev.pt))) return; - - op2 = new OutPt(); - op2.pt = pt; - op2.idx = outRec.idx; - op2.next = op; - op2.prev = op.prev; - op2.prev.next = op2; - op.prev = op2; - if (ToFront) outRec.pts = op2; + DeleteFromAEL(horzEdge); + DeleteFromAEL(eMaxPair); } + } else + { + if (horzEdge.OutIdx >= 0) AddOutPt(horzEdge, horzEdge.Top); + DeleteFromAEL(horzEdge); + } + } + //------------------------------------------------------------------------------ + + private TEdge GetNextInAEL(TEdge e, Direction Direction) + { + return Direction == Direction.dLeftToRight ? e.NextInAEL: e.PrevInAEL; + } + //------------------------------------------------------------------------------ + + private bool IsMinima(TEdge e) + { + return e != null && (e.Prev.NextInLML != e) && (e.Next.NextInLML != e); + } + //------------------------------------------------------------------------------ + + private bool IsMaxima(TEdge e, double Y) + { + return (e != null && e.Top.Y == Y && e.NextInLML == null); + } + //------------------------------------------------------------------------------ + + private bool IsIntermediate(TEdge e, double Y) + { + return (e.Top.Y == Y && e.NextInLML != null); + } + //------------------------------------------------------------------------------ + + private TEdge GetMaximaPair(TEdge e) + { + TEdge result = null; + if ((e.Next.Top == e.Top) && e.Next.NextInLML == null) + result = e.Next; + else if ((e.Prev.Top == e.Top) && e.Prev.NextInLML == null) + result = e.Prev; + if (result != null && (result.OutIdx == Skip || + (result.NextInAEL == result.PrevInAEL && !IsHorizontal(result)))) + return null; + return result; + } + //------------------------------------------------------------------------------ + + private bool ProcessIntersections(cInt botY, cInt topY) + { + if( m_ActiveEdges == null ) return true; + try { + BuildIntersectList(botY, topY); + if ( m_IntersectNodes == null) return true; + if (m_IntersectNodes.Next == null || FixupIntersectionOrder()) + ProcessIntersectList(); + else + return false; } - //------------------------------------------------------------------------------ - - internal void SwapPoints(ref IntPoint pt1, ref IntPoint pt2) - { - IntPoint tmp = pt1; - pt1 = pt2; - pt2 = tmp; + catch { + m_SortedEdges = null; + DisposeIntersectNodes(); + throw new ClipperException("ProcessIntersections error"); } - //------------------------------------------------------------------------------ + m_SortedEdges = null; + return true; + } + //------------------------------------------------------------------------------ + + private void BuildIntersectList(cInt botY, cInt topY) + { + if ( m_ActiveEdges == null ) return; - private bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a, - IntPoint pt2b, ref IntPoint pt1, ref IntPoint pt2) + //prepare for sorting ... + TEdge e = m_ActiveEdges; + m_SortedEdges = e; + while( e != null ) { - //precondition: segments are colinear. - if (Math.Abs(pt1a.X - pt1b.X) > Math.Abs(pt1a.Y - pt1b.Y)) - { - if (pt1a.X > pt1b.X) SwapPoints(ref pt1a, ref pt1b); - if (pt2a.X > pt2b.X) SwapPoints(ref pt2a, ref pt2b); - if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a; - if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b; - return pt1.X < pt2.X; - } else - { - if (pt1a.Y < pt1b.Y) SwapPoints(ref pt1a, ref pt1b); - if (pt2a.Y < pt2b.Y) SwapPoints(ref pt2a, ref pt2b); - if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a; - if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b; - return pt1.Y > pt2.Y; - } + e.PrevInSEL = e.PrevInAEL; + e.NextInSEL = e.NextInAEL; + e.Curr.X = TopX( e, topY ); + e = e.NextInAEL; } - //------------------------------------------------------------------------------ - private bool FindSegment(ref OutPt pp, bool UseFullInt64Range, - ref IntPoint pt1, ref IntPoint pt2) + //bubblesort ... + bool isModified = true; + while( isModified && m_SortedEdges != null ) { - if (pp == null) return false; - OutPt pp2 = pp; - IntPoint pt1a = new IntPoint(pt1); - IntPoint pt2a = new IntPoint(pt2); - do + isModified = false; + e = m_SortedEdges; + while( e.NextInSEL != null ) + { + TEdge eNext = e.NextInSEL; + IntPoint pt; + if (e.Curr.X > eNext.Curr.X) { - if (SlopesEqual(pt1a, pt2a, pp.pt, pp.prev.pt, UseFullInt64Range) && - SlopesEqual(pt1a, pt2a, pp.pt, UseFullInt64Range) && - GetOverlapSegment(pt1a, pt2a, pp.pt, pp.prev.pt, ref pt1, ref pt2)) - return true; - pp = pp.next; + if (!IntersectPoint(e, eNext, out pt) && e.Curr.X > eNext.Curr.X +1) + throw new ClipperException("Intersection error"); + if (pt.Y > botY) + { + pt.Y = botY; + if (Math.Abs(e.Dx) > Math.Abs(eNext.Dx)) + pt.X = TopX(eNext, botY); else + pt.X = TopX(e, botY); + } + InsertIntersectNode(e, eNext, pt); + SwapPositionsInSEL(e, eNext); + isModified = true; } - while (pp != pp2); + else + e = eNext; + } + if( e.PrevInSEL != null ) e.PrevInSEL.NextInSEL = null; + else break; + } + m_SortedEdges = null; + } + //------------------------------------------------------------------------------ + + private bool EdgesAdjacent(IntersectNode inode) + { + return (inode.Edge1.NextInSEL == inode.Edge2) || + (inode.Edge1.PrevInSEL == inode.Edge2); + } + //------------------------------------------------------------------------------ + + private bool FixupIntersectionOrder() + { + //pre-condition: intersections are sorted bottom-most (then left-most) first. + //Now it's crucial that intersections are made only between adjacent edges, + //so to ensure this the order of intersections may need adjusting ... + IntersectNode inode = m_IntersectNodes; + CopyAELToSEL(); + while (inode != null) + { + if (!EdgesAdjacent(inode)) + { + IntersectNode nextNode = inode.Next; + while (nextNode != null && !EdgesAdjacent(nextNode)) + nextNode = nextNode.Next; + if (nextNode == null) + return false; + SwapIntersectNodes(inode, nextNode); + } + SwapPositionsInSEL(inode.Edge1, inode.Edge2); + inode = inode.Next; + } + return true; + } + //------------------------------------------------------------------------------ + + private void ProcessIntersectList() + { + while (m_IntersectNodes != null) + { + IntersectNode iNode = m_IntersectNodes.Next; + { + IntersectEdges( m_IntersectNodes.Edge1 , + m_IntersectNodes.Edge2 , m_IntersectNodes.Pt, true); + SwapPositionsInAEL( m_IntersectNodes.Edge1 , m_IntersectNodes.Edge2 ); + } + m_IntersectNodes = null; + m_IntersectNodes = iNode; + } + } + //------------------------------------------------------------------------------ + + internal static cInt Round(double value) + { + return value < 0 ? (cInt)(value - 0.5) : (cInt)(value + 0.5); + } + //------------------------------------------------------------------------------ + + private static cInt TopX(TEdge edge, cInt currentY) + { + if (currentY == edge.Top.Y) + return edge.Top.X; + return edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y)); + } + //------------------------------------------------------------------------------ + + private void InsertIntersectNode(TEdge e1, TEdge e2, IntPoint pt) + { + IntersectNode newNode = new IntersectNode(); + newNode.Edge1 = e1; + newNode.Edge2 = e2; + newNode.Pt = pt; + newNode.Next = null; + if (m_IntersectNodes == null) m_IntersectNodes = newNode; + else if (newNode.Pt.Y > m_IntersectNodes.Pt.Y) + { + newNode.Next = m_IntersectNodes; + m_IntersectNodes = newNode; + } + else + { + IntersectNode iNode = m_IntersectNodes; + while (iNode.Next != null && newNode.Pt.Y < iNode.Next.Pt.Y) + iNode = iNode.Next; + newNode.Next = iNode.Next; + iNode.Next = newNode; + } + } + //------------------------------------------------------------------------------ + + private void SwapIntersectNodes(IntersectNode int1, IntersectNode int2) + { + TEdge e1 = int1.Edge1; + TEdge e2 = int1.Edge2; + IntPoint p = new IntPoint(int1.Pt); + int1.Edge1 = int2.Edge1; + int1.Edge2 = int2.Edge2; + int1.Pt = int2.Pt; + int2.Edge1 = e1; + int2.Edge2 = e2; + int2.Pt = p; + } + //------------------------------------------------------------------------------ + + private bool IntersectPoint(TEdge edge1, TEdge edge2, out IntPoint ip) + { + ip = new IntPoint(); + double b1, b2; + //nb: with very large coordinate values, it's possible for SlopesEqual() to + //return false but for the edge.Dx value be equal due to double precision rounding. + if (SlopesEqual(edge1, edge2, m_UseFullRange) || edge1.Dx == edge2.Dx) + { + if (edge2.Bot.Y > edge1.Bot.Y) + ip.Y = edge2.Bot.Y; + else + ip.Y = edge1.Bot.Y; return false; } - //------------------------------------------------------------------------------ - - internal bool Pt3IsBetweenPt1AndPt2(IntPoint pt1, IntPoint pt2, IntPoint pt3) + else if (edge1.Delta.X == 0) { - if (PointsEqual(pt1, pt3) || PointsEqual(pt2, pt3)) return true; - else if (pt1.X != pt2.X) return (pt1.X < pt3.X) == (pt3.X < pt2.X); - else return (pt1.Y < pt3.Y) == (pt3.Y < pt2.Y); + ip.X = edge1.Bot.X; + if (IsHorizontal(edge2)) + { + ip.Y = edge2.Bot.Y; + } + else + { + b2 = edge2.Bot.Y - (edge2.Bot.X / edge2.Dx); + ip.Y = Round(ip.X / edge2.Dx + b2); + } } - //------------------------------------------------------------------------------ - - private OutPt InsertPolyPtBetween(OutPt p1, OutPt p2, IntPoint pt) + else if (edge2.Delta.X == 0) { - OutPt result = new OutPt(); - result.pt = pt; - if (p2 == p1.next) + ip.X = edge2.Bot.X; + if (IsHorizontal(edge1)) { - p1.next = result; - p2.prev = result; - result.next = p2; - result.prev = p1; - } else + ip.Y = edge1.Bot.Y; + } + else { - p2.next = result; - p1.prev = result; - result.next = p1; - result.prev = p2; + b1 = edge1.Bot.Y - (edge1.Bot.X / edge1.Dx); + ip.Y = Round(ip.X / edge1.Dx + b1); } - return result; } - //------------------------------------------------------------------------------ + else + { + b1 = edge1.Bot.X - edge1.Bot.Y * edge1.Dx; + b2 = edge2.Bot.X - edge2.Bot.Y * edge2.Dx; + double q = (b2 - b1) / (edge1.Dx - edge2.Dx); + ip.Y = Round(q); + if (Math.Abs(edge1.Dx) < Math.Abs(edge2.Dx)) + ip.X = Round(edge1.Dx * q + b1); + else + ip.X = Round(edge2.Dx * q + b2); + } - private void SetHoleState(TEdge e, OutRec outRec) + if (ip.Y < edge1.Top.Y || ip.Y < edge2.Top.Y) { - bool isHole = false; - TEdge e2 = e.prevInAEL; - while (e2 != null) + if (edge1.Top.Y > edge2.Top.Y) { - if (e2.outIdx >= 0) - { - isHole = !isHole; - if (outRec.FirstLeft == null) - outRec.FirstLeft = m_PolyOuts[e2.outIdx]; - } - e2 = e2.prevInAEL; + ip.Y = edge1.Top.Y; + ip.X = TopX(edge2, edge1.Top.Y); + return ip.X < edge1.Top.X; + } + else + { + ip.Y = edge2.Top.Y; + ip.X = TopX(edge1, edge2.Top.Y); + return ip.X > edge2.Top.X; } - if (isHole) outRec.isHole = true; } - //------------------------------------------------------------------------------ + else + return true; + } + //------------------------------------------------------------------------------ - private double GetDx(IntPoint pt1, IntPoint pt2) + private void DisposeIntersectNodes() + { + while ( m_IntersectNodes != null ) { - if (pt1.Y == pt2.Y) return horizontal; - else return (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y); + IntersectNode iNode = m_IntersectNodes.Next; + m_IntersectNodes = null; + m_IntersectNodes = iNode; } - //--------------------------------------------------------------------------- + } + //------------------------------------------------------------------------------ - private bool FirstIsBottomPt(OutPt btmPt1, OutPt btmPt2) + private void ProcessEdgesAtTopOfScanbeam(cInt topY) + { + TEdge e = m_ActiveEdges; + while(e != null) { - OutPt p = btmPt1.prev; - while (PointsEqual(p.pt, btmPt1.pt) && (p != btmPt1)) p = p.prev; - double dx1p = Math.Abs(GetDx(btmPt1.pt, p.pt)); - p = btmPt1.next; - while (PointsEqual(p.pt, btmPt1.pt) && (p != btmPt1)) p = p.next; - double dx1n = Math.Abs(GetDx(btmPt1.pt, p.pt)); + //1. process maxima, treating them as if they're 'bent' horizontal edges, + // but exclude maxima with horizontal edges. nb: e can't be a horizontal. + bool IsMaximaEdge = IsMaxima(e, topY); - p = btmPt2.prev; - while (PointsEqual(p.pt, btmPt2.pt) && (p != btmPt2)) p = p.prev; - double dx2p = Math.Abs(GetDx(btmPt2.pt, p.pt)); - p = btmPt2.next; - while (PointsEqual(p.pt, btmPt2.pt) && (p != btmPt2)) p = p.next; - double dx2n = Math.Abs(GetDx(btmPt2.pt, p.pt)); - return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); - } - //------------------------------------------------------------------------------ + if(IsMaximaEdge) + { + TEdge eMaxPair = GetMaximaPair(e); + IsMaximaEdge = (eMaxPair == null || !IsHorizontal(eMaxPair)); + } - private OutPt GetBottomPt(OutPt pp) - { - OutPt dups = null; - OutPt p = pp.next; - while (p != pp) + if(IsMaximaEdge) + { + TEdge ePrev = e.PrevInAEL; + DoMaxima(e); + if( ePrev == null) e = m_ActiveEdges; + else e = ePrev.NextInAEL; + } + else { - if (p.pt.Y > pp.pt.Y) + //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ... + if (IsIntermediate(e, topY) && IsHorizontal(e.NextInLML)) + { + UpdateEdgeIntoAEL(ref e); + if (e.OutIdx >= 0) + AddOutPt(e, e.Bot); + AddEdgeToSEL(e); + } + else { - pp = p; - dups = null; + e.Curr.X = TopX( e, topY ); + e.Curr.Y = topY; } - else if (p.pt.Y == pp.pt.Y && p.pt.X <= pp.pt.X) + + if (StrictlySimple) { - if (p.pt.X < pp.pt.X) + TEdge ePrev = e.PrevInAEL; + if ((e.OutIdx >= 0) && (e.WindDelta != 0) && ePrev != null && + (ePrev.OutIdx >= 0) && (ePrev.Curr.X == e.Curr.X) && + (ePrev.WindDelta != 0)) { - dups = null; - pp = p; - } else - { - if (p.next != pp && p.prev != pp) dups = p; + OutPt op = AddOutPt(ePrev, e.Curr); + OutPt op2 = AddOutPt(e, e.Curr); + AddJoin(op, op2, e.Curr); //StrictlySimple (type-3) join } } - p = p.next; + + e = e.NextInAEL; } - if (dups != null) + } + + //3. Process horizontals at the Top of the scanbeam ... + ProcessHorizontals(true); + + //4. Promote intermediate vertices ... + e = m_ActiveEdges; + while (e != null) + { + if(IsIntermediate(e, topY)) { - //there appears to be at least 2 vertices at bottomPt so ... - while (dups != p) + OutPt op = null; + if( e.OutIdx >= 0 ) + op = AddOutPt(e, e.Top); + UpdateEdgeIntoAEL(ref e); + + //if output polygons share an edge, they'll need joining later ... + TEdge ePrev = e.PrevInAEL; + TEdge eNext = e.NextInAEL; + if (ePrev != null && ePrev.Curr.X == e.Bot.X && + ePrev.Curr.Y == e.Bot.Y && op != null && + ePrev.OutIdx >= 0 && ePrev.Curr.Y > ePrev.Top.Y && + SlopesEqual(e, ePrev, m_UseFullRange) && + (e.WindDelta != 0) && (ePrev.WindDelta != 0)) { - if (!FirstIsBottomPt(p, dups)) pp = dups; - dups = dups.next; - while (!PointsEqual(dups.pt, pp.pt)) dups = dups.next; + OutPt op2 = AddOutPt(ePrev, e.Bot); + AddJoin(op, op2, e.Top); + } + else if (eNext != null && eNext.Curr.X == e.Bot.X && + eNext.Curr.Y == e.Bot.Y && op != null && + eNext.OutIdx >= 0 && eNext.Curr.Y > eNext.Top.Y && + SlopesEqual(e, eNext, m_UseFullRange) && + (e.WindDelta != 0) && (eNext.WindDelta != 0)) + { + OutPt op2 = AddOutPt(eNext, e.Bot); + AddJoin(op, op2, e.Top); } } - return pp; + e = e.NextInAEL; } - //------------------------------------------------------------------------------ + } + //------------------------------------------------------------------------------ - private OutRec GetLowermostRec(OutRec outRec1, OutRec outRec2) + private void DoMaxima(TEdge e) + { + TEdge eMaxPair = GetMaximaPair(e); + if (eMaxPair == null) { - //work out which polygon fragment has the correct hole state ... - if (outRec1.bottomPt == null) - outRec1.bottomPt = GetBottomPt(outRec1.pts); - if (outRec2.bottomPt == null) - outRec2.bottomPt = GetBottomPt(outRec2.pts); - OutPt bPt1 = outRec1.bottomPt; - OutPt bPt2 = outRec2.bottomPt; - if (bPt1.pt.Y > bPt2.pt.Y) return outRec1; - else if (bPt1.pt.Y < bPt2.pt.Y) return outRec2; - else if (bPt1.pt.X < bPt2.pt.X) return outRec1; - else if (bPt1.pt.X > bPt2.pt.X) return outRec2; - else if (bPt1.next == bPt1) return outRec2; - else if (bPt2.next == bPt2) return outRec1; - else if (FirstIsBottomPt(bPt1, bPt2)) return outRec1; - else return outRec2; + if (e.OutIdx >= 0) + AddOutPt(e, e.Top); + DeleteFromAEL(e); + return; } - //------------------------------------------------------------------------------ - bool Param1RightOfParam2(OutRec outRec1, OutRec outRec2) + TEdge eNext = e.NextInAEL; + while(eNext != null && eNext != eMaxPair) { - do - { - outRec1 = outRec1.FirstLeft; - if (outRec1 == outRec2) return true; - } while (outRec1 != null); - return false; + IntersectEdges(e, eNext, e.Top, true); + SwapPositionsInAEL(e, eNext); + eNext = e.NextInAEL; } - //------------------------------------------------------------------------------ - private OutRec GetOutRec(int idx) + if(e.OutIdx == Unassigned && eMaxPair.OutIdx == Unassigned) { - OutRec outrec = m_PolyOuts[idx]; - while (outrec != m_PolyOuts[outrec.idx]) - outrec = m_PolyOuts[outrec.idx]; - return outrec; + DeleteFromAEL(e); + DeleteFromAEL(eMaxPair); } - //------------------------------------------------------------------------------ - - private void AppendPolygon(TEdge e1, TEdge e2) + else if( e.OutIdx >= 0 && eMaxPair.OutIdx >= 0 ) + { + IntersectEdges( e, eMaxPair, e.Top); + } +#if use_lines + else if (e.WindDelta == 0) { - //get the start and ends of both output polygons ... - OutRec outRec1 = m_PolyOuts[e1.outIdx]; - OutRec outRec2 = m_PolyOuts[e2.outIdx]; + if (e.OutIdx >= 0) + { + AddOutPt(e, e.Top); + e.OutIdx = Unassigned; + } + DeleteFromAEL(e); - OutRec holeStateRec; - if (Param1RightOfParam2(outRec1, outRec2)) - holeStateRec = outRec2; - else if (Param1RightOfParam2(outRec2, outRec1)) - holeStateRec = outRec1; - else - holeStateRec = GetLowermostRec(outRec1, outRec2); - - OutPt p1_lft = outRec1.pts; - OutPt p1_rt = p1_lft.prev; - OutPt p2_lft = outRec2.pts; - OutPt p2_rt = p2_lft.prev; - - EdgeSide side; - //join e2 poly onto e1 poly and delete pointers to e2 ... - if( e1.side == EdgeSide.esLeft ) - { - if (e2.side == EdgeSide.esLeft) - { - //z y x a b c - ReversePolyPtLinks(p2_lft); - p2_lft.next = p1_lft; - p1_lft.prev = p2_lft; - p1_rt.next = p2_rt; - p2_rt.prev = p1_rt; - outRec1.pts = p2_rt; - } else - { - //x y z a b c - p2_rt.next = p1_lft; - p1_lft.prev = p2_rt; - p2_lft.prev = p1_rt; - p1_rt.next = p2_lft; - outRec1.pts = p2_lft; - } - side = EdgeSide.esLeft; - } else - { - if (e2.side == EdgeSide.esRight) - { - //a b c z y x - ReversePolyPtLinks( p2_lft ); - p1_rt.next = p2_rt; - p2_rt.prev = p1_rt; - p2_lft.next = p1_lft; - p1_lft.prev = p2_lft; - } else - { - //a b c x y z - p1_rt.next = p2_lft; - p2_lft.prev = p1_rt; - p1_lft.prev = p2_rt; - p2_rt.next = p1_lft; - } - side = EdgeSide.esRight; - } - - outRec1.bottomPt = null; - if (holeStateRec == outRec2) - { - if (outRec2.FirstLeft != outRec1) - outRec1.FirstLeft = outRec2.FirstLeft; - outRec1.isHole = outRec2.isHole; - } - outRec2.pts = null; - outRec2.bottomPt = null; - - outRec2.FirstLeft = outRec1; - - int OKIdx = e1.outIdx; - int ObsoleteIdx = e2.outIdx; - - e1.outIdx = -1; //nb: safe because we only get here via AddLocalMaxPoly - e2.outIdx = -1; - - TEdge e = m_ActiveEdges; - while( e != null ) + if (eMaxPair.OutIdx >= 0) { - if( e.outIdx == ObsoleteIdx ) - { - e.outIdx = OKIdx; - e.side = side; - break; - } - e = e.nextInAEL; - } - outRec2.idx = outRec1.idx; - } - //------------------------------------------------------------------------------ - - private void ReversePolyPtLinks(OutPt pp) - { - if (pp == null) return; - OutPt pp1; - OutPt pp2; - pp1 = pp; - do - { - pp2 = pp1.next; - pp1.next = pp1.prev; - pp1.prev = pp2; - pp1 = pp2; - } while (pp1 != pp); - } - //------------------------------------------------------------------------------ - - private static void SwapSides(TEdge edge1, TEdge edge2) - { - EdgeSide side = edge1.side; - edge1.side = edge2.side; - edge2.side = side; - } - //------------------------------------------------------------------------------ - - private static void SwapPolyIndexes(TEdge edge1, TEdge edge2) - { - int outIdx = edge1.outIdx; - edge1.outIdx = edge2.outIdx; - edge2.outIdx = outIdx; - } - //------------------------------------------------------------------------------ - - private void IntersectEdges(TEdge e1, TEdge e2, IntPoint pt, Protects protects) - { - //e1 will be to the left of e2 BELOW the intersection. Therefore e1 is before - //e2 in AEL except when e1 is being inserted at the intersection point ... - - bool e1stops = (Protects.ipLeft & protects) == 0 && e1.nextInLML == null && - e1.xtop == pt.X && e1.ytop == pt.Y; - bool e2stops = (Protects.ipRight & protects) == 0 && e2.nextInLML == null && - e2.xtop == pt.X && e2.ytop == pt.Y; - bool e1Contributing = (e1.outIdx >= 0); - bool e2contributing = (e2.outIdx >= 0); - - //update winding counts... - //assumes that e1 will be to the right of e2 ABOVE the intersection - if (e1.polyType == e2.polyType) - { - if (IsEvenOddFillType(e1)) - { - int oldE1WindCnt = e1.windCnt; - e1.windCnt = e2.windCnt; - e2.windCnt = oldE1WindCnt; - } - else - { - if (e1.windCnt + e2.windDelta == 0) e1.windCnt = -e1.windCnt; - else e1.windCnt += e2.windDelta; - if (e2.windCnt - e1.windDelta == 0) e2.windCnt = -e2.windCnt; - else e2.windCnt -= e1.windDelta; - } - } - else - { - if (!IsEvenOddFillType(e2)) e1.windCnt2 += e2.windDelta; - else e1.windCnt2 = (e1.windCnt2 == 0) ? 1 : 0; - if (!IsEvenOddFillType(e1)) e2.windCnt2 -= e1.windDelta; - else e2.windCnt2 = (e2.windCnt2 == 0) ? 1 : 0; - } - - PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2; - if (e1.polyType == PolyType.ptSubject) - { - e1FillType = m_SubjFillType; - e1FillType2 = m_ClipFillType; - } - else - { - e1FillType = m_ClipFillType; - e1FillType2 = m_SubjFillType; - } - if (e2.polyType == PolyType.ptSubject) - { - e2FillType = m_SubjFillType; - e2FillType2 = m_ClipFillType; - } - else - { - e2FillType = m_ClipFillType; - e2FillType2 = m_SubjFillType; - } - - int e1Wc, e2Wc; - switch (e1FillType) - { - case PolyFillType.pftPositive: e1Wc = e1.windCnt; break; - case PolyFillType.pftNegative: e1Wc = -e1.windCnt; break; - default: e1Wc = Math.Abs(e1.windCnt); break; - } - switch (e2FillType) - { - case PolyFillType.pftPositive: e2Wc = e2.windCnt; break; - case PolyFillType.pftNegative: e2Wc = -e2.windCnt; break; - default: e2Wc = Math.Abs(e2.windCnt); break; - } - - if (e1Contributing && e2contributing) - { - if ( e1stops || e2stops || - (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || - (e1.polyType != e2.polyType && m_ClipType != ClipType.ctXor)) - AddLocalMaxPoly(e1, e2, pt); - else - { - AddOutPt(e1, pt); - AddOutPt(e2, pt); - SwapSides(e1, e2); - SwapPolyIndexes(e1, e2); - } - } - else if (e1Contributing) - { - if (e2Wc == 0 || e2Wc == 1) - { - AddOutPt(e1, pt); - SwapSides(e1, e2); - SwapPolyIndexes(e1, e2); - } - - } - else if (e2contributing) - { - if (e1Wc == 0 || e1Wc == 1) - { - AddOutPt(e2, pt); - SwapSides(e1, e2); - SwapPolyIndexes(e1, e2); - } - } - else if ( (e1Wc == 0 || e1Wc == 1) && - (e2Wc == 0 || e2Wc == 1) && !e1stops && !e2stops ) - { - //neither edge is currently contributing ... - Int64 e1Wc2, e2Wc2; - switch (e1FillType2) - { - case PolyFillType.pftPositive: e1Wc2 = e1.windCnt2; break; - case PolyFillType.pftNegative: e1Wc2 = -e1.windCnt2; break; - default: e1Wc2 = Math.Abs(e1.windCnt2); break; - } - switch (e2FillType2) - { - case PolyFillType.pftPositive: e2Wc2 = e2.windCnt2; break; - case PolyFillType.pftNegative: e2Wc2 = -e2.windCnt2; break; - default: e2Wc2 = Math.Abs(e2.windCnt2); break; - } - - if (e1.polyType != e2.polyType) - AddLocalMinPoly(e1, e2, pt); - else if (e1Wc == 1 && e2Wc == 1) - switch (m_ClipType) - { - case ClipType.ctIntersection: - if (e1Wc2 > 0 && e2Wc2 > 0) - AddLocalMinPoly(e1, e2, pt); - break; - case ClipType.ctUnion: - if (e1Wc2 <= 0 && e2Wc2 <= 0) - AddLocalMinPoly(e1, e2, pt); - break; - case ClipType.ctDifference: - if (((e1.polyType == PolyType.ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || - ((e1.polyType == PolyType.ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) - AddLocalMinPoly(e1, e2, pt); - break; - case ClipType.ctXor: - AddLocalMinPoly(e1, e2, pt); - break; - } - else - SwapSides(e1, e2); - } - - if ((e1stops != e2stops) && - ((e1stops && (e1.outIdx >= 0)) || (e2stops && (e2.outIdx >= 0)))) - { - SwapSides(e1, e2); - SwapPolyIndexes(e1, e2); - } - - //finally, delete any non-contributing maxima edges ... - if (e1stops) DeleteFromAEL(e1); - if (e2stops) DeleteFromAEL(e2); - } - //------------------------------------------------------------------------------ - - private void DeleteFromAEL(TEdge e) - { - TEdge AelPrev = e.prevInAEL; - TEdge AelNext = e.nextInAEL; - if (AelPrev == null && AelNext == null && (e != m_ActiveEdges)) - return; //already deleted - if (AelPrev != null) - AelPrev.nextInAEL = AelNext; - else m_ActiveEdges = AelNext; - if (AelNext != null) - AelNext.prevInAEL = AelPrev; - e.nextInAEL = null; - e.prevInAEL = null; - } - //------------------------------------------------------------------------------ - - private void DeleteFromSEL(TEdge e) - { - TEdge SelPrev = e.prevInSEL; - TEdge SelNext = e.nextInSEL; - if (SelPrev == null && SelNext == null && (e != m_SortedEdges)) - return; //already deleted - if (SelPrev != null) - SelPrev.nextInSEL = SelNext; - else m_SortedEdges = SelNext; - if (SelNext != null) - SelNext.prevInSEL = SelPrev; - e.nextInSEL = null; - e.prevInSEL = null; - } - //------------------------------------------------------------------------------ - - private void UpdateEdgeIntoAEL(ref TEdge e) - { - if (e.nextInLML == null) - throw new ClipperException("UpdateEdgeIntoAEL: invalid call"); - TEdge AelPrev = e.prevInAEL; - TEdge AelNext = e.nextInAEL; - e.nextInLML.outIdx = e.outIdx; - if (AelPrev != null) - AelPrev.nextInAEL = e.nextInLML; - else m_ActiveEdges = e.nextInLML; - if (AelNext != null) - AelNext.prevInAEL = e.nextInLML; - e.nextInLML.side = e.side; - e.nextInLML.windDelta = e.windDelta; - e.nextInLML.windCnt = e.windCnt; - e.nextInLML.windCnt2 = e.windCnt2; - e = e.nextInLML; - e.prevInAEL = AelPrev; - e.nextInAEL = AelNext; - if (e.dx != horizontal) InsertScanbeam(e.ytop); - } - //------------------------------------------------------------------------------ - - private void ProcessHorizontals() - { - TEdge horzEdge = m_SortedEdges; - while (horzEdge != null) - { - DeleteFromSEL(horzEdge); - ProcessHorizontal(horzEdge); - horzEdge = m_SortedEdges; - } - } - //------------------------------------------------------------------------------ - - private void ProcessHorizontal(TEdge horzEdge) - { - Direction Direction; - Int64 horzLeft, horzRight; - - if (horzEdge.xcurr < horzEdge.xtop) - { - horzLeft = horzEdge.xcurr; - horzRight = horzEdge.xtop; - Direction = Direction.dLeftToRight; - } - else - { - horzLeft = horzEdge.xtop; - horzRight = horzEdge.xcurr; - Direction = Direction.dRightToLeft; - } - - TEdge eMaxPair; - if (horzEdge.nextInLML != null) - eMaxPair = null; - else - eMaxPair = GetMaximaPair(horzEdge); - - TEdge e = GetNextInAEL(horzEdge, Direction); - while (e != null) - { - if (e.xcurr == horzEdge.xtop && eMaxPair == null) - { - if (SlopesEqual(e, horzEdge.nextInLML, m_UseFullRange)) - { - //if output polygons share an edge, they'll need joining later ... - if (horzEdge.outIdx >= 0 && e.outIdx >= 0) - AddJoin(horzEdge.nextInLML, e, horzEdge.outIdx, -1); - break; //we've reached the end of the horizontal line - } - else if (e.dx < horzEdge.nextInLML.dx) - //we really have got to the end of the intermediate horz edge so quit. - //nb: More -ve slopes follow more +ve slopes ABOVE the horizontal. - break; - } - - TEdge eNext = GetNextInAEL(e, Direction); - if (eMaxPair != null || - ((Direction == Direction.dLeftToRight) && (e.xcurr < horzRight)) || - ((Direction == Direction.dRightToLeft) && (e.xcurr > horzLeft))) - { - //so far we're still in range of the horizontal edge - - if (e == eMaxPair) - { - //horzEdge is evidently a maxima horizontal and we've arrived at its end. - if (Direction == Direction.dLeftToRight) - IntersectEdges(horzEdge, e, new IntPoint(e.xcurr, horzEdge.ycurr), 0); - else - IntersectEdges(e, horzEdge, new IntPoint(e.xcurr, horzEdge.ycurr), 0); - if (eMaxPair.outIdx >= 0) throw new ClipperException("ProcessHorizontal error"); - return; - } - else if (e.dx == horizontal && !IsMinima(e) && !(e.xcurr > e.xtop)) - { - if (Direction == Direction.dLeftToRight) - IntersectEdges(horzEdge, e, new IntPoint(e.xcurr, horzEdge.ycurr), - (IsTopHorz(horzEdge, e.xcurr)) ? Protects.ipLeft : Protects.ipBoth); - else - IntersectEdges(e, horzEdge, new IntPoint(e.xcurr, horzEdge.ycurr), - (IsTopHorz(horzEdge, e.xcurr)) ? Protects.ipRight : Protects.ipBoth); - } - else if (Direction == Direction.dLeftToRight) - { - IntersectEdges(horzEdge, e, new IntPoint(e.xcurr, horzEdge.ycurr), - (IsTopHorz(horzEdge, e.xcurr)) ? Protects.ipLeft : Protects.ipBoth); - } - else - { - IntersectEdges(e, horzEdge, new IntPoint(e.xcurr, horzEdge.ycurr), - (IsTopHorz(horzEdge, e.xcurr)) ? Protects.ipRight : Protects.ipBoth); - } - SwapPositionsInAEL(horzEdge, e); - } - else if ( (Direction == Direction.dLeftToRight && e.xcurr >= horzRight) || - (Direction == Direction.dRightToLeft && e.xcurr <= horzLeft) ) break; - e = eNext; - } //end while ( e ) - - if (horzEdge.nextInLML != null) - { - if (horzEdge.outIdx >= 0) - AddOutPt(horzEdge, new IntPoint(horzEdge.xtop, horzEdge.ytop)); - UpdateEdgeIntoAEL(ref horzEdge); - } - else - { - if (horzEdge.outIdx >= 0) - IntersectEdges(horzEdge, eMaxPair, - new IntPoint(horzEdge.xtop, horzEdge.ycurr), Protects.ipBoth); - DeleteFromAEL(eMaxPair); - DeleteFromAEL(horzEdge); - } - } - //------------------------------------------------------------------------------ - - private bool IsTopHorz(TEdge horzEdge, double XPos) - { - TEdge e = m_SortedEdges; - while (e != null) - { - if ((XPos >= Math.Min(e.xcurr, e.xtop)) && (XPos <= Math.Max(e.xcurr, e.xtop))) - return false; - e = e.nextInSEL; - } - return true; - } - //------------------------------------------------------------------------------ - - private TEdge GetNextInAEL(TEdge e, Direction Direction) - { - return Direction == Direction.dLeftToRight ? e.nextInAEL: e.prevInAEL; - } - //------------------------------------------------------------------------------ - - private bool IsMinima(TEdge e) - { - return e != null && (e.prev.nextInLML != e) && (e.next.nextInLML != e); - } - //------------------------------------------------------------------------------ - - private bool IsMaxima(TEdge e, double Y) - { - return (e != null && e.ytop == Y && e.nextInLML == null); - } - //------------------------------------------------------------------------------ - - private bool IsIntermediate(TEdge e, double Y) - { - return (e.ytop == Y && e.nextInLML != null); - } - //------------------------------------------------------------------------------ - - private TEdge GetMaximaPair(TEdge e) - { - if (!IsMaxima(e.next, e.ytop) || (e.next.xtop != e.xtop)) - return e.prev; else - return e.next; - } - //------------------------------------------------------------------------------ - - private bool ProcessIntersections(Int64 botY, Int64 topY) - { - if( m_ActiveEdges == null ) return true; - try { - BuildIntersectList(botY, topY); - if ( m_IntersectNodes == null) return true; - if (m_IntersectNodes.next == null || FixupIntersectionOrder()) - ProcessIntersectList(); - else - return false; + AddOutPt(eMaxPair, e.Top); + eMaxPair.OutIdx = Unassigned; } - catch { - m_SortedEdges = null; - DisposeIntersectNodes(); - throw new ClipperException("ProcessIntersections error"); - } - m_SortedEdges = null; - return true; - } - //------------------------------------------------------------------------------ - - private void BuildIntersectList(Int64 botY, Int64 topY) - { - if ( m_ActiveEdges == null ) return; - - //prepare for sorting ... - TEdge e = m_ActiveEdges; - m_SortedEdges = e; - while( e != null ) + DeleteFromAEL(eMaxPair); + } +#endif + else throw new ClipperException("DoMaxima error"); + } + //------------------------------------------------------------------------------ + + public static void ReversePaths(Paths polys) + { + polys.ForEach(delegate(Path poly) { poly.Reverse(); }); + } + //------------------------------------------------------------------------------ + + public static bool Orientation(Path poly) + { + return Area(poly) >= 0; + } + //------------------------------------------------------------------------------ + + private int PointCount(OutPt pts) + { + if (pts == null) return 0; + int result = 0; + OutPt p = pts; + do { - e.prevInSEL = e.prevInAEL; - e.nextInSEL = e.nextInAEL; - e.xcurr = TopX( e, topY ); - e = e.nextInAEL; + result++; + p = p.Next; } - - //bubblesort ... - bool isModified = true; - while( isModified && m_SortedEdges != null ) + while (p != pts); + return result; + } + //------------------------------------------------------------------------------ + + private void BuildResult(Paths polyg) + { + polyg.Clear(); + polyg.Capacity = m_PolyOuts.Count; + for (int i = 0; i < m_PolyOuts.Count; i++) { - isModified = false; - e = m_SortedEdges; - while( e.nextInSEL != null ) - { - TEdge eNext = e.nextInSEL; - IntPoint pt = new IntPoint(); - if (e.xcurr > eNext.xcurr) + OutRec outRec = m_PolyOuts[i]; + if (outRec.Pts == null) continue; + OutPt p = outRec.Pts; + int cnt = PointCount(p); + if (cnt < 2) continue; + Path pg = new Path(cnt); + for (int j = 0; j < cnt; j++) { - if (!IntersectPoint(e, eNext, ref pt) && e.xcurr > eNext.xcurr +1) - throw new ClipperException("Intersection error"); - if (pt.Y > botY) - { - pt.Y = botY; - pt.X = TopX(e, pt.Y); - } - InsertIntersectNode(e, eNext, pt); - SwapPositionsInSEL(e, eNext); - isModified = true; + pg.Add(p.Pt); + p = p.Prev; } - else - e = eNext; - } - if( e.prevInSEL != null ) e.prevInSEL.nextInSEL = null; - else break; - } - m_SortedEdges = null; - } - //------------------------------------------------------------------------------ - - private bool EdgesAdjacent(IntersectNode inode) - { - return (inode.edge1.nextInSEL == inode.edge2) || - (inode.edge1.prevInSEL == inode.edge2); - } - //------------------------------------------------------------------------------ - - private bool FixupIntersectionOrder() - { - //pre-condition: intersections are sorted bottom-most (then left-most) first. - //Now it's crucial that intersections are made only between adjacent edges, - //so to ensure this the order of intersections may need adjusting ... - IntersectNode inode = m_IntersectNodes; - CopyAELToSEL(); - while (inode != null) - { - if (!EdgesAdjacent(inode)) - { - IntersectNode nextNode = inode.next; - while (nextNode != null && !EdgesAdjacent(nextNode)) - nextNode = nextNode.next; - if (nextNode == null) - return false; - SwapIntersectNodes(inode, nextNode); - } - SwapPositionsInSEL(inode.edge1, inode.edge2); - inode = inode.next; - } - return true; - } - //------------------------------------------------------------------------------ - - private void ProcessIntersectList() - { - while (m_IntersectNodes != null) - { - IntersectNode iNode = m_IntersectNodes.next; - { - IntersectEdges( m_IntersectNodes.edge1 , - m_IntersectNodes.edge2 , m_IntersectNodes.pt, Protects.ipBoth ); - SwapPositionsInAEL( m_IntersectNodes.edge1 , m_IntersectNodes.edge2 ); - } - m_IntersectNodes = null; - m_IntersectNodes = iNode; - } - } - //------------------------------------------------------------------------------ - - private static Int64 Round(double value) - { - return value < 0 ? (Int64)(value - 0.5) : (Int64)(value + 0.5); - } - //------------------------------------------------------------------------------ - - private static Int64 TopX(TEdge edge, Int64 currentY) - { - if (currentY == edge.ytop) - return edge.xtop; - return edge.xbot + Round(edge.dx *(currentY - edge.ybot)); - } - //------------------------------------------------------------------------------ - - private void InsertIntersectNode(TEdge e1, TEdge e2, IntPoint pt) - { - IntersectNode newNode = new IntersectNode(); - newNode.edge1 = e1; - newNode.edge2 = e2; - newNode.pt = pt; - newNode.next = null; - if (m_IntersectNodes == null) m_IntersectNodes = newNode; - else if (newNode.pt.Y > m_IntersectNodes.pt.Y) - { - newNode.next = m_IntersectNodes; - m_IntersectNodes = newNode; + polyg.Add(pg); } - else - { - IntersectNode iNode = m_IntersectNodes; - while (iNode.next != null && newNode.pt.Y < iNode.next.pt.Y) - iNode = iNode.next; - newNode.next = iNode.next; - iNode.next = newNode; - } - } - //------------------------------------------------------------------------------ + } + //------------------------------------------------------------------------------ - private void SwapIntersectNodes(IntersectNode int1, IntersectNode int2) - { - TEdge e1 = int1.edge1; - TEdge e2 = int1.edge2; - IntPoint p = int1.pt; - int1.edge1 = int2.edge1; - int1.edge2 = int2.edge2; - int1.pt = int2.pt; - int2.edge1 = e1; - int2.edge2 = e2; - int2.pt = p; - } - //------------------------------------------------------------------------------ + private void BuildResult2(PolyTree polytree) + { + polytree.Clear(); - private bool IntersectPoint(TEdge edge1, TEdge edge2, ref IntPoint ip) - { - double b1, b2; - if (SlopesEqual(edge1, edge2, m_UseFullRange)) - { - if (edge2.ybot > edge1.ybot) - ip.Y = edge2.ybot; - else - ip.Y = edge1.ybot; - return false; - } - else if (edge1.dx == 0) - { - ip.X = edge1.xbot; - if (edge2.dx == horizontal) - { - ip.Y = edge2.ybot; - } - else - { - b2 = edge2.ybot - (edge2.xbot / edge2.dx); - ip.Y = Round(ip.X / edge2.dx + b2); - } - } - else if (edge2.dx == 0) + //add each output polygon/contour to polytree ... + polytree.m_AllPolys.Capacity = m_PolyOuts.Count; + for (int i = 0; i < m_PolyOuts.Count; i++) { - ip.X = edge2.xbot; - if (edge1.dx == horizontal) + OutRec outRec = m_PolyOuts[i]; + int cnt = PointCount(outRec.Pts); + if ((outRec.IsOpen && cnt < 2) || + (!outRec.IsOpen && cnt < 3)) continue; + FixHoleLinkage(outRec); + PolyNode pn = new PolyNode(); + polytree.m_AllPolys.Add(pn); + outRec.PolyNode = pn; + pn.m_polygon.Capacity = cnt; + OutPt op = outRec.Pts.Prev; + for (int j = 0; j < cnt; j++) { - ip.Y = edge1.ybot; + pn.m_polygon.Add(op.Pt); + op = op.Prev; } - else - { - b1 = edge1.ybot - (edge1.xbot / edge1.dx); - ip.Y = Round(ip.X / edge1.dx + b1); - } - } - else - { - b1 = edge1.xbot - edge1.ybot * edge1.dx; - b2 = edge2.xbot - edge2.ybot * edge2.dx; - double q = (b2 - b1) / (edge1.dx - edge2.dx); - ip.Y = Round(q); - if (Math.Abs(edge1.dx) < Math.Abs(edge2.dx)) - ip.X = Round(edge1.dx * q + b1); - else - ip.X = Round(edge2.dx * q + b2); } - if (ip.Y < edge1.ytop || ip.Y < edge2.ytop) + //fixup PolyNode links etc ... + polytree.m_Childs.Capacity = m_PolyOuts.Count; + for (int i = 0; i < m_PolyOuts.Count; i++) { - if (edge1.ytop > edge2.ytop) + OutRec outRec = m_PolyOuts[i]; + if (outRec.PolyNode == null) continue; + else if (outRec.IsOpen) { - ip.X = edge1.xtop; - ip.Y = edge1.ytop; - return TopX(edge2, edge1.ytop) < edge1.xtop; + outRec.PolyNode.IsOpen = true; + polytree.AddChild(outRec.PolyNode); } + else if (outRec.FirstLeft != null) + outRec.FirstLeft.PolyNode.AddChild(outRec.PolyNode); else - { - ip.X = edge2.xtop; - ip.Y = edge2.ytop; - return TopX(edge1, edge2.ytop) > edge2.xtop; - } - } - else - return true; - } - //------------------------------------------------------------------------------ - - private void DisposeIntersectNodes() - { - while ( m_IntersectNodes != null ) - { - IntersectNode iNode = m_IntersectNodes.next; - m_IntersectNodes = null; - m_IntersectNodes = iNode; + polytree.AddChild(outRec.PolyNode); } - } - //------------------------------------------------------------------------------ - - private void ProcessEdgesAtTopOfScanbeam(Int64 topY) - { - TEdge e = m_ActiveEdges; - while( e != null ) + } + //------------------------------------------------------------------------------ + + private void FixupOutPolygon(OutRec outRec) + { + //FixupOutPolygon() - removes duplicate points and simplifies consecutive + //parallel edges by removing the middle vertex. + OutPt lastOK = null; + outRec.BottomPt = null; + OutPt pp = outRec.Pts; + for (;;) { - //1. process maxima, treating them as if they're 'bent' horizontal edges, - // but exclude maxima with horizontal edges. nb: e can't be a horizontal. - if( IsMaxima(e, topY) && GetMaximaPair(e).dx != horizontal ) - { - //'e' might be removed from AEL, as may any following edges so ... - TEdge ePrev = e.prevInAEL; - DoMaxima(e, topY); - if( ePrev == null ) e = m_ActiveEdges; - else e = ePrev.nextInAEL; - } - else - { - bool intermediateVert = IsIntermediate(e, topY); - //2. promote horizontal edges, otherwise update xcurr and ycurr ... - if (intermediateVert && e.nextInLML.dx == horizontal) - { - if (e.outIdx >= 0) - { - AddOutPt(e, new IntPoint(e.xtop, e.ytop)); - - for (int i = 0; i < m_HorizJoins.Count; ++i) - { - IntPoint pt = new IntPoint(), pt2 = new IntPoint(); - HorzJoinRec hj = m_HorizJoins[i]; - if (GetOverlapSegment(new IntPoint(hj.edge.xbot, hj.edge.ybot), - new IntPoint(hj.edge.xtop, hj.edge.ytop), - new IntPoint(e.nextInLML.xbot, e.nextInLML.ybot), - new IntPoint(e.nextInLML.xtop, e.nextInLML.ytop), ref pt, ref pt2)) - AddJoin(hj.edge, e.nextInLML, hj.savedIdx, e.outIdx); - } - - AddHorzJoin(e.nextInLML, e.outIdx); - } - UpdateEdgeIntoAEL(ref e); - AddEdgeToSEL(e); - } - else + if (pp.Prev == pp || pp.Prev == pp.Next) { - e.xcurr = TopX( e, topY ); - e.ycurr = topY; - if (m_ForceSimple && e.prevInAEL != null && - e.prevInAEL.xcurr == e.xcurr && - e.outIdx >= 0 && e.prevInAEL.outIdx >= 0) - { - if (intermediateVert) - AddOutPt(e.prevInAEL, new IntPoint(e.xcurr, topY)); - else - AddOutPt(e, new IntPoint(e.xcurr, topY)); - } + DisposeOutPts(pp); + outRec.Pts = null; + return; } - e = e.nextInAEL; - } - } - - //3. Process horizontals at the top of the scanbeam ... - ProcessHorizontals(); - - //4. Promote intermediate vertices ... - e = m_ActiveEdges; - while( e != null ) - { - if( IsIntermediate( e, topY ) ) - { - if (e.outIdx >= 0) AddOutPt(e, new IntPoint(e.xtop, e.ytop)); - UpdateEdgeIntoAEL(ref e); - - //if output polygons share an edge, they'll need joining later ... - TEdge ePrev = e.prevInAEL; - TEdge eNext = e.nextInAEL; - if (ePrev != null && ePrev.xcurr == e.xbot && - ePrev.ycurr == e.ybot && e.outIdx >= 0 && - ePrev.outIdx >= 0 && ePrev.ycurr > ePrev.ytop && - SlopesEqual(e, ePrev, m_UseFullRange)) + //test for duplicate points and collinear edges ... + if ((pp.Pt == pp.Next.Pt) || (pp.Pt == pp.Prev.Pt) || + (SlopesEqual(pp.Prev.Pt, pp.Pt, pp.Next.Pt, m_UseFullRange) && + (!PreserveCollinear || !Pt2IsBetweenPt1AndPt3(pp.Prev.Pt, pp.Pt, pp.Next.Pt)))) { - AddOutPt(ePrev, new IntPoint(e.xbot, e.ybot)); - AddJoin(e, ePrev, -1, -1); + lastOK = null; + OutPt tmp = pp; + pp.Prev.Next = pp.Next; + pp.Next.Prev = pp.Prev; + pp = pp.Prev; + tmp = null; } - else if (eNext != null && eNext.xcurr == e.xbot && - eNext.ycurr == e.ybot && e.outIdx >= 0 && - eNext.outIdx >= 0 && eNext.ycurr > eNext.ytop && - SlopesEqual(e, eNext, m_UseFullRange)) + else if (pp == lastOK) break; + else { - AddOutPt(eNext, new IntPoint(e.xbot, e.ybot)); - AddJoin(e, eNext, -1, -1); - } - } - e = e.nextInAEL; - } - } - //------------------------------------------------------------------------------ - - private void DoMaxima(TEdge e, Int64 topY) - { - TEdge eMaxPair = GetMaximaPair(e); - Int64 X = e.xtop; - TEdge eNext = e.nextInAEL; - while( eNext != eMaxPair ) - { - if (eNext == null) throw new ClipperException("DoMaxima error"); - IntersectEdges( e, eNext, new IntPoint(X, topY), Protects.ipBoth ); - SwapPositionsInAEL(e, eNext); - eNext = e.nextInAEL; - } - if( e.outIdx < 0 && eMaxPair.outIdx < 0 ) - { - DeleteFromAEL( e ); - DeleteFromAEL( eMaxPair ); - } - else if( e.outIdx >= 0 && eMaxPair.outIdx >= 0 ) - { - IntersectEdges(e, eMaxPair, new IntPoint(X, topY), Protects.ipNone); - } - else throw new ClipperException("DoMaxima error"); - } - //------------------------------------------------------------------------------ - - public static void ReversePolygons(Polygons polys) - { - polys.ForEach(delegate(Polygon poly) { poly.Reverse(); }); - } - //------------------------------------------------------------------------------ - - public static bool Orientation(Polygon poly) - { - return Area(poly) >= 0; - } - //------------------------------------------------------------------------------ - - private int PointCount(OutPt pts) - { - if (pts == null) return 0; - int result = 0; - OutPt p = pts; - do - { - result++; - p = p.next; - } - while (p != pts); - return result; - } - //------------------------------------------------------------------------------ - - private void BuildResult(Polygons polyg) - { - polyg.Clear(); - polyg.Capacity = m_PolyOuts.Count; - for (int i = 0; i < m_PolyOuts.Count; i++) - { - OutRec outRec = m_PolyOuts[i]; - if (outRec.pts == null) continue; - OutPt p = outRec.pts; - int cnt = PointCount(p); - if (cnt < 3) continue; - Polygon pg = new Polygon(cnt); - for (int j = 0; j < cnt; j++) - { - pg.Add(p.pt); - p = p.prev; - } - polyg.Add(pg); - } - } - //------------------------------------------------------------------------------ - - private void BuildResult2(PolyTree polytree) - { - polytree.Clear(); - - //add each output polygon/contour to polytree ... - polytree.m_AllPolys.Capacity = m_PolyOuts.Count; - for (int i = 0; i < m_PolyOuts.Count; i++) - { - OutRec outRec = m_PolyOuts[i]; - int cnt = PointCount(outRec.pts); - if (cnt < 3) continue; - FixHoleLinkage(outRec); - PolyNode pn = new PolyNode(); - polytree.m_AllPolys.Add(pn); - outRec.polyNode = pn; - pn.m_polygon.Capacity = cnt; - OutPt op = outRec.pts; - for (int j = 0; j < cnt; j++) - { - pn.m_polygon.Add(op.pt); - op = op.prev; - } - } - - //fixup PolyNode links etc ... - polytree.m_Childs.Capacity = m_PolyOuts.Count; - for (int i = 0; i < m_PolyOuts.Count; i++) - { - OutRec outRec = m_PolyOuts[i]; - if (outRec.polyNode == null) continue; - if (outRec.FirstLeft == null) - polytree.AddChild(outRec.polyNode); - else - outRec.FirstLeft.polyNode.AddChild(outRec.polyNode); - } - } - //------------------------------------------------------------------------------ - - private void FixupOutPolygon(OutRec outRec) - { - //FixupOutPolygon() - removes duplicate points and simplifies consecutive - //parallel edges by removing the middle vertex. - OutPt lastOK = null; - outRec.bottomPt = null; - OutPt pp = outRec.pts; - for (;;) - { - if (pp.prev == pp || pp.prev == pp.next) - { - DisposeOutPts(pp); - outRec.pts = null; - return; - } - //test for duplicate points and for same slope (cross-product) ... - if (PointsEqual(pp.pt, pp.next.pt) || - SlopesEqual(pp.prev.pt, pp.pt, pp.next.pt, m_UseFullRange)) - { - lastOK = null; - OutPt tmp = pp; - pp.prev.next = pp.next; - pp.next.prev = pp.prev; - pp = pp.prev; - tmp = null; - } - else if (pp == lastOK) break; - else - { - if (lastOK == null) lastOK = pp; - pp = pp.next; - } - } - outRec.pts = pp; - } - //------------------------------------------------------------------------------ - - private bool JoinPoints(JoinRec j, out OutPt p1, out OutPt p2) - { - p1 = null; p2 = null; - OutRec outRec1 = m_PolyOuts[j.poly1Idx]; - OutRec outRec2 = m_PolyOuts[j.poly2Idx]; - if (outRec1 == null || outRec2 == null) return false; - OutPt pp1a = outRec1.pts; - OutPt pp2a = outRec2.pts; - IntPoint pt1 = j.pt2a, pt2 = j.pt2b; - IntPoint pt3 = j.pt1a, pt4 = j.pt1b; - if (!FindSegment(ref pp1a, m_UseFullRange, ref pt1, ref pt2)) return false; - if (outRec1 == outRec2) - { - //we're searching the same polygon for overlapping segments so - //segment 2 mustn't be the same as segment 1 ... - pp2a = pp1a.next; - if (!FindSegment(ref pp2a, m_UseFullRange, ref pt3, ref pt4) || (pp2a == pp1a)) - return false; - } - else if (!FindSegment(ref pp2a, m_UseFullRange, ref pt3, ref pt4)) return false; - - if (!GetOverlapSegment(pt1, pt2, pt3, pt4, ref pt1, ref pt2)) return false; - - OutPt p3, p4, prev = pp1a.prev; - //get p1 & p2 polypts - the overlap start & endpoints on poly1 - if (PointsEqual(pp1a.pt, pt1)) p1 = pp1a; - else if (PointsEqual(prev.pt, pt1)) p1 = prev; - else p1 = InsertPolyPtBetween(pp1a, prev, pt1); - - if (PointsEqual(pp1a.pt, pt2)) p2 = pp1a; - else if (PointsEqual(prev.pt, pt2)) p2 = prev; - else if ((p1 == pp1a) || (p1 == prev)) - p2 = InsertPolyPtBetween(pp1a, prev, pt2); - else if (Pt3IsBetweenPt1AndPt2(pp1a.pt, p1.pt, pt2)) - p2 = InsertPolyPtBetween(pp1a, p1, pt2); else - p2 = InsertPolyPtBetween(p1, prev, pt2); - - //get p3 & p4 polypts - the overlap start & endpoints on poly2 - prev = pp2a.prev; - if (PointsEqual(pp2a.pt, pt1)) p3 = pp2a; - else if (PointsEqual(prev.pt, pt1)) p3 = prev; - else p3 = InsertPolyPtBetween(pp2a, prev, pt1); - - if (PointsEqual(pp2a.pt, pt2)) p4 = pp2a; - else if (PointsEqual(prev.pt, pt2)) p4 = prev; - else if ((p3 == pp2a) || (p3 == prev)) - p4 = InsertPolyPtBetween(pp2a, prev, pt2); - else if (Pt3IsBetweenPt1AndPt2(pp2a.pt, p3.pt, pt2)) - p4 = InsertPolyPtBetween(pp2a, p3, pt2); else - p4 = InsertPolyPtBetween(p3, prev, pt2); - - //p1.pt == p3.pt and p2.pt == p4.pt so join p1 to p3 and p2 to p4 ... - if (p1.next == p2 && p3.prev == p4) - { - p1.next = p3; - p3.prev = p1; - p2.prev = p4; - p4.next = p2; - return true; - } - else if (p1.prev == p2 && p3.next == p4) - { - p1.prev = p3; - p3.next = p1; - p2.next = p4; - p4.prev = p2; - return true; - } - else - return false; //an orientation is probably wrong - } - //---------------------------------------------------------------------- - - private void FixupJoinRecs(JoinRec j, OutPt pt, int startIdx) - { - for (int k = startIdx; k < m_Joins.Count; k++) - { - JoinRec j2 = m_Joins[k]; - if (j2.poly1Idx == j.poly1Idx && PointIsVertex(j2.pt1a, pt)) - j2.poly1Idx = j.poly2Idx; - if (j2.poly2Idx == j.poly1Idx && PointIsVertex(j2.pt2a, pt)) - j2.poly2Idx = j.poly2Idx; - } - } - //---------------------------------------------------------------------- - - private bool Poly2ContainsPoly1(OutPt outPt1, OutPt outPt2, bool UseFullInt64Range) - { - OutPt pt = outPt1; - //Because the polygons may be touching, we need to find a vertex that - //isn't touching the other polygon ... - if (PointOnPolygon(pt.pt, outPt2, UseFullInt64Range)) - { - pt = pt.next; - while (pt != outPt1 && PointOnPolygon(pt.pt, outPt2, UseFullInt64Range)) - pt = pt.next; - if (pt == outPt1) return true; - } - return PointInPolygon(pt.pt, outPt2, UseFullInt64Range); - } - //---------------------------------------------------------------------- - - private void FixupFirstLefts1(OutRec OldOutRec, OutRec NewOutRec) - { - for (int i = 0; i < m_PolyOuts.Count; i++) - { - OutRec outRec = m_PolyOuts[i]; - if (outRec.pts != null && outRec.FirstLeft == OldOutRec) - { - if (Poly2ContainsPoly1(outRec.pts, NewOutRec.pts, m_UseFullRange)) - outRec.FirstLeft = NewOutRec; - } - } - } - //---------------------------------------------------------------------- - - private void FixupFirstLefts2(OutRec OldOutRec, OutRec NewOutRec) - { - foreach (OutRec outRec in m_PolyOuts) - if (outRec.FirstLeft == OldOutRec) outRec.FirstLeft = NewOutRec; - } - //---------------------------------------------------------------------- - - private void JoinCommonEdges() - { - for (int i = 0; i < m_Joins.Count; i++) - { - JoinRec j = m_Joins[i]; - - OutRec outRec1 = GetOutRec(j.poly1Idx); - OutRec outRec2 = GetOutRec(j.poly2Idx); - - if (outRec1.pts == null || outRec2.pts == null) continue; - - //get the polygon fragment with the correct hole state (FirstLeft) - //before calling JoinPoints() ... - OutRec holeStateRec; - if (outRec1 == outRec2) holeStateRec = outRec1; - else if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2; - else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1; - else holeStateRec = GetLowermostRec(outRec1, outRec2); - - OutPt p1, p2; - if (!JoinPoints(j, out p1, out p2)) continue; - - if (outRec1 == outRec2) - { - //instead of joining two polygons, we've just created a new one by - //splitting one polygon into two. - outRec1.pts = p1; - outRec1.bottomPt = null; - outRec2 = CreateOutRec(); - outRec2.pts = p2; - - if (Poly2ContainsPoly1(outRec2.pts, outRec1.pts, m_UseFullRange)) - { - //outRec2 is contained by outRec1 ... - outRec2.isHole = !outRec1.isHole; - outRec2.FirstLeft = outRec1; - - FixupJoinRecs(j, p2, i + 1); - - //fixup FirstLeft pointers that may need reassigning to OutRec1 - if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); - - FixupOutPolygon(outRec1); //nb: do this BEFORE testing orientation - FixupOutPolygon(outRec2); // but AFTER calling FixupJoinRecs() - - if ((outRec2.isHole ^ m_ReverseOutput) == (Area(outRec2, m_UseFullRange) > 0)) - ReversePolyPtLinks(outRec2.pts); - - } - else if (Poly2ContainsPoly1(outRec1.pts, outRec2.pts, m_UseFullRange)) - { - //outRec1 is contained by outRec2 ... - outRec2.isHole = outRec1.isHole; - outRec1.isHole = !outRec2.isHole; - outRec2.FirstLeft = outRec1.FirstLeft; - outRec1.FirstLeft = outRec2; - - FixupJoinRecs(j, p2, i + 1); - - //fixup FirstLeft pointers that may need reassigning to OutRec1 - if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2); - - FixupOutPolygon(outRec1); //nb: do this BEFORE testing orientation - FixupOutPolygon(outRec2); // but AFTER calling FixupJoinRecs() - - if ((outRec1.isHole ^ m_ReverseOutput) == (Area(outRec1, m_UseFullRange) > 0)) - ReversePolyPtLinks(outRec1.pts); - } - else - { - //the 2 polygons are completely separate ... - outRec2.isHole = outRec1.isHole; - outRec2.FirstLeft = outRec1.FirstLeft; - - FixupJoinRecs(j, p2, i + 1); - - //fixup FirstLeft pointers that may need reassigning to OutRec2 - if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2); - - FixupOutPolygon(outRec1); //nb: do this BEFORE testing orientation - FixupOutPolygon(outRec2); // but AFTER calling FixupJoinRecs() - } - } - else - { - //joined 2 polygons together ... - - //cleanup redundant edges ... - FixupOutPolygon(outRec1); - - outRec2.pts = null; - outRec2.bottomPt = null; - outRec2.idx = outRec1.idx; + if (lastOK == null) lastOK = pp; + pp = pp.Next; + } + } + outRec.Pts = pp; + } + //------------------------------------------------------------------------------ + + OutPt DupOutPt(OutPt outPt, bool InsertAfter) + { + OutPt result = new OutPt(); + result.Pt = outPt.Pt; + result.Idx = outPt.Idx; + if (InsertAfter) + { + result.Next = outPt.Next; + result.Prev = outPt; + outPt.Next.Prev = result; + outPt.Next = result; + } + else + { + result.Prev = outPt.Prev; + result.Next = outPt; + outPt.Prev.Next = result; + outPt.Prev = result; + } + return result; + } + //------------------------------------------------------------------------------ + + bool GetOverlap(cInt a1, cInt a2, cInt b1, cInt b2, out cInt Left, out cInt Right) + { + if (a1 < a2) + { + if (b1 < b2) {Left = Math.Max(a1,b1); Right = Math.Min(a2,b2);} + else {Left = Math.Max(a1,b2); Right = Math.Min(a2,b1);} + } + else + { + if (b1 < b2) {Left = Math.Max(a2,b1); Right = Math.Min(a1,b2);} + else { Left = Math.Max(a2, b2); Right = Math.Min(a1, b1); } + } + return Left < Right; + } + //------------------------------------------------------------------------------ + + bool JoinHorz(OutPt op1, OutPt op1b, OutPt op2, OutPt op2b, + IntPoint Pt, bool DiscardLeft) + { + Direction Dir1 = (op1.Pt.X > op1b.Pt.X ? + Direction.dRightToLeft : Direction.dLeftToRight); + Direction Dir2 = (op2.Pt.X > op2b.Pt.X ? + Direction.dRightToLeft : Direction.dLeftToRight); + if (Dir1 == Dir2) return false; + + //When DiscardLeft, we want Op1b to be on the Left of Op1, otherwise we + //want Op1b to be on the Right. (And likewise with Op2 and Op2b.) + //So, to facilitate this while inserting Op1b and Op2b ... + //when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b, + //otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.) + if (Dir1 == Direction.dLeftToRight) + { + while (op1.Next.Pt.X <= Pt.X && + op1.Next.Pt.X >= op1.Pt.X && op1.Next.Pt.Y == Pt.Y) + op1 = op1.Next; + if (DiscardLeft && (op1.Pt.X != Pt.X)) op1 = op1.Next; + op1b = DupOutPt(op1, !DiscardLeft); + if (op1b.Pt != Pt) + { + op1 = op1b; + op1.Pt = Pt; + op1b = DupOutPt(op1, !DiscardLeft); + } + } + else + { + while (op1.Next.Pt.X >= Pt.X && + op1.Next.Pt.X <= op1.Pt.X && op1.Next.Pt.Y == Pt.Y) + op1 = op1.Next; + if (!DiscardLeft && (op1.Pt.X != Pt.X)) op1 = op1.Next; + op1b = DupOutPt(op1, DiscardLeft); + if (op1b.Pt != Pt) + { + op1 = op1b; + op1.Pt = Pt; + op1b = DupOutPt(op1, DiscardLeft); + } + } - outRec1.isHole = holeStateRec.isHole; - if (holeStateRec == outRec2) - outRec1.FirstLeft = outRec2.FirstLeft; - outRec2.FirstLeft = outRec1; + if (Dir2 == Direction.dLeftToRight) + { + while (op2.Next.Pt.X <= Pt.X && + op2.Next.Pt.X >= op2.Pt.X && op2.Next.Pt.Y == Pt.Y) + op2 = op2.Next; + if (DiscardLeft && (op2.Pt.X != Pt.X)) op2 = op2.Next; + op2b = DupOutPt(op2, !DiscardLeft); + if (op2b.Pt != Pt) + { + op2 = op2b; + op2.Pt = Pt; + op2b = DupOutPt(op2, !DiscardLeft); + }; + } else + { + while (op2.Next.Pt.X >= Pt.X && + op2.Next.Pt.X <= op2.Pt.X && op2.Next.Pt.Y == Pt.Y) + op2 = op2.Next; + if (!DiscardLeft && (op2.Pt.X != Pt.X)) op2 = op2.Next; + op2b = DupOutPt(op2, DiscardLeft); + if (op2b.Pt != Pt) + { + op2 = op2b; + op2.Pt = Pt; + op2b = DupOutPt(op2, DiscardLeft); + }; + }; - //fixup FirstLeft pointers that may need reassigning to OutRec1 - if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); - } + if ((Dir1 == Direction.dLeftToRight) == DiscardLeft) + { + op1.Prev = op2; + op2.Next = op1; + op1b.Next = op2b; + op2b.Prev = op1b; + } + else + { + op1.Next = op2; + op2.Prev = op1; + op1b.Prev = op2b; + op2b.Next = op1b; + } + return true; + } + //------------------------------------------------------------------------------ + + private bool JoinPoints(Join j, out OutPt p1, out OutPt p2) + { + OutRec outRec1 = GetOutRec(j.OutPt1.Idx); + OutRec outRec2 = GetOutRec(j.OutPt2.Idx); + OutPt op1 = j.OutPt1, op1b; + OutPt op2 = j.OutPt2, op2b; + p1 = null; p2 = null; + + //There are 3 kinds of joins for output polygons ... + //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are a vertices anywhere + //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal). + //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same + //location at the Bottom of the overlapping segment (& Join.OffPt is above). + //3. StrictlySimple joins where edges touch but are not collinear and where + //Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point. + bool isHorizontal = (j.OutPt1.Pt.Y == j.OffPt.Y); + + if (isHorizontal && (j.OffPt == j.OutPt1.Pt) && (j.OffPt == j.OutPt2.Pt)) + { + //Strictly Simple join ... + op1b = j.OutPt1.Next; + while (op1b != op1 && (op1b.Pt == j.OffPt)) + op1b = op1b.Next; + bool reverse1 = (op1b.Pt.Y > j.OffPt.Y); + op2b = j.OutPt2.Next; + while (op2b != op2 && (op2b.Pt == j.OffPt)) + op2b = op2b.Next; + bool reverse2 = (op2b.Pt.Y > j.OffPt.Y); + if (reverse1 == reverse2) return false; + if (reverse1) + { + op1b = DupOutPt(op1, false); + op2b = DupOutPt(op2, true); + op1.Prev = op2; + op2.Next = op1; + op1b.Next = op2b; + op2b.Prev = op1b; + p1 = op1; + p2 = op1b; + return true; + } else + { + op1b = DupOutPt(op1, true); + op2b = DupOutPt(op2, false); + op1.Next = op2; + op2.Prev = op1; + op1b.Prev = op2b; + op2b.Next = op1b; + p1 = op1; + p2 = op1b; + return true; } - } - //------------------------------------------------------------------------------ + } + else if (isHorizontal) + { + //treat horizontal joins differently to non-horizontal joins since with + //them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt + //may be anywhere along the horizontal edge. + op1b = op1; + while (op1.Prev.Pt.Y == op1.Pt.Y && op1.Prev != op1b && op1.Prev != op2) + op1 = op1.Prev; + while (op1b.Next.Pt.Y == op1b.Pt.Y && op1b.Next != op1 && op1b.Next != op2) + op1b = op1b.Next; + if (op1b.Next == op1 || op1b.Next == op2) return false; //a flat 'polygon' + + op2b = op2; + while (op2.Prev.Pt.Y == op2.Pt.Y && op2.Prev != op2b && op2.Prev != op1b) + op2 = op2.Prev; + while (op2b.Next.Pt.Y == op2b.Pt.Y && op2b.Next != op2 && op2b.Next != op1) + op2b = op2b.Next; + if (op2b.Next == op2 || op2b.Next == op1) return false; //a flat 'polygon' + + cInt Left, Right; + //Op1 -. Op1b & Op2 -. Op2b are the extremites of the horizontal edges + if (!GetOverlap(op1.Pt.X, op1b.Pt.X, op2.Pt.X, op2b.Pt.X, out Left, out Right)) + return false; - private void UpdateOutPtIdxs(OutRec outrec) - { - OutPt op = outrec.pts; - do + //DiscardLeftSide: when overlapping edges are joined, a spike will created + //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up + //on the discard Side as either may still be needed for other joins ... + IntPoint Pt; + bool DiscardLeftSide; + if (op1.Pt.X >= Left && op1.Pt.X <= Right) + { + Pt = op1.Pt; DiscardLeftSide = (op1.Pt.X > op1b.Pt.X); + } + else if (op2.Pt.X >= Left&& op2.Pt.X <= Right) + { + Pt = op2.Pt; DiscardLeftSide = (op2.Pt.X > op2b.Pt.X); + } + else if (op1b.Pt.X >= Left && op1b.Pt.X <= Right) + { + Pt = op1b.Pt; DiscardLeftSide = op1b.Pt.X > op1.Pt.X; + } + else { - op.idx = outrec.idx; - op = op.prev; + Pt = op2b.Pt; DiscardLeftSide = (op2b.Pt.X > op2.Pt.X); + } + p1 = op1; p2 = op2; + return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide); + } else + { + //nb: For non-horizontal joins ... + // 1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y + // 2. Jr.OutPt1.Pt > Jr.OffPt.Y + + //make sure the polygons are correctly oriented ... + op1b = op1.Next; + while ((op1b.Pt == op1.Pt) && (op1b != op1)) op1b = op1b.Next; + bool Reverse1 = ((op1b.Pt.Y > op1.Pt.Y) || + !SlopesEqual(op1.Pt, op1b.Pt, j.OffPt, m_UseFullRange)); + if (Reverse1) + { + op1b = op1.Prev; + while ((op1b.Pt == op1.Pt) && (op1b != op1)) op1b = op1b.Prev; + if ((op1b.Pt.Y > op1.Pt.Y) || + !SlopesEqual(op1.Pt, op1b.Pt, j.OffPt, m_UseFullRange)) return false; + }; + op2b = op2.Next; + while ((op2b.Pt == op2.Pt) && (op2b != op2)) op2b = op2b.Next; + bool Reverse2 = ((op2b.Pt.Y > op2.Pt.Y) || + !SlopesEqual(op2.Pt, op2b.Pt, j.OffPt, m_UseFullRange)); + if (Reverse2) + { + op2b = op2.Prev; + while ((op2b.Pt == op2.Pt) && (op2b != op2)) op2b = op2b.Prev; + if ((op2b.Pt.Y > op2.Pt.Y) || + !SlopesEqual(op2.Pt, op2b.Pt, j.OffPt, m_UseFullRange)) return false; } - while(op != outrec.pts); - } - //------------------------------------------------------------------------------ - private void DoSimplePolygons() - { - int i = 0; - while (i < m_PolyOuts.Count) + if ((op1b == op1) || (op2b == op2) || (op1b == op2b) || + ((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false; + + if (Reverse1) { - OutRec outrec = m_PolyOuts[i++]; - OutPt op = outrec.pts; - if (op == null) continue; - do //for each Pt in Polygon until duplicate found do ... - { - OutPt op2 = op.next; - while (op2 != outrec.pts) - { - if (PointsEqual(op.pt, op2.pt) && op2.next != op && op2.prev != op) - { - //split the polygon into two ... - OutPt op3 = op.prev; - OutPt op4 = op2.prev; - op.prev = op4; - op4.next = op; - op2.prev = op3; - op3.next = op2; - - outrec.pts = op; - OutRec outrec2 = CreateOutRec(); - outrec2.pts = op2; - UpdateOutPtIdxs(outrec2); - if (Poly2ContainsPoly1(outrec2.pts, outrec.pts, m_UseFullRange)) - { - //OutRec2 is contained by OutRec1 ... - outrec2.isHole = !outrec.isHole; - outrec2.FirstLeft = outrec; - } - else - if (Poly2ContainsPoly1(outrec.pts, outrec2.pts, m_UseFullRange)) - { - //OutRec1 is contained by OutRec2 ... - outrec2.isHole = outrec.isHole; - outrec.isHole = !outrec2.isHole; - outrec2.FirstLeft = outrec.FirstLeft; - outrec.FirstLeft = outrec2; - } else - { - //the 2 polygons are separate ... - outrec2.isHole = outrec.isHole; - outrec2.FirstLeft = outrec.FirstLeft; - } - op2 = op; //ie get ready for the next iteration - } - op2 = op2.next; - } - op = op.next; - } - while (op != outrec.pts); + op1b = DupOutPt(op1, false); + op2b = DupOutPt(op2, true); + op1.Prev = op2; + op2.Next = op1; + op1b.Next = op2b; + op2b.Prev = op1b; + p1 = op1; + p2 = op1b; + return true; + } else + { + op1b = DupOutPt(op1, true); + op2b = DupOutPt(op2, false); + op1.Next = op2; + op2.Prev = op1; + op1b.Prev = op2b; + op2b.Next = op1b; + p1 = op1; + p2 = op1b; + return true; } } - //------------------------------------------------------------------------------ + } + //---------------------------------------------------------------------- - private static bool FullRangeNeeded(Polygon pts) - { - bool result = false; - for (int i = 0; i < pts.Count; i++) - { - if (Math.Abs(pts[i].X) > hiRange || Math.Abs(pts[i].Y) > hiRange) - throw new ClipperException("Coordinate exceeds range bounds."); - else if (Math.Abs(pts[i].X) > loRange || Math.Abs(pts[i].Y) > loRange) - result = true; - } - return result; - } - //------------------------------------------------------------------------------ - public static double Area(Polygon poly) - { - int highI = poly.Count - 1; - if (highI < 2) return 0; - if (FullRangeNeeded(poly)) - { - Int128 a = new Int128(0); - a = Int128.Int128Mul(poly[highI].X + poly[0].X, poly[0].Y - poly[highI].Y); - for (int i = 1; i <= highI; ++i) - a += Int128.Int128Mul(poly[i - 1].X + poly[i].X, poly[i].Y - poly[i - 1].Y); - return a.ToDouble() / 2; - } - else - { - double area = ((double)poly[highI].X + poly[0].X) * ((double)poly[0].Y - poly[highI].Y); - for (int i = 1; i <= highI; ++i) - area += ((double)poly[i - 1].X + poly[i].X) * ((double)poly[i].Y - poly[i -1].Y); - return area / 2; - } - } - //------------------------------------------------------------------------------ + private bool Poly2ContainsPoly1(OutPt outPt1, OutPt outPt2, bool UseFullRange) + { + OutPt pt = outPt1; - double Area(OutRec outRec, bool UseFull64BitRange) - { - OutPt op = outRec.pts; - if (op == null) return 0; - if (UseFull64BitRange) + //Because the polygons may be touching, we need to find a vertex that + //isn't touching the other polygon ... + if (PointOnPolygon(pt.Pt, outPt2, UseFullRange)) { - Int128 a = new Int128(0); - do - { - a += Int128.Int128Mul(op.pt.X + op.prev.pt.X, op.prev.pt.Y - op.pt.Y); - op = op.next; - } while (op != outRec.pts); - return a.ToDouble() / 2; + pt = pt.Next; + while (pt != outPt1 && PointOnPolygon(pt.Pt, outPt2, UseFullRange)) + pt = pt.Next; + if (pt == outPt1) return true; } - else + return PointInPolygon(pt.Pt, outPt2, UseFullRange); + } + //---------------------------------------------------------------------- + + private void FixupFirstLefts1(OutRec OldOutRec, OutRec NewOutRec) + { + for (int i = 0; i < m_PolyOuts.Count; i++) { - double a = 0; - do { - a = a + (op.pt.X + op.prev.pt.X) * (op.prev.pt.Y - op.pt.Y); - op = op.next; - } while (op != outRec.pts); - return a/2; + OutRec outRec = m_PolyOuts[i]; + if (outRec.Pts != null && outRec.FirstLeft == OldOutRec) + { + if (Poly2ContainsPoly1(outRec.Pts, NewOutRec.Pts, m_UseFullRange)) + outRec.FirstLeft = NewOutRec; + } } - } + } + //---------------------------------------------------------------------- - //------------------------------------------------------------------------------ - // OffsetPolygon functions ... - //------------------------------------------------------------------------------ + private void FixupFirstLefts2(OutRec OldOutRec, OutRec NewOutRec) + { + foreach (OutRec outRec in m_PolyOuts) + if (outRec.FirstLeft == OldOutRec) outRec.FirstLeft = NewOutRec; + } + //---------------------------------------------------------------------- - internal static Polygon BuildArc(IntPoint pt, double a1, double a2, double r, double limit) + private void JoinCommonEdges() + { + for (int i = 0; i < m_Joins.Count; i++) { - //see notes in clipper.pas regarding steps - double arcFrac = Math.Abs(a2 - a1) / (2 * Math.PI); - int steps = (int)(arcFrac * Math.PI / Math.Acos(1 - limit / Math.Abs(r))); - if (steps < 2) - steps = 2; - else if (steps > (int)(222.0 * arcFrac)) - steps = (int)(222.0 * arcFrac); - - double x = Math.Cos(a1); - double y = Math.Sin(a1); - double c = Math.Cos((a2 - a1) / steps); - double s = Math.Sin((a2 - a1) / steps); - Polygon result = new Polygon(steps +1); - for (int i = 0; i <= steps; ++i) - { - result.Add(new IntPoint(pt.X + Round(x * r), pt.Y + Round(y * r))); - double x2 = x; - x = x * c - s * y; //cross product - y = x2 * s + y * c; //dot product - } - return result; - } - //------------------------------------------------------------------------------ + Join j = m_Joins[i]; - internal static DoublePoint GetUnitNormal(IntPoint pt1, IntPoint pt2) - { - double dx = (pt2.X - pt1.X); - double dy = (pt2.Y - pt1.Y); - if ((dx == 0) && (dy == 0)) return new DoublePoint(); + OutRec outRec1 = GetOutRec(j.OutPt1.Idx); + OutRec outRec2 = GetOutRec(j.OutPt2.Idx); - double f = 1 * 1.0 / Math.Sqrt(dx * dx + dy * dy); - dx *= f; - dy *= f; + if (outRec1.Pts == null || outRec2.Pts == null) continue; - return new DoublePoint(dy, -dx); - } - //------------------------------------------------------------------------------ + //get the polygon fragment with the correct hole state (FirstLeft) + //before calling JoinPoints() ... + OutRec holeStateRec; + if (outRec1 == outRec2) holeStateRec = outRec1; + else if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2; + else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1; + else holeStateRec = GetLowermostRec(outRec1, outRec2); - internal class DoublePoint - { - public double X { get; set; } - public double Y { get; set; } - public DoublePoint(double x = 0, double y = 0) - { - this.X = x; this.Y = y; - } - public DoublePoint(DoublePoint dp) - { - this.X = dp.X; this.Y = dp.Y; - } - }; - //------------------------------------------------------------------------------ + OutPt p1, p2; + if (!JoinPoints(j, out p1, out p2)) continue; - private class PolyOffsetBuilder - { - private Polygons m_p; - private Polygon currentPoly; - private List normals = new List(); - private double m_delta, m_r, m_rmin; - private int m_i, m_j, m_k; - private const int m_buffLength = 128; + if (outRec1 == outRec2) + { + //instead of joining two polygons, we've just created a new one by + //splitting one polygon into two. + outRec1.Pts = p1; + outRec1.BottomPt = null; + outRec2 = CreateOutRec(); + outRec2.Pts = p2; - void OffsetPoint(JoinType jointype, double limit) - { - switch (jointype) - { - case JoinType.jtMiter: - { - m_r = 1 + (normals[m_j].X * normals[m_k].X + - normals[m_j].Y * normals[m_k].Y); - if (m_r >= m_rmin) DoMiter(); else DoSquare(); - break; - } - case JoinType.jtSquare: DoSquare(); break; - case JoinType.jtRound: DoRound(limit); break; - } - m_k = m_j; - } - //------------------------------------------------------------------------------ + //update all OutRec2.Pts Idx's ... + UpdateOutPtIdxs(outRec2); - public PolyOffsetBuilder(Polygons pts, Polygons solution, bool isPolygon, double delta, - JoinType jointype, EndType endtype, double limit = 0) + if (Poly2ContainsPoly1(outRec2.Pts, outRec1.Pts, m_UseFullRange)) { - //precondition: solution != pts + //outRec2 is contained by outRec1 ... + outRec2.IsHole = !outRec1.IsHole; + outRec2.FirstLeft = outRec1; - if (delta == 0) {solution = pts; return; } - m_p = pts; - m_delta = delta; - m_rmin = 0.5; + //fixup FirstLeft pointers that may need reassigning to OutRec1 + if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); - if (jointype == JoinType.jtMiter) - { - if (limit > 2) m_rmin = 2.0 / (limit * limit); - limit = 0.25; //just in case endtype == etRound - } - else - { - if (limit <= 0) limit = 0.25; - else if (limit > Math.Abs(delta)) limit = Math.Abs(delta); - } + if ((outRec2.IsHole ^ ReverseSolution) == (Area(outRec2) > 0)) + ReversePolyPtLinks(outRec2.Pts); - double deltaSq = delta * delta; - solution.Clear(); - solution.Capacity = pts.Count; - for (m_i = 0; m_i < pts.Count; m_i++) - { - int len = pts[m_i].Count; - if (len == 0 || (len < 3 && delta <= 0)) - continue; - else if (len == 1) - { - currentPoly = new Polygon(); - currentPoly = BuildArc(pts[m_i][0], 0, 2*Math.PI, delta, limit); - solution.Add(currentPoly); - continue; - } + } + else if (Poly2ContainsPoly1(outRec1.Pts, outRec2.Pts, m_UseFullRange)) + { + //outRec1 is contained by outRec2 ... + outRec2.IsHole = outRec1.IsHole; + outRec1.IsHole = !outRec2.IsHole; + outRec2.FirstLeft = outRec1.FirstLeft; + outRec1.FirstLeft = outRec2; - bool forceClose = PointsEqual(pts[m_i][0], pts[m_i][len - 1]); - if (forceClose) len--; - - //build normals ... - normals.Clear(); - normals.Capacity = len; - for (int j = 0; j < len -1; ++j) - normals.Add(GetUnitNormal(pts[m_i][j], pts[m_i][j+1])); - if (isPolygon || forceClose) - normals.Add(GetUnitNormal(pts[m_i][len - 1], pts[m_i][0])); - else - normals.Add(new DoublePoint(normals[len - 2])); - - currentPoly = new Polygon(); - if (isPolygon || forceClose) - { - m_k = len - 1; - for (m_j = 0; m_j < len; ++m_j) - OffsetPoint(jointype, limit); - solution.Add(currentPoly); - if (!isPolygon) - { - currentPoly = new Polygon(); - m_delta = -m_delta; - m_k = len - 1; - for (m_j = 0; m_j < len; ++m_j) - OffsetPoint(jointype, limit); - m_delta = -m_delta; - currentPoly.Reverse(); - solution.Add(currentPoly); - } - } - else - { - m_k = 0; - for (m_j = 1; m_j < len - 1; ++m_j) - OffsetPoint(jointype, limit); - - IntPoint pt1; - if (endtype == EndType.etButt) - { - m_j = len - 1; - pt1 = new IntPoint((Int64)Round(pts[m_i][m_j].X + normals[m_j].X * - delta), (Int64)Round(pts[m_i][m_j].Y + normals[m_j].Y * delta)); - AddPoint(pt1); - pt1 = new IntPoint((Int64)Round(pts[m_i][m_j].X - normals[m_j].X * - delta), (Int64)Round(pts[m_i][m_j].Y - normals[m_j].Y * delta)); - AddPoint(pt1); - } - else - { - m_j = len - 1; - m_k = len - 2; - normals[m_j].X = -normals[m_j].X; - normals[m_j].Y = -normals[m_j].Y; - if (endtype == EndType.etSquare) DoSquare(); - else DoRound(limit); - } - - //re-build Normals ... - for (int j = len - 1; j > 0; j--) - { - normals[j].X = -normals[j - 1].X; - normals[j].Y = -normals[j - 1].Y; - } - normals[0].X = -normals[1].X; - normals[0].Y = -normals[1].Y; - - m_k = len - 1; - for (m_j = m_k - 1; m_j > 0; --m_j) - OffsetPoint(jointype, limit); - - if (endtype == EndType.etButt) - { - pt1 = new IntPoint((Int64)Round(pts[m_i][0].X - normals[0].X * delta), - (Int64)Round(pts[m_i][0].Y - normals[0].Y * delta)); - AddPoint(pt1); - pt1 = new IntPoint((Int64)Round(pts[m_i][0].X + normals[0].X * delta), - (Int64)Round(pts[m_i][0].Y + normals[0].Y * delta)); - AddPoint(pt1); - } - else - { - m_k = 1; - if (endtype == EndType.etSquare) DoSquare(); - else DoRound(limit); - } - solution.Add(currentPoly); - } - } + //fixup FirstLeft pointers that may need reassigning to OutRec1 + if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2); - //finally, clean up untidy corners ... - Clipper clpr = new Clipper(); - clpr.AddPolygons(solution, PolyType.ptSubject); - if (delta > 0) - { - clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive); - } - else - { - IntRect r = clpr.GetBounds(); - Polygon outer = new Polygon(4); - - outer.Add(new IntPoint(r.left - 10, r.bottom + 10)); - outer.Add(new IntPoint(r.right + 10, r.bottom + 10)); - outer.Add(new IntPoint(r.right + 10, r.top - 10)); - outer.Add(new IntPoint(r.left - 10, r.top - 10)); - - clpr.AddPolygon(outer, PolyType.ptSubject); - clpr.ReverseSolution = true; - clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative); - if (solution.Count > 0) solution.RemoveAt(0); - } + if ((outRec1.IsHole ^ ReverseSolution) == (Area(outRec1) > 0)) + ReversePolyPtLinks(outRec1.Pts); } - //------------------------------------------------------------------------------ - - internal void AddPoint(IntPoint pt) + else { - if (currentPoly.Count == currentPoly.Capacity) - currentPoly.Capacity += m_buffLength; - currentPoly.Add(pt); - } - //------------------------------------------------------------------------------ + //the 2 polygons are completely separate ... + outRec2.IsHole = outRec1.IsHole; + outRec2.FirstLeft = outRec1.FirstLeft; - internal void DoSquare() - { - IntPoint pt1 = new IntPoint((Int64)Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), - (Int64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); - IntPoint pt2 = new IntPoint((Int64)Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), - (Int64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); - if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0) - { - double a1 = Math.Atan2(normals[m_k].Y, normals[m_k].X); - double a2 = Math.Atan2(-normals[m_j].Y, -normals[m_j].X); - a1 = Math.Abs(a2 - a1); - if (a1 > Math.PI) a1 = Math.PI * 2 - a1; - double dx = Math.Tan((Math.PI - a1) / 4) * Math.Abs(m_delta); - pt1 = new IntPoint((Int64)(pt1.X - normals[m_k].Y * dx), - (Int64)(pt1.Y + normals[m_k].X * dx)); - AddPoint(pt1); - pt2 = new IntPoint((Int64)(pt2.X + normals[m_j].Y * dx), - (Int64)(pt2.Y - normals[m_j].X * dx)); - AddPoint(pt2); - } - else - { - AddPoint(pt1); - AddPoint(m_p[m_i][m_j]); - AddPoint(pt2); - } + //fixup FirstLeft pointers that may need reassigning to OutRec2 + if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2); } - //------------------------------------------------------------------------------ + + } else + { + //joined 2 polygons together ... - internal void DoMiter() - { - if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0) - { - double q = m_delta / m_r; - AddPoint(new IntPoint((Int64)Round(m_p[m_i][m_j].X + - (normals[m_k].X + normals[m_j].X) * q), - (Int64)Round(m_p[m_i][m_j].Y + (normals[m_k].Y + normals[m_j].Y) * q))); - } - else - { - IntPoint pt1 = new IntPoint((Int64)Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), - (Int64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); - IntPoint pt2 = new IntPoint((Int64)Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), - (Int64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); - AddPoint(pt1); - AddPoint(m_p[m_i][m_j]); - AddPoint(pt2); - } - } - //------------------------------------------------------------------------------ + outRec2.Pts = null; + outRec2.BottomPt = null; + outRec2.Idx = outRec1.Idx; - internal void DoRound(double Limit) - { - IntPoint pt1 = new IntPoint(Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), - Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); - IntPoint pt2 = new IntPoint(Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), - Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); - AddPoint(pt1); - //round off reflex angles (ie > 180 deg) unless almost flat (ie < 10deg). - //cross product normals < 0 . angle > 180 deg. - //dot product normals == 1 . no angle - if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0) - { - if ((normals[m_j].X * normals[m_k].X + normals[m_j].Y * normals[m_k].Y) < 0.985) - { - double a1 = Math.Atan2(normals[m_k].Y, normals[m_k].X); - double a2 = Math.Atan2(normals[m_j].Y, normals[m_j].X); - if (m_delta > 0 && a2 < a1) a2 += Math.PI * 2; - else if (m_delta < 0 && a2 > a1) a2 -= Math.PI * 2; - Polygon arc = BuildArc(m_p[m_i][m_j], a1, a2, m_delta, Limit); - for (int m = 0; m < arc.Count; m++) - AddPoint(arc[m]); - } - } - else - AddPoint(m_p[m_i][m_j]); - AddPoint(pt2); - } - //------------------------------------------------------------------------------ + outRec1.IsHole = holeStateRec.IsHole; + if (holeStateRec == outRec2) + outRec1.FirstLeft = outRec2.FirstLeft; + outRec2.FirstLeft = outRec1; - } //end PolyOffsetBuilder - //------------------------------------------------------------------------------ + //fixup FirstLeft pointers that may need reassigning to OutRec1 + if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); + } + } + } + //------------------------------------------------------------------------------ - internal static bool UpdateBotPt(IntPoint pt, ref IntPoint botPt) + private void UpdateOutPtIdxs(OutRec outrec) + { + OutPt op = outrec.Pts; + do { - if (pt.Y > botPt.Y || (pt.Y == botPt.Y && pt.X < botPt.X)) - { - botPt = pt; - return true; - } - else return false; + op.Idx = outrec.Idx; + op = op.Prev; } - //------------------------------------------------------------------------------ + while(op != outrec.Pts); + } + //------------------------------------------------------------------------------ - public static Polygons OffsetPolygons(Polygons poly, double delta, - JoinType jointype, double MiterLimit, bool AutoFix) + private void DoSimplePolygons() + { + int i = 0; + while (i < m_PolyOuts.Count) { - Polygons result = new Polygons(); - - //AutoFix - fixes polygon orientation if necessary and removes - //duplicate vertices. Can be set false when you're sure that polygon - //orientation is correct and that there are no duplicate vertices. - if (AutoFix) + OutRec outrec = m_PolyOuts[i++]; + OutPt op = outrec.Pts; + if (op == null) continue; + do //for each Pt in Polygon until duplicate found do ... + { + OutPt op2 = op.Next; + while (op2 != outrec.Pts) { - int Len = poly.Count, botI = 0; - while (botI < Len && poly[botI].Count == 0) botI++; - if (botI == Len) return result; - - //botPt: used to find the lowermost (in inverted Y-axis) & leftmost point - //This point (on pts[botI]) must be on an outer polygon ring and if - //its orientation is false (counterclockwise) then assume all polygons - //need reversing ... - IntPoint botPt = poly[botI][0]; - for (int i = botI; i < Len; ++i) + if ((op.Pt == op2.Pt) && op2.Next != op && op2.Prev != op) + { + //split the polygon into two ... + OutPt op3 = op.Prev; + OutPt op4 = op2.Prev; + op.Prev = op4; + op4.Next = op; + op2.Prev = op3; + op3.Next = op2; + + outrec.Pts = op; + OutRec outrec2 = CreateOutRec(); + outrec2.Pts = op2; + UpdateOutPtIdxs(outrec2); + if (Poly2ContainsPoly1(outrec2.Pts, outrec.Pts, m_UseFullRange)) { - if (poly[i].Count == 0) continue; - if (UpdateBotPt(poly[i][0], ref botPt)) botI = i; - for (int j = poly[i].Count - 1; j > 0; j--) - { - if (PointsEqual(poly[i][j], poly[i][j - 1])) - poly[i].RemoveAt(j); - else if (UpdateBotPt(poly[i][j], ref botPt)) - botI = i; - } + //OutRec2 is contained by OutRec1 ... + outrec2.IsHole = !outrec.IsHole; + outrec2.FirstLeft = outrec; + } + else + if (Poly2ContainsPoly1(outrec.Pts, outrec2.Pts, m_UseFullRange)) + { + //OutRec1 is contained by OutRec2 ... + outrec2.IsHole = outrec.IsHole; + outrec.IsHole = !outrec2.IsHole; + outrec2.FirstLeft = outrec.FirstLeft; + outrec.FirstLeft = outrec2; + } else + { + //the 2 polygons are separate ... + outrec2.IsHole = outrec.IsHole; + outrec2.FirstLeft = outrec.FirstLeft; } - if (!Orientation(poly[botI])) - ReversePolygons(poly); + op2 = op; //ie get ready for the next iteration + } + op2 = op2.Next; } + op = op.Next; + } + while (op != outrec.Pts); + } + } + //------------------------------------------------------------------------------ + + public static double Area(Path poly) + { + int highI = poly.Count - 1; + if (highI < 2) return 0; + double area = ((double)poly[highI].X + poly[0].X) * ((double)poly[0].Y - poly[highI].Y); + for (int i = 1; i <= highI; ++i) + area += ((double)poly[i - 1].X + poly[i].X) * ((double)poly[i].Y - poly[i -1].Y); + return area / 2; + } + //------------------------------------------------------------------------------ + + double Area(OutRec outRec) + { + OutPt op = outRec.Pts; + if (op == null) return 0; + double a = 0; + do { + a = a + (double)(op.Pt.X + op.Prev.Pt.X) * (double)(op.Prev.Pt.Y - op.Pt.Y); + op = op.Next; + } while (op != outRec.Pts); + return a/2; + } + + //------------------------------------------------------------------------------ + // OffsetPolygon functions ... + //------------------------------------------------------------------------------ + + internal static DoublePoint GetUnitNormal(IntPoint pt1, IntPoint pt2) + { + double dx = (pt2.X - pt1.X); + double dy = (pt2.Y - pt1.Y); + if ((dx == 0) && (dy == 0)) return new DoublePoint(); + + double f = 1 * 1.0 / Math.Sqrt(dx * dx + dy * dy); + dx *= f; + dy *= f; + + return new DoublePoint(dy, -dx); + } + //------------------------------------------------------------------------------ + + private class PolyOffsetBuilder + { + private Paths m_p; + private Path currentPoly; + private List normals = new List(); + private double m_delta, m_sinA, m_sin, m_cos; + private double m_miterLim, m_Steps360; + private int m_i, m_j, m_k; + private const int m_buffLength = 128; + + void OffsetPoint(JoinType jointype) + { + m_sinA = (normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y); + if (m_sinA < 0.00005 && m_sinA > -0.00005) return; + else if (m_sinA > 1.0) m_sinA = 1.0; + else if (m_sinA < -1.0) m_sinA = -1.0; - new PolyOffsetBuilder(poly, result, true, delta, jointype, EndType.etClosed, MiterLimit); - return result; - } - //------------------------------------------------------------------------------ - - public static Polygons OffsetPolygons(Polygons poly, double delta, - JoinType jointype, double MiterLimit) - { - return OffsetPolygons(poly, delta, jointype, MiterLimit, true); - } - //------------------------------------------------------------------------------ - - public static Polygons OffsetPolygons(Polygons poly, double delta, JoinType jointype) - { - return OffsetPolygons(poly, delta, jointype, 0, true); - } - //------------------------------------------------------------------------------ - - public static Polygons OffsetPolygons(Polygons poly, double delta) - { - return OffsetPolygons(poly, delta, JoinType.jtSquare, 0, true); - } - //------------------------------------------------------------------------------ - - public static Polygons OffsetPolyLines(Polygons lines, - double delta, JoinType jointype, EndType endtype, - double limit) - { - Polygons result = new Polygons(); + if (m_sinA * m_delta < 0) + { + AddPoint(new IntPoint(Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), + Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta))); + AddPoint(m_p[m_i][m_j]); + AddPoint(new IntPoint(Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), + Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta))); + } + else + switch (jointype) + { + case JoinType.jtMiter: + { + double r = 1 + (normals[m_j].X * normals[m_k].X + + normals[m_j].Y * normals[m_k].Y); + if (r >= m_miterLim) DoMiter(r); else DoSquare(); + break; + } + case JoinType.jtSquare: DoSquare(); break; + case JoinType.jtRound: DoRound(); break; + } + m_k = m_j; + } + //------------------------------------------------------------------------------ - //automatically strip duplicate points because it gets complicated with - //open and closed lines and when to strip duplicates across begin-end ... - Polygons pts = new Polygons(lines); - for (int i = 0; i < pts.Count; ++i) - { - for (int j = pts[i].Count - 1; j > 0; j--) - if (PointsEqual(pts[i][j], pts[i][j - 1])) - pts[i].RemoveAt(j); - } + public PolyOffsetBuilder(Paths pts, out Paths solution, double delta, + JoinType jointype, EndType endtype, double limit = 0) + { + //precondition: solution != pts + solution = new Paths(); + if (ClipperBase.near_zero(delta)) {solution = pts; return; } + m_p = pts; + if (endtype != EndType.etClosed && delta < 0) delta = -delta; + m_delta = delta; + + if (jointype == JoinType.jtMiter) + { + //m_miterVal: see offset_triginometry.svg in the documentation folder ... + if (limit > 2) m_miterLim = 2 / (limit * limit); + else m_miterLim = 0.5; + if (endtype == EndType.etRound) limit = 0.25; + } + if (jointype == JoinType.jtRound || endtype == EndType.etRound) + { + if (limit <= 0) limit = 0.25; + else if (limit > Math.Abs(delta)*0.25) limit = Math.Abs(delta)*0.25; + //m_roundVal: see offset_triginometry2.svg in the documentation folder ... + m_Steps360 = Math.PI / Math.Acos(1 - limit / Math.Abs(delta)); + m_sin = Math.Sin(2 * Math.PI / m_Steps360); + m_cos = Math.Cos(2 * Math.PI / m_Steps360); + m_Steps360 /= Math.PI * 2; + if (delta < 0) m_sin = -m_sin; + } - if (endtype == EndType.etClosed) - { - int sz = pts.Count; - pts.Capacity = sz * 2; - for (int i = 0; i < sz; ++i) - { - Polygon line = new Polygon(pts[i]); - line.Reverse(); - pts.Add(line); - } - new PolyOffsetBuilder(pts, result, true, delta, jointype, endtype, limit); - } - else - new PolyOffsetBuilder(pts, result, false, delta, jointype, endtype, limit); + double deltaSq = delta * delta; + solution.Capacity = pts.Count; + for (m_i = 0; m_i < pts.Count; m_i++) + { + int len = pts[m_i].Count; + if (len == 0 || (len < 3 && delta <= 0)) continue; + + if (len == 1) + { + if (jointype == JoinType.jtRound) + { + double X = 1.0, Y = 0.0; + for (cInt j = 1; j <= Round(m_Steps360 * 2 * Math.PI); j++) + { + AddPoint(new IntPoint( + Round(m_p[m_i][0].X + X * delta), + Round(m_p[m_i][0].Y + Y * delta))); + double X2 = X; + X = X * m_cos - m_sin * Y; + Y = X2 * m_sin + Y * m_cos; + } + } + else + { + double X = -1.0, Y = -1.0; + for (int j = 0; j < 4; ++j) + { + AddPoint(new IntPoint(Round(m_p[m_i][0].X + X * delta), + Round(m_p[m_i][0].Y + Y * delta))); + if (X < 0) X = 1; + else if (Y < 0) Y = 1; + else X = -1; + } + } + continue; + } + + //build normals ... + normals.Clear(); + normals.Capacity = len; + for (int j = 0; j < len -1; ++j) + normals.Add(GetUnitNormal(pts[m_i][j], pts[m_i][j+1])); + if (endtype == EndType.etClosed) + normals.Add(GetUnitNormal(pts[m_i][len - 1], pts[m_i][0])); + else + normals.Add(new DoublePoint(normals[len - 2])); - return result; - } - //------------------------------------------------------------------------------ + currentPoly = new Path(); + if (endtype == EndType.etClosed) + { + m_k = len - 1; + for (m_j = 0; m_j < len; ++m_j) + OffsetPoint(jointype); + solution.Add(currentPoly); + } + else + { + m_k = 0; + for (m_j = 1; m_j < len - 1; ++m_j) + OffsetPoint(jointype); + + IntPoint pt1; + if (endtype == EndType.etButt) + { + m_j = len - 1; + pt1 = new IntPoint((cInt)Round(pts[m_i][m_j].X + normals[m_j].X * + delta), (cInt)Round(pts[m_i][m_j].Y + normals[m_j].Y * delta)); + AddPoint(pt1); + pt1 = new IntPoint((cInt)Round(pts[m_i][m_j].X - normals[m_j].X * + delta), (cInt)Round(pts[m_i][m_j].Y - normals[m_j].Y * delta)); + AddPoint(pt1); + } + else + { + m_j = len - 1; + m_k = len - 2; + m_sinA = 0; + normals[m_j] = new DoublePoint(-normals[m_j].X, -normals[m_j].Y); + if (endtype == EndType.etSquare) + DoSquare(); + else + DoRound(); + } + + //re-build Normals ... + for (int j = len - 1; j > 0; j--) + normals[j] = new DoublePoint(-normals[j - 1].X, -normals[j - 1].Y); + + normals[0] = new DoublePoint(-normals[1].X, -normals[1].Y); + + m_k = len - 1; + for (m_j = m_k - 1; m_j > 0; --m_j) + OffsetPoint(jointype); + + if (endtype == EndType.etButt) + { + pt1 = new IntPoint((cInt)Round(pts[m_i][0].X - normals[0].X * delta), + (cInt)Round(pts[m_i][0].Y - normals[0].Y * delta)); + AddPoint(pt1); + pt1 = new IntPoint((cInt)Round(pts[m_i][0].X + normals[0].X * delta), + (cInt)Round(pts[m_i][0].Y + normals[0].Y * delta)); + AddPoint(pt1); + } + else + { + m_k = 1; + m_sinA = 0; + if (endtype == EndType.etSquare) + DoSquare(); + else + DoRound(); + } + solution.Add(currentPoly); + } + } - //------------------------------------------------------------------------------ - // SimplifyPolygon functions ... - // Convert self-intersecting polygons into simple polygons - //------------------------------------------------------------------------------ + //finally, clean up untidy corners ... + Clipper clpr = new Clipper(); + clpr.AddPaths(solution, PolyType.ptSubject, true); + if (delta > 0) + { + clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive); + } + else + { + IntRect r = clpr.GetBounds(); + Path outer = new Path(4); + + outer.Add(new IntPoint(r.left - 10, r.bottom + 10)); + outer.Add(new IntPoint(r.right + 10, r.bottom + 10)); + outer.Add(new IntPoint(r.right + 10, r.top - 10)); + outer.Add(new IntPoint(r.left - 10, r.top - 10)); + + clpr.AddPath(outer, PolyType.ptSubject, true); + clpr.ReverseSolution = true; + clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative); + if (solution.Count > 0) solution.RemoveAt(0); + } + } + //------------------------------------------------------------------------------ - public static Polygons SimplifyPolygon(Polygon poly, - PolyFillType fillType = PolyFillType.pftEvenOdd) - { - Polygons result = new Polygons(); - Clipper c = new Clipper(); - c.ForceSimple = true; - c.AddPolygon(poly, PolyType.ptSubject); - c.Execute(ClipType.ctUnion, result, fillType, fillType); - return result; - } - //------------------------------------------------------------------------------ + internal void AddPoint(IntPoint pt) + { + if (currentPoly.Count == currentPoly.Capacity) + currentPoly.Capacity += m_buffLength; + currentPoly.Add(pt); + } + //------------------------------------------------------------------------------ - public static Polygons SimplifyPolygons(Polygons polys, - PolyFillType fillType = PolyFillType.pftEvenOdd) - { - Polygons result = new Polygons(); - Clipper c = new Clipper(); - c.ForceSimple = true; - c.AddPolygons(polys, PolyType.ptSubject); - c.Execute(ClipType.ctUnion, result, fillType, fillType); - return result; - } - //------------------------------------------------------------------------------ + internal void DoSquare() + { + double dx = Math.Tan(Math.Atan2(m_sinA, + normals[m_k].X * normals[m_j].X + normals[m_k].Y * normals[m_j].Y)/4); + AddPoint(new IntPoint( + Round(m_p[m_i][m_j].X + m_delta * (normals[m_k].X - normals[m_k].Y *dx)), + Round(m_p[m_i][m_j].Y + m_delta * (normals[m_k].Y + normals[m_k].X *dx)))); + AddPoint(new IntPoint( + Round(m_p[m_i][m_j].X + m_delta * (normals[m_j].X + normals[m_j].Y *dx)), + Round(m_p[m_i][m_j].Y + m_delta * (normals[m_j].Y - normals[m_j].X *dx)))); + } + //------------------------------------------------------------------------------ - private static double DistanceSqrd(IntPoint pt1, IntPoint pt2) - { - double dx = ((double)pt1.X - pt2.X); - double dy = ((double)pt1.Y - pt2.Y); - return (dx*dx + dy*dy); - } - //------------------------------------------------------------------------------ + internal void DoMiter(double r) + { + double q = m_delta / r; + AddPoint(new IntPoint(Round(m_p[m_i][m_j].X + (normals[m_k].X + normals[m_j].X) * q), + Round(m_p[m_i][m_j].Y + (normals[m_k].Y + normals[m_j].Y) * q))); + } + //------------------------------------------------------------------------------ - private static DoublePoint ClosestPointOnLine(IntPoint pt, IntPoint linePt1, IntPoint linePt2) - { - double dx = ((double)linePt2.X - linePt1.X); - double dy = ((double)linePt2.Y - linePt1.Y); - if (dx == 0 && dy == 0) - return new DoublePoint(linePt1.X, linePt1.Y); - double q = ((pt.X-linePt1.X)*dx + (pt.Y-linePt1.Y)*dy) / (dx*dx + dy*dy); - return new DoublePoint( - (1-q)*linePt1.X + q*linePt2.X, - (1-q)*linePt1.Y + q*linePt2.Y); - } - //------------------------------------------------------------------------------ + internal void DoRound() + { + double a = Math.Atan2(m_sinA, + normals[m_k].X * normals[m_j].X + normals[m_k].Y * normals[m_j].Y); + int steps = (int)Round(m_Steps360 * Math.Abs(a)); - private static bool SlopesNearColinear(IntPoint pt1, - IntPoint pt2, IntPoint pt3, double distSqrd) - { - if (DistanceSqrd(pt1, pt2) > DistanceSqrd(pt1, pt3)) return false; - DoublePoint cpol = ClosestPointOnLine(pt2, pt1, pt3); - double dx = pt2.X - cpol.X; - double dy = pt2.Y - cpol.Y; - return (dx*dx + dy*dy) < distSqrd; - } - //------------------------------------------------------------------------------ + double X = normals[m_k].X, Y = normals[m_k].Y, X2; + for (int i = 0; i < steps; ++i) + { + AddPoint(new IntPoint( + Round(m_p[m_i][m_j].X + X * m_delta), + Round(m_p[m_i][m_j].Y + Y * m_delta))); + X2 = X; + X = X * m_cos - m_sin * Y; + Y = X2 * m_sin + Y * m_cos; + } + AddPoint(new IntPoint( + Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), + Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta))); + } + //------------------------------------------------------------------------------ - private static bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd) - { - double dx = (double)pt1.X - pt2.X; - double dy = (double)pt1.Y - pt2.Y; - return ((dx * dx) + (dy * dy) <= distSqrd); - } - //------------------------------------------------------------------------------ + } //end PolyOffsetBuilder + //------------------------------------------------------------------------------ - public static Polygon CleanPolygon(Polygon poly, - double distance = 1.415) - { - //distance = proximity in units/pixels below which vertices - //will be stripped. Default ~= sqrt(2) so when adjacent - //vertices have both x & y coords within 1 unit, then - //the second vertex will be stripped. - double distSqrd = (distance * distance); - int highI = poly.Count -1; - Polygon result = new Polygon(highI + 1); - while (highI > 0 && PointsAreClose(poly[highI], poly[0], distSqrd)) highI--; - if (highI < 2) return result; - IntPoint pt = poly[highI]; - int i = 0; - for (;;) + internal static bool UpdateBotPt(IntPoint pt, ref IntPoint botPt) + { + if (pt.Y > botPt.Y || (pt.Y == botPt.Y && pt.X < botPt.X)) + { + botPt = pt; + return true; + } + else return false; + } + //------------------------------------------------------------------------------ + + internal static bool StripDupsAndGetBotPt(Path in_path, + Path out_path, bool closed, out IntPoint botPt) + { + botPt = new IntPoint(0, 0); + int len = in_path.Count; + if (closed) + while (len > 0 && (in_path[0] == in_path[len -1])) len--; + if (len == 0) return false; + out_path.Capacity = len; + int j = 0; + out_path.Add(in_path[0]); + botPt = in_path[0]; + for (int i = 1; i < len; ++i) + if (in_path[i] != out_path[j]) + { + out_path.Add(in_path[i]); + j++; + if (out_path[j].Y > botPt.Y || + ((out_path[j].Y == botPt.Y) && out_path[j].X < botPt.X)) + botPt = out_path[j]; + } + j++; + if (j < 2 || (closed && (j == 2))) j = 0; + while (out_path.Count > j) out_path.RemoveAt(j); + return j > 0; + } + //------------------------------------------------------------------------------ + + public static Paths OffsetPaths(Paths polys, double delta, + JoinType jointype, EndType endtype, double MiterLimit) + { + Paths out_polys = new Paths(polys.Count); + IntPoint botPt = new IntPoint(); + IntPoint pt; + int botIdx = -1; + for (int i = 0; i < polys.Count; ++i) + { + out_polys.Add(new Path()); + if (StripDupsAndGetBotPt(polys[i], out_polys[i], endtype == EndType.etClosed, out pt)) + if (botIdx < 0 || pt.Y > botPt.Y || (pt.Y == botPt.Y && pt.X < botPt.X)) { - while (i < highI && PointsAreClose(pt, poly[i], distSqrd)) i+=2; - int i2 = i; - while (i < highI && (PointsAreClose(poly[i], poly[i + 1], distSqrd) || - SlopesNearColinear(pt, poly[i], poly[i + 1], distSqrd))) i++; - if (i >= highI) break; - else if (i != i2) continue; - pt = poly[i++]; - result.Add(pt); + botPt = pt; + botIdx = i; } - if (i <= highI) result.Add(poly[i]); - i = result.Count; - if (i > 2 && SlopesNearColinear(result[i - 2], result[i - 1], result[0], distSqrd)) - result.RemoveAt(i -1); - if (result.Count < 3) result.Clear(); - return result; } - //------------------------------------------------------------------------------ + if (endtype == EndType.etClosed && botIdx >= 0 && !Orientation(out_polys[botIdx])) + ReversePaths(out_polys); + + Paths result; + new PolyOffsetBuilder(out_polys, out result, delta, jointype, endtype, MiterLimit); + return result; + } + //------------------------------------------------------------------------------ + +#if use_deprecated + public static Paths OffsetPolygons(Paths poly, double delta, + JoinType jointype, double MiterLimit, bool AutoFix) + { + return OffsetPaths(poly, delta, jointype, EndType.etClosed, MiterLimit); + } + //------------------------------------------------------------------------------ + + public static Paths OffsetPolygons(Paths poly, double delta, + JoinType jointype, double MiterLimit) + { + return OffsetPaths(poly, delta, jointype, EndType.etClosed, MiterLimit); + } + //------------------------------------------------------------------------------ + + public static Paths OffsetPolygons(Polygons polys, double delta, JoinType jointype) + { + return OffsetPaths(polys, delta, jointype, EndType.etClosed, 0); + } + //------------------------------------------------------------------------------ + + public static Paths OffsetPolygons(Polygons polys, double delta) + { + return OffsetPolygons(polys, delta, JoinType.jtSquare, 0, true); + } + //------------------------------------------------------------------------------ + + public static void ReversePolygons(Polygons polys) + { + polys.ForEach(delegate(Path poly) { poly.Reverse(); }); + } + //------------------------------------------------------------------------------ + + public static void PolyTreeToPolygons(PolyTree polytree, Polygons polys) + { + polys.Clear(); + polys.Capacity = polytree.Total; + AddPolyNodeToPaths(polytree, NodeType.ntAny, polys); + } + //------------------------------------------------------------------------------ +#endif - public static Polygons CleanPolygons(Polygons polys, - double distance = 1.415) - { - Polygons result = new Polygons(polys.Count); - for (int i = 0; i < polys.Count; i++) - result.Add(CleanPolygon(polys[i], distance)); - return result; - } - //------------------------------------------------------------------------------ - - public static void PolyTreeToPolygons(PolyTree polytree, Polygons polygons) - { - polygons.Clear(); - polygons.Capacity = polytree.Total; - AddPolyNodeToPolygons(polytree, polygons); - } - //------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ + // SimplifyPolygon functions ... + // Convert self-intersecting polygons into simple polygons + //------------------------------------------------------------------------------ - public static void AddPolyNodeToPolygons(PolyNode polynode, Polygons polygons) - { - if (polynode.Contour.Count > 0) - polygons.Add(polynode.Contour); - foreach (PolyNode pn in polynode.Childs) - AddPolyNodeToPolygons(pn, polygons); - } - //------------------------------------------------------------------------------ + public static Paths SimplifyPolygon(Path poly, + PolyFillType fillType = PolyFillType.pftEvenOdd) + { + Paths result = new Paths(); + Clipper c = new Clipper(); + c.StrictlySimple = true; + c.AddPath(poly, PolyType.ptSubject, true); + c.Execute(ClipType.ctUnion, result, fillType, fillType); + return result; + } + //------------------------------------------------------------------------------ + + public static Paths SimplifyPolygons(Paths polys, + PolyFillType fillType = PolyFillType.pftEvenOdd) + { + Paths result = new Paths(); + Clipper c = new Clipper(); + c.StrictlySimple = true; + c.AddPaths(polys, PolyType.ptSubject, true); + c.Execute(ClipType.ctUnion, result, fillType, fillType); + return result; + } + //------------------------------------------------------------------------------ + + private static double DistanceSqrd(IntPoint pt1, IntPoint pt2) + { + double dx = ((double)pt1.X - pt2.X); + double dy = ((double)pt1.Y - pt2.Y); + return (dx*dx + dy*dy); + } + //------------------------------------------------------------------------------ + + private static DoublePoint ClosestPointOnLine(IntPoint pt, IntPoint linePt1, IntPoint linePt2) + { + double dx = ((double)linePt2.X - linePt1.X); + double dy = ((double)linePt2.Y - linePt1.Y); + if (dx == 0 && dy == 0) + return new DoublePoint(linePt1.X, linePt1.Y); + double q = ((pt.X-linePt1.X)*dx + (pt.Y-linePt1.Y)*dy) / (dx*dx + dy*dy); + return new DoublePoint( + (1-q)*linePt1.X + q*linePt2.X, + (1-q)*linePt1.Y + q*linePt2.Y); + } + //------------------------------------------------------------------------------ + + private static bool SlopesNearCollinear(IntPoint pt1, + IntPoint pt2, IntPoint pt3, double distSqrd) + { + if (DistanceSqrd(pt1, pt2) > DistanceSqrd(pt1, pt3)) return false; + DoublePoint cpol = ClosestPointOnLine(pt2, pt1, pt3); + double dx = pt2.X - cpol.X; + double dy = pt2.Y - cpol.Y; + return (dx*dx + dy*dy) < distSqrd; + } + //------------------------------------------------------------------------------ + + private static bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd) + { + double dx = (double)pt1.X - pt2.X; + double dy = (double)pt1.Y - pt2.Y; + return ((dx * dx) + (dy * dy) <= distSqrd); + } + //------------------------------------------------------------------------------ + + public static Path CleanPolygon(Path path, + double distance = 1.415) + { + //distance = proximity in units/pixels below which vertices + //will be stripped. Default ~= sqrt(2) so when adjacent + //vertices have both x & y coords within 1 unit, then + //the second vertex will be stripped. + double distSqrd = (distance * distance); + int highI = path.Count -1; + Path result = new Path(highI + 1); + while (highI > 0 && PointsAreClose(path[highI], path[0], distSqrd)) highI--; + if (highI < 2) return result; + IntPoint pt = path[highI]; + int i = 0; + for (;;) + { + while (i < highI && PointsAreClose(pt, path[i], distSqrd)) i+=2; + int i2 = i; + while (i < highI && (PointsAreClose(path[i], path[i + 1], distSqrd) || + SlopesNearCollinear(pt, path[i], path[i + 1], distSqrd))) i++; + if (i >= highI) break; + else if (i != i2) continue; + pt = path[i++]; + result.Add(pt); + } + if (i <= highI) result.Add(path[i]); + i = result.Count; + if (i > 2 && SlopesNearCollinear(result[i - 2], result[i - 1], result[0], distSqrd)) + result.RemoveAt(i -1); + if (result.Count < 3) result.Clear(); + return result; + } + //------------------------------------------------------------------------------ + + internal static Paths Minkowki(Path poly, Path path, bool IsSum, bool IsClosed) + { + int delta = (IsClosed ? 1 : 0); + int polyCnt = poly.Count; + int pathCnt = path.Count; + Paths result = new Paths(pathCnt); + if (IsSum) + for (int i = 0; i < pathCnt; i++) + { + Path p = new Path(polyCnt); + foreach (IntPoint ip in poly) + p.Add(new IntPoint(path[i].X + ip.X, path[i].Y + ip.Y)); + result.Add(p); + } + else + for (int i = 0; i < pathCnt; i++) + { + Path p = new Path(polyCnt); + foreach (IntPoint ip in poly) + p.Add(new IntPoint(path[i].X - ip.X, path[i].Y - ip.Y)); + result.Add(p); + } + Paths quads = new Paths((pathCnt + delta) * (polyCnt + 1)); + for (int i = 0; i <= pathCnt - 2 + delta; i++) + for (int j = 0; j <= polyCnt - 1; j++) + { + Path quad = new Path(4); + quad.Add(result[i % pathCnt][j % polyCnt]); + quad.Add(result[(i + 1) % pathCnt][j % polyCnt]); + quad.Add(result[(i + 1) % pathCnt][(j + 1) % polyCnt]); + quad.Add(result[i % pathCnt][(j + 1) % polyCnt]); + if (!Orientation(quad)) quad.Reverse(); + quads.Add(quad); + } - } //end ClipperLib namespace + Clipper c = new Clipper(); + c.AddPaths(quads, PolyType.ptSubject, true); + c.Execute(ClipType.ctUnion, result, PolyFillType.pftNonZero, PolyFillType.pftNonZero); + return result; + } + //------------------------------------------------------------------------------ + + public static Paths MinkowkiSum(Path poly, Path path, bool IsClosed) + { + return Minkowki(poly, path, true, IsClosed); + } + //------------------------------------------------------------------------------ + + public static Paths MinkowkiDiff(Path poly, Path path, bool IsClosed) + { + return Minkowki(poly, path, false, IsClosed); + } + //------------------------------------------------------------------------------ + + public static Paths CleanPolygons(Paths polys, + double distance = 1.415) + { + Paths result = new Paths(polys.Count); + for (int i = 0; i < polys.Count; i++) + result.Add(CleanPolygon(polys[i], distance)); + return result; + } + //------------------------------------------------------------------------------ + + internal enum NodeType { ntAny, ntOpen, ntClosed }; + + public static Paths PolyTreeToPaths(PolyTree polytree) + { + + Paths result = new Paths(); + result.Capacity = polytree.Total; + AddPolyNodeToPaths(polytree, NodeType.ntAny, result); + return result; + } + //------------------------------------------------------------------------------ + + internal static void AddPolyNodeToPaths(PolyNode polynode, NodeType nt, Paths paths) + { + bool match = true; + switch (nt) + { + case NodeType.ntOpen: return; + case NodeType.ntClosed: match = !polynode.IsOpen; break; + default: break; + } + + if (polynode.Contour.Count > 0 && match) + paths.Add(polynode.Contour); + foreach (PolyNode pn in polynode.Childs) + AddPolyNodeToPaths(pn, nt, paths); + } + //------------------------------------------------------------------------------ + + public static Paths OpenPathsFromPolyTree(PolyTree polytree) + { + Paths result = new Paths(); + result.Capacity = polytree.ChildCount; + for (int i = 0; i < polytree.ChildCount; i++) + if (polytree.Childs[i].IsOpen) + result.Add(polytree.Childs[i].Contour); + return result; + } + //------------------------------------------------------------------------------ + + public static Paths ClosedPathsFromPolyTree(PolyTree polytree) + { + Paths result = new Paths(); + result.Capacity = polytree.Total; + AddPolyNodeToPaths(polytree, NodeType.ntClosed, result); + return result; + } + //------------------------------------------------------------------------------ + + } //end Clipper - class ClipperException : Exception - { - public ClipperException(string description) : base(description){} - } - //------------------------------------------------------------------------------ -} + class ClipperException : Exception + { + public ClipperException(string description) : base(description){} + } + //------------------------------------------------------------------------------ + +} //end ClipperLib namespace diff --git a/Curves/CurvesDemo/CurvesDemo.csproj b/Curves/CurvesDemo/CurvesDemo.csproj new file mode 100644 index 0000000..b09c29a --- /dev/null +++ b/Curves/CurvesDemo/CurvesDemo.csproj @@ -0,0 +1,110 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {26B71993-4477-4482-8991-8288A6D5C99D} + WinExe + Properties + Clipper_Curves_Demo + Clipper_Curves_Demo + v2.0 + + + 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + Form + + + Form1.cs + + + + + + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/Curves/CurvesDemo/CurvesDemo.sln b/Curves/CurvesDemo/CurvesDemo.sln new file mode 100644 index 0000000..2d36dd7 --- /dev/null +++ b/Curves/CurvesDemo/CurvesDemo.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C# Express 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CurvesDemo", "CurvesDemo.csproj", "{26B71993-4477-4482-8991-8288A6D5C99D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {26B71993-4477-4482-8991-8288A6D5C99D}.Debug|Any CPU.ActiveCfg = Debug|x86 + {26B71993-4477-4482-8991-8288A6D5C99D}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {26B71993-4477-4482-8991-8288A6D5C99D}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {26B71993-4477-4482-8991-8288A6D5C99D}.Debug|x86.ActiveCfg = Debug|x86 + {26B71993-4477-4482-8991-8288A6D5C99D}.Debug|x86.Build.0 = Debug|x86 + {26B71993-4477-4482-8991-8288A6D5C99D}.Release|Any CPU.ActiveCfg = Release|x86 + {26B71993-4477-4482-8991-8288A6D5C99D}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {26B71993-4477-4482-8991-8288A6D5C99D}.Release|Mixed Platforms.Build.0 = Release|x86 + {26B71993-4477-4482-8991-8288A6D5C99D}.Release|x86.ActiveCfg = Release|x86 + {26B71993-4477-4482-8991-8288A6D5C99D}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Curves/CurvesDemo/Form1.Designer.cs b/Curves/CurvesDemo/Form1.Designer.cs new file mode 100644 index 0000000..de4b6e5 --- /dev/null +++ b/Curves/CurvesDemo/Form1.Designer.cs @@ -0,0 +1,609 @@ +namespace Clipper_Lines_Demo +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripStatusLabel2 = new System.Windows.Forms.ToolStripStatusLabel(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.mLoad = new System.Windows.Forms.ToolStripMenuItem(); + this.mSave = new System.Windows.Forms.ToolStripMenuItem(); + this.mSaveAs = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); + this.mExit = new System.Windows.Forms.ToolStripMenuItem(); + this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.mIntersection = new System.Windows.Forms.ToolStripMenuItem(); + this.mUnion = new System.Windows.Forms.ToolStripMenuItem(); + this.mDifference = new System.Windows.Forms.ToolStripMenuItem(); + this.mXor = new System.Windows.Forms.ToolStripMenuItem(); + this.mNone = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.mEvenOdd = new System.Windows.Forms.ToolStripMenuItem(); + this.mNonZero = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); + this.mNewPath = new System.Windows.Forms.ToolStripMenuItem(); + this.mUndo = new System.Windows.Forms.ToolStripMenuItem(); + this.mClear = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator(); + this.mZoomIn = new System.Windows.Forms.ToolStripMenuItem(); + this.mZoomOut = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.quickTipsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.panel1 = new System.Windows.Forms.Panel(); + this.cbShowCoords = new System.Windows.Forms.CheckBox(); + this.cbSubjClosed = new System.Windows.Forms.CheckBox(); + this.rbClipPoly = new System.Windows.Forms.RadioButton(); + this.rbSubjEllipses = new System.Windows.Forms.RadioButton(); + this.rbSubjArc = new System.Windows.Forms.RadioButton(); + this.rbSubjQBezier = new System.Windows.Forms.RadioButton(); + this.rbSubjCBezier = new System.Windows.Forms.RadioButton(); + this.rbSubjLine = new System.Windows.Forms.RadioButton(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.cbShowCtrls = new System.Windows.Forms.CheckBox(); + this.cbReconstCurve = new System.Windows.Forms.CheckBox(); + this.bNewPath = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.DisplayPanel = new Clipper_Lines_Demo.MainForm.MyDisplayPanel(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + this.statusStrip1.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // statusStrip1 + // + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripStatusLabel1, + this.toolStripStatusLabel2}); + this.statusStrip1.Location = new System.Drawing.Point(0, 443); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Size = new System.Drawing.Size(623, 22); + this.statusStrip1.TabIndex = 2; + this.statusStrip1.Text = "statusStrip1"; + // + // toolStripStatusLabel1 + // + this.toolStripStatusLabel1.AutoSize = false; + this.toolStripStatusLabel1.BorderSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)((((System.Windows.Forms.ToolStripStatusLabelBorderSides.Left | System.Windows.Forms.ToolStripStatusLabelBorderSides.Top) + | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right) + | System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom))); + this.toolStripStatusLabel1.BorderStyle = System.Windows.Forms.Border3DStyle.SunkenOuter; + this.toolStripStatusLabel1.Margin = new System.Windows.Forms.Padding(0, 3, 0, 0); + this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; + this.toolStripStatusLabel1.Size = new System.Drawing.Size(110, 19); + this.toolStripStatusLabel1.Text = " Press F1 for Help"; + this.toolStripStatusLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // toolStripStatusLabel2 + // + this.toolStripStatusLabel2.AutoSize = false; + this.toolStripStatusLabel2.BorderSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)((((System.Windows.Forms.ToolStripStatusLabelBorderSides.Left | System.Windows.Forms.ToolStripStatusLabelBorderSides.Top) + | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right) + | System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom))); + this.toolStripStatusLabel2.BorderStyle = System.Windows.Forms.Border3DStyle.SunkenOuter; + this.toolStripStatusLabel2.Margin = new System.Windows.Forms.Padding(0, 3, 0, 0); + this.toolStripStatusLabel2.Name = "toolStripStatusLabel2"; + this.toolStripStatusLabel2.Size = new System.Drawing.Size(300, 19); + this.toolStripStatusLabel2.Text = " Copyright 2013 - Angus Johnson"; + this.toolStripStatusLabel2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.editToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(623, 24); + this.menuStrip1.TabIndex = 4; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mLoad, + this.mSave, + this.mSaveAs, + this.toolStripMenuItem3, + this.mExit}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // mLoad + // + this.mLoad.Name = "mLoad"; + this.mLoad.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); + this.mLoad.Size = new System.Drawing.Size(155, 22); + this.mLoad.Text = "&Open ..."; + this.mLoad.Click += new System.EventHandler(this.mOpen_Click); + // + // mSave + // + this.mSave.Name = "mSave"; + this.mSave.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.mSave.Size = new System.Drawing.Size(155, 22); + this.mSave.Text = "&Save"; + this.mSave.Click += new System.EventHandler(this.mSave_Click); + // + // mSaveAs + // + this.mSaveAs.Name = "mSaveAs"; + this.mSaveAs.Size = new System.Drawing.Size(155, 22); + this.mSaveAs.Text = "Save &As ..."; + this.mSaveAs.Click += new System.EventHandler(this.mSaveAs_Click); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size(152, 6); + // + // mExit + // + this.mExit.Name = "mExit"; + this.mExit.Size = new System.Drawing.Size(155, 22); + this.mExit.Text = "E&xit "; + this.mExit.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mExit.Click += new System.EventHandler(this.mExit_Click); + // + // editToolStripMenuItem + // + this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mIntersection, + this.mUnion, + this.mDifference, + this.mXor, + this.mNone, + this.toolStripMenuItem1, + this.mEvenOdd, + this.mNonZero, + this.toolStripMenuItem2, + this.mNewPath, + this.mUndo, + this.mClear, + this.toolStripMenuItem4, + this.mZoomIn, + this.mZoomOut}); + this.editToolStripMenuItem.Name = "editToolStripMenuItem"; + this.editToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.editToolStripMenuItem.Text = "E&dit"; + // + // mIntersection + // + this.mIntersection.Checked = true; + this.mIntersection.CheckState = System.Windows.Forms.CheckState.Checked; + this.mIntersection.Name = "mIntersection"; + this.mIntersection.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.I))); + this.mIntersection.Size = new System.Drawing.Size(202, 22); + this.mIntersection.Text = "&Intersection"; + this.mIntersection.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mIntersection.Click += new System.EventHandler(this.mClipType_Click); + // + // mUnion + // + this.mUnion.Name = "mUnion"; + this.mUnion.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U))); + this.mUnion.Size = new System.Drawing.Size(202, 22); + this.mUnion.Text = "&Union"; + this.mUnion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mUnion.Click += new System.EventHandler(this.mClipType_Click); + // + // mDifference + // + this.mDifference.Name = "mDifference"; + this.mDifference.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D))); + this.mDifference.Size = new System.Drawing.Size(202, 22); + this.mDifference.Text = "&Difference"; + this.mDifference.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mDifference.Click += new System.EventHandler(this.mClipType_Click); + // + // mXor + // + this.mXor.Name = "mXor"; + this.mXor.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X))); + this.mXor.Size = new System.Drawing.Size(202, 22); + this.mXor.Text = "&XOr"; + this.mXor.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mXor.Click += new System.EventHandler(this.mClipType_Click); + // + // mNone + // + this.mNone.Name = "mNone"; + this.mNone.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Q))); + this.mNone.Size = new System.Drawing.Size(202, 22); + this.mNone.Text = "Non&e"; + this.mNone.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mNone.Click += new System.EventHandler(this.mClipType_Click); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(199, 6); + // + // mEvenOdd + // + this.mEvenOdd.Checked = true; + this.mEvenOdd.CheckState = System.Windows.Forms.CheckState.Checked; + this.mEvenOdd.Name = "mEvenOdd"; + this.mEvenOdd.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.E))); + this.mEvenOdd.Size = new System.Drawing.Size(202, 22); + this.mEvenOdd.Text = "&EvenOdd"; + this.mEvenOdd.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mEvenOdd.Click += new System.EventHandler(this.mFillType_Clicked); + // + // mNonZero + // + this.mNonZero.Name = "mNonZero"; + this.mNonZero.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N))); + this.mNonZero.Size = new System.Drawing.Size(202, 22); + this.mNonZero.Text = "&NonZero"; + this.mNonZero.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mNonZero.Click += new System.EventHandler(this.mFillType_Clicked); + // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size(199, 6); + // + // mNewPath + // + this.mNewPath.Name = "mNewPath"; + this.mNewPath.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.P))); + this.mNewPath.Size = new System.Drawing.Size(202, 22); + this.mNewPath.Text = "New &Path"; + this.mNewPath.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mNewPath.Click += new System.EventHandler(this.mNewPath_Click); + // + // mUndo + // + this.mUndo.Name = "mUndo"; + this.mUndo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); + this.mUndo.Size = new System.Drawing.Size(202, 22); + this.mUndo.Text = "Und&o"; + this.mUndo.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mUndo.Click += new System.EventHandler(this.mUndo_Click); + // + // mClear + // + this.mClear.Name = "mClear"; + this.mClear.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); + this.mClear.Size = new System.Drawing.Size(202, 22); + this.mClear.Text = "&Clear"; + this.mClear.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.mClear.Click += new System.EventHandler(this.mClear_Click); + // + // toolStripMenuItem4 + // + this.toolStripMenuItem4.Name = "toolStripMenuItem4"; + this.toolStripMenuItem4.Size = new System.Drawing.Size(199, 6); + // + // mZoomIn + // + this.mZoomIn.Name = "mZoomIn"; + this.mZoomIn.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Oemplus))); + this.mZoomIn.Size = new System.Drawing.Size(202, 22); + this.mZoomIn.Text = "Zoom In"; + this.mZoomIn.Click += new System.EventHandler(this.mZoomIn_Click); + // + // mZoomOut + // + this.mZoomOut.Name = "mZoomOut"; + this.mZoomOut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.OemMinus))); + this.mZoomOut.Size = new System.Drawing.Size(202, 22); + this.mZoomOut.Text = "Zoom Out"; + this.mZoomOut.Click += new System.EventHandler(this.mZoomOut_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.quickTipsToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(40, 20); + this.helpToolStripMenuItem.Text = "&Help"; + // + // quickTipsToolStripMenuItem + // + this.quickTipsToolStripMenuItem.Name = "quickTipsToolStripMenuItem"; + this.quickTipsToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F1; + this.quickTipsToolStripMenuItem.Size = new System.Drawing.Size(141, 22); + this.quickTipsToolStripMenuItem.Text = "&Quick Tips"; + this.quickTipsToolStripMenuItem.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.quickTipsToolStripMenuItem.Click += new System.EventHandler(this.quickTipsToolStripMenuItem_Click); + // + // panel1 + // + this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.panel1.Controls.Add(this.cbShowCoords); + this.panel1.Controls.Add(this.cbSubjClosed); + this.panel1.Controls.Add(this.rbClipPoly); + this.panel1.Controls.Add(this.rbSubjEllipses); + this.panel1.Controls.Add(this.rbSubjArc); + this.panel1.Controls.Add(this.rbSubjQBezier); + this.panel1.Controls.Add(this.rbSubjCBezier); + this.panel1.Controls.Add(this.rbSubjLine); + this.panel1.Controls.Add(this.groupBox2); + this.panel1.Controls.Add(this.cbShowCtrls); + this.panel1.Controls.Add(this.cbReconstCurve); + this.panel1.Controls.Add(this.bNewPath); + this.panel1.Controls.Add(this.groupBox1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Left; + this.panel1.Location = new System.Drawing.Point(0, 24); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(159, 419); + this.panel1.TabIndex = 1; + // + // cbShowCoords + // + this.cbShowCoords.AutoSize = true; + this.cbShowCoords.Location = new System.Drawing.Point(12, 375); + this.cbShowCoords.Name = "cbShowCoords"; + this.cbShowCoords.Size = new System.Drawing.Size(119, 17); + this.cbShowCoords.TabIndex = 41; + this.cbShowCoords.Text = "Display Coord&inates"; + this.cbShowCoords.UseVisualStyleBackColor = true; + this.cbShowCoords.Click += new System.EventHandler(this.cbShowCoords_Click); + // + // cbSubjClosed + // + this.cbSubjClosed.AutoSize = true; + this.cbSubjClosed.Location = new System.Drawing.Point(26, 40); + this.cbSubjClosed.Name = "cbSubjClosed"; + this.cbSubjClosed.Size = new System.Drawing.Size(58, 17); + this.cbSubjClosed.TabIndex = 39; + this.cbSubjClosed.Text = "Cl&osed"; + this.cbSubjClosed.UseVisualStyleBackColor = true; + this.cbSubjClosed.Click += new System.EventHandler(this.cbSubjClosed_Click); + // + // rbClipPoly + // + this.rbClipPoly.AutoSize = true; + this.rbClipPoly.Location = new System.Drawing.Point(26, 218); + this.rbClipPoly.Name = "rbClipPoly"; + this.rbClipPoly.Size = new System.Drawing.Size(85, 17); + this.rbClipPoly.TabIndex = 20; + this.rbClipPoly.Text = "Li&ne (closed)"; + this.rbClipPoly.UseVisualStyleBackColor = true; + this.rbClipPoly.Click += new System.EventHandler(this.rbAdd_Click); + // + // rbSubjEllipses + // + this.rbSubjEllipses.AutoSize = true; + this.rbSubjEllipses.Enabled = false; + this.rbSubjEllipses.Location = new System.Drawing.Point(26, 151); + this.rbSubjEllipses.Name = "rbSubjEllipses"; + this.rbSubjEllipses.Size = new System.Drawing.Size(82, 17); + this.rbSubjEllipses.TabIndex = 19; + this.rbSubjEllipses.Text = "&Elliptical Arc"; + this.rbSubjEllipses.UseVisualStyleBackColor = true; + this.rbSubjEllipses.Click += new System.EventHandler(this.rbAdd_Click); + // + // rbSubjArc + // + this.rbSubjArc.AutoSize = true; + this.rbSubjArc.Location = new System.Drawing.Point(26, 129); + this.rbSubjArc.Name = "rbSubjArc"; + this.rbSubjArc.Size = new System.Drawing.Size(41, 17); + this.rbSubjArc.TabIndex = 18; + this.rbSubjArc.Text = "&Arc"; + this.rbSubjArc.UseVisualStyleBackColor = true; + this.rbSubjArc.Click += new System.EventHandler(this.rbAdd_Click); + // + // rbSubjQBezier + // + this.rbSubjQBezier.AutoSize = true; + this.rbSubjQBezier.Location = new System.Drawing.Point(26, 107); + this.rbSubjQBezier.Name = "rbSubjQBezier"; + this.rbSubjQBezier.Size = new System.Drawing.Size(62, 17); + this.rbSubjQBezier.TabIndex = 17; + this.rbSubjQBezier.Text = "&QBezier"; + this.rbSubjQBezier.UseVisualStyleBackColor = true; + this.rbSubjQBezier.Click += new System.EventHandler(this.rbAdd_Click); + // + // rbSubjCBezier + // + this.rbSubjCBezier.AutoSize = true; + this.rbSubjCBezier.Location = new System.Drawing.Point(25, 85); + this.rbSubjCBezier.Name = "rbSubjCBezier"; + this.rbSubjCBezier.Size = new System.Drawing.Size(61, 17); + this.rbSubjCBezier.TabIndex = 16; + this.rbSubjCBezier.Text = "&CBezier"; + this.rbSubjCBezier.UseVisualStyleBackColor = true; + this.rbSubjCBezier.Click += new System.EventHandler(this.rbAdd_Click); + // + // rbSubjLine + // + this.rbSubjLine.AutoSize = true; + this.rbSubjLine.Checked = true; + this.rbSubjLine.Location = new System.Drawing.Point(25, 63); + this.rbSubjLine.Name = "rbSubjLine"; + this.rbSubjLine.Size = new System.Drawing.Size(45, 17); + this.rbSubjLine.TabIndex = 15; + this.rbSubjLine.TabStop = true; + this.rbSubjLine.Text = "&Line"; + this.rbSubjLine.UseVisualStyleBackColor = true; + this.rbSubjLine.Click += new System.EventHandler(this.rbAdd_Click); + // + // groupBox2 + // + this.groupBox2.Location = new System.Drawing.Point(12, 194); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(128, 61); + this.groupBox2.TabIndex = 6; + this.groupBox2.TabStop = false; + this.groupBox2.Text = " Clip Paths "; + // + // cbShowCtrls + // + this.cbShowCtrls.AutoSize = true; + this.cbShowCtrls.Enabled = false; + this.cbShowCtrls.Location = new System.Drawing.Point(12, 337); + this.cbShowCtrls.Name = "cbShowCtrls"; + this.cbShowCtrls.Size = new System.Drawing.Size(103, 17); + this.cbShowCtrls.TabIndex = 36; + this.cbShowCtrls.Text = "Show C&trl Points"; + this.cbShowCtrls.UseVisualStyleBackColor = true; + this.cbShowCtrls.Click += new System.EventHandler(this.cbShowCtrls_Click); + // + // cbReconstCurve + // + this.cbReconstCurve.AutoSize = true; + this.cbReconstCurve.Location = new System.Drawing.Point(12, 306); + this.cbReconstCurve.Name = "cbReconstCurve"; + this.cbReconstCurve.Size = new System.Drawing.Size(132, 17); + this.cbReconstCurve.TabIndex = 35; + this.cbReconstCurve.Text = "Reconstructed Curves"; + this.cbReconstCurve.UseVisualStyleBackColor = true; + this.cbReconstCurve.Click += new System.EventHandler(this.cbReconstCurve_Click); + // + // bNewPath + // + this.bNewPath.Enabled = false; + this.bNewPath.Location = new System.Drawing.Point(12, 271); + this.bNewPath.Name = "bNewPath"; + this.bNewPath.Size = new System.Drawing.Size(130, 28); + this.bNewPath.TabIndex = 30; + this.bNewPath.Text = "New &Path"; + this.bNewPath.UseVisualStyleBackColor = true; + this.bNewPath.Click += new System.EventHandler(this.mNewPath_Click); + // + // groupBox1 + // + this.groupBox1.Location = new System.Drawing.Point(12, 17); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(130, 167); + this.groupBox1.TabIndex = 40; + this.groupBox1.TabStop = false; + this.groupBox1.Text = " Subject Paths "; + // + // DisplayPanel + // + this.DisplayPanel.BackColor = System.Drawing.SystemColors.Window; + this.DisplayPanel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.DisplayPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.DisplayPanel.Location = new System.Drawing.Point(159, 24); + this.DisplayPanel.Name = "DisplayPanel"; + this.DisplayPanel.Size = new System.Drawing.Size(464, 419); + this.DisplayPanel.TabIndex = 3; + this.DisplayPanel.Paint += new System.Windows.Forms.PaintEventHandler(this.DisplayPanel_Paint); + this.DisplayPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DisplayPanel_MouseDown); + this.DisplayPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.DisplayPanel_MouseMove); + this.DisplayPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.DisplayPanel_MouseUp); + // + // openFileDialog1 + // + this.openFileDialog1.DefaultExt = "txt"; + this.openFileDialog1.Filter = "Text Files | *.txt"; + this.openFileDialog1.Title = "Open Custom Data File ..."; + // + // saveFileDialog1 + // + this.saveFileDialog1.DefaultExt = "txt"; + this.saveFileDialog1.Filter = "Text Files | *.txt"; + this.saveFileDialog1.Title = "Save Custom Data ..."; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(623, 465); + this.Controls.Add(this.DisplayPanel); + this.Controls.Add(this.panel1); + this.Controls.Add(this.menuStrip1); + this.Controls.Add(this.statusStrip1); + this.KeyPreview = true; + this.Name = "MainForm"; + this.Text = "Clipper Curves Demo"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MainForm_FormClosed); + this.Load += new System.EventHandler(this.MainForm_Load); + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown); + this.Resize += new System.EventHandler(this.MainForm_Resize); + this.statusStrip1.ResumeLayout(false); + this.statusStrip1.PerformLayout(); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel2; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem mExit; + private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem mIntersection; + private System.Windows.Forms.ToolStripMenuItem mUnion; + private System.Windows.Forms.ToolStripMenuItem mDifference; + private System.Windows.Forms.ToolStripMenuItem mXor; + private System.Windows.Forms.ToolStripMenuItem mNone; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem mEvenOdd; + private System.Windows.Forms.ToolStripMenuItem mNonZero; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem mNewPath; + private System.Windows.Forms.ToolStripMenuItem mUndo; + private System.Windows.Forms.ToolStripMenuItem mClear; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem quickTipsToolStripMenuItem; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button bNewPath; + private System.Windows.Forms.CheckBox cbReconstCurve; + private System.Windows.Forms.CheckBox cbShowCtrls; + private System.Windows.Forms.ToolStripMenuItem mSaveAs; + private System.Windows.Forms.ToolStripMenuItem mLoad; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; + private MainForm.MyDisplayPanel DisplayPanel; + private System.Windows.Forms.RadioButton rbSubjEllipses; + private System.Windows.Forms.RadioButton rbSubjArc; + private System.Windows.Forms.RadioButton rbSubjQBezier; + private System.Windows.Forms.RadioButton rbSubjCBezier; + private System.Windows.Forms.RadioButton rbSubjLine; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.RadioButton rbClipPoly; + private System.Windows.Forms.CheckBox cbSubjClosed; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4; + private System.Windows.Forms.ToolStripMenuItem mZoomIn; + private System.Windows.Forms.ToolStripMenuItem mZoomOut; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.SaveFileDialog saveFileDialog1; + private System.Windows.Forms.CheckBox cbShowCoords; + private System.Windows.Forms.ToolStripMenuItem mSave; + } +} + diff --git a/Curves/CurvesDemo/Form1.cs b/Curves/CurvesDemo/Form1.cs new file mode 100644 index 0000000..55912ee --- /dev/null +++ b/Curves/CurvesDemo/Form1.cs @@ -0,0 +1,834 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Drawing; +using System.IO; +using System.Drawing.Drawing2D; +using ClipperLib; +using ClipperMultiPathsLib; + +namespace Clipper_Lines_Demo +{ + + using Path = List; + using Paths = List>; + using cInt = Int64; + + public partial class MainForm : Form + { + + const int SUBJECT = 0, CLIP = 1; + const double scale = 10.0; //removes the blocky-ness associated with integer rounding. + const int btnRadius = (int)(3.0 * scale); //control button size + bool LeftButtonPressed = false; + int MovingButtonIdx = -1; + MultiPathSegment MovingButtonSeg = null; + MultiPaths allPaths = new MultiPaths(0.5 * scale); + public Bitmap bmp = null; + public Graphics bmpGraphics = null; + string AppTitle; + + public MainForm() + { + InitializeComponent(); + } + //------------------------------------------------------------------------------ + + //subclass Panel to stop redraw flicker ... + //http://stackoverflow.com/questions/8046560/how-to-stop-flickering-c-sharp-winforms + public class MyDisplayPanel : System.Windows.Forms.Panel + { + public MyDisplayPanel() + { + this.SetStyle( + System.Windows.Forms.ControlStyles.UserPaint | + System.Windows.Forms.ControlStyles.AllPaintingInWmPaint | + System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer, + true); + } + } + //------------------------------------------------------------------------------ + + private CurveType GetRadiobuttonPathType() + { + if (rbSubjArc.Checked) return CurveType.Arc; + else if (rbSubjCBezier.Checked) return CurveType.CubicBezier; + else if (rbSubjQBezier.Checked) return CurveType.QuadBezier; + else if (rbSubjEllipses.Checked) return CurveType.EllipticalArc; + else return CurveType.Line; + } + //------------------------------------------------------------------------------ + + private CurveType GetCurrentPathType(MultiPath mp) + { + if (mp.Count == 0) return CurveType.Line; + else return mp[mp.Count - 1].curvetype; + } + //------------------------------------------------------------------------------ + + private MultiPath GetCurrentSubjMultiPath() + { + for (int i = allPaths.Count - 1; i >= 0; i--) + if (allPaths[i].RefID == SUBJECT) return allPaths[i]; + return null; + } + //------------------------------------------------------------------------------ + + private MultiPath GetCurrentClipMultiPath() + { + for (int i = allPaths.Count - 1; i >= 0; i--) + if (allPaths[i].RefID == CLIP) return allPaths[i]; + return null; + } + //------------------------------------------------------------------------------ + + private void BmpUpdateNeeded() + { + const int textOffset = 20; + + if (bmpGraphics == null) return; + FillMode fm = (mEvenOdd.Checked ? FillMode.Alternate : FillMode.Winding); + bmpGraphics.Clear(Color.White); + + //draw the subject and clip paths ... + Paths openPaths = new Paths(); + Paths closedPaths = new Paths(); + Paths clipPaths = new Paths(); + //sort the paths into open and closed subjects and (closed) clips ... + foreach (MultiPath mp2 in allPaths) + if (mp2.RefID == CLIP) clipPaths.Add(mp2.Flatten()); + else if (mp2.IsClosed) closedPaths.Add(mp2.Flatten()); + else openPaths.Add(mp2.Flatten()); + + DrawPath(bmpGraphics, openPaths, false, 0x0, 0xFFAAAAAA, fm, 1.0); + DrawPath(bmpGraphics, closedPaths, true, 0x0, 0xFFAAAAAA, fm, 1.0); + DrawPath(bmpGraphics, clipPaths, true, 0x10FF6600, 0x99FF6600, fm, 1.0); + + if (cbShowCoords.Checked) + { + Font fnt = new Font("Arial", 8); + SolidBrush brush = new SolidBrush(Color.Navy); + foreach (MultiPath mp2 in allPaths) + { + foreach (MultiPathSegment mps in mp2) + foreach (IntPoint ip in mps) + { + IntPoint ip2 = new IntPoint(ip.X / scale, ip.Y / scale); + string coords = ip2.X.ToString() + "," + ip2.Y.ToString(); + bmpGraphics.DrawString(coords, fnt, brush, ip2.X - textOffset, ip2.Y - textOffset, null); + } + } + fnt.Dispose(); + brush.Dispose(); + } + + //for the active path, draw control buttons and control lines too ... + MultiPath activePath = GetActivePath(); + if (activePath != null && activePath.Count > 0) + { + foreach (MultiPathSegment mps in activePath) + { + CurveType pt = mps.curvetype; + if (pt == CurveType.CubicBezier) + DrawBezierCtrlLines(bmpGraphics, mps, 0xFFEEEEEE); + else if (pt == CurveType.QuadBezier) + DrawBezierCtrlLines(bmpGraphics, mps, 0xFFEEEEEE); + } + + DrawButtons(bmpGraphics, activePath); + + //display the coords of a moving button ... + if (MovingButtonIdx >= 0) + { + Font f = new Font("Arial", 8); + SolidBrush b = new SolidBrush(Color.Navy); + IntPoint ip = MovingButtonSeg[MovingButtonIdx]; + ip.X = (int)(ip.X / scale); ip.Y = (int)(ip.Y / scale); + string coords = ip.X.ToString() + "," + ip.Y.ToString(); + bmpGraphics.DrawString(coords, f, b, ip.X - textOffset, ip.Y - textOffset, null); + f.Dispose(); + b.Dispose(); + } + } + + //if there's any clipping to be done, do it here ... + if (!mNone.Checked && GetCurrentSubjMultiPath() != null && GetCurrentClipMultiPath() != null) + { + PolyFillType pft = (mEvenOdd.Checked ? PolyFillType.pftEvenOdd : PolyFillType.pftNonZero); + ClipType ct; + if (mUnion.Checked) ct = ClipType.ctUnion; + else if (mDifference.Checked) ct = ClipType.ctDifference; + else if (mXor.Checked) ct = ClipType.ctXor; + else ct = ClipType.ctIntersection; + + //CLIPPING DONE HERE ... + Clipper c = new Clipper(); + c.ZFillFunction = MultiPaths.ClipCallback; //set the callback function (called at intersections) + if (openPaths.Count > 0) + c.AddPaths(openPaths, PolyType.ptSubject, false); + if (closedPaths.Count > 0) + c.AddPaths(closedPaths, PolyType.ptSubject, true); + c.AddPaths(clipPaths, PolyType.ptClip, true); + PolyTree polytree = new PolyTree(); + + Paths solution; + c.Execute(ct, polytree, pft, pft); //EXECUTE CLIP !!!!!!!!!!!!!!!!!!!!!! + solution = Clipper.ClosedPathsFromPolyTree(polytree); + if (!cbReconstCurve.Checked) + DrawPath(bmpGraphics, solution, true, 0x2033AA00, 0xFF33AA00, fm, 2.0); + solution = Clipper.OpenPathsFromPolyTree(polytree); + if (!cbReconstCurve.Checked) + DrawPath(bmpGraphics, solution, false, 0x0, 0xFF33AA00, fm, 2.0); + + //now to demonstrate reconstructing beziers & arcs ... + if (cbReconstCurve.Checked) + { + PolyNode pn = polytree.GetFirst(); + while (pn != null) + { + if (pn.IsHole || pn.Contour.Count < 2) + { + pn = pn.GetNext(); + continue; + } + + if (pn.ChildCount > 0) + throw new Exception("Sorry, this demo doesn't currently handle holes"); + + //and reconstruct each curve ... + MultiPath reconstructedMultiPath = allPaths.Reconstruct(pn.Contour); + + if (cbShowCtrls.Enabled && cbShowCtrls.Checked) + { + //show (small) buttons on the red reconstructed path too ... + DrawButtons(bmpGraphics, reconstructedMultiPath, true); + } + + //now to show how accurate these reconstructed (control) paths are, + //we flatten them (drawing them red) so we can compare them with + //the original flattened paths (light gray) ... + Paths paths = new Paths(); + paths.Add(reconstructedMultiPath.Flatten()); + DrawPath(bmpGraphics, paths, !pn.IsOpen, 0x18FF0000, 0xFFFF0000, fm, 2.0); + + pn = pn.GetNext(); + } + } + //else //shows just how many vertices there are in flattened paths ... + //{ + // solution = Clipper.PolyTreeToPaths(polytree); + // MultiPath flatMultiPath = new MultiPath(null, 0, false); + // foreach (Path p in solution) + // flatMultiPath.NewMultiPathSegment(PathType.Line, p); + // DrawButtons(bmpGraphics, flatMultiPath, true); + //} + } + + string s = " "; + if (mIntersection.Checked) s += "INTERSECTION"; + else if (mUnion.Checked) s += "UNION"; + else if (mDifference.Checked) s += "DIFFERENCE"; + else if (mXor.Checked) s += "XOR"; + else s += "NO CLIPPING"; + s += " with "; + if (mEvenOdd.Checked) s += "EVENODD fill."; + else s += "NONZERO fill."; + toolStripStatusLabel2.Text = s; + DisplayPanel.Invalidate(); + } + //------------------------------------------------------------------------------ + + private void DisplayPanel_Paint(object sender, PaintEventArgs e) + { + if (bmp == null) return; + var g = e.Graphics; + g.DrawImage(bmp,0,0); + } + //------------------------------------------------------------------------------ + + private void mExit_Click(object sender, EventArgs e) + { + Close(); + } + //------------------------------------------------------------------------------ + + private static Color MakeColor(uint color) + { + return Color.FromArgb((int)color); + } + //------------------------------------------------------------------------------ + + private static void IntPointsToGraphicsPath(Path path, GraphicsPath gp, bool closed) + { + if (path.Count == 0) return; + PointF[] pts = new PointF[path.Count]; + int j = -1; + for (int i = 0; i < path.Count; ++i) + { + if (i > 0 && path[i] == path[j]) continue; + j++; + pts[j] = PathToPointF(path[i]); + } + j++; + if (j < path.Count) Array.Resize(ref pts, j); + if (closed && j > 2) + { + gp.AddPolygon(pts); + } + else + { + gp.StartFigure(); + gp.AddLines(pts); + } + } + //------------------------------------------------------------------------------ + + private static void DoublePointsToGraphicsPath(List path, GraphicsPath gp, bool closed) + { + if (closed && path.Count < 2) return; + else if (!closed && path.Count < 3) return; + + PointF[] pts = new PointF[path.Count]; + for (int i = 0; i < path.Count; ++i) + { + pts[i] = new PointF((float)(path[i].X / scale), (float)(path[i].Y / scale)); + } + if (closed) + gp.AddPolygon(pts); + else + { + gp.StartFigure(); + gp.AddLines(pts); + } + } + //------------------------------------------------------------------------------ + + private static PointF[] MakeButton(IntPoint ip, bool small) + { + float d1 = (small ? 3 : 4), d2 = (small ? 1.0f : 1.5f); + PointF[] btnPts = new PointF[8]; + Path p = new Path(8); + float x = (float)(ip.X / scale); + float y = (float)(ip.Y / scale); + btnPts[0] = new PointF(x - d2, y - d1); + btnPts[1] = new PointF(x + d2, y - d1); + btnPts[2] = new PointF(x + d1, y - d2); + btnPts[3] = new PointF(x + d1, y + d2); + btnPts[4] = new PointF(x + d2, y + d1); + btnPts[5] = new PointF(x - d2, y + d1); + btnPts[6] = new PointF(x - d1, y + d2); + btnPts[7] = new PointF(x - d1, y - d2); + return btnPts; + } + //------------------------------------------------------------------------------ + + private static void DrawButtons(Graphics graphics, MultiPath mp, bool small = false) + { + if (mp == null || mp.Count == 0) return; + GraphicsPath gpath = new GraphicsPath(FillMode.Alternate); + SolidBrush midBrush, startBrush, endBrush; + Pen pen; + if (small) + { + midBrush = new SolidBrush(MakeColor(0xFFFFAAAA)); + startBrush = new SolidBrush(MakeColor(0xFFFFAAAA)); + endBrush = new SolidBrush(MakeColor(0xFFFFAAAA)); + pen = new Pen(MakeColor(0xFF660000), 1.0f); + } + else + { + midBrush = new SolidBrush(MakeColor(0x20808080)); + startBrush = new SolidBrush(MakeColor(0x9980FF80)); + endBrush = new SolidBrush(MakeColor(0x99FA8072)); + pen = new Pen(Color.Black, 1.0f); + } + foreach (MultiPathSegment mps in mp) + { + int len = mps.Count; + if (len == 0) continue; + + for (int j = 0; j < len; ++j) + { + PointF[] btnPts = MakeButton(mps[j], small); + gpath.AddPolygon(btnPts); + } + graphics.FillPath(midBrush, gpath); + graphics.DrawPath(pen, gpath); + gpath.Reset(); + } + + //draw the start button a shade of green ... + if (mp.Count > 0 && mp[0].Count > 0) + { + gpath.AddPolygon(MakeButton(mp[0][0], small)); + graphics.FillPath(startBrush, gpath); + + MultiPathSegment mps = mp[mp.Count - 1]; + //draw the end button a shade of red ... + if (mps.index > 0 || mps.Count > 1) + { + gpath.Reset(); + gpath.AddPolygon(MakeButton(mps[mps.Count -1], small)); + graphics.FillPath(endBrush, gpath); + } + } + + //clean-up + midBrush.Dispose(); + startBrush.Dispose(); + endBrush.Dispose(); + pen.Dispose(); + gpath.Dispose(); + } + //------------------------------------------------------------------------------ + + private static PointF PathToPointF(IntPoint ip) + { + PointF result = new PointF((float)(ip.X / scale), (float)(ip.Y / scale)); + return result; + } + //------------------------------------------------------------------------------ + + private static void DrawBezierCtrlLines(Graphics graphics, + MultiPathSegment mps, uint color) + { + int cnt = mps.Count; + if (cnt < 2) return; + Pen pen = new Pen(MakeColor(color)); + GraphicsPath gpath = new GraphicsPath(); + PointF[] pts = new PointF[2]; + pts[0] = PathToPointF(mps[0]); + pts[1] = PathToPointF(mps[1]); + gpath.StartFigure(); + gpath.AddLines(pts); + + if (mps.IsValid()) + if (mps.curvetype == CurveType.CubicBezier) + { + pts[0] = PathToPointF(mps[2]); + pts[1] = PathToPointF(mps[3]); + gpath.StartFigure(); + gpath.AddLines(pts); + } + else + { + pts[0] = PathToPointF(mps[2]); + gpath.StartFigure(); + gpath.AddLines(pts); + } + + graphics.DrawPath(pen, gpath); + pen.Dispose(); + gpath.Dispose(); + } + //------------------------------------------------------------------------------ + + private static void DrawPath(Graphics graphics, Paths paths, bool closed, + uint brushClr, uint penClr, + FillMode fillMode = FillMode.Alternate, double penWidth = 1.0) + { + if (paths.Count == 0) return; + + SolidBrush brush = new SolidBrush (MakeColor(brushClr)); + Pen pen = new Pen(MakeColor(penClr), (float)penWidth); + GraphicsPath gpath = new GraphicsPath(fillMode); + try + { + for (int i = 0; i < paths.Count; ++i) + IntPointsToGraphicsPath(paths[i], gpath, closed); + if (closed) graphics.FillPath(brush, gpath); + graphics.DrawPath(pen, gpath); + } + finally + { + brush.Dispose(); + pen.Dispose(); + gpath.Dispose(); + } + } + //------------------------------------------------------------------------------ + + private MultiPath GetActivePath() + { + if (rbClipPoly.Checked) + { + MultiPath mp = GetCurrentClipMultiPath(); + if (mp == null) return allPaths.NewMultiPath(CLIP, true); + else return mp; + } + else + { + MultiPath mp = GetCurrentSubjMultiPath(); + if (mp == null) return allPaths.NewMultiPath(SUBJECT, false); + else return mp; + } + } + //------------------------------------------------------------------------------ + + private int GetButtonIndex(IntPoint mousePt, out MultiPathSegment mps) + { + MultiPath mp = GetActivePath(); + mps = null; + if (mp.Count == 0) return -1; + for (int i = 0; i < mp.Count; i++) + for (int j = 0; j < mp[i].Count; j++) + if (Math.Abs(mp[i][j].X - mousePt.X) <= btnRadius && + Math.Abs(mp[i][j].Y - mousePt.Y) <= btnRadius) + { + mps = mp[i]; + return j; + } + return -1; + } + //------------------------------------------------------------------------------ + + private void DisplayPanel_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + mNewPath_Click(sender, e); + MovingButtonIdx = -1; + } + else if (DisplayPanel.Cursor == Cursors.Hand) + { + MovingButtonIdx = GetButtonIndex(new IntPoint(e.X * scale, e.Y * scale), out MovingButtonSeg); + BmpUpdateNeeded(); + } + else + { + //Add a new control point ... + + CurveType rbPathType = GetRadiobuttonPathType(); + MultiPath mp = GetActivePath(); + if (mp.Count == 0) + mp.NewMultiPathSegment(rbPathType, new Path()); + else if (rbPathType != GetCurrentPathType(mp)) + { + if (rbPathType != GetCurrentPathType(mp)) + { + Path tmp = new Path(); + if (!mp.IsValid()) + { + MultiPathSegment mps = mp[mp.Count - 1]; + foreach (IntPoint ip in mps) tmp.Add(ip); + mp.RemoveLast(); + } + mp.NewMultiPathSegment(rbPathType, tmp); + } + } + if (!mp[mp.Count - 1].Add(new IntPoint(e.X * scale, e.Y * scale))) + { + mp.NewMultiPathSegment(rbPathType, new Path()); + mp[mp.Count - 1].Add(new IntPoint(e.X * scale, e.Y * scale)); + } + + UpdateBtnAndMenuState(); + BmpUpdateNeeded(); + MovingButtonIdx = -1; + } + LeftButtonPressed = (e.Button == MouseButtons.Left); + } + //------------------------------------------------------------------------------ + + private void DisplayPanel_MouseMove(object sender, MouseEventArgs e) + { + if (LeftButtonPressed) + { + if (MovingButtonIdx < 0) return; + MultiPath mp = GetActivePath(); + if (MovingButtonIdx >= MovingButtonSeg.Count) return; + MovingButtonSeg.Move(MovingButtonIdx, new IntPoint(e.X * scale, e.Y * scale)); + BmpUpdateNeeded(); + } + else + { + int i = GetButtonIndex(new IntPoint(e.X * scale, e.Y * scale), out MovingButtonSeg); + DisplayPanel.Cursor = (i >= 0 ? Cursors.Hand : Cursors.Default); + } + } + //------------------------------------------------------------------------------ + + private void DisplayPanel_MouseUp(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) LeftButtonPressed = false; + if (MovingButtonIdx >= 0) + { + MovingButtonIdx = -1; + BmpUpdateNeeded(); + } + } + //------------------------------------------------------------------------------ + + private void MainForm_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyValue == (int)Keys.Escape) Close(); + else if (e.KeyValue == (int)Keys.Z && e.Control) mUndo_Click(sender, e); + } + //------------------------------------------------------------------------------ + + private void UpdateBtnAndMenuState() + { + mClear.Enabled = allPaths.Count > 0; + MultiPath mp = GetActivePath(); + int cnt = allPaths.Count; + MultiPath subjMp = GetCurrentSubjMultiPath(); + + cbSubjClosed.Checked = (subjMp != null && subjMp.IsClosed); + if (mp.Count == 0) + { + mUndo.Enabled = mp.owner.Count > 0; + mNewPath.Enabled = false; + bNewPath.Enabled = false; + return; + } + int j = mp[mp.Count - 1].Count; + mUndo.Enabled = (mp.Count > 1 || j > 0); + bNewPath.Enabled = mp.IsValid(); + mNewPath.Enabled = bNewPath.Enabled; + } + //------------------------------------------------------------------------------ + + private void mClipType_Click(object sender, EventArgs e) + { + mIntersection.Checked = (sender == mIntersection); + mUnion.Checked = (sender == mUnion); + mDifference.Checked = (sender == mDifference); + mXor.Checked = (sender == mXor); + mNone.Checked = (sender == mNone); + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void mFillType_Clicked(object sender, EventArgs e) + { + mEvenOdd.Checked = (sender == mEvenOdd); + mNonZero.Checked = (sender == mNonZero); + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void mUndo_Click(object sender, EventArgs e) + { + MultiPath mp = GetActivePath(); + if (mp.Count == 0) + { + if (mp.owner.Count == 1) return; + else mp.owner.RemoveAt(mp.owner.Count -1); + } + else + { + MultiPathSegment mps = mp[mp.Count - 1]; + if (!mps.RemoveLast()) mp.RemoveLast(); + } + UpdateBtnAndMenuState(); + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void mClear_Click(object sender, EventArgs e) + { + allPaths.Clear(); + UpdateBtnAndMenuState(); + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void mNewPath_Click(object sender, EventArgs e) + { + MultiPath mp = GetActivePath(); + if (!mp.IsValid()) return; + int refID = (rbClipPoly.Checked ? CLIP : SUBJECT); + mp.owner.NewMultiPath((UInt16)refID, mp.IsClosed); + UpdateBtnAndMenuState(); + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void rbAdd_Click(object sender, EventArgs e) + { + UpdateBtnAndMenuState(); + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void OnLoadResize(bool isLoading) + { + if (bmp != null) bmp.Dispose(); + if (bmpGraphics != null) bmpGraphics.Dispose(); + Rectangle r = DisplayPanel.ClientRectangle; + bmp = new Bitmap(r.Right, r.Height); + bmpGraphics = Graphics.FromImage(bmp); + bmpGraphics.SmoothingMode = SmoothingMode.AntiAlias; + bmpGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic; + + toolStripStatusLabel2.Width = statusStrip1.ClientSize.Width - + toolStripStatusLabel1.Width - statusStrip1.ClientSize.Height; + + if (!isLoading) BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void MainForm_Resize(object sender, EventArgs e) + { + OnLoadResize(false); + } + //------------------------------------------------------------------------------ + + private void MainForm_Load(object sender, EventArgs e) + { + OnLoadResize(true); + cbReconstCurve.Text = "Redraw &Reconstructed\nOpen Curves ( bold red )"; + AppTitle = this.Text + " - "; + } + //------------------------------------------------------------------------------ + + private void MainForm_FormClosed(object sender, FormClosedEventArgs e) + { + if (bmp != null) bmp.Dispose(); + if (bmpGraphics != null) bmpGraphics.Dispose(); + } + //------------------------------------------------------------------------------ + + private void quickTipsToolStripMenuItem_Click(object sender, EventArgs e) + { + MessageBox.Show(this, + "Ctrl+I - for Intersection operations\n" + + "Ctrl+U - for Union operations \n" + + "Ctrl+D - for Difference operations \n" + + "Ctrl+X - for XOR operations \n" + + "Ctrl+Q - clipping off \n" + + "------------------------------ \n" + + "Ctrl+E - for EvenOdd fills \n" + + "Ctrl+N - for NonZero fills \n" + + "------------------------------ \n" + + "Ctrl+P or RightClick - start new path \n" + + "Ctrl+Z - Undo last Button entry \n" + + "Ctrl+C - Clear \n" + + "------------------------------ \n" + + "F1 - to see these tips again \n" + + "Esc - to quit \n", + this.Text); + } + //------------------------------------------------------------------------------ + + private void cbReconstCurve_Click(object sender, EventArgs e) + { + cbShowCtrls.Enabled = cbReconstCurve.Checked; + if (allPaths.Count > 0 && GetCurrentSubjMultiPath() != null && + GetCurrentClipMultiPath() != null) + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void cbShowCtrls_Click(object sender, EventArgs e) + { + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void mSave_Click(object sender, EventArgs e) + { + if (openFileDialog1.FileName == "") + { + mSaveAs_Click(sender, e); + return; + } + StreamWriter writer = new StreamWriter(openFileDialog1.FileName); + if (writer == null) return; + writer.Write(allPaths.ToSvgString()); + writer.Close(); + } + //------------------------------------------------------------------------------ + + private void mSaveAs_Click(object sender, EventArgs e) + { + if (allPaths.Count == 0 || (allPaths.Count == 1 && allPaths[0].Count < 2)) + return; + if (openFileDialog1.FileName != "") + saveFileDialog1.FileName = openFileDialog1.FileName; + if (saveFileDialog1.ShowDialog() != DialogResult.OK) return; + openFileDialog1.FileName = saveFileDialog1.FileName; + this.Text = AppTitle + System.IO.Path.GetFileName(openFileDialog1.FileName); + StreamWriter writer = new StreamWriter(saveFileDialog1.FileName); + if (writer == null) return; + writer.Write(allPaths.ToSvgString()); + writer.Close(); + } + //------------------------------------------------------------------------------ + + private void mOpen_Click(object sender, EventArgs e) + { + if (openFileDialog1.ShowDialog() != DialogResult.OK) return; + allPaths.Clear(); + this.Text = AppTitle + System.IO.Path.GetFileName(openFileDialog1.FileName); + StreamReader sr = new StreamReader(openFileDialog1.FileName); + allPaths.FromSvgString(sr.ReadToEnd()); + sr.Close(); + UpdateBtnAndMenuState(); + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void cbSubjClosed_Click(object sender, EventArgs e) + { + MultiPath mp = GetCurrentSubjMultiPath(); + if (mp == null) allPaths.NewMultiPath(SUBJECT, false); + mp.IsClosed = cbSubjClosed.Checked; + if (rbClipPoly.Checked) + { + if (mp.Count == 0) rbSubjLine.Checked = true; + else + switch (mp[mp.Count - 1].curvetype) + { + case CurveType.Line: rbSubjLine.Checked = true; break; + case CurveType.Arc: rbSubjArc.Checked = true; break; + case CurveType.CubicBezier: rbSubjCBezier.Checked = true; break; + case CurveType.QuadBezier: rbSubjQBezier.Checked = true; break; + //case CurveType.EllipticalArc: rbSubjEllipses.Checked = true; break; + } + } + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void ScaleMultiPaths(MultiPaths multiP, double scale) + { + foreach (MultiPath mp in multiP) + foreach (MultiPathSegment mps in mp) + for (int i = 0; i < mps.Count; i++) + { + if (i == 0 && mps.index > 0) continue; + IntPoint ip = new IntPoint(mps[i].X * scale, mps[i].Y * scale, mps[i].Z); + mps.Move(i, ip); + } + } + //------------------------------------------------------------------------------ + + private void mZoomIn_Click(object sender, EventArgs e) + { + ScaleMultiPaths(allPaths, 2.0); + UpdateBtnAndMenuState(); + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void mZoomOut_Click(object sender, EventArgs e) + { + ScaleMultiPaths(allPaths, 0.5); + UpdateBtnAndMenuState(); + BmpUpdateNeeded(); + } + //------------------------------------------------------------------------------ + + private void cbShowCoords_Click(object sender, EventArgs e) + { + BmpUpdateNeeded(); + } + + } + + //--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + + +} diff --git a/Curves/CurvesDemo/Form1.resx b/Curves/CurvesDemo/Form1.resx new file mode 100644 index 0000000..b9db74c --- /dev/null +++ b/Curves/CurvesDemo/Form1.resx @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 236, 17 + + + 345, 17 + + + 475, 17 + + + 45 + + \ No newline at end of file diff --git a/Curves/CurvesDemo/MultiPaths.cs b/Curves/CurvesDemo/MultiPaths.cs new file mode 100644 index 0000000..3294136 --- /dev/null +++ b/Curves/CurvesDemo/MultiPaths.cs @@ -0,0 +1,1777 @@ +/******************************************************************************* +* * +* Author : Angus Johnson * +* Version : 0.5 pre-alpha * +* Date : 26 October 2013 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2013 * +* * +* License: * +* Use, modification & distribution is subject to Boost Software License Ver 1. * +* http://www.boost.org/LICENSE_1_0.txt * +* * +*******************************************************************************/ + +/******************************************************************************* +MultiPathSegment: +A MultiPathSegment represents a single curve defined by control points. All +(subclassed) MultiPathSegment have a set number of control points except for +the MultiPathSegment representing a series of polylines (MpsLine) which accepts +a variable number of 'control' points. The MultiPathSegment class representing +a cubic bezier - MpsCBezier - accepts 4 control points. An MpsElipticalArc +MultiPathSegment accepts 5 control points. Multiple curves of the same type in +a series (eg a series of cubic beziers) are represented by multiple +MultiPathSegments. A MultiPathSegment of CurveType.Line is the only 'curve' +type that accepts a variable number of control points. + +MultiPath: +MultiPath represents a list of connected MultiPathSegment. A single MultiPath +can contain up to 32,000 MultiPathSegment, and these MultiPathSegments may be +of any type or mixture of types. + +MultiPaths: +A MultiPaths object contains a list of MultiPath objects. +*******************************************************************************/ + + +using System; +using System.Collections; +using System.Collections.Generic; +using ClipperLib; +//using System.Diagnostics; //for debugging only +//using System.Windows.Forms; //for debugging only + +namespace ClipperMultiPathsLib +{ + + using Path = List; + using Paths = List>; + using IntList = List; + + //nb: The Arc implementation will probably be merged into the more generic EllipitcalArc. + public enum CurveType { Unknown, Line, CubicBezier, QuadBezier, Arc, EllipticalArc}; + + //------------------------------------------------------------------------------ + // MultiPaths + //------------------------------------------------------------------------------ + + public class MultiPaths + { + + public const double DefaultPrecision = 0.5; + public double Precision { get { return precision; } } + public int Count { get { return MultiPathList.Count; } } + + private double precision; + private List MultiPathList = new List(); + + //--------------------------------------------------------------------------- + //Format of IntPoint Z's 64bit value (in flattened paths) + //given that each vertex belongs to a MultiPathSegment within a MultiPath + //within a MultiPaths container object ... + //--------------------------------------------------------------------------- + //mpRef 16 (bits 48..63): User-defined MultiPath reference ID (eg for filtering) + //ovrLp 1 (bit 47): Overlap flag - for vertices shared by adjacent segments + //mpIdx 16 (bits 32..46): Index of a MultiPath (within a MultiPaths container) + //mpsIdx 15 (bits 16..30): Index of a MultiPathSegment within a MultiPath + //mpSort 16 (bits 0..15): Sort value (based on position in flattened path) + + internal static Int64 MakeZ(UInt16 mpRef, UInt16 mpIdx, UInt16 mpsIdx, UInt16 sort) + { + return (Int64)((UInt64)mpRef << 48 | (UInt64)mpIdx << 32 | (UInt64)mpsIdx << 16 | sort); + } + //--------------------------------------------------------------------------- + + public static void ClipCallback(IntPoint vert1, IntPoint vert2, ref IntPoint intersectPt) + { + //This function is called when a Clipper object encounters an intersection. + //The 'Z' values generated by MultiPaths are always even (see MakeZ) so that + //generating odd values here flags to Reconstruct() that the vertex is at an + //intersection while also preserving sort order ... + + if (Math.Abs(vert1.Z - vert2.Z) == 2) + { + //adjacent vertices in same segment + intersectPt.Z = vert1.Z; + intersectPt.Z = (Int64)((UInt64)vert1.Z & 0xFFFFFFFF00000000 | + ((UInt32)vert1.Z + (UInt32)vert2.Z)) / 2; + } + else if (Math.Abs((vert1.Z & 0xFFFF) - (vert2.Z & 0xFFFF)) == 2 && + Math.Abs(((vert1.Z >> 16) & 0xFFFF7FFFFFFF) - ((vert2.Z >> 16) & 0xFFFF7FFFFFFF)) < 2) + { + //adjacent vertices, one being an overlap vertex from the same or adjacent segment + intersectPt.Z = (((UInt64)vert1.Z & 0xFFFF7FFFFFFF0000) != 0 ? vert2.Z : vert1.Z) + + ((vert1.Z & 0xFFFF) + (vert2.Z & 0xFFFF)) / 2; + } + else + { + //we've hit the end of a segment (nb: stripping of any overlap flag too) + if ((UInt32)vert1.Z == 0) + intersectPt.Z = (Int64)((UInt64)vert2.Z & 0xFFFF7FFFFFFFFFFF) + 1; + else if ((UInt32)vert2.Z == 0) + intersectPt.Z = (Int64)((UInt64)vert1.Z & 0xFFFF7FFFFFFFFFFF) + 1; + else if (vert1.Z > vert2.Z) + intersectPt.Z = (Int64)((UInt64)vert2.Z & 0xFFFF7FFFFFFFFFFF) + 1; + else + intersectPt.Z = (Int64)((UInt64)vert1.Z & 0xFFFF7FFFFFFFFFFF) + 1; + } + } + //--------------------------------------------------------------------------- + + public MultiPaths(double precision = 0) + { + this.precision = (precision <= 0 ? DefaultPrecision : precision); + } + //--------------------------------------------------------------------------- + + public MultiPath this[int i] + { + get { return MultiPathList[i]; } + } + //--------------------------------------------------------------------------- + + public IEnumerator GetEnumerator() + { + foreach (MultiPath mp in MultiPathList) yield return mp; + } + //--------------------------------------------------------------------------- + + public void Clear() { MultiPathList.Clear(); } + //--------------------------------------------------------------------------- + + public bool RemoveAt(int i) + { + if (i < 0 || i >= Count) return false; + MultiPathList.RemoveAt(i); + return true; + } + //--------------------------------------------------------------------------- + + public MultiPath NewMultiPath(UInt16 refID, bool isClosedPath = false) + { + //nb: a MultiPath can be closed later too + if (Count > 0) + { + //if there's an empty MultiPath at the end then just use that ... + MultiPath mp = MultiPathList[Count - 1]; + if (mp.Count == 0) + { + mp.RefID = refID; + mp.IsClosed = isClosedPath; + return mp; + } + } + MultiPath newPath = new MultiPath(this, refID, isClosedPath); + MultiPathList.Add(newPath); + return newPath; + } + //--------------------------------------------------------------------------- + + internal int GetMultiIndex(Int64 Z) + { + return (int)((Z >> 32) & 0x7FFF); //nb: ignore the top (overlap) bit + } + //--------------------------------------------------------------------------- + + internal MultiPath GetMultiPath(Int64 Z) + { + int idx = GetMultiIndex(Z); + if (idx >= 0 && idx < Count) return MultiPathList[idx]; + else return null; + } + //--------------------------------------------------------------------------- + + internal static bool IsAdjacent(Int64 Z1, Int64 Z2) + { + //nb: Generally, uninterupted edges have the Z values of adjacent vertices + //differing by exactly 2 units. However, since Clipper removes collinear + //vertices, we need to accommodate differences of up to a tolerance. + const int tolerance = 6; + return Math.Abs((Z1 & 0xFFFFFFFFFFFF) - (Z2 & 0xFFFFFFFFFFFF)) <= tolerance; + } + //--------------------------------------------------------------------------- + + internal static bool IsOverlap(Int64 Z) + { + return Globals.Odd(Z >> 47); + } + //--------------------------------------------------------------------------- + + internal static bool IsOverlap(Int64 adjacentZ, Int64 currentZ) + { + //nb: returns false if currentZ is also an overlap ... + const int tolerance = 6; + return Math.Abs((adjacentZ & 0xFFFF) - (currentZ & 0xFFFF)) <= tolerance && + Globals.Even(currentZ >> 47) && Globals.Odd(adjacentZ >> 47) && + Math.Abs(((adjacentZ >> 16) & 0x7FFFFFFF) - ((currentZ >> 16) & 0x7FFFFFFF)) < 2; + } + //--------------------------------------------------------------------------- + + public MultiPath Reconstruct(Path flatPath) + { + int highI = flatPath.Count -1; + //nb: the MultiPath result has NO owner + MultiPath result = new MultiPath(null, 0, false); + MultiPath mp1 = GetMultiPath(flatPath[0].Z); + + if (highI < 0) return result; + else if (highI < 6) + { + //it's inefficient reconstructing very short curved segments, so + //manage these simply by creating a polyline segment ... + result.NewMultiPathSegment(CurveType.Line, flatPath); + result.IsClosed = (mp1 != null && mp1.IsClosed); + return result; + } + MultiPath mp2 = GetMultiPath(flatPath[highI].Z); + + if (mp1 == null || mp2 == null) + throw new MultiPathException("Reconstruct error: a vertex doesn't belong to this MultiPaths object"); + if (mp1.IsClosed != mp2.IsClosed) + throw new MultiPathException("Reconstruct error: can't combine open and closed paths"); + + Path p = new Path(); + result.IsClosed = mp1.IsClosed; + + //start by stripping off non-adjacent vertices, + //returning then as a (still flat) polyline ... + int i = 0; + while (i < highI && !IsAdjacent(flatPath[i].Z, flatPath[i + 1].Z) && + !IsOverlap(flatPath[i].Z, flatPath[i + 1].Z)) i++; + if (i > 0) + { + for (int j = 0; j <= i; j++) p.Add(flatPath[j]); + result.NewMultiPathSegment(CurveType.Line, p); + p.Clear(); + } + + if (mp1.IsClosed && i == 0) + { + //nb: with closed paths, flatPath[0] may start in the middle of a multipathsegment, + //so first find the start of a multipath segment ... + if (IsOverlap(flatPath[highI].Z, flatPath[0].Z)) + p.Add(flatPath[highI]); + else if (IsAdjacent(flatPath[0].Z, flatPath[highI].Z)) + { + //avoid starting in the middle of a multipathsegment ... + int j = 1; + while (j < highI && IsAdjacent(flatPath[highI - j].Z, flatPath[highI - j + 1].Z)) j++; + if (IsOverlap(flatPath[highI - j].Z, flatPath[highI - j + 1].Z)) p.Add(flatPath[highI - j]); //nb: don't j++ this one! + for (int k = 1; k <= j; k++) p.Add(flatPath[highI - j + k]); + highI -= j; + } + } + + //OK, beyond here at least flatPath[i] & flatPath[i+1] should be adjacent vertices + while (i <= highI) + { + p.Add(flatPath[i++]); + //now complete then next series of vertices ... + while (i <= highI && IsAdjacent(flatPath[i - 1].Z, flatPath[i].Z)) + p.Add(flatPath[i++]); + //and if we've just hit an overlap, then include it too (and increment i) ... + if (i <= highI && IsOverlap(flatPath[i].Z, flatPath[i - 1].Z)) p.Add(flatPath[i++]); + + //p now contains a copy of adjacent vertices on a multipath + //so we can now perform the reconstruction ... + + mp1 = GetMultiPath(p[0].Z); + + //finally, something to reconstruct ////////////////////////// + mp2 = mp1.Reconstruct(p); //note new use for mp2 + ////////////////////////////////////////////////////////////// + + //and append each segment in mp2 to result ... + for (int j = 0; j < mp2.Count; j++) + { + MultiPathSegment mps; + if (j > 0 && mp2[j].curvetype == CurveType.Line && + result[result.Count - 1].curvetype == CurveType.Line) + mps = result[result.Count - 1]; + else + mps = result.NewMultiPathSegment(mp2[j].curvetype, null); + mp2[j].AppendTo(mps); + } + + if (i > highI) break; + p.Clear(); + mp1 = null; + //regardless of fp[i-1] 's overlap state, we need to add it to the new segment ... + p.Add(flatPath[i - 1]); + + //if at an overlap then continue ... + if (IsOverlap(flatPath[i - 1].Z, flatPath[i].Z)) continue; + + //otherwise, while there are mismatches, just make a polyline ... + while (i < highI && !IsAdjacent(flatPath[i - 1].Z, flatPath[i].Z) && + !IsOverlap(flatPath[i - 1].Z, flatPath[i].Z)) p.Add(flatPath[i++]); + if (i == highI) p.Add(flatPath[i++]); + result.NewMultiPathSegment(CurveType.Line, p); + p.Clear(); + p.Add(flatPath[i - 1]); + } + return result; + } + //--------------------------------------------------------------------------- + + //ToSvgString: a crude (temporary) function that stores MultiPaths data. + //Still need to merge consecutive CurveType.Line segments, and needs + //CurveType.Arc replaced with CurveType.EllipticalArc etc ... + + public string ToSvgString() + { + + string result = ""; + + foreach (MultiPath mp in MultiPathList) + { + if (!mp.IsValid()) continue; + IntPoint startPt = mp[0][0]; + result += string.Format("\r\n" : "\"/>\r\n"); + } + return result; + } + //--------------------------------------------------------------------------- + + private int NextAlpha(string text, int startingAt = 0) + { + int len = text.Length; + //very crude parsing for the time being (only accepts integers) ... + while (startingAt < len && (text[startingAt] < 'A' || text[startingAt] > 'Z')) startingAt++; + return startingAt; + } + //--------------------------------------------------------------------------- + + private void AddStringToPath(string text, Path path) + { + string[] vals = text.Split(new char[] { ' ', ','}, StringSplitOptions.RemoveEmptyEntries); + int cnt = vals.Length / 2; + for (int i = 0; i < cnt; i++) + { + int x, y; + if (!int.TryParse(vals[i *2], out x) || + !int.TryParse(vals[i *2 +1], out y)) break; + path.Add(new IntPoint(x, y)); + } + } + //--------------------------------------------------------------------------- + + //FromSvgString: a crude (temporary) function that loads MultiPaths data from storage + public void FromSvgString(string svgText) + { + string[] lines = svgText.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); + //1. find path statement ... + foreach (string line in lines) + { + int i = line.IndexOf(" 0) + { + path.Clear(); + path.Add(lastIp); + char c = pathStr[0]; + pathStr = pathStr.Substring(1); + AddStringToPath(pathStr, path); + int cnt = path.Count; + lastIp = path[path.Count - 1]; + switch (c) + { + case 'Z': + currMp.IsClosed = true; + currMp = null; + break; + case 'L': + if (currMp == null) currMp = NewMultiPath(0, false); + currMp.NewMultiPathSegment(CurveType.Line, path); + break; + case 'A': + if (currMp == null) currMp = NewMultiPath(0, false); + for (int m = 0; m < cnt / 2; m++) + { + currMp.NewMultiPathSegment(CurveType.Arc, path); + path.RemoveRange(0, 2); + } + break; + case 'C': + if (currMp == null) currMp = NewMultiPath(0, false); + for (int m = 0; m < cnt / 3; m++) + { + currMp.NewMultiPathSegment(CurveType.CubicBezier, path); + path.RemoveRange(0, 3); + } + break; + case 'Q': + if (currMp == null) currMp = NewMultiPath(0, false); + for (int m = 0; m < cnt / 2; m++) + { + currMp.NewMultiPathSegment(CurveType.QuadBezier, path); + path.RemoveRange(0, 2); + } + break; + default: return; + } + pathStr = pathStr.Substring(NextAlpha(pathStr)); + } + + } + } + + } //end MultiPaths + + //--------------------------------------------------------------------------- + // MultiPath + //--------------------------------------------------------------------------- + + public class MultiPath + { + + public MultiPaths owner; + public UInt16 index; + public UInt16 RefID; + + private double precision; + private List segments = new List(); + private int currFlatIdx; + private MultiPathSegment currMps; + private Path flatPath = new Path(); + + //--------------------------------------------------------------------------- + + public MultiPath(MultiPaths owner, UInt16 refID, bool isClosed) + { + this.owner = owner; + this.index = (owner == null ? (UInt16)0 : (UInt16)owner.Count); + this.RefID = refID; + this.precision = (owner != null ? owner.Precision : MultiPaths.DefaultPrecision); + this.IsClosed = isClosed; + } + //--------------------------------------------------------------------------- + + public MultiPathSegment this[int i] + { + get { return segments[i]; } + } + //--------------------------------------------------------------------------- + + public IEnumerator GetEnumerator() + { + foreach (MultiPathSegment mps in segments) yield return mps; + } + //--------------------------------------------------------------------------- + + public int Count { get { return segments.Count; } } + //--------------------------------------------------------------------------- + + public MultiPathSegment NewMultiPathSegment(CurveType pt, Path path) + { + if (Count > 0 && !segments[Count - 1].IsValid()) + throw new MultiPathException("MultiPath Error: Appending to an invalid MultiPath."); + + MultiPathSegment mps; + UInt16 idx = (UInt16)segments.Count; + switch (pt) + { + case CurveType.Arc: mps = new MpsArc(this, idx); break; + case CurveType.Line: mps = new MpsLine(this, idx); break; + case CurveType.CubicBezier: mps = new MpsCBezier(this, idx); break; + case CurveType.QuadBezier: mps = new MpsQBezier(this, idx); break; + default: return null; + } + if (path != null) + { + int highI = Math.Min(path.Count, mps.maxCtrlPts) - 1; + for (int i = 0; i <= highI; i++) mps.Add(path[i]); + //foreach (IntPoint ip in path) mps.Add(ip); + } + segments.Add(mps); + return mps; + } + //--------------------------------------------------------------------------- + + public void Clear() { segments.Clear(); } + //--------------------------------------------------------------------------- + + //removals are not allowed except from the path end (or the whole path) + //otherwise the logic is broken where adjacent segments share a common vertex. + //In other words, for segment removals ... use either Clear() or RemoveLast() + public void RemoveLast() + { + if (Count > 0) segments.RemoveAt(Count - 1); + } + //--------------------------------------------------------------------------- + + public bool IsValid() + { + int i = Count; + if (i == 0) return false; + return segments[i - 1].IsValid(); + } + //--------------------------------------------------------------------------- + + public bool IsClosed { get; set; } + //--------------------------------------------------------------------------- + + private static IntPoint StripTop48Bits(IntPoint ip) + { + IntPoint result = ip; + result.Z = ip.Z & 0xFFFF; + return result; + } + //--------------------------------------------------------------------------- + + public MultiPath Reconstruct(Path flatPath) + { + MultiPath result = new MultiPath(null, 0, false); + int highI = flatPath.Count - 1; + + //avoid reconstructing very short curves ... + if (highI < 4) + { + if (highI > 0) //ie don't bother if just a single vertex + result.NewMultiPathSegment(CurveType.Line, flatPath); + return result; + } + + if (IsClosed) AddClosingLineSeg(); + + int seg1 = (UInt16)(flatPath[1].Z >> 16) & 0xFFFF; //nb: list indices are offset + int seg2 = (UInt16)(flatPath[highI - 1].Z >> 16) & 0xFFFF; //to avoid 'overlap' vertices + + if (seg1 != seg2) + throw new MultiPathException("Reconstruct error: mixing segments"); + + MultiPathSegment mps = segments[seg1]; + if (mps.curvetype == CurveType.Line) + { + result.NewMultiPathSegment(CurveType.Line, flatPath); + return result; + } + + //avoid sorting based on either end as they may be 'overlap' vertices ... + bool reversed = ((Int16)flatPath[1].Z > (Int16)flatPath[2].Z); + if (reversed) flatPath.Reverse(); + + flatPath[0] = StripTop48Bits(flatPath[0]); + flatPath[highI] = StripTop48Bits(flatPath[highI]); + + if (!mps.Reconstruct(flatPath[0], flatPath[highI], result)) + { + if (reversed) flatPath.Reverse(); + result.NewMultiPathSegment(CurveType.Line, flatPath); + return result; + } + + int cnt = 0; + foreach (MultiPathSegment mpsr in result) + { + cnt += mpsr.Count; + if (reversed) mpsr.Reverse(); + } + if (reversed) result.segments.Reverse(); + + if (IsClosed) RemoveClosingLineSeg(); + + + //finally, if the reconstructed path has more controls than the flattened path has + //vertices (typically with some beziers), then return the path as a simple polyline ... + if (cnt > flatPath.Count) + { + result.Clear(); + if (reversed) flatPath.Reverse(); + result.NewMultiPathSegment(CurveType.Line, flatPath); + } + + return result; + } + //--------------------------------------------------------------------------- + + internal void FlattenAdd(MultiPathSegment mps, IntPoint ip) + { + if (currFlatIdx < 0) + currMps = mps; + else if (mps != currMps) + { + //starting a new MultiPathSegment ... + if (currMps != null) + { + //set a flag on the overlap vertex ... + IntPoint prevIp = flatPath[currFlatIdx]; + prevIp.Z = prevIp.Z | 0x800000000000; + flatPath[currFlatIdx] = prevIp; + } + currMps = mps; + if (ip == flatPath[currFlatIdx]) + { + mps.flattenOffset = flatPath.Count * 2 - 2; + return; + } + mps.flattenOffset = flatPath.Count * 2; + } + else if (ip == flatPath[currFlatIdx]) + return; //ignore duplicate vertices + + ip.Z = MultiPaths.MakeZ(RefID, index, (UInt16)mps.index, (UInt16)(flatPath.Count * 2)); + flatPath.Add(ip); + currFlatIdx++; + } + //--------------------------------------------------------------------------- + + private void AddClosingLineSeg() + { + //nb: adds a temporary line segment since further segments may be added + if (IsValid()) + { + IntPoint ip1, ip2; + ip1 = segments[0][0]; + MultiPathSegment mps = segments[Count - 1]; + + ip2 = mps[mps.Count - 1]; + if (ip1 != ip2) + { + Path path = new Path(2); + path.Add(ip2); + path.Add(ip1); + mps = NewMultiPathSegment(CurveType.Line, path); + } + } + } + //--------------------------------------------------------------------------- + + private void RemoveClosingLineSeg() + { + if (Count > 1 & IsValid()) RemoveLast(); //nb: > 1 (NOT > 0) + } + //--------------------------------------------------------------------------- + + public Path Flatten() + { + currFlatIdx = -1; + flatPath.Clear(); + + if (IsClosed) AddClosingLineSeg(); + foreach (MultiPathSegment mps in segments) mps.Flatten(); + if (IsClosed) RemoveClosingLineSeg(); + + return flatPath; + } + //--------------------------------------------------------------------------- + + } //end MultiPath + + + //--------------------------------------------------------------------------- + // MultiPathSegment + //--------------------------------------------------------------------------- + + public abstract class MultiPathSegment + { + + public CurveType curvetype; + public MultiPath owner; + public UInt16 index; + + internal int flattenOffset; + internal int maxCtrlPts; + protected Path ctrls = new Path(); + + public MultiPathSegment(MultiPath owner, UInt16 index) + { + if (owner == null) + throw new MultiPathException("MultiPathSegments must have an owner."); + this.owner = owner; + this.index = index; + } + //------------------------------------------------------------------------------ + + public int Count { get { return ctrls.Count; } } + //------------------------------------------------------------------------------ + + public IntPoint this[int i] + { + get { return ctrls[i]; } + } + //--------------------------------------------------------------------------- + + public IEnumerator GetEnumerator() + { + foreach (IntPoint ip in ctrls) yield return ip; + } + //--------------------------------------------------------------------------- + + internal virtual void Flatten() + { + if (index < owner.Count - 1) + throw new MultiPathException("Flatten Error: undefined segment"); + } + //--------------------------------------------------------------------------- + + internal virtual bool IsValid() + { + return Count == maxCtrlPts; //maxCtrlPts is set in subclassed constructor + } + //--------------------------------------------------------------------------- + + internal void Reverse() + { + ctrls.Reverse(); + } + //--------------------------------------------------------------------------- + + protected double GetPrecision() + { + return (owner.owner != null ? owner.owner.Precision : MultiPaths.DefaultPrecision); + } + //--------------------------------------------------------------------------- + + public bool RemoveLast() + { + int i = Count; + if (i == 0) return false; + ctrls.RemoveAt(i - 1); + return true; + } + //------------------------------------------------------------------------------ + + public bool Add(IntPoint ip) + { + //copy the last point of the previous segment to the new segment ... + if (Count == 0) + { + if (index > 0) + { + IntPoint prev = GetPrevPt(); + if (prev != ip) ctrls.Add(prev); + } + } + else if (Count == maxCtrlPts) + return false; + else if (ip == ctrls[Count -1]) + return false; + ctrls.Add(ip); + return true; + } + //------------------------------------------------------------------------------ + + public void Move(int index, IntPoint newPt) + { + //if this is an overlap vertex then adjust the adjacent segment too ... + if (index == 0 && this.index > 0) + { + MultiPathSegment mpsPrev = owner[this.index - 1]; + mpsPrev.ctrls[mpsPrev.Count - 1] = newPt; + } + else if (IsValid() && index == Count -1 && this.index < owner.Count -1) + { + MultiPathSegment mpsNext = owner[this.index + 1]; + mpsNext.ctrls[0] = newPt; + } + ctrls[index] = newPt; + } + //------------------------------------------------------------------------------ + + public void AppendTo(MultiPathSegment mps) + { + foreach (IntPoint ip in ctrls) mps.ctrls.Add(ip); + } + //------------------------------------------------------------------------------ + + protected IntPoint GetPrevPt() + { + if (index == 0 || owner == null) + throw new MultiPathException("Error: no previous control point found"); + MultiPathSegment mps = owner[index - 1]; + return mps[mps.Count -1]; + } + //------------------------------------------------------------------------------ + + internal virtual bool Reconstruct(IntPoint startPt, IntPoint endPt, MultiPath mp) + { + return false; + } + //------------------------------------------------------------------------------ + + } + + //--------------------------------------------------------------------------- + // MpsLine class + //--------------------------------------------------------------------------- + + public class MpsLine : MultiPathSegment + { + public MpsLine(MultiPath owner, UInt16 index) + : base(owner, index) + { + curvetype = CurveType.Line; + maxCtrlPts = 0x7FFF; //~32000 + } + //--------------------------------------------------------------------------- + + internal override bool IsValid() + { + return Count > 0; + } + //--------------------------------------------------------------------------- + + internal override void Flatten() + { + if (!IsValid()) { base.Flatten(); return; } + for (int i = 0; i < Count; i++) + owner.FlattenAdd(this, ctrls[i]); + } + //--------------------------------------------------------------------------- + + } //end MpsLine class + + //--------------------------------------------------------------------------- + // MpsArc class + //--------------------------------------------------------------------------- + + public class MpsArc : MultiPathSegment + { + public DoublePoint origin; + public double radius = 0; + public bool isClockwise; + + public MpsArc(MultiPath owner, UInt16 index) + : base(owner, index) + { + curvetype = CurveType.Arc; + maxCtrlPts = 3; + } //constructor + //--------------------------------------------------------------------------- + + internal override bool IsValid() + { + return Count == 3; + } + //--------------------------------------------------------------------------- + + internal override void Flatten() + { + if (!IsValid()) { base.Flatten(); return; } + if (ctrls[0] == ctrls[2]) return; //empty arc + + DoublePoint p1 = new DoublePoint(ctrls[0]); + DoublePoint p2 = new DoublePoint(ctrls[1]); + DoublePoint p3 = new DoublePoint(ctrls[2]); + + if (!Globals.CircleFrom3Points(p1, p2, p3, out origin, out radius)) + { + //p1, p2 & p3 must be collinear, so ... + owner.FlattenAdd(this, ctrls[0]); + owner.FlattenAdd(this, ctrls[2]); + return; + } + + //store arc data ready for reconstruction ... + isClockwise = Globals.RightTurning(p1, p2, p3); + double a1 = Globals.GetAngle(origin, p1); + double a2 = Globals.GetAngle(origin, p3); + + double frac = Math.Abs(a2 - a1) / Globals.TwoPI; + if (isClockwise == (a2 >= a1)) frac = 1 - frac; + int steps = (int)Globals.Round(Globals.rad180 / Math.Acos(1 - GetPrecision() / radius)) + 1; + if (steps < 2) steps = 2; + double asin, acos, angle = frac * Globals.TwoPI / steps; + if (!isClockwise) angle = -angle; + Globals.SinCos(angle, out asin, out acos); + double x = ((double)p1.X - origin.X); + double y = ((double)p1.Y - origin.Y); + int j = 0; + for (; j < steps; j++) + { + owner.FlattenAdd(this, new IntPoint(Globals.Round(origin.X + x), Globals.Round(origin.Y + y))); + double x2 = x; + x = x * acos - asin * y; + y = x2 * asin + y * acos; + } + j++; + owner.FlattenAdd(this, ctrls[2]); + } + //--------------------------------------------------------------------------- + + internal override bool Reconstruct(IntPoint startPt, IntPoint endPt, MultiPath mp) + { + Path arcPath = new Path(); + + if (!IsValid() || radius == 0) + { + arcPath.Add(startPt); + arcPath.Add(endPt); + mp.NewMultiPathSegment(CurveType.Line, arcPath); + return false; + } + + if (startPt.Z == 0) startPt = ctrls[0]; + if (endPt.Z == 0) endPt = ctrls[2]; + + arcPath.Add(startPt); + double a1 = Globals.GetAngle(origin, new DoublePoint(startPt)); + double a2 = Globals.GetAngle(origin, new DoublePoint(endPt)); + double midA = Globals.GetMidAngle(a1, a2, isClockwise); + DoublePoint midPt = Globals.GetPointFromOrigin(origin, radius, midA); + arcPath.Add(new IntPoint(midPt)); + arcPath.Add(endPt); + mp.NewMultiPathSegment(CurveType.Arc, arcPath); + return true; + } + //--------------------------------------------------------------------------- + + } //end MpsArc class + + + //--------------------------------------------------------------------------- + // MpsEllipticalArc class + //--------------------------------------------------------------------------- + + public class MpsEllipticalArc : MultiPathSegment + { + public DoublePoint origin; + public DoublePoint radii; + public bool isClockwise; + public double ellipticalAngle; + + public MpsEllipticalArc(MultiPath owner, UInt16 index) + : base(owner, index) + { + curvetype = CurveType.EllipticalArc; + maxCtrlPts = 5; //startPt, Axis1Pt, OriginPt (Z:orientation), Axis2Pt, endPt + } //constructor + //--------------------------------------------------------------------------- + + internal override void Flatten() + { + if (!IsValid()) { base.Flatten(); return; } + if (ctrls[0] == ctrls[4]) return; //empty arc (full ellipses are ignored too) + + DoublePoint sp = new DoublePoint(ctrls[0]); + DoublePoint ep = new DoublePoint(ctrls[4]); + DoublePoint axis1 = new DoublePoint(ctrls[1]); + DoublePoint axis2 = new DoublePoint(ctrls[3]); + this.origin = new DoublePoint(ctrls[2]); + this.isClockwise = ctrls[2].Z >= 0; + this.radii = new DoublePoint(Globals.Distance(origin, axis1), Globals.Distance(origin, axis2)); + this.ellipticalAngle = Globals.GetAngle(origin, axis1); + if (ellipticalAngle > Globals.rad180) ellipticalAngle -= Globals.rad180; + List flat = + Globals.GetFlattenedEllipticalArc(origin, radii, + sp, ep, true, isClockwise, ellipticalAngle, GetPrecision()); + foreach (DoublePoint pt in flat) + owner.FlattenAdd(this, new IntPoint(pt)); + } + //--------------------------------------------------------------------------- + + internal override bool Reconstruct(IntPoint startPt, IntPoint endPt, MultiPath mp) + { + Path arcPath = new Path(); + + if (!IsValid() || radii.X == 0 || radii.Y == 0) + { + arcPath.Add(startPt); + arcPath.Add(endPt); + mp.NewMultiPathSegment(CurveType.Line, arcPath); + return false; + } + + if (startPt.Z == 0) startPt = ctrls[0]; + if (endPt.Z == 0) endPt = ctrls[4]; + + arcPath.Add(startPt); + arcPath.Add(ctrls[1]); + arcPath.Add(ctrls[2]); + arcPath.Add(ctrls[3]); + arcPath.Add(endPt); + mp.NewMultiPathSegment(CurveType.EllipticalArc, arcPath); + return true; + } + //--------------------------------------------------------------------------- + + } //end MpsEllipticalArc class + + //--------------------------------------------------------------------------- + // MpsBezier class + //--------------------------------------------------------------------------- + public abstract class MpsBezier : MultiPathSegment + { + + + internal List BezSegList = new List(); + internal BezSeg bezSegTree = null; + + //--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + internal class BezSeg + { + internal UInt16 RefID; + internal UInt16 SegID; + internal UInt32 Index; + internal DoublePoint[] Ctrls; + internal BezSeg[] Childs = new BezSeg[2]; + internal CurveType curvetype; + + internal BezSeg(UInt16 refID, UInt16 segID, UInt32 idx) + { + this.RefID = refID; + this.SegID = segID; + this.Index = idx; + } + + internal void GetFlattenedSeg(List bezSegs) + { + if (Childs[0] == null) + { + bezSegs.Add(this); + return; + } + Childs[0].GetFlattenedSeg(bezSegs); + Childs[1].GetFlattenedSeg(bezSegs); + } + + } + //--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + + internal class CBezSeg : BezSeg + { + internal CBezSeg(DoublePoint pt1, DoublePoint pt2, DoublePoint pt3, DoublePoint pt4, + UInt16 refID, UInt16 segID, UInt32 idx, double precision) + : base(refID, segID, idx) + { + curvetype = CurveType.CubicBezier; + Ctrls = new DoublePoint[4]; + Ctrls[0] = pt1; Ctrls[1] = pt2; Ctrls[2] = pt3; Ctrls[3] = pt4; + //assess curve flatness: + //http://groups.google.com/group/comp.graphics.algorithms ree/browse_frm hread/d85ca902fdbd746e + if (Math.Abs(pt1.X + pt3.X - 2 * pt2.X) + Math.Abs(pt2.X + pt4.X - 2 * pt3.X) + + Math.Abs(pt1.Y + pt3.Y - 2 * pt2.Y) + Math.Abs(pt2.Y + pt4.Y - 2 * pt3.Y) < precision) + return; + + //if not at maximum precision then (recursively) create sub-segments ... + //, p23, p34, p123, p234, p1234; + const double half = 0.5; + DoublePoint p12 = new DoublePoint((pt1.X + pt2.X) * half, (pt1.Y + pt2.Y) * half); + DoublePoint p23 = new DoublePoint((pt2.X + pt3.X) * half, (pt2.Y + pt3.Y) * half); + DoublePoint p34 = new DoublePoint((pt3.X + pt4.X) * half, (pt3.Y + pt4.Y) * half); + DoublePoint p123 = new DoublePoint((p12.X + p23.X) * half, (p12.Y + p23.Y) * half); + DoublePoint p234 = new DoublePoint((p23.X + p34.X) * half, (p23.Y + p34.Y) * half); + DoublePoint p1234 = new DoublePoint((p123.X + p234.X) * half, (p123.Y + p234.Y) * half); + idx = idx << 1; + Childs[0] = new CBezSeg(pt1, p12, p123, p1234, refID, segID, idx, precision); + Childs[1] = new CBezSeg(p1234, p234, p34, pt4, refID, segID, idx + 1, precision); + } + } //end CBezSeg + + internal class QBezSeg : BezSeg + { + internal QBezSeg(DoublePoint pt1, DoublePoint pt2, DoublePoint pt3, + UInt16 refID, UInt16 segID, UInt32 idx, double precision) + : base(refID, segID, idx) + { + curvetype = CurveType.QuadBezier; + Ctrls = new DoublePoint[3]; + Ctrls[0] = pt1; Ctrls[1] = pt2; Ctrls[2] = pt3; + //assess curve flatness: + if (Math.Abs(pt1.X + pt3.X - 2 * pt2.X) + Math.Abs(pt1.Y + pt3.Y - 2 * pt2.Y) < precision) return; + + //if not at maximum precision then (recursively) create sub-segments ... + //DoublePoint p12, p23, p123; + const double half = 0.5; + DoublePoint p12 = new DoublePoint((pt1.X + pt2.X) * half, (pt1.Y + pt2.Y) * half); + DoublePoint p23 = new DoublePoint((pt2.X + pt3.X) * half, (pt2.Y + pt3.Y) * half); + DoublePoint p123 = new DoublePoint((p12.X + p23.X) * half, (p12.Y + p23.Y) * half); + idx = idx << 1; + Childs[0] = new QBezSeg(pt1, p12, p123, refID, segID, idx, precision); + Childs[1] = new QBezSeg(p123, p23, pt3, refID, segID, idx + 1, precision); + } + } //end QBezSeg + //------------------------------------------------------------------------------ + + + public MpsBezier(MultiPath owner, UInt16 index) : base(owner, index) { } + //--------------------------------------------------------------------------- + + protected UInt32 GetMostSignificantBit(UInt32 v) //index is zero based + { + UInt32[] b = { 0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000 }; + Int32[] s = { 0x1, 0x2, 0x4, 0x8, 0x10 }; + Int32 result = 0; + for (int i = 4; i >= 0; --i) + if ((v & b[i]) != 0) + { + v = v >> s[i]; + result = result | s[i]; + } + return (UInt32)result; + } + //------------------------------------------------------------------------------ + + protected static bool IsBitSet(UInt32 val, Int32 index) + { + return (val & (1 << (int)index)) != 0; + } + //------------------------------------------------------------------------------ + + internal IntList BezierReconstruct(UInt32 startIdx, UInt32 endIdx) + { + IntList ilist = new IntList(); + + //get the maximum level ... + UInt32 L1 = GetMostSignificantBit(startIdx); + UInt32 L2 = GetMostSignificantBit(endIdx); + UInt32 Level = Math.Max(L1, L2); + + if (Level == 0) + { + ilist.Add(1); + return ilist; + } + + int L, R; + //Right marker (R): EndIdx projected onto the bottom level ... + if (endIdx == 1) + { + R = (1 << (int)((Level + 1))) - 1; + } + else + { + int k = (int)(Level - L2); + R = ((int)endIdx << k) + (1 << k) - 1; + } + + if (startIdx == 1) //special case + { + //Left marker (L) is bottom left of the binary tree ... + L = (1 << (int)Level); + L1 = Level; + } + else + { + L = (int)startIdx + 1; + if (L == (1 << (int)(Level + 1))) return ilist; //loops around tree so already at the end + } + + //now get blocks of nodes from the LEFT ... + int j = (int)(Level - L1); + do + { + //while next level up then down-right doesn't exceed L2 do ... + while (Globals.Even(L) && ((L << j) + (1 << (j + 1)) - 1 <= R)) + { + L = (L >> 1); //go up a level + j++; + } + ilist.Add(L); + L++; + } while (L != (3 << (int)(Level - j - 1)) && //ie crosses the ditch in the middle + (L << j) + (1 << j) < R); //or L is now over or to the right of R + + L = (L << j); + + //now get blocks of nodes from the RIGHT ... + List tmpList = new List(); + j = 0; + if (R >= L) + do + { + while (Globals.Odd(R) && ((R - 1) << j >= L)) + { + R = R >> 1; //go up a level + j++; + } + tmpList.Add(R); + R--; + } while (R != (3 << (int)(Level - j)) - 1 && ((R << j) > L)); + + for (j = tmpList.Count - 1; j >= 0; j--) + ilist.Add(tmpList[j]); + return ilist; + } + //------------------------------------------------------------------------------ + + internal override bool Reconstruct(IntPoint startPt, IntPoint endPt, MultiPath mp) + { + + if (!IsValid() || BezSegList.Count == 0) return false; + + uint startIdx, endIdx; + if (startPt.Z == 0 || startPt.Z == this.flattenOffset) + { + startIdx = 1; + } + else + { + startIdx = (uint)((Int16)startPt.Z - this.flattenOffset) / 2; + startIdx = BezSegList[(int)startIdx].Index; + } + + if (endPt.Z == 0) + { + endIdx = BezSegList[BezSegList.Count - 1].Index; + } + else + { + endIdx = (uint)((Int16)endPt.Z - this.flattenOffset) / 2; + if (endIdx > 0) endIdx--; + endIdx = BezSegList[(int)endIdx].Index; + } + + IntList intlist = BezierReconstruct(startIdx, endIdx); + //IntList now contains the indexes of one or a series of sub-segments + //that together define part of or the whole of the original bezier segment. + //We now append these sub-segments to the new list of control points ... + + for (int i = 0; i < intlist.Count; i++) + { + uint ii = (uint)intlist[i]; + BezSeg bs = this.bezSegTree; + Int32 k = (Int32)GetMostSignificantBit(ii) - 1; + while (k >= 0) + { + if (bs.Childs[0] == null) break; + if (IsBitSet(ii, k--)) + bs = bs.Childs[1]; + else + bs = bs.Childs[0]; + } + + if (i == 0 && startPt.Z != 0) + { + IntPoint pt = new IntPoint(bs.Ctrls[0]); + if (pt != startPt) + { + Path line = new Path(2); + line.Add(startPt); + line.Add(pt); + mp.NewMultiPathSegment(CurveType.Line, line); + } + } + Path bezCtrls = new Path(bs.Ctrls.Length); + foreach (DoublePoint dp in bs.Ctrls) + bezCtrls.Add(new IntPoint(dp)); + mp.NewMultiPathSegment(curvetype, bezCtrls); + + if (i == intlist.Count - 1 && endPt.Z != 0) + { + IntPoint pt = new IntPoint(bs.Ctrls[bs.Ctrls.Length - 1]); + if (pt != endPt) + { + Path line = new Path(2); + line.Add(pt); + line.Add(endPt); + mp.NewMultiPathSegment(CurveType.Line, line); + } + } + } + return true; + } + //--------------------------------------------------------------------------- + + }; //end MpsBezier + + public class MpsCBezier : MpsBezier + { + + public MpsCBezier(MultiPath owner, UInt16 index) + : base(owner, index) + { + curvetype = CurveType.CubicBezier; + maxCtrlPts = 4; + } + //--------------------------------------------------------------------------- + + internal override void Flatten() + { + if (!IsValid()) + { + if (index < owner.Count - 1) base.Flatten(); + return; + } + + DoublePoint [] c = new DoublePoint [4]; + //construct (recursively) the BezSeg tree structure ... + c[0] = new DoublePoint(ctrls[0]); + c[1] = new DoublePoint(ctrls[1]); + c[2] = new DoublePoint(ctrls[2]); + c[3] = new DoublePoint(ctrls[3]); + bezSegTree = new CBezSeg(c[0], c[1], c[2], c[3], this.index, 0, 1, GetPrecision()); + + BezSegList.Clear(); + bezSegTree.GetFlattenedSeg(BezSegList); + owner.FlattenAdd(this, new IntPoint(BezSegList[0].Ctrls[0])); + foreach (BezSeg bs in BezSegList) + owner.FlattenAdd(this, new IntPoint(bs.Ctrls[3])); + } + //--------------------------------------------------------------------------- + + } //end MpsCBezier class + //--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + + public class MpsQBezier : MpsBezier + { + + public MpsQBezier(MultiPath owner, UInt16 index) + : base(owner, index) + { + curvetype = CurveType.QuadBezier; + maxCtrlPts = 3; + } + //--------------------------------------------------------------------------- + + internal override void Flatten() + { + if (!IsValid()) + { + if (index < owner.Count - 1) base.Flatten(); + return; + } + + DoublePoint[] c = new DoublePoint[3]; + //construct (recursively) the BezSeg tree structure ... + c[0] = new DoublePoint(ctrls[0]); + c[1] = new DoublePoint(ctrls[1]); + c[2] = new DoublePoint(ctrls[2]); + bezSegTree = new QBezSeg(c[0], c[1], c[2], this.index, 0, 1, GetPrecision()); + + BezSegList.Clear(); + bezSegTree.GetFlattenedSeg(BezSegList); + owner.FlattenAdd(this, new IntPoint(BezSegList[0].Ctrls[0])); + foreach (BezSeg bs in BezSegList) + owner.FlattenAdd(this, new IntPoint(bs.Ctrls[2])); + } + //--------------------------------------------------------------------------- + + } //end MpsQBezier class + + + public class Globals + { + public const double rad180 = Math.PI; + public const double rad90 = rad180 / 2; + public const double rad270 = rad90 * 3; + public const double rad360 = rad180 * 2; + public const double TwoPI = rad360; + + public static bool Odd(Int64 val) + { + return (val % 2) == 1; + } + //------------------------------------------------------------------------------ + + public static bool Even(Int64 val) + { + return (val % 2) == 0; + } + //--------------------------------------------------------------------------- + + public static double Distance(IntPoint pt1, IntPoint pt2) + { + double dx = pt1.X - pt2.X; + double dy = pt1.Y - pt2.Y; + return Math.Sqrt(dx * dx + dy * dy); + } + //--------------------------------------------------------------------------- + + public static double Distance(DoublePoint pt1, DoublePoint pt2) + { + double dx = pt1.X - pt2.X; + double dy = pt1.Y - pt2.Y; + return Math.Sqrt(dx * dx + dy * dy); + } + //--------------------------------------------------------------------------- + + public static double DistanceSqrd(DoublePoint pt1, DoublePoint pt2) + { + double dx = pt1.X - pt2.X; + double dy = pt1.Y - pt2.Y; + return dx * dx + dy * dy; + } + //--------------------------------------------------------------------------- + + public static void SinCos(double angle, out double sinval, out double cosval) + { + sinval = Math.Sin(angle); + cosval = Math.Cos(angle); + } + //------------------------------------------------------------------------------ + + public static Int64 Round(double value) + { + return value < 0 ? (Int64)(value - 0.5) : (Int64)(value + 0.5); + } + //------------------------------------------------------------------------------ + + public static double NormalizeAngle(double angle) + { + if (angle > rad360) return angle - rad360; + else if (angle < 0) return angle + rad360; + else return angle; + } + //--------------------------------------------------------------------------- + + public static double GetAngle(DoublePoint startPt, DoublePoint endPt) + { + return NormalizeAngle(Math.Atan2(startPt.Y - endPt.Y, endPt.X - startPt.X)); + } + //------------------------------------------------------------------------------ + + public static double GetEllipticalAngle(DoublePoint origin, DoublePoint pt, + DoublePoint radii, double ellipseAngle = 0.0) + { + //returns the angle of 'pt' relative to the ellipse's axis + double dx = pt.X - origin.X, dy = pt.Y - origin.Y; + if (ellipseAngle != 0.0) + { + double dx2 = dx; + double asin = Math.Sin(-ellipseAngle), acos = Math.Cos(-ellipseAngle); + dx = dx2 * acos + dy * asin; + dy = dy * acos - dx2 * asin; + } + return NormalizeAngle(Math.Atan2(-dy * radii.X / radii.Y, dx)); + } + //------------------------------------------------------------------------------ + + public static DoublePoint GetPointFromOrigin(DoublePoint origin, double radius, double angle) + { + double asin, acos; + SinCos(angle, out asin, out acos); + return new DoublePoint(radius * acos + origin.X, -radius * asin + origin.Y); + } + //------------------------------------------------------------------------------ + + public static double GetMidAngle(double angle1, double angle3, bool isClockwise) + { + double a2 = NormalizeAngle((angle1 + angle3) / 2); + if (Math.Abs(angle1 - angle3) < 0.025) return a2; + else if ((a2 < angle1) != isClockwise) return NormalizeAngle(a2 + rad180); + else return a2; + } + //------------------------------------------------------------------------------ + + public static bool CircleFrom3Points(DoublePoint dp1, DoublePoint dp2, DoublePoint dp3, + out DoublePoint origin, out double radius) + { + //logic: A line perpendicular to a chord that passes through the chord's midpoint + //must also pass through the origin. Therefore given 2 chords we can find the origin. + origin = new DoublePoint(); + radius = 0.0; + double m1, m2, mp1x, mp1y, mp2x, mp2y; + if (dp1.Y == dp2.Y) + { + //test for collinear points ... + if ((dp3.Y - dp1.Y) * (dp2.X - dp3.X) == (dp3.X - dp1.X) * (dp3.Y - dp2.Y)) return false; + m1 = (dp3.X - dp1.X) / (dp1.Y - dp3.Y); //nb: inverse slopes + m2 = (dp2.X - dp3.X) / (dp3.Y - dp2.Y); + mp1x = (dp1.X + dp3.X) / 2; + mp1y = (dp1.Y + dp3.Y) / 2; + mp2x = (dp3.X + dp2.X) / 2; + mp2y = (dp3.Y + dp2.Y) / 2; + } + else if (dp2.Y == dp3.Y) + { + if ((dp1.Y - dp2.Y) * (dp1.X - dp3.X) == (dp2.X - dp1.X) * (dp3.Y - dp1.Y)) return false; + m1 = (dp2.X - dp1.X) / (dp1.Y - dp2.Y); //nb: inverse slopes + m2 = (dp1.X - dp3.X) / (dp3.Y - dp1.Y); + mp1x = (dp1.X + dp2.X) / 2; + mp1y = (dp1.Y + dp2.Y) / 2; + mp2x = (dp3.X + dp1.X) / 2; + mp2y = (dp3.Y + dp1.Y) / 2; + } + else //use 1-2, 2-3 + { + if ((dp1.Y - dp2.Y) * (dp2.X - dp3.X) == (dp2.X - dp1.X) * (dp3.Y - dp2.Y)) return false; + m1 = (dp2.X - dp1.X) / (dp1.Y - dp2.Y); //nb: inverse slopes + m2 = (dp2.X - dp3.X) / (dp3.Y - dp2.Y); + mp1x = (dp1.X + dp2.X) / 2; + mp1y = (dp1.Y + dp2.Y) / 2; + mp2x = (dp3.X + dp2.X) / 2; + mp2y = (dp3.Y + dp2.Y) / 2; + } + double b1 = mp1y - mp1x * m1; + double b2 = mp2y - mp2x * m2; + double x = (b2 - b1) / (m1 - m2); + origin = new DoublePoint(x, m1 * x + b1); + radius = Math.Sqrt((dp1.X - origin.X) * (dp1.X - origin.X) + + (dp1.Y - origin.Y) * (dp1.Y - origin.Y)); + return true; + } + //--------------------------------------------------------------------------- + + public static DoublePoint CircleOriginFrom2Points(DoublePoint dp1, DoublePoint dp2, + double radius, bool IsClockwise) + { + DoublePoint origin = new DoublePoint(); + if (dp1.X == dp2.X && dp1.Y == dp2.Y) return origin; + DoublePoint mp = new DoublePoint((dp1.X + dp2.X)/2.0,(dp1.Y + dp2.Y)/2.0); + double opp = Math.Sqrt(radius * radius - DistanceSqrd(dp1, mp)); + double adjMul2 = Distance(dp1, dp2); + double sign = (IsClockwise ? 1.0 : -1.0); + origin = new DoublePoint(mp.X + sign * opp * (dp1.Y - dp2.Y) / adjMul2, + mp.Y + sign * opp * (dp2.X - dp1.X) / adjMul2); + return origin; + } + //--------------------------------------------------------------------------- + + public static double GetEllipticalRadiusY(double radiusX, DoublePoint origin, DoublePoint dp) + { + dp = new DoublePoint(dp.X - origin.X, dp.Y - origin.Y); + if (Math.Abs(dp.X) > radiusX) return 0.0; + return Math.Sqrt(dp.Y * dp.Y / (1 - (dp.X * dp.X / (radiusX * radiusX)))); + } + //------------------------------------------------------------------------------ + + public static DoublePoint RotatePoint(DoublePoint origin, DoublePoint pt, double radians) + { + if (radians == 0.0) return pt; + double asin = Math.Sin(radians); + double acos = Math.Cos(radians); + pt = new DoublePoint(pt.X - origin.X, pt.Y - origin.Y); + return new DoublePoint(pt.X * acos + pt.Y * asin + origin.X, pt.Y * acos - pt.X * asin + origin.Y); + } + //--------------------------------------------------------------------------- + + public static List RotatePoints(DoublePoint origin, List pts, double radians) + { + if (radians == 0.0) return pts; + double asin = Math.Sin(radians); + double acos = Math.Cos(radians); + List result = new List(pts.Count); + foreach (DoublePoint dp in pts) + { + double x = ((dp.X - origin.X) * acos + (dp.Y - origin.Y) * asin) + origin.X; + double y = ((dp.Y - origin.Y) * acos - (dp.X - origin.X) * asin) + origin.Y; + result.Add(new DoublePoint(x, y)); + } + return result; + } + //--------------------------------------------------------------------------- + + public static bool GetEllipseFrom3Points( + DoublePoint axis1a, DoublePoint axis1b, DoublePoint pt, + out DoublePoint origin, out DoublePoint radii, out double angle_radians) + { + //axis1a & axis1b define the extent of one axis and origin is their midpoint ... + //the remaining point can be anywhere on the ellipse except on the defined axis. + origin = new DoublePoint((axis1a.X + axis1b.X) / 2, (axis1a.Y + axis1b.Y) / 2); + angle_radians = GetAngle(origin, axis1b); + if (angle_radians > rad90) angle_radians -= rad180; + pt = RotatePoint(origin, pt, -angle_radians); //ie rotate pt so it's axis aligned + double x = Distance(axis1a, origin); + double y = GetEllipticalRadiusY(x, origin, pt); + radii = new DoublePoint(x, y); + return y > 0; + } + //------------------------------------------------------------------------------ + + public static DoublePoint GetSvgEllipseOrigin(DoublePoint startPt, DoublePoint endPt, + DoublePoint radii, double angle_radians, bool largeArc, bool sweep) + { + //Code adapted from ... + //http://stackoverflow.com/questions/1805101/svg-elliptical-arcs-with-java + + // Ensure radii are valid ... + if (radii.X < 0.0 || radii.Y < 0.0) + radii = new DoublePoint(Math.Abs(radii.X),Math.Abs(radii.Y)); + if (radii.X == 0 || radii.Y == 0) return startPt; + + // Compute the half distance between the current and the final point + double dx2 = (startPt.X - endPt.X) / 2.0; + double dy2 = (startPt.Y - endPt.Y) / 2.0; + + //if the start and end points are the same then the result is indeterminate ... + if (dx2 == 0 && dy2 == 0) return startPt; + + double asin, acos; + SinCos(-angle_radians, out asin, out acos); + // Step 1 : Compute (x1, y1) + double x1 = acos * dx2 + asin * dy2; + double y1 = -asin * dx2 + acos * dy2; + + // Ensure radii are large enough + double rxSqr = radii.X * radii.X; + double rySqr = radii.Y * radii.Y; + double rx2Sqr = x1 * x1; + double ry2Sqr = y1 * y1; + double d = rx2Sqr / rxSqr + ry2Sqr / rySqr; + if (d > 1) + { + double sqrtD = Math.Sqrt(d); + radii = new DoublePoint(sqrtD * radii.X, sqrtD * radii.Y); + rxSqr = radii.X * radii.X; + rySqr = radii.Y * radii.Y; + } + + // Step 2 : Compute (cx1, cy1) + double sign = (largeArc == sweep ? -1 : 1); + double cx1, cy1; + double coef = sign * Math.Sqrt(Math.Abs(((rxSqr * rySqr) - + (rxSqr * ry2Sqr) - (rySqr * rx2Sqr)) / ((rxSqr * ry2Sqr) + (rySqr * rx2Sqr)))); + cx1 = coef * radii.X * y1 / radii.Y; + cy1 = coef * -radii.Y * x1 / radii.X; + + // Step 3 : Compute (cx, cy) from (cx1, cy1) + double cx = (startPt.X + endPt.X) / 2 + acos * cx1 - asin * cy1; + double cy = (startPt.Y + endPt.Y) / 2 + asin * cx1 + acos * cy1; + return new DoublePoint(cx, cy); + } + //--------------------------------------------------------------------------- + + public static void Swap(ref T val1, ref T val2) + { + T tmp = val1; val1 = val2; val2 = tmp; + } + //------------------------------------------------------------------------------ + + public static List GetFlattenedCircle(DoublePoint origin, + double radius, double precision = 0) + { + List result = new List(); + if (precision <= 0.0) precision = MultiPaths.DefaultPrecision; + int steps = (int)Globals.Round(Globals.rad180 / Math.Acos(1 - precision / radius)) + 1; + if (steps < 2) steps = 2; + double angle_delta = rad360 / steps; + + double asin, acos; + Globals.SinCos(angle_delta, out asin, out acos); + double x = radius; + double y = 0; + for (int j = 0; j <= steps; j++) + { + result.Add(new DoublePoint(origin.X + x, origin.Y + y)); + double x2 = x; + x = x2 * acos - asin * y; + y = x2 * asin + y * acos; + } + return result; + } + //------------------------------------------------------------------------------ + + public static List GetFlattenedEllipse(DoublePoint origin, + DoublePoint radii, double angleOfEllipse = 0.0, double precision = 0) + { + if (radii.X == radii.Y) return GetFlattenedCircle(origin, radii.X, precision); + + List result = new List(); + if (precision <= 0.0) precision = MultiPaths.DefaultPrecision; + int steps = (int)Globals.Round(Globals.rad180 / + Math.Acos(1 - precision / ((radii.X + radii.Y) / 2))) + 1; + if (steps < 2) steps = 2; + double angle = 0, angle_delta = rad360 / steps; + + for (int j = 0; j <= steps; j++) + { + double x = origin.X + radii.X * Math.Cos(angle); + double y = origin.Y - radii.Y * Math.Sin(angle); + result.Add(new DoublePoint(x, y)); + angle += angle_delta; + } + if (angleOfEllipse != 0.0) + result = RotatePoints(origin, result, angleOfEllipse); + return result; + } + //------------------------------------------------------------------------------ + + public static List GetFlattenedEllipticalArc(DoublePoint origin, + DoublePoint radii, DoublePoint startPt, DoublePoint endPt, bool LargeArc, bool IsClockwise, + double angleOfEllipse = 0.0, double precision = 0) + { + double a1 = GetEllipticalAngle(origin, startPt, radii, angleOfEllipse); + double a2 = GetEllipticalAngle(origin, endPt, radii, angleOfEllipse); + if (IsClockwise) Swap(ref a1, ref a2); + double aDiff = NormalizeAngle(a2 - a1); + if (aDiff > rad180 != LargeArc) Swap(ref a1, ref a2); + + double frac = aDiff / rad360; + List result = new List(); + if (precision <= 0.0) precision = MultiPaths.DefaultPrecision; + int steps = (int)Globals.Round(Globals.rad180 * frac / Math.Acos(1 - precision / ((radii.X + radii.Y) / 2))) + 1; + if (steps < 2) steps = 2; + double angle_delta = rad360 * frac / steps; + + for (int j = 0; j <= steps; j++) + { + double x = origin.X + radii.X * Math.Cos(a1); + double y = origin.Y - radii.Y * Math.Sin(a1); + result.Add(new DoublePoint(x, y)); + a1 += angle_delta; + } + if (angleOfEllipse != 0.0) + result = RotatePoints(origin, result, angleOfEllipse); + return result; + } + //------------------------------------------------------------------------------ + + public static bool RightTurning(DoublePoint dp1, DoublePoint dp2, DoublePoint dp3) + { + //cross product ... + double dx1 = dp2.X - dp1.X; + double dy1 = dp2.Y - dp1.Y; + double dx2 = dp3.X - dp2.X; + double dy2 = dp3.Y - dp2.Y; + return ((dx1 * dy2) - (dx2 * dy1)) > 0; + } + //------------------------------------------------------------------------------ + + } //end Globals class + //--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- + + class MultiPathException : Exception + { + public MultiPathException(string description) : base(description) { } + } + +} + diff --git a/Curves/CurvesDemo/Program.cs b/Curves/CurvesDemo/Program.cs new file mode 100644 index 0000000..38a2f93 --- /dev/null +++ b/Curves/CurvesDemo/Program.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace Clipper_Lines_Demo +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} diff --git a/Curves/CurvesDemo/Properties/AssemblyInfo.cs b/Curves/CurvesDemo/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8652f37 --- /dev/null +++ b/Curves/CurvesDemo/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Clipper_Lines_Demo")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Clipper_Lines_Demo")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a5243861-965a-4391-bfda-339c7db3f776")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Curves/CurvesDemo/Properties/Resources.Designer.cs b/Curves/CurvesDemo/Properties/Resources.Designer.cs new file mode 100644 index 0000000..f266d29 --- /dev/null +++ b/Curves/CurvesDemo/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1008 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Clipper_Curves_Demo.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Clipper_Curves_Demo.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Curves/CurvesDemo/Properties/Resources.resx b/Curves/CurvesDemo/Properties/Resources.resx new file mode 100644 index 0000000..ffecec8 --- /dev/null +++ b/Curves/CurvesDemo/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Curves/CurvesDemo/app.config b/Curves/CurvesDemo/app.config new file mode 100644 index 0000000..8494f72 --- /dev/null +++ b/Curves/CurvesDemo/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Curves/CurvesDemo/bin/Debug/Clipper_Curves_Demo.exe b/Curves/CurvesDemo/bin/Debug/Clipper_Curves_Demo.exe new file mode 100644 index 0000000000000000000000000000000000000000..d87614aaae3ba46b701a7b8ac69ccf7a2f125939 GIT binary patch literal 119808 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 z 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 W + diff --git a/Curves/CurvesDemo/clipper.cs b/Curves/CurvesDemo/clipper.cs new file mode 100644 index 0000000..b8770b7 --- /dev/null +++ b/Curves/CurvesDemo/clipper.cs @@ -0,0 +1,4808 @@ +/******************************************************************************* +* * +* Author : Angus Johnson * +* Version : 6.0.0 * +* Date : 30 October 2013 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2013 * +* * +* 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 * +* * +*******************************************************************************/ + +/******************************************************************************* +* * +* This is a translation of the Delphi Clipper library and the naming style * +* used has retained a Delphi flavour. * +* * +*******************************************************************************/ + +//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 performance. +#define use_xyz + +//UseLines: Enables line clipping. Adds a very minor cost to performance. +#define use_lines + +//When enabled, code developed with earlier versions of Clipper +//(ie prior to ver 6) should compile without changes. +//In a future update, this compatibility code will be removed. +#define use_deprecated + + +using System; +using System.Collections.Generic; +//using System.Text; //for Int128.AsString() & StringBuilder +//using System.IO; //debugging with streamReader & StreamWriter +//using System.Windows.Forms; //debugging to clipboard + +namespace ClipperLib +{ + +#if use_int32 + using cInt = Int32; +#else + using cInt = Int64; +#endif + + using Path = List; + using Paths = List>; + +#if use_deprecated + using Polygon = List; + using Polygons = List>; +#endif + + public struct DoublePoint + { + public double X; + public double Y; + + public DoublePoint(double x = 0, double y = 0) + { + this.X = x; this.Y = y; + } + public DoublePoint(DoublePoint dp) + { + this.X = dp.X; this.Y = dp.Y; + } + public DoublePoint(IntPoint ip) + { + this.X = ip.X; this.Y = ip.Y; + } + }; + + + //------------------------------------------------------------------------------ + // PolyTree & PolyNode classes + //------------------------------------------------------------------------------ + + public class PolyTree : PolyNode + { + internal List m_AllPolys = new List(); + + ~PolyTree() + { + Clear(); + } + + public void Clear() + { + for (int i = 0; i < m_AllPolys.Count; i++) + m_AllPolys[i] = null; + m_AllPolys.Clear(); + m_Childs.Clear(); + } + + public PolyNode GetFirst() + { + if (m_Childs.Count > 0) + return m_Childs[0]; + else + return null; + } + + public int Total + { + get { return m_AllPolys.Count; } + } + + } + + public class PolyNode + { + internal PolyNode m_Parent; + internal Path m_polygon = new Path(); + internal int m_Index; + internal List m_Childs = new List(); + + private bool IsHoleNode() + { + bool result = true; + PolyNode node = m_Parent; + while (node != null) + { + result = !result; + node = node.m_Parent; + } + return result; + } + + public int ChildCount + { + get { return m_Childs.Count; } + } + + public Path Contour + { + get { return m_polygon; } + } + + internal void AddChild(PolyNode Child) + { + int cnt = m_Childs.Count; + m_Childs.Add(Child); + Child.m_Parent = this; + Child.m_Index = cnt; + } + + public PolyNode GetNext() + { + if (m_Childs.Count > 0) + return m_Childs[0]; + else + return GetNextSiblingUp(); + } + + internal PolyNode GetNextSiblingUp() + { + if (m_Parent == null) + return null; + else if (m_Index == m_Parent.m_Childs.Count - 1) + return m_Parent.GetNextSiblingUp(); + else + return m_Parent.m_Childs[m_Index + 1]; + } + + public List Childs + { + get { return m_Childs; } + } + + public PolyNode Parent + { + get { return m_Parent; } + } + + public bool IsHole + { + get { return IsHoleNode(); } + } + + public bool IsOpen { get; set; } + } + + + //------------------------------------------------------------------------------ + // Int128 struct (enables safe math on signed 64bit integers) + // eg Int128 val1((Int64)9223372036854775807); //ie 2^63 -1 + // Int128 val2((Int64)9223372036854775807); + // Int128 val3 = val1 * val2; + // val3.ToString => "85070591730234615847396907784232501249" (8.5e+37) + //------------------------------------------------------------------------------ + + internal struct Int128 + { + private Int64 hi; + private UInt64 lo; + + public Int128(Int64 _lo) + { + lo = (UInt64)_lo; + if (_lo < 0) hi = -1; + else hi = 0; + } + + public Int128(Int64 _hi, UInt64 _lo) + { + lo = _lo; + hi = _hi; + } + + public Int128(Int128 val) + { + hi = val.hi; + lo = val.lo; + } + + public bool IsNegative() + { + return hi < 0; + } + + public static bool operator ==(Int128 val1, Int128 val2) + { + if ((object)val1 == (object)val2) return true; + else if ((object)val1 == null || (object)val2 == null) return false; + return (val1.hi == val2.hi && val1.lo == val2.lo); + } + + public static bool operator !=(Int128 val1, Int128 val2) + { + return !(val1 == val2); + } + + public override bool Equals(System.Object obj) + { + if (obj == null || !(obj is Int128)) + return false; + Int128 i128 = (Int128)obj; + return (i128.hi == hi && i128.lo == lo); + } + + public override int GetHashCode() + { + return hi.GetHashCode() ^ lo.GetHashCode(); + } + + public static bool operator >(Int128 val1, Int128 val2) + { + if (val1.hi != val2.hi) + return val1.hi > val2.hi; + else + return val1.lo > val2.lo; + } + + public static bool operator <(Int128 val1, Int128 val2) + { + if (val1.hi != val2.hi) + return val1.hi < val2.hi; + else + return val1.lo < val2.lo; + } + + public static Int128 operator +(Int128 lhs, Int128 rhs) + { + lhs.hi += rhs.hi; + lhs.lo += rhs.lo; + if (lhs.lo < rhs.lo) lhs.hi++; + return lhs; + } + + public static Int128 operator -(Int128 lhs, Int128 rhs) + { + return lhs + -rhs; + } + + public static Int128 operator -(Int128 val) + { + if (val.lo == 0) + return new Int128(-val.hi, 0); + else + return new Int128(~val.hi, ~val.lo + 1); + } + + //nb: Constructing two new Int128 objects every time we want to multiply longs + //is slow. So, although calling the Int128Mul method doesn't look as clean, the + //code runs significantly faster than if we'd used the * operator. + + public static Int128 Int128Mul(Int64 lhs, Int64 rhs) + { + bool negate = (lhs < 0) != (rhs < 0); + if (lhs < 0) lhs = -lhs; + if (rhs < 0) rhs = -rhs; + UInt64 int1Hi = (UInt64)lhs >> 32; + UInt64 int1Lo = (UInt64)lhs & 0xFFFFFFFF; + UInt64 int2Hi = (UInt64)rhs >> 32; + UInt64 int2Lo = (UInt64)rhs & 0xFFFFFFFF; + + //nb: see comments in clipper.pas + UInt64 a = int1Hi * int2Hi; + UInt64 b = int1Lo * int2Lo; + UInt64 c = int1Hi * int2Lo + int1Lo * int2Hi; + + UInt64 lo; + Int64 hi; + hi = (Int64)(a + (c >> 32)); + + unchecked { lo = (c << 32) + b; } + if (lo < b) hi++; + Int128 result = new Int128(hi, lo); + return negate ? -result : result; + } + + public static Int128 operator /(Int128 lhs, Int128 rhs) + { + if (rhs.lo == 0 && rhs.hi == 0) + throw new ClipperException("Int128: divide by zero"); + + bool negate = (rhs.hi < 0) != (lhs.hi < 0); + if (lhs.hi < 0) lhs = -lhs; + if (rhs.hi < 0) rhs = -rhs; + + if (rhs < lhs) + { + Int128 result = new Int128(0); + Int128 cntr = new Int128(1); + while (rhs.hi >= 0 && !(rhs > lhs)) + { + rhs.hi <<= 1; + if ((Int64)rhs.lo < 0) rhs.hi++; + rhs.lo <<= 1; + + cntr.hi <<= 1; + if ((Int64)cntr.lo < 0) cntr.hi++; + cntr.lo <<= 1; + } + rhs.lo >>= 1; + if ((rhs.hi & 1) == 1) + rhs.lo |= 0x8000000000000000; + rhs.hi = (Int64)((UInt64)rhs.hi >> 1); + + cntr.lo >>= 1; + if ((cntr.hi & 1) == 1) + cntr.lo |= 0x8000000000000000; + cntr.hi >>= 1; + + while (cntr.hi != 0 || cntr.lo != 0) + { + if (!(lhs < rhs)) + { + lhs -= rhs; + result.hi |= cntr.hi; + result.lo |= cntr.lo; + } + rhs.lo >>= 1; + if ((rhs.hi & 1) == 1) + rhs.lo |= 0x8000000000000000; + rhs.hi >>= 1; + + cntr.lo >>= 1; + if ((cntr.hi & 1) == 1) + cntr.lo |= 0x8000000000000000; + cntr.hi >>= 1; + } + return negate ? -result : result; + } + else if (rhs == lhs) + return new Int128(1); + else + return new Int128(0); + } + + public double ToDouble() + { + const double shift64 = 18446744073709551616.0; //2^64 + if (hi < 0) + { + if (lo == 0) + return (double)hi * shift64; + else + return -(double)(~lo + ~hi * shift64); + } + else + return (double)(lo + hi * shift64); + } + + }; + + //------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ + + public struct IntPoint + { + public cInt X; + public cInt Y; +#if use_xyz + public cInt Z; + + public IntPoint(cInt x, cInt y, cInt z = 0) + { + this.X = x; this.Y = y; this.Z = z; + } + + public IntPoint(double x, double y, double z = 0) + { + this.X = (cInt)x; this.Y = (cInt)y; this.Z = (cInt)z; + } + + public IntPoint(DoublePoint dp) + { + this.X = (cInt)dp.X; this.Y = (cInt)dp.Y; this.Z = 0; + } + + public IntPoint(IntPoint pt) + { + this.X = pt.X; this.Y = pt.Y; this.Z = pt.Z; + } +#else + public IntPoint(cInt X, cInt Y) + { + this.X = X; this.Y = Y; + } + public IntPoint(double x, double y) + { + this.X = (cInt)x; this.Y = (cInt)y; + } + + public IntPoint(IntPoint pt) + { + this.X = pt.X; this.Y = pt.Y; + } +#endif + + public static bool operator ==(IntPoint a, IntPoint b) + { + return a.X == b.X && a.Y == b.Y; + } + + public static bool operator !=(IntPoint a, IntPoint b) + { + return a.X != b.X || a.Y != b.Y; + } + + public override bool Equals(object obj) + { + if (obj == null) return false; + if (obj is IntPoint) + { + IntPoint a = (IntPoint)obj; + return (X == a.X) && (Y == a.Y); + } + else return false; + } + + public override int GetHashCode() + { + //simply prevents a compiler warning + return base.GetHashCode(); + } +} + + + public struct IntRect + { + public cInt left; + public cInt top; + public cInt right; + public cInt bottom; + + public IntRect(cInt l, cInt t, cInt r, cInt b) + { + this.left = l; this.top = t; + this.right = r; this.bottom = b; + } + public IntRect(IntRect ir) + { + this.left = ir.left; this.top = ir.top; + this.right = ir.right; this.bottom = ir.bottom; + } + } + + public enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; + public 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 + public enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; + public enum JoinType { jtSquare, jtRound, jtMiter }; + public enum EndType { etClosed, etButt, etSquare, etRound}; + + internal enum EdgeSide {esLeft, esRight}; + internal enum Direction {dRightToLeft, dLeftToRight}; + + internal class TEdge { + public IntPoint Bot; + public IntPoint Curr; + public IntPoint Top; + public IntPoint Delta; + public double Dx; + public PolyType PolyTyp; + public EdgeSide Side; + public int WindDelta; //1 or -1 depending on winding direction + public int WindCnt; + public int WindCnt2; //winding count of the opposite polytype + public int OutIdx; + public TEdge Next; + public TEdge Prev; + public TEdge NextInLML; + public TEdge NextInAEL; + public TEdge PrevInAEL; + public TEdge NextInSEL; + public TEdge PrevInSEL; + }; + + internal class IntersectNode + { + public TEdge Edge1; + public TEdge Edge2; + public IntPoint Pt; + public IntersectNode Next; + }; + + internal class LocalMinima + { + public cInt Y; + public TEdge LeftBound; + public TEdge RightBound; + public LocalMinima Next; + }; + + internal class Scanbeam + { + public cInt Y; + public Scanbeam Next; + }; + + internal class OutRec + { + public int Idx; + public bool IsHole; + public bool IsOpen; + public OutRec FirstLeft; //see comments in clipper.pas + public OutPt Pts; + public OutPt BottomPt; + public PolyNode PolyNode; + }; + + internal class OutPt + { + public int Idx; + public IntPoint Pt; + public OutPt Next; + public OutPt Prev; + }; + + internal class Join + { + public OutPt OutPt1; + public OutPt OutPt2; + public IntPoint OffPt; + }; + + public class ClipperBase + { + protected const double horizontal = -3.4E+38; + protected const int Skip = -2; + protected const int Unassigned = -1; + protected const double tolerance = 1.0E-20; + internal static bool near_zero(double val){return (val > -tolerance) && (val < tolerance);} + +#if use_int32 + internal const cInt loRange = 46340; + internal const cInt hiRange = 46340; +#else + internal const cInt loRange = 0x3FFFFFFF; + internal const cInt hiRange = 0x3FFFFFFFFFFFFFFFL; +#endif + + internal LocalMinima m_MinimaList; + internal LocalMinima m_CurrentLM; + internal List> m_edges = new List>(); + internal bool m_UseFullRange; + internal bool m_HasOpenPaths; + + //------------------------------------------------------------------------------ + + public bool PreserveCollinear + { + get; + set; + } + //------------------------------------------------------------------------------ + + internal static bool IsHorizontal(TEdge e) + { + return e.Delta.Y == 0; + } + //------------------------------------------------------------------------------ + + internal bool PointIsVertex(IntPoint pt, OutPt pp) + { + OutPt pp2 = pp; + do + { + if (pp2.Pt == pt) return true; + pp2 = pp2.Next; + } + while (pp2 != pp); + return false; + } + //------------------------------------------------------------------------------ + + internal bool PointOnLineSegment(IntPoint pt, + IntPoint linePt1, IntPoint linePt2, bool UseFullRange) + { + if (UseFullRange) + return ((pt.X == linePt1.X) && (pt.Y == linePt1.Y)) || + ((pt.X == linePt2.X) && (pt.Y == linePt2.Y)) || + (((pt.X > linePt1.X) == (pt.X < linePt2.X)) && + ((pt.Y > linePt1.Y) == (pt.Y < linePt2.Y)) && + ((Int128.Int128Mul((pt.X - linePt1.X), (linePt2.Y - linePt1.Y)) == + Int128.Int128Mul((linePt2.X - linePt1.X), (pt.Y - linePt1.Y))))); + else + return ((pt.X == linePt1.X) && (pt.Y == linePt1.Y)) || + ((pt.X == linePt2.X) && (pt.Y == linePt2.Y)) || + (((pt.X > linePt1.X) == (pt.X < linePt2.X)) && + ((pt.Y > linePt1.Y) == (pt.Y < linePt2.Y)) && + ((pt.X - linePt1.X) * (linePt2.Y - linePt1.Y) == + (linePt2.X - linePt1.X) * (pt.Y - linePt1.Y))); + } + //------------------------------------------------------------------------------ + + internal bool PointOnPolygon(IntPoint pt, OutPt pp, bool UseFullRange) + { + OutPt pp2 = pp; + while (true) + { + if (PointOnLineSegment(pt, pp2.Pt, pp2.Next.Pt, UseFullRange)) + return true; + pp2 = pp2.Next; + if (pp2 == pp) break; + } + return false; + } + //------------------------------------------------------------------------------ + + internal bool PointInPolygon(IntPoint pt, OutPt pp, bool UseFullRange) + { + OutPt pp2 = pp; + bool result = false; + if (UseFullRange) + { + do + { + if (((pp2.Pt.Y > pt.Y) != (pp2.Prev.Pt.Y > pt.Y)) && + (new Int128(pt.X - pp2.Pt.X) < + Int128.Int128Mul(pp2.Prev.Pt.X - pp2.Pt.X, pt.Y - pp2.Pt.Y) / + new Int128(pp2.Prev.Pt.Y - pp2.Pt.Y))) result = !result; + pp2 = pp2.Next; + } + while (pp2 != pp); + } + else + { + do + { + //http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html + if (((pp2.Pt.Y > pt.Y) != (pp2.Prev.Pt.Y > pt.Y)) && + ((pt.X - pp2.Pt.X) < (pp2.Prev.Pt.X - pp2.Pt.X) * (pt.Y - pp2.Pt.Y) / + (pp2.Prev.Pt.Y - pp2.Pt.Y))) result = !result; + pp2 = pp2.Next; + } + while (pp2 != pp); + } + return result; + } + //------------------------------------------------------------------------------ + + internal static bool SlopesEqual(TEdge e1, TEdge e2, bool UseFullRange) + { + if (UseFullRange) + return Int128.Int128Mul(e1.Delta.Y, e2.Delta.X) == + Int128.Int128Mul(e1.Delta.X, e2.Delta.Y); + else return (cInt)(e1.Delta.Y) * (e2.Delta.X) == + (cInt)(e1.Delta.X) * (e2.Delta.Y); + } + //------------------------------------------------------------------------------ + + protected static bool SlopesEqual(IntPoint pt1, IntPoint pt2, + IntPoint pt3, bool UseFullRange) + { + if (UseFullRange) + return Int128.Int128Mul(pt1.Y - pt2.Y, pt2.X - pt3.X) == + Int128.Int128Mul(pt1.X - pt2.X, pt2.Y - pt3.Y); + else return + (cInt)(pt1.Y - pt2.Y) * (pt2.X - pt3.X) - (cInt)(pt1.X - pt2.X) * (pt2.Y - pt3.Y) == 0; + } + //------------------------------------------------------------------------------ + + protected static bool SlopesEqual(IntPoint pt1, IntPoint pt2, + IntPoint pt3, IntPoint pt4, bool UseFullRange) + { + if (UseFullRange) + return Int128.Int128Mul(pt1.Y - pt2.Y, pt3.X - pt4.X) == + Int128.Int128Mul(pt1.X - pt2.X, pt3.Y - pt4.Y); + else return + (cInt)(pt1.Y - pt2.Y) * (pt3.X - pt4.X) - (cInt)(pt1.X - pt2.X) * (pt3.Y - pt4.Y) == 0; + } + //------------------------------------------------------------------------------ + + internal ClipperBase() //constructor (nb: no external instantiation) + { + m_MinimaList = null; + m_CurrentLM = null; + m_UseFullRange = false; + m_HasOpenPaths = false; + } + //------------------------------------------------------------------------------ + + public virtual void Clear() + { + DisposeLocalMinimaList(); + for (int i = 0; i < m_edges.Count; ++i) + { + for (int j = 0; j < m_edges[i].Count; ++j) m_edges[i][j] = null; + m_edges[i].Clear(); + } + m_edges.Clear(); + m_UseFullRange = false; + m_HasOpenPaths = false; + } + //------------------------------------------------------------------------------ + + private void DisposeLocalMinimaList() + { + while( m_MinimaList != null ) + { + LocalMinima tmpLm = m_MinimaList.Next; + m_MinimaList = null; + m_MinimaList = tmpLm; + } + m_CurrentLM = null; + } + //------------------------------------------------------------------------------ + + void RangeTest(IntPoint Pt, ref bool useFullRange) + { + if (useFullRange) + { + if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) + throw new ClipperException("Coordinate outside allowed range"); + } + else if (Pt.X > loRange || Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) + { + useFullRange = true; + RangeTest(Pt, ref useFullRange); + } + } + //------------------------------------------------------------------------------ + + private void InitEdge(TEdge e, TEdge eNext, + TEdge ePrev, IntPoint pt) + { + e.Next = eNext; + e.Prev = ePrev; + e.Curr = pt; + e.OutIdx = Unassigned; + } + //------------------------------------------------------------------------------ + + private void InitEdge2(TEdge e, PolyType polyType) + { + if (e.Curr.Y >= e.Next.Curr.Y) + { + e.Bot = e.Curr; + e.Top = e.Next.Curr; + } + else + { + e.Top = e.Curr; + e.Bot = e.Next.Curr; + } + SetDx(e); + e.PolyTyp = polyType; + } + //------------------------------------------------------------------------------ + + public bool AddPath(Path pg, PolyType polyType, bool Closed) + { +#if use_lines + if (!Closed && polyType == PolyType.ptClip) + throw new ClipperException("AddPath: Open paths must be subject."); +#else + if (!Closed) + throw new ClipperException("AddPath: Open paths have been disabled."); +#endif + + int highI = (int)pg.Count - 1; + bool ClosedOrSemiClosed = (highI > 0) && (Closed || (pg[0] == pg[highI])); + while (highI > 0 && (pg[highI] == pg[0])) --highI; + while (highI > 0 && (pg[highI] == pg[highI - 1])) --highI; + if ((Closed && highI < 2) || (!Closed && highI < 1)) return false; + + //create a new edge array ... + List edges = new List(highI+1); + for (int i = 0; i <= highI; i++) edges.Add(new TEdge()); + + //1. Basic initialization of Edges ... + try + { + edges[1].Curr = pg[1]; + RangeTest(pg[0], ref m_UseFullRange); + RangeTest(pg[highI], ref m_UseFullRange); + InitEdge(edges[0], edges[1], edges[highI], pg[0]); + InitEdge(edges[highI], edges[0], edges[highI - 1], pg[highI]); + for (int i = highI - 1; i >= 1; --i) + { + RangeTest(pg[i], ref m_UseFullRange); + InitEdge(edges[i], edges[i + 1], edges[i - 1], pg[i]); + } + } + catch + { + return false; //almost certainly a vertex has exceeded range + }; + + TEdge eStart = edges[0]; + if (!ClosedOrSemiClosed) eStart.Prev.OutIdx = Skip; + + //2. Remove duplicate vertices, and collinear edges (when closed) ... + TEdge E = eStart, eLoopStop = eStart; + for (;;) + { + if (E.Curr == E.Next.Curr) + { + //nb if E.OutIdx == Skip, it would have been semiOpen + if (E == eStart) eStart = E.Next; + E = RemoveEdge(E); + eLoopStop = E; + continue; + } + if (E.Prev == E.Next) + break; //only two vertices + else if ((ClosedOrSemiClosed || + (E.Prev.OutIdx != Skip && E.OutIdx != Skip && + E.Next.OutIdx != Skip)) && + SlopesEqual(E.Prev.Curr, E.Curr, E.Next.Curr, m_UseFullRange)) + { + //All collinear edges are allowed for open paths but in closed paths + //inner vertices of adjacent collinear edges are removed. However if the + //PreserveCollinear property has been enabled, only overlapping collinear + //edges (ie spikes) are removed from closed paths. + if (Closed && (!PreserveCollinear || + !Pt2IsBetweenPt1AndPt3(E.Prev.Curr, E.Curr, E.Next.Curr))) + { + if (E == eStart) eStart = E.Next; + E = RemoveEdge(E); + E = E.Prev; + eLoopStop = E; + continue; + } + } + E = E.Next; + if (E == eLoopStop) break; + } + + if ((!Closed && (E == E.Next)) || (Closed && (E.Prev == E.Next))) + return false; + m_edges.Add(edges); + + if (!Closed) + m_HasOpenPaths = true; + + //3. Do final Init and also find the 'highest' Edge. (nb: since I'm much + //more familiar with positive downwards Y axes, 'highest' here will be + //the Edge with the *smallest* Top.Y.) + TEdge eHighest = eStart; + E = eStart; + do + { + InitEdge2(E, polyType); + if (E.Top.Y < eHighest.Top.Y) eHighest = E; + E = E.Next; + } + while (E != eStart); + + //4. build the local minima list ... + if (AllHorizontal(E)) + { + if (ClosedOrSemiClosed) + E.Prev.OutIdx = Skip; + AscendToMax(ref E, false, false); + return true; + } + + //if eHighest is also the Skip then it's a natural break, otherwise + //make sure eHighest is positioned so we're either at a top horizontal or + //just starting to head down one edge of the polygon + E = eStart.Prev; //EStart.Prev == Skip edge + if (E.Prev == E.Next) + eHighest = E.Next; + else if (!ClosedOrSemiClosed && E.Top.Y == eHighest.Top.Y) + { + if ((IsHorizontal(E) || IsHorizontal(E.Next)) && + E.Next.Bot.Y == eHighest.Top.Y) + eHighest = E.Next; + else if (SharedVertWithPrevAtTop(E)) eHighest = E; + else if (E.Top == E.Prev.Top) eHighest = E.Prev; + else eHighest = E.Next; + } else + { + E = eHighest; + while (IsHorizontal(eHighest) || + (eHighest.Top == eHighest.Next.Top) || + (eHighest.Top == eHighest.Next.Bot)) //next is high horizontal + { + eHighest = eHighest.Next; + if (eHighest == E) + { + while (IsHorizontal(eHighest) || !SharedVertWithPrevAtTop(eHighest)) + eHighest = eHighest.Next; + break; //avoids potential endless loop + } + } + } + E = eHighest; + do + E = AddBoundsToLML(E, Closed); + while (E != eHighest); + return true; + } + //------------------------------------------------------------------------------ + + public bool AddPaths(Paths ppg, PolyType polyType, bool closed) + { + bool result = false; + for (int i = 0; i < ppg.Count; ++i) + if (AddPath(ppg[i], polyType, closed)) result = true; + return result; + } + //------------------------------------------------------------------------------ + +#if use_deprecated + public bool AddPolygon(Path pg, PolyType polyType) + { + return AddPath(pg, polyType, true); + } + //------------------------------------------------------------------------------ + + public bool AddPolygons(Paths ppg, PolyType polyType) + { + bool result = false; + for (int i = 0; i < ppg.Count; ++i) + if (AddPath(ppg[i], polyType, true)) result = true; + return result; + } + //------------------------------------------------------------------------------ +#endif + + internal bool Pt2IsBetweenPt1AndPt3(IntPoint pt1, IntPoint pt2, IntPoint pt3) + { + if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2)) return false; + else if (pt1.X != pt3.X) return (pt2.X > pt1.X) == (pt2.X < pt3.X); + else return (pt2.Y > pt1.Y) == (pt2.Y < pt3.Y); + } + //------------------------------------------------------------------------------ + + TEdge RemoveEdge(TEdge e) + { + //removes e from double_linked_list (but without removing from memory) + e.Prev.Next = e.Next; + e.Next.Prev = e.Prev; + TEdge result = e.Next; + e.Prev = null; //flag as removed (see ClipperBase.Clear) + return result; + } + //------------------------------------------------------------------------------ + + TEdge GetLastHorz(TEdge Edge) + { + TEdge result = Edge; + while (result.OutIdx != Skip && result.Next != Edge && IsHorizontal(result.Next)) + result = result.Next; + return result; + } + //------------------------------------------------------------------------------ + + bool SharedVertWithPrevAtTop(TEdge Edge) + { + TEdge E = Edge; + bool result = true; + while (E.Prev != Edge) + { + if (E.Top == E.Prev.Top) + { + if (E.Bot == E.Prev.Bot) + {E = E.Prev; continue;} + else result = true; + } + else result = false; + break; + } + while (E != Edge) + { + result = !result; + E = E.Next; + } + return result; + } + //------------------------------------------------------------------------------ + + bool SharedVertWithNextIsBot(TEdge Edge) + { + bool result = true; + TEdge E = Edge; + while (E.Prev != Edge) + { + bool A = (E.Next.Bot == E.Bot); + bool B = (E.Prev.Bot == E.Bot); + if (A != B) + { + result = A; + break; + } + A = (E.Next.Top == E.Top); + B = (E.Prev.Top == E.Top); + if (A != B) + { + result = B; + break; + } + E = E.Prev; + } + while (E != Edge) + { + result = !result; + E = E.Next; + } + return result; + } + //------------------------------------------------------------------------------ + + bool MoreBelow(TEdge Edge) + { + //Edge is Skip heading down. + TEdge E = Edge; + if (IsHorizontal(E)) + { + while (IsHorizontal(E.Next)) E = E.Next; + return E.Next.Bot.Y > E.Bot.Y; + } + else if (IsHorizontal(E.Next)) + { + while (IsHorizontal(E.Next)) E = E.Next; + return E.Next.Bot.Y > E.Bot.Y; + } + else return (E.Bot == E.Next.Top); + } + //------------------------------------------------------------------------------ + + bool JustBeforeLocMin(TEdge Edge) + { + //Edge is Skip and was heading down. + TEdge E = Edge; + if (IsHorizontal(E)) + { + while (IsHorizontal(E.Next)) E = E.Next; + return E.Next.Top.Y < E.Bot.Y; + } + else return SharedVertWithNextIsBot(E); + } + //------------------------------------------------------------------------------ + + bool MoreAbove(TEdge Edge) + { + if (IsHorizontal(Edge)) + { + Edge = GetLastHorz(Edge); + return (Edge.Next.Top.Y < Edge.Top.Y); + } + else if (IsHorizontal(Edge.Next)) + { + Edge = GetLastHorz(Edge.Next); + return (Edge.Next.Top.Y < Edge.Top.Y); + } + else + return (Edge.Next.Top.Y < Edge.Top.Y); + } + //------------------------------------------------------------------------------ + + bool AllHorizontal(TEdge Edge) + { + if (!IsHorizontal(Edge)) return false; + TEdge E = Edge.Next; + while (E != Edge) + { + if (!IsHorizontal(E)) return false; + else E = E.Next; + } + return true; + } + //------------------------------------------------------------------------------ + + private void SetDx(TEdge e) + { + e.Delta.X = (e.Top.X - e.Bot.X); + e.Delta.Y = (e.Top.Y - e.Bot.Y); + if (e.Delta.Y == 0) e.Dx = horizontal; + else e.Dx = (double)(e.Delta.X) / (e.Delta.Y); + } + //--------------------------------------------------------------------------- + + void DoMinimaLML(TEdge E1, TEdge E2, bool IsClosed) + { + if (E1 == null) + { + if (E2 == null) return; + LocalMinima NewLm = new LocalMinima(); + NewLm.Next = null; + NewLm.Y = E2.Bot.Y; + NewLm.LeftBound = null; + E2.WindDelta = 0; + NewLm.RightBound = E2; + InsertLocalMinima(NewLm); + } else + { + //E and E.Prev are now at a local minima ... + LocalMinima NewLm = new LocalMinima(); + NewLm.Y = E1.Bot.Y; + NewLm.Next = null; + if (IsHorizontal(E2)) //Horz. edges never start a Left bound + { + if (E2.Bot.X != E1.Bot.X) ReverseHorizontal(E2); + NewLm.LeftBound = E1; + NewLm.RightBound = E2; + } else if (E2.Dx < E1.Dx) + { + NewLm.LeftBound = E1; + NewLm.RightBound = E2; + } else + { + NewLm.LeftBound = E2; + NewLm.RightBound = E1; + } + NewLm.LeftBound.Side = EdgeSide.esLeft; + NewLm.RightBound.Side = EdgeSide.esRight; + //set the winding state of the first edge in each bound + //(it'll be copied to subsequent edges in the bound) ... + if (!IsClosed) NewLm.LeftBound.WindDelta = 0; + else if (NewLm.LeftBound.Next == NewLm.RightBound) NewLm.LeftBound.WindDelta = -1; + else NewLm.LeftBound.WindDelta = 1; + NewLm.RightBound.WindDelta = -NewLm.LeftBound.WindDelta; + InsertLocalMinima(NewLm); + } + } + //---------------------------------------------------------------------- + + TEdge DescendToMin(ref TEdge E) + { + //PRECONDITION: STARTING EDGE IS A VALID DESCENDING EDGE. + //Starting at the top of one bound we progress to the bottom where there's + //A local minima. We go to the top of the Next bound. These two bounds + //form the left and right (or right and left) bounds of the local minima. + TEdge EHorz; + E.NextInLML = null; + if (IsHorizontal(E)) + { + EHorz = E; + while (IsHorizontal(EHorz.Next)) EHorz = EHorz.Next; + if (EHorz.Bot!= EHorz.Next.Top) + ReverseHorizontal(E); + } + for (;;) + { + E = E.Next; + if (E.OutIdx == Skip) break; + else if (IsHorizontal(E)) + { + //nb: proceed through horizontals when approaching from their right, + // but break on horizontal minima if approaching from their left. + // This ensures 'local minima' are always on the left of horizontals. + + //look ahead is required in case of multiple consec. horizontals + EHorz = GetLastHorz(E); + if(EHorz == E.Prev || //horizontal line + (EHorz.Next.Top.Y < E.Top.Y && //bottom horizontal + EHorz.Next.Bot.X > E.Prev.Bot.X)) //approaching from the left + break; + if (E.Top.X != E.Prev.Bot.X) ReverseHorizontal(E); + if (EHorz.OutIdx == Skip) EHorz = EHorz.Prev; + while (E != EHorz) + { + E.NextInLML = E.Prev; + E = E.Next; + if (E.Top.X != E.Prev.Bot.X) ReverseHorizontal(E); + } + } + else if (E.Bot.Y == E.Prev.Bot.Y) break; + E.NextInLML = E.Prev; + } + return E.Prev; + } + //---------------------------------------------------------------------- + + void AscendToMax(ref TEdge E, bool Appending, bool IsClosed) + { + if (E.OutIdx == Skip) + { + E = E.Next; + if (!MoreAbove(E.Prev)) return; + } + + if (IsHorizontal(E) && Appending && + (E.Bot != E.Prev.Bot)) + ReverseHorizontal(E); + //now process the ascending bound .... + TEdge EStart = E; + for (;;) + { + if (E.Next.OutIdx == Skip || + ((E.Next.Top.Y == E.Top.Y) && !IsHorizontal(E.Next))) break; + E.NextInLML = E.Next; + E = E.Next; + if (IsHorizontal(E) && (E.Bot.X != E.Prev.Top.X)) + ReverseHorizontal(E); + } + + if (!Appending) + { + if (EStart.OutIdx == Skip) EStart = EStart.Next; + if (EStart != E.Next) + DoMinimaLML(null, EStart, IsClosed); + } + E = E.Next; + } + //---------------------------------------------------------------------- + + TEdge AddBoundsToLML(TEdge E, bool Closed) + { + //Starting at the top of one bound we progress to the bottom where there's + //A local minima. We then go to the top of the Next bound. These two bounds + //form the left and right (or right and left) bounds of the local minima. + + TEdge B; + bool AppendMaxima; + //do minima ... + if (E.OutIdx == Skip) + { + if (MoreBelow(E)) + { + E = E.Next; + B = DescendToMin(ref E); + } + else + B = null; + } + else + B = DescendToMin(ref E); + + if (E.OutIdx == Skip) //nb: may be BEFORE, AT or just THRU LM + { + //do minima before Skip... + DoMinimaLML(null, B, Closed); //store what we've got so far (if anything) + AppendMaxima = false; + //finish off any minima ... + if (E.Bot != E.Prev.Bot && MoreBelow(E)) + { + E = E.Next; + B = DescendToMin(ref E); + DoMinimaLML(B, E, Closed); + AppendMaxima = true; + } + else if (JustBeforeLocMin(E)) + E = E.Next; + } + else + { + DoMinimaLML(B, E, Closed); + AppendMaxima = true; + } + + //now do maxima ... + AscendToMax(ref E, AppendMaxima, Closed); + + if (E.OutIdx == Skip && (E.Top != E.Prev.Top)) //may be BEFORE, AT or just AFTER maxima + { + //finish off any maxima ... + if (MoreAbove(E)) + { + E = E.Next; + AscendToMax(ref E, false, Closed); + } + else if (E.Top == E.Next.Top || (IsHorizontal(E.Next) && (E.Top == E.Next.Bot))) + E = E.Next; //ie just before Maxima + } + return E; + } + //------------------------------------------------------------------------------ + + private void InsertLocalMinima(LocalMinima newLm) + { + if( m_MinimaList == null ) + { + m_MinimaList = newLm; + } + else if( newLm.Y >= m_MinimaList.Y ) + { + newLm.Next = m_MinimaList; + m_MinimaList = newLm; + } else + { + LocalMinima tmpLm = m_MinimaList; + while( tmpLm.Next != null && ( newLm.Y < tmpLm.Next.Y ) ) + tmpLm = tmpLm.Next; + newLm.Next = tmpLm.Next; + tmpLm.Next = newLm; + } + } + //------------------------------------------------------------------------------ + + protected void PopLocalMinima() + { + if (m_CurrentLM == null) return; + m_CurrentLM = m_CurrentLM.Next; + } + //------------------------------------------------------------------------------ + + private void ReverseHorizontal(TEdge e) + { + //swap horizontal edges' top and bottom x's so they follow the natural + //progression of the bounds - ie so their xbots will align with the + //adjoining lower edge. [Helpful in the ProcessHorizontal() method.] + cInt tmp = e.Top.X; + e.Top.X = e.Bot.X; + e.Bot.X = tmp; +#if use_xyz + tmp = e.Top.Z; + e.Top.Z = e.Bot.Z; + e.Bot.Z = tmp; +#endif + } + //------------------------------------------------------------------------------ + + protected virtual void Reset() + { + m_CurrentLM = m_MinimaList; + if (m_CurrentLM == null) return; //ie nothing to process + + //reset all edges ... + LocalMinima lm = m_MinimaList; + while (lm != null) + { + TEdge e = lm.LeftBound; + if (e != null) + { + e.Curr = e.Bot; + e.Side = EdgeSide.esLeft; + if (e.OutIdx != Skip) + e.OutIdx = Unassigned; + } + e = lm.RightBound; + e.Curr = e.Bot; + e.Side = EdgeSide.esRight; + if (e.OutIdx != Skip) + e.OutIdx = Unassigned; + + lm = lm.Next; + } + } + //------------------------------------------------------------------------------ + + public IntRect GetBounds() + { + IntRect result = new IntRect(); + LocalMinima lm = m_MinimaList; + if (lm == null) return result; + result.left = lm.LeftBound.Bot.X; + result.top = lm.LeftBound.Bot.Y; + result.right = lm.LeftBound.Bot.X; + result.bottom = lm.LeftBound.Bot.Y; + while (lm != null) + { + if (lm.LeftBound.Bot.Y > result.bottom) + result.bottom = lm.LeftBound.Bot.Y; + TEdge e = lm.LeftBound; + for (; ; ) + { + TEdge bottomE = e; + while (e.NextInLML != null) + { + if (e.Bot.X < result.left) result.left = e.Bot.X; + if (e.Bot.X > result.right) result.right = e.Bot.X; + e = e.NextInLML; + } + if (e.Bot.X < result.left) result.left = e.Bot.X; + if (e.Bot.X > result.right) result.right = e.Bot.X; + if (e.Top.X < result.left) result.left = e.Top.X; + if (e.Top.X > result.right) result.right = e.Top.X; + if (e.Top.Y < result.top) result.top = e.Top.Y; + + if (bottomE == lm.LeftBound) e = lm.RightBound; + else break; + } + lm = lm.Next; + } + return result; + } + + } //end ClipperBase + + public class Clipper : ClipperBase + { + //InitOptions that can be passed to the constructor ... + public const int ioReverseSolution = 1; + public const int ioStrictlySimple = 2; + public const int ioPreserveCollinear = 4; + + private List m_PolyOuts; + private ClipType m_ClipType; + private Scanbeam m_Scanbeam; + private TEdge m_ActiveEdges; + private TEdge m_SortedEdges; + private IntersectNode m_IntersectNodes; + private bool m_ExecuteLocked; + private PolyFillType m_ClipFillType; + private PolyFillType m_SubjFillType; + private List m_Joins; + private List m_GhostJoins; + private bool m_UsingPolyTree; +#if use_xyz + public delegate void TZFillCallback(IntPoint vert1, IntPoint vert2, ref IntPoint intersectPt); + public TZFillCallback ZFillFunction { get; set; } +#endif + public Clipper(int InitOptions = 0): base() //constructor + { + m_Scanbeam = null; + m_ActiveEdges = null; + m_SortedEdges = null; + m_IntersectNodes = null; + m_ExecuteLocked = false; + m_UsingPolyTree = false; + m_PolyOuts = new List(); + m_Joins = new List(); + m_GhostJoins = new List(); + ReverseSolution = (ioReverseSolution & InitOptions) != 0; + StrictlySimple = (ioStrictlySimple & InitOptions) != 0; + PreserveCollinear = (ioPreserveCollinear & InitOptions) != 0; +#if use_xyz + ZFillFunction = null; +#endif + } + //------------------------------------------------------------------------------ + + public override void Clear() + { + if (m_edges.Count == 0) return; //avoids problems with ClipperBase destructor + DisposeAllPolyPts(); + base.Clear(); + } + //------------------------------------------------------------------------------ + + void DisposeScanbeamList() + { + while ( m_Scanbeam != null ) { + Scanbeam sb2 = m_Scanbeam.Next; + m_Scanbeam = null; + m_Scanbeam = sb2; + } + } + //------------------------------------------------------------------------------ + + protected override void Reset() + { + base.Reset(); + m_Scanbeam = null; + m_ActiveEdges = null; + m_SortedEdges = null; + DisposeAllPolyPts(); + LocalMinima lm = m_MinimaList; + while (lm != null) + { + InsertScanbeam(lm.Y); + lm = lm.Next; + } + } + //------------------------------------------------------------------------------ + + public bool ReverseSolution + { + get; + set; + } + //------------------------------------------------------------------------------ + + public bool StrictlySimple + { + get; + set; + } + //------------------------------------------------------------------------------ + + private void InsertScanbeam(cInt Y) + { + if( m_Scanbeam == null ) + { + m_Scanbeam = new Scanbeam(); + m_Scanbeam.Next = null; + m_Scanbeam.Y = Y; + } + else if( Y > m_Scanbeam.Y ) + { + Scanbeam newSb = new Scanbeam(); + newSb.Y = Y; + newSb.Next = m_Scanbeam; + m_Scanbeam = newSb; + } else + { + Scanbeam sb2 = m_Scanbeam; + while( sb2.Next != null && ( Y <= sb2.Next.Y ) ) sb2 = sb2.Next; + if( Y == sb2.Y ) return; //ie ignores duplicates + Scanbeam newSb = new Scanbeam(); + newSb.Y = Y; + newSb.Next = sb2.Next; + sb2.Next = newSb; + } + } + //------------------------------------------------------------------------------ + + public bool Execute(ClipType clipType, Paths solution, + PolyFillType subjFillType, PolyFillType clipFillType) + { + if (m_ExecuteLocked) return false; + if (m_HasOpenPaths) throw + new ClipperException("Error: PolyTree struct is need for open path clipping."); + + m_ExecuteLocked = true; + solution.Clear(); + m_SubjFillType = subjFillType; + m_ClipFillType = clipFillType; + m_ClipType = clipType; + m_UsingPolyTree = false; + bool succeeded = ExecuteInternal(); + //build the return polygons ... + if (succeeded) BuildResult(solution); + m_ExecuteLocked = false; + return succeeded; + } + //------------------------------------------------------------------------------ + + public bool Execute(ClipType clipType, PolyTree polytree, + PolyFillType subjFillType, PolyFillType clipFillType) + { + if (m_ExecuteLocked) return false; + m_ExecuteLocked = true; + m_SubjFillType = subjFillType; + m_ClipFillType = clipFillType; + m_ClipType = clipType; + m_UsingPolyTree = true; + bool succeeded = ExecuteInternal(); + //build the return polygons ... + if (succeeded) BuildResult2(polytree); + m_ExecuteLocked = false; + return succeeded; + } + //------------------------------------------------------------------------------ + + public bool Execute(ClipType clipType, Paths solution) + { + return Execute(clipType, solution, + PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); + } + //------------------------------------------------------------------------------ + + public bool Execute(ClipType clipType, PolyTree polytree) + { + return Execute(clipType, polytree, + PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); + } + //------------------------------------------------------------------------------ + + internal void FixHoleLinkage(OutRec outRec) + { + //skip if an outermost polygon or + //already already points to the correct FirstLeft ... + if (outRec.FirstLeft == null || + (outRec.IsHole != outRec.FirstLeft.IsHole && + outRec.FirstLeft.Pts != null)) return; + + OutRec orfl = outRec.FirstLeft; + while (orfl != null && ((orfl.IsHole == outRec.IsHole) || orfl.Pts == null)) + orfl = orfl.FirstLeft; + outRec.FirstLeft = orfl; + } + //------------------------------------------------------------------------------ + + private bool ExecuteInternal() + { + try + { + Reset(); + if (m_CurrentLM == null) return false; + + cInt botY = PopScanbeam(); + do + { + InsertLocalMinimaIntoAEL(botY); + m_GhostJoins.Clear(); + ProcessHorizontals(false); + if (m_Scanbeam == null) break; + cInt topY = PopScanbeam(); + if (!ProcessIntersections(botY, topY)) return false; + ProcessEdgesAtTopOfScanbeam(topY); + botY = topY; + } while (m_Scanbeam != null || m_CurrentLM != null); + + //fix orientations ... + for (int i = 0; i < m_PolyOuts.Count; i++) + { + OutRec outRec = m_PolyOuts[i]; + if (outRec.Pts == null || outRec.IsOpen) continue; + if ((outRec.IsHole ^ ReverseSolution) == (Area(outRec) > 0)) + ReversePolyPtLinks(outRec.Pts); + } + + JoinCommonEdges(); + + for (int i = 0; i < m_PolyOuts.Count; i++) + { + OutRec outRec = m_PolyOuts[i]; + if (outRec.Pts != null && !outRec.IsOpen) + FixupOutPolygon(outRec); + } + + if (StrictlySimple) DoSimplePolygons(); + return true; + } + //catch { return false; } + finally + { + m_Joins.Clear(); + m_GhostJoins.Clear(); + } + } + //------------------------------------------------------------------------------ + + private cInt PopScanbeam() + { + cInt Y = m_Scanbeam.Y; + Scanbeam sb2 = m_Scanbeam; + m_Scanbeam = m_Scanbeam.Next; + sb2 = null; + return Y; + } + //------------------------------------------------------------------------------ + + private void DisposeAllPolyPts(){ + for (int i = 0; i < m_PolyOuts.Count; ++i) DisposeOutRec(i); + m_PolyOuts.Clear(); + } + //------------------------------------------------------------------------------ + + void DisposeOutRec(int index) + { + OutRec outRec = m_PolyOuts[index]; + if (outRec.Pts != null) DisposeOutPts(outRec.Pts); + outRec = null; + m_PolyOuts[index] = null; + } + //------------------------------------------------------------------------------ + + private void DisposeOutPts(OutPt pp) + { + if (pp == null) return; + OutPt tmpPp = null; + pp.Prev.Next = null; + while (pp != null) + { + tmpPp = pp; + pp = pp.Next; + tmpPp = null; + } + } + //------------------------------------------------------------------------------ + + private void AddJoin(OutPt Op1, OutPt Op2, IntPoint OffPt) + { + Join j = new Join(); + j.OutPt1 = Op1; + j.OutPt2 = Op2; + j.OffPt = OffPt; + m_Joins.Add(j); + } + //------------------------------------------------------------------------------ + + private void AddGhostJoin(OutPt Op, IntPoint OffPt) + { + Join j = new Join(); + j.OutPt1 = Op; + j.OffPt = OffPt; + m_GhostJoins.Add(j); + } + //------------------------------------------------------------------------------ + +#if use_xyz + internal void SetZ(ref IntPoint pt, TEdge e) + { + pt.Z = 0; + if (ZFillFunction != null) + { + //put the 'preferred' point as first parameter ... + if (e.OutIdx < 0) + ZFillFunction(e.Bot, e.Top, ref pt); //outside a path so presume entering + else + ZFillFunction(e.Top, e.Bot, ref pt); //inside a path so presume exiting + } + } + //------------------------------------------------------------------------------ +#endif + + private void InsertLocalMinimaIntoAEL(cInt botY) + { + while( m_CurrentLM != null && ( m_CurrentLM.Y == botY ) ) + { + TEdge lb = m_CurrentLM.LeftBound; + TEdge rb = m_CurrentLM.RightBound; + PopLocalMinima(); + + OutPt Op1 = null; + if (lb == null) + { + InsertEdgeIntoAEL(rb, null); + SetWindingCount(rb); + if (IsContributing(rb)) + Op1 = AddOutPt(rb, rb.Bot); + } + else + { + InsertEdgeIntoAEL(lb, null); + InsertEdgeIntoAEL(rb, lb); + SetWindingCount(lb); + rb.WindCnt = lb.WindCnt; + rb.WindCnt2 = lb.WindCnt2; + if (IsContributing(lb)) + Op1 = AddLocalMinPoly(lb, rb, lb.Bot); + + InsertScanbeam(lb.Top.Y); + } + + if (IsHorizontal(rb)) + AddEdgeToSEL(rb); + else + InsertScanbeam( rb.Top.Y ); + + if (lb == null) continue; + + //if output polygons share an Edge with a horizontal rb, they'll need joining later ... + if (Op1 != null && IsHorizontal(rb) && + m_GhostJoins.Count > 0 && rb.WindDelta != 0) + { + for (int i = 0; i < m_GhostJoins.Count; i++) + { + //if the horizontal Rb and a 'ghost' horizontal overlap, then convert + //the 'ghost' join to a real join ready for later ... + Join j = m_GhostJoins[i]; + if (HorzSegmentsOverlap(j.OutPt1.Pt, j.OffPt, rb.Bot, rb.Top)) + AddJoin(j.OutPt1, Op1, j.OffPt); + } + } + + if (lb.OutIdx >= 0 && lb.PrevInAEL != null && + lb.PrevInAEL.Curr.X == lb.Bot.X && + lb.PrevInAEL.OutIdx >= 0 && + SlopesEqual(lb.PrevInAEL, lb, m_UseFullRange) && + lb.WindDelta != 0 && lb.PrevInAEL.WindDelta != 0) + { + OutPt Op2 = AddOutPt(lb.PrevInAEL, lb.Bot); + AddJoin(Op1, Op2, lb.Top); + } + + if( lb.NextInAEL != rb ) + { + + if (rb.OutIdx >= 0 && rb.PrevInAEL.OutIdx >= 0 && + SlopesEqual(rb.PrevInAEL, rb, m_UseFullRange) && + rb.WindDelta != 0 && rb.PrevInAEL.WindDelta != 0) + { + OutPt Op2 = AddOutPt(rb.PrevInAEL, rb.Bot); + AddJoin(Op1, Op2, rb.Top); + } + + TEdge e = lb.NextInAEL; + if (e != null) + while (e != rb) + { + //nb: For calculating winding counts etc, IntersectEdges() assumes + //that param1 will be to the right of param2 ABOVE the intersection ... + IntersectEdges(rb, e, lb.Curr); //order important here + e = e.NextInAEL; + } + } + } + } + //------------------------------------------------------------------------------ + + private void InsertEdgeIntoAEL(TEdge edge, TEdge startEdge) + { + if (m_ActiveEdges == null) + { + edge.PrevInAEL = null; + edge.NextInAEL = null; + m_ActiveEdges = edge; + } + else if (startEdge == null && E2InsertsBeforeE1(m_ActiveEdges, edge)) + { + edge.PrevInAEL = null; + edge.NextInAEL = m_ActiveEdges; + m_ActiveEdges.PrevInAEL = edge; + m_ActiveEdges = edge; + } + else + { + if (startEdge == null) startEdge = m_ActiveEdges; + while (startEdge.NextInAEL != null && + !E2InsertsBeforeE1(startEdge.NextInAEL, edge)) + startEdge = startEdge.NextInAEL; + edge.NextInAEL = startEdge.NextInAEL; + if (startEdge.NextInAEL != null) startEdge.NextInAEL.PrevInAEL = edge; + edge.PrevInAEL = startEdge; + startEdge.NextInAEL = edge; + } + } + //---------------------------------------------------------------------- + + private bool E2InsertsBeforeE1(TEdge e1, TEdge e2) + { + if (e2.Curr.X == e1.Curr.X) + { + if (e2.Top.Y > e1.Top.Y) + return e2.Top.X < TopX(e1, e2.Top.Y); + else return e1.Top.X > TopX(e2, e1.Top.Y); + } + else return e2.Curr.X < e1.Curr.X; + } + //------------------------------------------------------------------------------ + + private bool IsEvenOddFillType(TEdge edge) + { + if (edge.PolyTyp == PolyType.ptSubject) + return m_SubjFillType == PolyFillType.pftEvenOdd; + else + return m_ClipFillType == PolyFillType.pftEvenOdd; + } + //------------------------------------------------------------------------------ + + private bool IsEvenOddAltFillType(TEdge edge) + { + if (edge.PolyTyp == PolyType.ptSubject) + return m_ClipFillType == PolyFillType.pftEvenOdd; + else + return m_SubjFillType == PolyFillType.pftEvenOdd; + } + //------------------------------------------------------------------------------ + + private bool IsContributing(TEdge edge) + { + PolyFillType pft, pft2; + if (edge.PolyTyp == PolyType.ptSubject) + { + pft = m_SubjFillType; + pft2 = m_ClipFillType; + } + else + { + pft = m_ClipFillType; + pft2 = m_SubjFillType; + } + + switch (pft) + { + case PolyFillType.pftEvenOdd: + //return false if a subj line has been flagged as inside a subj polygon + if (edge.WindDelta == 0 && edge.WindCnt != 1) return false; + break; + case PolyFillType.pftNonZero: + if (Math.Abs(edge.WindCnt) != 1) return false; + break; + case PolyFillType.pftPositive: + if (edge.WindCnt != 1) return false; + break; + default: //PolyFillType.pftNegative + if (edge.WindCnt != -1) return false; + break; + } + + switch (m_ClipType) + { + case ClipType.ctIntersection: + switch (pft2) + { + case PolyFillType.pftEvenOdd: + case PolyFillType.pftNonZero: + return (edge.WindCnt2 != 0); + case PolyFillType.pftPositive: + return (edge.WindCnt2 > 0); + default: + return (edge.WindCnt2 < 0); + } + case ClipType.ctUnion: + switch (pft2) + { + case PolyFillType.pftEvenOdd: + case PolyFillType.pftNonZero: + return (edge.WindCnt2 == 0); + case PolyFillType.pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + case ClipType.ctDifference: + if (edge.PolyTyp == PolyType.ptSubject) + switch (pft2) + { + case PolyFillType.pftEvenOdd: + case PolyFillType.pftNonZero: + return (edge.WindCnt2 == 0); + case PolyFillType.pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + else + switch (pft2) + { + case PolyFillType.pftEvenOdd: + case PolyFillType.pftNonZero: + return (edge.WindCnt2 != 0); + case PolyFillType.pftPositive: + return (edge.WindCnt2 > 0); + default: + return (edge.WindCnt2 < 0); + } + case ClipType.ctXor: + if (edge.WindDelta == 0) //XOr always contributing unless open + switch (pft2) + { + case PolyFillType.pftEvenOdd: + case PolyFillType.pftNonZero: + return (edge.WindCnt2 == 0); + case PolyFillType.pftPositive: + return (edge.WindCnt2 <= 0); + default: + return (edge.WindCnt2 >= 0); + } + else + return true; + } + return true; + } + //------------------------------------------------------------------------------ + + private void SetWindingCount(TEdge edge) + { + TEdge e = edge.PrevInAEL; + //find the edge of the same polytype that immediately preceeds 'edge' in AEL + while (e != null && ((e.PolyTyp != edge.PolyTyp) || (e.WindDelta == 0))) e = e.PrevInAEL; + if (e == null) + { + edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); + edge.WindCnt2 = 0; + e = m_ActiveEdges; //ie get ready to calc WindCnt2 + } + else if (edge.WindDelta == 0 && m_ClipType != ClipType.ctUnion) + { + edge.WindCnt = 1; + edge.WindCnt2 = e.WindCnt2; + e = e.NextInAEL; //ie get ready to calc WindCnt2 + } + else if (IsEvenOddFillType(edge)) + { + //EvenOdd filling ... + if (edge.WindDelta == 0) + { + //are we inside a subj polygon ... + bool Inside = true; + TEdge e2 = e.PrevInAEL; + while (e2 != null) + { + if (e2.PolyTyp == e.PolyTyp && e2.WindDelta != 0) + Inside = !Inside; + e2 = e2.PrevInAEL; + } + edge.WindCnt = (Inside ? 0 : 1); + } + else + { + edge.WindCnt = edge.WindDelta; + } + edge.WindCnt2 = e.WindCnt2; + e = e.NextInAEL; //ie get ready to calc WindCnt2 + } + else + { + //nonZero, Positive or Negative filling ... + if (e.WindCnt * e.WindDelta < 0) + { + //prev edge is 'decreasing' WindCount (WC) toward zero + //so we're outside the previous polygon ... + if (Math.Abs(e.WindCnt) > 1) + { + //outside prev poly but still inside another. + //when reversing direction of prev poly use the same WC + if (e.WindDelta * edge.WindDelta < 0) edge.WindCnt = e.WindCnt; + //otherwise continue to 'decrease' WC ... + else edge.WindCnt = e.WindCnt + edge.WindDelta; + } + else + //now outside all polys of same polytype so set own WC ... + edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); + } + else + { + //prev edge is 'increasing' WindCount (WC) away from zero + //so we're inside the previous polygon ... + if (edge.WindDelta == 0) + edge.WindCnt = (e.WindCnt < 0 ? e.WindCnt - 1 : e.WindCnt + 1); + //if wind direction is reversing prev then use same WC + else if (e.WindDelta * edge.WindDelta < 0) + edge.WindCnt = e.WindCnt; + //otherwise add to WC ... + else edge.WindCnt = e.WindCnt + edge.WindDelta; + } + edge.WindCnt2 = e.WindCnt2; + e = e.NextInAEL; //ie get ready to calc WindCnt2 + } + + //update WindCnt2 ... + if (IsEvenOddAltFillType(edge)) + { + //EvenOdd filling ... + while (e != edge) + { + if (e.WindDelta != 0) + edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0); + e = e.NextInAEL; + } + } + else + { + //nonZero, Positive or Negative filling ... + while (e != edge) + { + edge.WindCnt2 += e.WindDelta; + e = e.NextInAEL; + } + } + } + //------------------------------------------------------------------------------ + + private void AddEdgeToSEL(TEdge edge) + { + //SEL pointers in PEdge are reused to build a list of horizontal edges. + //However, we don't need to worry about order with horizontal edge processing. + if (m_SortedEdges == null) + { + m_SortedEdges = edge; + edge.PrevInSEL = null; + edge.NextInSEL = null; + } + else + { + edge.NextInSEL = m_SortedEdges; + edge.PrevInSEL = null; + m_SortedEdges.PrevInSEL = edge; + m_SortedEdges = edge; + } + } + //------------------------------------------------------------------------------ + + private void CopyAELToSEL() + { + TEdge e = m_ActiveEdges; + m_SortedEdges = e; + while (e != null) + { + e.PrevInSEL = e.PrevInAEL; + e.NextInSEL = e.NextInAEL; + e = e.NextInAEL; + } + } + //------------------------------------------------------------------------------ + + private void SwapPositionsInAEL(TEdge edge1, TEdge edge2) + { + //check that one or other edge hasn't already been removed from AEL ... + if (edge1.NextInAEL == edge1.PrevInAEL || + edge2.NextInAEL == edge2.PrevInAEL) return; + + if (edge1.NextInAEL == edge2) + { + TEdge next = edge2.NextInAEL; + if (next != null) + next.PrevInAEL = edge1; + TEdge prev = edge1.PrevInAEL; + if (prev != null) + prev.NextInAEL = edge2; + edge2.PrevInAEL = prev; + edge2.NextInAEL = edge1; + edge1.PrevInAEL = edge2; + edge1.NextInAEL = next; + } + else if (edge2.NextInAEL == edge1) + { + TEdge next = edge1.NextInAEL; + if (next != null) + next.PrevInAEL = edge2; + TEdge prev = edge2.PrevInAEL; + if (prev != null) + prev.NextInAEL = edge1; + edge1.PrevInAEL = prev; + edge1.NextInAEL = edge2; + edge2.PrevInAEL = edge1; + edge2.NextInAEL = next; + } + else + { + TEdge next = edge1.NextInAEL; + TEdge prev = edge1.PrevInAEL; + edge1.NextInAEL = edge2.NextInAEL; + if (edge1.NextInAEL != null) + edge1.NextInAEL.PrevInAEL = edge1; + edge1.PrevInAEL = edge2.PrevInAEL; + if (edge1.PrevInAEL != null) + edge1.PrevInAEL.NextInAEL = edge1; + edge2.NextInAEL = next; + if (edge2.NextInAEL != null) + edge2.NextInAEL.PrevInAEL = edge2; + edge2.PrevInAEL = prev; + if (edge2.PrevInAEL != null) + edge2.PrevInAEL.NextInAEL = edge2; + } + + if (edge1.PrevInAEL == null) + m_ActiveEdges = edge1; + else if (edge2.PrevInAEL == null) + m_ActiveEdges = edge2; + } + //------------------------------------------------------------------------------ + + private void SwapPositionsInSEL(TEdge edge1, TEdge edge2) + { + if (edge1.NextInSEL == null && edge1.PrevInSEL == null) + return; + if (edge2.NextInSEL == null && edge2.PrevInSEL == null) + return; + + if (edge1.NextInSEL == edge2) + { + TEdge next = edge2.NextInSEL; + if (next != null) + next.PrevInSEL = edge1; + TEdge prev = edge1.PrevInSEL; + if (prev != null) + prev.NextInSEL = edge2; + edge2.PrevInSEL = prev; + edge2.NextInSEL = edge1; + edge1.PrevInSEL = edge2; + edge1.NextInSEL = next; + } + else if (edge2.NextInSEL == edge1) + { + TEdge next = edge1.NextInSEL; + if (next != null) + next.PrevInSEL = edge2; + TEdge prev = edge2.PrevInSEL; + if (prev != null) + prev.NextInSEL = edge1; + edge1.PrevInSEL = prev; + edge1.NextInSEL = edge2; + edge2.PrevInSEL = edge1; + edge2.NextInSEL = next; + } + else + { + TEdge next = edge1.NextInSEL; + TEdge prev = edge1.PrevInSEL; + edge1.NextInSEL = edge2.NextInSEL; + if (edge1.NextInSEL != null) + edge1.NextInSEL.PrevInSEL = edge1; + edge1.PrevInSEL = edge2.PrevInSEL; + if (edge1.PrevInSEL != null) + edge1.PrevInSEL.NextInSEL = edge1; + edge2.NextInSEL = next; + if (edge2.NextInSEL != null) + edge2.NextInSEL.PrevInSEL = edge2; + edge2.PrevInSEL = prev; + if (edge2.PrevInSEL != null) + edge2.PrevInSEL.NextInSEL = edge2; + } + + if (edge1.PrevInSEL == null) + m_SortedEdges = edge1; + else if (edge2.PrevInSEL == null) + m_SortedEdges = edge2; + } + //------------------------------------------------------------------------------ + + + private void AddLocalMaxPoly(TEdge e1, TEdge e2, IntPoint pt) + { + AddOutPt(e1, pt); + if (e1.OutIdx == e2.OutIdx) + { + e1.OutIdx = Unassigned; + e2.OutIdx = Unassigned; + } + else if (e1.OutIdx < e2.OutIdx) + AppendPolygon(e1, e2); + else + AppendPolygon(e2, e1); + } + //------------------------------------------------------------------------------ + + private OutPt AddLocalMinPoly(TEdge e1, TEdge e2, IntPoint pt) + { + OutPt result; + TEdge e, prevE; + if (IsHorizontal(e2) || (e1.Dx > e2.Dx)) + { + result = AddOutPt(e1, pt); + e2.OutIdx = e1.OutIdx; + e1.Side = EdgeSide.esLeft; + e2.Side = EdgeSide.esRight; + e = e1; + if (e.PrevInAEL == e2) + prevE = e2.PrevInAEL; + else + prevE = e.PrevInAEL; + } + else + { + result = AddOutPt(e2, pt); + e1.OutIdx = e2.OutIdx; + e1.Side = EdgeSide.esRight; + e2.Side = EdgeSide.esLeft; + e = e2; + if (e.PrevInAEL == e1) + prevE = e1.PrevInAEL; + else + prevE = e.PrevInAEL; + } + + if (prevE != null && prevE.OutIdx >= 0 && + (TopX(prevE, pt.Y) == TopX(e, pt.Y)) && + SlopesEqual(e, prevE, m_UseFullRange) && + (e.WindDelta != 0) && (prevE.WindDelta != 0)) + { + OutPt outPt = AddOutPt(prevE, pt); + AddJoin(result, outPt, e.Top); + } + return result; + } + //------------------------------------------------------------------------------ + + private OutRec CreateOutRec() + { + OutRec result = new OutRec(); + result.Idx = Unassigned; + result.IsHole = false; + result.IsOpen = false; + result.FirstLeft = null; + result.Pts = null; + result.BottomPt = null; + result.PolyNode = null; + m_PolyOuts.Add(result); + result.Idx = m_PolyOuts.Count - 1; + return result; + } + //------------------------------------------------------------------------------ + + private OutPt AddOutPt(TEdge e, IntPoint pt) + { + bool ToFront = (e.Side == EdgeSide.esLeft); + if( e.OutIdx < 0 ) + { + OutRec outRec = CreateOutRec(); + outRec.IsOpen = (e.WindDelta == 0); + OutPt newOp = new OutPt(); + outRec.Pts = newOp; + newOp.Idx = outRec.Idx; + newOp.Pt = pt; + newOp.Next = newOp; + newOp.Prev = newOp; + if (!outRec.IsOpen) + SetHoleState(e, outRec); +#if use_xyz + if (pt == e.Bot) + newOp.Pt = e.Bot; + else if (pt == e.Top) + newOp.Pt = e.Top; + else + SetZ(ref newOp.Pt, e); +#endif + e.OutIdx = outRec.Idx; //nb: do this after SetZ ! + return newOp; + } else + { + OutRec outRec = m_PolyOuts[e.OutIdx]; + //OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most' + OutPt op = outRec.Pts; + if (ToFront && pt == op.Pt) return op; + else if (!ToFront && pt == op.Prev.Pt) return op.Prev; + + OutPt newOp = new OutPt(); + newOp.Idx = outRec.Idx; + newOp.Pt = pt; + newOp.Next = op; + newOp.Prev = op.Prev; + newOp.Prev.Next = newOp; + op.Prev = newOp; + if (ToFront) outRec.Pts = newOp; +#if use_xyz + if (pt == e.Bot) + newOp.Pt = e.Bot; + else if (pt == e.Top) + newOp.Pt = e.Top; + else + SetZ(ref newOp.Pt, e); +#endif + return newOp; + } + } + //------------------------------------------------------------------------------ + + internal void SwapPoints(ref IntPoint pt1, ref IntPoint pt2) + { + IntPoint tmp = new IntPoint(pt1); + pt1 = pt2; + pt2 = tmp; + } + //------------------------------------------------------------------------------ + + private bool HorzSegmentsOverlap( + IntPoint Pt1a, IntPoint Pt1b, IntPoint Pt2a, IntPoint Pt2b) + { + //precondition: both segments are horizontal + if ((Pt1a.X > Pt2a.X) == (Pt1a.X < Pt2b.X)) return true; + else if ((Pt1b.X > Pt2a.X) == (Pt1b.X < Pt2b.X)) return true; + else if ((Pt2a.X > Pt1a.X) == (Pt2a.X < Pt1b.X)) return true; + else if ((Pt2b.X > Pt1a.X) == (Pt2b.X < Pt1b.X)) return true; + else if ((Pt1a.X == Pt2a.X) && (Pt1b.X == Pt2b.X)) return true; + else if ((Pt1a.X == Pt2b.X) && (Pt1b.X == Pt2a.X)) return true; + else return false; + } + //------------------------------------------------------------------------------ + + private OutPt InsertPolyPtBetween(OutPt p1, OutPt p2, IntPoint pt) + { + OutPt result = new OutPt(); + result.Pt = pt; + if (p2 == p1.Next) + { + p1.Next = result; + p2.Prev = result; + result.Next = p2; + result.Prev = p1; + } else + { + p2.Next = result; + p1.Prev = result; + result.Next = p1; + result.Prev = p2; + } + return result; + } + //------------------------------------------------------------------------------ + + private void SetHoleState(TEdge e, OutRec outRec) + { + bool isHole = false; + TEdge e2 = e.PrevInAEL; + while (e2 != null) + { + if (e2.OutIdx >= 0) + { + isHole = !isHole; + if (outRec.FirstLeft == null) + outRec.FirstLeft = m_PolyOuts[e2.OutIdx]; + } + e2 = e2.PrevInAEL; + } + if (isHole) outRec.IsHole = true; + } + //------------------------------------------------------------------------------ + + private double GetDx(IntPoint pt1, IntPoint pt2) + { + if (pt1.Y == pt2.Y) return horizontal; + else return (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y); + } + //--------------------------------------------------------------------------- + + private bool FirstIsBottomPt(OutPt btmPt1, OutPt btmPt2) + { + OutPt p = btmPt1.Prev; + while ((p.Pt == btmPt1.Pt) && (p != btmPt1)) p = p.Prev; + double dx1p = Math.Abs(GetDx(btmPt1.Pt, p.Pt)); + p = btmPt1.Next; + while ((p.Pt == btmPt1.Pt) && (p != btmPt1)) p = p.Next; + double dx1n = Math.Abs(GetDx(btmPt1.Pt, p.Pt)); + + p = btmPt2.Prev; + while ((p.Pt == btmPt2.Pt) && (p != btmPt2)) p = p.Prev; + double dx2p = Math.Abs(GetDx(btmPt2.Pt, p.Pt)); + p = btmPt2.Next; + while ((p.Pt == btmPt2.Pt) && (p != btmPt2)) p = p.Next; + double dx2n = Math.Abs(GetDx(btmPt2.Pt, p.Pt)); + return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); + } + //------------------------------------------------------------------------------ + + private OutPt GetBottomPt(OutPt pp) + { + OutPt dups = null; + OutPt p = pp.Next; + while (p != pp) + { + if (p.Pt.Y > pp.Pt.Y) + { + pp = p; + dups = null; + } + else if (p.Pt.Y == pp.Pt.Y && p.Pt.X <= pp.Pt.X) + { + if (p.Pt.X < pp.Pt.X) + { + dups = null; + pp = p; + } else + { + if (p.Next != pp && p.Prev != pp) dups = p; + } + } + p = p.Next; + } + if (dups != null) + { + //there appears to be at least 2 vertices at bottomPt so ... + while (dups != p) + { + if (!FirstIsBottomPt(p, dups)) pp = dups; + dups = dups.Next; + while (dups.Pt != pp.Pt) dups = dups.Next; + } + } + return pp; + } + //------------------------------------------------------------------------------ + + private OutRec GetLowermostRec(OutRec outRec1, OutRec outRec2) + { + //work out which polygon fragment has the correct hole state ... + if (outRec1.BottomPt == null) + outRec1.BottomPt = GetBottomPt(outRec1.Pts); + if (outRec2.BottomPt == null) + outRec2.BottomPt = GetBottomPt(outRec2.Pts); + OutPt bPt1 = outRec1.BottomPt; + OutPt bPt2 = outRec2.BottomPt; + if (bPt1.Pt.Y > bPt2.Pt.Y) return outRec1; + else if (bPt1.Pt.Y < bPt2.Pt.Y) return outRec2; + else if (bPt1.Pt.X < bPt2.Pt.X) return outRec1; + else if (bPt1.Pt.X > bPt2.Pt.X) return outRec2; + else if (bPt1.Next == bPt1) return outRec2; + else if (bPt2.Next == bPt2) return outRec1; + else if (FirstIsBottomPt(bPt1, bPt2)) return outRec1; + else return outRec2; + } + //------------------------------------------------------------------------------ + + bool Param1RightOfParam2(OutRec outRec1, OutRec outRec2) + { + do + { + outRec1 = outRec1.FirstLeft; + if (outRec1 == outRec2) return true; + } while (outRec1 != null); + return false; + } + //------------------------------------------------------------------------------ + + private OutRec GetOutRec(int idx) + { + OutRec outrec = m_PolyOuts[idx]; + while (outrec != m_PolyOuts[outrec.Idx]) + outrec = m_PolyOuts[outrec.Idx]; + return outrec; + } + //------------------------------------------------------------------------------ + + private void AppendPolygon(TEdge e1, TEdge e2) + { + //get the start and ends of both output polygons ... + OutRec outRec1 = m_PolyOuts[e1.OutIdx]; + OutRec outRec2 = m_PolyOuts[e2.OutIdx]; + + OutRec holeStateRec; + if (Param1RightOfParam2(outRec1, outRec2)) + holeStateRec = outRec2; + else if (Param1RightOfParam2(outRec2, outRec1)) + holeStateRec = outRec1; + else + holeStateRec = GetLowermostRec(outRec1, outRec2); + + OutPt p1_lft = outRec1.Pts; + OutPt p1_rt = p1_lft.Prev; + OutPt p2_lft = outRec2.Pts; + OutPt p2_rt = p2_lft.Prev; + + EdgeSide side; + //join e2 poly onto e1 poly and delete pointers to e2 ... + if( e1.Side == EdgeSide.esLeft ) + { + if (e2.Side == EdgeSide.esLeft) + { + //z y x a b c + ReversePolyPtLinks(p2_lft); + p2_lft.Next = p1_lft; + p1_lft.Prev = p2_lft; + p1_rt.Next = p2_rt; + p2_rt.Prev = p1_rt; + outRec1.Pts = p2_rt; + } else + { + //x y z a b c + p2_rt.Next = p1_lft; + p1_lft.Prev = p2_rt; + p2_lft.Prev = p1_rt; + p1_rt.Next = p2_lft; + outRec1.Pts = p2_lft; + } + side = EdgeSide.esLeft; + } else + { + if (e2.Side == EdgeSide.esRight) + { + //a b c z y x + ReversePolyPtLinks( p2_lft ); + p1_rt.Next = p2_rt; + p2_rt.Prev = p1_rt; + p2_lft.Next = p1_lft; + p1_lft.Prev = p2_lft; + } else + { + //a b c x y z + p1_rt.Next = p2_lft; + p2_lft.Prev = p1_rt; + p1_lft.Prev = p2_rt; + p2_rt.Next = p1_lft; + } + side = EdgeSide.esRight; + } + + outRec1.BottomPt = null; + if (holeStateRec == outRec2) + { + if (outRec2.FirstLeft != outRec1) + outRec1.FirstLeft = outRec2.FirstLeft; + outRec1.IsHole = outRec2.IsHole; + } + outRec2.Pts = null; + outRec2.BottomPt = null; + + outRec2.FirstLeft = outRec1; + + int OKIdx = e1.OutIdx; + int ObsoleteIdx = e2.OutIdx; + + e1.OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly + e2.OutIdx = Unassigned; + + TEdge e = m_ActiveEdges; + while( e != null ) + { + if( e.OutIdx == ObsoleteIdx ) + { + e.OutIdx = OKIdx; + e.Side = side; + break; + } + e = e.NextInAEL; + } + outRec2.Idx = outRec1.Idx; + } + //------------------------------------------------------------------------------ + + private void ReversePolyPtLinks(OutPt pp) + { + if (pp == null) return; + OutPt pp1; + OutPt pp2; + pp1 = pp; + do + { + pp2 = pp1.Next; + pp1.Next = pp1.Prev; + pp1.Prev = pp2; + pp1 = pp2; + } while (pp1 != pp); + } + //------------------------------------------------------------------------------ + + private static void SwapSides(TEdge edge1, TEdge edge2) + { + EdgeSide side = edge1.Side; + edge1.Side = edge2.Side; + edge2.Side = side; + } + //------------------------------------------------------------------------------ + + private static void SwapPolyIndexes(TEdge edge1, TEdge edge2) + { + int outIdx = edge1.OutIdx; + edge1.OutIdx = edge2.OutIdx; + edge2.OutIdx = outIdx; + } + //------------------------------------------------------------------------------ + + private void IntersectEdges(TEdge e1, TEdge e2, IntPoint pt, bool protect = false) + { + //e1 will be to the left of e2 BELOW the intersection. Therefore e1 is before + //e2 in AEL except when e1 is being inserted at the intersection point ... + + bool e1stops = !protect && e1.NextInLML == null && + e1.Top.X == pt.X && e1.Top.Y == pt.Y; + bool e2stops = !protect && e2.NextInLML == null && + e2.Top.X == pt.X && e2.Top.Y == pt.Y; + bool e1Contributing = (e1.OutIdx >= 0); + bool e2Contributing = (e2.OutIdx >= 0); + +#if use_lines + //if either edge is on an OPEN path ... + if (e1.WindDelta == 0 || e2.WindDelta == 0) + { + //ignore subject-subject open path intersections UNLESS they + //are both open paths, AND they are both 'contributing maximas' ... + if (e1.WindDelta == 0 && e2.WindDelta == 0) + { + if ((e1stops || e2stops) && e1Contributing && e2Contributing) + AddLocalMaxPoly(e1, e2, pt); + } + //if intersecting a subj line with a subj poly ... + else if (e1.PolyTyp == e2.PolyTyp && + e1.WindDelta != e2.WindDelta && m_ClipType == ClipType.ctUnion) + { + if (e1.WindDelta == 0) + { + if (e2Contributing) + { + AddOutPt(e1, pt); + if (e1Contributing) e1.OutIdx = Unassigned; + } + } + else + { + if (e1Contributing) + { + AddOutPt(e2, pt); + if (e2Contributing) e2.OutIdx = Unassigned; + } + } + } + else if (e1.PolyTyp != e2.PolyTyp) + { + if ((e1.WindDelta == 0) && Math.Abs(e2.WindCnt) == 1 && + (m_ClipType != ClipType.ctUnion || e2.WindCnt2 == 0)) + { + AddOutPt(e1, pt); + if (e1Contributing) e1.OutIdx = Unassigned; + } + else if ((e2.WindDelta == 0) && (Math.Abs(e1.WindCnt) == 1) && + (m_ClipType != ClipType.ctUnion || e1.WindCnt2 == 0)) + { + AddOutPt(e2, pt); + if (e2Contributing) e2.OutIdx = Unassigned; + } + } + + if (e1stops) + if (e1.OutIdx < 0) DeleteFromAEL(e1); + else throw new ClipperException("Error intersecting polylines"); + if (e2stops) + if (e2.OutIdx < 0) DeleteFromAEL(e2); + else throw new ClipperException("Error intersecting polylines"); + return; + } +#endif + + //update winding counts... + //assumes that e1 will be to the Right of e2 ABOVE the intersection + if (e1.PolyTyp == e2.PolyTyp) + { + if (IsEvenOddFillType(e1)) + { + int oldE1WindCnt = e1.WindCnt; + e1.WindCnt = e2.WindCnt; + e2.WindCnt = oldE1WindCnt; + } + else + { + if (e1.WindCnt + e2.WindDelta == 0) e1.WindCnt = -e1.WindCnt; + else e1.WindCnt += e2.WindDelta; + if (e2.WindCnt - e1.WindDelta == 0) e2.WindCnt = -e2.WindCnt; + else e2.WindCnt -= e1.WindDelta; + } + } + else + { + if (!IsEvenOddFillType(e2)) e1.WindCnt2 += e2.WindDelta; + else e1.WindCnt2 = (e1.WindCnt2 == 0) ? 1 : 0; + if (!IsEvenOddFillType(e1)) e2.WindCnt2 -= e1.WindDelta; + else e2.WindCnt2 = (e2.WindCnt2 == 0) ? 1 : 0; + } + + PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2; + if (e1.PolyTyp == PolyType.ptSubject) + { + e1FillType = m_SubjFillType; + e1FillType2 = m_ClipFillType; + } + else + { + e1FillType = m_ClipFillType; + e1FillType2 = m_SubjFillType; + } + if (e2.PolyTyp == PolyType.ptSubject) + { + e2FillType = m_SubjFillType; + e2FillType2 = m_ClipFillType; + } + else + { + e2FillType = m_ClipFillType; + e2FillType2 = m_SubjFillType; + } + + int e1Wc, e2Wc; + switch (e1FillType) + { + case PolyFillType.pftPositive: e1Wc = e1.WindCnt; break; + case PolyFillType.pftNegative: e1Wc = -e1.WindCnt; break; + default: e1Wc = Math.Abs(e1.WindCnt); break; + } + switch (e2FillType) + { + case PolyFillType.pftPositive: e2Wc = e2.WindCnt; break; + case PolyFillType.pftNegative: e2Wc = -e2.WindCnt; break; + default: e2Wc = Math.Abs(e2.WindCnt); break; + } + + if (e1Contributing && e2Contributing) + { + if ( e1stops || e2stops || + (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || + (e1.PolyTyp != e2.PolyTyp && m_ClipType != ClipType.ctXor)) + AddLocalMaxPoly(e1, e2, pt); + else + { + AddOutPt(e1, pt); + AddOutPt(e2, pt); + SwapSides(e1, e2); + SwapPolyIndexes(e1, e2); + } + } + else if (e1Contributing) + { + if (e2Wc == 0 || e2Wc == 1) + { + AddOutPt(e1, pt); + SwapSides(e1, e2); + SwapPolyIndexes(e1, e2); + } + + } + else if (e2Contributing) + { + if (e1Wc == 0 || e1Wc == 1) + { + AddOutPt(e2, pt); + SwapSides(e1, e2); + SwapPolyIndexes(e1, e2); + } + } + else if ( (e1Wc == 0 || e1Wc == 1) && + (e2Wc == 0 || e2Wc == 1) && !e1stops && !e2stops ) + { + //neither edge is currently contributing ... + cInt e1Wc2, e2Wc2; + switch (e1FillType2) + { + case PolyFillType.pftPositive: e1Wc2 = e1.WindCnt2; break; + case PolyFillType.pftNegative: e1Wc2 = -e1.WindCnt2; break; + default: e1Wc2 = Math.Abs(e1.WindCnt2); break; + } + switch (e2FillType2) + { + case PolyFillType.pftPositive: e2Wc2 = e2.WindCnt2; break; + case PolyFillType.pftNegative: e2Wc2 = -e2.WindCnt2; break; + default: e2Wc2 = Math.Abs(e2.WindCnt2); break; + } + + if (e1.PolyTyp != e2.PolyTyp) + AddLocalMinPoly(e1, e2, pt); + else if (e1Wc == 1 && e2Wc == 1) + switch (m_ClipType) + { + case ClipType.ctIntersection: + if (e1Wc2 > 0 && e2Wc2 > 0) + AddLocalMinPoly(e1, e2, pt); + break; + case ClipType.ctUnion: + if (e1Wc2 <= 0 && e2Wc2 <= 0) + AddLocalMinPoly(e1, e2, pt); + break; + case ClipType.ctDifference: + if (((e1.PolyTyp == PolyType.ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || + ((e1.PolyTyp == PolyType.ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) + AddLocalMinPoly(e1, e2, pt); + break; + case ClipType.ctXor: + AddLocalMinPoly(e1, e2, pt); + break; + } + else + SwapSides(e1, e2); + } + + if ((e1stops != e2stops) && + ((e1stops && (e1.OutIdx >= 0)) || (e2stops && (e2.OutIdx >= 0)))) + { + SwapSides(e1, e2); + SwapPolyIndexes(e1, e2); + } + + //finally, delete any non-contributing maxima edges ... + if (e1stops) DeleteFromAEL(e1); + if (e2stops) DeleteFromAEL(e2); + } + //------------------------------------------------------------------------------ + + private void DeleteFromAEL(TEdge e) + { + TEdge AelPrev = e.PrevInAEL; + TEdge AelNext = e.NextInAEL; + if (AelPrev == null && AelNext == null && (e != m_ActiveEdges)) + return; //already deleted + if (AelPrev != null) + AelPrev.NextInAEL = AelNext; + else m_ActiveEdges = AelNext; + if (AelNext != null) + AelNext.PrevInAEL = AelPrev; + e.NextInAEL = null; + e.PrevInAEL = null; + } + //------------------------------------------------------------------------------ + + private void DeleteFromSEL(TEdge e) + { + TEdge SelPrev = e.PrevInSEL; + TEdge SelNext = e.NextInSEL; + if (SelPrev == null && SelNext == null && (e != m_SortedEdges)) + return; //already deleted + if (SelPrev != null) + SelPrev.NextInSEL = SelNext; + else m_SortedEdges = SelNext; + if (SelNext != null) + SelNext.PrevInSEL = SelPrev; + e.NextInSEL = null; + e.PrevInSEL = null; + } + //------------------------------------------------------------------------------ + + private void UpdateEdgeIntoAEL(ref TEdge e) + { + if (e.NextInLML == null) + throw new ClipperException("UpdateEdgeIntoAEL: invalid call"); + TEdge AelPrev = e.PrevInAEL; + TEdge AelNext = e.NextInAEL; + e.NextInLML.OutIdx = e.OutIdx; + if (AelPrev != null) + AelPrev.NextInAEL = e.NextInLML; + else m_ActiveEdges = e.NextInLML; + if (AelNext != null) + AelNext.PrevInAEL = e.NextInLML; + e.NextInLML.Side = e.Side; + e.NextInLML.WindDelta = e.WindDelta; + e.NextInLML.WindCnt = e.WindCnt; + e.NextInLML.WindCnt2 = e.WindCnt2; + e = e.NextInLML; + e.Curr = e.Bot; + e.PrevInAEL = AelPrev; + e.NextInAEL = AelNext; + if (!IsHorizontal(e)) InsertScanbeam(e.Top.Y); + } + //------------------------------------------------------------------------------ + + private void ProcessHorizontals(bool isTopOfScanbeam) + { + TEdge horzEdge = m_SortedEdges; + while (horzEdge != null) + { + DeleteFromSEL(horzEdge); + ProcessHorizontal(horzEdge, isTopOfScanbeam); + horzEdge = m_SortedEdges; + } + } + //------------------------------------------------------------------------------ + + void GetHorzDirection(TEdge HorzEdge, out Direction Dir, out cInt Left, out cInt Right) + { + if (HorzEdge.Bot.X < HorzEdge.Top.X) + { + Left = HorzEdge.Bot.X; + Right = HorzEdge.Top.X; + Dir = Direction.dLeftToRight; + } else + { + Left = HorzEdge.Top.X; + Right = HorzEdge.Bot.X; + Dir = Direction.dRightToLeft; + } + } + //------------------------------------------------------------------------ + + void PrepareHorzJoins(TEdge horzEdge, bool isTopOfScanbeam) + { + //get the last Op for this horizontal edge + //the point may be anywhere along the horizontal ... + OutPt outPt = m_PolyOuts[horzEdge.OutIdx].Pts; + if (horzEdge.Side != EdgeSide.esLeft) outPt = outPt.Prev; + + //First, match up overlapping horizontal edges (eg when one polygon's + //intermediate horz edge overlaps an intermediate horz edge of another, or + //when one polygon sits on top of another) ... + for (int i = 0; i < m_GhostJoins.Count; ++i) + { + Join j = m_GhostJoins[i]; + if (HorzSegmentsOverlap(j.OutPt1.Pt, j.OffPt, horzEdge.Bot, horzEdge.Top)) + AddJoin(j.OutPt1, outPt, j.OffPt); + } + //Also, since horizontal edges at the top of one SB are often removed from + //the AEL before we process the horizontal edges at the bottom of the next, + //we need to create 'ghost' Join records of 'contrubuting' horizontals that + //we can compare with horizontals at the bottom of the next SB. + if (isTopOfScanbeam) + if (outPt.Pt == horzEdge.Top) + AddGhostJoin(outPt, horzEdge.Bot); + else + AddGhostJoin(outPt, horzEdge.Top); + } + //------------------------------------------------------------------------------ + + private void ProcessHorizontal(TEdge horzEdge, bool isTopOfScanbeam) + { + Direction dir; + cInt horzLeft, horzRight; + + GetHorzDirection(horzEdge, out dir, out horzLeft, out horzRight); + + TEdge eLastHorz = horzEdge, eMaxPair = null; + while (eLastHorz.NextInLML != null && IsHorizontal(eLastHorz.NextInLML)) + eLastHorz = eLastHorz.NextInLML; + if (eLastHorz.NextInLML == null) + eMaxPair = GetMaximaPair(eLastHorz); + + for (;;) + { + bool IsLastHorz = (horzEdge == eLastHorz); + TEdge e = GetNextInAEL(horzEdge, dir); + while(e != null) + { + //Break if we've got to the end of an intermediate horizontal edge ... + //nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal. + if (e.Curr.X == horzEdge.Top.X && horzEdge.NextInLML != null && + e.Dx < horzEdge.NextInLML.Dx) break; + + TEdge eNext = GetNextInAEL(e, dir); //saves eNext for later + + if ((dir == Direction.dLeftToRight && e.Curr.X <= horzRight) || + (dir == Direction.dRightToLeft && e.Curr.X >= horzLeft)) + { + //so far we're still in range of the horizontal Edge but make sure + //we're at the last of consec. horizontals when matching with eMaxPair + if(e == eMaxPair && IsLastHorz) + { + if (horzEdge.OutIdx >= 0 && horzEdge.WindDelta != 0) + PrepareHorzJoins(horzEdge, isTopOfScanbeam); + if (dir == Direction.dLeftToRight) + IntersectEdges(horzEdge, e, e.Top); + else + IntersectEdges(e, horzEdge, e.Top); + if (eMaxPair.OutIdx >= 0) throw + new ClipperException("ProcessHorizontal error"); + return; + } + else if(dir == Direction.dLeftToRight) + { + IntPoint Pt = new IntPoint(e.Curr.X, horzEdge.Curr.Y); + IntersectEdges(horzEdge, e, Pt, true); + } + else + { + IntPoint Pt = new IntPoint(e.Curr.X, horzEdge.Curr.Y); + IntersectEdges(e, horzEdge, Pt, true); + } + SwapPositionsInAEL(horzEdge, e); + } + else if ((dir == Direction.dLeftToRight && e.Curr.X >= horzRight) || + (dir == Direction.dRightToLeft && e.Curr.X <= horzLeft)) break; + e = eNext; + } //end while + + if (horzEdge.OutIdx >= 0 && horzEdge.WindDelta != 0) + PrepareHorzJoins(horzEdge, isTopOfScanbeam); + + if (horzEdge.NextInLML != null && IsHorizontal(horzEdge.NextInLML)) + { + UpdateEdgeIntoAEL(ref horzEdge); + if (horzEdge.OutIdx >= 0) AddOutPt(horzEdge, horzEdge.Bot); + GetHorzDirection(horzEdge, out dir, out horzLeft, out horzRight); + } else + break; + } //end for (;;) + + if(horzEdge.NextInLML != null) + { + if(horzEdge.OutIdx >= 0) + { + OutPt op1 = AddOutPt( horzEdge, horzEdge.Top); + UpdateEdgeIntoAEL(ref horzEdge); + if (horzEdge.WindDelta == 0) return; + //nb: HorzEdge is no longer horizontal here + TEdge ePrev = horzEdge.PrevInAEL; + TEdge eNext = horzEdge.NextInAEL; + if (ePrev != null && ePrev.Curr.X == horzEdge.Bot.X && + ePrev.Curr.Y == horzEdge.Bot.Y && ePrev.WindDelta != 0 && + (ePrev.OutIdx >= 0 && ePrev.Curr.Y > ePrev.Top.Y && + SlopesEqual(horzEdge, ePrev, m_UseFullRange))) + { + OutPt op2 = AddOutPt(ePrev, horzEdge.Bot); + AddJoin(op1, op2, horzEdge.Top); + } + else if (eNext != null && eNext.Curr.X == horzEdge.Bot.X && + eNext.Curr.Y == horzEdge.Bot.Y && eNext.WindDelta != 0 && + eNext.OutIdx >= 0 && eNext.Curr.Y > eNext.Top.Y && + SlopesEqual(horzEdge, eNext, m_UseFullRange)) + { + OutPt op2 = AddOutPt(eNext, horzEdge.Bot); + AddJoin(op1, op2, horzEdge.Top); + } + } + else + UpdateEdgeIntoAEL(ref horzEdge); + } + else if (eMaxPair != null) + { + if (eMaxPair.OutIdx >= 0) + { + if (dir == Direction.dLeftToRight) + IntersectEdges(horzEdge, eMaxPair, horzEdge.Top); + else + IntersectEdges(eMaxPair, horzEdge, horzEdge.Top); + if (eMaxPair.OutIdx >= 0) throw + new ClipperException("ProcessHorizontal error"); + } else + { + DeleteFromAEL(horzEdge); + DeleteFromAEL(eMaxPair); + } + } else + { + if (horzEdge.OutIdx >= 0) AddOutPt(horzEdge, horzEdge.Top); + DeleteFromAEL(horzEdge); + } + } + //------------------------------------------------------------------------------ + + private TEdge GetNextInAEL(TEdge e, Direction Direction) + { + return Direction == Direction.dLeftToRight ? e.NextInAEL: e.PrevInAEL; + } + //------------------------------------------------------------------------------ + + private bool IsMinima(TEdge e) + { + return e != null && (e.Prev.NextInLML != e) && (e.Next.NextInLML != e); + } + //------------------------------------------------------------------------------ + + private bool IsMaxima(TEdge e, double Y) + { + return (e != null && e.Top.Y == Y && e.NextInLML == null); + } + //------------------------------------------------------------------------------ + + private bool IsIntermediate(TEdge e, double Y) + { + return (e.Top.Y == Y && e.NextInLML != null); + } + //------------------------------------------------------------------------------ + + private TEdge GetMaximaPair(TEdge e) + { + TEdge result = null; + if ((e.Next.Top == e.Top) && e.Next.NextInLML == null) + result = e.Next; + else if ((e.Prev.Top == e.Top) && e.Prev.NextInLML == null) + result = e.Prev; + if (result != null && (result.OutIdx == Skip || + (result.NextInAEL == result.PrevInAEL && !IsHorizontal(result)))) + return null; + return result; + } + //------------------------------------------------------------------------------ + + private bool ProcessIntersections(cInt botY, cInt topY) + { + if( m_ActiveEdges == null ) return true; + try { + BuildIntersectList(botY, topY); + if ( m_IntersectNodes == null) return true; + if (m_IntersectNodes.Next == null || FixupIntersectionOrder()) + ProcessIntersectList(); + else + return false; + } + catch { + m_SortedEdges = null; + DisposeIntersectNodes(); + throw new ClipperException("ProcessIntersections error"); + } + m_SortedEdges = null; + return true; + } + //------------------------------------------------------------------------------ + + private void BuildIntersectList(cInt botY, cInt topY) + { + if ( m_ActiveEdges == null ) return; + + //prepare for sorting ... + TEdge e = m_ActiveEdges; + m_SortedEdges = e; + while( e != null ) + { + e.PrevInSEL = e.PrevInAEL; + e.NextInSEL = e.NextInAEL; + e.Curr.X = TopX( e, topY ); + e = e.NextInAEL; + } + + //bubblesort ... + bool isModified = true; + while( isModified && m_SortedEdges != null ) + { + isModified = false; + e = m_SortedEdges; + while( e.NextInSEL != null ) + { + TEdge eNext = e.NextInSEL; + IntPoint pt; + if (e.Curr.X > eNext.Curr.X) + { + if (!IntersectPoint(e, eNext, out pt) && e.Curr.X > eNext.Curr.X +1) + throw new ClipperException("Intersection error"); + if (pt.Y > botY) + { + pt.Y = botY; + if (Math.Abs(e.Dx) > Math.Abs(eNext.Dx)) + pt.X = TopX(eNext, botY); else + pt.X = TopX(e, botY); + } + InsertIntersectNode(e, eNext, pt); + SwapPositionsInSEL(e, eNext); + isModified = true; + } + else + e = eNext; + } + if( e.PrevInSEL != null ) e.PrevInSEL.NextInSEL = null; + else break; + } + m_SortedEdges = null; + } + //------------------------------------------------------------------------------ + + private bool EdgesAdjacent(IntersectNode inode) + { + return (inode.Edge1.NextInSEL == inode.Edge2) || + (inode.Edge1.PrevInSEL == inode.Edge2); + } + //------------------------------------------------------------------------------ + + private bool FixupIntersectionOrder() + { + //pre-condition: intersections are sorted bottom-most (then left-most) first. + //Now it's crucial that intersections are made only between adjacent edges, + //so to ensure this the order of intersections may need adjusting ... + IntersectNode inode = m_IntersectNodes; + CopyAELToSEL(); + while (inode != null) + { + if (!EdgesAdjacent(inode)) + { + IntersectNode nextNode = inode.Next; + while (nextNode != null && !EdgesAdjacent(nextNode)) + nextNode = nextNode.Next; + if (nextNode == null) + return false; + SwapIntersectNodes(inode, nextNode); + } + SwapPositionsInSEL(inode.Edge1, inode.Edge2); + inode = inode.Next; + } + return true; + } + //------------------------------------------------------------------------------ + + private void ProcessIntersectList() + { + while (m_IntersectNodes != null) + { + IntersectNode iNode = m_IntersectNodes.Next; + { + IntersectEdges( m_IntersectNodes.Edge1 , + m_IntersectNodes.Edge2 , m_IntersectNodes.Pt, true); + SwapPositionsInAEL( m_IntersectNodes.Edge1 , m_IntersectNodes.Edge2 ); + } + m_IntersectNodes = null; + m_IntersectNodes = iNode; + } + } + //------------------------------------------------------------------------------ + + internal static cInt Round(double value) + { + return value < 0 ? (cInt)(value - 0.5) : (cInt)(value + 0.5); + } + //------------------------------------------------------------------------------ + + private static cInt TopX(TEdge edge, cInt currentY) + { + if (currentY == edge.Top.Y) + return edge.Top.X; + return edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y)); + } + //------------------------------------------------------------------------------ + + private void InsertIntersectNode(TEdge e1, TEdge e2, IntPoint pt) + { + IntersectNode newNode = new IntersectNode(); + newNode.Edge1 = e1; + newNode.Edge2 = e2; + newNode.Pt = pt; + newNode.Next = null; + if (m_IntersectNodes == null) m_IntersectNodes = newNode; + else if (newNode.Pt.Y > m_IntersectNodes.Pt.Y) + { + newNode.Next = m_IntersectNodes; + m_IntersectNodes = newNode; + } + else + { + IntersectNode iNode = m_IntersectNodes; + while (iNode.Next != null && newNode.Pt.Y < iNode.Next.Pt.Y) + iNode = iNode.Next; + newNode.Next = iNode.Next; + iNode.Next = newNode; + } + } + //------------------------------------------------------------------------------ + + private void SwapIntersectNodes(IntersectNode int1, IntersectNode int2) + { + TEdge e1 = int1.Edge1; + TEdge e2 = int1.Edge2; + IntPoint p = new IntPoint(int1.Pt); + int1.Edge1 = int2.Edge1; + int1.Edge2 = int2.Edge2; + int1.Pt = int2.Pt; + int2.Edge1 = e1; + int2.Edge2 = e2; + int2.Pt = p; + } + //------------------------------------------------------------------------------ + + private bool IntersectPoint(TEdge edge1, TEdge edge2, out IntPoint ip) + { + ip = new IntPoint(); + double b1, b2; + //nb: with very large coordinate values, it's possible for SlopesEqual() to + //return false but for the edge.Dx value be equal due to double precision rounding. + if (SlopesEqual(edge1, edge2, m_UseFullRange) || edge1.Dx == edge2.Dx) + { + if (edge2.Bot.Y > edge1.Bot.Y) + ip.Y = edge2.Bot.Y; + else + ip.Y = edge1.Bot.Y; + return false; + } + else if (edge1.Delta.X == 0) + { + ip.X = edge1.Bot.X; + if (IsHorizontal(edge2)) + { + ip.Y = edge2.Bot.Y; + } + else + { + b2 = edge2.Bot.Y - (edge2.Bot.X / edge2.Dx); + ip.Y = Round(ip.X / edge2.Dx + b2); + } + } + else if (edge2.Delta.X == 0) + { + ip.X = edge2.Bot.X; + if (IsHorizontal(edge1)) + { + ip.Y = edge1.Bot.Y; + } + else + { + b1 = edge1.Bot.Y - (edge1.Bot.X / edge1.Dx); + ip.Y = Round(ip.X / edge1.Dx + b1); + } + } + else + { + b1 = edge1.Bot.X - edge1.Bot.Y * edge1.Dx; + b2 = edge2.Bot.X - edge2.Bot.Y * edge2.Dx; + double q = (b2 - b1) / (edge1.Dx - edge2.Dx); + ip.Y = Round(q); + if (Math.Abs(edge1.Dx) < Math.Abs(edge2.Dx)) + ip.X = Round(edge1.Dx * q + b1); + else + ip.X = Round(edge2.Dx * q + b2); + } + + if (ip.Y < edge1.Top.Y || ip.Y < edge2.Top.Y) + { + if (edge1.Top.Y > edge2.Top.Y) + { + ip.Y = edge1.Top.Y; + ip.X = TopX(edge2, edge1.Top.Y); + return ip.X < edge1.Top.X; + } + else + { + ip.Y = edge2.Top.Y; + ip.X = TopX(edge1, edge2.Top.Y); + return ip.X > edge2.Top.X; + } + } + else + return true; + } + //------------------------------------------------------------------------------ + + private void DisposeIntersectNodes() + { + while ( m_IntersectNodes != null ) + { + IntersectNode iNode = m_IntersectNodes.Next; + m_IntersectNodes = null; + m_IntersectNodes = iNode; + } + } + //------------------------------------------------------------------------------ + + private void ProcessEdgesAtTopOfScanbeam(cInt topY) + { + TEdge e = m_ActiveEdges; + while(e != null) + { + //1. process maxima, treating them as if they're 'bent' horizontal edges, + // but exclude maxima with horizontal edges. nb: e can't be a horizontal. + bool IsMaximaEdge = IsMaxima(e, topY); + + if(IsMaximaEdge) + { + TEdge eMaxPair = GetMaximaPair(e); + IsMaximaEdge = (eMaxPair == null || !IsHorizontal(eMaxPair)); + } + + if(IsMaximaEdge) + { + TEdge ePrev = e.PrevInAEL; + DoMaxima(e); + if( ePrev == null) e = m_ActiveEdges; + else e = ePrev.NextInAEL; + } + else + { + //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ... + if (IsIntermediate(e, topY) && IsHorizontal(e.NextInLML)) + { + UpdateEdgeIntoAEL(ref e); + if (e.OutIdx >= 0) + AddOutPt(e, e.Bot); + AddEdgeToSEL(e); + } + else + { + e.Curr.X = TopX( e, topY ); + e.Curr.Y = topY; + } + + if (StrictlySimple) + { + TEdge ePrev = e.PrevInAEL; + if ((e.OutIdx >= 0) && (e.WindDelta != 0) && ePrev != null && + (ePrev.OutIdx >= 0) && (ePrev.Curr.X == e.Curr.X) && + (ePrev.WindDelta != 0)) + { + OutPt op = AddOutPt(ePrev, e.Curr); + OutPt op2 = AddOutPt(e, e.Curr); + AddJoin(op, op2, e.Curr); //StrictlySimple (type-3) join + } + } + + e = e.NextInAEL; + } + } + + //3. Process horizontals at the Top of the scanbeam ... + ProcessHorizontals(true); + + //4. Promote intermediate vertices ... + e = m_ActiveEdges; + while (e != null) + { + if(IsIntermediate(e, topY)) + { + OutPt op = null; + if( e.OutIdx >= 0 ) + op = AddOutPt(e, e.Top); + UpdateEdgeIntoAEL(ref e); + + //if output polygons share an edge, they'll need joining later ... + TEdge ePrev = e.PrevInAEL; + TEdge eNext = e.NextInAEL; + if (ePrev != null && ePrev.Curr.X == e.Bot.X && + ePrev.Curr.Y == e.Bot.Y && op != null && + ePrev.OutIdx >= 0 && ePrev.Curr.Y > ePrev.Top.Y && + SlopesEqual(e, ePrev, m_UseFullRange) && + (e.WindDelta != 0) && (ePrev.WindDelta != 0)) + { + OutPt op2 = AddOutPt(ePrev, e.Bot); + AddJoin(op, op2, e.Top); + } + else if (eNext != null && eNext.Curr.X == e.Bot.X && + eNext.Curr.Y == e.Bot.Y && op != null && + eNext.OutIdx >= 0 && eNext.Curr.Y > eNext.Top.Y && + SlopesEqual(e, eNext, m_UseFullRange) && + (e.WindDelta != 0) && (eNext.WindDelta != 0)) + { + OutPt op2 = AddOutPt(eNext, e.Bot); + AddJoin(op, op2, e.Top); + } + } + e = e.NextInAEL; + } + } + //------------------------------------------------------------------------------ + + private void DoMaxima(TEdge e) + { + TEdge eMaxPair = GetMaximaPair(e); + if (eMaxPair == null) + { + if (e.OutIdx >= 0) + AddOutPt(e, e.Top); + DeleteFromAEL(e); + return; + } + + TEdge eNext = e.NextInAEL; + while(eNext != null && eNext != eMaxPair) + { + IntersectEdges(e, eNext, e.Top, true); + SwapPositionsInAEL(e, eNext); + eNext = e.NextInAEL; + } + + if(e.OutIdx == Unassigned && eMaxPair.OutIdx == Unassigned) + { + DeleteFromAEL(e); + DeleteFromAEL(eMaxPair); + } + else if( e.OutIdx >= 0 && eMaxPair.OutIdx >= 0 ) + { + IntersectEdges( e, eMaxPair, e.Top); + } +#if use_lines + else if (e.WindDelta == 0) + { + if (e.OutIdx >= 0) + { + AddOutPt(e, e.Top); + e.OutIdx = Unassigned; + } + DeleteFromAEL(e); + + if (eMaxPair.OutIdx >= 0) + { + AddOutPt(eMaxPair, e.Top); + eMaxPair.OutIdx = Unassigned; + } + DeleteFromAEL(eMaxPair); + } +#endif + else throw new ClipperException("DoMaxima error"); + } + //------------------------------------------------------------------------------ + + public static void ReversePaths(Paths polys) + { + polys.ForEach(delegate(Path poly) { poly.Reverse(); }); + } + //------------------------------------------------------------------------------ + + public static bool Orientation(Path poly) + { + return Area(poly) >= 0; + } + //------------------------------------------------------------------------------ + + private int PointCount(OutPt pts) + { + if (pts == null) return 0; + int result = 0; + OutPt p = pts; + do + { + result++; + p = p.Next; + } + while (p != pts); + return result; + } + //------------------------------------------------------------------------------ + + private void BuildResult(Paths polyg) + { + polyg.Clear(); + polyg.Capacity = m_PolyOuts.Count; + for (int i = 0; i < m_PolyOuts.Count; i++) + { + OutRec outRec = m_PolyOuts[i]; + if (outRec.Pts == null) continue; + OutPt p = outRec.Pts; + int cnt = PointCount(p); + if (cnt < 2) continue; + Path pg = new Path(cnt); + for (int j = 0; j < cnt; j++) + { + pg.Add(p.Pt); + p = p.Prev; + } + polyg.Add(pg); + } + } + //------------------------------------------------------------------------------ + + private void BuildResult2(PolyTree polytree) + { + polytree.Clear(); + + //add each output polygon/contour to polytree ... + polytree.m_AllPolys.Capacity = m_PolyOuts.Count; + for (int i = 0; i < m_PolyOuts.Count; i++) + { + OutRec outRec = m_PolyOuts[i]; + int cnt = PointCount(outRec.Pts); + if ((outRec.IsOpen && cnt < 2) || + (!outRec.IsOpen && cnt < 3)) continue; + FixHoleLinkage(outRec); + PolyNode pn = new PolyNode(); + polytree.m_AllPolys.Add(pn); + outRec.PolyNode = pn; + pn.m_polygon.Capacity = cnt; + OutPt op = outRec.Pts.Prev; + for (int j = 0; j < cnt; j++) + { + pn.m_polygon.Add(op.Pt); + op = op.Prev; + } + } + + //fixup PolyNode links etc ... + polytree.m_Childs.Capacity = m_PolyOuts.Count; + for (int i = 0; i < m_PolyOuts.Count; i++) + { + OutRec outRec = m_PolyOuts[i]; + if (outRec.PolyNode == null) continue; + else if (outRec.IsOpen) + { + outRec.PolyNode.IsOpen = true; + polytree.AddChild(outRec.PolyNode); + } + else if (outRec.FirstLeft != null) + outRec.FirstLeft.PolyNode.AddChild(outRec.PolyNode); + else + polytree.AddChild(outRec.PolyNode); + } + } + //------------------------------------------------------------------------------ + + private void FixupOutPolygon(OutRec outRec) + { + //FixupOutPolygon() - removes duplicate points and simplifies consecutive + //parallel edges by removing the middle vertex. + OutPt lastOK = null; + outRec.BottomPt = null; + OutPt pp = outRec.Pts; + for (;;) + { + if (pp.Prev == pp || pp.Prev == pp.Next) + { + DisposeOutPts(pp); + outRec.Pts = null; + return; + } + //test for duplicate points and collinear edges ... + if ((pp.Pt == pp.Next.Pt) || (pp.Pt == pp.Prev.Pt) || + (SlopesEqual(pp.Prev.Pt, pp.Pt, pp.Next.Pt, m_UseFullRange) && + (!PreserveCollinear || !Pt2IsBetweenPt1AndPt3(pp.Prev.Pt, pp.Pt, pp.Next.Pt)))) + { + lastOK = null; + OutPt tmp = pp; + pp.Prev.Next = pp.Next; + pp.Next.Prev = pp.Prev; + pp = pp.Prev; + tmp = null; + } + else if (pp == lastOK) break; + else + { + if (lastOK == null) lastOK = pp; + pp = pp.Next; + } + } + outRec.Pts = pp; + } + //------------------------------------------------------------------------------ + + OutPt DupOutPt(OutPt outPt, bool InsertAfter) + { + OutPt result = new OutPt(); + result.Pt = outPt.Pt; + result.Idx = outPt.Idx; + if (InsertAfter) + { + result.Next = outPt.Next; + result.Prev = outPt; + outPt.Next.Prev = result; + outPt.Next = result; + } + else + { + result.Prev = outPt.Prev; + result.Next = outPt; + outPt.Prev.Next = result; + outPt.Prev = result; + } + return result; + } + //------------------------------------------------------------------------------ + + bool GetOverlap(cInt a1, cInt a2, cInt b1, cInt b2, out cInt Left, out cInt Right) + { + if (a1 < a2) + { + if (b1 < b2) {Left = Math.Max(a1,b1); Right = Math.Min(a2,b2);} + else {Left = Math.Max(a1,b2); Right = Math.Min(a2,b1);} + } + else + { + if (b1 < b2) {Left = Math.Max(a2,b1); Right = Math.Min(a1,b2);} + else { Left = Math.Max(a2, b2); Right = Math.Min(a1, b1); } + } + return Left < Right; + } + //------------------------------------------------------------------------------ + + bool JoinHorz(OutPt op1, OutPt op1b, OutPt op2, OutPt op2b, + IntPoint Pt, bool DiscardLeft) + { + Direction Dir1 = (op1.Pt.X > op1b.Pt.X ? + Direction.dRightToLeft : Direction.dLeftToRight); + Direction Dir2 = (op2.Pt.X > op2b.Pt.X ? + Direction.dRightToLeft : Direction.dLeftToRight); + if (Dir1 == Dir2) return false; + + //When DiscardLeft, we want Op1b to be on the Left of Op1, otherwise we + //want Op1b to be on the Right. (And likewise with Op2 and Op2b.) + //So, to facilitate this while inserting Op1b and Op2b ... + //when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b, + //otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.) + if (Dir1 == Direction.dLeftToRight) + { + while (op1.Next.Pt.X <= Pt.X && + op1.Next.Pt.X >= op1.Pt.X && op1.Next.Pt.Y == Pt.Y) + op1 = op1.Next; + if (DiscardLeft && (op1.Pt.X != Pt.X)) op1 = op1.Next; + op1b = DupOutPt(op1, !DiscardLeft); + if (op1b.Pt != Pt) + { + op1 = op1b; + op1.Pt = Pt; + op1b = DupOutPt(op1, !DiscardLeft); + } + } + else + { + while (op1.Next.Pt.X >= Pt.X && + op1.Next.Pt.X <= op1.Pt.X && op1.Next.Pt.Y == Pt.Y) + op1 = op1.Next; + if (!DiscardLeft && (op1.Pt.X != Pt.X)) op1 = op1.Next; + op1b = DupOutPt(op1, DiscardLeft); + if (op1b.Pt != Pt) + { + op1 = op1b; + op1.Pt = Pt; + op1b = DupOutPt(op1, DiscardLeft); + } + } + + if (Dir2 == Direction.dLeftToRight) + { + while (op2.Next.Pt.X <= Pt.X && + op2.Next.Pt.X >= op2.Pt.X && op2.Next.Pt.Y == Pt.Y) + op2 = op2.Next; + if (DiscardLeft && (op2.Pt.X != Pt.X)) op2 = op2.Next; + op2b = DupOutPt(op2, !DiscardLeft); + if (op2b.Pt != Pt) + { + op2 = op2b; + op2.Pt = Pt; + op2b = DupOutPt(op2, !DiscardLeft); + }; + } else + { + while (op2.Next.Pt.X >= Pt.X && + op2.Next.Pt.X <= op2.Pt.X && op2.Next.Pt.Y == Pt.Y) + op2 = op2.Next; + if (!DiscardLeft && (op2.Pt.X != Pt.X)) op2 = op2.Next; + op2b = DupOutPt(op2, DiscardLeft); + if (op2b.Pt != Pt) + { + op2 = op2b; + op2.Pt = Pt; + op2b = DupOutPt(op2, DiscardLeft); + }; + }; + + if ((Dir1 == Direction.dLeftToRight) == DiscardLeft) + { + op1.Prev = op2; + op2.Next = op1; + op1b.Next = op2b; + op2b.Prev = op1b; + } + else + { + op1.Next = op2; + op2.Prev = op1; + op1b.Prev = op2b; + op2b.Next = op1b; + } + return true; + } + //------------------------------------------------------------------------------ + + private bool JoinPoints(Join j, out OutPt p1, out OutPt p2) + { + OutRec outRec1 = GetOutRec(j.OutPt1.Idx); + OutRec outRec2 = GetOutRec(j.OutPt2.Idx); + OutPt op1 = j.OutPt1, op1b; + OutPt op2 = j.OutPt2, op2b; + p1 = null; p2 = null; + + //There are 3 kinds of joins for output polygons ... + //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are a vertices anywhere + //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal). + //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same + //location at the Bottom of the overlapping segment (& Join.OffPt is above). + //3. StrictlySimple joins where edges touch but are not collinear and where + //Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point. + bool isHorizontal = (j.OutPt1.Pt.Y == j.OffPt.Y); + + if (isHorizontal && (j.OffPt == j.OutPt1.Pt) && (j.OffPt == j.OutPt2.Pt)) + { + //Strictly Simple join ... + op1b = j.OutPt1.Next; + while (op1b != op1 && (op1b.Pt == j.OffPt)) + op1b = op1b.Next; + bool reverse1 = (op1b.Pt.Y > j.OffPt.Y); + op2b = j.OutPt2.Next; + while (op2b != op2 && (op2b.Pt == j.OffPt)) + op2b = op2b.Next; + bool reverse2 = (op2b.Pt.Y > j.OffPt.Y); + if (reverse1 == reverse2) return false; + if (reverse1) + { + op1b = DupOutPt(op1, false); + op2b = DupOutPt(op2, true); + op1.Prev = op2; + op2.Next = op1; + op1b.Next = op2b; + op2b.Prev = op1b; + p1 = op1; + p2 = op1b; + return true; + } else + { + op1b = DupOutPt(op1, true); + op2b = DupOutPt(op2, false); + op1.Next = op2; + op2.Prev = op1; + op1b.Prev = op2b; + op2b.Next = op1b; + p1 = op1; + p2 = op1b; + return true; + } + } + else if (isHorizontal) + { + //treat horizontal joins differently to non-horizontal joins since with + //them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt + //may be anywhere along the horizontal edge. + op1b = op1; + while (op1.Prev.Pt.Y == op1.Pt.Y && op1.Prev != op1b && op1.Prev != op2) + op1 = op1.Prev; + while (op1b.Next.Pt.Y == op1b.Pt.Y && op1b.Next != op1 && op1b.Next != op2) + op1b = op1b.Next; + if (op1b.Next == op1 || op1b.Next == op2) return false; //a flat 'polygon' + + op2b = op2; + while (op2.Prev.Pt.Y == op2.Pt.Y && op2.Prev != op2b && op2.Prev != op1b) + op2 = op2.Prev; + while (op2b.Next.Pt.Y == op2b.Pt.Y && op2b.Next != op2 && op2b.Next != op1) + op2b = op2b.Next; + if (op2b.Next == op2 || op2b.Next == op1) return false; //a flat 'polygon' + + cInt Left, Right; + //Op1 -. Op1b & Op2 -. Op2b are the extremites of the horizontal edges + if (!GetOverlap(op1.Pt.X, op1b.Pt.X, op2.Pt.X, op2b.Pt.X, out Left, out Right)) + return false; + + //DiscardLeftSide: when overlapping edges are joined, a spike will created + //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up + //on the discard Side as either may still be needed for other joins ... + IntPoint Pt; + bool DiscardLeftSide; + if (op1.Pt.X >= Left && op1.Pt.X <= Right) + { + Pt = op1.Pt; DiscardLeftSide = (op1.Pt.X > op1b.Pt.X); + } + else if (op2.Pt.X >= Left&& op2.Pt.X <= Right) + { + Pt = op2.Pt; DiscardLeftSide = (op2.Pt.X > op2b.Pt.X); + } + else if (op1b.Pt.X >= Left && op1b.Pt.X <= Right) + { + Pt = op1b.Pt; DiscardLeftSide = op1b.Pt.X > op1.Pt.X; + } + else + { + Pt = op2b.Pt; DiscardLeftSide = (op2b.Pt.X > op2.Pt.X); + } + p1 = op1; p2 = op2; + return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide); + } else + { + //nb: For non-horizontal joins ... + // 1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y + // 2. Jr.OutPt1.Pt > Jr.OffPt.Y + + //make sure the polygons are correctly oriented ... + op1b = op1.Next; + while ((op1b.Pt == op1.Pt) && (op1b != op1)) op1b = op1b.Next; + bool Reverse1 = ((op1b.Pt.Y > op1.Pt.Y) || + !SlopesEqual(op1.Pt, op1b.Pt, j.OffPt, m_UseFullRange)); + if (Reverse1) + { + op1b = op1.Prev; + while ((op1b.Pt == op1.Pt) && (op1b != op1)) op1b = op1b.Prev; + if ((op1b.Pt.Y > op1.Pt.Y) || + !SlopesEqual(op1.Pt, op1b.Pt, j.OffPt, m_UseFullRange)) return false; + }; + op2b = op2.Next; + while ((op2b.Pt == op2.Pt) && (op2b != op2)) op2b = op2b.Next; + bool Reverse2 = ((op2b.Pt.Y > op2.Pt.Y) || + !SlopesEqual(op2.Pt, op2b.Pt, j.OffPt, m_UseFullRange)); + if (Reverse2) + { + op2b = op2.Prev; + while ((op2b.Pt == op2.Pt) && (op2b != op2)) op2b = op2b.Prev; + if ((op2b.Pt.Y > op2.Pt.Y) || + !SlopesEqual(op2.Pt, op2b.Pt, j.OffPt, m_UseFullRange)) return false; + } + + if ((op1b == op1) || (op2b == op2) || (op1b == op2b) || + ((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false; + + if (Reverse1) + { + op1b = DupOutPt(op1, false); + op2b = DupOutPt(op2, true); + op1.Prev = op2; + op2.Next = op1; + op1b.Next = op2b; + op2b.Prev = op1b; + p1 = op1; + p2 = op1b; + return true; + } else + { + op1b = DupOutPt(op1, true); + op2b = DupOutPt(op2, false); + op1.Next = op2; + op2.Prev = op1; + op1b.Prev = op2b; + op2b.Next = op1b; + p1 = op1; + p2 = op1b; + return true; + } + } + } + //---------------------------------------------------------------------- + + + private bool Poly2ContainsPoly1(OutPt outPt1, OutPt outPt2, bool UseFullRange) + { + OutPt pt = outPt1; + + //Because the polygons may be touching, we need to find a vertex that + //isn't touching the other polygon ... + if (PointOnPolygon(pt.Pt, outPt2, UseFullRange)) + { + pt = pt.Next; + while (pt != outPt1 && PointOnPolygon(pt.Pt, outPt2, UseFullRange)) + pt = pt.Next; + if (pt == outPt1) return true; + } + return PointInPolygon(pt.Pt, outPt2, UseFullRange); + } + //---------------------------------------------------------------------- + + private void FixupFirstLefts1(OutRec OldOutRec, OutRec NewOutRec) + { + for (int i = 0; i < m_PolyOuts.Count; i++) + { + OutRec outRec = m_PolyOuts[i]; + if (outRec.Pts != null && outRec.FirstLeft == OldOutRec) + { + if (Poly2ContainsPoly1(outRec.Pts, NewOutRec.Pts, m_UseFullRange)) + outRec.FirstLeft = NewOutRec; + } + } + } + //---------------------------------------------------------------------- + + private void FixupFirstLefts2(OutRec OldOutRec, OutRec NewOutRec) + { + foreach (OutRec outRec in m_PolyOuts) + if (outRec.FirstLeft == OldOutRec) outRec.FirstLeft = NewOutRec; + } + //---------------------------------------------------------------------- + + private void JoinCommonEdges() + { + for (int i = 0; i < m_Joins.Count; i++) + { + Join j = m_Joins[i]; + + OutRec outRec1 = GetOutRec(j.OutPt1.Idx); + OutRec outRec2 = GetOutRec(j.OutPt2.Idx); + + if (outRec1.Pts == null || outRec2.Pts == null) continue; + + //get the polygon fragment with the correct hole state (FirstLeft) + //before calling JoinPoints() ... + OutRec holeStateRec; + if (outRec1 == outRec2) holeStateRec = outRec1; + else if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2; + else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1; + else holeStateRec = GetLowermostRec(outRec1, outRec2); + + OutPt p1, p2; + if (!JoinPoints(j, out p1, out p2)) continue; + + if (outRec1 == outRec2) + { + //instead of joining two polygons, we've just created a new one by + //splitting one polygon into two. + outRec1.Pts = p1; + outRec1.BottomPt = null; + outRec2 = CreateOutRec(); + outRec2.Pts = p2; + + //update all OutRec2.Pts Idx's ... + UpdateOutPtIdxs(outRec2); + + if (Poly2ContainsPoly1(outRec2.Pts, outRec1.Pts, m_UseFullRange)) + { + //outRec2 is contained by outRec1 ... + outRec2.IsHole = !outRec1.IsHole; + outRec2.FirstLeft = outRec1; + + //fixup FirstLeft pointers that may need reassigning to OutRec1 + if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); + + if ((outRec2.IsHole ^ ReverseSolution) == (Area(outRec2) > 0)) + ReversePolyPtLinks(outRec2.Pts); + + } + else if (Poly2ContainsPoly1(outRec1.Pts, outRec2.Pts, m_UseFullRange)) + { + //outRec1 is contained by outRec2 ... + outRec2.IsHole = outRec1.IsHole; + outRec1.IsHole = !outRec2.IsHole; + outRec2.FirstLeft = outRec1.FirstLeft; + outRec1.FirstLeft = outRec2; + + //fixup FirstLeft pointers that may need reassigning to OutRec1 + if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2); + + if ((outRec1.IsHole ^ ReverseSolution) == (Area(outRec1) > 0)) + ReversePolyPtLinks(outRec1.Pts); + } + else + { + //the 2 polygons are completely separate ... + outRec2.IsHole = outRec1.IsHole; + outRec2.FirstLeft = outRec1.FirstLeft; + + //fixup FirstLeft pointers that may need reassigning to OutRec2 + if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2); + } + + } else + { + //joined 2 polygons together ... + + outRec2.Pts = null; + outRec2.BottomPt = null; + outRec2.Idx = outRec1.Idx; + + outRec1.IsHole = holeStateRec.IsHole; + if (holeStateRec == outRec2) + outRec1.FirstLeft = outRec2.FirstLeft; + outRec2.FirstLeft = outRec1; + + //fixup FirstLeft pointers that may need reassigning to OutRec1 + if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); + } + } + } + //------------------------------------------------------------------------------ + + private void UpdateOutPtIdxs(OutRec outrec) + { + OutPt op = outrec.Pts; + do + { + op.Idx = outrec.Idx; + op = op.Prev; + } + while(op != outrec.Pts); + } + //------------------------------------------------------------------------------ + + private void DoSimplePolygons() + { + int i = 0; + while (i < m_PolyOuts.Count) + { + OutRec outrec = m_PolyOuts[i++]; + OutPt op = outrec.Pts; + if (op == null) continue; + do //for each Pt in Polygon until duplicate found do ... + { + OutPt op2 = op.Next; + while (op2 != outrec.Pts) + { + if ((op.Pt == op2.Pt) && op2.Next != op && op2.Prev != op) + { + //split the polygon into two ... + OutPt op3 = op.Prev; + OutPt op4 = op2.Prev; + op.Prev = op4; + op4.Next = op; + op2.Prev = op3; + op3.Next = op2; + + outrec.Pts = op; + OutRec outrec2 = CreateOutRec(); + outrec2.Pts = op2; + UpdateOutPtIdxs(outrec2); + if (Poly2ContainsPoly1(outrec2.Pts, outrec.Pts, m_UseFullRange)) + { + //OutRec2 is contained by OutRec1 ... + outrec2.IsHole = !outrec.IsHole; + outrec2.FirstLeft = outrec; + } + else + if (Poly2ContainsPoly1(outrec.Pts, outrec2.Pts, m_UseFullRange)) + { + //OutRec1 is contained by OutRec2 ... + outrec2.IsHole = outrec.IsHole; + outrec.IsHole = !outrec2.IsHole; + outrec2.FirstLeft = outrec.FirstLeft; + outrec.FirstLeft = outrec2; + } else + { + //the 2 polygons are separate ... + outrec2.IsHole = outrec.IsHole; + outrec2.FirstLeft = outrec.FirstLeft; + } + op2 = op; //ie get ready for the next iteration + } + op2 = op2.Next; + } + op = op.Next; + } + while (op != outrec.Pts); + } + } + //------------------------------------------------------------------------------ + + public static double Area(Path poly) + { + int highI = poly.Count - 1; + if (highI < 2) return 0; + double area = ((double)poly[highI].X + poly[0].X) * ((double)poly[0].Y - poly[highI].Y); + for (int i = 1; i <= highI; ++i) + area += ((double)poly[i - 1].X + poly[i].X) * ((double)poly[i].Y - poly[i -1].Y); + return area / 2; + } + //------------------------------------------------------------------------------ + + double Area(OutRec outRec) + { + OutPt op = outRec.Pts; + if (op == null) return 0; + double a = 0; + do { + a = a + (double)(op.Pt.X + op.Prev.Pt.X) * (double)(op.Prev.Pt.Y - op.Pt.Y); + op = op.Next; + } while (op != outRec.Pts); + return a/2; + } + + //------------------------------------------------------------------------------ + // OffsetPolygon functions ... + //------------------------------------------------------------------------------ + + internal static DoublePoint GetUnitNormal(IntPoint pt1, IntPoint pt2) + { + double dx = (pt2.X - pt1.X); + double dy = (pt2.Y - pt1.Y); + if ((dx == 0) && (dy == 0)) return new DoublePoint(); + + double f = 1 * 1.0 / Math.Sqrt(dx * dx + dy * dy); + dx *= f; + dy *= f; + + return new DoublePoint(dy, -dx); + } + //------------------------------------------------------------------------------ + + private class PolyOffsetBuilder + { + private Paths m_p; + private Path currentPoly; + private List normals = new List(); + private double m_delta, m_sinA, m_sin, m_cos; + private double m_miterLim, m_Steps360; + private int m_i, m_j, m_k; + private const int m_buffLength = 128; + + void OffsetPoint(JoinType jointype) + { + m_sinA = (normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y); + if (m_sinA < 0.00005 && m_sinA > -0.00005) return; + else if (m_sinA > 1.0) m_sinA = 1.0; + else if (m_sinA < -1.0) m_sinA = -1.0; + + if (m_sinA * m_delta < 0) + { + AddPoint(new IntPoint(Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), + Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta))); + AddPoint(m_p[m_i][m_j]); + AddPoint(new IntPoint(Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), + Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta))); + } + else + switch (jointype) + { + case JoinType.jtMiter: + { + double r = 1 + (normals[m_j].X * normals[m_k].X + + normals[m_j].Y * normals[m_k].Y); + if (r >= m_miterLim) DoMiter(r); else DoSquare(); + break; + } + case JoinType.jtSquare: DoSquare(); break; + case JoinType.jtRound: DoRound(); break; + } + m_k = m_j; + } + //------------------------------------------------------------------------------ + + public PolyOffsetBuilder(Paths pts, out Paths solution, double delta, + JoinType jointype, EndType endtype, double limit = 0) + { + //precondition: solution != pts + solution = new Paths(); + if (ClipperBase.near_zero(delta)) {solution = pts; return; } + m_p = pts; + if (endtype != EndType.etClosed && delta < 0) delta = -delta; + m_delta = delta; + + if (jointype == JoinType.jtMiter) + { + //m_miterVal: see offset_triginometry.svg in the documentation folder ... + if (limit > 2) m_miterLim = 2 / (limit * limit); + else m_miterLim = 0.5; + if (endtype == EndType.etRound) limit = 0.25; + } + if (jointype == JoinType.jtRound || endtype == EndType.etRound) + { + if (limit <= 0) limit = 0.25; + else if (limit > Math.Abs(delta)*0.25) limit = Math.Abs(delta)*0.25; + //m_roundVal: see offset_triginometry2.svg in the documentation folder ... + m_Steps360 = Math.PI / Math.Acos(1 - limit / Math.Abs(delta)); + m_sin = Math.Sin(2 * Math.PI / m_Steps360); + m_cos = Math.Cos(2 * Math.PI / m_Steps360); + m_Steps360 /= Math.PI * 2; + if (delta < 0) m_sin = -m_sin; + } + + double deltaSq = delta * delta; + solution.Capacity = pts.Count; + for (m_i = 0; m_i < pts.Count; m_i++) + { + int len = pts[m_i].Count; + if (len == 0 || (len < 3 && delta <= 0)) continue; + + if (len == 1) + { + if (jointype == JoinType.jtRound) + { + double X = 1.0, Y = 0.0; + for (cInt j = 1; j <= Round(m_Steps360 * 2 * Math.PI); j++) + { + AddPoint(new IntPoint( + Round(m_p[m_i][0].X + X * delta), + Round(m_p[m_i][0].Y + Y * delta))); + double X2 = X; + X = X * m_cos - m_sin * Y; + Y = X2 * m_sin + Y * m_cos; + } + } + else + { + double X = -1.0, Y = -1.0; + for (int j = 0; j < 4; ++j) + { + AddPoint(new IntPoint(Round(m_p[m_i][0].X + X * delta), + Round(m_p[m_i][0].Y + Y * delta))); + if (X < 0) X = 1; + else if (Y < 0) Y = 1; + else X = -1; + } + } + continue; + } + + //build normals ... + normals.Clear(); + normals.Capacity = len; + for (int j = 0; j < len -1; ++j) + normals.Add(GetUnitNormal(pts[m_i][j], pts[m_i][j+1])); + if (endtype == EndType.etClosed) + normals.Add(GetUnitNormal(pts[m_i][len - 1], pts[m_i][0])); + else + normals.Add(new DoublePoint(normals[len - 2])); + + currentPoly = new Path(); + if (endtype == EndType.etClosed) + { + m_k = len - 1; + for (m_j = 0; m_j < len; ++m_j) + OffsetPoint(jointype); + solution.Add(currentPoly); + } + else + { + m_k = 0; + for (m_j = 1; m_j < len - 1; ++m_j) + OffsetPoint(jointype); + + IntPoint pt1; + if (endtype == EndType.etButt) + { + m_j = len - 1; + pt1 = new IntPoint((cInt)Round(pts[m_i][m_j].X + normals[m_j].X * + delta), (cInt)Round(pts[m_i][m_j].Y + normals[m_j].Y * delta)); + AddPoint(pt1); + pt1 = new IntPoint((cInt)Round(pts[m_i][m_j].X - normals[m_j].X * + delta), (cInt)Round(pts[m_i][m_j].Y - normals[m_j].Y * delta)); + AddPoint(pt1); + } + else + { + m_j = len - 1; + m_k = len - 2; + m_sinA = 0; + normals[m_j] = new DoublePoint(-normals[m_j].X, -normals[m_j].Y); + if (endtype == EndType.etSquare) + DoSquare(); + else + DoRound(); + } + + //re-build Normals ... + for (int j = len - 1; j > 0; j--) + normals[j] = new DoublePoint(-normals[j - 1].X, -normals[j - 1].Y); + + normals[0] = new DoublePoint(-normals[1].X, -normals[1].Y); + + m_k = len - 1; + for (m_j = m_k - 1; m_j > 0; --m_j) + OffsetPoint(jointype); + + if (endtype == EndType.etButt) + { + pt1 = new IntPoint((cInt)Round(pts[m_i][0].X - normals[0].X * delta), + (cInt)Round(pts[m_i][0].Y - normals[0].Y * delta)); + AddPoint(pt1); + pt1 = new IntPoint((cInt)Round(pts[m_i][0].X + normals[0].X * delta), + (cInt)Round(pts[m_i][0].Y + normals[0].Y * delta)); + AddPoint(pt1); + } + else + { + m_k = 1; + m_sinA = 0; + if (endtype == EndType.etSquare) + DoSquare(); + else + DoRound(); + } + solution.Add(currentPoly); + } + } + + //finally, clean up untidy corners ... + Clipper clpr = new Clipper(); + clpr.AddPaths(solution, PolyType.ptSubject, true); + if (delta > 0) + { + clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive); + } + else + { + IntRect r = clpr.GetBounds(); + Path outer = new Path(4); + + outer.Add(new IntPoint(r.left - 10, r.bottom + 10)); + outer.Add(new IntPoint(r.right + 10, r.bottom + 10)); + outer.Add(new IntPoint(r.right + 10, r.top - 10)); + outer.Add(new IntPoint(r.left - 10, r.top - 10)); + + clpr.AddPath(outer, PolyType.ptSubject, true); + clpr.ReverseSolution = true; + clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative); + if (solution.Count > 0) solution.RemoveAt(0); + } + } + //------------------------------------------------------------------------------ + + internal void AddPoint(IntPoint pt) + { + if (currentPoly.Count == currentPoly.Capacity) + currentPoly.Capacity += m_buffLength; + currentPoly.Add(pt); + } + //------------------------------------------------------------------------------ + + internal void DoSquare() + { + double dx = Math.Tan(Math.Atan2(m_sinA, + normals[m_k].X * normals[m_j].X + normals[m_k].Y * normals[m_j].Y)/4); + AddPoint(new IntPoint( + Round(m_p[m_i][m_j].X + m_delta * (normals[m_k].X - normals[m_k].Y *dx)), + Round(m_p[m_i][m_j].Y + m_delta * (normals[m_k].Y + normals[m_k].X *dx)))); + AddPoint(new IntPoint( + Round(m_p[m_i][m_j].X + m_delta * (normals[m_j].X + normals[m_j].Y *dx)), + Round(m_p[m_i][m_j].Y + m_delta * (normals[m_j].Y - normals[m_j].X *dx)))); + } + //------------------------------------------------------------------------------ + + internal void DoMiter(double r) + { + double q = m_delta / r; + AddPoint(new IntPoint(Round(m_p[m_i][m_j].X + (normals[m_k].X + normals[m_j].X) * q), + Round(m_p[m_i][m_j].Y + (normals[m_k].Y + normals[m_j].Y) * q))); + } + //------------------------------------------------------------------------------ + + internal void DoRound() + { + double a = Math.Atan2(m_sinA, + normals[m_k].X * normals[m_j].X + normals[m_k].Y * normals[m_j].Y); + int steps = (int)Round(m_Steps360 * Math.Abs(a)); + + double X = normals[m_k].X, Y = normals[m_k].Y, X2; + for (int i = 0; i < steps; ++i) + { + AddPoint(new IntPoint( + Round(m_p[m_i][m_j].X + X * m_delta), + Round(m_p[m_i][m_j].Y + Y * m_delta))); + X2 = X; + X = X * m_cos - m_sin * Y; + Y = X2 * m_sin + Y * m_cos; + } + AddPoint(new IntPoint( + Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), + Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta))); + } + //------------------------------------------------------------------------------ + + } //end PolyOffsetBuilder + //------------------------------------------------------------------------------ + + internal static bool UpdateBotPt(IntPoint pt, ref IntPoint botPt) + { + if (pt.Y > botPt.Y || (pt.Y == botPt.Y && pt.X < botPt.X)) + { + botPt = pt; + return true; + } + else return false; + } + //------------------------------------------------------------------------------ + + internal static bool StripDupsAndGetBotPt(Path in_path, + Path out_path, bool closed, out IntPoint botPt) + { + botPt = new IntPoint(0, 0); + int len = in_path.Count; + if (closed) + while (len > 0 && (in_path[0] == in_path[len -1])) len--; + if (len == 0) return false; + out_path.Capacity = len; + int j = 0; + out_path.Add(in_path[0]); + botPt = in_path[0]; + for (int i = 1; i < len; ++i) + if (in_path[i] != out_path[j]) + { + out_path.Add(in_path[i]); + j++; + if (out_path[j].Y > botPt.Y || + ((out_path[j].Y == botPt.Y) && out_path[j].X < botPt.X)) + botPt = out_path[j]; + } + j++; + if (j < 2 || (closed && (j == 2))) j = 0; + while (out_path.Count > j) out_path.RemoveAt(j); + return j > 0; + } + //------------------------------------------------------------------------------ + + public static Paths OffsetPaths(Paths polys, double delta, + JoinType jointype, EndType endtype, double MiterLimit) + { + Paths out_polys = new Paths(polys.Count); + IntPoint botPt = new IntPoint(); + IntPoint pt; + int botIdx = -1; + for (int i = 0; i < polys.Count; ++i) + { + out_polys.Add(new Path()); + if (StripDupsAndGetBotPt(polys[i], out_polys[i], endtype == EndType.etClosed, out pt)) + if (botIdx < 0 || pt.Y > botPt.Y || (pt.Y == botPt.Y && pt.X < botPt.X)) + { + botPt = pt; + botIdx = i; + } + } + if (endtype == EndType.etClosed && botIdx >= 0 && !Orientation(out_polys[botIdx])) + ReversePaths(out_polys); + + Paths result; + new PolyOffsetBuilder(out_polys, out result, delta, jointype, endtype, MiterLimit); + return result; + } + //------------------------------------------------------------------------------ + +#if use_deprecated + public static Paths OffsetPolygons(Paths poly, double delta, + JoinType jointype, double MiterLimit, bool AutoFix) + { + return OffsetPaths(poly, delta, jointype, EndType.etClosed, MiterLimit); + } + //------------------------------------------------------------------------------ + + public static Paths OffsetPolygons(Paths poly, double delta, + JoinType jointype, double MiterLimit) + { + return OffsetPaths(poly, delta, jointype, EndType.etClosed, MiterLimit); + } + //------------------------------------------------------------------------------ + + public static Paths OffsetPolygons(Polygons polys, double delta, JoinType jointype) + { + return OffsetPaths(polys, delta, jointype, EndType.etClosed, 0); + } + //------------------------------------------------------------------------------ + + public static Paths OffsetPolygons(Polygons polys, double delta) + { + return OffsetPolygons(polys, delta, JoinType.jtSquare, 0, true); + } + //------------------------------------------------------------------------------ + + public static void ReversePolygons(Polygons polys) + { + polys.ForEach(delegate(Path poly) { poly.Reverse(); }); + } + //------------------------------------------------------------------------------ + + public static void PolyTreeToPolygons(PolyTree polytree, Polygons polys) + { + polys.Clear(); + polys.Capacity = polytree.Total; + AddPolyNodeToPaths(polytree, NodeType.ntAny, polys); + } + //------------------------------------------------------------------------------ +#endif + + //------------------------------------------------------------------------------ + // SimplifyPolygon functions ... + // Convert self-intersecting polygons into simple polygons + //------------------------------------------------------------------------------ + + public static Paths SimplifyPolygon(Path poly, + PolyFillType fillType = PolyFillType.pftEvenOdd) + { + Paths result = new Paths(); + Clipper c = new Clipper(); + c.StrictlySimple = true; + c.AddPath(poly, PolyType.ptSubject, true); + c.Execute(ClipType.ctUnion, result, fillType, fillType); + return result; + } + //------------------------------------------------------------------------------ + + public static Paths SimplifyPolygons(Paths polys, + PolyFillType fillType = PolyFillType.pftEvenOdd) + { + Paths result = new Paths(); + Clipper c = new Clipper(); + c.StrictlySimple = true; + c.AddPaths(polys, PolyType.ptSubject, true); + c.Execute(ClipType.ctUnion, result, fillType, fillType); + return result; + } + //------------------------------------------------------------------------------ + + private static double DistanceSqrd(IntPoint pt1, IntPoint pt2) + { + double dx = ((double)pt1.X - pt2.X); + double dy = ((double)pt1.Y - pt2.Y); + return (dx*dx + dy*dy); + } + //------------------------------------------------------------------------------ + + private static DoublePoint ClosestPointOnLine(IntPoint pt, IntPoint linePt1, IntPoint linePt2) + { + double dx = ((double)linePt2.X - linePt1.X); + double dy = ((double)linePt2.Y - linePt1.Y); + if (dx == 0 && dy == 0) + return new DoublePoint(linePt1.X, linePt1.Y); + double q = ((pt.X-linePt1.X)*dx + (pt.Y-linePt1.Y)*dy) / (dx*dx + dy*dy); + return new DoublePoint( + (1-q)*linePt1.X + q*linePt2.X, + (1-q)*linePt1.Y + q*linePt2.Y); + } + //------------------------------------------------------------------------------ + + private static bool SlopesNearCollinear(IntPoint pt1, + IntPoint pt2, IntPoint pt3, double distSqrd) + { + if (DistanceSqrd(pt1, pt2) > DistanceSqrd(pt1, pt3)) return false; + DoublePoint cpol = ClosestPointOnLine(pt2, pt1, pt3); + double dx = pt2.X - cpol.X; + double dy = pt2.Y - cpol.Y; + return (dx*dx + dy*dy) < distSqrd; + } + //------------------------------------------------------------------------------ + + private static bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd) + { + double dx = (double)pt1.X - pt2.X; + double dy = (double)pt1.Y - pt2.Y; + return ((dx * dx) + (dy * dy) <= distSqrd); + } + //------------------------------------------------------------------------------ + + public static Path CleanPolygon(Path path, + double distance = 1.415) + { + //distance = proximity in units/pixels below which vertices + //will be stripped. Default ~= sqrt(2) so when adjacent + //vertices have both x & y coords within 1 unit, then + //the second vertex will be stripped. + double distSqrd = (distance * distance); + int highI = path.Count -1; + Path result = new Path(highI + 1); + while (highI > 0 && PointsAreClose(path[highI], path[0], distSqrd)) highI--; + if (highI < 2) return result; + IntPoint pt = path[highI]; + int i = 0; + for (;;) + { + while (i < highI && PointsAreClose(pt, path[i], distSqrd)) i+=2; + int i2 = i; + while (i < highI && (PointsAreClose(path[i], path[i + 1], distSqrd) || + SlopesNearCollinear(pt, path[i], path[i + 1], distSqrd))) i++; + if (i >= highI) break; + else if (i != i2) continue; + pt = path[i++]; + result.Add(pt); + } + if (i <= highI) result.Add(path[i]); + i = result.Count; + if (i > 2 && SlopesNearCollinear(result[i - 2], result[i - 1], result[0], distSqrd)) + result.RemoveAt(i -1); + if (result.Count < 3) result.Clear(); + return result; + } + //------------------------------------------------------------------------------ + + internal static Paths Minkowki(Path poly, Path path, bool IsSum, bool IsClosed) + { + int delta = (IsClosed ? 1 : 0); + int polyCnt = poly.Count; + int pathCnt = path.Count; + Paths result = new Paths(pathCnt); + if (IsSum) + for (int i = 0; i < pathCnt; i++) + { + Path p = new Path(polyCnt); + foreach (IntPoint ip in poly) + p.Add(new IntPoint(path[i].X + ip.X, path[i].Y + ip.Y)); + result.Add(p); + } + else + for (int i = 0; i < pathCnt; i++) + { + Path p = new Path(polyCnt); + foreach (IntPoint ip in poly) + p.Add(new IntPoint(path[i].X - ip.X, path[i].Y - ip.Y)); + result.Add(p); + } + + Paths quads = new Paths((pathCnt + delta) * (polyCnt + 1)); + for (int i = 0; i <= pathCnt - 2 + delta; i++) + for (int j = 0; j <= polyCnt - 1; j++) + { + Path quad = new Path(4); + quad.Add(result[i % pathCnt][j % polyCnt]); + quad.Add(result[(i + 1) % pathCnt][j % polyCnt]); + quad.Add(result[(i + 1) % pathCnt][(j + 1) % polyCnt]); + quad.Add(result[i % pathCnt][(j + 1) % polyCnt]); + if (!Orientation(quad)) quad.Reverse(); + quads.Add(quad); + } + + Clipper c = new Clipper(); + c.AddPaths(quads, PolyType.ptSubject, true); + c.Execute(ClipType.ctUnion, result, PolyFillType.pftNonZero, PolyFillType.pftNonZero); + return result; + } + //------------------------------------------------------------------------------ + + public static Paths MinkowkiSum(Path poly, Path path, bool IsClosed) + { + return Minkowki(poly, path, true, IsClosed); + } + //------------------------------------------------------------------------------ + + public static Paths MinkowkiDiff(Path poly, Path path, bool IsClosed) + { + return Minkowki(poly, path, false, IsClosed); + } + //------------------------------------------------------------------------------ + + public static Paths CleanPolygons(Paths polys, + double distance = 1.415) + { + Paths result = new Paths(polys.Count); + for (int i = 0; i < polys.Count; i++) + result.Add(CleanPolygon(polys[i], distance)); + return result; + } + //------------------------------------------------------------------------------ + + internal enum NodeType { ntAny, ntOpen, ntClosed }; + + public static Paths PolyTreeToPaths(PolyTree polytree) + { + + Paths result = new Paths(); + result.Capacity = polytree.Total; + AddPolyNodeToPaths(polytree, NodeType.ntAny, result); + return result; + } + //------------------------------------------------------------------------------ + + internal static void AddPolyNodeToPaths(PolyNode polynode, NodeType nt, Paths paths) + { + bool match = true; + switch (nt) + { + case NodeType.ntOpen: return; + case NodeType.ntClosed: match = !polynode.IsOpen; break; + default: break; + } + + if (polynode.Contour.Count > 0 && match) + paths.Add(polynode.Contour); + foreach (PolyNode pn in polynode.Childs) + AddPolyNodeToPaths(pn, nt, paths); + } + //------------------------------------------------------------------------------ + + public static Paths OpenPathsFromPolyTree(PolyTree polytree) + { + Paths result = new Paths(); + result.Capacity = polytree.ChildCount; + for (int i = 0; i < polytree.ChildCount; i++) + if (polytree.Childs[i].IsOpen) + result.Add(polytree.Childs[i].Contour); + return result; + } + //------------------------------------------------------------------------------ + + public static Paths ClosedPathsFromPolyTree(PolyTree polytree) + { + Paths result = new Paths(); + result.Capacity = polytree.Total; + AddPolyNodeToPaths(polytree, NodeType.ntClosed, result); + return result; + } + //------------------------------------------------------------------------------ + + } //end Clipper + + class ClipperException : Exception + { + public ClipperException(string description) : base(description){} + } + //------------------------------------------------------------------------------ + +} //end ClipperLib namespace diff --git a/Delphi/agg demo/about_agg.txt b/Delphi/agg demo/about_agg.txt deleted file mode 100644 index 1e231cb..0000000 --- a/Delphi/agg demo/about_agg.txt +++ /dev/null @@ -1 +0,0 @@ -http://www.antigrain.com/ \ No newline at end of file diff --git a/Delphi/agg demo/agg_conv_clipper.pas b/Delphi/agg demo/agg_conv_clipper.pas deleted file mode 100644 index e983339..0000000 --- a/Delphi/agg demo/agg_conv_clipper.pas +++ /dev/null @@ -1,343 +0,0 @@ -(******************************************************************************* -* * -* Author : Angus Johnson * -* Version : 1.2 * -* Date : 29 September 2011 * -* Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2011 * -* * -* License: * -* Use, modification & distribution is subject to Boost Software License Ver 1. * -* http://www.boost.org/LICENSE_1_0.txt * -* * -*******************************************************************************) - -unit - agg_conv_clipper ; - -interface - -{$I agg_mode.inc } - -uses - types, - math, - agg_basics , - agg_array , - agg_vertex_source , - clipper; - -type - clipper_op_e = ( - clipper_or , - clipper_and , - clipper_xor , - clipper_a_minus_b , - clipper_b_minus_a - ); - - clipper_polyFillType = ( - clipper_evenOdd, - clipper_nonZero, - clipper_positive, - clipper_negative - ); - - status = (status_move_to, status_line_to, status_stop ); - - conv_clipper_ptr = ^conv_clipper; - conv_clipper = object(vertex_source) - m_src_a , - m_src_b : vertex_source_ptr; - - m_status : status; - m_vertex , - m_contour : int; - m_operation : clipper_op_e; - - m_scaling_factor: int; - - m_subjFillType, - m_clipFillType: clipper_polyFillType; - - m_poly_a , - m_poly_b , - m_result : TPolygons; - - m_vertex_accumulator: pod_deque; - clipper: TClipper; - - constructor Construct(a, b : vertex_source_ptr; - op : clipper_op_e = clipper_or; - subjFillType: clipper_polyFillType = clipper_evenOdd; - clipFillType: clipper_polyFillType = clipper_evenOdd; - scaling_factor: integer = 2); //default scaling == 2 decimal places - - destructor Destruct; virtual; - - procedure set_source1(source : vertex_source_ptr; - subjFillType: clipper_polyFillType = clipper_evenOdd); - procedure set_source2(source : vertex_source_ptr; - clipFillType: clipper_polyFillType = clipper_evenOdd); - - procedure operation(v : clipper_op_e ); - - // Vertex Source Interface - procedure rewind(path_id : unsigned ); virtual; - function vertex(x ,y : double_ptr ) : unsigned; virtual; - - function next_contour : boolean; - function next_vertex(x ,y : double_ptr ) : boolean; - procedure start_extracting; - procedure start_contour; - procedure add_vertex_ (x,y: double ); - procedure end_contour(var p: TPolygons); - procedure add(src : vertex_source_ptr; var p: TPolygons); - end; - -implementation - -function pft(cpft: clipper_polyFillType): TPolyFillType; -begin - case cpft of - clipper_evenOdd: result := pftEvenOdd; - clipper_nonZero: result := pftNonZero; - clipper_positive: result := pftPositive; - else {clipper_negative: } result := pftNegative; - end; -end; - -constructor conv_clipper.Construct(a, b: vertex_source_ptr; - op: clipper_op_e = clipper_or; - subjFillType: clipper_polyFillType = clipper_evenOdd; - clipFillType: clipper_polyFillType = clipper_evenOdd; - scaling_factor: integer = 2); //default scaling == 2 decimal places -begin - m_src_a := a; - m_src_b := b; - m_operation := op; - - m_scaling_factor := max(min(scaling_factor, 6),0); - m_scaling_factor := round(power(10, m_scaling_factor)); - - m_status := status_move_to; - m_vertex := -1; - m_contour := -1; - - m_poly_a := nil; - m_poly_b := nil; - m_result := nil; - m_vertex_accumulator.Construct (sizeof(TIntPoint), 8 ); - - m_subjFillType := subjFillType; - m_clipFillType := clipFillType; - clipper := TClipper.Create; -end; -//------------------------------------------------------------------------------ - -destructor conv_clipper.Destruct; -begin - clipper.Free; - m_vertex_accumulator.Destruct; -end; -//------------------------------------------------------------------------------ - -procedure conv_clipper.set_source1(source : vertex_source_ptr; - subjFillType: clipper_polyFillType = clipper_evenOdd); -begin - m_src_a := source; - m_subjFillType := subjFillType; -end; -//------------------------------------------------------------------------------ - -procedure conv_clipper.set_source2(source : vertex_source_ptr; - clipFillType: clipper_polyFillType = clipper_evenOdd); -begin - m_src_b := source; - m_clipFillType := clipFillType; -end; -//------------------------------------------------------------------------------ - -procedure conv_clipper.operation(v : clipper_op_e ); -begin - m_operation := v; -end; -//------------------------------------------------------------------------------ - -procedure conv_clipper.start_extracting; -begin - m_status := status_move_to; - m_contour := -1; - m_vertex := -1; -end; -//------------------------------------------------------------------------------ - -procedure conv_clipper.rewind(path_id : unsigned ); -begin - m_src_a.rewind(path_id ); - m_src_b.rewind(path_id ); - - add(m_src_a, m_poly_a ); - add(m_src_b, m_poly_b ); - m_result := nil; - - with clipper do - begin - clear; - case m_operation of - clipper_or : - begin - AddPolygons(m_poly_a, ptSubject); - AddPolygons(m_poly_b, ptClip); - Execute(ctUnion, m_result, pft(m_subjFillType), pft(m_clipFillType)); - end; - clipper_and : - begin - AddPolygons(m_poly_a, ptSubject); - AddPolygons(m_poly_b, ptClip); - Execute(ctIntersection, m_result, pft(m_subjFillType), pft(m_clipFillType)); - end; - clipper_xor : - begin - AddPolygons(m_poly_a, ptSubject); - AddPolygons(m_poly_b, ptClip); - Execute(ctXor, m_result, pft(m_subjFillType), pft(m_clipFillType)); - end; - clipper_a_minus_b : - begin - AddPolygons(m_poly_a, ptSubject); - AddPolygons(m_poly_b, ptClip); - Execute(ctDifference, m_result, pft(m_subjFillType), pft(m_clipFillType)); - end; - clipper_b_minus_a : - begin - AddPolygons(m_poly_b, ptSubject); - AddPolygons(m_poly_a, ptClip); - Execute(ctDifference, m_result, pft(m_subjFillType), pft(m_clipFillType)); - end; - end; - end; - start_extracting; -end; -//------------------------------------------------------------------------------ - -procedure conv_clipper.start_contour; -begin - m_vertex_accumulator.remove_all; -end; -//------------------------------------------------------------------------------ - -procedure conv_clipper.end_contour(var p: TPolygons); -var - i, len: integer; -begin - if m_vertex_accumulator.size < 3 then exit; - len := length(p); - setLength(p, len+1); - setLength(p[len], m_vertex_accumulator.size); - for i := 0 to m_vertex_accumulator.size -1 do - p[len][i] := PIntPoint(m_vertex_accumulator.array_operator(i))^; -end; -//------------------------------------------------------------------------------ - -procedure conv_clipper.add_vertex_ (x,y: double); -var - v : TIntPoint; -begin - v.x := round(x * m_scaling_factor); - v.y := round(y * m_scaling_factor); - m_vertex_accumulator.add(@v); -end; -//------------------------------------------------------------------------------ - -function conv_clipper.next_contour; -begin - result:=false; - inc(m_contour ); - if m_contour >= length(m_result) then exit; - m_vertex:=-1; - result:=true; -end; -//------------------------------------------------------------------------------ - -function conv_clipper.next_vertex(x ,y : double_ptr ) : boolean; -begin - result:=false; - inc(m_vertex); - if m_vertex >= length(m_result[m_contour]) then exit; - x^ := m_result[m_contour][m_vertex].X / m_scaling_factor; - y^ := m_result[m_contour][m_vertex].Y / m_scaling_factor; - result := true; -end; -//------------------------------------------------------------------------------ - -function conv_clipper.vertex(x ,y : double_ptr ) : unsigned; -begin - if m_status = status_move_to then - begin - if next_contour then - begin - if next_vertex(x ,y ) then - begin - m_status:=status_line_to; - result := path_cmd_move_to; - end else - begin - m_status := status_stop; - result := path_cmd_end_poly or path_flags_close; - end; - end else - result := path_cmd_stop; - end else - begin - if next_vertex(x ,y ) then - begin - result := path_cmd_line_to; - end else - begin - m_status := status_move_to; - result := path_cmd_end_poly or path_flags_close; - end; - end; -end; -//------------------------------------------------------------------------------ - -procedure conv_clipper.add(src : vertex_source_ptr; var p: TPolygons); -var - cmd: unsigned; - x, y, start_x ,start_y: double; - starting_first_line : boolean; -begin - start_x := 0.0; - start_y := 0.0; - starting_first_line := true; - p := nil; - - cmd := src.vertex(@x, @y ); - while not is_stop(cmd) do - begin - if is_vertex(cmd) then - begin - if is_move_to(cmd ) then - begin - if not starting_first_line then end_contour(p); - start_contour; - start_x := x; - start_y := y; - end; - add_vertex_(x ,y ); - starting_first_line := false; - end - else if is_end_poly(cmd ) then - begin - if not starting_first_line and is_closed(cmd ) then - add_vertex_(start_x ,start_y ); - end; - cmd := src.vertex(@x ,@y ); - end; - end_contour(p); -end; -//------------------------------------------------------------------------------ - -end. - diff --git a/Delphi/agg demo/clipper_test.dpr b/Delphi/agg demo/clipper_test.dpr deleted file mode 100644 index ee60a42..0000000 --- a/Delphi/agg demo/clipper_test.dpr +++ /dev/null @@ -1,975 +0,0 @@ -{target:win} -// -// AggPas 2.4 RM3 Demo application -// Note: Press F1 key on run to see more info about this demo -// -// Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap -// -program - clipper_test ; - -uses - SysUtils , - - agg_basics , - agg_platform_support , - - agg_color , - agg_pixfmt , - agg_pixfmt_rgb , - - agg_ctrl , - agg_slider_ctrl , - agg_cbox_ctrl , - agg_rbox_ctrl , - - agg_rendering_buffer , - agg_renderer_base , - agg_renderer_scanline , - agg_renderer_primitives , - agg_rasterizer_scanline_aa , - agg_scanline , - agg_scanline_u , - agg_scanline_p , - agg_render_scanlines , - - agg_math_stroke , - agg_path_storage , - agg_span_solid , - agg_conv_curve , - agg_conv_stroke , - agg_conv_transform , - agg_conv_clip_polygon , - agg_gsv_text , - agg_trans_affine , - agg_vertex_source , - - make_gb_poly_ , - make_arrows_, - - agg_conv_clipper, - clipper in '../clipper.pas'; - -{$I agg_mode.inc } - -const - flip_y = true; - -type - spiral = object(vertex_source ) - m_x , - m_y , - m_r1 , - m_r2 , - m_step , - - m_start_angle , - - m_angle , - m_curr_r , - m_da , - m_dr : double; - m_start : boolean; - - constructor Construct(x ,y ,r1 ,r2 ,step : double; start_angle : double = 0 ); - - procedure rewind(path_id : unsigned ); virtual; - function vertex(x ,y : double_ptr ) : unsigned; virtual; - - end; - - conv_poly_counter = object(vertex_source ) - m_src : vertex_source_ptr; - - m_contours , - m_points : unsigned; - - constructor Construct(src : vertex_source_ptr ); - - procedure rewind(path_id : unsigned ); virtual; - function vertex(x ,y : double_ptr ) : unsigned; virtual; - - end; - - the_application = object(platform_support ) - m_polygons , - m_operation : rbox_ctrl; - - m_x , - m_y : double; - - constructor Construct(format_ : pix_format_e; flip_y_ : boolean ); - destructor Destruct; - - procedure perform_rendering( - sl : scanline_ptr; - ras : rasterizer_scanline_ptr; - ren : renderer_scanline_ptr; - clipper : conv_clipper_ptr ); - - function render_clipper(sl : scanline_ptr; ras : rasterizer_scanline_ptr ) : unsigned; - - procedure on_init; virtual; - procedure on_draw; virtual; - - procedure on_mouse_move (x ,y : int; flags : unsigned ); virtual; - procedure on_mouse_button_down(x ,y : int; flags : unsigned ); virtual; - - procedure on_key(x ,y : int; key ,flags : unsigned ); virtual; - - procedure stress_test; - - end; - -{ CONSTRUCT } -constructor spiral.Construct; -begin - m_x :=x; - m_y :=y; - m_r1:=r1; - m_r2:=r2; - - m_step :=step; - m_start_angle:=start_angle; - m_angle :=start_angle; - - m_da:=deg2rad(4.0 ); - m_dr:=m_step / 90.0; - -end; - -{ REWIND } -procedure spiral.rewind; -begin - m_angle :=m_start_angle; - m_curr_r:=m_r1; - m_start :=true; - -end; - -{ VERTEX } -function spiral.vertex; -begin - if m_curr_r > m_r2 then - begin - result:=path_cmd_stop; - - exit; - - end; - - x^:=m_x + Cos(m_angle ) * m_curr_r; - y^:=m_y + Sin(m_angle ) * m_curr_r; - - m_curr_r:=m_curr_r + m_dr; - m_angle :=m_angle + m_da; - - if m_start then - begin - m_start:=false; - - result:=path_cmd_move_to; - - end - else - result:=path_cmd_line_to; - -end; - -{ CONSTRUCT } -constructor conv_poly_counter.Construct; -begin - m_src:=src; - - m_contours:=0; - m_points :=0; - -end; - -{ REWIND } -procedure conv_poly_counter.rewind; -begin - m_contours:=0; - m_points :=0; - - m_src.rewind(path_id ); - -end; - -{ VERTEX } -function conv_poly_counter.vertex; -var - cmd : unsigned; - -begin - cmd:=m_src.vertex(x ,y ); - - if is_vertex(cmd ) then - inc(m_points ); - - if is_move_to(cmd ) then - inc(m_contours ); - - result:=cmd; - -end; - -{ CONSTRUCT } -constructor the_application.Construct; -begin - inherited Construct(format_ ,flip_y_ ); - - m_polygons.Construct (5.0 ,5.0 ,5.0 + 205.0 ,110.0 ,not flip_y_ ); - m_operation.Construct(555.0 ,5.0 ,555.0 + 80.0 ,130.0 ,not flip_y_ ); - - m_operation.add_item ('None' ); - m_operation.add_item ('OR' ); - m_operation.add_item ('AND' ); - m_operation.add_item ('XOR' ); - m_operation.add_item ('A-B' ); - m_operation.add_item ('B-A' ); - m_operation.cur_item_(2 ); - - add_ctrl(@m_operation ); - - m_polygons.add_item ('Two Simple Paths' ); - m_polygons.add_item ('Closed Stroke' ); - m_polygons.add_item ('Great Britain and Arrows' ); - m_polygons.add_item ('Great Britain and Spiral' ); - m_polygons.add_item ('Spiral and Glyph' ); - m_polygons.cur_item_(3 ); - - add_ctrl(@m_polygons ); - -end; - -{ DESTRUCT } -destructor the_application.Destruct; -begin - inherited Destruct; - - m_polygons.Destruct; - m_operation.Destruct; - -end; - -{ PERFORM_RENDERING } -procedure the_application.perform_rendering; -var - counter : conv_poly_counter; - - t1 ,t2 ,x ,y : double; - - cmd : unsigned; - buf : array[0..99 ] of char8; - - rgba : aggclr; - txt : gsv_text; - - txt_stroke : conv_stroke; - -begin - if m_operation._cur_item > 0 then - begin - // Render clipped polygon - ras.reset; - - case m_operation._cur_item of - 1: clipper.operation(clipper_or ); - 2: clipper.operation(clipper_and ); - 3: clipper.operation(clipper_xor ); - 4: clipper.operation(clipper_a_minus_b ); - 5: clipper.operation(clipper_b_minus_a ); - - end; - - counter.Construct(clipper); - - start_timer; - counter.rewind(0); /////////////////////////this is where it all happens! - t1:=elapsed_time; - - ras.reset; - start_timer; - - cmd:=counter.vertex(@x ,@y ); - - while not is_stop(cmd ) do - begin - ras.add_vertex(x ,y ,cmd ); - - cmd:=counter.vertex(@x ,@y ); - - end; - rgba.ConstrDbl (0.5 ,0.75 ,0.5 ,1.0 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,ren ); - - t2:=elapsed_time; - - // Render information text - sprintf(@buf[0 ] ,'Contours: %d ' ,counter.m_contours ); - sprintf(@buf[StrLen(@buf ) ] ,'Points: %d' ,counter.m_points ); - - txt.Construct; - txt_stroke.Construct(@txt ); - - txt_stroke.width_ (1.5 ); - txt_stroke.line_cap_(round_cap ); - txt.size_ (10.0 ); - txt.start_point_ (250 ,5 ); - txt.text_ (@buf[0 ] ); - - ras.add_path (@txt_stroke ); - rgba.ConstrDbl (0.0 ,0.0 ,0.0 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,ren ); - - sprintf(@buf[0 ] ,'Clipper=%.3fms ' ,t1 ); - sprintf(@buf[StrLen(buf ) ] ,'Render=%.3fms' ,t2 ); - - txt.start_point_(250 ,20 ); - txt.text_ (@buf[0 ] ); - - ras.add_path (@txt_stroke ); - rgba.ConstrDbl (0.0 ,0.0 ,0.0 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,ren ); - - // Free - txt.Destruct; - txt_stroke.Destruct; - - end; - -end; - -{ RENDER_CLIPPER } -function the_application.render_clipper; -var - pf : pixel_formats; - rb : renderer_base; - - ren : renderer_scanline_aa_solid; - ps1 , - ps2 , - - gb_poly , - arrows , - glyph : path_storage; - - rgba : aggclr; - x ,y : double; - - mtx1 , - mtx2 , - mtx : trans_affine; - tat : trans_affine_translation; - tas : trans_affine_scaling; - - stroke, - stroke_stroke, - stroke_gb_poly : conv_stroke; - - trans , - trans_gb_poly , - trans_arrows : conv_transform; - - curve : conv_curve; - - sp : spiral; - clipper : conv_clipper; - -begin - pixfmt_bgr24(pf ,rbuf_window ); - - rb.Construct (@pf ); - ren.Construct(@rb ); - - case m_polygons._cur_item of - 0 : // Two simple paths - begin - ps1.Construct; - ps2.Construct; - - clipper.Construct(@ps1, @ps2, clipper_or, - clipper_nonZero, clipper_nonZero); - - x:=m_x - _initial_width / 2 + 100; - y:=m_y - _initial_height / 2 + 100; - - ps1.move_to(x + 140 ,y + 145 ); - ps1.line_to(x + 225 ,y + 44 ); - //ps1.line_to(x + 296 ,y + 219 ); - ps1.line_to(x + 396 ,y + 319 ); - ps1.close_polygon; - - ps1.line_to(x + 226 ,y + 289 ); - ps1.line_to(x + 82 ,y + 292 ); - - ps1.move_to(x + 220 ,y + 222 ); - ps1.line_to(x + 363 ,y + 249 ); - ps1.line_to(x + 265 ,y + 331 ); - - ps1.move_to(x + 242 ,y + 243 ); - ps1.line_to(x + 268 ,y + 309 ); - ps1.line_to(x + 325 ,y + 261 ); - - ps1.move_to(x + 259 ,y + 259 ); - ps1.line_to(x + 273 ,y + 288 ); - ps1.line_to(x + 298 ,y + 266 ); - - ps2.move_to(100 + 32 ,100 + 77 ); - ps2.line_to(100 + 473 ,100 + 263 ); - ps2.line_to(100 + 351 ,100 + 290 ); - ps2.line_to(100 + 354 ,100 + 374 ); - - ras.reset; - ras.add_path (@ps1 ); - rgba.ConstrDbl (0 ,0 ,0 ,0.1 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,@ren ); - - ras.reset; - ras.add_path (@ps2 ); - rgba.ConstrDbl (0.5 ,0.5 ,0 ,0.1 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,@ren ); - - perform_rendering(sl ,ras ,@ren ,@clipper ); - - ps1.Destruct; - ps2.Destruct; - clipper.Destruct; - - end; - - 1 : // Closed stroke - begin - ps1.Construct; - ps2.Construct; - stroke.Construct(@ps2 ); - stroke.width_ (10.0 ); - - clipper.Construct(@ps1 ,@stroke, clipper_or, - clipper_nonZero, clipper_nonZero); - - x:=m_x - _initial_width / 2 + 100; - y:=m_y - _initial_height / 2 + 100; - - ps1.move_to(x + 140 ,y + 145 ); - ps1.line_to(x + 225 ,y + 44 ); - ps1.line_to(x + 296 ,y + 219 ); - ps1.close_polygon; - - ps1.line_to(x + 226 ,y + 289 ); - ps1.line_to(x + 82 ,y + 292 ); - - ps1.move_to(x + 220 - 50 ,y + 222 ); - ps1.line_to(x + 265 - 50 ,y + 331 ); - ps1.line_to(x + 363 - 50 ,y + 249 ); - ps1.close_polygon(path_flags_ccw ); - - ps2.move_to(100 + 32 ,100 + 77 ); - ps2.line_to(100 + 473 ,100 + 263 ); - ps2.line_to(100 + 351 ,100 + 290 ); - ps2.line_to(100 + 354 ,100 + 374 ); - ps2.close_polygon; - - ras.reset; - ras.add_path (@ps1 ); - rgba.ConstrDbl (0 ,0 ,0 ,0.1 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,@ren ); - - ras.reset; - ras.add_path (@stroke ); - rgba.ConstrDbl (0.5 ,0.5 ,0 ,0.1 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,@ren ); - - perform_rendering(sl ,ras ,@ren ,@clipper ); - - ps1.Destruct; - ps2.Destruct; - stroke.Destruct; - clipper.Destruct; - - end; - - 2 : // Great Britain and Arrows - begin - gb_poly.Construct; - arrows.Construct; - - make_gb_poly(@gb_poly ); - make_arrows (@arrows ); - - mtx1.Construct; - mtx2.Construct; - tat.Construct(-1150 ,-1150 ); - tas.Construct(2.0 ); - mtx1.multiply(@tat ); - mtx1.multiply(@tas ); - - mtx2:=mtx1; - - tat.Construct(m_x - _initial_width / 2 ,m_y - _initial_height / 2 ); - - mtx2.multiply(@tat ); - - trans_gb_poly.Construct(@gb_poly ,@mtx1 ); - trans_arrows.Construct (@arrows ,@mtx2 ); - - clipper.Construct(@trans_gb_poly ,@trans_arrows, - clipper_or, clipper_nonZero, clipper_nonZero); - - ras.add_path (@trans_gb_poly ); - rgba.ConstrDbl (0.5 ,0.5 ,0 ,0.1 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,@ren ); - - stroke_gb_poly.Construct(@trans_gb_poly ); - stroke_gb_poly.width_ (0.1); - ras.add_path (@stroke_gb_poly ); - rgba.ConstrDbl (0 ,0 ,0 ); - ren.color_ (@rgba ); - render_scanlines (ras ,sl ,@ren ); - - ras.add_path (@trans_arrows ); - rgba.ConstrDbl (0.0 ,0.5 ,0.5 ,0.1 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,@ren ); - - perform_rendering(sl ,ras ,@ren ,@clipper ); - - gb_poly.Destruct; - arrows.Destruct; - stroke_gb_poly.Destruct; - clipper.Destruct; - - end; - - 3 : // Great Britain and a Spiral - begin - sp.Construct (m_x ,m_y ,10 ,150 ,30 ,0.0 ); - stroke.Construct(@sp ); - stroke.width_ (15.0 ); - - gb_poly.Construct; - make_gb_poly(@gb_poly ); - - mtx.Construct; - tat.Construct(-1150 ,-1150 ); - tas.Construct(2.0 ); - mtx.multiply(@tat ); - mtx.multiply(@tas ); - - trans_gb_poly.Construct(@gb_poly ,@mtx ); - - clipper.Construct(@trans_gb_poly ,@stroke, - clipper_or, clipper_nonZero, clipper_nonZero); - - ras.add_path (@trans_gb_poly ); - rgba.ConstrDbl (0.5 ,0.5 ,0 ,0.1 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,@ren ); - - stroke_gb_poly.Construct(@trans_gb_poly ); - stroke_gb_poly.width_ (0.2 ); - ras.add_path (@stroke_gb_poly ); - rgba.ConstrDbl (0 ,0 ,0 ); - ren.color_ (@rgba ); - render_scanlines (ras ,sl ,@ren ); - - ras.add_path (@stroke ); - rgba.ConstrDbl (0.0 ,0.5 ,0.5 ,0.1 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,@ren ); - - stroke_stroke.Construct(@stroke); - stroke_stroke.width_(0.1); - ras.add_path(@stroke_stroke ); - rgba.ConstrDbl (0 ,0 ,0 ); - ren.color_ (@rgba ); - render_scanlines (ras ,sl ,@ren ); - - perform_rendering(sl ,ras ,@ren ,@clipper ); - - stroke.Destruct; - stroke_stroke.Destruct; - gb_poly.Destruct; - stroke_gb_poly.Destruct; - clipper.Destruct; - - end; - - 4 : // Spiral and glyph - begin - sp.Construct (m_x ,m_y ,10 ,150 ,30 ,0.0 ); - stroke.Construct(@sp ); - stroke.width_ (15.0 ); - - glyph.Construct; - glyph.move_to(28.47 ,6.45 ); - glyph.curve3 (21.58 ,1.12 ,19.82 ,0.29 ); - glyph.curve3 (17.19 ,-0.93 ,14.21 ,-0.93 ); - glyph.curve3 (9.57 ,-0.93 ,6.57 ,2.25 ); - glyph.curve3 (3.56 ,5.42 ,3.56 ,10.60 ); - glyph.curve3 (3.56 ,13.87 ,5.03 ,16.26 ); - glyph.curve3 (7.03 ,19.58 ,11.99 ,22.51 ); - glyph.curve3 (16.94 ,25.44 ,28.47 ,29.64 ); - glyph.line_to(28.47 ,31.40 ); - glyph.curve3 (28.47 ,38.09 ,26.34 ,40.58 ); - glyph.curve3 (24.22 ,43.07 ,20.17 ,43.07 ); - glyph.curve3 (17.09 ,43.07 ,15.28 ,41.41 ); - glyph.curve3 (13.43 ,39.75 ,13.43 ,37.60 ); - glyph.line_to(13.53 ,34.77 ); - glyph.curve3 (13.53 ,32.52 ,12.38 ,31.30 ); - glyph.curve3 (11.23 ,30.08 ,9.38 ,30.08 ); - glyph.curve3 (7.57 ,30.08 ,6.42 ,31.35 ); - glyph.curve3 (5.27 ,32.62 ,5.27 ,34.81 ); - glyph.curve3 (5.27 ,39.01 ,9.57 ,42.53 ); - glyph.curve3 (13.87 ,46.04 ,21.63 ,46.04 ); - glyph.curve3 (27.59 ,46.04 ,31.40 ,44.04 ); - glyph.curve3 (34.28 ,42.53 ,35.64 ,39.31 ); - glyph.curve3 (36.52 ,37.21 ,36.52 ,30.71 ); - glyph.line_to(36.52 ,15.53 ); - glyph.curve3 (36.52 ,9.13 ,36.77 ,7.69 ); - glyph.curve3 (37.01 ,6.25 ,37.57 ,5.76 ); - glyph.curve3 (38.13 ,5.27 ,38.87 ,5.27 ); - glyph.curve3 (39.65 ,5.27 ,40.23 ,5.62 ); - glyph.curve3 (41.26 ,6.25 ,44.19 ,9.18 ); - glyph.line_to(44.19 ,6.45 ); - glyph.curve3 (38.72 ,-0.88 ,33.74 ,-0.88 ); - glyph.curve3 (31.35 ,-0.88 ,29.93 ,0.78 ); - glyph.curve3 (28.52 ,2.44 ,28.47 ,6.45 ); - glyph.close_polygon; - - glyph.move_to(28.47 ,9.62 ); - glyph.line_to(28.47 ,26.66 ); - glyph.curve3 (21.09 ,23.73 ,18.95 ,22.51 ); - glyph.curve3 (15.09 ,20.36 ,13.43 ,18.02 ); - glyph.curve3 (11.77 ,15.67 ,11.77 ,12.89 ); - glyph.curve3 (11.77 ,9.38 ,13.87 ,7.06 ); - glyph.curve3 (15.97 ,4.74 ,18.70 ,4.74 ); - glyph.curve3 (22.41 ,4.74 ,28.47 ,9.62 ); - glyph.close_polygon; - - mtx.Construct; - tas.Construct(4.0 ); - tat.Construct(220 ,200 ); - mtx.multiply(@tas ); - mtx.multiply(@tat ); - - trans.Construct(@glyph ,@mtx ); - curve.Construct(@trans ); - - clipper.Construct(@stroke ,@curve, clipper_or, - clipper_nonZero, clipper_nonZero); - - ras.reset; - ras.add_path (@stroke ); - rgba.ConstrDbl (0 ,0 ,0 ,0.1 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,@ren ); - - ras.reset; - ras.add_path (@curve ); - rgba.ConstrDbl (0.5 ,0.5 ,0 ,0.1 ); - ren.color_ (@rgba ); - render_scanlines(ras ,sl ,@ren ); - - perform_rendering(sl ,ras ,@ren ,@clipper ); - - stroke.Destruct; - glyph.Destruct; - curve.Destruct; - clipper.Destruct; - - end; - - end; - - result:=0; - -end; - -{ ON_INIT } -procedure the_application.on_init; -begin - m_x:=_width / 2.0; - m_y:=_height / 2.0; - -end; - -{ ON_DRAW } -procedure the_application.on_draw; -var - pf : pixel_formats; - - rgba : aggclr; - - ren_base : renderer_base; - ren_solid : renderer_scanline_aa_solid; - - sl : scanline_u8; - ras : rasterizer_scanline_aa; - -begin -// Initialize structures - pixfmt_bgr24(pf ,rbuf_window ); - - ren_base.Construct (@pf ); - ren_solid.Construct(@ren_base ); - - rgba.ConstrDbl(1 ,1 ,1 ); - ren_base.clear(@rgba ); - - sl.Construct; - ras.Construct; - -// Render - render_clipper(@sl ,@ras ); - -// Render the controls - render_ctrl(@ras ,@sl ,@ren_solid ,@m_polygons ); - render_ctrl(@ras ,@sl ,@ren_solid ,@m_operation ); - -// Free AGG resources - sl.Destruct; - ras.Destruct; - -end; - -{ ON_MOUSE_MOVE } -procedure the_application.on_mouse_move; -begin - if flags and mouse_left <> 0 then - begin - m_x:=x; - m_y:=y; - - force_redraw; - - end; - -end; - -{ ON_MOUSE_BUTTON_DOWN } -procedure the_application.on_mouse_button_down; -var - buf : array[0..99 ] of char8; - -begin - if flags and mouse_left <> 0 then - begin - m_x:=x; - m_y:=y; - - force_redraw; - - end; - - if flags and mouse_right <> 0 then - begin - sprintf (@buf[0 ] ,'%d ' ,x ); - sprintf (@buf[StrLen(@buf ) ] ,'%d' ,y ); - message_(@buf[0 ] ); - - end; - -end; - -{ ON_KEY } -procedure the_application.on_key; -begin - case key of - byte('t' ) , - byte('T' ) : - stress_test; - - end; - - if key = key_f1 then - message_( - '''Clipper'' by Angus Johnson is the most reliable implementation of the '#13 + - 'polygon boolean algebra. It implements Bala R. Vatti''s algorithm of arbitrary '#13 + - 'polygon clipping and allows you to calculate the Union, Intersection, Difference, '#13 + - 'and Exclusive OR between two poly-polygons (i.e., polygonal areas consisted of '#13 + - 'several contours). AGG has a simple wrapper class that can be used in the '#13 + - 'coordinate conversion pipeline. Note that all operations are done '#13 + - 'in the vectorial representation of the contours before rendering.'#13#13 + - 'How to play with:'#13#13 + - 'You can drag one polygon with the left mouse button pressed.'#13 + - 'Press the "T" key to perform the random polygon clipping stress testing.'#13 + - '(may take some time)' + - #13#13'Note: F2 key saves current "screenshot" file in this demo''s directory. ' ); - -end; - -{ STRESS_TEST } -// Stress-test. -// Works quite well on random polygons, no crashes, no memory leaks! -// Sometimes takes long to produce the result -procedure the_application.stress_test; - -{ random } -function random(min ,max : double ) : double; -var - r : int; - -begin - r:=(System.Random($7fff ) shl 15 ) or System.Random($7fff ); - - result:=$FFFFFFF + 1; - result:=((r and $FFFFFFF) / result ) * (max - min ) + min; - -end; - -var - sl : scanline_u8; - ras : rasterizer_scanline_aa; - - pf : pixel_formats; - - ren_base : renderer_base; - ren_solid : renderer_scanline_aa_solid; - - ps1 ,ps2 : path_storage; - - clipper : conv_clipper; - rgba : aggclr; - - i ,num_poly1 ,num_poly2 ,j ,k ,np ,op: unsigned; - - buf : array[0..99 ] of char8; - txt : gsv_text; - - txt_stroke : conv_stroke; - -begin - sl.Construct; - ras.Construct; - - pixfmt_bgr24(pf ,rbuf_window ); - - ren_base.Construct (@pf ); - ren_solid.Construct(@ren_base ); - - ps1.Construct; - ps2.Construct; - clipper.Construct(@ps1 ,@ps2, clipper_or, clipper_nonZero, clipper_nonZero); - - txt.Construct; - txt_stroke.Construct(@txt ); - - txt_stroke.width_ (1.5 ); - txt_stroke.line_cap_(round_cap ); - txt.size_ (10.0 ); - txt.start_point_ (5 ,5 ); - - for i:=0 to 999 do - begin - rgba.ConstrDbl(1 ,1 ,1 ); - ren_base.clear(@rgba ); - - num_poly1:=System.Random($7fff ) mod 10 + 1; - num_poly2:=System.Random($7fff ) mod 10 + 1; - - ps1.remove_all; - ps2.remove_all; - - for j:=0 to num_poly1 - 1 do - begin - ps1.move_to(random(0 ,_width ) ,random(0 ,_height ) ); - - np:=System.Random($7fff ) mod 20 + 2; - - for k:=0 to np - 1 do - ps1.line_to(random(0 ,_width ) ,random(0 ,_height ) ); - - end; - - for j:=0 to num_poly2 - 1 do - begin - ps2.move_to(random(0 ,_width ) ,random(0 ,_height ) ); - - np:=System.Random($7fff ) mod 20 + 2; - - for k:=0 to np - 1 do - ps2.line_to(random(0 ,_width ) ,random(0 ,_height ) ); - - end; - - op:=System.Random($7fff ) mod 5; - - case op of - 0 : - clipper.operation(clipper_or ); - - 1 : - clipper.operation(clipper_and ); - - 2 : - clipper.operation(clipper_xor ); - - 3 : - clipper.operation(clipper_a_minus_b ); - - else - clipper.operation(clipper_b_minus_a ); - - end; - - // Clipping result - ras.add_path (@clipper ); - rgba.ConstrDbl (0.5 ,0.0 ,0 ,0.5 ); - ren_solid.color_(@rgba ); - render_scanlines(@ras ,@sl ,@ren_solid ); - - // Counter display - sprintf (@buf[0 ] ,'%d / 1000' ,i + 1 ); - txt.text_(@buf[0 ] ); - - txt.start_point_(5 ,5 ); - - ras.add_path (@txt_stroke ); - rgba.ConstrDbl (0.0 ,0.0 ,0.0 ); - ren_solid.color_(@rgba ); - render_scanlines(@ras ,@sl ,@ren_solid ); - - // Refresh - update_window; - - end; - - message_('Done' ); - - ps1.Destruct; - ps2.Destruct; - clipper.Destruct; - - sl.Destruct; - ras.Destruct; - - txt.Destruct; - txt_stroke.Destruct; - - force_redraw; - -end; - -VAR - app : the_application; - -BEGIN - app.Construct(pix_format_bgr24 ,flip_y ); - app.caption_ ('AGG Example. Polygon Clipping with Clipper (F1-Help)' ); - - if app.init(640 ,520 ,window_resize ) then - app.run; - - app.Destruct; - -END. \ No newline at end of file diff --git a/Delphi/agg demo/clipper_test.exe b/Delphi/agg demo/clipper_test.exe deleted file mode 100644 index 962804d3867b7259a0dc456add20831478570e12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247296 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 15} //Delphi 7 + {$DEFINE UInt64Support} //nb: Delphi7 only marginally supports UInt64. + {$IFEND} + {$IF CompilerVersion >= 18} //Delphi 2007 + //Inline has been supported since D2005. + //However D2005 and D2006 have an Inline codegen bug (QC41166). + //http://www.thedelphigeek.com/2007/02/nasty-inline-codegen-bug-in-bds-2006.html + {$DEFINE INLINING} + {$IFEND} + {$ENDIF} +{$ENDIF} + interface uses SysUtils, Types, Classes, Math; type +{$IFDEF use_int32} + cInt = Int32; +{$ELSE} + cInt = Int64; +{$ENDIF} + PIntPoint = ^TIntPoint; - TIntPoint = record X, Y: Int64; end; - TIntRect = record Left, Top, Right, Bottom: Int64; end; +{$IFDEF use_xyz} + TIntPoint = record X, Y, Z: cInt; end; +{$ELSE} + TIntPoint = record X, Y: cInt; end; +{$ENDIF} + + TIntRect = record Left, Top, Right, Bottom: cInt; end; + + TDoublePoint = record X, Y: Double; end; + TArrayOfDoublePoint = array of TDoublePoint; + +{$IFDEF use_xyz} + TZFillCallback = procedure (const Pt1, Pt2: TIntPoint; var Pt: TIntPoint); +{$ENDIF} + + TInitOption = (ioReverseSolution, ioStrictlySimple, ioPreserveCollinear); + TInitOptions = set of TInitOption; TClipType = (ctIntersection, ctUnion, ctDifference, ctXor); TPolyType = (ptSubject, ptClip); @@ -51,35 +107,42 @@ TIntRect = record Left, Top, Right, Bottom: Int64; end; //see http://glprogramming.com/red/chapter11.html TPolyFillType = (pftEvenOdd, pftNonZero, pftPositive, pftNegative); - //TJoinType & TEndType are used by OffsetPolygons() + //TJoinType & TEndType are used by OffsetPaths() TJoinType = (jtSquare, jtRound, jtMiter); TEndType = (etClosed, etButt, etSquare, etRound); - TPolygon = array of TIntPoint; - TPolygons = array of TPolygon; + TPath = array of TIntPoint; + TPaths = array of TPath; + +{$IFDEF use_deprecated} + TPolygon = TPath; + TPolygons = TPaths; +{$ENDIF} TPolyNode = class; TArrayOfPolyNode = array of TPolyNode; TPolyNode = class private - FPolygon: TPolygon; - FParent : TPolyNode; - FIndex: Integer; - FCount : Integer; - FBuffLen : Integer; - FChilds: TArrayOfPolyNode; - function GetChild(Index: Integer): TPolyNode; - function IsHoleNode: boolean; + FPath: TPath; + FParent : TPolyNode; + FIndex : Integer; + FCount : Integer; + FBuffLen: Integer; + FIsOpen : Boolean; + FChilds : TArrayOfPolyNode; + function GetChild(Index: Integer): TPolyNode; + function IsHoleNode: boolean; procedure AddChild(PolyNode: TPolyNode); - function GetNextSiblingUp: TPolyNode; + function GetNextSiblingUp: TPolyNode; public - function GetNext: TPolyNode; - property ChildCount: Integer read FCount; - property Childs[index: Integer]: TPolyNode read GetChild; - property Parent: TPolyNode read FParent; - property IsHole: Boolean read IsHoleNode; - property Contour: TPolygon read FPolygon; + function GetNext: TPolyNode; + property ChildCount: Integer read FCount; + property Childs[index: Integer]: TPolyNode read GetChild; + property Parent: TPolyNode read FParent; + property IsHole: Boolean read IsHoleNode; + property IsOpen: Boolean read FIsOpen; + property Contour: TPath read FPath; end; TPolyTree = class(TPolyNode) @@ -93,29 +156,24 @@ TPolyTree = class(TPolyNode) property Total: Integer read GetTotal; end; - //the definitions below are used internally ... TEdgeSide = (esLeft, esRight); - TIntersectProtect = (ipLeft, ipRight); - TIntersectProtects = set of TIntersectProtect; TDirection = (dRightToLeft, dLeftToRight); + POutPt = ^TOutPt; + PEdge = ^TEdge; TEdge = record - XBot : Int64; //bottom - YBot : Int64; - XCurr: Int64; //current (ie relative to bottom of current scanbeam) - YCurr: Int64; - XTop : Int64; //top - YTop : Int64; - Dx : Double; //the inverse of slope - DeltaX: Int64; - DeltaY: Int64; + Bot : TIntPoint; //bottom + Curr : TIntPoint; //current (ie relative to bottom of current scanbeam) + Top : TIntPoint; //top + Delta: TIntPoint; + Dx : Double; //inverse of slope PolyType : TPolyType; Side : TEdgeSide; - WindDelta: Integer; //1 or -1 depending on winding direction + WindDelta: Integer; //1 or -1 depending on winding direction WindCnt : Integer; - WindCnt2 : Integer; //winding count of the opposite PolyType + WindCnt2 : Integer; //winding count of the opposite PolyType OutIdx : Integer; Next : PEdge; Prev : PEdge; @@ -131,7 +189,7 @@ TEdge = record PScanbeam = ^TScanbeam; TScanbeam = record - Y : Int64; + Y : cInt; Next: PScanbeam; end; @@ -145,19 +203,18 @@ TIntersectNode = record PLocalMinima = ^TLocalMinima; TLocalMinima = record - Y : Int64; + Y : cInt; LeftBound : PEdge; RightBound: PEdge; Next : PLocalMinima; end; - POutPt = ^TOutPt; - POutRec = ^TOutRec; TOutRec = record Idx : Integer; BottomPt : POutPt; IsHole : Boolean; + IsOpen : Boolean; //The 'FirstLeft' field points to the OutRec representing the polygon //immediately to the left of the current OutRec's polygon. When a polygon is //contained within another polygon, the polygon immediately to its left will @@ -176,107 +233,110 @@ TOutPt = record Prev : POutPt; end; - PJoinRec = ^TJoinRec; - TJoinRec = record - Pt1a : TIntPoint; - Pt1b : TIntPoint; - Poly1Idx : Integer; - Pt2a : TIntPoint; - Pt2b : TIntPoint; - Poly2Idx : Integer; - end; - - PHorzRec = ^THorzRec; - THorzRec = record - Edge : PEdge; - SavedIdx : Integer; - Next : PHorzRec; - Prev : PHorzRec; + PJoin = ^TJoin; + TJoin = record + OutPt1 : POutPt; + OutPt2 : POutPt; + OffPt : TIntPoint; //offset point (provides slope of common edges) end; TClipperBase = class private - FEdgeList : TList; - FLmList : PLocalMinima; //localMinima list - FCurrLm : PLocalMinima; //current localMinima node - FUse64BitRange : Boolean; //see LoRange and HiRange consts notes below + FEdgeList : TList; + FLmList : PLocalMinima; //localMinima list + FCurrLm : PLocalMinima; //current localMinima node + FUse64BitRange : Boolean; //see LoRange and HiRange consts notes below + FHasOpenPaths : Boolean; procedure DisposeLocalMinimaList; + procedure DisposePolyPts(PP: POutPt); protected + FPreserveCollinear : Boolean; procedure Reset; virtual; procedure PopLocalMinima; property CurrentLm: PLocalMinima read FCurrLm; + property HasOpenPaths: Boolean read FHasOpenPaths; public constructor Create; virtual; destructor Destroy; override; - function AddPolygon(const Polygon: TPolygon; PolyType: TPolyType): Boolean; - function AddPolygons(const Polygons: TPolygons; PolyType: TPolyType): Boolean; procedure Clear; virtual; + + function AddPath(const Path: TPath; PolyType: TPolyType; Closed: Boolean): Boolean; + function AddPaths(const Paths: TPaths; PolyType: TPolyType; Closed: Boolean): Boolean; + +{$IFDEF use_deprecated} + function AddPolygon(const Path: TPath; PolyType: TPolyType): Boolean; + function AddPolygons(const Paths: TPaths; PolyType: TPolyType): Boolean; +{$ENDIF} + + //PreserveCollinear: Prevents removal of 'inner' vertices when three or + //more vertices are collinear in solution polygons. + property PreserveCollinear: Boolean + read FPreserveCollinear write FPreserveCollinear; end; TClipper = class(TClipperBase) private - FPolyOutList : TList; - FJoinList : TList; - FClipType : TClipType; - FScanbeam : PScanbeam; //scanbeam list - FActiveEdges : PEdge; //active Edge list - FSortedEdges : PEdge; //used for temporary sorting - FIntersectNodes : PIntersectNode; - FClipFillType : TPolyFillType; - FSubjFillType : TPolyFillType; - FExecuteLocked : Boolean; - FHorizJoins : PHorzRec; - FReverseOutput : Boolean; - FForceSimple : Boolean; - FUsingPolyTree: Boolean; + FPolyOutList : TList; + FJoinList : TList; + FGhostJoinList : TList; + FClipType : TClipType; + FScanbeam : PScanbeam; //scanbeam list + FActiveEdges : PEdge; //active Edge list + FSortedEdges : PEdge; //used for temporary sorting + FIntersectNodes : PIntersectNode; + FClipFillType : TPolyFillType; + FSubjFillType : TPolyFillType; + FExecuteLocked : Boolean; + FReverseOutput : Boolean; + FStrictSimple : Boolean; + FUsingPolyTree : Boolean; +{$IFDEF use_xyz} + FZFillCallback : TZFillCallback; +{$ENDIF} procedure DisposeScanbeamList; - procedure InsertScanbeam(const Y: Int64); - function PopScanbeam: Int64; + procedure InsertScanbeam(const Y: cInt); + function PopScanbeam: cInt; procedure SetWindingCount(Edge: PEdge); function IsEvenOddFillType(Edge: PEdge): Boolean; function IsEvenOddAltFillType(Edge: PEdge): Boolean; procedure AddEdgeToSEL(Edge: PEdge); procedure CopyAELToSEL; - procedure InsertLocalMinimaIntoAEL(const BotY: Int64); + procedure InsertLocalMinimaIntoAEL(const BotY: cInt); procedure SwapPositionsInAEL(E1, E2: PEdge); procedure SwapPositionsInSEL(E1, E2: PEdge); - function IsTopHorz(const XPos: Int64): Boolean; - procedure ProcessHorizontal(HorzEdge: PEdge); - procedure ProcessHorizontals; + procedure ProcessHorizontal(HorzEdge: PEdge; IsTopOfScanbeam: Boolean); + procedure ProcessHorizontals(IsTopOfScanbeam: Boolean); procedure InsertIntersectNode(E1, E2: PEdge; const Pt: TIntPoint); - function ProcessIntersections(const BotY, TopY: Int64): Boolean; - procedure BuildIntersectList(const BotY, TopY: Int64); + function ProcessIntersections(const BotY, TopY: cInt): Boolean; + procedure BuildIntersectList(const BotY, TopY: cInt); procedure ProcessIntersectList; procedure DeleteFromAEL(E: PEdge); procedure DeleteFromSEL(E: PEdge); procedure IntersectEdges(E1,E2: PEdge; - const Pt: TIntPoint; protects: TIntersectProtects = []); - procedure DoMaxima(E: PEdge; const TopY: Int64); + const Pt: TIntPoint; Protect: Boolean = False); + procedure DoMaxima(E: PEdge); procedure UpdateEdgeIntoAEL(var E: PEdge); function FixupIntersectionOrder: Boolean; - procedure ProcessEdgesAtTopOfScanbeam(const TopY: Int64); + procedure ProcessEdgesAtTopOfScanbeam(const TopY: cInt); function IsContributing(Edge: PEdge): Boolean; function CreateOutRec: POutRec; - procedure AddOutPt(E: PEdge; const Pt: TIntPoint); + function AddOutPt(E: PEdge; const Pt: TIntPoint): POutPt; procedure AddLocalMaxPoly(E1, E2: PEdge; const Pt: TIntPoint); - procedure AddLocalMinPoly(E1, E2: PEdge; const Pt: TIntPoint); + function AddLocalMinPoly(E1, E2: PEdge; const Pt: TIntPoint): POutPt; function GetOutRec(Idx: integer): POutRec; procedure AppendPolygon(E1, E2: PEdge); - procedure DisposePolyPts(PP: POutPt); - procedure DisposeAllPolyPts; + procedure DisposeAllOutRecs; procedure DisposeOutRec(Index: Integer); procedure DisposeIntersectNodes; - function GetResult: TPolygons; - function GetResult2(PolyTree: TPolyTree): Boolean; + function BuildResult: TPaths; + function BuildResult2(PolyTree: TPolyTree): Boolean; procedure FixupOutPolygon(OutRec: POutRec); procedure SetHoleState(E: PEdge; OutRec: POutRec); - procedure AddJoin(E1, E2: PEdge; - E1OutIdx: Integer = -1; E2OutIdx: Integer = -1); + procedure AddJoin(Op1, Op2: POutPt; const OffPt: TIntPoint); procedure ClearJoins; - procedure AddHorzJoin(E: PEdge; Idx: Integer); - procedure ClearHorzJoins; - function JoinPoints(JR: PJoinRec; out P1, P2: POutPt): Boolean; - procedure FixupJoinRecs(JR: PJoinRec; Pt: POutPt; StartIdx: Integer); + procedure AddGhostJoin(OutPt: POutPt; const OffPt: TIntPoint); + procedure ClearGhostJoins; + function JoinPoints(Jr: PJoin; out P1, P2: POutPt): Boolean; procedure FixupFirstLefts1(OldOutRec, NewOutRec: POutRec); procedure FixupFirstLefts2(OldOutRec, NewOutRec: POutRec); procedure DoSimplePolygons; @@ -287,75 +347,100 @@ TClipper = class(TClipperBase) function ExecuteInternal: Boolean; virtual; public function Execute(clipType: TClipType; - out solution: TPolygons; + out solution: TPaths; subjFillType: TPolyFillType = pftEvenOdd; clipFillType: TPolyFillType = pftEvenOdd): Boolean; overload; function Execute(clipType: TClipType; var PolyTree: TPolyTree; subjFillType: TPolyFillType = pftEvenOdd; clipFillType: TPolyFillType = pftEvenOdd): Boolean; overload; - constructor Create; override; + constructor Create(InitOptions: TInitOptions = []); reintroduce; overload; destructor Destroy; override; procedure Clear; override; //ReverseSolution: reverses the default orientation property ReverseSolution: Boolean read FReverseOutput write FReverseOutput; - property ForceSimple: Boolean - read FForceSimple write FForceSimple; + //StrictlySimple: when false (the default) solutions are 'weakly' simple + property StrictlySimple: Boolean read FStrictSimple write FStrictSimple; +{$IFDEF use_xyz} + property ZFillFunction: TZFillCallback read FZFillCallback write FZFillCallback; +{$ENDIF} end; -function Orientation(const Pts: TPolygon): Boolean; overload; -function Area(const Pts: TPolygon): Double; overload; -function IntPoint(const X, Y: Int64): TIntPoint; +function Orientation(const Pts: TPath): Boolean; overload; +function Area(const Pts: TPath): Double; overload; + +{$IFDEF use_xyz} +function IntPoint(const X, Y: Int64; Z: Int64 = 0): TIntPoint; overload; +function IntPoint(const X, Y: Double; Z: Double = 0): TIntPoint; overload; +{$ELSE} +function IntPoint(const X, Y: cInt): TIntPoint; overload; +function IntPoint(const X, Y: Double): TIntPoint; overload; +{$ENDIF} + +function DoublePoint(const X, Y: Double): TDoublePoint; overload; +function DoublePoint(const Ip: TIntPoint): TDoublePoint; overload; + +function ReversePath(const Pts: TPath): TPath; +function ReversePaths(const Pts: TPaths): TPaths; + +function OffsetPaths(const Polys: TPaths; const Delta: Double; + JoinType: TJoinType = jtSquare; EndType: TEndType = etClosed; + Limit: Double = 0): TPaths; + +{$IFDEF use_deprecated} function ReversePolygon(const Pts: TPolygon): TPolygon; function ReversePolygons(const Pts: TPolygons): TPolygons; - -//OffsetPolygons precondition: outer polygons MUST be oriented clockwise, -//and inner 'hole' polygons must be oriented counter-clockwise ... function OffsetPolygons(const Polys: TPolygons; const Delta: Double; JoinType: TJoinType = jtSquare; Limit: Double = 0; AutoFix: Boolean = True): TPolygons; - -function OffsetPolyLines(const Lines: TPolygons; Delta: Double; - JoinType: TJoinType = jtSquare; EndType: TEndType = etSquare; - Limit: Double = 0): TPolygons; +function PolyTreeToPolygons(PolyTree: TPolyTree): TPolygons; +{$ENDIF} //SimplifyPolygon converts a self-intersecting polygon into a simple polygon. -function SimplifyPolygon(const Poly: TPolygon; FillType: TPolyFillType = pftEvenOdd): TPolygons; -function SimplifyPolygons(const Polys: TPolygons; FillType: TPolyFillType = pftEvenOdd): TPolygons; +function SimplifyPolygon(const Poly: TPath; FillType: TPolyFillType = pftEvenOdd): TPaths; +function SimplifyPolygons(const Polys: TPaths; FillType: TPolyFillType = pftEvenOdd): TPaths; //CleanPolygon removes adjacent vertices closer than the specified distance. -function CleanPolygon(const Poly: TPolygon; Distance: double = 1.415): TPolygon; -function CleanPolygons(const Polys: TPolygons; Distance: double = 1.415): TPolygons; +function CleanPolygon(const Poly: TPath; Distance: double = 1.415): TPath; +function CleanPolygons(const Polys: TPaths; Distance: double = 1.415): TPaths; -function PolyTreeToPolygons(PolyTree: TPolyTree): TPolygons; +function MinkowkiSum(const Base, Path: TPath; IsClosed: Boolean = true): TPaths; +function MinkowkiDiff(const Base, Path: TPath; IsClosed: Boolean = true): TPaths; -implementation +function PolyTreeToPaths(PolyTree: TPolyTree): TPaths; +function ClosedPathsFromPolyTree(PolyTree: TPolyTree): TPaths; +function OpenPathsFromPolyTree(PolyTree: TPolyTree): TPaths; -type - TDoublePoint = record X, Y: Double; end; - TArrayOfDoublePoint = array of TDoublePoint; +implementation const Horizontal: Double = -3.4e+38; - //The Area function places the most limits on coordinate values + + Unassigned : Integer = -1; + Skip : Integer = -2; //flag for the edge that closes an open path + + //The SlopesEqual function places the most limits on coordinate values //So, to avoid overflow errors, they must not exceed the following values... - LoRange: Int64 = $3FFFFFFF; //1.0e+9 - HiRange: Int64 = $3FFFFFFFFFFFFFFF; //4.6e+18 //Also, if all coordinates are within +/-LoRange, then calculations will be //faster. Otherwise using Int128 math will render the library ~10-15% slower. +{$IFDEF use_int32} + LoRange: cInt = 46340; + HiRange: cInt = 46340; +{$ELSE} + LoRange: cInt = $B504F333; //3.0e+9 + HiRange: cInt = $7FFFFFFFFFFFFFFF; //9.2e+18 +{$ENDIF} resourcestring - rsMissingRightbound = 'InsertLocalMinimaIntoAEL: missing RightBound'; rsDoMaxima = 'DoMaxima error'; rsUpdateEdgeIntoAEL = 'UpdateEdgeIntoAEL error'; rsHorizontal = 'ProcessHorizontal error'; rsInvalidInt = 'Coordinate exceeds range bounds'; - rsJoinError = 'Join Output polygons error'; rsIntersect = 'Intersection error'; - -{$IF CompilerVersion >= 20} - {$DEFINE INLINING} -{$IFEND} + rsOpenPath = 'AddPath: Open paths must be subject.'; + rsOpenPath2 = 'AddPath: Open paths have been disabled.'; + rsOpenPath3 = 'Error: TPolyTree struct is need for open path clipping.'; + rsPolylines = 'Error intersecting polylines'; //------------------------------------------------------------------------------ // TPolyNode methods ... @@ -451,6 +536,48 @@ function TPolyTree.GetTotal: Integer; Result := length(FAllNodes); end; +{$IFNDEF use_int32} + +//------------------------------------------------------------------------------ +// UInt64 math support for Delphi 6 +//------------------------------------------------------------------------------ + +{$OVERFLOWCHECKS OFF} +{$IFNDEF UInt64Support} +function CompareUInt64(const i, j: Int64): Integer; +begin + if Int64Rec(i).Hi < Int64Rec(j).Hi then + Result := -1 + else if Int64Rec(i).Hi > Int64Rec(j).Hi then + Result := 1 + else if Int64Rec(i).Lo < Int64Rec(j).Lo then + Result := -1 + else if Int64Rec(i).Lo > Int64Rec(j).Lo then + Result := 1 + else + Result := 0; +end; +{$ENDIF} + +function UInt64LT(const i, j: Int64): Boolean; {$IFDEF INLINING} inline; {$ENDIF} +begin +{$IFDEF UInt64Support} + Result := UInt64(i) < UInt64(j); +{$ELSE} + Result := CompareUInt64(i, j) = -1; +{$ENDIF} +end; + +function UInt64GT(const i, j: Int64): Boolean; {$IFDEF INLINING} inline; {$ENDIF} +begin +{$IFDEF UInt64Support} + Result := UInt64(i) > UInt64(j); +{$ELSE} + Result := CompareUInt64(i, j) = 1; +{$ENDIF} +end; +{$OVERFLOWCHECKS ON} + //------------------------------------------------------------------------------ // Int128 Functions ... //------------------------------------------------------------------------------ @@ -500,7 +627,7 @@ function Int128Equal(const Int1, Int2: TInt128): Boolean; function Int128LessThan(const Int1, Int2: TInt128): Boolean; begin if (Int1.Hi <> Int2.Hi) then Result := Int1.Hi < Int2.Hi - else Result := UInt64(Int1.Lo) < UInt64(Int2.Lo); + else Result := UInt64LT(Int1.Lo, Int2.Lo); end; //------------------------------------------------------------------------------ @@ -508,7 +635,7 @@ function Int128Add(const Int1, Int2: TInt128): TInt128; begin Result.Lo := Int1.Lo + Int2.Lo; Result.Hi := Int1.Hi + Int2.Hi; - if UInt64(Result.Lo) < UInt64(Int1.Lo) then Inc(Result.Hi); + if UInt64LT(Result.Lo, Int1.Lo) then Inc(Result.Hi); end; //------------------------------------------------------------------------------ @@ -516,7 +643,7 @@ function Int128Sub(const Int1, Int2: TInt128): TInt128; begin Result.Hi := Int1.Hi - Int2.Hi; Result.Lo := Int1.Lo - Int2.Lo; - if UInt64(Result.Lo) > UInt64(Int1.Lo) then Dec(Result.Hi); + if UInt64GT(Result.Lo, Int1.Lo) then Dec(Result.Hi); end; //------------------------------------------------------------------------------ @@ -547,7 +674,7 @@ function Int128Mul(Int1, Int2: Int64): TInt128; A := C shl 32; Result.Lo := A + B; - if UInt64(Result.Lo) < UInt64(A) then + if UInt64LT(Result.Lo, A) then Inc(Result.Hi); if Negate then Int128Negate(Result); @@ -635,44 +762,31 @@ function Int128Div(Dividend, Divisor: TInt128{; out Remainder: TInt128}): TInt12 end; //------------------------------------------------------------------------------ -function Int128AsDouble(val: TInt128): Double; -const - shift64: Double = 18446744073709551616.0; -var - lo: Int64; -begin - if (val.Hi < 0) then - begin - lo := -val.Lo; - if lo = 0 then - Result := val.Hi * shift64 else - Result := -(not val.Hi * shift64 + UInt64(lo)); - end else - Result := val.Hi * shift64 + UInt64(val.Lo); -end; +//function Int128AsDouble(val: TInt128): Double; +//const +// shift64: Double = 18446744073709551616.0; +//var +// lo: Int64; +//begin +// if (val.Hi < 0) then +// begin +// lo := -val.Lo; +// if lo = 0 then +// Result := val.Hi * shift64 else +// Result := -(not val.Hi * shift64 + UInt64(lo)); +// end else +// Result := val.Hi * shift64 + UInt64(val.Lo); +//end; //------------------------------------------------------------------------------ {$OVERFLOWCHECKS ON} +{$ENDIF} + //------------------------------------------------------------------------------ // Miscellaneous Functions ... //------------------------------------------------------------------------------ -function FullRangeNeeded(const Pts: TPolygon): Boolean; -var - I: Integer; -begin - Result := False; - for I := 0 to high(Pts) do - begin - if (abs(Pts[I].X) > HiRange) or (abs(Pts[I].Y) > HiRange) then - raise exception.Create(rsInvalidInt) - else if (abs(Pts[I].X) > LoRange) or (abs(Pts[I].Y) > LoRange) then - Result := True; - end; -end; -//------------------------------------------------------------------------------ - function PointCount(Pts: POutPt): Integer; var P: POutPt; @@ -688,87 +802,106 @@ function PointCount(Pts: POutPt): Integer; //------------------------------------------------------------------------------ function PointsEqual(const P1, P2: TIntPoint): Boolean; + {$IFDEF INLINING} inline; {$ENDIF} begin Result := (P1.X = P2.X) and (P1.Y = P2.Y); end; //------------------------------------------------------------------------------ -function IntPoint(const X, Y: Int64): TIntPoint; +{$IFDEF use_xyz} +function IntPoint(const X, Y: Int64; Z: Int64 = 0): TIntPoint; +begin + Result.X := X; + Result.Y := Y; + Result.Z := Z; +end; +//------------------------------------------------------------------------------ + +function IntPoint(const X, Y: Double; Z: Double = 0): TIntPoint; +begin + Result.X := Round(X); + Result.Y := Round(Y); + Result.Z := Round(Z); +end; +//------------------------------------------------------------------------------ + +{$ELSE} + +function IntPoint(const X, Y: cInt): TIntPoint; +begin + Result.X := X; + Result.Y := Y; +end; +//------------------------------------------------------------------------------ + +function IntPoint(const X, Y: Double): TIntPoint; +begin + Result.X := Round(X); + Result.Y := Round(Y); +end; + +{$ENDIF} +//------------------------------------------------------------------------------ + +function DoublePoint(const X, Y: Double): TDoublePoint; begin Result.X := X; Result.Y := Y; end; //------------------------------------------------------------------------------ -function Area(const Pts: TPolygon): Double; +function DoublePoint(const Ip: TIntPoint): TDoublePoint; +begin + Result.X := Ip.X; + Result.Y := Ip.Y; +end; +//------------------------------------------------------------------------------ + +function Area(const Pts: TPath): Double; var I, HighI: Integer; - A: TInt128; - D: Double; + D, D2: Double; begin Result := 0; HighI := high(Pts); if HighI < 2 then Exit; - if FullRangeNeeded(Pts) then - begin - A := Int128Sub(Int128Mul(Pts[HighI].X, Pts[0].Y), - Int128Mul(Pts[0].X, Pts[HighI].Y)); - for I := 0 to HighI-1 do - A := Int128Add(A, Int128Sub(Int128Mul(Pts[I].X, Pts[I+1].Y), - Int128Mul(Pts[I+1].X, Pts[I].Y))); - Result := Int128AsDouble(A) / 2; - end else + //see http://www.mathopenref.com/coordpolygonarea2.html + D2 := (Pts[HighI].X + Pts[0].X); + D := D2 * (Pts[0].Y - Pts[HighI].Y); + for I := 1 to HighI do begin - //see http://www.mathopenref.com/coordpolygonarea2.html - D := (Pts[HighI].X + Pts[0].X) * (Pts[0].Y - Pts[HighI].Y); - for I := 1 to HighI do - D := D + (Pts[I-1].X + Pts[I].X) * (Pts[I].Y - Pts[I-1].Y); - Result := D / 2; + D2 := (Pts[I-1].X + Pts[I].X); //ie forces floating point multiplication + D := D + D2 * (Pts[I].Y - Pts[I-1].Y); end; + Result := D * 0.5; end; //------------------------------------------------------------------------------ -function Area(OutRec: POutRec; UseFullInt64Range: Boolean): Double; overload; +function Area(OutRec: POutRec): Double; overload; var Op: POutPt; - D: Double; - A: TInt128; + D, D2: Double; begin + D := 0; Op := OutRec.Pts; - if not Assigned(Op) then - begin - Result := 0; - Exit; - end; - if UseFullInt64Range then - begin - A := Int128(0); - repeat - A := Int128Add(A, - Int128Mul(Op.Pt.X + Op.Prev.Pt.X, Op.Prev.Pt.Y - Op.Pt.Y)); - Op := Op.Next; - until Op = OutRec.Pts; - Result := Int128AsDouble(A) / 2; - end else - begin - D := 0; + if Assigned(Op) then repeat //nb: subtraction reversed since vertices are stored in reverse order ... - D := D + (Op.Pt.X + Op.Prev.Pt.X) * (Op.Prev.Pt.Y - Op.Pt.Y); + D2 := (Op.Pt.X + Op.Prev.Pt.X); + D := D + D2 * (Op.Prev.Pt.Y - Op.Pt.Y); Op := Op.Next; until Op = OutRec.Pts; - Result := D / 2; - end; + Result := D * 0.5; end; //------------------------------------------------------------------------------ -function Orientation(const Pts: TPolygon): Boolean; overload; +function Orientation(const Pts: TPath): Boolean; begin Result := Area(Pts) >= 0; end; //------------------------------------------------------------------------------ -function ReversePolygon(const Pts: TPolygon): TPolygon; +function ReversePath(const Pts: TPath): TPath; var I, HighI: Integer; begin @@ -779,7 +912,7 @@ function ReversePolygon(const Pts: TPolygon): TPolygon; end; //------------------------------------------------------------------------------ -function ReversePolygons(const Pts: TPolygons): TPolygons; +function ReversePaths(const Pts: TPaths): TPaths; var I, J, highJ: Integer; begin @@ -795,23 +928,10 @@ function ReversePolygons(const Pts: TPolygons): TPolygons; end; //------------------------------------------------------------------------------ -function PointIsVertex(const Pt: TIntPoint; PP: POutPt): Boolean; -var - Pp2: POutPt; -begin - Result := True; - Pp2 := PP; - repeat - if PointsEqual(Pp2.Pt, Pt) then Exit; - Pp2 := Pp2.Next; - until Pp2 = PP; - Result := False; -end; -//------------------------------------------------------------------------------ - function PointOnLineSegment(const Pt, LinePt1, LinePt2: TIntPoint; UseFullInt64Range: Boolean): Boolean; begin +{$IFNDEF use_int32} if UseFullInt64Range then Result := ((Pt.X = LinePt1.X) and (Pt.Y = LinePt1.Y)) or @@ -821,6 +941,7 @@ function PointOnLineSegment(const Pt, LinePt1, LinePt2: TIntPoint; Int128Equal(Int128Mul((Pt.X - LinePt1.X), (LinePt2.Y - LinePt1.Y)), Int128Mul((LinePt2.X - LinePt1.X), (Pt.Y - LinePt1.Y)))) else +{$ENDIF} Result := ((Pt.X = LinePt1.X) and (Pt.Y = LinePt1.Y)) or ((Pt.X = LinePt2.X) and (Pt.Y = LinePt2.Y)) or @@ -853,72 +974,64 @@ function PointInPolygon(const Pt: TIntPoint; PP: POutPt; UseFullInt64Range: Boolean): Boolean; var Pp2: POutPt; - A, B: TInt128; begin Result := False; Pp2 := PP; +{$IFNDEF use_int32} if UseFullInt64Range then begin repeat - if (((Pp2.Pt.Y <= Pt.Y) and (Pt.Y < Pp2.Prev.Pt.Y)) or - ((Pp2.Prev.Pt.Y <= Pt.Y) and (Pt.Y < Pp2.Pt.Y))) then - begin - A := Int128(Pt.X - Pp2.Pt.X); - B := Int128Div( Int128Mul(Pp2.Prev.Pt.X - Pp2.Pt.X, - Pt.Y - Pp2.Pt.Y), Int128(Pp2.Prev.Pt.Y - Pp2.Pt.Y) ); - if Int128LessThan(A, B) then Result := not Result; - end; + if ((pp2.Pt.Y > pt.Y) <> (pp2.Prev.Pt.Y > pt.Y)) and + Int128LessThan( Int128(pt.X - pp2.Pt.X), + Int128Div( Int128Mul(pp2.Prev.Pt.X - pp2.Pt.X, pt.Y - pp2.Pt.Y), + Int128(pp2.Prev.Pt.Y - pp2.Pt.Y)) ) then Result := not Result; Pp2 := Pp2.Next; until Pp2 = PP; end else - begin +{$ENDIF} repeat - if ((((Pp2.Pt.Y <= Pt.Y) and (Pt.Y < Pp2.Prev.Pt.Y)) or - ((Pp2.Prev.Pt.Y <= Pt.Y) and (Pt.Y < Pp2.Pt.Y))) and - (Pt.X < (Pp2.Prev.Pt.X - Pp2.Pt.X) * (Pt.Y - Pp2.Pt.Y) / - (Pp2.Prev.Pt.Y - Pp2.Pt.Y) + Pp2.Pt.X)) then Result := not Result; + //http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html + if (((pp2.Pt.Y > pt.Y) <> (pp2.Prev.Pt.Y > pt.Y)) and + ((pt.X - pp2.Pt.X) < (pp2.Prev.Pt.X - pp2.Pt.X) * (pt.Y - pp2.Pt.Y) / + (pp2.Prev.Pt.Y - pp2.Pt.Y))) then Result := not Result; Pp2 := Pp2.Next; until Pp2 = PP; - end; end; //------------------------------------------------------------------------------ function SlopesEqual(E1, E2: PEdge; UseFullInt64Range: Boolean): Boolean; overload; begin +{$IFNDEF use_int32} if UseFullInt64Range then - Result := Int128Equal(Int128Mul(E1.DeltaY, E2.DeltaX), - Int128Mul(E1.DeltaX, E2.DeltaY)) + Result := Int128Equal(Int128Mul(E1.Delta.Y, E2.Delta.X), + Int128Mul(E1.Delta.X, E2.Delta.Y)) else - Result := E1.DeltaY * E2.DeltaX = E1.DeltaX * E2.DeltaY; +{$ENDIF} + Result := E1.Delta.Y * E2.Delta.X = E1.Delta.X * E2.Delta.Y; end; //--------------------------------------------------------------------------- function SlopesEqual(const Pt1, Pt2, Pt3: TIntPoint; UseFullInt64Range: Boolean): Boolean; overload; begin +{$IFNDEF use_int32} if UseFullInt64Range then Result := Int128Equal( Int128Mul(Pt1.Y-Pt2.Y, Pt2.X-Pt3.X), Int128Mul(Pt1.X-Pt2.X, Pt2.Y-Pt3.Y)) else +{$ENDIF} Result := (Pt1.Y-Pt2.Y)*(Pt2.X-Pt3.X) = (Pt1.X-Pt2.X)*(Pt2.Y-Pt3.Y); end; //--------------------------------------------------------------------------- -function SlopesEqual(const Pt1, Pt2, Pt3, Pt4: TIntPoint; - UseFullInt64Range: Boolean): Boolean; overload; -begin - if UseFullInt64Range then - Result := Int128Equal( Int128Mul(Pt1.Y-Pt2.Y, Pt3.X-Pt4.X), - Int128Mul(Pt1.X-Pt2.X, Pt3.Y-Pt4.Y)) - else - Result := (Pt1.Y-Pt2.Y)*(Pt3.X-Pt4.X) = (Pt1.X-Pt2.X)*(Pt3.Y-Pt4.Y); -end; -//--------------------------------------------------------------------------- +(***************************************************************************** +* Dx: 0(90º) Slope: 0 = Dx: -inf * +* | Slope: 0.5 = Dx: -2 * +* +inf (180º) <--- o ---> -inf (0º) Slope: 2.0 = Dx: -0.5 * +* Slope: inf = Dx: 0 * +*****************************************************************************) -// 0(90º) // -// | // -// +inf (180º) --- o --- -inf (0º) // function GetDx(const Pt1, Pt2: TIntPoint): Double; begin if (Pt1.Y = Pt2.Y) then Result := Horizontal @@ -928,10 +1041,10 @@ function GetDx(const Pt1, Pt2: TIntPoint): Double; procedure SetDx(E: PEdge); {$IFDEF INLINING} inline; {$ENDIF} begin - E.DeltaX := (E.XTop - E.XBot); - E.DeltaY := (E.YTop - E.YBot); - if E.DeltaY = 0 then E.Dx := Horizontal - else E.Dx := E.DeltaX/E.DeltaY; + E.Delta.X := (E.Top.X - E.Bot.X); + E.Delta.Y := (E.Top.Y - E.Bot.Y); + if E.Delta.Y = 0 then E.Dx := Horizontal + else E.Dx := E.Delta.X/E.Delta.Y; end; //--------------------------------------------------------------------------- @@ -955,54 +1068,76 @@ procedure SwapPolyIndexes(Edge1, Edge2: PEdge); end; //------------------------------------------------------------------------------ -function TopX(Edge: PEdge; const currentY: Int64): Int64; +function TopX(Edge: PEdge; const currentY: cInt): cInt; +begin + if currentY = Edge.Top.Y then Result := Edge.Top.X + else if Edge.Top.X = Edge.Bot.X then Result := Edge.Bot.X + else Result := Edge.Bot.X + round(Edge.Dx*(currentY - Edge.Bot.Y)); +end; +//------------------------------------------------------------------------------ + +{$IFDEF use_xyz} +Procedure SetZ(var Pt: TIntPoint; E: PEdge; ZFillFunc: TZFillCallback); begin - if currentY = Edge.YTop then Result := Edge.XTop - else if Edge.XTop = Edge.XBot then Result := Edge.XBot - else Result := Edge.XBot + round(Edge.Dx*(currentY - Edge.YBot)); + Pt.Z := 0; + if assigned(ZFillFunc) then + begin + //put the 'preferred' point as first parameter ... + if E.OutIdx < 0 then + ZFillFunc(E.Bot, E.Top, Pt) //outside a path so presume entering ... + else + ZFillFunc(E.Top, E.Bot, Pt); //inside a path so presume exiting ... + end; end; //------------------------------------------------------------------------------ +{$ENDIF} function IntersectPoint(Edge1, Edge2: PEdge; out ip: TIntPoint; UseFullInt64Range: Boolean): Boolean; overload; var B1,B2,M: Double; begin - if SlopesEqual(Edge1, Edge2, UseFullInt64Range) then +{$IFDEF use_xyz} + ip.Z := 0; +{$ENDIF} + //nb: with very large coordinate values, it's possible for SlopesEqual() to + //return false but for the edge.Dx value be equal due to double precision + //rounding ... + if SlopesEqual(Edge1, Edge2, UseFullInt64Range) or (edge1.Dx = edge2.Dx) then begin //parallel edges, but nevertheless prepare to force the intersection - //since Edge2.XCurr < Edge1.XCurr ... - if Edge2.YBot > Edge1.YBot then - ip.Y := Edge2.YBot else - ip.Y := Edge1.YBot; + //since Edge2.Curr.X < Edge1.Curr.X ... + if Edge2.Bot.Y > Edge1.Bot.Y then + ip.Y := Edge2.Bot.Y else + ip.Y := Edge1.Bot.Y; Result := False; Exit; end; - if Edge1.Dx = 0 then + if Edge1.Delta.X = 0 then begin - ip.X := Edge1.XBot; + ip.X := Edge1.Bot.X; if Edge2.Dx = Horizontal then - ip.Y := Edge2.YBot + ip.Y := Edge2.Bot.Y else begin - with Edge2^ do B2 := YBot - (XBot/Dx); + with Edge2^ do B2 := Bot.Y - (Bot.X/Dx); ip.Y := round(ip.X/Edge2.Dx + B2); end; end - else if Edge2.Dx = 0 then + else if Edge2.Delta.X = 0 then begin - ip.X := Edge2.XBot; + ip.X := Edge2.Bot.X; if Edge1.Dx = Horizontal then - ip.Y := Edge1.YBot + ip.Y := Edge1.Bot.Y else begin - with Edge1^ do B1 := YBot - (XBot/Dx); + with Edge1^ do B1 := Bot.Y - (Bot.X/Dx); ip.Y := round(ip.X/Edge1.Dx + B1); end; end else begin - with Edge1^ do B1 := XBot - YBot * Dx; - with Edge2^ do B2 := XBot - YBot * Dx; + with Edge1^ do B1 := Bot.X - Bot.Y * Dx; + with Edge2^ do B2 := Bot.X - Bot.Y * Dx; M := (B2-B1)/(Edge1.Dx - Edge2.Dx); ip.Y := round(M); if Abs(Edge1.Dx) < Abs(Edge2.Dx) then @@ -1011,27 +1146,27 @@ function IntersectPoint(Edge1, Edge2: PEdge; ip.X := round(Edge2.Dx * M + B2); end; - //The precondition - E.XCurr > eNext.XCurr - indicates that the two edges do + //The precondition - E.Curr.X > eNext.Curr.X - indicates that the two edges do //intersect below TopY (and hence below the tops of either Edge). However, //when edges are almost parallel, rounding errors may cause False positives - //indicating intersections when there really aren't any. Also, floating point //imprecision can incorrectly place an intersect point beyond/above an Edge. //Therfore, further validation of the IP is warranted ... - if (ip.Y < Edge1.YTop) or (ip.Y < Edge2.YTop) then + if (ip.Y < Edge1.Top.Y) or (ip.Y < Edge2.Top.Y) then begin //Find the lower top of the two edges and compare X's at this Y. //If Edge1's X is greater than Edge2's X then it's fair to assume an //intersection really has occurred... - if (Edge1.YTop > Edge2.YTop) then + if (Edge1.Top.Y > Edge2.Top.Y) then begin - Result := TopX(Edge2, Edge1.YTop) < Edge1.XTop; - ip.X := Edge1.XTop; - ip.Y := Edge1.YTop; + ip.Y := edge1.Top.Y; + ip.X := TopX(edge2, edge1.Top.Y); + Result := ip.X < edge1.Top.X; end else begin - Result := TopX(Edge1, Edge2.YTop) > Edge2.XTop; - ip.X := Edge2.XTop; - ip.Y := Edge2.YTop; + ip.Y := edge2.Top.Y; + ip.X := TopX(edge1, edge2.Top.Y); + Result := ip.X > edge2.Top.X; end; end else Result := True; @@ -1051,255 +1186,640 @@ procedure ReversePolyPtLinks(PP: POutPt); Pp1 := Pp2; until Pp1 = PP; end; - //------------------------------------------------------------------------------ -// TClipperBase methods ... + +function Pt2IsBetweenPt1AndPt3(const Pt1, Pt2, Pt3: TIntPoint): Boolean; +begin + //nb: assumes collinearity. + if PointsEqual(Pt1, Pt3) or PointsEqual(Pt1, Pt2) or PointsEqual(Pt3, Pt2) then + Result := False + else if (Pt1.X <> Pt3.X) then + Result := (Pt2.X > Pt1.X) = (Pt2.X < Pt3.X) + else + Result := (Pt2.Y > Pt1.Y) = (Pt2.Y < Pt3.Y); +end; //------------------------------------------------------------------------------ -constructor TClipperBase.Create; +function GetOverlap(const A1, A2, B1, B2: cInt; out Left, Right: cInt): Boolean; begin - FEdgeList := TList.Create; - FLmList := nil; - FCurrLm := nil; - FUse64BitRange := False; //ie default is False + if (A1 < A2) then + begin + if (B1 < B2) then begin Left := Max(A1,B1); Right := Min(A2,B2); end + else begin Left := Max(A1,B2); Right := Min(A2,B1); end; + end else + begin + if (B1 < B2) then begin Left := Max(A2,B1); Right := Min(A1,B2); end + else begin Left := Max(A2,B2); Right := Min(A1,B1); end + end; + Result := Left < Right; end; //------------------------------------------------------------------------------ -destructor TClipperBase.Destroy; +procedure UpdateOutPtIdxs(OutRec: POutRec); +var + op: POutPt; begin - Clear; - FEdgeList.Free; - inherited; + op := OutRec.Pts; + repeat + op.Idx := OutRec.Idx; + op := op.Prev; + until op = OutRec.Pts; end; //------------------------------------------------------------------------------ -procedure RangeTest(const Pt: TIntPoint; - var MaxRange: Int64); {$IFDEF INLINING} inline; {$ENDIF} +procedure RangeTest(const Pt: TIntPoint; var Use64BitRange: Boolean); begin - if Pt.X > MaxRange then - if Pt.X > HiRange then - raise exception.Create(rsInvalidInt) - else MaxRange := HiRange; - if Pt.Y > MaxRange then - if Pt.Y > HiRange then - raise exception.Create(rsInvalidInt) - else MaxRange := HiRange; + if Use64BitRange then + begin + if (Pt.X > HiRange) or (Pt.Y > HiRange) or + (-Pt.X > HiRange) or (-Pt.Y > HiRange) then + raise exception.Create(rsInvalidInt); + end + else if (Pt.X > LoRange) or (Pt.Y > LoRange) or + (-Pt.X > LoRange) or (-Pt.Y > LoRange) then + begin + Use64BitRange := true; + RangeTest(Pt, Use64BitRange); + end; end; //------------------------------------------------------------------------------ -procedure SwapX(E: PEdge); +procedure ReverseHorizontal(E: PEdge); +var + tmp: cInt; begin //swap horizontal edges' top and bottom x's so they follow the natural //progression of the bounds - ie so their xbots will align with the //adjoining lower Edge. [Helpful in the ProcessHorizontal() method.] - E.XCurr := E.XTop; - E.XTop := E.XBot; - E.XBot := E.XCurr; + tmp := E.Top.X; + E.Top.X := E.Bot.X; + E.Bot.X := tmp; + +{$IFDEF use_xyz} + tmp := E.Top.Z; + E.Top.Z := E.Bot.Z; + E.Bot.Z := tmp; +{$ENDIF} end; //------------------------------------------------------------------------------ -function TClipperBase.AddPolygon(const Polygon: TPolygon; - PolyType: TPolyType): Boolean; +procedure InitEdge(E, Next, Prev: PEdge; + const Pt: TIntPoint); {$IFDEF INLINING} inline; {$ENDIF} +begin + E.Curr := Pt; + E.Next := Next; + E.Prev := Prev; + E.OutIdx := -1; +end; +//------------------------------------------------------------------------------ - //---------------------------------------------------------------------- +procedure InitEdge2(E: PEdge; PolyType: TPolyType); {$IFDEF INLINING} inline; {$ENDIF} +begin + if E.Curr.Y >= E.Next.Curr.Y then + begin + E.Bot := E.Curr; + E.Top := E.Next.Curr; + end else + begin + E.Top := E.Curr; + E.Bot := E.Next.Curr; + end; + SetDx(E); + E.PolyType := PolyType; +end; +//------------------------------------------------------------------------------ + +function RemoveEdge(E: PEdge): PEdge; {$IFDEF INLINING} inline; {$ENDIF} +begin + //removes E from double_linked_list (but without disposing from memory) + E.Prev.Next := E.Next; + E.Next.Prev := E.Prev; + Result := E.Next; + E.Prev := nil; //flag as removed (see ClipperBase.Clear) +end; +//------------------------------------------------------------------------------ - procedure InitEdge(E, eNext, ePrev: PEdge; const Pt: TIntPoint); +function SharedVertWithPrevAtTop(Edge: PEdge): Boolean; +var + E: PEdge; +begin + Result := True; + E := Edge; + while E.Prev <> Edge do begin - E.Next := eNext; - E.Prev := ePrev; - E.XCurr := Pt.X; - E.YCurr := Pt.Y; - if E.YCurr >= E.Next.YCurr then + if PointsEqual(E.Top, E.Prev.Top) then begin - E.XBot := E.XCurr; - E.YBot := E.YCurr; - E.XTop := E.Next.XCurr; - E.YTop := E.Next.YCurr; - E.WindDelta := 1; + if PointsEqual(E.Bot, E.Prev.Bot) then + begin E := E.Prev; Continue; end + else Result := True; end else - begin - E.XTop := E.XCurr; - E.YTop := E.YCurr; - E.XBot := E.Next.XCurr; - E.YBot := E.Next.YCurr; - E.WindDelta := -1; - end; - SetDx(E); - E.PolyType := PolyType; - E.OutIdx := -1; + Result := False; + Break; end; - //---------------------------------------------------------------------- + while E <> Edge do + begin + Result := not Result; + E := E.Next; + end; +end; +//------------------------------------------------------------------------------ - procedure InsertLocalMinima(Lm: PLocalMinima); - var - TmpLm: PLocalMinima; +function SharedVertWithNextIsBot(Edge: PEdge): Boolean; +var + E: PEdge; + A,B: Boolean; +begin + Result := True; + E := Edge; + while E.Prev <> Edge do begin - if not Assigned(FLmList) then - begin - FLmList := Lm; - end - else if (Lm.Y >= FLmList.Y) then + A := PointsEqual(E.Next.Bot, E.Bot); + B := PointsEqual(E.Prev.Bot, E.Bot); + if A <> B then begin - Lm.Next := FLmList; - FLmList := Lm; - end else + Result := A; + Break; + end; + A := PointsEqual(E.Next.Top, E.Top); + B := PointsEqual(E.Prev.Top, E.Top); + if A <> B then begin - TmpLm := FLmList; - while Assigned(TmpLm.Next) and (Lm.Y < TmpLm.Next.Y) do - TmpLm := TmpLm.Next; - Lm.Next := TmpLm.Next; - TmpLm.Next := Lm; + Result := B; + Break; end; + E := E.Prev; end; - //---------------------------------------------------------------------- - - function AddBoundsToLML(E: PEdge): PEdge; - var - NewLm: PLocalMinima; + while E <> Edge do begin - //Starting at the top of one bound we progress to the bottom where there's - //A local minima. We then go to the top of the Next bound. These two bounds - //form the left and right (or right and left) bounds of the local minima. - E.NextInLML := nil; + Result := not Result; E := E.Next; - while True do - begin - if E.Dx = Horizontal then - begin - //nb: proceed through horizontals when approaching from their right, - // but break on horizontal minima if approaching from their left. - // This ensures 'local minima' are always on the left of horizontals. - if (E.Next.YTop < E.YTop) and (E.Next.XBot > E.Prev.XBot) then Break; - if (E.XTop <> E.Prev.XBot) then SwapX(E); - //E.WindDelta := 0; safe option to consider when redesigning - E.NextInLML := E.Prev; - end - else if (E.YBot = E.Prev.YBot) then Break - else E.NextInLML := E.Prev; - E := E.Next; - end; + end; +end; +//------------------------------------------------------------------------------ - //E and E.Prev are now at a local minima ... - new(NewLm); - NewLm.Y := E.Prev.YBot; - NewLm.Next := nil; - if E.Dx = Horizontal then //Horizontal edges never start a left bound - begin - if (E.XBot <> E.Prev.XBot) then SwapX(E); - NewLm.LeftBound := E.Prev; - NewLm.RightBound := E; - end else if (E.Dx < E.Prev.Dx) then +function GetLastHorz(Edge: PEdge): PEdge; {$IFDEF INLINING} inline; {$ENDIF} +begin + Result := Edge; + while (Result.OutIdx <> Skip) and + (Result.Next <> Edge) and (Result.Next.Dx = Horizontal) do + Result := Result.Next; +end; +//------------------------------------------------------------------------------ + +function MoreBelow(Edge: PEdge): Boolean; {$IFDEF INLINING} inline; {$ENDIF} +var + E: PEdge; +begin + //Edge is Skip heading down. + E := Edge; + if E.Dx = Horizontal then + begin + while E.Next.Dx = Horizontal do E := E.Next; + Result := E.Next.Bot.Y > E.Bot.Y; + end else if E.Next.Dx = Horizontal then + begin + while E.Next.Dx = Horizontal do E := E.Next; + Result := E.Next.Bot.Y > E.Bot.Y; + end else + Result := PointsEqual(E.Bot, E.Next.Top); +end; +//------------------------------------------------------------------------------ + +function JustBeforeLocMin(Edge: PEdge): Boolean; +var + E: PEdge; +begin + //Edge is Skip and was heading down. + E := Edge; + if E.Dx = Horizontal then + begin + while E.Next.Dx = Horizontal do E := E.Next; + Result := E.Next.Top.Y < E.Bot.Y; + end else + result := SharedVertWithNextIsBot(E); +end; +//------------------------------------------------------------------------------ + +function MoreAbove(Edge: PEdge): Boolean; {$IFDEF INLINING} inline; {$ENDIF} +begin + if (Edge.Dx = Horizontal) then + begin + Edge := GetLastHorz(Edge); + Result := (Edge.Next.Top.Y < Edge.Top.Y); + end else if (Edge.Next.Dx = Horizontal) then + begin + Edge := GetLastHorz(Edge.Next); + Result := (Edge.Next.Top.Y < Edge.Top.Y); + end else + Result := (Edge.Next.Top.Y < Edge.Top.Y); +end; +//------------------------------------------------------------------------------ + +function AllHorizontal(Edge: PEdge): Boolean; +var + E: PEdge; +begin + Result := Edge.Dx = Horizontal; + if not Result then Exit; + E := Edge.Next; + while (E <> Edge) do + if E.Dx <> Horizontal then + begin + Result := False; + Exit; + end else + E := E.Next; +end; + +//------------------------------------------------------------------------------ +// TClipperBase methods ... +//------------------------------------------------------------------------------ + +constructor TClipperBase.Create; +begin + FEdgeList := TList.Create; + FLmList := nil; + FCurrLm := nil; + FUse64BitRange := False; //ie default is False +end; +//------------------------------------------------------------------------------ + +destructor TClipperBase.Destroy; +begin + Clear; + FEdgeList.Free; + inherited; +end; +//------------------------------------------------------------------------------ + +function TClipperBase.AddPath(const Path: TPath; + PolyType: TPolyType; Closed: Boolean): Boolean; + + //---------------------------------------------------------------------- + + procedure InsertLocalMinima(Lm: PLocalMinima); + var + TmpLm: PLocalMinima; + begin + if not Assigned(FLmList) then + begin + FLmList := Lm; + end + else if (Lm.Y >= FLmList.Y) then begin - NewLm.LeftBound := E.Prev; - NewLm.RightBound := E; + Lm.Next := FLmList; + FLmList := Lm; end else begin - NewLm.LeftBound := E; - NewLm.RightBound := E.Prev; + TmpLm := FLmList; + while Assigned(TmpLm.Next) and (Lm.Y < TmpLm.Next.Y) do + TmpLm := TmpLm.Next; + Lm.Next := TmpLm.Next; + TmpLm.Next := Lm; + end; + end; + //---------------------------------------------------------------------- + + procedure DoMinimaLML(E1, E2: PEdge); + var + NewLm: PLocalMinima; + begin + if not assigned(E1) then + begin + if not assigned(E2) then Exit; + new(NewLm); + NewLm.Next := nil; + NewLm.Y := E2.Bot.Y; + NewLm.LeftBound := nil; + E2.WindDelta := 0; + NewLm.RightBound := E2; + InsertLocalMinima(NewLm); + end else + begin + //E and E.Prev are now at a local minima ... + new(NewLm); + NewLm.Y := E1.Bot.Y; + NewLm.Next := nil; + if E2.Dx = Horizontal then //Horz. edges never start a left bound + begin + if (E2.Bot.X <> E1.Bot.X) then ReverseHorizontal(E2); + NewLm.LeftBound := E1; + NewLm.RightBound := E2; + end else if (E2.Dx < E1.Dx) then + begin + NewLm.LeftBound := E1; + NewLm.RightBound := E2; + end else + begin + NewLm.LeftBound := E2; + NewLm.RightBound := E1; + end; + NewLm.LeftBound.Side := esLeft; + NewLm.RightBound.Side := esRight; + //set the winding state of the first edge in each bound + //(it'll be copied to subsequent edges in the bound) ... + with NewLm^ do + begin + if not Closed then LeftBound.WindDelta := 0 + else if (LeftBound.Next = RightBound) then LeftBound.WindDelta := -1 + else LeftBound.WindDelta := 1; + RightBound.WindDelta := -LeftBound.WindDelta; + end; + InsertLocalMinima(NewLm); + end; + end; + //---------------------------------------------------------------------- + + function DescendToMin(var E: PEdge): PEdge; + var + EHorz: PEdge; + begin + //PRECONDITION: STARTING EDGE IS A VALID DESCENDING EDGE. + //Starting at the top of one bound we progress to the bottom where there's + //A local minima. We then go to the top of the Next bound. These two bounds + //form the left and right (or right and left) bounds of the local minima. + E.NextInLML := nil; + if (E.Dx = Horizontal) then + begin + EHorz := E; + while (EHorz.Next.Dx = Horizontal) do EHorz := EHorz.Next; + if not PointsEqual(EHorz.Bot, EHorz.Next.Top) then + ReverseHorizontal(E); + end; + while true do + begin + E := E.Next; + if (E.OutIdx = Skip) then Break + else if E.Dx = Horizontal then + begin + //nb: proceed through horizontals when approaching from their right, + // but break on horizontal minima if approaching from their left. + // This ensures 'local minima' are always on the left of horizontals. + + //look ahead is required in case of multiple consec. horizontals + EHorz := GetLastHorz(E); + if (EHorz = E.Prev) or //horizontal polyline OR + ((EHorz.Next.Top.Y < E.Top.Y) and //bottom horizontal + (EHorz.Next.Bot.X > E.Prev.Bot.X)) then //approaching from the left + Break; + if (E.Top.X <> E.Prev.Bot.X) then ReverseHorizontal(E); + if EHorz.OutIdx = Skip then EHorz := EHorz.Prev; + while E <> EHorz do + begin + E.NextInLML := E.Prev; + E := E.Next; + if (E.Top.X <> E.Prev.Bot.X) then ReverseHorizontal(E); + end; + end + else if (E.Bot.Y = E.Prev.Bot.Y) then Break; + E.NextInLML := E.Prev; + end; + Result := E.Prev; + end; + //---------------------------------------------------------------------- + + procedure AscendToMax(var E: PEdge; Appending: Boolean); + var + EStart: PEdge; + begin + if (E.OutIdx = Skip) then + begin + E := E.Next; + if not MoreAbove(E.Prev) then Exit; end; - NewLm.LeftBound.Side := esLeft; - NewLm.RightBound.Side := esRight; - InsertLocalMinima(NewLm); + if (E.Dx = Horizontal) and Appending and + not PointsEqual(E.Bot, E.Prev.Bot) then + ReverseHorizontal(E); //now process the ascending bound .... + EStart := E; while True do begin - if (E.Next.YTop = E.YTop) and not (E.Next.Dx = Horizontal) then Break; + if (E.Next.OutIdx = Skip) or + ((E.Next.Top.Y = E.Top.Y) and (E.Next.Dx <> Horizontal)) then Break; E.NextInLML := E.Next; E := E.Next; - if (E.Dx = Horizontal) and (E.XBot <> E.Prev.XTop) then SwapX(E); + if (E.Dx = Horizontal) and (E.Bot.X <> E.Prev.Top.X) then + ReverseHorizontal(E); + end; + + if not Appending then + begin + if EStart.OutIdx = Skip then EStart := EStart.Next; + if (EStart <> E.Next) then + DoMinimaLML(nil, EStart); + end; + E := E.Next; + end; + //---------------------------------------------------------------------- + + function AddBoundsToLML(E: PEdge): PEdge; + var + AppendMaxima: Boolean; + B: PEdge; + begin + //Starting at the top of one bound we progress to the bottom where there's + //A local minima. We then go to the top of the Next bound. These two bounds + //form the left and right (or right and left) bounds of the local minima. + + //do minima ... + if E.OutIdx = Skip then + begin + if MoreBelow(E) then + begin + E := E.Next; + B := DescendToMin(E); + end else + B := nil; + end else + B := DescendToMin(E); + + if (E.OutIdx = Skip) then //nb: may be BEFORE, AT or just THRU LM + begin + //do minima before Skip... + DoMinimaLML(nil, B); //store what we've got so far (if anything) + AppendMaxima := False; + //finish off any minima ... + if not PointsEqual(E.Bot,E.Prev.Bot) and MoreBelow(E) then + begin + E := E.Next; + B := DescendToMin(E); + DoMinimaLML(B, E); + AppendMaxima := True; + end + else if JustBeforeLocMin(E) then + E := E.Next; + end else + begin + DoMinimaLML(B, E); + AppendMaxima := True; + end; + + //now do maxima ... + AscendToMax(E, AppendMaxima); + + if (E.OutIdx = Skip) and not PointsEqual(E.Top, E.Prev.Top) then + begin + //may be BEFORE, AT or just AFTER maxima + //finish off any maxima ... + if MoreAbove(E) then + begin + E := E.Next; + AscendToMax(E, false); + end + else if PointsEqual(E.Top, E.Next.Top) or + ((E.Next.Dx = Horizontal) and PointsEqual(E.Top, E.Next.Bot)) then + E := E.Next; //ie just before Maxima end; - Result := E.Next; + Result := E; end; //---------------------------------------------------------------------- var - I, J, len: Integer; + I, HighI: Integer; Edges: PEdgeArray; - E, EHighest: PEdge; - Pg: TPolygon; - MaxVal: Int64; + E, EStart, ELoopStop, EHighest: PEdge; + ClosedOrSemiClosed: Boolean; begin - {AddPolygon} +{$IFDEF use_lines} + if not Closed and (polyType = ptClip) then + raise exception.Create(rsOpenPath); +{$ELSE} + if not Closed then raise exception.Create(rsOpenPath2); +{$ENDIF} + Result := False; //ie assume nothing added - len := length(Polygon); - if len < 3 then Exit; - SetLength(Pg, len); - - //1. check that coordinate values are within the valid range, and - //2. remove duplicate points and co-linear points - if FUse64BitRange then MaxVal := HiRange else MaxVal := LoRange; - RangeTest(Polygon[0], MaxVal); - Pg[0] := Polygon[0]; - J := 0; - for I := 1 to len-1 do - begin - if PointsEqual(Pg[J], Polygon[I]) then Continue; - RangeTest(Polygon[I], MaxVal); - if (J > 0) and SlopesEqual(Pg[J-1], Pg[J], Polygon[I], MaxVal = HiRange) then + HighI := High(Path); + ClosedOrSemiClosed := + (HighI > 0) and (Closed or PointsEqual(Path[0],Path[HighI])); + while (HighI > 0) and PointsEqual(Path[HighI],Path[0]) do Dec(HighI); + while (HighI > 0) and PointsEqual(Path[HighI],Path[HighI -1]) do Dec(HighI); + if (Closed and (HighI < 2)) or (not Closed and (HighI < 1)) then Exit; + + //1. Basic initialization of Edges ... + GetMem(Edges, sizeof(TEdge)*(HighI +1)); + try + FillChar(Edges^, sizeof(TEdge)*(HighI +1), 0); + Edges[1].Curr := Path[1]; + RangeTest(Path[0], FUse64BitRange); + RangeTest(Path[HighI], FUse64BitRange); + InitEdge(@Edges[0], @Edges[1], @Edges[HighI], Path[0]); + InitEdge(@Edges[HighI], @Edges[0], @Edges[HighI-1], Path[HighI]); + for I := HighI - 1 downto 1 do begin - if PointsEqual(Pg[J-1], Polygon[I]) then Dec(J); - end else - Inc(J); - Pg[J] := Polygon[I]; + RangeTest(Path[I], FUse64BitRange); + InitEdge(@Edges[I], @Edges[I+1], @Edges[I-1], Path[I]); + end; + except + FreeMem(Edges); + raise; //Range test fails end; - if (J < 2) then Exit; - FUse64BitRange := MaxVal = HiRange; - - //now remove duplicate points and co-linear edges at the loop around of the - //start and end coordinates ... - len := J+1; - while len > 2 do - begin - //nb: test for point equality before testing slopes ... - if PointsEqual(Pg[J], Pg[0]) then Dec(J) - else if PointsEqual(Pg[0], Pg[1]) or - SlopesEqual(Pg[J], Pg[0], Pg[1], FUse64BitRange) then + + EStart := @Edges[0]; + if not ClosedOrSemiClosed then EStart.Prev.OutIdx := Skip; + + //2. Remove duplicate vertices, and collinear edges (when closed) ... + E := EStart; + ELoopStop := EStart; + while (E <> E.Next) do //ie in case loop reduces to a single vertex + begin + if PointsEqual(E.Curr, E.Next.Curr) then begin - Pg[0] := Pg[J]; - Dec(J); - end - else if SlopesEqual(Pg[J-1], Pg[J], Pg[0], FUse64BitRange) then Dec(J) - else if SlopesEqual(Pg[0], Pg[1], Pg[2], FUse64BitRange) then + //nb E.OutIdx never equals Skip here because it would then be SemiClosed + if E = EStart then EStart := E.Next; + E := RemoveEdge(E); + ELoopStop := E; + Continue; + end; + if (E.Prev = E.Next) then + Break //only two vertices + else if (ClosedOrSemiClosed or + ((E.Prev.OutIdx <> Skip) and (E.OutIdx <> Skip) and + (E.Next.OutIdx <> Skip))) and + SlopesEqual(E.Prev.Curr, E.Curr, E.Next.Curr, FUse64BitRange) then begin - for I := 2 to J do Pg[I-1] := Pg[I]; - Dec(J); - end - else - Break; - Dec(len); + //All collinear edges are allowed for open paths but in closed paths + //inner vertices of adjacent collinear edges are removed. However if the + //PreserveCollinear property has been enabled, only overlapping collinear + //edges (ie spikes) are removed from closed paths. + if Closed and (not FPreserveCollinear or + not Pt2IsBetweenPt1AndPt3(E.Prev.Curr, E.Curr, E.Next.Curr)) then + begin + if E = EStart then EStart := E.Next; + E := RemoveEdge(E); + E := E.Prev; + ELoopStop := E; + Continue; + end; + end; + E := E.Next; + if E = ELoopStop then Break; end; - if len < 3 then Exit; - Result := True; - GetMem(Edges, sizeof(TEdge)*len); - FillChar(Edges^, sizeof(TEdge)*len, 0); - FEdgeList.Add(Edges); + if (not Closed and (E = E.Next)) or (Closed and (E.Prev = E.Next)) then + begin + FreeMem(Edges); + Exit; + end; + + if not Closed then + FHasOpenPaths := True; - //convert vertices to a Double-linked-list of edges and initialize ... - Edges[0].XCurr := Pg[0].X; - Edges[0].YCurr := Pg[0].Y; - InitEdge(@Edges[len-1], @Edges[0], @Edges[len-2], Pg[len-1]); - for I := len-2 downto 1 do - InitEdge(@Edges[I], @Edges[I+1], @Edges[I-1], Pg[I]); - InitEdge(@Edges[0], @Edges[1], @Edges[len-1], Pg[0]); - //reset XCurr & YCurr and find the 'highest' Edge. (nb: since I'm much more - //familiar with positive downwards Y axes, 'highest' here will be the Edge - //with the *smallest* YTop.) - E := @Edges[0]; + //3. Do the final Init and also find the 'highest' Edge. + //(nb: since I'm much more familiar with positive downwards Y axes, + //'highest' here is the Edge with the *smallest* Top.Y.) + E := EStart; EHighest := E; repeat - E.XCurr := E.XBot; - E.YCurr := E.YBot; - if E.YTop < EHighest.YTop then EHighest := E; + InitEdge2(E, PolyType); + if E.Top.Y < EHighest.Top.Y then EHighest := E; E := E.Next; - until E = @Edges[0]; + until E = EStart; - //make sure eHighest is positioned so the following loop works safely ... - if EHighest.WindDelta > 0 then EHighest := EHighest.Next; - if (EHighest.Dx = Horizontal) then EHighest := EHighest.Next; + Result := True; + FEdgeList.Add(Edges); + + //4. build the local minima list ... + if AllHorizontal(E) then + begin + if ClosedOrSemiClosed then + E.Prev.OutIdx := Skip; + AscendToMax(E, false); + Exit; + end; + + //if eHighest is also the Skip then it's a natural break, otherwise + //make sure eHighest is positioned so we're either at a top horizontal or + //just starting to head down one edge of the polygon + E := EStart.Prev; //EStart.Prev == Skip edge + if (E.Prev = E.Next) then + EHighest := E.Next + else if not ClosedOrSemiClosed and (E.Top.Y = EHighest.Top.Y) then + begin + if ((E.Dx = Horizontal) or (E.Next.Dx = Horizontal)) and + (E.Next.Bot.Y = eHighest.Top.Y) then + EHighest := E.Next + else if SharedVertWithPrevAtTop(E) then EHighest := E + else if PointsEqual(E.Top, E.Prev.Top) then EHighest := E.Prev + else EHighest := E.Next; + end else + begin + E := EHighest; + while (EHighest.Dx = Horizontal) or + (PointsEqual(EHighest.top, EHighest.next.top) or + PointsEqual(EHighest.top, EHighest.next.bot)) do {next is high horizontal} + begin + EHighest := EHighest.Next; + if EHighest = E then + begin + while (EHighest.Dx = Horizontal) or + not SharedVertWithPrevAtTop(EHighest) do + EHighest := EHighest.Next; + Break; //ie avoids potential endless loop + end; + end; + end; - //finally insert each local minima ... E := EHighest; repeat E := AddBoundsToLML(E); @@ -1307,14 +1827,14 @@ function TClipperBase.AddPolygon(const Polygon: TPolygon; end; //------------------------------------------------------------------------------ -function TClipperBase.AddPolygons(const Polygons: TPolygons; - PolyType: TPolyType): Boolean; +function TClipperBase.AddPaths(const Paths: TPaths; + PolyType: TPolyType; Closed: Boolean): Boolean; var I: Integer; begin Result := False; - for I := 0 to high(Polygons) do - if AddPolygon(Polygons[I], PolyType) then Result := True; + for I := 0 to high(Paths) do + if AddPath(Paths[I], PolyType, Closed) then Result := True; end; //------------------------------------------------------------------------------ @@ -1323,48 +1843,61 @@ procedure TClipperBase.Clear; I: Integer; begin DisposeLocalMinimaList; - for I := 0 to FEdgeList.Count -1 do dispose(PEdgeArray(fEdgeList[I])); + //dispose of Edges ... + for I := 0 to FEdgeList.Count -1 do + FreeMem(PEdgeArray(fEdgeList[I])); FEdgeList.Clear; + FUse64BitRange := False; + FHasOpenPaths := False; end; //------------------------------------------------------------------------------ procedure TClipperBase.Reset; var - E: PEdge; Lm: PLocalMinima; begin //Reset() allows various clipping operations to be executed //multiple times on the same polygon sets. - FCurrLm := FLmList; - //reset all edges ... Lm := FCurrLm; while Assigned(Lm) do begin - E := Lm.LeftBound; - while Assigned(E) do - begin - E.XCurr := E.XBot; - E.YCurr := E.YBot; - E.Side := esLeft; - E.OutIdx := -1; - E := E.NextInLML; - end; - E := Lm.RightBound; - while Assigned(E) do + //resets just the two (L & R) edges attached to each Local Minima ... + if assigned(Lm.LeftBound) then + with Lm.LeftBound^ do + begin + Curr := Bot; + Side := esLeft; + if OutIdx <> Skip then + OutIdx := Unassigned; + end; + with Lm.RightBound^ do begin - E.XCurr := E.XBot; - E.YCurr := E.YBot; - E.Side := esRight; - E.OutIdx := -1; - E := E.NextInLML; + Curr := Bot; + Side := esRight; + if OutIdx <> Skip then + OutIdx := Unassigned; end; Lm := Lm.Next; end; end; //------------------------------------------------------------------------------ +procedure TClipperBase.DisposePolyPts(PP: POutPt); +var + TmpPp: POutPt; +begin + PP.Prev.Next := nil; + while Assigned(PP) do + begin + TmpPp := PP; + PP := PP.Next; + dispose(TmpPp); + end; +end; +//------------------------------------------------------------------------------ + procedure TClipperBase.DisposeLocalMinimaList; begin while Assigned(FLmList) do @@ -1387,11 +1920,18 @@ procedure TClipperBase.PopLocalMinima; // TClipper methods ... //------------------------------------------------------------------------------ -constructor TClipper.Create; +constructor TClipper.Create(InitOptions: TInitOptions = []); begin inherited Create; FJoinList := TList.Create; + FGhostJoinList := TList.Create; FPolyOutList := TList.Create; + if ioReverseSolution in InitOptions then + FReverseOutput := true; + if ioStrictlySimple in InitOptions then + FStrictSimple := true; + if ioPreserveCollinear in InitOptions then + FPreserveCollinear := true; end; //------------------------------------------------------------------------------ @@ -1400,13 +1940,14 @@ destructor TClipper.Destroy; inherited; //this must be first since inherited Destroy calls Clear. DisposeScanbeamList; FJoinList.Free; + FGhostJoinList.Free; FPolyOutList.Free; end; //------------------------------------------------------------------------------ procedure TClipper.Clear; begin - DisposeAllPolyPts; + DisposeAllOutRecs; inherited; end; //------------------------------------------------------------------------------ @@ -1430,7 +1971,7 @@ procedure TClipper.Reset; begin inherited Reset; FScanbeam := nil; - DisposeAllPolyPts; + DisposeAllOutRecs; Lm := FLmList; while Assigned(Lm) do begin @@ -1441,21 +1982,27 @@ procedure TClipper.Reset; //------------------------------------------------------------------------------ function TClipper.Execute(clipType: TClipType; - out solution: TPolygons; + out solution: TPaths; subjFillType: TPolyFillType = pftEvenOdd; clipFillType: TPolyFillType = pftEvenOdd): Boolean; begin Result := False; solution := nil; if FExecuteLocked then Exit; - try + //nb: Open paths can only be returned via the PolyTree structure ... + if HasOpenPaths then raise Exception.Create(rsOpenPath3); + try try FExecuteLocked := True; FSubjFillType := subjFillType; FClipFillType := clipFillType; FClipType := clipType; FUsingPolyTree := False; Result := ExecuteInternal; - if Result then solution := GetResult; + solution := BuildResult; + except + solution := nil; + Result := False; + end; finally FExecuteLocked := False; end; @@ -1469,13 +2016,16 @@ function TClipper.Execute(clipType: TClipType; begin Result := False; if FExecuteLocked or not Assigned(PolyTree) then Exit; - try + try try FExecuteLocked := True; FSubjFillType := subjFillType; FClipFillType := clipFillType; FClipType := clipType; FUsingPolyTree := True; - Result := ExecuteInternal and GetResult2(PolyTree); + Result := ExecuteInternal and BuildResult2(PolyTree); + except + Result := False; + end; finally FExecuteLocked := False; end; @@ -1503,53 +2053,55 @@ function TClipper.ExecuteInternal: Boolean; var I: Integer; OutRec: POutRec; - BotY, TopY: Int64; + BotY, TopY: cInt; begin - Result := False; - try try + try Reset; - if not Assigned(fScanbeam) then - begin - Result := True; - Exit; - end; + Result := Assigned(fScanbeam); + if not Result then Exit; BotY := PopScanbeam; repeat InsertLocalMinimaIntoAEL(BotY); - ClearHorzJoins; - ProcessHorizontals; + ClearGhostJoins; + ProcessHorizontals(False); + if not assigned(FScanbeam) then Break; TopY := PopScanbeam; if not ProcessIntersections(BotY, TopY) then Exit; ProcessEdgesAtTopOfScanbeam(TopY); BotY := TopY; until not assigned(FScanbeam) and not assigned(CurrentLm); - //tidy up output polygons and fix orientations where necessary ... + //fix orientations ... for I := 0 to FPolyOutList.Count -1 do begin OutRec := FPolyOutList[I]; - if not Assigned(OutRec.Pts) then Continue; - FixupOutPolygon(OutRec); - if not Assigned(OutRec.Pts) then Continue; - if (OutRec.IsHole xor FReverseOutput) = (Area(OutRec, FUse64BitRange) > 0) then - ReversePolyPtLinks(OutRec.Pts); + if Assigned(OutRec.Pts) and not OutRec.IsOpen and + ((OutRec.IsHole xor FReverseOutput) = (Area(OutRec) > 0)) then + ReversePolyPtLinks(OutRec.Pts); end; + if FJoinList.count > 0 then JoinCommonEdges; - if FForceSimple then DoSimplePolygons; + + //unfortunately FixupOutPolygon() must be done after JoinCommonEdges ... + for I := 0 to FPolyOutList.Count -1 do + begin + OutRec := FPolyOutList[I]; + if Assigned(OutRec.Pts) and not OutRec.IsOpen then + FixupOutPolygon(OutRec); + end; + + if FStrictSimple then DoSimplePolygons; Result := True; - except - Result := False; - end; finally ClearJoins; - ClearHorzJoins; + ClearGhostJoins; end; end; //------------------------------------------------------------------------------ -procedure TClipper.InsertScanbeam(const Y: Int64); +procedure TClipper.InsertScanbeam(const Y: cInt); var Sb, Sb2: PScanbeam; begin @@ -1577,7 +2129,7 @@ procedure TClipper.InsertScanbeam(const Y: Int64); end; //------------------------------------------------------------------------------ -function TClipper.PopScanbeam: Int64; +function TClipper.PopScanbeam: cInt; var Sb: PScanbeam; begin @@ -1588,21 +2140,7 @@ function TClipper.PopScanbeam: Int64; end; //------------------------------------------------------------------------------ -procedure TClipper.DisposePolyPts(PP: POutPt); -var - TmpPp: POutPt; -begin - PP.Prev.Next := nil; - while Assigned(PP) do - begin - TmpPp := PP; - PP := PP.Next; - dispose(TmpPp); - end; -end; -//------------------------------------------------------------------------------ - -procedure TClipper.DisposeAllPolyPts; +procedure TClipper.DisposeAllOutRecs; var I: Integer; begin @@ -1624,39 +2162,82 @@ procedure TClipper.DisposeOutRec(Index: Integer); procedure TClipper.SetWindingCount(Edge: PEdge); var - E: PEdge; + E, E2: PEdge; + Inside: Boolean; begin E := Edge.PrevInAEL; //find the Edge of the same PolyType that immediately preceeds 'Edge' in AEL - while Assigned(E) and (E.PolyType <> Edge.PolyType) do E := E.PrevInAEL; + while Assigned(E) and ((E.PolyType <> Edge.PolyType) or (E.WindDelta = 0)) do + E := E.PrevInAEL; if not Assigned(E) then begin - Edge.WindCnt := Edge.WindDelta; + if Edge.WindDelta = 0 then Edge.WindCnt := 1 + else Edge.WindCnt := Edge.WindDelta; Edge.WindCnt2 := 0; E := FActiveEdges; //ie get ready to calc WindCnt2 - end else if IsEvenOddFillType(Edge) then + end + else if (Edge.WindDelta = 0) and (FClipType <> ctUnion) then begin - //even-odd filling ... Edge.WindCnt := 1; Edge.WindCnt2 := E.WindCnt2; E := E.NextInAEL; //ie get ready to calc WindCnt2 + end + else if IsEvenOddFillType(Edge) then + begin + //even-odd filling ... + if (Edge.WindDelta = 0) then //if edge is part of a line + begin + //are we inside a subj polygon ... + Inside := true; + E2 := E.PrevInAEL; + while assigned(E2) do + begin + if (E2.PolyType = E.PolyType) and (E2.WindDelta <> 0) then + Inside := not Inside; + E2 := E2.PrevInAEL; + end; + if Inside then Edge.WindCnt := 0 + else Edge.WindCnt := 1; + end + else //else a polygon + begin + Edge.WindCnt := Edge.WindDelta; + end; + Edge.WindCnt2 := E.WindCnt2; + E := E.NextInAEL; //ie get ready to calc WindCnt2 end else begin //NonZero, Positive, or Negative filling ... - if E.WindCnt * E.WindDelta < 0 then + if (E.WindCnt * E.WindDelta < 0) then begin - if (abs(E.WindCnt) > 1) then + //prev edge is 'decreasing' WindCount (WC) toward zero + //so we're outside the previous polygon ... + if (Abs(E.WindCnt) > 1) then begin - if (E.WindDelta * Edge.WindDelta < 0) then Edge.WindCnt := E.WindCnt + //outside prev poly but still inside another. + //when reversing direction of prev poly use the same WC + if (E.WindDelta * Edge.WindDelta < 0) then + Edge.WindCnt := E.WindCnt + //otherwise continue to 'decrease' WC ... else Edge.WindCnt := E.WindCnt + Edge.WindDelta; - end else - Edge.WindCnt := E.WindCnt + E.WindDelta + Edge.WindDelta; + end + else + //now outside all polys of same polytype so set own WC ... + if Edge.WindDelta = 0 then Edge.WindCnt := 1 + else Edge.WindCnt := Edge.WindDelta; end else begin - if (abs(E.WindCnt) > 1) and (E.WindDelta * Edge.WindDelta < 0) then - Edge.WindCnt := E.WindCnt - else if E.WindCnt + Edge.WindDelta = 0 then + //prev edge is 'increasing' WindCount (WC) away from zero + //so we're inside the previous polygon ... + if (Edge.WindDelta = 0) then + begin + if (E.WindCnt < 0) then Edge.WindCnt := E.WindCnt -1 + else Edge.WindCnt := E.WindCnt +1; + end + //if wind direction is reversing prev then use same WC + else if (E.WindDelta * Edge.WindDelta < 0) then Edge.WindCnt := E.WindCnt + //otherwise add to WC ... else Edge.WindCnt := E.WindCnt + Edge.WindDelta; end; Edge.WindCnt2 := E.WindCnt2; @@ -1669,7 +2250,9 @@ procedure TClipper.SetWindingCount(Edge: PEdge); //even-odd filling ... while (E <> Edge) do begin - if Edge.WindCnt2 = 0 then Edge.WindCnt2 := 1 else Edge.WindCnt2 := 0; + if E.WindDelta = 0 then //do nothing (ie ignore lines) + else if Edge.WindCnt2 = 0 then Edge.WindCnt2 := 1 + else Edge.WindCnt2 := 0; E := E.NextInAEL; end; end else @@ -1713,8 +2296,10 @@ function TClipper.IsContributing(Edge: PEdge): Boolean; Pft := FClipFillType; Pft2 := FSubjFillType end; + case Pft of - pftEvenOdd, pftNonZero: Result := abs(Edge.WindCnt) = 1; + pftEvenOdd: Result := (Edge.WindDelta <> 0) or (Edge.WindCnt = 1); + pftNonZero: Result := abs(Edge.WindCnt) = 1; pftPositive: Result := (Edge.WindCnt = 1); else Result := (Edge.WindCnt = -1); end; @@ -1746,17 +2331,25 @@ function TClipper.IsContributing(Edge: PEdge): Boolean; pftPositive: Result := (Edge.WindCnt2 > 0); pftNegative: Result := (Edge.WindCnt2 < 0); end; + ctXor: + if Edge.WindDelta = 0 then //XOr always contributing unless open + case Pft2 of + pftEvenOdd, pftNonZero: Result := (Edge.WindCnt2 = 0); + pftPositive: Result := (Edge.WindCnt2 <= 0); + pftNegative: Result := (Edge.WindCnt2 >= 0); + end; end; end; //------------------------------------------------------------------------------ -procedure TClipper.AddLocalMinPoly(E1, E2: PEdge; const Pt: TIntPoint); +function TClipper.AddLocalMinPoly(E1, E2: PEdge; const Pt: TIntPoint): POutPt; var E, prevE: PEdge; + OutPt: POutPt; begin if (E2.Dx = Horizontal) or (E1.Dx > E2.Dx) then begin - AddOutPt(E1, Pt); + Result := AddOutPt(E1, Pt); E2.OutIdx := E1.OutIdx; E1.Side := esLeft; E2.Side := esRight; @@ -1767,10 +2360,11 @@ procedure TClipper.AddLocalMinPoly(E1, E2: PEdge; const Pt: TIntPoint); prevE := E.PrevInAEL; end else begin - AddOutPt(E2, Pt); + Result := AddOutPt(E2, Pt); E1.OutIdx := E2.OutIdx; E1.Side := esRight; E2.Side := esLeft; + E := E2; if E.PrevInAEL = E1 then prevE := E1.PrevInAEL @@ -1780,8 +2374,12 @@ procedure TClipper.AddLocalMinPoly(E1, E2: PEdge; const Pt: TIntPoint); if Assigned(prevE) and (prevE.OutIdx >= 0) and (TopX(prevE, Pt.Y) = TopX(E, Pt.Y)) and - SlopesEqual(E, prevE, FUse64BitRange) then - AddJoin(E, prevE); + SlopesEqual(E, prevE, FUse64BitRange) and + (E.WindDelta <> 0) and (prevE.WindDelta <> 0) then + begin + OutPt := AddOutPt(prevE, Pt); + AddJoin(Result, OutPt, E.Top); + end; end; //------------------------------------------------------------------------------ @@ -1790,8 +2388,8 @@ procedure TClipper.AddLocalMaxPoly(E1, E2: PEdge; const Pt: TIntPoint); AddOutPt(E1, Pt); if (E1.OutIdx = E2.OutIdx) then begin - E1.OutIdx := -1; - E2.OutIdx := -1; + E1.OutIdx := Unassigned; + E2.OutIdx := Unassigned; end else if E1.OutIdx < E2.OutIdx then AppendPolygon(E1, E2) @@ -1804,7 +2402,7 @@ procedure TClipper.AddEdgeToSEL(Edge: PEdge); begin //SEL pointers in PEdge are reused to build a list of horizontal edges. //However, we don't need to worry about order with horizontal Edge processing. - if not Assigned(fSortedEdges) then + if not Assigned(FSortedEdges) then begin FSortedEdges := Edge; Edge.PrevInSEL := nil; @@ -1834,28 +2432,14 @@ procedure TClipper.CopyAELToSEL; end; //------------------------------------------------------------------------------ -procedure TClipper.AddJoin(E1, E2: PEdge; - E1OutIdx: Integer = -1; E2OutIdx: Integer = -1); +procedure TClipper.AddJoin(Op1, Op2: POutPt; const OffPt: TIntPoint); var - Jr: PJoinRec; + Jr: PJoin; begin new(Jr); - if E1OutIdx >= 0 then - Jr.Poly1Idx := E1OutIdx else - Jr.Poly1Idx := E1.OutIdx; - with E1^ do - begin - Jr.Pt1a := IntPoint(XCurr, YCurr); - Jr.Pt1b := IntPoint(XTop, YTop); - end; - if E2OutIdx >= 0 then - Jr.Poly2Idx := E2OutIdx else - Jr.Poly2Idx := E2.OutIdx; - with E2^ do - begin - Jr.Pt2a := IntPoint(XCurr, YCurr); - Jr.Pt2b := IntPoint(XTop, YTop); - end; + Jr.OutPt1 := Op1; + Jr.OutPt2 := Op2; + Jr.OffPt := OffPt; FJoinList.add(Jr); end; //------------------------------------------------------------------------------ @@ -1865,47 +2449,29 @@ procedure TClipper.ClearJoins; I: Integer; begin for I := 0 to FJoinList.count -1 do - Dispose(PJoinRec(fJoinList[I])); + Dispose(PJoin(fJoinList[I])); FJoinList.Clear; end; //------------------------------------------------------------------------------ -procedure TClipper.AddHorzJoin(E: PEdge; Idx: Integer); +procedure TClipper.AddGhostJoin(OutPt: POutPt; const OffPt: TIntPoint); var - Hr: PHorzRec; + Jr: PJoin; begin - new(Hr); - Hr.Edge := E; - Hr.SavedIdx := Idx; - if FHorizJoins = nil then - begin - FHorizJoins := Hr; - Hr.Next := Hr; - Hr.Prev := Hr; - end else - begin - Hr.Next := FHorizJoins; - Hr.Prev := FHorizJoins.Prev; - FHorizJoins.Prev.Next := Hr; - FHorizJoins.Prev := Hr; - end; + new(Jr); + Jr.OutPt1 := OutPt; + Jr.OffPt := OffPt; + FGhostJoinList.Add(Jr); end; //------------------------------------------------------------------------------ -procedure TClipper.ClearHorzJoins; +procedure TClipper.ClearGhostJoins; var - M, M2: PHorzRec; + I: Integer; begin - if not Assigned(fHorizJoins) then Exit; - M := FHorizJoins; - M.Prev.Next := nil; - while Assigned(M) do - begin - M2 := M.Next; - dispose(M); - M := M2; - end; - FHorizJoins := nil; + for I := 0 to FGhostJoinList.Count -1 do + Dispose(PJoin(FGhostJoinList[I])); + FGhostJoinList.Clear; end; //------------------------------------------------------------------------------ @@ -1919,141 +2485,148 @@ procedure SwapPoints(var Pt1, Pt2: TIntPoint); end; //------------------------------------------------------------------------------ -function GetOverlapSegment(Pt1a, Pt1b, Pt2a, Pt2b: TIntPoint; - out Pt1, Pt2: TIntPoint): Boolean; +function HorzSegmentsOverlap(const Pt1a, Pt1b, Pt2a, Pt2b: TIntPoint): Boolean; begin - //precondition: segments are colinear - if abs(Pt1a.X - Pt1b.X) > abs(Pt1a.Y - Pt1b.Y) then - begin - if Pt1a.X > Pt1b.X then SwapPoints(Pt1a, Pt1b); - if Pt2a.X > Pt2b.X then SwapPoints(Pt2a, Pt2b); - if (Pt1a.X > Pt2a.X) then Pt1 := Pt1a else Pt1 := Pt2a; - if (Pt1b.X < Pt2b.X) then Pt2 := Pt1b else Pt2 := Pt2b; - Result := Pt1.X < Pt2.X; - end else - begin - if Pt1a.Y < Pt1b.Y then SwapPoints(Pt1a, Pt1b); - if Pt2a.Y < Pt2b.Y then SwapPoints(Pt2a, Pt2b); - if (Pt1a.Y < Pt2a.Y) then Pt1 := Pt1a else Pt1 := Pt2a; - if (Pt1b.Y > Pt2b.Y) then Pt2 := Pt1b else Pt2 := Pt2b; - Result := Pt1.Y > Pt2.Y; - end; + //precondition: both segments are horizontal + Result := true; + if (Pt1a.X > Pt2a.X) = (Pt1a.X < Pt2b.X) then Exit + else if (Pt1b.X > Pt2a.X) = (Pt1b.X < Pt2b.X) then Exit + else if (Pt2a.X > Pt1a.X) = (Pt2a.X < Pt1b.X) then Exit + else if (Pt2b.X > Pt1a.X) = (Pt2b.X < Pt1b.X) then Exit + else if (Pt1a.X = Pt2a.X) and (Pt1b.X = Pt2b.X) then Exit + else if (Pt1a.X = Pt2b.X) and (Pt1b.X = Pt2a.X) then Exit + else Result := False; end; //------------------------------------------------------------------------------ -function E2InsertsBeforeE1(E1, E2: PEdge): Boolean; {$IFDEF INLINING} inline; {$ENDIF} +function E2InsertsBeforeE1(E1, E2: PEdge): Boolean; + {$IFDEF INLINING} inline; {$ENDIF} begin - if E2.XCurr = E1.XCurr then + if E2.Curr.X = E1.Curr.X then begin - if E2.YTop > E1.YTop then - Result := E2.XTop < TopX(E1, E2.YTop) else - Result := E1.XTop > TopX(E2, E1.YTop); + if E2.Top.Y > E1.Top.Y then + Result := E2.Top.X < TopX(E1, E2.Top.Y) else + Result := E1.Top.X > TopX(E2, E1.Top.Y); end else - Result := E2.XCurr < E1.XCurr; + Result := E2.Curr.X < E1.Curr.X; end; //---------------------------------------------------------------------- +procedure TClipper.InsertLocalMinimaIntoAEL(const BotY: cInt); -procedure TClipper.InsertLocalMinimaIntoAEL(const BotY: Int64); - - procedure InsertEdgeIntoAEL(Edge: PEdge); - var - E: PEdge; + procedure InsertEdgeIntoAEL(Edge, StartEdge: PEdge); begin - Edge.PrevInAEL := nil; - Edge.NextInAEL := nil; - if not Assigned(fActiveEdges) then + if not Assigned(FActiveEdges) then begin + Edge.PrevInAEL := nil; + Edge.NextInAEL := nil; FActiveEdges := Edge; - end else if E2InsertsBeforeE1(fActiveEdges, Edge) then + end + else if not Assigned(StartEdge) and + E2InsertsBeforeE1(FActiveEdges, Edge) then begin + Edge.PrevInAEL := nil; Edge.NextInAEL := FActiveEdges; FActiveEdges.PrevInAEL := Edge; FActiveEdges := Edge; end else begin - E := FActiveEdges; - while Assigned(E.NextInAEL) and - not E2InsertsBeforeE1(E.NextInAEL, Edge) do - E := E.NextInAEL; - Edge.NextInAEL := E.NextInAEL; - if Assigned(E.NextInAEL) then E.NextInAEL.PrevInAEL := Edge; - Edge.PrevInAEL := E; - E.NextInAEL := Edge; + if not Assigned(StartEdge) then StartEdge := FActiveEdges; + while Assigned(StartEdge.NextInAEL) and + not E2InsertsBeforeE1(StartEdge.NextInAEL, Edge) do + StartEdge := StartEdge.NextInAEL; + Edge.NextInAEL := StartEdge.NextInAEL; + if Assigned(StartEdge.NextInAEL) then + StartEdge.NextInAEL.PrevInAEL := Edge; + Edge.PrevInAEL := StartEdge; + StartEdge.NextInAEL := Edge; end; end; //---------------------------------------------------------------------- var + I: Integer; E: PEdge; - Pt, Pt2: TIntPoint; Lb, Rb: PEdge; - Hj: PHorzRec; + Jr: PJoin; + Op1, Op2: POutPt; begin while Assigned(CurrentLm) and (CurrentLm.Y = BotY) do begin Lb := CurrentLm.LeftBound; Rb := CurrentLm.RightBound; + PopLocalMinima; - InsertEdgeIntoAEL(Lb); - InsertScanbeam(Lb.YTop); - InsertEdgeIntoAEL(Rb); - - //set Edge winding states ... - if IsEvenOddFillType(Lb) then + Op1 := nil; + if not assigned(Lb) then begin - Lb.WindDelta := 1; - Rb.WindDelta := 1; + //nb: don't insert LB into either AEL or SEL + InsertEdgeIntoAEL(Rb, nil); + SetWindingCount(Rb); + if IsContributing(Rb) then + Op1 := AddOutPt(Rb, Rb.Bot); end else begin - Rb.WindDelta := -Lb.WindDelta + InsertEdgeIntoAEL(Lb, nil); + InsertEdgeIntoAEL(Rb, Lb); + SetWindingCount(Lb); + Rb.WindCnt := Lb.WindCnt; + Rb.WindCnt2 := Lb.WindCnt2; + if IsContributing(Lb) then + Op1 := AddLocalMinPoly(Lb, Rb, Lb.Bot); + InsertScanbeam(Lb.Top.Y); end; - SetWindingCount(Lb); - Rb.WindCnt := Lb.WindCnt; - Rb.WindCnt2 := Lb.WindCnt2; if Rb.Dx = Horizontal then - begin - AddEdgeToSEL(Rb); - InsertScanbeam(Rb.NextInLML.YTop); - end else - InsertScanbeam(Rb.YTop); + AddEdgeToSEL(Rb) else + InsertScanbeam(Rb.Top.Y); - if IsContributing(Lb) then - AddLocalMinPoly(Lb, Rb, IntPoint(Lb.XCurr, CurrentLm.Y)); + if not assigned(Lb) then Continue; //if output polygons share an Edge with rb, they'll need joining later ... - if (Rb.OutIdx >= 0) and (Rb.Dx = Horizontal) and Assigned(fHorizJoins) then + if assigned(Op1) and (Rb.Dx = Horizontal) and + (FGhostJoinList.Count > 0) and (Rb.WindDelta <> 0) then + begin + for I := 0 to FGhostJoinList.Count -1 do + begin + //if the horizontal Rb and a 'ghost' horizontal overlap, then convert + //the 'ghost' join to a real join ready for later ... + Jr := PJoin(FGhostJoinList[I]); + if HorzSegmentsOverlap(Jr.OutPt1.Pt, Jr.OffPt, Rb.Bot, Rb.Top) then + AddJoin(Jr.OutPt1, Op1, Jr.OffPt); + end; + end; + + if (Lb.OutIdx >= 0) and assigned(Lb.PrevInAEL) and + (Lb.PrevInAEL.Curr.X = Lb.Bot.X) and + (Lb.PrevInAEL.OutIdx >= 0) and + SlopesEqual(Lb.PrevInAEL, Lb, FUse64BitRange) and + (Lb.WindDelta <> 0) and (Lb.PrevInAEL.WindDelta <> 0) then begin - Hj := FHorizJoins; - repeat - //if horizontals rb & hj.Edge overlap, flag for joining later ... - if GetOverlapSegment(IntPoint(Hj.Edge.XBot, Hj.Edge.YBot), - IntPoint(Hj.Edge.XTop, Hj.Edge.YTop), IntPoint(Rb.XBot, Rb.YBot), - IntPoint(Rb.XTop, Rb.YTop), Pt, Pt2) then - AddJoin(Hj.Edge, Rb, Hj.SavedIdx); - Hj := Hj.Next; - until Hj = FHorizJoins; + Op2 := AddOutPt(Lb.PrevInAEL, Lb.Bot); + AddJoin(Op1, Op2, Lb.Top); end; if (Lb.NextInAEL <> Rb) then begin if (Rb.OutIdx >= 0) and (Rb.PrevInAEL.OutIdx >= 0) and - SlopesEqual(Rb.PrevInAEL, Rb, FUse64BitRange) then - AddJoin(Rb, Rb.PrevInAEL); - - E := Lb.NextInAEL; - Pt := IntPoint(Lb.XCurr,Lb.YCurr); - while E <> Rb do + SlopesEqual(Rb.PrevInAEL, Rb, FUse64BitRange) and + (Rb.WindDelta <> 0) and (Rb.PrevInAEL.WindDelta <> 0) then begin - if not Assigned(E) then raise exception.Create(rsMissingRightbound); - //nb: For calculating winding counts etc, IntersectEdges() assumes - //that param1 will be to the right of param2 ABOVE the intersection ... - IntersectEdges(Rb, E, Pt); - E := E.NextInAEL; + Op2 := AddOutPt(Rb.PrevInAEL, Rb.Bot); + AddJoin(Op1, Op2, Rb.Top); end; + + E := Lb.NextInAEL; + if Assigned(E) then + while (E <> Rb) do + begin + //nb: For calculating winding counts etc, IntersectEdges() assumes + //that param1 will be to the right of param2 ABOVE the intersection ... + IntersectEdges(Rb, E, Lb.Curr); + E := E.NextInAEL; + end; end; - PopLocalMinima; end; end; //------------------------------------------------------------------------------ @@ -2091,7 +2664,7 @@ procedure TClipper.DeleteFromSEL(E: PEdge); //------------------------------------------------------------------------------ procedure TClipper.IntersectEdges(E1,E2: PEdge; - const Pt: TIntPoint; protects: TIntersectProtects = []); + const Pt: TIntPoint; Protect: Boolean = False); var E1stops, E2stops: Boolean; E1Contributing, E2contributing: Boolean; @@ -2099,17 +2672,74 @@ procedure TClipper.IntersectEdges(E1,E2: PEdge; E1Wc, E2Wc, E1Wc2, E2Wc2: Integer; begin {IntersectEdges} - //E1 will be to the left of E2 BELOW the intersection. Therefore E1 is before //E2 in AEL except when E1 is being inserted at the intersection point ... - E1stops := not (ipLeft in protects) and not Assigned(E1.NextInLML) and - (E1.XTop = Pt.x) and (E1.YTop = Pt.Y); - E2stops := not (ipRight in protects) and not Assigned(E2.NextInLML) and - (E2.XTop = Pt.x) and (E2.YTop = Pt.Y); + E1stops := not Protect and not Assigned(E1.NextInLML) and + (E1.Top.X = Pt.x) and (E1.Top.Y = Pt.Y); + E2stops := not Protect and not Assigned(E2.NextInLML) and + (E2.Top.X = Pt.x) and (E2.Top.Y = Pt.Y); E1Contributing := (E1.OutIdx >= 0); E2contributing := (E2.OutIdx >= 0); +{$IFDEF use_lines} + //if either edge is on an OPEN path ... + if (E1.WindDelta = 0) or (E2.WindDelta = 0) then + begin + //ignore subject-subject open path intersections UNLESS they + //are both open paths, AND they are both 'contributing maximas' ... + if (E1.WindDelta = 0) AND (E2.WindDelta = 0) then + begin + if (E1stops or E2stops) and E1Contributing and E2Contributing then + AddLocalMaxPoly(E1, E2, Pt); + end + //if intersecting a subj line with a subj poly ... + else if (E1.PolyType = E2.PolyType) and + (E1.WindDelta <> E2.WindDelta) and (FClipType = ctUnion) then + begin + if (E1.WindDelta = 0) then + begin + if (E2Contributing) then + begin + AddOutPt(E1, pt); + if (E1Contributing) then E1.OutIdx := Unassigned; + end; + end else + begin + if (E1Contributing) then + begin + AddOutPt(E2, pt); + if (E2Contributing) then E2.OutIdx := Unassigned; + end; + end; + end + else if (E1.PolyType <> E2.PolyType) then + begin + //toggle subj open path OutIdx on/off when Abs(clip.WndCnt) = 1 ... + if (E1.WindDelta = 0) and (Abs(E2.WindCnt) = 1) and + ((FClipType <> ctUnion) or (E2.WindCnt2 = 0)) then + begin + AddOutPt(E1, Pt); + if E1Contributing then E1.OutIdx := Unassigned; + end + else if (E2.WindDelta = 0) and (Abs(E1.WindCnt) = 1) and + ((FClipType <> ctUnion) or (E1.WindCnt2 = 0)) then + begin + AddOutPt(E2, Pt); + if E2Contributing then E2.OutIdx := Unassigned; + end + end; + + if E1stops then + if (E1.OutIdx < 0) then deleteFromAEL(E1) + else raise Exception.Create(rsPolylines); + if E2stops then + if (E2.OutIdx < 0) then deleteFromAEL(E2) + else raise Exception.Create(rsPolylines); + Exit; + end; +{$ENDIF} + //update winding counts... //assumes that E1 will be to the right of E2 ABOVE the intersection if E1.PolyType = E2.PolyType then @@ -2133,6 +2763,7 @@ procedure TClipper.IntersectEdges(E1,E2: PEdge; if not IsEvenOddFillType(E2) then Inc(E1.WindCnt2, E2.WindDelta) else if E1.WindCnt2 = 0 then E1.WindCnt2 := 1 else E1.WindCnt2 := 0; + if not IsEvenOddFillType(E1) then Dec(E2.WindCnt2, E1.WindDelta) else if E2.WindCnt2 = 0 then E2.WindCnt2 := 1 else E2.WindCnt2 := 0; @@ -2172,8 +2803,9 @@ procedure TClipper.IntersectEdges(E1,E2: PEdge; begin if E1stops or E2stops or not (E1Wc in [0,1]) or not (E2Wc in [0,1]) or ((E1.PolyType <> E2.PolyType) and (fClipType <> ctXor)) then - AddLocalMaxPoly(E1, E2, Pt) - else + begin + AddLocalMaxPoly(E1, E2, Pt); + end else begin AddOutPt(E1, Pt); AddOutPt(E2, Pt); @@ -2325,7 +2957,7 @@ procedure TClipper.SetHoleState(E: PEdge; OutRec: POutRec); E2 := E.PrevInAEL; while Assigned(E2) do begin - if (E2.OutIdx >= 0) then + if (E2.OutIdx >= 0) and (E2.WindDelta <> 0) then begin IsHole := not IsHole; if not Assigned(OutRec.FirstLeft) then @@ -2396,13 +3028,14 @@ procedure TClipper.AppendPolygon(E1, E2: PEdge); else if Param1RightOfParam2(OutRec2, OutRec1) then HoleStateRec := OutRec1 else HoleStateRec := GetLowermostRec(OutRec1, OutRec2); - //get the start and ends of both output polygons ... + //get the start and ends of both output polygons and + //join E2 poly onto E1 poly and delete pointers to E2 ... + P1_lft := OutRec1.Pts; P2_lft := OutRec2.Pts; P1_rt := P1_lft.Prev; P2_rt := P2_lft.Prev; - //join E2 poly onto E1 poly and delete pointers to E2 ... if E1.Side = esLeft then begin if E2.Side = esLeft then @@ -2460,8 +3093,8 @@ procedure TClipper.AppendPolygon(E1, E2: PEdge); OKIdx := OutRec1.Idx; ObsoleteIdx := OutRec2.Idx; - E1.OutIdx := -1; //nb: safe because we only get here via AddLocalMaxPoly - E2.OutIdx := -1; + E1.OutIdx := Unassigned; //safe because we only get here via AddLocalMaxPoly + E2.OutIdx := Unassigned; E := FActiveEdges; while Assigned(E) do @@ -2483,6 +3116,7 @@ function TClipper.CreateOutRec: POutRec; begin new(Result); Result.IsHole := False; + Result.IsOpen := False; Result.FirstLeft := nil; Result.Pts := nil; Result.BottomPt := nil; @@ -2491,42 +3125,66 @@ function TClipper.CreateOutRec: POutRec; end; //------------------------------------------------------------------------------ -procedure TClipper.AddOutPt(E: PEdge; const Pt: TIntPoint); +function TClipper.AddOutPt(E: PEdge; const Pt: TIntPoint): POutPt; var OutRec: POutRec; - NewOp, Op: POutPt; + PrevOp, Op: POutPt; ToFront: Boolean; begin ToFront := E.Side = esLeft; if E.OutIdx < 0 then begin OutRec := CreateOutRec; - E.OutIdx := OutRec.Idx; - new(NewOp); - OutRec.Pts := NewOp; - NewOp.Next := NewOp; - NewOp.Prev := NewOp; - NewOp.Idx := OutRec.Idx; - SetHoleState(E, OutRec); + OutRec.IsOpen := (E.WindDelta = 0); + new(Result); + OutRec.Pts := Result; + Result.Pt := Pt; + Result.Next := Result; + Result.Prev := Result; + Result.Idx := OutRec.Idx; + if not OutRec.IsOpen then + SetHoleState(E, OutRec); +{$IFDEF use_xyz} + if PointsEqual(E.Bot, Pt) then + Result.Pt.Z := E.Bot.Z + else if PointsEqual(E.Top, Pt) then + Result.Pt.Z := E.Top.Z + else + SetZ(Result.Pt, E, FZFillCallback); +{$ENDIF} + E.OutIdx := OutRec.Idx; //nb: do this after SetZ ! end else begin OutRec := FPolyOutList[E.OutIdx]; + //OutRec.Pts is the 'left-most' point & OutRec.Pts.Prev is the 'right-most' Op := OutRec.Pts; - if (ToFront and PointsEqual(Pt, Op.Pt)) or - (not ToFront and PointsEqual(Pt, Op.Prev.Pt)) then Exit; - new(NewOp); - NewOp.Idx := OutRec.Idx; - NewOp.Next := Op; - NewOp.Prev := Op.Prev; - Op.Prev.Next := NewOp; - Op.Prev := NewOp; - if ToFront then OutRec.Pts := NewOp; + if ToFront then PrevOp := Op else PrevOp := Op.Prev; + if PointsEqual(Pt, PrevOp.Pt) then + begin + Result := PrevOp; + Exit; + end; + new(Result); + Result.Pt := Pt; + Result.Idx := OutRec.Idx; + Result.Next := Op; + Result.Prev := Op.Prev; + Op.Prev.Next := Result; + Op.Prev := Result; + if ToFront then OutRec.Pts := Result; +{$IFDEF use_xyz} + if PointsEqual(E.Bot, Pt) then + Result.Pt.Z := E.Bot.Z + else if PointsEqual(E.Top, Pt) then + Result.Pt.Z := E.Top.Z + else + SetZ(Result.Pt, E, FZFillCallback); +{$ENDIF} end; - NewOp.Pt := Pt; end; //------------------------------------------------------------------------------ -procedure TClipper.ProcessHorizontals; +procedure TClipper.ProcessHorizontals(IsTopOfScanbeam: Boolean); var E: PEdge; begin @@ -2534,23 +3192,8 @@ procedure TClipper.ProcessHorizontals; begin E := FSortedEdges; DeleteFromSEL(E); - ProcessHorizontal(E); - end; -end; -//------------------------------------------------------------------------------ - -function TClipper.IsTopHorz(const XPos: Int64): Boolean; -var - E: PEdge; -begin - Result := False; - E := FSortedEdges; - while Assigned(E) do - begin - if (XPos >= min(E.XCurr,E.XTop)) and (XPos <= max(E.XCurr,E.XTop)) then Exit; - E := E.NextInSEL; + ProcessHorizontal(E, IsTopOfScanbeam); end; - Result := True; end; //------------------------------------------------------------------------------ @@ -2560,23 +3203,30 @@ function IsMinima(E: PEdge): Boolean; {$IFDEF INLINING} inline; {$ENDIF} end; //------------------------------------------------------------------------------ -function IsMaxima(E: PEdge; const Y: Int64): Boolean; {$IFDEF INLINING} inline; {$ENDIF} +function IsMaxima(E: PEdge; const Y: cInt): Boolean; {$IFDEF INLINING} inline; {$ENDIF} begin - Result := Assigned(E) and (E.YTop = Y) and not Assigned(E.NextInLML); + Result := Assigned(E) and (E.Top.Y = Y) and not Assigned(E.NextInLML); end; //------------------------------------------------------------------------------ -function IsIntermediate(E: PEdge; const Y: Int64): Boolean; {$IFDEF INLINING} inline; {$ENDIF} +function IsIntermediate(E: PEdge; const Y: cInt): Boolean; {$IFDEF INLINING} inline; {$ENDIF} begin - Result := (E.YTop = Y) and Assigned(E.NextInLML); + Result := (E.Top.Y = Y) and Assigned(E.NextInLML); end; //------------------------------------------------------------------------------ function GetMaximaPair(E: PEdge): PEdge; begin - Result := E.Next; - if not IsMaxima(Result, E.YTop) or (Result.XTop <> E.XTop) then - Result := E.Prev; + if PointsEqual(E.Next.Top, E.Top) and not assigned(E.Next.NextInLML) then + Result := E.Next + else if PointsEqual(E.Prev.Top, E.Top) and not assigned(E.Prev.NextInLML) then + Result := E.Prev + else + Result := nil; + if assigned(Result) and ((Result.OutIdx = Skip) or + //result is false if both NextInAEL & PrevInAEL are nil & not horizontal ... + ((Result.NextInAEL = Result.PrevInAEL) and (Result.Dx <> Horizontal))) then + Result := nil; end; //------------------------------------------------------------------------------ @@ -2584,6 +3234,10 @@ procedure TClipper.SwapPositionsInAEL(E1, E2: PEdge); var Prev,Next: PEdge; begin + //check that one or other edge hasn't already been removed from AEL ... + if (E1.NextInAEL = E1.PrevInAEL) or (E2.NextInAEL = E2.PrevInAEL) then + Exit; + if E1.NextInAEL = E2 then begin Next := E2.NextInAEL; @@ -2666,28 +3320,75 @@ procedure TClipper.SwapPositionsInSEL(E1, E2: PEdge); end; //------------------------------------------------------------------------------ -procedure TClipper.ProcessHorizontal(HorzEdge: PEdge); +function GetNextInAEL(E: PEdge; Direction: TDirection): PEdge; + {$IFDEF INLINING} inline; {$ENDIF} +begin + if Direction = dLeftToRight then + Result := E.NextInAEL else + Result := E.PrevInAEL; +end; +//------------------------------------------------------------------------ - function GetNextInAEL(E: PEdge; Direction: TDirection): PEdge; +procedure GetHorzDirection(HorzEdge: PEdge; out Dir: TDirection; + out Left, Right: cInt); {$IFDEF INLINING} inline; {$ENDIF} +begin + if HorzEdge.Bot.X < HorzEdge.Top.X then + begin + Left := HorzEdge.Bot.X; + Right := HorzEdge.Top.X; + Dir := dLeftToRight; + end else begin - if Direction = dLeftToRight then - Result := E.NextInAEL else - Result := E.PrevInAEL; + Left := HorzEdge.Top.X; + Right := HorzEdge.Bot.X; + Dir := dRightToLeft; + end; +end; +//------------------------------------------------------------------------ + +procedure TClipper.ProcessHorizontal(HorzEdge: PEdge; IsTopOfScanbeam: Boolean); + + procedure PrepareHorzJoins; + var + I: Integer; + OutPt: POutPt; + begin + //get the last Op for this horizontal edge + //the point may be anywhere along the horizontal ... + OutPt := POutRec(FPolyOutList[HorzEdge.OutIdx]).Pts; + if HorzEdge.Side <> esLeft then OutPt := OutPt.Prev; + + //First, match up overlapping horizontal edges (eg when one polygon's + //intermediate horz edge overlaps an intermediate horz edge of another, or + //when one polygon sits on top of another) ... + for I := 0 to FGhostJoinList.Count -1 do + with PJoin(FGhostJoinList[I])^ do + if HorzSegmentsOverlap(OutPt1.Pt, OffPt, HorzEdge.Bot, HorzEdge.Top) then + AddJoin(OutPt1, OutPt, OffPt); + + //Also, since horizontal edges at the top of one SB are often removed from + //the AEL before we process the horizontal edges at the bottom of the next, + //we need to create 'ghost' Join records of 'contrubuting' horizontals that + //we can compare with horizontals at the bottom of the next SB. + if IsTopOfScanbeam then + if PointsEqual(OutPt.Pt, HorzEdge.Top) then + AddGhostJoin(OutPt, HorzEdge.Bot) else + AddGhostJoin(OutPt, HorzEdge.Top); end; - //------------------------------------------------------------------------ var - E, eNext, eMaxPair: PEdge; - HorzLeft, HorzRight: Int64; + E, eNext, ePrev, eMaxPair, eLastHorz: PEdge; + HorzLeft, HorzRight: cInt; Direction: TDirection; -const - ProtectLeft: array[Boolean] of TIntersectProtects = ([ipRight], [ipLeft,ipRight]); - ProtectRight: array[Boolean] of TIntersectProtects = ([ipLeft], [ipLeft,ipRight]); + Pt: TIntPoint; + Op1, Op2: POutPt; + IsLastHorz: Boolean; begin (******************************************************************************* * Notes: Horizontal edges (HEs) at scanline intersections (ie at the top or * * bottom of a scanbeam) are processed as if layered. The order in which HEs * -* are processed doesn't matter. HEs intersect with other HE xbots only [#], * +* are processed doesn't matter. HEs intersect with other HE Bot.Xs only [#] * +* (or they could intersect with Top.Xs only, ie EITHER Bot.Xs OR Top.Xs), * * and with other non-horizontal edges [*]. Once these intersections are * * processed, intermediate HEs then 'promote' the Edge above (NextInLML) into * * the AEL. These 'promoted' edges may in turn intersect [%] with other HEs. * @@ -2703,96 +3404,119 @@ procedure TClipper.ProcessHorizontal(HorzEdge: PEdge); * / \ / \ / * *******************************************************************************) - if HorzEdge.XCurr < HorzEdge.XTop then - begin - HorzLeft := HorzEdge.XCurr; - HorzRight := HorzEdge.XTop; - Direction := dLeftToRight; - end else - begin - HorzLeft := HorzEdge.XTop; - HorzRight := HorzEdge.XCurr; - Direction := dRightToLeft; - end; + GetHorzDirection(HorzEdge, Direction, HorzLeft, HorzRight); - if Assigned(HorzEdge.NextInLML) then + eLastHorz := HorzEdge; + while Assigned(eLastHorz.NextInLML) and + (eLastHorz.NextInLML.Dx = Horizontal) do eLastHorz := eLastHorz.NextInLML; + if Assigned(eLastHorz.NextInLML) then eMaxPair := nil else - eMaxPair := GetMaximaPair(HorzEdge); + eMaxPair := GetMaximaPair(eLastHorz); - E := GetNextInAEL(HorzEdge, Direction); - while Assigned(E) do + while true do //loops consec. horizontal edges begin - if (E.XCurr = HorzEdge.XTop) and not Assigned(eMaxPair) then + IsLastHorz := (HorzEdge = eLastHorz); + E := GetNextInAEL(HorzEdge, Direction); + while Assigned(E) do begin - if SlopesEqual(E, HorzEdge.NextInLML, FUse64BitRange) then + //Break if we've got to the end of an intermediate horizontal edge ... + //nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal. + if (E.Curr.X = HorzEdge.Top.X) and + Assigned(HorzEdge.NextInLML) and (E.Dx < HorzEdge.NextInLML.Dx) then + Break; + eNext := GetNextInAEL(E, Direction); //saves eNext for later + + if ((Direction = dLeftToRight) and (E.Curr.X <= HorzRight)) or + ((Direction = dRightToLeft) and (E.Curr.X >= HorzLeft)) then begin - //if output polygons share an Edge, they'll need joining later ... - if (HorzEdge.OutIdx >= 0) and (E.OutIdx >= 0) then - AddJoin(HorzEdge.NextInLML, E, HorzEdge.OutIdx); - Break; //we've reached the end of the horizontal line + //so far we're still in range of the horizontal Edge but make sure + //we're at the last of consec. horizontals when matching with eMaxPair + if (E = eMaxPair) and IsLastHorz then + begin + if (HorzEdge.OutIdx >= 0) and (HorzEdge.WindDelta <> 0) then + PrepareHorzJoins; + if Direction = dLeftToRight then + IntersectEdges(HorzEdge, E, E.Top) else + IntersectEdges(E, HorzEdge, E.Top); + if (eMaxPair.OutIdx >= 0) then raise exception.Create(rsHorizontal); + Exit; + end + else if (Direction = dLeftToRight) then + begin + Pt := IntPoint(E.Curr.X, HorzEdge.Curr.Y); + IntersectEdges(HorzEdge, E, Pt, True); + end else + begin + Pt := IntPoint(E.Curr.X, HorzEdge.Curr.Y); + IntersectEdges(E, HorzEdge, Pt, True); + end; + SwapPositionsInAEL(HorzEdge, E); end - else if (E.Dx < HorzEdge.NextInLML.Dx) then - //we really have got to the end of the intermediate horz Edge so quit. - //nb: More -ve slopes follow more +ve slopes ABOVE the horizontal. - Break; + else if ((Direction = dLeftToRight) and (E.Curr.X >= HorzRight)) or + ((Direction = dRightToLeft) and (E.Curr.X <= HorzLeft)) then + Break; + E := eNext; end; - eNext := GetNextInAEL(E, Direction); - if Assigned(eMaxPair) or - ((Direction = dLeftToRight) and (E.XCurr < HorzRight)) or - ((Direction = dRightToLeft) and (E.XCurr > HorzLeft)) then - begin - //so far we're still in range of the horizontal Edge - if (E = eMaxPair) then - begin - //HorzEdge is evidently a maxima horizontal and we've arrived at its end. - if Direction = dLeftToRight then - IntersectEdges(HorzEdge, E, IntPoint(E.XCurr, HorzEdge.YCurr)) else - IntersectEdges(E, HorzEdge, IntPoint(E.XCurr, HorzEdge.YCurr)); + if (HorzEdge.OutIdx >= 0) and (HorzEdge.WindDelta <> 0) then + PrepareHorzJoins; - if (eMaxPair.OutIdx >= 0) then raise exception.Create(rsHorizontal); - Exit; - end - else if (E.Dx = Horizontal) and not IsMinima(E) and not (E.XCurr > E.XTop) then - begin - //An overlapping horizontal Edge. Overlapping horizontal edges are - //processed as if layered with the current horizontal Edge (horizEdge) - //being infinitesimally lower that the Next (E). Therfore, we - //intersect with E only if E.XCurr is within the bounds of HorzEdge ... - if Direction = dLeftToRight then - IntersectEdges(HorzEdge, E, IntPoint(E.XCurr, HorzEdge.YCurr), - ProtectRight[not IsTopHorz(E.XCurr)]) - else - IntersectEdges(E, HorzEdge, IntPoint(E.XCurr, HorzEdge.YCurr), - ProtectLeft[not IsTopHorz(E.XCurr)]); - end - else if (Direction = dLeftToRight) then - IntersectEdges(HorzEdge, E, IntPoint(E.XCurr, HorzEdge.YCurr), - ProtectRight[not IsTopHorz(E.XCurr)]) - else - IntersectEdges(E, HorzEdge, IntPoint(E.XCurr, HorzEdge.YCurr), - ProtectLeft[not IsTopHorz(E.XCurr)]); - SwapPositionsInAEL(HorzEdge, E); - end - else if ((Direction = dLeftToRight) and (E.XCurr >= HorzRight)) or - ((Direction = dRightToLeft) and (E.XCurr <= HorzLeft)) then - Break; - E := eNext; + if Assigned(HorzEdge.NextInLML) and + (HorzEdge.NextInLML.Dx = Horizontal) then + begin + UpdateEdgeIntoAEL(HorzEdge); + if (HorzEdge.OutIdx >= 0) then AddOutPt(HorzEdge, HorzEdge.Bot); + GetHorzDirection(HorzEdge, Direction, HorzLeft, HorzRight); + end else + Break; end; if Assigned(HorzEdge.NextInLML) then begin if (HorzEdge.OutIdx >= 0) then - AddOutPt(HorzEdge, IntPoint(HorzEdge.XTop, HorzEdge.YTop)); - UpdateEdgeIntoAEL(HorzEdge); + begin + Op1 := AddOutPt(HorzEdge, HorzEdge.Top); + UpdateEdgeIntoAEL(HorzEdge); + if (HorzEdge.WindDelta = 0) then Exit; + //nb: HorzEdge is no longer horizontal here + ePrev := HorzEdge.PrevInAEL; + eNext := HorzEdge.NextInAEL; + if Assigned(ePrev) and (ePrev.Curr.X = HorzEdge.Bot.X) and + (ePrev.Curr.Y = HorzEdge.Bot.Y) and (ePrev.WindDelta <> 0) and + (ePrev.OutIdx >= 0) and (ePrev.Curr.Y > ePrev.Top.Y) and + SlopesEqual(HorzEdge, ePrev, FUse64BitRange) then + begin + Op2 := AddOutPt(ePrev, HorzEdge.Bot); + AddJoin(Op1, Op2, HorzEdge.Top); + end + else if Assigned(eNext) and (eNext.Curr.X = HorzEdge.Bot.X) and + (eNext.Curr.Y = HorzEdge.Bot.Y) and (eNext.WindDelta <> 0) and + (eNext.OutIdx >= 0) and (eNext.Curr.Y > eNext.Top.Y) and + SlopesEqual(HorzEdge, eNext, FUse64BitRange) then + begin + Op2 := AddOutPt(eNext, HorzEdge.Bot); + AddJoin(Op1, Op2, HorzEdge.Top); + end; + end else + UpdateEdgeIntoAEL(HorzEdge); + end + else if assigned(eMaxPair) then + begin + if (eMaxPair.OutIdx >= 0) then + begin + if Direction = dLeftToRight then + IntersectEdges(HorzEdge, eMaxPair, HorzEdge.Top) else + IntersectEdges(eMaxPair, HorzEdge, HorzEdge.Top); + if (eMaxPair.OutIdx >= 0) then + raise exception.Create(rsHorizontal); + end else + begin + DeleteFromAEL(HorzEdge); + DeleteFromAEL(eMaxPair); + end; end else begin - if HorzEdge.OutIdx >= 0 then - IntersectEdges(HorzEdge, eMaxPair, - IntPoint(HorzEdge.XTop, HorzEdge.YCurr), [ipLeft,ipRight]); - - if eMaxPair.OutIdx >= 0 then raise exception.Create(rsHorizontal); - DeleteFromAEL(eMaxPair); + if (HorzEdge.OutIdx >= 0) then AddOutPt(HorzEdge, HorzEdge.Top); DeleteFromAEL(HorzEdge); end; end; @@ -2802,10 +3526,14 @@ procedure TClipper.UpdateEdgeIntoAEL(var E: PEdge); var AelPrev, AelNext: PEdge; begin - if not Assigned(E.NextInLML) then raise exception.Create(rsUpdateEdgeIntoAEL); + //return true when AddOutPt() call needed too + if not Assigned(E.NextInLML) then + raise exception.Create(rsUpdateEdgeIntoAEL); + + E.NextInLML.OutIdx := E.OutIdx; + AelPrev := E.PrevInAEL; AelNext := E.NextInAEL; - E.NextInLML.OutIdx := E.OutIdx; if Assigned(AelPrev) then AelPrev.NextInAEL := E.NextInLML else FActiveEdges := E.NextInLML; @@ -2815,15 +3543,16 @@ procedure TClipper.UpdateEdgeIntoAEL(var E: PEdge); E.NextInLML.WindDelta := E.WindDelta; E.NextInLML.WindCnt := E.WindCnt; E.NextInLML.WindCnt2 := E.WindCnt2; - E := E.NextInLML; + E := E.NextInLML; //// + E.Curr := E.Bot; E.PrevInAEL := AelPrev; E.NextInAEL := AelNext; if E.Dx <> Horizontal then - InsertScanbeam(E.YTop); + InsertScanbeam(E.Top.Y); end; //------------------------------------------------------------------------------ -function TClipper.ProcessIntersections(const BotY, TopY: Int64): Boolean; +function TClipper.ProcessIntersections(const BotY, TopY: cInt): Boolean; begin Result := True; try @@ -2853,7 +3582,7 @@ procedure TClipper.DisposeIntersectNodes; end; //------------------------------------------------------------------------------ -procedure TClipper.BuildIntersectList(const BotY, TopY: Int64); +procedure TClipper.BuildIntersectList(const BotY, TopY: cInt); var E, eNext: PEdge; Pt: TIntPoint; @@ -2868,7 +3597,7 @@ procedure TClipper.BuildIntersectList(const BotY, TopY: Int64); begin E.PrevInSEL := E.PrevInAEL; E.NextInSEL := E.NextInAEL; - E.XCurr := TopX(E, TopY); + E.Curr.X := TopX(E, TopY); E := E.NextInAEL; end; @@ -2879,15 +3608,17 @@ procedure TClipper.BuildIntersectList(const BotY, TopY: Int64); while Assigned(E.NextInSEL) do begin eNext := E.NextInSEL; - if (E.XCurr > eNext.XCurr) then + if (E.Curr.X > eNext.Curr.X) then begin if not IntersectPoint(E, eNext, Pt, FUse64BitRange) and - (E.XCurr > eNext.XCurr +1) then + (E.Curr.X > eNext.Curr.X +1) then raise Exception.Create(rsIntersect); - if Pt.Y > BotY then + if (Pt.Y > botY) then begin - Pt.Y := BotY; - Pt.X := TopX(E, Pt.Y); + Pt.Y := botY; + if (abs(E.Dx) > abs(eNext.Dx)) then + Pt.X := TopX(eNext, botY) else + Pt.X := TopX(E, botY); end; InsertIntersectNode(E, eNext, Pt); SwapPositionsInSEL(E, eNext); @@ -2937,7 +3668,7 @@ procedure TClipper.ProcessIntersectList; Node := FIntersectNodes.Next; with FIntersectNodes^ do begin - IntersectEdges(Edge1, Edge2, Pt, [ipLeft,ipRight]); + IntersectEdges(Edge1, Edge2, Pt, True); SwapPositionsInAEL(Edge1, Edge2); end; dispose(fIntersectNodes); @@ -2946,40 +3677,65 @@ procedure TClipper.ProcessIntersectList; end; //------------------------------------------------------------------------------ -procedure TClipper.DoMaxima(E: PEdge; const TopY: Int64); +procedure TClipper.DoMaxima(E: PEdge); var ENext, EMaxPair: PEdge; - X: Int64; begin EMaxPair := GetMaximaPair(E); - X := E.XTop; + if not assigned(EMaxPair) then + begin + if E.OutIdx >= 0 then + AddOutPt(E, E.Top); + DeleteFromAEL(E); + Exit; + end; + ENext := E.NextInAEL; - while ENext <> EMaxPair do + //rarely, with overlapping collinear edges (in open paths) ENext can be nil + while Assigned(ENext) and (ENext <> EMaxPair) do begin - if not Assigned(ENext) then raise exception.Create(rsDoMaxima); - IntersectEdges(E, ENext, IntPoint(X, TopY), [ipLeft, ipRight]); + IntersectEdges(E, ENext, E.Top, True); SwapPositionsInAEL(E, ENext); ENext := E.NextInAEL; end; - if (E.OutIdx < 0) and (EMaxPair.OutIdx < 0) then + + if (E.OutIdx = Unassigned) and (EMaxPair.OutIdx = Unassigned) then begin DeleteFromAEL(E); DeleteFromAEL(EMaxPair); end else if (E.OutIdx >= 0) and (EMaxPair.OutIdx >= 0) then begin - IntersectEdges(E, EMaxPair, IntPoint(X, TopY)); + IntersectEdges(E, EMaxPair, E.Top); + end +{$IFDEF use_lines} + else if E.WindDelta = 0 then + begin + if (E.OutIdx >= 0) then + begin + AddOutPt(E, E.Top); + E.OutIdx := Unassigned; + end; + DeleteFromAEL(E); + + if (EMaxPair.OutIdx >= 0) then + begin + AddOutPt(EMaxPair, E.Top); + EMaxPair.OutIdx := Unassigned; + end; + DeleteFromAEL(EMaxPair); end - else raise exception.Create(rsDoMaxima); +{$ENDIF} + else + raise exception.Create(rsDoMaxima); end; //------------------------------------------------------------------------------ -procedure TClipper.ProcessEdgesAtTopOfScanbeam(const TopY: Int64); +procedure TClipper.ProcessEdgesAtTopOfScanbeam(const TopY: cInt); var - E, ePrev, eNext: PEdge; - Hj: PHorzRec; - Pt, Pt2: TIntPoint; - IntermediateVert: Boolean; + E, EMaxPair, ePrev, eNext: PEdge; + Op, Op2: POutPt; + IsMaximaEdge: Boolean; begin (******************************************************************************* * Notes: Processing edges at scanline intersections (ie at the top or bottom * @@ -3007,60 +3763,57 @@ procedure TClipper.ProcessEdgesAtTopOfScanbeam(const TopY: Int64); begin //1. process maxima, treating them as if they're 'bent' horizontal edges, // but exclude maxima with Horizontal edges. nb: E can't be a Horizontal. - if IsMaxima(E, TopY) and (GetMaximaPair(E).Dx <> Horizontal) then + IsMaximaEdge := IsMaxima(E, TopY); + if IsMaximaEdge then + begin + EMaxPair := GetMaximaPair(E); + IsMaximaEdge := not assigned(EMaxPair) or (EMaxPair.Dx <> Horizontal); + end; + + if IsMaximaEdge then begin //'E' might be removed from AEL, as may any following edges so ... ePrev := E.PrevInAEL; - DoMaxima(E, TopY); + DoMaxima(E); if not Assigned(ePrev) then E := FActiveEdges else E := ePrev.NextInAEL; end else begin - IntermediateVert := IsIntermediate(E, TopY); - //2. promote horizontal edges, otherwise update XCurr and YCurr ... - if IntermediateVert and (E.NextInLML.Dx = Horizontal) then + //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ... + if IsIntermediate(E, TopY) and (E.NextInLML.Dx = Horizontal) then begin - if (E.OutIdx >= 0) then - begin - AddOutPt(E, IntPoint(E.XTop, E.YTop)); - - Hj := FHorizJoins; - if Assigned(Hj) then - repeat - if GetOverlapSegment(IntPoint(Hj.Edge.XBot, Hj.Edge.YBot), - IntPoint(Hj.Edge.XTop, Hj.Edge.YTop), - IntPoint(E.NextInLML.XBot, E.NextInLML.YBot), - IntPoint(E.NextInLML.XTop, E.NextInLML.YTop), Pt, Pt2) then - AddJoin(Hj.Edge, E.NextInLML, Hj.SavedIdx, E.OutIdx); - Hj := Hj.Next; - until Hj = FHorizJoins; - - AddHorzJoin(E.NextInLML, E.OutIdx); - end; UpdateEdgeIntoAEL(E); + if (E.OutIdx >= 0) then + AddOutPt(E, E.Bot); AddEdgeToSEL(E); end else begin - E.XCurr := TopX(E, TopY); - E.YCurr := TopY; + E.Curr.X := TopX(E, TopY); + E.Curr.Y := TopY; + end; - if FForceSimple and Assigned(E.PrevInAEL) and - (E.PrevInAEL.XCurr = E.XCurr) and - (E.OutIdx >= 0) and (E.PrevInAEL.OutIdx >= 0) then + //When StrictlySimple and 'e' is being touched by another edge, then + //make sure both edges have a vertex here ... + if FStrictSimple then + begin + ePrev := E.PrevInAEL; + if (E.OutIdx >= 0) and (E.WindDelta <> 0) and + Assigned(ePrev) and (ePrev.Curr.X = E.Curr.X) and + (ePrev.OutIdx >= 0) and (ePrev.WindDelta <> 0) then begin - if IntermediateVert then - AddOutPt(E.PrevInAEL, IntPoint(E.XCurr, TopY)) - else - AddOutPt(E, IntPoint(E.XCurr, TopY)); + Op := AddOutPt(ePrev, E.Curr); + Op2 := AddOutPt(E, E.Curr); + AddJoin(Op, Op2, E.Curr); //strictly-simple (type-3) 'join' end; end; + E := E.NextInAEL; end; end; //3. Process horizontals at the top of the scanbeam ... - ProcessHorizontals; + ProcessHorizontals(True); //4. Promote intermediate vertices ... E := FActiveEdges; @@ -3068,27 +3821,31 @@ procedure TClipper.ProcessEdgesAtTopOfScanbeam(const TopY: Int64); begin if IsIntermediate(E, TopY) then begin - if (E.OutIdx >= 0) then AddOutPt(E, IntPoint(E.XTop, E.YTop)); + if (E.OutIdx >= 0) then + Op := AddOutPt(E, E.Top) else + Op := nil; UpdateEdgeIntoAEL(E); //if output polygons share an Edge, they'll need joining later ... ePrev := E.PrevInAEL; eNext := E.NextInAEL; - if Assigned(ePrev) and (ePrev.XCurr = E.XBot) and - (ePrev.YCurr = E.YBot) and (E.OutIdx >= 0) and - (ePrev.OutIdx >= 0) and (ePrev.YCurr > ePrev.YTop) and - SlopesEqual(E, ePrev, FUse64BitRange) then + if Assigned(ePrev) and (ePrev.Curr.X = E.Bot.X) and + (ePrev.Curr.Y = E.Bot.Y) and assigned(Op) and + (ePrev.OutIdx >= 0) and (ePrev.Curr.Y > ePrev.Top.Y) and + SlopesEqual(E, ePrev, FUse64BitRange) and + (E.WindDelta <> 0) and (ePrev.WindDelta <> 0) then begin - AddOutPt(ePrev, IntPoint(E.XBot, E.YBot)); - AddJoin(E, ePrev); + Op2 := AddOutPt(ePrev, E.Bot); + AddJoin(Op, Op2, E.Top); end - else if Assigned(eNext) and (eNext.XCurr = E.XBot) and - (eNext.YCurr = E.YBot) and (E.OutIdx >= 0) and - (eNext.OutIdx >= 0) and (eNext.YCurr > eNext.YTop) and - SlopesEqual(E, eNext, FUse64BitRange) then + else if Assigned(eNext) and (eNext.Curr.X = E.Bot.X) and + (eNext.Curr.Y = E.Bot.Y) and assigned(Op) and + (eNext.OutIdx >= 0) and (eNext.Curr.Y > eNext.Top.Y) and + SlopesEqual(E, eNext, FUse64BitRange) and + (E.WindDelta <> 0) and (eNext.WindDelta <> 0) then begin - AddOutPt(eNext, IntPoint(E.XBot, E.YBot)); - AddJoin(E, eNext); + Op2 := AddOutPt(eNext, E.Bot); + AddJoin(Op, Op2, E.Top); end; end; E := E.NextInAEL; @@ -3096,7 +3853,7 @@ procedure TClipper.ProcessEdgesAtTopOfScanbeam(const TopY: Int64); end; //------------------------------------------------------------------------------ -function TClipper.GetResult: TPolygons; +function TClipper.BuildResult: TPaths; var I, J, K, Cnt: Integer; OutRec: POutRec; @@ -3108,14 +3865,15 @@ function TClipper.GetResult: TPolygons; if Assigned(fPolyOutList[I]) then begin OutRec := FPolyOutList[I]; - Cnt := PointCount(OutRec.Pts); - if (Cnt < 3) then Continue; + if not assigned(OutRec.Pts) then Continue; + + Op := OutRec.Pts.Prev; + Cnt := PointCount(Op); + if (Cnt < 2) then Continue; SetLength(Result[J], Cnt); - Op := OutRec.Pts; for K := 0 to Cnt -1 do begin - Result[J][K].X := Op.Pt.X; - Result[J][K].Y := Op.Pt.Y; + Result[J][K] := Op.Pt; Op := Op.Prev; end; Inc(J); @@ -3124,7 +3882,7 @@ function TClipper.GetResult: TPolygons; end; //------------------------------------------------------------------------------ -function TClipper.GetResult2(PolyTree: TPolyTree): Boolean; +function TClipper.BuildResult2(PolyTree: TPolyTree): Boolean; var I, J, Cnt, CntAll: Integer; Op: POutPt; @@ -3141,19 +3899,19 @@ function TClipper.GetResult2(PolyTree: TPolyTree): Boolean; begin OutRec := fPolyOutList[I]; Cnt := PointCount(OutRec.Pts); - if Cnt < 3 then Continue; + if (OutRec.IsOpen and (cnt < 2)) or + (not outRec.IsOpen and (cnt < 3)) then Continue; FixHoleLinkage(OutRec); PolyNode := TPolyNode.Create; PolyTree.FAllNodes[CntAll] := PolyNode; OutRec.PolyNode := PolyNode; Inc(CntAll); - SetLength(PolyNode.FPolygon, Cnt); - Op := OutRec.Pts; + SetLength(PolyNode.FPath, Cnt); + Op := OutRec.Pts.Prev; for J := 0 to Cnt -1 do begin - PolyNode.FPolygon[J].X := Op.Pt.X; - PolyNode.FPolygon[J].Y := Op.Pt.Y; + PolyNode.FPath[J] := Op.Pt; Op := Op.Prev; end; end; @@ -3165,8 +3923,14 @@ function TClipper.GetResult2(PolyTree: TPolyTree): Boolean; begin OutRec := fPolyOutList[I]; if Assigned(OutRec.PolyNode) then - if Assigned(OutRec.FirstLeft) then - OutRec.FirstLeft.PolyNode.AddChild(OutRec.PolyNode) else + if OutRec.IsOpen then + begin + OutRec.PolyNode.FIsOpen := true; + PolyTree.AddChild(OutRec.PolyNode); + end + else if Assigned(OutRec.FirstLeft) then + OutRec.FirstLeft.PolyNode.AddChild(OutRec.PolyNode) + else PolyTree.AddChild(OutRec.PolyNode); end; SetLength(PolyTree.FChilds, PolyTree.FCount); @@ -3181,23 +3945,24 @@ procedure TClipper.FixupOutPolygon(OutRec: POutRec); var PP, Tmp, LastOK: POutPt; begin - //FixupOutPolygon() - removes duplicate points and simplifies - //co-linear edges by removing the middle vertex. + //remove duplicate points and collinear edges LastOK := nil; - OutRec.BottomPt := nil; + OutRec.BottomPt := nil; //flag as stale PP := OutRec.Pts; while True do begin - if (PP.Prev = PP) or (PP.Next = PP.Prev) then + if (PP = PP.Prev) or (PP.Next = PP.Prev) then begin DisposePolyPts(PP); OutRec.Pts := nil; Exit; end; - //test for duplicate points and for co-linear edges ... - if PointsEqual(PP.Pt, PP.Next.Pt) or - SlopesEqual(PP.Prev.Pt, PP.Pt, PP.Next.Pt, FUse64BitRange) then + //test for duplicate points and collinear edges ... + if PointsEqual(PP.Pt, PP.Next.Pt) or PointsEqual(PP.Pt, PP.Prev.Pt) or + (SlopesEqual(PP.Prev.Pt, PP.Pt, PP.Next.Pt, FUse64BitRange) and + (not FPreserveCollinear or + not Pt2IsBetweenPt1AndPt3(PP.Prev.Pt, PP.Pt, PP.Next.Pt))) then begin //OK, we need to delete a point ... LastOK := nil; @@ -3270,144 +4035,273 @@ function TClipper.FixupIntersectionOrder: Boolean; end; //------------------------------------------------------------------------------ -function FindSegment(var PP: POutPt; UseFullInt64Range: Boolean; - var Pt1, Pt2: TIntPoint): Boolean; -var - Pp2: POutPt; - Pt1a, Pt2a: TIntPoint; +function DupOutPt(OutPt: POutPt; InsertAfter: Boolean = true): POutPt; begin - if not Assigned(PP) then begin Result := False; Exit; end; - Result := True; - Pt1a := Pt1; Pt2a := Pt2; - Pp2 := PP; - repeat - //test for co-linearity before testing for overlap ... - if SlopesEqual(Pt1a, Pt2a, PP.Pt, PP.Prev.Pt, UseFullInt64Range) and - SlopesEqual(Pt1a, Pt2a, PP.Pt, UseFullInt64Range) and - GetOverlapSegment(Pt1a, Pt2a, PP.Pt, PP.Prev.Pt, Pt1, Pt2) then Exit; - PP := PP.Next; - until PP = Pp2; - Result := False; + new(Result); + Result.Pt := OutPt.Pt; + Result.Idx := OutPt.Idx; + if InsertAfter then + begin + Result.Next := OutPt.Next; + Result.Prev := OutPt; + OutPt.Next.Prev := Result; + OutPt.Next := Result; + end else + begin + Result.Prev := OutPt.Prev; + Result.Next := OutPt; + OutPt.Prev.Next := Result; + OutPt.Prev := Result; + end; end; //------------------------------------------------------------------------------ -function Pt3IsBetweenPt1AndPt2(const Pt1, Pt2, Pt3: TIntPoint): Boolean; +function JoinHorz(Op1, Op1b, Op2, Op2b: POutPt; + const Pt: TIntPoint; DiscardLeft: Boolean): Boolean; +var + Dir1, Dir2: TDirection; begin - if PointsEqual(Pt1, Pt3) or PointsEqual(Pt2, Pt3) then Result := True - else if (Pt1.X <> Pt2.X) then Result := (Pt1.X < Pt3.X) = (Pt3.X < Pt2.X) - else Result := (Pt1.Y < Pt3.Y) = (Pt3.Y < Pt2.Y); -end; -//------------------------------------------------------------------------------ + if Op1.Pt.X > Op1b.Pt.X then Dir1 := dRightToLeft else Dir1 := dLeftToRight; + if Op2.Pt.X > Op2b.Pt.X then Dir2 := dRightToLeft else Dir2 := dLeftToRight; + Result := Dir1 <> Dir2; + if not Result then Exit; -function InsertPolyPtBetween(p1, P2: POutPt; const Pt: TIntPoint): POutPt; -begin - if (p1 = P2) then raise exception.Create(rsJoinError); + //When DiscardLeft, we want Op1b to be on the left of Op1, otherwise we + //want Op1b to be on the right. (And likewise with Op2 and Op2b.) + //To facilitate this while inserting Op1b & Op2b when DiscardLeft == true, + //make sure we're either AT or RIGHT OF Pt before adding Op1b, otherwise + //make sure we're AT or LEFT OF Pt. (Likewise with Op2b.) + if Dir1 = dLeftToRight then + begin + while (Op1.Next.Pt.X <= Pt.X) and + (Op1.Next.Pt.X >= Op1.Pt.X) and (Op1.Next.Pt.Y = Pt.Y) do + Op1 := Op1.Next; + if DiscardLeft and (Op1.Pt.X <> Pt.X) then Op1 := Op1.Next; + Op1b := DupOutPt(Op1, not DiscardLeft); + if not PointsEqual(Op1b.Pt, Pt) then + begin + Op1 := Op1b; + Op1.Pt := Pt; + Op1b := DupOutPt(Op1, not DiscardLeft); + end; + end else + begin + while (Op1.Next.Pt.X >= Pt.X) and + (Op1.Next.Pt.X <= Op1.Pt.X) and (Op1.Next.Pt.Y = Pt.Y) do + Op1 := Op1.Next; + if not DiscardLeft and (Op1.Pt.X <> Pt.X) then Op1 := Op1.Next; + Op1b := DupOutPt(Op1, DiscardLeft); + if not PointsEqual(Op1b.Pt, Pt) then + begin + Op1 := Op1b; + Op1.Pt := Pt; + Op1b := DupOutPt(Op1, DiscardLeft); + end; + end; + + if Dir2 = dLeftToRight then + begin + while (Op2.Next.Pt.X <= Pt.X) and + (Op2.Next.Pt.X >= Op2.Pt.X) and (Op2.Next.Pt.Y = Pt.Y) do + Op2 := Op2.Next; + if DiscardLeft and (Op2.Pt.X <> Pt.X) then Op2 := Op2.Next; + Op2b := DupOutPt(Op2, not DiscardLeft); + if not PointsEqual(Op2b.Pt, Pt) then + begin + Op2 := Op2b; + Op2.Pt := Pt; + Op2b := DupOutPt(Op2, not DiscardLeft); + end; + end else + begin + while (Op2.Next.Pt.X >= Pt.X) and + (Op2.Next.Pt.X <= Op2.Pt.X) and (Op2.Next.Pt.Y = Pt.Y) do + Op2 := Op2.Next; + if not DiscardLeft and (Op2.Pt.X <> Pt.X) then Op2 := Op2.Next; + Op2b := DupOutPt(Op2, DiscardLeft); + if not PointsEqual(Op2b.Pt, Pt) then + begin + Op2 := Op2b; + Op2.Pt := Pt; + Op2b := DupOutPt(Op2, DiscardLeft); + end; + end; - new(Result); - Result.Pt := Pt; - Result.Idx := p1.Idx; - if P2 = p1.Next then - begin - p1.Next := Result; - P2.Prev := Result; - Result.Next := P2; - Result.Prev := p1; - end else + if (Dir1 = dLeftToRight) = DiscardLeft then + begin + Op1.Prev := Op2; + Op2.Next := Op1; + Op1b.Next := Op2b; + Op2b.Prev := Op1b; + end + else begin - P2.Next := Result; - p1.Prev := Result; - Result.Next := p1; - Result.Prev := P2; + Op1.Next := Op2; + Op2.Prev := Op1; + Op1b.Prev := Op2b; + Op2b.Next := Op1b; end; end; //------------------------------------------------------------------------------ -function TClipper.JoinPoints(JR: PJoinRec; out P1, P2: POutPt): Boolean; +function TClipper.JoinPoints(Jr: PJoin; out P1, P2: POutPt): Boolean; var OutRec1, OutRec2: POutRec; - Prev, p3, p4, Pp1a, Pp2a: POutPt; - Pt1, Pt2, Pt3, Pt4: TIntPoint; + Op1, Op1b, Op2, Op2b: POutPt; + Pt: TIntPoint; + Reverse1, Reverse2, DiscardLeftSide: Boolean; + IsHorizontal: Boolean; + Left, Right: cInt; begin Result := False; - OutRec1 := FPolyOutList[Jr.Poly1Idx]; - OutRec2 := FPolyOutList[Jr.Poly2Idx]; - if not Assigned(OutRec1) then Exit; - if not Assigned(OutRec2) then Exit; - - Pp1a := OutRec1.Pts; - Pp2a := OutRec2.Pts; - Pt1 := Jr.Pt2a; Pt2 := Jr.Pt2b; - Pt3 := Jr.Pt1a; Pt4 := Jr.Pt1b; - if not FindSegment(Pp1a, FUse64BitRange, Pt1, Pt2) then Exit; - if (OutRec1 = OutRec2) then - begin - //we're searching the same polygon for overlapping segments so - //segment 2 mustn't be the same as segment 1 ... - Pp2a := Pp1a.Next; - if not FindSegment(Pp2a, FUse64BitRange, Pt3, Pt4) or (Pp2a = Pp1a) then - Exit; - end else - if not FindSegment(Pp2a, FUse64BitRange, Pt3, Pt4) then Exit; - if not GetOverlapSegment(Pt1, Pt2, Pt3, Pt4, Pt1, Pt2) then Exit; - - Prev := Pp1a.Prev; - if PointsEqual(Pp1a.Pt, Pt1) then P1 := Pp1a - else if PointsEqual(Prev.Pt, Pt1) then P1 := Prev - else P1 := InsertPolyPtBetween(Pp1a, Prev, Pt1); - - if PointsEqual(Pp1a.Pt, Pt2) then P2 := Pp1a - else if PointsEqual(Prev.Pt, Pt2) then P2 := Prev - else if (P1 = Pp1a) or (P1 = Prev) then - P2 := InsertPolyPtBetween(Pp1a, Prev, Pt2) - else if Pt3IsBetweenPt1AndPt2(Pp1a.Pt, P1.Pt, Pt2) then - P2 := InsertPolyPtBetween(Pp1a, P1, Pt2) - else - P2 := InsertPolyPtBetween(P1, Prev, Pt2); - - Prev := Pp2a.Prev; - if PointsEqual(Pp2a.Pt, Pt1) then p3 := Pp2a - else if PointsEqual(Prev.Pt, Pt1) then p3 := Prev - else p3 := InsertPolyPtBetween(Pp2a, Prev, Pt1); - - if PointsEqual(Pp2a.Pt, Pt2) then p4 := Pp2a - else if PointsEqual(Prev.Pt, Pt2) then p4 := Prev - else if (p3 = Pp2a) or (p3 = Prev) then - p4 := InsertPolyPtBetween(Pp2a, Prev, Pt2) - else if Pt3IsBetweenPt1AndPt2(Pp2a.Pt, p3.Pt, Pt2) then - p4 := InsertPolyPtBetween(Pp2a, p3, Pt2) - else - p4 := InsertPolyPtBetween(p3, Prev, Pt2); - if (P1.Next = P2) and (p3.Prev = p4) then - begin - P1.Next := p3; - p3.Prev := P1; - P2.Prev := p4; - p4.Next := P2; - Result := True; + OutRec1 := GetOutRec(Jr.OutPt1.Idx); + OutRec2 := GetOutRec(Jr.OutPt2.Idx); + Op1 := Jr.OutPt1; + Op2 := Jr.OutPt2; + + //There are 3 kinds of joins for output polygons ... + //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are a vertices anywhere + //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal). + //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same + //location at the bottom of the overlapping segment (& Join.OffPt is above). + //3. StrictSimple joins where edges touch but are not collinear and where + //Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point. + IsHorizontal := (Jr.OutPt1.Pt.Y = Jr.OffPt.Y); + + if IsHorizontal and PointsEqual(Jr.OffPt, Jr.OutPt1.Pt) and + PointsEqual(Jr.OffPt, Jr.OutPt2.Pt) then + begin + //Strictly Simple join ... + Op1b := Jr.OutPt1.Next; + while (Op1b <> Op1) and + PointsEqual(Op1b.Pt, Jr.OffPt) do Op1b := Op1b.Next; + Reverse1 := (Op1b.Pt.Y > Jr.OffPt.Y); + Op2b := Jr.OutPt2.Next; + while (Op2b <> Op2) and + PointsEqual(Op2b.Pt, Jr.OffPt) do Op2b := Op2b.Next; + Reverse2 := (Op2b.Pt.Y > Jr.OffPt.Y); + if (Reverse1 = Reverse2) then Exit; + if Reverse1 then + begin + Op1b := DupOutPt(Op1, False); + Op2b := DupOutPt(Op2, True); + Op1.Prev := Op2; + Op2.Next := Op1; + Op1b.Next := Op2b; + Op2b.Prev := Op1b; + P1 := Op1; + P2 := Op1b; + Result := True; + end else + begin + Op1b := DupOutPt(Op1, True); + Op2b := DupOutPt(Op2, False); + Op1.Next := Op2; + Op2.Prev := Op1; + Op1b.Prev := Op2b; + Op2b.Next := Op1b; + P1 := Op1; + P2 := Op1b; + Result := True; + end; end - else if (P1.Prev = P2) and (p3.Next = p4) then - begin - P1.Prev := p3; - p3.Next := P1; - P2.Next := p4; - p4.Prev := P2; - Result := True; - end; -end; -//------------------------------------------------------------------------------ + else if IsHorizontal then + begin + op1b := op1; + while (op1.Prev.Pt.Y = op1.Pt.Y) and + (op1.Prev <> Op1b) and (op1.Prev <> op2) do + op1 := op1.Prev; + while (op1b.Next.Pt.Y = op1b.Pt.Y) and + (op1b.Next <> Op1) and (op1b.Next <> op2) do + op1b := op1b.Next; + if (op1b.Next = Op1) or (op1b.Next = op2) then Exit; //a flat 'polygon' + + op2b := op2; + while (op2.Prev.Pt.Y = op2.Pt.Y) and + (op2.Prev <> Op2b) and (op2.Prev <> op1b) do + op2 := op2.Prev; + while (op2b.Next.Pt.Y = op2b.Pt.Y) and + (op2b.Next <> Op2) and (op2b.Next <> op1) do + op2b := op2b.Next; + if (op2b.Next = Op2) or (op2b.Next = op1) then Exit; //a flat 'polygon' + + //Op1 --> Op1b & Op2 --> Op2b are the extremites of the horizontal edges + if not GetOverlap(Op1.Pt.X, Op1b.Pt.X, Op2.Pt.X, Op2b.Pt.X, Left, Right) then + Exit; -procedure TClipper.FixupJoinRecs(JR: PJoinRec; Pt: POutPt; StartIdx: Integer); -var - JR2: PJoinRec; -begin - for StartIdx := StartIdx to FJoinList.count -1 do + //DiscardLeftSide: when joining overlapping edges, a spike will be created + //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up + //on the discard side as either may still be needed for other joins ... + if (Op1.Pt.X >= Left) and (Op1.Pt.X <= Right) then + begin + Pt := Op1.Pt; DiscardLeftSide := Op1.Pt.X > Op1b.Pt.X; + end else if (Op2.Pt.X >= Left) and (Op2.Pt.X <= Right) then + begin + Pt := Op2.Pt; DiscardLeftSide := Op2.Pt.X > Op2b.Pt.X; + end else if (Op1b.Pt.X >= Left) and (Op1b.Pt.X <= Right) then + begin + Pt := Op1b.Pt; DiscardLeftSide := Op1b.Pt.X > Op1.Pt.X; + end else + begin + Pt := Op2b.Pt; DiscardLeftSide := Op2b.Pt.X > Op2.Pt.X; + end; + + Result := JoinHorz(Op1, Op1b, Op2, Op2b, Pt, DiscardLeftSide); + if not Result then Exit; + P1 := Op1; P2 := Op2; + end else begin - Jr2 := FJoinList[StartIdx]; - if (Jr2.Poly1Idx = Jr.Poly1Idx) and PointIsVertex(Jr2.Pt1a, Pt) then - Jr2.Poly1Idx := Jr.Poly2Idx; - if (Jr2.Poly2Idx = Jr.Poly1Idx) and PointIsVertex(Jr2.Pt2a, Pt) then - Jr2.Poly2Idx := Jr.Poly2Idx; + //make sure the polygons are correctly oriented ... + Op1b := Op1.Next; + while PointsEqual(Op1b.Pt, Op1.Pt) and (Op1b <> Op1) do Op1b := Op1b.Next; + Reverse1 := (Op1b.Pt.Y > Op1.Pt.Y) or + not SlopesEqual(Op1.Pt, Op1b.Pt, Jr.OffPt, FUse64BitRange); + if Reverse1 then + begin + Op1b := Op1.Prev; + while PointsEqual(Op1b.Pt, Op1.Pt) and (Op1b <> Op1) do Op1b := Op1b.Prev; + if (Op1b.Pt.Y > Op1.Pt.Y) or + not SlopesEqual(Op1.Pt, Op1b.Pt, Jr.OffPt, FUse64BitRange) then Exit; + end; + Op2b := Op2.Next; + while PointsEqual(Op2b.Pt, Op2.Pt) and (Op2b <> Op2) do Op2b := Op2b.Next; + Reverse2 := (Op2b.Pt.Y > Op2.Pt.Y) or + not SlopesEqual(Op2.Pt, Op2b.Pt, Jr.OffPt, FUse64BitRange); + if Reverse2 then + begin + Op2b := Op2.Prev; + while PointsEqual(Op2b.Pt, Op2.Pt) and (Op2b <> Op2) do Op2b := Op2b.Prev; + if (Op2b.Pt.Y > Op2.Pt.Y) or + not SlopesEqual(Op2.Pt, Op2b.Pt, Jr.OffPt, FUse64BitRange) then Exit; + end; + + if (Op1b = Op1) or (Op2b = Op2) or (Op1b = Op2b) or + ((OutRec1 = OutRec2) and (Reverse1 = Reverse2)) then Exit; + + if Reverse1 then + begin + Op1b := DupOutPt(Op1, False); + Op2b := DupOutPt(Op2, True); + Op1.Prev := Op2; + Op2.Next := Op1; + Op1b.Next := Op2b; + Op2b.Prev := Op1b; + P1 := Op1; + P2 := Op1b; + Result := True; + end else + begin + Op1b := DupOutPt(Op1, True); + Op2b := DupOutPt(Op2, False); + Op1.Next := Op2; + Op2.Prev := Op1; + Op1b.Prev := Op2b; + Op2b.Next := Op1b; + P1 := Op1; + P2 := Op1b; + Result := True; + end; end; end; //------------------------------------------------------------------------------ @@ -3466,7 +4360,7 @@ procedure TClipper.FixupFirstLefts2(OldOutRec, NewOutRec: POutRec); procedure TClipper.JoinCommonEdges; var I: Integer; - Jr: PJoinRec; + Jr: PJoin; OutRec1, OutRec2, HoleStateRec: POutRec; P1, P2: POutPt; begin @@ -3474,10 +4368,11 @@ procedure TClipper.JoinCommonEdges; begin Jr := FJoinList[I]; - OutRec1 := GetOutRec(Jr.Poly1Idx); - OutRec2 := GetOutRec(Jr.Poly2Idx); + OutRec1 := GetOutRec(Jr.OutPt1.Idx); + OutRec2 := GetOutRec(Jr.OutPt2.Idx); if not Assigned(OutRec1.Pts) or not Assigned(OutRec2.Pts) then Continue; + if OutRec1.IsOpen or OutRec2.IsOpen then Continue; //get the polygon fragment with the correct hole state (FirstLeft) //before calling JoinPoints() ... @@ -3486,34 +4381,31 @@ procedure TClipper.JoinCommonEdges; else if Param1RightOfParam2(OutRec2, OutRec1) then HoleStateRec := OutRec1 else HoleStateRec := GetLowermostRec(OutRec1, OutRec2); - if not JoinPoints(JR, P1, P2) then Continue; + if not JoinPoints(Jr, P1, P2) then Continue; if (OutRec1 = OutRec2) then begin //instead of joining two polygons, we've just created a new one by //splitting one polygon into two. - OutRec1.Pts := P1; + OutRec1.Pts := P1; //Jr.OutPt1 OutRec1.BottomPt := nil; OutRec2 := CreateOutRec; OutRec2.Pts := P2; - Jr.Poly2Idx := OutRec2.Idx; + //update all OutRec2.Pts idx's ... + UpdateOutPtIdxs(OutRec2); + + //sort out the hole states of both polygon ... if Poly2ContainsPoly1(OutRec2.Pts, OutRec1.Pts, FUse64BitRange) then begin //OutRec2 is contained by OutRec1 ... OutRec2.IsHole := not OutRec1.IsHole; OutRec2.FirstLeft := OutRec1; - //now fixup any subsequent joins that match the new polygon ... - FixupJoinRecs(Jr, P2, I + 1); - //fixup FirstLeft pointers that may need reassigning to OutRec1 if FUsingPolyTree then FixupFirstLefts2(OutRec2, OutRec1); - FixupOutPolygon(OutRec1); //nb: do this BEFORE testing orientation - FixupOutPolygon(OutRec2); // but AFTER calling FixupJoinRecs() - - if (OutRec2.IsHole xor FReverseOutput) = (Area(OutRec2, FUse64BitRange) > 0) then + if (OutRec2.IsHole xor FReverseOutput) = (Area(OutRec2) > 0) then ReversePolyPtLinks(OutRec2.Pts); end else if Poly2ContainsPoly1(OutRec1.Pts, OutRec2.Pts, FUse64BitRange) then begin @@ -3523,16 +4415,10 @@ procedure TClipper.JoinCommonEdges; OutRec2.FirstLeft := OutRec1.FirstLeft; OutRec1.FirstLeft := OutRec2; - //now fixup any subsequent joins that match the new polygon ... - FixupJoinRecs(Jr, P2, I + 1); - //fixup FirstLeft pointers that may need reassigning to OutRec1 if FUsingPolyTree then FixupFirstLefts2(OutRec1, OutRec2); - FixupOutPolygon(OutRec1); //nb: do this BEFORE testing orientation - FixupOutPolygon(OutRec2); // but AFTER calling PointIsVertex() - - if (OutRec1.IsHole xor FReverseOutput) = (Area(OutRec1, FUse64BitRange) > 0) then + if (OutRec1.IsHole xor FReverseOutput) = (Area(OutRec1) > 0) then ReversePolyPtLinks(OutRec1.Pts); end else begin @@ -3540,22 +4426,13 @@ procedure TClipper.JoinCommonEdges; OutRec2.IsHole := OutRec1.IsHole; OutRec2.FirstLeft := OutRec1.FirstLeft; - //now fixup any subsequent joins that match the new polygon ... - FixupJoinRecs(Jr, P2, I + 1); - //fixup FirstLeft pointers that may need reassigning to OutRec2 if FUsingPolyTree then FixupFirstLefts1(OutRec1, OutRec2); - - FixupOutPolygon(OutRec1); //nb: do this AFTER calling PointIsVertex() - FixupOutPolygon(OutRec2); // in FixupJoinRecs() end; end else begin //joined 2 polygons together ... - //cleanup edges ... - FixupOutPolygon(OutRec1); - //delete the obsolete pointer ... OutRec2.Pts := nil; OutRec2.BottomPt := nil; @@ -3573,18 +4450,6 @@ procedure TClipper.JoinCommonEdges; end; //------------------------------------------------------------------------------ -procedure UpdateOutPtIdxs(OutRec: POutRec); -var - op: POutPt; -begin - op := OutRec.Pts; - repeat - op.Idx := OutRec.Idx; - op := op.Prev; - until op = OutRec.Pts; -end; -//------------------------------------------------------------------------------ - procedure TClipper.DoSimplePolygons; var I: Integer; @@ -3598,7 +4463,7 @@ procedure TClipper.DoSimplePolygons; inc(I); Op := OutRec1.Pts; if not assigned(OP) then Continue; - repeat //for each Pt in Polygon until duplicate found do ... + repeat //for each Pt in Path until duplicate found do ... Op2 := Op.Next; while (Op2 <> OutRec1.Pts) do begin @@ -3618,6 +4483,7 @@ procedure TClipper.DoSimplePolygons; OutRec2 := CreateOutRec; OutRec2.Pts := Op2; UpdateOutPtIdxs(OutRec2); + if Poly2ContainsPoly1(OutRec2.Pts, OutRec1.Pts, FUse64BitRange) then begin //OutRec2 is contained by OutRec1 ... @@ -3648,7 +4514,7 @@ procedure TClipper.DoSimplePolygons; end; //------------------------------------------------------------------------------ -// OffsetPolygons ... +// OffsetPaths ... //------------------------------------------------------------------------------ function GetUnitNormal(const Pt1, Pt2: TIntPoint): TDoublePoint; @@ -3672,56 +4538,7 @@ function GetUnitNormal(const Pt1, Pt2: TIntPoint): TDoublePoint; end; //------------------------------------------------------------------------------ -//Notes on the number of steps used to build an arc: -//Given S = arbitrary no. steps used to construct chords approximating a CIRCLE, -//then the angle (A) of each step = 2 * Pi / S -//The chord between two steps (pt1) & (pt2) is perpendicular to the line -//segment between the circle's center (pt3) to the chord's midpoint (pt4). -//Let the length of the line segment (pt3) & (Pt4) = D, and let the distance -//from the chord's midpoint (pt4) to the circle = Q, such that R - Q = D -//If Q is a pre-defined constant (ie the maximum allowed deviation from circle), -//then given that cos(angle) = adjacent/hypotenuse ... -// cos(A/2) = D/R -// = (R - Q)/R -// = 1 - Q/R -// A/2 = ArcCos(1 - Q/R) -// A = 2 * ArcCos(1 - Q/R) -//2 * Pi / S = 2 * ArcCos(1 - Q/R) -// S = Pi / ArcCos(1 - Q/R) -//Instead of a CIRCLE, given an ARC from angle A1 to angle A2 ... -// ArcFrac = Abs(A2 - A1)/(2 * Pi) -// Steps = ArcFrac * Pi / ArcCos(1 - Q/R) -function BuildArc(const Pt: TIntPoint; - A1, A2, R: Single; Limit: Double): TPolygon; -var - I: Integer; - Steps: Int64; - X, X2, Y, ArcFrac: Double; - S, C: Extended; -begin - ArcFrac := Abs(A2 - A1) / (2 * Pi); - //Limit == Q in comments above ... - Steps := Trunc(ArcFrac * Pi / ArcCos(1 - Limit / Abs(R))); - if Steps < 2 then Steps := 2 - else if Steps > 222.0 * ArcFrac then //ie R > 10000 * Limit - Steps := Trunc(222.0 * ArcFrac); - - Math.SinCos(A1, S, C); - X := C; Y := S; - Math.SinCos((A2 - A1) / Steps, S, C); - SetLength(Result, Steps + 1); - for I := 0 to Steps do - begin - Result[I].X := Pt.X + Round(X * R); - Result[I].Y := Pt.Y + Round(Y * R); - X2 := X; - X := X * C - S * Y; //cross product & dot product here ... - Y := X2 * S + Y * C; //avoids repeat calls to the much slower SinCos() - end; -end; -//------------------------------------------------------------------------------ - -function GetBounds(const Pts: TPolygons): TIntRect; +function GetBounds(const Pts: TPaths): TIntRect; var I,J: Integer; begin @@ -3749,24 +4566,25 @@ function GetBounds(const Pts: TPolygons): TIntRect; TOffsetBuilder = class private FDelta: Double; - FJoinType: TJoinType; - FLimit: Double; + FSinA, FSin, FCos: Extended; + FMiterLim, FSteps360: Double; FNorms: TArrayOfDoublePoint; - FSolution: TPolygons; + FSolution: TPaths; FOutPos: Integer; - FInP: TPolygon; - FOutP: TPolygon; + FInP: TPath; + FOutP: TPath; procedure AddPoint(const Pt: TIntPoint); procedure DoSquare(J, K: Integer); procedure DoMiter(J, K: Integer; R: Double); procedure DoRound(J, K: Integer); - function OffsetPoint(J, K: Integer; RMin: Double): Integer; + procedure OffsetPoint(J: Integer; + var K: Integer; JoinType: TJoinType); public - constructor Create(const Pts: TPolygons; Delta: Double; - IsPolygon: Boolean; JoinType: TJoinType; EndType: TEndType; + constructor Create(const Pts: TPaths; Delta: Double; + JoinType: TJoinType; EndType: TEndType; Limit: Double = 0); - property Solution: TPolygons read FSolution; + property Solution: TPaths read FSolution; end; //------------------------------------------------------------------------------ @@ -3785,138 +4603,117 @@ procedure TOffsetBuilder.AddPoint(const Pt: TIntPoint); procedure TOffsetBuilder.DoSquare(J, K: Integer); var - A1, A2, Dx: Double; - Pt1, Pt2: TIntPoint; -begin - Pt1.X := round(FInP[J].X + FNorms[K].X * FDelta); - Pt1.Y := round(FInP[J].Y + FNorms[K].Y * FDelta); - Pt2.X := round(FInP[J].X + FNorms[J].X * FDelta); - Pt2.Y := round(FInP[J].Y + FNorms[J].Y * FDelta); - if ((FNorms[K].X * FNorms[J].Y - - FNorms[J].X * FNorms[K].Y) * FDelta >= 0) then - begin - A1 := ArcTan2(FNorms[K].Y, FNorms[K].X); - A2 := ArcTan2(-FNorms[J].Y, -FNorms[J].X); - A1 := abs(A2 - A1); - if A1 > pi then A1 := pi*2 - A1; - Dx := tan((pi - A1)/4) * abs(FDelta); - Pt1 := IntPoint(round(Pt1.X -FNorms[K].Y * Dx), - round(Pt1.Y + FNorms[K].X * Dx)); - AddPoint(Pt1); - Pt2 := IntPoint(round(Pt2.X + FNorms[J].Y * Dx), - round(Pt2.Y - FNorms[J].X * Dx)); - AddPoint(Pt2); - end else - begin - AddPoint(Pt1); - AddPoint(FInP[J]); - AddPoint(Pt2); - end; + A, Dx: Double; +begin + //see offset_triginometry.svg in the documentation folder ... + A := ArcTan2(FSinA, FNorms[K].X * FNorms[J].X + FNorms[K].Y * FNorms[J].Y); + Dx := tan(A/4); + AddPoint(IntPoint( + round(FInP[J].X + FDelta * (FNorms[K].X - FNorms[K].Y *Dx)), + round(FInP[J].Y + FDelta * (FNorms[K].Y + FNorms[K].X *Dx)))); + AddPoint(IntPoint( + round(FInP[J].X + FDelta * (FNorms[J].X + FNorms[J].Y *Dx)), + round(FInP[J].Y + FDelta * (FNorms[J].Y - FNorms[J].X *Dx)))); end; //------------------------------------------------------------------------------ procedure TOffsetBuilder.DoMiter(J, K: Integer; R: Double); var Q: Double; - Pt1, Pt2: TIntPoint; begin - if ((FNorms[K].X * FNorms[J].Y - - FNorms[J].X * FNorms[K].Y) * FDelta >= 0) then - begin - Q := FDelta / R; - AddPoint(IntPoint(round(FInP[J].X + (FNorms[K].X + FNorms[J].X)*Q), - round(FInP[J].Y + (FNorms[K].Y + FNorms[J].Y)*Q))); - end else - begin - Pt1.X := round(FInP[J].X + FNorms[K].X * FDelta); - Pt1.Y := round(FInP[J].Y + FNorms[K].Y * FDelta); - Pt2.X := round(FInP[J].X + FNorms[J].X * FDelta); - Pt2.Y := round(FInP[J].Y + FNorms[J].Y * FDelta); - AddPoint(Pt1); - AddPoint(FInP[J]); - AddPoint(Pt2); - end; + Q := FDelta / R; + AddPoint(IntPoint(round(FInP[J].X + (FNorms[K].X + FNorms[J].X)*Q), + round(FInP[J].Y + (FNorms[K].Y + FNorms[J].Y)*Q))); end; //------------------------------------------------------------------------------ procedure TOffsetBuilder.DoRound(J, K: Integer); var - M: Integer; - A1, A2: Double; - Pt1, Pt2: TIntPoint; - Arc: TPolygon; -begin - Pt1.X := round(FInP[J].X + FNorms[K].X * FDelta); - Pt1.Y := round(FInP[J].Y + FNorms[K].Y * FDelta); - Pt2.X := round(FInP[J].X + FNorms[J].X * FDelta); - Pt2.Y := round(FInP[J].Y + FNorms[J].Y * FDelta); - AddPoint(Pt1); - //round off reflex angles (ie > 180 deg) unless almost flat (ie < 10deg). - //(N1.X * N2.Y - N2.X * N1.Y) == unit normal "cross product" == sin(angle) - //(N1.X * N2.X + N1.Y * N2.Y) == unit normal "dot product" == cos(angle) - //dot product Normals == 1 -> no angle - if (FNorms[K].X * FNorms[J].Y - - FNorms[J].X * FNorms[K].Y) * FDelta >= 0 then - begin - if ((FNorms[J].X * FNorms[K].X - + FNorms[J].Y * FNorms[K].Y) < 0.985) then - begin - A1 := ArcTan2(FNorms[K].Y, FNorms[K].X); - A2 := ArcTan2(FNorms[J].Y, FNorms[J].X); - if (FDelta > 0) and (A2 < A1) then A2 := A2 + pi*2 - else if (FDelta < 0) and (A2 > A1) then A2 := A2 - pi*2; - Arc := BuildArc(FInP[J], A1, A2, FDelta, FLimit); - for M := 0 to high(Arc) do AddPoint(Arc[M]); - end; - end else - AddPoint(FInP[J]); - AddPoint(Pt2); + I, Steps: Integer; + A, X, X2, Y: Double; +begin + A := ArcTan2(FSinA, FNorms[K].X * FNorms[J].X + FNorms[K].Y * FNorms[J].Y); + Steps := Round(FSteps360 * Abs(A)); + + X := FNorms[K].X; + Y := FNorms[K].Y; + for I := 1 to Steps do + begin + AddPoint(IntPoint( + round(FInP[J].X + X * FDelta), + round(FInP[J].Y + Y * FDelta))); + X2 := X; + X := X * FCos - FSin * Y; + Y := X2 * FSin + Y * FCos; + end; + AddPoint(IntPoint( + round(FInP[J].X + FNorms[J].X * FDelta), + round(FInP[J].Y + FNorms[J].Y * FDelta))); end; //------------------------------------------------------------------------------ -function TOffsetBuilder.OffsetPoint(J, K: Integer; RMin: Double): Integer; +procedure TOffsetBuilder.OffsetPoint(J: Integer; + var K: Integer; JoinType: TJoinType); var R: Double; begin - case FJoinType of - jtMiter: - begin - R := 1 + (FNorms[J].X * FNorms[K].X + FNorms[J].Y * FNorms[K].Y); - if (R >= RMin) then DoMiter(J, K, R) - else DoSquare(J, K); + FSinA := (FNorms[K].X * FNorms[J].Y - FNorms[J].X * FNorms[K].Y); + if (FSinA < 0.00005) and (FSinA > -0.00005) then Exit + else if (FSinA > 1.0) then FSinA := 1.0 + else if (FSinA < -1.0) then FSinA := -1.0; + + if FSinA * FDelta < 0 then + begin + AddPoint(IntPoint(round(FInP[J].X + FNorms[K].X * FDelta), + round(FInP[J].Y + FNorms[K].Y * FDelta))); + AddPoint(FInP[J]); + AddPoint(IntPoint(round(FInP[J].X + FNorms[J].X * FDelta), + round(FInP[J].Y + FNorms[J].Y * FDelta))); + end + else + case JoinType of + jtMiter: + begin + R := 1 + (FNorms[J].X * FNorms[K].X + FNorms[J].Y * FNorms[K].Y); + if (R >= FMiterLim) then DoMiter(J, K, R) + else DoSquare(J, K); + end; + jtSquare: DoSquare(J, K); + jtRound: DoRound(J, K); end; - jtSquare: DoSquare(J, K); - jtRound: DoRound(J, K); - end; - Result := J; + K := J; end; //------------------------------------------------------------------------------ -constructor TOffsetBuilder.Create(const Pts: TPolygons; Delta: Double; - IsPolygon: Boolean; JoinType: TJoinType; EndType: TEndType; Limit: Double = 0); +constructor TOffsetBuilder.Create(const Pts: TPaths; Delta: Double; + JoinType: TJoinType; EndType: TEndType; Limit: Double = 0); var I, J, K, Len: Integer; - R, RMin: Double; - Outer: TPolygon; + Outer: TPath; Bounds: TIntRect; - ForceClose: Boolean; + X,X2,Y: Double; begin FSolution := nil; - RMin := 0.5; - FJoinType := JoinType; - if not IsPolygon and (Delta < 0) then Delta := -Delta; + if (EndType <> etClosed) and (Delta < 0) then Delta := -Delta; FDelta := Delta; - - if FJoinType = jtMiter then + if JoinType = jtMiter then begin - if Limit > 2 then RMin := 2/(sqr(Limit)); - FLimit := 0.25; //just in case EndType == etRound - end else + //FMiterConst: see offset_triginometry3.svg in the documentation folder ... + if Limit > 2 then FMiterLim := 2/(sqr(Limit)) + else FMiterLim := 0.5; + if EndType = etRound then Limit := 0.25; + end; + + if (JoinType = jtRound) or (EndType = etRound) then begin - if Limit <= 0 then FLimit := 0.25 - else if Limit > abs(FDelta) then FLimit := abs(FDelta) - else FLimit := Limit; + if (Limit <= 0) then Limit := 0.25 + else if Limit > abs(FDelta) * 0.25 then Limit := abs(FDelta) * 0.25; + //FRoundConst: see offset_triginometry2.svg in the documentation folder ... + FSteps360 := Pi / ArcCos(1 - Limit / Abs(FDelta)); + Math.SinCos(2 * Pi / FSteps360, FSin, FCos); + FSteps360 := FSteps360 / (Pi * 2); + if FDelta < 0 then FSin := -FSin; end; SetLength(FSolution, length(Pts)); @@ -3926,22 +4723,45 @@ constructor TOffsetBuilder.Create(const Pts: TPolygons; Delta: Double; FInP := Pts[I]; Len := length(FInP); - if (Len = 0) or ((Len < 3) and (FDelta <= 0)) then - Continue - else if (Len = 1) then + if (Len = 0) or ((Len < 3) and (FDelta <= 0)) then Continue; + + //if a single vertex then build circle or a square ... + if (Len = 1) then begin - FInP := BuildArc(FInP[0], 0, 2*pi, FDelta, Limit); + if JoinType = jtRound then + begin + X := 1; Y := 0; + for J := 1 to Round(FSteps360 * 2 * Pi) do + begin + AddPoint(IntPoint( + Round(FInP[0].X + X * FDelta), + Round(FInP[0].Y + Y * FDelta))); + X2 := X; + X := X * FCos - FSin * Y; + Y := X2 * FSin + Y * FCos; + end + end else + begin + X := -1; Y := -1; + for J := 1 to 4 do + begin + AddPoint(IntPoint( Round(FInP[0].X + X * FDelta), + Round(FInP[0].Y + Y * FDelta))); + if X < 0 then X := 1 + else if Y < 0 then Y := 1 + else X := -1; + end; + end; + SetLength(FOutP, FOutPos); + FSolution[I] := FOutP; Continue; end; - ForceClose := PointsEqual(FInP[0], FInP[Len -1]); - if ForceClose then dec(Len); - //build Normals ... SetLength(FNorms, Len); for J := 0 to Len-2 do FNorms[J] := GetUnitNormal(FInP[J], FInP[J+1]); - if IsPolygon or ForceClose then + if (EndType = etClosed) then FNorms[Len-1] := GetUnitNormal(FInP[Len-1], FInP[0]) else FNorms[Len-1] := FNorms[Len-2]; @@ -3949,36 +4769,19 @@ constructor TOffsetBuilder.Create(const Pts: TPolygons; Delta: Double; FOutPos := 0; FOutP := nil; - if IsPolygon or ForceClose then + if (EndType = etClosed) then begin K := Len -1; for J := 0 to Len-1 do - K := OffsetPoint(J, K, RMin); + OffsetPoint(J, K, JoinType); SetLength(FOutP, FOutPos); FSolution[I] := FOutP; - - if not IsPolygon then - begin - FOutPos := 0; - FOutP := nil; - FDelta := -FDelta; - - K := Len -1; - for J := 0 to Len-1 do - K := OffsetPoint(J, K, RMin); - - FDelta := -FDelta; - SetLength(FOutP, FOutPos); - J := Length(FSolution); - setLength(FSolution, J +1); - FSolution[J] := ReversePolygon(FOutP); - end; end else //is polyline begin K := 0; //offset the polyline going forward ... for J := 1 to Len-2 do - K := OffsetPoint(J, K, RMin); + OffsetPoint(J, K, JoinType); //handle the end (butt, round or square) ... if EndType = etButt then @@ -3994,8 +4797,10 @@ constructor TOffsetBuilder.Create(const Pts: TPolygons; Delta: Double; K := Len - 2; FNorms[J].X := -FNorms[J].X; FNorms[J].Y := -FNorms[J].Y; - if EndType = etSquare then DoSquare(J, K) - else DoRound(J, K); + FSinA := 0; + if EndType = etSquare then + DoSquare(J, K) else + DoRound(J, K); end; //re-build Normals ... @@ -4010,7 +4815,7 @@ constructor TOffsetBuilder.Create(const Pts: TPolygons; Delta: Double; //offset the polyline going backward ... K := Len -1; for J := Len -2 downto 1 do - K := OffsetPoint(J, K, RMin); + OffsetPoint(J, K, JoinType); //finally handle the start (butt, round or square) ... if EndType = etButt then @@ -4021,18 +4826,20 @@ constructor TOffsetBuilder.Create(const Pts: TPolygons; Delta: Double; round(FInP[0].Y + FNorms[0].Y * FDelta))); end else begin - if EndType = etSquare then DoSquare(0, 1) - else DoRound(0, 1); + FSinA := 0; + if EndType = etSquare then + DoSquare(0, 1) else + DoRound(0, 1); end; SetLength(FOutP, FOutPos); FSolution[I] := FOutP; end; end; - //finally, clean up untidy corners ... + //now clean up untidy corners ... with TClipper.Create do try - AddPolygons(FSolution, ptSubject); + AddPaths(FSolution, ptSubject, True); if Delta > 0 then begin Execute(ctUnion, FSolution, pftPositive, pftPositive); @@ -4044,7 +4851,7 @@ constructor TOffsetBuilder.Create(const Pts: TPolygons; Delta: Double; Outer[1] := IntPoint(Bounds.right+10, Bounds.bottom+10); Outer[2] := IntPoint(Bounds.right+10, Bounds.top-10); Outer[3] := IntPoint(Bounds.left-10, Bounds.top-10); - AddPolygon(Outer, ptSubject); + AddPath(Outer, ptSubject, True); ReverseSolution := True; Execute(ctUnion, FSolution, pftNegative, pftNegative); //delete the outer rectangle ... @@ -4058,128 +4865,81 @@ constructor TOffsetBuilder.Create(const Pts: TPolygons; Delta: Double; end; //------------------------------------------------------------------------------ -function BuildOffset(const Pts: TPolygons; Delta: Double; IsPolygon: Boolean; - JoinType: TJoinType; EndType: TEndType; Limit: Double = 0): TPolygons; -begin - with TOffsetBuilder.Create(Pts, Delta, IsPolygon, JoinType, EndType, Limit) do - try - result := Solution; - finally - Free; - end; -end; -//------------------------------------------------------------------------------ - -function UpdateBotPt(const Pt: TIntPoint; var BotPt: TIntPoint): Boolean; -begin - if (pt.Y > BotPt.Y) or ((pt.Y = BotPt.Y) and (Pt.X < BotPt.X)) then - begin - BotPt := Pt; - Result := True; - end - else Result := False; -end; -//------------------------------------------------------------------------------ - -function OffsetPolygons(const Polys: TPolygons; const Delta: Double; - JoinType: TJoinType = jtSquare; Limit: Double = 0; - AutoFix: Boolean = True): TPolygons; -var - I, J, K, Len, BotI: Integer; - Pts: TPolygons; - BotPt: TIntPoint; -begin - Pts := Polys; - Result := nil; - //AutoFix - fixes polygon orientation if necessary and removes - //duplicate vertices. Can be set False when you're sure that polygon - //orientation is correct and that there are no duplicate vertices. - if AutoFix then - begin - Len := Length(Polys); - SetLength(Pts, Len); - BotI := 0; //index of outermost polygon - while (BotI < Len) and (Length(Polys[BotI]) = 0) do Inc(BotI); - if (BotI = Len) then Exit; - BotPt := Polys[BotI][0]; - for I := BotI to Len - 1 do - begin - Len := Length(Polys[I]); - SetLength(Pts[I], Len); - if Len = 0 then Continue; - Pts[I][0] := Polys[I][0]; - if UpdateBotPt(Pts[I][0], BotPt) then BotI := I; - K := 0; - for J := 1 to Len - 1 do - if not PointsEqual(Pts[I][K], Polys[I][J]) then - begin - Inc(K); - Pts[I][K] := Polys[I][J]; - if UpdateBotPt(Pts[I][K], BotPt) then BotI := I; - end; - if K + 1 < Len then - SetLength(Pts[I], K + 1); - end; - if not Orientation(Pts[BotI]) then - Pts := ReversePolygons(Pts); - end; - Result := BuildOffset(Pts, Delta, True, JoinType, etButt, Limit); -end; -//------------------------------------------------------------------------------ - -function StripDups(const Poly: TPolygon): TPolygon; +function StripDupsAndGetBotPt(const Poly: TPath; Closed: Boolean; + out BotPt: PIntPoint): TPath; var I, J, Len: Integer; begin + Result := nil; + BotPt := nil; Len := Length(Poly); - SetLength(Result, Len); + if Closed then + while (Len > 0) and PointsEqual(Poly[0], Poly[Len -1]) do Dec(Len); if Len = 0 then Exit; + SetLength(Result, Len); J := 0; Result[0] := Poly[0]; + BotPt := @Result[0]; for I := 1 to Len - 1 do if not PointsEqual(Poly[I], Result[J]) then begin Inc(J); Result[J] := Poly[I]; + if Result[J].Y > BotPt.Y then + BotPt := @Result[J] + else if (Result[J].Y = BotPt.Y) and (Result[J].X < BotPt.X) then + BotPt := @Result[J]; end; Inc(J); - if J < Len then SetLength(Result, J); + if (J < 2) or (Closed and (J = 2)) then J := 0; + SetLength(Result, J); end; //------------------------------------------------------------------------------ -function OffsetPolyLines(const Lines: TPolygons; Delta: Double; - JoinType: TJoinType = jtSquare; EndType: TEndType = etSquare; - Limit: Double = 0): TPolygons; +function OffsetPaths(const Polys: TPaths; const Delta: Double; + JoinType: TJoinType = jtSquare; EndType: TEndType = etClosed; + Limit: Double = 0): TPaths; var - I, Len: Integer; - Pts: TPolygons; + I, Len, BotI: Integer; + Pts: TPaths; + BotPt, Pt: PIntPoint; begin - //automatically strip duplicate points because it gets complicated with - //open and closed lines and when to strip duplicates across begin-end ... - Pts := Lines; - Len := Length(Pts); + Result := nil; + Len := Length(Polys); SetLength(Pts, Len); + BotPt := nil; + BotI := -1; + //BotPt => lower most and left most point which must be an outer polygon for I := 0 to Len -1 do - Pts[I] := StripDups(Lines[I]); - - if EndType = etClosed then begin - SetLength(Pts, Len *2); - for I := 0 to Len -1 do - Pts[Len + I] := ReversePolygon(Pts[I]); - Result := BuildOffset(Pts, Delta, True, JoinType, EndType, Limit); - end - else - Result := BuildOffset(Pts, Delta, False, JoinType, EndType, Limit); + Pts[I] := StripDupsAndGetBotPt(Polys[I], EndType = etClosed, Pt); + if assigned(Pt) then + if not assigned(BotPt) or (Pt.Y > BotPt.Y) or + ((Pt.Y = BotPt.Y) and (Pt.X < BotPt.X)) then + begin + BotPt := Pt; + BotI := I; + end; + end; + + if (EndType = etClosed) and (BotI >= 0) and not Orientation(Pts[BotI]) then + Pts := ReversePaths(Pts); + + with TOffsetBuilder.Create(Pts, Delta, JoinType, EndType, Limit) do + try + result := Solution; + finally + Free; + end; end; //------------------------------------------------------------------------------ -function SimplifyPolygon(const Poly: TPolygon; FillType: TPolyFillType = pftEvenOdd): TPolygons; +function SimplifyPolygon(const Poly: TPath; FillType: TPolyFillType = pftEvenOdd): TPaths; begin with TClipper.Create do try - ForceSimple := True; - AddPolygon(Poly, ptSubject); + StrictlySimple := True; + AddPath(Poly, ptSubject, True); Execute(ctUnion, Result, FillType, FillType); finally free; @@ -4187,12 +4947,12 @@ function SimplifyPolygon(const Poly: TPolygon; FillType: TPolyFillType = pftEven end; //------------------------------------------------------------------------------ -function SimplifyPolygons(const Polys: TPolygons; FillType: TPolyFillType = pftEvenOdd): TPolygons; +function SimplifyPolygons(const Polys: TPaths; FillType: TPolyFillType = pftEvenOdd): TPaths; begin with TClipper.Create do try - ForceSimple := True; - AddPolygons(Polys, ptSubject); + StrictlySimple := True; + AddPaths(Polys, ptSubject, True); Execute(ctUnion, Result, FillType, FillType); finally free; @@ -4224,7 +4984,7 @@ function ClosestPointOnLine(const Pt, LinePt1, LinePt2: TIntPoint): TDoublePoint end; //------------------------------------------------------------------------------ -function SlopesNearColinear(const Pt1, Pt2, Pt3: TIntPoint; DistSqrd: Double): Boolean; +function SlopesNearCollinear(const Pt1, Pt2, Pt3: TIntPoint; DistSqrd: Double): Boolean; var Cpol: TDoublePoint; Dx, Dy: Double; @@ -4245,7 +5005,7 @@ function PointsAreClose(const Pt1, Pt2: TIntPoint; end; //------------------------------------------------------------------------------ -function CleanPolygon(const Poly: TPolygon; Distance: Double = 1.415): TPolygon; +function CleanPolygon(const Poly: TPath; Distance: Double = 1.415): TPath; var I, I2, K, HighI: Integer; DistSqrd: double; @@ -4273,7 +5033,7 @@ function CleanPolygon(const Poly: TPolygon; Distance: Double = 1.415): TPolygon; while (I < HighI) and PointsAreClose(Pt, Poly[I+1], DistSqrd) do inc(I,2); I2 := I; while (I < HighI) and (PointsAreClose(Poly[I], Poly[I+1], DistSqrd) or - SlopesNearColinear(Pt, Poly[I], Poly[I+1], DistSqrd)) do inc(I); + SlopesNearCollinear(Pt, Poly[I], Poly[I+1], DistSqrd)) do inc(I); if I >= highI then Break else if I <> I2 then Continue; Pt := Poly[I]; @@ -4288,14 +5048,14 @@ function CleanPolygon(const Poly: TPolygon; Distance: Double = 1.415): TPolygon; inc(K); end; - if (K > 2) and SlopesNearCoLinear(Result[K -2], + if (K > 2) and SlopesNearCollinear(Result[K -2], Result[K -1], Result[0], DistSqrd) then Dec(K); if (K < 3) then Result := nil else if (K <= HighI) then SetLength(Result, K); end; //------------------------------------------------------------------------------ -function CleanPolygons(const Polys: TPolygons; Distance: double = 1.415): TPolygons; +function CleanPolygons(const Polys: TPaths; Distance: double = 1.415): TPaths; var I, Len: Integer; begin @@ -4306,28 +5066,173 @@ function CleanPolygons(const Polys: TPolygons; Distance: double = 1.415): TPolyg end; //------------------------------------------------------------------------------ -procedure AddPolyNodeToPolygons(PolyNode: TPolyNode; var Polygons: TPolygons); +function Minkowki(const Base, Path: TPath; + IsSum: Boolean; IsClosed: Boolean): TPaths; +var + i, j, delta, baseLen, pathLen: integer; + quads: TPaths; + quad: TPath; +begin + if IsClosed then delta := 1 else delta := 0; + + baseLen := Length(Base); + pathLen := Length(Path); + setLength(Result, pathLen); + if IsSum then + for i := 0 to pathLen -1 do + begin + setLength(Result[i], baseLen); + for j := 0 to baseLen -1 do + begin + Result[i][j].X := Path[i].X + Base[j].X; + Result[i][j].Y := Path[i].Y + Base[j].Y; + end; + end + else + for i := 0 to pathLen -1 do + begin + setLength(Result[i], baseLen); + for j := 0 to baseLen -1 do + begin + Result[i][j].X := Path[i].X - Base[j].X; + Result[i][j].Y := Path[i].Y - Base[j].Y; + end; + end; + + SetLength(quad, 4); + SetLength(quads, (pathLen + delta) * (baseLen + 1)); + for i := 0 to pathLen - 2 + delta do + begin + for j := 1 to baseLen - 1 do + begin + quad[0] := Result[i mod pathLen][j mod baseLen]; + quad[1] := Result[(i+1) mod pathLen][j mod baseLen]; + quad[2] := Result[(i+1) mod pathLen][(j+1) mod baseLen]; + quad[3] := Result[i mod pathLen][(j+1) mod baseLen]; + if not Orientation(quad) then quad := ReversePath(quad); + quads[i*baseLen + j] := copy(quad, 0, 4); + end; + end; + + with TClipper.Create() do + try + AddPaths(quads, ptSubject, True); + Execute(ctUnion, Result, pftNonZero); + finally + Free; + end; +end; +//------------------------------------------------------------------------------ + +function MinkowkiSum(const Base, Path: TPath; IsClosed: Boolean = true): TPaths; +begin + Result := Minkowki(Base, Path, true, IsClosed); +end; +//------------------------------------------------------------------------------ + +function MinkowkiDiff(const Base, Path: TPath; IsClosed: Boolean = true): TPaths; +begin + Result := Minkowki(Base, Path, false, IsClosed); +end; +//------------------------------------------------------------------------------ + +type + TNodeType = (ntAny, ntOpen, ntClosed); + +procedure AddPolyNodeToPolygons(PolyNode: TPolyNode; + NodeType: TNodeType; var Paths: TPaths); var I: Integer; + Match: Boolean; begin - if Length(PolyNode.Contour) > 0 then + case NodeType of + ntAny: Match := True; + ntClosed: Match := not PolyNode.IsOpen; + else Exit; + end; + + if (Length(PolyNode.Contour) > 0) and Match then begin - I := Length(Polygons); - SetLength(Polygons, I +1); - Polygons[I] := PolyNode.Contour; + I := Length(Paths); + SetLength(Paths, I +1); + Paths[I] := PolyNode.Contour; end; for I := 0 to PolyNode.ChildCount - 1 do - AddPolyNodeToPolygons(PolyNode.Childs[I], Polygons); + AddPolyNodeToPolygons(PolyNode.Childs[I], NodeType, Paths); end; //------------------------------------------------------------------------------ -function PolyTreeToPolygons(PolyTree: TPolyTree): TPolygons; +function PolyTreeToPaths(PolyTree: TPolyTree): TPaths; +begin + Result := nil; + AddPolyNodeToPolygons(PolyTree, ntAny, Result); +end; +//------------------------------------------------------------------------------ + +function ClosedPathsFromPolyTree(PolyTree: TPolyTree): TPaths; +begin + Result := nil; + AddPolyNodeToPolygons(PolyTree, ntClosed, Result); +end; +//------------------------------------------------------------------------------ + +function OpenPathsFromPolyTree(PolyTree: TPolyTree): TPaths; +var + I, J: Integer; begin Result := nil; - AddPolyNodeToPolygons(PolyTree, Result); + //Open polys are top level only, so ... + for I := 0 to PolyTree.ChildCount - 1 do + if PolyTree.Childs[I].IsOpen then + begin + J := Length(Result); + SetLength(Result, J +1); + Result[J] := PolyTree.Childs[I].Contour; + end; +end; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +{$IFDEF use_deprecated} +function TClipperBase.AddPolygons(const Paths: TPaths; PolyType: TPolyType): Boolean; +begin + Result := AddPaths(Paths, PolyType, True); +end; +//------------------------------------------------------------------------------ + +function TClipperBase.AddPolygon(const Path: TPath; PolyType: TPolyType): Boolean; +begin + Result := AddPath(Path, PolyType, True); +end; +//------------------------------------------------------------------------------ + +function OffsetPolygons(const Polys: TPolygons; const Delta: Double; + JoinType: TJoinType = jtSquare; Limit: Double = 0; + AutoFix: Boolean = True): TPolygons; +begin + result := OffsetPaths(Polys, Delta, JoinType, etClosed, Limit); +end; +//------------------------------------------------------------------------------ + +function PolyTreeToPolygons(PolyTree: TPolyTree): TPolygons; +begin + result := PolyTreeToPaths(PolyTree); end; +//------------------------------------------------------------------------------ +function ReversePolygon(const Pts: TPolygon): TPolygon; +begin + result := ReversePath(Pts); +end; //------------------------------------------------------------------------------ + +function ReversePolygons(const Pts: TPolygons): TPolygons; +begin + result := ReversePaths(Pts); +end; //------------------------------------------------------------------------------ +{$ENDIF} + end. diff --git a/Delphi/main demo/GR32_Misc.pas b/Delphi/main demo/GR32_Misc.pas index 48c4f95..aaa1932 100644 --- a/Delphi/main demo/GR32_Misc.pas +++ b/Delphi/main demo/GR32_Misc.pas @@ -19,7 +19,7 @@ interface uses Windows, Types, Classes, SysUtils, Math, GR32, GR32_LowLevel, GR32_Blend, GR32_Transforms, - Graphics, GR32_Math, GR32_Polygons, GR32_PolygonsEx, GR32_VPR; + Graphics, GR32_Math, GR32_Polygons, GR32_VPR; type TArrayOfArrayOfArrayOfFixedPoint = array of TArrayOfArrayOfFixedPoint; diff --git a/Delphi/main demo/main.dfm b/Delphi/main demo/main.dfm index e3fb4ac..b6d4099 100644 --- a/Delphi/main demo/main.dfm +++ b/Delphi/main demo/main.dfm @@ -1,9 +1,9 @@ object MainForm: TMainForm Left = 235 Top = 110 - Width = 731 - Height = 547 Caption = 'Clipper Delphi Demo' + ClientHeight = 520 + ClientWidth = 723 Color = clBtnFace Font.Charset = ARABIC_CHARSET Font.Color = clWindowText @@ -275,6 +275,7 @@ object MainForm: TMainForm ScaleMode = smScale ScrollBars.ShowHandleGrip = True ScrollBars.Style = rbsDefault + ScrollBars.Size = 16 OverSize = 0 TabOrder = 2 OnDblClick = bNextClick diff --git a/Delphi/main demo/main.pas b/Delphi/main demo/main.pas index d59fce0..07a675e 100644 --- a/Delphi/main demo/main.pas +++ b/Delphi/main demo/main.pas @@ -18,7 +18,7 @@ interface Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, Math, GR32, GR32_Image, GR32_Polygons, //http://sourceforge.net/projects/graphics32/ - GR32_PolygonsEx, GR32_VPR, //http://sourceforge.net/projects/vpr/ + GR32_VPR, //http://sourceforge.net/projects/vpr/ GR32_Misc, clipper; type @@ -35,7 +35,7 @@ TStyleInfo = record end; TPolyInfo = record - polygons: TPolygons; + paths: TPaths; si: TStyleInfo; end; TPolyInfos = array of TPolyInfo; @@ -63,7 +63,7 @@ TSvgBuilder = class style: TStyleInfo; constructor Create; procedure Clear; - procedure AddPolygons(const poly: TPolygons); + procedure AddPaths(const poly: TPaths); procedure AddText(const text: string; X,Y: integer); function SaveToFile(filename: string; scale: double = 1.0; margin: integer = 10): boolean; @@ -171,7 +171,7 @@ function IntArrayToStr(a: TArrayOfInteger; scale: double = 1.0; end; //------------------------------------------------------------------------------ -procedure TSvgBuilder.AddPolygons(const poly: TPolygons); +procedure TSvgBuilder.AddPaths(const poly: TPaths); var i, len: integer; begin @@ -179,9 +179,9 @@ procedure TSvgBuilder.AddPolygons(const poly: TPolygons); if i = 0 then Exit; len := length(polyList); setlength(polyList, len+1); - setlength(polyList[len].polygons, i); + setlength(polyList[len].paths, i); for i := 0 to i-1 do - polyList[len].polygons[i] := Copy(poly[i], 0, MaxInt); + polyList[len].paths[i] := Copy(poly[i], 0, MaxInt); polyList[len].si.pft := style.pft; polyList[len].si.brushClr := style.brushClr; polyList[len].si.penClr := style.penClr; @@ -235,21 +235,21 @@ function TSvgBuilder.SaveToFile(filename: string; //calculate the bounding rect (skipping empty polygons) ... while i < len do begin - len2 := length(polyList[i].polygons); + len2 := length(polyList[i].paths); j := 0; - while (j < len2) and (length(polyList[i].polygons[j]) < 3) do inc(j); + while (j < len2) and (length(polyList[i].paths[j]) < 3) do inc(j); if j < len2 then Break; inc(i); end; if i = len then Exit; - rec.left := polyList[i].polygons[j][0].X; + rec.left := polyList[i].paths[j][0].X; rec.right := rec.left; - rec.top := polyList[i].polygons[j][0].Y; + rec.top := polyList[i].paths[j][0].Y; rec.bottom := rec.top; for i := i to len -1 do - for j := 0 to length(polyList[i].polygons) -1 do - for k := 0 to length(polyList[i].polygons[j]) -1 do - with polyList[i].polygons[j][k] do + for j := 0 to length(polyList[i].paths) -1 do + for k := 0 to length(polyList[i].paths[j]) -1 do + with polyList[i].paths[j][k] do begin if X < rec.left then rec.left := X else if X > rec.right then rec.right := X; @@ -277,17 +277,17 @@ function TSvgBuilder.SaveToFile(filename: string; svg_xml_start[1]])); for i := 0 to len -1 do - if assigned(polyList[i].polygons) then + if assigned(polyList[i].paths) then begin ss.WriteString(poly_start); - for j := 0 to high(polyList[i].polygons) do + for j := 0 to high(polyList[i].paths) do begin - if (length(polyList[i].polygons[j]) < 3) then continue; - with polyList[i].polygons[j][0] do + if (length(polyList[i].paths[j]) < 3) then continue; + with polyList[i].paths[j][0] do ss.WriteString( format(' M %1.2f %1.2f', [X * scale + offsetX, Y * scale + offsetY])); - for k := 1 to high(polyList[i].polygons[j]) do - with polyList[i].polygons[j][k] do + for k := 1 to high(polyList[i].paths[j]) do + with polyList[i].paths[j][k] do ss.WriteString( format(' L %1.2f %1.2f', [X * scale + offsetX, Y * scale + offsetY])); ss.WriteString(' z'); @@ -310,11 +310,11 @@ function TSvgBuilder.SaveToFile(filename: string; if polyList[i].si.showCoords then begin ss.WriteString(''#10#10); - for j := 0 to high(polyList[i].polygons) do + for j := 0 to high(polyList[i].paths) do begin - if (length(polyList[i].polygons[j]) < 3) then continue; - for k := 0 to high(polyList[i].polygons[j]) do - with polyList[i].polygons[j][k] do + if (length(polyList[i].paths[j]) < 3) then continue; + for k := 0 to high(polyList[i].paths[j]) do + with polyList[i].paths[j][k] do ss.WriteString(format('%1.0n,%1.0n'#10, [X * scale + offsetX, Y * scale + offsetY, X, Y])); ss.WriteString(#10); @@ -360,10 +360,10 @@ function TSvgBuilder.SaveToFile(filename: string; scale: integer = 1; //scale bitmap to 10 decimal places subj: TArrayOfArrayOfFloatPoint = nil; clip: TArrayOfArrayOfFloatPoint = nil; - subjI: TPolygons = nil; - clipI: TPolygons = nil; + subjI: TPaths = nil; + clipI: TPaths = nil; solution: TArrayOfArrayOfFloatPoint = nil; - solutionI: TPolygons = nil; + solutionI: TPaths = nil; subjOpacity: cardinal = $FF000000; clipOpacity: cardinal = $FF000000; @@ -373,7 +373,7 @@ function TSvgBuilder.SaveToFile(filename: string; //------------------------------------------------------------------------------ function AAFloatPoint2AAPoint(const a: TArrayOfArrayOfFloatPoint; - decimals: integer = 0): TPolygons; + decimals: integer = 0): TPaths; var i,j,decScale: integer; begin @@ -391,7 +391,7 @@ function AAFloatPoint2AAPoint(const a: TArrayOfArrayOfFloatPoint; end; //------------------------------------------------------------------------------ -function AAPoint2AAFloatPoint(const a: TPolygons; +function AAPoint2AAFloatPoint(const a: TPaths; decimals: integer = 0): TArrayOfArrayOfFloatPoint; var i,j,decScale: integer; @@ -461,7 +461,7 @@ procedure TMainForm.RepaintBitmapI; var pfm: TPolyFillMode; sol: TArrayOfArrayOfFloatPoint; - solI: TPolygons; + solI: TPaths; scaling: single; begin ImgView321.Bitmap.Clear(clWhite32); @@ -609,8 +609,8 @@ procedure TMainForm.ShowStaticPolys; if not rbNone.Checked then with TClipper.Create do try - AddPolygons(subjI, ptSubject); - AddPolygons(clipI, ptClip); + AddPaths(subjI, ptSubject, true); + AddPaths(clipI, ptClip, true); Execute(GetOpTypeI, solutionI, pftNonZero, pftNonZero); finally free; @@ -653,8 +653,8 @@ procedure TMainForm.ShowRandomPolys1(newPoly: boolean); if not rbNone.Checked then with TClipper.Create do try - AddPolygons(subjI, ptSubject); - AddPolygons(clipI, ptClip); + AddPaths(subjI, ptSubject, true); + AddPaths(clipI, ptClip, true); Execute(GetOpTypeI, solutionI, fillType, fillType); finally free; @@ -701,8 +701,8 @@ procedure TMainForm.ShowRandomPolys2(newPoly: boolean); if not rbNone.Checked then with TClipper.Create do try - AddPolygons(subjI, ptSubject); - AddPolygons(clipI, ptClip); + AddPaths(subjI, ptSubject, true); + AddPaths(clipI, ptClip, true); Execute(GetOpTypeI, solutionI, fillType, fillType); finally free; @@ -741,7 +741,7 @@ procedure TMainForm.FormKeyPress(Sender: TObject; var Key: Char); end; //------------------------------------------------------------------------------ -function MakeArrayOfIntPoint(const pts: array of integer): TPolygon; +function MakeArrayOfIntPoint(const pts: array of integer): TPath; var i, len: integer; begin @@ -769,15 +769,15 @@ procedure TMainForm.bSaveSvgClick(Sender: TObject); style.brushClr := $0F0000FF; style.penClr := $800099FF; - AddPolygons(subjI); + AddPaths(subjI); style.brushClr := $0FFFFF00; style.penClr := $80FF9900; - AddPolygons(clipI); + AddPaths(clipI); style.brushClr := $2000FF00; style.penClr := $FF006600; - AddPolygons(solutionI); + AddPaths(solutionI); SaveToFile(SaveDialog1.FileName, invScale); finally diff --git a/Documentation/Docs/Overview/Changes.htm b/Documentation/Docs/Overview/Changes.htm index 15b36bf..4089b27 100644 --- a/Documentation/Docs/Overview/Changes.htm +++ b/Documentation/Docs/Overview/Changes.htm @@ -1,6 +1,5 @@ - - + + - + - + + + + + + + + + + + + + + + Deprecated + + + + + + + + + + + + + + + + + + + + + +

Deprecated

+ + +

Since version 6 is a major upgrade from previous versions, quite a number of changes have been made to exposed structures, functions and to public methods of the Clipper class too. To minimize any inconvenience to existing users of the library, I've included some code to preserve backward compatability. However, because this code will be removed in a future update the code has been marked as deprecated, and a precompiler directive 'use_deprecated' has been defined (ie deprecated code is enabled by default).

Deprecated Structures:

+ + + + + + + + + + + + + + + + + + +
Polygon + replaced by Path +
Polygons + replaced by Paths +


Deprecated
ClipperBase methods:

+ + + + + + + + + + + + + + + + + + +
ClipperBase.AddPolygon + replaced by ClipperBase.AddPath +
ClipperBase.AddPolygons + replaced by ClipperBase.AddPaths +


Deprecated Functions:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReversePolygon + replaced by ReversePath +
ReversePolygons + replaced by ReversePaths +
OffsetPolygons + replaced by OffsetPaths +
OffsetPolylines + replaced by OffsetPaths +
PolyTreeToPolygons + replaced by PolyTreeToPaths +


+ +

See Also

+

ClipperBase, ClipperBase.AddPath, ClipperBase.AddPaths, OffsetPaths, PolyTreeToPaths, ReversePath, ReversePaths, Path, Paths

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Overview/Example.htm b/Documentation/Docs/Overview/Example.htm index 26353c2..cd832e5 100644 --- a/Documentation/Docs/Overview/Example.htm +++ b/Documentation/Docs/Overview/Example.htm @@ -62,18 +62,18 @@

Example

uses graphics32, clipper; - function GetEllipsePoints(bounds: TIntRect): TPolygon; + function GetEllipsePoints(bounds: TIntRect): TPath; begin //code to create an elliptical polygon here end; - procedure DrawPolygons(polys: TPolygons; color: TColor32); + procedure DrawPolygons(polys: TPaths; color: TColor32); begin //code to display the polygons here end; var - sub, clp, sol: TPolygons; + sub, clp, sol: TPaths; begin //set up the subject and clip polygons ... @@ -92,8 +92,8 @@

Example

//get the intersection of the subject and clip polygons ... with TClipper.Create do try - AddPolygons(sub, ptSubject); - AddPolygons(clp, ptClip); + AddPaths(sub, ptSubject, true); + AddPaths(clp, ptClip, true); Execute(ctIntersection, sol, pftEvenOdd, pftEvenOdd); finally free; @@ -124,28 +124,28 @@

Example

... //from clipper.hpp ... - //typedef long long long64; - //struct IntPoint {long64 X; long64 Y;}; - //typedef std::vector<IntPoint> Polygon; - //typedef std::vector<Polygon> Polygons; + //typedef long long cInt; + //struct IntPoint {cInt X; cInt Y;}; + //typedef std::vector<IntPoint> Path; + //typedef std::vector<Polygon> Paths; using namespace ClipperLib; - void GetEllipsePoints(IntRect& bounds, Polygon& p) + void GetEllipsePoints(IntRect& bounds, Path& p) {/* ... */} - void DrawPolygons(Polygons& p, unsigned color) + void DrawPolygons(Paths& p, unsigned color) {/* ... */} int main() { //set up the subject and clip polygons ... - Polygons sub(3); + Paths sub(3); GetEllipsePoints(IntRect(100,100,300,300), sub[0]); GetEllipsePoints(IntRect(125,130,275,180), sub[1]); GetEllipsePoints(IntRect(125,220,275,270), sub[2]); - Polygons clp(1); + Paths clp(1); GetEllipsePoints(IntRect(140,70,220,320), clp[0]); //display the subject and clip polygons ... @@ -154,13 +154,13 @@

Example

//get the intersection of the subject and clip polygons ... Clipper clpr; - clpr.AddPolygons(sub, ptSubject); - clpr.AddPolygons(clp, ptClip); - Polygons sol; - clpr.Execute(ctIntersection, sol, pftEvenOdd, pftEvenOdd); + clpr.AddPaths(sub, ptSubject, true); + clpr.AddPaths(clp, ptClip, true); + Paths solution; + clpr.Execute(ctIntersection, solution, pftEvenOdd, pftEvenOdd); //finally draw the intersection polygons ... - DrawPolygons(sol, 0x40808080); + DrawPolygons(solution, 0x40808080); } @@ -184,32 +184,32 @@

Example

using ClipperLib; ... - using Polygon = List<IntPoint>; - using Polygons = List<List<IntPoint>>; + using Path = List<IntPoint>; + using Paths = List<List<IntPoint>>; - static Polygon GetEllipsePoints(IntRect bounds) + static Path GetEllipsePoints(IntRect bounds) {/* ... */} - static void DrawPolygons(Polygon p, unsigned color) + static void DrawPolygons(Path p, uint color) {/* ... */} static void Main(string[] args) { - Polygons subjs = new Polygons(3); + Paths subjs = new Paths(3); subjs.Add(GetEllipsePoints(new IntRect(100,100,300,300))); subjs.Add(GetEllipsePoints(new IntRect(125,130,275,180))); subjs.Add(GetEllipsePoints(new IntRect(125,220,275,270))); - Polygons clips = new Polygons(1); + Paths clips = new Paths(1); clips.Add(GetEllipsePoints(new IntRect(140,70,220,320))); DrawPolygons(subjs, 0x8033FFFF); DrawPolygons(clips, 0x80FFFF33); - Polygons solution = new Polygons(); + Paths solution = new Paths(); Clipper c = new Clipper(); - c.AddPolygons(subjs, PolyType.ptSubject); - c.AddPolygons(clips, PolyType.ptClip); + c.AddPaths(subjs, PolyType.ptSubject, true); + c.AddPaths(clips, PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution); DrawPolygons(solution, 0x40808080); @@ -226,7 +226,7 @@

Example

- + diff --git a/Documentation/Docs/Overview/FAQ.htm b/Documentation/Docs/Overview/FAQ.htm index 4154b49..acd2b26 100644 --- a/Documentation/Docs/Overview/FAQ.htm +++ b/Documentation/Docs/Overview/FAQ.htm @@ -58,17 +58,17 @@

FAQ

How do I use floating point coordinates with Clipper?

-

It's a simple task to multiply your floating point coordinates by a scaling factor (that's typically a power of 10 depending on the desired precision). Then with the solution polygons, divide the returned coordinates by this same scaling factor. Clipper accepts integer coordinates as large as ±4.6e18, so it can accommodate very large scaling factors.

+

It's a simple task to multiply your floating point coordinates by a scaling factor (that's typically a power of 10 depending on the desired precision). Then with the solution paths, divide the returned coordinates by this same scaling factor. Clipper accepts integer coordinates as large as ±4.6e18, so it can accommodate very large scaling.

Does Clipper handle polygons with holes?

-

'Holes' are implied simply by having their orientations opposite that of their container polygons.

+

'Holes' are defined using the suppied polygon filling rule. (See also Clipper.Execute)

-

Some solution polygons share a common edge. Is this a bug?

+

Some polygons in the solution share a common edge. Is this a bug?

-

No. However Clipper tries very hard to minimize this by merging polygons that share a common edge.

+

No, though this should happen rarely as of version 6. (See Clipper.Execute for more about this.)

I have lots of polygons that I want to 'union'. Can I do this in one operation?

@@ -76,73 +76,27 @@

FAQ

Yes. Just add all the polygons as subject polygons to the Clipper object. (You don't have to assign both subject and clip polygons.)

-

The OffsetPolygons function is returning tiny artefacts? Could this be a bug?

+

The OffsetPaths function is returning tiny artefacts? Could this be a bug?

-

The precision of the input coordinates may be a problem. The Clipper Library only operates on integer coordinates so if you need better precision than integers, scale the coordinates (eg by a factor of 10) before passing them to the OffsetPolygons function. Then it's a simple matter to reverse the scaling on the output polygons.

- - -

The OffsetPolygons function is returning unexpected results? Could this be a bug?

- -

Most likely the orientation of the input polygons is wrong.

+

The precision of the input coordinates may be a problem. Because the Clipper Library only operates on integer coordinates, you may need to scale your coordinates (eg by a factor of 10) to improve precision when passing them to the OffsetPaths function. (Reverse any scaling on the output polygons too.)

Is there an easy way to reverse polygon orientations?

-

Yes, see ReversePolygons.

- -
- - -

Is it possible to get the offset of a line or a polyline?

- -

Yes. If it's two vertices forming a single line, just treat this line as if it were a polygon. Polylines however must first be converted into 'flat' polygons. Do this by appending to the polyline a reverse copy of the polyline while avoiding duplicating the end coordinates: c1,c2,...,cn,c(n-1),c(n-2),...,c2.

- - - - - - -
- -
-var
-  pts: TPolygon;
-  ppts: TPolygons;
-begin
-  //define the polyline ...
-  setlength(pts, 5);
-  pts[0] := IntPoint(10,10);
-  pts[1] := IntPoint(100,100);
-  pts[2] := IntPoint(150,100);
-  pts[3] := IntPoint(100,10);
-  pts[4] := IntPoint(10,100);
-
-  //convert the line to a 'flat' polygon ...
-  len := length(pts);
-  setLength(pts, len*2 -2);
-  for i := 1 to len -2 do pts[len-1 +i] := pts[len-1 -i];
-
-  //do the offsetting ...
-  setlength(ppts, 1);
-  ppts[0] := pts;
-  ppts := OffsetPolygons(ppts, 6, jtSquare, 0);
-          
- -


+

Yes, see ReversePaths.

 

My drawings contain lots of ellipses and arcs. How can I perform clipping operations or offsetting on these?

-

You'll have to convert then to polygons. Many graphics libraries have 'flatten path' routines.

- +

You'll have to convert then to paths. Many graphics libraries have 'flatten path' routines. (See also the Beziers unit that's included in this library. However, there's no documentation on it yet.)

See Also

-

OffsetPolygons, Orientation, ReversePolygons

+

Clipper.Execute, OffsetPaths, ReversePaths, PolyFillType

- + diff --git a/Documentation/Docs/Overview/License.htm b/Documentation/Docs/Overview/License.htm index 238dd29..d779975 100644 --- a/Documentation/Docs/Overview/License.htm +++ b/Documentation/Docs/Overview/License.htm @@ -67,7 +67,7 @@

License

- + diff --git a/Documentation/Docs/Overview/Rounding.htm b/Documentation/Docs/Overview/Rounding.htm index eeea15d..f40d52b 100644 --- a/Documentation/Docs/Overview/Rounding.htm +++ b/Documentation/Docs/Overview/Rounding.htm @@ -51,20 +51,20 @@

Rounding

-

By using an integer type for polygon coordinates, the Clipper Library has been able to avoid problems of numerical robustness that can cause havoc with geometric computations. Problems associated with integer rounding and their possible solutions are discussed below.

It's important to stress at the outset that rounding causes vertices to move fractions of a unit away from their 'true' positions. Nevertheless, the resulting imprecision can be very effectively managed by appropriate scaling.

Very high degrees of precision can be achieved by scaling (or increasing scaling) of polygon coordinates.

The Clipper library accepts integer coordinate values in the range ±0x3FFFFFFFFFFFFFFF (± 4.6e+18) in order to accommodate very high degrees of precision.

Apart from the imprecision resulting from vertices being forced onto an integer grid, another complication that very occasionally arises is tiny self-intersection artefacts. In the unscaled image on the left (where one unit equals one pixel), the area of intersection of 2 polygons has been highlighted in bright green.

+

By using an integer type for polygon coordinates, the Clipper Library has been able to avoid problems of numerical robustness that can cause havoc with geometric computations. Problems associated with integer rounding and their possible solutions are discussed below.

It's important to stress at the outset that rounding causes vertices to move fractions of a unit away from their 'true' positions. Nevertheless, the resulting imprecision can be very effectively managed by appropriate scaling.

The Clipper Library supports scaling to very high degrees of precision by accepting integer coordinate values in the range ±0x3FFFFFFFFFFFFFFF (± 4.6e+18).

Another complication of using a discrete numbers (as opposed to real numbers) is that very occasionally tiny self-intersection artefacts arise. In the unscaled image on the left (where one unit equals one pixel), the area of intersection of two polygons has been highlighted in bright green.

-



A 30X 'close up' of the lower points of intersection of these same 2 polygons shows the presence of a tiny self-intersecting artefact. The three 'black dots' highlight the actual points of intersection (with their fractional coordinates displayed). The 'red dots' show where these points of intersection are located once rounding is applied. With a little care you can see that rounding reverses the orientation of these vertices and causes a tiny self-intersecting artefact.

Although these tiny self-intersections are uncommon, if it's deemed necessary, they can be removed using CleanPolygons.

+



A 30X 'close up' of the lower points of intersection of these same two polygons shows the presence of a tiny self-intersecting artefact. The three 'black dots' highlight the actual points of intersection (with their fractional coordinates displayed). The 'red dots' show where these points of intersection are located once rounding is applied. With a little care you can see that rounding reverses the orientation of these vertices and causes a tiny self-intersecting artefact.

Although these tiny self-intersections are uncommon, if it's deemed necessary, they are best removed with CleanPolygons. (Setting Clipper's StrictlySimple property to true would also address this self-intersection but the tiny (sub-unit) polygon 'artefact' with incorrect orientation would still appear in the solution.)

-



In this final example, the single polygon on the left also has a tiny self-intersection. However, the clipping algorithm sees this vertex (88,50) as simply 'touching' rather than intersecting the right edge of the polygon (though only by a fraction of a unit). Since this intersection won't be detected, the clipping solution (eg following a union operation) will still contain this tiny self-intersection.

+



In this final example, the single polygon on the left also has a tiny self-intersection. However, the clipping algorithm sees this vertex (88,50) as simply 'touching' rather than intersecting the right edge of the polygon (though only by a fraction of a unit). Since this intersection won't normally be detected, the clipping solution (eg following a union operation) will still contain this tiny self-intersection. Setting Clipper's StrictlySimple property to true avoids this uncommon problem.

See Also

-

CleanPolygons

+

Clipper.StrictlySimple, CleanPolygons

- + diff --git a/Documentation/Docs/Overview/_Body.htm b/Documentation/Docs/Overview/_Body.htm index e668451..cf48fa9 100644 --- a/Documentation/Docs/Overview/_Body.htm +++ b/Documentation/Docs/Overview/_Body.htm @@ -26,7 +26,7 @@ - + + + + + + + + + + + + + + + + Constructor + + + + + + + + + + + + + + + + + + + + + + +

Clipper.Constructor

+ + +

Del.» constructor TClipper.Create(InitOptions: TInitOptions = []);

+ +

C++ » Clipper::Clipper(int initOptions = 0) : ClipperBase();

+ +

C#  » public Clipper(initOptions = 0): base() {};

+ +

The Clipper constructor creates an instance of the Clipper class. One or more InitOptions may be passed as a parameter to set the corresponding properties. (These properties can still be set or reset after construction.)

Examples:

+ + + + + + +
+ +
+  //C++ constructor setting StrictlySimple and PreserveCollinear properties ...
+  Clipper clipper(ioStrictlySimple | ioPreserveCollinear);
+
+  //C# constructor setting StrictlySimple and PreserveCollinear properties ...
+  Clipper clipper = new Clipper(Clipper.ioStrictlySimple | Clipper.ioPreserveCollinear);
+
+  //Delphi constructor setting StrictlySimple and PreserveCollinear properties ...
+  clipper := TClipper.Create([ioStrictlySimple, ioPreserveCollinear]);
+          
+ +

 

+ + + + + +

See Also

+

PreserveCollinear, ReverseSolution, StrictlySimple, InitOptions

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Methods/Execute.htm b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Methods/Execute.htm index 59c6627..0c2239b 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Methods/Execute.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Methods/Execute.htm @@ -53,22 +53,38 @@

Clipper.Execute

-

Del.»
function Execute(clipType: TClipType;
  out solution: TPolygons;
  subjFillType: TPolyFillType = pftEvenOdd;
  clipFillType: TPolyFillType = pftEvenOdd): boolean; overload;

function Execute(clipType: TClipType;
  out solution: TPolyTree;
  subjFillType: TPolyFillType = pftEvenOdd;
  clipFillType: TPolyFillType = pftEvenOdd): boolean; overload;

+

Del.»
function Execute(clipType: TClipType;
  out solution: TPaths;
  subjFillType: TPolyFillType = pftEvenOdd;
  clipFillType: TPolyFillType = pftEvenOdd): boolean; overload;

function Execute(clipType: TClipType;
  out solution: TPolyTree;
  subjFillType: TPolyFillType = pftEvenOdd;
  clipFillType: TPolyFillType = pftEvenOdd): boolean; overload;

-

C++ »
bool Execute(ClipType clipType,
  Polygons &solution,
  PolyFillType subjFillType = pftEvenOdd,
  PolyFillType clipFillType = pftEvenOdd);

bool Execute(ClipType clipType,
  PolyTree &solution,
  PolyFillType subjFillType = pftEvenOdd,
  PolyFillType clipFillType = pftEvenOdd);

+

C++ »
bool Execute(ClipType clipType,
  Paths &solution,
  PolyFillType subjFillType = pftEvenOdd,
  PolyFillType clipFillType = pftEvenOdd);

bool Execute(ClipType clipType,
  PolyTree &solution,
  PolyFillType subjFillType = pftEvenOdd,
  PolyFillType clipFillType = pftEvenOdd);

-

C#  »
public bool Execute(ClipType clipType,
  Polygons solution,
  PolyFillType subjFillType,
  PolyFillType clipFillType);

public bool Execute(ClipType clipType,
  PolyTree solution,
  PolyFillType subjFillType,
  PolyFillType clipFillType);

+

C#  »
public bool Execute(ClipType clipType,
  Paths solution,
  PolyFillType subjFillType,
  PolyFillType clipFillType);

public bool Execute(ClipType clipType,
  PolyTree solution,
  PolyFillType subjFillType,
  PolyFillType clipFillType);


-

Once subject and clip polygons have been assigned (via AddPolygon and/or AddPolygons), Execute can then perform the clipping operation (intersection, union, difference or XOR) specified by the clipType parameter. This operation is performed on both subject and clip polygon sets using their respective fill types. (Subject and clip polygons usually use the same fill type.)

The solution parameter can be either a Polygons or PolyTree structure. While polygons returned in the solution won't be in any specific order, they will never overlap or be self-intersecting. Since holes will be oriented opposite outer polygons, the solution fill type can be either EvenOdd or NonZero.

Execute can be called multiple times without reassigning subject and clip polygons (ie when different clipping operations are required on the same polygon sets).

+

Once subject and clip paths have been assigned (via AddPath and/or AddPaths), Execute can then perform the clipping operation (intersection, union, difference or XOR) specified by the clipType parameter.

The solution parameter can be either a Paths or PolyTree structure. The Paths structure is simpler than the PolyTree stucture. Because of this it is quicker to populate and hence clipping performance is a little better (it's roughly 10% faster). However, the PolyTree data structure provides more information about the returned paths which may be important to users. Firstly, the PolyTree structure preserves nested parent-child polygon relationships (ie outer polygons owning/containing holes and holes owning/containing other outer polygons etc). Also, only the PolyTree structure can differentiate between open and closed paths since each PolyNode has an IsOpen property. (The Path structure has no member indicating whether it's open or closed.) For this reason, when open paths are passed to a Clipper object, the user must use a PolyTree object as the solution parameter, otherwise an exception will be raised.

When a PolyTree object is used in a clipping operation on open paths, two ancilliary functions have been provided to quickly separate out open and closed paths from the solution - OpenPathsFromPolyTree and ClosedPathsFromPolyTree. PolyTreeToPaths is also available to convert path data to a Paths structure (irrespective of whether they're open or closed).

There are several things to note about the solution paths returned: +

    + +
  • they aren't in any specific order
  • + +
  • they should never overlap or be self-intersecting (but see notes on rounding)
  • + +
  • holes will be oriented opposite outer polygons
  • + +
  • the solution fill type can be considered either EvenOdd or NonZero since it will comply with either filling rule
  • + +
  • polygons may rarely share a common edge (though this is now very rare as of version 6)
  • + +


+ + +

The subjFillType and clipFillType parameters define the polygon fill rule to be applied to the polygons (ie closed paths) in the subject and clip paths respectively. (It's usual though obviously not essential that both sets of polygons use the same fill rule.)

Execute can be called multiple times without reassigning subject and clip polygons (ie when different clipping operations are required on the same polygon sets).

See Also

-

Example, ClipperBase.AddPolygon, ClipperBase.AddPolygons, PolyTree, ClipType, PolyFillType, Polygons

+

Example, Rounding, ClipperBase.AddPath, ClipperBase.AddPaths, PolyNode.IsOpen, PolyTree, ClosedPathsFromPolyTree, OpenPathsFromPolyTree, PolyTreeToPaths, ClipType, Path, Paths, PolyFillType

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ForceSimple.htm b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/PreserveCollinear.htm similarity index 58% rename from Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ForceSimple.htm rename to Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/PreserveCollinear.htm index 9521961..2cfb621 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ForceSimple.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/PreserveCollinear.htm @@ -22,7 +22,7 @@ - ForceSimple + PreserveCollinear @@ -50,27 +50,20 @@ -

Clipper.ForceSimple

+

Clipper.PreserveCollinear

-

Del.» property ForceSimple: boolean; override;

+

Del.» property PreserveCollinear: boolean; override;

-

C++ » void ForceSimple(bool value);

+

C++ » void PreserveCollinear(bool value);

-

C#  » public bool ForceSimple { get {} set {} };

+

C#  » public bool PreserveCollinear { get {} set {} };

-

When this property is set to true, individual polygons returned in the solution of the Clipper object's Execute() method will be guaranteed to be 'strictly' simple - without self-intersections and with no touching vertices. This is computationally expensive, slowing clipping by about 10%. When this property is false (the default), polygons will be 'weakly' simple - without self-intersections but they may have touching vertices.


+


Prevents the removal of 'inner' vertices when three or more vertices are collinear in solution paths.

- -

In the image above, a weakly simple polygon (on the left) is converted to two strictly simple polygons. (The outlines with arrows are intended to aid visualizing vertex order.)

See also the article on Simple Polygon on Wikipedia.

- - - -

See Also

-

Execute, SimplifyPolygons

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ReverseSolution.htm b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ReverseSolution.htm index 86cdca2..c3af646 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ReverseSolution.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ReverseSolution.htm @@ -67,9 +67,9 @@

Clipper.ReverseSolution

See Also

-

Execute, Orientation

+

Execute, Orientation

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/StrictlySimple.htm b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/StrictlySimple.htm new file mode 100644 index 0000000..3bc7b13 --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/StrictlySimple.htm @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + StrictlySimple + + + + + + + + + + + + + + + + + + + + + + +

Clipper.StrictlySimple

+ + +

Del.» property StrictlySimple: boolean; override;

+ +

C++ » void StrictlySimple(bool value);

+ +

C#  » public bool StrictlySimple { get {} set {} };

+ + +


Terminology:
+

    + +
  • A simple polygon is one that does not self-intersect.
  • + +
  • A weakly simple polygon is a simple polygon that contains 'touching' vertices, or 'touching' edges.
  • + +
  • A strictly simple polygon is a simple polygon that does not contain 'touching' vertices, or 'touching' edges.
  • + +

+ +

Vertices 'touch' if they share the same coordinates (and are not adjacent). An edge touches another if one of its end vertices touches another edge excluding its adjacent edges, or if they are co-linear and overlapping (including adjacent edges).

Polygons returned by clipping operations (see Clipper.Execute()) should always be simple polygons. When the StrictlySimply property is enabled, polygons returned will be strictly simple, otherwise they may be weakly simple. It's computationally expensive ensuring polygons are strictly simple and so this property is disabled by default.


+ + +

In the image above, the two examples show weakly simple polygons being broken into two strictly simple polygons. (The outlines with arrows are intended to aid visualizing vertex order.)

See also the article on Simple Polygon on Wikipedia.

+ + + +

See Also

+

Execute, SimplifyPolygons

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ZFillFunction.htm b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ZFillFunction.htm new file mode 100644 index 0000000..702dda5 --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/ZFillFunction.htm @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + ZFillFunction + + + + + + + + + + + + + + + + + + + + + + +

Clipper.ZFillFunction

+ + +

Del.» property ZFillFunction: TZFillCallback read FZFillCallback write FZFillCallback;

+ +

C++ » void ZFillFunction(ZFillCallback zFillFunc);

+ +

C#  » public ZFillCallback ZFillFunction { get; set; };

+
+ +

This property is only exposed if the Preprocessor directive use_xyz has been defined. (If it is defined, a Z member will be added to the IntPoint structure.) When a custom callback function is assigned it will be called during clipping operations so custom Z values can be assigned intersection vertices.

Vertices in the solution of clipping operations more often than not correspond to input (subject or clip) vertices, but those vertices created at edge intersections do not. While the X and Y coordinates for these 'intersection' vertices are obviously defined by the points of intersection, there's no obvious way to assign their Z values. It really depends on the needs of the library user. While there are 4 vertices directly influencing an intersection vertex (ie the vertices on each end of the 2 intersecting edges), in an attempt to keep things simple only the vertices bounding one edge will be passed to the callback function.

The CurvesDemo application in the Curves directory in the distrubution zip package shows how the Z member together with the callback function can be used to flatten curved paths (defined by control points) and after clipping, to 'de-flatten' or reconstruct curved paths in the clipping solution.

+ + + + + + +
+ +
+Del. » procedure MyCallback(const Vert1, Vert2: TIntPoint; var IntersectPt: TIntPoint);  
+C++  » void MyCallback(const IntPoint& vert1, const IntPoint& vert2, IntPoint& intersectPt){...}
+C#   » public static void MyCallback(IntPoint vert1, IntPoint vert2, ref IntPoint intersectPt){...}
+          
+ +

 

+ + +

See Also

+

Defines, IntPoint, ZFillCallback

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Classes/Clipper/_Body.htm b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/_Body.htm index fc4ffbf..059dd2b 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/Clipper/_Body.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/Clipper/_Body.htm @@ -57,12 +57,11 @@

Hierarchy

ClipperBase


-

The Clipper class encapsulates boolean operations on polygons (intersection, union, difference and XOR), which is also called polygon clipping.

Input polygons, both subject and clip sets, are passed to a Clipper object by its AddPolygon and AddPolygons methods, and the clipping operation is performed by calling its Execute method. Multiple boolean operations can be performed on the same input polygon sets by repeat calls to Execute.

+

The Clipper class encapsulates boolean operations on polygons (intersection, union, difference and XOR), which is also called polygon clipping.

Input polygons, both subject and clip sets, are passed to a Clipper object by its AddPath and AddPaths methods, and the clipping operation is performed by calling its Execute method. Multiple boolean operations can be performed on the same input polygon sets by repeat calls to Execute.

Reference

- @@ -71,19 +70,27 @@

Reference

- + + + - + + + - @@ -91,32 +98,24 @@

Reference

- - - - - -
Fields - Methods +
Methods Properties
+ Constructor + PreserveCollinear
Execute ForceSimple + ReverseSolution
StrictlySimple +
ReverseSolution + ZFillFunction
- AddPolygon + AddPath
- AddPolygons + AddPaths
- Clear
- GetBounds @@ -126,7 +125,7 @@

Reference

See Also

Overview, ClipType

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPath.htm b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPath.htm new file mode 100644 index 0000000..64cd5ad --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPath.htm @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + AddPath + + + + + + + + + + + + + + + + + + + + + + +

ClipperBase.AddPath

+ + +

Del.» function AddPath(const path: TPath; polyType: TPolyType; Closed: Boolean): Boolean;

+ +

C++ » bool AddPath(const Path &pg, PolyType polyType, bool closed);

+ +

C#  » public virtual bool AddPath(Path pg, PolyType polyType, bool closed);

+
+ + +

Any number of subject and clip paths can be added to a clipping task, either individually via the AddPath() method, or as groups via the AddPaths() method, or even using both methods.

'Subject' paths may be either open (lines) or closed (polygons) or even a mixture of both, but 'clipping' paths must always be closed. Clipper allows polygons to clip both lines and other polygons, but doesn't allow lines to clip either lines or polygons.

With closed paths, orientation should conform with the filling rule that will be passed via Clippper's Execute method.

+ + + +

Path Coordinate range:
Path coordinates must be between ± 0x3FFFFFFFFFFFFFFF (± 4.6e+18), otherwise a range error will be thrown when attempting to add the path to the Clipper object. If coordinates can be kept between ± 0x3FFFFFFF (± 1.0e+9), a modest increase in performance (approx. 15-20%) over the larger range can be achieved by avoiding large integer math. If the preprocessor directive use_int32 is defined (allowing a further increase in performance of 20-30%), then the maximum range is restricted to ± 46340 (± 4.6e+4).

+ + +

Return Value:
The function will return false if the path is empty or almost empty. A path is almost empty when: +

    + +
  • it has less than 2 vertices.
  • + +
  • it has 2 vertices but is not an open path
  • + +
  • the vertices are all co-linear and it is not an open path
  • + +

+ +
+ + + + +

See Also

+

Example, Clipper.Execute, AddPaths, Orientation, Defines, Path, PolyFillType, PolyType

+ + + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPaths.htm b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPaths.htm new file mode 100644 index 0000000..ab51e18 --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPaths.htm @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + AddPaths + + + + + + + + + + + + + + + + + + + + + + +

ClipperBase.AddPaths

+ + +

Del.» function AddPaths(const paths: TPaths; polyType: TPolyType): boolean;

+ +

C++ » bool AddPaths(const Paths &ppg, PolyType polyType);

+ +

C#  » public virtual bool AddPaths(Paths ppg, PolyType polyType);

+
+ +

Any number of subject and clip paths can be added to a clipping task, either individually via the AddPath() method, or as groups via the AddPaths() method, or even using both methods.

'Subject' paths may be either open (lines) or closed (polygons) or even a mixture of both, but 'clipping' paths must always be closed. Clipper allows polygons to clip both lines and other polygons, but doesn't allow lines to clip either lines or polygons.

With closed paths, orientation should conform with the filling rule that will be passed via Clippper's Execute method.

+ + + +

Path Coordinate range:
Path coordinates must be between ± 0x3FFFFFFFFFFFFFFF (± 4.6e+18), otherwise a range error will be thrown when attempting to add the path to the Clipper object. If coordinates can be kept between ± 0x3FFFFFFF (± 1.0e+9), a modest increase in performance (approx. 15-20%) over the larger range can be achieved by avoiding large integer math. If the preprocessor directive use_int32 is defined (allowing a further increase in performance of 20-30%), then the maximum range is restricted to ± 46340 (± 4.6e+4).

+ + +

Return Value:
The function will return false if all the paths are empty or almost empty. A path is almost empty when: +

    + +
  • it has less than 2 vertices.
  • + +
  • it has 2 vertices but is not an open path
  • + +
  • the vertices are all co-linear and it is not an open path
  • + +

+ +
+ + + + +

See Also

+

Example, Clipper.Execute, AddPaths, Orientation, Defines, Paths, PolyFillType, PolyType

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPolygon.htm b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPolygon.htm deleted file mode 100644 index 4f1ee61..0000000 --- a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPolygon.htm +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - AddPolygon - - - - - - - - - - - - - - - - - - - - - - -

ClipperBase.AddPolygon

- - -

Del.» function AddPolygon(const polygon: TPolygon; polyType: TPolyType): boolean;

- -

C++ » bool AddPolygon(const Polygon &pg, PolyType polyType);

- -

C#  » public virtual bool AddPolygon(Polygon pg, PolyType polyType);

-
- - -

Any number of subject and clip polygons can be added to the clipping task, either individually via the AddPolygon() method, or as groups via the AddPolygons() method, or even using both methods.

Polygon orientation should conform with the polygon filling rule that will be applied (see Clippper's Execute method).

- - - -

Polygon Coordinate range:
Polygon coordinates must be between ± 0x3FFFFFFFFFFFFFFF (± 4.6e+18), otherwise a range error will be thrown when attempting to add the polygon to the Clipper object. If coordinates can be kept between ± 0x3FFFFFFF (± 1.0e+9), a modest increase in performance (approx. 15-20%) over the larger range can be achieved by avoiding large integer math.

- - -

Return Value:
The function will return false if the polygon is empty. A polygon is empty when: -

    - -
  • there are less than 3 coordinates defining the polygon
  • - -
  • the coordinates are all co-linear
  • - -

- -
- - - - -

See Also

-

Example, Clipper.Execute, AddPolygons, Orientation, PolyFillType, Polygon, PolyType

- - - - - - \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPolygons.htm b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPolygons.htm deleted file mode 100644 index a1fff3d..0000000 --- a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/AddPolygons.htm +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - AddPolygons - - - - - - - - - - - - - - - - - - - - - - -

ClipperBase.AddPolygons

- - -

Del.» function AddPolygons(const polygons: TPolygons; polyType: TPolyType): boolean;

- -

C++ » bool AddPolygons(const Polygons &ppg, PolyType polyType);

- -

C#  » public virtual bool AddPolygons(Polygons ppg, PolyType polyType);

-
- -

Any number of subject and clip polygons can be added to the clipping task, either individually via the AddPolygon() method, or as groups via the AddPolygons() method, or even using both methods.

Polygon orientation should conform with the polygon filling rule that will be applied (see Clippper's Execute method).

- - -

Polygon Coordinate range:
Polygon coordinates must be between ± 0x3FFFFFFFFFFFFFFF (± 4.6e+18), otherwise a range error will be thrown when attempting to add the polygon to the Clipper object. If coordinates can be kept between ± 0x3FFFFFFF (± 1.0e+9), a modest increase in performance (approx. 15-20%) over the larger range can be achieved by avoiding large integer math.

- - -

Return Value:
The function will return false if all polygons are empty. A polygon is empty when: -

    - -
  • there are less than 3 coordinates defining the polygon
  • - -
  • the coordinates are all co-linear
  • - -

- -
- - - - -

See Also

-

Example, Clipper.Execute, AddPolygon, Orientation, PolyFillType, Polygons, PolyType

- - - - - - \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/Clear.htm b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/Clear.htm index 3c9b8f0..45adf1b 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/Clear.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/Clear.htm @@ -64,7 +64,7 @@

ClipperBase.Clear

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/GetBounds.htm b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/GetBounds.htm index 66461ee..3087afd 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/GetBounds.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/Methods/GetBounds.htm @@ -69,7 +69,7 @@

ClipperBase.GetBounds

See Also

Example, IntRect

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/_Body.htm b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/_Body.htm index e3988e2..a2132c6 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/_Body.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/ClipperBase/_Body.htm @@ -52,13 +52,12 @@

ClipperBase

-

ClipperBase is the ancestor class to Clipper. It should not be instantiated directly.

+

ClipperBase is an abstract base class for Clipper. A ClipperBase object should not be instantiated directly.

Reference

- @@ -66,26 +65,18 @@

Reference

- - - - - - @@ -93,7 +84,7 @@

Reference

See Also

Clipper

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Methods/GetNext.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Methods/GetNext.htm index 58c4309..3550377 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Methods/GetNext.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Methods/GetNext.htm @@ -90,7 +90,7 @@

PolyNode.GetNext

See Also

PolyTree.GetFirst

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/ChildCount.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/ChildCount.htm index d154e49..74b49bc 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/ChildCount.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/ChildCount.htm @@ -67,7 +67,7 @@

PolyNode.ChildCount

See Also

Childs

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Childs.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Childs.htm index 7b456e0..cbd1163 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Childs.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Childs.htm @@ -68,7 +68,7 @@

PolyNode.Childs

See Also

ChildCount

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Contour.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Contour.htm index 8b0b560..0bb17ad 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Contour.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Contour.htm @@ -52,17 +52,17 @@
Fields - Methods +
Methods
- AddPolygon + AddPath
- AddPolygons + AddPaths
- Clear
- GetBounds

PolyNode.Contour

-

Del.» property Contour: TPolygon; //read only

+

Del.» property Contour: TPath; //read only

-

C++ » Polygon Contour; //public field

+

C++ » Path Contour; //public field

-

C#  » public Polygon Contour; //read only property

+

C#  » public Path Contour; //read only property

-

Returns the list of polygon vertices.

+

Returns a path list which contains any number of vertices.

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/IsHole.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/IsHole.htm index a46ba45..a0c06af 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/IsHole.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/IsHole.htm @@ -65,7 +65,7 @@

PolyNode.IsHole

See Also

Overview, Contour, PolyTree

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/IsOpen.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/IsOpen.htm new file mode 100644 index 0000000..9425733 --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/IsOpen.htm @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + IsOpen + + + + + + + + + + + + + + + + + + + + + + +

PolyNode.IsOpen

+ + +

Del.» IsOpen: Boolean; //read only

+ +

C++ » bool IsOpen; //field

+ +

C#  » public bool IsOpen; //read only property

+ + +

Returns true when the PolyNode's Contour results from a clipping operation on an open contour (path). Only top-level PolyNodes can contain open contours.

+ +

See Also

+

Contour

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Parent.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Parent.htm index 9a2234d..8acdbe9 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Parent.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/Properties/Parent.htm @@ -62,7 +62,7 @@

PolyNode.Parent

Returns the parent PolyNode.

The PolyTree object (which is also a PolyNode) does not have a parent and will return a null pointer.

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/_Body.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/_Body.htm index 963da7d..82785e7 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/_Body.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyNode/_Body.htm @@ -57,8 +57,7 @@

PolyNode

Reference

- @@ -67,32 +66,24 @@

Reference

- - - - + + +
Fields - Methods +
Methods Properties
- GetNext ChildCount
- Childs
- Contour
- IsHole @@ -101,6 +92,10 @@

Reference

IsOpen +
Parent @@ -110,7 +105,7 @@

Reference

See Also

Overview, Clipper.Execute, PolyTree

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Methods/Clear.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Methods/Clear.htm index 9c97bce..85f6c9c 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Methods/Clear.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Methods/Clear.htm @@ -66,7 +66,7 @@

PolyTree.Clear

See Also

Clipper.Execute

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Methods/GetFirst.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Methods/GetFirst.htm index e2d21e9..3633a3d 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Methods/GetFirst.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Methods/GetFirst.htm @@ -70,7 +70,7 @@

PolyTree.GetFirst

See Also

PolyNode.GetNext, PolyNode.ChildCount, PolyNode.Childs

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Properties/Total.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Properties/Total.htm index 1f4f025..bae8ce1 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Properties/Total.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/Properties/Total.htm @@ -67,7 +67,7 @@

PolyTree.Total

See Also

PolyNode.ChildCount, PolyNode.Childs

- + diff --git a/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/_Body.htm b/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/_Body.htm index 151b075..0ff9027 100644 --- a/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/_Body.htm +++ b/Documentation/Docs/Units/ClipperLib/Classes/PolyTree/_Body.htm @@ -57,7 +57,7 @@

Hierarchy

PolyNode


-

The PolyTree data structure is only used to receive solutions from polygon clipping operations. Its advantage over the Polygons structure (which can also receive solutions) is that it also represents the parent-child relationships of the returned polygons.

An empty PolyTree object can be passed as the solution parameter to a Clipper object's Execute method. Once the clipping operation is completed, this method returns with the PolyTree structure filled with data representing the solution.

A PolyTree object is a container for any number of PolyNode children, with each contained PolyNode representing a single polygon contour (either an outer or hole polygon). PolyTree itself is a specialized PolyNode whose immediate children represent the top-level outer polygons of the solution. (Its own Contour property is always empty.) The contained top-level PolyNodes may contain their own PolyNode children representing hole polygons that may also contain children representing nested outer polygons etc. Children of outers will always be holes, and children of holes will always be outers.

Since the PolyTree data structure is more complex than the alternative Polygons data structure, and because it's more computationally expensive to process (the Execute method being roughly 5-10% slower), it should only be used when parent-child polygon relationships are needed and not just polygon coordinates.

+

PolyTree is intended as a read-only data structure that should only be used to receive solutions from polygon clipping operations. It's an alternative data structure the Paths structure which can also receive clipping solutions. Its major advantages over the Paths structure is that it properly represents the parent-child relationships of the returned polygons, and that it also differentiates between open and closed paths. However, since a PolyTree is more complex than a Paths structure, and because it's more computationally expensive to process (the Execute method being roughly 5-10% slower), it should only be used when parent-child polygon relationships are needed, or when open paths are being 'clipped'.

An empty PolyTree object can be passed as the solution parameter to a Clipper object's Execute method. Once the clipping operation is completed, this method returns with the PolyTree structure filled with data representing the solution.

A PolyTree object is a container for any number of PolyNode children, with each contained PolyNode representing a single polygon contour (either an outer or hole polygon). PolyTree itself is a specialized PolyNode whose immediate children represent the top-level outer polygons of the solution. (Its own Contour property is always empty.) The contained top-level PolyNodes may contain their own PolyNode children representing hole polygons that may also contain children representing nested outer polygons etc. Children of outers will always be holes, and children of holes will always be outers.

PolyTrees can also contain open paths. Open paths will always be represented by top level PolyNodes. Two functions are provided to quickly separate out open and closed paths from a polytree - OpenPathsFromPolyTree and ClosedPathsFromPolyTree.

@@ -101,8 +101,7 @@

Hierarchy

Reference

- @@ -111,16 +110,12 @@

Reference

- - - - - - + + +
Fields - Methods +
Methods Properties
- Clear Total
- GetFirst @@ -131,32 +126,24 @@

Reference

- GetNext ChildCount
- Childs
- Contour
- IsHole @@ -165,6 +152,10 @@

Reference

IsOpen +
Parent @@ -172,9 +163,9 @@

Reference

See Also

-

Overview, Clipper, Clipper.Execute, PolyNode, Polygons

+

Overview, Clipper, Clipper.Execute, PolyNode, ClosedPathsFromPolyTree, OpenPathsFromPolyTree, Paths

- + diff --git a/Documentation/Docs/Units/ClipperLib/Routines/Area.htm b/Documentation/Docs/Units/ClipperLib/Functions/Area.htm similarity index 74% rename from Documentation/Docs/Units/ClipperLib/Routines/Area.htm rename to Documentation/Docs/Units/ClipperLib/Functions/Area.htm index 3e7e8da..feaee1c 100644 --- a/Documentation/Docs/Units/ClipperLib/Routines/Area.htm +++ b/Documentation/Docs/Units/ClipperLib/Functions/Area.htm @@ -51,21 +51,21 @@

Area

-

Del.» function Area(const pts: TPolygon): double;

+

Del.» function Area(const pts: TPath): double;

-

C++ » double Area(const Polygon &poly);

+

C++ » double Area(const Path &poly);

-

C#  » public static double Area(Polygon poly);

+

C#  » public static double Area(Path poly);

-

This function returns the area of the supplied polygon. Depending on orientation, this value may be positive or negative. If Orientation is true, then the area will be positive and conversely, if Orientation is false, then the area will be negative.

+

This function returns the area of the supplied polygon. (It's assumed that the path will be closed.) Depending on orientation, this value may be positive or negative. If Orientation is true, then the area will be positive and conversely, if Orientation is false, then the area will be negative.


See Also

-

Orientation, Polygon

+

Orientation, Path

- + diff --git a/Documentation/Docs/Units/ClipperLib/Routines/CleanPolygon.htm b/Documentation/Docs/Units/ClipperLib/Functions/CleanPolygon.htm similarity index 56% rename from Documentation/Docs/Units/ClipperLib/Routines/CleanPolygon.htm rename to Documentation/Docs/Units/ClipperLib/Functions/CleanPolygon.htm index 8ec5efc..d15d0b1 100644 --- a/Documentation/Docs/Units/ClipperLib/Routines/CleanPolygon.htm +++ b/Documentation/Docs/Units/ClipperLib/Functions/CleanPolygon.htm @@ -51,35 +51,37 @@

CleanPolygon

-

Del.» function CleanPolygon(const Poly: TPolygon; Distance: double = 1.415): TPolygon;

+

Del.» function CleanPolygon(const Poly: TPath; Distance: double = 1.415): TPath;

-

C++ » void CleanPolygon(Polygon &in_poly, Polygon &out_poly, double distance = 1.415);

+

C++ » void CleanPolygon(const Path &in_poly, Path &out_poly, double distance = 1.415);

-

C#  » public static Polygon CleanPolygon(Polygon poly, double distance = 1.415);

+

C++ » void CleanPolygon(Path &poly, double distance = 1.415);

+ +

C#  » public static Path CleanPolygon(Path poly, double distance = 1.415);


Removes vertices:

    -
  • that join co-linear edges
  • +
  • that join co-linear edges, or join edges that are almost co-linear (such that if the vertex was moved no more than the specified distance the edges would be co-linear)
  • -
  • within the specified distance of an adjacent vertex
  • +
  • that are within the specified distance of an adjacent vertex
  • -
  • within the specified distance of a semi-adjacent vertex together with their out-lying vertices
  • +
  • that are within the specified distance of a semi-adjacent vertex together with their out-lying vertices

-

Vertices are semi-adjacent when they are separated by a single (out-lying) vertex. The distance parameter's default value approximates √2 so that adjacent or semi-adjacent vertices having their corresponding X and Y coordinates differing by no more than 1 unit will precipitate the removal of one the vertices (together with the out-lying vertex if they are semi-adjacent).

(C++ only: The in_poly and out_poly parameters can reference the same object.)

   

+

Vertices are semi-adjacent when they are separated by a single (out-lying) vertex.

The distance parameter's default value is approximately √2 so that a vertex will be removed when adjacent or semi-adjacent vertices having their corresponding X and Y coordinates differing by no more than 1 unit. (If the egdes are semi-adjacent the out-lying vertex will be removed too.)

C++ only: This function is overloaded. In the first definition, the in_poly and out_poly parameters can reference the same Path object though in that case the calling code might be clearer if the second definition (accepting a single Paths parameter) is used.

   

See Also

-

CleanPolygons, SimplifyPolygon, Polygon

+

CleanPolygons, SimplifyPolygon, Path

- + diff --git a/Documentation/Docs/Units/ClipperLib/Functions/CleanPolygons.htm b/Documentation/Docs/Units/ClipperLib/Functions/CleanPolygons.htm new file mode 100644 index 0000000..0af8039 --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Functions/CleanPolygons.htm @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + CleanPolygons + + + + + + + + + + + + + + + + + + + + + +

CleanPolygons

+ + +

Del.» function CleanPolygons(const Polys: TPaths; Distance: double = 1.415): TPaths;

+ +

C++ » void CleanPolygons(const Paths &in_polys, Paths &out_polys, double distance = 1.415);

+ +

C++ » void CleanPolygons(Paths &polys, double distance = 1.415);

+ +

C#  » public static Paths CleanPolygons(Paths polys, double distance = 1.415);

+
+ + +

Removes vertices: +

    + +
  • that join co-linear edges, or join edges that are almost co-linear (such that if the vertex was moved no more than the specified distance the edges would be co-linear)
  • + +
  • that are within the specified distance of an adjacent vertex
  • + +
  • that are within the specified distance of a semi-adjacent vertex together with their out-lying vertices
  • + +

+ +

Vertices are semi-adjacent when they are separated by a single (out-lying) vertex.

The distance parameter's default value is approximately √2 so that a vertex will be removed when adjacent or semi-adjacent vertices having their corresponding X and Y coordinates differing by no more than 1 unit. (If the egdes are semi-adjacent the out-lying vertex will be removed too.)

C++ only: This function is overloaded. In the first definition, the in_polys and out_polys parameters can reference the same Paths object though in that case the calling code might be clearer if the second definition (accepting a single Paths parameter) is used.

   

+ + + + +

See Also

+

CleanPolygon, SimplifyPolygons

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Functions/ClosedPathsFromPolyTree.htm b/Documentation/Docs/Units/ClipperLib/Functions/ClosedPathsFromPolyTree.htm new file mode 100644 index 0000000..d35e85e --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Functions/ClosedPathsFromPolyTree.htm @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + ClosedPathsFromPolyTree + + + + + + + + + + + + + + + + + + + + + +

ClosedPathsFromPolyTree

+ + +

Del.» function ClosedPathsFromPolyTree(PolyTree: TPolyTree): TPaths;

+ +

C++ » void ClosedPathsFromPolyTree(PolyTree& polytree, Paths& paths);

+ +

C#  » public static void ClosedPathsFromPolyTree(PolyTree polytree, Paths paths);

+
+ + +

This function filters out open paths from the PolyTree structure and returns only closed paths in a Paths structure.

+ +

See Also

+

PolyTree, Paths

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Routines/CleanPolygons.htm b/Documentation/Docs/Units/ClipperLib/Functions/MinkowskiDiff.htm similarity index 57% rename from Documentation/Docs/Units/ClipperLib/Routines/CleanPolygons.htm rename to Documentation/Docs/Units/ClipperLib/Functions/MinkowskiDiff.htm index b7890cf..a97f30d 100644 --- a/Documentation/Docs/Units/ClipperLib/Routines/CleanPolygons.htm +++ b/Documentation/Docs/Units/ClipperLib/Functions/MinkowskiDiff.htm @@ -22,7 +22,7 @@ - CleanPolygons + MinkowskiDiff @@ -48,37 +48,26 @@
-

CleanPolygons

+

MinkowskiDiff

-

Del.» function CleanPolygons(const Polys: TPolygons; Distance: double = 1.415): TPolygons;

+

Del.» function MinkowskiDiff(const Poly: TPath; const Path: TPath; IsClosed: Boolean): TPaths;

-

C++ » void CleanPolygons(Polygons &in_polys, Polygon &out_polys, double distance = 1.415);

+

C++ » void MinkowskiDiff(const Path& poly, const Path& path, Paths& solution, bool isClosed);

-

C#  » public static Polygons CleanPolygons(Polygons polys, double distance = 1.415);

+

C#  » public static Paths MinkowskiDiff(Path poly, Path path, bool isClosed);


-

Removes vertices: -

    - -
  • that join co-linear edges
  • - -
  • positioned within the specified distance of an adjacent vertex
  • - -
  • positioned within the specified distance of a semi-adjacent vertex together with their out-lying vertices
  • - -

- -

Vertices are semi-adjacent when they are separated by a single (out-lying) vertex. The distance parameter's default value approximates √2 so that adjacent or semi-adjacent vertices having their corresponding X and Y coordinates differing by no more than 1 unit will precipitate the removal of one the vertices (together with the out-lying vertex if they are semi-adjacent).

   

+

Minkowski Difference is performed by subtracting each point in a polygon from the set of points in an open or closed path. The resulting polygon (or polygons) define the region that the original polygon would have passed over had it had been moved from the beginning to the end of that path. A key feature of Minkowski Difference is that when it's applied to two polygons, the resulting polygon will contain the coordinate space origin when the original polygons overlap (ie when they collide).

See Also

-

CleanPolygon, SimplifyPolygons

+

MinkowskiSum, Path, Paths

- + diff --git a/Documentation/Docs/Units/ClipperLib/Functions/MinkowskiSum.htm b/Documentation/Docs/Units/ClipperLib/Functions/MinkowskiSum.htm new file mode 100644 index 0000000..494a670 --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Functions/MinkowskiSum.htm @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + MinkowskiSum + + + + + + + + + + + + + + + + + + + + + +

MinkowskiSum

+ + +

Del.» function MinkowskiSum(const Poly: TPath; const Path: TPath; IsClosed: Boolean): TPaths;

+ +

C++ » void MinkowskiSum(const Path& poly, const Path& path, Paths& solution, bool isClosed);

+ +

C#  » public static Paths MinkowskiSum(Path poly, Path path, bool isClosed);

+
+ + +

Minkowski Addition is performed by adding each point in a polygon to the set of points in an open or closed path. The resulting polygon (or polygons) define the region that the original polygon would have passed over had it had been moved from the beginning to the end of that path.

+ + + +

See Also

+

MinkowskiDiff, Path, Paths

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Routines/OffsetPolyLines.htm b/Documentation/Docs/Units/ClipperLib/Functions/OffsetPaths.htm similarity index 58% rename from Documentation/Docs/Units/ClipperLib/Routines/OffsetPolyLines.htm rename to Documentation/Docs/Units/ClipperLib/Functions/OffsetPaths.htm index 917ab82..4fb2233 100644 --- a/Documentation/Docs/Units/ClipperLib/Routines/OffsetPolyLines.htm +++ b/Documentation/Docs/Units/ClipperLib/Functions/OffsetPaths.htm @@ -22,7 +22,7 @@ - OffsetPolyLines + OffsetPaths @@ -48,35 +48,41 @@ -

OffsetPolyLines

+

OffsetPaths

-

Del.» function OffsetPolyLines(const Polylines: TPolygons; const Delta: Double; JoinType: TJoinType = jtSquare; EndType: TEndType = etSquare; Limit: double = 0.0): TPolygons;

+

Del.» function OffsetPaths(const polys: Paths; const delta: double; JoinType: TJoinType = jtSquare; EndType: TEndType = etClosed; Limit: double = 0.0): TPaths;

-

C++ » void OffsetPolyLines(const Polygons &in_polys, Polygons &out_polys, double delta, JoinType jointype = jtSquare, EndType endtype = etSquare, double limit = 0.0);

+

C++ » void OffsetPaths(const Paths &in_polys, Paths &out_polys, double delta, JoinType jointype = jtSquare, EndType endtype = etClosed, double limit = 0.0);

-

C#  » public static Polygons OffsetPolyLines(Polygons polylines, double delta, JoinType jointype = JoinType.jtSquare, EndType endtype = EndType.etSquare, double limit = 0.0);

+

C#  » public static Paths OffsetPaths(Paths polys, double delta, JoinType jointype = JoinType.jtSquare, EndType endtype = EndType.etClosed, double limit = 0.0);


-

This function offsets or grows the supplied polylines both inward and outward by the delta amount so that the resulting 'line' will have a width of twice delta.

The polylines parameter (in_polys & out_polys in C++) represents a collection vertices that define one or more line contours. These contours are open by default, unless the EndType paramter indicates otherwise. (C++ only: The in_polys and out_polys parameters can reference the same object.)

Edge joins may be one of three jointypes - jtMiter, jtSquare or jtRound.

Line ends may be one of four endtypes - etClosed, etButt, etSquare or etRound. (See the image below for examples.)



Just as with the OffsetPolygons function, the meaning and use of the limit parameter depends on joinType: +

This function offsets the 'polys' parameter by the 'delta' amount. 'polys' may be open or closed paths. With closed paths (polygons), positive delta values 'expand' outer contours and 'shrink' inner 'hole' contours. Negative deltas do the reverse. With open paths (lines), the sign of the delta value is ignored since it's not possible to 'shrink' open paths.

(C++ only: The in_polys and out_polys parameters can reference the same object.)

+ + +

Edge joins may be one of three jointypes - jtMiter, jtSquare or jtRound. (See the image below for examples.)



The meaning and use of the limit parameter depends on jointype:

    -
  • jtMiter: limit sets the maximum distance in multiples of delta that vertices can be offset from their original positions before squaring is applied. The default value is 2 (ie twice delta) which is also the smallest allowed value. If offsetting was allowed without any limits (ie without squaring), then offsetting at very acute angles would produce unacceptably long 'spikes'.
  • +
  • jtMiter: limit sets the maximum distance in multiples of delta that vertices can be offset from their original positions before squaring is applied. The default value is 2 (ie twice delta) which is also the smallest allowed value. If the angle is acute enough to require squaring, then squaring will occur at 1 times delta. If offsetting was allowed without any limits (ie without squaring), then offsetting at very acute angles would produce unacceptably long 'spikes'.
  • jtRound: limit sets the maximum distance that rounded joins can deviate from their true arcs (since it would require an infinite number of vertices to perfectly represent an arc). The default limit is 0.25 units though realistically precision can never be better than 0.5 since arc coordinates will still be rounded to integer values. When offsetting polygons with very large coordinate values (typically as a result of scaling), it's advisable to increase limit to maintain consistent precisions at all joins because the maximum number of vertices allowed in any arc is 222. (This hard coded upper limit has been chosen because the imprecision in a circle constructed with 222 vertices will be only 1/10000th its radius and, not only is creating very large numbers of arc vertices computationally expensive, it can cause out-of-memory problems.)
  • -
  • jtSquare: The limit parameter is ignored.
  • +
  • jtSquare: The limit parameter is ignored since squaring will be applied uniformally at 1 times delta.

+
+ +

Self-intersections in closed paths must be removed before the paths are passed to OffsetPaths.

See Also

-

OffsetPolygons, EndType, JoinType, Polygon

+

JoinType, Path

- + diff --git a/Documentation/Docs/Units/ClipperLib/Functions/OpenPathsFromPolyTree.htm b/Documentation/Docs/Units/ClipperLib/Functions/OpenPathsFromPolyTree.htm new file mode 100644 index 0000000..456f87b --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Functions/OpenPathsFromPolyTree.htm @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + OpenPathsFromPolyTree + + + + + + + + + + + + + + + + + + + + + +

OpenPathsFromPolyTree

+ + +

Del.» function OpenPathsFromPolyTree(PolyTree: TPolyTree): TPaths;

+ +

C++ » void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);

+ +

C#  » public static void OpenPathsFromPolyTree(PolyTree polytree, Paths paths);

+
+ + +

This function filters out closed paths from the PolyTree structure and returns only open paths in a Paths structure.

+ +

See Also

+

PolyTree, Paths

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Routines/Orientation.htm b/Documentation/Docs/Units/ClipperLib/Functions/Orientation.htm similarity index 66% rename from Documentation/Docs/Units/ClipperLib/Routines/Orientation.htm rename to Documentation/Docs/Units/ClipperLib/Functions/Orientation.htm index 1dabff8..b8e0f85 100644 --- a/Documentation/Docs/Units/ClipperLib/Routines/Orientation.htm +++ b/Documentation/Docs/Units/ClipperLib/Functions/Orientation.htm @@ -51,14 +51,14 @@

Orientation

-

Del.» function Orientation(const poly: TPolygon): boolean;

+

Del.» function Orientation(const poly: TPath): boolean;

-

C++ » bool Orientation(const Polygon &poly); // Function in the ClipperLib namespace.

+

C++ » bool Orientation(const Path &poly); // Function in the ClipperLib namespace.

-

C#  » public static bool Orientation(Polygon poly); // Static method of the Clipper class in the ClipperLib namespace.

+

C#  » public static bool Orientation(Path poly); // Static method of the Clipper class in the ClipperLib namespace.

-

Given that polygon vertices are declared in a specific order, orientation refers to the direction (clockwise or counter-clockwise) that these vertices progress around the contents of a polygon.

Orientation is also dependent on axis direction:
+

Orientation is only important to closed paths. Given that vertices are declared in a specific order, orientation refers to the direction (clockwise or counter-clockwise) that these vertices progress around a closed path.

Orientation is also dependent on axis direction:

  • On Y-axis positive upward displays, Orientation will return true if the polygon's orientation is counter-clockwise.
  • @@ -71,23 +71,21 @@

    Orientation



    Notes:

      -
    • Self-intersecting polygons have indeterminate orientations. If a self-intersecting polygon is passed to this function it won't return a predictable result.
    • +
    • Self-intersecting polygons have indeterminate orientations in which case this function won't return a meaningful value.
    • The majority of 2D graphic display libraries (eg GDI, GDI+, XLib, Cairo, AGG, Graphics32) and even the SVG file format have their coordinate origins at the top-left corner of their respective viewports with their Y axes increasing downward. However, some display libraries (eg Quartz, OpenGL) have their coordinate origins undefined or in the classic bottom-left position with their Y axes increasing upward.
    • For Non-Zero filled polygons, the orientation of holes must be opposite that of outer polygons.
    • -
    • For polygons in the solution returned by Clipper's Execute method, their orientations will always be true for outer polygons and false for hole polygons (unless the ReverseSolution property has been enabled).
    • - -
    • For the OffsetPolygons function to work as expected, outer polygons must have a true orientation and hole polygons must have a false orientation.
    • +
    • For closed paths (polygons) in the solution returned by Clipper's Execute method, their orientations will always be true for outer polygons and false for hole polygons (unless the ReverseSolution property has been enabled).


    See Also

    -

    Overview, Clipper.ReverseSolution, OffsetPolygons, Polygon

    +

    Overview, Clipper.ReverseSolution, Path

    - + diff --git a/Documentation/Docs/Units/ClipperLib/Functions/PolyTreeToPaths.htm b/Documentation/Docs/Units/ClipperLib/Functions/PolyTreeToPaths.htm new file mode 100644 index 0000000..accc8d5 --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Functions/PolyTreeToPaths.htm @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + PolyTreeToPaths + + + + + + + + + + + + + + + + + + + + + +

    PolyTreeToPaths

    + + +

    Del.» function PolyTreeToPaths(PolyTree: TPolyTree): TPaths;

    + +

    C++ » void PolyTreeToPaths(PolyTree& polytree, Paths& paths);

    + +

    C#  » public static void PolyTreeToPaths(PolyTree polytree, Paths paths);

    +
    + + +

    This function converts a PolyTree structure into a Paths structure.

    + +

    See Also

    +

    PolyTree, Paths

    + + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Routines/ReversePolygon.htm b/Documentation/Docs/Units/ClipperLib/Functions/ReversePath.htm similarity index 80% rename from Documentation/Docs/Units/ClipperLib/Routines/ReversePolygon.htm rename to Documentation/Docs/Units/ClipperLib/Functions/ReversePath.htm index 223f50d..c474131 100644 --- a/Documentation/Docs/Units/ClipperLib/Routines/ReversePolygon.htm +++ b/Documentation/Docs/Units/ClipperLib/Functions/ReversePath.htm @@ -22,7 +22,7 @@ - ReversePolygon + ReversePath @@ -48,23 +48,23 @@ -

    ReversePolygon

    +

    ReversePath

    -

    Del.» function ReversePolygon(const polys: TPolygon): TPolygon;

    +

    Del.» function ReversePath(const polys: TPath): TPath;

    -

    C++ » void ReversePolygon(const Polygon &p);

    +

    C++ » void ReversePath(const Path &p);

    -

    C#  » //Call Polygon.Reverse().

    +

    C#  » //Call Path.Reverse().


    -

    Reverses the vertex order (and hence orientation) in the specified polygon.

    +

    Reverses the vertex order (and hence orientation) in the specified path.

    See Also

    -

    Polygon

    +

    Path

    - + diff --git a/Documentation/Docs/Units/ClipperLib/Routines/ReversePolygons.htm b/Documentation/Docs/Units/ClipperLib/Functions/ReversePaths.htm similarity index 81% rename from Documentation/Docs/Units/ClipperLib/Routines/ReversePolygons.htm rename to Documentation/Docs/Units/ClipperLib/Functions/ReversePaths.htm index 4659aa5..0464285 100644 --- a/Documentation/Docs/Units/ClipperLib/Routines/ReversePolygons.htm +++ b/Documentation/Docs/Units/ClipperLib/Functions/ReversePaths.htm @@ -22,7 +22,7 @@ - ReversePolygons + ReversePaths @@ -48,22 +48,22 @@ -

    ReversePolygons

    +

    ReversePaths

    -

    Del.» function ReversePolygons(const polys: TPolygons): TPolygons;

    +

    Del.» function ReversePaths(const p: TPaths): TPaths;

    -

    C++ » void ReversePolygons(const Polygons &p);

    +

    C++ » void ReversePaths(const Paths &p);

    -

    C#  » void ReversePolygons( Polygons polys );

    +

    C#  » void ReversePaths( Paths p );


    -

    Reverses the vertex order (and hence orientation) in every polygon.

    +

    Reverses the vertex order (and hence orientation) in each contained path.

    - + diff --git a/Documentation/Docs/Units/ClipperLib/Routines/SimplifyPolygon.htm b/Documentation/Docs/Units/ClipperLib/Functions/SimplifyPolygon.htm similarity index 65% rename from Documentation/Docs/Units/ClipperLib/Routines/SimplifyPolygon.htm rename to Documentation/Docs/Units/ClipperLib/Functions/SimplifyPolygon.htm index 16f1241..f2a2939 100644 --- a/Documentation/Docs/Units/ClipperLib/Routines/SimplifyPolygon.htm +++ b/Documentation/Docs/Units/ClipperLib/Functions/SimplifyPolygon.htm @@ -51,24 +51,24 @@

    SimplifyPolygon

    -

    Del.» function SimplifyPolygon(const Poly: TPolygon; FillType: TPolyFillType = pftEvenOdd): TPolygons;

    +

    Del.» function SimplifyPolygon(const Poly: TPath; FillType: TPolyFillType = pftEvenOdd): TPaths;

    -

    C++ » void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys,
            PolyFillType fillType = pftEvenOdd);

    +

    C++ » void SimplifyPolygon(const Path &in_poly, Paths &out_polys,
            PolyFillType fillType = pftEvenOdd);

    -

    C#  » public static Polygons SimplifyPolygon(Polygon poly,
            PolyFillType fillType = PolyFillType.pftEvenOdd);

    +

    C#  » public static Paths SimplifyPolygon(Path poly,
            PolyFillType fillType = PolyFillType.pftEvenOdd);


    -

    Removes self-intersections from the supplied polygon (by performing a boolean union operation using the nominated PolyFillType).
    Polygons with non-contiguous duplicate vertices (ie 'touching') will be split into two polygons.

    C++ only: The in_polys and out_polys parameters can reference the same object.


    +

    Removes self-intersections from the supplied polygon (by performing a boolean union operation using the nominated PolyFillType).
    Polygons with non-contiguous duplicate vertices (ie 'touching') will be split into two polygons.


    See Also

    -

    Clipper.ForceSimple, CleanPolygon, PolyFillType, Polygon

    +

    Clipper.StrictlySimple, CleanPolygon, Path, PolyFillType

    - + diff --git a/Documentation/Docs/Units/ClipperLib/Routines/SimplifyPolygons.htm b/Documentation/Docs/Units/ClipperLib/Functions/SimplifyPolygons.htm similarity index 57% rename from Documentation/Docs/Units/ClipperLib/Routines/SimplifyPolygons.htm rename to Documentation/Docs/Units/ClipperLib/Functions/SimplifyPolygons.htm index 05f0d9f..acc8e8e 100644 --- a/Documentation/Docs/Units/ClipperLib/Routines/SimplifyPolygons.htm +++ b/Documentation/Docs/Units/ClipperLib/Functions/SimplifyPolygons.htm @@ -51,23 +51,25 @@

    SimplifyPolygons

    -

    Del.» function SimplifyPolygons(const polys: TPolygons;
            FillType: TPolyFillType = pftEvenOdd): TPolygons;

    +

    Del.» function SimplifyPolygons(const polys: TPaths;
            FillType: TPolyFillType = pftEvenOdd): TPaths;

    -

    C++ » void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys,
            PolyFillType fillType = pftEvenOdd);

    +

    C++ » void SimplifyPolygons(const Paths &in_polys, Paths &out_polys,
            PolyFillType fillType = pftEvenOdd);

    -

    C#  » public static Polygons SimplifyPolygons(Polygons polys,
            PolyFillType fillType = PolyFillType.pftEvenOdd);

    +

    C++ » void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);

    + +

    C#  » public static Polygons SimplifyPolygons(Paths polys,
            PolyFillType fillType = PolyFillType.pftEvenOdd);


    -

    Removes self-intersections from the supplied polygons (by performing a boolean union operation using the nominated PolyFillType).
    Polygons with non-contiguous duplicate vertices (ie 'touching') will be split into two polygons.

    C++ only: The in_polys and out_polys parameters can reference the same Polygons object.


    +

    Removes self-intersections from the supplied polygons (by performing a boolean union operation using the nominated PolyFillType).
    Polygons with non-contiguous duplicate vertices (ie 'vertices are touching') will be split into two polygons.

    C++ only: This function is overloaded. In the first definition, the in_polys and out_polys parameters can reference the same Paths object though in that case the calling code might be clearer if the second definition (accepting a single Paths parameter) is used.


    See Also

    -

    Clipper.ForceSimple, CleanPolygons, PolyFillType

    +

    Clipper.StrictlySimple, CleanPolygons, PolyFillType

    - + diff --git a/Documentation/Docs/Units/ClipperLib/PreProcessor/Defines.htm b/Documentation/Docs/Units/ClipperLib/PreProcessor/Defines.htm new file mode 100644 index 0000000..4845f09 --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/PreProcessor/Defines.htm @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + Defines + + + + + + + + + + + + + + + + + + + + + +

    Defines

    + + +

    Del.»
     {$DEFINE use_int32}
     {$DEFINE use_xyz}
     {$DEFINE use_lines}
     {$DEFINE use_deprecated}

    + +

    C++ »
     #define use_int32
     #define use_xyz
     #define use_lines
     #define use_deprecated

    + +

    C#  »
     #define use_int32
     #define use_xyz
     #define use_lines
     #define use_deprecated

    + + +

    PreProcessor Defines:

    use_int32:
    When enabled 32bit integers are used instead of 64bit integers. This improves clipping performance by about 20-30% but coordinate values are limited to the range ± 46340. (Disabled by default)

    use_xyz:
    Adds a 'Z' member to IntPoint with only a minor cost to perfomance. For more details see Clipper's ZFillFunction property. (Disabled by default)

    use_lines:
    Enables open path (line) clipping. If line clipping is disabled, there's generally a very small (ie ~5%) improvement in performance. (Enabled by default)

    use_deprecated:
    Enables code developed with versions of Clipper prior to version 6 to compile without changes.
    This exposes compatability code that will be removed in a future update. (Enabled by default)

    + +

    See Also

    +

    Clipper.ZFillFunction, IntPoint

    + + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Routines/OffsetPolygons.htm b/Documentation/Docs/Units/ClipperLib/Routines/OffsetPolygons.htm deleted file mode 100644 index 050325a..0000000 --- a/Documentation/Docs/Units/ClipperLib/Routines/OffsetPolygons.htm +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - OffsetPolygons - - - - - - - - - - - - - - - - - - - - - -

    OffsetPolygons

    - - -

    Del.» function OffsetPolygons(const polys: TPolygons; const delta: double; JoinType: TJoinType = jtSquare; Limit: double = 0.0; AutoFix: boolean = true): TPolygons;

    - -

    C++ » void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, double delta, JoinType jointype = jtSquare, double limit = 0.0, bool autoFix = true);

    - -

    C#  » public static Polygons OffsetPolygons(Polygons polys, double delta, JoinType jointype = JoinType.jtSquare, double limit = 0.0, bool autoFix = true);

    -
    - - -

    This function offsets the 'polys' polygons parameter by the 'delta' amount. Positive delta values expand outer polygons and contract inner 'hole' polygons. Negative deltas do the reverse.

    (C++ only: The in_polys and out_polys parameters can reference the same object.)

    - - -

    Edge joins may be one of three jointypes - jtMiter, jtSquare or jtRound. (See the image below for examples.)



    Just as with the OffsetPolyLines function, the meaning and use of the limit parameter depends on joinType: -

      - -
    • jtMiter: limit sets the maximum distance in multiples of delta that vertices can be offset from their original positions before squaring is applied. The default value is 2 (ie twice delta) which is also the smallest allowed value. If offsetting was allowed without any limits (ie without squaring), then offsetting at very acute angles would produce unacceptably long 'spikes'.
    • - -
    • jtRound: limit sets the maximum distance that rounded joins can deviate from their true arcs (since it would require an infinite number of vertices to perfectly represent an arc). The default limit is 0.25 units though realistically precision can never be better than 0.5 since arc coordinates will still be rounded to integer values. When offsetting polygons with very large coordinate values (typically as a result of scaling), it's advisable to increase limit to maintain consistent precisions at all joins because the maximum number of vertices allowed in any arc is 222. (This hard coded upper limit has been chosen because the imprecision in a circle constructed with 222 vertices will be only 1/10000th its radius and, not only is creating very large numbers of arc vertices computationally expensive, it can cause out-of-memory problems.)
    • - -
    • jtSquare: The limit parameter is ignored.
    • - -

    - -

    - - -

    The polygons passed to OffsetPolygons must not be self-intersecting and need to be oriented such that outer polygons have a true orientation and hole polygons have a false orientation. If the orientations of input polygons are incorrect, the function will return unexpected results. Likewise, 'duplicate vertices' (ie consecutive vertices with identical coordinates, including start and end vertices) cause problems with the offset algorithm.

    The autoFix parameter when true will force the function to check for and fix incorrect polygon orientations and remove duplicate vertices. However, if orientations are known to be correct and there's no likelihood of duplicate vertices, then it's advisable to set autoFix to false since 'auto-fixing' is computationally expensive.

    Offsetting self-intersecting polygons can be achieved by first calling SimplyPolygons.

    -
    - - - -

    See Also

    -

    Overview, OffsetPolyLines, Orientation, SimplifyPolygons, JoinType, Polygon

    - - - - - - \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Types/CInt.htm b/Documentation/Docs/Units/ClipperLib/Types/CInt.htm new file mode 100644 index 0000000..eabe93b --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Types/CInt.htm @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + CInt + + + + + + + + + + + + + + + + + + + + + +

    CInt

    + + +

    Del.»
    {$IFDEF use_int32}
     cInt = Int32;
    {$ELSE}
      cInt = Int64;
    {$ENDIF}

    + +

    C++ »
    #ifdef use_int32
      typedef int cInt;
    #else
      typedef signed long long cInt;
    #endif

    + +

    C#  »
    #if use_int32
      using cInt = Int32;
    #else
      using cInt = Int64;
    #endif

    + + +

    cInt is the integer type used by the Clipper Library.

    If the preprocessor directive use_int32 has been defined (it is left undefined by default), cInt will represent a signed 32bit integer, otherwise it will represent a signed 64bit integer. Clipping performance can be improved by 20-30% when use_int32 is enabled but the trade-off is that coordinate values are restricted to a much narrower range (± 46340).

    + +

    See Also

    +

    Defines

    + + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Types/ClipType.htm b/Documentation/Docs/Units/ClipperLib/Types/ClipType.htm index 1d013e4..b04eb81 100644 --- a/Documentation/Docs/Units/ClipperLib/Types/ClipType.htm +++ b/Documentation/Docs/Units/ClipperLib/Types/ClipType.htm @@ -73,14 +73,27 @@

    ClipType


-


     

All polygon clipping is performed with a Clipper object with the specific boolean operation indicated by the ClipType parameter passed in its Execute method.

+


     

All polygon clipping is performed with a Clipper object with the specific boolean operation indicated by the ClipType parameter passed in its Execute method.


+ + +

With regard to open paths (polylines), clipping rules generally match those of closed paths (polygons).
However, when there are both polyline and polygon subjects, the following clipping rules apply: +

    + +
  • union operations - polylines will be clipped by any overlapping polygons so that non-overlapped portions will be returned in the solution together with the union-ed polygons
  • + +
  • intersection, difference and xor operations - polylines will be clipped only by 'clip' polygons and there will be not interaction between polylines and subject polygons.
  • + +


+ + +

Example of clipping behaviour when mixing polyline and polygon subjects:

See Also

Overview, Clipper, Clipper.Execute, PolyFillType

- + diff --git a/Documentation/Docs/Units/ClipperLib/Types/EndType.htm b/Documentation/Docs/Units/ClipperLib/Types/EndType.htm index fd731f4..92c8327 100644 --- a/Documentation/Docs/Units/ClipperLib/Types/EndType.htm +++ b/Documentation/Docs/Units/ClipperLib/Types/EndType.htm @@ -59,10 +59,10 @@

EndType


-

The OffsetPolyLines function has an EndType parameter that accepts one of four end types: +

The OffsetPaths function has an EndType parameter that accepts one of four end types:

    -
  • etClosed: Ends are joined using the JoinType style.
  • +
  • etClosed: There are no ends in a closed path.
  • etButt: Ends are squared off abruptly.
  • @@ -72,12 +72,14 @@

    EndType

-

+



Note: The order of the vertices in the last example has been changed because the OffsetPaths function does not accept self-intersecting closed paths. Self-intersecting closed paths must be 'simplified' before offsetting. The first 3 examples above show offsetting of open paths. There are no limitations to offsetting on open paths.

+ +

See Also

-

OffsetPolyLines, JoinType

+

OffsetPaths, JoinType

- + diff --git a/Documentation/Docs/Units/ClipperLib/Types/ExPolygons.htm b/Documentation/Docs/Units/ClipperLib/Types/ExPolygons.htm deleted file mode 100644 index 585d1a9..0000000 --- a/Documentation/Docs/Units/ClipperLib/Types/ExPolygons.htm +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - - - - - - - - - - - - - - - ExPolygons - - - - - - - - - - - - - - - - - - - - - -

ExPolygons

- - -

-

ExPolygons

- -

In Clipper Ver 5.1, the ExPolygons structure was replaced with the PolyTree class.

The PolyTreeToExPolygons() function below and its accompanying code may be useful if for some reason you are stuck with using ExPolygons.

- - - - - - - -
Delphi ... -
- -
-
-  type
-    TExPolygon = record
-      Outer: TPolygon;
-      Holes: TPolygons;
-    end;
-    TExPolygons = array of TExPolygon;
-
-  procedure AddOuterPolyNodeToExPolygons(PolyNode: TPolyNode; 
-    var ExPolygons: TExPolygons);
-  var
-    I, J, Cnt: Integer;
-  begin
-    Cnt := Length(ExPolygons);
-    SetLength(ExPolygons, Cnt + 1);
-    ExPolygons[Cnt].Outer := PolyNode.Contour;
-    SetLength(ExPolygons[Cnt].Holes, PolyNode.ChildCount);
-    for I := 0 to PolyNode.ChildCount - 1 do
-    begin
-      ExPolygons[Cnt].Holes[I] := PolyNode.Childs[I].Contour;
-      //Add outer polygons contained by (nested within) holes ...
-      for J := 0 to PolyNode.Childs[I].ChildCount - 1 do
-        AddOuterPolyNodeToExPolygons(PolyNode.Childs[I].Childs[J], ExPolygons);
-    end;
-  end;
-
-  function PolyTreeToExPolygons(PolyTree: TPolyTree): TExPolygons;
-  var
-    I: Integer;
-  begin
-    Result := nil;
-    for I := 0 to PolyTree.ChildCount - 1 do
-      AddOuterPolyNodeToExPolygons(PolyTree.Childs[I], Result);
-  end;
-          
- -


- - - - - - - -
C++ ... -
- -
-
-   struct ExPolygon {
-    Polygon outer;
-    Polygons holes;
-  };
-
-  typedef std::vector< ExPolygon > ExPolygons;
-
-  void AddOuterPolyNodeToExPolygons(PolyNode& polynode, ExPolygons& expolygons)
-  {  
-    size_t cnt = expolygons.size();
-    expolygons.resize(cnt + 1);
-    expolygons[cnt].outer = polynode.Contour;
-    expolygons[cnt].holes.resize(polynode.ChildCount());
-    for (int i = 0; i < polynode.ChildCount(); ++i)
-    {
-      expolygons[cnt].holes[i] = polynode.Childs[i]->Contour;
-      //Add outer polygons contained by (nested within) holes ...
-      for (int j = 0; j < polynode.Childs[i]->ChildCount(); ++j)
-        AddOuterPolyNodeToExPolygons(*polynode.Childs[i]->Childs[j], expolygons);
-    }
-  }
-
-  void PolyTreeToExPolygons(PolyTree& polytree, ExPolygons& expolygons)
-  {
-    expolygons.clear();
-    for (int i = 0; i < polytree.ChildCount(); ++i)
-      AddOuterPolyNodeToExPolygons(*polytree.Childs[i], expolygons);
-  }
-          
- -


- - - - - - - -
C# ... -
- -
-
-  using ExPolygons = List<ExPolygon>;	
-  using Polygon = List<IntPoint>;
-  using Polygons = List<List<IntPoint>>;
-
-  public struct ExPolygon {
-      public Polygon outer;
-      public Polygons holes;
-  }    
-
-  void AddOuterPolyNodeToExPolygons(PolyNode polynode, ref ExPolygons expolygons)
-  {  
-    ExPolygon ep = new ExPolygon();
-    ep.outer = new Polygon(polynode.Contour);
-    ep.holes = new Polygons(polynode.ChildCount);
-    foreach (PolyNode node in polynode.Childs)
-    {
-      ep.holes.Add(node.Contour);
-      //Add outer polygons contained by (nested within) holes ...
-      foreach (PolyNode n in node.Childs)
-          AddOuterPolyNodeToExPolygons(n, ref expolygons);
-    }
-    expolygons.Add(ep);
-  }
-
-  void PolyTreeToExPolygons(PolyTree polytree, ref ExPolygons expolygons)
-  {
-      expolygons.Clear();
-      foreach (PolyNode node in polytree.Childs)
-        AddOuterPolyNodeToExPolygons(node, ref expolygons);
-  }
-          
- -


-
 
- -

See Also

-

PolyTree

- - - - - - - \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Types/InitOptions.htm b/Documentation/Docs/Units/ClipperLib/Types/InitOptions.htm new file mode 100644 index 0000000..768f8d6 --- /dev/null +++ b/Documentation/Docs/Units/ClipperLib/Types/InitOptions.htm @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + InitOptions + + + + + + + + + + + + + + + + + + + + + +

InitOptions

+ + +

Del.» type TInitOption = (ioReverseSolution, ioStrictlySimple, ioPreserveCollinear);

+ +

C++ » enum InitOptions {
        ioReverseSolution  = 1,
        ioStrictlySimple   = 2,
        ioPreserveCollinear = 4};

+ +

C#  » public const int ioReverseSolution  = 1;
      public const int ioStrictlySimple   = 2;
      public const int ioPreserveCollinear = 4;

+
+ + +

+ + + + + +

See Also

+

Clipper.Constructor, Clipper.PreserveCollinear, Clipper.ReverseSolution, Clipper.StrictlySimple

+ + + + + + \ No newline at end of file diff --git a/Documentation/Docs/Units/ClipperLib/Types/IntPoint.htm b/Documentation/Docs/Units/ClipperLib/Types/IntPoint.htm index 5236a6e..1c530e4 100644 --- a/Documentation/Docs/Units/ClipperLib/Types/IntPoint.htm +++ b/Documentation/Docs/Units/ClipperLib/Types/IntPoint.htm @@ -50,23 +50,23 @@

IntPoint

-

Del.» TIntPoint = record X, Y: int64; end;

+

Del.» TIntPoint = record X, Y: cInt; end;

-

C++ » struct IntPoint { long64 X; long64 Y; ... };

+

C++ » struct IntPoint { cInt X; cInt Y; ... };

-

C#  » public class IntPoint { public Int64 X; { get; set; } public Int64 Y; { get; set; } ... };

+

C#  » public class IntPoint { public cInt X; { get; set; } public cInt Y; { get; set; } ... };


-

The IntPoint structure is used to represent all vertices in the Clipper Library. The integer storage type has been deliberately chosen to preserve numerical robustness. (Early versions of the library used floating point coordinates, but it became apparent that floating point imprecision would always cause occasional errors.)

A sequence of IntPoints are contained within a Polygon structure to represent a single polygon contour.

Users wishing to clip or offset polygons containing floating point coordinates need to use appropriate scaling (see notes on rounding) when converting these values to and from IntPoints.

+

The IntPoint structure is used to represent all vertices in the Clipper Library. An integer storage type has been deliberately chosen to preserve numerical robustness. (Early versions of the library used floating point coordinates, but it became apparent that floating point imprecision would always cause occasional errors.)

A sequence of IntPoints are contained within a Path structure to represent a single contour.

As of version 6, IntPoint now has an optional third member 'Z'. This can be enabled by exposing (ie uncommenting) the PreProcessor define 'use_xyz'. When the Z member is used, its values will be copied to corresponding verticies in solutions to clipping operations. However, at points of intersection where there's no corresponding Z value, the value will be assigned zero unless a new value is provided by a user supplied callback function.

Users wishing to clip or offset polygons containing floating point coordinates need to use appropriate scaling when converting these values to and from IntPoints.

See also the notes on rounding.

See Also

-

Rounding, long64, Polygon, Polygons

+

Rounding, Clipper.ZFillFunction, Defines, CInt, Path, Paths

- + diff --git a/Documentation/Docs/Units/ClipperLib/Types/IntRect.htm b/Documentation/Docs/Units/ClipperLib/Types/IntRect.htm index c14dd83..97ebcc5 100644 --- a/Documentation/Docs/Units/ClipperLib/Types/IntRect.htm +++ b/Documentation/Docs/Units/ClipperLib/Types/IntRect.htm @@ -50,19 +50,19 @@

IntRect

-

Del.»
TIntRect = record left, top, right, bottom: Int64; end;

+

Del.»
TIntRect = record left, top, right, bottom: cInt; end;

-

C++ »
struct IntPoint { long64 left; long64 top; long64 right; long64 bottom; ... };

+

C++ »
struct IntPoint { cInt left; cInt top; cInt right; cInt bottom; ... };

-

C#  »
public class IntPoint {
  public Int64 left; { get; set; }
  public Int64 top; { get; set; }
  public Int64 right; { get; set; }
  public Int64 bottom; { get; set; } ... };

+

C#  »
public class IntPoint {
  public cInt left; { get; set; }
  public cInt top; { get; set; }
  public cInt right; { get; set; }
  public cInt bottom; { get; set; } ... };

Structure returned by Clipper's GetBounds method.


See Also

-

ClipperBase.GetBounds, Long64

+

ClipperBase.GetBounds, CInt

- + diff --git a/Documentation/Docs/Units/ClipperLib/Types/JoinType.htm b/Documentation/Docs/Units/ClipperLib/Types/JoinType.htm index c46a1ef..c2b6937 100644 --- a/Documentation/Docs/Units/ClipperLib/Types/JoinType.htm +++ b/Documentation/Docs/Units/ClipperLib/Types/JoinType.htm @@ -59,7 +59,7 @@

JoinType


-

The OffsetPolygons function has a JoinType parameter that accepts one of three join types: +

The OffsetPaths function has a JoinType parameter that accepts one of three join types:

  • jtSquare: Convex edge joins are squared off at exactly delta units
  • @@ -70,13 +70,13 @@

    JoinType

-

  

+

  

See Also

-

OffsetPolygons

+

OffsetPaths

- + diff --git a/Documentation/Docs/Units/ClipperLib/Types/Polygon.htm b/Documentation/Docs/Units/ClipperLib/Types/Path.htm similarity index 59% rename from Documentation/Docs/Units/ClipperLib/Types/Polygon.htm rename to Documentation/Docs/Units/ClipperLib/Types/Path.htm index d387f7a..5300079 100644 --- a/Documentation/Docs/Units/ClipperLib/Types/Polygon.htm +++ b/Documentation/Docs/Units/ClipperLib/Types/Path.htm @@ -22,7 +22,7 @@ - Polygon + Path @@ -48,21 +48,21 @@ -

Polygon

+

Path

-

Del.» TPolygon = array of TIntPoint;

+

Del.» TPath = array of TIntPoint;

-

C++ » typedef std::vector<IntPoint> Polygon;

+

C++ » typedef std::vector<IntPoint> Path;

-

C#  » using Polygon = List<IntPoint>;

+

C#  » using Path = List<IntPoint>;


-

This structure contains a sequence of IntPoint vertices defining a single path (see also terminology). This path is almost always a closed path. The exception to this is when it's passed to the OffsetPolyLines function. There the polylines parameter represents an open path (unless otherwise indicated by the function's EndType parameter).

Multiple polygons (both outers and holes) are encapsulated within a Polygons structure.

+

This structure contains a sequence of IntPoint vertices defining a single contour (see also terminology). Paths may be open and represent line segments bounded by 2 or more vertices, or they may be closed and represent polygons.

Multiple paths can be grouped into a Paths structure.

See Also

-

Overview, Example, ClipperBase.AddPolygon, PolyTree, OffsetPolyLines, Orientation, EndType, IntPoint, Polygons

+

Overview, Example, ClipperBase.AddPath, PolyTree, Orientation, IntPoint, Paths

- + diff --git a/Documentation/Docs/Units/ClipperLib/Types/Polygons.htm b/Documentation/Docs/Units/ClipperLib/Types/Paths.htm similarity index 57% rename from Documentation/Docs/Units/ClipperLib/Types/Polygons.htm rename to Documentation/Docs/Units/ClipperLib/Types/Paths.htm index a8eedbb..7399e21 100644 --- a/Documentation/Docs/Units/ClipperLib/Types/Polygons.htm +++ b/Documentation/Docs/Units/ClipperLib/Types/Paths.htm @@ -22,7 +22,7 @@ - Polygons + Paths @@ -48,17 +48,17 @@ -

Polygons

+

Paths

-

Del.» TPolygons = array of TPolygon;

+

Del.» TPaths = array of TPath;

-

C++ » typedef std::vector< Polygon > Polygons;

+

C++ » typedef std::vector< Path > Paths;

-

C#  » using Polygons = List<List< IntPoint >>;

+

C#  » using Paths = List<List< IntPoint >>;


-

This structure is fundamental to the Clipper Library. It is used to provide polygon coordinate data to, and receive solutions from both clipping and offsetting operations.

Whether or not a contained polygon is a hole is determined by its orientation (NonZero filling rule) and its location relative to other polygons (EvenOdd filling rule).

+

This structure is fundamental to the Clipper Library. It's a list or array of one or more Path structures. (The Path structure contains an ordered list of vertices that make a single contour.)

Paths may open (lines), or they may closed (polygons).


@@ -67,9 +67,9 @@

Polygons

See Also

-

Overview, Clipper.Execute, ClipperBase.AddPolygon, ClipperBase.AddPolygons, OffsetPolygons, Orientation, IntPoint, PolyFillType, Polygon

+

Clipper.Execute, ClipperBase.AddPath, ClipperBase.AddPaths, OffsetPaths, IntPoint, Path

- + diff --git a/Documentation/Docs/Units/ClipperLib/Types/PolyFillType.htm b/Documentation/Docs/Units/ClipperLib/Types/PolyFillType.htm index 449ea2f..1d39ae6 100644 --- a/Documentation/Docs/Units/ClipperLib/Types/PolyFillType.htm +++ b/Documentation/Docs/Units/ClipperLib/Types/PolyFillType.htm @@ -59,23 +59,25 @@

PolyFillType


-

This parameter indicates the filling rule that's to be applied to a polygon or group of polygons.

The differences between the various fill rules can best be understood by determining the winding number of every polygon sub-region (ie those regions bounded by polygon edges).

Firstly, edge direction is determined by the order in which vertices are declared when constructing a polygon.

The winding number for any given polygon sub-region can be derived by:

    +

    Filling indicates regions that are inside a polygon (ie 'filled' with a brush color or pattern in a graphical display), and non-filling indicates regions outside polygons. The Clipper Library supports 4 filling rules: Even-Odd, Non-Zero, Positive and Negative.

    The simplest filling rule is Even-Odd filling. Given a group of polygons and starting from a point outside, whenever a contour is crossed either filling starts if it had stopped or it stops if it had started. For example, given a single rectangular polygon, when its first (eg left) edge is crossed filling starts and we're inside the polygon. Filling stops again when the next (eg right) edge is crossed.

    With the exception of Even-Odd filling, all other filling rules rely on edge direction and winding numbers to determine filling. Edge direction is determined by the order in which vertices are declared when constructing a polygon. Edge direction is used to determine the winding numbers of polygon regions and subregions.

    The winding number for any given polygon sub-region can be derived by:

    1. starting with a winding number of zero
    2. -
    3. from a point (P1) that's within the sub-region, draw an imaginary line to another point that's outside the polygon or polygons (P2)
    4. +
    5. from a point (P1) that's outside all polygons, draw an imaginary line to a point that's inside a given sub-region (P2)
    6. -
    7. while traversing the line from P1 to P2, for each polygon edge that crosses the line from left to right increment the winding number, and for each polygon edge that crosses the line from right to left decrement the winding number.
    8. +
    9. while traversing the line from P1 to P2, for each polygon edge that crosses the line from right to left increment the winding number, and for each polygon edge that crosses the line from left to right decrement the winding number.
    10. + +
    11. Once you arrive at the given sub-region you have its winding number.

    -


    Even-Odd (Alternate): Odd numbered sub-regions are filled, while even numbered sub-regions are not.
    Non-Zero (Winding): All non-zero sub-regions are filled.
    Positive: All sub-regions with winding counts > 0 are filled.
    Negative: All sub-regions with winding counts < 0 are filled.

            

    By far the most widely used fill rules are Even-Odd (aka Alternate) and Non-Zero (aka Winding). Most graphics rendering libraries (AGG, Android Graphics, Cairo, GDI+, OpenGL, Quartz 2D etc) and vector graphics storage formats (SVG, Postscript, Photoshop etc) support both these rules. However some libraries (eg Java's Graphics2D) only support one fill rule. Android Graphics and OpenGL are the only libraries (that I'm aware of) that support multiple filling rules.

    It's useful to note that edge direction has no affect on a winding number's odd-ness or even-ness. This means that orientation is unimportant when the Even-Odd rule is employed. Also, determining brush filling with the Even-Odd rule is very simple - fill whenever an edge has been crossed an odd number of times, and don't fill when an edge has been crossed an even number of times.

    The direction of the Y-axis affects polygon orientation and edge direction. However, changing Y-axis orientation will only change the sign of winding numbers, not their magnitudes, and has no effect on either Even-Odd or Non-Zero filling.

    +


    Even-Odd (Alternate): Odd numbered sub-regions are filled, while even numbered sub-regions are not.
    Non-Zero (Winding): All non-zero sub-regions are filled.
    Positive: All sub-regions with winding counts > 0 are filled.
    Negative: All sub-regions with winding counts < 0 are filled.

            

    By far the most widely used fill rules are Even-Odd (aka Alternate) and Non-Zero (aka Winding). Most graphics rendering libraries (AGG, Android Graphics, Cairo, GDI+, OpenGL, Quartz 2D etc) and vector graphics storage formats (SVG, Postscript, Photoshop etc) support both these rules. However some libraries (eg Java's Graphics2D) only support one fill rule. Android Graphics and OpenGL are the only libraries (that I'm aware of) that support multiple filling rules.

    It's useful to note that edge direction has no affect on a winding number's odd-ness or even-ness. (This is why orientation is ignored when the Even-Odd rule is employed.)

    The direction of the Y-axis does affect polygon orientation and edge direction. However, changing Y-axis orientation will only change the sign of winding numbers, not their magnitudes, and has no effect on either Even-Odd or Non-Zero filling.

    See Also

    -

    Clipper.Execute, Orientation

    +

    Clipper.Execute, Orientation

    - + diff --git a/Documentation/Docs/Units/ClipperLib/Types/PolyType.htm b/Documentation/Docs/Units/ClipperLib/Types/PolyType.htm index 8bf0202..b34f662 100644 --- a/Documentation/Docs/Units/ClipperLib/Types/PolyType.htm +++ b/Documentation/Docs/Units/ClipperLib/Types/PolyType.htm @@ -64,9 +64,9 @@

    PolyType

    See Also

    -

    ClipperBase.AddPolygon, ClipperBase.AddPolygons, ClipType

    +

    ClipperBase.AddPath, ClipperBase.AddPaths, ClipType

    - + diff --git a/Documentation/Docs/Units/ClipperLib/Types/long64.htm b/Documentation/Docs/Units/ClipperLib/Types/ZFillCallback.htm similarity index 67% rename from Documentation/Docs/Units/ClipperLib/Types/long64.htm rename to Documentation/Docs/Units/ClipperLib/Types/ZFillCallback.htm index ffedf3a..4e36b3d 100644 --- a/Documentation/Docs/Units/ClipperLib/Types/long64.htm +++ b/Documentation/Docs/Units/ClipperLib/Types/ZFillCallback.htm @@ -22,7 +22,7 @@ - long64 + ZFillCallback @@ -48,19 +48,23 @@ -

    long64

    +

    ZFillCallback

    -

    Del.» Equivalent to Int64

    +

    Del.» type TZFillCallback = procedure (const Z1, Z2: cInt; var Pt: TIntPoint);

    -

    C++ » typedef signed long long long64;

    +

    C++ » typedef void (*TZFillCallback)(cInt z1, cInt z2, IntPoint& pt);

    -

    C#  » Equivalent to Int64

    +

    C#  » public delegate void TZFillCallback(cInt Z1, cInt Z2, ref IntPoint pt);


    +

    + +

    See Also

    +

    Clipper.ZFillFunction

    - + diff --git a/Documentation/Docs/Units/ClipperLib/_Body.htm b/Documentation/Docs/Units/ClipperLib/_Body.htm index afec9df..adaa482 100644 --- a/Documentation/Docs/Units/ClipperLib/_Body.htm +++ b/Documentation/Docs/Units/ClipperLib/_Body.htm @@ -47,106 +47,162 @@

    ClipperLib

    -Unit clipper + + +

    Filenames: clipper.pas; clipper.hpp and clipper.cpp; clipper.cs

    Namespace: ClipperLib

    +

    Contents

    - - + - - + - - + - - + - + + + + + + + - + - - + + + + + + + - + - + + + + + + - + - - + - - +
    Types +
    PreProcessor + Types Classes - Routines + Functions
    ClipType + Defines + CInt Clipper Area + Area
    EndType + + ClipType ClipperBase CleanPolygon + CleanPolygon
    ExPolygons + + EndType PolyNode CleanPolygons + CleanPolygons
    IntPoint + + InitOptions PolyTree OffsetPolygons + ClosedPathsFromPolyTree
    + IntPoint + + MinkowskiDiff +
    + IntRect OffsetPolyLines + MinkowskiSum
    + JoinType Orientation + OffsetPaths
    long64 + + Path + + OpenPathsFromPolyTree +
    + Paths ReversePolygon + Orientation
    + PolyFillType ReversePolygons + PolyTreeToPaths +
    + PolyType + + ReversePath
    Polygon + + ZFillCallback SimplifyPolygon + ReversePaths
    Polygons + + SimplifyPolygons + SimplifyPolygon
    PolyType + SimplifyPolygons +
    - + diff --git a/Documentation/Docs/_Body.htm b/Documentation/Docs/_Body.htm index 8f0b890..d53d31b 100644 --- a/Documentation/Docs/_Body.htm +++ b/Documentation/Docs/_Body.htm @@ -47,7 +47,7 @@ -

    The Clipper Library - Version 5

    +

    The Clipper Library - Version 6

    @@ -61,10 +61,19 @@

    The Clipper Library - Version 5

    +
    Rounding Deprecated + License
    +

    PreProcessor Directives

    + + + + +
    Defines +
    @@ -81,58 +90,70 @@

    Classes

    Types

    - - - - - - - - - + -
    ClipType + CInt IntPoint + InitOptions long64 + JoinType Polygons + PolyFillType
    EndType + ClipType IntRect + IntPoint PolyFillType + Path PolyType
    ExPolygons + EndType JoinType + IntRect + Paths Polygon + ZFillCallback
    -

    Routines

    +

    Functions

    - - - - - - - + + + + + + - - -
    Area + Area CleanPolygons + ClosedPathsFromPolyTree OffsetPolyLines + OffsetPaths ReversePolygon + PolyTreeToPaths SimplifyPolygon + SimplifyPolygon
    CleanPolygon + CleanPolygon OffsetPolygons + MinkowskiDiff + OpenPathsFromPolyTree + ReversePath + SimplifyPolygons +
    CleanPolygons Orientation + MinkowskiSum ReversePolygons + Orientation SimplifyPolygons + ReversePaths
    @@ -144,7 +165,7 @@

    Units

    - + diff --git a/Documentation/Html_Docs.zip b/Documentation/Html_Docs.zip deleted file mode 100644 index 3c64bad25eef0ad375548bdcbbaac37bc42ce6f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 683537 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 z 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 TED6_=`6#gRVXMZ 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

    1j=K+TYDvt?tTUCRt^0k+9pV5 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

    ?6Q0FQuyx2%jju66| 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

    -Gph#L{^F)H}*ouY5^!^9MqUCFIU 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ʹrf$y+RI1gxoAO567-1N;{~}Ro;)~Xc$DXvI6yyq79JjuJ zjF3@Nv#zxT4NI6|IK9`dy&!xs^`vUL_K9lrD%E7a3*XoFw2F&~F`Pw?J-q(MU{tD7*U{R8%46LEsJRxc1L_}r+@LD7XJEb+dDxoDY*jD(#1er$dd>lX zD)tf7jHm)c1Z~GF#@^B`ap*A+Y|uQ^LXZ*-O3Pxg=d*9a8?4>60SSF-`vQ9y^7h0A0^~kblH;8RWW0Ms%rG6PpohBesrjd4{`8WIl5*&_B=Uc!?7C;}|W&~kV9 z2GO@>jb3y2$E%{u$8rwyvqT1D*TBbqQACCdbS>*{ED3;ff~+JbEKYbE&bs1J4z>iI z4o^EZ?cFRfu~xTx0_F*l8iMJ0RF|a*Z~*LrO<)rZoh_onVITm?yDZOt`qBhBu74Jy zUnm9kKEg85=Q}W;i6%o2QyC1`F_^jlS@#DUk*Ch5CkN&;v91+wf~?t{FSM;}i#}!$ zdbZK!pP4`;;$cwg$p{t380sD#s=Ku$MUaRu9?U&O@gRcl;K&Ad6+!BNO#oH+k0yXG ziCz(lej~66Fi}9LBwqZ{1b~@g%2b^;E4J>B+=;q)K|U^{<>t~X)_t`}PE(F@$PX1$%_uq9mYu?hKvctDI8~{ZxN1`yzB2-{?GIyx^;-0cCY9oP-EFTarex!j4Qxf} zfS|!;-FuPc%wvrJp!(xFyjST@9V!N+r63n}1^*By7E0C!y7w{V2kfDont@` zS+3P;xUtOD)H*@5ZA*3ZJRwziMS5HsTVb!U)UO!BRts7Ve=9pSwV*VT2#<2jNf5su z7|#&f8o`85in~fr7)+_Qk9Hxk)FMSGHuwk5d5~sdMvP+}EVL|}`$_ydfpZ)`ot){J z)DcaNF{{wQCyW3ZXi|Drgal={j*&nEP2NCIYD;V;EUlnekh_x>I3pB!5vT~C%!l3PBg8~R0h)#BP>gBB|im5H0K+r%u zL?rz|7|;%g1In73y#6KC^r)+Hb)c;2MJWm$EuUv5%uIU1tG|{7%9=JkhR~xc;SjT= zN{q+Xhjm^YZ(($f>kZx6L`~+?{uVQlN0OGYz5`DDaa3RXcwtAw`o$e@CSfSZ$)MHI zb%?v0+f=e%i5Oc}hFzAMgTbq2k?#p_{RQat5xk? z^?-vj-6?9s{+PG+E}Prj-_|Z{jGL>6MFybY_&S^x{yBO~wt#Vk zoGi+8>asC@!ms;WzId+U8wzl65#>B(!dFMFNVYi|a&mv7bh2N~`yRQFk2KZ7o4dxC z^7{m#n`R@)C9K$a<(?yJ+@`kihS)IZu#aL?&X1TWIb zJr3?vX6c+r$uIVv*Ip%l#34JNUl#rN=C)!KGP!Ce0caT+Z*d4Jf>8^B)fV3iLF6ou z$c6(9)ocN-;RYFe>QS5Bg?|WkFHToVdk9_FWmBy z4M3B*IzOh?UC5bc>f#YC4-m77@ZfzaZ?$Bm9!xGMJ#7sy{`C!_U<-|{OMcej8Y-o1fUtzCY9IgXI#iQ zIabY?v2Lxd(yt>Q@hmL-+G6Qd9yEm_5#62*imnucRu*$-X8Ky>iUmM6b9=s5wIawV zLUu2ruUF-IN6=OTHvEa1K>f4@zwKTwZVv8vb3^M&N?G?0RKr+_B=io>tgGkNd~T;g zqf^M}LB!vQIM3i{r?L6YU{Qu%orVqG!t`~jkE#e74c_g%2a<(I+*+pO8G#nHFRWg z$4jgzEinYMW(W%Gp?7ZQO=h&M9ke}s=VDKMs-3l-{U5xaXSpFPru=xQ^7;o#6n%w| zx}Ie^(Y$MImj0GQg~XxKwWN`rfTUh6HUC8gOUi?;F~X!QG&!!Exi-L=A~@YxAQ!J7 zQ`wAr;cukhwOsJq&tCnD%t*vIFT40wrG(0wRmuCcZpe0A_OJFqvAe@lp1s&ApmEx` zb|v;HO8I5K-?UJX#(kiYhnQWJ6&{~%p~Hu^t`_6C>Kh-YyJlU8`{nE2kU-E91SgZl zLJetKR9JLkq~jlPy$zz2Xhnmc*xk<#i(IY_zfQFqLEx*YR1ZyI;ji^};B#2!_f9$8nd(q}4>gGvcs}hQ+R(p-BUP5n zdRvW+VMej166z6Xd|2TL!M;%=J2}%IhxHw~8Opd98TD-Kaed!XfENu}4h=RDiM)A6 z9p<5NDNx^;I@GB$(qJ7&^F<9XFWiG&W|DKxH8rf0sZUM8L5t<`y0?LO>%Tin5aorq zBa4J@Ih(&n>?gT(H)<8>_|?ic^DgNuxu)(RZ~hPfE^Oni z%+0<$Etnf2Rs7~BWcJK)pPT#cTGp80LaM&~ie=evz+qSNGXWIH1SSq4b{x2MT?C^-g5s~Kz=UsvO*6KC5h z!#S;zV|F1>jf1mws6fG^+`m)4U z`Al|8uK@Hx615n@Wh4|iuZQJ72wtl3-k1Q zCMT;Xhw89E2Ffo~7M2rcsH(GiL7r@g_TXg+7A*-*bM%3W2(+q!UZFGgJfOChc_;{o z+Lm>tMdurMDXV1~FIScWzZ@uEod~`kv4o!56_xrU7zjP@4Zx>Fs$eGH^S|A9_o!gJb&B+@{OoNJEYp6|-xMSWyuMLbU*&_NcGHH<$c^8A%HZ4EixdudsuRy_)-C zmWz7prX{f?j93OqTQoXFy-8DzNo}~iDc7PqjWp44<3%nv9kIPJb-!d+Y=mOJ(BgLO zox#zMt!VE{2%vux48`T*N3Db*El-lF(M#iQn@q4yElx=)4sRm4)mASUCbYIcV*TN8 zfv!>@N)Q9XBeR%AK>kMXRbF|?hOT}0E&rS|mP@Q!6HiD1X73s)HWGwM6YS!Y!-c_) z;0pHGwBIdBt?g>X@zcnC8nl!YR?nY-pDpG3K3=B5Yn#yi@Z)fm)NB&-e8+}IUqN~i zI38Xe>L_#asZSL|a&iLmG-=B8AB&+T>)rq~NdC%Uw~qDZuiF7LAkFz1*yXQjExOCu z_46HHlS&%^!#@bBZU7`Y-`bGx9W;OEQ{t5?taQV!fNmARy7@msIGv?^y$Gy7@6?Zo zH?2#Hd?)uR5O6e4HQWqT@r)z|{NEK-h%chM~ahp!7#nO`F^F5C<~L?Joal(E)!eW8drx+b#V>aF2ud_3Yv=-I)A zxP31}!nFmB@@V{Cg`pBDdx)=mozzyc4rQBrAvNtskg@{!Ug3ZE8@Eln&_G91uj(@< zb^ZpGLTRwK8*Z2#6L8r9o80WY=xgkYgUYES7)A=b^8!I3^UB7TLl6b-I&9$-gx!3# zLk$k4YcJiooHbM-J49c&e93aQ7~Jovq)k`BomB-~Ugi9^xe;D)@*>4`!dfV`O?$3J zRgjE<8;{*1o`x4ZWg!(VS;}rzzwwEZ1G?k1cLGemPwpLag9A30{-=Jg+#p$a_0a**I z17=3uJ71a(*#fnTu z-{jnyW!bfy1D$};9I@$)*ESRDAdI7l8QG4s8}z9#HO9!A7`mdq+z3qO^r`wf`aE8W zN0?=Z^qk@c2{XwY=ASA9_=hp{8KTNM5je~Sz+vY6&vJ;rhWQ@_E7jFl;1&08m4b7XGdL~{Udis-1^ZSo-rqf~{iYkWT&%i3)zd3jt4lzjZ1 zkV4;iWyuI=kZp@=Y3MIpr3hpw`9jqml#2UWzCPNAFc=HM-8?hw{Ve^ zYVAzyV0I2CbhDqQP=C#)!wLYh(*Lj$H&Yv;L>BMhUSEbZPq0K`1jDC^Cn%T6&wmIb z$M1D1Jf_!8JD`kU*e&p`2{In#nRgxzmsbV0h{}F3YAq1iTaDT#;#aQLdu%s&HwAon z&2Km3$d9FlqVmitsQN@2oHWwPI|{Tei^8SGs!n`@p-t9QniNMtsrg$6=qFhjt4yxV z?_&&p*83B@lwXX$yZrRb7Sf^brtVg5j`AuH-a$|2*f$K85BU?1b5}(lo;RhVb@sA? zZf$9q{!2SGUY6E_Co3Ey5Tm$J-Eh=ggn^RzFqCSCHn5A90u!gmk0;+i)B#TA1cE-OqdGIE z%~zkC4kP>BqZ2+eG)Pa?W>te1tM6hxxZM)Yu zj+jwJaLySQ{M5xp!TxH{fI)*$a)n@is6+(kEPIvOx94W|86pIAWV)f6Eg!!Ucy{Na zeW$6^OHBlx-G-;`9P5v=C*xoXJ&|HL;waperh(%#vIQOq#bNA-npp8tE9_@47?kFV z1q=k%u%(}-Ngu%Oj+Qx1<8$cws${h%4pSb8?^De?s}BAj&fYON({9}wO~xJd6qW(8`--sAYglE;A?tY^52Sd7}wQD`1 z^8gOpX-|#V_xA^0k^Sqs@pt`v8k`oxALI7Lx^k0JgYOm1vhHjM{WTz&NOS8rH?%1% zMO?pWne$fQh9W}_Ec)H@`DW{8AvWpFSV!CSd&V++7Kd#o<(N98ebuIBp_U+PQuLC1 zy#hF@!k%44BEK;9{$CP%!v0<6Apq+p1z0!Be?a2@)=f_O2Zal4zl4`QnYw`yVHi+) zTQ(*&X*VhrK0%QE3x``fD?)-w?LGc%i4Wy2B>c-}yEv-j=1;$)a_e8Q<-nVQM) z;lRhuKkAfW!i}EHeRpE4P^=yXnva$62jr$gqP*_1hTmaorWGszxv30+lbqsw7TKfL zEB@6aQ~k~x$6vYWQlV!w&vu5G!&m1H&W$kSM~|;VKqYb9ix_7#H!lIa!`Hh3+Q)2< zWj_WESVy8EZijJayi=f$u^Bs?61#7)W9*}BU3@I6 zotOd~(I+j+KzSMiZ$<d_r_bI->U&lON<&J=e2T#4&) zXrL&t&(Ju7mF)xsf%YDdRRv{EzaQ=`6mB;454)bYY*(4`i)P0D{zh^o zZ4SfzXDzQzZ@vgmms#O7C5_UQpFE|0~`SC=&lEfz(ZZQIcWyNTZLt0x~C zkHRbU45zN84E@2%rVn@h+fRDZ23HC8};HAOaS!F8=ba-D#K8@|>GaQ6GR#hPyp zoD`a}0nujmJstD{mj9AVfZ2#=#`xWbAYSSw* zRM8+DSCdMuY$#Kxo;ka5hUQHB0;xjFcl+23vaKNe98e28@HF|j{H9<+&z#RIlw(;s ziCPuHfEV-RDKwH~1{pD@%l{14@dhRbr!< z!?r}vnp~o9+6L9jb(9i@K~6qT>}h{$)uO4JrAGrPEB~01Tx%K`vfobsp^SRmbO>hkO*@U%14N#Kn6L((oo5(}VgHwPuq6z?OF({dl zIKQ>c-~BFYw#R_lUHf44X}#gvT?)-7ZuKn4V^^vQev5U`vi_icHj1?YdgDa<_wmyIUc!&?eQk-NnuPV~)jfj#!PQmN#^md3%C`hqV;FFqp-B zh$n-zjp-Z>Gm|IHe>3@gb;735G{xGn3vfrXHJdl5i(;TK_O~i&JwfSQy!HL}%1G70 zNo%zv=a!-{tnIM6mhiyLoK@``b1qHPvu9#OuKl06nq*Y)I}7jY||R# z62Yvj&a2xnm5=KcbMlUkLD%G=x)-=BKODZ zNVdCs%`O$1`$bIGe>5Fcm`ZC}2FJ4;rzBfWS!Bd9Z$#Sj3KD-xYrLLs%&HM49q3}n zci5{VJ}-6ZtM^cq|17B2VdO5cnLK?D6vE6w3W)WZg`~?TrT+;FHh(M>f?hTje*v@` zVBO$Y9{^(r+Eyh_ubB+xfe)QL2I<6D6lAJaz*~pUoe47%V0fd*5_AiC%S93LV~>u; zUIfLA1Fv+r2`Nn%L0m|(ofvf|7L9nj%HT;$GM}N_+&Q%qc}W9Q>f3gU*-fw{2tksH zgm9M>Owbv5SFa^+hOobha$SQtsFq@=1eI=0hdk?#jC;krKT!<~b==`qv5!!8+ab+T z{cr3sM>kKj8-CY3FN8GlPc6t!lZ_|s%}HLr>fs^#;oS1E*8g~54KH&$u>yZU8GT(a z$sqjB_lRC;J$bDjG_gpI*fYA$?>fSX>s>M6`4lKOp{`ESyW~p#B`7mlR7V#6^n$*(hB0L~;E`9lJ3)b&+QI^I` ztLmXDp^U)+-RllZ=KAuzDgkP_$lYaIl)C5{5|~o3{#Q85DW6$ikk3fiO0Tf>v=7rm zqfW7v+o6Wh3<_JUb(z@)c}qNU6#;wKWaMF1?3znJZyVof0}{qLpY%E4#1@we+s7jk zuG51fs>6lBS@zorr$H{82x3?+Sgb?)Zpo&hvYKcBUL4{vdL+Uh4^zr(JRe~N#YzIv zMSKOvuS7(Hvenz}wn^`V{MviD{nCvE&!SWV|PhD%m~#AytsQ%xEW zPD!8GGOH=8@*QygieSSICGlG5?2zB+D1DvPu(RXFK7wQ(u{N&|^PsKRMb%1q4BM`W z+8}rCk$68SZdPXdJnAxH8W;0v3#Lp5(kkZNeFcahwA`FMH4(GL;`?~d${Y@y=B`+i z^Vo@f!a_{-b-Gjgqbw%xkpmqD#2mszW*iWnt%bgVsk(dVexH&-yZ$Z;C3*{`TFUI` zfVCIhb<*yAP4rd~Qo?|86!_>wWZF*=Iae&=OO8WhJ1*uCeSedPDwgX`EYLAxLU1y{ ztv;V-ZEX)T`wcjXJT$G5q>XKi zv;x^aRLq+C0x{^(g!CSYE0U}!$#i0l;2EJQ0b)!Xfl*F2k5NO42+N40|hUrIM>U)*hvBe9oQTu>HAvK1baPwrx$W@W(9p3{(Q1)AdKLw#bnr^j+lb--P+UVE!3` zr9deQeaNuMr2|xBH4y)AU9W$mbp3z)_76_4RJXPNi_>{XKKqdbEWu>8c0f#INl)1H zSPZmaV57VpP|R-uBZz;z5;uHBPdl#32}2S|dvoSodt4di0FFil22SsvJ|_r|EN1qP zrmzoR5AQto-K^g`V&cmn>|AU<>@&g!@W~_^ghBWB%j3JZDygD|j2|*-@F7S!V#&$( zqt(G8nhj>Nq!Ox@vbXu#TXa+$b;RBhV1ifcbz1r1V~b{@rqqhVAZV2m<&rFZdG>Rv zg2on!S6esz>U7kk&??z-(N#osd0w3dy!A`#NTn}PiZnEr5is!&QjJn!Ey}c;7-r6bH zi3g^tfE_y|3ND^-I#3Vcs_pXeb2V&&HXn9c?(}fCtnCsa5{4U0rmuodNlsaVDJgJ_ z(xieA*MyG_Y*9nPx;I?fcG&$jC(dT1$^V^T@?0yagM<23pU z5r^1WU1vYOSiI51bT_iLEK^bTfzf4{tdP14WUM@s)7V(^DEwT(0M2FbNiFfv=ra5= zu*q@MwZUoV=&2${p*PF%a0~k)JX}MaF4tllN5X@M>(vlGi!81!b?wMFzPq zD=T2Mv3~K3%X!d+ts4b3-cjv+qfn~gK|lfDQ>l`35f62-p!K(AKbN5GIw|f<njICSopk`VX4y7rKf#pR~W0_Sjl7%d@sh0&()NV?&xmbKoO5TFE9O!r^Wm|QU zW@&q0J4o=4Pve0j)VDfFy{ETDXtcwC z@W_;L$X|8}3e42Oc1pw)V*$jJeBwB%$zN?7YbJuA6E@XY{jFph_paKz{I&(Q(?+Z- zC{v3Hz9RK&b=#w&ipIAq1scm0@uI9&42hc)}q}nRhG)A zZK0!=Tbu>p?bJ3AXG>A13oni>)83p8ze6S!-1Dd;@(SEsCzNB*T39|H(C@skD5!segM*BemmX)R2b$C&FV=q#rG*hm8m zv%Fb+EfttM9QC286&nVL+9=|UpjwY)@o%lfc2q82Ihm2SIsS<09 zyI?=TE`}})L#$`k`%6^|MB*&-2RfRyh?hl?1;ttlqQsUYg$g5^%40^V(wKK`FtEv= zqRxtXm58Kj1K&}k`0ZI=Rj5X47(fLXV9Vp|EpMKSJl(`IsP6MEm`!6$FSmF?%x?%o z_+HltFP1U_2|S^SMMUbA4!0~)B-^c+tM~bBsM5E2uk}GIC`uUY*K0@TKD5~crW`@& z@*<&1k-jNPxp*zS$UojCCvA5I_AIo`T+ea?sSxet3Z`zJ+swW?9|yCHXtxHkk$q-y z13?t28&*R*VqF-ZTViy!Gi*@Oub_cc}9a2V1Fa#IIYz&k~VFHhfVPz$7Fo9 ze)P$h1M<(x7^q&is42U4EnYh}wl_6l9Gj`AtwP53>zhn#xC2UqeBWOsTAm~X5F>Qa zxq(5#p_2A0inJ+Zexwh^gaq$?Gecd&{sKEvXk~=&!o=m!bp-I=c9*V~gw3Tcdfk|T z%;qKvCY#DJ-k%P3Btguk;E#VJh&eOraeSgss&}sqV7WrVrIM?nzByV>~@|WodCCIqLOa++eW8E)OT|{!cFeu=;@P z=6`OJ{5!Br`u~;V`~%vk#Ld5;4X&;%M(hAq^CO~cYG1r92W=1$*HV>6Go|mXam(3z zAg5JG#XvTA1wknMUdL*eJau7R7y9-_5XvWO5_cx2Vk<+@2$ARA8RRSZYxeu;fss#1 zdt~CeZf=*~=`q&=$f~Op0xX#rxClCOM850D@0cY<4t9pK;R8dSD(7L;J}# zD-K4Es`J{+KtatAsM$aqER8>br94{Gv%Kawn4I$q%vGs=_c9WJ<{X04k*~)-S)9Dy zQVUm732s6S>IkNM;v36Y@*ZxrU)Z#GUp%`(R;glHx|oY%?`Vs#l3PjWXh|j60ckvC zM`m&?84yHe5y@5!q8}9X!8E;|FG3OoJ-_1^u+tn^QfFAU52K_2_tx@=p6}#XxAnkh z+XY@c!I}bbqO7<)(loO+<~$}G>aHxjHL;ZISBWjk?Gor$Q;a*LOwKLpqZG zhe0$|{i^w#A-h5!h>8Mxn|r$J=+{jf+t0Ip?D79ItPv~N$# z{XZL(S>M^%$y9;9%f$n zJa$9sf+q33LtkARqoWP%G|2%a)S3zR3sIJOP-HE7Ckf6BD0IIk&HMT4_CDn;^li8< zHRwC-gbr+%mNt6#c-~5|Vv&rH{3PjjB-$x#Wh`jB4sE|mVaH$BDe>~HCf5~*2Z^4@ z@NyKRZR^*gUMF=QVsbHWU7@Uze_+fwJnQRQ55VKnTxSN1()-ojY`FelUOqnRr(dE; zc=GH?;8(3poS&9nuW4$ccgn7r-|DN9c@;f{a)e=3zTTPl_{rk`3f%>-eG66(o1TU5 zHBj#Uux3r5jVRFVMAMU2a50HP8v|LvgKa_SMf}}6P}k+ZL3}<4=iU=h>oYvKD+WA5sAJ)|3p_6fUZ_= zCn_ocS!Y1t%Jm43+b=x0P{ zr>P)e!?7dEO64WSk`)iG@W!gBS-{TF5s9XbCt;5}RjvJ!J+QSJTiZRGPb0S)`c~@b zgs2*8*x;DwH5&{1_(*osZ&o8`us%uzHGZS}$u&qPI$y@$_wORYz~{OF|wCdvZ}JEa+~e2AnGi+4e@y zF1W>ng?bB;2U7*|gaU4nJoG9R2j#=ds4n$=6BSl~(|%tJ22aN#a@#SA`GmD_1MAe} zq4Q;%mP&EuGq&LG2wXS56saB)vgFaoNLl*PgAtP%L=C8gj}_^~429~cRDypw*k!b7 z45+@u*D>y3*gwL~8myU@nI^c$SU$U>1 zk`M?e8|8*WdW&*rlZAwOpCb;z9oe*GOf@VOXf<$#X*71`qQWz{1c=&XG$XYOa&}gR zWBp-mk5WY{$}_IfnLm+9t(9iu)UkPgUzlko#5-8oh0^`juE%2Y8RJ(wHnl^I_G9Xk zUox}TR~e+g!n`|eer(@X^BBpQ)9jE!n=MLE;xWPsYn^Ur7!dw)Hps(-aLBY>^FNF$*o1DIqR zU~e4%fvvIX+u7@zySliTI{ob%6lLuJM8dn?9dHA!K?%&weK9xC1=sI)IcIn*kc_on zPUC^RNJjCxExme5{l%YZO=b!8 zW8;G$J*+@^4*q|Xp<%l)K`)DlB6QFCS z7paH&CZcS?g6D{X=A|qA=><%ac0B9&Jx4GITY?Qc-`>VEoR2I5!JTd5-dL`l<00h4 zUsk8x2}>%A5BQ(FVhO;SiD7yP34rq*2oMnee}FX`fKyELZ7l6f_3d13jZB^Xu6BAW z{SCQxcfbhr%BU83`$g=4pd0Lra%~ofrkN3I)4}O?YxRfj7?nA)!6xia;>SN*D1(PP zh%U-eUhQd>0W=pBis>U2$bN6ZDuMsL(=V8kQOC` z`9W$NTx zQQqA_hM*-@q{K)kmhnCZ3H*_uOPE~1wKHbI(YhQa4Hey+{4=XfVS&z5B}?IM3oHGH z$r$`cyi%c6;TwARDrOn<9TqD|_kP#m4OTp%x3fiID7>jKN-7uo@gqsjf!;}$-aAe4 zu&{2}zr-jW0BZ|fK?I`#SeqCG5D@!+U~TOB#`ZQghJPuz{#8@IRO$UILg8K47c>F8 z0QH~G0&kF<8TUh5DZQNXznE#l)^sAJl2&-w79W>9vz1W1Xfh1RTv^!PzfTzOutqxg z$>{WWc6T>l#vm28v?~?)TcNLYkfM2OQC&gPxarNBgSg7CVi+lwBsgMLm=^B_(Hlt0 zSbm1}U<@^5mMPjSK@ztY^eVPv5q8;O{TFoaL5v2X0xcwT?#nmU1IWtQ^wi!U#Fjqd zGg#nJ5Qq*{LYqUJ1<)ur(5gY9o{bRb4B?oF}R0YR2Ms!s&!D z#Zv;s_GM>bHVl|;=d4JeuJpyzI&ODAJA{MwT|F0=BaWH32*)}2+U4)ut`feizn-gj zap<+Dwwk?WpxjtIQMG5qJq&Yre#%H!N66W7Md$2WP}AtNymCeFl`vXYGsuR#kzs{W z3W;0ZN$2=o$DegYktk!{h{@nGQq$}Z%ksT1)d5=$^xLRa$zhH9--r#B=&Tr?s63z^ zAelVF+033!OO-BL#^c=y;^wHu*Nj5Xvj|nIw^+YiZ@Ft5I8nqt@uUgqB1!A@3{#Ti zfFQ4E4394w-;Tn#2Dv>I8H;u0=aN+iWiHis-b`zEVaxj(*nZM$dUh|9{LnX1rS5{F z#h5RwU=mNBE*lSFoz~dcyw~&vO}_n?6Ysl0}OnnKFi1$X?O5xV9~HZt)*DUTyn*K399{o0DcBfqSC z(1;CU(VCoswOExXwlZ_Hin%YRLo!zY^O>v`VmsG*o?0S* zS`m@o@Kh}=U^w5CY)H2Vu}o#HjQDnS$I!SlfdR4w{HLX8`+`Otx4mkuvgl;}0aM;jqT2UvvLD&wr#GfcyBPoUPJRHmhVFn`(ExDG06zaoPQ#&Z zX6fYY@(=&?50F$9*6sQLIgMOb-x(Qck_M$cN(0Xwj;h6EdK@b$259=9XU@td_|aOI z=&XHX^?czO-K>``%JJu;f-HonSrD@s>_hJ?Jl%&6biPH^OM|lR!dG-Q)23q^6*>#k zBRdX_@l|&73)E0H3vK}c0uwnIqgCDf(;mZLb}LA?JE)84Iv1SPUgr;(gd5@&^?uDY za?0k(X1c^;iQQu)Qt|4CJB!Z+gR3c*d4iPL7)USC&TOlQwlSAjLNWKm42$YD5>rQ# zh*s`Nd#0S@d17#=PaA*ql*o}#pqJ9~oxVzAFoF3PD=%*l_DQMsQE23To)l0VAt)gB zX;a=2;|U&7BW5Tm@X=Hy^aU#YT>RNJoBj1K8Ad4JUAt<7P`d!$vp;~J|C4vksc&op zXm;w`8QT8M&bCUu(d&eW0Cr|{QU|V9@~qyJbt?T?vY^*=#!2jMbYkRSxI$L;w9UN| zN@hiii4e0pIT3h?i*!+A9nZeh9$k^@1>63cr@!s^|CiCDY*G^fkwKP9E<}2(z=10*uw8JJ}vk40M)$=~8^>j)7 z*3fp7)bgq#29r>wjc}TlzBXbRl3=zH{T(f386yz&L{-W}C_@N0rH;4bv4J`Im>VYv zF((p`@o*srakT1OMwDH+yna9R^SvMB=Ma=_F1H0!L(xOG2hMqyHhWQx8+N6++Svl_ z-)?VxD^b_j*-Y);R9n11{^b%|6aY%2USZxe0F34UH~Sw1@Qe)l762s&U_<~c2NCj1eVGxuh^IaJ(O+iGcFTdrUrR!wiq_kgrqL$TO^N|qx!7Yzg^qEv=%$!KOF7~~e{R7D%YUl8OIPbsBp$6=F!(LkAFF}m0!qDH{LI#R2mCnEF#J<8DZ^+Hf`lJ>d!v_$tG)rj^u zK=wJoKR?&Zx^kkyBna~a1tQ)i#pIXNO7&zq$i^t%qQtbT#*n8Ro97f^tRt zP8b~?udm8ov)P7@(RGRVUO?n%oJFOUzJ1Sl-%}wKo}9#RU}ydNj8ajAfY0c(Y}-E{ z{^50554pRQixW>)OuY)_@){sP-7hIOj{^tV^a#)fX@gWz_tLtE8_|%0WrAqtWaU)# zQ{V5WDk-*};w=GY-{=L6)4)C&gPbT7I>BE3sXQxqsj6RlC`k)6kV&eaY7k7jgIB<* zNHQqE6+JUE6x$v^bX3y~;zAt9t(Ig8lu->QA?QD@U8a<$mmY>gS%_ddiY;IGU3FH&%w6l(h- zE(FBz@Yiv|TIRg9vNGe!YpIJVMZSq}X9j85i?Y zHDDD66y#t;SS}ZFZihN*VT!2;CLo1a+c_^8$~-pMJ8e4!bjHrZRD_Cg+mTgMc@h1h zY3OidFEGm+%`Fd)6uB85Zzxzft+F8;<#S{;%fi5BjCqP<{bWNjGT%E(Q7D0SM*AsO z$-)3iJ(CeVj^;*PLCm|5P)9H48X|0#WJfy-NUtR4IqlEZ@SZ2~5|Jq#HU?$V+7Qn)}E(Ikrzm_amWTG^v1wdO9U`Q_pfk(eWRClqMZ4cpI2{HBD?aXMUuhRpcB)f3k9pb~QgJx%jo zg{{pze8P2^7Aml-l&kfRX8Yb)gUo-;^yC5uBJA!2Dd$J*H9nbsg?r0=2!ecg^I3Oa zW4v?!GZy*{Aaw`HIe$%nf3^i!`hQRXWMtBJHg)=8>ZI>%Y4W#&c8!y@2LwYQ)1%cR zZIZHJd&a}FPGap&E49!I4OqFS$i?|W@6WB5GczQB)>ziEJ^pa%HuvW58Bz2XDt#J# zXM`%S6i;1&s&g^}k{WBm2*fE4`^Y)hhNDo0YsGaf6@$o+nkiJKU5u$CXaA(90JT$r zT@-VObCdGS8Df+OG(1bPWEVLyD03Ms2a0?-SH-$L_3SC}BGzNe+;wpaHiPLVGTzdk zw;DeX-b%GtO*}W%{ebRA7I=)1HWhgL_?d;KE6cu`SM%^~qkb%fyLh<+tF4bKcH zJDLxV*fVUj?oeAbhS=9$TB#gI(NPQI^iGCo-_$=}0+A(9Ce?P*`bp`TyuVw(Ix>~t zn4FN#Aq?2uq@QZ#cR)5QT_k#tHMnlY1v0zEdXG-{~=(^`hWS}|EkLWBYI7W z+m;JtKpm=HFXqTYNrq*sYiIniA7wAd#W4fju);q-_~$BlH(4}l2o&;|d;8_lx*d-t zpyaOS#we)@#_p|(p%6U~?)OD1qesp1)D0YqR%t(D;4HFyGMvUG!^-U2lo@Wj+$9Cp zmw95We-f=VqE%FCV#SbJ$FBm#WH{n{6E;~|{^64+vS>;V1@D+S?46Rhp<9#mLk0^X zTbAjbY1?$zR%v5lqo`^aWfFcFjX9@NpF_ndLD%sx^Y0;t?QbUR#ueh#CN zt6+sDLST+#kvl;cJ=aat?fg&rf|B~;FL^A>(A2cDh}5zQ)@gNC*fH{ZhpfaZ@RPFJ zK;vXREy?jo-~lZert=02-#xG9t0sh}xgjEqID#rR9CqJCdr1X(3I*-?B+TF5u&L&TEg zX$6+Tr6I=nwrws0jqj_*Wy>=@d~K>l#?n~%?CSxlQ=81BG{{WG^@o*Mah7m<@|F3% zk8o?(v>rvL;bowJoV;6#Ds>B*x=rQnEiDtT=B%#2T7n*n8DzOrEcW+ahyHguLxeTt1 zEz7y~&Kn7j#BtvQhB8YGat_9#S4$q5a;En9>X!vBv;;Uzn>bl#{RZ>Q?OVg<%}o`% zN8KNL)C*rZN;bjzQ0N-8396dU!~Kv6bG|whSyyseCT;rZJL_pG8{YmB`i$a*+Ll07 zYn2|x$2mD^xHmnuw$E^T^_9%+bMSStXSQeGcPdgR{kxS3>Qb^r37XeBgwWi1`;DrR z^2MgQqV))hKxs0@YRz6tR`Q296Rvn0`B5c|N2a_n-hrb8^!3#wc(WTrL<2)8A!D-+ z`aztDBHPr9P4Y%r`-)Ly_Vg7`5e3a~KtL1`6?@BwekW4#DM>?ooeUP*ojByuS$I1u zi;m|vc|``U91m2Vx17R<6BV~VlVxQ^T6r(j0xpIYMT|n_!9rB-p{<6=$pqg z?5eIAVC$R_g1-#ozdyG8{eMxRvijGd=zm$(McjC+ea z~OGW`j!uHpT=-qNf#hp?1#2#^BoPPVBf=qcgL z-D84a{8TaM4Ge+|wy~D^{(-9&`E*_W!B*hG=f`az#J>J}$g5OSlW%J$+@V<3)~yp? zZ`IFHQNA2>43M*9jvV2bj|1UiW^7XV6K=@_O~!82%XUVSszA>L zbYtHVbCy@%($m*h{GJR7wDLKA!W71LNX<#Yp)j}0Y|)jchonv4V^gcUwhko6PulpT zPm!;>psZ2W|J0mH@c2Pw3m0=NTrs!yC}+OE|9if7OTQ?hfMXif;)E;>D8Nu8(M$2j zb!qjFU?_<@)}32ET)_Rks;rk?BY#Txwg6=bh+h&ZyqA_tviWL9$gc1lOHR%NU9Oxr z6}4)R+yQzaGq43r)C|*w(z(3<;TY znRVXSGmv{F2aHfRzV6r0dVCUF zysb-LKIC87>XPv8$SoTrZftjFtfY#b{U6uEId~TYun;qmYThzE$HNL4g0gb+(0oUO zUNAis^;U6mOqj-6z*uIaG87MB8fh4;N6PaM)#7Yn%0gfbu0KL1HNPuBDMKZ13A(!0 zY;5^7Y<7Dd`g-wkIR>f7%R$kkZn~&V80O8PSQH2;jcgT=FU<9C^$u=+3c4N}G(3yi z+rQr!xHw!#d}ib9=G57In*=gB%tuL8!Xg)JtzaUi)Fl@;b^Lb7g(FQ1=RGlh|4stt z1+QDi@&TL9A!0jtRUDQL9rAM~P`2gh1 zus@wolR+*%^5=;QC-H&QhfrM7Ts6cN^4NixPn$(+@7ZVUAqXuO_2d&`Z%cX7tA71#R06p9*Vg6m}jYKlM*?+v(>VEy8>G+B88s|3Q5X=5(>O zKrQ=><>4$1iGeqS-WjHJE+J@hxW=q!g)cBJH++cxE8*K&GUB3t72KwP=PGgBeaft;IO6c-F4%ck~&`RX(o>+?tTt&b?o8b`(NQ8K^Q1uL@xH@ zRhswdYb_r-05h4uWMKE`bxy$UM8(vol-syIFF(V=URb0}7fp{n1X*9>h~mPx z1RfyfhH+gBdSinA(mq9!+0qNx9^ODS`5knFc2kcJUz`&ec=74r1ifkGLn`Zgz<*P% zy~;&tuIUl~Xpx1`L75cJ*y?6D=<=53J~DFeHRK$>7|=vdpCj+exWR7|3!}yi%zz%q zGP3tDXbDcU|DsGhtzJW06bAdPpt6393ST$i-6@1Tqzo|qd@$}8c83 z_|Z0%k<$H_&RVfchU@v0DjbmB0h+@z%tdB2Q|!?Xf6Hj0PuOWp3Lo|u-jz9MvWt2b zD|jW{=kwtX!hE$$+pfzKbbC0J-Um(1xWG-WI(msQM@Q%*tE6y zZ_)M9ve!H0)LC_g{asjZ;3)C^NrMQip6y+S6@6YC<7wd~;2VR=?d+t7lG5n|7ZgaB z>9`C0oV>emO*ioMT@NndwKA9rlEGFGt3HTN;Yj5DE?WUcS{5MX)9PugYWavd@LU`> zMRsmtkM?Zgt1lU?Un2#sr;5r%I>6{nWuwt`7K+?R$lAKXo^-b4@g)_pWRl%TiiOuq z@ueT$;2F>hu+`@c6_O)@rDWXN3n^P^s=iSPcFWv3GRdZ4D-F(QZs8ClD?zsu5K1r! z_$s8Tsrm%5v2^CHeH)+UUO%MG}r37ce%;sYq-c7GaC8Z>9xxCbZOD-9!R5b|8d_WZ> zc{+cK5@4N5ht53GCtPy0Z*&!uIlE1g9vp?lmoDd_XQrH;LADjIr}YvZz!wLJe_4O8 zu4Aaqrafhe%l9}B7k4vUOkpys8>9NlLwn%pmY|nflj5@5J!0@0d-^APx5w4B|Eay7 z?mYtSCO?$G$F93vgSku%J6+eV*Uk}rs=kus&;IO{^6Y5=l#_qH%0u)jr_53~Y0M;C znol=%vVuK4CDvrd{BO0sNLxh%bcOTTIS#J6SgN5&HKtTaE-{U3YCY#^I5N%oUm>UaN5?HMZ8xPQPz*Cu zV50K}1fAGJ(Hy2ZZXEU09@lso-)fKTZR#Ju51TviORgJPaRaYzv&Uobr zl+vzxwtaQeK5uN}radv{b3c?G>WOgsr`0lwMe1eUj3iF(X|wSossKbywgx zigoA1DW~EAL;QfLGB5n@zYR0MRd_Q!HH^p9`N79Ooyj;6HNh{%6Hm;8|RgR zBB@PA+DJgUKpba2Ok*LH8j->F7vh+ClQ6~qU38o(Ex5OuE!032>vxmiOi@O~pH4)% za`IXk*cKePM`*r;=gTK1nwhf*U+sA;@E{&%=h7s`~XaL9|7R$wW|EF->jt3a%w{D*2o zOMaS)G?||(-^9hY#OUi}>*SNjXR4$sm}gS`c{LEh5(kA8 z4%Uo@{npvlYRNxz^s_qU|pn&;7IjXA8`?c7lHx<@Q=Y(cw-FP zZ$%LBD+CIrV1Pyta@KDLq*{nK*pm14FUwF?iw84f{4y5N*<q^OcQUvKhV^f(k3zZZSK&+7clwIm6p007jH39N# zId}k~C$*{2?Y;nV&`LX7t*0ne$Lz*Hwm~Zl@5uQc0~yVhfD*hG&WoJ4>LpQpaS>&p zRjVa|f_|SV10GGxHVG%#S%|hRM$%u8*LBGj7Ydlw@pqYr<~wuFFZrAStL4R~Fx3B!<(2n#4o`%%+6P(xxF;M1@7*QT?eS z@NkvcoL_6kL~C|1QJiNFD_I4`0AmT`PNCPgeF&And2|_V#V%&_O>hX6pe~Rgt?nXu zcfbsR&~_QNKuL1CO^)_;cS&PGU5}HoqXG07=QZ+}x_#g-P!~$4WIcRSmjI$9nI!!0 z)+NwfD+dM#Jo}psmBo6^sVMJgbJL(?ha}d$XVbrAtFJ-1>;*~pXJUUnjI>J$1;+6p zohpnE=>0gbNF>q<>v3t}^E`4^txfIin0Rm)=v+K3bU+_p?lo+lI_f@mZZruv?@Z|p z+BLGO0{QsndWh5E1S2qYxegCIJj;^MarKjLo@pNv7U41^pEOfKd`BU8s?J7XtY?oQ z&@_CV?>zT%f$3n3(}WXcv~w3E-TZMxh=yCQgxu92pLJ>Q1G<1!_q8W@=E0HD%#_I6 z0+p=%dG%xa^NhXaP3sFkK~#`h#kHg!2xP@7cw)!Q?)xO(67}!R|G1>!390 zlrAHA9>{Gfy|^cEWTDaV3N19rtYWwdmeC_ zK95WGIpy(oUqukx+`Pde(BECOLenxCnF_`I6JBq^jo;i65whNKZvqR>(XO7B(d-*+ zUU4lzi}bto@Z8>(V_>zG<9d!H_H@9PNLF|a9Z3p?GJCTX&;}CGOO*BLz;!T&!mOl~ zzz)!eE&K);#67BJDNOeE(8j0QVda3Gx`q&9!;|=+n7~r+etaY#PwC;v)x7$JKiiV> zh-RFRCG7wK{d$Ov@hEpJvLqo-8>^*>n6v+?;EH354WYkTN7E~Ckoej^SJ!_*>sjVM z#O|UCO|bWZ2i>Czsx}+cK326Po2;BHI3Ld_P@@KcFg98H>S9Z$d?xK^g=Xvw# z(rtdFIUv%xt>x$PKfLAE(^RW&|Ke3kCrAu+Yg6Z_R%h8&|21D;*%^4MYw^dxouPAn zyPvMEIP}d8;r{_SK*qne4l$>{M~xmf8-;S;UyZK@efWVc+xz{yRIuBp1!)HeI`b|? zj-018=z0lN36V+3%g-iScX29m`?mi%q#A6m*oe{{iH#}0hvrwO2<%GZV9ujr{XTBl z?Uqucb(9;Q&w*`%I~7qf)^v1XyZjs!TH&F@+4oQ}f?^)2I{9`_K8N2Yv*IY7iGvCZ zoWHU7>gB@Uhz{qhZv;a4RuODoEpj+_ptINnHUs?oXg&pr3Y6^W*;!hG^Bk8|iiEQR z=(cAW%N|Fw;-p#>HC^DjzrFqI(e`gf4B}Qb0dBOF0i>*I-hy?sH7(AD=p(A~+9|BY zYaN=pSgPA+4f#p|Y(Nt!xZ7RjF4^S*U7Sx>d?>2_F5-Cf7A{yxDJax9w2G88PS(5`xP7_PKLVHPIKIcayiWcv5~TuBoRH&pv3p)d3|`D zO9HjYDUq(8YfGk7a03xLC>L_NRvjJ!$D6)Y-#7w-eiwMuer%F*n-$}R0DubX-|SyK zRM@pWo#ElVqB*O`94M;c3a`Wgf;}#sOz=3c5Qgsf9Ubk$|8EAb5!2GB*9iiAi)MX{LVyhUQiuFRMyX)5r zPS$m6zdpcCYjz3V^WYLdsQaA;+K*@Q|N8l}63c?eVRFpzY6YS*bG|Dz|(2_}c zH{7>4T=-)nCBGi!*sj7plst4}^ZBY7F0|;|!_f41ZOi!W<4sDsK_ONRnUtsaJONhI zq?^DGEuWt^`GhbBa+xhu34_~+@E11zSLwMpi1JMgssNuUD{m-+P6&9R)IqS0(ipfK zQQ9p4n~-=*MSGTgqdfHpvl7>@ITn|$VZm!rOZ8*a%FeSM!@xJ^6&#NM!?aPu zhHaP@@3*|<7T_c&J6EreT@jqMembIcH(Y^X8K0dPxNF--4E_5!c( zCR!vU#2BUq8{{KBCjS1L=TAVcS>p8IM5z`L2!EM_8`wRp0BWfB4d2Q^LW%6M&+4Io zjhX|J@s0ajB497vOzUOG4X^24=#r%qGF@8EzBC}R3x9a5VW-o$hQj6B{dqLA-wFa} zuI$I=LYJ8Kq^_t|uW4p9)-(4V44so*>~6^Y`3kGoVur%C0F71)ySgITtyiGY z6_sAYJ7S#a?_FQ(tjfXaw5G_d5gLNi8hzhb`N!Evo=}}kzS1q+mOLM8Q~kZTu_W2p zKlC@u4{E6%yBnG;s1MY@q#5@)W4oJt)Tz{}cue?+sPn@fnC4U_p_f>^1t?6^=~vKM z6X=C#dQl(9y8b2+zFgTnOU!B5fcKD-z=c zLhO+nFag!7h>#0qS4z2V%CrHNySaep4*XHa_GmT>uRg&A@Y7-m3Y$fd!xZ4QCaeVl z_}KL`yK~}SzebM;^y^$M>;$AI?8YTHF+_H5;z`i7PsjY#HNbrBr+N}Zz7yyeb~7{n z^|1a29iTqZQ^fS9nP;ZInU8?%P;Fi&MqO_L*EI`{^PGf503AXW%!(3tusi#PW^n{` z^=%Au(}C{9q;HM{s<9k6<3U{l!ce3AB+pKY?_Z@H} zETvqd2_*r#|L)L$bgIM9BFr@q=OKJ(8aMDd-cc#m0*F1{q1LX($mHOB`N*cD7s!EKD`*m>pn3h_3G*-JG8P_>4Yz?| zOz%q&y>ei+-8B}wPq5cv;c0%prX=KYF*?I&#pEuJ3}C|g!>Yc7Foe?_?i7)9)tv)D zc6TV#7!PJ7N%9ap1m2ClcvxfLkuM&Ot!ZXbS1YVk#-J{IO$ zAwKAaU(aDu3V-X$j%i?KO>}-r#JL^}I_+NSeypiVo!Zi6U7W!=30LB!m`$NqftQ>a zC6!#QDJY2qCcwES6+E>(PHwG6HF^L{f6_(R4t!V4#9X0aJ~A$h(KbQpXIn zC5E{u$vxnrOwpX_UHgThKvA@-zt$!J-ZcOtEFruW4}d8eTE*MRWVvUT6lm#@vKp#D zJ~B%*9}g#01*UC27IDZjYy^N9!HUoWYC80q03fIcI%KUt*f(Fl(0Rm7Enkp>#MJtp z1AsJGih_7_si7XQe_WtnY5sH^b&mO6@f#ea-F6Thig_Wc?A{ptaX!-vhFJ=OS1Uc; ze?Q6Ig9JgIvM?5ODu?86v!g%ZA+oAqlOV^>&whFD7r%s>(h(r;`)%MFpF7+M-;#XB znFaciIV0A?K%ysN2q%|$hDCgr0hl^UL%8)f5|8$%X)7?4AHy`r{+&1CiNQ#f!%8pzC;aI@BF+fCrVzEHj^R!Bwqx4>voOcu$*-E^Mjx$zR`1r?*ytknmKdx?JeV*-Lt^w<0P$f5ERJ$bs~TZWQG zK81g}yZ3gw?AsGLk)uSk!iNU48a_0g_S;w@@p3R6a@-;kt$6PMxt>KsX_*?SQwc8U zjcF8)q$A7%Mw(TgL%3+Gk5S!9fdqx;BmUgl6gh%Xv5$DrSYj*vrc?{&s353qN8vZX z0LA^^EgQY}i|JgM0tzu1(RM}OOrm^&9l-~1V{L>@yR_sSu*hr}&S5;DfP(GX!G_NE zDhDXS7%j6vt#tdgNzxuqfGrZHR6<+$wM;!QBR=m2hV251xJ1G&2d ziL=;5=NtXN$=>AMDx2+olaOZ4 z6A<&cgQe;;C&U;hz_}_!V)Q*rRn(SF1+HiL3GyA#Tj|A{Zy!7cQhCp}o`mb96|Owm zR;ZSLBa^NIh)AM0oG$Q+KkELFtlSXnSZOxmo6WU%th>mkq#v=AMLNaP#S1u&AsO6T zyl1D*0LW;P0>!XyCQv`bw#$(oi{oR^8-1Hk)k3<{?8q?#>nJ*qZsLJ-lYoQ*?w%#C z7G;Q&Q?dp!qx<8s%rBF_r+7&nu7xB z=TiAS_pDNm{GM8pBdu3bpg}F+u=0)pt~%Zmku$D9vk`P8>NDtJ-&FxaQ{Wdx)jrZl zW;$z$nbmyAA)Tzf&E*S!kIwS?%jFRsJ)w~h)x9p~1Bg*gR^6|zDXM*?p^{%vNX~#B z%S$~%ioQm5GQ9poBau2v{K($$794v~u@ayQ%exC2VLXUFgP#LPngDO9Ad!C{-Y^-J z*61_>>G<;%{KVw5^u0#m>%#9B^cyoKaN7xW13-k3g_ojTC%K9U&y&W7lYjnIyX2Y2y8{IqLwwWy8#6m)RN zG=+`8WF2UC=N>e#D#R|`f*^)tKgbU4@`tVWw_WUA{-gIi`5uTj9b@>WqC1YYOr_So z!w_gqX?l$H(w+R|e%;*kkR{Xd>RQ46b5 zfpu?ejz)6#E|OsoweP%uoD(#Yk}DNQ9pn*02f#S01UDa1bI4tBu6vPEd{s{o1CqE} zA;Uq(=7o(0RslMOY{TIZk_Zlx{^M{XL~gi7sE^<>4v*fed~K&;M<3MhW+gP#n+2&M z(Yeg0;_gQfO}RXuu~x+3q3Lfma#+U}=7dT&LWZm+uDv8~Vr*&Zox$SAla}gC(UGL8wwj=ishq3*HMUvNZ1|xledjmp)Q{xxH8oDnSgQ<^wx&nU=Hv;y z2Jz;(bK;`yxRy2sk{SZbophQJ=Y!jyJ=didC`1Yxm6++&ZXZMe4P%TVjH^%>->_JB zpmwlvDpP^haKsR~1yVT~hm-bPTWy)WMx)K>FptHZVsnZa`xpZ;A|vrk z?%`kZPC0&0v4p$SLw84r{Kw|>TYnZt=C#BQ02LKF2gv7x6yD z$awFT3xT)w0{oA1t10wh{xOaz7hVcp1NR_|^=?(;tI}Ie& zXXZ`KOf#Qr5yv>A&IK1%wGq@ejl1!$g&Dk}{NWJz+(2mSc4G-V^hIUy-n{Y|y5*eV z^9NxYphXa4+^%8=(q+$PKsmwn`(Q)~wlw37kjHYXdCS0YUdpGgsUQzIK>hVcF`uZ6 zdvnh`o^@QS;dZx%Ua7LriLmt*lXm+yw}E{BR+HwU$%xwbZ~16^U@8`4{u8L47%hB)Ln6bE0$cZ*vx%}Cdw2Pj8cybNm}pwUV24&pK~Ue zfyn%Ux%73V-V37@ObcD_43~T`bV87!RDC^VdHBWX4KCYSu|d1pWk-~_ljHgIOO#ir zwe0sVm#l*$Z0KlpFSs@potLncHjV;VnNA-gS$IH4Cz_QWnAe{ zXI0D?DkMGMACqyA52!BVMYPoYetcrFQ-&$`_&dJkCNMcoH!chwmRxj~^G?DmL>Ya2 zFOfMx<3^(Ac^Wf~{ag;grn^}&o4$-Ybf8-9Mwnr@6XTcN8snvnmLlIYnz)O}i0}F_ zvx`On!g+v*2_s^Hm~h1$J|O!cB*R~a5H~O@?yhzVP}a`=gibv0-#)%1<2SM4fV{ig zR*yj?lDEGx)|w%rT&w-Ih!ydh3?T>jA6ZQd%+Io*de^Tgyq(r|y#J(?#tZGgyUt)x z?Q1JwCjFI5sJD6zS)>f!cn6gDb1ffN(y!%uT)Bt@h)-G%9&Vb9WmWxd_tTb6U7VcE zRxF(XJ5~HOo!NzS5w!z?1gfsSgvSe9va1)qkkAbhDRm0yxy-=j6vpylJ$EvN~UF&wUGOVhO1E z2v`Cw|9iU+@0HY|?mjo$5={2-XYz|=OU1xO+|HPnG7=RJfZJC2fD|S7^;-lSs|AS^mL}2HR{Tveqvh}gin1Z8d5|7?V&hqJU=b7f{>elYJAg}8` z0aDP*IrR3ocFvi05#5)GBi97OmBcPB78ni}6pB{5-*yJ{C zH0seFL|*$QH7N4FrN{?#XG4L2A=@Pg_UnTortZcFBF3#zTU4GpMsC0udG{sUOYHdi zYTo1yRIPFKhq}hQKklJYf=hXVVA+u3#{CpuTcq^^CE4)J2APvGJtA~a-A=@u>}2Be zYc4XtL@{8~znpB0G%%i;V43W$xy9PKiJZAY%p}c}9s64}M5=smZYI2sSPcWr6{MzD zO02wk8kTqL4#=!#S**@U@Gxxi>tNE6dt*%QIb>6A#1+N7lHHKuaUgo5&1=}6m9bMm zGe(+?1Fzey7lJC;YoF_88$?*mff#nME$QE2*R7{JrxIgd*&+C*UFqeD`Vf`T~II z7dC2-{1r~HG8bTT3DE03JqUBFQQydn((hca3})Bj$_vQgZW@cA3mv1wKGKNn8JYp3 z@ys~H)yycsjceFaFyn2N8Sc}>fc2tebfJuo#CID=ZCcngAM6pdb*S=HV#@LNx{s#~W{01a!w2cE3HmqyiBrI3Lep z^4-qqi0bld(GZRW^-%~w4)OmOMcy&^`V%TP(xo9sVlv+jBVX(5MQSXoOP_lAYss>B8(bF0DMge*T z{ARR$Zv_4U!q&Hh)zh;Cq+i1iy&{l}w{M3DzG_3rGsss>2j`j9d)~!EvW$}#0 zkAHcHJ!t{;zH>y4%S2+qSMVB$M5zb_Q%}`|hifNI5o#T2b;1?mpW{vYIHo)i6&?Sv z_jhKO-i#;1;V`NE@FyC?1E!K1LWb*Z3B(an_-)jSWa@%P4xzHNr3#Q?^XXUayhVy{ zdf8wW*&HhJp&9mucff50uc=KW0OPLjAaWMChQPPI!?XYW!NoxZkM~^t1D$oeT9c;l zI6MMG7Qa*HMMUqf-{~ZGAmA_`h*4fU&1SIwxt2Jt58?~&3Z?kqvb_H}#F{VR%DIc) zJcT=mz|v2F<@W>t5_O{d$RU#b+jj0mEUj`RWP{Aoc2@^Sehv>hhIe6v9QnOEfU9G6k|*)q0ZI>EADtJj zEQe%Yvf677T+=Xf*LK8Tc3G9@n0|NSn@)8u&(+6E)qKwTpIAwY%WRm9*?| zRSFwq=-5pOqC~cGGI4{%vi;kYUaG=lHC0UePdt&d-%WNaZsWjNtwEc2bWg5D(tf3!m_(JVd7LFCv58*EWRt>IgUF)huTO12G} z{lj%Vn9e;Y;!Vs>kfZF`=hh5?S^V?`?D*Al35-)0!IRkjhE}?83qTMAg_vzkPZq3W zN!GH=7X={OD}q^-s{?je(w^OHt^`HUshsSwMrAe`KkNw#I@KeEQf>z69(iGi#1Nw` zNnL?JTNJ6jVvhn(n=iFc;#e*a4MBnzJe8M#zb1oCqV@GGmHiMtdL5%VP?*y28hzl@ zw<0z<{iijb*INKr_-uIF1yvuF)_yaqC*e@y9#*-NZYZTFN&#Gp4zS@R23R)!g)vaP znXI7DdxK1pjiYH!uwS;xhoHEjBj7f;3iRD3q%97 zw9Tc}4Vultjl+c#SnOES6lL&VAB1n_B=1A#GOsH`hERR)p*Z?(MlIn~3@}tas$o0l z{2{5|B4EUm&it(@8EM}~TyudD@rE~(hjtAhk6y~fF>0(d607QML?gsDAVogIO2b9VuA+M3Z&>;V0 zc1|Llzb?0E=4s}(0nGt8w{N!>>gt>K3>r;!oyr-3S(>A&xZGEn*Rrwji2v!2ESFecUGNJ71r!P_)_IPyTMKxnUru z^7!0vB5BF8;%*>s4a}~*Kz)52BEp;9DnG)Qhot1L+`E*W4H4(Z&ES-BmgM$EcLrAd z&d3Dgr@p{eh?{Bc?N8VVYGkHtlHyNFxa z>8#L7-RiQppPP9@DB{BYsLU_`6&5sSMIqqf3~U_dRIm*8DU%P=#vu=L<47-b@S+nD zO%5uB;Ks`tkCWfX*LHenNWy4(7|k8T&&eqTg*&BC*ajR_U;Mc&Ku1hgLKdJ*zvA@G zxyJZHlMid0+_8b*Tdj@LtvQ-DBYClRW*8x@sTB_|{>WHw-}XQEv2|&j|I?kfZriGWFi=WQ{;*E@Y;^g*ILL|D)&J-*AzMd~Rqz>Zb7zZulOOxUxHxA?H zR8`NPl1_<3%F4@9=;kJ#55<{Vf9#{kNwx*3tKx%SK6n5vOU(R4A3g{UV;})|T=6w9 z$pwTcM(-lum-1$8hAVIwjX1KMb@+r`P9=mVbQj1-ZteL?5sp-|>44{`dW@b?P@w5c zr$yn(B^rQTz~Zp=|E?*3ul_ly_6Kp9#UjnLK&qvNeTpEc2#8xU3Nkzj;P{(=t)XKs zu%42k2U{l!KUa))r#74Xh1`-tztemQV<6pGnQhe`=PBmTUcC~2FD=0oCA-p5uu`I% zU$fx0S8ELsccb%HyOq`?4*E|x*k0iK`JY^B@nVa{yl%u;$Q@wT3|7dgDS-=Tj^u2+ z9ZQ;BcLrRk7U`nJoa zkmEAViehhn>74+tPx)zsjr2`=*V@XOo{8^Uo4TptrsUNzjT3ul(TiV!QKEAD0 zp{bzp{0zk59MIk-;@m{J7GA^m2dL&kx-&Eekz-c>DdV?ZAJdfs`bm5Ekvs&!!O@Tu z;L!vMeTH_N$0!nmd;(4XP5yqDOzLum&4oM@CtDudXITCW&Q2VBQeFRKGBFSO!-~u>MNEt$eZVZ}Rs$b@!ZchvZQ8H~RNG;s9K!%;@bukmcQPE{{Sw z*mM6Tf4@tJVPc06Pfj3I@vbg3;XKbS@Iar86op8QmUs078{k+ z3(Xp|R*(?Zy-G~a^!o+yTWQ)lZ1i(C=|KhTAN~w0dgGm5ow~ZB1|f(3HnPB;zU9}H z_S$Mnmep*)^j!m{?^jlBvYot3WlRe07w0;k}Nz{B;s{y;)y6S?wT3@CUyV27F%^q!;G`2rK-sI;} zUP2X0fx=b4F;HpGXjHab1vV_T8x~rPSW+~MlY4|5dUraxPruLdDH>ps2lQ1UQ|o9H zm~2e4fnHsy?XJyq00&Mvj4w%*xoW=nlbeYpv>5%ppu%l{cn|(RhL#%{_aWm!TgERS z<340;qrj}R7VWssi^|=`8PG_~LEi->>1^N^An)mK)>gv(?fs?IqR(-V3H4Ra!$AUY zx4y)mvBD!uDAT;k$>k9X(hqHzyqdqplB7mbGv?UzGX+%Q@ovoE2+F-RuCAEe-R^w@ zrBwts3EjL2*7z;Mi#*O<8N2@je|+qd1K|ck=1i&UK{`*}Ic3)cK`>{O7%~f_;%gMT z>crA%nnBhbWQPbnN6e25BvH&etb08aIxsiD?~33}m~`&W5@teHK3TAI(e z==AWjjC_9q2*{|=FmbH|?guY=77D2PAdI{DXcr1AEFl`3DvUelUp{Jt_bBE*n88(# zw(Fd}vMO9VHmGZdqj1H&?*{#^1yyy5%_AQC4^_QJ_D|0nuZy~5^D;&waO)cup}7Pz z+N$@oaKk?tfB~j@^QNcSD(7U+CBl2`PKV~&M`4>9q}>c}{1a;hn#uV-r944Nta1~M zj+-bxT)+!_9odQy(~a|cc=# z8qWfkP>j$?9x+(_QZ7gj^a>M6hC9i#qDToKF>I*PW8l?euhLuyt1+O zJ~m6ffhPQd+GeNI@M<6w@M8gUj5YCqu?ZrU|HAyyC5`jxo~Zqi>&VLEBp|0K2oT2V3057G`ZfcyMo&P0rFSHUVxO zaeG6I?h_F8(7mS0Phf@==`kB4r50lp)HMvb`$*ViOnW;fjkS0o!~a>tgCZd;`lw&I zM4cfbHr7A5gH`*=+GwQfdnVjtp$~%TO==kvDR6=tW^u>%Vtx;UcVJIe+1ojZnK#sO z?MRMIj6XA)8OIG+J`Kr@%Gytqu^!E$+@q&oZ-QrBbcSZXvaWJNvr}f?0N<|cwTR~` z@hGL^czuk0RzoGCKH@S4&^3jLsp;LQiXAJQNeD{MnGe}*3)-D>OrgopK>Vs~{C#0GAu;p##zt?3sNIWL4+0nKZ?Bw9+$; zp5y>-_)Nq~AKo8y*P+b__Yh>n_ySAS(8Z?7-@bX_U$5s=su&{xTYgj_r_lKp$;({}p}>(eb3|PnJ7f+&;ECrg#bEmt;5Am04Us0;EeCci_A5iJKyU*+q3}tN z2@q8168H`T2Z09Z2w-`?oVl4)3o{v*6A)Ynv|yf#vy<~zL=RA2XAr)F4+1WhE?^ia zkbp3>4WOCeh;o5cTc_`kU`lLRHj)b7nw8eG6-#3EYB!cBZ;f?|dBjNdQRKbhP-`=UJi`(S6G6@UFe?VReG99l27FaC?Je zaP$i73MUz4EfQ~QwGM_bBYr~)&uf10-6s)|M;eb)WX@@c7l6gf4Q#1B^H1WDHe$l( zXDPlCZ$3ckc|8P6RE6ei9!0+qgwqb*>Zav77{qHVQg>`5Yf%DczXd*W_FupX*l(IR z!B{JJ^!yaGpmtQ%%6whn!Ow)M=<0l|@DR<;bxMyLEYofS$6`*g$Xd}^h`(NLaezZ zMHC@%kAoo4o#?#_isRcL5Pc@ht!-;aqxnXTiBX_-y~EgOBn}hLVI1~4jSF^RWcb!$ z8?}VZif&3>gtofs?ceQ2aIf)c^@nrqD4M!^DCb^of%PQ*3^sjT6azUV%q2qf@a*sEbZ9f2{*jP*#s*52Sh{x5gPwgK!k4x zLxVYA!^elh!O3`_fSWvR_jGBukYT_t^dt`>MJb%CRRlph)S)Q{x_XVXn-I;Tihx#_ zDhH5&oJDU%P@zD9!0n7>ThHO81!`~X@ALm+?^v7TwvC^yUqP`Clh)~EIc=vsMbcl}#qN;CAg(gN zeAO6)?C*x32ym1ZR7J@zZ7k4mc(8Wq9M!FTfk?GVbQBA-YQ5ALzXQwWv1@scttaz7!;09>l<; zL6jm~d*Zl>y$0kTcx^K9(qzr&uZj&;h`t$7GFwPor;FZfJ_Hq=_uj~u1En~*y2A;H zI!|+2OoGwA6=siayQ=E|>F8?f z1r}0YTuD5nMnQY$4WscKliO|nxMz!{?%8?i zZEnF<@uJM<&fh`G2>)KM!d1YzPuH@r|JyBF#uc$S&9(4eI6}CP{ie8Lu{e;sHy(5a z@6r3*?(KC&NNg2F$XWGaBBZ+?kT89yYwOOV zeR0+BU>g7WS=3bA5gc)eouxx$WbSnIWH7Db`00eyH}oMMK6$+S@McVlW*xAKP43n2 z64VYPSltV7PP-JQ+Wus$-<3_E)_|giz&z(jGE6sDM$!Pk-#R|PEq`Ldog#wA7V`u+ zA%Oh*7gnI1-V^;u-Xe9w8%FE$^6nXnOHvb=IHryq$1O=%s)Wzc42VwGXs3H)3%)|bPjFCCE+O?Fo}C$e9NRE zE@{W!f5++E{~PO#l9=xaqm+9NCE&dW(X}ZXC#}Etz{%Cffb0=OdSoXuk(k{&(f%?%dU@$ItN{&(#l10-x8evp?O)(%1DB{pH7Ep+{@ijL{|z zgOba4>7QEE$=z&wvx^_sSL~?B6Q%o(FdL>Kl#N?nQQUL53G`s_o6ip%XzjQJglX7hr}2V+Kd1OMJBQlbzkiJC{vWZZk&PgwYON zGs%-WH*y52S|vGt_Y~I2K%FgG?%*k;qe~SlcXKT1UYU9sQ!IQu_Fj=`$mE^pxEx4O zAt_N&T(L$1b7@#5@p<*5CqI4cxf+WrYoi#1&L};*W?h8s?q}!GCI+87tp4^l!0Y+p zVbUIGKV6)|c@u`~o89qaER;M4uO3VC8v*0=vk}Hs25+KY)yZe*OOVuhRPGA^K~I|? zReT8j=H;tV^2yJ>l0;?hA{i8A@-mkc<#Z2l^mxR z*Nd;|ie)DQ&re7E&-68TZreJ_@AxCf&!Z`3O{cG?N5{vHj*jo957Xo6Yxw68e%(<9 zd|>Hg^f(16$vi~LazD5VSI`OPtvnwN|2I!jca3zbckh1EsOH z4#F5>wMmfYMxN?4s8X()Q@Amu6t8n+bvUMl0Qd(tiDF6hb#-ZypV##{GULUvzJ#Jv z5D?%>8!>l>Ua1oj&ThOP@0liyS=?QP?Pw`SyivjmW%fQdqj@YT$-d_C6KZHfUD7;n z^+Bh>m*bK}S8L7d1agOUES~c-Z>ON9ar){bQSF2i;-XF3bfR2%P_!=us(m7}(j(<1 z_J1{E&N{>|z-n3Gq568EOxRKlg3dz{1)t9(iB9!R{TaaBZ_z<-S?mW~Uz}Xk4GGSo zA#dmLvOI@pndosDkYY!I>~`4HSyGhMQz`DyD9wAR)P7DTP^RTFv@XF}wcPJu-$kN@ z}Qh`wmxkXI-A6MlFWy4p&JBa!kz0uv(0iC}tFUm>0VY?7G6Y2Fv! z+6=G`y48ZI%wy9Mmyh>)cOm}}27B$gh2^7%ppCfY z8?C-Ijzyn3*(?OS;y~WEag+ZuO3{LN$@Lpd(5qIF=ov{*2*RT66~iu{7wCtM(C%p0 zi5r9E=@oCYTFMU-uM&C6adc!i0SXxJfAw3<08D>-v~#X5!#r7^hDAFeN^5UabYoKV zplTREi@Lo}y|>FO6B-r1UFh4HDP&7K)AAmr=<2e6UaAAj=9Al3#W_VM09|%x5%?Bm zHsT}}=;+_KElZjR6k~Dh`hxl~LMdJOl6~-FAzh*Ptc?5SuWJ$njCDt7_C-1|JO>jc zKhp*qc1y}KDtyVonSUcUs7OSONl{NQ3Ljn&!KF`J=Dk?g!jW+|?A*)ztVDC0vjIM% z{wCE5u05ix|3HaiVjw2Rr^K3bV!tyd%!VVB;dG>I0kvArkOmdGyH`tjwh@MUFd~QL zY-(xy#$SR3@foBVn{=FmZ*l|Lo=-^rYf&0}*@ESJ$7~b%0;|NA;S)SJC3-nIw^m2mtmsoXAT`3ab zO}XNj10igZV`^~5L_tmqXr!Ycd>%p&rU%r?mJKw|mi|NtL(e>lU zr;oRfu0MnSw(0I8-^zDz1AG4KXNQMS06{>$zw~H)e_3n~i%#*vaes;zD}$A&#L+R; zefH|r7gYDC8LkBRkewYJ9_-UM0m-xRql5hDqdQ1ah|p^Q_&Nsc=uxMWzj*m;q{k#f zmp*rk)x{lJ`re&Y%Vw2tpTed*&XA5~TsJ$|pS}ikzMnIc!%u(z;&%vWhzbmY`hJk>jn|RhcpYW%`3PzC zgs|gR2qXar1K@AG9R{mGW`~qQd!&OPWCjfvp1l^VeIRL-ikycM#+Pa6CN^@IhM!~$M~ zZw+t-A|sTt8mQphIr?(P^qRR8)gs_UI#!85Ig&g5Zr2xXpV07MW1HS9esIw~YBT~O zT6lPAr8~A^@)QkHLN#kviU&YnOCMHbo|oJ6asM*Pf-F7o)FDZSGWwDq;N1J7AL+rG zRyDs;Bl%?FrfOMtD=<>~2pG|Q-6jDr6-@Z_k{J8xcg0}F3d7vB4vTC&Sd%>>j3Fq8 ze6eSHvTw~b98(ahg*?Fd_Ybv#ox~hKyZi0Gy30K*jm&9$=xN#eGPJXOVzdG0=HHD| z8J_WLFT0u+#o|9K`1$!heQs?@6Q3MPu7u&hF=8X$ZN1fC1d$h3|ofz;Csl zE{awlOO3**_D?(HkjmQD?(emv`uqP5t^6hZJqX5|FRFuDxzK1A=!KMaJ~2WS%_p}n zXRNbo4xdhD6jGIt1WtmE;(r$0LYFkTc#Oa`R`>9=n%yhghq3b zvIj}7Fo*ScMkeFQR+)l~sRt2j>Kzm-x%a>+rBju*7*Uo&E|hWRyfLlOhynBqbt1o^ z1h$^4B-pDsiPaqpX57l=bXUb4@iPc_R|PyhS{*Hpp=X?~aUKbKj!kaMR9r_8>MJ_o zu0zdJ2q4s$`0N)rc;Pb2W#Ovi^48E`?hP`kpcMrcuFP-ktQcaW)YIy`JHTPkeOiUf zGY|>h4is3qACobcla`jQ>2Ll#do$Pw?-L7Tde{cYCq*lZWkEgj)?6 zK5if6bf8?&S#axaJ3qjmJFMhoN{d=o5W^;ENlu?E$P&TN223<}YZvnw2JCPzWQVf~ zITd`o*g|&HR2QTZ7XDPjVX+JU>&p`gHpB<*#a1>i;ICK%!iFYBF}LLMc~PFz330>k zO_Cu#NbxQHl-7514D%l=EF%k~;=in6&fy=!PeV6}4qhlUfa4TgbgdwPh(VSn*^K|16=9 zLh8w};x!R(Z&(@3bdFeQke!exGz4q4WcXWwV?zcCGF>`!3LzQYBDA;$g%m$OtcJGM z%U#f3e4XaDt`}^NW``~xj)@|^KgDu^G5Tir>bquDLj~>q56sD~1IvqQHiLz@#ThES z2XrEcf*^^14G2;$1i)J5CP>PGf)?rnf=&qs0bqf?%Ie^H5P%ly1H#Y720?IBUH`n_g2%FSN0?#U3k`I);S(^L#+p4VckKLqTA5?pY4&_=08irp z;9RpF1h+QzqB4^G^@BjTTQl*2iIWD@wJWeujZ4;}sF6$SR?rjzQm!kOs8Tn|Oa3i$ z#{-Ajj|Og6c@E(GAQQ>Os-2GXOyHF~GXk9oer8kNMN~SqOWv=+f|XNs8Uw2|)Z4-reO7Jf#hn3T=B6C=-%52@Od?*EWPy zYC!xUNW7|E->qNs;+}3TfNTGmU2-sX@q*P0(K6e%CFxQ0oJ(%T0=5^lq_o<8OHuPG z7_{plWR2RzLwnL0N$r6fImN?^4wcEJ96Xmrbp;AZ6Tcv@crAYB-A zehWiOJFdJ-Iq+|MAQ|}m<49$cc?>y#xV1$Xg?3Lm$ld;0Z+od-ot-H`t*LDqy}e*? zU-I<_5??`@Fhab(xRHVHv_Idbd6@z zh?M+rQwiou4^1(s9D8Y%gx&@k1BZe0V6m%gP{bIs~ zDN0mSFoPJC7W6*3C%aYkPt321=IQ+af(SG9Iy&sX>}8A}J+*G{mXIPTXYc}VYn|OV zLaM6oJe8())x*m6iA~T4PC99jbYN&u8Z{9VeB_sGM~h0cv=Y?$ds|1igR07)4?y5I zP;PU;&)U1qR!K7n`{&i!?Cs3!!Ol>bus7fLE2+IR|ImX5Hz+^z0ear`Q68s^*TCbE z2Nd0DI)IUy+d8g97gw$Jo+9>>K*YwA+&@Fg?nI#02iVfA=_4V#$DrOZfewvblYI)m z{6%>Vc`<9)aZ_I}Pmw2gvV%>q$eW^}W6s|heCPR&lp&Nu6aBCm0QK5+H*sJfw)#BD5*SVDX~~6TI&p2$J0f;u`j*IP4?bNRR~mr!R-7nTNEs?? z&M(Njn!2UuYP=b4c-P!S{lS-mHtKQj1`jqQmCLoE4?i!L=xoGP{>1YX&Kq7>EO6Cjxw@!l%^2%G z!#E~T8{<4T>;S{!370dee*q@P4Tgs%397-0nMR+1B(6gOt%N}R1P1zRxKLZ(D%$ym z_>mbH0Sn(CA9_DOCc9VcT0`SAeQd7>)qPO?O$9<=flKH71X`DF0`**fBBbcuFlRJ? z(7G(7_Z^`R4#*4Nr!t7a$Eg7=e8yV2Ol1uk5zkw9~x!2rXso0#&2B!4b0J{S`P;~T~oqvXVUHC*&T zp@YoHa2o;yqj|MpgXf&y^^tbEzu5x}M>i4e+lI@L{gtv4xD-!*By|xVL9Av24%lnClc915njxalc8Jb-GU)o_ zPR6H;nI)fe%AZ(B`r&?EZkU+@pvZc zvyEU~=NjI+uIBQVC6A?kUak~1_MSvvj0<_KdH&+rt7rUMi4`8{KSHhzlYivIK?HX@ zR^ks5PSlTTUc#T-6`Ie`{K6Nxr{&cO4KRpp6$y9xg%1*b>No1s(UDO+ueLU(ZA2>- z@tQIa?znUtMy`Rtlyn?H&u9y*{8x0g2mQc|j+JYMM7>f$h$Nk2i42?j&gzgdUy?b> zc}@IN!$OVX2}w_21x8n5ih|mzV1O%>5@&>u#f(k%y9<@zl%=!ko0OCQ)eQNnA%}1z z(c@v_1r*K4NWx5stB5z*l#|5>v{}5|cGdv4E+cj}b-#DR0{pN9;0NQh;;?`jQDB5sUA3fo zs3y;ZHVhj5aaISudSODGQQY&+nDSVWq}|McLlWZQ20+~KGEhUOm&!d&k^z^TmcmiR zf(*vQ)wOmkux&=Vsvfp|kq>T`lKuYz^K0OjnQv@t4(NQP6wb^DCSfU2RN89d!&j5< z7D~tbo7NuZ){ZDStk)C$wc-s$)x&RE_(*uQdqiN85lpjaStVGDY*oWS(Y=VN;ynlwa ztYuFF);4?B06fIK6oBWdZkh`94cdzyv&TpNh3)F{N?aMl&xrN}VEBbW|BVf_u=aBT zB?Ht6jX@>bSU$p*ELQ1MQ@#}IT)NT4m!wvrA+`zjGc2_K@OuxRe!NrQPG)Ri8wgBG zT@3sTceclt1ng2!BYf=2HNVHh72FJru@GSU?yqP^$&=h@Nc~@TP4KrUl5*4q@H2fh z@2?x`5T*5~${(XOr*vd+t`fSp*?;)z)5BLdKvyt8EJ})|A}mSmRWD&b zs7`@TF>LIzI7LM=%WM*|7iEnl?DLnn+Crj^deBuE#b|n#ju9x8ME(dtm3ktu1+q%|jq*C_sg+*p*B|7b7fcVeGKLJh<9W{tdURX7M$A8{l$HL6J2IcE5`+;xNl@p>LuYpY7 zpPQv+FyVrjF5dEhKFhcx&Q35Q{WEl!IY~lGH`L9K#!qsl@4V18o9c^624JAq5$}TN zZipx_tvMMpPe-T`PU#k$)%Ckhl;8Kwc;AEZ;02ziVwnPlScvNr73?9K`7-tE8$`!c#WBqZyhs^FTB#{l z$1%@o20nVuu)%fWwhY+IIL$$36|{1%bq9=H&>O1Mi+o62&GVn=>#<00bbTKBKmYtQ z_^0bL%80fOGlkq_CxgzKbshCn@8K4*mv+~*xPJevhrVjje=o)CLWDX_!ZTllk;7)* zem4w_ETJaAj#$utBW0Td-afz_w}&O!J$F*OKS7x!ne>7vXhcqM4FOn+7PM(U5YmK* zpPOeYVv_LuLi=?07OHCW_IpP9G?eBW3qzsX_HDUhiGqM+%{2^0(NG{E;1&&}!W&Go z4Z%}>`q4*uLK0Tc#fIR4?v!nyO)gzq6-S7b<~+j+OfF`7jdxVB|9KoUV}V&QqpW@#VBcn zc)GAih)(ZoE;xZ}{S3My3e_AlZps98RTK@GZSk8#G{m68aRN9H>b@}!mk%N&=+S~Z zzU9XfwEzNP?5Ys9dZ?p0spW&%2bzH@M~f^#T9!$hfJBUYa;W=_;LY=~jWw1>$Fn-h zzBAMAibX`QvaLDGr+)-frcWgnmw4Qjx_g>h#vR9b`O|cg;sWI)aobi-94Z?mbFkbN zp;N5h(^xVs5HRI5UPznaEPeV3{ZbKnLqa%ldrrqhq$G74SPNH3|DE6C$M?~b+LDcg z8?>Cq9JHO1q&rNblJo^f&>U+3CBd&$Ie`m=su8OzjQDUppW(cyF7cM9oZ(|(dbbbf zohy)e%NgCX30~0fB`CEjhrxD62%Ri$dTgPvH|*$;7ZMHxF@vuPj9S`7qTmb3TD`H- zy$Z}jq5+U;QQx>rN~^aWf!YA-o>j;_Uzg<-@nc^=Vk?~F-f>3Dp2Hl=47Rl=CV5iH z_M{ddo9JjcdGkmDB%!5&>o>e@+iL5|_FZ6=scd2J2N5x$#mKWCiZ13V7oVlBg&Wo! zzBe#*)E~(qnXSpA&v3ka(&+kOOwgh@N;a{-fvJ!;~eZNuBK~Zj8&@9nX zh7H^EdIR-V)@_0&Bp;s|B&NQwF9xtGBa55H#E&^!dFxrEz6d@8-h{3RVAJKq4>HojU>aF{P+3 z09C?Ce=E*@m8D!GKxr+xbV{22#dJv*6!f_;&lAj@st8%ApZd5E&wuVURU1K)|M)uL z0Jb*Jl3-Det;n7qq**!Lj|~_fY=O}~-b#4Sv=zeFL)Q0Py9>*HFJ~JB zpRHw&$f#}OF&0qs5x@SkjJ7Q%$amHp^ov?!uZ%Me3|3Q%iG&~mkDum?%Ufk7O-`_Dj(Q`*9u9dkIOY<4 z+h1Csm8;B)#j9$e599zGI_lH`{(Jv;wS5TJY$#$>j8ZwU=H$NG;x3UAU+7DOAX;Lv z@T|nD1(t_WI`$Nq4hx#y26br?6Fha!i%(wH8YYx)4dS;i`{N=LAQ@2wO|`27KQfQ$napxbjyvLyq5Q8YXH(%nn9tYQ|GXFI!<2GcR) zCN1a>>A}YPEyh9wyV`YSWGqq4aYxc(CCE6;A$Y5lRYtEy2ACOg%)0$Y@!Tg+6?F&KIpKy}|qCLueD%WhX=5GA7F#n zedy4*m`WWF;SYsx$j94|{c1gSmBLwf(l{1nEcCVDbxV5>@CMVM!2-Yb+|o;qmK1ys zlj;ggjR-{lhQ-pqWSwri>`gWz+e%>JuZyqgk@(F!{Fe7$trAF|6TA9Q9-&dc7N|ww zir0OF>yGP#R$5w8A_=>Uf}H?utL2)0C|c*lI=DA0G(jwWwpFE&wqUv}JMH3X+Sv-1 z7VOn@idm-`j+n2>4i0qW_tjOiN9nO_1JOc>a@qRQ9oYRLc_ahtyi)~LiCC(Qzp5*6 zem+WNLzh7B(oIwUg?bA-tnf@~&@8|^-Rn<_d6d#67e0c31iA&v(=P6g+D?NfW=<<6 z(!=5rE;o=U3}(!zQoQL9y0^;VS*H^0Vc_lSfHuHUpVI_SM%mlNg$=q;A0rLB+Ps#8ByRWI;qw`tf zBXdvxkd|9p2rG;o7siQl4}#hsS$^F>nO)YPz8~%>sxCn zLjr4L6xC%b(h?%o0valrAMo}{SR8x@?5A*t27m8RD$CQIbG&AomvkEs&t+itUln-A zgCdUx?>GjiNjMudDlwmX=ia!T!9Kg}5I`#*+ygRMu zcO|^6p50w6@2bo5JN6t1D1Lo+S+0t^s{(eP{QEl<0$Pz_J)zJxwnG^w_3W0C>5EGv zZj^TS!|xp&-E8eq(M3&mEtJ8Jr|v$cgB<*2Og?5$rgtAVtJ`_Wu*91x){;*SR5g9Q ze|)zO-(yK0=TIR*J2^?%Pvs-Ui$#T#A#y*?VG$!WC6mw?2pu=z;Q`-UL8twV+NCG2 z$yg>hAyIW))xcB~7C9_KzfxJVZkELr_=HaO2{!i`ql@j1zz~(UfrNI5t2w+C)31k5 zQ_SDt0#7OM7~XoE!=l{QhRdA!tSMJgR)1<~I4>7gc!gdUq$Gc9u_cyyVr6)6r6_-Q zs}R_ax>exMQmVm6PhDWeXnR&3N}Mn2>nj1JKf8dCx7*%b7Fry>w8Wpqb1sx3Ls2XM zS!{19<1&U3LGU<0n#6;&*A`K>Z-1ZF^~(9J7`jOX!EjP&G#r>0Zr)6;u0Ivq;-*|y z^e`j&80Y9yx}%nP^b}c4-)_JIK$fLcNCmt8dbt`S-ybRv=4)+Csgmq7@z78j?Vg2x z^o2&+Z{xRttIm-uQ11s<;f`^;C#>*sxP?@??{9GK*(DQ}78NaKkZlCFOhOIi)2YL9 z^IX?y6O^3$XR6EwM!YJKEw3ipULQl7TpMS(JgO3*PeRekXJ{FvLV7M{>S)w~;&@BI zJT4P)Z#)GS4`t`9hy&g~3|8b_2EwKOSlVPT9@%>+t+bE^k@>l9A&wGKv>F;c5VnyEL4^sK)8O|hu1?D)zT z;5}AAHtqYS7v{OIVx@XGcBJR}H{s{6OLmjttOrqyPpC$Kur_LYReV{zziVjf5cJK* z-GKIX!zO&kdj+=?&P%(HVa79*IPg17M?dTa{1%$6YF3BIIuqBLNQIOsn2rn;nQ1~{ zGVJ}2C$M|u{QzS7Bx)A}qCr5S_z*+~tZzsfxhS`5T(VLFpBn{U{+y9@0kjR4oOu05 zuj{wBXEo`bRLq zH~Bh+1*XMsk4HP45!;r%9Unvc&iF zV32z%LF`twR@29~`YMM_QH!NL5oV7f4Xi3=_ffP#gn*3HNm>w3N~Y}0p8gm`@RRNc ztW6|Yv0y(+`B=|5ByB1m)YmKS=qT}yVVdtH?l}t_0nt&nC)@&M@Etc*34EDwd&&cR z^0U=WaQ5DR#|}{L)Xt_@t9=0D>2WDc98_e|vBL>-AId}ZQ?WBBXqN2npyF`nDV;&K z*;FzqP=Ui>%&+Wz20G64;nSlA!q4yIsM1Xy?x)}1O`kr@JB34SF=2Mx84h$c>IZqS zKF0{>i;}z`Jg={Ad*?@mJMhX~GI*f1um+UUA*V73k>(~3p54C1^XX2A7E~%}KTTmm zt1I_PF=6YixP|lT(p8*@<2e)HBw>F@3lxfY{-z-|L6T|A*UwgJ6hwQOy6s@ommB0S zXcP_83w%klT%BI8Xfyljx>@;457Z1FTX2`cK+CG6XYIC9LR_(Aoi#n+IlAx)S2?_t~25d*PDp; zAf^vx98CN%j*RP+w7ilfs!bZy43E&qh$?!J4>DI-?4##<5wQi4uuxylqLN~`D#_Xb z%6;au1`+ynaE`hpT#(-NL>Ya$V#-!1FVfD;)^K#M$tPV456frCa>g*JL0Wz;%J~&o zU%p8gYj)U;XsDM(QuVYAV)Zr0dmSy}JC8gKy{C{G7+`ORb;bniXZ(#lWf@lVGas`E zni;$`^n85VPOm0AaYNuc&&hqaJ1EHmg0y}Qe=a~}}B4p0L3kX6Pbe!0}c zIBTG?-aVrXm~N@wRfS-h9JuR_>sHg*e(vk!dUt2-?AL%R{Nb+ye!OO6h{71mWJP2j zT;^9Gxq+oVg;tpHdXBDbS&TO#8wWY9nc1;@bq${_$F2cfZo@tXH!tSv@Y@#mi8l2% zynnF@+>g(sj!>K0ut}Hu@s70ti;6JTBtICqriLBqNOT$l%^+J{_Y%)~Vf6+J+m=K* zZG+5+`^;5H@!;x47NT^uB-7vz5QLRwc`iVjA#lLI*o#Icf~hQm&f_!9kl+0H_U^8w zKAlDoAS4DBnAV6=DLD8~x+VCxZcsiYg)0IUbZzyu45%Mr!X46&xc!&i{MV3cEDl=O!Q214b3#5V_eZ~93Jw4TBam))gzQJq+C%TxzY}6m{T3k*I4ItjtT%e zl2f*{z;z@K5%ZU7^ z0I-~DEHn*p(a$mGsgbX*G}Q-#+R&KYYZ8ZOQVaWAS-^r|NghbA0E1gv84XMnTn13K zy|x)qxlyOqv;}xPkVQlaHTdEsz*r)__B%*X%Ep5x^ps8=~y~iMnSZA1F!1s_o>qzE048y_iZq zMO#KTmwakxId5Y(FOw|(S-2q4c0Uw}?V+nyt{1Ij8Q{6`K<@?pP0nOPm1YC!P|~&9 z$H|X(pFld&kIE_?St-=jKPl9l46pm7SJ693uew!p)f3rPVh+w+X0sKc6|AQ%7;{8t zRcv~O8Ji{qcw&WD%8#k0-aWN2*S5MuELp9U*V~x}-0ka*WbR=dJ5+dbk2PtO;U)*j z(CI;P(888DDdwugmDgfZed4ss(LvmHZGjBl%JF{os-7e%f2REQs7-}$O?EHBCwhx- z8PE9EUT>~j4Gfyn`G?Ec>loE|uk%JG{y0VseTXUoW(Xl zM}V8h`{a={B9-mg4V$v&D3MbZ9Q`|iT|=G5>mKlsx2T65yV^M9ecx}c;2I(u?CqMt`cM5e zXki<~zTzh#_uCZUpJ6+X;9Y+Zua0uIAS1PNo8ue6voNd{*QJ#r(SoBP(q*fNClnsW z0wF~)2`_dKfNYK2tdF44+c!ow+l@|a`+FT4aMXo2N%}|f*SJk@I`E#8#g+NIjq}p= z^103x4#z{PE|VL(@#OF^Hx*zg5n_`YbIx8g_}Yx5F^lPduRntOC&b~t>nAy|ib1ko zWf8z*tl2fKm-4gnsx|XR)ND@+B$HlA8kW)#X9SD0y^Q+&+Q>4Yb`{ zT`%#8u{Oyy`E1pE!Vf!^l*JPUNu&e*Kwf^}NHg1013by3x~V0?I2eA4YYjV*9)x{3 z!IQ|x^jd_)e|l{~Xe$r4K})2+0X~M1-==2Bdg$%OUqLsiyB02acMno2^z&Y_z5P|k zJ6WK?;ObMTbBu}%F%~A=EGHB@T#r3guGhNEiX?g9l*ic5tcuW|1lr#uUsrS3-sHmC zSxWfmWfMldiWnQ-dlinF@gOx^fOS-Si_N~pI0VUS7PBY`T%&IAl|1Gh+~)(?a^gmB zf~NUSQv9QaB!PPp6nVS~o>JR8>%^n#tb&L-uBtAk;FL-ui_ymC$4yQjKfz6#`TZL-8!*>@Uc}vL1#3G7 zML1S*HE;$XkmDLf?Yh35vYDkLC)!2p*P2mq$&R@eeB;PRA$nNJ=FvD6f?xf zm~s8gw1;i2P@Ge#1cgi1qSZ7A$2%4#YsLZC6I)#Sorqh&QHQwPBqMS}Zr~fF*nlK|>-KpSP}dd}jwOXXe*4F`237^ZJI&QX9`2 zb46hjldCuUIGpRy5a zF~7Pfur_@hf$3n5(eQULPpV?BeC~5TXP?dMVuhLbA>d|3bMZ_;ZfDbC`)|kjPIZoX z6ekMPv+1+#KS463!m;P-4Lvg7K7gm}=oI=*egMzMC9}=iA+zJAIlLgR%HOs=!cYx! z($sSp3%ts&n(Bli#X|Z;HJg=-6!$h*NCs;*Dol^IR{Cq-)RD*vr4GmIy;4B zeU7_a`05>adsX^Y5t0VGNXnEx~2m7lx=DkE(CaOofVV;#k6%W;# ztU-pI9ahiNa~!P23VhO>z}giA0`^=Ht{;~8r#@MY+^(H17{#Nx*rGfqNB_wU&PBq4 z*C$52NxrxHZsj858i{y#SiEyPZ4VlJ?3XQanAfM}JV7KR?21D-s9*Y7h zOWO{!i*>!lcepyy4VsT~E*R81L8o?*L`+ydv8TG=_*R~5=EF9tgDgu5ca~wC(8Hv(>qJ-O*}$fSJLK%Yoj6r49Tn&8eRpM!Ps=Nia7iV+ zC3`+y$>1aEM zZoU~m^$eWuYDviYk6Fo?&NPI&o#}@yzCIQGb-DYnBRC^LT`%x%N@%92UR{*stVEG< z37xpV7t#%dVB8mHoKpa6Db1W@M$q>`F4$=+ zr~bKd@SrKvi@+qFpOS#ErhxVG5aj1_g#1T)N7~&u4g5@hh1Xp6Hci@cr<6X9<-TuT zDLm7-t=TjVaY}cg{CDQ`Xe=iUH@pWAXsly28jYmUXf#71@s*T@6`Pl9M5bbTT|8{~ zNo&GqA-ZMaiy57kibwzCGmh_|2Atpf2&jL$D#cWU_)UTaw-^C7PQJP6%e1ymEO@*= zk14K8dZv2;^gwC*HBetB_a@iHV$w+2i{)}Y9*xRHbssj@ayToOqXKM`(1H1Ae|Pt} z5&XOV+-UFl;WJMU_nsL&Du=b5z1{u&7xp5fZE|5y7Wn2vuHb>Z=T}qo30*xXr!q!T z?Yk=*HZo(QgGB+bs>KAO#Q~TBe9?qMDgRV1n5!jxF~r6=o7Flp1%aTfNyk)6lUZr^ zd!;mPPeSDk*oya4P|~!*J$``MXoH#?9We3(ds%+c7O>;WhgWE;j^NQaT_CrQuv_Nm zj6{z~y-;KR&=5E}M+Q(7vOfyO|t zQ}|m2GK;KlqFkP1!M(?8bOS_d}6vmXUR-kV_4>@E~f&#oJW5^oS z~d4w-x?pI(Facg8_e0~swD$w>&9){jXBldj;x@}q zT<0ZMFR=or+$<%Db@1fA0dmoM zX1%z9o0*dShbzbpx*wU|Fm5-Ou(Vy=@E!tgV4LO|PChpaT$*m05;rpdJtgorRQqZ% zy}2&S`_$0)&4R8m4!=Iip1668?-+hir?+1p(f6{!kL>HCn;L zaSpxxdIYx>UyqI+RiCr_yIA1y{oT>ItYz<%FlF`w(VQxZ}AH%n%)`{ zRs^`itZ*#@qy`Cj#En)mr$$EP@2rmQLO6sEPO*Y59+gd|7iES z5+G}Va?%l`?!<4Xy#1x=N6A>|5K%C7Rg&gv>5SQ|vocZ43{$yYL&4^tAoWC=<=qdy zU7_6p0(34KUK6*YOYHF*_deB5F?vW-lJOxYZI6m)Vpk7x%Y;V+r4h05p+5B4r`nLxmwOJeR z+li#$N@DD{!sy2Xx_*L~GH84YBx6j`zK1O;Vbol(C!KVrVk5XhbpeMeM3)ZY zIy>vbzxXa=Sd<< zU&Lagm(twq%R&OEXG>l>2dw zNwyUh17fYGZ^Z%IA^bN7A&4xT>{Q1MkrR|$^n=~NQc5=)CN0PQV3c|}+tnEx%xZc0 z8qxp*4GHz6a2L5AXJ~F8u;CMxsy$gg?!rKnf9!8c+}L zI2FA#B-cIefnlz1BSj>#B4i1c=Z2o^xy4m>*8`oW;zLNv@=*Q9g?QDMxlBJz9JSDw zq@Be=mPJS)3{%g`XJve6FK&=ra#0Xm8;=QzUsO5WK8xL;{4er!!iVP~2W)7X3MgIR z%AvTi@|G-qaM?iJ1}q0Jzy0!;^0?4F=1Ef8hG3|c3ID3+^y5`o+UesSE+U-Ii!T4h z7d~Y3wj{A-khr0$yN_~e{~qV8$Nj^1xN_70XkGLZvi*o;LpD;gNsp{#m-Wp>b+!!L zVpeBVp-rK!puVh7oLec7P!$nJY=c%~Mr|4}4}s?$Z?)Mxyzi}b&u-J3q-$`oo5xsmFFYtA=8oh^brOL5O78Tp}6;6&Of zUfq>VJ`h%~#Q`QkdHEFWg1+Q9k78L5z#0%80SnyDwc|*=kc8kYoonG**=Z4zxXGwACTa_C0H|i1Y@u4xyQ90QxpbnF zK+!CB-jj1yf-hsrg;;Q&)$B9NlnGNPtYv{DNTCv*@8C~eGHe}UZxOnL1o}`tQQMkC zlNy2aE=~>(jg|mHQq1iPAgib?*stmnNCyGf*nJO!$DGX|*bG>V?V4=T6w}KdYLit< zup>@ z3UL~bUTdnD5>-?GG*dEpS?_q(Mm42I-W!q@&ctasoUidsgCT&M4Ui)Xw zkQygr0UbojNe_=wJKT9S9pevmLR2_WFbT;hIncEH*j5}iMS(B~i6$aVNc&ev0kteI z!Nj6iJd{DunX!)YDXp@`GEtWhGfN~&S_C}8omiKC=~!c(Ob2!w_2b*y#LBF0B5eV0 zF^51Gob5CC{tjM&>IET7pi8~S=4zbHneFE;IXf{Y!p1PMuL#-k*HWtk?ewj4l0wWW~d%B!=p0HpNki}+hu`|3wOD*toTDCUiYIqUjuG(Yxwd)Q ztBg*azU|SbKkgVd-|@@8&tiIc)eO&+-dSK2=Jiq@D#@u|8*0;8X!G!_l4Jv<-W5!A zz(5&4^fw6uv6OvtBPI4bB`)fQ95XqS7o`y`+R;@47R8PrzmsOVrlpJ4GJGA) zx&<|rf$`j6#=7yx6m8XJ94{I6%4fxcNi3xv*sQGl&&1=#6%`?xRf47N5ax6uwUneT4?k ze-pANs}{h@p4Ust!DrRa*)2yKl@B>%c9oR_5qb)4J~GLAImEZ{vln~z$#Fls;2@k&l^B-+tvFh z_7*cX|Hoy0blUEnsP<@Nr&5B_ed6oY0@&a|^3;|JgYGqx+NgtO7dav1c;vIJMJRSvZx$22-(+`YO}5r*kt4Yc^iR12f_W%DMj z@7A0_ux2_mRjp7{w-y@ZM5p|H5S<&d;Q&f^l%1iOdQM)q8>u&J!_;S^S8cF(L1FwSl+U(!XYO2?q>VMI^#T zSu9{s3V4pQv^9(!`{A7+;ceeyZq-q)4R9TX-sX1RqS1=t_^@!!7nr9t*xRC|b+72Y zv*Uz!1-D*yujgsk5}zDhB{dFVIgtfl2aY{VbksB|Qrh6%|dB3TsT3xMbOzkKvVay3?my1s|#G*i`k5#x187{Ro9tn3-?05j- z{d%c61Vu!h0N5kmC~U0BtqmDE~awzkL)1&VPW zypwPBY!zofoW8B1ATW@_P1^CJebe$XrUULRAr9RB9qBWAHvol0;tS__a>l4-y8o$2 z(G{{1-RN}$*>G;L<;Q>}sHK#7$qc|jZj_pl$sQej5gL1rz-_}#x2geV!~m2Rq%dH$ zlJy&#jCazN-87~Pd1GK$JF(`IGS~oZyhIj;OuH&%ix-^XVbW*al-KUPd+*bGsa?mh zaYiiGZmpZ2YRZHM!c8Wm&Bw5JXL1nU8$RQC*GR^f;yARC`uR>c?|R8?t(gl0U6!0_ zeIceGx~_Tq<^dyBv4a}a8o=+q`#6DZ8ca=*nGi|xSl^a9ohX8`QPqTbg%At!+Ga;g z=k^1sSzCw*qeB!>=0o0E)x6l+l(NR_mek)>x2P)yE97W}G}*M1YH``u%YXD(#Q%jv zmeQc+G&8FRwMDihv_1|S&4)1@H?jDD)ir`z*1U`G>d%@)BYn9%9hy}g&{6Hu zg4rM1nnW8l(dReLC|kZsKvELRr|^<97>S#;p0A%UeuV!R-FdW$CdPGu3^JZK_j#3B zjBSfyXB4u_J7*L@iM#m1zrqKX{0$~{0^zk1>R*B)7Y#3Cbx*%I2*YMa1RFNnsckP2 zHx@*33gt|fqOFJYz5V^C)bvdr+M{*b{_fMHpF*86<`@zK+C(4Sd-|DOJM7bGc*ui> zvn#%6J9Or3{tT?R>@p$@1~=xXcAut_SrUMM=@78Pmy}`Ri%=G%0R?S2*f7FD=JKiB z^*DLAM*|coHGbJ}^t5ZiS&YXnNa&0oKfN>au26v~vfDYR$wUpJdNOBsmhzOHLy#^! zw07UNZCj^p+qP|=wr$(CZQHhO+d6%}x|2Ko|3NC1j567ks-2bftWaJOtFN^~bW~7% z>T+}WeL9yH^rVJmz5o~`|0uPptYFVT5dXs;oVeon%MH+520Opp;GrvY*6qy$ir}KwVwZigU1q$=$&lR^T7j0 zKX--|5WcqG=Z&=(XLUCaX%gWTR3Vd-q8#1l*YGb>m79=>QeoJ?}qW8WY} z?b1(iUR=x*fJFgDl(H?X`s{ZQ3tn8T5ER*@I%rzi&Ky{pRW}WsAHq!;&l`&Hm4EqC z0iz4R!-x{iTXsRdk$>}FPGRMpoKsh+2MaRZIjNgdYz8_yddy;4P=mSH276YeMZ6rP z45~_7aP|TACWg#QF-oo7?+c}EoEkA@8>6lbXe=ECUh|CySY4j^)doM`BKlqll90VD zgS;p)>o=B+l|Ca9U{?TkUfhN+U=RF@>WkL*3`>r)1m)?Y+vG|dDufn2y>mm}T?V-&}Pb+HA?&cPx-FGOAUuUAWC(7&ChE^ow_<1LA zF%mFFYT4QXKP>M<1gwNiXWW{h3`tg?z+=ICxDX-OKw`vqEeiq6EIwQ=jJx)8!FLOI zy;7e7_IU!O85wB6L)=GNj>PBS_Y_prt!qdjDc(jk;7e)##{2>$K$5~81(Wo`HSai%aX9=Hfx+Y~@or2Nvjli*)9~0Ep}=*w_NQFIC|4XE+sEhoWx|+*OOAp zl0*a?XbcF(5iW#7Z$1>+bP+@OfgXVe7bmPz$XZ?#UTBI56AF5x(b=R_`7;Y5VJ(QH z948lyj2CW$C$!O5u`@|3YTBOanfmb$>Z$GqEF8FmGZP$!JMkp+qQD)TTUb|zhy=PF z-%=RRHdB9KtxgBCtTpr0YR7=5TZL}j_^Jrz{nCxe6z!Sb=~s-ItAa7H+r^UENE@4FZ9=PuNb+ zSw?m8<(_$W3BSmpgj3KJ9xQ&Pb542Twt-k##`W1V5qZh|rrB34O=5J6R7a5el50;7 z&7e}a$WP4SG*tPrSFS=^(t-a{Mc>ZI+eGOAg8YU&v&EXDE7vKP7B8X5-ig@E#}i zB8TmvN!Tty;@$@Y$Kf%gnPy&|{8ScrcU2)ursMF(B^w|2?k*?ibX=qHJxw1oC_lr- z{oj9>se{I^hc!^&TweaQ-;%5OIf6ex0pH#gbd~s=e|x%HbA<-*x_!cx-Jf(LJ6=us zjw+yDHBnmxD!@^G95yh%O4#F*t@E;L;L5vt%Aq8~0=46^tM3himYq9GJv8M$yVoSp zr``SyjCJL4zF_{@9xceD^QCSp5C2`fOFjDd03*f|iSTpTNe(&v=X@R=J z*@A_|fQ}T5O~HBA?zu>*$?_pe0vUBYSlNMXgQ+hr#WJdV=!}BX3s_gpx&1xnpuIb$ z_qYE2w*v&`c89As#x^nC@7}4~!RbY2ensIMD!MX112hRX4e2&S@ZKs# zYuZMF;|h=`Y!YFh&?;S`?3sBCOS@5DFHB-!s6=c`m?iK4l29H;ooI`29Zx4=%FugH zkd3I)pql*lNu)t6uR8{`>KbF$rm|}6Qvznt@<}ghm9veM>~rHscc~6eD&<5^nk1zP zIwj3M>w+fWL*Hdyn32ZUsF1o^eD7-IZohJGCIF{VxbDOwQ6!lW(Q@He6DqDSci-?- zm=VPY$n*L3sv0FsbMW08BbUBVAuXN?iMAsBongC|J-+w&-F?RjX&kz!DYWHGt*e)% zZ}o@(lCvrOKZ|uFSUB#}gLd&~@|;M$q96rYd&BWF+}cD4Q4DAT9ytnmemh5>vy&OM z0!|tuDQIKghi=}zY3`=>^P!LotIft}e-MK5?+JRYn-2429(hbT6X#j7GgJa)GZa@{ z2`8tcrv!DXUwDl3Q3V0yFKf?Iy=5A<>p>|6Wx7$}+JP<)pVQK5B`ZU(@KOIm8v!D8 zH0LO6(uR9ytQ&o(T^5GQJW0PT_;`8pX)1L^N=Y} zH?$Zjx42W1wFyLwGK&9mb88BnF;%L9_qTW;0V$P6 zdmOUUcCBvMDb>AiQW|@e?p`7Erd~)bzIDzgT#CW zYd>7}HXty#5*kITt|@<ZR5FN;8Y*mE28g+LvHi;P{nbl@MK9$V2>h>LU z^EQbK+0CU1Y=>;_Nr_>0B@8_)T$0|x_(p|2b4F13T<=6IPE9jhXGjUpuFC1Pbpa*s z>lYjKZ6FgrHhj0Zy|j1AoGu|0KvV-p|Fi+`XCh#Bx|e(*K@@4%D5Q;G__*eu5g9{rY!(YruM>4Lb$gWrYd;fM1B#;Ae@$803*>(f? z74o(eqRQV{CIuu`QJU)srxmcj9pXph0o`HLeG=p`15RdtS%(F3O_6NLIavyT@Lq-Y zT$37Jd1)?$4e&d7d^?Q%Azw~8XoS4}mId>EEpqY}t*B2b0M`{j^d*i$~aofow=Qvp|7{UeTi8K0`lZZ`iR-z17hv z>O%z`%BN&z*f`zpfa3E-__cwPK>v!lYqkm-_RC$7XYG~b5%i|Sy*f1Q;_-oKv#)Lb z9RSTF)bt!P7!%wKgs=woIUi79XPc-G$A-v60bTsNRNp#&HE`u#!8yFPzFEgGldZLh zY-1yFnlOH?5#6G7d|rP8LOYGk)ntGn{RduehC=TJ(L!eEADjb);&vgdDgMo?K-}@# zH}yQKNhrrE&)P#+V1ixD>extMi*VB% zW`$Y8twlxlOrl7Qb1(gV;J0+br^KGcyg&1}$`NewYo;emV)Z3f86j4d2^weWGor1< z(cF&4H8mG!M78{O1u5Ls+^wJhP-n94w`AssHneNWY9s-YL@$p}L_V zGtrcDH!R_9r(}xC(Uc#kUJUOLFVdivBJcB!Dt*&PGBx2fJU*pTraCKohm|s=R7t3W z)|DYPQ)dJTOH4;KeLQP!-n6l+U^HMCkzWF@=+A1tPqrWJ8)>$rWY68sJ}4(z9dnVX z0tokbKtz}%m4tDd(RRK2TkQ7z92LLshV5~ieE^7H0Ie83^mDh$tjdHAy@gA5jUWhx zakC-h-`&J_wcE8^2F0NVzyY=1=PAVpG}E53dDXv^+M3w~)Kp^Kk3I?`=DC)0PmC{d zb@vH5^9LfxgGS&Ju^$-qD)bOcUJHZR^D3hOSeO$UK?nSc@QNF^T0?J~%nGZ>m5zf{ z$9bsEErhLRLSkge$@ux9DCkc?b~Nuvxu@H~t3UYSZQ`{*Nz>;M;#S*xZ{R;HE1^aS z$vZihV*8_TaT}4^yWD?DiE8G)`8JwNAt5|M*v>DBX)|(gAjZ`wRl&bb#JFx^FW@yV z-CrCGT8bdtl+RDIk*XZrT>VF9xmHzg!JA+Z`d@S+`aKgQg63Q#koG25BOefy!PiajS689Bkx@X$EnKYw z4?t9_7i2b`4GM}^p`+9XnQmUPT|hnz1!dwzlFcSt9#mFeN2=Q~mirBVzB`Xdg(rGTra zkX8&>2FJOl=E@;f+cbzz9*W&5l!Y_4v9-kX>kRGt#)Iq1)kcpO7GR2tT0n_dINn%2ehp_o#7dBydwGvRPkV8{qW*+G7x{`bEc_|hoNPT^? zn{Y`%-&qjomPs#9UKig3ebLj@E~5>IcHt8ZOQsK^cyQ#htsgwkG7Yt4Ps)OEzfx^L z%ZmC_hh$O>vMVwTH+Ii$1??$nc%4+-gS)`@R|$_>?xm))0>ZPjLmT3+E>(2OXUA*T z39vUU3+)0QA}=Q5mlM2XT=J89mMRHTy-2M&`oAORFJY6Q*w;D%{9x@fyPN{6)zGj6 zZI~m@J}xvPN?Hq1#lo(S5=}M;(6&Cu1f=3?P&63EAc;W6?6u`#cnMYM_!>Lo4G^i$ zzfWjgH%UEO;9KQ3LHP4MGKvHLWd#y~4>!s=c>_mro4y?R|K!crk##le%C*biU0lt^ z?v(ejjU?uj<(qhrdvAu0f)L_LWW^4K$zO)Yu=Y;^AzQuyBtiTz@xKjT3HX`);srXO zg|Pc|Zv%KvOF(F6z}~mclMS%9igr3QMtSw)B11}1jpG4 zoBV&t{jq=TfPP87^^CN&>pUABOnCCNvQE5 zQh^=5gTNGYcB3^Ru8&dcqL}2v0;pd<30zIJ@&+;BMi3{1f2^3WZ<@+e7fx+{3PXOey0W#qo`}OwNXxw`Q-X3~ zvt|oRq*n-rlT&Ofo;_Te8ArRv9eya z8urS|4XT^m3ihqKR`s!uAF(}F?SZZTK@)DZl?pR$+VOFbcgtti9d);MSv3G-Ok5 zu>Tbun@lPi9_Qh;X8?+Rcf*dNZmZMp==JC|&z0a8&Y<2n$M(9-=A!!F>d+T9ci*J9 zs*s@W;)p#`hTmDUg_Mnn$h={$v0x-fo&YC$FJxt+$FSw$=BS&}mV66QeEhTo%G2L0 zvp&c$01p=dIc*xFjfW)g2A6bmIjr|8I^m3BVd98(Q_47_`%dREH$nsZw0pb&BM&Q12h3ZH!E+&Dp5ZvZ^<-WN_ z2(n{2G3h{QgU^k&lwg)b3k_kXTD}V5bxc0)2w5UgiM5Bi7~Sk=jwPk?%T~ZH64)je zt!nk(Au?H8yt}}3?w%|7@OUg=DPA|d=|@0lC=W8BtTumvUv+N-(_PQxjs5Xx$T9dy z!D~Mr8wAJJ1`aAVzZ)4FV)JM%!e*wX*aTgf8Z_}CYc_Y)z@i#)&`dL=CVV-mhR%dE zhW79UUIDESYy~1hD_nl0&J$D=UKyD9Z)MEYIIIwVdI)Y<(Dei=*OVmt4x=+-%_-N#L9A(#rxliRX;@D`)a+Sn$; z;K1s5l==dBU^Uo}bPdzhIVd{XzvdabCHvie4{IrGL?eR}h@YpnWn9Ou`}Q(#;Q{biJ2@;{t% zE7HibbtreVb9!+k6JUVbA6ORI))QU#cL~YJ31+gVn3hX3P=p-Rgt;BnZBHs7#3XKB zxj!@V;fX?!7y{ZyR>1Z^%K{S6!P2g0=_?1E9TQN?ham$`{qLD=KstSuo30VgyqU!1+EV%fHVjP*9>W0*Xs9~a64hJg6SM3`+hew1I(}Jm7XB~Xwif?GEjtdDHn{zPtgVL( z$-njUvdgCgFn~bIe-V5lC9t(%`fis!4uyz{hAbJP2wVCVVd~p11oCSMW=9T9^s9vwv72|Rlk|yVEG7(o>IpSl_wbAbcVS(Zks|>58&CyKfMLZ^&Gy;bR z{iavatm4&dh9eSzQVMS7(P7SfG|)MioD*4mH8mz1b` zo^Ey?es&|NRP}te1W~;@y!H+Gnyoeo24qubxi8&`fmF2AmlTj<3hi8sZ&8O3i>?h4 zme7YLSB4od5pgc&;;D_bpc9yctW!cIZ$`lYwDqTa#vs@l$21(oYhV&a|LTA&lK*#OjOQp#?H0bK8IB0TF9bp>DDs$9n07l|CsQ=Y8@ePJulebDu^pai{X%)l!x zeiV4}sRwT|aae>m|0aOz(SvkScCkxgaZI*{+pDI z9WCvho#>T4{yH1FOIVs)*!(w~O&#f-O`ZPRw{oI)aQSQLOlR!m)T6c)yUBp)L#NMp zS-D6@JOEYS6`b~$>QdBJwc-aTjAOX6L3wKsGIO(;}@9_8_zZp3pP=#C9UMUa$ZRpp+7CITkU zXgv~k8k0%%1G*evU=mWTSOEEr-v?o84!OsS>_7js$e*LdSaCYXJ8}CTPGfBWzV~rq zc2^PzI?>LQ)!3YwDkz;fJ6OaRyr@u!Az;2`mOu2-bWrNUv3us}f}C-LM+ux=a**CX z&nOIW`$KQ^E3J)t2wuDcwZ7)rR^linXgqIvBZ1Zwqt=tH16OguyvVX?n7s+n{TNeM zFMvyzu4|Pk2>T|cvFOl5c!M@(e+Ws&tQWnS1|3CwLS`8U)C`7WW3d$1j|e%Tm8 zc@pnYml%aGDR{JtglqYFMx?7>m+GDSCv_>Pr~f#l2ZCX%30w4##aWaC*d^J~9)9pB zTdfLjcI0|&w&9Bg!6>*V&9Pj;ASWU5I*?x09WO~wN;N9*nuOSYTYKrAwnlc|UqNde znHU+KXQzK%yCN7(DYj|Qle#8$JlNgvGYc)X4|XIwX}aGqEF8A>FZbp!%595JH`tVz zY0e;Bv;ie0461J%gv=GNENIDB#AzsXA{3xFcwBe|7A)BEUDgs$6!B%PM0@4tL9IW#7^90ME{A4#`}|Gtkx~XGHsq~_s3Pk>lOf$dE6ZV4xJMO zbrN^O^hcORvk~1U=8_V0Nd-Q~k>8_flHNonQ4 z|0!B4rx`qJrz4horzh&=e#ER&IhY~9M9R^=JN#T1h}nN3NXTR^SL*|=TF}oB4-oGl z-;A#%VFZ$1-J!seG&i+sRV%kvWEl%nyf2NPk5x1k%LSgre6e+hWlhAI>XDPV7mZSl zC7ylZ>YrTnbV#_r+;x>N?kt&SO-!Bd4nIB{o5zzZZYL?~6Nd7UNJq8UEW~zzi11^a(Pge>*i&wfM zAK86$hHRw23FB;Yg|{*57};yr2YPQph5PUtclNB@Tx4G)Gi9 z)%wagWXCQo%1a+`dsl7{t<^uglP=4&4TFUgEh#z1pIba})iWd6uQy!qBxRXpB=R)1Kf z%(8_#zFW3E3Z+OEkix!kjmsdQ8q`THWzG!+*^gi0GyKgn%e(`}$5N8pE0$lJb22ZF zj1J@N22uPU@uP+T)Xy3$M0ukIRL|=pz!yWuH_`yDlGZ*0d31Jz$Y7jI^LP}4Qs^x< z{#n+NJJ5`qh%a-rK^CbZf{!r;mq=5jVm@`LlarlYt{y!P7s%D1Qm%dqG#MwN5BIiy zJ3CsyJ|Y%|Qk1vy^MU{8l8S*MiRVa?gu_;_1sWf1O7f22%BxjUIm4P`CQ+#;afVhC zja}Q%LaUWU&r?#B-8zTf28oezybR->1yOA?$A9#0K=ls)DN=MD&N2UU64RfLhsY-9 z@gJIdE@ve^R_HudrIoS?sMp%Go7K=CJ8_hj?xHsqe6;i`{~IAF*_x|bIJ79lBVb(f z)$-yGK9w$V=4KkU3R+L&xZsG=(H10c7-sB)<+-|*QmMt_&W7w16E|~a-PGezQ^Iu- zYwu%kn}GQ7QL~{ zfLwJvckxHVM`;H&SCb1MVM~2jxe=UqfR57wf*~q@Q6>A86M?5Z%$$=^(^%ESspBoW zmuF|C3D%QYx}`NwuKEQ#eYu_Pd2mV01qocLMl&-hJY!#NOR0E<(&HgK6N(&@eafG! zUreOm2q>0q#e9IYAv1+-WN?=8!nTG7Ju3prCk3i9c3l!n`-K#@^ZAS{8o(VVl9yZ8 z@GXT;BT6Yj5=c3u(BJKuDVv!D2>@%dNfq{#rI-D1ZC}aWV|W(M4*i49cXS!dci*djvmPl4~l=gDcTBW!Ku5nN~1y=d@cQ zU*(t8a<=Gd-azpk? z9)t%LM%BecSKd*dpPK16v&;IAWGjn2 zlxmmW!P5}2M8 zi^KYl?c~IoeLN~Ztf;SO)7Z=Ry+cuJ?Ft7caz!QPpa12mgQe!?*!KOa{1i;3_JIE? zFeH<=CT)PJ1~4(vo@P70Dm1{u2hY=P$ZNC5$f_!*X|dk4M3Pv2mnGaghxt!I+pI1^ zdR)>A=bU*ks20;v1Zn1;j<{zA24%qRLgxpL9-H_h6Lg25z-tH=Llj+T3!eb&Z7>0( z`-HdIMMQxU8jIpQd3|mn-SR*l;1_XI|LPM8<71Qb1AS#kz8_dJN)4_;Cog$c)+hqQ z=d0}JU)LfsXv>|Bg9I*$C3xi9V-7x8Y#*wvWr85Its>PI94{qu2{!ZQ(a&6oeME^A z8IumOInYp<6u~>;n8EFzKDXACTi>|!Z z?u!c;L5oXs2O5LJ`z{rCND?6^;IFSZcFrRzQqAtC2&k0(thG>P?_o~SqDN#PiuS+m zCe!>ve)V9*r4bpjjHn?<{$P?#+J4xuRu(=9(fj+VJ2VrAaeeZI!{dhzxFHm!4TaIi z4lW%rt1N~cmo;HM?^jU}^kmf$UJf9M|JNG-??NY(KLi0{ZCbLk*DKcft(fzkIJ74X!NjL8q>NoMZB<@o({Xw7h+7G(68aqF~ zg@2#jzp~b3Qt~7V);jSTrBpF)$< zdH2aBNR*yILJnpBZAGH_`8d_XJHE&tqQRnhzeurFUD{urS44!hWy)=~)g)#7kGGbC zJnaP+6pznlnz0g?G8|6$*g~O#Np{s=>p1JgBe*8cGkf-7$w;Q;n6FL!N@+%tbuC6* zM+U1cTxxfff24{v-4k}~%YjpW-_M6+scqT1J)LvR!m}j+Uxw8&>k`wquhi_!LD49j z*5)*gFG{%O4;8PG3hPXo(j?c?>ikP74}y*rj%RltfwDhc!zN~fShUCH~v zB10U=FfMUR?Cc~IdMC>@ujmtSfp=)s^>e_5)-w%h$JI zr^oJ~hv&Ptj$d5c+ZW2crS*d2>Q54e_+~QhHAGohDtXTo3a9jJc5+!OC({$QIg_0y z_&5;6nqid_sB;27M`A3*iEEz3Mhe4pj%dMN%9XAt6DP0L^4la zRw>c5QDLk7LB{}6Om#Sqw{4I8n7{ zyq_eOp8spvOLf71a!2DG9EPu>D{xb|nI(TnF4i8^B?W_01V9a`UDAZ z$V}z&Qu2H>pCBP+HEg{g6$$SzSK;(GhzuA@b~+3u%m`JsEcN@3XMUdhM2Sn0e>_1( zXm)AS0*5RgqJwLW`mGQU!qn3-w?tIpR!hsp4+620DAa)^RF}Ak(9;Ee# zZY>Y|MfJV_HrCd$vErgRCU^jvH#hiafdn>%WsK*flk~jJhz;E+-mMNok!eu0D8~)f z^w)REDa_3RKO@&SQCKTLMkpG>*%Qv(|2kbohMO};a#LRgYSzV-uQVI2f~1)0z!FHh z(jiYC%jbT#iM}2VHF@TmK~Lont8$+sdXjaV1GAf@zhkxMmfg8?^{W&wSkrACCl!u!=WWEXNIW98!o*RFB3*jov*-w*WO#;vhJ(asjsSI!h4t7xvY#j}FgJ!L z=T(FZqp0x;S6Upr{?O_2*frbg&}#%ruSMQns4mGz9PV6!;+&$elBUgg?zmCo2a8%5 z|FGj<;!vqSvUwK!EjDkinL4ee$TD*Rzlkgvj98(3&qq`?2<{dZN87~rb<)OBSQVE( zm!&nglBR+uTG%Ach@D)bIgsTc#K7LO{`&G zW_N;R7Mc-MLUojR%KOyQWg5$Lty~LehplC{Q-#WT-E2|k?;((TQHPsO)VfC*u(F|o8<)G70{Ne8<8U4UfEN|0 zP5c%rEhQe0|3rGJWJQ6Io)|*u$T_VLHjh836uG$k=e5tLLWvecGp^#=$v_ZNVc&={ z?pimiW3$>_@o9l$)(|$irny=1PUVP6zJ)!y?y)2~tOes{C&Z!$9I1tpDnd+1k}~k) zIGy%ry+iu6h|62=bmN}OmPweQ9!MjIN#6E)^Mm?~G6Q=^(J!|<gY^w8bqHH~r zO0^wqi3K3`Y-P9U$Hih_&n`Yr7p>G&qRrRiS5hm`@&??37hDO_^yF)+#Qt!p>~-KJfd4Wq|m|GYn+(a zCcgnQQiH9V!~(!W=)H{zbwlq18)tm62!G!ez&&$AinEjhI zYDvU-xq8`>Ef0s}iZLGlJTxdBPcPPjqpSzP*I-XYE^`V67|#411|!;}FwXrpHSAp#jn1A& zP%v5V5PBSxDRNFD)Ul==vTLj;XO~!uVb>aEy+~)l%rkA^AWLaSug+kN^iY%QCI_8737zR}Ek8hDMFjS9M>H)0 z;yyR#gML)zDH~p-Z`JgHjcx&aC`&3csG3%MH2YhA;mJlP{5fD3hS1BcbAo z(Y0AB24$~pt>LCFTxQ;tf%eQ{v+%GKn{sDh`HQ$X$A(jqt=wg3>*6Hf z?R-gV)@>j)XM>BT0d%*;35b!M1wx} zi#0c>e1XWUdcCSgtRkS;ipVk=*XKtCu74k{IJ|uroiP}|E)S*)>e3v2-FfN02o~sP z#waS5@S=Qb@Gt5Q0%p++$=TP3$-X`59I_gHFzhMA)V;ULl`Plz(bs{GZR1#$%O z4;(=Vu!djx6UG_jtvt=rM1}yc8MGHtmsGuUZU_NT$fW!8FaR|}ginUGF&ZGGR*|YG zqS_Lr&@ivl_g6It&7#@d^;;z!ZfP(LILvX2Mt$Qg0s{%T<`|k!F!tAuz>VH99)}wy zFjEx8Yc>@H&hh^e+n^kZiovTyUV-ZSt~NqJ5kwM`*FC`%SIiP|QmjG^5^+>Op|98M zO6lC|j;iBHeDEasUme3sqFPUmFWI!yJ(*0Gl8R zF~3(=oUbyDudPDywpAkfy(#2#V?Vtr-PNP<*#0sa7x=Lpf&Q_bMbR%(ES+I;XC-;B zlbe2rc}0sT1x1$XR%ALTp~D=`08K+?Pt!e(u){EDc?{e{=3Rj1$v-67X&3h&UK(Gk3^t#Qso9k#}FQZROW%*)E9Z4GBL z9UhjOv5!81=IDMyvy1Z=rswaQ6+!qr4o%NUQL*+5Q{`e;1eQ}Ai}d!v3L)+sVv2VZ z`HlVRdTR-DKR1Jx;D!8|Bs>zds2=AxwtGR4RrvRJVRiYZW*c1;otc6>vq2Xq7`564)LLx{P61;?9L!ut80HbA%7>*HdN;qvPcDoB(8^PY$=MtsHV~W zN-354Z;Ug|#cM9G3m14y41G&s3INyGDT9O`A-Ke#(u03>C-+EJWnxxi*fSAw$`TaZmNeB6SU&#Y3I*`hNQuCs|fKaR6yF zh0{!{^j}iM-4Py!Q7N8_86)=60!bUo&Mc3t;-Q|6HT0VQIXR`|dg9T}sUZd;+E4;(yRDZn=DF0r@)mOLT6d6(N-L zsU%O8&kN1j|B08I`Sin{rCdE1-mQy{*2Koi(0kyHVjT92bq{wbBK|FWLl@qYE?TpGwdna}&a$b)b)GP8kbDSeA z1EG6Cz-~vif4+a#47lyRK-lZS89JnS9ga^HV$g%HO`JmVrC+o5Ulhain&7q|)jsW8 zg5G(PWGdW3WgqAnpP~k$KV`lub#0Og^AoEUH`a6-d;MosE@Wo=BVz9kY@m$ZA7PRR z_#O+!-Q^1my>%yHf;Sj{9(H+2{v;WP*rwlK75KyXq#X*k@c$!7Eo z&2`A@0fHxYZ!u(7{(=yt<@(Y2C-6a2$SRD!{F9V{6oj~zoj7S}0Ff3L_TPp8*6a)x z5oZhc=dMTkT`j_30vO|_L{H)A75*cPo7 z0S4W4k4TqWXcSou2kbz<0^JdZf)C1`8{cAAY z|7i+lAPI0d0GoypIs2s#J@h^i+?VVxKj`~~IKXdE3!)UHY?$3lP_vyD$$@mEU@sa+ z1>+yfH4mX<%XHF@?`rCN@atf1osV;H#{$k*-#6wD+cd{<kk{gQ~x}o9t~W0$>)0i1D)*8S_D@~g`pVV zBZe4?nT*j!Z-?b7la31So1kOHBG<0;%RZgp3G zN;xWoT=>N=2Yc@YV1{479~2isGwvQ1R5yHx^aGd+`u)5-!|KmLSJ-=jBZT4&+V28D zSU4k%>sE|1GEz}x@C3Z>Ttn0X@_g!bmj2}GNFMGUQ)?!@?b{i-0r=iCB<>}xq|TwM z>VR-Da%Tvn$c=d#w7EYO_%*eBKyR+6*MsVgY4`Egv_M+O6dxW@@_boT3PQf!(me@% zSC8(>Za;)WM2ovdFlW@i689J@YikkY3s^<}pNM#aH@u8I zcoERsn2HC;p?vV_ciU2OoBx20ny&>y97t>4EpLwXzh5QA3c=PRfFsc4t?t(RwFUyh>P+!UvZI+TA+W|p|nvyf)<0>^zT~sZ$xyAkI6@))GcFzab=87QCJ?U6s zS?DlyzN|ko<=Ze=Qa?xTLO6wGnML_8z~%%9AGUibGL?q|$7h4YX&=n&K16PRS1IpA zA=4#tt1{vU9nFzj&?Nr$M@z<6`VaDvOPsLLl$wKuS>^iPI96c* z6|13t28HoF_Y_#~N~9x)_cJ!PBK*W_UU$gZpaY#UCU`6@Qe0?@v8&WJ@s289^v4%7 z4ZCgO1Ljjp-U6lO_|!4OSj>b)tmvd>_v(MKJ`loS^kcv9)7ab4xeu$KZrLgJf(PkF zJo#dxj+wCZi@?b-%pH;^nWQI_n%vuB2l1Hk=QtYay8f50r9{+F4u_&;V!|9_b&Ityo8 zn;K1zrbPzCUv2YmcxzsOPxC%4H1qD5JAb!Wj+_NZOlT|l1qe@XSJy>^`&I@7>DJDk z-h|nb+spaP7<*}5-ge+P4H=Jz@6SLF&i*s+-N^<{uA7r5ir!8RpEp3*4e%uv(eJ)n zBM#4zz<4qKq*j&E#dSq)bs(GPVJ(D}sKIz`O??zf?o2KYuiv7zDvfpZfPfg9Mz22$ zhG&E=iB3NXABRUN&IxHw^bfzY^Eeb};Q3=r1~)nfN7BaK=5tAQ5)blmW1Z34mM5?W zSa3M`)a={av&(M+XzmcxkTmbw&S+@WZG<@Sol!@SHI!;iO#g+3Br<+}!Ixl{f2Mu2 zU()@P2Oa#=2c`^!ObG-$hSIsu9D=5dD_@ntb=UgtM?CQcVaMqf>#fI?T)ijzgr0%V ztlU*yBl2BXnPq+xXyjyl!HlFMmP0&V;=uzXB)$7Tz~=POp@fiSke#g2 z!Z2fJn6Xz1m8FmtrL2`UlJ-=jB5f2(i-b^=v|8%5yz?21Z)PyM?{|Nn_kQpG|L2^0 z&bjB_ZyD7Kp?yDv3JJceSNV!JClC%_^#3#0Dd?h9(2K0&;zAc4w`UR0*Nb+q@I4dU z#c6)&($rp^OQOHU&R^QKULkDf&j!AD>%Ii%P%gC}8N_ql@r99wl?k_<1OvXVTFN1i zJi9@wCn0*#yZzd2lLRRKnkF0)FO7Q5C%N5ua{&9fWoG1z#MnEwv2JoQ$)zTO8t!RA z5ut%9RZlNY?k!QZn{xwqj?IkFV&h>hxQ0*Q$US+baDB}^o-+k~*$-UjtbSo~;ga$_ z^Mf;es?81s5@eEaJTo`mDR{X0Gd@?a>$_1=;?@?&WQjkf1(maW#X zdOhao-fhy$wmjXK<(hq_LN-~rPpg(ke*eR+Gs0#HwWeF=&$?OsP1bn9o4wo_d{a6P za@}Kdq@))Zm8tCEpX|x2F*p0rqJ8rm@_+NX>b5x@R%((_&o0!Hwb`1p&7fdWQ*p7i zpRJRorVICxba+L+lLRb=TnO&HUJ+*=hDI9vLU*?I}*nU!Oi* z;xGA(^aD2AWsTt__tbZ`R9(|9chE9A{?R_(%UI*dOy2E(c6tj0_a^?Bx!Fj3&xb^E z{iD=Pw?#$1WMnVwJRUAC6l9_OsWRclU0%hw#89?keU~@gUt0Y%T2C33cDNhNHB&uf zy#H6R^-KQE7T3Et1s|M}I!`o|;QMvr)gcl84qskvr{#4bUv{Rf;o0-SSD^ll=ccQx zL<{YoP)aZCkL9cOe>}_VTH>qZo~YOdrf=Ty5Ph;LeiZf_r+3s|2y0V1y-Q9zAhD)8 z+xpn$irv#!tk5bvqA&MDSIF^ecywO@H*aqa#q8_6w5i4-&-xqm4kWJX2;fu;KJNIf z#{c8n60tRY;Z9SpWpb}}Sk&gThWp4>LFb(-y;P^0WVz1xwdG^wdSSyeEj*`dTBr1J ztIeo8CUPxjOF4V)xof)`lPi{b%DI2hJ|E&AjJGjrn~^1=o%3w~iJ*K9Lx_VO!WV zrNe*K<$kRAo3b~pMk)B#<1WoN5repsGFna+KeC=#V`;qbjK?KNSP+2MbZa)gwUl00pn z%zOMxSHnPdsY+w9ssfkv62F5&-ku_M+qt=oip4YxJ@v{iN*a}X*Wo?a;nIhbfiAisoZrK{Jw$&v(j*p_8ao~Fvq=EA0hPqNzC0|r>(y`z6giD zR8U)~@%p30gN6>v#cFY-k&dRZhaNTYzAldGX8-P!by&Bc{?YagVPC3uT0D?+ z#Gj3ih~Hl4lH{uG%I=xhDf#rsw%6y4zb_A+WF8c++_bSOmiN(T?XC^@ikg;5mVsuX ztr1wYBDb%Tnz?psm?%b9;FE7ppD`spp7`+9x=+~4%~dHI>cU7}>$R4Lnrdc*Wv*Y( zb*jhNKPvxo`2J;4XVi0=ABZhjU|9Pt#JM&w^EGx_qvgpQT%gNl>vNx%FH<-tQowq0f8r)!-rzkN3?oWuD%;QFGH%4>K*!jtHpwcDOmS+ob9yk3}_WZ8JQ zd#zdHsn9S5T;2W*o4I)}4)ng#O>Dj$kRyKZ1}UuX>qoxV3m2G`Eqo;Ryxu9UEK0TT z+tP&rjgB96f&xEJLl+9E;SW>aO~zo9r(-ZmEEEdCUPOQ5h~l8cp)?GY1gLAnGF_G4YB2C-_P$Y|5mlJb!JNC zyWXs(LmR`-PA|@y8vf;N_nwt~WgiS{uKD&I_9C6*{3K3$H^hF93|G~%dEKpk&Nm*{X59R_$aH_`UeQYHqh}pe zuLdk#m{T5Q6X{)0=hnY-y~Me;R&xi7bUu8l*ufO*1NO!%+`s9|$9>+l!@Y3F)|UOY z?A)pe3UurI}+!{?K3Zy(0AIG zp_@>7Us+;J==Ny0Z_a_FB}Nxrx4pQL`8Ok2bMw3pp)W7|=Nr-2kRWz?ZCSR7cr4kZ zBXwFyy3zi{byF2@?>Y7J1U7%J(gl}z;lR~P5=vV{k7azFe^1(z$F6G6oJHY039hF5 z{Hk$r=d6U&vGdm5tT8k7ak;r|i`Sbp@(b?shs`G~UV8PB^|KG^?V4W6RW092n<)nB zldIZx`W|>LcKOZcYfmq{Ywr>k_7t3bePxmE3Td|1;`Cjb>jd9OlI+tt+eDSI4^wtUH( z^-Hl-VaW;81>({Y<_2d977DFv=1e>oJJoOP)nxMJ9?h$~_7?f+x*07hCpL4G&9BuPE94(E zE6K3yOXbjyn)3I0ifL5p&vl=1O9H;#jH{dUK;EuOI?eO(r&~Eowk>uklfCh9PF$6h z(o9vWCY72%*(G|HZl`Wa_Y}S}X|gNIY#KqdohykIKshrnV*diL(zaVOuFajZId^f6*0=zFi$vK@>N2 z?2}1MGVKWS&3HS*g0GURL24N}|6@U8Zi*VmV3#~*gs==ZJ`jU z!D?6EwlW=(>=l3Eqg$R7U7o8If2W4m!n*5svSCv(KRK-}I%$oVv)}pF3l|AD4_vV( zga@mOyQ?YBl-S_k8vHSHw%ZO#Nw>}Y#-7DZ%JOQFDu+9+TXSx5R3bFZ{qg>`t52K% z9D&6Ry_*gNO6U6~A3yb};ny|xKk8ClwSKAZmTQOTcY@Pdg*OMa_znsaOXC7{ob8$Iw-CkO1_hp>AjSQu)%SjSf zH)Yj@+OoG{N2WUdXFI*4ciS!@dFQgG`gK*2lh^#guVP!m9aX)?@wDdMWu{yuf3D5l zZOXMh?po&GU!1( z9}uze*7})#$84*W%6qx1r@oZ`T_0=Xo%rm>w8?_0w<3-R*!0IZh<}WFwx=Ph@lw|r z+M==0u~Dl+HGOFzEEd9S7>pbXi$)mHjqL62t4Ma+msG-YOG$WJpH@YqO>TL%a!#z> z$sNK9>d$&(ZZ18kc3D)QY2BPBH>*AdMwQ~iKTMOp%l3%yK419G(@P|N%R?bcw{jJ2 zy)M5)rgpZ8hJ+wn&QvSj2O{zw-<)`A?rm(m+|l3sTlOBWcjL6A1MxY|O`4W%OV=LD zonIHUtFu41=kDdZ&ZMM@>*ORuQ$4w!*}usB_%BlCT`PHPpUxv+Ufj-+#c$`@bkodW zmB0=)L~9<<58f|wXw-VEg4+w*X$;aQqBX@!MtZTEcfewb7Y{kaEdon32M>+mKu~}_ z!Zg%i^Nz6%j_@N=7SoLX_83Y3duw&*Lkq6a?2Z{X#o_SI%7uqLkv z%lkcDG=Az!(aXC&Ued1FCL*EB#h;P+++TjT`dmJ^9?fIoQ(rk^lPt|>S zsMe&VWwP99>Q&r^t<{hC6HP9)-&1!JFE*&du2@1S_<-Jt3l%KY-5WAEQ?i^#a&xaJbue_ITF z8&xJ%hzXqT$tsQTwqqAa@Jr}^qv@Y|0yP}&}`MiX1YpH9ZdpjwO&sQz#H(hH> z#97?%(Xn)O_DhJo6LUh~_V#kEmkKo{zN-jj(vejGpVsAkZJ3;BIOpqL4s-Edlh59V z66WN#%3XiA`gf;`t^Pu*OH&@S+AZ5A@>RC*3h%eteQ9@-Qe!ioytI56e#aux`tY!1lMJv{N9Z$7g<9v8g zQQfU+Z$0zOb~M~|F8a^@;$x5L9~;uN9_&l9-I0%L5w1}mUHamSkI8w8nMPf9&j=Q~IRZ?|8deLE?73!Rr>bl2btJX? zxZvbry}Q$qGdgXp?l-%yYb=SYL-%~CK77LAj>EC;52g;^)=D=`*S%W4zklKSp7KEc zqjy$co%0}GHhW7}ZK0G%*-nB>`+;-11OsyFfkFf4-%}q&Yen8lu->>TX!Ry8kLI#d zi)|7YzV<6~NUs%}Q{NL7R`cZct@{^t@M-gDCLWmN{TENxog+|%gYx`T;V;)Weo(qJS)M1Ia^Jy! zTCth*uo1mFWo3b^o6-B(fkYCiedD^>$_oT&d&L&A)MYg(=BXs6# zDQn&>Juif9ogu-Unp3jL?dE5vO@G;}&Dhw5G1Me1kue)Llpc{QY+D8!|KQbtrfG0C?s>NG(EuV_P z#LUKE#0F6?7z8IlogT+UpG1hDfiU+jz#43btMr5C4G3coZxD~|V=$v521*;C2IBm@ z0|SXK|%DjPsOLOnp3s zI3}*j5bS{7vkgbH-H_gcvJT){5QDu)grT{i1|Jv1u>F!c@*4=5UEt{2!}wVE%m1J7 z^#}xOe6SbIe`r)nFaCtQ1}bl$T7jZEW&SU!3{o-V6hy7%uV4QnOu}Hkg8OQsxY}(0 zg$w6L#FLpRweLqPDGP{rc`+Cr6j83@zYwh?2J0h%%v7r%8$YrI16d}7-x3sA#+r$c zu@vHp!vu&I<6T%JSUj4ixxYTWw~7OUF$6fYr=6ZKHjWfP2_}cQ2a}jiim&8``$TT| z_Q6~XMq^kFEd2G9Fi|xO!-?)8!6ULW^Mt58OoLb}HGowbYcdHkUa$S_&pTigcb1uFvhgl(ii0~t-WqIJxE>?_gGx3; zs2wOoTasT$us11ySpc3C4EQOc@dJ ztmH4Ti!2k3k-vE5ZYn(jbG0xi;`vYbcBEjuA1x8nQdhla>64RO7)&y3+t7ZRQp~a< zEcq!i*VG0ff!Tg*H1wg>nsGOjc>ag~b1=#ch~5Q5U<1WSISXidWFnrK1ycQ8b)}%h zSu~yA0&nh&FC*fL0mxeI$-IDicp@Dq2!H4Fr3P8mXr`;VK>o)FBI@XTYs%e1gGRf3)3yz#{f#ivhe7_GRca z!2fwd;7sSY`_;31$&i*8KvjvhP13jV(FZmQ-X0NSMA>nZud{Xn!5Sb~itzO#*Auc3N1F_|vqpQ4IqKqk%>`7Ny?`|NR1ZHVq83LToLu?v<>7X!m)0w`M4AnCC|O+n7lEL(FVqtFykA2PUA z^}MlBM@wM)&+u~30mNKDoQIk#XSwkanawe9vgMwlmv(O^K-+)qYiX8fskaC z80Otl~W1@t)n*@G+j|hbEyhNZcH_RiNbv#2-m@eh3g^1K`^?p)HM7f5`7O1 zs*%BlWVU^#Y#0-NJlw@XrP{?h5&FC4J8>Xqn_^IhLBtI8n!?p9ApF+WZ1?G~rJ|G79 zQ8Oyi5_;t-LPGS{{7q>%08VipIvR=V%cw|8>5=x#G}W;v+-{x#6PXVkzy=!@t}i** zhi29tmVjVn37|8NSb+o%yK1XMP!9%kk&TV+F4|rZ8UV@PpA_IiBp`P?he4?Rl?YNy zUtAe24W&BLq0${}Shy~qI%!A>g13hU5jOtr400Ijao{dUa{l}ahV_)DS0s7XFa$Ax zfaozo25NjX`UmMBp5^f;7plmU(BV{auwmg^x|{|ON(>+o2s9n2bySKq$f0; z4Py%(9bYL%!{d=PgiilZ&_DOx(;aVN5Yo}NBCG8=hV+NA$hk4~Om!H9DnMNn2d@71 zj`=5NV=xWiV#t4`HY{8^3Bw>h$TG&v1iLh%bu~X)cdaeNU>wiT-=Hmz8AkAhd)9a| ziR41@htx%{P1sfmoad$uTeaZ`3F(k*1{)Txj>?mVv_X#BT@c3#L~hU0sq^0{30z5g z@B0Ki2Gb55eYg1jW9BG~K?l>CQZ~7V44!rlI@-Y#Ri+FH6F~HY9Y!dFW3>T*#6t7a zao`ha41S@YO#>hWL=wp)dOg0fZPFKCa>O2~<2FO5-RMQE(Plh6o-|^YLuU&S{$PDB zo~~)HKze%sKr7*DKa3Fw%U>|EkE8?81to-Zr+tqE1+G9x1NeK70HAm?v%*;$e(m>Z z9y@O0pwu^@kB%83!vK_lrw16a`8vT!{i1!(*~`HzpF>9rz+FrmkKCVtEeE{@{F!oFDSIbJf2tS&7(Agm?NZZJ7?P$;Ui8d? z6oqtT@uM~@T#BSPhkOY>7!GF=baNoju}Oa$FaKp>h|NyuXotou9v&U$J@CAOOF)Rf z8<9+d85BZ>tpBS>X?H&xJYN7E&WHya7OrL%G?)<*P>05Y{Ph0-*O=YIw+O&9L_BbNvk4Q%+xR{XP z(JuOAe1N-`p+77(ik{vcBOl8_KnQv1wkrSt>1dEo3?MehhuoQg98g#{OBVo;jt)n+ zPFC;`o+$>MFw~TdXe2kq<^(UyqZ)K{R9J`6gmDWA4o0># zOiWVJrsy6DQXm~&BqfE@00y3YU^aYp7*1*v3`IJ6QdJ^o!;MM)MA~So^b0hy^y*fw zUndFsDOKp`Jl{BCH0;HFV9|0hCwY=+C^Xkdujfh02Y#fZWl-KilL2{%hBlfigAa~h zJMgZ3j1*Y!By>1L8Eja%@kW(FU0J_j&i>2`r!vpaF z1iTyEw?RWtHgMujJe^(-TXu{)JG~H6Ni+z5VnB!s0UwN~L&%6~*IMH}NyQI}@?6jt z9RjP9=@2LbzmPDDK{X)#gU7Uoun+_G@1bEZ{;d zLTx(u>>9NUD7eW`!C+vkNOyP;$P%7ADZsyFgLM@Qk$Mmw`lDAt78rcr zR~aGTpTi4*T4u*Ali{ul8F%v zB$_~?(2Gw)OvGrWwh53}7})zkei^|a447OP17L{UnLQnuWkdz!N^MxU_+_!KhJ`mF zU|<2Ip9v?R(8;y0XFe0(CqQ9ifG7Jhs8C|vs3o_pOp*cuCqhT75T4DN3UD-sB@1_gn}+4s06w|AbfMxvI{^U3syo3H)_MeCE(Zu2$;qM zl|>&|;&DZ}@xW36YM?C@eqsVFqXk6@P=xY#-AVFH$8eqHH*#$&v3R4^o%YTSc^JPQ4kqRg0b&ruyz^rr zny<7rS1>oh8Cu#Jj>J3-n0$wNo|7Q9=7C?r3EyDD!nLzxEKCa%J2WJ9fgHOGIaD?l zB(*+5mm$b6O|`|Ge&Yj1%!lw-9+GfC?FN?cC|-IY!6ZKtEGOjQ>Wk`Z2z;gRxphXc z3H=HOUg*VYZ#gUCQoQuZA;1v`5BpPp1d9ntiZZ(pADDPE)T^-Z9&A{+E`Bl*65AzA zz_C9fb0xqyLU16VG=x21pv31B0Efr8y_leHdiE|p8qQn1Kw5OHd~cipIy@ChFbbg{ z`+0O7j?4kJY~IwHuy;5L(}Fh7z4sI02&CU9R7P>*R6?{%_k-<|z(vv3&a-b50k`$S zlj-ph;b;03yqE#=xYxyz|-VzAV!ppF84R5X(_Xb13H0YfM zM87~UZzlMW1w1p}LY9&S4z%x_oH7x7I8SDRzC(4Ix2kQ0N)fJO22nR9LM&J zh+Z$CmjXIk`e=~}q8qJdB7K_{2TwiZ_8_o6x~Qp~IT8F(vzm5R|8HMNJYJ9<(B|ou zm;iw_k?hAr{QZH=Iz4cQEQ%p19G^20bT4K>n~__TLk7R^2K%5Fl}@>dfcxRSnI$y! z7Rn7P~bU5vw z8T%I8b0>rIOQ=r(-v(Z~W+MH)C;nEpAo+SYeMI|?wblgCZQenrGZ7~E@dWn!yntU1bBIpR{dKJ44;+XvLC0R%a6kgkWxzP-lM0)c zETfM&4PinN_j~gn#6WeR0J^-o*~~J<&`}5z{FI_sF32sL4!}p3S90%I#~(TeVM4G} zE@mGW5VSGOK>A0P38;r4bm#>dIK6H=n_U@D{dB<^h8F)5{FK$WVM_5roea_uApW0p zR8uk^2o5t8=dXGvKrm_mq#GYrF9G}rs6NpOJo~{q{umM9vX~+h1q8^x8eK%R|C#{7 zXd$4(QRue^;9UV8T_c|R%R2nnG4S7cVWTAA;AfcRbarl*CwYt@z(tpOZU=&SK(G{* zox>(ifMAR$SpKr@V+=4zGt7b&7wZgkVL&Ya=vOQ3umZ?xg`GMUJoQ)2smEzlv{?tA zYkf-S4TOSr;FkLQVKglKwVnkuMRKS=*?lA?y@U&fF%b!iS-^Bd4yWjzD12ttqE)@r ze!*5){oV-DJNMrSpi+?X8~IG}$a6*H6Ue{KmsuW!ReLqaiB7(?0^^%?Q0Ng~IvmR= zG(#gsxh^_BzB_yg0e#S@rq`ksw6O7e92-1W1Kx)AWsDfBm`X~@E^c^=w>yJXwi&l* zX(+TtBDWb_!0_mhM^2DN&$(1*qe`u$q~bDY9|jJiqm5cSzHVQOXmJO$KyJWM8x}4n zXR*$)#Dy|&yV@lfKk&g1)CAiDjq}YCVPT-4z$BwzvyGEroo1;^2-(ji5KpEIepm#> z;|4rG%mhTzK%FMwLf<&~CdoRFs!IUL#S@JPU_C~OK8Eja% zHep$3Sq7RATn3)Tqds%Q7#k5l7WbTgvOJI(!FC3H;%p(qI+>b_JG^L*NAB^`YcvN) zqUsY{;xh2aB!2iUbksy`0m3_9F~uT4_!v6c?>5P@PN?qU zfxNIdU_=JJ;(#V(&7?)aKoJcFMALLGV4X$-9+!mF z8|?%(^9L$)tR^V2PNU*7@OcNa3&oqjXf&U^MlCaoo^{T^lgq%fT!nR>B`(N>4CWsO zv&nCIt!2HurEdmsT!!Kpy?N+b!aC1V7eDH$0R8+sLGilzCtu8cP-Q8E54!eqT*d;$ zz%$xDl)(jT=tP5g)gdz+oyhVPs6IZt4|?rFLmC|emkntSeRxfk;}&f_}H<9vQkU+W?@J2eRj$;G>O)Qw0; zNVmbC6%`pcb0i&jAAE@TXqfq^c{$knJoa$EYV!Dr1BtP%&sFKGw|t$hN=ZmcUzL=W zzb-9*L+YxCq=bY7^JsuOm`3SyS5Jd-oQj+7CdIq-sdwPig{ODSy-7&uzMuV({_rTV z2Pe-t-O{^7LQ;`Pb7V_FLQ4AKuKFz#|3CN!%FN3eTbS`I@=q=NcUaUJ?x`F4-#1|< zKQ9%_*CBd0Ohfe?qlr{Z?Ccf(J5shJt)h;qhU#fTY|k99M>j0o21ehY=kZr|_D=Dr zm4>7mKRG;3n z6YeWbkwMylKc^ZK7$T&rq)ufq8LZhaUhH({HTL(;{)kXmYEt1mc*%9Nl8jq?`!QH> z*U8?IAtEtHDMWcy@mP0}SB!Uc@|{|XO<8B|qs9Sx%+@dQZ5so$zkFq}=j3eDc9)Oc z`t!on1*2ZZh}40U#5|>2wDSv}PG?E&BpR2ApS4conmQ+Xk!$&sry+Ry5DmtNQ^jD} z8%i%&5%T-n*tDu9Vkn|#O{pT0waXXl>o0RWnd?0B_#ER}HeRpzhKEw|#YkRDLbTK8 zU>{q-pKc3FLHMDQ@r)hfJ7kw^V z&q+nkbwz)LGGn|eWkTMvjU*!t6e9LLJS2~&{IA#Szs@m(j~7 zn;~y&35bQNoj2xBUMa*f$Zi4@i>RGLq+E0gx!y@yrjvlt}f+HF6;W$A?{S< zQhoK|d=B@tlhn!T-Ai9|_m_^!1aba>CxWPr$rsiQH*LnRaw+a?vGuz7v(TSxkMxd; zEw&pxYBebLwaENtKzm_+k8RK3N#*faPyFG{8^LcK0yX8C5X9|d1?#Veb<(3M$_E%e2$_DHW#BW7v7GL;}efCiC#E(p6I$2oG;kA&6m43SiD}>#UL~cdTxz_L3O7M_?RH(}%T-Q)CNs%pl1TynpxFpZBdb0E)kZ)xKrE*I;! zFk6?HD;ITc3peWTvIXBoe(RmZWN;9AFr3vFL*Dwn!ubw~yY7G9Yp?gSUc<&B+iYF6 zbaC?0PK1gPrV&Kl#1DMK;Y^WxXV50EIMMcTqv@rM$tQ<3GFjMIYaNc=`fgLNqvhM- z`$}st@rlFlSZzO_yFSneI4nh&RH}g(@ zWg+W3eFL68tjeQ1i96>FV`AB}LO%kr zK~(eJB(%M!H|w-%AKFgWB#WcK{`0#7e#?&-u?0)wJefp5?4xb63E_B#xU&=C!LxN& z6|S%?)LpInMFCocqrWqePcbx=-?_QZR?%wvziY9c4LLUhR)H9k{2jiL3>I6b{Gapx zt&ZmfmyU!|{cX=~W6D5+$aT}Mg$n6G@tR$l_~uP3P22azXOU6khARnHTR}KahX}Gh zirGojP-dNil~pCrk(`lHsT;pbk3BvZ63`+psL8Q+s%EN|5B#DF5m6ql$fN#Npe+a(BKH#Tr^m@Mc-?|%io&d!TDpV@cKf7P5^-l1t@Ht~6^Qe)gXY5_Ax$KKg_ zVv3XZ>aH?vvo@@>xiB|LZhEoIs#bH{#kaL_u%U7-+<+y@Ny7wcb@xIp`tiYIzap%j zUTdR?IC5whhxt>BT-dqnBGOcjJRKgbn^-zl72gn_i_K8TdR4u-H3Wa)%JB52nct0~ zg-zudg+vItrL_%q9}{@0LH^JRce`(nh`sdDQAM$0t7WmBm6);EzIY1r^&Y{FKOA)D zVr2P;Qtih4OTPl@1(9>7&5^G6N^k99mDq>A%G{KCKo{krTizD@lSL%hFeB-nvh{gU z{SOu!ZO!}ColWN0p-j!wy7Iu<<=YttH(2jP}7=xLTn@%NwT; z?ps(ZaT9 zvFDOq0o3t@!Ij)3XchWK`S^7yMX5=8s-euDJ->Hm`Qg7J3m&(Z8dzBz{IR2my>K73s9nkQ2(9(Txhv(oW;{MkmFX4Yq@C<2UR_vo~XY2I+ zSpOa-!~fTbv%XyvI+IwI3R|@MJ1}73e}@0>nGp2f%lk-f!UPp)armWz-maWDH=Q#Lyr#cx{$WF9+=iJ&s&;x6c6S>kapY-g)|1PKE zv)mish;ijri2FuNNac*03~K0H`J9Do()42uC)C`pT}_sI^6wQIH^p*Te5#U<^PzHx z^7}=@NjKD<*hA1HIGrCaa%&xK-u7b++u#K6zG;uilRr0L#r*GWZaG*c&MEy}BgA_y zi|ge;4_N$cB!Fk4Rh3D+)6KZbWY{7ZLj1~o|NY_1R9IVL`(Bc$3Z7CH%VF?Dxn$^< zk;e3R)8ltaR!hoXvFjq84}8vVMcPkihl#CxerMY7MLH9iULhiAA_i;d(2LJ*LUaW= zdAc0zuf?P9h0C~)Z?~2iM1SUrO@hUhhfLf=ZgmNdTd7j~JkggBq0$ebf_f>b&_;K5+giuB}0+DGRedyLa4};3^l(RKKuDQE9L!m7Cu= z!AqHIsp$Nm++5O7vS%{Y$zU&gVrFh_AeKdFmR4V12^Z{Albje=b}zqL8qm(q!=daK zE*|dIHr7aI8iW;RC>l3Dj8G^qCD6{#ytpX6Y+8bwKA;q8;;8Yk+WG#TwENI7Tx9~| zyP6^L!}m%Acx>*|-%5{<7fl0oQE@R(&vVQA5uZ~WJMO;95tkokI~u8#j##*8g>&^i zDLLw~(cgU_{l}-iSZA*D+P(0@UVX%DI-Sge(mC3Bv|^)O*NwUIy2dqFkBzeIKgCK% z+MkUA{y;WJ*FHIN|F&~(S|nz&&a2~Uy%F!)rKHVGm}$KABpJIj;L9P<;;qcnJJmG7 z9UZ!eZL<-Ll$2&EsgkD0k0B@D9xFrybnS0JHoql;Cll;4P!Qf}sVYw}%b1*0_<)te zqFU0aqo7BjM+n47q!X`nG3B3^NrNWoxjmSP;|`A?BY>b(QCsVMxAFf;f*U~*y9{B zMS4UCV}#OM_HbjV9>vej>*!oM%=cFf14=OMw);<)o5?gTscZ?2FuBi+5cu-+*%9JP zeWdoYm)E>*oHu&zl#RU8PH}GLO4v3jT?_s6QUprvi#BGP%SuO80S?0hty3anQZPv}B==ytU>&LA=d6pr;M&n6l}_O;U~ zZqQu~A~9Ayxm65xN)i8nW5je0u@*x`7gpFLR(+`_5ql`SXre*MHDAB4pJp#tocyD~ za@EX=aivL$%HKsb$mw8GT%tQpjkG$B>AO?cMdz=XZcRUjF2qz*h+GZr`W=2*6(V-e zp2*9~Zs6*O2)X~R>eRYVgOs!kMYfpbI%e_?;V`;Ys-466TYHd#;rR-WD#^CBEMf1>WZ-al({Z0^Vr^7~+^T$G!*nLlJdRhLRKcexHEQ!tH z6PdGtF$u$CozM9?VVPu)D=R{(&QulUBm1Pf~QudseK=6H8*GS!i_pj3&T1kcHybO^GM_ztPCp5mE=?)IC zvmrw`VOZjHC^Jm`IL9dc1-&zGU5ZP{wSS=@)m$aGOh_x!@>KoF z%y3(wbFOQKnSs*2>m#b9@rQbgY#o=wo18hX`C#gAq!G9LSV+c%?K8HTSs%-opEG8^ zmRW88)V-YYhM6dvP}9+YLXMAswaLkEGq}QAGm3j?aamlRxfG8gAHqf?4li+X`kH3p zPz#6j*&bue#!G|};?i9z7>cf&#BeZ!@BZ(5b2`}@{RTtNvtq?_HE-hT#>R_%`uZi; zH1#~NGYA8@tXFI=6H=8zc~OxP{6o1#BnyWx3kMlkjIJV|8AB$6!b-lb?ZLG`Y}O^! zE=c!>lie3D)n9UgXcZMcyv}H-Z_y%ap)*xe>`=%lAMnXea&L=!>dn-B z9h1YE^;~NH@tn zNR7Rj3}*L|$h+X57j>n}GHcN8TMcxg_@5}t_=?p(sDIY3B%iQJzV@#S_!gw(v7{W> z>U4V`{zOAvB*}QJFy=3@rnM=haPJN-+V+h<*qGtRk4i zU?UCeoJ5%VEwA%kQ}C75+I~XK_xynFS~FuX<>gwdomJjvgadLdDjYbPogU_vZI;^< z@6*8D((vg6cnjO6OkhY@Jj1^oPLpiHPrCOY42AJ#6VSY@&G0O!CWgbeVq;vE!VL{Z z#Xxh5LUsL!kZgigaj2!!kNvgB)Iv?Srh_KiYytEJNx0p;zH9Sa)^0TPra<5D8Hj$A zY4dOR!%iNDs8P~(nXUUM`OV*Rl#Bnf=d5);3iOuz+pHQI@oKp>NNQq610T5|WOm!G zq8AfW{t(@_0w0 z8I&c-$=kzevf4*~Oy;? zI;4KZu#W-^@M+Q`V@{ZaB~s%y%CrDBj}#a}vhIfVz{grmrxY|GP4Hr<6fVbDb@=b_ zjq4O{U`MhwzQX)zr)?3jcby{125f91JbyPCN6SO;ie&@O;;QdB!E=5ko|aeD>0hO- zoN*H)J0{*=#5+03QIV%oYfE(2KFw)bA4r&zhWkir6s^uLkv$X%St*Y@9|4 zKA;9BRuF&o!>TT2_&nU+oHxyeVni28Bg<&O&rew$7V4TNOoIN_BASuJjO44UF5UAFhm%bIZ-#AoHG`}n|gq|+c5QbK|$9Y_tBQ1P{vxw;mhr73!=PkvMtvKE5E$ z{nAt8x%Qg#VSB1)CTqs!Yd6Y|v)`b`j+5hH%jNlqk1;mdgj%Yi>l3j~$edvRO;X{D zPmh?M(UUFVyvB_Z>is+m+z|s(y z_ACafnh*Wi!OMF%z5zM0+wwO$kGO6phyepkoQgDhmp<1|yx0L(@Zu73;?W19TnFE( z5cZNO1wT=D^QBWdeVO@(KQt=>fL^!xb46W82Dbkxma4kK*3sVO?{d7}BA`axzh|_1 z7qZc(xODp^8SZ#D`1AD8HAv$aXDl7^!J5QtWogXTx!DH6{9K*wHxBrI-gY9pw&zCc z$QNxD11otT{&v+2y4}~$04;lwepX(gbzOB3n{)C__kGnRUs5<}KK;i#;REZceH4ug_lii| z{jdIoLdSaj@8oh98oB;7%r>;@$cuk!pjF?Ef5XZZBM;c^w^S&Rndr9%=MFxc8q~5X ztY@a;KKU?a`|W@;0CP9DjG6mkGGj6Q$F*scqWWtaW@Lh9lh8?hloX6((B+<}a>(pT zFI$8|rF4eMr*OluD=+3SQ9{bqxB4~U8yY@_60s}!HiN0quk;_KV4g^ubdG|rDiWRX zhOtnx0*?7ouFBtS$V?YTYxUB5D@5zEAr7{Oxp zmJo-qxWivkj(1{`2{&N?HT6h&aq%?vSQ z7gL~LQRVqGMhCxqZ)tPq`kYZ)JC1#Kkzm%d=C_Yzy0V*cb)5O7{Pn*GtW3d-;eAUF zgUk-yk;gH@d@#IF3_xr&7kMUGu8(0+D8b(8WO!`upAlS6t8r^|`Wp>-Ha~TUbtq?R zt7-PNijr==gGmi}!!z0$C3|1n(BfV6^kt>i=$m)Y3^2r$$#ab-viI!_v&vAQcf$nB z^bPgrXF7@1-~*o~)Sp;-G4CCl7-RlrvSRIQvZwD`@^5Cp-+BwztxPFiHOV+G5}vd3@dhGTKlYC4birxCd0 zAGrkjkO&~Km{A!&+-SKL+Rr1*(wxT9LEFiS*$ zy|y-swTY%il$-@$Bvc>i$8sdh5DIOPiO5qzzL9C$N4unV@0m7Qym)G$5(~{Hpm4D4 z+~na}Lr5{I+~4qgYpcv}=RdnY;MVx{JiI8Y1DmAwWl=V6Y@>cN!9N z?V>*dUN|=kTk&hNRqn)kkA>((XwQ|>xy}hFJj!?wkS5@|(I=E=*p+ItxVf`t!1c-p zx0I%qhClX1I8|-HR~0sB_%r)epizP_buOV^HcPM2e^>>gBVp@K++X-4MaRY^uZ1Yg zy*am0E7WAiQ2Z^-xULr3$cepmA^oFic7(NtHQ{8lC{{+Hqvwa1=@Fq$3CH&~`|YAp zt;t)Kn(8M((OG!iSH@|mYrmZz9`uFh*6gh3;6?qPF36lqZ1~e?*q}LL@B)*EJroU@~{wn`$^J82{w_Y~B#ikyq*^yg?)THy< zecav@_o4I0sLK8mLV07{A357OqM9Hl0tdurbmGW~WMJ=4`UgjdZ%yzGDk0wOM#|ST z6M&AkU{zARXK4r~?7v*2-_B>@dsH~9}IdznZ3%)?Ff7c)Yr1w(m^q~x?c_p1M9IoBJc0Y_2kI(Bf zUKM8jG((KTN~WT9S<$w{9<@ULgkr|DO4_93Hujyey8N5o`#PV-6zF>di~-RTy({AD zSI_s6nQbGb+Nifx$L(iya}9MG{oL5KB$c!({cA`er@J67PtW<$2EP!Y)!+Th{V`|6 zmc{y$y`#gIywP`as~^imVXdqm2C=~-8e=;OI{jWboVaWECL)#*Q+bw7^s11;r*9BK zh*DK|t_AKloy}|UCvfW>uc7#+pY?6vYAa613miN~-w$u#AJLw#q<2-SH?x$?KjV2N zZA6rS0lIzb6>>wRcCw=)UdvR>A(t%d;;HExHTGp`hlzJ%3x@Bq=ydR~JWH~G@$oCw zgAY4P(c4?gBhOAkp75KUpqobsKSwTOLQFr!l;f0^cv6p>A3xLhuv+`)OGrjX$kg@Q zw;_J7>b$A~j>`zI4@yyr$Ll+F;TrbGWsOs4kYFiSJW6?TTxKIl0&`n|bE58?)@_M4qpH4mVzmVAlC!>TVslB*2fLLj<&n&@GOVC6JQi}SVa8LVFRS|P&Sg6 zC|1?Xc%-a9rC?>(zn_qnxeas%hs7%!g{Wja#6WGP?%xlEiJeS1%&n$NUMtBcsu>Qn zTp&hhvym?Hc%Kt@5JG5i&5i6QWJob%W{g$OH15Cr{iBRPqVr}UO}GFcsutZq0zE)G_r5NREgn+T--8oKHCkab_0OFnwvWHl6cjOtl#H;Cy z%%yTZsI-=k&ptR@Djc}^?_tneru#xr4C%@=zAWOxU7wBa4aznE_9czQ+4SCiO6OnG zoH`#NVxX9#g5!`u+y0c`S=7$n`?sY4Q0KaBog@ZvK@$@f|EbGI6$_Iz^_2bi_G|Vo zBt%O8`o0-*k8f$YMytgf^X{)CYX}G+Z`dfQ4^m*@ z&&x(`X0Xaq8Sd^YM4?UzS(K(nBhtZp)aM=xBib^V(!*J9Z(u)dsQ<_S^5y+V z`tLvZ`w)IYMH0vFLLD`4X>$E_ZgT=#PZ*=2Qm*{WYK6nDG8jnzCz! zS<&^EvGNLUJA6iSpAen|!`BL=hj%TN=I>MDT94V?`_HS5vCk++%3Y}SZ;U#e>S$8D zTv0K6!p0w@*rAx&e@e$s!-c;K(ayUuro=49Ed6Gyg+uRPpF70#xj{Dz^gu|+`8%n2xg zWisQ?5}G_=t6~xgJ)X>P0YkmFiXvUx_(mi|gW$GF6$5;p1HgTYvtA{REGG4H)LItn8n zXkAhhF(A!dtq{VAr!)+-#H>@zZ&E%$Jkq=w!afy5f{qbZ?b9$3Kh{Wf-$$M6R4CDh zA@~$JX~uw1`juX+6Xtb0rDU(|>fN*sy3_FWaYtL1*_aB-?`@2a9)+$3-T+&7#7Ipd z17@W`GS}ypZ2q3jRYb(JzXA>G+8vL$?&$QFH!sEAt@c%7 zPb~r5Et&8&@?A4yVV(X0RsZH&>vFJxPbPe6BLP4ROU(6=^lBM~IsMI3YGQclpC06+ zfN&Mu1#+{eF??MC3>K36ETP1t6j^|xmd{Q6XS zqxPqdD}5y>KzYNO#<4pke2gC2hAA;BugdxQKmv^#m($DNdBszi4C>voZ&`_GkQciI zuvp9*0KL|h(o#MUC9)p;m+I`%+S)3i0jluRbI9w~Q&elyr6AF{i@MO!4d?bXlnpl^ zjU-TEHFnS8a-bL~9QiMbmt;V37B{#0^^8))xtaU3q0fc$SaXt(Ni89MZC+wuvoEUV zUwF<$3;EGYSrfb-{{nAUSXg{LXSg0Y@J3^^^^%?}@NTK8-G0teBoWi})E>~__e{>F&9=yqGr2F-29COLU|a9>-f3h&csIuxIP%!j%MM8h z!4i2g`{S<(@U8XIk#qgIW?Z6+m6~(2Z%ku&{13hynu~CjmXbc-9h|>%ipFeih)`kY z@Hsk4TiZq{DDl%2k^ArQ@uq`&g)|P-R4^e}bCYIj@g%t*(t5q@)ZU5o!x)@%qG9#d zmp?DceKo0-gzjAa#Czc4rJdmKySSy7=ewJ_v2(b77-bObE!9W3E;plI`aGU4_m5h& z#O31IE6IjSiM^{QJvAOimWbA5;o|P{c{Yw>-G`?LleEK9z_aYm8~IGF>^Y6`m_bw7Pw%mSb8~*@NS^c-ctrU zhg++IDn4Q`2)G&Ux?y?fX_?WtI%XgJOmwueWbb1Gh>B|LN|GVtTkn?M<@&tQC4ECP zCw>01UT$~*SFW|3o$kQGnd(onc3=BJ2)b|mxvPMD#?dqzL+k}X#5kj#>^?-;`V_j< z_+jWnbZ@pw1m%`T!NLTW()(2*e??mEAHCUUsZklVMl0f4J?>;If)Z7yqv@Oz6}jB6 zPxF01YJ#|_=X87WL0Ug|$B(of<5$D}pZ3I*G|O36%c1MFXCZ%z?K0QE%E_~|GzKRL z>k>zYsJ$m+g3`QQ?`W*kng$|{KJ}b;GC+UIcA#*Q?={BL` z*aEvqV{^p5l27X6Ziq5QR!T8tlPbnP zDtm2OXCyMYn55-bUyI_hRKrNuGY2JL>H8ggjZ5oy3?py-iEgCb+zii*qg$?dxr@>$ znciUWGY_%N9g$_cCC5p$H5763o5eXl^D-M_fJOJHeD88U{*M46z@2v9p3o@osry56 z%GP%Ml_c?U8>zi@#`?pP#iMRlnP8XJ^-X>e<{s3gm0ioI=BRbW?bkej0 zDsgm7AXJ65UXi{}!)$VsgsUwz;v5Z*m8#7*c?G|YR(C{3Kez1lU2ZOvSD=ro^X2;| zzo+LkgFBu33Vl@nHI@4z5B%RpLXWEV4K{jLGNAcAP@`^S3ybJs+xn%+Cc7aI9p7DM zs(01}CtpW?WQdpy?=HsUImqA5kC5atNKy!)!T+X&hSz}993uZp$XIo;xzESxqe4)Z z-q+HHYWiIBII44NU9E731yY0j%7|D&Lu}Ec4#_iMt$NxS;jNyeB+nzSAbW1A4igdk zR9!&fh^7ZV-po98X4n$!fg7NO&Ln4MZ||e&2UnV&!nQe0fZD9j*#mc=ybPjNM69>E z=eh6uWsBik`NB&Hq zYHR#!v71hQg-lzz`po(2GdX20Zsm$$d+sH-`8psTw=)6{iyNZGJd+*d`8cEE2>|5( zD$s~0k*m`;1C{>xRP3|?Ib)^i)5iF3jz=>wV6`^Jf{}uFf+oxju~&#XI|0u+ixdFf zXX?6F`r6>5%%7I>39ot35}V-YwpQvBYF6J1;I5(-q&GO1So%|Ae3X{&sy{^eoP`J{ z%lVjOyj;_@Gu=3n7g$(8M$aPi8bT(8GwSSBT^;uYG#$dU1d*AZE?o(SD_ukUs9OO7 z3M>(H0I``j236hzSBK<)N4SON^2N+RG1RzZ;n!Q7@QtDU1OrkS#KI%a5Tcn&_7&=L zeaV=luN972xUeQFgG)_SV?~pS2{IC#OjD?&FI`CA$LtY9IKb;7*U}d-@5sG`cut7i zyzKWdlRDuO1IWSIV-&=69WcDWoO1Tx=`nrPaV6~Kb4nD7Lm*3<)yKALby|ejGxImv zY=rowXYu;0D0FrwdoPyGo4I2Y^zJ%fg8C`SE@{8tPmJkyQ5^aPKcUPclft3q#Fu?G zUhM0?B&&q_j}+ve{R(5jJ$D#?dxvU7?ETn;5A@KpxWk6`PQucLc}_Mk$E$~>KL@+= zddEv=I-W@{A&eT$kEiXZ6IQRcVIQ`r?B)G1h<|u8n-x4V+78upeBju*lvrI?1$N;g z_a1KaWOw^}ZOnN8=`PIlO9*hiZKk`eG=ftD;*RM=T)Z*6wJ)-ul;C$Bd9bn|j=Zi^ z(P69(3tynW5-NACuXS(MdVxMi(d;vR&Ie)*X#Y9m1FU&Z<)5WqI<qEu*qE~BWUGJp4uq8Np0vj$sv9)z16->MYE7v%!BN$)xKlui5KCu_! z7O?QPb>`0S+?T1|tW3=Q%qZCGT#8WnQ?WGu(L=GuOGvOt+U)uxLretE_e~|-S|lTV z;)RQzGVxaa8k+WQ{{BSZga%P~aMpOifThQ@1$*VZ7Tv`QV#d{qYt@tyg0_cEt8*x8 z{hEb29Ljq2IF@ODb%L;nW_a?<7VKWHykru!6Phns059Dlfhp zw6-v-AjwS4_c}#;?xOx!YJ7XV=#f?;bXjq)mQwQ~ zY;v+r$kFhX?vzE1*_+>p{pReZPwS#)SG{g$T;PQGDf=%oFlDEu4EjH;>Pt+38eZ>N zQp++vx)_k(8rq5zJ)U&xBAC?sFD`3CCeXKiHX7>mBkVRdc&(9i^#55B&%8Y+-=@p* z`j0?JNDHwtbSlm)0Nabri7lOlY`>66e9Igx{R6&Ya2LoEL6g%f+mw!SzJ6#G3G1%@ zU}y7P>K@Qj08KlA`&&#bKbsS&gK|s!Xo7>4h`)Yn4u9Emb#3|wfss89dpSGp8r1lO zi57}chp}#b0LzwTq_@bh?NqW%{@0|G(K=TKpA57fZDMYO{EM)Y^W#K!~qQdEoC9B7O zw0G5Sv~|F1d-MURe*|Rm>CCo0*HItO1M*J7EwNXP?XghcT;VhUg1ftYJb>km)_o|@ z@evs-KuS^16oh4iAG7mjGBBPz1vH-gZoaM`E65mLbOyP`^Vd_<8z{-A>VUcICT1nU zh6;DN62&WBhkFM^^L3bj0`1?R;N=N+17OkwD*!{V8wlCB4%GAiGLM#!w>=4mzbeP> zn?3_J3NTE@5-8??>|;jbJ^+EHmiUJV^dTO^2>hNWEX@Sq&P%c;wbVv?r+_fvvEX|S zl7Rr_UB#q8-tnQmZvMx*o_09znIuvZpv1oK&Q~WZCB2`+-oW*L+>aLYQ5(}=z}5i- zhrn$ht`LAxGB+xc@MVG(>=zm&f&30Ki$GBSV<5dbUi5ds*+o{)5|T2N4~PkM#AQUy zzu_gmV#!YTvmh+)@4EuRr_GtbqnjU(mjImq!Aor>Pa0$X=l;0rX85x+^!*F(jNnyO zjfE5g?Efp^2%QCmG!(~@lM_2GImE9VErh5^1~wLF(7|;XGXqNmoZlmEO|283!$ghq z{MWCjHl;ApTehBKXD>$7_XNnB@NazK@`WXVcLkg{O=`wK2q$xmYytT_Oa8p$`X!>I z2)32DG1>EmBkE$%qFnlA?dwys*cJs{+i&;D^on|*WrN#;Vctx6LF?Ei*XXPE5OSzO z2s;qia~A+Ly;OH7Lc^=`PKd9p78nCrvRdIOu{yAFWG4)xdfZPbprSTqkTQ-?SUn+shkym7- zua|UxRxFqj4g6TX{md~Y?r>YfQ*s=TcXPGn_xrPqqsI3Nr8CQM9%c7Vcglwi|2!it zPz+YL*86I-U+-)64sopfW#$>9M?5>WP0ufVe2YdzyBGy*Sf(Bpdp1fk*q1)taveRD zBLoVX*1S9L)SNm0e53ZBN{DzJ-RhO<$&C_c_zIh%5Bb)Z+_zWMxmKRb&E!N$YcrL{ z>*Eogl~wqiL;UVQP&Yn3HyQXtqJ4P^YKgIhhGk00l-lp7YK*CxCokl5#XVcfS*Xqn zOU-d8$3>4zyEVV^v<%dKzjXHW_j08tn^f;>tJJlVzs-Z4Gp_vMi{1XNAl@jKEK9*^ z4k>q@-bn0Sk}h4P#Q{5$MXfl|r$fBh?{i&&7}t3jP8Ck#JZd#hFTk0}ef=1_CSDXQ z#apqIw7tzR4Hs4{o42(5=9SWW1=Ifz)Z%L9C)P#=+TvT5&%ce(I!Ho?W#gVUG*?D` zWsP>A@$@7u&${FG+oK&_oD>~m`^`(rAN?${nEn;Pe{rw*v3*fZ=E+mw&W>$M2g(Tc z>M~hC(aLSh?EsLQ`PMN@ZaiGS{;>Jy`aQf3?Zmt5U%t0=#Zeg;f2(E9C??quxDfta z=5CVwPra1l7l&=-xVy?ZCUuC_p;4=qkwR`RS~yz5J0h&e$Ir1H(O;@xpP-6Av)%`u z_K{~H4<=uAmVaplB28y(I`u{RyoP`tr6IzX4bFDu!l9(~b%uGVDdtwuPabW0vKmSm zlnUS@nK9gx`=Ox|WsTWcX3ui?C|uy+7nyTRNU>&e2MCA0H@=N z7!j*t%bYNsysrhroL_wNORBc`WP_c_f6d*#*{nwRF!ZT69J5niVl7ehdjGmtyVV!7 z$NA7BQ*X}aXcA|T%iVbM!WW=1O8A=xwEUWN!)ZRLSh zi1n`>gcm4KYic6m|Kxy2-&1g9z=#0C56UWTK|)*;&jN*pEK?}d?gATo>;?dOLrB1d zr9lm=+kyR{sw1CfjsAl!DKM1;0mybc)4>bsq?+Nu)K`IFJYKYSTFG(v%-2Rt8onZ!h0b-PE z7RW>2BPM(m0XfgVS`P>~NE^pjWSTJM%I|;o3zrnHQ$!E~ydnqp6a1By0iPdFS1eex+)w@}_a<&@^?aZAn6D0y}A5H+%Te&l9i$Z@<{9O@j5NHHm z9nICLq&Lzi!!~C&VD#f->HT8cJ7pd$jg3N>r;4}zB*~mC8c!kKJ_PhY3tw#(M*p91oAycIe+yn2*|5Hr6wb_Q#hdsT906eSFk? zn#c^dO^gqU2BiBbySS2GB;WWnboCitdlw`Z@+qJ956|C)7${fg9);0gQIXgkst}FS z!@Kc=ga;|qz&JFYhQ|3UlqkJ@Md@)cm9y>5if#2L0BIxlZPqn-6f(C}tilT@?-b)7AN`B^3 zDcjZlX#JB7)X#wnX`&`*WYwF$g#x6G5W1Xc7x|lF51rTE9D=s>rqik zEPKs_g%Fipt=_p{0UtJQ&dc+P@y2(H^BxjsSAvJ3tJOlDJtWEj+3)6E)ncJZ&wghD zT}6ku&OE&!Xa=o<|9*Zahgp!$9fB)c-PT9YD;_ zo!*iAitVN^)F?6t+2dCv7Qphl_U$H;qR$^!Im>5wxld-dj0AqDzH!*EWi>@-A07E- zYdRfeu763tHgoR!R9cO2wm|mgZt}o0=^9jd79loLxQ7uiVQ>p~{fgMzmC;zClRcJ^ z8-Vd1whewT+v<^L1!_7dQCe7`DTb=tDb zaE9wCr{v5ru1R5SuR>}tdSQHqxFXe*5)W10yMr9$3<;T*2+0IiG2JIufKd+wr1Uy; zbm7ClZ2GS^?JtB@Fyvs;O;*#9LpfQgqJ`j>Q{8T4R+z@GQFPG}Up0xlJ(#Do5AiHJwD z!tZUBomu<_n1SzPe#d#X4oE5c2`j+v{E`fqNFde)DxbuLG?6xsKAll;@?ZP}=gt2J zG*qgm5XIpkW|R_B!y)gLtNm-;r;{20ZX|Kid6i`32+Ebs! zg^Zed-Nzpz)bF+Tcy$>zX?M#_vga2jR-jn!kWj?pgaOBSCGeGKB}-~%%^;?0n|$Xl zGv&2>$Kbu*auPu3_601u94FmVA*S%kF{tN0_u9N_Pn^wh!Eg#SxU~hn4*Rb|+B$gk3L7ogOq_;Ta=KMdipzK+ zR1rMuIE#4(R=3-6B#;>VBobwl_FY9G<%*gBNoBdI^k+c4fQUXcd zJx)->-a0)4jC7%e1|P6F^wgcLq6^YkFUih*e7U84OKGYoJZF4AK~mr{+Xh(!70VDS z=+?$vw`xn4{<3)7dY>BBH-&uS)|8DuOR(1OJjK{}{?Ta1NcK2YI>2_h#$|%PSHBp~ zkb@kG7As4?k={k5mQ*SDPK|6;b!sVvSm5L@ml<^4aoyD3YDp*8xeSfGVs7#%8~tq+ z(HIp>#8H;9TQ+#bqlcD_d^X_JPb(8GB>kQ=zi(f^V}4KPHq?O@dHhc&%;`sI8&A+C zv+7S-%Z!TuF{eJ`AbrjY0?Fju4SrVf@?)AlKAN9L9Hj0gbdAWxiUO@CD{zW){#)fK z6!je@wUg@t#^7t}J2Gddyw9{`pdoXv?|le5lwIe-UEx}z*7~cJA90r%R2|*0#;P`m z#xHsqUKIvWh0LPZPLX0-Lp04q#_hHM)MvZ8fY_Gp68s zU+WLy*P*ZdYF#NO`jE3yTL-Y0Wd5gh^JVx&X*4H%tcA?1T0XX^4$+ z#Wxs0Da^#p1lA0uv!a;4jsM^B7|{4`pa_8;ae9zQyu{f!|C|32-V&6!@wdOL0LwR` z=BtRs88em#l8&|FMTLLeEEWK!PaXf#;=q`@XJsyBf{eA^eW@{Hd_WO*pYX--YFq|p zZW#hdvT9t;;ceH;?}5(>82%l*#aSBwY$=N=@H5|_FD&k?#Pn>D6+1o!+A~HRkWJR! zUH8}PjnEo@aS`#OIJ66JX&}x#C;VmXlp=`Jy@C!n=5Uf)c$v^sDVn+siexgc8wky* zc&cjGS`OmayfZrI$mKgLH%%i!y-Z=iwCJhiQfagK$s?oVar1PC6vjqSQd1akyN`eJ zK%u|4Y_a*&g}08?>#X;M@2$U{6=RWY8W1QL9n$oLr{3h5|qcZ z&7nNMAfEH9NmwG3D7-NqztLX;YhTG?ZDWSm`nXx$?+LxbeB0X@c(D6=^EkP7HTQ|M zB+@OdY9%>uz1G`&W+Z|A7YQhooeUySo=+DwiCvsN+?C<5lj5|GZrZo1b&Hq3zkL1? z_4A?PH3kdGRwL-yHbcyl4S!J=262Ou+MZXt)cVQ_=7Z7-KFTuYHrD?v^L+B&Y?yU4c!?Q@I2kpTHln+NGnKf^|G5Z zykJ6T4JmwCJBcenjhLKz`Wt*^GBqp;d`s-4&;Fg25|W#bYL}R+)`;8U$Z%L`Zq(kp zf`xrFxev@mPL2)7{TtqECwG*;91- zzVH8SQmHH{iU>)vQ?e^dk}XlP46;Vqm$3{}A(ara8%p+s$j;bh$rh53eP70IEHi%R zt=IeWef<8J$HZ;ihOXbo7nb}9jYRbzPYyq z<-Z2H)EVf6A#yIc+vW593{glHaa)`o>ugCW#C+XW*)%nIRkCYYR1 z6%_IB7w^sX+63XG7o@}{w`UGzVsE_-G^%hSXD8t}&}D1Ad)7$u`~pE{YrV$k7Rh;N z2&^ySM6$q5Ejr|+y=uRDs-PsFwd#|y_D>|Jz!mv`(gj9yQvH@>h9#&uur3r73gyExq*AINR9 zlKiatXyZv;9ES!EnslP)c33(&{hfd^>402}>YB~5q(<$8-{4-9`AVh0@Gv$943IjP z3OfBGgs!m_td)B2XPZTnq|;ubH<~3P9~o54o?@ED_PE>xcOyV>6;XI7*=xB% z#b02S=TJ**NCf1PGnNZZAw7*jQzKT#elJ}5pAa95V4H+XU?*1+G$Pt!YVrf&8~{o? z{85F0yJmmQfB67J+^bN9ofHiqdi0Vm(pH?+AqEY;h4S9EJ`ir?(b162putsc=C2{= z!4J7(VK6M26;O>XD+Mp5w@8-LA$LX;>_H+6i1H$u3)|pTibaW!|5M&w!2jNLG_d4% z8OsXNJ8)9a-u#zCuuBKq-5hUDj3k@^K9F0p8Q*+7hf$vza&@KJPZ$z9V<|XAi8vJl z$dw(@91+Im4;b%aS^FF?j~~c@S@Nk~^W!rq2HxH>^cpvb)|(_oI2?Q+d!y%XwL)iA z3(GZg;DfKWWa;b&GCr-dOw>tYNR&f0MrWr1B$l*_?5Pq=)3yMc`LBJ>v__jsZ7fO+ zuw4m=Z_!^kw<1UK8X6$!w_+OhUKNmJ{4(3`-nGlKBhE`FGRfpoR>`Mk4DwxrTAe>> zas&1oZSH>7+Z}wCviR!T^Oc=F%Si>x=9k$}+w6;~pPYL%S+3rF!R_@ywMi^Ffa-(% zbenlE!^ZFKPpn@$7lNz{#eFu9ef|4;m(TmD8hK}-UfSXMC^uW}khK5FKtu7Jnp!n_ zln4KU&gVaCYft)b%bw6Exyy2XXf&8(TS8-AFnc30cWI&d93IUbG0PiEn7>pw@7`v5 z!nzxM*z>2~iWjk()^CM@rM)acQX)!gsD>aLy*%NoNQxK>aAiIJVf0(I|Ni!m53@wl zcX3@z@vh#LnMh-=mf^xu`4UfyZMriRoJHeIA01`LDt>Eq_C5DvSB&MIh|8XnE(^^* z6sOdrT*@t7qWfH3!$TJg4YO-R`rR?Xb>$10ojDeDF>Xm|e0MJ;VW?-z?u^9*S5)!p z$DUGF;`-ult5!XeX8*lg+P-^;ho>tImCmo|=D=|4QG%Poi)CDGq@ICUYevZW$yRh<-cq0!N_cf?MJd)8{#g!p_^@wjF2`1WN*2JmYH=eQ zn>Yl$O1YlZTzl-Tie+6G#w6!ins%(xy8>h_t2`c48{=0!} zTkX|r>uocMh^*^~lV;S~=UlbTp(r=xr1|!;0uGl(h2hs&JKIEK*F1_vpVMrpY22uw zRNDiAq<1&>qIj}pYX}|-6(t=3b`|esMX|4|U#feWmsB%l5c5sqj+WfNv{NMXuuyP3 z?||WwUuy8URPguIcQ$fOo!5+<@lSY+dMv#OAlXn;U+Zsba{Zf=zi-@lw2sf{49)Ru zF~Pq@+>sPzXZ(dkoX4h{T+(&&|GsSz0oTwKdY)`b9>UE!tuM3HSlXF#u%yu;Hbh+IQLk;kB}9AiBGW67#Jy-&~eV!)t(5t1RuA7zHtSU(!2c&61B( z?2t}y=I@6GJ_~uCS2G;4R{~M3Y!#H@!T-OInID^Zg*xRnq+e@Xp&IuuKZ+8-GR3^1 zzkDynt(W$*l4xnc(c}~b=I52Tk6!KtG=n&=U;aA?l#Nera)&P2Vzqy}wJgKrM0uTRH8qY7TZ8q2&Ql zino|T7ck)nrAQ#jGVxC5+{d?N5$`#RSbuaq+Hy&IqBQR|7gvX_RCw4FZ~PVJs(@55 zNJf67-!p0>sJs0BegbkROkitv#m+kGiu)R*;_f{%`1JWHwl}u zmUJX_^V!prG$IjnyjkLR!t#q^pdN-StBohZ-zHA?3_i?*qSudIv=p55EVp*K?48O}n0e*2*4(G( ztao>wKYA{|N;#pzwXW7G;Phrs{Ch4PMf@+&QYu}w7ypNdvU^QET6Zg@h{e8Br3?%*ydHw=zEhhhFtgG=(;Vb zb6bedCOL+5=yHX}zQ?)TQ(qqmsVf=$<43#me0;_E*XVl*Nw_xV{gTWR6oX|(9ZL4^ z?nyK3*KVrF?>c6OMvv{8It*k%$zS>y=WZ6pIN#}dK#qAZ6%}K4YhWj z*SUNAtTVzI>oSa;E)^8(?Q0+!#?d6}cj>~mNZ`w!%Qovm>sOb*IYJjL;jVW( ze~=ACOTGUwLjr96T8amsi<(s2oto3uiB4PVg6tx<@KT!pePJRLKeq-l( zbb*NzXz1zdNddv+$~XKNp{1^x8be}bnYT_uE1B);rV0`gGHb@bdVjKXo~l1ep|84W z?*XiVdngV(Kp6{e!0X=6`^5g?JP6bCV#-7%AFuV#_6?OLH2F}gey2y^e#E;y;C^Td zAEFrgq!TpZui#l0Kqp`VTry+^I#dgATc}78<`Or@-i_so!9cOZxBx*_!B^j(kHpcpz!7fk+5h@urkShkqE81675;!_tYj*^V9gk@b0ChuB*ZyB zAJID{-^>_cE&e-JqZv$iodMze>H=gn%ae>Bf} zASGm4{N5R2Z94cOW)E0MLej(ShgXT8;jOxG<`j{9_INMr?`Ug{l0y%$0=hZhv=}t8 z0{TU~a*%y;Q&G!V6@=#l&$jWWw)+I8h>pRL+ygHAADVj{yQCK-N5}2esXCLFa+TMK zn6>>>-pu3i$Uv~TkN6;yYRPO}R^GAi#Y`J7W~iB^s5+C9GHWTyE%Kuci;3f{LoJfB zaiq;1u9y?a&OJa@g;9S2`elf9m&hl2CB-ED-on(7#{NVg%$>_$GSR;Y;{+DStEcX> zto@1=HM%@iV_evF`|-(g%ZMNe%uM_H1ugsB=3c6ov)9_{wNw(^*2$?)!prN=&pWvB zHyb=i(;l9xrVL_rz9rWwW6F^K-5>Krl{$r4H}0rZ_Aqnn15x)yD|^yum+Pcu+dCzn zkG}s(jU^YUkC$i;cf2QPZ3g`nuT}aKSJqzFTi7HuQ=Ln|#CBPIU2Qh^<*?)2d$ zT>pr*kikvpXqC| zs9Fj8>6@~sPUpRR=EylhDSP$X^tTDIL8D#rmqK)TXQ6|@orL_NYbmQ00TPlwQy+EJ z{Yw3q6eBP=l|Hd?3*BS&AG-Zf2~V7f`=g^>SZ<^*E^Gu$oFApuR;FU(i$p3ZiK1`K zFY={zG#*Y5m8SjCbPh?qA&6)hMeGQy!+%e08Vi_!!TJsh`h^Bb#N>vDsj2+2dc{|L zC*Sbjlfm&K{7LXRq=_jxqiBM_;rw1Z;EJw~9wYc3K1Y_`HM@$3o6b$k z0}C3V#KP6v9B!>e;;8pG+z#V{}%o`NZ5d-)pl@8x%tSArD}Y4>qlVld(v3rGiwXum^(}SKd=Zlxk-ni6c^kl7 z-GKfako_8L&0ouFcnEv7*#`EI8h%Au1A?qDXc=qXm4VG8MR5v~97A{LmLdekN9w`t z7Br;B{V&STzIJ>hHh|EoRB0Y`*O`{tp`>mm{gy|B8Dd}lxOkp``1b&sq_tOM=ugxb zF73q0{qhs0SVj=SXU^cYMi&t$CQ7+bi-jT+egwp5L8eY@gqT0$&DfCW4#!)wts9r# zUwIhuIJ^;Sb^G=!f`Gu8s`n8BkE)feHbWTT?Bt00#vC^<2O6=OU?-^4i{1*ML??vop``EfbK5=tMR0ALLK1FjgJiL|dnYz`) zY09Jv;n{<%c2drL9SI%-gUx4oLvLLDGJbKqA6A+O)2qh>^zBdfrq+q?ap8+=o*&sc z7m8W|J&gWzuir#^x>~je?OEW8TfhC#w^Sq0lK0}pCsUzZm-3kj-?}GeH@>#izeSOl zrS42He{fmPwx^`r`-$9JZ%A>-Dd!hmxycC@`B1Ki`6*gB}p}PWfn1X<%BoEYq6!Y zZ~bYF&!e?NI^mtZVdMSFf^w(mn$zpsTQtvp+G<}mzy0;VQn2XUjU`Dxijx%?xeVb! z#`p^(SR(VjU|r0!gCerRQtHae*9`i>B%D^?uI07eU8uvOg#!p>I@pZGWtb{)zQTLO zBYW+j#fFBm(<09Dtw8e`8GO-v|2kwY4Oc#OC`NFmsGnf}@CzaX>taFyfI52F}Ay36uO^EoU$ z(<$Yb#+VKI_Z8fwlj|{G{?n*2AhOyNs#7H20aEI5F3(u^`Ag36jHhYq3{G>ZuLF|x zz(rqE%!thm+lg~I_bc;ZXT%e5K42CM$la~quZ;s@$b6r<1%N-+7TxFJvvaL?01HPy z*!t%bh@bst_-=L%Rya!^Bqu}PyzId2eTK~kkw)Kwf7nPufmrl-jg3_e|2Po3eK-b) zv9U5yaD#xY0lr^G2-B_yV^hGu{w$46vFT2lxgKN-1 zdoKDSbmoMW<0jI0H&CZ@)wM4jMQmks(4d1)?Ur`b^`r#gwfr}9dBSR=t=&T}Ksw1b zxqcg9^F(@~fbVtCko^r(E1t_F(S&&VuZacE=oab{IGaA{X9goB^8XARdHwe#lXg*? z$QOgUOuGLmAiKtwQ zM4IY$Og^N5>>%MD|2;Sya#-qi`MQRrBf&N4zanK3)$_+5f#To^wd?44$fY|5!FW)Q z8X+4V@H7ye2W6;_4d(jaXb@bHLbSF{XL2tJX^(t?y8#dMonz=vJm+H1W1CL$feh~eFV)DqDl#v*x2wq)VC+!LA<1{^Sd1j4CTb}El z=hJ1rE#lP@srlNDcGNNajZ=0AIIUcx65)}7V~I;7FZ8QDqN4)Cq!srm2B*sbjwN+( z%bc`*n&~HPkA+2WFP0c5%GyIxct>5NQJmCi z1ys>xwvT(oF0eU=K-%3`v|`r)`R(!jYZO3etH-H(J8D*3lYYQv<{v`xRgv@gv(c5I z?ekOb;-8C`zbMkE0$12l0UJa%xl(dto*$L;^rKiP1CEPT@5sq`ecld~?yC0P{&2Ra zpKYy4WOO3G5qYP3qXM&OGOOG=G)L-oZ7Ya=c)8U}*$Kaq&@Ic(Zen7IWaAx1{$D|0 z&x#mDty~lx^HZ#G{FpL|OVa=ojDwEc^w@Z0c*@jrPxLBV0IN~^qm!U@%J)d2G88uT zv$Hh1#>cO772pfZYd)VV`Xqg_%{+QXbCbQAy*0-0SjKU0bETJx6T$p9rf;jYsqU_1 z`#^v(=eZTb9d3at1u88Q#^Z@7zPBiUSAK77>!SJV^l95zZKQHlI6gk6n3Ebt9nW9e z?U$N2UbRG_GAEla%h5?Pts5O-kS%%q`{({v=&Z5Vn8w>kT4~R|9)9%A@%8yj=VJw5;QT)ihMbL+=-`{vKu%7#lvj&_UZVOJ~RgwBwQp*W%m7YbtomBU8!1X~6t? zh6ip7N)1K+b~LWLmmCKRLav}ojJd|=_`^(*^9}x%=QjvxEW9BTma8*+7}9ChNuGysLHy?O=$`R!Q@>O;1}e| z#DZJXSpSRkS7=Z@#bmzww zoXr#MOa&#ayja%T0jdc*3o1Vdv<)va0Pq&2*!{`W3D&d=p6S&LhBl+C*hnzI;hSAt z!S8p(Ddtm?i)$)1-#afue_dEzkq9j6@zOG%nbnWsP`i>VOZ0gWPu#-TD+9~aBt31@ zMe=P$MET8BDR!gAOwOX?2+LYj>Zmbpn&a>=)CCyH4(@cuervmH{sv?{f|5=){{FM*gPRhDN5<8^uz0yG1NKwhXE+u55?`j@>P@~Q~|Q; zt`D0PfA(ys`+`6o|5$MlED?6R{sQyY;<`U#2#tq$;g+-^IOQKD;(~&LmMnEH5yaY^ zZpDNHulVoa2C}(7Py##x@pcG+e&nBNAsUi1YFg3dHq;2I5@Ib8^P*~_a=RbclKeB! z&$?LJ0O@jlhrbEE2K*!TD3{25AESUR0C$Kd?LX=R=yC9`9a%W@*{Sw_;dT+$qbD=| zi)xxiJPq+zMQ1>M^`1sFScD*PPdHFuya$x*B_##^6DM)V4b`Icl^dYl*)b+L zxU%Y-0sShgJ+Tu>#CCfU5~={{bny19pLhRP79#=GU~?mXD5$0_OF#`DspESvapb>@ zyDqK3)q2oBT{MY7v!M+5Q5L#4|7vjrti0)Ax-3kw2qD`*iJYfwzWN1RTe4 zzPf#d&11g$+Sc}0+^p=^P}EzW)RQg-zc)A6Ps!!7zn1wXMZH68)s`1b zkllIWGj*mp+d}3vP#kg$0D;`TmOQIzh!a0`VD6cS10+?H*loSE;wcpvojpEru6V4LC(Cvg6w>VyxROTMel1`KrGz*TJadx$Bz##Faw+dwK+bFl_ zn~nZ#rk(gc0rn%8tUjw>-<@b6A@;Dx-S%(fl@qk-!=!WTkKCF5Rn?gVB3nOZ6qmZk zR;*V)nZ^%@mDrgA{oU%}+mR_Ou&GY71?k_(0THZ=E4T#JUP1m#^(0h-Mz}z|XWNWW z-aHRm)>|l}2m7|vJ)c}j?ulhRenjqT#Q6T5bAIBtrej}PrZBeD=}gH@TULy9$`RkP zzf7dseKxpL;L`u()8!KQ+SJlhda9{egOr2Uh<|h2I?Sq{nCv3wXwNhkJce*B7e}5~JTf-0CW_F#SiKfJ#}SHXBtZ zj0^s==q{bq9froYUyzchR(6fZ^R~Qt6%hK8`6pPZqR#VgCa(m`wkh4ab1&5omBRI7 zXjx3sY?Dh>?Wkwg{BPocwwp|_Z_TIru12- zjbR~W21u3@?E7>`W|FEgsD zED}-;FHuimkAgBn@v7u9_GUf8i^xVg+l5OS{T1v!dps|Es_%G00QOeXw{ZrM{@O*O zo66S`-nJEZc`wGWwWit-Uu3S$xvp&Uj|>*K^1H}nCm1fTM*0-qvhXGRo?W=N;hT~i z8=0ToNzQ1_D3R}=h1n9X%66oH0k>+2CkU1pC2(f{;_8yXtte9i7PDlInU^%jMLI>rdeOT}vr`tI_=B?<8O~leUHO5~8xdn8 z&*!Q)sUih*htp5j#P--)Qvt(V{I-R2`F}~UK1_Oq4 z5`v+ZQm3ke8(j{e#6H@iKAe+R&d;QhLI)k9LO)+tY!3fn zq4Pdn`0?}*bk*|8{p5-D3W~QDrG`o%t?!-leoZin>@uY6Q$)z)xVgsEu)~9ri%p^T zg*$U2ybE?-^4R52fZ|j3@bCl10ygLUwv|2cHVs33`Yjf*5`Ted5Ihw-9`_4^|5J8c3LlP*oB^67^KPb8HM)-W zI5HmO{j*1*eOWr@+ehx%jK0d%;&T4#08uI~GZ5P90P;?nTZRjY2G4^Rf>@iI#H_il z(+Zner9^gSP1n0#NQQM0;_yyK2xcH<+OBYB-+-$=ENjUTv!)JYAJ1DtB^+=@Ro4jO zjo3Xu(y_CN!W5I9%P8sXt8(^uPr0yvr-eN{vQPAbP0#1ALX}YMAO6PoTD0)tXx*1R zZv9ra5)(K!_NWs^W1!T5sRUI0FcQ`ZX9*zJ|LgVz86z4t0=+|!pt#9g;F2a}0RBH( z{q7zE11iuzz8&%dOTb?N!uin-K;)$-uV!L4d@o_a9Q+c3q}WHH*Y=AY5(4$`fS7zy z^q_Mnd^kQLy2q^}XAQUrflv6108?L(;6PaQPyDb);y6GNinj(ui0}%ep?^XWc(3gb zLHkdU;s1hK0T~h8dogI%{X4i|jYY z5ZV!&H*9Y|XaSLlvwp+Bhp9vprl;A8^fP~Kzdf_%ekO;sEdb)t#X-WZQ_9j@cyM3zr#_qPcB?6WlVG# z?7e!7!;K$r(j5OYs?JAt(Ea1}!)&FDtUG1qRlkzUnNBoBw#_qd^(A;3>TR3ces}~J z7^1eg>r8gqD=Nd=5I+@SeP{67kxM1SOPuECrJcrd**P)jrL`m~*~x6Q-N4uF*v2$j z$+yVJ7?gd-LD_(k*0I+P>{GJS$!LEo=GXGOVl*Ob%ggLQOv&=oy|-H6MV6p3H)^W za9m-~8k*Y_sXcXBC(|T*oAUi-?KjIbEzv8f3A&;erKB)`d(&gBAubvv7U%Os+F>B= z;CJfd*5btF(9>R0C$fE5MYuOrhkwhxA3D&n8Fnu$m(i%GNF&)fB-e|D`QcS;S=iiu z?A0a>a|`pg21@|$tIG~dST%865WI|A-hU`T9KDtM+wG27)$gLbM$6ouR}0kB+@2#( zrBU7QX-^|zDZV0&mT$g?$Z+gBb6ZW?;6#fxIFgK=tDLwerII8zv#TRR9*?@XEjS6p zWw&S8^3Y8lzpY*+A*zTwf8FYo{KF{d$5z!vPEr3ja>+(;NISN_>+)42qHkc>5@HmW zB$Jdm`ht!CceB1yEu7>SE!?5`sCDT7kut4>p>@hLYX)GuYfjJW#5@*|df7u*$H!8Z zNn%H(yeEgHgo}uDUXRaKrQZEDz94bpP2Klk3`tz-zsWPp#V0?pSIgs+UaF*-q&J(G zvd6&=ptAIFElK5;MSU1mJadoPYH4uAwSOUrzlN*pBE^gtt7Pw;v>o^`9@1qhA`=%# ziTySkCT{eDX}SFZw0OH2-^k{q)kB*VAPjyZ=iZSeg{w>AlK7P(JkJ)%wM&R%E1S`6 z{(in)mgaW=<)yo&S*OUu1lBJk+k-2fhn8u=!U)A*gaysAJA<_2VU0 z7y}62ul6MyhBBAhPC5>&BiW*9KFF9VEBMaKtL+*lc?jCh=$SZ~Z>oQ8auVAO|2HvV ztNmU3IEn#=B><4ls;A5FavAk2`6eHdd-ds0;K<}0e4!Wk#~UPF)LHd3O7``B7iB@^ zYoGSkC@Yw>2GB7e+X>&0o-+G0*PAMiaAW-@-(d(V1t|=Aj&MGbwcl3)?7nxQbV29C zI6~Z9envO`0L#MAsf;6oY7e3x(gmJLc{P|00kudkv|Ad^BP;aP z=;*mc0XV}*zF=bx*~_~^5vnT16X!l8%6yA#fUv9;)ZooJug5N^D8D_<-TWWHbG`~% zk}RP0!+P_NjAue&LN*gqW3s6JdsX`Oy#oyb%)>9o`06m6lKAhDb~VwL7G>@a><*&s zl~$xI&j_a~Xg=l_(KKs_N|d|(@`qm{mljISLO40}4t4VFvvOv)IfczjvYK56wg-99 zg#?yghLhXUgYkpda_{WP`=o+VOphgDL)>!SMdo`wTDtq=kmu0)K{&d65pGdd;8hLu zP8CI%9YN%Tv}wCSzX$*LIyizAB#^nI@g$7>0r(!m!0g`E`9I*4^bJIa`dI2OY78k$ z|6%lOU<&~(-{q@I&sp&iu;a~L*QlumZL6oq@G1PB_GSqk8Kr|%ZNx|jV-bK;dZ7@8 z7y}hET=0GO<|PMxmLoKY3%O0&VN>4(@9(ICB?M?hAc26BM=T;R(dO=@>&TW=d&~6* z;6D19t+cQUt$e%|c3y50@)Ogx+eb|6Pp`{Z|lB=$Mk!v%A{C7>nKKMGM<)BT3Krs9VkNl`d{rSeCODu`1Vf)Uj%F7@f!@-j#_~q2Q5xS z{WjTw(t_PAQcF##b5+BlUq9Ed(>geBsG71Uk15-rz^!mCb8k%spXeM~-``WhJL=E@fL+zHo{6BvTnWOR?D+N(g<4W(+n zD@!)};%9VcC$yWi@TLQ<3mmB^9_gaFGKL2eEy{O{rkppQ&Th4#zj%G>6pNc%4tZU& z<0a$J#1&>_C4D(`G3KS)hX2pR){i3Io4&v9$H*FN?%xQ>M%f4_D-te|ROm0RDZS+H zrs@&cUh8_Uqeq=2uwNtfW*0>kb8VreuWlLP@rcS$@pPN){p`+x!fwal^{96&TBRCx zA}1;qC2J^)YFg^3TDB%%3n+vr^$XBcXzv@IHa$Z2BqvFICNzZ*)J;uLeUkaSPdJ=nW|A!&&Ztk8?N^Cn?w~(`V zWB|9_+7>aLzK&vWH--2o2SMKbBY81#)*3$YJ}I*Uq}t%V8+T=F^B(ooe^Ls5`&jrb z1w&OeD&E!YwCc|7DA!iIw_ks_xK2tU$WJS}IDQtRW4IpZVCW6q1jB0<(E)EOSY)NP zMPxVmXXX@8#($ENQdSeDha|Z?L)hzPbh5y_2&qu0MeXJ_gS0GmpK*!O6_oph?F>uV zALnpum9OOmyncfWBNc`tG&P@9!H4$Sr6gc%-9tht(W29tq+<)(Q9Y zN>9`6i-96Py?%3np;z}EQ$~}o)A~x&sn%Yz3{|l*=o{EWCqQ_3k&HI49#-pZ@~w%* zh9A|*Fm4Q@cC}tHl$_jxf>|6o*=6p12>az4cw)&BCM^t)HMK@!eo} z4%?$OAIaa8-yX&v4{O72RtYhYgiKQ4LLImfmUI6@(m7~YLwE{f5tAJ!bZQIfZqo%8 z(iLo4mxV*~*Nx{9*i9Z(ixwjvY_us0Uko5@eL0jB;K=hFR5DLvB#N-JF3Q@J8uG2` z|1u)y1bOH;l+_{r!2K0OTNRhZ62=6_z4s12;kuN+2w7L7%8~op&BjUruEcMvxSkR0 z5Aj!kMlJR0`itz;ueUIYEOgK)pneTK0e=NAM|ie1c8i712MjiB9Vr1zY#oRV`e3Kx z@R6*5Q0srK;&xN*IybM!cjVStf$;lO34jh;>XI!SRLZEroI)lhFZ$1vVsG?|Wf<|Zw7H}{U1;Fvbz z2r!welvAm(kEa_lRp=a-98G>jJ>BioUMY57TCO8bWxm&TdV|xrgRu$mnWKp#2=LEd zFKa0(Dmr2*?^i^dvYK_Ma$}N(V01z0t6MQnY0d`vRN>V&SV8w?eGZuFh@wD03h9PIDt@S0u> zaH5TGeQ-SG>PiIf-Q0OET)bPPc0yxoW*V8!qy6X zNAr1lN=p-C=cHr?H#H;EZGw%&RL}B?vT@(+IybTteyaTM{8c;o1DxFkk)JHdym95X zG1_HL_DfQV0*3f^ZsH-1e@u>>->Xxoqi?uxzx(=N(o+SqbltLF0@#J*Z*~C}T5U8+ z;%@JJ>HC%{Gf?nC_;)8A%^R)50nr+I2Ojm1dMR7HhV?ws+7+0~)`sd$v3|aLeHpIR z-t!hq`ft0Qq&El#B|TbsN$u`7lo8*IL`aN2dIwHDK-Xz@o-NBuu)rJ{Na)ZpojQ|J zY>8ED-ZQZUh1;=6wiXYuB1L`mGjo)NQ=KHY0W%)BeRdxdN1j^NxheZ zj0Rqc`tM)xRvO4UXEAu+DB<_l*b!an^p&nbj~{O?z=Zh__VezSi5j8i%@Cr;8WZ*Y zHhh2S{o6}9v536aQ)B9elJ+_3c~1{^R?4 zjlArQyG`ytd?~x1m6^%L_7e04AbvbK%1@`|y$3%mR$aYIWHf{?MgD%z&S7Z&K=@e? zRMq7%QbxRXv=feMnix~!yk(~q-`^=I8JT*__bZl_x-Da7ZJ~6VBcwKw#)QgsFJvG< zv`+fuNc!R2?78COfA>9HAAQrJROsxULltTrl7;d|dwpG7nVyGak;+54)K-#L?bgeF zjK@?9x2cvj9XG>Hw5o5s|I&P2=d3a0`BAOjMKR*k9G5O=h-K=(O#)pj*U%$ z)&q8BSa2*F;CGJ6YqI{Sg#3}ZPLI7|JM_6LQ{5kwPFmox)W$~}d_u@*(w~>`{f&xR z!>(!S2r&DFhhITQVj%bIxttpoaJOH}DhLaTb1$ z$TQJHyIJbXzg)q+E8v}7t%3{V_4X!%!i7eUe{PZqa6g+bp*O+Q%LZZ)wb!jv>K0f= zoe3UtI}9|#PH7Q?WLLS{t61y98w24PVsnJ%0uSh)v4j|`ln z0o`dq0vXFG4@SosmKf?U)MkaS`Ip1^oj1Vl%R{rs_~`G$JecpZntSDW`{sf`j2V9S ziJ2vy(f=mN%iz1iCx+ns5R@-;d!O>rmHE6@{3qbt$6qxv~w+PP=>0T(uw*HV-PXbHNhffY zoTW$7Dm12~gh+a~+iL|xW7o-^W|rQ%WU}MV4Zq>>o;7l!X5Hb|s#F287oqlWUV>4~ zwZEkPMeO(G>(0NvLIdY5YOIPg>lr-TeApgQse%WJIRl$m<=p( zO4t?De}KMzw#S^*YIpMd-wlgcht{e%f=m5?NbZ2I$)+-E?8f_4Lw_eVeT7Xo=+7X!;42Zac%gqvO}{ zyDj}buPX}dh6+qhPJ3*wbPZ=wWKVAYI2KZ`YxOm#Y7^^KKQTleq_fq@X#V3zi=?m~Q= z^IFX3&Np9sdV;XS9ps&8oTD!78ja;CI@9R*DID8hlFPc1@Oqn8c%JM%nfpz~A%`sc z&MJIl=F~Y!6xJwKZI z?{2bLzLf3?_z|BxX)W?@K6`$!=)sELpn%IsnFI{^6YBH12cEAIRqj|fDd|55d?Mlf zt3>xb(}gIu)`jawWX5B9Y(-2v-!|(gXB1|2n=}gyqKcfW#P97~wZvWwvyjn@>|b)X zjwmLrB=ks9vdUsj`Z~VkH~m`rcIcJQBQLhW_y_8xS~W1sQth^y(-RTfc_slF8A1BT zBR)K5zU-ivxyQEu;FWUFFyCIIZKi()|7$$p{r2pf(W!_aqs=*gUG~hjWK!gbOznw+ zKc}rvc|DHSUaKeAoGyI0GyM?81d*PHd%Kode=O_&(N0ymQ~JtoxaI`axQ*SC<4WU7 zYCRuIdE%shN60T$?tTg+w~CT%LeNpc>aCk}GH{nbEHbh4YyZY(Rpd(3IB(y_R;>bX z4Yi~ep4y+Wvhtaqf;>R%P$Iai=L=NY(_+mcF?eHh^3l5Uir9@1s z7Vk?(em8TdAVxWJrZ;|@FqL@Q!V(E0{5T&5@ae2(&^=?dAMdo=Z1f#=$}LP7cw`cJ zy^7k0He%naDT4#c1om^jl>~{cjgCg1OMHaltHS*rg#!2pB}kPqyGk1McOY%62~-St z+)KxB>P~T_NrH5qJBVx;YRtLL$wa(~$5xv{b|&mD=7Rl+~lIBqNY#c!UBS`UPI4bUM+oJM|ciJn*Q zC}Fo>&aWp(3QqQI)>jF`egvPD-0dm7GuWGFyYW?}{*SGXneaVlS~Q(|?l{ZVn0?UG zCXy${S*qfAnXu(McvT~ThHW))SD_+h0=F~&lzPlBv;`uQkp9rou#c$RC^i{J-1Cad z^wXVleiNN~y$gfm1SI$U>{&Iy(*gen;U8Pfj>k~Yok(0VI*r$}ACl>0E2wTxd(h|k{#@ofb20feVQf>& zlp!$7pvZcfE*X-1e6gzQ#UeD37(@5?jfnRmZT^Xe?PvLc}@51|dg3p{W9 z%%#(CfBKU&4{h$OQp&5#5&IxupzN}OgU(A*H(jyHUvGUrM3M@m5b})wMKzbLZhI}= znfz`p`_^$*nf^{z;yhsx)th`RB zq^2xPzL+fKphPt}WKtY35x_@moeW#};!)^y^ayG(viibEqUmS)ik0GGY5ne}k5)&+ zd`ws8>S~SD=RWJD98j!9RS>3x%Lh2}S%yCU^txggapQ|{K6b~(vyjr``}Yz*Slnwz zmc5Re1veXJ+(^z`>Lp|htq+a$>VJDQ+?P<+F_xvo&XFrd+1WwQa>g6&cZvfR$gr`&g=GLZIiD0s9?Ey7s2}keQuxC&T`ld?-tvnEs-^87?|`|9pm! z;BWUr&I}=p;L;cM?Cft#D{T1g#>f+@yd!-DJ40;Ub?$}ZaJgpSu+M8d>S|-8BeqMj zB28XqU%bA&JfF@{;(!_~Djcqx!0L z^E*G(_u2KmRA-P0AU4uO?vuSwPJJa1SCbsDT)p`s`%FZGUYT=iBhhserdY{PP&H^je`!1uY{lfYSLAH ze`YpJKO}lrq%7$mI&#bSQsWQG#Ya*C^;K_v2uAHH*}uN|lX8DB?T^*sGbjuD&|xf& zY@b2+P))_Vb7AXFyZITrQpU)@T%V@h=beEGuWfP+Ed2-Tu%B#lFce!1&d)34j^dnO z@o$|z;yk>I>QUr6A8L(?45d(szb&;n9hAS;Tr4YjpBLTnLYE4k@A`8fd_k0d|7I)X zYRAnKP5qW^8th#m#ecD8oDmV;8%t_=ea7O8on5b|dcu|DjH$J=uvA7qgCQLJcp}}q z>>E28OB@%{AG9A5&^SxkY*vw_qCIC?DE-I9qVVN?Cb-_5vinpFkL*=w>rWrSd}WqjQP#2i_{9O@5C5se)IZ2B0gGO*9g@Nen@q$rff7a(#zy4^ zwg8l}m#{{k&K>Nk+k+h7_w$1AyapFd43YxU>LyFe>gF4Grd-R~@_zG;Yz#SFQ6yv<|5ZYk$nyz)6WoK?tpqRCV8(#WCl<%B(@Ql)<*A@ zt5+f5ysr4ri!KTdUMZ{^F0h+Pgcx{_RbOO^k`GT(T7{ANNwjT7gQV%( zg7gD{C9P_wznZu&yo$YIpc3zp7$6YoADsFy>VWb``CrB9>=D=hww+|V{bnOi{?+N( z)tXHP=V6|R;EM}9%Tg;zv>TqAw*iy?CO+52nX~2T=osb1YWS-z+FBE9g!c+Z46l;j z`JtqQ&W5y#$rim=5C`f~%SjW(-|FS&epGD3lR_CMqo`WaDBnO1=0Cf(vHIj|kp}I` zt4pl21oA^NnYdjLk`Q$Mmjy2ntWIX6))VN6FR{|GrJYS-*%K8*)Xc{ij2OY?>er|S z<2mmoTpPdshM@?f;bL4uqvf@%I%3B~-E+mL4voV1FUkDPSzX#8Pb0?tAbjqq`Lb~F6fq;clWo7;BYZBwo#+jyrN)+&3Z&VY23P@^w)i7-jdGI z44vSg%2~Nd?q8jhnG!2~%pbb>nGch*Gye7QY^eX|>uiRXBJA{B$J%P-8P4G=GW-`0 zeqc5z6IT-&reDaUuh4S1@unk9?EahRoFj>T+;K)m!VZNv7<@Ms% zjjyx$&J{h{F0r936sPob(ZPSl_(-|01U?jru^(HlljU{K`D6P2^>?WmI;Id$y^Ug< zh3VU1FH+=O4wrBpZgYxkg|c44UCh%UD9)kya>=WNTOH#+!&Pd|toD_8jz)OJ9_=mN zq=ubQ$bYdDOgD1_h7+wW+cKYs2eDrEojCIuv)4aHBx8bb;_)03{wrP*mc)H%dxkWl zFQNXIg5Z0>Tr@%z!kxAsIiKL9Q*5_0)#wO7idAAY|17jqKtl)ItVz8ycaM##JyIOz6MORa}fqxE5bD$RkP z&6FDdrgNO z2B>MTbqtMxSbpJNk)WsJPzGP@z9Zd(tfw?U|08kf!><+htA$K$^l5z_bnW-f7* z45{4csM~8RfU5{%VpJ-Ne5_X}MN|GD zVsanPUl;wa=U`}%bI;A)?WL9Pa9Vh02XX0e%G}w1YI10dr*UTjhQWAuUT?_>K{frA zWv6o~j`Of;kb+`fOv0AWMSm?cAHILQGwlbYXN)zzvtG$sWWM&GPyH#7#lBpq3*B6& zg4K;iWnqjIdSPdzVy%H%JvWajG_Jzg_Wxt*&Euio|M&kwmWU`uDJqe5q!hBXSdy($ zDGZXW?7J9L5?Pb7WD6mL5VDP>$i6RG$G$Td%h-R9*L2>$&-ahxR<|>Uq0aO5cwUd| zx?f8L^hI5>b0-=Ic!FU2lz*ITl0%(8oze-0tn@oYhCPRtmn#6}A=HHov zZ}h~+=7}EtCYQ<3x1yp8DtR@O<9GjP7K|=-#S)x+1MCW(EeGsB$|qBWJu7zv$3Arb zf~n1kk^-yV7c_d+wH~82k4HZRbLQCW^JH6rYN$7hTk9tzi35*nkz%~gyW~3LVm_4@ z__AOtIon!|dZhyAcQM9O6b~AXVt#hncQ?d=v)4E2#@)M`AXC6kKr`sV z`tMH(Uq0c>oIOe2n3Odq&!5HikOtqUb_2!mslzn^ArF=BbX^~(9+Wd!o~dmL*{+P@ zMo&hh{E?AKx7RL8EVXZJ(g;4g(@JXk6XUKRl*kj^_WHNgy(grBBU}uF@h*$|w}-Ij zOVr=`xD*-vV8g)2h5_;z9nf;3`pM?Gi^o5tcE@*x9??>Dko9}(e3egW*JH110Q$QA zTGDw=O_;NAHC&`NniLmNhs+9AdTL}Y_l;KVR>73`eAKiYSDz0P4pt65D`7-^?V30W ze&Km=QeP)UxTTAIy_;~{_WY9o7~G|2D2Rb=1$9qVegkFg%al#joPeRj+9Y;m?W$Rlm>cWCNz4((IB z=vvz6sJGsZ+H>L>ctSNItjX&+U9%!&f4MOOGw8Yp_SfgRll<>ehNf7be0pGQ;bt5Z z>OTL{5$gxfl{4MZTFr0~G^e@P{Ln1k}*}_6aV2 zrZ>+R;GtDf>tS8%s+KOJcZML`lbF*?ni(jzDy3hFKY+1`yH2aVcG9h&w8s@2^mp!1 zz4+9nt-?2*$9t`IfJ%d~UA!{#8|Ch*uLf2;K9qKuy=1IYz&m}c-ozvIeP}5xY;N>2 zHb%*ajA-(mqmqyRqD`t^6xF>pX>jw>Uf*!?%L@@?Kuo|(u6^$z=U$@%=2m%^zi=N2 zekhuT#pUE{SxfXpshe-u&F(*7&qnJFxSWa|?$vwTyCH`w#i`eWOEx%o#3UV=&FWZ~ zYq@BO&#kzO<@<~#m=SE+&s-fn53rug2go>fE%GmA^*^4x7fn#4*91Wyjibere+wl_ zvV{kFhV^Z6f<;3ofS&Hz$QF8NxEPk!vtTqD0r`h`bngywl-C#il}MQDkj#iM?xu+* zz?2K)tU}MVD#USPOy|-G3XJO7?J2Or!Yb`n8Z$x>mcToToi5@t^J6%Kr*!uIK~5(l z9QF`-K+SNpz_btJ{L;zn^Uz83lLX}%$ZwHmrKtXcJ*R=bFk?9C3&$qBYjTAK5?p4N zIbaF&7xZj`J(6F3C_3vQ3oceo%TaiG1t70*X{-84RWd{N{dhVe>k@dNqy-`%VZdD8 z2)%>i{&c-!{j-oKY^*aB5Mc+Ue2*0LgKe6~It}G~3qQ_(+(5iK$m)3ptAq^vmS?42 zlPi_DL05t;1A?3USG5FAAXsG>V~m2Jm`PF4BuX=?$@y&O6-W)fLT(95U+8n-?Z9gr+19BKV)_a+U7 zq~>Uch4o(%wz1Jx*%$ux_JIhqJf>K~c$z39Dap{SFac&z(1o6MpRqvz5V1!f(lJ51 zXW9>;4!5tj`dBPCvunV0%e+-YX+8Ln*vwjv zvn>8+xcy?;(2XrQ=OtFR^$(d!vMy`kNCQibKj|4B`mIqb9^d46PGcJ_HjHOuZ}bi3 zgkpYY+k5844Lohow0^!UmGq^zedx!^k88O!amvz{@<%0r#hwP0^9kMFfQ;Wn^QE%w z5acma5Q1v%UFR9PA0E%eAm_0*^_3C6j$jY*3q3T?u9RuARMr+x2FKO2rXA)Y@KW@9 z9SNRO4zJe|S$8KS@nBHnwV(QAdO3H+w02#WyU!H*AECj&PwB65Izlw5S2`y2DVx-9 zr_Qh8Ri)6_Zm{@0sLny8U|a#8O2N%Q613t!D;%w z$tbvynVI=oEoZCE{XNYltEuyBvR_uG{A=Gr!#1;Y=kIV%_D3j<;pvFj9MoTy#iQ~V z>U?&O;kFHFJscm@)Ea6_8xxB4FMBNgLWQ(4-{@m>EE;yZlEbdr$|E^$C+{M!D;9sB z^AH%tQohA`#6le?KA_F$AgXQT!1A5V=T+QHNpV_7bD^jwq2{LO@P`3IFjA`8Eja=m z9TIE+PVbChyQFLsx7rwuNAI@c?&$a-Y_9k2>#Z`sWRHm!{i^vJVPl#G^$&1pO@j9O z*hbgFrJ_XAx9Ek=x9#JnFGO%74KjZlIVCm?ZtWF=<+BUUNI)=*^Bg{iA@%b`i)isV z0JVKW0aeHH_q+LMYob!v+QXKzVHIw+pmLSt6l&NcsbHZN`POlZw!+6;43Adlmj4Rv zng68hiR!kjrsa*!k$c-txQ8~8bT=EfJP2cQiTjw?aL0h*(ni`((g@<_RL4op&e`qj zi7Uwx1`l=&hVj%^%^LTwUzGq=Kzc{VVy>hxSwbagipM#nF^Dt!JYet&J;&%o_H9nO zhCqZ(_Qxj6q86&Bs#_leRYy=|#gp{q2(f6(it z&Dnhz*qc`}!z8{QZyZUV3e$B3{B!c2Q7Ir8Xq8}a6+t-cWe#^{V9o#uL)D4)HQ~x9 z(5TFywJIF(0nHjIy*C5nWRn&I&cH*{b!HTs2bA@VpyH|-A}eSO|9Kv7=5QBLDI=8; z-HCTlI?gdjuZ3ZMDl&|7JR!y#CktPIS=tLyY+#h^_J=;w8fGjVRhEBamADHMK7%?u z^!|UlU&IP@NKFy*KZFfOsBdwV0Ff2w>JqQO_ef+Vm})_NkpIWYbh2QL_#6jN2qw{c zP7wohu>$Ig^{1yN=%7}d=Eg7*IfLQajpzjs_3sc{o4xZ$hGtdj(+~ND~o;-*#K;J2veT{|#Yh$5d zK2LBUMv{h-Z&(%9u0N^veTeV!o*LnJf&6<7pm6 z@8(w;T%C+PZ4Ue-afe}L%H6wn58eL!aCdqC5SMZXkHBW{XQs^^+s*SydFn_&3>6xA zA-!t*3&WeTnCnhq*?PVz``%M;uVPRh6fjw)-B70OpN42yTQelLJ<2aCdzO`&w3!F` zT%jRut*0GG^IRT1UKjF`67W53u~DrT<9CYxG1C3Ktu1vD=i377qq&Du{md%qvM3kh zZY_0E#riqdE)EeX_4bc@dfR_@Q3-@>7MEau{`rZ8b;Dx?!U1zkx_R<}*ylu{En9E< z^JS)c7dL|09DDEHZFH4o<1GJTkEmt_yzXIuLECd%V@;V7|$tBm3c>#t3J-`QLkcSv^?wxonZMbF+e(*Kdmp%7y@tjbz= zQOA~!pQ(p#&Mv1%6JTC!e2SoA5;42ldX=VhdH(%9ImxSclryU(^mD`VNRRh|@q`}f zjkn^K1oN6s_7rpu8_-sTDOwJs?z71$yD<5&J1U?w?{*`W=RGqcMqtXNoCWP zz?+4)&#LB0mv1N*gB$(Ip&D%o$B^(B#QNv^rzqgpk0ZNjjZ0~TA>P_G5;YLTxZ`1C zK@33_tD&&6PPcrscxlAp_`BAz?XM}{stUglvzpwES91k-H6HE`>Lpa;MHlgK2w}QR@A$imjcSYVU7_Wt& ziMct}w&)xTtNGZunDzxc^3d$o5Jyw#ZuYSPP+`~Y`?(&*OJ@4xs19@W0?<_KkK<#2 z++a&<#MbYi#szewJ(v9Xl~u$&|9-tr>Hb~S3HqtKT3>?^tLV3URY$6ebN6d2Ve=m~ zEZ01gyIEgy_y8NBM56%Al%hWxwMMI2s+oUR-iyns-g1EI3zR+_uh1a3{c=@Aw~u7i ze=SeVDiIw`7!C=cJC27|YiN2~pT3L{vdVrrm0%-(+O66^5O0abLHS$q0Mi-SAJyQA z;UKgl9EOxWhiu{f+~C4jDAZ6QS=le;WuSIs2T+)RW{t}@K_gTuKoSwHIoAQ9oClBPpA+u5Gr^Kqklu=Atb)LKMWh6dyxny4G=M`IUNguJ>rLb*eREg}%AjXo z-7|2&+%EVFMM>bHk$Lj{CDK{}4{srjO+_wkBRF@zP$YuKrhE#~P>}j=cENw2c+)le zz5z(rsR7f-uJeobuv8E)gtgEB-g#IL0jj3nq6TNv{VK6pO%!1b%%FWXXjPxcbMz*F zmLjUpkH+Q5eFvuwOs>$fHs&;QhUng$9S8EtBb2Enrt84n`C@c8{ZhlNwSbC9a`7A_ zR9l*!rIg-D|H~-vxG!gv!?|O?Wok6Q9(Oc|wEiaN-mqwHqR4N-b<+Ji4 zASC`ZgI2$J{UlsnJayo`k=b-JE5s>_|4P;dSu>rYI$2nXTm<*E`%``3_Y5vA!- zIExKi?90XrhJC#Wdi>aptuUe&psuXs`d7r;EFFqLWs;g!i!5$PdoH1{$6M!aKd+y+zJp3MG<%{gv+d%3B}X z~rin?C51bO}Q5h2)KU<8=|A4xT@dOj&Somm!3Z9hlR|F(yIZfsgC4xWPM_ zR{4KRj1Pv{zaN;@ApX!Z%#mMmTd3E{qM~!=GFkW(6X)TyNE}ql^nC7xFm5JyCMk!h z$~2d15IqutNcd?ugu&kLGWk|HZgtn?_p4#gbFmf8@(@GXQ7;^H@HF7OR6nS=L=%=S z3Z#v`TOZyA&^j|hJA@xPAr_i_7K=v=b5*A<#JBgG2E}aA%hoT7b#qN1G;P23+U2@F}F#*+dGaDq8rL+9B%fE))QZ|H0>g+ygd6!wS=p$ zU$=OVFkvNm3JDE3l_GTAeAPibqV?`Frd@ms*-R+WMCC?%q(FlOfNlsKk~``z=d24n z((mEki#{@Zu&NtG#Mr|89OL(lp^EF_*&c9+hQePrq zs%a){=p5$N4)qcF+cw>0Hi1y>b4>xNeKb!I??cHCFbxdgSG-$|_KF);4oeE#>L0I2 zfs6Hm);dgyQeR>Hr+zZQA6l2E;H9J_`gT`nX%I9@fgRcLrT9*ozPn^h0>HsZnUGn4 zK25l&Nl(8b4or>A`a}88v#FNX{~Q(ohp8wBYv6l%Kp6nr;E)-dg@EyvGz3YvNegl} z%{}DY&6M*qI2Si4FG8^ocnb&F!R5%wKu&tXhlQdc$H!q1|Ac$@AII#Z-l-er9N$uU z5efpR%`k(il!v0pd;^(j!%?Y`5sohq5{+nyudQ*8f`754j`+_ljl_AGAvr^C^Z9S` zlsd>q>{MKfn*6o|D4BFp%$ZVAP;PSxHQ@Y%1s-N`;fewZhRfCip7t{A81`QAjK!0u z;j2PT50kL$L-kAKKu$LpE^t(^*Ihj6e01>(&>T|yt;>tRO&EUzR(42EHU5+o{Wn&Y zbH%i+j5lq|s05a{0>lHazgWcf4y$z?zRHt%WKS@9!0~*1VnWs-EdJJ-XVb>aIB)wW zCU-j*3wbM8MvoJV0$@tOl6LTLe>etm3pI`x; zQ961%>+|0h>KD8a`^ba7L@odCzGEI>n@46-cf9`Axo>epFq^h`y_XFeo}r_%rPgp5 z87G2<=o_RA1jwZxI)eG)qwzUCih4XVy%K}VXE}8zr_o*aM+H?Hr9HgD^T&~U_9;#3 z_Ts3G2reeef$xySJpbfNWZi|?5!Fj`@%wZ5i^}OAYEz&G}C2Kfk|dI=s}X|Nn-qb(Pqnbtw2u)$kyg4Gmp8@g(^ql_ z-2P3fI`kilXTz?*i9B|KPT;~Px^pFroIGo%(>aM@#BH#A$YCOtoLIyMo$Z}%fMuP?A~_kd|KVBoA&^F?EuXSX_57VHIB(-o%=GpVBLtnWQD zcX4SOU-51q4G(si>+-10k(Y^?C=&eAewR(L_J0ndG~+^;%j z$acr!(PC%ib=!>xo&{s!iCZyV;&Z(&%N-$JN>0{;#XXV|4rUaLHs6kP(>MQ$aLQWO z+rIuxJ8g@}B>=iDkKZ@@?m+ZGX}o)>liLsg|>4rY}fJbw!Ij z?=G6J`4!xAo%X_ISXnDS_k72>-?bhvjrsil3NPipFB@7_oB(hQ6kGme5(X0=Tg(B3 zrIR%Bk-hOB-bVeA3BBfPLLC(RkY9%M*k}4fQ|49+^=HsmkUd;3H#;a3%6VEC3uM)| zbZ-{UWRy{GP{}U0|2W!j5%7zz<`nE%hxd+ioeU-pq@xp>7NE6raASc{oZ4p?s|BY$ zQO3dSE^Hn>4UEAML{Il$59WV#$lfsd#PL@U077!2McfexE9|t5rvXS2OH#(X^qO!s z>;KFLDc0+8dll%h@WJcx=*@ja0I{T1f^LO=AMjgbAc4j_+pB7j{orLp6h19Q zRp|_6!^p!2c8JtE8&=zuP{RO6=RYGL3+(~C7r6x!6j!A7e&y^LlPfT=B1ixWyOw@$qG?&*IVN05UDpvXg_3ezx~&O87-f3KN&u#eQI!) zJpv-CH#bbk4eLV8k1ULQT6SK-yb4kELLt=yV6nS_B>b!DiX<>tV@$NZVW{NDwp~2D zLreLtcPihaQ^=BV;XVQ#Z>>@!kGw(ePF|mIn`#+D z+U^&0DR!3!xa#rO>V1w1-b-G~aC8?R9(yb0ytMr_=`3YKj1pW_o%+k!evKObiWzVm zQ8?WncXFgMiQdbEN#H|tsCeX-efPiBdD*Tkx*C!?K@py&F1^fvGO9 zJ8nchcP6l`KQC9FJJi1W8fJAf`1*WaH1pv?LV!`?$3=AvqwzqQ-1Q);FLTfci~?dg_U%J3|`zdzlpHtAGW z`TQs^S$~0%_0tC~|JS#pFWfjdArKK^xAc1>l(VTiBK_2!bT9}?p0j1v!LF`USPD9( zjSwHRkB?H?=JNywnzG7CLu2W+YRQ+m@WzIj7Cn6P>9+&pNiCH_x;;5s!kAbI_Jy9R zypvqy7?Vx;X-j>zztaBr#9=RIt^s0iO5)&@SP;Have*jdW@ZOw7`d(OZviplb@+sH ztW^F|O@%$R6kg@R>7?4 zife~xkzCV>3Yx6`rPln>K4*ZXk(|Q`uhL6F}pD?Wo&Oq<2Y0C33Iv6^+2<3yjn`WnCUd znWSi!GSq8mjoVs`7~>e7TQ_9siP;GeBC5yaHY3})dw9(BLP3|hKt!HFcK?Kj-iFlI zch6$6I@jUys*5UY3KI9pX2|huu~ml?e%ZKQC&}hxg^Hf#?Yx&6MyF;9h<#-LcimdRq9C? zrxs%Wn`2`CBnDNpdoR(+_~6HUcYU2&&U-M2vv6__e(l|9Zl1@U7C7aO0{+7|u;*>0-~NXuKB{ycixU7)G13q8n%j??y~%lpzMB?V76M)!6luG9 zpy9kCVtP{T|GVcP5n5#wJTV?oAPu2B&2W>4{^b z#k(gv;M7H4E>P(V&=|0Vs5_l~3w`ym@`!ki25^hkR%@M}hEOrVj-=HwNzV_?WbjD~nJ$|i8G`s@`9cKqx}h63W(MkyObZXm0` z6W4UHs~djEQt(gl?9rf8XxtUV&#ftpMEgHFLK*1CT1#-0APAc#C}tL~{^~FMZx!e) zBcQSm;KDzsjshbM4KNr45CHZMjFATDGpkcTE&zI)>4`_<0097LT|P923V1UA?^WY) z)Sii-zlg7z1J6K-Gcney*hfzG3oPs*dbIDkf%P9K>T#ht!i<+em5lDq&bfY2Ge6c? zd99i9EuX( z?gY-SuF5qiB4RlxR>ATDKQ-rCGR<`22un`xzM{=B&1_K2X&V| zRGe<(`Cjq+p2m(#uhi^duk@PFoNZ5xSG>9R@-3QRyawm=N}N->TZ4esmmi>Ui@f|= zUuWIjQJAOqQhLE2SOhYO>y}k%h}8^n8^+uFC@Cs3y4lt2v8kCho%77!89g_X2R<4* z*OkbgCyITk1#ALJS6D@ck1b%O%f5)0rc7rjSXU|eb>7^c)PG|lzq!n{(DQm(@vSb& zk9KJqqq0r*jB^K$_=UYZlw4ACs+W(y`>e;MTgru2Kcjdq^!GdxdcZw?Qcy!=w|pq3 zZ0F}rcw=as%Mtx2+jmypuE##>{;skl&4cYWUYpFNmuJ<@HC^S1`Sa(`Z&;R=q#Mu0 zUA~ooZc&`xV)^MXeix47g`eX==^?2Y&be1ij6?Inj9s%LF&i26V8}L6Yc5&{&x4?i zqh2UUQoq`H2Noj=aAv9YpFbnv`3D_T-ZGP$okCzTt#+)5u?>h)*cJ;!)_ z>*QdfZm6{PXPFW&oHp6;uplEUSQ##odFSL=!U()~+P5TiNw&i!%tM(~5@5*K9Z zqani-o)wtFwAmAxF8AKJqh~)3;4U^xJex5Woa_;}B-|Zjf4s{kk!IU_L9!_(jqHS| zx&|drotaUuBBB`meIqtH8+-(0%%ZZcu9BRe-g*KwLt82l}KBT^!t(=tGlPi(Cd-gSx zum2%v<=UA8oN3rF2T}JIr*N7$;Zw`}!mV|A)9k^w<%x<|tb_vUt93bx%?!(RF=MPS zVQ_i<3r09o8An2vvg4bivNT4QGe0KGj zYUFm3Ev{bbD^k`$^AQN73s`=S6rs@^!kj0KGWDf)O4aYnA!3QV#8&Jlt zya})7c<4WznmIEAeb6uFGzOQb_9mxl%)mH;u{hBR5U81vdX~dRK8@9W-h!u)+eyq0 zVY%tD0xV2Xlf`o!zw*jA(4I7%ss5nUPa)sNF5|PpSH|#;%tnqLI`AK;zW+r&^ot^( zdhjc}hW1c~3;L^r?C|qUeL4hhmPmP$Y|FO9At5626$9w@f!WiB77TpRDepqyx&nT? ze;16?hmkr9;Chl=J9%n&KL2M%WT2e7HC$ z`SzmBqO3DFKBVi6%-fshA+hq@JqS<6Q3lMCumPR8VgBtw-?n;W>OIpjIHbQeYk`>p zIj+AF!LkilY6Nx0Q5!T1@HEkx1W5eUIH#a5AkM$6BB~N9xPP=Dj}Gv*%qr$h8v@VZ ze-9(61bQ$)B0r_b8U%E62%*@26~D)dlghX-e)bCT;SAYKNM5K;o0{^1NY8b5UCMY( zjolmKKML1>W0QVX9Ym_8Aw5LChCq!qP|eycApZ*P6M>??HH`6#P^Pub3bPEnrSDXS zk&DZptsZDh0`Fz_0cW^x{P!q=jw6WKAaALs7XCBvr-O`Mv5eX@<;)oP;qX#NX1?l( zlxpS|J~=aMl``Z?v2fZqS*%F!a-TZLj4`(Zm<@1eUi zA0j+I<9ym_S63~`DT1nHBX_&lJ1M6agAL6*dnvLDdvi7$l0AESN%iCDwE#ZBv~>c} z#@xwcb9&dYS!_n(T088lGPZktc8_uCp58dNNF+`5eJqO^R5}*--eb2`S3W@YPiLj2UiBQJ*}Wwk7o&&gZkyz-i&+tkVAjZ1=W8U4INxdL-+<%O+Hz-tySBUO zb`Fi{^_2kcxaz%whG`#(DF`H?OGqbiBEzxwl1(UP_vz7szq4HJKi{uRuU&#=mLp>m zTj+fDt-!M0RmnRjNuQ>7(2X=)dp1lN8OTov+Y8vsjzmkuB7>OzvxcjR?b8~T#m;TS&2)+dE+aWpGe_C1kKeG z#ziz%R%!Hl4Kl@{Io-IVbNa;g&TdBWnswhri*DZozxLD}7Gv;ND$?J;iR^Oh6Vn@1 z41X&1jO5NsxPgd1TeA|;N|fJa`CV~B6^fNCNgra{KdG79@^mh7qp)Qp`MRaBb+M!= ziesa6FH;<)KYy*FA%>`9NSF*8Ezr}ir$u!>pQ9*7l8~gK4;>$p+qH26J2Brx9}Ohu zO+URM%YI=wJHB+rk*nC~82EU3`HkDsr6}Vm!@`%*S|FL>d)((2%#T=zzP{C zWsbI=5-+62s&pJk6O{+M?ULwHXMG3OW6fUJJpa3U$(zufl+fZUgZL1{ZwS3jGSg?e z?PJ`#a?tlx?r%IJcMM4Q8!KK^)jN?6B6c<6RUaScO zg7j9s5lSf^ibDRb2KjEpVS7QP6;zczN^3sI=KF7g8Jq~8Ie{xv7F`M}#ciizZ8%tP4u%$O^kwKQ^+d>q&E7?MmiTc0&%Kt(~ z2v!GSe$7@uk7=?$@)@f_9C5PjKl_S;5rl6Bh3U4 zry5GF*9ra)2VL+#GX0@03L;7~p_3YcI?}ER%}jFr`E81jfqhsF|GWJC%soTlj)(53 zmCEE&dthNT35Mrd^hs%-HbU*^s1eO(?@{=_O!$ZB6BBb#>r#(@YpN*3j!TSFGz$e*i2=5y|{ zD}vE;hqt4ZgpXYq+6`aed*tshs8<>H;HJIe`zE%AJ3sAO)3$>4t{;=jtg4XniATlS5wTn8xex zoRZ}gWZxS(?Qwj3tSa@@EWhpd+{n9(08pUX7OP|W!ga)Ot71M+r9;wo&E;0wmeK;r z@z11AH-pY!x#=7oRLJ8x2Nt=;P&E9ZS7glmh-w}6n!95Kfr6^GEkU^-c7LAL4Ske) zaOvyvZ9a#${tY{EnYmXkPpLl=0YF^Ebw)fS80>b`lB}IPR(C|A22w(t=7;oYX2Q}6 zjPdIqUN6RVeP6yIm>=q}bUgmm79Q37L*0zHU{65L6c}xXTU%{Cks8;q#c^#84D2yx zEmpdR=TT`TiX!N@+8b{g{9nCIXUDm&(TcC1LpqF=7If`(|yUxa=Kq}jNgpXd#2TLEQR zWS^}Q+_-FT)^a~aXXiOgoL#Mro0;@u$Dz~e`XbfAC(b&)u9;dGBT8GN^Kp(VJmthS zgAD5D#Bq*n6ERs*63CbXSb->3_ibaEBD>ZVHb(2w(tZRf%bq$j$f$5a^3cC}^1uE7f04H4bYLSu_I52KcMp?^JYw!&@Pk%4@N`0ME+?M@jKDt&q5oXW34if)?_dxI6ePAh)(jj#g{s3UAy=P& zcbE+Frao(a(<_XL|9**TW1Ay1$QY{ljEo3g765nBaQ(c< zgwjU3%Q-4N#j=Hub67CSGKVIfWQxllDdJQ}BWJIYIPMQ#buwXc=phk{>QUc}P_}dZ z`Y{u-#G4sPo*RyFpox`pxfm5MiH6+s9BP@SxMm9==K9T(vl?+%9M{?kXPh8MrFyKur42>2>O@5)*><8bmdXv4bA>B&bUH#(#4w5&8PsQGxv zN#t+bWYZ;4I;*dR5%QlWw*R)UwG!|24;PVLQcR~z^r*N-ZM)jr+2&O*w6JBHIrlnN zr`xisOgiGPg4@iT_aps=sqO@8s`x;*1uNgcF`LNKm*3NL@o&p+ih{F|TIOAqp&2`8&GdqRT8>UxZNtB4H#mGQq$6SQS>{OA$8T(H(1%Uu?~N>Cqn7 zBN3a86y2GJiqmgMLG&7{Qe0}5w{txF`=TUhQobbrmPWOY#_DOtZ8D9Et80tzP^eg7 z%8nV^1gC;37wKdkZ}(;8QKip=n?FrGbL)T8vdzwMlwwzxKd;kR9s3b^eXZk1$AgQ# zO;`^r2crNe?lP8MKA*!R>~iA>%|*pkDQ``0t*bHN>gumaQ*%3?*30Z9`z0fOeKL&* z{j|q#%5gzrXSo96x=S6+X6{{!9nG}Be@i_6tETAu#I;w+!Xi@hZa`&8%TVCzhZQQzpH9P(5vwv>$C$2!QBYG*oH(hsyl?6&8+G|$J z>UOS!Fl3KG^br;GojovEaBA}@aicl6QM1vMUjgM|BOBp=z12JJYO|7?P;a)&WJuhJ zl#sAqyXqrxhc+(A%xsFk>X&<;jpCdNIoAeZuhE#`&O&j`;(cHFY4W!|kvVb4m@Q!nJ7yvL3AI$JD}V{6AD{@F6L&n4yQsPEF+pUe7z z&YzIFE;9>aCy5IBVdsOYp(FbUGsUgI*eZFW{c;|*lR0^_BtU04a>;y4OWaGV~ ze&i8U!C0hr#qEQ9R5EZ5MvuI(EQQ)^`0ZLX>8pPZl?4Js-X!l>DBeg7awH!dE!kE$MxJ#Wrjo9eE5s6Wm*DvnNJt{md}v= zT>BOvwUh6<{`M{AgprSg+wig=SILhbeb>+Q=%|_#b=xQ5eVixqsU@Cw!Dq{``rS)# zh<(fP_!cVsT$yIpZn+J&>NFEk?4gm!Q8X?g(jPbVRi6*?xmfK=DqgyU$W`0-=3HBa(`Hgtz6Z6$0qtHVdGgL z_EHs{b8JP;q7XP2(R#S4*HZnt&hAqi6g^;$JS?x(R=5|lH2GF8JuI^~O;4pPi0;}C z<_AFy7e}K#W7Tg^jn~*!_)x6xYdZHmbbTp8!S3UUUK8Cxi;ZZb$q+#_{`=)D)8Ix< z&Iyxe293tsV=*OR^z=u6-mqcjw?Qc-zfQqVDTkK_%{_hKcCaq)AQL^;Uqe#imx~*D zgzI2O-f=g00ksoqU9X3z^J`#C!I_?g&7r^8RAK=HJ?rFeV2)5Lhk?E;7xKvvYEbv(K zN5}~X1bkH)#uger;fAPw9z|A>gu9tSMtM5=1JAxr_N-LJO;dT_XAJ*}xMme#y|7!p zf2xv6rS$*{%aN0MVxD>l=o4xpm$^If!$f;IjX}=~<0}D&=o$#Lzjb(3VhV<#x%%FA;bbo1ZRWiZ`Z{_3Nj2? z2`~xWRTIrfnmyzEcq`q%L=zQ(25&kznA6cU$m%%uuH`l^{{*;U|LHOa-Q_1jwMSMH zm117DDQF6{y!!6g+^1GXu3;B8R5)O>O~7TKbFunTB-$1U*#9D}TmwJJQqMI7-U4!P zX>*O4oOX)LLS|X!QgLed6~ZEb3E2{dY^IT>Eiyge=Tl(}YG>zonM14Fd5U%bPl7QP zTs%CV37=hWT_WQP;ERB()ewnTfgv139pZr5d1w**OoyzWeL>o{(Ygr(X@&yS$bxPH z#L6cDp*m!=Wq$QOuo}Uhc;nfus~EY9D>^G5@ub3p49aOQ_Ck$B`YeKFR$xD$#Rx_`Dl4h_>S5fYCe@Q{?0UVB^3E)`;H$Eu) zeD%Nr0Bxhv8Tzov38%<@GMVy^4(@0WSWCgYk1u^7@yd;r58_i%56C9?|BFv;QF5nt zshLj~4H13=B6(LGYfx0Kj|`M){tqc+U2z&}b20=A%H(gkv&_6JbE}}E zG>{W6D~SdAggDzZ?fva<6%)T(4E=b!TmJoTG)DKl5+%E;!_v4iueSQZc5SHMDsh`o z^-ZaO)JfUWo-bM+h2ICT0U7v%J0D}#K;NxB!g4tL*yI+M(5RKnQI)Hls$%RZiBDlV z2>$4~66F;ILej$`+eh$!^1!U~;|g!4%y+hTY;$APU7TE*b~R(D-qHrUBoaxx^)ycI z5gpB(98tTQKHTeEeM-}&lNU#QZs>^U-L!ijL(`0j^({%iERyKZx*VB3-<_c;7o&QN zLGWF=`qOluDDyg1V{t1{gXN{YB!-E(A+L~~goaey#$C~*JjP8icJ9?&|1WoPCZC>P z^uO*z!gy})^u0UamGGp0-tBzk{)4z#irtWH(uc4=<%r?m?ban#lY>2vs=s}HhuKCy zq(EXu-3p-Th!6RJr)zQdKq3@A(O-AWUxQ0U1*FF1c*>pIwWGY`@-l* z;lbr*;!WJA{&6oWf#ZJW~L_)0}fqiV+iiGBBvn!?s6tPH#F zs4q$XTIy|IBoyi@-H`&0HvS?Z{EvkDoe#ihI>YIw_&u&?)X4fm-iGVEWH$DfS1umsQPm9-cJqr&C-Y;nty0Ucl1 zD2GV(bkRd3Z0TwpuwH|W?#gucaHTRSZZ1aLGyV5z<2IgFj${(Si>dv8HlTUdb9b5# zg`l@HHK$(5X+7@*Q69FvS*dJ}P6(582HE}cb|StbXcY21+a9(rlRmUXzQdbo^h%rK zaEco2nPq6|yV9>Qk?lIy)^wM;ISiuRyI{Rr30+m%JXU44V-W54vknLbL#U6ZaA=uW zrL%DgV_X)f;De?aa~;DwC3S1e3aG+Z|7I;?8rI2TtB8Qb0g1oW%;evllKM$MRv(6f zjKAh&F=8B@%LR9>uIV4i5&ljx8jbuqAOK{cAi_0VY)f|vQm^u@3YocEUy-(2hyWlC zPi82cLiVs^MocSn0}4U~WPRJ~aa0yr0S}O22M3P@Lpen7XJFO^8|i3q;&jO8uLtF)L#V6H%A} zqi<>t;$yswgHFLK5V#|RL6peQY-T3DRb#-N5V1xVvkZda9J;7t* zf|7JnFS#cd`EZh8Y8u(?PwaEMfIntQM+>3YHpGTR*~N1dVU7$a!@K&O+{zKk@7~ZB zA~Img13x9}Wf}81N1Rk&$_s*4))&0CZ{505wcKs#Sz&7#(fwQuSWnN<{uv%~DIMHz ztT&r-iNA`?YZ1yx15y3qz8;tQ@Ne`<*2gCVf6N1Q_%V(}26I43`cU$Zk^Oik&MnKP zN%o%8F9=?2W!foNub)4^AD$kWGi7>+x+Uj!({Z?L;V=H&lic5$4*PMM+Gnd=PbVKI zsq0hdq7HsC!a(wM|5VOMA8TPHlA-;~y4?10%=~G$VPe1KkLyecSr*!^y@md!MB_#! z3A=}_(Fz)Ia>@>h^ZnnuO=-HAx42ct1*`T7To!cry!~)rus4OY5elU2Li-$J7alkw_xF6>GJSJHC$vW=OYOKckSkLdL~KHhun z5uSDB%H`n@pOG8%UWtikc%5Q^)ifarr5sg$Y}WU3k$OcX0&i&-3u(7%Fe_|+b8)hE zOGHUG5?Qpm{4at(`nAT_##AorYqim7QjDJ~8gfVZ=aa+PvZCD%^xsT=f2ojma9>pR&^ zudi)qPlj5{4PKb)EA|_VT#WQ0*mWloYXC8&FM_3m5~s-5ydwr4&74;-dKO)#tAoM5 z_(|f?mmU412_u|^^TP{tGRNZa_6Xf{EzZKD6^AMB+{51 zqq6P7OZJ5C{+O#u7FqVpyj@Zm#4Y7{rDQhf{lszRckV`8A=}ZgqJ-hIry0p#LBA2b zCe(6t*uO2RfpNV|lee%6p!$zY>h+;uo3}WZUuSR+Od*H6d56;@neMx`Jha)LqcOK^ za?j`HXhS-QEj%j#R`!c|--G&E8v|y80){4MkRm31bJSiEVZA8N*1;8FoXJ6Mm?e{M zw?VQ6g%_+Wh^ziGy=EWwzSB%}(bT^Iyx$N8aFd+vOUnol;Bz9uf*Wd=Kqncy0<|1} zv1X2lKLd!h&`p~f28~ZZRDl5(cBRlTm>{(OH9-+zDm7*YQ_)C`lKTQ^2p}w+5VgA6 zM*_^PdIH40RHd#fB8$fVA>0v{BsLEzMtY?aF#~6?*UKsJpj-l9l)uh5`1{u*?8!3W(! z0n0RV=za_V95m31ly?)UF|uPZhVK_Yt3|RRBesC{4v~HGm^)y|8gyGobsU_O-Nzg& z0LWXW`KG8!V7I)%ctemB1XjtGisC!)#%dPAk?2>sLx{T>Oy*fdaKK@LZ>1r1Oyt)g z6K`PADM+gpA5jC;JMstS35NcHfT1n-`y9HZEN=_gkUqaN849lm&L6++bfK)djlx4| ztsXUWR`HN_|MbX#m7f;(N3n`w&*%$mT>-N4XL+xx_$M5FZ+)5APQ0vu6E7m`-7_dT zkIk~df|T8$bt~-v{_$*|Bs+;QS^Go9cgt}He^zXk?iV{B$ruYGCOycRiLzrL0tWZO zP}QgBSyKo1P@rg6tPAiw8`_yu9g*5|ByDjOA&`k*r#g>{(P3=hACep?(?1w|H_b7B z;I3;O)3R1-I(e7D0MNetPM^EmGFPK}b5}9*$2-4Ga?Tf>7g$II&ZDT;!xq%G$&@CTk!p`;$` z`n-wQM{RwGTXpuappt2Q3^7}Z>q{K9Z7DDk3QQwbY!BdDkKV<&s?Lj+Hg-VtiaRj> zHIt2xwZN*&+{Si~-|aExK(*f@Hy1CCg}yb5W4iWy;HntK-M`^W)QzhbPkT)6uasm@ zrd{HoT{bXGlR5MTB5c=Sr6iYG>~eW2_+puOnxp6Vd&d8*#tu&KMTqO;s5?(!!#SFK z@y}2BvA;ksehg@tzP_D9L#2RfrM>xx!bU55uK4-5ec1f%Nq+2NRtn>~-g4#l%hvL* zl@2?;T+|AGp}AAmX-ph!bYooL#M?!0O~x||^^a$bOX?prxhq<~F)tq0BVIlI_>?|- zjL5-y{d#*GpAfh!!u7!|?im_voH=<#hG8r~QidVoUUOA?wc+{xfy0g=nt{z)>T6>} zWn`6QsvZ2i)CQWa5tQsC!S_-knW_{U9p7@`feRd7wbR?YaatIlS7PaE7AUx|l36F} zoKJ1d#$<&Kz!#q#SqXc0E=3c?dyRXa*iM$ilK-4gO|T;${+hSGe+lZ;Mby{85~W1& zxObE@*e5gX?tfmU{HTvqf3ogGrT)V0uFDPA`wWa3UyhLsDs=aW#y%7EITc7USn9vk zs-S#n8TaPYRv@>Jnzi`2e?}bPN=dy0nKK?Ad`K3ozp%*g>Q;Ev2T9wmd_ocJM5V!) z%yFP}G*pGZ7~yEgJucpvWNg@Q!r4OdKFpRLE(L8jb)g4Uh&XSs&ulYpYJ|Jz(Rmwj zkKyCW2_E8sHovE6O@ITQ*$BcWCd$%|gTQEULUb^%N5Zf~>N^DT2gLrrw!S;8iJ8QYZuO)2*n}KhkhS$M+3T+&VTjKXwYwr5UZQU z+9+~Rz9#9V2!KyDGf`o8{T_1z5Ksl|w41?b02?qul`jC8;pwaw5>L!wBz6eJJpeEq zfJq!u`obh#3#f;WdS`%;B!UwVL*MHIXpjV_lt*nYX_D|rvCja`3PJL0VU-wlmDVik z0%Bho6omd8r34_gq_+C>x9p3rg@Asa5d&wI9v{-aIAhBQY^>WlOQiuR19qoZ#W-Gm zF;Jf!a^@s$03uPJfA+X)G!=A)nSv?*!wtaGS;ufzm4D-OX$ESd(}fG|TSNL6bwxhv zZUe})d*#b$5iQ>Nf>59XJn1DBE0WhTYQ%*1|+HIqJ2dSUUIxMdx{nSBxpB*jD>RD> zL;CpbtRLVzX1PNnV9mfI?lRkjP|G3%9&wO~94zWtj*4{J`zd7X8 z_|=KP9uc9eEnO~EYlS;gw_i%qeY?&%_f9^jJZqa^tg5yW-DmgPGWv=CK$9j}ueZ~9 z*%VLLDkqQc{j9AxR_{%PlKO4mUcvd3(OQw$uX4mOA69-sbc72gzdFwT&;c9zmU`PQ zj~QwlW*ZJ$ZM0VoHG9)IRRS4MX(LfEAGZc&Ae4xbVh;dyQhoqvhRI`&fJ6IV<<8h0 z9_^cGmK1-9tV7oNCyfaJUaOKD5MM|}*WcXghxU1$WKg7(DG^{O?8lmw+`dZfBq!_;Wn$N0%h7i`Bif0JGoN% zJ6c!m_t`79ZB-9zUqX#63ya9RNyi+xxcCl`8*~5;-}M?1OOagriN<$f+jXN-6o3F9 z5Ys?3Ms=-~CR2w0k|yo#9|h1hnk5Gm~%$caa`r|Cof_!Y58Ry^PrOg&_f zrq>9S2Hc=Vs&%6d!>6`Hm4DyzN2Ppmbvk$MF6ZTC#Qa5IiDapUSnA&(8Nz75(ipM zJmx1|(g?}KaqqPRJTqo{r$r$3lz7xmgp`7UckI8u9QXRG@bvF8w-J<6^1`x9LoXi>Hxmq(?YU~Bs)kbpy-{IV&d=++q8 zT9I+lesC0*IXqOPAGd?F<9TpI@Q+Rstfo62S%PC(?Ss6~cJ#xGys5o0>lxrkp9MMx z@i|64%*!Ie*e*k*na4;atWLa6&oDrHIiF&Qc7lYFFGf~1`7qm;cr$|UMM_xrmTerj zVlWtl&A=0PWus`c>RR0@iwz&!(f%_|6{?i5Yi!%(I&^Y+^gH61zAA>c)a}tXuD(rP z*h(Ka4IqnHlw?IB+7W3524Rt`1^|)cwOpUKpYnzWQHMx7RhWs;OTcxLJAd}Of_(*J zv|xOR>Zj6~jG<0~fBHRilQ|)E=KDy_BK`x8*Dw< zvo@5V6U}TqwGLBt_dxX`x>Ll8sq7eVQ+Fis;Jo42^pg1JxGBdz;7w{ldodIoLj)kX zpfCWO>+A%urRD$xr$<$5ac*a14Wl|}@{F z!~vS?3-}%rs{s@y$TU^GABD68E>d2M9eD&EN=8SV9hz>WpoIcj5Or4EIcW8MZ5AY= z?M@Vc?8hA~IAsQqANFytF!tTYZs|(c?DxQ7Ig8_@*Wrmh-E0uWCd6Hw^kcke!SXd$ z1F`e!*?>h6waW~v3g;jpD@)pMftDlIOO5cI+$rG1gDB#rn?`lPa;{`WBibbF8Vosv zB$Rj!-n@tnDd8AuMCTs#z;_fkQ_7bjXEDZSf2xR;vlyQFC+YRpu~!DBkDHDYz>*ay zU;zXFx|KD}Jmg;24gU{BF3kn?4-nzM@O53MsUDbKl+*`Rcj|eJAH}JY(p!Bq^1K6M zy@lVvPuR@hO{oi0a*s$Pwg}hmpY<7xFIQu=h@3#r@nh+4!)79Y5tSoncx!A#zu-+W z=|Z%GDxA@8x_z)%*B!|dWmEZ?_^7YSJmCEsN%$17Ib2)zg~siSkY~`JX0Z1}$1lJr z#S^K!;5$JFVJ=+Z+0OYP)T%vm7#AMD@>8)*i;l794m=V1e1XJ9U35t{b3;_|cgtt9 zem|D#LNh(hT3?OF2)-Fwj}}my82XXNw~ra`s=?5!uxx+m;sy!6o45b6yru5QdTL_2 zj`|n^n-?#4-Cpu?Yq1^OJ`}3QxRO@g7}f3x8dopTxV44rbXOyfH@g}J%ymX^Q^h>Y zMq*-4ZTT6UNnkAeUhUpqT27YV?VY7}30GZ$q6+F^1DIoqTT7pHyE3%>4txx90?~r@ zv%GXG!87u4%We%nlNf#VAPadPjE$#Nn_9noUv@jlP|{s5`eT?$A7*fP7&RZ7^f?pf z+$PdBy7otO>`efImDh-yym7g}Oj2hZEu0WK!%H!u!2JrB$TxMUDF4K8=u;h1wBuP< z+Aiu}GIK%hcdLmHZcUi5;0cyzH(!4Ja%8dg6h=ltUoj=SJm%E*&4K<7{&xLCr@g2K zwZMm|Vs#+)7M20yL~wTReiZG7mE3b;EuZPquf+veqe(4d>YIf85dKrhlcEOuDG7Wq zj)hbFqD-b!&u(=CtO-?sf8iqBa?-g~`Q&Nq1Q!hg`x>JA1l6LYD}UGM88z9Acw5Dl zJ!Hb#r`E4309^ieEnbYd;1!ONpjyl@bN{ksTXKA3M$FShvyab(&6c8$bSEcvh&89X zN8j&v$7WitEvz<4QczJYOw412NbMrjsg`kqQ`%i=Zv2uJ_vzs$>`A|QWBuB*Q!VL% zSAzr`SjNoHR~p~`OwHP;zI6R*TdpCM0coi(-L#wdj$;vV1O8FUXJfn7_M4VM(blF( z>T0h_c=5z9jO7taly43&&5o*X97DlwQ&MlG%k2}TI&&mJQw+JIuz!ScAMY}3IP2{u z^!y7mKk$?7p|z3&L7x}dpwhh3%cHx*lRg1InAq`eOWDjo-!4z*whrck#GyI|#hgCU z^1(xjqiz=3Ral7UNf-fVj zq<^`d^JevKBT+aKgiQuY`%)%9lWu11lQ_r<2jp<4Juvm%%nW_au7sC>wwdlM3HqEN zNytXb{)JiFN8iFNgo-52E)0T(woJ)Qp*j#tHFrXYgDy|+y5>^LWbujsi=eK&BywVnwKfTq3E>BOVoDCF-44jaDD98g%YvU`htwN^Xjx6Kr{ zp)UR@ZL2tE?XYzi5{x8ZT7ZRLe@D^XzO|i_?EuOS37SK^O6g7q#0*AkC~Oe5rOh1m zh=jJ<@2RojI5;aZn$BtfX%6Ur3yqrH`jbvB z60)M_agrkI&I8*TTsi;*5;(6i6Vyn^dXn#H4BMl6Opwi}$2pz8mtqYj;FV)E@8a^@ zOe2|e2^tht)whzGGmp=2Xl;3Te$9hIRlqpe_w>a`CQ}Az zPTIYNvbr;Z`AW*na8VKq3yTarT#=3Ydl#MC!)H+q!8M=UuP94C-dl3>v3>i=jQk;% zI9k6Y(}1G!dFj+fDU-7E`_|VO&1Y(eDNXU_J=~LWR;%&GD*dOFxK%~BnEa4plR@Q) z2??`Q*Dw3nxz>u0-#$K+ZW1vgzo;Q$aKY(1@mz=M;ZftBXqwq490=>Jr?MM%bd&BKePtpqa< z@GJB(OSwRDAQW4EyjV8pWxFRsBrO47!F^7Gya zt~#E9`Dps^fUYI?()F(@>oJU$hcBhPN#isLJ2mX~**hx>uk-^}6b&iuwrUEpB32Zc z4crt@Oc!?_8KTT|Rq}*t_Ir$uKIq=sNG!WGzImBptm=UgThaPS*4UEeyn}q;B7YC)x4YCx@-4{1M?;&ZKJ+CC1NGm)7PRY z$W2S<<)kxRNw}Pnh}ZlGeWte&uOtxPvUN2_9R`IW$;lHT$TR+^b)YF={LRdl8WaG3Z)@2rPx1-cUQB&tiAoS*%@% zQ3GrO;gcVEyS%+6lhAM@{xz@C_e80Ak}H=b{-phg!$)XC^TT_hXHIzWp@pZtHk1@l ztwp$sJU#l806bjIlHz4g1a{imACdl%WCjrG!ePd`C9$`0k;WdgHI=8EhUMP8Qa7_~ z-)uIoWu^! z%X5Tw29b8Bug-7%Ed2#D8S0xWa@ad2EzglmzK*r0sY!|)^o`I!=HJCXV!8y#B7c@e z{IcnDoOBSeL|jslzuI@zYr)Hj#J_R42UjDZ&3oq`4U}0HpDe7HU&No12!o{1Ep=E_ z6$r9h^`1yi0aBH}o>1mToFevvZ%OSRhBlTey{!-XyJqa_vK4MkGKmk>-`}jgiwJ6` zTpHZ`+@IpPZ23bHCn#0@I^6T}TfE_JDz)mefYA871{F_PNbpsp0{yr`nB}UsAF+A% zx^D6H{gbi01 zgfW#UeiV!77Hja8o>G44x)7Fm(9ZH;4%ua#mO^pS-0NkOyN`w47yI$t=gT~XBjOl? zaIp7npLZnJcMeHMi@H)TcJ-fidHk?e&XD>sD*W;{>%GXjRc5M39|dzK(#stPRZ;l0 zwNsvD4Yhr1&!4t~cMmVmjJh4a(k8IA7ur00qyaMkrgiKRZ%=w1zrhMg} zJK^ZQKV&C&i>%B~)TRz`i)d`;1;Rznt}S|wtZqB#1LGIq#k>{Pz_qS_0=mA z6SiKwI8or%OQWpdYC95&;y@O3eXUb4ma|$KoX<-%-uC?CoM@@r33XsNH!5|{%MmfK z2eQ>H5MC!mf_{&dQO92~B!3fOBhJ_9mbOF{%8Qkn+s*{l9JtJ@yg} zA>NU7kAB5G5Z>zNWsY0Mp+o~q2;WYB7qV7O#f29B%d`yNIhj2uv{iWEG29a$U*w|S zK-fH8WEtCvBgs-HBOT`;1+AqYDS~gHTXy$PNXFMDf!I{#5V$Ne>b?=Oyt_Te)NJ>Y8p;7;Qiqu!;H=V`?j$w4N}JABj9X>lN}`a7MVeX%SND~<*!%`gH-tb z^i;j?+p9UOqhf4xs@Gm#r#eP1tR)lm8jjSM7V7us;1quT`x{A<@KOSW&N?eWZ9AC} znfs6LN~?KSTBK0Y9puzfOY!sGH4KvaqwWdXVs=wlBR01IC49rXncN3qPjw~dxU>lW zO`2U;Ik#b92TMVQ+#v{4lU8xWe(w@`xaAQ0N_pgyz!BN?-Z-js9T?jE^U#WQ(zp53 zhzkIajm2I(<2C^mUHDH;AXaT${LV)WO1KJ>$Aa12r~64wkig=bt+EeRLNvz8>icmt z$>~o~y6R-R#-mi-dP&h@vjbCw==4Ie?$x?w6^<(o5;a?>gY0K7)cyNK?nkU|&f}|O z9On@$8`AzuI!X8K50YwTJ(r3}*V-65S!nLjl? z?eik&F`&nt7bn`T^gt&+?N2&)_@7@Uru7+}HS`YI^Ep>Ek9_)c&N)R3Tn0M%5Q_+3 zeR#%TQcLbkXPha7o;PGo9fqFMU5-Yc(`BNy+0Ml4hjIu-JLM(pd67v)1@!sXUaO_+ z?eqJ3<)^uv^-sZy_WanUL-s%Hj&uDZRvt9(fn3l!k8zR70G^cV;^!Fz$M`Sk}a3ww#8Eh=;NPH(xWq z9&Zggt1;yBF*pjFwMAsua9v&lj`_83ng2Sc%Fno2&B$-orViG2d++U4ZD@i_)wVK5 zrkmv=%{(2NufL)Sw9t;(t;TXcj}9Y_hVd?VheRJH^~0E>2M>q2i)#0|*zHYTxgN%U zdSLpaH~!0)8}AIS62r1;lMA_rSY%@gHrL3i>lyO3Ye)&+Uap_uZSj+r%QXkurM`vx z3P;S{ywGzMNINh!wI1lWJoaY_weGR4u#?SGQoy!RX(wcJQg2b7UvHHpE%e^1!e(n~ z>cil0KH|#rYm$Fos~*oL;o82X29Q7stnR_ zKH!s-9QW!Mp@=Tw^qtlVxm?hz3stH z*rhi)D_(hrj751}712B2YExowIrBuc%G)PSe6e|?8|dw2^F~iGV%mR!Mc$|(;TIJg z0^JG;s?0O}M*GHBg6H`VKbwE~v~&N{hd7!9bJJWkxt~2KRj!6<`}B!I^G6x6?&%hv z3=EV)&8}Kn{Di(Nnf+~k)$qm3$`0CS>Q9vs{CrjKW+dN6&0M-P?JV$nU!*{y&}96} zxClGjs}HQ2LImq1Ih>;UV=v_jbJv#%Asu;-K)Pj7QEjcWaFaV6#hv9}hPM~a_}1VEN_^qnHJ?dJq6qTKbkf*qFMH=Aq) zmPe`EK&u0T*(!Yv5T^JlGv5p4%msDEWso z0rz2vCA&`^pZD`MsUr#q*H7;oRdIiuaK%}Sdq*u6riX{(P%&#ktCyoW4-$MI<3Nxb zJRg1ZTpIJ}*`xEb%l<%#Rh1C-a%onI!WsV6=55KknNjfEA4i3>nd+C>Z0t7BN!1uZ zA3fQ?A6r|ZgA>(+a;XxL~csy?ez2nGU{=ykJ)I@+$JBm z-&r%`+221xf?@pqdUq;bm8P!!WeFA-dmFf~dMRV8r8&3ncD+)ie`sN*D79qUYs1H# z4Y<7YGP6borM`-U6-CeiIr4^hx^-K7LX4b}+p^NV$iib24kO`jlmCffk)fB3?ndWiYi1CVfo zg6Xsb*F)Z+?h#&@>l75_IJ1`ql?QHH3Uw9^ruGf?pI^Pu)4NcWm95nF0`3Co6H>YS zP|ecuJzNNF+}&*Vz#wb#!F}h3Z1)7JmYcN?25bC%F2{_UasE^&Y2)aZdi;@X<{PqH zRxob=s~GpN^ORTQ+&|)1Eqzp!qdTpj9fw$y+$C%BwiCJpKWF-RU7CqUnq9fV6H&p6 z4DnCj@V&jQ=S-U|mqB6XhF;j=Z_*yZR|Iw_LVg-2rjSK`o({W;G^!E(K>fCxy5w-^ z<((Ox6|oL5{$~D)j`r%^*Lkw?mX4;H787%WH*_kL<5bHwKt5lF;KknaYepFbKTWFd z2~H47Qnegk8>(Mywx)k2nbi%Nh};&OytBM>suGZfIbWM)Yc_AaK3kgknZGE9i6Hn=fro*FA4^(h>VokhLse4 z8p}VtO)F&Y<{ld7;%A;6W_P;_A(Xv8fc_Lx@;AJSr^u*+b>iT!)F;=>d!%E z@9AygS}7Eu#bMklXjadCWT;KaB@FttIoDjl*K(*TdO}Y&(8%Mbjncs5l6)v`}z zBX$fUW?4)jv%?)&;U|Y=?0~u19Sin<7r%6;W9l!*$ARx2kanalR6?HR ztDl7K@GkdcOZ{Q|-Nw7+)}Nt)zV$q)<1kz|PzS;|*`xxPjHe_-b=jOCHN&#tzA~3;Vhp?3tsJ z_yjFMYY^|8IGd~dBRbh(RfLOtrjw{w&74j;_IUaVS~}(y46b@8Q+yL~Y+r%RR`7~v zeJ#5~x@{0&wyXF~HGJ$xd+jrAFu8Jq`=Cf4_o3>0)O;yh)oW>sRcJ~&cE$f&(lYve zNXgFyv11RV{*-sjTb9FipX#$1JANni2Pa! z!(qr=lN49*`Pek#ulm+9jTpI+UE?%VI8JaIm8QGi>OghvnmXxmryK*%EZ_6*@ED0j zc$PNJ-E3=9F$ado(EMO%LCjx{&oD+1Hs;wQ?>oG@k}im1?zTq3XE|%^O#@c+z3=Q+mwv)O4D^zi@Dm`p>oAC HCLjM7Oepl- literal 0 HcmV?d00001 diff --git a/Documentation/Images/endtypes.png b/Documentation/Images/endtypes.png new file mode 100644 index 0000000000000000000000000000000000000000..9ff57aaf42b43954eaddc90b886694ff3fbd6c98 GIT binary patch literal 8551 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 literal 0 HcmV?d00001 diff --git a/Documentation/Images/jointypes.png b/Documentation/Images/jointypes.png index 19df862b4ee0c070e6e5ec09e9b69fb02daf4170..f13642958cd4bea058c13206cddf8d1760fe9bcf 100644 GIT binary patch literal 7899 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 delta 6436 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%0AJ*6QIU;8 zp_o5D%7QOyoB#%7Q%8>ln9c^g;)usMe5o>tSqcXQMN-~4CsV>a4>!l9(_?`K5x=!{ z^`^!9z+t+(FjckrIJi(GYh(8Ub2cThJ@eP`sx$cX$?^A(jlEi)S90W!f-TyKV1tfk&)DEYjB{AB+R zzpnViFlD_z%jd6xJxhPO=CNn4d9ZZ#zLoQyetIg^X0)okE-}#TIIXLvd(n4~KRIqi zR+MHU7}P$*Bc!HNYwa{K9AN`FbyUTwhVbcVVT<7(0-|~JjwIE;7*6`wD@U~#q3Vt`#95Orvs7cY+o?Lo@@5X)A%V{?#5Ri*! zNOtUnY)vAG^ayH90OQR{rm*F|cfOCm@6Z2NfUZ7DALst>OkF|MJ110Kbs-PsEa{WW z(pS$qR(|g5WdrQJE=(tApvKqx4 zAk^%;O2z$N?&r1a#I@Q3cQQJL6r3bcsU$EEw>kVHLIPtuJsArkAs+ zi-j84(AIP4T=Te$;HA@b%>M-VxWt8fj2|9M@i(5Rhi-VWoJ=R8gRfK1*@b6Aw29Zq z)Bpn!BX;vKXPL34iJzrbLW0l~NVuYbm(bTqdfQ0O5S=7^G~dzJ%ie(!;>`#9zWi*- zn~&ry(cV)a>G|sD&mS!Km%925T%ZGE+dsY^^5#USgaKwz{}?qpXBNZ&pnx*s8guob2C(k`4 z$Df{jpZ2GbKA}6G`qk)9xH`E^Oc(`yYv*^haNBFT>Yx0BnlV~F;;yw1U7b5|BY!;p z@u>HyHS|!gpvrfTX1zB*=;h1}4}TdK7`d@q^GpET{ytI*4V1|h z3QmLiC`8i?q5!@jDy<08#U)j?>t`iZQa$LpOP85ZLT1iP1OI5+`YP5vxDFN@7|9e&biyb3=o}?9v5J&8;_d{8Jj>Zo+EzIBtmm%g#G8s zx^4iII#F^N&KMnT0G*vGYJ-C59P2RmILUq`m6wR;Ab5joTL49r%*O?jWA8<6m}2C zl-;0jAKdx!im{8HTL0$Zien)!XD=B(A7`5qn&9K=Z9=6IuE$C*e67AX(5PH^bBDgB9ry{0Z?cI3bvpRM@2$L!-%kDg*ZDo)o%~fn2AvGUo-rnR z)F+Eq$`x>fE2I5%XUs}veJ^Z&bLDo|V=r%fXV02vraWp!!e_8A@nMm?BQy!3Oy0k7 zU-cc6qUl)ULV1^o3xL6Xu0x{C=8V&pj&4!@s8A{F;$(Ego-S)(w(&h zj|O4kmczBn%*kHGgX!XmjrPYjSE!j)C9eb-9jmgzv}8pMZT(Ndt6M%^@a;q1F5a(9 z|Hs1NQ()R%9bGEgsdBO)Pg``Z>hHJHlfGR4!5IsV*D2`EdVjWAUkUaMcy0FMcmZv8 z@w&Rj0-0Rq$Z+&^^YV4~rcKX6&C(u(!J)Lw38zl zo7h)+p^m3G%?(k{RZNZb={JF{7AP?{uhDu96!i9;xY#y-d?W_jo>L7PJx;Elm`c`t ztg!XLc~*6-rv*W6QnXidhtTxg?uNFW5h(#}>|PW1H%ahp>vK=DSYvW@6Z-*EeYNbZ zm2?03{jm-2?frtDZ?q@&{e)UawuHMyCL5&kgh;Vy}43Q_B%p0Y1O3)-ArzHU_ z%Zv2k@q+RjgIv8ReCXv!7DRJ~N&%%3nk7(WV+s=iEhy~QLAyj;tf zG9uJgw1VmJzQ6COG_bI)Aw9i)ROi&eY$?({=#awR&d!ofZbBhBpLfFP>_-PKmgE?s z)(rIUTQ%=#=wZ8{tD(EOysh?uU!Pr;eV38rE7Ns}P(%b`!V?p|h}b(4FCXIRP27Wt zpDST1b6HOuvPst=n~9GP$sA9e5@jqzq^F0patODZ$Rxy-2|XhK`ED+h*Bb1)fu$e( z&4CQdOx@MsR<7~Gv$62`;$&Vw0WfL^oyI{ztnblUh2%>ANkCl;Y{+6 zk@#W6&-Q#DMkO+sb@E~x0wvr4vx?lU6q7Wt@Jgp;YaKcT2s=K)lP{E-NOFwbcs*3M z4XhLbgW47W9I3yTGt8A#*&GMjh+CEt#fY8H!nshV=)8u3wYFKOcuPCMxpPy+`#>FGk;oz@lY-&vAdyy{>|Nc^&q z3$_;KKELUmuaEuY?c#Iiu-Ws{Cq?*%c)NOGWFu$(=}%RDCVZl-16i% z*XDRe4Py}X{6 zoorGx6&C3B*7t>Y1NgdNLX^&;Nr3n(wVW%p+(}vbTiD3uq~I)xa;Lid5t1F17R(A> zwQbF>4;iAMR+r~CzLOD>7Rm4+O7HR7$7 z!upcsKfaXz##U98kmcgxNa>ifu5k~i=i)-We0@puRc-0(!~UFRw&J4q_DS!j)W}I! zJ;T#wN$j{K@1CgOH0~-sw*Kt4pYqme9L$yJIzMgJpO1b!BXzuv(~b=}R(NRpTWdyT zzbtpuZBm_>_7<}V8j$cn_odTsbQX?r4ea2EtRXPfDc&rn>L$J^8rUc6-*J^FY5s&L zeSMKw%GB8G7fHcl+2Kz<`Pf#djs%a|8tj^{C%A6{7h z(OIh0(9^}^#i@@!IdM6iTBKK8oe$U*tO@C`4^6Zo=f$ll#)l4vFA1|Emqn*gfW(9* zNAPT057#c59F5l--{h~~OGS_La!5B{a-^VT;lwEQWKkS;_z*wXi}ia4R{&q-mC$fd z(~@#VL}bnSV#VdR4>0?Qa;8KXx$%@UC2k&6@a7Rhf?Y|JQ~s5%IS-GurVsPrYvU7d zYf)Cv%M>wbXHWO?pD18l(^W@re__k2{CbKIZTYDAvr;FTdN^k%!tGLT3t?0uf>?tX zb%D3t+^APT0Ak^iDt6)J&Y_X4332mW816y=`%-(^+dDu1YTqvvPwn&w_8>0K#8J0N zE$_P0HN-c7-$6{^y!byYCTO5Qnh~+ z(?#tqUA=b7TE4kC5jqb7e|Yb#xIc0!C3JOAkaMR=asbUMF(4QnaBjU~B9QEzy87ik zKeX>H35$uQW=dEg#NTCLrbJCTIbytYmPA=7JT3{=8}4@s*zfQC>WjlawSIiwUJtC@ zdbR!F(TbDwo4)>Q2?;_;@4hRClY-(@8d%S6T)AzH;gfpYbwn5$Zu&*&Tb&Y1<(m)I zjL!&Ov0#XDL+H$L1KD}9epy?0YeBKlvqhQ-_r`4@QV})N15A#i!4EqRK!b?aM~c6$ zBEAx%oEMe}Mgc~YP}GM}#sxNpj?SQNb~~H!B-BiaL{41Xl`|y) z#NW+3eAo}!vo;;59v={_kEH_RDL1cCoeatb!s{jsz1I@>at8e-_!Z;&psskde16y4 z&rW?Xapj=OV1Y!q?P9LpgUDqSofR`@uCcxol0+*1Q$M2@!=4f57alg5vdjCL`7=f< z>yId#D52nM2cK{{V%z0JL6$|$B`saV-I-)ZlPd+pGu(R43!+3%m#Vv|`8=kBpO-UN zAiI`fHE6vU*Fa}S2dZDTthKhFoO>IH2fO~tTmP_@%#m#kgre40jBq}`B!bQd~k7Ql-*#Dv?=F1YfyQ%Q;)xks9X%9UGTn;{*?j z#kdA~dsx*PT3cw2@!Dp-zBX&^-6CI4CoA)BNNVamssBB3p_LusZIm1l&vN$Ih_X8F zx;>S%b0SpPZ2%#M^P88=jI$xTDJ60_@z7mMR=nx}03_Z#zV7wn=F6vE`CFq7ot8so zr{389F_dl5@LAOI9fL9YBdT9--mBYFLK1Y&i|#1irz#-SmO6F={*L?WiMIHK3YI1- z86JmO*3iVAVeb$u#7B7O++V?9QVm1#(wdB^YUE)+8fMl~7dB74>qNuE%#aoHZID%B zTQRPIJ|50g^`Va?)rTq(N#w0v0w8Q&kJQ7BDeddW3xgYw0D2e^P zyX1$*N5^F9+|AX|1seG8*-v{iTu5#q86W@9sO62EmXXmJI`JWP>F!7;D)x$H7s|R8P1e2o zk70JPg32$wZ+83*OZ7BMjB6mU@`1BW7WZ%A3#F%v+S}NoX(L1DjgO?`x|(MGh|~ZT z10-%DqJllA8j@qY6C*w0vdrpzVd(N4?A=_LaBjtw>`7T6VFB)j)d~AUY3=Onl-=a* zVIBU+t;7)!4EKm+Udrrn8=Mvb9+p)Tp)zHY1_yh4a;}n0pGzf|D-5CfHA`0+J|K-k zPdvXl4o9{{ma~Zhvx^wp6b@jwEpPOFj!WZ`l#o}Nut#R+bpz0)Vtmw10HBEf=%Dr=?9nGCWUuCPg(rON#AWeyY zk*ROJ`bYsqMPrlZU)N7edT2Srf=(B=o7JBluJ7+7b$3jP@^Ev6bJO@VCDunL^bhiN zg&T|vX6-%QIP+>ZKPx53&$Zx6J;HtZ1u)an*?Xp>y^|wW^`iqY#!rU^xXm3Gp?zZ3 z>z=Z*L~ZSX+fCvJkqFZorOj*j<&j_LH){_4sD0S)59McZvL2Z010{TL^fNsIy*-{Z z6wy|wdG&KD&*K9k>QMnDAo+6^iLd|VPDJ%yrcfh$IoK-fobVK~@f2bF$K)71tK zzz2`jw$}W5h)EjgCR^QI+w6}Ly88|y;#=?E)2gN^< zq;#s4@7M&x`qR+eT-I6s`y-$0{@BZv$}Dp=GR=6ZsI8)&$FRi|ad{p0j!A>&QD`n% zjokn>5&oH22e|Wi{T(JV$KG5qRRiHVMx^*dwcwx(>;~IIw~w({ZB#xF@O5Hl2*Pv& zT^~#obKCToE|J0RS89!OL-dMer;FMh9H`TS+YRG!Tw!*~~cYRbtqhD05n@0P@gj_cj#ZRex{iTb%A*C1#|X0Y?Fg7F_Pk z(w|Yie@-KCcHs~jA zDKQU4j7XsvJK^PY(g)Nu^MTH_ZO{0O;81@ze{UB9FZhR|N;X{v@z;F8hWY3S1tMP;a^_f^7ha7f2Oa=3?)vEgu^D5%8b$B2hTQ} zxU;mcAEw#1F*%HFbEnWO-pZRRX5;wu1mBUV0l)34pj)o1U-_}ZR&6&00CwDICp9VB3tD&Q|GM=~?Jmx!tPdW1aHu?yu&3J47TJ z%QwEsr_L&K1j(;aUm+BTdzSt1+;f}W{C?R-4~{Wd;}2_P0voD6@nSi8dpMag|ADjH ze6Si1+9tuIN;m?EiOIvah*)AO;F=zsmsncey>@p+c5*;WC<}hCvAt*PuppJQ!ToLR z>V;dA%ll`H4%5f5*4!Zkh(aK)n%A0;83L@E80m#r99ZJexn`Ct6Tf9*Ij^<=zFOH= zKqR3UEMX&jJe}aK-CY|R`EW|CigxThJ`LBJ#SdKZX4JMh!0oge@C$hUTO z_DgHs>YJ`RxURKAU$v$W}iZ?jJb$ct9&x*GjnyuI_Iahc7L}mW}j{Uiz z;4g1ipEIxS7!f_p_!(MPybl9?;A|5t@2~{DRR!>VP`{aD!mXj+(TLTiYjZ@gG| z{m`_baXv6MP_v_jE$~s54LsQ6nkK%Ww+}-WQD0iT@1(2{0}B|P9Px$nu6t(tG6o1_BHGky{lP z?g5Byk{;UY?HP2gw&-Sbp z9T}#P&)6sHzf#Kq_=NYfx%v?$;~)&8%@2G1#Hw2W%?a^$#R~)CkK9U{=a}kRX2Lj> z_bc|EZn$r@X3I5v8=z60MF!f4;QsrqSN{D_hVkPL7I>3QQK4Uj?M z$dSSBk-_op$`06c27;l3%4F2|)+G{|blRF__hc=)U)iNyQwrDF?XZcshxaW0$MWj1j5!nB-OLQMJe;Y_RVy@*D4!YvywYmU{xeOmOI|D|X&=?n z$H&7dGs*v6+m?E%2}dAxG;PlB77^PRAt(&)xLN7*r!KZ(l<1qv|M<6}CDUS52h2$H z+j+d6DkAHX!-zt~5o#ONE9}4fWP@e==fF`g-sq2GOjc zuoENOQ};B?nghS!;(oaQef5p9ei=uojHyyH)fu0FG7MC!jL!&$IRN&KpL)N0aUL0M zrUtq@5gwm-TI)%uW;n{`>_lmB?QEObr$&$HX6w0iOrhrpuroHVGpFL?J*H+ zb#f^7VpVI!%SuHBxSBdL)XjwnYg*SLz!0368DfC+zwk;YLQ@M0iw@^E$AoI;&EQ9I zR@@#bA`Ov5o;k!XG0IClWe4vUPmSGnv=(qwsOa zyjM%6#qK&$FYoUU@}(Lh(o4?>@u70`4v5My1Oc}YXX<26Ywi#tbj&h;{-&aV$8vMj zo+5|Bt7dfQDen!rRoN;2bjV5zu4VeD@DF~uuwY`;w2`4OE?i~5`)jLSJPy%is&*G2 zhL3o3+)|D02cKTgtYBYOq|F~(lYxJ~-h64+m~egT&WMHNa%I5j?@wA=h(JhKCX=Z# z7=&wlK|-Mf!}YC#%0|9W)TbKsPyoP$gb2@wpg|<-c#gPf+Q%uc$cRS(x1!7oZ> z{pPksxQSvL4HQe|jtqO#F$TsB!Y62;fqmxWL~c1;)6&@sEm|=@@s}Otb*+PD$q}AS z9~IWv-n0E!okp)YY%ILeWkCZviBt~HX|!_)23uHw8(=45MJO14=xV|lwV3(jUCF15 z+v&+$ggvk(*sYr{p$dPw-Gr&bT77%;k6B4mHF_8^?3t7K{$%c5jfd*B@9q6_61E(! z1;*CtUg-1T2qcsa3{4{^50kO+W@LLRWClKz$@>rIw;aFFHYX<{N=Y4}ae9D)Y@VdD zkyl#Pt*lA+1tN_OW$7f6JXY8`dT1bEvrRM*SPa3xt=6AzfY?R@F~SlfJxyfbHBm5z zCJYbxVnd0YGKwI|rA6)C!UNrfB3Ws5w`vs#2(5!7R%wMQDyr6K$!5-n-5k4 zf8ytWJmHW-1Ki+3q0F>{!ggOT=ly4zsH|Fx z@Nl6D`L(!)VPei*>ZolI!2G@Xz%YFt7z#-*_QDL|anLIz!xDYzg>sE)ZD937`OOF` z=o*?~34TWknzf@jxJvvrx_pmEK$HbB^TtKO%3rr^D4U6GG|=6JiO|Ty1`M==BsZ^d z^%GgGUA+jv2*r)3d!1)Ul-K&bmH11~+yE=4Swt`cJ;!gEYez87pmhh%Ho+m+H1j8A zQHFf@kU^z)fj%xGn2-K`qU+#%QICQs;sXa|Cr=3hZYPXK|!dz_jJRxd{h$pxx5MWIpXdB!MGQm12QMSm-=&T?{dD0{4TnyXypefrHcJaiPw)k< z@Ylt}-ruj__DHz`36un5(VImv5h7wS-Ne^4@$WIG>8E94B_&}}l-I=ywjmtL?Iuyi zs%AtI($+_^Y|tzLcl&g4d#{*ECC8;P9PBXY@n#sqHLAIj8SJf|q{i*#hrXJn{`Hpw zA4%;F#fVgPk8}HdPo?^&<#pW1V3uWN4bw-3|GKjrpxydw)F;5Jf8mFu&t7%P5W&H`Z{0s{ocL`mgh;MZYdt(=L)Ew-|x z#od*uQ7@t{LXoVZp{THzZ|D#T#eIFL{i7!l$+cPE{(fSCz-#@utt>pqeb(4;bs&mS z)WsEl{LR0=>RP+|nO`&#wKqNbU3Sz!>Zxx_UIJCR>?VJnGP~1819XlNU^kN{{!|2o5p&aZ6u#_KnIfibs7k|G!J#{paNS zRi6$GON{irdaM2Io0_`gBRmbzv6ypK*Omp~oMC@gKapj{@r+AWlD|;Ymsi}bQLPJH z!0(a5N$Q*5!kMD-*iz~bDnGpwPHmZ- zJ}x5|nse{0c(Jl`!2I!%hFfYH@Huheo-}IWC=pb&G2(-xg)NJx#t)GO}YoU=v9aCW!1!+i_#b@g;N1E{NH z_sM!7D8rEq%iVk3lYdS;^yy=p-WVO5kr_Eu$4(wjrw-RFUSb}XVTeRj&4E(n z{qo(#hhN}ccqq#`!H%~py^NtLp&zb z!=#A>AD>53?wL4zVq9dB&d+}=%5_lq*xP3tKa>fAt02m##Mjda5D{R3D;SiVFm=rb1xmc=YRj?NqEb% zmu&y%4@p6Bl;=EEMrKbW%Bdh2G5|mLz|16npnwZyT^PQmJXhSz%QYM`)(nzT;!bsv zC>^;kuo2H}f9sP`&s%?2X~Fs5Ebf*NWu6*6RjzML%KH_7Z?O2Z@xsm<_gCW$T|GA? zJ9Pct$|cic_0_3CWAThyyLyjbXf=ygm)Kkb3$AoNz9{M7*=D?qYG9A3?`-KczCAd) zw|^*{sLUxjs$@HMaIn98wR|ZoKr_c01Mb9yRt(=eC)q&#Aj#3*2hTN|m6fJ00I`Oa zad}*cpVP8$pZdFK*AwGbd~oMWo-S9Rb$KI6&ZP38wFJ1p^nnYjN9UKADpa=G7*cSO zjMVIBQs3PymWk&Dq}k-g-dx#zvH>tE_jKdTG2y#T)b}f>upDZsnx5$IS8T|wnmaBM zfe-xH#R_&*FzfDVv3Vu!wBf^F1l0%6HR+t!Q3+6}1who68VEyDQP0gz_J43*BH~n| z)P^iq=2W#Q7FZhKX>5VvhX&p=GcHBf3Ok(zTH7Lkub7+_;%#*=Xq7lA`?LWB8Ysy% zAQkmI18i>Wj=EuMpX!ka3;(q@L!Bv*D=1Xq1aLbfd*+bj|<35 z@^f=$z<0xJn5ZQ5B=y&uF8O#m;W{Smg$1`3Yo|ji2U^!DbhcE8&z#F-ol(vzv6Rp4b@W3&l zW)O8=lb|4Sp_#Z2nin}$S(p<$+RodJZjGk>rA1SstDE>hcSaANSJEMu_Zyh^PKot4 z9Jsc0_IC5ck-^5V4%YK*X*;}`Y70WUWi#XcI#hGll!1vlL<-R%EY;lJh4QZK@>iJovYgs%w>v08=6U)VCB0-R1f4X>fohM$R_wA$e77se$SP z2}t_ao#nA%iIcKIaGmA#T=**tZfu8(b8%uQ9lb&*>ciuK?s>Q|@kHNxEOXu7%46qS zb;gh;(tcVzo^e)*kzRlwaJGmBO<&?i;9k?rze7(r+Q#k`umzKbClKZU7VvUq{e1r? zA8!5jp~oKbwT_NOB@$`B<-|w!_71~GhwTV*bQn09&K|Zu%ZDoG@9EL0fu@TS(*ej( z=S|bLvs{5hz2ezQ!A}JHx%G(pV)W$h?9<92x$$B%4FmuP^u1=Kpa#&r^JSfxN&bM8 zY4N^z!O?XqXQhBEfT|I0vD_SoM0o)QsMMysjyo|c#3rl27Rb;zpM80a$b5BAYB(cs8*kSePjbaqTAywXXpQtA|heD}{uAo|5tZ3%6rfeePdcDDPR zoXD+5YDc8_o3cg>n}moN-tT(EyDCvKr5hnZ@n$*hIn@a8jOcFj!5TuTWf+EdSfIPg zd~gNQqlGO&zIxkSKKy9=|L-5cQJqO;nFCNwZ`hBm<_M#Xk{p-hK1wq}76hUT4qlrJmUH&6AWwJ4#ZzO7E7_jzPEg&I8-Cun?ZAaqy8~E$8r0X&Pba4Rwf;v|NOH6n zn`df9K~HaAW#b@jd3c@+RU8NBm}5VG`{((s*b?*l__;o#R`?E85zM5-_*k}7qf;1q zxP?629o4tHIy0Rq8X_HgIvSiE@o-~aspZB;c$U}mVg_dxAlue?m;tShhX)tQH9jyiQhwrAVq3I=;3+3$XSMf%2jQ2O2FLiRnI+gHJH3vgE z`s#$cHO)PJJe^D#?z9%+h42-@9?&M>kcX0#W%STM?Ijkv5rR5_BCd|A*;Odsn!4oh z!HY?&rc}Lo(7RErqQ0gjXISu#<8`X(a*G8aH$a3@J_}mdJc(Sch#OqSN^`m?dI#2> z>o|2^aq7lYye@a7v>KxsPa!RyLSIaVgDErkH&>vv2!(*HYMS^OT@O0BVsncC@qA0F zx^G<#B+4F(`fNFL4>|)Ct#9i&oZk#Dq^u`m(o|>*uQpq(XyDl?k7L`5v{HbSfOFvS z5YUgy(2HC0O4{N50B__VbzlnwjRS@TCseBa$KRrE`XE z0QasbGCCNXcA;VUWEp(l(jH869CUv6Hb0ggb7u!IOt^)jN4 zZc(?|s%~C!JHlT$OtHj_0%|`m3)?E$Q1F23S_JAjKph;>z!JHVoWhCWShV>2?G@hI zNtlFMUh}oS!wgYo{qM_bWHmF*WpE|Rv=7z$R~}tc@mYOdZ_Tqa9weZQ-H-G)6Fj1fIo3A8n1boiGWOG~QyDn~ca$K}yGk~STvQMdJofK>Bm?cE}y z_X=T%ot>SzAO%+7h%&?3fY^B1ZDMAyWz*}uV%eFJc2z?UMEoW$tRtkh?IlDrDQA;0<71ln&`j-w8<=VYX0|#R#G=g|!e4imk4Oyw;`rqEqA)Fw zLDO%-u_!2-sX%o*jd9c5DNIfto9&zSwh)B4wtP5~7z}v|A?>JVsc&a75Qby64jWrM> z2|?Xo2PqmX({oes2sa4{a(8D%%F96%}!StJSiFa6_8%;i-@uLXQFV}GJtqsp@iCY=JzI^xcaZ`wL+7?I* z9!Y)YbEO@YQ9No3hQW2p{34W1_ntN?%-w~7`wXYo&689$^0Sit@0}TER7nn?Tej>{# zYVB9MW}k`RB_T_+mU=RYtmC4F+raHb3+egjF&FgN-<2Gs9{ z%_f!AaZO|&e0A>sY-nwZ;BbC305&Y_=(Io$c5sX3Qgye!c@AJm zoq7U0viB5K95W{U+60*4DX6*QB2N{y;Sy3~y&Kz&(DI5TvTaA}#-s&V!2C-~OQ$fz z-$;u8^-8~VabnyzJ0A9O?d}TT?8smij3ph&io`N*kF>IZhx1F1_X+lMGbL!WSJDS) zZ!fsqnP5)K3YHr)A;R_xS#TpzHpJ_y8AWdoryly>e#2&Tb+&H5 zP~N3o?qFwU_vGErW7N`_3AoJcWPgi0iW`vP%5HsaJ@w_y96UR~oUiV~fimb~LIk%u zo%7iAAU03Dy-9AeN@=`y;XNlkENd(5Dq+^s-^}{ z9X1=`acv79&)z0|f-Dw0rGZz!53mc+0euBW7`3o;a0pK?O}$R1M0H*^$Nu2PK6Yo) z*PAXOe$g(BE~)D773*zs3XF#DzVS`|kK3-exiEoWFd!Wn_Cm1?p+q}d6dUG|ndHy1 z4qYRxb#ZdI(K9hR1r7=?)7b=#vfm4YeHh1ParoT;fhE3YMjWs=tZ#G(3zrPA2X}$^ zq_mn-)yP{sH3owWFbUC!M*5ggB#W{X>R2EM)W7=k(jyCpsJ0lTgv?6zFD&cYajfpq zJCcn5fSH0@WG?Y0Mm8N{0c&VGNmH!z3(M0G!T?AEP76hSa%Hg&-Du4w7gbu_Z6Nbo zB{!!C$gtd)MW^c_c!bMm#lzeGb*M%rSKtA!`mO+DH&ZzYuG%d=+!KaYT?642Em%Xh zSb}_A<0CwO+*Sq$LX;i@W5sAuGGI%T35Dtw2;AR|?>_D0;Z)Zuz|+A~b7a~$%>eog zvulczxD_?<|Fpo%#f5v|1zgv`5tUYT!?!3qT3&N{?cE}cbpHIy9rw*nu;lkF6~N$8 zLj!0xqTPb?1`9$1uE6X>4zX13V4c63J1+9TStI;QmdWw+ttL`_{U2TcxWxskh)@tp z2#AI8ec)^}d?Qtn(7?M~!%?4wYh(8&n@_rIfO*A4p_jSwy6HK6L@kfZbZKnsNr|y) zQVo$FZi3A_Siss!q;enA()Vs_pe54DF|`(U)|iMx=cp;WyQjs%D;8CWQ`tk?2_0T6&d9D+qsY6Jk)3ND6v0)zS?heNpml1517lNwcLSt7K^9GZaPq7eb*48oKo7jzX}%C^apx74zxs~Ls%FA zCQ_h9^W8}?P*F)7NL4qP)xZ_7jMnur8TK>*$J}v|wDMf4;ncMVa0Jtb5e+`m z6MT(!k}^f`yZRhjpUq+-vn4gw2e{z(Jr#(bwY$OM4xBIR!dS=6T)VphgQTIYhe6d( zYwpSGk?7<{GawGi`22DWXWgF4IXR}%OcSMP-gTlOHP+iib^;BtQ`kBi*j%w}A;`|o zycCM-C&iWQvO4aZoJgaoHn>v6=whiHAPS0P7TFeuFM;|QZ3w4RFr=2xjyHXOfQ!TV z%`-+@OCDudcAco7H8w&gmX`M`fDWJx(V;9KYQfzBfp=4T4{qIr;UP5WK>UpJ+;g(Q zfvUmP0bDZ@eJ#tH0{%K()DA;1IxP@xU!PCINj9|$^Ge#`x^spFSzK3e^L^m0Fcof% z023xedSS>CWsfcc_>fCA@ut|dF=!ARnple@=6ZThn11j@R6;#Dsd> z3Pen>K73=83sg$yb(`FmB`m-#KEgB9-|hc8Mz}48<+cXiLP9@^TO_`{EjLDP zejIpPRB~JQ{(mU9b7F4GZMm6pTLW*)ZMm6pTLW*)ZMm6pTLW*)ZMm89{{X6R84fku RNZ9}Y002ovPDHLkV1fmrw;uoi literal 0 HcmV?d00001 diff --git a/Documentation/Images/line_clipping2.png b/Documentation/Images/line_clipping2.png new file mode 100644 index 0000000000000000000000000000000000000000..244ac93264463add1b5591cdd7f2eff181e77882 GIT binary patch literal 25061 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

    K_ziuYM$U(QsdjpO~|b#UIgijGOT9ZyPPSrLPDe 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 N$Vw_nREwDe{|{{TZdw2U literal 0 HcmV?d00001 diff --git a/Documentation/Images/linesdemo.png b/Documentation/Images/linesdemo.png new file mode 100644 index 0000000000000000000000000000000000000000..a24b09c25effad36bdbb8752381be4b02ecf51ba GIT binary patch literal 42798 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 TXg&wN4j?c0L+D!9BNzVxp1l|T literal 0 HcmV?d00001 diff --git a/Documentation/Images/polyline_offset.png b/Documentation/Images/polyline_offset.png deleted file mode 100644 index a2efb18d49d78577beae1b201ea60a58bf80a64e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8016 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 O2I*=VYLq^(d-H!L1NkWc diff --git a/Documentation/Images/polylines.png b/Documentation/Images/polylines.png deleted file mode 100644 index 397f2ea7a76a5b52b33f5ad2d9c949943d332b3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4836 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 diff --git a/Documentation/Images/zfill.png b/Documentation/Images/zfill.png new file mode 100644 index 0000000000000000000000000000000000000000..99a2e497cdd9dfb30279c579fa9d0dea97357c23 GIT binary patch literal 5762 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 literal 0 HcmV?d00001 diff --git a/Documentation/Scripts/SyntaxHighlighter/scripts/shBrushCSharp.js b/Documentation/Scripts/SyntaxHighlighter/scripts/shBrushCSharp.js index 079214e..50a8ebe 100644 --- a/Documentation/Scripts/SyntaxHighlighter/scripts/shBrushCSharp.js +++ b/Documentation/Scripts/SyntaxHighlighter/scripts/shBrushCSharp.js @@ -28,6 +28,8 @@ 'override params private protected public readonly ref return sbyte sealed set ' + 'short sizeof stackalloc static string struct switch this throw true try ' + 'typeof uint ulong unchecked unsafe ushort using virtual void while'; + + var clipper = 'Clipper Path Paths IntPoint List PolyType PolyFillType ClipType IntRect'; function fixComments(match, regexInfo) { @@ -47,6 +49,9 @@ { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings { regex: /^\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // c# keyword + + { regex: new RegExp(this.getKeywords(clipper), 'gm'), css: 'color4'}, + { regex: /\bpartial(?=\s+(?:class|interface|struct)\b)/g, css: 'keyword' }, // contextual keyword: 'partial' { regex: /\byield(?=\s+(?:return|break)\b)/g, css: 'keyword' } // contextual keyword: 'yield' ]; diff --git a/Documentation/Scripts/menu_data.js b/Documentation/Scripts/menu_data.js index b0ef729..6c6258b 100644 --- a/Documentation/Scripts/menu_data.js +++ b/Documentation/Scripts/menu_data.js @@ -9,8 +9,10 @@ td_1_4 = "FAQ" url_1_4 = "Overview/FAQ.htm" td_1_5 = "Rounding" url_1_5 = "Overview/Rounding.htm" -td_1_6 = "License" -url_1_6 = "Overview/License.htm" +td_1_6 = "Deprecated" +url_1_6 = "Overview/Deprecated.htm" +td_1_7 = "License" +url_1_7 = "Overview/License.htm" td_2 = "Internet" td_2_1 = "Clipper at SourceForge" diff --git a/Documentation/clipper.chm b/Documentation/clipper.chm index 75da2508c402f2bdab0ab1876a756b64fe2e596f..7cee1c25074f81fdc69ec9176b2d913630ec6441 100644 GIT binary patch literal 507124 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

    PzsxNVcVh z-2$MVx<+7u>RmR}n1H5y`sl6kVuMrP;yTt!e_Vgha9=E%T*vJ!e|HKuilwC zoh1;UyN(itMxvF2NsNoV+QuVcf!$8XzdDNnbBx(^y2wrC)5jM1E#wXWQAYyGu$wd_ zGK3x((UExVV+mTjS!;16pz%q0z9XrU#9`-)3WArJ8~+@GofT1b84EELF0|dcXi^-9 zE2HPO1pq_E5s47Wa{-)DSOK@=>3uh;N>@;ADNIN;e4_@X$By#b8NeVtNcUa&EQ1-> z^nkzi+O;Mi-cH908qX`C13hIEOqKhIo6cVI|aIK*Fmhcjt-Z4vOI^P^> zK4X&0>~HLdB0UKKi}I35b<2_+CDL&cllR5|lty75*Ca)DMmETi&2OWzW-Co*Ri|~n z!o@Fq1>y5O!L7|0U@qo3ta&gP@eT_UC_Du-IC4zY-o8#Q@fFqZn?l`8z*dzj8k3<7 zfL*gCh6Y(jr^0{;;tvd3 zBx4S+RRE@EQ-s+GbG(ZU{pj2$?Ba~>Xn!%0PK1CZkUZca|KFv(Kh2QbwDuz zaHtyQr(>XIE7zqLL>$L!?TSn>m^zLSazCaRd52t5XI{!f@P+&C!?o|*RxjEP%~=)| z@D@}F1EavOD8h*BlQ%w@?b5pb=j&vPN_bPm~1b&un&h=`#6#h)yyZfhiW1g>O~z;MF9BU zi1s5x!HkDEEtl`vF%9%rL#F50!r%vR zo`sJy0X1A%qI;aI`^|%6-*^}ex?7{@GTlNW3R$(}Th=OF@IA%hNb1s^;KygECud(B zK{jx2;6tIy1>spr+=cjOBNF#^t>n4=wXq8rAYy)=?eL%Kfg~-PW~uGCDTn`c0h2U( zyR=y)6kxW;PBT(Ig@Y7lQ|$t26nVm&RkIfvHfW8OHv(1hyrZq@D?n*!>o=#K zYiTJbv#M?`vTpvZs&s$Zz zHf9kzEAGpposLM6Nt2HIsX@z{R8Ixs!`3 z*gfcQvz2Mm`*VJ~l15Rz$-0d#g>?~tkr%rjoVkRmkmlDNjW03KgGIrm6ELS{b?XQNuGNj4R{qPz{=DVa*Wn43sjRXBp7 zjB?~>vSgN+arjp#`}{}iEPrB_j~Ef1BaKiAe*fX?TrT{yK6*3@$X z8hUK@=DVs*?#Z@==j#ol7)B2jAe&~@&C98EAV8LZpQ9!mo-o5_GUhRtl=Jj1fPC0> zp6(ndj`3!jcc+{*tmN`3*Efm+1=hY-XSm<&JGr%#+uXxy4N?^ueezheC==cOaLj#R zCV7`)O$o@tN>A7jYp7#kCq!5_9OR3FfWE`xhUXn(p94Rn>bmC~vDDO)T96R~tsk>t zR85RPYu?#!$8Z|%Qo%@%&KFJrOHm>UB0<6`C0%kz=?-<)fOI>!)gvbxZ*tfduV~;O zm3n72-EA}BM39qca{dFqDReEni{En6>XuS$ zqj|vh50~Le@PN9sNFuXbIStRf>1JfwVx2=9tpYxd2b#FjF$TGNmv{mkB)bNP< z(WuTLZPBS=Z7m*+1G$3Fqi%6YGF=ZUdL9xij(dD<4gHS{L?TK#(b&~yFU#)&|8@@L zfTDn_(Rj0j2(`n^9C@sQJREZ}9M3LG_JH}oAh_xCI8#?k9p$u=&HLY?8g=W5Vm*u0 zgO$kGt3lcptS4tjVm6U>!z~+gKVJ>i~KK=@_i#jMOcqUs=EynR{fyMoe{w&M)N>_omklS3X%G{04JvJCm z3jxwGI1bPxdU;slJ#+w>g!ouBik?+K9iY7+sDHEZ>u zVUZOXJ$x{F-4>q6e%LnPT&2M6SqJzYeNKMNZFC&Idn#jMTeXN zz}+oZ(j{P2EQgmYQ-kT(F6@U=d)3CX|=0!wX=~xnhhQPC?*kK-~v7U1Eg; z^deT6g}^AI`V14)jAe1T`VcbTWn#%!;3g==!0*h8OFk{IN0Bm2&gCC;yN`W6n(+?N z%5W+8i<36C9bH$^TYRydB?fYRhLWr!JDX2VAVChMNgadL*@cRz-gqvp*dL+SFZG{} z6`#wpwwV6BS=zY_6zNEBntx3Z*4w`Zw#ix<2m7kR4LM0bWumfLX|l zZ99&L&$hLr4mg_~v^B=l7i#GpkqV9FUsUpJSG3$MTyg{f)~GF;(P-_{6Yj9I zFLFij9`c7YPqeRF*(;o?sVR!8idc zM02>V1H=3X>)!0mlD5wD4Xo`!`=IY>CoDaV7QfR$gsN;XrbKChneA-jZ9+=C~j&nX#&ssgIS5@-IU;yxTa%ztp(LjbgP}|w*t|$5m4R_6;l^p+w;u&;>bDR#I zazZflSDfR?RWSN+ED~q{3r2oh5sK%YPpXrlS3XD8^^dmCJoP`$-$0ZXC>?NwZ8X3| zCVFw)BB4O2!4Ehj(=%x@%Fnr37N=H>D_9i!xDl1B4(L61!esMM3BmXGi#yc^dn zqaJUu4M22BS#>xydK(pvKyZ^lwa;5sr^r5!&gqunQ5`B{i#WydaeHsCEBsDjR)bAm zUs3WXrUY_ttFr1w6<34VQ4(f>V80qCfZCno3sxc*lMoyv5;km;9AhgL2}GfI7RgPT zG1IFR@=F4OTWI;Mk2&9)Dc?fIHW{iD=4te7Mugr$A*PoDL)F|~Yadc`j2!P9wKc3`2pV+PE^l1Nn_%VmGxHQSBGy zJCfNUz-@Um<@p(>gy*`x_3qi@Z01nZ*Gon(lnUi{if3>ci&z3C28RYf3~8|T=>x!g zI5pi!ah53WzntL7jyT82H8^k`)v|sXn*nTC*|yqz4LPd`a%nr|!{cs5g4zceg!a|> z?&@Nm>{nI9N|=a z%X8?FDU{!gx;v5Z3J0VrSu+@(!!0?PptusIl!3zl&fH+BMJTsg19FHdsr{DPS%lVr z-s+P>N=Du|GQJ*EDLP~*leT^giW0)`70Ei~R2g-tcyvZU1Ca=0a76{B6SMLZ{E({b zBHbL3p3H_~ZKaOX-L_gg*~kmyOgS-LOIKcMR58EsNs3?^wQQ+Tm1g@eC8iB z-j4YARQiF*aV|W_hSyk|#{G?nkj`GmV{i@W#zlj}Z+BfTbbSYD^J-AHHy(vSCzz(O zldJ5Q#K1IQ7?sk2Qavn>5+^Qc;J9e;{IQC%u7)gHr~=AgKp=MWVWBiMcrXR0P5e&3 zh8xd<0e~}Wc`+p+X<0sdJ8?g_Z@wJToYO_r>lBQxo|#FdU0UtllubZq)?6BLlCt7u%1D~A-+GfD^5|uFd;ER+)=B1SM-u;RubAXk4SD?zDh>82lb)}x`En&4L@Rn2=u|T&vQ6oR&9F>84#|4#0ooZG_Ae+E z3FSNKu8TD+nT&oTQV6Vs?W0wWeZga@z}8>)_Tt0xgkmNTmAGwBkPnx>2(V1O&OS=y z!g5=;4vGT@HDX)BS#5r>&#YZcq`C^N85IgLMr+|{p}}9_>C9@AbS2Yd@}BhZ znno(O-~iU4M!IoCOUYEU_?&?{9_Pal>Q;PfX_vAP1iXdiswB#;__}o8Bb4AwV#&-d zn$yejAHd;(mi7EIwaZmSG*Frr^rNsNxm5MmUgUZ=JxY09GHR{;^QJIzyZ-Uxx zTiOsC^oXam$Dx#v$JE?*JnmNGTvq0dvo4$@%enfN2CB$-IW9W9{T}L>$md2`I_`Yo z7L1ul7gtzQzU*c$t|(}&)Xw|pVMn#RnnD;&ouoY)Z?>E$xK`>3rw%J}1J-j;B>Kj7 zaO3BUg3ZRoo=e=moCzsuY~QzbJe@P`=C)d#Kufhy9R+&q$3A3OZN{7ml|j0>rjCq< zOfV{>sBGEv-R2{ARx^2LrBp5Ep4UeeM#ysZ+{S%3oQ;0#j3uQLI(JqH1D?Elz>p}zIm)lC+s<>=*GyiPw^RFpGo-6^92*;C ztsV&m>&k@Xl$|ntDb18g?xiX~cu3hF!K5m`UFXzOjpl7Oq*K=sT7JR06b{NnIzF%IsPZ8P&?{K?y)EPI~u1npD z#YcJkFhXz7BmYEckUsYq%$JOc{yge=2zEyfw-1MCd z<9wvD-Lq!7HPhWWNoUrM^Kg&4M|X9K!4O$@nyRw-R-5|P5BP40h;M_jny2QO@HWP3 zq?*Wz84HTU^zuA~B0dE?_`N>CE*~X&9b>fGx0k*)Hpif(&!;im_IM*w(R5nLmOH0u zs)?$%%Tj%ymbC8ft#JW;L9Q9_SPWC_W3sYpPZ#Tp{o*VBiG~`>NiP$G=ggIiIz}|x z*({mlcpMYP`LVOR%B&UB&J2UO|8_!_hPPJDSW8*2RoV`Xh$HQExOGn%lC@AV*y<-( z_fiOt`}iS5_C1H|X+?}NS;yUwmzZ(`mH_}i5y6`h^DpRA7v zJhEw~$MZ(iMa^e#Yi*5|G#0h-+oW@`Hm{A%TCNhkHrfjT!R>9P2a<#4$Scq1y+<+LHx3RPR5Y!y0+Q23_xxyU3_;Tc+ zXyLB!D;h&W{FMFi=fJ~1duCpKyR|mw)?21#*E_0!FIZF(3|+WR8%%)5W3@I5NQN(d?>tEw8PQO=*0(t*l{ol=LS+=TGf;=uk)i-cto$mKcW)MZHIdHlLSf>$sbx)@~1x&4Zlh;Sv_G zZS+};2dvq0QoG?TEFqEa#nC>yuCY!`&Q+#~VCw=Sg*JGC{(P?_e7}_B65aRj&-td6 zI2^n}J&{Jpj_j5c7BWn@9q~dU8QC|Tys3{IH)q;yCHBloTJ#v1_0M~GS9!zO%4)#= z-%N1}VvfRaMtm!^F4l3VKc$&1V9>)jAgWP?d1V5U4fWjZUGG^^k?LP3)i#_{x;0-% z>0X*baqE`uvO7$KiQRn@Z;0=4D043;pCvF>hVq5^mSQgEZ7=M?$&ky6)GUhKhXiyQ zs^D3G9rO;&9fxoDyrzSVxIBsSb>;2wv%65Ima-guraU*%V z2YZ^pnh2>y=h$O5vd~Da4I;Mi*cDhfYE4Eeoee@>X7@W86lt0y=bN~#`bLHDbx+IE z!!!-c2FdP$d-5oT5^(*4(0x21=W=0GzfzRR-7)G<_Px1eyLt7JniS1E?2^uxSfNd) zn@5R^g3cDpikL-sexz&KghLD*^BP~6`v_-4s@gyVG+b7joWMwSi&YMG>??FaSy(Ca z#!bi$S}AJ{EJXkz-YB?`x1LW83WCL=+T7sndE;gwsw+f$@~}tPzM2QDSycSQ5@vueKXMvG zy#GP!Zf}vSmJ>VnwDioXAuKbag%?b0Tl-3f+1aa#5gS!qJa-TGJRa(1=McI!YjL zt|HU>THms^{B$)#_XYXWgm?O3S?kp$nVIloNRymNiwWA?GqUI{Z||t@rgb=bE3Vu^ zb%j2bl0-|fs=~YP1%*IiFi8ogc(d^EpIYfQMW!XW7Jy(uDl5O2@#U4doEOMdTuT%# zH|A1WyNgH8p~-upt+wnMpu6^0Bv_#~d8RYGs31Z&Ba^Jnu~p2dRx|r1mAE)Gho@D3 zIK5wv&Zn(ePRy`p)Yh4Nd|fhUlg`kW8eW9W${EbMgK)fYDjalhf!XFLsKHk>wOtva zrNn#(uI|_yQGFd=Gm}*Gt@wL4(2eOivSZ^uk({KT9>~jS$C-vNLNbB zuQ@4-zu~Kt7GPk6*+X92a`@I5Me)45$1h2hZw3lyB?X{%LPMh%N#ayk-rh^?y9exY zmur+#CIcUyO6*Fx@b4wu%J>H`DokKOyPy*CZa6sk_w17WPHVuO(kt$>__lb%BxR@N zE|$n4XHlub5E~N}>nCFPH=a@LA-x~EsNpFoDS|L0Z{?LqdQHQ_t7AeBHe6l7eZ7k@ z#6VBsgatA3PDHHg7L-wVi>@=+s;{C5WEhLN+?j1kpM3cuh_1y#)F^&wD`{2c4M( zouSd@Hs~%o&!h{^{01#KY%AUk`}r6qT#lrU5ZvQX7as){fz;Z}nlD5eu!)}emm;W| z>mp<=HTgG@(Oa&Q++iJu>@if*E(s+jJ^KY;)`|^)u_Q;37|Cb=@)A- zqxBJexM$rRnxuDhSFo>o;|}{8!nPPVrmTJ)zin~>`t)A4e>XR3kn@q=D)LXMryIgb zrF*(?d3Np z<2yMZiji8RZ1pBk#w+Ghk#v?jH5Q3??kzfo0akO2j{g3RiV?G3$Sz8)a&>L6ZyN24 ze!|;hw7d?7#tvd&-gf(EAhTHN(}n^T9T+RPIbp75+HLc3%&E95?&uajY0xY3nj^|3 zqAQ&TKYd!sjEUGWD<&W<*p+5I^y3v#0XFQ|dtkn8N8ET2paRzZ7G9kz!_Fwhws=0_ zuox(UOxlV~<+UBkW^o&7YvJ%9xE)k7VzCf$x9g<&C`^XP;e#Ihmp>_Vb|4TwuM;xm zsJo*=7s2i-HXkMZAfGN$x_%|&GA8!`P`myqVvE@n?r80TgMWmsh(ru z;}*+xF0%sax3Os*qnBry=0s>`Q-0~F7SB$!%1yHEJ(@S4lby+%>a$YML3)Lf;Vbtd zxWrrgh+4m2vPYVq_39W_b+vIB8?^L8&i61P7Q(A?5>^^VFeVc0cFNjA(hWEGZmG+ief+^B^4K<*0%tMdC5hy` z(y%~$Zv~AHNpP-M8cx00I=U1}$uKib9IpTUxkO8eD?K$?ebfMqPoVF0e}4Z=MBnD-6XHNpOLi zZ7~pC!w;1ZQHL61hCi(q9Nf-_%wQ2S4C;bCP`I5iWgjd|j$u_<9@B&ALpo`n-scsr zj&CCZZG4>Rc?7!+$HBxxTL@(sshP62m_yaSG&5R;NZcf(3AO4_D&+CXDNO?5w2X{s zbYl040&-ObuW~bxfPkyJ{iuD|j0b^7yhLtKhS8q`@EnIwAhEu(Ps#8C$(IcD*NF@szaKn3&5+G`-R^p^Sh^X|AxuI{edJD(LLhvO( z0=$TDoDRi`S?ALT7ugZ4SoBR6PG1tnny~>9T>E#2SZODdGpg^-rBBnIT4t5q>&!$k z8Za;+al?Q(urx6UShajk!bFAq34{Y(wot`6T8;6SJ0s2K+@9gzttMnTaVGc#*81)hBhK3NCq#8l8} zi?G>=jUqL;U`9xFT2M~7xT9&ujC(6iK5>HI5AO4^$k33JnM@s_Zg6(2R-C=Z5Fy6F z3%h(m@Qxm}z;h|>O`Z$gbPuTYr`hh_`&RUlg*KGY_}>C$EP4UXWU@do87-oDV(3br zA)P-7x|Aj)XwTIQe{O2aAt4NCe6~$Yvalnuc!�gxVs3^+2|r0j`kT=!f-9GZlVd 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 z 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

    hpPA4 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

    qh#P`KLO}RyqN78MTMdnclIm&vOs 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

  1. Q}x{50PO2JOUhvWi*2Q^WHO3mh0oz5kOLO8HwmK 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%0AWGJ++9mBCY}Q5IQ_b67^einsrU#{Sbb~2XSe| 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

    P#Gn`1s25Vs_8Pck91}t%_d#qz?qgs;-nzaPN|D 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

    2{l+maKTUJJ$vy?0Xk{z!xkt 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 z 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

  2. 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�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 literal 361748 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

    ;Us3m6s`Y*Rl2UNn(tnX*s>sWw=V^##m=64LuE z&{+dY5xv%f_EI=__1R2!`1!3LMHhkh z2Zg9Ia(yplo%$f&8r{x~I!ql42Akb^mF757GIQ7?m%;&G9W}~jK|8QXvTNd2;VCyV zZM80Xf^e=|W&DjQtV(q&_hj$-^%No{UXEyxanA#Uf@^|xH6^aQg&S|{FxpuNv{&uM zW#%!qlWz3VEzZc6)F|nTgx|5K@;Rx(Q>m5-1(d$5j)cHB&}5%sKtRwlnQv*5LqLIE zp!j$WTYvvc$AoRYFFX1UOC`u$S5Eoke4s#4{?k~jvUdtoD- z91q0!IIo8mUm5dYd?Z8}jwQ%`?JE0D_=j6IR$-`6D2BRK=L20AOL$cfUqqKm>0`L# z)v3;ucf?aUyY>R*)OhPDahTtUwh8Fr`klN3zm>Ywk7LJHFYi|*1v>bXIs%-(!uN)} z8|NtPj*jDkp(0hxyyfe5R7YY+4irYIIEm+I*A{!?AewSD{q38Ecv1MqJL2oq{WD{} z_e+O}22Sdqn<-qZNf@y`n4@Q;r-^fOj4Ecjz1jtQ5(_=?(&5l<6+RlG%)B7NRmOyJ z?z{_+HuW)!GiUnjUrEobpWIYjz+kdgQ!*#(#qtS)e-bh6#mI+9zaF_PTCtm>)>W{0)_rlAx~DFCwF{B z8Qwf`V(HM@SC;9aysUU@W!iK~&d>fBGhrEIyG={k^4D80{iKLHWW8KMLW^)EO5N=i zEHO8*=be@1STBxaUX&U6l?QKJa$8pgvQeIju3j$m^W%(`ziD{(9t`Z|zuYPljx(&cJ&idjux_{2Q34 zPTG(}DD+15dHFPJ2CZ9EXpkX)8?kzqPTM8*ToNf?Q-+mJd{cM3CQ+r)ZidU5x|SRk z{hqJ?`g+-Jp5%ymR75D*wK3n5WhfE|ngN`*uU_eaR5nfG;FmcBD#^o&? zGcl!=@5D&Tq7%<*P_1+>cKM3sIvR6vgFS9goWMV|1-`66^CzkZwZ7awmHo6jaljTS zjljM57PXGFK3d&T1<(!*4Q2l1AwOdav^UnclPXi7?wxmwHIO1LLtV7_ZZYrp+ zp{+wY(oZBi_|$c5_1K~v^+aswnXZm0o?0Ep@tr3H4N8P(j0Rnk462$n6-64)Hm2o@ zh!4G*swCWfRm%d`CXl3Ca)f6<4;bAzgP8MuZt^mxjSp@*%}zXY=424Y0i&loK85s6 zrtOs83pl$c3)kD2hmG3Fx_h@`6>uMy(p_xNy|>$~mX>T<7*FXrxZTKiTh%lC(BKeP z-r4e3LfM4Zy3tPMWz=6SGMtxo>M(UntM#;?l+tUzMY?8cg3&~l-KcCj+sJZ0dp}l7 z`9gv}hp26}U$s@WzqYvfSoJ$hiX*` z!6=j{Rj=1_7`fX9B-#okRESj?TTDr!51cZpHFMWR(!!ux((DAp;nfBC?+p_{#?UJ)4se& z8^LfV4tcRf(uPUnYcb#2V;NRJ4le?7R|2u-+QutmhY1eCAu-U~uvTudOCI5g`DSJ1 z1tRge929yKeT?R(HEZz8X+NrUFj@NA8Z{Jp?*$@R&a4jZm6xsAXj_P(#*~_eaMuEI zBS<|bYzz}95q$RDF+Q8+!^0s&O!Hpu7uJ@oboJVmU@8@NhM(^nhseTE#hG0Zob`@mo5kK z3CEr9Lx*`votSH0?=HI#X2y!7bJAWfN;AC=Fmy}ysWyWw9}gL#%qf*xEc3(+^KKG`F{f#==n+YxoY67dB&_+k0^7_IQE z%-N(GSgRejj}wU)Hv|bUz81@5D^77h1+G^QWv8rWZb5w9;g;x9&3Y4lDj*US)PzF9 z&LaA50-+MEOIw8;Ob)cRVPl?HnQe$in&2snFrlk>vTJ%KeG`^o>UvJV;GE|37S@T$ zEGOFO9JXVTpmlmXoPA2Imu8VJ(#}fY!T@PbA${AU3L!q&{k?4{b%shjl#vlpRGOUG zTu$L7@iA0KRaF|aQ6<#jki#I4!vN$31Nu%GZQHZnHaZN$_^6RMw#_NO9JAiI(*UPo z50J=rmI^H$$e382eG214u&yds9XvT%W_XR>zA^9o#s^ebU%PKw+jvnI$)aQvTEZ58 zsnD;SCVO4vQju^?9fMJ?Sp=^-7Ey=YCT?Mkuh%ZXM^v8IJdVE-r2_l%YmgS>sl}y7 zgSV}|52;7DMmf9IQLS*&jGHAHisCCZiA(y5aSBf^?pkuhh^_U(vyLsM&h+^&RED-O zgD<#*#p|uIpucWjGvM>y=#^c_Qb%4*Kz3ZWl6F3EYSO+?LnDt`e$z0`8nM-3ECY2j z{POK=XexTPUUY`gNyX6@cMY>=>$4}(&gD66p8WP_JkLPcv-gujS|Uc~0&d)f-m0Ti ze%hmkmkA6VtCPLXdBeb|U-+cq`$?Mh2g?!|Z`+{Swzg9*eWeSU9m;q*GSTvCBoR=< zy4ws+Q{O|y3{OTx3;qv7Q~42!o>}m95T`W=1`A6))2(}MEW{O2U;LJOkG33G-HHhr zFY4SEI>EnVJ6`La;@yVbUN}~7S81Fz=N0y`CxxKplTKH4r6Jc;p*&pz!FyvbV z9jQ;OwXQsK8I$GKg&cC?vX;QDDS%z!GD3__;R`nK{~kfvt;Z=R8BWR55!`@>w4RQX z|5h1kftr2{wokY0`jrZmKXVpZ1B*etcL|zKa6j5aaPo%&=}|l*Zu1)bC=A$o?{MmP z0sKu=(e>hYcW6{q?5e@nZ~@b83KU-_mXJ`jTLpcZty^W;9E}q8YWJTS^=Z)@v2N5- z6R)(8(5(jOu-?RScH*^Nw$(o8C!(fqdUxJk!bn*3)GF_VK>KB^Vi4>16fJQz6+R!u zm~8DSEo*bo>FGQq7FDC=Jnr@01S(n)!m1CLeZplrUaqB(Ya%{hmf=TToj>0qzLnh{ zwK2(Ce?#+TWi!N5LK~HqIqo}tc2a){8pr#Oru(tw1jA*kAe%_+f~c#7{ic0oO8O9= zGv+n-$2c+&c4OWrWU!`HeJLN>HG9+3scM#9x*?9Pfz@|Rwi>g$bpEkG{rz_;!4z!z z7f4nMkRbrCc0wH2lut=HAylNs2p3esanjaDY^{-6?nSaY#9?9y3QRk=Fqm{QH_+@K z1K$*auYVHK&EQh+sA@LRl{_E|lXWxn=B5!7xe6-A*+nTISStD0JzhJMLz{1`pjnJB z-!+gF&hH=XuS$E65GURq64)Z{IBHYW6<=(o5}EGO{DhT@@K)(`C;k%2?Hwmkz{Skz zE=rRh9>~|MhO0^=mR^8pRpg7UiaoeRd$L}RL-3Q}YKajcbxW3YMmuZIqPaz-ciOltR2h0&XOrd5^t+M)i~6nW`AP z8nVcS#WIQ%S;#nNN$;4n$y~73pmp3c()tSXCBeni&@Um^TlT=!5GT3l%x@ajI}Ka- zii=9SzO3%Pe3PUN0W<3H^bOC-$4yu}WyBU;f;M4zM`DDi!O>0L*PIPKR|o{Fup^^5 zoyXR(4b_H_yy6Ly*|k!c?=DJ{nJ%a@IAtj^av3wsw7GiM9n?NfKm9J38f6D1PnF1- z%dvkEU^}vlM(uSaYy{bCZ;+ieGlMp(dnCj7jl6WFMD&T+;5zGufIU_Za}|k?f~J9t z0d#ty6-pg>27SWEFHhGE@K@2PGHveT%JSFpJX8L=aGzy8Z5{F~*jII+03sDhBm4-m4syW)(Kkts+#k%v zpyESab*t6cD;!v-I4CnyYBOb$+;7bkalh|G3USk}>D}yx$8)tqp9(f}4UKQ^Lci|G z^!PmD++tAsJm}eXnyCENe!df)UHfn4`QXQ1sYBI@t|Drq1l&q3i$dlg?Fbktmn>d> z!H`MkIB6GO+(NK-PHl3YXy7ZdO9wbqt;~tnecOgAW2Q>CkwqYJy#@KGvC$|vxth%h|3qRdIE9OD3L}K0+>=j8MmC7>A)!OXeFtw*4yvl|U#bA~byL1WT%z#7=9Y zz~jI?x%h9d36DpL8AA@|jK`Kau}z8MnEE0e9eFB4xZ1R;=3yZbL1wI8tNK7I8|8VY zvN(HU;v|KYZrj8cuat_6Ed`hEze7J*)Rhu^>)p!5HcAL`kyRi*n)>;(8V7o(EksK> zmjt>gr{Y<+4Ux+n0im16EC0ahNihKlr!ZPB<#njb1~LiPg2k^yV}vI+Q%*PU1Pfv>9=C6%k>^VXy_t+q6>H=2EW?J_Adyar4& zT}CkpI58bxnpKZjLB|f~m@!^X9Qw1)62RwR5e=1BWa>7o1Zx^wFDk1C z388MIj7taU-PfSc`LclqkkBb+JL$qieC)a0B*Jxrn?1um4q<{>p7JKlkP}e_-Z5|2 zaWnj+Fi+JX=uB|I#%r~0T01dTrmwA8*Dn#c-n|O2!Z039&m*dMr|0AR?J9=7wO4UM zO*!lv2w_ylMQ@W7w?BfVq>Zpg*ty#R2@(c(u!)kPV9I+cy-_wElkJ4O-8AmQy#bNd zB!ae!{Qz8!)oY2TOXiU|=G`ArQ7X4=V@opKoxNf9IC!V|ozP*qp4@5*#OlKk)^0zs z?#782ATb1-RmWGuAr=bf!9;%&pMF)9Sn3+1F%30 zEmZnu{G-55*X!xbdK(6w4dJ18hr}f;W_%vQIvrZ!mKu!6mYF)y(-vbGtSO3e6};Uc zDqzLX^Ywmqkx=e!ljcwLxgAQ$ib-O8s*`RzCk1eYyk@56%!S>@lKq5y%SOP22*gj_ z+n@FeZ;5NjL?T@w>P!;%3+EDmz=vLZfx5J!c9})WD-i_`8Y(a{K!j!ppr0+V9Coz` zuxd~)rGFYQ`&BZgeujfi+}9}TC= z(TV!WIfDruLo(|0?xIj~&1Ja&lw}y}x!u0)rvE0H_!pl;Hv?!4O(v+I86BS*#?wXl z3UTO`nUD0{&IjofB%#V<_;w)AyR|r;c6*y&I_88dr>+$d@?gyQ4uL7{_4_eF8cI5w z_pmYBK;u!Nd}z$NOX9;P+MH#HLC);-9@cqt!z<8T0Kf2EGsW~7^&)TfGAIlaUg_?( z-!!EVzcrXwW;C8hZe`erMcZcu7}jdJjQK6Y)X!3)B*tsKIWIj&(!@5iI0<$TTELG2 zK9bY7GG@3tnN7n2c&MO>bem9cC|smskh@WKL!OuQPx7NvGfChM=1F&3BY!MxDN0uT zg0?iVF$6YTlyR)$8GQS79}i6YJkstgsU_~i6zd6tHkF6~2MaVcwTduZ= zWZ#{*J?o?>5!Tq}WgV&Qe5=F3vjUZJM%1l$B7)-aPH~74?|!pNJPUw5lRk8yia(C`V&^Q*E`vd?*e25JAI{_F4{bC?Q9i zx-=;YJiVT)T$*}ZU6R?5?9|pD!-t)fxn_Q7Yn|cY;}_V_)wv*)5J>j{aI*6vF@I-R zEDUD({9=8!;XNR;tnh4AVWBR4u{nt_Ur`QD7H6nE@({=8R-ixe)Fs(<24)cYQyfm7 z>4+yL-~4OkTP!x_oa_rQpElHvEvz=y5#sG^?TxG5C3TJGZ^(2mx>&}pgO7J}j*{4$ zKA8=!T^PjFuz7N&FHhCAk9}H-q0zv-z>R}A0o93DSoqxbY3$Yb^ISF&=vxs)xRHYKAW z9K0u80_Wj!EKXK3 z?~ISdmHl+&=}}C&T#8*Y-lzH3fUj7Ljfd^<&n(qE0gu3Uy|X0(Khky+;B4DD1G-QJ4ei1}g4 zEmyQ{s?=cIN=0*Ed@o|e5FC@lBkZ;G)#xnZ&UY3?k~1TW5_m`mGCNxP(u6OE0z%su zXE)b6-7-gr;$yl{vkgs1^)S;;SMhNc@G+o6&ZU9jw)JTGlblm@LKUp(^DjSPHw7RV z)%%*==1-~ZVg9-SR(*S-6r{(E6Js2EmoVGXfUl!1g~k*y0Pmn=^;PTA z5d~Nd=?iD24&Wymo+b5}7tli=%)Arp6m&1nC&#*XPd}PpXno%fCc@s?GPh5W)=@`# zc}R>vC?D*MF)S(PmW7roGndT=;m;aWSyq`l9;&C(2s!?mPoXzmr2%}7!0b*|&pfcDvYg^rY085cVpl3RYjN&bI9-!dXPBetH!v?ZnOW-Oizl zTQaVEKK;|eF-B=ya5vArrZqlS`#RzpA?lq`OqWfVR;95K>aT9|gQzaYiUkPCS(v+$PRxV+c;HiIZF zZN$Uspr9m~Ct{}iJjT7hBuwdRE~9l0g(hsN0naAFZN`_q!bU9+SDt0(wV=ts4^vBN z#2{#~7SQ9%k)QQC@m=?D-YBd0E1ZHXejQR}R3aMch)FGe$t+{pI>)GjV=q_uMWm3~ zJWA{g1|#_bOmA)aGq(V?4+GCYE;kyv-s>iOZtA^M zWt4FkY&1a`c)KW(5&4c-W6>^QXQ;}pF@J=B2X*BWI_Rxxy9erR)`#+r z(M8QTIW0q{;({nC3|E1%j!el5iaN5l#P+)7!%Mj(%eo!uQCbX}?)^gH1)iQ^tUaZ8 z!r*6g${E&X9LFznkCS{x=$ajB)ofI}m*>?>nD?m;_Mu_k)fuhT_HHowzZ^7o&l^4S z3hZMlqW04tahyRG!XRj9D}uS;CsWn1=PWeV*CU)Gvh4D$8w(Bj`XzS?*(gkb*!PGG zJe1=yT&7b%60ankRmIQp1r5j-bGPUX-Bb=M-6KC1l4&-s)a(@}iP@;NJ&DfwDAY9x z$*A)sCIas%4W13C{DX|-6=uIm&w8kiJNf#q{eVfPq|chLx%h2Cz-=8sb~!m61E|&B z%!VvcI&s4A96)1CGLhuALUOl*xV>r-o`L(ULvX}FDDInttA@e_6#7V5Fys1?0uzgM zd^PM>gS_l1oen77T|WNzwAUfyD5|sW^EV=*9l~p!2CMlFl@7=sN7gMHGQ#l6O@c*^ z^TV0v-_`pi3p~q6$fgPGQ(_##K*uA>3J{bsi$@)MIM9k`HfGNodT+6$e|g+Ni<9 zGB_p4XfZ6mOA7Ph7wXY6q+utm1lNJHUP6@lWE)Fmn~3j@49WTPPm&kmKvvC^GdkEOY+){BIX|gObAyt!XUnn(>5_Duy6Zh9*9{i_kFmS9I7;uwyx!HMnIYs)s zIK|LXnMpF0Z7c}%#|cClC|^NW^_}A@KHEcPfigL}!A>Mjyp`Es#7@d7FbmC3DJpl$ z7Y{7D?4zRXe}f@X(XAZo^g7SSlwX^`ko(@>CFi!cBB=^$quACYv@^2LMAsu+`2E3h zL!L}AYZKY>uY4(gHajKwO>Z_kz}?X0yV&_{H+PT0L4wH>$2$}VG`yrH56VoLJWR|J z!!}*m*q&jH9^C1Rv*R2bH!2Q>-kN_4D0pNf2fn;JfYS!C) z=_TkSIadQlB*yOF1r63dBG&nRMsfR{Q^uP`%%)11S>AHBvs+Il76<@|usu5fzzF5x z%6%S{V|OLI5{g+_oU~A($o*Wib^NIf$@Mame3*p8|u>=7F|*318iuF21~K zZca{R;n3Njn;X_zPnyZo?xi7|)uj*6^Tz(ZFMgjf~)gacrVK0F0LBgGt`!h(YG zgZO+25m~0fCW7$i4iX`9hDSl=6B87Oi9&y39`NNgXfSfn=oXKu0ru?y1Cw$W%&4PV z;>(V6{s8dToNmy5)+|L^(8yH0B&+FsUD1Nrdg0gVP9ieHO_1gOs zG_rpBV5D@iC9L0;>m&sd2$K!Q^G2C3wO;wVCd|qh9D2R(Y%b|mw2)9X3x4jDOormj zI171&&~}7YR^hNYlT#desTs*+-{;dvZd*`vJlWgxF$3Ci7{C58VS{p^x2q$Q`SOA~qwFVMEYose~Fg76TS38z*TwXH~7c zjSM|vOO*s1%kI<{$2A#20T!%!z0?SAC*sD2KHf6CT1G$e;>Dq$B9+fBK4;A+E`MqR zpGv++W2K3zHk^`n$2FivOxW$hbck=HhTaoC{N{k|@I!1wU8}hW#9`&eC1TP#1D~i7 z8=C`NYrEF5W2|BX4N;uz`hvK>W{{ z(KUsWF;mo#CRcWUIvp1|ysE~gAdK4ni5o;e35%fmR`yn&_~{xdQNXm>!{fW@%yN9b6oG}KXvFjF#z z885%YvO#N#)LUz??j5r=rtf9uMl%$}q$<<_zkIm6^`cakt@J(+hdw+C04C7O`}xOl|Ov@Q5p?bDGhRW^oqYWR9bk#y#1-i zcto(Obiyl??VZ|N6k{4n?R}}I{|^9ZK$gEw4KlQg*zOSOZw~A+*Kv7fr;e9Ok*|cQ z6`d;YtCcHQT|P5v@7>2mEo+nRActAV@PBxmx&8{nm8e=iv8KOheores_n=Z zyffo=hJ}(dELH@^;m>{(a7SWl@s9TE&L7xo51GCWPc3)U1A~1(@5eaEN{c4WI#`IN*q(&;b!->A$84ke)nK55)Y)$#(OBuCwM3jPlGfb0?a0p+)@iVq zcVDL>Jz=on@WqRUQYAPhh_LI**{Z}1@At!1%SvyC#k`c$15H)iz)^o*@prR3;NCgT zy+~EdDoKxTP}v5JKrP`UF7=BimCZ_xa6&mmr0SfD1&5g)n^1|-quPOd)RtM%_9zQM zKQh@L@@QiN4OFrV#_|ogZ(h;Zis?yfQZlWOW=;7eXK1z(TOmFJuR(~%rDS+3S@C}&U{F?y+f&ntt|LjR`{ig+Wu zlrjAx9JSPE92J8ZXpEMz`^Kfl^(8{IB{~{@3Own)N8+1BnBs|kR~4w?2o!!5gEtI` z+j#aXsvNgeo4C+>nU3oDD+ASauCuu9rOS_H>AR207#50tKxR0b_)~FupT)R1&fUFhG1ulH zIu{`gt5NhO?K98f;VvxG&)uBgcWKtSF`{wn+gvi}{_f?Cu1GfcK7u2M&%!>nh0s~s zBtor`(V!W-cnBnZT+{sQyWE*R4I#Jxu9K3#(CyiAs`Z>VyY4=OlF^e&(45(YaD`W6 z4q()UGVx9wjA#!ouTv)`oRb`vw#@!uHiHo4pZ{TJF>l&G&ln;&xm}nGoXX6=Pg(et zkeu;iba7%lHm0+OInJSph0q1sqtzKmi1OrWzV=)4YzgrsJ0i)$GI@0!{>G7Hhr~?vzm@ z;crKKw+P?ydG@$J!|GVD+Y^+Pm__D6;vp_cKntLCXy4bvJ@4~}yP5w+qbC5I4@uP? z6hf3?5xrOSO_3_d;~eEH5ldBv9z4Y3MdM(VDAn0Zq{dC;Yhb!0&PbLyDCUDd66$~L zbF#|+$r9;Cl}5+-F^rZj5*gtdx_)?RrBK4pC1XKt*r3=}GDEgM&A(!sU#`Jy`)Fa< zh5&etm>U?C)g;tqZ(Blb%%VObmZMEAM_JjDJ!*9d8plFyJx%j z??a((i~DALZ)a)&VVAa5?$)*`QPHI-T9KpK^2Vk-9wH{+IZtGTR`w!G+{&d>>zyB*ghX>IxY z2aWVlu{hh*!T|_y0B|q>XL5jhKtlllQQPCD3_<6VLdHYHWdl6(K+7?XkSOw@G$>%# z=QWp1GBapgQy}-F6QO5}gB_jV+|(Um+Rbw--Lr>6>rxUGb<@rd+|IuE2su8vw-naQ zIIa`w%b>LeboZDmH>Y*JhNj^d3RG^Vg37F?D~c9p4s&sl zx(!#-QG)hZRKj>MS7n>5rxNQ@)E$T5hfsp)W-ch8UaNJ*-4*;e1 z5;pY~GUkcslYY-*_ZH}s`y+bj@Cyhl2xVD*=Zc>Iz32D(E^1A`phocd;~R+UzgxDd zVeYgxC-03raB(@*!7|~>k>xz6`-`N z&|vz%03qt!8EhG(c(=6Rd;jzC-$b2&Z1zR9gN*YLCAj2F)KLY(mpt2#mT<^k?@D6H+m|#6V}RF?=u0342BT z`pZSRyr5N@6C5C?WK-3Co4N|h##bDbb@S&d-OcQ1{$j6r_4RN+9{| znas{)t&ZOVsV%{|Ti$ygJ+SYP;s-eLOnm9cXZG!X1w7eP1a+(b3|mDMS-yAL=xc?u zdz#sw24{rELTy2#Wa+d#RfWG1p*x-3vHj33nK$qI ztsK|HGVwT(|NdSTuPJ~lwmJ!Q1gwNcuhTG7ybMh}7@=kl{)lRD(Z5XK4YE|&`>ded z1royhp+b9G&PGYf#vDC~M*FIY!}P zTae!~SqK_{@qj4WbW(XV;J__K*6E7XovVfJ)9ypXpUHS;Yi(ee>$56Nt%o=u;w;^`6msxG}ax9kvh97;p z=6n3#{#N7L5sEa$v9_%Oa6ttlY)?33kPXw`KzU|=|hA`r7(_oTp^b?zh3QFtQ zdJSXCw#<*$uvX$)@dlr&7Dyt=glB8j!<%Shc?#Y3H&Gx}|6Mqlu(o!Cw}C@G<5;g4 z|8wUTz#zl}004XkbpvFu0AP9mPii?+c-t0PT@rTTkzB{m9O|#3E|YQ>6#l}5;NVv@ z--=FjJKJy_$EBB32Qw1S1`U+4bt{Z?PhCu>ak zIo~aL(@R1*PHkA;?{%3LDHbNrx*cBb*WxW-z7eQ6&8lBs(kUR|T)4{BpBE)cJtO{Z zp^2Ak_MC;2>t6EW2%DUapJC3OFES7>HR%#!)w8YI1tTV%5?6Si_lnyfR%wBaP4N`J zbj5Y-igqmCX~QMjWI8LPayIe?}w+VY3}3DC>^U2}o99$B@$7wH_m|CrS#@?CQ( zB}Q_pl>556OX*$0gzi0C8{WM|^CT{3RMO0^4*igY5lR5?H2{}>6id(}007i>m1&RS z94%9KqayMjAzt-*2AM%`eo=*Z6B0z$SGZG}p;)C?0)9Au2i(n-<;B|CX-XVtHVTym zFViA^%&=8jq)=%pVK+~4B$QV1%*f=P#L$*iDqCrVMc;W-ltJ!B<7*?o_K04pP@R7a z>ALeTe)rjrxchd*e<$$5k8+DR2Bq12$`j5z7a+w_=p6|gvU;XSmNWN3;=hDb!G0fs>VOZG1e@oqT&qrera%Ay1_1M~rE~NG9{^zF*an+D zBCQ3ySlD2+L$)B-9=vHb`QTjTN+t)1pYRb^JmWvA3zYN!yYJf?6>R!O5DC(e&KaFoSnHOld1ef3jIb}ATd!Se8-pQCv-%y=vX_%_cC!q zvhqwiAjxT1CT5S0^qln3`n(!)fQ1n6VWnJ1J6^jnk}Us`9usbg+9iA`+&%MmcB#WGRu_UL`kbla4gp1^=ZtOd6f8~7Sku(i*J_ax@?C!3NHDt zwNz?c*?T{VCKj+vciaO{!-npS^*o$RUClI8#Z95;^xHM#%j@PQ=hEmf-DGOEsJC$c z)g4?ni}lWM&nrl0_ROO5! zA>PL~XztzlrMxWs*Y_cErpE0kVv;Rfk*g0ScO?{>)|jeB`P6Gy_ssAbZ?z}HVvbTn zc-$zJRwJb7B+K{IdqO5p;`t(N9PyOq)kzqB@!m<$B;L@+7^cSIt!hZ!bD{5au&N=9 z!B9H!Y!E8`Dd8kJAH#szF+6n$As&X?-!eKR8TDh_>{~2E zWH3xhPQ*|De>;WXzpxg5JG#b*En@*;yhEaK(b)*PS=r;bzAZ^;f>Rj_;Qj8*a)x9p zXHt%8v$OO7ES&jgr7FXwEET9r!@wEDq&$NNqdT8(A^L^a^W;9{ici1!^K3=+JUqie z59U`38e$C{i~u5ze^>s{j}@W;SNIuGDqGX^6P|+wetq{e*%d2A4L75N88q}9V^2^q z9avdmG{n?F0Teu*?!r;cpvA33mr>WpnB9W>J_TdO;h4YS1Z*^x!tAb$`YR2(J)-y1 zozW_#`CXZcNr6APg=+S;p0#GRPF_Q`pZ6q=-o#>8aHWXEvLT1-bRY=4H^D#$oYZofY$&34+F6T6mkIII{-9lxb97{2HE3&`V)m=$*x5@ zIaE#Mhjui*OGg*Yy-->hoaUwTyemx=>w*;qs@!uc6m_58(V?ZF4J9GdsX097i@cM2 z3=~)orH_tMB)ah*&O&>^-LqbGcdxst|6AY;BdSlt{}0&7U)DYr*K!iw?~@X&#QPjZw-@t^wEIM(3HC z&*!ckW-JV8~dQIaTkd%lNXa=q(?KZ@p!EG2nVDE^!XmlYD9`&R)xc0l)yf2LOv!7K#A)Jpfxo z<#-a-C0^q?B)3(^AJ=NtB^Z}|tn*ZsaVZM2$Lq))1?g#9T25V7J0d6H11ERoRQ`37 zMn;g}T)H5vXdF(V@(A^OIf93qydre8hBy|);wj_nzh)|y@wGmN{f%rlo0*PT~zBuvYqqY&guVM~11rC!ExsSUgs zH`&z%#rzaG08jt`-4?G0006EBq3iDI>50M6TJq3b^4c9xndyRO(8flY}O z#Mhbidli-V&w|_)#{m7bCS_N;Lob^bClK6MWrwHp=_XzzrTdvKgOAc8H4(zpK6?wPANKc#6_Dkuo_p1yFrJ3*4+r8jp7_yP~ z`Fb_tlPZY*|C81QA$JOi0zgHELD7h;@(9I;#`O0MS_s`pH^0<(JSokX z?)oAJ_$dQa-)}*GkcDXA?aVQq&X(Wm#H&`eU152=^3#R>PFII1<_D^ruL#S8ZE8^ zqKl-mpRcd2g=^n&|9hERwsnh8H#l+r?O> zvTOerl`08}^wL=F*Hd(Hl4y;ZKfpi)WY=Oe#&(Py><~*vOEK94Hk^l+kV(T0@@6P@ za(BM%c{8~epAh&k9>Luj8IOHOjrzlpzCstUBoK8PuKp#2nWgG_`;(;1Zy`V$fq?b z#RCMEm8=C3)OG4=nf+2tRgf`NdIfSSRu|+ff2ChFPT5mRt_ayWP(om#0)W4wT&ZcU zs8of@DOnnkKnE1u(2K3hs6ESgc0{pi?E@u30X{@jA` zzL~uOV<{iHDT-4j4MzJUv-KCV|18TZzk+3)*(f2lbX^@AMIfYLDoB+S$+FS5P7;U2 zK=on-B*v%UQ)rKD+86T`d)QkgMKkw(7aR1YE(zb*j6>rwzX7e8nyske@C2uxdO4c4 zY8N=&&uAz~%m$7}1%d@kMAN;V=Iey5Fw63KKo!c`bFEK_76PQKJf7e2IVzVY5=oH% zZG9_K0@nSDIaXE$Zu$qkU)+Noc2G9*hLx2jZIvt|3TPnSrf8>Hej z313(tYG6l?@GR?(gLShh;(G1z6uy9=co~-qTxx?y2I5C_GQLjh>~!LX!$R-&bDJ;@ z_8yt=>59CVlL8pbjurG zJ1naWRBt(YdRg=w2xzjNv&GlWcuKH%)5s(pfEuaKH1LQ;+Ym$?s!J7&QGU@W-8b$4SrymygkrSEHy>J$ zeJ&-q*u`kGwKYx3S-W$GlLT#393@GH<~{%r0RSQ)IIFk< z?|1vY?!BD%=iPQUH|Miz)|8b?x6QS2Tg}ZZtEtK|r3_he#AJ+8Gk_>DMWGA}d;$0Z z!9@oF$M`71;se4L=_>>j#s@-vq!12BX%K}cG#tcffe1yHYBLPP8+sxPREenKm|i?- z=g|Sxa?&6(#-=+`AOyfgOC@an9a^Y!8A)_{WZ@UaqctI<9;}I?(1cLdER_;a!knv+ zX$Yslq?R@d`XCx3M0{A4RH0_j<_fg(1%smFMhZ7+nTSbsBvs6mQn7%lRce~fh_ckw z4#Q@(Ua>J{HhrOj%Zc@85Ikh971^H-eifuu8KxRVjr=cs?R3Bj;K@H_Gaafgtx7S% z`$^JRY$3!j)@PTp*h-XoC$-aDv9z8j!^}_DKdc&1w69@d5gPSjFxxT#kBuF3Yu?Vi4KSb-FE-V^G7!S7hc2U98nXQ`aMX-2ou#5ICpko zR%|ZphLDI!1!zKLX{GqWi%2)tTB>3lUwKs^FhwcMNkoaAlj zCZr7m9g>JgQi*`!a$&Rg1o|oRl zO;oHfG~(nP5#`4oXL65%uqK4Tz?sHL6z7q}<;g$wk|#;5O%rz17}ZTsa9OQnv0_9O z09jf&?b%o(Co=|aB%Zj5Vi~AhUaeWSWol|rbu!cpRn#UX2wQSh9OoZ;V^)GQr64Wm zXoGFjNhQd;BzA|l-qztunp<=TIB9aR4$(^F5RqN6y9`)b9ot9IEEbM`n8;`0UPQdZ zkixM@aZP1_59-p-E_F}a)LSUw5@nUt z^rGe3J2&m;b4$R4f3jF%>9v)ge0w0rsEf>*Yh3N;t`KwTRZ2Cpr8+5i>e>f;m8tY% z?K7IXo=7gpnP5c3L5_$sb(X&r%!_U17Jv8!J07Z6T@L~a&ybZw7IvgYdkHN2+0u32 zZISjywibb`KHlIf#SL7cNs3TIt~p=6YD7&nQIBPQVfUPN;Gj1Lo-Ct)wq`{rYQE2J z1H5ed#}l?(ydIIs!vvJJA7)|XBY9o~uQF5P$UR@K%^3n%ixT8l$ICP}UQKRPSNi%Z zI)rpH((V!Kc%?hiCUk*n?o-^a(zho0Gm=Y#dMNbJ%>Ui<*stRkuPuhh8fpiG6r19&`%0>mbZ}1Rta1Sc#xa@ooRClL;lKX_n7AugFf81&!kS-&6vlSKg^Gw$h0ju9rG9%y9`t}&-( zw#Y z5GH~~9`4GDM;kp`oS1f~g!wsD@n_yoJDcgz)eDbS8-D(l!tSiXRn z6S6@Q88F0r0OPp0oYX;e+s)wB9(G)6BvQEWUY_#@ z$2$8gL)VmpzRRcAl^z;M+`0bjOqmh8ttqeW{L0It6q4ZaZW^v|5m)Y3r4DqZnMyq| z#*(0nNkp7QgfV~{r~|VV0&dK({qAaQUe%;Q)GMoqckV@M5+Ka`aP0i3tZpFrG9e1% z`kXc9DssKqvC?p|>=!teqhul#Jf$&zx>wo@`73O4*bA<0M8;zETSRfS%Ht%MC=M#I zuBGBuU4)Ih`u(uMgQSu?9=wU0aJP24JZ>?KcwL8n%JcAleuWP4DE#VFMYYChY7xdV z(!L>Xq0h`e_J!lZlxT{@lTsYi>d}AzI%Zqv$)sN@$>&l;8HjkNsUm`L7r`(nyQSlf zm-fIV^GuRRju(j+cBH7`3neAX*1%jZlnw53jqQ+EDgm^q@^dMfRYq8CgeF$H!u$ z>f%Df-Kyam=!wQ|0o+}CXPZ@L9A#zl79OJ5KZjuJnYe1zgUFO*tkR!Y4!MRZBxz6+nl%U6Zmo8W9k!j_ zIO~P6Ut@`G0JPgD_ay3x%K8GMNi@4wAR)uDrtj;0#InBTd-SkwwubNV<^*4_D@Y6J zwnfy^+ltg(!y1s^a1*D-O`v)!CF2qe`VmX^n0KoZ@W5FFm254uoldlBffcIQ-CbhmpOl{q%jcKc9{*E$~>SJ!K#L21Hzq8Q*c7U*)<^LccgqI83ONvAFjSR|{~6dY=uf~!@1 zZ2)}aLUrBF#LdS>H{&izlk$UX(W_!Bfc7EVgp056j*e8&H#rH(&y~5}eG;~-Ys436 zcb-S`=tIJLk$6ZJW^daB_&8j>0%z&GPQ^PA^QZ?{D1!xyx!mRwoXu5NrqUd!^azf6 ze?th7>;F>#XAUU5S^q2#=j%{Y=AI??#8tl3updj(WqH8nEq^aUq!iqXeFX2zx?S`Q zvqBKt^UDS^oRfUE)skr4?|Gd&A0jO}A_xiw_yP6}eQ^ZEH#F%MX8yQn0H6Tk0suwC zXa*p-0018Sxt6xOnf2BTWy{}RgM^`Mf|?R#BMgPh7RGMCWqr*ysbo{J2U$feE#&t) zVGt@plCfcO-D3SBhrFW;B(;=Ks=&7`MZ}P+cHe}cuio?RZ!+0#I-Mq0bJcB1Wx67y zL-Jyq?Wt*-D4cj(K+sQ7M$%@^9mzJ@#^Lxk{` z7_iV$6Xi`z_rgq85HZ533mR#!XbnAwuYK4{l$;c9WbjqYR-D_?_@UK(}D%>35mWf?RxwBp?O5RqHBioglT?g6ElY{`|_uS zeBH_s2FtN3xRz#oIy0KI4?cqg0-cYWqWbsD%b32XFdhTr z*pjB7%2pWOBHbm|6}%_y*KblqAn~PrGCb;6eK(S~U&}WlZBh_dedFL!4H&=V*80Ry z=Y4yeoPIfGRspfO%O9y7rYLv*TJCvo5TshkZ`4q&O-1;Q?i75hP+bJFONtx&GXg2A ztLkXBb3#Gslgn1G;cayQooi@&CizoihVY`6bZ0^bb?pSTD&7h7sjx_?*>!tmlG?tu z*xdJ+Z`C-B6sO~%d4Gq%sb9J3mG7s)P|I{fHb*&_YeQ92muOgxm*fP!T{=%r5F=rg za%#|8@-bI$oFusjx>ur+8@akjGfiWx<=;ELxzZ4C_8Lw4G@#z1ZC{brtOYTqay`6z z&pC;bcG#bHNQ`<*LJO*M;p^RLZPYz;Xe({(xGNyAWZuKgjs!=!>F(;eDpG$}W>?AS zMDqtl0ALs&J^=c?dP_7kfJ6WQuYPD#=-thhYz#PYpyMADiJiim!Tl69w}=UwD5{4pzI>!%va{x_65Q} z;!N^tB4_|uzy$yR6iM(R1OVP2@L5^+@VJ&{i^qM!Ol5_ay9bpoP>`5km)9!_N=w8J zqU{K3n=pu=02BZK^%CBNi)a9V{Q!Hn?`GY_%|Z08Vtj?d_=~JQWi@Q)_}P{C;Z&~} zq=Xx02T>`86DtaD@G4o1LAd?L|2!=3zit;!co>vBTm1YR$y;1_B`I>hR7#sjFqXt< zjJg~Htmkko2Yrg_LcP3Hv_hlX_K{;1|vj zpCsBN_Ab%8=A^CLPyA=tJL#G_N)j{vO9g#m&ypL1GI}8UCq+%0VbcgoWUT4oh_EFe zFZ+$p4&g{~UL;cuMvD(0O|?flW7tfX8573}I3!mv8~5yDVKtM}FGldD!)=EsnKVf$ zd&NsRQd+;7jaGjqbnT8MBn1rs01zt!F-JWB008+jqK<=ZLhVo@@DFIFCK0oJ{gFYI zo|n%s>O`@5zRBj~PjZ+8kSF_T8A4F~dPWZ@H;mS3qnQ{%U?pcpS%%9q87?o;&6yc7 zGSkbM88kJmvhKZ188I@Ot>K~4J@ob&-9}F!8(eh2^|{q`h?yDrW~y8YO~K3qFlC$> z0d*o+=rfF|D)(fcs!N80IHfA^^5?lc1T~WwR+7%TnePh! z6iYr_g;RavjM)T=wkIEsmnm_~7fLGV#%cCxf*(Dg}_`pw)N*Mk9)Dv5bT)FyVCLLDdA{~lIGey>PY`=G-?&{^hk+QU@jKR&?^-rt003$S`Mk)bht*kA@6Jd4^26;~=o%_L)rwvuC_Go^#qTm4k$1STTjk^B^%g*zLE zg`w~2GA1gvZ?hy^@)u!l6mBRlb?I&2I?N=I(M+H*4l6+A$wM8QjEd1(Hc>bN@!!oC zNLwzFx7_?KY5UJCs??|=bWR_fJr3ns&ZhuTGNb)%qj{3EZdLMG#kFy4L&XUe2oeCeLT@^opoDjSI@21>}^gx#4}9; z9P}#M;rYU6!*EPh>M_WWbIaNybtio}sG~#bTQ}#ISG!6`*lOZxsg{#n&z8{nTDPP3 zbpaiF?9)bUS4otyzA({d%u!3E4Mpr~AxxWCx}WXh%4_rdwmRK&5TEY#kv)5+coMaU z)tZoZSroOOSOYPw*}V1HDvy%?2YcZ&#|D zX|Vv8(V{voD$C8*7dQ#ugeW{MhX9xV!oZov{kIl>%>1y&m4`&YatTuR(8F+k~`!UdJ(Sw?2rwo6|To6 z40T6!QQ1DHoi!UNr&C2rl4BQ+;G)x5BzEI;=ug62(SH!H)zJgvj{l3Og00dsBEfP* zK>-p1Hp`E*d1?dkZ=EWe={)Yb2h?~$8@5QoCAKcIn7qwJZIc#KS+l9jVvf0fWZP;X zy%xX@o#xK4T{B-|1}}nYjkXXm!P&ktks(cUDb@2hAgjn=c)=V1 z0Kg*rM3}!u6Z%dD3jhFs&H!tE`xreSxtKRw&m1q4?PlVc%FG6EW^PgDM3!Y-&BgVM zTe7C7K{FZcb`HB z+37U+!h6qt(J=R`gNG(gY86 zj!7tvVc1Eop9jp+2ue!qWzfR@i~g3E9x5!JogVPJ&m}yZ7~S;Q#%bT}Vy2H~fbrnl z@?xQj5k9%rw21a4r@=NtE^D(^z@Sq99EyGT=MRh*;)thn=|5gii!6S)CsiJh8~T^K z^~yEd{IXYaSgA5?FuX$el+vViva?>PL|&HoyF|oximnMhDY3zn|KhFD^q#T3*cbLi z?nFN@tZEPlE5|~zPY;)XY!zFOuMol&PkjPLY1!14BP!Hrq&0LL$7N18iG>V(6gKUg zC$J?%Rz;}v!1a`(@BY>58|X%FBS_vQ@Z zjcBb`JgPN+$%j?9=kPo3b}B3tB1jvqvGN&Amg9V0KfqN8?`pCLNfq>zy$yR z#%ZD5Gvl=x5LDgg5tx#{ZiUa?i=>78ZV;oPjW@PLz4^B|v(=J=6q-L+Lh}HLy#$O6 z)Z6Huh8j)2PzqrmQm_4HO6twwLNfrA@CE=2d!0hv&xDh!!n|+knLRLIUYAa`Gd_+H_8u>S01#mSC+R^1 zKwtm>_yHF1H*x-JF`(8ga(R(kgRWBdIDf!7D1C!4UM7ytF0*_T@4*LZ5~9G0U)UFY z;E%>c{f$9O`0!Xx_>SZGlEfw2Nb*g!O!=wu#h>1JoJV~t6v&0%6~iye!>F4v&12PK#!3~QYL$>M=QW=g z+S@89VGcDFa83A<=}b*JGUKfF4X%MAnh%xArTp#fE>@)U>GV#~zzfEDgNo z8#_&=ovSvpzXD_W^;-JTDJQWD(jJq>iR1a zK|M6e*bhlqnO^3bsLn6nQ9mJN000mW000000ssIL0027xd%^SGFL>U2k@r*t@4eo8 zcrOG&dr?*1332xdc$HLKQ4z&OgL^UrMI-=V004b(vRupgB}hz`lFc#668sO{HNi5u z0UGCRGb)rqQh5!hdBAs6MYV3<`=T(~wI9AH9Z*{P^Hqa|D)-wjF-!mUye~b76Lo4f z(;;T4P&3Ld8>U$%-Ea66 zOJh1SOXC7tQR6#mGg2BeV&Pl+2_gIEq+WZhm*++P{ior-@Sh5N;wKpJv6x2bzgBTwG&6W@=USc=X^8o}OcRnfw4}#D2?; z+cFP<%ZMy2|1GJAzHM6-!+mOT)VK7%`V{bODwg#DD64EN{|sUb(%o9)sQ)rP+mII5 zBfM7s{jak;pZGxEnh6~J{S&$774S{p+`mTm>3{cg1#MjigVO>_sP{ia%5~4jmwJ-v zxz69ue*lCiDgp4EGS!HKx067Czr~erD-hlM} zSY}vW187hAWkf&5%Lojt_Ig{E**ypAFx3MCy&}WX+K0pg{b63u@9Ccf=Y~JED@^_Thi{26}_8W25O3)Rf; zu&=Xtf`-q|_~M*^u)g%uJvU`c@nS0|UQK|X*J zOiK^?epK@LOG1~gd|6lhje@@?9gu}bUhUm%PU0^-+;A6}9 z8uS|D7@2cCk?TeEZTye)J z#lE{u=G6bS#*AEC?@7Ok8=SCs@+HofoT=@S2A-g|Il`NNj*8ZLE z+Nb9d{=0t+dWz@EIW&`zM&uzs_yUsfUBZojj14}=U;N)vkRV+=Wo*>&%)sf(c~AQQ z98gaHY5V@1U1=on50gTHN|1j_5}(a*~0M3_uoqzDWPaxdIw~?Myn0 z7W;dE1Lhe2;wN7i2lG1mqWGS7XjqO9_(sOy#Ay^0ocwygaKZp8{LRx=yXo>*mro#&8(i@ zK>bVqc$McK`3qPc{o5p56eQIWA)SG>8oM|LvLg`TlG9{Jz*~?|VNW z9}G^)wEFR9^{KOJsQJgi8KlnHs($$Xv+5rG^VdJe1;)RnClVmU1I%&Q0ao;r0L_0N z;|ux%^3wZu|NmeQ-vlCLxNq?X*%R=ej?LNr{U87H=LFB$+v_0l{gV`4^?yIk{JxeW zzS%Y+)y0V4)?2>+eJI|zg_=}-1$_KBS*i0X&sp~Mvi<&CvHIWQe2Dq;@&h8}r2Nv) z%D?+h$-lQ*T=09Xk*~tp#?ScJ{gwVS{Vc0Pmh)rJ6E!RNg8jagNA}pTvxo=z5!irV z2Y7gZAT#0r@Z#9c?900dJix#M8ayn2-jztk`^SgT6|we%s|5Rp0RM2r9|2e0y%#y` z?*W0PYiX`e`D0fH--Scx&DeM?l8ldXP!^57^O=;`?BydJN&4Qe@ikvVJQg|zuGCkGPe0Fe+f-`G5lpO=?dF#)rR@`@TbD>0Q11M@zXt{^+CBM^p}s~Z?F&9 z5d3FxQ|Ep@Uk?Mt<2>-Q01prF69=4E{&nC10UrL~07*c$zj-z4>6!hn9ezEjv4Kg} zmw#KjoKNLXWuH$vbK~=x?$EUwd=8EjKEI8#5=b*v0<$)hpWB>u_1yP!e4gUaFW1-? zSU5fU^WS~qW&l^gk~8Cd??nG*KYseB`zpTp9)Y*~fWI0q&TX?FS^9u0%H03($M$0j z6#Oi;>a#7*_0vb#Z*5oYUifDJ_Jo%G*YxW0w^2LGS1VfYe{KEC2E*y=Umv5#v2XJN z^=9u8pc?G{ecu3==^x6#vjaRlz;7P5UD(X*)AIm4z`z3qYc=}MV}sNCto{C8!5}O8`OmKpg)g1B zpU<;=&9*e>e}3=3tA%AvLSOIT=>MdJvijR69AfMF|H3~g<4FI0Ypyce{M4E8MXcov zjJ&>kp`PIWzYwk+{rsaZUk&Ewr^oS(OP`0~;hMex|Camwy)wPr_{(h#4pLuWzpr+G z_p)1iEidDo@>*X{xZV1rxK7}NkNU6E3IhB1etolkcG~URe9ziY^BaMF8QDJkgE+|a z*{_YC(w}o-iS=t&o?q(=UWy;Th}k=Q_CuhD;e7K!eUkY38tAZ^Un4p^z`h&c0Sq3r zAAkM=G=Sd+czA$cKdO><_Md~Z*mU+^BzxQUar+2`ALfs*$K!ru4`-R@{a>k1XlmK} z9WMlq{`w6Wf%-o;G}ZKxkNe)%uauNq09^P}H3z}kM=3%%KLc;nJ)1J&nO12(GL&reXZ z`0j%CzyD9mHmBBp;KcniO)>nc{s0TLBZvHLsmZsmt=R9_`|jI1Km0UEN4O{cGceu7 zKI(suo*$-*(R9Rw{`-U2X!-o^3-Mr|6YQ(`{XdpIS6Y4jv#S-g*Vg$funzzHmS2A@ z^n>(QI}-c;scgihe81&N?5*D)pY3cOZrgY4KTAu*Km74nyEgmt{r_60QUBS2<2wHD zw=6E{d>>S<;^J?VUx=NnnQQ0o)cNl!{kQ(GFDE-!)yj~^UwlJ8DO)V${iYQhZ-2~% z2CuSzsDDX+GHI&!tGy5a_R#wj|9;Uq;!1s``nCV!lMk4We&6~@@ACcpSIg z_$L@?-kbiCpZa2c^^ZZH?6dXFXL@Oo{c%4&w$RM-JKt-1r%r#BRcFrvzxBO)aR29t z@$vU9CSXpX{NWG&n?+=w?A{~b{=cmW?^1vMcYgn0c9vZE+kAK1|N5f)XMn%`=AYG7 z42Gqz#=gS%CeI0f8nlqD^+oc8_gH_a9{&CRe&Mft6q}9E<%D0(uViDret^HzU&S{6 z<;mq)nQ?ioC)*E;cR@+NSG*Vfmt*Z>{q-mP9Y@&m_~t)#Ff#Ztzc0j3sN=sM>U_{Y zE;GV?ShZ1F{yq-gMDfA<5c5)X|Mr)E2BobzAMB1>|Gv!cbTBk(@SuM4li-zK!GFZV zqOpH#vaCLrm?6Fn4}T?xod6sF|N95`j@|QqU^;Q1nK8oP5A=V;@4nJr+hB8E{Jul} zv0roiSzX%uW=r!7tNNc%!}a6BOvc(@zT+gH_PAa8RXL_}wXWKv&t8o+_4yTjDenSF zzG(dEU;B~GP`>wn5aYS}J13L=DE>70JISWUfB(hmPNdYRT>NqSl`|H*wR-kv1c z(nR7@d||3T;0zU~_{Ve@-1+?PpEJ($`JNvZ`t^N2=2I(p7cVGk@Ozq1gEpV}{olrE zKHu}pLpSxE^B)-=go@>36^!e}qiTeRb`C$)_ zGGBC|@w@t~)gs{kS3l@YojiT!SGO10>AiiFQ1yU6!#Iz4{LT;ablDLwf9I9n9$)w{ ze_xoeqx&GUO9cAxw~n9ou>DG!)zwyUMcZGcD zLp*sI>rVgm-|x~^`VW7*`}vj7?lwOk&RYCi=M}?J>-kG*R-G|9@}G< z|K+n&Kz{q|f~$PkOXaIbVL1Q4Fg(CK8lD}$53hs6!LRwv|LGqd;NSuH^?y1>N+0_E z_uasS{LN1{rFDK5mM*QfE&ep5!4La&`{x&p-%R`2N|4TF>l#QDKx{ zYb{x>U%jIPnDUp8C)JNYKDqSYYz~XJLCS;*-7ql?vl-Kj!}oHyP-pw01-vU^`lDWk6|K;3dU)pb< zT0eUPV1F|&KrPrN-uwrC|E~ZqX66&3^4}lFVL|hF`+x@rc&~z7@tQB=4?Muw1IGhT zgBADQo+moQ|B{tW ze`)`H0aStt3iQ3*W@G->r1r70_eKA7ulil-Md!NT^P}((_WuCvhXY?gOJMMA_J7C~ zZuW~TV4VH)5s}+H>L>PlH7n-@+webpc)HqzIQBod)LtWYkM$;ai;J81PuB|5kdL-pSzO&-3H5NAq-As&?ueLVr`Q(C)mZ>LMleC#fC|AQYeGX3Bpkg;O?1IQMY9(t$4}!1 z$houkbT1%#Lc*O@Uq6TX&)BYPYw7!z0+YgW?|^`Ue)NM6RCtggpaOj&Dl!reGD5hc z+$18R`(kQ(A}Vrba(U|t^z=J5Wy&qCvVG@GyWdi)CMGDlq#~v_xHuxAwKO?f?sr@} z-c}YD5_i|@ODxF=Osq^xiRvl}EUfA(YpyKEyYvPw*X;(!$-H*5zQVr7w(`Fg4kowP z6=nuD7i7j~*5lm^7m)YtNjq@v^^zh&myT@AB#k z3kwo5D_;w?Kqj}nyuc_d!NFY-B38_8zo3d z30Wn@=?R*u<$8Wq?e#iRZH4^>Ys1xAC!6)K6Wr5k#P;s;+S{?&JDDwQx!kYlSEtu! zhg)vM!`u4{-S6xDF`NGb0}Dsa3x|h%rb6dZ#KlR>($YrC%)7fj&2m27pPi)UqGMlA zxpR?mZ|^g7@u^-zeWZ$uf`*{wf?@GvXmdD|G+sPDEiJ@cOjKQ+oUD9=t;fWbN3zPE zp60cB^R#qaw|)M#+X>h1<_{7Xsn!*bn3})4o}Z{y>hSXUs*b%Ug{5Qb&Q#dNLh)5@ zBhfe!7roImPUkg=8yR<36OzW`t=ve-$>nq~CFtnsFls0-DynLgy1ljfYVP|-kH!K9 z$J5f<3J%-r>U*_|dw+j}jgN!u+2Z8o;#%x?=DmBI{M?+(%>VvFe?LD*OHW5rQ}I{! zP5j@#x11H+6aO9fwcer=>h0AIw< zlB8F5)G{q_L*-}dHdzLIU26NrR^1wHAx&RRnbqB`CSFu^oi9|QDhV6bUK|#9 zuYk#H>3#hhusPJoLMZ^J%+R2=lB0xdR(jPgvpA(8$uj>2K{o=+j2cEeaYRLcs&rZq z&`w-@3dXwycn8T#9oD!Igv2Z&Nh^@4h!bB%D_9(x=wse7QPWNJ14$4tJ22)a0!QVD z{G{-DH|Ek!(UG@zuDmp7FjRaND28uur{e0B{()r?-@=UF#P0@MF57kPo=U0}fbF<0@WF9}xzzqx#@L98cx5DOV036Sap z2$7?1gwqw;UYt$40t`#SM#Lu&5DwyHz(HGa4Fr$(Y&(j`j9>^SU~^@$?V4Um0(eLR z472^`0Ig+L3ey8-@QF(T*t*93vXFM{-Sw_m&>+YU}bW4$DzkKKZYtG z=3&BZ`S4a2a z{tR|aFB@R!)**KY9XV|}~IiG})SqFrBGa-Rd3oy&@ht9k5mKp^JFqzb;5KXtxsBdUqLRff|pBb^XDFbql zcYasI0XGgbNAmWq4^=42oYqj_?exUy6M;g9OjBImca zFChKWF`(FOsi^5CBy4f6#>EaHK&X^7{4i1o7A(IEDi0uO%lp?#rJKv;(NN{}>CSqw z!^&#XW{(zII#8MJP}|l5h56LBFS)tU68ZWEpm>ZdXG>ctbeJG>{~UkNT=G{(x1ag;cm3hek3NQqx2gP*RC}h##s3O&^QTq z!Zhs+GiDqnuWjhs*%L~)aCF~PyKYHkDqC_o4R`1Zt^Z~t!aBjweTU&hP&S(U_j+iQ zxB1GK`s@Hm!iC+g_vi7 z>9DX~yU3`+bNH9h>-XUL&uL5pj85vUIbj>X!D1qPYGbZr@ykqa1WwoBe+9wi%@Q?V znW9!!0lQ1Yb&Ai1NYMrC2(Ym$nQMaQ25~3&XriO7DI`XjL?yEjA>l)N99_+5?v@)6 zn6~=2TG1Ne3$B9j!<|~gZjvh?v37|^tuw+#B`A~IC)#ZhMwQE2a<~BoXd2ZB=3GcM zLa}nkJFI>Nnj>M+tVEKC3(fq3skaq*;fJ%lEz2u+2ZCyw0ciP^c34Z^6-#W!p{Cx? zRBgTL25O5cZnF%|iAY^CFx~-ifyq1yQcRKfCNdUoVK^y(01~j0f*D5j7bLYI9QmPA zWzhCMvUFOCe9H49(@+N~0N~ks3r6`B{tjlI0Zg<@D%RQ06L{?7GSvoIwhJBcA?`X4 z^ON?h4LR1V_Nq$Erzsp+)YTEi_;OI5q+ABIqi~O02r-pnB)+20%84h6Mg8UPn$3*- z!{G&;xmEoA4FZ5$aK%`HuIm|>1J;?}gLY(mnCsMesQAvfY~Im>$?+N#sII`M&*mqV zOuGgEZC+JyWtZShG$w69&U>Wwq1pnh)g6l$r|}lOr_>FL{{q# zY8x{(&l!krPOW{Rupu+MJwrZBH-1YqqI&B%x8*j8!FS-OK(V>^qn=1XKM6Bmhp+9$ zbe7956u5$*Rb*v;@%c*qR(jz#1mvWlhw3%DGAK_2^N_|OaLiMDJ4M5p|2}dGFKi$2 zc7Vt9j$E@Hc-i&3xuxYMk?>Y{W?%cj1}j%Qv%|a=7|C7rr=G{w|;0>BM4`lbmn zYQn~V1sS&iTw!u#3~+Ju!^*rpJy5C8^nCTG_}ly;xpR6$OG81Ijl)I3Jx~aTh)}7@ z(V+5vH`+LN?zmo!!{0$(TaiePEN%B=%|>^Z9ea;*ckCcjIGBVElkf)fTRKcZ`A;A{ z2;wGG`L8aBBy{^A6kao$MZ(vZ;iLd(5C_d!l6ct#DZVZs)OVa&s++nOX!h~}Rvyl} z=LB8mX+t=6eau5Bj!PK$qolr}lC^YcvlZrj~B@zo;ZU(b! z@1ee+MO&y0v)U_SopFc&`Io~&c4*jGSk!&1#1<-iwfaTGdf+@RunWdoA5NZ)nKY2~ z^iIzBWwb@Pl!v#6p$V0{ezfLk+s2AsFt>&PqO2sVj+|p5NjD=78gV2yJAdK*R)7xP zDi$zg?U6V8=`80H(bza%$PBogFJwfRogo68jDS#zw;5yK2ugfydV^(PQJ-rG21CUB+ zf33JH_mZWkDcNp0S>Kc1mZDy-M+35tP}TyOrI6Uq$S=+WWW;WH(xL!neCg)k&bYCl z=QKul=T8a2z;VpaS8lN14U=8f2Qc_`Tik8({vV-00cyYIGpBjO7l%VCgt+AO$s8d#GN5f<&%Uhm{{Mrth*!z#Tw_SJ$|$}AXU}Q` z+P3l8$5Y%!^x9eAx(Y$VfQ+eU`@=nl69bejj^&SH_!*gQ-1f=apJ8HQR(>{*e1Zjo z8Y&vLy7DcauMNrA=5R}yw7};EwD@2grZ*-9hMzO{R}QVIkitu29(t;JBK%n(Mbqwo zXz|Zhs!O*&SqU1Afzr?n!C!|O8n^|^F7o4hmugJy<4dVdol|e2ewjVhJiFAq19yEW zD3f;Tg$*h#g6Y;U#07EI)co`it`qw))fdq#VZuuAxB{)2lRUirwn2j>OJZwM@U(pv zg?7x#u)vWrL^KYkfkcTf?1b6A*l#h5kXXA_*Lkx*CD}QuOa)JK95c{2_rc1F{s=UoNnji%xvO9YFy@kK=fFPFT&4nmJx9*; zP=Hx`<6gz&II!%oq$)PnwUY*p`J9~@D4Gvuno}|K5H>&jF|L>h7u*guFcF(6H;*gD zD_e;v#yz!75bGXxS8S~!_O+??c0w1%=;;P=%9gav(mG$<2LqGq*#XC$6vr7+d)?iK0p=&E_YW>CTs3j^RMSINO-) zrP?kv^2-#G!(oMEFs`c7+;K+DkpMo8&`f^}%IWc$Gf3mpY=dm`<`p8KHl&;koHENW z4+%AtjSeKQ3qvEeFdk5%CE*z)L@6PS@nq8*2bn^u;H#VZik(fn~D1C$9 z{p6H1v#LT-#m7;ftnn()lj|wYr4xl8DbxsBiqH7$13lSd;7Ux!pgJ7I5?FIUH_?{i zRvTr`bcjV+SfmAYudq$Lpg%{LN#z0D^~x}T-1RxIG)j?8`2r@94Sw9HIUp+jR7WU+pcb_@LT+&=F;_uql5~gOv(sP0&qaY^ zHteP zEo*7y5(20c2gv29QzFA#ez36VK*LETTV=}ixV^%=nbx(X0BW; zJUBvUoNzGVK#Gv~F@#Y_5_dJ(2P%_2@RrM1rr3?RQ$!da)unGUk!zmb3JICmDGcu= zlO1{m3#fbj;=l=J9YhNRC3yMBL)dkQR7+kf=y%m^4Tp1%oH{~$$Y)Bt~(Yz>`dmVn*gExqx#RQ~D9@CLx(Qb|& z8>kK`>cA@rOu!-;WxXMD-d_)OBAHxxvl? zE|MV@e?dtVz=L{i-7&XW$?`0S~N2F}u~VU0kP2$wLKu!o2q@wf=L zP=L#*LttmQv;*2&^i=rTysS7b6)x(`@8ck$twb&Fa#{ER{VN@Qkr?%i%_6-J#6#Fr zAI&F%SNUL2X-tSgCS|N%HZM9x@FW(Uv6!yi&W#Dw`poO(nvyP|pUVWgC#2aGvVnu4 zy+fzQsEQ0@xHJWuKy)Pc0nNrFhb-$ffZv3SUfU28ar6xZr_*ZCiJx~_}> ztYFT)vddLgUq62-e;sA(060PvASaEO*4w*kUx~v5`B_xx49Y#SuT?TYZBUN~_CoPY zW4VIa7kK>DY<{H&@=;XKS63@f24-5Ef2|~Bzgiqh&lhwmwY%r`KH#r9`R07id1qy@53-PZ z=iiXWz?iBqig3iK(<;;w7kdXxC+3z+m+)Nm%(*KUAO1IM^_Q#`+_0ekehG)fZ_ zEqRpfz*H?yxPE9HlLkiuBg@E*400}UIAl%(@()vB1j|g0@OFG8ky^0|_hxQ<-#y2Rsxh>Gy+CAx#?Wyv|mK0o6eGooM*G!ib;2RwJ0;g1QXCH(}fvs+sIb3i) z2b_vUq%KqWl#3prwse+A2e(KDaAY->1MEuLNW0$M5Vekp#AdRofako5ag*_`Wy-uv zXi*?v|93w(T5rVdNg6+^`Ty;OD^1QIRbbjWKbd(-=_cqHqmi+kevy-1#{PopSd2c? zwhx@kh;}39^DGi~x#6G%ZQf{TiG$_1n+BN1Gh-cyAVMgK%z2X~J4j2*LnoL`MCRK8 zw^?_YW|{Mi_TH@`V_aT~U(D4OD$G3_5*>XkB1B?jO75ca&^mxj@+7jP449Ham)5c=5nLGI!G6Tc zEdwkQylip{(?82mT+D1i%$Nu|9b-(ND9V%AkbT;QBDnxVbBQD*D0Sv-CPyHW!im-^xYfmbfOZt?8_GRBpGaD ztOnX8u-Oj1x&NY>CZx9+mKaRNo%ssM_nR1%1y9~Q(M)zCom*JRE6@z`RM@-tkXAla z);L%wU&nHkNF&ah#wcxc{7{ixsrp(_=b+vHXF&jwB97PnbY!(RI6_AvOPP( za6wAm{&>)>Ch4p+ToA!~`XT>b8xmu#{s_c*Nfh6g+x_wS5aLAn<)7}HOL;@>=;U|0 zCEUhk{oC>V<~TH{6gVbhHyjWJ0m!&nz~o-U-og>i^9hdG7^S?<-J;Xbk}21GGFU4;U2pK>J7O<#+%A;E5qan^&so`tWQKrlZ$KlM@R6{3#NQQmEm^Z}Wkk`M; zZgPzQM)w>JBG+EggRpwV`0V12?Jvu zA&I%OGE7LHP(w@q@h=G z&_N17Nwj&kg&Lk(&7yK^pb`^nlPdRdvPOZT@5qrqXnM9*ZC*;x#FvcZ@PeYW14cj+TuWkPx-l(-lL~4pC#Nh{ zb>LJh*KIfi{m#t}O+)T8d7*5;algI^=;C(NR}TlDHX3_8Q5{;hSwdfoJzxKsFrAg# zqirQQVpoecYqk;FUu324!B`yqu^AppiI|sL67wqZQOvK5mDNgD1iS)jwpUO?M-;+C zb1x&4FQ2hiV3F?RphbD7s8Wtz!q>gg@91VT*0rlPG+*(Or{g!;DOP7RX4}E3!L$mk zw#?K;gL}U604UKk#+Ue0>5ARG!9~Ez%J`0+0JG__l!j!s6f+vnNPVZ^`1N?BWFMO z9u3tSd4yhPzrC{s1p(UMU+#-kB_c<8-m1d_QSFScEvOE}#m%Y%gJi=j?6wF9GH;l#-7*{FqfFGO#l(qkSo@BG!{^)Nj?1hRpZ6xO&2;6d zs~cLas>kg-cd<>mx!F}>+M01)VLh#+TceNWCz7FY8_u_#(L?`&?dxhiBQ!?7QGTul z0^GEAw}`>V$odV$4?$)ZJWcFe{~MN4#@QOi&W-mZt~Cc|84+x{=!kdly?{`YgM(uW zj272|T2(_3POIx*C32V_>8V7H0V-p5)^0hCZAr_iBe3*U!T`Y}kwdU2qkcqxW&Y%p zSF`8->FQ*tEhrS{PG-?)5X7G8Y`fc{DFb9DvMGAH1XL~EIBF*VIwsqB*V}l8za*~S zN=N4ay<9Gu)g&3wa!ERzQWRpntqM&`sI1b0ha7BUVdhol3MezYd0{ZBviV+Fhe}o? z8KL_E&_SsMb{8wM=f~bI=0Ng0_l}Mt21duNZ2ivg4tX3!jsW3kfp`ve#kf_q8a*bJ zHMCA(>^zKkV1j%)uJdn1HxeZLl0H9wq#)Wf35 zSSkBzJ{GHTPFFi!m0!9N&PXk~x|4RO4KW;>~>*bnKd-#=%1+ zN6%Bt_;|bqt~Z}uP$(vM)5xV|t)$%rB&4Tp;os5f-Ggr{kQ*ACaC~AGFrD*s_CfDB zyx}QFtFtQI!`T-vPdSN|joU^qT-!Z}cb8EX!AKfL1W!+n%`QonQN!*{A-;%36hl9^ zA8Rf?P(Y&gZ(>dn{CBZRpY=Wo>qH7;Mv+`hECiL>gIp2?8LoOnM-~wx5~tf>94=nh z(Flhnfl<>cYr7;I>QBGY`@tHv;t>vYxxEM5EkSIN;!gi*KPw0XV}*UK8klJ_tM zwRAbr(&=9CMusr4RAp|g>J0fDIgw3%s#ZH<9zbCBDKhm_Q(-6#X$c8C{LMn{(qvE_ zytfJ%L)v62Fmnev+YrHOo=R}H-UBU|%`&f6Ed@Q~W4%YV`TG_g8v9LI+?i(|l&-Ld zc{fpjr5xd8vmLN3TpYy>Iwu0Hh=E^jORKxy)}T~4_f7anx<%*P*1RLBcS9Ru+-Diz zit0!b`g;Tmasq>Ei&wy%90QnC9|<|O>s5M^3}?o@Kv%|x1>T2bEMEZ)cg@U=#**t6 zmT&j`S=r0IZDlS^i8tQ>93{6?$i#W}6=sB6qEe>1uSV>yOf@g>6fB9!f#(L&ka?hr zi(5Pg+l=HfCL$jShU|VS4}ytv!8boUA5ABH^f~y?m1ua&OL&bU;W&sd|5M|p1TiM} z(-^2O_YNv62<=>1r&Zxxpeuh_NO`HcSfF!p3F6=05tQ0f9Zkw_n`9~}$PO%Z_Fi1E zzI(C9{^0p_Nc8nEa)|LZrGch$%vpoz5ixM)RN+LrZj&tp*XVFBX(|+E`R0s;5_>}k zP>6NH=E!;T0uT(C^=AED1Sw87sYw zUhjaD5YMnvk1PWi9H#Z-5*veldDbaYkMFq4L`Omo?aVrj7a95iQHBOF#9NWbS0gC^ z)VG30Vd`?%KF3NxBvbU-v*(Y-*0#+6GhSp-@7-Yb>9m8E*`j1tF*{2+hNlDFd6e$)Ht*bIA%_&| zcpDs!-NYPEyL1(vYhBGDF(D<5p?1<=&)Ubvj&MZn>`>~n84Qv|HeKTu$SyBaK)@PG zxo`*IZe0^;dNPxRZ#nVBeY0MTi(Vfdd1~ny;3sNyHZCb7n`&~nDZ7JAsXCF}&qOlc z+97uIcZTJ;z^S(Oxk_>wO@raQ;CHPRkpwNfkA z=?tgrM`PA{QW8BX+lT78IM^KkSB4}MpFy$(1%dQfsgL4FfUHko_}D+|LytwmFRrp9 zz^$No5gy0adrhL0EOIf?kCVkml_C90Xm3Wkuu@^(6&LOw^sW1G3$G{djT(z(Uea;4 zHt5c3J%wKkQ@+KEpypbW@wd#-Vd-ZD%>0R7Wc`&Q!iwddrPAC&O2-QCsI-M!#x*Cb zY-mK7F&AW}vm!*Mk!`m-pGC*F(!^+uZzVsrFt2C5pB~?`hAC}z?P70NuMFMJk_gaV zM~MO>QObcO#swd(4H?q}qm9mT*o#%=mt1g4Vd^NaizatDy8BLU_3O*#@8Laz+y zXuS5Z6usT7HNcwC_^dqNnOITcu=hy?!zxc<1Cqhc4k){jg_w#P+HPGmsg_HXQG440 zh@s+$#0d4d5Z;sn`woKl~+VYj#qw@+0i2Ok6${|5#w0)A)91u zhh;|+=}!n+l$K1WTbAxBk&ly^zA^@&Gzs*(CMnW1vP+I_h8c}JTWvbEI=1r@E`RAM z459M~ZfVE^b2G?c&4Iy*cv_jl;Vc-(5#}m!cW`o#ud0R`73!uzw#;1Mm`@+Ni4jvh?+xYuExx-|7vRmX(-58^e3ybHfnh>>@ zd?m$VW4Rjup)Q-Fl29-S?-vys8@`Odz})?6)i5_5O0=t*NM5JbzhNngKQU>OjX1zn z0h^waJDoYJTcpCxk#-M(Q4=L4t9M_hSY)CDu=ncR@H)8$3$*OQZEac9A;tv5p=p@C zj)S_aT%=wRc_Od4FEYnq>^MTn|C(dw9q~!sxiT-r7w@|dSNSQhy5e?t&akM2x1~xg z7zUO>5mZ$6r6{QUYUvcz&WohfpT!XNE0t}^GmWJK zfsIB^DTQg2O7m&OWO%`%eL2MF$Ciw}b~~{^ToSQbFX(_T0%HS&Xgo3# z%z296a`&DWwI3A_fgInDq`nH_*CC3xa8WOTbPyL{@tcv&{@O4_WPXk>40r_RS@Sp* zP|KMryw1xu;JCQ)4TTZTyFIER<0Uk%pk-UNWvkK>=UyO*q%7eMes+d&a`)L5Xa@NV zJ|4VO5Z|TaE5kI(arOhp^2Yf)b^x`k@EevY+A-`WoqWnvqJ_Yk4ktSt}T=eugI?R%u? zs^h|RrzBE*(rdR~RoUBhS&pa@twYaFrZ!V2@hTcI2D{D3oLN*aT4mtSlbnNxMjLH5 z;Cy&>Y|!o&1h92-9V`)8r%gT}TxeY`2cy{P)(1ACBr6*gtHx*Oz>}k^xjqYVSd}Q! z^K)t2`%a$4lDbhX(RGc0g%=SXl`p$lInfC_AY-%j9-h#RS?g0nv}$a1PuMpSRJH1= z1+Ln()Jd+*`<&#$wx7n*(c~!?l7P3d(#(8K0oO=PH#KaR?tC>)u_h-eq)rxr!Py-3 zKFaV`8+R)yU&unUAH|FDT1>{IinXUx*wS(zuzHQvcFTE~bB%XCiT30hTNNYW6pRj_ z1C%2=c-#uSs(ZOH;jW=s_ZcN(_H=0^wdlq&_>&iqy5y-=Lp$YQd2V~K<5&_#mSX{a zVa%}lo#|V|VE~!DBd%(HyL?}m>w9UF=#A#d~^t+!7V9NlQZ)xfY&Gd1ua3Ll9~U zS~jxU*Jl~}ZEsY^(k%`9asD7$yOy|E0d0ArDz72FiN9e|~g|Mcd6W7vZvzh9v zHoPa@7M`y)j9?f(RD*1vRW&oE+JXRH3Ve>3aCyQHqs*MiTu{)_yMgj!*ZI11AUa06 zt?Zq1(y)@)r)cjh3RPG;pPwOqu`cD;Qf;#ht29WMWcLYx5yMQE`@uo=ftmDNnnxue z8z?~$mm7EY`*>adF3J;tk8Z$iT5d9nhB2e2t=a8kOp3s7b7;pWa4Weph2wU^b zfIo)VaFhx_dT_vU3RsF1Q4ErqaiqBq)mgu%ljg((L_TI6O@&m4O6_u^78 z6Nk*fDd;ZqjaxgsOIZZq*y8BD9L)~dNc@2 z$(1cyZor2;L{*)m6n!{!xwUq?C+iNagR5VDm7xJnj zK`>BCXzLWss1C%Fvy?>*FFY`dqIKL4xcym|d1D6y^oJ~k+eT~mj#CketQ3v!9M~9= z8rsxF+_&D+vmm=5kpr-37!{@rs*U->%$%ACAlopL#tuXWVE*`MzU-SwgrKK1i^7Y@Q;Pnj*OVR6AYyF<7{cH&UfskLED8ctid-dT^jM58cF zVrm#bT&)j|0?VQa3KX947F)|AHpalr{r~<~ao{X&2e(3Vb2=^BG(7hNV96}fN+a!F zA|w2mic!xDm9ll@F|H5dHyRuBUM(?TK0YUr(_FEP8HzZdISipOLz|8-Wrv@^Qd&i6 zck;!KZ9q@(VB*3lVe&^>Ig^32ZV|pql|wQ*z*@V`O>$mS;g8;0_Y8fqqd6N$yjYO0m;`ve`+$A9Gc{poY6>W#9e?wLcryro{ zd@tNl9a|Id$A+)2vXky0ESBpN05FZ!GwpExa-U9<@9*Dypfk@}h-lSheMVqkMP3sP zj9j*KS9Cvj8$U2Z1(qQcOMpf@VZ)oZeKHe6KxAy%1mj3_kQb)Vhs?Vxq1khkRjnoqx6k8ZfE>9&oOn*%;5R^K3k6*yg_!ojR-=Us zD%SjE6T6HOapC+i%BwPy<)UzS)I|UvX4oCd7N(5NlVTC--Q_!h?HtKs!&;Q2d0rqf?qYRRU;@VQG zJv=_3t#qSBqA}Jz+Q(T-A8spWCkC3E+4PT44V!SRE&AT@QLcQv0P-@aP(+#??Z61x zJYnzP(t46{dWW=~!N6~1U z+YSes&1u>-gj=RzT!evd zhU$4=_J2vMl~4s}d)z+Fd*lgl50C}wbWEX98=xt>ns}x#+i#nPA}NWe*tAr{J3M`Q z`}R!DtQ+oYtRdtIJ%#&89+aShr5J1s*_UOK4APKqVyU${@{2dq?+=radGfyx{$2=bwJac?EB6#x7syGekW--a}f65q>4&7Nn-m0kHWoj%{%M#mehcU zm(x{&Q|Px>;RFOd2~``+WqFG31MaM085Y&6GQW^lG#tAD`L@I96y`P6Wb+ju4`zyM z_tZ+oZhdh0K~t(9OC z5Z*!waDB}B9;BKnY-y9OI)9&}YceAD4hl2C92%_Vo=bUhgfD7yeZSTncEW9MT3?_& z+{&TUAEyw*r>)OPvZim~c7RPL*As?t+?yxM|YIlOyv)3+(D$IA88gm-@6=hf*9NpHN^&84*4iLSsy^w3XDB6nYD;8v1D*&0MC#DZ0%Xlw&-yX*T~c_>ax1w842#uTa|Y3R$i_-O339(^u`pu zZ+Pv4NEL-SQtzxbEX?8jyi-t62>{COVO)0XIVBW2SmV{aA)<@n(mpDqm z;8Zd?9x5rgWDWpGK)1h>5`OZE%fuHJndPNY(ba+BL>i2Z6(JPE%ofwk#L6;sbgM*) z`FrI&N)4&oZ7p`nk+sgVau&Rxwrbp#V!Y+46obl>-Mx(I=JBN{`0ec1c^T~R7MsWS z(#K53b17ktyyn_O{>M~2bapz9i~CR~GHM_?y&H0Q?d?b-Upu;`@xTn);Y_VPY&H9y z3%h_BRMH1(^-w@coUo`# zfC|t(!CDLzb?`vuB8XZ8SW~275Z@!(7po}an2?+y?x-u~V zubAXk4SD?zDh>KAlb*4%`*J5AL@jz4>Qu@n+NO0wrdau&V^Ti5kha!F@LR<7gmRtq z*VP^xP{zZNDFj+V`c*2&zTh#{WbdzgfAL{`LbDSHN?o?6$cRf|Gigk{&OXZILi3xq z4yptXyFR#vwcP(;pIOr7;IpsNQjJ5W9C;M%k9YH5?{LuPxNG;oDmXAkDf8ZN^*8ck zZ_&3#FGa5W?`)KEj$19MXmoZ&lI$q9WK=228?A?+{lujZlj-h%Gz2YgRYY zegugNS=jW?)h<;P&_HT>@UP*n2UGW3c%k|2^(f_a$f&OV5_mSAEzW*hHpIlYEaESu z?MR(LRN=Z5gZ7NnLSy()_05(Qi}PE$Ym5=yPqfQLPgZD!3=*6Xh|IQxdlT4p+SG*F zrAIxjJP@daJE-WmCvx%{B(pKEnRO;*Tn_5gr=Wt2+~cAH*)Q(irF?Ict^>$7WWkk* zm2r+W0_cj~<+HDo^rN2YFU3O9Vv zEZSsT?YqEj#+jv(&-Q(5&ec29YHy^)1+-8L-%%sT_3TWB&}PJ`n;GcaXzJs5$^@oD zsml89hSX2NJNJ6hs`uh?-S-9_h-)cW5leD@=nj+ib7g|HvOyD};^jm?iScDnc#L4r z6W6IskB>=_IX9V?`7HR3$TbhVcP$3b7kAu%uFx^X9l+ zpcjqLjX}xDtjm=0u;hZ?bT@6IqHlQ-QkZfUJ3D)bWq~<;OiD}~azaFmN);RE`I3>9ZNRyg6dV z!7T-+;vPew#f~{4`-YUAjKEeEOqfCwd6HKtL589v;PYQ#0>r zkjh%#^cUv%JdZh7&22}-yQ1QL%|Te8>&#$aOZ0gjFH=ov+rWC1F8fTya6n&^ItUag zOpr~4H^_%9*P;c)GGB_|x2tRdK%k>^L*I{>29=T;5a)&X)pOTLl3<)mZXzt(08KEu z4(sGKC1?@!KJ~VeeV9I<449X;7{1cdmDT85A;KwiqN$c-3kn4{+O&L!w*C-lhw_>L zXOvEw^YT1c9|9~LATH#D;vsxIcNQ3`2zFl5a;GA`51!(->t3^VvZeTtP+C<{O@CL9dmi|xX!TaNS^HD%HgNNG(w5JX z=Xy+=>DHZfJ1E3i>&{(1Djq{r-G!=V=Id_CTwLJnr9M8o#-g5%XKLG+E5d4;E0Qdr z66Z`T6jC_x@Tm7T1mk@8=-Hg5dUsyZ+w3F*lG>+&bVsqrk+P;8N{*M)nr51KdaW*{ z2fRt$?{6As(AVS|0UySY#SW&sD>rqa-gqz8;@{}FvYhoIff(C2lHu2=W^1dJlRS+h zgn@qS^nSnVVp`v!nC$R3q&b)?^=!3d6^q54;AlAFUYBF%l!ICQ7bUL{f`u`4@_3Jr zLbg*Aao(*caV9I78#0pf68obBeSj*7SVo4V73v ziTbG8ZLY0t5pxEkcAlH`K9=T%wc*dXrdLK=p~ul_s|g}rq$1@Iul6h7^&pG$bW35| z%k#MG9T|tL2$njCTFt(el}ZcI>Kz-{YnwM7x&wlGB^3?dgQF{L*qdOE926~__8moo zNNk^SKcXDE_~_5<%y75X=Y9Ok)TMgI74SxjSs;7DiY!5-)uiOH9m!kp_8Th=i-yzD z=9qp1rlHeJAe!QSe9}RLCZD6dnX6$|0x9y5lGZeiII_uYsVd%<^K3XcpL;mkke%Y| zvJ|1!OW{@^a`;WpL#liqL|=MXua&;&C76jp1w~a=gLMj8vobpH8IgQltdLr9)&N_k z2p6KR1c?0Ui|sm85&-u!ftMvlp@VVn(t*tfrMX(}X6g0YgQPRzCwjO9C2Tvr7GnW> z#@yt7fRjr|>_d5c*KTX96_<0BX`+ew%e)wb7B@fR<`{^ZeCgDH2SjIw7)kK-NTq; zF`N+}%dHD`9I8*LdCLr17$-z^$`H>iU{V-g-QM-mCE2N>brNy+IaOT5cBHQMDU`Re z=^njjL@L_PHlO@_nhKfuNnrN?aJptYK4jR?S**Abz1{;pP2f!g z)FQpt<2JL<$Sn<`_VCzMSU8GJMk>7xN`7wtI~^8nnk4U=SZ)3{eA4B$)8xEO{be@iL8>& z9@C1LMR&xTaFfCy>2uQoV=knR|*9PZjz>4h}0>37CW$PQXC zUGa%;iBCLH4Z0~dx%3P+S}y6j$V+xuc`W!0rr~!t-1tjj`3iuUh?lUjTU5Ak;X-#p z-YYyJqciFp{xyAY&@-+$QcuGe=dd_+oAv6qn)l}!dl7PY>p5-xmL*7OE8>nb>Nvpr zRe>B|t3xXyRw|oaEq10v>mny}9oWySCyhDJtn(?B{ ztl!-F0GvuzLjo)fTIum%h}ga)j@0|YwT4LNCl|7NXJfy4%y1nf-G5@WORZj^=JVyC zWLcM_`4^6Try>;yk40}Ugt_I8n1w2@l5NYwUSayGJ@997@grE63C{hCi=dJO zPk_p9XZykx-?ap4m_GACk|Amlwz;Z9&D)#7tERkAkW$XkS*PD#Mj&*QK;U6Ts{3lE z%iQwS)C^M>+Mf~8>xX5nSD0pJ!jK_NaV9S&Yjp3((c9nNP~URvc)Lrk++u~5PNten zOS!Vj!}kS+KxHsV38#Ix<+D#Mb(io`&>@uz`4i_79E3w{1 zBk0iNzR*@%c8w6;`ztbRa63HHA>LGwsUwj|-sadYX4J18PZ26DacB-xtNd|(!5*AX zTeVK#uxQlQ<$XRc8MOCoH0H(^VY6~ZyRI2Lp93@5Ang+J(L&O9*;;DTT z%YZ4_a5soRy%XibFrxGgSq2x^eR?9dJC3wtVTT>HCYb2ml8A|1g7IPsWZ1}Vh4q%j+!Gd@}Bn19&IjI*7vi(kLz^&RV_Pd#~_=Zi&PtRO1l0(s= zQiUKkCMwxa#qn=EqufJ#KXp*UR8mp|Vo2Z0E0gvbh6h&1#9ocKyQ2D<7GsH#p286m zYUHGpyCL}{KLz4J2kAGtw#6Q}>ojmgV;JI31ctas&`BoGUfg~cH_^{E?V2elu{ATw z9`k4qjv#E{U*>B&1)I{Txo=AlJiUf(cAg2MbLTM|+S+N=b|#0GN2}Pd z%J@H%EJ*R2^dzvYsyF#>Bs{POuKd(T4DxB+{2n@yx^&LDgXwCvU9F zyorq8bDiXl33-N(z>;xEPf_dnEEu$QX(-TJ9V%Krm657O4fam}ppj9(Uxyp5i}1ij z_3qOozo)x{dDR$r-PaMg#lSFT^X&NTw=31B5vvQ_zfp#gkMvcMc#2y6BUUQi_H6*Q zY1kHo7G6eZQ5%{F^|}B_5rBs&!c0PJb?#B`1kUpY-HlHU0bqm7&U?~dbc8a#&$vpJ$(lHFM;A4C=4A&ehX2p?Zlv?fT+F;)_-yQyjxyfpJ z91e{g#K67o_fJ5%SnAV;0yZ5OJJ>m4zINJu^Ks0vz%%aX8b4{!FZP}z%q5~Lod-XD zTgi=z*)c07psm=I<~{V|712RUmgCa58+wUo=Zp)vu_v z{Dpf2`6<7yWnEW~n^8d^_=E`;{cff!M?RGbbrq&$KV)l2Nr|CVGV;@+bf8R+#U(@>>K*C zRNFvF(zW)YD>O`H-r~m0h9Od2d&s^)24gMtF4rIbFiAjm5vIhQOt?*AIde2D5T9EC z>&qHsD^`x1Z?=whg_80#Ku$Wf<1ZbZ%=Jnp0fFh27@>7sK6pyxVNMoodh-;eVBwVi zSw-o^CQh<7iEo7=#ceGuT&fLj0b?Y0hx@a>Kw1~rC3QDb1urWM#S}?&gP(0P5?#a( zmJm^h8f1q*tri^J&WFrkk+Tfy0zS~V9WiAetW1vKRaqX>gXzRNX&>I_m9CsAM+7%) zaHix@FLxa$5G!mUmSMJb$?9_+TnEz3Zyh9cl8`0Vt3$1j#x18b3Wd=!F{09n-Yba6 zacn-zPQd~KF7G#_^q~S98a(nPc6%_K7#))LJ%k0B_LX=_ju%^=!mW#VL6X z?O+CebUhB4uZoo;;>z|#eYgvHcl|4qy@NJ@mFD}KLXzbXTodr(x6*Y8$x?-VYK{^^t)1ZzDIG6eGs-Qx9spsNG+xhD_{0 z956jS;b3<(G^qGGom+zgtcI{=9=v=^C9oI;OmEE0ve^`P`6>Ho9jp^mLZ>doWG6O? z*W#Szkn6Re_VDpC(vDd7W}JQU3C|zk=Vy_jA}Pw59ieY=cdS>Oy~hwC`N58W`-I~k zKx%{MRNR|97P{&lQR~mMT)t(lP|O$F(?-^QCs6XD4X`1T0m92@7tIxelsX9M{7K=( zHX%TZyJr4#S!)XkWk~9?ZDN&$9Er+HUPvU|5(%&ix9<*dgyq6N(Wy35?uTtn$P+9i zAk}#3?L3?V_na>M9X93bu?TA;+byHgLav?@5b)1h@qS}65Hy>Y{S4yS@h(}&`4Qlo ziP4VCy>a+M!B9hA^Lh;(58dcPZ}TKhq~+3plB^GbIA#FP%4%FHbwaG?#x4>V5kn+r zcQoa08<@ihZ6P%@gB{)@S4e>~Gj(%k=8mwKX?QRyX5yu}!%0RSVeQ;&dP zD8qOAAE|J(7CZ-jutR!4*&cAGv}K{iqYLI=cKPQgLAiGqrMMTILas;*E&k5Mz1}Tk z#Ken>p5&OiphzS3ek=j8Al`DMFHJsi2GzS`FasGfCXz4jT8ExfKpyGj+0x^54mh&J zbudu)oJ7-!Vpip70Xim)Wb7SHO{CO$2v3=w>72)&7zxE>PC3iGU{S=%9bH@EfF-w2 zzE}yfA{wrI+>In6NetUVEJ9K4{3}k>IzFSp^Lp=-U1gRn}+DSVh zR3kS>irmnrQ8s01WJEsR!UquaiK$BsC{e?w|^gbNzO_D43peHvvqZ6yrw4j2V=AH}O_Pm75<4x;$$u>?v8n__#(N3|cAJ0aw zRfVWj@`0qE2gD3I8OKBbT1=?Uc%emes-p`^D~Sh2(|Sjtjo6`M9jP-ScOc2Sjva82 zn$&hCvbOx@*Q6aZ`tIep!Q58)zUDAfCb4>yh!BYExDqcd3IV^=9X$OJ2Shwrr=*LG z#@KvoOT_3Nci#ZaL!67JsbW;sLN*S}zGuNt#9;l+XL3BVGUFJf8Ss78HkUFsH~=PS zxxAAoR7|bSSsUvv*gRFhznR5YG{AQ^Cd~sbia28rE$FE%K^V!lq=T||JF^XqwA+>a zCxDA1wPy{Nz<$mhK~V)VC*j`RSpfq;LO0fMd(}{bi~L<{KK;8$O84tVM|CN#zti94 zUZlmoLPnwG?Zw~nYuYyaF_1ejAN1V0tF#Cq5|E|D5punGd!)JaPZ1}BUC0xLuJ zmfE>08}W^H#}1Y=e!Y1=V0d9b?`_up&;`oE42k=wNTd{6j`Y(Oz4x}v=XThLNpJ$9AGMmQP1@Y8k*zH001m~|iU4R6H|Se~ zD0I|Bh@Ku(n;SlnUQrX_6vC9j!m`(Onvr3Zvc37Ps|kWMJ;9@F?U?1qhaC{17RTIL zhbINGZS-XCB8V*wW}A7VCSkiQzN&>wJ=J7oP_IflGgxM~TSgMNYO3%CPoU2;D<8d| z1ytXn)$d*FDtj8|x<}g$yq)F*M`kXMukP%H3aARpcA3qJQs&G8R*(^Ly)_szKHJ|b zZB~j0mmL(%XcWbG64Pve2;ARu_UDFdZKc%#9%?8=b0msNZ$8p(YHCN zrpvgi>&$CV0Jvo;6C7wP;&H^?+ho}CWDOD>sFd4wTjg8_O^#aQrKpf1IRoikY1Crc zsG@Llaej^XD-Xg%K1ZK;9#o z7Lr>XHv)k)EqkAjgqwG77Q?WAk0P2A+@ili#k*(^mtlYvJCgJO^%7$xqN00ue{ePJ zX?=}1$@DX1^@JVQ;9w5~uu$Ajt$1NTrcg%C8Xu{~lR7ez^@?hlPm7u`fOPYuRjPEs z=VhLg9`6?|vC}3vXnVp-fn2?Xh}D~hj+9zn8s1^cn#E{s1y3W$i!30F$;KQYb+J5o zVZEjc(o8w_O)7%{%aFZGBM<5vX0}m7LS>@y>{-$tGkE6i67z7m#KadHB2O0svt|Cq zC|h}H2@jg*BZtH$9R85)f&(1FV_?J0t7__Coo|?Vc`}H_TB*FE2N+ou#l)Bjwf;~D z7M-lJ@%;)!A~G}K5w!sLFCXhkTaRAH_123`xf3FL!tTx-@SxN8!2fe)27gCrsu}E~Ed@UbfR41++VucGsk!McIr*w-#?r z-krT}p@P(xAmAhy2UiEW?E2?GbbpkpCYLl2@iZkFL^_oA8A}`Bpq=e~MTy_i(Us(uU zPeDvK9tQ{HR>`Yo-C~xi*i$>%I#z-3hhkyuC%e%nyfwj1j6gOgA|kmYTNk~BW?!tB zXq0PMhXZbXkUwE(QOTopH~@?qmGB(7kvii5rQ}eo+`9MC^WK`j?Yv3 z-|0F+Vz_*k=hUrfe3Fir2Fqm7NlCKKC`Nsaq-^(h>-w=SDg-2v~XOmi_>)7%@AX?t#JaDyhnQ?^_f9AN9}E2!ZdQr^;X zJLM-_lb=aF{GSb%VPErL>$&(Ytjs<>Y!aGf;9tOEzDIl?!<9nqxh!K!#l6bSv+VR9 z;{jDcpZ#(N0r^Z8t1OwbsOLLozN2&n9C;RSD0WFImm!t~hd`&QiRbR_LFegdgcdGI z)o#YBK|x!5-RF63{lMNdV3JZ~13ct<>#(fb*Sksefm~0 z)lGNFy7m2e@AHMFHOwf6sr0 zLfo&2@M)%-%t-2Wa*kDpI@UL01q-rFmf8JWT^7tah7>$CV&X$pvQ7=(`3-EH4H>gC zG1ZC~s%nL8dGI(SclY*EhdfD6xAvX~-M#Jjr!vLZSW3hdPhnZV1`ziIjA%?Eq1#7bpa)eC9v`B)vMxLkG-c4w>XWiG6DQW)2&Bi z4n))CC6?=j`?mdg=Mpq5Q1Tg7Zt{JHe9dX-^C4AY7izSgxDoX{fKQiDl+c*%H&O&Pu!;6VJ#Eb~@{*N~1EIFYZA%*;WtoPCYu>Vvp;#5Lui<-LLc;h1Iyw_B)7 zv=TNXhT*#51k z55HX`Qz!!mIw_Iv_Gp)Tum;Yc%XH2iM-Wb#eM-(h!v?;GW9L%0b?AB+n6&f9$GjHx z5>0Ck;ZA)`tY{+~UT3+WS=f4xoH#%tOXZ7Eze{Dnz+zxzjan_l%vIS1IM@=Hv(UzD zFA_xD=>v9E6F!^{b`S_T2wc>? zS3IiB{)BXGB1&%Py#B~Q-sB}i4GCk%*@2435O~~>7X;N2iXl2?J3B0_CXO_`zEy!N zDr5igUx7zRV7q%7UV#LwiJdk;Uh(Baf|p$E>(sIZ zOz(slntcj3>lvL~kTxS#Gci;${mxw0%$qd#Ck;7nWg~c*5u>nI(J}apbyAf zQ)9rCys7>!kr@@ChqXXRyax)LA5nW(imI;1F!P4HbQ2Yh3i*Tt<@{S%t25Q@0XG%q zUHW1edwnGvO}(tspDADNx8MU^L^!9(~p5}*<_#&`2cosRcs|i+9xM(UQxdhzX_Wc zgpjgBEATOwbX7X+7Gqy^tbtu5sVD^P_6UgB$*rEOMcE*Ommk!fGt#Jl4& zqRO&Lr9f00=HgF*LzmhE(^@$`-QVE6P_l%NZgo61L=yA4N5-^q4n=rF>K}C?@6yX!R@QYj;|L%;ftv~)^ncKVZ2SwaO2+H zB16Ra^E(LVK;~RA5Ee1Oo{MLvx?X5B&AQcAdp6Vsi^xj^7cJ4x;L+#zBcm@>_Y$Se z@uXyGw3kH|H$Zc@-9thSJB^D{amkLEEuIK1-)oDBH1%q3=)o!{YLvP&UmF2^H%t6moN!uioI6Vs% zaatUZk1fQ@a&PJ)YtQ_H+?tL=<{X!9Kro=auj|>}v}m4LSHC9r%g~&(*ZR}ScC1u5 zFi$7EV$!i8`|+o~!&BZ8CK)Mj`ZWeBtzb^v*|BI{qBb|g#4H#{DjO+@I4Ip<>%dKm zL#(8hUD8OiPa}%rH|K4efX~`Tk6FOF_7W!1b`U(YglkRr$W+1(kd>MK^-Xt-ZrrlK_vkWNX3j;DTl!d=xm;zFw2;2gx`9EAdGxCA%Nt;HXBB*AsT0A&%o-wFlI$`2=P?>e%Cg z*TLleskS46Tmk@r<>70Yn65&)kg|9*wFJyIz%Cw4=vxr39&$uc?EcB@xfYYPk%L0I zvO|AUlGV7#?8iauXtTD_Vu};B_Kt4iTG@%Wd+b^~H*JIMG2NeH_#}V}cA*pJU1{3e zE<>N@m#m6p<%DHFS6Z#24_^#(Ri4;oV6-~&v}W%`&?v-mef#9j_u@HlVUL@^HBaE6 z_o|SP(kF6vt@Q}3&L0nJRF)Mlnz!|(r-{TY(@tInUGIg&)5{C-a2$5G zrJ@(WycosUrzQ3hw8ru8M2#87lvSWpAt=YT+5IxhV6FB(L3`D%muSd2}+^cc2RmJ z1d=|&-o3)Yw#HslWW&;VP7Jw9NQddp2c4y(^N_knVD1_NFank#U5xkAv-Nj+bvp)_ zoDJZT;0%`fM+PplRweHJ(V#hFWY^pLADG&O5TINZrlQ=PyukkxvA9y@lus%Y%!L{nZ%t|R1|8~$Q|C=>ONrU z-TC28+HaQEaqJuOX>5m$Fq6AM`$|^5!MKI4!n${l9R~r&3YRqrc4j8Q|ae-dAX zBM~e|vOS`$7ZTvU_Z78hsJEe2@y>^Il00sU5ZcF$$WJVM-6^$2J$DqPsgEDVK|v!k ze+j90=2Zq}s`oXvs>*mz*xLLU?!o5cdcgvRx&Miu2SGv;H=R=!K4aT`wtmDDpU75J z$37Ga3$8}1{^Nk-hx_VWD7aX}za=-9^5TJUqZxaoEfEJI((M`?|4kw<&7L5e{S84q zTBAMR9iQ1q2D~o2nwfmeuZ96ijT)XW;W@U5ufoK0y$cf(?vOCAstwjui`F14WUV0e zsFl~;8H&=S_Jz;%RwM?OIN2gm{A=LwMNWcDw6#Ew#u6WZ9CKR2HTyl;UgVrqSuB@s z8QbD2_n;=E;DwH^GKr>XGB&BSB0blHTEHg;Zuy9A#7zuj3T9V{RzJN3*Ohxbk4{}! zTFdpuRjYO@&aPCTI#?ENv#sChf_FuO-yzLp0G#{sNHhKVP}9qMMM5CtQkSP4_bx5|C$b zjnz6AK=Q@hg^oNbtxIEo>(dG8Iyo>f!=Az(+@PZ?&^QGtQQ%8wPky@73O{qk1PlXt zG=+HJDo_G*lB(+21np@__7D zPtlAECk}JZw;{3k{W&oGhDX_ow(y>gtbu2V7cf^@p+K6o-1#dG&j=M_h~>8h82Ecc~w^&M(G}S zU~wj(fc+33#K1fnv{OeMKD)BrnFeuC;YwRKj}M4r$k*wL#FUR{l6Di=#jUlsG_VCa zYCPOb5e^qOnXfh~Eh2eqSJCf@x1rV~>^!|iA4(IJHrx>qlONh*!y6g#(YGV0R3_u* zXpTJu7`11h*Q~nP%xd}Jo2qWD#H*x*a>5HHqF5k8r7_GO41Zn+vqnYUqzkzQ%?)Z@ z5h>7dyi2%?07&9OjaAjLBY!Xj4RSFY)XcJxCJ=#bzZm=85_nY7NVHBzT-ypFPX}Zt z--gw9#wv2`G?bA;Lo|o$<3gGH_gfNOeuik&?Q+j(krM2vr@KI#ZQ&)+^2?5KUILa- zOY70KDOEbu+$&2au7~GwV{oVaJKyZiH`h++;GAROUzBqzL0Ft4N*rwzx*gOkfo=z|b>^Rb&~)6nCM94xwjh zhY3c+G_UJW3QaBnhX#(m(k*9KjoM-KifQ^o+A8%M@eIz@8;wsk3zdi`cqZ;hG5IuYzW~5>P7=<#40JO-K7%xC z(Is^3IkPVOJ!|p8Gc4&GLnsa`o)vvnGd~|;5E>9>n zx5`aF@iKvG+~jF zGJth7$HA9uL7}Z#{N6V>*0i;<#cR8V%Q4+c4ZyFVkdx1;D}&0R@SE%*_>ax1JS#ZF zp;>ZcJrK{>fi|ABr8J+H1@ly=RY_3Si?#_0<#?Vq6q7$*7R3t_EX}(MQA^LVH+dB2DqkyiFYRnCvt}vk%nLGh?i*fi9UCJ)x-VxPpw!kQ9$--#QP7;)N{Q zLQscJ5TU?9m7UwT4oA@{xc7{_$DUhfJ_7}Hl~A@kFO&Rb&^CM>y5P4_#L?4`lEP+4tH?R&3hoj|TQTM11cyipwRb8#OWxqd$c)y|siVGi z@};`_Ds3Z#31Y9JtYXk{!e|Te%B6@FI7cS264II+Ze}xMLDp`K$ArcOC>?@TL#$nV zLWOVQb(~e8MKzs+UEzc4d^lxffkV8h>&OQ5P|KW+dI%Il`sshWx@jaA`{zA!_Zq>c zRK9qqU%aI-8|p2!akq3lWNuW294M{ZJD-W2jShzJR(tX^8BvQ9@;jp7(Av0Qo$3nu z*6N-t+rln;PDY+ECF+7+d3v7!@?f23(xn^j^g1ZC_q)I~YRWn`7gP-SsmaVapqTU9 zPzIfs7SBS*8P@1giq#I5JNlN>8irS+f}SMFp1{-6yBww>k*Lr-i)b%#lR1>Bm*;S( z-BCDAtd)m8r76`MdZunx!COObmNba*KEX$#kEgkyU=lRMbadBexHK}=1{TqbUo^jGw-sKNl8FdTjqb>QY6S5>2I7~n%tS!n2VHhL|2&G$vU zH=@bydNCvK;Lz)fMxViw-6ZP}KG$8)0&J(U~;C zvg9OwVM23;$8ii9i|G>xpO~mPwG`dEbf;w5B*O%D8-=y?NgLr7p^)l3Z_Ov}PA)T| z8dhkOskr;_h-Jep2wD~eUak@+pXtiKkh+nP;U0r-{BygUI+?T`ezqjD0YOz!R>!0> z{us>ylLiDJSUt=VXP*L2>ygHZ#No1lCGA{n1_w(#R!egC-yZN@FuATB>%6S4Qm+|| zK2}#FC{?TJq)5LHYMYRyw-o(uVYs0&SYZ@X78K;b9%uggP+o(S0lcDWYyMF>R7_-b zXi#bGoYfA<5g+Qh)-DqkDQp`J3KMa}QSJo;8uLi7{bEz4!E{hz; zopKXvZp-V#)a+2zvjA)5jx+kFg){0;+(xN(kliG3vuttDXI8ax7egv zGGCYC!)5ee7FKsOAr9JsO{Eyv%@?ec6^$VLGD7T~YQ)JX;uPraAv`@_7@aXO|E1)C ztw2QNPnB0F-&vr<;L+k<0xB95_jLJM_E^ZQl_EK^fqjOKZD+QiXdv5-u;b(4jmYywIh?T2;k2rz z(G=4Wb6FVeyGBRU7btSTw0?B*AiU$eAW*G<{;eC+V1ZgfjJ*)oWjmzbeF=DWLsMm> z>Ov$R(g$qV*Nl7ESU9IaDf-ncv-NA6q?c%rIuSr1}_)dh;pHcEQe=xEhD<>E-55?RBvK*Nb1bd;2vX&8ZH zv*?;l=HNDFAyE_2OwdT!zRkTpxsbEeE0s@Z$3k|^`K-xv!)WWz4v8w2T+_<|rTM%E zSLKy0HqHBx`TA1(vkBF6eD+*Pz@{(FsSdt>A7$>BR%iFERIcYePCj#no(_zr>%4=N zVhGYO8_KvPtBj9gT>#3`b!Il@eKWjI)HyeE3ra|{mn^fduCZ^xX@bZ$p43S7l)y3? zhYxwhlqw$8x(B}rzX-n%3y7)MpusqNWdT?~(z-b09MZf$pjw{EvE0){4uZTkMRM2K zrbU>T5fU`o`!T)bHht2u&JdE%8_>crgR2VKPPYKr;c&^&TUV1r{sg*lF48Yx@^o*H zD7D<_AvJI%T2PexsLFCX*r-q=3331u(2#D?p=e%if#RjLDxySnbgnIy(p!O=HtYA6-5TTvpn`VK7UYsE|`U+C5XgEL}QG zpoIKj1`aw)6A}^8^>J*7xWRA>-K*U3Rx(Fhcr{!^(u~&NT1tC|nFtiUA{Vo96hA2* zO+YAE3?+aX3#_8pm*5Pqh#IF%_D&a=pfLSO;N(0!kL78t>ebVNFgj!t97)>XNksw^ zf^(382G{!yS*1>zwPXSneO;>9lHVZmE_MS!orNGJ%FOlgXmRwk(ic@t3B08b4 z656o&HWvN}kYs!aN0bqulfu`FlWYdV#mfzLt1tFw zuKaO)Bwf?5Ev-@b(oXqcBG3=5OAXMVZ!}7DafkGMG2;v8N`w=lN{IK5A0sF{& zs}Ye=$x@qWOl`KyfI3>R<(#L-?z)vggc;a+cZ)qzhcmG8)sr1V>i&u`g)T>WGJm;$ zDq+L}?tULqv?YN!3)HMw9*EO6bWp;K1J$?H@7}~hHb4pO4-TCY=x|qV^jn9GGq>QW zqU7csm;<0^j45}kgwqk^xMiz=TlXUp{N`qtL3 z>z!5!6}6=HQM)P`)!C^x1Tu=&-akIqw&37_a92EMTn-sUaaDg9Qn5-35pjEbA zTP4I~H>A#Pu?cqs*+M!g!}Co2T%YK?b@0=~WlvU4#&hR-ISv%5^3Y$Eo^nWQkV_Dk zcUx?&^mmg2Q8tBVM@JV<$|a^{cz1j4jC})LZQsc5GADvOxeq z00bSD`R>xqLTZs*SJ6_g?ZoE3*I9Jdi)*ARsSB`PV`FG$M~|5|5jl)iphx!%>*;QR zmaB=8dk^TSG|e7vDq_Zyxsr0nozs6EL469|>dz17rY94u@^JfmxgGpn%BKE3fGu(teE=saBGl3H#yiY^+=&iQf!0LahBB)Zt;4)88@kYBP-ZM z%zzpVB`?W7k3{uxPa6t*1`??TzC-R zLBUdbuhcUw*4!cM&+WPK@w6W!5f?6ayaM+@!zm0oJTp@(UcEiZ;`n%V^{ppdDJ%T2 zOjrNWnU2wt9%Dhx9;M#3xB(J-+^W_b{s;E)GHI$^A1+kVA6OUpv<#77@~-<%S%-Ob z9C^EVz-sa*>LobNC>Q|*Zj3O?NUWZnjtTZrKq?a3Uw}=HXTex|ZCIPrb)30qUmN_ihZv+|4UcY)nif*HgD2W{I3b z%(|1O%5gVll`E$})j{Wv(*)r&B(%bPgm9rsaFai2h@exqLV*>&N zPjQR1wbOH{pY|iCEqO!LwnSl}8Ps+N;Ky7)h}nL0ldS7~)3A&HGeFG0GxmK&8Gp>f zlUh(3!#ebOQ_c7_X`w{Wp}mkc4F;-55qy_FO+>e!P^vxie18P)O;)w$<(>mM-$FOx z4?uUN%TKxTM+Y7QG2@UJ!SOWYa_C3sI=u|qw7jOtW>f`uwWm(sbO4Dl{z7!H-!>|0 zb%iY#iHZ6qYE~HhlmlOg1F;V#>#rT|YsI$0$IIZ#>JA)27eAV6-O@+%5#mRE^*+fyaz0*VdRixk6tsn=C}AD;B~suMn+cM1j}R>3ONeXG+9w$nvr}5!UPb_-2c9ZX9`Sl^4QMQK=tS2Gle91o`630#0Q;se?vh za{h^}3@N#h{ooO^t%gz6~}id&(NxEP+UHiv1s#4Jg5^ zr{bZyXj)ZsftJHpFO=;uRhhn$tp)sEvPa<-uOEATaMGN!2eBNl)}g9rz>afXjnn_n z*6XTfMh0AnqUtxEg3De%;!A!+f>cI8Cd0O5%712zJ=c{0*93vP|9-T7-!deCo-f_F zH5iE*&4u@(CR>R=ssL^EH@n`ov;I(B< z>xGZmPZ+>@!S#C`H5<(mN=W3zR{WKKbNx1_2*mX-~!cVqrUY?2%qGAktNk6zbP;xvc=}{%5X#^of}p9A7W~BjwZK`A5H_ zq^>_odid=NfB5^$fecAQmDR%2ddC?|t)>SogY8h`0!fB6F^X)<>AFJI2%%vdGzEe` zDS``{MJC&uBI#1#6YOUon500s&*8yRvIiZ>2r)qtw!*rf+OX-P(Srx4p5;~0HN?1Q z!p+fRd{8l6{Gplq?rkCggQ!y2id(3fa0esmM;gJ}c&Akh+WJ_S>lbt_w@OY1)UK5V zTXa-4l==27WQM^LeWv_3p9InK5)8B>=l*T|$rf{3O;+(5ADfU@U7gK24des(1_#pt zT{2(AzwPzp(oPp->yN{r6@k2`q(>@XgI(V-4oq0wrBQfP=;v23hs3r`?GKp7!|3^B zIEP(B7*!Q~>0b`5i(QW5p-{hyb79Hf_IuD z$3Yj*SAgf{f`e6o4KMV|d2me#XRxyCjt0Y}33dQRp>jyuxU1Up)3qL?4mj>`U1#_J zbH!vhZ{Nk%{8msOq>zi@!S9{2dke2@Hk=m=fz-;pLArj6JhYjsIm2}6e@*H2`Uu-T z>y)5l5|Q1Qx67K_z;lk3PQnw9fgFQ5&GE+0@i`LosL3zmGm%DpKY4O1{li0>MsW>~ z>V`b-)0tmh1r=Po`1wawx^7&RRJJ4{w=UN?+1C_u`td|~Za!K<(Gck|)HF2Squ#!e zvl)nDV%M-I^;3s&0wP8-lJK5cO@ZkPfu}V0Qh!%Q zL+ZOV6V8TZ<;+ci^;XmM?hS1hy?AbXt*&W)W(T0cR!|}?ysL&0apI6Bu%B2eFX2Qf zO@YFcuMbp0+g_i+1ITY~KBV7;(u6OWkbR8f{9TX`H3}E1k9lBO&+R}W%9EU7O*lgL zY(fOl)DxtS^d#)Xn|{*d_iQ?D->~x>z~ISF^unP!?%r@^hKYr3RS>{>KQH-b&!}&L z5hdyrjTkwepo&1UbCtzAzvrxT8Ot|?SF(H)&PL!f+R&yuR^@EdKFiw8M4}l_-A7Ns zcX^2Rf8yclv%0~MwD5%xQJBQ|3~bp3(2eNxzy{2VHpUYcRtA~ARzP=MjAQ4o5Wswl zL$do{m;m6&?iS+9W7DI`ea9^&$o-FtLNgiOjn%5T45K3_b^4ZHlnSLF&F$vCyM;USMck4k|AnSOTHMm>^>M|a67@>Y zj3Hj6iC@oDo3=3ZdQd7p)JlPo-??iN7!nSqUHTPkP%hia#Ws26uHMRGLI`N~t(g*z z|K|a#i2rx>loX8S@2Yu#SzS+FZO!Zl(`ux-&~Sr#dTJnR9=YK4AK%?ne~rPze8dF# zTK6T-kg9sHs-UP}rb4T$0|3!BZ=X0pFjy!u$u=^G;KC^4w~?bYvq^*F%4nNl$h^*1 z_ru$?>BTX664-d!b2VlCm9|$bax_$GnJAzFbMu(`{2)(@`0r|~rO|4$O$zN(xY!nX z|Cs0b-u=Rq$*)+qZsqq6W~trBRVpC!?Gkr#zKET`l)p~m4+p1VF85FN)LGxZ3GN}V zhsK_3OiS@|sVVr}^WSs-+zMZ|=}F8$l|6-&Dzhm|K*Lp2SdplOxfOv*G$TdG`4mATo$b3TbjSu%{tn_QkDb)QZfDAM@EQDY3g7 zr^Qaa@~S%^kH|Qa=Fgn^5z4Y&hb9G$doc?5KxeynTiy32Q>&(5M7r)FK!|*aj=Df~ zzDM&ASNIVt`9R{=^Px5@zo{td*|9JtPq{BpY2lzm?vSZL_N!v#>^Nbc2rCUc1&{~8 z(0?~HygdvDR#V9eAHBVZkhpwl0;IwC7gq+zv5c{D7CRrbhZu!dSfBJMRn9l&YCC;t zQ7*nPTo3ewavYr493_#%2RY_0gJsAe^U_N*8e2p8JP(a@N*(dce0M|pSNgl!DjBj( zv&DVw9*5bTW>mVl_IbS<{EpB|cf<tMjkbvI$p zx?{Y@;S7YBpf?d!ebUy;^0lA%^2HwVrba7pwKJ$jmzNZjMP>DP0}R9&TrQ{^3916c zd8!ZY_gu69+k#lHxp8%iS1EvHbh)Fc5Xs{@UxBj^X^7k{GEz4lfPe+M3_I<=tMk4h z-VlB=G4bs@R;fX4|7&}%eRuq*_3tw3M`e+r@{J~wvnQjKJRG;p%j$)D)~JF@M8-{M zl*0UOG*CsN1>4%+XT#f@!g0LFlWasDoS7^nd0IRPx%hLz?u}{%XxU?!-1!d%fsF{A zr(Z$3k?V3w1+2(?2gJTJu(aa8_SK@HQvsM({CV>9nbIPtI-|e%%W^a_vp&^$%KHhF zO&D#ScvKt5UQ)YruJcdfT7f}{o41iuzu_=1Ts0FSC98uOr03Q|xYnP9rTEZ6CLQbz zZ-I!8Z}6)80iRP=iy*Dt{7!;@$0YCx{4F=``u^{jy-gp!Z`h$4G9+~-;Er_PTAGek zlS^R_kp7@BS6=Ek|F2?gj-Q1XhIla4=%h?9qqmuYkbnLO@^kcIZo7E|pz0dQG1B zcPm4<3*3rLj)3*|ky7YvmvrT|`E^R?GksO!?`pr-awoEh&%MOlUJ&4IRjtjlS-5yj@ zTO@3rW`<_D);c$$E1XFA^fnff(QmV?_w2|(D07S;C)Z(j7M=C+g<{UeJSZnw{o1); zPiG9}WSynB zicA4>wO%tfEqqd>W-4^l z!u;#Vz}%jg*i77!P)bMnQmS(myt?y-q!&_DpiB9N%JFndA5qEK$=iqC&a@ zd*CirUo`T*%QErYd_tf7g;sBpS$A5083W1okcLQM*IK;=XS`h3w}+K7%-ScHQ6Oam zqsNjj1P86HoW6uarxQ%WZ=33kMqa?yyQ8~NKDSAega&@%$CsKeC$N-Df1Xs5r+^hL z9ES2$gf_YQaOyvLL(T~I1CefEV9!$5;uswvgI}J*1jVClxXfiU6=4^{qZn9OR#u)_+M@C{80++uv}7(J1uprt4ub2_(Bw|g zWM`6}8DwhEgDY5p3+!IFo3RJClIfoPg=6w`Wwld)EHcXDm9LE=@i{p>X##!yei87c zi)~)>)O5ow+GlPkHPC3kGiHmx4vtL< zA@uRTOyt@dkeBpdB5wSjRTJI?*xFQWfR{Gu?Y{&N=jZZm=yde)MUv^9r;!rlYVgbG zboGxpnv*n)e7m$O`j;Ql`qTH|+g~G%E^1ev{u(;Zx&jEl7*BF9vthq+*$Qy)?LO1# z#qH{5j1SN6bIT5iMPrpaVcJ6$EKQD2^a9wQ$W=Gd@RZcm_;dsEZFnK(^|SP);Y9jT zLtA z+oS7(R8k@$J>?rVb@lsYk^Wm3AAhuw;1?6t2i)rOe&CdrsZK?llz>{jkwCqejjf^3 zMK8?VH$Kf*f~WVSzAXr7qoToPiSst&AdiD>a7+v7wb#zx$~?> zaA)<0%NSn<{xXzcB|2LJz%>!<&+~`GM!Z468k9vcWBZ#IVF%Te14}eXo#~seG#GAu z!~ov8@ig4hDv_&TQR@%hFtgmwNAMh zEKPGvnfhLw_TXi3I0J4w^9)`oBuEz6sOkaf;U@lM!1IyEWX#XO(!u7?Qv%)@^#Cpw z21S-&RVWQwHQ>2U?W*BUA(fqRGL5zgt9W_mq*B5t6Q$%BD+sI`qedmERsOccP@Hu= zTRTBW7N+sT|G3v8M(kWab{v1CjQiOOd>-bAVAdwWTfx8?nog|mBD|yM!Y~%iP{Vka zGJqNNQN`vu5^$T+R$<9LVC20nIqyrp7P)`^Tr(_f+)^*fjXuGSXPmf~?h zuGI9wFRd(UdprfJF}xxDbYhKpSYbpI;j{@4h60P*t*936cWHOyUYQH5R8;T}qk=7{#_-q+j zT#H^E6~v)BiuH+6s+LD);|^sN94wu{4eBs4riTT=`JI#5brhR^k$MGgv=T>mINvEYier5!Zcj>_nz@4(!;nn$?z>dSOB~;7PVh<<+Ll z9et4_OZnVJ`c~-LGQo7%%`~I$^#78cAu0)2IQ^Sbcs!oncys#q-5o2?)|p$Noe9q7 zjJqudG_Jb7yCg4GkhK%vG`bL@=ERc@qk@f#Ho?m>$n`QLGD7TfBGZBT>5|g>tIF9E zO4F2afAA+`qe9%e@X-2n;@7@Kf||@Ca6ab_O|6bHuWlN-ve+2jO8fYFpGbW{e3DhK zlMT+06fdztV$#0hpr^xG!+^hre;nE4wZwR)ruJ$%0&L%W(=^izjvtWomg}x(@TE2O zcNcOuDa0|)ib=EY%K~YBB0WbX1;L>F7GB($6!zB(nS|fXk;f7VYu)hegPJ7Ss81ID z?%HO}%}L98dpuGGCP)f9V|pVAmg*e)&|R2Yo$XMKd#7e7Q5ot}0=u!<6WeKUSEI{) zHpD-kPTYLx0rVPb&V5EsrXpF)^2NFfW+IN7(8DX3hCTfrH%RERY3IUiTvqbp(ECK^b%t;Q(|U}&@0h$~*cJwje;|9p5|4KejiCg6gLEW>{Nr3AJ}IfS9ty?w0W zqUP-($0J$5s*|EQlNbL zT(KdU;vl3mJ&tc57RY}}saC!RwsXVq@zz2+$nLIT#cgTUwxy3>SDXi`!}04E@-Z@C z42UIuLJqPvSH6>o9mdtop?qWba*=wB4sa@oSU&--i?U=|@s&Na-y{FF95+9;CIZlP z93d7MR?h}>0wuK1_p|5Y9XO~OO?a3jz|+M*F_xAe6eQE)t%gWb5tOv+U~l^jB?|u0 zzN8}~8iG=g2h$0v*qIFKUbWH97ub*(A14|e<^x9zUqnTRB2i5?-Q4WVj76{3Cgp99 zrU4$jK^Xb4J^{Ro1d4;LuvYajirpF2uiU6rb|GU=L(!Sv1y60w7O*E+`u)3uOi-qa zM36l}7Lm{V)EmP&-)KuU+UVL04i-KnQYh2oHM|lsG&Q}CJ?9q4s=n<&;>ldJsDzFl z+>eeo+&P*cm6n*;5yX1At8r@D(EEx&Xj0g^wSuap|MRNTSjty;)W4T(bykYnR-UuR z*@wrV%PQyA8%{`&E`yaj7y{wsvO_P_8fyo_b}qk+g!p1w!-f`ZcnTr+&zf1on__$l*W_#PeiEwwDG`>ohj6Ui)syaGYNb#F9R74D$E?$+*54~jY& z@1I>okkOEb(Jk2)xlkAn$P$vJgkBJabfJbOHmcRr&-RHL!MGS&#<@6zmb=}QJbd$i z8XzDzQ`NbZmP>kPJj*zUCcqGvxb(TY80qyL3hea<=Iig@FY|QTROEzZ&a2Mj=lcw+ zoIJuX(39U;hlSKPG*umsw#*bD z9sBriDhio+Zm*oFTesyoIA?z_Smt~b9dEBNryTJed=Y*zE*)y1ho2nV&H@Gz zvzfO;8o!-=z7G{(0uSJk1qv&ld|pO`WfBGR9*B>`4jx2Zz;9Yh_Xx7^4>(@Mk`Ji+ z3tK)4h(d^#!^O-^;RCyMo^)0wkQ^glJS4&{b9Zfx3c!tSPa9_uJu{7Yo^gUXpdjUf zFj+Q?mf&jy6IGSABJrdnHl0K&%p8NuznWw@>Mc_ocBTZP2^U$e=q2iMqhLMHKd*v$ z^b>~I==c7l;;hbEnJ-#5*1!XcKqOP9$H+->=UYY@pW{RWGl^r_BjmxAPURVqa?6om z?ntR@{%RQJ`*0jF)7)y(?3pD|5p+ja`&p>L*J-xa{6Vuk42Cae528+)<>raHFPw`x zpO0AHtnO=O7}S&ZjDT7i3=075;cO`0RiGk4KuEEL+SvJS)sK1!B@|Lx792Jj?JBC} z!~K8}2+&YUPlC1bMP-4oPUnH(C{GRNXM(sZp=M(^p_!q2Pr_kW(1B1uH=}x-IKBDV zz}$~=&*B}mj`nLkOv8ECr2BCtv|eK^OW3MCOxWT&ytESg$w$gV0RtPBaHzxJr=256 z&pgFoTwUpM6&RztpVXxQqt9I$;wqRi?*VDJ&V3TUdKVwG$TQZol4$6Fox|+noueV< zp~>RlM>#+5qRGA2;zwOD5CmkmnGHVO z4DX706w6OVB5R409(r$ozBMagjbfpjtys$SWw5sHiIFN#HMG~V@b>HaMItIh2H6c` zqis_so)YmvA#pTGtYk8q(5&TF>73NPJz2s zmJ;qWyMGKgP!liwRoOhlE$hWqK5#P0kG`_+(6J?mpeb0B3G6 zV(R)#u7`xkY7SOlxc-)De%bVird*^tUt$XHB-lN^3hNM`%D(CeiJlIQmPr0y`g zrSchxo*t+)B)>#~p!#tb;xo}1u;NCiUqJ028?t(G5E<=vX2ch(qfLDt&j|ZlwT^m? z=Vf8cuKcxNKCDA#t#aXf0$Cf4Oc{8CUxcZRRQBysaSIp;b}phNUl|$84XwByZR4D$ zgQ!eMn4`Fp@&!?32QbD4qJp&?@w@Kjbx3k=FH+HRGRzAmmQ_e^v~WH+cBh$E%-0$f zpEi+2qN1f4PWg&jS^NDnRa1^%c1x_gVYl|i+S8pcFUN;|(0Vovwn2w^IVi7qJolQQ znH#B>*U5D%GORTRY)LBnNCOk+dAkh$EM$gNyz5~pUfwe`xNuPs!}Z53V8aYBt%8Ci z`DYD?$6P0=y%;O@xGPBXBW5&6LS6>Q#xGibyatZ|edU;Tq(M0DMjA_9s#y&BIu!y* zOjRYNaU`ecaGs8AweDDY+v(*LvK(IC^_rOs$qm~4LoJ1n{24Ity6X5WG;o$IFYUEU z@7=g7Od^5oU|cPI+UL-5y{QT-!T2$D4)5#!y_>lGb-=t3dJ@C%Ldx9FD4hl11N52C zh9G@*w~MB|9UmhIwQNbYuk7IC*aP3_pb}Y=Bg@JhvxLGhXs=+7amYB7>jFvF(4_&K zq753;s*a8$_bUM(NLgUJ!rmQJvTGPt>&nGBS)khPS4QdYB&5|BQ@No5hRyP3V&^|C zS-mXV(@O*|(5YX5Vvm+_L3w*#Z?`4Hy^s;s06fAKb1~l(6i+HI(P0xkj*Nw{z6O=9K7R+=rEmukFwFcRsAAS&n9&S2obRkojnaBxlP)3?<&w zO?b=|0~dcJ1S)aWr{FwMkcFO~zL2j!b%|EG&X5q7<~bjM>_$yYJmZd?nFfh6Yzg07 zHO@!DK7x6-=1I3=$Sw!JJuRjSy-ZmLS!&tY^#G~T@WleAv3*g)iHm~*E{=m7{z3eR zd<_k)CDq1^l)9%`*7Kmlc(V&3bZ%mhF|I)X5vT9a4tDp_ms-AUEUd_PJP zYYgdKumeRT6a!e%@sH8$Ls0Noxa(3q{g?&ui8RkCaTVU(iPcKFA*-r8_^^7zqAGDO zYs_b{zA>9|HCk>GDz&7d+jO?oc@639e8V8z( zd@cefqru;nN|5jfsdbDrD&wIeXuH>TsJFXHV{{N3A_l^IL^w*0%RCRW)NMtWov2Qj z5V-nGHhDX(*W1qFIBe#2g!YEW=OmMw{?V#c4JLe>eR=bSzQTe|7s?B)m#!;+v#t?- zulMMKa$?g}_UXO%uPh}Fk^B3TE|aS*A{Ay+)&KG~^M-r%E`Nd4twrRSEg#c%sr;;F zL$s={CZmHQc&w5kJyunNFAI5s`CyRbdo$7B+*89>*SS@rQ9VA(Cza(rvACP^T}nxH z9CP|1T7^PkC~U%a)s%H+HJ1UjsD9wZ=@}^$LgdM-P)@+*NtWg;>$D8Adm(3 z>_draTuitSa8NOle~%sb0WVx6_D_X3S9CPjY-W1>Zq_y{hJ-4F|K&y?ArJ9cC0M;Y zKyJJBL|b}h5**B-O?S3dEO1n6#6#NF#cBMl+4&&2~HgflA7Gur=h>yVodfmPGpGM zG6w~#=OI~hh8!P>qj;Zy>qJ1&OG!^4NRyjvt-a=3otuzkSGgWxbrzg#GJvJh2qDKC zr(pOq7ZG`7UlYtWu*QtBCn1X8%DBHWV|>+q##BQ`6EidiIdhqmS&z5PwBRaS0bCY_ z{Sp!19BGN{VMJ)fO_g#$yE&G044ES>VPDyFZ*S-;!|jz4WAZ!H!d&YAH7-jXCBi+Nw00+)W$ls zWoP82pP+YAoKJGLh7PqTIM)DY)%mxZYuq;k!3wOxi}nSz?@0p*6&i2y7~B#|&lNI! zuxY0GI#>9-VmA?2*B$bl50WU$HKPKqf9{xbUm zHx!#791gN3F2JFcr=x*=q*0~&Hb}BRXp;<7z!FWelfaS4)PMs`5p((E*5#gGJK5Lo zV?CPT+3zmVE^z(wC`@38<+CXgf?iH3BGfJhZE_OS(hVO-9~SQxBMF;X8h=CACZ+#u zlE5{|>G~}E>m`+g>=C2@leSL}Ufh|L3^?bD*F#IBvH{W8%7)WZldR_wN?g+LsEQ1? zMR(GMCCY$>=TB>&K9oWN*KMIjMMSjYG}|#_Z<%!JM$?oTO35r4C@Q+t8x`o~0TG{( zfdj&YrPpm=TjK_|A!{z`%M1M1Lq#$_OOXO zTtSihMWv+yc2=O&#S4}b?)dzBa>z`G1Bkfqk~R!k!b*iI8F$ZxP_jNNxM4doz zZ~kP_4i^%o0`cbyvv0frJdVMon~y;_6=a||q(Gi!K}^AU$SN^;|LS`F>g<34Mfe>{ z8r;{ff^4NyqIuHw+Cx-33w3*`dE;d7Jxa*mrfjR^uvzk`3qCmErb6*aITD6a6j~BY zr?DL;(MDs166W`w{E>q~f#-4>J!<9EBF!5P&3aA&J-eA`lznM}9)o712c^AhRug@r zGJ2O;r`$+>=4#cTrW3U@PsRI4SluN34i@r-*1Gba^y>T8RY2CmAe_4j-~>fu6oDk> zkc-fimooA1hPHEB#=8Kzt!W3a)pMu0+bQs-|U*mZ_vSkPj)JnW6n>M=H7z41~7dAIe zM5ccIq!l+$MSVOlktUQ@EUt1!oTwKOz9=4#|3HL!9!Lzl{kW8H`1z+}P{z1HLlWg! z+u?s4_TJo4YhpL}6JAm9S&Xi+oW2wMY3ZB-PW5^uJ;+=fR^D1c7#xGgx?<&x)v@T* z(gRgbq^Bt_1xVvE()aD@-r`)tmA_-5o&4;G{qX1;ACG>F1Z}|PsY~fYUd2X$u#aOiNYJN38`Q1lsFH zcm)wy?$v`Qcq+^29N#sXQdgeS@WVH;5~Ca>WKB`g61>g1_!rl^JU=&9bImU>MAJc; zGAY66JGkIU$-xYcn*6+utc~8CW`w!HFT%XmI}pe4SHs~U;Q7Y4=eRympF$G)Gwkw@ z)V}A0^HjmBvOO=*(&vHUqvF2%9&ofHBtqq>a~;CrAt_0pPUA?_jG&}i##DNT5iC~& z=R~nWF}ia0Kt`9TNYQ7jssTm7wcg3-r%>z>nkz4~)~PL@O>4CE>Q@e8>E`#6j0~p+E+|AXz-9i zp-^F6mWc`yNhNU94cZITFX3|Vb<$Tl>U6G~?!fp?{dkF2NF$$Usfxu_v&=!^~4n)5%etvyc8)gu|=Z(-jXi&Wn2-w0- zf1oenAg)R9mCjIpm(SWcRY48!`RglHDxn!VrYFdBi9lF^l>>otI!E@6+91i-DHLZt zg;{Gz^ZbkFY3u_5*iI(?I_@Mq6EMe09Y{4)Xx@$9$U^ZOJ!2Z8S9sA{r}h2*;IEbsr};euZDP(?x?DEPHmg~ zcQ!n*WU{||J0Upjwya}3c`pCko z9CZ52Qnk}G+`Z7x1B>uqoXAr!y4W)ZZaeydcuVg!uZ#3+vQ_N2ddf|sXHPWKLx$De zKJp;1apw6@rhUrFeK1kHkdv@CPAr5$kir8<-KbWg`Xxzjg#l$$t;;v}!|%H0I}4V- zPzP1iy*0<^-5O~!HsOG|siBz5J!dM)yN0dKyQU9Jfbk7)nM^BU7)u31( zgHS?^J*}Ika8J*(rq9VRF;UGg{e^><)7E0X^a&^I^G9S#286#gS}F3Ve~%$4@J&{% z9}p3Sml_Nkg{Z;ArS^A|Sy|8`T8Ha z%QERbBpt0IV}9Cv&qfHPZZ|3Q3-drR+Wee1P1*fDE+WvzC46Syw3_C>&|E&tJXGL6a)LYQ$`SauZr3uMnu?Na)|=quiqOdtM9X5tD33%YYJ{v&C@&+2v1et zAhq~0HR8E(-m`8O=#UJkC-H*iGvjmSYbk-aj>wlWcl5#pU+Q+~vM}+Yy#;BN@(^6g zxHn#cAVPrbWjTtNd4lt=1&)rUr@s0{T|3>p=b*U2&5pCpNSrq?9Md>{ToOY#_2o!t zh)!)*x8pVx2Q`j}e! zhpy?Gi?l2(9DmuyMz??H%k1LICFc8VBuSw%@x(2C6aD2FvDX~fwF|qnnSsz&42vuO z$T|sXBGj(tYbZVjj`=ck+TOwoD;-M^mMxE7R({0eqUBlRNU#* zGM2mj+uai5ht-0bC0AWzisd9BR|zAfaU7=Se9c%j&b;sxW=rUPsaeVtz3h|5liM_w zLvZ-OOC)t13RQ@ZuX1uN{o(WZUF%}!<|&Bv?H+wfi(5-p#Hrdc7zudzw< zziH?4s(qzDNH{A7t!m9ZN=5dym@}9;xZ%d`-o-s!0F?D!tvUqJYbptrw6XKwC!5=nv??Y;!cN3 z>*=Jihw3qxg`Mexj@9OlA<^0~)CWqUNZ+iG=u`l846dn?BE35tPFnK)QW8FZFum-9 zecj~f_;r6Lw;?|}CYF4b!eMePuNNYMi)5mJitPJ<(QGV5)4H0#im@Lv1T%%nIZAr& zt;)YR1WF8RdExBv;=C&LQ2Zo_ar=LT;QQFt#D}lFeb}~IXA!>SCfNEUH4P3?$eQSA z>}J!^pbe;B4dvvXb5hTz8f2;J#6gA$j!FP(qyvLr};|^#1ixK%ouI8!#WbTxcPwjBP}Q?!0G_THc8XlFR~ZDcY~m42+63!74S{$i}f zStM6qwY$Xx9=zromG*5+WRZg%#}Nj3aBsQX8oBW{AU1Ab9uC5Qg=AJ;Nej*Fxg(4=eO0gr$`7nSX?T}>wu*9s*C}F z7{>ZC{f9%MKtk~Z?43VPmnnf(X9Zy@Svnp}BXew>OSd%YQ^(mtE^@+8^#Yw5xi_D{ zrf^|Y?%{7BAe1z3q|z(-GbJi{k6erYSQjVAWgBqZYpFY6(WSL}M&m2#+5?V>%Mqh6Pd1W@ zS&o1);;$@~FGH)go=Z-GKwDZATXFLsZYMAy3!*5F77HeQ zNb$+EXY|&ctI=cGwys-hIumeXBl7*8ataiZg$y|(CU$Vbn^uittZ_LM`EQP_wO{%y zIcK~G^y~@Nv{`6%qls=KfMe28k0A$gXfG2+gE?xYXl~GOYC$Awj|-_@Wc0US7E^wt zjUCGBYRcedQijNa;v&@2RKr^R48yOUP)GWjRZ_5fqBxyUCUpGdJj_Lf-Er{Z#=QK1 z7OR8ZbeIS;sPZxpV7zVRHV@aBZwE0&uofAXVBQ+;hV^;I@6GKhRHKHk$u7Kk+iji~ zjWctq#~aAv&IOeV2nG%5a8V&7hr3_yF&}`yYr%X%e9k%8I&d@vpg&>UCo`BrT`(oSI%Dw98xGC=41OSb6-5O?(-Y(;}oyKeL`7BLcH<- zByU?cdB(Jmpd~+C*#KbSmoMfqtCC^NRLR{P(%~qAIE0L0zGTWKHljz-P)S!2n>(#7 zF$L)oQoHLv_QWAcREb%iOa)F#k~Mqq1c^tAk&>463l{2XwfZM98vk^(s#~3ioB_{C zv_1Wa^0ahAGS_UTJgEb))pt%BfkeG@8L%X|)VF(U8e)E*9Bj;kutn$O?Az(q3VQoM zD~}}QQ!?-S&7em0JoLz!rgEmXt+Anc)AX37`(sN%lLBklB_$6funP;p`BiED_~?< zZ*_4U%JF9AGlAsvh({O zN>elIq+G7ei+Hs;g1w!A9={-;{7LI>kVqvt7HD=~dd|pHjbAKY`9rvb9k<0Ocjh3v z@0KW8q21coEY2H9=^RDg$*QWbsU}%3%b74Q&o^HtU3wnAjw8`MpH00yQ}L^nR^Zc^ zZhB`u1X@+U@9Y4(_ zTENY3V<+A7VSJZ&&x>(i-75ME{+&yL&9nS5hyMBJ)h$-!4{8LNv*w~aTWRB;YN>?K zIB1X4$y>4I)|&NxQVxkyj;)>%8!5>4!36$D)EtL=<44eEaLHTEEp~+0P+ea8XVMsA zE(0KFH@i->zoO8%M5_%p_(>~30~v!I4MHVTBji!v)02wT3(2tf0m25a0+`omqTy>%7noX38fO?BWXIQ*Bdbvl&*^SAneE}i25CqUT0 zf;&6SD|+w?+xuMH4G55lPn;aX$?T$KGf)RV{B#m${MRD$%tB#8Ao znCj7?pd*E(46Jnl1G5N*;T4*d0F?`tBFi}q4A}01I07`ZkV%^gD3uJIDJ}MjW#0ne zTI85~QOgxW=dPz$qrNgmF2)+Q*^4ks^Kr>!Dz40aWI~Eec+Fa&m!`yeLl*8B6-)`G z%gD=Tc0!;^W(``tF%yGiFxL)DtKqMzBntGg7ns6Fxjw?kRM>?6U;syUz8zcV1(NA{#${ni40fzhDnJmxzKep%3kv^X*7 z-jQlY^#rvaYD2oN?t}ew3&Wv5{!(s-nYbAm9grd%{djFb?pjSB&;&8T>u<_quFMrI zmihCn9tynX<+~OOBi-0Hh&W^=zBz(}B+vQ|bAs2?-OY+j`2?ZdnZF|BGm5}FT?QOVQ4}|2K4nSVs+vo zFE4Sj+_p$lRZU1|hc1>?ivx}X* z;Zo`Qr?w4PJ>G10b(!%4a&I645S%UZy@YE(1<|V-+FtVW^3n{8tE?IEU}sxu6qodcZUCkzE5Xt+DRXj$fUe zf|Wd*Cse{ve*E4vC3lvWo|CY;&@@150x0tfC@A<7?CU}7cz8{>Dm>kxSUW-dwgCC( zk_i&Lp*4OiZ)34g_X@L+AyX~Sq99u&l6*M!)GYuQ#>fC!uE@QBja1(m>(->-p`pXa zUy{T|ySeyV$w>h~I~0@)6%bA*oKxH|4nEApnOjy8; z^87NGD`WN;YFka$Oc${fXQR#3sm|z~Kbe3N&3}qYPe0rY)G%s&$z!(DOxwhyMM!tQF_GI4nrL8_o7ct+VjFqW_r*CS|URoDl zbAz7ul&z*=+(NAQn+0VTNJ-VnVxz=KEvckzr=11!c0m4 zCMLQ>yTa0XWP8cr0}TalA&BM*Isk+*rv&iT_9!;cFbsk=>B(pnYaq~AAVvUYkiJR% z4GbWTF!zZsTF!hFDu`(iFT*$Hq5r-MvWgv$pCD==+1J+J)5||`LFMB?A;>pc1}bLc zGHmBOd7-}~pkU9-BWps)!bKvijVwrVfyQpTO6uN6vwL;=FN=Yeq|-jQr8LO=6;5q@ zA95DQN1o_SP&Huu8kJ=tr{EZock?!(yexoL#I?ILzgK<78Av_m(W{v2RKl0BSk^1i zhc2b_!H?D;EPVR>9fTPA`<*%6hel2Ov>Di@pb(;f_Zi%JT@Jm(K}`9i`4qoPKL_8l zKjuwE8^IZ#rX^dN3Mnn>Yv-l^CgvanU3%IaXt${fi`mN8e}*>U7{)=_o@N_WV%< zl?APmN_E9zsOThV^)j88TT&cooL~6-IwQ%mATl(FYm1EC-@u(fzG*cr8W*5-YwtmW zN!sI>s6xNYm~r~J-!Nd|a!Vi+27Q~2U8Zent%AeSSdRS0Q)JkCw$Hc#e%}dy*xM;& zn}Nmpj5_O#3doS1{G=u;vBFa4H7i|r%Vl)kB1Ackl^zDP#Q__nemP_-qimb|ITK2XSS#u#(-g6U-<_OlGet>LO@I$;!QH~ZdOkaE1 z7iBxchI9<%yDLQa?Y&fQV0>)Y9DKxJsKXgA?Ya9<)$O+1y*-5RIy?sPavRfIJbGh9 zA^C49Sx`asugT}HEQ0&C182j<{a*p$lhCA27)3|xETPD%rg5ks6DyOu z;)UjrRIO_w({5~5Z75(tePDVzR*sbuVbkm{(a3>bBjv%)9=s8HAtJEYysYOl#s#k~t74K)4pzT`KB1D5eVqA%iF#?AbT2xEoh6jm(~~)maB+GP%=IT#qhwk# zB)63m7d?o&O6}UX*e}IQG<}px99Zz>|0+WOJ`}2YY9`-<`G(t-{+Ed`U!l0v;^~9; zYlx~!eZFEqt0qi!AH>H%r&})P3wQ^^#5G-^jgw1*^7hIA6n_(Iqr`QxC(3nalGfVsO>B+I8U3C}~Mw zPfkl~_w>C@=nn8beN&6oLXnl+CH@Y9^)y#I)60+IUt33rV&?PmFp=SJ$7*7aY^WDG z6I13OZAIZvhUz_VIufOJ+vR;z{q3sbEVrg`#Dk7P&d*mrvB^C)Lp?ulCNRQ|9x@pI zG~`=QHZtEmHCKUprsRZcx56?Io~6_VN74O*Odqa4n?!f*fdxr1WJ~Bs` zRh8fN7E~|Gn1BqZ2G)&x^FAR#fq9xBIwDj`Oce5l@2AWdvGg8JA-@06%qHqSh6RQ4 zVCPqI52%oxq5y6?)epm}cZb7OhJ(PF#K=BfT2#3Ao5~jvCH{ov4;}JC7OfI{*nvl@ z0S$Z*+#@_)SJQi68@%5O%Q16@=BfrjKy%j$CC>+%(7}Sx|79$(mB;UP&x!}#tel3X z?$5q1Oxp{#0tZMUgB5-GIMVNR2idaKutn(P{&ZO9agJjlmOJ2l5TkuEBSLw~WKdmV z{qxs#@>SfexY!JX-%KiO+S@0P^1V#Q5Nb&4a6qqcX;mC@pDe#7kecht+YBpJ#Km%%(P6}v9$a^D4Iq0of7>Jx{? zbR|5lz8wnvJ?jK&*T*}g3|_K>izx`c-O}y200|6^NTV+Y5V{OH^nf)qjK2a?!a;rq z%lT}9s$>128Q6Z(DuMNE9KS;?4Q7k+$v#7Mjd-LtBtvdvFh`=TS12)lnaFs!t8p ztR7E=Aoq}qHW6w0|4qdP4Erx_242v$__I#5A#I7t>~7@TGl>05+i*5r{GzHa2L2i9 zNbGS~Ow?lg`s~N|a<%RaJnqwEpX9)q*LRzh{7* z?ra-1s0emW1*vpYIh9LFKu=JWQu*)d*TLm2Ad%FfsB!mF+JO4*_&viWeU}|%(+CqX{_u4@`kltL?xxuD=-5a3^;{*0J+$rbL-2N#zIwLywHM_v{LIK3mPNcVcn z9OH#-y}o-=M|oRt#CnaN2*(g2uBZrn18vF6raJ-R9#=0=Jw0=79;9`kjbpiK*VdK) zy#+Gc*?Z(~M6&isk)9Z7CF?XEwXufh;0sl`6h{197t3IHA7!)5C@1{@YSpF3E# zz{SsOS$=k>BzY9?z-XtCJhVRWEK3#lbdibBJcz3tyQX1oUHr_|Zh05}{_YNY#7&%U zqm2Ls+`h90bysgw0sxw|e)FIGXccnng&bv`ClA+AsJD+dCnxv8b#4X|4BaG5 zp0om|cxdgGz2o%2uKtXUWF%~2Yyb#zyK5?+Z~Fp;T?2ktOm2NAP~k}bb_Tmi%Sc!7 z>V>BTHrw~Te)K&lpUJhkzQXXnLzj-i{@p7MZbQ@rgVD4fF~;-Cv4|ZKk%2v;1a@kG zkz;U(?4${Oie`-gn@Z6QYglu@Nj3VKmd$bOQ{fd0kGmi*li!` z<$Eo!C`3XP?8cV3dX=!dhMDs8zyINkHuR?Bgsp2+h|&JlbM~Ry&!%H-ADDum?FgPC z4=0x}Msjb;p$6grJ?Arbv^fG+AO`6B9>EXHf86w7*=lfjrJfoCdqsykV!zC*6EqhF*IQ50lySaO4(Gr zaPWSEFC@H=R@wa3TQSA4Yo#_3912gRFWjosq&TIk+$bXL;!>7r}9B=;F%Iei?u z>WH>)%y(HR+Z6Khg<|e9<;KNZ`du@#HX=3kzI|-Oz8-5fTX)0)Ht*n%%ic$4F5Q&Q zM-Q=TCyry-DzfB*VC@mnHy^8z&nnEchE1KLz8fyVtqP-aG*0RiUk1V^`pdtkjd0dY z*XY%bQVJ?VMF)gTF1e8rgHHc>y4l3kY00JWx#_qFD2 z747o?cXN1ZCQiqh0Rw1vWa?H~F41h}5UBFbxVeJ|Zpb8`QYkZfJ4)`#n}?!UObGpM zw1ftu8Cv6AVw-*~?DwN&Js^A^-H^q}gGMwaUUDPA?4MxQU=!R4F-6&zl|jfR=JmQa zrPpQ^c@*Ecyn4=WS<9!d-w*aXAM5kSQ=U7T)cHvf6Q0tEM{b_R2@vo@z)XGlS=O-jzd z#U?n!OA66#<6snW+&n<)bBb3`couZLV$AKH>wu`%HKb=bOLO ze$0EM4(~O*Ml%_J4#5jQ5_^j6W6y^xGH;L4ngu~L5 zn{Wl?_y~9zV8qi^!|2j-^%yQ+B0V?#p{x1z?)7q$>--HX*Ob`~>1Qad4dxC$?XAyu zE@dU2GF?vR_1r4drFY5$yY13tw&ZXtQ{ox@j+~vAmE4SNUWdGzO{KfJ2NfO7h+|$; zHky{z7~k~sGd5?EEdosX2a&lW$O`QT2flNf^d&*VpbBerOM|Te==v z5?n%f?y6~hUR|aY5-Dnx6Wv1gmMM}Pfry$cL8^W@lCHbP_V^38h5fz~OJ-E}ndNIE zyjdirGp2y?>jDp5vJUfc#OnagwXrzU^j6?HkgvDh9dye`SwRVNI7n^`jS(NPdtAkB za8=(;R=y|&5a8)`L?2N5zz{qURbE@yknTttNlET6YfJSiqHoZ$TS)J$eA{Sr^LS*7 z^deK?RL90LB)Xr^f2{UZ@Bgi^kfZrBJD{n6#+gdAQA zh()W81!kv1afW8AqfoaY)8d@dQcKtz%|26kPi$MA$H#N-CR@rYX zF+Y8N5ffV6Jd4d>!W{tiLrb6}3KX}f`hcjg@8R61(&{dk) z5OV})^Pj;Ai8b59*fYFGw?NJs8h7J8PlSXU_aIC}a9zBw-g>MtXZlD5SHm3>OPCCwZu<^ayr-Im9RO$Yf)tyx@Pu zHKsjc?a&kzk?;O5Nd*V0QUijz=(2ZlF=omP*A>l}y+orr|v zCFM9MK$}6O^jhG}QCL4^JuWtXR?Yzi3J1+UAz2$;)9YxD4T{$8R;8Y6`T2d4n0W=h zp|?hTRJ_g`HE_3DS4-hq)J z?}V9#33;62hDoYlL!Z(T{L`0nM4wiD7TvhTqSBqsRQenX=%0j$@;!+wRQP&HikK%} z-hST5&B{_=kNUYbg-mWWcxxB>mX6Y0vDs}^w zR}P6!!dgyByZIh;?IRZYHce+Y(19%5eMy@m5?ERzHr1hC5BXsBo)WUw7pi#p4BJde zg_b?KvUHGUv~kBz*@vR>SXxn0p+$5^^^R_NEPOi=$bIw$;k|V3BQR2B$KPa<$NJg( zZ4H~sikUrlVgB&?yVOwUGBe)MJ4zz8x>yZpF_m@Xkfo$bpI|YP+f|ekTV^yhpR>Bi zH5>HYV}!iQ{)+RACJ(Hr&%TPd8cL}cV=KG~@^B+pG%219MZ<+a{Xuhpm?^s>lPrz0 z=kDT2F$%Re%GiN>tKGYf$j7Ay+3oBP=nN3Wh)4!VZOcIJZ=wGAK7W!|f^@`(0}B8>)ieqT2K^$W;9qh0V2h3FrohF3HLi_ z6X0xfcx?;PBe6mfzYRQW;cPB2N~;@(<%aI_(t4JmZXs*lc*_)jS;HFciwtUT((K+Z-foi|8_Y zQS{v46_hm*#WQ6x!Q+0jzU;L3qQv{~rW0^3&BdUD_?4Pg_vYn~90Sli96zJSL3hO$ z-2Z~S=@Zxp-ABM{Pbi9taNN?_-vLp~yo0wa_*DjFhIi}XS;(e|d6K#i>hz-nQ8w?S z|HAwl8*RA`F-iL;mS{6@B_^`>4A!>Rl?;@`@;Zv7V&+e6k7p|CdG$KsqJKn11cJ6S z>eb*~F<1NlAA`Z6eDpukS!5kz4y|W>+SK| zpUws0(UD3!s!&$`9}kD}qYc!+kkDpQB*0c*pU}s7Gg&Nv*&m@YGXmeI>;O|rGo>MH z2B)52=T1;gE^OZ8c$va;h+g|lzun^$5`NGP7cP5k*A^Z+1xa^2Ha6@oyPoDrI+h-nIXa}qn`eeC z^Fwmp@tE)5=i9|9FT@c9Or&^7( zU{tB>kT9zJBcrmok!4$#$Sq1=OV>IZomH}s35UM$%hyKQSUz)*?elx4`NEb-cq-XL zv0_~G-vbSKR<`aavJCXDY0ORB9G}&ymh+dtIhxllf;S8Lo1@MzmpC$he^6gufBi!d z8F+4w45L0rm>a$a>)9dM->3U_Y_La$gfceQP{oe?%8&!0)Oy%$i&aTykRdKdvtsGn zl4;AB7-m@2J!OqwU>(JAG~}9;Sar#Q;1=N0xQ`Mv*OJ#oV2Qr%LG~15`BO~pmrR{B zSkFot!$jZo`L0x9yQBjC%c3gb44u3z#@ns@1}fhD3b_`S;|($q9Y@XhS(f7oU2y7- zLpg;&IlG>&1r}u|u{b`4yrOppQbpK-upYvcT+$^`Bl!M}4y>(GRtnLvxGr2nvA9gT zq;5lS$~&P?X@?0Q5YD&OUt-c@h+EkkP_&*w2PPLJ^-iX~)6K1A^6h-$VrQV|Q05QY%iEtRJecakmnm$cJ?2ki z53xPmdsAjl@h0BReW}42YR!;S{iY@v_O^ghslnyb-q>hf8dyR^Aw$jJ;Xg~fg&~U@ zDKO}Lg~&CQ&SH%r+h%-Ajkj*jXYrG$Iycw-<#K_{+v)U3r=K~_w2Ss#jn6sGC)!@z za@2E>>d|-Xg!r3(bEm3xN%c!OiEJv=F~1ZvmVFr9n%9jDX_aWKUDIf<4A=@pnO2mN zEe~J6ozPYY419`3H^PNgX3nUnCo9n^i;ML4y*MJ&!fhV#KRLNJS{VYyu@x^7vaJSS zth<;gz?C|l@QTb`9k*s#+>JvFY*C0C3Mf2NbMG98h!FjI0!X(^Fzd*v{aSjkAoRZ& zDH>MF&>{BI1k_D!DMh?!&S#U@n&5kf?YI64V@C8#eCqxh0{o@Yf<3Uf;jIiUkZ)~( zArt!bH=|-9Q9HD~$p)qbnBZwdFd|mDQB|Ereia_9Yz1lnX+`t|qb`1{^{tV$r1p45 z2caEJ+Mgh|1hasX{jTpZxUAcEdx*QH;A3bL4zi%X}o zFl%+S2tD{67%II&vxGU9?#I^d!v_$4B+5ivYbj_uFtIeLuehVY#}2FA z#tPr1r7Xw}pPaW(-oK6z$ITwXjO2OZcY^-qh%7Xn6(N&K=?`F~nxAbXlMzWrN`Zs? zl=nA6&>$O5hh{wYgCrut+6Cs82{Nq%X{C4Z4LInpUejD79dq$|Si~}o<|Oz+F^9g` z10fHWgH8*#>)su`z>v7~xcIJrnPfSM@VP}flR;$8L4cEJ$MhMoLZMM7n3#tP)b-^1 zODdy3a3je2dKw<|GNPEJCLo4?3i~_6J(%<~fu(ihz1@0|eYNZ>R_F}SKpca^HHXd- zHX`ggqt&=4Z#MFIzmufg==oLz#{8*~_$OKeH6GF`4!+ofyF7Gs&|`wLg`~Hw9oytB z=Q2QRm3~n_4v9Q@^@CHUsQLjcil_IRe?ziPw%w2Y9b(q~mpP_yOp^{YI`5id ze!s_Hdrs~zFxTO2KCj)8Kx@L)IFoAlCUPf={X}XmV%8c)zy9P{l{%{?XvE-#50<6D zltOSGrUCLj?(kto5XL7e?;{zvmF5i-0kKjD2FeEEEkw)h@F2=gP7%yaOJGv=Qm3+_}GFxFt1=`gD1f!9)P_O`AicSC@(UVu z`tM~W6>M#ZSgZUWRn7NPKas1W7BaMj&eBg{(NN*1BV;L?2q4?d1lan$Kjl)hLh+vX zL4>6J>c!5OxAX#rLc-7#B70MU%7*U>WUZSXe(#CQ$RC3uhQ&Y19J3 zL*l?x9sJ%vE$|ckb#ZvoIoXT?1r^IofVGoezPrLz$h?g$2&4!G&9h@K9t{$SN--0Q zobGa4daV(Q=S}vmv!R^!bB<-)7VI^RbrlI@U(q=_vEjg9PW0(aI$LE>fjzLBf?p5p zS>*+?^^VQvNpUAOPg}3|4|7=QE{Z)N%Bq<~rFY2V4H6p-80es9-_~M`NQAS~9xWh1 zuc&Kdvo{;tk$ZC%ZBd)aZLbbWxa%{X$LW*DJg71X(4u_eg*jUS@O|`>foPvXs~7zx zQT+V-bOWCj3_cWb0bb0L!IWFO{&~{a@esxJ{shA!R zc>;j+1_5QoU^PKD@`CD4a3bWmnl54AA{=B8{ds2kunydf>p{8FL}F+*H^Bdd+brQ` zVUIXLPh*+_!qdS=Tsj(dAs_i+^~?uuae*gZB3l9GN2bR+=1pb3%zHGvllT|+ z1D3fdx;%hLago1Dz2~OAtFGh3!kt-oo~H_}-xOJ^M`2C%N9Zn4_&!J*B~eX!OM36}z0H zB+|u!BQ1EQ{dF2z6OBtsLV4`qVaZBRkd*7lov1J6o7w7p@@#t!vp_G^2}ld^MeW|O z0a=aVFXm8#1spdz@>lc7?aY0-g_MbTHk-1(ZD?2;YtD$OnrD~(Kfz#VhigQfMpp%V zlXZ{=r&p~Fbs&r8LyA@LDk-7?CuV#wWOd+=rWnQDtl=i0!gj^)qb_}BIBdazXaIgx z5eW#Pp>C$2Ma;2q_dHb~>zYiO4Bee~*N;LnIAZM0`Z?wQNn}SwxYf4usB2c!NISj# z+M>zR51FI&X@3jzc^5<=a&WVS-*VgJyf`D zCCwP$MPY&|_S@6n0pjep&1rjenRTjz`bFyHy8cqJRo}!LwgbB1rK*J=4tpAO#KB&) z+`a2Uv5uJ(WR@LX(Y5u&;*QG=RjRyC&>;O&=`B1{Hj&{MO@7kM=XJgIGI`-!Ao>1G zaJpSXTjS7GhL&N+C)v5VKMnXqF>0#N!Lu}0Tull%{Pmea)!H&0-XH$)RN!EeVA-&s z=y+{?YCx$Yt+tMl$d{DDkU6LR^`cbB#_f1SsCLtanfZIIsk!u0S?#cRSC(&sZ->m| z+n|x~Eun+fG^6{tj@p%>2x)drgb}w89euxy`P=&57hNF1I7;G8UDW4g^p_uoZ!XlK z2C=)U87}&!AdGceG$QxWUHZ_`Ev*g^+uok@Mv|j{U|8%aSAPl)Y56*DMw)w-}3o7|P-Z2bHj|Xl6SddF+-K0xs1Lt9TE0FpiFIa|f8LdQhKR$fzR88OPM}As zkpI=PpLopFoUF*Q34g*mPiPV_uHUPKem!D>SIh3IQx#rt&z;Fi5vkz8_>FsW#z10< z#s$Qhy@@wGYJMKrnDe=CddshTVfO|Seg=So|8PS$4w5InEv)(ZqIyb^<(DYmDK21x zr>0qY!T^~do`emj46~dQN|RlPe)lV94%BC7jEAjL*;kr3WgmS^W7EpeK^hSOMO(2; zy(MDyU!|JJq&h8gW5nSfGjt}?Om(M>U{}b5=q!U?KGw7K78la_e=hmOgZ6;i|AB|&e1b;CL)WKYN19+!P+uRGWb z;JRhxW@_ZXdM*EaAO9cP-^rDyGX>m^%>LD@kiEx;Ans=fLz+5gD+-c?k55Vkmn91c zfYf>^umUX2Oz0Nf^@(n<`}FN2a_uR;wGKo_%|_1#fZV_5KmlktIH{$|*i-cen=vSL z!b4G-0`;kTlEdYIu(K-?;{B?Y2+3O6;QrHQDiQYwE)NRh;%xL2rR2k*pTfv<(uANi zQGJyj&bzw?d(pazw-0iU;%VEL5^z%ckGa;n-DI4+lopdsWHfL@9_%TFkG|#M}E;7vrfe)zQ_awLwm(YiK++&6S z(igl{%)`bxhoVD`F!%b6bC{144G-q~>W0*_j}d2L^%lD(@~)lLrE79HO#Z1oOYP#O|q;c8&s@me*giDij$$Yvo2ym zsTxVZ$v;&m&Yq?3M#7-(jF6a%qZt%bNKRMib*4T0+;99fDJ0%VX~B%?3Q$kL@IKY? zEg}PMgJ2^Idni?w{ys@QeaSVB=>sB6-HVcAr~8Qz3iNgSb@rljb?UoGB9Du5IlK7| z!R}}Uj)!eC{Wl|FY8Y?ZlKi935F>W@s)!B8b;(`f1QypPpis6iP)IOxT^zMjiqe7~WI`-TE+~!?%bz)c z`M#lto!bKebr@ILqm`S=wy zU=&3IF(XE%6oGg}zOlKRuBAW~4d&$m4831$%_!mVTLm%FxyRJmQnA=`qUcbf27g%A zp|A_yy{F|fL8IwZ@rJjWJeiXDts}Y9--^wk^h`EsVk0LyPjt3%z2$pxP|K6cMpmH~ zNo|AjcLo2ReG}wWb*=By8D zWOGhE$lf3quJ;5%uBEqAw0oEpt07+Iz>f=|t_1e2()7r*4KDb$qS8dZvCGHrzex9J zSzWl7?L4DA$tABdZ9ZMIiyq%F&VDw@(689aeA$9FHxq-daoH&=Md(k+5M)zS_D9F- zE|<0A=OOB}VM~=t{)8fK^~-%7nxa#w4A>eBDxiODuzvT7bp83foX?cG z-4=18LUv~(@p6J#lN*kMAS*~6St2fJqu>5&ad{*4cGEv9E4&=wzLK%mTW#3-z7 zzYniJo;e&nEw;;P@38JH)7J+I-6RSY36y$FH#|S|SbXP!|Kr9(d$Py!0pNTcB3~80 zl{Ms}Jaj0ycY=7m{=VA)vv&9%ko^Ub{p`iF&c@9<{B7Fvaod9Yi;J}W8U9v{YKIZi z>Nz-iR9KJBBzde9^sbU;4ISaz2Y3oXog$$l<;TvX1D@%k<60O9dB)|yxTOq2(&eT_ z+`_X3#(ahXhEM)^*>Da*FwIGw`hs($z$Zz}0g0~64lH@a-<1ZxAp4|{Q|;j%e&HWd zE_ZsktMg)^#3<0NkO8^?t4!MFwuF!m1ogrT2^XHgvx2CuUZmK&N)HV-vFTa^^l$uw|ud_2&WKUoU-;%0hQJ{SytJTf5*E zk#LPb<hQ#s0L!U2zJ>QYlg=2aPG+DQ zBxoaS9H;$!Cc%_zlf7?njq9rd5CQ`3T{N1_Kf${MdUv<=qAEMU>bspN@mm22F&_u^ zIFmGIotIC+5w7g3v5X5)&*vbT`M;ps8v@S|CY9X_xd$?ci=5qyH;9W= z_wSa3VXD-G^hTk&D<~&uz~&X4R;IJun||Ql+tFT|6jN%ylIG)LE*et`4lN)~(`09Y z_B^u@<(98fG6l>5!zzRb?k-&z;C`9kQ+j`wz(z`O&nP5lMiqKmwf04p2UlD<1IIuB z4s4>-ZdQGsGb-Y;z;N+sBedUJ`f`OR&*ylD0}%QC{G}uyxlsxfEqENZzmVeGI^e{uxmX9^_a_ez*qu<+=%{rxdoY9uN2O^()!G%G zE58%d^uCXN?7^!e+Fw(GBKKujchy+$r{5e!#sA=t$E}oJ{E$di$%mCytMsz8iT4xT zHdQEan7d~Kor744A?|gR)00QDA67j9t z=;_TYk^^>v0l$l)21+;(~R8x5a7=p*s{$04=1TeVNkxR6*YFApbH z9M*3mQ4}tiH}(uRT2li2~6Muw^6N}OQD;Y?&!iQ4W zgdKslaBF4l!+^Hzx-s7U2Sf!n6z-q%75$V!Zu>+gfKA8=Qh*CRBD^*?BEkW= z!Nr4wpS&;c8(gGKNlp}~5NKj+7!2ip|J(N{w`G{FV`XV*jBRgQD6Z*h`*I;ywcH}W zX}fZr!oua!t7Sr|>+D)v!I_ikpCqFPWZ~E|m28Tc zE1+|`YJp++X9Le$6N!{OAwO-8;(JS68yLWQG$^X*%|!gXfr4kaJ6v6>qz+d#2#Y?i zHIaJ&bJxDk@#cVcO-!gtv7A&YEOliTm6Sa-Dob!@t&8S(R<$~U?iyR7C}Izcs9c1= zU5P-ipJ9WsE&S=lQx@nLbwXS|v&S@wJ@JcM58Oi&E#(Ugr|ZgY4nO4Na|`(?H1))< zLWVnbCaThNX8n%8x4_afB}-H8`D!I8tlI7eT&O>)WvkjRdTs>)mp1X{3s&3%9vkc7 zf(q@#k?!asxDnFt@gh+=8_WS-Iu=U|5okco0!r6&L~uGd-Ftz8mF;0R)ce!Qla6!I z$cdh9^k3v;or*xFe&q_F>27Pq!X2{C^ZjEA+hmumKdF;`rN$@CO0KEufs}R%ApH%Y z9K(n=w~Wy`o}c?&AmOq#BSPOnQ*ex^)6tbbOtmjML#wO{-Fyr4Av%I{iGFQGNDEEa zP*$6_%Mg~o&hAsTmtR@pxxc(&q>w_Li+Sh`bZ0)vuEw9*zVG+5%g1E^g3AfEnp*L( zszn-9&C6*4L8XLTxn|bob{c|fZ7Yaim4mmgzZk6pbX45g*Bl&(q2OP&e@S_>xb0Q3 zP5(87nv`^`{<~Q;RNU9u({abw6D1;NRb!^yNw`4MM=bV#AbOew^9Cw$Y)YQ#gLZ6x zc_3T)kM-e0cY5l%(LpTg&h_XtejpQ`fXlfQtE)9zfhYqU1_MjPNukeQ01d8$!L6Ub znxgZQJ7@p;RRo3DR{9mv&ecn@p!5jXeJ?}T3CtvG{=T(-GD``_^@p>qDc11WS4P@g z?*A;wGQr(Nh&+HD_%SLO;!^vN!*eRmQP58D#(*LrVuvMK>^b(f+;~hag+ZtWv+$Mg z4!Vs`N0AwSMU+B-J@xt=rM7qmHTyojLrfu-Bdb-ZuYK8%cra97e}{5*}L?HI{Ie~4;(ZUq<$q5}b>SFtWw ztZeO~yuB!yE$H$5@LF4`vjJJKfO;M|sI!r+t#Q03>hYLcl3!TGkAEDLd_gjXDSo-j0XA^xtOm9rG9M%&zpf zsw}D=P@gL36;`*+_d6USS9U6H>Qnr+?Br~N9LCx;vKot8n5Q;TZO(~Apc%2HtC*=B zJAgILs?Rt(?*+hl!8WhMh+q4F>#tL~gN%g)Wp%7Ul_un1wZ#V8%KZ2w-BQA^m41$5 zT2VZd&j_sK0dc0WkM3rlUGDV~1u7*)7ARN*4YoPx)pWo%&kq*&_E@ue3a>uv9D313 zOEKEpRlwV;)~;M(VQj!M*0*IZoi}Y`Yry2PR`|JFaMvZbYp5J0p1G_r- z+njB0mW_JR?%92SVFvS#sF%F|5-DUVqC!{f?*ZI_KQp;U3Z>Cs^%vQsT3w8Rv(;38 zQer@2egY1Bz@mlE7#Xbk6|3%N2@JN>AXJ=0q_AN7*0J-N@=vTZGIXYvWx~=mLblhS&$j#-@5zPOR zn?GQ~*Ko8kM}yqBuU|8LP>nfGZA_p$4nDa$5}SF4t_0IzWn9l`hW(|WJ1x{P;=r0I z__~RN$DK=4N0w?Y>k6$OCEMcDk947+`Dioja34%mmO8zgwy@2oJO9nAlf*2T&4YjW zY~UXCXb&dH>Op3__#UG%5Zk=;)S2+Vf>QR|2_@u3>YgUdyj(NFqe`>-wqFqSXv5!B zs%u{^jz;7h?5bcsqTp6{d1`^Fb*1TIrtDb2PZBID^Vk9}~^xqj8PZ`uy%Z78BnBBX*G6a?|-XM=V;ca^Cg@dGT zW2cEsZu6AQi6RsWSNQPK*F?T_W9WBmziXt#xfcm;yL!+AZqbVxsmyUu*F=HgyIAf4 z4CAp|B&UCC%qp4mS~-A&?34{&!}|0~Tf<>_q7m3B;gxvzjUinBvv_%a`a_MRhMtZN)z1y0--NB7 zBmDOMK5XDNS|D~i1uqNDpoCsFm9*^dk{A*Ajc|?!rtFkmVKQ6FHT%k`#{GvO7$^fE z%}}+8Yk!$V?{>=KgYpec9(EDP2Xf1E!4y|k&1k7|8uq023aW!&ti z_m_YE@ZGsq8=pLk;&DZHukP)0JO`IOkSV#;t5oHgkxJ6Co3=lA=1b-SJx&R5Sdr9e zL8VYWBD}Gwbuhfut>t*@PDRZ6t9O*Y<60*3n`?mb)tV3Tc6d%H+Q3{L9t!c8#~pJa zo=u*193Tt6{ysO;YHi!mWXKcYD`cYhe;=GID zoL9>Dfepd&_1J|Xo)oitq8M^56@Qu0(efAhf^Byhj(mk3+wcaOm}b`2VjQ{s_IZvn z(R}OSf$4=-FK~4#yD+L3R|OqbO^|$C*2ujZX0&?`Bg`Hy3)Z|MV0FJ41-W?&hchDc z^8tkBzq51gY4z*Lb|S&Eyk^luzKBH)G-fcWi+dRYus)K-|IQ~J%$&$ z4BmbItKLR0#$-kRBVXJ81`8f^r!V8@e0&3hsi79Ys7J;^>LOY zyj73nv$l4!pwdvvAV5z0yELwUyyT+;%iqzC=^Z7&h3be+->>iA-z zfL1pb|FaGZSieK-eDnf+|C)S9G)4`qG@1e}XLFr!-@;q^CmFvakIDlN;f3qwx9PU7 z_gg8wRutDkvB#>}sqiMjn^&N=8yI!|<1?g_5o! zW<^0A5+waHQ`vP9l&e>hwCYor#knmtQSn>vBzVm4^p5z)we4z#kLi?dRW!qqM3P&E z5RYUJlPt+&Ls~e_*MiBj$e%lY>oy5dQsxShL_y~jd-~j_6V|bhCcLHVFj3Y1Vds@~ zs3tRi4}GiLW@Ab-XXUDM_{df2tUmx;^4ftEoL@vf8$?5U&zp*jk&BBS5v7WoXvSC> zWkm(t-+sbET+`cKvz>QgySZYah=6tOr=>wF<|+zpkM-T5Pyo@07{6RDW|Mlp8SM^9 zx*xlsj5KI&F3cA6rd>-vTM>Rv_J?HwD?Jx)3V+g)ln z==A`%iLUu(Bx0vAVYP$USyTg)@R;oTY}$;nF-0DhgrlEqj5o4k-b=GD<6yxbdO35< zqlnHK1oKZ-{EF&geR0e^q7NFo(hTDFRek*XjCBi};es6_jjJ9_N9mho32TDHJIr>k z_RiwvOis^X-@DD-v(LJ{xV*Z1`wfp0t|kr0d|Y$Zs5Dij@wy!a{x{3Gr~Z-z(t8H2 z?Vil62jnuT!x8Pm7pz&+;A1Y0g#+Z)b6yKh5D>RpgIZ@TYBzBM7tex7JolDK9$rU2 zF}#i1oLB*Cb}j~e|JJXpFWGlYwpravaJz!>A5w`Xi110Lk2>^%6GaP#qc2rS`{PWa z6Gk5^MH*aDNSV_X7aAZKv_=9!Y-HuZ@{`J|=MX*FRoQ5~VJRwZeOPqdpw=g>Q2y~U zZ*kYniqe5=EPggVQ}^L=T-7oFTf{QaR8|?*J!8`~|7F&z@U~jLwHCuYaFoAL5CBrQ;YM9oe z6ZTCNubArTEXrID>rgXY!#4M>G*gdhm|YHwenI5{@qF5pmz@ev#CjjL$MjW<4|n8< zF3J7^k^Ju@3FHZ$MQ`mms!$M+wqHpyZpf5gnI>{^C>0L3wL#QEHs9pNL_o5%tl6t_ z5F5Yy(2~R?Fd2nxZ{7kazixeS!gw`*nxql2XJ-*;hrgg+t{B@Zf}7v#rz2j(zV(SA zs=HvCHitd7Nu|T6K8E+SCn(!IU&D92Z-%~pRvi-AzaU0~c;&w!Txd4P1jgadcT_|U z8LLotizYBaq@bP}!@7In^qPe9ihRobU^ICvP-j*0QyN(xqu{&HfS1(;lF3wO%>tF;RJ5rT-f(~($U)Yr?Sc~;+k{9BG*mcJ-wf>lG~S>?gw~r&brm}+hxBF~ zvq4*1k!QSM%OL#zNErSNs*F(^_|K>VH@X7o!&93Y0}tbZ-xlc{MpQYr7mKSove%gf z)`d#1Mgg*Dola2_Ed-9q8(T&!}i$-(_xC_Fi)6aBGkm7q2EUAgRK=^d!g`K#2 z;9^2Ylgqc}{4l(oKAi!Gt;xnQa(xM+F*Tz*Uy3YQ7W^P;iN;>g{x=A}U_p?5F@NKh zljDZK9$ci2%m%%{uVVa#YoWQ8ZiwUWO|{95!g-dZxz|_ z*9_3HzIx?(HMQv=vn;qsR`aMp^8z7NR#;^Y@1kPF8^*Eg5x0J~#;Vc2FgN zlbqN-X{Pv$0AJ=i^|@u*08ghlrSCqtLxD}*dmWMlzrZMX*<^$L2j9XZmac>i>k%8d zbinnM3Y7vdnYKxDGLvZySk+sqhpyw~!hmvl4aZ<4qf#&W>*W>UnO5l}!E0)O#8t~< zK|l2xYvuqv0Soy-i1Kw=7-I!8wnV_{+ehqvD^o^X>((CQxPZHQ$Ea(l*79{Zix;nu zxz4GiPmZj3V=08)Z7LZ33~v#~9&|05SLm` z6;;Ry-IV;Dmyfc*?;q?Ynk~*^au-8JP5`cbE?h?UPj#yxW1TlbBoN4%QMtRv{)Pa% znZiPKFm&E0rKpjeY#vYN2J1fXjthM2;H!h>joh$jJoO!du({m9j3gEk6 z4!@A!vu56?)n_n$pWykh?l`ul9KRR9nI{_?APjN;08C5u699P~n@#P$6hC7PC@`x{ z{Hv}pR4PEvhVS8ZgEh~v4I?7Zxzp*ac>2uNoiW17MJ z$l`4duTIvQUHHPuJB)O8Rjppf9&J(LXS(R|=tALD#YaVM56A8P-XS6B zj&k`T z(rV`KYA6L4pi9K*Ry4h_gDpg(DyB;4nhzBCmX={A=A-L_m$zxtt%M3HG=cOiCypSt zu22XC>FX#x9m+}sMRT&b3L$jPvaW%mCLs8v7?92!usir@2nf5MNPX?=TRR9K*Iv=v zmHJt^eC>H{*n}~)a{I1nN#=L7@F7mw_v-3(HUYQ3map9 zUf{W~Q7>v!F06s&n3lJFj(6X)QLm|8F^p|e8vEY5A!~489(Ie|Pvx5t@#xVLvux_C z)9ugRD|Et&<9;JRN8`;rJgZKbLhdSBQ#CF99uMo}d5!RKZ!HnVDX7A7aZ>G()VW{- z&Rs!HJ*I;%vg=R-K++FK*vG*ssWr9AeNC1|Ldu^nxS)L#{88Gb^htQp%$jgLx(92y zI+Tz@gfo2gHJ9FH{5JGcTc~6v?GtogKgq%@v!&st=ODu#mQp|rHEx6d$t|!W`}Jue zP_B+SKq!AN1D=bLiv>j2CmImK<#(k=A-<_3MEut*m53{K*)ePRMWHKyQB(qGmQvO<00*F+$-!56gszi>AR zMjpXDZ)dF*qNEun?SVF<&cu-l`{$V4v+`g_@BX)c4Ilvc9~<@uV!H(=YGCHiF24ZE z7f=o+0vfUj-7$pX*^Y!ZYA6{RS2NW&u}|1iy*jUgg=^eFJq4w70cHAhNiAbv z$*Vx|n`OOHg1Og6CxB3uiEc~nl;Jot?zRQPyZWmykiQN=P)cL)R9>>!B!*Y)U~Y&G zxar;o{({|&EF77F?8GBc<2#5s6V>MC0Vb}MEK!!2}n6M!g+>UI<{KCh2K!U{a z=r{S^*S;pR>FcxL$pAfbEwxfYq0~g2-vGPofm122yK>4#@X1-&@bY%&}F1|ypTc8Aiqo0kx)cq%S47# z2@n!mpRnu^@rk&nIbv{BDz05dulKeKM4F9P1BKk}y~AkE6G#uf5Q+W-ACZgc(MkM+ zOa3&8^POjrXahb3HscbE*C>t6{R%y%?@+yMgNNMkYMZj}efn<}5a@nUBs?HdO5UZ= zD+rMlNIOtZ)5``RQ7qSEB&`JLsHr)Hd{}0ITO%=matepokYA+%j&X9MKLEzHD)*ip z$+a&=uT&&?i#Lc4?I$Y`e*Kw{g|AXSrSZ%=>q}QF({Ji_=bT#4V z*YqnLEmiql33G0xD3^1567#rNGZSYe;@1jc*&uv`vcVS&|EQVV+%`~OnZteax!%EC z?;ae`8`&SHWN{A$e4%iB7!w!F z$64_hxompxw)5m<#^J0OS|2vikkpKPKvXHnxshxgY`_NZs$I)%<|#cM#H$Hv(5PvCD$m`N^yBvW6f>+ z9+(2rv6VxHiJ&`&za_tBC84Hufa09ZCGx>y{m92aNY9zzG#<4S{Z}!eBp&uOdPyms z`5pecMM1Dq7+|K-1rb`@#BVds<=V zrYYZlfdVqg8cKvNdwuE>8%BX@)q-ow#Rfu5<_S!MzRakkdqC`*I2V*~kG!v7RIi*u zG%^0ybi%P4DvW5^bp}7duVb#X98HnHE2@TReJ9H4do%uDXS$ z#pppJ(p*ddzf?}#MK^U^2n@A1G^M-A$MsjL))m13nT2CuZx5!BRniYTbVK_V+CNne zd0)m7i~)_f$&>^15eEx&ck{-Utux>D5gzU(6}@lP6Gd*UZXw=VopyHjU*mW^)jfl8 zyx9DncZ3C(HtVXd%!$9h4%`urX2SOU{tmKSfo0n!Tt6K1$2RIaY2nU{f3o0g;zDjq zFLB{O0 z#pqxABboV?GB5zi(yCepmhVO#&$5A&06=wak|0S)g74738hJ8zevQDOGL5Qfd)m9A z{2(FvRXr0mc!Y59qvZTmUorEG+gu=D*GcEbU71ATJp?!+EEPi`t>7z7F`E4~1T6|9 z;I*$k-8aCboQ9W7{cc*|In;X$T^bU{y68MwTYZ(jKHK`}d(d7mr|;3$_8`mP98#LlFGedzuk{;mN}pq~Z!R(*Jxi0FeoX?I4ZJ&C8vaav)^H zVRQ$T&JR9`Uc7!#xjTLCGxlSl_WnKWI+{&xrqu4Ow(KmQ>Qx~4zX8=72VQ0GPksU^-4GQbk0>?-UMH(e)u9jky$H@kz4SynSSclq{V zSvPZBdMzoOb!#VO5bigMZ59inAR0XQ4j$v;rdvQ+V~rIhC6h!G)#IXWbv<0@${iAY zr9#oAH7>gE!^a579(4?`AJ<3WTKir-^1hpc4!J}V?^0J&0eDmh`iHo|2(BPdRqQ5; zzM_(?9qxhx%I}IFAO`J$}@{dsqMZy{yXxuJiETcDvW#Fs`ADQT?MoH9Li> zi0?8y3$AX6X70K!a00YLH{k!|2XXJC**W6!|2BMG{HD!rhQ-PfenLMC%&SV?r)&8f zP;=+TYwB(G9o#(i>~HQT2hCG*Arz`tmwGC-cXG&+UeHF2+EZE?x=^$MSn}y z0J@DGbZo889s}17*JISjV~kZE-=E1@;&pihFz2{o3vd@#aRfVml~R3djKR22CBO`R zwuSv|X|mjm?3yh*k%mqTk?Petw6usL?H&BN^*+g6v?S%NTo@I*cM^}N_F>noakGjpnmBW_HB(q8iyXPx66O0_#iD zNG#-w`>IARr7d6b@@==xIxKV3lAG-LknJN?_M((niZN3cx>jn?P5=`*G&5EJ>_cLb%+9silZ^0 zCMRUpQBPSorP>WB(vJmvG1Xt_zkXfbT>5Y$2=#l!WQAH5k%M(fu{rdAcg_D<6t$fZ zXnV{Mk-y&YLOmZ{R{cdMzH|dxdvh031#X29K$KMZQrzRO+DkO0)9WVMg8l8$ONJty zf=bfApZg&@saUY5>lJM@xRlCl%1c^CFEKkP@0rmg7kXO_(>fpM?LL|EsQ%=t0_zQE#oMa7edl2U-S+d5F(JHUOzT=>#zR^+NiNQBlC)?ND7a zU{Ya?1A2g>Kr?BH-TI^v#WUe>)7Job2hDdU+>8xR5G(pR6$!B1S1mLb4t?F{QZnD( zX4T{=cG|NBNRJ1}@>o=o3VV@(4K8d{mi^d^uc?yamn%b5S+Eu6h zs!dVAWWL>#!Y4Pu3+D0PBiL_yJBfURvJ=aU`G`Uet?rcmZQ^CTgoRQ{+1`aO7Ih^o zY@usi7K`G59gH6ymd4uWXxv+?;f@38v)cf?wQaVy)%K#fGMY%$;(&6a*Bt_JHT49Q zZ~}y09&Mtm@7hq|_9;pvAcgJX0KR9c(d-yqYTB+o zNzY%4M%{TF64AV9<~(5nDBMs;aLku~C&2^+jLT`T%xu>dJBM0z zO4%6I3BS0>SLRUPT+r(Mbss)!Yi`m??!Y)D$R_tYeB@3%4;G2IMH&4c80%dOaMtUa zm}jfuBXRpVi{n?bZ(&81PUE;+iP?yj>t?K?CbBCnW;DQpv8ATOJeVMLec;$9m0Glr zfHxF)67A7;U4t((oTnd_GwqOmQ~9!S@1ahcmo$=YBR5CSJc4u3>uH*S-^X){6>Ebd z7ld?#l!^$MnrwLZ?H^|F<-qV!7|0FJ*^!qev$<483%#6WO3-R4_R0LLEGk{iCh&fS zZ7RS{SM&Apu)m)WXeV90EPQ!ne?#igbJg_?LgufWX24NK*^aXn!8Yi37?lRwsR$^T z=kkzn1??-iO}{6x4Do%06rXn_mjhT zpaftrF2Gq3o{z&VJ&phZXdVxf;4Ub`PaxF;ESYKN1P2w$oZoYu!cvE~Bz!B4ynzyV zG}+*}YaEQVX>>(>_J!h?k#I;9r*Bk~Lm>!SqhieMr-$fE_ShNQT2~00_>3_V$DS{#?)xS-Q$hBpy(uc_hvM^e^gvL^l{OWPogGLJ z4Z&{d;JYxTR)?z3!~Bw%*l1^2;trV76&hW_BC%WazUvzq@GWtCY*hubO#Zz$?qZ{_qR6_ep-(yQ`ZK@DGc?r{FQDW~sEMqfIdevyNqZfg4Z$ zj0R(JtcC_Iv4^Mjt}iZt^No{24F5x^DEB`)5v$Taqbdgfy=ZHB1g z(oRbo;lXyASc3t9cXf(=)*|}c;Xt@Nkyof~A)p2*vYp7vKIMJ|dgmwqRB~i^Gl=$o zBX9fNlT?d>SCtcBf^Fg)%pE6mPPM*W*|jpH0)YlrDYx00k$scdyT>TinjSPUJ(F%03ZMVyYpR$`hh%u04eMISNs0}P&x=M0uz%um|}iTzq=lYCA{VCua0R8(@UKP-c z#VSS|GtgmZTc5}NF9cAnfB&6tZ*Om3Pd{IN_8y+U9o^O6-y{CBzq`AytDmo@r>mEf zr<%4otk6pE9?#&JL zO)agRTCZs=;)~GN186z zd~FVY10q>-VHd(!l6d{$S&|6Vcz*b)vSn5~1FVHT!@gt15!=w>JJZk2KqmJ+*yT&h z`eI8HJgP=3RkKXA&4UC*z`0M;UqGx`3!oIjzSOQ7l^V_Y!WjV zBBlOP0a%$`j~=sbfsBiIi&{EkSj}eOlQ(9NAGO(lSm)Wr_(WK67~5#>MflS+7-zf9 zj^W+?FC$&`^wlTwhtgXjGJ=kaEbw49>p3o0(Etuq-$%d?VIb*zVKHdYwAVxnQ#y;TQ-a_QOd!30zY1(9wZZm zr68u8W9-jzjid9ntJBhxldyPhZME%z6otWh;hP&tZ{dtSM>Ca;XR8o@v|b;{#ARtS z^Yt{zHByPA35B3Oo1L3|#oZt3(L>bRp`WMoNJAEKBrA9&i`-By8U24I@M^)>GGd5 zjjS3pQA|t$A87;2PVgf0XNFl^0{7I3i`gFBWc-Po1R6f}2CAX_ZT!!UtB*y~9z@i? zg1WjO!zR{hoAKV9sqAF0^i>O6mG)Q8(OZzgIDk{%Kw3@fF!3Y?-s%{oy<}{=NJGe6y~OHu_XbePVwc zwlm?1R#*PR>-anPRPJ^s>xAi!+2(4w@iGs%|L=gNQ}nKKF}Y3!UFJjLrPfxRdcK$M z%?Ig^e*I2IRF}UMB{w>e~m&p^RVUp`w^w95zEU_ zyK`zXs=81-;+r;k`%2Kex_dJmdCyG0IVMES%mPGtl`zE%ZK?epA5nunQQ}|{_-B02 zPyP!04^$^JKm-#pf%pReyl?+x04-}nPya?OGqT{8vRWFQWL86S06(9r3gA%RVDj1M z;TK}W(^`Mx#t-0t`bPSvo_O#1{ghhmbcfpC`CJ-{5u=*z50F1Q(KqL7UNiiYm-myp{rihF{{{X-{m~}&O;g%{5h^U->9MIgFQ(C8#1To`{u{d=bji83HJ*1@AxSP3M| z*q7=30rH#1ERWBRdOSaOC)pwGz{0C})FZ$|EBIOkMv#0EzqN;SmBfU5nu~XXLnX0o z#T22^cW@LTye^1Kue)`CteZZrRgRoBW{sHYOPRmQWHwnV+zknJq2Jb!e7o`K+c+9n zxfoiI!mVSG!X+Wm2F7z92T3`%LHe1|3AyCO*cp6D-cj}fQREk#;1S|r(Op=_yMtTr zuca-;d~NDYZJSRfW(m?QT0piqDqpfZ>&Z40v`X)P1?t2~>AUcF>=q;%(U1t9AkZg3 zZs?nF-0guqhI{bwQ9QCSN@jy5+P{B?ADj!^q$1ozm4}X_I)j`k9GW_<;yx?hkBSD$ zdO316R z2o87qy;S{#Je|4!#3@eQIj8RhRXLIRbs-KAg&^=@%JhQB+nzxn-Rg7(-NG4^eB#i! zC_}ECKAeby%)dMA=7daQ(c;;w`RH-)tX%2LwVfJ%AU{BUYsLLrk@~lb(b@eUog5NO zXM=g|+?oWlUkBL z)eBJo42at&o_XH+5y7^T{8xo;A+|j^60-cYEKL?!v>w z5_H()`29OZl)|FtPRIM(wtwhhlO*#`X~{=XwnvxB0#X)E9S?74z$|t4{0=qzC|S~Z zc|6q_?;E8`MKDW7jV@`<(cjN0BPjDY4Qd|q)^l;~@PyCVFd7vC9oe`3#;h?sOn7zg zIPTqs)mv(U&EXOn3z6hGt?2oiO)q_4}SQ zlag<0=Ausa5Xk24ODIKIsu~)~FBMloTeUx<7PzN{KZ~w_064}xr09D5Meun}5ofkN zSzP+uIRJ?gc9ab|b_t|#g3*uzKyASk$96ts-%~An&bdCZMow>C)0++9d?JA!y2ar_ z1};JlE}oyv3*K7`+XtT-?r2)7Hr~ydTG%RMgqvkjhO->r8`(hmC&~l=zLA``n^Jvi>kR-GoV=ryNdRwl4T2 z?cdTbSW=j>qtesSK7ad82{bh3L(Be9b2Nt(GNy-^-&?#NuNB1t)~WKS;wd<}3DSPK z+Lp%3s)M3%14|no@E1bOQEfBTu}5i) zPz5+jhk$C+TZw%>Xx1^C#pnO!~RV@744@8~TJ27$8iJOOFOLlvak_w<46 z@-6xjEieOp4R^rDpWeX({?fgk)}(y3LjlO`?MG{yaD-Lf1e9m~l;K5`*?>NAk|Wf* zxNqY)9bWf9H^q-U-`-kGbq=3Ih4qBb#39u~JMHvs+)zP8!&|r4{_vgUr{qE)adDz4nLj-o z*4!a-7u0v72cq$9P9^6t5u%%LF9X;hYFu%dPdYq#4%v5$%2J_vcB}Br%lf4o7qs?^ z!ZZ4{fzxT3H0WhiO0ZN;BF__$Q}FhV#K z5#Q-%hQY@FbLJYVO&3ZWl6XSRVn$m$|8P_RDv&u{hiPYk1wQhtKAB;gaZotkjK@33 z@~9Yi9bJ00x3ul=4)?@8;tyq6ZrN zy|wxEC~#d(-cH6&9!_?i(jb94G2vOX)UU@;ZhjXgSxxkBaokASe+vh&aDVs2tMbUc zQbeXa#7&J*IN^30+#a*g1^*ACi*~}R9OO~L_eb_TU!UHkCwrn=WR-ow$9?|-ahnKF zR6c4JW#=#^_OL7tPFef}*iwiNRTd;xASa`C1Bati7mkYXkkP?@#5&#LzO?l)Pdpu@ z*kCz0{%{kSgbEiQakss{{DFc2LHvTSpzU~7Sm~Q;iW1i`a!#HK4s8}`*}2OdKpP~T zy7&o8QOd@UiGhM8RNp*)aNV-Y?!_%K5HZ&@zqT8>%e>35n{NdI$latxA8CTovvuVR znZ1c3h2vAa8xo1G+pSaab2U5|ZL|v}1&10|+bfoKH7f$=Ipr>~ysk*zZ;u zWOOb0U0!`tAs!pe`0q~gf^u%~=Tn5R9g_$I3V{vr9 z*TXlyoI@`wAaCY|xrRtaej|QC@;_{_iU_!jR~;}^-GIwbRs08CyL}{d5)V^6Hj5SF ztU6I$n)=L+*(Tq)hhYI0E$?ZJ5H>-5+fZ;!%u>D99Y9xtQgkyfK^i{B zE_njb#kpyNt^fdizSXFfNO>Zcu53(1T>pZfCoU$G6zRa5;uEG+2{~fL>IYYVW44dw zR`Sz485;F@K#uT4cj}#N_M`Mp#~tsl)7)WWu_Ml!MQc*SqwnMQ#-O*hiIYxOz#rMo zZesI-EkFRo^N}%iU-OIPM~VY>_Hf--Pd`os)DKz-NJ@|yZ3FM6X@Eh~DgCKRV|no| zs=-6JprLEf;m9biHA*_-XC|Ao*6vpt%X*8z(b|Z6-Dz6Ug{ht2Au*2w+Qm|HwmO7A zgGAd=*E3D<_rQ}X>L}48REfvXFX_i3z#-xkAq*7ErS+;jt+rZ=i(Yr_=U#Qq9CG{j zQy_l+6IERo3m>%PPt>y){Vppz-K;DxhZdrhq#r|dMYPiwvFB3o8tG#DeG^6Bf#{@R zO_g@F{~P2r%Y3ILtzhxtWE`eX1Mv97V=?s^rbY;JrJU`$w|oy?Qg zB`Wm3fX!C>KFsVp!uNLIE89rj3Wk$9%0{mL4~`0 ztFZRMW-;jny<~V#%XRQ7>GYb@Ucb2BTw9x+UH?s=9k?)(@(Y?(TPmsmzZM99D={#; zn>!VJ20KYV1qU=WFyN^bKqK7YMB0qGJ5RzxMt1c3`gio64hB34-^7&whkU^VDl|?9QNhzd;yJ(e$Dc0_httxF zKPOL2MRmO3ZGvB~Ln9!p!bPs0@GUY3rG?&iwc(<}zH>6W?>w;#- zB@a&ZC&PG3*7TP5d!SCJ&Px+`y${|a8%19_FQcB0aaE4>zCW`u zNux;x%#y0_oE7U{&trDH-=fThFFD)EI27a@`xDK%7{{X_x@XzB=4s{NyNu^#P>Hh>dt_6n>%oEJ+`)Eo$Z8-Z3T3! z3$M$v%R5I1+h_T%sGVWG4u02GzX*4ug_QJv$4gJ_tj(6*?o=a3n1e@saaUW?WW+c8 zLwd>(m=<0a&ipTkzgtXnps)~_HkSNNGdtkPFtD)N#$X8QS^>*kIEwY!+nbSi@j z5Us?znxA5jg!iGJy}mY=ZCEdP!L*Uz>En6Z=01!#*xeg>LP24mI17>?yln zZXLXbH%B<8neqQ%;J#hGrX|nlPZaA=-533U=9UR@Gq8K>(&s5N51$u^q(NJ|FuQ;` zvq4Mb$=^Y5=KSMeXv^F~H&#XSHd#KaRJf0r8!E&)tJPZr$GuXrv4*+88Jr z{v3k31k=2L&5sN_9EywPjd@`?kFn2D(MLzoh+j0T8fxTwE;PzXc+$bI|c^3 z^92$T+-HE8zzf$k58G-EVg8=6@91Wi=+VVwZ-vgK!>JK}`_xA;SxNu}e_B^shjQ61 zwly*iQ2!pFuVMF;oTKDRU1G+hGVZ`y7DdGn8QF8~SWOaWV*PjDQ--DkRnqes8nPL2 z1a17jO~8l22f}Am4G6ZO@3{1-Q>=BG*IH$8g9))(8zSI%L?pB!X^4}J`i5CjnV9#R0oD#UBAyGD-m zVRQCd@ka($T!uDx6{0Z{9QsD_TvRIfiuhb8jdr-xv4^!LiSqDD@;#}H8YPFksTFVa zKQ-jt0{j$Z)cv9R(*J{HA-Q9O0S5%bg09XF`AtCzo{t8oV^(eADirV@w*em^u++vB zvk{*cpWGyO(mFht87bc}DS8{hPX!P6T*Kdjwm!~T^@*8j7(oGJCZlqSOxnGK z(%;|lVt%VzQYa|kFVV+{X|?Z6VvjY##`7=>J^u{vBYs=}E|b2z@(*VZ3o#C4rXDX9 z-^&$ZV&+y$zqoa2R@%_}vovaR+gde@eC30#zHTMKKqYJ75(94I;-lk#v_B5uwKEKA^0@r+!-(zQccO;cJRLfCNDG1xgTWeXP!dL~MaXV-(<4 zA9cVrwlU?&SJ2HSC;z?cz9b0F5lAMQHW9i!aQgBkS?xwo_O^*t#u;QzXj2s7$&Q@o zexTpKCcz}2C(|${`8e!yup@+CYDxI z2C;;1iQEPm?5-y;06MK7oCR_0{&s-cPLS zjr>?|8hTTZwl#wIV0Olzvm4kSV+7@kibRCZArOA&WXdbLe9(N&ml2#FhQpu42jR-v zkY(BJ@_RYe=bIue=v%7NS_6)mIxkCo#RJ(AGG`fB{r?X<@uV2*MhD!5AwFwxkT3n8hKy#7ZowE=ElmjO=u^H`e}rwL*#+Cq>fe*971Pz9o8L ziqgT9Tyk_42OnE`i%vO}%GPiONH0&mBX$LPqj=XZ%4OtMzsDUHE$*Ma|Gy1p-(t z76dd4f1N|yb_7j9$Vx0K{WJ#X$MXCwlG5a`u2y)*WK*2|7dqrXAMnEHuM#50l%4-6 zB2i%gjfM1p-70OhElGKtK?#PiH^=j(d!WvzOsFJww&nNnh3v*6QP9dV7o~WZsehnn znO;&+Ww{rAqIlVOV|lJYfnY%l@d-a&=S!uXuKM&7QMnRj2P#+jBX8T5^+v$?7~xu*aYd{NE9 zqIc6dj}B(YRkes{Tx*ZSHS#-Xbu6FqK%{?!c-+GJj%TtSI08oRPUt6PJ$yael;RU( z5fR|Qwu1y@WYlEL%r1>RJty=y>-~DsdTvkq4oJU$sfr3sTwh-pn9#A~d~oUko%keR zE;&`xLXPg9RYabXRb5YqXZe2j5U}zP66r^r2j5wp>D1$QD}EwO7B-)C@y=%_)H<5` z-Z{?|wI*ck6l3#=bh6;caOUNwV+{j;HvS79VkyS+jGmm_aH=V{$I7_JQLuYN5arr)D7ajS=-1YZh@l$`sq-AH^CoFb1 zTyPLabB4^MS%y$N5Ir3{Gl;+Y!3OdvQZfn`ebO4fOcP*9@0n{1lMGO`lSU%{Qm*?6 zyu`!;@DaHAu3%;UJx_QQz~AdjBTvK%)w8GZ&VKLZg<4@?YS%A+-b2D1S{Dtn5W-qo>2r##IJPe|6f+ z4==LK|MQv^VD9m>&Ip!4L>_AjajpoFc3!5o@YqHH;pg@XW3ubWn&=xv6Rd$C;iaHrt;1 zkdQPhiFZr}I?P%AZX)Gygl1O2a6Y3Yr~! z!WgaLiC8@lL&I?=L(a}js)XNTBcHS}%ATF~%=8GmDnLpQP$ln{^ZCQPS)z|I7D>t= z17U7nBdh)i=jSt~+9~4F3PqJ<8IWG|n{Xtjr~RFecj3Y=KC6V(Nu+F><2vkb`@A!v z*uY;@a#i;Ih$chMyqBSs%w~d+jXd5%^JiG7bM#~hCA!Eg53^a!E6;gyThV$$rGZJA z6f1Jmfal)^aKWMibeVQ2Ng*0biCq^AA%z+_$~a$*Y~3QjYEyFS_fikBC0i3JBgl|V zdqhorMp8vMp1%daNe&CN;X=hh!lYJ>A$K%#1dKzVJm&=C0XSv0EoB+$OTIzWk{qN% z

    x1tQu(Ldn`HU4`nZ! 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
    Z6fp_Bd^YY$uoBaM`yKhUfP{B>>7+ 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%0DfX0dwn3j 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 kLqeG6o#fDHd{N - + - + + - + diff --git a/cpp/cpp_opengl/main.cpp b/cpp/cpp_opengl/main.cpp index bc80630..ea59b38 100644 --- a/cpp/cpp_opengl/main.cpp +++ b/cpp/cpp_opengl/main.cpp @@ -2,13 +2,13 @@ #include #include #include -//#include +#include #include #include #include #include #include -#include "../clipper.hpp" +#include "clipper.hpp" using namespace std; using namespace ClipperLib; @@ -25,7 +25,7 @@ PolyFillType pft = pftEvenOdd; JoinType jt = jtRound; bool show_clipping = true; Polygons sub, clp, sol; -int VertCount = 5; +int VertCount = 35; int scale = 10; double delta = 0.0; @@ -129,7 +129,6 @@ void InitGraphics() glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glTranslatef (0.375, 0.375, 0); } //------------------------------------------------------------------------------ @@ -156,15 +155,18 @@ void ResizeGraphics(int width, int height) } //------------------------------------------------------------------------------ -void DrawPolygon(Polygons &pgs, poly_color_type pct) +void SetGlColor(unsigned color) { - switch (pct) - { - case pctSubject: glColor4f(0.0f, 0.0f, 1.0f, 0.062f); break; - case pctClip: glColor4f(1.0f, 1.0f, 0.0f, 0.062f); break; - default: glColor4f(0.0f, 1.0f, 0.0f, 0.25f); - } + byte a = color >> 24; + byte r = (color >> 16) & 0xFF, g = (color >> 8) & 0xFF, b = color & 0xFF; + glColor4f(float(r)/255, float(g)/255, float(b)/255, float(a)/255); +} +//------------------------------------------------------------------------------ +void DrawPolygon(Polygons &pgs, unsigned brushColor, unsigned strokeColor) +{ + bool IsSolution = (strokeColor == 0xFF000000); + SetGlColor(brushColor); GLUtesselator* tess = gluNewTess(); gluTessCallback(tess, GLU_TESS_BEGIN, (void (CALLBACK*)())&BeginCallback); gluTessCallback(tess, GLU_TESS_VERTEX, (void (CALLBACK*)())&VertexCallback); @@ -173,25 +175,21 @@ void DrawPolygon(Polygons &pgs, poly_color_type pct) gluTessCallback(tess, GLU_TESS_ERROR, (void (CALLBACK*)())&ErrorCallback); gluTessNormal(tess, 0.0, 0.0, 1.0); - switch (pft) - { - case pftEvenOdd: - gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); - break; - case pftNonZero: - gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); - break; - case pftPositive: - gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE); - break; - default: //case pftNegative - if (pct == pctSolution) - gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); - else - gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NEGATIVE); - } + GLdouble windingRule; + if (IsSolution) + windingRule = GLU_TESS_WINDING_ODD; + else + switch (pft) + { + case pftEvenOdd: windingRule = GLU_TESS_WINDING_ODD; break; + case pftNonZero: windingRule = GLU_TESS_WINDING_NONZERO; break; + case pftPositive: windingRule = GLU_TESS_WINDING_POSITIVE; break; + default: windingRule = GLU_TESS_WINDING_NEGATIVE; break; + } + gluTessProperty(tess, GLU_TESS_WINDING_RULE, windingRule); - gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); //GL_FALSE + //brush fill polygons ... + gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); gluTessBeginPolygon(tess, NULL); for (Polygons::size_type i = 0; i < pgs.size(); ++i) { @@ -207,19 +205,9 @@ void DrawPolygon(Polygons &pgs, poly_color_type pct) gluTessEndPolygon(tess); ClearVectors(); - switch (pct) - { - case pctSubject: - glColor4f(0.0f, 0.6f, 1.0f, 0.5f); - break; - case pctClip: - glColor4f(1.0f, 0.6f, 0.0f, 0.5f); - break; - default: - glColor4f(0.0f, 0.4f, 0.0f, 1.0f); - } - if (pct == pctSolution) glLineWidth(1.0f); else glLineWidth(0.8f); - + //now 'stroke' polygons ... + SetGlColor(strokeColor); + glLineWidth(1.0f); gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE); for (Polygons::size_type i = 0; i < pgs.size(); ++i) @@ -233,14 +221,6 @@ void DrawPolygon(Polygons &pgs, poly_color_type pct) gluTessVertex(tess, vert, vert); } - switch (pct) - { - case pctSubject: - glColor4f(0.0f, 0.0f, 0.8f, 0.5f); - break; - case pctClip: - glColor4f(0.6f, 0.0f, 0.0f, 0.5f); - } gluTessEndContour(tess); gluTessEndPolygon(tess); } @@ -251,6 +231,24 @@ void DrawPolygon(Polygons &pgs, poly_color_type pct) } //------------------------------------------------------------------------------ +enum TextSize {tsSmall, tsMedium, tsLarge}; + +void DrawText(int x,int y, char* text, TextSize size = tsMedium) +{ + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + glRasterPos2f(x, y); + void* font; + switch (size) + { + case tsSmall: font = GLUT_BITMAP_HELVETICA_10; break; + case tsLarge: font = GLUT_BITMAP_HELVETICA_18; break; + default: font = GLUT_BITMAP_HELVETICA_12; + } + for (char *c = text; *c != '\0'; c++) + glutBitmapCharacter(font, *c); +} +//------------------------------------------------------------------------------ + void DrawGraphics() { //this can take a few moments ... @@ -258,55 +256,57 @@ void DrawGraphics() SetCursor(hWaitCursor); SetClassLong(hWnd, GCL_HCURSOR, (DWORD)hWaitCursor); - //fill background with a light off-gray color ... + //fill background color ... glClearColor(1,1,1,1); glClear(GL_COLOR_BUFFER_BIT); - //glRasterPos2f(110, 340); - //glColor4f(0.0f, 1.0f, 0.0f, 1.0f); - //char * text = "Positive Fills"; - //for (int i = 0; i < strlen(text); ++i) - // glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, text[i]); - - DrawPolygon(sub, pctSubject); - DrawPolygon(clp, pctClip); - if (show_clipping) DrawPolygon(sol, pctSolution); + DrawPolygon(sub, 0x100066FF, 0x990066FF); + DrawPolygon(clp, 0x10FF6600, 0x99FF6600); + if (show_clipping) DrawPolygon(sol, 0x6000FF00, 0xFF000000); + + //RECT r; + //GetWindowRect(hStatus, &r); + //int statusHeight = r.bottom - r.top; + //GetClientRect(hWnd, &r); + //r.bottom -= statusHeight; + //DrawText(4, 16, "This is a demo."); wstringstream ss; if (!show_clipping) - ss << L"Clipper Demo - NO CLIPPING"; + ss << L" NO CLIPPING"; else switch (ct) { case ctUnion: - ss << L"Clipper Demo - UNION"; + ss << L" UNION"; break; case ctDifference: - ss << L"Clipper Demo - DIFFERENCE"; + ss << L" DIFFERENCE"; break; case ctXor: - ss << L"Clipper Demo - XOR"; + ss << L" XOR"; break; default: - ss << L"Clipper Demo - INTERSECTION"; + ss << L" INTERSECTION"; } switch(pft) { case pftEvenOdd: - ss << L" (EvenOdd filled polygons with "; + ss << L" with EVENODD filling and "; break; case pftNonZero: - ss << L" (NonZero filled polygons with "; + ss << L" with NONZERO filling and "; break; case pftPositive: - ss << L" (Positive filled polygons with "; + ss << L" with POSITIVE filling and "; break; default: - ss << L" (Negative filled polygons with "; + ss << L" with NEGATIVE filling and "; } - ss << VertCount << " vertices each.)"; - SetWindowText(hWnd, ss.str().c_str()); + ss << VertCount << " vertices."; + wstring s = ss.str(); + SendMessage(hStatus, SB_SETTEXT, (WPARAM)1, (LPARAM)const_cast(s.c_str())); HCURSOR hArrowCursor = LoadCursor(NULL, IDC_ARROW); SetCursor(hArrowCursor); @@ -394,19 +394,10 @@ void TranslatePolygon(ClipperLib::Polygon &p, int dx, int dy) } //--------------------------------------------------------------------------- -//void MakePolygonFromIntArray(const int ints[][2], int size, ClipperLib::Polygon &p) -//{ -// p.clear(); -// p.reserve(size / 2); -// for (int i = 0; i < size; ++i) -// p.push_back(IntPoint(ints[i][0], ints[i][1])); -//} -//--------------------------------------------------------------------------- - void UpdatePolygons(bool updateSolutionOnly) { if (VertCount < 0) VertCount = -VertCount; - if (VertCount > 50) VertCount = 50; + if (VertCount > 99) VertCount = 99; if (VertCount < 3) VertCount = 3; Clipper c; @@ -418,18 +409,13 @@ void UpdatePolygons(bool updateSolutionOnly) GetWindowRect(hStatus, &r); int statusHeight = r.bottom - r.top; GetClientRect(hWnd, &r); + r.bottom -= statusHeight; sub.resize(1); clp.resize(1); - //int ints[] = {0,0,0, -100,100, -100,100, 0}; - //int ints2[] = {0, 100, 100, -200,0, -200,100, 100}; - //MakePolygonFromInts(ints, 8, sub[0]); - //TranslatePolygon(sub[0], 100,220); - //MakePolygonFromInts(ints2, 8, clp[0]); - //TranslatePolygon(sub[1], 100,220); - MakeRandomPoly(sub[0], r.right, r.bottom - statusHeight, VertCount); - MakeRandomPoly(clp[0], r.right, r.bottom - statusHeight, VertCount); + MakeRandomPoly(sub[0], r.right, r.bottom, VertCount); + MakeRandomPoly(clp[0], r.right, r.bottom, VertCount); //SaveToFile("subj.txt", sub); //SaveToFile("clip.txt", clp); @@ -500,7 +486,7 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) L"P - for Positive fills.\n" L"N - for Negative fills.\n" L"------------------------------\n" - L"nn - number of vertices (3..50).\n" + L"nn - number of vertices (3..99).\n" L"------------------------------\n" L"UP arrow - Expand Solution.\n" L"DN arrow - Contract Solution.\n" @@ -513,43 +499,58 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) L"SPACE, ENTER or click to refresh.\n" L"F1 - to see this help dialog again.\n" L"Esc - to quit.\n", - L"Clipper Demo - Help", 0); + L" Help", 0); return 0; case WM_COMMAND: - switch(LOWORD(wParam)) { - case 1: PostQuitMessage(0); break; //escape - case 98: SendMessage(hWnd, WM_HELP, 0, 0); break; - case 99: MessageBox(hWnd, L"After closing this dialog,\ntype the required number of vertices (3-50) then ...", L"Clipper Demo", 0); - case 101: show_clipping = true; ct = ctIntersection; UpdatePolygons(true); break; - case 102: show_clipping = true; ct = ctUnion; UpdatePolygons(true); break; - case 103: show_clipping = true; ct = ctDifference; UpdatePolygons(true); break; - case 104: show_clipping = true; ct = ctXor; UpdatePolygons(true); break; - case 105: pft = pftEvenOdd; UpdatePolygons(true); break; - case 106: pft = pftNonZero; UpdatePolygons(true); break; - case 107: pft = pftPositive; UpdatePolygons(true); break; - case 108: pft = pftNegative; UpdatePolygons(true); break; - case 109: show_clipping = !show_clipping; UpdatePolygons(true); break; - case 110: case 111: case 112: case 113: case 114: - case 115: case 116: case 117: case 118: case 119: - DoNumericKeyPress(LOWORD(wParam) - 110); - break; - case 120: UpdatePolygons(false); break; //space, return - case 131: if (delta < 20*scale) {delta += scale; UpdatePolygons(true);} break; - case 132: if (delta > -20*scale) {delta -= scale; UpdatePolygons(true);} break; - case 133: if (delta != 0.0) {delta = 0.0; UpdatePolygons(true);} break; - case 141: {jt = jtMiter; if (delta != 0.0) UpdatePolygons(true);} break; - case 142: {jt = jtSquare; if (delta != 0.0) UpdatePolygons(true);} break; - case 143: {jt = jtRound; if (delta != 0.0) UpdatePolygons(true);} break; - default: return DefWindowProc (hWnd, uMsg, wParam, lParam); + switch(LOWORD(wParam)) + { + case VK_ESCAPE: PostQuitMessage(0); break; //for accelerator IDs see menu.res + case 98: SendMessage(hWnd, WM_HELP, 0, 0); break; + case 99: MessageBox(hWnd, + L"After closing this dialog,\ntype the required number of vertices (3-99) then ...", + L"Clipper Demo", 0); + case 101: show_clipping = true; ct = ctIntersection; UpdatePolygons(true); break; + case 102: show_clipping = true; ct = ctUnion; UpdatePolygons(true); break; + case 103: show_clipping = true; ct = ctDifference; UpdatePolygons(true); break; + case 104: show_clipping = true; ct = ctXor; UpdatePolygons(true); break; + case 105: pft = pftEvenOdd; UpdatePolygons(true); break; + case 106: pft = pftNonZero; UpdatePolygons(true); break; + case 107: pft = pftPositive; UpdatePolygons(true); break; + case 108: pft = pftNegative; UpdatePolygons(true); break; + case 109: show_clipping = !show_clipping; UpdatePolygons(true); break; + case 110: case 111: case 112: case 113: case 114: + case 115: case 116: case 117: case 118: case 119: + DoNumericKeyPress(LOWORD(wParam) - 110); + break; + case 120: UpdatePolygons(false); break; //space, return + case 131: if (delta < 20*scale) {delta += scale; UpdatePolygons(true);} break; + case 132: if (delta > -20*scale) {delta -= scale; UpdatePolygons(true);} break; + case 133: if (delta != 0.0) {delta = 0.0; UpdatePolygons(true);} break; + case 141: {jt = jtMiter; if (delta != 0.0) UpdatePolygons(true);} break; + case 142: {jt = jtSquare; if (delta != 0.0) UpdatePolygons(true);} break; + case 143: {jt = jtRound; if (delta != 0.0) UpdatePolygons(true);} break; + default: return DefWindowProc (hWnd, uMsg, wParam, lParam); + } + return 0; + } + case WM_LBUTTONDOWN: + { + return 0; } - return 0; case WM_LBUTTONUP: - UpdatePolygons(false); - return 0; - + { + //int xPos = short(lParam & 0xFFFF); + //int yPos = short(lParam >> 16); + //wstringstream ss; + //ss << " " << xPos << ", " << yPos; + //wstring s = ss.str(); + //SendMessage(hStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)const_cast(s.c_str())); + UpdatePolygons(false); + return 0; + } // Default event handler default: return DefWindowProc (hWnd, uMsg, wParam, lParam); } @@ -560,7 +561,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - const LPCWSTR appname = TEXT("Clipper Demo"); + const LPCWSTR appname = TEXT("Clipper OpenGL Demo"); WNDCLASS wndclass; MSG msg; @@ -612,7 +613,13 @@ int WINAPI WinMain (HINSTANCE hInstance, InitCommonControls(); hStatus = CreateWindowEx(0, L"msctls_statusbar32", NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, (HMENU)0, hInstance, NULL); - SetWindowText(hStatus, L" Copyright © Angus Johnson 2011"); + + //set two panels in statusbar ... + int statusWidths [] = {120, -1}; + SendMessage(hStatus, SB_SETPARTS, + (WPARAM)(sizeof(statusWidths)/sizeof(int)), (LPARAM)statusWidths); + + SetWindowText(hStatus, L" Press F1 for help"); // Initialize OpenGL InitGraphics(); diff --git a/cpp/cpp_opengl/menu.res b/cpp/cpp_opengl/menu.res index b639bb8e6656095214a8f9e6ff49d4efdac6fc34..8d2e57d5ea3ed2a4cc8082e1bb85787e6fd8aacc 100644 GIT binary patch delta 13 UcmX@Xb%JX{3Jat3= e.nextE.yCurr: - e.xBot = e.xCurr - e.yBot = e.yCurr - e.xTop = e.nextE.xCurr - e.yTop = e.nextE.yCurr + e.Curr = pt + if e.Curr.y >= e.nextE.Curr.y: + e.Bot = e.Curr + e.Top = e.nextE.Curr e.windDelta = 1 else: - e.xTop = e.xCurr - e.yTop = e.yCurr - e.xBot = e.nextE.xCurr - e.yBot = e.nextE.yCurr + e.Top = e.Curr + e.Bot = e.nextE.Curr e.windDelta = -1 _SetDx(e) e.outIdx = -1 e.PolyType = polyType def _SwapX(e): - e.xCurr = e.xTop - e.xTop = e.xBot - e.xBot = e.xCurr + e.Curr = Point(e.Top.x, e.Curr.y) + e.Top = Point(e.Bot.x, e.Top.y) + e.Bot = Point(e.Curr.x, e.Bot.y) class ClipperBase(object): @@ -302,28 +297,28 @@ def _AddBoundsToLML(self, e): e = e.nextE while True: if e.dx == horizontal: - if (e.nextE.yTop < e.yTop) and (e.nextE.xBot > e.prevE.xBot): break - if (e.xTop != e.prevE.xBot): _SwapX(e) + if (e.nextE.Top.y < e.Top.y) and (e.nextE.Bot.x > e.prevE.Bot.x): break + if (e.Top.x != e.prevE.Bot.x): _SwapX(e) e.nextInLML = e.prevE - elif e.yBot == e.prevE.yBot: break + elif e.Bot.y == e.prevE.Bot.y: break else: e.nextInLML = e.prevE e = e.nextE if e.dx == horizontal: - if (e.xBot != e.prevE.xBot): _SwapX(e) - lm = LocalMinima(e.prevE.yBot, e.prevE, e) + if (e.Bot.x != e.prevE.Bot.x): _SwapX(e) + lm = LocalMinima(e.prevE.Bot.y, e.prevE, e) elif (e.dx < e.prevE.dx): - lm = LocalMinima(e.prevE.yBot, e.prevE, e) + lm = LocalMinima(e.prevE.Bot.y, e.prevE, e) else: - lm = LocalMinima(e.prevE.yBot, e, e.prevE) + lm = LocalMinima(e.prevE.Bot.y, e, e.prevE) lm.leftBound.side = EdgeSide.Left lm.rightBound.side = EdgeSide.Right self._InsertLocalMinima(lm) while True: - if e.nextE.yTop == e.yTop and e.nextE.dx != horizontal: break + if e.nextE.Top.y == e.Top.y and e.nextE.dx != horizontal: break e.nextInLML = e.nextE e = e.nextE - if e.dx == horizontal and e.xBot != e.prevE.xTop: _SwapX(e) + if e.dx == horizontal and e.Bot.x != e.prevE.Top.x: _SwapX(e) return e.nextE def _Reset(self): @@ -332,15 +327,13 @@ def _Reset(self): while lm is not None: e = lm.leftBound while e is not None: - e.xCurr = e.xBot - e.yCurr = e.yBot + e.Curr = e.Bot e.side = EdgeSide.Left e.outIdx = -1 e = e.nextInLML e = lm.rightBound while e is not None: - e.xCurr = e.xBot - e.yCurr = e.yBot + e.Curr = e.Bot e.side = EdgeSide.Right e.outIdx = -1 e = e.nextInLML @@ -378,8 +371,7 @@ def AddPolygon(self, polygon, polyType): edges = [] for i in range(ln): edges.append(Edge()) - edges[0].xCurr = pg[0].x - edges[0].yCurr = pg[0].y + edges[0].Curr = pg[0] _InitEdge(edges[ln-1], edges[0], edges[ln-2], pg[ln-1], polyType) for i in range(ln-2, 0, -1): _InitEdge(edges[i], edges[i+1], edges[i-1], pg[i], polyType) @@ -387,9 +379,8 @@ def AddPolygon(self, polygon, polyType): e = edges[0] eHighest = e while True: - e.xCurr = e.xBot - e.yCurr = e.yBot - if e.yTop < eHighest.yTop: eHighest = e + e.Curr = e.Bot + if e.Top.y < eHighest.Top.y: eHighest = e e = e.nextE if e == edges[0]: break # make sure eHighest is positioned so the following loop works safely ... @@ -422,64 +413,64 @@ def _PopLocalMinima(self): #=============================================================================== def _IntersectPoint(edge1, edge2): if _SlopesEqual2(edge1, edge2): - if (edge2.ybot > edge1.ybot): y = edge2.ybot - else: y = edge1.ybot + if (edge2.Bot.y > edge1.Bot.y): y = edge2.Bot.y + else: y = edge1.Bot.y return Point(0, y), False if edge1.dx == 0: - x = edge1.xBot + x = edge1.Bot.x if edge2.dx == horizontal: - y = edge2.yBot + y = edge2.Bot.y else: - b2 = edge2.yBot - Decimal(edge2.xBot)/edge2.dx - y = round(Decimal(x)/edge2.dx + b2) + b2 = edge2.Bot.y - float(edge2.Bot.x)/edge2.dx + y = round(float(x)/edge2.dx + b2) elif edge2.dx == 0: - x = edge2.xBot + x = edge2.Bot.x if edge1.dx == horizontal: - y = edge1.yBot + y = edge1.Bot.y else: - b1 = edge1.yBot - Decimal(edge1.xBot)/edge1.dx - y = round(Decimal(x)/edge1.dx + b1) + b1 = edge1.Bot.y - float(edge1.Bot.x)/edge1.dx + y = round(float(x)/edge1.dx + b1) else: - b1 = edge1.xBot - edge1.yBot * edge1.dx - b2 = edge2.xBot - edge2.yBot * edge2.dx - m = Decimal(b2-b1)/(edge1.dx - edge2.dx) + b1 = float(edge1.Bot.x) - float(edge1.Bot.y) * edge1.dx + b2 = float(edge2.Bot.x) - float(edge2.Bot.y) * edge2.dx + m = (b2-b1)/(edge1.dx - edge2.dx) y = round(m) if math.fabs(edge1.dx) < math.fabs(edge2.dx): x = round(edge1.dx * m + b1) else: x = round(edge2.dx * m + b2) - if (y < edge1.yTop) or (y < edge2.yTop): - if (edge1.yTop > edge2.yTop): - return Point(edge1.xTop,edge1.yTop), _TopX(edge2, edge1.yTop) < edge1.xTop + if (y < edge1.Top.y) or (y < edge2.Top.y): + if (edge1.Top.y > edge2.Top.y): + return edge1.Top, _TopX(edge2, edge1.Top.y) < edge1.Top.x else: - return Point(edge2.xTop,edge2.yTop), _TopX(edge1, edge2.yTop) > edge2.xTop + return edge2.Top, _TopX(edge1, edge2.Top.y) > edge2.Top.x else: return Point(x,y), True def _TopX(e, currentY): - if currentY == e.yTop: return e.xTop - elif e.xTop == e.xBot: return e.xBot - else: return e.xBot + round(e.dx * Decimal(currentY - e.yBot)) + if currentY == e.Top.y: return e.Top.x + elif e.Top.x == e.Bot.x: return e.Bot.x + else: return e.Bot.x + round(e.dx * float(currentY - e.Bot.y)) def _E2InsertsBeforeE1(e1,e2): - if (e2.xCurr == e1.xCurr): - if (e2.yTop > e1.yTop): - return e2.xTop < _TopX(e1, e2.yTop) - return e1.xTop > _TopX(e2, e1.yTop) + if (e2.Curr.x == e1.Curr.x): + if (e2.Top.y > e1.Top.y): + return e2.Top.x < _TopX(e1, e2.Top.y) + return e1.Top.x > _TopX(e2, e1.Top.y) else: - return e2.xCurr < e1.xCurr + return e2.Curr.x < e1.Curr.x def _IsMinima(e): return e is not None and e.prevE.nextInLML != e and e.nextE.nextInLML != e def _IsMaxima(e, y): - return e is not None and e.yTop == y and e.nextInLML is None + return e is not None and e.Top.y == y and e.nextInLML is None def _IsIntermediate(e, y): - return e.yTop == y and e.nextInLML is not None + return e.Top.y == y and e.nextInLML is not None def _GetMaximaPair(e): - if not _IsMaxima(e.nextE, e.yTop) or e.nextE.xTop != e.xTop: + if not _IsMaxima(e.nextE, e.Top.y) or e.nextE.Top.x != e.Top.x: return e.prevE else: return e.nextE @@ -498,7 +489,7 @@ def _ProtectRight(val): def _GetDx(pt1, pt2): if (pt1.y == pt2.y): return horizontal - else: return Decimal(pt2.x - pt1.x)/(pt2.y - pt1.y) + else: return float(pt2.x - pt1.x)/float(pt2.y - pt1.y) def _Param1RightOfParam2(outRec1, outRec2): while outRec1 is not None: @@ -731,7 +722,7 @@ class Clipper(ClipperBase): def __init__(self): ClipperBase.__init__(self) - self.ReverseOutput = False + self.ReverseSolution = False self.ForceSimple = False self._PolyOutList = [] @@ -918,7 +909,7 @@ def _InsertLocalMinimaIntoAEL(self, botY): lb = self._CurrentLocMin.leftBound rb = self._CurrentLocMin.rightBound self._InsertEdgeIntoAEL(lb) - self._InsertScanbeam(lb.yTop) + self._InsertScanbeam(lb.Top.y) self._InsertEdgeIntoAEL(rb) if self._IsEvenOddFillType(lb): lb.windDelta = 1 @@ -930,19 +921,16 @@ def _InsertLocalMinimaIntoAEL(self, botY): rb.windCnt2 = lb.windCnt2 if rb.dx == horizontal: self._AddEdgeToSEL(rb) - self._InsertScanbeam(rb.nextInLML.yTop) + self._InsertScanbeam(rb.nextInLML.Top.y) else: - self._InsertScanbeam(rb.yTop) + self._InsertScanbeam(rb.Top.y) if self._IsContributing(lb): - self._AddLocalMinPoly(lb, rb, Point(lb.xCurr, self._CurrentLocMin.y)) + self._AddLocalMinPoly(lb, rb, Point(lb.Curr.x, self._CurrentLocMin.y)) if rb.outIdx >= 0 and rb.dx == horizontal and self._HorzJoins is not None: hj = self._HorzJoins while True: - dummy1, dummy2, overlap = _GetOverlapSegment(Point(hj.edge.xBot, hj.edge.yBot), - Point(hj.edge.xTop, hj.edge.yTop), - Point(rb.xBot, rb.yBot), - Point(rb.xTop, rb.yTop)) + dummy1, dummy2, overlap = _GetOverlapSegment(hj.edge.Bot, hj.edge.Top, rb.Bot, rb.Top) if overlap: self._AddJoin(hj.edge, rb, hj.savedIdx) hj = hj.nextHj @@ -954,7 +942,7 @@ def _InsertLocalMinimaIntoAEL(self, botY): self._AddJoin(rb, rb.prevInAEL) e = lb.nextInAEL - pt = Point(lb.xCurr, lb.yCurr) + pt = lb.Curr while e != rb: self._IntersectEdges(rb, e, pt) e = e.nextInAEL @@ -1030,26 +1018,26 @@ def _SwapPositionsInSEL(self, e1, e2): def _IsTopHorz(self, xPos): e = self._SortedEdges while e is not None: - if (xPos >= min(e.xCurr,e.xTop)) and (xPos <= max(e.xCurr,e.xTop)): + if (xPos >= min(e.Curr.x,e.Top.x)) and (xPos <= max(e.Curr.x,e.Top.x)): return False e = e.nextInSEL return True def _ProcessHorizontal(self, horzEdge): - if horzEdge.xCurr < horzEdge.xTop: - horzLeft = horzEdge.xCurr - horzRight = horzEdge.xTop + if horzEdge.Curr.x < horzEdge.Top.x: + horzLeft = horzEdge.Curr.x + horzRight = horzEdge.Top.x direction = Direction.LeftToRight else: - horzLeft = horzEdge.xTop - horzRight = horzEdge.xCurr + horzLeft = horzEdge.Top.x + horzRight = horzEdge.Curr.x direction = Direction.RightToLeft eMaxPair = None if horzEdge.nextInLML is None: eMaxPair = _GetMaximaPair(horzEdge) e = _GetnextInAEL(horzEdge, direction) while e is not None: - if (e.xCurr == horzEdge.xTop) and eMaxPair is None: + if (e.Curr.x == horzEdge.Top.x) and eMaxPair is None: if _SlopesEqual2(e, horzEdge.nextInLML): if horzEdge.outIdx >= 0 and e.outIdx >= 0: self._AddJoin(horzEdge.nextInLML, e, horzEdge.outIdx) @@ -1057,39 +1045,39 @@ def _ProcessHorizontal(self, horzEdge): elif e.dx < horzEdge.nextInLML.dx: break eNext = _GetnextInAEL(e, direction) if eMaxPair is not None or \ - ((direction == Direction.LeftToRight) and (e.xCurr < horzRight)) or \ - ((direction == Direction.RightToLeft) and (e.xCurr > horzLeft)): + ((direction == Direction.LeftToRight) and (e.Curr.x < horzRight)) or \ + ((direction == Direction.RightToLeft) and (e.Curr.x > horzLeft)): if e == eMaxPair: if direction == Direction.LeftToRight: - self._IntersectEdges(horzEdge, e, Point(e.xCurr, horzEdge.yCurr)) + self._IntersectEdges(horzEdge, e, Point(e.Curr.x, horzEdge.Curr.y)) else: - self._IntersectEdges(e, horzEdge, Point(e.xCurr, horzEdge.yCurr)) + self._IntersectEdges(e, horzEdge, Point(e.Curr.x, horzEdge.Curr.y)) return - elif e.dx == horizontal and not _IsMinima(e) and e.xCurr <= e.xTop: + elif e.dx == horizontal and not _IsMinima(e) and e.Curr.x <= e.Top.x: if direction == Direction.LeftToRight: - self._IntersectEdges(horzEdge, e, Point(e.xCurr, horzEdge.yCurr), - _ProtectRight(not self._IsTopHorz(e.xCurr))) + self._IntersectEdges(horzEdge, e, Point(e.Curr.x, horzEdge.Curr.y), + _ProtectRight(not self._IsTopHorz(e.Curr.x))) else: - self._IntersectEdges(e, horzEdge, Point(e.xCurr, horzEdge.yCurr), - _ProtectLeft(not self._IsTopHorz(e.xCurr))) + self._IntersectEdges(e, horzEdge, Point(e.Curr.x, horzEdge.Curr.y), + _ProtectLeft(not self._IsTopHorz(e.Curr.x))) elif (direction == Direction.LeftToRight): - self._IntersectEdges(horzEdge, e, Point(e.xCurr, horzEdge.yCurr), - _ProtectRight(not self._IsTopHorz(e.xCurr))) + self._IntersectEdges(horzEdge, e, Point(e.Curr.x, horzEdge.Curr.y), + _ProtectRight(not self._IsTopHorz(e.Curr.x))) else: - self._IntersectEdges(e, horzEdge, Point(e.xCurr, horzEdge.yCurr), - _ProtectLeft(not self._IsTopHorz(e.xCurr))) + self._IntersectEdges(e, horzEdge, Point(e.Curr.x, horzEdge.Curr.y), + _ProtectLeft(not self._IsTopHorz(e.Curr.x))) self._SwapPositionsInAEL(horzEdge, e) - elif ((direction == Direction.LeftToRight and e.xCurr >= horzRight) or \ - (direction == Direction.RightToLeft and e.xCurr <= horzLeft)): break + elif ((direction == Direction.LeftToRight and e.Curr.x >= horzRight) or \ + (direction == Direction.RightToLeft and e.Curr.x <= horzLeft)): break e = eNext if horzEdge.nextInLML is not None: if horzEdge.outIdx >= 0: - self._AddOutPt(horzEdge, Point(horzEdge.xTop, horzEdge.yTop)) + self._AddOutPt(horzEdge, horzEdge.Top) self._UpdateEdgeIntoAEL(horzEdge) else: if horzEdge.outIdx >= 0: self._IntersectEdges(horzEdge, eMaxPair, \ - Point(horzEdge.xTop, horzEdge.yCurr), Protects.Both) + Point(horzEdge.Top.x, horzEdge.Curr.y), Protects.Both) if eMaxPair.outIdx >= 0: raise Exception("Clipper: Horizontal Error") self._DeleteFromAEL(eMaxPair) self._DeleteFromAEL(horzEdge) @@ -1104,12 +1092,12 @@ def _AddJoin(self, e1, e2, e1OutIdx = -1, e2OutIdx = -1): jr = JoinRec() if e1OutIdx >= 0: jr.poly1Idx = e1OutIdx else: jr.poly1Idx = e1.outIdx - jr.pt1a = Point(e1.xCurr, e1.yCurr) - jr.pt1b = Point(e1.xTop, e1.yTop) + jr.pt1a = e1.Curr + jr.pt1b = e1.Top if e2OutIdx >= 0: jr.poly2Idx = e2OutIdx else: jr.poly2Idx = e2.outIdx - jr.pt2a = Point(e2.xCurr, e2.yCurr) - jr.pt2b = Point(e2.xTop, e2.yTop) + jr.pt2a = e2.Curr + jr.pt2b = e2.Top if self._JoinList is None: self._JoinList = [] self._JoinList.append(jr) @@ -1168,18 +1156,18 @@ def _BuildIntersectList(self, botY, topY): while e is not None: e.prevInSEL = e.prevInAEL e.nextInSEL = e.nextInAEL - e.xCurr = _TopX(e, topY) + e.Curr = Point(_TopX(e, topY), e.Curr.y) e = e.nextInAEL while True: isModified = False e = self._SortedEdges while e.nextInSEL is not None: eNext = e.nextInSEL - if e.xCurr <= eNext.xCurr: + if e.Curr.x <= eNext.Curr.x: e = eNext continue pt, intersected = _IntersectPoint(e, eNext) - if not intersected and e.xCurr > eNext.xCurr +1: + if not intersected and e.Curr.x > eNext.Curr.x +1: raise Exception("Intersect Error") if pt.y > botY: pt = Point(_TopX(e, botY), botY) @@ -1232,10 +1220,10 @@ def _DeleteFromSEL(self, e): def _IntersectEdges(self, e1, e2, pt, protects = Protects.Neither): e1stops = protects & Protects.Left == 0 and \ e1.nextInLML is None and \ - e1.xTop == pt.x and e1.yTop == pt.y + e1.Top.x == pt.x and e1.Top.y == pt.y e2stops = protects & Protects.Right == 0 and \ e2.nextInLML is None and \ - e2.xTop == pt.x and e2.yTop == pt.y + e2.Top.x == pt.x and e2.Top.y == pt.y e1Contributing = e1.outIdx >= 0 e2contributing = e2.outIdx >= 0 @@ -1338,7 +1326,7 @@ def _IntersectEdges(self, e1, e2, pt, protects = Protects.Neither): def _DoMaxima(self, e, topY): eMaxPair = _GetMaximaPair(e) - x = e.xTop + x = e.Top.x eNext = e.nextInAEL while eNext != eMaxPair: if eNext is None: raise Exception("DoMaxima error") @@ -1373,7 +1361,7 @@ def _UpdateEdgeIntoAEL(self, e): e.prevInAEL = aelPrev e.nextInAEL = aelNext if e.dx != horizontal: - self._InsertScanbeam(e.yTop) + self._InsertScanbeam(e.Top.y) return e def _AddLocalMinPoly(self, e1, e2, pt): @@ -1541,15 +1529,12 @@ def _ProcessEdgesAtTopOfScanbeam(self, topY): intermediateVert = _IsIntermediate(e, topY) if intermediateVert and e.nextInLML.dx == horizontal: if e.outIdx >= 0: - self._AddOutPt(e, Point(e.xTop, e.yTop)) + self._AddOutPt(e, e.Top) hj = self._HorzJoins if hj is not None: while True: _1, _2, overlap = _GetOverlapSegment( - Point(hj.edge.xBot, hj.edge.yBot), - Point(hj.edge.xTop, hj.edge.yTop), - Point(e.nextInLML.XBot, e.nextInLML.yBot), - Point(e.nextInLML.xTop, e.nextInLML.yTop)) + hj.edge.Bot, hj.edge.Top, e.nextInLML.Bot, e.nextInLML.Top) if overlap: self._AddJoin(hj.edge, e.nextInLML, hj.savedIdx, e.outIdx) hj = hj.nextHj if hj == self._HorzJoins: break @@ -1558,15 +1543,14 @@ def _ProcessEdgesAtTopOfScanbeam(self, topY): e = self._UpdateEdgeIntoAEL(e) self._AddEdgeToSEL(e) else: - e.xCurr = _TopX(e, topY) - e.yCurr = topY + e.Curr = Point(_TopX(e, topY), topY) if (self.ForceSimple and e.prevInAEL is not None and - e.prevInAEL.xCurr == e.xCurr and + e.prevInAEL.Curr.x == e.Curr.x and e.outIdx >= 0 and e.prevInAEL.outIdx >= 0): if (intermediateVert): - self._AddOutPt(e.prevInAEL, Point(e.xCurr, topY)); + self._AddOutPt(e.prevInAEL, Point(e.Curr.x, topY)); else: - self._AddOutPt(e, Point(e.xCurr, topY)) + self._AddOutPt(e, Point(e.Curr.x, topY)) e = e.nextInAEL self._ProcessHorizontals() @@ -1575,22 +1559,22 @@ def _ProcessEdgesAtTopOfScanbeam(self, topY): while e is not None: if _IsIntermediate(e, topY): if (e.outIdx >= 0) : - self._AddOutPt(e, Point(e.xTop, e.yTop)) + self._AddOutPt(e, e.Top) e = self._UpdateEdgeIntoAEL(e) ePrev = e.prevInAEL eNext = e.nextInAEL - if ePrev is not None and ePrev.xCurr == e.xBot and \ - (ePrev.yCurr == e.yBot) and (e.outIdx >= 0) and \ - (ePrev.outIdx >= 0) and (ePrev.yCurr > ePrev.yTop) and \ + if ePrev is not None and ePrev.Curr.x == e.Bot.x and \ + (ePrev.Curr.y == e.Bot.y) and (e.outIdx >= 0) and \ + (ePrev.outIdx >= 0) and (ePrev.Curr.y > ePrev.Top.y) and \ _SlopesEqual2(e, ePrev): - self._AddOutPt(ePrev, Point(e.xBot, e.yBot)) + self._AddOutPt(ePrev, e.Bot) self._AddJoin(e, ePrev) - elif eNext is not None and (eNext.xCurr == e.xBot) and \ - (eNext.yCurr == e.yBot) and (e.outIdx >= 0) and \ - (eNext.outIdx >= 0) and (eNext.yCurr > eNext.yTop) and \ + elif eNext is not None and (eNext.Curr.x == e.Bot.x) and \ + (eNext.Curr.y == e.Bot.y) and (e.outIdx >= 0) and \ + (eNext.outIdx >= 0) and (eNext.Curr.y > eNext.Top.y) and \ _SlopesEqual2(e, eNext): - self._AddOutPt(eNext, Point(e.xBot, e.yBot)) + self._AddOutPt(eNext, e.Bot) self._AddJoin(e, eNext) e = e.nextInAEL @@ -1713,7 +1697,7 @@ def _JoinCommonEdges(self): _FixupOutPolygon(outRec1) _FixupOutPolygon(outRec2) - if outRec2.isHole == self._Area(outRec2) > 0.0: + if (outRec2.isHole ^ self.ReverseSolution) == self._Area(outRec2) > 0.0: _ReversePolyPtLinks(outRec2.pts) elif _Poly2ContainsPoly1(outRec1.pts, outRec2.pts): @@ -1729,7 +1713,7 @@ def _JoinCommonEdges(self): _FixupOutPolygon(outRec1) _FixupOutPolygon(outRec2) - if outRec1.isHole == self._Area(outRec1) > 0.0: + if (outRec1.isHole ^ self.ReverseSolution) == self._Area(outRec1) > 0.0: _ReversePolyPtLinks(outRec1.pts) else: outRec2.isHole = outRec1.isHole @@ -1799,7 +1783,7 @@ def _DoSimplePolygons(self): return def _ExecuteInternal(self): - try: +# try: try: self._Reset() if self._Scanbeam is None: return True @@ -1818,7 +1802,7 @@ def _ExecuteInternal(self): if outRec.pts is None: continue _FixupOutPolygon(outRec) if outRec.pts is None: continue - if outRec.isHole == (self._Area(outRec.pts) > 0.0): + if ((outRec.isHole ^ self.ReverseSolution) == (self._Area(outRec.pts) > 0.0)): _ReversePolyPtLinks(outRec.pts) if self._JoinList is not None: self._JoinCommonEdges() @@ -1828,8 +1812,8 @@ def _ExecuteInternal(self): finally: self._JoinList = None self._HorzJoins = None - except: - return False +# except: +# return False def Execute( self, @@ -1881,7 +1865,7 @@ def _BuildResult(self, polygons): poly = [] op = outRec.pts for _ in range(cnt): - poly.append(Point(op.pt.x, op.pt.y)) + poly.append(op.pt) op = op.prevOp polygons.append(poly) return @@ -1915,39 +1899,16 @@ def _BuildResult2(self, polyTree): # OffsetPolygons (+ ancilliary functions) #=============================================================================== -FloatPoint = namedtuple('FloatPoint', 'x y') -Rect = namedtuple('FloatPoint', 'left top right bottom') - def _GetUnitNormal(pt1, pt2): if pt2.x == pt1.x and pt2.y == pt1.y: return FloatPoint(0.0, 0.0) - dx = pt2.x - pt1.x - dy = pt2.y - pt1.y + dx = float(pt2.x - pt1.x) + dy = float(pt2.y - pt1.y) f = 1.0 / math.hypot(dx, dy) dx = float(dx) * f dy = float(dy) * f return FloatPoint(dy, -dx) -def _BuildArc(pt, a1, a2, r, limit): - arcFrac = abs(a2 - a1) / (2 * math.pi); - steps = int(arcFrac * math.pi / math.acos(1 - limit / abs(r))) - if steps < 2: steps = 2 - elif steps > 222.0 * arcFrac: - steps = int(222.0 * arcFrac) - - result = [] - y = math.sin(a1) - x = math.cos(a1) - s = math.sin((a2-a1)/steps) - c = math.cos((a2-a1)/steps) - for _ in range(steps+1): - result.append(FloatPoint(pt.x + round(x * r), pt.y + round(y * r))) - x2 = x - x = x * c - s * y # cross product & dot product here ... - y = x2 * s + y * c # avoids repeat calls to the much slower sin() & cos() - - return result - def _GetBounds(pts): left = None for poly in pts: @@ -1989,74 +1950,79 @@ def _StripDupPts(poly): def _OffsetInternal(polys, isPolygon, delta, jointype = JoinType.Square, endtype = EndType.Square, limit = 0.0): def _DoSquare(pt): - pt1 = Point(round(pt.x + Normals[k].x * delta), round(pt.y + Normals[k].y * delta)) - pt2 = Point(round(pt.x + Normals[j].x * delta), round(pt.y + Normals[j].y * delta)) - if (Normals[k].x*Normals[j].y-Normals[j].x*Normals[k].y) * delta >= 0: - a1 = math.atan2(Normals[k].y, Normals[k].x) - a2 = math.atan2(-Normals[j].y, -Normals[j].x) - a1 = abs(a2 - a1); - if a1 > math.pi: a1 = math.pi * 2 - a1 - dx = math.tan((math.pi - a1)/4) * abs(delta) - - pt1 = Point(round(pt1.x -Normals[k].y * dx), round(pt1.y + Normals[k].x * dx)) - result.append(pt1) - pt2 = Point(round(pt2.x + Normals[j].y * dx), round(pt2.y - Normals[j].x * dx)) - result.append(pt2) - else: - result.append(pt1) - result.append(pt) - result.append(pt2) + # see offset_triginometry.svg in the documentation folder ... + dx = math.tan(math.atan2(sinA, + Normals[k].x * Normals[j].x + Normals[k].y * Normals[j].y)/4) + result.append(Point( + round(pt.x + delta * (Normals[k].x - Normals[k].y *dx)), + round(pt.y + delta * (Normals[k].y + Normals[k].x *dx)))) + result.append(Point( + round(pt.x + delta * (Normals[j].x + Normals[j].y *dx)), + round(pt.y + delta * (Normals[j].y - Normals[j].x *dx)))) + return def _DoMiter(pt, r): - if ((Normals[k].x* Normals[j].y - Normals[j].x * Normals[k].y) * delta >= 0): - q = delta / r; - result.append(Point(round(pt.x + (Normals[k].x + Normals[j].x) *q), - round(pt.y + (Normals[k].y + Normals[j].y) *q))) - else: - pt1 = Point(round(pt.x + Normals[k].x * delta), \ - round(pt.y + Normals[k].y * delta)) - pt2 = Point(round(pt.x + Normals[j].x * delta), \ - round(pt.y + Normals[j].y * delta)) - result.append(pt1) - result.append(pt) - result.append(pt2) - - def _DoRound(pt, limit): - pt1 = Point(round(pt.x + Normals[k].x * delta), \ - round(pt.y + Normals[k].y * delta)) - pt2 = Point(round(pt.x + Normals[j].x * delta), \ - round(pt.y + Normals[j].y * delta)) - result.append(pt1) - if (Normals[k].x * Normals[j].y - Normals[j].x * Normals[k].y) *delta >= 0: - if (Normals[j].x * Normals[k].x + Normals[j].y * Normals[k].y) < 0.985: - a1 = math.atan2(Normals[k].y, Normals[k].x) - a2 = math.atan2(Normals[j].y, Normals[j].x) - if (delta > 0) and (a2 < a1): a2 = a2 + math.pi * 2 - elif (delta < 0) and (a2 > a1): a2 = a2 - math.pi * 2 - arc = _BuildArc(pt, a1, a2, delta, limit) - result.extend(arc) - else: - result.append(pt) - result.append(pt2) - - def _OffsetPoint(jointype, limit): - if jointype == JoinType.Miter: + q = delta / r + result.append(Point( + round(pt.x + (Normals[k].x + Normals[j].x) * q), + round(pt.y + (Normals[k].y + Normals[j].y) * q))) + return + + + def _DoRound(pt): + a = math.atan2(sinA, + Normals[k].x * Normals[j].x + Normals[k].y * Normals[j].y) + steps = round(step360 * abs(a)); + X,Y = Normals[k].x, Normals[k].y + for _ in range(steps): + result.append(Point( + round(pt.x + X * delta), round(pt.y + Y * delta))) + X2 = X + X = X * mcos - msin * Y + Y = X2 * msin + Y * mcos + result.append(Point(round(pt.x + Normals[j].x * delta), + round(pt.y + Normals[j].y * delta))); + return + + def GetSin(): + result = (Normals[k].x * Normals[j].y - Normals[j].x * Normals[k].y) + if (result > 1.0): result = 1.0 + elif (result < -1.0): result = -1.0 + return result + + def _OffsetPoint(jointype): + if (sinA * delta < 0): + result.append(Point(round(pts[j].x + Normals[k].x * delta), + round(pts[j].y + Normals[k].y * delta))) + result.append(pts[j]) + result.append(Point(round(pts[j].x + Normals[j].x * delta), + round(pts[j].y + Normals[j].y * delta))) + elif jointype == JoinType.Miter: r = 1.0 + (Normals[j].x * Normals[k].x + Normals[j].y * Normals[k].y) - if (r >= rmin): _DoMiter(pts[j], r) + if (r >= miterLim): _DoMiter(pts[j], r) else: _DoSquare(pts[j]) elif jointype == JoinType.Square: _DoSquare(pts[j]) - else: _DoRound(pts[j], limit) + else: _DoRound(pts[j]) return j if delta == 0: return polys - rmin = 0.5 - if (jointype == JoinType.Miter): - if (limit > 2): - rmin = 2.0 / (limit * limit) - limit = 0.25; #just in case endtype == EndType.Round - else: - if (limit <= 0): limit = 0.25 - elif (limit > abs(delta)): limit = abs(delta) + if not isPolygon and delta < 0: delta = -delta + + if jointype == JoinType.Miter: + # miterLim: see offset_triginometry3.svg in the documentation folder ... + if limit > 2: miterLim = 2 / (limit * limit) + else: miterLim = 0.5 + if endtype == EndType.Round: limit = 0.25 + + if jointype == JoinType.Round or endtype == EndType.Round: + if limit <= 0: limit = 0.25 + elif limit > abs(delta)*0.25: limit = abs(delta)*0.25 + # step360: see offset_triginometry2.svg in the documentation folder ... + step360 = math.pi / math.acos(1 - limit / abs(delta)) + msin = math.sin(2 * math.pi / step360) + mcos = math.cos(2 * math.pi / step360) + step360 /= math.pi * 2 + if delta < 0: msin = -msin res = [] ppts = polys[:] @@ -2066,8 +2032,24 @@ def _OffsetPoint(jointype, limit): cnt = len(pts) if (cnt == 0 or cnt < 3 and delta <= 0): continue - elif (cnt == 1): - res.append(_BuildArc(pts[0], 0, 2 * math.pi, delta, limit)) + + if (cnt == 1): + if jointype == JoinType.Round: + X,Y = 1.0, 0.0 + for _ in range(round(step360 * 2 * math.pi)): + result.append(Point(round(pts[0].x + X * delta), + round(pts[0].y + Y * delta))) + X2 = X + X = X * mcos - msin * Y + Y = X2 * msin + Y * mcos + else: + X,Y = -1.0, -1.0 + for _ in range(4): + result.append(Point(round(pts[0].x + X * delta), + round(pts[0].y + Y * delta))) + if X < 0: X = 1 + elif Y < 0: Y = 1 + else: X = -1 continue forceClose = _PointsEqual(pts[0], pts[cnt - 1]) @@ -2084,7 +2066,8 @@ def _OffsetPoint(jointype, limit): if (isPolygon or forceClose): k = cnt - 1 for j in range(cnt): - k = _OffsetPoint(jointype, limit) + sinA = GetSin() + k = _OffsetPoint(jointype) res.append(result) if not isPolygon: @@ -2092,7 +2075,8 @@ def _OffsetPoint(jointype, limit): delta = -delta k = cnt - 1 for j in range(cnt): - k = _OffsetPoint(jointype, limit) + sinA = GetSin() + k = _OffsetPoint(jointype) delta = -delta res.append(result[::-1]) @@ -2100,7 +2084,8 @@ def _OffsetPoint(jointype, limit): # offset the polyline going forward ... k = 0; for j in range(1, cnt-1): - k = _OffsetPoint(jointype, limit) + sinA = GetSin() + k = _OffsetPoint(jointype) # handle the end (butt, round or square) ... if (endtype == EndType.Butt): @@ -2114,19 +2099,20 @@ def _OffsetPoint(jointype, limit): else: j = cnt - 1; k = cnt - 2; - Normals[j] = DoublePoint(-Normals[j].x, -Normals[j].y) + Normals[j] = FloatPoint(-Normals[j].x, -Normals[j].y) if (endtype == EndType.Square): _DoSquare(pts[j]) - else: _DoRound(pts[j], limit) + else: _DoRound(pts[j]) # re-build Normals ... for j in range(cnt -1, 0, -1): - Normals[j] = DoublePoint(-Normals[j -1].x, -Normals[j -1].y) - Normals[0] = DoublePoint(-Normals[1].x, -Normals[1].y) + Normals[j] = FloatPoint(-Normals[j -1].x, -Normals[j -1].y) + Normals[0] = FloatPoint(-Normals[1].x, -Normals[1].y) # offset the polyline going backward ... k = cnt -1; for j in range(cnt -2, 0, -1): - k = _OffsetPoint(jointype, limit) + sinA = GetSin() + k = _OffsetPoint(jointype) # finally handle the start (butt, round or square) ... if (endtype == EndType.Butt): @@ -2140,7 +2126,7 @@ def _OffsetPoint(jointype, limit): j = 0 k = 1 if (endtype == EndType.Square): _DoSquare(pts[0]) - else: _DoRound(pts[0], limit) + else: _DoRound(pts[0]) res.append(result) @@ -2156,10 +2142,9 @@ def _OffsetPoint(jointype, limit): outer.append(Point(bounds.right+10, bounds.top-10)) outer.append(Point(bounds.left-10, bounds.top-10)) c.AddPolygon(outer, PolyType.Subject) + c.ReverseSolution = True c.Execute(ClipType.Union, res, PolyFillType.Negative, PolyFillType.Negative) if len(res) > 0: res.pop(0) - for poly in res: - poly = poly[::-1] return res def OffsetPolygons(polys, delta, jointype = JoinType.Square, limit = 0.0, autoFix = True): @@ -2207,9 +2192,9 @@ def _ClosestPointOnLine(pt, linePt1, linePt2): dx = linePt2.x - linePt1.x dy = linePt2.y - linePt1.y if (dx == 0 and dy == 0): - return DoublePoint(linePt1.x, linePt1.y) + return FloatPoint(linePt1.x, linePt1.y) q = ((pt.x-linePt1.x)*dx + (pt.Y-linePt1.Y)*dy) / (dx*dx + dy*dy) - return DoublePoint( + return FloatPoint( (1-q)*linePt1.X + q*linePt2.X, (1-q)*linePt1.Y + q*linePt2.Y)

    atjwWD3dqis~#>x8NoCi+HH<}xKa1pi%h9@XKW3_Al0`vNga3wGk5o8`ObQFXH^@18~A1m84uBBBj+#4_7ZU=J!Eax!>?ne-|xkudd< zbQ9&sQSkEWYACoEU-Dsdve*8Dk#h>6?_g6O*6J{E6VI=oA2qAKa1&=sBDE210)gintSzSy~Hz zutxYx9)Iti;9VF3E2U!8fKIq_eAzynCEz(-T6jM!?VNfc%h@iCQTeed@d0l_=(2R7 zdbXZP^|m$a1g+vB`S3zXm--Sd==*xYa02$4$OYfX9%xJ>6}6`X)aMz^@}HKkmJCKLY2S z&#Qdg*;u$L>#9BWAJq)W5ts>9qz-TuP8rP4!Twr*bU|xgiE%4SH$|#7gocp_Ohqe9 zDZNEsXqp?f@Y#d~IVuR?R(Uxq8vhNRsr-bG_~FvHY>4t7df|1@yH0=Y!P`qEnCXdC z&PtZrbCqdzofGwOBYuRfTIweR_SLg^>l95!!V_n1?M}MIg}B#zBax9-*HSwP6lfsp zB~ktAqT&#ePcamdjw`HM&R89WG!RRX9T1)la}|v$-AbcD5lISB6y?SCrId>XPDKj} zF*IwPP0v3h7rnEgwOH~LC=czf;(uX(Ow}gJ%HIyg5{6d&m_aram2A_7c255cqik;c z9_6u+hmnz|FOe7aK*?O|&%KTIe8(XjU5~P#R+!tU>6YHn-2oA9XNS4BGeI zYhfzn^s%T}Z(;+@jN{%Tl|ssu2@tAErKzA}Gu3DBBiS6JP>UPN z&30;~e3>b~h!M#OZ%Q*_THJawqGtIt$Ssq67^LJ-owl`={uFZDQhyZRMV$=7e>LmQ zBQ%r%{OY(|gk(SAmRegQ>BPQ^2jou7uxE=dkm{meiI8y`AaLroa;+lCt2kMy zukF~|1OhVxrsQlQ$@+crVB8n#OPAchQwT%eliZ?eF2@TrZI9j-%R$gFzJ9P`M$e~}Vn>^sq01g7QDB5vf z>QWH&#FI;y39-xZaZj`UgT&HL)Tu$(!?C+EIeGvjB%G*v|3Clc-dJ5ko>8ge=t9pY zPvQU~LlH@wf{MTnKrL|(fQR7=k6{>LZ6`%>N~+hTw0O2A;3&1`IK zX{Q?MCQszT=WlZ3NR2Dj4AtSeO_9}D;(i~EO=W9``pvJQPA#J39&WTpSTmuk`j|Lj zXAradm4$XGer6v_v8*ULE{rpBo)7ocRMYn5!y{*+I2?rx^b%ZgJ=F)|{{+oDS8l@AUb&6l8xrSFJ1;TL*&DT4(#jls7jh6B@U`#1whyn(IP)L zFf^>{3=I~fTdwLYfq#n~Y5(y62QFGgbC9{^cqTOl^lo>IX{m(U%T?1-j2(jt{1q$o zkvb;Mmu6-bM+bT$0^YZ834fIo^*DF<=XChkMy6Y)jkF$$K3k9;ny%=zL&Glez7CFG zvKoV+?JWbPAPm!*aLF@uU z;(VBaFR}lYfIy(!mA55dNr)&K3^71_F+A@EcGiiCoo2??GX<4)F~WrTB3$&kz5 z!=*N?a=Og=)f2DTHg3~R$`VBYNLxUD(;{AFd*o6VlPy~}>nN7pg8GNi!8=-#@({Ce? z1dzc#^V0Q?T6kmA)02+ZIYs+{Br=;^OM6EhY3Zh>oTkrZJ|-T(6IBxlX97+_W)L)H z-$*dA_LaxO+=uTuQ^TEPPCT=)EW?mhDFdzSj&{|RlQZ>?(9QWFt+AJ*`a0naM@m&U z9;2+>FdfG7s==V`0q__h4a1(amivzC{m7RnD~s?cZ+txawd?QA_u{wY%(2FS$Ab3v zae{PF=&pTh&(cE*WKOlUAIJ9l;^ND{u$tfrxH&pbSDS!X?#Oi{8_WS-b{^Q*rsKmU zMPW~GDYjB6ZEYtcY#lUf7=n4cpk5=VbFIY0{=CLK(7t(}Y{@W)+|1kjez++Q>wCiP zn?Ij}Is$B>d3=%Ikd)JZ^sM|5l>7}x4j1ttf2{ab^rd82_#fwO_jSm0U+;}Hr_9r%9inu2|+nJv1YdW%Fr7mMo?=|5h8ncF3%YP&r@BIvk%n7|wr*WBre?KrFu(ipIu-vlLY*i}!$xtK zQd0j^##^X{u+R4c{U)-XGh@9rNbJeeCn4EH#qUp!=>z=mKWUNe29Wbn&MbR1QE<_4 zF>#u4rCVps6*Zq`=C5$ex9&B)N?P-8kyjHVLLULBcabYgi;GqoHfVTpuPq)T;1A4L z2R>u<7P7v%CKTORE||zTIGo?nY`#1LGJ1!zzwC_j7|T z?j2`1wQK&z`F``93A>p5^aXalOU4GMt@`Nk$vtwd|BJlO%63Gru*f`FF;yRtwdNsv8$JI}o$waVdFjP?_bF>w{)e;^TkVk#dEAtOE(s5k zUnDs%QklB3qvv_=nI`FJ$7PWrrxyju{WahdD4)PjD(X3K>gYbH2q_#;KN9{A1RydP;>uxG3-aGwCy!SDW2neeJa*2_F3oRmC>Syaq!GRQ z1a18eDlobS-rP8hHXlroDRtOqrH;U5i~60b`?GQYv~`YAxtpRxcP92-~)l_f#s-g+?c_>K&Y2MyxUKD z&%ySX2dDc_!pur|>JI4p-$~JqCO7Xhe59Km&ys6g`jqTk$ zuh*z^2>T65tpQd8PsY`ikkMMn;Q{>g)#pG@LWS<`z<~PLpo;0-Uhj0&8Sh3XIRyFh z&#kv_vZXEAkbP8i3PYj8h&m|5=$s5t^-H%3(&c$cfN}K|BbWFPpDfi~x`T|yaUgXe zcU+&_c6`ckkK^aMxfP(TZrBnjvK=58P-LIc%9&nlVpb6#*#1Nn1Qfggyqu%e6$t#I z`xxH%k}v)7v}hd0!tiZWuW{MUWu#MlD6|wbxE?Pnev%a&rWJ6 zaI67%*-?$!!QZON6W3}1x7T(uig(e{8YY~85IZWiDj+C2*?>P2d@DJfWOef z7hDk=G7foMZ0iDeuo{Q!~=>I)E2TtaD;nVE< zhv=D~v4S4t5!93YT3y2_6q`cGiP^w)tNyxIVw;f>RoDcOG(ERdNHO z;(Y3N_$vR`>~dEgpym7cwFSF!++fjs42XRf(XYkKtIyJho9(x~GLgIQ?b)5ZQcRrI zWK`djQ8A>D6vh?HORWDV8t-EA6FX+VHs7~PxR7Wv9;!GWmX3b^EQMnt)UTaW44-Fa zE_72nF);|M_ zfpUn5O$ThdlV8W>u3t4~)jHCvXN1;sF=-XpN@HpwxL?-UGZ_Y$UM~c0O;dBK=rHVa zm{^R13YpOQbB3FS)EoaKx`?lpILQ0h2!jzC1qIy>l~wJc%^b9J-R#@lM?5MT92~6l z`f%gwDQv5shcTXYohk)BTC{*CLf??ur<#ZJ#gZ4x2Kv4mfOjSY#0ulVzrCOi;&crm zrv6+5=qwL3JEYy60d9_RQ$(5+i1t1o6vf|AHJ2*6pbLA|I>Cp6N2W0LZE&Bn42C*Y^ybG+4~mZLu7nViW@z{<5vy2cb>;1L z-^ZfY)mg0+K68?}@zaJT>UOf+7NsP{fK8(b_oe}&r`xm3va4EX^KfZVOiU&DT5javp5`z`#z5W-NW@t2Lp(lx{)~D;k(v-M zoZgP3HVz*SDqfv7AXqTL;8DW`{njn~oC$ua(;s`=NsmDhC$P|=l zSy2M^|0!&ap@*9Qsz?v`K2J_QJ3yDP!%GKOdul6-HBj-l|JLA|_CQ~MS~6Z^rv6Pc zoBUf2$De_|;cD!pYW?LO(5HgTSzU@(CyutC3(qlu;2)a$(R@mlVuV=HOAH5DJYF7~h@RX9Yd?%yfsAu=C2tTV z06zp`we!)WrPEzgUDdXV7i%(=&N|&WE{p#rWjvmX|L-UcRTXY+ZE0p@2qQ?{aZ>1z zymU%#X#4f-!JMP?B@yE9TS2u zMHNaPlZqy;vnCR=3~KQi!TE2m9lB?NhH@c1z4-0-(%Zj6EIb7r&modE?)lPze(j1M z;eeMs+ciD6->U`#0*h#PB~&rQecsTCilyWqo#(D5D^NiJved$dv%Q4#JdCMO5K zM2G?q`KO`jm%DKXRpAYk;I+6#*14oFI!JsTmC)-pw-K*$YVS{~<|YKz1HoT=5wePJ zNp^|8tQuNOZ2XGLI8qc{@<$39Qr%_B{QCV-{0u#X>n7+nD1jeFKFqEFK5Ft2rM>EU zpE(Y=iO#rB|7T2cQKP1t=_nyg9gwWhQOmThyeYE%80#VyrRcOyLXz&n^zK5Xh|$10 zRa4v3DXFVCXQy0JnzKpZ1YVWY&E96LX)4PIJgPUfWN*iWOj6=X=^%sn)j#0)%i+7g z0JHBxgfdfm$WDeKp~=2uivK}SogYpxC`31j)=w%mN`g>LdGKOp>Sboc@E46>6Jj0i z4@Pz!k&b3v(hrTaG!yV_YXyG`^m#L#`9<2P+@3u%>ORt0750k^NnWdJ{iH%?%XU za*jhv1J92i?38MobI+Ziz>*|Du!R22pZ2SK)LsF=m$_PMhl1r1HVFPV!iN&d?a1}( z+SZ+3IkqjPhJNBFmg9RD)yo%dd12(xYd?f1Xn>Iy6K)Bw18g3}A{)c`vM|z~jHAQ< zu^;vgWgmWkyem=JN{P$~>%eHAO;=Tuv3|E zE^Lm4;c(Ov#J`5F6dld}VN-lUj+!dwHXit95xwm6KgtY%y)C-4MDH|13f6vF?#>!L z5RyZ9Vn13@H0;(|ivLzt9Qs;gFH~>y(bodzu z{O?*{w4L(4Q`920vL9dF>q)j_y!>~dJgq0N;Kc^Hc{D+>ewuDHCBXj?Mo7d02hH_^ z9h>N)-CnJIgIr%q)zMs163F>DiU|5}M(fE&Fg(ZLRwoS*Cd!i1OE#Tu`aE*_=aQ@f z9P#L}EQ6d!0e7-Z{Cg}0Hh*gkK-!KSh^e;ZWN{pv-HwXR0K&bRR1$**3*A`cF4u!) z#+<^?5D@jlp-t&&hnp2Ll}VCp~&1g?e)7I364Rl%N8S^pb)51 zM@c-BZS4)O3+tmt+L2#=H?Qj2+7!r>FWxwu=SS|gXBbtcu_Uq! z(Kee>txtjg3;!;E?0OU`-W{OdP;=>L&6DJl30$k+ATJFO{0;KB%4fMIE|Q>_+Uy3+ zu)UK$r;J~tl*bBJw}Alc)cpO75FLa~JcyYLw%`0!DRuuUH8NsWHjmbM%b5*q!NASH z&%!rYmcy-pP)%@s6dd*l;?23yV&Yq3hfbtRem=I23JSo{begk&rQ3zCg2g z>o=-=(12RN;D1bjse;F;!K0lt@Lt+|`ag4t+-+*#7`O`3JyCz#S%*y;VyEvy9&B4e zHdyRyW8L6OFJv_I4NebNysY6r;al`!1Oz70`-U70PtI@999gX#RcIGo0`zGI+|v8p z&9kqzAj4A(c~i0}OxuzXCJM?ObGyBq;0<6G{sK+_tpv_QXDnL!)qd{;gGbEnDW*TX z($P>OMo^T$j2w0F0XlGAOtXw%V`_xjm9C^=88j`ev;O2%Dr%3>0Z#q@dw_~aR1sYr zejwcFPUgG8fT>#Sx94K7)QZ^8yO|mRp0>@2)tkjhF-SqsbO5W>ag<$UGl!R#KegM^ z0AL|&cwg!Gjpw`9A&oOJzNqc;B=>1JJMo^^=z|Y-t9v_VzJiZVai6c@^^lL|nJi)* zD`ik$IQ>I5=~+d5p>o+oE3JiMl=^?>e?)$uDhx4F{}??!J!466{z-rkhu1JZ1C))& z)m=k-&5vPC{87E2!%7K4@Hp|WF&z&OIT8-cOqGkL%w84F^#8j(jTScWGT9JB?$&Ls zhbAZMERJHvSUwKdTEB|;DFT`q=43W5SXZA{e zv+=W3;B#-(%jZ(9MCbR8Gwu_IVC2pZ#Q(}?B<|{J3MtoXi+0sQ+SxUfG)qa!4Ac^{ zHH*AJWAKH7ZxNmvrLCs#5)7C52dLq#FhaQ*I=Ww0sga_g%a+&c>pQf03;wwkf`jGs z2)oGL>*ev0xUk^np5>cqXqxD#7Vyn}s0VpffW~TZZ8L`7gq!so_mBa%xDAWD*}WXg zmVjrIBqwN=plgoO*&^6D?R{$oTy{c|Ykvx@CQ~i)_m1E3qs{R*)__Da$FIgOLH~Vn zg$oSKDZi9zvXy7U__5tjhrlLOI5`_lo5-B(GN_7+pS4iRsHhxLV;syhY-+ykni+RH zo`?-|jvV&x``L&Qpdd~4oxHYRG^4zrt++ZVLZzdY4rbwm4`Vo@r9x#;Ik1$?^}Y|o zmU`wNR5y~ux(l%{I>8Wi{{P4=HAlE<>}S+_gSS>pN_5i=&BS|#%v zIHR+;FtBoEX`cU{>e#3Ie2xt2{aZlg_2dF#LXae~=Fuqd6)n|LrnXXk+H$gj(vqh| zt<8k;Ii9eEiK>VodOe3q-8UQjpACQ7a&up)PE!Tk>aQz@i>UnQf;$+4 zekOijH+frQ!S>9O?1!7g{`amb>3f<*a_^f`>-yG9pnVl==$2?`)UaS_-3Zpz#viu{ zUk*JRl6VNC3F*_%KBg}c%1~tbcE?n{T_4oFGRcj3t_^BRDXRrJ&g?2_bsono{lKk%Cw)m@u4thZ^?sRJF9y2#632G zQO6Nr!fGIGj$}a1oc>b4?Ch^u$!t2u`OOOHEhN=Y``~>AWe2=_Bi-gE_IQ@nc_I#~ z!PR8=Wb?KLo&J{E^~-qTz3LtQvUUHKz0#~ME-Bw{Sp;`;nOXn)?@7Q`av`;q?z0lM zjniwzg3tpA84Z5cB*e#zo6sUUK?J%8Xfh`5zT=^@*e~s z!F}MxySrJQUl(^H6Q-enfS*;TAX%Q{e|Bgm31|EGzj%Ve-bckJ34uRDk^ky|cdgmM zU||BZuWuwpRQW)HCYs77F5_-D$O_N){GUGBt;xIXE_}<%@wY~X$lc#6+vktz7IOYI zR$1}K_&VMu^YZCLFsbzUadP@XQMYgQd|=~02oG(5?~4`X1H+@E;^vdvaFa*wG&z47 z#mxbRQ+l7zy`57{@mBg{I)BUNy|4P?@xz981ySv|)SoCz;G8Akzp1M`l5sI&(iHX& z**Ko??*~IysAj&6X#<{ksa=VX6#EdWa(v_W6Y?hfl#h02@3V6Ivj!s%C?ax%EW$D6 z`~ZCa3=C-+PPPAg3MT&Vj<3+&q#FP%^B3Ge`G24h@QsmlMV<<$AsElOu+ z>;jC;$>o(V_=%Qm5MJ9^Gg|__h`Fcg!|I0u|8w42IIPdF4dvY+=<&x`-;9VfL!{C|4$aiGYuGsdvYpA%Wi*lbtW=^Q4)3JWFr}hla|D!XcDSc^x=s$)$U<&PN z88+;DgSovE^uychUp-+t+{j7in%Z_kb1Gh0i47s1C2*DmnI(Q_GlHu>aFIMW+qk zH7UPBZ=ZxZuhXxjm0s)7j63~*ER52A`vD#YPJ1DLoAI`2vg`|IUb8no+;hZlZ$wdR z_o2<)j@~Rq)}(R&L0|t2pVG>#hlZWj)U)*`Zsz0a9q6gX_pVt%w6kdxGfg6`h+3hHBC!rVNOwq?!C^b;?~b3(f?w7!6=T-NeimZQ=6X0 zh6xDH&B zhg&WyuVuUG-EigX4WMMwTlRAo%kINy^bcMBIdu6=qVLu5^{<)2I!Ys4M=j zF0`c#fQx)Q`idhW}oy>3TBfEtvDT;<_ z@0?Eyw|g+T$vR@YzMI1*hrcqY4HQu>{YSkH)c2P7A8mZtQ+o2|;g4O5a)0Vgy@-c$ zUXc$~4$`VmR=TU@P)!}v*GL?<%7M>kt%2&f)m2yesu7h>u}qfVyS3VlNs5}(%UbEf&O)tBB-bgpUXHN7k|B6!i2SqpE^fQ z$Qz^Q)*BwOMTYrWgYcHfbN(foPMaI)In8DxUTE>V$)tY?bxj|d!!0Z(#SN=M*CTp2 zv%f}$jt{;taQ4}9&00LSVv_oouvbFu>&G4h(2IW^+Bv@DGPo(U8zyw*78yT}{)VN4 zwM2@K@Ak`1I4N`ft#9@l2wtlhuU1)R^xjRg8P2~l-!Jh4xZAmuqf-s%rq@*s@*`Xg z?H?MbaQJ*+qThO4=ox7m%H7I-w-EO|-1T!)|6l@6BFEu-P?wOn;j;mEej7v&4U^A1 z=N|!Q(%UQ8wNcwxw72)}w>Z8>{uy)}^j^hUR?pGZQsG;pi+i=Nf%f7T2g{z7{Xyzb zX;OtpRV-us?&`Tj1T}V|+n#zJhDi5dRkl58GM_>)d|Ji#;^= z9++@47=vlkilOv<4QZYUd+VmWW?o6dcQBd_c-6Bo4smf^ok!l&w<>W>rcAQfpXJ$# zV6*W8sQ%gPKs-(#l>_TCyvF0}v!5<0I}6JgB;6VX2YOHYfjY(2B%cUnwxc#Hj8@21 zVYQCe#_L(`By0{z#%I!SYvm0~uQ3k4m*rFcm28wI!nB+89=UHlfY=zz;m|YTEQ%R> zqV1;u&&)9W#nDv#_gX)H)P*ubYuNVk_1l_QVz?XKvBTqApyAI6%Oj8lJCf3J+N~PZ zV}i&s>|x-)b(@vo_%Q6pwuD1u^f5VSy>8fjKDk&{e>B05P>na;qn(=`Fm8pGL;8{0gB9exRnUct(6~H1_yyA@0~lE&$ruDV#3Zy#BOJX<^uXZc+4s6EVC z39tEaF*t4qu?lt0YXI?#`0NoP^)#|UtTku)w?bnKi}|P zI3E5m4ix8jIL|frWDybAF|pRF;9?%vp3Tg;>e02EG?Z{8Rw$*)W)VF5F68>2KK#e= zu%5zK<(bu_DG#3Z&KsZjIX4TFo%+*5M9;8auZF9BW=#gGssve>AEDRBVn{JaVzs_Y zooncx0@F5G~#ARnvB^ zacSTX)}^{^Ahd>R&Be#jTb}B14y-m=*Z_VU7Nkm$hF&`r{2rAW6NqPKMWdFJ{0*)L zMvwXHTEriF0~`xq^*%HG1ZZd5uoPru?T514ja|uVTz8}$*y|sZn(tpvrlQN|1o!H^ zE>*CczSU4BRQ4f2jPvkE3+@-mSnPhRn%SlW1~ELSNmgDrLOOjhIR=QaYV~k0j|t^GDG-&q^oEV4!jN(xP|N2@P3(R2ht@ms>^Hy@wCnC5S z`@>G z{v2A{?_!_(>S*J~2#)VqmacmI&GLeP<4Y@9_#3x-bnawRyI7PFgR3pmZ^us(7%&x4 zZ2YV1XHi@AP?^1#v6%Y$QSC_&y*8y9|B>>I!xH-%?y?96oE+GDV($G^bUEtyzJJQ$Td<@k-@#y`sd%#Kzp_*3J=mb_REtMa#mnE^El zF1DpGx|a%jTaf5=a*^!?qSr&{#c(niLEf<2*G$$5_@(xdEW~p9DwtOO6wQ3eE zHrXj4^SRmD6uy%%ZbhqGCGp5g_!XYwZC9~bp{Q7k!fiJcYI+milp-&mWuk_YC6~c% z^bX?ZTqxPT7mdvO#SA}r9FZ&(m&4SD^#>iMu6U0)e0ZoMzV{2u=WWhZOQsJ^`K@72 z0@v=h4k25G<+t=METEL{EJS6}6Q$RROHQ+5o#*zDHYvhPiLw5J8}WE1TQxC?(zD5| zP{zKfMYCQ~=PHDIN1jvlY;EVv)co?M=G8q)VBUw=HF(lqFZU0VC}RHzDs?*4EDrk% z)U{>}_?Pl+kIm0j1P9bW1aM_6Sr?@3>xO zb@MdDxpLoL)ao~s?RJ&^JHWSfjGq_p@SZp}qPyJI5YcWF4Op;5<#VOc6M3*>{3Wrb#BM&YsBaZCPlG2D$;69 zoWxLM_`3RT+k0PYdWE6tY)Nsfg>Ds_AI54#e;SDGKfw%GL5S7%ijP{T!g&qTM>G;^ z{K8#X`YxVeaw;B)*ToxVYi-K>eeXBk-zJIjFV?6_k4#KUXP3NOc?)=~nHp`+hHTb?I%qDQ1h+pEZjd)}9r! z;eF8w`dxEQXGK*dGN^I95^DHAMM&{>z0Eh`uDaHaUdOV1C82dbEw&9kQY1mp3zl3| zJGb$?cclzG_)f+yfb_%>QA+*4&m_u!v)$GH$`~<+liKtt^71K%8@l`{R09o1)dio> zZJ590&6EF2GXrNsEtps1S_;j?lX9yBmjsp9YSSbtb|`<;03TXSa$n!C5sJfPk|7e6s(cLv+;GjFv8N{fr?@nK|Y@0OBWR=m6%D1mq;7T&qjYxH){CQD3 zULmjUjT(xnvz{t-cl1Wv3%%(|NxhGJATf|D1gR4-f3z^SC8zZ&<154v2~ZN*)C_Yr zpP&7KcGnf2Fp0Nc6#Vu=-yi2#X<^r?NWNPFiua4$74h>hrSU?&tb015&Gk;S??~i) ze`~IKW$$6lw%UBfXkw^UURT1k8jR;ttxzRgYE$)#srDA-6FAdQPrtho;_ld!QOyLc zvLva+zW=3eO2_H0pbl!~K)u4<1%ZiyVCT*&>@Rgnn5f;AnfKHd&o}O(%^dBr zsa$A#9sZK?lamfV{|y(-4i|Tz+`Xpzb_~ws>}W$JGd|SO{!Fjo03lR1@1s4lS*2s_ z|B&Oq+2jQlNh3Bnp-XaS(8$x%kc}b|14un9_v7n7&???FXjA4PBeY()6Y~fm>R4Gh zG}K*K@2Pr!7&ol4ZyR>M&E26Nrh~9-ty0IJi@3h1He-9Kd!NFlX_TTAZOIn=HO!vp zwMg`1xE{Q(wkzOdUw1T%pm(&^ncVx0cf#6gRQpm06xr%c_iwUqIevAHPDch~wc7-U zWGHCzA>h$8633OiLGfO;yL%&*LQ@nTm}q``HErr)R-J!ZWc|p1Sn)ozMUJ&-N)Nw2 z_LILhL>Bp8RqdhEjMVv+1z{^P+d_HON z*WyZ{Vg^6m;92bf@Ra!$mvjXGLmPb@c{EM}m`WOyHNkbpp(0W766y9|gm&?pICb+To#(AL+R~1k646v3tMg|ABP%qN$ z2Q>b!jf}Ok;%87flJ24in3kRDEi<*mrwPoB6+aYcr*KIY-KAaoW>f&1Kg5pkIUMX8 z6pfx(Y!|12=d|?b?T$pXJCLFn#nyvmc+COk{;{ur1h-0$+;%)RVa?b_aerp4R!Khz zVxN0qtK2FM6*!B!gq+T+6d3}X`d!nP_YOG|lywQYLLvWTD3W{zq;Bk#!?! z1vjbSh}kq=>xbARoY|3u!e+cMNTBv$Yzidxe_N>otLKAI3c_ecX9HF5g`u)~LnuN_ zHR2H1Br9i}wKqvi(!^LGzoAIqG;8C`n&GIY*VrEZ%Tz?Kb*v)>eY3Dgb}2Xfb~k&nA?JUfv0xpb)NNq;rJW=@0MpJG6l^svO;iLy@uW`%@sd-5;Zt zw)=jlitXJ8&1Gsk_kk>AX*+#l$(FWHL&z$!5S!W|3!z1PkMKhH00000GXO9|2{X|1 z*D)gSH$Mw~FWJc!~e6+w6X!3BuiF6z_ zD5kl|W$UlG7t4B+Y3Px*C93cn`H%tb`r*;op&?A(S=-m(5#M4Mk8U_2nr@!&xUkN* zsK@!zSADjZx+O&&RChcvo87E zQl1hUtX&k0G}aw7On0X-Pl!feC$kRQh@xqu8 z;9R{fNC2wCULDJ#M1u62#9$r1VKy>W-=hct4AHOL42G}7-*I89qCP!_kTW8qL44fK z>TU{O&cJNpRC^@osz{m@-RA`PK4Oi6WLE%^NkHtFH%vl5d`z@R&&Q)%j^lu`k}h5z z#Yqfpo*u8!pFX(gbn$l@Pe#0V^$+bS;HBfach~Hp2 zHa{R5l!*%w8FBi61DwCZOg?lF?zIx26 zUB8r8sHMsyyrTj_O;nBKFldA$N;!W51a9__K@s-0Pu~n%uwe^3?gg0!$WaM#tZvY>9*{i5rE1H=+Pj zAZae^ou`3w_3l~1Y-`Z+zQPjj(hj}c$QixqGfharH2)5DMr)2mNi< z;WQ;mJ*T($jrp!_3B9fgF$6Qp{j8evAKd@3?x6|Q|0Ew}+g4(Lra{c$Lk}dk8KwFC zyx#F*od4ffvR9#JH%;-RKwZ^sN+J9DU**~KcgxIVR&*%$TXs_{Q1w<^xO<1V)(t(W zT8bu5>0+p?;R1@-FVp%;+kpl)f|^z0U{>F*i~_s^%}sF9(gP^&<=$*lJ2Q34{%Gu6QU`rde z1%^1$_N0ic^%uxp!NO!ZGt09OrBk|`4bnsMgCS;`1faLqPK&7 z>?$X5S(lY*u&n;#3&(iLEYtLME82C3r02EnSLQ9X-u|aKs?E9b6_xRzM2Kz zrPB!C`DnS)Qi=sRgZJ9wMOq~YBCne^AfA1o$w`DvN;ctOR+c|^3S+gW|2Q#WbhdW^b*>EWsj>~ zlB&m!Z{kp~b?`&{h7b9*l%S%DBp_M65mzeYJ5HkcBJN>7XAEF_8f_hUhiouI>O&__ z41#4fvwgJ%*lnR=2)BEhC*T6scHB&@+fS=uyk3(RryZXxHKADZvW?-;>oCypBCQJ2 zL~oF1p24yXzC~}K(Cz}Ox(!4T(e1+f;-{3UVdK%=*o~nElP7%dw>5aJarEM9obl71 zkqe+OBTU*x+ofZ(``X2O#L^|Gkq9PlfR-qp(tVm6j)3YYUV3{z-hec#V3*YP5p>H- zq#tz|hi4C-j?_thtGx!MLL<~UI*59X2Yyb#Qe53E*0NTX*poL@U0b#q+9xPkg9O#2 zVZ^yqX0EqHD|K~dnmx^Mx*XAp1C)J_H{~4X!pD8(t2A0}Hl~TB_o0-nqC0Sy!>?Z_ z$v|aQ7!6cn$UwrW?)IJP_0hj1X0Ab_A%sX zr4Fr%YMh#$;t1y)bk)JEj!*-$D&RJ}gB$S$Bw_I0(G3X+1#Zd5<08yD>OVM ziXR_u)O|&FXb;qw=mFn2VlfC#D%2P)&^pX5C^0H9whQ{O?7ZG6)C|r@e&5k}y+{nK zbg^&VC45k5PGIgZI%{(oV_ZYGn!kTNnzh*;(DZ`bSu18DMLTnSRDNWV9N%-bk7=6V z(wybDYH6&`VU!v#t@(ZUFXF`uJz)Mm19+-{{@BM>Ffx&!%!(A4$D{8huG&pd1kbPc z&L6FW+voe%EW^_di{=cF-=b*ofD~A=cyHS)HV919UQV|wly+Nn%9LGg?M|IiPNG3q zyg&d?Rkn#)FZtDMBQM@|A=#TaIr$BtSi5@8O>MSGTMY~K))toRfFe4jh<{OhyQ@lq zlPxV^T%BoLb}7R>iZX5ov&4jZurqxpIEl$znk$!Ht+U*wesn-T=xwKw=g735m%yY| z&9-WW1eK76#&*^y=Uw&FV88+)$N)Vp;A=2msCAVlVXTH}?b_YBNyphk-;d943}<6u zgJuqT!>F|M8L}0AP<$+>txy{$kw)YC%+J={W|(Y?a#^yT-fHl-Y0c4OwAT0iH6H6E z=unwWwVMu%u|+MS#G{VoGxPY^=Qp=f?xl#Ub8w_iX6=k9 zpYIHsX7=fgS?jrDWOA{OK6Z{2AT!hUK)|wG(CK8C@d(Jy+#YC4&u-HFtF3{t^0|9n zOJF(udCQFO(M~~&*{IQpLTO<=&lFEE$Y5GfiD5fOo~L}Ks2a%!o!TSSwymV)Ic`kh z=8LZ%*RmR{S<_)=PW&5ISGQhby^Hiv!19eH6t|9jf-8^6l{o9EE!;kem|N}t0P+|L zN=Ey(fkRUh5TBLSoIhw`}Qif_f_IG2F!(FgfW>9uPB0>z$7SS{KW7btUMiP}-!cvaAHN)K>Y%ty_QW zwA?vf`i(KWX!*9uAk2AmiSZqFZmh>%2di1&kZ%8}3Z^o*H#M~idzJhCo_(VYCYn>G zQV5r-Q)Az|N7&)rhGh&vAxk+hh-NgHOAyh9{a<70w;8YBiE}UG)l09^g|LOY+IR9w zv49gQW%zjbdqFzdX8f=@o1U+R{b)|C`nf@~kE~izW|rz88K{#_V#NQNZI--?7#!~H z6nWg_^laLBeRyX)s$JPFU%(a-=vLYUG#wtB2dp7brhVVz&7PE>df^PcBuO5I(;R|j zNH$m25?hz{G7H2ZjF;TjW7S}XL{ItIeyFA0TI*=ynJjAM*dpAWar0e_m*@N@=6-SR zW-6{zvs`r;Ybra{5sH-Da4JVPOi!sqVe&v{OTlraA|6?!LPlje>SxI4cA|-!fJa)Tw~@Wo-C{!xESA- zpl7NSP?64h>-5Li9p>4i2nj$~Y+Wy29QEUlB)?x|t6ulo_Os)oqe^Gsle}RzzXaMo zgIkT6)bmePEGjj}biPcYL0X@u0>hEDHgMWMgS)J&mSuP>_0GCldsq;Qx#+cm?se{G z2OY>fC_<(wCV-rJ8>o3!s$P*jTRe{Gy~+}^ydNla5?SvMRp)pfm(n21W5Ur?V&*)d zrWkE=Cmf6>L)(M=TGw!8$X#CuwSEP+3&RPckV7cw6vi4CJbN=77LTS^bjE)WFv z$N;rG61T>h&Wi|SVCUxOaTU${IDHqGuMTROkoO%P%y{{S8M+5$5+R#9cSsSN`iMHQ z*`rup4jV5}d9K)eh8mkBVX5)82$5ruCgdk2?+GDog$F{@`+;T!@%ee11!*1`d1O0o zB-&>eB6hGEdLJ1SJo5s!(!s`P(hTa+`!koC48%4S0t)0xO|~oUi4MLiE{q#!?K22B z-4a=EraVl_{ZLgh?02-Ox>x`8O;Vy^T$qqt0w7SYeValdvZ*z<*PHn4wO@7h8<=b$ z*=6}AC08kS=mvWYknN6+R=+XEQx3BN%9NgpE5;s>>Ryu=f^CyhTMY?mvcC)G$-@V+ z=2~y{0Glt+)0tspuAJHe(Co+Hh~h7bP9=uR6EdR3Hf#B!c;v9e!cpse0e+1+NT7`n zU$|F+UM1dDHtSW5DU2t7OuaF5fp+v>zd)32-u~5*u~_p&M;^Ch%hXxu6=Fv@t_S9* zmIP%gg~C}@po`F(+JRhXboIT*#|Sh7^uH{&Y>YplS9jX>*ipFllmJhOuPzj+USORb ziF_wq)|8FCy|hEzQeunON-rm}(0PlqAGS{f$d-wxEM7qgNb6uwV z1bK-l*T@?J4!yAjAci)dSWFIk`sX$BhIGjA%aigyy&H&U+Q85pijC80pNH^LM5PA^ z8&coQfHJuCZv-mA9dn}UdHxkIUwsjYVc0d{9~lE7TG`xS~*O02yPlT;YGG*Kuf(o zPk2SNW&4egG1mvcHS$bpeq%%1^Ba5H9*!C7@7BdlY}DAuLO*; z%!=KgE8KtZS91@HGnps+j^H&F#F!-6KTGGI3C1 z!tWZ|2!voggHJvN&8B5?qL<_xuR!o%Cm&GmhH(`%36JeKTi3*ik9An^u zI9PSNGg4+^3zP>rZ!o=Ja3jr|XFTt)oeq4oBkN^*7A`{-t6EB7uuR&#aQ?6N=L`6B z4rH8Irng*^`{^@9oS5{EF(PSX`2&i*W_nfm4JKOx%s$&W^mEpDgX;m`0GG*Txng#zqLe?EY%5y1q9&$o5-@oq}#8UP?bhY@blwd zOz4^9B|%7iP;`ci5URx*n&-@8`DzDmwFx1F(qdBf3ZE3gskE_ZH#V9G2D2PbXj5XM z9Qs7TOv`iZhkBu819yu#va}|CU8p?l7JL8EDy`RN3B_*z9NIDP;3d#~foH{u*&v)H zPQ}T%q0#TVqj(Nyn3)dgg*9&3SgPg1+0TM*);QDHlyin?mb}2Rp0N&fy0Q+_<)1@9 zm&D|jN}y+gyaO2#{Oi=cvWI?$@-ff%2a`vvYMb<(SCN9F~qd|z| zdvu`y7<`=a`(`K6hB zq(;b8KU&H43Ooc6(v})D1{_Da9 zpqCg~ovwuMZlzPi1!IGXy)LK!yqO0DQnj1YP4r}`&@6N!?4tMYmfbd;NlC!BJPHsk}9bo zNf)HVNgyW<+fG~jd#S;~K|Mx>gCKj60YE}qirY!m!Q0s!u&|--@OjwG@jA&p7-#Gp z1S%i=ri@n#ys?7Hq=yzj2Na;y*m>{Q2%r#7o3U#>!~d)(h>vAplqO zi}-jBW9B728t00~ z&w$!-8bYlS;07(56CSw|S_2NN=TET?IcQc4BmY{51x-MZAr_QzATgLhK9n(qH;`&T zAOWzf5@0|~iH{7-k)tdXHf*288GY1cwex)W8K?J)SX5dq*Q$^LGSWLo$Taa67)Bw7 z%k)03m0%QvmSM3VubYN|8yHj%ktpL;6=9bW(xBEd_sw>{j@Pjp8Lz}8aPHkq z!EMj$9{~@oU~o$Hkjs%@B34iJ{q-RsGWcwXr!*s;QQVno+tb0<&~?mqE66vN;xSlP zbI103kY;HXwBxHd{#IUM;Ar^T5zFa)4i*^O4uH-2?$olw%-e3ZwgA72w-WkthU9E! zi=(oUyPP`vZ2*4iq2S^nAXI%OK5=}B-|#e}bC_SD00YaucyK-*BR~T^RV?LyMUmK5 z!dC6NkVqX6-M-u(h=taG zWCFOp0{DDw)D&z+U`S@^GwgmD0Rzgd=~&WfWg%CyOq(PyRz=Iai|A~2-ofCOTO_Co z0Ifx)WkREt&aCrD@vJ!_?k!FV7RAciszG}58$#|e`75omG(JWZ*Y~~RiEqJ*;Rax# z=6Im0-Zp}(i$n@}S6Br`gPqBK3ZmGhX-b5KH=X~!phc3r)T|0zsm^d<_9H@gT;gM* z5%KqI;b2bRoFGkA@TGE%u!0v((xAb#yHy3o2W?^c>mRC|ad8g6t z;$69q3N!lP<23d!Yi0gxK|6Fp$^g_PJ`s&kvS%AoNV)tczE^5WPf`6hRV&C*-uFBE z`I5Sk1yHFo2sD6eUAA_7;CA2Z%LF{RGMPh>nQ;aLOQF%htyb>3!Wj_6czH;xprF>V zzhGXyE)#fM;_D$&)_E^Qy6B2l`7!JEDsh}eMPd{MF|+JB9%T%hfW|6nyrYm^8_eyQ z03__b@@otQKb0n}u?m1{jq8lDuA|nHDP0cyk+3@5H|Oj^`BI|~Er8Z=+J%5!mY`m* z(a#9=c_-vpqn0U5$>f=%CN#6>1%u3j`8c<4;=BRX~w#ycM0n%WllKdX@Rikq}ma64M6M=(FXf>XKr&h#WE+!Ib$Z2ylvIM8}X8>jw!43n5 z)6QCN%-566Sm~FFbzgOBJ%7fMw!kY7E-nn9IHpBaBT<{ziYGUL@@AZZXQ8}O>6Ka} zE&x8%`?bYeLKMA{ffy0xNQ1zYW4>mR@2+fs#F-4XScX}{YUTmDeF}ri#6!5;`Lo^V zWHrPS1rsqDh^S?dF8k15Vg(sS5!HnquZB#&*pQBv2jS9f%f)4OQLZ({Y*@YA_EYKp z)U8NI5FzAc#Y_S|yoATfNLqG`z?`lT{9l~l*v$p6ln;6Inv%9CV^TTdF#_)pn%wXy zN&M>947_FyMVjQ`Yo!we0cK=%ax7XKm%qfd5t2f5Vp`HOY|Rdio2bQ#E02N@C<@zh z+;Zce-$28%co*lXLBVM#1LTDa)>=?H1-+LgC?fn$CU!Yxqk|tpe1!Do zTA?6GPWO0)yg~L?@yc5xj5@DO?Kz3k=;5GLZ-(@>`t!nZ0f^WHaS-lIR?~v6Pi6~g zs_i-`fH(=Ej&pv0(BlVE4)y{7`E~%b%E$HGuOvWXdX_^I&$Y{$atFm()gDJ*^{QIU zt%p83yDKd-U#;LX?z^!ga-a0pSG_hV10t@9^oW>ewAr_6C9u~AS{L~D23nm_TYNxm zI@O*kz!iFZBu_ym9MR;briPB>C?}E_vH?izhzb}{vc%?5cTJ3pS$1ds5c}B(kz$>i zsHyFSIw>w_;7G3iW$w8qqA=xxTB@bHt@MhMJD*q#ZH1V-D_ZIKBLli=DaLr&8FJ?l z=bWhZdO9`nz>ey2-wu70*FwsK2-d?mIB?8kppY?(DXvun0e#IFRV3knG2EbmJ$INR zO=pm~n}I>DEvuZk64PbQ>>!&^2$7MZzn41YRw}E^WiZX;q~&6%R;xO7IbTShrTB}m zXeA$C(m?{z{?3GdBW@<&mdEg_4$b`r+KkH>c}k2wD7lHEpXzv7ou$?g=3x)YjLFm| zX0o6@M?kjwNY$yff!_P7v&~wD^y9#Wo2=+bdnCH4QaWkJhrO9Yn;eOg4ccHs zJ>OR($w4?;;F(xBpH+^sRahM%jw1Vm!)Q#rl%us(b*1|b zU=#aXDcYlF;?^HhR(2VcODa~8B5ue3rY*hRAn!azG|FAKh|hFF@U&bO%My)kfyxXu znV9&8lh7$CF{g2!WSng^P7eYz)=|eJf;r2ED5T79bSpwual18Xz`F`pO3r9=f)z-3 zxQv-Y$USd_1Lc!z`#T*aGg9H09?kqKDD|W|oeea4Qq;aS~VI~YAH*l|76fE@X0Zl7j1L?Ne$xJNljAc zquwE(FHt(F%F~^9fUchF+Rw>w)_YLisILo|PrxwGbqIXUCa%+=>6X2Lpi6F<>BKf# zsNCYg>c45bb^5T#^=((KlJbb|VnV&!vFyEW!D#Ecx{lw{j4a6HYFTd39w2>)5a92= zLbjLk=LU;ZzLFY%6rO?!KE^YXjM&c)ya-M8o`}v+N=Cbt$04;`IMr>ISLPrVoe^ic zGA4-@{nXpfzaHbz_o$*+36m~apmeZZp{Sdh$91th;wl{jmw3V0@H9Snu=J5EF=8x+;X-se12)uk7mplsOqUq80Uq0hGQS`PG#(~2 zmCfL}UF{xbr$y*kde@ax1tJdGU+m zI-nb;1Xm)8Vz)`?$QYio%A*R<#_^=3g*){otg)3*K&SjgTSA{P+*cm~ zHbF$-*ny`3Tbnv-5__y^AbEM0@LJCVv|Ql;=w7Ry80kV=y{VD|T&svn@RybWZVQ`8 z6KYY6@2nx*bmj4 zqO5OCqIVH&9i_f0}3b^L$7+8ua2MXKxKhOZ|Yq1Xk8c9N4tE7VQQmW}p-*V)O;ztd!8 zM+%iYQtxNYs}q{a2-|=0xGOL3od#3Z03umP z36*&@eVM49S`D*qW;wYBYyJ@8-&*=(kKu;~`|$?zNYS_D_}rNp(p!~=QH*ub6mIl6 z{AahN36g+}`HH?95|}-*f)B`fm5Ft1g%0peTxN{+e`&oORI5&EVa-feQ{7sG2ie;6 z-Cn8)*f11ELhRQ5OUgLx=+FvSy0ZV?p?@g=y1dPFw&hPdg{!r5_a?`UYZ$H@OYi#O zW5UZJV0EyRI0oXg2NAUr+a1X)O}yu;#PW((G&4h_G(C1AaM*`-`IAqQY4;i=}0!G!ag zn>z|kdJ+HWNI=cTs7W3PDpD`yLq8=*+!M0Y-D5B$!)>7%-L^=*qeGNSs`2J>KF&E= zjifxW;LK8o633xEjrG=RW-LUnA1UP}Q7OGeU?gPv&RKGLP=nSONEcUT%rUdsLP-kV z85D#qFwZYa)|H6Q1VN*&>jmX3pjgTeW6S0$jF+C0Bf_WR!8~pEZ|`1#db*65=qV;< z(H4QDU&Jz%p^bP_n#P%N|0pXaw2+);YheBzATIH3vw`$Dte~+H_bswaEqmKV0U|s4 zg;*nqLi{3y6O(=MrH4*oO#6iAE+GzO8b5JI6#f-9+e=@f)9qUBv$N%MTv+L?Jf7}^ z59g2Lc=dJf??@vH{|W;LdkB*C(*D(n-&A)!A1EBkJ|vmd)}DI(;|sx>{*cW3bmoBG zl#LL)>-{a|ibMO4KkBxY5j<&N#?pX39NPGZKyZn?-wpl>s(Gbk6duyP@u62nRJOmmE%cOr)D}IQYU6)FZYGk#jAk7Di5lVWm zQ?A!5lHHY#W63}jq`D>WjD~r#f0mPz1tjSL`%7HwA!L#hFKl60D5<**rM5}n|L4MR z!AcJib_PT|FduACtOWq94<4L*8en}&92tW?3M2MrqRozb&^tIIithdOI)Z%u*bWOQ ztf?BU`K2~YF}P%V=)Lv`#4W>i1lUEnBtp@X8m_t44TJ8&wrRB7%>VfAmNNKv!>X9( zn!(%w+=wHLZ9%uX7W&s6$OMp=Uerj}@vw^Av{pcZyJ63OK+u%;N1NEYQ zZ#T>GLh!5c?oryL{D3ulU(C763M3?{Bp0l17WoWxFvAY4PhNeEgKSQ1w`57yC?aN7 z7vrp{M7gG+9s~=`J08qrZ-ho2x@BMF{_|yz!Ku9&b`gAyD~cx2A0alfP*%;PTkRiB z1Je~IZD^rlR&a#00;Z-Mn5}EHP@Dy3Q@tkijvM?BR5J+LOlb*sGOiiD4l#f0N97h3 zmuT&Q9OOKGPbnD-+w82WjlbKS)%G=Zx;Y(AIqle<$)qCuj_fi;hTD```_xhi#^bsUYB`Cc--JVzV55-H*SKv!M%de_q$EV$B52@fEvrUvj&VSeHT4+QX9ds{ zd@5W@wQ;pLZ+@|Ajp35_)cHX%tP=4UE)JN3@5oX_kE^NVTk}FY=FB9^M-R5Do4T^K zs5Zr{xhN4Vrqu}IJE=x{v2~4lMYUaF{jCa>X%r_bWei1b(&twpo!g>)w)MJi?6Peb z`Mq7K-r{_L`Mo+G{qK##81CH_#Z5Z(j&x|pd7uh^J?RiryH)-T?GDN9J}MNJ$3BvD zb5-iF$`NeiKxSbe%YW8(Qy_8IO!Yd_^t#!5OKX0&_zHDi zB;)Y=YZ6DyWo)?cz~G_=IZKa5p#7bJ{Pl>P&IyZ&(NeX23oOBrbUt|dHEcO>Ok9Fy z{!SX9%Amh-Efyp^MClfKPO4gm31i-&z#n(KN%-73kePSXqaVTHgjezj5Wn9k@R0DJ zFzN=XMjh0LN z!U?!NQ0&%k?53_IS#agA=w_e5!agd_KTNKBM?64hU&Q|6m8g7hlV0IU9uvWr-`001dbQb6yQQ@N3;mOSCRd&T8z9e_} zBsE7UG_)|u_iGltNH0M6fTfD4?PDF7)N?*-m6TlfdCHAo>lFmWuX-jTnWVArw0CJl^+Cv1Ls7MBEw+rkPYNs6DcVa)ATJC8vc{UmxVgX`K<0?NHZ5=V zG+F|lR$zcE@`P8}wr>URL73VS3G0ye_K(N}8qk6x^?okv@WN>VDS-9zT5ln8M~{IB zv|uj#F{^NFRCtR_pn@3oUzM)_-o2sdSX5jW_iceibKW5k6z3p+6lTSV%eG=dY-k}R z$3$p_>0CL7awyi0RR3o_6%PPVVg;`-aiuUBUoQ7Y{nTVu9)IShwZb5jsjwj*$3I5vgj6bsB~H4uMA23tU_rT+Ty?*b}h|Tp5r{?}#{zH!UBBXhCI@PZJ_wB>yVD5ZjQrxMWw0j8L)_ z^9Q+C5G-fru}!uqhSx@4^I@FCTe%4=o+**mz~UD!9_-Zu`-|F37xgo|x5H^lLAh}| zrGv@G*9p;Yg#vz@%Bx#tSLztZ#^ycZvqY?IOdQEPfO64UEaF1<2hqv(LYY(6t(=|- z{>xzvZ0J|08g>sSw9n7CeAhsqGLV6;OoqY)L}Bsu#Oy0gS*CubTs4OAIS&r)Q1a_A z`t*j#8O`+t!4B)1xw;?lrl6^L#0tv)@KEXVyL#Cf*w)>fwsypNWa+r%iS$k6MlSPh zS{hI7D5&5REAMw!P8PJlGV6C}ZEv5du$5J3Tp)j0W2;Q3n3ICgSpbZy>Qxyi&~&k?$Gx;dOG31y?Zy8HeXIFX9K z{Fl7QRmb+pRTGt~>(CWUQUV5G$#y_6JTDz6dCQ=D`rog$Xsw&Lr<)KujMp+#GvDk_S1<{(9}X>8kkR&y(Ls4&VXdDs-nIvh~-cWR8gkg~ml|N13R zy+xe_Rz_lspj@F))wyyqc@KJ)R61ck54e*ebf6OMK81?Bg*7FC+!o0Ql@9=|0*LQ9 zzlzC2N;Hfl`1jG++vcZGD|bF!aO$(2Oy572ihEN1P(g%$3_%@vs=I_VZN)&8? z<#V9C#BepzarOG;GF_&>Q&!hT0U*pa8Nu0@p6>SqXLRJ^Zx7)!%GGA1t; zZ$+v=I7?n;Lyw|~Ymf}GJUhnG~CBqyc zti0K1b2d(VWD8qIj@k+#t)ESfbmxaS5AZQ`t3j-PqZ7@jQO3Xm>sZGwUzY7Xd*X_1 zPZ)2dHWWzYslHJF&?H(RE52;{I;CY>5n{*`jT?Yk`|zaq0a6-| zQ+@C@80XKhnp(Mq$}tFj=dQ(yp^e!kAo zlQ?W6-RTA}KgmWBi^e?@{7Wx2#hXwmSoNl!!$>mO**t25dsM+z6*M_WZTkTsOJHO^ zrpX%!J2i5FkQDD^m1t*84sM7-=FH4BQ@tB7`>Vy%f|^5ESyk}%wFoC(FBn+6c=&xw z`m03<CduwIMR|6}F~8hTtwzkEgnyx+b(Ff>hU zEA?Y}QZ5H3?KQ~Ouis2w1+AlFX$Zl)!3N`i55AIvDt)X17!^ZqODYYg2^C3r@zB!> z?b(8o%0tjLr`^(CAFf%bgv@-Tv0s*xc zoSoW^U(>i4lf~h!Q3QZ$Gn-^71EqQ~boC7SP-9*5Jp+a&=Hp{v_-#j)F<_wK6BtYH z+1HI_k=f%zMra<(t!thMZoQcYgx0~uz*+}LzC^YA!cA}W}*(IqAppPm>$o7snN&pqsusTMWcQ*3VRCJz=TV>Dv zf)tA!s0-jUPwv(O_T;*xCFVjw4~NKg7RBthLr{H7`hsVny(;IOPI2|Xd`N)cV_CZ?q^$_7 zs21U?76_E75;g96^tH2VyE7p(W}RN>hk2RLGYU!9LP*33&C=*=9UK+9{D*!Y0I0`> z=_5T@Rgr9OZ0~XZ5g2m>4wA<1Dt`+rr!{~fxSAa^5_Vz_h2P+J<1wU%GpPI^?*1; zY^&?uVA6%{BHr#hs5gFmZ>WA7099o3EBfAZWQ(NshNDGl`&jf17sWYx2do{=P#EHy$o8gooR2Hqw433jSi& z+F9$qT2;e;p2Gla5<-M5ebANY9?Lxr69#6Ob>u8093Eh_n!W@YcTu~)ZMUQ3?HT|m z_D5pEk1ZQ?iXT@!E>;Q37?~m$LOX5@WPqTZctdB)QB@x_4gd`4$dKtLfXCwZBiLX* z)pH^TAWJ@%WDlrUM(o!s!=OX8KIMA-z}SR~ZzGCpn2Sn<5a3SlQFWp(a!)|;Jx;Q-*Ve(7C^jyuB{}(>q`*ApPj8DCqd+%? zUgvsq<-%Q2>lZ^f3y$}72Tjv}H1bu_78SLvfg-DN>~@aMyo3>{d~ZD(vkeW3+F_^N zwX$Cnr*jSAYh2VGCE82e>Dwf_PF6?7Rf-utSNnEMq%_hWx9qi;G18CMJr`*lGBokO zX;ve!ESQnim<$6gtB#A?C;)P(h?ho93)HZ8q=dxmWqE4QOFFi%>RIz5dMuxBOv<3M zWc-IYOgUhlG1d0%S6ceIfVka%)%Y|k_Pp;!;S$_oAp0^hH;KsS=!g=fO6U+3zdV+) zLn2qBE;qe z`B&}gMTb*~PfXW4<{BWyY$I}FEk=d`D)X-gn64zu#tMcCu9DZ<9F#kuB@;Zungpkb zzgS1xWmP7nZ9GWg94u$&hgIb_Gt*#&W*6H4Q?0*mO`_Oh#C&?wvSbP69{2;b1xLDh z8l3_3!KLd8Awzq16z2@=9VLpoSOSa?4EMaQ_b9a@+TPe8SPu!Mr*|uiqviBz)L3jg z!dd)kmn~jE#(HT|x4u+2DOB{dSuSc6KpPn|_Bh2jx}dv5e)}p6ScvR>CvPSH^qy1j z--BaYcI=Po^OCoyr25nkAyimXZfVXR0AXMR@uc@s0Js4hElf@zJjzRWhTZUKjH3?- z(;1hN@?c{s+d)us%>0eROO5`5Y0p_GHRg3tv9lnKv0GUT-{<&XTYmCicdgM@b?e9n&}a36_#5+W(h%Q{vaQ_Ra9>d%#OE%|N`a2X7I1CVuDbM(NpsR{8bd<9*eQ%fq|KDi&r!oRmT1 z`q?fPxGzTOTmTBMDw%9Rx3jiwz(z04%$`C1T%c1uC7{;tI$Xna-kkdyh?%pv zIR8C7ikc3Y#qeR8+RXStUT#cP{_#8h+BzTn%4Bn#FL9W0uBs@lf7Fc3Ts zsCegkemHPKHI=^!>xY8>=d@=b>qnwlDpNC}}k&2)+L5?D8B`~ZX<(1~Pbs>c^X^sJ*$8g0$pDZr=w<^9YWda#)$hf%7) zISRjjfzoGR5;t`PqBFpn09v9kTN>`M4FxW z156O{hM;berWrx8vtcb)k{-@Wk5{gOme};8!0cp=0(H4`exfr)QrUc%B7HE=FF}Jm z&m+KPFlXygX7dS&dkY+f_KCKSS)(e!uhN*V0!Q|z6gqxDJD}S+xuF;PaXP@7byAQq zJAC*B!_9U|Vg&U!1{NzI#vGKEVnx-1#MLVR&e#+T4g&o!`+T2WWExQQdi297!8x<+ z0>UuoI&($Nb6dAP;Oz`teQsGlC4Wdyc+!RhP6 z8gBrJcf^$k#680FD(##i@~G`<=TkfiS@>=T#(7VGj%qq(jvDJWyBE3g^Bm2#P+QrRx_Y~=-21*>Y#Trh zy|-6X5Xvk}oirv7cgfkIicCKhNpE7^d`K@@NRR2X$VaOm9E_}v%-hRQ84@wPk)EeO zmS2`fQLp15J`Jr8`<@lLbG%;W2LQh=Ua)@}M6v8a`ZMsqXhv9nc!QMy6nrQ+@^cbO zFo1wW+JVt?fU`q+z-XwwcVJ%QvND9DUBrvxl5M`f)2BkNDN=zK2X4*BrcagbH`ad+#&g)A}D^xQ^fAA8P}ba*N& z9^l9hx@h%rEOCQQtk0q9Ty%sI8eC}l!lHGZIOf)x!Qf!Bbdb2IbWwG&_cT-0g)mJu zCzM_bEn@7MayX~+!#e3c;9=1@bMW?&Q;8?@d3)UPe~yJ&_Rr1N#@8kVAAF>2d`)A1 z`70+NmPUMZ_>`PuoHR{28;Rda_lztc`_Lj`Ybm%5)_a7g# zU~9yBy`9G@21``;#9WHL`>5L$^tAFWUvGZza%t^#a+P;+Q5MuhHBJj=ZQ-^zNL2bdPdK#DInAd9 zMp*NMNtUyYuq--NDQSVT`zSld^W3YyUG?W)dZeo>kvj33^fgIn?i?%nA16qT!Tz}G@AEdno#~|1fz@}#%n&k5ha8oAI25>WX`QAu6{FO=A^(@|M3b&^M6D&9 zS=IJm-7_|+4h>D-x^~lTvMAmEB_^j z_-Foyq;6d$#rygvtF09CH-AOboORh3Ge3bNLJ>Hu29*88+qCoz>37;C7|cQ^?#{+7 zQ4z_}I;T+Hoe)P(%;9Ud>IZ90jB9Z%hPu_OZ5Ro{!T-!jYQ4@Xy=@gUj#i>iDdsAl zcjivcmZC*Qwg)AiKI4X;cWe0TX4)h6&l_sIfDk`8YF@&BqCNVz>BLp!)}636#HyG0 z{B)#RP4i%+hk}W^`3b5$VVl!qaZx6{n^WGxOd!-3Cf6Ao{?Ra`dzlIyHrcVaMYN=l;r zs{l0I{xS}8m^l{eo7s=5O{?;TsP{y?pFu4JSMSwoNa zZy--lYtsZ7QX1u5xL9#{_*5@G{2a4|_?>uZMQ9ShXF)j=B0UZOS3s!0vIa-82{j{$ z>t5eNtT&LaYhq9VQ$D3=#h+*+Sl2syxPTm!xy5^S zN5pV(cA_q6Z^6yzyfW~Np-;xT2IkBC8*A!?vVF8$R~S%KTg9%u& z1m~bln)kfB5DDXI*!WJ;i`OEUvC#wuwg^z>&|E-nem&D>f<92wzE+mh1{!WuH`!Fc z2aY19*KmEWZ*>kCDOGqNSOO;=@+8Z!D}i$u;3XD>zayxf_{>B~#03}beRcDUD2fn` zCkatB>Ta|_peSq%WIw2A07yP#+B~q2-(v`LKb;$hA0g1UVmeHH=`)BDpt{&iy#qDg z0Vec!BWfbGN$NCoC+%PF4>yahm zi{*)NNgsW>RfIvIy$U1py;fZK_-9A)5a_JsFp>q$Hp#H{O-R+e1A%s`!;z`-(oxJj z05$30eDzhE4T~rFs+S-e?Vy8gW3+NX2u%(>h~&GCR}rT0br+qUE$xZ0)(115m2;LO}{v_S6R%^wwNtIdarhqu~Xn}4Jb1+UaE_BThVRLH-6^ezy({| zR(YF?I<_lGVv*d+*!&X_AF8hh9+nERptUCZ1qcfh!cLgxYe^j!U&z9-Bx27abqup$ zqCS72i<)K89r3^9-GZ9|7&DzCY%!jL^{>nWn%5t}mq-j3hJ|q>YSBsgF;q*Mu{_s- zj+}&69f(Mu25l>+G|@)=A=BBZeh@yuH*(^l#?RB2&9xDE6hOHIOj1=ELyVgDHVy@9 zw#)Zb4dcRbOfi+^@;$GZNOf&)K=$3!zmV`w6sTJO;fG=^?B0ludbX0DJ2 z<$KlFwCMv9J>aU?Cp$4=*Z>$Ya>Yrqx0;?oCCC{syJ$px)!*~wmzEVc3%-b+r@OXS z=e+Z!05x1qmAzm5_X3w&gQT#Cz|PAeIV1_DfMOH!G!}#BN|Se6QCYa&=DXU8fFp9| z79|HgFV?2CdSq*LXN0($dVy^aj5C!Z9g!3pJqf}KG;qn!jMZtmY|3p~epuw)ynyaCu z$>=nCtbck7J$^lCq7JHlaCOmnTV6b_!F<2~BAK~*#OyAp(<82i>xU&E&^VeOaL9wl z@}?N4y$h&AQxG@ld`nD~vI=>U^@9CN2fy1?3E@-3MpnVHIJK4+_}ul#$+SiK`(YIFVmj1@Q?ZpZJrC z)V-xg^SZ=2lhH`7hlhe6h6#MvR+Abyts4}T0ze^I1#zk+kH+1VWF52| z3iI5Wse{0Pd^0a)@cDCk6fGZ|nrG~7#Ysh z!Of#2-RYi!o7x@(Ou|v#T9#C#Q#ZpJ>#E=A@BjUf6_;(PtZ@ci8+6ysP*{#G=h9OZ zbW#egT!S!@MWfB@NYTN=4cQ~zOy;}3-c4$1Bh$tMYs@ zdeAn%l&tJwLj>_BDn}opL=BYM+X$GO+sfNmPr`Zy8pEUc+2~Ir$bu34A!H75CFKHD z;)f&hlGv=3Y%%;&7auYakSi9laTj)~XZCNVH>PjmbsXCLOTd&?PYFX~xP}r`;Tym! z8&clGxp@%vtBr@R$BP0!SR`5G(3U|59sO@T$lyr<&TS4N04>eCf;Ec1fdeIAF)f-- zKXnk_!BO+WTF3#T0PsNpfiDCZU%}t4pp1i_qf7UGte8|H$b>JIF)sR+)<8*lClWCL zfI^$BMTg{*)BPoDaa9)3m&)r^ctX{ z%}bLObck}rr)8MKlFK!7B<>!_5b0b~k1|gV$Z#6Z$29_Xf;8K?-?y!`@$aN7+sGf& zIh~TE9yjqHGwQ^1Fo7Vzkm|Ws^Q;iGHFmOA$NY@A7%(C=p|I_EzOR-2;v4ZOYY0(5 zD|Zc42gmop)&U*;|2ybgkm>zcd$kP;!UZNv51SDj3n~LwD_MK_Urcipabvw9`J^{s zcmS;*QGKAik_+s9tVqX}|a4c|k_Qjd%M<^$Mb+Yq1%P;&!lT-0i_M1p9w*}c3t zblmcmPuofqjZdAJS&^d;1Fy(UwmX`R1Z$%a)?l#GG{Yn*{w^1IiCvrUer!KvQ$5S* zka|^&hDK_|LNLKN5u+i6-g!R!*Fg?$SgpXZ>K#W5U^JxvU)#V2%gXkibyc4Hnr`<_g=20TCZ0lD+z4w*GPm;{ZfcH6e4vbWirXE$Z~vH=i>vn0 z{}dIt?zJc`Vgn8L56!g=S)uy+%AYl7I_S)Uzj7NFVF&FYz_WC~c zJ9T8}u4)A{JrHpMlgycfoOC-_lydC(DV~@btxZ zFVerWtClX;4mDxJgy!fJG_O3ZC!p6guAt3sER$;+t4n5w^6>`%A%W1e>F-i8#GzB5 zG$_JaK?!+nGq0cBwwa@yLeD+{F~>=z9Xy3w7n&M!?l00e?b z0zV^6-ppuuI@c}`4yirE5!A-!V|;A3Q&GIy^dYb1+{d@qPwkwKTBx^HHz*F~RML+Z zdrftsBNmR<_86`hy2BxT#bUvDtF0=@AfrQNuaR@44}kF5wba($6&ALgHJ}ApphvcB zHP~5xztd7Gee*bA!D+ZjQ(WL?0u(L4&f-rl6rX+}n_Shq#yn@=;wUAZ-MW68ip>naN= z;b<%W?N1lJE*z~ZB2gT&AWL`c)ds{1@pP+Bm^~~p6%N{{z$Ba3zThL>l7e_oa?DOh z=_!y{$`ryx_d|w>LJ%0{{;5nn#KZD{aHIXWNFI$uiVdJV9ORx{IA-ht6x*wJ!P@oO zOcl6mNj;5brkVifp8ClP3e@XJ6(wTHn-$5x05;+kGW+KJUcmeIeN`Q`Q?&Oni+#UX z`;clCI;|U$%ZUnF&|{w<7r>-j4AAf?R=ZKCyZ4zzbAswgfb|wAN<%!HTJXAd91c_l zUabq-Z;e~Wk%yh6cDIS?M*Ddpmh%~*p`czl_9~6l#@S1n!MbIsx$Ipl;d+R~j|pBN zYkPGNfTT|qG-`KjODu^1pEV80=Tli9Bao1zh{kF8kz zN2<#r5Yg;4J>wxUV@+4!j-(DE3fB@Qf)K<$t)3WEQrD^?} zJtiFjl2=6^NO(XN+x(~Qg;B|JBuw4= zt~$-UkN?>1&tYF%UdMtzsgR)${BBQ0!{d)V{Dg0Wos@kQQrqMaZ<1@6Uwn8iOMu}u z9aeM9v~c@7F>N~|j@;Li)v#XCf@hkkbbByO&^NiTPf#mnFupmfyA*hn8+F4HpDx3h zx)7c<)_#CC{1J?mB@gjl8LH-mFSQz&2BGMI_c&R^C4(8f8Iy~Y`)SwCvTaU{0DAg_ z<9ooop5EJVLfFFmIe$}PRU77V{X6hYu3gc9a@A|$SQd!PG6B8%Pbn(Z$q=&+0 zJ5;G&PlSX07b6N!B|GMER$HvMhWgV%$fwv5tTs(E$}O`UV0-*Ug<~luEfQD~)68t3 zLja@kTheY+Yc-NL6u?}5%Y@4U@3DFtGgL#k7y;@H~HxM20AZPsu z+}ifQDF&Z1U|RD%fUC?Qh2rSQYZrqKVH#BEULQ_RNKL%q36cN{8xb}0XxkLOEnB!C z{Z6pBhr`Z{TM0SpdYoOpekrSHc^T7QVhroljh-YAw#in@m zHm3s2TaQ+iuOkc`b zb{WL5Gx}r+ekjq$Y8Z)Zvs~B~A9b|H?dMuc-FA)HESoK--n@C94@USb4!BP#7Oiv( zBt>mVwDb+0Xz-6@vpcUaWW0h(-tlWgz-qzldqz&rNvEfO+!0P2sbg#>^_`v9T-)Ifi3|`HBzE^6pHwDZ=kaC$= z=_J1ehn<@ZOQNF2{6lt~QCR)6R`!)D@7C&tof`i5df24|DCO>8L*8fOZk*yJOK4Sy z3tNm17D>|1%2&p0#T?S!-n;9xr}gFo%^Qtd+-u$`H#}q33I$L3p0WeeP=g z<&YbgGBB$OgnDv|1H!Tt;pW_pf2q$Fr7~M0U7Iyn((@>Q*&=q=6AujsEGaWDPS4o1 zln?awhBVpyD`UQRttTVmL(lMeNxjPMbJ0Y4X;9}_QaBusQSIfs!txLyZzw~2W|X4I z9xia8@P1x-Gil9cI2L3`PVd>VukGB?YE>wxCB-r0JH@`< z_TodL{`&JmdFjBC-Wr^8oLG~e$f3nHy7Lw`#4U5$(PO%xIkCbWhzV6vDQYwF`Kdfh zI>dU2Q6Lik-2{XzlqBf@puXRR&7?MegOut%0*eHy0(I1@fB&QBjZxhpQ~0!!6;<_@ zZo&C>jsj%eOLBtLL%u0_h5}^@mb=h=iteKLKLX$`O_wdhHCk9W-{DAD>aP8wmvV~6 zOOL8Qd27!|`N2-g;%m7bt%E+(A~gouChKmgr}Vj}KT9DyHGiWr<=uu9djlQw$JJJ{k756LkJ6eFpW>;o(50 zt?qtCR-QCE3rsSzP9gKaq-0~CzaQmdX_-b^p&?5qWac$q7kl}_zQfk+EyLv z?*Kiu>GWWZ&-LqZrs2I>2<#89-N%bHG_1kqZ| zJZ2EbY{@FK$<#w z&bBN^>*zoJR&3dmwv#GVZ^q6wQjMSlFZMOirI7;r;(Wye?=EzPDhPk=lp9P-8H?6Yk&TvR(GGO$jk zkUWM%3kwThdyvUxB%$3pQuuQnmmS&ZC=|saynK7G$*hFEX;BBHrj0H>Q=zFOC9``2 zk6Z3oD>Wf{ca0H$QV5$uoVNA~pJc~tp{5_|tBu=NH3!$Xt3-eBLuvP(Aw*P`=^Cdw zZwnS;{KBAJidcG@@9x_(hb^ot8E>MJ;iRSI3`z0HNYI?k6}BV9w8z3DifwLukncv* z4YIBwo+q+0Rl+1_L|8~DT*RL|kt1AVYx$yQ-6S!wH2}rysS3f2g^+}WLLGGfgV$cl zI)u7ZXQOXcT^$U-u>a6XTETftx^>e$#Ffvd$j!x2&px##u=0nUey<`sAMH{)Hsu`< zR43uegIMTFlRn{f0Dt%aqHFYHJdEykAF{cwWX=s@!Qe@x9>Zw*4h0WhFpg$7eIP|E zheyIi(}QEIytNoYklb2y`1-Ks#4bLqKgPt4R{KYfbHM+w`6>!aEdN&1*u(Y=-R0Yt zildRD41jh_m|c6d#6^2Q=;w`qB|?T*P4)=N_Q!SKt4L`lQWPJJW1GY35?P+!j*Yn2 z6VO&G}IDgBMz)IUBce4po@(sueB&h5~Q=HAt*vjcrak zFu<#X0H1xp1C5lUyInvY`;5zOEu zAa2$I1Y#Z^%Sa&)2-sRpRfiDiI6PBG*bO3nBbcA#!p&$Rjn(eQCsnf>c7j^Kcs`WW z=DUx5aHTAMmWmY)M^N+v5@P22p2m?)zUe?jTum`CIW|m*G%{UwqSuOJ>39m`78jZv z$STJ7S&sRvjIr?ZJ2fuF2p9tkrpa7%8qqZ(3!<;npw!4&A!v$Ha*Uj10CkrB8~=O? zz7;yp18-)bb4#Iil@HlC>+!#S>}aFK%52Ss4u%Y}*G*mQeegcyR83-jq8#lc&-{}g zm=?LGWzG*4tBn$w1HbT9DSMEWEVDA4J8ET_EzxN(!gW)(CRsG~(skc25o}lx7r_;QZc0wq4(i;U2ysBq zJP|r~(yM@2s`@}C`k*pLSbYz%8E7-z7~q;L$2mQc+o>Y{uPW-|k; zY5x#ecRsm1H2)*c)3BSQcd#*ZPMJb)1Q8aDM;Gxz7TQ={V`g>!s%2gUZC-Xxo5IHA zageRRA;d>m`!>L&Vd+WuPxa@sZ0`VvhOpIxb~An4QwkzH5t_r_Qy4)VHWuJiVGS!;5oUzB4hsDOyB7#Y5o#b8Cc}IJbUHk@D{>G@mY)Eq-VAbgeQTfz8tm1gPmxtU)N^>q4ttXFm%r0pE zOcwWbJj*F`;ZN~NE=W(yV`H_sd({QwqruX>t7wQ4X)}IW@nFBkO7SL~58nyeeP3ja z-A@rr=BTqdUqp05+fY^3ZV_NeBq%1vk$AH$P3{Y1Fcft`q<_qAN5QPVbB>sWSECQ- zeDNXp1ug4L@J?6zbL}w;0K`Zw$gj*~S{K;8c*b#)={KQ}Ky9dWP zSNtEZ%MD61IC^*~!V~`+uoH`_GIfNgZh&0TFU8Lmla*)7l;S#PmkZ_!GAaqcPBjB; z!HQK^3k2Y`Mw7&5!?ytz6X{B$>7JwCq3xW`hr$0@Ch>j*kV#Nxc%bnNTN!;xS=Qpy zqt})>=`EGGd=v`f!wAEX=MkH;Aui6A0(p}|BwP{eAtYM<6!lSga$}Q5vr2k0;c?FdlGtD=xP=L?gqOF z#7ty}M1Vi{rCxygTW;INH20V_Ctgx<_BE`>6r-0=R{bs@_wRLkv>*p#(V8G%|Jd+* ziFYJ2410y7@fsMS2bHni9q1nf!77}IjKaj|Yjo~SC>>2XzqLEjbXJnc-elOv)BwB9 zhzG{zhj!%-9|N=+Sj3+pEM`NqB21gaMKLt(AR7acHf%Z7M=W3VfuIWEah~d#MH+O^7m6^tW9uS7n@T-N3Vw?>D>mSTv56+7fah{6vYy zoeF3eL%byC_$h>@QY;={dMTT^GswsRl(4gmq#rIVe4$&zgp_H^5+emWnbhu}Rx2U1!h-4N~ z;C=3EL0Rx2*yYa~2LtLGIBgMh2io14rhWJbAhH&Cw3d!vEiRTmf!kUXiBA?KBV0ZL zy>utnkm+X=kjF4gZ8C`|#q^oN> zbdhSHU2R;j#n2a1jDuBqnP;BcW8!!>bvA`Xc8b|xXDx2gyIM-_!-Unq^DgCLq`<^z z>;h&Y1c~^fL4+^vi4&2q*p5V^GV$jkY;cD(1HC|}9^u&V?Syd?fE$A!i|$bR4G$nL zsEQ=6rMLoABre-vV!$mTADHM_4n5ffSEkU5AZ!vm66ifT9L9<9h0yJ9CkrbOLGygB ztCYJi{FQfp=##Wt|3kVy4sQX#&B-Wa!-8=_33(%YDkfrKsM`wG2=OQ>HC!d`*^@T3 zc>{yY!03x!H%qfeNH%D?i7A|lidJdlPo%@RBsRc7&b2fRa@@bInI zBAuk5pLNJf7XzVyA|z5tmOBr5K>F{~ZWfLgJVJ~Wh=izlDtO6Wf>7C?cdb*r2i0T0 zf~*3~y14=+Nstxl@W-B0yunnKP@*~7Fq^rI4IGkC3Y;xyr`Q4%EgqTTKVCpx30WlV zD%LC`Gz>5kk=WHVd;M}%MYc77&w1>PLz$IUrP=)iB?Z|BX&mg)2BrBur2csHqYg{O zSI%24mGi>8Cp@Q8Jz<@0wLcBDLqIOT3#xJX`F-5^M#Y25EgFuZ{Xm)L@uDCNi!~tJ zVVbn2I%Gm9dr)_OYv@12xMvRty19gnkWwT+rUlFQph1g|UZ?$g(f$)3ZcVK4@5-~b zHf!xg=ifx3axt!fduo{(R`=AQ&qa6yn)*juLy^n7BIhGMU_g=%w)M_Gh;Bhm&bU+|_#{TFG;I%m-O0n+5|j{hA9pH;Ii%nCu`BWZywdN%2;58Bg=I-XqLptZ_i|-E^QPMg$7~PGK z@_ekQ%!TDAD~>7QcZmW5B$Eup=zC=OG@nF<_JF`xTM1oAW#8Ibd*Zl#?urgsIRYI` zQ7G3|jsq}~9&(;{u3F9R;V#B7#KRJX&JsZ5J%0VhWA6CWGzRpgm-4+L1gM1;Br*A1}D;&?2)Juy_>L;{ihfvZL*= zk6>gC)2WB;#RO(ZBhw$`NOxX&N^}H-I@th@X@G*9l+>uTJo0&4%Hv}v*`X72MyrCnu++3#-*kh8>B3C>b-4RjOKtq4co!S7i->B%JqY1Q6rphQN?BQ#x;=jN~Q z-9Q73|Cy>km4k?QSdP@01!A9F^?Qk z1B4`8oR~bvNc}d^W87$p#&S8H z#=3SZ5D`cmEIsf@hdt--wH#=;Sh2GW5VVxVpSQ6~>iFv@`O!fJK{KwswtWU&UVJa3 z#h?ejpxSTr7M2rn^|`CGa%AIsBXZFFMjcqLg=*2yJMWdr`k}&{63(5MIAwr{{z5(p zx(01CCYNfd#(z-#O8WM(U3*o-dOF7adZ_!Ivetc44qEkV}P$mkrGrPzOdkJ zX5Lt7poGyM35B1rNDoX0T%{_V1JuC|i#PTp9u%#M1`z8H@#eih$3KJ*$_B}GaXEYUk2RoA)bX)h9#hDFO-4@2;w`E zF3!4El@kKw}cwHjd+T)gDxYOq{=ad@W!+ z9Q8*5zI^nIzb^vZiH&uIR0@Z5o4iGUSM-P3=d1fG;@?keM;wHkx%psr(<+gxuZmtJ z=!1CEnD1z{sp;K|4&{+P>^?1HvV7~us6Mi^O)~?iHtt;?cOcnZ zu6XY7vdEBXvKRT7MdOa&q;}A%gH^cXWE(T_j}r6BCsG@|ac1!LIa$)HF8cNeTtpV} z?@t1-mV$#}JfKW)XpzP#I3r~qp@ zGhY<|uN24;ct50oI)&BmAhja^hAYZ?jmaV7#X5?d@p`z#pogZp0;G^KANdl-1cJ;@ zY*o7)QQLH+Mc#k`t~oUj`11q5OOQkRG-8z?_PUeUN?aHZ3e2kSR8Z_eNm>A5 z=Nj*M)4PNb;6D%5QD|IYLCqlhkVZwD$9>#Xrz?Szk1YtkH=f4UPRgAxb_+|W;OFR@ zs7lWYM*0Z3f>?o=L4Jj3$$W21N*qY9YDZ$5~t!RvrT0&d66Vd62tjh)vHJ zSX|P$s54{%om*q{oaFC<=Yg(Q7T#Ij%43_G)bmOgnRte)?+cFT6m2Wkp~o{6xSkiO z&6zNda$<&(26=S32)*8>fam8eC;0KgH-~Ipc82;|j!4(>|M)Gv*B(u<))uc!2!-4Q zk8*i3K&g!a3`n&C4Avx3xk8k71Ep|q$n^nO;Y^oT`3Ss%B~YvNFl7U@!ERN2?a?<_ z`W0ZB7rH4vBuky{7C)ntGz%S&Jtd(6Ba?L##5@&06|_L#%M!-mcyI|!bvMTT-n@X! zZwRge<}1=zEK3}%(0z7n!h)FZ=p$CYgS$?eE-oh}S$DG*JXzz5)znu-tzzK|HTbeR zk1td!cllkMG?E^Ad+nUkKm24j6VVeAKQY?(bxA2J)`eo-fv_lJEK z5PQF?gw+z1ZY`4}#VpA|)DpStO31(UrQL4{;N&o?F%MRkAo{tZ&Fixq@y1c&*ki%P zR!yQCw|_)Io75ACPKk<%$QCZok#*FW%67WbMD&6IPc+9s;t|e1!~|zcVS384dk?sJ zfp0KCL+jk}7aQC*N9xBXC@l0C(g z3!Y_5%`xEvjLQxgCI6HXZoe96L_&dil8p05q09&>(KnFnXcn4jlWA`mja^r~9Yc&I z(+#z_03klqDjh+Klm}==Ro zSGTL2=)-@c%UfZo3r2bMItiX)VbP?rn(U`5Aey|ntWXM1ru)^taj>(56d>b z4?mu&h?+~Xh62tG0eT$TyM12hn7xL|T$*8#6PefJ8N_8kd%f34hh37Y-myi0qQ>q8 z$KEp9sDo9+8xbHIBQ}c?ogH-eK?wI%dwNI*cAYD|fZGD{9UA=tZ`iiT#IXx-6){V0 z0U`+Mw|t$LK3DN4h6tPXK#xA6F2cHCLGmR^$EzZXFK`~vsg;)L1YiPY5Uv4n_PLj7 ztox@@b)OP|MF7o>B*bJQFqri=Upm>9wFN^vAmiB4mic??JLd3SusqU%Xpe_E+l`6c zdik(;3+Nx26{54>L5!giLDKmLF&G?uhJ@O^jbd^GJpz^6&m206KR-H0dmY;%Kfb(F~?;Ykyj>DZjZ+VKwE9vDh zx(m{2i{~Rtv4G@5k^wvipTt13D`$tf=uMwo+I}=PmH!3ZtRMJ+#=H^frQi8@AuYHvU*!n8?{d@ zR*7iz{hT%&yVt&JE|YYyy*lqzxO6%hb=ch|0g>;WKfp#qmlyHkCJb54al3@x_xGnc zX2(aC8dv}Tp#`x67v(I?fo`JHK+~X74zO7oJeL|6Po1(qpO6Nf-$QoHy2Ge00ZOd! zlH)g->S`5q{PvkL3SH%X{1I0O5jKoyBqhGTDg6mm|?(*sspUIZf_b;fDhzQx=D zi2`NgwHy;;a;2ad`PP^421L;4PoEg-`gh8${8C9^T^pW6O`nkeFBk^f&9t#Wn0+>N zhW~f>%msY{cb(k_zQx_wLw*ma5!9<$JMSZFML_cp-Cx6ty?~DcD~);JQ7J&E1rr2W z(2!}Q<&0G`?%{oXJcUDT_TST7v(p7t2Pax1v1q%kkK3Q7 zXFVBmT}wTt9P)l#+z%KiLH|jIO6M3M^atp8^p^Ub#7^=eyc|{ja(#GrC0`}B2AJ`~ z+eqfyQ{hPdxsJ;wv@~STuZD^9{Z$P^vhdnMLlWD3Otu8EDQ z&0X?!+r&1|a6s-Dv6Ul)@W4eTVY`A#kDQBMVBl+7q8P-v4*~H>%-KL?xL=PCFgw(A zwS>|kYof2@Dhv=u4ky$}?e7peKCL;9{CO`o_3A+T1r<2>V3Ie;1brHTor{mzU%f&1 ze>z2NAJtYA11~W_H)GKiNo1!Eke=B{ zmb6cb;f9Zv=$NGqtNkeLS1(^7w zc#G}W5V9e2qXF`87$^dKaN<`4n8eDDG!HP%V55jjkD_AY105#xe5MaO17slRgWpQ^ zxb{#LAyaXet$AC!_JP|!{B&44SQa!}}gX}TrDN^br>qyY}G?4;Hf}363 z5|hUx#F`!d3l9X^J_?#d1y3*??dl!|Jv-*Rm+ZnaN6dIJEt4>c>*U)OZU2pTLi)%xm^cb3pqiZqTvt^8+6cVhoY}># zzqx?41<9O&#u15leq4SH?bco{`u}&hlfuP>XicxAP}s)Vy}UjH2>kqca!U+B3h=s71{_zuZqL0 z13bhuR1yKgy3kR!?SnjVkWQf%Q@!K2S}jkY|2H~V)k<5 zx)?xg0Qpk*5-R&6l~TX?{18nPVd}3w0eWiI6-2zWZxeM@oA8TiU z@H*sugNE{Vl;V4JQV{a|6o4~wJqCuFPQrw1MbBPXMqNoe43Vm;zI-IxW`nPQ(f7?s z-=Ec=-@_gtM82Df^zeW)rYRvLjfJ78?|#@tHGF;z({xylEE4^>Tla{IXqG&Y;()vN z`H1kAB+Xv^5~)uRBL*<*wcLYN&DRb7gY<@`BH_s)kYI+qZ?48U+A-bOrrZjRjcXpPF=OI z$tRNN3o?UYCA|i1m$6_>m4yw4>HckrujSu&OO3$>nuLpRU!ZO}7~M3T-N`=n=G+>X zZyLGSbKq+7wA4>?S&!0UO?RAxefqE`cd)C1q{LIc?H~#+cTJ&A8wjr}z#8^ZwwScW zdJ>99(3wZ*OeX)($MmL~s@`nwMW!MFg*bnFBHn8uN=NPTh}jLMsG1`*tX>WCH7UAH zZN}DVrwYZIfrRWBrbCOZw+8i_LC+r%a;lQv*g{?BEp^xzCb!{JT?d_pRTf64hq(rO zxwdLAXa3)jQo(YDJPDUD$99UjlZVrtD^=U52zBx$FnHC&Jqj$7LjZv_HR=Oq-M-Sw zLZXEM;?d=t0jvZSJfJ(QOjMUi8M;^6GR!*n5Ht#w9D!x_5aW{9#yXs_=LG8}NA5Ne zw&tX-9#-jl1T7FE-V@pJb59JwFkSl?@GJemZX%~=2=pcdh7QpkH!KN-VDK55aUGtT{ai4{1W7Hg}P#|~5MyGy^s^#vHUm>++fF>%obGK`X3 z*e3q?kK3Ou!t?&bfb@RXX`e8(Wm}!tilL+j+H~Ka39}A6y~Mxtoh8%gUv}VM9It65 zJ5Oxj%hX-qJ1x4iZ7BXssx~v|@}c$Su-Yb}rR+0Cl9mI0`>Rzfn)GN&XB02bVl@2W~g!?}*@8_a4lSo7iaSyeWc4BWuQ` z?wVFo9_}dbyev4aw-3A9n+;+!LP4(y3>F}xF}f$~_jg+l=K}B4+hJ&H0w3L!w@H_rs)9jF9L+3z=wbb@WV%lxA~ZX zl+M&C=#1U>J~X5it&)Fgu0e_?lO-`WMf&5_snR^N&oA&3_9*#x%9u+VH^xN0xeT=Bkve0|a@dc|9J5 zt+&h``6@8xQXB+ps)wVTN0J-p+26vl@r!L^9}Z_PSTnejB~r~CaJq8tViIY9t`?-Ppaz(fxn>vUkiYC0aFJM={wRvF>0fy ztmiF}y@dv}7cEt3qy@JfKC!ctbyx2zaOD!KqVq5sU_1t?=2_z6MD*KyI}#G(*=HIiQFdFaZaes5W9b z@_9pj^uvhaS9%uI8>a;J9;w(uc)wwNzy-Ci7>l#WI4e*7Z#}LB1Ns`n7V!~OCznDN zz>!s2(|7V~FVkGYD?z12Pk$9IV_mo-tyP(MBq1a+AgGxk<~5zLG&=`+4TQM_8li3` z#37gv?m}o9{v+GOJ3BDAN z_=I^XK%c@{BQ?L-?aVe$3B&5@vu^%|QCxm{is`e2A0(kz8ba6rQFsBM!t6tNJ#nr+ zY{*SdJnsDRogem@nzz+yJqZ#8ML4k=4Hj({6#d*kgvf6|`%II~)Lxv7J#I%U>O$p` zf5pX)Ht-ksI%e%KvdVi2UTof3zi}^g=1`Mslr=fY9?$XYe|l_YKoZ3^=z%WC)Jyq_ z81W1lweM_-piu8T4#^Z31RsCzQXP}Lo79B62>&1-*q4vqH9A)oN>E&z%$OgCtn_WC zOtG&g-6#gDl<|GqqtE(!U2lYJ1lI~k=9^wo>^7Tv*`jW|KhraBcF%dPZ)Wq3VD@zv zAa#EIHoPwTD$QTK{6jxeHzOui_3ZJH!+`WvaOQD{>MfJ8f{wtLHsTD%A|#`zAW@Bs zpEKsJxght2O(d)JGd05vTMn26Ko#I?WZBPU1ItaiHxSZQfGk8tNTathHZ0zmTDCyH zc6-Ll|Bb$K!vBj$AZb=TGmTq!VVFAESIUEUJ2_SWNkF#0n3#<2(RbY7aA?LsOBoaP z93P9rGfHE=#iI#+Fh=~J2en+`em)!X1mM1hnxfT>V^^;4U|Wx>Y&ct`uMySydb;Y?SlVKRByML>(b)a+3q6fcO|jN^nXVTnA(gc zd}PT@Ut2_8^s%CB`TYyE&sY%}1*V+v?}LG=VWBv)7=>@%U5%vHe7n55szhIwAsUD5__9ghQnlY)+pW+_Svh zQJ^w>fN-w_Ssr)l#g}@~#GCzZx(KQL-joHV(k?vE0MgxLYvRYeTARY+INpL(`ze6m zK#H$MEE8`1ahYj5CneG%x2f96dausGyE9X%7hUQT1vLV;*wGhAvSsRWaCxlQB_{tj zQ17U1Mliexx|^+mHhqWH5rX7YcNckv;9Z?_)!<$dH9$V;HjAGBx*a+HmIrAgUv3aX z8R`2iihN+)$d!ewmz~eMXJXmDn;j@^Rv{pZGz>t!*l+Jo!M)TcVkl~yg2h{g(8TgT zfecZ>`V-!wA)G%Cw4d>M?(AfRwE1Im=!a*|pzLo{eRqWC4#!b<|V-LVM}!M~_{w_VNipCR7prlotBm z1i*8=*IxL=T=%v1Gk%m<#QWn~(~D_pmh2fO!{5p5JBV=nKr`sCQyiL5KqkpN99>^p z8F@XfT#kezE4Y9vy#E0({n3R5dqLV~yjqi6K~whRo4W;!wD6va@H}Nj}QnrFSy6kpP5hLEWP-`;{8n>F!ZAt%=A`kWX)8%$IN$Of_Z1^4+pR`>I7j>PEiEZ{0QHu@U2XB~a~$Fo^zEmuXwA*=H(^kAr`P zeg=50B$dshG_(bp;20AZVcNc3?)SAG51&0wo39T3NssmU{Y&k>Nuv3ZhBd@w1hO(6 zkIASNmzMHLLqazX+`910Q2QnGGw>lL%Nm+mqKgn1@+k zZ;$e@^!ujs$OZt|MAyghE8r)@#3Bicl1HjoXu=T}%9$qR<6@M*ePldb9|6LE`EgU; z7?%Iqt1enry;j>(HZ=Y*SJpnEcU+hfmwX`SRv`lU#27YoRjq=F2`Oakr1&%}r8+rLP_S#BuDzVpX+5@i_GCE8zFRvz+hVmEGS){3woxBQ$Q`7ZR z)$hzw`k=D{l(TT{U+Cq6GR%+0(>$YTi{E`ue>?H%b+|%rAM7QNdghj_c?&!wCF z6TMa#z+Qt{>Y@OKJC7JKRs-Dw$`Hap@ng*Eep@>VOlPslFF+wNZ7njs2_RgSXou{k zqcnZ^`8f8Vx2;wz6S&@0DiLTN!KFhr!d?0ahf>gGHK*z1NH?} zN$YLlx8pXF=yAFmLpCp?`xIr8g>Nh&&iXYHe5d6chW^=EcmxLD@70!vY5UbRcT@41 z&5v*-BqzuDKqacrG=yeCJ|{GdO2TJkIagv=Bg z0s9>h+GXhvMw80rh0@u@REJ=QTt#q0`iJNEXUnkOkk$2~AE75jd^~TnamYS-(Hu`p z8K=yyUu84GvqTe{tBX#*b|dx1SUo%cIQ0~VhwSSq!d9^YW486#C>AbGO*Pcnl=te=sct!w*-v*o?|?I;D9k;zKh1|6dh-~tj3He`@G)utB}gC& ze{{g_L4TKo(cij=yC}2nP>J_S5Z^k#o@V`nK8A1(D#_$BKQh}-B)hGoBza@~U#?!q zsiHIt4wFs^A_PRe?$@po_9y`AZfCu)s2j;FBN6%pla`7zvU0-?rVd|uc=1tW-yh$E zY^to6QHRnX$>0l=4vpHzJ%BKE#vl500=e(Z-Z$oX!rCf1hur^D+x(+CtiOKOM9i9J z{0D;7iPQtj7*9r4mn*lZ`wHk?Zr7Lu^j!foPpL*-CVjiNdb(ky3B5L3OPoTXk03gv z4HgXH(dC2TS^~W2^ZZU8_gSkG>6A1qF+veUyepUoOucFMNt5E&1s*`LC|3C?6hsC* zF$qC!O`AX5`uzI%L}zuqvYeYNuRg`tzX3944H}=Br3@9ve-XXu2_q5HaP<9N-qVkb z3JS^7pCBL)M%tMB;~3VT?+vVULudn~eH5!`r-< znn-OjbbeaB9y9ytH|&gDO(7$Et)`P-wni#SLyCkhgXT3dQLfb7HWHAhd6fKN_<{ST z6ZkNK^hWc)J@nFEUlcs}dBp;C-G>ORc^mT#Ifn`~r-pInn>4h`;-o3QQelD=WU!3N zIC+KfXD$G78Nb3Cajyg1w;>f3*@!-4Sa|qmFrwDhzqkjx-+#naQX^gW@9BtV>4g<| z<%TjL`P!eMG>2A{|1;O-J$Urf)czNvV%7E`QxN<`86RZ1q>%RqX*h#oSMzSPu6#ol zp`e4F3-8h64)&4G)%*6H-6B`j}&)<*VMa*B_B8^gur;EdC)cc)N7!Pm6P zi4cqY(B)?E2{Js5vCN))Xx^i4yBOxExlEW=#0#eH6dp}r#vu0@p0LB%BPX}TZB2Vc*1e2bwpRSLdU?+^l0=+He=Cxg@OS|Ni z$$jlXq7wwuH+X{^H2}eYci4&qUHHUSS~PljZpYwBX!D=94Ac+C>5Z_f0iwq+fR$K} znzqi9lA6dhtohLHFCZbw3{IZiNig8rr@i}*-qb3utOeuO>X4K(!YU7;vbuRd-s9N) zVP~I9sICbb&_H($+;~4|fe{`)GOSn9^y#A5H^t%@S5xW*xT#5JkM=&>Sk58Am$S zT}l$oQzdVq!62_Ags_+e7qVgJ3s?UM+&n z&>JBY<7Y=Oq=jx@X~+PnvUaY2S|fFc-{tW=>h-NaU-TetmF`Qu(-8>JKOy-B)gys= zgDF09)Q{Ywj66SmB|pjpz9~6rsmDMw;+3XfN_q8fZpoXp~A*o8UA4UW1K1GRE@;&No)=gT<330@dq-z z!u+e7vZ`eekc2=^XPajmKyFW1zKq5tgNykos3*ILJG)xAf5RTvBHivS)sFf>^ICA` z8_RGy9?;NzPf)z~!YHgE!Pv>=HBpo%53^rxmrMe_T(6&DsGT(BwZmbb^^ht|CFUTn z+}xn$vy9QwP~owJ5GZLWQ)*%skeA}CATm#U8py+l1d<7J5k@o@;C%I`zd_Dk^h~A2 z!+(KaU7neGRuZ#cE?<=M^)Lnwq&n26qb$p6@AD(p5P!8F_qB`|O;Y{0zPITT?LfQU z5AuAO#RJ#m#w3FN74LTsd#xkTpWV<$Pdf7X0ob~5gQ5X)DkNA3l3S<;p1l!aLeV5qvrewvCL6i-u_;_b6$)P;95cs`7-i1k!_Rb=afL=+F^ z#Jm+DPVp^De-4mgrtK^Rg?Y0}B5prpdEbbQ0U!+RNRE=y_+Kd|A9Y^vfr*0yz#Ulb zh6#V1!j%=ENKdJuaunPsOBFWv=-o8h<{vVkli)Y{iqZYWA>QYtZg_))na(^ zz+0Zz5xOiT2V?|M8IiK8qMPyY!2^HYw@=m?+EpLvC?@k*1`3BZROb+@Yj=|t_h2js zZgDBl8$A#utor@5J7;fQKURJZF%0e+g0L5UJZI3b+YCyesa);_pPHYh zfR^)DRgHG$^S=c>j;a9(CK}7D&Pq-#rL0K&IyV7UerVsGBJL-g57>wYk_5k$04g+` z4vD|DDmrtaKKW305!4nad$)%RewwJ7mH{sK7==|L3mGL!VB5#=2^wCcbW1^Whz>*I}1M}nOBFjHhP9Yyn;P{zk zK=Xux2^}`+S@F5cVy8y@^cVRRx6KKhK2V-izW>0cGDeyo*I7PIznS-1h@3#%r)Gpd zuKz$PvP)$^*A)NW!*}!P#@0L5`b5A^ix#<*1~?FD#{$9(#ZDk?H;C7Q_3#QNMQ{xH z0LyYkubn%+u|FNkYnq=G|1!=Qa(ky|3>X2)Lg+1Gn5RQ=2|PA{m9-sDH(u&Lr_kJJ%$f5A|;) z9rU{+VOW@oU97?z!?w`B*2t;e$8eE%>IlGdE>;U9|FXL=%~4_?FxL025Rz(m7H>}IWROJCQ{MiGbxx$^nu;A;MiH9Fg!J1$G zH;WWE3YR-{-nsQz3y+?ZKE;$>PEY#`xGKZ(JSyG0JDPqrF7U_Gzq1z5XX_-0gazuP z&1daUb?S@#yC2Z!zyGPs(AYTE)-V3n{p0`E>mGO-DU3tSegPW3|AmY})7MM!A0xLw~=3_y7QZ`CaRP?CQV1nsH(JKTD|+dU~5{1LFcCdq`7z`a>fE0Balh zAo-wM^Z96Tfq;2&`MGh4k&(Iin0ZP1cX58#aPKcO$TE5mQg}9qC#*D*V7Pbtiy@R1 zt+-JD0NXZ*|8xU5)&0K+&V0mtlmP$=OV$0Kk3mm%u2!x(Fc5#&(hW^y?ASzvV3-5-qk^*Y-t#A{dnYl<;D(7S#|*Poz! zKso$#6zS{t?v+)#+ZoYt2Z_W8y(u9>-s33000aDga$l9^pF910`ej0pT(WIPMBH;*Z=^Ylq4GWd5Pf(e>htY02cK! zEu@f_4 zVN&EeA*8dQ-Pp+QW^DG?*G;bd{27rz$!0FPztx7Z;K-oXEGT z&@D}-bMO8g?{z7oktRuKsn)umho40Z}{sY8O;Q%ap&?Ur@6-<=FQABA+ZyK*z# zk$3@9Z7_1FTGH^lMr#EPNplIl7VUUwsZ6_F2{IL@1)1t(T$&GM}nTMK* zlP(*r*!4F=Wyu2H)!+gRt+`aJ)GQ23dSXT6Bn$o-n$`w_ac+FJHB6UG#M$RtZ-BPP z!slbxM&6bKS0);w1`*Y+j~VXdee^qAPSBDw5oQL>?xoeGq|$t-mU7eyWZ0J^xPh91 z^*H{&SXlW&QL!=`+9lS)zOCk%SQE4=ZH*)NI6P7QNHfh+>X!O(HS6m=Q`x={sH>WO z;gcgGTPWzosKL(A53+xogBv&-HA4xO-JQ<|Rn?HJ9aC&gf?~bCfzfTiY~988guE3%@z0TVl4wR+5zE{^#h_#PjJ9X@yD~m8*qKf&{D)y zRfg#x-Z8}}jIh@+^k-*_K{^VRSKCti_mh*9nkn&iQahFQz4rMjxGaspDiUqD%Qn1* zW$dY7n+<#RvCKuS%=7v%vM_#x#83kStxadEQ?0$!1{aHdjnVod2GeV$2Y_TC^+QZF2+eUxI~v(WuD1< z|JxYmmGjmlg=e8+jbt16IfMDJ_5!>-c|r6=wb&q2ClGM`1@4yP*CMh={SyC-ncgS9 zHBHJ(*e^jPAx@;M!KZOyr}FJ8IJFGt`sNnO9%ddgp6nnsk)G~vpxeT=oxmQTm_OSD zOy+zhA#2z1ZnLm2px#vJY!D8$mfNT18%`7Zg1Z7UjpC zhw819E@w_N66t{PwwZd_jb)K<2N*4;6dL`6C7i&-UVk}+Y*C8CufXU+xh{jwMjjhq z3=^^KV5A=yjb;rn%f%LSU~nJc+A_fhUf(I?OQP;8(8RSFM$*qyBCPiFJ^_0ZPo)>2 z>BSUN01_4bd`5O^|0_zCpC^?B9Tl!+l--b^w^JXJh|a|zvCjlU8oBe>rO3S6Qz|PL zxd1u;jM|tLx}2!uOS7zUD{C6^jf1MW>67T4IURCeYLk0190uUNMP`z!y@=1;Phfkc zQBw|@E!w|O0Ob?TpU+|7@B&K%9Kycn_S4H_q_>ONx)^7job#l>@emEoCpg-VlWf6= zao*`(Kn!FjWG4yqKW5IkCz%@FmoGbq!bXQimnY>DErdHkq0gQzC)U?u2x_;M+0;j_ zuX|dmrELh8+Giv73ouWsdS)s2;RG3d%)Zk`U+U`K5+oC4Kpx~AWE{9w;s!r}SJxI9 zE{+}BWfa)C6v2u21eO3{aTDZGlc61n&g)%vU*oK@LL-?TFDBoEl5Wg$l*(SL588A2 zp)aMqK9FwPSa5Q2j9TSH-2of#Je%IbKI}u_sgd#TvhM|FhXZf=oPY$**G!F`Ep#sQ z^4#iy^n-AgzB8Xr&=BexW3}kmj=woDI$p{)!kEA?S+)SXl4ENPfoZKHMBkiAR@@b&*p)Psj$*wALgG_kFuZ5udhUZEC}>L>c$#D72E zLfarLAeUrLDv z#b`eWg2ZFXwe!QyzL_syPM2KO;Glh<3#v0aD{1F3K~6we#!`tElM0nqte*^nL9BAu za=(B(b3fugIykL5@UDa;vFHkIiA$P09Hn zeX3V=rBR$7oIq!1BK=B~mur_OJiEIx@y^3Qz>}^#PGCXZShH8>yBq?zi^oek@(uY+ zW1GW@!=&uJHEu%ZFw0myQFO}ZH(~)yWU0dxH=dO2pedL_P=*d9 zLtd>Ase~W((*T5l>D03hMkfc>b{)4IoB!G9md4%sk3QywHEsv^&0Ogmi5$hxK*ez% z-Ea)ZpOBkznRd+rh5Tim>^|@t9*F66D{#^tK3hgU#rD4NlGrOpXY0u5G9PANtwO6) z9!R_)sF-ScuaW;R8?pg;jn>}NPK#`eagX^$igNBF8m06mc-mjUHn+0CcaawSL`5LT zPeZn>iw}WTS}rb|6X)xol1q#Ikb6XJgty$F=Ha# z_uxaFaiA?3l&+BDHG5eR;zk{CaU>aW=K1ur{2T0-u{W4LnH06m5FF&w4xk>8Yg|;H zB*rv)Z>*@{%wtVEXr7f$B`TK5c)(J%9}<6-;&y(PeuI~?(ftkb+vgE1{;Qw1W}6(( zeUcZMxul_4u44I>Sj#aNXVcs1ykd$QBtLm4<#D`pU?%(6TF|xpjI#~&&zgif4eild z=)@Ay_1sqtKu(aC!M{X0g;+ck*`Dfdj6=(D%`GuEx~b)D^}W86W0_PCTmRNNk5JZ zj?8gRO>vFeOu1_DnRQ}1NBbLe#5i)g{8H32Q#CB3{pz?czk9ZB6VzNvdAHr0g5Tq} zO}pdJr&-ag{??gCyfz$t zdv(>-bMtjyqkGO~E~Urke{XJzUBBZ(=P~bxB(d>192&E#<%#7c%BN1mO+x(vIAe9D z8@qcOt^Tt~9F0z4hm_bfytOo812baStUB~KWw3EZFeA>pVsXPOAB{ZJC_|Zlv=?;~ zf5~U$zu$6))73%P=El#*z8uS)9E2D|3zVlkTsq5BQ|D3aZbrg_!uTzfei?H)ACj9Y zUQ~8ehjK?UGsYj}e!J7%+06+g4SdL}`r6%s)4e(7QwGItTpwjWy-Vc{pUH8wa!PPGxY zHKIe9xhRXzJic=V=ZqvlBhd-WT75U%TK(XIg_eIkdlQ4xqG}~-YP{E1TjSMBwyejm z==zIVUt6gWfI#eRbe9{Vm67sjRdM~hR=1NYI#!LYe(y~4Z$s+eE`~0vZj#Ejl#rmo z3~~23xPIKWxtp-F-!hLC;e}lv`*%I^zEo!8oET-M>T%^K3qQVMg=Y&6>G&5twxN6b z%zO0gyQQbrXr;eiYMU*kmJN=Vug4TbRP~e7l6rs61CABhHuW~4MMXU)L0ZvVpYX9d ze!4urKCF+RjcP}+@&EWv?*2}jXkW06y3Ty<>4weEG7`=5+V(!)tKay5H@|hYBTgOo zJX#`}Fp@GceFa2l8)n8Cl1(%WZb=^13p0~Rv-miU-n)L%uWGD_Dw5oEgGkOy&n?-q zk5QuJeT>0m&t`Xe5^C9&T#5hoUJJDawn6Xh^8R zg(`H&?X&X$eE9g{qt2@Y1s$+2t)fEBx=KUW);G)%K(saDW{I)-I;*e~|nXCNE^gag~fef|JX!%!8jbY9|CpzTy90k4; zGXQsaI3N#QnnCOVyx0gVdwG4ozARf>4`=GT`!wnNaU7T3i`B=sx01Zp`Kq z;F>dF{9Ud1@#O7L-Fy?`;8FB3JnugJ?)3}6GaBidDXQh8LQ~a!B={y*o~rdJENu?Q zM}3E{GG8HO{qEf*m{rqZC(k5n27W)7%{jK=Q zX)0wYM+zEL7lGbjUUbIv4K+PN!DZWlzaBsF_4x~aG-H}p&1v?Qj%xyVANv=|I+z*` ztAgMBwEB6L+Sgo2^f{gdUcw_1((sV0Cg-c#dx2}wq0zrj4NY~8X_#Vzn1^|e0{+=} zZvU1QZ_`1NBW-tP`~a!}W?-j#9^F^;L$q$FxM(R!)8XZ2FnZd%nayLpE{2c9ANd0J zs)0w#S(t;1oiaibr~ z{rrNppf9+B@9FkR1U80R~!>%{Vq8Cm9ftdl%z zgWWYg)9dwM{T=6%#U6 zVhPS<$GkYJ(tXR%23y@olO8x3HD6-0{GDZRm(;d+dFda!4NVc;{St_uiJmbfoBx_H zBX$=XtHV2y?Bo=PCn0(B5e0R@O!J!c+=A)MOdhOP<=oyoUH+A^nfNavKPSL}z6j}m z@FAcn|F5t9l%LzCQVaaTvHl}<88WATi0)oq$YXdnk?u9>4O~PMXbX7q|NIEeBE>A# zq!~_AUi$9kRe3m{3DYgTZ`2T}%u;w{V(wyi$QW-kfyre}+f7H!y^}5yyH5fsv;Y4X zpimtYR6gC0!P+sNcRhgZV@&j)IE+ANeI+?F(LH52KG2@V1ulgg{##ss9%KMMqT(LGap*dkWI+j0Ga)`a+fah?usUA8oPXlln?tLm_ zb!N_SwJttjLKsegJ4dIt$GIhlvbiW5-Q+$Y?iIA4+ow^^09x_-eE?2LS@*>seDB+p z^Z)#DXwj6W{lCgu1fWM;7}`PW)Zi83tY6OqtgMpyF9QS-E7Thud#1UlxQ?GYj~d89 zkOOQS58`tVF9&||LfmChxB31%O8o=P?Q^`L!ElkA_m5Tu5oD2o@4>@hmzh7wW0i$K zb1kqNPU!WhgP2EU&2OA|Xg2yzm6cq(Gb~#Aw{BZ?g17OP9p-s0$0MVdqGVmtw}`LR6q0^QWtgPz?t9lGxW_@OMKV=q%ovw zAbFslm!F{b`{iGWQMYk3OiWKt%S!os3-P--n3(?4bYK2oH;x<|qv9@i9$05}?rVy?4EKmtYX(`-HRqN|$Z=wlv}a zdiT|19;M+kk^b)?HZqby zpKspaXEwi3RTyX&Vk+W#;y=saqw(HJv+~(7JSXl>`Z>RIT$Jltc+QE0TPv!go`2MHvqGl`h%2&hml~eJ}goasJ#+~*(wlVe8O1OKu3;XFN z?85I~_4~|@-Zrx4>wg$uzPld7JIek;5kmlLhuh-($)9KwK|Fk%_dOXjs>Nj^sQDk~ zWha%#mIOZU3M5dakH9B~J$dlIVeVUQ?E!4?ds%jgP)C@PNHPJcI&ws@L2CHG!ssox`i;I$%_6VDlfdE!Ci^>YR2dlBpslt z1%3>zkW@03RMI6V^w@FVsyE5vcgv6J`T4KsWu<0P`Ix3( zW`c^M&lIzFf8scNptQ+Hm4 z&^ytgV2WSB@Br1+QM+%0>zQPA1?K_MJru@&|;@mn1!9c$#$ko=nZwEq$U z(&CpK$~V6=@=%>&1pkk;NP-(;8|$RtKSjJtcxs?3s^7Tq&faS(MDYIwkjf_S1;~^{ z*%o;og+COp3OGt%l9ch>Cy4q?P^h2Hlc)FDeptdbcGwfR7QGpG`?xx1-O2`SA5h6f zW^k+B-$uft@*UASEqt_p2E^gzLK_`t6|Y;kbd*$$e15xBW9tjNl=XXhlM44s4zlin-WhuP&CN$} zjc*>Nhf~!&cP{TzO=B1g$QCIV!Adzxty_3w+%B=yC=H}mgx>?X@a3J=ZK35z z<^B)B+aNw`Q+g9VSRQ$AFQTsNe`jP`RU5%botnv=PHMP~%?lp-vDsdA7zM(w{`S)s{;hL#h0e!$MUGsQKYxEOWRHtr&vA-^q_ zaQ0*h0W*Ttn_ED7A6(I1KF-6o`jT0el_`AR`geQy-FrATqXq{*fS`%Uxq%T#S5Qm+^jd4R1-v4`SrPyITn7Go29kR+x<5P0M!ot zM%L4Ggp$BwYd-XZBdM2_1!=I}Fp~oUi8IC2IdPyF-kbO}t+Aaa zmVziIoZA>&GcB?5JazR^JSNi^DlQtm{lUa;TzN9KViavOjrNpZLg&U$0B93_OJi%R zZwAthMR556UL<1$9i(D1!Rc0?ixE`j#=GGo#qQh1s`zn>oQ6yOcJ+AjQdpajdH6r!4Qq$whMc4bKl&^(wH_b9Qt<@eAYrsFxFHe}Y$U4fhxK zNhk4rfXZJ{R`5W`(^>p~`jtNIh40gNb%^>wjH_+B{~xunQRy8)F)snUpd+EY5>fBi z+|cNkzoU|xD3@q8ENl6a^94@bRJ?bg`*FJlx)(ST{@HiC)>pu#n%>!wIH8;f{?IXiRyn};J8B(VdrK8+%rw&>5o!Sw-t6La1-D^n(z6_0K3tLU4uy$KSZM~1s?!tM_A zNqo2|U#mkaj)Pa3Z5>@RBt4)88&m{aCWyCm2{P86tE1Qu$(*kFe0sKo1}I!jv~Cj_ zY~^k-L1?kdBI)ZpbjGQO1m*BNKOD9}{uyJ$I1FR)d9$WE3i_*M1m0%2D%Kpq?bu+beoMy=;Smuld8+Bbb zy`H#C%s==Z4Q;KV$~nJRW0F1fM~_6eyjpYWU(5b9V(9Lu*!0&&=4Sv47Ulbsl>7VA z=~Ug>_J30lJr&&1P$p;zUfr*H>j29@M@rqk(qvQooyDtJE~EzlSepB!*jn3sN4DJP zg7^bJL_4L_2LTjm_oc)Tan@M4PAdxCuk61-lEpvx1N~CpJ?RcAyVUXN#kj8l$i!9J z8D}y@3Frv|fo8;x$FTdj!CPhZq+1Py#73SEB2 zR=T5q9**ILEK=1le{NGg3H58ym(GBbZt#?X$P)b~)s^L-A6ubvP3@V~I!50{Z0tPi zT4a+oH5x~g3Ld_6F`(-CE(mxA1`%b*UVx8)rT(40%9-83{ZAH4cR5PJ>(oO~-qI^6 zH)A&KbTDY=@#~)Zx_zgqLg(cJR2b{dAD{tL0wkmiqz#0=^Y6XaoMG-8SDvCREcR|t zzEw?UZZER`7G7_EguKQfuwHkPY>SHE$L<&EbGKIF^L)s{jDag)5DoguQ01(DzJM!w z=XhUED9|8}x$8=}e?ROF5aP#$nZG#vuRlV3fBperh*>gXrf14r$-UcyO-A37Oo;R! zc;#+_mi11a>8W(?hdDJ2jC^~&b-kr?P5ApL&sIeruuS8J|8L)nMnjhRjtYKM zf-LL=AGdzxO}7cth2oDE;E4JkPFxW_=)d4V1e^`B=`UUNKM%0;;QgnrRv$mnRm5CC z*gpbmsRSTA0FWXaG{ytw1pplI6ZKu!hxz}0h$~N#d&u{xv>)ra`nJ^ge;-XK`)vu| zC98-V`~FTo+~i@^|Cu_Md0*7<^#8*$Xw{hei+~1b7>Tg_CT>OcH^(#oDWI|D73Lcz zl5hDQy}h3ZACHK|kp_A&DeS->SRpKF;)&b~Gtl;JZ%VLqC-WarZ)h{=Q3jNol<{_2 z=D%C(i~M^>o>nIW#mL+$f#*He*A{xg3;|jZKNuOTAn_4&_#iO96gcMvt)YKlby8Hq9 zEi2V7>S+rhAzXYCYZwrG3xAPYyU!OvLH`B*wN$rqb`Fj_R&6W*>F>h~V1O}8l^WiI zP^>On+c#EeghF)cWU>5}JTsOGt259QDW*O9VLno8e(Y|RuC%Si<30`+aGfKGQ&8YM zTz=CH-X5PHyFjvcN2b-gmF?D~^P0KBW_$#+oI~2h%6$^&vy}qeJv#k!N`F%KIcAW-rntMg2T1;60%Llh-A6brCa27? z0fTX;t$95kW{6&AZDz0I+4`?6nD6Mg>Dz+y!#&3?OIU7>Shkc}R+P9cD=Ck;a*<)Rq;E27ueXI1zq1dS*}@CCu+e8Np_afhtfS1Qs@yy3 zzn!QmTME6(QK~W?=M3E^avsjkhaWc2SatSS_7(YEOXU)1Ojgy1PNl3ox$W=Y`tFWd zmo6-uIdm^Io-FRk;>&CKR#>{4rdVwqy*|2KwVkYBZw-YC)o}2v>=nwpb;QRio^vh2 zMif>DZj^O2XgBNSmZ5T4{@bCe;^sl?d0NeNY}9w^8hLkz_a1NJw4xjDQ(56t z^H{{@DFa3k zx{yC;?;=}j51VJ_Gw;8xyzd022O8(5mp7+0TIJFrheG#CX!B=wK3p$y9qEwWFP?MA z3loE1)2*W05TMrqcANnl#m4A+Lw|pgm z%YN?6_y+<^#H7uJcU52Kh}2W9UKV=7tvi~l)q)46qr}pjy*Ru~@+P6y?0Qrq?OL@D zMCMq(B~oP3DWAJ%0qfkcK+gjV&xt&8A#^K)(i9obHljP6)m51Wzp6!O5W07OK{n>D zcLOiL(GBMcX?rguf?VEBq4({g>^8D_aQ%07TU=R2GZjIxdQf?1f?bVU3>^2;>`KjF zG{djS?UPH5_PZKOv6p33v8yF%!w#j>ocz-NGQwZbKxenP)0er8IBKPwzF`DGJB3DI<7ih8m+Ls9u(-c98mYF#Y)s5{Ra9DnP%c#6 zfUPM)R2!!s;Ks{C%yn4?g=CXo(w;2GgRh@S9*c>$gAZ%ujWeL8Sk0y4(!C-gZDa6CW(fbe3;UZ5jVF!-*JoVV9e=-@!Lpa9Iin zb%;8d-0_$@tXzVgrLTkIj&#d*)N9>cOti-^rs-bv$(-8C;U-|8&vVZ6)zpY@Mqsf( z#^ZjDRV0FKlI>NjFXMn&DbQ=fb^`T$B#Z+i z-`by2qb?*_+G{NnoYi~yy+f5{ytE(F!KWAHw4{VmO<+9j&eG~$LH%}7sIS4%i-(xZ zninI$$?I46*>A)K9VCZnHL_KCsIoQg(8;uDab)dQ^1^4`yxkHGL{<0tW37Dk3U#kj z1{$!^=^2q1u@>-CsagvK3vOU_DU%X9alNi#Q{>M-<9?6rJ?#*{zr940>ci|!`;|F) zGh#m9K52LWRA|qAD~ynj8f@lJ+_ARSRlT@JO6qA*wpwpy&Yr_jF5b_KJpsPW(ugez zAP;LK<-rN_weh9al1z46WLC6L*zs|29-&(n9An^$ckKv&M<{P_!KS)tcC)B|pSFVR z_l$k)DwKhV^}9~w>l7m$tC6bnAL8A7h<@+(^QmfH{z5FN0dCn{P@pjfX{cmItCjdBYu(&u zOx7Slq8*d)RGg2Fyc-8&)JT=6I}zV-8kOMfu8_hUh^(Y4+hZ9_yV>SGH>M}fjkm?+ zd+043yVOGZx#m-CB@6=kUtB^EKx#!mRXXV#7^qitRr`rHmt z1?W#hbHNRn@5t|bR{mgn6bHSXk)9b*juDAI*TkNDN*i5+=JJ}ho8boD(XrGPm)+Ufs^y7vIv#Zov!6NTuuk|q*%QRa9*?r!(u8TaZ(n$e!@?%d1E zXg$b_*)I&h(+{(G5Ce8TF7LMJP~`_VWY#m8%F zNv_AxvT4WmifRSGN~)k<=LB|IcmJNehqL{g%Fu=&jMMeO;dY->)2%yolAgPXq-E2tXrMJ|ip5k6$$LM(CIi)vC zk(g3axa@Y;s#>2ki%3T8F!v-dEA>Now#bIKPP6 zTJHT+uOEZTZ-!sBux&_6Y$ptH&j$L}nnBU~okDP>+&w9N=C2Y9o{h=4lesRSRemnv z%n5&J=XuE2O#HXW`0aTya_-$HqMDtWaJvPW;RW=pI;6r;M-lG-B>{Z-T1r)1|AH2u zFmbRA@Jszz$=sbzzE^in*V^k;Qg@Dl!T(`F>SJ8ol;^csD)g>YeZ> z(Y`_E2rENktx#Jwo0o`|lpx$3TbI@GOx{m%+Htmi-VWpg90aA+{(;jk46 zj#Jr6cE%JC;%u#8UgM z?5+N;eyw74sIn9BY#SPEG#<-Cu7qH7Xy1^j?(heM5#-=3*`bjonL5Ow0M;4Vyh?1g z6)Y|{)eI6ZooarLZ?1hZUT67qjjk*G1*j@PJ#JV$b5cY`oS?MNF%Ab0M z$(_vIQ3PQZ8U9@GmNw{ot^tn+(fHsCpWWrEPW|3idxdJzNAzw4kiVe4$WMN# z4~hV-*0CfS(0NDKq3PeX?7!TQCAE$K|1v>2w71IJ>G@YbR2@r-6C&ej8GC^1nn(@%2rqAqQeK{8y$_&uRMT`FqZOpzj!1 zT=L8f(4QX{>t*q~a&I18NK9`(CvugI;>tR}qv%8V2DtBJlyAjE^p-+r)7spas`dn; zV2QMy_v({+KM?}NGzN~5d@V%?*K)CZSWWZ_BNNzJQMA--XD?a1M_?h0l7ERCD4v6< zVEk2246rR6_nBO^NUPTeadtxf8_9?l#4v;_iy`S&K2_zk?e!b{_Oxhvs{$-KIj z0rS|~!131pTH!N+{)#_hc8y}}6V!Orj8UGtR<)Krm!ia1sgwlRmug??H!jTCOW$a~ z?~6tyTLaovlXDiI$=m2F%IN-o?S-9Ypp;?XMXXOOHRY9O!HOpm>H(IA`EB`Y`V@OL zk)!L~I&ZL+Zd_}y8z?Y!N0u)@Tv4_py4q(+~2wy42n2S18Kn?;+*t z?GsKx(Q77Wqtctd`NP~ajo(!cOR9jzTib_R<8?T6QS@dC{>U>5Vy@ASlQja7<+mjN#CH(F+szspBzjDGb)-$v^De$!k6 zadFBPD-I{TAJj<4nubn&wimCt`kv5FYBBb=t~U>_*LbgFl<)XHIcEB7Gzu}{;-b}D z8b!H)l5IwdxpJ%XPw459B-9?qp7>=}BIIrY$42h!R%)3m1#wErQg7jS0({N~(n z62-{G-wO!b6BYeWroV`fxXBDk>@QyAUo+)0J@PfUlv#ShL~J1cKXUB!2XbuR#IO~) zpJE)Rf)W$;zvWjt6&Hu}R~wCC+_sCET69W(H@e1g)d5nc<)8qw^1*5e^-IguKHO;pad-J=c_#rB?Jj3s_2=2 z&uTi(Pk8p_AKO%;&}@WE8<7&D?4J!8)2GCj56ZQxqSg^jMN0NOb0WC~{r4XbVW=be zX~H0Y&v5yab-miV@)AoV|4E?GTz^9U@61(5Ak{_q$x%`u(k$8cC-kbXX}ap$wSvbx z_fSDd0{b5Fze@lxRG%cm@b^Gjb3d7R9ns1YzYak}zXi&wBXh#^0kJGKNL+{zO_sIS z5s3cv{o;Sd_Hk&5b+hD8xHZ_LH}2VEN>6`Us;k;2L4PS+h06IAsApL|e8si2%)j>w zs?=kfoB8u*3RlHPvxd|tvpk~z_`eLj!GG?*l=SNfr;y@Ut@|)P{!kMU(34=N^bnL} z7FldvCqpxD#d_9%NO6BO%2MI5AH4v+jfA-k5ywZX%w*K;G#QHpE%-_Et6U8xgk&s&Vrv^i} zPxSl~j6~m<;>^$|z53twk)Eo5+AI30t7S1I+|R{pQO958ne_F4oj6oA>eE6GVDfCs zR6m~!w7oX?Rr(?f+};y^$B6Z%1Hq@|jlx@RI!Tv$_H7f4eZCk(U&!C2wb8_RFccG> zGAnSCqR*iyP#>XBLuT^o%sSO$pcRmE!Tb_11OMEmf9ID4iSl-fuSY3~l_P^NIv^?P|&r2$$pM_W+TJHX>EnwUH zLUCY?+0pYCZu=}CP!e5c zVcvMUAoV}x!Z5DjMn%6V?U@$oI6uR6z>JL3cO)C)B>rH|_@_a+>vKvUkovCzSvK|mE@q?cm*4vP2jM-xzb!3QH?(Z#U*=X703Oo_Ff`!e(Z?V8`s1iq zSuxK1W@G|N7hra{>i+|@9|v*7i$fLjY0xG%cck0a z&H1kNjkRh)(0!cRZ;$pA^gSP&#~9~L&H4)h0Q7zAY5oeDv`hR=J-W1ZR4(7R+oT|P z{Ir8KhtmB+q>Sb#%W!z=Pqf)&0R4XP;Hn?_G1{a&CjWmzRS+EjQ3B#SLPq7A zJfLr4VJ&U_~O)1J~4f`yNj=i%ZKMIZ+>g6s>!v?KsIA4|?pj76Hh#mnE7 zjMQnLqox4^(E9%TJRV5ktiqA>>ifYDq~D9D*6N>+tNoCF#s`HEABqJZ%cs`%eYlH4 z#MLgN?rx7sNFXap-0`XVwmxZ4chx#G}Uw_J% zdCTgIh!&91_Pu>OP=fMPa+u|5)0bg=*ZjA717d3S?J>i2^I$|j#R}DggD)Q03SX&8 zfa&|^7Yw(&^!9J5P*m{uYN#3Zc#;thp?b1TO$KYSb;J&^D z^)YXx+K@rM`M7X-zo5QJ-2YGBPvVBQJ$_#g)EtCE<$r(K?D@g+;~k5|{S(5a{n1`& zpDT#Sr=MtF1>rY-f38g-0I7_kf|2u=zp|!tB*Gn)jQ53Elw91zJ1hUJW|{?4x+bT8 zGD$_xdNbCWm(dtP)mh6Yp?~51u2n1n%7+sUbWJo-kV<=?;H-~W-}2$UX5|QCKa^ba zaFNiTDur*9BlDgBP1Mry8MPG}WttxExquk?3shMB*gw1X*xrOsHpz$gmL_Pm`Q-RUSG=DTaY|rKqGz|ywvXJo}x!DOz|H= z`(MD+w4DFbG;>o-@ib`EWNPz-?8BGmr{zw1h z(7qOV{WKJZh-Ij7wT0blo+<FMlUMO`bq;W)CFux)xR{*Mtq{)}~jB4rF1K!(7UMBS{>m>2RTtC~#^;kS;02J7e{ zjYNNm-ZQ*IKS-!HXVc$1y$jTj=MD`t19U-903 z)RUMjoj`3QF2;+HAHxh`ySrIkO_t3CZz{8JEXLi_jVaqoQi2ck_I6y09j7-$HY^7V zXg@tBjr&DlFJRRLIb1Z@mHN>mZW`TY*#aPHS#r|1M&K{Q~tUiq# zVxlHIT)!i(6L$* zz4ilhg>@o6OQWwBWfpO-QUuS*cdbA$UX#sL82h-&c^~uKelOX*#_F5z)!aSSVg*%_ zgiTr7Q_Yq-FyJigKteh?y>ahR6hF?%yoL&^dVdpj9B3!<`a)R{Ez4N5i>*R9=e%Bg zE)vJs&a-(hTWtClzv(2iw$t?%q+)(sk?=YJ?6C6Q>T&X#?!~d5uKKE=>Wx!7EIxh- z1{o~~=Wyk-N*q`dGun2%=FY)4+?!}fut%yMiE$m2hPLX?r)hKt z&$kUF!swG?6V$d4(=v-smyLUt+1Qs)O(I4C0%eQ|IrN|q9cwytCdt>&9xJf+ER|n~ zqQU${i@xn?`e{7QnsC(eirvSdPwpw*sg9xQoeRGU`J!%@Wck-ZkFQz3UrXnoIOug- zQojGQMzQQ%XFUmB;c^CY@9y+h2StTgx&}64rfNzBS`du5A5kq%upbZ>mcwD}2kg(smJag@!x4EO#;7;-^m6s3;1V}4B0uNCK9((QdO2%_tKM8`l ztzbZCW7@@We=BMPsAO|}R_O;Ns?`5AB`YpS5C6kVr20QTk@@HfCI&*K@x#nNi<6W| zWUqNcg-HPAXO$%Q_7y7_Nk_QNq|cP%d9WwB`!eSTu-tVyzGVClC05o70UOUtckci4 znW;W}E~X#tX4LbM1o826`+X!V{cqc>(12iyve0>D$Ms^!QotIx8}%etjfy3Xyk3SJe4_f96&3)VyVZ zN9*sN8_eSx`&{A-*4NJk>FIuQ6qbH3|0X$`nHU|=R4y-b-BiA@&AgRZwf(gRXo3dqB3##s8m3`BDC%45yF!-_Sjq zBck^NQ)>_2uA)tUB`K`WxmHDli)&BI8Po=Hf9ukon9o@x5IH!Pw%=BM!lM2i+A8;g z|E`|l#!j@mf6HB$O8@E!aMb>@%_+@s)3|uaWF&Y9Gr+;&=}=^;?3sv1G^XQePW|;6 z(Kr17I$(|eW7*045}3dD>3{Fu3EH6RMZ5aOA$-sN{^1Oy)KAEs%dsQy^`VLgK>h+; zJ$|rjnX}@_W!X)Mf6m;oOaDRESo80H4ZBvn2CzD6l)U}aJo^56SQ>w|MDc0agaE*Q zzz?7v&i`L*p_0Hq^=1DpBmGt)M0P6Xmq`RAdP#Q#s3sn~N!b?g!n&yk+lfgytYx!17z zz4S^UJ030cFL3e8%76Q}ty3xQ5>54rPQDT1mxkj$}NV_V9EGmfHCk0!0!1o z#HiOYX$|@RbU>UU;RZiQ>D&Z>yP<;E^a}q6xUr>tMaTmAs6rXS?Y;YW!S4S^+4z6n zme$@ODt1HHl=%3fKSMCYu6&l)vPgJM)}=KZsL6-I`Ngm2UGm9qoA}NMPGO z|91p)n1;=%uw!A10%fp z_P70el;nD;{{@N6Tsh~{{8vZV6z)a>`+UdWh1(mu4_p!ccPRf|#MxN!T^r5TcwZVp zBc+;avUuMD666&UivO6c;`fBXN2pFy8HgkPYyCB)U!6$f#erXP_5KAcocN}{nDoqW ziHYEr{@q47AYl14L3?)SGBIWeL|i}JQkH=X!-H2?(fA#l?0=PRmcNag#eCltk?v~c zuN1LgFwKWd+uwxwn`-ATMd}NA&l(#4lqxga_vcEfFXU)=jxmqS)FaNFK9SaNL1_pH2;M=Y^FvtsGZEBBVKwRwNQXO0KvJKgy&v_6YZh_?@R75%#Q?ck&8^LCCzr1-yN zd_v0KI=)v|C&KBAV;J_3s7m&LfoAIe3q)qbg=@n9*CU}alYi{0V>z$m*#5*D{2?ih z9#WZq)I`A>hWoeve*;kFxW#{IOO_gTTT`pA$x|i+^ED}0{m+R1{dg*p7taX%+P83_ z@h|KoAKseu{o4o#KOty=C};P70j_h91V4~!GE;q_&;=!1&~s5890|qe#;-I zBWX(gXxIOhe@?8STbiHMsc!ts;k$~*)!uQx5JRc@0}Cm*@4qpjPRLaQk|ej-Vn zBUeyMw|nU+nD0<0U9hg7Dk|VR7_%tc=f$#rvj{l!~vUdJlEQ6E36fc8`z~2h*2x#ngqxmMD(iBxs zVa?6^0~YuTvIQaL{8{W%D#KgTOzXb1J9?rE`W!c_*hVMJCm$x$aYFSxTk0Vlv0fPs zRKZ;;dB8}zq7Ug3IzI;?rzn<9)an8E9;SL`d7`;~28?8~-OKTvA$mf2{CU4sG@4kH zG5z=2Sz&0ELIPz#>uKE>P#mqh=tW;j^e`Z&!oJUu8Vmm#h{XICV=tn*jze7v{X&d& zv;+FG)nc04mNk2c>u<6gf}?;dnIeSi4j=C(jFNDkKTUjlnV2SOLrOvG{xUfbgn*L3 zL(mT_V!{88-1~he|3F{=!Om;{+FMI_UVR7ZzO?^qlCN2nj`+@hfI28K$Nt8p=4QWU z?&teEKZuL4iUHaO^DKYD6Jx*FB=((w*o1pKG^G+VxU^Bn-)5}5-hSz6W?5>|FQLa1 z8mLchtk((&bDZngH0PV3oN}Chj`2euARvU!w?5&b)ifJ(_t!Wv2;0-2-bXNRJJnHX zdDw9Ga8CKJJ%+8`_J}{H#U-G@0U*}fTAgA7Y>-U*S$Z2OcYa4Zt^)!BS+2sM@Yp76 zNTstmBHg$Gn{{&YZz%%`WE310eEb;*4 z08llVD0qQvq>;J_;#kaOm*qyH7j+kieEAT9A>BkdoNGxpGI$RRw1yCqv@Fa!G^g&M zt9Xy-Bgo3m4G{AWRh6qD?Zy6E`238#Iwoe?43aVE<;27J2_y1U)aN=S4iBG;6&@u5 zoUIee81JJD*wk;Xvpbku#Tq8ALEnY=F*M7fdFfCl�c3nO;W;lY@xT)eNN}%-v*l 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 b59nsB3P?N^>uOhM_=R!Q`2T{)h(i4bAV-)I diff --git a/README b/README index c4852e8..d44a165 100644 --- a/README +++ b/README @@ -2,7 +2,38 @@ Clipper Change Log ============================================================ -v5.1.6 (23 May 2014) +v6.0.0 (30 October 2013) +* Added: Open path (polyline) clipping. A new 'Curves' demo + application showcases this (see the 'Curves' directory). +* Update: Major improvement in the merging of + shared/collinear edges in clip solutions (see Execute). +* Added: The IntPoint structure now has an optional 'Z' member. + (See the precompiler directive use_xyz.) +* Added: Users can now force Clipper to use 32bit integers + (via the precompiler directive use_int32) instead of using + 64bit integers. +* Modified: To accommodate open paths, the Polygon and Polygons + structures have been renamed Path and Paths respectively. The + AddPolygon and AddPolygons methods of the ClipperBase class + have been renamed AddPath and AddPaths respectively. Several + other functions have been similarly renamed. +* Modified: The PolyNode Class has a new IsOpen property. +* Modified: The Clipper class has a new ZFillFunction property. +* Added: MinkowskiSum and MinkowskiDiff functions added. +* Added: Several other new functions have been added including + PolyTreeToPaths, OpenPathsFromPolyTree and ClosedPathsFromPolyTree. +* Added: The Clipper constructor now accepts an optional InitOptions + parameter to simplify setting properties. +* Bugfixes: Numerous minor bugs have been fixed. +* Deprecated: Version 6 is a major upgrade from previous versions + and quite a number of changes have been made to exposed structures + and functions. To minimize inconvenience to existing library users, + some code has been retained and some added to maintain backward + compatibility. However, because this code will be removed in a + future update, it has been marked as deprecated and a precompiler + directive use_deprecated has been defined. + +v5.1.6 (23 May 2013) * BugFix: CleanPolygon function was buggy. * Changed: The behaviour of the 'miter' JoinType has been changed so that when squaring occurs, it's no longer @@ -12,7 +43,7 @@ v5.1.6 (23 May 2014) * Added: New OffsetPolyLines function * Update: Minor code refactoring and optimisations -v5.1.5 (5 May 2014) +v5.1.5 (5 May 2013) * Added: ForceSimple property to Clipper class * Update: Improved documentation diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 1ac3728..7ecec7f 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -10,6 +10,6 @@ ADD_LIBRARY(polyclipping clipper.cpp) # The header name clipper.hpp is too generic, so install in a subdirectory INSTALL (FILES clipper.hpp DESTINATION include/polyclipping) -INSTALL (TARGETS polyclipping LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) +INSTALL (TARGETS polyclipping ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) -SET_TARGET_PROPERTIES(polyclipping PROPERTIES VERSION 10.0.0 SOVERSION 10 ) \ No newline at end of file +SET_TARGET_PROPERTIES(polyclipping PROPERTIES VERSION 12.0.0 SOVERSION 12 ) \ No newline at end of file diff --git a/cpp/clipper.cpp b/cpp/clipper.cpp index 02a7b70..de0351e 100644 --- a/cpp/clipper.cpp +++ b/cpp/clipper.cpp @@ -1,8 +1,8 @@ /******************************************************************************* * * * Author : Angus Johnson * -* Version : 5.1.6 * -* Date : 23 May 2013 * +* Version : 6.0.0 * +* Date : 30 October 2013 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2013 * * * @@ -46,22 +46,100 @@ #include #include #include +#include namespace ClipperLib { -static long64 const loRange = 0x3FFFFFFF; -static long64 const hiRange = 0x3FFFFFFFFFFFFFFFLL; +#ifdef use_int32 + static cInt const loRange = 46340; + static cInt const hiRange = 46340; +#else + static cInt const loRange = 0x3FFFFFFF; + static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL; + typedef unsigned long long ulong64; +#endif + static double const pi = 3.141592653589793238; enum Direction { dRightToLeft, dLeftToRight }; +static int const Unassigned = -1; //edge not currently 'owning' a solution +static int const Skip = -2; //edge that would otherwise close a path + #define HORIZONTAL (-1.0E+40) #define TOLERANCE (1.0e-20) #define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE)) -#define NEAR_EQUAL(a, b) NEAR_ZERO((a) - (b)) -const char coords_range_error[] = "Coordinate exceeds range bounds."; +struct TEdge { + IntPoint Bot; + IntPoint Curr; + IntPoint Top; + IntPoint Delta; + double Dx; + PolyType PolyTyp; + EdgeSide Side; + int WindDelta; //1 or -1 depending on winding direction + int WindCnt; + int WindCnt2; //winding count of the opposite polytype + int OutIdx; + TEdge *Next; + TEdge *Prev; + TEdge *NextInLML; + TEdge *NextInAEL; + TEdge *PrevInAEL; + TEdge *NextInSEL; + TEdge *PrevInSEL; +}; + +struct IntersectNode { + TEdge *Edge1; + TEdge *Edge2; + IntPoint Pt; + IntersectNode *Next; +}; + +struct LocalMinima { + cInt Y; + TEdge *LeftBound; + TEdge *RightBound; + LocalMinima *Next; +}; + +struct OutPt; + +struct OutRec { + int Idx; + bool IsHole; + bool IsOpen; + OutRec *FirstLeft; //see comments in clipper.pas + PolyNode *PolyNd; + OutPt *Pts; + OutPt *BottomPt; +}; + +struct OutPt { + int Idx; + IntPoint Pt; + OutPt *Next; + OutPt *Prev; +}; + +struct Join { + OutPt *OutPt1; + OutPt *OutPt2; + IntPoint OffPt; +}; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +inline cInt Round(double val) +{ + if ((val < 0)) return static_cast(val - 0.5); + else return static_cast(val + 0.5); +} +//------------------------------------------------------------------------------ -inline long64 Abs(long64 val) +inline cInt Abs(cInt val) { return val < 0 ? -val : val; } @@ -97,7 +175,7 @@ int PolyTree::Total() const // PolyNode methods ... //------------------------------------------------------------------------------ -PolyNode::PolyNode(): Childs(), Parent(0), Index(0) +PolyNode::PolyNode(): Childs(), Parent(0), Index(0), m_IsOpen(false) { } //------------------------------------------------------------------------------ @@ -148,11 +226,20 @@ bool PolyNode::IsHole() const } return result; } +//------------------------------------------------------------------------------ + +bool PolyNode::IsOpen() const +{ + return m_IsOpen; +} +//------------------------------------------------------------------------------ + +#ifndef use_int32 //------------------------------------------------------------------------------ // Int128 class (enables safe math on signed 64bit integers) -// eg Int128 val1((long64)9223372036854775807); //ie 2^63 -1 -// Int128 val2((long64)9223372036854775807); +// eg Int128 val1((cInt)9223372036854775807); //ie 2^63 -1 +// Int128 val2((cInt)9223372036854775807); // Int128 val3 = val1 * val2; // val3.AsString => "85070591730234615847396907784232501249" (8.5e+37) //------------------------------------------------------------------------------ @@ -161,25 +248,25 @@ class Int128 { public: - ulong64 lo; - long64 hi; + cUInt lo; + cInt hi; - Int128(long64 _lo = 0) + Int128(cInt _lo = 0) { - lo = (ulong64)_lo; + lo = (cUInt)_lo; if (_lo < 0) hi = -1; else hi = 0; } Int128(const Int128 &val): lo(val.lo), hi(val.hi){} - Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){} + Int128(const cInt& _hi, const ulong64& _lo): lo(_lo), hi(_hi){} - long64 operator = (const long64 &val) + Int128& operator = (const cInt &val) { lo = (ulong64)val; if (val < 0) hi = -1; else hi = 0; - return val; + return *this; } bool operator == (const Int128 &val) const @@ -264,11 +351,11 @@ class Int128 while (divisor.hi >= 0 && !(divisor > dividend)) { divisor.hi <<= 1; - if ((long64)divisor.lo < 0) divisor.hi++; + if ((cInt)divisor.lo < 0) divisor.hi++; divisor.lo <<= 1; cntr.hi <<= 1; - if ((long64)cntr.lo < 0) cntr.hi++; + if ((cInt)cntr.lo < 0) cntr.hi++; cntr.lo <<= 1; } divisor.lo >>= 1; @@ -319,9 +406,11 @@ class Int128 else return (double)(lo + hi * shift64); } + }; +//------------------------------------------------------------------------------ -Int128 Int128Mul (long64 lhs, long64 rhs) +Int128 Int128Mul (cInt lhs, cInt rhs) { bool negate = (lhs < 0) != (rhs < 0); @@ -339,299 +428,274 @@ Int128 Int128Mul (long64 lhs, long64 rhs) ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi; Int128 tmp; - tmp.hi = long64(a + (c >> 32)); - tmp.lo = long64(c << 32); - tmp.lo += long64(b); + tmp.hi = cInt(a + (c >> 32)); + tmp.lo = cInt(c << 32); + tmp.lo += cInt(b); if (tmp.lo < b) tmp.hi++; if (negate) tmp = -tmp; return tmp; -} +}; +#endif //------------------------------------------------------------------------------ +// Miscellaneous global functions //------------------------------------------------------------------------------ -bool FullRangeNeeded(const Polygon &pts) -{ - bool result = false; - for (Polygon::size_type i = 0; i < pts.size(); ++i) - { - if (Abs(pts[i].X) > hiRange || Abs(pts[i].Y) > hiRange) - throw coords_range_error; - else if (Abs(pts[i].X) > loRange || Abs(pts[i].Y) > loRange) - result = true; - } - return result; -} -//------------------------------------------------------------------------------ - -bool Orientation(const Polygon &poly) +bool Orientation(const Path &poly) { return Area(poly) >= 0; } //------------------------------------------------------------------------------ -inline bool PointsEqual( const IntPoint &pt1, const IntPoint &pt2) -{ - return ( pt1.X == pt2.X && pt1.Y == pt2.Y ); -} -//------------------------------------------------------------------------------ - -double Area(const Polygon &poly) +double Area(const Path &poly) { int highI = (int)poly.size() -1; if (highI < 2) return 0; - if (FullRangeNeeded(poly)) { - Int128 a; - a = Int128Mul(poly[highI].X + poly[0].X, poly[0].Y - poly[highI].Y); - for (int i = 1; i <= highI; ++i) - a += Int128Mul(poly[i - 1].X + poly[i].X, poly[i].Y - poly[i -1].Y); - return a.AsDouble() / 2; - } - else - { - double a; - a = ((double)poly[highI].X + poly[0].X) * ((double)poly[0].Y - poly[highI].Y); - for (int i = 1; i <= highI; ++i) - a += ((double)poly[i - 1].X + poly[i].X) * ((double)poly[i].Y - poly[i - 1].Y); - return a / 2; - } + double a; + a = ((double)poly[highI].X + poly[0].X) * ((double)poly[0].Y - poly[highI].Y); + for (int i = 1; i <= highI; ++i) + a += ((double)poly[i - 1].X + poly[i].X) * ((double)poly[i].Y - poly[i - 1].Y); + return a / 2; } //------------------------------------------------------------------------------ -double Area(const OutRec &outRec, bool UseFullInt64Range) +double Area(const OutRec &outRec) { - OutPt *op = outRec.pts; + OutPt *op = outRec.Pts; if (!op) return 0; - if (UseFullInt64Range) { - Int128 a(0); - do { - a += Int128Mul(op->pt.X + op->prev->pt.X, op->prev->pt.Y - op->pt.Y); - op = op->next; - } while (op != outRec.pts); - return a.AsDouble() / 2; - } - else - { - double a = 0; - do { - a = a + (op->pt.X + op->prev->pt.X) * (op->prev->pt.Y - op->pt.Y); - op = op->next; - } while (op != outRec.pts); - return a / 2; - } + double a = 0; + do { + a = a + (double)(op->Pt.X + op->Prev->Pt.X) * (double)(op->Prev->Pt.Y - op->Pt.Y); + op = op->Next; + } while (op != outRec.Pts); + return a / 2; } //------------------------------------------------------------------------------ -bool PointIsVertex(const IntPoint &pt, OutPt *pp) +bool PointIsVertex(const IntPoint &Pt, OutPt *pp) { OutPt *pp2 = pp; do { - if (PointsEqual(pp2->pt, pt)) return true; - pp2 = pp2->next; + if (pp2->Pt == Pt) return true; + pp2 = pp2->Next; } while (pp2 != pp); return false; } //------------------------------------------------------------------------------ -bool PointOnLineSegment(const IntPoint pt, +bool PointOnLineSegment(const IntPoint Pt, const IntPoint linePt1, const IntPoint linePt2, bool UseFullInt64Range) { +#ifndef use_int32 if (UseFullInt64Range) - return ((pt.X == linePt1.X) && (pt.Y == linePt1.Y)) || - ((pt.X == linePt2.X) && (pt.Y == linePt2.Y)) || - (((pt.X > linePt1.X) == (pt.X < linePt2.X)) && - ((pt.Y > linePt1.Y) == (pt.Y < linePt2.Y)) && - ((Int128Mul((pt.X - linePt1.X), (linePt2.Y - linePt1.Y)) == - Int128Mul((linePt2.X - linePt1.X), (pt.Y - linePt1.Y))))); + return ((Pt.X == linePt1.X) && (Pt.Y == linePt1.Y)) || + ((Pt.X == linePt2.X) && (Pt.Y == linePt2.Y)) || + (((Pt.X > linePt1.X) == (Pt.X < linePt2.X)) && + ((Pt.Y > linePt1.Y) == (Pt.Y < linePt2.Y)) && + ((Int128Mul((Pt.X - linePt1.X), (linePt2.Y - linePt1.Y)) == + Int128Mul((linePt2.X - linePt1.X), (Pt.Y - linePt1.Y))))); else - return ((pt.X == linePt1.X) && (pt.Y == linePt1.Y)) || - ((pt.X == linePt2.X) && (pt.Y == linePt2.Y)) || - (((pt.X > linePt1.X) == (pt.X < linePt2.X)) && - ((pt.Y > linePt1.Y) == (pt.Y < linePt2.Y)) && - ((pt.X - linePt1.X) * (linePt2.Y - linePt1.Y) == - (linePt2.X - linePt1.X) * (pt.Y - linePt1.Y))); +#endif + return ((Pt.X == linePt1.X) && (Pt.Y == linePt1.Y)) || + ((Pt.X == linePt2.X) && (Pt.Y == linePt2.Y)) || + (((Pt.X > linePt1.X) == (Pt.X < linePt2.X)) && + ((Pt.Y > linePt1.Y) == (Pt.Y < linePt2.Y)) && + ((Pt.X - linePt1.X) * (linePt2.Y - linePt1.Y) == + (linePt2.X - linePt1.X) * (Pt.Y - linePt1.Y))); } //------------------------------------------------------------------------------ -bool PointOnPolygon(const IntPoint pt, OutPt *pp, bool UseFullInt64Range) +bool PointOnPolygon(const IntPoint Pt, OutPt *pp, bool UseFullInt64Range) { OutPt *pp2 = pp; while (true) { - if (PointOnLineSegment(pt, pp2->pt, pp2->next->pt, UseFullInt64Range)) + if (PointOnLineSegment(Pt, pp2->Pt, pp2->Next->Pt, UseFullInt64Range)) return true; - pp2 = pp2->next; + pp2 = pp2->Next; if (pp2 == pp) break; } return false; } //------------------------------------------------------------------------------ -bool PointInPolygon(const IntPoint &pt, OutPt *pp, bool UseFullInt64Range) +bool PointInPolygon(const IntPoint &Pt, OutPt *pp, bool UseFullInt64Range) { OutPt *pp2 = pp; bool result = false; +#ifndef use_int32 if (UseFullInt64Range) { do { - if ((((pp2->pt.Y <= pt.Y) && (pt.Y < pp2->prev->pt.Y)) || - ((pp2->prev->pt.Y <= pt.Y) && (pt.Y < pp2->pt.Y))) && - Int128(pt.X - pp2->pt.X) < - Int128Mul(pp2->prev->pt.X - pp2->pt.X, pt.Y - pp2->pt.Y) / - Int128(pp2->prev->pt.Y - pp2->pt.Y)) - result = !result; - pp2 = pp2->next; + if (((pp2->Pt.Y > Pt.Y) != (pp2->Prev->Pt.Y > Pt.Y)) && + (Int128(Pt.X - pp2->Pt.X) < + Int128Mul(pp2->Prev->Pt.X - pp2->Pt.X, Pt.Y - pp2->Pt.Y) / + Int128(pp2->Prev->Pt.Y - pp2->Pt.Y))) result = !result; + pp2 = pp2->Next; } while (pp2 != pp); + return result; } - else +#endif + do { - do - { - if ((((pp2->pt.Y <= pt.Y) && (pt.Y < pp2->prev->pt.Y)) || - ((pp2->prev->pt.Y <= pt.Y) && (pt.Y < pp2->pt.Y))) && - (pt.X < (pp2->prev->pt.X - pp2->pt.X) * (pt.Y - pp2->pt.Y) / - (pp2->prev->pt.Y - pp2->pt.Y) + pp2->pt.X )) result = !result; - pp2 = pp2->next; - } - while (pp2 != pp); + //http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html + if (((pp2->Pt.Y > Pt.Y) != (pp2->Prev->Pt.Y > Pt.Y)) && + ((Pt.X - pp2->Pt.X) < (pp2->Prev->Pt.X - pp2->Pt.X) * (Pt.Y - pp2->Pt.Y) / + (pp2->Prev->Pt.Y - pp2->Pt.Y))) result = !result; + pp2 = pp2->Next; } + while (pp2 != pp); return result; } //------------------------------------------------------------------------------ bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range) { +#ifndef use_int32 if (UseFullInt64Range) - return Int128Mul(e1.deltaY, e2.deltaX) == Int128Mul(e1.deltaX, e2.deltaY); - else return e1.deltaY * e2.deltaX == e1.deltaX * e2.deltaY; + return Int128Mul(e1.Delta.Y, e2.Delta.X) == Int128Mul(e1.Delta.X, e2.Delta.Y); + else +#endif + return e1.Delta.Y * e2.Delta.X == e1.Delta.X * e2.Delta.Y; } //------------------------------------------------------------------------------ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3, bool UseFullInt64Range) { +#ifndef use_int32 if (UseFullInt64Range) return Int128Mul(pt1.Y-pt2.Y, pt2.X-pt3.X) == Int128Mul(pt1.X-pt2.X, pt2.Y-pt3.Y); - else return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y); + else +#endif + return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y); } //------------------------------------------------------------------------------ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range) { +#ifndef use_int32 if (UseFullInt64Range) return Int128Mul(pt1.Y-pt2.Y, pt3.X-pt4.X) == Int128Mul(pt1.X-pt2.X, pt3.Y-pt4.Y); - else return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y); + else +#endif + return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y); +} +//------------------------------------------------------------------------------ + +inline bool IsHorizontal(TEdge &e) +{ + return e.Delta.Y == 0; } //------------------------------------------------------------------------------ -double GetDx(const IntPoint pt1, const IntPoint pt2) +inline double GetDx(const IntPoint pt1, const IntPoint pt2) { return (pt1.Y == pt2.Y) ? HORIZONTAL : (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y); } //--------------------------------------------------------------------------- -void SetDx(TEdge &e) +inline void SetDx(TEdge &e) { - e.deltaX = (e.xtop - e.xbot); - e.deltaY = (e.ytop - e.ybot); + e.Delta.X = (e.Top.X - e.Bot.X); + e.Delta.Y = (e.Top.Y - e.Bot.Y); - if (e.deltaY == 0) e.dx = HORIZONTAL; - else e.dx = (double)(e.deltaX) / e.deltaY; + if (e.Delta.Y == 0) e.Dx = HORIZONTAL; + else e.Dx = (double)(e.Delta.X) / e.Delta.Y; } //--------------------------------------------------------------------------- -void SwapSides(TEdge &edge1, TEdge &edge2) -{ - EdgeSide side = edge1.side; - edge1.side = edge2.side; - edge2.side = side; -} -//------------------------------------------------------------------------------ - -void SwapPolyIndexes(TEdge &edge1, TEdge &edge2) +inline void SwapSides(TEdge &Edge1, TEdge &Edge2) { - int outIdx = edge1.outIdx; - edge1.outIdx = edge2.outIdx; - edge2.outIdx = outIdx; + EdgeSide Side = Edge1.Side; + Edge1.Side = Edge2.Side; + Edge2.Side = Side; } //------------------------------------------------------------------------------ -inline long64 Round(double val) +inline void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2) { - return (val < 0) ? static_cast(val - 0.5) : static_cast(val + 0.5); + int OutIdx = Edge1.OutIdx; + Edge1.OutIdx = Edge2.OutIdx; + Edge2.OutIdx = OutIdx; } //------------------------------------------------------------------------------ -long64 TopX(TEdge &edge, const long64 currentY) +inline cInt TopX(TEdge &edge, const cInt currentY) { - return ( currentY == edge.ytop ) ? - edge.xtop : edge.xbot + Round(edge.dx *(currentY - edge.ybot)); + return ( currentY == edge.Top.Y ) ? + edge.Top.X : edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y)); } //------------------------------------------------------------------------------ -bool IntersectPoint(TEdge &edge1, TEdge &edge2, +bool IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip, bool UseFullInt64Range) { +#ifdef use_xyz + ip.Z = 0; +#endif double b1, b2; - if (SlopesEqual(edge1, edge2, UseFullInt64Range)) + //nb: with very large coordinate values, it's possible for SlopesEqual() to + //return false but for the edge.Dx value be equal due to double precision rounding. + if (SlopesEqual(Edge1, Edge2, UseFullInt64Range) || Edge1.Dx == Edge2.Dx) { - if (edge2.ybot > edge1.ybot) ip.Y = edge2.ybot; - else ip.Y = edge1.ybot; + if (Edge2.Bot.Y > Edge1.Bot.Y) ip.Y = Edge2.Bot.Y; + else ip.Y = Edge1.Bot.Y; return false; } - else if (NEAR_ZERO(edge1.dx)) + else if (Edge1.Delta.X == 0) { - ip.X = edge1.xbot; - if (NEAR_EQUAL(edge2.dx, HORIZONTAL)) - ip.Y = edge2.ybot; + ip.X = Edge1.Bot.X; + if (IsHorizontal(Edge2)) + ip.Y = Edge2.Bot.Y; else { - b2 = edge2.ybot - (edge2.xbot / edge2.dx); - ip.Y = Round(ip.X / edge2.dx + b2); + b2 = Edge2.Bot.Y - (Edge2.Bot.X / Edge2.Dx); + ip.Y = Round(ip.X / Edge2.Dx + b2); } } - else if (NEAR_ZERO(edge2.dx)) + else if (Edge2.Delta.X == 0) { - ip.X = edge2.xbot; - if (NEAR_EQUAL(edge1.dx, HORIZONTAL)) - ip.Y = edge1.ybot; + ip.X = Edge2.Bot.X; + if (IsHorizontal(Edge1)) + ip.Y = Edge1.Bot.Y; else { - b1 = edge1.ybot - (edge1.xbot / edge1.dx); - ip.Y = Round(ip.X / edge1.dx + b1); + b1 = Edge1.Bot.Y - (Edge1.Bot.X / Edge1.Dx); + ip.Y = Round(ip.X / Edge1.Dx + b1); } } else { - b1 = edge1.xbot - edge1.ybot * edge1.dx; - b2 = edge2.xbot - edge2.ybot * edge2.dx; - double q = (b2-b1) / (edge1.dx - edge2.dx); + b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx; + b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx; + double q = (b2-b1) / (Edge1.Dx - Edge2.Dx); ip.Y = Round(q); - if (std::fabs(edge1.dx) < std::fabs(edge2.dx)) - ip.X = Round(edge1.dx * q + b1); + if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx)) + ip.X = Round(Edge1.Dx * q + b1); else - ip.X = Round(edge2.dx * q + b2); + ip.X = Round(Edge2.Dx * q + b2); } - if (ip.Y < edge1.ytop || ip.Y < edge2.ytop) + if (ip.Y < Edge1.Top.Y || ip.Y < Edge2.Top.Y) { - if (edge1.ytop > edge2.ytop) + if (Edge1.Top.Y > Edge2.Top.Y) { - ip.X = edge1.xtop; - ip.Y = edge1.ytop; - return TopX(edge2, edge1.ytop) < edge1.xtop; + ip.Y = Edge1.Top.Y; + ip.X = TopX(Edge2, Edge1.Top.Y); + return ip.X < Edge1.Top.X; } else { - ip.X = edge2.xtop; - ip.Y = edge2.ytop; - return TopX(edge1, edge2.ytop) > edge2.xtop; + ip.Y = Edge2.Top.Y; + ip.X = TopX(Edge1, Edge2.Top.Y); + return ip.X > Edge2.Top.X; } } else @@ -645,9 +709,9 @@ void ReversePolyPtLinks(OutPt *pp) OutPt *pp1, *pp2; pp1 = pp; do { - pp2 = pp1->next; - pp1->next = pp1->prev; - pp1->prev = pp2; + pp2 = pp1->Next; + pp1->Next = pp1->Prev; + pp1->Prev = pp2; pp1 = pp2; } while( pp1 != pp ); } @@ -656,53 +720,189 @@ void ReversePolyPtLinks(OutPt *pp) void DisposeOutPts(OutPt*& pp) { if (pp == 0) return; - pp->prev->next = 0; + pp->Prev->Next = 0; while( pp ) { OutPt *tmpPp = pp; - pp = pp->next; + pp = pp->Next; delete tmpPp; } } //------------------------------------------------------------------------------ -void InitEdge(TEdge *e, TEdge *eNext, - TEdge *ePrev, const IntPoint &pt, PolyType polyType) +inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt) { std::memset(e, 0, sizeof(TEdge)); - e->next = eNext; - e->prev = ePrev; - e->xcurr = pt.X; - e->ycurr = pt.Y; - if (e->ycurr >= e->next->ycurr) - { - e->xbot = e->xcurr; - e->ybot = e->ycurr; - e->xtop = e->next->xcurr; - e->ytop = e->next->ycurr; - e->windDelta = 1; + e->Next = eNext; + e->Prev = ePrev; + e->Curr = Pt; + e->OutIdx = Unassigned; +} +//------------------------------------------------------------------------------ + +void InitEdge2(TEdge& e, PolyType Pt) +{ + if (e.Curr.Y >= e.Next->Curr.Y) + { + e.Bot = e.Curr; + e.Top = e.Next->Curr; } else { - e->xtop = e->xcurr; - e->ytop = e->ycurr; - e->xbot = e->next->xcurr; - e->ybot = e->next->ycurr; - e->windDelta = -1; + e.Top = e.Curr; + e.Bot = e.Next->Curr; + } + SetDx(e); + e.PolyTyp = Pt; +} +//------------------------------------------------------------------------------ + +TEdge* RemoveEdge(TEdge* e) +{ + //removes e from double_linked_list (but without removing from memory) + e->Prev->Next = e->Next; + e->Next->Prev = e->Prev; + TEdge* result = e->Next; + e->Prev = 0; //flag as removed (see ClipperBase.Clear) + return result; +} +//------------------------------------------------------------------------------ + +TEdge* GetLastHorz(TEdge* Edge) +{ + TEdge* result = Edge; + while (result->OutIdx != Skip && result->Next != Edge && IsHorizontal(*result->Next)) + result = result->Next; + return result; +} +//------------------------------------------------------------------------------ + +bool SharedVertWithPrevAtTop(TEdge* Edge) +{ + TEdge* E = Edge; + bool result = true; + while (E->Prev != Edge) + { + if (E->Top == E->Prev->Top) + { + if (E->Bot == E->Prev->Bot) + {E = E->Prev; continue;} + else result = true; + } + else result = false; + break; + } + while (E != Edge) + { + result = !result; + E = E->Next; + } + return result; +} +//------------------------------------------------------------------------------ + +bool SharedVertWithNextIsBot(TEdge* Edge) +{ + bool result = true; + TEdge* E = Edge; + while (E->Prev != Edge) + { + bool A = (E->Next->Bot == E->Bot); + bool B = (E->Prev->Bot == E->Bot); + if (A != B) + { + result = A; + break; + } + A = (E->Next->Top == E->Top); + B = (E->Prev->Top == E->Top); + if (A != B) + { + result = B; + break; + } + E = E->Prev; + } + while (E != Edge) + { + result = !result; + E = E->Next; + } + return result; +} +//------------------------------------------------------------------------------ + +bool MoreBelow(TEdge* Edge) +{ + //Edge is Skip heading down. + TEdge* E = Edge; + if (IsHorizontal(*E)) + { + while (IsHorizontal(*E->Next)) E = E->Next; + return E->Next->Bot.Y > E->Bot.Y; + } else if (IsHorizontal(*E->Next)) + { + while (IsHorizontal(*E->Next)) E = E->Next; + return E->Next->Bot.Y > E->Bot.Y; + } + else return (E->Bot == E->Next->Top); +} +//------------------------------------------------------------------------------ + +bool JustBeforeLocMin(TEdge* Edge) +{ + //Edge is Skip and was heading down. + TEdge*E = Edge; + if (IsHorizontal(*E)) + { + while (IsHorizontal(*E->Next)) E = E->Next; + return E->Next->Top.Y < E->Bot.Y; + } + else return SharedVertWithNextIsBot(E); +} +//------------------------------------------------------------------------------ + +bool MoreAbove(TEdge* Edge) +{ + if (IsHorizontal(*Edge)) + { + Edge = GetLastHorz(Edge); + return (Edge->Next->Top.Y < Edge->Top.Y); + } else if (IsHorizontal(*Edge->Next)) + { + Edge = GetLastHorz(Edge->Next); + return (Edge->Next->Top.Y < Edge->Top.Y); + } + else + return (Edge->Next->Top.Y < Edge->Top.Y); +} +//------------------------------------------------------------------------------ + +bool AllHorizontal(TEdge* Edge) +{ + if (!IsHorizontal(*Edge)) return false; + TEdge* E = Edge->Next; + while (E != Edge) + { + if (!IsHorizontal(*E)) return false; + else E = E->Next; } - SetDx(*e); - e->polyType = polyType; - e->outIdx = -1; + return true; } //------------------------------------------------------------------------------ -inline void SwapX(TEdge &e) +inline void ReverseHorizontal(TEdge &e) { - //swap horizontal edges' top and bottom x's so they follow the natural + //swap horizontal edges' Top and Bottom x's so they follow the natural //progression of the bounds - ie so their xbots will align with the //adjoining lower edge. [Helpful in the ProcessHorizontal() method.] - e.xcurr = e.xtop; - e.xtop = e.xbot; - e.xbot = e.xcurr; + cInt tmp = e.Top.X; + e.Top.X = e.Bot.X; + e.Bot.X = tmp; +#ifdef use_xyz + tmp = e.Top.Z; + e.Top.Z = e.Bot.Z; + e.Bot.Z = tmp; +#endif } //------------------------------------------------------------------------------ @@ -717,7 +917,7 @@ void SwapPoints(IntPoint &pt1, IntPoint &pt2) bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a, IntPoint pt2b, IntPoint &pt1, IntPoint &pt2) { - //precondition: segments are colinear. + //precondition: segments are Collinear. if (Abs(pt1a.X - pt1b.X) > Abs(pt1a.Y - pt1b.Y)) { if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b); @@ -738,19 +938,19 @@ bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a, bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2) { - OutPt *p = btmPt1->prev; - while (PointsEqual(p->pt, btmPt1->pt) && (p != btmPt1)) p = p->prev; - double dx1p = std::fabs(GetDx(btmPt1->pt, p->pt)); - p = btmPt1->next; - while (PointsEqual(p->pt, btmPt1->pt) && (p != btmPt1)) p = p->next; - double dx1n = std::fabs(GetDx(btmPt1->pt, p->pt)); - - p = btmPt2->prev; - while (PointsEqual(p->pt, btmPt2->pt) && (p != btmPt2)) p = p->prev; - double dx2p = std::fabs(GetDx(btmPt2->pt, p->pt)); - p = btmPt2->next; - while (PointsEqual(p->pt, btmPt2->pt) && (p != btmPt2)) p = p->next; - double dx2n = std::fabs(GetDx(btmPt2->pt, p->pt)); + OutPt *p = btmPt1->Prev; + while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Prev; + double dx1p = std::fabs(GetDx(btmPt1->Pt, p->Pt)); + p = btmPt1->Next; + while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Next; + double dx1n = std::fabs(GetDx(btmPt1->Pt, p->Pt)); + + p = btmPt2->Prev; + while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Prev; + double dx2p = std::fabs(GetDx(btmPt2->Pt, p->Pt)); + p = btmPt2->Next; + while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next; + double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt)); return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); } //------------------------------------------------------------------------------ @@ -758,35 +958,35 @@ bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2) OutPt* GetBottomPt(OutPt *pp) { OutPt* dups = 0; - OutPt* p = pp->next; + OutPt* p = pp->Next; while (p != pp) { - if (p->pt.Y > pp->pt.Y) + if (p->Pt.Y > pp->Pt.Y) { pp = p; dups = 0; } - else if (p->pt.Y == pp->pt.Y && p->pt.X <= pp->pt.X) + else if (p->Pt.Y == pp->Pt.Y && p->Pt.X <= pp->Pt.X) { - if (p->pt.X < pp->pt.X) + if (p->Pt.X < pp->Pt.X) { dups = 0; pp = p; } else { - if (p->next != pp && p->prev != pp) dups = p; + if (p->Next != pp && p->Prev != pp) dups = p; } } - p = p->next; + p = p->Next; } if (dups) { - //there appears to be at least 2 vertices at bottomPt so ... + //there appears to be at least 2 vertices at BottomPt so ... while (dups != p) { if (!FirstIsBottomPt(p, dups)) pp = dups; - dups = dups->next; - while (!PointsEqual(dups->pt, pp->pt)) dups = dups->next; + dups = dups->Next; + while (dups->Pt != pp->Pt) dups = dups->Next; } } return pp; @@ -796,52 +996,70 @@ OutPt* GetBottomPt(OutPt *pp) bool FindSegment(OutPt* &pp, bool UseFullInt64Range, IntPoint &pt1, IntPoint &pt2) { - //outPt1 & outPt2 => the overlap segment (if the function returns true) + //OutPt1 & OutPt2 => the overlap segment (if the function returns true) if (!pp) return false; OutPt* pp2 = pp; IntPoint pt1a = pt1, pt2a = pt2; do { - if (SlopesEqual(pt1a, pt2a, pp->pt, pp->prev->pt, UseFullInt64Range) && - SlopesEqual(pt1a, pt2a, pp->pt, UseFullInt64Range) && - GetOverlapSegment(pt1a, pt2a, pp->pt, pp->prev->pt, pt1, pt2)) + if (SlopesEqual(pt1a, pt2a, pp->Pt, pp->Prev->Pt, UseFullInt64Range) && + SlopesEqual(pt1a, pt2a, pp->Pt, UseFullInt64Range) && + GetOverlapSegment(pt1a, pt2a, pp->Pt, pp->Prev->Pt, pt1, pt2)) return true; - pp = pp->next; + pp = pp->Next; } while (pp != pp2); return false; } //------------------------------------------------------------------------------ -bool Pt3IsBetweenPt1AndPt2(const IntPoint pt1, +bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3) { - if (PointsEqual(pt1, pt3) || PointsEqual(pt2, pt3)) return true; - else if (pt1.X != pt2.X) return (pt1.X < pt3.X) == (pt3.X < pt2.X); - else return (pt1.Y < pt3.Y) == (pt3.Y < pt2.Y); + if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2)) + return false; + else if (pt1.X != pt3.X) + return (pt2.X > pt1.X) == (pt2.X < pt3.X); + else + return (pt2.Y > pt1.Y) == (pt2.Y < pt3.Y); } //------------------------------------------------------------------------------ -OutPt* InsertPolyPtBetween(OutPt* p1, OutPt* p2, const IntPoint pt) +OutPt* InsertPolyPtBetween(OutPt* p1, OutPt* p2, const IntPoint Pt) { if (p1 == p2) throw "JoinError"; OutPt* result = new OutPt; - result->pt = pt; - if (p2 == p1->next) + result->Pt = Pt; + if (p2 == p1->Next) { - p1->next = result; - p2->prev = result; - result->next = p2; - result->prev = p1; + p1->Next = result; + p2->Prev = result; + result->Next = p2; + result->Prev = p1; } else { - p2->next = result; - p1->prev = result; - result->next = p1; - result->prev = p2; + p2->Next = result; + p1->Prev = result; + result->Next = p1; + result->Prev = p2; } return result; } +//------------------------------------------------------------------------------ + +bool HorzSegmentsOverlap(const IntPoint& pt1a, const IntPoint& pt1b, + const IntPoint& pt2a, const IntPoint& pt2b) +{ + //precondition: both segments are horizontal + if ((pt1a.X > pt2a.X) == (pt1a.X < pt2b.X)) return true; + else if ((pt1b.X > pt2a.X) == (pt1b.X < pt2b.X)) return true; + else if ((pt2a.X > pt1a.X) == (pt2a.X < pt1b.X)) return true; + else if ((pt2b.X > pt1a.X) == (pt2b.X < pt1b.X)) return true; + else if ((pt1a.X == pt2a.X) && (pt1b.X == pt2b.X)) return true; + else if ((pt1a.X == pt2b.X) && (pt1b.X == pt2a.X)) return true; + else return false; +} + //------------------------------------------------------------------------------ // ClipperBase class methods ... @@ -851,7 +1069,7 @@ ClipperBase::ClipperBase() //constructor { m_MinimaList = 0; m_CurrentLM = 0; - m_UseFullRange = true; + m_UseFullRange = false; } //------------------------------------------------------------------------------ @@ -861,107 +1079,178 @@ ClipperBase::~ClipperBase() //destructor } //------------------------------------------------------------------------------ -void RangeTest(const IntPoint& pt, long64& maxrange) +void RangeTest(const IntPoint& Pt, bool& useFullRange) { - if (Abs(pt.X) > maxrange) + if (useFullRange) { - if (Abs(pt.X) > hiRange) - throw coords_range_error; - else maxrange = hiRange; + if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) + throw "Coordinate outside allowed range"; } - if (Abs(pt.Y) > maxrange) + else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) { - if (Abs(pt.Y) > hiRange) - throw coords_range_error; - else maxrange = hiRange; + useFullRange = true; + RangeTest(Pt, useFullRange); } } //------------------------------------------------------------------------------ -bool ClipperBase::AddPolygon(const Polygon &pg, PolyType polyType) +bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) { - int len = (int)pg.size(); - if (len < 3) return false; +#ifdef use_lines + if (!Closed && PolyTyp == ptClip) + throw clipperException("AddPath: Open paths must be subject."); +#else + if (!Closed) + throw clipperException("AddPath: Open paths have been disabled."); +#endif - long64 maxVal; - if (m_UseFullRange) maxVal = hiRange; else maxVal = loRange; - RangeTest(pg[0], maxVal); + int highI = (int)pg.size() -1; + bool ClosedOrSemiClosed = (highI > 0) && (Closed || (pg[0] == pg[highI])); + while (highI > 0 && (pg[highI] == pg[0])) --highI; + while (highI > 0 && (pg[highI] == pg[highI -1])) --highI; + if ((Closed && highI < 2) || (!Closed && highI < 1)) return false; - Polygon p(len); - p[0] = pg[0]; - int j = 0; + //create a new edge array ... + TEdge *edges = new TEdge [highI +1]; - for (int i = 0; i < len; ++i) + //1. Basic initialization of Edges ... + try { - RangeTest(pg[i], maxVal); - - if (i == 0 || PointsEqual(p[j], pg[i])) continue; - else if (j > 0 && SlopesEqual(p[j-1], p[j], pg[i], m_UseFullRange)) + edges[1].Curr = pg[1]; + RangeTest(pg[0], m_UseFullRange); + RangeTest(pg[highI], m_UseFullRange); + InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]); + InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]); + for (int i = highI - 1; i >= 1; --i) { - if (PointsEqual(p[j-1], pg[i])) j--; - } else j++; - p[j] = pg[i]; + RangeTest(pg[i], m_UseFullRange); + InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]); + } + } + catch(...) + { + delete [] edges; + return false; //almost certainly a vertex has exceeded range } - if (j < 2) return false; - len = j+1; - while (len > 2) + TEdge *eStart = &edges[0]; + if (!ClosedOrSemiClosed) eStart->Prev->OutIdx = Skip; + + //2. Remove duplicate vertices, and collinear edges (when closed) ... + TEdge *E = eStart, *eLoopStop = eStart; + for (;;) { - //nb: test for point equality before testing slopes ... - if (PointsEqual(p[j], p[0])) j--; - else if (PointsEqual(p[0], p[1]) || - SlopesEqual(p[j], p[0], p[1], m_UseFullRange)) - p[0] = p[j--]; - else if (SlopesEqual(p[j-1], p[j], p[0], m_UseFullRange)) j--; - else if (SlopesEqual(p[0], p[1], p[2], m_UseFullRange)) + if ((E->Curr == E->Next->Curr)) { - for (int i = 2; i <= j; ++i) p[i-1] = p[i]; - j--; + if (E == eStart) eStart = E->Next; + E = RemoveEdge(E); + eLoopStop = E; + continue; } - else break; - len--; + if (E->Prev == E->Next) + break; //only two vertices + else if ((ClosedOrSemiClosed || + (E->Prev->OutIdx != Skip && E->OutIdx != Skip && + E->Next->OutIdx != Skip)) && + SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange)) + { + //All collinear edges are allowed for open paths but in closed paths + //inner vertices of adjacent collinear edges are removed. However if the + //PreserveCollinear property has been enabled, only overlapping collinear + //edges (ie spikes) are removed from closed paths. + if (Closed && (!m_PreserveCollinear || + !Pt2IsBetweenPt1AndPt3(E->Prev->Curr, E->Curr, E->Next->Curr))) + { + if (E == eStart) eStart = E->Next; + E = RemoveEdge(E); + E = E->Prev; + eLoopStop = E; + continue; + } + } + E = E->Next; + if (E == eLoopStop) break; } - if (len < 3) return false; - //create a new edge array ... - TEdge *edges = new TEdge [len]; + if ((!Closed && (E == E->Next)) || (Closed && (E->Prev == E->Next))) + { + delete [] edges; + return false; + } m_edges.push_back(edges); - //convert vertices to a double-linked-list of edges and initialize ... - edges[0].xcurr = p[0].X; - edges[0].ycurr = p[0].Y; - InitEdge(&edges[len-1], &edges[0], &edges[len-2], p[len-1], polyType); - for (int i = len-2; i > 0; --i) - InitEdge(&edges[i], &edges[i+1], &edges[i-1], p[i], polyType); - InitEdge(&edges[0], &edges[1], &edges[len-1], p[0], polyType); - - //reset xcurr & ycurr and find 'eHighest' (given the Y axis coordinates - //increase downward so the 'highest' edge will have the smallest ytop) ... - TEdge *e = &edges[0]; - TEdge *eHighest = e; + if (!Closed) + m_HasOpenPaths = true; + + //3. Do final Init and also find the 'highest' Edge. (nb: since I'm much + //more familiar with positive downwards Y axes, 'highest' here will be + //the Edge with the *smallest* Top.Y.) + TEdge *eHighest = eStart; + E = eStart; do { - e->xcurr = e->xbot; - e->ycurr = e->ybot; - if (e->ytop < eHighest->ytop) eHighest = e; - e = e->next; + InitEdge2(*E, PolyTyp); + if (E->Top.Y < eHighest->Top.Y) eHighest = E; + E = E->Next; } - while ( e != &edges[0]); + while (E != eStart); - //make sure eHighest is positioned so the following loop works safely ... - if (eHighest->windDelta > 0) eHighest = eHighest->next; - if (NEAR_EQUAL(eHighest->dx, HORIZONTAL)) eHighest = eHighest->next; + //4. build the local minima list ... + if (AllHorizontal(E)) + { + if (ClosedOrSemiClosed) + E->Prev->OutIdx = Skip; + AscendToMax(E, false, false); + return true; + } - //finally insert each local minima ... - e = eHighest; - do { - e = AddBoundsToLML(e); + //if eHighest is also the Skip then it's a natural break, otherwise + //make sure eHighest is positioned so we're either at a top horizontal or + //just starting to head down one edge of the polygon + E = eStart->Prev; //EStart.Prev == Skip edge + if (E->Prev == E->Next) + eHighest = E->Next; + else if (!ClosedOrSemiClosed && E->Top.Y == eHighest->Top.Y) + { + if ((IsHorizontal(*E) || IsHorizontal(*E->Next)) && + E->Next->Bot.Y == eHighest->Top.Y) + eHighest = E->Next; + else if (SharedVertWithPrevAtTop(E)) eHighest = E; + else if (E->Top == E->Prev->Top) eHighest = E->Prev; + else eHighest = E->Next; + } else + { + E = eHighest; + while (IsHorizontal(*eHighest) || + (eHighest->Top == eHighest->Next->Top) || + (eHighest->Top == eHighest->Next->Bot)) //next is high horizontal + { + eHighest = eHighest->Next; + if (eHighest == E) + { + while (IsHorizontal(*eHighest) || !SharedVertWithPrevAtTop(eHighest)) + eHighest = eHighest->Next; + break; //avoids potential endless loop + } + } } - while( e != eHighest ); + E = eHighest; + do + E = AddBoundsToLML(E, Closed); + while (E != eHighest); return true; } //------------------------------------------------------------------------------ +bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed) +{ + bool result = false; + for (Paths::size_type i = 0; i < ppg.size(); ++i) + if (AddPath(ppg[i], PolyTyp, Closed)) result = true; + return result; +} +//------------------------------------------------------------------------------ + void ClipperBase::InsertLocalMinima(LocalMinima *newLm) { if( ! m_MinimaList ) @@ -970,91 +1259,217 @@ void ClipperBase::InsertLocalMinima(LocalMinima *newLm) } else if( newLm->Y >= m_MinimaList->Y ) { - newLm->next = m_MinimaList; + newLm->Next = m_MinimaList; m_MinimaList = newLm; } else { LocalMinima* tmpLm = m_MinimaList; - while( tmpLm->next && ( newLm->Y < tmpLm->next->Y ) ) - tmpLm = tmpLm->next; - newLm->next = tmpLm->next; - tmpLm->next = newLm; + while( tmpLm->Next && ( newLm->Y < tmpLm->Next->Y ) ) + tmpLm = tmpLm->Next; + newLm->Next = tmpLm->Next; + tmpLm->Next = newLm; } } //------------------------------------------------------------------------------ -TEdge* ClipperBase::AddBoundsToLML(TEdge *e) +void ClipperBase::DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed) +{ + if (!E1) + { + if (!E2) return; + LocalMinima* NewLm = new LocalMinima; + NewLm->Next = 0; + NewLm->Y = E2->Bot.Y; + NewLm->LeftBound = 0; + E2->WindDelta = 0; + NewLm->RightBound = E2; + InsertLocalMinima(NewLm); + } else + { + //E and E.Prev are now at a local minima ... + LocalMinima* NewLm = new LocalMinima; + NewLm->Y = E1->Bot.Y; + NewLm->Next = 0; + if (IsHorizontal(*E2)) //Horz. edges never start a Left bound + { + if (E2->Bot.X != E1->Bot.X) ReverseHorizontal(*E2); + NewLm->LeftBound = E1; + NewLm->RightBound = E2; + } else if (E2->Dx < E1->Dx) + { + NewLm->LeftBound = E1; + NewLm->RightBound = E2; + } else + { + NewLm->LeftBound = E2; + NewLm->RightBound = E1; + } + NewLm->LeftBound->Side = esLeft; + NewLm->RightBound->Side = esRight; + //set the winding state of the first edge in each bound + //(it'll be copied to subsequent edges in the bound) ... + if (!IsClosed) NewLm->LeftBound->WindDelta = 0; + else if (NewLm->LeftBound->Next == NewLm->RightBound) NewLm->LeftBound->WindDelta = -1; + else NewLm->LeftBound->WindDelta = 1; + NewLm->RightBound->WindDelta = -NewLm->LeftBound->WindDelta; + InsertLocalMinima(NewLm); + } +} +//---------------------------------------------------------------------- + +TEdge* ClipperBase::DescendToMin(TEdge *&E) { + //PRECONDITION: STARTING EDGE IS A VALID DESCENDING EDGE. //Starting at the top of one bound we progress to the bottom where there's - //a local minima. We then go to the top of the next bound. These two bounds + //A local minima. We go to the top of the Next bound. These two bounds //form the left and right (or right and left) bounds of the local minima. - e->nextInLML = 0; - e = e->next; + TEdge* EHorz; + E->NextInLML = 0; + if (IsHorizontal(*E)) + { + EHorz = E; + while (IsHorizontal(*EHorz->Next)) EHorz = EHorz->Next; + if (EHorz->Bot != EHorz->Next->Top) + ReverseHorizontal(*E); + } for (;;) { - if (NEAR_EQUAL(e->dx, HORIZONTAL)) + E = E->Next; + if (E->OutIdx == Skip) break; + else if (IsHorizontal(*E)) { //nb: proceed through horizontals when approaching from their right, // but break on horizontal minima if approaching from their left. // This ensures 'local minima' are always on the left of horizontals. - if (e->next->ytop < e->ytop && e->next->xbot > e->prev->xbot) break; - if (e->xtop != e->prev->xbot) SwapX(*e); - e->nextInLML = e->prev; + + //look ahead is required in case of multiple consec. horizontals + EHorz = GetLastHorz(E); + if(EHorz == E->Prev || //horizontal line + (EHorz->Next->Top.Y < E->Top.Y && //bottom horizontal + EHorz->Next->Bot.X > E->Prev->Bot.X)) //approaching from the left + break; + if (E->Top.X != E->Prev->Bot.X) ReverseHorizontal(*E); + if (EHorz->OutIdx == Skip) EHorz = EHorz->Prev; + while (E != EHorz) + { + E->NextInLML = E->Prev; + E = E->Next; + if (E->Top.X != E->Prev->Bot.X) ReverseHorizontal(*E); + } } - else if (e->ycurr == e->prev->ycurr) break; - else e->nextInLML = e->prev; - e = e->next; + else if (E->Bot.Y == E->Prev->Bot.Y) break; + E->NextInLML = E->Prev; } + return E->Prev; +} +//---------------------------------------------------------------------- - //e and e.prev are now at a local minima ... - LocalMinima* newLm = new LocalMinima; - newLm->next = 0; - newLm->Y = e->prev->ybot; - - if ( NEAR_EQUAL(e->dx, HORIZONTAL) ) //horizontal edges never start a left bound - { - if (e->xbot != e->prev->xbot) SwapX(*e); - newLm->leftBound = e->prev; - newLm->rightBound = e; - } else if (e->dx < e->prev->dx) - { - newLm->leftBound = e->prev; - newLm->rightBound = e; - } else +void ClipperBase::AscendToMax(TEdge *&E, bool Appending, bool IsClosed) +{ + if (E->OutIdx == Skip) { - newLm->leftBound = e; - newLm->rightBound = e->prev; + E = E->Next; + if (!MoreAbove(E->Prev)) return; } - newLm->leftBound->side = esLeft; - newLm->rightBound->side = esRight; - InsertLocalMinima( newLm ); + if (IsHorizontal(*E) && Appending && (E->Bot != E->Prev->Bot)) + ReverseHorizontal(*E); + //now process the ascending bound .... + TEdge *EStart = E; for (;;) { - if ( e->next->ytop == e->ytop && !NEAR_EQUAL(e->next->dx, HORIZONTAL) ) break; - e->nextInLML = e->next; - e = e->next; - if ( NEAR_EQUAL(e->dx, HORIZONTAL) && e->xbot != e->prev->xtop) SwapX(*e); + if (E->Next->OutIdx == Skip || + ((E->Next->Top.Y == E->Top.Y) && !IsHorizontal(*E->Next))) break; + E->NextInLML = E->Next; + E = E->Next; + if (IsHorizontal(*E) && (E->Bot.X != E->Prev->Top.X)) + ReverseHorizontal(*E); } - return e->next; + + if (!Appending) + { + if (EStart->OutIdx == Skip) EStart = EStart->Next; + if (EStart != E->Next) + DoMinimaLML(0, EStart, IsClosed); + } + E = E->Next; } -//------------------------------------------------------------------------------ +//---------------------------------------------------------------------- -bool ClipperBase::AddPolygons(const Polygons &ppg, PolyType polyType) +TEdge* ClipperBase::AddBoundsToLML(TEdge* E, bool IsClosed) { - bool result = false; - for (Polygons::size_type i = 0; i < ppg.size(); ++i) - if (AddPolygon(ppg[i], polyType)) result = true; - return result; + //Starting at the top of one bound we progress to the bottom where there's + //A local minima. We then go to the top of the Next bound. These two bounds + //form the left and right (or right and left) bounds of the local minima. + + TEdge* B; + bool AppendMaxima; + //do minima ... + if (E->OutIdx == Skip) + { + if (MoreBelow(E)) + { + E = E->Next; + B = DescendToMin(E); + } else + B = 0; + } else + B = DescendToMin(E); + + if (E->OutIdx == Skip) //nb: may be BEFORE, AT or just THRU LM + { + //do minima before Skip... + DoMinimaLML(0, B, IsClosed); //store what we've got so far (if anything) + AppendMaxima = false; + //finish off any minima ... + if ((E->Bot != E->Prev->Bot) && MoreBelow(E)) + { + E = E->Next; + B = DescendToMin(E); + DoMinimaLML(B, E, IsClosed); + AppendMaxima = true; + } + else if (JustBeforeLocMin(E)) + E = E->Next; + } else + { + DoMinimaLML(B, E, IsClosed); + AppendMaxima = true; + } + + //now do maxima ... + AscendToMax(E, AppendMaxima, IsClosed); + + if (E->OutIdx == Skip && (E->Top != E->Prev->Top)) + { + //may be BEFORE, AT or just AFTER maxima + //finish off any maxima ... + if (MoreAbove(E)) + { + E = E->Next; + AscendToMax(E, false, IsClosed); + } + else if ((E->Top == E->Next->Top) || + (IsHorizontal(*E->Next) && (E->Top == E->Next->Bot))) + E = E->Next; //ie just before Maxima + } + return E; } -//------------------------------------------------------------------------------ +//---------------------------------------------------------------------- void ClipperBase::Clear() { DisposeLocalMinimaList(); - for (EdgeList::size_type i = 0; i < m_edges.size(); ++i) delete [] m_edges[i]; + for (EdgeList::size_type i = 0; i < m_edges.size(); ++i) + { + //for each edge array in turn, find the first used edge and + //check for and remove any hiddenPts in each edge in the array. + TEdge* edges = m_edges[i]; + delete [] edges; + } m_edges.clear(); m_UseFullRange = false; + m_HasOpenPaths = false; } //------------------------------------------------------------------------------ @@ -1067,25 +1482,21 @@ void ClipperBase::Reset() LocalMinima* lm = m_MinimaList; while( lm ) { - TEdge* e = lm->leftBound; - while( e ) - { - e->xcurr = e->xbot; - e->ycurr = e->ybot; - e->side = esLeft; - e->outIdx = -1; - e = e->nextInLML; - } - e = lm->rightBound; - while( e ) + TEdge* e = lm->LeftBound; + if (e) { - e->xcurr = e->xbot; - e->ycurr = e->ybot; - e->side = esRight; - e->outIdx = -1; - e = e->nextInLML; + e->Curr = e->Bot; + e->Side = esLeft; + if (e->OutIdx != Skip) + e->OutIdx = Unassigned; } - lm = lm->next; + e = lm->RightBound; + e->Curr = e->Bot; + e->Side = esRight; + if (e->OutIdx != Skip) + e->OutIdx = Unassigned; + + lm = lm->Next; } } //------------------------------------------------------------------------------ @@ -1094,7 +1505,7 @@ void ClipperBase::DisposeLocalMinimaList() { while( m_MinimaList ) { - LocalMinima* tmpLm = m_MinimaList->next; + LocalMinima* tmpLm = m_MinimaList->Next; delete m_MinimaList; m_MinimaList = tmpLm; } @@ -1105,7 +1516,7 @@ void ClipperBase::DisposeLocalMinimaList() void ClipperBase::PopLocalMinima() { if( ! m_CurrentLM ) return; - m_CurrentLM = m_CurrentLM->next; + m_CurrentLM = m_CurrentLM->Next; } //------------------------------------------------------------------------------ @@ -1118,100 +1529,103 @@ IntRect ClipperBase::GetBounds() result.left = result.top = result.right = result.bottom = 0; return result; } - result.left = lm->leftBound->xbot; - result.top = lm->leftBound->ybot; - result.right = lm->leftBound->xbot; - result.bottom = lm->leftBound->ybot; + result.left = lm->LeftBound->Bot.X; + result.top = lm->LeftBound->Bot.Y; + result.right = lm->LeftBound->Bot.X; + result.bottom = lm->LeftBound->Bot.Y; while (lm) { - if (lm->leftBound->ybot > result.bottom) - result.bottom = lm->leftBound->ybot; - TEdge* e = lm->leftBound; + if (lm->LeftBound->Bot.Y > result.bottom) + result.bottom = lm->LeftBound->Bot.Y; + TEdge* e = lm->LeftBound; for (;;) { TEdge* bottomE = e; - while (e->nextInLML) + while (e->NextInLML) { - if (e->xbot < result.left) result.left = e->xbot; - if (e->xbot > result.right) result.right = e->xbot; - e = e->nextInLML; + if (e->Bot.X < result.left) result.left = e->Bot.X; + if (e->Bot.X > result.right) result.right = e->Bot.X; + e = e->NextInLML; } - if (e->xbot < result.left) result.left = e->xbot; - if (e->xbot > result.right) result.right = e->xbot; - if (e->xtop < result.left) result.left = e->xtop; - if (e->xtop > result.right) result.right = e->xtop; - if (e->ytop < result.top) result.top = e->ytop; + if (e->Bot.X < result.left) result.left = e->Bot.X; + if (e->Bot.X > result.right) result.right = e->Bot.X; + if (e->Top.X < result.left) result.left = e->Top.X; + if (e->Top.X > result.right) result.right = e->Top.X; + if (e->Top.Y < result.top) result.top = e->Top.Y; - if (bottomE == lm->leftBound) e = lm->rightBound; + if (bottomE == lm->LeftBound) e = lm->RightBound; else break; } - lm = lm->next; + lm = lm->Next; } return result; } - //------------------------------------------------------------------------------ // TClipper methods ... //------------------------------------------------------------------------------ -Clipper::Clipper() : ClipperBase() //constructor +Clipper::Clipper(int initOptions) : ClipperBase() //constructor { - m_Scanbeam = 0; m_ActiveEdges = 0; m_SortedEdges = 0; m_IntersectNodes = 0; m_ExecuteLocked = false; m_UseFullRange = false; - m_ReverseOutput = false; - m_ForceSimple = false; + m_ReverseOutput = ((initOptions & ioReverseSolution) != 0); + m_StrictSimple = ((initOptions & ioStrictlySimple) != 0); + m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0); + m_HasOpenPaths = false; +#ifdef use_xyz + m_ZFill = 0; +#endif } //------------------------------------------------------------------------------ Clipper::~Clipper() //destructor { Clear(); - DisposeScanbeamList(); + m_Scanbeam.clear(); +} +//------------------------------------------------------------------------------ + +#ifdef use_xyz +void Clipper::ZFillFunction(TZFillCallback zFillFunc) +{ + m_ZFill = zFillFunc; } //------------------------------------------------------------------------------ +#endif void Clipper::Clear() { if (m_edges.empty()) return; //avoids problems with ClipperBase destructor - DisposeAllPolyPts(); + DisposeAllOutRecs(); ClipperBase::Clear(); } //------------------------------------------------------------------------------ -void Clipper::DisposeScanbeamList() -{ - while ( m_Scanbeam ) { - Scanbeam* sb2 = m_Scanbeam->next; - delete m_Scanbeam; - m_Scanbeam = sb2; - } -} -//------------------------------------------------------------------------------ - -void Clipper::Reset() +void Clipper::Reset() { ClipperBase::Reset(); - m_Scanbeam = 0; + m_Scanbeam.clear(); m_ActiveEdges = 0; m_SortedEdges = 0; - DisposeAllPolyPts(); + DisposeAllOutRecs(); LocalMinima* lm = m_MinimaList; while (lm) { InsertScanbeam(lm->Y); - lm = lm->next; + lm = lm->Next; } } //------------------------------------------------------------------------------ -bool Clipper::Execute(ClipType clipType, Polygons &solution, +bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType subjFillType, PolyFillType clipFillType) { if( m_ExecuteLocked ) return false; + if (m_HasOpenPaths) + throw clipperException("Error: PolyTree struct is need for open path clipping."); m_ExecuteLocked = true; solution.resize(0); m_SubjFillType = subjFillType; @@ -1246,11 +1660,11 @@ void Clipper::FixHoleLinkage(OutRec &outrec) //skip OutRecs that (a) contain outermost polygons or //(b) already have the correct owner/child linkage ... if (!outrec.FirstLeft || - (outrec.isHole != outrec.FirstLeft->isHole && - outrec.FirstLeft->pts)) return; + (outrec.IsHole != outrec.FirstLeft->IsHole && + outrec.FirstLeft->Pts)) return; OutRec* orfl = outrec.FirstLeft; - while (orfl && ((orfl->isHole == outrec.isHole) || !orfl->pts)) + while (orfl && ((orfl->IsHole == outrec.IsHole) || !orfl->Pts)) orfl = orfl->FirstLeft; outrec.FirstLeft = orfl; } @@ -1258,88 +1672,73 @@ void Clipper::FixHoleLinkage(OutRec &outrec) bool Clipper::ExecuteInternal() { - bool succeeded; + bool succeeded = true; try { Reset(); - if (!m_CurrentLM ) return true; - long64 botY = PopScanbeam(); + if (!m_CurrentLM) return false; + cInt botY = PopScanbeam(); do { InsertLocalMinimaIntoAEL(botY); - ClearHorzJoins(); - ProcessHorizontals(); - long64 topY = PopScanbeam(); + ClearGhostJoins(); + ProcessHorizontals(false); + if (m_Scanbeam.empty()) break; + cInt topY = PopScanbeam(); succeeded = ProcessIntersections(botY, topY); if (!succeeded) break; ProcessEdgesAtTopOfScanbeam(topY); botY = topY; - } while(m_Scanbeam || m_CurrentLM); + } while (!m_Scanbeam.empty() || m_CurrentLM); } - catch(...) { + catch(...) + { succeeded = false; } if (succeeded) { - //tidy up output polygons and fix orientations where necessary ... + //fix orientations ... for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) { OutRec *outRec = m_PolyOuts[i]; - if (!outRec->pts) continue; - FixupOutPolygon(*outRec); - if (!outRec->pts) continue; - - if ((outRec->isHole ^ m_ReverseOutput) == (Area(*outRec, m_UseFullRange) > 0)) - ReversePolyPtLinks(outRec->pts); + if (!outRec->Pts || outRec->IsOpen) continue; + if ((outRec->IsHole ^ m_ReverseOutput) == (Area(*outRec) > 0)) + ReversePolyPtLinks(outRec->Pts); } if (!m_Joins.empty()) JoinCommonEdges(); - if (m_ForceSimple) DoSimplePolygons(); + + //unfortunately FixupOutPolygon() must be done after JoinCommonEdges() + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + OutRec *outRec = m_PolyOuts[i]; + if (outRec->Pts && !outRec->IsOpen) + FixupOutPolygon(*outRec); + } + + if (m_StrictSimple) DoSimplePolygons(); } ClearJoins(); - ClearHorzJoins(); + ClearGhostJoins(); return succeeded; } //------------------------------------------------------------------------------ -void Clipper::InsertScanbeam(const long64 Y) +void Clipper::InsertScanbeam(const cInt Y) { - if( !m_Scanbeam ) - { - m_Scanbeam = new Scanbeam; - m_Scanbeam->next = 0; - m_Scanbeam->Y = Y; - } - else if( Y > m_Scanbeam->Y ) - { - Scanbeam* newSb = new Scanbeam; - newSb->Y = Y; - newSb->next = m_Scanbeam; - m_Scanbeam = newSb; - } else - { - Scanbeam* sb2 = m_Scanbeam; - while( sb2->next && ( Y <= sb2->next->Y ) ) sb2 = sb2->next; - if( Y == sb2->Y ) return; //ie ignores duplicates - Scanbeam* newSb = new Scanbeam; - newSb->Y = Y; - newSb->next = sb2->next; - sb2->next = newSb; - } + m_Scanbeam.insert(Y); } //------------------------------------------------------------------------------ -long64 Clipper::PopScanbeam() +cInt Clipper::PopScanbeam() { - long64 Y = m_Scanbeam->Y; - Scanbeam* sb2 = m_Scanbeam; - m_Scanbeam = m_Scanbeam->next; - delete sb2; + cInt Y = *m_Scanbeam.begin(); + m_Scanbeam.erase(m_Scanbeam.begin()); return Y; } //------------------------------------------------------------------------------ -void Clipper::DisposeAllPolyPts(){ +void Clipper::DisposeAllOutRecs(){ for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) DisposeOutRec(i); m_PolyOuts.clear(); @@ -1349,7 +1748,7 @@ void Clipper::DisposeAllPolyPts(){ void Clipper::DisposeOutRec(PolyOutList::size_type index) { OutRec *outRec = m_PolyOuts[index]; - if (outRec->pts) DisposeOutPts(outRec->pts); + if (outRec->Pts) DisposeOutPts(outRec->Pts); delete outRec; m_PolyOuts[index] = 0; } @@ -1357,59 +1756,94 @@ void Clipper::DisposeOutRec(PolyOutList::size_type index) void Clipper::SetWindingCount(TEdge &edge) { - TEdge *e = edge.prevInAEL; + TEdge *e = edge.PrevInAEL; //find the edge of the same polytype that immediately preceeds 'edge' in AEL - while ( e && e->polyType != edge.polyType ) e = e->prevInAEL; - if ( !e ) + while (e && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL; + if (!e) { - edge.windCnt = edge.windDelta; - edge.windCnt2 = 0; - e = m_ActiveEdges; //ie get ready to calc windCnt2 - } else if ( IsEvenOddFillType(edge) ) + edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); + edge.WindCnt2 = 0; + e = m_ActiveEdges; //ie get ready to calc WindCnt2 + } + else if (edge.WindDelta == 0 && m_ClipType != ctUnion) + { + edge.WindCnt = 1; + edge.WindCnt2 = e->WindCnt2; + e = e->NextInAEL; //ie get ready to calc WindCnt2 + } + else if (IsEvenOddFillType(edge)) { //EvenOdd filling ... - edge.windCnt = 1; - edge.windCnt2 = e->windCnt2; - e = e->nextInAEL; //ie get ready to calc windCnt2 - } else + if (edge.WindDelta == 0) + { + //are we inside a subj polygon ... + bool Inside = true; + TEdge *e2 = e->PrevInAEL; + while (e2) + { + if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0) + Inside = !Inside; + e2 = e2->PrevInAEL; + } + edge.WindCnt = (Inside ? 0 : 1); + } + else + { + edge.WindCnt = edge.WindDelta; + } + edge.WindCnt2 = e->WindCnt2; + e = e->NextInAEL; //ie get ready to calc WindCnt2 + } + else { //nonZero, Positive or Negative filling ... - if ( e->windCnt * e->windDelta < 0 ) + if (e->WindCnt * e->WindDelta < 0) { - if (Abs(e->windCnt) > 1) + //prev edge is 'decreasing' WindCount (WC) toward zero + //so we're outside the previous polygon ... + if (Abs(e->WindCnt) > 1) { - if (e->windDelta * edge.windDelta < 0) edge.windCnt = e->windCnt; - else edge.windCnt = e->windCnt + edge.windDelta; - } else - edge.windCnt = e->windCnt + e->windDelta + edge.windDelta; + //outside prev poly but still inside another. + //when reversing direction of prev poly use the same WC + if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt; + //otherwise continue to 'decrease' WC ... + else edge.WindCnt = e->WindCnt + edge.WindDelta; + } + else + //now outside all polys of same polytype so set own WC ... + edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta); } else { - if ( Abs(e->windCnt) > 1 && e->windDelta * edge.windDelta < 0) - edge.windCnt = e->windCnt; - else if ( e->windCnt + edge.windDelta == 0 ) - edge.windCnt = e->windCnt; - else edge.windCnt = e->windCnt + edge.windDelta; + //prev edge is 'increasing' WindCount (WC) away from zero + //so we're inside the previous polygon ... + if (edge.WindDelta == 0) + edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1); + //if wind direction is reversing prev then use same WC + else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt; + //otherwise add to WC ... + else edge.WindCnt = e->WindCnt + edge.WindDelta; } - edge.windCnt2 = e->windCnt2; - e = e->nextInAEL; //ie get ready to calc windCnt2 + edge.WindCnt2 = e->WindCnt2; + e = e->NextInAEL; //ie get ready to calc WindCnt2 } - //update windCnt2 ... - if ( IsEvenOddAltFillType(edge) ) + //update WindCnt2 ... + if (IsEvenOddAltFillType(edge)) { //EvenOdd filling ... - while ( e != &edge ) + while (e != &edge) { - edge.windCnt2 = (edge.windCnt2 == 0) ? 1 : 0; - e = e->nextInAEL; + if (e->WindDelta != 0) + edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0); + e = e->NextInAEL; } } else { //nonZero, Positive or Negative filling ... while ( e != &edge ) { - edge.windCnt2 += e->windDelta; - e = e->nextInAEL; + edge.WindCnt2 += e->WindDelta; + e = e->NextInAEL; } } } @@ -1417,7 +1851,7 @@ void Clipper::SetWindingCount(TEdge &edge) bool Clipper::IsEvenOddFillType(const TEdge& edge) const { - if (edge.polyType == ptSubject) + if (edge.PolyTyp == ptSubject) return m_SubjFillType == pftEvenOdd; else return m_ClipFillType == pftEvenOdd; } @@ -1425,7 +1859,7 @@ bool Clipper::IsEvenOddFillType(const TEdge& edge) const bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const { - if (edge.polyType == ptSubject) + if (edge.PolyTyp == ptSubject) return m_ClipFillType == pftEvenOdd; else return m_SubjFillType == pftEvenOdd; } @@ -1434,7 +1868,7 @@ bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const bool Clipper::IsContributing(const TEdge& edge) const { PolyFillType pft, pft2; - if (edge.polyType == ptSubject) + if (edge.PolyTyp == ptSubject) { pft = m_SubjFillType; pft2 = m_ClipFillType; @@ -1447,14 +1881,17 @@ bool Clipper::IsContributing(const TEdge& edge) const switch(pft) { case pftEvenOdd: + //return false if a subj line has been flagged as inside a subj polygon + if (edge.WindDelta == 0 && edge.WindCnt != 1) return false; + break; case pftNonZero: - if (Abs(edge.windCnt) != 1) return false; + if (Abs(edge.WindCnt) != 1) return false; break; case pftPositive: - if (edge.windCnt != 1) return false; + if (edge.WindCnt != 1) return false; break; default: //pftNegative - if (edge.windCnt != -1) return false; + if (edge.WindCnt != -1) return false; } switch(m_ClipType) @@ -1464,11 +1901,11 @@ bool Clipper::IsContributing(const TEdge& edge) const { case pftEvenOdd: case pftNonZero: - return (edge.windCnt2 != 0); + return (edge.WindCnt2 != 0); case pftPositive: - return (edge.windCnt2 > 0); + return (edge.WindCnt2 > 0); default: - return (edge.windCnt2 < 0); + return (edge.WindCnt2 < 0); } break; case ctUnion: @@ -1476,36 +1913,51 @@ bool Clipper::IsContributing(const TEdge& edge) const { case pftEvenOdd: case pftNonZero: - return (edge.windCnt2 == 0); + return (edge.WindCnt2 == 0); case pftPositive: - return (edge.windCnt2 <= 0); + return (edge.WindCnt2 <= 0); default: - return (edge.windCnt2 >= 0); + return (edge.WindCnt2 >= 0); } break; case ctDifference: - if (edge.polyType == ptSubject) + if (edge.PolyTyp == ptSubject) switch(pft2) { case pftEvenOdd: case pftNonZero: - return (edge.windCnt2 == 0); + return (edge.WindCnt2 == 0); case pftPositive: - return (edge.windCnt2 <= 0); + return (edge.WindCnt2 <= 0); default: - return (edge.windCnt2 >= 0); + return (edge.WindCnt2 >= 0); } else switch(pft2) { case pftEvenOdd: case pftNonZero: - return (edge.windCnt2 != 0); + return (edge.WindCnt2 != 0); + case pftPositive: + return (edge.WindCnt2 > 0); + default: + return (edge.WindCnt2 < 0); + } + break; + case ctXor: + if (edge.WindDelta == 0) //XOr always contributing unless open + switch(pft2) + { + case pftEvenOdd: + case pftNonZero: + return (edge.WindCnt2 == 0); case pftPositive: - return (edge.windCnt2 > 0); + return (edge.WindCnt2 <= 0); default: - return (edge.windCnt2 < 0); + return (edge.WindCnt2 >= 0); } + else + return true; break; default: return true; @@ -1513,48 +1965,55 @@ bool Clipper::IsContributing(const TEdge& edge) const } //------------------------------------------------------------------------------ -void Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt) +OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) { + OutPt* result; TEdge *e, *prevE; - if( NEAR_EQUAL(e2->dx, HORIZONTAL) || ( e1->dx > e2->dx ) ) + if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx )) { - AddOutPt( e1, pt ); - e2->outIdx = e1->outIdx; - e1->side = esLeft; - e2->side = esRight; + result = AddOutPt(e1, Pt); + e2->OutIdx = e1->OutIdx; + e1->Side = esLeft; + e2->Side = esRight; e = e1; - if (e->prevInAEL == e2) - prevE = e2->prevInAEL; + if (e->PrevInAEL == e2) + prevE = e2->PrevInAEL; else - prevE = e->prevInAEL; + prevE = e->PrevInAEL; } else { - AddOutPt( e2, pt ); - e1->outIdx = e2->outIdx; - e1->side = esRight; - e2->side = esLeft; + result = AddOutPt(e2, Pt); + e1->OutIdx = e2->OutIdx; + e1->Side = esRight; + e2->Side = esLeft; e = e2; - if (e->prevInAEL == e1) - prevE = e1->prevInAEL; + if (e->PrevInAEL == e1) + prevE = e1->PrevInAEL; else - prevE = e->prevInAEL; + prevE = e->PrevInAEL; + } + + if (prevE && prevE->OutIdx >= 0 && + (TopX(*prevE, Pt.Y) == TopX(*e, Pt.Y)) && + SlopesEqual(*e, *prevE, m_UseFullRange) && + (e->WindDelta != 0) && (prevE->WindDelta != 0)) + { + OutPt* outPt = AddOutPt(prevE, Pt); + AddJoin(result, outPt, e->Top); } - if (prevE && prevE->outIdx >= 0 && - (TopX(*prevE, pt.Y) == TopX(*e, pt.Y)) && - SlopesEqual(*e, *prevE, m_UseFullRange)) - AddJoin(e, prevE, -1, -1); + return result; } //------------------------------------------------------------------------------ -void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt) +void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) { - AddOutPt( e1, pt ); - if( e1->outIdx == e2->outIdx ) + AddOutPt( e1, Pt ); + if( e1->OutIdx == e2->OutIdx ) { - e1->outIdx = -1; - e2->outIdx = -1; + e1->OutIdx = Unassigned; + e2->OutIdx = Unassigned; } - else if (e1->outIdx < e2->outIdx) + else if (e1->OutIdx < e2->OutIdx) AppendPolygon(e1, e2); else AppendPolygon(e2, e1); @@ -1568,14 +2027,14 @@ void Clipper::AddEdgeToSEL(TEdge *edge) if( !m_SortedEdges ) { m_SortedEdges = edge; - edge->prevInSEL = 0; - edge->nextInSEL = 0; + edge->PrevInSEL = 0; + edge->NextInSEL = 0; } else { - edge->nextInSEL = m_SortedEdges; - edge->prevInSEL = 0; - m_SortedEdges->prevInSEL = edge; + edge->NextInSEL = m_SortedEdges; + edge->PrevInSEL = 0; + m_SortedEdges->PrevInSEL = edge; m_SortedEdges = edge; } } @@ -1587,27 +2046,20 @@ void Clipper::CopyAELToSEL() m_SortedEdges = e; while ( e ) { - e->prevInSEL = e->prevInAEL; - e->nextInSEL = e->nextInAEL; - e = e->nextInAEL; + e->PrevInSEL = e->PrevInAEL; + e->NextInSEL = e->NextInAEL; + e = e->NextInAEL; } } //------------------------------------------------------------------------------ -void Clipper::AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx, int e2OutIdx) +void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint OffPt) { - JoinRec* jr = new JoinRec; - if (e1OutIdx >= 0) - jr->poly1Idx = e1OutIdx; else - jr->poly1Idx = e1->outIdx; - jr->pt1a = IntPoint(e1->xcurr, e1->ycurr); - jr->pt1b = IntPoint(e1->xtop, e1->ytop); - if (e2OutIdx >= 0) - jr->poly2Idx = e2OutIdx; else - jr->poly2Idx = e2->outIdx; - jr->pt2a = IntPoint(e2->xcurr, e2->ycurr); - jr->pt2b = IntPoint(e2->xtop, e2->ytop); - m_Joins.push_back(jr); + Join* j = new Join; + j->OutPt1 = op1; + j->OutPt2 = op2; + j->OffPt = OffPt; + m_Joins.push_back(j); } //------------------------------------------------------------------------------ @@ -1619,161 +2071,252 @@ void Clipper::ClearJoins() } //------------------------------------------------------------------------------ -void Clipper::AddHorzJoin(TEdge *e, int idx) +void Clipper::ClearGhostJoins() { - HorzJoinRec* hj = new HorzJoinRec; - hj->edge = e; - hj->savedIdx = idx; - m_HorizJoins.push_back(hj); + for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++) + delete m_GhostJoins[i]; + m_GhostJoins.resize(0); } //------------------------------------------------------------------------------ -void Clipper::ClearHorzJoins() +void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt) { - for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); i++) - delete m_HorizJoins[i]; - m_HorizJoins.resize(0); + Join* j = new Join; + j->OutPt1 = op; + j->OutPt2 = 0; + j->OffPt = OffPt; + m_GhostJoins.push_back(j); } //------------------------------------------------------------------------------ -void Clipper::InsertLocalMinimaIntoAEL(const long64 botY) +void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) { while( m_CurrentLM && ( m_CurrentLM->Y == botY ) ) { - TEdge* lb = m_CurrentLM->leftBound; - TEdge* rb = m_CurrentLM->rightBound; - - InsertEdgeIntoAEL( lb ); - InsertScanbeam( lb->ytop ); - InsertEdgeIntoAEL( rb ); - - if (IsEvenOddFillType(*lb)) + TEdge* lb = m_CurrentLM->LeftBound; + TEdge* rb = m_CurrentLM->RightBound; + PopLocalMinima(); + OutPt *Op1 = 0; + if (!lb) { - lb->windDelta = 1; - rb->windDelta = 1; - } + //nb: don't insert LB into either AEL or SEL + InsertEdgeIntoAEL(rb, 0); + SetWindingCount(*rb); + if (IsContributing(*rb)) + Op1 = AddOutPt(rb, rb->Bot); + } else { - rb->windDelta = -lb->windDelta; + InsertEdgeIntoAEL(lb, 0); + InsertEdgeIntoAEL(rb, lb); + SetWindingCount( *lb ); + rb->WindCnt = lb->WindCnt; + rb->WindCnt2 = lb->WindCnt2; + if (IsContributing(*lb)) + Op1 = AddLocalMinPoly(lb, rb, lb->Bot); + InsertScanbeam(lb->Top.Y); } - SetWindingCount( *lb ); - rb->windCnt = lb->windCnt; - rb->windCnt2 = lb->windCnt2; - if( NEAR_EQUAL(rb->dx, HORIZONTAL) ) - { - //nb: only rightbounds can have a horizontal bottom edge - AddEdgeToSEL( rb ); - InsertScanbeam( rb->nextInLML->ytop ); - } + if(IsHorizontal(*rb)) + AddEdgeToSEL(rb); else - InsertScanbeam( rb->ytop ); + InsertScanbeam( rb->Top.Y ); - if( IsContributing(*lb) ) - AddLocalMinPoly( lb, rb, IntPoint(lb->xcurr, m_CurrentLM->Y) ); + if (!lb) continue; //if any output polygons share an edge, they'll need joining later ... - if (rb->outIdx >= 0 && NEAR_EQUAL(rb->dx, HORIZONTAL)) + if (Op1 && IsHorizontal(*rb) && + m_GhostJoins.size() > 0 && (rb->WindDelta != 0)) { - for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i) + for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i) { - IntPoint pt, pt2; //returned by GetOverlapSegment() but unused here. - HorzJoinRec* hj = m_HorizJoins[i]; - //if horizontals rb and hj.edge overlap, flag for joining later ... - if (GetOverlapSegment(IntPoint(hj->edge->xbot, hj->edge->ybot), - IntPoint(hj->edge->xtop, hj->edge->ytop), - IntPoint(rb->xbot, rb->ybot), - IntPoint(rb->xtop, rb->ytop), pt, pt2)) - AddJoin(hj->edge, rb, hj->savedIdx); + Join* jr = m_GhostJoins[i]; + //if the horizontal Rb and a 'ghost' horizontal overlap, then convert + //the 'ghost' join to a real join ready for later ... + if (HorzSegmentsOverlap(jr->OutPt1->Pt, jr->OffPt, rb->Bot, rb->Top)) + AddJoin(jr->OutPt1, Op1, jr->OffPt); } } - if( lb->nextInAEL != rb ) + if (lb->OutIdx >= 0 && lb->PrevInAEL && + lb->PrevInAEL->Curr.X == lb->Bot.X && + lb->PrevInAEL->OutIdx >= 0 && + SlopesEqual(*lb->PrevInAEL, *lb, m_UseFullRange) && + (lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0)) + { + OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot); + AddJoin(Op1, Op2, lb->Top); + } + + if(lb->NextInAEL != rb) { - if (rb->outIdx >= 0 && rb->prevInAEL->outIdx >= 0 && - SlopesEqual(*rb->prevInAEL, *rb, m_UseFullRange)) - AddJoin(rb, rb->prevInAEL); - TEdge* e = lb->nextInAEL; - IntPoint pt = IntPoint(lb->xcurr, lb->ycurr); - while( e != rb ) + if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 && + SlopesEqual(*rb->PrevInAEL, *rb, m_UseFullRange) && + (rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0)) + { + OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot); + AddJoin(Op1, Op2, rb->Top); + } + + TEdge* e = lb->NextInAEL; + if (e) { - if(!e) throw clipperException("InsertLocalMinimaIntoAEL: missing rightbound!"); - //nb: For calculating winding counts etc, IntersectEdges() assumes - //that param1 will be to the right of param2 ABOVE the intersection ... - IntersectEdges( rb , e , pt , ipNone); //order important here - e = e->nextInAEL; + while( e != rb ) + { + //nb: For calculating winding counts etc, IntersectEdges() assumes + //that param1 will be to the Right of param2 ABOVE the intersection ... + IntersectEdges(rb , e , lb->Curr); //order important here + e = e->NextInAEL; + } } } - PopLocalMinima(); + } } //------------------------------------------------------------------------------ void Clipper::DeleteFromAEL(TEdge *e) { - TEdge* AelPrev = e->prevInAEL; - TEdge* AelNext = e->nextInAEL; + TEdge* AelPrev = e->PrevInAEL; + TEdge* AelNext = e->NextInAEL; if( !AelPrev && !AelNext && (e != m_ActiveEdges) ) return; //already deleted - if( AelPrev ) AelPrev->nextInAEL = AelNext; + if( AelPrev ) AelPrev->NextInAEL = AelNext; else m_ActiveEdges = AelNext; - if( AelNext ) AelNext->prevInAEL = AelPrev; - e->nextInAEL = 0; - e->prevInAEL = 0; + if( AelNext ) AelNext->PrevInAEL = AelPrev; + e->NextInAEL = 0; + e->PrevInAEL = 0; } //------------------------------------------------------------------------------ void Clipper::DeleteFromSEL(TEdge *e) { - TEdge* SelPrev = e->prevInSEL; - TEdge* SelNext = e->nextInSEL; + TEdge* SelPrev = e->PrevInSEL; + TEdge* SelNext = e->NextInSEL; if( !SelPrev && !SelNext && (e != m_SortedEdges) ) return; //already deleted - if( SelPrev ) SelPrev->nextInSEL = SelNext; + if( SelPrev ) SelPrev->NextInSEL = SelNext; else m_SortedEdges = SelNext; - if( SelNext ) SelNext->prevInSEL = SelPrev; - e->nextInSEL = 0; - e->prevInSEL = 0; + if( SelNext ) SelNext->PrevInSEL = SelPrev; + e->NextInSEL = 0; + e->PrevInSEL = 0; +} +//------------------------------------------------------------------------------ + +#ifdef use_xyz + +void Clipper::SetZ(IntPoint& pt, TEdge& e) +{ + pt.Z = 0; + if (m_ZFill) + { + //put the 'preferred' point as first parameter ... + if (e.OutIdx < 0) + (*m_ZFill)(e.Bot, e.Top, pt); //outside a path so presume entering + else + (*m_ZFill)(e.Top, e.Bot, pt); //inside a path so presume exiting + } } //------------------------------------------------------------------------------ +#endif void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, - const IntPoint &pt, const IntersectProtects protects) + const IntPoint &Pt, bool protect) { - //e1 will be to the left of e2 BELOW the intersection. Therefore e1 is before + //e1 will be to the Left of e2 BELOW the intersection. Therefore e1 is before //e2 in AEL except when e1 is being inserted at the intersection point ... - bool e1stops = !(ipLeft & protects) && !e1->nextInLML && - e1->xtop == pt.X && e1->ytop == pt.Y; - bool e2stops = !(ipRight & protects) && !e2->nextInLML && - e2->xtop == pt.X && e2->ytop == pt.Y; - bool e1Contributing = ( e1->outIdx >= 0 ); - bool e2contributing = ( e2->outIdx >= 0 ); + bool e1stops = !protect && !e1->NextInLML && + e1->Top.X == Pt.X && e1->Top.Y == Pt.Y; + bool e2stops = !protect && !e2->NextInLML && + e2->Top.X == Pt.X && e2->Top.Y == Pt.Y; + bool e1Contributing = ( e1->OutIdx >= 0 ); + bool e2Contributing = ( e2->OutIdx >= 0 ); + +#ifdef use_lines + //if either edge is on an OPEN path ... + if (e1->WindDelta == 0 || e2->WindDelta == 0) + { + //ignore subject-subject open path intersections UNLESS they + //are both open paths, AND they are both 'contributing maximas' ... + if (e1->WindDelta == 0 && e2->WindDelta == 0) + { + if ((e1stops || e2stops) && e1Contributing && e2Contributing) + AddLocalMaxPoly(e1, e2, Pt); + } + + //if intersecting a subj line with a subj poly ... + else if (e1->PolyTyp == e2->PolyTyp && + e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion) + { + if (e1->WindDelta == 0) + { + if (e2Contributing) + { + AddOutPt(e1, Pt); + if (e1Contributing) e1->OutIdx = Unassigned; + } + } + else + { + if (e1Contributing) + { + AddOutPt(e2, Pt); + if (e2Contributing) e2->OutIdx = Unassigned; + } + } + } + else if (e1->PolyTyp != e2->PolyTyp) + { + //toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ... + if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 && + (m_ClipType != ctUnion || e2->WindCnt2 == 0)) + { + AddOutPt(e1, Pt); + if (e1Contributing) e1->OutIdx = Unassigned; + } + else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) && + (m_ClipType != ctUnion || e1->WindCnt2 == 0)) + { + AddOutPt(e2, Pt); + if (e2Contributing) e2->OutIdx = Unassigned; + } + } + + if (e1stops) + if (e1->OutIdx < 0) DeleteFromAEL(e1); + else throw clipperException("Error intersecting polylines"); + if (e2stops) + if (e2->OutIdx < 0) DeleteFromAEL(e2); + else throw clipperException("Error intersecting polylines"); + return; + } +#endif //update winding counts... - //assumes that e1 will be to the right of e2 ABOVE the intersection - if ( e1->polyType == e2->polyType ) + //assumes that e1 will be to the Right of e2 ABOVE the intersection + if ( e1->PolyTyp == e2->PolyTyp ) { if ( IsEvenOddFillType( *e1) ) { - int oldE1WindCnt = e1->windCnt; - e1->windCnt = e2->windCnt; - e2->windCnt = oldE1WindCnt; + int oldE1WindCnt = e1->WindCnt; + e1->WindCnt = e2->WindCnt; + e2->WindCnt = oldE1WindCnt; } else { - if (e1->windCnt + e2->windDelta == 0 ) e1->windCnt = -e1->windCnt; - else e1->windCnt += e2->windDelta; - if ( e2->windCnt - e1->windDelta == 0 ) e2->windCnt = -e2->windCnt; - else e2->windCnt -= e1->windDelta; + if (e1->WindCnt + e2->WindDelta == 0 ) e1->WindCnt = -e1->WindCnt; + else e1->WindCnt += e2->WindDelta; + if ( e2->WindCnt - e1->WindDelta == 0 ) e2->WindCnt = -e2->WindCnt; + else e2->WindCnt -= e1->WindDelta; } } else { - if (!IsEvenOddFillType(*e2)) e1->windCnt2 += e2->windDelta; - else e1->windCnt2 = ( e1->windCnt2 == 0 ) ? 1 : 0; - if (!IsEvenOddFillType(*e1)) e2->windCnt2 -= e1->windDelta; - else e2->windCnt2 = ( e2->windCnt2 == 0 ) ? 1 : 0; + if (!IsEvenOddFillType(*e2)) e1->WindCnt2 += e2->WindDelta; + else e1->WindCnt2 = ( e1->WindCnt2 == 0 ) ? 1 : 0; + if (!IsEvenOddFillType(*e1)) e2->WindCnt2 -= e1->WindDelta; + else e2->WindCnt2 = ( e2->WindCnt2 == 0 ) ? 1 : 0; } PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2; - if (e1->polyType == ptSubject) + if (e1->PolyTyp == ptSubject) { e1FillType = m_SubjFillType; e1FillType2 = m_ClipFillType; @@ -1782,7 +2325,7 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, e1FillType = m_ClipFillType; e1FillType2 = m_SubjFillType; } - if (e2->polyType == ptSubject) + if (e2->PolyTyp == ptSubject) { e2FillType = m_SubjFillType; e2FillType2 = m_ClipFillType; @@ -1792,30 +2335,30 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, e2FillType2 = m_SubjFillType; } - long64 e1Wc, e2Wc; + cInt e1Wc, e2Wc; switch (e1FillType) { - case pftPositive: e1Wc = e1->windCnt; break; - case pftNegative: e1Wc = -e1->windCnt; break; - default: e1Wc = Abs(e1->windCnt); + case pftPositive: e1Wc = e1->WindCnt; break; + case pftNegative: e1Wc = -e1->WindCnt; break; + default: e1Wc = Abs(e1->WindCnt); } switch(e2FillType) { - case pftPositive: e2Wc = e2->windCnt; break; - case pftNegative: e2Wc = -e2->windCnt; break; - default: e2Wc = Abs(e2->windCnt); + case pftPositive: e2Wc = e2->WindCnt; break; + case pftNegative: e2Wc = -e2->WindCnt; break; + default: e2Wc = Abs(e2->WindCnt); } - if ( e1Contributing && e2contributing ) + if ( e1Contributing && e2Contributing ) { if ( e1stops || e2stops || (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || - (e1->polyType != e2->polyType && m_ClipType != ctXor) ) - AddLocalMaxPoly(e1, e2, pt); + (e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) ) + AddLocalMaxPoly(e1, e2, Pt); else { - AddOutPt(e1, pt); - AddOutPt(e2, pt); + AddOutPt(e1, Pt); + AddOutPt(e2, Pt); SwapSides( *e1 , *e2 ); SwapPolyIndexes( *e1 , *e2 ); } @@ -1824,16 +2367,16 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, { if (e2Wc == 0 || e2Wc == 1) { - AddOutPt(e1, pt); + AddOutPt(e1, Pt); SwapSides(*e1, *e2); SwapPolyIndexes(*e1, *e2); } } - else if ( e2contributing ) + else if ( e2Contributing ) { if (e1Wc == 0 || e1Wc == 1) { - AddOutPt(e2, pt); + AddOutPt(e2, Pt); SwapSides(*e1, *e2); SwapPolyIndexes(*e1, *e2); } @@ -1843,46 +2386,46 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, { //neither edge is currently contributing ... - long64 e1Wc2, e2Wc2; + cInt e1Wc2, e2Wc2; switch (e1FillType2) { - case pftPositive: e1Wc2 = e1->windCnt2; break; - case pftNegative : e1Wc2 = -e1->windCnt2; break; - default: e1Wc2 = Abs(e1->windCnt2); + case pftPositive: e1Wc2 = e1->WindCnt2; break; + case pftNegative : e1Wc2 = -e1->WindCnt2; break; + default: e1Wc2 = Abs(e1->WindCnt2); } switch (e2FillType2) { - case pftPositive: e2Wc2 = e2->windCnt2; break; - case pftNegative: e2Wc2 = -e2->windCnt2; break; - default: e2Wc2 = Abs(e2->windCnt2); + case pftPositive: e2Wc2 = e2->WindCnt2; break; + case pftNegative: e2Wc2 = -e2->WindCnt2; break; + default: e2Wc2 = Abs(e2->WindCnt2); } - if (e1->polyType != e2->polyType) - AddLocalMinPoly(e1, e2, pt); + if (e1->PolyTyp != e2->PolyTyp) + AddLocalMinPoly(e1, e2, Pt); else if (e1Wc == 1 && e2Wc == 1) switch( m_ClipType ) { case ctIntersection: if (e1Wc2 > 0 && e2Wc2 > 0) - AddLocalMinPoly(e1, e2, pt); + AddLocalMinPoly(e1, e2, Pt); break; case ctUnion: if ( e1Wc2 <= 0 && e2Wc2 <= 0 ) - AddLocalMinPoly(e1, e2, pt); + AddLocalMinPoly(e1, e2, Pt); break; case ctDifference: - if (((e1->polyType == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || - ((e1->polyType == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) - AddLocalMinPoly(e1, e2, pt); + if (((e1->PolyTyp == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || + ((e1->PolyTyp == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) + AddLocalMinPoly(e1, e2, Pt); break; case ctXor: - AddLocalMinPoly(e1, e2, pt); + AddLocalMinPoly(e1, e2, Pt); } else SwapSides( *e1, *e2 ); } if( (e1stops != e2stops) && - ( (e1stops && (e1->outIdx >= 0)) || (e2stops && (e2->outIdx >= 0)) ) ) + ( (e1stops && (e1->OutIdx >= 0)) || (e2stops && (e2->OutIdx >= 0)) ) ) { SwapSides( *e1, *e2 ); SwapPolyIndexes( *e1, *e2 ); @@ -1896,38 +2439,38 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, void Clipper::SetHoleState(TEdge *e, OutRec *outrec) { - bool isHole = false; - TEdge *e2 = e->prevInAEL; + bool IsHole = false; + TEdge *e2 = e->PrevInAEL; while (e2) { - if (e2->outIdx >= 0) + if (e2->OutIdx >= 0 && e2->WindDelta != 0) { - isHole = !isHole; + IsHole = !IsHole; if (! outrec->FirstLeft) - outrec->FirstLeft = m_PolyOuts[e2->outIdx]; + outrec->FirstLeft = m_PolyOuts[e2->OutIdx]; } - e2 = e2->prevInAEL; + e2 = e2->PrevInAEL; } - if (isHole) outrec->isHole = true; + if (IsHole) outrec->IsHole = true; } //------------------------------------------------------------------------------ OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2) { //work out which polygon fragment has the correct hole state ... - if (!outRec1->bottomPt) - outRec1->bottomPt = GetBottomPt(outRec1->pts); - if (!outRec2->bottomPt) - outRec2->bottomPt = GetBottomPt(outRec2->pts); - OutPt *outPt1 = outRec1->bottomPt; - OutPt *outPt2 = outRec2->bottomPt; - if (outPt1->pt.Y > outPt2->pt.Y) return outRec1; - else if (outPt1->pt.Y < outPt2->pt.Y) return outRec2; - else if (outPt1->pt.X < outPt2->pt.X) return outRec1; - else if (outPt1->pt.X > outPt2->pt.X) return outRec2; - else if (outPt1->next == outPt1) return outRec2; - else if (outPt2->next == outPt2) return outRec1; - else if (FirstIsBottomPt(outPt1, outPt2)) return outRec1; + if (!outRec1->BottomPt) + outRec1->BottomPt = GetBottomPt(outRec1->Pts); + if (!outRec2->BottomPt) + outRec2->BottomPt = GetBottomPt(outRec2->Pts); + OutPt *OutPt1 = outRec1->BottomPt; + OutPt *OutPt2 = outRec2->BottomPt; + if (OutPt1->Pt.Y > OutPt2->Pt.Y) return outRec1; + else if (OutPt1->Pt.Y < OutPt2->Pt.Y) return outRec2; + else if (OutPt1->Pt.X < OutPt2->Pt.X) return outRec1; + else if (OutPt1->Pt.X > OutPt2->Pt.X) return outRec2; + else if (OutPt1->Next == OutPt1) return outRec2; + else if (OutPt2->Next == OutPt2) return outRec1; + else if (FirstIsBottomPt(OutPt1, OutPt2)) return outRec1; else return outRec2; } //------------------------------------------------------------------------------ @@ -1943,11 +2486,11 @@ bool Param1RightOfParam2(OutRec* outRec1, OutRec* outRec2) } //------------------------------------------------------------------------------ -OutRec* Clipper::GetOutRec(int idx) +OutRec* Clipper::GetOutRec(int Idx) { - OutRec* outrec = m_PolyOuts[idx]; - while (outrec != m_PolyOuts[outrec->idx]) - outrec = m_PolyOuts[outrec->idx]; + OutRec* outrec = m_PolyOuts[Idx]; + while (outrec != m_PolyOuts[outrec->Idx]) + outrec = m_PolyOuts[outrec->Idx]; return outrec; } //------------------------------------------------------------------------------ @@ -1955,8 +2498,8 @@ OutRec* Clipper::GetOutRec(int idx) void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) { //get the start and ends of both output polygons ... - OutRec *outRec1 = m_PolyOuts[e1->outIdx]; - OutRec *outRec2 = m_PolyOuts[e2->outIdx]; + OutRec *outRec1 = m_PolyOuts[e1->OutIdx]; + OutRec *outRec2 = m_PolyOuts[e2->OutIdx]; OutRec *holeStateRec; if (Param1RightOfParam2(outRec1, outRec2)) @@ -1966,381 +2509,473 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) else holeStateRec = GetLowermostRec(outRec1, outRec2); - OutPt* p1_lft = outRec1->pts; - OutPt* p1_rt = p1_lft->prev; - OutPt* p2_lft = outRec2->pts; - OutPt* p2_rt = p2_lft->prev; + //get the start and ends of both output polygons and + //join e2 poly onto e1 poly and delete pointers to e2 ... + + OutPt* p1_lft = outRec1->Pts; + OutPt* p1_rt = p1_lft->Prev; + OutPt* p2_lft = outRec2->Pts; + OutPt* p2_rt = p2_lft->Prev; - EdgeSide side; + EdgeSide Side; //join e2 poly onto e1 poly and delete pointers to e2 ... - if( e1->side == esLeft ) + if( e1->Side == esLeft ) { - if( e2->side == esLeft ) + if( e2->Side == esLeft ) { //z y x a b c ReversePolyPtLinks(p2_lft); - p2_lft->next = p1_lft; - p1_lft->prev = p2_lft; - p1_rt->next = p2_rt; - p2_rt->prev = p1_rt; - outRec1->pts = p2_rt; + p2_lft->Next = p1_lft; + p1_lft->Prev = p2_lft; + p1_rt->Next = p2_rt; + p2_rt->Prev = p1_rt; + outRec1->Pts = p2_rt; } else { //x y z a b c - p2_rt->next = p1_lft; - p1_lft->prev = p2_rt; - p2_lft->prev = p1_rt; - p1_rt->next = p2_lft; - outRec1->pts = p2_lft; + p2_rt->Next = p1_lft; + p1_lft->Prev = p2_rt; + p2_lft->Prev = p1_rt; + p1_rt->Next = p2_lft; + outRec1->Pts = p2_lft; } - side = esLeft; + Side = esLeft; } else { - if( e2->side == esRight ) + if( e2->Side == esRight ) { //a b c z y x ReversePolyPtLinks(p2_lft); - p1_rt->next = p2_rt; - p2_rt->prev = p1_rt; - p2_lft->next = p1_lft; - p1_lft->prev = p2_lft; + p1_rt->Next = p2_rt; + p2_rt->Prev = p1_rt; + p2_lft->Next = p1_lft; + p1_lft->Prev = p2_lft; } else { //a b c x y z - p1_rt->next = p2_lft; - p2_lft->prev = p1_rt; - p1_lft->prev = p2_rt; - p2_rt->next = p1_lft; + p1_rt->Next = p2_lft; + p2_lft->Prev = p1_rt; + p1_lft->Prev = p2_rt; + p2_rt->Next = p1_lft; } - side = esRight; + Side = esRight; } - outRec1->bottomPt = 0; + outRec1->BottomPt = 0; if (holeStateRec == outRec2) { if (outRec2->FirstLeft != outRec1) outRec1->FirstLeft = outRec2->FirstLeft; - outRec1->isHole = outRec2->isHole; + outRec1->IsHole = outRec2->IsHole; } - outRec2->pts = 0; - outRec2->bottomPt = 0; - + outRec2->Pts = 0; + outRec2->BottomPt = 0; outRec2->FirstLeft = outRec1; - int OKIdx = e1->outIdx; - int ObsoleteIdx = e2->outIdx; + int OKIdx = e1->OutIdx; + int ObsoleteIdx = e2->OutIdx; - e1->outIdx = -1; //nb: safe because we only get here via AddLocalMaxPoly - e2->outIdx = -1; + e1->OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly + e2->OutIdx = Unassigned; TEdge* e = m_ActiveEdges; while( e ) { - if( e->outIdx == ObsoleteIdx ) + if( e->OutIdx == ObsoleteIdx ) { - e->outIdx = OKIdx; - e->side = side; + e->OutIdx = OKIdx; + e->Side = Side; break; } - e = e->nextInAEL; + e = e->NextInAEL; } - outRec2->idx = outRec1->idx; + outRec2->Idx = outRec1->Idx; } //------------------------------------------------------------------------------ OutRec* Clipper::CreateOutRec() { OutRec* result = new OutRec; - result->isHole = false; + result->IsHole = false; + result->IsOpen = false; result->FirstLeft = 0; - result->pts = 0; - result->bottomPt = 0; - result->polyNode = 0; + result->Pts = 0; + result->BottomPt = 0; + result->PolyNd = 0; m_PolyOuts.push_back(result); - result->idx = (int)m_PolyOuts.size()-1; + result->Idx = (int)m_PolyOuts.size()-1; return result; } //------------------------------------------------------------------------------ -void Clipper::AddOutPt(TEdge *e, const IntPoint &pt) +OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt) { - bool ToFront = (e->side == esLeft); - if( e->outIdx < 0 ) + bool ToFront = (e->Side == esLeft); + if( e->OutIdx < 0 ) { OutRec *outRec = CreateOutRec(); - e->outIdx = outRec->idx; + outRec->IsOpen = (e->WindDelta == 0); OutPt* newOp = new OutPt; - outRec->pts = newOp; - newOp->pt = pt; - newOp->idx = outRec->idx; - newOp->next = newOp; - newOp->prev = newOp; - SetHoleState(e, outRec); + outRec->Pts = newOp; + newOp->Idx = outRec->Idx; + newOp->Pt = pt; + newOp->Next = newOp; + newOp->Prev = newOp; + if (!outRec->IsOpen) + SetHoleState(e, outRec); +#ifdef use_xyz + if (pt == e->Bot) newOp->Pt = e->Bot; + else if (pt == e->Top) newOp->Pt = e->Top; + else SetZ(newOp->Pt, *e); +#endif + e->OutIdx = outRec->Idx; //nb: do this after SetZ ! + return newOp; } else { - OutRec *outRec = m_PolyOuts[e->outIdx]; - OutPt* op = outRec->pts; - if ((ToFront && PointsEqual(pt, op->pt)) || - (!ToFront && PointsEqual(pt, op->prev->pt))) return; + OutRec *outRec = m_PolyOuts[e->OutIdx]; + //OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most' + OutPt* op = outRec->Pts; + + if (ToFront && (pt == op->Pt)) return op; + else if (!ToFront && (pt == op->Prev->Pt)) return op->Prev; OutPt* newOp = new OutPt; - newOp->pt = pt; - newOp->idx = outRec->idx; - newOp->next = op; - newOp->prev = op->prev; - newOp->prev->next = newOp; - op->prev = newOp; - if (ToFront) outRec->pts = newOp; + newOp->Idx = outRec->Idx; + newOp->Pt = pt; + newOp->Next = op; + newOp->Prev = op->Prev; + newOp->Prev->Next = newOp; + op->Prev = newOp; + if (ToFront) outRec->Pts = newOp; +#ifdef use_xyz + if (pt == e->Bot) newOp->Pt = e->Bot; + else if (pt == e->Top) newOp->Pt = e->Top; + else SetZ(newOp->Pt, *e); +#endif + return newOp; } } //------------------------------------------------------------------------------ -void Clipper::ProcessHorizontals() +void Clipper::ProcessHorizontals(bool IsTopOfScanbeam) { TEdge* horzEdge = m_SortedEdges; - while( horzEdge ) + while(horzEdge) { - DeleteFromSEL( horzEdge ); - ProcessHorizontal( horzEdge ); + DeleteFromSEL(horzEdge); + ProcessHorizontal(horzEdge, IsTopOfScanbeam); horzEdge = m_SortedEdges; } } //------------------------------------------------------------------------------ -bool Clipper::IsTopHorz(const long64 XPos) -{ - TEdge* e = m_SortedEdges; - while( e ) - { - if( ( XPos >= std::min(e->xcurr, e->xtop) ) && - ( XPos <= std::max(e->xcurr, e->xtop) ) ) return false; - e = e->nextInSEL; - } - return true; -} -//------------------------------------------------------------------------------ - inline bool IsMinima(TEdge *e) { - return e && (e->prev->nextInLML != e) && (e->next->nextInLML != e); + return e && (e->Prev->NextInLML != e) && (e->Next->NextInLML != e); } //------------------------------------------------------------------------------ -inline bool IsMaxima(TEdge *e, const long64 Y) +inline bool IsMaxima(TEdge *e, const cInt Y) { - return e && e->ytop == Y && !e->nextInLML; + return e && e->Top.Y == Y && !e->NextInLML; } //------------------------------------------------------------------------------ -inline bool IsIntermediate(TEdge *e, const long64 Y) +inline bool IsIntermediate(TEdge *e, const cInt Y) { - return e->ytop == Y && e->nextInLML; + return e->Top.Y == Y && e->NextInLML; } //------------------------------------------------------------------------------ TEdge *GetMaximaPair(TEdge *e) { - if( !IsMaxima(e->next, e->ytop) || e->next->xtop != e->xtop ) - return e->prev; else - return e->next; + TEdge* result = 0; + if ((e->Next->Top == e->Top) && !e->Next->NextInLML) + result = e->Next; + else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML) + result = e->Prev; + + if (result && (result->OutIdx == Skip || + //result is false if both NextInAEL & PrevInAEL are nil & not horizontal ... + (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) + return 0; + return result; } //------------------------------------------------------------------------------ -void Clipper::SwapPositionsInAEL(TEdge *edge1, TEdge *edge2) +void Clipper::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2) { - if( edge1->nextInAEL == edge2 ) + //check that one or other edge hasn't already been removed from AEL ... + if (Edge1->NextInAEL == Edge1->PrevInAEL || + Edge2->NextInAEL == Edge2->PrevInAEL) return; + + if( Edge1->NextInAEL == Edge2 ) { - TEdge* next = edge2->nextInAEL; - if( next ) next->prevInAEL = edge1; - TEdge* prev = edge1->prevInAEL; - if( prev ) prev->nextInAEL = edge2; - edge2->prevInAEL = prev; - edge2->nextInAEL = edge1; - edge1->prevInAEL = edge2; - edge1->nextInAEL = next; + TEdge* Next = Edge2->NextInAEL; + if( Next ) Next->PrevInAEL = Edge1; + TEdge* Prev = Edge1->PrevInAEL; + if( Prev ) Prev->NextInAEL = Edge2; + Edge2->PrevInAEL = Prev; + Edge2->NextInAEL = Edge1; + Edge1->PrevInAEL = Edge2; + Edge1->NextInAEL = Next; } - else if( edge2->nextInAEL == edge1 ) + else if( Edge2->NextInAEL == Edge1 ) { - TEdge* next = edge1->nextInAEL; - if( next ) next->prevInAEL = edge2; - TEdge* prev = edge2->prevInAEL; - if( prev ) prev->nextInAEL = edge1; - edge1->prevInAEL = prev; - edge1->nextInAEL = edge2; - edge2->prevInAEL = edge1; - edge2->nextInAEL = next; + TEdge* Next = Edge1->NextInAEL; + if( Next ) Next->PrevInAEL = Edge2; + TEdge* Prev = Edge2->PrevInAEL; + if( Prev ) Prev->NextInAEL = Edge1; + Edge1->PrevInAEL = Prev; + Edge1->NextInAEL = Edge2; + Edge2->PrevInAEL = Edge1; + Edge2->NextInAEL = Next; } else { - TEdge* next = edge1->nextInAEL; - TEdge* prev = edge1->prevInAEL; - edge1->nextInAEL = edge2->nextInAEL; - if( edge1->nextInAEL ) edge1->nextInAEL->prevInAEL = edge1; - edge1->prevInAEL = edge2->prevInAEL; - if( edge1->prevInAEL ) edge1->prevInAEL->nextInAEL = edge1; - edge2->nextInAEL = next; - if( edge2->nextInAEL ) edge2->nextInAEL->prevInAEL = edge2; - edge2->prevInAEL = prev; - if( edge2->prevInAEL ) edge2->prevInAEL->nextInAEL = edge2; + TEdge* Next = Edge1->NextInAEL; + TEdge* Prev = Edge1->PrevInAEL; + Edge1->NextInAEL = Edge2->NextInAEL; + if( Edge1->NextInAEL ) Edge1->NextInAEL->PrevInAEL = Edge1; + Edge1->PrevInAEL = Edge2->PrevInAEL; + if( Edge1->PrevInAEL ) Edge1->PrevInAEL->NextInAEL = Edge1; + Edge2->NextInAEL = Next; + if( Edge2->NextInAEL ) Edge2->NextInAEL->PrevInAEL = Edge2; + Edge2->PrevInAEL = Prev; + if( Edge2->PrevInAEL ) Edge2->PrevInAEL->NextInAEL = Edge2; } - if( !edge1->prevInAEL ) m_ActiveEdges = edge1; - else if( !edge2->prevInAEL ) m_ActiveEdges = edge2; + if( !Edge1->PrevInAEL ) m_ActiveEdges = Edge1; + else if( !Edge2->PrevInAEL ) m_ActiveEdges = Edge2; } //------------------------------------------------------------------------------ -void Clipper::SwapPositionsInSEL(TEdge *edge1, TEdge *edge2) +void Clipper::SwapPositionsInSEL(TEdge *Edge1, TEdge *Edge2) { - if( !( edge1->nextInSEL ) && !( edge1->prevInSEL ) ) return; - if( !( edge2->nextInSEL ) && !( edge2->prevInSEL ) ) return; + if( !( Edge1->NextInSEL ) && !( Edge1->PrevInSEL ) ) return; + if( !( Edge2->NextInSEL ) && !( Edge2->PrevInSEL ) ) return; - if( edge1->nextInSEL == edge2 ) + if( Edge1->NextInSEL == Edge2 ) { - TEdge* next = edge2->nextInSEL; - if( next ) next->prevInSEL = edge1; - TEdge* prev = edge1->prevInSEL; - if( prev ) prev->nextInSEL = edge2; - edge2->prevInSEL = prev; - edge2->nextInSEL = edge1; - edge1->prevInSEL = edge2; - edge1->nextInSEL = next; + TEdge* Next = Edge2->NextInSEL; + if( Next ) Next->PrevInSEL = Edge1; + TEdge* Prev = Edge1->PrevInSEL; + if( Prev ) Prev->NextInSEL = Edge2; + Edge2->PrevInSEL = Prev; + Edge2->NextInSEL = Edge1; + Edge1->PrevInSEL = Edge2; + Edge1->NextInSEL = Next; } - else if( edge2->nextInSEL == edge1 ) + else if( Edge2->NextInSEL == Edge1 ) { - TEdge* next = edge1->nextInSEL; - if( next ) next->prevInSEL = edge2; - TEdge* prev = edge2->prevInSEL; - if( prev ) prev->nextInSEL = edge1; - edge1->prevInSEL = prev; - edge1->nextInSEL = edge2; - edge2->prevInSEL = edge1; - edge2->nextInSEL = next; + TEdge* Next = Edge1->NextInSEL; + if( Next ) Next->PrevInSEL = Edge2; + TEdge* Prev = Edge2->PrevInSEL; + if( Prev ) Prev->NextInSEL = Edge1; + Edge1->PrevInSEL = Prev; + Edge1->NextInSEL = Edge2; + Edge2->PrevInSEL = Edge1; + Edge2->NextInSEL = Next; } else { - TEdge* next = edge1->nextInSEL; - TEdge* prev = edge1->prevInSEL; - edge1->nextInSEL = edge2->nextInSEL; - if( edge1->nextInSEL ) edge1->nextInSEL->prevInSEL = edge1; - edge1->prevInSEL = edge2->prevInSEL; - if( edge1->prevInSEL ) edge1->prevInSEL->nextInSEL = edge1; - edge2->nextInSEL = next; - if( edge2->nextInSEL ) edge2->nextInSEL->prevInSEL = edge2; - edge2->prevInSEL = prev; - if( edge2->prevInSEL ) edge2->prevInSEL->nextInSEL = edge2; + TEdge* Next = Edge1->NextInSEL; + TEdge* Prev = Edge1->PrevInSEL; + Edge1->NextInSEL = Edge2->NextInSEL; + if( Edge1->NextInSEL ) Edge1->NextInSEL->PrevInSEL = Edge1; + Edge1->PrevInSEL = Edge2->PrevInSEL; + if( Edge1->PrevInSEL ) Edge1->PrevInSEL->NextInSEL = Edge1; + Edge2->NextInSEL = Next; + if( Edge2->NextInSEL ) Edge2->NextInSEL->PrevInSEL = Edge2; + Edge2->PrevInSEL = Prev; + if( Edge2->PrevInSEL ) Edge2->PrevInSEL->NextInSEL = Edge2; } - if( !edge1->prevInSEL ) m_SortedEdges = edge1; - else if( !edge2->prevInSEL ) m_SortedEdges = edge2; + if( !Edge1->PrevInSEL ) m_SortedEdges = Edge1; + else if( !Edge2->PrevInSEL ) m_SortedEdges = Edge2; } //------------------------------------------------------------------------------ TEdge* GetNextInAEL(TEdge *e, Direction dir) { - return dir == dLeftToRight ? e->nextInAEL : e->prevInAEL; + return dir == dLeftToRight ? e->NextInAEL : e->PrevInAEL; } //------------------------------------------------------------------------------ -void Clipper::ProcessHorizontal(TEdge *horzEdge) +void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cInt& Right) { - Direction dir; - long64 horzLeft, horzRight; - - if( horzEdge->xcurr < horzEdge->xtop ) + if (HorzEdge.Bot.X < HorzEdge.Top.X) { - horzLeft = horzEdge->xcurr; - horzRight = horzEdge->xtop; - dir = dLeftToRight; + Left = HorzEdge.Bot.X; + Right = HorzEdge.Top.X; + Dir = dLeftToRight; } else { - horzLeft = horzEdge->xtop; - horzRight = horzEdge->xcurr; - dir = dRightToLeft; + Left = HorzEdge.Top.X; + Right = HorzEdge.Bot.X; + Dir = dRightToLeft; } +} +//------------------------------------------------------------------------ - TEdge* eMaxPair; - if( horzEdge->nextInLML ) eMaxPair = 0; - else eMaxPair = GetMaximaPair(horzEdge); +void Clipper::PrepareHorzJoins(TEdge* horzEdge, bool isTopOfScanbeam) +{ + //get the last Op for this horizontal edge + //the point may be anywhere along the horizontal ... + OutPt* outPt = m_PolyOuts[horzEdge->OutIdx]->Pts; + if (horzEdge->Side != esLeft) outPt = outPt->Prev; - TEdge* e = GetNextInAEL( horzEdge , dir ); - while( e ) + //First, match up overlapping horizontal edges (eg when one polygon's + //intermediate horz edge overlaps an intermediate horz edge of another, or + //when one polygon sits on top of another) ... + for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i) { - if ( e->xcurr == horzEdge->xtop && !eMaxPair ) - { - if (SlopesEqual(*e, *horzEdge->nextInLML, m_UseFullRange)) - { - //if output polygons share an edge, they'll need joining later ... - if (horzEdge->outIdx >= 0 && e->outIdx >= 0) - AddJoin(horzEdge->nextInLML, e, horzEdge->outIdx); - break; //we've reached the end of the horizontal line - } - else if (e->dx < horzEdge->nextInLML->dx) - //we really have got to the end of the intermediate horz edge so quit. - //nb: More -ve slopes follow more +ve slopes ABOVE the horizontal. - break; - } + Join* j = m_GhostJoins[i]; + if (HorzSegmentsOverlap(j->OutPt1->Pt, j->OffPt, horzEdge->Bot, horzEdge->Top)) + AddJoin(j->OutPt1, outPt, j->OffPt); + } + //Also, since horizontal edges at the top of one SB are often removed from + //the AEL before we process the horizontal edges at the bottom of the next, + //we need to create 'ghost' Join records of 'contrubuting' horizontals that + //we can compare with horizontals at the bottom of the next SB. + if (isTopOfScanbeam) + if (outPt->Pt == horzEdge->Top) + AddGhostJoin(outPt, horzEdge->Bot); + else + AddGhostJoin(outPt, horzEdge->Top); +} +//------------------------------------------------------------------------------ + +/******************************************************************************* +* Notes: Horizontal edges (HEs) at scanline intersections (ie at the Top or * +* Bottom of a scanbeam) are processed as if layered. The order in which HEs * +* are processed doesn't matter. HEs intersect with other HE Bot.Xs only [#] * +* (or they could intersect with Top.Xs only, ie EITHER Bot.Xs OR Top.Xs), * +* and with other non-horizontal edges [*]. Once these intersections are * +* processed, intermediate HEs then 'promote' the Edge above (NextInLML) into * +* the AEL. These 'promoted' edges may in turn intersect [%] with other HEs. * +*******************************************************************************/ + +void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam) +{ + Direction dir; + cInt horzLeft, horzRight; + + GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); - TEdge* eNext = GetNextInAEL( e, dir ); + TEdge* eLastHorz = horzEdge, *eMaxPair = 0; + while (eLastHorz->NextInLML && IsHorizontal(*eLastHorz->NextInLML)) + eLastHorz = eLastHorz->NextInLML; + if (!eLastHorz->NextInLML) + eMaxPair = GetMaximaPair(eLastHorz); - if (eMaxPair || - ((dir == dLeftToRight) && (e->xcurr < horzRight)) || - ((dir == dRightToLeft) && (e->xcurr > horzLeft))) + for (;;) + { + bool IsLastHorz = (horzEdge == eLastHorz); + TEdge* e = GetNextInAEL(horzEdge, dir); + while(e) { - //so far we're still in range of the horizontal edge - if( e == eMaxPair ) - { - //horzEdge is evidently a maxima horizontal and we've arrived at its end. - if (dir == dLeftToRight) - IntersectEdges(horzEdge, e, IntPoint(e->xcurr, horzEdge->ycurr), ipNone); - else - IntersectEdges(e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr), ipNone); - if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error"); - return; - } - else if( NEAR_EQUAL(e->dx, HORIZONTAL) && !IsMinima(e) && !(e->xcurr > e->xtop) ) + //Break if we've got to the end of an intermediate horizontal edge ... + //nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal. + if (e->Curr.X == horzEdge->Top.X && horzEdge->NextInLML && + e->Dx < horzEdge->NextInLML->Dx) break; + + TEdge* eNext = GetNextInAEL(e, dir); //saves eNext for later + + if ((dir == dLeftToRight && e->Curr.X <= horzRight) || + (dir == dRightToLeft && e->Curr.X >= horzLeft)) { - //An overlapping horizontal edge. Overlapping horizontal edges are - //processed as if layered with the current horizontal edge (horizEdge) - //being infinitesimally lower that the next (e). Therfore, we - //intersect with e only if e.xcurr is within the bounds of horzEdge ... - if( dir == dLeftToRight ) - IntersectEdges( horzEdge , e, IntPoint(e->xcurr, horzEdge->ycurr), - (IsTopHorz( e->xcurr ))? ipLeft : ipBoth ); + //so far we're still in range of the horizontal Edge but make sure + //we're at the last of consec. horizontals when matching with eMaxPair + if(e == eMaxPair && IsLastHorz) + { + if (horzEdge->OutIdx >= 0 && horzEdge->WindDelta != 0) + PrepareHorzJoins(horzEdge, isTopOfScanbeam); + if (dir == dLeftToRight) + IntersectEdges(horzEdge, e, e->Top); + else + IntersectEdges(e, horzEdge, e->Top); + if (eMaxPair->OutIdx >= 0) throw clipperException("ProcessHorizontal error"); + return; + } + else if(dir == dLeftToRight) + { + IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y); + IntersectEdges(horzEdge, e, Pt, true); + } else - IntersectEdges( e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr), - (IsTopHorz( e->xcurr ))? ipRight : ipBoth ); + { + IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y); + IntersectEdges( e, horzEdge, Pt, true); + } + SwapPositionsInAEL( horzEdge, e ); } - else if( dir == dLeftToRight ) + else if( (dir == dLeftToRight && e->Curr.X >= horzRight) || + (dir == dRightToLeft && e->Curr.X <= horzLeft) ) break; + e = eNext; + } //end while + + if (horzEdge->OutIdx >= 0 && horzEdge->WindDelta != 0) + PrepareHorzJoins(horzEdge, isTopOfScanbeam); + + if (horzEdge->NextInLML && IsHorizontal(*horzEdge->NextInLML)) + { + UpdateEdgeIntoAEL(horzEdge); + if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Bot); + GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); + } else + break; + } //end for (;;) + + if(horzEdge->NextInLML) + { + if(horzEdge->OutIdx >= 0) + { + OutPt* op1 = AddOutPt( horzEdge, horzEdge->Top); + UpdateEdgeIntoAEL(horzEdge); + if (horzEdge->WindDelta == 0) return; + //nb: HorzEdge is no longer horizontal here + TEdge* ePrev = horzEdge->PrevInAEL; + TEdge* eNext = horzEdge->NextInAEL; + if (ePrev && ePrev->Curr.X == horzEdge->Bot.X && + ePrev->Curr.Y == horzEdge->Bot.Y && ePrev->WindDelta != 0 && + (ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y && + SlopesEqual(*horzEdge, *ePrev, m_UseFullRange))) { - IntersectEdges( horzEdge, e, IntPoint(e->xcurr, horzEdge->ycurr), - (IsTopHorz( e->xcurr ))? ipLeft : ipBoth ); + OutPt* op2 = AddOutPt(ePrev, horzEdge->Bot); + AddJoin(op1, op2, horzEdge->Top); } - else + else if (eNext && eNext->Curr.X == horzEdge->Bot.X && + eNext->Curr.Y == horzEdge->Bot.Y && eNext->WindDelta != 0 && + eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y && + SlopesEqual(*horzEdge, *eNext, m_UseFullRange)) { - IntersectEdges( e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr), - (IsTopHorz( e->xcurr ))? ipRight : ipBoth ); + OutPt* op2 = AddOutPt(eNext, horzEdge->Bot); + AddJoin(op1, op2, horzEdge->Top); } - SwapPositionsInAEL( horzEdge, e ); } - else if( (dir == dLeftToRight && e->xcurr >= horzRight) || - (dir == dRightToLeft && e->xcurr <= horzLeft) ) break; - e = eNext; - } //end while - - if( horzEdge->nextInLML ) - { - if( horzEdge->outIdx >= 0 ) - AddOutPt( horzEdge, IntPoint(horzEdge->xtop, horzEdge->ytop)); - UpdateEdgeIntoAEL( horzEdge ); + else + UpdateEdgeIntoAEL(horzEdge); } - else + else if (eMaxPair) { - if ( horzEdge->outIdx >= 0 ) - IntersectEdges( horzEdge, eMaxPair, - IntPoint(horzEdge->xtop, horzEdge->ycurr), ipBoth); - if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error"); - DeleteFromAEL(eMaxPair); + if (eMaxPair->OutIdx >= 0) + { + if (dir == dLeftToRight) + IntersectEdges(horzEdge, eMaxPair, horzEdge->Top); + else + IntersectEdges(eMaxPair, horzEdge, horzEdge->Top); + if (eMaxPair->OutIdx >= 0) + throw clipperException("ProcessHorizontal error"); + } else + { + DeleteFromAEL(horzEdge); + DeleteFromAEL(eMaxPair); + } + } else + { + if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Top); DeleteFromAEL(horzEdge); } } @@ -2348,35 +2983,38 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge) void Clipper::UpdateEdgeIntoAEL(TEdge *&e) { - if( !e->nextInLML ) throw + if( !e->NextInLML ) throw clipperException("UpdateEdgeIntoAEL: invalid call"); - TEdge* AelPrev = e->prevInAEL; - TEdge* AelNext = e->nextInAEL; - e->nextInLML->outIdx = e->outIdx; - if( AelPrev ) AelPrev->nextInAEL = e->nextInLML; - else m_ActiveEdges = e->nextInLML; - if( AelNext ) AelNext->prevInAEL = e->nextInLML; - e->nextInLML->side = e->side; - e->nextInLML->windDelta = e->windDelta; - e->nextInLML->windCnt = e->windCnt; - e->nextInLML->windCnt2 = e->windCnt2; - e = e->nextInLML; - e->prevInAEL = AelPrev; - e->nextInAEL = AelNext; - if( !NEAR_EQUAL(e->dx, HORIZONTAL) ) InsertScanbeam( e->ytop ); + + e->NextInLML->OutIdx = e->OutIdx; + TEdge* AelPrev = e->PrevInAEL; + TEdge* AelNext = e->NextInAEL; + if (AelPrev) AelPrev->NextInAEL = e->NextInLML; + else m_ActiveEdges = e->NextInLML; + if (AelNext) AelNext->PrevInAEL = e->NextInLML; + e->NextInLML->Side = e->Side; + e->NextInLML->WindDelta = e->WindDelta; + e->NextInLML->WindCnt = e->WindCnt; + e->NextInLML->WindCnt2 = e->WindCnt2; + e = e->NextInLML; + e->Curr = e->Bot; + e->PrevInAEL = AelPrev; + e->NextInAEL = AelNext; + if (!IsHorizontal(*e)) InsertScanbeam(e->Top.Y); } //------------------------------------------------------------------------------ -bool Clipper::ProcessIntersections(const long64 botY, const long64 topY) +bool Clipper::ProcessIntersections(const cInt botY, const cInt topY) { if( !m_ActiveEdges ) return true; try { BuildIntersectList(botY, topY); if (!m_IntersectNodes) return true; - if (!m_IntersectNodes->next || FixupIntersectionOrder()) ProcessIntersectList(); + if (!m_IntersectNodes->Next || FixupIntersectionOrder()) ProcessIntersectList(); else return false; } - catch(...) { + catch(...) + { m_SortedEdges = 0; DisposeIntersectNodes(); throw clipperException("ProcessIntersections error"); @@ -2390,14 +3028,14 @@ void Clipper::DisposeIntersectNodes() { while ( m_IntersectNodes ) { - IntersectNode* iNode = m_IntersectNodes->next; + IntersectNode* iNode = m_IntersectNodes->Next; delete m_IntersectNodes; m_IntersectNodes = iNode; } } //------------------------------------------------------------------------------ -void Clipper::BuildIntersectList(const long64 botY, const long64 topY) +void Clipper::BuildIntersectList(const cInt botY, const cInt topY) { if ( !m_ActiveEdges ) return; @@ -2406,10 +3044,10 @@ void Clipper::BuildIntersectList(const long64 botY, const long64 topY) m_SortedEdges = e; while( e ) { - e->prevInSEL = e->prevInAEL; - e->nextInSEL = e->nextInAEL; - e->xcurr = TopX( *e, topY ); - e = e->nextInAEL; + e->PrevInSEL = e->PrevInAEL; + e->NextInSEL = e->NextInAEL; + e->Curr.X = TopX( *e, topY ); + e = e->NextInAEL; } //bubblesort ... @@ -2418,27 +3056,29 @@ void Clipper::BuildIntersectList(const long64 botY, const long64 topY) { isModified = false; e = m_SortedEdges; - while( e->nextInSEL ) + while( e->NextInSEL ) { - TEdge *eNext = e->nextInSEL; - IntPoint pt; - if(e->xcurr > eNext->xcurr) + TEdge *eNext = e->NextInSEL; + IntPoint Pt; + if(e->Curr.X > eNext->Curr.X) { - if (!IntersectPoint(*e, *eNext, pt, m_UseFullRange) && e->xcurr > eNext->xcurr +1) + if (!IntersectPoint(*e, *eNext, Pt, m_UseFullRange) && e->Curr.X > eNext->Curr.X +1) throw clipperException("Intersection error"); - if (pt.Y > botY) + if (Pt.Y > botY) { - pt.Y = botY; - pt.X = TopX(*e, pt.Y); + Pt.Y = botY; + if (std::fabs(e->Dx) > std::fabs(eNext->Dx)) + Pt.X = TopX(*eNext, botY); else + Pt.X = TopX(*e, botY); } - InsertIntersectNode( e, eNext, pt ); + InsertIntersectNode( e, eNext, Pt ); SwapPositionsInSEL(e, eNext); isModified = true; } else e = eNext; } - if( e->prevInSEL ) e->prevInSEL->nextInSEL = 0; + if( e->PrevInSEL ) e->PrevInSEL->NextInSEL = 0; else break; } while ( isModified ); @@ -2446,26 +3086,26 @@ void Clipper::BuildIntersectList(const long64 botY, const long64 topY) } //------------------------------------------------------------------------------ -void Clipper::InsertIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt) +void Clipper::InsertIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &Pt) { IntersectNode* newNode = new IntersectNode; - newNode->edge1 = e1; - newNode->edge2 = e2; - newNode->pt = pt; - newNode->next = 0; + newNode->Edge1 = e1; + newNode->Edge2 = e2; + newNode->Pt = Pt; + newNode->Next = 0; if( !m_IntersectNodes ) m_IntersectNodes = newNode; - else if(newNode->pt.Y > m_IntersectNodes->pt.Y ) + else if(newNode->Pt.Y > m_IntersectNodes->Pt.Y ) { - newNode->next = m_IntersectNodes; + newNode->Next = m_IntersectNodes; m_IntersectNodes = newNode; } else { IntersectNode* iNode = m_IntersectNodes; - while(iNode->next && newNode->pt.Y <= iNode->next->pt.Y) - iNode = iNode->next; - newNode->next = iNode->next; - iNode->next = newNode; + while(iNode->Next && newNode->Pt.Y <= iNode->Next->Pt.Y) + iNode = iNode->Next; + newNode->Next = iNode->Next; + iNode->Next = newNode; } } //------------------------------------------------------------------------------ @@ -2474,11 +3114,11 @@ void Clipper::ProcessIntersectList() { while( m_IntersectNodes ) { - IntersectNode* iNode = m_IntersectNodes->next; + IntersectNode* iNode = m_IntersectNodes->Next; { - IntersectEdges( m_IntersectNodes->edge1 , - m_IntersectNodes->edge2 , m_IntersectNodes->pt, ipBoth ); - SwapPositionsInAEL( m_IntersectNodes->edge1 , m_IntersectNodes->edge2 ); + IntersectEdges( m_IntersectNodes->Edge1 , + m_IntersectNodes->Edge2 , m_IntersectNodes->Pt, true); + SwapPositionsInAEL( m_IntersectNodes->Edge1 , m_IntersectNodes->Edge2 ); } delete m_IntersectNodes; m_IntersectNodes = iNode; @@ -2486,123 +3126,147 @@ void Clipper::ProcessIntersectList() } //------------------------------------------------------------------------------ -void Clipper::DoMaxima(TEdge *e, long64 topY) +void Clipper::DoMaxima(TEdge *e) { TEdge* eMaxPair = GetMaximaPair(e); - long64 X = e->xtop; - TEdge* eNext = e->nextInAEL; - while( eNext != eMaxPair ) + if (!eMaxPair) + { + if (e->OutIdx >= 0) + AddOutPt(e, e->Top); + DeleteFromAEL(e); + return; + } + + TEdge* eNext = e->NextInAEL; + while(eNext && eNext != eMaxPair) { - if (!eNext) throw clipperException("DoMaxima error"); - IntersectEdges( e, eNext, IntPoint(X, topY), ipBoth ); + IntersectEdges(e, eNext, e->Top, true); SwapPositionsInAEL(e, eNext); - eNext = e->nextInAEL; + eNext = e->NextInAEL; } - if( e->outIdx < 0 && eMaxPair->outIdx < 0 ) + + if(e->OutIdx == Unassigned && eMaxPair->OutIdx == Unassigned) { - DeleteFromAEL( e ); - DeleteFromAEL( eMaxPair ); + DeleteFromAEL(e); + DeleteFromAEL(eMaxPair); } - else if( e->outIdx >= 0 && eMaxPair->outIdx >= 0 ) + else if( e->OutIdx >= 0 && eMaxPair->OutIdx >= 0 ) { - IntersectEdges( e, eMaxPair, IntPoint(X, topY), ipNone ); + IntersectEdges( e, eMaxPair, e->Top); } +#ifdef use_lines + else if (e->WindDelta == 0) + { + if (e->OutIdx >= 0) + { + AddOutPt(e, e->Top); + e->OutIdx = Unassigned; + } + DeleteFromAEL(e); + + if (eMaxPair->OutIdx >= 0) + { + AddOutPt(eMaxPair, e->Top); + eMaxPair->OutIdx = Unassigned; + } + DeleteFromAEL(eMaxPair); + } +#endif else throw clipperException("DoMaxima error"); } //------------------------------------------------------------------------------ -void Clipper::ProcessEdgesAtTopOfScanbeam(const long64 topY) +void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) { TEdge* e = m_ActiveEdges; while( e ) { //1. process maxima, treating them as if they're 'bent' horizontal edges, // but exclude maxima with horizontal edges. nb: e can't be a horizontal. - if( IsMaxima(e, topY) && !NEAR_EQUAL(GetMaximaPair(e)->dx, HORIZONTAL) ) + bool IsMaximaEdge = IsMaxima(e, topY); + + if(IsMaximaEdge) { - //'e' might be removed from AEL, as may any following edges so ... - TEdge* ePrev = e->prevInAEL; - DoMaxima(e, topY); + TEdge* eMaxPair = GetMaximaPair(e); + IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair)); + } + + if(IsMaximaEdge) + { + TEdge* ePrev = e->PrevInAEL; + DoMaxima(e); if( !ePrev ) e = m_ActiveEdges; - else e = ePrev->nextInAEL; + else e = ePrev->NextInAEL; } else { - bool intermediateVert = IsIntermediate(e, topY); - //2. promote horizontal edges, otherwise update xcurr and ycurr ... - if (intermediateVert && NEAR_EQUAL(e->nextInLML->dx, HORIZONTAL) ) + //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ... + if (IsIntermediate(e, topY) && IsHorizontal(*e->NextInLML)) { - if (e->outIdx >= 0) - { - AddOutPt(e, IntPoint(e->xtop, e->ytop)); - - for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i) - { - IntPoint pt, pt2; - HorzJoinRec* hj = m_HorizJoins[i]; - if (GetOverlapSegment(IntPoint(hj->edge->xbot, hj->edge->ybot), - IntPoint(hj->edge->xtop, hj->edge->ytop), - IntPoint(e->nextInLML->xbot, e->nextInLML->ybot), - IntPoint(e->nextInLML->xtop, e->nextInLML->ytop), pt, pt2)) - AddJoin(hj->edge, e->nextInLML, hj->savedIdx, e->outIdx); - } - - AddHorzJoin(e->nextInLML, e->outIdx); - } UpdateEdgeIntoAEL(e); + if (e->OutIdx >= 0) + AddOutPt(e, e->Bot); AddEdgeToSEL(e); - } else + } + else { - e->xcurr = TopX( *e, topY ); - e->ycurr = topY; + e->Curr.X = TopX( *e, topY ); + e->Curr.Y = topY; + } - if (m_ForceSimple && e->prevInAEL && - e->prevInAEL->xcurr == e->xcurr && - e->outIdx >= 0 && e->prevInAEL->outIdx >= 0) + if (m_StrictSimple) + { + TEdge* ePrev = e->PrevInAEL; + if ((e->OutIdx >= 0) && (e->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) && + (ePrev->Curr.X == e->Curr.X) && (ePrev->WindDelta != 0)) { - if (intermediateVert) - AddOutPt(e->prevInAEL, IntPoint(e->xcurr, topY)); - else - AddOutPt(e, IntPoint(e->xcurr, topY)); + OutPt* op = AddOutPt(ePrev, e->Curr); + OutPt* op2 = AddOutPt(e, e->Curr); + AddJoin(op, op2, e->Curr); //StrictlySimple (type-3) join } } - e = e->nextInAEL; + + e = e->NextInAEL; } } - //3. Process horizontals at the top of the scanbeam ... - ProcessHorizontals(); + //3. Process horizontals at the Top of the scanbeam ... + ProcessHorizontals(true); //4. Promote intermediate vertices ... e = m_ActiveEdges; - while( e ) + while(e) { - if( IsIntermediate( e, topY ) ) + if(IsIntermediate(e, topY)) { - if( e->outIdx >= 0 ) AddOutPt(e, IntPoint(e->xtop,e->ytop)); + OutPt* op = 0; + if( e->OutIdx >= 0 ) + op = AddOutPt(e, e->Top); UpdateEdgeIntoAEL(e); //if output polygons share an edge, they'll need joining later ... - TEdge* ePrev = e->prevInAEL; - TEdge* eNext = e->nextInAEL; - if (ePrev && ePrev->xcurr == e->xbot && - ePrev->ycurr == e->ybot && e->outIdx >= 0 && - ePrev->outIdx >= 0 && ePrev->ycurr > ePrev->ytop && - SlopesEqual(*e, *ePrev, m_UseFullRange)) + TEdge* ePrev = e->PrevInAEL; + TEdge* eNext = e->NextInAEL; + if (ePrev && ePrev->Curr.X == e->Bot.X && + ePrev->Curr.Y == e->Bot.Y && op && + ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y && + SlopesEqual(*e, *ePrev, m_UseFullRange) && + (e->WindDelta != 0) && (ePrev->WindDelta != 0)) { - AddOutPt(ePrev, IntPoint(e->xbot, e->ybot)); - AddJoin(e, ePrev); + OutPt* op2 = AddOutPt(ePrev, e->Bot); + AddJoin(op, op2, e->Top); } - else if (eNext && eNext->xcurr == e->xbot && - eNext->ycurr == e->ybot && e->outIdx >= 0 && - eNext->outIdx >= 0 && eNext->ycurr > eNext->ytop && - SlopesEqual(*e, *eNext, m_UseFullRange)) + else if (eNext && eNext->Curr.X == e->Bot.X && + eNext->Curr.Y == e->Bot.Y && op && + eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y && + SlopesEqual(*e, *eNext, m_UseFullRange) && + (e->WindDelta != 0) && (eNext->WindDelta != 0)) { - AddOutPt(eNext, IntPoint(e->xbot, e->ybot)); - AddJoin(e, eNext); + OutPt* op2 = AddOutPt(eNext, e->Bot); + AddJoin(op, op2, e->Top); } } - e = e->nextInAEL; + e = e->NextInAEL; } } //------------------------------------------------------------------------------ @@ -2612,72 +3276,75 @@ void Clipper::FixupOutPolygon(OutRec &outrec) //FixupOutPolygon() - removes duplicate points and simplifies consecutive //parallel edges by removing the middle vertex. OutPt *lastOK = 0; - outrec.bottomPt = 0; - OutPt *pp = outrec.pts; + outrec.BottomPt = 0; + OutPt *pp = outrec.Pts; for (;;) { - if (pp->prev == pp || pp->prev == pp->next ) + if (pp->Prev == pp || pp->Prev == pp->Next ) { DisposeOutPts(pp); - outrec.pts = 0; + outrec.Pts = 0; return; } - //test for duplicate points and for same slope (cross-product) ... - if ( PointsEqual(pp->pt, pp->next->pt) || - SlopesEqual(pp->prev->pt, pp->pt, pp->next->pt, m_UseFullRange) ) + + //test for duplicate points and collinear edges ... + if ((pp->Pt == pp->Next->Pt) || (pp->Pt == pp->Prev->Pt) || + (SlopesEqual(pp->Prev->Pt, pp->Pt, pp->Next->Pt, m_UseFullRange) && + (!m_PreserveCollinear || + !Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt)))) { lastOK = 0; OutPt *tmp = pp; - pp->prev->next = pp->next; - pp->next->prev = pp->prev; - pp = pp->prev; + pp->Prev->Next = pp->Next; + pp->Next->Prev = pp->Prev; + pp = pp->Prev; delete tmp; } else if (pp == lastOK) break; else { if (!lastOK) lastOK = pp; - pp = pp->next; + pp = pp->Next; } } - outrec.pts = pp; + outrec.Pts = pp; } //------------------------------------------------------------------------------ -void Clipper::BuildResult(Polygons &polys) +int PointCount(OutPt *Pts) { - polys.reserve(m_PolyOuts.size()); - for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) - { - if (m_PolyOuts[i]->pts) + if (!Pts) return 0; + int result = 0; + OutPt* p = Pts; + do { - Polygon pg; - OutPt* p = m_PolyOuts[i]->pts; - do - { - pg.push_back(p->pt); - p = p->prev; - } while (p != m_PolyOuts[i]->pts); - if (pg.size() > 2) - polys.push_back(pg); + result++; + p = p->Next; } - } + while (p != Pts); + return result; } //------------------------------------------------------------------------------ -int PointCount(OutPt *pts) +void Clipper::BuildResult(Paths &polys) { - if (!pts) return 0; - int result = 0; - OutPt* p = pts; - do + polys.reserve(m_PolyOuts.size()); + for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) + { + if (!m_PolyOuts[i]->Pts) continue; + Path pg; + OutPt* p = m_PolyOuts[i]->Pts->Prev; + int cnt = PointCount(p); + if (cnt < 2) continue; + pg.reserve(cnt); + for (int i = 0; i < cnt; ++i) { - result++; - p = p->next; + pg.push_back(p->Pt); + p = p->Prev; } - while (p != pts); - return result; + polys.push_back(pg); + } } //------------------------------------------------------------------------------ @@ -2689,21 +3356,21 @@ void Clipper::BuildResult2(PolyTree& polytree) for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++) { OutRec* outRec = m_PolyOuts[i]; - int cnt = PointCount(outRec->pts); - if (cnt < 3) continue; + int cnt = PointCount(outRec->Pts); + if ((outRec->IsOpen && cnt < 2) || (!outRec->IsOpen && cnt < 3)) continue; FixHoleLinkage(*outRec); PolyNode* pn = new PolyNode(); //nb: polytree takes ownership of all the PolyNodes polytree.AllNodes.push_back(pn); - outRec->polyNode = pn; + outRec->PolyNd = pn; pn->Parent = 0; pn->Index = 0; pn->Contour.reserve(cnt); - OutPt *op = outRec->pts; + OutPt *op = outRec->Pts->Prev; for (int j = 0; j < cnt; j++) { - pn->Contour.push_back(op->pt); - op = op->prev; + pn->Contour.push_back(op->Pt); + op = op->Prev; } } @@ -2712,11 +3379,16 @@ void Clipper::BuildResult2(PolyTree& polytree) for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++) { OutRec* outRec = m_PolyOuts[i]; - if (!outRec->polyNode) continue; - if (outRec->FirstLeft) - outRec->FirstLeft->polyNode->AddChild(*outRec->polyNode); + if (!outRec->PolyNd) continue; + if (outRec->IsOpen) + { + outRec->PolyNd->m_IsOpen = true; + polytree.AddChild(*outRec->PolyNd); + } + else if (outRec->FirstLeft) + outRec->FirstLeft->PolyNd->AddChild(*outRec->PolyNd); else - polytree.AddChild(*outRec->polyNode); + polytree.AddChild(*outRec->PolyNd); } } //------------------------------------------------------------------------------ @@ -2725,25 +3397,25 @@ void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2) { //just swap the contents (because fIntersectNodes is a single-linked-list) IntersectNode inode = int1; //gets a copy of Int1 - int1.edge1 = int2.edge1; - int1.edge2 = int2.edge2; - int1.pt = int2.pt; - int2.edge1 = inode.edge1; - int2.edge2 = inode.edge2; - int2.pt = inode.pt; + int1.Edge1 = int2.Edge1; + int1.Edge2 = int2.Edge2; + int1.Pt = int2.Pt; + int2.Edge1 = inode.Edge1; + int2.Edge2 = inode.Edge2; + int2.Pt = inode.Pt; } //------------------------------------------------------------------------------ inline bool EdgesAdjacent(const IntersectNode &inode) { - return (inode.edge1->nextInSEL == inode.edge2) || - (inode.edge1->prevInSEL == inode.edge2); + return (inode.Edge1->NextInSEL == inode.Edge2) || + (inode.Edge1->PrevInSEL == inode.Edge2); } //------------------------------------------------------------------------------ bool Clipper::FixupIntersectionOrder() { - //pre-condition: intersections are sorted bottom-most (then left-most) first. + //pre-condition: intersections are sorted Bottom-most (then Left-most) first. //Now it's crucial that intersections are made only between adjacent edges, //so to ensure this the order of intersections may need adjusting ... IntersectNode *inode = m_IntersectNodes; @@ -2752,15 +3424,15 @@ bool Clipper::FixupIntersectionOrder() { if (!EdgesAdjacent(*inode)) { - IntersectNode *nextNode = inode->next; + IntersectNode *nextNode = inode->Next; while (nextNode && !EdgesAdjacent(*nextNode)) - nextNode = nextNode->next; + nextNode = nextNode->Next; if (!nextNode) return false; SwapIntersectNodes(*inode, *nextNode); } - SwapPositionsInSEL(inode->edge1, inode->edge2); - inode = inode->next; + SwapPositionsInSEL(inode->Edge1, inode->Edge2); + inode = inode->Next; } return true; } @@ -2768,140 +3440,357 @@ bool Clipper::FixupIntersectionOrder() inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2) { - if (e2.xcurr == e1.xcurr) + if (e2.Curr.X == e1.Curr.X) { - if (e2.ytop > e1.ytop) - return e2.xtop < TopX(e1, e2.ytop); - else return e1.xtop > TopX(e2, e1.ytop); + if (e2.Top.Y > e1.Top.Y) + return e2.Top.X < TopX(e1, e2.Top.Y); + else return e1.Top.X > TopX(e2, e1.Top.Y); } - else return e2.xcurr < e1.xcurr; + else return e2.Curr.X < e1.Curr.X; } //------------------------------------------------------------------------------ -void Clipper::InsertEdgeIntoAEL(TEdge *edge) +bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2, + cInt& Left, cInt& Right) { - edge->prevInAEL = 0; - edge->nextInAEL = 0; - if( !m_ActiveEdges ) + if (a1 < a2) { - m_ActiveEdges = edge; - } - else if( E2InsertsBeforeE1(*m_ActiveEdges, *edge) ) - { - edge->nextInAEL = m_ActiveEdges; - m_ActiveEdges->prevInAEL = edge; - m_ActiveEdges = edge; - } else + if (b1 < b2) {Left = std::max(a1,b1); Right = std::min(a2,b2);} + else {Left = std::max(a1,b2); Right = std::min(a2,b1);} + } + else { - TEdge* e = m_ActiveEdges; - while( e->nextInAEL && !E2InsertsBeforeE1(*e->nextInAEL , *edge) ) - e = e->nextInAEL; - edge->nextInAEL = e->nextInAEL; - if( e->nextInAEL ) e->nextInAEL->prevInAEL = edge; - edge->prevInAEL = e; - e->nextInAEL = edge; + if (b1 < b2) {Left = std::max(a2,b1); Right = std::min(a1,b2);} + else {Left = std::max(a2,b2); Right = std::min(a1,b1);} } + return Left < Right; } -//---------------------------------------------------------------------- +//------------------------------------------------------------------------------ -bool Clipper::JoinPoints(const JoinRec *j, OutPt *&p1, OutPt *&p2) -{ - OutRec *outRec1 = m_PolyOuts[j->poly1Idx]; - OutRec *outRec2 = m_PolyOuts[j->poly2Idx]; - if (!outRec1 || !outRec2) return false; - OutPt *pp1a = outRec1->pts; - OutPt *pp2a = outRec2->pts; - IntPoint pt1 = j->pt2a, pt2 = j->pt2b; - IntPoint pt3 = j->pt1a, pt4 = j->pt1b; - if (!FindSegment(pp1a, m_UseFullRange, pt1, pt2)) return false; - if (outRec1 == outRec2) - { - //we're searching the same polygon for overlapping segments so - //segment 2 mustn't be the same as segment 1 ... - pp2a = pp1a->next; - if (!FindSegment(pp2a, m_UseFullRange, pt3, pt4) || (pp2a == pp1a)) - return false; - } - else if (!FindSegment(pp2a, m_UseFullRange, pt3, pt4)) return false; - - if (!GetOverlapSegment(pt1, pt2, pt3, pt4, pt1, pt2)) return false; - - OutPt *p3, *p4, *prev = pp1a->prev; - //get p1 & p2 polypts - the overlap start & endpoints on poly1 - if (PointsEqual(pp1a->pt, pt1)) p1 = pp1a; - else if (PointsEqual(prev->pt, pt1)) p1 = prev; - else p1 = InsertPolyPtBetween(pp1a, prev, pt1); - - if (PointsEqual(pp1a->pt, pt2)) p2 = pp1a; - else if (PointsEqual(prev->pt, pt2)) p2 = prev; - else if ((p1 == pp1a) || (p1 == prev)) - p2 = InsertPolyPtBetween(pp1a, prev, pt2); - else if (Pt3IsBetweenPt1AndPt2(pp1a->pt, p1->pt, pt2)) - p2 = InsertPolyPtBetween(pp1a, p1, pt2); else - p2 = InsertPolyPtBetween(p1, prev, pt2); - - //get p3 & p4 polypts - the overlap start & endpoints on poly2 - prev = pp2a->prev; - if (PointsEqual(pp2a->pt, pt1)) p3 = pp2a; - else if (PointsEqual(prev->pt, pt1)) p3 = prev; - else p3 = InsertPolyPtBetween(pp2a, prev, pt1); - - if (PointsEqual(pp2a->pt, pt2)) p4 = pp2a; - else if (PointsEqual(prev->pt, pt2)) p4 = prev; - else if ((p3 == pp2a) || (p3 == prev)) - p4 = InsertPolyPtBetween(pp2a, prev, pt2); - else if (Pt3IsBetweenPt1AndPt2(pp2a->pt, p3->pt, pt2)) - p4 = InsertPolyPtBetween(pp2a, p3, pt2); else - p4 = InsertPolyPtBetween(p3, prev, pt2); - - //p1.pt == p3.pt and p2.pt == p4.pt so join p1 to p3 and p2 to p4 ... - if (p1->next == p2 && p3->prev == p4) - { - p1->next = p3; - p3->prev = p1; - p2->prev = p4; - p4->next = p2; - return true; - } - else if (p1->prev == p2 && p3->next == p4) +inline void UpdateOutPtIdxs(OutRec& outrec) +{ + OutPt* op = outrec.Pts; + do { - p1->prev = p3; - p3->next = p1; - p2->next = p4; - p4->prev = p2; - return true; + op->Idx = outrec.Idx; + op = op->Prev; } - else - return false; //an orientation is probably wrong + while(op != outrec.Pts); } -//---------------------------------------------------------------------- +//------------------------------------------------------------------------------ -void Clipper::FixupJoinRecs(JoinRec *j, OutPt *pt, unsigned startIdx) +void Clipper::InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge) { - for (JoinList::size_type k = startIdx; k < m_Joins.size(); k++) - { - JoinRec* j2 = m_Joins[k]; - if (j2->poly1Idx == j->poly1Idx && PointIsVertex(j2->pt1a, pt)) - j2->poly1Idx = j->poly2Idx; - if (j2->poly2Idx == j->poly1Idx && PointIsVertex(j2->pt2a, pt)) - j2->poly2Idx = j->poly2Idx; - } + if(!m_ActiveEdges) + { + edge->PrevInAEL = 0; + edge->NextInAEL = 0; + m_ActiveEdges = edge; + } + else if(!startEdge && E2InsertsBeforeE1(*m_ActiveEdges, *edge)) + { + edge->PrevInAEL = 0; + edge->NextInAEL = m_ActiveEdges; + m_ActiveEdges->PrevInAEL = edge; + m_ActiveEdges = edge; + } + else + { + if(!startEdge) startEdge = m_ActiveEdges; + while(startEdge->NextInAEL && + !E2InsertsBeforeE1(*startEdge->NextInAEL , *edge)) + startEdge = startEdge->NextInAEL; + edge->NextInAEL = startEdge->NextInAEL; + if(startEdge->NextInAEL) startEdge->NextInAEL->PrevInAEL = edge; + edge->PrevInAEL = startEdge; + startEdge->NextInAEL = edge; + } } //---------------------------------------------------------------------- -bool Poly2ContainsPoly1(OutPt* outPt1, OutPt* outPt2, bool UseFullInt64Range) +OutPt* DupOutPt(OutPt* outPt, bool InsertAfter) { - OutPt* pt = outPt1; - //Because the polygons may be touching, we need to find a vertex that - //isn't touching the other polygon ... - if (PointOnPolygon(pt->pt, outPt2, UseFullInt64Range)) + OutPt* result = new OutPt; + result->Pt = outPt->Pt; + result->Idx = outPt->Idx; + if (InsertAfter) + { + result->Next = outPt->Next; + result->Prev = outPt; + outPt->Next->Prev = result; + outPt->Next = result; + } + else + { + result->Prev = outPt->Prev; + result->Next = outPt; + outPt->Prev->Next = result; + outPt->Prev = result; + } + return result; +} +//------------------------------------------------------------------------------ + +bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b, + const IntPoint Pt, bool DiscardLeft) +{ + Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight); + Direction Dir2 = (op2->Pt.X > op2b->Pt.X ? dRightToLeft : dLeftToRight); + if (Dir1 == Dir2) return false; + + //When DiscardLeft, we want Op1b to be on the Left of Op1, otherwise we + //want Op1b to be on the Right. (And likewise with Op2 and Op2b.) + //So, to facilitate this while inserting Op1b and Op2b ... + //when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b, + //otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.) + if (Dir1 == dLeftToRight) + { + while (op1->Next->Pt.X <= Pt.X && + op1->Next->Pt.X >= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) + op1 = op1->Next; + if (DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next; + op1b = DupOutPt(op1, !DiscardLeft); + if (op1b->Pt != Pt) + { + op1 = op1b; + op1->Pt = Pt; + op1b = DupOutPt(op1, !DiscardLeft); + } + } + else + { + while (op1->Next->Pt.X >= Pt.X && + op1->Next->Pt.X <= op1->Pt.X && op1->Next->Pt.Y == Pt.Y) + op1 = op1->Next; + if (!DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next; + op1b = DupOutPt(op1, DiscardLeft); + if (op1b->Pt != Pt) + { + op1 = op1b; + op1->Pt = Pt; + op1b = DupOutPt(op1, DiscardLeft); + } + } + + if (Dir2 == dLeftToRight) + { + while (op2->Next->Pt.X <= Pt.X && + op2->Next->Pt.X >= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) + op2 = op2->Next; + if (DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next; + op2b = DupOutPt(op2, !DiscardLeft); + if (op2b->Pt != Pt) + { + op2 = op2b; + op2->Pt = Pt; + op2b = DupOutPt(op2, !DiscardLeft); + }; + } else + { + while (op2->Next->Pt.X >= Pt.X && + op2->Next->Pt.X <= op2->Pt.X && op2->Next->Pt.Y == Pt.Y) + op2 = op2->Next; + if (!DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next; + op2b = DupOutPt(op2, DiscardLeft); + if (op2b->Pt != Pt) + { + op2 = op2b; + op2->Pt = Pt; + op2b = DupOutPt(op2, DiscardLeft); + }; + }; + + if ((Dir1 == dLeftToRight) == DiscardLeft) + { + op1->Prev = op2; + op2->Next = op1; + op1b->Next = op2b; + op2b->Prev = op1b; + } + else + { + op1->Next = op2; + op2->Prev = op1; + op1b->Prev = op2b; + op2b->Next = op1b; + } + return true; +} +//------------------------------------------------------------------------------ + +bool Clipper::JoinPoints(const Join *j, OutPt *&p1, OutPt *&p2) +{ + OutRec* outRec1 = GetOutRec(j->OutPt1->Idx); + OutRec* outRec2 = GetOutRec(j->OutPt2->Idx); + OutPt *op1 = j->OutPt1, *op1b; + OutPt *op2 = j->OutPt2, *op2b; + + //There are 3 kinds of joins for output polygons ... + //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are a vertices anywhere + //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal). + //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same + //location at the Bottom of the overlapping segment (& Join.OffPt is above). + //3. StrictSimple joins where edges touch but are not collinear and where + //Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point. + bool isHorizontal = (j->OutPt1->Pt.Y == j->OffPt.Y); + + if (isHorizontal && (j->OffPt == j->OutPt1->Pt) && + (j->OffPt == j->OutPt2->Pt)) { - pt = pt->next; - while (pt != outPt1 && PointOnPolygon(pt->pt, outPt2, UseFullInt64Range)) - pt = pt->next; - if (pt == outPt1) return true; + //Strictly Simple join ... + op1b = j->OutPt1->Next; + while (op1b != op1 && (op1b->Pt == j->OffPt)) + op1b = op1b->Next; + bool reverse1 = (op1b->Pt.Y > j->OffPt.Y); + op2b = j->OutPt2->Next; + while (op2b != op2 && (op2b->Pt == j->OffPt)) + op2b = op2b->Next; + bool reverse2 = (op2b->Pt.Y > j->OffPt.Y); + if (reverse1 == reverse2) return false; + if (reverse1) + { + op1b = DupOutPt(op1, false); + op2b = DupOutPt(op2, true); + op1->Prev = op2; + op2->Next = op1; + op1b->Next = op2b; + op2b->Prev = op1b; + p1 = op1; + p2 = op1b; + return true; + } else + { + op1b = DupOutPt(op1, true); + op2b = DupOutPt(op2, false); + op1->Next = op2; + op2->Prev = op1; + op1b->Prev = op2b; + op2b->Next = op1b; + p1 = op1; + p2 = op1b; + return true; + } + } + else if (isHorizontal) + { + //treat horizontal joins differently to non-horizontal joins since with + //them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt + //may be anywhere along the horizontal edge. + op1b = op1; + while (op1->Prev->Pt.Y == op1->Pt.Y && op1->Prev != op1b && op1->Prev != op2) + op1 = op1->Prev; + while (op1b->Next->Pt.Y == op1b->Pt.Y && op1b->Next != op1 && op1b->Next != op2) + op1b = op1b->Next; + if (op1b->Next == op1 || op1b->Next == op2) return false; //a flat 'polygon' + + op2b = op2; + while (op2->Prev->Pt.Y == op2->Pt.Y && op2->Prev != op2b && op2->Prev != op1b) + op2 = op2->Prev; + while (op2b->Next->Pt.Y == op2b->Pt.Y && op2b->Next != op2 && op2b->Next != op1) + op2b = op2b->Next; + if (op2b->Next == op2 || op2b->Next == op1) return false; //a flat 'polygon' + + cInt Left, Right; + //Op1 --> Op1b & Op2 --> Op2b are the extremites of the horizontal edges + if (!GetOverlap(op1->Pt.X, op1b->Pt.X, op2->Pt.X, op2b->Pt.X, Left, Right)) + return false; + + //DiscardLeftSide: when overlapping edges are joined, a spike will created + //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up + //on the discard Side as either may still be needed for other joins ... + IntPoint Pt; + bool DiscardLeftSide; + if (op1->Pt.X >= Left && op1->Pt.X <= Right) + { + Pt = op1->Pt; DiscardLeftSide = (op1->Pt.X > op1b->Pt.X); + } + else if (op2->Pt.X >= Left&& op2->Pt.X <= Right) + { + Pt = op2->Pt; DiscardLeftSide = (op2->Pt.X > op2b->Pt.X); + } + else if (op1b->Pt.X >= Left && op1b->Pt.X <= Right) + { + Pt = op1b->Pt; DiscardLeftSide = op1b->Pt.X > op1->Pt.X; + } + else + { + Pt = op2b->Pt; DiscardLeftSide = (op2b->Pt.X > op2->Pt.X); + } + p1 = op1; p2 = op2; + return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide); + } else + { + //nb: For non-horizontal joins ... + // 1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y + // 2. Jr.OutPt1.Pt > Jr.OffPt.Y + + //make sure the polygons are correctly oriented ... + op1b = op1->Next; + while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Next; + bool Reverse1 = ((op1b->Pt.Y > op1->Pt.Y) || + !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)); + if (Reverse1) + { + op1b = op1->Prev; + while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Prev; + if ((op1b->Pt.Y > op1->Pt.Y) || + !SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)) return false; + }; + op2b = op2->Next; + while ((op2b->Pt == op2->Pt) && (op2b != op2))op2b = op2b->Next; + bool Reverse2 = ((op2b->Pt.Y > op2->Pt.Y) || + !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)); + if (Reverse2) + { + op2b = op2->Prev; + while ((op2b->Pt == op2->Pt) && (op2b != op2)) op2b = op2b->Prev; + if ((op2b->Pt.Y > op2->Pt.Y) || + !SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)) return false; + } + + if ((op1b == op1) || (op2b == op2) || (op1b == op2b) || + ((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false; + + if (Reverse1) + { + op1b = DupOutPt(op1, false); + op2b = DupOutPt(op2, true); + op1->Prev = op2; + op2->Next = op1; + op1b->Next = op2b; + op2b->Prev = op1b; + p1 = op1; + p2 = op1b; + return true; + } else + { + op1b = DupOutPt(op1, true); + op2b = DupOutPt(op2, false); + op1->Next = op2; + op2->Prev = op1; + op1b->Prev = op2b; + op2b->Next = op1b; + p1 = op1; + p2 = op1b; + return true; + } } - return PointInPolygon(pt->pt, outPt2, UseFullInt64Range); +} +//---------------------------------------------------------------------- + +bool Poly2ContainsPoly1(OutPt* OutPt1, OutPt* OutPt2, bool UseFullInt64Range) +{ + OutPt* Pt = OutPt1; + //Because the polygons may be touching, we need to find a vertex that + //isn't touching the other polygon ... + if (PointOnPolygon(Pt->Pt, OutPt2, UseFullInt64Range)) + { + Pt = Pt->Next; + while (Pt != OutPt1 && PointOnPolygon(Pt->Pt, OutPt2, UseFullInt64Range)) + Pt = Pt->Next; + if (Pt == OutPt1) return true; + } + return PointInPolygon(Pt->Pt, OutPt2, UseFullInt64Range); } //---------------------------------------------------------------------- @@ -2911,9 +3800,9 @@ void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) { OutRec* outRec = m_PolyOuts[i]; - if (outRec->pts && outRec->FirstLeft == OldOutRec) + if (outRec->Pts && outRec->FirstLeft == OldOutRec) { - if (Poly2ContainsPoly1(outRec->pts, NewOutRec->pts, m_UseFullRange)) + if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts, m_UseFullRange)) outRec->FirstLeft = NewOutRec; } } @@ -2934,12 +3823,12 @@ void Clipper::JoinCommonEdges() { for (JoinList::size_type i = 0; i < m_Joins.size(); i++) { - JoinRec* j = m_Joins[i]; + Join* j = m_Joins[i]; - OutRec *outRec1 = GetOutRec(j->poly1Idx); - OutRec *outRec2 = GetOutRec(j->poly2Idx); + OutRec *outRec1 = GetOutRec(j->OutPt1->Idx); + OutRec *outRec2 = GetOutRec(j->OutPt2->Idx); - if (!outRec1->pts || !outRec2->pts) continue; + if (!outRec1->Pts || !outRec2->Pts) continue; //get the polygon fragment with the correct hole state (FirstLeft) //before calling JoinPoints() ... @@ -2956,75 +3845,59 @@ void Clipper::JoinCommonEdges() { //instead of joining two polygons, we've just created a new one by //splitting one polygon into two. - outRec1->pts = p1; - outRec1->bottomPt = 0; + outRec1->Pts = p1; + outRec1->BottomPt = 0; outRec2 = CreateOutRec(); - outRec2->pts = p2; + outRec2->Pts = p2; + + //update all OutRec2.Pts Idx's ... + UpdateOutPtIdxs(*outRec2); - if (Poly2ContainsPoly1(outRec2->pts, outRec1->pts, m_UseFullRange)) + if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts, m_UseFullRange)) { //outRec2 is contained by outRec1 ... - outRec2->isHole = !outRec1->isHole; + outRec2->IsHole = !outRec1->IsHole; outRec2->FirstLeft = outRec1; - FixupJoinRecs(j, p2, i+1); - //fixup FirstLeft pointers that may need reassigning to OutRec1 if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1); - FixupOutPolygon(*outRec1); //nb: do this BEFORE testing orientation - FixupOutPolygon(*outRec2); // but AFTER calling FixupJoinRecs() - - - if ((outRec2->isHole ^ m_ReverseOutput) == (Area(*outRec2, m_UseFullRange) > 0)) - ReversePolyPtLinks(outRec2->pts); + if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0)) + ReversePolyPtLinks(outRec2->Pts); - } else if (Poly2ContainsPoly1(outRec1->pts, outRec2->pts, m_UseFullRange)) + } else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts, m_UseFullRange)) { //outRec1 is contained by outRec2 ... - outRec2->isHole = outRec1->isHole; - outRec1->isHole = !outRec2->isHole; + outRec2->IsHole = outRec1->IsHole; + outRec1->IsHole = !outRec2->IsHole; outRec2->FirstLeft = outRec1->FirstLeft; outRec1->FirstLeft = outRec2; - FixupJoinRecs(j, p2, i+1); - //fixup FirstLeft pointers that may need reassigning to OutRec1 if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2); - FixupOutPolygon(*outRec1); //nb: do this BEFORE testing orientation - FixupOutPolygon(*outRec2); // but AFTER calling FixupJoinRecs() - - if ((outRec1->isHole ^ m_ReverseOutput) == (Area(*outRec1, m_UseFullRange) > 0)) - ReversePolyPtLinks(outRec1->pts); + if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0)) + ReversePolyPtLinks(outRec1->Pts); } else { //the 2 polygons are completely separate ... - outRec2->isHole = outRec1->isHole; + outRec2->IsHole = outRec1->IsHole; outRec2->FirstLeft = outRec1->FirstLeft; - FixupJoinRecs(j, p2, i+1); - //fixup FirstLeft pointers that may need reassigning to OutRec2 if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2); - - FixupOutPolygon(*outRec1); //nb: do this BEFORE testing orientation - FixupOutPolygon(*outRec2); // but AFTER calling FixupJoinRecs() } } else { //joined 2 polygons together ... - //cleanup redundant edges ... - FixupOutPolygon(*outRec1); - - outRec2->pts = 0; - outRec2->bottomPt = 0; - outRec2->idx = outRec1->idx; + outRec2->Pts = 0; + outRec2->BottomPt = 0; + outRec2->Idx = outRec1->Idx; - outRec1->isHole = holeStateRec->isHole; + outRec1->IsHole = holeStateRec->IsHole; if (holeStateRec == outRec2) outRec1->FirstLeft = outRec2->FirstLeft; outRec2->FirstLeft = outRec1; @@ -3036,137 +3909,91 @@ void Clipper::JoinCommonEdges() } //------------------------------------------------------------------------------ -inline void UpdateOutPtIdxs(OutRec& outrec) -{ - OutPt* op = outrec.pts; - do - { - op->idx = outrec.idx; - op = op->prev; - } - while(op != outrec.pts); -} -//------------------------------------------------------------------------------ - void Clipper::DoSimplePolygons() { PolyOutList::size_type i = 0; while (i < m_PolyOuts.size()) { OutRec* outrec = m_PolyOuts[i++]; - OutPt* op = outrec->pts; + OutPt* op = outrec->Pts; if (!op) continue; do //for each Pt in Polygon until duplicate found do ... { - OutPt* op2 = op->next; - while (op2 != outrec->pts) + OutPt* op2 = op->Next; + while (op2 != outrec->Pts) { - if (PointsEqual(op->pt, op2->pt) && op2->next != op && op2->prev != op) + if ((op->Pt == op2->Pt) && op2->Next != op && op2->Prev != op) { //split the polygon into two ... - OutPt* op3 = op->prev; - OutPt* op4 = op2->prev; - op->prev = op4; - op4->next = op; - op2->prev = op3; - op3->next = op2; - - outrec->pts = op; + OutPt* op3 = op->Prev; + OutPt* op4 = op2->Prev; + op->Prev = op4; + op4->Next = op; + op2->Prev = op3; + op3->Next = op2; + + outrec->Pts = op; OutRec* outrec2 = CreateOutRec(); - outrec2->pts = op2; + outrec2->Pts = op2; UpdateOutPtIdxs(*outrec2); - if (Poly2ContainsPoly1(outrec2->pts, outrec->pts, m_UseFullRange)) + if (Poly2ContainsPoly1(outrec2->Pts, outrec->Pts, m_UseFullRange)) { //OutRec2 is contained by OutRec1 ... - outrec2->isHole = !outrec->isHole; + outrec2->IsHole = !outrec->IsHole; outrec2->FirstLeft = outrec; } else - if (Poly2ContainsPoly1(outrec->pts, outrec2->pts, m_UseFullRange)) + if (Poly2ContainsPoly1(outrec->Pts, outrec2->Pts, m_UseFullRange)) { //OutRec1 is contained by OutRec2 ... - outrec2->isHole = outrec->isHole; - outrec->isHole = !outrec2->isHole; + outrec2->IsHole = outrec->IsHole; + outrec->IsHole = !outrec2->IsHole; outrec2->FirstLeft = outrec->FirstLeft; outrec->FirstLeft = outrec2; } else { //the 2 polygons are separate ... - outrec2->isHole = outrec->isHole; + outrec2->IsHole = outrec->IsHole; outrec2->FirstLeft = outrec->FirstLeft; } - op2 = op; //ie get ready for the next iteration + op2 = op; //ie get ready for the Next iteration } - op2 = op2->next; + op2 = op2->Next; } - op = op->next; + op = op->Next; } - while (op != outrec->pts); + while (op != outrec->Pts); } } //------------------------------------------------------------------------------ -void ReversePolygon(Polygon& p) +void ReversePath(Path& p) { std::reverse(p.begin(), p.end()); } //------------------------------------------------------------------------------ -void ReversePolygons(Polygons& p) +void ReversePaths(Paths& p) { - for (Polygons::size_type i = 0; i < p.size(); ++i) - ReversePolygon(p[i]); + for (Paths::size_type i = 0; i < p.size(); ++i) + ReversePath(p[i]); } //------------------------------------------------------------------------------ // OffsetPolygon functions ... //------------------------------------------------------------------------------ -struct DoublePoint -{ - double X; - double Y; - DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {} -}; -//------------------------------------------------------------------------------ - -Polygon BuildArc(const IntPoint &pt, - const double a1, const double a2, const double r, double limit) -{ - //see notes in clipper.pas regarding steps - double arcFrac = std::fabs(a2 - a1) / (2 * pi); - int steps = (int)(arcFrac * pi / std::acos(1 - limit / std::fabs(r))); - if (steps < 2) steps = 2; - else if (steps > (int)(222.0 * arcFrac)) steps = (int)(222.0 * arcFrac); - - double x = std::cos(a1); - double y = std::sin(a1); - double c = std::cos((a2 - a1) / steps); - double s = std::sin((a2 - a1) / steps); - Polygon result(steps +1); - for (int i = 0; i <= steps; ++i) - { - result[i].X = pt.X + Round(x * r); - result[i].Y = pt.Y + Round(y * r); - double x2 = x; - x = x * c - s * y; //cross product - y = x2 * s + y * c; //dot product - } - return result; -} -//------------------------------------------------------------------------------ - DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2) { if(pt2.X == pt1.X && pt2.Y == pt1.Y) return DoublePoint(0, 0); - double dx = (double)(pt2.X - pt1.X); + double Dx = (double)(pt2.X - pt1.X); double dy = (double)(pt2.Y - pt1.Y); - double f = 1 *1.0/ std::sqrt( dx*dx + dy*dy ); - dx *= f; + double f = 1 *1.0/ std::sqrt( Dx*Dx + dy*dy ); + Dx *= f; dy *= f; - return DoublePoint(dy, -dx); + return DoublePoint(dy, -Dx); } //------------------------------------------------------------------------------ @@ -3175,151 +4002,173 @@ DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2) class OffsetBuilder { private: - const Polygons& m_p; - Polygon* m_curr_poly; + const Paths& m_p; + Path* m_curr_poly; std::vector normals; - double m_delta, m_rmin, m_r; + double m_delta, m_sinA, m_sin, m_cos; + double m_miterLim, m_Steps360; size_t m_i, m_j, m_k; static const int buffLength = 128; public: -OffsetBuilder(const Polygons& in_polys, Polygons& out_polys, - bool isPolygon, double delta, JoinType jointype, EndType endtype, double limit): m_p(in_polys) +OffsetBuilder(const Paths& in_polys, Paths& out_polys, + double Delta, JoinType jointype, EndType endtype, double limit): m_p(in_polys) { //precondition: &out_polys != &in_polys - if (NEAR_ZERO(delta)) {out_polys = in_polys; return;} - m_rmin = 0.5; - m_delta = delta; - if (jointype == jtMiter) - { - if (limit > 2) m_rmin = 2.0 / (limit * limit); - limit = 0.25; //just in case endtype == etRound - } - else - { - if (limit <= 0) limit = 0.25; - else if (limit > std::fabs(delta)) limit = std::fabs(delta); - } - - double deltaSq = delta*delta; - out_polys.clear(); - out_polys.resize(m_p.size()); - for (m_i = 0; m_i < m_p.size(); m_i++) - { - size_t len = m_p[m_i].size(); + if (NEAR_ZERO(Delta)) {out_polys = in_polys; return;} + //we can't shrink a polyline so ... + if (endtype != etClosed && Delta < 0) Delta = -Delta; + m_delta = Delta; - if (len == 0 || (len < 3 && delta <= 0)) - continue; - else if (len == 1) - { - out_polys[m_i] = BuildArc(m_p[m_i][0], 0, 2*pi, delta, limit); - continue; - } + if (jointype == jtMiter) + { + //m_miterLim: see offset_triginometry.svg in the documentation folder ... + if (limit > 2) m_miterLim = 2/(limit*limit); + else m_miterLim = 0.5; + if (endtype == etRound) limit = 0.25; + } - bool forceClose = PointsEqual(m_p[m_i][0], m_p[m_i][len -1]); - if (forceClose) len--; - - //build normals ... - normals.clear(); - normals.resize(len); - for (m_j = 0; m_j < len -1; ++m_j) - normals[m_j] = GetUnitNormal(m_p[m_i][m_j], m_p[m_i][m_j +1]); - if (isPolygon || forceClose) - normals[len-1] = GetUnitNormal(m_p[m_i][len-1], m_p[m_i][0]); - else //is open polyline - normals[len-1] = normals[len-2]; - - m_curr_poly = &out_polys[m_i]; - m_curr_poly->reserve(len); + if (jointype == jtRound || endtype == etRound) + { + if (limit <= 0) limit = 0.25; + else if (limit > std::fabs(Delta)*0.25) limit = std::fabs(Delta)*0.25; + //m_Steps360: see offset_triginometry2.svg in the documentation folder ... + m_Steps360 = pi / acos(1 - limit / std::fabs(Delta)); + m_sin = std::sin(2 * pi / m_Steps360); + m_cos = std::cos(2 * pi / m_Steps360); + m_Steps360 /= pi * 2; + if (Delta < 0) m_sin = -m_sin; + } - if (isPolygon || forceClose) - { - m_k = len -1; - for (m_j = 0; m_j < len; ++m_j) - OffsetPoint(jointype, limit); + out_polys.clear(); + out_polys.resize(m_p.size()); + for (m_i = 0; m_i < m_p.size(); m_i++) + { + size_t len = m_p[m_i].size(); - if (!isPolygon) + if (len == 0 || (len < 3 && Delta <= 0)) continue; + + if (len == 1) + { + if (jointype == jtRound) + { + double X = 1.0, Y = 0.0; + for (cInt j = 1; j <= Round(m_Steps360 * 2 * pi); j++) { - size_t j = out_polys.size(); - out_polys.resize(j+1); - m_curr_poly = &out_polys[j]; - m_curr_poly->reserve(len); - m_delta = -m_delta; - - m_k = len -1; - for (m_j = 0; m_j < len; ++m_j) - OffsetPoint(jointype, limit); - m_delta = -m_delta; - ReversePolygon(*m_curr_poly); + AddPoint(IntPoint( + Round(m_p[m_i][0].X + X * Delta), + Round(m_p[m_i][0].Y + Y * Delta))); + double X2 = X; + X = X * m_cos - m_sin * Y; + Y = X2 * m_sin + Y * m_cos; } - } - else //is open polyline + } else { - //offset the polyline going forward ... - m_k = 0; - for (m_j = 1; m_j < len -1; ++m_j) - OffsetPoint(jointype, limit); - - //handle the end (butt, round or square) ... - IntPoint pt1; - if (endtype == etButt) + double X = -1.0, Y = -1.0; + for (int j = 0; j < 4; ++j) { - m_j = len - 1; - pt1 = IntPoint(Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), - Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); - AddPoint(pt1); - pt1 = IntPoint(Round(m_p[m_i][m_j].X - normals[m_j].X * m_delta), - Round(m_p[m_i][m_j].Y - normals[m_j].Y * m_delta)); - AddPoint(pt1); - } - else - { - m_j = len - 1; - m_k = len - 2; - normals[m_j].X = -normals[m_j].X; - normals[m_j].Y = -normals[m_j].Y; - if (endtype == etSquare) DoSquare(); - else DoRound(limit); + AddPoint(IntPoint( Round(m_p[m_i][0].X + X * Delta), + Round(m_p[m_i][0].Y + Y * Delta))); + if (X < 0) X = 1; + else if (Y < 0) Y = 1; + else X = -1; } + } + continue; + } - //re-build Normals ... - for (int j = len - 1; j > 0; --j) - { - normals[j].X = -normals[j - 1].X; - normals[j].Y = -normals[j - 1].Y; - } - normals[0].X = -normals[1].X; - normals[0].Y = -normals[1].Y; + //build normals ... + normals.clear(); + normals.resize(len); + for (m_j = 0; m_j < len -1; ++m_j) + normals[m_j] = GetUnitNormal(m_p[m_i][m_j], m_p[m_i][m_j +1]); + if (endtype == etClosed) + normals[len-1] = GetUnitNormal(m_p[m_i][len-1], m_p[m_i][0]); + else //is open polyline + normals[len-1] = normals[len-2]; + + m_curr_poly = &out_polys[m_i]; + m_curr_poly->reserve(len); - //offset the polyline going backward ... - m_k = len -1; - for (m_j = m_k - 1; m_j > 0; --m_j) - OffsetPoint(jointype, limit); + if (endtype == etClosed) + { + m_k = len -1; + for (m_j = 0; m_j < len; ++m_j) + OffsetPoint(jointype); + } + else //is open polyline + { + //offset the polyline going forward ... + m_k = 0; + for (m_j = 1; m_j < len -1; ++m_j) + OffsetPoint(jointype); + + //handle the end (butt, round or square) ... + IntPoint pt1; + if (endtype == etButt) + { + m_j = len - 1; + pt1 = IntPoint(Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), + Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); + AddPoint(pt1); + pt1 = IntPoint(Round(m_p[m_i][m_j].X - normals[m_j].X * m_delta), + Round(m_p[m_i][m_j].Y - normals[m_j].Y * m_delta)); + AddPoint(pt1); + } + else + { + m_j = len - 1; + m_k = len - 2; + m_sinA = 0; + normals[m_j].X = -normals[m_j].X; + normals[m_j].Y = -normals[m_j].Y; + if (endtype == etSquare) + DoSquare(); + else + DoRound(); + } - //finally handle the start (butt, round or square) ... - if (endtype == etButt) - { - pt1 = IntPoint(Round(m_p[m_i][0].X - normals[0].X * m_delta), - Round(m_p[m_i][0].Y - normals[0].Y * m_delta)); - AddPoint(pt1); - pt1 = IntPoint(Round(m_p[m_i][0].X + normals[0].X * m_delta), - Round(m_p[m_i][0].Y + normals[0].Y * m_delta)); - AddPoint(pt1); - } else - { - m_k = 1; - if (endtype == etSquare) DoSquare(); - else DoRound(limit); - } + //re-build Normals ... + for (int j = len - 1; j > 0; --j) + { + normals[j].X = -normals[j - 1].X; + normals[j].Y = -normals[j - 1].Y; + } + normals[0].X = -normals[1].X; + normals[0].Y = -normals[1].Y; + + //offset the polyline going backward ... + m_k = len -1; + for (m_j = m_k - 1; m_j > 0; --m_j) + OffsetPoint(jointype); + + //finally handle the start (butt, round or square) ... + if (endtype == etButt) + { + pt1 = IntPoint(Round(m_p[m_i][0].X - normals[0].X * m_delta), + Round(m_p[m_i][0].Y - normals[0].Y * m_delta)); + AddPoint(pt1); + pt1 = IntPoint(Round(m_p[m_i][0].X + normals[0].X * m_delta), + Round(m_p[m_i][0].Y + normals[0].Y * m_delta)); + AddPoint(pt1); + } else + { + m_sinA = 0; + m_k = 1; + if (endtype == etSquare) + DoSquare(); + else + DoRound(); } + } } //and clean up untidy corners using Clipper ... Clipper clpr; - clpr.AddPolygons(out_polys, ptSubject); - if (delta > 0) + clpr.AddPaths(out_polys, ptSubject, true); + if (Delta > 0) { if (!clpr.Execute(ctUnion, out_polys, pftPositive, pftPositive)) out_polys.clear(); @@ -3327,13 +4176,13 @@ OffsetBuilder(const Polygons& in_polys, Polygons& out_polys, else { IntRect r = clpr.GetBounds(); - Polygon outer(4); + Path outer(4); outer[0] = IntPoint(r.left - 10, r.bottom + 10); outer[1] = IntPoint(r.right + 10, r.bottom + 10); outer[2] = IntPoint(r.right + 10, r.top - 10); outer[3] = IntPoint(r.left - 10, r.top - 10); - clpr.AddPolygon(outer, ptSubject); + clpr.AddPath(outer, ptSubject, true); clpr.ReverseSolution(true); if (clpr.Execute(ctUnion, out_polys, pftNegative, pftNegative)) out_polys.erase(out_polys.begin()); @@ -3345,104 +4194,86 @@ OffsetBuilder(const Polygons& in_polys, Polygons& out_polys, private: -void OffsetPoint(JoinType jointype, double limit) +void OffsetPoint(JoinType jointype) { + m_sinA = (normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y); + if (std::fabs(m_sinA) < 0.00005) return; //ie collinear + else if (m_sinA > 1.0) m_sinA = 1.0; + else if (m_sinA < -1.0) m_sinA = -1.0; + + if (m_sinA * m_delta < 0) + { + AddPoint(IntPoint(Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), + Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta))); + AddPoint(m_p[m_i][m_j]); + AddPoint(IntPoint(Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), + Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta))); + } + else switch (jointype) - { - case jtMiter: { - m_r = 1 + (normals[m_j].X*normals[m_k].X + - normals[m_j].Y*normals[m_k].Y); - if (m_r >= m_rmin) DoMiter(); else DoSquare(); - break; + case jtMiter: + { + double r = 1 + (normals[m_j].X*normals[m_k].X + + normals[m_j].Y*normals[m_k].Y); + if (r >= m_miterLim) DoMiter(r); else DoSquare(); + break; + } + case jtSquare: DoSquare(); break; + case jtRound: DoRound(); break; } - case jtSquare: DoSquare(); break; - case jtRound: DoRound(limit); break; - } - m_k = m_j; + m_k = m_j; } //------------------------------------------------------------------------------ -void AddPoint(const IntPoint& pt) +void AddPoint(const IntPoint& Pt) { if (m_curr_poly->size() == m_curr_poly->capacity()) m_curr_poly->reserve(m_curr_poly->capacity() + buffLength); - m_curr_poly->push_back(pt); + m_curr_poly->push_back(Pt); } //------------------------------------------------------------------------------ void DoSquare() { - IntPoint pt1 = IntPoint(Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), - Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); - IntPoint pt2 = IntPoint(Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), - Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); - if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0) - { - double a1 = std::atan2(normals[m_k].Y, normals[m_k].X); - double a2 = std::atan2(-normals[m_j].Y, -normals[m_j].X); - a1 = std::fabs(a2 - a1); - if (a1 > pi) a1 = pi * 2 - a1; - double dx = std::tan((pi - a1) / 4) * std::fabs(m_delta); - pt1 = IntPoint((long64)(pt1.X -normals[m_k].Y * dx), (long64)(pt1.Y + normals[m_k].X * dx)); - AddPoint(pt1); - pt2 = IntPoint((long64)(pt2.X + normals[m_j].Y * dx), (long64)(pt2.Y -normals[m_j].X * dx)); - AddPoint(pt2); - } - else - { - AddPoint(pt1); - AddPoint(m_p[m_i][m_j]); - AddPoint(pt2); - } + double Dx = std::tan(std::atan2(m_sinA, + normals[m_k].X * normals[m_j].X + normals[m_k].Y * normals[m_j].Y)/4); + AddPoint(IntPoint( + Round(m_p[m_i][m_j].X + m_delta * (normals[m_k].X - normals[m_k].Y *Dx)), + Round(m_p[m_i][m_j].Y + m_delta * (normals[m_k].Y + normals[m_k].X *Dx)))); + AddPoint(IntPoint( + Round(m_p[m_i][m_j].X + m_delta * (normals[m_j].X + normals[m_j].Y *Dx)), + Round(m_p[m_i][m_j].Y + m_delta * (normals[m_j].Y - normals[m_j].X *Dx)))); } //------------------------------------------------------------------------------ -void DoMiter() +void DoMiter(double r) { - if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0) - { - double q = m_delta / m_r; - AddPoint(IntPoint(Round(m_p[m_i][m_j].X + (normals[m_k].X + normals[m_j].X) * q), - Round(m_p[m_i][m_j].Y + (normals[m_k].Y + normals[m_j].Y) * q))); - } - else - { - IntPoint pt1 = IntPoint(Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), - Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); - IntPoint pt2 = IntPoint(Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), - Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); - AddPoint(pt1); - AddPoint(m_p[m_i][m_j]); - AddPoint(pt2); - } + double q = m_delta / r; + AddPoint(IntPoint(Round(m_p[m_i][m_j].X + (normals[m_k].X + normals[m_j].X) * q), + Round(m_p[m_i][m_j].Y + (normals[m_k].Y + normals[m_j].Y) * q))); } //------------------------------------------------------------------------------ -void DoRound(double limit) +void DoRound() { - IntPoint pt1 = IntPoint(Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta), - Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta)); - IntPoint pt2 = IntPoint(Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), - Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); - AddPoint(pt1); - //round off reflex angles (ie > 180 deg) unless almost flat (ie < ~10deg). - if ((normals[m_k].X*normals[m_j].Y - normals[m_j].X*normals[m_k].Y) * m_delta >= 0) - { - if (normals[m_j].X * normals[m_k].X + normals[m_j].Y * normals[m_k].Y < 0.985) - { - double a1 = std::atan2(normals[m_k].Y, normals[m_k].X); - double a2 = std::atan2(normals[m_j].Y, normals[m_j].X); - if (m_delta > 0 && a2 < a1) a2 += pi *2; - else if (m_delta < 0 && a2 > a1) a2 -= pi *2; - Polygon arc = BuildArc(m_p[m_i][m_j], a1, a2, m_delta, limit); - for (Polygon::size_type m = 0; m < arc.size(); m++) - AddPoint(arc[m]); - } - } - else - AddPoint(m_p[m_i][m_j]); - AddPoint(pt2); + double a = std::atan2(m_sinA, + normals[m_k].X * normals[m_j].X + normals[m_k].Y * normals[m_j].Y); + int steps = (int)Round(m_Steps360 * std::fabs(a)); + + double X = normals[m_k].X, Y = normals[m_k].Y, X2; + for (int i = 0; i < steps; ++i) + { + AddPoint(IntPoint( + Round(m_p[m_i][m_j].X + X * m_delta), + Round(m_p[m_i][m_j].Y + Y * m_delta))); + X2 = X; + X = X * m_cos - m_sin * Y; + Y = X2 * m_sin + Y * m_cos; + } + AddPoint(IntPoint( + Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta), + Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta))); } //-------------------------------------------------------------------------- @@ -3451,126 +4282,71 @@ void DoRound(double limit) //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -bool UpdateBotPt(const IntPoint &pt, IntPoint &botPt) +void StripDupsAndGetBotPt(Path& in_path, Path& out_path, bool closed, IntPoint* botPt) { - if (pt.Y > botPt.Y || (pt.Y == botPt.Y && pt.X < botPt.X)) + botPt = 0; + size_t len = in_path.size(); + if (closed) + while (len > 0 && (in_path[0] == in_path[len -1])) len--; + if (len == 0) return; + out_path.resize(len); + int j = 0; + out_path[0] = in_path[0]; + botPt = &out_path[0]; + for (size_t i = 1; i < len; ++i) + if (in_path[i] != out_path[j]) { - botPt = pt; - return true; + j++; + out_path[j] = in_path[i]; + if (out_path[j].Y > botPt->Y) + botPt = &out_path[j]; + else if ((out_path[j].Y == botPt->Y) && out_path[j].X < botPt->X) + botPt = &out_path[j]; } - else return false; + j++; + if (j < 2 || (closed && (j == 2))) j = 0; + out_path.resize(j); } -//-------------------------------------------------------------------------- +//------------------------------------------------------------------------------ -void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, - double delta, JoinType jointype, double limit, bool autoFix) +void OffsetPaths(const Paths &in_polys, Paths &out_polys, + double delta, JoinType jointype, EndType endtype, double limit) { - if (!autoFix && &in_polys != &out_polys) - { - OffsetBuilder(in_polys, out_polys, true, delta, jointype, etClosed, limit); - return; - } - - Polygons inPolys = Polygons(in_polys); + //just in case in_polys == &out_polys ... + Paths inPolys = Paths(in_polys); out_polys.clear(); + out_polys.resize(inPolys.size()); - //ChecksInput - fixes polygon orientation if necessary and removes - //duplicate vertices. Can be set false when you're sure that polygon - //orientation is correct and that there are no duplicate vertices. - if (autoFix) + IntPoint *botPt = 0, *pt = 0; + int botIdx = -1; + for (size_t i = 0; i < in_polys.size(); ++i) { - size_t polyCount = inPolys.size(), botPoly = 0; - while (botPoly < polyCount && inPolys[botPoly].empty()) botPoly++; - if (botPoly == polyCount) return; - - //botPt: used to find the lowermost (in inverted Y-axis) & leftmost point - //This point (on m_p[botPoly]) must be on an outer polygon ring and if - //its orientation is false (counterclockwise) then assume all polygons - //need reversing ... - IntPoint botPt = inPolys[botPoly][0]; - for (size_t i = botPoly; i < polyCount; ++i) - { - if (inPolys[i].size() < 3) { inPolys[i].clear(); continue; } - if (UpdateBotPt(inPolys[i][0], botPt)) botPoly = i; - Polygon::iterator it = inPolys[i].begin() +1; - while (it != inPolys[i].end()) + StripDupsAndGetBotPt(inPolys[i], out_polys[i], endtype == etClosed, pt); + if (botPt) + if (!botPt || pt->Y > botPt->Y || (pt->Y == botPt->Y && pt->X < botPt->X)) { - if (PointsEqual(*it, *(it -1))) - it = inPolys[i].erase(it); - else - { - if (UpdateBotPt(*it, botPt)) botPoly = i; - ++it; - } + botPt = pt; + botIdx = i; } - } - if (!Orientation(inPolys[botPoly])) - ReversePolygons(inPolys); - } - OffsetBuilder(inPolys, out_polys, true, delta, jointype, etClosed, limit); -} -//------------------------------------------------------------------------------ -void OffsetPolyLines(const Polygons &in_lines, Polygons &out_lines, - double delta, JoinType jointype, EndType endtype, - double limit, bool autoFix) -{ - if (!autoFix && endtype != etClosed && &in_lines != &out_lines) - { - OffsetBuilder(in_lines, out_lines, false, delta, jointype, endtype, limit); - return; } + if (endtype == etClosed && botIdx >= 0 && !Orientation(inPolys[botIdx])) + ReversePaths(inPolys); - Polygons inLines = Polygons(in_lines); - if (autoFix) - for (size_t i = 0; i < inLines.size(); ++i) - { - if (inLines[i].size() < 2) { inLines[i].clear(); continue; } - Polygon::iterator it = inLines[i].begin() +1; - while (it != inLines[i].end()) - { - if (PointsEqual(*it, *(it -1))) - it = inLines[i].erase(it); - else - ++it; - } - } - - if (endtype == etClosed) - { - size_t sz = inLines.size(); - inLines.resize(sz * 2); - for (size_t i = 0; i < sz; ++i) - { - inLines[sz+i] = inLines[i]; - ReversePolygon(inLines[sz+i]); - } - OffsetBuilder(inLines, out_lines, true, delta, jointype, endtype, limit); - } - else - OffsetBuilder(inLines, out_lines, false, delta, jointype, endtype, limit); + OffsetBuilder(inPolys, out_polys, delta, jointype, endtype, limit); } //------------------------------------------------------------------------------ -void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType) +void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType) { Clipper c; - c.ForceSimple(true); - c.AddPolygon(in_poly, ptSubject); + c.StrictlySimple(true); + c.AddPaths(in_polys, ptSubject, true); c.Execute(ctUnion, out_polys, fillType, fillType); } //------------------------------------------------------------------------------ -void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType) -{ - Clipper c; - c.ForceSimple(true); - c.AddPolygons(in_polys, ptSubject); - c.Execute(ctUnion, out_polys, fillType, fillType); -} -//------------------------------------------------------------------------------ - -void SimplifyPolygons(Polygons &polys, PolyFillType fillType) +void SimplifyPolygons(Paths &polys, PolyFillType fillType) { SimplifyPolygons(polys, polys, fillType); } @@ -3578,45 +4354,45 @@ void SimplifyPolygons(Polygons &polys, PolyFillType fillType) inline double DistanceSqrd(const IntPoint& pt1, const IntPoint& pt2) { - double dx = ((double)pt1.X - pt2.X); + double Dx = ((double)pt1.X - pt2.X); double dy = ((double)pt1.Y - pt2.Y); - return (dx*dx + dy*dy); + return (Dx*Dx + dy*dy); } //------------------------------------------------------------------------------ -DoublePoint ClosestPointOnLine(const IntPoint& pt, const IntPoint& linePt1, const IntPoint& linePt2) +DoublePoint ClosestPointOnLine(const IntPoint& Pt, const IntPoint& linePt1, const IntPoint& linePt2) { - double dx = ((double)linePt2.X - linePt1.X); + double Dx = ((double)linePt2.X - linePt1.X); double dy = ((double)linePt2.Y - linePt1.Y); - if (dx == 0 && dy == 0) + if (Dx == 0 && dy == 0) return DoublePoint((double)linePt1.X, (double)linePt1.Y); - double q = ((pt.X-linePt1.X)*dx + (pt.Y-linePt1.Y)*dy) / (dx*dx + dy*dy); + double q = ((Pt.X-linePt1.X)*Dx + (Pt.Y-linePt1.Y)*dy) / (Dx*Dx + dy*dy); return DoublePoint( (1-q)*linePt1.X + q*linePt2.X, (1-q)*linePt1.Y + q*linePt2.Y); } //------------------------------------------------------------------------------ -bool SlopesNearColinear(const IntPoint& pt1, +bool SlopesNearCollinear(const IntPoint& pt1, const IntPoint& pt2, const IntPoint& pt3, double distSqrd) { if (DistanceSqrd(pt1, pt2) > DistanceSqrd(pt1, pt3)) return false; DoublePoint cpol = ClosestPointOnLine(pt2, pt1, pt3); - double dx = pt2.X - cpol.X; + double Dx = pt2.X - cpol.X; double dy = pt2.Y - cpol.Y; - return (dx*dx + dy*dy) < distSqrd; + return (Dx*Dx + dy*dy) < distSqrd; } //------------------------------------------------------------------------------ bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd) { - double dx = (double)pt1.X - pt2.X; + double Dx = (double)pt1.X - pt2.X; double dy = (double)pt1.Y - pt2.Y; - return ((dx * dx) + (dy * dy) <= distSqrd); + return ((Dx * Dx) + (dy * dy) <= distSqrd); } //------------------------------------------------------------------------------ -void CleanPolygon(const Polygon& in_poly, Polygon& out_poly, double distance) +void CleanPolygon(const Path& in_poly, Path& out_poly, double distance) { //distance = proximity in units/pixels below which vertices //will be stripped. Default ~= sqrt(2). @@ -3628,73 +4404,215 @@ void CleanPolygon(const Polygon& in_poly, Polygon& out_poly, double distance) if (&in_poly != &out_poly) out_poly.resize(highI + 1); - IntPoint pt = in_poly[highI]; + IntPoint Pt = in_poly[highI]; int i = 0, k = 0; for (;;) { - while (i < highI && PointsAreClose(pt, in_poly[i+1], distSqrd)) i+=2; + while (i < highI && PointsAreClose(Pt, in_poly[i+1], distSqrd)) i+=2; int i2 = i; while (i < highI && (PointsAreClose(in_poly[i], in_poly[i+1], distSqrd) || - SlopesNearColinear(pt, in_poly[i], in_poly[i+1], distSqrd))) i++; + SlopesNearCollinear(Pt, in_poly[i], in_poly[i+1], distSqrd))) i++; if (i >= highI) break; else if (i != i2) continue; - pt = in_poly[i++]; - out_poly[k++] = pt; + Pt = in_poly[i++]; + out_poly[k++] = Pt; } if (i <= highI) out_poly[k++] = in_poly[i]; - if (k > 2 && SlopesNearColinear(out_poly[k -2], out_poly[k -1], out_poly[0], distSqrd)) k--; + if (k > 2 && SlopesNearCollinear(out_poly[k -2], out_poly[k -1], out_poly[0], distSqrd)) k--; if (k < 3) out_poly.clear(); else if (k <= highI) out_poly.resize(k); } //------------------------------------------------------------------------------ -void CleanPolygons(const Polygons& in_polys, Polygons& out_polys, double distance) +void CleanPolygon(Path& poly, double distance) +{ + CleanPolygon(poly, poly, distance); +} +//------------------------------------------------------------------------------ + +void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance) { - for (Polygons::size_type i = 0; i < in_polys.size(); ++i) + for (Paths::size_type i = 0; i < in_polys.size(); ++i) CleanPolygon(in_polys[i], out_polys[i], distance); } //------------------------------------------------------------------------------ -void AddPolyNodeToPolygons(const PolyNode& polynode, Polygons& polygons) +void CleanPolygons(Paths& polys, double distance) { - if (!polynode.Contour.empty()) - polygons.push_back(polynode.Contour); + CleanPolygons(polys, polys, distance); +} +//------------------------------------------------------------------------------ + +void Minkowki(const Path& poly, const Path& path, + Paths& solution, bool isSum, bool isClosed) +{ + int delta = (isClosed ? 1 : 0); + size_t polyCnt = poly.size(); + size_t pathCnt = path.size(); + Paths pp; + pp.reserve(pathCnt); + if (isSum) + for (size_t i = 0; i < pathCnt; ++i) + { + Path p; + p.reserve(polyCnt); + for (size_t j = 0; j < poly.size(); ++j) + p.push_back(IntPoint(path[i].X + poly[j].X, path[i].Y + poly[j].Y)); + pp.push_back(p); + } + else + for (size_t i = 0; i < pathCnt; ++i) + { + Path p; + p.reserve(polyCnt); + for (size_t j = 0; j < poly.size(); ++j) + p.push_back(IntPoint(path[i].X - poly[j].X, path[i].Y - poly[j].Y)); + pp.push_back(p); + } + + Paths quads; + quads.reserve((pathCnt + delta) * (polyCnt + 1)); + for (size_t i = 0; i <= pathCnt - 2 + delta; ++i) + for (size_t j = 0; j <= polyCnt - 1; ++j) + { + Path quad; + quad.reserve(4); + quad.push_back(pp[i % pathCnt][j % polyCnt]); + quad.push_back(pp[(i + 1) % pathCnt][j % polyCnt]); + quad.push_back(pp[(i + 1) % pathCnt][(j + 1) % polyCnt]); + quad.push_back(pp[i % pathCnt][(j + 1) % polyCnt]); + if (!Orientation(quad)) ReversePath(quad); + quads.push_back(quad); + } + + Clipper c; + c.AddPaths(quads, ptSubject, true); + c.Execute(ctUnion, solution, pftNonZero, pftNonZero); +} +//------------------------------------------------------------------------------ + +void MinkowkiSum(const Path& poly, const Path& path, Paths& solution, bool isClosed) +{ + Minkowki(poly, path, solution, true, isClosed); +} +//------------------------------------------------------------------------------ + +void MinkowkiDiff(const Path& poly, const Path& path, Paths& solution, bool isClosed) +{ + Minkowki(poly, path, solution, false, isClosed); +} +//------------------------------------------------------------------------------ + +enum NodeType {ntAny, ntOpen, ntClosed}; + +void AddPolyNodeToPolygons(const PolyNode& polynode, NodeType nodetype, Paths& paths) +{ + bool match = true; + if (nodetype == ntClosed) match = !polynode.IsOpen(); + else if (nodetype == ntOpen) return; + + if (!polynode.Contour.empty() && match) + paths.push_back(polynode.Contour); for (int i = 0; i < polynode.ChildCount(); ++i) - AddPolyNodeToPolygons(*polynode.Childs[i], polygons); + AddPolyNodeToPolygons(*polynode.Childs[i], nodetype, paths); +} +//------------------------------------------------------------------------------ + +void PolyTreeToPaths(const PolyTree& polytree, Paths& paths) +{ + paths.resize(0); + paths.reserve(polytree.Total()); + AddPolyNodeToPolygons(polytree, ntAny, paths); } //------------------------------------------------------------------------------ -void PolyTreeToPolygons(const PolyTree& polytree, Polygons& polygons) +void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths) { - polygons.resize(0); - polygons.reserve(polytree.Total()); - AddPolyNodeToPolygons(polytree, polygons); + paths.resize(0); + paths.reserve(polytree.Total()); + AddPolyNodeToPolygons(polytree, ntClosed, paths); } //------------------------------------------------------------------------------ -std::ostream& operator <<(std::ostream &s, IntPoint& p) +void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths) { - s << p.X << ' ' << p.Y << "\n"; + paths.resize(0); + paths.reserve(polytree.Total()); + //Open paths are top level only, so ... + for (int i = 0; i < polytree.ChildCount(); ++i) + if (polytree.Childs[i]->IsOpen()) + paths.push_back(polytree.Childs[i]->Contour); +} +//------------------------------------------------------------------------------ + +std::ostream& operator <<(std::ostream &s, const IntPoint &p) +{ + s << "(" << p.X << "," << p.Y << ")"; return s; } //------------------------------------------------------------------------------ -std::ostream& operator <<(std::ostream &s, Polygon &p) +std::ostream& operator <<(std::ostream &s, const Path &p) { - for (Polygon::size_type i = 0; i < p.size(); i++) - s << p[i]; - s << "\n"; + if (p.empty()) return s; + Path::size_type last = p.size() -1; + for (Path::size_type i = 0; i < last; i++) + s << "(" << p[i].X << "," << p[i].Y << "), "; + s << "(" << p[last].X << "," << p[last].Y << ")\n"; return s; } //------------------------------------------------------------------------------ -std::ostream& operator <<(std::ostream &s, Polygons &p) +std::ostream& operator <<(std::ostream &s, const Paths &p) { - for (Polygons::size_type i = 0; i < p.size(); i++) + for (Paths::size_type i = 0; i < p.size(); i++) s << p[i]; s << "\n"; return s; } //------------------------------------------------------------------------------ +#ifdef use_deprecated +bool ClipperBase::AddPolygon(const Path &pg, PolyType PolyTyp) +{ + return AddPath(pg, PolyTyp, true); +} +//------------------------------------------------------------------------------ + +bool ClipperBase::AddPolygons(const Paths &ppg, PolyType PolyTyp) +{ + bool result = false; + for (Paths::size_type i = 0; i < ppg.size(); ++i) + if (AddPath(ppg[i], PolyTyp, true)) result = true; + return result; +} +//------------------------------------------------------------------------------ + +void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, + double delta, JoinType jointype, double limit, bool autoFix) +{ + OffsetPaths(in_polys, out_polys, delta, jointype, etClosed, limit); +} +//------------------------------------------------------------------------------ + +void PolyTreeToPolygons(const PolyTree& polytree, Paths& paths) +{ + PolyTreeToPaths(polytree, paths); +} +//------------------------------------------------------------------------------ + +void ReversePolygon(Path& p) +{ + std::reverse(p.begin(), p.end()); +} +//------------------------------------------------------------------------------ + +void ReversePolygons(Paths& p) +{ + for (Paths::size_type i = 0; i < p.size(); ++i) + ReversePolygon(p[i]); +} +#endif + + } //ClipperLib namespace diff --git a/cpp/clipper.hpp b/cpp/clipper.hpp index e313cfa..cbc7029 100644 --- a/cpp/clipper.hpp +++ b/cpp/clipper.hpp @@ -1,8 +1,8 @@ /******************************************************************************* * * * Author : Angus Johnson * -* Version : 5.1.6 * -* Date : 23 May 2013 * +* Version : 6.0.0 * +* Date : 30 October 2013 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2013 * * * @@ -34,11 +34,30 @@ #ifndef clipper_hpp #define clipper_hpp +#define CLIPPER_VERSION "6.0.0" + +//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 + +//When enabled, code developed with earlier versions of Clipper +//(ie prior to ver 6) should compile without changes. +//In a future update, this compatability code will be removed. +#define use_deprecated + #include +#include #include #include #include #include +#include namespace ClipperLib { @@ -50,23 +69,63 @@ enum PolyType { ptSubject, ptClip }; //see http://glprogramming.com/red/chapter11.html enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }; -typedef signed long long long64; -typedef unsigned long long ulong64; +#ifdef use_int32 +typedef int cInt; +typedef unsigned int cUInt; +#else +typedef signed long long cInt; +typedef unsigned long long cUInt; +#endif struct IntPoint { -public: - long64 X; - long64 Y; - IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {}; - friend std::ostream& operator <<(std::ostream &s, IntPoint &p); + 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; -typedef std::vector< IntPoint > Polygon; -typedef std::vector< Polygon > Polygons; +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); -std::ostream& operator <<(std::ostream &s, Polygon &p); -std::ostream& operator <<(std::ostream &s, Polygons &p); +#ifdef use_deprecated +typedef signed long long long64; //backward compatibility only +typedef Path Polygon; +typedef Paths Polygons; +#endif + +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 (*TZFillCallback)(IntPoint& z1, IntPoint& z2, IntPoint& pt); +#endif class PolyNode; typedef std::vector< PolyNode* > PolyNodes; @@ -75,13 +134,15 @@ class PolyNode { public: PolyNode(); - Polygon Contour; + Path Contour; PolyNodes Childs; PolyNode* Parent; PolyNode* GetNext() const; bool IsHole() const; + bool IsOpen() const; int ChildCount() const; private: + bool m_IsOpen; PolyNode* GetNextSiblingUp() const; unsigned Index; //node index in Parent.Childs void AddChild(PolyNode& child); @@ -99,119 +160,63 @@ class PolyTree: public PolyNode PolyNodes AllNodes; friend class Clipper; //to access AllNodes }; - -enum JoinType { jtSquare, jtRound, jtMiter }; -enum EndType { etClosed, etButt, etSquare, etRound}; - -bool Orientation(const Polygon &poly); -double Area(const Polygon &poly); - -void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, - double delta, JoinType jointype = jtSquare, double limit = 0, bool autoFix = true); - -void OffsetPolyLines(const Polygons &in_lines, Polygons &out_lines, - double delta, JoinType jointype = jtSquare, EndType endtype = etSquare, double limit = 0, bool autoFix = true); - -void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd); -void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd); -void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd); - -void CleanPolygon(const Polygon& in_poly, Polygon& out_poly, double distance = 1.415); -void CleanPolygons(const Polygons& in_polys, Polygons& out_polys, double distance = 1.415); -void PolyTreeToPolygons(const PolyTree& polytree, Polygons& polygons); +enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4}; +enum JoinType {jtSquare, jtRound, jtMiter}; +enum EndType {etClosed, etButt, etSquare, etRound}; -void ReversePolygon(Polygon& p); -void ReversePolygons(Polygons& p); +bool Orientation(const Path &poly); +double Area(const Path &poly); -//used internally ... -enum EdgeSide { esLeft = 1, esRight = 2}; -enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 }; -//inline IntersectProtects operator|(IntersectProtects a, IntersectProtects b) -//{return static_cast(static_cast(a) | static_cast(b));} - -struct TEdge { - long64 xbot; - long64 ybot; - long64 xcurr; - long64 ycurr; - long64 xtop; - long64 ytop; - double dx; - long64 deltaX; - long64 deltaY; - PolyType polyType; - EdgeSide side; - int windDelta; //1 or -1 depending on winding direction - int windCnt; - int windCnt2; //winding count of the opposite polytype - int outIdx; - TEdge *next; - TEdge *prev; - TEdge *nextInLML; - TEdge *nextInAEL; - TEdge *prevInAEL; - TEdge *nextInSEL; - TEdge *prevInSEL; -}; +#ifdef use_deprecated + void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, + double delta, JoinType jointype = jtSquare, double limit = 0, bool autoFix = true); + void PolyTreeToPolygons(const PolyTree& polytree, Paths& paths); + void ReversePolygon(Path& p); + void ReversePolygons(Paths& p); +#endif -struct IntersectNode { - TEdge *edge1; - TEdge *edge2; - IntPoint pt; - IntersectNode *next; -}; +void OffsetPaths(const Paths &in_polys, Paths &out_polys, + double delta, JoinType jointype, EndType endtype, double limit = 0); -struct LocalMinima { - long64 Y; - TEdge *leftBound; - TEdge *rightBound; - LocalMinima *next; -}; +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); -struct Scanbeam { - long64 Y; - Scanbeam *next; -}; +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); -struct OutPt; //forward declaration +void MinkowkiSum(const Path& poly, const Path& path, Paths& solution, bool isClosed); +void MinkowkiDiff(const Path& poly, const Path& path, Paths& solution, bool isClosed); -struct OutRec { - int idx; - bool isHole; - OutRec *FirstLeft; //see comments in clipper.pas - PolyNode *polyNode; - OutPt *pts; - OutPt *bottomPt; -}; +void PolyTreeToPaths(const PolyTree& polytree, Paths& paths); +void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths); +void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths); -struct OutPt { - int idx; - IntPoint pt; - OutPt *next; - OutPt *prev; -}; +void ReversePath(Path& p); +void ReversePaths(Paths& p); -struct JoinRec { - IntPoint pt1a; - IntPoint pt1b; - int poly1Idx; - IntPoint pt2a; - IntPoint pt2b; - int poly2Idx; -}; +struct IntRect { cInt left; cInt top; cInt right; cInt bottom; }; -struct HorzJoinRec { - TEdge *edge; - int savedIdx; -}; +//enums that are used internally ... +enum EdgeSide { esLeft = 1, esRight = 2}; -struct IntRect { long64 left; long64 top; long64 right; long64 bottom; }; +//forward declarations (for stuff used internally) ... +struct TEdge; +struct IntersectNode; +struct LocalMinima; +struct Scanbeam; +struct OutPt; +struct OutRec; +struct Join; typedef std::vector < OutRec* > PolyOutList; typedef std::vector < TEdge* > EdgeList; -typedef std::vector < JoinRec* > JoinList; -typedef std::vector < HorzJoinRec* > HorzJoinList; +typedef std::vector < Join* > JoinList; + +//------------------------------------------------------------------------------ //ClipperBase is the ancestor to the Clipper class. It should not be //instantiated directly. This class simply abstracts the conversion of sets of @@ -221,29 +226,43 @@ class ClipperBase public: ClipperBase(); virtual ~ClipperBase(); - bool AddPolygon(const Polygon &pg, PolyType polyType); - bool AddPolygons( const Polygons &ppg, PolyType polyType); + bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed); + bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed); + +#ifdef use_deprecated + bool AddPolygon(const Path &pg, PolyType PolyTyp); + bool AddPolygons(const Paths &ppg, PolyType PolyTyp); +#endif + virtual void Clear(); IntRect GetBounds(); + bool PreserveCollinear() {return m_PreserveCollinear;}; + void PreserveCollinear(bool value) {m_PreserveCollinear = value;}; protected: void DisposeLocalMinimaList(); - TEdge* AddBoundsToLML(TEdge *e); + TEdge* AddBoundsToLML(TEdge *e, bool IsClosed); void PopLocalMinima(); virtual void Reset(); void InsertLocalMinima(LocalMinima *newLm); + void DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed); + TEdge* DescendToMin(TEdge *&E); + void AscendToMax(TEdge *&E, bool Appending, bool IsClosed); LocalMinima *m_CurrentLM; LocalMinima *m_MinimaList; bool m_UseFullRange; EdgeList m_edges; + bool m_PreserveCollinear; + bool m_HasOpenPaths; }; +//------------------------------------------------------------------------------ class Clipper : public virtual ClipperBase { public: - Clipper(); + Clipper(int initOptions = 0); ~Clipper(); bool Execute(ClipType clipType, - Polygons &solution, + Paths &solution, PolyFillType subjFillType = pftEvenOdd, PolyFillType clipFillType = pftEvenOdd); bool Execute(ClipType clipType, @@ -253,17 +272,21 @@ class Clipper : public virtual ClipperBase void Clear(); bool ReverseSolution() {return m_ReverseOutput;}; void ReverseSolution(bool value) {m_ReverseOutput = value;}; - bool ForceSimple() {return m_ForceSimple;}; - void ForceSimple(bool value) {m_ForceSimple = 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(TZFillCallback zFillFunc); +#endif protected: void Reset(); virtual bool ExecuteInternal(); private: PolyOutList m_PolyOuts; JoinList m_Joins; - HorzJoinList m_HorizJoins; + JoinList m_GhostJoins; ClipType m_ClipType; - Scanbeam *m_Scanbeam; + std::set< cInt, std::greater > m_Scanbeam; TEdge *m_ActiveEdges; TEdge *m_SortedEdges; IntersectNode *m_IntersectNodes; @@ -272,15 +295,17 @@ class Clipper : public virtual ClipperBase PolyFillType m_SubjFillType; bool m_ReverseOutput; bool m_UsingPolyTree; - bool m_ForceSimple; - void DisposeScanbeamList(); + bool m_StrictSimple; +#ifdef use_xyz + TZFillCallback m_ZFill; //custom callback +#endif void SetWindingCount(TEdge& edge); bool IsEvenOddFillType(const TEdge& edge) const; bool IsEvenOddAltFillType(const TEdge& edge) const; - void InsertScanbeam(const long64 Y); - long64 PopScanbeam(); - void InsertLocalMinimaIntoAEL(const long64 botY); - void InsertEdgeIntoAEL(TEdge *edge); + void InsertScanbeam(const cInt Y); + cInt PopScanbeam(); + void InsertLocalMinimaIntoAEL(const cInt botY); + void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge); void AddEdgeToSEL(TEdge *edge); void CopyAELToSEL(); void DeleteFromSEL(TEdge *e); @@ -288,27 +313,28 @@ class Clipper : public virtual ClipperBase void UpdateEdgeIntoAEL(TEdge *&e); void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2); bool IsContributing(const TEdge& edge) const; - bool IsTopHorz(const long64 XPos); + bool IsTopHorz(const cInt XPos); void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); - void DoMaxima(TEdge *e, long64 topY); - void ProcessHorizontals(); - void ProcessHorizontal(TEdge *horzEdge); + void DoMaxima(TEdge *e); + void PrepareHorzJoins(TEdge* horzEdge, bool isTopOfScanbeam); + void ProcessHorizontals(bool IsTopOfScanbeam); + void ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam); void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); - void AddLocalMinPoly(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, - const IntPoint &pt, const IntersectProtects protects); + const IntPoint &pt, bool protect = false); OutRec* CreateOutRec(); - void AddOutPt(TEdge *e, const IntPoint &pt); - void DisposeAllPolyPts(); + OutPt* AddOutPt(TEdge *e, const IntPoint &pt); + void DisposeAllOutRecs(); void DisposeOutRec(PolyOutList::size_type index); - bool ProcessIntersections(const long64 botY, const long64 topY); + bool ProcessIntersections(const cInt botY, const cInt topY); void InsertIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt); - void BuildIntersectList(const long64 botY, const long64 topY); + void BuildIntersectList(const cInt botY, const cInt topY); void ProcessIntersectList(); - void ProcessEdgesAtTopOfScanbeam(const long64 topY); - void BuildResult(Polygons& polys); + void ProcessEdgesAtTopOfScanbeam(const cInt topY); + void BuildResult(Paths& polys); void BuildResult2(PolyTree& polytree); void SetHoleState(TEdge *e, OutRec *outrec); void DisposeIntersectNodes(); @@ -316,19 +342,19 @@ class Clipper : public virtual ClipperBase void FixupOutPolygon(OutRec &outrec); bool IsHole(TEdge *e); void FixHoleLinkage(OutRec &outrec); - void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1); + void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt); void ClearJoins(); - void AddHorzJoin(TEdge *e, int idx); - void ClearHorzJoins(); - bool JoinPoints(const JoinRec *j, OutPt *&p1, OutPt *&p2); - void FixupJoinRecs(JoinRec *j, OutPt *pt, unsigned startIdx); + void ClearGhostJoins(); + void AddGhostJoin(OutPt *op, const IntPoint offPt); + bool JoinPoints(const Join *j, OutPt *&p1, OutPt *&p2); void JoinCommonEdges(); void DoSimplePolygons(); void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec); void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec); +#ifdef use_xyz + void SetZ(IntPoint& pt, TEdge& e); +#endif }; - -//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ class clipperException : public std::exception diff --git a/cpp/cpp_agg/agg_conv_clipper.h b/cpp/cpp_agg/agg_conv_clipper.h index 55532ce..15f66f9 100644 --- a/cpp/cpp_agg/agg_conv_clipper.h +++ b/cpp/cpp_agg/agg_conv_clipper.h @@ -39,15 +39,15 @@ namespace agg status m_status; int m_vertex; int m_contour; - int m_scaling_factor; - clipper_op_e m_operation; + int m_scaling_factor; + clipper_op_e m_operation; pod_bvector m_vertex_accumulator; - ClipperLib::Polygons m_poly_a; - ClipperLib::Polygons m_poly_b; - ClipperLib::Polygons m_result; - ClipperLib::Clipper m_clipper; - clipper_PolyFillType m_subjFillType; - clipper_PolyFillType m_clipFillType; + ClipperLib::Paths m_poly_a; + ClipperLib::Paths m_poly_b; + ClipperLib::Paths m_result; + ClipperLib::Clipper m_clipper; + clipper_PolyFillType m_subjFillType; + clipper_PolyFillType m_clipFillType; int Round(double val) { @@ -91,9 +91,9 @@ namespace agg bool next_vertex(double* x, double* y); void start_extracting(); void add_vertex_(double &x, double &y); - void end_contour(ClipperLib::Polygons &p); + void end_contour(ClipperLib::Paths &p); - template void add(VS &src, ClipperLib::Polygons &p){ + template void add(VS &src, ClipperLib::Paths &p){ unsigned cmd; double x; double y; double start_x; double start_y; bool starting_first_line; @@ -169,36 +169,36 @@ namespace agg switch( m_operation ) { case clipper_or: { - m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject ); - m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip ); + m_clipper.AddPaths( m_poly_a , ClipperLib::ptSubject, true ); + m_clipper.AddPaths( m_poly_b , ClipperLib::ptClip, true ); m_clipper.Execute( ClipperLib::ctUnion , m_result , pftSubj, pftClip); break; } case clipper_and: { - m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject ); - m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip ); + m_clipper.AddPaths( m_poly_a , ClipperLib::ptSubject, true ); + m_clipper.AddPaths( m_poly_b , ClipperLib::ptClip, true ); m_clipper.Execute( ClipperLib::ctIntersection , m_result, pftSubj, pftClip ); break; } case clipper_xor: { - m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject ); - m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip ); + m_clipper.AddPaths( m_poly_a , ClipperLib::ptSubject, true ); + m_clipper.AddPaths( m_poly_b , ClipperLib::ptClip, true ); m_clipper.Execute( ClipperLib::ctXor , m_result, pftSubj, pftClip ); break; } case clipper_a_minus_b: { - m_clipper.AddPolygons( m_poly_a , ClipperLib::ptSubject ); - m_clipper.AddPolygons( m_poly_b , ClipperLib::ptClip ); + m_clipper.AddPaths( m_poly_a , ClipperLib::ptSubject, true ); + m_clipper.AddPaths( m_poly_b , ClipperLib::ptClip, true ); m_clipper.Execute( ClipperLib::ctDifference , m_result, pftSubj, pftClip ); break; } case clipper_b_minus_a: { - m_clipper.AddPolygons( m_poly_b , ClipperLib::ptSubject ); - m_clipper.AddPolygons( m_poly_a , ClipperLib::ptClip ); + m_clipper.AddPaths( m_poly_b , ClipperLib::ptSubject, true ); + m_clipper.AddPaths( m_poly_a , ClipperLib::ptClip, true ); m_clipper.Execute( ClipperLib::ctDifference , m_result, pftSubj, pftClip ); break; } @@ -208,7 +208,7 @@ namespace agg //------------------------------------------------------------------------------ template - void conv_clipper::end_contour( ClipperLib::Polygons &p) + void conv_clipper::end_contour( ClipperLib::Paths &p) { unsigned i, len; diff --git a/cpp/cpp_cairo/cairo_clipper.cpp b/cpp/cpp_cairo/cairo_clipper.cpp index d373b1b..5767b9d 100644 --- a/cpp/cpp_cairo/cairo_clipper.cpp +++ b/cpp/cpp_cairo/cairo_clipper.cpp @@ -23,12 +23,12 @@ namespace ClipperLib { namespace { - inline long64 Round(double val) + inline cInt Round(double val) { - if ((val < 0)) return (long64)(val - 0.5); else return (long64)(val + 0.5); + if ((val < 0)) return (cInt)(val - 0.5); else return (cInt)(val + 0.5); } - void transform_point(cairo_t* pen, Transform transform, long64* x, long64* y) + void transform_point(cairo_t* pen, Transform transform, cInt* x, cInt* y) { double _x = (double)*x, _y = (double)*y; switch (transform) @@ -47,7 +47,7 @@ namespace ClipperLib { } void cairo_to_clipper(cairo_t* cr, - Polygons &pg, + Paths &pg, int scaling_factor, Transform transform) { @@ -105,7 +105,7 @@ namespace ClipperLib { } //-------------------------------------------------------------------------- - void clipper_to_cairo(const Polygons &pg, + void clipper_to_cairo(const Paths &pg, cairo_t* cr, int scaling_factor, Transform transform) @@ -120,7 +120,7 @@ namespace ClipperLib { continue; cairo_new_sub_path(cr); for (size_t j = 0; j < sz; ++j) { - long64 x = pg[i][j].X, y = pg[i][j].Y; + cInt x = pg[i][j].X, y = pg[i][j].Y; if (transform != tNone) transform_point(cr, transform, &x, &y); cairo_line_to(cr, (double)x / scaling, (double)y / scaling); diff --git a/cpp/cpp_cairo/cairo_clipper.hpp b/cpp/cpp_cairo/cairo_clipper.hpp index d767da2..7c52dfd 100644 --- a/cpp/cpp_cairo/cairo_clipper.hpp +++ b/cpp/cpp_cairo/cairo_clipper.hpp @@ -33,11 +33,11 @@ namespace ClipperLib { //accomplished by setting the scaling factor (10^x) in the following functions. //When scaling, remember that on most platforms, integer is only a 32bit value. void cairo_to_clipper(cairo_t* cr, - ClipperLib::Polygons &pg, + ClipperLib::Paths &pg, int scaling_factor = 0, Transform transform = tNone); - void clipper_to_cairo(const ClipperLib::Polygons &pg, + void clipper_to_cairo(const ClipperLib::Paths &pg, cairo_t* cr, int scaling_factor = 0, Transform transform = tNone); diff --git a/cpp/cpp_cairo/main.cpp b/cpp/cpp_cairo/main.cpp index 13a6012..4c71b95 100644 --- a/cpp/cpp_cairo/main.cpp +++ b/cpp/cpp_cairo/main.cpp @@ -12,15 +12,17 @@ #include "cairo_clipper.hpp" //--------------------------------------------------------------------------- -LPCTSTR ClsName = "CairoApp"; -LPCTSTR WndName = "A Simple Cairo Clipper Demo"; -int offsetVal = 0; +int offsetVal; LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -int CALLBACK WinMain(HINSTANCE hInstance, +int APIENTRY main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { + WCHAR* ClsName = L"CairoApp"; + WCHAR* WndName = L"A Simple Cairo Clipper Demo"; + offsetVal = 0; + MSG Msg; HWND hWnd; WNDCLASSEX WndClsEx; @@ -87,7 +89,7 @@ void OnPaint(HWND hWnd, HDC dc) cairo_arc(cr, 170,110,70,0,2*3.1415926); cairo_close_path(cr); cairo::cairo_to_clipper(cr, pg, scaling); - clpr.AddPolygons(pg, ptSubject); + clpr.AddPaths(pg, ptSubject, true); cairo_set_source_rgba(cr, 0, 0, 1, 0.25); cairo_fill_preserve (cr); cairo_set_source_rgba(cr, 0, 0, 0, 0.5); @@ -104,7 +106,7 @@ void OnPaint(HWND hWnd, HDC dc) cairo_arc(cr, 190,50,20,0,2*3.1415926); cairo_close_path(cr); cairo::cairo_to_clipper(cr, pg, scaling); - clpr.AddPolygons(pg, ptClip); + clpr.AddPaths(pg, ptClip, true); cairo_set_source_rgba(cr, 1, 0, 0, 0.25); cairo_fill_preserve (cr); cairo_set_source_rgba(cr, 0, 0, 0, 0.5); @@ -112,7 +114,7 @@ void OnPaint(HWND hWnd, HDC dc) clpr.Execute(ctIntersection, pg, pftNonZero, pftNonZero); //now do something fancy with the returned polygons ... - OffsetPolygons(pg, pg, offsetVal * std::pow((double)10,scaling), jtMiter); + OffsetPaths(pg, pg, offsetVal * std::pow((double)10,scaling), jtMiter, etClosed); //finally copy the clipped path back to the cairo context and draw it ... cairo::clipper_to_cairo(pg, cr, scaling); diff --git a/cpp/cpp_console/Debug/clip.txt b/cpp/cpp_console/Debug/clip.txt deleted file mode 100644 index 9a4a413..0000000 --- a/cpp/cpp_console/Debug/clip.txt +++ /dev/null @@ -1,6 +0,0 @@ -1 -4 -90, 10, -240, 10, -240, 90, -90, 90 \ No newline at end of file diff --git a/cpp/cpp_console/Debug/subj.txt b/cpp/cpp_console/Debug/subj.txt deleted file mode 100644 index 7033a4c..0000000 --- a/cpp/cpp_console/Debug/subj.txt +++ /dev/null @@ -1,13 +0,0 @@ -1 -11 -0, 0, -200, 0, -200, 100, -50, 100, -50, 50, -75, 75, -100, 50, -75, 25, -50, 50, -50, 100, -0, 100, diff --git a/cpp/cpp_console/File1.cpp b/cpp/cpp_console/File1.cpp deleted file mode 100644 index 5c57651..0000000 --- a/cpp/cpp_console/File1.cpp +++ /dev/null @@ -1,458 +0,0 @@ -//--------------------------------------------------------------------------- - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "clipper.hpp" - -//--------------------------------------------------------------------------- - -using namespace std; -using namespace ClipperLib; - -static string ColorToHtml(unsigned clr) -{ - stringstream ss; - ss << '#' << hex << std::setfill('0') << setw(6) << (clr & 0xFFFFFF); - return ss.str(); -} -//------------------------------------------------------------------------------ - -static float GetAlphaAsFrac(unsigned clr) -{ - return ((float)(clr >> 24) / 255); -} -//------------------------------------------------------------------------------ - -//a simple class that builds an SVG file with any number of polygons -class SVGBuilder -{ - - class StyleInfo - { - public: - PolyFillType pft; - unsigned brushClr; - unsigned penClr; - double penWidth; - bool showCoords; - - StyleInfo() - { - pft = pftNonZero; - brushClr = 0xFFFFFFCC; - penClr = 0xFF000000; - penWidth = 0.8; - showCoords = false; - } - }; - - class PolyInfo - { - public: - Polygons polygons; - StyleInfo si; - - PolyInfo(Polygons polygons, StyleInfo style) - { - this->polygons = polygons; - this->si = style; - } - }; - - typedef std::vector PolyInfoList; - -private: - PolyInfoList polyInfos; - static const std::string svg_xml_start[]; - static const std::string poly_end[]; - -public: - StyleInfo style; - - void AddPolygons(Polygons& poly) - { - if (poly.size() == 0) return; - polyInfos.push_back(PolyInfo(poly, style)); - } - - bool SaveToFile(char * filename, double scale = 1.0, int margin = 10) - { - //calculate the bounding rect ... - PolyInfoList::size_type i = 0; - Polygons::size_type j; - while (i < polyInfos.size()) - { - j = 0; - while (j < polyInfos[i].polygons.size() && - polyInfos[i].polygons[j].size() == 0) j++; - if (j < polyInfos[i].polygons.size()) break; - i++; - } - if (i == polyInfos.size()) return false; - - IntRect rec; - rec.left = polyInfos[i].polygons[j][0].X; - rec.right = rec.left; - rec.top = polyInfos[i].polygons[j][0].Y; - rec.bottom = rec.top; - for ( ; i < polyInfos.size(); ++i) - for (Polygons::size_type j = 0; j < polyInfos[i].polygons.size(); ++j) - for (Polygon::size_type k = 0; k < polyInfos[i].polygons[j].size(); ++k) - { - IntPoint ip = polyInfos[i].polygons[j][k]; - if (ip.X < rec.left) rec.left = ip.X; - else if (ip.X > rec.right) rec.right = ip.X; - if (ip.Y < rec.top) rec.top = ip.Y; - else if (ip.Y > rec.bottom) rec.bottom = ip.Y; - } - - if (scale == 0) scale = 1.0; - if (margin < 0) margin = 0; - rec.left = (long64)((double)rec.left * scale); - rec.top = (long64)((double)rec.top * scale); - rec.right = (long64)((double)rec.right * scale); - rec.bottom = (long64)((double)rec.bottom * scale); - long64 offsetX = -rec.left + margin; - long64 offsetY = -rec.top + margin; - - ofstream file; - file.open(filename); - if (!file.is_open()) return false; - file.setf(ios::fixed); - file.precision(0); - file << svg_xml_start[0] << - ((rec.right - rec.left) + margin*2) << "px" << svg_xml_start[1] << - ((rec.bottom - rec.top) + margin*2) << "px" << svg_xml_start[2] << - ((rec.right - rec.left) + margin*2) << " " << - ((rec.bottom - rec.top) + margin*2) << svg_xml_start[3]; - setlocale(LC_NUMERIC, "C"); - file.precision(2); - - for (PolyInfoList::size_type i = 0; i < polyInfos.size(); ++i) - { - file << " \n\n"; - for (Polygons::size_type j = 0; j < polyInfos[i].polygons.size(); ++j) - { - if (polyInfos[i].polygons[j].size() < 3) continue; - for (Polygon::size_type k = 0; k < polyInfos[i].polygons[j].size(); ++k) - { - IntPoint ip = polyInfos[i].polygons[j][k]; - file << "" << - ip.X << "," << ip.Y << "\n"; - file << "\n"; - } - } - file << "\n"; - } - } - file << "\n"; - file.close(); - setlocale(LC_NUMERIC, ""); - return true; - } -}; -//------------------------------------------------------------------------------ - -const std::string SVGBuilder::svg_xml_start [] = - {"\n" - "\n\n" - "\n\n" - }; -const std::string SVGBuilder::poly_end [] = - {"\"\n style=\"fill:", - "; fill-opacity:", - "; fill-rule:", - "; stroke:", - "; stroke-opacity:", - "; stroke-width:", - ";\"/>\n\n" - }; - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ - -inline long64 Round(double val) -{ - if ((val < 0)) return (long64)(val - 0.5); else return (long64)(val + 0.5); -} -//------------------------------------------------------------------------------ - -bool LoadFromFile(Polygons &ppg, char * filename, double scale= 1, - int xOffset = 0, int yOffset = 0) -{ - ppg.clear(); - - FILE *f = fopen(filename, "r"); - if (!f) return false; - int polyCnt, vertCnt; - char junk [80]; - double X, Y; - if (fscanf(f, "%d", &polyCnt) == 1 && polyCnt > 0) - { - ppg.resize(polyCnt); - for (int i = 0; i < polyCnt; i++) { - if (fscanf(f, "%d", &vertCnt) != 1 || vertCnt <= 0) break; - ppg[i].resize(vertCnt); - for (int j = 0; j < vertCnt; j++) { - if (fscanf(f, "%lf%*[, ]%lf", &X, &Y) != 2) break; - ppg[i][j].X = Round((X + xOffset) * scale); - ppg[i][j].Y = Round((Y + yOffset) * scale); - fgets(junk, 80, f); - } - } - } - fclose(f); - return true; -} -//------------------------------------------------------------------------------ - -void SaveToConsole(const string name, const Polygons &pp, double scale = 1.0) -{ - cout << '\n' << name << ":\n" - << pp.size() << '\n'; - for (unsigned i = 0; i < pp.size(); ++i) - { - cout << pp[i].size() << '\n'; - for (unsigned j = 0; j < pp[i].size(); ++j) - cout << pp[i][j].X /scale << ", " << pp[i][j].Y /scale << ",\n"; - } - cout << "\n"; -} -//--------------------------------------------------------------------------- - -void SaveToFile(char *filename, Polygons &pp, double scale = 1) -{ - FILE *f = fopen(filename, "w"); - if (!f) return; - fprintf(f, "%d\n", pp.size()); - for (unsigned i = 0; i < pp.size(); ++i) - { - fprintf(f, "%d\n", pp[i].size()); - if (scale > 1.01 || scale < 0.99) { - for (unsigned j = 0; j < pp[i].size(); ++j) - fprintf(f, "%.6lf, %.6lf,\n", - (double)pp[i][j].X /scale, (double)pp[i][j].Y /scale); - } - else - { - for (unsigned j = 0; j < pp[i].size(); ++j) - fprintf(f, "%lld, %lld,\n", pp[i][j].X, pp[i][j].Y ); - } - } - fclose(f); -} -//--------------------------------------------------------------------------- - -void MakeRandomPoly(int edgeCount, int width, int height, Polygons & poly) -{ - poly.resize(1); - poly[0].resize(edgeCount); - for (int i = 0; i < edgeCount; i++){ - poly[0][i].X = rand() % width; - poly[0][i].Y = rand() % height; - } -} -//------------------------------------------------------------------------------ - -#pragma argsused -int _tmain(int argc, _TCHAR* argv[]) -{ - if (argc > 1 && - (strcmp(argv[1], "-b") == 0 || strcmp(argv[1], "--benchmark") == 0)) - { - //do a benchmark test that creates a subject and a clip polygon both with - //100 vertices randomly placed in a 400 * 400 space. Then perform an - //intersection operation based on even-odd filling. Repeat all this X times. - int loop_cnt = 100; - char * dummy; - if (argc > 2) loop_cnt = strtol(argv[2], &dummy, 10); - if (loop_cnt == 0) loop_cnt = 100; - cout << "\nPerforming " << loop_cnt << " random intersection operations ... "; - srand(time(0)); - int error_cnt = 0; - Polygons subject, clip, solution; - Clipper clpr; - time_t time_start = clock(); - for (int i = 0; i < loop_cnt; i++) { - MakeRandomPoly(100, 400, 400, subject); - MakeRandomPoly(100, 400, 400, clip); - clpr.Clear(); - clpr.AddPolygons(subject, ptSubject); - clpr.AddPolygons(clip, ptClip); - if (!clpr.Execute(ctIntersection, solution, pftEvenOdd, pftEvenOdd)) - error_cnt++; - } - double time_elapsed = double(clock() - time_start)/CLOCKS_PER_SEC; - cout << "\nFinished in " << time_elapsed << " secs with "; - cout << error_cnt << " errors.\n\n"; - //let's save the very last result ... - SaveToFile("Subject.txt", subject); - SaveToFile("Clip.txt", clip); - SaveToFile("Solution.txt", solution); - //and see it as an image too ... - SVGBuilder svg; - svg.style.penWidth = 0.8; - svg.style.pft = pftEvenOdd; - svg.style.brushClr = 0x1200009C; - svg.style.penClr = 0xCCD3D3DA; - svg.AddPolygons(subject); - svg.style.brushClr = 0x129C0000; - svg.style.penClr = 0xCCFFA07A; - svg.AddPolygons(clip); - svg.style.brushClr = 0x6080ff9C; - svg.style.penClr = 0xFF003300; - svg.style.pft = pftNonZero; - svg.AddPolygons(solution); - svg.SaveToFile("solution.svg"); - return 0; - } - - if (argc < 3) - { - cout << "\nUSAGE:\n" - << "clipper --benchmark [LOOP_COUNT (default = 100)]\n" - << "or\n" - << "clipper sub_file clp_file CLIPTYPE [SUB_FILL CLP_FILL] [PRECISION] [SVG_SCALE]\n" - << "where ...\n" - << " CLIPTYPE = INTERSECTION or UNION or DIFFERENCE or XOR, and\n" - << " ???_FILL = EVENODD or NONZERO (default = NONZERO)\n" - << " PRECISION = in decimal places (default = 0)\n" - << " SVG_SCALE = SVG output scale (default = 1.0)\n\n"; - cout << "\nINPUT AND OUTPUT FILE FORMAT ([optional] {comments}):\n" - << "Polygon Count\n" - << "Vertex Count {first polygon}\n" - << "X, Y[,] {first vertex}\n" - << "X, Y[,] {next vertex}\n" - << "{etc.}\n" - << "Vertex Count {second polygon, if there is one}\n" - << "X, Y[,] {first vertex of second polygon}\n" - << "{etc.}\n\n"; - return 1; - } - - int scale_log10 = 0; - char * dummy; - if (argc > 6) scale_log10 = strtol(argv[6], &dummy, 10); - double scale = std::pow(double(10), scale_log10); - - double svg_scale = 1.0; - if (argc > 7) svg_scale = strtod(argv[7], &dummy); - svg_scale /= scale; - - Polygons subject, clip; - - if (!LoadFromFile(subject, argv[1], scale)) - { - cerr << "\nCan't open the file " << argv[1] - << " or the file format is invalid.\n"; - return 1; - } - if (!LoadFromFile(clip, argv[2], scale)) - { - cerr << "\nCan't open the file " << argv[2] - << " or the file format is invalid.\n"; - return 1; - } - - ClipType clipType = ctIntersection; - const string sClipType[] = {"INTERSECTION", "UNION", "DIFFERENCE", "XOR"}; - - if (argc > 3) - { - if (stricmp(argv[3], "XOR") == 0) clipType = ctXor; - else if (stricmp(argv[3], "UNION") == 0) clipType = ctUnion; - else if (stricmp(argv[3], "DIFFERENCE") == 0) clipType = ctDifference; - else clipType = ctIntersection; - } - - PolyFillType subj_pft = pftNonZero, clip_pft = pftNonZero; - if (argc > 5) - { - if (stricmp(argv[4], "EVENODD") == 0) subj_pft = pftEvenOdd; - if (stricmp(argv[5], "EVENODD") == 0) clip_pft = pftEvenOdd; - } - - Clipper c; - c.AddPolygons(subject, ptSubject); - c.AddPolygons(clip, ptClip); - Polygons solution; - - bool succeeded = c.Execute(clipType, solution, subj_pft, clip_pft); - string s = "Subjects ("; - s += (subj_pft == pftEvenOdd ? "EVENODD)" : "NONZERO)"); - - //ie don't change the polygons back to the original size if we've - //just down-sized them to a manageable (all-in-one-screen) size ... - //if (scale < 1) scale = 1; - - SaveToConsole(s, subject, scale); - s = "Clips ("; - s += (clip_pft == pftEvenOdd ? "EVENODD)" : "NONZERO)"); - SaveToConsole(s, clip, scale); - if (succeeded) { - s = "Solution (using " + sClipType[clipType] + ")"; - //SaveToConsole(s, solution, scale); - SaveToFile("solution.txt", solution, scale); - - //OffsetPolygons(solution, solution, -5.0 *scale, jtRound, 4); - - //let's see the result too ... - SVGBuilder svg; - svg.style.penWidth = 0.8; - svg.style.brushClr = 0x1200009C; - svg.style.penClr = 0xCCD3D3DA; - svg.style.pft = subj_pft; - svg.AddPolygons(subject); - svg.style.brushClr = 0x129C0000; - svg.style.penClr = 0xCCFFA07A; - svg.style.pft = clip_pft; - svg.AddPolygons(clip); - svg.style.brushClr = 0x6080ff9C; - svg.style.penClr = 0xFF003300; - svg.style.pft = pftNonZero; - svg.AddPolygons(solution); - svg.SaveToFile("solution.svg", svg_scale); - } else - cout << (sClipType[clipType] + " failed!\n\n"); - - return 0; -} -//--------------------------------------------------------------------------- diff --git a/cpp/cpp_console/clipper.cbproj b/cpp/cpp_console/clipper.cbproj deleted file mode 100644 index 18a198d..0000000 --- a/cpp/cpp_console/clipper.cbproj +++ /dev/null @@ -1,147 +0,0 @@ - - - {13421A08-E1A3-411C-B53C-144521F7116E} - 12.0 - Debug - - - true - - - true - Base - true - - - true - Base - true - - - false - true - rtl.lib - rtl.lib - vcl.bpi;rtl.bpi;vclx.bpi;vclactnband.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;TeeUI.bpi;Tee.bpi;TeeDB.bpi;adortl.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;VclSmp.bpi;dbexpress.bpi;DbxCommonDriver.bpi;DataSnapIndy10ServerTransport.bpi;DataSnapProviderClient.bpi;DataSnapServer.bpi;DbxClientDriver.bpi;DBXInterBaseDriver.bpi;DBXMySQLDriver.bpi;dbxcds.bpi;DBXSybaseASEDriver.bpi;DBXSybaseASADriver.bpi;DBXOracleDriver.bpi;DBXMSSQLDriver.bpi;DBXInformixDriver.bpi;DBXDb2Driver.bpi;bcbie.bpi;xmlrtl.bpi;bcbsmp.bpi;GR32_CB6.bpi;GR32_DSGN_CB6.bpi - true - exe - CppConsoleApplication - JPHNE - NO_STRICT - true - ..\..\cpp;C:\Program Files (x86)\Borland\graphics32-1-9-0-r1336\Examples\Vcl\Drawing\Clipper\cpp\test_console;$(CG_BOOST_ROOT)\boost\tr1\tr1;$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;$(CG_BOOST_ROOT) - ..\..\cpp;C:\Program Files (x86)\Borland\graphics32-1-9-0-r1336\Examples\Vcl\Drawing\Clipper\cpp\test_console;$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk - false - true - - - false - false - true - false - true - _DEBUG;$(Defines) - false - Debug - true - None - DEBUG - true - true - true - $(BDS)\lib\debug;$(ILINK_LibraryPath) - true - Full - true - - - NDEBUG;$(Defines) - Release - $(BDS)\lib\release;$(ILINK_LibraryPath) - None - - - - 2 - - - 1 - - - 1 - - - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - - - - - CPlusPlusBuilder.Personality.12 - CppConsoleApplication - - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 3081 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - - - subj.txt clip.txt intersection NONZERO NONZERO 0 1.0 - - False - - - - - - - False - - False - - True - False - - - False - True - True - - - - 12 - - diff --git a/cpp/cpp_opengl/clipper_demo.exe b/cpp/cpp_opengl/clipper_demo.exe index 9eba464a484bee06906318147bddd7bc866ddf11..68e77dfde75a5898e62229e2245044904c528670 100644 GIT binary patch delta 94243 zcmbq+4O~>$nfD9~c$LvR>O@DGB$H&)kU|m_lQ3SBfH=b_49qaj3`Ra|YqQjnF2Y3`mMZV#^QE&*%8R_-ACyJByjb}b|J9qgy z4TjG98yXwFgfhpi_yfocx8c*0+VQt3i{`A$!ZUz0d>)_o|NFO6o-}5CX_aC4xw%He zG5RmWM#Aia-gFB}wVf#a*ew{NGsD_97Ib8ra+KB6iXsb)hS)(9>#43fVA7lOKKP&E z#gkp?W$1YGM6GGN)_~CqgagM9zohI}@f&aAc3msi)pAY>)G#Yx-3FK*OhXo2? z={I9W*R*Vb05QeJCmK!ps>eiSkD;uZ{h_LRYC!|x2)m*;_+&;$e)=8jCT187HRv>1 zt=G5a!wKyfZqJkL6X1Okvh!8oQYJF~%G_tNqK2j-RGy z%|thZ1!w1X{8##Y%HliFtiWUamun%wdPc?Lp_-}6blH&=Z zL3^HB`Gmk^D;u?HnramqDZjZ@Er!zca)4vB@ z_NI>jVpe2UJ!V#BsZmQUz3DWGkD8;p&|=H<~gth^1&84%bSvl`M=-$?whGP}hT zKixRv7lbZ}l-%>I-prZ>wY5)`FT_9QuO}L3{73TjY3UrZuzVBiQ{Bf{50ft|;`8na zHFQV~y~)sLYbR?RRjb}o-3Q~H$`@MFW38Qr#`VnoW=6McV^s%L_iL(qKXZ4E^~K&X zjGb4j-bmby*JCGRoyM_uP=*@JeNe61&#F4dPL92!y5CT%UT58`>NU0MO;)vEb$2o< zC7$U9_}^J zdZ=Er>Qw~QYpSWzj?QYSksRN>i(F?oRS1RcF+yKDFvX z{IIxpANo*)_-XO!uj6S7JTt&knp)S=6>855ppOphHf z#!e}KsE<`$5MS*!imzTbrUEVdnEOoX1dYLSV$UgA|JU$Bd`mX9r?KM%8^tZGBCZ_rD474AD99PI=Z-KDz35p`5k$ ziTjTjl~cp)06WEeC&m5!##0IQ5gUyC-l$dqBi>MbCsp~(FL-lH{Jd;_>Ns!BiwWrc zgT_-=fovI90j)fXUCFpEw#~yzvDQv$TuyU^4n{@%5%)fYhROnIJYiw2Z%M8D8ycGg z*7~NTw7%Bx73O;_!?&M}WBbqNempif|DCaO2`dnW$@|CN0TOg`BzSl1v=IpEduwj! zpt0)B`Nvh?Thj3+u_4V>^(L)QCsybnp}|a$yigw|H8Z3!`OHk;&`kLf3%$WG@2dSA z>;z$GUrf>G+WMM4%Q=|k^hK(|B7I;K_n$PL`UJ~*HTIrSZN0HHZzq>#;!{i0ilw<~ zJT;-VUS?NW)#c%H*C!@+wN3!GOH3Y#hM9Yaoy<7JLW(BemD`zn7&t%5#(|w<7u7t~ zFR1lE&KroSAForqM(h-whqIqm4eeR$5FO;t=!2tvO|=S)N8g0^znP7XoZ3DAl)BTzTF2En#z)y4HEd>~YjeXU z)gut^aG+^UgGo98Eb$1&SlDdX)w<9SEn=moGETCvAUjy88T&xA=aBj+ID@f%H7uy5 zX4X?f#G!laRIJO$uAti3N%hg#N$dgDI;GbFZ@_DHwmwdx_j_z0_#fc9IWdR_}X3^9?a<(y#Hd?#lx{H zrj||YRM#I<+C8@RmCw`C4`#(W^Vbg6zK(jeuMO6|Nfj@44b~o_X9W)@2WvYo4(o+O z_(~P~@P4wQhOg9Mbg*_vuP6VrbVYHp-mW22_KDP6HrWpZsVwc95-_rj+7*BQ}9EmHP(bddrXIm`U^%l0xn%QhsqfUWs5mM{v?wap4 zvwWM{;xrG|IR(73s3lG-o-G8gbU;2ZIRdRa4KPx|d_piBQGM6;?P@iHMY1t;)of-J zxXrA%5>@vlR$x}$BjBDC)ji4ztaL?!>bEV#in&4-?6A)&`9^Syg>1}cmqMemMLHy# zUpMOHzZ-=v*&>UsR;xVARb`{w=2CQsxkp@XYs*|kU?GbX(zf2XO;J;s(~^c(jWga% zo{3ILIVr|}fNzrTGH>O!N$$~Utt!dru%ZXPxEJnMuO#mcKJ>1Zd74jA$Cx4NM(W;2VZ7jezO!Y zi*c~g1|~?N7@x&UO;W@(d9f>kIF_=8%753V71<@PwPgv|6~Cq7Uj3`M_s?jg z%tVp+^dD)i$HixVhtC#4dPj`)QIGYO?2lAjTJ_dUbW4258CC8B_mBaKdcH9&c6$DF$ym~A6KgVOUR0|_4S!Q<|i^iz$LG#X@0{D78;Q(jk9*OV#S{8-0i-~6r0ovoIKibe(|lw ziH@_gxS0fpVJ z2T#Vz>}Q|XOZRQY+*2ujk2O8{y@3b zidRyPEJ~qqx#J6W-J)3O%4%q{^AuXA12Y~gLYrh;L z+_h)>a#+Zb8CpU#!J6%MmIs*6mg&m^+(7qlQ!PISJ0i#pz)`8pEN=$b3*}7&c9AJj z%37T)v?hzW%}lnlDhoT2?OUE1%FFJ_ta1eXtk+5 zrhAD$j2bVahSV*C=^gLz-)^JX01$H+^K}c7CkqoT%>jexaj>wndVN)QwnxY;1;Hjh zVDL%dLTP^g`+fa`LmwY3kQZFIn{F8Gm)PIbbhgzr|134pFH`LwZZ6diX&?xRot^V* zAK?Il1e)49qxZ8SffeICn%M@kbhTw3PGr|s$eMz>)4Z&+X2be!wUksK`ZM+{qj>mEF$2R*TvLfs2B``e=7_=aG@z5H{<>E(e-KA6@!)nFlnf; zd3XS)D+&Avwmn(ei&9p$B%^G(T*MY)%pyK!ab89-jTz))7LsT@{9RNX{HhQe5eBm_ zH0s0RqiewK)GmKKF`@UEkO#9->q2qnsW7mw%zx6r`guhO9sf|$%o z1s2Sb3UgX)ib;`ax>;On$ew!4qH7o@uqgt5Xs`^bR0wa!E zs^8247S-=y0hBvg0OeV1ja~KTBp#p!ctb6myhRpokwYykyn%@~0Ox}SX6AQfD;DN; zW_nGke+lzvWrNxGE@$4HOt9ttJk`6B9bx{Js&72w2>4;O-Yd@@NVDNU3{>P3M>JTw zWbn!Hi&v6g=>WvGS6*iaqK-)Wt4`pG0ke~iM8SOJWo%oCyP+%ATzOp{uF*AC%CTcC zyonuu-6)-nemT;<$!TEQ9MX1&>}K1X(srl(2-}t=ZO@V)WZQD2?K$#&%q6Xm?_%3b z(sq-a$+ij7c0r!cwwa~vW;p`@2R2D(<)0_8(TNnCC+T?9%+_pd>jcf0j?0&CsLB9s z$0HvIicdhB*NwZ~*QHZp8(n#HwSK~Z*|L$%Wd$bJ0(p_kV**1`ElBGHupQO7c_)n0 zdUMo-2ZL)NV2PNdlc-W8NCi|S!YQ-qCj`goJ?@DW2jp57a1iBL?*wz1$vjR_Dg{c$ zEU6$1Ej&5A(}Enm(>?C%u84y=c1rJ{<4BeiplXpEDUc&4JI)JD$RLz#+a?JDP`sG# z)0902SV#afiKV|W`6KdW+BDjwssETaPs#AElyeg4N&W%Y7|6>AtdvcxEAasfm?git zWtQS*YXr$FG(D2r*-aR$*Rkxo@qC8Yw@3kpe4hDDQot#{1By=|AH}^X739d>{0Q6x z0rM((1i-St3P273fbs!Yn*{(G)Ac?8hF{AE+XQvk%^iC3GCV6~*MH#M1nY5yE2Fju zVd3$pn8d;vtjp!El>b=6fmbjE*t5(W0vnDkAgWdzykaaT4(dH3Z^_a(>zfGN{A0+r>bfLLV*5Nie2V0L+F z{v3#Ai?p49Xtqk*35Wxje?HCMYhjO@x#)yTF(1>qX_Y0RU#S{c*JJOJ7^Ib#1&{QukjBYp1>Z(x)&`_AbP)`5PG zlLP$&eMtdsps(-r;LyN1s&`BB?%HnQwWexNI$n3)g1ZWg6{HZzTUqh~$(IARt91z| zRLClYmWyqq$zmZVm^sO9ljni_f){pRmqS*u?R)gH)#hqNQA)Z?hoh zLH5mwJ|cb4GDk^sxoul#{G1DCDY=KC)67v8Lh5a`b)P`0T$&f z2uR2wg_blP?F`MwX&zD)#PF$Jq}FTH zRH_=kscH1rQkO35k8)xEM*UuWq|uwJE8lYYuIUXlS7?0N04{w1*QW*$+rB_FGNh3P zVjeUQa{vMkY3ntytq5;OBA6%nuF10jFNndo*tP`4H%p~hF>X$Desdle<%!wYRF8$M zO@3`?tizmrr}EaA;ZsILzRJQb$q<&S`88W)Vhf>SUeh8x^$A9Jtm!dU1|e2}+U`M= z5h;JHDSPZ3DZBbm(J@tV!PrI8LiU3eHg8vwRkzmnq#DtE^haQ26}IpZYOfTvq{Tj& zXv){SehOkF3YVeq`ovVLbH-~Nsw0X7dPyo>X%6}QQc=q?6Ig&$L5=|4|I*2yglwgsLn6NJ9jQ+ zhq``iNCLflXT#wS*%TxWH> zeBcyu@3&y-ZpmK*is27nTu7y4mJhmAnDKu zMs&@t1H#nSz9hI2?ete*8T~c~GqN!`RECP%0>DNHSha}2RLks%=XNQr2`E<39nHH> zZ5@K}8`;#ms**EERcF{3E82*wM)F$ZM_I%w`K>Y(2sX)UlkaB{yX3dapOermm2eZ2 zD%+@n0mMUOqq=HSZ_y?!7j#`46F+5To1{ZxTRsT%E{rPQ7TZ>NT@l;vMnO!e#LbpT zPmln_HdrRHkrq%Z2?|KIr9PobuX9bAH2^#Q3> z8Isd!&9KLjO&C;NwUHiB5}>b>>({(#SjLWE9l-&_>+razYOw9RTp%eMp~aTZz&oMc z*C!on{1Pj*w1@g|+plMzWMAo;NRd1?S!nlIwELo1RF4(pH-bvc`g7HiP<*s4WgF$U zV2CQ$?*9-waL}}@lld-hQbDc_hV{gg_(pR7Q`?LUo%W*;T<8?vvQ^>-38R3=D3~Cq2%ZRL$XXDXT zBtU&wW{$q0NgohH6g9EyiGN_#o7xK2o11&gX3s@JJ{v!D`C zy-Og^t6nb2>yn>-G1V4Nc_zTYOufD=78 zArN7WspH9IPbjewa}aFoRe6QcUoDvq&9t$@zU4`gH~ zVPw=cVv@ut9T2F+&(VUNgfOk9;KEkdnpCjso;=hh@$LbZ&Pq+v3~+~KrsyJuSyzp- zYNuKX%Mp0?YG|+=>KxeqwhL;5Igtr<(S_=KU8^S~3)9sGJet`mp*Oz-5^I1jbSI$bXRkw*met`PaZ&Ja!fJ)8-m~vDxjahM#wlKdps}W zamcmoh-(`JVCLUM_J$*38?U-;qmHx6ojAB0iyLjM#w0y%5}$noeYMPDk4Y=UXI`Uz zn;p=@!14txjS2nRpiaUUwL)>Q3hb;?wW!S|4kHZ(sdrN%6($bXoM;FTVqkwQK0y=c z3#)KQi_u$!6N5!FZ}i4H!^EjSy|X!TXJS6{;sStbK|mW)EtsP=n)W8uTdVNJ(bpyZ zA=ZdS*`!-elWGqf0yZP~3tGRhtD;iAg}|7>>Njcg{>0B)TPj^nGm>;_WuDI*eVB$M z9Xlop-G&KUH3Z5j`!&ULYo32O4<~@EIKk&Os+8@1D^-)+qJ$@{*FRsNjcwDT`8xstsB`w zsbOPuDUkT1Xf}@3S4RHt2l3)ntQrBUiq#wFIC2s*0=p-yJF%UW*CVVCi`Jvv^1t-u zf{Pih9gugSU0y3_6U4g!>~X3q?|?5_4n`iu-I9A)g(MCoHvT}xXrk-9Os4?ssM>7S zHqp?YO>9mNxW10_Id+9}bv@d1Bl=M7gnOQi?J_uKLEAYw(q>~&+k&=eW`wo9JlNhU zXa?GS9bz&5ue{+VR_Y*9ZHMxosI`@qLaRhdwJ`06*!B#nX=8k_=n4#^Y&K9|G}upw zb99qhjT1XV?!<5!(d8bkS+D;LE5$W047X5e^+p=1n9eqa3ewqzny-+~c4>}OOlLco zml0fv3#^;&mxJ%p1aU2OPYpnBewO55QyRODKP_Ku9PXI)-~;%(;=v__m*_Gur(RWe zT5EbdcNls+W<&Lcn{;Am%nAgxfV=>|3j4$%t{jV&~DG6?R50aq6 z6w&hE>)8A79eRz=Pp^^jUPsr%cPl0|g=a#rclFX&&Ga08m8~*G+IPOv?tN7)S@Mcr zz)F_9A(bq7vwiiFH=Q3f)O|M<3zo=2GUsJ31tJSYh zE&>E#=6Mxxvvo_~kk%~)Tua}GE+(+GQ7|p~%bNC*rLR^Gi-1n|SeV*V{RU6=qIfZ1 z)YP6qMfA|?xq$UI^m>N$59~Kk^gGloUmO-)vOoTD^cLKQY(bzLDxF`Er`c9Z{9`#$ zqx*^K*M75q>e`QuET1NhPLoD=?Nmw((HYA+hrfwo;ID#N?P^(iw;}3o_Z`$MgOd!w zL$$jg`?mW|_PP&}*C9M~xksXVXg8#+Yky-f)MkB%3ZaALN$Ept2J4yI`Sy~$LLh00 zQG53b7y&{rxe^GfXB|sdOa1D`a2`AZkN0@i8zxTg>1#V5O%H32EQKWNDKYGUZ^R9@ zHOaLuzKDJ}*E+SLNeR5OeAT^NKvFf41pgTf}J-q6FYLJU@$B@ul)}jE!#>Qt5Rxd!?n#@ z{`U7M=MBKZL=>2Z;r{vZod&~h_n&a??~IU3bj>|L)152f7Cof4UXov)4&OI-wf<>R zkQ3Y9rQIntXO{}Oon2Q_RJRsC9Ib~gkga^0)xbqATE0t3Gsq>t2Uq{Z#D!Zeu-oYT z&)hfR>;(S?m@xiicypo|MJ1quT3v0)QI))x~Df4msXt;}N zjd>bfB_^T(Y8|+^%HBiBd>SEix222a!642|CK;JEO zMP0FGKeiGcH-QRFg{tS*!HA$u-D#)FR*0Msio z-Fg=O8Z{@PX?o2Kd9kahO^p-Ims-5}hWO!TN9+pqcqK(%klX1hst{kM9&;7`{5*f= zkKd)o&#M2u8+D*pMpIt>C3=i0UPJU~;yW<~%hOE?;qDBKx&r^cf`41^kLFGH03j54 z5WqbnF9WxiaxVH92`?MC@RGJ;8AOgq08EE}E)XM9sRk>13;7k@Tf~JJvKc9agAl=7 zY)5@!IhdB9A1!X97R8ln8MOe*WVAy)I{cvSbR@6mQyFh-+;73YxF=Zw0HH9FM>#l#x3AgD3tQH8)^~>^ zL2Zyf-N3lXEg%m+aI8fjG`Y%o&}-cP7LrzBE~~(Um5p-!q<(jSJH*9hg3*I~Gu$=` zA%No-^e-U?=?;tRh_g`TYf#-lt!-;3TS3!bHv(BHn=S(}VT;v7z_WvKw=pp6(O6aZ;UmI(|#M9|WtQsEktYNr(#3cWHr3yQyn9o4pE8w_D~RMAuz9pHxDqYc5# zfpah$mq)i&2s8wMR))@4VO~bzN_i{utj;|Q^sQ8@SF6R%YH>8N1uF6^^b}!7*;(y2 z-scJJA?h-+P7U%Kqp$*0%kM;`uu@W6>VHBOS z($(tvW(<@N;RC}8v%s75Xgg7ZsK8}VidYNgB(`VN8Vw?me{r1&w`|Yk`e^iG5 ztR3X`NfypxtDSacdb+(?U^F{NJ0ct+?Lh}7d}eTx5M(nEZWB{lUas7LWC+Ho#JPkt zy{ny0e;};g30@c?TDIP8J{SjdX_pQ(e47>xx@FL)HiD?A9>ceiEm*`N`mJy;mA?j! zv!SJyDV*CAe^#>05@3B=%{!A&c=S#{l2)Pveuw4yv3lD64CqzL9Iz^IinIc18g;vg zwjO~m&@8PrvvmNlJghxUf-CJGkik_`C$_x}Xkt4sZX+v1mw4E$=tftaBDs{L%{xFUI6yqB0K?x4dq}F%?zOBnWrv2a~8gRW`dx1zxlq}H%Uk+ahBjzRFbu7TOnLzt`0UuuT7!Hy3p*rbu6!E_ zxI3CJ4UbjaEjft$|D zMl>TgotMF|1N&aW9bakKUG!7an?Io55mZW|)9>sPg1VjL}(-Q)I zw3MjBOEX#UB0HorV@I-&WFAn|cnj6FjP-%d_pEzSeV)FfPB+@9?X>aKvWT}NE_aGk zjo0012p&&;p1!lbU9Hc6Ed2!du&edkc-qaMzGsjdcD252kn0#9kRh@H(T`UYqr3sj z6k)tKb~NJXdW3Y-Yk2jhg+mV+lgKM&YS@_8eY@yo%X5lq@@|3Vhi5e~e zZ=n{IfXPrxiM1I15r`z3qo$S*x;bp7i$Wjf9SlAf!-#Q(NNF7E{1JSH6HbD862jyiLQ6;5yVx&j(^2|; ze4%wI%!`euHZ7fS#xI2P4YAg}h8Cv+5A)rIt@hY2X%qw8`c1f-X9uw}OgRDS_T|e! zoM}1)GJTE0^!46RbP6J7;TV)rb&(YvPCV-hf`Im>aAD9b!xbtdKBC2m^&-0 zhpa}`#W?LY{Mq5#u_IrMPe3nPPs z>@Mv|tXyIv^LV8qZxl3w+K|ANdm#G&q%nxNp%=pCsMrQtho%oE&Ett2-t*^}f+K&U zvipUIAC)UmnGQm9M$#gldpa-lz3BaL+-q&rr;G`2!h{8YL35su&(EIrJ(!p)QYp4S zMHs^8kG2hH3y1O-BxNTiZ{kYf7gW#Gx<%^LNd52#w2`zJ|Jd$(Maw_JuQ2zu&GuT2 ztGV{~x?j=NT%Ed_>#g1H{aQ|N^6v7zf*AE{SoR6+HHZz=)64C?L)yoODXifd*59yM znd}Tc4Ttp3H0lhhGyFC5xX&20^W~F0h7L_B&LZfMO&HhZ8`j`oE&knxe{?&t{Q705 z!SUn;C*3zIA(}4cER417G-UADPQf70WQbibTN$zI`QVV`z70?_n0h=WV@JW>`3i}g ztwKz(8sI`(WYKn?!D7GxO*Y4N@-o<#qg3X>EofyBYP@j%u(D=&@ll9L862CgZk-8% z526?xrK?Q~T=}->T*Xyxi*{@8 zoFcvzoxpP8HtRj<902^xP|WgSE`hTIc?E!RUcL|CB5dV8m?HB9gz2|nVt)qDi!VLV zD1AYyfZMPo@C&Cn95_gqey?!_wX zY6Sv~N7V{D>z4YVmU2UXVpG@JK|j<2QjDn{gt8D-HzfWRa(Ch-xDF;>U`T2Zw5gBV z)dDyy*eI4fSqXA)Nea9wx^5mqnKlLhb6>{5Y9SmUXt0DxeH7SfbO7$Rp)-=&VM{5s zx?0Ko2Oh^gpaC9XPmyUi zjYX}oLR|*^07PHN&v4&_^!or5g1Yp3H#?Wz-*pv^3l?%*Pz3F0Df;o40TbdM1!jE_ zo(l_-uLbR2^tX@`Q`Eee$817XXc{4TcwxBfO#(J8Lj?ygxx*CtQCJDiCbHW%0R`7~ zOy94qAiMyp1jmGh3SRCmOWW*#GDTa28BNN+b8Zs)`!F%A1AKu>O=>YrMuHlIRmZFr zTA8S3s2gnR20Pcf&L*|?7><;-4m4rPq$5BBEUX(< zL7!5@0&jQZohY)x+kJ9wXo?`DIq-lcgOUk8(b)G=xMX7iVNi$DPBggLp;aC0_`C8< z*Z>jWJBP$5ghfD#g4rFyKo}-BE4-Qnwb_PfCBk1|agiOUQ)o%9Vba)lX*|Hft0Rc3 zeHYOyYn$1ssB|KlrWQoOg?d)wu;I#ShRRyq9#ywDYgr^DhgVDQ%BO26l=mj{6O7L| zu3H?roe_BTyBZwwVi#QdZ()yTN$a!Ve(`vYv_1!%>8jf3o$$q{8hKPBmo;QbTe9SA z){rA@$&v3u4Y2SBfF(BaB0^k&w@&ibgAeuRW%yS{QxKW~bsNG8Zu*Y}>M(M>^sd>6_yU*x+hINdZ(Yv<^$5&JRae!i{(9A0rxw(!Tj~;}h%CEZe^Jls z>-EZY>Xv#CdAfJ~b%|`$o9v{%URAbC)$-RRTdK{_|DtnJpVs4styYWkYr132c*gSQ zSKp+L!D>aJsh;WD(yTkm!mT_CWx`BXGYUxlkwyU%^;g!+0?qmuQPtn9dZTKA(yVTa zCe}$;l2h|EGrwMEZBz|3V;8Y`YJD_;Ad@KD)~p7iya((vdPsJMs`UT@LwK6i=4KuE zXlz?EfUi-DS62ggJOlXE$q3x3HSc);RY8dF$VR8F{T+?UG{kT;xAaPEq8vWpQ-Hm(~i#$m8{2`&f}dIz2+fRpBs3t;Dzik#4t z1}tz?f>U*Y6_G*my=t5Le^QtF;&yaYi3bR zC6c38edR{gsRh!7+CzaU>(o;tvWE0Lfh;~t)~=QZ zB`#o!&w!;eB?-k=eM2QsIE$;niJRq9Y*Cr}Y$MH-o<4;@Ahm5$-4#*CV z0v;M+vr)dcox5fE)%HqMAQ!{u$pr~shGDgR6Q0!PYw)VJ(SN zw#;`${87l*#N`IGx3Rvtrx^#`6{!{5zD5Ei_KZ7+h;d}%fnS1emlh_%+q#QO4>O^@ z>D4ZeV^nf`E^~660it}KBZ^Z;5ym$?i8Ng1CUn7C4NHIs2$QVvnP@Y-5Ow%q^SH7K zuKomYxkgrPzODxL4qfRE1=@PV^prXRV8WKc7n5;eKlfu-L#4QPE2cyC^?|t*I4Zd?f%nnOQ5w`2k43I-}?w2BJD+vp!UI- zGBH651oY4zq_wNs#T6rM{~L8+6=98aplB83_nILG$n7;~g02>Rvt@P(;SY~W2!C+# zIp*^D-UpAymMn_p%i4-Kb*M(jbS(aCb&AEW&3}86Jf%m5pTb%qIvVOy8p>mlQpNag zdMvd{#c%;^;l(yqN(1S!_83fzZ$ddqRbt!Y{E2j$emo&wRoq*I2Ozd5OZ@suJQ4uY zOe^fV_Kja9LC~FS!wMuGQZD}y!I5mo4Xeruw!=v}%pF-t1!ib3=`Xwg3tEfc19Fa4 zNRnk3CZ90rL$U2ed_o#)Sw;I>&bPP7q3>=P-`xl(99M$v{Q;`BhrV0>w(t#wq5)o? zn9x;w?(h1wr%6pXDU?0RCDG{ zA!}^Dz1H!W_+2%$yXvIYzxp%KJ9Gl@lvk?ZN`xRb)U)k%th^RpTxk&W!G!tqp}U2R z0)-G?@%eZyD=$%lCCNv{ufpi37jx@?{#c;~k>`mT&1H+prSfq&R$3vPsgK(zEb4JP zo2z29xhlq+se7kIXTw_!(Q$~bt{((8ea7Pb;6El8Z&G8c?7MNh-Rx~LU0+MV44Y|(pRocIdlW+-ZJ`z%-%a#)Z~ z#sV{;HVOg>(*~kJ&oH?YLshSKReRwX}PC0&nMIt2FPw zPU0>+ShS-M3MMf^x6^W4(+ku6OKNqrI0(%*_}!a~P0dMT)AoGiNr38|g1nZ3D)qmw zZeOhjLBsICYU`Or30F44$dO_K1`=3v(2otNN~{R2 zreL#=52kH5_5GFyQQy^WgtA#oJ%oE;{sEXMmXJIM!Tl=yi@!b4H_*qnuVyvTWu35J zS*43&+diTxWt1Joj(-mPbK+l?RBRRZl70|DdZ3iW7V+x=s=12Xg7&PQYiUOVZez-P zi)42hbOt6YD-zTwh}CfwS;c3+iUut+U1b*WnT^yoWOl(0A@2PH?W#{uX1QRV5WjvF zUt#AaTSfnGF}Exp|E_(X%(cuVRi{y}k--#8c5fb@GK0)hU z;#`UE`RINn*84_~y`cA=NKf{-pL*mAuVCe|O%61*!{x5UnFkAtQ|qBwBgqULYzDP^ zFHcOoZp{6dy^}D(ifH98)<@YDY)QNxH!V||rR&iQwJAzo;A`oAZdi?4%~LiQs4q*L z8)1aG2f9*Se+hGoSKF@OdvBX_7sjLiHqWcABnnjGtb~chpR~l(bM@0|XB}1Pfknok zL6e#^$Ece46a!2jIJcC~`l-N+}xM z3NtwZ4an)+2dkb*mq{T#gHhLIQn2m_YDL^fnHRyzw;;&~Vo;?mRw!=Mr1cggNr3XB z$gBIIx&pT7Ld3934OZlaN|PS9K)Z1yw#{achf!Qj-bw{F-DQ0;!w!>=( z!=JOzOSfjdZL<-g1v3zZc}M%vAF$BHUW9qGnc6U%|M4ZDeeErsE;M=}i1l!11D*ls z|90*tZOjT8nJ3Tv2W)3PNDn0#YH`}6t74lUsuDJlJo;4v8Cri0g5avj660?Xzk;{` zvN*qvXX2H`_>ZWRVpbfGTiTl(Abwt_R7$oif0l&AQFAElq7=5QSTlHQC5uPNIHUzo zYUveMCM!~iKUK`3it^{c_20>*X*=`RN&b4!8{GvNDFR5U7Ta?8(Deg-KxiAm;B`oI zFuva@g=u^*f}&}Be~uKsd3;_Gf#eQzC;dUwnw=oQlrbXOZ zJfGTbHiUx_Z9WDa{yWqlE>w&c(k9>~s#+st!oLgN*HnB;rAS)QCOzJh>-|ZQsB~;Eo1-;$D(0T{V8OtpyKYOPb-|4?91c4$3S@+d^IkRz?1j ztHK|x#;po}Oct^E0S4|BdzkJ4P}4P#b@xmEkM)gliR!sf#EsZk-be zf?%Mh(71K5l84oRS-a;v>cP5?bp!c`ze&<2fJfLj6mjoB{vh0$4ENMkct@k_Nreah zVq6iMehjMJsp@yc<~g>cAzuWsvZEKc1BE=5gOOGZzgZ?L7@}(1it1 z{sSKQp@1rBz9PnXWNH`XBOtMF550v`ZN6P97Gy;#G|Sudu^Z_GB5{hL z40ZrP30pTzgMfTXka-XS6|Py>Lk2 z1@ayEsRDFGepDEvMcamaL*x($_ZxWK!2O1DWhAB7Fn>o8q|k0-wqXmMk+4-Y20E_G zw`Q^8gBsy7CQ~moy=qFn2;AC^M_eQ*l8*6^B|a(Qt&Y7)0zxB z_1IDER>k-qvW8yBvl>DPU(??Lc3+ zCc;;I;NO8Xh6Dh4ChDs`D zhPjwy-93=!lp-E?sFf>F%fQAYSCCPx zY!opnKLnX3T){T_kb933?NY*BzI_FA$P>bbD$l|{{$lsUsoU+y~P!1hB+qRhNPRwtTUOokXe3?un0qY>xGYg2-Q0UdYkB& zLPo$bg=Grh1i)wF)RMEB8i4$NfrW-hV7NqQFQkzb3;AYHH#7<>7MZYM;+&)X02(VC z7EB06inL)0tmUaT6cDUw<|ioN$nYDs23d_24wa=yr34>~9P)*PHzC3tyIO98`TCu$ zHa`W=e0M(`Zow6HDz~>}yF8ABGY|x~)s`%eI9p~Y^Ib)bra8#o(v6FD9NN{c#t*so z|AuY~0EN8QYL;3d{634xw~*}`8A-(0Q?ztGJ3~s8DhCpV6e4#Ca&N9gzEcq)mp+@z zCp4zDyKUGTm}p_7HK}uu{tbyuxV%$kX%yPsj$v|mYIj?P{|TScCy28~H@u+(4HdM+ zMwrwE)Y50=sZV@1$!BRiMqO{44ndv{!BQ9MO@d&V0>Ls3gm;xkC`F0T_z)mSEJq3# zeOz9f#)X3oA6DVxp3u7!Tt3@WcLbL&i$H^@<<0^!l$vTbAUh-Krn3b|&Zy@ut%B?P z^eqGuV+AQGaG0HoupRkO86AdkYaVQNYH6L?m_KCz#s(|*X=WS+Q0LowJ@r^2@Dur} zr;Ziplg(~gW!8(ZzF2czlDq4FKPiqi*MViA_<0}N{J z20YiY1DMm**aVk8vvf{Z)F@ybzB&w9N}FU720+L8Zr+JicE%KGm_4ZAmj1i zlOsrF_-W11k?k0D4zwU1aJ#M|r}C|qd9E@?)3b>TOtFO$)EsGu6IW3O1049V53rQO zTX43fOa7d$1YmC7|1V%650l{E1;L*(Ih)mvSITE8I^iROGp=%+Svr7pazPsNklqx* zYH**hsrCGpgja*d2Cos^fn<}eryEmU1wVQ_3Wey~w!xSRNUpB+i@!O-~-?N3D2M*c1Jf^?+iH(0u{ zttTimYjnPX92}Io$Q3k4Q;|@KO5uXZKH5#L2XA3b;dbD*V&N$7fE@wul8@5ef>Wh* zw~!eyg4jleE|qkC5JW&kKsb=u182wq-;VO(mk8cgBoVesCt4oH@EngW2E z{#$@gD8IoBKWyXx%d=fUN`J6JhZfm|%h^ZTf=_`7=QOi~th_`|X(1>}hZJ%|?;#Ko z_CSeI;iW>-lR}{n5vw0Q5QEwYit`-DTw|>W&V_7NV1u+mz}JKF3zBS8@0iF-0oYL!stc|@%;2};=0)G?iaNz;y z0c|gAUN?Y7XkKzFbf7UR--^#A0ak86Oz2Y1MzIXw)in>g!A^)j3t4b(TahH_xi0Al zHbuTgEw-!cv5Pjf**=wtS}nGz>+SFnfy>BLA}dY`IA^gMgbMCfpv$s3!XAY)KUl|E z?Pg`Sie$TUVb7dPU-fVDhm;L?KC|vimR-K72EL&NZtGGjet1B|FDMjQ#JCB1GFKUh z?^WpW!B3I94cG(sB`E^xM5<}2C@Cru#r9aiRH<%d1d_NIFW|4yIFBBJXz&0Y5QQlP z(FQ*yV<44wd@(%~q8iUhQ)H8RqfWlDLrLtoBwJl@v=R9#k05yO~hrnTZLxlDv$FR-gSNcBmvnr^EK=L=XgR!r_93?ZA1 zT3NESL2sQut+h?vk@QvLtv}ruE_LV^Sww+Dt>Yx0Igw73@&wu86m$!`+4yUE0S7&L zp+w(9Wn`s<2U`eq7+E1LP>#`~RSH<;oJqArNPvS;CS~oMRxx9$V)P=&IhK(kF7nOb z*m)}T5emNr)B7$ZC=}a_Y1q@NR}TVvW8> zv;;c>$nK`P0PEI$yfUXU`Ws$3fXe6=2NV!6TCNA(Bu@KneUY6qw*Egr#M53*2gm_+E+hjEkoe3zQtsXa)a>cX zjK2<5=l7COiES?vZ9~Qu_$L;dT^`Dd2_^p`QmF)Kd7x4W((=HBOlpb&`nfAmJ~J+@^XQzg9ZrxSK#g7X3F0cPrVEB zcg6IM8euun)l@L3FbO!44ICb(Xeric*J1B*UpM|0_?4*%P!iGP1juy?OUWl7KJy*w z>c5@D|HmAF&(kO2erXaXviA6{17m@Ew_$-7L(RVcX97o6PRsL6L}!vm=I|h5^(IAQ z5anqsHQlD2kU!*b2lRq<-G^NFq5gbi8 z@zIsP#hg8wdm1sF5oofJZ9;7OJuSUyAKb!8DN8o3pHc}dzLf6jAL$vApC6XvSzt@x zjSamxW=UW}!EEOk72#L|Q#3FN_LuS?+|;~gt@T@c&I%^IN}qJ#znwC=gBze%Z$)QT zpYzegVyqXLF5t+=C;Gz|_(V}<7H(4L^Z3Yoj+7=BGs_-bg-OyJrL&6o^sQXcz=My? z)3@*#=ux&`*Qmjp@z#BGZ&~-a8sN?jWu^YM0Qwq8SeHmaq3?NY1ix}2uvH}7HrTPE zhxv-aL`*CCH$)fAP{)y{$2_)N*#{8{b{A>+K4f-YKtAvb@C>hQkc)ZDzK_k9?E9i~ zb>+_d$pZN@B{dM+J^_h{?VzVo;(0zo4yx;j5AR7j{lRe_O26aSCuo8`fWeD<(qF)r zKL^8_@5ID}f|avTn)Pv5G3?}}(N3Eb@N2K&dZWAT1>Uh3uOe!M%FtUy$OGQP75AF! z6qpv6e1IU>Xs8UJ1z3Y0rm$cNWkhXpjQ3QoumFbw+KA4r@|b|=6T5brU{!(*4p9xe zk?F8e*wwt=fStV#VdZHOR=TyT9XF@Cn8UR)iJ9!`a0&K}8>7XaAvwX%icPtvq?2NN zn6NTv(LVSt1YLwaBPk(KDcX4OEqf}B7Pb?y>tEDCA^iK&9_XK-j>op`hF@l>fN4Xt z@F2@0^7#w9wgV_=@U>BrGvKQ7DUfdbJ_}Bg4ofMAMgAhlskRw#Br5iVO+ZDB>>kVE3;uzNvz>OVBb1Z{)={ROLs_wMl zge+u=UD`=FHF=2x#66WMw3h+xJ31$ft(=FTie1en*scUZsxbWq#bgU!9U?{O8rzOW zU*?VY&p9CegbL~w0TI;hYkRz=-LM_u+Jn4;Yz)wwWBGb1`|=LV z@EW0N=rTAI07d*sml*G(GFo7LeUXU%=^vq}W<%1+cyc?I(gWWU{Bn?hoTzI|*@uFl z!dFa4ju5&AMbY2Vk7Jain3yRATABQg*S8hih2iPfD*!hOjbqni2P|FJO>oFYUFmqk zbJ+HdxxctY`C4Ggn()-fa@yX{GAO`E3j5E;hxze%9gEfwbKyoBTbEIjn1-Pa6d(7=8nK;enuSAZ-`k$397sa|ZgA0k@6XQcLrN zL-=8V4S8JPCS{neoTCzQNF3-x9G(~_*D&bq^k#g>?X#$AJ~~Y->hJ3R?S`Tm45BwZ#5I_R2Lpuf*`Mfkn;M4N19Q4AY{{i3BRR*&?^HQve3Jx zAcAgS!;%5_>lYs6H8#Kr=t7kx3G0CSmHr`ArM|zv9A*|an~W{^(Uy?Cyp|rdszt!} z4BUU&MxFr)34XOj3s9D-HhRHmW(!?cC{|HyI|%7uAk7OnXl53D-U%UDbdkA$xM zS~B`08m_6N0pNBfJ1;oKgw z4}PBEN4@%#B;KG-(mKBnb<}u0NOwE`i!5=vFZ)lMQKs@ZQSFC>N^Y&cGv*#L4iqlA zcx1rc7efGff9Hkbtc!{MBbXeOV@_0X0MiQfOPv`I z%g-0&2$Nt!VKY)cW+wbxnSfDlo|o=@HvmW8{-gM9Nlb1A)yz^u2Qj<9nA{tv$b1J? z_aWx)RNW_4#doG1UyiDwW7=s1{1S-TBDPyZZLe&Ag0$HPwm7m%`^BN}!477H#g51fZi6{SdJ z4|lA4VTV2)b#&y{-Ju}fsi%DhlKbKC_P^imnLrL1tQ9zgB;Plm%_7vC$99yYb~1Ap zGacx9&%~^GEb6kR_O_R}Eb8-}MCazJA^I^$iGPF3AkrIt2>llVGGGUuqyOZDoZjDw zUmo}x3%!;NHxX3{?Pj6nTLVtB--Sc{UG$4F+V{SM{n0LdKx=y#Yw06$Fx3A(trzZ2{E_Vg_Pl}0JYk}+1T%FN zmLQzqRvL41l9-|O08R3G>O}kMPew5(sAmmo=uI*)hTd|y-=tqNv%}bd03-OUL8M0} zWy&4^^&Wz^O!$R|jVOc5O6bjOiyGqo-0rtB;e+ym8hV9VK;7Yf6?F!md?j1?Kb(CH zTvSE(|IY3Lt1d1gtN4PTqN1Roh@yZ(fTD>lq9FN(`O=13rmR_si_e0(Ubm=gT`TQ@ zsOPb=vee|MG!PSf$uLc!K&i)iE-e|BkCKx6|DL(ai`nn@|9}4I-FxrMnYlA(&di)S z=gb+C4)sKR>~r?nQx05SwGV?-dzHR`*~DE{^5<1Lfi+qE{9DbA4Y!)>7h#2#T>iaQ zW2Es278+?<`9%y$sGvQ;)Yh6euqh)~Uzh=2ioBr!0Tb5FSkqi-K#7(jrR3_;eM6Xd3-fu><7>DUz!!|2OH?udhiN=k@;^k|GmzCTllY*C)V*_J^%H=@9_dZ{Hl%@ zj8$$y%54zcmRA-e(;fS6A(r;0QM;HhLkx~K!iAZ19O%xXudmT0>C<7($BSx`-vEQw z3EY;X_X(|gMfq=Y43`_ z_tPuh1#FF7`{DT7u04-~NUyI8ox}1ZwU&eN|tL?JNp4;D^ z3pGEyzy?910?)O=9sBwaA@{s}eVBkq_$D@uwXcq{ua6NNRL5-eo_zEkM^d55k#D3R zligA+k9(Ec(MnCnvNibEhR}u3$SU)!V~(Ddc&W4GTL!S5zI+PC*=7n>FZ2LHlM11* zhBp1s^IV(mI7oCSe*%08XA~mjUMt`JCjttHb`|ig3b;@q_OiK8Mhn71tyzE*hIAbE zve5*;{Pl@lbr|aE^u0B=>Zj`J^j$AC)~5&6wh!GnwF>XfzRFSp@GuDFeJG87CYI!I5huN6Fzsi3NxY4yjP+Q0hp%5FMMt$RXoAE1R9vknJn z)s@$tkYhnX^ukLC>g%-vE3LN!<1$Rp3gwQDvzTt zdqVe{4lf=vG+z<3p*<^{vC08TnS}1x8bC2Z%vr2Y5MQ6D(>eO%@HBr-3y%BZ=a5lV zI?ng1`w7K6T6FJF_)?W*8cVWz2l zxdN^o9HFernV6iDl5EMMW|+}cSFi0_XTWKp<#p*%G+{DqJj01%IIL_bEv)a(1Dq)> zeeVsG-LUDMKR9y+4sbyc+LWh{u@E0w*NG1COLaVLv*KC)R`CL