Skip to content

Commit

Permalink
Fixed bug affecting open paths and REVERSE_ORIENTATION
Browse files Browse the repository at this point in the history
Other minor tweaks
  • Loading branch information
AngusJohnson committed May 5, 2022
1 parent 04c591e commit 8e8925b
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 147 deletions.
94 changes: 41 additions & 53 deletions CPP/Clipper2Lib/clipper.engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3163,76 +3163,64 @@ namespace Clipper2Lib {

bool BuildPath(OutPt& op, bool isOpen, Path64& path)
{
try
{
int cnt = PointCount(&op);
if (cnt < 2) return false;
path.resize(0);
path.reserve(cnt);
Point64 lastPt = op.pt;
path.push_back(lastPt);
{
int cnt = PointCount(&op);
if (cnt < 2) return false;
path.resize(0);
path.reserve(cnt);
#ifdef REVERSE_ORIENTATION
OutPt* op2 = op.next;
op = op.next;
Point64 lastPt = op.pt;
path.push_back(lastPt);
OutPt* op2 = op.next;
#else
OutPt* op2 = op.prev;
Point64 lastPt = op.pt;
path.push_back(lastPt);
OutPt* op2 = op.prev;
#endif
while (op2 != &op)
{
if (op2->pt != lastPt)
{
lastPt = op2->pt;
path.push_back(lastPt);
}
while (op2 != &op)
{
if (op2->pt != lastPt)
{
lastPt = op2->pt;
path.push_back(lastPt);
}
#ifdef REVERSE_ORIENTATION
op2 = op2->next;
op2 = op2->next;
#else
op2 = op2->prev;
op2 = op2->prev;
#endif
}
}
}
catch (...)
{
return false;
}

return true;
return true;
}
//------------------------------------------------------------------------------

bool ClipperBase::BuildPaths(Paths64& solutionClosed, Paths64* solutionOpen)
void ClipperBase::BuildPaths(Paths64& solutionClosed, Paths64* solutionOpen)
{
try
solutionClosed.resize(0);
//solutionClosed.reserve(outrec_list_.size());
if (solutionOpen)
{
solutionOpen->resize(0);
solutionOpen->reserve(outrec_list_.size());
}
for(OutRec* outrec : outrec_list_)
{
solutionClosed.resize(0);
//solutionClosed.reserve(outrec_list_.size());
if (solutionOpen)
if (outrec->pts == NULL) continue;
Path64 path;
if (solutionOpen && outrec->state == OutRecState::Open)
{
solutionOpen->resize(0);
solutionOpen->reserve(outrec_list_.size());
if (BuildPath(*outrec->pts, true, path))
solutionOpen->emplace_back(std::move(path));
path.resize(0);
}
for(OutRec* outrec : outrec_list_)
else
{
if (outrec->pts == NULL) continue;
Path64 path;
if (solutionOpen && outrec->state == OutRecState::Open)
{
if (BuildPath(*outrec->pts, true, path))
solutionOpen->emplace_back(std::move(path));
path.resize(0);
}
else
{
if (BuildPath(*outrec->pts, false, path))
solutionClosed.emplace_back(std::move(path));
path.resize(0);
}

if (BuildPath(*outrec->pts, false, path))
solutionClosed.emplace_back(std::move(path));
path.resize(0);
}

}
catch(...) { return false; }
return true;
}
//------------------------------------------------------------------------------

Expand Down
6 changes: 3 additions & 3 deletions CPP/Clipper2Lib/clipper.engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ namespace Clipper2Lib {
void DeleteJoin(Joiner* joiner);
void ProcessJoinerList();
OutRec* ProcessJoin(Joiner* joiner);
virtual bool ExecuteInternal(ClipType ct, FillRule ft);
void BuildPaths(Paths64& solutionClosed, Paths64* solutionOpen);
void BuildTree(PolyPath64& polytree, Paths64& open_paths);
#ifdef USINGZ
ZFillCallback zfill_func_; //custom callback
void SetZ(const Active& e1, const Active& e2, Point64& pt);
Expand All @@ -220,9 +223,6 @@ namespace Clipper2Lib {
void CleanUp(); //unlike Clear, CleanUp preserves added paths
void AddPath(const Path64& path, PathType polytype, bool is_open);
void AddPaths(const Paths64& paths, PathType polytype, bool is_open);
virtual bool ExecuteInternal(ClipType ct, FillRule ft);
bool BuildPaths(Paths64& solutionClosed, Paths64* solutionOpen);
void BuildTree(PolyPath64& polytree, Paths64& open_paths);

virtual bool Execute(ClipType clip_type,
FillRule fill_rule, Paths64& solution_closed);
Expand Down
2 changes: 2 additions & 0 deletions CPP/Clipper2Lib/clipper.offset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ void ClipperOffset::DoGroupOffset(PathGroup& group, double delta)
{
//clean up self-intersections ...
ClipperD c(0);
c.PreserveCollinear = false;
c.AddSubject(group.paths_out_);
if (group.is_reversed)
c.Execute(ClipType::Union, FillRule::Negative, group.paths_out_);
Expand Down Expand Up @@ -389,6 +390,7 @@ PathsD ClipperOffset::Execute(double delta)
{
//clean up self-intersections ...
ClipperD c(0);
c.PreserveCollinear = false;
c.AddSubject(result);
if (groups_[0].is_reversed)
c.Execute(ClipType::Union, FillRule::Negative, result);
Expand Down
5 changes: 4 additions & 1 deletion CSharp/Clipper2Lib/Clipper.Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3272,11 +3272,14 @@ internal bool BuildPath(OutPt op, bool isOpen, Path64 path)
int cnt = PointCount(op);
if (cnt < 2) return false;
path.Clear();
#if REVERSE_ORIENTATION
op = op.next;
Point64 lastPt = op.pt;
path.Add(lastPt);
#if REVERSE_ORIENTATION
op = op.next;
#else
Point64 lastPt = op.pt;
path.Add(lastPt);
op = op.prev;
#endif
for (int i = 1; i < cnt; i++)
Expand Down
2 changes: 2 additions & 0 deletions CSharp/Clipper2Lib/Clipper.Offset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ public PathsD Execute(double delta)
{
//clean up self-intersections ...
ClipperD c = new ClipperD(RoundingDecimalPrecision);
c.PreserveCollinear = false;
c.AddSubject(solution);
if (_pathGroups[0]._pathsReversed)
c.Execute(ClipType.Union, FillRule.Negative, solution);
Expand Down Expand Up @@ -464,6 +465,7 @@ private void DoGroupOffset(PathGroup group, double delta)
{
//clean up self-intersections ...
ClipperD c = new ClipperD(RoundingDecimalPrecision);
c.PreserveCollinear = false;
c.AddSubject(group._outPaths);
if (group._pathsReversed)
c.Execute(ClipType.Union, FillRule.Negative, group._outPaths);
Expand Down
16 changes: 11 additions & 5 deletions CSharp/Clipper2LibExample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using System;
using System.IO;
using System.Collections.Generic;
using Clipper2Lib;

namespace Clipper2LibExample
{

using Path64 = List<Point64>;
using Paths64 = List<List<Point64>>;
using PathD = List<PointD>;
using PathsD = List<List<PointD>>;

internal class Program
{
Expand All @@ -30,6 +29,14 @@ internal static PathD Ellipse(RectD rec)
return result;
}

internal static void OpenFile(string filename)
{
string path = Path.GetFullPath(filename);
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new System.Diagnostics.ProcessStartInfo(path) { UseShellExecute = true };
p.Start();
}

internal static void MakeSvg(string caption, string filename,
Paths64 subj, Paths64 openSubj, Paths64 clip,
Paths64 solution, FillRule fill, bool hideSolutionCoords = false)
Expand All @@ -45,6 +52,8 @@ internal static void MakeSvg(string caption, string filename,
if (solution != null)
svg.AddPaths(solution, false, 0x4000FF00, 0x80000000, 1.2, !hideSolutionCoords);
svg.SaveToFile(filename, 800, 600);

OpenFile(filename);
}

public static void Main()
Expand Down Expand Up @@ -97,10 +106,7 @@ public static void Main()
MakeSvg("Sample 9 - inflate:10; end:joined", "../../../solution9.svg",
null, subj, null, solution9, FillRule.EvenOdd);

//PathD pattern = ClipperFunc.MakePath(new double[] { -7,0, 0,-10, 7,0, 0,10 }); //diamond
//PathD pattern = ClipperFunc.MakePath(new double[] { -10,-5, 10,-5, 10,5, -10,5 }); //rectangle
PathD pattern = Ellipse(new RectD(-10, -10, 10, 10)); //circle

PathD path = ClipperFunc.MakePath(new double[] { 0, 0, 100, 200, 200, 0 });
Paths64 solution10 = ClipperFunc.Paths64(Minkowski.Sum(pattern, path, true));
MakeSvg("Sample 10 - Minkowski.Sum", "../../../solution10.svg",
Expand Down
Loading

0 comments on commit 8e8925b

Please sign in to comment.