Better polymorphism for ExPolygon::XS->rotate

This commit is contained in:
Alessandro Ranellucci 2013-07-14 16:03:06 +02:00
parent 28a4f1a61e
commit 06de21b154
6 changed files with 32 additions and 21 deletions

View File

@ -15,15 +15,6 @@ package Slic3r::ExPolygon::XS;
use overload use overload
'@{}' => sub { $_[0]->arrayref }; '@{}' => sub { $_[0]->arrayref };
# to handle legacy code
sub rotate {
my $self = shift;
my ($angle, $center) = @_;
$center = Slic3r::Point::XS->new(@$center) if ref($center) ne 'Slic3r::Point::XS';
$self->_rotate($angle, $center);
}
package Slic3r::ExPolygon::Collection; package Slic3r::ExPolygon::Collection;
use overload use overload
'@{}' => sub { $_[0]->arrayref }; '@{}' => sub { $_[0]->arrayref };

View File

@ -20,7 +20,7 @@ class ExPolygon
SV* arrayref(); SV* arrayref();
void scale(double factor); void scale(double factor);
void translate(double x, double y); void translate(double x, double y);
void _rotate(double angle, Point* center); void rotate(double angle, Point* center);
}; };
typedef std::vector<ExPolygon> ExPolygons; typedef std::vector<ExPolygon> ExPolygons;
@ -44,11 +44,11 @@ ExPolygon::translate(double x, double y)
} }
void void
ExPolygon::_rotate(double angle, Point* center) ExPolygon::rotate(double angle, Point* center)
{ {
contour._rotate(angle, center); contour.rotate(angle, center);
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) { for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
(*it)._rotate(angle, center); (*it).rotate(angle, center);
} }
} }

View File

@ -42,7 +42,7 @@ void
ExPolygonCollection::rotate(double angle, Point* center) ExPolygonCollection::rotate(double angle, Point* center)
{ {
for (ExPolygons::iterator it = expolygons.begin(); it != expolygons.end(); ++it) { for (ExPolygons::iterator it = expolygons.begin(); it != expolygons.end(); ++it) {
(*it)._rotate(angle, center); (*it).rotate(angle, center);
} }
} }

View File

@ -40,6 +40,14 @@ point2perl(Point& point) {
return sv_bless(newRV_noinc((SV*)av), gv_stashpv("Slic3r::Point", GV_ADD)); return sv_bless(newRV_noinc((SV*)av), gv_stashpv("Slic3r::Point", GV_ADD));
} }
void
perl2point(SV* point_sv, Point& point)
{
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));
}
} }
#endif #endif

View File

@ -18,7 +18,7 @@ class Polygon
Points points; Points points;
void scale(double factor); void scale(double factor);
void translate(double x, double y); void translate(double x, double y);
void _rotate(double angle, Point* center); void rotate(double angle, Point* center);
}; };
typedef std::vector<Polygon> Polygons; typedef std::vector<Polygon> Polygons;
@ -42,7 +42,7 @@ Polygon::translate(double x, double y)
} }
void void
Polygon::_rotate(double angle, Point* center) Polygon::rotate(double angle, Point* center)
{ {
for (Points::iterator it = points.begin(); it != points.end(); ++it) { for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).rotate(angle, center); (*it).rotate(angle, center);
@ -58,10 +58,7 @@ perl2polygon(SV* poly_sv, Polygon& poly)
for (unsigned int i = 0; i < num_points; i++) { for (unsigned int i = 0; i < num_points; i++) {
SV** point_sv = av_fetch(poly_av, i, 0); SV** point_sv = av_fetch(poly_av, i, 0);
AV* point_av = (AV*)SvRV(*point_sv); perl2point(*point_sv, poly.points[i]);
Point& p = poly.points[i];
p.x = (unsigned long)SvIV(*av_fetch(point_av, 0, 0));
p.y = (unsigned long)SvIV(*av_fetch(point_av, 1, 0));
} }
} }

View File

@ -13,7 +13,6 @@
%code{% RETVAL = expolygon2perl(*THIS); %}; %code{% RETVAL = expolygon2perl(*THIS); %};
void scale(double factor); void scale(double factor);
void translate(double x, double y); void translate(double x, double y);
void _rotate(double angle, Point* center);
%{ %{
ExPolygon* ExPolygon*
@ -29,6 +28,22 @@ ExPolygon::new(...)
OUTPUT: OUTPUT:
RETVAL RETVAL
void
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;
}
%} %}
}; };