mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-09 14:55:08 -06:00
Ported ExtrusionPath to XS. Failing test for Surface
This commit is contained in:
parent
8c1e1cc3ea
commit
f612d4c64e
24 changed files with 501 additions and 143 deletions
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
60
xs/src/ExtrusionEntity.hpp
Normal file
60
xs/src/ExtrusionEntity.hpp
Normal 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
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
22
xs/t/06_polygon.t
Normal 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
37
xs/t/07_extrusionpath.t
Normal 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
126
xs/xsp/ExtrusionPath.xsp
Normal 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
29
xs/xsp/Polygon.xsp
Normal 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
45
xs/xsp/Polyline.xsp
Normal 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);
|
||||
}
|
||||
|
||||
%}
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
%};
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue