Files
OrcaSlicer/src/slic3r/GUI/Plater.hpp
T
SoftFever 4a32a9e066 Match mixed filament swatches to the editor's gradient preview
The sidebar Mixed Filament list, the extruder icons, the color painting
gizmo and the canvas filament bar now show the same bottom-to-top fade the
Edit Mixed Filament preview shows, custom gradient curves included, instead
of a horizontal fade between the two component colours. Ordinary and vendor
multi-colour filaments are drawn exactly as before.
2026-08-23 22:11:49 +08:00

1054 lines
42 KiB
C++

#ifndef slic3r_Plater_hpp_
#define slic3r_Plater_hpp_
#include <memory>
#include <vector>
#include <boost/filesystem/path.hpp>
#include <wx/colour.h>
#include <wx/panel.h>
// BBS
#include <wx/notebook.h>
#include "Selection.hpp"
#include "libslic3r/enum_bitmask.hpp"
#include "libslic3r/Preset.hpp"
#include "libslic3r/BoundingBox.hpp"
#include "libslic3r/GCode/GCodeProcessor.hpp"
#include "Jobs/Job.hpp"
#include "Jobs/Worker.hpp"
#include "Search.hpp"
#include "PartPlate.hpp"
#include "GUI_App.hpp"
#include "Jobs/PrintJob.hpp"
#include "Jobs/SendJob.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/PrintBase.hpp"
#include "libslic3r/calib.hpp"
#include "libslic3r/CutUtils.hpp"
#include "libslic3r/FlushVolCalc.hpp"
#define FILAMENT_SYSTEM_COLORS_NUM 16
class wxButton;
class ScalableButton;
class wxScrolledWindow;
class wxString;
class ComboBox;
class Button;
namespace Slic3r {
class BuildVolume;
enum class BuildVolume_Type : char;
class Model;
class ModelObject;
class ModelInstance;
class Print;
class SLAPrint;
//BBS: add partplatelist and SlicingStatusEvent
class PartPlateList;
class SlicingStatusEvent;
class BackgroundSlicingProcess;
enum SLAPrintObjectStep : unsigned int;
enum class ConversionType : int;
class DevAms;
using ModelInstancePtrs = std::vector<ModelInstance*>;
namespace UndoRedo {
class Stack;
enum class SnapshotType : unsigned char;
struct Snapshot;
}
namespace GUI {
class SyncAmsInfoDialog;
class MainFrame;
class ConfigOptionsGroup;
class ObjectSettings;
class ObjectLayers;
class ObjectList;
class GLCanvas3D;
class Mouse3DController;
class NotificationManager;
class DailyTipsWindow;
struct Camera;
class GLToolbar;
class PlaterPresetComboBox;
class PartPlateList;
class SyncNozzleAndAmsDialog;
class FinishSyncAmsDialog;
using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>;
class Plater;
enum class ActionButtonType : int;
// Sentinel filament id meaning "use the slot the sidebar context menu was opened on"
// (Sidebar::priv::m_menu_filament_id) rather than an explicit index.
inline constexpr int kSidebarContextMenuFilamentId = -2;
#define EVT_PUBLISHING_START 1
#define EVT_PUBLISHING_STOP 2
//BBS: add EVT_SLICING_UPDATE declare here
wxDECLARE_EVENT(EVT_SLICING_UPDATE, Slic3r::SlicingStatusEvent);
wxDECLARE_EVENT(EVT_PUBLISH, wxCommandEvent);
wxDECLARE_EVENT(EVT_OPEN_PLATESETTINGSDIALOG, wxCommandEvent);
// Explanation of int param
// Bit 0: 1 = automatic mode, 0 = manual mode.
// Bit 1: 1 = need auto slicing(from preview page), 0 = not need auto slicing.
wxDECLARE_EVENT(EVT_OPEN_FILAMENT_MAP_SETTINGS_DIALOG, wxCommandEvent);
wxDECLARE_EVENT(EVT_REPAIR_MODEL, wxCommandEvent);
wxDECLARE_EVENT(EVT_FILAMENT_COLOR_CHANGED, wxCommandEvent);
wxDECLARE_EVENT(EVT_INSTALL_PLUGIN_NETWORKING, wxCommandEvent);
wxDECLARE_EVENT(EVT_INSTALL_PLUGIN_HINT, wxCommandEvent);
wxDECLARE_EVENT(EVT_UPDATE_PLUGINS_WHEN_LAUNCH, wxCommandEvent);
wxDECLARE_EVENT(EVT_PREVIEW_ONLY_MODE_HINT, wxCommandEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_COLOR_MODE_CHANGED, SimpleEvent);
wxDECLARE_EVENT(EVT_PRINT_FROM_SDCARD_VIEW, SimpleEvent);
wxDECLARE_EVENT(EVT_CREATE_FILAMENT, SimpleEvent);
wxDECLARE_EVENT(EVT_MODIFY_FILAMENT, SimpleEvent);
wxDECLARE_EVENT(EVT_ADD_FILAMENT, SimpleEvent);
wxDECLARE_EVENT(EVT_DEL_FILAMENT, SimpleEvent);
wxDECLARE_EVENT(EVT_NOTICE_CHILDE_SIZE_CHANGED, SimpleEvent);
wxDECLARE_EVENT(EVT_NOTICE_FULL_SCREEN_CHANGED, IntEvent);
using ColorEvent = Event<wxColour>;
wxDECLARE_EVENT(EVT_ADD_CUSTOM_FILAMENT, ColorEvent);
const wxString DEFAULT_PROJECT_NAME = "Untitled";
class SidebarProps
{
public:
static int TitlebarMargin(){ return 8 ;} // Use as side margins on titlebar. Has less margin on sides to create separation with its content
static int ContentMargin() { return 12;} // Use as side margins contents of title
static int ContentMarginV(){ return 9 ;} // Use as vertical margins contents of title
static int IconSpacing() { return 10;} // Use on main elements in same group of controls
static int WideSpacing() { return 18;} // Use between main elements / control groups for separation or preventing accidental clicks important
static int ElementSpacing(){ return 5 ;} // Use if elements has relation between them like edit button for combo box etc.
};
class Sidebar : public wxPanel
{
ConfigOptionMode m_mode;
//Button * btn_sync{nullptr};
ScalableButton * ams_btn{nullptr};
bool m_last_slice_state = false;
SyncNozzleAndAmsDialog* m_sna_dialog{nullptr};
FinishSyncAmsDialog* m_fna_dialog{nullptr};
std::vector<BedType> m_cur_combox_bed_types;
std::string m_cur_image_bed_type;
int m_last_combo_bedtype_count{0};
bool m_begin_sync_printer_status{false};
SyncAmsInfoDialog* m_sync_dlg{nullptr};
void update_sync_ams_btn_enable(wxUpdateUIEvent &e);
public:
enum DockingState
{
None, Left, Right
};
Sidebar(Plater *parent);
Sidebar(Sidebar &&) = delete;
Sidebar(const Sidebar &) = delete;
Sidebar &operator=(Sidebar &&) = delete;
Sidebar &operator=(const Sidebar &) = delete;
~Sidebar();
void on_enter_image_printer_bed(wxMouseEvent &evt);
void on_leave_image_printer_bed(wxMouseEvent &evt);
void on_change_color_mode(bool is_dark);
void create_printer_preset();
void init_filament_combo(PlaterPresetComboBox **combo, const int filament_idx);
void remove_unused_filament_combos(const size_t current_extruder_count);
void update_all_preset_comboboxes();
//void update_partplate(PartPlateList& list);
void update_presets(Slic3r::Preset::Type preset_type);
//BBS
const std::vector<BedType>& get_cur_combox_bed_types() { return m_cur_combox_bed_types; }
void update_presets_from_to(Slic3r::Preset::Type preset_type, std::string from, std::string to);
BedType get_cur_select_bed_type();
std::string get_cur_select_bed_image();
void set_bed_type_accord_combox(BedType bed_type);
bool reset_bed_type_combox_choices(bool is_sidebar_init = false);
void change_top_border_for_mode_sizer(bool increase_border);
void update_filaments_area_height();
void update_filaments_counter(bool force_layout = false);
void msw_rescale();
void sys_color_changed();
void search();
void jump_to_option(size_t selected);
void jump_to_option(const std::string& opt_key, Preset::Type type, const std::wstring& category);
// BBS. Add filament_added() method.
void on_filament_count_change(size_t num_filaments);
void on_filaments_delete(size_t filament_id);
void add_filament();
void delete_filament(size_t filament_id = size_t(-1), int replace_filament_id = -1); // 0 base, -1 means default
void change_filament(size_t from_id, size_t to_id); // 0 base
void edit_filament();
void add_custom_filament(wxColour new_col, const std::string& preset_name = std::string(), bool skip_preset_validation = false);
bool is_new_project_in_gcode3mf();
// BBS
void on_bed_type_change(BedType bed_type);
void load_ams_list(MachineObject* obj);
std::map<int, DynamicPrintConfig> build_filament_ams_list(MachineObject* obj);
void sync_ams_list(bool is_from_big_sync_btn = false);
bool sync_extruder_list();
bool is_fila_switch_ready();
void reset_fila_switch();
bool need_auto_sync_extruder_list_after_connect_priner(const MachineObject* obj);
void update_sync_status(const MachineObject* obj);
int get_sidebar_pos_right_x();
void on_size(SimpleEvent &e);
void on_full_screen(IntEvent &);
void get_big_btn_sync_pos_size(wxPoint &pt, wxSize &size);
void get_small_btn_sync_pos_size(wxPoint &pt, wxSize &size);
// Orca
static bool should_show_SEMM_buttons();
void show_SEMM_buttons();
void enable_purge_mode_btn(bool enable);
// Sidebar nozzle-count badge on the extruder cards (multi-nozzle printers only).
void set_extruder_nozzle_count(int extruder_id, int nozzle_count);
void enable_nozzle_count_edit(bool enable);
void update_dynamic_filament_list();
PlaterPresetComboBox * printer_combox();
ObjectList* obj_list();
ObjectSettings* obj_settings();
ObjectLayers* obj_layers();
wxPanel* scrolled_panel();
wxPanel* print_panel();
wxPanel* filament_panel();
ConfigOptionsGroup* og_freq_chng_params(const bool is_fff);
wxButton* get_wiping_dialog_button();
void set_flushing_volume_warning(const bool flushing_volume_modify);
// BBS
void enable_buttons(bool enable);
void set_btn_label(const ActionButtonType btn_type, const wxString& label) const;
bool show_reslice(bool show) const;
bool show_export(bool show) const;
bool show_send(bool show) const;
bool show_eject(bool show)const;
bool show_export_removable(bool show) const;
bool get_eject_shown() const;
bool is_multifilament();
void deal_btn_sync();
void pop_sync_nozzle_and_ams_dialog();
void pop_finsish_sync_ams_dialog();
void update_mode();
bool is_collapsed();
void collapse(bool collapse);
void update_searcher();
void update_ui_from_settings();
bool show_object_list(bool show) const;
void finish_param_edit();
/**
* @brief Automatically calculates flushing volumes
* @param filament_idx Specifies the filament index to calculate. -1 indicates all filament indices.
* @param extruder_id Specifies the extruder id to calculate. -1 indicates all extruders indices.
*/
void auto_calc_flushing_volumes(const int filament_idx = -1, const int extruder_id = -1);
void jump_to_object(ObjectDataViewModelNode* item);
void can_search();
#ifdef _MSW_DARK_MODE
void show_mode_sizer(bool show);
#endif
std::vector<PlaterPresetComboBox*>& combos_filament();
void clear_combos_filament_badge();
void udpate_combos_filament_badge();
// Mixed-color filament sidebar section
void add_mixed_filament();
void edit_mixed_filament(size_t idx);
void delete_mixed_filament_at(size_t idx);
void decompose_filament_color(int filament_idx);
void recalc_filament_scroll_sizes();
void update_mixed_filament_list();
bool has_broken_mixed_filament() const;
bool has_broken_mixed_filament(const PartPlate* plate) const;
void collect_physical_filament_info(std::vector<std::string>& color_strs,
std::vector<std::string>& names,
std::vector<std::string>& types,
std::vector<size_t>* config_indices = nullptr);
Search::OptionsSearcher& get_searcher();
std::string& get_search_line();
void update_printer_thumbnail();
bool need_auto_sync_after_connect_printer() const { return m_need_auto_sync_after_connect_printer; }
void set_need_auto_sync_after_connect_printer(bool need_auto_sync) { m_need_auto_sync_after_connect_printer = need_auto_sync; }
private:
void auto_calc_flushing_volumes_internal(const int filament_id, const int extruder_id);
private:
struct priv;
std::unique_ptr<priv> p;
wxBoxSizer* m_scrolled_sizer = nullptr;
bool m_need_auto_sync_after_connect_printer{false};
};
class Plater: public wxPanel
{
public:
using fs_path = boost::filesystem::path;
Plater(wxWindow *parent, MainFrame *main_frame);
Plater(Plater &&) = delete;
Plater(const Plater &) = delete;
Plater &operator=(Plater &&) = delete;
Plater &operator=(const Plater &) = delete;
~Plater();
bool Show(bool show = true);
bool is_project_dirty() const;
bool is_presets_dirty() const;
void set_plater_dirty(bool is_dirty);
void update_project_dirty_from_presets();
int save_project_if_dirty(const wxString& reason);
void reset_project_dirty_after_save();
void reset_project_dirty_initial_presets();
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
void render_project_state_debug_window() const;
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
Sidebar& sidebar();
const Model& model() const;
Model& model();
const Print& fff_print() const;
Print& fff_print();
const SLAPrint& sla_print() const;
SLAPrint& sla_print();
// Helper: returns config indices where filament_is_mixed == true
std::vector<size_t> mixed_filament_config_indices() const;
// Helper: returns config indices where filament_is_mixed == false
std::vector<size_t> physical_filament_config_indices() const;
int new_project(bool skip_confirm = false, bool silent = false, const wxString& project_name = wxString());
// BBS: save & backup
void load_project(wxString const & filename = "", wxString const & originfile = "-");
int save_project(bool saveAs = false);
//BBS download project by project id
void import_model_id(wxString download_info);
void download_project(const wxString& project_id);
void request_model_download(wxString url);
void request_download_project(std::string project_id);
// BBS: check snapshot
bool up_to_date(bool saved, bool backup);
bool open_3mf_file(const fs::path &file_path);
int get_3mf_file_count(std::vector<fs::path> paths);
void add_file();
// Returns false when no object was added (e.g. the user cancelled the load dialog).
bool add_model(bool imperial_units = false, std::string fname = "");
void import_zip_archive();
void import_sl1_archive();
void extract_config_from_project();
void load_gcode();
void load_gcode(const wxString& filename);
void reload_gcode_from_disk();
void reload_print();
// SoftFever
void calib_pa(const Calib_Params& params);
//ORCA: Add pattern parameter to calib_flowrate
void calib_flowrate(bool is_linear, int pass, InfillPattern pattern = ipArchimedeanChords);
void calib_temp(const Calib_Params& params);
void calib_max_vol_speed(const Calib_Params& params);
void calib_retraction(const Calib_Params& params);
void calib_VFA(const Calib_Params& params);
void calib_input_shaping_freq(const Calib_Params& params);
void calib_input_shaping_damp(const Calib_Params& params);
void Calib_Cornering(const Calib_Params& params);
BuildVolume_Type get_build_volume_type() const;
//BBS: add only gcode mode
bool is_gcode_3mf() { return m_exported_file; }
bool only_gcode_mode() { return m_only_gcode; }
void set_only_gcode(bool only_gcode) { m_only_gcode = only_gcode; }
//BBS: add only gcode mode
bool using_exported_file() { return m_exported_file; }
void set_using_exported_file(bool exported_file) {
m_exported_file = exported_file;
}
bool is_empty_project();
bool is_multi_extruder_ams_empty();
// BBS
bool is_new_project_and_check_state() { return m_new_project_and_check_state; }
wxString get_project_name();
void update_all_plate_thumbnails(bool force_update = false);
void update_obj_preview_thumbnail(ModelObject *, int obj_idx, int vol_idx, std::vector<Slic3r::ColorRGBA> colors, int camera_view_angle_type);
void invalid_all_plate_thumbnails();
void force_update_all_plate_thumbnails();
const VendorProfile::PrinterModel * get_curr_printer_model();
std::map<std::string, std::string> get_bed_texture_maps();
bool get_enable_wrapping_detection();
static wxColour get_next_color_for_filament();
static wxString get_slice_warning_string(GCodeProcessorResult::SliceWarning& warning);
bool preview_zip_archive(const boost::filesystem::path& archive_path);
// BBS: restore
std::vector<size_t> load_files(const std::vector<boost::filesystem::path>& input_files, LoadStrategy strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig, bool ask_multi = false);
// To be called when providing a list of files to the GUI slic3r on command line.
std::vector<size_t> load_files(const std::vector<std::string>& input_files, LoadStrategy strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig, bool ask_multi = false);
// to be called on drag and drop
bool load_files(const wxArrayString& filenames);
const wxString& get_last_loaded_gcode() const { return m_last_loaded_gcode; }
void update(bool conside_update_flag = false, bool force_background_processing_update = false);
//BBS
void object_list_changed();
// Get the worker handling the UI jobs (arrange, fill bed, etc...)
// Here is an example of starting up an ad-hoc job:
// queue_job(
// get_ui_job_worker(),
// [](Job::Ctl &ctl) {
// // Executed in the worker thread
//
// CursorSetterRAII cursor_setter{ctl};
// std::string msg = "Running";
//
// ctl.update_status(0, msg);
// for (int i = 0; i < 100; i++) {
// usleep(100000);
// if (ctl.was_canceled()) break;
// ctl.update_status(i + 1, msg);
// }
// ctl.update_status(100, msg);
// },
// [](bool, std::exception_ptr &e) {
// // Executed in UI thread after the work is done
//
// try {
// if (e) std::rethrow_exception(e);
// } catch (std::exception &e) {
// BOOST_LOG_TRIVIAL(error) << e.what();
// }
// e = nullptr;
// });
// This would result in quick run of the progress indicator notification
// from 0 to 100. Use replace_job() instead of queue_job() to cancel all
// pending jobs.
Worker& get_ui_job_worker();
const Worker & get_ui_job_worker() const;
void select_view(const std::string& direction);
//BBS: add no_slice logic
void select_view_3D(const std::string& name, bool no_slice = true);
void reload_paint_after_background_process_apply();
bool is_preview_shown() const;
bool is_preview_loaded() const;
bool is_view3D_shown() const;
bool are_view3D_labels_shown() const;
void show_view3D_labels(bool show);
bool is_view3D_overhang_shown() const;
void show_view3D_overhang(bool show);
bool is_sidebar_enabled() const;
void enable_sidebar(bool enabled);
bool is_sidebar_collapsed() const;
void collapse_sidebar(bool collapse);
Sidebar::DockingState get_sidebar_docking_state() const;
void reset_window_layout();
// Called after the Preferences dialog is closed and the program settings are saved.
// Update the UI based on the current preferences.
void update_ui_from_settings();
//BBS
void select_curr_plate_all();
void remove_curr_plate_all();
void select_all();
void deselect_all();
void exit_gizmo();
void remove(size_t obj_idx);
void reset(bool apply_presets_change = false);
void reset_with_confirm();
//BBS: return int for various result
int close_with_confirm(std::function<bool(bool yes_or_no)> second_check = nullptr); // BBS close project
//BBS: trigger a restore project event
void trigger_restore_project(int skip_confirm = 0);
bool delete_object_from_model(size_t obj_idx, bool refresh_immediately = true); // BBS support refresh immediately
void delete_all_objects_from_model(); //BBS delete all objects from model
void set_selected_visible(bool visible);
void remove_selected();
void increase_instances(size_t num = 1);
void decrease_instances(size_t num = 1);
void set_number_of_copies(/*size_t num*/);
void fill_bed_with_copies();
void fill_bed_with_instances();
bool is_selection_empty() const;
void scale_selection_to_fit_print_volume();
void convert_unit(ConversionType conv_type);
// BBS: replace z with plane_points
void cut(size_t obj_idx, size_t instance_idx, std::array<Vec3d, 4> plane_points, ModelObjectCutAttributes attributes);
// BBS: segment model with CGAL
void segment(size_t obj_idx, size_t instance_idx, double smoothing_alpha=0.5, int segment_number=5);
void apply_cut_object_to_model(size_t init_obj_idx, const ModelObjectPtrs& cut_objects);
void merge(size_t obj_idx, std::vector<int> &vol_indeces);
void send_to_printer(bool isall = false);
void export_gcode(bool prefer_removable);
void export_gcode_3mf(bool export_all = false);
void send_gcode_finish(wxString name);
void export_core_3mf();
static TriangleMesh combine_mesh_fff(const ModelObject& mo, int instance_id, std::function<void(const std::string&)> notify_func = {});
void export_stl(bool extended = false, bool selection_only = false, bool multi_stls = false, FileType file_type = FT_STL);
//BBS: remove amf
//void export_amf();
//BBS add extra param for exporting 3mf silence
// BBS: backup
int export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path(), SaveStrategy strategy = SaveStrategy::Default, int export_plate_idx = -1, Export3mfProgressFn proFn = nullptr);
//BBS
void publish_project();
void reload_from_disk();
void replace_with_stl();
void replace_all_with_stl();
void reload_all_from_disk();
bool has_toolpaths_to_export() const;
void export_toolpaths_to_obj() const;
void reslice();
void record_slice_preset(std::string action);
void reslice_SLA_supports(const ModelObject &object, bool postpone_error_messages = false);
void reslice_SLA_hollowing(const ModelObject &object, bool postpone_error_messages = false);
void reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &object, bool postpone_error_messages = false);
void clear_before_change_mesh(int obj_idx);
void changed_mesh(int obj_idx);
void changed_object(ModelObject &object);
void changed_object(int obj_idx);
void changed_objects(const std::vector<size_t>& object_idxs);
void schedule_background_process(bool schedule = true);
bool is_background_process_update_scheduled() const;
void suppress_background_process(const bool stop_background_process) ;
// Expose the slicing process so the device GUI can read the current
// GCodeProcessorResult (e.g. the nozzle grouping for print-dispatch mapping).
BackgroundSlicingProcess& background_process();
/* -1: send current gcode if not specified
* -2: send all gcode to target machine */
int send_gcode(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
void send_gcode_legacy(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
int export_config_3mf(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
//BBS jump to nonitor after print job finished
void send_calibration_job_finished(wxCommandEvent &evt);
void print_job_finished(wxCommandEvent &evt);
void send_job_finished(wxCommandEvent& evt);
void publish_job_finished(wxCommandEvent& evt);
void open_platesettings_dialog(wxCommandEvent& evt);
void open_filament_map_setting_dialog(wxCommandEvent &evt);
void on_change_color_mode(SimpleEvent& evt);
void eject_drive();
void take_snapshot(const std::string &snapshot_name);
//void take_snapshot(const wxString &snapshot_name);
void take_snapshot(const std::string &snapshot_name, UndoRedo::SnapshotType snapshot_type);
//void take_snapshot(const wxString &snapshot_name, UndoRedo::SnapshotType snapshot_type);
void undo();
void redo();
void undo_to(int selection);
void redo_to(int selection);
bool undo_redo_string_getter(const bool is_undo, int idx, const char** out_text);
void undo_redo_topmost_string_getter(const bool is_undo, std::string& out_text);
int update_print_required_data(Slic3r::DynamicPrintConfig config, Slic3r::Model model, Slic3r::PlateDataPtrs plate_data_list, std::string file_name, std::string file_path);
bool search_string_getter(int idx, const char** label, const char** tooltip);
// For the memory statistics.
const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const;
void clear_undo_redo_stack_main();
// Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo.
void enter_gizmos_stack();
// BBS: return false if not changed
bool leave_gizmos_stack();
void on_filament_change(size_t filament_idx);
void on_filament_count_change(size_t extruders_count);
void on_filaments_delete(size_t extruders_count, size_t filament_id, int replace_filament_id = -1, const std::vector<unsigned char>& is_mixed_before_delete = {});
std::vector<Slic3r::ColorRGBA> get_extruders_colors();
// BBS
void on_bed_type_change(BedType bed_type);
bool update_filament_colors_in_full_config();
void config_change_notification(const DynamicPrintConfig &config, const std::string& key);
void on_config_change(const DynamicPrintConfig &config);
void force_filament_colors_update();
void force_print_bed_update();
// On activating the parent window.
void on_activate();
std::vector<std::string> get_extruder_colors_from_plater_config(const GCodeProcessorResult* const result = nullptr) const;
std::vector<std::string> get_filament_colors_render_info() const;
std::vector<std::string> get_filament_color_render_type() const;
// Per slot, the colours a gradient mixed filament actually prints, sampled bottom (index 0)
// to top, so the sidebar, the paint gizmo and the extruder icons draw the same fade the
// editor previews rather than a straight blend of two endpoints. A slot that is not a
// gradient mixed filament gets an empty ramp. Cached; recomputed when the config changes.
const std::vector<std::vector<wxColour>>& get_filament_gradient_ramps() const;
std::vector<std::string> get_colors_for_color_print(const GCodeProcessorResult* const result = nullptr) const;
void set_global_filament_map_mode(FilamentMapMode mode);
void set_global_filament_map(const std::vector<int>& filament_map);
void set_global_filament_volume_map(const std::vector<int>& filament_volume_map);
std::vector<int> get_global_filament_map() const;
std::vector<int> get_global_filament_volume_map() const;
FilamentMapMode get_global_filament_map_mode() const;
void update_menus();
wxString get_selected_printer_name_in_combox();
enum class PrinterWarningType {
NOT_CONNECTED,
INCONSISTENT,
UNINSTALL_FILAMENT,
EMPTY_FILAMENT
};
void pop_warning_and_go_to_device_page(wxString printer_name, PrinterWarningType type, const wxString &title);
bool check_printer_initialized(MachineObject *obj, bool only_warning = false,bool popup_warning = true);
bool is_same_printer_for_connected_and_selected(bool popup_warning = true);
// BBS
//void show_action_buttons(const bool is_ready_to_slice) const;
wxString get_project_filename(const wxString& extension = wxEmptyString) const;
wxString get_export_gcode_filename(const wxString& extension = wxEmptyString, bool only_filename = false, bool export_all = false) const;
void set_project_filename(const wxString& filename);
void update_print_error_info(int code, std::string msg, std::string extra);
bool is_export_gcode_scheduled() const;
const Selection& get_selection() const;
int get_selected_object_idx();
bool is_single_full_object_selection() const;
GLCanvas3D* canvas3D();
const GLCanvas3D * canvas3D() const;
GLCanvas3D* get_current_canvas3D(bool exclude_preview = false);
GLCanvas3D* get_view3D_canvas3D();
GLCanvas3D* get_preview_canvas3D();
GLCanvas3D* get_assmeble_canvas3D();
wxWindow* get_select_machine_dialog();
void arrange();
void orient();
void find_new_position(const ModelInstancePtrs &instances);
//BBS: add job state related functions
void set_prepare_state(int state);
int get_prepare_state();
//BBS: add print job releated functions
void get_print_job_data(PrintPrepareData* data);
void set_print_job_plate_idx(int plate_idx);
int get_send_calibration_finished_event();
int get_print_finished_event();
int get_send_finished_event();
int get_publish_finished_event();
void set_current_canvas_as_dirty();
void unbind_canvas_event_handlers();
void reset_canvas_volumes();
PrinterTechnology printer_technology() const;
const DynamicPrintConfig * config() const;
bool set_printer_technology(PrinterTechnology printer_technology);
//BBS
void cut_selection_to_clipboard();
void copy_selection_to_clipboard();
void paste_from_clipboard();
//BBS: add clone logic
void clone_selection();
void center_selection();
void drop_selection();
void search(bool plater_is_active, Preset::Type type, wxWindow *tag, TextInput *etag, wxWindow *stag);
void mirror(Axis axis);
void split_object(bool auto_drop = true);
void split_object(int obj_idx, bool auto_drop = true);
void split_volume();
void optimize_rotation();
// find all empty cells on the plate and won't overlap with exclusion areas
static std::vector<Vec2f> get_empty_cells(const Vec2f step);
//BBS:
void fill_color(int extruder_id);
std::string get_3mf_filename() { return m_3mf_path; };
bool can_delete() const;
bool can_delete_all() const;
bool can_add_model() const;
bool can_add_plate() const;
bool can_delete_plate() const;
bool can_increase_instances() const;
bool can_decrease_instances() const;
bool can_set_instance_to_object() const;
bool can_fix_through_cgal() const;
bool can_simplify() const;
bool can_smooth_mesh() const;
bool can_split_to_objects() const;
bool can_split_to_volumes() const;
bool can_arrange() const;
//BBS
bool can_cut_to_clipboard() const;
bool can_layers_editing() const;
bool can_paste_from_clipboard() const;
bool can_copy_to_clipboard() const;
bool can_undo() const;
bool can_redo() const;
bool can_reload_from_disk() const;
bool can_replace_with_stl() const;
bool can_replace_all_with_stl() const;
bool can_mirror() const;
bool can_split(bool to_objects) const;
#if ENABLE_ENHANCED_PRINT_VOLUME_FIT
bool can_scale_to_print_volume() const;
#endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT
//BBS:
bool can_fillcolor() const;
bool has_assmeble_view() const;
void msw_rescale();
void sys_color_changed();
// BBS
#if 0
bool init_view_toolbar();
void enable_view_toolbar(bool enable);
#endif
bool init_collapse_toolbar();
const Camera& get_camera() const;
Camera& get_camera();
//BBS: partplate list related functions
PartPlateList& get_partplate_list();
void validate_current_plate(bool& model_fits, bool& validate_error);
// Rebuild the missing-plugin sets from the active presets and (re)show/close their notifications.
// Returns true when slicing must be blocked (a referenced plugin is still missing); sets
// *block_toggled when the blocked state changed since the previous call (so the caller can refresh
// the Slice button). Helper for validate_current_plate and the reslice() gate.
bool refresh_missing_plugin_block(bool* block_toggled = nullptr);
// Re-run plate validation when a plugin finishes loading, but only while a missing-plugin
// notification is active, so it clears automatically once the required plugin is available.
void revalidate_current_plate_if_plugins_missing();
// Install the given missing cloud plugin refs, showing an app-modal pulsing progress dialog
// (Cancel stops before the next plugin). Runs the blocking install on a worker thread; the
// dialog is driven from the UI thread. Clears the missing-plugin notification once resolved.
void install_missing_cloud_plugins(const std::vector<std::string>& cloud_refs);
// Activate the given inactive plugin refs (load the plugin / enable the capability). No progress
// dialog; the loads run on a background worker that re-validates the plate once they settle, so
// the notification clears (or flips to broken if the plugin lacks the capability).
void enable_inactive_plugins(const std::vector<std::string>& refs);
// True when the active preset references plugins that are missing and not yet acknowledged, as
// of the last validate_current_plate. Other slice-ready writers consult this to stay consistent.
bool plugins_block_slicing() const;
//BBS: select the plate by index
int select_plate(int plate_index, bool need_slice = false);
//BBS: update progress result
void apply_background_progress();
//BBS: select the plate by hover_id
int select_plate_by_hover_id(int hover_id, bool right_click = false, bool isModidyPlateName = false);
//BBS: delete the plate, index= -1 means the current plate
int delete_plate(int plate_index = -1);
int duplicate_plate(int plate_index = -1);
//BBS: select the sliced plate by index
int select_sliced_plate(int plate_index, bool skip_zoom = false);
//BBS: set bed positions
void set_bed_position(Vec2d& pos);
//BBS: is the background process slicing currently
bool is_background_process_slicing() const;
//BBS: update slicing context
void update_slicing_context_to_current_partplate();
//BBS: show object info
void show_object_info();
//BBS
bool show_publish_dialog(bool show = true);
//BBS: post process string object exception strings by warning types
void post_process_string_object_exception(StringObjectException &err);
void update_objects_position_when_select_preset(const std::function<void()> &select_prest);
bool check_ams_status(bool is_slice_all);
// only check sync status and printer model id
bool get_machine_sync_status();
void update_machine_sync_status();
// Rewrite every plate's per-filament volume choice for the filaments grouped onto this
// extruder after its Flow type changed (Hybrid resets them to Standard so the user
// re-assigns concrete volumes in the grouping dialog).
void update_filament_volume_map(int extruder_id, int volume_type);
#if ENABLE_ENVIRONMENT_MAP
void init_environment_texture();
unsigned int get_environment_texture_id() const;
#endif // ENABLE_ENVIRONMENT_MAP
const BuildVolume& build_volume() const;
// BBS
//const GLToolbar& get_view_toolbar() const;
//GLToolbar& get_view_toolbar();
const GLToolbar& get_collapse_toolbar() const;
GLToolbar& get_collapse_toolbar();
void update_preview_bottom_toolbar();
void update_preview_moves_slider();
void enable_preview_moves_slider(bool enable);
#if 0
void update_partplate();
#endif
void reset_gcode_toolpaths();
void reset_last_loaded_gcode() { m_last_loaded_gcode = ""; }
const Mouse3DController& get_mouse3d_controller() const;
Mouse3DController& get_mouse3d_controller();
//BBS: update when switch muilti_extruder printer
void update_flush_volume_matrix(size_t old_nozzle_size, size_t new_nozzle_size);
//BBS: add bed exclude area
void set_bed_shape() const;
void set_bed_shape(const Pointfs &shape,
const Pointfs &exclude_area,
const Pointfs &wrapping_exclude_area,
const double printable_height,
std::vector<Pointfs> extruder_areas,
std::vector<double> extruder_heights,
const std::string &custom_texture,
const std::string &custom_model,
bool force_as_custom = false) const;
const NotificationManager* get_notification_manager() const;
NotificationManager* get_notification_manager();
DailyTipsWindow* get_dailytips() const;
//BBS: show message in status bar
void show_status_message(std::string s);
void init_notification_manager();
void bring_instance_forward();
bool need_update() const;
void set_need_update(bool need_update);
void update_title_dirty_status();
// ROII wrapper for suppressing the Undo / Redo snapshot to be taken.
class SuppressSnapshots
{
public:
SuppressSnapshots(Plater *plater) : m_plater(plater)
{
m_plater->suppress_snapshots();
}
~SuppressSnapshots()
{
m_plater->allow_snapshots();
}
private:
Plater *m_plater;
};
// RAII wrapper for taking an Undo / Redo snapshot while disabling the snapshot taking by the methods called from inside this snapshot.
class TakeSnapshot
{
public:
TakeSnapshot(Plater *plater, const std::string &snapshot_name) : m_plater(plater)
{
m_plater->take_snapshot(snapshot_name);
m_plater->suppress_snapshots();
}
/*TakeSnapshot(Plater *plater, const wxString &snapshot_name) : m_plater(plater)
{
m_plater->take_snapshot(snapshot_name);
m_plater->suppress_snapshots();
}*/
TakeSnapshot(Plater* plater, const std::string& snapshot_name, UndoRedo::SnapshotType snapshot_type) : m_plater(plater)
{
m_plater->take_snapshot(snapshot_name, snapshot_type);
m_plater->suppress_snapshots();
}
/*TakeSnapshot(Plater *plater, const wxString &snapshot_name, UndoRedo::SnapshotType snapshot_type) : m_plater(plater)
{
m_plater->take_snapshot(snapshot_name, snapshot_type);
m_plater->suppress_snapshots();
}*/
~TakeSnapshot()
{
m_plater->allow_snapshots();
}
private:
Plater *m_plater;
};
// BBS: limit to single snapshot taking by the methods called from inside
// this snapshot.
class SingleSnapshot
{
public:
SingleSnapshot(Plater *plater) : m_plater(plater)
{
m_plater->single_snapshots_enter(this);
}
~SingleSnapshot() { m_plater->single_snapshots_leave(this); }
bool check(bool modify)
{
if (token && (this->modify || !modify)) return false;
token = true;
this->modify = modify;
return true;
}
private:
Plater *m_plater;
bool token = false;
bool modify = false;
};
bool inside_snapshot_capture();
void toggle_render_statistic_dialog();
bool is_render_statistic_dialog_visible() const;
void toggle_show_wireframe();
bool is_show_wireframe() const;
void enable_wireframe(bool status);
bool is_wireframe_enabled() const;
// Wrapper around wxWindow::PopupMenu to suppress error messages popping out while tracking the popup menu.
bool PopupMenu(wxMenu *menu, const wxPoint& pos = wxDefaultPosition);
bool PopupMenu(wxMenu *menu, int x, int y) { return this->PopupMenu(menu, wxPoint(x, y)); }
//BBS: add popup logic for table object
bool PopupObjectTable(int object_id, int volume_id, const wxPoint& position);
//BBS: popup selection at default position
bool PopupObjectTableBySelection();
// get same Plater/ObjectList menus
wxMenu* plate_menu();
wxMenu* object_menu();
wxMenu* part_menu();
wxMenu* text_part_menu();
wxMenu* svg_part_menu();
wxMenu* sla_object_menu();
wxMenu* default_menu();
wxMenu* instance_menu();
wxMenu* layer_menu();
wxMenu* multi_selection_menu();
wxMenu* filament_action_menu(int active_filament_menu_id);
int GetPlateIndexByRightMenuInLeftUI();
void SetPlateIndexByRightMenuInLeftUI(int);
static bool has_illegal_filename_characters(const wxString& name);
static bool has_illegal_filename_characters(const std::string& name);
static void show_illegal_characters_warning(wxWindow* parent);
std::string get_preview_only_filename() { return m_preview_only_filename; };
bool last_arrange_job_is_finished()
{
bool prevRunning = false;
return m_arrange_running.compare_exchange_strong(prevRunning, true);
};
std::atomic<bool> m_arrange_running{false};
void reset_check_status() { m_check_status = 0; }
bool is_loading_project() const { return m_loading_project; }
void mark_plate_toolbar_image_dirty();
bool is_plate_toolbar_image_dirty() const;
void clear_plate_toolbar_image_dirty();
private:
struct priv;
std::unique_ptr<priv> p;
std::string m_3mf_path;
// Set true during PopupMenu() tracking to suppress immediate error message boxes.
// The error messages are collected to m_tracking_popup_menu_error_message instead and these error messages
// are shown after the pop-up dialog closes.
bool m_tracking_popup_menu = false;
wxString m_tracking_popup_menu_error_message;
wxString m_last_loaded_gcode;
//BBS: add only gcode mode
bool m_only_gcode { false };//just for .gcode file not for .gcode.3mf
bool m_exported_file { false };
bool skip_thumbnail_invalid { false };
bool m_loading_project { false };
bool m_new_project_and_check_state{false};
std::string m_preview_only_filename;
int m_valid_plates_count { 0 };
int m_check_status = 0; // 0 not check, 1 check success, 2 check failed
bool m_b_plate_toolbar_image_dirty{ true };
void suppress_snapshots();
void allow_snapshots();
// BBS: single snapshot
void single_snapshots_enter(SingleSnapshot *single);
void single_snapshots_leave(SingleSnapshot *single);
// BBS: add project slice related functions
int start_next_slice();
void _calib_pa_pattern(const Calib_Params& params);
void _calib_pa_pattern_gen_gcode();
void _calib_pa_tower(const Calib_Params& params);
void _calib_pa_select_added_objects();
void cut_horizontal(size_t obj_idx, size_t instance_idx, double z, ModelObjectCutAttributes attributes);
void on_filament_map_mode_change();
friend class SuppressBackgroundProcessingUpdate;
friend class PlaterDropTarget;
};
class SuppressBackgroundProcessingUpdate
{
public:
SuppressBackgroundProcessingUpdate();
~SuppressBackgroundProcessingUpdate();
private:
bool m_was_scheduled;
};
std::vector<int> get_min_flush_volumes(const DynamicPrintConfig &full_config, size_t nozzle_id);
Preset *get_printer_preset(const MachineObject *obj);
wxArrayString get_all_camera_view_type();
} // namespace GUI
} // namespace Slic3r
#endif