diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index 12d66fdd7..5fb0ca1c5 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -1,4 +1,4 @@ -package Slic3r::ExPolygon; +gpackage Slic3r::ExPolygon; use strict; use warnings; @@ -34,7 +34,7 @@ sub clone { # no-op for legacy with ::XS sub arrayref { $_[0] } -sub arrayref_pp { [ map $_->arrayref_pp, @{$_[0]} ] } +sub pp { [ map $_->pp, @{$_[0]} ] } sub contour { my $self = shift; @@ -108,7 +108,7 @@ sub noncollapsing_offset_ex { sub encloses_point { my $self = shift; my ($point) = @_; - return Boost::Geometry::Utils::point_covered_by_polygon($point->arrayref, $self->arrayref_pp); + return Boost::Geometry::Utils::point_covered_by_polygon($point->arrayref, $self->pp); } # A version of encloses_point for use when hole borders do not matter. @@ -141,7 +141,7 @@ sub clip_line { my $self = shift; my ($line) = @_; # line must be a Slic3r::Line object - return Boost::Geometry::Utils::polygon_multi_linestring_intersection($self->arrayref_pp, [$line->arrayref_pp]); + return Boost::Geometry::Utils::polygon_multi_linestring_intersection($self->pp, [$line->pp]); } sub simplify { @@ -150,7 +150,7 @@ sub simplify { # it would be nice to have a multilinestring_simplify method in B::G::U my @simplified = Slic3r::Geometry::Clipper::simplify_polygons( - [ map Boost::Geometry::Utils::linestring_simplify($_, $tolerance), @{$self->arrayref_pp} ], + [ map Boost::Geometry::Utils::linestring_simplify($_, $tolerance), @{$self->pp} ], ); return @{ Slic3r::Geometry::Clipper::union_ex([ @simplified ]) }; } diff --git a/lib/Slic3r/Fill/Honeycomb.pm b/lib/Slic3r/Fill/Honeycomb.pm index 6c1ca6df1..2ead45721 100644 --- a/lib/Slic3r/Fill/Honeycomb.pm +++ b/lib/Slic3r/Fill/Honeycomb.pm @@ -90,7 +90,7 @@ sub fill_surface { # path is more straight @paths = map Slic3r::Polyline->new(@$_), @{ Boost::Geometry::Utils::polygon_multi_linestring_intersection( - $surface->expolygon->arrayref_pp, + $surface->expolygon->pp, \@polygons, ) }; diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm index 661704019..ffca16005 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -66,7 +66,7 @@ sub fill_surface { # clip paths against a slightly offsetted expolygon, so that the first and last paths # are kept even if the expolygon has vertical sides my @paths = @{ Boost::Geometry::Utils::polygon_multi_linestring_intersection( - +($expolygon->offset_ex(scaled_epsilon))[0]->arrayref_pp, # TODO: we should use all the resulting expolygons and clip the linestrings to a multipolygon object + +($expolygon->offset_ex(scaled_epsilon))[0]->pp, # TODO: we should use all the resulting expolygons and clip the linestrings to a multipolygon object [ @{ $self->cache->{$cache_id} } ], ) }; diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index b0bc0119d..54034a8a4 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -891,7 +891,7 @@ sub repaint { # if sequential printing is enabled and we have more than one object if ($parent->{config}->complete_objects && (map @{$_->instances}, @{$parent->{objects}}) > 1) { - my $convex_hull = Slic3r::Polygon->new(@{convex_hull([ map @{$_->contour->arrayref_pp}, @{$parent->{object_previews}->[-1][2]} ])}); + my $convex_hull = Slic3r::Polygon->new(@{convex_hull([ map @{$_->contour->pp}, @{$parent->{object_previews}->[-1][2]} ])}); my ($clearance) = @{offset([$convex_hull], $parent->{config}->extruder_clearance_radius / 2 * $parent->{scaling_factor}, 100, JT_ROUND)}; $dc->SetPen($parent->{clearance_pen}); $dc->SetBrush($parent->{transparent_brush}); diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index 42f8cd22e..a045ca90d 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -179,8 +179,8 @@ sub traverse_pt { sub _convert { my $polygons = shift; - $polygons = $polygons->arrayref_pp if ref $polygons eq 'Slic3r::ExPolygon::XS'; - $polygons = [ map $_->arrayref_pp, @$polygons ] if @$polygons && ref $polygons->[0] eq 'Slic3r::Polygon'; + $polygons = $polygons->pp if ref $polygons eq 'Slic3r::ExPolygon::XS'; + $polygons = [ map $_->pp, @$polygons ] if @$polygons && ref $polygons->[0] eq 'Slic3r::Polygon'; return $polygons; } diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm index b99a1ce8a..b29f78dc2 100644 --- a/lib/Slic3r/Polygon.pm +++ b/lib/Slic3r/Polygon.pm @@ -22,7 +22,7 @@ sub wkt { sub is_counter_clockwise { my $self = shift; - return Slic3r::Geometry::Clipper::is_counter_clockwise($self->arrayref_pp); + return Slic3r::Geometry::Clipper::is_counter_clockwise($self->pp); } sub make_counter_clockwise { @@ -57,12 +57,12 @@ sub remove_acute_vertices { sub encloses_point { my $self = shift; my ($point) = @_; - return Boost::Geometry::Utils::point_covered_by_polygon($point->arrayref, [$self->arrayref_pp]); + return Boost::Geometry::Utils::point_covered_by_polygon($point->arrayref, [$self->pp]); } sub area { my $self = shift; - return Slic3r::Geometry::Clipper::area($self->arrayref_pp); + return Slic3r::Geometry::Clipper::area($self->pp); } sub grow { diff --git a/lib/Slic3r/Polyline.pm b/lib/Slic3r/Polyline.pm index a24c56787..350c69096 100644 --- a/lib/Slic3r/Polyline.pm +++ b/lib/Slic3r/Polyline.pm @@ -18,7 +18,7 @@ sub new { } sub arrayref { $_[0] } -sub arrayref_pp { +sub pp { my $self = shift; if (ref($self->[0]) eq 'Slic3r::Point') { return [ map $_->arrayref, @$self ]; @@ -68,7 +68,7 @@ sub simplify { my $self = shift; my $tolerance = shift || 10; - my $simplified = Boost::Geometry::Utils::linestring_simplify($self->arrayref_pp, $tolerance); + my $simplified = Boost::Geometry::Utils::linestring_simplify($self->pp, $tolerance); return (ref $self)->new(@$simplified); } @@ -79,7 +79,7 @@ sub reverse { sub length { my $self = shift; - return Boost::Geometry::Utils::linestring_length($self->arrayref_pp); + return Boost::Geometry::Utils::linestring_length($self->pp); } sub grow { @@ -119,7 +119,7 @@ sub clip_with_expolygon { my $self = shift; my ($expolygon) = @_; - my $result = Boost::Geometry::Utils::polygon_multi_linestring_intersection($expolygon->arrayref_pp, [$self->arrayref_pp]); + my $result = Boost::Geometry::Utils::polygon_multi_linestring_intersection($expolygon->pp, [$self->pp]); bless $_, 'Slic3r::Polyline' for @$result; return @$result; } diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index a1f214d0c..f8336ec45 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -763,7 +763,7 @@ sub write_gcode { my @islands = (); foreach my $obj_idx (0 .. $#{$self->objects}) { my $convex_hull = convex_hull([ - map @{$_->contour->arrayref_pp}, map @{$_->slices}, @{$self->objects->[$obj_idx]->layers}, + map @{$_->contour->pp}, map @{$_->slices}, @{$self->objects->[$obj_idx]->layers}, ]); # discard layers only containing thin walls (offset would fail on an empty polygon) if (@$convex_hull) { diff --git a/t/clean_polylines.t b/t/clean_polylines.t index 092b0792d..3aabf4715 100644 --- a/t/clean_polylines.t +++ b/t/clean_polylines.t @@ -25,7 +25,7 @@ use Slic3r; [0,0],[1,0],[2,0],[2,1],[2,2],[1,2],[0,2],[0,1],[0,0], ); $polyline = $polyline->simplify(1); - is_deeply $polyline->arrayref_pp, [ [0, 0], [2, 0], [2, 2], [0, 2], [0, 0] ], 'Douglas-Peucker'; + is_deeply $polyline->pp, [ [0, 0], [2, 0], [2, 2], [0, 2], [0, 0] ], 'Douglas-Peucker'; } { @@ -33,7 +33,7 @@ use Slic3r; [0,0], [50,50], [100,0], [125,-25], [150,50], ); $polyline = $polyline->simplify(25); - is_deeply $polyline->arrayref_pp, [ [0, 0], [50, 50], [125, -25], [150, 50] ], 'Douglas-Peucker'; + is_deeply $polyline->pp, [ [0, 0], [50, 50], [125, -25], [150, 50] ], 'Douglas-Peucker'; } { diff --git a/t/geometry.t b/t/geometry.t index e96ec729f..ac808fa1d 100644 --- a/t/geometry.t +++ b/t/geometry.t @@ -158,7 +158,7 @@ is Slic3r::Geometry::can_connect_points(@$points, $polygons), 0, 'can_connect_po { my $polyline = Slic3r::Polyline->new([0, 0], [10, 0], [20, 0]); - is_deeply [ map $_->arrayref_pp, $polyline->lines ], [ + is_deeply [ map $_->pp, $polyline->lines ], [ [ [0, 0], [10, 0] ], [ [10, 0], [20, 0] ], ], 'polyline_lines'; @@ -170,7 +170,7 @@ is Slic3r::Geometry::can_connect_points(@$points, $polygons), 0, 'can_connect_po my $polyline = Slic3r::Polygon->new([0, 0], [10, 0], [5, 5]); my $result = $polyline->split_at_index(1); is ref($result), 'Slic3r::Polyline', 'split_at_index returns polyline'; - is_deeply $result->arrayref_pp, [ [10, 0], [5, 5], [0, 0], [10, 0] ], 'split_at_index'; + is_deeply $result->pp, [ [10, 0], [5, 5], [0, 0], [10, 0] ], 'split_at_index'; } #========================================================== diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm index c34f1a78d..c49c6afa5 100644 --- a/xs/lib/Slic3r/XS.pm +++ b/xs/lib/Slic3r/XS.pm @@ -11,16 +11,16 @@ package Slic3r::Point; use overload '@{}' => sub { $_[0]->arrayref }; -package Slic3r::ExPolygon::XS; +package Slic3r::ExPolygon; use overload '@{}' => sub { $_[0]->arrayref }; -package Slic3r::Polyline::XS; +package Slic3r::Polyline; use overload '@{}' => sub { $_[0]->arrayref }, 'fallback' => 1; -package Slic3r::Polygon::XS; +package Slic3r::Polygon; use overload '@{}' => sub { $_[0]->arrayref }; diff --git a/xs/src/ExPolygon.hpp b/xs/src/ExPolygon.hpp index 26608b127..34f010f2b 100644 --- a/xs/src/ExPolygon.hpp +++ b/xs/src/ExPolygon.hpp @@ -19,7 +19,10 @@ class ExPolygon Polygon contour; Polygons holes; bool in_collection; - SV* to_SV(bool pureperl = false, bool pureperl_children = false); + void from_SV(SV* poly_sv); + void from_SV_check(SV* poly_sv); + SV* to_SV(); + SV* to_SV_pureperl(); void scale(double factor); void translate(double x, double y); void rotate(double angle, Point* center); @@ -55,48 +58,60 @@ ExPolygon::rotate(double angle, Point* center) } SV* -ExPolygon::to_SV(bool pureperl, bool pureperl_children) -{ - if (pureperl) { - const unsigned int num_holes = this->holes.size(); - AV* av = newAV(); - av_extend(av, num_holes); // -1 +1 - av_store(av, 0, this->contour.to_SV(pureperl_children, pureperl_children)); - for (unsigned int i = 0; i < num_holes; i++) { - av_store(av, i+1, this->holes[i].to_SV(pureperl_children, pureperl_children)); - } - return sv_bless(newRV_noinc((SV*)av), gv_stashpv("Slic3r::ExPolygon", GV_ADD)); - } else { - SV* sv = newSV(0); - sv_setref_pv( sv, "Slic3r::ExPolygon::XS", this ); - return sv; +ExPolygon::to_SV() { + const unsigned int num_holes = this->holes.size(); + AV* av = newAV(); + av_extend(av, num_holes); // -1 +1 + + SV* sv = newSV(0); + sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(this->contour) ); + av_store(av, 0, sv); + + for (unsigned int i = 0; i < num_holes; i++) { + sv = newSV(0); + sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(this->holes[i]) ); + av_store(av, i+1, sv); } + return newRV_noinc((SV*)av); +} + +SV* +ExPolygon::to_SV_pureperl() +{ + const unsigned int num_holes = this->holes.size(); + AV* av = newAV(); + av_extend(av, num_holes); // -1 +1 + av_store(av, 0, this->contour.to_SV_pureperl()); + for (unsigned int i = 0; i < num_holes; i++) { + av_store(av, i+1, this->holes[i].to_SV_pureperl()); + } + return newRV_noinc((SV*)av); } void -perl2expolygon(SV* expoly_sv, ExPolygon& expoly) +ExPolygon::from_SV(SV* expoly_sv) { AV* expoly_av = (AV*)SvRV(expoly_sv); const unsigned int num_polygons = av_len(expoly_av)+1; - expoly.holes.resize(num_polygons-1); + this->holes.resize(num_polygons-1); SV** polygon_sv = av_fetch(expoly_av, 0, 0); - expoly.contour.from_SV(*polygon_sv); + this->contour.from_SV(*polygon_sv); for (unsigned int i = 0; i < num_polygons-1; i++) { polygon_sv = av_fetch(expoly_av, i+1, 0); - expoly.holes[i].from_SV(*polygon_sv); + this->holes[i].from_SV(*polygon_sv); } } void -perl2expolygon_check(SV* expoly_sv, ExPolygon& expoly) +ExPolygon::from_SV_check(SV* expoly_sv) { if (sv_isobject(expoly_sv) && (SvTYPE(SvRV(expoly_sv)) == SVt_PVMG)) { // a XS ExPolygon was supplied - expoly = *(ExPolygon *)SvIV((SV*)SvRV( expoly_sv )); + *this = *(ExPolygon *)SvIV((SV*)SvRV( expoly_sv )); } else { // a Perl arrayref was supplied - perl2expolygon(expoly_sv, expoly); + this->from_SV(expoly_sv); } } diff --git a/xs/src/Line.hpp b/xs/src/Line.hpp new file mode 100644 index 000000000..94e400595 --- /dev/null +++ b/xs/src/Line.hpp @@ -0,0 +1,107 @@ +#ifndef slic3r_Line_hpp_ +#define slic3r_Line_hpp_ + +extern "C" { +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +#include "ppport.h" +} + +#include "Point.hpp" +#include + +namespace Slic3r { + +class Line +{ + public: + Point a; + Point b; + Line() {}; + explicit Line(Point _a, Point _b): a(_a), b(_b) {}; + void from_SV(SV* line_sv); + void from_SV_check(SV* line_sv); + SV* to_SV(); + SV* to_SV_pureperl(); + void scale(double factor); + void translate(double x, double y); + void rotate(double angle, Point* center); + void reverse(); +}; + +typedef std::vector Lines; + +void +Line::scale(double factor) +{ + this->a.scale(factor); + this->b.scale(factor); +} + +void +Line::translate(double x, double y) +{ + this->a.translate(x, y); + this->b.translate(x, y); +} + +void +Line::rotate(double angle, Point* center) +{ + this->a.rotate(angle, center); + this->b.rotate(angle, center); +} + +void +Line::reverse() +{ + std::swap(this->a, this->b); +} + +void +Line::from_SV(SV* line_sv) +{ + AV* line_av = (AV*)SvRV(line_sv); + this->a.from_SV_check(*av_fetch(line_av, 0, 0)); + this->b.from_SV_check(*av_fetch(line_av, 1, 0)); +} + +void +Line::from_SV_check(SV* line_sv) +{ + if (sv_isobject(line_sv) && (SvTYPE(SvRV(line_sv)) == SVt_PVMG)) { + *this = *(Line*)SvIV((SV*)SvRV( line_sv )); + } else { + this->from_SV(line_sv); + } +} + +SV* +Line::to_SV() { + AV* av = newAV(); + av_extend(av, 1); + + SV* sv = newSV(0); + sv_setref_pv( sv, "Slic3r::Point", new Point(this->a) ); + av_store(av, 0, sv); + + sv = newSV(0); + sv_setref_pv( sv, "Slic3r::Point", new Point(this->b) ); + av_store(av, 1, sv); + + return newRV_noinc((SV*)av); +} + +SV* +Line::to_SV_pureperl() { + AV* av = newAV(); + av_extend(av, 1); + av_store(av, 0, this->a.to_SV_pureperl()); + av_store(av, 1, this->b.to_SV_pureperl()); + return newRV_noinc((SV*)av); +} + +} + +#endif diff --git a/xs/src/MultiPoint.hpp b/xs/src/MultiPoint.hpp new file mode 100644 index 000000000..1952a65a5 --- /dev/null +++ b/xs/src/MultiPoint.hpp @@ -0,0 +1,110 @@ +#ifndef slic3r_MultiPoint_hpp_ +#define slic3r_MultiPoint_hpp_ + +extern "C" { +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +#include "ppport.h" +} + +#include "Point.hpp" +#include +#include + +namespace Slic3r { + +class MultiPoint +{ + public: + Points points; + void from_SV(SV* poly_sv); + void from_SV_check(SV* poly_sv); + SV* to_SV(); + SV* to_SV_pureperl(); + void scale(double factor); + void translate(double x, double y); + void rotate(double angle, Point* center); + void reverse(); +}; + +void +MultiPoint::scale(double factor) +{ + for (Points::iterator it = points.begin(); it != points.end(); ++it) { + (*it).scale(factor); + } +} + +void +MultiPoint::translate(double x, double y) +{ + for (Points::iterator it = points.begin(); it != points.end(); ++it) { + (*it).translate(x, y); + } +} + +void +MultiPoint::rotate(double angle, Point* center) +{ + for (Points::iterator it = points.begin(); it != points.end(); ++it) { + (*it).rotate(angle, center); + } +} + +void +MultiPoint::reverse() +{ + std::reverse(this->points.begin(), this->points.end()); +} + +void +MultiPoint::from_SV(SV* poly_sv) +{ + AV* poly_av = (AV*)SvRV(poly_sv); + const unsigned int num_points = av_len(poly_av)+1; + this->points.resize(num_points); + + for (unsigned int i = 0; i < num_points; i++) { + SV** point_sv = av_fetch(poly_av, i, 0); + this->points[i].from_SV_check(*point_sv); + } +} + +void +MultiPoint::from_SV_check(SV* poly_sv) +{ + if (sv_isobject(poly_sv) && (SvTYPE(SvRV(poly_sv)) == SVt_PVMG)) { + *this = *(MultiPoint*)SvIV((SV*)SvRV( poly_sv )); + } else { + this->from_SV(poly_sv); + } +} + +SV* +MultiPoint::to_SV() { + const unsigned int num_points = this->points.size(); + AV* av = newAV(); + av_extend(av, num_points-1); + for (unsigned int i = 0; i < num_points; i++) { + SV* sv = newSV(0); + sv_setref_pv( sv, "Slic3r::Point", new Point(this->points[i]) ); + av_store(av, i, sv); + } + return newRV_noinc((SV*)av); +} + +SV* +MultiPoint::to_SV_pureperl() { + const unsigned int num_points = this->points.size(); + AV* av = newAV(); + av_extend(av, num_points-1); + for (unsigned int i = 0; i < num_points; i++) { + av_store(av, i, this->points[i].to_SV_pureperl()); + } + return newRV_noinc((SV*)av); +} + +} + +#endif diff --git a/xs/src/Point.hpp b/xs/src/Point.hpp index 78e60003d..09f9f36d3 100644 --- a/xs/src/Point.hpp +++ b/xs/src/Point.hpp @@ -19,7 +19,9 @@ class Point long x; long y; explicit Point(long _x = 0, long _y = 0): x(_x), y(_y) {}; - SV* to_SV(bool pureperl = false); + void from_SV(SV* point_sv); + void from_SV_check(SV* point_sv); + SV* to_SV_pureperl(); void scale(double factor); void translate(double x, double y); void rotate(double angle, Point* center); @@ -58,35 +60,29 @@ Point::coincides_with(Point* point) } SV* -Point::to_SV(bool pureperl) { - if (pureperl) { - AV* av = newAV(); - av_fill(av, 1); - av_store(av, 0, newSViv(this->x)); - av_store(av, 1, newSViv(this->y)); - return newRV_noinc((SV*)av); - } else { - SV* sv = newSV(0); - sv_setref_pv( sv, "Slic3r::Point", new Point(*this) ); - return sv; - } +Point::to_SV_pureperl() { + AV* av = newAV(); + av_fill(av, 1); + av_store(av, 0, newSViv(this->x)); + av_store(av, 1, newSViv(this->y)); + return newRV_noinc((SV*)av); } void -perl2point(SV* point_sv, Point& point) +Point::from_SV(SV* point_sv) { - AV* point_av = (AV*)SvRV(point_sv); - point.x = (unsigned long)SvIV(*av_fetch(point_av, 0, 0)); - point.y = (unsigned long)SvIV(*av_fetch(point_av, 1, 0)); + AV* point_av = (AV*)SvRV(point_sv); + this->x = (unsigned long)SvIV(*av_fetch(point_av, 0, 0)); + this->y = (unsigned long)SvIV(*av_fetch(point_av, 1, 0)); } void -perl2point_check(SV* point_sv, Point& point) +Point::from_SV_check(SV* point_sv) { if (sv_isobject(point_sv) && (SvTYPE(SvRV(point_sv)) == SVt_PVMG)) { - point = *(Point*)SvIV((SV*)SvRV( point_sv )); + *this = *(Point*)SvIV((SV*)SvRV( point_sv )); } else { - perl2point(point_sv, point); + this->from_SV(point_sv); } } diff --git a/xs/src/Polygon.hpp b/xs/src/Polygon.hpp index a52674b7d..24d5bb58e 100644 --- a/xs/src/Polygon.hpp +++ b/xs/src/Polygon.hpp @@ -13,12 +13,7 @@ extern "C" { namespace Slic3r { -class Polygon : public Polyline { - protected: - char* perl_class() { - return (char*)"Slic3r::Polygon"; - } -}; +class Polygon : public MultiPoint {}; typedef std::vector Polygons; diff --git a/xs/src/Polyline.hpp b/xs/src/Polyline.hpp index 6e243f890..a1e5a0193 100644 --- a/xs/src/Polyline.hpp +++ b/xs/src/Polyline.hpp @@ -8,94 +8,26 @@ extern "C" { #include "ppport.h" } -#include "Point.hpp" -#include -#include -#include +#include "Line.hpp" +#include "MultiPoint.hpp" namespace Slic3r { -class Polyline -{ +class Polyline : public MultiPoint { public: - Points points; - void from_SV(SV* poly_sv); - void from_SV_check(SV* poly_sv); - SV* to_SV(bool pureperl = false, bool pureperl_children = false); - void scale(double factor); - void translate(double x, double y); - void rotate(double angle, Point* center); - void reverse(); - protected: - virtual char* perl_class() { - return (char*)"Slic3r::Polyline"; - } + Lines lines(); }; typedef std::vector Polylines; -void -Polyline::scale(double factor) +Lines +Polyline::lines() { - for (Points::iterator it = points.begin(); it != points.end(); ++it) { - (*it).scale(factor); + Lines lines; + for (int i = 0; i < this->points.size()-1; i++) { + lines.push_back(Line(this->points[i], this->points[i+1])); } -} - -void -Polyline::translate(double x, double y) -{ - for (Points::iterator it = points.begin(); it != points.end(); ++it) { - (*it).translate(x, y); - } -} - -void -Polyline::rotate(double angle, Point* center) -{ - for (Points::iterator it = points.begin(); it != points.end(); ++it) { - (*it).rotate(angle, center); - } -} - -void -Polyline::reverse() -{ - std::reverse(this->points.begin(), this->points.end()); -} - -void -Polyline::from_SV(SV* poly_sv) -{ - AV* poly_av = (AV*)SvRV(poly_sv); - const unsigned int num_points = av_len(poly_av)+1; - this->points.resize(num_points); - - for (unsigned int i = 0; i < num_points; i++) { - SV** point_sv = av_fetch(poly_av, i, 0); - perl2point_check(*point_sv, this->points[i]); - } -} - -void -Polyline::from_SV_check(SV* poly_sv) -{ - if (sv_isobject(poly_sv) && (SvTYPE(SvRV(poly_sv)) == SVt_PVMG)) { - *this = *(Polyline*)SvIV((SV*)SvRV( poly_sv )); - } else { - this->from_SV(poly_sv); - } -} - -SV* -Polyline::to_SV(bool pureperl, bool pureperl_children) { - const unsigned int num_points = this->points.size(); - AV* av = newAV(); - av_extend(av, num_points-1); - for (unsigned int i = 0; i < num_points; i++) { - av_store(av, i, this->points[i].to_SV(pureperl_children)); - } - return sv_bless(newRV_noinc((SV*)av), gv_stashpv(this->perl_class(), GV_ADD)); + return lines; } } diff --git a/xs/t/04_expolygon.t b/xs/t/04_expolygon.t index fb7295362..15b6a2bb9 100644 --- a/xs/t/04_expolygon.t +++ b/xs/t/04_expolygon.t @@ -4,7 +4,7 @@ use strict; use warnings; use Slic3r::XS; -use Test::More tests => 15; +use Test::More tests => 17; use constant PI => 4 * atan2(1, 1); @@ -21,28 +21,29 @@ my $hole_in_square = [ # cw [160, 140], ]; -my $expolygon = Slic3r::ExPolygon::XS->new($square, $hole_in_square); -is_deeply [ @{$expolygon->arrayref_pp} ], [$square, $hole_in_square], 'expolygon roundtrip'; +my $expolygon = Slic3r::ExPolygon->new($square, $hole_in_square); -my $arrayref = $expolygon->arrayref; -isa_ok $arrayref, 'Slic3r::ExPolygon', 'Perl expolygon is blessed'; +is ref($expolygon->pp), 'ARRAY', 'expolygon pp is unblessed'; +is_deeply $expolygon->pp, [$square, $hole_in_square], 'expolygon roundtrip'; -my $arrayref_pp = $expolygon->arrayref_pp; -isa_ok $arrayref_pp, 'Slic3r::ExPolygon', 'Perl expolygon is blessed'; -isa_ok $arrayref_pp->[0], 'Slic3r::Polygon', 'Perl polygons are blessed'; -isnt ref($arrayref_pp->[0][0]), 'Slic3r::Point', 'Perl polygon points are not blessed'; +is ref($expolygon->arrayref), 'ARRAY', 'expolygon arrayref is unblessed'; +isa_ok $expolygon->[0], 'Slic3r::Polygon', 'expolygon polygon is blessed'; +isa_ok $expolygon->[0][0], 'Slic3r::Point', 'expolygon point is blessed'; { - my $clone = $expolygon->clone; - is_deeply [ @{$clone->arrayref_pp} ], [$square, $hole_in_square], 'clone'; - # The following tests implicitely check that modifying clones - # does not modify the original one. + my $polygon = $expolygon->[0]; + $polygon->scale(2); + isnt $expolygon->[0][0][0], $polygon->[0][0], 'a copy of polygons is returned'; } +is_deeply $expolygon->clone->pp, [$square, $hole_in_square], 'clone'; +# The following tests implicitely check that modifying clones +# does not modify the original one. + { my $expolygon2 = $expolygon->clone; $expolygon2->scale(2.5); - is_deeply [ @{$expolygon2->arrayref_pp} ], [ + is_deeply $expolygon2->pp, [ [map [ 2.5*$_->[0], 2.5*$_->[1] ], @$square], [map [ 2.5*$_->[0], 2.5*$_->[1] ], @$hole_in_square] ], 'scale'; @@ -51,7 +52,7 @@ isnt ref($arrayref_pp->[0][0]), 'Slic3r::Point', 'Perl polygon points are not bl { my $expolygon2 = $expolygon->clone; $expolygon2->translate(10, -5); - is_deeply [ @{$expolygon2->arrayref_pp} ], [ + is_deeply $expolygon2->pp, [ [map [ $_->[0]+10, $_->[1]-5 ], @$square], [map [ $_->[0]+10, $_->[1]-5 ], @$hole_in_square] ], 'translate'; @@ -60,7 +61,7 @@ isnt ref($arrayref_pp->[0][0]), 'Slic3r::Point', 'Perl polygon points are not bl { my $expolygon2 = $expolygon->clone; $expolygon2->rotate(PI/2, Slic3r::Point->new(150,150)); - is_deeply [ @{$expolygon2->arrayref_pp} ], [ + is_deeply $expolygon2->pp, [ [ @$square[1,2,3,0] ], [ @$hole_in_square[3,0,1,2] ] ], 'rotate around Point'; @@ -69,7 +70,7 @@ isnt ref($arrayref_pp->[0][0]), 'Slic3r::Point', 'Perl polygon points are not bl { my $expolygon2 = $expolygon->clone; $expolygon2->rotate(PI/2, [150,150]); - is_deeply [ @{$expolygon2->arrayref_pp} ], [ + is_deeply $expolygon2->pp, [ [ @$square[1,2,3,0] ], [ @$hole_in_square[3,0,1,2] ] ], 'rotate around pure-Perl Point'; @@ -78,19 +79,27 @@ isnt ref($arrayref_pp->[0][0]), 'Slic3r::Point', 'Perl polygon points are not bl { my $expolygon2 = $expolygon->clone; $expolygon2->scale(2); - my $collection = Slic3r::ExPolygon::Collection->new($expolygon->arrayref_pp, $expolygon2->arrayref_pp); - is_deeply [ @{$collection->arrayref_pp} ], [ $expolygon->arrayref_pp, $expolygon2->arrayref_pp ], - 'expolygon collection'; + my $collection = Slic3r::ExPolygon::Collection->new($expolygon->pp, $expolygon2->pp); + is_deeply $collection->pp, [ $expolygon->pp, $expolygon2->pp ], + 'expolygon collection (pure Perl) roundtrip'; + my $collection2 = Slic3r::ExPolygon::Collection->new($expolygon, $expolygon2); - is_deeply [ @{$collection->arrayref_pp} ], [ @{$collection2->arrayref_pp} ], - 'expolygon collection with XS expolygons'; + is_deeply $collection->pp, $collection2->pp, + 'expolygon collection (XS) roundtrip'; $collection->clear; is scalar(@$collection), 0, 'clear collection'; + $collection->append($expolygon); is scalar(@$collection), 1, 'append to collection'; - is_deeply $collection->[0]->clone->arrayref_pp, $expolygon->arrayref_pp, 'clone collection item'; + my $exp = $collection->[0]; + $exp->scale(3); + ### we store a copy, not the original by reference + ###is_deeply $expolygon->pp, $exp->pp, 'input is stored by reference in collection'; + is_deeply $collection->[0]->pp, $exp->pp, 'collection items are returned by reference'; + + is_deeply $collection->[0]->clone->pp, $collection->[0]->pp, 'clone collection item'; } __END__ diff --git a/xs/t/05_surface.t b/xs/t/05_surface.t index b167ba1a9..1fc699121 100644 --- a/xs/t/05_surface.t +++ b/xs/t/05_surface.t @@ -19,7 +19,7 @@ my $hole_in_square = [ # cw [160, 140], ]; -my $expolygon = Slic3r::ExPolygon::XS->new($square, $hole_in_square); +my $expolygon = Slic3r::ExPolygon->new($square, $hole_in_square); my $surface = Slic3r::Surface->new( expolygon => $expolygon, surface_type => Slic3r::Surface::S_TYPE_INTERNAL, @@ -27,8 +27,8 @@ my $surface = Slic3r::Surface->new( $surface = $surface->clone; -isa_ok $surface->expolygon, 'Slic3r::ExPolygon::XS', 'expolygon'; -is_deeply [ @{$surface->expolygon->arrayref_pp} ], [$square, $hole_in_square], 'expolygon roundtrip'; +isa_ok $surface->expolygon, 'Slic3r::ExPolygon', 'expolygon'; +is_deeply [ @{$surface->expolygon->pp} ], [$square, $hole_in_square], 'expolygon roundtrip'; is $surface->surface_type, Slic3r::Surface::S_TYPE_INTERNAL, 'surface_type'; $surface->surface_type(Slic3r::Surface::S_TYPE_BOTTOM); @@ -43,7 +43,7 @@ is $surface->extra_perimeters, 2, 'extra_perimeters'; { my $collection = Slic3r::Surface::Collection->new($surface, $surface->clone); is scalar(@$collection), 2, 'collection has the right number of items'; - is_deeply $collection->[0]->expolygon->arrayref_pp, [$square, $hole_in_square], + is_deeply $collection->[0]->expolygon->pp, [$square, $hole_in_square], 'collection returns a correct surface expolygon'; $collection->clear; is scalar(@$collection), 0, 'clear collection'; diff --git a/xs/t/06_polygon.t b/xs/t/06_polygon.t index b1a9015b4..d024fd76c 100644 --- a/xs/t/06_polygon.t +++ b/xs/t/06_polygon.t @@ -13,11 +13,10 @@ my $square = [ # ccw [100, 200], ]; -my $polygon = Slic3r::Polygon::XS->new(@$square); -is_deeply [ @{$polygon->arrayref_pp} ], [ @$square ], 'polygon roundtrip'; +my $polygon = Slic3r::Polygon->new(@$square); +is_deeply [ @{$polygon->pp} ], [ @$square ], 'polygon roundtrip'; -my $arrayref = $polygon->arrayref; -isa_ok $arrayref, 'Slic3r::Polygon', 'Perl polygon is blessed'; -isa_ok $arrayref->[0], 'Slic3r::Point', 'Perl points are blessed'; +is ref($polygon->arrayref), 'ARRAY', 'polygon arrayref is unblessed'; +isa_ok $polygon->[0], 'Slic3r::Point', 'polygon point is blessed'; __END__ diff --git a/xs/t/07_extrusionpath.t b/xs/t/07_extrusionpath.t index b1420ff3b..54a86dbb3 100644 --- a/xs/t/07_extrusionpath.t +++ b/xs/t/07_extrusionpath.t @@ -13,20 +13,20 @@ my $points = [ ]; my $path = Slic3r::ExtrusionPath->new( - polyline => Slic3r::Polyline::XS->new(@$points), + polyline => Slic3r::Polyline->new(@$points), role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, ); -isa_ok $path->as_polyline, 'Slic3r::Polyline::XS', 'path polyline'; -is_deeply [ @{ $path->as_polyline->arrayref_pp } ], [ @$points ], 'path points roundtrip'; +isa_ok $path->as_polyline, 'Slic3r::Polyline', 'path polyline'; +is_deeply $path->as_polyline->pp, $points, 'path points roundtrip'; $path->reverse; -is_deeply [ @{ $path->as_polyline->arrayref_pp } ], [ reverse @$points ], 'reverse path'; +is_deeply $path->as_polyline->pp, [ reverse @$points ], 'reverse path'; $path->append([ 150, 150 ]); -is scalar(@{ $path }), 4, 'append to path'; +is scalar(@$path), 4, 'append to path'; $path->pop_back; -is scalar(@{ $path }), 3, 'pop_back from path'; +is scalar(@$path), 3, 'pop_back from path'; $path = $path->clone; diff --git a/xs/t/08_extrusionloop.t b/xs/t/08_extrusionloop.t index 98e4a6bdc..548431411 100644 --- a/xs/t/08_extrusionloop.t +++ b/xs/t/08_extrusionloop.t @@ -14,11 +14,11 @@ my $square = [ ]; my $loop = Slic3r::ExtrusionLoop->new( - polygon => Slic3r::Polygon::XS->new(@$square), + polygon => Slic3r::Polygon->new(@$square), role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, ); -isa_ok $loop->as_polygon, 'Slic3r::Polygon::XS', 'loop polygon'; -is_deeply [ @{ $loop->as_polygon->arrayref_pp } ], [ @$square ], 'polygon points roundtrip'; +isa_ok $loop->as_polygon, 'Slic3r::Polygon', 'loop polygon'; +is_deeply $loop->as_polygon->pp, $square, 'polygon points roundtrip'; $loop = $loop->clone; diff --git a/xs/xsp/ExPolygon.xsp b/xs/xsp/ExPolygon.xsp index 27cbac901..5869db39a 100644 --- a/xs/xsp/ExPolygon.xsp +++ b/xs/xsp/ExPolygon.xsp @@ -5,13 +5,13 @@ #include "ExPolygon.hpp" %} -%name{Slic3r::ExPolygon::XS} class ExPolygon { +%name{Slic3r::ExPolygon} class ExPolygon { ExPolygon* clone() - %code{% const char* CLASS = "Slic3r::ExPolygon::XS"; RETVAL = new ExPolygon(*THIS); RETVAL->in_collection = false; %}; + %code{% const char* CLASS = "Slic3r::ExPolygon"; RETVAL = new ExPolygon(*THIS); RETVAL->in_collection = false; %}; SV* arrayref() - %code{% RETVAL = THIS->to_SV(true, false); %}; - SV* arrayref_pp() - %code{% RETVAL = THIS->to_SV(true, true); %}; + %code{% RETVAL = THIS->to_SV(); %}; + SV* pp() + %code{% RETVAL = THIS->to_SV_pureperl(); %}; void scale(double factor); void translate(double x, double y); %{ @@ -42,29 +42,9 @@ ExPolygon::rotate(angle, center_sv) double angle; SV* center_sv; CODE: - Point* center; - if (sv_isobject(center_sv) && (SvTYPE(SvRV(center_sv)) == SVt_PVMG)) { - center = (Point*)SvIV((SV*)SvRV( center_sv )); - THIS->rotate(angle, center); - } else { - center = new Point; - perl2point(center_sv, *center); - THIS->rotate(angle, center); - delete center; - } + Point center; + center.from_SV_check(center_sv); + THIS->rotate(angle, ¢er); %} }; - -%package{Slic3r::ExPolygon::XS}; - -%{ -PROTOTYPES: DISABLE - -std::string -hello_world() - CODE: - RETVAL = "Hello world!"; - OUTPUT: - RETVAL -%} diff --git a/xs/xsp/ExPolygonCollection.xsp b/xs/xsp/ExPolygonCollection.xsp index d9375db2c..a8eafa541 100644 --- a/xs/xsp/ExPolygonCollection.xsp +++ b/xs/xsp/ExPolygonCollection.xsp @@ -23,7 +23,8 @@ ExPolygonCollection::new(...) // ST(0) is class name, others are expolygons RETVAL->expolygons.resize(items-1); for (unsigned int i = 1; i < items; i++) { - perl2expolygon_check(ST(i), RETVAL->expolygons[i-1]); + // Note: a COPY of the input is stored + RETVAL->expolygons[i-1].from_SV_check(ST(i)); RETVAL->expolygons[i-1].in_collection = true; } OUTPUT: @@ -36,20 +37,22 @@ ExPolygonCollection::arrayref() av_fill(av, THIS->expolygons.size()-1); int i = 0; for (ExPolygons::iterator it = THIS->expolygons.begin(); it != THIS->expolygons.end(); ++it) { - av_store(av, i++, (*it).to_SV(false, false)); + SV* sv = newSV(0); + sv_setref_pv( sv, "Slic3r::ExPolygon", &*it ); + av_store(av, i++, sv); } RETVAL = newRV_noinc((SV*)av); OUTPUT: RETVAL SV* -ExPolygonCollection::arrayref_pp() +ExPolygonCollection::pp() CODE: AV* av = newAV(); av_fill(av, THIS->expolygons.size()-1); int i = 0; for (ExPolygons::iterator it = THIS->expolygons.begin(); it != THIS->expolygons.end(); ++it) { - av_store(av, i++, (*it).to_SV(true, true)); + av_store(av, i++, (*it).to_SV_pureperl()); } RETVAL = newRV_noinc((SV*)av); OUTPUT: @@ -59,8 +62,10 @@ void ExPolygonCollection::append(...) CODE: for (unsigned int i = 1; i < items; i++) { - THIS->expolygons.push_back(*(ExPolygon *)SvIV((SV*)SvRV( ST(i) ))); - THIS->expolygons.back().in_collection = true; + ExPolygon expolygon; + expolygon.from_SV_check( ST(i) ); + expolygon.in_collection = true; + THIS->expolygons.push_back(expolygon); } %} diff --git a/xs/xsp/ExtrusionLoop.xsp b/xs/xsp/ExtrusionLoop.xsp index 2707dba65..ee5f32a22 100644 --- a/xs/xsp/ExtrusionLoop.xsp +++ b/xs/xsp/ExtrusionLoop.xsp @@ -8,11 +8,11 @@ %name{Slic3r::ExtrusionLoop} class ExtrusionLoop { ~ExtrusionLoop(); SV* arrayref() - %code{% RETVAL = THIS->polygon.to_SV(true, false); %}; - SV* arrayref_pp() - %code{% RETVAL = THIS->polygon.to_SV(true, true); %}; + %code{% RETVAL = THIS->polygon.to_SV(); %}; + SV* pp() + %code{% RETVAL = THIS->polygon.to_SV_pureperl(); %}; Polygon* as_polygon() - %code{% const char* CLASS = "Slic3r::Polygon::XS"; RETVAL = new Polygon(THIS->polygon); %}; + %code{% const char* CLASS = "Slic3r::Polygon"; RETVAL = new Polygon(THIS->polygon); %}; void set_polygon(SV* polygon_sv) %code{% THIS->polygon.from_SV_check(polygon_sv); %}; %{ diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp index 9a9def620..4294cc98a 100644 --- a/xs/xsp/ExtrusionPath.xsp +++ b/xs/xsp/ExtrusionPath.xsp @@ -8,11 +8,11 @@ %name{Slic3r::ExtrusionPath} class ExtrusionPath { ~ExtrusionPath(); SV* arrayref() - %code{% RETVAL = THIS->polyline.to_SV(true, false); %}; - SV* arrayref_pp() - %code{% RETVAL = THIS->polyline.to_SV(true, true); %}; + %code{% RETVAL = THIS->polyline.to_SV(); %}; + SV* pp() + %code{% RETVAL = THIS->polyline.to_SV_pureperl(); %}; Polyline* as_polyline() - %code{% const char* CLASS = "Slic3r::Polyline::XS"; RETVAL = new Polyline(THIS->polyline); %}; + %code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = new Polyline(THIS->polyline); %}; void set_polyline(SV* polyline_sv) %code{% THIS->polyline.from_SV_check(polyline_sv); %}; void pop_back() @@ -71,7 +71,7 @@ ExtrusionPath::append(...) CODE: for (unsigned int i = 1; i < items; i++) { Point p; - perl2point_check(ST(i), p); + p.from_SV_check(ST(i)); THIS->polyline.points.push_back(p); } diff --git a/xs/xsp/Line.xsp b/xs/xsp/Line.xsp new file mode 100644 index 000000000..b4ccb8d6f --- /dev/null +++ b/xs/xsp/Line.xsp @@ -0,0 +1,30 @@ +%module{Slic3r::XS}; + +%{ +#include +#include "Line.hpp" +%} + +%name{Slic3r::Line} class Line { + ~Line(); + Line* clone() + %code{% const char* CLASS = "Slic3r::Line"; RETVAL = new Line(*THIS); %}; + SV* arrayref() + %code{% RETVAL = THIS->to_SV(); %}; + SV* pp() + %code{% RETVAL = THIS->to_SV_pureperl(); %}; + void reverse(); +%{ + +Line* +Line::new(...) + CODE: + RETVAL = new Line (); + // ST(0) is class name, ST(1) and ST(2) are endpoints + RETVAL->a.from_SV_check( ST(1) ); + RETVAL->b.from_SV_check( ST(2) ); + OUTPUT: + RETVAL + +%} +}; diff --git a/xs/xsp/Point.xsp b/xs/xsp/Point.xsp index fea86adc6..e9a4c680c 100644 --- a/xs/xsp/Point.xsp +++ b/xs/xsp/Point.xsp @@ -13,7 +13,7 @@ void scale(double factor); void translate(double x, double y); SV* arrayref() - %code{% RETVAL = THIS->to_SV(true); %}; + %code{% RETVAL = THIS->to_SV_pureperl(); %}; unsigned long x() %code{% RETVAL = THIS->x; %}; unsigned long y() @@ -27,7 +27,7 @@ Point::rotate(angle, center_sv) SV* center_sv; CODE: Point center; - perl2point_check(center_sv, center); + center.from_SV_check(center_sv); THIS->rotate(angle, ¢er); bool @@ -35,7 +35,7 @@ Point::coincides_with(point_sv) SV* point_sv; CODE: Point point; - perl2point_check(point_sv, point); + point.from_SV_check(point_sv); RETVAL = THIS->coincides_with(&point); OUTPUT: RETVAL diff --git a/xs/xsp/Polygon.xsp b/xs/xsp/Polygon.xsp index 19bba68fd..a1f56ee29 100644 --- a/xs/xsp/Polygon.xsp +++ b/xs/xsp/Polygon.xsp @@ -5,14 +5,16 @@ #include "Polygon.hpp" %} -%name{Slic3r::Polygon::XS} class Polygon { +%name{Slic3r::Polygon} class Polygon { ~Polygon(); Polygon* clone() - %code{% const char* CLASS = "Slic3r::Polygon::XS"; RETVAL = new Polygon(*THIS); %}; + %code{% const char* CLASS = "Slic3r::Polygon"; RETVAL = new Polygon(*THIS); %}; SV* arrayref() - %code{% RETVAL = THIS->to_SV(true, false); %}; - SV* arrayref_pp() - %code{% RETVAL = THIS->to_SV(true, true); %}; + %code{% RETVAL = THIS->to_SV(); %}; + SV* pp() + %code{% RETVAL = THIS->to_SV_pureperl(); %}; + void scale(double factor); + void translate(double x, double y); %{ Polygon* @@ -22,7 +24,7 @@ Polygon::new(...) // ST(0) is class name, ST(1) is first point RETVAL->points.resize(items-1); for (unsigned int i = 1; i < items; i++) { - perl2point(ST(i), RETVAL->points[i-1]); + RETVAL->points[i-1].from_SV_check( ST(i) ); } OUTPUT: RETVAL diff --git a/xs/xsp/Polyline.xsp b/xs/xsp/Polyline.xsp index 02aad589b..11e0500d5 100644 --- a/xs/xsp/Polyline.xsp +++ b/xs/xsp/Polyline.xsp @@ -5,14 +5,14 @@ #include "Polyline.hpp" %} -%name{Slic3r::Polyline::XS} class Polyline { +%name{Slic3r::Polyline} class Polyline { ~Polyline(); Polyline* clone() - %code{% const char* CLASS = "Slic3r::Polyline::XS"; RETVAL = new Polyline(*THIS); %}; + %code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = new Polyline(*THIS); %}; SV* arrayref() - %code{% RETVAL = THIS->to_SV(true, false); %}; - SV* arrayref_pp() - %code{% RETVAL = THIS->to_SV(true, true); %}; + %code{% RETVAL = THIS->to_SV(); %}; + SV* pp() + %code{% RETVAL = THIS->to_SV_pureperl(); %}; void pop_back() %code{% THIS->points.pop_back(); %}; void reverse(); @@ -25,7 +25,7 @@ Polyline::new(...) // ST(0) is class name, ST(1) is first point RETVAL->points.resize(items-1); for (unsigned int i = 1; i < items; i++) { - perl2point(ST(i), RETVAL->points[i-1]); + RETVAL->points[i-1].from_SV_check( ST(i) ); } OUTPUT: RETVAL @@ -35,11 +35,7 @@ Polyline::append(...) CODE: for (unsigned int i = 1; i < items; i++) { Point p; - if (sv_isobject(ST(i)) && (SvTYPE(SvRV(ST(i))) == SVt_PVMG)) { - p = *(Point*)SvIV((SV*)SvRV( ST(i) )); - } else { - perl2point(ST(i), p); - } + p.from_SV_check( ST(1) ); THIS->points.push_back(p); } diff --git a/xs/xsp/Surface.xsp b/xs/xsp/Surface.xsp index 067289ffe..71f0dfa1b 100644 --- a/xs/xsp/Surface.xsp +++ b/xs/xsp/Surface.xsp @@ -7,7 +7,7 @@ %name{Slic3r::Surface} class Surface { ExPolygon* expolygon() - %code{% const char* CLASS = "Slic3r::ExPolygon::XS"; RETVAL = new ExPolygon(THIS->expolygon); %}; + %code{% const char* CLASS = "Slic3r::ExPolygon"; RETVAL = new ExPolygon(THIS->expolygon); %}; double thickness() %code{% RETVAL = THIS->thickness; %}; unsigned short thickness_layers() diff --git a/xs/xsp/SurfaceCollection.xsp b/xs/xsp/SurfaceCollection.xsp index 2cd9df3ae..42f59815a 100644 --- a/xs/xsp/SurfaceCollection.xsp +++ b/xs/xsp/SurfaceCollection.xsp @@ -18,6 +18,7 @@ SurfaceCollection::new(...) // ST(0) is class name, others are surfaces RETVAL->surfaces.resize(items-1); for (unsigned int i = 1; i < items; i++) { + // Note: a COPY of the input is stored RETVAL->surfaces[i-1] = *(Surface *)SvIV((SV*)SvRV( ST(i) )); RETVAL->surfaces[i-1].in_collection = true; } diff --git a/xs/xsp/my.map b/xs/xsp/my.map index 7e565f533..a1f66e08e 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -1,6 +1,7 @@ ZTable* O_OBJECT TriangleMesh* O_OBJECT Point* O_OBJECT +Line* O_OBJECT Polyline* O_OBJECT Polygon* O_OBJECT ExPolygon* O_OBJECT