mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Massive reduction of memory usage (down to one third).
This commit is contained in:
		
							parent
							
								
									882a022e3a
								
							
						
					
					
						commit
						b246480535
					
				
					 10 changed files with 75 additions and 31 deletions
				
			
		|  | @ -80,7 +80,7 @@ our $perimeter_acceleration = 25;   # mm/s^2 | |||
| our $infill_acceleration    = 50;   # mm/s^2 | ||||
| 
 | ||||
| # accuracy options | ||||
| our $scaling_factor         = 0.00000001; | ||||
| our $scaling_factor         = 0.000001; | ||||
| our $resolution             = 0.01; | ||||
| our $small_perimeter_length = (6.5 / $scaling_factor)*2*PI; | ||||
| our $layer_height           = 0.4; | ||||
|  |  | |||
|  | @ -78,6 +78,7 @@ sub extrude_loop { | |||
|     my ($loop, $description) = @_; | ||||
|      | ||||
|     # extrude all loops ccw | ||||
|     $loop->deserialize; | ||||
|     $loop->polygon->make_counter_clockwise; | ||||
|      | ||||
|     # find the point of the loop that is closest to the current extruder position | ||||
|  | @ -85,6 +86,7 @@ sub extrude_loop { | |||
|      | ||||
|     # split the loop at the starting point and make a path | ||||
|     my $extrusion_path = $loop->split_at($start_at); | ||||
|     $extrusion_path->deserialize; | ||||
|      | ||||
|     # clip the path to avoid the extruder to get exactly on the first point of the loop; | ||||
|     # if polyline was shorter than the clipping distance we'd get a null polyline, so | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ use Moo; | |||
| 
 | ||||
| # the underlying Slic3r::Polygon objects holds the geometry | ||||
| has 'polygon' => ( | ||||
|     is          => 'ro', | ||||
|     is          => 'rw', | ||||
|     required    => 1, | ||||
|     handles     => [qw(is_printable nearest_point_to)], | ||||
| ); | ||||
|  | @ -14,6 +14,12 @@ has 'role'         => (is => 'rw', required => 1); | |||
| sub BUILD { | ||||
|     my $self = shift; | ||||
|     bless $self->polygon, 'Slic3r::Polygon'; | ||||
|     $self->polygon($self->polygon->serialize); | ||||
| } | ||||
| 
 | ||||
| sub deserialize { | ||||
|     my $self = shift; | ||||
|     $self->polygon($self->polygon->deserialize); | ||||
| } | ||||
| 
 | ||||
| sub split_at { | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ use Slic3r::Geometry qw(PI X Y epsilon deg2rad rotate_points); | |||
| 
 | ||||
| # the underlying Slic3r::Polyline objects holds the geometry | ||||
| has 'polyline' => ( | ||||
|     is          => 'ro', | ||||
|     is          => 'rw', | ||||
|     required    => 1, | ||||
|     handles     => [qw(merge_continuous_lines lines length)], | ||||
| ); | ||||
|  | @ -34,6 +34,12 @@ use constant EXTR_ROLE_SUPPORTMATERIAL  => 6; | |||
| sub BUILD { | ||||
|     my $self = shift; | ||||
|     bless $self->polyline, 'Slic3r::Polyline'; | ||||
|     $self->polyline($self->polyline->serialize); | ||||
| } | ||||
| 
 | ||||
| sub deserialize { | ||||
|     my $self = shift; | ||||
|     $self->polyline($self->polyline->deserialize); | ||||
| } | ||||
| 
 | ||||
| sub clip_end { | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ sub shortest_path { | |||
|     my ($start_near) = @_; | ||||
|      | ||||
|     my @my_paths = @{$self->paths}; | ||||
|     $_->deserialize for @my_paths; | ||||
|     my @paths = (); | ||||
|     my $start_at; | ||||
|     CYCLE: while (@my_paths) { | ||||
|  |  | |||
|  | @ -236,7 +236,7 @@ sub polyline_lines { | |||
| } | ||||
| 
 | ||||
| sub polygon_lines { | ||||
|     my ($polygon) = @_; | ||||
|     my ($polygon) = @_;use XXX; ZZZ $polygon if !eval { @$polygon }; | ||||
|     return polyline_lines([ @$polygon, $polygon->[0] ]); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -284,19 +284,14 @@ sub make_perimeters { | |||
|             } | ||||
|         } | ||||
|          | ||||
|         foreach my $hole (reverse @holes) { | ||||
|             push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $hole, role => EXTR_ROLE_PERIMETER); | ||||
|         # do holes, then contours starting from innermost one | ||||
|         foreach my $polygon ((reverse @holes), (map $_->contour, map @$_, reverse @$island)) { | ||||
|             next unless $polygon->is_printable; | ||||
|             push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new( | ||||
|                 polygon => $polygon, | ||||
|                 role => (abs($polygon->length) <= $Slic3r::small_perimeter_length) ? EXTR_ROLE_SMALLPERIMETER : EXTR_ROLE_PERIMETER, | ||||
|             ); | ||||
|         } | ||||
|          | ||||
|         # do contours starting from innermost one | ||||
|         foreach my $contour (map $_->contour, map @$_, reverse @$island) { | ||||
|             push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $contour, role => EXTR_ROLE_PERIMETER); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     # detect small perimeters by checking their area | ||||
|     for (@{ $self->perimeters }) { | ||||
|         $_->role(EXTR_ROLE_SMALLPERIMETER) if abs($_->polygon->length) <= $Slic3r::small_perimeter_length; | ||||
|     } | ||||
|      | ||||
|     # add thin walls as perimeters | ||||
|  | @ -384,16 +379,6 @@ sub remove_small_surfaces { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| sub remove_small_perimeters { | ||||
|     my $self = shift; | ||||
|     my @good_perimeters = grep $_->is_printable, @{$self->perimeters}; | ||||
|     Slic3r::debugf "removed %d unprintable perimeters at layer %d\n", | ||||
|         (@{$self->perimeters} - @good_perimeters), $self->id | ||||
|         if @good_perimeters != @{$self->perimeters}; | ||||
|      | ||||
|     @{$self->perimeters} = @good_perimeters; | ||||
| } | ||||
| 
 | ||||
| # make bridges printable | ||||
| sub process_bridges { | ||||
|     my $self = shift; | ||||
|  |  | |||
|  | @ -21,6 +21,22 @@ sub new { | |||
|     $self; | ||||
| } | ||||
| 
 | ||||
| sub serialize { | ||||
|     my $self = shift; | ||||
|     my $s = \ pack 'l*', map @$_, @$self; | ||||
|     bless $s, ref $self; | ||||
|     return $s; | ||||
| } | ||||
| 
 | ||||
| sub deserialize { | ||||
|     my $self = shift; | ||||
|     my @v = unpack '(l2)*', $$self; | ||||
|     my $o = [ map [ $v[2*$_], $v[2*$_+1] ], 0 .. int($#v/2) ]; | ||||
|     bless $_, 'Slic3r::Point' for @$o; | ||||
|     bless $o, ref $self; | ||||
|     return $o; | ||||
| } | ||||
| 
 | ||||
| sub id { | ||||
|     my $self = shift; | ||||
|     return join ' - ', sort map $_->id, @$self; | ||||
|  |  | |||
|  | @ -188,11 +188,6 @@ sub export_gcode { | |||
|     $status_cb->(45, "Detect bridges"); | ||||
|     $_->process_bridges for map @{$_->layers}, @{$self->objects}; | ||||
|      | ||||
|     # this will remove unprintable perimeter loops | ||||
|     # (those that are too tight for extrusion) | ||||
|     $status_cb->(50, "Cleaning up the perimeters"); | ||||
|     $_->remove_small_perimeters for map @{$_->layers}, @{$self->objects}; | ||||
|      | ||||
|     # detect which fill surfaces are near external layers | ||||
|     # they will be split in internal and internal-solid surfaces | ||||
|     $status_cb->(60, "Generating horizontal shells"); | ||||
|  |  | |||
							
								
								
									
										33
									
								
								t/serialize.t
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								t/serialize.t
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,33 @@ | |||
| use Test::More; | ||||
| use strict; | ||||
| use warnings; | ||||
| 
 | ||||
| plan tests => 2; | ||||
| 
 | ||||
| BEGIN { | ||||
|     use FindBin; | ||||
|     use lib "$FindBin::Bin/../lib"; | ||||
| } | ||||
| 
 | ||||
| use Slic3r; | ||||
| use Slic3r::Geometry qw(scale); | ||||
| 
 | ||||
| #========================================================== | ||||
| 
 | ||||
| { | ||||
|     my $points = [ | ||||
|         [226,701], [260,681], [109,420], [149,397], [300,658], [308,654], | ||||
|     ]; | ||||
|     foreach my $point (@$points) { | ||||
|         @$point = map scale $_, @$point; | ||||
|     } | ||||
|     my $polyline = Slic3r::Polyline->new($points); | ||||
|     my $serialized = $polyline->serialize; | ||||
|     my $deserialized = $serialized->deserialize; | ||||
|     is scalar(@$deserialized), scalar(@$points), 'number of deserialized points'; | ||||
|     is_deeply $deserialized, $points, 'deserialized points coordinates'; | ||||
| } | ||||
| 
 | ||||
| #========================================================== | ||||
| 
 | ||||
| __END__ | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci