mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	More incomplete work for using bed_shape in plater
This commit is contained in:
		
							parent
							
								
									f4e4640c73
								
							
						
					
					
						commit
						7a20c4d52a
					
				
					 4 changed files with 77 additions and 61 deletions
				
			
		|  | @ -50,7 +50,7 @@ sub new { | ||||||
|     my ($parent) = @_; |     my ($parent) = @_; | ||||||
|     my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); |     my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||||||
|     $self->{config} = Slic3r::Config->new_from_defaults(qw( |     $self->{config} = Slic3r::Config->new_from_defaults(qw( | ||||||
|         bed_size print_center complete_objects extruder_clearance_radius skirts skirt_distance |         bed_size bed_shape print_center complete_objects extruder_clearance_radius skirts skirt_distance | ||||||
|     )); |     )); | ||||||
|     $self->{model} = Slic3r::Model->new; |     $self->{model} = Slic3r::Model->new; | ||||||
|     $self->{print} = Slic3r::Print->new; |     $self->{print} = Slic3r::Print->new; | ||||||
|  | @ -676,12 +676,7 @@ sub changescale { | ||||||
| sub arrange { | sub arrange { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|      |      | ||||||
|     # get the bounding box of the model area shown in the viewport |     my $bb = Slic3r::Polygon->new_scale(@{$self->{config}->bed_shape})->bounding_box; | ||||||
|     my $bb = Slic3r::Geometry::BoundingBox->new_from_points([ |  | ||||||
|         Slic3r::Point->new(@{ $self->{canvas}->point_to_model_units([0,0]) }), |  | ||||||
|         Slic3r::Point->new(@{ $self->{canvas}->point_to_model_units([ map { $_->GetWidth, $_->GetHeight } $self->{canvas}->GetSize ]) }), |  | ||||||
|     ]); |  | ||||||
|      |  | ||||||
|     eval { |     eval { | ||||||
|         $self->{model}->arrange_objects($self->GetFrame->config->min_object_distance, $bb); |         $self->{model}->arrange_objects($self->GetFrame->config->min_object_distance, $bb); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  | @ -3,11 +3,11 @@ use strict; | ||||||
| use warnings; | use warnings; | ||||||
| use utf8; | use utf8; | ||||||
| 
 | 
 | ||||||
| use List::Util qw(max first); | use List::Util qw(min max first); | ||||||
| use Slic3r::Geometry qw(X Y scale unscale convex_hull); | use Slic3r::Geometry qw(X Y scale unscale convex_hull); | ||||||
| use Slic3r::Geometry::Clipper qw(offset JT_ROUND); | use Slic3r::Geometry::Clipper qw(offset JT_ROUND); | ||||||
| use Wx qw(:misc :pen :brush :sizer :font :cursor wxTAB_TRAVERSAL); | use Wx qw(:misc :pen :brush :sizer :font :cursor wxTAB_TRAVERSAL); | ||||||
| use Wx::Event qw(EVT_MOUSE_EVENTS EVT_PAINT); | use Wx::Event qw(EVT_MOUSE_EVENTS EVT_PAINT EVT_SIZE); | ||||||
| use base 'Wx::Panel'; | use base 'Wx::Panel'; | ||||||
| 
 | 
 | ||||||
| use constant CANVAS_TEXT => join('-', +(localtime)[3,4]) eq '13-8' | use constant CANVAS_TEXT => join('-', +(localtime)[3,4]) eq '13-8' | ||||||
|  | @ -40,6 +40,9 @@ sub new { | ||||||
|      |      | ||||||
|     EVT_PAINT($self, \&repaint); |     EVT_PAINT($self, \&repaint); | ||||||
|     EVT_MOUSE_EVENTS($self, \&mouse_event); |     EVT_MOUSE_EVENTS($self, \&mouse_event); | ||||||
|  |     EVT_SIZE($self, sub { | ||||||
|  |         $self->update_bed_size; | ||||||
|  |     }); | ||||||
|      |      | ||||||
|     return $self; |     return $self; | ||||||
| } | } | ||||||
|  | @ -71,25 +74,27 @@ sub repaint { | ||||||
|     my $size = $self->GetSize; |     my $size = $self->GetSize; | ||||||
|     my @size = ($size->GetWidth, $size->GetHeight); |     my @size = ($size->GetWidth, $size->GetHeight); | ||||||
|      |      | ||||||
|     # draw grid |     # draw bed | ||||||
|     $dc->SetPen($self->{grid_pen}); |     { | ||||||
|     my $step = 10 * $self->{scaling_factor}; |         $dc->SetPen($self->{print_center_pen}); | ||||||
|     for (my $x = $step; $x <= $size[X]; $x += $step) { |         $dc->SetBrush($self->{transparent_brush}); | ||||||
|         $dc->DrawLine($x, 0, $x, $size[Y]); |         $dc->DrawPolygon($self->scaled_points_to_pixel($self->{bed_polygon}, 1), 0, 0); | ||||||
|     } |  | ||||||
|     for (my $y = $step; $y <= $size[Y]; $y += $step) { |  | ||||||
|         $dc->DrawLine(0, $y, $size[X], $y); |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     # draw grid | ||||||
|  |     $dc->SetPen($self->{grid_pen}); | ||||||
|  |     $dc->DrawLine(map @$_, @$_) for @{$self->{grid}}; | ||||||
|  |      | ||||||
|     # draw print center |     # draw print center | ||||||
|     if (@{$self->{objects}}) { |     if (@{$self->{objects}} && $Slic3r::GUI::Settings->{_}{autocenter}) { | ||||||
|  |         my $center = $self->unscaled_point_to_pixel($self->{config}->print_center); | ||||||
|         $dc->SetPen($self->{print_center_pen}); |         $dc->SetPen($self->{print_center_pen}); | ||||||
|         $dc->DrawLine($size[X]/2, 0, $size[X]/2, $size[Y]); |         $dc->DrawLine($center->[X], 0, $center->[X], $size[Y]); | ||||||
|         $dc->DrawLine(0, $size[Y]/2, $size[X], $size[Y]/2); |         $dc->DrawLine(0, $center->[Y], $size[X], $center->[Y]); | ||||||
|         $dc->SetTextForeground(Wx::Colour->new(0,0,0)); |         $dc->SetTextForeground(Wx::Colour->new(0,0,0)); | ||||||
|         $dc->SetFont(Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL)); |         $dc->SetFont(Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL)); | ||||||
|         $dc->DrawLabel("X = " . $self->{config}->print_center->[X], Wx::Rect->new(0, 0, $self->GetSize->GetWidth, $self->GetSize->GetHeight), wxALIGN_CENTER_HORIZONTAL | wxALIGN_BOTTOM); |         $dc->DrawLabel("X = " . $self->{config}->print_center->[X], Wx::Rect->new(0, 0, $center->[X]*2, $self->GetSize->GetHeight), wxALIGN_CENTER_HORIZONTAL | wxALIGN_BOTTOM); | ||||||
|         $dc->DrawRotatedText("Y = " . $self->{config}->print_center->[Y], 0, $size[Y]/2+15, 90); |         $dc->DrawRotatedText("Y = " . $self->{config}->print_center->[Y], 0, $center->[Y]+15, 90); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     # draw frame |     # draw frame | ||||||
|  | @ -131,7 +136,7 @@ sub repaint { | ||||||
|             } |             } | ||||||
|             foreach my $expolygon (@$thumbnail) { |             foreach my $expolygon (@$thumbnail) { | ||||||
|                 foreach my $points (@{$expolygon->pp}) { |                 foreach my $points (@{$expolygon->pp}) { | ||||||
|                     $dc->DrawPolygon($self->points_to_pixel($points, 1), 0, 0); |                     $dc->DrawPolygon($self->scaled_points_to_pixel($points, 1), 0, 0); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|              |              | ||||||
|  | @ -151,7 +156,7 @@ sub repaint { | ||||||
|                 my ($clearance) = @{offset([$thumbnail->convex_hull], (scale($self->{config}->extruder_clearance_radius) / 2), 1, JT_ROUND, scale(0.1))}; |                 my ($clearance) = @{offset([$thumbnail->convex_hull], (scale($self->{config}->extruder_clearance_radius) / 2), 1, JT_ROUND, scale(0.1))}; | ||||||
|                 $dc->SetPen($self->{clearance_pen}); |                 $dc->SetPen($self->{clearance_pen}); | ||||||
|                 $dc->SetBrush($self->{transparent_brush}); |                 $dc->SetBrush($self->{transparent_brush}); | ||||||
|                 $dc->DrawPolygon($self->points_to_pixel($clearance, 1), 0, 0); |                 $dc->DrawPolygon($self->scaled_points_to_pixel($clearance, 1), 0, 0); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -163,7 +168,7 @@ sub repaint { | ||||||
|             my ($convex_hull) = @{offset([convex_hull(\@points)], scale($self->{config}->skirt_distance), 1, JT_ROUND, scale(0.1))}; |             my ($convex_hull) = @{offset([convex_hull(\@points)], scale($self->{config}->skirt_distance), 1, JT_ROUND, scale(0.1))}; | ||||||
|             $dc->SetPen($self->{skirt_pen}); |             $dc->SetPen($self->{skirt_pen}); | ||||||
|             $dc->SetBrush($self->{transparent_brush}); |             $dc->SetBrush($self->{transparent_brush}); | ||||||
|             $dc->DrawPolygon($self->points_to_pixel($convex_hull, 1), 0, 0); |             $dc->DrawPolygon($self->scaled_points_to_pixel($convex_hull, 1), 0, 0); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  | @ -173,16 +178,15 @@ sub repaint { | ||||||
| sub mouse_event { | sub mouse_event { | ||||||
|     my ($self, $event) = @_; |     my ($self, $event) = @_; | ||||||
|      |      | ||||||
|     my $point = $event->GetPosition; |     my $pos = $event->GetPosition; | ||||||
|     my $pos = $self->point_to_model_units([ $point->x, $point->y ]);  #]] |     my $point = $self->point_to_model_units([ $pos->x, $pos->y ]);  #]] | ||||||
|     $pos = Slic3r::Point->new_scale(@$pos); |  | ||||||
|     if ($event->ButtonDown) { |     if ($event->ButtonDown) { | ||||||
|         $self->{on_select_object}->(undef); |         $self->{on_select_object}->(undef); | ||||||
|         OBJECTS: for my $obj_idx (0 .. $#{$self->{objects}}) { |         OBJECTS: for my $obj_idx (0 .. $#{$self->{objects}}) { | ||||||
|             my $object = $self->{objects}->[$obj_idx]; |             my $object = $self->{objects}->[$obj_idx]; | ||||||
|             for my $instance_idx (0 .. $#{ $object->instance_thumbnails }) { |             for my $instance_idx (0 .. $#{ $object->instance_thumbnails }) { | ||||||
|                 my $thumbnail = $object->instance_thumbnails->[$instance_idx]; |                 my $thumbnail = $object->instance_thumbnails->[$instance_idx]; | ||||||
|                 if (defined first { $_->contour->contains_point($pos) } @$thumbnail) { |                 if (defined first { $_->contour->contains_point($point) } @$thumbnail) { | ||||||
|                     $self->{on_select_object}->($obj_idx); |                     $self->{on_select_object}->($obj_idx); | ||||||
|                      |                      | ||||||
|                     if ($event->LeftDown) { |                     if ($event->LeftDown) { | ||||||
|  | @ -190,12 +194,12 @@ sub mouse_event { | ||||||
|                         my $instance = $self->{model}->objects->[$obj_idx]->instances->[$instance_idx]; |                         my $instance = $self->{model}->objects->[$obj_idx]->instances->[$instance_idx]; | ||||||
|                         my $instance_origin = [ map scale($_), @{$instance->offset} ]; |                         my $instance_origin = [ map scale($_), @{$instance->offset} ]; | ||||||
|                         $self->{drag_start_pos} = [   # displacement between the click and the instance origin in scaled model units |                         $self->{drag_start_pos} = [   # displacement between the click and the instance origin in scaled model units | ||||||
|                             $pos->x - $instance_origin->[X], |                             $point->x - $instance_origin->[X], | ||||||
|                             $pos->y - $instance_origin->[Y],  #- |                             $point->y - $instance_origin->[Y],  #- | ||||||
|                         ]; |                         ]; | ||||||
|                         $self->{drag_object} = [ $obj_idx, $instance_idx ]; |                         $self->{drag_object} = [ $obj_idx, $instance_idx ]; | ||||||
|                     } elsif ($event->RightDown) { |                     } elsif ($event->RightDown) { | ||||||
|                         $self->{on_right_click}->($point); |                         $self->{on_right_click}->($pos); | ||||||
|                     } |                     } | ||||||
|                      |                      | ||||||
|                     last OBJECTS; |                     last OBJECTS; | ||||||
|  | @ -224,7 +228,7 @@ sub mouse_event { | ||||||
|         $self->Refresh; |         $self->Refresh; | ||||||
|     } elsif ($event->Moving) { |     } elsif ($event->Moving) { | ||||||
|         my $cursor = wxSTANDARD_CURSOR; |         my $cursor = wxSTANDARD_CURSOR; | ||||||
|         if (defined first { $_->contour->contains_point($pos) } map @$_, map @{$_->instance_thumbnails}, @{ $self->{objects} }) { |         if (defined first { $_->contour->contains_point($point) } map @$_, map @{$_->instance_thumbnails}, @{ $self->{objects} }) { | ||||||
|             $cursor = Wx::Cursor->new(wxCURSOR_HAND); |             $cursor = Wx::Cursor->new(wxCURSOR_HAND); | ||||||
|         } |         } | ||||||
|         $self->SetCursor($cursor); |         $self->SetCursor($cursor); | ||||||
|  | @ -234,13 +238,37 @@ sub mouse_event { | ||||||
| sub update_bed_size { | sub update_bed_size { | ||||||
|     my $self = shift; |     my $self = shift; | ||||||
|      |      | ||||||
|     # supposing the preview canvas is square, calculate the scaling factor |  | ||||||
|     # to constrain print bed area inside preview |  | ||||||
|     # when the canvas is not rendered yet, its GetSize() method returns 0,0 |     # when the canvas is not rendered yet, its GetSize() method returns 0,0 | ||||||
|  |     my $canvas_size = $self->GetSize; | ||||||
|  |     my ($canvas_w, $canvas_h) = ($canvas_size->GetWidth, $canvas_size->GetHeight); | ||||||
|  |     return if $canvas_w == 0; | ||||||
|  |      | ||||||
|  |     # get bed shape polygon | ||||||
|  |     $self->{bed_polygon} = my $polygon = Slic3r::Polygon->new_scale(@{$self->{config}->bed_shape}); | ||||||
|  |     my $bb = $polygon->bounding_box; | ||||||
|  |     my $size = $bb->size; | ||||||
|  |      | ||||||
|  |     # calculate the scaling factor needed for constraining print bed area inside preview | ||||||
|     # scaling_factor is expressed in pixel / mm |     # scaling_factor is expressed in pixel / mm | ||||||
|     my $width = $self->GetSize->GetWidth; |     $self->{scaling_factor} = min($canvas_w / unscale($size->x), $canvas_h / unscale($size->y)); #) | ||||||
|     $self->{scaling_factor} = $width / max(@{ $self->{config}->bed_size }) |      | ||||||
|         if $width != 0; |     # calculate the displacement needed to center bed | ||||||
|  |     $self->{bed_origin} = [ | ||||||
|  |         $self->GetSize->GetWidth/2  - (unscale($bb->x_max + $bb->x_min)/2 * $self->{scaling_factor}), | ||||||
|  |         $canvas_h - ($self->GetSize->GetHeight/2 - (unscale($bb->y_max + $bb->y_min)/2 * $self->{scaling_factor})), | ||||||
|  |     ]; | ||||||
|  |      | ||||||
|  |     # cache bed contours and grid | ||||||
|  |     { | ||||||
|  |         my $step = scale 10;  # 1cm grid | ||||||
|  |         $self->{grid} = my $grid = [];   # arrayref of lines | ||||||
|  |         for (my $x = $bb->x_min + $step; $x < $bb->x_max; $x += $step) { | ||||||
|  |             push @$grid, $self->scaled_points_to_pixel([[$x, $bb->y_min], [$x, $bb->y_max]], 1); | ||||||
|  |         } | ||||||
|  |         for (my $y = $bb->y_min + $step; $y < $bb->y_max; $y += $step) { | ||||||
|  |             push @$grid, $self->scaled_points_to_pixel([[$bb->x_min, $y], [$bb->x_max, $y]], 1); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub clean_instance_thumbnails { | sub clean_instance_thumbnails { | ||||||
|  | @ -251,35 +279,25 @@ sub clean_instance_thumbnails { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| # coordinates of the model origin (0,0) in pixels | # convert a model coordinate into a pixel coordinate | ||||||
| sub model_origin_to_pixel { | sub unscaled_point_to_pixel { | ||||||
|     my ($self) = @_; |  | ||||||
|      |  | ||||||
|     return [ |  | ||||||
|         $self->GetSize->GetWidth/2 - ($self->{config}->print_center->[X] * $self->{scaling_factor}), |  | ||||||
|         $self->GetSize->GetHeight/2 - ($self->{config}->print_center->[Y] * $self->{scaling_factor}), |  | ||||||
|     ]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| # convert a model coordinate into a pixel coordinate, assuming preview has square shape |  | ||||||
| sub point_to_pixel { |  | ||||||
|     my ($self, $point) = @_; |     my ($self, $point) = @_; | ||||||
|      |      | ||||||
|     my $canvas_height = $self->GetSize->GetHeight; |     my $canvas_height = $self->GetSize->GetHeight; | ||||||
|     my $zero = $self->model_origin_to_pixel; |     my $zero = $self->{bed_origin}; | ||||||
|     return [ |     return [ | ||||||
|         $point->[X] * $self->{scaling_factor} + $zero->[X], |         $point->[X] * $self->{scaling_factor} + $zero->[X], | ||||||
|         $canvas_height - ($point->[Y] * $self->{scaling_factor} + $zero->[Y]), |         $canvas_height - $point->[Y] * $self->{scaling_factor} + ($zero->[Y] - $canvas_height), | ||||||
|     ]; |     ]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub points_to_pixel { | sub scaled_points_to_pixel { | ||||||
|     my ($self, $points, $unscale) = @_; |     my ($self, $points, $unscale) = @_; | ||||||
|      |      | ||||||
|     my $result = []; |     my $result = []; | ||||||
|     foreach my $point (@$points) { |     foreach my $point (@$points) { | ||||||
|         $point = [ map unscale($_), @$point ] if $unscale; |         $point = [ map unscale($_), @$point ] if $unscale; | ||||||
|         push @$result, $self->point_to_pixel($point); |         push @$result, $self->unscaled_point_to_pixel($point); | ||||||
|     } |     } | ||||||
|     return $result; |     return $result; | ||||||
| } | } | ||||||
|  | @ -288,11 +306,13 @@ sub point_to_model_units { | ||||||
|     my ($self, $point) = @_; |     my ($self, $point) = @_; | ||||||
|      |      | ||||||
|     my $canvas_height = $self->GetSize->GetHeight; |     my $canvas_height = $self->GetSize->GetHeight; | ||||||
|     my $zero = $self->model_origin_to_pixel; |     my $zero = $self->{bed_origin}; | ||||||
|     return [ |     my $p = Slic3r::Point->new( | ||||||
|                           ($point->[X] - $zero->[X]) / $self->{scaling_factor}, |         scale ($point->[X] - $zero->[X]) / $self->{scaling_factor}, | ||||||
|         (($canvas_height - $point->[Y] - $zero->[Y]) / $self->{scaling_factor}), |         scale ($point->[Y] - $zero->[Y]) / $self->{scaling_factor}, | ||||||
|     ]; |     ); | ||||||
|  |     use XXX; YYY $p->pp; | ||||||
|  |     return $p; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 1; | 1; | ||||||
|  |  | ||||||
|  | @ -146,6 +146,7 @@ sub duplicate { | ||||||
| sub _arrange { | sub _arrange { | ||||||
|     my ($self, $sizes, $distance, $bb) = @_; |     my ($self, $sizes, $distance, $bb) = @_; | ||||||
|      |      | ||||||
|  |     # we supply unscaled data to arrange() | ||||||
|     return Slic3r::Geometry::arrange( |     return Slic3r::Geometry::arrange( | ||||||
|         scalar(@$sizes),                # number of parts |         scalar(@$sizes),                # number of parts | ||||||
|         max(map $_->x, @$sizes),        # cell width |         max(map $_->x, @$sizes),        # cell width | ||||||
|  |  | ||||||
|  | @ -427,7 +427,7 @@ Print::invalidate_state_by_config_options(const std::vector<t_config_option_key> | ||||||
|         } else if (*opt_key == "nozzle_diameter") { |         } else if (*opt_key == "nozzle_diameter") { | ||||||
|             steps.insert(psInitExtruders); |             steps.insert(psInitExtruders); | ||||||
|         } else if (*opt_key == "avoid_crossing_perimeters" |         } else if (*opt_key == "avoid_crossing_perimeters" | ||||||
|             || *opt_key == "bed_size" |             || *opt_key == "bed_shape" | ||||||
|             || *opt_key == "bed_temperature" |             || *opt_key == "bed_temperature" | ||||||
|             || *opt_key == "bridge_acceleration" |             || *opt_key == "bridge_acceleration" | ||||||
|             || *opt_key == "bridge_fan_speed" |             || *opt_key == "bridge_fan_speed" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci