OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GUI::Plater Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/Plater.hpp>

Inheritance diagram for Slic3r::GUI::Plater:
Collaboration diagram for Slic3r::GUI::Plater:

Classes

struct  ImexGhostTooltip
class  SuppressSnapshots
class  TakeSnapshot
class  SingleSnapshot
struct  priv

Public Types

enum class  PrinterWarningType { NOT_CONNECTED , INCONSISTENT , UNINSTALL_FILAMENT , EMPTY_FILAMENT }

Public Member Functions

 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 ()
void normalize_bed_types (bool printer_setting_changed)
int save_project_if_dirty (const wxString &reason)
void reset_project_dirty_after_save ()
void reset_project_dirty_initial_presets ()
Sidebar & sidebar ()
const Model & model () const
Model & model ()
const Print & fff_print () const
Print & fff_print ()
const SLAPrint & sla_print () const
SLAPrint & sla_print ()
std::vector< size_t > mixed_filament_config_indices () const
std::vector< size_t > physical_filament_config_indices () const
int new_project (bool skip_confirm=false, bool silent=false, const wxString &project_name=wxString(), bool reload_presets=true)
void load_project (wxString const &filename="", wxString const &originfile="-")
int save_project (bool saveAs=false)
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)
bool up_to_date (bool saved, bool backup)
bool open_3mf_file (const boost::filesystem::path &file_path)
int get_3mf_file_count (std::vector< boost::filesystem::path > paths)
void add_file ()
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 ()
void refresh_belt_view ()
void calib_pa (const Calib_Params &params)
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
bool is_gcode_3mf ()
bool only_gcode_mode ()
void set_only_gcode (bool only_gcode)
bool gcode_settings_loaded () const
bool using_exported_file ()
void set_using_exported_file (bool exported_file)
bool is_empty_project ()
bool is_multi_extruder_ams_empty ()
bool is_new_project_and_check_state ()
wxString get_project_name ()
void update_all_plate_thumbnails (bool force_update=false)
void update_plate_thumbnails (int plate_idx, bool force_update)
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 ()
bool preview_zip_archive (const boost::filesystem::path &archive_path)
std::vector< size_t > load_files (const std::vector< boost::filesystem::path > &input_files, LoadStrategy strategy=LoadStrategy::LoadModel|LoadStrategy::LoadConfig, bool ask_multi=false, bool *published_out=nullptr)
bool load_files (const wxArrayString &filenames)
const wxString & get_last_loaded_gcode () const
void update (bool conside_update_flag=false, bool force_background_processing_update=false)
void object_list_changed ()
Worker & get_ui_job_worker ()
const Worker & get_ui_job_worker () const
void select_view (const std::string &direction)
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 are_collision_volumes_shown () const
void show_collision_volumes (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 ()
void add_dock_pane (wxWindow *window, const std::string &name, const wxString &caption, const std::string &dock, const wxSize &size, std::function< void()> on_close)
void remove_dock_pane (wxWindow *window)
void show_dock_pane (wxWindow *window, bool show)
void remove_dock_panes ()
void update_ui_from_settings ()
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, bool reload_presets=true)
void reset_with_confirm ()
int close_with_confirm (std::function< bool(bool yes_or_no)> second_check=nullptr)
void trigger_restore_project (int skip_confirm=0)
bool delete_object_from_model (size_t obj_idx, bool refresh_immediately=true)
void 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 ()
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)
void cut (size_t obj_idx, size_t instance_idx, std::array< Vec3d, 4 > plane_points, ModelObjectCutAttributes attributes)
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 ()
bool export_3mf_copy (const boost::filesystem::path &output_path)
int export_published_3mf (const std::vector< std::string > &published_keys, const std::vector< Slic3r::PublishedMaterialEntry > &material_keys)
bool get_pending_published (std::vector< std::string > &out_keys, std::vector< Slic3r::PublishedMaterialEntry > &out_material) const
void set_pending_published (const std::vector< std::string > &published_keys, const std::vector< Slic3r::PublishedMaterialEntry > &material_keys)
void export_stl (bool extended=false, bool selection_only=false, bool multi_stls=false, FileType file_type=FT_STL)
int export_3mf (const boost::filesystem::path &output_path=boost::filesystem::path(), SaveStrategy strategy=SaveStrategy::Default, int export_plate_idx=-1, Export3mfProgressFn proFn=nullptr)
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 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 notify_painting_removed ()
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)
BackgroundSlicingProcess & background_process ()
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)
void send_calibration_job_finished (wxCommandEvent &evt)
void print_job_finished (wxCommandEvent &evt)
void send_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 std::string &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)
const Slic3r::UndoRedo::Stack & undo_redo_stack_main () const
void clear_undo_redo_stack_main ()
void enter_gizmos_stack ()
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 ()
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 ()
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
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 ()
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)
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 ()
class UVEditorCanvas * get_uv_editor_canvas ()
void show_uv_editor (bool show)
void arrange ()
void orient ()
void find_new_position (const ModelInstancePtrs &instances)
void set_prepare_state (int state)
int get_prepare_state ()
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 ()
void set_current_canvas_as_dirty ()
void unbind_canvas_event_handlers ()
void reset_canvas_volumes ()
void on_imex_ghost_click (int physical_head)
ImexGhostTooltip format_imex_ghost_tooltip (int physical_head) const
PrinterTechnology printer_technology () const
const DynamicPrintConfig * config () const
bool set_printer_technology (PrinterTechnology printer_technology)
void cut_selection_to_clipboard ()
void copy_selection_to_clipboard ()
void paste_from_clipboard ()
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 ()
void fill_color (int extruder_id)
std::string get_3mf_filename ()
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
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
bool can_fillcolor () const
bool has_assmeble_view () const
void msw_rescale ()
void sys_color_changed ()
bool init_collapse_toolbar ()
const Camera & get_camera () const
Camera & get_camera ()
PartPlateList & get_partplate_list ()
void validate_current_plate (bool &model_fits, bool &validate_error)
bool refresh_missing_plugin_block (bool *block_toggled=nullptr)
void revalidate_current_plate_if_plugins_missing ()
void install_missing_cloud_plugins (const std::vector< std::string > &cloud_refs)
void enable_inactive_plugins (const std::vector< std::string > &refs)
bool plugins_block_slicing () const
int select_plate (int plate_index, bool need_slice=false)
void apply_background_progress ()
int select_plate_by_hover_id (int hover_id, bool right_click=false, bool isModidyPlateName=false)
int add_plate ()
int delete_plate (int plate_index=-1)
int duplicate_plate (int plate_index=-1)
int select_sliced_plate (int plate_index, bool skip_zoom=false)
void set_bed_position (Vec2d &pos)
bool is_background_process_slicing () const
void update_slicing_context_to_current_partplate ()
void show_object_info ()
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)
bool get_machine_sync_status ()
void update_machine_sync_status ()
void update_filament_volume_map (int extruder_id, int volume_type)
const BuildVolume & build_volume () const
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)
void reset_gcode_toolpaths ()
void reset_last_loaded_gcode ()
const Mouse3DController & get_mouse3d_controller () const
Mouse3DController & get_mouse3d_controller ()
void update_flush_volume_matrix (size_t old_nozzle_size, size_t new_nozzle_size)
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
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 ()
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
void toggle_show_xray ()
bool is_show_xray () const
bool PopupMenu (wxMenu *menu, const wxPoint &pos=wxDefaultPosition)
bool PopupMenu (wxMenu *menu, int x, int y)
bool PopupObjectTable (int object_id, int volume_id, const wxPoint &position)
bool PopupObjectTableBySelection ()
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)
std::string get_preview_only_filename ()
bool last_arrange_job_is_finished ()
void reset_check_status ()
bool is_loading_project () const
void mark_plate_toolbar_image_dirty ()
bool is_plate_toolbar_image_dirty () const
void clear_plate_toolbar_image_dirty ()
unsigned plate_toolbar_image_version () const

Static Public Member Functions

static wxColour get_next_color_for_filament ()
static wxString get_slice_warning_string (GCodeProcessorResult::SliceWarning &warning)
static TriangleMesh combine_mesh_fff (const ModelObject &mo, int instance_id, std::function< void(const std::string &)> notify_func={})
static std::vector< Vec2f > get_empty_cells (const Vec2f step, const std::vector< BoundingBoxf > &local_exclude_boxes={}, bool include_plate_exclude_areas=true)
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)

Public Attributes

std::atomic< bool > m_arrange_running {false}

Private Member Functions

void suppress_snapshots ()
void allow_snapshots ()
void single_snapshots_enter (SingleSnapshot *single)
void single_snapshots_leave (SingleSnapshot *single)
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 _calib_apply_belt_mode ()
void _calib_temp_belt_sectioned (const Calib_Params &params, double belt_angle_rad)
void cut_horizontal (size_t obj_idx, size_t instance_idx, double z, ModelObjectCutAttributes attributes)
void on_filament_map_mode_change ()

Private Attributes

std::unique_ptr< priv > p
std::string m_3mf_path
bool m_tracking_popup_menu = false
wxString m_tracking_popup_menu_error_message
wxString m_last_loaded_gcode
bool m_only_gcode { false }
bool m_gcode_settings_loaded { false }
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
bool m_b_plate_toolbar_image_dirty { true }
unsigned m_plate_toolbar_image_version { 0 }

Friends

class SuppressBackgroundProcessingUpdate
class PlaterDropTarget

Detailed Description


Class Documentation

◆ Slic3r::GUI::Plater::ImexGhostTooltip

struct Slic3r::GUI::Plater::ImexGhostTooltip
Collaboration diagram for Slic3r::GUI::Plater::ImexGhostTooltip:
Class Members
int filament_slot_1based
string label
int physical_head
ColorRGBA swatch

Member Enumeration Documentation

◆ PrinterWarningType

Enumerator
NOT_CONNECTED 
INCONSISTENT 
UNINSTALL_FILAMENT 
EMPTY_FILAMENT 
689 {
690 NOT_CONNECTED,
691 INCONSISTENT,
692 UNINSTALL_FILAMENT,
693 EMPTY_FILAMENT
694 };

Constructor & Destructor Documentation

◆ Plater() [1/3]

Slic3r::GUI::Plater::Plater ( wxWindow * parent,
MainFrame * main_frame )
15646 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxGetApp().get_min_size())
15647 , p(new priv(this, main_frame))
15648{
15649 // Initialization performed in the private c-tor
15650 enable_wireframe(true);
15651 m_only_gcode = false;
15652}
bool m_only_gcode
Definition Plater.hpp:1094
std::unique_ptr< priv > p
Definition Plater.hpp:1084
void enable_wireframe(bool status)
Definition Plater.cpp:23981
Definition Plater.cpp:7172

References enable_wireframe(), m_only_gcode, and p.

Referenced by Plater(), Plater(), Slic3r::GUI::Plater::priv::priv(), Slic3r::GUI::Plater::SingleSnapshot::SingleSnapshot(), Slic3r::GUI::Plater::SuppressSnapshots::SuppressSnapshots(), Slic3r::GUI::Plater::TakeSnapshot::TakeSnapshot(), Slic3r::GUI::Plater::TakeSnapshot::TakeSnapshot(), operator=(), and operator=().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Plater() [2/3]

Slic3r::GUI::Plater::Plater ( Plater && )
delete

References Plater().

Here is the call graph for this function:

◆ Plater() [3/3]

Slic3r::GUI::Plater::Plater ( const Plater & )
delete

References Plater().

Here is the call graph for this function:

◆ ~Plater()

Slic3r::GUI::Plater::~Plater ( )
default

Member Function Documentation

◆ _calib_apply_belt_mode()

void Slic3r::GUI::Plater::_calib_apply_belt_mode ( )
private
16743{
16744 double angle_rad = 0.;
16745 Vec3d axis = Vec3d::UnitX();
16746 if (!belt_calib_rotation_params(angle_rad, axis))
16747 return;
16748
16749 auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
16750 // Spiral vase stays enabled where the tests request it: the support wedge
16751 // lies strictly below the object, support layers never spiralize
16752 // (spiral_vase_enable requires an object layer), and the spiral/support
16753 // exclusivity check only applies to globally enabled supports — the wedge
16754 // uses per-object supports.
16755 // A skirt would be drawn in the first slicing plane, which lies mostly
16756 // above the belt surface.
16757 print_config->set_key_value("skirt_loops", new ConfigOptionInt(0));
16758
16759 const Matrix3d cancel_rotation = Eigen::AngleAxisd(angle_rad, axis).toRotationMatrix();
16760 std::vector<size_t> obj_idxs;
16761 for (size_t i = 0; i < model().objects.size(); ++i) {
16762 ModelObject* obj = model().objects[i];
16763 if (obj->instances.size() != 1)
16764 continue;
16765 obj_idxs.emplace_back(i);
16766
16767 // Manual tree support: only the floating bottom face gets a support
16768 // wedge (via the belt-floor extension in TreeSupport::generate()),
16769 // leaving the test features untouched. The style is pinned to hybrid
16770 // because the default style resolves to organic, which bypasses the
16771 // non-organic generator that hosts the belt-floor extension.
16772 obj->config.set_key_value("enable_support", new ConfigOptionBool(true));
16773 obj->config.set_key_value("support_type", new ConfigOptionEnum<SupportType>(stTree));
16774 obj->config.set_key_value("support_style", new ConfigOptionEnum<SupportMaterialStyle>(smsTreeHybrid));
16775 obj->config.set_key_value("support_on_build_plate_only", new ConfigOptionBool(false));
16776 // With the default base pattern, tree support base areas print as
16777 // hollow outlines (no infill) — the wedge needs a real pattern.
16778 obj->config.set_key_value("support_base_pattern", new ConfigOptionEnum<SupportMaterialPattern>(smpRectilinear));
16779
16780 // Counter-rotate exactly the way the rotate gizmo would: rotation on
16781 // the instance, then a plain drop to the bed. This leaves the object
16782 // in the same state shape as any manually rotated object, which the
16783 // belt pipeline is known to handle.
16784 ModelInstance* inst = obj->instances.front();
16785 inst->rotate(cancel_rotation);
16786 obj->invalidate_bounding_box();
16787 obj->ensure_on_bed();
16788 }
16789
16790 // Each object's support wedge extends upstream of it by roughly its own
16791 // depth (at 45°), so the tight flat-bed layouts of the multi-part tests
16792 // leave wedges intersecting the neighbouring parts. Keep the grid rows of
16793 // the test layouts together and open up the space between rows just
16794 // enough for the wedge shadow.
16795 if (obj_idxs.size() > 1) {
16796 std::vector<ModelObject*> sorted_objs;
16797 sorted_objs.reserve(obj_idxs.size());
16798 for (size_t i : obj_idxs)
16799 sorted_objs.emplace_back(model().objects[i]);
16800 std::sort(sorted_objs.begin(), sorted_objs.end(), [](const ModelObject* a, const ModelObject* b) {
16801 return a->instances.front()->get_offset(Y) < b->instances.front()->get_offset(Y);
16802 });
16803 std::vector<std::vector<ModelObject*>> rows;
16804 double row_y = std::numeric_limits<double>::quiet_NaN();
16805 for (ModelObject* o : sorted_objs) {
16806 const double oy = o->instances.front()->get_offset(Y);
16807 if (rows.empty() || oy - row_y > 1.)
16808 rows.emplace_back();
16809 rows.back().emplace_back(o);
16810 row_y = oy;
16811 }
16812 const double wedge_factor = std::abs(std::tan(angle_rad));
16813 double cursor = std::numeric_limits<double>::quiet_NaN();
16814 for (std::vector<ModelObject*>& row : rows) {
16815 double rmin = std::numeric_limits<double>::max();
16816 double rmax = std::numeric_limits<double>::lowest();
16817 for (ModelObject* o : row) {
16818 const BoundingBoxf3 bb = o->instance_bounding_box(0);
16819 rmin = std::min(rmin, bb.min.y());
16820 rmax = std::max(rmax, bb.max.y());
16821 }
16822 if (std::isnan(cursor))
16823 cursor = rmin; // the first row anchors the layout
16824 const double shift = cursor - rmin;
16825 for (ModelObject* o : row) {
16826 ModelInstance* inst = o->instances.front();
16827 inst->set_offset(Y, inst->get_offset(Y) + shift);
16828 o->invalidate_bounding_box();
16829 }
16830 cursor += (rmax - rmin) * (1. + wedge_factor) + 5.;
16831 }
16832 }
16833
16834 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
16835 wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
16836 changed_objects(obj_idxs);
16837}
const Model & model() const
Definition Plater.cpp:16047
void changed_objects(const std::vector< size_t > &object_idxs)
Definition Plater.cpp:22267
ModelObjectPtrs objects
Definition Model.hpp:1702
@ TYPE_PRINT
Definition Preset.hpp:246
static bool belt_calib_rotation_params(double &angle_rad, Vec3d &axis)
Definition Plater.cpp:16710
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
@ smpRectilinear
Definition PrintConfig.hpp:357
@ stTree
Definition PrintConfig.hpp:379
@ smsTreeHybrid
Definition PrintConfig.hpp:363
Eigen::Matrix< double, 3, 3, Eigen::DontAlign > Matrix3d
Definition Point.hpp:86
@ Y
Definition libslic3r.h:142
size_t rows(const T &raster)
Definition MarchingSquares.hpp:171

References Slic3r::GUI::belt_calib_rotation_params(), changed_objects(), Slic3r::ModelObject::config, Slic3r::ModelObject::ensure_on_bed(), Slic3r::ModelInstance::get_offset(), Slic3r::ModelObject::instances, Slic3r::ModelObject::invalidate_bounding_box(), Slic3r::BoundingBoxBase< PointType, std::vector< PointType > >::max, Slic3r::BoundingBoxBase< PointType, std::vector< PointType > >::min, model(), Slic3r::Model::objects, Slic3r::ModelInstance::rotate(), Slic3r::ModelConfig::set_key_value(), Slic3r::ModelInstance::set_offset(), Slic3r::smpRectilinear, Slic3r::smsTreeHybrid, Slic3r::stTree, Slic3r::Preset::TYPE_PRINT, and Slic3r::Y.

Referenced by _calib_pa_tower(), Calib_Cornering(), calib_flowrate(), calib_input_shaping_damp(), calib_input_shaping_freq(), calib_max_vol_speed(), calib_retraction(), and calib_VFA().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _calib_pa_pattern()

void Slic3r::GUI::Plater::_calib_pa_pattern ( const Calib_Params & params)
private
16879{
16880 std::vector<double> speeds{params.speeds};
16881 std::vector<double> accels{params.accelerations};
16882 std::vector<size_t> object_idxs{};
16883 /* Set common parameters */
16884 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
16885 DynamicPrintConfig& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
16886 auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
16887 double nozzle_diameter = printer_config->option<ConfigOptionFloats>("nozzle_diameter")->get_at(0);
16888 set_config_values<bool, ConfigOptionBoolsNullable>(filament_config, "filament_retract_when_changing_layer", false);
16889 set_config_values<bool, ConfigOptionBoolsNullable>(filament_config, "filament_wipe", false);
16891 set_config_values<bool, ConfigOptionBools>(printer_config, "retract_when_changing_layer", false);
16892 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool(false));
16893
16894 //Orca: find acceleration to use in the test
16895 auto accel = print_config.get_abs_value_at("outer_wall_acceleration", params.extruder_id); // get the outer wall acceleration
16896 if (accel == 0) // if outer wall accel isnt defined, fall back to inner wall accel
16897 accel = print_config.get_abs_value_at("inner_wall_acceleration", params.extruder_id);
16898 if (accel == 0) // if inner wall accel is not defined fall back to default accel
16899 accel = print_config.get_abs_value_at("default_acceleration", params.extruder_id);
16900 // Orca: Set all accelerations except first layer, as the first layer accel doesnt affect the PA test since accel
16901 // is set to the travel accel before printing the pattern.
16902 if (accels.empty()) {
16903 accels.assign({accel});
16904 const auto msg{_L("INFO:") + "\n" +
16905 format_wxstr(_L("No accelerations provided for calibration. Use default acceleration value %1%mm/s²"), long(accel))};
16906 get_notification_manager()->push_notification(msg.utf8_string());
16907 } else {
16908 // set max acceleration in case of batch mode to get correct test pattern size
16909 accel = *std::max_element(accels.begin(), accels.end());
16910 }
16911 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "outer_wall_acceleration", accel);
16912 print_config.set_key_value( "print_sequence", new ConfigOptionEnum(PrintSequence::ByLayer));
16913
16914 //Orca: find jerk value to use in the test
16915 if(!has_junction_deviation(printer_config) && print_config.get_abs_value_at("default_jerk", params.extruder_id) > 0){ // we have set a jerk value
16916 auto jerk = print_config.get_abs_value_at("outer_wall_jerk", params.extruder_id); // get outer wall jerk
16917 if (jerk == 0) // if outer wall jerk is not defined, get inner wall jerk
16918 jerk = print_config.get_abs_value_at("inner_wall_jerk", params.extruder_id);
16919 if (jerk == 0) // if inner wall jerk is not defined, get the default jerk
16920 jerk = print_config.get_abs_value_at("default_jerk", params.extruder_id);
16921
16922 //Orca: Set jerk values. Again first layer jerk should not matter as it is reset to the travel jerk before the
16923 // first PA pattern is printed.
16924 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "default_jerk", jerk);
16925 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "outer_wall_jerk", jerk);
16926 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "inner_wall_jerk", jerk);
16927 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "top_surface_jerk", jerk);
16928 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "infill_jerk", jerk);
16929 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "travel_jerk", jerk);
16930 }
16931
16933 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "default_junction_deviation", 0);
16934 }
16935
16936 for (const auto& opt : SuggestedConfigCalibPAPattern().floats_pairs) {
16937 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, opt.first, opt.second[0]);
16938 }
16939
16940 for (const auto& opt : SuggestedConfigCalibPAPattern().nozzle_ratio_pairs) {
16941 print_config.set_key_value(
16942 opt.first,
16943 new ConfigOptionFloatOrPercent(nozzle_diameter * opt.second / 100, false)
16944 );
16945 }
16946
16947 for (const auto& opt : SuggestedConfigCalibPAPattern().int_pairs) {
16948 print_config.set_key_value(
16949 opt.first,
16950 new ConfigOptionInt(opt.second)
16951 );
16952 }
16953
16954 print_config.set_key_value(SuggestedConfigCalibPAPattern().brim_pair.first,
16955 new ConfigOptionEnum<BrimType>(SuggestedConfigCalibPAPattern().brim_pair.second));
16956
16957 print_config.set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
16958
16959 // Orca: Set the outer wall speed to the optimal speed for the test, cap it with max volumetric speed
16960 if (speeds.empty()) {
16961 // TODO: per-variant cap
16963 wxGetApp().preset_bundle->full_config(),
16964 print_config.get_abs_value("line_width", nozzle_diameter),
16965 print_config.get_abs_value("layer_height"), 0, 0);
16966 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "outer_wall_speed", speed);
16967
16968 speeds.assign({speed});
16969 const auto msg{_L("INFO:") + "\n" +
16970 format_wxstr(_L("No speeds provided for calibration. Use default optimal speed %1%mm/s"), long(speed))};
16971 get_notification_manager()->push_notification(msg.utf8_string());
16972 } else if (speeds.size() == 1) {
16973 // If we have single value provided, set speed using global configuration.
16974 // per-object config is not set in this case
16975 set_config_values<double, ConfigOptionFloatsNullable>(&print_config, "outer_wall_speed", speeds.front());
16976 }
16977
16978 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
16979 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
16980 wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty();
16981 wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
16982 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
16983 wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config();
16984
16985 const DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config();
16986 PresetBundle* preset_bundle = wxGetApp().preset_bundle;
16987 const bool is_bbl_machine = preset_bundle->is_bbl_vendor();
16988 auto cur_plate = get_partplate_list().get_plate(0);
16989
16990 // add "handle" cube
16992 auto *cube = model().objects[0];
16993
16994 CalibPressureAdvancePattern pa_pattern(
16995 params,
16996 full_config,
16997 is_bbl_machine,
16998 *cube,
16999 cur_plate->get_origin()
17000 );
17001
17002 /* Having PA pattern configured, we could make a set of polygons resembling N test patterns.
17003 * We'll arrange this set of polygons, so we would know position of each test pattern and
17004 * could position test cubes later on
17005 *
17006 * We'll take advantage of already existing cube: scale it up to test pattern size to use
17007 * as a reference for objects arrangement. Polygon is slightly oversized to add spaces between patterns.
17008 * That arrangement will be used to place 'handle cubes' for each test. */
17009 auto cube_bb = cube->raw_bounding_box();
17010 cube->scale((pa_pattern.print_size_x() + 4) / cube_bb.size().x(),
17011 (pa_pattern.print_size_y() + 4) / cube_bb.size().y(),
17012 pa_pattern.max_layer_z() / cube_bb.size().z());
17013
17014 arrangement::ArrangePolygons arranged_items;
17015 {
17016 arrangement::ArrangeParams ap;
17017 Points bedpts = arrangement::get_shrink_bedpts(&full_config, ap);
17018
17019 for(size_t i = 0; i < speeds.size() * accels.size(); i++) {
17020 arrangement::ArrangePolygon p;
17021 cube->instances[0]->get_arrange_polygon(&p);
17022 p.bed_idx = 0;
17023 arranged_items.emplace_back(p);
17024 }
17025
17026 arrangement::arrange(arranged_items, bedpts, ap);
17027 }
17028
17029 /* scale cube back to the size of test pattern 'handle' */
17030 cube_bb = cube->raw_bounding_box();
17031 cube->scale(pa_pattern.handle_xy_size() / cube_bb.size().x(),
17032 pa_pattern.handle_xy_size() / cube_bb.size().y(),
17033 pa_pattern.max_layer_z() / cube_bb.size().z());
17034
17035 /* Set speed and acceleration on per-object basis and arrange anchor object on the plates.
17036 * Test gcode will be genecated during plate slicing */
17037 for(size_t test_idx = 0; test_idx < arranged_items.size(); test_idx++) {
17038 const auto &ai = arranged_items[test_idx];
17039 size_t plate_idx = arranged_items[test_idx].bed_idx;
17040 auto tspd = speeds[test_idx % speeds.size()];
17041 auto tacc = accels[test_idx / speeds.size()];
17042
17043 /* make an own copy of anchor cube for each test */
17044 auto obj = test_idx == 0 ? cube : model().add_object(*cube);
17045 auto obj_idx = std::distance(model().objects.begin(), std::find(model().objects.begin(), model().objects.end(), obj));
17046 obj->name.assign(std::string("pa_pattern_") + std::to_string(int(tspd)) + std::string("_") + std::to_string(int(tacc)));
17047
17048 auto &obj_config = obj->config;
17049 if (speeds.size() > 1)
17050 obj_config.set_key_value("outer_wall_speed", new ConfigOptionFloatsNullable(1, tspd));
17051 if (accels.size() > 1)
17052 obj_config.set_key_value("outer_wall_acceleration", new ConfigOptionFloatsNullable(1, tacc));
17053
17054 auto cur_plate = get_partplate_list().get_plate(plate_idx);
17055 if (!cur_plate) {
17056 plate_idx = get_partplate_list().create_plate();
17057 cur_plate = get_partplate_list().get_plate(plate_idx);
17058 }
17059
17060 object_idxs.emplace_back(obj_idx);
17061 get_partplate_list().add_to_plate(obj_idx, 0, plate_idx);
17062 const Vec3d obj_offset{unscale<double>(ai.translation(X)),
17063 unscale<double>(ai.translation(Y)),
17064 0};
17065 obj->instances[0]->set_offset(cur_plate->get_origin() + obj_offset + pa_pattern.handle_pos_offset());
17066 obj->ensure_on_bed();
17067
17068 if (obj_idx == 0)
17070 else
17071 sidebar().obj_list()->add_object_to_list(obj_idx);
17072 }
17073
17074 model().calib_pa_pattern = std::make_unique<CalibPressureAdvancePattern>(pa_pattern);
17075 changed_objects(object_idxs);
17076}
#define _L(s)
Definition OBJ.cpp:34
static float find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int extruder_id=0, int filament_idx=0)
Definition calib.cpp:29
ConfigOption * option(const t_config_option_key &opt_key, bool create=false)
Definition Config.hpp:2768
bool set_key_value(const std::string &opt_key, ConfigOption *opt)
Definition Config.hpp:3022
void push_notification(const NotificationType type, int timestamp=0)
Definition NotificationManager.cpp:1892
void update_name_for_items()
Definition GUI_ObjectList.cpp:947
void load_generic_subobject(const std::string &type_name, const ModelVolumeType type)
Definition GUI_ObjectList.cpp:2532
void add_object_to_list(size_t obj_idx, bool call_selection_changed=true, bool notify_partplate=true, bool do_info_update=true)
Definition GUI_ObjectList.cpp:4214
int add_to_plate(int obj_id, int instance_id, int plate_id)
Definition PartPlate.cpp:7422
PartPlate * get_plate(int index)
Definition PartPlate.cpp:6874
int create_plate(bool adjust_position=true)
Definition PartPlate.cpp:6561
const NotificationManager * get_notification_manager() const
Definition Plater.cpp:23864
PartPlateList & get_partplate_list()
Definition Plater.cpp:22578
Sidebar & sidebar()
Definition Plater.cpp:16046
ObjectList * obj_list()
Definition Plater.cpp:6638
ModelObject * add_object()
Definition Model.cpp:607
std::unique_ptr< CalibPressureAdvancePattern > calib_pa_pattern
Definition Model.hpp:1885
@ TYPE_PRINTER
Definition Preset.hpp:250
@ TYPE_FILAMENT
Definition Preset.hpp:248
wxString format_wxstr(const char *fmt, TArgs &&... args)
Definition format.hpp:22
static DynamicPrintConfig & printer_config()
Definition GUI_ObjectList.cpp:131
static bool has_junction_deviation(const DynamicPrintConfig *printer_config)
Definition Plater.cpp:1398
static void set_config_values(DynamicPrintConfig *config, const std::string &key, T value)
Definition Plater.cpp:379
std::vector< ArrangePolygon > ArrangePolygons
Definition Arrange.hpp:126
Points get_shrink_bedpts(const DynamicPrintConfig *print_cfg, const ArrangeParams &params)
Definition Arrange.cpp:339
void arrange(ArrangePolygons &items, const ArrangePolygons &excludes, const Points &bed, const ArrangeParams &params)
Definition Arrange.cpp:1280
zaa_minimize_perimeter_height nozzle_diameter((ConfigOptionBool, reduce_infill_retraction))((ConfigOptionBool
@ INVALID
Definition Model.hpp:356
ConfigOptionFloatsTempl< true > ConfigOptionFloatsNullable
Definition Config.hpp:1016
@ ByLayer
Definition PrintConfig.hpp:311
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:73
T unscale(Q v)
Definition libslic3r.h:138
@ X
Definition libslic3r.h:141
ConfigOptionFloatsTempl< false > ConfigOptionFloats
Definition Config.hpp:1015

References _L, Slic3r::Calib_Params::accelerations, Slic3r::Model::add_object(), Slic3r::GUI::ObjectList::add_object_to_list(), Slic3r::GUI::PartPlateList::add_to_plate(), Slic3r::arrangement::arrange(), Slic3r::ByLayer, Slic3r::Model::calib_pa_pattern, changed_objects(), Slic3r::ModelObject::config, Slic3r::GUI::PartPlateList::create_plate(), Slic3r::ModelObject::ensure_on_bed(), Slic3r::Calib_Params::extruder_id, Slic3r::CalibPressureAdvance::find_optimal_PA_speed(), Slic3r::GUI::format_wxstr(), Slic3r::ConfigBase::get_abs_value(), Slic3r::ConfigBase::get_abs_value_at(), get_notification_manager(), get_partplate_list(), Slic3r::GUI::PartPlateList::get_plate(), Slic3r::arrangement::get_shrink_bedpts(), Slic3r::CalibPressureAdvancePattern::handle_pos_offset(), Slic3r::CalibPressureAdvancePattern::handle_xy_size(), Slic3r::GUI::has_junction_deviation(), Slic3r::ModelObject::instances, Slic3r::INVALID, Slic3r::PresetBundle::is_bbl_vendor(), Slic3r::GUI::ObjectList::load_generic_subobject(), Slic3r::CalibPressureAdvancePattern::max_layer_z(), model(), Slic3r::ModelObject::name, Slic3r::nozzle_diameter(), Slic3r::GUI::Sidebar::obj_list(), Slic3r::Model::objects, p, Slic3r::CalibPressureAdvancePattern::print_size_x(), Slic3r::CalibPressureAdvancePattern::print_size_y(), Slic3r::GUI::printer_config(), Slic3r::GUI::NotificationManager::push_notification(), Slic3r::GUI::set_config_values(), Slic3r::DynamicConfig::set_key_value(), Slic3r::ModelConfig::set_key_value(), sidebar(), Slic3r::Calib_Params::speeds, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, Slic3r::Preset::TYPE_PRINTER, Slic3r::unscale(), Slic3r::GUI::ObjectList::update_name_for_items(), Slic3r::X, and Slic3r::Y.

Referenced by calib_pa().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _calib_pa_pattern_gen_gcode()

void Slic3r::GUI::Plater::_calib_pa_pattern_gen_gcode ( )
private
17079{
17080 if (!model().calib_pa_pattern)
17081 return;
17082
17083 auto cur_plate = get_partplate_list().get_curr_plate();
17084 if (cur_plate->empty())
17085 return;
17086
17087 /* Container to store custom g-codes genereted by the test generator.
17088 * We'll store gcode for all tests on a single plate here. Once the plate handling is done,
17089 * all the g-codes will be merged into a single one on per-layer basis */
17090 std::vector<CustomGCode::Info> mgc;
17091 PresetBundle *preset_bundle = wxGetApp().preset_bundle;
17092
17093 /* iterate over all cubes on current plate and generate gcode for them */
17094 for (auto obj : cur_plate->get_objects_on_this_plate()) {
17095 auto gcode = model().calib_pa_pattern->generate_custom_gcodes(
17096 preset_bundle->full_config(),
17097 preset_bundle->is_bbl_vendor(),
17098 *obj,
17099 cur_plate->get_origin()
17100 );
17101 mgc.emplace_back(gcode);
17102 }
17103
17104 // move first item into model custom gcode
17106 pcgc = std::move(mgc[0]);
17107 mgc.erase(mgc.begin());
17108
17109 // concat layer gcodes for each test
17110 for (size_t i = 0; i < pcgc.gcodes.size(); i++) {
17111 for (auto &gc : mgc) {
17112 pcgc.gcodes[i].extra += gc.gcodes[i].extra;
17113 }
17114 }
17115}
PartPlate * get_curr_plate()
Definition PartPlate.hpp:962
int get_curr_plate_index() const
Definition PartPlate.hpp:961
std::map< int, CustomGCode::Info > plates_custom_gcodes
Definition Model.hpp:1743
static std::string gcode(Type type)
Definition IMSlider.cpp:111

References Slic3r::Model::calib_pa_pattern, Slic3r::PresetBundle::full_config(), Slic3r::GUI::gcode(), Slic3r::GUI::PartPlateList::get_curr_plate(), Slic3r::GUI::PartPlateList::get_curr_plate_index(), get_partplate_list(), Slic3r::PresetBundle::is_bbl_vendor(), model(), and Slic3r::Model::plates_custom_gcodes.

Referenced by reslice().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _calib_pa_select_added_objects()

void Slic3r::GUI::Plater::_calib_pa_select_added_objects ( )
private
17186 {
17187 // update printable state for new volumes on canvas3D
17188 wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects({0});
17189
17190 Selection& selection = p->view3D->get_canvas3d()->get_selection();
17191 selection.clear();
17192 selection.add_object(0, false);
17193
17194 // BBS: update object list selection
17195 p->sidebar->obj_list()->update_selections();
17196 selection.notify_instance_update(-1, -1);
17197 if (p->view3D->get_canvas3d()->get_gizmos_manager().is_enabled()) {
17198 // this is required because the selected object changed and the flatten on face an sla support gizmos need to be updated accordingly
17199 p->view3D->get_canvas3d()->update_gizmos_on_off_state();
17200 }
17201}
@ Selection
Definition Shortcuts.hpp:72

References Slic3r::GUI::Selection::add_object(), Slic3r::GUI::Selection::clear(), Slic3r::GUI::Selection::notify_instance_update(), and p.

Referenced by _calib_pa_tower().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _calib_pa_tower()

void Slic3r::GUI::Plater::_calib_pa_tower ( const Calib_Params & params)
private
17136 {
17137 if (!add_model(false, Slic3r::resources_dir() + "/calib/pressure_advance/tower_with_seam.drc"))
17138 return;
17139
17140 auto& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
17141 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
17142 auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
17143
17144 const double nozzle_diameter = printer_config->option<ConfigOptionFloats>("nozzle_diameter")->get_at(0);
17145
17146 print_config.set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
17147 filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats{ 1.0f });
17148
17149
17150 auto& obj_cfg = model().objects[0]->config;
17151
17152 obj_cfg.set_key_value("alternate_extra_wall", new ConfigOptionBool(false));
17153 auto full_config = wxGetApp().preset_bundle->full_config();
17154 update_speed_parameter("outer_wall_speed");
17155 update_speed_parameter("inner_wall_speed");
17156 obj_cfg.set_key_value("seam_position", new ConfigOptionEnum<SeamPosition>(spRear));
17157 obj_cfg.set_key_value("wall_loops", new ConfigOptionInt(2));
17158 obj_cfg.set_key_value("top_shell_layers", new ConfigOptionInt(0));
17159 obj_cfg.set_key_value("bottom_shell_layers", new ConfigOptionInt(0));
17160 obj_cfg.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
17161 obj_cfg.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btEar));
17162 obj_cfg.set_key_value("brim_object_gap", new ConfigOptionFloat(.0f));
17163 obj_cfg.set_key_value("brim_ears_max_angle", new ConfigOptionFloat(135.f));
17164 obj_cfg.set_key_value("brim_width", new ConfigOptionFloat(6.f));
17165 obj_cfg.set_key_value("seam_slope_type", new ConfigOptionEnum<SeamScarfType>(SeamScarfType::None));
17166 print_config.set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0));
17167
17168 changed_objects({ 0 });
17169 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
17170 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
17171 wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty();
17172 wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
17173 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
17174 wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config();
17175
17176 auto new_height = std::ceil((params.end - params.start) / params.step) + 1;
17177 auto obj_bb = model().objects[0]->bounding_box_exact();
17178 if (new_height < obj_bb.size().z()) {
17180 }
17181
17184}
void cut_horizontal(size_t obj_idx, size_t instance_idx, double z, ModelObjectCutAttributes attributes)
Definition Plater.cpp:17117
bool add_model(bool imperial_units=false, std::string fname="")
Definition Plater.cpp:16628
void _calib_pa_select_added_objects()
Definition Plater.cpp:17186
void _calib_apply_belt_mode()
Definition Plater.cpp:16742
void update_speed_parameter(const std::string &key)
Definition CalibUtils.cpp:156
zaa_minimize_perimeter_height ConfigOptionFloat
Definition PrintConfig.hpp:1954
@ btEar
Definition PrintConfig.hpp:456
@ spRear
Definition PrintConfig.hpp:395
const std::string & resources_dir()
Definition utils.cpp:296
@ KeepLower
Definition CutUtils.hpp:15
@ None
Definition PrintConfig.hpp:400

References _calib_apply_belt_mode(), _calib_pa_select_added_objects(), add_model(), Slic3r::btEar, changed_objects(), Slic3r::ConfigOptionFloat, cut_horizontal(), Slic3r::Calib_Params::end, Slic3r::KeepLower, model(), Slic3r::None, Slic3r::nozzle_diameter(), Slic3r::Model::objects, Slic3r::GUI::printer_config(), Slic3r::resources_dir(), Slic3r::spRear, Slic3r::Calib_Params::start, Slic3r::Calib_Params::step, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, Slic3r::Preset::TYPE_PRINTER, and Slic3r::GUI::update_speed_parameter().

Referenced by calib_pa().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _calib_temp_belt_sectioned()

void Slic3r::GUI::Plater::_calib_temp_belt_sectioned ( const Calib_Params & params,
double belt_angle_rad )
private
17584{
17585 constexpr double base_temp_tower_nozzle_diameter = 0.4;
17586 constexpr double base_temp_tower_block_height = 10.0;
17587 constexpr int base_temp_tower_temp_step = 5;
17588
17589 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
17590 auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
17591 auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
17592
17593 const long start_temp = lround(params.start);
17594 const long end_temp = lround(params.end);
17595 const int n_blocks = std::max(1, int((start_temp - end_temp) / base_temp_tower_temp_step) + 1);
17596
17597 const ConfigOptionFloats* nozzle_diameter_config = printer_config->option<ConfigOptionFloats>("nozzle_diameter");
17598 size_t nozzle_id = static_cast<size_t>(std::max(params.extruder_id, 0));
17599 double nozzle_diameter = base_temp_tower_nozzle_diameter;
17600 if (nozzle_diameter_config && !nozzle_diameter_config->values.empty()) {
17601 nozzle_id = std::min(nozzle_id, nozzle_diameter_config->values.size() - 1);
17602 nozzle_diameter = nozzle_diameter_config->values[nozzle_id];
17603 }
17604 if (nozzle_diameter <= 0.0)
17605 nozzle_diameter = base_temp_tower_nozzle_diameter;
17606 const double nozzle_scale = nozzle_diameter / base_temp_tower_nozzle_diameter;
17607
17608 std::vector<size_t> obj_idxs;
17609 for (int i = 0; i < n_blocks; ++i) {
17610 const long temp = start_temp - long(i) * base_temp_tower_temp_step;
17611 const size_t count_before = model().objects.size();
17612 add_model(false, Slic3r::resources_dir() + "/calib/temperature_tower/temperature_tower.drc");
17613 if (model().objects.size() <= count_before)
17614 break; // model failed to load — don't index into an empty list
17615 // The cut replaces the object at the END of the list, so re-acquire
17616 // the index after every operation.
17617 size_t obj_idx = model().objects.size() - 1;
17618
17619 // Isolate this temperature's block (full-tower coordinates, the same
17620 // 500-down-to-temp indexing the monolithic flow cuts with).
17621 const double block_bottom = double(lround(double(500 - temp) / base_temp_tower_temp_step)) * base_temp_tower_block_height;
17622 auto obj_bb = model().objects[obj_idx]->bounding_box_exact();
17623 if (block_bottom + base_temp_tower_block_height < obj_bb.size().z()) {
17624 cut_horizontal(obj_idx, 0, block_bottom + base_temp_tower_block_height - EPSILON, ModelObjectCutAttribute::KeepLower);
17625 obj_idx = model().objects.size() - 1;
17626 }
17627 if (block_bottom > 0) {
17628 cut_horizontal(obj_idx, 0, block_bottom + EPSILON, ModelObjectCutAttribute::KeepUpper);
17629 obj_idx = model().objects.size() - 1;
17630 }
17631
17632 ModelObject* obj = model().objects[obj_idx];
17633 if (std::abs(nozzle_scale - 1.0) > EPSILON)
17634 obj->scale(nozzle_scale, nozzle_scale, nozzle_scale);
17635 obj->name = std::string("temp_") + std::to_string(temp);
17636 obj->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter / 2));
17637 obj->config.set_key_value("alternate_extra_wall", new ConfigOptionBool(false));
17638 obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum<SeamScarfType>(SeamScarfType::None));
17639 obj->config.set_key_value("overhang_reverse", new ConfigOptionBool(false));
17640 obj->config.set_key_value("precise_z_height", new ConfigOptionBool(false));
17641 obj->ensure_on_bed();
17642 obj_idxs.emplace_back(obj_idx);
17643 }
17644
17645 // Space the blocks along the belt with strictly increasing layer ranges:
17646 // each block must start past the previous block's highest slicing plane,
17647 // which trails its far edge by height / tan(angle). Anchor the row near
17648 // the gantry so the whole test stays in the plate area.
17649 const double cot_a = 1. / std::max(0.1, std::tan(belt_angle_rad));
17650 double cursor = 20.;
17651 for (size_t idx : obj_idxs) {
17652 ModelObject* obj = model().objects[idx];
17653 ModelInstance* inst = obj->instances.front();
17654 const BoundingBoxf3 bb = obj->instance_bounding_box(0);
17655 inst->set_offset(Y, inst->get_offset(Y) + (cursor - bb.min.y()));
17656 obj->invalidate_bounding_box();
17657 cursor += bb.size().y() + bb.size().z() * cot_a + 5.;
17658 }
17659
17660 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
17661 filament_config->set_key_value("nozzle_temperature_initial_layer", new ConfigOptionInts(1, (int)start_temp));
17662 filament_config->set_key_value("nozzle_temperature", new ConfigOptionInts(1, (int)start_temp));
17663 print_config->set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
17664 print_config->set_key_value("initial_layer_print_height", new ConfigOptionFloat(nozzle_diameter / 2));
17665 print_config->set_key_value("skirt_loops", new ConfigOptionInt(0));
17666
17667 changed_objects(obj_idxs);
17668 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
17669 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
17670 wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
17671 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
17672
17673 p->background_process.fff_print()->set_calib_params(params);
17674}
#define EPSILON
Definition ColorUtils.cpp:64
ConfigOptionIntsTempl< false > ConfigOptionInts
Definition Config.hpp:1154
@ KeepUpper
Definition CutUtils.hpp:15

References add_model(), changed_objects(), Slic3r::ModelObject::config, Slic3r::ConfigOptionFloat, cut_horizontal(), Slic3r::Calib_Params::end, Slic3r::ModelObject::ensure_on_bed(), EPSILON, Slic3r::Calib_Params::extruder_id, Slic3r::ModelInstance::get_offset(), Slic3r::ModelObject::instance_bounding_box(), Slic3r::ModelObject::instances, Slic3r::ModelObject::invalidate_bounding_box(), Slic3r::KeepLower, Slic3r::KeepUpper, Slic3r::BoundingBoxBase< PointType, std::vector< PointType > >::min, model(), Slic3r::ModelObject::name, Slic3r::None, Slic3r::nozzle_diameter(), Slic3r::Model::objects, p, Slic3r::GUI::printer_config(), Slic3r::resources_dir(), Slic3r::ModelObject::scale(), Slic3r::ModelConfig::set_key_value(), Slic3r::ModelInstance::set_offset(), Slic3r::BoundingBox3Base< PointType >::size(), Slic3r::Calib_Params::start, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, Slic3r::ConfigOptionVector< double >::values, and Slic3r::Y.

Referenced by calib_temp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_dock_pane()

void Slic3r::GUI::Plater::add_dock_pane ( wxWindow * window,
const std::string & name,
const wxString & caption,
const std::string & dock,
const wxSize & size,
std::function< void()> on_close )
19166{
19167 p->add_dock_pane(window, name, caption, dock, size, std::move(on_close));
19168}

References p.

Referenced by Slic3r::anonymous_namespace{PluginHostUi.cpp}::ui_create_dock_panel().

Here is the caller graph for this function:

◆ add_file()

void Slic3r::GUI::Plater::add_file ( )
18990{
18991 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " entry";
18992 wxArrayString input_files;
18993 wxGetApp().import_model(this, input_files);
18994 if (input_files.empty()) return;
18995
18996 std::vector<fs::path> paths;
18997 for (const auto &file : input_files) paths.emplace_back(into_path(file));
18998
18999 std::string snapshot_label;
19000 assert(!paths.empty());
19001
19002 snapshot_label = "Import Objects";
19003 snapshot_label += ": ";
19004 snapshot_label += encode_path(paths.front().filename().string().c_str());
19005 for (size_t i = 1; i < paths.size(); ++i) {
19006 snapshot_label += ", ";
19007 snapshot_label += encode_path(paths[i].filename().string().c_str());
19008 }
19009
19010 // BBS: check file types
19011 auto loadfiles_type = LoadFilesType::NoFile;
19012 auto amf_files_count = get_3mf_file_count(paths);
19013
19014 if (paths.size() > 1 && amf_files_count < paths.size()) { loadfiles_type = LoadFilesType::Multiple3MFOther; }
19015 if (paths.size() > 1 && amf_files_count == paths.size()) { loadfiles_type = LoadFilesType::Multiple3MF; }
19016 if (paths.size() > 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::MultipleOther; }
19017 if (paths.size() == 1 && amf_files_count == 1) { loadfiles_type = LoadFilesType::Single3MF; };
19018 if (paths.size() == 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::SingleOther; };
19019
19020 auto first_file = std::vector<fs::path>{};
19021 auto tmf_file = std::vector<fs::path>{};
19022 auto other_file = std::vector<fs::path>{};
19023
19024 switch (loadfiles_type)
19025 {
19027 open_3mf_file(paths[0]);
19028 break;
19029
19031 Plater::TakeSnapshot snapshot(this, snapshot_label);
19032 if (!load_files(paths, LoadStrategy::LoadModel, false).empty()) {
19033 if (get_project_name() == _L("Untitled") && paths.size() > 0) {
19034 boost::filesystem::path full_path(paths[0].string());
19035 p->set_project_name(from_u8(full_path.stem().string()));
19036 }
19037 wxGetApp().mainframe->update_title();
19038 if (wxGetApp().app_config->get("recent_models") == "true")
19039 wxGetApp().mainframe->add_to_recent_projects(paths[0].wstring());
19040 }
19041 break;
19042 }
19044 first_file = std::vector<fs::path>{paths[0]};
19045 for (auto i = 0; i < paths.size(); i++) {
19046 if (i > 0) { other_file.push_back(paths[i]); }
19047 };
19048
19049 open_3mf_file(first_file[0]);
19050 if (!load_files(other_file, LoadStrategy::LoadModel).empty()) { wxGetApp().mainframe->update_title(); }
19051 break;
19052
19054 Plater::TakeSnapshot snapshot(this, snapshot_label);
19055 if (!load_files(paths, LoadStrategy::LoadModel, true).empty()) {
19056 if (get_project_name() == _L("Untitled") && paths.size() > 0) {
19057 boost::filesystem::path full_path(paths[0].string());
19058 p->set_project_name(from_u8(full_path.stem().string()));
19059 }
19060 wxGetApp().mainframe->update_title();
19061 if (wxGetApp().app_config->get("recent_models") == "true")
19062 for (auto &path : paths)
19063 wxGetApp().mainframe->add_to_recent_projects(path.wstring());
19064 }
19065 break;
19066 }
19068 for (const auto &path : paths) {
19069 if (boost::iends_with(path.filename().string(), ".3mf")) {
19070 if (first_file.size() <= 0)
19071 first_file.push_back(path);
19072 else
19073 tmf_file.push_back(path);
19074 } else {
19075 other_file.push_back(path);
19076 }
19077 }
19078
19079 open_3mf_file(first_file[0]);
19081 if (!load_files(other_file, LoadStrategy::LoadModel, false).empty()) {
19082 wxGetApp().mainframe->update_title();
19083 if (wxGetApp().app_config->get("recent_models") == "true")
19084 for (auto &file : other_file)
19085 wxGetApp().mainframe->add_to_recent_projects(file.wstring());
19086 }
19087 break;
19088 default:break;
19089 }
19090}
bool open_3mf_file(const boost::filesystem::path &file_path)
Definition Plater.cpp:18941
std::vector< size_t > load_files(const std::vector< boost::filesystem::path > &input_files, LoadStrategy strategy=LoadStrategy::LoadModel|LoadStrategy::LoadConfig, bool ask_multi=false, bool *published_out=nullptr)
int get_3mf_file_count(std::vector< boost::filesystem::path > paths)
Definition Plater.cpp:18978
wxString get_project_name()
Definition Plater.cpp:18343
wxString from_u8(const std::string &str)
Definition GUI.cpp:544
@ Single3MF
Definition Plater.cpp:476
@ NoFile
Definition Plater.cpp:475
@ MultipleOther
Definition Plater.cpp:479
@ SingleOther
Definition Plater.cpp:477
@ Multiple3MFOther
Definition Plater.cpp:480
@ Multiple3MF
Definition Plater.cpp:478
boost::filesystem::path into_path(const wxString &str)
Definition GUI.cpp:564
std::string encode_path(const char *src)
Definition utils.cpp:1382
@ LoadModel
Definition bbs_3mf.hpp:222
bool empty(const BoundingBoxBase< PointType, PointsType > &bb)
Definition BoundingBox.hpp:273

References _L, Slic3r::empty(), Slic3r::encode_path(), Slic3r::GUI::from_u8(), get_3mf_file_count(), get_project_name(), Slic3r::GUI::into_path(), load_files(), Slic3r::LoadModel, Slic3r::GUI::Multiple3MF, Slic3r::GUI::Multiple3MFOther, Slic3r::GUI::MultipleOther, Slic3r::GUI::NoFile, open_3mf_file(), p, Slic3r::GUI::Single3MF, and Slic3r::GUI::SingleOther.

Here is the call graph for this function:

◆ add_model()

bool Slic3r::GUI::Plater::add_model ( bool imperial_units = false,
std::string fname = "" )
16629{
16630 wxArrayString input_files;
16631
16632 std::vector<fs::path> paths;
16633 if (fname.empty()) {
16634 wxGetApp().import_model(this, input_files);
16635 if (input_files.empty())
16636 return false;
16637
16638 for (const auto& file : input_files)
16639 paths.emplace_back(into_path(file));
16640 }
16641 else {
16642 paths.emplace_back(fname);
16643 }
16644
16645 std::string snapshot_label;
16646 assert(! paths.empty());
16647 if (paths.size() == 1) {
16648 snapshot_label = "Import Object";
16649 snapshot_label += ": ";
16650 snapshot_label += encode_path(paths.front().filename().string().c_str());
16651 } else {
16652 snapshot_label = "Import Objects";
16653 snapshot_label += ": ";
16654 snapshot_label += paths.front().filename().string().c_str();
16655 for (size_t i = 1; i < paths.size(); ++ i) {
16656 snapshot_label += ", ";
16657 snapshot_label += encode_path(paths[i].filename().string().c_str());
16658 }
16659 }
16660
16661 Plater::TakeSnapshot snapshot(this, snapshot_label);
16662
16663 // BBS: check file types
16664 auto loadfiles_type = LoadFilesType::NoFile;
16665 auto amf_files_count = get_3mf_file_count(paths);
16666
16667 if (paths.size() > 1 && amf_files_count < paths.size()) { loadfiles_type = LoadFilesType::Multiple3MFOther; }
16668 if (paths.size() > 1 && amf_files_count == paths.size()) { loadfiles_type = LoadFilesType::Multiple3MF; }
16669 if (paths.size() > 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::MultipleOther; }
16670 if (paths.size() == 1 && amf_files_count == 1) { loadfiles_type = LoadFilesType::Single3MF; };
16671 if (paths.size() == 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::SingleOther; };
16672
16673 bool ask_multi = false;
16674
16675 if (loadfiles_type == LoadFilesType::MultipleOther)
16676 ask_multi = true;
16677
16678 auto strategy = LoadStrategy::LoadModel;
16679 if (imperial_units) strategy = strategy | LoadStrategy::ImperialUnits;
16680 const bool loaded = !load_files(paths, strategy, ask_multi).empty();
16681 if (loaded) {
16682
16683 if (get_project_name() == _L("Untitled") && paths.size() > 0) {
16684 boost::filesystem::path full_path(paths[0].string());
16685 p->set_project_name(from_u8(full_path.stem().string()));
16686 }
16687
16688 wxGetApp().mainframe->update_title();
16689 }
16690 return loaded;
16691}
@ ImperialUnits
Definition bbs_3mf.hpp:226

References _L, Slic3r::encode_path(), Slic3r::GUI::from_u8(), get_3mf_file_count(), get_project_name(), Slic3r::ImperialUnits, Slic3r::GUI::into_path(), load_files(), Slic3r::LoadModel, Slic3r::GUI::Multiple3MF, Slic3r::GUI::Multiple3MFOther, Slic3r::GUI::MultipleOther, Slic3r::GUI::NoFile, p, Slic3r::GUI::Single3MF, and Slic3r::GUI::SingleOther.

Referenced by _calib_pa_tower(), _calib_temp_belt_sectioned(), Calib_Cornering(), calib_flowrate(), calib_input_shaping_damp(), calib_input_shaping_freq(), calib_max_vol_speed(), calib_pa(), calib_retraction(), calib_temp(), and calib_VFA().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_plate()

int Slic3r::GUI::Plater::add_plate ( )
23522{
23523 if (!p->can_add_plate())
23524 return -1;
23525 take_snapshot("add partplate");
23526 int new_plate = p->partplate_list.create_plate();
23527 if (new_plate < 0)
23528 return new_plate;
23529 p->partplate_list.select_plate(new_plate);
23530 update();
23531
23532 // BBS set default view
23533 //get_camera().select_view("topfront");
23534 p->camera.requires_zoom_to_plate = REQUIRES_ZOOM_TO_ALL_PLATE;
23535 return new_plate;
23536}
#define REQUIRES_ZOOM_TO_ALL_PLATE
Definition Camera.hpp:21
void take_snapshot(const std::string &snapshot_name)
Definition Plater.cpp:21281
void update(bool conside_update_flag=false, bool force_background_processing_update=false)
Definition Plater.cpp:19092

References p, REQUIRES_ZOOM_TO_ALL_PLATE, take_snapshot(), and update().

Here is the call graph for this function:

◆ allow_snapshots()

void Slic3r::GUI::Plater::allow_snapshots ( )
private
21286{ p->allow_snapshots(); }

References p.

◆ apply_background_progress()

void Slic3r::GUI::Plater::apply_background_progress ( )
22584{
22585 PartPlate* part_plate = p->partplate_list.get_curr_plate();
22586 int plate_index = p->partplate_list.get_curr_plate_index();
22587 bool result_valid = part_plate->is_slice_result_valid();
22588 const auto& preset_bundle = wxGetApp().preset_bundle;
22589 //always apply the current plate's print
22590 Print::ApplyStatus invalidated;
22591 if (preset_bundle->get_printer_extruder_count() > 1) {
22592 std::vector<int> f_maps = part_plate->get_real_filament_maps(preset_bundle->project_config);
22593 std::vector<int> f_volume_maps = part_plate->get_filament_volume_maps();
22594 if (f_volume_maps.empty()) {
22595 f_volume_maps = preset_bundle->get_default_nozzle_volume_types_for_filaments(f_maps);
22596 }
22597 invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false, f_maps, f_volume_maps));
22598 }
22599 else
22600 invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false));
22601
22602 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, after apply, invalidated= %3%, previous result_valid %4% ") % __LINE__ % plate_index % invalidated % result_valid;
22603 if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED)
22604 {
22605 part_plate->update_slice_result_valid_state(false);
22606 //p->ready_to_slice = true;
22607 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, true);
22608 }
22609}
@ eEventPlateUpdate
Definition MainFrame.hpp:338
ApplyStatus
Definition PrintBase.hpp:410
@ APPLY_STATUS_INVALIDATED
Definition PrintBase.hpp:417

References Slic3r::PrintBase::APPLY_STATUS_INVALIDATED, Slic3r::GUI::MainFrame::eEventPlateUpdate, Slic3r::GUI::PartPlate::get_filament_volume_maps(), Slic3r::GUI::PartPlate::get_real_filament_maps(), Slic3r::GUI::PartPlate::is_slice_result_valid(), model(), p, and Slic3r::GUI::PartPlate::update_slice_result_valid_state().

Here is the call graph for this function:

◆ apply_cut_object_to_model()

void Slic3r::GUI::Plater::apply_cut_object_to_model ( size_t init_obj_idx,
const ModelObjectPtrs & cut_objects )
19469{
19470 model().delete_object(obj_idx);
19472
19473 // suppress to call selection update for Object List to avoid call of early Gizmos on/off update
19474 p->load_model_objects(new_objects, false, false);
19475
19476 // now process all updates of the 3d scene
19477 update();
19478 // Update InfoItems in ObjectList after update() to use of a correct value of the GLCanvas3D::is_sinking(),
19479 // which is updated after a view3D->reload_scene(false, flags & (unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH) call
19480 for (size_t idx = 0; idx < p->model.objects.size(); idx++)
19481 wxGetApp().obj_list()->update_info_items(idx);
19482
19483 Selection& selection = p->get_selection();
19484 size_t last_id = p->model.objects.size() - 1;
19485 for (size_t i = 0; i < new_objects.size(); ++i)
19486 selection.add_object((unsigned int)(last_id - i), i == 0);
19487
19488 // UIThreadWorker w;
19489 // arrange(w, true);
19490 // w.wait_for_idle();
19491}
void delete_object_from_list()
Definition GUI_ObjectList.cpp:4352
void delete_object(size_t idx)
Definition Model.cpp:672

References Slic3r::GUI::Selection::add_object(), Slic3r::Model::delete_object(), Slic3r::GUI::ObjectList::delete_object_from_list(), model(), Slic3r::GUI::Sidebar::obj_list(), p, sidebar(), and update().

Referenced by cut_horizontal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ are_collision_volumes_shown()

bool Slic3r::GUI::Plater::are_collision_volumes_shown ( ) const
19133{
19134 return wxGetApp().app_config->get_bool("show_collision_volumes");
19135}

◆ are_view3D_labels_shown()

bool Slic3r::GUI::Plater::are_view3D_labels_shown ( ) const
19129{ return p->are_view3D_labels_shown(); }

References p.

Referenced by Slic3r::GUI::GLCanvas3D::_render_canvas_toolbar().

Here is the caller graph for this function:

◆ arrange()

void Slic3r::GUI::Plater::arrange ( )
22132{
22133 auto &w = get_ui_job_worker();
22134 if (w.is_idle()) {
22135 p->take_snapshot(_u8L("Arrange"));
22136 replace_job(w, std::make_unique<ArrangeJob>());
22137 }
22138}
Worker & get_ui_job_worker()
Definition Plater.cpp:19110
bool replace_job(Worker &w, Args &&...args)
Definition Worker.hpp:99
#define _u8L(s)
Definition I18N.hpp:11

References _u8L, get_ui_job_worker(), p, and Slic3r::GUI::replace_job().

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), increase_instances(), Slic3r::GUI::MenuFactory::load_handy_model(), and select_plate_by_hover_id().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ background_process()

BackgroundSlicingProcess & Slic3r::GUI::Plater::background_process ( )
22331{ return p->background_process; }

References p.

Referenced by Slic3r::DevNozzleMappingCtrl::CtrlGetAutoNozzleMappingV0(), and Slic3r::DevUtilBackend::GetNozzleGroupResult().

Here is the caller graph for this function:

◆ bring_instance_forward()

void Slic3r::GUI::Plater::bring_instance_forward ( )
24027{
24028 p->bring_instance_forward();
24029}

References p.

◆ build_volume()

const BuildVolume & Slic3r::GUI::Plater::build_volume ( ) const
23804{
23805 return p->bed.build_volume();
23806}

References p.

Referenced by find_new_position(), get_empty_cells(), and Slic3r::GUI::Plater::priv::update_print_volume_state().

Here is the caller graph for this function:

◆ Calib_Cornering()

void Slic3r::GUI::Plater::Calib_Cornering ( const Calib_Params & params)
18040{
18041 const auto Calib_Cornering = _L("Cornering test");
18042 new_project(false, false, Calib_Cornering);
18043 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
18044 if (params.mode != CalibMode::Calib_Cornering)
18045 return;
18046
18047 const std::string cornering_model_path = params.test_model == 0
18048 ? "/calib/input_shaping/ringing_tower.drc"
18049 : (params.test_model == 1 ? "/calib/input_shaping/fast_tower_test.drc" : "/calib/cornering/SCV-V2.drc");
18050 if (!add_model(false, Slic3r::resources_dir() + cornering_model_path))
18051 return;
18052 if (params.test_model == 0)
18054 auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
18055 auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
18056 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
18057
18059 printer_config->set_key_value("machine_max_junction_deviation", new ConfigOptionFloats{params.end});
18060 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "default_junction_deviation", 0);
18061 } else {
18062 printer_config->set_key_value("machine_max_jerk_x", new ConfigOptionFloats{params.end});
18063 printer_config->set_key_value("machine_max_jerk_y", new ConfigOptionFloats{params.end});
18064 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "default_jerk", 0);
18065 }
18066
18067 zero_pressure_advance_where_disabled(filament_config);
18068
18069 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
18070 printer_config->set_key_value("input_shaping_emit", new ConfigOptionBool{true});
18071 printer_config->set_key_value("input_shaping_type", new ConfigOptionEnum<InputShaperType>(InputShaperType::Disable));
18072 filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats { 0.0 });
18073 filament_config->set_key_value("slow_down_min_speed", new ConfigOptionFloats { 0.0 });
18074 filament_config->set_key_value("slow_down_for_layer_cooling", new ConfigOptionBools{false});
18075 const double filament_max_volumetric_speed = filament_config->option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
18076 filament_config->set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{std::max(filament_max_volumetric_speed, 200.0)});
18077 set_config_values<bool, ConfigOptionBools>(print_config, "enable_overhang_speed", false);
18078 print_config->set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
18079 print_config->set_key_value("wall_loops", new ConfigOptionInt(1));
18080 print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0));
18081 print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(1));
18082 print_config->set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
18083 print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false));
18084 print_config->set_key_value("spiral_mode", new ConfigOptionBool(true));
18085 print_config->set_key_value("spiral_mode_smooth", new ConfigOptionBool(false));
18086 print_config->set_key_value("bottom_surface_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
18087 const double machine_max_speed = std::min(printer_config->option<ConfigOptionFloats>("machine_max_speed_x")->get_at(0), printer_config->option<ConfigOptionFloats>("machine_max_speed_y")->get_at(0));
18088 const double machine_max_acceleration = printer_config->option<ConfigOptionFloats>("machine_max_acceleration_extruding")->get_at(0);
18089 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "outer_wall_speed", machine_max_speed);
18090 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "default_acceleration", machine_max_acceleration);
18091 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "outer_wall_acceleration", machine_max_acceleration);
18092 print_config->set_key_value("precise_z_height", new ConfigOptionBool(false));
18093 model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
18094 model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0));
18095 model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));
18096
18097 changed_objects({ 0 });
18098 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
18099 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
18100 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_ui_from_settings();
18101 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_ui_from_settings();
18102
18104 p->background_process.fff_print()->set_calib_params(params);
18105}
#define TAB_ID_PREPARE
Definition MainFrame.hpp:60
const double & get_at(size_t i) const
Definition Config.hpp:676
int new_project(bool skip_confirm=false, bool silent=false, const wxString &project_name=wxString(), bool reload_presets=true)
Definition Plater.cpp:16054
void Calib_Cornering(const Calib_Params &params)
Definition Plater.cpp:18039
static void zero_pressure_advance_where_disabled(DynamicPrintConfig *filament_config)
Definition Plater.cpp:395
static void belt_calib_flip_ringing_tower(Model &model)
Definition Plater.cpp:16734
@ btOuterOnly
Definition PrintConfig.hpp:458
@ ipRectilinear
Definition PrintConfig.hpp:128
@ Calib_Cornering
Definition calib.hpp:36
@ tlTraditional
Definition PrintConfig.hpp:469
ConfigOptionBoolsTempl< false > ConfigOptionBools
Definition Config.hpp:2066
@ Disable
Definition PrintConfig.hpp:578

References _calib_apply_belt_mode(), _L, add_model(), Slic3r::GUI::belt_calib_flip_ringing_tower(), Slic3r::btOuterOnly, Slic3r::Calib_Cornering, Calib_Cornering(), changed_objects(), Slic3r::ConfigOptionFloat, Slic3r::Disable, Slic3r::Calib_Params::end, Slic3r::GUI::has_junction_deviation(), Slic3r::ipRectilinear, Slic3r::Calib_Params::mode, model(), new_project(), Slic3r::Model::objects, p, Slic3r::GUI::printer_config(), Slic3r::resources_dir(), Slic3r::GUI::set_config_values(), TAB_ID_PREPARE, Slic3r::Calib_Params::test_model, Slic3r::tlTraditional, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, and Slic3r::GUI::zero_pressure_advance_where_disabled().

Referenced by Calib_Cornering().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calib_flowrate()

void Slic3r::GUI::Plater::calib_flowrate ( bool is_linear,
int pass,
InfillPattern pattern = ipArchimedeanChords )
17329 {
17330 if (pass != 1 && pass != 2)
17331 return;
17332 wxString calib_name;
17333 if (is_linear) {
17334 calib_name = pass == 2 ? _L("Orca YOLO Flow Calibration - Perfectionist version") : _L("Orca YOLO Flow Calibration");
17335 } else
17336 calib_name = wxString::Format(_L("Flowrate Test - Pass%d"), pass);
17337
17338 if (new_project(false, false, calib_name) == wxID_CANCEL)
17339 return;
17340
17341 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
17342
17343 if (is_linear) {
17344 if (pass == 1)
17345 add_model(false,
17346 (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "Orca-LinearFlow.3mf").string());
17347 else
17348 add_model(false,
17349 (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "Orca-LinearFlow_fine.3mf").string());
17350 } else {
17351 if (pass == 1)
17352 add_model(false,
17353 (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass1.3mf").string());
17354 else
17355 add_model(false,
17356 (boost::filesystem::path(Slic3r::resources_dir()) / "calib" / "filament_flow" / "flowrate-test-pass2.3mf").string());
17357 }
17358
17359 // ORCA: pass the pattern
17360 adjust_settings_for_flowrate_calib(model().objects, is_linear, pass, pattern);
17361 wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config();
17362 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
17363 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
17364
17366
17367 // Refresh object after scaling
17368 const std::vector<size_t> object_idx(boost::counting_iterator<size_t>(0), boost::counting_iterator<size_t>(model().objects.size()));
17369 changed_objects(object_idx);
17370}
void adjust_settings_for_flowrate_calib(ModelObjectPtrs &objects, bool linear, int pass, InfillPattern pattern)
Definition Plater.cpp:17206

References _calib_apply_belt_mode(), _L, add_model(), Slic3r::GUI::adjust_settings_for_flowrate_calib(), changed_objects(), model(), new_project(), Slic3r::GUI::printer_config(), Slic3r::resources_dir(), TAB_ID_PREPARE, and Slic3r::Preset::TYPE_PRINTER.

Here is the call graph for this function:

◆ calib_input_shaping_damp()

void Slic3r::GUI::Plater::calib_input_shaping_damp ( const Calib_Params & params)
17973{
17974 const auto calib_input_shaping_name = _L("Input shaping Damping test");
17975 new_project(false, false, calib_input_shaping_name);
17976 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
17977 if (params.mode != CalibMode::Calib_Input_shaping_damp)
17978 return;
17979
17980 if (!add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.drc" : "/calib/input_shaping/fast_tower_test.drc")))
17981 return;
17982 if (params.test_model < 1)
17984 auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
17985 auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
17986 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
17987 const auto gcode_flavor_option = printer_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor");
17988
17990 printer_config->set_key_value("machine_max_junction_deviation", new ConfigOptionFloats {(std::max(printer_config->option<ConfigOptionFloats>("machine_max_junction_deviation")->values.front(), 0.25))});
17991 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "default_junction_deviation", 0);
17992 } else {
17993 const double jerk_value = (gcode_flavor_option && gcode_flavor_option->value == GCodeFlavor::gcfKlipper) ? 5.0 : 10.0;
17994 printer_config->set_key_value("machine_max_jerk_x", new ConfigOptionFloats{std::max(printer_config->option<ConfigOptionFloats>("machine_max_jerk_x")->values.front(), jerk_value)});
17995 printer_config->set_key_value("machine_max_jerk_y", new ConfigOptionFloats{std::max(printer_config->option<ConfigOptionFloats>("machine_max_jerk_y")->values.front(), jerk_value)});
17996 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "default_jerk", 0);
17997 }
17998
17999 zero_pressure_advance_where_disabled(filament_config);
18000
18001 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
18002 printer_config->set_key_value("input_shaping_emit", new ConfigOptionBool{false});
18003 filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats { 0.0 });
18004 filament_config->set_key_value("slow_down_min_speed", new ConfigOptionFloats { 0.0 });
18005 filament_config->set_key_value("slow_down_for_layer_cooling", new ConfigOptionBools{false});
18006 set_config_values<bool, ConfigOptionBools>(print_config, "enable_overhang_speed", false);
18007 // A 100% factor sends Klipper MINIMUM_CRUISE_RATIO=0 with every acceleration change, for the whole test.
18008 print_config->set_key_value("accel_to_decel_enable", new ConfigOptionBool(true));
18009 print_config->set_key_value("accel_to_decel_factor", new ConfigOptionPercent(100));
18010 print_config->set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
18011 print_config->set_key_value("wall_loops", new ConfigOptionInt(1));
18012 print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0));
18013 print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(1));
18014 print_config->set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
18015 print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false));
18016 print_config->set_key_value("spiral_mode", new ConfigOptionBool(true));
18017 print_config->set_key_value("spiral_mode_smooth", new ConfigOptionBool(false));
18018 print_config->set_key_value("bottom_surface_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
18019 const double machine_max_speed = std::min(printer_config->option<ConfigOptionFloats>("machine_max_speed_x")->get_at(0), printer_config->option<ConfigOptionFloats>("machine_max_speed_y")->get_at(0));
18020 const double machine_max_acceleration = printer_config->option<ConfigOptionFloats>("machine_max_acceleration_extruding")->get_at(0);
18021 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "outer_wall_speed", machine_max_speed);
18022 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "default_acceleration", machine_max_acceleration);
18023 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "outer_wall_acceleration", machine_max_acceleration);
18024 print_config->set_key_value("precise_z_height", new ConfigOptionBool(false));
18025 model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
18026 model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0));
18027 model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));
18028
18029 changed_objects({ 0 });
18030 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
18031 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
18032 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_ui_from_settings();
18033 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_ui_from_settings();
18034
18036 p->background_process.fff_print()->set_calib_params(params);
18037}
std::vector< double > values
Definition Config.hpp:418
@ gcfKlipper
Definition PrintConfig.hpp:53
@ Calib_Input_shaping_damp
Definition calib.hpp:35

References _calib_apply_belt_mode(), _L, add_model(), Slic3r::GUI::belt_calib_flip_ringing_tower(), Slic3r::btOuterOnly, Slic3r::Calib_Input_shaping_damp, changed_objects(), Slic3r::ConfigOptionFloat, Slic3r::gcfKlipper, Slic3r::GUI::has_junction_deviation(), Slic3r::ipRectilinear, Slic3r::Calib_Params::mode, model(), new_project(), Slic3r::Model::objects, p, Slic3r::GUI::printer_config(), Slic3r::resources_dir(), Slic3r::GUI::set_config_values(), TAB_ID_PREPARE, Slic3r::Calib_Params::test_model, Slic3r::tlTraditional, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, and Slic3r::GUI::zero_pressure_advance_where_disabled().

Here is the call graph for this function:

◆ calib_input_shaping_freq()

void Slic3r::GUI::Plater::calib_input_shaping_freq ( const Calib_Params & params)
17905{
17906 const auto calib_input_shaping_name = _L("Input shaping Frequency test");
17907 new_project(false, false, calib_input_shaping_name);
17908 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
17909 if (params.mode != CalibMode::Calib_Input_shaping_freq)
17910 return;
17911
17912 if (!add_model(false, Slic3r::resources_dir() + (params.test_model < 1 ? "/calib/input_shaping/ringing_tower.drc" : "/calib/input_shaping/fast_tower_test.drc")))
17913 return;
17914 if (params.test_model < 1)
17916 auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
17917 auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
17918 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
17919 const auto gcode_flavor_option = printer_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor");
17920
17922 printer_config->set_key_value("machine_max_junction_deviation", new ConfigOptionFloats {(std::max(printer_config->option<ConfigOptionFloats>("machine_max_junction_deviation")->values.front(), 0.25))});
17923 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "default_junction_deviation", 0);
17924 } else {
17925 const double jerk_value = (gcode_flavor_option && gcode_flavor_option->value == GCodeFlavor::gcfKlipper) ? 5.0 : 10.0;
17926 printer_config->set_key_value("machine_max_jerk_x", new ConfigOptionFloats{std::max(printer_config->option<ConfigOptionFloats>("machine_max_jerk_x")->values.front(), jerk_value)});
17927 printer_config->set_key_value("machine_max_jerk_y", new ConfigOptionFloats{std::max(printer_config->option<ConfigOptionFloats>("machine_max_jerk_y")->values.front(), jerk_value)});
17928 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "default_jerk", 0);
17929 }
17930
17931 zero_pressure_advance_where_disabled(filament_config);
17932
17933 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
17934 printer_config->set_key_value("input_shaping_emit", new ConfigOptionBool{false});
17935 filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats { 0.0 });
17936 filament_config->set_key_value("slow_down_min_speed", new ConfigOptionFloats { 0.0 });
17937 filament_config->set_key_value("slow_down_for_layer_cooling", new ConfigOptionBools{false});
17938 print_config->set_key_value("layer_height", new ConfigOptionFloat(0.2));
17939 set_config_values<bool, ConfigOptionBools>(print_config, "enable_overhang_speed", false);
17940 // A 100% factor sends Klipper MINIMUM_CRUISE_RATIO=0 with every acceleration change, for the whole test.
17941 print_config->set_key_value("accel_to_decel_enable", new ConfigOptionBool(true));
17942 print_config->set_key_value("accel_to_decel_factor", new ConfigOptionPercent(100));
17943 print_config->set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
17944 print_config->set_key_value("wall_loops", new ConfigOptionInt(1));
17945 print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0));
17946 print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(1));
17947 print_config->set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
17948 print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false));
17949 print_config->set_key_value("spiral_mode", new ConfigOptionBool(true));
17950 print_config->set_key_value("spiral_mode_smooth", new ConfigOptionBool(false));
17951 print_config->set_key_value("bottom_surface_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
17952 const double machine_max_speed = std::min(printer_config->option<ConfigOptionFloats>("machine_max_speed_x")->get_at(0), printer_config->option<ConfigOptionFloats>("machine_max_speed_y")->get_at(0));
17953 const double machine_max_acceleration = printer_config->option<ConfigOptionFloats>("machine_max_acceleration_extruding")->get_at(0);
17954 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "outer_wall_speed", machine_max_speed);
17955 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "default_acceleration", machine_max_acceleration);
17956 set_config_values<double, ConfigOptionFloatsNullable>(print_config, "outer_wall_acceleration", machine_max_acceleration);
17957 print_config->set_key_value("precise_z_height", new ConfigOptionBool(false));
17958 model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
17959 model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0));
17960 model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));
17961
17962 changed_objects({ 0 });
17963 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
17964 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
17965 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_ui_from_settings();
17966 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_ui_from_settings();
17967
17969 p->background_process.fff_print()->set_calib_params(params);
17970}
@ Calib_Input_shaping_freq
Definition calib.hpp:34

References _calib_apply_belt_mode(), _L, add_model(), Slic3r::GUI::belt_calib_flip_ringing_tower(), Slic3r::btOuterOnly, Slic3r::Calib_Input_shaping_freq, changed_objects(), Slic3r::ConfigOptionFloat, Slic3r::gcfKlipper, Slic3r::GUI::has_junction_deviation(), Slic3r::ipRectilinear, Slic3r::Calib_Params::mode, model(), new_project(), Slic3r::Model::objects, p, Slic3r::GUI::printer_config(), Slic3r::resources_dir(), Slic3r::GUI::set_config_values(), TAB_ID_PREPARE, Slic3r::Calib_Params::test_model, Slic3r::tlTraditional, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, and Slic3r::GUI::zero_pressure_advance_where_disabled().

Here is the call graph for this function:

◆ calib_max_vol_speed()

void Slic3r::GUI::Plater::calib_max_vol_speed ( const Calib_Params & params)
17677{
17678 const auto calib_vol_speed_name = _L("Max volumetric speed test");
17679 new_project(false, false, calib_vol_speed_name);
17680 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
17681 if (params.mode != CalibMode::Calib_Vol_speed_Tower)
17682 return;
17683 if (!add_model(false, Slic3r::resources_dir() + "/calib/volumetric_speed/SpeedTestStructure.drc"))
17684 return;
17685
17686 auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
17687 auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
17688 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
17689 auto obj = model().objects[0];
17690 auto& obj_cfg = obj->config;
17691
17692 auto bed_shape = printer_config->option<ConfigOptionPoints>("printable_area")->values;
17693 BoundingBoxf bed_ext = get_extents(bed_shape);
17694 auto scale_obj = (bed_ext.size().x() - 10) / obj->bounding_box_exact().size().x();
17695 if (scale_obj < 1.0)
17696 obj->scale(scale_obj, 1, 1);
17697
17698 const ConfigOptionFloats* nozzle_diameter_config = printer_config->option<ConfigOptionFloats>("nozzle_diameter");
17699 assert(nozzle_diameter_config->values.size() > 0);
17700 double nozzle_diameter = nozzle_diameter_config->values[0];
17701 double line_width = nozzle_diameter * 1.75;
17702 double layer_height = nozzle_diameter * 0.8;
17703
17704 auto max_lh = printer_config->option<ConfigOptionFloats>("max_layer_height");
17705 for (size_t i = 0; i < max_lh->values.size(); ++i) {
17706 if (max_lh->values[i] < layer_height)
17707 max_lh->values[i] = layer_height;
17708 }
17709
17710 const double filament_max_volumetric_speed = filament_config->option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
17711 set_config_values<double, ConfigOptionFloats>(filament_config, "filament_max_volumetric_speed", std::max(filament_max_volumetric_speed, 200.0));
17712 filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats{0.0});
17713 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
17714 obj_cfg.set_key_value("enable_overhang_speed", new ConfigOptionBoolsNullable(1, false));
17715 obj_cfg.set_key_value("wall_loops", new ConfigOptionInt(1));
17716 obj_cfg.set_key_value("alternate_extra_wall", new ConfigOptionBool(false));
17717 obj_cfg.set_key_value("top_shell_layers", new ConfigOptionInt(0));
17718 obj_cfg.set_key_value("bottom_shell_layers", new ConfigOptionInt(0));
17719 obj_cfg.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
17720 obj_cfg.set_key_value("outer_wall_line_width", new ConfigOptionFloatOrPercent(line_width, false));
17721 obj_cfg.set_key_value("layer_height", new ConfigOptionFloat(layer_height));
17722 obj_cfg.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterAndInner));
17723 obj_cfg.set_key_value("brim_width", new ConfigOptionFloat(5.0));
17724 obj_cfg.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));
17725 obj_cfg.set_key_value("precise_z_height", new ConfigOptionBool(false));
17726 print_config->set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
17727 print_config->set_key_value("spiral_mode", new ConfigOptionBool(true));
17728 print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0));
17729 print_config->set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
17730
17731 changed_objects({ 0 });
17732 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
17733 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
17734 wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty();
17735 wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
17736 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
17737 wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config();
17738
17739 // cut upper
17740 auto obj_bb = obj->bounding_box_exact();
17741 auto height = (params.end - params.start + 1) / params.step;
17742 if (height < obj_bb.size().z()) {
17744 }
17745
17747
17748 auto new_params = params;
17749 auto mm3_per_mm = Flow(line_width, layer_height, nozzle_diameter).mm3_per_mm() * filament_config->option<ConfigOptionFloatsNullable>("filament_flow_ratio")->get_at(0);
17750 new_params.end = params.end / mm3_per_mm;
17751 new_params.start = params.start / mm3_per_mm;
17752 new_params.step = params.step / mm3_per_mm;
17753
17754 p->background_process.fff_print()->set_calib_params(new_params);
17755}
static std::string layer_height
Definition Tab.cpp:4294
coord_t height(const BoundingBox &box)
Definition Arrange.cpp:1185
@ btOuterAndInner
Definition PrintConfig.hpp:460
ConfigOptionBoolsTempl< true > ConfigOptionBoolsNullable
Definition Config.hpp:2067
@ Calib_Vol_speed_Tower
Definition calib.hpp:31
BoundingBox get_extents(const ExPolygonsWithIds &e)
Definition Emboss.cpp:1374

References _calib_apply_belt_mode(), _L, add_model(), Slic3r::ModelObject::bounding_box_exact(), Slic3r::btOuterAndInner, Slic3r::Calib_Vol_speed_Tower, changed_objects(), Slic3r::ModelObject::config, Slic3r::ConfigOptionFloat, cut_horizontal(), Slic3r::Calib_Params::end, Slic3r::get_extents(), Slic3r::KeepLower, Slic3r::GUI::layer_height, Slic3r::Flow::mm3_per_mm(), Slic3r::Calib_Params::mode, model(), new_project(), Slic3r::nozzle_diameter(), Slic3r::Model::objects, p, Slic3r::GUI::printer_config(), Slic3r::resources_dir(), Slic3r::ModelObject::scale(), Slic3r::GUI::set_config_values(), Slic3r::BoundingBox3Base< PointType >::size(), Slic3r::Calib_Params::start, Slic3r::Calib_Params::step, TAB_ID_PREPARE, Slic3r::tlTraditional, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, Slic3r::Preset::TYPE_PRINTER, and Slic3r::ConfigOptionVector< double >::values.

Here is the call graph for this function:

◆ calib_pa()

void Slic3r::GUI::Plater::calib_pa ( const Calib_Params & params)
16840{
16841 // ORCA-Belt: PA Line / PA Pattern have the belt plumbing in place
16842 // (belt kinematics in world-coordinates mode draws them on the belt surface)
16843 // but are not validated yet — keep them gated to the PA Tower for now.
16844 {
16845 double angle_rad = 0.;
16846 Vec3d axis = Vec3d::UnitX();
16847 if (belt_calib_rotation_params(angle_rad, axis) && params.mode != CalibMode::Calib_PA_Tower) {
16848 MessageDialog msg_dlg(nullptr, _L("PA Line and PA Pattern tests are not enabled yet on belt printers.\nPlease use the PA Tower method instead."),
16849 wxEmptyString, wxICON_WARNING | wxOK);
16850 msg_dlg.ShowModal();
16851 return;
16852 }
16853 }
16854 const auto calib_pa_name = _L("Pressure Advance Test");
16855 new_project(false, false, calib_pa_name);
16856 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
16857 auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
16858 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
16859 print_config->set_key_value("overhang_reverse", new ConfigOptionBool(false));
16860 print_config->set_key_value("precise_z_height", new ConfigOptionBool(false));
16861 print_config->set_key_value("wipe_inward", new ConfigOptionBool(false));
16862 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
16863 switch (params.mode) {
16865 add_model(false, Slic3r::resources_dir() + "/calib/pressure_advance/pressure_advance_test.drc");
16866 break;
16868 _calib_pa_pattern(params);
16869 break;
16871 _calib_pa_tower(params);
16872 break;
16873 default: break;
16874 }
16875 p->background_process.fff_print()->set_calib_params(params);
16876}
void _calib_pa_tower(const Calib_Params &params)
Definition Plater.cpp:17136
void _calib_pa_pattern(const Calib_Params &params)
Definition Plater.cpp:16878
@ Calib_PA_Line
Definition calib.hpp:25
@ Calib_PA_Pattern
Definition calib.hpp:26
@ Calib_PA_Tower
Definition calib.hpp:27

References _calib_pa_pattern(), _calib_pa_tower(), _L, add_model(), Slic3r::GUI::belt_calib_rotation_params(), Slic3r::Calib_PA_Line, Slic3r::Calib_PA_Pattern, Slic3r::Calib_PA_Tower, Slic3r::Calib_Params::mode, new_project(), p, Slic3r::GUI::printer_config(), Slic3r::resources_dir(), Slic3r::GUI::DPIAware< P >::ShowModal(), and TAB_ID_PREPARE.

Here is the call graph for this function:

◆ calib_retraction()

void Slic3r::GUI::Plater::calib_retraction ( const Calib_Params & params)
17758{
17759 const auto calib_retraction_name = _L("Retraction");
17760 new_project(false, false, calib_retraction_name);
17761 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
17762 if (params.mode != CalibMode::Calib_Retraction_tower)
17763 return;
17764
17765 if (!add_model(false, Slic3r::resources_dir() + "/calib/retraction/retraction_tower.drc"))
17766 return;
17767
17768 auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
17769 auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
17770 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
17771 auto obj = model().objects[0];
17772
17773 print_config->set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
17774 print_config->set_key_value("wipe_inward", new ConfigOptionBool(false));
17775
17776 float nozzle_diameter = printer_config->option<ConfigOptionFloats>("nozzle_diameter")->get_at(0);
17777 float layer_height;
17778 if (nozzle_diameter <= 0.1f) {
17779 layer_height = 0.05f;
17780 } else if (nozzle_diameter <= 0.2f) {
17781 layer_height = 0.1f;
17782 } else {
17783 layer_height = 0.2f;
17784 }
17785
17786 auto max_lh = printer_config->option<ConfigOptionFloats>("max_layer_height");
17787 for (size_t i = 0; i < max_lh->values.size(); ++i) {
17788 if (max_lh->values[i] < layer_height) max_lh->values[i] = layer_height;
17789 }
17790
17791 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
17792 printer_config->set_key_value("use_firmware_retraction", new ConfigOptionBool(false));
17793 obj->config.set_key_value("wall_loops", new ConfigOptionInt(2));
17794 obj->config.set_key_value("top_shell_layers", new ConfigOptionInt(0));
17795 obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(3));
17796 obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
17797 print_config->set_key_value("initial_layer_print_height", new ConfigOptionFloat(layer_height));
17798 obj->config.set_key_value("layer_height", new ConfigOptionFloat(layer_height));
17799 obj->config.set_key_value("alternate_extra_wall", new ConfigOptionBool(false));
17800 obj->config.set_key_value("seam_position", new ConfigOptionEnum<SeamPosition>(spAligned));
17801 obj->config.set_key_value("wall_sequence", new ConfigOptionEnum<WallSequence>(WallSequence::InnerOuter));
17802 obj->config.set_key_value("overhang_reverse", new ConfigOptionBool(false));
17803 obj->config.set_key_value("precise_z_height", new ConfigOptionBool(false));
17804 obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum<SeamScarfType>(SeamScarfType::None));
17805
17806
17807 changed_objects({ 0 });
17808
17809 // cut upper
17810 auto obj_bb = obj->bounding_box_exact();
17811 auto height = 1.0 + 0.4 + ((params.end - params.start)) / params.step - EPSILON;
17812 if (height < obj_bb.size().z()) {
17814 }
17815
17817 p->background_process.fff_print()->set_calib_params(params);
17818}
@ spAligned
Definition PrintConfig.hpp:395
@ Calib_Retraction_tower
Definition calib.hpp:33
@ InnerOuter
Definition PrintConfig.hpp:246

References _calib_apply_belt_mode(), _L, add_model(), Slic3r::ModelObject::bounding_box_exact(), Slic3r::Calib_Retraction_tower, changed_objects(), Slic3r::ModelObject::config, Slic3r::ConfigOptionFloat, cut_horizontal(), Slic3r::Calib_Params::end, EPSILON, Slic3r::InnerOuter, Slic3r::KeepLower, Slic3r::GUI::layer_height, Slic3r::Calib_Params::mode, model(), new_project(), Slic3r::None, Slic3r::nozzle_diameter(), Slic3r::Model::objects, p, Slic3r::GUI::printer_config(), Slic3r::resources_dir(), Slic3r::ModelConfig::set_key_value(), Slic3r::spAligned, Slic3r::Calib_Params::start, Slic3r::Calib_Params::step, and TAB_ID_PREPARE.

Here is the call graph for this function:

◆ calib_temp()

void Slic3r::GUI::Plater::calib_temp ( const Calib_Params & params)
17383 {
17384 constexpr double base_temp_tower_nozzle_diameter = 0.4;
17385 constexpr double base_temp_tower_block_height = 10.0;
17386 constexpr int base_temp_tower_temp_step = 5;
17387
17388 // A belt provini tower exists only for the ranges it was embossed for, and another
17389 // range's model would print numbers that do not match its temperatures. Refuse
17390 // before the current project is replaced.
17391 if (params.mode == CalibMode::Calib_Temp_Tower && params.test_model >= 1) {
17392 const auto &printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
17393 if (printer_config.has("belt_printer") && printer_config.opt_bool("belt_printer") &&
17394 ! boost::filesystem::exists(belt_temp_tower_asset(params))) {
17395 MessageDialog dlg(static_cast<wxWindow *>(wxGetApp().mainframe),
17396 format_wxstr(_L("No belt temperature tower is available for the range %1% to %2%℃. "
17397 "Use a range the tower models cover, for example 230 to 190."),
17398 (int) lround(params.start), (int) lround(params.end)),
17399 _L("Temperature tower"), wxICON_ERROR | wxOK);
17400 dlg.ShowModal();
17401 return;
17402 }
17403 }
17404
17405 const auto calib_temp_name = _L("Nozzle temperature test");
17406 new_project(false, false, calib_temp_name);
17407 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
17408 if (params.mode != CalibMode::Calib_Temp_Tower)
17409 return;
17410
17411 // Belt printers build along the conveyor, not vertically — a tall tower cannot
17412 // be sliced. Instead lay a row of DISCRETE provini (one per temperature) along
17413 // the belt and change temperature in discrete steps via custom per-layer G-code
17414 // (M104), injected in the empty gap just before each provino so the nozzle is
17415 // settled by the time that provino prints. We deliberately do NOT call
17416 // set_calib_params here: its per-layer interpolation (interpolate_value_across_
17417 // layers) would overwrite these discrete M104 events.
17418 {
17419 auto belt_printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
17420 if (belt_printer_config->has("belt_printer") && belt_printer_config->opt_bool("belt_printer")) {
17421 // Belt temperature-tower model selector (Calib_Params::test_model):
17422 // 0 = "Standard" -> Joe's counter-rotated sectioned tower.
17423 // 1 = "Overhang" -> engraved inverted-L provini that stress overhang
17424 // print-quality at each discrete temperature (below).
17425 if (params.test_model < 1) {
17426 double belt_angle_rad = 0.; Vec3d belt_axis = Vec3d::UnitX();
17427 belt_calib_rotation_params(belt_angle_rad, belt_axis);
17428 _calib_temp_belt_sectioned(params, std::abs(belt_angle_rad));
17429 return;
17430 }
17431 constexpr int TEMP_STEP = 5; // matches Temp_Calibration_Dlg
17432 // Shared geometry contract with the offline asset generator
17433 // (resources/calib/temperature_tower/gen_belt_temp_tower.py): provini are
17434 // replicated along the belt (designed Y) at this pitch. The slicing plane
17435 // is oblique (belt_slice_rotation_angle), so the per-zone advance in the
17436 // layer print_z space the custom-gcode matcher uses is PITCH*cos(theta).
17437 constexpr double PITCH_Y = 74.718; // designed-Y pitch == gen PITCH
17438 const double angle = belt_printer_config->has("belt_slice_rotation_angle")
17439 ? belt_printer_config->opt_float("belt_slice_rotation_angle") : 45.0;
17440 const double zone_topz = PITCH_Y * std::cos(angle * M_PI / 180.0);
17441 // The custom-gcode matcher attaches each event to a real sliced layer. The
17442 // empty inter-provino gap has NO layers, so an event placed there is silently
17443 // dropped. Fire it 70 layers ABOVE provino i's start instead — inside the
17444 // provino body, past the gap and the overlap with provino i-1's tail, so the
17445 // temperature change attaches and applies cleanly. (layer print_z steps by the
17446 // process layer height.)
17447 auto belt_print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
17448 const double layer_h = belt_print_config->has("layer_height")
17449 ? belt_print_config->opt_float("layer_height") : 0.2;
17450 const double into_provino = 70.0 * layer_h;
17451
17452 const int t_start = (int) lround(params.start);
17453 const int t_end = (int) lround(params.end);
17454 std::vector<int> temps;
17455 const int tstep = (t_start >= t_end) ? -TEMP_STEP : TEMP_STEP;
17456 for (int t = t_start; (tstep < 0) ? (t >= t_end) : (t <= t_end); t += tstep)
17457 temps.push_back(t);
17458 if (temps.empty()) temps.push_back(t_start);
17459
17460 const std::string asset = belt_temp_tower_asset(params);
17461 if (!boost::filesystem::exists(asset)) // refused above, before new_project()
17462 return;
17463 if (!add_model(false, asset) || model().objects.empty())
17464 return;
17465
17466 // Place keel-first asset at the belt entry (designed Y = 0) so Z_gcode
17467 // starts at 0, centered laterally on the bed, resting on the conveyor.
17468 ModelObject* obj = model().objects[0];
17469 obj->ensure_on_bed();
17470 BoundingBoxf3 obb = obj->bounding_box_exact();
17471 auto bed_shape = belt_printer_config->option<ConfigOptionPoints>("printable_area")->values;
17472 BoundingBoxf bed_ext = get_extents(bed_shape);
17473 obj->translate_instances(Vec3d(bed_ext.center().x() - obb.center().x(), -obb.min.y(), 0.0));
17474
17475 auto belt_filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
17476 belt_filament_config->set_key_value("nozzle_temperature_initial_layer", new ConfigOptionInts(1, temps.front()));
17477 belt_filament_config->set_key_value("nozzle_temperature", new ConfigOptionInts(1, temps.front()));
17478 obj->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btNoBrim));
17479 obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum<SeamScarfType>(SeamScarfType::None));
17480 obj->config.set_key_value("overhang_reverse", new ConfigOptionBool(false));
17481 belt_printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
17482
17483 const int plate_idx = get_partplate_list().get_curr_plate_index();
17484 model().curr_plate_index = plate_idx;
17485 CustomGCode::Info &cg_info = model().plates_custom_gcodes[plate_idx];
17486 cg_info.mode = CustomGCode::Mode::SingleExtruder;
17487 cg_info.gcodes.clear();
17488 for (size_t i = 1; i < temps.size(); ++i) {
17489 const double pz = double(i) * zone_topz + into_provino; // 70 layers into provino i
17490 cg_info.gcodes.push_back(CustomGCode::Item{
17491 pz, CustomGCode::Custom, 1, "",
17492 "M104 S" + std::to_string(temps[i]) + " ; belt temp zone " + std::to_string(temps[i]) });
17493 }
17494
17495 changed_objects({ 0 });
17496 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
17497 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
17498 return;
17499 }
17500 }
17501
17502 if (!add_model(false, Slic3r::resources_dir() + "/calib/temperature_tower/temperature_tower.drc"))
17503 return;
17504 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
17505 auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
17506 auto start_temp = lround(params.start);
17507 const ConfigOptionFloats* nozzle_diameter_config = printer_config->option<ConfigOptionFloats>("nozzle_diameter");
17508 size_t nozzle_id = static_cast<size_t>(std::max(params.extruder_id, 0));
17509 double nozzle_diameter = base_temp_tower_nozzle_diameter;
17510 if (nozzle_diameter_config && !nozzle_diameter_config->values.empty()) {
17511 nozzle_id = std::min(nozzle_id, nozzle_diameter_config->values.size() - 1);
17512 nozzle_diameter = nozzle_diameter_config->values[nozzle_id];
17513 }
17514 if (nozzle_diameter <= 0.0)
17515 nozzle_diameter = base_temp_tower_nozzle_diameter;
17516
17517 const double nozzle_scale = nozzle_diameter / base_temp_tower_nozzle_diameter;
17518 const double block_height = base_temp_tower_block_height;
17519
17520 // cut upper
17521 auto obj_bb = model().objects[0]->bounding_box_exact();
17522 auto block_count = lround((500 - params.end) / base_temp_tower_temp_step + 1);
17523 if (block_count > 0) {
17524 // subtract EPSILON offset to avoid cutting at the exact location where the flat surface is
17525 auto new_height = block_count * block_height - EPSILON;
17526 if (new_height < obj_bb.size().z()) {
17528 }
17529 }
17530
17531 // cut bottom
17532 obj_bb = model().objects[0]->bounding_box_exact();
17533 block_count = lround((500 - params.start) / base_temp_tower_temp_step);
17534 if (block_count > 0) {
17535 auto new_height = block_count * block_height + EPSILON;
17536 if (new_height < obj_bb.size().z()) {
17538 }
17539 }
17540
17541 if (params.nozzle_based_resize && std::abs(nozzle_scale - 1.0) > EPSILON)
17542 model().objects[0]->scale(nozzle_scale, nozzle_scale, nozzle_scale);
17543
17544 model().objects[0]->ensure_on_bed();
17545
17546 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
17547 set_config_values<int, ConfigOptionInts>(filament_config, "nozzle_temperature_initial_layer", (int) start_temp);
17548 set_config_values<int, ConfigOptionInts>(filament_config, "nozzle_temperature", (int) start_temp);
17549 // When resizing is disabled the 0.4 mm / 0.2 mm reference model is printed as-is (preset layer height kept).
17550 if (params.nozzle_based_resize)
17551 model().objects[0]->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter/2));
17552 model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
17553 model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(5.0));
17554 model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));
17555 model().objects[0]->config.set_key_value("alternate_extra_wall", new ConfigOptionBool(false));
17556 model().objects[0]->config.set_key_value("seam_slope_type", new ConfigOptionEnum<SeamScarfType>(SeamScarfType::None));
17557 model().objects[0]->config.set_key_value("overhang_reverse", new ConfigOptionBool(false));
17558 model().objects[0]->config.set_key_value("precise_z_height", new ConfigOptionBool(false));
17559
17560 auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
17561 print_config->set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
17562 if (params.nozzle_based_resize)
17563 print_config->set_key_value("initial_layer_print_height", new ConfigOptionFloat(nozzle_diameter/2));
17564
17565
17566 changed_objects({ 0 });
17567 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
17568 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
17569 wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
17570 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
17571
17572 p->background_process.fff_print()->set_calib_params(params);
17573}
#define M_PI
Definition ExtrusionSimulator.cpp:31
bool has(const t_config_option_key &opt_key) const
Definition Config.hpp:2697
bool opt_bool(const t_config_option_key &opt_key) const
Definition Config.hpp:3072
void _calib_temp_belt_sectioned(const Calib_Params &params, double belt_angle_rad)
Definition Plater.cpp:17583
int curr_plate_index
Definition Model.hpp:1742
@ SingleExtruder
Definition CustomGCode.hpp:56
@ Custom
Definition CustomGCode.hpp:23
static std::string belt_temp_tower_asset(const Calib_Params &params)
Definition Plater.cpp:17375
@ btNoBrim
Definition PrintConfig.hpp:461
@ Calib_Temp_Tower
Definition calib.hpp:30
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138

References _calib_temp_belt_sectioned(), _L, add_model(), Slic3r::angle(), Slic3r::GUI::belt_calib_rotation_params(), Slic3r::GUI::belt_temp_tower_asset(), Slic3r::ModelObject::bounding_box_exact(), Slic3r::btNoBrim, Slic3r::btOuterOnly, Slic3r::Calib_Temp_Tower, Slic3r::BoundingBox3Base< PointType >::center(), changed_objects(), Slic3r::ModelObject::config, Slic3r::ConfigOptionFloat, Slic3r::Model::curr_plate_index, Slic3r::CustomGCode::Custom, cut_horizontal(), Slic3r::Calib_Params::end, Slic3r::ModelObject::ensure_on_bed(), EPSILON, Slic3r::Calib_Params::extruder_id, Slic3r::GUI::format_wxstr(), Slic3r::CustomGCode::Info::gcodes, Slic3r::GUI::PartPlateList::get_curr_plate_index(), Slic3r::get_extents(), get_partplate_list(), Slic3r::KeepLower, Slic3r::KeepUpper, M_PI, Slic3r::BoundingBoxBase< PointType, std::vector< PointType > >::min, Slic3r::Calib_Params::mode, Slic3r::CustomGCode::Info::mode, model(), new_project(), Slic3r::None, Slic3r::Calib_Params::nozzle_based_resize, Slic3r::nozzle_diameter(), Slic3r::Model::objects, p, Slic3r::Model::plates_custom_gcodes, Slic3r::GUI::printer_config(), Slic3r::resources_dir(), Slic3r::GUI::set_config_values(), Slic3r::ModelConfig::set_key_value(), Slic3r::GUI::DPIAware< P >::ShowModal(), Slic3r::CustomGCode::SingleExtruder, Slic3r::Calib_Params::start, TAB_ID_PREPARE, Slic3r::Calib_Params::test_model, Slic3r::ModelObject::translate_instances(), Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, and Slic3r::ConfigOptionVector< double >::values.

Here is the call graph for this function:

◆ calib_VFA()

void Slic3r::GUI::Plater::calib_VFA ( const Calib_Params & params)
17821{
17822 const auto calib_vfa_name = _L("VFA test");
17823 new_project(false, false, calib_vfa_name);
17824 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
17825 if (params.mode != CalibMode::Calib_VFA_Tower)
17826 return;
17827
17828 if (!add_model(false, Slic3r::resources_dir() + "/calib/vfa/vfa.drc"))
17829 return;
17830 auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
17831 auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
17832 auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
17833
17834 const ConfigOptionFloats* nozzle_diameter_config = printer_config->option<ConfigOptionFloats>("nozzle_diameter");
17835 size_t nozzle_id = static_cast<size_t>(std::max(params.extruder_id, 0));
17837 if (nozzle_diameter_config && !nozzle_diameter_config->values.empty()) {
17838 nozzle_id = std::min(nozzle_id, nozzle_diameter_config->values.size() - 1);
17839 nozzle_diameter = nozzle_diameter_config->values[nozzle_id];
17840 }
17841 if (nozzle_diameter <= 0.0)
17843
17844 // Resolved layer height: use the (possibly auto-adjusted) value from the dialog, else default to nozzle/2.
17845 double layer_height = params.vfa_layer_height > 0.0 ? params.vfa_layer_height : nozzle_diameter / 2.0;
17846
17847 // cut upper (on the unscaled model, using the base block height); the scaling below keeps the physical
17848 // block height (vfa_layers_per_block * layer_height) in sync with the speed stepping in GCode::process_layer.
17849 // Subtract EPSILON (as the temperature tower does) so the cut lands just below the flat block surface instead
17850 // of exactly on it, which would otherwise add a degenerate extra layer.
17851 auto obj_bb = model().objects[0]->bounding_box_exact();
17852 auto height = vfa_base_block_height * ((params.end - params.start) / params.step + 1) - EPSILON;
17853 if (height < obj_bb.size().z()) {
17855 }
17856
17857 // When resizing is enabled, XY scales with the nozzle (footprint / line width) and Z scales so each base
17858 // block becomes vfa_layers_per_block layers of the resolved layer height. When disabled the 0.4 mm / 0.2 mm
17859 // reference model is printed as-is (preset layer height kept).
17860 if (params.nozzle_based_resize) {
17861 const double xy_scale = nozzle_diameter / vfa_base_nozzle_diameter;
17862 const double z_scale = (vfa_layers_per_block * layer_height) / vfa_base_block_height;
17863 if (std::abs(xy_scale - 1.0) > EPSILON || std::abs(z_scale - 1.0) > EPSILON)
17864 model().objects[0]->scale(xy_scale, xy_scale, z_scale);
17865 }
17866
17867 model().objects[0]->ensure_on_bed();
17868
17869 printer_config->set_key_value("resonance_avoidance", new ConfigOptionBool{false});
17870 filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats { 0.0 });
17871 set_config_values<bool, ConfigOptionBoolsNullable>(print_config, "enable_overhang_speed", false);
17872 print_config->set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
17873 print_config->set_key_value("wall_loops", new ConfigOptionInt(1));
17874 print_config->set_key_value("alternate_extra_wall", new ConfigOptionBool(false));
17875 print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0));
17876 print_config->set_key_value("bottom_shell_layers", new ConfigOptionInt(1));
17877 print_config->set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
17878 print_config->set_key_value("detect_thin_wall", new ConfigOptionBool(false));
17879 print_config->set_key_value("spiral_mode", new ConfigOptionBool(true));
17880 print_config->set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
17881 print_config->set_key_value("precise_z_height", new ConfigOptionBool(false));
17882 if (params.nozzle_based_resize) {
17883 print_config->set_key_value("initial_layer_print_height", new ConfigOptionFloat(layer_height));
17884 model().objects[0]->config.set_key_value("layer_height", new ConfigOptionFloat(layer_height));
17885 }
17886 model().objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
17887 model().objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0));
17888 model().objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));
17889
17890 changed_objects({ 0 });
17891 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
17892 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
17893 wxGetApp().get_tab(Preset::TYPE_PRINT)->update_ui_from_settings();
17894 wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_ui_from_settings();
17895
17897 // Pass the resolved layer height on (only meaningful when resized). GCode's VFA stepping is layer-based, so
17898 // it does not require it, but keep it consistent with the geometry.
17899 Calib_Params calib_params = params;
17900 calib_params.vfa_layer_height = params.nozzle_based_resize ? layer_height : 0.0;
17901 p->background_process.fff_print()->set_calib_params(calib_params);
17902}
@ Calib_VFA_Tower
Definition calib.hpp:32
static constexpr double vfa_base_nozzle_diameter
Definition calib.hpp:66
static constexpr int vfa_layers_per_block
Definition calib.hpp:64
static constexpr double vfa_base_block_height
Definition calib.hpp:65

References _calib_apply_belt_mode(), _L, add_model(), Slic3r::btOuterOnly, Slic3r::Calib_VFA_Tower, changed_objects(), Slic3r::ConfigOptionFloat, cut_horizontal(), Slic3r::Calib_Params::end, EPSILON, Slic3r::Calib_Params::extruder_id, Slic3r::KeepLower, Slic3r::GUI::layer_height, Slic3r::Calib_Params::mode, model(), new_project(), Slic3r::Calib_Params::nozzle_based_resize, Slic3r::nozzle_diameter(), Slic3r::Model::objects, p, Slic3r::GUI::printer_config(), Slic3r::resources_dir(), Slic3r::GUI::set_config_values(), Slic3r::Calib_Params::start, Slic3r::Calib_Params::step, TAB_ID_PREPARE, Slic3r::tlTraditional, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, Slic3r::ConfigOptionVector< double >::values, Slic3r::vfa_base_block_height, Slic3r::vfa_base_nozzle_diameter, Slic3r::Calib_Params::vfa_layer_height, and Slic3r::vfa_layers_per_block.

Here is the call graph for this function:

◆ can_add_model()

bool Slic3r::GUI::Plater::can_add_model ( ) const
23881{ return !is_background_process_slicing(); }
bool is_background_process_slicing() const
Definition Plater.cpp:23583

References is_background_process_slicing().

Here is the call graph for this function:

◆ can_add_plate()

bool Slic3r::GUI::Plater::can_add_plate ( ) const
23882{ return !is_background_process_slicing() && p->can_add_plate(); }

References is_background_process_slicing(), and p.

Here is the call graph for this function:

◆ can_arrange()

bool Slic3r::GUI::Plater::can_arrange ( ) const
23892{ return p->can_arrange(); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog().

Here is the caller graph for this function:

◆ can_copy_to_clipboard()

bool Slic3r::GUI::Plater::can_copy_to_clipboard ( ) const
23926{
23927 if (!IsShown() || !p->is_view3D_shown())
23928 return false;
23929
23930 if (is_selection_empty())
23931 return false;
23932
23933 const Selection& selection = p->view3D->get_canvas3d()->get_selection();
23934 if ((wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) && !selection.is_sla_compliant())
23935 return false;
23936
23937 return true;
23938}
bool is_selection_empty() const
Definition Plater.cpp:19423
@ ptSLA
Definition Config.hpp:233

References is_selection_empty(), Slic3r::GUI::Selection::is_sla_compliant(), p, and Slic3r::ptSLA.

Referenced by copy_selection_to_clipboard().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ can_cut_to_clipboard()

bool Slic3r::GUI::Plater::can_cut_to_clipboard ( ) const
23919{
23920 if (is_selection_empty())
23921 return false;
23922 return true;
23923}

References is_selection_empty().

Referenced by cut_selection_to_clipboard().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ can_decrease_instances()

bool Slic3r::GUI::Plater::can_decrease_instances ( ) const
23885{ return p->can_decrease_instances(); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), and decrease_instances().

Here is the caller graph for this function:

◆ can_delete()

bool Slic3r::GUI::Plater::can_delete ( ) const
23879{ return p->can_delete(); }

References p.

◆ can_delete_all()

bool Slic3r::GUI::Plater::can_delete_all ( ) const
23880{ return p->can_delete_all(); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog().

Here is the caller graph for this function:

◆ can_delete_plate()

bool Slic3r::GUI::Plater::can_delete_plate ( ) const
23883{ return p->can_delete_plate(); }

References p.

◆ can_fillcolor()

bool Slic3r::GUI::Plater::can_fillcolor ( ) const
23945{ return p->can_fillcolor(); }

References p.

Referenced by fill_color().

Here is the caller graph for this function:

◆ can_fix_through_cgal()

bool Slic3r::GUI::Plater::can_fix_through_cgal ( ) const
23887{ return p->can_fix_through_cgal(); }

References p.

◆ can_increase_instances()

bool Slic3r::GUI::Plater::can_increase_instances ( ) const
23884{ return p->can_increase_instances(); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), and increase_instances().

Here is the caller graph for this function:

◆ can_layers_editing()

bool Slic3r::GUI::Plater::can_layers_editing ( ) const
23893{ return p->can_layers_editing(); }

References p.

◆ can_mirror()

bool Slic3r::GUI::Plater::can_mirror ( ) const
23949{ return p->can_mirror(); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog().

Here is the caller graph for this function:

◆ can_paste_from_clipboard()

bool Slic3r::GUI::Plater::can_paste_from_clipboard ( ) const
23895{
23896 if (!IsShown() || !p->is_view3D_shown()) return false;
23897
23898 const Selection& selection = p->view3D->get_canvas3d()->get_selection();
23899 const Selection::Clipboard& clipboard = selection.get_clipboard();
23900
23901 if (clipboard.is_empty() && p->sidebar->obj_list()->clipboard_is_empty())
23902 return false;
23903
23904 if ((wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA) && !clipboard.is_sla_compliant())
23905 return false;
23906
23907 Selection::EMode mode = clipboard.get_mode();
23908 if ((mode == Selection::Volume) && !selection.is_from_single_instance())
23909 return false;
23910
23911 if ((mode == Selection::Instance) && (selection.get_mode() != Selection::Instance))
23912 return false;
23913
23914 return true;
23915}
EMode
Definition Selection.hpp:52
@ Instance
Definition Selection.hpp:54
@ Volume
Definition Selection.hpp:53

References Slic3r::GUI::Selection::get_clipboard(), Slic3r::GUI::Selection::Clipboard::get_mode(), Slic3r::GUI::Selection::get_mode(), Slic3r::GUI::Selection::Instance, Slic3r::GUI::Selection::Clipboard::is_empty(), Slic3r::GUI::Selection::is_from_single_instance(), Slic3r::GUI::Selection::Clipboard::is_sla_compliant(), p, Slic3r::ptSLA, and Slic3r::GUI::Selection::Volume.

Referenced by paste_from_clipboard().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ can_redo()

bool Slic3r::GUI::Plater::can_redo ( ) const
23942{ return IsShown() && p->is_view3D_shown() && p->m_worker.is_idle() && p->undo_redo_stack().has_redo_snapshot(); }

References p.

◆ can_reload_from_disk()

bool Slic3r::GUI::Plater::can_reload_from_disk ( ) const
23943{ return p->can_reload_from_disk(); }

References p.

◆ can_replace_all_with_stl()

bool Slic3r::GUI::Plater::can_replace_all_with_stl ( ) const
23948{ return p->can_replace_all_with_stl(); }

References p.

◆ can_replace_with_stl()

bool Slic3r::GUI::Plater::can_replace_with_stl ( ) const
23947{ return p->can_replace_with_stl(); }

References p.

◆ can_set_instance_to_object()

bool Slic3r::GUI::Plater::can_set_instance_to_object ( ) const
23886{ return p->can_set_instance_to_object(); }

References p.

◆ can_simplify()

bool Slic3r::GUI::Plater::can_simplify ( ) const
23888{ return p->can_simplify(); }

References p.

◆ can_smooth_mesh()

bool Slic3r::GUI::Plater::can_smooth_mesh ( ) const
23889{ return p->can_smooth_mesh(); }

References p.

◆ can_split()

bool Slic3r::GUI::Plater::can_split ( bool to_objects) const
23950{ return p->can_split(to_objects); }

References p.

◆ can_split_to_objects()

bool Slic3r::GUI::Plater::can_split_to_objects ( ) const
23890{ return p->can_split_to_objects(); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog().

Here is the caller graph for this function:

◆ can_split_to_volumes()

bool Slic3r::GUI::Plater::can_split_to_volumes ( ) const
23891{ return p->can_split_to_volumes(); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog().

Here is the caller graph for this function:

◆ can_undo()

bool Slic3r::GUI::Plater::can_undo ( ) const
23941{ return IsShown() && p->is_view3D_shown() && p->m_worker.is_idle() && p->undo_redo_stack().has_undo_snapshot(); }

References p.

◆ canvas3D() [1/2]

GLCanvas3D * Slic3r::GUI::Plater::canvas3D ( )
22071{
22072 // BBS modify view3D->get_canvas3d() to current canvas
22073 return p->get_current_canvas3D();
22074}

References p.

Referenced by Slic3r::GUI::add_volume_with_gizmo(), increase_instances(), Slic3r::GUI::init_arrange_params(), and search().

Here is the caller graph for this function:

◆ canvas3D() [2/2]

const GLCanvas3D * Slic3r::GUI::Plater::canvas3D ( ) const
22077{
22078 // BBS modify view3D->get_canvas3d() to current canvas
22079 return p->get_current_canvas3D();
22080}

References p.

◆ center_selection()

void Slic3r::GUI::Plater::center_selection ( )
22333{ p->center_selection(); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog().

Here is the caller graph for this function:

◆ changed_mesh()

void Slic3r::GUI::Plater::changed_mesh ( int obj_idx)
22219{
22220 ModelObject* mo = model().objects[obj_idx];
22222 update();
22223 p->object_list_changed();
22224 p->schedule_background_process();
22225}
void reproject_points_and_holes(ModelObject *object)
Definition ReprojectPointsOnMesh.hpp:30

References model(), Slic3r::Model::objects, p, Slic3r::sla::reproject_points_and_holes(), and update().

Here is the call graph for this function:

◆ changed_object() [1/2]

void Slic3r::GUI::Plater::changed_object ( int obj_idx)
22258{
22259 if (obj_idx < 0)
22260 return;
22261 ModelObject *object = p->model.objects[obj_idx];
22262 if (object == nullptr)
22263 return;
22264 changed_object(*object);
22265}
void changed_object(ModelObject &object)
Definition Plater.cpp:22227

References changed_object(), and p.

Here is the call graph for this function:

◆ changed_object() [2/2]

void Slic3r::GUI::Plater::changed_object ( ModelObject & object)
22227 {
22228 assert(object.get_model() == &p->model); // is object from same model?
22229 object.invalidate_bounding_box();
22230 p->partplate_list.invalidate_exclusion_volume_previews();
22231
22232 // recenter and re - align to Z = 0
22233 object.ensure_on_bed(p->printer_technology != ptSLA);
22234
22235 if (p->printer_technology == ptSLA) {
22236 // Update the SLAPrint from the current Model, so that the reload_scene()
22237 // pulls the correct data, update the 3D scene.
22238 p->update_restart_background_process(true, false);
22239 } else
22240 p->view3D->reload_scene(false);
22241
22242 // update print
22243 p->schedule_background_process();
22244
22245 // Check outside bed
22247
22248 if (!is_loading_project()) {
22249 LifecycleEventContext ctx;
22250 ctx.name = object.name;
22251 ctx.id = std::to_string(object.id().id);
22252 ctx.source = "geometry";
22254 }
22255}
void requires_check_outside_state()
Definition GLCanvas3D.hpp:990
GLCanvas3D * get_current_canvas3D(bool exclude_preview=false)
Definition Plater.cpp:22126
bool is_loading_project() const
Definition Plater.hpp:1074
@ ObjectChanged
Definition LifecycleEvents.hpp:39
void fire_lifecycle_event(LifecycleEvent event, const LifecycleEventContext &ctx)
Definition LifecycleEvents.hpp:234

References Slic3r::fire_lifecycle_event(), get_current_canvas3D(), Slic3r::LifecycleEventContext::id, is_loading_project(), Slic3r::LifecycleEventContext::name, Slic3r::ObjectChanged, p, Slic3r::ptSLA, Slic3r::GUI::GLCanvas3D::requires_check_outside_state(), and Slic3r::LifecycleEventContext::source.

Referenced by changed_object().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ changed_objects()

void Slic3r::GUI::Plater::changed_objects ( const std::vector< size_t > & object_idxs)
22268{
22269 if (object_idxs.empty())
22270 return;
22271
22272 p->partplate_list.invalidate_exclusion_volume_previews();
22273
22274 for (size_t obj_idx : object_idxs) {
22275 if (obj_idx < p->model.objects.size()) {
22276 if (p->model.objects[obj_idx]->min_z() >= SINKING_Z_THRESHOLD)
22277 // re - align to Z = 0
22278 p->model.objects[obj_idx]->ensure_on_bed();
22279 }
22280 }
22281 if (this->p->printer_technology == ptSLA) {
22282 // Update the SLAPrint from the current Model, so that the reload_scene()
22283 // pulls the correct data, update the 3D scene.
22284 this->p->update_restart_background_process(true, false);
22285 }
22286 else {
22287 p->view3D->reload_scene(false);
22288 p->view3D->get_canvas3d()->update_instance_printable_state_for_objects(object_idxs);
22289 }
22290
22291 // update print
22292 this->p->schedule_background_process();
22293
22294 if (!is_loading_project()) {
22295 for (size_t obj_idx : object_idxs) {
22296 if (obj_idx >= p->model.objects.size() || p->model.objects[obj_idx] == nullptr)
22297 continue;
22298
22299 LifecycleEventContext ctx;
22300 ctx.name = p->model.objects[obj_idx]->name;
22301 ctx.id = std::to_string(p->model.objects[obj_idx]->id().id);
22302 ctx.index = static_cast<int>(obj_idx);
22303 ctx.source = "geometry";
22305 }
22306 }
22307}
static const float SINKING_Z_THRESHOLD
Definition Model.hpp:1967

References Slic3r::fire_lifecycle_event(), Slic3r::LifecycleEventContext::id, Slic3r::LifecycleEventContext::index, is_loading_project(), model(), Slic3r::LifecycleEventContext::name, Slic3r::ObjectChanged, p, Slic3r::ptSLA, Slic3r::SINKING_Z_THRESHOLD, and Slic3r::LifecycleEventContext::source.

Referenced by _calib_apply_belt_mode(), _calib_pa_pattern(), _calib_pa_tower(), _calib_temp_belt_sectioned(), Calib_Cornering(), calib_flowrate(), calib_input_shaping_damp(), calib_input_shaping_freq(), calib_max_vol_speed(), calib_retraction(), calib_temp(), and calib_VFA().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_ams_status()

bool Slic3r::GUI::Plater::check_ams_status ( bool is_slice_all)
23736{
23737 if (m_check_status == 0) {
23738 if (!p->check_ams_status_impl(is_slice_all)) {
23739 m_check_status = 0;
23740 return false;
23741 }
23742 else {
23743 m_check_status = 1;
23744 }
23745 }
23746
23747 return true;
23748}
int m_check_status
Definition Plater.hpp:1103

References m_check_status, and p.

Referenced by select_plate().

Here is the caller graph for this function:

◆ check_printer_initialized()

bool Slic3r::GUI::Plater::check_printer_initialized ( MachineObject * obj,
bool only_warning = false,
bool popup_warning = true )
19941{
19942 if (!obj)
19943 return false;
19944
19945 bool has_been_initialized = true;
19946
19947 const auto& extruders = obj->GetExtderSystem()->GetExtruders();
19948 for (const DevExtder& extruder : extruders) {
19949
19950 // Skip check if nozzle type is unknown
19951 if (extruder.GetNozzleType() == NozzleType::ntUndefine) {
19952 continue;
19953 }
19954
19955 if (extruder.GetNozzleFlowType() == NozzleFlowType::NONE_FLOWTYPE) {
19956 has_been_initialized = false;
19957 break;
19958 }
19959 }
19960
19961 if (!has_been_initialized) {
19962 if (popup_warning) {
19963 if (!only_warning) {
19964 if (DevPrinterConfigUtil::get_printer_can_set_nozzle(obj->get_show_printer_type())) {
19965 MessageDialog dlg(wxGetApp().plater(), _L("The nozzle type is not set. Please set the nozzle and try again."), _L("Warning"), wxOK | wxICON_WARNING);
19966 dlg.ShowModal();
19967 } else {
19968 MessageDialog dlg(wxGetApp().plater(), _L("The nozzle type is not set. Please check."), _L("Warning"), wxOK | wxICON_WARNING);
19969 dlg.ShowModal();
19970 }
19971
19972 PrinterPartsDialog print_parts_dlg(nullptr);
19973 print_parts_dlg.update_machine_obj(obj);
19974 print_parts_dlg.ShowModal();
19975 } else {
19976 auto printer_name = get_selected_printer_name_in_combox(); // wxString(obj->get_preset_printer_model_name(machine_print_name))
19977 pop_warning_and_go_to_device_page(printer_name, Plater::PrinterWarningType::NOT_CONNECTED, _L("Sync printer information"));
19978 }
19979 }
19980 return false;
19981 }
19982 return true;
19983}
static bool get_printer_can_set_nozzle(std::string type_str)
Definition DevConfigUtil.h:100
wxString get_selected_printer_name_in_combox()
Definition Plater.cpp:22348
void pop_warning_and_go_to_device_page(wxString printer_name, PrinterWarningType type, const wxString &title)
Definition Plater.cpp:22354
@ NOT_CONNECTED
Definition Plater.hpp:690
static Plater * plater()
Definition GUI_Factories.cpp:400
@ NONE_FLOWTYPE
Definition DevDefs.h:117
@ ntUndefine
Definition CommonDefs.hpp:14

References _L, Slic3r::DevPrinterConfigUtil::get_printer_can_set_nozzle(), get_selected_printer_name_in_combox(), Slic3r::MachineObject::get_show_printer_type(), Slic3r::MachineObject::GetExtderSystem(), Slic3r::DevExtderSystem::GetExtruders(), Slic3r::NONE_FLOWTYPE, NOT_CONNECTED, Slic3r::ntUndefine, Slic3r::GUI::plater(), pop_warning_and_go_to_device_page(), Slic3r::GUI::DPIAware< P >::ShowModal(), and Slic3r::GUI::PrinterPartsDialog::update_machine_obj().

Referenced by is_same_printer_for_connected_and_selected().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clear_before_change_mesh()

void Slic3r::GUI::Plater::clear_before_change_mesh ( int obj_idx)
22193{
22194 ModelObject* mo = model().objects[obj_idx];
22195
22196 // If there are custom supports/seams/mmu/fuzzy skin segmentation, remove them. Fixed mesh
22197 // may be different and they would make no sense.
22198 bool paint_removed = false;
22199 for (ModelVolume* mv : mo->volumes) {
22200 paint_removed |= ! mv->supported_facets.empty() || ! mv->seam_facets.empty() || ! mv->mmu_segmentation_facets.empty() || !mv->fuzzy_skin_facets.empty();
22201 mv->supported_facets.reset();
22202 mv->seam_facets.reset();
22203 mv->mmu_segmentation_facets.reset();
22204 mv->fuzzy_skin_facets.reset();
22205 }
22206 if (paint_removed)
22208}
void notify_painting_removed()
Definition Plater.cpp:22210

References Slic3r::FacetsAnnotation::empty(), Slic3r::ModelVolume::fuzzy_skin_facets, Slic3r::ModelVolume::mmu_segmentation_facets, model(), notify_painting_removed(), Slic3r::Model::objects, Slic3r::FacetsAnnotation::reset(), Slic3r::ModelVolume::seam_facets, Slic3r::ModelVolume::supported_facets, and Slic3r::ModelObject::volumes.

Here is the call graph for this function:

◆ clear_plate_toolbar_image_dirty()

void Slic3r::GUI::Plater::clear_plate_toolbar_image_dirty ( )
449{
451}
bool m_b_plate_toolbar_image_dirty
Definition Plater.hpp:1104

References m_b_plate_toolbar_image_dirty.

◆ clear_undo_redo_stack_main()

void Slic3r::GUI::Plater::clear_undo_redo_stack_main ( )
23956{ p->undo_redo_stack_main().clear(); }

References p.

◆ clone_selection()

void Slic3r::GUI::Plater::clone_selection ( )
22455{
22456 if (is_selection_empty())
22457 return;
22458 CloneDialog dlg(this);
22459 dlg.ShowModal();
22460}

References is_selection_empty(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Here is the call graph for this function:

◆ close_with_confirm()

int Slic3r::GUI::GUI::Plater::close_with_confirm ( std::function< bool(bool yes_or_no)> second_check = nullptr)
19200{
19201 if (up_to_date(false, false)) {
19202 if (second_check && !second_check(false)) return wxID_CANCEL;
19203 model().set_backup_path("");
19204 return wxID_NO;
19205 }
19206
19207 MessageDialog dlg(static_cast<wxWindow*>(this), _L("The current project has unsaved changes. Would you like to save before continuing\?"),
19208 wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Save"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE);
19209 dlg.show_dsa_button(_L("Remember my choice."));
19210 auto choise = wxGetApp().app_config->get("save_project_choise");
19211 auto result = choise.empty() ? dlg.ShowModal() : choise == "yes" ? wxID_YES : wxID_NO;
19212 if (result == wxID_CANCEL)
19213 return result;
19214 else {
19215 if (dlg.get_checkbox_state())
19216 wxGetApp().app_config->set("save_project_choise", result == wxID_YES ? "yes" : "no");
19217 if (result == wxID_YES) {
19218 result = save_project();
19219 if (result == wxID_CANCEL) {
19220 if (choise.empty())
19221 return result;
19222 else
19223 result = wxID_NO;
19224 }
19225 }
19226 }
19227
19228 if (second_check && !second_check(result == wxID_YES)) return wxID_CANCEL;
19229
19230 model().set_backup_path("");
19231 up_to_date(true, false);
19232 up_to_date(true, true);
19233
19234 return result;
19235}
int save_project(bool saveAs=false)
Definition Plater.cpp:16296
bool up_to_date(bool saved, bool backup)
Definition Plater.cpp:16614
void set_backup_path(const std::string &path)
Definition Model.cpp:1174
#define SLIC3R_APP_FULL_NAME
Definition libslic3r.h:11

References _L, Slic3r::GUI::MsgDialog::get_checkbox_state(), model(), save_project(), Slic3r::GUI::MsgDialog::show_dsa_button(), Slic3r::GUI::DPIAware< P >::ShowModal(), SLIC3R_APP_FULL_NAME, and up_to_date().

Referenced by load_gcode(), load_project(), and new_project().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ collapse_sidebar()

void Slic3r::GUI::Plater::collapse_sidebar ( bool collapse)
19151{ p->collapse_sidebar(collapse); }

References p.

◆ combine_mesh_fff()

TriangleMesh Slic3r::GUI::Plater::combine_mesh_fff ( const ModelObject & mo,
int instance_id,
std::function< void(const std::string &)> notify_func = {} )
static
19987{
19988 TriangleMesh mesh;
19989
19990 std::vector<csg::CSGPart> csgmesh;
19991 csgmesh.reserve(2 * mo.volumes.size());
19992 bool has_splitable_volume = csg::model_to_csgmesh(mo, Transform3d::Identity(), std::back_inserter(csgmesh),
19994
19995 std::string fail_msg = _u8L("Unable to perform boolean operation on model meshes. "
19996 "Only positive parts will be kept. You may fix the meshes and try again.");
19997 if (auto fail_reason_name = csg::check_csgmesh_booleans(Range{ std::begin(csgmesh), std::end(csgmesh) }); std::get<0>(fail_reason_name) != csg::BooleanFailReason::OK) {
19998 std::string name = std::get<1>(fail_reason_name);
19999 std::map<csg::BooleanFailReason, std::string> fail_reasons = {
20001 {csg::BooleanFailReason::MeshEmpty, Slic3r::format( _u8L("Reason: part \"%1%\" is empty."), name)},
20002 {csg::BooleanFailReason::NotBoundAVolume, Slic3r::format(_u8L("Reason: part \"%1%\" does not bound a volume."), name)},
20003 {csg::BooleanFailReason::SelfIntersect, Slic3r::format(_u8L("Reason: part \"%1%\" has self intersection."), name)},
20004 {csg::BooleanFailReason::NoIntersection, Slic3r::format(_u8L("Reason: \"%1%\" and another part have no intersection."), name)} };
20005 fail_msg += " " + fail_reasons[std::get<0>(fail_reason_name)];
20006 }
20007 else {
20008 try {
20009 MeshBoolean::mcut::McutMeshPtr meshPtr = csg::perform_csgmesh_booleans_mcut(Range{ std::begin(csgmesh), std::end(csgmesh) });
20011 }
20012 catch (...) {}
20013#if 0
20014 // if mcut fails, try again with CGAL
20015 if (mesh.empty()) {
20016 try {
20017 auto meshPtr = csg::perform_csgmesh_booleans(Range{ std::begin(csgmesh), std::end(csgmesh) });
20019 }
20020 catch (...) {}
20021 }
20022#endif
20023 }
20024
20025 if (mesh.empty()) {
20026 if (notify_func)
20027 notify_func(fail_msg);
20028
20029 for (const ModelVolume* v : mo.volumes)
20030 if (v->is_model_part()) {
20031 TriangleMesh vol_mesh(v->mesh());
20032 vol_mesh.transform(v->get_matrix(), true);
20033 mesh.merge(vol_mesh);
20034 }
20035 }
20036
20037 if (instance_id == -1) {
20038 TriangleMesh vols_mesh(std::move(mesh));
20039 mesh = TriangleMesh();
20040 for (const ModelInstance* i : mo.instances) {
20041 TriangleMesh m = vols_mesh;
20042 m.transform(i->get_matrix(), true);
20043 mesh.merge(m);
20044 }
20045 }
20046 else if (0 <= instance_id && instance_id < int(mo.instances.size()))
20047 mesh.transform(mo.instances[instance_id]->get_matrix(), true);
20048 return mesh;
20049}
TriangleMesh cgal_to_triangle_mesh(const _Mesh &cgalmesh)
Definition MeshBoolean.cpp:262
TriangleMesh mcut_to_triangle_mesh(const McutMesh &mcutmesh)
Definition MeshBoolean.cpp:714
std::unique_ptr< McutMesh, McutMeshDeleter > McutMeshPtr
Definition MeshBoolean.hpp:108
std::tuple< BooleanFailReason, std::string, It > check_csgmesh_booleans(const Range< It > &csgrange, Visitor &&vfn)
Definition PerformCSGMeshBooleans.hpp:266
MeshBoolean::cgal::CGALMeshPtr perform_csgmesh_booleans(const Range< It > &csgparts)
Definition PerformCSGMeshBooleans.hpp:368
void perform_csgmesh_booleans_mcut(MeshBoolean::mcut::McutMeshPtr &mcutm, const Range< It > &csgrange)
Definition PerformCSGMeshBooleans.hpp:215
bool model_to_csgmesh(const ModelObject &mo, const Transform3d &trafo, OutIt out, int parts_to_include=mpartsPositive)
Definition ModelToCSGMesh.hpp:26
@ MeshEmpty
Definition PerformCSGMeshBooleans.hpp:20
@ NotBoundAVolume
Definition PerformCSGMeshBooleans.hpp:20
@ NoIntersection
Definition PerformCSGMeshBooleans.hpp:20
@ SelfIntersect
Definition PerformCSGMeshBooleans.hpp:20
@ OK
Definition PerformCSGMeshBooleans.hpp:20
@ mpartsPositive
Definition ModelToCSGMesh.hpp:19
@ mpartsNegative
Definition ModelToCSGMesh.hpp:20
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:45

References _u8L, Slic3r::MeshBoolean::cgal::cgal_to_triangle_mesh(), Slic3r::csg::check_csgmesh_booleans(), Slic3r::TriangleMesh::empty(), Slic3r::format(), Slic3r::ModelInstance::get_matrix(), Slic3r::ModelVolume::get_matrix(), Slic3r::ModelObject::instances, Slic3r::ModelVolume::is_model_part(), Slic3r::MeshBoolean::mcut::mcut_to_triangle_mesh(), Slic3r::TriangleMesh::merge(), Slic3r::ModelVolume::mesh(), Slic3r::csg::MeshEmpty, Slic3r::csg::model_to_csgmesh(), Slic3r::csg::mpartsNegative, Slic3r::csg::mpartsPositive, Slic3r::csg::NoIntersection, Slic3r::csg::NotBoundAVolume, Slic3r::csg::OK, Slic3r::csg::perform_csgmesh_booleans(), Slic3r::csg::perform_csgmesh_booleans_mcut(), Slic3r::csg::SelfIntersect, Slic3r::TriangleMesh::transform(), and Slic3r::ModelObject::volumes.

Referenced by Slic3r::GUI::ObjectList::boolean(), and export_stl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ config()

◆ config_change_notification()

void Slic3r::GUI::Plater::config_change_notification ( const DynamicPrintConfig & config,
const std::string & key )
21495{
21496 GLCanvas3D* view3d_canvas = get_view3D_canvas3D();
21497 if (key == std::string("print_sequence")) {
21498 auto seq_print = config.option<ConfigOptionEnum<PrintSequence>>("print_sequence");
21499 if (seq_print && view3d_canvas && view3d_canvas->is_initialized() && view3d_canvas->is_rendering_enabled()) {
21500 NotificationManager* notify_manager = get_notification_manager();
21501 if (seq_print->value == PrintSequence::ByObject) {
21502 std::string info_text = _u8L("Print By Object: \nWe suggest using auto-arrange to avoid collisions when printing.");
21503 notify_manager->bbl_show_seqprintinfo_notification(info_text);
21504 }
21505 else
21506 notify_manager->bbl_close_seqprintinfo_notification();
21507 }
21508 }
21509 // notification for more options
21510}
GLCanvas3D * get_view3D_canvas3D()
Definition Plater.cpp:22082
const DynamicPrintConfig * config() const
Definition Plater.cpp:22160
@ ByObject
Definition PrintConfig.hpp:312

References _u8L, Slic3r::GUI::NotificationManager::bbl_close_seqprintinfo_notification(), Slic3r::GUI::NotificationManager::bbl_show_seqprintinfo_notification(), Slic3r::ByObject, config(), get_notification_manager(), get_view3D_canvas3D(), Slic3r::GUI::GLCanvas3D::is_initialized(), and Slic3r::GUI::GLCanvas3D::is_rendering_enabled().

Referenced by on_config_change().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ convert_unit()

void Slic3r::GUI::Plater::convert_unit ( ConversionType conv_type)
19434{
19435 std::vector<int> obj_idxs, volume_idxs;
19436 wxGetApp().obj_list()->get_selection_indexes(obj_idxs, volume_idxs);
19437 if (obj_idxs.empty() && volume_idxs.empty())
19438 return;
19439
19440 TakeSnapshot snapshot(this, conv_type == ConversionType::CONV_FROM_INCH ? "Convert from imperial units" :
19441 conv_type == ConversionType::CONV_TO_INCH ? "Revert conversion from imperial units" :
19442 conv_type == ConversionType::CONV_FROM_METER ? "Convert from meters" : "Revert conversion from meters");
19443 wxBusyCursor wait;
19444
19445 ModelObjectPtrs objects;
19446 std::reverse(obj_idxs.begin(), obj_idxs.end());
19447 for (int obj_idx : obj_idxs) {
19448 ModelObject *object = p->model.objects[obj_idx];
19449 object->convert_units(objects, conv_type, volume_idxs);
19450 remove(obj_idx);
19451 }
19452 std::reverse(objects.begin(), objects.end());
19453 p->load_model_objects(objects);
19454
19455 Selection& selection = p->view3D->get_canvas3d()->get_selection();
19456 size_t last_obj_idx = p->model.objects.size() - 1;
19457
19458 if (volume_idxs.empty()) {
19459 for (size_t i = 0; i < objects.size(); ++i)
19460 selection.add_object((unsigned int)(last_obj_idx - i), i == 0);
19461 }
19462 else {
19463 for (int vol_idx : volume_idxs)
19464 selection.add_volume(last_obj_idx, vol_idx, 0, false);
19465 }
19466}
Definition Plater.hpp:966
void remove(size_t obj_idx)
Definition Plater.cpp:19185
@ CONV_TO_INCH
Definition Model.hpp:745
@ CONV_FROM_METER
Definition Model.hpp:748
@ CONV_FROM_INCH
Definition Model.hpp:746
std::vector< ModelObject * > ModelObjectPtrs
Definition CutUtils.hpp:13

References Slic3r::GUI::Selection::add_object(), Slic3r::GUI::Selection::add_volume(), Slic3r::CONV_FROM_INCH, Slic3r::CONV_FROM_METER, Slic3r::CONV_TO_INCH, p, and remove().

Here is the call graph for this function:

◆ copy_selection_to_clipboard()

void Slic3r::GUI::Plater::copy_selection_to_clipboard ( )
22431{
22432 // At first try to copy selected values to the ObjectList's clipboard
22433 // to check if Settings or Layers are selected in the list
22434 // and then copy to 3DCanvas's clipboard if not
22435 if (can_copy_to_clipboard() && !p->sidebar->obj_list()->copy_to_clipboard())
22436 p->view3D->get_canvas3d()->get_selection().copy_to_clipboard();
22437}
bool can_copy_to_clipboard() const
Definition Plater.cpp:23925

References can_copy_to_clipboard(), and p.

Here is the call graph for this function:

◆ cut()

void Slic3r::GUI::Plater::cut ( size_t obj_idx,
size_t instance_idx,
std::array< Vec3d, 4 > plane_points,
ModelObjectCutAttributes attributes )

Referenced by cut_horizontal().

Here is the caller graph for this function:

◆ cut_horizontal()

void Slic3r::GUI::Plater::cut_horizontal ( size_t obj_idx,
size_t instance_idx,
double z,
ModelObjectCutAttributes attributes )
private
17118{
17119 wxCHECK_RET(obj_idx < p->model.objects.size(), "obj_idx out of bounds");
17120 auto *object = p->model.objects[obj_idx];
17121
17122 wxCHECK_RET(instance_idx < object->instances.size(), "instance_idx out of bounds");
17123
17124 if (! attributes.has(ModelObjectCutAttribute::KeepUpper) && ! attributes.has(ModelObjectCutAttribute::KeepLower))
17125 return;
17126
17127 wxBusyCursor wait;
17128
17129 const Vec3d instance_offset = object->instances[instance_idx]->get_offset();
17130 Cut cut(object, instance_idx, Geometry::translation_transform(z * Vec3d::UnitZ() - instance_offset), attributes);
17131 const auto new_objects = cut.perform_with_plane();
17132
17133 apply_cut_object_to_model(obj_idx, new_objects);
17134}
void apply_cut_object_to_model(size_t init_obj_idx, const ModelObjectPtrs &cut_objects)
Definition Plater.cpp:19468
void cut(size_t obj_idx, size_t instance_idx, std::array< Vec3d, 4 > plane_points, ModelObjectCutAttributes attributes)
@ Cut
Definition Shortcuts.hpp:33
void translation_transform(Transform3d &transform, const Vec3d &translation)
Definition Geometry.cpp:346

References apply_cut_object_to_model(), cut(), Slic3r::enum_bitmask< option_type, typename >::has(), Slic3r::KeepLower, Slic3r::KeepUpper, model(), p, and Slic3r::Geometry::translation_transform().

Referenced by _calib_pa_tower(), _calib_temp_belt_sectioned(), calib_max_vol_speed(), calib_retraction(), calib_temp(), and calib_VFA().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cut_selection_to_clipboard()

void Slic3r::GUI::Plater::cut_selection_to_clipboard ( )
22423{
22424 Plater::TakeSnapshot snapshot(this, "Cut Selected Objects");
22425 if (can_cut_to_clipboard() && !p->sidebar->obj_list()->cut_to_clipboard()) {
22426 p->view3D->get_canvas3d()->get_selection().cut_to_clipboard();
22427 }
22428}
bool can_cut_to_clipboard() const
Definition Plater.cpp:23918

References can_cut_to_clipboard(), and p.

Here is the call graph for this function:

◆ decrease_instances()

void Slic3r::GUI::Plater::decrease_instances ( size_t num = 1)
19331{
19332 if (! can_decrease_instances()) { return; }
19333
19334 Plater::TakeSnapshot snapshot(this, "Decrease Instances");
19335
19336 int obj_idx = p->get_selected_object_idx();
19337
19338 ModelObject* model_object = p->model.objects[obj_idx];
19339 if (model_object->instances.size() > num) {
19340 for (size_t i = 0; i < num; ++ i) {
19341 p->partplate_list.notify_instance_removed(obj_idx, static_cast<int>(model_object->instances.size()) - 1);
19342 model_object->delete_last_instance();
19343 }
19344 p->update();
19345 // Delete object from Sidebar list. Do it after update, so that the GLScene selection is updated with the modified model.
19346 sidebar().obj_list()->decrease_object_instances(obj_idx, num);
19347 }
19348 else {
19349 remove(obj_idx);
19350 }
19351
19352 if (!model_object->instances.empty())
19353 p->get_selection().add_instance(obj_idx, (int)model_object->instances.size() - 1);
19354
19355 p->selection_changed();
19356 this->p->schedule_background_process();
19357 //if (wxGetApp().app_config->get("auto_arrange") == "true") {
19358 // this->set_prepare_state(Job::PREPARE_STATE_MENU);
19359 // this->arrange();
19360 //}
19361}
void decrease_object_instances(const size_t obj_idx, const size_t num)
Definition GUI_ObjectList.cpp:4499
bool can_decrease_instances() const
Definition Plater.cpp:23885

References can_decrease_instances(), Slic3r::GUI::ObjectList::decrease_object_instances(), Slic3r::ModelObject::delete_last_instance(), Slic3r::ModelObject::instances, Slic3r::GUI::Sidebar::obj_list(), p, remove(), and sidebar().

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), and set_number_of_copies().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ default_menu()

wxMenu * Slic3r::GUI::Plater::default_menu ( )
24128{ return p->menus.default_menu(); }

References p.

◆ delete_all_objects_from_model()

void Slic3r::GUI::Plater::delete_all_objects_from_model ( )
19251{
19252 p->delete_all_objects_from_model();
19253}

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog().

Here is the caller graph for this function:

◆ delete_object_from_model()

bool Slic3r::GUI::Plater::delete_object_from_model ( size_t obj_idx,
bool refresh_immediately = true )
19247{ return p->delete_object_from_model(obj_idx, refresh_immediately); }

References p.

◆ delete_plate()

int Slic3r::GUI::Plater::delete_plate ( int plate_index = -1)
23553{
23554 int index = plate_index, ret;
23555
23556 if (plate_index == -1)
23557 index = p->partplate_list.get_curr_plate_index();
23558
23559 take_snapshot("delete partplate");
23560 ret = p->partplate_list.delete_plate(index);
23561
23562 //BBS: update the current print to the current plate
23563 p->partplate_list.update_slice_context_to_current_plate(p->background_process);
23564 p->preview->update_gcode_result(p->partplate_list.get_current_slice_result());
23565 p->sidebar->obj_list()->reload_all_plates();
23566
23567 // BBS update default view
23568 //get_camera().select_view("topfront");
23569 //get_camera().requires_zoom_to_plate = REQUIRES_ZOOM_TO_ALL_PLATE;
23570
23571 //need to call update
23572 update();
23573 return ret;
23574}

References p, take_snapshot(), and update().

Referenced by select_plate_by_hover_id().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ deselect_all()

void Slic3r::GUI::Plater::deselect_all ( )
19182{ p->deselect_all(); }

References p.

◆ download_project()

void Slic3r::GUI::Plater::download_project ( const wxString & project_id)
16595{
16596 return;
16597}

◆ drop_selection()

void Slic3r::GUI::Plater::drop_selection ( )
22334{ p->drop_selection(); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog().

Here is the caller graph for this function:

◆ duplicate_plate()

int Slic3r::GUI::Plater::duplicate_plate ( int plate_index = -1)
23539{
23540 int index = plate_index, ret;
23541 if (plate_index == -1)
23542 index = p->partplate_list.get_curr_plate_index();
23543
23544 ret = p->partplate_list.duplicate_plate(index);
23545
23546 //need to call update
23547 update();
23548 return ret;
23549}

References p, and update().

Here is the call graph for this function:

◆ eject_drive()

void Slic3r::GUI::Plater::eject_drive ( )
21275{
21276 wxBusyCursor wait;
21277 wxGetApp().removable_drive_manager()->set_and_verify_last_save_path(p->last_output_dir_path);
21278 wxGetApp().removable_drive_manager()->eject_drive();
21279}

References p.

◆ enable_inactive_plugins()

void Slic3r::GUI::Plater::enable_inactive_plugins ( const std::vector< std::string > & refs)
23088{
23089 if (refs.empty())
23090 return;
23091 // Local and instant — load the plugin and/or enable the capability. The plugin-load callback
23092 // re-validates the plate and clears (or reclassifies) the notification; no progress dialog needed.
23094}
void resolve_inactive_plugins(const std::vector< std::string > &refs)
Definition PluginResolver.cpp:447

References Slic3r::resolve_inactive_plugins().

Referenced by refresh_missing_plugin_block().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ enable_preview_moves_slider()

void Slic3r::GUI::Plater::enable_preview_moves_slider ( bool enable)

◆ enable_sidebar()

void Slic3r::GUI::Plater::enable_sidebar ( bool enabled)
19149{ p->enable_sidebar(enabled); }

References p.

Referenced by load_gcode(), load_project(), new_project(), and Slic3r::GUI::Plater::priv::set_current_panel().

Here is the caller graph for this function:

◆ enable_wireframe()

void Slic3r::GUI::Plater::enable_wireframe ( bool status)
23982{
23983 p->wireframe_enabled = status;
23984}

References p.

Referenced by Plater().

Here is the caller graph for this function:

◆ enter_gizmos_stack()

void Slic3r::GUI::Plater::enter_gizmos_stack ( )
23957{ p->enter_gizmos_stack(); }

References p.

◆ exit_gizmo()

void Slic3r::GUI::Plater::exit_gizmo ( )
19183{ p->exit_gizmo(); }

References p.

◆ export_3mf()

int Slic3r::GUI::Plater::export_3mf ( const boost::filesystem::path & output_path = boost::filesystem::path(),
SaveStrategy strategy = SaveStrategy::Default,
int export_plate_idx = -1,
Export3mfProgressFn proFn = nullptr )
20410{
20411 int ret = 0;
20412 //if (p->model.objects.empty()) {
20413 // MessageDialog dialog(nullptr, _L("No objects to export."), _L("Save project"), wxYES);
20414 // if (dialog.ShowModal() == wxYES)
20415 // return -1;
20416 //}
20417
20418 if (output_path.empty())
20419 return -1;
20420
20421 bool export_config = true;
20422 wxString path = from_path(output_path);
20423
20424 if (!path.Lower().EndsWith(".3mf"))
20425 return -1;
20426
20427 // take care about private data stored into .3mf
20428 // modify model
20429 publish(p->model, strategy);
20430
20431 DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure();
20432 const std::string path_u8 = into_u8(path);
20433 wxBusyCursor wait;
20434
20435 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << boost::format(": path=%1%, backup=%2%, export_plate_idx=%3%, SaveStrategy=%4%")
20436 %output_path.string()%(strategy & SaveStrategy::Backup)%export_plate_idx %(unsigned int)strategy;
20437
20438 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": path=%1%, backup=%2%, export_plate_idx=%3%, SaveStrategy=%4%")
20439 % std::string("") % (strategy & SaveStrategy::Backup) % export_plate_idx % (unsigned int)strategy;
20440
20441 //BBS: add plate logic for thumbnail generate
20442 std::vector<ThumbnailData*> thumbnails;
20443 std::vector<ThumbnailData*> no_light_thumbnails;
20444 std::vector<ThumbnailData*> calibration_thumbnails;
20445 std::vector<ThumbnailData*> top_thumbnails;
20446 std::vector<ThumbnailData*> picking_thumbnails;
20447 std::vector<PlateBBoxData*> plate_bboxes;
20448 // BBS: backup
20449 if (!(strategy & SaveStrategy::Backup)) {
20450 for (int i = 0; i < p->partplate_list.get_plate_count(); i++) {
20451 ThumbnailData* thumbnail_data = &p->partplate_list.get_plate(i)->thumbnail_data;
20452 if (p->partplate_list.get_plate(i)->thumbnail_data.is_valid() && using_exported_file()) {
20453 //no need to generate thumbnail
20454 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": non need to re-generate thumbnail for gcode/exported mode of plate %1%")%i;
20455 }
20456 else {
20457 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate thumbnail for plate %1%") % i;
20458 const ThumbnailsParams thumbnail_params = { {}, false, true, true, true, i };
20459 p->generate_thumbnail(p->partplate_list.get_plate(i)->thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second,
20460 thumbnail_params, Camera::EType::Ortho);
20461 }
20462 thumbnails.push_back(thumbnail_data);
20463
20464 ThumbnailData *no_light_thumbnail_data = &p->partplate_list.get_plate(i)->no_light_thumbnail_data;
20465 if (p->partplate_list.get_plate(i)->no_light_thumbnail_data.is_valid() && using_exported_file()) {
20466 // no need to generate thumbnail
20467 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": non need to re-generate thumbnail for gcode/exported mode of plate %1%") % i;
20468 } else {
20469 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate thumbnail for plate %1%") % i;
20470 const ThumbnailsParams thumbnail_params = {{}, false, true, true, true, i};
20471 p->generate_thumbnail(p->partplate_list.get_plate(i)->no_light_thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params,
20473 }
20474 no_light_thumbnails.push_back(no_light_thumbnail_data);
20475 //ThumbnailData* calibration_data = &p->partplate_list.get_plate(i)->cali_thumbnail_data;
20476 //calibration_thumbnails.push_back(calibration_data);
20477 PlateBBoxData* plate_bbox_data = &p->partplate_list.get_plate(i)->cali_bboxes_data;
20478 plate_bboxes.push_back(plate_bbox_data);
20479
20480 //generate top and picking thumbnails
20481 ThumbnailData* top_thumbnail = &p->partplate_list.get_plate(i)->top_thumbnail_data;
20482 if (top_thumbnail->is_valid() && using_exported_file()) {
20483 //no need to generate thumbnail
20484 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": non need to re-generate top_thumbnail for gcode/exported mode of plate %1%")%i;
20485 }
20486 else {
20487 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate top_thumbnail for plate %1%") % i;
20488 const ThumbnailsParams thumbnail_params = { {}, false, true, false, true, i };
20489 p->generate_thumbnail(p->partplate_list.get_plate(i)->top_thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params,
20491 }
20492 top_thumbnails.push_back(top_thumbnail);
20493
20494 ThumbnailData* picking_thumbnail = &p->partplate_list.get_plate(i)->pick_thumbnail_data;
20495 if (picking_thumbnail->is_valid() && using_exported_file()) {
20496 //no need to generate thumbnail
20497 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": non need to re-generate pick_thumbnail for gcode/exported mode of plate %1%")%i;
20498 }
20499 else {
20500 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate pick_thumbnail for plate %1%") % i;
20501 const ThumbnailsParams thumbnail_params = { {}, false, true, false, true, i };
20502 p->generate_thumbnail(p->partplate_list.get_plate(i)->pick_thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params,
20504 }
20505 picking_thumbnails.push_back(picking_thumbnail);
20506 }
20507
20508 if (p->partplate_list.get_curr_plate()->is_slice_result_valid()) {
20509 //BBS generate BBS calibration thumbnails
20510 int index = p->partplate_list.get_curr_plate_index();
20511 //ThumbnailData* calibration_data = calibration_thumbnails[index];
20512 //const ThumbnailsParams calibration_params = { {}, false, true, true, true, p->partplate_list.get_curr_plate_index() };
20513 //p->generate_calibration_thumbnail(*calibration_data, PartPlate::cali_thumbnail_width, PartPlate::cali_thumbnail_height, calibration_params);
20514 if (using_exported_file()) {
20515 //do nothing
20516 }
20517 else
20518 *plate_bboxes[index] = p->generate_first_layer_bbox();
20519 }
20520 }
20521
20522 //BBS: add bbs 3mf logic
20523 PlateDataPtrs plate_data_list;
20524 p->partplate_list.store_to_3mf_structure(plate_data_list, (strategy & SaveStrategy::WithGcode || strategy & SaveStrategy::WithSliceInfo), export_plate_idx,
20525 strategy & SaveStrategy::WithStatistics);
20526
20527 // Orca: non-BBL G-code isn't post-processed in place, so run the scripts on a copy before packing it.
20528 std::vector<std::string> pp_tmp_files;
20529 ScopeGuard remove_pp_tmp_files([&pp_tmp_files]() {
20530 for (const std::string& f : pp_tmp_files) {
20531 boost::system::error_code ec;
20532 boost::filesystem::remove(f, ec);
20533 }
20534 });
20535
20536 // Backups (SkipStatic) don't pack G-code, so don't run user scripts for them.
20537 if ((strategy & SaveStrategy::WithGcode) && !(strategy & SaveStrategy::SkipStatic) &&
20538 p->printer_technology == ptFFF && !wxGetApp().preset_bundle->is_bbl_vendor()) {
20539 try {
20540 for (PlateData* pd : plate_data_list) {
20541 if (pd == nullptr || pd->gcode_file.empty())
20542 continue;
20543 PartPlate* plate = p->partplate_list.get_plate(pd->plate_index);
20544 if (plate == nullptr)
20545 continue;
20546 PrintBase* print = nullptr;
20547 plate->get_print(&print, nullptr, nullptr);
20548 Print* fff_print = dynamic_cast<Print*>(print);
20549 if (fff_print == nullptr)
20550 continue;
20551
20552 std::string src_path = pd->gcode_file; // in/out: becomes the post-processed copy if a script ran
20553 std::string output_name = path_u8; // scripts see the real target; a rename is ignored for 3mf
20554 if (run_post_process_scripts(src_path, true, "File", output_name, fff_print->full_print_config())) {
20555 pp_tmp_files.push_back(src_path);
20556 pd->gcode_file = src_path;
20557 }
20558 }
20559 } catch (const std::exception& ex) {
20560 release_PlateData_list(plate_data_list);
20561 show_error(this, ex.what(), false);
20562 return -1;
20563 }
20564 }
20565
20566 // BBS: backup
20567 PresetBundle& preset_bundle = *wxGetApp().preset_bundle;
20568 std::vector<Preset*> project_presets = preset_bundle.get_current_project_embedded_presets();
20569
20570 StoreParams store_params;
20571 store_params.path = path_u8;
20572 store_params.model = &p->model;
20573 store_params.plate_data_list = plate_data_list;
20574 store_params.export_plate_idx = export_plate_idx;
20575 store_params.project_presets = project_presets;
20576 store_params.config = export_config ? &cfg : nullptr;
20577 store_params.thumbnail_data = thumbnails;
20578 store_params.no_light_thumbnail_data = no_light_thumbnails;
20579 store_params.top_thumbnail_data = top_thumbnails;
20580 store_params.pick_thumbnail_data = picking_thumbnails;
20581 store_params.calibration_thumbnail_data = calibration_thumbnails;
20582 store_params.proFn = proFn;
20583 store_params.id_bboxes = plate_bboxes;//BBS
20584 store_params.project = &p->project;
20585 store_params.strategy = strategy | SaveStrategy::Zip64;
20586
20587
20588 // get type and color for platedata
20589 auto* filament_color = dynamic_cast<const ConfigOptionStrings*>(cfg.option("filament_colour"));
20590 auto* nozzle_diameter_option = dynamic_cast<const ConfigOptionFloats*>(cfg.option("nozzle_diameter"));
20591 auto* filament_id_opt = dynamic_cast<const ConfigOptionStrings*>(cfg.option("filament_ids"));
20592 std::string nozzle_diameter_str;
20593 if (nozzle_diameter_option)
20594 nozzle_diameter_str = nozzle_diameter_option->serialize();
20595
20596 std::string printer_model_id = preset_bundle.printers.get_edited_preset().get_printer_type(&preset_bundle);
20597 // The printer reads slice_info.config and knows only its own catalog ids.
20598 auto* id_agent = preset_bundle.is_bbl_vendor() ? wxGetApp().getAgent() : nullptr;
20599
20600 for (int i = 0; i < plate_data_list.size(); i++) {
20601 PlateData *plate_data = plate_data_list[i];
20602 plate_data->printer_model_id = printer_model_id;
20603 plate_data->nozzle_diameters = nozzle_diameter_str;
20604 for (auto it = plate_data->slice_filaments_info.begin(); it != plate_data->slice_filaments_info.end(); it++) {
20605 std::string display_filament_type;
20606 it->type = cfg.get_filament_type(display_filament_type, it->id);
20607 it->filament_id = filament_id_opt ? filament_id_opt->get_at(it->id) : "";
20608 if (id_agent)
20609 it->filament_id = id_agent->from_orca_filament_id(it->filament_id);
20610 it->color = filament_color ? filament_color->get_at(it->id) : "#FFFFFF";
20611 // save filament info used in curr plate
20612 int index = p->partplate_list.get_curr_plate_index();
20613 if (store_params.id_bboxes.size() > index) {
20614 store_params.id_bboxes[index]->filament_ids.push_back(it->id);
20615 store_params.id_bboxes[index]->filament_colors.push_back(it->color);
20616 }
20617 }
20618 }
20619
20620 // handle Design Info
20621 bool has_design_info = false;
20622 ModelDesignInfo designInfo;
20623 if (p->model.design_info != nullptr) {
20624 if (!p->model.design_info->Designer.empty()) {
20625 BOOST_LOG_TRIVIAL(trace) << "design_info, found designer = " << p->model.design_info->Designer;
20626 has_design_info = true;
20627 }
20628 }
20629 if (!has_design_info) {
20630 // add Designed Info
20631 if (p->model.design_info == nullptr) {
20632 // set designInfo before export and reset after export
20633 if (wxGetApp().is_user_login()) {
20634 p->model.design_info = std::make_shared<ModelDesignInfo>();
20635 //p->model.design_info->Designer = wxGetApp().getAgent()->get_user_nickname();
20636 p->model.design_info->Designer = "";
20637 p->model.design_info->DesignerUserId = wxGetApp().getAgent()->get_user_id();
20638 BOOST_LOG_TRIVIAL(trace) << "design_info prepare, designer = "<< "";
20639 BOOST_LOG_TRIVIAL(trace) << "design_info prepare, designer_user_id = " << p->model.design_info->DesignerUserId;
20640 }
20641 }
20642 }
20643
20644 bool store_result = Slic3r::store_bbs_3mf(store_params);
20645 // reset designed info
20646 if (!has_design_info)
20647 p->model.design_info = nullptr;
20648
20649 if (store_result) {
20650 if (!(store_params.strategy & SaveStrategy::Silence)) {
20651 // Success
20652 p->set_project_filename(path);
20653 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << __LINE__ << " call set_project_filename: " << path;
20654 }
20655 }
20656 else {
20657 ret = -1;
20658 }
20659
20660 if (project_presets.size() > 0)
20661 {
20662 for (unsigned int i = 0; i < project_presets.size(); i++)
20663 {
20664 delete project_presets[i];
20665 }
20666 project_presets.clear();
20667 }
20668
20669 release_PlateData_list(plate_data_list);
20670
20671 for (unsigned int i = 0; i < calibration_thumbnails.size(); i++)
20672 {
20673 //release the data here, as it will always be generated when export
20674 calibration_thumbnails[i]->reset();
20675 }
20676 for (unsigned int i = 0; i < no_light_thumbnails.size(); i++) {
20677 // release the data here, as it will always be generated when export
20678 no_light_thumbnails[i]->reset();
20679 }
20680 for (unsigned int i = 0; i < top_thumbnails.size(); i++)
20681 {
20682 //release the data here, as it will always be generated when export
20683 top_thumbnails[i]->reset();
20684 }
20685 top_thumbnails.clear();
20686 for (unsigned int i = 0; i < picking_thumbnails.size(); i++)
20687 {
20688 //release the data here, as it will always be generated when export
20689 picking_thumbnails[i]->reset();;
20690 }
20691 picking_thumbnails.clear();
20692
20693 return ret;
20694}
static const std::pair< unsigned int, unsigned int > THUMBNAIL_SIZE_3MF
Definition Plater.cpp:308
const Print & fff_print() const
Definition Plater.cpp:16049
bool using_exported_file()
Definition Plater.hpp:426
void publish(Model &model, SaveStrategy strategy)
Function to secure private data before store to 3mf.
Definition Plater.cpp:20368
wxString from_path(const boost::filesystem::path &path)
Definition GUI.cpp:555
void show_error(wxWindow *parent, const wxString &message, bool has_code_excerpts)
Definition GUI.cpp:296
std::string into_u8(const wxString &str)
Definition GUI.cpp:549
void trace(unsigned int level, const char *message)
Definition utils.cpp:247
std::vector< PlateData * > PlateDataPtrs
Definition bbs_3mf.hpp:278
void release_PlateData_list(PlateDataPtrs &plate_data_list)
Definition bbs_3mf.cpp:9740
bool run_post_process_scripts(std::string &src_path, bool make_copy, const std::string &host, std::string &output_name, const DynamicPrintConfig &config)
Definition PostProcessor.cpp:346
bool store_bbs_3mf(StoreParams &store_params)
Definition bbs_3mf.cpp:9723
@ ptFFF
Definition Config.hpp:231
@ WithGcode
Definition bbs_3mf.hpp:169
@ WithStatistics
Definition bbs_3mf.hpp:181
@ Backup
Definition bbs_3mf.hpp:185
@ SkipStatic
Definition bbs_3mf.hpp:171
@ Silence
Definition bbs_3mf.hpp:170
@ WithSliceInfo
Definition bbs_3mf.hpp:173
@ Zip64
Definition bbs_3mf.hpp:166
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124
@ Ortho
Definition Camera.hpp:39
@ Iso
Definition Camera.hpp:44
@ Top_Plate
Definition Camera.hpp:53

References Slic3r::Backup, Slic3r::StoreParams::calibration_thumbnail_data, Slic3r::StoreParams::config, Slic3r::StoreParams::export_plate_idx, Slic3r::f(), fff_print(), Slic3r::GUI::from_path(), Slic3r::PresetBundle::get_current_project_embedded_presets(), Slic3r::PresetCollection::get_edited_preset(), Slic3r::DynamicPrintConfig::get_filament_type(), Slic3r::GUI::PartPlate::get_print(), Slic3r::Preset::get_printer_type(), Slic3r::StoreParams::id_bboxes, Slic3r::GUI::into_u8(), Slic3r::PresetBundle::is_bbl_vendor(), Slic3r::ThumbnailData::is_valid(), Slic3r::GUI::Camera::Iso, Slic3r::StoreParams::model, Slic3r::StoreParams::no_light_thumbnail_data, Slic3r::PlateData::nozzle_diameters, Slic3r::ConfigBase::option(), Slic3r::GUI::Camera::Ortho, p, Slic3r::StoreParams::path, Slic3r::StoreParams::pick_thumbnail_data, Slic3r::StoreParams::plate_data_list, Slic3r::PlateData::printer_model_id, Slic3r::PresetBundle::printers, Slic3r::StoreParams::proFn, Slic3r::StoreParams::project, Slic3r::StoreParams::project_presets, Slic3r::ptFFF, Slic3r::release_PlateData_list(), Slic3r::run_post_process_scripts(), Slic3r::GUI::show_error(), Slic3r::Silence, Slic3r::SkipStatic, Slic3r::PlateData::slice_filaments_info, Slic3r::store_bbs_3mf(), Slic3r::StoreParams::strategy, Slic3r::StoreParams::thumbnail_data, THUMBNAIL_SIZE_3MF, Slic3r::GUI::Camera::Top_Plate, Slic3r::StoreParams::top_thumbnail_data, Slic3r::trace(), using_exported_file(), Slic3r::WithGcode, Slic3r::WithSliceInfo, Slic3r::WithStatistics, and Slic3r::Zip64.

Referenced by export_3mf_copy(), export_config_3mf(), export_core_3mf(), export_gcode_3mf(), export_published_3mf(), save_project(), and send_gcode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ export_3mf_copy()

bool Slic3r::GUI::Plater::export_3mf_copy ( const boost::filesystem::path & output_path)
19730{
19731 Model& model = p->model;
19732 SvgArchivePathsRestorer svg_paths(model);
19733
19734 // With no design info, export_3mf() writes the signed-in account's user id as the designer; an
19735 // empty one keeps it out. export_3mf() also drops design info without a designer name afterwards.
19736 const std::shared_ptr<ModelDesignInfo> design_info = model.design_info;
19737 if (design_info == nullptr)
19738 model.design_info = std::make_shared<ModelDesignInfo>();
19739 ScopeGuard restore_design_info([&model, design_info]() { model.design_info = design_info; });
19740
19741 // The project save's layout, plus Silence so the project file name stays as it is. Unlike a save
19742 // it never adds FullPathSources: a copy is for sharing, and those are paths on this machine.
19744}
int export_3mf(const boost::filesystem::path &output_path=boost::filesystem::path(), SaveStrategy strategy=SaveStrategy::Default, int export_plate_idx=-1, Export3mfProgressFn proFn=nullptr)
Definition Plater.cpp:20409
@ ShareMesh
Definition bbs_3mf.hpp:176
@ SplitModel
Definition bbs_3mf.hpp:183

References export_3mf(), model(), p, Slic3r::ShareMesh, Slic3r::Silence, and Slic3r::SplitModel.

Referenced by Slic3r::anonymous_namespace{PluginHostApp.cpp}::export_3mf_copy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ export_config_3mf()

int Slic3r::GUI::Plater::export_config_3mf ( int plate_idx = -1,
Export3mfProgressFn proFn = nullptr )
21191{
21192 int result = 0;
21193 /* generate 3mf */
21194 set_print_job_plate_idx(plate_idx);
21195
21196 PartPlate* plate = get_partplate_list().get_curr_plate();
21197 try {
21198 p->m_print_job_data._3mf_config_path = fs::path(plate->get_temp_config_3mf_path());
21199 }
21200 catch (std::exception&) {
21201 BOOST_LOG_TRIVIAL(error) << "generate 3mf path failed";
21202 return -1;
21203 }
21204
21206 result = export_3mf(p->m_print_job_data._3mf_config_path, strategy, plate_idx, proFn);
21207
21208 return result;
21209}
void set_print_job_plate_idx(int plate_idx)
Definition Plater.cpp:14567
SaveStrategy
Definition bbs_3mf.hpp:163
@ SkipAuxiliary
Definition bbs_3mf.hpp:174
@ SkipModel
Definition bbs_3mf.hpp:172

References export_3mf(), Slic3r::GUI::PartPlateList::get_curr_plate(), get_partplate_list(), Slic3r::GUI::PartPlate::get_temp_config_3mf_path(), p, set_print_job_plate_idx(), Slic3r::Silence, Slic3r::SkipAuxiliary, Slic3r::SkipModel, and Slic3r::WithSliceInfo.

Here is the call graph for this function:

◆ export_core_3mf()

void Slic3r::GUI::Plater::export_core_3mf ( )
19722{
19723 wxString path = p->get_export_file(FT_3MF);
19724 if (path.empty()) { return; }
19725 const std::string path_u8 = into_u8(path);
19727}
@ FT_3MF
Definition GUI_App.hpp:124

References export_3mf(), Slic3r::GUI::FT_3MF, Slic3r::GUI::into_u8(), p, and Slic3r::Silence.

Here is the call graph for this function:

◆ export_gcode()

void Slic3r::GUI::Plater::export_gcode ( bool prefer_removable)
19494{
19495 if (p->model.objects.empty())
19496 return;
19497
19498 //if (get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode(true))
19499 // return;
19500
19501 if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index())
19502 return;
19503
19504 // If possible, remove accents from accented latin characters.
19505 // This function is useful for generating file names to be processed by legacy firmwares.
19506 fs::path default_output_file;
19507 try {
19508 // Update the background processing, so that the placeholder parser will get the correct values for the ouput file template.
19509 // Also if there is something wrong with the current configuration, a pop-up dialog will be shown and the export will not be performed.
19510 unsigned int state = this->p->update_restart_background_process(false, false);
19512 return;
19513 default_output_file = this->p->background_process.output_filepath_for_project(
19514 into_path(this->p->get_project_filename(".3mf")));
19515 } catch (const Slic3r::PlaceholderParserError &ex) {
19516 // Show the error with monospaced font.
19517 show_error(this, ex.what(), true);
19518 return;
19519 } catch (const std::exception &ex) {
19520 show_error(this, ex.what(), false);
19521 return;
19522 }
19523 default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string()));
19524 AppConfig &appconfig = *wxGetApp().app_config;
19525 RemovableDriveManager &removable_drive_manager = *wxGetApp().removable_drive_manager();
19526 // Get a last save path, either to removable media or to an internal media.
19527 std::string start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), prefer_removable);
19528 if (prefer_removable) {
19529 // Returns a path to a removable media if it exists, prefering start_dir. Update the internal removable drives database.
19530 start_dir = removable_drive_manager.get_removable_drive_path(start_dir);
19531 if (start_dir.empty())
19532 // Direct user to the last internal media.
19533 start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), false);
19534 }
19535
19536 fs::path output_path;
19537 {
19538 std::string ext = default_output_file.extension().string();
19539 wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _L("Save G-code file as:") : _L("Save SLA file as:"),
19540 start_dir,
19541 from_path(default_output_file.filename()),
19543 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
19544 );
19545 if (dlg.ShowModal() == wxID_OK) {
19546 output_path = into_path(dlg.GetPath());
19547 while (has_illegal_filename_characters(output_path.filename().string())) {
19548 show_error(this, _L("The provided file name is not valid.") + "\n" +
19549 _L("The following characters are not allowed by a FAT file system:") + " <>:/\\|?*\"");
19550 dlg.SetFilename(from_path(output_path.filename()));
19551 if (dlg.ShowModal() == wxID_OK)
19552 output_path = into_path(dlg.GetPath());
19553 else {
19554 output_path.clear();
19555 break;
19556 }
19557 }
19558 }
19559 }
19560
19561 if (! output_path.empty()) {
19562 bool path_on_removable_media = removable_drive_manager.set_and_verify_last_save_path(output_path.string());
19563 //bool path_on_removable_media = false;
19564 p->notification_manager->new_export_began(path_on_removable_media);
19565 p->exporting_status = path_on_removable_media ? ExportingStatus::EXPORTING_TO_REMOVABLE : ExportingStatus::EXPORTING_TO_LOCAL;
19566 p->last_output_path = output_path.string();
19567 p->last_output_dir_path = output_path.parent_path().string();
19568 p->export_gcode(output_path, path_on_removable_media);
19569 // Storing a path to AppConfig either as path to removable media or a path to internal media.
19570 // is_path_on_removable_drive() is called with the "true" parameter to update its internal database as the user may have shuffled the external drives
19571 // while the dialog was open.
19572 appconfig.update_last_output_dir(output_path.parent_path().string(), path_on_removable_media);
19573
19574 try {
19575 json j;
19576 auto printer_config = Slic3r::GUI::wxGetApp().preset_bundle->printers.get_edited_preset_with_vendor_profile().preset;
19577 if (printer_config.is_system) {
19578 j["printer_preset"] = printer_config.name;
19579 } else {
19580 j["printer_preset"] = printer_config.config.opt_string("inherits");
19581 }
19582
19583 PresetBundle *preset_bundle = wxGetApp().preset_bundle;
19584 if (preset_bundle) {
19585 j["gcode_printer_model"] = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
19586 }
19587 NetworkAgent *agent = wxGetApp().getAgent();
19588 } catch (...) {}
19589
19590 }
19591}
std::string & opt_string(const t_config_option_key &opt_key, bool create=false)
Definition Config.hpp:3042
static bool has_illegal_filename_characters(const wxString &name)
Definition Plater.cpp:416
PrinterTechnology printer_technology() const
Definition Plater.cpp:22155
@ FT_SL1
Definition GUI_App.hpp:137
@ FT_GCODE
Definition GUI_App.hpp:126
wxString file_wildcards(FileType file_type, const std::string &custom_extension)
Definition GUI_App.cpp:695
@ EXPORTING_TO_REMOVABLE
Definition Plater.cpp:7166
@ EXPORTING_TO_LOCAL
Definition Plater.cpp:7167
nlohmann::json json
Definition AssembleList.cpp:42
std::string fold_utf8_to_ascii(const std::string &src, bool is_convert_for_filename)
Definition ASCIIFolding.cpp:1949
@ UPDATE_BACKGROUND_PROCESS_INVALID
Definition Plater.cpp:7565

References _L, Slic3r::GUI::EXPORTING_TO_LOCAL, Slic3r::GUI::EXPORTING_TO_REMOVABLE, Slic3r::GUI::file_wildcards(), Slic3r::fold_utf8_to_ascii(), Slic3r::GUI::from_path(), Slic3r::GUI::FT_GCODE, Slic3r::GUI::FT_SL1, Slic3r::PresetCollection::get_edited_preset(), Slic3r::AppConfig::get_last_output_dir(), Slic3r::Preset::get_printer_type(), Slic3r::GUI::RemovableDriveManager::get_removable_drive_path(), has_illegal_filename_characters(), Slic3r::GUI::into_path(), p, Slic3r::GUI::printer_config(), printer_technology(), Slic3r::PresetBundle::printers, Slic3r::ptFFF, Slic3r::GUI::RemovableDriveManager::set_and_verify_last_save_path(), Slic3r::GUI::show_error(), Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_INVALID, and Slic3r::AppConfig::update_last_output_dir().

Here is the call graph for this function:

◆ export_gcode_3mf()

void Slic3r::GUI::Plater::export_gcode_3mf ( bool export_all = false)
19600{
19601 if (p->model.objects.empty())
19602 return;
19603
19604 if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index())
19605 return;
19606
19607 //calc default_output_file, get default output file from background process
19608 fs::path default_output_file;
19609 AppConfig& appconfig = *wxGetApp().app_config;
19610 std::string start_dir;
19611 try {
19612 // Update the background processing, so that the placeholder parser will get the correct values for the ouput file template.
19613 // Also if there is something wrong with the current configuration, a pop-up dialog will be shown and the export will not be performed.
19614 unsigned int state = this->p->update_restart_background_process(false, false);
19616 return;
19617 default_output_file = this->p->background_process.output_filepath_for_project(
19618 into_path(this->p->get_project_filename(".3mf")));
19619 }
19620 catch (const Slic3r::PlaceholderParserError& ex) {
19621 // Show the error with monospaced font.
19622 show_error(this, ex.what(), true);
19623 return;
19624 }
19625 catch (const std::exception& ex) {
19626 show_error(this, ex.what(), false);
19627 return;
19628 }
19629 default_output_file.replace_extension(".gcode.3mf");
19630 default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string()));
19631
19632 //Get a last save path
19633 start_dir = appconfig.get_last_output_dir(default_output_file.parent_path().string(), false);
19634
19635 fs::path output_path;
19636 {
19637 std::string ext = default_output_file.extension().string();
19638 wxFileDialog dlg(this, _L("Save Sliced file as:"),
19639 start_dir,
19640 from_path(default_output_file.filename()),
19642 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
19643 );
19644 if (dlg.ShowModal() == wxID_OK) {
19645 output_path = into_path(dlg.GetPath());
19646 ext = output_path.extension().string();
19647 if (ext != ".3mf")
19648 output_path = output_path.string() + ".3mf";
19649 }
19650 }
19651
19652 if (!output_path.empty()) {
19653 //BBS do not set to removable media path
19654 bool path_on_removable_media = false;
19655 p->notification_manager->new_export_began(path_on_removable_media);
19656 p->exporting_status = path_on_removable_media ? ExportingStatus::EXPORTING_TO_REMOVABLE : ExportingStatus::EXPORTING_TO_LOCAL;
19657 //BBS do not save last output path
19658 p->last_output_path = output_path.string();
19659 p->last_output_dir_path = output_path.parent_path().string();
19660 int plate_idx = get_partplate_list().get_curr_plate_index();
19661 if (export_all)
19662 plate_idx = PLATE_ALL_IDX;
19664 if (wxGetApp().app_config->get_bool("export_statistics"))
19665 strategy = strategy | SaveStrategy::WithStatistics;
19666 if (export_3mf(output_path, strategy, plate_idx) < 0) {
19667 // No file was written (e.g. a post-processing script failed), don't report a successful export.
19668 p->exporting_status = ExportingStatus::NOT_EXPORTING;
19669 return;
19670 }
19671
19672 RemovableDriveManager& removable_drive_manager = *wxGetApp().removable_drive_manager();
19673
19674
19675 bool on_removable = removable_drive_manager.is_path_on_removable_drive(p->last_output_dir_path);
19676
19677
19678 // update last output dir
19679 appconfig.update_last_output_dir(output_path.parent_path().string(), false);
19680 p->notification_manager->push_exporting_finished_notification(output_path.string(), p->last_output_dir_path, on_removable);
19681 }
19682}
#define PLATE_ALL_IDX
Definition PartPlate.hpp:57
@ FT_GCODE_3MF
Definition GUI_App.hpp:125
@ NOT_EXPORTING
Definition Plater.cpp:7165

References _L, export_3mf(), Slic3r::GUI::EXPORTING_TO_LOCAL, Slic3r::GUI::EXPORTING_TO_REMOVABLE, Slic3r::GUI::file_wildcards(), Slic3r::fold_utf8_to_ascii(), Slic3r::GUI::from_path(), Slic3r::GUI::FT_GCODE_3MF, Slic3r::GUI::PartPlateList::get_curr_plate_index(), Slic3r::AppConfig::get_last_output_dir(), get_partplate_list(), Slic3r::GUI::into_path(), Slic3r::GUI::RemovableDriveManager::is_path_on_removable_drive(), Slic3r::GUI::NOT_EXPORTING, p, PLATE_ALL_IDX, Slic3r::GUI::show_error(), Slic3r::Silence, Slic3r::SkipModel, Slic3r::SplitModel, Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_INVALID, Slic3r::AppConfig::update_last_output_dir(), Slic3r::WithGcode, and Slic3r::WithStatistics.

Here is the call graph for this function:

◆ export_published_3mf()

int Slic3r::GUI::Plater::export_published_3mf ( const std::vector< std::string > & published_keys,
const std::vector< Slic3r::PublishedMaterialEntry > & material_keys )
19751{
19752 wxString path = p->get_export_file(FT_3MF, _L("Publish 3MF file as:"), true);
19753 if (path.empty() || path == "<cancel>")
19754 return wxID_CANCEL;
19755
19756 nlohmann::json j = nlohmann::json::array();
19757 for (const std::string& key : published_keys)
19758 j.push_back(key);
19759 nlohmann::json jm = nlohmann::json::array();
19760 for (const Slic3r::PublishedMaterialEntry& e : material_keys)
19761 jm.push_back({{"material",
19762 {{"filament_type", e.filament_type},
19763 {"filament_vendor", e.filament_vendor},
19764 {"filament_id", e.filament_id},
19765 {"setting_id", e.setting_id},
19766 {"name", e.preset_name}}},
19767 {"slot", e.slot},
19768 {"keys", e.keys},
19769 {"full", e.full},
19770 {"full_keys", e.full_keys},
19771 {"publish_type", e.publish_type},
19772 {"type", e.publish_type_value},
19773 {"publish_color", e.publish_color},
19774 {"color", e.color}});
19775
19776 Model& model = this->model();
19777 // Save the previous metadata so it can be restored after the export, keeping the in-memory
19778 // project pristine (the published flag lives only in the exported file).
19779 const bool had_model_info = (model.model_info != nullptr);
19780 const bool had_published = had_model_info &&
19781 (model.model_info->metadata_items.find(ORCA_PUBLISHED_TAG) != model.model_info->metadata_items.end());
19782 const bool had_published_keys = had_model_info && (model.model_info->metadata_items.find(ORCA_PUBLISHED_KEYS_TAG) !=
19783 model.model_info->metadata_items.end());
19784 const bool had_material_keys = had_model_info && (model.model_info->metadata_items.find(ORCA_PUBLISHED_MATERIAL_TAG) !=
19785 model.model_info->metadata_items.end());
19786 const bool had_payload = had_model_info &&
19787 (model.model_info->metadata_items.find(ORCA_PUBLISHED_CONFIG_TAG) != model.model_info->metadata_items.end());
19788 const std::string prev_published = had_published ? model.model_info->metadata_items.at(ORCA_PUBLISHED_TAG) : std::string();
19789 const std::string prev_published_keys = had_published_keys ? model.model_info->metadata_items.at(ORCA_PUBLISHED_KEYS_TAG) :
19790 std::string();
19791 const std::string prev_material_keys = had_material_keys ? model.model_info->metadata_items.at(ORCA_PUBLISHED_MATERIAL_TAG) :
19792 std::string();
19793 const std::string prev_payload = had_payload ? model.model_info->metadata_items.at(ORCA_PUBLISHED_CONFIG_TAG) : std::string();
19794
19795 SvgArchivePathsRestorer svg_paths(model);
19796
19797 auto restore_temporary_state = [&]() {
19798 svg_paths.restore();
19799
19800 if (!had_model_info) {
19801 model.model_info = nullptr;
19802 } else {
19803 if (had_published)
19804 model.model_info->metadata_items[ORCA_PUBLISHED_TAG] = prev_published;
19805 else
19806 model.model_info->metadata_items.erase(ORCA_PUBLISHED_TAG);
19807 if (had_published_keys)
19808 model.model_info->metadata_items[ORCA_PUBLISHED_KEYS_TAG] = prev_published_keys;
19809 else
19810 model.model_info->metadata_items.erase(ORCA_PUBLISHED_KEYS_TAG);
19811 if (had_material_keys)
19812 model.model_info->metadata_items[ORCA_PUBLISHED_MATERIAL_TAG] = prev_material_keys;
19813 else
19814 model.model_info->metadata_items.erase(ORCA_PUBLISHED_MATERIAL_TAG);
19815 if (had_payload)
19816 model.model_info->metadata_items[ORCA_PUBLISHED_CONFIG_TAG] = prev_payload;
19817 else
19818 model.model_info->metadata_items.erase(ORCA_PUBLISHED_CONFIG_TAG);
19819 }
19820 };
19821 bool state_restored = false;
19822 auto restore_now = [&]() {
19823 if (state_restored)
19824 return;
19825 restore_temporary_state();
19826 state_restored = true;
19827 };
19828 ScopeGuard restore_guard(restore_now);
19829
19830 if (model.model_info == nullptr)
19831 model.model_info = std::make_shared<ModelInfo>();
19832 model.model_info->metadata_items[ORCA_PUBLISHED_TAG] = "1";
19833 model.model_info->metadata_items[ORCA_PUBLISHED_KEYS_TAG] = j.dump();
19834 model.model_info->metadata_items[ORCA_PUBLISHED_MATERIAL_TAG] = jm.dump();
19835
19836 int ret = -1;
19837 try {
19838 // Minimal published export: filter full_config to the published keys, material keys,
19839 // identity fields and plate geometry keys, and omit the project config file, the
19840 // project-embedded preset dumps and the OrcaSlicer version tag from the archive. The
19841 // filtered values are serialized into the published_config metadata payload instead, so
19842 // OrcaSlicer versions without the publish feature fall back to importing the geometry only
19843 // (keeping the receiver's presets) while new versions rebuild the config from the payload.
19844 DynamicPrintConfig full_cfg = wxGetApp().preset_bundle->full_config_secure();
19845 DynamicPrintConfig filtered_cfg = filter_published_config(full_cfg, published_keys, material_keys);
19846 std::string payload;
19847 for (const std::string& key : filtered_cfg.keys()) {
19848 // A value containing a newline would break the INI written below (read_ini throws),
19849 // so load_from_ini_string discards the whole settings block on import. Skip such
19850 // keys instead of silently dropping every setting.
19851 std::string value = filtered_cfg.opt_serialize(key);
19852 if (value.find('\n') != std::string::npos) {
19853 BOOST_LOG_TRIVIAL(warning) << "publish: dropping key \"" << key
19854 << "\" from the published payload (value contains a newline)";
19855 continue;
19856 }
19857 payload += key + " = " + value + "\n";
19858 }
19859 model.model_info->metadata_items[ORCA_PUBLISHED_CONFIG_TAG] = std::move(payload);
19860
19861 // Same file layout as save_project(), plus Silence (so export_3mf does not set the project
19862 // filename on success, keeping this a pure export like export_core_3mf()) and MinimalPublished.
19864 bool full_pathnames = wxGetApp().app_config->get_bool("export_sources_full_pathnames");
19865 if (full_pathnames)
19866 save_strategy = save_strategy | SaveStrategy::FullPathSources;
19867 ret = export_3mf(into_path(path), save_strategy, -1, nullptr);
19868 } catch (...) {
19869 restore_now();
19870 MessageDialog(this,
19871 _L("Failed to export the published 3MF file.\nPlease check whether the folder exists online or if other programs "
19872 "have the file open."),
19873 _L("Publish"), wxOK | wxICON_WARNING)
19874 .ShowModal();
19875 return wxID_CANCEL;
19876 }
19877
19878 if (ret < 0) {
19879 restore_now();
19880 MessageDialog(this,
19881 _L("Failed to export the published 3MF file.\nPlease check whether the folder exists online or if other programs "
19882 "have the file open."),
19883 _L("Publish"), wxOK | wxICON_WARNING)
19884 .ShowModal();
19885 return wxID_CANCEL;
19886 }
19887 restore_now();
19888
19889 // Register the exported file in the "Recently opened" list
19890 wxGetApp().mainframe->add_to_recent_projects(path);
19891
19892 return wxID_YES;
19893}
DynamicPrintConfig filter_published_config(const DynamicPrintConfig &full_config, const std::vector< std::string > &published_keys, const std::vector< PublishedMaterialEntry > &material_keys)
Definition PublishSettings.cpp:194
constexpr const char * ORCA_PUBLISHED_CONFIG_TAG
Definition bbs_3mf.hpp:195
@ MinimalPublished
Definition bbs_3mf.hpp:179
@ FullPathSources
Definition bbs_3mf.hpp:165
constexpr const char * ORCA_PUBLISHED_TAG
Definition bbs_3mf.hpp:192
constexpr const char * ORCA_PUBLISHED_KEYS_TAG
Definition bbs_3mf.hpp:193
constexpr const char * ORCA_PUBLISHED_MATERIAL_TAG
Definition bbs_3mf.hpp:194

References _L, export_3mf(), Slic3r::filter_published_config(), Slic3r::GUI::FT_3MF, Slic3r::FullPathSources, Slic3r::GUI::into_path(), Slic3r::DynamicConfig::keys(), Slic3r::MinimalPublished, model(), Slic3r::ConfigBase::opt_serialize(), Slic3r::ORCA_PUBLISHED_CONFIG_TAG, Slic3r::ORCA_PUBLISHED_KEYS_TAG, Slic3r::ORCA_PUBLISHED_MATERIAL_TAG, Slic3r::ORCA_PUBLISHED_TAG, p, Slic3r::ShareMesh, Slic3r::GUI::DPIAware< P >::ShowModal(), Slic3r::Silence, and Slic3r::SplitModel.

Here is the call graph for this function:

◆ export_stl()

void Slic3r::GUI::Plater::export_stl ( bool extended = false,
bool selection_only = false,
bool multi_stls = false,
FileType file_type = FT_STL )
20054{
20055 if (p->model.objects.empty()) { return; }
20056
20057 int quality = 0;
20058
20059 switch (file_type) {
20060 case FT_DRC:
20061 AppConfig* app_config = wxGetApp().app_config;
20062 if (app_config)
20063 quality = stoi(app_config->get("drc_bits"));
20064 else
20065 quality = DRC_BITS_DEFAULT;
20066 break;
20067 }
20068
20069 wxString path;
20070 if (multi_stls) {
20071 wxDirDialog dlg(this, _L("Choose a directory"), from_u8(wxGetApp().app_config->get_last_dir()),
20072 wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
20073 if (dlg.ShowModal() == wxID_OK) {
20074 path = dlg.GetPath() + "/";
20075 }
20076 } else {
20077 path = p->get_export_file(file_type);
20078 }
20079 if (path.empty()) { return; }
20080 const std::string path_u8 = into_u8(path);
20081
20082 wxBusyCursor wait;
20083 const auto& selection = p->get_selection();
20084 const auto obj_idx = selection.get_object_idx();
20085
20086#if EXPORT_WITH_BOOLEAN
20087 if (selection_only && (obj_idx == -1 || selection.is_wipe_tower()))
20088 return;
20089#else
20090 // BBS support selecting multiple objects
20091 if (selection_only && selection.is_wipe_tower()) return;
20092
20093 // BBS
20094 if (selection_only) {
20095 // only support selection single full object and mulitiple full object
20096 if (!selection.is_single_full_object() && !selection.is_multiple_full_object()) return;
20097 }
20098
20099 // Following lambda generates a combined mesh for export with normals pointing outwards.
20100 auto mesh_to_export_fff_no_boolean = [this](const ModelObject &mo, int instance_id) {
20101 TriangleMesh mesh;
20102
20103 //Prusa export negative parts
20104 std::vector<csg::CSGPart> csgmesh;
20105 csgmesh.reserve(2 * mo.volumes.size());
20106 csg::model_to_csgmesh(mo, Transform3d::Identity(), std::back_inserter(csgmesh),
20108
20109 auto csgrange = range(csgmesh);
20110 if (csg::is_all_positive(csgrange)) {
20111 mesh = TriangleMesh{csg::csgmesh_merge_positive_parts(csgrange)};
20112 } else if (std::get<2>(csg::check_csgmesh_booleans(csgrange)) == csgrange.end()) {
20113 try {
20114 auto cgalm = csg::perform_csgmesh_booleans(csgrange);
20116 } catch (...) {}
20117 }
20118
20119 if (mesh.empty()) {
20121 _u8L("Unable to perform boolean operation on model meshes. "
20122 "Only positive parts will be exported."));
20123
20124 for (const ModelVolume* v : mo.volumes)
20125 if (v->is_model_part()) {
20126 TriangleMesh vol_mesh(v->mesh());
20127 vol_mesh.transform(v->get_matrix(), true);
20128 mesh.merge(vol_mesh);
20129 }
20130 }
20131 if (instance_id == -1) {
20132 TriangleMesh vols_mesh(mesh);
20133 mesh = TriangleMesh();
20134 for (const ModelInstance *i : mo.instances) {
20135 TriangleMesh m = vols_mesh;
20136 m.transform(i->get_matrix(), true);
20137 mesh.merge(m);
20138 }
20139 } else if (0 <= instance_id && instance_id < int(mo.instances.size()))
20140 mesh.transform(mo.instances[instance_id]->get_matrix(), true);
20141 return mesh;
20142 };
20143#endif
20144 auto mesh_to_export_sla = [&, this](const ModelObject& mo, int instance_id) {
20145 TriangleMesh mesh;
20146
20147 const SLAPrintObject *object = this->p->sla_print.get_print_object_by_model_object_id(mo.id());
20148
20149 if (auto m = object->get_mesh_to_print(); m.empty())
20150 mesh = combine_mesh_fff(mo, instance_id, [this](const std::string& msg) {return get_notification_manager()->push_general_error_notification(msg); });
20151 else {
20152 const Transform3d mesh_trafo_inv = object->trafo().inverse();
20153 const bool is_left_handed = object->is_left_handed();
20154
20155 auto pad_mesh = extended? object->pad_mesh() : TriangleMesh{};
20156 pad_mesh.transform(mesh_trafo_inv);
20157
20158 auto supports_mesh = extended ? object->support_mesh() : TriangleMesh{};
20159 supports_mesh.transform(mesh_trafo_inv);
20160
20161 const std::vector<SLAPrintObject::Instance>& obj_instances = object->instances();
20162 for (const SLAPrintObject::Instance& obj_instance : obj_instances) {
20163 auto it = std::find_if(object->model_object()->instances.begin(), object->model_object()->instances.end(),
20164 [&obj_instance](const ModelInstance *mi) { return mi->id() == obj_instance.instance_id; });
20165 assert(it != object->model_object()->instances.end());
20166
20167 if (it != object->model_object()->instances.end()) {
20168 const bool one_inst_only = selection_only && ! selection.is_single_full_object();
20169
20170 const int instance_idx = it - object->model_object()->instances.begin();
20171 const Transform3d& inst_transform = one_inst_only
20172 ? Transform3d::Identity()
20173 : object->model_object()->instances[instance_idx]->get_transformation().get_matrix();
20174
20175 TriangleMesh inst_mesh;
20176
20177 if (!pad_mesh.empty()) {
20178 TriangleMesh inst_pad_mesh = pad_mesh;
20179 inst_pad_mesh.transform(inst_transform, is_left_handed);
20180 inst_mesh.merge(inst_pad_mesh);
20181 }
20182
20183 if (!supports_mesh.empty()) {
20184 TriangleMesh inst_supports_mesh = supports_mesh;
20185 inst_supports_mesh.transform(inst_transform, is_left_handed);
20186 inst_mesh.merge(inst_supports_mesh);
20187 }
20188
20189 TriangleMesh inst_object_mesh = object->get_mesh_to_print();
20190
20191 inst_object_mesh.transform(mesh_trafo_inv);
20192 inst_object_mesh.transform(inst_transform, is_left_handed);
20193
20194 inst_mesh.merge(inst_object_mesh);
20195
20196 // ensure that the instance lays on the bed
20197 inst_mesh.translate(0.0f, 0.0f, -inst_mesh.bounding_box().min.z());
20198
20199 // merge instance with global mesh
20200 mesh.merge(inst_mesh);
20201
20202 if (one_inst_only)
20203 break;
20204 }
20205 }
20206 }
20207
20208 return mesh;
20209 };
20210
20211 std::function<TriangleMesh(const ModelObject& mo, int instance_id)>
20212 mesh_to_export;
20213
20214 if (p->printer_technology == ptFFF)
20215#if EXPORT_WITH_BOOLEAN
20216 mesh_to_export = [this](const ModelObject& mo, int instance_id) {return Plater::combine_mesh_fff(mo, instance_id,
20217 [this](const std::string& msg) {return get_notification_manager()->push_general_error_notification(msg); }); };
20218#else
20219 mesh_to_export = mesh_to_export_fff_no_boolean;
20220#endif
20221 else
20222 mesh_to_export = mesh_to_export_sla;
20223
20224 auto get_save_file = [file_type](std::string const & dir, std::string const & name) {
20225 std::string ext = "";
20226 switch (file_type) {
20227 case FT_STL: ext = ".stl"; break;
20228 case FT_DRC: ext = ".drc"; break;
20229 }
20230
20231 auto path = dir + name + ext;
20232 int n = 1;
20233 while (boost::filesystem::exists(path))
20234 path = dir + name + "(" + std::to_string(n++) + ")"+ext;
20235 return path;
20236 };
20237
20238 TriangleMesh mesh;
20239 if (selection_only) {
20240 if (selection.is_single_full_object()) {
20241 const auto obj_idx = selection.get_object_idx();
20242 const ModelObject* model_object = p->model.objects[obj_idx];
20243 if (selection.get_mode() == Selection::Instance)
20244 mesh = mesh_to_export(*model_object, (model_object->instances.size() > 1) ? -1 : selection.get_instance_idx());
20245 else {
20246 const GLVolume* volume = selection.get_first_volume();
20247 mesh = model_object->volumes[volume->volume_idx()]->mesh();
20248 mesh.transform(volume->get_volume_transformation().get_matrix(), true);
20249 }
20250
20251 if (model_object->instances.size() == 1) mesh.translate(-model_object->origin_translation.cast<float>());
20252 }
20253 else if (selection.is_multiple_full_object() && !multi_stls) {
20254 const std::set<std::pair<int, int>>& instances_idxs = p->get_selection().get_selected_object_instances();
20255 for (const std::pair<int, int>& i : instances_idxs) {
20256 ModelObject* object = p->model.objects[i.first];
20257 mesh.merge(mesh_to_export(*object, i.second));
20258 }
20259 }
20260 else if (selection.is_multiple_full_object() && multi_stls) {
20261 const std::set<std::pair<int, int>> &instances_idxs = p->get_selection().get_selected_object_instances();
20262 for (const std::pair<int, int> &i : instances_idxs) {
20263 ModelObject *object = p->model.objects[i.first];
20264 auto mesh = mesh_to_export(*object, i.second);
20265 mesh.translate(-object->origin_translation.cast<float>());
20266
20267 switch (file_type) {
20268 case FT_STL: Slic3r::store_stl(get_save_file(path_u8, object->name).c_str(), &mesh, true); break;
20269 case FT_DRC: Slic3r::store_drc(get_save_file(path_u8, object->name).c_str(), &mesh, quality); break;
20270 }
20271 }
20272 return;
20273 }
20274 }
20275 else if (!multi_stls) {
20276 for (const ModelObject* o : p->model.objects) {
20277 mesh.merge(mesh_to_export(*o, -1));
20278 }
20279 } else {
20280 for (const ModelObject* o : p->model.objects) {
20281 auto mesh = mesh_to_export(*o, -1);
20282 mesh.translate(-o->origin_translation.cast<float>());
20283
20284 switch (file_type) {
20285 case FT_STL: Slic3r::store_stl(get_save_file(path_u8, o->name).c_str(), &mesh, true); break;
20286 case FT_DRC: Slic3r::store_drc(get_save_file(path_u8, o->name).c_str(), &mesh, quality); break;
20287 }
20288 }
20289 return;
20290 }
20291
20292 switch (file_type) {
20293 case FT_STL: Slic3r::store_stl(path_u8.c_str(), &mesh, true); break;
20294 case FT_DRC: Slic3r::store_drc(path_u8.c_str(), &mesh, quality); break;
20295 }
20296}
#define DRC_BITS_DEFAULT
Definition DRC.hpp:8
void push_plater_error_notification(const std::string &text)
Definition NotificationManager.cpp:2095
void push_general_error_notification(const std::string &text)
Definition NotificationManager.cpp:2109
static TriangleMesh combine_mesh_fff(const ModelObject &mo, int instance_id, std::function< void(const std::string &)> notify_func={})
Definition Plater.cpp:19986
@ FT_DRC
Definition GUI_App.hpp:139
@ FT_STL
Definition GUI_App.hpp:121
static bool is_left_handed(const Transform3d::ConstLinearPart &m)
Definition Selection.cpp:2998
indexed_triangle_set csgmesh_merge_positive_parts(const Cont &csgmesh)
Definition CSGMesh.hpp:107
bool is_all_positive(const Cont &csgmesh)
Definition CSGMesh.hpp:91
@ mpartsDoSplits
Definition ModelToCSGMesh.hpp:22
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:96
auto range(Cont &&cont)
Definition libslic3r.h:405
bool store_drc(const char *path, TriangleMesh *mesh, int bits, int speed)
Definition DRC.cpp:127
bool store_stl(const char *path, TriangleMesh *mesh, bool binary)
Definition STL.cpp:43

References _L, _u8L, Slic3r::TriangleMesh::bounding_box(), Slic3r::MeshBoolean::cgal::cgal_to_triangle_mesh(), Slic3r::csg::check_csgmesh_booleans(), combine_mesh_fff(), Slic3r::csg::csgmesh_merge_positive_parts(), DRC_BITS_DEFAULT, Slic3r::TriangleMesh::empty(), Slic3r::GUI::from_u8(), Slic3r::GUI::FT_DRC, Slic3r::GUI::FT_STL, Slic3r::AppConfig::get(), Slic3r::GUI::Selection::get_first_volume(), Slic3r::GUI::Selection::get_instance_idx(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::ModelInstance::get_matrix(), Slic3r::ModelVolume::get_matrix(), Slic3r::SLAPrintObject::get_mesh_to_print(), Slic3r::GUI::Selection::get_mode(), get_notification_manager(), Slic3r::GUI::Selection::get_object_idx(), Slic3r::GLVolume::get_volume_transformation(), Slic3r::ObjectBase::id(), Slic3r::GUI::Selection::Instance, Slic3r::ModelObject::instances, Slic3r::GUI::into_u8(), Slic3r::csg::is_all_positive(), Slic3r::GUI::is_left_handed(), Slic3r::ModelVolume::is_model_part(), Slic3r::GUI::Selection::is_multiple_full_object(), Slic3r::GUI::Selection::is_single_full_object(), Slic3r::GUI::Selection::is_wipe_tower(), Slic3r::TriangleMesh::merge(), Slic3r::ModelVolume::mesh(), Slic3r::BoundingBoxBase< PointType, std::vector< PointType > >::min, Slic3r::PrintObjectBase::model_object(), Slic3r::csg::model_to_csgmesh(), Slic3r::csg::mpartsDoSplits, Slic3r::csg::mpartsNegative, Slic3r::csg::mpartsPositive, Slic3r::ModelObject::name, Slic3r::ModelObject::origin_translation, p, Slic3r::csg::perform_csgmesh_booleans(), Slic3r::ptFFF, Slic3r::GUI::NotificationManager::push_general_error_notification(), Slic3r::GUI::NotificationManager::push_plater_error_notification(), Slic3r::range(), Slic3r::store_drc(), Slic3r::store_stl(), Slic3r::TriangleMesh::transform(), Slic3r::TriangleMesh::translate(), Slic3r::GLVolume::volume_idx(), and Slic3r::ModelObject::volumes.

Here is the call graph for this function:

◆ export_toolpaths_to_obj()

void Slic3r::GUI::Plater::export_toolpaths_to_obj ( ) const
20723{
20725 return;
20726
20727 wxString path = p->get_export_file(FT_OBJ);
20728 if (path.empty())
20729 return;
20730
20731 wxBusyCursor wait;
20732 p->preview->get_canvas3d()->export_toolpaths_to_obj(into_u8(path).c_str());
20733}
bool is_preview_loaded() const
Definition Plater.cpp:19126
@ FT_OBJ
Definition GUI_App.hpp:122

References Slic3r::GUI::FT_OBJ, Slic3r::GUI::into_u8(), is_preview_loaded(), p, printer_technology(), and Slic3r::ptFFF.

Here is the call graph for this function:

◆ extract_config_from_project()

void Slic3r::GUI::Plater::extract_config_from_project ( )
18131{
18132 wxString input_file;
18133 wxGetApp().load_project(this, input_file);
18134
18135 if (! input_file.empty())
18137}
@ LoadConfig
Definition bbs_3mf.hpp:223

References Slic3r::GUI::into_path(), load_files(), and Slic3r::LoadConfig.

Here is the call graph for this function:

◆ fff_print() [1/2]

Print & Slic3r::GUI::Plater::fff_print ( )
16050{ return p->fff_print; }

References p.

◆ fff_print() [2/2]

const Print & Slic3r::GUI::Plater::fff_print ( ) const
16049{ return p->fff_print; }

References p.

Referenced by export_3mf().

Here is the caller graph for this function:

◆ filament_action_menu()

wxMenu * Slic3r::GUI::Plater::filament_action_menu ( int active_filament_menu_id)
24132{ return p->menus.filament_action_menu(active_filament_menu_id); }

References p.

◆ fill_bed_with_copies()

void Slic3r::GUI::Plater::fill_bed_with_copies ( )
19406{
19407 auto &w = get_ui_job_worker();
19408 if (w.is_idle()) {
19409 p->take_snapshot(_u8L("Arrange"));
19410 replace_job(w, std::make_unique<FillBedJob>());
19411 }
19412}

References _u8L, get_ui_job_worker(), p, and Slic3r::GUI::replace_job().

Here is the call graph for this function:

◆ fill_bed_with_instances()

void Slic3r::GUI::Plater::fill_bed_with_instances ( )
19415{
19416 auto &w = get_ui_job_worker();
19417 if (w.is_idle()) {
19418 p->take_snapshot(_u8L("Arrange"));
19419 replace_job(w, std::make_unique<FillBedJob>(true));
19420 }
19421}

References _u8L, get_ui_job_worker(), p, and Slic3r::GUI::replace_job().

Here is the call graph for this function:

◆ fill_color()

void Slic3r::GUI::Plater::fill_color ( int extruder_id)
22415{
22416 if (can_fillcolor()) {
22417 p->assemble_view->get_canvas3d()->get_selection().fill_color(extruder_id);
22418 }
22419}
bool can_fillcolor() const
Definition Plater.cpp:23945

References can_fillcolor(), and p.

Here is the call graph for this function:

◆ find_new_position()

void Slic3r::GUI::Plater::find_new_position ( const ModelInstancePtrs & instances)
10941{
10942 arrangement::ArrangePolygons movable, fixed;
10943 arrangement::ArrangeParams arr_params = init_arrange_params(this);
10944
10945 for (const ModelObject *mo : p->model.objects)
10946 for (ModelInstance *inst : mo->instances) {
10947 auto it = std::find(instances.begin(), instances.end(), inst);
10948 arrangement::ArrangePolygon arrpoly;
10949 inst->get_arrange_polygon(&arrpoly);
10950
10951 if (it == instances.end())
10952 fixed.emplace_back(std::move(arrpoly));
10953 else {
10954 arrpoly.setter = [it](const arrangement::ArrangePolygon &p) {
10955 if (p.is_arranged() && p.bed_idx == 0) {
10956 Vec2d t = p.translation.cast<double>();
10957 (*it)->apply_arrange_result(t, p.rotation);
10958 }
10959 };
10960 movable.emplace_back(std::move(arrpoly));
10961 }
10962 }
10963
10964 if (auto wt = get_wipe_tower_arrangepoly(*this))
10965 fixed.emplace_back(*wt);
10966
10967 arrangement::arrange(movable, fixed, this->build_volume().polygon(), arr_params);
10968
10969 for (auto & m : movable)
10970 m.apply();
10971}
const BuildVolume & build_volume() const
Definition Plater.cpp:23803
std::optional< arrangement::ArrangePolygon > get_wipe_tower_arrangepoly(const Plater &plater)
Definition ArrangeJob.cpp:968
arrangement::ArrangeParams init_arrange_params(Plater *p)
Definition ArrangeJob.cpp:989
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:67

References Slic3r::arrangement::arrange(), build_volume(), Slic3r::ModelInstance::get_arrange_polygon(), Slic3r::GUI::get_wipe_tower_arrangepoly(), Slic3r::GUI::init_arrange_params(), Slic3r::ModelObject::instances, p, and Slic3r::arrangement::ArrangePolygon::setter.

Here is the call graph for this function:

◆ force_filament_colors_update()

void Slic3r::GUI::Plater::force_filament_colors_update ( )
21752{
21753//BBS: filament_color logic has been moved out of filament setting
21754#if 0
21755 bool update_scheduled = false;
21756 DynamicPrintConfig* config = p->config;
21757 const std::vector<std::string> filament_presets = wxGetApp().preset_bundle->filament_presets;
21758 if (filament_presets.size() > 1 &&
21759 p->config->option<ConfigOptionStrings>("filament_colour")->values.size() == filament_presets.size())
21760 {
21761 const PresetCollection& filaments = wxGetApp().preset_bundle->filaments;
21762 std::vector<std::string> filament_colors;
21763 filament_colors.reserve(filament_presets.size());
21764
21765 for (const std::string& filament_preset : filament_presets)
21766 filament_colors.push_back(filaments.find_preset(filament_preset, true)->config.opt_string("filament_colour", (unsigned)0));
21767
21768 if (config->option<ConfigOptionStrings>("filament_colour")->values != filament_colors) {
21769 config->option<ConfigOptionStrings>("filament_colour")->values = filament_colors;
21770 update_scheduled = true;
21771 }
21772 }
21773
21774 if (update_scheduled) {
21775 update();
21776 p->sidebar->obj_list()->update_filament_colors();
21777 }
21778
21779 if (p->main_frame->is_loaded())
21780 this->p->schedule_background_process();
21781#endif
21782}

References config(), Slic3r::Preset::config, Slic3r::PresetCollection::find_preset(), Slic3r::DynamicConfig::opt_string(), p, update(), and Slic3r::ConfigOptionVector< T >::values.

Here is the call graph for this function:

◆ force_print_bed_update()

void Slic3r::GUI::Plater::force_print_bed_update ( )
21785{
21786 // Fill in the printer model key with something which cannot possibly be valid, so that Plater::on_config_change() will update the print bed
21787 // once a new Printer profile config is loaded.
21788 p->config->opt_string("printer_model", true) = "bbl_empty";
21789}

References p.

◆ force_update_all_plate_thumbnails()

void Slic3r::GUI::Plater::force_update_all_plate_thumbnails ( )
18394{
18396 }
18397 else {
18400 }
18401}
bool skip_thumbnail_invalid
Definition Plater.hpp:1098
void update_all_plate_thumbnails(bool force_update=false)
Definition Plater.cpp:18348
void invalid_all_plate_thumbnails()
Definition Plater.cpp:18380

References invalid_all_plate_thumbnails(), skip_thumbnail_invalid, update_all_plate_thumbnails(), and using_exported_file().

Here is the call graph for this function:

◆ format_imex_ghost_tooltip()

Plater::ImexGhostTooltip Slic3r::GUI::Plater::format_imex_ghost_tooltip ( int physical_head) const
24068{
24069 ImexGhostTooltip t{physical_head, -1, GLVolume::UNPRINTABLE_COLOR, {}};
24070
24071 const PartPlate* plate = p->partplate_list.get_curr_plate();
24072 if (!plate) {
24073 t.label = Slic3r::format(_u8L("T%1% -> (no plate)"), physical_head);
24074 return t;
24075 }
24076
24077 const ConfigOptionInts pem = effective_physical_extruder_map(*wxGetApp().preset_bundle);
24078 const auto map = plate->get_imex_head_filament_map();
24079 const int logical = resolve_filament_for_head(map, pem, physical_head);
24080 if (logical < 0) {
24081 // No filament slot resolves to this physical head. Usually means the printer's
24082 // extruder count is understated relative to the filament palette (user added a
24083 // filament without extending printer_extruder_id in the Machine tab).
24084 // TRN IDEX/IQEX ghost tooltip. %1% is the number of the physical print head.
24085 t.label = Slic3r::format(_u8L("T%1% — no filament routed\nAdd an extruder in the Machine tab so this head has a filament slot."), physical_head);
24086 return t;
24087 }
24088 t.filament_slot_1based = logical + 1;
24089 // Reuse the pem/map already hoisted above so label and swatch are derived
24090 // from one resolution, not two.
24091 t.swatch = plate->get_imex_head_filament_color(physical_head, pem, map);
24092 t.swatch.a(1.0f); // tooltip swatch opaque
24093 // TRN IDEX/IQEX ghost tooltip. %1% is the number of the physical print head, %2% the filament it prints.
24094 t.label = Slic3r::format(_u8L("T%1% -> filament %2%"), physical_head, t.filament_slot_1based);
24095 return t;
24096}
static ColorRGBA UNPRINTABLE_COLOR
Definition 3DScene.hpp:98
Definition Plater.hpp:748
ConfigOptionInts effective_physical_extruder_map(const ConfigOptionInts *explicit_pem, int nozzle_count)
Definition IMEXHelpers.cpp:52
int resolve_filament_for_head(const std::map< int, int > &plate_map, const ConfigOptionInts &pem, int physical)
Definition IMEXHelpers.cpp:556

References _u8L, Slic3r::ColorRGBA::a(), Slic3r::effective_physical_extruder_map(), Slic3r::GUI::Plater::ImexGhostTooltip::filament_slot_1based, Slic3r::format(), Slic3r::GUI::PartPlate::get_imex_head_filament_color(), Slic3r::GUI::PartPlate::get_imex_head_filament_map(), Slic3r::GUI::Plater::ImexGhostTooltip::label, p, Slic3r::resolve_filament_for_head(), Slic3r::GUI::Plater::ImexGhostTooltip::swatch, and Slic3r::GLVolume::UNPRINTABLE_COLOR.

Here is the call graph for this function:

◆ gcode_settings_loaded()

bool Slic3r::GUI::Plater::gcode_settings_loaded ( ) const
inline
bool m_gcode_settings_loaded
Definition Plater.hpp:1096

References m_gcode_settings_loaded, and m_only_gcode.

◆ get_3mf_file_count()

int Slic3r::GUI::Plater::get_3mf_file_count ( std::vector< boost::filesystem::path > paths)
18979{
18980 auto count = 0;
18981 for (const auto &path : paths) {
18982 if (boost::iends_with(path.filename().string(), ".3mf")) {
18983 count++;
18984 }
18985 }
18986 return count;
18987}
static unsigned int count
Definition AuxiliaryDataViewModel.cpp:246

References count.

Referenced by add_file(), add_model(), and load_files().

Here is the caller graph for this function:

◆ get_3mf_filename()

std::string Slic3r::GUI::Plater::get_3mf_filename ( )
inline
783{ return m_3mf_path; };
std::string m_3mf_path
Definition Plater.hpp:1085

References m_3mf_path.

◆ get_assmeble_canvas3D()

GLCanvas3D * Slic3r::GUI::Plater::get_assmeble_canvas3D ( )
22093{
22094 if (p->assemble_view)
22095 return p->assemble_view->get_canvas3d();
22096 return nullptr;
22097}

References p.

◆ get_bed_texture_maps()

std::map< std::string, std::string > Slic3r::GUI::Plater::get_bed_texture_maps ( )
8480{
8481 auto pm = get_curr_printer_model();
8482 if (pm) {
8483 std::map<std::string, std::string> maps;
8484 if (pm->use_double_extruder_default_texture.size() > 0) {
8485 maps["use_double_extruder_default_texture"] = pm->use_double_extruder_default_texture;
8486 }
8487 if (pm->bottom_texture_end_name.size() > 0) {
8488 maps["bottom_texture_end_name"] = pm->bottom_texture_end_name;
8489 }
8490 if (pm->bottom_texture_rect.size() > 0) {
8491 maps["bottom_texture_rect"] = pm->bottom_texture_rect;
8492 }
8493 if (pm->bottom_texture_rect_longer.size() > 0) {
8494 maps["bottom_texture_rect_longer"] = pm->bottom_texture_rect_longer;
8495 }
8496 if (pm->middle_texture_rect.size() > 0) {
8497 maps["middle_texture_rect"] = pm->middle_texture_rect;
8498 }
8499 return maps;
8500 }
8501 return {};
8502}
const VendorProfile::PrinterModel * get_curr_printer_model()
Definition Plater.cpp:8460

References get_curr_printer_model().

Here is the call graph for this function:

◆ get_build_volume_type()

BuildVolume_Type Slic3r::GUI::Plater::get_build_volume_type ( ) const
18107{ return p->bed.get_build_volume_type(); }

References p.

◆ get_camera() [1/2]

Camera & Slic3r::GUI::Plater::get_camera ( )
22573{
22574 return p->camera;
22575}

References p.

◆ get_camera() [2/2]

const Camera & Slic3r::GUI::Plater::get_camera ( ) const
22568{
22569 return p->camera;
22570}

References p.

Referenced by Slic3r::GUI::TextLinesModel::render().

Here is the caller graph for this function:

◆ get_collapse_toolbar() [1/2]

GLToolbar & Slic3r::GUI::Plater::get_collapse_toolbar ( )
23827{
23828 return p->collapse_toolbar;
23829}

References p.

◆ get_collapse_toolbar() [2/2]

const GLToolbar & Slic3r::GUI::Plater::get_collapse_toolbar ( ) const
23822{
23823 return p->collapse_toolbar;
23824}

References p.

◆ get_colors_for_color_print()

std::vector< std::string > Slic3r::GUI::Plater::get_colors_for_color_print ( const GCodeProcessorResult *const result = nullptr) const
21942{
21943 std::vector<std::string> colors = get_extruder_colors_from_plater_config(result);
21944
21945 if (wxGetApp().is_gcode_viewer() && result != nullptr) {
21946 for (const CustomGCode::Item& code : result->custom_gcode_per_print_z) {
21947 if (code.type == CustomGCode::ColorChange)
21948 colors.emplace_back(code.color);
21949 }
21950 }
21951 else {
21952 //BBS
21953 colors.reserve(colors.size() + p->model.get_curr_plate_custom_gcodes().gcodes.size());
21954 for (const CustomGCode::Item& code : p->model.get_curr_plate_custom_gcodes().gcodes) {
21955 if (code.type == CustomGCode::ColorChange)
21956 colors.emplace_back(code.color);
21957 }
21958 }
21959
21960 return colors;
21961}
std::vector< std::string > get_extruder_colors_from_plater_config(const GCodeProcessorResult *const result=nullptr) const
Definition Plater.cpp:21797
@ ColorChange
Definition CustomGCode.hpp:19

References Slic3r::CustomGCode::Item::color, Slic3r::CustomGCode::ColorChange, Slic3r::GCodeProcessorResult::custom_gcode_per_print_z, get_extruder_colors_from_plater_config(), p, and Slic3r::CustomGCode::Item::type.

Here is the call graph for this function:

◆ get_curr_printer_model()

const VendorProfile::PrinterModel * Slic3r::GUI::Plater::get_curr_printer_model ( )
8461{
8462 auto bundle = wxGetApp().preset_bundle;
8463 if (bundle) {
8464 const Preset *curr = &bundle->printers.get_selected_preset();
8465 if (curr) {
8466 const VendorProfile::PrinterModel *pm = PresetUtils::system_printer_model(*curr);
8467 if (!pm) {
8468 auto curr_parent = bundle->printers.get_selected_preset_parent();
8469 if (curr_parent) {
8470 pm = PresetUtils::system_printer_model(*curr_parent);
8471 }
8472 }
8473 return pm;
8474 }
8475 }
8476 return nullptr;
8477}
const VendorProfile::PrinterModel * system_printer_model(const Preset &preset)
Definition Preset.cpp:5081
@ Preset
Definition calib.hpp:39

References Slic3r::PresetUtils::system_printer_model().

Referenced by get_bed_texture_maps().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_current_canvas3D()

GLCanvas3D * Slic3r::GUI::Plater::get_current_canvas3D ( bool exclude_preview = false)

◆ get_dailytips()

DailyTipsWindow * Slic3r::GUI::Plater::get_dailytips ( ) const
23859{
23860 static DailyTipsWindow* dailytips_win = new DailyTipsWindow();
23861 return dailytips_win;
23862}

◆ get_empty_cells()

std::vector< Vec2f > Slic3r::GUI::Plater::get_empty_cells ( const Vec2f step,
const std::vector< BoundingBoxf > & local_exclude_boxes = {},
bool include_plate_exclude_areas = true )
static
22465{
22466 PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
22467 BoundingBoxf3 build_volume = plate->get_build_volume(true);
22468 Vec2d vmin(build_volume.min.x(), build_volume.min.y()), vmax(build_volume.max.x(), build_volume.max.y());
22469 BoundingBoxf bbox(vmin, vmax);
22470 std::vector<Vec2f> cells;
22471 auto min_x = step(0)/2;// start_point.x() - step(0) * int((start_point.x() - bbox.min.x()) / step(0));
22472 auto min_y = step(1)/2;// start_point.y() - step(1) * int((start_point.y() - bbox.min.y()) / step(1));
22473 std::vector<BoundingBoxf> exclude_boxs;
22474 if (include_plate_exclude_areas) {
22475 const auto &exclude_box3s = plate->get_exclude_areas();
22476 for (const auto &box : exclude_box3s) {
22477 Vec2d vmin(box.min.x(), box.min.y()), vmax(box.max.x(), box.max.y());
22478 exclude_boxs.emplace_back(vmin, vmax);
22479 }
22480 }
22481 const Vec3d plate_origin = plate->get_origin();
22482 for (BoundingBoxf box : local_exclude_boxes) {
22483 box.translate(Vec2d(plate_origin.x(), plate_origin.y()));
22484 exclude_boxs.emplace_back(std::move(box));
22485 }
22486 for (float x = min_x + bbox.min.x(); x < bbox.max.x() - step(0) / 2; x += step(0))
22487 for (float y = min_y + bbox.min.y(); y < bbox.max.y() - step(1) / 2; y += step(1)) {
22488 bool in_exclude = false;
22489 BoundingBoxf cell(Vec2d(x - step(0) / 2, y - step(1) / 2), Vec2d(x + step(0) / 2, y + step(1) / 2));
22490 for (auto& box : exclude_boxs) {
22491 if (box.overlap(cell)) {
22492 in_exclude = true;
22493 break;
22494 }
22495 }
22496 if(in_exclude)
22497 continue;
22498 cells.emplace_back(x, y);
22499 }
22500 return cells;
22501}
void step(Coord &crd, const Dir d, const long n=1)
Definition MarchingSquares.hpp:213

References build_volume(), Slic3r::GUI::PartPlate::get_build_volume(), Slic3r::GUI::PartPlate::get_exclude_areas(), Slic3r::GUI::PartPlate::get_origin(), Slic3r::BoundingBoxBase< PointType, APointsType >::max, and Slic3r::BoundingBoxBase< PointType, APointsType >::min.

Referenced by Slic3r::GUI::FillBedJob::process().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_enable_wrapping_detection()

bool Slic3r::GUI::Plater::get_enable_wrapping_detection ( )
8505{
8506 const DynamicPrintConfig & print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
8507 const ConfigOptionBool * wrapping_detection = print_config.option<ConfigOptionBool>("enable_wrapping_detection");
8508 return (wrapping_detection != nullptr) && wrapping_detection->value;
8509}

References Slic3r::ConfigBase::option(), and Slic3r::ConfigOptionSingle< T >::value.

Here is the call graph for this function:

◆ get_export_gcode_filename()

wxString Slic3r::GUI::Plater::get_export_gcode_filename ( const wxString & extension = wxEmptyString,
bool only_filename = false,
bool export_all = false ) const
22041{
22042 return p->get_export_gcode_filename(extension, only_filename, export_all);
22043}

References p.

◆ get_extruder_colors_from_plater_config()

std::vector< std::string > Slic3r::GUI::Plater::get_extruder_colors_from_plater_config ( const GCodeProcessorResult *const result = nullptr) const
21798{
21799 if (wxGetApp().is_gcode_viewer() && result != nullptr)
21800 return result->extruder_colors;
21801 else {
21802 const Slic3r::DynamicPrintConfig* config = &wxGetApp().preset_bundle->project_config;
21803 std::vector<std::string> filament_colors;
21804 if (!config->has("filament_colour")) // in case of a SLA print
21805 return filament_colors;
21806
21807 filament_colors = (config->option<ConfigOptionStrings>("filament_colour"))->values;
21808 return filament_colors;
21809 }
21810}

References config(), and Slic3r::GCodeProcessorResult::extruder_colors.

Referenced by get_colors_for_color_print(), and get_extruders_colors().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_extruders_colors()

std::vector< Slic3r::ColorRGBA > Slic3r::GUI::Plater::get_extruders_colors ( )
21460{
21461 unsigned char rgba_color[4] = {};
21462 std::vector<std::string> colors = get_extruder_colors_from_plater_config();
21463 std::vector<Slic3r::ColorRGBA> colors_out(colors.size());
21464 for (const std::string &color : colors) {
21465 Slic3r::GUI::BitmapCache::parse_color4(color, rgba_color);
21466 size_t color_idx = &color - &colors.front();
21467 colors_out[color_idx] = {
21468 float(rgba_color[0]) / 255.f,
21469 float(rgba_color[1]) / 255.f,
21470 float(rgba_color[2]) / 255.f,
21471 float(rgba_color[3]) / 255.f,
21472 };
21473 }
21474 return colors_out;
21475}
static bool parse_color4(const std::string &scolor, unsigned char *rgba_out)
Definition BitmapCache.cpp:559

References get_extruder_colors_from_plater_config(), and Slic3r::GUI::BitmapCache::parse_color4().

Here is the call graph for this function:

◆ get_filament_color_render_type()

std::vector< std::string > Slic3r::GUI::Plater::get_filament_color_render_type ( ) const
21887{
21888 const Slic3r::DynamicPrintConfig *config = &wxGetApp().preset_bundle->project_config;
21889 std::vector<std::string> ctype;
21890 if (!config->has("filament_colour_type")) return ctype;
21891
21892 ctype = (config->option<ConfigOptionStrings>("filament_colour_type"))->values;
21893
21894 auto slots = parse_mixed_gradient_slots(*config, ctype.size());
21895 while (ctype.size() < slots.size()) ctype.push_back("1");
21896 for (size_t i = 0; i < ctype.size() && i < slots.size(); ++i) {
21897 if (slots[i].is_gradient)
21898 ctype[i] = "0";
21899 }
21900
21901 return ctype;
21902}
std::vector< MixedGradientSlot > parse_mixed_gradient_slots(const Slic3r::DynamicPrintConfig &config, size_t slot_count)
Definition Plater.cpp:21823

References config().

Here is the call graph for this function:

◆ get_filament_colors_render_info()

std::vector< std::string > Slic3r::GUI::Plater::get_filament_colors_render_info ( ) const
21870{
21871 const Slic3r::DynamicPrintConfig* config = &wxGetApp().preset_bundle->project_config;
21872 std::vector<std::string> color_packs;
21873 if (!config->has("filament_multi_colour")) return color_packs;
21874
21875 color_packs = (config->option<ConfigOptionStrings>("filament_multi_colour"))->values;
21876
21877 auto slots = parse_mixed_gradient_slots(*config, color_packs.size());
21878 for (size_t i = 0; i < color_packs.size(); ++i) {
21879 if (slots[i].is_gradient)
21880 color_packs[i] = slots[i].color_from + " " + slots[i].color_to;
21881 }
21882
21883 return color_packs;
21884}

References config().

Here is the call graph for this function:

◆ get_filament_gradient_ramps()

const std::vector< std::vector< wxColour > > & Slic3r::GUI::Plater::get_filament_gradient_ramps ( ) const
21905{
21906 // Sampling a ramp walks the measured-blend recipe table once per step and the paint toolbar
21907 // asks for the ramps every rendered frame, so they are cached against the config values they
21908 // are built from. The cache is static rather than a Plater member because the extruder icons
21909 // ask for the ramps from MenuFactory::init(), which runs while this Plater is still inside its
21910 // own constructor, so wxGetApp().plater_ is not assigned yet.
21911 static std::string s_ramps_key;
21912 static std::vector<std::vector<wxColour>> s_ramps;
21913
21914 static const char* ramp_keys[] = {"filament_is_mixed", "filament_mixed_gradient",
21915 "filament_mixed_components", "filament_colour",
21916 "filament_mixed_gradient_range", "filament_mixed_gradient_curve"};
21917
21918 const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config;
21919 std::string key;
21920 for (const char* opt_key : ramp_keys)
21921 if (const ConfigOption* opt = config.option(opt_key))
21922 key += opt->serialize() + '\n';
21923 if (key == s_ramps_key)
21924 return s_ramps;
21925
21926 // 64 bands outresolve every swatch drawn from this, all of which resample it down to their
21927 // own height, so one cached resolution serves the icons and both ImGui filament bars.
21928 const auto* colour_opt = config.option<ConfigOptionStrings>("filament_colour");
21929 const size_t n = colour_opt ? colour_opt->values.size() : 0;
21930 s_ramps.assign(n, {});
21931 for (size_t i = 0; i < n; ++i)
21932 s_ramps[i] = mixed_gradient_ramp(config, i, 64);
21933 s_ramps_key = std::move(key);
21934
21935 return s_ramps;
21936}
std::vector< wxColour > mixed_gradient_ramp(const Slic3r::DynamicPrintConfig &cfg, size_t slot, int steps)
Definition FilamentBitmapUtils.cpp:163

References config(), Slic3r::GUI::mixed_gradient_ramp(), and Slic3r::ConfigOptionVector< T >::values.

Here is the call graph for this function:

◆ get_global_filament_map()

std::vector< int > Slic3r::GUI::Plater::get_global_filament_map ( ) const
21987{
21988 auto& project_config = wxGetApp().preset_bundle->project_config;
21989 return project_config.option<ConfigOptionInts>("filament_map")->values;
21990}

Referenced by Slic3r::GUI::get_applied_map().

Here is the caller graph for this function:

◆ get_global_filament_map_mode()

FilamentMapMode Slic3r::GUI::Plater::get_global_filament_map_mode ( ) const
22000{
22001 auto& project_config = wxGetApp().preset_bundle->project_config;
22002 return project_config.option<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode")->value;
22003}

Referenced by Slic3r::GUI::get_applied_map_mode().

Here is the caller graph for this function:

◆ get_global_filament_volume_map()

std::vector< int > Slic3r::GUI::Plater::get_global_filament_volume_map ( ) const
21993{
21994 auto& project_config = wxGetApp().preset_bundle->project_config;
21995 return project_config.option<ConfigOptionInts>("filament_volume_map")->values;
21996}

Referenced by Slic3r::GUI::get_applied_volume_map().

Here is the caller graph for this function:

◆ get_last_loaded_gcode()

const wxString & Slic3r::GUI::Plater::get_last_loaded_gcode ( ) const
inline
456{ return m_last_loaded_gcode; }
wxString m_last_loaded_gcode
Definition Plater.hpp:1092

References m_last_loaded_gcode.

◆ get_machine_sync_status()

bool Slic3r::GUI::Plater::get_machine_sync_status ( )
23762{
23763 return p->get_machine_sync_status();
23764}

References p.

Referenced by Slic3r::GUI::try_pop_up_before_slice().

Here is the caller graph for this function:

◆ get_mouse3d_controller() [1/2]

Mouse3DController & Slic3r::GUI::Plater::get_mouse3d_controller ( )
23849{
23850 return p->mouse3d_controller;
23851}

References p.

◆ get_mouse3d_controller() [2/2]

const Mouse3DController & Slic3r::GUI::Plater::get_mouse3d_controller ( ) const
23844{
23845 return p->mouse3d_controller;
23846}

References p.

◆ get_next_color_for_filament()

wxColour Slic3r::GUI::Plater::get_next_color_for_filament ( )
static
8512{
8513 static int curr_color_filamenet = 0;
8514 // refs to https://www.ebaomonthly.com/window/photo/lesson/colorList.htm
8515 wxColour colors[FILAMENT_SYSTEM_COLORS_NUM] = {
8516 // ORCA updated all color palette
8517 wxColour("#00C1AE"),
8518 wxColour("#F4E2C1"),
8519 wxColour("#ED1C24"),
8520 wxColour("#00FF7F"),
8521 wxColour("#F26722"),
8522 wxColour("#FFEB31"),
8523 wxColour("#7841CE"),
8524 wxColour("#115877"),
8525 wxColour("#ED1E79"),
8526 wxColour("#2EBDEF"),
8527 wxColour("#345B2F"),
8528 wxColour("#800080"),
8529 wxColour("#FA8173"),
8530 wxColour("#800000"),
8531 wxColour("#F7B763"),
8532 wxColour("#A4C41E"),
8533 };
8534 return colors[curr_color_filamenet++ % FILAMENT_SYSTEM_COLORS_NUM];
8535}
#define FILAMENT_SYSTEM_COLORS_NUM
Definition Plater.hpp:58

References FILAMENT_SYSTEM_COLORS_NUM.

Referenced by Slic3r::GUI::Sidebar::add_filament(), Slic3r::GUI::Plater::priv::load_files(), and Slic3r::GUI::Tab::on_value_change().

Here is the caller graph for this function:

◆ get_notification_manager() [1/2]

NotificationManager * Slic3r::GUI::Plater::get_notification_manager ( )
23854{
23855 return p->notification_manager.get();
23856}

References p.

◆ get_notification_manager() [2/2]

const NotificationManager * Slic3r::GUI::Plater::get_notification_manager ( ) const
23865{
23866 return p->notification_manager.get();
23867}

References p.

Referenced by _calib_pa_pattern(), config_change_notification(), export_stl(), Slic3r::PluginManager::fetch_plugins_from_cloud(), load_gcode(), load_project(), new_project(), notify_painting_removed(), and show_object_info().

Here is the caller graph for this function:

◆ get_partplate_list()

PartPlateList & Slic3r::GUI::Plater::get_partplate_list ( )

◆ get_pending_published()

bool Slic3r::GUI::Plater::get_pending_published ( std::vector< std::string > & out_keys,
std::vector< Slic3r::PublishedMaterialEntry > & out_material ) const
19897{
19898 if (!p->m_has_pending_published)
19899 return false;
19900 out_keys = p->m_pending_published_keys;
19901 out_material = p->m_pending_material_keys;
19902 return true;
19903}

References p.

◆ get_prepare_state()

int Slic3r::GUI::Plater::get_prepare_state ( )
14554{
14555 return p->m_job_prepare_state;
14556}

References p.

Referenced by Slic3r::GUI::init_arrange_params().

Here is the caller graph for this function:

◆ get_preview_canvas3D()

GLCanvas3D * Slic3r::GUI::Plater::get_preview_canvas3D ( )
22088{
22089 return p->preview->get_canvas3d();
22090}

References p.

◆ get_preview_only_filename()

std::string Slic3r::GUI::Plater::get_preview_only_filename ( )
inline
1064{ return m_preview_only_filename; };
std::string m_preview_only_filename
Definition Plater.hpp:1101

References m_preview_only_filename.

◆ get_print_finished_event()

int Slic3r::GUI::Plater::get_print_finished_event ( )
14584{
14585 return EVT_PRINT_FINISHED;
14586}

◆ get_print_job_data()

void Slic3r::GUI::Plater::get_print_job_data ( PrintPrepareData * data)
14559{
14560 if (data) {
14561 data->plate_idx = p->m_print_job_data.plate_idx;
14562 data->_3mf_path = p->m_print_job_data._3mf_path;
14563 data->_3mf_config_path = p->m_print_job_data._3mf_config_path;
14564 }
14565}

References Slic3r::GUI::PrintPrepareData::_3mf_config_path, Slic3r::GUI::PrintPrepareData::_3mf_path, p, and Slic3r::GUI::PrintPrepareData::plate_idx.

◆ get_project_filename()

wxString Slic3r::GUI::Plater::get_project_filename ( const wxString & extension = wxEmptyString) const
22036{
22037 return p->get_project_filename(extension);
22038}

References p.

Referenced by Slic3r::GUI::Plater::priv::get_export_file_path(), Slic3r::GUI::Plater::priv::reset(), save_project(), and Slic3r::GUI::ProjectDirtyStateManager::update_from_presets().

Here is the caller graph for this function:

◆ get_project_name()

wxString Slic3r::GUI::Plater::get_project_name ( )
18344{
18345 return p->get_project_name();
18346}

References p.

Referenced by add_file(), add_model(), and Slic3r::GUI::Plater::priv::get_export_file_path().

Here is the caller graph for this function:

◆ get_select_machine_dialog()

wxWindow * Slic3r::GUI::Plater::get_select_machine_dialog ( )
22018{
22019 return p->m_select_machine_dlg;
22020}

References p.

◆ get_selected_object_idx()

int Slic3r::GUI::Plater::get_selected_object_idx ( )
22061{
22062 return p->get_selected_object_idx();
22063}

References p.

Referenced by Slic3r::GUI::Plater::priv::can_decrease_instances(), Slic3r::GUI::Plater::priv::can_increase_instances(), Slic3r::GUI::Plater::priv::can_set_instance_to_object(), Slic3r::GUI::Plater::priv::can_simplify(), Slic3r::GUI::Plater::priv::layers_height_allowed(), Slic3r::GUI::Plater::priv::on_right_click(), and Slic3r::GUI::Plater::priv::split_object().

Here is the caller graph for this function:

◆ get_selected_printer_name_in_combox()

wxString Slic3r::GUI::Plater::get_selected_printer_name_in_combox ( )
22348 {
22349 PresetBundle * preset_bundle = wxGetApp().preset_bundle;
22350 std::string printer_model = preset_bundle->printers.get_selected_preset().config.option<ConfigOptionString>("printer_model")->value;
22351 return printer_model;
22352}
zaa_minimize_perimeter_height ConfigOptionString
Definition PrintConfig.hpp:1702

References Slic3r::Preset::config, Slic3r::PresetCollection::get_selected_preset(), Slic3r::ConfigBase::option(), and Slic3r::PresetBundle::printers.

Referenced by check_printer_initialized(), and is_same_printer_for_connected_and_selected().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_selection()

◆ get_send_calibration_finished_event()

int Slic3r::GUI::Plater::get_send_calibration_finished_event ( )
14579{
14580 return EVT_SEND_CALIBRATION_FINISHED;
14581}

◆ get_send_finished_event()

int Slic3r::GUI::Plater::get_send_finished_event ( )
14589{
14590 return EVT_SEND_FINISHED;
14591}

◆ get_sidebar_docking_state()

Sidebar::DockingState Slic3r::GUI::Plater::get_sidebar_docking_state ( ) const
19152{ return p->get_sidebar_docking_state(); }

References p.

◆ get_slice_warning_string()

wxString Slic3r::GUI::Plater::get_slice_warning_string ( GCodeProcessorResult::SliceWarning & warning)
static
8538{
8539 if (warning.msg == BED_TEMP_TOO_HIGH_THAN_FILAMENT) {
8540 return _L("The current heatbed temperature is relatively high. The nozzle may clog when printing this filament in a closed environment. Please open the front door and/or remove the upper glass.");
8541 } else if (warning.msg == NOZZLE_HRC_CHECKER) {
8542 return _L("The nozzle hardness required by the filament is higher than the default nozzle hardness of the printer. Please replace the hardened nozzle or filament, otherwise, the nozzle will be worn down or damaged.");
8543 } else if (warning.msg == NOT_SUPPORT_TRADITIONAL_TIMELAPSE) {
8544 return _L("Enabling traditional timelapse photography may cause surface imperfections. It is recommended to change to smooth mode.");
8545 } else if (warning.msg == NOT_GENERATE_TIMELAPSE) {
8546 return wxString();
8547 } else if (warning.msg == SMOOTH_TIMELAPSE_WITHOUT_PRIME_TOWER) {
8548 return _L("Smooth mode for timelapse is enabled, but the prime tower is off, which may cause print defects. Please enable the prime tower, re-slice and print again.");
8549 }
8550 else {
8551 return wxString(warning.msg);
8552 }
8553}
#define SMOOTH_TIMELAPSE_WITHOUT_PRIME_TOWER
Definition GCodeProcessor.hpp:49
#define NOT_SUPPORT_TRADITIONAL_TIMELAPSE
Definition GCodeProcessor.hpp:47
#define BED_TEMP_TOO_HIGH_THAN_FILAMENT
Definition GCodeProcessor.hpp:46
#define NOT_GENERATE_TIMELAPSE
Definition GCodeProcessor.hpp:48
#define NOZZLE_HRC_CHECKER
Definition GCodeProcessor.hpp:45

References _L, BED_TEMP_TOO_HIGH_THAN_FILAMENT, Slic3r::GCodeProcessorResult::SliceWarning::msg, NOT_GENERATE_TIMELAPSE, NOT_SUPPORT_TRADITIONAL_TIMELAPSE, NOZZLE_HRC_CHECKER, and SMOOTH_TIMELAPSE_WITHOUT_PRIME_TOWER.

Referenced by Slic3r::GUI::SelectMachineDialog::on_ok_btn().

Here is the caller graph for this function:

◆ get_ui_job_worker() [1/2]

Worker & Slic3r::GUI::Plater::get_ui_job_worker ( )
19110{ return p->m_worker; }

References p.

Referenced by arrange(), fill_bed_with_copies(), fill_bed_with_instances(), import_sl1_archive(), optimize_rotation(), orient(), remove_selected(), reslice(), and set_selected_visible().

Here is the caller graph for this function:

◆ get_ui_job_worker() [2/2]

const Worker & Slic3r::GUI::Plater::get_ui_job_worker ( ) const
19112{ return p->m_worker; }

References p.

◆ get_uv_editor_canvas()

UVEditorCanvas * Slic3r::GUI::Plater::get_uv_editor_canvas ( )
22100{
22101 return p->uv_editor_canvas;
22102}

References p.

◆ get_view3D_canvas3D()

GLCanvas3D * Slic3r::GUI::Plater::get_view3D_canvas3D ( )
22083{
22084 return p ? p->view3D->get_canvas3d() : nullptr;
22085}

References p.

Referenced by config_change_notification(), reslice(), update_obj_preview_thumbnail(), and update_plate_thumbnails().

Here is the caller graph for this function:

◆ GetPlateIndexByRightMenuInLeftUI()

int Slic3r::GUI::Plater::GetPlateIndexByRightMenuInLeftUI ( )
24133{ return p->m_is_RightClickInLeftUI; }

References p.

◆ has_assmeble_view()

bool Slic3r::GUI::Plater::has_assmeble_view ( ) const
23946{ return p->has_assemble_view(); }

References p.

◆ has_illegal_filename_characters() [1/2]

bool Slic3r::GUI::Plater::has_illegal_filename_characters ( const std::string & name)
static
423{
424 const char* illegal_characters = "<>:/\\|?*\"";
425 for (size_t i = 0; i < std::strlen(illegal_characters); i++)
426 if (name.find_first_of(illegal_characters[i]) != std::string::npos)
427 return true;
428
429 return false;
430}

◆ has_illegal_filename_characters() [2/2]

bool Slic3r::GUI::Plater::has_illegal_filename_characters ( const wxString & name)
static
417{
418 std::string name = into_u8(wxs_name);
420}

References has_illegal_filename_characters(), and Slic3r::GUI::into_u8().

Referenced by export_gcode(), BitmapTextRenderer::GetValueFromEditorCtrl(), has_illegal_filename_characters(), and Slic3r::GUI::ObjectList::rename_item().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_toolpaths_to_export()

bool Slic3r::GUI::Plater::has_toolpaths_to_export ( ) const
20718{
20719 return p->preview->get_canvas3d()->has_toolpaths_to_export();
20720}

References p.

◆ import_model_id()

void Slic3r::GUI::Plater::import_model_id ( wxString download_info)
16360{
16361 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << __LINE__ << " download info: " << download_info;
16362
16363 wxString download_origin_url = download_info;
16364 wxString download_url;
16365 wxString filename;
16366 wxString separator = "&name=";
16367
16368 try
16369 {
16370 size_t namePos = download_info.Find(separator);
16371 if (namePos != wxString::npos) {
16372 download_url = download_info.Mid(0, namePos);
16373 filename = download_info.Mid(namePos + separator.Length());
16374
16375 }
16376 else {
16377 fs::path download_path = fs::path(download_origin_url.wx_str());
16378 download_url = download_origin_url;
16379 filename = download_path.filename().string();
16380 }
16381
16382 }
16383 catch (const std::exception&)
16384 {
16385 //wxString sError = error.what();
16386 }
16387
16388 // The name comes from the link: reduce it to a plain file name inside the download folder.
16389 filename = from_u8(sanitize_file_basename(into_u8(filename)));
16390 if (filename.empty())
16391 filename = "untitled.3mf";
16392
16393 bool download_ok = false;
16394 int retry_count = 0;
16395 const int max_retries = 3;
16396
16397 /* jump to 3D eidtor */
16398 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
16399
16400 /* prepare progress dialog */
16401 bool cont = true;
16402 bool cont_dlg = true;
16403 bool cancel = false;
16404 wxString msg;
16405 wxString dlg_title = _L("Importing Model");
16406
16407 int percent = 0;
16408 ProgressDialog dlg(dlg_title,
16409 wxString(' ', 100) + "\n\n\n\n",
16410 100, // range
16411 this, // parent
16412 wxPD_CAN_ABORT |
16413 wxPD_APP_MODAL |
16414 wxPD_AUTO_HIDE |
16415 wxPD_SMOOTH);
16416
16417 boost::filesystem::path target_path;
16418
16419 //reset params
16420 p->project.reset();
16421
16422 /* prepare project and profile */
16423 boost::thread import_thread = Slic3r::create_thread([&percent, &cont, &retry_count, &msg, &target_path, &download_ok, download_url, &filename] {
16424
16425 // Orca: NetworkAgent is not needed and only prevents this from running
16426// NetworkAgent* m_agent = Slic3r::GUI::wxGetApp().getAgent();
16427// if (!m_agent) return;
16428
16429 int res = 0;
16430 std::string http_body;
16431
16432 msg = _L("Preparing 3MF file...");
16433
16434 target_path = fs::path(wxGetApp().app_config->get("download_path"));
16435
16436 //check file suffix
16437 wxString extension = fs::path(filename.wx_str()).extension().c_str();
16438 if (!extension.Contains(".3mf")) {
16439 msg = _L("Download failed; unknown file format.");
16440 return;
16441 }
16442
16443 //never replace an existing file
16444 std::string unused_filename;
16445 try {
16446 if (!find_unused_filename(target_path, into_u8(filename), {}, unused_filename))
16447 unused_filename.clear();
16448 } catch (const std::exception&) {
16449 unused_filename.clear();
16450 }
16451 if (unused_filename.empty()) {
16452 msg = _L("Importing to Orca Slicer failed. Please download the file and manually import it.");
16453 return;
16454 }
16455 filename = from_u8(unused_filename);
16456
16457
16458 msg = _L("Downloading project...");
16459
16460 //target_path = wxStandardPaths::Get().GetTempDir().utf8_str().data();
16461
16462
16463 //target_path = wxGetApp().get_local_models_path().c_str();
16464 boost::uuids::uuid uuid = boost::uuids::random_generator()();
16465 std::string unique = to_string(uuid).substr(0, 6);
16466
16467 //target_path /= (boost::format("%1%_%2%.3mf") % filename % unique).str();
16468 target_path /= fs::path(filename.wc_str());
16469
16470 fs::path tmp_path = target_path;
16471 tmp_path += format(".%1%", ".download");
16472
16473 auto filesize = 0;
16474 bool size_limit = false;
16475 auto http = Http::get(download_url.ToStdString());
16476
16477 while (cont && retry_count < max_retries) {
16478 retry_count++;
16479 http.on_progress([&percent, &cont, &msg, &filesize, &size_limit](Http::Progress progress, bool& cancel) {
16480
16481 if (!cont) cancel = true;
16482 if (progress.dltotal != 0) {
16483
16484 if (filesize == 0) {
16485 filesize = progress.dltotal;
16486 double megabytes = static_cast<double>(progress.dltotal) / (1024 * 1024);
16487 //The maximum size of a 3mf file is 500mb
16488 if (megabytes > 500) {
16489 cont = false;
16490 size_limit = true;
16491 }
16492 }
16493 percent = progress.dlnow * 100 / progress.dltotal;
16494 }
16495
16496 if (size_limit) {
16497 msg = _L("Download failed; File size exception.");
16498 }
16499 else {
16500 msg = wxString::Format(_L("Project downloaded %d%%"), percent);
16501 }
16502 })
16503 .on_error([&msg, &cont, &retry_count](std::string body, std::string error, unsigned http_status) {
16504 (void)body;
16505 BOOST_LOG_TRIVIAL(error) << format("Error getting: `%1%`: HTTP %2%, %3%",
16506 body,
16507 http_status,
16508 error);
16509
16510 if (retry_count == max_retries) {
16511 msg = _L("Importing to Orca Slicer failed. Please download the file and manually import it.");
16512 cont = false;
16513 }
16514 })
16515 .on_complete([&cont, &download_ok, &msg, tmp_path, &target_path](std::string body, unsigned /* http_status */) {
16516 fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc);
16517 file.write(body.c_str(), body.size());
16518 file.close();
16519 cont = false;
16520 try {
16521 // Another file may have taken the name while downloading.
16522 std::string unused_filename;
16523 if (find_unused_filename(target_path.parent_path(), target_path.filename().string(), {}, unused_filename)) {
16524 target_path = target_path.parent_path() / unused_filename;
16525 fs::rename(tmp_path, target_path);
16526 download_ok = true;
16527 return;
16528 }
16529 } catch (const std::exception &e) {
16530 BOOST_LOG_TRIVIAL(error) << "import_model_id: failed to move the download into place: " << e.what();
16531 }
16532 boost::system::error_code ec;
16533 fs::remove(tmp_path, ec);
16534 msg = _L("Importing to Orca Slicer failed. Please download the file and manually import it.");
16535 }).perform_sync();
16536
16537 // for break while
16538 //cont = false;
16539 }
16540
16541 });
16542
16543 while (cont && cont_dlg) {
16544 wxMilliSleep(50);
16545 cont_dlg = dlg.Update(percent, msg);
16546 if (!cont_dlg) {
16547 cont = cont_dlg;
16548 cancel = true;
16549 }
16550
16551 if (download_ok)
16552 break;
16553 }
16554
16555 if (import_thread.joinable())
16556 import_thread.join();
16557
16558 dlg.Hide();
16559
16560#ifdef _WIN32
16561 dlg.Close();
16562#endif
16563
16564 if (download_ok) {
16565 BOOST_LOG_TRIVIAL(trace) << "import_model_id: target_path = " << target_path.string();
16566 /* load project */
16567 // Orca: If download is a zip file, treat it as if file has been drag and dropped on the plater
16568 if (target_path.extension() == ".zip")
16569 { wxArrayString arr; arr.Add(from_path(target_path)); this->load_files(arr); }
16570 else
16571 this->load_project(from_path(target_path));
16572 /*BBS set project info after load project, project info is reset in load project */
16573 //p->project.project_model_id = model_id;
16574 //p->project.project_design_id = design_id;
16575 AppConfig* config = wxGetApp().app_config;
16576 if (config) {
16577 p->project.project_country_code = config->get_country_code();
16578 }
16579
16580 // show save new project
16581 p->set_project_filename(target_path.wstring());
16582 p->notification_manager->push_import_finished_notification(target_path.string(), target_path.parent_path().string(), false);
16583 }
16584 else {
16585 if (!msg.empty()) {
16586 MessageDialog msg_wingow(nullptr, msg, wxEmptyString, wxICON_WARNING | wxOK);
16587 msg_wingow.SetSize(wxSize(FromDIP(480), -1));
16588 msg_wingow.ShowModal();
16589 }
16590 return;
16591 }
16592}
void load_project(wxString const &filename="", wxString const &originfile="-")
Definition Plater.cpp:16144
static Http get(std::string url)
Definition Http.cpp:886
static std::string to_string(libvgcode::EMoveType type)
Definition GCodeViewer.cpp:377
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:36
bool find_unused_filename(const boost::filesystem::path &dest_folder, const std::string &filename, const boost::filesystem::path &ignored_marker, std::string &result)
Definition utils.cpp:1494
boost::thread create_thread(boost::thread::attributes &attrs, Fn &&fn)
Definition Thread.hpp:48
std::string sanitize_file_basename(const std::string &name)
Definition Utils.hpp:326
@ http
Definition IPrinterAgent.hpp:64

References _L, config(), Slic3r::create_thread(), Slic3r::Http::Progress::dlnow, Slic3r::Http::Progress::dltotal, Slic3r::find_unused_filename(), Slic3r::GUI::format(), Slic3r::GUI::from_path(), Slic3r::GUI::from_u8(), Slic3r::Http::get(), Slic3r::http, Slic3r::GUI::into_u8(), load_files(), load_project(), p, Slic3r::sanitize_file_basename(), Slic3r::GUI::DPIAware< P >::ShowModal(), TAB_ID_PREPARE, Slic3r::GUI::to_string(), Slic3r::trace(), and Slic3r::GUI::ProgressDialog::Update().

Here is the call graph for this function:

◆ import_sl1_archive()

void Slic3r::GUI::Plater::import_sl1_archive ( )
18122{
18123 auto &w = get_ui_job_worker();
18124 if (w.is_idle() && p->m_sla_import_dlg->ShowModal() == wxID_OK) {
18125 p->take_snapshot(_u8L("Import SLA archive"));
18126 replace_job(w, std::make_unique<SLAImportJob>(p->m_sla_import_dlg));
18127 }
18128}

References _u8L, get_ui_job_worker(), p, and Slic3r::GUI::replace_job().

Here is the call graph for this function:

◆ import_zip_archive()

void Slic3r::GUI::Plater::import_zip_archive ( )
18110{
18111 wxString input_file;
18112 wxGetApp().import_zip(this, input_file);
18113 if (input_file.empty())
18114 return;
18115
18116 wxArrayString arr;
18117 arr.Add(input_file);
18118 load_files(arr);
18119}

References load_files().

Here is the call graph for this function:

◆ increase_instances()

void Slic3r::GUI::Plater::increase_instances ( size_t num = 1)
19287{
19288 if (! can_increase_instances()) { return; }
19289
19290 Plater::TakeSnapshot snapshot(this, "Increase Instances");
19291
19292 int obj_idx = p->get_selected_object_idx();
19293
19294 ModelObject* model_object = p->model.objects[obj_idx];
19295 ModelInstance* model_instance = model_object->instances.back();
19296
19297 bool was_one_instance = model_object->instances.size()==1;
19298
19299 double offset_base = canvas3D()->get_size_proportional_to_max_bed_size(0.05);
19300 double offset = offset_base;
19301 for (size_t i = 0; i < num; i++, offset += offset_base) {
19302 Vec3d offset_vec = model_instance->get_offset() + Vec3d(offset, offset, 0.0);
19303 model_object->add_instance(offset_vec, model_instance->get_scaling_factor(), model_instance->get_rotation(), model_instance->get_mirror());
19304// p->print.get_object(obj_idx)->add_copy(Slic3r::to_2d(offset_vec));
19305 }
19306 // Register the copies with the plate they land on before the scene reloads: the plate's
19307 // filament list and wipe tower preview are read from that registry.
19308 for (size_t i = model_object->instances.size() - num; i < model_object->instances.size(); ++i)
19309 p->partplate_list.notify_instance_update(obj_idx, static_cast<int>(i));
19310
19311#ifdef SUPPORT_AUTO_CENTER
19312 if (p->get_config("autocenter") == "true")
19313 arrange();
19314#endif
19315
19316 p->update();
19317
19318 p->get_selection().add_instance(obj_idx, (int)model_object->instances.size() - 1);
19319
19320 sidebar().obj_list()->increase_object_instances(obj_idx, was_one_instance ? num + 1 : num);
19321
19322 p->selection_changed();
19323 this->p->schedule_background_process();
19324 //if (wxGetApp().app_config->get("auto_arrange") == "true") {
19325 // this->set_prepare_state(Job::PREPARE_STATE_MENU);
19326 // this->arrange();
19327 //}
19328}
double get_size_proportional_to_max_bed_size(double factor) const
Definition GLCanvas3D.cpp:6187
void increase_object_instances(const size_t obj_idx, const size_t num)
Definition GUI_ObjectList.cpp:4493
bool can_increase_instances() const
Definition Plater.cpp:23884
void arrange()
Definition Plater.cpp:22131
GLCanvas3D * canvas3D()
Definition Plater.cpp:22070
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:582

References Slic3r::ModelObject::add_instance(), arrange(), can_increase_instances(), canvas3D(), Slic3r::ModelInstance::get_mirror(), Slic3r::ModelInstance::get_offset(), Slic3r::ModelInstance::get_rotation(), Slic3r::ModelInstance::get_scaling_factor(), Slic3r::GUI::GLCanvas3D::get_size_proportional_to_max_bed_size(), Slic3r::GUI::ObjectList::increase_object_instances(), Slic3r::ModelObject::instances, Slic3r::GUI::Sidebar::obj_list(), Slic3r::offset(), p, and sidebar().

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), and set_number_of_copies().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_collapse_toolbar()

bool Slic3r::GUI::Plater::init_collapse_toolbar ( )
22563{
22564 return p->init_collapse_toolbar();
22565}

References p.

◆ init_notification_manager()

void Slic3r::GUI::Plater::init_notification_manager ( )
23870{
23871 p->init_notification_manager();
23872}

References p.

◆ inside_snapshot_capture()

bool Slic3r::GUI::Plater::inside_snapshot_capture ( )
23959{ return p->inside_snapshot_capture(); }

References p.

◆ install_missing_cloud_plugins()

void Slic3r::GUI::Plater::install_missing_cloud_plugins ( const std::vector< std::string > & cloud_refs)
23027{
23028 if (cloud_refs.empty())
23029 return;
23030
23031 // Shared between the UI-thread dialog/timer and the resolver's worker thread.
23032 struct InstallProgressState
23033 {
23034 std::atomic<bool> cancel{false};
23035 std::atomic<bool> finished{false};
23036 std::atomic<bool> torn_down{false};
23037 std::mutex mtx;
23038 std::string message;
23039 };
23040 auto state = std::make_shared<InstallProgressState>();
23041 state->message = _u8L("Preparing to install plugins...");
23042
23043 wxWindow* parent = wxGetApp().mainframe;
23044 auto* dialog = new wxProgressDialog(_L("Installing plugins"), from_u8(state->message), 100,
23045 parent, wxPD_APP_MODAL | wxPD_CAN_ABORT);
23046 dialog->Pulse();
23047
23048 // UI-thread timer: animate the pulse, observe the Cancel button, and tear down when the worker
23049 // signals completion. The timer is deleted via CallAfter so it is never freed inside its own
23050 // handler.
23051 auto* timer = new wxTimer();
23052 timer->Bind(wxEVT_TIMER, [this, dialog, timer, state](wxTimerEvent&) {
23053 std::string msg;
23054 {
23055 std::lock_guard<std::mutex> lock(state->mtx);
23056 msg = state->message;
23057 }
23058 // Once cancellation is requested, the in-flight plugin still has to finish; reflect that.
23059 if (state->cancel)
23060 msg = _u8L("Cancelling — finishing the current plugin...");
23061
23062 if (!dialog->Pulse(from_u8(msg)))
23063 state->cancel = true;
23064
23065 // Tear down exactly once: Stop() prevents further ticks, but guard so a stale queued tick
23066 // can never double-Destroy the dialog or double-delete the timer.
23067 if (state->finished && !state->torn_down.exchange(true)) {
23068 timer->Stop();
23069 dialog->Destroy();
23070 wxGetApp().CallAfter([timer]() { delete timer; });
23072 }
23073 });
23074 timer->Start(100);
23075
23076 PluginInstallProgress progress;
23077 progress.on_plugin_begin = [state](const std::string& name, std::size_t /*index*/, std::size_t /*total*/) {
23078 std::lock_guard<std::mutex> lock(state->mtx);
23079 state->message = (boost::format(_u8L("Installing %1%...")) % name).str();
23080 };
23081 progress.is_cancelled = [state]() { return state->cancel.load(); };
23082 progress.on_finished = [state]() { state->finished = true; };
23083
23084 resolve_missing_plugins(cloud_refs, std::move(progress));
23085}
void revalidate_current_plate_if_plugins_missing()
Definition Plater.cpp:23015
void resolve_missing_plugins(const std::vector< std::string > &refs, PluginInstallProgress progress)
Definition PluginResolver.cpp:392
@ lock
Definition GLGizmoEmboss.cpp:209

References _L, _u8L, Slic3r::GUI::from_u8(), Slic3r::PluginInstallProgress::is_cancelled, Slic3r::PluginInstallProgress::on_finished, Slic3r::PluginInstallProgress::on_plugin_begin, Slic3r::resolve_missing_plugins(), and revalidate_current_plate_if_plugins_missing().

Referenced by refresh_missing_plugin_block().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ instance_menu()

wxMenu * Slic3r::GUI::Plater::instance_menu ( )
24129{ return p->menus.instance_menu(); }

References p.

◆ invalid_all_plate_thumbnails()

void Slic3r::GUI::Plater::invalid_all_plate_thumbnails ( )
18381{
18383 return;
18384 BOOST_LOG_TRIVIAL(info) << "thumb: invalid all";
18385 for (int i = 0; i < get_partplate_list().get_plate_count(); i++) {
18386 PartPlate* plate = get_partplate_list().get_plate(i);
18387 plate->thumbnail_data.reset();
18388 plate->no_light_thumbnail_data.reset();
18389 }
18391}
int get_plate_count() const
Definition PartPlate.cpp:7042
ThumbnailData thumbnail_data
Definition PartPlate.hpp:425
void mark_plate_toolbar_image_dirty()
Definition Plater.cpp:437
void reset()
Definition ThumbnailData.cpp:78

References get_partplate_list(), Slic3r::GUI::PartPlateList::get_plate(), Slic3r::GUI::PartPlateList::get_plate_count(), mark_plate_toolbar_image_dirty(), Slic3r::GUI::PartPlate::no_light_thumbnail_data, Slic3r::ThumbnailData::reset(), skip_thumbnail_invalid, Slic3r::GUI::PartPlate::thumbnail_data, and using_exported_file().

Referenced by force_update_all_plate_thumbnails().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_background_process_slicing()

bool Slic3r::GUI::Plater::is_background_process_slicing ( ) const
23584{
23585 return p->m_is_slicing;
23586}

References p.

Referenced by can_add_model(), and can_add_plate().

Here is the caller graph for this function:

◆ is_background_process_update_scheduled()

bool Slic3r::GUI::Plater::is_background_process_update_scheduled ( ) const
22318{
22319 return this->p->background_process_timer.IsRunning();
22320}

References p.

◆ is_empty_project()

bool Slic3r::GUI::Plater::is_empty_project ( )
20735 {
20736 return model().objects.empty();
20737}

References model(), and Slic3r::Model::objects.

Here is the call graph for this function:

◆ is_export_gcode_scheduled()

bool Slic3r::GUI::Plater::is_export_gcode_scheduled ( ) const
22051{
22052 return p->background_process.is_export_scheduled();
22053}

References p.

◆ is_gcode_3mf()

bool Slic3r::GUI::Plater::is_gcode_3mf ( )
inline
418{ return m_exported_file; }
bool m_exported_file
Definition Plater.hpp:1097

References m_exported_file.

Referenced by normalize_bed_types().

Here is the caller graph for this function:

◆ is_loading_project()

bool Slic3r::GUI::Plater::is_loading_project ( ) const
inline
1074{ return m_loading_project; }
bool m_loading_project
Definition Plater.hpp:1099

References m_loading_project.

Referenced by changed_object(), and changed_objects().

Here is the caller graph for this function:

◆ is_multi_extruder_ams_empty()

bool Slic3r::GUI::Plater::is_multi_extruder_ams_empty ( )
20739{
20740 std::vector<std::string> extruder_ams_count_str = p->config->option<ConfigOptionStrings>("extruder_ams_count", true)->values;
20741 std::vector<std::map<int, int>> extruder_ams_counts = get_extruder_ams_count(extruder_ams_count_str);
20742 for (auto extruder_ams_count : extruder_ams_counts) {
20743 for (auto iter = extruder_ams_count.begin(); iter != extruder_ams_count.end(); ++iter) {
20744 if (iter->second != 0)
20745 return false;
20746 }
20747 }
20748 return true;
20749}
std::vector< std::map< int, int > > get_extruder_ams_count(const std::vector< std::string > &strs)
Definition PrintConfig.cpp:869

References Slic3r::get_extruder_ams_count(), and p.

Here is the call graph for this function:

◆ is_new_project_and_check_state()

bool Slic3r::GUI::Plater::is_new_project_and_check_state ( )
inline
bool m_new_project_and_check_state
Definition Plater.hpp:1100

References m_new_project_and_check_state.

Referenced by update().

Here is the caller graph for this function:

◆ is_plate_toolbar_image_dirty()

bool Slic3r::GUI::Plater::is_plate_toolbar_image_dirty ( ) const

◆ is_presets_dirty()

bool Slic3r::GUI::Plater::is_presets_dirty ( ) const
15662{ return p->is_presets_dirty(); }

References p.

◆ is_preview_loaded()

bool Slic3r::GUI::Plater::is_preview_loaded ( ) const
19126{ return p->is_preview_loaded(); }

References p.

Referenced by export_toolpaths_to_obj().

Here is the caller graph for this function:

◆ is_preview_shown()

bool Slic3r::GUI::Plater::is_preview_shown ( ) const
19125{ return p->is_preview_shown(); }

References p.

Referenced by Slic3r::GUI::Plater::priv::schedule_auto_reslice_if_needed(), search(), select_plate(), Slic3r::GUI::Plater::priv::trigger_auto_reslice_now(), and Slic3r::GUI::Plater::priv::update().

Here is the caller graph for this function:

◆ is_project_dirty()

bool Slic3r::GUI::Plater::is_project_dirty ( ) const
15661{ return p->is_project_dirty(); }

References p.

Referenced by Slic3r::GUI::Plater::priv::update_title_dirty_status().

Here is the caller graph for this function:

◆ is_render_statistic_dialog_visible()

bool Slic3r::GUI::Plater::is_render_statistic_dialog_visible ( ) const
23967{
23968 return p->show_render_statistic_dialog;
23969}

References p.

◆ is_same_printer_for_connected_and_selected()

bool Slic3r::GUI::Plater::is_same_printer_for_connected_and_selected ( bool popup_warning = true)
22383{
22384 if (!wxGetApp().getDeviceManager()) {
22385 return false;
22386 }
22387 MachineObject *obj = wxGetApp().getDeviceManager()->get_selected_machine();
22388 if (obj == nullptr) {
22389 return false;
22390 }
22391 if (!check_printer_initialized(obj, true, popup_warning))
22392 return false;
22393 const std::string machine_model = obj->printer_type;
22394 PresetBundle *preset_bundle = wxGetApp().preset_bundle;
22395 const std::string selected_model = preset_bundle ? preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle) : std::string();
22398 !get_printer_preset(obj)) {
22399 return false;
22400 }
22401
22402 if (wxGetApp().is_blocking_printing()) {
22403 if (popup_warning) {
22404 auto printer_name = get_selected_printer_name_in_combox(); // wxString(obj->get_preset_printer_model_name(machine_print_name))
22405 pop_warning_and_go_to_device_page(printer_name, PrinterWarningType::INCONSISTENT, _L("Synchronize AMS Filament Information"));
22406 }
22407 return false;
22408 }
22409 return true;
22410}
static bool is_optional_printer_model_id(const std::string &model_id)
Definition DevConfigUtil.h:69
bool check_printer_initialized(MachineObject *obj, bool only_warning=false, bool popup_warning=true)
Definition Plater.cpp:19940
@ INCONSISTENT
Definition Plater.hpp:691
Preset * get_printer_preset(const MachineObject *obj)
Definition Plater.cpp:19913

References _L, check_printer_initialized(), Slic3r::PresetCollection::get_edited_preset(), Slic3r::GUI::get_printer_preset(), Slic3r::Preset::get_printer_type(), get_selected_printer_name_in_combox(), INCONSISTENT, Slic3r::DevPrinterConfigUtil::is_optional_printer_model_id(), pop_warning_and_go_to_device_page(), Slic3r::MachineObject::printer_type, and Slic3r::PresetBundle::printers.

Here is the call graph for this function:

◆ is_selection_empty()

bool Slic3r::GUI::Plater::is_selection_empty ( ) const
19424{
19425 return p->get_selection().is_empty() || p->get_selection().is_wipe_tower();
19426}

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), can_copy_to_clipboard(), can_cut_to_clipboard(), and clone_selection().

Here is the caller graph for this function:

◆ is_show_wireframe()

bool Slic3r::GUI::Plater::is_show_wireframe ( ) const
23977{
23978 return p->show_wireframe;
23979}

References p.

Referenced by Slic3r::GUI::GLCanvas3D::_render_canvas_toolbar().

Here is the caller graph for this function:

◆ is_show_xray()

bool Slic3r::GUI::Plater::is_show_xray ( ) const
23997{
23998 return p->show_xray;
23999}

References p.

Referenced by Slic3r::GUI::GLCanvas3D::_render_canvas_toolbar().

Here is the caller graph for this function:

◆ is_sidebar_collapsed()

bool Slic3r::GUI::Plater::is_sidebar_collapsed ( ) const
19150{ return p->sidebar_layout.is_collapsed; }

References p.

Referenced by Slic3r::GUI::Plater::priv::init_collapse_toolbar().

Here is the caller graph for this function:

◆ is_sidebar_enabled()

bool Slic3r::GUI::Plater::is_sidebar_enabled ( ) const
19148{ return p->sidebar_layout.is_enabled; }

References p.

◆ is_single_full_object_selection()

bool Slic3r::GUI::Plater::is_single_full_object_selection ( ) const
22066{
22067 return p->get_selection().is_single_full_object();
22068}

References p.

◆ is_view3D_overhang_shown()

bool Slic3r::GUI::Plater::is_view3D_overhang_shown ( ) const
19145{ return p->is_view3D_overhang_shown(); }

References p.

Referenced by Slic3r::GUI::GLCanvas3D::_render_canvas_toolbar().

Here is the caller graph for this function:

◆ is_view3D_shown()

bool Slic3r::GUI::Plater::is_view3D_shown ( ) const
19127{ return p->is_view3D_shown(); }

References p.

Referenced by select_plate().

Here is the caller graph for this function:

◆ is_wireframe_enabled()

bool Slic3r::GUI::Plater::is_wireframe_enabled ( ) const
23987{
23988 return p->wireframe_enabled;
23989}

References p.

◆ last_arrange_job_is_finished()

bool Slic3r::GUI::Plater::last_arrange_job_is_finished ( )
inline
1067 {
1068 bool prevRunning = false;
1069 return m_arrange_running.compare_exchange_strong(prevRunning, true);
1070 };
std::atomic< bool > m_arrange_running
Definition Plater.hpp:1071

References m_arrange_running.

Referenced by select_plate_by_hover_id().

Here is the caller graph for this function:

◆ layer_menu()

wxMenu * Slic3r::GUI::Plater::layer_menu ( )
24130{ return p->menus.layer_menu(); }

References p.

◆ leave_gizmos_stack()

bool Slic3r::GUI::Plater::leave_gizmos_stack ( )
23958{ return p->leave_gizmos_stack(); } // BBS: return false if not changed

References p.

◆ load_files() [1/2]

std::vector< size_t > Slic3r::GUI::Plater::load_files ( const std::vector< boost::filesystem::path > & input_files,
LoadStrategy strategy = LoadStrategy::LoadModel|LoadStrategy::LoadConfig,
bool ask_multi = false,
bool * published_out = nullptr )

References Slic3r::LoadConfig, and Slic3r::LoadModel.

Referenced by add_file(), add_model(), extract_config_from_project(), import_model_id(), import_zip_archive(), load_files(), Slic3r::GUI::MenuFactory::load_handy_model(), load_project(), open_3mf_file(), Slic3r::GUI::GUI_App::post_init(), and preview_zip_archive().

Here is the caller graph for this function:

◆ load_files() [2/2]

bool Slic3r::GUI::Plater::load_files ( const wxArrayString & filenames)
18750{
18751 const std::regex pattern_drop(".*[.](stp|step|stl|oltp|obj|amf|3mf|svg|zip|drc|glb|gltf|fbx)", std::regex::icase);
18752 const std::regex pattern_gcode_drop(".*[.](gcode|g)", std::regex::icase);
18753
18754 std::vector<fs::path> normal_paths;
18755 std::vector<fs::path> gcode_paths;
18756
18757 for (const auto& filename : filenames) {
18758 fs::path path(into_path(filename));
18759 if (std::regex_match(path.string(), pattern_drop))
18760 normal_paths.push_back(std::move(path));
18761 else if (std::regex_match(path.string(), pattern_gcode_drop))
18762 gcode_paths.push_back(std::move(path));
18763 else
18764 continue;
18765 }
18766
18767 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": normal_paths %1%, gcode_paths %2%")%normal_paths.size() %gcode_paths.size();
18768 if (normal_paths.empty() && gcode_paths.empty()) {
18769 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": can not find valid path, return directly");
18770 // Likely no supported files
18771 return false;
18772 }
18773 else if (normal_paths.empty()){
18774 //only gcode files
18775 if (gcode_paths.size() > 1) {
18776 show_info(this, _L("Only one G-code file can be opened at a time."), _L("G-code loading"));
18777 return false;
18778 }
18779 load_gcode(from_path(gcode_paths.front()));
18780 return true;
18781 }
18782
18783 if (!gcode_paths.empty()) {
18784 show_info(this, _L("G-code files and models cannot be loaded together!"), _L("G-code loading"));
18785 return false;
18786 }
18787
18789 //for (std::vector<fs::path>::const_reverse_iterator it = normal_paths.rbegin(); it != normal_paths.rend(); ++it) {
18790 // std::string filename = (*it).filename().string();
18791 // ////BBS: only 3mf will be treated as project file
18792 // if (open_3mf_file((*it)))
18793 // return true;
18794 //}
18795
18797 std::string snapshot_label;
18798 assert(!normal_paths.empty());
18799 if (normal_paths.size() == 1) {
18800 snapshot_label = "Load File";
18801 snapshot_label += ": ";
18802 snapshot_label += encode_path(normal_paths.front().filename().string().c_str());
18803 } else {
18804 snapshot_label = "Load Files";
18805 snapshot_label += ": ";
18806 snapshot_label += encode_path(normal_paths.front().filename().string().c_str());
18807 for (size_t i = 1; i < normal_paths.size(); ++i) {
18808 snapshot_label += ", ";
18809 snapshot_label += encode_path(normal_paths[i].filename().string().c_str());
18810 }
18811 }
18812
18813 //Plater::TakeSnapshot snapshot(this, snapshot_label);
18814 //load_files(normal_paths, LoadStrategy::LoadModel);
18815
18816 // BBS: check file types
18817 std::sort(normal_paths.begin(), normal_paths.end(), [](fs::path obj1, fs::path obj2) { return obj1.filename().string() < obj2.filename().string(); });
18818
18819 auto loadfiles_type = LoadFilesType::NoFile;
18820 auto amf_files_count = get_3mf_file_count(normal_paths);
18821
18822 if (normal_paths.size() > 1 && amf_files_count < normal_paths.size()) { loadfiles_type = LoadFilesType::Multiple3MFOther; }
18823 if (normal_paths.size() > 1 && amf_files_count == normal_paths.size()) { loadfiles_type = LoadFilesType::Multiple3MF; }
18824 if (normal_paths.size() > 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::MultipleOther; }
18825 if (normal_paths.size() == 1 && amf_files_count == 1) { loadfiles_type = LoadFilesType::Single3MF; };
18826 if (normal_paths.size() == 1 && amf_files_count == 0) { loadfiles_type = LoadFilesType::SingleOther; };
18827
18828 auto first_file = std::vector<fs::path>{};
18829 auto tmf_file = std::vector<fs::path>{};
18830 auto other_file = std::vector<fs::path>{};
18831 auto res = true;
18832
18833 if (this->m_only_gcode || this->m_exported_file) {
18834 if ((loadfiles_type == LoadFilesType::SingleOther)
18835 || (loadfiles_type == LoadFilesType::MultipleOther)) {
18836 show_info(this, _L("Unable to add models in preview mode"), _L("Add Models"));
18837 return false;
18838 }
18839 }
18840
18841 // Orca: Iters through given paths and imports files from zip then remove zip from paths
18842 // returns true if zip files were found
18843 auto handle_zips = [this](std::vector<fs::path>& paths) { // NOLINT(*-no-recursion) - Recursion is intended and should be managed properly
18844 bool res = false;
18845 for (auto it = paths.begin(); it != paths.end();) {
18846 if (boost::algorithm::iends_with(it->string(), ".zip")) {
18847 res = true;
18849 it = paths.erase(it);
18850 } else
18851 it++;
18852 }
18853 return res;
18854 };
18855
18856 switch (loadfiles_type) {
18858 open_3mf_file(normal_paths[0]);
18859 break;
18860
18862 Plater::TakeSnapshot snapshot(this, snapshot_label);
18863 if (handle_zips(normal_paths)) return true;
18864 if (load_files(normal_paths, LoadStrategy::LoadModel, false).empty()) { res = false; }
18865 break;
18866 }
18868 first_file = std::vector<fs::path>{normal_paths[0]};
18869 for (auto i = 0; i < normal_paths.size(); i++) {
18870 if (i > 0) { other_file.push_back(normal_paths[i]); }
18871 };
18872
18873 open_3mf_file(first_file[0]);
18874 if (load_files(other_file, LoadStrategy::LoadModel).empty()) { res = false; }
18875 break;
18876
18878 Plater::TakeSnapshot snapshot(this, snapshot_label);
18879 if (handle_zips(normal_paths)) {
18880 if (normal_paths.empty()) return true;
18881 }
18882 if (load_files(normal_paths, LoadStrategy::LoadModel, true).empty()) { res = false; }
18883 break;
18884 }
18885
18887 for (const auto &path : normal_paths) {
18888 if (boost::iends_with(path.filename().string(), ".3mf")){
18889 if (first_file.size() <= 0)
18890 first_file.push_back(path);
18891 else
18892 tmf_file.push_back(path);
18893 } else {
18894 other_file.push_back(path);
18895 }
18896 }
18897
18898 open_3mf_file(first_file[0]);
18899 if (load_files(tmf_file, LoadStrategy::LoadModel).empty()) { res = false; }
18900 if (res && handle_zips(other_file)) {
18901 if (normal_paths.empty()) return true;
18902 }
18903 if (load_files(other_file, LoadStrategy::LoadModel, false).empty()) { res = false; }
18904 break;
18905 default: break;
18906 }
18907
18908 return res;
18909}
bool preview_zip_archive(const boost::filesystem::path &archive_path)
Definition Plater.cpp:18416
void load_gcode()
Definition Plater.cpp:18139
void show_info(wxWindow *parent, const wxString &message, const wxString &title)
Definition GUI.cpp:316

References _L, Slic3r::empty(), Slic3r::encode_path(), Slic3r::GUI::from_path(), get_3mf_file_count(), Slic3r::GUI::into_path(), load_files(), load_gcode(), Slic3r::LoadModel, m_exported_file, m_only_gcode, Slic3r::GUI::Multiple3MF, Slic3r::GUI::Multiple3MFOther, Slic3r::GUI::MultipleOther, Slic3r::GUI::NoFile, open_3mf_file(), preview_zip_archive(), Slic3r::GUI::show_info(), Slic3r::GUI::Single3MF, and Slic3r::GUI::SingleOther.

Here is the call graph for this function:

◆ load_gcode() [1/2]

void Slic3r::GUI::Plater::load_gcode ( )
18140{
18141 // Ask user for a gcode file name.
18142 wxString input_file;
18143 wxGetApp().load_gcode(this, input_file);
18144 // And finally load the gcode file.
18145 load_gcode(input_file);
18146}

References load_gcode().

Referenced by load_files(), load_gcode(), Slic3r::GUI::GUI_App::post_init(), and reload_gcode_from_disk().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_gcode() [2/2]

void Slic3r::GUI::Plater::load_gcode ( const wxString & filename)
18150{
18151 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << __LINE__ << " entry and filename: " << filename;
18152 BOOST_LOG_TRIVIAL(info) << __FUNCTION__;
18153 if (! is_gcode_file(into_u8(filename))
18154 || (m_last_loaded_gcode == filename && m_only_gcode)
18155 )
18156 return;
18157
18158 m_last_loaded_gcode = filename;
18159
18160 // An OrcaSlicer G-code carries the settings it was sliced with. They replace the selected presets as a
18161 // .gcode.3mf's do, so unsaved preset changes get the save-or-discard choice of opening a project rather
18162 // than the new project's choice to keep them.
18163 PresetBundle* preset_bundle = wxGetApp().preset_bundle;
18164 const std::string path = into_u8(filename);
18165 std::optional<DynamicPrintConfig> file_config;
18166 ConfigSubstitutions substitutions;
18167 {
18168 wxBusyCursor wait;
18169 try {
18170 file_config = preset_bundle->config_from_gcode(path, ForwardCompatibilitySubstitutionRule::Enable, substitutions);
18171 } catch (const std::exception& ex) {
18172 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": no settings to load from " << path << ": " << ex.what();
18173 }
18174 }
18175
18176 // BSS: create a new project when load_gcode, force close previous one
18177 if (file_config) {
18178 auto check = [](bool yes_or_no) {
18179 return yes_or_no || wxGetApp().check_and_save_current_preset_changes(_L("Load project"), _L("Some presets are modified."));
18180 };
18181 if (close_with_confirm(check) == wxID_CANCEL || new_project(true, true) != wxID_YES)
18182 return;
18183 } else if (new_project(false, true) != wxID_YES)
18184 return;
18185
18186 m_only_gcode = true;
18188 // A previewed G-code's settings are not the selection the app should remember.
18189 PresetBundle::SelectionExportBlocker no_selection_export(*preset_bundle);
18190 // What loading the file's settings replaces, to put back if that load fails or the file is rejected.
18191 std::optional<PresetBundle::Selection> previous;
18192 if (file_config) {
18193 previous = preset_bundle->selection();
18194 if (!previous)
18195 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": project presets are still loaded, not loading the settings of " << path;
18196 }
18197 auto unload_file_settings = [this, preset_bundle, &previous]() {
18198 if (!previous)
18199 return;
18200 preset_bundle->restore_selection(*previous);
18201 wxGetApp().load_current_presets(false, false);
18202 // Switching back to the previous printer re-derives some project settings (TabPrinter::on_preset_loaded),
18203 // and only the printer refresh shows them in the sidebar's flow selectors.
18204 preset_bundle->project_config = std::move(previous->project_config);
18209 // The rejections after the switch to the preview have already shown the sidebar with the file's settings.
18210 enable_sidebar(false);
18211 previous.reset();
18212 };
18213 if (previous) {
18214 try {
18215 preset_bundle->load_config_model(path, std::move(*file_config));
18217 } catch (const std::exception& ex) {
18218 unload_file_settings();
18221 GUI::format(_L("Failed loading file \"%1%\". An invalid configuration was found."), path) +
18222 "\n" + ex.what());
18223 }
18224 }
18226 wxGetApp().load_current_presets(false, false);
18227 sync_loaded_project_filament_config(preset_bundle->project_config);
18231 if (!substitutions.empty())
18232 show_substitutions_info(substitutions, path);
18233 }
18234
18235 // cleanup view before to start loading/processing
18236 //BBS: update gcode to current partplate's
18237 GCodeProcessorResult* current_result = p->partplate_list.get_current_slice_result();
18238 Print& current_print = p->partplate_list.get_current_fff_print();
18239 //BBS:already reset in new_project
18240 //current_result->reset();
18241 //p->gcode_result.reset();
18242 //reset_gcode_toolpaths();
18243 p->preview->reload_print(m_only_gcode);
18244 wxGetApp().mainframe->select_tab(TAB_ID_PREVIEW);
18245 p->set_current_panel(p->preview, true);
18246 p->get_current_canvas3D()->render();
18247 //p->notification_manager->bbl_show_plateinfo_notification(into_u8(_L("Preview only mode for gcode file.")));
18248
18249 wxBusyCursor wait;
18250
18251 // process gcode
18252 GCodeProcessor processor;
18253 processor.init_filament_maps_and_nozzle_type_when_import_only_gcode();
18254 try
18255 {
18256 GCodeProcessor::s_IsBBLPrinter = wxGetApp().preset_bundle->is_bbl_vendor();
18257 processor.process_file(filename.ToUTF8().data());
18258 }
18259 catch (const std::exception& ex)
18260 {
18261 unload_file_settings();
18262 show_error(this, ex.what());
18263 return;
18264 }
18265 *current_result = std::move(processor.extract_result());
18266 //current_result->filename = filename;
18267
18268 BedType bed_type = current_result->bed_type;
18269 if (bed_type != BedType::btCount) {
18270 DynamicPrintConfig &proj_config = wxGetApp().preset_bundle->project_config;
18271 proj_config.set_key_value("curr_bed_type", new ConfigOptionEnum<BedType>(bed_type));
18272 on_bed_type_change(bed_type);
18273 }
18274
18275 current_print.apply(this->model(), wxGetApp().preset_bundle->full_config());
18276
18277 current_print.apply_config_for_render(processor.export_config_for_render());
18278
18279 //BBS: add cost info when drag in gcode
18280 auto& ps = current_result->print_statistics;
18281 double total_cost = 0.0;
18282 for (auto volume : ps.total_volumes_per_extruder) {
18283 size_t extruder_id = volume.first;
18284 double density = current_result->filament_densities.at(extruder_id);
18285 double cost = current_result->filament_costs.at(extruder_id);
18286 double weight = volume.second * density * 0.001;
18287 total_cost += weight * cost * 0.001;
18288 }
18289 current_print.print_statistics().total_cost = total_cost;
18290
18291 current_print.set_gcode_file_ready();
18292
18293 // Belt printer: detect the belt tilt from the loaded G-code header and enable
18294 // belt view mode on the GCodeViewer so the "Show designed view" toggle appears.
18295 if (current_result->belt_tilt_angle > 0.f) {
18296 float angle = current_result->belt_tilt_angle;
18297 p->preview->get_canvas3d()->get_gcode_viewer().set_belt_printer(true, angle);
18298 } else {
18299 p->preview->get_canvas3d()->get_gcode_viewer().set_belt_printer(false, 0.f);
18300 }
18301
18302 // show results
18303 p->preview->reload_print(m_only_gcode);
18304 //BBS: zoom to bed 0 for gcode preview
18305 //p->preview->get_canvas3d()->zoom_to_gcode();
18306 p->preview->get_canvas3d()->zoom_to_plate(0);
18307
18308 if (p->preview->get_canvas3d()->get_gcode_layers_zs().empty()) {
18309 unload_file_settings();
18310 MessageDialog(this, format_wxstr(_L("The selected file:\n%1%\ndoes not contain valid G-code."), filename),
18311 wxString(GCODEVIEWER_APP_NAME) + " - " + _L("An Error has occurred while loading the G-code file."), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal();
18313 } else {
18314 set_project_filename(filename);
18315 }
18316
18317 // Orca: Fix crash when loading gcode file multiple times
18318 if (m_only_gcode) {
18319 p->view3D->get_canvas3d()->remove_raycasters_for_picking(SceneRaycaster::EType::Bed);
18320 }
18321
18322 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false, false); //20250416 ban gcode to send print
18323}
#define TAB_ID_PREVIEW
Definition MainFrame.hpp:61
static bool s_IsBBLPrinter
Definition GCodeProcessor.hpp:650
@ WarningNotificationLevel
Definition NotificationManager.hpp:224
int close_with_confirm(std::function< bool(bool yes_or_no)> second_check=nullptr)
Definition Plater.cpp:19199
void update_project_dirty_from_presets()
Definition Plater.cpp:15664
void enable_sidebar(bool enabled)
Definition Plater.cpp:19149
void on_bed_type_change(BedType bed_type)
Definition Plater.cpp:21477
void set_project_filename(const wxString &filename)
Definition Plater.cpp:22045
void reset_project_dirty_initial_presets()
Definition Plater.cpp:15667
@ Bed
Definition SceneRaycaster.hpp:49
void update_presets(Slic3r::Preset::Type preset_type)
Definition Plater.cpp:3922
#define GCODEVIEWER_APP_NAME
Definition libslic3r.h:12
static void sync_loaded_project_filament_config(DynamicConfig &proj_cfg)
Definition Plater.cpp:8887
void show_substitutions_info(const PresetsConfigSubstitutions &presets_config_substitutions)
Definition GUI.cpp:429
@ CustomNotification
Definition NotificationManager.hpp:66
const wxString DEFAULT_PROJECT_NAME
Definition Plater.hpp:143
@ Enable
Definition Config.hpp:245
std::vector< ConfigSubstitution > ConfigSubstitutions
Definition Config.hpp:269
BedType
Definition PrintConfig.hpp:507
@ btCount
Definition PrintConfig.hpp:515
bool is_gcode_file(const std::string &path)
Definition utils.cpp:1208
bool check(ModelVolumeType volume_type)
Definition GLGizmoEmboss.cpp:515

References _L, Slic3r::angle(), Slic3r::Print::apply(), Slic3r::Print::apply_config_for_render(), Slic3r::GUI::SceneRaycaster::Bed, Slic3r::GCodeProcessorResult::bed_type, Slic3r::GCodeProcessorResult::belt_tilt_angle, Slic3r::btCount, close_with_confirm(), Slic3r::PresetBundle::config_from_gcode(), Slic3r::GUI::CustomNotification, Slic3r::GUI::DEFAULT_PROJECT_NAME, Slic3r::GUI::MainFrame::eEventPlateUpdate, Slic3r::Enable, enable_sidebar(), Slic3r::GCodeProcessor::export_config_for_render(), Slic3r::GCodeProcessor::extract_result(), Slic3r::GCodeProcessorResult::filament_costs, Slic3r::GCodeProcessorResult::filament_densities, Slic3r::GUI::format(), Slic3r::GUI::format_wxstr(), Slic3r::PresetBundle::full_config(), GCODEVIEWER_APP_NAME, get_notification_manager(), Slic3r::GCodeProcessor::init_filament_maps_and_nozzle_type_when_import_only_gcode(), Slic3r::GUI::into_u8(), Slic3r::is_gcode_file(), Slic3r::PresetBundle::load_config_model(), m_gcode_settings_loaded, m_last_loaded_gcode, m_only_gcode, model(), new_project(), on_bed_type_change(), p, Slic3r::GCodeProcessorResult::print_statistics, Slic3r::Print::print_statistics(), Slic3r::GCodeProcessor::process_file(), Slic3r::PresetBundle::project_config, Slic3r::GUI::NotificationManager::push_notification(), reset_project_dirty_initial_presets(), Slic3r::PresetBundle::restore_selection(), Slic3r::GCodeProcessor::s_IsBBLPrinter, Slic3r::PresetBundle::selection(), Slic3r::Print::set_gcode_file_ready(), Slic3r::DynamicConfig::set_key_value(), set_project_filename(), Slic3r::GUI::show_error(), Slic3r::GUI::show_substitutions_info(), Slic3r::GUI::DPIAware< P >::ShowModal(), sidebar(), Slic3r::GUI::sync_loaded_project_filament_config(), TAB_ID_PREVIEW, Slic3r::PrintStatistics::total_cost, Slic3r::trace(), Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINTER, Slic3r::GUI::Sidebar::update_presets(), update_project_dirty_from_presets(), and Slic3r::GUI::NotificationManager::WarningNotificationLevel.

Here is the call graph for this function:

◆ load_project()

void Slic3r::GUI::Plater::load_project ( wxString const & filename = "",
wxString const & originfile = "-" )
16146{
16147 model().calib_pa_pattern.reset(nullptr);
16148 model().plates_custom_gcodes.clear();
16149
16150 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "filename is: " << filename2 << "and originfile is: " << originfile;
16151 BOOST_LOG_TRIVIAL(info) << __FUNCTION__;
16152 auto filename = filename2;
16153 auto check = [&filename, this] (bool yes_or_no) {
16154 if (!yes_or_no && !wxGetApp().check_and_save_current_preset_changes(_L("Load project"),
16155 _L("Some presets are modified.")))
16156 return false;
16157 if (filename.empty()) {
16158 // Ask user for a project file name.
16159 wxGetApp().load_project(this, filename);
16160 }
16161 return !filename.empty();
16162 };
16163
16164 // BSS: save project, force close
16165 int result;
16166 if ((result = close_with_confirm(check)) == wxID_CANCEL) {
16167 return;
16168 }
16169
16170 // BBS
16171 if (m_loading_project) {
16172 //some error cases happens
16173 //return directly
16174 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": current loading other project, return directly");
16175 return;
16176 }
16177
16178 m_loading_project = true;
16179 ScopeGuard loading_project_sc([this]() { m_loading_project = false; }); // Make sure state restored on any early return
16180
16181 m_only_gcode = false;
16182 m_exported_file = false;
16191
16192 auto path = into_path(filename);
16193
16195 if (originfile == "<silence>") {
16196 strategy = strategy | LoadStrategy::Silence;
16197 } else if (originfile == "<loadall>") {
16198 // Do nothing
16199 } else if (originfile != "-") {
16200 strategy = strategy | LoadStrategy::Restore;
16201 } else {
16202 switch (determine_load_type(filename.ToStdString())) {
16203 case LoadType::OpenProject: break; // Do nothing
16204 case LoadType::LoadGeometry:; strategy = LoadStrategy::LoadModel; break;
16205 default: return; // User cancelled
16206 }
16207 }
16208 bool load_restore = strategy & LoadStrategy::Restore;
16209
16210 // Take the Undo / Redo snapshot.
16211 reset();
16212
16213 Plater::TakeSnapshot snapshot(this, "Load Project", UndoRedo::SnapshotType::ProjectSeparator);
16214
16215 std::vector<fs::path> input_paths;
16216 input_paths.push_back(path);
16217 if (strategy & LoadStrategy::Restore)
16218 input_paths.push_back(into_u8(originfile));
16219
16220 bool loaded_published = false;
16221 std::vector<size_t> res = load_files(input_paths, strategy, false, &loaded_published);
16222
16225 wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
16226
16227 // if res is empty no data has been loaded
16228 if (!res.empty() && !loaded_published && (load_restore || !(strategy & LoadStrategy::Silence))) {
16229 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " call set_project_filename: " << (load_restore ? originfile : filename);
16230 p->set_project_filename(load_restore ? originfile : filename);
16231 if (load_restore && originfile.IsEmpty()) {
16232 p->set_project_name(_L("Untitled"));
16233 }
16234
16235 {
16236 Slic3r::LifecycleEventContext ctx;
16237 ctx.name = into_u8(load_restore ? originfile : filename);
16240 }
16241
16242 } else {
16243 if (using_exported_file()) {
16244 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " using ecported set project filename: " << filename;
16245 p->set_project_filename(filename);
16246 } else if (loaded_published && !res.empty()) {
16247 // A "published" 3MF loads as a new project: its path must not become the project
16248 // filename (Save/Ctrl-S prompts for a destination instead of overwriting it);
16249 // reset() already cleared the project name, so restore the default title and keep
16250 // the file in recents. Only on a successful load (res not empty): a failed or
16251 // cancelled load must not pollute "Recently opened".
16252 p->set_project_name(_L("Untitled"));
16253 if (!filename.IsEmpty())
16254 wxGetApp().mainframe->add_to_recent_projects(filename);
16255 }
16256
16257 }
16258
16259 // BBS set default 3D view and direction after loading project
16260 //p->select_view_3D("3D");
16261 if (!m_exported_file) {
16262 p->select_view("topfront");
16263 p->camera.requires_zoom_to_plate = REQUIRES_ZOOM_TO_ALL_PLATE;
16264 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
16265 }
16266 else {
16267 p->partplate_list.select_plate_view();
16268 }
16269
16271
16272 wxGetApp().app_config->update_last_backup_dir(model().get_backup_path());
16273 if (load_restore && !originfile.empty()) {
16274 wxGetApp().app_config->update_skein_dir(into_path(originfile).parent_path().string());
16275 wxGetApp().app_config->update_config_dir(into_path(originfile).parent_path().string());
16276 }
16277
16278 if (!load_restore)
16279 up_to_date(true, false);
16280 else
16281 p->dirty_state.update_from_undo_redo_stack(true);
16282 up_to_date(true, true);
16283
16284 // Clear plate overrides that are incompatible with the selected printer.
16285 normalize_bed_types(false);
16286
16287 wxGetApp().params_panel()->switch_to_object_if_has_object_configs();
16288
16289 auto has_modify = is_flush_config_modified();
16291
16292 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " load project done";
16293}
bool is_flush_config_modified()
Definition WipeTowerDialog.cpp:239
void bbl_close_preview_only_notification()
Definition NotificationManager.cpp:3413
void bbl_close_plateinfo_notification()
Definition NotificationManager.cpp:3398
void bbl_close_3mf_warn_notification()
Definition NotificationManager.cpp:3384
void close_notification_of_type(const NotificationType type)
Definition NotificationManager.cpp:2231
void reset(bool apply_presets_change=false, bool reload_presets=true)
Definition Plater.cpp:19186
void normalize_bed_types(bool printer_setting_changed)
Definition Plater.cpp:15672
void set_flushing_volume_warning(const bool flushing_volume_modify)
Definition Plater.cpp:6687
@ OpenProject
Definition Plater.cpp:486
@ LoadGeometry
Definition Plater.cpp:487
LoadType determine_load_type(std::string filename, std::string override_setting="")
Definition Plater.cpp:18911
@ SlicingSeriousWarning
Definition NotificationManager.hpp:99
@ PlaterError
Definition NotificationManager.hpp:106
@ SlicingWarning
Definition NotificationManager.hpp:102
@ PlaterWarning
Definition NotificationManager.hpp:110
@ SlicingError
Definition NotificationManager.hpp:97
@ ProjectSeparator
Definition UndoRedo.hpp:40
std::string name
Definition LifecycleEvents.hpp:75
@ ProjectOpened
Definition LifecycleEvents.hpp:22
@ Ok
Definition LifecycleEvents.hpp:68
LifecycleEvtCode code
Definition LifecycleEvents.hpp:79
@ Restore
Definition bbs_3mf.hpp:228
@ Silence
Definition bbs_3mf.hpp:225

References _L, Slic3r::GUI::NotificationManager::bbl_close_3mf_warn_notification(), Slic3r::GUI::NotificationManager::bbl_close_plateinfo_notification(), Slic3r::GUI::NotificationManager::bbl_close_preview_only_notification(), Slic3r::Model::calib_pa_pattern, Slic3r::GUI::NotificationManager::close_notification_of_type(), close_with_confirm(), Slic3r::LifecycleEventContext::code, Slic3r::GUI::determine_load_type(), enable_sidebar(), Slic3r::fire_lifecycle_event(), get_notification_manager(), Slic3r::GUI::into_path(), Slic3r::GUI::into_u8(), is_flush_config_modified(), load_files(), Slic3r::LoadConfig, Slic3r::GUI::LoadGeometry, Slic3r::LoadModel, m_exported_file, m_loading_project, m_only_gcode, model(), Slic3r::LifecycleEventContext::name, normalize_bed_types(), Slic3r::Ok, Slic3r::GUI::OpenProject, p, Slic3r::GUI::PlaterError, Slic3r::GUI::PlaterWarning, Slic3r::Model::plates_custom_gcodes, Slic3r::ProjectOpened, Slic3r::UndoRedo::ProjectSeparator, REQUIRES_ZOOM_TO_ALL_PLATE, reset(), reset_project_dirty_initial_presets(), Slic3r::Restore, Slic3r::GUI::Sidebar::set_flushing_volume_warning(), sidebar(), Slic3r::Silence, Slic3r::GUI::SlicingError, Slic3r::GUI::SlicingSeriousWarning, Slic3r::GUI::SlicingWarning, TAB_ID_PREPARE, up_to_date(), update_project_dirty_from_presets(), and using_exported_file().

Referenced by import_model_id(), and open_3mf_file().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mark_plate_toolbar_image_dirty()

void Slic3r::GUI::Plater::mark_plate_toolbar_image_dirty ( )
438{
441}
unsigned m_plate_toolbar_image_version
Definition Plater.hpp:1105

References m_b_plate_toolbar_image_dirty, and m_plate_toolbar_image_version.

Referenced by invalid_all_plate_thumbnails().

Here is the caller graph for this function:

◆ merge()

void Slic3r::GUI::Plater::merge ( size_t obj_idx,
std::vector< int > & vol_indeces )

◆ mirror()

void Slic3r::GUI::Plater::mirror ( Axis axis)
22335{ p->mirror(axis); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog().

Here is the caller graph for this function:

◆ mixed_filament_config_indices()

std::vector< size_t > Slic3r::GUI::Plater::mixed_filament_config_indices ( ) const
15705{
15706 std::vector<size_t> indices;
15707 auto& config = wxGetApp().preset_bundle->project_config;
15708 auto* opt = config.option<ConfigOptionBools>("filament_is_mixed");
15709 if (!opt) return indices;
15710 for (size_t i = 0; i < opt->values.size(); ++i)
15711 if (opt->values[i]) indices.push_back(i);
15712 return indices;
15713}

References config().

Referenced by Slic3r::GUI::Sidebar::Sidebar().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ model() [1/2]

Model & Slic3r::GUI::Plater::model ( )
16048{ return p->model; }

References p.

◆ model() [2/2]

◆ msw_rescale()

void Slic3r::GUI::Plater::msw_rescale ( )
22525{
22526 p->preview->msw_rescale();
22527
22528 p->view3D->get_canvas3d()->msw_rescale();
22529
22530 p->sidebar->msw_rescale();
22531
22532 p->menus.msw_rescale();
22533
22534 Layout();
22535 GetParent()->Layout();
22536}

References p.

◆ multi_selection_menu()

wxMenu * Slic3r::GUI::Plater::multi_selection_menu ( )
24131{ return p->menus.multi_selection_menu(); }

References p.

◆ need_update()

bool Slic3r::GUI::Plater::need_update ( ) const
24032{
24033 return p->need_update();
24034}

References p.

Referenced by set_need_update(), and update().

Here is the caller graph for this function:

◆ new_project()

int Slic3r::GUI::Plater::new_project ( bool skip_confirm = false,
bool silent = false,
const wxString & project_name = wxString(),
bool reload_presets = true )
16055{
16056 model().calib_pa_pattern.reset(nullptr);
16057 model().plates_custom_gcodes.clear();
16058
16059 bool transfer_preset_changes = false;
16060 // BBS: save confirm
16061 auto check = [this,&transfer_preset_changes](bool yes_or_no) {
16063 wxString header = _L("Some presets are modified.") + "\n" +
16064 (yes_or_no ? _L("You can keep the modified presets for the new project or discard them") :
16065 _L("You can keep the modified presets for the new project, discard, or save changes as new presets."));
16067 if (!yes_or_no)
16068 act_buttons |= ActionButtons::SAVE;
16069 if (m_exported_file) { //.gcode.3mf ignore presets modify
16070 m_exported_file = false;
16071 }
16072 bool result = wxGetApp().check_and_keep_current_preset_changes(_L("Creating a new project"), header, act_buttons, &transfer_preset_changes);
16074 return result;
16075 };
16076 int result;
16077 if (!skip_confirm && (result = close_with_confirm(check)) == wxID_CANCEL)
16078 return wxID_CANCEL;
16079
16080 m_only_gcode = false;
16081 m_exported_file = false;
16082 m_loading_project = false;
16084
16085 if (!silent)
16086 wxGetApp().mainframe->select_tab(TAB_ID_PREPARE);
16087
16088 //get_partplate_list().reinit();
16089 //get_partplate_list().update_slice_context_to_current_plate(p->background_process);
16090 //p->preview->update_gcode_result(p->partplate_list.get_current_slice_result());
16091 if (!silent) {
16092 Slic3r::LifecycleEventContext ctx;
16095 }
16096 {
16097 // Same rationale as in Plater::priv::reset(): the whole reset + preset-reload +
16098 // baseline-reset sequence below settles into its final dirty state only once it
16099 // completes, so hold notifications until then to avoid firing on transient flips.
16100 ProjectDirtyStateManager::NotificationSuppressor dirty_notify_suppressor(p->dirty_state);
16101
16102 reset(transfer_preset_changes, reload_presets);
16105 wxGetApp().update_saved_preset_from_current_preset();
16107
16108 //reset project
16109 p->project.reset();
16110 //set project name
16111 if (project_name.empty())
16112 p->set_project_name(_L("Untitled"));
16113 else
16114 p->set_project_name(project_name);
16115
16116 Plater::TakeSnapshot snapshot(this, "New Project", UndoRedo::SnapshotType::ProjectSeparator);
16117 }
16118
16119 Model m;
16120 model().load_from(m); // new id avoid same path name
16121
16122 //select first plate
16124 SimpleEvent event(EVT_GLCANVAS_PLATE_SELECT);
16125 p->on_plate_selected(event);
16126
16127 p->load_auxiliary_files();
16128 wxGetApp().app_config->update_last_backup_dir(model().get_backup_path());
16129
16130 // BBS set default view and zoom
16131 p->select_view_3D("3D");
16132 p->select_view("topfront");
16133 p->camera.requires_zoom_to_bed = true;
16135
16136 up_to_date(true, false);
16137 up_to_date(true, true);
16138 return wxID_YES;
16139}
void clear_all()
Definition NotificationManager.cpp:2263
int select_plate(int index)
Definition PartPlate.cpp:6934
void reset_project_dirty_after_save()
Definition Plater.cpp:15666
void load_from(Model &model)
Definition Model.cpp:1190
@ KEEP
Definition UnsavedChangesDialog.hpp:252
@ SAVE
Definition UnsavedChangesDialog.hpp:253
@ REMEMBER_CHOISE
Definition UnsavedChangesDialog.hpp:255
@ NewProject
Definition LifecycleEvents.hpp:21

References _L, Slic3r::Model::calib_pa_pattern, Slic3r::GUI::NotificationManager::clear_all(), close_with_confirm(), Slic3r::LifecycleEventContext::code, enable_sidebar(), Slic3r::fire_lifecycle_event(), get_notification_manager(), get_partplate_list(), Slic3r::GUI::KEEP, Slic3r::Model::load_from(), m_exported_file, m_loading_project, m_new_project_and_check_state, m_only_gcode, model(), Slic3r::NewProject, Slic3r::Ok, p, Slic3r::Model::plates_custom_gcodes, Slic3r::UndoRedo::ProjectSeparator, Slic3r::GUI::REMEMBER_CHOISE, reset(), reset_project_dirty_after_save(), reset_project_dirty_initial_presets(), Slic3r::GUI::SAVE, Slic3r::GUI::PartPlateList::select_plate(), TAB_ID_PREPARE, up_to_date(), and update_project_dirty_from_presets().

Referenced by Calib_Cornering(), calib_flowrate(), calib_input_shaping_damp(), calib_input_shaping_freq(), calib_max_vol_speed(), calib_pa(), calib_retraction(), calib_temp(), calib_VFA(), and load_gcode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ normalize_bed_types()

void Slic3r::GUI::Plater::normalize_bed_types ( bool printer_setting_changed)
15673{
15674 if (only_gcode_mode() || is_gcode_3mf())
15675 return;
15676
15677 auto &preset_bundle = *wxGetApp().preset_bundle;
15678 // Keep FFF plate settings intact while an SLA printer is selected.
15679 if (preset_bundle.printers.get_edited_preset().printer_technology() != ptFFF)
15680 return;
15681
15682 const auto &printer_config = preset_bundle.printers.get_edited_preset().config;
15683
15684 const bool supports_multiple_bed_types =
15685 preset_bundle.is_bbl_vendor() || printer_config.opt_bool("support_multi_bed_types");
15686 // Clear local overrides for single-bed printers.
15687 const bool overrides_reset = !supports_multiple_bed_types &&
15688 !p->partplate_list.check_all_plate_local_bed_type({});
15689
15690 if (overrides_reset) {
15691 set_plater_dirty(true);
15692 show_info(this,
15693 _L("The selected printer does not support multiple bed types.\nBed type overrides were reset to the global bed type."),
15694 _L("Plate bed types reset"));
15695 }
15696
15697 // Refresh the controls after a capability change, even when no override was reset.
15698 if (multi_bed_changed || overrides_reset) {
15700 wxGetApp().obj_list()->update_and_show_object_settings_item();
15701 }
15702}
bool is_gcode_3mf()
Definition Plater.hpp:418
void set_plater_dirty(bool is_dirty)
Definition Plater.cpp:15663
bool only_gcode_mode()
Definition Plater.hpp:419
void update_all_preset_comboboxes()
Definition Plater.cpp:3795

References _L, is_gcode_3mf(), only_gcode_mode(), p, Slic3r::GUI::printer_config(), Slic3r::ptFFF, set_plater_dirty(), Slic3r::GUI::show_info(), sidebar(), and Slic3r::GUI::Sidebar::update_all_preset_comboboxes().

Referenced by load_project().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ notify_painting_removed()

void Slic3r::GUI::Plater::notify_painting_removed ( )
22211{
22215 _u8L("Custom supports and color painting were removed before repairing."));
22216}
@ PrintInfoNotificationLevel
Definition NotificationManager.hpp:218
@ CustomSupportsAndSeamRemovedAfterRepair
Definition NotificationManager.hpp:122

References _u8L, Slic3r::GUI::CustomSupportsAndSeamRemovedAfterRepair, get_notification_manager(), Slic3r::GUI::NotificationManager::PrintInfoNotificationLevel, and Slic3r::GUI::NotificationManager::push_notification().

Referenced by clear_before_change_mesh().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ object_list_changed()

void Slic3r::GUI::Plater::object_list_changed ( )
19108{ p->object_list_changed(); }

References p.

Referenced by Slic3r::GUI::Plater::priv::delete_all_objects_from_model(), Slic3r::GUI::Plater::priv::delete_object_from_model(), Slic3r::GUI::Plater::priv::remove(), and Slic3r::GUI::Plater::priv::reset().

Here is the caller graph for this function:

◆ object_menu()

wxMenu * Slic3r::GUI::Plater::object_menu ( )
24123{ return p->menus.object_menu(); }

References p.

◆ on_activate()

void Slic3r::GUI::Plater::on_activate ( )
21792{
21793 this->p->show_delayed_error_message();
21794}

References p.

◆ on_bed_type_change()

void Slic3r::GUI::Plater::on_bed_type_change ( BedType bed_type)
21478{
21479 sidebar().on_bed_type_change(bed_type);
21480}
void on_bed_type_change(BedType bed_type)
Definition Plater.cpp:6042

References Slic3r::GUI::Sidebar::on_bed_type_change(), and sidebar().

Referenced by load_gcode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_change_color_mode()

void Slic3r::GUI::Plater::on_change_color_mode ( SimpleEvent & evt)

References config(), and model().

Here is the call graph for this function:

◆ on_config_change()

void Slic3r::GUI::Plater::on_config_change ( const DynamicPrintConfig & config)
21513{
21514 bool update_scheduled = false;
21515 bool bed_shape_changed = false;
21516 bool exclusion_preview_changed = false;
21517 bool imex_changed = false;
21518 //bool print_sequence_changed = false;
21519 t_config_option_keys diff_keys = p->config->diff(config);
21520
21521 size_t old_nozzle_size = 1, new_nozzle_size = 1;
21522 auto * opt_old = p->config->option<ConfigOptionFloats>("nozzle_diameter");
21523 auto * opt_new = config.option<ConfigOptionFloats>("nozzle_diameter");
21524 if (opt_old && opt_new) {
21525 old_nozzle_size = opt_old->values.size();
21526 new_nozzle_size = opt_new->values.size();
21527 }
21528
21529 for (auto opt_key : diff_keys) {
21530 if (opt_key == "filament_colour") {
21531 update_scheduled = true; // update should be scheduled (for update 3DScene) #2738
21532
21534 p->sidebar->update_mixed_filament_list();
21535 p->partplate_list.invalidate_exclusion_volume_previews();
21536 p->sidebar->obj_list()->update_filament_colors();
21537 p->sidebar->update_dynamic_filament_list();
21538 continue;
21539 }
21540 }
21541 if (opt_key == "filament_type") {
21543 p->sidebar->update_mixed_filament_list();
21544 continue;
21545 }
21546 // The mixed-filament type check folds filament_is_support into the component type
21547 // (DynamicPrintConfig::get_filament_type -> "PLA-S"), so a support-preset switch must
21548 // refresh the list even though filament_type itself did not change.
21549 if (opt_key == "filament_is_support") {
21550 p->config->set_key_value(opt_key, config.option(opt_key)->clone());
21551 p->sidebar->update_mixed_filament_list();
21552 continue;
21553 }
21554 if (opt_key == "material_colour") {
21555 update_scheduled = true; // update should be scheduled (for update 3DScene)
21556 }
21557
21558 p->config->set_key_value(opt_key, config.option(opt_key)->clone());
21559 if (opt_key == "bed_exclude_volume_mode" || opt_key == "bed_exclude_area" ||
21560 opt_key == "bed_exclude_volumes" || opt_key == "extruder_bed_exclude_volumes" || opt_key == "extruder_offset" ||
21561 opt_key == "master_extruder_id" || opt_key == "nozzle_diameter" ||
21562 opt_key == "printable_height" || opt_key == "extruder_colour")
21563 exclusion_preview_changed = true;
21564
21565 if (opt_key == "printer_technology") {
21566 this->set_printer_technology(config.opt_enum<PrinterTechnology>(opt_key));
21567 // print technology is changed, so we should to update a search list
21568 p->sidebar->update_searcher();
21569 p->reset_gcode_toolpaths();
21570 p->view3D->get_canvas3d()->reset_sequential_print_clearance();
21571 p->preview->get_canvas3d()->reset_volumes();
21572 //BBS: invalid all the slice results
21573 p->partplate_list.invalid_all_slice_result();
21574 }
21575 //BBS: add bed_exclude_area
21576 else if (opt_key == "printable_area" || opt_key == "bed_exclude_volume_mode" || opt_key == "bed_exclude_area"
21577 || opt_key == "bed_exclude_volumes" || opt_key == "extruder_bed_exclude_volumes" || opt_key == "extruder_offset"
21578 || opt_key == "bed_custom_texture" || opt_key == "bed_custom_model"
21579 || opt_key == "extruder_clearance_height_to_lid"
21580 || opt_key == "extruder_clearance_height_to_rod") {
21581 bed_shape_changed = true;
21582 update_scheduled = true;
21583 }
21584 else if (opt_key == "bed_shape" || opt_key == "bed_custom_texture" || opt_key == "bed_custom_model") {
21585 bed_shape_changed = true;
21586 update_scheduled = true;
21587 }
21588 else if (boost::starts_with(opt_key, "enable_prime_tower") ||
21589 boost::starts_with(opt_key, "prime_tower") ||
21590 boost::starts_with(opt_key, "wipe_tower") ||
21591 opt_key == "filament_minimal_purge_on_wipe_tower" ||
21592 opt_key == "single_extruder_multi_material" ||
21593 // BBS
21594 opt_key == "prime_volume") {
21595 update_scheduled = true;
21596 }
21597 else if(opt_key == "extruder_colour") {
21598 update_scheduled = true;
21599 p->partplate_list.invalidate_exclusion_volume_previews();
21600 //p->sidebar->obj_list()->update_extruder_colors();
21601 }
21602 else if (opt_key == "printable_height") {
21603 bed_shape_changed = true;
21604 update_scheduled = true;
21605 }
21606 else if (opt_key == "print_sequence") {
21607 update_scheduled = true;
21608 //print_sequence_changed = true;
21609 }
21610 else if (opt_key == "printer_model") {
21611 p->reset_gcode_toolpaths();
21612 if (old_nozzle_size != new_nozzle_size) {
21613 update_flush_volume_matrix(old_nozzle_size, new_nozzle_size);
21614 }
21615
21616 // update to force bed selection(for texturing)
21617 bed_shape_changed = true;
21618 update_scheduled = true;
21619 }
21620 // Orca: update when *_filament changed
21621 else if (opt_key == "support_interface_filament" || opt_key == "support_filament" ||
21622 opt_key == "outer_wall_filament_id" || opt_key == "inner_wall_filament_id" ||
21623 opt_key == "sparse_infill_filament_id" || opt_key == "internal_solid_filament_id" ||
21624 opt_key == "top_surface_filament_id" || opt_key == "bottom_surface_filament_id" ||
21625 opt_key == "enable_support" || opt_key == "raft_layers" || opt_key == "wall_loops" ||
21626 opt_key == "sparse_infill_density" || opt_key == "top_shell_layers" ||
21627 opt_key == "bottom_shell_layers" || opt_key == "brim_type" || opt_key == "brim_width") {
21628 update_scheduled = true;
21629 p->partplate_list.invalidate_exclusion_volume_previews();
21630 }
21631 // IDEX/IQEX: when is_imex toggles the mode icon needs to be repositioned on every plate.
21632 // set_shape() short-circuits when the bed geometry is unchanged, so we refresh explicitly.
21633 // Defer until after the loop so bed_shape_changed / set_bed_shape() run first if needed.
21634 else if (opt_key == "is_imex") {
21635 imex_changed = true;
21636 update_scheduled = true;
21637 }
21638 // Orca: the center of mass markers weigh the parts by it.
21639 else if (opt_key == "filament_density" && wxGetApp().show_center_of_mass())
21640 p->view3D->get_canvas3d()->set_as_dirty();
21641 }
21642
21643 if (bed_shape_changed) {
21644 set_bed_shape();
21646 }
21647
21648 if (exclusion_preview_changed)
21649 p->partplate_list.invalidate_exclusion_volume_previews();
21650
21651 if (bed_shape_changed || exclusion_preview_changed)
21653
21654 // After any bed-shape or is_imex change, ensure the IMEX mode icon geometry and
21655 // raycaster are correct. set_shape() short-circuits when the bed is unchanged,
21656 // so we call refresh_imex_icons() explicitly whenever is_imex is active.
21657 // Always done AFTER set_bed_shape() so m_shape is current.
21658 if (bed_shape_changed || imex_changed) {
21659 auto* is_imex_opt = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionBool>("is_imex");
21660 if (is_imex_opt && is_imex_opt->value)
21661 p->partplate_list.refresh_imex_icons();
21662 }
21663
21664 config_change_notification(config, std::string("print_sequence"));
21665
21666 if (update_scheduled)
21667 update();
21668
21669 if (p->main_frame->is_loaded()) {
21670 this->p->schedule_background_process();
21672 p->schedule_auto_reslice_if_needed();
21673 }
21674}
void request_extra_frame()
Definition GLCanvas3D.hpp:1385
void config_change_notification(const DynamicPrintConfig &config, const std::string &key)
Definition Plater.cpp:21494
bool update_filament_colors_in_full_config()
Definition Plater.cpp:21482
void update_title_dirty_status()
Definition Plater.cpp:24062
bool set_printer_technology(PrinterTechnology printer_technology)
Definition Plater.cpp:22162
void update_flush_volume_matrix(size_t old_nozzle_size, size_t new_nozzle_size)
Definition Plater.cpp:21676
void set_bed_shape() const
Definition Plater.cpp:21718
PrinterTechnology
Definition Config.hpp:229
std::vector< std::string > t_config_option_keys
Definition Config.hpp:97

References config(), config_change_notification(), get_current_canvas3D(), Slic3r::DynamicConfig::opt_enum(), p, Slic3r::GUI::GLCanvas3D::request_extra_frame(), Slic3r::GUI::GLCanvas3D::requires_check_outside_state(), set_bed_shape(), set_printer_technology(), update(), update_filament_colors_in_full_config(), update_flush_volume_matrix(), update_title_dirty_status(), and Slic3r::ConfigOptionVector< double >::values.

Here is the call graph for this function:

◆ on_filament_change()

void Slic3r::GUI::Plater::on_filament_change ( size_t filament_idx)
21363{
21364 auto& filament_presets = wxGetApp().preset_bundle->filament_presets;
21365 if (filament_idx >= filament_presets.size())
21366 return;
21367 Slic3r::Preset* filament = wxGetApp().preset_bundle->filaments.find_preset(filament_presets[filament_idx]);
21368 if (filament == nullptr)
21369 return;
21370 std::string filament_type = filament->config.option<ConfigOptionStrings>("filament_type")->values[0];
21371}
DynamicPrintConfig config
Definition Preset.hpp:300
zaa_minimize_perimeter_height filament_type((ConfigOptionBools, filament_soluble))((ConfigOptionStrings

References Slic3r::Preset::config, Slic3r::filament_type(), and Slic3r::ConfigBase::option().

Referenced by Slic3r::anonymous_namespace{PluginHostPresets.cpp}::bind_filament_target().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_filament_count_change()

void Slic3r::GUI::Plater::on_filament_count_change ( size_t extruders_count)
21375{
21376 // only update elements in plater
21378 sidebar().on_filament_count_change(num_filaments);
21380
21381 Slic3r::GUI::PartPlateList &plate_list = get_partplate_list();
21382 plate_list.set_filament_count(num_filaments);
21383 for (int i = 0; i < plate_list.get_plate_count(); ++i) {
21384 PartPlate* part_plate = plate_list.get_plate(i);
21385 part_plate->update_first_layer_print_sequence(num_filaments);
21386 }
21387
21388 for (ModelObject* mo : wxGetApp().model().objects) {
21389 for (ModelVolume* mv : mo->volumes) {
21390 mv->update_extruder_count(num_filaments);
21391 }
21392 }
21393}
void update_objects_list_filament_column(size_t filaments_count)
Definition GUI_ObjectList.cpp:1046
void set_filament_count(int filament_count)
Definition PartPlate.cpp:9173
void update_first_layer_print_sequence(size_t filament_nums)
Definition PartPlate.cpp:5667
void on_filament_count_change(size_t num_filaments)
Definition Plater.cpp:5705

References get_partplate_list(), Slic3r::GUI::PartPlateList::get_plate(), Slic3r::GUI::PartPlateList::get_plate_count(), model(), Slic3r::GUI::Sidebar::obj_list(), Slic3r::GUI::Sidebar::on_filament_count_change(), Slic3r::GUI::PartPlateList::set_filament_count(), sidebar(), Slic3r::ModelVolume::update_extruder_count(), update_filament_colors_in_full_config(), Slic3r::GUI::PartPlate::update_first_layer_print_sequence(), Slic3r::GUI::ObjectList::update_objects_list_filament_column(), and Slic3r::ModelObject::volumes.

Here is the call graph for this function:

◆ on_filament_map_mode_change()

void Slic3r::GUI::Plater::on_filament_map_mode_change ( )
private
22006{
22007 auto& plate_list = this->get_partplate_list();
22008 int plate_count = plate_list.get_plate_count();
22009 for (int idx = 0; idx < plate_count; ++idx) {
22010 auto plate=plate_list.get_plate(idx);
22011 auto plate_map_mode = plate->get_filament_map_mode();
22012 if (plate_map_mode == fmmDefault)
22013 plate->clear_filament_map();
22014 }
22015}
@ fmmDefault
Definition PrintConfig.hpp:637

References Slic3r::fmmDefault, and get_partplate_list().

Referenced by set_global_filament_map_mode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_filaments_delete()

void Slic3r::GUI::Plater::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 = {} )
21396{
21397 // only update elements in plater
21399
21400 // update fisrt print sequence and other layer sequence
21401 //move to partplate->on_filament_deleted
21402 /*Slic3r::GUI::PartPlateList &plate_list = get_partplate_list();
21403 for (int i = 0; i < plate_list.get_plate_count(); ++i) {
21404 PartPlate *part_plate = plate_list.get_plate(i);
21405 part_plate->update_first_layer_print_sequence_when_delete_filament(filament_id);
21406 }*/
21407
21408 // update mmu info
21409 // A volume assigned to a mixed slot legitimately sits past the physical filament count, so
21410 // the paint cleanup must know which slots were mixed. Callers that already shrank the arrays
21411 // pass the pre-delete flags; otherwise read the current ones.
21412 const auto &is_mixed = is_mixed_before_delete.empty()
21413 ? wxGetApp().preset_bundle->project_config.option<ConfigOptionBools>("filament_is_mixed")->values
21414 : is_mixed_before_delete;
21415 for (ModelObject *mo : wxGetApp().model().objects) {
21416 for (ModelVolume *mv : mo->volumes) {
21417 mv->update_extruder_count_when_delete_filament(num_filaments, filament_id + 1, replace_filament_id + 1, is_mixed); // this function is 1 base
21418 }
21419 }
21420
21421 // update object/volume/support(object and volume) filament id
21422 // Must run before UI update which triggers update_mixed_filament_list() →
21423 // update_objects_list_filament_column() that clips extruders above total count.
21424 sidebar().obj_list()->update_objects_list_filament_column_when_delete_filament(filament_id, num_filaments, replace_filament_id);
21425
21426 // update global support filament
21427 static const char *keys[] = {"support_filament", "support_interface_filament"};
21428 for (auto key : keys)
21429 if (p->config->has(key)) {
21430 if(p->config->opt_int(key) == filament_id + 1)
21431 (*(p->config)).erase(key);
21432 else {
21433 int new_value = p->config->opt_int(key) > filament_id ? p->config->opt_int(key) - 1 : p->config->opt_int(key);
21434 (*(p->config)).set_key_value(key, new ConfigOptionInt(new_value));
21435 }
21436 }
21437
21438 // update UI — runs after remap so update_mixed_filament_list() won't clip remapped extruder IDs
21439 sidebar().on_filaments_delete(filament_id);
21440
21441 // update customize gcode
21442 for (auto item = p->model.plates_custom_gcodes.begin(); item != p->model.plates_custom_gcodes.end(); ++item) {
21443 auto iter = std::remove_if(item->second.gcodes.begin(), item->second.gcodes.end(), [filament_id](const CustomGCode::Item& gcode_item) {
21444 return (gcode_item.type == CustomGCode::Type::ToolChange && gcode_item.extruder == filament_id + 1);
21445 });
21446 if (replace_filament_id == -1)
21447 item->second.gcodes.erase(iter, item->second.gcodes.end());
21448 else if(iter != item->second.gcodes.end()) {
21449 iter->extruder = replace_filament_id + 1;
21450 }
21451
21452 for (auto& item : item->second.gcodes) {
21453 if (item.type == CustomGCode::Type::ToolChange && item.extruder > filament_id)
21454 item.extruder--;
21455 }
21456 }
21457}
void update_objects_list_filament_column_when_delete_filament(size_t filament_id, size_t filaments_count, int replace_filament_id=-1)
Definition GUI_ObjectList.cpp:1070
void on_filaments_delete(size_t filament_id)
Definition Plater.cpp:5767
@ ToolChange
Definition CustomGCode.hpp:21
void erase(std::vector< VecType > &vec, const std::vector< bool > &flags)
Definition RaycastManager.cpp:315

References model(), Slic3r::GUI::Sidebar::obj_list(), Slic3r::GUI::Sidebar::on_filaments_delete(), p, sidebar(), Slic3r::CustomGCode::ToolChange, Slic3r::ModelVolume::update_extruder_count_when_delete_filament(), update_filament_colors_in_full_config(), Slic3r::GUI::ObjectList::update_objects_list_filament_column_when_delete_filament(), and Slic3r::ModelObject::volumes.

Here is the call graph for this function:

◆ on_imex_ghost_click()

void Slic3r::GUI::Plater::on_imex_ghost_click ( int physical_head)
24099{
24100 const ConfigOptionInts pem = effective_physical_extruder_map(*wxGetApp().preset_bundle);
24101
24102 int lane_count = 0;
24103 for (int pv : pem.values) if (pv == physical_head) ++lane_count;
24104 if (lane_count < 2) return; // single-lane head -> click is a no-op, tooltip conveyed status
24105
24106 PartPlate* plate = p->partplate_list.get_curr_plate();
24107 if (!plate) return;
24108
24109 auto* picker = new IMEXFilamentPickerPopover(
24110 p->view3D->get_canvas3d()->get_wxglcanvas(),
24111 plate, pem, physical_head,
24112 [this]() {
24113 take_snapshot("edit imex head filament");
24114 update_project_dirty_from_presets();
24115 set_plater_dirty(true);
24116 update();
24117 });
24118 picker->popup_at_cursor();
24119}

References Slic3r::effective_physical_extruder_map(), p, and Slic3r::ConfigOptionVector< int >::values.

Here is the call graph for this function:

◆ only_gcode_mode()

bool Slic3r::GUI::Plater::only_gcode_mode ( )
inline
419{ return m_only_gcode; }

References m_only_gcode.

Referenced by normalize_bed_types().

Here is the caller graph for this function:

◆ open_3mf_file()

bool Slic3r::GUI::Plater::open_3mf_file ( const boost::filesystem::path & file_path)
18942{
18943 std::string filename = encode_path(file_path.filename().string().c_str());
18944 if (!boost::algorithm::iends_with(filename, ".3mf")) {
18945 return false;
18946 }
18947
18948 bool not_empty_plate = !model().objects.empty();
18949 bool load_setting_ask_when_relevant = wxGetApp().app_config->get(SETTING_PROJECT_LOAD_BEHAVIOUR) == OPTION_PROJECT_LOAD_BEHAVIOUR_ASK_WHEN_RELEVANT;
18950 LoadType load_type = determine_load_type(filename, (not_empty_plate && load_setting_ask_when_relevant) ? OPTION_PROJECT_LOAD_BEHAVIOUR_ALWAYS_ASK : "");
18951
18952 if (load_type == LoadType::Unknown) return false;
18953
18954 switch (load_type) {
18955 case LoadType::OpenProject: {
18956 if (wxGetApp().can_load_project())
18957 load_project(from_path(file_path), "<loadall>");
18958 break;
18959 }
18961 Plater::TakeSnapshot snapshot(this, "Import Object");
18962 load_files({file_path}, LoadStrategy::LoadModel);
18963 break;
18964 }
18965 case LoadType::LoadConfig: {
18967 break;
18968 }
18969 case LoadType::Unknown: {
18970 assert(false);
18971 break;
18972 }
18973 }
18974
18975 return true;
18976}
#define OPTION_PROJECT_LOAD_BEHAVIOUR_ALWAYS_ASK
Definition AppConfig.hpp:25
#define OPTION_PROJECT_LOAD_BEHAVIOUR_ASK_WHEN_RELEVANT
Definition AppConfig.hpp:24
#define SETTING_PROJECT_LOAD_BEHAVIOUR
Definition AppConfig.hpp:22
LoadType
Definition Plater.cpp:484
@ LoadConfig
Definition Plater.cpp:488
@ Unknown
Definition Plater.cpp:485

References Slic3r::GUI::determine_load_type(), Slic3r::encode_path(), Slic3r::GUI::from_path(), load_files(), load_project(), Slic3r::GUI::LoadConfig, Slic3r::LoadConfig, Slic3r::GUI::LoadGeometry, Slic3r::LoadModel, model(), Slic3r::Model::objects, Slic3r::GUI::OpenProject, OPTION_PROJECT_LOAD_BEHAVIOUR_ALWAYS_ASK, OPTION_PROJECT_LOAD_BEHAVIOUR_ASK_WHEN_RELEVANT, SETTING_PROJECT_LOAD_BEHAVIOUR, and Slic3r::GUI::Unknown.

Referenced by add_file(), and load_files().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_filament_map_setting_dialog()

void Slic3r::GUI::Plater::open_filament_map_setting_dialog ( wxCommandEvent & evt)
23184{
23185 PartPlate* curr_plate = p->partplate_list.get_curr_plate();
23186 int value = evt.GetInt(); //1 means from gcode view
23187 bool need_slice = value ==1; // If from gcode view, should slice
23188
23189 const auto& project_config = wxGetApp().preset_bundle->project_config;
23190 auto filament_colors = config()->option<ConfigOptionStrings>("filament_colour")->values;
23191 auto filament_types = config()->option<ConfigOptionStrings>("filament_type")->values;
23192
23193 auto plate_filament_maps = curr_plate->get_real_filament_maps(project_config);
23194 auto plate_filament_map_mode = curr_plate->get_filament_map_mode();
23195 auto plate_filament_volume_maps = curr_plate->get_real_filament_volume_maps(project_config);
23196 if (plate_filament_maps.size() != filament_colors.size()) // refine it later, save filament map to app config
23197 plate_filament_maps.resize(filament_colors.size(), 1);
23198 if (plate_filament_volume_maps.size() != filament_colors.size())
23199 plate_filament_volume_maps.resize(filament_colors.size(), 0);
23200
23201 FilamentMapDialog filament_dlg(this,
23202 filament_colors,
23204 plate_filament_maps,
23205 plate_filament_volume_maps,
23206 curr_plate->get_extruders(true),
23207 plate_filament_map_mode,
23208 this->get_machine_sync_status(),
23209 false
23210 );
23211
23212 if (filament_dlg.ShowModal() == wxID_OK) {
23213 std::vector<int> new_filament_maps = filament_dlg.get_filament_maps();
23214 std::vector<int> old_filament_maps = curr_plate->get_real_filament_maps(project_config);
23215
23216 FilamentMapMode old_map_mode = curr_plate->get_filament_map_mode();
23217 FilamentMapMode new_map_mode = filament_dlg.get_mode();
23218
23219 std::vector<int> new_filament_volume_maps = filament_dlg.get_filament_volume_maps();
23220 std::vector<int> old_filament_volume_maps = curr_plate->get_real_filament_volume_maps(project_config);
23221
23222 if (new_map_mode != old_map_mode) {
23223 curr_plate->set_filament_map_mode(new_map_mode);
23224 }
23225
23226 if (new_map_mode == fmmManual){
23227 curr_plate->set_filament_maps(new_filament_maps);
23228 curr_plate->set_filament_volume_maps(new_filament_volume_maps);
23229 }
23230
23231 bool need_invalidate = (old_map_mode != new_map_mode ||
23232 old_filament_maps != new_filament_maps ||
23233 old_filament_volume_maps != new_filament_volume_maps);
23234
23235 if (need_invalidate) {
23236 if (need_slice) {
23237 wxPostEvent(this, SimpleEvent(EVT_GLTOOLBAR_SLICE_PLATE));
23238 }
23239 else {
23240 curr_plate->update_slice_result_valid_state(false);
23241 set_plater_dirty(true);
23242 update();
23243 }
23244 }
23245 }
23246 return;
23247}
static const std::vector< std::string > filament_types
Definition CreatePresetsDialog.cpp:123
FilamentMapMode
Definition PrintConfig.hpp:632
@ fmmManual
Definition PrintConfig.hpp:635

References config(), Slic3r::GUI::filament_types, Slic3r::fmmManual, Slic3r::GUI::PartPlate::get_extruders(), Slic3r::GUI::PartPlate::get_filament_map_mode(), Slic3r::GUI::FilamentMapDialog::get_filament_maps(), Slic3r::GUI::FilamentMapDialog::get_filament_volume_maps(), Slic3r::GUI::FilamentMapDialog::get_mode(), Slic3r::GUI::PartPlate::get_real_filament_maps(), Slic3r::GUI::PartPlate::get_real_filament_volume_maps(), Slic3r::ConfigBase::option(), p, Slic3r::ConfigOptionVector< T >::resize(), Slic3r::GUI::PartPlate::set_filament_map_mode(), Slic3r::GUI::PartPlate::set_filament_maps(), Slic3r::GUI::PartPlate::set_filament_volume_maps(), set_plater_dirty(), Slic3r::GUI::FilamentMapDialog::ShowModal(), Slic3r::ConfigOptionVector< T >::size(), update(), and Slic3r::GUI::PartPlate::update_slice_result_valid_state().

Here is the call graph for this function:

◆ open_platesettings_dialog()

void Slic3r::GUI::Plater::open_platesettings_dialog ( wxCommandEvent & evt)
23103 {
23104 int plate_index = evt.GetInt();
23105 PlateSettingsDialog dlg(this, _L("Plate Settings"), evt.GetString() == "only_layer_sequence");
23106 PartPlate* curr_plate = p->partplate_list.get_curr_plate();
23107 dlg.sync_bed_type(curr_plate->get_bed_type());
23108
23109 auto curr_print_seq = curr_plate->get_print_seq();
23110 if (curr_print_seq != PrintSequence::ByDefault) {
23111 dlg.sync_print_seq(int(curr_print_seq) + 1);
23112 }
23113 else
23114 dlg.sync_print_seq(0);
23115
23116 auto first_layer_print_seq = curr_plate->get_first_layer_print_sequence();
23117 if (first_layer_print_seq.empty())
23118 dlg.sync_first_layer_print_seq(0);
23119 else
23120 dlg.sync_first_layer_print_seq(1, curr_plate->get_first_layer_print_sequence());
23121
23122 auto other_layers_print_seq = curr_plate->get_other_layers_print_sequence();
23123 if (other_layers_print_seq.empty())
23124 dlg.sync_other_layers_print_seq(0, {});
23125 else {
23126 dlg.sync_other_layers_print_seq(1, curr_plate->get_other_layers_print_sequence());
23127 }
23128
23129 dlg.sync_spiral_mode(curr_plate->get_spiral_vase_mode(), !curr_plate->has_spiral_mode_config());
23130
23131 dlg.Bind(EVT_SET_BED_TYPE_CONFIRM, [this, plate_index, &dlg](wxCommandEvent& e) {
23132 PartPlate* curr_plate = p->partplate_list.get_curr_plate();
23133 BedType old_bed_type = curr_plate->get_bed_type();
23134 auto bt_sel = dlg.get_bed_type_choice();
23135 if (old_bed_type != bt_sel) {
23136 curr_plate->set_bed_type(bt_sel);
23138 set_plater_dirty(true);
23139 }
23140 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select bed type %1% for plate %2% at plate side") % bt_sel % plate_index;
23141
23142 if (dlg.get_first_layer_print_seq_choice() != 0)
23143 curr_plate->set_first_layer_print_sequence(dlg.get_first_layer_print_seq());
23144 else
23145 curr_plate->set_first_layer_print_sequence({});
23146
23147 if (dlg.get_other_layers_print_seq_choice() != 0)
23148 curr_plate->set_other_layers_print_sequence(dlg.get_other_layers_print_seq_infos());
23149 else
23150 curr_plate->set_other_layers_print_sequence({});
23151
23152 int ps_sel = dlg.get_print_seq_choice();
23153 if (ps_sel != 0)
23154 curr_plate->set_print_seq(PrintSequence(ps_sel - 1));
23155 else
23156 curr_plate->set_print_seq(PrintSequence::ByDefault);
23157
23158 int spiral_sel = dlg.get_spiral_mode_choice();
23159 if (spiral_sel == 1) {
23160 curr_plate->set_spiral_vase_mode(true, false);
23161 }
23162 else if (spiral_sel == 2) {
23163 curr_plate->set_spiral_vase_mode(false, false);
23164 }
23165 else {
23166 curr_plate->set_spiral_vase_mode(false, true);
23167 }
23168
23170 set_plater_dirty(true);
23171 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select print sequence %1% for plate %2% at plate side") % ps_sel % plate_index;
23172 auto plate_config = *(curr_plate->config());
23173 wxGetApp().plater()->config_change_notification(plate_config, std::string("print_sequence"));
23174 update();
23175 wxGetApp().obj_list()->update_selections();
23176 });
23177 dlg.set_plate_name(from_u8(curr_plate->get_plate_name()));
23178
23179 dlg.ShowModal();
23180 curr_plate->set_plate_name(dlg.get_plate_name().ToUTF8().data());
23181}
PrintSequence
Definition PrintConfig.hpp:310
@ ByDefault
Definition PrintConfig.hpp:313

References _L, Slic3r::ByDefault, Slic3r::GUI::PartPlate::config(), Slic3r::GUI::from_u8(), Slic3r::GUI::PartPlate::get_bed_type(), Slic3r::GUI::PlateSettingsDialog::get_bed_type_choice(), Slic3r::GUI::PlateSettingsDialog::get_first_layer_print_seq(), Slic3r::GUI::PlateSettingsDialog::get_first_layer_print_seq_choice(), Slic3r::GUI::PartPlate::get_first_layer_print_sequence(), Slic3r::GUI::PlateSettingsDialog::get_other_layers_print_seq_choice(), Slic3r::GUI::PlateSettingsDialog::get_other_layers_print_seq_infos(), Slic3r::GUI::PartPlate::get_other_layers_print_sequence(), Slic3r::GUI::PartPlate::get_plate_name(), Slic3r::GUI::PlateSettingsDialog::get_plate_name(), Slic3r::GUI::PartPlate::get_print_seq(), Slic3r::GUI::PlateSettingsDialog::get_print_seq_choice(), Slic3r::GUI::PlateSettingsDialog::get_spiral_mode_choice(), Slic3r::GUI::PartPlate::get_spiral_vase_mode(), Slic3r::GUI::PartPlate::has_spiral_mode_config(), p, Slic3r::GUI::PartPlate::set_bed_type(), Slic3r::GUI::PartPlate::set_first_layer_print_sequence(), Slic3r::GUI::PartPlate::set_other_layers_print_sequence(), Slic3r::GUI::PartPlate::set_plate_name(), Slic3r::GUI::PlateSettingsDialog::set_plate_name(), set_plater_dirty(), Slic3r::GUI::PartPlate::set_print_seq(), Slic3r::GUI::PartPlate::set_spiral_vase_mode(), Slic3r::GUI::DPIAware< P >::ShowModal(), Slic3r::GUI::PlateSettingsDialog::sync_bed_type(), Slic3r::GUI::PlateSettingsDialog::sync_first_layer_print_seq(), Slic3r::GUI::PlateSettingsDialog::sync_other_layers_print_seq(), Slic3r::GUI::PlateSettingsDialog::sync_print_seq(), Slic3r::GUI::PlateSettingsDialog::sync_spiral_mode(), update(), and update_project_dirty_from_presets().

Here is the call graph for this function:

◆ operator=() [1/2]

Plater & Slic3r::GUI::Plater::operator= ( const Plater & )
delete

References Plater().

Here is the call graph for this function:

◆ operator=() [2/2]

Plater & Slic3r::GUI::Plater::operator= ( Plater && )
delete

References Plater().

Here is the call graph for this function:

◆ optimize_rotation()

void Slic3r::GUI::Plater::optimize_rotation ( )
22339{
22340 auto &w = get_ui_job_worker();
22341 if (w.is_idle()) {
22342 p->take_snapshot(_u8L("Optimize Rotation"));
22343 replace_job(w, std::make_unique<OrientJob>());
22344 }
22345}

References _u8L, get_ui_job_worker(), p, and Slic3r::GUI::replace_job().

Here is the call graph for this function:

◆ orient()

void Slic3r::GUI::Plater::orient ( )
14539{
14540 auto &w = get_ui_job_worker();
14541 if (w.is_idle()) {
14542 p->take_snapshot(_u8L("Orient"));
14543 replace_job(w, std::make_unique<OrientJob>());
14544 }
14545}

References _u8L, get_ui_job_worker(), p, and Slic3r::GUI::replace_job().

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), and select_plate_by_hover_id().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ part_menu()

wxMenu * Slic3r::GUI::Plater::part_menu ( )
24124{ return p->menus.part_menu(); }

References p.

◆ paste_from_clipboard()

void Slic3r::GUI::Plater::paste_from_clipboard ( )
22440{
22442 return;
22443
22444 Plater::TakeSnapshot snapshot(this, "Paste From Clipboard");
22445
22446 // At first try to paste values from the ObjectList's clipboard
22447 // to check if Settings or Layers were copied
22448 // and then paste from the 3DCanvas's clipboard if not
22449 if (!p->sidebar->obj_list()->paste_from_clipboard())
22450 p->view3D->get_canvas3d()->get_selection().paste_from_clipboard();
22451}
bool can_paste_from_clipboard() const
Definition Plater.cpp:23894

References can_paste_from_clipboard(), and p.

Here is the call graph for this function:

◆ physical_filament_config_indices()

std::vector< size_t > Slic3r::GUI::Plater::physical_filament_config_indices ( ) const
15716{
15717 std::vector<size_t> indices;
15718 auto& config = wxGetApp().preset_bundle->project_config;
15719 auto* opt = config.option<ConfigOptionBools>("filament_is_mixed");
15720 size_t total = wxGetApp().preset_bundle->filament_presets.size();
15721 for (size_t i = 0; i < total; ++i) {
15722 if (!opt || i >= opt->values.size() || !opt->values[i])
15723 indices.push_back(i);
15724 }
15725 return indices;
15726}
size_t size() const override
Definition Config.hpp:722

References config().

Here is the call graph for this function:

◆ plate_menu()

wxMenu * Slic3r::GUI::Plater::plate_menu ( )
24122{ return p->menus.plate_menu(); }

References p.

◆ plate_toolbar_image_version()

unsigned Slic3r::GUI::Plater::plate_toolbar_image_version ( ) const
inline

◆ plugins_block_slicing()

bool Slic3r::GUI::Plater::plugins_block_slicing ( ) const
23097{
23098 // Single source of truth: slicing is blocked while PluginResolver still has unresolved plugin
23099 // references — missing (download), inactive (activate), or broken (capability unavailable).
23101}
bool has_inactive_plugins()
Definition PluginResolver.cpp:354
bool has_broken_plugins()
Definition PluginResolver.cpp:373
bool has_missing_plugins()
Definition PluginResolver.cpp:335

References Slic3r::has_broken_plugins(), Slic3r::has_inactive_plugins(), and Slic3r::has_missing_plugins().

Here is the call graph for this function:

◆ pop_warning_and_go_to_device_page()

void Slic3r::GUI::Plater::pop_warning_and_go_to_device_page ( wxString printer_name,
PrinterWarningType type,
const wxString & title )
22355{
22356 printer_name.Replace("Bambu Lab", "", false);
22357 wxString content;
22358 MainFrame* frame = wxGetApp().mainframe;
22359 bool device_page = frame != nullptr && frame->m_monitor_page->in_book();
22361 if (device_page) {
22362 content = wxString::Format(_L("Printer not connected. Please go to the device page to connect %s before syncing."),
22363 printer_name);
22364 } else {
22365 content = wxString::Format(
22366 _L("OrcaSlicer can't connect to %s. Please check if the printer is powered on and connected to the network."), printer_name);
22367 }
22368 } else if (type == PrinterWarningType::INCONSISTENT) {
22369 content = wxString::Format(_L("The currently connected printer on the device page is not %s. Please switch to %s before syncing."), printer_name, printer_name);
22370 } else if (type == PrinterWarningType::UNINSTALL_FILAMENT) {
22371 content = _L("There are no filaments on the printer. Please load the filaments on the printer first.");
22372 } else if (type == PrinterWarningType::EMPTY_FILAMENT) {
22373 content = _L("The filaments on the printer are all unknown types. Please go to the printer screen or software device page to set the filament type.");
22374 }
22375 MessageDialog dlg(this, content, title, wxOK | wxFORWARD | wxICON_WARNING, _L("Device Page"));
22376 auto result = dlg.ShowModal();
22377 if (result == wxFORWARD) {
22378 wxGetApp().mainframe->select_tab(TAB_ID_MONITOR);
22379 }
22380}
#define TAB_ID_MONITOR
Definition MainFrame.hpp:62
@ UNINSTALL_FILAMENT
Definition Plater.hpp:692
@ EMPTY_FILAMENT
Definition Plater.hpp:693

References _L, EMPTY_FILAMENT, INCONSISTENT, Slic3r::GUI::MainFrame::m_monitor_page, NOT_CONNECTED, Slic3r::GUI::DPIAware< P >::ShowModal(), TAB_ID_MONITOR, and UNINSTALL_FILAMENT.

Referenced by check_printer_initialized(), and is_same_printer_for_connected_and_selected().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PopupMenu() [1/2]

bool Slic3r::GUI::Plater::PopupMenu ( wxMenu * menu,
const wxPoint & pos = wxDefaultPosition )
24010{
24011 // Don't want to wake up and trigger reslicing while tracking the pop-up menu.
24013 // When tracking a pop-up menu, postpone error messages from the slicing result.
24014 m_tracking_popup_menu = true;
24015 bool out = wxGetApp().mainframe->PopupMenu(menu, pos);
24016 m_tracking_popup_menu = false;
24018 // Don't know whether the CallAfter is necessary, but it should not hurt.
24019 // The menus likely sends out some commands, so we may be safer if the dialog is shown after the menu command is processed.
24020 wxString message = std::move(m_tracking_popup_menu_error_message);
24021 wxTheApp->CallAfter([message, this]() { show_error(this, message); });
24023 }
24024 return out;
24025}
friend class SuppressBackgroundProcessingUpdate
Definition Plater.hpp:1125
wxString m_tracking_popup_menu_error_message
Definition Plater.hpp:1090
bool m_tracking_popup_menu
Definition Plater.hpp:1089

References m_tracking_popup_menu, m_tracking_popup_menu_error_message, Slic3r::GUI::show_error(), and SuppressBackgroundProcessingUpdate.

Here is the call graph for this function:

◆ PopupMenu() [2/2]

bool Slic3r::GUI::Plater::PopupMenu ( wxMenu * menu,
int x,
int y )
inline
1038{ return this->PopupMenu(menu, wxPoint(x, y)); }
bool PopupMenu(wxMenu *menu, const wxPoint &pos=wxDefaultPosition)
Definition Plater.cpp:24009

References PopupMenu().

Referenced by PopupMenu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PopupObjectTable()

bool Slic3r::GUI::Plater::PopupObjectTable ( int object_id,
int volume_id,
const wxPoint & position )
24044{
24045 if (dynamic_cast<TabPrinter *>(wxGetApp().get_tab(Preset::TYPE_PRINTER))->m_extruders_count > 1) {
24046 MessageDialog dlg(this, _L("Currently, the object configuration form cannot be used with a multiple-extruder printer."), _L("Not available"), wxOK | wxICON_WARNING);
24047 dlg.ShowModal();
24048 return false;
24049 }
24050 return p->PopupObjectTable(object_id, volume_id, position);
24051}

References _L, p, Slic3r::GUI::DPIAware< P >::ShowModal(), and Slic3r::Preset::TYPE_PRINTER.

Here is the call graph for this function:

◆ PopupObjectTableBySelection()

bool Slic3r::GUI::Plater::PopupObjectTableBySelection ( )
24054{
24055 wxDataViewItem item;
24056 int obj_idx, vol_idx;
24057 const wxPoint pos = wxPoint(0, 0); //Fake position
24058 wxGetApp().obj_list()->get_selected_item_indexes(obj_idx, vol_idx, item);
24059 return p->PopupObjectTable(obj_idx, vol_idx, pos);
24060}
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:16

References p.

◆ post_process_string_object_exception()

void Slic3r::GUI::Plater::post_process_string_object_exception ( StringObjectException & err)
23696{
23697 PresetBundle* preset_bundle = wxGetApp().preset_bundle;
23699 try {
23700 int extruder_id = atoi(err.params[2].c_str()) - 1;
23701 if (extruder_id < preset_bundle->filament_presets.size()) {
23702 std::string filament_name = preset_bundle->filament_presets[extruder_id];
23703 // ORCA: Prefer the selected preset's alias/name and trim any @Printer suffix for display.
23704 for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) {
23705 if (filament_it->name == filament_name) {
23706 if (!filament_it->alias.empty()) {
23707 filament_name = filament_it->alias;
23708 } else {
23709 char target = '@';
23710 size_t pos = filament_name.find(target);
23711 if (pos != std::string::npos) {
23712 filament_name = filament_name.substr(0, pos - 1);
23713 }
23714 }
23715 break;
23716 }
23717 }
23718 err.string = format(_L("Plate %d: %s is not suggested for use printing filament %s (%s). If you still want to do this print job, please set this filament\'s bed temperature to a number that is not zero."),
23719 err.params[0], err.params[1], err.params[2], filament_name);
23720 err.string += "\n";
23721 }
23722 } catch (...) {
23723 ;
23724 }
23725 }
23726
23727 return;
23728}
@ STRING_EXCEPT_FILAMENT_NOT_MATCH_BED_TYPE
Definition PrintBase.hpp:28

References _L, Slic3r::PresetCollection::begin(), Slic3r::PresetCollection::end(), Slic3r::PresetBundle::filament_presets, Slic3r::PresetBundle::filaments, Slic3r::GUI::format(), Slic3r::StringObjectException::params, Slic3r::StringObjectException::string, Slic3r::STRING_EXCEPT_FILAMENT_NOT_MATCH_BED_TYPE, and Slic3r::StringObjectException::type.

Referenced by validate_current_plate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ preview_zip_archive()

bool Slic3r::GUI::Plater::preview_zip_archive ( const boost::filesystem::path & archive_path)
18417{
18418 //std::vector<fs::path> unzipped_paths;
18419 std::vector<fs::path> non_project_paths;
18420 std::vector<fs::path> project_paths;
18421 try
18422 {
18423 mz_zip_archive archive;
18424 mz_zip_zero_struct(&archive);
18425
18426 if (!open_zip_reader(&archive, archive_path.string())) {
18427 // TRN %1% is archive path
18428 std::string err_msg = GUI::format(_u8L("Loading of a ZIP archive on path %1% has failed."), archive_path.string());
18429 throw Slic3r::FileIOError(err_msg);
18430 }
18431 mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
18432 mz_zip_archive_file_stat stat;
18433 // selected_paths contains paths and its uncompressed size. The size is used to distinguish between files with same path.
18434 std::vector<std::pair<fs::path, size_t>> selected_paths;
18435 FileArchiveDialog dlg(static_cast<wxWindow*>(wxGetApp().mainframe), &archive, selected_paths);
18436 if (dlg.ShowModal() == wxID_OK)
18437 {
18438 std::string archive_path_string = archive_path.string();
18439 archive_path_string = archive_path_string.substr(0, archive_path_string.size() - 4);
18440 fs::path archive_dir(wxStandardPaths::Get().GetTempDir().utf8_str().data());
18441
18442 for (auto& path_w_size : selected_paths) {
18443 const fs::path& path = path_w_size.first;
18444 size_t size = path_w_size.second;
18445 // find path in zip archive
18446 for (mz_uint i = 0; i < num_entries; ++i) {
18447 if (mz_zip_reader_file_stat(&archive, i, &stat)) {
18448 if (size != stat.m_uncomp_size) // size must fit
18449 continue;
18450 std::string name = Slic3r::decode_archive_entry_path(&archive, stat);
18451 fs::path archive_path(name);
18452
18453 if (archive_path.empty())
18454 continue;
18455 if (path != archive_path)
18456 continue;
18457 // decompressing
18458 try
18459 {
18460 std::replace(name.begin(), name.end(), '\\', '/');
18461 // rename if file exists
18462 std::string filename = path.filename().string();
18463 std::string extension = path.extension().string();
18464 std::string just_filename = filename.substr(0, filename.size() - extension.size());
18465 std::string final_filename = just_filename;
18466
18467 size_t version = 0;
18468 while (fs::exists(archive_dir / (final_filename + extension)))
18469 {
18470 ++version;
18471 final_filename = just_filename + "(" + std::to_string(version) + ")";
18472 }
18473 filename = final_filename + extension;
18474 fs::path final_path = archive_dir / filename;
18475 std::string buffer((size_t)stat.m_uncomp_size, 0);
18476 // Decompress action. We already has correct file index in stat structure.
18477 mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
18478 if (res == 0) {
18479 // TRN: First argument = path to file, second argument = error description
18480 wxString error_log = GUI::format_wxstr(_L("Failed to unzip file to %1%: %2%"), final_path.string(), mz_zip_get_error_string(mz_zip_get_last_error(&archive)));
18481 BOOST_LOG_TRIVIAL(error) << error_log;
18482 show_error(nullptr, error_log);
18483 break;
18484 }
18485 // write buffer to file
18486 fs::fstream file(final_path, std::ios::out | std::ios::binary | std::ios::trunc);
18487 file.write(buffer.c_str(), buffer.size());
18488 file.close();
18489 if (!fs::exists(final_path)) {
18490 wxString error_log = GUI::format_wxstr(_L("Failed to find unzipped file at %1%. Unzipping of file has failed."), final_path.string());
18491 BOOST_LOG_TRIVIAL(error) << error_log;
18492 show_error(nullptr, error_log);
18493 break;
18494 }
18495 BOOST_LOG_TRIVIAL(info) << "Unzipped " << final_path;
18496 if (!boost::algorithm::iends_with(filename, ".3mf") && !boost::algorithm::iends_with(filename, ".amf")) {
18497 non_project_paths.emplace_back(final_path);
18498 break;
18499 }
18500 // if 3mf - read archive headers to find project file
18501 if (/*(boost::algorithm::iends_with(filename, ".3mf") && !is_project_3mf(final_path.string())) ||*/
18502 (boost::algorithm::iends_with(filename, ".amf") && !boost::algorithm::iends_with(filename, ".zip.amf"))) {
18503 non_project_paths.emplace_back(final_path);
18504 break;
18505 }
18506
18507 project_paths.emplace_back(final_path);
18508 break;
18509 }
18510 catch (const std::exception& e)
18511 {
18512 // ensure the zip archive is closed and rethrow the exception
18513 close_zip_reader(&archive);
18514 throw Slic3r::FileIOError(e.what());
18515 }
18516 }
18517 }
18518 }
18519 close_zip_reader(&archive);
18520 if (non_project_paths.size() + project_paths.size() != selected_paths.size())
18521 BOOST_LOG_TRIVIAL(error) << "Decompresing of archive did not retrieve all files. Expected files: "
18522 << selected_paths.size()
18523 << " Decopressed files: "
18524 << non_project_paths.size() + project_paths.size();
18525 } else {
18526 close_zip_reader(&archive);
18527 return false;
18528 }
18529
18530 }
18531 catch (const Slic3r::FileIOError& e) {
18532 // zip reader should be already closed or not even opened
18533 GUI::show_error(this, e.what());
18534 return false;
18535 }
18536 // none selected
18537 if (project_paths.empty() && non_project_paths.empty())
18538 {
18539 return false;
18540 }
18541
18542 // 1 project file and some models - behave like drag n drop of 3mf and then load models
18543 if (project_paths.size() == 1)
18544 {
18545 wxArrayString aux;
18546 aux.Add(from_u8(project_paths.front().string()));
18547 bool loaded3mf = load_files(aux);
18548 load_files(non_project_paths, LoadStrategy::LoadModel);
18549 boost::system::error_code ec;
18550 if (loaded3mf) {
18551 fs::remove(project_paths.front(), ec);
18552 if (ec)
18553 BOOST_LOG_TRIVIAL(error) << ec.message();
18554 }
18555 for (const fs::path& path : non_project_paths) {
18556 // Delete file from temp file (path variable), it will stay only in app memory.
18557 boost::system::error_code ec;
18558 fs::remove(path, ec);
18559 if (ec)
18560 BOOST_LOG_TRIVIAL(error) << ec.message();
18561 }
18562 return true;
18563 }
18564
18565 // load all projects and all models as geometry
18566 load_files(project_paths, LoadStrategy::LoadModel);
18567 load_files(non_project_paths, LoadStrategy::LoadModel);
18568
18569
18570 for (const fs::path& path : project_paths) {
18571 // Delete file from temp file (path variable), it will stay only in app memory.
18572 boost::system::error_code ec;
18573 fs::remove(path, ec);
18574 if (ec)
18575 BOOST_LOG_TRIVIAL(error) << ec.message();
18576 }
18577 for (const fs::path& path : non_project_paths) {
18578 // Delete file from temp file (path variable), it will stay only in app memory.
18579 boost::system::error_code ec;
18580 fs::remove(path, ec);
18581 if (ec)
18582 BOOST_LOG_TRIVIAL(error) << ec.message();
18583 }
18584
18585 return true;
18586}
bool open_zip_reader(mz_zip_archive *zip, const std::string &fname)
Definition miniz_extension.cpp:119
bool close_zip_reader(mz_zip_archive *zip)
Definition miniz_extension.cpp:129
std::string decode_archive_entry_path(mz_zip_archive *zip, const mz_zip_archive_file_stat &stat)
Definition miniz_extension.cpp:162

References _L, _u8L, Slic3r::close_zip_reader(), Slic3r::decode_archive_entry_path(), Slic3r::GUI::format(), Slic3r::GUI::format_wxstr(), Slic3r::GUI::from_u8(), load_files(), Slic3r::LoadModel, Slic3r::open_zip_reader(), Slic3r::GUI::show_error(), and Slic3r::GUI::DPIAware< P >::ShowModal().

Referenced by load_files().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_job_finished()

void Slic3r::GUI::Plater::print_job_finished ( wxCommandEvent & evt)
21227{
21228 //start print failed
21229 if (p) {
21230#ifdef __APPLE__
21231 p->hide_select_machine_dlg();
21232#else
21233 if (Slic3r::GUI::wxGetApp().get_inf_dialog_contect().empty()) {
21234 p->hide_select_machine_dlg();
21235 } else {
21236 p->enter_prepare_mode();
21237 }
21238#endif // __APPLE__
21239 }
21240
21241
21242 Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
21243 if (!dev) return;
21244
21245 const std::string dev_id = evt.GetString().ToStdString();
21246 MachineObject* selected = dev->get_selected_machine();
21247 // After a LAN print, the completion event reselects the same printer.
21248 // Keep the active session while asynchronous status traffic may still be in flight.
21249 if (!selected || selected->get_dev_id() != dev_id || selected->connection_type() != "lan")
21250 dev->set_selected_machine(dev_id);
21251 p->main_frame->request_select_tab(TAB_ID_MONITOR);
21252 // Selects the status page on a built Device tab; one built by the switch starts there.
21253 MonitorPanel* curr_monitor = MonitorPanel::if_built();
21254 if(curr_monitor)
21255 curr_monitor->get_tabpanel()->ChangeSelection(MonitorPanel::PrinterTab::PT_STATUS);
21256}
bool set_selected_machine(std::string dev_id)
Definition DevManager.cpp:636
MachineObject * get_selected_machine()
Definition DevManager.cpp:747
static MonitorPanel * if_built()
Definition Lazy.hpp:183
@ PT_STATUS
Definition Monitor.hpp:111

References Tabbook::ChangeSelection(), Slic3r::MachineObject::connection_type(), Slic3r::empty(), Slic3r::MachineObject::get_dev_id(), Slic3r::DeviceManager::get_selected_machine(), Slic3r::GUI::MonitorPanel::get_tabpanel(), Slic3r::GUI::LazyInstance< MonitorPanel >::if_built(), p, Slic3r::GUI::MonitorPanel::PT_STATUS, Slic3r::DeviceManager::set_selected_machine(), and TAB_ID_MONITOR.

Here is the call graph for this function:

◆ printer_technology()

PrinterTechnology Slic3r::GUI::Plater::printer_technology ( ) const
22156{
22157 return p->printer_technology;
22158}

References p.

Referenced by export_gcode(), export_toolpaths_to_obj(), reslice(), set_printer_technology(), Slic3r::GUI::MainFrame::technology_changed(), and Slic3r::GUI::MainFrame::update_menubar().

Here is the caller graph for this function:

◆ redo()

void Slic3r::GUI::Plater::redo ( )
21297{ p->redo(); }

References p.

◆ redo_to()

void Slic3r::GUI::Plater::redo_to ( int selection)
21309{
21310 if (selection == 0) {
21311 p->redo();
21312 return;
21313 }
21314
21315 const int idx = p->get_active_snapshot_index() + selection + 1;
21316 p->undo_redo_to(p->undo_redo_stack().snapshots()[idx].timestamp);
21317}

References p.

◆ refresh_belt_view()

void Slic3r::GUI::Plater::refresh_belt_view ( )
18338{
18339 p->preview->refresh_belt_view();
18340}

References p.

◆ refresh_missing_plugin_block()

bool Slic3r::GUI::Plater::refresh_missing_plugin_block ( bool * block_toggled = nullptr)
22923{
22924 // PluginResolver owns the per-preset-type missing sets; rebuild them from each preset's own
22925 // "plugins" manifest so the state is always fresh. A plugin is resolved when it is
22926 // installed/loaded, or when no active setting references it any more (refresh drops it then).
22927 // The block is derived solely from PluginResolver; snapshot it before the refresh to detect a
22928 // toggle (so the caller can refresh the Slice button).
22929 const bool was_blocked = has_missing_plugins() || has_inactive_plugins() || has_broken_plugins();
22930 refresh_missing_plugins(*wxGetApp().preset_bundle);
22931
22932 const auto missing_refs = [](const std::vector<MissingPlugin>& missing) {
22933 std::vector<std::string> refs;
22934 refs.reserve(missing.size());
22935 for (const MissingPlugin& m : missing)
22936 refs.emplace_back(create_full_ref(m.ref));
22937 return refs;
22938 };
22939
22940 const auto signature = [&missing_refs](const std::vector<MissingPlugin>& missing) {
22941 std::vector<std::string> refs = missing_refs(missing);
22942 std::sort(refs.begin(), refs.end());
22943 std::string sig;
22944 for (const std::string& r : refs) { sig += r; sig += '\n'; }
22945 return sig;
22946 };
22947
22948 // Show/refresh the non-closable notification for one missing set. Only (re)create it when the
22949 // set changes; pushing every validate would close+recreate it (flicker, reset hover) since
22950 // validate runs on many triggers. shown_sig also gates plugin-load re-validation.
22951 const auto update = [&](NotificationType type, const std::vector<MissingPlugin>& missing,
22952 std::string* shown_sig, const std::string& header,
22953 const std::string& resolve_label,
22954 std::function<bool(wxEvtHandler*)> resolve_action) {
22955 if (missing.empty()) {
22956 if (!shown_sig->empty()) {
22957 p->notification_manager->close_notification_of_type(type);
22958 shown_sig->clear();
22959 }
22960 return;
22961 }
22962 const std::string sig = signature(missing);
22963 if (*shown_sig != sig) {
22964 std::vector<JumpTo> body;
22965 for (const auto& m : missing)
22966 body.emplace_back(JumpTo{m.ref.capability_name, m.opt, m.opt_type});
22967
22968 p->notification_manager->push_plugin_missing_notification(
22969 type, header, resolve_label, std::move(body), std::move(resolve_action));
22970 *shown_sig = sig;
22971 }
22972 };
22973
22974 const std::vector<MissingPlugin> missing_cloud = get_missing_cloud_plugins();
22975 const std::vector<MissingPlugin> missing_local = get_missing_local_plugins();
22976 const std::vector<std::string> missing_cloud_refs = missing_refs(missing_cloud);
22977 const std::vector<std::string> missing_local_refs = missing_refs(missing_local);
22978
22980 &p->m_cloud_missing_shown_sig,
22981 _u8L("OrcaCloud plugins required by the current preset are not installed:"),
22982 _u8L("Install Plugins"),
22983 [this, missing_cloud_refs](wxEvtHandler*) { install_missing_cloud_plugins(missing_cloud_refs); return false; });
22984 // "Find on OrcaCloud" is only a suggestion: it opens the browser but cannot resolve the missing
22985 // plugin in-session, so it never closes the notification or unblocks slicing. The user resolves a
22986 // local plugin by installing it or by changing the setting that needs it.
22988 &p->m_local_missing_shown_sig,
22989 _u8L("Local plugins required by the current preset are missing:"),
22990 _u8L("Find on OrcaCloud"),
22991 [missing_local_refs](wxEvtHandler*) { open_missing_plugins_on_cloud(missing_local_refs); return false; });
22992
22993 const std::vector<MissingPlugin> inactive = get_inactive_plugins();
22994 const std::vector<MissingPlugin> broken = get_broken_plugins();
22995 const std::vector<std::string> inactive_refs = missing_refs(inactive);
22996 const std::vector<std::string> broken_refs = missing_refs(broken);
22997
22999 &p->m_inactive_shown_sig,
23000 _u8L("Plugins required by the current preset are not activated:"),
23001 _u8L("Activate Now"),
23002 [this, inactive_refs](wxEvtHandler*) { enable_inactive_plugins(inactive_refs); return false; });
23004 &p->m_broken_shown_sig,
23005 _u8L("The installed plugin does not provide the required capability — it may be outdated:"),
23006 _u8L("Find on OrcaCloud"),
23007 [broken_refs](wxEvtHandler*) { open_missing_plugins_on_cloud(broken_refs); return false; });
23008
23009 const bool blocked = has_missing_plugins() || has_inactive_plugins() || has_broken_plugins();
23010 if (block_toggled)
23011 *block_toggled = (was_blocked != blocked);
23012 return blocked;
23013}
void install_missing_cloud_plugins(const std::vector< std::string > &cloud_refs)
Definition Plater.cpp:23026
void enable_inactive_plugins(const std::vector< std::string > &refs)
Definition Plater.cpp:23087
NotificationType
Definition NotificationManager.hpp:65
@ OrcaPluginCapabilityUnavailableError
Definition NotificationManager.hpp:199
@ OrcaCloudPluginMissingError
Definition NotificationManager.hpp:193
@ OrcaLocalPluginMissingError
Definition NotificationManager.hpp:192
@ OrcaPluginInactiveError
Definition NotificationManager.hpp:196
void refresh_missing_plugins(const PresetBundle &preset_bundle)
Definition PluginResolver.cpp:238
std::vector< MissingPlugin > get_broken_plugins()
Definition PluginResolver.cpp:363
std::vector< MissingPlugin > get_missing_local_plugins()
Definition PluginResolver.cpp:324
void open_missing_plugins_on_cloud(const std::vector< std::string > &local_refs)
Definition PluginResolver.cpp:484
std::vector< MissingPlugin > get_missing_cloud_plugins()
Definition PluginResolver.cpp:313
std::string create_full_ref(const PluginCapabilityRef &ref)
Definition PluginResolver.cpp:213
std::vector< MissingPlugin > get_inactive_plugins()
Definition PluginResolver.cpp:344

References _u8L, Slic3r::create_full_ref(), enable_inactive_plugins(), Slic3r::get_broken_plugins(), Slic3r::get_inactive_plugins(), Slic3r::get_missing_cloud_plugins(), Slic3r::get_missing_local_plugins(), Slic3r::has_broken_plugins(), Slic3r::has_inactive_plugins(), Slic3r::has_missing_plugins(), install_missing_cloud_plugins(), Slic3r::open_missing_plugins_on_cloud(), Slic3r::GUI::OrcaCloudPluginMissingError, Slic3r::GUI::OrcaLocalPluginMissingError, Slic3r::GUI::OrcaPluginCapabilityUnavailableError, Slic3r::GUI::OrcaPluginInactiveError, p, Slic3r::refresh_missing_plugins(), and update().

Referenced by reslice(), and validate_current_plate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reload_all_from_disk()

void Slic3r::GUI::Plater::reload_all_from_disk ( )
20713{
20714 p->reload_all_from_disk();
20715}

References p.

◆ reload_from_disk()

void Slic3r::GUI::Plater::reload_from_disk ( )
20698{
20699 p->reload_from_disk();
20700}

References p.

Referenced by Slic3r::GUI::Plater::priv::reload_all_from_disk().

Here is the caller graph for this function:

◆ reload_gcode_from_disk()

void Slic3r::GUI::Plater::reload_gcode_from_disk ( )
18326{
18327 wxString filename(m_last_loaded_gcode);
18328 m_last_loaded_gcode.clear();
18329 load_gcode(filename);
18330}

References load_gcode(), and m_last_loaded_gcode.

Here is the call graph for this function:

◆ reload_paint_after_background_process_apply()

void Slic3r::GUI::Plater::reload_paint_after_background_process_apply ( )
19121 {
19122 p->preview->set_reload_paint_after_background_process_apply(true);
19123}

References p.

◆ reload_print()

void Slic3r::GUI::Plater::reload_print ( )
18333{
18334 p->preview->reload_print();
18335}

References p.

Referenced by select_plate(), and select_plate_by_hover_id().

Here is the caller graph for this function:

◆ remove()

void Slic3r::GUI::Plater::remove ( size_t obj_idx)
19185{ p->remove(obj_idx); }

References p.

Referenced by Slic3r::GUI::GLGizmoEmboss::close(), convert_unit(), decrease_instances(), and Slic3r::GUI::Plater::priv::split_object().

Here is the caller graph for this function:

◆ remove_curr_plate_all()

void Slic3r::GUI::Plater::remove_curr_plate_all ( )
19179{ p->remove_curr_plate_all(); }

References p.

◆ remove_dock_pane()

void Slic3r::GUI::Plater::remove_dock_pane ( wxWindow * window)
19169{ p->remove_dock_pane(window); }

References p.

◆ remove_dock_panes()

void Slic3r::GUI::Plater::remove_dock_panes ( )
19171{
19172 while (!p->m_dock_panes.empty())
19173 p->remove_dock_pane(p->m_dock_panes.begin()->first);
19174}

References p.

◆ remove_selected()

void Slic3r::GUI::Plater::remove_selected ( )
19268{
19269 /*if (p->get_selection().is_empty())
19270 return;*/
19271 if (p->get_curr_selection().is_empty())
19272 return;
19273
19274 // BBS: check before deleting object
19275 if (!p->can_delete())
19276 return;
19277
19278 Plater::TakeSnapshot snapshot(this, "Delete Selected Objects");
19280
19281 //BBS delete current selected
19282 // p->view3D->delete_selected();
19283 p->get_current_canvas3D()->delete_selected();
19284}
virtual void cancel_all()=0

References Slic3r::GUI::Worker::cancel_all(), get_ui_job_worker(), and p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), and Slic3r::GUI::GLGizmoEmboss::close().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ replace_all_with_stl()

void Slic3r::GUI::Plater::replace_all_with_stl ( )
20708{
20709 p->replace_all_with_stl();
20710}

References p.

◆ replace_with_stl()

void Slic3r::GUI::Plater::replace_with_stl ( )
20703{
20704 p->replace_with_stl();
20705}

References p.

◆ request_download_project()

void Slic3r::GUI::Plater::request_download_project ( std::string project_id)
16607{
16608 wxCommandEvent* event = new wxCommandEvent(EVT_DOWNLOAD_PROJECT);
16609 event->SetString(project_id);
16610 wxQueueEvent(this, event);
16611}

◆ request_model_download()

void Slic3r::GUI::Plater::request_model_download ( wxString url)
16600{
16601 wxCommandEvent* event = new wxCommandEvent(EVT_IMPORT_MODEL_ID);
16602 event->SetString(url);
16603 wxQueueEvent(this, event);
16604}

◆ reset()

void Slic3r::GUI::Plater::reset ( bool apply_presets_change = false,
bool reload_presets = true )
19186{ p->reset(apply_presets_change, reload_presets); }

References p.

Referenced by load_project(), new_project(), and reset_with_confirm().

Here is the caller graph for this function:

◆ reset_canvas_volumes()

void Slic3r::GUI::Plater::reset_canvas_volumes ( )
22151{
22152 p->reset_canvas_volumes();
22153}

References p.

◆ reset_check_status()

void Slic3r::GUI::Plater::reset_check_status ( )
inline
1072{ m_check_status = 0; }

References m_check_status.

◆ reset_gcode_toolpaths()

void Slic3r::GUI::Plater::reset_gcode_toolpaths ( )
23837{
23838 //BBS: add some logs
23839 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": reset the gcode viewer's toolpaths");
23840 p->reset_gcode_toolpaths();
23841}

References p.

Referenced by Slic3r::GUI::Plater::priv::delete_all_objects_from_model(), Slic3r::GUI::Plater::priv::reset(), reslice(), select_plate(), Slic3r::GUI::Plater::priv::set_current_panel(), and Slic3r::GUI::Plater::priv::update_background_process().

Here is the caller graph for this function:

◆ reset_last_loaded_gcode()

void Slic3r::GUI::Plater::reset_last_loaded_gcode ( )
inline
915{ m_last_loaded_gcode = ""; }

References m_last_loaded_gcode.

◆ reset_project_dirty_after_save()

void Slic3r::GUI::Plater::reset_project_dirty_after_save ( )
15666{ p->reset_project_dirty_after_save(); }

References p.

Referenced by new_project(), and save_project().

Here is the caller graph for this function:

◆ reset_project_dirty_initial_presets()

void Slic3r::GUI::Plater::reset_project_dirty_initial_presets ( )
15667{ p->reset_project_dirty_initial_presets(); }

References p.

Referenced by load_gcode(), load_project(), and new_project().

Here is the caller graph for this function:

◆ reset_window_layout()

void Slic3r::GUI::Plater::reset_window_layout ( )
19155{
19156 p->reset_window_layout();
19157#ifdef SLIC3R_CAD
19158 // The Design tab docks its own sidebar.
19159 if (DesignPanel* design = DesignPanel::if_built())
19160 design->reset_window_layout();
19161#endif
19162}

References Slic3r::GUI::LazyInstance< DesignPanel >::if_built(), and p.

Here is the call graph for this function:

◆ reset_with_confirm()

void Slic3r::GUI::Plater::reset_with_confirm ( )
19188{
19189 if (p->model.objects.empty() || MessageDialog(static_cast<wxWindow *>(this), _L("All objects will be removed, continue?"),
19190 wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Delete All"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE)
19191 .ShowModal() == wxID_YES) {
19192 reset();
19193 // BBS: jump to plater panel
19194 wxGetApp().mainframe->select_tab(TAB_ID_HOME);
19195 }
19196}
#define TAB_ID_HOME
Definition MainFrame.hpp:56

References _L, p, reset(), SLIC3R_APP_FULL_NAME, and TAB_ID_HOME.

Here is the call graph for this function:

◆ reslice()

void Slic3r::GUI::Plater::reslice ( )
20753{
20754 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: enter, process_completed_with_error=%2%")%__LINE__ %p->process_completed_with_error;
20755 // There is "invalid data" button instead "slice now"
20756 if (p->process_completed_with_error == p->partplate_list.get_curr_plate_index())
20757 {
20758 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": process_completed_with_error, return directly");
20760 return;
20761 }
20762
20763 // A mixed filament with deleted or type-mismatched components cannot be resolved at slicing
20764 // time. MainFrame::get_enable_slice_status() already disables the Slice button for it, but the
20765 // Preview-tab switch, auto-slice and queued slice events reach reslice() directly, so refuse
20766 // here too instead of letting the engine slice the broken slot as a plain filament.
20767 if (sidebar().has_broken_mixed_filament()) {
20768 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": broken mixed filament detected, refuse to slice";
20769 return;
20770 }
20771
20772 // In case SLA gizmo is in editing mode, refuse to continue
20773 // and notify user that he should leave it first.
20774 if (get_view3D_canvas3D()->get_gizmos_manager().is_in_editing_mode(true))
20775 return;
20776
20777 // Enforce the missing-plugin block at the slicing choke point: menu/keyboard/queued triggers can
20778 // carry a stale enabled state while plugins load asynchronously. refresh_missing_plugin_block
20779 // rebuilds the missing sets and notifications from the active presets without running
20780 // Print::validate; all other validation keeps upstream behavior and is surfaced by
20781 // update_background_process() below.
20783 p->partplate_list.get_curr_plate()->update_slice_ready_status(false);
20784 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false);
20785 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": required plugins missing; slicing blocked.";
20786 return;
20787 }
20788
20789 // Stop the running (and queued) UI jobs and only proceed if they actually
20790 // get stopped.
20791 unsigned timeout_ms = 10000;
20792 if (!stop_queue(this->get_ui_job_worker(), timeout_ms)) {
20793 BOOST_LOG_TRIVIAL(error) << "Could not stop UI job within "
20794 << timeout_ms << " milliseconds timeout!";
20795 return;
20796 }
20797
20798 // Orca: regenerate CalibPressureAdvancePattern custom G-code to apply changes
20799 if (model().calib_pa_pattern) {
20801 }
20802
20803 if (printer_technology() == ptSLA) {
20804 for (auto& object : model().objects)
20805 if (object->sla_points_status == sla::PointsStatus::NoPoints)
20806 object->sla_points_status = sla::PointsStatus::Generating;
20807 }
20808
20809 //FIXME Don't reslice if export of G-code or sending to OctoPrint is running.
20810 // bitmask of UpdateBackgroundProcessReturnState
20811 unsigned int state = this->p->update_background_process(true);
20813 this->p->view3D->reload_scene(false);
20814 // If the SLA processing of just a single object's supports is running, restart slicing for the whole object.
20815 this->p->background_process.set_task(PrintBase::TaskParams());
20816 // Only restarts if the state is valid.
20817 //BBS: jusdge the result
20818 bool result = this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART);
20819
20820 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: restart background,state=%2%, result=%3%")%__LINE__%state %result;
20821 if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) != 0)
20822 {
20823 //BBS: add logs
20824 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": state %1% is UPDATE_BACKGROUND_PROCESS_INVALID, can not slice") % state;
20825 p->update_fff_scene_only_shells();
20826 return;
20827 }
20828
20829 if ((!result) && p->m_slice_all && (p->m_cur_slice_plate < (p->partplate_list.get_plate_count() - 1)))
20830 {
20831 //slice next
20832 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": in slicing all, current plate %1% already sliced, skip to next") % p->m_cur_slice_plate ;
20833 SlicingProcessCompletedEvent evt(EVT_PROCESS_COMPLETED, 0,
20835 // Post the "complete" callback message, so that it will slice the next plate soon
20836 wxQueueEvent(this, evt.Clone());
20837 p->m_is_slicing = true;
20838 if (p->m_cur_slice_plate == 0)
20840 return;
20841 }
20842
20843 if (result) {
20844 p->m_is_slicing = true;
20845 }
20846
20847 bool clean_gcode_toolpaths = true;
20848 // BBS
20849 if (p->background_process.running())
20850 {
20851 //p->ready_to_slice = false;
20852 p->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, false);
20853 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": background process is running, m_is_slicing is true");
20854 }
20855 else if (!p->background_process.empty() && !p->background_process.idle()) {
20856 //p->show_action_buttons(true);
20857 //p->ready_to_slice = true;
20858 p->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, true);
20859 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": background process changes to not_idle, set ready_to_slice back to true");
20860 }
20861 else {
20862 //BBS: add reset logic for empty plate
20863 PartPlate * current_plate = p->background_process.get_current_plate();
20864
20865 if (!current_plate->has_printable_instances()) {
20866 clean_gcode_toolpaths = true;
20867 current_plate->update_slice_result_valid_state(false);
20868 }
20869 else {
20870 clean_gcode_toolpaths = false;
20871 current_plate->update_slice_result_valid_state(true);
20872 }
20873 p->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, false);
20874 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": background process in idle state, use previous result, clean_gcode_toolpaths=%1%")%clean_gcode_toolpaths;
20875 }
20876
20877 if (clean_gcode_toolpaths)
20879
20880 p->preview->reload_print();
20881
20882 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": finished, started slicing for plate %1%") % p->partplate_list.get_curr_plate_index();
20883}
@ eEventSliceUpdate
Definition MainFrame.hpp:340
void reset_gcode_toolpaths()
Definition Plater.cpp:23836
void _calib_pa_pattern_gen_gcode()
Definition Plater.cpp:17078
bool refresh_missing_plugin_block(bool *block_toggled=nullptr)
Definition Plater.cpp:22922
@ Finished
Definition BackgroundSlicingProcess.hpp:54
bool stop_queue(Worker &w, unsigned timeout_ms=0)
Definition Worker.hpp:114
@ NoPoints
Definition SupportPoint.hpp:14
@ Generating
Definition SupportPoint.hpp:15
@ UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE
Definition Plater.cpp:7562
@ UPDATE_BACKGROUND_PROCESS_FORCE_RESTART
Definition Plater.cpp:7567

References _calib_pa_pattern_gen_gcode(), Slic3r::SlicingProcessCompletedEvent::Clone(), Slic3r::GUI::MainFrame::eEventPlateUpdate, Slic3r::GUI::MainFrame::eEventSliceUpdate, Slic3r::SlicingProcessCompletedEvent::Finished, Slic3r::sla::Generating, get_ui_job_worker(), get_view3D_canvas3D(), Slic3r::GUI::PartPlate::has_printable_instances(), model(), Slic3r::sla::NoPoints, p, printer_technology(), Slic3r::ptSLA, refresh_missing_plugin_block(), reset_gcode_toolpaths(), sidebar(), Slic3r::GUI::stop_queue(), Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART, Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_INVALID, Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE, and Slic3r::GUI::PartPlate::update_slice_result_valid_state().

Referenced by select_plate(), Slic3r::GUI::Plater::priv::set_current_panel(), and Slic3r::GUI::Plater::priv::trigger_auto_reslice_now().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reslice_SLA_hollowing()

void Slic3r::GUI::Plater::reslice_SLA_hollowing ( const ModelObject & object,
bool postpone_error_messages = false )
20926{
20927 reslice_SLA_until_step(slaposDrillHoles, object, postpone_error_messages);
20928}
void reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &object, bool postpone_error_messages=false)
Definition Plater.cpp:20930
@ slaposDrillHoles
Definition SLAPrint.hpp:44

References reslice_SLA_until_step(), and Slic3r::slaposDrillHoles.

Here is the call graph for this function:

◆ reslice_SLA_supports()

void Slic3r::GUI::Plater::reslice_SLA_supports ( const ModelObject & object,
bool postpone_error_messages = false )
20921{
20922 reslice_SLA_until_step(slaposPad, object, postpone_error_messages);
20923}
@ slaposPad
Definition SLAPrint.hpp:48

References reslice_SLA_until_step(), and Slic3r::slaposPad.

Here is the call graph for this function:

◆ reslice_SLA_until_step()

void Slic3r::GUI::Plater::reslice_SLA_until_step ( SLAPrintObjectStep step,
const ModelObject & object,
bool postpone_error_messages = false )
20931{
20932 //FIXME Don't reslice if export of G-code or sending to OctoPrint is running.
20933 // bitmask of UpdateBackgroundProcessReturnState
20934 unsigned int state = this->p->update_background_process(true, postpone_error_messages);
20936 this->p->view3D->reload_scene(false);
20937
20938 if (this->p->background_process.empty() || (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID))
20939 // Nothing to do on empty input or invalid configuration.
20940 return;
20941
20942 // Limit calculation to the single object only.
20943 PrintBase::TaskParams task;
20944 task.single_model_object = object.id();
20945 // If the background processing is not enabled, calculate supports just for the single instance.
20946 // Otherwise calculate everything, but start with the provided object.
20947 if (!this->p->background_processing_enabled()) {
20948 task.single_model_instance_only = true;
20949 task.to_object_step = step;
20950 }
20951 this->p->background_process.set_task(task);
20952 // and let the background processing start.
20953 this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART);
20954}

References Slic3r::ObjectID::id, p, Slic3r::PrintBase::TaskParams::single_model_instance_only, Slic3r::PrintBase::TaskParams::single_model_object, Slic3r::PrintBase::TaskParams::to_object_step, Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART, Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_INVALID, and Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE.

Referenced by reslice_SLA_hollowing(), and reslice_SLA_supports().

Here is the caller graph for this function:

◆ revalidate_current_plate_if_plugins_missing()

void Slic3r::GUI::Plater::revalidate_current_plate_if_plugins_missing ( )
23016{
23017 // Only do work while a missing-plugin notification is up, so the plugin-load hook does not
23018 // trigger a full validation for every plugin that loads during normal startup/use.
23019 if (p->m_local_missing_shown_sig.empty() && p->m_cloud_missing_shown_sig.empty() &&
23020 p->m_inactive_shown_sig.empty() && p->m_broken_shown_sig.empty())
23021 return;
23022 bool model_fits = true, validate_error = false;
23023 validate_current_plate(model_fits, validate_error);
23024}
void validate_current_plate(bool &model_fits, bool &validate_error)
Definition Plater.cpp:22798

References p, and validate_current_plate().

Referenced by install_missing_cloud_plugins().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ save_project()

int Slic3r::GUI::Plater::save_project ( bool saveAs = false)
16297{
16298 //if (up_to_date(false, false)) // should we always save
16299 // return;
16300 auto filename = get_project_filename(".3mf");
16301 if (!saveAs && filename.IsEmpty())
16302 saveAs = true;
16303 if (saveAs)
16304 filename = p->get_export_file(FT_3MF);
16305 if (filename.empty())
16306 return wxID_NO;
16307 if (filename == "<cancel>")
16308 return wxID_CANCEL;
16309
16310 //BBS export 3mf without gcode
16312 bool full_pathnames = wxGetApp().app_config->get_bool("export_sources_full_pathnames");
16313 if (full_pathnames) {
16314 save_strategy = save_strategy | SaveStrategy::FullPathSources;
16315 }
16316 {
16317 Slic3r::LifecycleEventContext ctx;
16318 ctx.name = into_u8(filename);
16321 }
16322 if (export_3mf(into_path(filename), save_strategy) < 0) {
16323 MessageDialog(this, _L("Failed to save the project.\nPlease check whether the folder exists online or if other programs have the project file open."),
16324 _L("Save project"), wxOK | wxICON_WARNING).ShowModal();
16325 return wxID_CANCEL;
16326 }
16327 {
16328 Slic3r::LifecycleEventContext ctx;
16329 ctx.name = into_u8(filename);
16332 }
16333
16334 Slic3r::remove_backup(model(), false);
16335
16336 p->set_project_filename(filename);
16337 BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << __LINE__ << " call set_project_filename: " << filename;
16338
16339 up_to_date(true, false);
16340 up_to_date(true, true);
16341
16342 wxGetApp().update_saved_preset_from_current_preset();
16344 try {
16345 json j;
16346 boost::uintmax_t size = boost::filesystem::file_size(into_path(filename));
16347 j["file_size"] = size;
16348 j["file_name"] = std::string(filename.mb_str());
16349
16350 NetworkAgent* agent = wxGetApp().getAgent();
16351 }
16352 catch (...) {}
16353
16355 return wxID_YES;
16356}
wxString get_project_filename(const wxString &extension=wxEmptyString) const
Definition Plater.cpp:22035
void remove_backup(Model &model, bool removeAll)
Definition bbs_3mf.cpp:9774
@ ProjectAfterSave
Definition LifecycleEvents.hpp:24
@ ProjectBeforeSave
Definition LifecycleEvents.hpp:23

References _L, Slic3r::LifecycleEventContext::code, export_3mf(), Slic3r::fire_lifecycle_event(), Slic3r::GUI::FT_3MF, Slic3r::FullPathSources, get_project_filename(), Slic3r::GUI::into_path(), Slic3r::GUI::into_u8(), model(), Slic3r::LifecycleEventContext::name, Slic3r::Ok, p, Slic3r::ProjectAfterSave, Slic3r::ProjectBeforeSave, Slic3r::remove_backup(), reset_project_dirty_after_save(), Slic3r::ShareMesh, Slic3r::GUI::DPIAware< P >::ShowModal(), Slic3r::SplitModel, Slic3r::trace(), up_to_date(), and update_title_dirty_status().

Referenced by close_with_confirm().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ save_project_if_dirty()

int Slic3r::GUI::Plater::save_project_if_dirty ( const wxString & reason)
15665{ return p->save_project_if_dirty(reason); }

References p.

◆ scale_selection_to_fit_print_volume()

void Slic3r::GUI::Plater::scale_selection_to_fit_print_volume ( )
19429{
19430 p->scale_selection_to_fit_print_volume();
19431}

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog().

Here is the caller graph for this function:

◆ schedule_background_process()

void Slic3r::GUI::Plater::schedule_background_process ( bool schedule = true)
22310{
22311 if (schedule)
22312 this->p->schedule_background_process();
22313
22314 this->p->suppressed_backround_processing_update = false;
22315}

References p.

Referenced by select_plate_by_hover_id(), and Slic3r::GUI::Plater::priv::update().

Here is the caller graph for this function:

◆ search()

void Slic3r::GUI::Plater::search ( bool plater_is_active,
Preset::Type type,
wxWindow * tag,
TextInput * etag,
wxWindow * stag )
22504{
22505 if (plater_is_active) {
22506 if (is_preview_shown())
22507 return;
22508 // plater should be focused for correct navigation inside search window
22509 this->SetFocus();
22510
22511 wxKeyEvent evt;
22512#ifdef __APPLE__
22513 evt.m_keyCode = 'f';
22514#else /* __APPLE__ */
22515 evt.m_keyCode = WXK_CONTROL_F;
22516#endif /* __APPLE__ */
22517 evt.SetControlDown(true);
22518 canvas3D()->on_char(evt);
22519 }
22520 else
22521 p->sidebar->get_searcher().show_dialog(type, tag, etag, stag);
22522}
void on_char(wxKeyEvent &evt)
Definition GLCanvas3D.cpp:4058
bool is_preview_shown() const
Definition Plater.cpp:19125

References canvas3D(), is_preview_shown(), Slic3r::GUI::GLCanvas3D::on_char(), and p.

Referenced by Slic3r::GUI::Plater::priv::reload_from_disk().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ search_string_getter()

bool Slic3r::GUI::Plater::search_string_getter ( int idx,
const char ** label,
const char ** tooltip )
21351{
21352 const Search::OptionsSearcher& search_list = p->sidebar->get_searcher();
21353
21354 if (0 <= idx && (size_t)idx < search_list.size()) {
21355 search_list[idx].get_marked_label_and_tooltip(label, tooltip);
21356 return true;
21357 }
21358
21359 return false;
21360}

References p, and Slic3r::Search::OptionsSearcher::size().

Here is the call graph for this function:

◆ segment()

void Slic3r::GUI::Plater::segment ( size_t obj_idx,
size_t instance_idx,
double smoothing_alpha = 0.5,
int segment_number = 5 )

◆ select_all()

void Slic3r::GUI::Plater::select_all ( )
19181{ p->select_all(); }

References p.

Referenced by Slic3r::GUI::Plater::priv::reload_all_from_disk().

Here is the caller graph for this function:

◆ select_curr_plate_all()

void Slic3r::GUI::Plater::select_curr_plate_all ( )
19178{ p->select_curr_plate_all(); }

References p.

◆ select_plate()

int Slic3r::GUI::Plater::select_plate ( int plate_index,
bool need_slice = false )
22613{
22614 int ret;
22615 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, need_slice %3% ")%__LINE__ %plate_index %need_slice;
22616 take_snapshot("select partplate!");
22617 ret = p->partplate_list.select_plate(plate_index);
22618 if (!ret) {
22619 if (is_view3D_shown())
22620 wxGetApp().plater()->canvas3D()->render();
22621 }
22622 const auto& preset_bundle = wxGetApp().preset_bundle;
22623
22624 if ((!ret) && (p->background_process.can_switch_print()))
22625 {
22626 //select successfully
22627 p->partplate_list.update_slice_context_to_current_plate(p->background_process);
22628 p->preview->update_gcode_result(p->partplate_list.get_current_slice_result());
22629 p->update_print_volume_state();
22630
22631 PartPlate* part_plate = p->partplate_list.get_curr_plate();
22632 bool result_valid = part_plate->is_slice_result_valid();
22633 PrintBase* print = nullptr;
22634 GCodeResult* gcode_result = nullptr;
22635 Print::ApplyStatus invalidated;
22636
22637 part_plate->get_print(&print, &gcode_result, NULL);
22638
22639 //always apply the current plate's print
22640 if (preset_bundle->get_printer_extruder_count() > 1) {
22641 std::vector<int> f_maps = part_plate->get_real_filament_maps(preset_bundle->project_config);
22642 std::vector<int> f_volume_maps = part_plate->get_filament_volume_maps();
22643 if (f_volume_maps.empty()) {
22644 f_volume_maps = preset_bundle->get_default_nozzle_volume_types_for_filaments(f_maps);
22645 }
22646 invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false, f_maps, f_volume_maps));
22647 }
22648 else
22649 invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false));
22650 bool model_fits, validate_err;
22651
22652 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, after apply, invalidated= %3%, previous result_valid %4% ")%__LINE__ %plate_index %invalidated %result_valid;
22653 if (result_valid)
22654 {
22655 if (is_preview_shown())
22656 {
22657 if (need_slice) { //from preview's thumbnail
22658 if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) || (gcode_result->moves.empty())){
22659 if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED)
22660 part_plate->update_slice_result_valid_state(false);
22661 p->process_completed_with_error = -1;
22662 p->m_slice_all = false;
22664 reslice();
22665 }
22666 else {
22667 validate_current_plate(model_fits, validate_err);
22668 //just refresh_print
22669 reload_print();
22670 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false, true);
22671 }
22672 }
22673 else {// from multiple slice's next
22674 //do nothing
22675 }
22676 }
22677 else
22678 {
22679 validate_current_plate(model_fits, validate_err);
22680 if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED)
22681 {
22682 part_plate->update_slice_result_valid_state(false);
22683 // BBS
22684 //p->show_action_buttons(true);
22685 //p->ready_to_slice = true;
22686 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, true);
22687 }
22688 else
22689 {
22690 // BBS
22691 //p->show_action_buttons(false);
22692 //p->ready_to_slice = false;
22693 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false);
22694
22695 reload_print();
22696 }
22697 }
22698 }
22699 else
22700 {
22701 //check inside status
22702 //model_fits = p->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside;
22703 //bool validate_err = false;
22704 validate_current_plate(model_fits, validate_err);
22705 if (model_fits && !validate_err) {
22706 p->process_completed_with_error = -1;
22707 }
22708 else {
22709 p->process_completed_with_error = p->partplate_list.get_curr_plate_index();
22710 }
22711 if (is_preview_shown())
22712 {
22713 if (need_slice)
22714 {
22715 //p->process_completed_with_error = -1;
22716 p->m_slice_all = false;
22718 if (model_fits && !validate_err) {
22719 if (!check_ams_status(false)){
22720 return ret;
22721 }
22722 reslice();
22723 }
22724 else {
22725 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false);
22726 //sometimes the previous print's sliced result is still valid, but the newly added object is laid over the boundary
22727 //then the print toolpath will be shown, so we should not refresh print here, only onload shell
22728 //refresh_print();
22729 p->update_fff_scene_only_shells();
22730 }
22731 }
22732 else {
22733 //p->ready_to_slice = false;
22734 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false);
22735 reload_print();
22736 }
22737 }
22738 else
22739 {
22740 //validate_current_plate(model_fits, validate_err);
22741 //check inside status
22742 /*if (model_fits && !validate_err){
22743 p->process_completed_with_error = -1;
22744 }
22745 else {
22746 p->process_completed_with_error = p->partplate_list.get_curr_plate_index();
22747 }*/
22748
22749 // BBS: don't show action buttons
22750 //p->show_action_buttons(true);
22751 //p->ready_to_slice = true;
22752 if (model_fits && part_plate->has_printable_instances())
22753 {
22754 //p->view3D->get_canvas3d()->post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, true));
22755 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, true);
22756 }
22757 else
22758 {
22759 //p->view3D->get_canvas3d()->post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false));
22760 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false);
22761 }
22762 }
22763 }
22764 }
22765
22766 SimpleEvent event(EVT_GLCANVAS_PLATE_SELECT);
22767 p->on_plate_selected(event);
22768
22769 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: plate %2%, return %3%")%__LINE__ %plate_index %ret;
22770 return ret;
22771}
void reslice()
Definition Plater.cpp:20752
bool is_view3D_shown() const
Definition Plater.cpp:19127
void reload_print()
Definition Plater.cpp:18332
bool check_ams_status(bool is_slice_all)
Definition Plater.cpp:23735
GCodeProcessorResult GCodeResult
Definition PartPlate.hpp:98

References Slic3r::PrintBase::APPLY_STATUS_INVALIDATED, check_ams_status(), Slic3r::GUI::MainFrame::eEventPlateUpdate, Slic3r::GUI::PartPlate::get_filament_volume_maps(), Slic3r::GUI::PartPlate::get_print(), Slic3r::GUI::PartPlate::get_real_filament_maps(), Slic3r::GUI::PartPlate::has_printable_instances(), is_preview_shown(), Slic3r::GUI::PartPlate::is_slice_result_valid(), is_view3D_shown(), model(), Slic3r::GCodeProcessorResult::moves, p, reload_print(), reset_gcode_toolpaths(), reslice(), take_snapshot(), Slic3r::GUI::PartPlate::update_slice_result_valid_state(), and validate_current_plate().

Referenced by select_plate_by_hover_id(), and select_sliced_plate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_plate_by_hover_id()

int Slic3r::GUI::Plater::select_plate_by_hover_id ( int hover_id,
bool right_click = false,
bool isModidyPlateName = false )
23252{
23253 int ret;
23254 int action, plate_index;
23255
23256 plate_index = hover_id / PartPlate::GRABBER_COUNT;
23257 action = isModidyPlateName ? PartPlate::PLATE_NAME_HOVER_ID : hover_id % PartPlate::GRABBER_COUNT;
23258
23259 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": enter, hover_id %1%, plate_index %2%, action %3%")%hover_id % plate_index %action;
23260 if (action == 0)
23261 {
23262 //select plate
23263 ret = p->partplate_list.select_plate(plate_index);
23264 if (!ret) {
23265 SimpleEvent event(EVT_GLCANVAS_PLATE_SELECT);
23266 p->on_plate_selected(event);
23267 }
23268 if ((!ret)&&(p->background_process.can_switch_print()))
23269 {
23270 //select successfully
23271 p->partplate_list.update_slice_context_to_current_plate(p->background_process);
23272 p->preview->update_gcode_result(p->partplate_list.get_current_slice_result());
23273 p->update_print_volume_state();
23274
23275 PartPlate* part_plate = p->partplate_list.get_curr_plate();
23276 bool result_valid = part_plate->is_slice_result_valid();
23277 PrintBase* print = nullptr;
23278 GCodeResult* gcode_result = nullptr;
23279 Print::ApplyStatus invalidated;
23280
23281 const auto& preset_bundle = wxGetApp().preset_bundle;
23282
23283 part_plate->get_print(&print, &gcode_result, NULL);
23284 //always apply the current plate's print
23285 if (preset_bundle->get_printer_extruder_count() > 1) {
23286 std::vector<int> f_maps = part_plate->get_real_filament_maps(preset_bundle->project_config);
23287 std::vector<int> f_volume_maps = part_plate->get_filament_volume_maps();
23288 if (f_volume_maps.empty()) {
23289 f_volume_maps = preset_bundle->get_default_nozzle_volume_types_for_filaments(f_maps);
23290 }
23291 invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false, f_maps, f_volume_maps));
23292 }
23293 else
23294 invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false));
23295 bool model_fits, validate_err;
23296 validate_current_plate(model_fits, validate_err);
23297
23298 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: after apply, invalidated= %2%, previous result_valid %3% ")%__LINE__ % invalidated %result_valid;
23299 if (result_valid)
23300 {
23301 if (invalidated & PrintBase::APPLY_STATUS_INVALIDATED)
23302 {
23303 //bool model_fits, validate_err;
23304 //validate_current_plate(model_fits, validate_err);
23305 part_plate->update_slice_result_valid_state(false);
23306
23307 // BBS
23308 //p->show_action_buttons(true);
23309 //p->ready_to_slice = true;
23310 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, true);
23311 }
23312 else
23313 {
23314 // BBS
23315 //p->show_action_buttons(false);
23316 //validate_current_plate(model_fits, validate_err);
23317 //p->ready_to_slice = false;
23318 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false);
23319
23320 reload_print();
23321 }
23322 }
23323 else
23324 {
23325 //check inside status
23326 if (model_fits && !validate_err){
23327 p->process_completed_with_error = -1;
23328 }
23329 else {
23330 p->process_completed_with_error = p->partplate_list.get_curr_plate_index();
23331 }
23332
23333 // BBS: don't show action buttons
23334 //p->show_action_buttons(true);
23335 //p->ready_to_slice = true;
23336 if (model_fits && part_plate->has_printable_instances())
23337 {
23338 //p->view3D->get_canvas3d()->post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, true));
23339 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": will set can_slice to true");
23340 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, true);
23341 }
23342 else
23343 {
23344 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": will set can_slice to false, has_printable_instances %1%")%part_plate->has_printable_instances();
23345 //p->view3D->get_canvas3d()->post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false));
23346 p->main_frame->update_slice_print_status(MainFrame::eEventPlateUpdate, false);
23347 }
23348 }
23349 }
23350 }
23351 else if ((action == 1)&&(!right_click))
23352 {
23353 //delete plate
23354 ret = delete_plate(plate_index);
23355 }
23356 else if ((action == 2)&&(!right_click))
23357 {
23358 //arrange the plate
23359 //take_snapshot("select_orient partplate");
23360 ret = select_plate(plate_index);
23361 if (!ret)
23362 {
23364 orient();
23365 }
23366 else
23367 {
23368 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index;
23369 ret = -1;
23370 }
23371 }
23372 else if ((action == 3)&&(!right_click))
23373 {
23374 //arrange the plate
23375 //take_snapshot("select_arrange partplate");
23376 ret = select_plate(plate_index);
23377 if (!ret)
23378 {
23381 arrange();
23382 }
23383 }
23384 else
23385 {
23386 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index;
23387 ret = -1;
23388 }
23389 }
23390 else if ((action == 4)&&(!right_click))
23391 {
23392 //lock the plate
23393 take_snapshot("lock partplate");
23394 ret = p->partplate_list.lock_plate(plate_index, !p->partplate_list.is_locked(plate_index));
23395 }
23396 else if ((action == 5)&&(!right_click))
23397 {
23398 // set the plate type
23399 ret = select_plate(plate_index);
23400 if (!ret) {
23401 wxCommandEvent evt(EVT_OPEN_PLATESETTINGSDIALOG);
23402 evt.SetInt(plate_index);
23403 evt.SetEventObject(this);
23404 wxPostEvent(this, evt);
23405
23407 } else {
23408 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index;
23409 ret = -1;
23410 }
23411 }
23412 else if ((action == PartPlate::PLATE_FILAMENT_MAP_ID) && (!right_click)) {
23413 ret = select_plate(plate_index);
23414 if (!ret) {
23415 PartPlate * curr_plate = p->partplate_list.get_curr_plate();
23416 wxCommandEvent evt(EVT_OPEN_FILAMENT_MAP_SETTINGS_DIALOG);
23417 evt.SetInt(0); // 0 means not from gcodeviewer
23418 evt.SetEventObject(this);
23419 wxPostEvent(this, evt);
23420 } else {
23421 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index;
23422 ret = -1;
23423 }
23424 }
23425 else if ((action == 6) && (!right_click)) {
23426 // set the plate type
23427 ret = select_plate(plate_index);
23428 if (!ret) {
23429 PlateNameEditDialog dlg(this, wxID_ANY, _L("Edit Plate Name"));
23430 PartPlate * curr_plate = p->partplate_list.get_curr_plate();
23431
23432 wxString curr_plate_name = from_u8(curr_plate->get_plate_name());
23433 dlg.set_plate_name(curr_plate_name);
23434
23435 int result=dlg.ShowModal();
23436 if (result == wxID_YES) {
23437 wxString dlg_plate_name = dlg.get_plate_name();
23438 curr_plate->set_plate_name(dlg_plate_name.ToUTF8().data());
23439 }
23440 } else {
23441 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index;
23442 ret = -1;
23443 }
23444 } else if ((action == 7) && (!right_click)) {
23445 // move plate to the front
23446 take_snapshot("move plate to the front");
23447 ret = p->partplate_list.move_plate_to_index(plate_index,0);
23448 p->partplate_list.update_slice_context_to_current_plate(p->background_process);
23449 p->preview->update_gcode_result(p->partplate_list.get_current_slice_result());
23450 p->sidebar->obj_list()->reload_all_plates();
23451 p->partplate_list.update_plates();
23452 update();
23453 p->partplate_list.select_plate(0);
23454 }
23455 else if (action == (int)PartPlate::PLATE_IMEX_MODE_ID)
23456 {
23457 ret = select_plate(plate_index);
23458 if (!ret) {
23459 PartPlate* curr_plate = p->partplate_list.get_curr_plate();
23460 // Ordered mode list: kImexPrimaryMode first, then each named mode once.
23461 const std::vector<std::string> modes =
23462 imex_plate_mode_choices(wxGetApp().preset_bundle->printers.get_edited_preset().config);
23463
23464 if (right_click) {
23465 // Show a popup menu with all modes.
23466 wxMenu menu;
23467 std::string current = curr_plate->get_imex_mode();
23468 std::vector<int> mode_ids;
23469 mode_ids.reserve(modes.size());
23470 for (size_t i = 0; i < modes.size(); ++i) {
23471 int id = wxNewId();
23472 mode_ids.push_back(id);
23473 const wxString label = (modes[i] == kImexPrimaryMode) ? _L("Primary") : from_u8(modes[i]);
23474 wxMenuItem* item = menu.AppendRadioItem(id, label);
23475 if (modes[i] == current)
23476 item->Check(true);
23477 }
23478 menu.Bind(wxEVT_MENU, [this, curr_plate, modes, mode_ids](wxCommandEvent& e) {
23479 auto it = std::find(mode_ids.begin(), mode_ids.end(), e.GetId());
23480 if (it == mode_ids.end()) return;
23481 const size_t idx = std::distance(mode_ids.begin(), it);
23482 take_snapshot("set imex mode");
23483 curr_plate->set_imex_mode(modes[idx]);
23485 set_plater_dirty(true);
23486 update();
23487 });
23488 p->view3D->get_canvas3d()->get_wxglcanvas()->PopupMenu(&menu);
23489 ret = 1; // signal to caller: popup was shown, suppress plate context menu
23490 } else {
23491 // Left-click: always cycles mode. The IMEX ghost renderer exposes
23492 // the per-head filament picker on the plate itself; no popover here.
23493 const std::string current_mode = curr_plate->get_imex_mode();
23494 auto it = std::find(modes.begin(), modes.end(), current_mode);
23495 size_t next_idx = (it == modes.end()) ? 0 : ((it - modes.begin() + 1) % modes.size());
23496 std::string next_mode = modes[next_idx];
23497 if (next_mode != current_mode) {
23498 take_snapshot("set imex mode");
23499 curr_plate->set_imex_mode(next_mode);
23501 set_plater_dirty(true);
23502 update();
23503 }
23504 }
23505 } else {
23506 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index;
23507 ret = -1;
23508 }
23509 }
23510 else
23511 {
23512 BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "invalid action %1%, with right_click=%2%" << action << right_click;
23513 ret = -1;
23514 }
23515
23516 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: return %2%")%__LINE__ % ret;
23517 return ret;
23518}
@ PREPARE_STATE_MENU
Definition Job.hpp:24
static constexpr unsigned int PLATE_IMEX_MODE_ID
Definition PartPlate.hpp:287
static constexpr unsigned int GRABBER_COUNT
Definition PartPlate.hpp:288
static constexpr unsigned int PLATE_NAME_HOVER_ID
Definition PartPlate.hpp:285
static constexpr unsigned int PLATE_FILAMENT_MAP_ID
Definition PartPlate.hpp:286
int select_plate(int plate_index, bool need_slice=false)
Definition Plater.cpp:22612
int delete_plate(int plate_index=-1)
Definition Plater.cpp:23552
void orient()
Definition Plater.cpp:14538
bool last_arrange_job_is_finished()
Definition Plater.hpp:1066
void schedule_background_process(bool schedule=true)
Definition Plater.cpp:22309
void set_prepare_state(int state)
Definition Plater.cpp:14548
std::vector< std::string > imex_plate_mode_choices(const ConfigBase &cfg)
Definition IMEXHelpers.cpp:694
constexpr const char * kImexPrimaryMode
Definition IMEXHelpers.hpp:27

References _L, Slic3r::PrintBase::APPLY_STATUS_INVALIDATED, arrange(), delete_plate(), Slic3r::GUI::MainFrame::eEventPlateUpdate, Slic3r::GUI::from_u8(), Slic3r::GUI::PartPlate::get_filament_volume_maps(), Slic3r::GUI::PartPlate::get_imex_mode(), Slic3r::GUI::PartPlate::get_plate_name(), Slic3r::GUI::PlateNameEditDialog::get_plate_name(), Slic3r::GUI::PartPlate::get_print(), Slic3r::GUI::PartPlate::get_real_filament_maps(), Slic3r::GUI::PartPlate::GRABBER_COUNT, Slic3r::GUI::PartPlate::has_printable_instances(), Slic3r::imex_plate_mode_choices(), Slic3r::GUI::PartPlate::is_slice_result_valid(), Slic3r::kImexPrimaryMode, last_arrange_job_is_finished(), model(), orient(), p, Slic3r::GUI::PartPlate::PLATE_FILAMENT_MAP_ID, Slic3r::GUI::PartPlate::PLATE_IMEX_MODE_ID, Slic3r::GUI::PartPlate::PLATE_NAME_HOVER_ID, Slic3r::GUI::Job::PREPARE_STATE_MENU, reload_print(), schedule_background_process(), select_plate(), Slic3r::GUI::PartPlate::set_imex_mode(), Slic3r::GUI::PartPlate::set_plate_name(), Slic3r::GUI::PlateNameEditDialog::set_plate_name(), set_plater_dirty(), set_prepare_state(), Slic3r::GUI::DPIAware< P >::ShowModal(), take_snapshot(), update(), update_project_dirty_from_presets(), Slic3r::GUI::PartPlate::update_slice_result_valid_state(), and validate_current_plate().

Here is the call graph for this function:

◆ select_sliced_plate()

int Slic3r::GUI::Plater::select_sliced_plate ( int plate_index,
bool skip_zoom = false )
22774{
22775 int ret = 0;
22776 BOOST_LOG_TRIVIAL(info) << "select_sliced_plate plate_idx=" << plate_index;
22777
22778 Freeze();
22779 ret = select_plate(plate_index, true);
22780 if (ret)
22781 {
22782 BOOST_LOG_TRIVIAL(error) << "select_plate error for plate_idx=" << plate_index;
22783 Thaw();
22784 return -1;
22785 }
22786 if(skip_zoom)
22787 p->partplate_list.select_plate_view();
22788 Thaw();
22789
22790 return ret;
22791}

References p, and select_plate().

Here is the call graph for this function:

◆ select_view()

void Slic3r::GUI::Plater::select_view ( const std::string & direction)
19116{ p->select_view(direction); }

References p.

◆ select_view_3D()

void Slic3r::GUI::Plater::select_view_3D ( const std::string & name,
bool no_slice = true )
19119{ p->select_view_3D(name, no_slice); }

References p.

◆ send_calibration_job_finished()

void Slic3r::GUI::Plater::send_calibration_job_finished ( wxCommandEvent & evt)
21213{
21214 p->main_frame->request_select_tab(TAB_ID_CALIBRATION);
21215 CalibrationPanel* calibration_panel = CalibrationPanel::ensure();
21216 if (calibration_panel) {
21217 auto curr_wizard = static_cast<CalibrationWizard*>(calibration_panel->get_tabpanel()->GetPage(evt.GetInt()));
21218 wxCommandEvent event(EVT_CALIBRATION_JOB_FINISHED);
21219 event.SetString(evt.GetString());
21220 event.SetEventObject(curr_wizard);
21221 wxPostEvent(curr_wizard, event);
21222 }
21223 evt.Skip();
21224}
#define TAB_ID_CALIBRATION
Definition MainFrame.hpp:69
static CalibrationPanel * ensure()
Definition Lazy.hpp:186

References Slic3r::GUI::LazyInstance< CalibrationPanel >::ensure(), Slic3r::GUI::CalibrationPanel::get_tabpanel(), p, and TAB_ID_CALIBRATION.

Here is the call graph for this function:

◆ send_gcode()

int Slic3r::GUI::Plater::send_gcode ( int plate_idx = -1,
Export3mfProgressFn proFn = nullptr )
21162{
21163 int result = 0;
21164 /* generate 3mf */
21165 set_print_job_plate_idx(plate_idx);
21166
21167 PartPlate* plate = get_partplate_list().get_curr_plate();
21168 try {
21169 p->m_print_job_data._3mf_path = fs::path(plate->get_tmp_gcode_path());
21170 p->m_print_job_data._3mf_path.replace_extension("3mf");
21171 }
21172 catch (std::exception&) {
21173 BOOST_LOG_TRIVIAL(error) << "generate 3mf path failed";
21174 return -1;
21175 }
21176
21178#if !BBL_RELEASE_TO_PUBLIC
21179 //only save model in QA environment
21180 std::string sel = get_app_config()->get("iot_environment");
21181 if (sel == ENV_PRE_HOST)
21183#endif
21184
21185 result = export_3mf(p->m_print_job_data._3mf_path, strategy, plate_idx, proFn);
21186
21187 return result;
21188}
#define ENV_PRE_HOST
Definition AppConfig.hpp:19
bool get(const std::string &section, const std::string &key, std::string &value) const
Definition AppConfig.hpp:147
AppConfig * get_app_config()
Definition GUI.cpp:539

References ENV_PRE_HOST, export_3mf(), Slic3r::AppConfig::get(), Slic3r::GUI::get_app_config(), Slic3r::GUI::PartPlateList::get_curr_plate(), get_partplate_list(), Slic3r::GUI::PartPlate::get_tmp_gcode_path(), p, set_print_job_plate_idx(), Slic3r::Silence, Slic3r::SkipAuxiliary, Slic3r::SkipModel, Slic3r::SplitModel, and Slic3r::WithGcode.

Referenced by send_gcode_legacy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_gcode_finish()

void Slic3r::GUI::Plater::send_gcode_finish ( wxString name)
19685{
19686 auto out_str = GUI::format(_L("The file %s has been sent to the printer's storage space and can be viewed on the printer."), name);
19687 p->notification_manager->push_exporting_finished_notification(out_str, "", false);
19688}

References _L, Slic3r::GUI::format(), and p.

Referenced by send_job_finished().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_gcode_legacy()

void Slic3r::GUI::Plater::send_gcode_legacy ( int plate_idx = -1,
Export3mfProgressFn proFn = nullptr )
20956{
20957 // if physical_printer is selected, send gcode for this printer
20958 // DynamicPrintConfig* physical_printer_config = wxGetApp().preset_bundle->physical_printers.get_selected_printer_config();
20959 DynamicPrintConfig* physical_printer_config = &Slic3r::GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config;
20960 if (! physical_printer_config || p->model.objects.empty())
20961 return;
20962
20963 PrintHostJob upload_job(physical_printer_config);
20964 if (upload_job.empty())
20965 return;
20966
20967 // Orca: the use_3mf printer option makes us send a .gcode.3mf to the printer
20968 const auto* use_3mf_opt = physical_printer_config->option<ConfigOptionBool>("use_3mf");
20969 const bool use_3mf = use_3mf_opt != nullptr && use_3mf_opt->value;
20970
20971 upload_job.upload_data.use_3mf = use_3mf;
20972 // Orca: the concrete plate to export/send (PLATE_CURRENT_IDX resolves to the current plate).
20973 const int resolved_plate_idx = plate_idx == PLATE_CURRENT_IDX ? get_partplate_list().get_curr_plate_index() : plate_idx;
20974
20975 // Obtain default output path
20976 fs::path default_output_file;
20977 try {
20978 // Update the background processing, so that the placeholder parser will get the correct values for the ouput file template.
20979 // Also if there is something wrong with the current configuration, a pop-up dialog will be shown and the export will not be performed.
20980 unsigned int state = this->p->update_restart_background_process(false, false);
20982 return;
20983 default_output_file = this->p->background_process.output_filepath_for_project(
20984 into_path(this->p->get_project_filename(".3mf")));
20985 } catch (const Slic3r::PlaceholderParserError& ex) {
20986 // Show the error with monospaced font.
20987 show_error(this, ex.what(), true);
20988 return;
20989 } catch (const std::exception& ex) {
20990 show_error(this, ex.what(), false);
20991 return;
20992 }
20993 default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string()));
20994 if (use_3mf) {
20995 // Orca: a gcode-in-3mf bundle is named ".gcode.3mf" (matching "Export plate sliced file")
20996 default_output_file.replace_extension(".gcode.3mf");
20997 }
20998
20999 // Repetier specific: Query the server for the list of file groups.
21000 wxArrayString groups;
21001 {
21002 wxBusyCursor wait;
21003 upload_job.printhost->get_groups(groups);
21004 }
21005
21006 // PrusaLink specific: Query the server for the list of file groups.
21007 wxArrayString storage_paths;
21008 wxArrayString storage_names;
21009 {
21010 wxBusyCursor wait;
21011 try {
21012 upload_job.printhost->get_storage(storage_paths, storage_names);
21013 } catch (const Slic3r::IOError& ex) {
21014 show_error(this, ex.what(), false);
21015 return;
21016 }
21017 }
21018
21019 {
21020 auto preset_bundle = wxGetApp().preset_bundle;
21021 auto config = get_app_config();
21022
21023 const auto host_type_opt = physical_printer_config->option<ConfigOptionEnum<PrintHostType>>("host_type");
21024 const auto host_type = host_type_opt != nullptr ? host_type_opt->value : htElegooLink;
21025 const auto* ff_serial_opt = physical_printer_config->option<ConfigOptionString>("flashforge_serial_number");
21026 const auto* ff_code_opt = physical_printer_config->option<ConfigOptionString>("printhost_apikey");
21027 const bool flashforge_local_api = host_type == htFlashforge && ff_serial_opt != nullptr && !ff_serial_opt->value.empty() &&
21028 ff_code_opt != nullptr && !ff_code_opt->value.empty();
21029
21030 std::unique_ptr<PrintHostSendDialog> pDlg;
21031 if (host_type == htElegooLink) {
21032 pDlg = std::make_unique<ElegooPrintHostSendDialog>(default_output_file, upload_job.printhost->get_post_upload_actions(), groups,
21033 storage_paths, storage_names,
21034 config->get_bool("open_device_tab_post_upload"));
21035 } else if (host_type == htCrealityPrint) {
21036 pDlg = std::make_unique<CrealityPrintHostSendDialog>(default_output_file, upload_job.printhost->get_post_upload_actions(), groups,
21037 storage_paths, storage_names,
21038 config->get_bool("open_device_tab_post_upload"),
21039 upload_job.printhost.get());
21040 } else if (flashforge_local_api) {
21041 auto* flashforge_host = dynamic_cast<Flashforge*>(upload_job.printhost.get());
21042 if (flashforge_host == nullptr) {
21043 show_error(this, _L("Flashforge host is not available."), false);
21044 return;
21045 }
21046
21047 std::vector<FlashforgeMaterialSlot> slots;
21048 bool supports_material_station = false;
21049 {
21050 wxBusyCursor wait;
21051 wxString msg;
21052 if (!flashforge_host->fetch_material_slots(slots, &supports_material_station, msg)) {
21053 show_error(this, msg.empty() ? _L("Unable to log in to the Flashforge printer.") : msg, false);
21054 return;
21055 }
21056 }
21057
21058 std::vector<FilamentInfo> project_filaments;
21059 PlateDataPtrs plate_data_list;
21060 DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config();
21061 const auto* filament_color = dynamic_cast<const ConfigOptionStrings*>(cfg.option("filament_colour"));
21062 const auto* filament_id_opt = dynamic_cast<const ConfigOptionStrings*>(cfg.option("filament_ids"));
21063 auto enrich_project_filaments = [&](std::vector<FilamentInfo>& filaments) {
21064 for (auto& filament : filaments) {
21065 if (filament.id < 0)
21066 continue;
21067
21068 std::string display_filament_type;
21069 try {
21070 filament.type = cfg.get_filament_type(display_filament_type, filament.id);
21071 } catch (...) {
21072 }
21073
21074 if (filament.type.empty())
21075 filament.type = display_filament_type;
21076 if (filament.type.empty())
21077 filament.type = "Unknown";
21078
21079 filament.filament_id = filament_id_opt ? filament_id_opt->get_at(static_cast<size_t>(filament.id)) : "";
21080 filament.color = filament_color ? filament_color->get_at(static_cast<size_t>(filament.id)) : "#FFFFFF";
21081 if (filament.color.empty())
21082 filament.color = "#FFFFFF";
21083 }
21084 };
21085
21086 p->partplate_list.store_to_3mf_structure(plate_data_list, true, plate_idx);
21087 PlateData* selected_plate_data = (resolved_plate_idx >= 0 && resolved_plate_idx < static_cast<int>(plate_data_list.size())) ? plate_data_list[resolved_plate_idx] : nullptr;
21088 if (selected_plate_data == nullptr && !plate_data_list.empty())
21089 selected_plate_data = plate_data_list.front();
21090
21091 if (selected_plate_data != nullptr)
21092 project_filaments = selected_plate_data->slice_filaments_info;
21093
21094 if (project_filaments.empty()) {
21095 if (PartPlate* plate = get_partplate_list().get_plate(resolved_plate_idx); plate != nullptr)
21096 project_filaments = plate->get_slice_filaments_info();
21097 }
21098
21099 if (!project_filaments.empty())
21100 enrich_project_filaments(project_filaments);
21101 release_PlateData_list(plate_data_list);
21102
21103 pDlg = std::make_unique<FlashforgePrintHostSendDialog>(default_output_file, upload_job.printhost->get_post_upload_actions(), groups,
21104 storage_paths, storage_names,
21105 config->get_bool("open_device_tab_post_upload"),
21106 flashforge_host,
21107 supports_material_station,
21108 std::move(slots),
21109 project_filaments);
21110 } else {
21111 pDlg = std::make_unique<PrintHostSendDialog>(default_output_file, upload_job.printhost->get_post_upload_actions(), groups,
21112 storage_paths, storage_names, config->get_bool("open_device_tab_post_upload"));
21113 }
21114
21115 pDlg->init();
21116 if (pDlg->ShowModal() != wxID_OK) {
21117 return;
21118 }
21119
21120 config->set_bool("open_device_tab_post_upload", pDlg->switch_to_device_tab());
21121 // PrintHostUpload upload_data;
21122 upload_job.switch_to_device_tab = pDlg->switch_to_device_tab();
21123 upload_job.upload_data.upload_path = pDlg->filename();
21124 upload_job.upload_data.post_action = pDlg->post_action();
21125 upload_job.upload_data.group = pDlg->group();
21126 upload_job.upload_data.storage = pDlg->storage();
21127 upload_job.upload_data.extended_info = pDlg->extendedInfo();
21128 // Orca: gcode inside a .gcode.3mf is index-coded (Metadata/plate_<N>.gcode) and a bundle may
21129 // carry several of them, so the upload must name which plate to print via a 1-based plateindex.
21130 // Even a single-plate bundle needs it, since its gcode entry is still indexed. The host upload
21131 // forwards the field and servers that don't use it ignore it. "All plates" points at the
21132 // current plate — the bundle still carries every plate's gcode.
21133 if (use_3mf) {
21134 const int plateindex = (plate_idx == PLATE_ALL_IDX ? get_partplate_list().get_curr_plate_index() : resolved_plate_idx) + 1;
21135 upload_job.upload_data.extended_info["plateindex"] = std::to_string(plateindex);
21136 }
21137 }
21138
21139 // Show "Is printer clean" dialog for PrusaConnect - Upload and print.
21140 if (std::string(upload_job.printhost->get_name()) == "PrusaConnect" && upload_job.upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
21141 GUI::MessageDialog dlg(nullptr, _L("Is the printer ready? Is the print sheet in place, empty and clean?"), _L("Upload and Print"), wxOK | wxCANCEL);
21142 if (dlg.ShowModal() != wxID_OK)
21143 return;
21144 }
21145
21146 if (use_3mf) {
21147 // Process gcode
21148 const int result = send_gcode(resolved_plate_idx, nullptr);
21149
21150 if (result < 0) {
21151 wxString msg = _L("Abnormal print file data. Please slice again");
21152 show_error(this, msg, false);
21153 return;
21154 }
21155
21156 upload_job.upload_data.source_path = p->m_print_job_data._3mf_path;
21157 }
21158
21159 p->export_gcode(fs::path(), false, std::move(upload_job));
21160}
#define PLATE_CURRENT_IDX
Definition PartPlate.hpp:56
int send_gcode(int plate_idx=-1, Export3mfProgressFn proFn=nullptr)
Definition Plater.cpp:21161
@ htElegooLink
Definition PrintConfig.hpp:119
@ htCrealityPrint
Definition PrintConfig.hpp:119
@ htFlashforge
Definition PrintConfig.hpp:119
@ StartPrint
Definition PrintHost.hpp:25
zaa_minimize_perimeter_height use_3mf((ConfigOptionStrings, small_area_infill_flow_compensation_model))((ConfigOptionBool

References _L, config(), Slic3r::PrintHostJob::empty(), Slic3r::PrintHostUpload::extended_info, Slic3r::fold_utf8_to_ascii(), Slic3r::GUI::get_app_config(), Slic3r::GUI::PartPlateList::get_curr_plate_index(), Slic3r::DynamicPrintConfig::get_filament_type(), get_partplate_list(), Slic3r::PrintHostUpload::group, Slic3r::htCrealityPrint, Slic3r::htElegooLink, Slic3r::htFlashforge, Slic3r::GUI::into_path(), Slic3r::ConfigBase::option(), p, PLATE_ALL_IDX, PLATE_CURRENT_IDX, Slic3r::PrintHostUpload::post_action, Slic3r::PrintHostJob::printhost, Slic3r::release_PlateData_list(), send_gcode(), Slic3r::GUI::show_error(), Slic3r::GUI::DPIAware< P >::ShowModal(), Slic3r::PlateData::slice_filaments_info, Slic3r::PrintHostUpload::source_path, Slic3r::StartPrint, Slic3r::PrintHostUpload::storage, Slic3r::PrintHostJob::switch_to_device_tab, Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_INVALID, Slic3r::PrintHostJob::upload_data, Slic3r::PrintHostUpload::upload_path, Slic3r::PrintHostUpload::use_3mf, Slic3r::use_3mf(), and Slic3r::ConfigOptionSingle< T >::value.

Here is the call graph for this function:

◆ send_job_finished()

void Slic3r::GUI::Plater::send_job_finished ( wxCommandEvent & evt)
21259{
21260 Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
21261 if (!dev) return;
21262 //dev->set_selected_machine(evt.GetString().ToStdString());
21263
21264 send_gcode_finish(evt.GetString());
21265 p->hide_send_to_printer_dlg();
21266 //p->main_frame->request_select_tab(TAB_ID_MONITOR);
21268 //MonitorPanel* curr_monitor = p->main_frame->m_monitor;
21269 //if (curr_monitor)
21270 // curr_monitor->get_tabpanel()->ChangeSelection(MonitorPanel::PrinterTab::PT_STATUS);
21271}
void send_gcode_finish(wxString name)
Definition Plater.cpp:19684

References p, and send_gcode_finish().

Here is the call graph for this function:

◆ send_to_printer()

void Slic3r::GUI::Plater::send_to_printer ( bool isall = false)
19594{
19595 p->on_action_send_to_printer(isall);
19596}

References p.

◆ set_bed_position()

void Slic3r::GUI::Plater::set_bed_position ( Vec2d & pos)
23578{
23579 p->bed.set_position(pos);
23580}

References p.

◆ set_bed_shape() [1/2]

void Slic3r::GUI::Plater::set_bed_shape ( ) const
21719{
21720 std::string texture_filename;
21721 auto bundle = wxGetApp().preset_bundle;
21722 if (bundle != nullptr) {
21723 const Preset* curr = &bundle->printers.get_selected_preset();
21724 if (curr->is_system)
21725 texture_filename = PresetUtils::system_printer_bed_texture(*curr);
21726 else {
21727 auto *printer_model = curr->config.opt<ConfigOptionString>("printer_model");
21728 if (printer_model != nullptr && ! printer_model->value.empty()) {
21729 texture_filename = bundle->get_texture_for_printer_model(printer_model->value);
21730 }
21731 }
21732 }
21733 const ConfigOptionPoints *bed_exclude_area = p->config->option<ConfigOptionPoints>("bed_exclude_area");
21734 set_bed_shape(p->config->option<ConfigOptionPoints>("printable_area")->values,
21735 //BBS: add bed exclude areas
21736 bed_exclude_area->values,
21737 p->config->option<ConfigOptionPoints>("wrapping_exclude_area")->values,
21738 p->config->option<ConfigOptionFloat>("printable_height")->value,
21739 p->config->option<ConfigOptionPointsGroups>("extruder_printable_area")->values,
21740 p->config->option<ConfigOptionFloatsNullable>("extruder_printable_height")->values,
21741 p->config->option<ConfigOptionString>("bed_custom_texture")->value.empty() ? texture_filename : p->config->option<ConfigOptionString>("bed_custom_texture")->value,
21742 p->config->option<ConfigOptionString>("bed_custom_model")->value);
21743}
std::string system_printer_bed_texture(const Preset &preset)
Definition Preset.cpp:5107

References Slic3r::Preset::config, Slic3r::Preset::is_system, Slic3r::DynamicConfig::opt(), p, set_bed_shape(), Slic3r::PresetUtils::system_printer_bed_texture(), Slic3r::ConfigOptionSingle< T >::value, and Slic3r::ConfigOptionVector< T >::values.

Referenced by on_config_change(), and set_bed_shape().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_bed_shape() [2/2]

void Slic3r::GUI::Plater::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
21747{
21748 p->set_bed_shape(make_counter_clockwise(shape), exclude_area, wrapping_exclude_area, printable_height, extruder_areas, extruder_heights, custom_texture, custom_model, force_as_custom);
21749}
Pointfs make_counter_clockwise(const Pointfs &pointfs)
Definition ClipperUtils.cpp:1568
zaa_minimize_perimeter_height printable_height((ConfigOptionFloatsNullable, extruder_printable_height))((ConfigOptionPoint

References Slic3r::make_counter_clockwise(), p, and Slic3r::printable_height().

Here is the call graph for this function:

◆ set_current_canvas_as_dirty()

void Slic3r::GUI::Plater::set_current_canvas_as_dirty ( )
22141{
22142 p->set_current_canvas_as_dirty();
22143}

References p.

◆ set_global_filament_map()

void Slic3r::GUI::Plater::set_global_filament_map ( const std::vector< int > & filament_map)
21974{
21975 auto& project_config = wxGetApp().preset_bundle->project_config;
21976 project_config.option<ConfigOptionInts>("filament_map")->values = filament_map;
21977 p->partplate_list.invalidate_exclusion_volume_previews();
21978}
zaa_minimize_perimeter_height filament_map((ConfigOptionInts, filament_volume_map))((ConfigOptionInts

References Slic3r::filament_map(), and p.

Referenced by Slic3r::GUI::try_pop_up_before_slice().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_global_filament_map_mode()

void Slic3r::GUI::Plater::set_global_filament_map_mode ( FilamentMapMode mode)
21964{
21965 auto& project_config = wxGetApp().preset_bundle->project_config;
21966 auto mode_ptr = project_config.option<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode");
21967 FilamentMapMode old_mode = mode_ptr->value;
21968 if(mode != old_mode)
21970 mode_ptr->value = mode;
21971}
void on_filament_map_mode_change()
Definition Plater.cpp:22005

References on_filament_map_mode_change().

Referenced by Slic3r::GUI::try_pop_up_before_slice().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_global_filament_volume_map()

void Slic3r::GUI::Plater::set_global_filament_volume_map ( const std::vector< int > & filament_volume_map)
21981{
21982 auto& project_config = wxGetApp().preset_bundle->project_config;
21983 project_config.option<ConfigOptionInts>("filament_volume_map")->values = filament_volume_map;
21984}

Referenced by Slic3r::GUI::try_pop_up_before_slice().

Here is the caller graph for this function:

◆ set_need_update()

void Slic3r::GUI::Plater::set_need_update ( bool need_update)
24037{
24038 p->set_need_update(need_update);
24039}
bool need_update() const
Definition Plater.cpp:24031

References need_update(), and p.

Here is the call graph for this function:

◆ set_number_of_copies()

void Slic3r::GUI::Plater::set_number_of_copies ( )
19384{
19385 int obj_idx = p->get_selected_object_idx();
19386 if (obj_idx == -1)
19387 return;
19388
19389 ModelObject* model_object = p->model.objects[obj_idx];
19390
19391 const int num = GetNumberFromUser( " ", _L("Number of copies:"),
19392 _L("Copies of the selected object"), model_object->instances.size(), 0, 1000, this );
19393 if (num < 0)
19394 return;
19395
19396 Plater::TakeSnapshot snapshot(this, (boost::format("Set numbers of copies to %1%")%num).str());
19397
19398 int diff = num - (int)model_object->instances.size();
19399 if (diff > 0)
19401 else if (diff < 0)
19403}
void increase_instances(size_t num=1)
Definition Plater.cpp:19286
void decrease_instances(size_t num=1)
Definition Plater.cpp:19330
static long GetNumberFromUser(const wxString &msg, const wxString &prompt, const wxString &title, long value, long min, long max, wxWindow *parent)
Definition Plater.cpp:19363
Slic3r::Polygons diff(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:731

References _L, decrease_instances(), Slic3r::diff(), Slic3r::GUI::GetNumberFromUser(), increase_instances(), Slic3r::ModelObject::instances, and p.

Here is the call graph for this function:

◆ set_only_gcode()

void Slic3r::GUI::Plater::set_only_gcode ( bool only_gcode)
inline
420{ m_only_gcode = only_gcode; }

References m_only_gcode.

◆ set_pending_published()

void Slic3r::GUI::Plater::set_pending_published ( const std::vector< std::string > & published_keys,
const std::vector< Slic3r::PublishedMaterialEntry > & material_keys )
19907{
19908 p->m_has_pending_published = true;
19909 p->m_pending_published_keys = published_keys;
19910 p->m_pending_material_keys = material_keys;
19911}

References p.

◆ set_plater_dirty()

void Slic3r::GUI::Plater::set_plater_dirty ( bool is_dirty)
15663{ p->set_plater_dirty(is_dirty); }

References p.

Referenced by normalize_bed_types(), open_filament_map_setting_dialog(), open_platesettings_dialog(), and select_plate_by_hover_id().

Here is the caller graph for this function:

◆ set_prepare_state()

void Slic3r::GUI::Plater::set_prepare_state ( int state)
14549{
14550 p->m_job_prepare_state = state;
14551}

References p.

Referenced by Slic3r::GUI::MenuFactory::load_handy_model(), and select_plate_by_hover_id().

Here is the caller graph for this function:

◆ set_print_job_plate_idx()

void Slic3r::GUI::Plater::set_print_job_plate_idx ( int plate_idx)
14568{
14569 if (plate_idx == PLATE_CURRENT_IDX) {
14570 p->m_print_job_data.plate_idx = get_partplate_list().get_curr_plate_index();
14571 }
14572 else {
14573 p->m_print_job_data.plate_idx = plate_idx;
14574 }
14575}

References Slic3r::GUI::PartPlateList::get_curr_plate_index(), get_partplate_list(), p, and PLATE_CURRENT_IDX.

Referenced by export_config_3mf(), and send_gcode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_printer_technology()

bool Slic3r::GUI::Plater::set_printer_technology ( PrinterTechnology printer_technology)
22163{
22164 p->printer_technology = printer_technology;
22165 bool ret = p->background_process.select_technology(printer_technology);
22166 if (ret) {
22167 // Update the active presets.
22168 }
22169 //FIXME for SLA synchronize
22170 //p->background_process.apply(Model)!
22171
22172 if (printer_technology == ptSLA) {
22173 for (ModelObject* model_object : p->model.objects) {
22174 model_object->ensure_on_bed();
22175 }
22176 }
22177
22178 p->label_btn_export = printer_technology == ptFFF ? L("Export G-code") : L("Export");
22179 p->label_btn_send = printer_technology == ptFFF ? L("Send G-code") : L("Send to printer");
22180
22181 if (wxGetApp().mainframe != nullptr)
22182 wxGetApp().mainframe->update_menubar();
22183
22184 p->sidebar->get_searcher().set_printer_technology(printer_technology);
22185
22186 p->notification_manager->set_fff(printer_technology == ptFFF);
22187 p->notification_manager->set_slicing_progress_hidden();
22188
22189 return ret;
22190}
#define L(s)
Definition ExtrusionEntity.cpp:25

References Slic3r::ModelObject::ensure_on_bed(), L, p, printer_technology(), Slic3r::ptFFF, and Slic3r::ptSLA.

Referenced by Slic3r::GUI::MainFrame::load_config(), and on_config_change().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_project_filename()

void Slic3r::GUI::Plater::set_project_filename ( const wxString & filename)
22046{
22047 p->set_project_filename(filename);
22048}

References p.

Referenced by load_gcode(), Slic3r::GUI::GUI_App::post_init(), and Slic3r::GUI::Plater::priv::reset().

Here is the caller graph for this function:

◆ set_selected_visible()

void Slic3r::GUI::Plater::set_selected_visible ( bool visible)
19256{
19257 if (p->get_curr_selection().is_empty())
19258 return;
19259
19260 Plater::TakeSnapshot snapshot(this, "Set Selected Objects Visible in AssembleView");
19262
19263 p->get_current_canvas3D()->set_selected_visible(visible);
19264}

References Slic3r::GUI::Worker::cancel_all(), get_ui_job_worker(), and p.

Here is the call graph for this function:

◆ set_using_exported_file()

void Slic3r::GUI::Plater::set_using_exported_file ( bool exported_file)
inline
427 {
428 m_exported_file = exported_file;
429 }

References m_exported_file.

◆ SetPlateIndexByRightMenuInLeftUI()

void Slic3r::GUI::Plater::SetPlateIndexByRightMenuInLeftUI ( int index)
24134{ p->m_is_RightClickInLeftUI = index; }

References p.

◆ Show()

bool Slic3r::GUI::Plater::Show ( bool show = true)
15655{
15656 if (wxGetApp().mainframe)
15657 wxGetApp().mainframe->show_option(show);
15658 return wxPanel::Show(show);
15659}

◆ show_collision_volumes()

void Slic3r::GUI::Plater::show_collision_volumes ( bool show)
19138{
19139 wxGetApp().app_config->set_bool("show_collision_volumes", show);
19140 p->partplate_list.invalidate_exclusion_volume_previews();
19141 p->view3D->get_canvas3d()->set_as_dirty();
19142 p->view3D->get_canvas3d()->request_extra_frame();
19143}

References p.

◆ show_dock_pane()

void Slic3r::GUI::Plater::show_dock_pane ( wxWindow * window,
bool show )
19175{ p->show_dock_pane(window, show); }

References p.

Referenced by Slic3r::anonymous_namespace{PluginHostUi.cpp}::handle_show().

Here is the caller graph for this function:

◆ show_illegal_characters_warning()

void Slic3r::GUI::Plater::show_illegal_characters_warning ( wxWindow * parent)
static
433{
434 show_error(parent, _L("Invalid name, the following characters are not allowed:") + " <>:/\\|?*\"");
435}

References _L, and Slic3r::GUI::show_error().

Referenced by Slic3r::GUI::ObjectList::OnEditingDone(), and Slic3r::GUI::ObjectList::rename_item().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_object_info()

void Slic3r::GUI::Plater::show_object_info ( )
23597{
23598 NotificationManager *notify_manager = get_notification_manager();
23599 const Selection& selection = get_selection();
23600 int selCount = selection.get_volume_idxs().size();
23601 ModelObjectPtrs objects = model().objects;
23602 int obj_idx = selection.get_object_idx();
23603 std::string info_text;
23604
23605 if (selCount > 1 && !selection.is_single_full_object()) {
23606 notify_manager->bbl_close_objectsinfo_notification();
23607 if (selection.get_mode() == Selection::EMode::Volume) {
23608 info_text += (boost::format(_utf8(L("Number of currently selected parts: %1%\n"))) % selCount).str();
23609 } else if (selection.get_mode() == Selection::EMode::Instance) {
23610 int content_count = selection.get_content().size();
23611 info_text += (boost::format(_utf8(L("Number of currently selected objects: %1%\n"))) % content_count).str();
23612 }
23613 notify_manager->bbl_show_objectsinfo_notification(info_text, false, !(p->current_panel == p->view3D));
23614 return;
23615 }
23616 else if (objects.empty() || (obj_idx < 0) || (obj_idx >= objects.size()) ||
23617 objects[obj_idx]->volumes.empty() ||// hack to avoid crash when deleting the last object on the bed
23618 (selection.is_single_full_object() && objects[obj_idx]->instances.size()> 1) ||
23619 !(selection.is_single_full_instance() || selection.is_single_volume()))
23620 {
23621 notify_manager->bbl_close_objectsinfo_notification();
23622 return;
23623 }
23624
23625 const ModelObject* model_object = objects[obj_idx];
23626 int inst_idx = selection.get_instance_idx();
23627 if ((inst_idx < 0) || (inst_idx >= model_object->instances.size()))
23628 {
23629 notify_manager->bbl_close_objectsinfo_notification();
23630 return;
23631 }
23632 bool imperial_units = wxGetApp().app_config->get("use_inches") == "1";
23633 double koef = imperial_units ? GizmoObjectManipulation::mm_to_in : 1.0f;
23634
23635 ModelVolume* vol = nullptr;
23636 Transform3d t;
23637 int face_count;
23638 Vec3d size;
23639 if (selection.is_single_volume()) {
23640 std::vector<int> obj_idxs, vol_idxs;
23641 wxGetApp().obj_list()->get_selection_indexes(obj_idxs, vol_idxs);
23642 if (vol_idxs.size() != 1)
23643 {
23644 //corner case when merge/split/remove
23645 return;
23646 }
23647 vol = model_object->volumes[vol_idxs[0]];
23648 t = model_object->instances[inst_idx]->get_matrix() * vol->get_matrix();
23649 info_text += (boost::format(_utf8(L("Part name: %1%\n"))) % vol->name).str();
23650 face_count = static_cast<int>(vol->mesh().facets_count());
23651 size = vol->get_convex_hull().transformed_bounding_box(t).size();
23652 }
23653 else {
23654 //int obj_idx, vol_idx;
23655 //wxGetApp().obj_list()->get_selected_item_indexes(obj_idx, vol_idx);
23656 //if (obj_idx < 0) {
23657 // //corner case when merge/split/remove
23658 // return;
23659 //}
23660 info_text += (boost::format(_utf8(L("Object name: %1%\n"))) % model_object->name).str();
23661 face_count = static_cast<int>(model_object->facets_count());
23662 size = model_object->instance_convex_hull_bounding_box(inst_idx).size();
23663 }
23664
23665 //Vec3d size = vol ? vol->mesh().transformed_bounding_box(t).size() : model_object->instance_bounding_box(inst_idx).size();
23666 if (imperial_units)
23667 info_text += (boost::format(_utf8(L("Size: %1% x %2% x %3% in\n"))) %(size(0)*koef) %(size(1)*koef) %(size(2)*koef)).str();
23668 else
23669 info_text += (boost::format(_utf8(L("Size: %1% x %2% x %3% mm\n"))) %size(0) %size(1) %size(2)).str();
23670
23671 const TriangleMeshStats& stats = vol ? vol->mesh().stats() : model_object->get_object_stl_stats();
23672 double volume_val = stats.volume;
23673 if (vol)
23674 volume_val *= std::fabs(t.matrix().block(0, 0, 3, 3).determinant());
23675 volume_val = volume_val * pow(koef,3);
23676 if (imperial_units)
23677 info_text += (boost::format(_utf8(L("Volume: %1% in³\n"))) %volume_val).str();
23678 else
23679 info_text += (boost::format(_utf8(L("Volume: %1% mm³\n"))) %volume_val).str();
23680 info_text += (boost::format(_utf8(L("Triangles: %1%\n"))) %face_count).str();
23681
23682 wxString info_manifold;
23683 int non_manifold_edges = 0;
23684 auto mesh_errors = p->sidebar->obj_list()->get_mesh_errors_info(&info_manifold, &non_manifold_edges);
23685
23686 if (non_manifold_edges > 0) {
23687 info_manifold += "\n" + _L("Tips:") + "\n" + _L("Use \"Fix Model\" to repair the mesh.");
23688 }
23689
23690 info_manifold = "<Error>" + info_manifold + "</Error>";
23691 info_text += into_u8(info_manifold);
23692 notify_manager->bbl_show_objectsinfo_notification(info_text, non_manifold_edges > 0, !(p->current_panel == p->view3D));
23693}
static const double mm_to_in
Definition GizmoObjectManipulation.hpp:31
const Selection & get_selection() const
Definition Plater.cpp:22055
#define _utf8(s)
Definition I18N.hpp:10

References _L, _utf8, Slic3r::GUI::NotificationManager::bbl_close_objectsinfo_notification(), Slic3r::GUI::NotificationManager::bbl_show_objectsinfo_notification(), Slic3r::ModelObject::facets_count(), Slic3r::GUI::Selection::get_content(), Slic3r::ModelVolume::get_convex_hull(), Slic3r::GUI::Selection::get_instance_idx(), Slic3r::ModelVolume::get_matrix(), Slic3r::GUI::Selection::get_mode(), get_notification_manager(), Slic3r::GUI::Selection::get_object_idx(), Slic3r::ModelObject::get_object_stl_stats(), get_selection(), Slic3r::GUI::Selection::get_volume_idxs(), Slic3r::GUI::Selection::Instance, Slic3r::ModelObject::instance_convex_hull_bounding_box(), Slic3r::ModelObject::instances, Slic3r::GUI::into_u8(), Slic3r::GUI::Selection::is_single_full_instance(), Slic3r::GUI::Selection::is_single_full_object(), Slic3r::GUI::Selection::is_single_volume(), L, Slic3r::ModelVolume::mesh(), Slic3r::GUI::GizmoObjectManipulation::mm_to_in, model(), Slic3r::ModelObject::name, Slic3r::ModelVolume::name, Slic3r::Model::objects, p, Slic3r::BoundingBox3Base< PointType >::size(), Slic3r::TriangleMesh::stats(), Slic3r::TriangleMesh::transformed_bounding_box(), Slic3r::GUI::Selection::Volume, Slic3r::TriangleMeshStats::volume, and Slic3r::ModelObject::volumes.

Here is the call graph for this function:

◆ show_status_message()

void Slic3r::GUI::Plater::show_status_message ( std::string s)
23875{
23876 BOOST_LOG_TRIVIAL(trace) << "show_status_message:" << s;
23877}

References Slic3r::trace().

Here is the call graph for this function:

◆ show_uv_editor()

void Slic3r::GUI::Plater::show_uv_editor ( bool show)
22105{
22106 if (p->uv_editor_panel == nullptr)
22107 return;
22108 const wxAuiPaneInfo &pane = p->m_aui_mgr.GetPane(p->uv_editor_panel);
22109 if (!pane.IsOk() || pane.IsShown() == show)
22110 return;
22111
22112 // Deferred, because GLGizmoTextureDisplacement calls this from its ImGui panel - that is, from
22113 // the middle of the 3D canvas's GL frame. Showing an AUI pane re-lays out the window and
22114 // delivers the resulting size/paint events synchronously, and the UV canvas painting itself
22115 // makes its own surface current in the app's *shared* GL context, which mid-frame is the one
22116 // the 3D canvas is drawing into. Doing the layout once the frame is over avoids that entirely.
22117 CallAfter([this, show]() {
22118 wxAuiPaneInfo &deferred_pane = p->m_aui_mgr.GetPane(p->uv_editor_panel);
22119 if (!deferred_pane.IsOk() || deferred_pane.IsShown() == show)
22120 return;
22121 deferred_pane.Show(show);
22122 p->m_aui_mgr.Update();
22123 });
22124}

References p.

◆ show_view3D_labels()

void Slic3r::GUI::Plater::show_view3D_labels ( bool show)
19130{ p->show_view3D_labels(show); }

References p.

◆ show_view3D_overhang()

void Slic3r::GUI::Plater::show_view3D_overhang ( bool show)
19146{ p->show_view3D_overhang(show); }

References p.

◆ sidebar()

Sidebar & Slic3r::GUI::Plater::sidebar ( )
16046{ return *p->sidebar; }

References p.

Referenced by _calib_pa_pattern(), apply_cut_object_to_model(), Slic3r::anonymous_namespace{PluginHostPresets.cpp}::bind_filament_target(), Slic3r::GUI::Plater::priv::check_ams_status_impl(), decrease_instances(), increase_instances(), load_gcode(), load_project(), normalize_bed_types(), on_bed_type_change(), on_filament_count_change(), on_filaments_delete(), and reslice().

Here is the caller graph for this function:

◆ single_snapshots_enter()

void Slic3r::GUI::Plater::single_snapshots_enter ( SingleSnapshot * single)
private
21289{
21290 p->single_snapshots_enter(single);
21291}

References p.

◆ single_snapshots_leave()

void Slic3r::GUI::Plater::single_snapshots_leave ( SingleSnapshot * single)
private
21293{
21294 p->single_snapshots_leave(single);
21295}

References p.

◆ sla_object_menu()

wxMenu * Slic3r::GUI::Plater::sla_object_menu ( )
24127{ return p->menus.sla_object_menu(); }

References p.

◆ sla_print() [1/2]

SLAPrint & Slic3r::GUI::Plater::sla_print ( )
16052{ return p->sla_print; }

References p.

◆ sla_print() [2/2]

const SLAPrint & Slic3r::GUI::Plater::sla_print ( ) const
16051{ return p->sla_print; }

References p.

◆ split_object() [1/2]

void Slic3r::GUI::Plater::split_object ( bool auto_drop = true)
22336{ p->split_object(auto_drop); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), and Slic3r::GUI::Plater::priv::on_action_split_objects().

Here is the caller graph for this function:

◆ split_object() [2/2]

void Slic3r::GUI::Plater::split_object ( int obj_idx,
bool auto_drop = true )

◆ split_volume()

void Slic3r::GUI::Plater::split_volume ( )
22337{ p->split_volume(); }

References p.

Referenced by Slic3r::GUI::anonymous_namespace{NativeCommands.cpp}::build_command_catalog(), and Slic3r::GUI::Plater::priv::on_action_split_volumes().

Here is the caller graph for this function:

◆ start_next_slice()

int Slic3r::GUI::Plater::start_next_slice ( )
private
20887{
20888 // Stop arrange and (or) optimize rotation tasks.
20889 //this->stop_jobs();
20890
20891 //FIXME Don't reslice if export of G-code or sending to OctoPrint is running.
20892 // bitmask of UpdateBackgroundProcessReturnState
20893 unsigned int state = this->p->update_background_process(true, false, false);
20895 this->p->view3D->reload_scene(false);
20896
20897 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": update_background_process returns %1%")%state;
20898 if (!p->partplate_list.get_curr_plate()->can_slice()) {
20899 p->process_completed_with_error = p->partplate_list.get_curr_plate_index();
20900 BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": found invalidated apply in update_background_process.");
20901 return -1;
20902 }
20903
20904 // Only restarts if the state is valid.
20905 bool result = this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART);
20906 if (!result)
20907 {
20908 //slice next
20909 SlicingProcessCompletedEvent evt(EVT_PROCESS_COMPLETED, 0,
20911 // Post the "complete" callback message, so that it will slice the next plate soon
20912 wxQueueEvent(this, evt.Clone());
20913 }
20914 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": restart_background_process returns %1%")%result;
20915
20916 return 0;
20917}

References Slic3r::SlicingProcessCompletedEvent::Clone(), Slic3r::SlicingProcessCompletedEvent::Finished, p, Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART, and Slic3r::GUI::Plater::priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE.

Here is the call graph for this function:

◆ suppress_background_process()

void Slic3r::GUI::Plater::suppress_background_process ( const bool stop_background_process)
22323{
22324 if (stop_background_process)
22325 this->p->background_process_timer.Stop();
22326
22327 this->p->suppressed_backround_processing_update = true;
22328}

References p.

◆ suppress_snapshots()

void Slic3r::GUI::Plater::suppress_snapshots ( )
private
21285{ p->suppress_snapshots(); }

References p.

◆ svg_part_menu()

wxMenu * Slic3r::GUI::Plater::svg_part_menu ( )
24126{ return p->menus.svg_part_menu(); }

References p.

◆ sys_color_changed()

void Slic3r::GUI::Plater::sys_color_changed ( )
22539{
22540 p->preview->sys_color_changed();
22541 p->sidebar->sys_color_changed();
22542 p->menus.sys_color_changed();
22543 if (p->m_select_machine_dlg) p->m_select_machine_dlg->sys_color_changed();
22544
22545 Layout();
22546 GetParent()->Layout();
22547}

References p.

◆ take_snapshot() [1/2]

void Slic3r::GUI::Plater::take_snapshot ( const std::string & snapshot_name)
21281{ p->take_snapshot(snapshot_name); }

References p.

Referenced by add_plate(), delete_plate(), Slic3r::GUI::Plater::priv::enter_gizmos_stack(), select_plate(), and select_plate_by_hover_id().

Here is the caller graph for this function:

◆ take_snapshot() [2/2]

void Slic3r::GUI::Plater::take_snapshot ( const std::string & snapshot_name,
UndoRedo::SnapshotType snapshot_type )
21283{ p->take_snapshot(snapshot_name, snapshot_type); }

References p.

◆ text_part_menu()

wxMenu * Slic3r::GUI::Plater::text_part_menu ( )
24125{ return p->menus.text_part_menu(); }

References p.

◆ toggle_render_statistic_dialog()

void Slic3r::GUI::Plater::toggle_render_statistic_dialog ( )
23962{
23963 p->show_render_statistic_dialog = !p->show_render_statistic_dialog;
23964}

References p.

◆ toggle_show_wireframe()

void Slic3r::GUI::Plater::toggle_show_wireframe ( )
23972{
23973 p->show_wireframe = !p->show_wireframe;
23974}

References p.

◆ toggle_show_xray()

void Slic3r::GUI::Plater::toggle_show_xray ( )
23992{
23993 p->show_xray = !p->show_xray;
23994}

References p.

◆ trigger_restore_project()

void Slic3r::GUI::Plater::trigger_restore_project ( int skip_confirm = 0)
19239{
19240 auto evt = new wxCommandEvent(EVT_RESTORE_PROJECT, this->GetId());
19241 evt->SetInt(skip_confirm);
19242 wxQueueEvent(this, evt);
19243 //wxPostEvent(this, *evt);
19244}

◆ unbind_canvas_event_handlers()

void Slic3r::GUI::Plater::unbind_canvas_event_handlers ( )
22146{
22147 p->unbind_canvas_event_handlers();
22148}

References p.

◆ undo()

void Slic3r::GUI::Plater::undo ( )
21296{ p->undo(); }

References p.

◆ undo_redo_stack_main()

const UndoRedo::Stack & Slic3r::GUI::Plater::undo_redo_stack_main ( ) const
23955{ return p->undo_redo_stack_main(); }

References p.

Referenced by Slic3r::GUI::Plater::priv::up_to_date().

Here is the caller graph for this function:

◆ undo_redo_string_getter()

bool Slic3r::GUI::Plater::undo_redo_string_getter ( const bool is_undo,
int idx,
const char ** out_text )
21319{
21320 const std::vector<UndoRedo::Snapshot>& ss_stack = p->undo_redo_stack().snapshots();
21321 const int idx_in_ss_stack = p->get_active_snapshot_index() + (is_undo ? -(++idx) : idx);
21322
21323 if (0 < idx_in_ss_stack && (size_t)idx_in_ss_stack < ss_stack.size() - 1) {
21324 *out_text = ss_stack[idx_in_ss_stack].name.c_str();
21325 return true;
21326 }
21327
21328 return false;
21329}

References p.

◆ undo_redo_topmost_string_getter()

void Slic3r::GUI::Plater::undo_redo_topmost_string_getter ( const bool is_undo,
std::string & out_text )
21338{
21339 const std::vector<UndoRedo::Snapshot>& ss_stack = p->undo_redo_stack().snapshots();
21340 const int idx_in_ss_stack = p->get_active_snapshot_index() + (is_undo ? -1 : 0);
21341
21342 if (0 < idx_in_ss_stack && (size_t)idx_in_ss_stack < ss_stack.size() - 1) {
21343 out_text = ss_stack[idx_in_ss_stack].name;
21344 return;
21345 }
21346
21347 out_text = "";
21348}

References p.

◆ undo_to()

void Slic3r::GUI::Plater::undo_to ( int selection)
21299{
21300 if (selection == 0) {
21301 p->undo();
21302 return;
21303 }
21304
21305 const int idx = p->get_active_snapshot_index() - selection - 1;
21306 p->undo_redo_to(p->undo_redo_stack().snapshots()[idx].timestamp);
21307}

References p.

◆ up_to_date()

bool Slic3r::GUI::Plater::up_to_date ( bool saved,
bool backup )
16615{
16616 if (saved) {
16618 return p->up_to_date(saved, backup);
16619 }
16620 // A Design-tab project is object-less until it is committed to the plate, but its feature
16621 // tree is real work: treating it as an empty project skipped both the autosave and the
16622 // "unsaved changes" prompt, so quitting threw it away without asking. Non-CAD projects
16623 // never carry a recipe, so the empty-project shortcut is unchanged for them.
16624 return (p->model.objects.empty() && p->model.cad_recipe.empty()) ||
16625 (p->up_to_date(saved, backup) && !Slic3r::has_other_changes(backup));
16626}
bool has_other_changes(bool backup)
Definition bbs_3mf.cpp:9848
void clear_other_changes(bool backup)
Definition bbs_3mf.cpp:9843

References Slic3r::clear_other_changes(), Slic3r::has_other_changes(), and p.

Referenced by close_with_confirm(), load_project(), new_project(), and save_project().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update()

void Slic3r::GUI::Plater::update ( bool conside_update_flag = false,
bool force_background_processing_update = false )
19093{
19095 return;
19096 }
19097 unsigned int flag = force_background_processing_update ? (unsigned int)Plater::priv::UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE : 0;
19098 if (conside_update_flag) {
19099 if (need_update()) {
19100 p->update(flag);
19101 p->set_need_update(false);
19102 }
19103 }
19104 else
19105 p->update(flag);
19106}
bool is_new_project_and_check_state()
Definition Plater.hpp:434
@ FORCE_BACKGROUND_PROCESSING_UPDATE
Definition Plater.cpp:7349

References Slic3r::GUI::Plater::priv::FORCE_BACKGROUND_PROCESSING_UPDATE, is_new_project_and_check_state(), need_update(), and p.

Referenced by add_plate(), apply_cut_object_to_model(), Slic3r::GUI::Plater::priv::apply_textured_mesh_import_result(), changed_mesh(), Slic3r::GUI::Plater::priv::delete_all_objects_from_model(), Slic3r::GUI::Plater::priv::delete_object_from_model(), delete_plate(), duplicate_plate(), force_filament_colors_update(), on_config_change(), open_filament_map_setting_dialog(), open_platesettings_dialog(), refresh_missing_plugin_block(), Slic3r::GUI::Plater::priv::reload_from_disk(), Slic3r::GUI::Plater::priv::remove(), Slic3r::GUI::Plater::priv::replace_all_with_stl(), Slic3r::GUI::Plater::priv::replace_with_stl(), Slic3r::GUI::Plater::priv::reset(), select_plate_by_hover_id(), Slic3r::GUI::try_pop_up_before_slice(), Slic3r::GUI::Plater::priv::undo_redo_to(), Slic3r::GUI::Plater::priv::update_after_undo_redo(), and Slic3r::GUI::Plater::priv::update_objects_position_when_select_preset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_all_plate_thumbnails()

void Slic3r::GUI::Plater::update_all_plate_thumbnails ( bool force_update = false)
18349{
18350 for (int i = 0; i < get_partplate_list().get_plate_count(); i++)
18351 update_plate_thumbnails(i, force_update);
18352}
void update_plate_thumbnails(int plate_idx, bool force_update)
Definition Plater.cpp:18354

References get_partplate_list(), Slic3r::GUI::PartPlateList::get_plate_count(), and update_plate_thumbnails().

Referenced by force_update_all_plate_thumbnails().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_filament_colors_in_full_config()

bool Slic3r::GUI::Plater::update_filament_colors_in_full_config ( )
21483{
21484 DynamicPrintConfig& project_config = wxGetApp().preset_bundle->project_config;
21485 const auto& full_config = wxGetApp().preset_bundle->full_config();
21486 ConfigOptionStrings* color_opt = project_config.option<ConfigOptionStrings>("filament_colour");
21487 const ConfigOptionStrings* type_opt = full_config.option<ConfigOptionStrings>("filament_type");
21488
21489 p->config->option<ConfigOptionStrings>("filament_colour")->values = color_opt->values;
21490 p->config->option<ConfigOptionStrings>("filament_type")->values = type_opt->values;
21491 return true;
21492}

References Slic3r::ConfigBase::option(), p, and Slic3r::ConfigOptionVector< T >::values.

Referenced by on_config_change(), on_filament_count_change(), and on_filaments_delete().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_filament_volume_map()

void Slic3r::GUI::Plater::update_filament_volume_map ( int extruder_id,
int volume_type )
23767{
23768 // Hybrid is a per-extruder mix, not a per-filament volume; reset the affected filaments
23769 // to Standard so the manual grouping dialog starts from a concrete assignment.
23770 int selected_volume_type = volume_type == static_cast<int>(NozzleVolumeType::nvtHybrid) ? static_cast<int>(NozzleVolumeType::nvtStandard) : volume_type;
23771 auto& partplate_list = get_partplate_list();
23772 for (int idx = 0; idx < partplate_list.get_plate_count(); ++idx) {
23773 auto plate = partplate_list.get_plate(idx);
23774 if (!plate) continue;
23775 auto filament_map = plate->get_filament_maps();
23776 auto filament_volume_map = plate->get_filament_volume_maps();
23777 if (filament_map.empty() || filament_volume_map.empty()) continue;
23778 if (filament_volume_map.size() < filament_map.size()) {
23779 filament_volume_map.resize(filament_map.size(), static_cast<int>(NozzleVolumeType::nvtStandard));
23780 }
23781 for (size_t i = 0; i < filament_map.size(); ++i) {
23782 if (filament_map[i] == extruder_id + 1) {
23783 filament_volume_map[i] = selected_volume_type;
23784 }
23785 }
23786 plate->set_filament_volume_maps(filament_volume_map);
23787 }
23788}
@ nvtHybrid
Definition PrintConfig.hpp:621
@ nvtStandard
Definition PrintConfig.hpp:619

References Slic3r::filament_map(), get_partplate_list(), Slic3r::GUI::PartPlateList::get_plate(), Slic3r::GUI::PartPlateList::get_plate_count(), Slic3r::nvtHybrid, and Slic3r::nvtStandard.

Here is the call graph for this function:

◆ update_flush_volume_matrix()

void Slic3r::GUI::Plater::update_flush_volume_matrix ( size_t old_nozzle_size,
size_t new_nozzle_size )
21677{
21678 size_t nozzle_nums = wxGetApp().preset_bundle->get_printer_extruder_count();
21679 Slic3r::DynamicPrintConfig *project_config = &wxGetApp().preset_bundle->project_config;
21680
21681 // Verify whether it is the first time start Studio
21682 size_t filament_nums = project_config->option<ConfigOptionStrings>("filament_colour")->values.size();
21683 size_t flush_volume_size = project_config->option<ConfigOptionFloats>("flush_volumes_matrix")->values.size();
21684
21685 assert(nozzle_nums == new_nozzle_size);
21686 if (old_nozzle_size < new_nozzle_size) {
21687
21688 std::vector<double> first_flush_volume_mtx = get_flush_volumes_matrix(project_config->option<ConfigOptionFloats>("flush_volumes_matrix")->values, -1, old_nozzle_size);
21689 if (first_flush_volume_mtx.size() == filament_nums * filament_nums * new_nozzle_size) { // load file
21690 set_flush_volumes_matrix(project_config->option<ConfigOptionFloats>("flush_volumes_matrix")->values, first_flush_volume_mtx, -1, new_nozzle_size);
21691 } else {
21692 first_flush_volume_mtx.resize(filament_nums * filament_nums, 0);
21693 std::vector<double> flush_volume_mtx;
21694 for (size_t i = 0; i < new_nozzle_size; ++i) {
21695 flush_volume_mtx.insert(flush_volume_mtx.end(), first_flush_volume_mtx.begin(), first_flush_volume_mtx.end());
21696 }
21697 set_flush_volumes_matrix(project_config->option<ConfigOptionFloats>("flush_volumes_matrix")->values, flush_volume_mtx, -1, new_nozzle_size);
21698 }
21699 std::vector<double> flush_multipliers = project_config->option<ConfigOptionFloats>("flush_multiplier")->values;
21700 flush_multipliers.resize(nozzle_nums, 1.f);
21701 project_config->option<ConfigOptionFloats>("flush_multiplier")->values = flush_multipliers;
21702 }
21703 else if (old_nozzle_size > new_nozzle_size) {
21704 std::vector<double> new_flush_volume_mtx;
21705 for (size_t i = 0; i < new_nozzle_size; ++i) {
21706 std::vector<double> flush_volume_mtx = get_flush_volumes_matrix(project_config->option<ConfigOptionFloats>("flush_volumes_matrix")->values, -1, old_nozzle_size);
21707 flush_volume_mtx.resize(filament_nums * filament_nums, 0);
21708 new_flush_volume_mtx.insert(new_flush_volume_mtx.end(), flush_volume_mtx.begin(), flush_volume_mtx.end());
21709 }
21710
21711 std::vector<double> flush_multipliers = project_config->option<ConfigOptionFloats>("flush_multiplier")->values;
21712 flush_multipliers.resize(nozzle_nums, 1.f);
21713 set_flush_volumes_matrix(project_config->option<ConfigOptionFloats>("flush_volumes_matrix")->values, new_flush_volume_mtx, -1, new_nozzle_size);
21714 project_config->option<ConfigOptionFloats>("flush_multiplier")->values = flush_multipliers;
21715 }
21716}
static void set_flush_volumes_matrix(std::vector< T > &out_matrix, const std::vector< T > &fv_matrix, size_t extruder_id=-1, size_t nozzle_nums=1)
Definition PrintConfig.hpp:2698
static std::vector< T > get_flush_volumes_matrix(const std::vector< T > &fv_matrix, size_t extruder_id=-1, size_t nozzle_nums=1)
Definition PrintConfig.hpp:2685

References Slic3r::get_flush_volumes_matrix(), Slic3r::ConfigBase::option(), Slic3r::set_flush_volumes_matrix(), and Slic3r::ConfigOptionVector< T >::size().

Referenced by on_config_change().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_machine_sync_status()

void Slic3r::GUI::Plater::update_machine_sync_status ( )
23751{
23752 DeviceManager *dev_maneger = wxGetApp().getDeviceManager();
23753 if (!dev_maneger) {
23754 GUI::wxGetApp().sidebar().update_sync_status(nullptr);
23755 return;
23756 }
23757 MachineObject *obj = wxGetApp().getDeviceManager()->get_selected_machine();
23758 GUI::wxGetApp().sidebar().update_sync_status(obj);
23759}

◆ update_menus()

void Slic3r::GUI::Plater::update_menus ( )
22346{ p->menus.update(); }

References p.

◆ update_obj_preview_thumbnail()

void Slic3r::GUI::Plater::update_obj_preview_thumbnail ( ModelObject * mo,
int obj_idx,
int vol_idx,
std::vector< Slic3r::ColorRGBA > colors,
int camera_view_angle_type )
18368{
18369 PartPlate * plate = get_partplate_list().get_plate(0);
18370 ThumbnailsParams thumbnail_params = {{}, false, true, true, true, 0, false};
18371 GLVolumeCollection cur_volumes;
18372 cur_volumes.load_object_volume(mo, obj_idx, vol_idx, 0, "volume", true, false, false, false);
18373 ModelObjectPtrs model_objects;
18374 model_objects.emplace_back(mo);
18375 get_view3D_canvas3D()->render_thumbnail(plate->obj_preview_thumbnail_data, colors, plate->plate_thumbnail_width, plate->plate_thumbnail_height, thumbnail_params,
18376 model_objects, cur_volumes, Camera::EType::Ortho, (Camera::ViewAngleType) camera_view_angle_type, false, false);
18377}
void render_thumbnail(ThumbnailData &thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams &thumbnail_params, Camera::EType camera_type, Camera::ViewAngleType camera_view_angle_type=Camera::ViewAngleType::Iso, bool for_picking=false, bool ban_light=false)
Definition GLCanvas3D.cpp:2933
ViewAngleType
Definition Camera.hpp:43

References get_partplate_list(), Slic3r::GUI::PartPlateList::get_plate(), get_view3D_canvas3D(), Slic3r::GLVolumeCollection::load_object_volume(), Slic3r::GUI::PartPlate::obj_preview_thumbnail_data, Slic3r::GUI::Camera::Ortho, Slic3r::GUI::PartPlate::plate_thumbnail_height, Slic3r::GUI::PartPlate::plate_thumbnail_width, and Slic3r::GUI::GLCanvas3D::render_thumbnail().

Here is the call graph for this function:

◆ update_objects_position_when_select_preset()

void Slic3r::GUI::Plater::update_objects_position_when_select_preset ( const std::function< void()> & select_prest)
23731{
23732 p->update_objects_position_when_select_preset(select_prest);
23733}

References p.

Referenced by Slic3r::GUI::Plater::priv::on_select_preset().

Here is the caller graph for this function:

◆ update_plate_thumbnails()

void Slic3r::GUI::Plater::update_plate_thumbnails ( int plate_idx,
bool force_update )
18355{
18356 PartPlate* plate = get_partplate_list().get_plate(plate_idx);
18357 ThumbnailsParams thumbnail_params = { {}, false, true, true, true, plate_idx};
18358 if (force_update || !plate->thumbnail_data.is_valid()) {
18359 get_view3D_canvas3D()->render_thumbnail(plate->thumbnail_data, plate->plate_thumbnail_width, plate->plate_thumbnail_height, thumbnail_params, Camera::EType::Ortho);
18360 }
18361 if (force_update || !plate->no_light_thumbnail_data.is_valid()) {
18362 get_view3D_canvas3D()->render_thumbnail(plate->no_light_thumbnail_data, plate->plate_thumbnail_width, plate->plate_thumbnail_height, thumbnail_params,
18364 }
18365}

References get_partplate_list(), Slic3r::GUI::PartPlateList::get_plate(), get_view3D_canvas3D(), Slic3r::ThumbnailData::is_valid(), Slic3r::GUI::Camera::Iso, Slic3r::GUI::PartPlate::no_light_thumbnail_data, Slic3r::GUI::Camera::Ortho, Slic3r::GUI::PartPlate::plate_thumbnail_height, Slic3r::GUI::PartPlate::plate_thumbnail_width, Slic3r::GUI::GLCanvas3D::render_thumbnail(), and Slic3r::GUI::PartPlate::thumbnail_data.

Referenced by update_all_plate_thumbnails().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_preview_bottom_toolbar()

void Slic3r::GUI::Plater::update_preview_bottom_toolbar ( )
23832{
23833 p->update_preview_bottom_toolbar();
23834}

References p.

◆ update_preview_moves_slider()

void Slic3r::GUI::Plater::update_preview_moves_slider ( )

◆ update_print_error_info()

void Slic3r::GUI::Plater::update_print_error_info ( int code,
std::string msg,
std::string extra )
22023{
22024 if (p->m_select_machine_dlg) {
22025 p->m_select_machine_dlg->update_print_error_info(code, msg, extra);
22026 }
22027
22028 if (p->m_send_to_sdcard_dlg) {
22029 p->m_send_to_sdcard_dlg->update_print_error_info(code, msg, extra);
22030 }
22031 if (CalibrationPanel* calibration = CalibrationPanel::if_built())
22032 calibration->update_print_error_info(code, msg, extra);
22033}

References Slic3r::GUI::LazyInstance< CalibrationPanel >::if_built(), and p.

Here is the call graph for this function:

◆ update_print_required_data()

int Slic3r::GUI::Plater::update_print_required_data ( Slic3r::DynamicPrintConfig config,
Slic3r::Model model,
Slic3r::PlateDataPtrs plate_data_list,
std::string file_name,
std::string file_path )
21332{
21333 return p->update_print_required_data(config, model, plate_data_list, file_name, file_path);
21334}

References config(), model(), and p.

Here is the call graph for this function:

◆ update_project_dirty_from_presets()

void Slic3r::GUI::Plater::update_project_dirty_from_presets ( )
15664{ p->update_project_dirty_from_presets(); }

References p.

Referenced by Slic3r::anonymous_namespace{PluginHostPresets.cpp}::bind_filament_target(), load_gcode(), load_project(), new_project(), open_platesettings_dialog(), and select_plate_by_hover_id().

Here is the caller graph for this function:

◆ update_slicing_context_to_current_partplate()

void Slic3r::GUI::Plater::update_slicing_context_to_current_partplate ( )
23590{
23591 p->partplate_list.update_slice_context_to_current_plate(p->background_process);
23592 p->preview->update_gcode_result(p->partplate_list.get_current_slice_result());
23593}

References p.

◆ update_title_dirty_status()

void Slic3r::GUI::Plater::update_title_dirty_status ( )
24063{
24064 p->update_title_dirty_status();
24065}

References p.

Referenced by on_config_change(), save_project(), and Slic3r::GUI::Plater::priv::undo_redo_to().

Here is the caller graph for this function:

◆ update_ui_from_settings()

void Slic3r::GUI::Plater::update_ui_from_settings ( )
19114{ p->update_ui_from_settings(); }

References p.

Referenced by Slic3r::GUI::Plater::priv::on_create_filament(), and Slic3r::GUI::Plater::priv::on_modify_filament().

Here is the caller graph for this function:

◆ using_exported_file()

bool Slic3r::GUI::Plater::using_exported_file ( )
inline
426{ return m_exported_file; }

References m_exported_file.

Referenced by export_3mf(), force_update_all_plate_thumbnails(), invalid_all_plate_thumbnails(), and load_project().

Here is the caller graph for this function:

◆ validate_current_plate()

void Slic3r::GUI::Plater::validate_current_plate ( bool & model_fits,
bool & validate_error )
22799{
22800 ObjectFilamentResults object_results;
22801 ModelInstanceEPrintVolumeState state = p->view3D->get_canvas3d()->check_volumes_outside_state(&object_results);
22802 model_fits = (state != ModelInstancePVS_Partly_Outside);
22803
22804 PartPlate *cur_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
22805 if (model_fits) { // TPU check
22806 bool tpu_valid = cur_plate->check_tpu_printable_status(wxGetApp().preset_bundle->full_config(), wxGetApp().preset_bundle->get_used_tpu_filaments(cur_plate->get_extruders(true)));
22807 model_fits &= tpu_valid;
22808 }
22809
22810 if (model_fits) { // Filament printable check
22812 bool filament_printable = cur_plate->check_filament_printable(wxGetApp().preset_bundle->full_config(), filament_printable_error_msg);
22813 model_fits &= filament_printable;
22814 }
22815
22816 model_fits = model_fits && object_results.filaments.empty();
22817 validate_error = false;
22818 if (p->printer_technology == ptFFF) {
22819 //std::string plater_text = _u8L("An object is laid over the boundary of plate or exceeds the height limit.\n"
22820 // "Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");;
22821 std::vector<StringObjectException> warnings;
22822 Polygons polygons;
22823 std::vector<std::pair<Polygon, float>> height_polygons;
22824 p->background_process.fff_print()->set_check_multi_filaments_compatibility(wxGetApp().app_config->get("enable_high_low_temp_mixed_printing") == "false");
22825 StringObjectException err = p->background_process.validate(&warnings, &polygons, &height_polygons);
22826 // update string by type
22828 BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": validate err=%1%, warnings=%2%, model_fits %3%")%err.string%warnings.size() %model_fits;
22829
22830 // The same check update_background_process() applies. Without it this path clears
22831 // the invalid flag and closes the notification on a plate that is still unslicable.
22832 // model_fits is set too, mirroring the missing-plugin block further down: the slice
22833 // is already gated by m_apply_invalid, but leaving m_ready_for_slice true would be a
22834 // trap for any future consumer that reads it on its own.
22835 if (err.string.empty()) {
22836 err.string = imex_placement_error(p->partplate_list.get_curr_plate());
22837 if (!err.string.empty())
22838 model_fits = false;
22839 }
22840
22841 if (err.string.empty()) {
22842 p->partplate_list.get_curr_plate()->update_apply_result_invalid(false);
22843 p->notification_manager->set_all_slicing_errors_gray(true);
22844 p->notification_manager->close_notification_of_type(NotificationType::ValidateError);
22845 p->notification_manager->bbl_close_3mf_warn_notification();
22846
22847 p->process_validation_warnings(warnings);
22848 p->view3D->get_canvas3d()->reset_sequential_print_clearance();
22849 p->view3D->get_canvas3d()->set_as_dirty();
22850 p->view3D->get_canvas3d()->request_extra_frame();
22851 }
22852 else {
22853 // The print is not valid.
22854 p->partplate_list.get_curr_plate()->update_apply_result_invalid(true);
22855 // Show error as notification.
22856 p->notification_manager->push_validate_error_notification(err);
22857 p->process_validation_warnings(warnings);
22858 //model_fits = false;
22859 validate_error = true;
22860 p->view3D->get_canvas3d()->set_sequential_print_clearance_visible(true);
22861 p->view3D->get_canvas3d()->set_sequential_print_clearance_render_fill(true);
22862 p->view3D->get_canvas3d()->set_sequential_print_clearance_polygons(polygons, height_polygons);
22863 }
22864
22865 std::string clashed_text = get_object_clashed_text();
22866 if (state == ModelInstancePVS_Partly_Outside) {
22867 p->notification_manager->push_plater_error_notification(clashed_text);
22868 }
22869 else {
22870 p->notification_manager->close_plater_error_notification(clashed_text);
22871 }
22872 std::string left_unprintable_text = get_left_extruder_unprintable_text(), right_unprintable_text = get_right_extruder_unprintable_text();
22873 if (!left_unprintable_text.empty())
22874 {
22875 p->notification_manager->bbl_show_filament_map_invalid_notification_before_slice(NotificationType::LeftExtruderUnprintableError, left_unprintable_text);
22876 }
22877 else {
22878 p->notification_manager->bbl_close_filament_map_invalid_notification_before_slice(NotificationType::LeftExtruderUnprintableError);
22879 }
22880
22881 if (!right_unprintable_text.empty())
22882 {
22883 p->notification_manager->bbl_show_filament_map_invalid_notification_before_slice(NotificationType::RightExtruderUnprintableError,right_unprintable_text);
22884 }
22885 else {
22886 p->notification_manager->bbl_close_filament_map_invalid_notification_before_slice(NotificationType::RightExtruderUnprintableError);
22887 }
22888
22889 /*if (state == ModelInstancePVS_Limited) {
22890 p->notification_manager->push_plater_warning_notification(get_object_limited_text());
22891 }
22892 else {
22893 p->notification_manager->close_plater_warning_notification(get_object_limited_text());
22894 }*/
22895 }
22896
22897 // Missing-plugin validation (both technologies): block slicing while the active preset(s)
22898 // reference plugin capabilities that are not installed/loadable here. The helper rebuilds the
22899 // missing sets, manages the notifications, and reports whether slicing is blocked. plugins_block_changed
22900 // is set when the block toggled, so the Slice button can be refreshed below.
22901 bool plugins_block_changed = false;
22902 if (refresh_missing_plugin_block(&plugins_block_changed)) {
22903 model_fits = false;
22904 validate_error = true;
22905 }
22906
22907 PartPlate* part_plate = p->partplate_list.get_curr_plate();
22908 part_plate->update_slice_ready_status(model_fits);
22909
22910 // The toolbar Slice button is normally refreshed only by the canvas
22911 // (EVT_GLCANVAS_ENABLE_ACTION_BUTTONS) on geometry updates. When the missing-plugin block toggles
22912 // without a geometry change (e.g. a plugin finishing loading, or a setting edit that drops the
22913 // last missing plugin), refresh it here — AFTER update_slice_ready_status set the plate's
22914 // can_slice() flag that get_enable_slice_status() reads — so the button doesn't lag until the
22915 // next bed click.
22916 if (plugins_block_changed && !p->background_process.running())
22917 p->main_frame->update_slice_print_status(MainFrame::eEventObjectUpdate, model_fits);
22918
22919 return;
22920}
@ eEventObjectUpdate
Definition MainFrame.hpp:337
void post_process_string_object_exception(StringObjectException &err)
Definition Plater.cpp:23695
std::string imex_placement_error(PartPlate *plate)
Definition Plater.cpp:11377
std::string & get_left_extruder_unprintable_text()
Definition GLCanvas3D.cpp:269
std::string & get_object_clashed_text()
Definition GLCanvas3D.cpp:263
wxString filament_printable_error_msg
Definition GLCanvas3D.cpp:302
@ RightExtruderUnprintableError
Definition NotificationManager.hpp:108
@ LeftExtruderUnprintableError
Definition NotificationManager.hpp:107
@ ValidateError
Definition NotificationManager.hpp:92
std::string & get_right_extruder_unprintable_text()
Definition GLCanvas3D.cpp:274
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:22
ModelInstanceEPrintVolumeState
Definition Model.hpp:1410
@ ModelInstancePVS_Partly_Outside
Definition Model.hpp:1413

References Slic3r::GUI::PartPlate::check_filament_printable(), Slic3r::GUI::PartPlate::check_tpu_printable_status(), Slic3r::GUI::MainFrame::eEventObjectUpdate, Slic3r::GUI::filament_printable_error_msg, Slic3r::ObjectFilamentResults::filaments, Slic3r::GUI::PartPlate::get_extruders(), Slic3r::GUI::get_left_extruder_unprintable_text(), Slic3r::GUI::get_object_clashed_text(), Slic3r::GUI::get_right_extruder_unprintable_text(), Slic3r::GUI::LeftExtruderUnprintableError, Slic3r::ModelInstancePVS_Partly_Outside, p, post_process_string_object_exception(), Slic3r::ptFFF, refresh_missing_plugin_block(), Slic3r::GUI::RightExtruderUnprintableError, Slic3r::StringObjectException::string, Slic3r::GUI::PartPlate::update_slice_ready_status(), and Slic3r::GUI::ValidateError.

Referenced by revalidate_current_plate_if_plugins_missing(), select_plate(), and select_plate_by_hover_id().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PlaterDropTarget

friend class PlaterDropTarget
friend

◆ SuppressBackgroundProcessingUpdate

friend class SuppressBackgroundProcessingUpdate
friend

Member Data Documentation

◆ m_3mf_path

std::string Slic3r::GUI::Plater::m_3mf_path
private

Referenced by get_3mf_filename().

◆ m_arrange_running

std::atomic<bool> Slic3r::GUI::Plater::m_arrange_running {false}
1071{false};

Referenced by last_arrange_job_is_finished().

◆ m_b_plate_toolbar_image_dirty

bool Slic3r::GUI::Plater::m_b_plate_toolbar_image_dirty { true }
private

◆ m_check_status

int Slic3r::GUI::Plater::m_check_status = 0
private

◆ m_exported_file

bool Slic3r::GUI::Plater::m_exported_file { false }
private

◆ m_gcode_settings_loaded

bool Slic3r::GUI::Plater::m_gcode_settings_loaded { false }
private
1096{ false };

Referenced by gcode_settings_loaded(), and load_gcode().

◆ m_last_loaded_gcode

wxString Slic3r::GUI::Plater::m_last_loaded_gcode
private

◆ m_loading_project

bool Slic3r::GUI::Plater::m_loading_project { false }
private
1099{ false };

Referenced by is_loading_project(), load_project(), and new_project().

◆ m_new_project_and_check_state

bool Slic3r::GUI::Plater::m_new_project_and_check_state {false}
private
1100{false};

Referenced by is_new_project_and_check_state(), and new_project().

◆ m_only_gcode

bool Slic3r::GUI::Plater::m_only_gcode { false }
private
1094{ false };//just for .gcode file not for .gcode.3mf

Referenced by Plater(), gcode_settings_loaded(), load_files(), load_gcode(), load_project(), new_project(), only_gcode_mode(), and set_only_gcode().

◆ m_plate_toolbar_image_version

unsigned Slic3r::GUI::Plater::m_plate_toolbar_image_version { 0 }
private

◆ m_preview_only_filename

std::string Slic3r::GUI::Plater::m_preview_only_filename
private

◆ m_tracking_popup_menu

bool Slic3r::GUI::Plater::m_tracking_popup_menu = false
private

Referenced by PopupMenu().

◆ m_tracking_popup_menu_error_message

wxString Slic3r::GUI::Plater::m_tracking_popup_menu_error_message
private

Referenced by PopupMenu().

◆ m_valid_plates_count

int Slic3r::GUI::Plater::m_valid_plates_count { 0 }
private
1102{ 0 };

◆ p

std::unique_ptr<priv> Slic3r::GUI::Plater::p
private

Referenced by Plater(), _calib_pa_pattern(), _calib_pa_select_added_objects(), _calib_temp_belt_sectioned(), add_dock_pane(), add_file(), add_model(), add_plate(), allow_snapshots(), apply_background_progress(), apply_cut_object_to_model(), are_view3D_labels_shown(), arrange(), background_process(), bring_instance_forward(), build_volume(), Calib_Cornering(), calib_input_shaping_damp(), calib_input_shaping_freq(), calib_max_vol_speed(), calib_pa(), calib_retraction(), calib_temp(), calib_VFA(), can_add_plate(), can_arrange(), can_copy_to_clipboard(), can_decrease_instances(), can_delete(), can_delete_all(), can_delete_plate(), can_fillcolor(), can_fix_through_cgal(), can_increase_instances(), can_layers_editing(), can_mirror(), can_paste_from_clipboard(), can_redo(), can_reload_from_disk(), can_replace_all_with_stl(), can_replace_with_stl(), can_set_instance_to_object(), can_simplify(), can_smooth_mesh(), can_split(), can_split_to_objects(), can_split_to_volumes(), can_undo(), canvas3D(), canvas3D(), center_selection(), changed_mesh(), changed_object(), changed_object(), changed_objects(), check_ams_status(), clear_undo_redo_stack_main(), collapse_sidebar(), Slic3r::GUI::collect_imex_warnings(), config(), convert_unit(), copy_selection_to_clipboard(), cut_horizontal(), cut_selection_to_clipboard(), decrease_instances(), default_menu(), delete_all_objects_from_model(), delete_object_from_model(), delete_plate(), deselect_all(), drop_selection(), duplicate_plate(), eject_drive(), enable_sidebar(), enable_wireframe(), enter_gizmos_stack(), exit_gizmo(), export_3mf(), export_3mf_copy(), export_config_3mf(), export_core_3mf(), export_gcode(), export_gcode_3mf(), export_published_3mf(), export_stl(), export_toolpaths_to_obj(), fff_print(), fff_print(), filament_action_menu(), fill_bed_with_copies(), fill_bed_with_instances(), fill_color(), find_new_position(), force_filament_colors_update(), force_print_bed_update(), format_imex_ghost_tooltip(), get_assmeble_canvas3D(), get_build_volume_type(), get_camera(), get_camera(), get_collapse_toolbar(), get_collapse_toolbar(), get_colors_for_color_print(), get_current_canvas3D(), get_export_gcode_filename(), get_machine_sync_status(), get_mouse3d_controller(), get_mouse3d_controller(), get_notification_manager(), get_notification_manager(), get_partplate_list(), get_pending_published(), get_prepare_state(), get_preview_canvas3D(), get_print_job_data(), get_project_filename(), get_project_name(), get_select_machine_dialog(), get_selected_object_idx(), get_selection(), get_sidebar_docking_state(), get_ui_job_worker(), get_ui_job_worker(), get_uv_editor_canvas(), get_view3D_canvas3D(), GetPlateIndexByRightMenuInLeftUI(), has_assmeble_view(), has_toolpaths_to_export(), import_model_id(), import_sl1_archive(), increase_instances(), init_collapse_toolbar(), init_notification_manager(), inside_snapshot_capture(), instance_menu(), is_background_process_slicing(), is_background_process_update_scheduled(), is_export_gcode_scheduled(), is_multi_extruder_ams_empty(), is_presets_dirty(), is_preview_loaded(), is_preview_shown(), is_project_dirty(), is_render_statistic_dialog_visible(), is_selection_empty(), is_show_wireframe(), is_show_xray(), is_sidebar_collapsed(), is_sidebar_enabled(), is_single_full_object_selection(), is_view3D_overhang_shown(), is_view3D_shown(), is_wireframe_enabled(), layer_menu(), leave_gizmos_stack(), load_gcode(), load_project(), mirror(), model(), model(), msw_rescale(), multi_selection_menu(), need_update(), new_project(), normalize_bed_types(), object_list_changed(), object_menu(), on_activate(), on_config_change(), on_filaments_delete(), on_imex_ghost_click(), open_filament_map_setting_dialog(), open_platesettings_dialog(), optimize_rotation(), orient(), part_menu(), paste_from_clipboard(), plate_menu(), PopupObjectTable(), PopupObjectTableBySelection(), print_job_finished(), printer_technology(), redo(), redo_to(), refresh_belt_view(), refresh_missing_plugin_block(), reload_all_from_disk(), reload_from_disk(), reload_paint_after_background_process_apply(), reload_print(), remove(), remove_curr_plate_all(), remove_dock_pane(), remove_dock_panes(), remove_selected(), replace_all_with_stl(), replace_with_stl(), reset(), reset_canvas_volumes(), reset_gcode_toolpaths(), reset_project_dirty_after_save(), reset_project_dirty_initial_presets(), reset_window_layout(), reset_with_confirm(), reslice(), reslice_SLA_until_step(), revalidate_current_plate_if_plugins_missing(), save_project(), save_project_if_dirty(), scale_selection_to_fit_print_volume(), schedule_background_process(), search(), search_string_getter(), select_all(), select_curr_plate_all(), select_plate(), select_plate_by_hover_id(), select_sliced_plate(), select_view(), select_view_3D(), send_calibration_job_finished(), send_gcode(), send_gcode_finish(), send_gcode_legacy(), send_job_finished(), send_to_printer(), set_bed_position(), set_bed_shape(), set_bed_shape(), set_current_canvas_as_dirty(), Slic3r::GUI::Plater::priv::set_current_panel(), set_global_filament_map(), set_need_update(), set_number_of_copies(), set_pending_published(), set_plater_dirty(), set_prepare_state(), set_print_job_plate_idx(), set_printer_technology(), set_project_filename(), set_selected_visible(), SetPlateIndexByRightMenuInLeftUI(), show_collision_volumes(), show_dock_pane(), show_object_info(), show_uv_editor(), show_view3D_labels(), show_view3D_overhang(), sidebar(), single_snapshots_enter(), single_snapshots_leave(), sla_object_menu(), sla_print(), sla_print(), split_object(), split_volume(), start_next_slice(), suppress_background_process(), suppress_snapshots(), svg_part_menu(), sys_color_changed(), take_snapshot(), take_snapshot(), text_part_menu(), toggle_render_statistic_dialog(), toggle_show_wireframe(), toggle_show_xray(), unbind_canvas_event_handlers(), undo(), undo_redo_stack_main(), undo_redo_string_getter(), undo_redo_topmost_string_getter(), undo_to(), up_to_date(), update(), update_filament_colors_in_full_config(), update_menus(), update_objects_position_when_select_preset(), update_preview_bottom_toolbar(), update_print_error_info(), update_print_required_data(), update_project_dirty_from_presets(), update_slicing_context_to_current_partplate(), update_title_dirty_status(), update_ui_from_settings(), and validate_current_plate().

◆ skip_thumbnail_invalid

bool Slic3r::GUI::Plater::skip_thumbnail_invalid { false }
private

The documentation for this class was generated from the following files:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/Plater.hpp
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/Plater.cpp