Ported ExtrusionPath to XS. Failing test for Surface

This commit is contained in:
Alessandro Ranellucci 2013-07-15 12:14:22 +02:00
parent 8c1e1cc3ea
commit f612d4c64e
24 changed files with 501 additions and 143 deletions

View file

@ -15,10 +15,78 @@ package Slic3r::ExPolygon::XS;
use overload
'@{}' => sub { $_[0]->arrayref };
package Slic3r::Polyline::XS;
use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
package Slic3r::Polygon::XS;
use overload
'@{}' => sub { $_[0]->arrayref };
package Slic3r::ExPolygon::Collection;
use overload
'@{}' => sub { $_[0]->arrayref };
package Slic3r::ExtrusionLoop;
sub new {
my ($class, %args) = @_;
my $polygon = ref($args{polygon}) eq 'Slic3r::Polygon::XS'
? $args{polygon}
: Slic3r::Polygon::XS->new(@{$args{polygon}});
return $class->_new(
$polygon, # required
$args{role}, # required
$args{height} // -1,
$args{flow_spacing} // -1,
);
}
sub clone {
my ($self, %args) = @_;
return (ref $self)->_new(
$args{polygon} // $self->polygon->clone,
$args{role} // $self->role,
$args{height} // $self->height,
$args{flow_spacing} // $self->flow_spacing,
);
}
package Slic3r::ExtrusionPath;
use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
sub new {
my ($class, %args) = @_;
my $polyline = ref($args{polyline}) eq 'Slic3r::Polyline::XS'
? $args{polyline}
: Slic3r::Polyline::XS->new(@{$args{polyline}});
return $class->_new(
$polyline, # required
$args{role}, # required
$args{height} // -1,
$args{flow_spacing} // -1,
);
}
sub clone {
my ($self, %args) = @_;
return (ref $self)->_new(
$args{polyline} // $self->as_polyline,
$args{role} // $self->role,
$args{height} // $self->height,
$args{flow_spacing} // $self->flow_spacing,
);
}
package Slic3r::Surface;
sub new {
@ -29,12 +97,12 @@ sub new {
if defined $args{bridge_angle} && $args{bridge_angle} < 0;
return $class->_new(
delete $args{expolygon}, # required
delete $args{surface_type}, # required
delete $args{thickness} // -1,
delete $args{thickness_layers} // 1,
delete $args{bridge_angle} // -1,
delete $args{extra_perimeters} // 0,
$args{expolygon} // (die "Missing required expolygon\n"),
$args{surface_type} // (die "Missing required surface_type\n"),
$args{thickness} // -1,
$args{thickness_layers} // 1,
$args{bridge_angle} // -1,
$args{extra_perimeters} // 0,
);
}

View file

@ -0,0 +1,60 @@
#ifndef slic3r_ExtrusionEntity_hpp_
#define slic3r_ExtrusionEntity_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include "Polygon.hpp"
#include "Polyline.hpp"
namespace Slic3r {
enum ExtrusionRole {
erPerimeter,
erExternalPerimeter,
erOverhangPerimeter,
erContourInternalPerimeter,
erFill,
erSolidFill,
erTopSolidFill,
erBrige,
erInternalBridge,
erSkirt,
erSupportMaterial,
erGapFill,
};
class ExtrusionEntity
{
public:
ExtrusionRole role;
double height; // vertical thickness of the extrusion expressed in mm
double flow_spacing;
};
class ExtrusionPath : public ExtrusionEntity
{
public:
Polyline polyline;
void reverse();
};
class ExtrusionLoop : public ExtrusionEntity
{
public:
Polygon polygon;
};
void
ExtrusionPath::reverse()
{
this->polyline.reverse();
}
}
#endif

View file

@ -9,6 +9,7 @@ extern "C" {
}
#include "Point.hpp"
#include <algorithm>
namespace Slic3r {
@ -19,6 +20,7 @@ class Polyline
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
void reverse();
};
typedef std::vector<Polyline> Polylines;
@ -49,6 +51,12 @@ Polyline::rotate(double angle, Point* center)
}
}
void
Polyline::reverse()
{
std::reverse(this->points.begin(), this->points.end());
}
void
perl2polyline(SV* poly_sv, Polyline& poly)
{

View file

@ -4,7 +4,7 @@ use strict;
use warnings;
use Slic3r::XS;
use Test::More tests => 10;
use Test::More tests => 11;
my $square = [ # ccw
[100, 100],
@ -49,6 +49,10 @@ is $surface->extra_perimeters, 2, 'extra_perimeters';
is scalar(@$collection), 0, 'clear collection';
$collection->append($surface);
is scalar(@$collection), 1, 'append to collection';
my $item = $collection->[0];
$item->surface_type(Slic3r::Surface::S_TYPE_INTERNAL);
is $item->surface_type, $collection->[0]->surface_type, 'changing item affects actual item';
}
__END__

22
xs/t/06_polygon.t Normal file
View file

@ -0,0 +1,22 @@
#!/usr/bin/perl
use strict;
use warnings;
use Slic3r::XS;
use Test::More tests => 3;
my $square = [ # ccw
[100, 100],
[200, 100],
[200, 200],
[100, 200],
];
my $polygon = Slic3r::Polygon::XS->new(@$square);
is_deeply [ @$polygon ], [ @$square ], 'polygon roundtrip';
isa_ok $polygon->arrayref, 'Slic3r::Polygon', 'Perl polygon is blessed';
isa_ok $polygon->[0], 'Slic3r::Point', 'Perl points are blessed';
__END__

37
xs/t/07_extrusionpath.t Normal file
View file

@ -0,0 +1,37 @@
#!/usr/bin/perl
use strict;
use warnings;
use Slic3r::XS;
use Test::More tests => 7;
my $points = [
[100, 100],
[200, 100],
[200, 200],
];
my $path = Slic3r::ExtrusionPath->new(
polyline => Slic3r::Polyline::XS->new(@$points),
role => Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER,
);
isa_ok $path->as_polyline, 'Slic3r::Polyline::XS', 'path polyline';
is_deeply [ @{ $path->as_polyline } ], [ @$points ], 'path points roundtrip';
$path->reverse;
is_deeply [ @{ $path->as_polyline } ], [ reverse @$points ], 'reverse path';
$path->append([ 150, 150 ]);
is scalar(@{ $path }), 4, 'append to path';
$path->pop_back;
is scalar(@{ $path }), 3, 'pop_back from path';
$path = $path->clone;
is $path->role, Slic3r::ExtrusionPath::EXTR_ROLE_EXTERNAL_PERIMETER, 'role';
$path->role(Slic3r::ExtrusionPath::EXTR_ROLE_FILL);
is $path->role, Slic3r::ExtrusionPath::EXTR_ROLE_FILL, 'modify role';
__END__

126
xs/xsp/ExtrusionPath.xsp Normal file
View file

@ -0,0 +1,126 @@
%module{Slic3r::XS};
%{
#include <myinit.h>
#include "ExtrusionEntity.hpp"
%}
%name{Slic3r::ExtrusionPath} class ExtrusionPath {
~ExtrusionPath();
SV* arrayref()
%code{% RETVAL = polyline2perl(THIS->polyline); %};
void pop_back()
%code{% THIS->polyline.points.pop_back(); %};
void reverse();
%{
ExtrusionPath*
_new(CLASS, polyline_sv, role, height, flow_spacing)
char* CLASS;
SV* polyline_sv;
ExtrusionRole role;
double height;
double flow_spacing;
CODE:
RETVAL = new ExtrusionPath ();
if (sv_isobject(polyline_sv) && (SvTYPE(SvRV(polyline_sv)) == SVt_PVMG)) {
RETVAL->polyline = *(Polyline*)SvIV((SV*)SvRV( polyline_sv ));
} else {
perl2polyline(polyline_sv, RETVAL->polyline);
}
RETVAL->role = role;
RETVAL->height = height;
RETVAL->flow_spacing = flow_spacing;
OUTPUT:
RETVAL
Polyline*
ExtrusionPath::as_polyline()
PREINIT:
const char* CLASS = "Slic3r::Polyline::XS";
CODE:
RETVAL = new Polyline(THIS->polyline);
OUTPUT:
RETVAL
void
ExtrusionPath::set_polyline(polyline_sv)
SV* polyline_sv;
CODE:
if (sv_isobject(polyline_sv) && (SvTYPE(SvRV(polyline_sv)) == SVt_PVMG)) {
THIS->polyline = *(Polyline*)SvIV((SV*)SvRV( polyline_sv ));
} else {
perl2polyline(polyline_sv, THIS->polyline);
}
ExtrusionRole
ExtrusionPath::role(...)
CODE:
if (items > 1) {
THIS->role = (ExtrusionRole)SvUV(ST(1));
}
RETVAL = THIS->role;
OUTPUT:
RETVAL
double
ExtrusionPath::height(...)
CODE:
if (items > 1) {
THIS->height = (double)SvNV(ST(1));
}
RETVAL = THIS->height;
OUTPUT:
RETVAL
double
ExtrusionPath::flow_spacing(...)
CODE:
if (items > 1) {
THIS->flow_spacing = (double)SvNV(ST(1));
}
RETVAL = THIS->flow_spacing;
OUTPUT:
RETVAL
void
ExtrusionPath::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);
}
THIS->polyline.points.push_back(p);
}
%}
};
%package{Slic3r::ExtrusionPath};
%{
IV
_constant()
ALIAS:
EXTR_ROLE_PERIMETER = erPerimeter
EXTR_ROLE_EXTERNAL_PERIMETER = erExternalPerimeter
EXTR_ROLE_OVERHANG_PERIMETER = erOverhangPerimeter
EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER = erContourInternalPerimeter
EXTR_ROLE_FILL = erFill
EXTR_ROLE_SOLIDFILL = erSolidFill
EXTR_ROLE_TOPSOLIDFILL = erTopSolidFill
EXTR_ROLE_BRIDGE = erBrige
EXTR_ROLE_INTERNALBRIDGE = erInternalBridge
EXTR_ROLE_SKIRT = erSkirt
EXTR_ROLE_SUPPORTMATERIAL = erSupportMaterial
EXTR_ROLE_GAPFILL = erGapFill
PROTOTYPE:
CODE:
RETVAL = ix;
OUTPUT: RETVAL
%}

29
xs/xsp/Polygon.xsp Normal file
View file

@ -0,0 +1,29 @@
%module{Slic3r::XS};
%{
#include <myinit.h>
#include "Polygon.hpp"
%}
%name{Slic3r::Polygon::XS} class Polygon {
~Polygon();
Polygon* clone()
%code{% const char* CLASS = "Slic3r::Polygon::XS"; RETVAL = new Polygon(*THIS); %};
SV* arrayref()
%code{% RETVAL = polygon2perl(*THIS); %};
%{
Polygon*
Polygon::new(...)
CODE:
RETVAL = new Polygon ();
// 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]);
}
OUTPUT:
RETVAL
%}
};

45
xs/xsp/Polyline.xsp Normal file
View file

@ -0,0 +1,45 @@
%module{Slic3r::XS};
%{
#include <myinit.h>
#include "Polyline.hpp"
%}
%name{Slic3r::Polyline::XS} class Polyline {
~Polyline();
Polyline* clone()
%code{% const char* CLASS = "Slic3r::Polyline::XS"; RETVAL = new Polyline(*THIS); %};
SV* arrayref()
%code{% RETVAL = polyline2perl(*THIS); %};
void pop_back()
%code{% THIS->points.pop_back(); %};
void reverse();
%{
Polyline*
Polyline::new(...)
CODE:
RETVAL = new Polyline ();
// 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]);
}
OUTPUT:
RETVAL
void
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);
}
THIS->points.push_back(p);
}
%}
};

View file

@ -1,8 +1,14 @@
ZTable* O_OBJECT
TriangleMesh* O_OBJECT
Point* O_OBJECT
Polyline* O_OBJECT
Polygon* O_OBJECT
ExPolygon* O_OBJECT
ExPolygonCollection* O_OBJECT
SurfaceType T_UV
ExtrusionPath* O_OBJECT
ExtrusionLoop* O_OBJECT
Surface* O_OBJECT
SurfaceCollection* O_OBJECT
ExtrusionRole T_UV
SurfaceType T_UV

View file

@ -4,9 +4,17 @@
%typemap{AV*};
%typemap{Point*};
%typemap{ExPolygon*};
%typemap{Polyline*};
%typemap{Polygon*};
%typemap{SurfaceType}{parsed}{
%cpp_type{SurfaceType};
%precall_code{%
$CVar = (SurfaceType)SvUV($PerlVar);
%};
};
};
%typemap{ExtrusionRole}{parsed}{
%cpp_type{ExtrusionRole};
%precall_code{%
$CVar = (ExtrusionRole)SvUV($PerlVar);
%};
};