From 0741ecc2aa4b00629f210a6348d56adcfb237bf8 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Fri, 10 Mar 2017 17:36:14 -0600 Subject: [PATCH] Add weight/cost output to gcode. On the way to #647 (#3669) * Add weight/cost output to gcode. On the way to #647 * added total cost/weight to Extruder statistics, mocked up addendum to status bar change. * Added second information box that populates after exporting gcode for sliced statistics. * Changed filament density to use g/cm^3. Extended tooltip to indicate calculation methods. * Hide sliced info box when gcode export hasn't been done. * Remove if invalidated and we have background processing or the configuration changes. * Called layout after every Hide/Show call to ensure that it is placed correctly on different platforms. Changed output units to cm/cm^3 Conflicts: lib/Slic3r/GUI/Plater.pm --- lib/Slic3r/GUI/Plater.pm | 54 +++++++++++++++++++++++++++++++- lib/Slic3r/GUI/Tab.pm | 4 ++- lib/Slic3r/Print/GCode.pm | 16 ++++++++++ lib/Slic3r/Print/Object.pm | 2 ++ xs/src/libslic3r/Extruder.cpp | 12 +++++++ xs/src/libslic3r/Extruder.hpp | 2 ++ xs/src/libslic3r/Print.hpp | 2 +- xs/src/libslic3r/PrintConfig.cpp | 24 ++++++++++++++ xs/src/libslic3r/PrintConfig.hpp | 4 +++ xs/xsp/Extruder.xsp | 2 ++ xs/xsp/Print.xsp | 21 +++++++++++++ 11 files changed, 140 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index fa04fc436..3ce193a7c 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -142,6 +142,7 @@ sub new { $self->stop_background_process; $self->statusbar->SetStatusText("Slicing cancelled"); $self->{preview_notebook}->SetSelection(0); + }); $self->start_background_process; } else { @@ -431,6 +432,36 @@ sub new { } } } + + my $print_info_sizer; + { + my $box = Wx::StaticBox->new($self, -1, "Sliced Info"); + $print_info_sizer = Wx::StaticBoxSizer->new($box, wxVERTICAL); + $print_info_sizer->SetMinSize([350,-1]); + my $grid_sizer = Wx::FlexGridSizer->new(2, 2, 5, 5); + $grid_sizer->SetFlexibleDirection(wxHORIZONTAL); + $grid_sizer->AddGrowableCol(1, 1); + $grid_sizer->AddGrowableCol(3, 1); + $print_info_sizer->Add($grid_sizer, 0, wxEXPAND); + my @info = ( + fil_cm => "Used Filament (cm)", + fil_cm3 => "Used Filament (cm^3)", + fil_g => "Used Filament (g)", + cost => "Cost", + ); + while (my $field = shift @info) { + my $label = shift @info; + my $text = Wx::StaticText->new($self, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + $text->SetFont($Slic3r::GUI::small_font); + $grid_sizer->Add($text, 0); + + $self->{"print_info_$field"} = Wx::StaticText->new($self, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + $self->{"print_info_$field"}->SetFont($Slic3r::GUI::small_font); + $grid_sizer->Add($self->{"print_info_$field"}, 0); + } + $self->{"sliced_info_box"} = $print_info_sizer; + + } my $buttons_sizer = Wx::BoxSizer->new(wxHORIZONTAL); $buttons_sizer->AddStretchSpacer(1); @@ -444,6 +475,9 @@ sub new { $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5); $right_sizer->Add($self->{list}, 1, wxEXPAND, 5); $right_sizer->Add($object_info_sizer, 0, wxEXPAND, 0); + $right_sizer->Add($print_info_sizer, 0, wxEXPAND, 0); + $right_sizer->Hide($print_info_sizer); + $self->{"right_sizer"} = $right_sizer; my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL); $hsizer->Add($self->{preview_notebook}, 1, wxEXPAND | wxTOP, 1); @@ -1090,6 +1124,11 @@ sub async_apply_config { if ($invalidated) { # kill current thread if any $self->stop_background_process; + # remove the sliced statistics box because something changed. + if ($self->{"right_sizer"}) { + $self->{"right_sizer"}->Hide($self->{"sliced_info_box"}); + $self->{"right_sizer"}->Layout; + } } else { $self->resume_background_process; } @@ -1263,6 +1302,8 @@ sub export_gcode { # this updates buttons status $self->object_list_changed; + $self->{"right_sizer"}->Show($self->{"sliced_info_box"}); + $self->{"right_sizer"}->Layout; return $self->{export_gcode_output_file}; } @@ -1357,6 +1398,10 @@ sub on_export_completed { $self->send_gcode if $send_gcode; $self->{print_file} = undef; $self->{send_gcode_file} = undef; + $self->{"print_info_cost"}->SetLabel(sprintf("%.2f" , $self->{print}->total_cost)); + $self->{"print_info_fil_g"}->SetLabel(sprintf("%.2f" , $self->{print}->total_weight)); + $self->{"print_info_fil_cm3"}->SetLabel(sprintf("%.2f" , $self->{print}->total_extruded_volume) / 1000); + $self->{"print_info_fil_cm"}->SetLabel(sprintf("%.2f" , $self->{print}->total_used_filament) / 10); # this updates buttons status $self->object_list_changed; @@ -1553,7 +1598,10 @@ sub update { } else { $self->resume_background_process; } - + if ($self->{"right_sizer"}) { + $self->{"right_sizer"}->Hide($self->{"sliced_info_box"}); + $self->{"right_sizer"}->Layout; + } $self->refresh_canvases; } @@ -1627,6 +1675,10 @@ sub on_config_change { $self->Layout; } } + if ($self->{"right_sizer"}) { + $self->{"right_sizer"}->Hide($self->{"sliced_info_box"}); + $self->{"right_sizer"}->Layout; + } return if !$self->GetFrame->is_loaded; diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index fdd05b75b..c515df76f 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -897,7 +897,7 @@ sub build { my $self = shift; $self->init_config_options(qw( - filament_colour filament_diameter filament_notes filament_max_volumetric_speed extrusion_multiplier + filament_colour filament_diameter filament_notes filament_max_volumetric_speed extrusion_multiplier filament_density filament_cost temperature first_layer_temperature bed_temperature first_layer_bed_temperature fan_always_on cooling min_fan_speed max_fan_speed bridge_fan_speed disable_fan_first_layers @@ -912,6 +912,8 @@ sub build { $optgroup->append_single_option_line('filament_colour', 0); $optgroup->append_single_option_line('filament_diameter', 0); $optgroup->append_single_option_line('extrusion_multiplier', 0); + $optgroup->append_single_option_line('filament_density', 0); + $optgroup->append_single_option_line('filament_cost', 0); } { diff --git a/lib/Slic3r/Print/GCode.pm b/lib/Slic3r/Print/GCode.pm index 026865392..086f7e33f 100644 --- a/lib/Slic3r/Print/GCode.pm +++ b/lib/Slic3r/Print/GCode.pm @@ -255,17 +255,33 @@ sub export { $self->print->clear_filament_stats; $self->print->total_used_filament(0); $self->print->total_extruded_volume(0); + $self->print->total_weight(0); + $self->print->total_cost(0); foreach my $extruder (@{$gcodegen->writer->extruders}) { my $used_filament = $extruder->used_filament; my $extruded_volume = $extruder->extruded_volume; + my $filament_weight = $extruded_volume * $extruder->filament_density / 1000; + my $filament_cost = $filament_weight * ($extruder->filament_cost / 1000); $self->print->set_filament_stats($extruder->id, $used_filament); printf $fh "; filament used = %.1fmm (%.1fcm3)\n", $used_filament, $extruded_volume/1000; + if ($filament_weight > 0) { + $self->print->total_weight($self->print->total_weight + $filament_weight); + printf $fh "; filament used = %.1fg\n", + $filament_weight; + if ($filament_cost > 0) { + $self->print->total_cost($self->print->total_cost + $filament_cost); + printf $fh "; filament cost = %.1f\n", + $filament_cost; + } + } $self->print->total_used_filament($self->print->total_used_filament + $used_filament); $self->print->total_extruded_volume($self->print->total_extruded_volume + $extruded_volume); } + printf $fh "; total filament cost = %.1f\n", + $self->print->total_cost; # append full config print $fh "\n"; diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 9b9e99e9f..8dbefc117 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -417,6 +417,8 @@ sub generate_support_material { $self->_support_material->generate($self); $self->set_step_done(STEP_SUPPORTMATERIAL); + my $stats = "Weight: %.1fg, Cost: %.1f" , $self->print->total_weight, $self->print->total_cost; + $self->print->status_cb->(85, $stats); } sub _support_material { diff --git a/xs/src/libslic3r/Extruder.cpp b/xs/src/libslic3r/Extruder.cpp index b9be14661..8cf3e8b0a 100644 --- a/xs/src/libslic3r/Extruder.cpp +++ b/xs/src/libslic3r/Extruder.cpp @@ -111,6 +111,18 @@ Extruder::filament_diameter() const return this->config->filament_diameter.get_at(this->id); } +double +Extruder::filament_density() const +{ + return this->config->filament_density.get_at(this->id); +} + +double +Extruder::filament_cost() const +{ + return this->config->filament_cost.get_at(this->id); +} + double Extruder::extrusion_multiplier() const { diff --git a/xs/src/libslic3r/Extruder.hpp b/xs/src/libslic3r/Extruder.hpp index 76b70df63..729996cd1 100644 --- a/xs/src/libslic3r/Extruder.hpp +++ b/xs/src/libslic3r/Extruder.hpp @@ -29,6 +29,8 @@ class Extruder double used_filament() const; double filament_diameter() const; + double filament_density() const; + double filament_cost() const; double extrusion_multiplier() const; double retract_length() const; double retract_lift() const; diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 5ec3653ed..092fc84c3 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -167,7 +167,7 @@ class Print PrintRegionPtrs regions; PlaceholderParser placeholder_parser; // TODO: status_cb - double total_used_filament, total_extruded_volume; + double total_used_filament, total_extruded_volume, total_cost, total_weight; std::map filament_stats; PrintState state; diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 34a10a414..aca51e334 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -355,6 +355,30 @@ PrintConfigDef::PrintConfigDef() opt->values.push_back(3); def->default_value = opt; } + + def = this->add("filament_density", coFloats); + def->label = "Density"; + def->tooltip = "Enter your filament density here. This is only for statistical information. A decent way is to weigh a known length of filament and compute the ratio of the length to volume. Better is to calculate the volume directly through displacement."; + def->sidetext = "g/cm^3"; + def->cli = "filament-density=f@"; + def->min = 0; + { + ConfigOptionFloats* opt = new ConfigOptionFloats(); + opt->values.push_back(0); + def->default_value = opt; + } + + def = this->add("filament_cost", coFloats); + def->label = "Cost"; + def->tooltip = "Enter your filament cost per kg here. This is only for statistical information."; + def->sidetext = "money/kg"; + def->cli = "filament-cost=f@"; + def->min = 0; + { + ConfigOptionFloats* opt = new ConfigOptionFloats(); + opt->values.push_back(0); + def->default_value = opt; + } def = this->add("filament_settings_id", coString); def->default_value = new ConfigOptionString(""); diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 2a0b080bf..27c5d4e75 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -289,6 +289,8 @@ class GCodeConfig : public virtual StaticPrintConfig ConfigOptionString extrusion_axis; ConfigOptionFloats extrusion_multiplier; ConfigOptionFloats filament_diameter; + ConfigOptionFloats filament_density; + ConfigOptionFloats filament_cost; ConfigOptionFloats filament_max_volumetric_speed; ConfigOptionBool gcode_comments; ConfigOptionEnum gcode_flavor; @@ -322,6 +324,8 @@ class GCodeConfig : public virtual StaticPrintConfig OPT_PTR(extrusion_axis); OPT_PTR(extrusion_multiplier); OPT_PTR(filament_diameter); + OPT_PTR(filament_density); + OPT_PTR(filament_cost); OPT_PTR(filament_max_volumetric_speed); OPT_PTR(gcode_comments); OPT_PTR(gcode_flavor); diff --git a/xs/xsp/Extruder.xsp b/xs/xsp/Extruder.xsp index 2a315858e..36f5427c7 100644 --- a/xs/xsp/Extruder.xsp +++ b/xs/xsp/Extruder.xsp @@ -42,6 +42,8 @@ %code%{ RETVAL = THIS->retract_speed_mm_min; %}; double filament_diameter(); + double filament_density(); + double filament_cost(); double extrusion_multiplier(); double retract_length(); double retract_lift(); diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index fbd4c3765..1bd25edb4 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -288,5 +288,26 @@ Print::total_extruded_volume(...) OUTPUT: RETVAL + +double +Print::total_weight(...) + CODE: + if (items > 1) { + THIS->total_weight = (double)SvNV(ST(1)); + } + RETVAL = THIS->total_weight; + OUTPUT: + RETVAL + +double +Print::total_cost(...) + CODE: + if (items > 1) { + THIS->total_cost = (double)SvNV(ST(1)); + } + RETVAL = THIS->total_cost; + OUTPUT: + RETVAL + %} };