diff options
author | bubnikv <bubnikv@gmail.com> | 2016-09-13 12:24:55 +0300 |
---|---|---|
committer | bubnikv <bubnikv@gmail.com> | 2016-09-13 12:24:55 +0300 |
commit | b2a6f439234e691421e74cdf7ff2b16e3c7a59d3 (patch) | |
tree | f826696b5341bec80a6b410f88e34c42b429475c /lib | |
parent | 6dfe4c0b964a7063bf2d52b2bd89cdbbed59a2c1 (diff) |
Documented perl modules.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Slic3r.pm | 35 | ||||
-rw-r--r-- | lib/Slic3r/Config.pm | 25 | ||||
-rw-r--r-- | lib/Slic3r/GCode/CoolingBuffer.pm | 17 | ||||
-rw-r--r-- | lib/Slic3r/GCode/PressureRegulator.pm | 2 | ||||
-rw-r--r-- | lib/Slic3r/GUI.pm | 3 | ||||
-rw-r--r-- | lib/Slic3r/GUI/Plater.pm | 4 | ||||
-rw-r--r-- | lib/Slic3r/Layer.pm | 2 | ||||
-rw-r--r-- | lib/Slic3r/Model.pm | 3 | ||||
-rw-r--r-- | lib/Slic3r/Print.pm | 3 | ||||
-rw-r--r-- | lib/Slic3r/Print/Object.pm | 13 | ||||
-rw-r--r-- | lib/Slic3r/Print/Simple.pm | 8 | ||||
-rw-r--r-- | lib/Slic3r/Print/State.pm | 1 | ||||
-rw-r--r-- | lib/Slic3r/Test/SectionCut.pm | 1 |
13 files changed, 107 insertions, 10 deletions
diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index 4df83f99a..e9e7563c1 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -1,3 +1,6 @@ +# This package loads all the non-GUI Slic3r perl packages. +# In addition, it implements utility functions for file handling and threading. + package Slic3r; # Copyright holder: Alessandro Ranellucci @@ -26,10 +29,11 @@ BEGIN { $have_threads = 0 if $Moo::VERSION == 1.003000; } -warn "Running Slic3r under Perl 5.16 is not supported nor recommended\n" +warn "Running Slic3r under Perl 5.16 is neither supported nor recommended\n" if $^V == v5.16; use FindBin; +# Path to the images. our $var = sub { decode_path($FindBin::Bin) . "/var/" . $_[0] }; use Moo 1.003001; @@ -71,13 +75,16 @@ use Encode::Locale 1.05; use Encode; use Unicode::Normalize; +# Scaling between the float and integer coordinates. +# Floats are in mm. use constant SCALING_FACTOR => 0.000001; -use constant RESOLUTION => 0.0125; -use constant SCALED_RESOLUTION => RESOLUTION / SCALING_FACTOR; +# Resolution to simplify perimeters to. These constants are now used in C++ code only. Better to publish them to Perl from the C++ code. +# use constant RESOLUTION => 0.0125; +# use constant SCALED_RESOLUTION => RESOLUTION / SCALING_FACTOR; use constant LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER => 0.15; -use constant INFILL_OVERLAP_OVER_SPACING => 0.3; +# use constant INFILL_OVERLAP_OVER_SPACING => 0.3; -# keep track of threads we created +# Keep track of threads we created. Each thread keeps its own list of threads it spwaned. my @my_threads = (); my @threads : shared = (); my $pause_sema = Thread::Semaphore->new; @@ -113,6 +120,12 @@ sub spawn_thread { return $thread; } +# If the threading is enabled, spawn a set of threads. +# Otherwise run the task on the current thread. +# Used for +# Slic3r::Print::Object->layers->make_perimeters : This is a pure C++ function. +# Slic3r::Print::Object->layers->make_fill : This requires a rewrite of Fill.pm to C++. +# Slic3r::Print::SupportMaterial::generate_toolpaths sub parallelize { my %params = @_; @@ -176,7 +189,7 @@ sub thread_cleanup { warn "Calling thread_cleanup() from main thread\n"; return; } - + # prevent destruction of shared objects no warnings 'redefine'; *Slic3r::BridgeDetector::DESTROY = sub {}; @@ -195,7 +208,7 @@ sub thread_cleanup { *Slic3r::ExtrusionPath::Collection::DESTROY = sub {}; *Slic3r::ExtrusionSimulator::DESTROY = sub {}; *Slic3r::Flow::DESTROY = sub {}; - *Slic3r::Filler::Destroy = sub {}; + *Slic3r::Filler::DESTROY = sub {}; *Slic3r::GCode::DESTROY = sub {}; *Slic3r::GCode::AvoidCrossingPerimeters::DESTROY = sub {}; *Slic3r::GCode::OozePrevention::DESTROY = sub {}; @@ -268,6 +281,12 @@ sub resume_all_threads { $pause_sema->up; } +# Convert a Unicode path to a file system locale. +# The encoding is (from Encode::Locale POD): +# Alias | Windows | Mac OS X | POSIX +# locale_fs | ANSI | UTF-8 | nl_langinfo +# where nl_langinfo is en-US.UTF-8 on a modern Linux as well. +# So this conversion seems to make the most sense on Windows. sub encode_path { my ($path) = @_; @@ -277,6 +296,7 @@ sub encode_path { return $path; } +# Convert a path coded by a file system locale to Unicode. sub decode_path { my ($path) = @_; @@ -292,6 +312,7 @@ sub decode_path { return $path; } +# Open a file by converting $filename to local file system locales. sub open { my ($fh, $mode, $filename) = @_; return CORE::open $$fh, $mode, encode_path($filename); diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index a98565b83..9324c824a 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -1,3 +1,6 @@ +# Extends C++ class Slic3r::DynamicPrintConfig +# This perl class does not keep any perl class variables, +# all the storage is handled by the underlying C++ code. package Slic3r::Config; use strict; use warnings; @@ -11,6 +14,8 @@ our @Ignore = qw(duplicate_x duplicate_y multiply_x multiply_y support_material_ rotate scale duplicate_grid start_perimeters_at_concave_points start_perimeters_at_non_overhang randomize_start seal_position bed_size print_center g0); +# C++ Slic3r::PrintConfigDef exported as a Perl hash of hashes. +# The C++ counterpart is a constant singleton. our $Options = print_config_def(); # overwrite the hard-coded readonly value (this information is not available in XS) @@ -24,6 +29,8 @@ $Options->{threads}{readonly} = !$Slic3r::have_threads; } } +# Fill in the underlying C++ Slic3r::DynamicPrintConfig with the content of the defaults +# provided by the C++ class Slic3r::FullPrintConfig. sub new_from_defaults { my $class = shift; my (@opt_keys) = @_; @@ -39,12 +46,16 @@ sub new_from_defaults { return $self; } +# From command line parameters sub new_from_cli { my $class = shift; my %args = @_; + # Delete hash keys with undefined value. delete $args{$_} for grep !defined $args{$_}, keys %args; + # Replace the start_gcode, end_gcode ... hash values + # with the content of the files they reference. for (qw(start end layer toolchange)) { my $opt_key = "${_}_gcode"; if ($args{$opt_key}) { @@ -57,7 +68,7 @@ sub new_from_cli { } } } - + my $self = $class->new; foreach my $opt_key (keys %args) { my $opt_def = $Options->{$opt_key}; @@ -83,6 +94,8 @@ sub merge { return $config; } +# Load a flat ini file without a category into the underlying C++ Slic3r::DynamicConfig class, +# convert legacy configuration names. sub load { my $class = shift; my ($file) = @_; @@ -91,6 +104,8 @@ sub load { return $class->load_ini_hash($ini->{_}); } +# Deserialize a perl hash into the underlying C++ Slic3r::DynamicConfig class, +# convert legacy configuration names. sub load_ini_hash { my $class = shift; my ($ini_hash) = @_; @@ -175,6 +190,8 @@ sub _handle_legacy { return ($opt_key, $value); } +# Create a hash of hashes from the underlying C++ Slic3r::DynamicPrintConfig. +# The first hash key is '_' meaning no category. sub as_ini { my ($self) = @_; @@ -186,6 +203,7 @@ sub as_ini { return $ini; } +# Save the content of the underlying C++ Slic3r::DynamicPrintConfig as a flat ini file without any category. sub save { my $self = shift; my ($file) = @_; @@ -343,6 +361,7 @@ sub validate { # CLASS METHODS: +# Write a "Windows" style ini file with categories enclosed in squre brackets. sub write_ini { my $class = shift; my ($file, $ini) = @_; @@ -361,6 +380,10 @@ sub write_ini { close $fh; } +# Parse a "Windows" style ini file with categories enclosed in squre brackets. +# Returns a hash of hashes over strings. +# {category}{name}=value +# Non-categorized entries are stored under a category '_'. sub read_ini { my $class = shift; my ($file) = @_; diff --git a/lib/Slic3r/GCode/CoolingBuffer.pm b/lib/Slic3r/GCode/CoolingBuffer.pm index 19fb8d7a8..d960eae1e 100644 --- a/lib/Slic3r/GCode/CoolingBuffer.pm +++ b/lib/Slic3r/GCode/CoolingBuffer.pm @@ -1,9 +1,13 @@ +# A standalone (no C++ implementation) G-code filter, to control cooling of the print. +# The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited +# and the print is modified to stretch over a minimum layer time. + package Slic3r::GCode::CoolingBuffer; use Moo; has 'config' => (is => 'ro', required => 1); # Slic3r::Config::Print -has 'gcodegen' => (is => 'ro', required => 1); -has 'gcode' => (is => 'rw', default => sub {""}); +has 'gcodegen' => (is => 'ro', required => 1); # Slic3r::GCode C++ instance +has 'gcode' => (is => 'rw', default => sub {""}); # Cache of a G-code snippet emitted for a single layer. has 'elapsed_time' => (is => 'rw', default => sub {0}); has 'layer_id' => (is => 'rw'); has 'last_z' => (is => 'rw', default => sub { {} }); # obj_id => z (basically a 'last seen' table) @@ -20,12 +24,15 @@ sub append { my $return = ""; if (exists $self->last_z->{$obj_id} && $self->last_z->{$obj_id} != $print_z) { + # A layer was finished, Z of the object's layer changed. Process the layer. $return = $self->flush; } $self->layer_id($layer_id); $self->last_z->{$obj_id} = $print_z; $self->gcode($self->gcode . $gcode); + #FIXME Vojtech: This is a very rough estimate of the print time, + # not taking into account the acceleration profiles generated by the printer firmware. $self->elapsed_time($self->elapsed_time + $self->gcodegen->elapsed_time); $self->gcodegen->set_elapsed_time(0); @@ -46,9 +53,12 @@ sub flush { if ($self->config->cooling) { Slic3r::debugf "Layer %d estimated printing time: %d seconds\n", $self->layer_id, $elapsed; if ($elapsed < $self->config->slowdown_below_layer_time) { + # Layer time very short. Enable the fan to a full throttle and slow down the print + # (stretch the layer print time to slowdown_below_layer_time). $fan_speed = $self->config->max_fan_speed; $speed_factor = $elapsed / $self->config->slowdown_below_layer_time; } elsif ($elapsed < $self->config->fan_below_layer_time) { + # Layer time quite short. Enable the fan proportionally according to the current layer time. $fan_speed = $self->config->max_fan_speed - ($self->config->max_fan_speed - $self->config->min_fan_speed) * ($elapsed - $self->config->slowdown_below_layer_time) / ($self->config->fan_below_layer_time - $self->config->slowdown_below_layer_time); #/ @@ -56,6 +66,9 @@ sub flush { Slic3r::debugf " fan = %d%%, speed = %d%%\n", $fan_speed, $speed_factor * 100; if ($speed_factor < 1) { + # Adjust feed rate of G1 commands marked with an _EXTRUDE_SET_SPEED + # as long as they are not _WIPE moves (they cannot if they are _EXTRUDE_SET_SPEED) + # and they are not preceded directly by _BRIDGE_FAN_START (do not adjust bridging speed). $gcode =~ s/^(?=.*?;_EXTRUDE_SET_SPEED)(?!.*?;_WIPE)(?<!;_BRIDGE_FAN_START\n)(G1\sF)(\d+(?:\.\d+)?)/ my $new_speed = $2 * $speed_factor; $1 . sprintf("%.3f", $new_speed < $self->min_print_speed ? $self->min_print_speed : $new_speed) diff --git a/lib/Slic3r/GCode/PressureRegulator.pm b/lib/Slic3r/GCode/PressureRegulator.pm index 6074b9486..d03094ab2 100644 --- a/lib/Slic3r/GCode/PressureRegulator.pm +++ b/lib/Slic3r/GCode/PressureRegulator.pm @@ -1,3 +1,5 @@ +# A pure perl (no C++ implementation) G-code filter, to control the pressure inside the nozzle. + package Slic3r::GCode::PressureRegulator; use Moo; diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index 7f4a028a5..c95e9afbb 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -95,6 +95,9 @@ sub OnInit { $self->{notifier} = Slic3r::GUI::Notifier->new; # locate or create data directory + # Unix: ~/.Slic3r + # Windows: "C:\Users\username\AppData\Roaming\Slic3r" or "C:\Documents and Settings\username\Application Data\Slic3r" + # Mac: "~/Library/Application Support/Slic3r" $datadir ||= Slic3r::decode_path(Wx::StandardPaths::Get->GetUserDataDir); my $enc_datadir = Slic3r::encode_path($datadir); Slic3r::debugf "Data directory: %s\n", $datadir; diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 79e9ae259..4c8283c95 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -51,6 +51,7 @@ sub new { )); $self->{model} = Slic3r::Model->new; $self->{print} = Slic3r::Print->new; + # List of Perl objects Slic3r::GUI::Plater::Object, representing a 2D preview of the platter. $self->{objects} = []; $self->{print}->set_status_cb(sub { @@ -976,6 +977,8 @@ sub schedule_background_process { } } +# Executed asynchronously by a timer every PROCESS_DELAY (0.5 second). +# The timer is started by schedule_background_process(), sub async_apply_config { my ($self) = @_; @@ -1848,6 +1851,7 @@ sub OnDropFiles { $self->{window}->load_file($_) for @$filenames; } +# 2D preview of an object. Each object is previewed by its convex hull. package Slic3r::GUI::Plater::Object; use Moo; diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index 32a6e62fc..59df3d28f 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -1,3 +1,5 @@ +# Extends the C++ class Slic3r::Layer. + package Slic3r::Layer; use strict; use warnings; diff --git a/lib/Slic3r/Model.pm b/lib/Slic3r/Model.pm index 057c1f7fe..39daa753f 100644 --- a/lib/Slic3r/Model.pm +++ b/lib/Slic3r/Model.pm @@ -1,3 +1,4 @@ +# extends C++ class Slic3r::Model package Slic3r::Model; use List::Util qw(first max any); @@ -99,6 +100,7 @@ sub convert_multipart_object { $self->delete_object($_) for reverse 0..($self->objects_count-2); } +# Extends C++ class Slic3r::ModelMaterial package Slic3r::Model::Material; sub apply { @@ -106,6 +108,7 @@ sub apply { $self->set_attribute($_, $attributes{$_}) for keys %$attributes; } +# Extends C++ class Slic3r::ModelObject package Slic3r::Model::Object; use File::Basename qw(basename); diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 053fcdef9..d349eb1a0 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -1,3 +1,5 @@ +# The slicing work horse. +# Extends C++ class Slic3r::Print package Slic3r::Print; use strict; use warnings; @@ -89,6 +91,7 @@ sub export_gcode { } } +# Export SVG slices for the offline SLA printing. sub export_svg { my $self = shift; my %params = @_; diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 78e4c0f71..919bb10e8 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -1,4 +1,5 @@ package Slic3r::Print::Object; +# extends c++ class Slic3r::PrintObject (Print.xsp) use strict; use warnings; @@ -32,6 +33,14 @@ sub support_layers { return [ map $self->get_support_layer($_), 0..($self->support_layer_count - 1) ]; } +# 1) Decides Z positions of the layers, +# 2) Initializes layers and their regions +# 3) Slices the object meshes +# 4) Slices the modifier meshes and reclassifies the slices of the object meshes by the slices of the modifier meshes +# 5) Applies size compensation (offsets the slices in XY plane) +# 6) Replaces bad slices by the slices reconstructed from the upper/lower layer +# Resulting expolygons of layer regions are marked as Internal. +# # this should be idempotent sub slice { my $self = shift; @@ -326,6 +335,7 @@ sub slice { $self->set_step_done(STEP_SLICE); } +# called from slice() sub _slice_region { my ($self, $region_id, $z, $modifier) = @_; @@ -1110,6 +1120,9 @@ sub combine_infill { } } +# Simplify the sliced model, if "resolution" configuration parameter > 0. +# The simplification is problematic, because it simplifies the slices independent from each other, +# which makes the simplified discretization visible on the object surface. sub _simplify_slices { my ($self, $distance) = @_; diff --git a/lib/Slic3r/Print/Simple.pm b/lib/Slic3r/Print/Simple.pm index d84d1cb53..3771bfe4a 100644 --- a/lib/Slic3r/Print/Simple.pm +++ b/lib/Slic3r/Print/Simple.pm @@ -1,3 +1,10 @@ +# A simple wrapper to quickly print a single model without a GUI. +# Used by the command line slic3r.pl, by command line utilities pdf-slic3s.pl and view-toolpaths.pl, +# and by the quick slice menu of the Slic3r GUI. +# +# It creates and owns an instance of Slic3r::Print to perform the slicing +# and it accepts an instance of Slic3r::Model from the outside. + package Slic3r::Print::Simple; use Moo; @@ -51,6 +58,7 @@ has 'output_file' => ( ); sub set_model { + # $model is of type Slic3r::Model my ($self, $model) = @_; # make method idempotent so that the object is reusable diff --git a/lib/Slic3r/Print/State.pm b/lib/Slic3r/Print/State.pm index 7220aa818..d242e3760 100644 --- a/lib/Slic3r/Print/State.pm +++ b/lib/Slic3r/Print/State.pm @@ -1,3 +1,4 @@ +# Wraps C++ enums Slic3r::PrintStep and Slic3r::PrintObjectStep package Slic3r::Print::State; use strict; use warnings; diff --git a/lib/Slic3r/Test/SectionCut.pm b/lib/Slic3r/Test/SectionCut.pm index 467f4e9d4..04106d46f 100644 --- a/lib/Slic3r/Test/SectionCut.pm +++ b/lib/Slic3r/Test/SectionCut.pm @@ -1,3 +1,4 @@ +# Slices at the XZ plane, for debugging purposes. package Slic3r::Test::SectionCut; use Moo; |