diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 167d77e3e..fd08cd5e7 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -324,6 +324,11 @@ static void glfw_callback(int error_code, const char* description) BOOST_LOG_TRIVIAL(error) << "error_code " < &load_configs = m_config.option("load_settings", true)->values; //BBS: always use ForwardCompatibilitySubstitutionRule::Enable //const ForwardCompatibilitySubstitutionRule config_substitution_rule = m_config.option>("config_compatibility", true)->value; @@ -540,6 +547,11 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << "object "<name <<", id :" << o->id().id << ", from bbl 3mf\n"; } + Semver old_version(1, 5, 9); + if ((file_version < old_version) && !config.empty()) { + translate_old = true; + } + /*for (ModelObject *model_object : model.objects) for (ModelInstance *model_instance : model_object->instances) { @@ -1280,7 +1292,15 @@ int CLI::run(int argc, char **argv) if (m_models.size() > 0) { std::string bed_texture; - partplate_list.reset_size(bedfs[2].x() - bedfs[0].x(), bedfs[2].y() - bedfs[0].y(), print_height); + if (translate_old) { + current_width = bedfs[2].x() - bedfs[0].x(); + current_depth = bedfs[2].y() - bedfs[0].y(); + current_height = print_height; + partplate_list.reset_size(current_width + bed3d_ax3s_default_tip_radius, current_depth + bed3d_ax3s_default_tip_radius, current_height, false); + } + else { + partplate_list.reset_size(bedfs[2].x() - bedfs[0].x(), bedfs[2].y() - bedfs[0].y(), print_height, false); + } partplate_list.set_shapes(bedfs, excluse_areas, bed_texture, height_to_lid, height_to_rod); plate_stride = partplate_list.plate_stride_x(); BOOST_LOG_TRIVIAL(info) << "bed size, x="< 0) { partplate_list.load_from_3mf_structure(plate_data_src); + //BBS: translate old 3mf to correct positions + if (translate_old) { + //translate the objects + int plate_count = partplate_list.get_plate_count(); + for (int index = 1; index < plate_count; index ++) { + Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(index); + + Vec3d cur_origin = cur_plate->get_origin(); + Vec3d new_origin = partplate_list.compute_origin_using_new_size(index, current_width, current_depth); + + cur_plate->translate_all_instance(new_origin - cur_origin); + } + partplate_list.reset_size(current_width, current_depth, current_height); + } } /*for (ModelObject *model_object : m_models[0].objects) for (ModelInstance *model_instance : model_object->instances) diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index a33445b93..c2b18f3e9 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -1745,6 +1745,29 @@ int PartPlate::remove_instance(int obj_id, int instance_id) return result; } +//translate instance on the plate +void PartPlate::translate_all_instance(Vec3d position) +{ + for (std::set>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it) + { + int obj_id = it->first; + int instance_id = it->second; + + if ((obj_id >= 0) && (obj_id < m_model->objects.size())) + { + ModelObject* object = m_model->objects[obj_id]; + if ((instance_id >= 0) && (instance_id < object->instances.size())) + { + ModelInstance* instance = object->instances[instance_id]; + const Vec3d& offset = instance->get_offset(); + instance->set_offset(offset + position); + } + } + } + return; +} + + //update instance exclude state void PartPlate::update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box) { @@ -2467,6 +2490,23 @@ Vec3d PartPlateList::compute_origin(int i, int cols) return origin; } +//compute the origin for printable plate with index i using new width +Vec3d PartPlateList::compute_origin_using_new_size(int i, int new_width, int new_depth) +{ + Vec3d origin; + int row, col; + + row = i / m_plate_cols; + col = i % m_plate_cols; + + origin(0) = col * (new_width * (1. + LOGICAL_PART_PLATE_GAP)); + origin(1) = -row * (new_depth * (1. + LOGICAL_PART_PLATE_GAP)); + origin(2) = 0; + + return origin; +} + + //compute the origin for printable plate with index i Vec3d PartPlateList::compute_origin_for_unprintable() { @@ -2698,7 +2738,7 @@ void PartPlateList::release_icon_textures() } //this may be happened after machine changed -void PartPlateList::reset_size(int width, int depth, int height) +void PartPlateList::reset_size(int width, int depth, int height, bool reload_objects) { Vec3d origin1, origin2; @@ -2710,7 +2750,10 @@ void PartPlateList::reset_size(int width, int depth, int height) m_plate_depth = depth; m_plate_height = height; update_all_plates_pos_and_size(false, false); - reload_all_objects(); + if (reload_objects) + reload_all_objects(); + else + clear(false, false, false, -1); } return; diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index c0534781f..f2d76262c 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -290,6 +290,9 @@ public: //remove instance from plate int remove_instance(int obj_id, int instance_id); + //translate instance on the plate + void translate_all_instance(Vec3d position); + //update instance exclude state void update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box = nullptr); @@ -568,11 +571,13 @@ public: ~PartPlateList(); //this may be happened after machine changed - void reset_size(int width, int depth, int height); + void reset_size(int width, int depth, int height, bool reload_objects = true); //clear all the instances in the plate, but keep the plates void clear(bool delete_plates = false, bool release_print_list = false, bool except_locked = false, int plate_index = -1); //clear all the instances in the plate, and delete the plates, only keep the first default plate void reset(bool do_init); + //compute the origin for printable plate with index i using new width + Vec3d compute_origin_using_new_size(int i, int new_width, int new_depth); //reset partplate to init states void reinit(); @@ -580,6 +585,11 @@ public: //get the plate stride double plate_stride_x(); double plate_stride_y(); + void get_plate_size(int& width, int& depth, int& height) { + width = m_plate_width; + depth = m_plate_depth; + height = m_plate_height; + } /*basic plate operations*/ //create an empty plate and return its index diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d60eb65e6..38d744680 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1394,10 +1394,10 @@ void Sidebar::sync_ams_list() if (!ams_filament_ids.empty()) boost::algorithm::split(list2, ams_filament_ids, boost::algorithm::is_any_of(",")); struct SyncAmsDialog : MessageDialog { - SyncAmsDialog(wxWindow * parent, bool first): MessageDialog(parent, + SyncAmsDialog(wxWindow * parent, bool first): MessageDialog(parent, first ? _L("Sync filaments with AMS will drop all current selected filament presets and colors. Do you want to continue?") - : _L("Already did a synchronization, do you want to update only changes or resync all?"), + : _L("Already did a synchronization, do you want to update only changes or resync all?"), _L("Sync filaments with AMS"), 0) { if (first) { @@ -2902,6 +2902,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ std::vector empty_result; bool dlg_cont = true; bool is_user_cancel = false; + bool translate_old = false; + int current_width, current_depth, current_height; if (input_files.empty()) { return std::vector(); } @@ -3160,7 +3162,17 @@ std::vector Plater::priv::load_files(const std::vector& input_ return empty_result; } + Semver old_version(1, 5, 9); + if ((en_3mf_file_type == En3mfType::From_BBS) && (file_version < old_version) && load_model && load_config && !config_loaded.empty()) { + translate_old = true; + partplate_list.get_plate_size(current_width, current_depth, current_height); + } + if (load_config) { + if (translate_old) { + //set the size back + partplate_list.reset_size(current_width + Bed3D::Axes::DefaultTipRadius, current_depth + Bed3D::Axes::DefaultTipRadius, current_height, false); + } partplate_list.load_from_3mf_structure(plate_data); partplate_list.update_slice_context_to_current_plate(background_process); this->preview->update_gcode_result(partplate_list.get_current_slice_result()); @@ -3552,6 +3564,21 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (new_model) delete new_model; + //BBS: translate old 3mf to correct positions + if (translate_old) { + //translate the objects + int plate_count = partplate_list.get_plate_count(); + for (int index = 1; index < plate_count; index ++) { + PartPlate* cur_plate = (PartPlate *)partplate_list.get_plate(index); + + Vec3d cur_origin = cur_plate->get_origin(); + Vec3d new_origin = partplate_list.compute_origin_using_new_size(index, current_width, current_depth); + + cur_plate->translate_all_instance(new_origin - cur_origin); + } + partplate_list.reset_size(current_width, current_depth, current_height); + } + //BBS: add gcode loading logic in the end q->m_exported_file = false; q->skip_thumbnail_invalid = false; @@ -6905,7 +6932,7 @@ void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_ar double z = config->opt_float("printable_height"); //Pointfs& exclude_areas = config->option("bed_exclude_area")->values; - partplate_list.reset_size(max.x() - min.x(), max.y() - min.y(), z); + partplate_list.reset_size(max.x() - min.x() - Bed3D::Axes::DefaultTipRadius, max.y() - min.y() - Bed3D::Axes::DefaultTipRadius, z); partplate_list.set_shapes(shape, exclude_areas, custom_texture, height_to_lid, height_to_rod); Vec2d new_shape_position = partplate_list.get_current_shape_position();