From 1fb57e439ef61bf99f9f23c06bfc774935180f33 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 21 Oct 2016 16:53:42 +0200 Subject: [PATCH] Defined the +-* operators on Pointf. Removed the deprecated VibrationLimit feature. Added triangle infill. The Prusa3D fork of Slic3r has been marked as "Slic3r Prusa Edition" with menus pointing to the prusa3d/slic3r github release page and Prusa3D drivers downloads page. --- README.md | 2 - lib/Slic3r.pm | 2 +- lib/Slic3r/Config.pm | 2 +- lib/Slic3r/GCode/VibrationLimit.pm | 63 -------------- lib/Slic3r/GUI.pm | 1 + lib/Slic3r/GUI/AboutDialog.pm | 3 +- lib/Slic3r/GUI/MainFrame.pm | 18 ++-- lib/Slic3r/GUI/Tab.pm | 3 +- lib/Slic3r/Print/GCode.pm | 9 -- lib/Slic3r/Print/Object.pm | 2 +- slic3r.pl | 2 - t/cooling.t | 1 - t/vibrationlimit.t | 98 ---------------------- xs/src/libslic3r/Fill/FillBase.cpp | 1 + xs/src/libslic3r/Fill/FillRectilinear2.cpp | 14 +++- xs/src/libslic3r/Fill/FillRectilinear2.hpp | 11 +++ xs/src/libslic3r/Geometry.cpp | 88 ++++++++++++++++++- xs/src/libslic3r/Geometry.hpp | 14 +--- xs/src/libslic3r/Point.cpp | 18 ---- xs/src/libslic3r/Point.hpp | 10 ++- xs/src/libslic3r/Print.cpp | 1 - xs/src/libslic3r/PrintConfig.cpp | 10 +-- xs/src/libslic3r/PrintConfig.hpp | 5 +- xs/src/libslic3r/libslic3r.h | 1 + xs/xsp/XS.xsp | 6 ++ 25 files changed, 148 insertions(+), 237 deletions(-) delete mode 100644 lib/Slic3r/GCode/VibrationLimit.pm delete mode 100644 t/vibrationlimit.t diff --git a/README.md b/README.md index 078edec75..d1254395b 100644 --- a/README.md +++ b/README.md @@ -140,8 +140,6 @@ The author of the Silk icon set is Mark James. --gcode-arcs Use G2/G3 commands for native arcs (experimental, not supported by all firmwares) --gcode-comments Make G-code verbose by adding comments (default: no) - --vibration-limit Limit the frequency of moves on X and Y axes (Hz, set zero to disable; - default: 0) --pressure-advance Adjust pressure using the experimental advance algorithm (K constant, set zero to disable; default: 0) diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index 77e45688e..b7c265c41 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -11,6 +11,7 @@ use warnings; require v5.10; our $VERSION = VERSION(); +our $FORK_NAME = FORK_NAME(); our $debug = 0; sub debugf { @@ -67,7 +68,6 @@ use Slic3r::GCode::MotionPlanner; use Slic3r::GCode::PressureRegulator; use Slic3r::GCode::Reader; use Slic3r::GCode::SpiralVase; -use Slic3r::GCode::VibrationLimit; use Slic3r::Geometry qw(PI); use Slic3r::Geometry::Clipper; use Slic3r::Layer; diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index 9324c824a..b4cfaa5d9 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -12,7 +12,7 @@ use List::Util qw(first max); our @Ignore = qw(duplicate_x duplicate_y multiply_x multiply_y support_material_tool acceleration adjust_overhang_flow standby_temperature scale rotate duplicate duplicate_grid rotate scale duplicate_grid start_perimeters_at_concave_points start_perimeters_at_non_overhang - randomize_start seal_position bed_size print_center g0); + randomize_start seal_position bed_size print_center g0 vibration_limit); # C++ Slic3r::PrintConfigDef exported as a Perl hash of hashes. # The C++ counterpart is a constant singleton. diff --git a/lib/Slic3r/GCode/VibrationLimit.pm b/lib/Slic3r/GCode/VibrationLimit.pm deleted file mode 100644 index 496d1e73a..000000000 --- a/lib/Slic3r/GCode/VibrationLimit.pm +++ /dev/null @@ -1,63 +0,0 @@ -package Slic3r::GCode::VibrationLimit; -use Moo; - -extends 'Slic3r::GCode::Reader'; - -has '_min_time' => (is => 'lazy'); -has '_last_dir' => (is => 'ro', default => sub { [0,0] }); -has '_dir_time' => (is => 'ro', default => sub { [0,0] }); - -# inspired by http://hydraraptor.blogspot.it/2010/12/frequency-limit.html - -use List::Util qw(max); - -sub _build__min_time { - my ($self) = @_; - return 1 / ($self->config->vibration_limit * 60); # in minutes -} - -sub process { - my $self = shift; - my ($gcode) = @_; - - my $new_gcode = ""; - $self->parse($gcode, sub { - my ($reader, $cmd, $args, $info) = @_; - - if ($cmd eq 'G1' && $info->{dist_XY} > 0) { - my $point = Slic3r::Pointf->new($args->{X} // $reader->X, $args->{Y} // $reader->Y); - my @dir = ( - ($point->x <=> $reader->X), - ($point->y <=> $reader->Y), #$ - ); - my $time = $info->{dist_XY} / ($args->{F} // $reader->F); # in minutes - - if ($time > 0) { - my @pause = (); - foreach my $axis (0..$#dir) { - if ($dir[$axis] != 0 && $self->_last_dir->[$axis] != $dir[$axis]) { - if ($self->_last_dir->[$axis] != 0) { - # this axis is changing direction: check whether we need to pause - if ($self->_dir_time->[$axis] < $self->_min_time) { - push @pause, ($self->_min_time - $self->_dir_time->[$axis]); - } - } - $self->_last_dir->[$axis] = $dir[$axis]; - $self->_dir_time->[$axis] = 0; - } - $self->_dir_time->[$axis] += $time; - } - - if (@pause) { - $new_gcode .= sprintf "G4 P%d\n", max(@pause) * 60 * 1000; - } - } - } - - $new_gcode .= $info->{raw} . "\n"; - }); - - return $new_gcode; -} - -1; diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index c95e9afbb..b91930870 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -90,6 +90,7 @@ sub OnInit { my ($self) = @_; $self->SetAppName('Slic3r'); + $self->SetAppDisplayName('Slic3r Prusa Edition'); Slic3r::debugf "wxWidgets version %s, Wx version %s\n", &Wx::wxVERSION_STRING, $Wx::VERSION; $self->{notifier} = Slic3r::GUI::Notifier->new; diff --git a/lib/Slic3r/GUI/AboutDialog.pm b/lib/Slic3r/GUI/AboutDialog.pm index 7b9625976..398fde97d 100644 --- a/lib/Slic3r/GUI/AboutDialog.pm +++ b/lib/Slic3r/GUI/AboutDialog.pm @@ -27,7 +27,7 @@ sub new { $hsizer->Add($vsizer, 1, wxEXPAND, 0); # title - my $title = Wx::StaticText->new($self, -1, 'Slic3r', wxDefaultPosition, wxDefaultSize); + my $title = Wx::StaticText->new($self, -1, $Slic3r::FORK_NAME, wxDefaultPosition, wxDefaultSize); my $title_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); $title_font->SetWeight(wxFONTWEIGHT_BOLD); $title_font->SetFamily(wxFONTFAMILY_ROMAN); @@ -47,6 +47,7 @@ sub new { '' . '' . '' . + 'Copyright © 2016 Vojtech Bubnik, Prusa Research.
' . 'Copyright © 2011-2016 Alessandro Ranellucci.
' . 'Slic3r is licensed under the ' . 'GNU Affero General Public License, version 3.' . diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 6a367b807..3b7d7ef46 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -20,7 +20,7 @@ our $last_config; sub new { my ($class, %params) = @_; - my $self = $class->SUPER::new(undef, -1, 'Slic3r', wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE); + my $self = $class->SUPER::new(undef, -1, $Slic3r::FORK_NAME . ' - ' . $Slic3r::VERSION, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE); $self->SetIcon(Wx::Icon->new($Slic3r::var->("Slic3r_128px.png"), wxBITMAP_TYPE_PNG) ); # store input params @@ -37,7 +37,7 @@ sub new { # initialize status bar $self->{statusbar} = Slic3r::GUI::ProgressStatusBar->new($self, -1); - $self->{statusbar}->SetStatusText("Version $Slic3r::VERSION - Remember to check for updates at http://slic3r.org/"); + $self->{statusbar}->SetStatusText("Version $Slic3r::VERSION - Remember to check for updates at http://github.com/prusa3d/slic3r/releases"); $self->SetStatusBar($self->{statusbar}); $self->{loaded} = 1; @@ -294,13 +294,19 @@ sub _init_menubar { $self->config_wizard; }); $helpMenu->AppendSeparator(); + $self->_append_menu_item($helpMenu, "Prusa 3D Drivers", 'Open the Prusa3D drivers download page in your browser', sub { + Wx::LaunchDefaultBrowser('http://www.prusa3d.com/drivers/'); + }); + $self->_append_menu_item($helpMenu, "Prusa Edition Releases", 'Open the Prusa Edition releases page in your browser', sub { + Wx::LaunchDefaultBrowser('http://github.com/prusa3d/slic3r/releases'); + }); +# my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", 'Check for new Slic3r versions', sub { +# wxTheApp->check_version(1); +# }); +# $versioncheck->Enable(wxTheApp->have_version_check); $self->_append_menu_item($helpMenu, "Slic3r &Website", 'Open the Slic3r website in your browser', sub { Wx::LaunchDefaultBrowser('http://slic3r.org/'); }); - my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", 'Check for new Slic3r versions', sub { - wxTheApp->check_version(1); - }); - $versioncheck->Enable(wxTheApp->have_version_check); $self->_append_menu_item($helpMenu, "Slic3r &Manual", 'Open the Slic3r manual in your browser', sub { Wx::LaunchDefaultBrowser('http://manual.slic3r.org/'); }); diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index 34fb2dabe..c05465664 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -1002,7 +1002,7 @@ sub build { gcode_flavor use_relative_e_distances serial_port serial_speed octoprint_host octoprint_apikey - use_firmware_retraction pressure_advance vibration_limit + use_firmware_retraction pressure_advance use_volumetric_e start_gcode end_gcode before_layer_gcode layer_gcode toolchange_gcode nozzle_diameter extruder_offset @@ -1208,7 +1208,6 @@ sub build { $optgroup->append_single_option_line('use_firmware_retraction'); $optgroup->append_single_option_line('use_volumetric_e'); $optgroup->append_single_option_line('pressure_advance'); - $optgroup->append_single_option_line('vibration_limit'); } } { diff --git a/lib/Slic3r/Print/GCode.pm b/lib/Slic3r/Print/GCode.pm index d39241949..d837a4637 100644 --- a/lib/Slic3r/Print/GCode.pm +++ b/lib/Slic3r/Print/GCode.pm @@ -7,7 +7,6 @@ has 'fh' => (is => 'ro', required => 1); has '_gcodegen' => (is => 'rw'); has '_cooling_buffer' => (is => 'rw'); has '_spiral_vase' => (is => 'rw'); -has '_vibration_limit' => (is => 'rw'); has '_arc_fitting' => (is => 'rw'); has '_pressure_regulator' => (is => 'rw'); has '_pressure_equalizer' => (is => 'rw'); @@ -109,9 +108,6 @@ sub BUILD { $self->_spiral_vase(Slic3r::GCode::SpiralVase->new(config => $self->config)) if $self->config->spiral_vase; - $self->_vibration_limit(Slic3r::GCode::VibrationLimit->new(config => $self->config)) - if $self->config->vibration_limit != 0; - $self->_arc_fitting(Slic3r::GCode::ArcFitting->new(config => $self->config)) if $self->config->gcode_arcs; @@ -664,11 +660,6 @@ sub filter { my ($self, $gcode, $flush) = @_; $flush //= 0; - # apply vibration limit if enabled; - # this injects pauses according to time (thus depends on actual speeds) - $gcode = $self->_vibration_limit->process($gcode) - if defined $self->_vibration_limit; - # apply pressure regulation if enabled; # this depends on actual speeds $gcode = $self->_pressure_regulator->process($gcode, $flush) diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 17852a528..5ca29789c 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -685,7 +685,7 @@ sub _support_material { flow => $self->support_material_flow, interface_flow => $self->support_material_flow(FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE), soluble_interface => ($self->config->support_material_contact_distance == 0), - ); + ); } } diff --git a/slic3r.pl b/slic3r.pl index f320c3ab2..f6fe4bb4f 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -306,8 +306,6 @@ $j --gcode-arcs Use G2/G3 commands for native arcs (experimental, not supported by all firmwares) --gcode-comments Make G-code verbose by adding comments (default: no) - --vibration-limit Limit the frequency of moves on X and Y axes (Hz, set zero to disable; - default: $config->{vibration_limit}) --pressure-advance Adjust pressure using the experimental advance algorithm (K constant, set zero to disable; default: $config->{pressure_advance}) diff --git a/t/cooling.t b/t/cooling.t index 9958037f1..f39fa0f52 100644 --- a/t/cooling.t +++ b/t/cooling.t @@ -109,7 +109,6 @@ $config->set('disable_fan_first_layers', 0); $config->set('bridge_speed', 99); $config->set('top_solid_layers', 1); # internal bridges use solid_infil speed $config->set('bottom_solid_layers', 1); # internal bridges use solid_infil speed - $config->set('vibration_limit', 30); # test that fan is turned on even when vibration limit (or other G-code post-processor) is enabled my $print = Slic3r::Test::init_print('overhang', config => $config); my $fan = 0; diff --git a/t/vibrationlimit.t b/t/vibrationlimit.t deleted file mode 100644 index 7bfa27acb..000000000 --- a/t/vibrationlimit.t +++ /dev/null @@ -1,98 +0,0 @@ -use Test::More tests => 9; -use strict; -use warnings; - -BEGIN { - use FindBin; - use lib "$FindBin::Bin/../lib"; -} - -use Slic3r; -use Slic3r::Geometry qw(epsilon); -use Slic3r::Test; - -my $config = Slic3r::Config->new_from_defaults; - -# tolerance, in minutes -# (our time estimation differs from the internal one because of decimals truncation) -my $epsilon = 0.002; - -my $test = sub { - my ($conf) = @_; - $conf ||= $config; - - my $print = Slic3r::Test::init_print('2x20x10', config => $conf); - - my $min_time = 1 / ($conf->vibration_limit * 60); # minimum time between direction changes in minutes - my %dir = (X => 0, Y => 0); - my %dir_time = (X => 0, Y => 0); - my %dir_sleep_time = (X => 0, Y => 0); - my $last_cmd_pause = 0; - Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { - my ($self, $cmd, $args, $info) = @_; - - if ($cmd !~ /^G[01]$/) { - if ($cmd eq 'G4') { - $last_cmd_pause = (($args->{P} // 0) / 1000 + ($args->{S} // 0)) / 60; # in minutes - $dir_sleep_time{$_} += $last_cmd_pause for qw(X Y); - $last_cmd_pause -= $epsilon; # error builds up - } - return; - } - - # Z moves are slow enough that we can consider any vibration interrupted - if ($info->{dist_Z}) { - $dir_time{$_} += 99999 for qw(X Y); - $last_cmd_pause = 0; - return; - } elsif ($info->{dist_E} != 0 && $info->{dist_XY} == 0) { - my $time = abs($info->{dist_E}) / ($args->{F} // $self->F); # in minutes - $dir_time{$_} += $time for qw(X Y); - $last_cmd_pause = 0; - return; - } - - # compute move time (this assumes that the speed is XY-bound, which happens very likely) - my $time = abs($info->{dist_XY}) / ($args->{F} // $self->F); # in minutes - - my $one_axis_would_trigger_limit_without_pause = 0; - foreach my $axis (qw(X Y)) { - # get the direction by comparing the new $axis coordinate with the current one - # 1 = positive, 0 = no change, -1 = negative - my $dir = $info->{"new_$axis"} <=> $self->$axis; - - # are we changing direction on this axis? - if ($dir != 0 && $dir{$axis} != $dir) { - # this move changes direction on this axis - if ($dir{$axis} != 0) { - if (($dir_time{$axis} + $dir_sleep_time{$axis}) < ($min_time - $epsilon)) { - fail 'vibration limit exceeded'; - } - $one_axis_would_trigger_limit_without_pause = 1 - if ($dir_time{$axis} - $last_cmd_pause) < $min_time; - } - $dir{$axis} = $dir; - $dir_time{$axis} = 0; - $dir_sleep_time{$axis} = 0; - } - $dir_time{$axis} += $time; - } - fail 'no unnecessary pauses are added' - if $last_cmd_pause > $epsilon && !$one_axis_would_trigger_limit_without_pause; - - $last_cmd_pause = 0; - }); - - 1; -}; - -$config->set('gcode_comments', 1); -$config->set('perimeters', 1); -foreach my $frequency (5, 10, 15) { - foreach my $gapfillspeed (20, 50, 100) { - $config->set('vibration_limit', $frequency); - ok $test->(), "vibrations limited to ${frequency}Hz (gap fill speed = ${gapfillspeed} mm/s)"; - } -} - -__END__ diff --git a/xs/src/libslic3r/Fill/FillBase.cpp b/xs/src/libslic3r/Fill/FillBase.cpp index 42c1f5ab2..ba3a5ee47 100644 --- a/xs/src/libslic3r/Fill/FillBase.cpp +++ b/xs/src/libslic3r/Fill/FillBase.cpp @@ -24,6 +24,7 @@ Fill* Fill::new_from_type(const InfillPattern type) // case ipRectilinear: return new FillRectilinear(); case ipLine: return new FillLine(); case ipGrid: return new FillGrid2(); + case ipTriangles: return new FillTriangles(); // case ipGrid: return new FillGrid(); case ipArchimedeanChords: return new FillArchimedeanChords(); case ipHilbertCurve: return new FillHilbertCurve(); diff --git a/xs/src/libslic3r/Fill/FillRectilinear2.cpp b/xs/src/libslic3r/Fill/FillRectilinear2.cpp index 728926eb2..5b37ddf84 100644 --- a/xs/src/libslic3r/Fill/FillRectilinear2.cpp +++ b/xs/src/libslic3r/Fill/FillRectilinear2.cpp @@ -1449,10 +1449,20 @@ Polylines FillGrid2::fill_surface(const Surface *surface, const FillParams ¶ Polylines polylines_out; if (! fill_surface_by_lines(surface, params, 0.f, polylines_out) || ! fill_surface_by_lines(surface, params, float(M_PI / 2.), polylines_out)) { - printf("FillRectilinear2::fill_surface() failed to fill a region.\n"); + printf("FillGrid2::fill_surface() failed to fill a region.\n"); + } + return polylines_out; } + +Polylines FillTriangles::fill_surface(const Surface *surface, const FillParams ¶ms) +{ + Polylines polylines_out; + if (! fill_surface_by_lines(surface, params, 0.f, polylines_out) || + ! fill_surface_by_lines(surface, params, float(M_PI / 3.), polylines_out) || + ! fill_surface_by_lines(surface, params, float(2. * M_PI / 3.), polylines_out)) { + printf("FillTriangles::fill_surface() failed to fill a region.\n"); + } return polylines_out; } } // namespace Slic3r - \ No newline at end of file diff --git a/xs/src/libslic3r/Fill/FillRectilinear2.hpp b/xs/src/libslic3r/Fill/FillRectilinear2.hpp index dc0832b0e..dffa8921c 100644 --- a/xs/src/libslic3r/Fill/FillRectilinear2.hpp +++ b/xs/src/libslic3r/Fill/FillRectilinear2.hpp @@ -35,6 +35,17 @@ protected: virtual float _layer_angle(size_t idx) const { return 0.f; } }; +class FillTriangles : public FillRectilinear2 +{ +public: + virtual ~FillTriangles() {} + virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms); + +protected: + // The grid fill will keep the angle constant between the layers, see the implementation of Slic3r::Fill::Base. + virtual float _layer_angle(size_t idx) const { return 0.f; } +}; + }; // namespace Slic3r #endif // slic3r_FillRectilinear2_hpp_ diff --git a/xs/src/libslic3r/Geometry.cpp b/xs/src/libslic3r/Geometry.cpp index e61f83355..8a36e12cd 100644 --- a/xs/src/libslic3r/Geometry.cpp +++ b/xs/src/libslic3r/Geometry.cpp @@ -343,9 +343,92 @@ linint(double value, double oldmin, double oldmax, double newmin, double newmax) return (value - oldmin) * (newmax - newmin) / (oldmax - oldmin) + newmin; } -Pointfs -arrange(size_t total_parts, Pointf part, coordf_t dist, const BoundingBoxf* bb) +#if 0 +// Point with a weight, by which the points are sorted. +// If the points have the same weight, sort them lexicographically by their positions. +struct ArrangeItem { + ArrangeItem() {} + Pointf pos; + coordf_t weight; + bool operator<(const ArrangeItem &other) const { + return weight < other.weight || + ((weight == other.weight) && (pos.y < other.pos.y || (pos.y == other.pos.y && pos.x < other.pos.x))); + } +}; + +Pointfs arrange(size_t num_parts, const Pointf &part_size, coordf_t gap, const BoundingBoxf* bed_bounding_box) { + // Use actual part size (the largest) plus separation distance (half on each side) in spacing algorithm. + const Pointf cell_size(part_size.x + gap, part_size.y + gap); + + const BoundingBoxf bed_bbox = (bed_bounding_box != NULL && bed_bounding_box->defined) ? + *bed_bounding_box : + // Bogus bed size, large enough not to trigger the unsufficient bed size error. + BoundingBoxf( + Pointf(0, 0), + Pointf(cell_size.x * num_parts, cell_size.y * num_parts)); + + // This is how many cells we have available into which to put parts. + size_t cellw = size_t(floor((bed_bbox.size().x + gap) / cell_size.x)); + size_t cellh = size_t(floor((bed_bbox.size().y + gap) / cell_size.y)); + if (num_parts > cellw * cellh) + CONFESS("%zu parts won't fit in your print area!\n", num_parts); + + // Get a bounding box of cellw x cellh cells, centered at the center of the bed. + Pointf cells_size(cellw * cell_size.x - gap, cellh * cell_size.y - gap); + Pointf cells_offset(bed_bbox.center() - 0.5 * cells_size); + BoundingBoxf cells_bb(cells_offset, cells_size + cells_offset); + + // List of cells, sorted by distance from center. + std::vector cellsorder(cellw * cellh, ArrangeItem()); + for (size_t j = 0; j < cellh; ++ j) { + // Center of the jth row on the bed. + coordf_t cy = linint(j + 0.5, 0., double(cellh), cells_bb.min.y, cells_bb.max.y); + // Offset from the bed center. + coordf_t yd = cells_bb.center().y - cy; + for (size_t i = 0; i < cellw; ++ i) { + // Center of the ith column on the bed. + coordf_t cx = linint(i + 0.5, 0., double(cellw), cells_bb.min.x, cells_bb.max.x); + // Offset from the bed center. + coordf_t xd = cells_bb.center().x - cx; + // Cell with a distance from the bed center. + ArrangeItem &ci = cellsorder[j * cellw + i]; + // Cell center + ci.pos.x = cx; + ci.pos.y = cy; + // Square distance of the cell center to the bed center. + ci.weight = xd * xd + yd * yd; + } + } + // Sort the cells lexicographically by their distances to the bed center and left to right / bttom to top. + std::sort(cellsorder.begin(), cellsorder.end()); + cellsorder.erase(cellsorder.begin() + num_parts, cellsorder.end()); + + // Return the (left,top) corners of the cells. + Pointfs positions; + positions.reserve(num_parts); + for (std::vector::const_iterator it = cellsorder.begin(); it != cellsorder.end(); ++ it) + positions.push_back(Pointf(it->pos.x - 0.5 * part_size.x, it->pos.y - 0.5 * part_size.y)); + return positions; +} +#else +class ArrangeItem { + public: + Pointf pos; + size_t index_x, index_y; + coordf_t dist; +}; +class ArrangeItemIndex { + public: + coordf_t index; + ArrangeItem item; + ArrangeItemIndex(coordf_t _index, ArrangeItem _item) : index(_index), item(_item) {}; +}; +Pointfs +arrange(size_t total_parts, const Pointf &part_size, coordf_t dist, const BoundingBoxf* bb) +{ + Pointf part = part_size; + // use actual part size (the largest) plus separation distance (half on each side) in spacing algorithm part.x += dist; part.y += dist; @@ -463,6 +546,7 @@ arrange(size_t total_parts, Pointf part, coordf_t dist, const BoundingBoxf* bb) return positions; } +#endif #ifdef SLIC3R_DEBUG // The following code for the visualization of the boost Voronoi diagram is based on: diff --git a/xs/src/libslic3r/Geometry.hpp b/xs/src/libslic3r/Geometry.hpp index 75762a8c8..2c05c1e38 100644 --- a/xs/src/libslic3r/Geometry.hpp +++ b/xs/src/libslic3r/Geometry.hpp @@ -25,20 +25,8 @@ double rad2deg_dir(double angle); double deg2rad(double angle); void simplify_polygons(const Polygons &polygons, double tolerance, Polygons* retval); -class ArrangeItem { - public: - Pointf pos; - size_t index_x, index_y; - coordf_t dist; -}; -class ArrangeItemIndex { - public: - coordf_t index; - ArrangeItem item; - ArrangeItemIndex(coordf_t _index, ArrangeItem _item) : index(_index), item(_item) {}; -}; double linint(double value, double oldmin, double oldmax, double newmin, double newmax); -Pointfs arrange(size_t total_parts, Pointf part, coordf_t dist, const BoundingBoxf* bb); +Pointfs arrange(size_t num_parts, const Pointf &part_size, coordf_t gap, const BoundingBoxf* bed_bounding_box); class MedialAxis { public: diff --git a/xs/src/libslic3r/Point.cpp b/xs/src/libslic3r/Point.cpp index 6dbcc6f00..8b71746e0 100644 --- a/xs/src/libslic3r/Point.cpp +++ b/xs/src/libslic3r/Point.cpp @@ -312,24 +312,6 @@ Point::vector_to(const Point &point) const return Vector(point.x - this->x, point.y - this->y); } -Point -operator+(const Point& point1, const Point& point2) -{ - return Point(point1.x + point2.x, point1.y + point2.y); -} - -Point -operator-(const Point& point1, const Point& point2) -{ - return Point(point1.x - point2.x, point1.y - point2.y); -} - -Point -operator*(double scalar, const Point& point2) -{ - return Point(scalar * point2.x, scalar * point2.y); -} - std::ostream& operator<<(std::ostream &stm, const Pointf &pointf) { diff --git a/xs/src/libslic3r/Point.hpp b/xs/src/libslic3r/Point.hpp index 58747690a..2cf046133 100644 --- a/xs/src/libslic3r/Point.hpp +++ b/xs/src/libslic3r/Point.hpp @@ -66,9 +66,9 @@ class Point Vector vector_to(const Point &point) const; }; -Point operator+(const Point& point1, const Point& point2); -Point operator-(const Point& point1, const Point& point2); -Point operator*(double scalar, const Point& point2); +inline Point operator+(const Point& point1, const Point& point2) { return Point(point1.x + point2.x, point1.y + point2.y); } +inline Point operator-(const Point& point1, const Point& point2) { return Point(point1.x - point2.x, point1.y - point2.y); } +inline Point operator*(double scalar, const Point& point2) { return Point(scalar * point2.x, scalar * point2.y); } class Point3 : public Point { @@ -102,6 +102,10 @@ class Pointf Vectorf vector_to(const Pointf &point) const; }; +inline Pointf operator+(const Pointf& point1, const Pointf& point2) { return Pointf(point1.x + point2.x, point1.y + point2.y); } +inline Pointf operator-(const Pointf& point1, const Pointf& point2) { return Pointf(point1.x - point2.x, point1.y - point2.y); } +inline Pointf operator*(double scalar, const Pointf& point2) { return Pointf(scalar * point2.x, scalar * point2.y); } + class Pointf3 : public Pointf { public: diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 329843f5c..b22d16999 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -233,7 +233,6 @@ Print::invalidate_state_by_config_options(const std::vector || *opt_key == "travel_speed" || *opt_key == "use_firmware_retraction" || *opt_key == "use_relative_e_distances" - || *opt_key == "vibration_limit" || *opt_key == "wipe" || *opt_key == "z_offset" || *opt_key == "max_volumetric_extrusion_rate_slope_negative" diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 1e05380e9..bbbe52123 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -371,6 +371,7 @@ PrintConfigDef::PrintConfigDef() def->enum_keys_map = ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("rectilinear"); def->enum_values.push_back("grid"); + def->enum_values.push_back("triangles"); def->enum_values.push_back("line"); def->enum_values.push_back("concentric"); def->enum_values.push_back("honeycomb"); @@ -380,6 +381,7 @@ PrintConfigDef::PrintConfigDef() def->enum_values.push_back("octagramspiral"); def->enum_labels.push_back("Rectilinear"); def->enum_labels.push_back("Grid"); + def->enum_labels.push_back("Triangles"); def->enum_labels.push_back("Line"); def->enum_labels.push_back("Concentric"); def->enum_labels.push_back("Honeycomb"); @@ -1325,14 +1327,6 @@ PrintConfigDef::PrintConfigDef() def->cli = "use-volumetric-e!"; def->default_value = new ConfigOptionBool(false); - def = this->add("vibration_limit", coFloat); - def->label = "Vibration limit (deprecated)"; - def->tooltip = "This experimental option will slow down those moves hitting the configured frequency limit. The purpose of limiting vibrations is to avoid mechanical resonance. Set zero to disable."; - def->sidetext = "Hz"; - def->cli = "vibration-limit=f"; - def->min = 0; - def->default_value = new ConfigOptionFloat(0); - def = this->add("wipe", coBools); def->label = "Wipe while retracting"; def->tooltip = "This flag will move the nozzle while retracting to minimize the possible blob on leaky extruders."; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index b7cd3a995..34dbe3645 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -30,7 +30,7 @@ enum GCodeFlavor { }; enum InfillPattern { - ipRectilinear, ipGrid, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb, + ipRectilinear, ipGrid, ipTriangles, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, }; @@ -58,6 +58,7 @@ template<> inline t_config_enum_values ConfigOptionEnum::get_enum t_config_enum_values keys_map; keys_map["rectilinear"] = ipRectilinear; keys_map["grid"] = ipGrid; + keys_map["triangles"] = ipTriangles; keys_map["line"] = ipLine; keys_map["concentric"] = ipConcentric; keys_map["honeycomb"] = ipHoneycomb; @@ -413,7 +414,6 @@ class PrintConfig : public GCodeConfig ConfigOptionInt standby_temperature_delta; ConfigOptionInts temperature; ConfigOptionInt threads; - ConfigOptionFloat vibration_limit; ConfigOptionBools wipe; ConfigOptionFloat z_offset; @@ -470,7 +470,6 @@ class PrintConfig : public GCodeConfig OPT_PTR(standby_temperature_delta); OPT_PTR(temperature); OPT_PTR(threads); - OPT_PTR(vibration_limit); OPT_PTR(wipe); OPT_PTR(z_offset); diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h index 98ee7f03f..4f51f2c96 100644 --- a/xs/src/libslic3r/libslic3r.h +++ b/xs/src/libslic3r/libslic3r.h @@ -9,6 +9,7 @@ #include #include +#define SLIC3R_FORK_NAME "Slic3r Prusa Edition" #define SLIC3R_VERSION "1.3.0-dev" //FIXME This epsilon value is used for many non-related purposes: diff --git a/xs/xsp/XS.xsp b/xs/xsp/XS.xsp index 044332757..9b068882c 100644 --- a/xs/xsp/XS.xsp +++ b/xs/xsp/XS.xsp @@ -22,4 +22,10 @@ DEBUG_OUT_PATH_PREFIX() RETVAL = newSVpv(SLIC3R_DEBUG_OUT_PATH_PREFIX, 0); OUTPUT: RETVAL +SV* +FORK_NAME() + CODE: + RETVAL = newSVpv(SLIC3R_FORK_NAME, 0); + OUTPUT: RETVAL + %} \ No newline at end of file