mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Ported Slic3r::Surface to XS
This commit is contained in:
		
							parent
							
								
									b1ad466189
								
							
						
					
					
						commit
						399bc80899
					
				
					 8 changed files with 207 additions and 63 deletions
				
			
		|  | @ -32,6 +32,7 @@ use Encode::Locale; | ||||||
| use Boost::Geometry::Utils 0.15; | use Boost::Geometry::Utils 0.15; | ||||||
| use Moo 0.091009; | use Moo 0.091009; | ||||||
| 
 | 
 | ||||||
|  | use Slic3r::XS;   # import all symbols (constants etc.) before they get parsed | ||||||
| use Slic3r::Config; | use Slic3r::Config; | ||||||
| use Slic3r::ExPolygon; | use Slic3r::ExPolygon; | ||||||
| use Slic3r::Extruder; | use Slic3r::Extruder; | ||||||
|  | @ -65,7 +66,6 @@ use Slic3r::Print::Object; | ||||||
| use Slic3r::Print::Region; | use Slic3r::Print::Region; | ||||||
| use Slic3r::Surface; | use Slic3r::Surface; | ||||||
| use Slic3r::TriangleMesh; | use Slic3r::TriangleMesh; | ||||||
| use Slic3r::XS; |  | ||||||
| our $build = eval "use Slic3r::Build; 1"; | our $build = eval "use Slic3r::Build; 1"; | ||||||
| 
 | 
 | ||||||
| use constant SCALING_FACTOR         => 0.000001; | use constant SCALING_FACTOR         => 0.000001; | ||||||
|  | @ -113,6 +113,7 @@ sub thread_cleanup { | ||||||
|     *Slic3r::ExPolygon::Collection::DESTROY = sub {}; |     *Slic3r::ExPolygon::Collection::DESTROY = sub {}; | ||||||
|     *Slic3r::ExPolygon::XS::DESTROY = sub {}; |     *Slic3r::ExPolygon::XS::DESTROY = sub {}; | ||||||
|     *Slic3r::Point::XS::DESTROY     = sub {}; |     *Slic3r::Point::XS::DESTROY     = sub {}; | ||||||
|  |     *Slic3r::Surface::DESTROY       = sub {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub encode_path { | sub encode_path { | ||||||
|  |  | ||||||
|  | @ -7,67 +7,6 @@ our @ISA = qw(Exporter); | ||||||
| our @EXPORT_OK   = qw(S_TYPE_TOP S_TYPE_BOTTOM S_TYPE_INTERNAL S_TYPE_INTERNALSOLID S_TYPE_INTERNALBRIDGE S_TYPE_INTERNALVOID); | our @EXPORT_OK   = qw(S_TYPE_TOP S_TYPE_BOTTOM S_TYPE_INTERNAL S_TYPE_INTERNALSOLID S_TYPE_INTERNALBRIDGE S_TYPE_INTERNALVOID); | ||||||
| our %EXPORT_TAGS = (types => \@EXPORT_OK); | our %EXPORT_TAGS = (types => \@EXPORT_OK); | ||||||
| 
 | 
 | ||||||
| use constant S_EXPOLYGON            => 0; |  | ||||||
| use constant S_SURFACE_TYPE         => 1; |  | ||||||
| use constant S_THICKNESS            => 2;  # in mm |  | ||||||
| use constant S_THICKNESS_LAYERS     => 3;  # in layers |  | ||||||
| use constant S_BRIDGE_ANGLE         => 4; |  | ||||||
| use constant S_EXTRA_PERIMETERS     => 5; |  | ||||||
| 
 |  | ||||||
| use constant S_TYPE_TOP             => 0; |  | ||||||
| use constant S_TYPE_BOTTOM          => 1; |  | ||||||
| use constant S_TYPE_INTERNAL        => 2; |  | ||||||
| use constant S_TYPE_INTERNALSOLID   => 3; |  | ||||||
| use constant S_TYPE_INTERNALBRIDGE  => 4; |  | ||||||
| use constant S_TYPE_INTERNALVOID    => 5; |  | ||||||
| 
 |  | ||||||
| sub new { |  | ||||||
|     my $class = shift; |  | ||||||
|     my %args = @_; |  | ||||||
|      |  | ||||||
|     my $self = [ |  | ||||||
|         map delete $args{$_}, qw(expolygon surface_type thickness thickness_layers bridge_angle extra_perimeters), |  | ||||||
|     ]; |  | ||||||
|     $self->[S_THICKNESS_LAYERS] //= 1; |  | ||||||
|      |  | ||||||
|     bless $self, $class; |  | ||||||
|     $self; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| sub clone { |  | ||||||
|     my $self = shift; |  | ||||||
|     my %p = @_; |  | ||||||
|      |  | ||||||
|     return (ref $self)->new( |  | ||||||
|         (map { $_ => $self->$_ } qw(surface_type thickness thickness_layers bridge_angle)), |  | ||||||
|         expolygon => (defined $p{expolygon} ? delete $p{expolygon} : $self->expolygon->clone), |  | ||||||
|         %p, |  | ||||||
|     ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| sub expolygon       { $_[0][S_EXPOLYGON] } |  | ||||||
| sub surface_type    { $_[0][S_SURFACE_TYPE] = $_[1] if defined $_[1]; $_[0][S_SURFACE_TYPE] } |  | ||||||
| sub thickness       { $_[0][S_THICKNESS] } |  | ||||||
| sub thickness_layers    { $_[0][S_THICKNESS_LAYERS] } |  | ||||||
| sub bridge_angle    { $_[0][S_BRIDGE_ANGLE] = $_[1] if defined $_[1]; $_[0][S_BRIDGE_ANGLE] } |  | ||||||
| sub extra_perimeters { $_[0][S_EXTRA_PERIMETERS] = $_[1] if defined $_[1]; $_[0][S_EXTRA_PERIMETERS] } |  | ||||||
| 
 |  | ||||||
| if (eval "use Class::XSAccessor::Array; 1") { |  | ||||||
|     Class::XSAccessor::Array->import( |  | ||||||
|         getters => { |  | ||||||
|             expolygon           => S_EXPOLYGON, |  | ||||||
|         }, |  | ||||||
|         accessors => { |  | ||||||
|             surface_type        => S_SURFACE_TYPE, |  | ||||||
|             thickness           => S_THICKNESS, |  | ||||||
|             thickness_layers    => S_THICKNESS_LAYERS, |  | ||||||
|             bridge_angle        => S_BRIDGE_ANGLE, |  | ||||||
|             extra_perimeters    => S_EXTRA_PERIMETERS, |  | ||||||
|         }, |  | ||||||
|         replace => 1, |  | ||||||
|     ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| # delegate handles | # delegate handles | ||||||
| sub encloses_point  { $_[0]->expolygon->encloses_point } | sub encloses_point  { $_[0]->expolygon->encloses_point } | ||||||
| sub lines           { $_[0]->expolygon->lines } | sub lines           { $_[0]->expolygon->lines } | ||||||
|  |  | ||||||
|  | @ -32,4 +32,36 @@ use overload | ||||||
| 
 | 
 | ||||||
| sub clone { (ref $_[0])->_clone($_[0]) } | sub clone { (ref $_[0])->_clone($_[0]) } | ||||||
| 
 | 
 | ||||||
|  | package Slic3r::Surface; | ||||||
|  | 
 | ||||||
|  | sub new { | ||||||
|  |     my ($class, %args) = @_; | ||||||
|  |      | ||||||
|  |     # defensive programming: make sure no negative bridge_angle is supplied | ||||||
|  |     die "Error: invalid negative bridge_angle\n" | ||||||
|  |         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, | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | sub clone { | ||||||
|  |     my ($self, %args) = @_; | ||||||
|  |      | ||||||
|  |     return (ref $self)->_new( | ||||||
|  |         delete $args{expolygon}         // $self->expolygon->clone, | ||||||
|  |         delete $args{surface_type}      // $self->surface_type, | ||||||
|  |         delete $args{thickness}         // $self->thickness, | ||||||
|  |         delete $args{thickness_layers}  // $self->thickness_layers, | ||||||
|  |         delete $args{bridge_angle}      // $self->bridge_angle, | ||||||
|  |         delete $args{extra_perimeters}  // $self->extra_perimeters, | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 1; | 1; | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								xs/src/Surface.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								xs/src/Surface.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | ||||||
|  | #ifndef slic3r_Surface_hpp_ | ||||||
|  | #define slic3r_Surface_hpp_ | ||||||
|  | 
 | ||||||
|  | extern "C" { | ||||||
|  | #include "EXTERN.h" | ||||||
|  | #include "perl.h" | ||||||
|  | #include "XSUB.h" | ||||||
|  | #include "ppport.h" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #include "ExPolygon.hpp" | ||||||
|  | 
 | ||||||
|  | namespace Slic3r { | ||||||
|  | 
 | ||||||
|  | enum SurfaceType { stTop, stBottom, stInternal, stInternalSolid, stInternalBridge, stInternalVoid }; | ||||||
|  | 
 | ||||||
|  | class Surface | ||||||
|  | { | ||||||
|  |     public: | ||||||
|  |     ExPolygon       expolygon; | ||||||
|  |     SurfaceType     surface_type; | ||||||
|  |     double          thickness;          // in mm
 | ||||||
|  |     unsigned short  thickness_layers;   // in layers
 | ||||||
|  |     double          bridge_angle; | ||||||
|  |     unsigned short  extra_perimeters; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										43
									
								
								xs/t/05_surface.t
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								xs/t/05_surface.t
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | ||||||
|  | #!/usr/bin/perl | ||||||
|  | 
 | ||||||
|  | use strict; | ||||||
|  | use warnings; | ||||||
|  | 
 | ||||||
|  | use Slic3r::XS; | ||||||
|  | use Test::More tests => 6; | ||||||
|  | 
 | ||||||
|  | my $square = [  # ccw | ||||||
|  |     [100, 100], | ||||||
|  |     [200, 100], | ||||||
|  |     [200, 200], | ||||||
|  |     [100, 200], | ||||||
|  | ]; | ||||||
|  | my $hole_in_square = [  # cw | ||||||
|  |     [140, 140], | ||||||
|  |     [140, 160], | ||||||
|  |     [160, 160], | ||||||
|  |     [160, 140], | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | my $expolygon = Slic3r::ExPolygon::XS->new($square, $hole_in_square); | ||||||
|  | my $surface = Slic3r::Surface->new( | ||||||
|  |     expolygon => $expolygon, | ||||||
|  |     surface_type => Slic3r::Surface::S_TYPE_INTERNAL, | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | $surface = $surface->clone; | ||||||
|  | 
 | ||||||
|  | isa_ok $surface->expolygon, 'Slic3r::ExPolygon::XS', 'expolygon'; | ||||||
|  | is_deeply [ @{$surface->expolygon} ], [$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); | ||||||
|  | is $surface->surface_type, Slic3r::Surface::S_TYPE_BOTTOM, 'modify surface_type'; | ||||||
|  | 
 | ||||||
|  | $surface->bridge_angle(30); | ||||||
|  | is $surface->bridge_angle, 30, 'bridge_angle'; | ||||||
|  | 
 | ||||||
|  | $surface->extra_perimeters(2); | ||||||
|  | is $surface->extra_perimeters, 2, 'extra_perimeters'; | ||||||
|  | 
 | ||||||
|  | __END__ | ||||||
							
								
								
									
										90
									
								
								xs/xsp/Surface.xsp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								xs/xsp/Surface.xsp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,90 @@ | ||||||
|  | %module{Slic3r::XS}; | ||||||
|  | 
 | ||||||
|  | %{ | ||||||
|  | #include <myinit.h> | ||||||
|  | #include "Surface.hpp" | ||||||
|  | %} | ||||||
|  | 
 | ||||||
|  | %name{Slic3r::Surface} class Surface { | ||||||
|  |     %name{_clone} Surface(Surface& self); | ||||||
|  |     ~Surface(); | ||||||
|  |     ExPolygon* expolygon() | ||||||
|  |         %code{% const char* CLASS = "Slic3r::ExPolygon::XS"; RETVAL = new ExPolygon(THIS->expolygon); %}; | ||||||
|  |     double thickness() | ||||||
|  |         %code{% RETVAL = THIS->thickness; %}; | ||||||
|  |     unsigned short thickness_layers() | ||||||
|  |         %code{% RETVAL = THIS->thickness_layers; %}; | ||||||
|  | %{ | ||||||
|  | 
 | ||||||
|  | Surface* | ||||||
|  | _new(CLASS, expolygon, surface_type, thickness, thickness_layers, bridge_angle, extra_perimeters) | ||||||
|  |     char*           CLASS; | ||||||
|  |     ExPolygon*      expolygon; | ||||||
|  |     SurfaceType     surface_type; | ||||||
|  |     double          thickness; | ||||||
|  |     unsigned short  thickness_layers; | ||||||
|  |     double          bridge_angle; | ||||||
|  |     unsigned short  extra_perimeters; | ||||||
|  |     CODE: | ||||||
|  |         RETVAL = new Surface (); | ||||||
|  |         RETVAL->expolygon           = *expolygon; | ||||||
|  |         RETVAL->surface_type        = surface_type; | ||||||
|  |         RETVAL->thickness           = thickness; | ||||||
|  |         RETVAL->thickness_layers    = thickness_layers; | ||||||
|  |         RETVAL->bridge_angle        = bridge_angle; | ||||||
|  |         RETVAL->extra_perimeters    = extra_perimeters; | ||||||
|  |     OUTPUT: | ||||||
|  |         RETVAL | ||||||
|  | 
 | ||||||
|  | SurfaceType | ||||||
|  | Surface::surface_type(...) | ||||||
|  |     CODE: | ||||||
|  |         if (items > 1) { | ||||||
|  |             THIS->surface_type = (SurfaceType)SvUV(ST(1)); | ||||||
|  |         } | ||||||
|  |         RETVAL = THIS->surface_type; | ||||||
|  |     OUTPUT: | ||||||
|  |         RETVAL | ||||||
|  | 
 | ||||||
|  | double | ||||||
|  | Surface::bridge_angle(...) | ||||||
|  |     CODE: | ||||||
|  |         if (items > 1) { | ||||||
|  |             THIS->bridge_angle = (double)SvNV(ST(1)); | ||||||
|  |         } | ||||||
|  |         RETVAL = THIS->bridge_angle; | ||||||
|  |     OUTPUT: | ||||||
|  |         RETVAL | ||||||
|  | 
 | ||||||
|  | unsigned short | ||||||
|  | Surface::extra_perimeters(...) | ||||||
|  |     CODE: | ||||||
|  |         if (items > 1) { | ||||||
|  |             THIS->extra_perimeters = (double)SvUV(ST(1)); | ||||||
|  |         } | ||||||
|  |         RETVAL = THIS->extra_perimeters; | ||||||
|  |     OUTPUT: | ||||||
|  |         RETVAL | ||||||
|  | 
 | ||||||
|  | %} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | %package{Slic3r::Surface}; | ||||||
|  | %{ | ||||||
|  | 
 | ||||||
|  | IV | ||||||
|  | _constant() | ||||||
|  |   ALIAS: | ||||||
|  |     S_TYPE_TOP              = stTop | ||||||
|  |     S_TYPE_BOTTOM           = stBottom | ||||||
|  |     S_TYPE_INTERNAL         = stInternal | ||||||
|  |     S_TYPE_INTERNALSOLID    = stInternalSolid | ||||||
|  |     S_TYPE_INTERNALBRIDGE   = stInternalBridge | ||||||
|  |     S_TYPE_INTERNALVOID     = stInternalVoid | ||||||
|  |   PROTOTYPE: | ||||||
|  |   CODE: | ||||||
|  |     RETVAL = ix; | ||||||
|  |   OUTPUT: RETVAL | ||||||
|  | 
 | ||||||
|  | %} | ||||||
|  | 
 | ||||||
|  | @ -3,3 +3,5 @@ TriangleMesh*         O_OBJECT | ||||||
| Point*         O_OBJECT | Point*         O_OBJECT | ||||||
| ExPolygon*      O_OBJECT | ExPolygon*      O_OBJECT | ||||||
| ExPolygonCollection*    O_OBJECT | ExPolygonCollection*    O_OBJECT | ||||||
|  | SurfaceType     T_UV | ||||||
|  | Surface*        O_OBJECT | ||||||
|  |  | ||||||
|  | @ -2,4 +2,11 @@ | ||||||
| %typemap{std::vector<unsigned int>*}; | %typemap{std::vector<unsigned int>*}; | ||||||
| %typemap{SV*}; | %typemap{SV*}; | ||||||
| %typemap{AV*}; | %typemap{AV*}; | ||||||
| %typemap{Point*}; | %typemap{Point*}; | ||||||
|  | %typemap{ExPolygon*}; | ||||||
|  | %typemap{SurfaceType}{parsed}{ | ||||||
|  |   %cpp_type{SurfaceType}; | ||||||
|  |   %precall_code{% | ||||||
|  |     $CVar = (SurfaceType)SvUV($PerlVar); | ||||||
|  |   %}; | ||||||
|  | }; | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci