diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 50265cb670..29a7e3fcf9 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -1193,8 +1193,12 @@ private: class ModelWipeTower final : public ObjectBase { public: - Vec2d position; - double rotation; + Vec2d position = Vec2d(180., 140.); + double rotation = 0.; + + bool operator==(const ModelWipeTower& other) const { return position == other.position && rotation == other.rotation; } + bool operator!=(const ModelWipeTower& other) const { return !((*this) == other); } + private: friend class cereal::access; diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index eaf593aade..aa80cb6e28 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -1066,7 +1066,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ num_extruders_changed = true; } } - + ModelObjectStatusDB model_object_status_db; // 1) Synchronize model objects. diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7b79215c1a..8c9e028487 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1011,8 +1011,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_RESET_SKEW, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MIRRORED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent); -wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); -wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent); +wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_TOUCHED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event); wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>); wxDEFINE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_STARTED, SimpleEvent); @@ -2392,10 +2391,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re if (extruders_count > 1 && wt && !co) { - const float x = dynamic_cast(m_config->option("wipe_tower_x"))->value; - const float y = dynamic_cast(m_config->option("wipe_tower_y"))->value; + const float x = m_model->wipe_tower.position.x(); + const float y = m_model->wipe_tower.position.y(); const float w = dynamic_cast(m_config->option("wipe_tower_width"))->value; - const float a = dynamic_cast(m_config->option("wipe_tower_rotation_angle"))->value; + const float a = m_model->wipe_tower.rotation; const float bw = dynamic_cast(m_config->option("wipe_tower_brim_width"))->value; const float ca = dynamic_cast(m_config->option("wipe_tower_cone_angle"))->value; @@ -3954,8 +3953,10 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) if (object_moved) post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_MOVED)); - if (wipe_tower_origin != Vec3d::Zero()) - post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_MOVED, std::move(wipe_tower_origin))); + if (wipe_tower_origin != Vec3d::Zero()) { + m_model->wipe_tower.position = Vec2d(wipe_tower_origin[0], wipe_tower_origin[1]); + post_event(SimpleEvent(EVT_GLCANVAS_WIPETOWER_TOUCHED)); + } if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects) { update_sequential_clearance(true); @@ -3999,7 +4000,8 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) const Vec3d offset = v->get_volume_offset(); Vec3d rot_unit_x = v->get_volume_transformation().get_matrix().linear() * Vec3d::UnitX(); double z_rot = std::atan2(rot_unit_x.y(), rot_unit_x.x()); - post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), z_rot))); + m_model->wipe_tower.position = Vec2d(offset.x(), offset.y()); + m_model->wipe_tower.rotation = (180./M_PI) * z_rot; } const int object_idx = v->object_idx(); if (object_idx < 0 || (int)m_model->objects.size() <= object_idx) @@ -4316,9 +4318,9 @@ GLCanvas3D::WipeTowerInfo GLCanvas3D::get_wipe_tower_info() const for (const GLVolume* vol : m_volumes.volumes) { if (vol->is_wipe_tower) { - wti.m_pos = Vec2d(m_config->opt_float("wipe_tower_x"), - m_config->opt_float("wipe_tower_y")); - wti.m_rotation = (M_PI/180.) * m_config->opt_float("wipe_tower_rotation_angle"); + wti.m_pos = Vec2d(m_model->wipe_tower.position.x(), + m_model->wipe_tower.position.y()); + wti.m_rotation = (M_PI/180.) * m_model->wipe_tower.rotation; const BoundingBoxf3& bb = vol->bounding_box(); wti.m_bb = BoundingBoxf{to_2d(bb.min), to_2d(bb.max)}; break; @@ -6885,11 +6887,8 @@ const SLAPrint* GLCanvas3D::sla_print() const void GLCanvas3D::WipeTowerInfo::apply_wipe_tower(Vec2d pos, double rot) { - DynamicPrintConfig cfg; - cfg.opt("wipe_tower_x", true)->value = pos.x(); - cfg.opt("wipe_tower_y", true)->value = pos.y(); - cfg.opt("wipe_tower_rotation_angle", true)->value = (180./M_PI) * rot; - wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg); + wxGetApp().plater()->model().wipe_tower.position = pos; + wxGetApp().plater()->model().wipe_tower.rotation = (180./M_PI) * rot; } void GLCanvas3D::RenderTimer::Notify() diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index aed8f199ac..f96a958991 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -163,12 +163,11 @@ wxDECLARE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event); // data: +1 => increase, -1 => decrease wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent); -wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); +wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_TOUCHED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_RESET_SKEW, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MIRRORED, SimpleEvent); -wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent); wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event); wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>); wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_STARTED, SimpleEvent); @@ -919,8 +918,6 @@ public: inline double rotation() const { return m_rotation; } inline const Vec2d bb_size() const { return m_bb.size(); } inline const BoundingBoxf& bounding_box() const { return m_bb; } - - void apply_wipe_tower() const { apply_wipe_tower(m_pos, m_rotation); } static void apply_wipe_tower(Vec2d pos, double rot); }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9438c6c22b..760284a1c9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -701,8 +701,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) { if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); }); view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); }); view3D_canvas->Bind(EVT_GLCANVAS_FORCE_UPDATE, [this](SimpleEvent&) { update(); }); - view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this); - view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this); + view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_TOUCHED,[this](SimpleEvent&) { update(); }); view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); }); view3D_canvas->Bind(EVT_GLCANVAS_RESET_SKEW, [this](SimpleEvent&) { update(); }); view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_SCALED, [this](SimpleEvent&) { update(); }); @@ -2092,6 +2091,12 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool if (full_config.has("binary_gcode")) // needed for SLA full_config.set("binary_gcode", bool(full_config.opt_bool("binary_gcode") & wxGetApp().app_config->get_bool("use_binary_gcode_when_supported"))); + // Also tell the backend about the position of the wipe tower. + // TODO: Refactor the backend and the apply function to take this from the Model. + full_config.set("wipe_tower_x", model.wipe_tower.position.x(), true); + full_config.set("wipe_tower_y", model.wipe_tower.position.y(), true); + full_config.set("wipe_tower_rotation_angle", model.wipe_tower.rotation, true); + const Preset &selected_printer = wxGetApp().preset_bundle->printers.get_selected_preset(); std::string printer_model_serialized = full_config.option("printer_model")->serialize(); std::string vendor_repo_prefix; @@ -3234,19 +3239,13 @@ void Plater::priv::on_right_click(RBtnEvent& evt) void Plater::priv::on_wipetower_moved(Vec3dEvent &evt) { - DynamicPrintConfig cfg; - cfg.opt("wipe_tower_x", true)->value = evt.data(0); - cfg.opt("wipe_tower_y", true)->value = evt.data(1); - wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg); + model.wipe_tower.position = Vec2d(evt.data[0], evt.data[1]); } void Plater::priv::on_wipetower_rotated(Vec3dEvent& evt) { - DynamicPrintConfig cfg; - cfg.opt("wipe_tower_x", true)->value = evt.data(0); - cfg.opt("wipe_tower_y", true)->value = evt.data(1); - cfg.opt("wipe_tower_rotation_angle", true)->value = Geometry::rad2deg(evt.data(2)); - wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg); + model.wipe_tower.position = Vec2d(evt.data[0], evt.data[1]); + model.wipe_tower.rotation = Geometry::rad2deg(evt.data(2)); } void Plater::priv::on_update_geometry(Vec3dsEvent<2>&) @@ -3789,13 +3788,6 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed if (view3D->get_canvas3d()->get_gizmos_manager().wants_reslice_supports_on_undo()) snapshot_data.flags |= UndoRedo::SnapshotData::RECALCULATE_SLA_SUPPORTS; - //FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config. - // This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config. - if (this->printer_technology == ptFFF) { - const DynamicPrintConfig &config = wxGetApp().preset_bundle->prints.get_edited_preset().config; - model.wipe_tower.position = Vec2d(config.opt_float("wipe_tower_x"), config.opt_float("wipe_tower_y")); - model.wipe_tower.rotation = config.opt_float("wipe_tower_rotation_angle"); - } const GLGizmosManager& gizmos = view3D->get_canvas3d()->get_gizmos_manager(); if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator && get_config_bool("clear_undo_redo_stack_on_new_project")) @@ -3865,13 +3857,6 @@ void Plater::priv::undo_redo_to(std::vector::const_iterator } // Save the last active preset name of a particular printer technology. ((this->printer_technology == ptFFF) ? m_last_fff_printer_profile_name : m_last_sla_printer_profile_name) = wxGetApp().preset_bundle->printers.get_selected_preset_name(); - //FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config. - // This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config. - if (this->printer_technology == ptFFF) { - const DynamicPrintConfig &config = wxGetApp().preset_bundle->prints.get_edited_preset().config; - model.wipe_tower.position = Vec2d(config.opt_float("wipe_tower_x"), config.opt_float("wipe_tower_y")); - model.wipe_tower.rotation = config.opt_float("wipe_tower_rotation_angle"); - } const int layer_range_idx = it_snapshot->snapshot_data.layer_range_idx; // Flags made of Snapshot::Flags enum values. unsigned int new_flags = it_snapshot->snapshot_data.flags; @@ -3921,22 +3906,6 @@ void Plater::priv::undo_redo_to(std::vector::const_iterator // This also switches the printer technology based on the printer technology of the active printer profile. wxGetApp().load_current_presets(); } - //FIXME updating the Print config from the Wipe tower config values at the ModelWipeTower. - // This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config. - if (this->printer_technology == ptFFF) { - const DynamicPrintConfig ¤t_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; - Vec2d current_position(current_config.opt_float("wipe_tower_x"), current_config.opt_float("wipe_tower_y")); - double current_rotation = current_config.opt_float("wipe_tower_rotation_angle"); - if (current_position != model.wipe_tower.position || current_rotation != model.wipe_tower.rotation) { - DynamicPrintConfig new_config; - new_config.set_key_value("wipe_tower_x", new ConfigOptionFloat(model.wipe_tower.position.x())); - new_config.set_key_value("wipe_tower_y", new ConfigOptionFloat(model.wipe_tower.position.y())); - new_config.set_key_value("wipe_tower_rotation_angle", new ConfigOptionFloat(model.wipe_tower.rotation)); - Tab *tab_print = wxGetApp().get_tab(Preset::TYPE_PRINT); - tab_print->load_config(new_config); - tab_print->update_dirty(); - } - } // set selection mode for ObjectList on sidebar this->sidebar->obj_list()->set_selection_mode(new_selected_settings_on_sidebar ? ObjectList::SELECTION_MODE::smSettings : new_selected_layer_on_sidebar ? ObjectList::SELECTION_MODE::smLayer :