You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/Clipper2Lib-/CPP/Tests/TestExportHeaders.cpp

203 lines
7.6 KiB
C++

#include <gtest/gtest.h>
#include "clipper2/clipper.h"
#include "clipper2/clipper.core.h"
#include "clipper2/clipper.export.h"
using namespace Clipper2Lib;
static bool CreatePolyPath64FromCPolyPath(CPolyPath64& v, PolyPath64& owner)
{
int64_t poly_len = *v++, child_count = *v++;
if (!poly_len) return false;
Path64 path;
path.reserve(poly_len);
for (size_t i = 0; i < poly_len; ++i)
{
int64_t x = *v++, y = *v++;
#ifdef USINGZ
z_type z = Reinterpret<z_type>(*v++);
path.push_back(Point64(x, y, z));
#else
path.push_back(Point64(x, y));
#endif
}
PolyPath64* new_owner = owner.AddChild(path);
for (size_t i = 0; i < child_count; ++i)
CreatePolyPath64FromCPolyPath(v, *new_owner);
return true;
}
static bool BuildPolyTree64FromCPolyTree(CPolyTree64 tree, PolyTree64& result)
{
result.Clear();
int64_t* v = tree;
int64_t array_len = *v++, child_count = *v++;
for (size_t i = 0; i < child_count; ++i)
if (!CreatePolyPath64FromCPolyPath(v, result)) return false;
return true;
}
static bool CreatePolyPathDFromCPolyPath(CPolyPathD& v, PolyPathD& owner)
{
size_t poly_len = static_cast<size_t>(*v++);
size_t child_count = static_cast<size_t>(*v++);
if (!poly_len) return false;
PathD path;
path.reserve(poly_len);
for (size_t i = 0; i < poly_len; ++i)
{
double x = *v++, y = *v++;
#ifdef USINGZ
z_type z = Reinterpret<z_type>(*v++);
path.push_back(PointD(x, y, z));
#else
path.push_back(PointD(x, y));
#endif
}
PolyPathD* new_owner = owner.AddChild(path);
for (size_t i = 0; i < child_count; ++i)
CreatePolyPathDFromCPolyPath(v, *new_owner);
return true;
}
static bool BuildPolyTreeDFromCPolyTree(CPolyTreeD tree, PolyTreeD& result)
{
result.Clear();
double* v = tree;
int64_t array_len = static_cast<int64_t>(*v++);
int64_t child_count = static_cast<int64_t>(*v++);
for (size_t i = 0; i < child_count; ++i)
if (!CreatePolyPathDFromCPolyPath(v, result)) return false;
return true;
}
TEST(Clipper2Tests, ExportHeader64)
{
uint8_t None = 0, Intersection = 1, Union = 2, Difference = 3, Xor = 4;
uint8_t EvenOdd = 0, NonZero = 1, Positive = 2, Negative = 3;
Paths64 subj, clip, solution;
//subj.push_back(MakeRandomPoly(600, 400, 25));
//clip.push_back(MakeRandomPoly(600, 400, 25));
for (int i = 1; i < 6; ++i)
subj.push_back(MakePath({ -i*20,-i * 20, i * 20,-i * 20, i * 20,i * 20, -i * 20,i * 20 }));
clip.push_back(MakePath({ -90,-120,90,-120, 90,120, -90,120 }));
CPaths64 c_subj_open = nullptr, c_sol = nullptr, c_sol_open = nullptr;
// Note: while CreateCPaths64 isn't exported in clipper.export.h, it can still
// be used here because we're simply statically compiling clipper.export.h.
// Normally clipper.export.h will be compiled into a DLL/so so it can be called
// by non C++ applications. If CreateCPaths64 was an exported function and it
// was called by a non C++ application, it would crash that application.
CPaths64 c_subj = CreateCPathsFromPathsT(subj);
CPaths64 c_clip = CreateCPathsFromPathsT(clip);
BooleanOp64(Intersection, EvenOdd, c_subj, c_subj_open, c_clip, c_sol, c_sol_open);
solution = ConvertCPathsToPathsT(c_sol);
//clean up !!!
delete[] c_subj;
delete[] c_clip;
DisposeArray64(c_sol);
DisposeArray64(c_sol_open);
EXPECT_EQ(solution.size(), 5);
}
TEST(Clipper2Tests, ExportHeaderD)
{
uint8_t None = 0, Intersection = 1, Union = 2, Difference = 3, Xor = 4;
uint8_t EvenOdd = 0, NonZero = 1, Positive = 2, Negative = 3;
PathsD subj, clip, solution;
//subj.push_back(MakeRandomPolyD(600, 400, 25));
//clip.push_back(MakeRandomPolyD(600, 400, 25));
for (int i = 1; i < 6; ++i)
subj.push_back(MakePathD({ -i * 20,-i * 20, i * 20,-i * 20, i * 20,i * 20, -i * 20,i * 20 }));
clip.push_back(MakePathD({ -90,-120,90,-120, 90,120, -90,120 }));
CPathsD c_subj_open = nullptr, c_sol = nullptr, c_sol_open = nullptr;
// Note: while CreateCPathsD isn't exported in clipper.export.h, it can still
// be used here because we're simply statically compiling clipper.export.h.
// Normally clipper.export.h will be compiled into a DLL/so so it can be called
// by non C++ applications. If CreateCPathsD was an exported function and it
// was called by a non C++ application, it would crash that application.
CPathsD c_subj = CreateCPathsFromPathsT(subj);
CPathsD c_clip = CreateCPathsFromPathsT(clip);
BooleanOpD(Intersection, EvenOdd, c_subj, c_subj_open, c_clip, c_sol, c_sol_open);
solution = ConvertCPathsToPathsT(c_sol);
//clean up !!!
delete[] c_subj;
delete[] c_clip;
DisposeArrayD(c_sol);
DisposeArrayD(c_sol_open);
EXPECT_EQ(solution.size(), 5);
}
TEST(Clipper2Tests, ExportHeaderTree64)
{
uint8_t None = 0, Intersection = 1, Union = 2, Difference = 3, Xor = 4;
uint8_t EvenOdd = 0, NonZero = 1, Positive = 2, Negative = 3;
Paths64 subj, clip, solution;
for (int i = 1; i < 6; ++i)
subj.push_back(MakePath({ -i * 20,-i * 20, i * 20,-i * 20, i * 20,i * 20, -i * 20,i * 20 }));
clip.push_back(MakePath({ -90,-120,90,-120, 90,120, -90,120 }));
CPaths64 c_subj_open = nullptr, c_sol = nullptr, c_sol_open = nullptr;
// Note: while CreateCPaths64 isn't exported in clipper.export.h, it can still
// be used here because we're statically compiling clipper.export.h.
// More likely, clipper.export.h will be compiled into a DLL/so so it can be
// called by non C++ applications. If CreateCPaths64 was an exported function
// and it was called by a non C++ application, it would crash that application.
CPaths64 c_subj = CreateCPathsFromPathsT(subj);
CPaths64 c_clip = CreateCPathsFromPathsT(clip);
int64_t* c_sol_tree = nullptr;
BooleanOp_PolyTree64(Intersection, EvenOdd, c_subj, c_subj_open, c_clip, c_sol_tree, c_sol_open);
PolyTree64 sol_tree;
// convert CPolyTree64 to PolyTree64
BuildPolyTree64FromCPolyTree(c_sol_tree, sol_tree);
// convert PolyTree64 to Paths64
solution = PolyTreeToPaths64(sol_tree);
//clean up !!!
delete[] c_subj;
delete[] c_clip;
DisposeArray64(c_sol_tree);
DisposeArray64(c_sol_open);
PolyPath64* pp = &sol_tree;
for (int i = 0; i < 5; ++i)
{
EXPECT_TRUE(pp->Count() == 1);
pp = pp->Child(0);
}
}
TEST(Clipper2Tests, ExportHeaderTreeD)
{
uint8_t None = 0, Intersection = 1, Union = 2, Difference = 3, Xor = 4;
uint8_t EvenOdd = 0, NonZero = 1, Positive = 2, Negative = 3;
PathsD subj, clip, solution;
for (int i = 1; i < 6; ++i)
subj.push_back(MakePathD({ -i * 20,-i * 20, i * 20,-i * 20, i * 20,i * 20, -i * 20,i * 20 }));
clip.push_back(MakePathD({ -90,-120,90,-120, 90,120, -90,120 }));
CPathsD c_subj_open = nullptr, c_sol = nullptr, c_sol_open = nullptr;
// Note: while CreateCPathsD isn't exported in clipper.export.h, it can still
// be used here because we're statically compiling clipper.export.h.
// More likely, clipper.export.h will be compiled into a DLL/so so it can be
// called by non C++ applications. If CreateCPathsD was an exported function
// and it was called by a non C++ application, it would crash that application.
CPathsD c_subj = CreateCPathsFromPathsT(subj);
CPathsD c_clip = CreateCPathsFromPathsT(clip);
static const int precision = 4;
CPolyPathD c_sol_tree = nullptr;
BooleanOp_PolyTreeD(Intersection, EvenOdd, c_subj, c_subj_open, c_clip,
c_sol_tree, c_sol_open, precision);
PolyTreeD sol_tree;
// convert CPolyTreeD to PolyTreeD
BuildPolyTreeDFromCPolyTree(c_sol_tree, sol_tree);
// convert PolyTreeD to PathsD
solution = PolyTreeToPathsD(sol_tree);
//clean up !!!
delete[] c_subj;
delete[] c_clip;
DisposeArrayD(c_sol_tree);
DisposeArrayD(c_sol_open);
PolyPathD* pp = &sol_tree;
for (int i = 0; i < 5; ++i)
{
EXPECT_TRUE(pp->Count() == 1);
pp = pp->Child(0);
}
}