diff --git a/src/libslic3r/AppConfig.hpp b/src/libslic3r/AppConfig.hpp new file mode 100644 index 000000000..ae8eae2ca --- /dev/null +++ b/src/libslic3r/AppConfig.hpp @@ -0,0 +1,291 @@ +#ifndef slic3r_AppConfig_hpp_ +#define slic3r_AppConfig_hpp_ + +#include +#include +#include +#include "nlohmann/json.hpp" +#include + +#include "libslic3r/Config.hpp" +#include "libslic3r/Semver.hpp" +#include "Calib.hpp" + +using namespace nlohmann; + +#define ENV_DEV_HOST "0" +#define ENV_QAT_HOST "1" +#define ENV_PRE_HOST "2" +#define ENV_PRODUCT_HOST "3" + +#define SUPPORT_DARK_MODE +//#define _MSW_DARK_MODE + + +namespace Slic3r { + +class AppConfig +{ +public: + enum class EAppMode : unsigned char + { + Editor, + GCodeViewer + }; + + //BBS: remove GCodeViewer as seperate APP logic + explicit AppConfig() : + m_dirty(false), + m_orig_version(Semver::invalid()), + m_mode(EAppMode::Editor), + m_legacy_datadir(false) + { + this->reset(); + } + + std::string get_language_code(); + std::string get_hms_host(); + + // Clear and reset to defaults. + void reset(); + // Override missing or keys with their defaults. + void set_defaults(); + + // Load the slic3r.ini from a user profile directory (or a datadir, if configured). + // return error string or empty strinf + std::string load(); + // Store the slic3r.ini into a user profile directory (or a datadir, if configured). + void save(); + + // Does this config need to be saved? + bool dirty() const { return m_dirty; } + + + void set_dirty() { m_dirty = true; } + + // Const accessor, it will return false if a section or a key does not exist. + bool get(const std::string §ion, const std::string &key, std::string &value) const + { + value.clear(); + auto it = m_storage.find(section); + if (it == m_storage.end()) + return false; + auto it2 = it->second.find(key); + if (it2 == it->second.end()) + return false; + value = it2->second; + return true; + } + std::string get(const std::string §ion, const std::string &key) const + { std::string value; this->get(section, key, value); return value; } + std::string get(const std::string &key) const + { std::string value; this->get("app", key, value); return value; } + void set(const std::string §ion, const std::string &key, const std::string &value) + { +#ifndef NDEBUG + { + std::string key_trimmed = key; + boost::trim_all(key_trimmed); + assert(key_trimmed == key); + assert(! key_trimmed.empty()); + } +#endif // NDEBUG + std::string &old = m_storage[section][key]; + if (old != value) { + old = value; + m_dirty = true; + } + } + + void set_str(const std::string& section, const std::string& key, const std::string& value) + { +#ifndef NDEBUG + { + std::string key_trimmed = key; + boost::trim_all(key_trimmed); + assert(key_trimmed == key); + assert(!key_trimmed.empty()); + } +#endif // NDEBUG + std::string& old = m_storage[section][key]; + if (old != value) { + old = value; + m_dirty = true; + } + } + + void set(const std::string& section, const std::string &key, bool value) + { + if (value){ + set(section, key, std::string("true")); + } else { + set(section, key, std::string("false")); + } + } + + + void set(const std::string &key, const std::string &value) + { this->set("app", key, value); } + + void set_bool(const std::string &key, const bool &value) + { + this->set("app", key, value); + } + + bool has(const std::string §ion, const std::string &key) const + { + auto it = m_storage.find(section); + if (it == m_storage.end()) + return false; + auto it2 = it->second.find(key); + return it2 != it->second.end() && ! it2->second.empty(); + } + bool has(const std::string &key) const + { return this->has("app", key); } + + void erase(const std::string §ion, const std::string &key) + { + auto it = m_storage.find(section); + if (it != m_storage.end()) { + it->second.erase(key); + } + } + + 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(); } + + typedef std::map>> VendorMap; + bool get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const; + void set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable); + void set_vendors(const AppConfig &from); + void set_vendors(const VendorMap &vendors) { m_vendors = vendors; m_dirty = true; } + void set_vendors(VendorMap &&vendors) { m_vendors = std::move(vendors); m_dirty = true; } + const VendorMap& vendors() const { return m_vendors; } + + const std::vector &get_filament_presets() const { return m_filament_presets; } + void set_filament_presets(const std::vector &filament_presets){ + m_filament_presets = filament_presets; + m_dirty = true; + } + const std::vector &get_filament_colors() const { return m_filament_colors; } + void set_filament_colors(const std::vector &filament_colors){ + m_filament_colors = filament_colors; + m_dirty = true; + } + + const std::vector &get_printer_cali_infos() const { return m_printer_cali_infos; } + void save_printer_cali_infos(const PrinterCaliInfo& cali_info, bool need_change_status = true); + + // return recent/last_opened_folder or recent/settings_folder or empty string. + std::string get_last_dir() const; + void update_config_dir(const std::string &dir); + void update_skein_dir(const std::string &dir); + + //std::string get_last_output_dir(const std::string &alt) const; + //void update_last_output_dir(const std::string &dir); + std::string get_last_output_dir(const std::string& alt, const bool removable = false) const; + void update_last_output_dir(const std::string &dir, const bool removable = false); + + // BBS: backup & restore + std::string get_last_backup_dir() const; + void update_last_backup_dir(const std::string &dir); + + std::string get_region(); + std::string get_country_code(); + bool is_engineering_region(); + + void save_custom_color_to_config(const std::vector &colors); + std::vector get_custom_color_from_config(); + // reset the current print / filament / printer selections, so that + // the PresetBundle::load_selections(const AppConfig &config) call will select + // the first non-default preset when called. + void reset_selections(); + + // Get the default config path from Slic3r::data_dir(). + std::string config_path(); + + // Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating) + bool legacy_datadir() const { return m_legacy_datadir; } + void set_legacy_datadir(bool value) { m_legacy_datadir = value; } + + // Get the Slic3r version check url. + // This returns a hardcoded string unless it is overriden by "version_check_url" in the ini file. + std::string version_check_url() const; + + // Returns the original Slic3r version found in the ini file before it was overwritten + // by the current version + Semver orig_version() const { return m_orig_version; } + + // Does the config file exist? + bool exists(); + + void set_loading_path(const std::string& path) { m_loading_path = path; } + std::string loading_path() { return (m_loading_path.empty() ? config_path() : m_loading_path); } + + std::vector get_recent_projects() const; + void set_recent_projects(const std::vector& recent_projects); + + void set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz); + std::vector get_mouse_device_names() const; + bool get_mouse_device_translation_speed(const std::string& name, double& speed) const + { return get_3dmouse_device_numeric_value(name, "translation_speed", speed); } + bool get_mouse_device_translation_deadzone(const std::string& name, double& deadzone) const + { return get_3dmouse_device_numeric_value(name, "translation_deadzone", deadzone); } + bool get_mouse_device_rotation_speed(const std::string& name, float& speed) const + { return get_3dmouse_device_numeric_value(name, "rotation_speed", speed); } + bool get_mouse_device_rotation_deadzone(const std::string& name, float& deadzone) const + { return get_3dmouse_device_numeric_value(name, "rotation_deadzone", deadzone); } + bool get_mouse_device_zoom_speed(const std::string& name, double& speed) const + { return get_3dmouse_device_numeric_value(name, "zoom_speed", speed); } + bool get_mouse_device_swap_yz(const std::string& name, bool& swap) const + { return get_3dmouse_device_numeric_value(name, "swap_yz", swap); } + + static const std::string SECTION_FILAMENTS; + static const std::string SECTION_MATERIALS; + +private: + template + bool get_3dmouse_device_numeric_value(const std::string &device_name, const char *parameter_name, T &out) const + { + std::string key = std::string("mouse_device:") + device_name; + auto it = m_storage.find(key); + if (it == m_storage.end()) + return false; + auto it_val = it->second.find(parameter_name); + if (it_val == it->second.end()) + return false; + out = T(string_to_double_decimal_point(it_val->second)); + return true; + } + + // Type of application: Editor or GCodeViewer + EAppMode m_mode { EAppMode::Editor }; + // Map of section, name -> value + std::map> m_storage; + + // Map of enabled vendors / models / variants + VendorMap m_vendors; + // Has any value been modified since the config.ini has been last saved or loaded? + bool m_dirty; + // Original version found in the ini file before it was overwritten + Semver m_orig_version; + // Whether the existing version is before system profiles & configuration updating + bool m_legacy_datadir; + + std::string m_loading_path; + + std::vector m_filament_presets; + std::vector m_filament_colors; + + std::vector m_printer_cali_infos; +}; + +} // namespace Slic3r + +#endif /* slic3r_AppConfig_hpp_ */ diff --git a/src/libslic3r/Fill/Fill.hpp b/src/libslic3r/Fill/Fill.hpp new file mode 100644 index 000000000..e92ab2dee --- /dev/null +++ b/src/libslic3r/Fill/Fill.hpp @@ -0,0 +1,33 @@ +#ifndef slic3r_Fill_hpp_ +#define slic3r_Fill_hpp_ + +#include +#include +#include + +#include "../libslic3r.h" +#include "../PrintConfig.hpp" + +#include "FillBase.hpp" + +namespace Slic3r { + +class ExtrusionEntityCollection; +class LayerRegion; + +// An interface class to Perl, aggregating an instance of a Fill and a FillData. +class Filler +{ +public: + Filler() : fill(nullptr) {} + ~Filler() { + delete fill; + fill = nullptr; + } + Fill *fill; + FillParams params; +}; + +} // namespace Slic3r + +#endif // slic3r_Fill_hpp_ diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp new file mode 100644 index 000000000..5672d55e4 --- /dev/null +++ b/src/libslic3r/Fill/FillBase.hpp @@ -0,0 +1,181 @@ +#ifndef slic3r_FillBase_hpp_ +#define slic3r_FillBase_hpp_ + +#include +#include +#include +#include +#include + +#include + +#include "../libslic3r.h" +#include "../BoundingBox.hpp" +#include "../Exception.hpp" +#include "../Utils.hpp" +#include "../ExPolygon.hpp" +//BBS: necessary header for new function +#include "../PrintConfig.hpp" +#include "../Flow.hpp" +#include "../ExtrusionEntity.hpp" +#include "../ExtrusionEntityCollection.hpp" + +namespace Slic3r { + +class Surface; +enum InfillPattern : int; + +namespace FillAdaptive { + struct Octree; +}; + +// Infill shall never fail, therefore the error is classified as RuntimeError, not SlicingError. +class InfillFailedException : public Slic3r::RuntimeError { +public: + InfillFailedException() : Slic3r::RuntimeError("Infill failed") {} +}; + +struct FillParams +{ + bool full_infill() const { return density > 0.9999f; } + // Don't connect the fill lines around the inner perimeter. + bool dont_connect() const { return anchor_length_max < 0.05f; } + double filter_out_gap_fill { 0.0 }; + // Fill density, fraction in <0, 1> + float density { 0.f }; + + // Length of an infill anchor along the perimeter. + // 1000mm is roughly the maximum length line that fits into a 32bit coord_t. + float anchor_length { 1000.f }; + float anchor_length_max { 1000.f }; + + // G-code resolution. + double resolution { 0.0125 }; + + // Don't adjust spacing to fill the space evenly. + bool dont_adjust { true }; + + // Monotonic infill - strictly left to right for better surface quality of top infills. + bool monotonic { false }; + + // For Honeycomb. + // we were requested to complete each loop; + // in this case we don't try to make more continuous paths + bool complete { false }; + + // For Concentric infill, to switch between Classic and Arachne. + bool use_arachne{ false }; + // Layer height for Concentric infill with Arachne. + coordf_t layer_height { 0.f }; + + // BBS + Flow flow; + ExtrusionRole extrusion_role{ ExtrusionRole(0) }; + bool using_internal_flow{ false }; + //BBS: only used for new top surface pattern + float no_extrusion_overlap{ 0.0 }; + bool dont_sort{ false }; // do not sort the lines, just simply connect them + bool can_reverse{true}; +}; +static_assert(IsTriviallyCopyable::value, "FillParams class is not POD (and it should be - see constructor)."); + +class Fill +{ +public: + // Index of the layer. + size_t layer_id; + // Z coordinate of the top print surface, in unscaled coordinates + coordf_t z; + // in unscaled coordinates + coordf_t spacing; + // infill / perimeter overlap, in unscaled coordinates + coordf_t overlap; + // in radians, ccw, 0 = East + float angle; + // In scaled coordinates. Maximum lenght of a perimeter segment connecting two infill lines. + // Used by the FillRectilinear2, FillGrid2, FillTriangles, FillStars and FillCubic. + // If left to zero, the links will not be limited. + coord_t link_max_length; + // In scaled coordinates. Used by the concentric infill pattern to clip the loops to create extrusion paths. + coord_t loop_clipping; + // In scaled coordinates. Bounding box of the 2D projection of the object. + BoundingBox bounding_box; + + // Octree builds on mesh for usage in the adaptive cubic infill + FillAdaptive::Octree* adapt_fill_octree = nullptr; + + // BBS: all no overlap expolygons in same layer + ExPolygons no_overlap_expolygons; + +public: + virtual ~Fill() {} + virtual Fill* clone() const = 0; + + static Fill* new_from_type(const InfillPattern type); + static Fill* new_from_type(const std::string &type); + static bool use_bridge_flow(const InfillPattern type); + + void set_bounding_box(const Slic3r::BoundingBox &bbox) { bounding_box = bbox; } + + // Use bridge flow for the fill? + virtual bool use_bridge_flow() const { return false; } + + // Do not sort the fill lines to optimize the print head path? + virtual bool no_sort() const { return false; } + + // Perform the fill. + virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms); + virtual ThickPolylines fill_surface_arachne(const Surface* surface, const FillParams& params); + + // BBS: this method is used to fill the ExtrusionEntityCollection. + // It call fill_surface by default + virtual void fill_surface_extrusion(const Surface* surface, const FillParams& params, ExtrusionEntitiesPtr& out); + +protected: + Fill() : + layer_id(size_t(-1)), + z(0.), + spacing(0.), + // Infill / perimeter overlap. + overlap(0.), + // Initial angle is undefined. + angle(FLT_MAX), + link_max_length(0), + loop_clipping(0), + // The initial bounding box is empty, therefore undefined. + bounding_box(Point(0, 0), Point(-1, -1)) + {} + + // The expolygon may be modified by the method to avoid a copy. + virtual void _fill_surface_single( + const FillParams & /* params */, + unsigned int /* thickness_layers */, + const std::pair & /* direction */, + ExPolygon /* expolygon */, + Polylines & /* polylines_out */) {}; + + // Used for concentric infill to generate ThickPolylines using Arachne. + virtual void _fill_surface_single(const FillParams& params, + unsigned int thickness_layers, + const std::pair& direction, + ExPolygon expolygon, + ThickPolylines& thick_polylines_out) {} + + virtual float _layer_angle(size_t idx) const { return (idx & 1) ? float(M_PI/2.) : 0; } + + virtual std::pair _infill_direction(const Surface *surface) const; + +public: + static void connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, const double spacing, const FillParams ¶ms); + static void connect_infill(Polylines &&infill_ordered, const Polygons &boundary, const BoundingBox& bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms); + static void connect_infill(Polylines &&infill_ordered, const std::vector &boundary, const BoundingBox &bbox, Polylines &polylines_out, double spacing, const FillParams ¶ms); + + static void connect_base_support(Polylines &&infill_ordered, const std::vector &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms); + static void connect_base_support(Polylines &&infill_ordered, const Polygons &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms); + + static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance); +}; + +} // namespace Slic3r + +#endif // slic3r_FillBase_hpp_ diff --git a/src/slic3r/GUI/ConfigWizard.hpp b/src/slic3r/GUI/ConfigWizard.hpp new file mode 100644 index 000000000..891c1187a --- /dev/null +++ b/src/slic3r/GUI/ConfigWizard.hpp @@ -0,0 +1,66 @@ +#ifndef slic3r_ConfigWizard_hpp_ +#define slic3r_ConfigWizard_hpp_ + +#include + +#include + +#include "GUI_Utils.hpp" + +namespace Slic3r { + +class PresetBundle; +class PresetUpdater; + +namespace GUI { + + +class ConfigWizard: public DPIDialog +{ +public: + // Why is the Wizard run + enum RunReason { + RR_DATA_EMPTY, // No or empty datadir + RR_DATA_LEGACY, // Pre-updating datadir + RR_DATA_INCOMPAT, // Incompatible datadir - Slic3r downgrade situation + RR_USER, // User requested the Wizard from the menus + }; + + // What page should wizard start on + enum StartPage { + SP_WELCOME, + SP_PRINTERS, + SP_FILAMENTS, + SP_MATERIALS, + SP_CUSTOM, + SP_CONFIGS, + }; + + ConfigWizard(wxWindow *parent); + ConfigWizard(ConfigWizard &&) = delete; + ConfigWizard(const ConfigWizard &) = delete; + ConfigWizard &operator=(ConfigWizard &&) = delete; + ConfigWizard &operator=(const ConfigWizard &) = delete; + ~ConfigWizard(); + + // Run the Wizard. Return whether it was completed. + bool run(RunReason reason, StartPage start_page = SP_WELCOME); + + static const wxString& name(const bool from_menu = false); +protected: + void on_dpi_changed(const wxRect &suggested_rect) override ; + void on_sys_color_changed() override; + +private: + struct priv; + std::unique_ptr p; + + friend struct ConfigWizardPage; +}; + + + +} +} + +#endif diff --git a/src/slic3r/GUI/CreatePresetsDialog.hpp b/src/slic3r/GUI/CreatePresetsDialog.hpp new file mode 100644 index 000000000..9bb09c57d --- /dev/null +++ b/src/slic3r/GUI/CreatePresetsDialog.hpp @@ -0,0 +1,401 @@ +#ifndef slic3r_CreatePresetsDialog_hpp_ +#define slic3r_CreatePresetsDialog_hpp_ + +#include "libslic3r/Preset.hpp" +#include "wxExtensions.hpp" +#include "GUI_Utils.hpp" +#include "Widgets/Label.hpp" +#include "Widgets/TextInput.hpp" +#include "Widgets/Button.hpp" +#include "Widgets/RadioBox.hpp" +#include "Widgets/CheckBox.hpp" +#include "Widgets/ComboBox.hpp" +#include "miniz.h" +#include "ParamsDialog.hpp" + +namespace Slic3r { +namespace GUI { + +class CreateFilamentPresetDialog : public DPIDialog +{ +public: + CreateFilamentPresetDialog(wxWindow *parent); + ~CreateFilamentPresetDialog(); + +protected: + enum FilamentOptionType { + VENDOR = 0, + TYPE, + SERIAL, + FILAMENT_PRESET, + PRESET_FOR_PRINTER, + FILAMENT_NAME_COUNT + }; + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; + bool is_check_box_selected(); + wxBoxSizer *create_item(FilamentOptionType option_type); + wxBoxSizer *create_vendor_item(); + wxBoxSizer *create_type_item(); + wxBoxSizer *create_serial_item(); + wxBoxSizer *create_filament_preset_item(); + wxBoxSizer *create_filament_preset_for_printer_item(); + wxBoxSizer *create_button_item(); + +private: + void clear_filament_preset_map(); + wxArrayString get_filament_preset_choices(); + wxBoxSizer * create_radio_item(wxString title, wxWindow *parent, wxString tooltip, std::vector> &radiobox_list); + void select_curr_radiobox(std::vector> &radiobox_list, int btn_idx); + wxString curr_create_filament_type(); + void get_filament_presets_by_machine(); + void get_all_filament_presets(); + void get_all_visible_printer_name(); + void update_dialog_size(); + template + void sort_printer_by_nozzle(std::vector> &printer_name_to_filament_preset); + +private: + struct CreateType + { + wxString base_filament; + wxString base_filament_preset; + }; + +private: + std::vector> m_create_type_btns; + std::unordered_map<::CheckBox *, std::pair> m_filament_preset; + std::unordered_map<::CheckBox *, std::pair> m_machint_filament_preset; + std::unordered_map> m_filament_choice_map; + std::unordered_map m_public_name_to_filament_id_map; + std::unordered_map m_all_presets_map; + std::unordered_set m_system_filament_types_set; + std::set m_visible_printers; + CreateType m_create_type; + Button * m_button_create = nullptr; + Button * m_button_cancel = nullptr; + ComboBox * m_filament_vendor_combobox = nullptr; + ::CheckBox * m_can_not_find_vendor_checkbox = nullptr; + ComboBox * m_filament_type_combobox = nullptr; + ComboBox * m_exist_vendor_combobox = nullptr; + ComboBox * m_filament_preset_combobox = nullptr; + TextInput * m_filament_custom_vendor_input = nullptr; + wxGridSizer * m_filament_presets_sizer = nullptr; + wxPanel * m_filament_preset_panel = nullptr; + wxScrolledWindow * m_scrolled_preset_panel = nullptr; + TextInput * m_filament_serial_input = nullptr; + wxBoxSizer * m_scrolled_sizer = nullptr; + wxStaticText * m_filament_preset_text = nullptr; + +}; + +class CreatePrinterPresetDialog : public DPIDialog +{ +public: + CreatePrinterPresetDialog(wxWindow *parent); + ~CreatePrinterPresetDialog(); + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; + +/******************************************************** Control Construction *****************************************************/ + wxBoxSizer *create_step_switch_item(); + //Create Printer Page1 + void create_printer_page1(wxWindow *parent); + wxBoxSizer *create_type_item(wxWindow *parent); + wxBoxSizer *create_printer_item(wxWindow *parent); + wxBoxSizer *create_nozzle_diameter_item(wxWindow *parent); + wxBoxSizer *create_bed_shape_item(wxWindow *parent); + wxBoxSizer *create_bed_size_item(wxWindow *parent); + wxBoxSizer *create_origin_item(wxWindow *parent); + wxBoxSizer *create_hot_bed_stl_item(wxWindow *parent); + wxBoxSizer *create_hot_bed_svg_item(wxWindow *parent); + wxBoxSizer *create_max_print_height_item(wxWindow *parent); + wxBoxSizer *create_page1_btns_item(wxWindow *parent); + //Improt Presets Page2 + void create_printer_page2(wxWindow *parent); + wxBoxSizer *create_printer_preset_item(wxWindow *parent); + wxBoxSizer *create_presets_item(wxWindow *parent); + wxBoxSizer *create_presets_template_item(wxWindow *parent); + wxBoxSizer *create_page2_btns_item(wxWindow *parent); + + void show_page1(); + void show_page2(); + +/********************************************************** Data Interaction *******************************************************/ + bool data_init(); + void set_current_visible_printer(); + void select_curr_radiobox(std::vector> &radiobox_list, int btn_idx); + void select_all_preset_template(std::vector> &preset_templates); + void deselect_all_preset_template(std::vector> &preset_templates); + void update_presets_list(bool jast_template = false); + void on_preset_model_value_change(wxCommandEvent &e); + void clear_preset_combobox(); + bool save_printable_area_config(Preset *preset); + bool check_printable_area(); + bool validate_input_valid(); + void load_texture(); + void load_model_stl(); + bool load_system_and_user_presets_with_curr_model(PresetBundle &temp_preset_bundle, bool just_template = false); + void generate_process_presets_data(std::vector presets, std::string nozzle); + void update_preset_list_size(); + wxArrayString printer_preset_sort_with_nozzle_diameter(const VendorProfile &vendor_profile, float nozzle_diameter); + + wxBoxSizer *create_radio_item(wxString title, wxWindow *parent, wxString tooltip, std::vector> &radiobox_list); + + wxString curr_create_preset_type(); + wxString curr_create_printer_type(); + +private: + struct CreatePrinterType + { + wxString create_printer; + wxString create_nozzle; + wxString base_template; + wxString base_curr_printer; + }; + + CreatePrinterType m_create_type; + std::vector> m_create_type_btns; + std::vector> m_create_presets_btns; + std::vector> m_filament_preset; + std::vector> m_process_preset; + std::unordered_map> m_printer_name_to_preset; + VendorProfile m_printer_preset_vendor_selected; + Slic3r::VendorProfile::PrinterModel m_printer_preset_model_selected; + bool rewritten = false; + Preset * m_printer_preset = nullptr; + wxStaticBitmap * m_step_1 = nullptr; + wxStaticBitmap * m_step_2 = nullptr; + Button * m_button_OK = nullptr; + Button * m_button_create = nullptr; + Button * m_button_page1_cancel = nullptr; + Button * m_button_page2_cancel = nullptr; + Button * m_button_page2_back = nullptr; + Button * m_button_bed_stl = nullptr; + Button * m_button_bed_svg = nullptr; + wxScrolledWindow * m_page1 = nullptr; + wxPanel * m_page2 = nullptr; + wxScrolledWindow * m_scrolled_preset_window = nullptr; + wxBoxSizer * m_scrooled_preset_sizer = nullptr; + ComboBox * m_select_vendor = nullptr; + ComboBox * m_select_model = nullptr; + ComboBox * m_select_printer = nullptr; + ::CheckBox * m_can_not_find_vendor_combox = nullptr; + wxStaticText * m_can_not_find_vendor_text = nullptr; + wxTextCtrl * m_custom_vendor_text_ctrl = nullptr; + wxTextCtrl * m_custom_model_text_ctrl = nullptr; + ComboBox * m_nozzle_diameter = nullptr; + ComboBox * m_printer_vendor = nullptr; + ComboBox * m_printer_model = nullptr; + TextInput * m_bed_size_x_input = nullptr; + TextInput * m_bed_size_y_input = nullptr; + TextInput * m_bed_origin_x_input = nullptr; + TextInput * m_bed_origin_y_input = nullptr; + TextInput * m_print_height_input = nullptr; + wxGridSizer * m_filament_preset_template_sizer = nullptr; + wxGridSizer * m_process_preset_template_sizer = nullptr; + wxPanel * m_filament_preset_panel = nullptr; + wxPanel * m_process_preset_panel = nullptr; + wxPanel * m_preset_template_panel = nullptr; + wxBoxSizer * m_filament_sizer = nullptr; + wxPanel * m_printer_info_panel = nullptr; + wxBoxSizer * m_page1_sizer = nullptr; + wxBoxSizer * m_printer_info_sizer = nullptr; + wxBoxSizer * m_page2_sizer = nullptr; + wxStaticText * m_upload_stl_tip_text = nullptr; + wxStaticText * m_upload_svg_tip_text = nullptr; + std::string m_custom_texture; + std::string m_custom_model; +}; + +enum SuccessType { + PRINTER = 0, + FILAMENT +}; + +class CreatePresetSuccessfulDialog : public DPIDialog +{ +public: + CreatePresetSuccessfulDialog(wxWindow *parent, const SuccessType &create_success_type); + ~CreatePresetSuccessfulDialog(); + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; + +private: + Button *m_button_ok = nullptr; + Button *m_button_cancel = nullptr; +}; + +class ExportConfigsDialog : public DPIDialog +{ +public: + ExportConfigsDialog(wxWindow *parent); + ~ExportConfigsDialog();//to do: delete preset + +protected: + + struct ExportType + { + wxString preset_bundle; + wxString filament_bundle; + wxString printer_preset; + wxString filament_preset; + wxString process_preset; + }; + + enum ExportCase { + INITIALIZE_FAIL = 0, + ADD_FILE_FAIL, + ADD_BUNDLE_STRUCTURE_FAIL, + FINALIZE_FAIL, + OPEN_ZIP_WRITTEN_FILE, + EXPORT_CANCEL, + EXPORT_SUCCESS, + CASE_COUNT, + }; + +private: + void data_init(); + void select_curr_radiobox(std::vector> &radiobox_list, int btn_idx); + void on_dpi_changed(const wxRect &suggested_rect) override; + void show_export_result(const ExportCase &export_case); + bool has_check_box_selected(); + bool preset_is_not_compatible_bbl_printer(Preset *preset); + bool earse_preset_fields_for_safe(Preset *preset); + std::string initial_file_path(const wxString &path, const std::string &sub_file_path); + std::string initial_file_name(const wxString &path, const std::string file_name); + wxBoxSizer *create_export_config_item(wxWindow *parent); + wxBoxSizer *create_button_item(wxWindow *parent); + wxBoxSizer *create_select_printer(wxWindow *parent); + wxBoxSizer *create_radio_item(wxString title, wxWindow *parent, wxString tooltip, std::vector> &radiobox_list); + int initial_zip_archive(mz_zip_archive &zip_archive, const std::string &file_path); + ExportCase save_zip_archive_to_file(mz_zip_archive &zip_archive); + ExportCase save_presets_to_zip(const std::string &export_file, const std::vector> &config_paths); + ExportCase archive_preset_bundle_to_file(const wxString &path); + ExportCase archive_filament_bundle_to_file(const wxString &path); + ExportCase archive_printer_preset_to_file(const wxString &path); + ExportCase archive_filament_preset_to_file(const wxString &path); + ExportCase archive_process_preset_to_file(const wxString &path); + +private: + std::vector> m_export_type_btns; + std::vector> m_preset; // for printer preset bundle,printer preset, process preset export + std::vector> m_printer_name; // for filament and peocess preset export, collaborate with m_filament_name_to_presets + std::unordered_map m_printer_presets;//first: printer name, second: printer presets have same printer name + std::unordered_map> m_filament_presets;//first: printer name, second: filament presets have same printer name + std::unordered_map> m_process_presets;//first: printer name, second: filament presets have same printer name + std::unordered_map>> m_filament_name_to_presets;//first: filament name, second presets have same filament name and printer name in vector + ExportType m_exprot_type; + wxBoxSizer * m_main_sizer = nullptr; + wxScrolledWindow * m_scrolled_preset_window = nullptr; + wxGridSizer * m_preset_sizer = nullptr; + wxPanel * m_presets_window = nullptr; + Button * m_button_ok = nullptr; + Button * m_button_cancel = nullptr; + wxStaticText * m_serial_text = nullptr; +}; + +class CreatePresetForPrinterDialog : public DPIDialog +{ +public: + CreatePresetForPrinterDialog(wxWindow *parent, std::string filament_type, std::string filament_id, std::string filament_vendor, std::string filament_name); + ~CreatePresetForPrinterDialog(); + +private: + void on_dpi_changed(const wxRect &suggested_rect) override; + void get_visible_printer_and_compatible_filament_presets(); + wxBoxSizer *create_selected_printer_preset_sizer(); + wxBoxSizer *create_selected_filament_preset_sizer(); + wxBoxSizer *create_button_sizer(); + +private: + std::string m_filament_id; + std::string m_filament_name; + std::string m_filament_vendor; + std::string m_filament_type; + std::shared_ptr m_preset_bundle; + ComboBox * m_selected_printer = nullptr; + ComboBox * m_selected_filament = nullptr; + Button * m_ok_btn = nullptr; + Button * m_cancel_btn = nullptr; + std::unordered_map> filament_choice_to_filament_preset; + std::unordered_map>> m_printer_compatible_filament_presets; // need be used when add presets + +}; + +class EditFilamentPresetDialog; + +class PresetTree +{ +public: + PresetTree(EditFilamentPresetDialog *dialog); + + wxPanel *get_preset_tree(std::pair>> printer_and_presets); + +private: + wxPanel *get_root_item(wxPanel *parent, const std::string &printer_name); + + wxPanel *get_child_item(wxPanel *parent, std::shared_ptr preset, std::string printer_name, int preset_index, bool is_last = false); + + void delete_preset(std::string printer_name, int need_delete_preset_index); + + void edit_preset(std::string printer_name, int need_edit_preset_index); + +private: + EditFilamentPresetDialog * m_parent_dialog = nullptr; + std::pair>> m_printer_and_presets; + +}; + +class EditFilamentPresetDialog : public DPIDialog +{ +public: + EditFilamentPresetDialog(wxWindow *parent, FilamentInfomation *filament_info); + ~EditFilamentPresetDialog(); + + wxPanel *get_preset_tree_panel() { return m_preset_tree_panel; } + std::shared_ptr get_need_edit_preset() { return m_need_edit_preset; } + void set_printer_name(const std::string &printer_name) { m_selected_printer = printer_name; } + void set_need_delete_preset_index(int need_delete_preset_index) { m_need_delete_preset_index = need_delete_preset_index; } + void set_need_edit_preset_index(int need_edit_preset_index) { m_need_edit_preset_index = need_edit_preset_index; } + void delete_preset(); + void edit_preset(); + +private: + void on_dpi_changed(const wxRect &suggested_rect) override; + bool get_same_filament_id_presets(std::string filament_id); + void update_preset_tree(); + wxBoxSizer *create_filament_basic_info(); + wxBoxSizer *create_add_filament_btn(); + wxBoxSizer *create_preset_tree_sizer(); + wxBoxSizer *create_button_sizer(); + +private: + PresetTree * m_preset_tree_creater = nullptr; + std::string m_filament_id; + std::string m_filament_name; + std::string m_vendor_name; + std::string m_filament_type; + std::string m_filament_serial; + Button * m_add_filament_btn = nullptr; + Button * m_del_filament_btn = nullptr; + Button * m_ok_btn = nullptr; + wxBoxSizer * m_preset_tree_sizer = nullptr; + wxPanel * m_preset_tree_panel = nullptr; + wxScrolledWindow * m_preset_tree_window = nullptr; + wxBoxSizer * m_main_sizer = nullptr; + wxStaticText * m_note_text = nullptr; + int m_need_delete_preset_index = -1; + int m_need_edit_preset_index = -1; + std::shared_ptr m_need_edit_preset; + std::string m_selected_printer = ""; + std::unordered_map>> m_printer_compatible_presets; + +}; + +} +} +#endif \ No newline at end of file diff --git a/src/slic3r/GUI/GUI.hpp b/src/slic3r/GUI/GUI.hpp new file mode 100644 index 000000000..765406583 --- /dev/null +++ b/src/slic3r/GUI/GUI.hpp @@ -0,0 +1,90 @@ +#ifndef slic3r_GUI_hpp_ +#define slic3r_GUI_hpp_ + +namespace boost { class any; } +namespace boost::filesystem { class path; } + +#include + +#include "libslic3r/Config.hpp" +#include "libslic3r/Preset.hpp" + +class wxWindow; +class wxMenuBar; +class wxComboCtrl; +class wxFileDialog; +class wxTopLevelWindow; + +namespace Slic3r { + +class AppConfig; +class DynamicPrintConfig; +class Print; + +namespace GUI { + +void disable_screensaver(); +void enable_screensaver(); +bool debugged(); +void break_to_debugger(); + +// Platform specific Ctrl+/Alt+ (Windows, Linux) vs. ⌘/⌥ (OSX) prefixes +extern const std::string& shortkey_ctrl_prefix(); +extern const std::string& shortkey_alt_prefix(); + +extern AppConfig* get_app_config(); + +extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); + +// Change option value in config +void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index = 0); + +// If monospaced_font is true, the error message is displayed using html
tags, +// so that the code formatting will be preserved. This is useful for reporting errors from the placeholder parser. +void show_error(wxWindow* parent, const wxString& message, bool monospaced_font = false); +void show_error(wxWindow* parent, const char* message, bool monospaced_font = false); +inline void show_error(wxWindow* parent, const std::string& message, bool monospaced_font = false) { show_error(parent, message.c_str(), monospaced_font); } +void show_error_id(int id, const std::string& message); // For Perl +void show_info(wxWindow* parent, const wxString& message, const wxString& title = wxString()); +void show_info(wxWindow* parent, const char* message, const char* title = nullptr); +inline void show_info(wxWindow* parent, const std::string& message,const std::string& title = std::string()) { show_info(parent, message.c_str(), title.c_str()); } +void warning_catcher(wxWindow* parent, const wxString& message); +void show_substitutions_info(const PresetsConfigSubstitutions& presets_config_substitutions); +void show_substitutions_info(const ConfigSubstitutions& config_substitutions, const std::string& filename); + +// Creates a wxCheckListBoxComboPopup inside the given wxComboCtrl, filled with the given text and items. +// Items data must be separated by '|', and contain the item name to be shown followed by its initial value (0 for false, 1 for true). +// For example "Item1|0|Item2|1|Item3|0", and so on. +void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, const std::string& items); + +// Returns the current state of the items listed in the wxCheckListBoxComboPopup contained in the given wxComboCtrl, +// encoded inside an unsigned int. +unsigned int combochecklist_get_flags(wxComboCtrl* comboCtrl); + +// Sets the current state of the items listed in the wxCheckListBoxComboPopup contained in the given wxComboCtrl, +// with the flags encoded in the given unsigned int. +void combochecklist_set_flags(wxComboCtrl* comboCtrl, unsigned int flags); + +// wxString conversions: + +// wxString from std::string in UTF8 +wxString from_u8(const std::string &str); +// std::string in UTF8 from wxString +std::string into_u8(const wxString &str); +// wxString from boost path +wxString from_path(const boost::filesystem::path &path); +// boost path from wxString +boost::filesystem::path into_path(const wxString &str); + +// Display an About dialog +extern void about(); +// Display a Login dialog +extern void login(); +// Ask the destop to open the datadir using the default file explorer. +extern void desktop_open_datadir_folder(); +// Ask the destop to open one folder +extern void desktop_open_any_folder(const std::string path); +} // namespace GUI +} // namespace Slic3r + +#endif