diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index ecba7ba8a..e2e7c50dd 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -226,6 +226,7 @@ sub thread_cleanup { *Slic3r::Geometry::BoundingBoxf::DESTROY = sub {}; *Slic3r::Geometry::BoundingBoxf3::DESTROY = sub {}; *Slic3r::Layer::PerimeterGenerator::DESTROY = sub {}; + *Slic3r::LayerHeightSpline::DESTROY = sub {}; *Slic3r::Line::DESTROY = sub {}; *Slic3r::Linef3::DESTROY = sub {}; *Slic3r::Model::DESTROY = sub {}; diff --git a/lib/Slic3r/GUI/Plater/SplineControl.pm b/lib/Slic3r/GUI/Plater/SplineControl.pm index 8f1d7e5fe..236b68903 100644 --- a/lib/Slic3r/GUI/Plater/SplineControl.pm +++ b/lib/Slic3r/GUI/Plater/SplineControl.pm @@ -79,33 +79,74 @@ sub repaint { # draw original layers as lines my $last_z = 0.0; my @points = (); - foreach my $z (@{$self->{original_interpolated_layers}}) { - my $layer_h = $z - $last_z; +# foreach my $z (@{$self->{original_interpolated_layers}}) { +# my $layer_h = $z - $last_z; +# $dc->SetPen($self->{original_pen}); +# my $pl = $self->point_to_pixel(0, $z); +# my $pr = $self->point_to_pixel($layer_h, $z); +# #$dc->DrawLine($pl->x, $pl->y, $pr->x, $pr->y); +# push (@points, $pr); +# $last_z = $z; +# } +# +# $dc->DrawSpline(\@points); + if($self->{original_height_spline}) { + $last_z = 0.0; + @points = (); + #draw spline $dc->SetPen($self->{original_pen}); - my $pl = $self->point_to_pixel(0, $z); - my $pr = $self->point_to_pixel($layer_h, $z); - #$dc->DrawLine($pl->x, $pl->y, $pr->x, $pr->y); - push (@points, $pr); - $last_z = $z; + @points = (); + foreach my $pixel (0..$size[1]) { + my @z = $self->pixel_to_point(Wx::Point->new(0, $pixel)); + my $h = $self->{original_height_spline}->getLayerHeightAt($z[1]); + my $p = $self->point_to_pixel($h, $z[1]); + push (@points, $p); + } + $dc->DrawLines(\@points); } - - $dc->DrawSpline(\@points); + + # # draw interactive (user modified) layers as lines - $last_z = 0.0; - @points = (); - if($self->{interactive_heights}) { - foreach my $i (0..@{$self->{interactive_heights}}-1) { - my $z = $self->{original_layers}[$i]; - my $layer_h = $self->{interactive_heights}[$i]; - $dc->SetPen($self->{interactive_pen}); - my $pl = $self->point_to_pixel(0, $z); - my $pr = $self->point_to_pixel($layer_h, $z); - $dc->DrawLine($pl->x, $pl->y, $pr->x, $pr->y); - push (@points, $pr); +# $last_z = 0.0; +# @points = (); +# if($self->{interactive_heights}) { +# foreach my $i (0..@{$self->{interactive_heights}}-1) { +# my $z = $self->{original_layers}[$i]; +# my $layer_h = $self->{interactive_heights}[$i]; +# $dc->SetPen($self->{interactive_pen}); +# my $pl = $self->point_to_pixel(0, $z); +# my $pr = $self->point_to_pixel($layer_h, $z); +# $dc->DrawLine($pl->x, $pl->y, $pr->x, $pr->y); +# push (@points, $pr); +# } +# +# $dc->DrawSpline(\@points); +# } + + if($self->{interactive_height_spline}) { + $last_z = 0.0; + @points = (); + # draw layer lines + foreach my $z (@{$self->{interactive_height_spline}->getInterpolatedLayers}) { + my $layer_h = $z - $last_z; + $dc->SetPen($self->{interactive_pen}); + my $pl = $self->point_to_pixel(0, $z); + my $pr = $self->point_to_pixel($layer_h, $z); + $dc->DrawLine($pl->x, $pl->y, $pr->x, $pr->y); + $last_z = $z; + } + + #draw spline + $dc->SetPen($self->{interactive_pen}); + @points = (); + foreach my $pixel (0..$size[1]) { + my @z = $self->pixel_to_point(Wx::Point->new(0, $pixel)); + my $h = $self->{interactive_height_spline}->getLayerHeightAt($z[1]); + my $p = $self->point_to_pixel($h, $z[1]); + push (@points, $p); } - - $dc->DrawSpline(\@points); + $dc->DrawLines(\@points); } @@ -152,10 +193,12 @@ sub mouse_event { if ($event->LeftDown) { # start dragging $self->{left_drag_start_pos} = $pos; + $self->{interactive_height_spline} = $self->{object}->layer_height_spline->clone; } if ($event->RightDown) { # start dragging $self->{right_drag_start_pos} = $pos; + $self->{interactive_height_spline} = $self->{object}->layer_height_spline->clone; } } elsif ($event->LeftUp) { if($self->{left_drag_start_pos}) { @@ -171,6 +214,7 @@ sub mouse_event { $self->Refresh; $self->{object}->layer_height_spline->suppressUpdate; $self->{on_layer_update}->(@{$self->{interpolated_layers}}); + $self->{interactive_height_spline} = undef; } $self->{left_drag_start_pos} = undef; } elsif ($event->RightUp) { @@ -187,6 +231,7 @@ sub mouse_event { $self->Refresh; $self->{object}->layer_height_spline->suppressUpdate; $self->{on_layer_update}->(@{$self->{interpolated_layers}}); + $self->{interactive_height_spline} = undef; } $self->{right_drag_start_pos} = undef; } elsif ($event->Dragging) { @@ -197,6 +242,10 @@ sub mouse_event { # compute updated interactive layer heights $self->_interactive_quadratic_curve($start_pos[1], $obj_pos[0], $range); + + unless($self->{interactive_height_spline}->updateLayerHeights($self->{interactive_heights})) { + die "Unable to update interactive interpolated layers!\n"; + } $self->Refresh; } elsif($self->{right_drag_start_pos}) { my @start_pos = $self->pixel_to_point($self->{right_drag_start_pos}); @@ -204,6 +253,9 @@ sub mouse_event { # compute updated interactive layer heights $self->_interactive_linear_curve($start_pos[1], $obj_pos[0], $range); + unless($self->{interactive_height_spline}->updateLayerHeights($self->{interactive_heights})) { + die "Unable to update interactive interpolated layers!\n"; + } $self->Refresh; } } elsif ($event->Moving) { @@ -236,6 +288,7 @@ sub update { my $self = shift; if($self->{object}->layer_height_spline->layersUpdated) { + $self->{original_height_spline} = $self->{object}->layer_height_spline->clone; $self->{original_layers} = $self->{object}->layer_height_spline->getOriginalLayers; $self->{original_interpolated_layers} = $self->{object}->layer_height_spline->getInterpolatedLayers; $self->{interpolated_layers} = $self->{object}->layer_height_spline->getInterpolatedLayers; # Initialize to current values diff --git a/xs/src/libslic3r/LayerHeightSpline.cpp b/xs/src/libslic3r/LayerHeightSpline.cpp index c04cf2ce7..596a40932 100644 --- a/xs/src/libslic3r/LayerHeightSpline.cpp +++ b/xs/src/libslic3r/LayerHeightSpline.cpp @@ -21,6 +21,23 @@ LayerHeightSpline::LayerHeightSpline(coordf_t object_height) this->_cusp_value = -1; } +LayerHeightSpline::LayerHeightSpline(const LayerHeightSpline &other) +: _object_height(other._object_height), _layer_height_spline(NULL) +{ + + this->_original_layers = other._original_layers; + this->_internal_layers = other._internal_layers; + this->_internal_layer_heights = other._internal_layer_heights; + this->_is_valid = other._is_valid; + this->_update_required = other._update_required; + this->_layers_updated = other._layers_updated; + this->_layer_heights_updated = other._layer_heights_updated; + this->_cusp_value = other._cusp_value; + if(this->_is_valid) { + this->_updateBSpline(); + } +} + LayerHeightSpline::~LayerHeightSpline() { if (this->_layer_height_spline) { @@ -80,9 +97,9 @@ bool LayerHeightSpline::setLayers(std::vector layers) // add 0-values at both ends to achieve correct boundary conditions this->_internal_layers = this->_original_layers; this->_internal_layers.insert(this->_internal_layers.begin(), 0); // add z = 0 to the front - this->_internal_layers.push_back(this->_internal_layers.back()+1); // and object_height + 1 to the end - this->_internal_layer_heights.insert(this->_internal_layer_heights.begin(), 0); - this->_internal_layer_heights.push_back(0); + //this->_internal_layers.push_back(this->_internal_layers.back()+1); // and object_height + 1 to the end + this->_internal_layer_heights.insert(this->_internal_layer_heights.begin(), this->_internal_layer_heights[0]); + //this->_internal_layer_heights.push_back(0); this->_layers_updated = true; this->_layer_heights_updated = false; @@ -102,12 +119,14 @@ bool LayerHeightSpline::updateLayerHeights(std::vector heights) bool result = false; // do we receive the correct number of values? - if(heights.size() == this->_internal_layers.size()-2) { + if(heights.size() == this->_internal_layers.size()-1) { this->_internal_layer_heights = heights; - // add leading an trailing 0-value - this->_internal_layer_heights.insert(this->_internal_layer_heights.begin(), 0); - this->_internal_layer_heights.push_back(0); + // add leading and trailing 0-value + this->_internal_layer_heights.insert(this->_internal_layer_heights.begin(), this->_internal_layer_heights[0]); + //this->_internal_layer_heights.push_back(0); result = this->_updateBSpline(); + }else{ + std::cerr << "Unable to update layer heights. You provided " << heights.size() << " layers, but " << this->_internal_layers.size()-1 << " expected" << std::endl; } this->_layers_updated = false; @@ -186,7 +205,7 @@ bool LayerHeightSpline::_updateBSpline() this->_internal_layers.size(), &this->_internal_layer_heights[0], 0, - 0, + 1, 0); if (this->_layer_height_spline->ok()) { diff --git a/xs/src/libslic3r/LayerHeightSpline.hpp b/xs/src/libslic3r/LayerHeightSpline.hpp index 0b618a5ac..3fe9c09a4 100644 --- a/xs/src/libslic3r/LayerHeightSpline.hpp +++ b/xs/src/libslic3r/LayerHeightSpline.hpp @@ -12,6 +12,7 @@ class LayerHeightSpline { public: LayerHeightSpline(coordf_t object_height); + LayerHeightSpline(const LayerHeightSpline &other); ~LayerHeightSpline(); bool hasData(); // indicate that we have valid data bool updateRequired(); // indicate whether we want to generate a new spline from the layers diff --git a/xs/xsp/LayerHeightSpline.xsp b/xs/xsp/LayerHeightSpline.xsp index 3f915230e..a7b33608f 100644 --- a/xs/xsp/LayerHeightSpline.xsp +++ b/xs/xsp/LayerHeightSpline.xsp @@ -6,7 +6,10 @@ %} %name{Slic3r::LayerHeightSpline} class LayerHeightSpline { - // owned by PrintObject, no constructor/destructor + LayerHeightSpline(double object_height); + ~LayerHeightSpline(); + Clone clone() + %code%{ RETVAL = THIS; %}; bool hasData(); bool updateRequired(); @@ -21,7 +24,6 @@ std::vector getOriginalLayers(); std::vector getInterpolatedLayers(); coordf_t getLayerHeightAt(coordf_t height); - //%code%{ RETVAL = THIS->upper_layer; %}; void setCuspValue(coordf_t cusp_value); coordf_t getCuspValue(); diff --git a/xs/xsp/my.map b/xs/xsp/my.map index 69c1831cc..66fa26e78 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -180,6 +180,7 @@ Ref O_OBJECT_SLIC3R_T LayerHeightSpline* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T +Clone O_OBJECT_SLIC3R_T PlaceholderParser* O_OBJECT_SLIC3R Ref O_OBJECT_SLIC3R_T diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt index fbc2d03f5..7df7dfaf2 100644 --- a/xs/xsp/typemap.xspt +++ b/xs/xsp/typemap.xspt @@ -135,6 +135,7 @@ %typemap{LayerHeightSpline*}; %typemap{Ref}{simple}; +%typemap{Clone}{simple}; %typemap{SupportLayer*}; %typemap{Ref}{simple};