Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.15)

project(poly2tri LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)

include(FetchContent)
FetchContent_Declare(
gsl
GIT_REPOSITORY https://github.com/microsoft/GSL.git
GIT_TAG 1d036585ccea8a57dc5fdc84406181db3d1f3205)
FetchContent_MakeAvailable(gsl)

option(P2T_BUILD_TESTS "Build tests" OFF)
option(P2T_BUILD_TESTBED "Build the testbed application" OFF)

file(GLOB SOURCES poly2tri/common/*.cc poly2tri/sweep/*.cc)
file(GLOB HEADERS poly2tri/*.h poly2tri/common/*.h poly2tri/sweep/*.h)
add_library(poly2tri ${SOURCES} ${HEADERS})
target_include_directories(poly2tri INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(poly2tri PUBLIC GSL)

get_target_property(poly2tri_target_type poly2tri TYPE)
if(poly2tri_target_type STREQUAL SHARED_LIBRARY)
Expand Down
4 changes: 2 additions & 2 deletions poly2tri/sweep/cdt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@

namespace p2t {

CDT::CDT(const std::vector<Point*>& polyline)
CDT::CDT(gsl::span<Point> polyline)
{
sweep_context_ = new SweepContext(polyline);
sweep_ = new Sweep;
}

void CDT::AddHole(const std::vector<Point*>& polyline)
void CDT::AddHole(gsl::span<Point> polyline)
{
sweep_context_->AddHole(polyline);
}
Expand Down
6 changes: 4 additions & 2 deletions poly2tri/sweep/cdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include "sweep_context.h"
#include "sweep.h"

#include <gsl/span>

#include "../common/dll_symbol.h"

/**
Expand All @@ -54,7 +56,7 @@ class P2T_DLL_SYMBOL CDT
*
* @param polyline
*/
CDT(const std::vector<Point*>& polyline);
explicit CDT(gsl::span<Point> polyline);

/**
* Destructor - clean up memory
Expand All @@ -66,7 +68,7 @@ class P2T_DLL_SYMBOL CDT
*
* @param polyline
*/
void AddHole(const std::vector<Point*>& polyline);
void AddHole(gsl::span<Point> polyline);

/**
* Add a steiner point
Expand Down
17 changes: 10 additions & 7 deletions poly2tri/sweep/sweep_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,25 @@

namespace p2t {

SweepContext::SweepContext(std::vector<Point*> polyline) : points_(std::move(polyline)),
SweepContext::SweepContext(gsl::span<Point> polyline) :
front_(nullptr),
head_(nullptr),
tail_(nullptr),
af_head_(nullptr),
af_middle_(nullptr),
af_tail_(nullptr)
{
InitEdges(points_);
for (auto& point : polyline) {
points_.push_back(&point);
}
InitEdges(polyline);
}

void SweepContext::AddHole(const std::vector<Point*>& polyline)
void SweepContext::AddHole(gsl::span<Point> polyline)
{
InitEdges(polyline);
for (auto i : polyline) {
points_.push_back(i);
for (auto& point : polyline) {
points_.push_back(&point);
}
}

Expand Down Expand Up @@ -95,12 +98,12 @@ void SweepContext::InitTriangulation()

}

void SweepContext::InitEdges(const std::vector<Point*>& polyline)
void SweepContext::InitEdges(gsl::span<Point> polyline)
{
size_t num_points = polyline.size();
for (size_t i = 0; i < num_points; i++) {
size_t j = i < num_points - 1 ? i + 1 : 0;
edge_list.push_back(new Edge(*polyline[i], *polyline[j]));
edge_list.push_back(new Edge(polyline[i], polyline[j]));
}
}

Expand Down
8 changes: 5 additions & 3 deletions poly2tri/sweep/sweep_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

#pragma once

#include <gsl/span>

#include <list>
#include <vector>
#include <cstddef>
Expand All @@ -51,7 +53,7 @@ class SweepContext {
public:

/// Constructor
explicit SweepContext(std::vector<Point*> polyline);
explicit SweepContext(gsl::span<Point> polyline);
/// Destructor
~SweepContext();

Expand Down Expand Up @@ -82,7 +84,7 @@ Point* GetPoints();

void RemoveFromMap(Triangle* triangle);

void AddHole(const std::vector<Point*>& polyline);
void AddHole(gsl::span<Point> polyline);

void AddPoint(Point* point);

Expand Down Expand Up @@ -147,7 +149,7 @@ Point* tail_;
Node *af_head_, *af_middle_, *af_tail_;

void InitTriangulation();
void InitEdges(const std::vector<Point*>& polyline);
void InitEdges(gsl::span<Point> polyline);

};

Expand Down
90 changes: 41 additions & 49 deletions testbed/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@
using namespace std;
using namespace p2t;

bool ParseFile(string filename, vector<Point*>& out_polyline, vector<vector<Point*>>& out_holes,
vector<Point*>& out_steiner);
std::pair<Point, Point> BoundingBox(const std::vector<Point*>& polyline);
bool ParseFile(string filename, vector<Point>& out_polyline, vector<vector<Point>>& out_holes,
vector<Point>& out_steiner);
std::pair<Point, Point> BoundingBox(gsl::span<const Point> polyline);
void GenerateRandomPointDistribution(size_t num_points, double min, double max,
vector<Point*>& out_polyline,
vector<vector<Point*>>& out_holes,
vector<Point*>& out_steiner);
vector<Point>& out_polyline,
vector<vector<Point>>& out_holes,
vector<Point>& out_steiner);
void Init(int window_width, int window_height);
void ShutDown(int return_code);
void MainLoop(const double zoom);
Expand Down Expand Up @@ -89,24 +89,16 @@ vector<Triangle*> triangles;
/// Triangle map
list<Triangle*> map;
/// Polylines
vector<Point*> polyline;
vector<vector<Point*>> holes;
vector<Point*> steiner;
vector<Point> polyline;
vector<vector<Point>> holes;
vector<Point> steiner;

/// Draw the entire triangle map?
bool draw_map = false;
/// Create a random distribution of points?
bool random_distribution = false;

GLFWwindow* window = NULL;

template <class C> void FreeClear(C& cntr)
{
for (typename C::iterator it = cntr.begin(); it != cntr.end(); ++it) {
delete *it;
}
cntr.clear();
}
GLFWwindow* window = nullptr;

int main(int argc, char* argv[])
{
Expand Down Expand Up @@ -187,12 +179,12 @@ int main(int argc, char* argv[])
/*
* STEP 2: Add holes or Steiner points
*/
for (const auto& hole : holes) {
for (auto& hole : holes) {
assert(!hole.empty());
cdt->AddHole(hole);
}
for (const auto& s : steiner) {
cdt->AddPoint(s);
for (auto& s : steiner) {
cdt->AddPoint(&s);
}

/*
Expand All @@ -206,7 +198,7 @@ int main(int argc, char* argv[])
map = cdt->GetMap();
const size_t points_in_holes =
std::accumulate(holes.cbegin(), holes.cend(), size_t(0),
[](size_t cumul, const vector<Point*>& hole) { return cumul + hole.size(); });
[](size_t cumul, const vector<Point>& hole) { return cumul + hole.size(); });

cout << "Number of primary constrained edges = " << polyline.size() << endl;
cout << "Number of holes = " << holes.size() << endl;
Expand All @@ -222,26 +214,26 @@ int main(int argc, char* argv[])

// Cleanup
delete cdt;
FreeClear(polyline);
for (vector<Point*>& hole : holes) {
FreeClear(hole);
polyline.clear();
for (vector<Point>& hole : holes) {
hole.clear();
}
FreeClear(steiner);
steiner.clear();

ShutDown(0);
return 0;
}

bool ParseFile(string filename, vector<Point*>& out_polyline, vector<vector<Point*>>& out_holes,
vector<Point*>& out_steiner)
bool ParseFile(string filename, vector<Point>& out_polyline, vector<vector<Point>>& out_holes,
vector<Point>& out_steiner)
{
enum ParserState {
Polyline,
Hole,
Steiner,
};
ParserState state = Polyline;
vector<Point*>* hole = nullptr;
vector<Point>* hole = nullptr;
try {
string line;
ifstream myfile(filename);
Expand Down Expand Up @@ -272,14 +264,14 @@ bool ParseFile(string filename, vector<Point*>& out_polyline, vector<vector<Poin
double y = StringToDouble(tokens[1]);
switch (state) {
case Polyline:
out_polyline.push_back(new Point(x, y));
out_polyline.push_back(Point(x, y));
break;
case Hole:
assert(hole != nullptr);
hole->push_back(new Point(x, y));
hole->push_back(Point(x, y));
break;
case Steiner:
out_steiner.push_back(new Point(x, y));
out_steiner.push_back(Point(x, y));
break;
default:
assert(0);
Expand All @@ -296,36 +288,36 @@ bool ParseFile(string filename, vector<Point*>& out_polyline, vector<vector<Poin
return true;
}

std::pair<Point, Point> BoundingBox(const std::vector<Point*>& polyline)
std::pair<Point, Point> BoundingBox(gsl::span<const Point> polyline)
{
assert(polyline.size() > 0);
using Scalar = decltype(p2t::Point::x);
Point min(std::numeric_limits<Scalar>::max(), std::numeric_limits<Scalar>::max());
Point max(std::numeric_limits<Scalar>::min(), std::numeric_limits<Scalar>::min());
for (const Point* point : polyline) {
min.x = std::min(min.x, point->x);
min.y = std::min(min.y, point->y);
max.x = std::max(max.x, point->x);
max.y = std::max(max.y, point->y);
for (const Point& point : polyline) {
min.x = std::min(min.x, point.x);
min.y = std::min(min.y, point.y);
max.x = std::max(max.x, point.x);
max.y = std::max(max.y, point.y);
}
return std::make_pair(min, max);
}

void GenerateRandomPointDistribution(size_t num_points, double min, double max,
vector<Point*>& out_polyline,
vector<vector<Point*>>& out_holes, vector<Point*>& out_steiner)
vector<Point>& out_polyline,
vector<vector<Point>>& out_holes, vector<Point>& out_steiner)
{
out_polyline.push_back(new Point(min, min));
out_polyline.push_back(new Point(min, max));
out_polyline.push_back(new Point(max, max));
out_polyline.push_back(new Point(max, min));
out_polyline.push_back(Point(min, min));
out_polyline.push_back(Point(min, max));
out_polyline.push_back(Point(max, max));
out_polyline.push_back(Point(max, min));

max -= (1e-4);
min += (1e-4);
for (int i = 0; i < num_points; i++) {
double x = Random(Fun, min, max);
double y = Random(Fun, min, max);
out_steiner.push_back(new Point(x, y));
out_steiner.push_back(Point(x, y));
}
}

Expand Down Expand Up @@ -440,16 +432,16 @@ void Draw(const double zoom)
// green
glColor3f(0, 1, 0);

vector<vector<Point*>*> polylines;
vector<vector<Point>*> polylines;
polylines.push_back(&polyline);
for (vector<Point*>& hole : holes) {
for (vector<Point>& hole : holes) {
polylines.push_back(&hole);
}
for(int i = 0; i < polylines.size(); i++) {
const vector<Point*>& poly = *polylines[i];
const vector<Point>& poly = *polylines[i];
glBegin(GL_LINE_LOOP);
for(int j = 0; j < poly.size(); j++) {
glVertex2d(poly[j]->x, poly[j]->y);
glVertex2d(poly[j].x, poly[j].y);
}
glEnd();
}
Expand Down
Loading