From fae06e0773abf1cf6a04a66615958724e162797a Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Sat, 19 Oct 2024 22:55:33 +0200 Subject: [PATCH] Vectorization of the wipe tower --- src/libslic3r/Arrange/SceneBuilder.cpp | 2 +- src/libslic3r/Format/3mf.cpp | 74 ++++++++++++------- src/libslic3r/GCode.cpp | 2 +- src/libslic3r/GCode/PrintExtents.cpp | 4 +- src/libslic3r/Model.cpp | 14 +++- src/libslic3r/Model.hpp | 32 +++----- src/libslic3r/ObjectID.cpp | 20 ++--- src/libslic3r/ObjectID.hpp | 6 +- src/libslic3r/Print.cpp | 10 +-- src/libslic3r/PrintApply.cpp | 4 +- src/slic3r/GUI/3DScene.cpp | 2 +- src/slic3r/GUI/GCodeViewer.cpp | 4 +- src/slic3r/GUI/GLCanvas3D.cpp | 22 +++--- src/slic3r/GUI/Jobs/ArrangeJob2.cpp | 2 +- src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp | 4 +- src/slic3r/GUI/Plater.cpp | 8 +- tests/arrange/test_arrange_integration.cpp | 4 +- 17 files changed, 117 insertions(+), 97 deletions(-) diff --git a/src/libslic3r/Arrange/SceneBuilder.cpp b/src/libslic3r/Arrange/SceneBuilder.cpp index 35a9189623..9809ef59ab 100644 --- a/src/libslic3r/Arrange/SceneBuilder.cpp +++ b/src/libslic3r/Arrange/SceneBuilder.cpp @@ -567,7 +567,7 @@ void ArrangeableSlicerModel::for_each_arrangeable_(Self &&self, Fn &&fn) template void ArrangeableSlicerModel::visit_arrangeable_(Self &&self, const ObjectID &id, Fn &&fn) { - if (id == self.m_model->wipe_tower.id()) { + if (id == wipe_tower_instance_id(0)) { self.m_wth->visit(fn); return; diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 2634cd6490..1edc3b50e5 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -47,6 +47,8 @@ namespace pt = boost::property_tree; #include "libslic3r/NSVGUtils.hpp" +#include "libslic3r/MultipleBeds.hpp" + #include // Slightly faster than sprintf("%.9g"), but there is an issue with the karma floating point formatter, @@ -773,7 +775,7 @@ namespace Slic3r { } // Initialize the wipe tower position (see the end of this function): - model.wipe_tower.position.x() = std::numeric_limits::max(); + model.get_wipe_tower_vector().front().position.x() = std::numeric_limits::max(); // Read root model file if (start_part_stat.m_file_index < num_entries) { @@ -850,13 +852,13 @@ namespace Slic3r { } - if (model.wipe_tower.position.x() == std::numeric_limits::max()) { + if (model.get_wipe_tower_vector().front().position.x() == std::numeric_limits::max()) { // This is apparently an old project from before PS 2.9.0, which saved wipe tower pos and rotation // into config, not into Model. Try to load it from the config file. // First set default in case we do not find it (these were the default values of the config options). - model.wipe_tower.position.x() = 180; - model.wipe_tower.position.y() = 140; - model.wipe_tower.rotation = 0.; + model.get_wipe_tower_vector().front().position.x() = 180; + model.get_wipe_tower_vector().front().position.y() = 140; + model.get_wipe_tower_vector().front().rotation = 0.; for (mz_uint i = 0; i < num_entries; ++i) { if (mz_zip_reader_file_stat(&archive, i, &stat)) { @@ -1679,17 +1681,29 @@ namespace Slic3r { pt::ptree main_tree; pt::read_xml(iss, main_tree); - try { - auto& node = main_tree.get_child("wipe_tower_information"); - double pos_x = node.get(".position_x"); - double pos_y = node.get(".position_y"); - double rot_deg = node.get(".rotation_deg"); - model.wipe_tower.position = Vec2d(pos_x, pos_y); - model.wipe_tower.rotation = rot_deg; - } catch (const boost::property_tree::ptree_bad_path&) { - // Handles missing node or attribute. - add_error("Error while reading wipe tower information."); - return; + for (const auto& bed_block : main_tree) { + if (bed_block.first != "wipe_tower_information") + continue; + try { + int bed_idx = 0; + try { + bed_idx = bed_block.second.get(".bed_idx"); + } catch (const boost::property_tree::ptree_bad_path&) { + // Probably an old project with no bed_idx info - pretend that we saw 0. + } + if (bed_idx >= int(m_model->get_wipe_tower_vector().size())) + continue; + double pos_x = bed_block.second.get(".position_x"); + double pos_y = bed_block.second.get(".position_y"); + double rot_deg = bed_block.second.get(".rotation_deg"); + model.get_wipe_tower_vector()[bed_idx].position = Vec2d(pos_x, pos_y); + model.get_wipe_tower_vector()[bed_idx].rotation = rot_deg; + } + catch (const boost::property_tree::ptree_bad_path&) { + // Handles missing node or attribute. + add_error("Error while reading wipe tower information."); + return; + } } } @@ -1725,11 +1739,11 @@ namespace Slic3r { value_ss >> val; if (! value_ss.fail()) { if (boost::starts_with(line, "wipe_tower_x")) - model.wipe_tower.position.x() = val; + model.get_wipe_tower_vector().front().position.x() = val; else if (boost::starts_with(line, "wipe_tower_y")) - model.wipe_tower.position.y() = val; + model.get_wipe_tower_vector().front().position.y() = val; else - model.wipe_tower.rotation = val; + model.get_wipe_tower_vector().front().rotation = val; } } } @@ -3621,11 +3635,11 @@ namespace Slic3r { std::string opt_serialized; if (key == "wipe_tower_x") - opt_serialized = float_to_string_decimal_point(model.wipe_tower.position.x()); + opt_serialized = float_to_string_decimal_point(model.get_wipe_tower_vector().front().position.x()); else if (key == "wipe_tower_y") - opt_serialized = float_to_string_decimal_point(model.wipe_tower.position.y()); + opt_serialized = float_to_string_decimal_point(model.get_wipe_tower_vector().front().position.y()); else if (key == "wipe_tower_rotation_angle") - opt_serialized = float_to_string_decimal_point(model.wipe_tower.rotation); + opt_serialized = float_to_string_decimal_point(model.get_wipe_tower_vector().front().rotation); else opt_serialized = config.opt_serialize(key); @@ -3842,11 +3856,19 @@ bool _3MF_Exporter::_add_wipe_tower_information_file_to_archive( mz_zip_archive& std::string out = ""; pt::ptree tree; - pt::ptree& main_tree = tree.add("wipe_tower_information", ""); - main_tree.put(".position_x", model.wipe_tower.position.x()); - main_tree.put(".position_y", model.wipe_tower.position.y()); - main_tree.put(".rotation_deg", model.wipe_tower.rotation); + size_t bed_idx = 0; + for (const ModelWipeTower& wipe_tower : model.get_wipe_tower_vector()) { + pt::ptree& main_tree = tree.add("wipe_tower_information", ""); + + main_tree.put(".bed_idx", bed_idx); + main_tree.put(".position_x", wipe_tower.position.x()); + main_tree.put(".position_y", wipe_tower.position.y()); + main_tree.put(".rotation_deg", wipe_tower.rotation); + ++bed_idx; + if (bed_idx >= s_multiple_beds.get_number_of_beds()) + break; + } std::ostringstream oss; boost::property_tree::write_xml(oss, tree); diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 4592af045a..111ff6c665 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1314,7 +1314,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail std::vector> layers_to_print = collect_layers_to_print(print); // Prusa Multi-Material wipe tower. if (has_wipe_tower && ! layers_to_print.empty()) { - m_wipe_tower = std::make_unique(print.model().wipe_tower.position.cast(), print.model().wipe_tower.rotation, print.config(), *print.wipe_tower_data().priming.get(), print.wipe_tower_data().tool_changes, *print.wipe_tower_data().final_purge.get()); + m_wipe_tower = std::make_unique(print.model().wipe_tower().position.cast(), print.model().wipe_tower().rotation, print.config(), *print.wipe_tower_data().priming.get(), print.wipe_tower_data().tool_changes, *print.wipe_tower_data().final_purge.get()); // Set position for wipe tower generation. Vec3d new_position = this->writer().get_position(); diff --git a/src/libslic3r/GCode/PrintExtents.cpp b/src/libslic3r/GCode/PrintExtents.cpp index 8b38a20a8d..0842279d19 100644 --- a/src/libslic3r/GCode/PrintExtents.cpp +++ b/src/libslic3r/GCode/PrintExtents.cpp @@ -151,8 +151,8 @@ BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_ // Wipe tower extrusions are saved as if the tower was at the origin with no rotation // We need to get position and angle of the wipe tower to transform them to actual position. Transform2d trafo = - Eigen::Translation2d(print.model().wipe_tower.position.x(), print.model().wipe_tower.position.y()) * - Eigen::Rotation2Dd(Geometry::deg2rad(print.model().wipe_tower.rotation)); + Eigen::Translation2d(print.model().wipe_tower().position.x(), print.model().wipe_tower().position.y()) * + Eigen::Rotation2Dd(Geometry::deg2rad(print.model().wipe_tower().rotation)); BoundingBoxf bbox; for (const std::vector &tool_changes : print.wipe_tower_data().tool_changes) { diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index f1c18b1a1c..67c261dcba 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -70,7 +70,7 @@ Model& Model::assign_copy(const Model &rhs) // copy custom code per height this->custom_gcode_per_print_z_vector = rhs.custom_gcode_per_print_z_vector; - this->wipe_tower = rhs.wipe_tower; + this->wipe_tower_vector = rhs.wipe_tower_vector; return *this; } @@ -93,7 +93,7 @@ Model& Model::assign_copy(Model &&rhs) // copy custom code per height this->custom_gcode_per_print_z_vector = std::move(rhs.custom_gcode_per_print_z_vector); - this->wipe_tower = rhs.wipe_tower; + this->wipe_tower_vector = rhs.wipe_tower_vector; return *this; } @@ -120,6 +120,16 @@ void Model::update_links_bottom_up_recursive() } } +ModelWipeTower& Model::wipe_tower() +{ + return const_cast(const_cast(this)->wipe_tower()); +} + +const ModelWipeTower& Model::wipe_tower() const +{ + return wipe_tower_vector[s_multiple_beds.get_active_bed()]; +} + CustomGCode::Info& Model::custom_gcode_per_print_z() { return const_cast(const_cast(this)->custom_gcode_per_print_z()); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index c8660d396f..2fad659305 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -1253,7 +1253,7 @@ private: // Note: The following class does not have to inherit from ObjectID, it is currently // only used for arrangement. It might be good to refactor this in future. -class ModelWipeTower final : public ObjectBase +class ModelWipeTower { public: Vec2d position = Vec2d(180., 140.); @@ -1265,25 +1265,9 @@ public: // Assignment operator does not touch the ID! ModelWipeTower& operator=(const ModelWipeTower& rhs) { position = rhs.position; rotation = rhs.rotation; return *this; } - -private: - friend class cereal::access; - friend class UndoRedo::StackImpl; - friend class Model; - - // Constructors to be only called by derived classes. - // Default constructor to assign a unique ID. explicit ModelWipeTower() {} - // Constructor with ignored int parameter to assign an invalid ID, to be replaced - // by an existing ID copied from elsewhere. - explicit ModelWipeTower(int) : ObjectBase(-1) {} - // Copy constructor copies the ID. explicit ModelWipeTower(const ModelWipeTower &cfg) = default; - // Disabled methods. - ModelWipeTower(ModelWipeTower &&rhs) = delete; - ModelWipeTower& operator=(ModelWipeTower &&rhs) = delete; - // For serialization / deserialization of ModelWipeTower composed into another class into the Undo / Redo stack as a separate object. template void serialize(Archive &ar) { ar(position, rotation); } }; @@ -1301,14 +1285,21 @@ public: ModelMaterialMap materials; // Objects are owned by a model. Each model may have multiple instances, each instance having its own transformation (shift, scale, rotation). ModelObjectPtrs objects; - // Wipe tower object. - ModelWipeTower wipe_tower; + + ModelWipeTower& wipe_tower(); + const ModelWipeTower& wipe_tower() const; + std::vector& get_wipe_tower_vector() { return wipe_tower_vector; } + const std::vector& get_wipe_tower_vector() const { return wipe_tower_vector; } + CustomGCode::Info& custom_gcode_per_print_z(); const CustomGCode::Info& custom_gcode_per_print_z() const; std::vector& get_custom_gcode_per_print_z_vector() { return custom_gcode_per_print_z_vector; } private: + // Wipe tower object. + std::vector wipe_tower_vector = std::vector(MAX_NUMBER_OF_BEDS); + // Extensions for color print std::vector custom_gcode_per_print_z_vector = std::vector(MAX_NUMBER_OF_BEDS); @@ -1413,8 +1404,7 @@ private: friend class cereal::access; friend class UndoRedo::StackImpl; template void serialize(Archive &ar) { - Internal::StaticSerializationWrapper wipe_tower_wrapper(wipe_tower); - ar(materials, objects, wipe_tower_wrapper); + ar(materials, objects, wipe_tower_vector); } }; diff --git a/src/libslic3r/ObjectID.cpp b/src/libslic3r/ObjectID.cpp index fd650e8140..d204ef7a92 100644 --- a/src/libslic3r/ObjectID.cpp +++ b/src/libslic3r/ObjectID.cpp @@ -8,17 +8,19 @@ namespace Slic3r { size_t ObjectBase::s_last_id = 0; -// Unique object / instance ID for the wipe tower. -ObjectID wipe_tower_object_id() -{ - static ObjectBase mine; - return mine.id(); -} +struct WipeTowerId : public ObjectBase { + // Need to inherit because ObjectBase + // destructor is protected. + using ObjectBase::ObjectBase; +}; -ObjectID wipe_tower_instance_id() +ObjectID wipe_tower_instance_id(size_t bed_idx) { - static ObjectBase mine; - return mine.id(); + static std::vector mine; + if (bed_idx >= mine.size()) { + mine.resize(bed_idx + 1); + } + return mine[bed_idx].id(); } ObjectWithTimestamp::Timestamp ObjectWithTimestamp::s_last_timestamp = 1; diff --git a/src/libslic3r/ObjectID.hpp b/src/libslic3r/ObjectID.hpp index 529538074d..a7253173af 100644 --- a/src/libslic3r/ObjectID.hpp +++ b/src/libslic3r/ObjectID.hpp @@ -86,9 +86,6 @@ private: static inline ObjectID generate_new_id() { return ObjectID(++ s_last_id); } static size_t s_last_id; - - friend ObjectID wipe_tower_object_id(); - friend ObjectID wipe_tower_instance_id(); friend class cereal::access; friend class Slic3r::UndoRedo::StackImpl; @@ -135,8 +132,7 @@ private: }; // Unique object / instance ID for the wipe tower. -extern ObjectID wipe_tower_object_id(); -extern ObjectID wipe_tower_instance_id(); +ObjectID wipe_tower_instance_id(size_t bed_idx); } // namespace Slic3r diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 4e14649e53..f7f15cd49c 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1048,8 +1048,8 @@ void Print::process() if (this->has_wipe_tower()) { // These values have to be updated here, not during wipe tower generation. // When the wipe tower is moved/rotated, it is not regenerated. - m_wipe_tower_data.position = model().wipe_tower.position; - m_wipe_tower_data.rotation_angle = model().wipe_tower.rotation; + m_wipe_tower_data.position = model().wipe_tower().position; + m_wipe_tower_data.rotation_angle = model().wipe_tower().rotation; } auto conflictRes = ConflictChecker::find_inter_of_lines_in_diff_objs(objects(), m_wipe_tower_data); @@ -1278,8 +1278,8 @@ Points Print::first_layer_wipe_tower_corners() const pts.emplace_back(center + r*Vec2d(std::cos(alpha)/cone_x_scale, std::sin(alpha))); for (Vec2d& pt : pts) { - pt = Eigen::Rotation2Dd(Geometry::deg2rad(model().wipe_tower.rotation)) * pt; - pt += model().wipe_tower.position; + pt = Eigen::Rotation2Dd(Geometry::deg2rad(model().wipe_tower().rotation)) * pt; + pt += model().wipe_tower().position; pts_scaled.emplace_back(Point(scale_(pt.x()), scale_(pt.y()))); } } @@ -1553,7 +1553,7 @@ void Print::_make_wipe_tower() this->throw_if_canceled(); // Initialize the wipe tower. - WipeTower wipe_tower(model().wipe_tower.position.cast(), model().wipe_tower.rotation, m_config, m_default_region_config, wipe_volumes, m_wipe_tower_data.tool_ordering.first_extruder()); + WipeTower wipe_tower(model().wipe_tower().position.cast(), model().wipe_tower().rotation, m_config, m_default_region_config, wipe_volumes, m_wipe_tower_data.tool_ordering.first_extruder()); // Set the extruder & material properties at the wipe tower object. for (size_t i = 0; i < m_config.nozzle_diameter.size(); ++ i) diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 5018eedd64..3ab77d7a64 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -1123,9 +1123,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ } // Check the position and rotation of the wipe tower. - if (model.wipe_tower != m_model.wipe_tower) + if (model.wipe_tower() != m_model.wipe_tower()) update_apply_status(this->invalidate_step(psSkirtBrim)); - m_model.wipe_tower = model.wipe_tower; + m_model.wipe_tower() = model.wipe_tower(); ModelObjectStatusDB model_object_status_db; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 21290486ad..5b69de646a 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -606,7 +606,7 @@ int GLVolumeCollection::load_wipe_tower_preview( v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle)); v.composite_id = GLVolume::CompositeID(INT_MAX, 0, 0); v.geometry_id.first = 0; - v.geometry_id.second = wipe_tower_instance_id().id; + v.geometry_id.second = wipe_tower_instance_id(0).id; v.is_wipe_tower = true; v.shader_outside_printer_detection_enabled = !size_unknown; return int(volumes.size() - 1); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 1405912910..e06b5426b7 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1698,8 +1698,8 @@ void GCodeViewer::load_wipetower_shell(const Print& print) const std::vector> z_and_depth_pairs = print.wipe_tower_data(extruders_count).z_and_depth_pairs; const float brim_width = wipe_tower_data.brim_width; if (depth != 0.) { - m_shells.volumes.load_wipe_tower_preview(wxGetApp().plater()->model().wipe_tower.position.x(), wxGetApp().plater()->model().wipe_tower.position.y(), config.wipe_tower_width, depth, z_and_depth_pairs, - max_z, config.wipe_tower_cone_angle, wxGetApp().plater()->model().wipe_tower.rotation, false, brim_width); + m_shells.volumes.load_wipe_tower_preview(wxGetApp().plater()->model().wipe_tower().position.x(), wxGetApp().plater()->model().wipe_tower().position.y(), config.wipe_tower_width, depth, z_and_depth_pairs, + max_z, config.wipe_tower_cone_angle, wxGetApp().plater()->model().wipe_tower().rotation, false, brim_width); GLVolume* volume = m_shells.volumes.volumes.back(); volume->color.a(0.25f); volume->force_native_color = true; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e4bb744ddc..0a6913ff62 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2454,10 +2454,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re if (extruders_count > 1 && wt && !co) { - const float x = m_model->wipe_tower.position.x(); - const float y = m_model->wipe_tower.position.y(); + 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 = m_model->wipe_tower.rotation; + 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; @@ -4042,7 +4042,7 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_MOVED)); if (wipe_tower_origin != Vec3d::Zero()) { - m_model->wipe_tower.position = Vec2d(wipe_tower_origin[0], wipe_tower_origin[1]); + m_model->wipe_tower().position = Vec2d(wipe_tower_origin[0], wipe_tower_origin[1]); post_event(SimpleEvent(EVT_GLCANVAS_WIPETOWER_TOUCHED)); } @@ -4088,8 +4088,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()); - m_model->wipe_tower.position = Vec2d(offset.x(), offset.y()); - m_model->wipe_tower.rotation = (180./M_PI) * 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) @@ -4406,9 +4406,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_model->wipe_tower.position.x(), - m_model->wipe_tower.position.y()); - wti.m_rotation = (M_PI/180.) * m_model->wipe_tower.rotation; + 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; @@ -7000,8 +7000,8 @@ const SLAPrint* GLCanvas3D::sla_print() const void GLCanvas3D::WipeTowerInfo::apply_wipe_tower(Vec2d pos, double rot) { - wxGetApp().plater()->model().wipe_tower.position = pos; - wxGetApp().plater()->model().wipe_tower.rotation = (180./M_PI) * rot; + 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/Jobs/ArrangeJob2.cpp b/src/slic3r/GUI/Jobs/ArrangeJob2.cpp index 81eb7459ea..d913d93b0d 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob2.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob2.cpp @@ -180,7 +180,7 @@ arr2::SceneBuilder build_scene(Plater &plater, ArrangeSelectionMode mode) AnyPtr wth; if (wti) { - wth = std::make_unique(plater.model().wipe_tower.id(), wti); + wth = std::make_unique(wipe_tower_instance_id(0), wti); } if (plater.config()) { diff --git a/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp index 6cbe195c43..e02fba2fa1 100644 --- a/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp +++ b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp @@ -427,8 +427,8 @@ public: if (wipe_tower_data.final_purge) m_final.emplace_back(*wipe_tower_data.final_purge.get()); - m_angle = print.model().wipe_tower.rotation / 180.0f * PI; - m_position = print.model().wipe_tower.position.cast(); + m_angle = print.model().wipe_tower().rotation / 180.0f * PI; + m_position = print.model().wipe_tower().position.cast(); m_layers_count = wipe_tower_data.tool_changes.size() + (m_priming.empty() ? 0 : 1); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 72c5e2a4fa..c9b33b8db2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1330,7 +1330,7 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (load_config) { this->model.get_custom_gcode_per_print_z_vector() = model.get_custom_gcode_per_print_z_vector(); - this->model.wipe_tower = model.wipe_tower; + this->model.get_wipe_tower_vector() = model.get_wipe_tower_vector(); } } @@ -3388,13 +3388,13 @@ void Plater::priv::on_right_click(RBtnEvent& evt) void Plater::priv::on_wipetower_moved(Vec3dEvent &evt) { - model.wipe_tower.position = Vec2d(evt.data[0], evt.data[1]); + model.wipe_tower().position = Vec2d(evt.data[0], evt.data[1]); } void Plater::priv::on_wipetower_rotated(Vec3dEvent& evt) { - model.wipe_tower.position = Vec2d(evt.data[0], evt.data[1]); - model.wipe_tower.rotation = Geometry::rad2deg(evt.data(2)); + 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>&) diff --git a/tests/arrange/test_arrange_integration.cpp b/tests/arrange/test_arrange_integration.cpp index 2f1a345f34..9a5f8dc6d3 100644 --- a/tests/arrange/test_arrange_integration.cpp +++ b/tests/arrange/test_arrange_integration.cpp @@ -1001,7 +1001,7 @@ TEST_CASE("Test SceneBuilder", "[arrange2][integration]") arr2::SceneBuilder bld; Model mdl; bld.set_model(mdl); - bld.set_wipe_tower_handler(std::make_unique(mdl.wipe_tower.id())); + bld.set_wipe_tower_handler(std::make_unique(wipe_tower_instance_id(0))); WHEN("the selection mask is initialized as a fallback default in the created scene") { @@ -1014,7 +1014,7 @@ TEST_CASE("Test SceneBuilder", "[arrange2][integration]") bool wt_selected = false; scene.model() - .visit_arrangeable(mdl.wipe_tower.id(), + .visit_arrangeable(wipe_tower_instance_id(0), [&wt_selected]( const arr2::Arrangeable &arrbl) { wt_selected = arrbl.is_selected();