mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Merge branch 'master' into xsdata
Conflicts: lib/Slic3r.pm lib/Slic3r/ExPolygon.pm lib/Slic3r/Fill.pm lib/Slic3r/Fill/Rectilinear.pm lib/Slic3r/GCode.pm lib/Slic3r/GUI/Plater.pm lib/Slic3r/Geometry/Clipper.pm lib/Slic3r/Layer/Region.pm lib/Slic3r/Print.pm lib/Slic3r/Print/Object.pm lib/Slic3r/TriangleMesh.pm t/shells.t xs/MANIFEST
This commit is contained in:
		
						commit
						b38cc2c244
					
				
					 60 changed files with 1432 additions and 798 deletions
				
			
		|  | @ -2,7 +2,7 @@ use Test::More; | |||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| plan tests => 7; | ||||
| plan tests => 10; | ||||
| 
 | ||||
| BEGIN { | ||||
|     use FindBin; | ||||
|  | @ -78,6 +78,28 @@ use Slic3r; | |||
|     ok @simplified == 1, 'gear simplified to a single polygon'; | ||||
|     note sprintf "original points: %d\nnew points: %d", $num_points, scalar(@{$simplified[0]}); | ||||
|     ok @{$simplified[0]} < $num_points, 'gear was further simplified using Douglas-Peucker'; | ||||
|      | ||||
|     my @simplified_ex = Slic3r::ExPolygon->new($polygon)->simplify(10); | ||||
|     is_deeply [ map $_->pp, @simplified_ex ], [ [ map $_->pp, @simplified ] ], 'simplified polygon equals simplified expolygon'; | ||||
| } | ||||
| 
 | ||||
| { | ||||
|     my $square = Slic3r::Polygon->new(  # ccw | ||||
|         [100, 100], | ||||
|         [200, 100], | ||||
|         [200, 200], | ||||
|         [100, 200], | ||||
|     ); | ||||
|     my $hole_in_square = Slic3r::Polygon->new(  # cw | ||||
|         [140, 140], | ||||
|         [140, 160], | ||||
|         [160, 160], | ||||
|         [160, 140], | ||||
|     ); | ||||
|     my $expolygon = Slic3r::ExPolygon->new($square, $hole_in_square); | ||||
|     my @simplified = $hole_in_square->simplify; | ||||
|     is scalar(@simplified), 1, 'hole simplification returns one polygon'; | ||||
|     ok $simplified[0]->is_counter_clockwise, 'hole simplification turns cw polygon into ccw polygon'; | ||||
| } | ||||
| 
 | ||||
| { | ||||
|  |  | |||
							
								
								
									
										56
									
								
								t/fill.t
									
										
									
									
									
								
							
							
						
						
									
										56
									
								
								t/fill.t
									
										
									
									
									
								
							|  | @ -2,7 +2,7 @@ use Test::More; | |||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| plan tests => 10; | ||||
| plan tests => 32; | ||||
| 
 | ||||
| BEGIN { | ||||
|     use FindBin; | ||||
|  | @ -11,6 +11,7 @@ BEGIN { | |||
| 
 | ||||
| use Slic3r; | ||||
| use Slic3r::Geometry qw(scale X Y); | ||||
| use Slic3r::Geometry::Clipper qw(diff_ex); | ||||
| use Slic3r::Surface qw(:types); | ||||
| use Slic3r::Test; | ||||
| 
 | ||||
|  | @ -48,6 +49,59 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ } | |||
|     } | ||||
| } | ||||
| 
 | ||||
| { | ||||
|     my $test = sub { | ||||
|         my ($expolygon, $flow_spacing) = @_; | ||||
|          | ||||
|         my $filler = Slic3r::Fill::Rectilinear->new( | ||||
|             bounding_box    => $expolygon->bounding_box, | ||||
|             angle           => 0, | ||||
|         ); | ||||
|         my $surface = Slic3r::Surface->new( | ||||
|             surface_type    => S_TYPE_BOTTOM, | ||||
|             expolygon       => $expolygon, | ||||
|         ); | ||||
|         my ($params, @paths) = $filler->fill_surface($surface, flow_spacing => $flow_spacing, density => 1); | ||||
|          | ||||
|         # check whether any part was left uncovered | ||||
|         my @grown_paths = map Slic3r::Polyline->new(@$_)->grow(scale $params->{flow_spacing}/2), @paths; | ||||
|         my $uncovered = diff_ex([ @$expolygon ], [ @grown_paths ], 1); | ||||
|          | ||||
|         # ignore very small dots | ||||
|         @$uncovered = grep $_->area > (scale $flow_spacing)**2, @$uncovered; | ||||
|          | ||||
|         is scalar(@$uncovered), 0, 'solid surface is fully filled'; | ||||
|          | ||||
|         if (0 && @$uncovered) { | ||||
|             require "Slic3r/SVG.pm"; | ||||
|             Slic3r::SVG::output( | ||||
|                 "uncovered.svg", | ||||
|                 expolygons => [$expolygon], | ||||
|                 red_expolygons => $uncovered, | ||||
|             ); | ||||
|             exit; | ||||
|         } | ||||
|     }; | ||||
|      | ||||
|     my $expolygon = Slic3r::ExPolygon->new([ | ||||
|         [6883102, 9598327.01296997], | ||||
|         [6883102, 20327272.01297], | ||||
|         [3116896, 20327272.01297], | ||||
|         [3116896, 9598327.01296997], | ||||
|     ]); | ||||
|     $test->($expolygon, 0.55); | ||||
|      | ||||
|     for (1..20) { | ||||
|         $expolygon->scale(1.05); | ||||
|         $test->($expolygon, 0.55); | ||||
|     } | ||||
|      | ||||
|     $expolygon = Slic3r::ExPolygon->new( | ||||
|         [[59515297,5422499],[59531249,5578697],[59695801,6123186],[59965713,6630228],[60328214,7070685],[60773285,7434379],[61274561,7702115],[61819378,7866770],[62390306,7924789],[62958700,7866744],[63503012,7702244],[64007365,7434357],[64449960,7070398],[64809327,6634999],[65082143,6123325],[65245005,5584454],[65266967,5422499],[66267307,5422499],[66269190,8310081],[66275379,17810072],[66277259,20697500],[65267237,20697500],[65245004,20533538],[65082082,19994444],[64811462,19488579],[64450624,19048208],[64012101,18686514],[63503122,18415781],[62959151,18251378],[62453416,18198442],[62390147,18197355],[62200087,18200576],[61813519,18252990],[61274433,18415918],[60768598,18686517],[60327567,19047892],[59963609,19493297],[59695865,19994587],[59531222,20539379],[59515153,20697500],[58502480,20697500],[58502480,5422499]] | ||||
|     ); | ||||
|     $test->($expolygon, 0.524341649025257); | ||||
| } | ||||
| 
 | ||||
| { | ||||
|     my $collection = Slic3r::Polyline::Collection->new(polylines => [ | ||||
|         Slic3r::Polyline->new([0,15], [0,18], [0,20]), | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ use Test::More; | |||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| plan tests => 24; | ||||
| plan tests => 25; | ||||
| 
 | ||||
| BEGIN { | ||||
|     use FindBin; | ||||
|  | @ -183,3 +183,10 @@ is Slic3r::Geometry::can_connect_points(@$points, $polygons), 0, 'can_connect_po | |||
| } | ||||
| 
 | ||||
| #========================================================== | ||||
| 
 | ||||
| { | ||||
|     my $line = Slic3r::Line->new([10,10], [20,10]); | ||||
|     is +($line->grow(5))[0]->area, Slic3r::Polygon->new([5,5], [25,5], [25,15], [5,15])->area, 'grow line'; | ||||
| } | ||||
| 
 | ||||
| #========================================================== | ||||
|  |  | |||
							
								
								
									
										13
									
								
								t/layers.t
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								t/layers.t
									
										
									
									
									
								
							|  | @ -1,4 +1,4 @@ | |||
| use Test::More tests => 5; | ||||
| use Test::More tests => 4; | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
|  | @ -56,15 +56,4 @@ ok $test->(), "positive Z offset"; | |||
| $config->set('z_offset', -0.8); | ||||
| ok $test->(), "negative Z offset"; | ||||
| 
 | ||||
| { | ||||
|     my $config = Slic3r::Config->new_from_defaults; | ||||
|     $config->set('nozzle_diameter', [0.35]); | ||||
|     $config->set('layer_height', 0.1333); | ||||
|      | ||||
|     my $print = Slic3r::Test::init_print('2x20x10', config => $config); | ||||
|     $print->init_extruders; | ||||
|     $_->region(0) for @{$print->objects->[0]->layers};  # init layer regions | ||||
|     ok $print->objects->[0]->layers->[1]->support_material_contact_height > 0, 'support_material_contact_height is positive'; | ||||
| } | ||||
| 
 | ||||
| __END__ | ||||
|  |  | |||
|  | @ -48,8 +48,9 @@ my $test = sub { | |||
|             } | ||||
|             if ($info->{dist_Z} < 0) { | ||||
|                 fail 'going down only after lifting' if !$lifted; | ||||
|                 fail 'going down by the same amount of the lift' | ||||
|                     if !_eq($info->{dist_Z}, -$print->extruders->[$tool]->retract_lift); | ||||
|                 fail 'going down by the same amount of the lift or by the amount needed to get to next layer' | ||||
|                     if !_eq($info->{dist_Z}, -$print->extruders->[$tool]->retract_lift) | ||||
|                         && !_eq($info->{dist_Z}, -$print->extruders->[$tool]->retract_lift + $conf->layer_height); | ||||
|                 $lifted = 0; | ||||
|             } | ||||
|             fail 'move Z at travel speed' if ($args->{F} // $self->F) != $conf->travel_speed * 60; | ||||
|  | @ -123,6 +124,8 @@ $retract_tests->(' (G0 and duplicate)'); | |||
| $config->set('duplicate', 1); | ||||
| $config->set('g0', 0); | ||||
| $config->set('infill_extruder', 2); | ||||
| $retract_tests->(' (dual extruder)'); | ||||
| $config->set('skirts', 4); | ||||
| $config->set('skirt_height', 3); | ||||
| $retract_tests->(' (dual extruder with multiple skirt layers)'); | ||||
| 
 | ||||
| __END__ | ||||
|  |  | |||
							
								
								
									
										70
									
								
								t/shells.t
									
										
									
									
									
								
							
							
						
						
									
										70
									
								
								t/shells.t
									
										
									
									
									
								
							|  | @ -1,4 +1,4 @@ | |||
| use Test::More tests => 4; | ||||
| use Test::More tests => 10; | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
|  | @ -84,4 +84,72 @@ use Slic3r::Test; | |||
|         "correct number of top solid shells is generated in V-shaped object"; | ||||
| } | ||||
| 
 | ||||
| { | ||||
|     my $config = Slic3r::Config->new_from_defaults; | ||||
|     # we need to check against one perimeter because this test is calibrated | ||||
|     # (shape, extrusion_width) so that perimeters cover the bottom surfaces of | ||||
|     # their lower layer - the test checks that shells are not generated on the | ||||
|     # above layers (thus 'across' the shadow perimeter) | ||||
|     # the test is actually calibrated to leave a narrow bottom region for each | ||||
|     # layer - we test that in case of fill_density = 0 such narrow shells are  | ||||
|     # discarded instead of grown | ||||
|     $config->set('perimeters', 1); | ||||
|     $config->set('fill_density', 0); | ||||
|     $config->set('cooling', 0);                 # prevent speed alteration | ||||
|     $config->set('first_layer_speed', '100%');  # prevent speed alteration | ||||
|     $config->set('layer_height', 0.4); | ||||
|     $config->set('first_layer_height', '100%'); | ||||
|     $config->set('extrusion_width', 0.5); | ||||
|     $config->set('bottom_solid_layers', 3); | ||||
|     $config->set('top_solid_layers', 0); | ||||
|     $config->set('solid_infill_speed', 99); | ||||
|      | ||||
|     my $print = Slic3r::Test::init_print('V', config => $config); | ||||
|     my %layers = ();  # Z => 1 | ||||
|     Slic3r::GCode::Reader->new(gcode => Slic3r::Test::gcode($print))->parse(sub { | ||||
|         my ($self, $cmd, $args, $info) = @_; | ||||
|         $layers{$self->Z} = 1 | ||||
|             if $info->{extruding} && ($args->{F} // $self->F) == $config->solid_infill_speed*60; | ||||
|     }); | ||||
|     is scalar(keys %layers), $config->bottom_solid_layers, | ||||
|         "shells are not propagated across perimeters of the neighbor layer"; | ||||
| } | ||||
| 
 | ||||
| { | ||||
|     my $config = Slic3r::Config->new_from_defaults; | ||||
|     $config->set('spiral_vase', 1); | ||||
|     $config->set('bottom_solid_layers', 0); | ||||
|     $config->set('skirts', 0); | ||||
|     $config->set('first_layer_height', '100%'); | ||||
|      | ||||
|     # TODO: this needs to be tested with a model with sloping edges, where starting | ||||
|     # points of each layer are not aligned - in that case we would test that no | ||||
|     # travel moves are left to move to the new starting point - in a cube, end | ||||
|     # points coincide with next layer starting points (provided there's no clipping) | ||||
|     my $test = sub { | ||||
|         my ($model_name, $description) = @_; | ||||
|         my $print = Slic3r::Test::init_print($model_name, config => $config); | ||||
|         my $travel_moves_after_first_extrusion = 0; | ||||
|         my $started_extruding = 0; | ||||
|         my @z_steps = (); | ||||
|         Slic3r::GCode::Reader->new(gcode => Slic3r::Test::gcode($print))->parse(sub { | ||||
|             my ($self, $cmd, $args, $info) = @_; | ||||
|              | ||||
|             $started_extruding = 1 if $info->{extruding}; | ||||
|             push @z_steps, ($args->{Z} - $self->Z) | ||||
|                 if $started_extruding && exists $args->{Z}; | ||||
|             $travel_moves_after_first_extrusion++ | ||||
|                 if $info->{travel} && $started_extruding && !exists $args->{Z}; | ||||
|         }); | ||||
|         is $travel_moves_after_first_extrusion, 0, "no gaps in spiral vase ($description)"; | ||||
|         ok !(grep { $_ > $config->layer_height } @z_steps), "no gaps in Z ($description)"; | ||||
|     }; | ||||
|      | ||||
|     $test->('20mm_cube', 'solid model'); | ||||
|     $test->('40x10', 'hollow model'); | ||||
|      | ||||
|     $config->set('z_offset', -10); | ||||
|     $test->('20mm_cube', 'solid model with negative z-offset'); | ||||
| } | ||||
| 
 | ||||
| __END__ | ||||
|  |  | |||
							
								
								
									
										45
									
								
								t/support.t
									
										
									
									
									
								
							
							
						
						
									
										45
									
								
								t/support.t
									
										
									
									
									
								
							|  | @ -1,4 +1,4 @@ | |||
| use Test::More tests => 1; | ||||
| use Test::More tests => 13; | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
|  | @ -7,15 +7,58 @@ BEGIN { | |||
|     use lib "$FindBin::Bin/../lib"; | ||||
| } | ||||
| 
 | ||||
| use List::Util qw(first); | ||||
| use Slic3r; | ||||
| use Slic3r::Geometry qw(epsilon); | ||||
| use Slic3r::Test; | ||||
| 
 | ||||
| { | ||||
|     my $config = Slic3r::Config->new_from_defaults; | ||||
|     my @contact_z = my @top_z = (); | ||||
|      | ||||
|     my $test = sub { | ||||
|         my $flow = Slic3r::Flow->new(nozzle_diameter => $config->nozzle_diameter->[0], layer_height => $config->layer_height); | ||||
|         my @support_layers = Slic3r::Print::Object::_compute_support_layers(\@contact_z, \@top_z, $config, $flow); | ||||
|          | ||||
|         is $support_layers[0], $config->first_layer_height, | ||||
|             'first layer height is honored'; | ||||
|         is scalar(grep { $support_layers[$_]-$support_layers[$_-1] <= 0 } 1..$#support_layers), 0, | ||||
|             'no null or negative support layers'; | ||||
|         is scalar(grep { $support_layers[$_]-$support_layers[$_-1] > $flow->nozzle_diameter + epsilon } 1..$#support_layers), 0, | ||||
|             'no layers thicker than nozzle diameter'; | ||||
|          | ||||
|         my $wrong_top_spacing = 0; | ||||
|         foreach my $top_z (@top_z) { | ||||
|             # find layer index of this top surface | ||||
|             my $layer_id = first { abs($support_layers[$_] - $top_z) < epsilon } 0..$#support_layers; | ||||
|              | ||||
|             # check that first support layer above this top surface is spaced with nozzle diameter | ||||
|             $wrong_top_spacing = 1 | ||||
|                 if ($support_layers[$layer_id+1] - $support_layers[$layer_id]) != $flow->nozzle_diameter; | ||||
|         } | ||||
|         ok !$wrong_top_spacing, 'layers above top surfaces are spaced correctly'; | ||||
|     }; | ||||
|      | ||||
|     $config->set('layer_height', 0.2); | ||||
|     $config->set('first_layer_height', 0.3); | ||||
|     @contact_z = (1.9); | ||||
|     @top_z = (1.1); | ||||
|     $test->(); | ||||
|      | ||||
|     $config->set('first_layer_height', 0.4); | ||||
|     $test->(); | ||||
|      | ||||
|     $config->set('layer_height', $config->nozzle_diameter->[0]); | ||||
|     $test->(); | ||||
| } | ||||
| 
 | ||||
| { | ||||
|     my $config = Slic3r::Config->new_from_defaults; | ||||
|     $config->set('raft_layers', 3); | ||||
|     $config->set('brim_width',  6); | ||||
|     $config->set('skirts', 0); | ||||
|     $config->set('support_material_extruder', 2); | ||||
|     $config->set('support_material_interface_extruder', 2); | ||||
|     $config->set('layer_height', 0.4); | ||||
|     $config->set('first_layer_height', '100%'); | ||||
|     my $print = Slic3r::Test::init_print('20mm_cube', config => $config); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci