Turn ExtrusionLoop into a collection of polylines. Includes some changes to the Polygon API to avoid returning newly allocatd objects
This commit is contained in:
parent
c72dc13d7e
commit
d2d885fc53
@ -157,56 +157,85 @@ ExtrusionPath::gcode(Extruder* extruder, double e, double F,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ExtrusionLoop::ExtrusionLoop(const Polygon &polygon, ExtrusionRole role)
|
||||||
|
{
|
||||||
|
this->role = role;
|
||||||
|
this->set_polygon(polygon);
|
||||||
|
}
|
||||||
|
|
||||||
ExtrusionLoop*
|
ExtrusionLoop*
|
||||||
ExtrusionLoop::clone() const
|
ExtrusionLoop::clone() const
|
||||||
{
|
{
|
||||||
return new ExtrusionLoop (*this);
|
return new ExtrusionLoop (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtrusionPath*
|
void
|
||||||
ExtrusionLoop::split_at_index(int index) const
|
ExtrusionLoop::split_at_index(int index, ExtrusionPath* path) const
|
||||||
{
|
{
|
||||||
Polyline* poly = this->polygon.split_at_index(index);
|
Polygon polygon;
|
||||||
|
this->polygon(&polygon);
|
||||||
|
|
||||||
|
polygon.split_at_index(index, &path->polyline);
|
||||||
|
|
||||||
ExtrusionPath* path = new ExtrusionPath();
|
|
||||||
path->polyline = *poly;
|
|
||||||
path->role = this->role;
|
path->role = this->role;
|
||||||
path->mm3_per_mm = this->mm3_per_mm;
|
path->mm3_per_mm = this->mm3_per_mm;
|
||||||
path->width = this->width;
|
path->width = this->width;
|
||||||
path->height = this->height;
|
path->height = this->height;
|
||||||
|
|
||||||
delete poly;
|
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtrusionPath*
|
void
|
||||||
ExtrusionLoop::split_at_first_point() const
|
ExtrusionLoop::split_at_first_point(ExtrusionPath* path) const
|
||||||
{
|
{
|
||||||
return this->split_at_index(0);
|
return this->split_at_index(0, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ExtrusionLoop::make_counter_clockwise()
|
ExtrusionLoop::make_counter_clockwise()
|
||||||
{
|
{
|
||||||
return this->polygon.make_counter_clockwise();
|
Polygon polygon;
|
||||||
|
this->polygon(&polygon);
|
||||||
|
|
||||||
|
bool was_cw = polygon.is_clockwise();
|
||||||
|
if (was_cw) this->reverse();
|
||||||
|
return was_cw;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExtrusionLoop::reverse()
|
ExtrusionLoop::reverse()
|
||||||
{
|
{
|
||||||
// no-op
|
for (Polylines::iterator polyline = this->polylines.begin(); polyline != this->polylines.end(); ++polyline)
|
||||||
|
polyline->reverse();
|
||||||
|
std::reverse(this->polylines.begin(), this->polylines.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
Point
|
Point
|
||||||
ExtrusionLoop::first_point() const
|
ExtrusionLoop::first_point() const
|
||||||
{
|
{
|
||||||
return this->polygon.points.front();
|
return this->polylines.front().points.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
Point
|
Point
|
||||||
ExtrusionLoop::last_point() const
|
ExtrusionLoop::last_point() const
|
||||||
{
|
{
|
||||||
return this->polygon.points.front(); // in polygons, first == last
|
return this->polylines.back().points.back(); // which coincides with first_point(), by the way
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExtrusionLoop::set_polygon(const Polygon &polygon)
|
||||||
|
{
|
||||||
|
Polyline polyline;
|
||||||
|
polygon.split_at_first_point(&polyline);
|
||||||
|
this->polylines.clear();
|
||||||
|
this->polylines.push_back(polyline);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExtrusionLoop::polygon(Polygon* polygon) const
|
||||||
|
{
|
||||||
|
for (Polylines::const_iterator polyline = this->polylines.begin(); polyline != this->polylines.end(); ++polyline) {
|
||||||
|
// for each polyline, append all points except the last one (because it coincides with the first one of the next polyline)
|
||||||
|
polygon->points.insert(polygon->points.end(), polyline->points.begin(), polyline->points.end()-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
|
@ -73,14 +73,18 @@ class ExtrusionPath : public ExtrusionEntity
|
|||||||
class ExtrusionLoop : public ExtrusionEntity
|
class ExtrusionLoop : public ExtrusionEntity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Polylines polylines;
|
||||||
|
|
||||||
|
ExtrusionLoop(const Polygon &polygon, ExtrusionRole role);
|
||||||
ExtrusionLoop* clone() const;
|
ExtrusionLoop* clone() const;
|
||||||
Polygon polygon;
|
void split_at_index(int index, ExtrusionPath* path) const;
|
||||||
ExtrusionPath* split_at_index(int index) const;
|
void split_at_first_point(ExtrusionPath* path) const;
|
||||||
ExtrusionPath* split_at_first_point() const;
|
|
||||||
bool make_counter_clockwise();
|
bool make_counter_clockwise();
|
||||||
void reverse();
|
void reverse();
|
||||||
Point first_point() const;
|
Point first_point() const;
|
||||||
Point last_point() const;
|
Point last_point() const;
|
||||||
|
void set_polygon(const Polygon &polygon);
|
||||||
|
void polygon(Polygon* polygon) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -51,43 +51,41 @@ Polygon::lines(Lines* lines) const
|
|||||||
lines->push_back(Line(this->points.back(), this->points.front()));
|
lines->push_back(Line(this->points.back(), this->points.front()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Polyline*
|
void
|
||||||
Polygon::split_at(const Point &point) const
|
Polygon::split_at(const Point &point, Polyline* polyline) const
|
||||||
{
|
{
|
||||||
// find index of point
|
// find index of point
|
||||||
for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) {
|
for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) {
|
||||||
if (it->coincides_with(point))
|
if (it->coincides_with(point)) {
|
||||||
return this->split_at_index(it - this->points.begin());
|
this->split_at_index(it - this->points.begin(), polyline);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CONFESS("Point not found");
|
CONFESS("Point not found");
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Polyline*
|
void
|
||||||
Polygon::split_at_index(int index) const
|
Polygon::split_at_index(int index, Polyline* polyline) const
|
||||||
{
|
{
|
||||||
Polyline* poly = new Polyline;
|
polyline->points.reserve(this->points.size() + 1);
|
||||||
poly->points.reserve(this->points.size() + 1);
|
|
||||||
for (Points::const_iterator it = this->points.begin() + index; it != this->points.end(); ++it)
|
for (Points::const_iterator it = this->points.begin() + index; it != this->points.end(); ++it)
|
||||||
poly->points.push_back(*it);
|
polyline->points.push_back(*it);
|
||||||
for (Points::const_iterator it = this->points.begin(); it != this->points.begin() + index + 1; ++it)
|
for (Points::const_iterator it = this->points.begin(); it != this->points.begin() + index + 1; ++it)
|
||||||
poly->points.push_back(*it);
|
polyline->points.push_back(*it);
|
||||||
return poly;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Polyline*
|
void
|
||||||
Polygon::split_at_first_point() const
|
Polygon::split_at_first_point(Polyline* polyline) const
|
||||||
{
|
{
|
||||||
return this->split_at_index(0);
|
this->split_at_index(0, polyline);
|
||||||
}
|
}
|
||||||
|
|
||||||
Points
|
void
|
||||||
Polygon::equally_spaced_points(double distance) const
|
Polygon::equally_spaced_points(double distance, Points* points) const
|
||||||
{
|
{
|
||||||
Polyline* polyline = this->split_at_first_point();
|
Polyline polyline;
|
||||||
Points pts = polyline->equally_spaced_points(distance);
|
this->split_at_first_point(&polyline);
|
||||||
delete polyline;
|
polyline.equally_spaced_points(distance, points);
|
||||||
return pts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
|
@ -20,10 +20,10 @@ class Polygon : public MultiPoint {
|
|||||||
Point last_point() const;
|
Point last_point() const;
|
||||||
Lines lines() const;
|
Lines lines() const;
|
||||||
void lines(Lines* lines) const;
|
void lines(Lines* lines) const;
|
||||||
Polyline* split_at(const Point &point) const;
|
void split_at(const Point &point, Polyline* polyline) const;
|
||||||
Polyline* split_at_index(int index) const;
|
void split_at_index(int index, Polyline* polyline) const;
|
||||||
Polyline* split_at_first_point() const;
|
void split_at_first_point(Polyline* polyline) const;
|
||||||
Points equally_spaced_points(double distance) const;
|
void equally_spaced_points(double distance, Points* points) const;
|
||||||
double area() const;
|
double area() const;
|
||||||
bool is_counter_clockwise() const;
|
bool is_counter_clockwise() const;
|
||||||
bool is_clockwise() const;
|
bool is_clockwise() const;
|
||||||
|
@ -89,11 +89,10 @@ Polyline::extend_start(double distance)
|
|||||||
|
|
||||||
/* this method returns a collection of points picked on the polygon contour
|
/* this method returns a collection of points picked on the polygon contour
|
||||||
so that they are evenly spaced according to the input distance */
|
so that they are evenly spaced according to the input distance */
|
||||||
Points
|
void
|
||||||
Polyline::equally_spaced_points(double distance) const
|
Polyline::equally_spaced_points(double distance, Points* points) const
|
||||||
{
|
{
|
||||||
Points pts;
|
points->push_back(this->first_point());
|
||||||
pts.push_back(this->first_point());
|
|
||||||
double len = 0;
|
double len = 0;
|
||||||
|
|
||||||
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
|
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
|
||||||
@ -102,19 +101,17 @@ Polyline::equally_spaced_points(double distance) const
|
|||||||
if (len < distance) continue;
|
if (len < distance) continue;
|
||||||
|
|
||||||
if (len == distance) {
|
if (len == distance) {
|
||||||
pts.push_back(*it);
|
points->push_back(*it);
|
||||||
len = 0;
|
len = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
double take = segment_length - (len - distance); // how much we take of this segment
|
double take = segment_length - (len - distance); // how much we take of this segment
|
||||||
Line segment(*(it-1), *it);
|
Line segment(*(it-1), *it);
|
||||||
pts.push_back(segment.point_at(take));
|
points->push_back(segment.point_at(take));
|
||||||
it--;
|
it--;
|
||||||
len = -take;
|
len = -take;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -19,7 +19,7 @@ class Polyline : public MultiPoint {
|
|||||||
void clip_start(double distance);
|
void clip_start(double distance);
|
||||||
void extend_end(double distance);
|
void extend_end(double distance);
|
||||||
void extend_start(double distance);
|
void extend_start(double distance);
|
||||||
Points equally_spaced_points(double distance) const;
|
void equally_spaced_points(double distance, Points* points) const;
|
||||||
void simplify(double tolerance);
|
void simplify(double tolerance);
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
|
@ -33,7 +33,7 @@ template <class T>
|
|||||||
class Clone {
|
class Clone {
|
||||||
T* val;
|
T* val;
|
||||||
public:
|
public:
|
||||||
Clone() {}
|
Clone() : val() {}
|
||||||
Clone(T* t) : val(new T(*t)) {}
|
Clone(T* t) : val(new T(*t)) {}
|
||||||
Clone(const T& t) : val(new T(t)) {}
|
Clone(const T& t) : val(new T(t)) {}
|
||||||
operator T*() const {return val; }
|
operator T*() const {return val; }
|
||||||
|
@ -4,7 +4,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Slic3r::XS;
|
use Slic3r::XS;
|
||||||
use Test::More tests => 7;
|
use Test::More tests => 8;
|
||||||
|
|
||||||
my $square = [
|
my $square = [
|
||||||
[100, 100],
|
[100, 100],
|
||||||
@ -18,7 +18,8 @@ my $loop = Slic3r::ExtrusionLoop->new(
|
|||||||
role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
|
role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||||
mm3_per_mm => 1,
|
mm3_per_mm => 1,
|
||||||
);
|
);
|
||||||
isa_ok $loop->polygon, 'Slic3r::Polygon::Ref', 'loop polygon';
|
isa_ok $loop, 'Slic3r::ExtrusionLoop';
|
||||||
|
isa_ok $loop->polygon, 'Slic3r::Polygon', 'loop polygon';
|
||||||
is_deeply $loop->polygon->pp, $square, 'polygon points roundtrip';
|
is_deeply $loop->polygon->pp, $square, 'polygon points roundtrip';
|
||||||
|
|
||||||
$loop = $loop->clone;
|
$loop = $loop->clone;
|
||||||
|
@ -9,13 +9,14 @@
|
|||||||
%name{Slic3r::ExtrusionLoop} class ExtrusionLoop {
|
%name{Slic3r::ExtrusionLoop} class ExtrusionLoop {
|
||||||
~ExtrusionLoop();
|
~ExtrusionLoop();
|
||||||
SV* arrayref()
|
SV* arrayref()
|
||||||
%code{% RETVAL = THIS->polygon.to_AV(); %};
|
%code{% Polygon polygon; THIS->polygon(&polygon); RETVAL = polygon.to_AV(); %};
|
||||||
SV* pp()
|
SV* pp()
|
||||||
%code{% RETVAL = THIS->polygon.to_SV_pureperl(); %};
|
%code{% Polygon polygon; THIS->polygon(&polygon); RETVAL = polygon.to_SV_pureperl(); %};
|
||||||
void reverse()
|
void reverse();
|
||||||
%code{% THIS->polygon.reverse(); %};
|
ExtrusionPath* split_at_index(int index)
|
||||||
ExtrusionPath* split_at_index(int index);
|
%code{% RETVAL = new ExtrusionPath (); THIS->split_at_index(index, RETVAL); %};
|
||||||
ExtrusionPath* split_at_first_point();
|
ExtrusionPath* split_at_first_point()
|
||||||
|
%code{% RETVAL = new ExtrusionPath (); THIS->split_at_first_point(RETVAL); %};
|
||||||
bool make_counter_clockwise();
|
bool make_counter_clockwise();
|
||||||
Clone<Point> first_point();
|
Clone<Point> first_point();
|
||||||
Clone<Point> last_point();
|
Clone<Point> last_point();
|
||||||
@ -33,22 +34,25 @@ _new(CLASS, polygon_sv, role, mm3_per_mm, width, height)
|
|||||||
float width;
|
float width;
|
||||||
float height;
|
float height;
|
||||||
CODE:
|
CODE:
|
||||||
RETVAL = new ExtrusionLoop ();
|
Polygon polygon;
|
||||||
RETVAL->polygon.from_SV_check(polygon_sv);
|
polygon.from_SV_check(polygon_sv);
|
||||||
RETVAL->role = role;
|
RETVAL = new ExtrusionLoop (polygon, role);
|
||||||
RETVAL->mm3_per_mm = mm3_per_mm;
|
RETVAL->mm3_per_mm = mm3_per_mm;
|
||||||
RETVAL->width = width;
|
RETVAL->width = width;
|
||||||
RETVAL->height = height;
|
RETVAL->height = height;
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
Ref<Polygon>
|
Polygon*
|
||||||
ExtrusionLoop::polygon(...)
|
ExtrusionLoop::polygon(...)
|
||||||
CODE:
|
CODE:
|
||||||
if (items > 1) {
|
if (items > 1) {
|
||||||
THIS->polygon.from_SV_check( ST(1) );
|
Polygon polygon;
|
||||||
|
polygon.from_SV_check( ST(1) );
|
||||||
|
THIS->set_polygon(polygon);
|
||||||
}
|
}
|
||||||
RETVAL = &(THIS->polygon);
|
RETVAL = new Polygon ();
|
||||||
|
THIS->polygon(RETVAL);
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
|
@ -19,12 +19,13 @@
|
|||||||
void reverse();
|
void reverse();
|
||||||
Lines lines();
|
Lines lines();
|
||||||
Polyline* split_at(Point* point)
|
Polyline* split_at(Point* point)
|
||||||
%code{% RETVAL = THIS->split_at(*point); %};
|
%code{% RETVAL = new Polyline(); THIS->split_at(*point, RETVAL); %};
|
||||||
Polyline* split_at_index(int index)
|
Polyline* split_at_index(int index)
|
||||||
%code{% RETVAL = THIS->split_at_index(index); %};
|
%code{% RETVAL = new Polyline(); THIS->split_at_index(index, RETVAL); %};
|
||||||
Polyline* split_at_first_point()
|
Polyline* split_at_first_point()
|
||||||
%code{% RETVAL = THIS->split_at_first_point(); %};
|
%code{% RETVAL = new Polyline(); THIS->split_at_first_point(RETVAL); %};
|
||||||
Points equally_spaced_points(double distance);
|
Points equally_spaced_points(double distance)
|
||||||
|
%code{% THIS->equally_spaced_points(distance, &RETVAL); %};
|
||||||
double length();
|
double length();
|
||||||
double area();
|
double area();
|
||||||
bool is_counter_clockwise();
|
bool is_counter_clockwise();
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
Lines lines();
|
Lines lines();
|
||||||
Clone<Point> first_point();
|
Clone<Point> first_point();
|
||||||
Clone<Point> last_point();
|
Clone<Point> last_point();
|
||||||
Points equally_spaced_points(double distance);
|
Points equally_spaced_points(double distance)
|
||||||
|
%code{% THIS->equally_spaced_points(distance, &RETVAL); %};
|
||||||
double length();
|
double length();
|
||||||
bool is_valid();
|
bool is_valid();
|
||||||
void clip_end(double distance);
|
void clip_end(double distance);
|
||||||
|
Loading…
Reference in New Issue
Block a user