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
|
||||
|
||||
ExtrusionLoop::ExtrusionLoop(const Polygon &polygon, ExtrusionRole role)
|
||||
{
|
||||
this->role = role;
|
||||
this->set_polygon(polygon);
|
||||
}
|
||||
|
||||
ExtrusionLoop*
|
||||
ExtrusionLoop::clone() const
|
||||
{
|
||||
return new ExtrusionLoop (*this);
|
||||
}
|
||||
|
||||
ExtrusionPath*
|
||||
ExtrusionLoop::split_at_index(int index) const
|
||||
void
|
||||
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->mm3_per_mm = this->mm3_per_mm;
|
||||
path->width = this->width;
|
||||
path->height = this->height;
|
||||
|
||||
delete poly;
|
||||
return path;
|
||||
}
|
||||
|
||||
ExtrusionPath*
|
||||
ExtrusionLoop::split_at_first_point() const
|
||||
void
|
||||
ExtrusionLoop::split_at_first_point(ExtrusionPath* path) const
|
||||
{
|
||||
return this->split_at_index(0);
|
||||
return this->split_at_index(0, path);
|
||||
}
|
||||
|
||||
bool
|
||||
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
|
||||
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
|
||||
ExtrusionLoop::first_point() const
|
||||
{
|
||||
return this->polygon.points.front();
|
||||
return this->polylines.front().points.front();
|
||||
}
|
||||
|
||||
Point
|
||||
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
|
||||
|
@ -73,14 +73,18 @@ class ExtrusionPath : public ExtrusionEntity
|
||||
class ExtrusionLoop : public ExtrusionEntity
|
||||
{
|
||||
public:
|
||||
Polylines polylines;
|
||||
|
||||
ExtrusionLoop(const Polygon &polygon, ExtrusionRole role);
|
||||
ExtrusionLoop* clone() const;
|
||||
Polygon polygon;
|
||||
ExtrusionPath* split_at_index(int index) const;
|
||||
ExtrusionPath* split_at_first_point() const;
|
||||
void split_at_index(int index, ExtrusionPath* path) const;
|
||||
void split_at_first_point(ExtrusionPath* path) const;
|
||||
bool make_counter_clockwise();
|
||||
void reverse();
|
||||
Point first_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()));
|
||||
}
|
||||
|
||||
Polyline*
|
||||
Polygon::split_at(const Point &point) const
|
||||
void
|
||||
Polygon::split_at(const Point &point, Polyline* polyline) const
|
||||
{
|
||||
// find index of point
|
||||
for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) {
|
||||
if (it->coincides_with(point))
|
||||
return this->split_at_index(it - this->points.begin());
|
||||
if (it->coincides_with(point)) {
|
||||
this->split_at_index(it - this->points.begin(), polyline);
|
||||
return;
|
||||
}
|
||||
}
|
||||
CONFESS("Point not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Polyline*
|
||||
Polygon::split_at_index(int index) const
|
||||
void
|
||||
Polygon::split_at_index(int index, Polyline* polyline) const
|
||||
{
|
||||
Polyline* poly = new Polyline;
|
||||
poly->points.reserve(this->points.size() + 1);
|
||||
polyline->points.reserve(this->points.size() + 1);
|
||||
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)
|
||||
poly->points.push_back(*it);
|
||||
return poly;
|
||||
polyline->points.push_back(*it);
|
||||
}
|
||||
|
||||
Polyline*
|
||||
Polygon::split_at_first_point() const
|
||||
void
|
||||
Polygon::split_at_first_point(Polyline* polyline) const
|
||||
{
|
||||
return this->split_at_index(0);
|
||||
this->split_at_index(0, polyline);
|
||||
}
|
||||
|
||||
Points
|
||||
Polygon::equally_spaced_points(double distance) const
|
||||
void
|
||||
Polygon::equally_spaced_points(double distance, Points* points) const
|
||||
{
|
||||
Polyline* polyline = this->split_at_first_point();
|
||||
Points pts = polyline->equally_spaced_points(distance);
|
||||
delete polyline;
|
||||
return pts;
|
||||
Polyline polyline;
|
||||
this->split_at_first_point(&polyline);
|
||||
polyline.equally_spaced_points(distance, points);
|
||||
}
|
||||
|
||||
double
|
||||
|
@ -20,10 +20,10 @@ class Polygon : public MultiPoint {
|
||||
Point last_point() const;
|
||||
Lines lines() const;
|
||||
void lines(Lines* lines) const;
|
||||
Polyline* split_at(const Point &point) const;
|
||||
Polyline* split_at_index(int index) const;
|
||||
Polyline* split_at_first_point() const;
|
||||
Points equally_spaced_points(double distance) const;
|
||||
void split_at(const Point &point, Polyline* polyline) const;
|
||||
void split_at_index(int index, Polyline* polyline) const;
|
||||
void split_at_first_point(Polyline* polyline) const;
|
||||
void equally_spaced_points(double distance, Points* points) const;
|
||||
double area() const;
|
||||
bool is_counter_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
|
||||
so that they are evenly spaced according to the input distance */
|
||||
Points
|
||||
Polyline::equally_spaced_points(double distance) const
|
||||
void
|
||||
Polyline::equally_spaced_points(double distance, Points* points) const
|
||||
{
|
||||
Points pts;
|
||||
pts.push_back(this->first_point());
|
||||
points->push_back(this->first_point());
|
||||
double len = 0;
|
||||
|
||||
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) {
|
||||
pts.push_back(*it);
|
||||
points->push_back(*it);
|
||||
len = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
double take = segment_length - (len - distance); // how much we take of this segment
|
||||
Line segment(*(it-1), *it);
|
||||
pts.push_back(segment.point_at(take));
|
||||
points->push_back(segment.point_at(take));
|
||||
it--;
|
||||
len = -take;
|
||||
}
|
||||
|
||||
return pts;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -19,7 +19,7 @@ class Polyline : public MultiPoint {
|
||||
void clip_start(double distance);
|
||||
void extend_end(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);
|
||||
|
||||
#ifdef SLIC3RXS
|
||||
|
@ -33,7 +33,7 @@ template <class T>
|
||||
class Clone {
|
||||
T* val;
|
||||
public:
|
||||
Clone() {}
|
||||
Clone() : val() {}
|
||||
Clone(T* t) : val(new T(*t)) {}
|
||||
Clone(const T& t) : val(new T(t)) {}
|
||||
operator T*() const {return val; }
|
||||
|
@ -4,7 +4,7 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 7;
|
||||
use Test::More tests => 8;
|
||||
|
||||
my $square = [
|
||||
[100, 100],
|
||||
@ -18,7 +18,8 @@ my $loop = Slic3r::ExtrusionLoop->new(
|
||||
role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||
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';
|
||||
|
||||
$loop = $loop->clone;
|
||||
|
@ -9,13 +9,14 @@
|
||||
%name{Slic3r::ExtrusionLoop} class ExtrusionLoop {
|
||||
~ExtrusionLoop();
|
||||
SV* arrayref()
|
||||
%code{% RETVAL = THIS->polygon.to_AV(); %};
|
||||
%code{% Polygon polygon; THIS->polygon(&polygon); RETVAL = polygon.to_AV(); %};
|
||||
SV* pp()
|
||||
%code{% RETVAL = THIS->polygon.to_SV_pureperl(); %};
|
||||
void reverse()
|
||||
%code{% THIS->polygon.reverse(); %};
|
||||
ExtrusionPath* split_at_index(int index);
|
||||
ExtrusionPath* split_at_first_point();
|
||||
%code{% Polygon polygon; THIS->polygon(&polygon); RETVAL = polygon.to_SV_pureperl(); %};
|
||||
void reverse();
|
||||
ExtrusionPath* split_at_index(int index)
|
||||
%code{% RETVAL = new ExtrusionPath (); THIS->split_at_index(index, RETVAL); %};
|
||||
ExtrusionPath* split_at_first_point()
|
||||
%code{% RETVAL = new ExtrusionPath (); THIS->split_at_first_point(RETVAL); %};
|
||||
bool make_counter_clockwise();
|
||||
Clone<Point> first_point();
|
||||
Clone<Point> last_point();
|
||||
@ -33,22 +34,25 @@ _new(CLASS, polygon_sv, role, mm3_per_mm, width, height)
|
||||
float width;
|
||||
float height;
|
||||
CODE:
|
||||
RETVAL = new ExtrusionLoop ();
|
||||
RETVAL->polygon.from_SV_check(polygon_sv);
|
||||
RETVAL->role = role;
|
||||
Polygon polygon;
|
||||
polygon.from_SV_check(polygon_sv);
|
||||
RETVAL = new ExtrusionLoop (polygon, role);
|
||||
RETVAL->mm3_per_mm = mm3_per_mm;
|
||||
RETVAL->width = width;
|
||||
RETVAL->height = height;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Ref<Polygon>
|
||||
Polygon*
|
||||
ExtrusionLoop::polygon(...)
|
||||
CODE:
|
||||
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:
|
||||
RETVAL
|
||||
|
||||
|
@ -19,12 +19,13 @@
|
||||
void reverse();
|
||||
Lines lines();
|
||||
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)
|
||||
%code{% RETVAL = THIS->split_at_index(index); %};
|
||||
%code{% RETVAL = new Polyline(); THIS->split_at_index(index, RETVAL); %};
|
||||
Polyline* split_at_first_point()
|
||||
%code{% RETVAL = THIS->split_at_first_point(); %};
|
||||
Points equally_spaced_points(double distance);
|
||||
%code{% RETVAL = new Polyline(); THIS->split_at_first_point(RETVAL); %};
|
||||
Points equally_spaced_points(double distance)
|
||||
%code{% THIS->equally_spaced_points(distance, &RETVAL); %};
|
||||
double length();
|
||||
double area();
|
||||
bool is_counter_clockwise();
|
||||
|
@ -23,7 +23,8 @@
|
||||
Lines lines();
|
||||
Clone<Point> first_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();
|
||||
bool is_valid();
|
||||
void clip_end(double distance);
|
||||
|
Loading…
Reference in New Issue
Block a user