From 34b354810208fe39d8a8a0e244b5a77d81f35578 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Fri, 12 Apr 2019 16:18:46 +0200 Subject: [PATCH] Filaments and materials selection/installation --- resources/profiles/PrusaResearch.ini | 95 +++++++ src/libslic3r/PrintConfig.cpp | 8 + src/slic3r/GUI/AppConfig.hpp | 6 + src/slic3r/GUI/ConfigWizard.cpp | 362 ++++++++++++++++++++++-- src/slic3r/GUI/ConfigWizard_private.hpp | 139 +++++++-- src/slic3r/GUI/Preset.cpp | 43 ++- src/slic3r/GUI/Preset.hpp | 5 + src/slic3r/GUI/PresetBundle.cpp | 8 + 8 files changed, 608 insertions(+), 58 deletions(-) diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index 406fd93c8..690471334 100644 --- a/resources/profiles/PrusaResearch.ini +++ b/resources/profiles/PrusaResearch.ini @@ -82,6 +82,29 @@ variants = default technology = SLA family = SL1 +[default_filaments] +Generic PLA = 1 +Generic PLA MMU2 = 1 +Prusa PLA = 1 +Prusa PLA MMU2 = 1 +Prusament PLA = 1 +Prusament PLA MMU2 = 1 + +[default_sla_materials] +Prusa Azure Blue Tough 0.05 = 1 +Prusa Black Tough 0.05 = 1 +Prusa Green Casting 0.05 = 1 +Prusa Grey Tough 0.05 = 1 +Prusa Maroon Tough 0.05 = 1 +Prusa Orange Tough 0.025 = 1 +Prusa Orange Tough 0.035 = 1 +Prusa Orange Tough 0.05 = 1 +Prusa Orange Tough 0.1 = 1 +Prusa Pink Tough 0.05 = 1 +Prusa Skin Tough 0.05 = 1 +Prusa Transparent Red Tough 0.05 = 1 +Prusa White Tough 0.05 = 1 + # All presets starting with asterisk, for example *common*, are intermediate and they will # not make it into the user interface. @@ -1128,6 +1151,7 @@ filament_density = 3.9 filament_colour = #804040 filament_max_volumetric_speed = 9 filament_notes = "List of materials tested with standard print settings:\n\nColorFabb bronzeFill\nColorFabb brassFill\nColorFabb steelFill\nColorFabb copperFill" +filament_vendor = ColorFabb [filament:ColorFabb HT] inherits = *PET* @@ -1145,11 +1169,13 @@ max_fan_speed = 20 min_fan_speed = 10 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 270 +filament_vendor = ColorFabb [filament:ColorFabb PLA-PHA] inherits = *PLA* filament_cost = 55.5 filament_density = 1.24 +filament_vendor = ColorFabb [filament:ColorFabb woodFill] inherits = *PLA* @@ -1163,6 +1189,7 @@ filament_max_volumetric_speed = 10 first_layer_temperature = 200 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 200 +filament_vendor = ColorFabb [filament:ColorFabb corkFill] inherits = *PLA* @@ -1175,6 +1202,7 @@ filament_max_volumetric_speed = 6 first_layer_temperature = 220 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 +filament_vendor = ColorFabb [filament:ColorFabb XT] inherits = *PET* @@ -1184,6 +1212,7 @@ filament_density = 1.27 first_layer_bed_temperature = 90 first_layer_temperature = 260 temperature = 270 +filament_vendor = ColorFabb [filament:ColorFabb XT-CF20] inherits = *PET* @@ -1199,6 +1228,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{el temperature = 260 filament_retract_length = nil filament_retract_lift = 0.2 +filament_vendor = ColorFabb [filament:ColorFabb nGen] inherits = *PET* @@ -1211,6 +1241,7 @@ filament_type = NGEN first_layer_temperature = 240 max_fan_speed = 35 min_fan_speed = 20 +filament_vendor = ColorFabb [filament:ColorFabb nGen flex] inherits = *FLEX* @@ -1231,12 +1262,14 @@ temperature = 260 filament_retract_length = nil filament_retract_lift = 0 compatible_printers_condition = nozzle_diameter[0]>0.35 and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material) +filament_vendor = ColorFabb [filament:E3D Edge] inherits = *PET* filament_cost = 56.9 filament_density = 1.26 filament_type = EDGE +filament_vendor = E3D [filament:E3D PC-ABS] inherits = *ABS* @@ -1245,6 +1278,7 @@ filament_type = PC filament_density = 1.05 first_layer_temperature = 270 temperature = 270 +filament_vendor = E3D [filament:Fillamentum ABS] inherits = *ABS* @@ -1252,6 +1286,7 @@ filament_cost = 32.4 filament_density = 1.04 first_layer_temperature = 240 temperature = 240 +filament_vendor = Fillamentum [filament:Fillamentum ASA] inherits = *ABS* @@ -1266,6 +1301,7 @@ slowdown_below_layer_time = 15 first_layer_temperature = 265 temperature = 265 filament_type = ASA +filament_vendor = Fillamentum [filament:Prusament ASA] inherits = *ABS* @@ -1296,6 +1332,7 @@ first_layer_temperature = 275 max_fan_speed = 50 min_fan_speed = 50 temperature = 275 +filament_vendor = Fillamentum [filament:Fillamentum Timberfill] inherits = *PLA* @@ -1309,24 +1346,28 @@ filament_max_volumetric_speed = 10 first_layer_temperature = 190 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 190 +filament_vendor = Fillamentum [filament:Generic ABS] inherits = *ABS* filament_cost = 27.82 filament_density = 1.04 filament_notes = "List of materials tested with standard ABS print settings:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladec ABS" +filament_vendor = Generic [filament:Generic PET] inherits = *PET* filament_cost = 27.82 filament_density = 1.27 filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladec PETG" +filament_vendor = Generic [filament:Generic PLA] inherits = *PLA* filament_cost = 25.4 filament_density = 1.24 filament_notes = "List of materials tested with standard PLA print settings:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladec PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH" +filament_vendor = Generic [filament:Generic FLEX] inherits = *FLEX* @@ -1347,6 +1388,7 @@ filament_colour = #3A80CA first_layer_bed_temperature = 100 first_layer_temperature = 270 temperature = 270 +filament_vendor = Polymaker [filament:PrimaSelect PVA+] inherits = *PLA* @@ -1363,12 +1405,14 @@ filament_type = PVA first_layer_temperature = 195 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 195 +filament_vendor = PrimaSelect [filament:Prusa ABS] inherits = *ABS* filament_cost = 27.82 filament_density = 1.08 filament_notes = "List of materials tested with standard ABS print settings:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladec ABS" +filament_vendor = Prusa [filament:*ABS MMU2*] inherits = Prusa ABS @@ -1385,6 +1429,7 @@ filament_unloading_speed = 20 [filament:Generic ABS MMU2] inherits = *ABS MMU2* +filament_vendor = Generic [filament:Prusament ASA MMU2] inherits = *ABS MMU2* @@ -1410,6 +1455,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{el [filament:Prusa ABS MMU2] inherits = *ABS MMU2* +filament_vendor = Prusa [filament:Prusa HIPS] inherits = *ABS* @@ -1428,6 +1474,7 @@ max_fan_speed = 20 min_fan_speed = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 +filament_vendor = Prusa [filament:Prusa PET] inherits = *PET* @@ -1435,6 +1482,7 @@ filament_cost = 27.82 filament_density = 1.27 filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nPlasty Mladec PETG" compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +filament_vendor = Prusa [filament:Prusament PETG] inherits = *PET* @@ -1444,12 +1492,14 @@ filament_cost = 24.99 filament_density = 1.27 filament_type = PETG compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +filament_vendor = Prusa [filament:Prusa PET 0.6 nozzle] inherits = *PET06* filament_cost = 27.82 filament_density = 1.27 filament_notes = "List of manufacturers tested with standard PET print settings:\n\nE3D Edge\nPlasty Mladec PETG" +filament_vendor = Prusa [filament:Prusament PETG 0.6 nozzle] inherits = *PET06* @@ -1458,6 +1508,7 @@ temperature = 250 filament_cost = 24.99 filament_density = 1.27 filament_type = PETG +filament_vendor = Prusa [filament:*PET MMU2*] inherits = Prusa PET @@ -1485,9 +1536,11 @@ filament_max_volumetric_speed = 13 [filament:Generic PET MMU2] inherits = *PET MMU2* +filament_vendor = Generic [filament:Prusa PET MMU2] inherits = *PET MMU2* +filament_vendor = Prusa [filament:Prusament PETG MMU2] inherits = *PET MMU2* @@ -1498,16 +1551,19 @@ inherits = *PET MMU2 06* [filament:Prusa PET MMU2 0.6 nozzle] inherits = *PET MMU2 06* +filament_vendor = Prusa [filament:Prusament PETG MMU2 0.6 nozzle] inherits = *PET MMU2 06* filament_type = PETG +filament_vendor = Prusa [filament:Prusa PLA] inherits = *PLA* filament_cost = 25.4 filament_density = 1.24 filament_notes = "List of materials tested with standard PLA print settings:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFiberlogy PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladec PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nAmazonBasics PLA" +filament_vendor = Prusa [filament:Prusament PLA] inherits = *PLA* @@ -1515,6 +1571,7 @@ temperature = 215 filament_cost = 24.99 filament_density = 1.24 filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa" +filament_vendor = Prusa [filament:*PLA MMU2*] inherits = Prusa PLA @@ -1534,18 +1591,22 @@ filament_unloading_speed_start = 100 [filament:Generic PLA MMU2] inherits = *PLA MMU2* +filament_vendor = Generic [filament:Prusa PLA MMU2] inherits = *PLA MMU2* +filament_vendor = Prusa [filament:Prusament PLA MMU2] inherits = *PLA MMU2* +filament_vendor = Prusa [filament:SemiFlex or Flexfill 98A] inherits = *FLEX* filament_cost = 82 filament_density = 1.22 filament_max_volumetric_speed = 1.35 +filament_vendor = Flexfill [filament:Taulman Bridge] inherits = *common* @@ -1567,6 +1628,7 @@ max_fan_speed = 5 min_fan_speed = 0 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 250 +filament_vendor = Taulman [filament:Taulman T-Glase] inherits = *PET* @@ -1580,6 +1642,7 @@ first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" +filament_vendor = Taulman [filament:Verbatim BVOH] inherits = *common* @@ -1603,6 +1666,7 @@ max_fan_speed = 100 min_fan_speed = 100 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 210 +filament_vendor = Verbatim [filament:Verbatim BVOH MMU2] inherits = Verbatim BVOH @@ -1622,6 +1686,7 @@ filament_unload_time = 12 filament_unloading_speed = 20 filament_unloading_speed_start = 100 filament_loading_speed_start = 19 +filament_vendor = Verbatim [filament:PrimaSelect PVA+ MMU2] inherits = *common* @@ -1660,6 +1725,7 @@ min_print_speed = 15 slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 195 +filament_vendor = PrimaSelect [filament:Verbatim PP] inherits = *common* @@ -1682,6 +1748,7 @@ max_fan_speed = 100 min_fan_speed = 100 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 +filament_vendor = Verbatim ## Filaments MMU1 @@ -1902,6 +1969,7 @@ initial_exposure_time = 40 inherits = *common 0.025* exposure_time = 6 initial_exposure_time = 45 +material_vendor = Bluecast [sla_material:BlueCast X10 0.025] inherits = *common 0.025* @@ -1912,6 +1980,7 @@ initial_exposure_time = 100 inherits = *common 0.025* exposure_time = 6 initial_exposure_time = 35 +material_vendor = Prusa [sla_material:Prusa Grey Tough 0.025] inherits = *common 0.025* @@ -1964,31 +2033,37 @@ initial_exposure_time = 35 inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 35 +material_vendor = Bluecast [sla_material:BlueCast Keramaster 0.05] inherits = *common 0.05* exposure_time = 8 initial_exposure_time = 45 +material_vendor = Bluecast [sla_material:BlueCast Keramaster Dental 0.05] inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 50 +material_vendor = Bluecast [sla_material:BlueCast LCD-DLP Original 0.05] inherits = *common 0.05* exposure_time = 10 initial_exposure_time = 60 +material_vendor = Bluecast [sla_material:BlueCast Phrozen Wax 0.05] inherits = *common 0.05* exposure_time = 16 initial_exposure_time = 50 +material_vendor = Bluecast [sla_material:BlueCast S+ 0.05] inherits = *common 0.05* exposure_time = 9 initial_exposure_time = 45 +material_vendor = Bluecast [sla_material:BlueCast X10 0.05] inherits = *common 0.05* @@ -1999,26 +2074,31 @@ initial_exposure_time = 100 inherits = *common 0.05* exposure_time = 6 initial_exposure_time = 40 +material_vendor = Monocure [sla_material:Monocure 3D Blue Rapid Resin 0.05] inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 40 +material_vendor = Monocure [sla_material:Monocure 3D Clear Rapid Resin 0.05] inherits = *common 0.05* exposure_time = 8 initial_exposure_time = 40 +material_vendor = Monocure [sla_material:Monocure 3D Grey Rapid Resin 0.05] inherits = *common 0.05* exposure_time = 10 initial_exposure_time = 30 +material_vendor = Monocure [sla_material:Monocure 3D White Rapid Resin 0.05] inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 40 +material_vendor = Monocure [sla_material:3DM-HTR140 (high temperature) 0.05] inherits = *common 0.05* @@ -2034,36 +2114,43 @@ initial_exposure_time = 25 inherits = *common 0.05* exposure_time = 20 initial_exposure_time = 40 +material_vendor = 3DM [sla_material:3DM-DENT 0.05] inherits = *common 0.05* exposure_time = 7 initial_exposure_time = 45 +material_vendor = 3DM [sla_material:3DM-HR Green 0.05] inherits = *common 0.05* exposure_time = 15 initial_exposure_time = 40 +material_vendor = 3DM [sla_material:3DM-HR Red Wine 0.05] inherits = *common 0.05* exposure_time = 9 initial_exposure_time = 35 +material_vendor = 3DM [sla_material:3DM-XPRO White 0.05] inherits = *common 0.05* exposure_time = 9 initial_exposure_time = 35 +material_vendor = 3DM [sla_material:FTD Ash Grey 0.05] inherits = *common 0.05* exposure_time = 9 initial_exposure_time = 40 +material_vendor = FTD [sla_material:Harz Labs Model Resin Cherry 0.05] inherits = *common 0.05* exposure_time = 8 initial_exposure_time = 45 +material_vendor = Harz Labs [sla_material:Photocentric Hard Grey 0.05] inherits = *common 0.05* @@ -2116,6 +2203,7 @@ initial_exposure_time = 35 inherits = *common 0.05* exposure_time = 13 initial_exposure_time = 40 +material_vendor = Prusa ## [sla_material:Prusa Yellow Solid 0.05] ## inherits = *common 0.05* @@ -2126,6 +2214,7 @@ initial_exposure_time = 40 inherits = *common 0.05* exposure_time = 7.5 initial_exposure_time = 35 +material_vendor = Prusa ## [sla_material:Prusa Transparent Green Tough 0.05] ## inherits = *common 0.05* @@ -2136,21 +2225,25 @@ initial_exposure_time = 35 inherits = *common 0.05* exposure_time = 6 initial_exposure_time = 35 +material_vendor = Prusa [sla_material:Prusa Maroon Tough 0.05] inherits = *common 0.05* exposure_time = 7.5 initial_exposure_time = 35 +material_vendor = Prusa [sla_material:Prusa Pink Tough 0.05] inherits = *common 0.05* exposure_time = 8 initial_exposure_time = 35 +material_vendor = Prusa [sla_material:Prusa Azure Blue Tough 0.05] inherits = *common 0.05* exposure_time = 8 initial_exposure_time = 35 +material_vendor = Prusa [sla_material:Prusa Transparent Tough 0.05] inherits = *common 0.05* @@ -2193,6 +2286,7 @@ initial_exposure_time = 15 inherits = *common 0.035* exposure_time = 6 initial_exposure_time = 35 +material_vendor = Prusa ########### Materials 0.1 @@ -2235,6 +2329,7 @@ initial_exposure_time = 55 inherits = *common 0.1* exposure_time = 8 initial_exposure_time = 35 +material_vendor = Prusa [sla_material:Prusa Green Casting 0.1] inherits = *common 0.1* diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 1ce00f269..ac30941cb 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -749,6 +749,10 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionStrings { "" }); def->cli = ConfigOptionDef::nocli; + def = this->add("filament_vendor", coString); + def->set_default_value(new ConfigOptionString(L("(Unknown)"))); + def->cli = ConfigOptionDef::nocli; + def = this->add("fill_angle", coFloat); def->label = L("Fill angle"); def->category = L("Infill"); @@ -2474,6 +2478,10 @@ void PrintConfigDef::init_sla_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("")); + def = this->add("material_vendor", coString); + def->set_default_value(new ConfigOptionString(L("(Unknown)"))); + def->cli = ConfigOptionDef::nocli; + def = this->add("default_sla_material_profile", coString); def->label = L("Default SLA material profile"); def->tooltip = L("Default print profile associated with the current printer profile. " diff --git a/src/slic3r/GUI/AppConfig.hpp b/src/slic3r/GUI/AppConfig.hpp index 8ad17b9db..fe30c0af6 100644 --- a/src/slic3r/GUI/AppConfig.hpp +++ b/src/slic3r/GUI/AppConfig.hpp @@ -80,6 +80,12 @@ public: } } + bool has_section(const std::string §ion) const + { return m_storage.find(section) != m_storage.end(); } + const std::map& get_section(const std::string §ion) const + { return m_storage.find(section)->second; } + void set_section(const std::string §ion, const std::map& data) + { m_storage[section] = data; } void clear_section(const std::string §ion) { m_storage[section].clear(); } diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 0115ff5f9..0d35ce1af 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -1,3 +1,5 @@ +// FIXME: extract absolute units -> em + #include "ConfigWizard_private.hpp" #include @@ -19,6 +21,7 @@ #include #include #include +#include #include #include "libslic3r/Utils.hpp" @@ -62,7 +65,7 @@ struct PrinterPickerEvent : public wxEvent wxDEFINE_EVENT(EVT_PRINTER_PICK, PrinterPickerEvent); -PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors, const ModelFilter &filter) +PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig, const ModelFilter &filter) : wxPanel(parent) , vendor_id(vendor.id) , width(0) @@ -132,7 +135,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt auto *cbox = new Checkbox(variants_panel, label, model_id, variant.name); i == 0 ? cboxes.push_back(cbox) : cboxes_alt.push_back(cbox); - bool enabled = appconfig_vendors.get_variant("PrusaResearch", model_id, variant.name); + bool enabled = appconfig.get_variant("PrusaResearch", model_id, variant.name); cbox->SetValue(enabled); variants_sizer->Add(cbox, 0, wxBOTTOM, 3); @@ -210,8 +213,8 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt SetSizer(sizer); } -PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors) - : PrinterPicker(parent, vendor, std::move(title), max_cols, appconfig_vendors, [](const VendorProfile::PrinterModel&) { return true; }) +PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig) + : PrinterPicker(parent, vendor, std::move(title), max_cols, appconfig, [](const VendorProfile::PrinterModel&) { return true; }) {} void PrinterPicker::select_all(bool select, bool alternates) @@ -241,6 +244,19 @@ void PrinterPicker::select_one(size_t i, bool select) } } +bool PrinterPicker::any_selected() const +{ + for (const auto &cb : cboxes) { + if (cb->GetValue()) { return true; } + } + + for (const auto &cb : cboxes_alt) { + if (cb->GetValue()) { return true; } + } + + return false; +} + void PrinterPicker::on_checkbox(const Checkbox *cbox, bool checked) { PrinterPickerEvent evt(EVT_PRINTER_PICK, GetId(), vendor_id, cbox->model, cbox->variant, checked); @@ -289,6 +305,7 @@ void ConfigWizardPage::append_text(wxString text) void ConfigWizardPage::append_spacer(int space) { + // FIXME: scaling content->AddSpacer(space); } @@ -330,7 +347,7 @@ PagePrinters::PagePrinters(ConfigWizard *parent, wxString title, wxString shortn bool check_first_variant = technology == T_FFF && wizard_p()->check_first_variant(); - AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors; + AppConfig &appconfig = this->wizard_p()->appconfig_new; const auto families = vendor.families(); for (const auto &family : families) { @@ -345,7 +362,7 @@ PagePrinters::PagePrinters(ConfigWizard *parent, wxString title, wxString shortn } const auto picker_title = family.empty() ? wxString() : wxString::Format(_(L("%s Family")), family); - auto *picker = new PrinterPicker(this, vendor, picker_title, MAX_COLS, appconfig_vendors, filter); + auto *picker = new PrinterPicker(this, vendor, picker_title, MAX_COLS, appconfig, filter); if (check_first_variant) { // Select the default (first) model/variant on the Prusa vendor @@ -353,8 +370,9 @@ PagePrinters::PagePrinters(ConfigWizard *parent, wxString title, wxString shortn check_first_variant = false; } - picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) { - appconfig_vendors.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable); + picker->Bind(EVT_PRINTER_PICK, [this, &appconfig](const PrinterPickerEvent &evt) { + appconfig.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable); + wizard_p()->on_printer_pick(this); }); append(new wxStaticLine(this)); @@ -377,6 +395,159 @@ int PagePrinters::get_width() const [](int acc, const PrinterPicker *picker) { return std::max(acc, picker->get_width()); }); } +bool PagePrinters::any_selected() const +{ + for (const auto *picker : printer_pickers) { + if (picker->any_selected()) { return true; } + } + + return false; +} + + +const std::string PageMaterials::EMPTY; + +PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxString title, wxString shortname, wxString list1name) + : ConfigWizardPage(parent, std::move(title), std::move(shortname)) + , materials(materials) + , list_l1(new StringList(this)) + , list_l2(new StringList(this)) + , list_l3(new PresetList(this)) + , sel1_prev(wxNOT_FOUND) + , sel2_prev(wxNOT_FOUND) +{ + append_spacer(VERTICAL_SPACING); + + const int em = parent->em_unit(); + const int list_h = 30*em; + + list_l1->SetMinSize(wxSize(8*em, list_h)); + list_l2->SetMinSize(wxSize(13*em, list_h)); + list_l3->SetMinSize(wxSize(25*em, list_h)); + + auto *grid = new wxFlexGridSizer(3, 0, em); + + grid->Add(new wxStaticText(this, wxID_ANY, list1name)); + grid->Add(new wxStaticText(this, wxID_ANY, _(L("Vendor:")))); + grid->Add(new wxStaticText(this, wxID_ANY, _(L("Profile:")))); + + grid->Add(list_l1); + grid->Add(list_l2); + grid->Add(list_l3); + + auto *btn_sizer = new wxBoxSizer(wxHORIZONTAL); + auto *sel_all = new wxButton(this, wxID_ANY, _(L("All"))); + auto *sel_none = new wxButton(this, wxID_ANY, _(L("None"))); + btn_sizer->Add(sel_all, 0, wxRIGHT, em / 2); + btn_sizer->Add(sel_none); + + grid->Add(new wxBoxSizer(wxHORIZONTAL)); + grid->Add(new wxBoxSizer(wxHORIZONTAL)); + grid->Add(btn_sizer, 0, wxALIGN_RIGHT); + + append(grid); + + list_l1->append(_(L("(All)")), &EMPTY); + + for (const std::string &type : materials->types) { + list_l1->append(type, &type); + } + + list_l1->Bind(wxEVT_LISTBOX, [this](wxCommandEvent &) { + update_lists(list_l1->GetSelection(), list_l2->GetSelection()); + }); + list_l2->Bind(wxEVT_LISTBOX, [this](wxCommandEvent &) { + update_lists(list_l1->GetSelection(), list_l2->GetSelection()); + }); + + list_l3->Bind(wxEVT_CHECKLISTBOX, [this](wxCommandEvent &evt) { select_material(evt.GetInt()); }); + + sel_all->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { select_all(true); }); + sel_none->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { select_all(false); }); + + if (list_l1->GetCount() > 0) { + list_l1->SetSelection(0); + update_lists(0, 0); + } +} + +void PageMaterials::update_lists(int sel1, int sel2) +{ + wxWindowUpdateLocker freeze_guard(this); + (void)freeze_guard; + + if (sel1 != sel1_prev) { + // Refresh the second list + + // XXX: The vendor list is created with quadratic complexity here, + // but the number of vendors is realistically so small this shouldn't be a problem. + + list_l2->Clear(); + list_l2->append(_(L("(All)")), &EMPTY); + if (sel1 != wxNOT_FOUND) { + const std::string &type = list_l1->get_data(sel1); + + materials->filter_presets(type, EMPTY, [this](Preset &p) { + const std::string &vendor = this->materials->get_vendor(p); + + if (list_l2->find(vendor) == wxNOT_FOUND) { + list_l2->append(vendor, &vendor); + } + }); + } + + sel1_prev = sel1; + sel2 = 0; + sel2_prev = wxNOT_FOUND; + list_l2->SetSelection(sel2); + list_l3->Clear(); + } + + if (sel2 != sel2_prev) { + // Refresh the third list + + list_l3->Clear(); + if (sel1 != wxNOT_FOUND && sel2 != wxNOT_FOUND) { + const std::string &type = list_l1->get_data(sel1); + const std::string &vendor = list_l2->get_data(sel2); + + materials->filter_presets(type, vendor, [this](Preset &p) { + const int i = list_l3->append(p.name, &p); + const bool checked = wizard_p()->appconfig_new.has(materials->appconfig_section(), p.name); + list_l3->Check(i, checked); + }); + } + + sel2_prev = sel2; + } +} + +void PageMaterials::select_material(int i) +{ + const bool checked = list_l3->IsChecked(i); + const Preset &preset = list_l3->get_data(i); + + if (checked) { + wizard_p()->appconfig_new.set(materials->appconfig_section(), preset.name, "1"); + } else { + wizard_p()->appconfig_new.erase(materials->appconfig_section(), preset.name); + } +} + +void PageMaterials::select_all(bool select) +{ + wxWindowUpdateLocker freeze_guard(this); + (void)freeze_guard; + + for (int i = 0; i < list_l3->GetCount(); i++) { + const bool current = list_l3->IsChecked(i); + if (current != select) { + list_l3->Check(i, select); + select_material(i); + } + } +} + const char *PageCustom::default_profile_name = "My Settings"; @@ -400,7 +571,7 @@ PageCustom::PageCustom(ConfigWizard *parent) cb_custom->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { tc_profile_name->Enable(custom_wanted()); - wizard_p()->on_custom_setup(custom_wanted()); + wizard_p()->on_custom_setup(); }); append(cb_custom); @@ -453,20 +624,20 @@ PageVendors::PageVendors(ConfigWizard *parent) auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); boldfont.SetWeight(wxFONTWEIGHT_BOLD); - AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors; + AppConfig &appconfig = this->wizard_p()->appconfig_new; wxArrayString choices_vendors; for (const auto vendor_pair : wizard_p()->vendors) { const auto &vendor = vendor_pair.second; if (vendor.id == "PrusaResearch") { continue; } - auto *picker = new PrinterPicker(this, vendor, "", MAX_COLS, appconfig_vendors); + auto *picker = new PrinterPicker(this, vendor, "", MAX_COLS, appconfig); picker->Hide(); pickers.push_back(picker); choices_vendors.Add(vendor.name); - picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) { - appconfig_vendors.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable); + picker->Bind(EVT_PRINTER_PICK, [this, &appconfig](const PrinterPickerEvent &evt) { + appconfig.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable); }); } @@ -875,6 +1046,68 @@ void ConfigWizardIndex::msw_rescale() } +// Materials + +const std::string Materials::UNKNOWN = "(Unknown)"; +const std::string Materials::SECTION_FILAMENTS = "filaments"; +const std::string Materials::SECTION_MATERIALS = "sla_materials"; + +const std::string& Materials::appconfig_section() const +{ + return (technology & T_FFF) ? SECTION_FILAMENTS : SECTION_MATERIALS; +} + +const std::string& Materials::get_type(Preset &preset) const +{ + return (technology & T_FFF) ? get_filament_type(preset) : get_material_type(preset); +} + +const std::string& Materials::get_vendor(Preset &preset) const +{ + return (technology & T_FFF) ? get_filament_vendor(preset) : get_material_vendor(preset); +} + +const std::string& Materials::get_filament_type(const Preset &preset) +{ + const auto *opt = preset.config.opt("filament_type"); + if (opt != nullptr && opt->values.size() > 0) { + return opt->values[0]; + } else { + return UNKNOWN; + } +} + +const std::string& Materials::get_filament_vendor(const Preset &preset) +{ + const auto *opt = preset.config.opt("filament_vendor"); + return opt != nullptr ? opt->value : UNKNOWN; +} + +const std::string& Materials::get_material_type(Preset &preset) +{ + // XXX: The initial_layer_height is of a float type and contains no string to reference, + // and so here he serialize it into an ad-hoc option initial_layer_height_str, which is then referenced + + const auto *opt_str = preset.config.opt("initial_layer_height_str"); + if (opt_str == nullptr) { + const auto *opt = preset.config.opt("initial_layer_height"); + if (opt == nullptr) { return UNKNOWN; } + + auto *new_opt_str = new ConfigOptionString(opt->serialize()); + preset.config.set_key_value("initial_layer_height_str", new_opt_str); + return new_opt_str->value; + } else { + return opt_str->value; + } +} + +const std::string& Materials::get_material_vendor(const Preset &preset) +{ + const auto *opt = preset.config.opt("material_vendor"); + return opt != nullptr ? opt->value : UNKNOWN; +} + + // priv static const std::unordered_map> legacy_preset_map {{ @@ -888,7 +1121,7 @@ static const std::unordered_map { "Original Prusa i3 MK3.ini", std::make_pair("MK3", "0.4") }, }}; -void ConfigWizard::priv::load_pages(bool custom_setup) +void ConfigWizard::priv::load_pages() { const auto former_active = index->active_item(); @@ -897,9 +1130,15 @@ void ConfigWizard::priv::load_pages(bool custom_setup) index->add_page(page_welcome); index->add_page(page_fff); index->add_page(page_msla); + + index->add_page(page_filaments); + if (any_sla_selected) { + index->add_page(page_sla_materials); + } + index->add_page(page_custom); - if (custom_setup) { + if (page_custom->custom_wanted()) { index->add_page(page_firmware); index->add_page(page_bed); index->add_page(page_diams); @@ -946,10 +1185,15 @@ void ConfigWizard::priv::load_vendors() const auto vendor_dir = fs::path(Slic3r::data_dir()) / "vendor"; const auto rsrc_vendor_dir = fs::path(resources_dir()) / "profiles"; + PresetBundle bundle; + // Load vendors from the "vendors" directory in datadir - for (auto &dir_entry : boost::filesystem::directory_iterator(vendor_dir)) + // XXX: The VendorProfile is loaded twice here, ditto below + for (auto &dir_entry : boost::filesystem::directory_iterator(vendor_dir)) { if (Slic3r::is_ini_file(dir_entry)) { try { + bundle.load_configbundle(dir_entry.path().string(), PresetBundle::LOAD_CFGBNDLE_SYSTEM); + auto vp = VendorProfile::from_ini(dir_entry.path()); vendors[vp.id] = std::move(vp); } @@ -957,13 +1201,17 @@ void ConfigWizard::priv::load_vendors() BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % dir_entry.path() % e.what(); } } + } // Additionally load up vendors from the application resources directory, but only those not seen in the datadir - for (auto &dir_entry : boost::filesystem::directory_iterator(rsrc_vendor_dir)) + for (auto &dir_entry : boost::filesystem::directory_iterator(rsrc_vendor_dir)) { if (Slic3r::is_ini_file(dir_entry)) { const auto id = dir_entry.path().stem().string(); + if (vendors.find(id) == vendors.end()) { try { + bundle.load_configbundle(dir_entry.path().string(), PresetBundle::LOAD_CFGBNDLE_SYSTEM); + auto vp = VendorProfile::from_ini(dir_entry.path()); vendors_rsrc[vp.id] = dir_entry.path().filename().string(); vendors[vp.id] = std::move(vp); @@ -973,11 +1221,24 @@ void ConfigWizard::priv::load_vendors() } } } + } + + // Move materials to our Materials container: + for (auto &&f : bundle.filaments) { + f.vendor = nullptr; + filaments.presets.push_back(std::move(f)); + filaments.types.insert(Materials::get_filament_type(f)); + } + for (auto &&m : bundle.sla_materials) { + m.vendor = nullptr; + sla_materials.presets.push_back(std::move(m)); + sla_materials.types.insert(Materials::get_material_type(m)); + } // Load up the set of vendors / models / variants the user has had enabled up till now const AppConfig *app_config = GUI::get_app_config(); if (! app_config->legacy_datadir()) { - appconfig_vendors.set_vendors(*app_config); + appconfig_new.set_vendors(*app_config); } else { // In case of legacy datadir, try to guess the preference based on the printer preset files that are present const auto printer_dir = fs::path(Slic3r::data_dir()) / "printer"; @@ -988,9 +1249,31 @@ void ConfigWizard::priv::load_vendors() const auto &model = needle->second.first; const auto &variant = needle->second.second; - appconfig_vendors.set_variant("PrusaResearch", model, variant, true); + appconfig_new.set_variant("PrusaResearch", model, variant, true); } } + + // Load up the materials enabled till now + if (app_config->has_section(Materials::SECTION_FILAMENTS)) { + appconfig_new.set_section(Materials::SECTION_FILAMENTS, app_config->get_section(Materials::SECTION_FILAMENTS)); + } else { + // No AppConfig settings, load up defaults from vendor section(s) + for (const auto &vendor : bundle.vendors) { + for (const auto &profile : vendor.default_filaments) { + appconfig_new.set(Materials::SECTION_FILAMENTS, profile, "1"); + } + } + } + if (app_config->has_section(Materials::SECTION_MATERIALS)) { + appconfig_new.set_section(Materials::SECTION_MATERIALS, app_config->get_section(Materials::SECTION_MATERIALS)); + } else { + // No AppConfig settings, load up defaults from vendor section(s) + for (const auto &vendor : bundle.vendors) { + for (const auto &profile : vendor.default_sla_materials) { + appconfig_new.set(Materials::SECTION_MATERIALS, profile, "1"); + } + } + } } void ConfigWizard::priv::add_page(ConfigWizardPage *page) @@ -1004,14 +1287,25 @@ void ConfigWizard::priv::enable_next(bool enable) btn_finish->Enable(enable); } -void ConfigWizard::priv::on_custom_setup(bool custom_wanted) +void ConfigWizard::priv::on_custom_setup() { - load_pages(custom_wanted); + load_pages(); +} + +void ConfigWizard::priv::on_printer_pick(PagePrinters *page) +{ + if (page == page_msla) { + const bool any_sla_selected_new = page->any_selected(); + if (any_sla_selected != any_sla_selected_new) { + any_sla_selected = any_sla_selected_new; + load_pages(); + } + } } void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater) { - const auto enabled_vendors = appconfig_vendors.vendors(); + const auto enabled_vendors = appconfig_new.vendors(); // Install bundles from resources if needed: std::vector install_bundles; @@ -1066,7 +1360,13 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese preset_bundle->reset(true); } - app_config->set_vendors(appconfig_vendors); + app_config->set_vendors(appconfig_new); + if (appconfig_new.has_section(Materials::SECTION_FILAMENTS)) { + app_config->set_section(Materials::SECTION_FILAMENTS, appconfig_new.get_section(Materials::SECTION_FILAMENTS)); + } + if (appconfig_new.has_section(Materials::SECTION_MATERIALS)) { + app_config->set_section(Materials::SECTION_MATERIALS, appconfig_new.get_section(Materials::SECTION_MATERIALS)); + } app_config->set("version_check", page_update->version_check ? "1" : "0"); app_config->set("preset_update", page_update->preset_update ? "1" : "0"); @@ -1155,12 +1455,17 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) p->add_page(p->page_welcome = new PageWelcome(this)); - p->page_fff = new PagePrinters(this, _(L("Prusa FFF Technology Printers")), "Prusa FFF", vendor_prusa, 0, PagePrinters::T_FFF); + p->page_fff = new PagePrinters(this, _(L("Prusa FFF Technology Printers")), "Prusa FFF", vendor_prusa, 0, T_FFF); p->add_page(p->page_fff); - p->page_msla = new PagePrinters(this, _(L("Prusa MSLA Technology Printers")), "Prusa MSLA", vendor_prusa, 0, PagePrinters::T_SLA); + p->page_msla = new PagePrinters(this, _(L("Prusa MSLA Technology Printers")), "Prusa MSLA", vendor_prusa, 0, T_SLA); p->add_page(p->page_msla); + p->add_page(p->page_filaments = new PageMaterials(this, &p->filaments, + _(L("Filament Profiles Selection")), _(L("Filaments")), _(L("Type:")) )); + p->add_page(p->page_sla_materials = new PageMaterials(this, &p->sla_materials, + _(L("SLA Material Profiles Selection")), _(L("SLA Materials")), _(L("Layer height:")) )); + p->add_page(p->page_custom = new PageCustom(this)); p->add_page(p->page_update = new PageUpdate(this)); p->add_page(p->page_vendors = new PageVendors(this)); @@ -1169,7 +1474,8 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) p->add_page(p->page_diams = new PageDiameters(this)); p->add_page(p->page_temps = new PageTemperatures(this)); - p->load_pages(false); + p->any_sla_selected = p->page_msla->any_selected(); + p->load_pages(); vsizer->Add(topsizer, 1, wxEXPAND | wxALL, DIALOG_MARGIN); vsizer->Add(hline, 0, wxEXPAND); @@ -1191,6 +1497,8 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) p->btn_finish->Hide(); p->btn_sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &) { + p->any_sla_selected = true; + p->load_pages(); p->page_fff->select_all(true, false); p->page_msla->select_all(true, false); p->index->go_to(p->page_update); @@ -1240,7 +1548,7 @@ void ConfigWizard::on_dpi_changed(const wxRect &suggested_rect) { p->index->msw_rescale(); - const int& em = em_unit(); + const int em = em_unit(); msw_buttons_rescale(this, em, { wxID_APPLY, wxID_CANCEL, diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index f4848933f..b57161c00 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "libslic3r/PrintConfig.hpp" #include "slic3r/Utils/PresetUpdater.hpp" @@ -41,6 +43,13 @@ enum { ROW_SPACING = 75, }; +enum Technology { + // Bitflag equivalent of PrinterTechnology + T_FFF = 0x1, + T_SLA = 0x2, + T_Any = ~0, +}; + typedef std::function ModelFilter; struct PrinterPicker: wxPanel @@ -61,19 +70,20 @@ struct PrinterPicker: wxPanel std::vector cboxes; std::vector cboxes_alt; - PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors, const ModelFilter &filter); - PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig_vendors); + PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig, const ModelFilter &filter); + PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxString title, size_t max_cols, const AppConfig &appconfig); void select_all(bool select, bool alternates = false); void select_one(size_t i, bool select); - void on_checkbox(const Checkbox *cbox, bool checked); + bool any_selected() const; int get_width() const { return width; } const std::vector& get_button_indexes() { return m_button_indexes; } private: int width; - std::vector m_button_indexes; + + void on_checkbox(const Checkbox *cbox, bool checked); }; struct ConfigWizardPage: wxPanel @@ -111,19 +121,93 @@ struct PageWelcome: ConfigWizardPage struct PagePrinters: ConfigWizardPage { - enum Technology { - // Bitflag equivalent of PrinterTechnology - T_FFF = 0x1, - T_SLA = 0x2, - T_Any = ~0, - }; - std::vector printer_pickers; PagePrinters(ConfigWizard *parent, wxString title, wxString shortname, const VendorProfile &vendor, unsigned indent, Technology technology); void select_all(bool select, bool alternates = false); int get_width() const; + bool any_selected() const; +}; + + +struct Materials +{ + Technology technology; + std::vector presets; + std::set types; + + Materials(Technology technology) : technology(technology) {} + + const std::string& appconfig_section() const; + const std::string& get_type(Preset &preset) const; + const std::string& get_vendor(Preset &preset) const; + + template void filter_presets(const std::string &type, const std::string &vendor, F cb) { + for (Preset &preset : presets) { + if ((type.empty() || get_type(preset) == type) && (vendor.empty() || get_vendor(preset) == vendor)) { + cb(preset); + } + } + } + + static const std::string UNKNOWN; + static const std::string SECTION_FILAMENTS; + static const std::string SECTION_MATERIALS; + static const std::string& get_filament_type(const Preset &preset); + static const std::string& get_filament_vendor(const Preset &preset); + static const std::string& get_material_type(Preset &preset); + static const std::string& get_material_vendor(const Preset &preset); +}; + +// Here we extend wxListBox and wxCheckListBox +// to make the client data API much easier to use. +template struct DataList : public T +{ + DataList(wxWindow *parent) : T(parent, wxID_ANY) {} + + int append(const std::string &label, const D *data) { + void *ptr = reinterpret_cast(const_cast(data)); + return this->Append(from_u8(label), ptr); + } + + int append(const wxString &label, const D *data) { + void *ptr = reinterpret_cast(const_cast(data)); + return this->Append(label, ptr); + } + + const D& get_data(int n) { + return *reinterpret_cast(this->GetClientData(n)); + } + + int find(const D &data) { + for (int i = 0; i < this->GetCount(); i++) { + if (get_data(i) == data) { return i; } + } + + return wxNOT_FOUND; + } +}; + +typedef DataList StringList; +typedef DataList PresetList; + +struct PageMaterials: ConfigWizardPage +{ + // Technology technology; + Materials *materials; + StringList *list_l1, *list_l2; + PresetList *list_l3; + // wxCheckListBox *list_l3; + int sel1_prev, sel2_prev; + + PageMaterials(ConfigWizard *parent, Materials *materials, wxString title, wxString shortname, wxString list1name); + + void update_lists(int sel1, int sel2); + void select_material(int i); + void select_all(bool select); + + static const std::string EMPTY; }; struct PageCustom: ConfigWizardPage @@ -228,12 +312,6 @@ private: int em_w; int em_h; - /* #ys_FIXME_delete_after_testing by VK - const wxBitmap bg; - const wxBitmap bullet_black; - const wxBitmap bullet_blue; - const wxBitmap bullet_white; - */ ScalableBitmap bg; ScalableBitmap bullet_black; ScalableBitmap bullet_blue; @@ -245,9 +323,6 @@ private: ssize_t item_hover; size_t last_page; - /* #ys_FIXME_delete_after_testing by VK - int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em_w) + em_w; } - */ int item_height() const { return std::max(bullet_black.bmp().GetSize().GetHeight(), em_w) + em_w; } void on_paint(wxPaintEvent &evt); @@ -256,14 +331,18 @@ private: wxDEFINE_EVENT(EVT_INDEX_PAGE, wxCommandEvent); + struct ConfigWizard::priv { ConfigWizard *q; ConfigWizard::RunReason run_reason; - AppConfig appconfig_vendors; + AppConfig appconfig_new; // Backing for vendor/model/variant and material selections in the GUI std::unordered_map vendors; - std::unordered_map vendors_rsrc; - std::unique_ptr custom_config; + Materials filaments; // Holds available filament presets and their types & vendors + Materials sla_materials; // Ditto for SLA materials + std::unordered_map vendors_rsrc; // List of bundles to install from resources + std::unique_ptr custom_config; // Backing for custom printer definition + bool any_sla_selected; // Used to decide whether to display SLA Materials page wxScrolledWindow *hscroll = nullptr; wxBoxSizer *hscroll_sizer = nullptr; @@ -279,6 +358,8 @@ struct ConfigWizard::priv PageWelcome *page_welcome = nullptr; PagePrinters *page_fff = nullptr; PagePrinters *page_msla = nullptr; + PageMaterials *page_filaments = nullptr; + PageMaterials *page_sla_materials = nullptr; PageCustom *page_custom = nullptr; PageUpdate *page_update = nullptr; PageVendors *page_vendors = nullptr; // XXX: ? @@ -289,9 +370,14 @@ struct ConfigWizard::priv PageDiameters *page_diams = nullptr; PageTemperatures *page_temps = nullptr; - priv(ConfigWizard *q) : q(q) {} + priv(ConfigWizard *q) + : q(q) + , filaments(T_FFF) + , sla_materials(T_SLA) + , any_sla_selected(false) + {} - void load_pages(bool custom_setup); + void load_pages(); void init_dialog_size(); bool check_first_variant() const; @@ -299,7 +385,8 @@ struct ConfigWizard::priv void add_page(ConfigWizardPage *page); void enable_next(bool enable); - void on_custom_setup(bool custom_wanted); + void on_custom_setup(); + void on_printer_pick(PagePrinters *page); void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index d2503d349..01cd4fa4d 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -99,6 +99,9 @@ static const std::unordered_map pre_family_model_map { VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem::path &path, bool load_all) { static const std::string printer_model_key = "printer_model:"; + static const std::string filaments_section = "default_filaments"; + static const std::string materials_section = "default_sla_materials"; + const std::string id = path.stem().string(); if (! boost::filesystem::exists(path)) { @@ -107,6 +110,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem VendorProfile res(id); + // Helper to get compulsory fields auto get_or_throw = [&](const ptree &tree, const std::string &key) -> ptree::const_assoc_iterator { auto res = tree.find(key); @@ -116,6 +120,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem return res; }; + // Load the header const auto &vendor_section = get_or_throw(tree, "vendor")->second; res.name = get_or_throw(vendor_section, "name")->second.data(); @@ -127,6 +132,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem res.config_version = std::move(*config_version); } + // Load URLs const auto config_update_url = vendor_section.find("config_update_url"); if (config_update_url != vendor_section.not_found()) { res.config_update_url = config_update_url->second.data(); @@ -141,6 +147,7 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem return res; } + // Load printer models for (auto §ion : tree) { if (boost::starts_with(section.first, printer_model_key)) { VendorProfile::PrinterModel model; @@ -182,6 +189,24 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem } } + // Load filaments and sla materials to be installed by default + const auto filaments = tree.find(filaments_section); + if (filaments != tree.not_found()) { + for (auto &pair : filaments->second) { + if (pair.second.data() == "1") { + res.default_filaments.insert(pair.first); + } + } + } + const auto materials = tree.find(materials_section); + if (materials != tree.not_found()) { + for (auto &pair : materials->second) { + if (pair.second.data() == "1") { + res.default_sla_materials.insert(pair.first); + } + } + } + return res; } @@ -351,10 +376,17 @@ bool Preset::update_compatible(const Preset &active_printer, const DynamicPrintC void Preset::set_visible_from_appconfig(const AppConfig &app_config) { if (vendor == nullptr) { return; } - const std::string &model = config.opt_string("printer_model"); - const std::string &variant = config.opt_string("printer_variant"); - if (model.empty() || variant.empty()) { return; } - is_visible = app_config.get_variant(vendor->id, model, variant); + + if (type == TYPE_PRINTER) { + const std::string &model = config.opt_string("printer_model"); + const std::string &variant = config.opt_string("printer_variant"); + if (model.empty() || variant.empty()) { return; } + is_visible = app_config.get_variant(vendor->id, model, variant); + } else if (type == TYPE_FILAMENT) { + is_visible = app_config.has("filaments", name); + } else if (type == TYPE_SLA_MATERIAL) { + is_visible = app_config.has("sla_materials", name); + } } const std::vector& Preset::print_options() @@ -404,7 +436,7 @@ const std::vector& Preset::filament_options() "filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel", "filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe", // Profile compatibility - "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits" + "filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits" }; return s_opts; } @@ -504,6 +536,7 @@ const std::vector& Preset::sla_material_options() "initial_exposure_time", "material_correction", "material_notes", + "material_vendor", "default_sla_material_profile", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits" diff --git a/src/slic3r/GUI/Preset.hpp b/src/slic3r/GUI/Preset.hpp index e1efdc1ef..dfb72d495 100644 --- a/src/slic3r/GUI/Preset.hpp +++ b/src/slic3r/GUI/Preset.hpp @@ -71,9 +71,14 @@ public: }; std::vector models; + std::set default_filaments; + std::set default_sla_materials; + VendorProfile() {} VendorProfile(std::string id) : id(std::move(id)) {} + // Load VendorProfile from an ini file. + // If `load_all` is false, only the header with basic info (name, version, URLs) is loaded. static VendorProfile from_ini(const boost::filesystem::path &path, bool load_all=true); static VendorProfile from_ini(const boost::property_tree::ptree &tree, const boost::filesystem::path &path, bool load_all=true); diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index d9e90333c..f254ad15c 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -323,6 +323,14 @@ void PresetBundle::load_installed_printers(const AppConfig &config) for (auto &preset : printers) { preset.set_visible_from_appconfig(config); } + + for (auto &preset : filaments) { + preset.set_visible_from_appconfig(config); + } + + for (auto &preset : sla_materials) { + preset.set_visible_from_appconfig(config); + } } // Load selections (current print, current filaments, current printer) from config.ini