From c04be58648b663eeb5e1f10572b0c19d94ec9815 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 12 Feb 2019 16:34:42 +0100 Subject: [PATCH 01/18] Implemented estimated printing time for the SLA printing --- src/libslic3r/Print.cpp | 4 +- src/libslic3r/SLAPrint.cpp | 80 ++++++++++++++++++++++++++++++++++++++ src/libslic3r/SLAPrint.hpp | 30 ++++++++++++++ src/libslic3r/Utils.hpp | 63 ++++++++++++++++++++++++++++++ src/slic3r/GUI/Plater.cpp | 21 ++++++++++ 5 files changed, 196 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 6416a709a..3e78c9a85 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1863,7 +1863,7 @@ std::string Print::output_filename() const DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders(); return this->PrintBase::output_filename(m_config.output_filename_format.value, "gcode", &config); } - +/* // Shorten the dhms time by removing the seconds, rounding the dhm to full minutes // and removing spaces. static std::string short_time(const std::string &time) @@ -1903,7 +1903,7 @@ static std::string short_time(const std::string &time) ::sprintf(buffer, "%ds", seconds); return buffer; } - +*/ DynamicConfig PrintStatistics::config() const { DynamicConfig config; diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 142428f1d..b848e2698 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -966,6 +966,9 @@ void SLAPrint::process() st += unsigned(PRINT_STEP_LEVELS[currentstep] * pstd); } + // Fill statistics + fill_statistics(); + // If everything vent well report_status(*this, 100, L("Slicing done")); } @@ -1027,6 +1030,46 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vectorget_slice_index().size()) + max_layers_cnt = po->get_slice_index().size(); + } + if (max_layers_cnt == 0) + return; + + float init_exp_time = m_material_config.initial_exposure_time.getFloat();//35; + float exp_time = m_material_config.exposure_time.getFloat();//8; + + // TODO : fade_layers_cnt should be filled in the future + // This variable will be a part of the print(material) preset + const int fade_layers_cnt = 10; // [3;20] + + // TODO : tilt_delay_before_time & tilt_delay_after_time should be filled in the future + // These values are received from the printer after a printing start + const float tilt_delay_before_time = 0.0; + const float tilt_delay_after_time = 0.0; + if (tilt_delay_before_time + tilt_delay_after_time > 0.0) + { + init_exp_time += tilt_delay_before_time + tilt_delay_after_time; + exp_time += tilt_delay_before_time + tilt_delay_after_time; + } + + float estim_time = init_exp_time * 3 + exp_time * (max_layers_cnt - 3 - fade_layers_cnt); + + const float delta_time = (init_exp_time - exp_time) / (fade_layers_cnt+1); + double fade_layer_time = init_exp_time; + while (fade_layer_time > exp_time) + { + fade_layer_time -= delta_time; + estim_time += fade_layer_time; + } + + m_print_statistics.estimated_print_time = get_time_dhms(estim_time); +} + // Returns true if an object step is done on all objects and there's at least one object. bool SLAPrint::is_step_done(SLAPrintObjectStep step) const { @@ -1257,4 +1300,41 @@ std::vector SLAPrintObject::transformed_support_points() const return ret; } +DynamicConfig SLAPrintStatistics::config() const +{ + DynamicConfig config; + const std::string print_time = Slic3r::short_time(this->estimated_print_time); + config.set_key_value("print_time", new ConfigOptionString(print_time)); + config.set_key_value("used_material", new ConfigOptionFloat(this->total_used_material/* / 1000.*/)); + config.set_key_value("total_cost", new ConfigOptionFloat(this->total_cost)); + config.set_key_value("total_weight", new ConfigOptionFloat(this->total_weight)); + return config; +} + +DynamicConfig SLAPrintStatistics::placeholders() +{ + DynamicConfig config; + for (const std::string &key : { + "print_time", "used_material", "total_cost", "total_weight" }) + config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}")); + return config; +} + +std::string SLAPrintStatistics::finalize_output_path(const std::string &path_in) const +{ + std::string final_path; + try { + boost::filesystem::path path(path_in); + DynamicConfig cfg = this->config(); + PlaceholderParser pp; + std::string new_stem = pp.process(path.stem().string(), 0, &cfg); + final_path = (path.parent_path() / (new_stem + path.extension().string())).string(); + } + catch (const std::exception &ex) { + BOOST_LOG_TRIVIAL(error) << "Failed to apply the print statistics to the export file name: " << ex.what(); + final_path = path_in; + } + return final_path; +} + } // namespace Slic3r diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 21503c6f6..0e12fff63 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -171,6 +171,29 @@ using PrintObjects = std::vector; class TriangleMesh; +struct SLAPrintStatistics +{ + SLAPrintStatistics() { clear(); } + std::string estimated_print_time; + double total_used_material; + double total_cost; + double total_weight; + + // Config with the filled in print statistics. + DynamicConfig config() const; + // Config with the statistics keys populated with placeholder strings. + static DynamicConfig placeholders(); + // Replace the print statistics placeholders in the path. + std::string finalize_output_path(const std::string &path_in) const; + + void clear() { + estimated_print_time.clear(); + total_used_material = 0.; + total_cost = 0.; + total_weight = 0.; + } +}; + /** * @brief This class is the high level FSM for the SLA printing process. * @@ -208,6 +231,8 @@ public: std::string output_filename() const override { return this->PrintBase::output_filename(m_print_config.output_filename_format.value, "zip"); } + const SLAPrintStatistics& print_statistics() const { return m_print_statistics; } + private: using SLAPrinter = FilePrinter; using SLAPrinterPtr = std::unique_ptr; @@ -215,6 +240,8 @@ private: // Invalidate steps based on a set of parameters changed. bool invalidate_state_by_config_options(const std::vector &opt_keys); + void fill_statistics(); + SLAPrintConfig m_print_config; SLAPrinterConfig m_printer_config; SLAMaterialConfig m_material_config; @@ -246,6 +273,9 @@ private: // The printer itself SLAPrinterPtr m_printer; + // Estimated print time, material consumed. + SLAPrintStatistics m_print_statistics; + friend SLAPrintObject; }; diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 046745e6f..c13df4546 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -206,6 +206,69 @@ public: void reset() { closure = Closure(); } }; +// Shorten the dhms time by removing the seconds, rounding the dhm to full minutes +// and removing spaces. +static std::string short_time(const std::string &time) +{ + // Parse the dhms time format. + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + if (time.find('d') != std::string::npos) + ::sscanf(time.c_str(), "%dd %dh %dm %ds", &days, &hours, &minutes, &seconds); + else if (time.find('h') != std::string::npos) + ::sscanf(time.c_str(), "%dh %dm %ds", &hours, &minutes, &seconds); + else if (time.find('m') != std::string::npos) + ::sscanf(time.c_str(), "%dm %ds", &minutes, &seconds); + else if (time.find('s') != std::string::npos) + ::sscanf(time.c_str(), "%ds", &seconds); + // Round to full minutes. + if (days + hours + minutes > 0 && seconds >= 30) { + if (++minutes == 60) { + minutes = 0; + if (++hours == 24) { + hours = 0; + ++days; + } + } + } + // Format the dhm time. + char buffer[64]; + if (days > 0) + ::sprintf(buffer, "%dd%dh%dm", days, hours, minutes); + else if (hours > 0) + ::sprintf(buffer, "%dh%dm", hours, minutes); + else if (minutes > 0) + ::sprintf(buffer, "%dm", minutes); + else + ::sprintf(buffer, "%ds", seconds); + return buffer; +} + +// Returns the given time is seconds in format DDd HHh MMm SSs +static std::string get_time_dhms(float time_in_secs) +{ + int days = (int)(time_in_secs / 86400.0f); + time_in_secs -= (float)days * 86400.0f; + int hours = (int)(time_in_secs / 3600.0f); + time_in_secs -= (float)hours * 3600.0f; + int minutes = (int)(time_in_secs / 60.0f); + time_in_secs -= (float)minutes * 60.0f; + + char buffer[64]; + if (days > 0) + ::sprintf(buffer, "%dd %dh %dm %ds", days, hours, minutes, (int)time_in_secs); + else if (hours > 0) + ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)time_in_secs); + else if (minutes > 0) + ::sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs); + else + ::sprintf(buffer, "%ds", (int)time_in_secs); + + return buffer; +} + } // namespace Slic3r #if WIN32 diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 774e61024..18a923d45 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -153,6 +153,7 @@ enum SlisedInfoIdx siFilament_m, siFilament_mm3, siFilament_g, + siMateril_unit, siCost, siEstimatedTime, siWTNumbetOfToolchanges, @@ -193,6 +194,7 @@ SlicedInfo::SlicedInfo(wxWindow *parent) : init_info_label(_(L("Used Filament (m)"))); init_info_label(_(L("Used Filament (mm³)"))); init_info_label(_(L("Used Filament (g)"))); + init_info_label(_(L("Used Material (unit)"))); init_info_label(_(L("Cost"))); init_info_label(_(L("Estimated printing time"))); init_info_label(_(L("Number of tool changes"))); @@ -817,6 +819,21 @@ void Sidebar::show_sliced_info_sizer(const bool show) p->sliced_info->Show(show); if (show) { + if (p->plater->printer_technology() == ptSLA) + { + const SLAPrintStatistics& ps = p->plater->sla_print().print_statistics(); + p->sliced_info->SetTextAndShow(siMateril_unit, wxString::Format("%.2f", ps.total_used_material)); + p->sliced_info->SetTextAndShow(siCost, wxString::Format("%.2f", ps.total_cost)); + p->sliced_info->SetTextAndShow(siEstimatedTime, ps.estimated_print_time, _(L("Estimated printing time")) + " :"); + + // Hide non-SLA sliced info parameters + p->sliced_info->SetTextAndShow(siFilament_m, "N/A"); + p->sliced_info->SetTextAndShow(siFilament_mm3, "N/A"); + p->sliced_info->SetTextAndShow(siFilament_g, "N/A"); + p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, "N/A"); + } + else + { const PrintStatistics& ps = p->plater->fff_print().print_statistics(); const bool is_wipe_tower = ps.total_wipe_tower_filament > 0; @@ -864,6 +881,10 @@ void Sidebar::show_sliced_info_sizer(const bool show) // if there is a wipe tower, insert number of toolchanges info into the array: p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, is_wipe_tower ? wxString::Format("%.d", p->plater->fff_print().wipe_tower_data().number_of_toolchanges) : "N/A"); + + // Hide non-FFF sliced info parameters + p->sliced_info->SetTextAndShow(siMateril_unit, "N/A"); + } } Layout(); From 589ac889a319506d1c43fdee19db99f10ecc3fa5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 13 Feb 2019 08:44:42 +0100 Subject: [PATCH 02/18] Fixed OSX build --- src/libslic3r/SLAPrint.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index b848e2698..0e358d8c7 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -8,6 +8,7 @@ #include #include +#include #include //#include //#include "tbb/mutex.h" @@ -1032,6 +1033,8 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vectorget_slice_index().size()) From 88f04e0faef5cc18a9cf0d6761a611abe54db3a7 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 13 Feb 2019 15:35:41 +0100 Subject: [PATCH 03/18] Added calculation of the material consumption --- src/libslic3r/SLAPrint.cpp | 56 ++++++++++++++++++++++++++++++++------ src/libslic3r/SLAPrint.hpp | 6 ++-- src/slic3r/GUI/Plater.cpp | 15 ++++++++-- 3 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 0e358d8c7..08ab56db3 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1033,16 +1033,52 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vectorget_support_slices()) + for (const ExPolygon& polygon : polygons) + supports_volume += polygon.area() *layer_height; + + // Calculate full volume of the object + for (const ExPolygons& polygons : po->get_model_slices()) + for (const ExPolygon& polygon : polygons) + models_volume += polygon.area() *layer_height; + + const SLAPrintObject::SliceIndex& slice_index = po->get_slice_index(); + + // If init_layer_height isn't equivalent to the layer_height, + // let correct volume of the first(initial) layer + if (init_layer_height != layer_height) + { + const auto index = slice_index.begin(); + if (index->second.support_slices_idx != SLAPrintObject::SliceRecord::NONE) + for (const ExPolygon& polygon : po->get_support_slices().front()) + supports_volume += polygon.area() *(init_layer_height - layer_height); + if (index->second.model_slices_idx != SLAPrintObject::SliceRecord::NONE) + for (const ExPolygon& polygon : po->get_model_slices().front()) + models_volume += polygon.area() *(init_layer_height - layer_height); + } + + if (max_layers_cnt < slice_index.size()) + max_layers_cnt = slice_index.size(); + } + + m_print_statistics.support_used_material = supports_volume * SCALING_FACTOR * SCALING_FACTOR; + m_print_statistics.objects_used_material = models_volume * SCALING_FACTOR * SCALING_FACTOR; + // Estimated printing time // A layers count o the highest object - int max_layers_cnt = 0; - for (SLAPrintObject * po : m_objects) { - if (max_layers_cnt < po->get_slice_index().size()) - max_layers_cnt = po->get_slice_index().size(); - } if (max_layers_cnt == 0) - return; - + m_print_statistics.estimated_print_time = "N/A"; float init_exp_time = m_material_config.initial_exposure_time.getFloat();//35; float exp_time = m_material_config.exposure_time.getFloat();//8; @@ -1308,7 +1344,8 @@ DynamicConfig SLAPrintStatistics::config() const DynamicConfig config; const std::string print_time = Slic3r::short_time(this->estimated_print_time); config.set_key_value("print_time", new ConfigOptionString(print_time)); - config.set_key_value("used_material", new ConfigOptionFloat(this->total_used_material/* / 1000.*/)); + config.set_key_value("objects_used_material", new ConfigOptionFloat(this->objects_used_material)); + config.set_key_value("support_used_material", new ConfigOptionFloat(this->support_used_material)); config.set_key_value("total_cost", new ConfigOptionFloat(this->total_cost)); config.set_key_value("total_weight", new ConfigOptionFloat(this->total_weight)); return config; @@ -1318,7 +1355,8 @@ DynamicConfig SLAPrintStatistics::placeholders() { DynamicConfig config; for (const std::string &key : { - "print_time", "used_material", "total_cost", "total_weight" }) + "print_time", "total_cost", "total_weight", + "objects_used_material", "support_used_material" }) config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}")); return config; } diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 0e12fff63..f054921c8 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -175,7 +175,8 @@ struct SLAPrintStatistics { SLAPrintStatistics() { clear(); } std::string estimated_print_time; - double total_used_material; + double objects_used_material; + double support_used_material; double total_cost; double total_weight; @@ -188,7 +189,8 @@ struct SLAPrintStatistics void clear() { estimated_print_time.clear(); - total_used_material = 0.; + objects_used_material = 0.; + support_used_material = 0.; total_cost = 0.; total_weight = 0.; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 18a923d45..f4a3c0b48 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -822,8 +822,19 @@ void Sidebar::show_sliced_info_sizer(const bool show) if (p->plater->printer_technology() == ptSLA) { const SLAPrintStatistics& ps = p->plater->sla_print().print_statistics(); - p->sliced_info->SetTextAndShow(siMateril_unit, wxString::Format("%.2f", ps.total_used_material)); - p->sliced_info->SetTextAndShow(siCost, wxString::Format("%.2f", ps.total_cost)); + wxString new_label = _(L("Used Material (mm³)")) + " :"; + const bool is_supports = ps.support_used_material > 0.0; + if (is_supports) + new_label += wxString::Format("\n - %s\n - %s", _(L("object(s)")), _(L("supports and pad"))); + + wxString info_text = is_supports ? + wxString::Format("%.2f \n%.2f \n%.2f", ps.objects_used_material + ps.support_used_material/* / 1000*/, + ps.objects_used_material/* / 1000*/, + ps.support_used_material/* / 1000*/) : + wxString::Format("%.2f", ps.objects_used_material + ps.support_used_material/* / 1000*/); + p->sliced_info->SetTextAndShow(siMateril_unit, info_text, new_label); + + p->sliced_info->SetTextAndShow(siCost, "N/A"/*wxString::Format("%.2f", ps.total_cost)*/); p->sliced_info->SetTextAndShow(siEstimatedTime, ps.estimated_print_time, _(L("Estimated printing time")) + " :"); // Hide non-SLA sliced info parameters From 3f23bd5224412e76dcb71ba150aa6c999d3c8f9a Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 13 Feb 2019 16:30:40 +0100 Subject: [PATCH 04/18] Save statistics values to the config.ini --- src/libslic3r/PrintExport.hpp | 22 +++++++++++++++++++++- src/libslic3r/SLAPrint.cpp | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/PrintExport.hpp b/src/libslic3r/PrintExport.hpp index 5cfb55217..d40b60aad 100644 --- a/src/libslic3r/PrintExport.hpp +++ b/src/libslic3r/PrintExport.hpp @@ -14,6 +14,12 @@ namespace Slic3r { +enum ePrintStatistics +{ + psObjectsUsedMaterial = 0, + psSupportUsedMaterial +}; + enum class FilePrinterFormat { SLA_PNGZIP, SVG @@ -118,6 +124,9 @@ template<> class FilePrinter double m_layer_height = .0; Raster::Origin m_o = Raster::Origin::TOP_LEFT; + double m_objects_used_material = 0.0; + double m_support_used_material = 0.0; + std::string createIniContent(const std::string& projectname) { double layer_height = m_layer_height; @@ -129,6 +138,9 @@ template<> class FilePrinter auto stepnum_str = to_string(static_cast(800*layer_height)); auto layerh_str = to_string(layer_height); + const std::string objects_used_material = to_string(m_objects_used_material); + const std::string support_used_material = to_string(m_support_used_material); + return string( "action = print\n" "jobDir = ") + projectname + "\n" + @@ -143,7 +155,9 @@ template<> class FilePrinter "layerHeight = " + layerh_str + "\n" "noteInfo = " "expTime="+expt_str+"+resinType=generic+layerHeight=" - +layerh_str+"+printer=DWARF3\n"; + +layerh_str+"+printer=DWARF3\n" + "objUsedMaterial=" + objects_used_material + "\n" + "supUsedMaterial=" + support_used_material + "\n"; } public: @@ -277,6 +291,12 @@ public: out.close(); m_layers_rst[i].first.reset(); } + + void set_statistics(const std::vector statistics) + { + m_objects_used_material = statistics[psObjectsUsedMaterial]; + m_support_used_material = statistics[psSupportUsedMaterial]; + } }; } diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 08ab56db3..f95b16cfe 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -969,6 +969,10 @@ void SLAPrint::process() // Fill statistics fill_statistics(); + // Set statistics values to the printer + SLAPrinter& printer = *m_printer; + printer.set_statistics({m_print_statistics.objects_used_material, + m_print_statistics.support_used_material}); // If everything vent well report_status(*this, 100, L("Slicing done")); From 2df069323c9de13b7caf9102ab0ce98a49b8ca5e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 18 Feb 2019 12:28:58 +0100 Subject: [PATCH 05/18] Time estimation improvement --- src/libslic3r/PrintExport.hpp | 56 +++++++----- src/libslic3r/SLAPrint.cpp | 164 +++++++++++++++++++++------------- src/libslic3r/SLAPrint.hpp | 4 + src/slic3r/GUI/Plater.cpp | 10 +-- 4 files changed, 147 insertions(+), 87 deletions(-) diff --git a/src/libslic3r/PrintExport.hpp b/src/libslic3r/PrintExport.hpp index d40b60aad..64babd507 100644 --- a/src/libslic3r/PrintExport.hpp +++ b/src/libslic3r/PrintExport.hpp @@ -16,8 +16,12 @@ namespace Slic3r { enum ePrintStatistics { - psObjectsUsedMaterial = 0, - psSupportUsedMaterial + psUsedMaterial = 0, + psNumFade, + psNumSlow, + psNumFast, + + psCnt }; enum class FilePrinterFormat { @@ -124,40 +128,45 @@ template<> class FilePrinter double m_layer_height = .0; Raster::Origin m_o = Raster::Origin::TOP_LEFT; - double m_objects_used_material = 0.0; - double m_support_used_material = 0.0; + double m_used_material = 0.0; + int m_cnt_fade_layers = 0; + int m_cnt_slow_layers = 0; + int m_cnt_fast_layers = 0; std::string createIniContent(const std::string& projectname) { - double layer_height = m_layer_height; +// double layer_height = m_layer_height; using std::string; using std::to_string; auto expt_str = to_string(m_exp_time_s); auto expt_first_str = to_string(m_exp_time_first_s); - auto stepnum_str = to_string(static_cast(800*layer_height)); - auto layerh_str = to_string(layer_height); +// auto stepnum_str = to_string(static_cast(800*layer_height)); + auto layerh_str = to_string(m_layer_height); - const std::string objects_used_material = to_string(m_objects_used_material); - const std::string support_used_material = to_string(m_support_used_material); + const std::string cnt_fade_layers = to_string(m_cnt_fade_layers); + const std::string cnt_slow_layers = to_string(m_cnt_slow_layers); + const std::string cnt_fast_layers = to_string(m_cnt_fast_layers); + const std::string used_material = to_string(m_used_material); return string( "action = print\n" "jobDir = ") + projectname + "\n" + "expTime = " + expt_str + "\n" "expTimeFirst = " + expt_first_str + "\n" - "stepNum = " + stepnum_str + "\n" - "wifiOn = 1\n" - "tiltSlow = 60\n" - "tiltFast = 15\n" - "numFade = 10\n" - "startdelay = 0\n" +// "stepNum = " + stepnum_str + "\n" +// "wifiOn = 1\n" +// "tiltSlow = 60\n" +// "tiltFast = 15\n" + "numFade = " + cnt_fade_layers + "\n" +// "startdelay = 0\n" "layerHeight = " + layerh_str + "\n" "noteInfo = " - "expTime="+expt_str+"+resinType=generic+layerHeight=" - +layerh_str+"+printer=DWARF3\n" - "objUsedMaterial=" + objects_used_material + "\n" - "supUsedMaterial=" + support_used_material + "\n"; + "expTime = "+expt_str+" + resinType = generic+layerHeight = " + +layerh_str+" + printer = DWARF3\n" + "usedMaterial = " + used_material + "\n" + "numSlow = " + cnt_slow_layers + "\n" + "numFast = " + cnt_fast_layers + "\n"; } public: @@ -294,8 +303,13 @@ public: void set_statistics(const std::vector statistics) { - m_objects_used_material = statistics[psObjectsUsedMaterial]; - m_support_used_material = statistics[psSupportUsedMaterial]; + if (statistics.size() != psCnt) + return; + + m_used_material = statistics[psUsedMaterial]; + m_cnt_fade_layers = int(statistics[psNumFade]); + m_cnt_slow_layers = int(statistics[psNumSlow]); + m_cnt_fast_layers = int(statistics[psNumFast]); } }; diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index f95b16cfe..ecc990d01 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -971,8 +971,11 @@ void SLAPrint::process() fill_statistics(); // Set statistics values to the printer SLAPrinter& printer = *m_printer; - printer.set_statistics({m_print_statistics.objects_used_material, - m_print_statistics.support_used_material}); + printer.set_statistics({(m_print_statistics.objects_used_material + m_print_statistics.support_used_material)/1000, + 10.0, + double(m_print_statistics.slow_layers_count), + double(m_print_statistics.fast_layers_count) + }); // If everything vent well report_status(*this, 100, L("Slicing done")); @@ -1037,80 +1040,119 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vectorget_support_slices()) - for (const ExPolygon& polygon : polygons) - supports_volume += polygon.area() *layer_height; - - // Calculate full volume of the object - for (const ExPolygons& polygons : po->get_model_slices()) - for (const ExPolygon& polygon : polygons) - models_volume += polygon.area() *layer_height; - const SLAPrintObject::SliceIndex& slice_index = po->get_slice_index(); - - // If init_layer_height isn't equivalent to the layer_height, - // let correct volume of the first(initial) layer - if (init_layer_height != layer_height) - { - const auto index = slice_index.begin(); - if (index->second.support_slices_idx != SLAPrintObject::SliceRecord::NONE) - for (const ExPolygon& polygon : po->get_support_slices().front()) - supports_volume += polygon.area() *(init_layer_height - layer_height); - if (index->second.model_slices_idx != SLAPrintObject::SliceRecord::NONE) - for (const ExPolygon& polygon : po->get_model_slices().front()) - models_volume += polygon.area() *(init_layer_height - layer_height); - } - - if (max_layers_cnt < slice_index.size()) + if (max_layers_cnt < slice_index.size()) { max_layers_cnt = slice_index.size(); + highest_obj_idx = std::find(m_objects.begin(), m_objects.end(), po) - m_objects.begin(); + } } - m_print_statistics.support_used_material = supports_volume * SCALING_FACTOR * SCALING_FACTOR; + const SLAPrintObject * highest_obj = m_objects[highest_obj_idx]; + const SLAPrintObject::SliceIndex& highest_obj_slice_index = highest_obj->get_slice_index(); + + const double delta_fade_time = (init_exp_time - exp_time) / (fade_layers_cnt + 1); + double fade_layer_time = init_exp_time; + + int sliced_layer_cnt = 0; + for (const auto& layer : highest_obj_slice_index) + { + const double l_height = (layer.first == highest_obj_slice_index.begin()->first && + init_layer_height != layer_height) ? + init_layer_height : layer_height; + + // Calculation of the consumed material + + double layer_model_area = 0; + double layer_support_area = 0; + for (SLAPrintObject * po : m_objects) + { + const auto index = po->get_slice_index(); + if (index.find(layer.first) == index.end()) + continue; + + if (index.at(layer.first).model_slices_idx != SLAPrintObject::SliceRecord::NONE) { + for (const ExPolygon& polygon : po->get_model_slices().at(index.at(layer.first).model_slices_idx)) + layer_model_area += polygon.area(); + } + /*else */if (index.at(layer.first).support_slices_idx != SLAPrintObject::SliceRecord::NONE) { + for (const ExPolygon& polygon : po->get_support_slices().front()) + layer_support_area += polygon.area(); + } + } + models_volume += layer_model_area * l_height; + supports_volume += layer_support_area * l_height; + + // Calculation of the slow and fast layers to the future controlling those values on FW + + const bool is_fast_layer = (layer_model_area + layer_support_area) <= display_area*slow_fast_limit; + const double tilt_time = is_fast_layer ? fast_tilt : slow_tilt; + if (is_fast_layer) + fast_layers++; + else + slow_layers++; + + + // Calculation of the printing time + + if (sliced_layer_cnt < 3) + estim_time += init_exp_time; + else if (fade_layer_time > exp_time) + { + fade_layer_time -= delta_fade_time; + estim_time += fade_layer_time; + } + else + estim_time += exp_time; + + estim_time += tilt_time; + + sliced_layer_cnt++; + } + + m_print_statistics.support_used_material = supports_volume * SCALING_FACTOR * SCALING_FACTOR; m_print_statistics.objects_used_material = models_volume * SCALING_FACTOR * SCALING_FACTOR; // Estimated printing time // A layers count o the highest object if (max_layers_cnt == 0) m_print_statistics.estimated_print_time = "N/A"; - float init_exp_time = m_material_config.initial_exposure_time.getFloat();//35; - float exp_time = m_material_config.exposure_time.getFloat();//8; + else + m_print_statistics.estimated_print_time = get_time_dhms(float(estim_time)); - // TODO : fade_layers_cnt should be filled in the future - // This variable will be a part of the print(material) preset - const int fade_layers_cnt = 10; // [3;20] - - // TODO : tilt_delay_before_time & tilt_delay_after_time should be filled in the future - // These values are received from the printer after a printing start - const float tilt_delay_before_time = 0.0; - const float tilt_delay_after_time = 0.0; - if (tilt_delay_before_time + tilt_delay_after_time > 0.0) - { - init_exp_time += tilt_delay_before_time + tilt_delay_after_time; - exp_time += tilt_delay_before_time + tilt_delay_after_time; - } - - float estim_time = init_exp_time * 3 + exp_time * (max_layers_cnt - 3 - fade_layers_cnt); - - const float delta_time = (init_exp_time - exp_time) / (fade_layers_cnt+1); - double fade_layer_time = init_exp_time; - while (fade_layer_time > exp_time) - { - fade_layer_time -= delta_time; - estim_time += fade_layer_time; - } - - m_print_statistics.estimated_print_time = get_time_dhms(estim_time); + m_print_statistics.fast_layers_count = fast_layers; + m_print_statistics.slow_layers_count = slow_layers; } // Returns true if an object step is done on all objects and there's at least one object. diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index f054921c8..ffa451b35 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -177,6 +177,8 @@ struct SLAPrintStatistics std::string estimated_print_time; double objects_used_material; double support_used_material; + size_t slow_layers_count; + size_t fast_layers_count; double total_cost; double total_weight; @@ -191,6 +193,8 @@ struct SLAPrintStatistics estimated_print_time.clear(); objects_used_material = 0.; support_used_material = 0.; + slow_layers_count = 0; + fast_layers_count = 0; total_cost = 0.; total_weight = 0.; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f4a3c0b48..fc5f52161 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -822,16 +822,16 @@ void Sidebar::show_sliced_info_sizer(const bool show) if (p->plater->printer_technology() == ptSLA) { const SLAPrintStatistics& ps = p->plater->sla_print().print_statistics(); - wxString new_label = _(L("Used Material (mm³)")) + " :"; + wxString new_label = _(L("Used Material (ml)")) + " :"; const bool is_supports = ps.support_used_material > 0.0; if (is_supports) new_label += wxString::Format("\n - %s\n - %s", _(L("object(s)")), _(L("supports and pad"))); wxString info_text = is_supports ? - wxString::Format("%.2f \n%.2f \n%.2f", ps.objects_used_material + ps.support_used_material/* / 1000*/, - ps.objects_used_material/* / 1000*/, - ps.support_used_material/* / 1000*/) : - wxString::Format("%.2f", ps.objects_used_material + ps.support_used_material/* / 1000*/); + wxString::Format("%.2f \n%.2f \n%.2f", (ps.objects_used_material + ps.support_used_material) / 1000, + ps.objects_used_material / 1000, + ps.support_used_material / 1000) : + wxString::Format("%.2f", ps.objects_used_material + ps.support_used_material / 1000); p->sliced_info->SetTextAndShow(siMateril_unit, info_text, new_label); p->sliced_info->SetTextAndShow(siCost, "N/A"/*wxString::Format("%.2f", ps.total_cost)*/); From a690466dbfb875f7131225faf278c4e82d4fd5a0 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 18 Feb 2019 13:18:47 +0100 Subject: [PATCH 06/18] Fixed a typo for the last commit --- src/libslic3r/SLAPrint.cpp | 4 ++-- src/slic3r/GUI/Plater.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index ecc990d01..13bb57b5e 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1056,8 +1056,8 @@ void SLAPrint::fill_statistics() // This variable will be a part of the print preset const int fade_layers_cnt = 10; // [3;20] - const double width = m_printer_config.display_width.getFloat() / SCALING_FACTOR; - const double height = m_printer_config.display_width.getFloat() / SCALING_FACTOR; + const double width = m_printer_config.display_width.getFloat() / SCALING_FACTOR; + const double height = m_printer_config.display_height.getFloat() / SCALING_FACTOR; const double display_area = width*height; double supports_volume = 0.0; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index fc5f52161..87a950b7f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -831,7 +831,7 @@ void Sidebar::show_sliced_info_sizer(const bool show) wxString::Format("%.2f \n%.2f \n%.2f", (ps.objects_used_material + ps.support_used_material) / 1000, ps.objects_used_material / 1000, ps.support_used_material / 1000) : - wxString::Format("%.2f", ps.objects_used_material + ps.support_used_material / 1000); + wxString::Format("%.2f", (ps.objects_used_material + ps.support_used_material) / 1000); p->sliced_info->SetTextAndShow(siMateril_unit, info_text, new_label); p->sliced_info->SetTextAndShow(siCost, "N/A"/*wxString::Format("%.2f", ps.total_cost)*/); From 9d0acc010d170b3e47dfe166f3fb79a5f27a2105 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 18 Feb 2019 16:04:55 +0100 Subject: [PATCH 07/18] Added new options for SLAPrintSettings (faded_layers) and SLAPrinterSettings (fast/slow_tilt_time and area_fill) --- src/libslic3r/PrintConfig.cpp | 34 ++++++++++++++++++++++++++++++++++ src/libslic3r/PrintConfig.hpp | 10 ++++++++++ src/libslic3r/SLAPrint.cpp | 19 +++++++++---------- src/slic3r/GUI/Preset.cpp | 2 ++ src/slic3r/GUI/Tab.cpp | 8 ++++++++ 5 files changed, 63 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 3e1ee9f9f..31d19e317 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2435,6 +2435,32 @@ void PrintConfigDef::init_sla_params() def->enum_labels.push_back(L("Portrait")); def->default_value = new ConfigOptionEnum(sladoPortrait); + def = this->add("fast_tilt_time", coFloat); + def->label = L("Fast"); + def->full_label = L("Fast tilt"); + def->tooltip = L("Time of the fast tilt"); + def->sidetext = L("s"); + def->min = 0; + def->mode = comExpert; + def->default_value = new ConfigOptionFloat(5.); + + def = this->add("slow_tilt_time", coFloat); + def->label = L("Slow"); + def->full_label = L("Slow tilt"); + def->tooltip = L("Time of the slow tilt"); + def->sidetext = L("s"); + def->min = 0; + def->mode = comExpert; + def->default_value = new ConfigOptionFloat(8.); + + def = this->add("area_fill", coFloat); + def->label = L("Area fill"); + def->tooltip = L("The percentage of the bed area. \nIf the print area exceeds the specified value, \nthen a slow tilt will be used, otherwise - a fast tilt"); + def->sidetext = L("%"); + def->min = 0; + def->mode = comExpert; + def->default_value = new ConfigOptionFloat(50.); + def = this->add("printer_correction", coFloats); def->full_label = L("Printer scaling correction"); def->tooltip = L("Printer scaling correction"); @@ -2450,6 +2476,14 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->default_value = new ConfigOptionFloat(0.3); + def = this->add("faded_layers", coInt); + def->label = L("Faded layers"); + def->tooltip = L("Number of the layers needed for the exposure time fade from initial exposure time to the exposure time"); + def->min = 3; + def->max = 20; + def->mode = comExpert; + def->default_value = new ConfigOptionInt(10); + def = this->add("exposure_time", coFloat); def->label = L("Exposure time"); def->tooltip = L("Exposure time"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 20c089d1c..e4648c952 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -958,6 +958,9 @@ class SLAPrintObjectConfig : public StaticPrintConfig public: ConfigOptionFloat layer_height; + //Number of the layers needed for the exposure time fade [3;20] + ConfigOptionInt faded_layers /*= 10*/; + // Enabling or disabling support creation ConfigOptionBool supports_enable; @@ -1028,6 +1031,7 @@ protected: void initialize(StaticCacheBase &cache, const char *base_ptr) { OPT_PTR(layer_height); + OPT_PTR(faded_layers); OPT_PTR(supports_enable); OPT_PTR(support_head_front_diameter); OPT_PTR(support_head_penetration); @@ -1085,6 +1089,9 @@ public: ConfigOptionInt display_pixels_y; ConfigOptionEnum display_orientation; ConfigOptionFloats printer_correction; + ConfigOptionFloat fast_tilt_time; + ConfigOptionFloat slow_tilt_time; + ConfigOptionFloat area_fill; protected: void initialize(StaticCacheBase &cache, const char *base_ptr) { @@ -1097,6 +1104,9 @@ protected: OPT_PTR(display_pixels_y); OPT_PTR(display_orientation); OPT_PTR(printer_correction); + OPT_PTR(fast_tilt_time); + OPT_PTR(slow_tilt_time); + OPT_PTR(area_fill); } }; diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 13bb57b5e..d24be4504 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1005,7 +1005,10 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector steps; @@ -1043,18 +1046,14 @@ void SLAPrint::fill_statistics() const double init_layer_height = m_material_config.initial_layer_height.getFloat(); const double layer_height = m_default_object_config.layer_height.getFloat(); - // TODO : slow_fast_limit, fast_tilt, slow_tilt should be filled in the future - // These variables will be a part of the printer preset - const double slow_fast_limit = 0.5; // if printing area is more than 50% of the bed area, then use a slow tilt - const double fast_tilt = 5.0; - const double slow_tilt = 8.0; + const double area_fill = m_printer_config.area_fill.getFloat()*0.01;// 0.5 (50%); + const double fast_tilt = m_printer_config.fast_tilt_time.getFloat();// 5.0; + const double slow_tilt = m_printer_config.slow_tilt_time.getFloat();// 8.0; const double init_exp_time = m_material_config.initial_exposure_time.getFloat(); const double exp_time = m_material_config.exposure_time.getFloat(); - // TODO : fade_layers_cnt should be filled in the future - // This variable will be a part of the print preset - const int fade_layers_cnt = 10; // [3;20] + const int fade_layers_cnt = m_default_object_config.faded_layers.getInt();// 10 // [3;20] const double width = m_printer_config.display_width.getFloat() / SCALING_FACTOR; const double height = m_printer_config.display_height.getFloat() / SCALING_FACTOR; @@ -1116,7 +1115,7 @@ void SLAPrint::fill_statistics() // Calculation of the slow and fast layers to the future controlling those values on FW - const bool is_fast_layer = (layer_model_area + layer_support_area) <= display_area*slow_fast_limit; + const bool is_fast_layer = (layer_model_area + layer_support_area) <= display_area*area_fill; const double tilt_time = is_fast_layer ? fast_tilt : slow_tilt; if (is_fast_layer) fast_layers++; diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index ee182a01a..b755cc075 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -408,6 +408,7 @@ const std::vector& Preset::sla_print_options() if (s_opts.empty()) { s_opts = { "layer_height", + "faded_layers", "supports_enable", "support_head_front_diameter", "support_head_penetration", @@ -465,6 +466,7 @@ const std::vector& Preset::sla_printer_options() "bed_shape", "max_print_height", "display_width", "display_height", "display_pixels_x", "display_pixels_y", "display_orientation", + "fast_tilt_time", "slow_tilt_time", "area_fill", "printer_correction", "print_host", "printhost_apikey", "printhost_cafile", "printer_notes", diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 28b7cd248..174b3983c 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1949,6 +1949,13 @@ void TabPrinter::build_sla() optgroup->append_line(line); optgroup->append_single_option_line("display_orientation"); + optgroup = page->new_optgroup(_(L("Tilt"))); + line = { _(L("Tilt time")), "" }; + line.append_option(optgroup->get_option("fast_tilt_time")); + line.append_option(optgroup->get_option("slow_tilt_time")); + optgroup->append_line(line); + optgroup->append_single_option_line("area_fill"); + optgroup = page->new_optgroup(_(L("Corrections"))); line = Line{ m_config->def()->get("printer_correction")->full_label, "" }; std::vector axes{ "X", "Y", "Z" }; @@ -3178,6 +3185,7 @@ void TabSLAPrint::build() auto optgroup = page->new_optgroup(_(L("Layers"))); optgroup->append_single_option_line("layer_height"); + optgroup->append_single_option_line("faded_layers"); page = add_options_page(_(L("Supports")), "building.png"); optgroup = page->new_optgroup(_(L("Supports"))); From 9e3434ecc14ef58454528d035e3b9aa98003e895 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 19 Feb 2019 12:14:13 +0100 Subject: [PATCH 08/18] Fixed calculation of the consumed material for the supports --- src/libslic3r/SLAPrint.cpp | 31 ++++++++++++++++++++++++++----- src/slic3r/GUI/Plater.cpp | 19 ++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index d24be4504..21c922a16 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1100,13 +1100,34 @@ void SLAPrint::fill_statistics() const auto index = po->get_slice_index(); if (index.find(layer.first) == index.end()) continue; - - if (index.at(layer.first).model_slices_idx != SLAPrintObject::SliceRecord::NONE) { - for (const ExPolygon& polygon : po->get_model_slices().at(index.at(layer.first).model_slices_idx)) + + const SLAPrintObject::SliceRecord& record = index.at(layer.first); + + if (record.model_slices_idx != SLAPrintObject::SliceRecord::NONE && + record.support_slices_idx != SLAPrintObject::SliceRecord::NONE) + { + double model_area = 0; + for (const ExPolygon& polygon : po->get_model_slices().at(record.model_slices_idx)) + model_area += polygon.area(); + + layer_model_area += model_area; + + Polygons polygons = to_polygons(po->get_model_slices().at(record.model_slices_idx)); + append(polygons, to_polygons(po->get_support_slices().at(record.support_slices_idx))); + polygons = union_(polygons); + double poligons_area = 0; + for (const Polygon& polygon : polygons) + poligons_area += polygon.area(); + + if (poligons_area > model_area) + layer_support_area += (poligons_area-model_area); + } + else if (record.model_slices_idx != SLAPrintObject::SliceRecord::NONE) { + for (const ExPolygon& polygon : po->get_model_slices().at(record.model_slices_idx)) layer_model_area += polygon.area(); } - /*else */if (index.at(layer.first).support_slices_idx != SLAPrintObject::SliceRecord::NONE) { - for (const ExPolygon& polygon : po->get_support_slices().front()) + else if (record.support_slices_idx != SLAPrintObject::SliceRecord::NONE) { + for (const ExPolygon& polygon : po->get_support_slices().at(record.support_slices_idx)) layer_support_area += polygon.area(); } } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 87a950b7f..e8944654a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -99,6 +99,11 @@ public: wxStaticText *info_facets; wxStaticText *info_materials; wxStaticText *info_manifold; + + wxStaticText *label_volume; + wxStaticText *label_materials; + std::vector sla_hided_items; + bool showing_manifold_warning_icon; void show_sizer(bool show); }; @@ -120,15 +125,16 @@ ObjectInfo::ObjectInfo(wxWindow *parent) : (*info_label)->SetFont(wxGetApp().small_font()); grid_sizer->Add(text, 0); grid_sizer->Add(*info_label, 0); + return text; }; init_info_label(&info_size, _(L("Size"))); - init_info_label(&info_volume, _(L("Volume"))); + label_volume = init_info_label(&info_volume, _(L("Volume"))); init_info_label(&info_facets, _(L("Facets"))); - init_info_label(&info_materials, _(L("Materials"))); + label_materials = init_info_label(&info_materials, _(L("Materials"))); Add(grid_sizer, 0, wxEXPAND); - auto *info_manifold_text = new wxStaticText(parent, wxID_ANY, _(L("Manifold"))); + auto *info_manifold_text = new wxStaticText(parent, wxID_ANY, _(L("Manifold")) + ":"); info_manifold_text->SetFont(wxGetApp().small_font()); info_manifold = new wxStaticText(parent, wxID_ANY, ""); info_manifold->SetFont(wxGetApp().small_font()); @@ -139,6 +145,8 @@ ObjectInfo::ObjectInfo(wxWindow *parent) : sizer_manifold->Add(manifold_warning_icon, 0, wxLEFT, 2); sizer_manifold->Add(info_manifold, 0, wxLEFT, 2); Add(sizer_manifold, 0, wxEXPAND | wxTOP, 4); + + sla_hided_items = { label_volume, info_volume, label_materials, info_materials }; } void ObjectInfo::show_sizer(bool show) @@ -811,6 +819,11 @@ void Sidebar::show_info_sizer() } p->object_info->show_sizer(true); + + if (p->plater->printer_technology() == ptSLA) { + for (auto item: p->object_info->sla_hided_items) + item->Show(false); + } } void Sidebar::show_sliced_info_sizer(const bool show) From 327114fa3ec8e0f01ffb53878f17c441bd49a361 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 19 Feb 2019 13:47:40 +0100 Subject: [PATCH 09/18] Added missed include for the OSX build --- src/libslic3r/SLAPrint.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index ffa451b35..23c34ada1 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -2,7 +2,7 @@ #define slic3r_SLAPrint_hpp_ #include - +#include "ClipperUtils.hpp" #include "PrintBase.hpp" #include "PrintExport.hpp" #include "Point.hpp" From 98a551587ce74b051f4ac6538763c3557801577f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 20 Feb 2019 15:13:03 +0100 Subject: [PATCH 10/18] Improved used material estimation (take instances too) --- src/libslic3r/SLAPrint.cpp | 98 +++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 34 deletions(-) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 21c922a16..6252fe188 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1059,6 +1059,24 @@ void SLAPrint::fill_statistics() const double height = m_printer_config.display_height.getFloat() / SCALING_FACTOR; const double display_area = width*height; + // get polygons for all instances in the object + auto get_all_polygons = [](const ExPolygons& input_polygons, const std::vector& instances) { + ExPolygons polygons; + const size_t inst_cnt = instances.size(); + + polygons.reserve(input_polygons.size()*inst_cnt); + for (const ExPolygon& polygon : input_polygons) { + for (size_t i = 0; i < inst_cnt; ++i) + { + ExPolygon tmp = polygon; + tmp.rotate(Geometry::rad2deg(instances[i].rotation)); + tmp.translate(instances[i].shift.x(), instances[i].shift.y()); + polygons.push_back(tmp); + } + } + return polygons; + }; + double supports_volume = 0.0; double models_volume = 0.0; @@ -1093,46 +1111,58 @@ void SLAPrint::fill_statistics() // Calculation of the consumed material - double layer_model_area = 0; - double layer_support_area = 0; + Polygons model_polygons; + Polygons supports_polygons; + for (SLAPrintObject * po : m_objects) { - const auto index = po->get_slice_index(); - if (index.find(layer.first) == index.end()) - continue; - - const SLAPrintObject::SliceRecord& record = index.at(layer.first); - - if (record.model_slices_idx != SLAPrintObject::SliceRecord::NONE && - record.support_slices_idx != SLAPrintObject::SliceRecord::NONE) - { - double model_area = 0; - for (const ExPolygon& polygon : po->get_model_slices().at(record.model_slices_idx)) - model_area += polygon.area(); - - layer_model_area += model_area; - - Polygons polygons = to_polygons(po->get_model_slices().at(record.model_slices_idx)); - append(polygons, to_polygons(po->get_support_slices().at(record.support_slices_idx))); - polygons = union_(polygons); - double poligons_area = 0; - for (const Polygon& polygon : polygons) - poligons_area += polygon.area(); - - if (poligons_area > model_area) - layer_support_area += (poligons_area-model_area); + const SLAPrintObject::SliceIndex& index = po->get_slice_index(); + auto key = layer.first; + if (index.find(layer.first) == index.end()) { + const SLAPrintObject::SliceIndex::const_iterator it_key = std::find_if(index.begin(), index.end(), + [key](const SLAPrintObject::SliceIndex::value_type& id) -> bool { return std::abs(key - id.first) < EPSILON; }); + if (it_key == index.end()) + continue; + key = it_key->first; } - else if (record.model_slices_idx != SLAPrintObject::SliceRecord::NONE) { - for (const ExPolygon& polygon : po->get_model_slices().at(record.model_slices_idx)) - layer_model_area += polygon.area(); + + const SLAPrintObject::SliceRecord& record = index.at(key); + + if (record.model_slices_idx != SLAPrintObject::SliceRecord::NONE) { + const ExPolygons& expolygons = po->get_model_slices().at(record.model_slices_idx); + const ExPolygons model_expolygons = get_all_polygons(expolygons, po->instances()); + + append(model_polygons, to_polygons(model_expolygons)); } - else if (record.support_slices_idx != SLAPrintObject::SliceRecord::NONE) { - for (const ExPolygon& polygon : po->get_support_slices().at(record.support_slices_idx)) - layer_support_area += polygon.area(); + + if (record.support_slices_idx != SLAPrintObject::SliceRecord::NONE) { + const ExPolygons& expolygons = po->get_support_slices().at(record.support_slices_idx); + const ExPolygons support_expolygons = get_all_polygons(expolygons, po->instances()); + + append(supports_polygons, to_polygons(support_expolygons)); } } - models_volume += layer_model_area * l_height; - supports_volume += layer_support_area * l_height; + + model_polygons = union_(model_polygons); + double layer_model_area = 0; + for (const Polygon& polygon : model_polygons) + layer_model_area += polygon.area(); + + if (layer_model_area != 0) + models_volume += layer_model_area * l_height; + + if (!supports_polygons.empty() && !model_polygons.empty()) + append(supports_polygons, model_polygons); + supports_polygons = union_(supports_polygons); + double layer_support_area = 0; + for (const Polygon& polygon : supports_polygons) + layer_support_area += polygon.area(); + + if (layer_support_area != 0) { + layer_support_area -= layer_model_area; + supports_volume += layer_support_area * l_height; + } + // Calculation of the slow and fast layers to the future controlling those values on FW From 3ccfe7f53e9fea7215f06a365f2cfc882691bcef Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 21 Feb 2019 11:43:34 +0100 Subject: [PATCH 11/18] Fixed OSX-build --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 2 +- src/slic3r/GUI/Tab.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index f94d68147..5afd7ae59 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -44,7 +44,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : def.label = L("Name"); def.gui_type = "legend"; def.tooltip = L("Object name"); - def.width = 200; + def.width = 21 * wxGetApp().em_unit(); def.default_value = new ConfigOptionString{ " " }; m_og->append_single_option_line(Option(def, "object_name")); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 135420edb..430caaf0e 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -204,7 +204,7 @@ protected: void set_type(); int m_em_unit; - std::set m_dirty_options = {}; + std::set m_dirty_options; public: PresetBundle* m_preset_bundle; From 8d09508ca8ecc641726ce81958f834db76bb3d5f Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 21 Feb 2019 12:09:03 +0100 Subject: [PATCH 12/18] SLA supports: Update only supports for the selected object from iside the SLA support gizmo. --- src/slic3r/GUI/GLGizmo.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index 7a7f08518..086dbfdb1 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -1790,7 +1790,7 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const G update_mesh(); // If there are no points, let's ask the backend if it calculated some. - if (m_editing_mode_cache.empty() && m_parent.sla_print()->is_step_done(slaposSupportPoints)) + if (m_editing_mode_cache.empty()) get_data_from_backend(); if (m_model_object != m_old_model_object) @@ -2169,7 +2169,7 @@ void GLGizmoSlaSupports::delete_selected_points() m_unsaved_changes = true; } // This should trigger the support generation - // wxGetApp().plater()->reslice(); + // wxGetApp().plater()->reslice_SLA_supports(*m_model_object); } select_point(NoPoints); @@ -2283,7 +2283,9 @@ RENDER_AGAIN: if (apply_changes) { editing_mode_apply_changes(); force_refresh = true; - m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); + // Recalculate support structures once the editing mode is left. + // m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); + wxGetApp().plater()->reslice_SLA_supports(*m_model_object); } ImGui::SameLine(); bool discard_changes = m_imgui->button(_(L("Discard changes"))); @@ -2316,7 +2318,7 @@ RENDER_AGAIN: if (m_model_object->sla_support_points.empty() || dlg.ShowModal() == wxID_YES) { m_model_object->sla_support_points.clear(); m_editing_mode_cache.clear(); - wxGetApp().plater()->reslice(); + wxGetApp().plater()->reslice_SLA_supports(*m_model_object); } #endif } @@ -2335,7 +2337,7 @@ RENDER_AGAIN: m_model_object->sla_support_points.clear(); m_editing_mode_cache.clear(); - wxGetApp().plater()->reslice(); + wxGetApp().plater()->reslice_SLA_supports(*m_model_object); } ImGui::SameLine(); if (m_imgui->button(_(L("Cancel")))) { @@ -2496,7 +2498,7 @@ void GLGizmoSlaSupports::editing_mode_reload_cache() void GLGizmoSlaSupports::get_data_from_backend() { for (const SLAPrintObject* po : m_parent.sla_print()->objects()) { - if (po->model_object()->id() == m_model_object->id()) { + if (po->model_object()->id() == m_model_object->id() && po->is_step_done(slaposSupportPoints)) { const std::vector& points = po->get_support_points(); auto mat = po->trafo().inverse().cast(); for (unsigned int i=0; i Date: Thu, 21 Feb 2019 12:19:00 +0100 Subject: [PATCH 13/18] Fix Preview legend scaling --- src/slic3r/GUI/GLCanvas3D.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ee7425de2..e68f3673b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3879,8 +3879,8 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c wxMemoryDC mask_memDC; // calculate scaling -// const float scale = canvas.get_canvas_size().get_scale_factor(); - const float scale = wxGetApp().em_unit()*0.1; // get scale from em_unit() value, because of get_scale_factor() return 1 + const float scale_gl = canvas.get_canvas_size().get_scale_factor(); + const float scale = scale_gl * wxGetApp().em_unit()*0.1; // get scale from em_unit() value, because of get_scale_factor() return 1 const int scaled_square = std::floor((float)Px_Square * scale); const int scaled_title_offset = Px_Title_Offset * scale; const int scaled_text_offset = Px_Text_Offset * scale; @@ -3888,7 +3888,7 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c const int scaled_border = Px_Border * scale; // select default font - const wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)/*.Scale(scale)*/; // font is no need to scale now + const wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl); memDC.SetFont(font); mask_memDC.SetFont(font); From 76f1aa09d058ec9eaa2d87471c8eac08df27c10b Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 21 Feb 2019 12:39:38 +0100 Subject: [PATCH 14/18] Fixed an issue with background processing cancelation & SLA supports for a single object only. Fixed a spelling issue in "call_cancell_xxx" --- src/libslic3r/Print.cpp | 8 ++++---- src/libslic3r/PrintBase.hpp | 2 +- src/libslic3r/SLAPrint.cpp | 8 ++++---- src/slic3r/GUI/Plater.cpp | 5 +++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index d47cdf99f..5af247780 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -717,7 +717,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co if (model.id() != m_model.id()) { // Kill everything, initialize from scratch. // Stop background processing. - this->call_cancell_callback(); + this->call_cancel_callback(); update_apply_status(this->invalidate_all_steps()); for (PrintObject *object : m_objects) { model_object_status.emplace(object->model_object()->id(), ModelObjectStatus::Deleted); @@ -749,7 +749,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co } else { // Reorder the objects, add new objects. // First stop background processing before shuffling or deleting the PrintObjects in the object list. - this->call_cancell_callback(); + this->call_cancel_callback(); update_apply_status(this->invalidate_step(psGCodeExport)); // Second create a new list of objects. std::vector model_objects_old(std::move(m_model.objects)); @@ -859,7 +859,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co model_object.assign_copy(model_object_new); } else if (support_blockers_differ || support_enforcers_differ) { // First stop background processing before shuffling or deleting the ModelVolumes in the ModelObject's list. - this->call_cancell_callback(); + this->call_cancel_callback(); update_apply_status(false); // Invalidate just the supports step. auto range = print_object_status.equal_range(PrintObjectStatus(model_object.id())); @@ -960,7 +960,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co } } if (m_objects != print_objects_new) { - this->call_cancell_callback(); + this->call_cancel_callback(); update_apply_status(this->invalidate_all_steps()); m_objects = print_objects_new; // Delete the PrintObjects marked as Unknown or Deleted. diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index e70edd20d..e01b678a5 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -326,7 +326,7 @@ protected: tbb::mutex& state_mutex() const { return m_state_mutex; } std::function cancel_callback() { return m_cancel_callback; } - void call_cancell_callback() { m_cancel_callback(); } + void call_cancel_callback() { m_cancel_callback(); } // If the background processing stop was requested, throw CanceledException. // To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly. diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 213437612..473df09e8 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -182,7 +182,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf if (model.id() != m_model.id()) { // Kill everything, initialize from scratch. // Stop background processing. - this->call_cancell_callback(); + this->call_cancel_callback(); update_apply_status(this->invalidate_all_steps()); for (SLAPrintObject *object : m_objects) { model_object_status.emplace(object->model_object()->id(), ModelObjectStatus::Deleted); @@ -211,7 +211,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf } else { // Reorder the objects, add new objects. // First stop background processing before shuffling or deleting the PrintObjects in the object list. - this->call_cancell_callback(); + this->call_cancel_callback(); update_apply_status(this->invalidate_step(slapsRasterize)); // Second create a new list of objects. std::vector model_objects_old(std::move(m_model.objects)); @@ -380,7 +380,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf } if (m_objects != print_objects_new) { - this->call_cancell_callback(); + this->call_cancel_callback(); update_apply_status(this->invalidate_all_steps()); m_objects = print_objects_new; // Delete the PrintObjects marked as Unknown or Deleted. @@ -436,7 +436,7 @@ void SLAPrint::set_task(const TaskParams ¶ms) } } if (!running) - this->cancel_callback(); + this->call_cancel_callback(); // Now the background process is either stopped, or it is inside one of the print object steps to be calculated anyway. if (params.single_model_instance_only) { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 5056fe72e..4da9f6652 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2036,8 +2036,9 @@ unsigned int Plater::priv::update_background_process(bool force_validation) //background_process.is_export_scheduled() - byl zavolan "Export G-code", background processing ma jmeno export souboru //background_process.is_upload_scheduled() - byl zavolan "Send to OctoPrint", jeste nebylo doslajsovano (pak se preda upload fronte a background process zapomene) //background_process.empty() - prazdna plocha - // pokud (invalidated != Print::APPLY_STATUS_UNCHANGED) a ! background_process.empty() -> je neco ke slajsovani (povol tlacitko) - // pokud (return_state & UPDATE_BACKGROUND_PROCESS_INVALID) != 0 -> doslo k chybe (gray out "Slice now") + // pokud (return_state & UPDATE_BACKGROUND_PROCESS_INVALID) != 0 -> doslo k chybe (gray out "Slice now") mozna "Invalid data"??? + // jinak background_process.running() -> Zobraz "Slicing ..." + // jinak pokud ! background_process.empty() && ! background_process.finished() -> je neco ke slajsovani (povol tlacitko) "Slice Now" return return_state; } From bf699462c3c0b01c6a8389cd66db8d0d1df2a442 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 21 Feb 2019 11:54:18 +0100 Subject: [PATCH 15/18] imgui: Attempt to fix Tab key --- src/slic3r/GUI/GLCanvas3D.cpp | 12 +++++++++--- src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/GUI_Preview.cpp | 2 +- src/slic3r/GUI/ImGuiWrapper.cpp | 7 ++----- src/slic3r/GUI/Plater.cpp | 5 ++--- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e68f3673b..ad19b08bd 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4085,6 +4085,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); wxDEFINE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event); wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>); wxDEFINE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); +wxDEFINE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent); GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) : m_canvas(canvas) @@ -5321,10 +5322,15 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) #endif // ENABLE_IMGUI if (evt.GetEventType() == wxEVT_KEY_UP) { const int keyCode = evt.GetKeyCode(); - - // shift has been just released - SLA gizmo might want to close rectangular selection. - if (m_gizmos.get_current_type() == Gizmos::SlaSupports && keyCode == WXK_SHIFT && m_gizmos.mouse_event(SLAGizmoEventType::ShiftUp)) + + if (keyCode == WXK_TAB) { + // Enable switching between 3D and Preview with Tab + // m_canvas->HandleAsNavigationKey(evt); // XXX: Doesn't work in some cases / on Linux + post_event(SimpleEvent(EVT_GLCANVAS_TAB)); + } else if (m_gizmos.get_current_type() == Gizmos::SlaSupports && keyCode == WXK_SHIFT && m_gizmos.mouse_event(SLAGizmoEventType::ShiftUp)) { + // shift has been just released - SLA gizmo might want to close rectangular selection. m_dirty = true; + } } evt.Skip(); // Needed to have EVT_CHAR generated as well diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 3d44aa13f..ff136e190 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -131,6 +131,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event); wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>); wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent); +wxDECLARE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent); // this describes events being passed from GLCanvas3D to SlaSupport gizmo enum class SLAGizmoEventType { diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 717d6de00..f730496ce 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -229,7 +229,7 @@ bool Preview::init(wxWindow* parent, DynamicPrintConfig* config, BackgroundSlici if ((config == nullptr) || (process == nullptr) || (gcode_preview_data == nullptr)) return false; - if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)) + if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */)) return false; m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 0ec0050e6..0e437ef6d 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -138,11 +138,8 @@ bool ImGuiWrapper::update_key_data(wxKeyEvent &evt) io.KeyAlt = evt.AltDown(); io.KeySuper = evt.MetaDown(); - // XXX: Unfortunatelly this seems broken due to some interference with wxWidgets, - // we have to return true always (perform re-render). - // new_frame(); - // return want_keyboard() || want_text_input(); - return true; + new_frame(); + return want_keyboard() || want_text_input(); } } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 4da9f6652..08f444d91 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1146,9 +1146,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D = new View3D(q, &model, config, &background_process); preview = new Preview(q, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); }); - // Let the Tab key switch between the 3D view and the layer preview. - view3D->Bind(wxEVT_NAVIGATION_KEY, [this](wxNavigationKeyEvent &evt) { if (evt.IsFromTab()) this->select_next_view_3D(); }); - preview->Bind(wxEVT_NAVIGATION_KEY, [this](wxNavigationKeyEvent &evt) { if (evt.IsFromTab()) this->select_next_view_3D(); }); panels.push_back(view3D); panels.push_back(preview); @@ -1201,6 +1198,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event &evt) { this->sidebar->enable_buttons(evt.data); }); view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_GEOMETRY, &priv::on_update_geometry, this); view3D_canvas->Bind(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, &priv::on_3dcanvas_mouse_dragging_finished, this); + view3D_canvas->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); }); // 3DScene/Toolbar: view3D_canvas->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this); view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); }); @@ -1216,6 +1214,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) // Preview events: preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); }); view3D_canvas->Bind(EVT_GLCANVAS_INIT, [this](SimpleEvent&) { init_view_toolbar(); }); From ac0c7e80653c3e0109e558c32f07cf6d73e54eee Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 21 Feb 2019 15:46:04 +0100 Subject: [PATCH 16/18] Optimization of SLA print time estimation, moved SLA print time estimation calculation into rasterization step, so that the print time estimation is tracked by some SLAPrintStep. Extended the output file name generator to use the SLA print statistics. --- src/libslic3r/PrintExport.hpp | 1 + src/libslic3r/SLAPrint.cpp | 103 ++++++++++++++++++---------------- src/libslic3r/SLAPrint.hpp | 4 +- src/slic3r/GUI/Plater.cpp | 88 ++++++++++++++--------------- 4 files changed, 100 insertions(+), 96 deletions(-) diff --git a/src/libslic3r/PrintExport.hpp b/src/libslic3r/PrintExport.hpp index 64babd507..e196cde5f 100644 --- a/src/libslic3r/PrintExport.hpp +++ b/src/libslic3r/PrintExport.hpp @@ -14,6 +14,7 @@ namespace Slic3r { +// Used for addressing parameters of FilePrinter::set_statistics() enum ePrintStatistics { psUsedMaterial = 0, diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index db8789fa0..01f35149d 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -2,6 +2,7 @@ #include "SLA/SLASupportTree.hpp" #include "SLA/SLABasePool.hpp" #include "SLA/SLAAutoSupports.hpp" +#include "ClipperUtils.hpp" #include "MTUtils.hpp" #include @@ -477,6 +478,15 @@ void SLAPrint::finalize() m_stepmask[istep] = true; } +// Generate a recommended output file name based on the format template, default extension, and template parameters +// (timestamps, object placeholders derived from the model, current placeholder prameters and print statistics. +// Use the final print statistics if available, or just keep the print statistics placeholders if not available yet (before the output is finalized). +std::string SLAPrint::output_filename() const +{ + DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders(); + return this->PrintBase::output_filename(m_print_config.output_filename_format.value, "zip", &config); +} + namespace { // Compile the argument for support creation from the static print config. sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) { @@ -960,6 +970,15 @@ void SLAPrint::process() // Print all the layers in parallel tbb::parallel_for(0, lvlcnt, lvlfn); + + // Fill statistics + this->fill_statistics(); + // Set statistics values to the printer + m_printer->set_statistics({(m_print_statistics.objects_used_material + m_print_statistics.support_used_material)/1000, + 10.0, + double(m_print_statistics.slow_layers_count), + double(m_print_statistics.fast_layers_count) + }); }; using slaposFn = std::function; @@ -1042,16 +1061,6 @@ void SLAPrint::process() st += unsigned(PRINT_STEP_LEVELS[currentstep] * pstd); } - // Fill statistics - fill_statistics(); - // Set statistics values to the printer - SLAPrinter& printer = *m_printer; - printer.set_statistics({(m_print_statistics.objects_used_material + m_print_statistics.support_used_material)/1000, - 10.0, - double(m_print_statistics.slow_layers_count), - double(m_print_statistics.fast_layers_count) - }); - // If everything vent well report_status(*this, 100, L("Slicing done")); } @@ -1128,7 +1137,7 @@ void SLAPrint::fill_statistics() const double init_exp_time = m_material_config.initial_exposure_time.getFloat(); const double exp_time = m_material_config.exposure_time.getFloat(); - const int fade_layers_cnt = m_default_object_config.faded_layers.getInt();// 10 // [3;20] + const int fade_layers_cnt = m_default_object_config.faded_layers.getInt();// 10 // [3;20] const double width = m_printer_config.display_width.getFloat() / SCALING_FACTOR; const double height = m_printer_config.display_height.getFloat() / SCALING_FACTOR; @@ -1136,17 +1145,21 @@ void SLAPrint::fill_statistics() // get polygons for all instances in the object auto get_all_polygons = [](const ExPolygons& input_polygons, const std::vector& instances) { - ExPolygons polygons; const size_t inst_cnt = instances.size(); - polygons.reserve(input_polygons.size()*inst_cnt); + size_t polygon_cnt = 0; + for (const ExPolygon& polygon : input_polygons) + polygon_cnt += polygon.holes.size() + 1; + + Polygons polygons; + polygons.reserve(polygon_cnt * inst_cnt); for (const ExPolygon& polygon : input_polygons) { for (size_t i = 0; i < inst_cnt; ++i) { ExPolygon tmp = polygon; tmp.rotate(Geometry::rad2deg(instances[i].rotation)); tmp.translate(instances[i].shift.x(), instances[i].shift.y()); - polygons.push_back(tmp); + polygons_append(polygons, to_polygons(std::move(tmp))); } } return polygons; @@ -1161,13 +1174,21 @@ void SLAPrint::fill_statistics() size_t fast_layers = 0; // find highest object - size_t max_layers_cnt = 0; + // Which is a better bet? To compare by max_z or by number of layers in the index? + double max_z = 0.; + size_t max_layers_cnt = 0; size_t highest_obj_idx = 0; - for (SLAPrintObject * po : m_objects) { + for (SLAPrintObject *&po : m_objects) { const SLAPrintObject::SliceIndex& slice_index = po->get_slice_index(); - if (max_layers_cnt < slice_index.size()) { - max_layers_cnt = slice_index.size(); - highest_obj_idx = std::find(m_objects.begin(), m_objects.end(), po) - m_objects.begin(); + if (! slice_index.empty()) { + double z = (-- slice_index.end())->first; + size_t cnt = slice_index.size(); + //if (z > max_z) { + if (cnt > max_layers_cnt) { + max_layers_cnt = cnt; + max_z = z; + highest_obj_idx = &po - &m_objects.front(); + } } } @@ -1180,9 +1201,7 @@ void SLAPrint::fill_statistics() int sliced_layer_cnt = 0; for (const auto& layer : highest_obj_slice_index) { - const double l_height = (layer.first == highest_obj_slice_index.begin()->first && - init_layer_height != layer_height) ? - init_layer_height : layer_height; + const double l_height = (layer.first == highest_obj_slice_index.begin()->first) ? init_layer_height : layer_height; // Calculation of the consumed material @@ -1191,31 +1210,21 @@ void SLAPrint::fill_statistics() for (SLAPrintObject * po : m_objects) { - const SLAPrintObject::SliceIndex& index = po->get_slice_index(); - auto key = layer.first; - if (index.find(layer.first) == index.end()) { - const SLAPrintObject::SliceIndex::const_iterator it_key = std::find_if(index.begin(), index.end(), - [key](const SLAPrintObject::SliceIndex::value_type& id) -> bool { return std::abs(key - id.first) < EPSILON; }); - if (it_key == index.end()) + const SLAPrintObject::SliceRecord *record = nullptr; + { + const SLAPrintObject::SliceIndex& index = po->get_slice_index(); + auto key = layer.first; + const SLAPrintObject::SliceIndex::const_iterator it_key = index.lower_bound(key - float(EPSILON)); + if (it_key == index.end() || it_key->first > key + EPSILON) continue; - key = it_key->first; + record = &it_key->second; } - const SLAPrintObject::SliceRecord& record = index.at(key); - - if (record.model_slices_idx != SLAPrintObject::SliceRecord::NONE) { - const ExPolygons& expolygons = po->get_model_slices().at(record.model_slices_idx); - const ExPolygons model_expolygons = get_all_polygons(expolygons, po->instances()); - - append(model_polygons, to_polygons(model_expolygons)); - } + if (record->model_slices_idx != SLAPrintObject::SliceRecord::NONE) + append(model_polygons, get_all_polygons(po->get_model_slices()[record->model_slices_idx], po->instances())); - if (record.support_slices_idx != SLAPrintObject::SliceRecord::NONE) { - const ExPolygons& expolygons = po->get_support_slices().at(record.support_slices_idx); - const ExPolygons support_expolygons = get_all_polygons(expolygons, po->instances()); - - append(supports_polygons, to_polygons(support_expolygons)); - } + if (record->support_slices_idx != SLAPrintObject::SliceRecord::NONE) + append(supports_polygons, get_all_polygons(po->get_support_slices()[record->support_slices_idx], po->instances())); } model_polygons = union_(model_polygons); @@ -1227,17 +1236,13 @@ void SLAPrint::fill_statistics() models_volume += layer_model_area * l_height; if (!supports_polygons.empty() && !model_polygons.empty()) - append(supports_polygons, model_polygons); - supports_polygons = union_(supports_polygons); + supports_polygons = diff(supports_polygons, model_polygons); double layer_support_area = 0; for (const Polygon& polygon : supports_polygons) layer_support_area += polygon.area(); - if (layer_support_area != 0) { - layer_support_area -= layer_model_area; + if (layer_support_area != 0) supports_volume += layer_support_area * l_height; - } - // Calculation of the slow and fast layers to the future controlling those values on FW diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 570021561..4ac17f7b5 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -2,7 +2,6 @@ #define slic3r_SLAPrint_hpp_ #include -#include "ClipperUtils.hpp" #include "PrintBase.hpp" #include "PrintExport.hpp" #include "Point.hpp" @@ -237,8 +236,7 @@ public: } const PrintObjects& objects() const { return m_objects; } - std::string output_filename() const override - { return this->PrintBase::output_filename(m_print_config.output_filename_format.value, "zip"); } + std::string output_filename() const override; const SLAPrintStatistics& print_statistics() const { return m_print_statistics; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 103463f87..8c035215b 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -101,7 +101,7 @@ public: wxStaticText *label_volume; wxStaticText *label_materials; - std::vector sla_hided_items; + std::vector sla_hidden_items; bool showing_manifold_warning_icon; void show_sizer(bool show); @@ -145,7 +145,7 @@ ObjectInfo::ObjectInfo(wxWindow *parent) : sizer_manifold->Add(info_manifold, 0, wxLEFT, 2); Add(sizer_manifold, 0, wxEXPAND | wxTOP, 4); - sla_hided_items = { label_volume, info_volume, label_materials, info_materials }; + sla_hidden_items = { label_volume, info_volume, label_materials, info_materials }; } void ObjectInfo::show_sizer(bool show) @@ -839,7 +839,7 @@ void Sidebar::show_info_sizer() p->object_info->show_sizer(true); if (p->plater->printer_technology() == ptSLA) { - for (auto item: p->object_info->sla_hided_items) + for (auto item: p->object_info->sla_hidden_items) item->Show(false); } } @@ -876,56 +876,56 @@ void Sidebar::show_sliced_info_sizer(const bool show) } else { - const PrintStatistics& ps = p->plater->fff_print().print_statistics(); - const bool is_wipe_tower = ps.total_wipe_tower_filament > 0; + const PrintStatistics& ps = p->plater->fff_print().print_statistics(); + const bool is_wipe_tower = ps.total_wipe_tower_filament > 0; - wxString new_label = _(L("Used Filament (m)")); - if (is_wipe_tower) - new_label += wxString::Format(" :\n - %s\n - %s", _(L("objects")), _(L("wipe tower"))); + wxString new_label = _(L("Used Filament (m)")); + if (is_wipe_tower) + new_label += wxString::Format(" :\n - %s\n - %s", _(L("objects")), _(L("wipe tower"))); - wxString info_text = is_wipe_tower ? - wxString::Format("%.2f \n%.2f \n%.2f", ps.total_used_filament / 1000, - (ps.total_used_filament - ps.total_wipe_tower_filament) / 1000, - ps.total_wipe_tower_filament / 1000) : - wxString::Format("%.2f", ps.total_used_filament / 1000); - p->sliced_info->SetTextAndShow(siFilament_m, info_text, new_label); + wxString info_text = is_wipe_tower ? + wxString::Format("%.2f \n%.2f \n%.2f", ps.total_used_filament / 1000, + (ps.total_used_filament - ps.total_wipe_tower_filament) / 1000, + ps.total_wipe_tower_filament / 1000) : + wxString::Format("%.2f", ps.total_used_filament / 1000); + p->sliced_info->SetTextAndShow(siFilament_m, info_text, new_label); - p->sliced_info->SetTextAndShow(siFilament_mm3, wxString::Format("%.2f", ps.total_extruded_volume)); - p->sliced_info->SetTextAndShow(siFilament_g, wxString::Format("%.2f", ps.total_weight)); + p->sliced_info->SetTextAndShow(siFilament_mm3, wxString::Format("%.2f", ps.total_extruded_volume)); + p->sliced_info->SetTextAndShow(siFilament_g, wxString::Format("%.2f", ps.total_weight)); - new_label = _(L("Cost")); - if (is_wipe_tower) - new_label += wxString::Format(" :\n - %s\n - %s", _(L("objects")), _(L("wipe tower"))); - - info_text = is_wipe_tower ? - wxString::Format("%.2f \n%.2f \n%.2f", ps.total_cost, - (ps.total_cost - ps.total_wipe_tower_cost), - ps.total_wipe_tower_cost) : - wxString::Format("%.2f", ps.total_cost); - p->sliced_info->SetTextAndShow(siCost, info_text, new_label); + new_label = _(L("Cost")); + if (is_wipe_tower) + new_label += wxString::Format(" :\n - %s\n - %s", _(L("objects")), _(L("wipe tower"))); + + info_text = is_wipe_tower ? + wxString::Format("%.2f \n%.2f \n%.2f", ps.total_cost, + (ps.total_cost - ps.total_wipe_tower_cost), + ps.total_wipe_tower_cost) : + wxString::Format("%.2f", ps.total_cost); + p->sliced_info->SetTextAndShow(siCost, info_text, new_label); - if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") - p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A"); - else { - new_label = _(L("Estimated printing time")) +" :"; - info_text = ""; - if (ps.estimated_normal_print_time != "N/A") { - new_label += wxString::Format("\n - %s", _(L("normal mode"))); - info_text += wxString::Format("\n%s", ps.estimated_normal_print_time); + if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A") + p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A"); + else { + new_label = _(L("Estimated printing time")) +" :"; + info_text = ""; + if (ps.estimated_normal_print_time != "N/A") { + new_label += wxString::Format("\n - %s", _(L("normal mode"))); + info_text += wxString::Format("\n%s", ps.estimated_normal_print_time); + } + if (ps.estimated_silent_print_time != "N/A") { + new_label += wxString::Format("\n - %s", _(L("silent mode"))); + info_text += wxString::Format("\n%s", ps.estimated_silent_print_time); + } + p->sliced_info->SetTextAndShow(siEstimatedTime, info_text, new_label); } - if (ps.estimated_silent_print_time != "N/A") { - new_label += wxString::Format("\n - %s", _(L("silent mode"))); - info_text += wxString::Format("\n%s", ps.estimated_silent_print_time); - } - p->sliced_info->SetTextAndShow(siEstimatedTime, info_text, new_label); - } - // if there is a wipe tower, insert number of toolchanges info into the array: - p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, is_wipe_tower ? wxString::Format("%.d", p->plater->fff_print().wipe_tower_data().number_of_toolchanges) : "N/A"); + // if there is a wipe tower, insert number of toolchanges info into the array: + p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, is_wipe_tower ? wxString::Format("%.d", p->plater->fff_print().wipe_tower_data().number_of_toolchanges) : "N/A"); - // Hide non-FFF sliced info parameters - p->sliced_info->SetTextAndShow(siMateril_unit, "N/A"); + // Hide non-FFF sliced info parameters + p->sliced_info->SetTextAndShow(siMateril_unit, "N/A"); } } From 051ca410f675b20e2829fdfc96342571abf04427 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 21 Feb 2019 18:31:01 +0100 Subject: [PATCH 17/18] More input handling fixes --- src/slic3r/GUI/GLCanvas3D.cpp | 17 +++++++++++++---- src/slic3r/GUI/GLCanvas3D.hpp | 1 + src/slic3r/GUI/GUI_Preview.cpp | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ad19b08bd..b194ba138 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4119,6 +4119,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) , m_multisample_allowed(false) , m_regenerate_volumes(true) , m_moving(false) + , m_tab_down(false) , m_color_by("volume") , m_reload_delayed(false) , m_render_sla_auxiliaries(true) @@ -5314,6 +5315,8 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) void GLCanvas3D::on_key(wxKeyEvent& evt) { + const int keyCode = evt.GetKeyCode(); + #if ENABLE_IMGUI auto imgui = wxGetApp().imgui(); if (imgui->update_key_data(evt)) { @@ -5321,9 +5324,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) } else #endif // ENABLE_IMGUI if (evt.GetEventType() == wxEVT_KEY_UP) { - const int keyCode = evt.GetKeyCode(); - - if (keyCode == WXK_TAB) { + if (m_tab_down && keyCode == WXK_TAB && !evt.HasAnyModifiers()) { // Enable switching between 3D and Preview with Tab // m_canvas->HandleAsNavigationKey(evt); // XXX: Doesn't work in some cases / on Linux post_event(SimpleEvent(EVT_GLCANVAS_TAB)); @@ -5331,9 +5332,17 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) // shift has been just released - SLA gizmo might want to close rectangular selection. m_dirty = true; } + } else if (evt.GetEventType() == wxEVT_KEY_DOWN) { + m_tab_down = keyCode == WXK_TAB && !evt.HasAnyModifiers(); } - evt.Skip(); // Needed to have EVT_CHAR generated as well + if (keyCode != WXK_TAB + && keyCode != WXK_LEFT + && keyCode != WXK_UP + && keyCode != WXK_RIGHT + && keyCode != WXK_DOWN) { + evt.Skip(); // Needed to have EVT_CHAR generated as well + } } void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index ff136e190..f3e1bc918 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -946,6 +946,7 @@ private: bool m_multisample_allowed; bool m_regenerate_volumes; bool m_moving; + bool m_tab_down; bool m_render_sla_auxiliaries; std::string m_color_by; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index f730496ce..b311cde51 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -52,7 +52,7 @@ View3D::~View3D() bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process) { - if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)) + if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */)) return false; m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this); From 14b4685ecb5ee6c0c0ad36789b4e2c4cb29a5d64 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 21 Feb 2019 18:59:21 +0100 Subject: [PATCH 18/18] Scaling in PrintHostDialogs, FirmwareDialog, UpdateDialogs --- src/slic3r/GUI/FirmwareDialog.cpp | 23 ++++++++++++++--------- src/slic3r/GUI/GUI_App.cpp | 1 + src/slic3r/GUI/MsgDialog.hpp | 4 ++-- src/slic3r/GUI/PrintHostDialogs.cpp | 9 +++++---- src/slic3r/GUI/UpdateDialogs.cpp | 14 ++++++++------ 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/slic3r/GUI/FirmwareDialog.cpp b/src/slic3r/GUI/FirmwareDialog.cpp index 2df1f0bc9..90e2cbc9c 100644 --- a/src/slic3r/GUI/FirmwareDialog.cpp +++ b/src/slic3r/GUI/FirmwareDialog.cpp @@ -13,6 +13,7 @@ #include "libslic3r/Utils.hpp" #include "avrdude/avrdude-slic3r.hpp" #include "GUI.hpp" +#include "GUI_App.hpp" #include "I18N.hpp" #include "MsgDialog.hpp" #include "../Utils/HexFile.hpp" @@ -36,7 +37,6 @@ #include #include #include -#include "GUI_App.hpp" namespace fs = boost::filesystem; @@ -693,11 +693,16 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) : enum { DIALOG_MARGIN = 15, SPACING = 10, - MIN_WIDTH = 600, - MIN_HEIGHT = 200, - MIN_HEIGHT_EXPANDED = 500, + MIN_WIDTH = 50, + MIN_HEIGHT = 18, + MIN_HEIGHT_EXPANDED = 40, }; + const int em = GUI::wxGetApp().em_unit(); + int min_width = MIN_WIDTH * em; + int min_height = MIN_HEIGHT * em; + int min_height_expanded = MIN_HEIGHT_EXPANDED * em; + wxFont status_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); status_font.MakeBold(); wxFont mono_font(wxFontInfo().Family(wxFONTFAMILY_TELETYPE)); @@ -769,10 +774,10 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) : auto *topsizer = new wxBoxSizer(wxVERTICAL); topsizer->Add(panel, 1, wxEXPAND | wxALL, DIALOG_MARGIN); - SetMinSize(wxSize(MIN_WIDTH, MIN_HEIGHT)); + SetMinSize(wxSize(min_width, min_height)); SetSizerAndFit(topsizer); const auto size = GetSize(); - SetSize(std::max(size.GetWidth(), static_cast(MIN_WIDTH)), std::max(size.GetHeight(), static_cast(MIN_HEIGHT))); + SetSize(std::max(size.GetWidth(), static_cast(min_width)), std::max(size.GetHeight(), static_cast(min_height))); Layout(); SetEscapeId(wxID_CLOSE); // To close the dialog using "Esc" button @@ -786,13 +791,13 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) : } }); - p->spoiler->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, [this](wxCollapsiblePaneEvent &evt) { + p->spoiler->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, [=](wxCollapsiblePaneEvent &evt) { if (evt.GetCollapsed()) { - this->SetMinSize(wxSize(MIN_WIDTH, MIN_HEIGHT)); + this->SetMinSize(wxSize(min_width, min_height)); const auto new_height = this->GetSize().GetHeight() - this->p->txt_stdout->GetSize().GetHeight(); this->SetSize(this->GetSize().GetWidth(), new_height); } else { - this->SetMinSize(wxSize(MIN_WIDTH, MIN_HEIGHT_EXPANDED)); + this->SetMinSize(wxSize(min_width, min_height_expanded)); } this->Layout(); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 0e1f73a1a..1847b2898 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -78,6 +78,7 @@ IMPLEMENT_APP(GUI_App) GUI_App::GUI_App() : wxApp() + , m_em_unit(10) #if ENABLE_IMGUI , m_imgui(new ImGuiWrapper()) #endif // ENABLE_IMGUI diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp index a5af6afe2..09bb89e4f 100644 --- a/src/slic3r/GUI/MsgDialog.hpp +++ b/src/slic3r/GUI/MsgDialog.hpp @@ -32,8 +32,8 @@ struct MsgDialog : wxDialog protected: enum { - CONTENT_WIDTH = 50,//500, - CONTENT_MAX_HEIGHT = 60,//600, + CONTENT_WIDTH = 50, + CONTENT_MAX_HEIGHT = 60, BORDER = 30, VERT_SPACING = 15, HORIZ_SPACING = 5, diff --git a/src/slic3r/GUI/PrintHostDialogs.cpp b/src/slic3r/GUI/PrintHostDialogs.cpp index 6dfa11889..0d70027c0 100644 --- a/src/slic3r/GUI/PrintHostDialogs.cpp +++ b/src/slic3r/GUI/PrintHostDialogs.cpp @@ -38,7 +38,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path) #endif auto *label_dir_hint = new wxStaticText(this, wxID_ANY, _(L("Use forward slashes ( / ) as a directory separator if needed."))); - label_dir_hint->Wrap(CONTENT_WIDTH); + label_dir_hint->Wrap(CONTENT_WIDTH * wxGetApp().em_unit()); content_sizer->Add(txt_filename, 0, wxEXPAND); content_sizer->Add(label_dir_hint); @@ -135,10 +135,11 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent) , on_error_evt(this, EVT_PRINTHOST_ERROR, &PrintHostQueueDialog::on_error, this) , on_cancel_evt(this, EVT_PRINTHOST_CANCEL, &PrintHostQueueDialog::on_cancel, this) { - enum { HEIGHT = 800, WIDTH = 400, SPACING = 5 }; + enum { HEIGHT = 60, WIDTH = 30, SPACING = 5 }; - SetSize(wxSize(HEIGHT, WIDTH)); - SetSize(GetMinSize()); + const auto em = GetTextExtent("m").x; + + SetSize(wxSize(HEIGHT * em, WIDTH * em)); auto *topsizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/slic3r/GUI/UpdateDialogs.cpp b/src/slic3r/GUI/UpdateDialogs.cpp index 346a9e231..c4b78eb1a 100644 --- a/src/slic3r/GUI/UpdateDialogs.cpp +++ b/src/slic3r/GUI/UpdateDialogs.cpp @@ -12,6 +12,7 @@ #include "libslic3r/libslic3r.h" #include "libslic3r/Utils.hpp" #include "GUI.hpp" +#include "GUI_App.hpp" #include "I18N.hpp" #include "ConfigWizard.hpp" @@ -34,7 +35,8 @@ MsgUpdateSlic3r::MsgUpdateSlic3r(const Semver &ver_current, const Semver &ver_on auto *text = new wxStaticText(this, wxID_ANY, _(L("To download, follow the link below."))); const auto link_width = link->GetSize().GetWidth(); - text->Wrap(CONTENT_WIDTH > link_width ? CONTENT_WIDTH : link_width); + const int content_width = CONTENT_WIDTH * wxGetApp().em_unit(); + text->Wrap(content_width > link_width ? content_width : link_width); content_sizer->Add(text); content_sizer->AddSpacer(VERT_SPACING); @@ -75,7 +77,7 @@ MsgUpdateConfig::MsgUpdateConfig(const std::unordered_mapWrap(CONTENT_WIDTH); + text->Wrap(CONTENT_WIDTH * wxGetApp().em_unit()); content_sizer->Add(text); content_sizer->AddSpacer(VERT_SPACING); @@ -115,16 +117,16 @@ MsgDataIncompatible::MsgDataIncompatible(const std::unordered_mapWrap(CONTENT_WIDTH); + text->Wrap(CONTENT_WIDTH * wxGetApp().em_unit()); content_sizer->Add(text); auto *text2 = new wxStaticText(this, wxID_ANY, wxString::Format(_(L("This Slic3r PE version: %s")), SLIC3R_VERSION)); - text2->Wrap(CONTENT_WIDTH); + text2->Wrap(CONTENT_WIDTH * wxGetApp().em_unit()); content_sizer->Add(text2); content_sizer->AddSpacer(VERT_SPACING); auto *text3 = new wxStaticText(this, wxID_ANY, _(L("Incompatible bundles:"))); - text3->Wrap(CONTENT_WIDTH); + text3->Wrap(CONTENT_WIDTH * wxGetApp().em_unit()); content_sizer->Add(text3); content_sizer->AddSpacer(VERT_SPACING); @@ -175,7 +177,7 @@ MsgDataLegacy::MsgDataLegacy() : )), ConfigWizard::name() )); - text->Wrap(CONTENT_WIDTH); + text->Wrap(CONTENT_WIDTH * wxGetApp().em_unit()); content_sizer->Add(text); content_sizer->AddSpacer(VERT_SPACING);