Skip to content

Commit

Permalink
Fixed open path clipping issue (#60)
Browse files Browse the repository at this point in the history
Fixed crash dereferencing a null pointer (#59)
Numerous other minor tweaks
  • Loading branch information
AngusJohnson committed May 22, 2022
1 parent d671af9 commit 51979a4
Show file tree
Hide file tree
Showing 21 changed files with 1,631 additions and 3,052 deletions.
1,288 changes: 704 additions & 584 deletions CPP/Clipper2Lib/clipper.engine.cpp

Large diffs are not rendered by default.

50 changes: 25 additions & 25 deletions CPP/Clipper2Lib/clipper.engine.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*******************************************************************************
* Author : Angus Johnson *
* Version : 10.0 (beta) - aka Clipper2 *
* Date : 18 May 2022 *
* Date : 22 May 2022 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2022 *
* Purpose : This is the main polygon clipping module *
Expand Down Expand Up @@ -55,17 +55,17 @@ namespace Clipper2Lib {

struct Vertex {
Point64 pt;
Vertex* next = NULL;
Vertex* prev = NULL;
Vertex* next = nullptr;
Vertex* prev = nullptr;
VertexFlags flags = VertexFlags::None;
};

struct OutPt {
Point64 pt;
OutPt* next = NULL;
OutPt* prev = NULL;
OutPt* next = nullptr;
OutPt* prev = nullptr;
OutRec* outrec;
Joiner* joiner = NULL;
Joiner* joiner = nullptr;

OutPt(const Point64& pt_, OutRec* outrec_): pt(pt_), outrec(outrec_) {
next = this;
Expand All @@ -86,12 +86,12 @@ namespace Clipper2Lib {
//OutRec: contains a path in the clipping solution. Edges in the AEL will
//have OutRec pointers assigned when they form part of the clipping solution.
struct OutRec {
size_t idx;
OutRec* owner;
Active* front_edge;
Active* back_edge;
OutPt* pts;
PolyPath64* polypath = NULL;
size_t idx = 0;
OutRec* owner = nullptr;
Active* front_edge = nullptr;
Active* back_edge = nullptr;
OutPt* pts = nullptr;
PolyPath64* polypath = nullptr;
OutRecState state = OutRecState::Undefined;
};

Expand All @@ -103,21 +103,21 @@ namespace Clipper2Lib {
int wind_dx = 1; //1 or -1 depending on winding diRect64on
int wind_cnt = 0;
int wind_cnt2 = 0; //winding count of the opposite polytype
OutRec* outrec = NULL;
OutRec* outrec = nullptr;
//AEL: 'active edge list' (Vatti's AET - active edge table)
// a linked list of all edges (from left to right) that are present
// (or 'active') within the current scanbeam (a horizontal 'beam' that
// sweeps from bottom to top over the paths in the clipping operation).
Active* prev_in_ael = NULL;
Active* next_in_ael = NULL;
Active* prev_in_ael = nullptr;
Active* next_in_ael = nullptr;
//SEL: 'sorted edge list' (Vatti's ST - sorted table)
// linked list used when sorting edges into their new positions at the
// top of scanbeams, but also (re)used to process horizontals.
Active* prev_in_sel = NULL;
Active* next_in_sel = NULL;
Active* jump = NULL;
Vertex* vertex_top = NULL;
LocalMinima* local_min = NULL; //the bottom of an edge 'bound' (also Vatti)
Active* prev_in_sel = nullptr;
Active* next_in_sel = nullptr;
Active* jump = nullptr;
Vertex* vertex_top = nullptr;
LocalMinima* local_min = nullptr; //the bottom of an edge 'bound' (also Vatti)
bool is_left_bound = false;
};

Expand All @@ -144,9 +144,9 @@ namespace Clipper2Lib {
bool error_found_ = false;
bool has_open_paths_ = false;
bool minima_list_sorted_ = false;
Active *actives_ = NULL;
Active *sel_ = NULL;
Joiner *horz_joiners_ = NULL;
Active *actives_ = nullptr;
Active *sel_ = nullptr;
Joiner *horz_joiners_ = nullptr;
std::vector<LocalMinima*> minima_list_;
std::vector<LocalMinima*>::iterator loc_min_iter_;
std::vector<Vertex*> vertex_lists_;
Expand Down Expand Up @@ -235,7 +235,7 @@ namespace Clipper2Lib {
bool PreserveCollinear = true;
void Clear();
#ifdef USINGZ
ClipperBase() { zfill_func_ = NULL; };
ClipperBase() { zfill_func_ = nullptr; };
void ZFillFunction(ZFillCallback zFillFunc);
#else
ClipperBase() {};
Expand Down Expand Up @@ -265,7 +265,7 @@ namespace Clipper2Lib {
explicit PolyPath(int precision = 0) //NB only for root node
{
scale_ = std::pow(10, precision);
parent_ = NULL;
parent_ = nullptr;
}

virtual ~PolyPath() { Clear(); };
Expand Down
16 changes: 10 additions & 6 deletions CPP/Examples/ConsoleDemo1/ConsoleDemo1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "../../Clipper2Lib/clipper.h"
#include "../../Utils/clipper.svg.utils.h"
#include "../../Utils/ClipFileLoad.h"
#include "../../Utils/ClipFileSave.h"
#include "../../Utils/Timer.h"

using namespace Clipper2Lib;
Expand Down Expand Up @@ -38,7 +39,7 @@ int main()
if (test_type == TestType::Simple) break;

case TestType::SavedTests:
RunSavedTests("../../../Tests/tests.txt", 1, 200, false, false);
RunSavedTests("../../../Tests/tests.txt", 1, 0xFFFF, false, false);
//or test just one of the samples in tests.txt
//DoTestsFromFile("../../Tests/tests.txt", 16, 16, true, true);
if (test_type == TestType::SavedTests) break;
Expand All @@ -58,8 +59,9 @@ int main()

std::cout << std::endl;
#ifdef _DEBUG
//std::cout << "Press any key to continue" << std::endl;
//const char c = _getch();
std::string s;
std::cout << "Press Enter to continue" << std::endl;
std::getline(std::cin, s);
#endif
return 0;
}
Expand Down Expand Up @@ -132,7 +134,9 @@ void DoSimpleTest(bool show_solution_coords)

Paths64 subject, clip;
subject.push_back(MakeStar(Point64(225, 225), 220, 9));
clip.push_back(Ellipse<int64_t>(Point64(225,225), 150, 150));
clip.push_back(Ellipse<int64_t>(Point64(225,225), 150, 150));
//SaveTest("debug.txt", false, &subject, NULL, &clip, 0, 0, ClipType::Intersection, fr);

//Intersect both shapes and then 'inflate' result -10 (ie deflate)
solution = Intersect(subject, clip, fr);
solution = InflatePaths(solution, -10, JoinType::Round, EndType::Polygon);
Expand Down Expand Up @@ -175,11 +179,11 @@ void RunSavedTests(const std::string& filename,
int64_t count2 = solution.size();
int64_t count_diff = abs(count2 - count);
if (count && count_diff > 2 && count_diff/ static_cast<double>(count) > 0.02)
std::cout << " Test " << i << " counts differ: Saved val= " <<
std::cout << " Test " << i << " path counts differ: Saved val= " <<
count << "; New val=" << count2 << std::endl;
int64_t area_diff = std::abs(area2 - area);
if (area && (area_diff > 2) && (area_diff/static_cast<double>(area)) > 0.02)
std::cout << " Test " << i << " areas differ: Saved val= " <<
std::cout << " Test " << i << " path areas differ: Saved val= " <<
area << "; New val=" << area2 << std::endl;
if (svg_draw)
{
Expand Down
1 change: 1 addition & 0 deletions CPP/Utils/ClipFileLoad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ bool LoadTestNum(ifstream &source, int test_num, bool seek_from_start,
int64_t& area, int64_t& count, ClipType &ct, FillRule &fr)
{
string line;
area = 0; count = 0;
bool found = false;
if (seek_from_start) source.seekg(0, ios_base::beg);
stringstream::pos_type last_read_line_pos = source.tellg();
Expand Down
18 changes: 13 additions & 5 deletions CPP/Utils/ClipFileSave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ void PathsToStream(Paths64& paths, std::ostream& stream)
}

bool SaveTest(const std::string& filename, bool append,
Clipper2Lib::Paths64& subj, Clipper2Lib::Paths64& subj_open, Clipper2Lib::Paths64& clip,
Clipper2Lib::Paths64* subj, Clipper2Lib::Paths64* subj_open, Clipper2Lib::Paths64* clip,
int64_t area, int64_t count, Clipper2Lib::ClipType ct, Clipper2Lib::FillRule fr)
{
string line;
Expand Down Expand Up @@ -280,12 +280,20 @@ bool SaveTest(const std::string& filename, bool append,
source << "FILLRULE: " << fillrule_string << endl;
source << "SOL_AREA: " << area << endl;
source << "SOL_COUNT: " << count << endl;
source << "SUBJECTS" << endl;
PathsToStream(subj, source);
if (clip.size())
if (subj)
{
source << "SUBJECTS" << endl;
PathsToStream(*subj, source);
}
if (subj_open)
{
source << "SUBJECTS_OPEN" << endl;
PathsToStream(*subj_open, source);
}
if (clip && clip->size())
{
source << "CLIPS" << endl;
PathsToStream(clip, source);
PathsToStream(*clip, source);
}
source << endl;
source.close();
Expand Down
2 changes: 1 addition & 1 deletion CPP/Utils/ClipFileSave.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "../Clipper2Lib/clipper.h"

bool SaveTest(const std::string& filename, bool append,
Clipper2Lib::Paths64& subj, Clipper2Lib::Paths64& subj_open, Clipper2Lib::Paths64& clip,
Clipper2Lib::Paths64* subj, Clipper2Lib::Paths64* subj_open, Clipper2Lib::Paths64* clip,
int64_t area, int64_t count, Clipper2Lib::ClipType ct, Clipper2Lib::FillRule fr);

#endif //CLIPPER_TEST_SAVE_H
14 changes: 13 additions & 1 deletion CSharp/Clipper2Lib.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleDemo", "Clipper2LibExamples\ConsoleDemo\ConsoleDemo.csproj", "{9D72A42C-E1B0-4E7A-B3B4-62C0AA02E5A7}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleDemo", "Clipper2LibExamples\ConsoleDemo\ConsoleDemo.csproj", "{9D72A42C-E1B0-4E7A-B3B4-62C0AA02E5A7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Clipper2.SVG", "Utils\SVG\Clipper2.SVG.csproj", "{BC8E75BA-24E1-4D6A-AE54-0B1019C18EFE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Clipper.FileIO.", "Utils\ClipFileIO\Clipper.FileIO..csproj", "{2EF8FB02-E3F6-46CE-954F-5E1B0AD64DB7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -32,6 +36,14 @@ Global
{9D72A42C-E1B0-4E7A-B3B4-62C0AA02E5A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D72A42C-E1B0-4E7A-B3B4-62C0AA02E5A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D72A42C-E1B0-4E7A-B3B4-62C0AA02E5A7}.Release|Any CPU.Build.0 = Release|Any CPU
{BC8E75BA-24E1-4D6A-AE54-0B1019C18EFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC8E75BA-24E1-4D6A-AE54-0B1019C18EFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC8E75BA-24E1-4D6A-AE54-0B1019C18EFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC8E75BA-24E1-4D6A-AE54-0B1019C18EFE}.Release|Any CPU.Build.0 = Release|Any CPU
{2EF8FB02-E3F6-46CE-954F-5E1B0AD64DB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2EF8FB02-E3F6-46CE-954F-5E1B0AD64DB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2EF8FB02-E3F6-46CE-954F-5E1B0AD64DB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2EF8FB02-E3F6-46CE-954F-5E1B0AD64DB7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading

0 comments on commit 51979a4

Please sign in to comment.