Finished --cut implementation
This commit is contained in:
parent
fe1691c151
commit
4f5d9ca795
@ -132,9 +132,9 @@ if (@ARGV) { # slicing from command line
|
||||
$mesh->cut($opt{cut}, $upper, $lower);
|
||||
$upper->repair;
|
||||
$lower->repair;
|
||||
Slic3r::Format::STL->write_file("${file}_upper.stl", $upper, binary => 0)
|
||||
$upper->write_ascii("${file}_upper.stl")
|
||||
if $upper->facets_count > 0;
|
||||
Slic3r::Format::STL->write_file("${file}_lower.stl", $lower, binary => 0)
|
||||
$lower->write_ascii("${file}_lower.stl")
|
||||
if $lower->facets_count > 0;
|
||||
}
|
||||
exit;
|
||||
|
@ -3,6 +3,9 @@
|
||||
#include "Polygon.hpp"
|
||||
#include "Line.hpp"
|
||||
#include "ClipperUtils.hpp"
|
||||
#include "polypartition.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@ -188,6 +191,54 @@ ExPolygon::triangulate(Polygons* polygons) const
|
||||
polygon->triangulate_convex(polygons);
|
||||
}
|
||||
|
||||
void
|
||||
ExPolygon::triangulate2(Polygons* polygons) const
|
||||
{
|
||||
// convert polygons
|
||||
std::list<TPPLPoly> input;
|
||||
|
||||
// contour
|
||||
{
|
||||
TPPLPoly p;
|
||||
p.Init(this->contour.points.size());
|
||||
for (Points::const_iterator point = this->contour.points.begin(); point != this->contour.points.end(); ++point) {
|
||||
p[ point-this->contour.points.begin() ].x = point->x;
|
||||
p[ point-this->contour.points.begin() ].y = point->y;
|
||||
}
|
||||
p.SetHole(false);
|
||||
input.push_back(p);
|
||||
}
|
||||
|
||||
// holes
|
||||
for (Polygons::const_iterator hole = this->holes.begin(); hole != this->holes.end(); ++hole) {
|
||||
TPPLPoly p;
|
||||
p.Init(hole->points.size());
|
||||
for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) {
|
||||
p[ point-hole->points.begin() ].x = point->x;
|
||||
p[ point-hole->points.begin() ].y = point->y;
|
||||
}
|
||||
p.SetHole(true);
|
||||
input.push_back(p);
|
||||
}
|
||||
|
||||
// perform triangulation
|
||||
std::list<TPPLPoly> output;
|
||||
int res = TPPLPartition().Triangulate_MONO(&input, &output);
|
||||
if (res != 1) CONFESS("Triangulation failed");
|
||||
|
||||
// convert output polygons
|
||||
for (std::list<TPPLPoly>::iterator poly = output.begin(); poly != output.end(); ++poly) {
|
||||
long num_points = poly->GetNumPoints();
|
||||
Polygon p;
|
||||
p.points.resize(num_points);
|
||||
for (long i = 0; i < num_points; ++i) {
|
||||
p.points[i].x = (*poly)[i].x;
|
||||
p.points[i].y = (*poly)[i].y;
|
||||
}
|
||||
polygons->push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SLIC3RXS
|
||||
SV*
|
||||
ExPolygon::to_AV() {
|
||||
|
@ -30,6 +30,7 @@ class ExPolygon
|
||||
void get_trapezoids(Polygons* polygons) const;
|
||||
void get_trapezoids(Polygons* polygons, double angle) const;
|
||||
void triangulate(Polygons* polygons) const;
|
||||
void triangulate2(Polygons* polygons) const;
|
||||
|
||||
#ifdef SLIC3RXS
|
||||
void from_SV(SV* poly_sv);
|
||||
|
@ -680,6 +680,40 @@ class _area_comp {
|
||||
std::vector<double>* abs_area;
|
||||
};
|
||||
|
||||
void
|
||||
TriangleMeshSlicer::make_expolygons_simple(std::vector<IntersectionLine> &lines, ExPolygons* slices)
|
||||
{
|
||||
Polygons loops;
|
||||
this->make_loops(lines, &loops);
|
||||
|
||||
Polygons cw;
|
||||
for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++loop) {
|
||||
if (loop->area() >= 0) {
|
||||
ExPolygon ex;
|
||||
ex.contour = *loop;
|
||||
slices->push_back(ex);
|
||||
} else {
|
||||
cw.push_back(*loop);
|
||||
}
|
||||
}
|
||||
|
||||
// assign holes to contours
|
||||
for (Polygons::const_iterator loop = cw.begin(); loop != cw.end(); ++loop) {
|
||||
int slice_idx = -1;
|
||||
double current_contour_area = -1;
|
||||
for (ExPolygons::iterator slice = slices->begin(); slice != slices->end(); ++slice) {
|
||||
if (slice->contour.contains_point(loop->points.front())) {
|
||||
double area = slice->contour.area();
|
||||
if (area < current_contour_area || current_contour_area == -1) {
|
||||
slice_idx = slice - slices->begin();
|
||||
current_contour_area = area;
|
||||
}
|
||||
}
|
||||
}
|
||||
(*slices)[slice_idx].holes.push_back(*loop);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slices)
|
||||
{
|
||||
@ -852,24 +886,27 @@ TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
|
||||
if (upper != NULL) {
|
||||
// compute shape of section
|
||||
ExPolygons section;
|
||||
this->make_expolygons(upper_lines, §ion);
|
||||
this->make_expolygons_simple(upper_lines, §ion);
|
||||
|
||||
// triangulate section
|
||||
Polygons triangles;
|
||||
for (ExPolygons::const_iterator expolygon = section.begin(); expolygon != section.end(); ++expolygon)
|
||||
expolygon->triangulate(&triangles);
|
||||
expolygon->triangulate2(&triangles);
|
||||
|
||||
// convert triangles to facets and append them to mesh
|
||||
for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) {
|
||||
Polygon p = *polygon;
|
||||
p.reverse();
|
||||
stl_facet facet;
|
||||
facet.normal.x = 0;
|
||||
facet.normal.y = 0;
|
||||
facet.normal.z = -1;
|
||||
for (size_t i = 0; i <= 2; ++i) {
|
||||
facet.vertex[i].x = unscale(p.points[i].x);
|
||||
facet.vertex[i].y = unscale(p.points[i].y);
|
||||
facet.vertex[i].z = z;
|
||||
}
|
||||
//stl_add_facet(&upper->stl, &facet);
|
||||
stl_add_facet(&upper->stl, &facet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -877,29 +914,32 @@ TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
|
||||
if (lower != NULL) {
|
||||
// compute shape of section
|
||||
ExPolygons section;
|
||||
this->make_expolygons(lower_lines, §ion);
|
||||
this->make_expolygons_simple(lower_lines, §ion);
|
||||
|
||||
// triangulate section
|
||||
Polygons triangles;
|
||||
for (ExPolygons::const_iterator expolygon = section.begin(); expolygon != section.end(); ++expolygon)
|
||||
expolygon->triangulate(&triangles);
|
||||
expolygon->triangulate2(&triangles);
|
||||
|
||||
// convert triangles to facets and append them to mesh
|
||||
for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) {
|
||||
stl_facet facet;
|
||||
facet.normal.x = 0;
|
||||
facet.normal.y = 0;
|
||||
facet.normal.z = 1;
|
||||
for (size_t i = 0; i <= 2; ++i) {
|
||||
facet.vertex[i].x = unscale(polygon->points[i].x);
|
||||
facet.vertex[i].y = unscale(polygon->points[i].y);
|
||||
facet.vertex[i].z = z;
|
||||
}
|
||||
//stl_add_facet(&lower->stl, &facet);
|
||||
stl_add_facet(&lower->stl, &facet);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
stl_get_size(&(upper->stl));
|
||||
stl_get_size(&(lower->stl));
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
TriangleMeshSlicer::TriangleMeshSlicer(TriangleMesh* _mesh) : mesh(_mesh), v_scaled_shared(NULL)
|
||||
|
@ -92,6 +92,7 @@ class TriangleMeshSlicer
|
||||
stl_vertex* v_scaled_shared;
|
||||
void make_loops(std::vector<IntersectionLine> &lines, Polygons* loops);
|
||||
void make_expolygons(const Polygons &loops, ExPolygons* slices);
|
||||
void make_expolygons_simple(std::vector<IntersectionLine> &lines, ExPolygons* slices);
|
||||
void make_expolygons(std::vector<IntersectionLine> &lines, ExPolygons* slices);
|
||||
};
|
||||
|
||||
|
1561
xs/src/polypartition.cpp
Normal file
1561
xs/src/polypartition.cpp
Normal file
File diff suppressed because it is too large
Load Diff
343
xs/src/polypartition.h
Normal file
343
xs/src/polypartition.h
Normal file
@ -0,0 +1,343 @@
|
||||
//Copyright (C) 2011 by Ivan Fratric
|
||||
//
|
||||
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
//of this software and associated documentation files (the "Software"), to deal
|
||||
//in the Software without restriction, including without limitation the rights
|
||||
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
//copies of the Software, and to permit persons to whom the Software is
|
||||
//furnished to do so, subject to the following conditions:
|
||||
//
|
||||
//The above copyright notice and this permission notice shall be included in
|
||||
//all copies or substantial portions of the Software.
|
||||
//
|
||||
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
//THE SOFTWARE.
|
||||
|
||||
|
||||
#include <list>
|
||||
using namespace std;
|
||||
|
||||
typedef double tppl_float;
|
||||
|
||||
#define TPPL_CCW 1
|
||||
#define TPPL_CW -1
|
||||
|
||||
//2D point structure
|
||||
struct TPPLPoint {
|
||||
tppl_float x;
|
||||
tppl_float y;
|
||||
|
||||
TPPLPoint operator + (const TPPLPoint& p) const {
|
||||
TPPLPoint r;
|
||||
r.x = x + p.x;
|
||||
r.y = y + p.y;
|
||||
return r;
|
||||
}
|
||||
|
||||
TPPLPoint operator - (const TPPLPoint& p) const {
|
||||
TPPLPoint r;
|
||||
r.x = x - p.x;
|
||||
r.y = y - p.y;
|
||||
return r;
|
||||
}
|
||||
|
||||
TPPLPoint operator * (const tppl_float f ) const {
|
||||
TPPLPoint r;
|
||||
r.x = x*f;
|
||||
r.y = y*f;
|
||||
return r;
|
||||
}
|
||||
|
||||
TPPLPoint operator / (const tppl_float f ) const {
|
||||
TPPLPoint r;
|
||||
r.x = x/f;
|
||||
r.y = y/f;
|
||||
return r;
|
||||
}
|
||||
|
||||
bool operator==(const TPPLPoint& p) const {
|
||||
if((x == p.x)&&(y==p.y)) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool operator!=(const TPPLPoint& p) const {
|
||||
if((x == p.x)&&(y==p.y)) return false;
|
||||
else return true;
|
||||
}
|
||||
};
|
||||
|
||||
//Polygon implemented as an array of points with a 'hole' flag
|
||||
class TPPLPoly {
|
||||
protected:
|
||||
|
||||
TPPLPoint *points;
|
||||
long numpoints;
|
||||
bool hole;
|
||||
|
||||
public:
|
||||
|
||||
//constructors/destructors
|
||||
TPPLPoly();
|
||||
~TPPLPoly();
|
||||
|
||||
TPPLPoly(const TPPLPoly &src);
|
||||
TPPLPoly& operator=(const TPPLPoly &src);
|
||||
|
||||
//getters and setters
|
||||
long GetNumPoints() {
|
||||
return numpoints;
|
||||
}
|
||||
|
||||
bool IsHole() {
|
||||
return hole;
|
||||
}
|
||||
|
||||
void SetHole(bool hole) {
|
||||
this->hole = hole;
|
||||
}
|
||||
|
||||
TPPLPoint &GetPoint(long i) {
|
||||
return points[i];
|
||||
}
|
||||
|
||||
TPPLPoint *GetPoints() {
|
||||
return points;
|
||||
}
|
||||
|
||||
TPPLPoint& operator[] (int i) {
|
||||
return points[i];
|
||||
}
|
||||
|
||||
//clears the polygon points
|
||||
void Clear();
|
||||
|
||||
//inits the polygon with numpoints vertices
|
||||
void Init(long numpoints);
|
||||
|
||||
//creates a triangle with points p1,p2,p3
|
||||
void Triangle(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3);
|
||||
|
||||
//inverts the orfer of vertices
|
||||
void Invert();
|
||||
|
||||
//returns the orientation of the polygon
|
||||
//possible values:
|
||||
// TPPL_CCW : polygon vertices are in counter-clockwise order
|
||||
// TPPL_CW : polygon vertices are in clockwise order
|
||||
// 0 : the polygon has no (measurable) area
|
||||
int GetOrientation();
|
||||
|
||||
//sets the polygon orientation
|
||||
//orientation can be
|
||||
// TPPL_CCW : sets vertices in counter-clockwise order
|
||||
// TPPL_CW : sets vertices in clockwise order
|
||||
void SetOrientation(int orientation);
|
||||
};
|
||||
|
||||
class TPPLPartition {
|
||||
protected:
|
||||
struct PartitionVertex {
|
||||
bool isActive;
|
||||
bool isConvex;
|
||||
bool isEar;
|
||||
|
||||
TPPLPoint p;
|
||||
tppl_float angle;
|
||||
PartitionVertex *previous;
|
||||
PartitionVertex *next;
|
||||
};
|
||||
|
||||
struct MonotoneVertex {
|
||||
TPPLPoint p;
|
||||
long previous;
|
||||
long next;
|
||||
};
|
||||
|
||||
class VertexSorter{
|
||||
MonotoneVertex *vertices;
|
||||
public:
|
||||
VertexSorter(MonotoneVertex *v) : vertices(v) {}
|
||||
bool operator() (long index1, long index2);
|
||||
};
|
||||
|
||||
struct Diagonal {
|
||||
long index1;
|
||||
long index2;
|
||||
};
|
||||
|
||||
//dynamic programming state for minimum-weight triangulation
|
||||
struct DPState {
|
||||
bool visible;
|
||||
tppl_float weight;
|
||||
long bestvertex;
|
||||
};
|
||||
|
||||
//dynamic programming state for convex partitioning
|
||||
struct DPState2 {
|
||||
bool visible;
|
||||
long weight;
|
||||
list<Diagonal> pairs;
|
||||
};
|
||||
|
||||
//edge that intersects the scanline
|
||||
struct ScanLineEdge {
|
||||
long index;
|
||||
TPPLPoint p1;
|
||||
TPPLPoint p2;
|
||||
|
||||
//determines if the edge is to the left of another edge
|
||||
bool operator< (const ScanLineEdge & other) const;
|
||||
|
||||
bool IsConvex(const TPPLPoint& p1, const TPPLPoint& p2, const TPPLPoint& p3) const;
|
||||
};
|
||||
|
||||
//standard helper functions
|
||||
bool IsConvex(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3);
|
||||
bool IsReflex(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3);
|
||||
bool IsInside(TPPLPoint& p1, TPPLPoint& p2, TPPLPoint& p3, TPPLPoint &p);
|
||||
|
||||
bool InCone(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p);
|
||||
bool InCone(PartitionVertex *v, TPPLPoint &p);
|
||||
|
||||
int Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TPPLPoint &p22);
|
||||
|
||||
TPPLPoint Normalize(const TPPLPoint &p);
|
||||
tppl_float Distance(const TPPLPoint &p1, const TPPLPoint &p2);
|
||||
|
||||
//helper functions for Triangulate_EC
|
||||
void UpdateVertexReflexity(PartitionVertex *v);
|
||||
void UpdateVertex(PartitionVertex *v,PartitionVertex *vertices, long numvertices);
|
||||
|
||||
//helper functions for ConvexPartition_OPT
|
||||
void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates);
|
||||
void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
|
||||
void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
|
||||
|
||||
//helper functions for MonotonePartition
|
||||
bool Below(TPPLPoint &p1, TPPLPoint &p2);
|
||||
void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2);
|
||||
|
||||
//triangulates a monotone polygon, used in Triangulate_MONO
|
||||
int TriangulateMonotone(TPPLPoly *inPoly, list<TPPLPoly> *triangles);
|
||||
|
||||
public:
|
||||
|
||||
//simple heuristic procedure for removing holes from a list of polygons
|
||||
//works by creating a diagonal from the rightmost hole vertex to some visible vertex
|
||||
//time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices
|
||||
//space complexity: O(n)
|
||||
//params:
|
||||
// inpolys : a list of polygons that can contain holes
|
||||
// vertices of all non-hole polys have to be in counter-clockwise order
|
||||
// vertices of all hole polys have to be in clockwise order
|
||||
// outpolys : a list of polygons without holes
|
||||
//returns 1 on success, 0 on failure
|
||||
int RemoveHoles(list<TPPLPoly> *inpolys, list<TPPLPoly> *outpolys);
|
||||
|
||||
//triangulates a polygon by ear clipping
|
||||
//time complexity O(n^2), n is the number of vertices
|
||||
//space complexity: O(n)
|
||||
//params:
|
||||
// poly : an input polygon to be triangulated
|
||||
// vertices have to be in counter-clockwise order
|
||||
// triangles : a list of triangles (result)
|
||||
//returns 1 on success, 0 on failure
|
||||
int Triangulate_EC(TPPLPoly *poly, list<TPPLPoly> *triangles);
|
||||
|
||||
//triangulates a list of polygons that may contain holes by ear clipping algorithm
|
||||
//first calls RemoveHoles to get rid of the holes, and then Triangulate_EC for each resulting polygon
|
||||
//time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices
|
||||
//space complexity: O(n)
|
||||
//params:
|
||||
// inpolys : a list of polygons to be triangulated (can contain holes)
|
||||
// vertices of all non-hole polys have to be in counter-clockwise order
|
||||
// vertices of all hole polys have to be in clockwise order
|
||||
// triangles : a list of triangles (result)
|
||||
//returns 1 on success, 0 on failure
|
||||
int Triangulate_EC(list<TPPLPoly> *inpolys, list<TPPLPoly> *triangles);
|
||||
|
||||
//creates an optimal polygon triangulation in terms of minimal edge length
|
||||
//time complexity: O(n^3), n is the number of vertices
|
||||
//space complexity: O(n^2)
|
||||
//params:
|
||||
// poly : an input polygon to be triangulated
|
||||
// vertices have to be in counter-clockwise order
|
||||
// triangles : a list of triangles (result)
|
||||
//returns 1 on success, 0 on failure
|
||||
int Triangulate_OPT(TPPLPoly *poly, list<TPPLPoly> *triangles);
|
||||
|
||||
//triangulates a polygons by firstly partitioning it into monotone polygons
|
||||
//time complexity: O(n*log(n)), n is the number of vertices
|
||||
//space complexity: O(n)
|
||||
//params:
|
||||
// poly : an input polygon to be triangulated
|
||||
// vertices have to be in counter-clockwise order
|
||||
// triangles : a list of triangles (result)
|
||||
//returns 1 on success, 0 on failure
|
||||
int Triangulate_MONO(TPPLPoly *poly, list<TPPLPoly> *triangles);
|
||||
|
||||
//triangulates a list of polygons by firstly partitioning them into monotone polygons
|
||||
//time complexity: O(n*log(n)), n is the number of vertices
|
||||
//space complexity: O(n)
|
||||
//params:
|
||||
// inpolys : a list of polygons to be triangulated (can contain holes)
|
||||
// vertices of all non-hole polys have to be in counter-clockwise order
|
||||
// vertices of all hole polys have to be in clockwise order
|
||||
// triangles : a list of triangles (result)
|
||||
//returns 1 on success, 0 on failure
|
||||
int Triangulate_MONO(list<TPPLPoly> *inpolys, list<TPPLPoly> *triangles);
|
||||
|
||||
//creates a monotone partition of a list of polygons that can contain holes
|
||||
//time complexity: O(n*log(n)), n is the number of vertices
|
||||
//space complexity: O(n)
|
||||
//params:
|
||||
// inpolys : a list of polygons to be triangulated (can contain holes)
|
||||
// vertices of all non-hole polys have to be in counter-clockwise order
|
||||
// vertices of all hole polys have to be in clockwise order
|
||||
// monotonePolys : a list of monotone polygons (result)
|
||||
//returns 1 on success, 0 on failure
|
||||
int MonotonePartition(list<TPPLPoly> *inpolys, list<TPPLPoly> *monotonePolys);
|
||||
|
||||
//partitions a polygon into convex polygons by using Hertel-Mehlhorn algorithm
|
||||
//the algorithm gives at most four times the number of parts as the optimal algorithm
|
||||
//however, in practice it works much better than that and often gives optimal partition
|
||||
//uses triangulation obtained by ear clipping as intermediate result
|
||||
//time complexity O(n^2), n is the number of vertices
|
||||
//space complexity: O(n)
|
||||
//params:
|
||||
// poly : an input polygon to be partitioned
|
||||
// vertices have to be in counter-clockwise order
|
||||
// parts : resulting list of convex polygons
|
||||
//returns 1 on success, 0 on failure
|
||||
int ConvexPartition_HM(TPPLPoly *poly, list<TPPLPoly> *parts);
|
||||
|
||||
//partitions a list of polygons into convex parts by using Hertel-Mehlhorn algorithm
|
||||
//the algorithm gives at most four times the number of parts as the optimal algorithm
|
||||
//however, in practice it works much better than that and often gives optimal partition
|
||||
//uses triangulation obtained by ear clipping as intermediate result
|
||||
//time complexity O(n^2), n is the number of vertices
|
||||
//space complexity: O(n)
|
||||
//params:
|
||||
// inpolys : an input list of polygons to be partitioned
|
||||
// vertices of all non-hole polys have to be in counter-clockwise order
|
||||
// vertices of all hole polys have to be in clockwise order
|
||||
// parts : resulting list of convex polygons
|
||||
//returns 1 on success, 0 on failure
|
||||
int ConvexPartition_HM(list<TPPLPoly> *inpolys, list<TPPLPoly> *parts);
|
||||
|
||||
//optimal convex partitioning (in terms of number of resulting convex polygons)
|
||||
//using the Keil-Snoeyink algorithm
|
||||
//M. Keil, J. Snoeyink, "On the time bound for convex decomposition of simple polygons", 1998
|
||||
//time complexity O(n^3), n is the number of vertices
|
||||
//space complexity: O(n^3)
|
||||
// poly : an input polygon to be partitioned
|
||||
// vertices have to be in counter-clockwise order
|
||||
// parts : resulting list of convex polygons
|
||||
//returns 1 on success, 0 on failure
|
||||
int ConvexPartition_OPT(TPPLPoly *poly, list<TPPLPoly> *parts);
|
||||
};
|
@ -33,6 +33,8 @@
|
||||
%code{% THIS->get_trapezoids(&RETVAL, angle); %};
|
||||
Polygons triangulate()
|
||||
%code{% THIS->triangulate(&RETVAL); %};
|
||||
Polygons triangulate2()
|
||||
%code{% THIS->triangulate2(&RETVAL); %};
|
||||
%{
|
||||
|
||||
ExPolygon*
|
||||
|
Loading…
Reference in New Issue
Block a user