diff --git a/src/libslic3r/BuildVolume.cpp b/src/libslic3r/BuildVolume.cpp index f639f9a..397f4b5 100644 --- a/src/libslic3r/BuildVolume.cpp +++ b/src/libslic3r/BuildVolume.cpp @@ -8,7 +8,9 @@ namespace Slic3r { -BuildVolume::BuildVolume(const std::vector &bed_shape, const double max_print_height) : m_bed_shape(bed_shape), m_max_print_height(max_print_height) +//B52 +BuildVolume::BuildVolume(const std::vector &bed_shape, const double max_print_height, const std::vector &exclude_bed_shape) + : m_bed_shape(bed_shape), m_max_print_height(max_print_height),m_exclude_bed_shape(exclude_bed_shape) { assert(max_print_height >= 0); @@ -22,11 +24,16 @@ BuildVolume::BuildVolume(const std::vector &bed_shape, const double max_p BoundingBoxf bboxf = get_extents(bed_shape); m_bboxf = BoundingBoxf3{ to_3d(bboxf.min, 0.), to_3d(bboxf.max, max_print_height) }; + //B52 if (bed_shape.size() >= 4 && std::abs((m_area - double(m_bbox.size().x()) * double(m_bbox.size().y()))) < sqr(SCALED_EPSILON)) { // Square print bed, use the bounding box for collision detection. m_type = Type::Rectangle; m_circle.center = 0.5 * (m_bbox.min.cast() + m_bbox.max.cast()); m_circle.radius = 0.5 * m_bbox.size().cast().norm(); + } else if (exclude_bed_shape.size()>3) { + m_type = Type::Rectangle; + m_circle.center = 0.5 * (m_bbox.min.cast() + m_bbox.max.cast()); + m_circle.radius = 0.5 * m_bbox.size().cast().norm(); } else if (bed_shape.size() > 3) { // Circle was discretized, formatted into text with limited accuracy, thus the circle was deformed. // RANSAC is slightly more accurate than the iterative Taubin / Newton method with such an input. @@ -304,19 +311,49 @@ BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& i } } +//B52 BuildVolume::ObjectState BuildVolume::volume_state_bbox(const BoundingBoxf3& volume_bbox, bool ignore_bottom) const { assert(m_type == Type::Rectangle); BoundingBox3Base build_volume = this->bounding_volume().inflated(SceneEpsilon); + std::vector> exclude_build_volume; + for (int i = 1; i < m_exclude_bed_shape.size(); i += 7) { + std::vector tem_exclude_bed_shap; + for (int j = 1; j < 6; j++) + tem_exclude_bed_shap.push_back(m_exclude_bed_shape[i + j]); + BoundingBoxf tem_bboxf = get_extents(tem_exclude_bed_shap); + auto tem_exclude_bboxf = BoundingBoxf3{to_3d(tem_bboxf.min, 0.), to_3d(tem_bboxf.max, m_max_print_height)}; + BoundingBox3Base tem_build_volume = tem_exclude_bboxf.inflated(SceneEpsilon); + exclude_build_volume.push_back(tem_build_volume); + } + + bool is_contain = false; + bool is_intersect = false; + + for (const auto &tem_build_volume : exclude_build_volume) { + if (tem_build_volume.contains(volume_bbox)) { + is_contain=true; + is_intersect = false; + break; + } + else if (tem_build_volume.intersects(volume_bbox)) { + is_contain = false; + is_intersect = true; + } + } if (m_max_print_height == 0.0) build_volume.max.z() = std::numeric_limits::max(); if (ignore_bottom) build_volume.min.z() = -std::numeric_limits::max(); return build_volume.max.z() <= - SceneEpsilon ? ObjectState::Below : + is_contain ? ObjectState::Outside : + is_intersect ? ObjectState::Outside : build_volume.contains(volume_bbox) ? ObjectState::Inside : - build_volume.intersects(volume_bbox) ? ObjectState::Colliding : ObjectState::Outside; + build_volume.intersects(volume_bbox) ? ObjectState::Colliding : + ObjectState::Outside; } +//B52 bool BuildVolume::all_paths_inside(const GCodeProcessorResult& paths, const BoundingBoxf3& paths_bbox, bool ignore_bottom) const { auto move_valid = [](const GCodeProcessorResult::MoveVertex &move) { @@ -332,7 +369,32 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult& paths, const Boun build_volume.max.z() = std::numeric_limits::max(); if (ignore_bottom) build_volume.min.z() = -std::numeric_limits::max(); - return build_volume.contains(paths_bbox); + std::vector> exclude_build_volume; + for (int i = 1; i < m_exclude_bed_shape.size(); i += 7) { + std::vector tem_exclude_bed_shap; + for (int j = 1; j < 5; j++) + tem_exclude_bed_shap.push_back(m_exclude_bed_shape[i + j]); + BoundingBoxf tem_bboxf = get_extents(tem_exclude_bed_shap); + auto tem_exclude_bboxf = BoundingBoxf3{to_3d(tem_bboxf.min, 0.), to_3d(tem_bboxf.max, m_max_print_height)}; + BoundingBox3Base tem_build_volume = tem_exclude_bboxf.inflated(SceneEpsilon); + exclude_build_volume.push_back(tem_build_volume); + } + + bool is_contain = false; + bool is_intersect = false; + + for (const auto &tem_build_volume : exclude_build_volume) { + if (tem_build_volume.contains(paths_bbox)) { + is_contain = true; + is_intersect = false; + break; + } else if (tem_build_volume.intersects(paths_bbox)) { + is_contain = false; + is_intersect = true; + } + } + + return (build_volume.contains(paths_bbox) && !is_contain && !is_intersect); } case Type::Circle: { diff --git a/src/libslic3r/BuildVolume.hpp b/src/libslic3r/BuildVolume.hpp index 6537d27..7da19b1 100644 --- a/src/libslic3r/BuildVolume.hpp +++ b/src/libslic3r/BuildVolume.hpp @@ -34,10 +34,13 @@ public: // Initialized to empty, all zeros, Invalid. BuildVolume() {} // Initialize from PrintConfig::bed_shape and PrintConfig::max_print_height - BuildVolume(const std::vector &bed_shape, const double max_print_height); + //B52 + BuildVolume(const std::vector &bed_shape, const double max_print_height, const std::vector &exclude_bed_shape); // Source data, unscaled coordinates. const std::vector& bed_shape() const { return m_bed_shape; } + //B52 + const std::vector& exclude_bed_shape() const { return m_exclude_bed_shape; } double max_print_height() const { return m_max_print_height; } // Derived data @@ -101,6 +104,8 @@ public: private: // Source definition of the print bed geometry (PrintConfig::bed_shape) std::vector m_bed_shape; + //B52 + std::vector m_exclude_bed_shape; // Source definition of the print volume height (PrintConfig::max_print_height) double m_max_print_height; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 8859081..fe2452e 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -536,8 +536,8 @@ static std::vector s_Preset_printer_options { "default_print_profile", "inherits", "remaining_times", "silent_mode", "machine_limits_usage", "thumbnails", "thumbnails_format", -//Y20 - "bed_exclude_area_0", "bed_exclude_area_1", +//Y20 //B52 + "bed_exclude_area", //Y16 "chamber_temperature", "auxiliary_fan", "chamber_fan" }; @@ -655,7 +655,9 @@ static std::vector s_Preset_sla_printer_options { //FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset. "print_host", "printhost_apikey", "printhost_cafile", "printer_notes", - "inherits" + "inherits", + //B52 + "bed_exclude_area", }; const std::vector& Preset::print_options() { return s_Preset_print_options; } @@ -1348,9 +1350,8 @@ static const std::set independent_from_extruder_number_options = { "filament_ramming_parameters", "gcode_substitutions", "post_process", -//Y20 - "bed_exclude_area_0", - "bed_exclude_area_1", +//Y20 //B52 + "bed_exclude_area", }; bool PresetCollection::is_independent_from_extruder_number_option(const std::string& opt_key) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index c7677e7..db2fca7 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -60,9 +60,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "autoemit_temperature_commands", "avoid_crossing_perimeters", "avoid_crossing_perimeters_max_detour", - //Y20 - "bed_exclude_area_0", - "bed_exclude_area_1", + //Y20 //B52 + "bed_exclude_area", "bed_shape", "bed_temperature", "before_layer_gcode", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 5871d0c..4b3f14f 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -281,14 +281,9 @@ void PrintConfigDef::init_common_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) }); - //Y20 - def = this->add("bed_exclude_area_0", coPoints); - def->label = L("Bed exclude area 1"); - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0) }); - - def = this->add("bed_exclude_area_1", coPoints); - def->label = L("Bed exclude area 2"); + //Y20 //B52 + def = this->add("bed_exclude_area", coPoints); + def->label = L("Bed exclude area"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0) }); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index c391800..d8d0366 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -800,9 +800,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionBool, avoid_crossing_perimeters)) ((ConfigOptionFloatOrPercent, avoid_crossing_perimeters_max_detour)) ((ConfigOptionPoints, bed_shape)) - //Y20 - ((ConfigOptionPoints, bed_exclude_area_0)) - ((ConfigOptionPoints, bed_exclude_area_1)) + //Y20 //B52 + ((ConfigOptionPoints, bed_exclude_area)) ((ConfigOptionInts, bed_temperature)) //Y16 ((ConfigOptionBool, chamber_temperature)) diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index 3743221..5af9c53 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -3619,9 +3619,12 @@ void fff_tree_support_generate(PrintObject &print_object, std::function break; ++idx; } - FFFTreeSupport::generate_support_areas(*print_object.print(), - BuildVolume(Pointfs{ Vec2d{ -300., -300. }, Vec2d{ -300., +300. }, Vec2d{ +300., +300. }, Vec2d{ +300., -300. } }, 0.), { idx }, - throw_on_cancel); + //B52 + FFFTreeSupport::generate_support_areas(*print_object.print(), + BuildVolume(Pointfs{Vec2d{-300., -300.}, Vec2d{-300., +300.}, Vec2d{+300., +300.}, + Vec2d{+300., -300.}}, + 0., Pointfs{Vec2d{0., 0.}}), + {idx}, throw_on_cancel); } } // namespace Slic3r diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 92383dc..3647ab5 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -29,7 +29,13 @@ static const Slic3r::ColorRGBA DEFAULT_TRANSPARENT_GRID_COLOR = { 0.9f, 0.9f, 0 namespace Slic3r { namespace GUI { -bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) +//B52 +bool Bed3D::set_shape(const Pointfs & bed_shape, + const double max_print_height, + const std::string &custom_texture, + const std::string &custom_model, + const Pointfs & exclude_bed_shape, + bool force_as_custom) { auto check_texture = [](const std::string& texture) { boost::system::error_code ec; // so the exists call does not throw (e.g. after a permission problem) @@ -66,12 +72,14 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c } - if (m_build_volume.bed_shape() == bed_shape && m_build_volume.max_print_height() == max_print_height && m_type == type && m_texture_filename == texture_filename && m_model_filename == model_filename) + //B52 + if (m_build_volume.bed_shape() == bed_shape && m_build_volume.exclude_bed_shape() == exclude_bed_shape && m_build_volume.max_print_height() == max_print_height && m_type == type && m_texture_filename == texture_filename && m_model_filename == model_filename) // No change, no need to update the UI. return false; m_type = type; - m_build_volume = BuildVolume { bed_shape, max_print_height }; + //B52 + m_build_volume = BuildVolume{bed_shape, max_print_height, exclude_bed_shape}; m_texture_filename = texture_filename; m_model_filename = model_filename; m_extended_bounding_box = this->calc_extended_bounding_box(); @@ -287,6 +295,7 @@ void Bed3D::init_contourlines() // Try to match the print bed shape with the shape of an active profile. If such a match exists, // return the print bed model. +//B52 std::tuple Bed3D::detect_type(const Pointfs& shape) { auto bundle = wxGetApp().preset_bundle; @@ -294,12 +303,12 @@ std::tuple Bed3D::detect_type(const Point const Preset* curr = &bundle->printers.get_selected_preset(); while (curr != nullptr) { if (curr->config.has("bed_shape")) { - if (shape == dynamic_cast(curr->config.option("bed_shape"))->values) { + //if (shape == dynamic_cast(curr->config.option("bed_shape"))->values) { std::string model_filename = PresetUtils::system_printer_bed_model(*curr); std::string texture_filename = PresetUtils::system_printer_bed_texture(*curr); if (!model_filename.empty() && !texture_filename.empty()) return { Type::System, model_filename, texture_filename }; - } + //} } curr = bundle->printers.get_preset_parent(*curr); diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index cf20b6a..f4512b2 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -59,7 +59,13 @@ public: // Return true if the bed shape changed, so the calee will update the UI. //FIXME if the build volume max print height is updated, this function still returns zero // as this class does not use it, thus there is no need to update the UI. - bool set_shape(const Pointfs& bed_shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false); + //B52 + bool set_shape(const Pointfs & bed_shape, + const double max_print_height, + const std::string &custom_texture, + const std::string &custom_model, + const Pointfs & exclude_bed_shape, + bool force_as_custom = false); // Build volume geometry for various collision detection tasks. const BuildVolume& build_volume() const { return m_build_volume; } diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 08fc7f3..868e4bc 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -20,9 +20,10 @@ namespace Slic3r { namespace GUI { -BedShape::BedShape(const ConfigOptionPoints& points) +//B52 +BedShape::BedShape(const ConfigOptionPoints &points1, const ConfigOptionPoints &points2) { - m_build_volume = { points.values, 0. }; + m_build_volume = {points1.values, 0., points2.values}; } static std::string get_option_label(BedShape::Parameter param) @@ -149,23 +150,37 @@ void BedShape::apply_optgroup_values(ConfigOptionsGroupShp optgroup) optgroup->set_value("rect_origin" , to_2d(-1 * m_build_volume.bounding_volume().min)); } } -//Y20 -void BedShape::apply_exclude_values(ConfigOptionsGroupShp optgroup) +//Y20 //B52 +void BedShape::apply_exclude_values(const ConfigOptionPoints &points,ConfigOptionsGroupShp optgroup1, ConfigOptionsGroupShp optgroup2) { - optgroup->set_value("exclude_area_max" , to_2d(m_build_volume.bounding_volume().max)); - optgroup->set_value("exclude_area_min" , to_2d(m_build_volume.bounding_volume().min)); + if (points.values.size() == 1) { + optgroup1->set_value("exclude_area_max", to_2d(m_build_volume.bounding_volume().min)); + optgroup1->set_value("exclude_area_min", to_2d(m_build_volume.bounding_volume().min)); + optgroup2->set_value("exclude_area_max", to_2d(m_build_volume.bounding_volume().min)); + optgroup2->set_value("exclude_area_min", to_2d(m_build_volume.bounding_volume().min)); + } else if (points.values.size() == 8) { + optgroup1->set_value("exclude_area_max", Vec2d(points.values[4].x(), points.values[4].y())); + optgroup1->set_value("exclude_area_min", Vec2d(points.values[2].x(), points.values[2].y())); + optgroup2->set_value("exclude_area_max", to_2d(m_build_volume.bounding_volume().min)); + optgroup2->set_value("exclude_area_min", to_2d(m_build_volume.bounding_volume().min)); + } else if (points.values.size() > 14) { + optgroup1->set_value("exclude_area_max", Vec2d(points.values[4].x(), points.values[4].y())); + optgroup1->set_value("exclude_area_min", Vec2d(points.values[2].x(), points.values[2].y())); + optgroup2->set_value("exclude_area_max", Vec2d(points.values[11].x(), points.values[11].y())); + optgroup2->set_value("exclude_area_min", Vec2d(points.values[9].x(), points.values[9].y())); + } } BedShapeDialog::BedShapeDialog(wxWindow* parent) : DPIDialog(parent, wxID_ANY, _(L("Bed Shape")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {} -//Y20 -void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionPoints& exclude_area_0, const ConfigOptionPoints& exclude_area_1, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model) +//Y20 //B52 +void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionPoints& exclude_area, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model) { SetFont(wxGetApp().normal_font()); m_panel = new BedShapePanel(this); - //Y20 - m_panel->build_panel(default_pt, exclude_area_0, exclude_area_1, custom_texture, custom_model); + //Y20 //B52 + m_panel->build_panel(default_pt, exclude_area, custom_texture, custom_model); auto main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(m_panel, 1, wxEXPAND); @@ -203,14 +218,14 @@ void BedShapeDialog::on_dpi_changed(const wxRect &suggested_rect) const std::string BedShapePanel::NONE = "None"; const std::string BedShapePanel::EMPTY_STRING = ""; -//Y20 -void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const ConfigOptionPoints& exclude_area_0, const ConfigOptionPoints& exclude_area_1, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model) +//Y20 //B52 +void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const ConfigOptionPoints& exclude_area, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model) { + //B52 wxGetApp().UpdateDarkUI(this); m_shape = default_pt.values; //Y20 - m_exclude_area_0 = exclude_area_0.values; - m_exclude_area_1 = exclude_area_1.values; + m_exclude_area = exclude_area.values; m_custom_texture = custom_texture.value.empty() ? NONE : custom_texture.value; m_custom_model = custom_model.value.empty() ? NONE : custom_model.value; @@ -280,10 +295,10 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf top_sizer->Add(m_canvas, 1, wxEXPAND | wxALL, 10); SetSizerAndFit(top_sizer); - - set_shape(default_pt); - //Y20 - set_exclude_area(exclude_area_0, exclude_area_1); + //B52 + set_shape(default_pt, exclude_area); + //Y20 //B52 + set_exclude_area(default_pt, exclude_area); update_preview(); } @@ -498,27 +513,25 @@ wxPanel* BedShapePanel::init_model_panel() // Deduce the bed shape type(rect, circle, custom) // This routine shall be smart enough if the user messes up // with the list of points in the ini file directly. -void BedShapePanel::set_shape(const ConfigOptionPoints& points) +//B52 +void BedShapePanel::set_shape(const ConfigOptionPoints &points1, const ConfigOptionPoints &points2) { - BedShape shape(points); + BedShape shape(points1,points2); m_shape_options_book->SetSelection(int(shape.get_page_type())); shape.apply_optgroup_values(m_optgroups[int(shape.get_page_type())]); // Copy the polygon to the canvas, make a copy of the array, if custom shape is selected if (shape.is_custom()) - m_loaded_shape = points.values; + m_loaded_shape = points1.values; update_shape(); } -//Y20 -void BedShapePanel::set_exclude_area(const ConfigOptionPoints& points_0, const ConfigOptionPoints& points_1) +//Y20 //B52 +void BedShapePanel::set_exclude_area(const ConfigOptionPoints &points1, const ConfigOptionPoints &points2) { - BedShape exclude_0(points_0); - exclude_0.apply_exclude_values(exclude_optgroup_0); - - BedShape exclude_1(points_1); - exclude_1.apply_exclude_values(exclude_optgroup_1); + BedShape exclude(points1,points2); + exclude.apply_exclude_values(points2, exclude_optgroup_0, exclude_optgroup_1); update_shape(); } @@ -593,37 +606,72 @@ void BedShapePanel::update_shape() break; } -//Y20 - m_exclude_area_0 = update_exclude_area(exclude_optgroup_0); - m_exclude_area_1 = update_exclude_area(exclude_optgroup_1); +//Y20 //B52 + m_exclude_area = update_exclude_area(exclude_optgroup_0, exclude_optgroup_1); update_preview(); } -//Y20 -const std::vector BedShapePanel::update_exclude_area(ConfigOptionsGroupShp options_group) +//Y20 //B52 +const std::vector BedShapePanel::update_exclude_area(ConfigOptionsGroupShp options_group_0, ConfigOptionsGroupShp options_group_1) { - Vec2d exclude_max(Vec2d::Zero()); - Vec2d exclude_min(Vec2d::Zero()); + Vec2d exclude_max_0(Vec2d::Zero()); + Vec2d exclude_min_0(Vec2d::Zero()); + Vec2d exclude_max_1(Vec2d::Zero()); + Vec2d exclude_min_1(Vec2d::Zero()); std::vector e_area = {Vec2d(0, 0)}; + auto page_idx = m_shape_options_book->GetSelection(); + auto opt_group = m_optgroups[page_idx]; + if (static_cast(page_idx) == BedShape::PageType::Rectangle) { + try { + exclude_max_0 = boost::any_cast(options_group_0->get_value("exclude_area_max")); + } catch (const std::exception & /* e */) { + exclude_max_0 = Vec2d::Zero(); + } - try { exclude_max = boost::any_cast(options_group->get_value("exclude_area_max")); } - catch (const std::exception & /* e */) { return e_area; } + try { + exclude_min_0 = boost::any_cast(options_group_0->get_value("exclude_area_min")); + } catch (const std::exception & /* e */) { + exclude_min_0 = Vec2d::Zero(); + } - try { exclude_min = boost::any_cast(options_group->get_value("exclude_area_min")); } - catch (const std::exception & /* e */) { return e_area; } + try { + exclude_max_1 = boost::any_cast(options_group_1->get_value("exclude_area_max")); + } catch (const std::exception & /* e */) { + exclude_max_1 = Vec2d::Zero(); + } - auto e_x = exclude_max(0); - auto e_y = exclude_max(1); + try { + exclude_min_1 = boost::any_cast(options_group_1->get_value("exclude_area_min")); + } catch (const std::exception & /* e */) { + exclude_min_1 = Vec2d::Zero(); + } - auto e_dx = exclude_min(0); - auto e_dy = exclude_min(1); - - e_area = { Vec2d(e_dx, e_dy), - Vec2d(e_x, e_dy), - Vec2d(e_x, e_y), - Vec2d(e_dx, e_y) }; + if (exclude_max_0 != Vec2d(0., 0.)) { + e_area.push_back({0, 0}); + e_area.push_back({exclude_min_0.x(), exclude_min_0.y()}); + e_area.push_back({exclude_min_0.x(), exclude_max_0.y()}); + e_area.push_back({exclude_max_0.x(), exclude_max_0.y()}); + e_area.push_back({exclude_max_0.x(), exclude_min_0.y()}); + e_area.push_back({exclude_min_0.x(), exclude_min_0.y()}); + e_area.push_back({0, 0}); + } + if (exclude_max_1 != Vec2d(0., 0.)) { + e_area.push_back({0, 0}); + e_area.push_back({exclude_min_1.x(), exclude_min_1.y()}); + e_area.push_back({exclude_min_1.x(), exclude_max_1.y()}); + e_area.push_back({exclude_max_1.x(), exclude_max_1.y()}); + e_area.push_back({exclude_max_1.x(), exclude_min_1.y()}); + e_area.push_back({exclude_min_1.x(), exclude_min_1.y()}); + e_area.push_back({0, 0}); + } + if (e_area.size() > 1) { + for (const auto &point : e_area) { + m_shape.push_back({point.x(), point.y()}); + } + } + } return e_area; } diff --git a/src/slic3r/GUI/BedShapeDialog.hpp b/src/slic3r/GUI/BedShapeDialog.hpp index 962821a..10cd381 100644 --- a/src/slic3r/GUI/BedShapeDialog.hpp +++ b/src/slic3r/GUI/BedShapeDialog.hpp @@ -36,7 +36,8 @@ struct BedShape ExcludeMin }; - BedShape(const ConfigOptionPoints& points); + //B52 + BedShape(const ConfigOptionPoints &points1, const ConfigOptionPoints &points2); bool is_custom() { return m_build_volume.type() == BuildVolume::Type::Convex || m_build_volume.type() == BuildVolume::Type::Custom; } @@ -47,8 +48,8 @@ struct BedShape wxString get_full_name_with_params(); void apply_optgroup_values(ConfigOptionsGroupShp optgroup); - //Y20 - void apply_exclude_values(ConfigOptionsGroupShp optgroup); + //Y20 //B52 + void apply_exclude_values(const ConfigOptionPoints &points , ConfigOptionsGroupShp optgroup1, ConfigOptionsGroupShp optgroup2); private: BuildVolume m_build_volume; @@ -62,22 +63,21 @@ class BedShapePanel : public wxPanel Bed_2D* m_canvas; std::vector m_shape; std::vector m_loaded_shape; - //Y20 - std::vector m_exclude_area_0; - std::vector m_exclude_area_1; + //Y20 //B52 + std::vector m_exclude_area; std::string m_custom_texture; std::string m_custom_model; public: BedShapePanel(wxWindow* parent) : wxPanel(parent, wxID_ANY), m_custom_texture(NONE), m_custom_model(NONE) {} -//Y20 - void build_panel(const ConfigOptionPoints& default_pt, const ConfigOptionPoints& exclude_area_0, const ConfigOptionPoints& exclude_area_1, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model); +//Y20 //B52 + void build_panel(const ConfigOptionPoints& default_pt, const ConfigOptionPoints& exclude_area_0, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model); // Returns the resulting bed shape polygon. This value will be stored to the ini file. const std::vector& get_shape() const { return m_shape; } - //Y20 - const std::vector& get_exclude_area_0() const { return m_exclude_area_0; } - const std::vector& get_exclude_area_1() const { return m_exclude_area_1; } + //Y20 //B52 + const std::vector& get_exclude_area() const { return m_exclude_area; } + //const std::vector& get_exclude_area_1() const { return m_exclude_area_1; } const std::string& get_custom_texture() const { return (m_custom_texture != NONE) ? m_custom_texture : EMPTY_STRING; } const std::string& get_custom_model() const { return (m_custom_model != NONE) ? m_custom_model : EMPTY_STRING; } @@ -90,12 +90,15 @@ private: ConfigOptionsGroupShp exclude_optgroup_1; wxPanel* init_texture_panel(); wxPanel* init_model_panel(); - void set_shape(const ConfigOptionPoints& points); -//Y20 - void set_exclude_area(const ConfigOptionPoints& points_0, const ConfigOptionPoints& points_1); + //B52 + void set_shape(const ConfigOptionPoints &points1, const ConfigOptionPoints &points2); + //Y20 //B52 + void set_exclude_area(const ConfigOptionPoints &points1, const ConfigOptionPoints &points2); void update_preview(); void update_shape(); - const std::vector update_exclude_area(ConfigOptionsGroupShp options_group); + //B52 + const std::vector update_exclude_area(ConfigOptionsGroupShp options_group_0, ConfigOptionsGroupShp options_group_1); + mutable std::vector m_exclude_bounding_box; void load_stl(); void load_texture(); void load_model(); @@ -111,13 +114,12 @@ class BedShapeDialog : public DPIDialog BedShapePanel* m_panel; public: BedShapeDialog(wxWindow* parent); -//Y20 - void build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionPoints& exclude_area_0, const ConfigOptionPoints& exclude_area_1, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model); +//Y20 //B52 + void build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionPoints& exclude_area, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model); const std::vector& get_shape() const { return m_panel->get_shape(); } -//Y20 - const std::vector& get_exclude_area_0() const { return m_panel->get_exclude_area_0(); } - const std::vector& get_exclude_area_1() const { return m_panel->get_exclude_area_1(); } +//Y20 //B52 + const std::vector& get_exclude_area() const { return m_panel->get_exclude_area(); } const std::string& get_custom_texture() const { return m_panel->get_custom_texture(); } const std::string& get_custom_model() const { return m_panel->get_custom_model(); } diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 283534e..82190f0 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -1829,9 +1829,8 @@ PageBedShape::PageBedShape(ConfigWizard *parent) append_text(_L("Set the shape of your printer's bed.")); shape_panel->build_panel(*wizard_p()->custom_config->option("bed_shape"), - //Y20 - *wizard_p()->custom_config->option("bed_exclude_area_0"), - *wizard_p()->custom_config->option("bed_exclude_area_1"), + //Y20 //B52 + *wizard_p()->custom_config->option("bed_exclude_area"), *wizard_p()->custom_config->option("bed_custom_texture"), *wizard_p()->custom_config->option("bed_custom_model")); @@ -1841,15 +1840,13 @@ PageBedShape::PageBedShape(ConfigWizard *parent) void PageBedShape::apply_custom_config(DynamicPrintConfig &config) { const std::vector& points = shape_panel->get_shape(); - //Y20 - const std::vector& exclude_area_0 = shape_panel->get_exclude_area_0(); - const std::vector& exclude_area_1 = shape_panel->get_exclude_area_1(); + //Y20 //B52 + const std::vector& exclude_area = shape_panel->get_exclude_area(); const std::string& custom_texture = shape_panel->get_custom_texture(); const std::string& custom_model = shape_panel->get_custom_model(); config.set_key_value("bed_shape", new ConfigOptionPoints(points)); - //Y20 - config.set_key_value("bed_exclude_area_0", new ConfigOptionPoints(exclude_area_0)); - config.set_key_value("bed_exclude_area_1", new ConfigOptionPoints(exclude_area_1)); + //Y20 //B52 + config.set_key_value("bed_exclude_area", new ConfigOptionPoints(exclude_area)); config.set_key_value("bed_custom_texture", new ConfigOptionString(custom_texture)); config.set_key_value("bed_custom_model", new ConfigOptionString(custom_model)); } @@ -3320,8 +3317,8 @@ ConfigWizard::ConfigWizard(wxWindow *parent) p->load_vendors(); p->custom_config.reset(DynamicPrintConfig::new_from_defaults_keys({ -//Y20 - "gcode_flavor", "bed_shape", "bed_exclude_area_0", "bed_exclude_area_1", "bed_custom_texture", "bed_custom_model", "nozzle_diameter", "filament_diameter", "temperature", "bed_temperature", +//Y20 //B52 + "gcode_flavor", "bed_shape", "bed_exclude_area", "bed_custom_texture", "bed_custom_model", "nozzle_diameter", "filament_diameter", "temperature", "bed_temperature", })); p->index = new ConfigWizardIndex(this); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index f1ac89a..ee7d6cb 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -921,7 +921,9 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr { min.x(), max.y() } }; } - wxGetApp().plater()->set_bed_shape(bed_shape, gcode_result.max_print_height, texture, model, gcode_result.bed_shape.empty()); + //B52 + wxGetApp().plater()->set_bed_shape(bed_shape, gcode_result.max_print_height, texture, model, + {{0.,0.}},gcode_result.bed_shape.empty()); } m_print_statistics = gcode_result.print_statistics; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f2fbb96..873d246 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1501,6 +1501,7 @@ bool GLCanvas3D::check_volumes_outside_state(GLVolumeCollection& volumes, ModelI const Slic3r::BuildVolume& build_volume = m_bed.build_volume(); const std::vector volumes_idxs = volumes_to_process_idxs(); + //B52 for (unsigned int vol_idx : volumes_idxs) { GLVolume* volume = volumes.volumes[vol_idx]; if (!volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (!volume->is_wipe_tower && volume->composite_id.volume_id >= 0))) { @@ -1518,6 +1519,7 @@ bool GLCanvas3D::check_volumes_outside_state(GLVolumeCollection& volumes, ModelI //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently. case BuildVolume::Type::Custom: state = build_volume.object_state(volume_convex_mesh(*volume).its, volume->world_matrix().cast(), volume_sinking(*volume)); + // state = build_volume.volume_state_bbox(volume_bbox(*volume)); break; default: // Ignore, don't produce any collision. diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 810057c..ea4275a 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -203,8 +203,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt } break; case coPoints:{ - //Y20 - if (opt_key == "bed_shape" || opt_key == "bed_exclude_area_0" || opt_key == "bed_exclude_area_1") { + //Y20 //B52 + if (opt_key == "bed_shape" || opt_key == "bed_exclude_area") { config.option(opt_key)->values = boost::any_cast>(value); break; } diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 7c62219..7766722 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -953,8 +953,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config ret = config.option(opt_key)->getInt(); break; case coPoints: -//Y20 - if (opt_key == "bed_shape" || opt_key == "bed_exclude_area_0" || opt_key == "bed_exclude_area_1") +//Y20 //B52 + if (opt_key == "bed_shape" || opt_key == "bed_exclude_area") ret = config.option(opt_key)->values; else ret = config.option(opt_key)->get_at(idx); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0649f2a..5e5e498 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2009,7 +2009,13 @@ struct Plater::priv // triangulate the bed and store the triangles into m_bed.m_triangles, // fills the m_bed.m_grid_lines and sets m_bed.m_origin. // Sets m_bed.m_polygon to limit the object placement. - void set_bed_shape(const Pointfs& shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false); + //B52 + void set_bed_shape(const Pointfs & shape, + const double max_print_height, + const std::string &custom_texture, + const std::string &custom_model, + const Pointfs & exclude_bed_shape, + bool force_as_custom = false); bool can_delete() const; bool can_delete_all() const; @@ -2095,7 +2101,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) "layer_height", "first_layer_height", "min_layer_height", "max_layer_height", "brim_width", "perimeters", "perimeter_extruder", "fill_density", "infill_extruder", "top_solid_layers", "support_material", "support_material_extruder", "support_material_interface_extruder", - "support_material_contact_distance", "support_material_bottom_contact_distance", "raft_layers" + "support_material_contact_distance", "support_material_bottom_contact_distance", "raft_layers", + //B52 + "bed_exclude_area" })) , sidebar(new Sidebar(q)) , notification_manager(std::make_unique(q)) @@ -4885,10 +4893,16 @@ bool Plater::priv::can_reload_from_disk() const return !paths.empty(); } - -void Plater::priv::set_bed_shape(const Pointfs& shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) +//B52 +void Plater::priv::set_bed_shape(const Pointfs & shape, + const double max_print_height, + const std::string &custom_texture, + const std::string &custom_model, + const Pointfs & exclude_bed_shape, + bool force_as_custom) { - bool new_shape = bed.set_shape(shape, max_print_height, custom_texture, custom_model, force_as_custom); + + bool new_shape = bed.set_shape(shape, max_print_height, custom_texture, custom_model, exclude_bed_shape, force_as_custom); if (new_shape) { if (view3D) view3D->bed_shape_changed(); if (preview) preview->bed_shape_changed(); @@ -8104,7 +8118,9 @@ void Plater::on_config_change(const DynamicPrintConfig &config) p->view3D->get_canvas3d()->reset_sequential_print_clearance(); p->view3D->get_canvas3d()->set_sla_view_type(GLCanvas3D::ESLAViewType::Original); } - else if (opt_key == "bed_shape" || opt_key == "bed_custom_texture" || opt_key == "bed_custom_model") { + //B52 + else if (opt_key == "bed_shape" || opt_key == "bed_custom_texture" || opt_key == "bed_custom_model" || + opt_key == "bed_exclude_area") { bed_shape_changed = true; update_scheduled = true; } @@ -8145,22 +8161,34 @@ void Plater::on_config_change(const DynamicPrintConfig &config) this->p->schedule_background_process(); } +//B52 void Plater::set_bed_shape() const { - set_bed_shape(p->config->option("bed_shape")->values, - p->config->option("max_print_height")->value, + + auto bed_shape = p->config->option("bed_shape")->values; + auto exclude_area = p->config->option("bed_exclude_area")->values; + set_bed_shape(bed_shape, p->config->option("max_print_height")->value, p->config->option("bed_custom_texture")->value, - p->config->option("bed_custom_model")->value); + p->config->option("bed_custom_model")->value, exclude_area); } -void Plater::set_bed_shape(const Pointfs& shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) const + //B52 + void Plater::set_bed_shape(const Pointfs & shape, + const double max_print_height, + const std::string &custom_texture, + const std::string &custom_model, + const Pointfs & exclude_bed_shape, + bool force_as_custom) const { - p->set_bed_shape(shape, max_print_height, custom_texture, custom_model, force_as_custom); + p->set_bed_shape(shape, max_print_height, custom_texture, custom_model, exclude_bed_shape, force_as_custom); } +//B52 void Plater::set_default_bed_shape() const { - set_bed_shape({ { 0.0, 0.0 }, { 200.0, 0.0 }, { 200.0, 200.0 }, { 0.0, 200.0 } }, 0.0, {}, {}, true); + set_bed_shape({{0.0, 0.0}, {200.0, 0.0}, {200.0, 200.0}, {0.0, 200.0}}, 0.0, {}, {}, { + {0.0, 0.0} + }, true); } void Plater::force_filament_colors_update() diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 214ccdd..171ff08 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -437,7 +437,13 @@ public: Mouse3DController& get_mouse3d_controller(); void set_bed_shape() const; - void set_bed_shape(const Pointfs& shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const; + //B52 + void set_bed_shape(const Pointfs & shape, + const double max_print_height, + const std::string &custom_texture, + const std::string &custom_model, + const Pointfs & exclude_bed_shape, + bool force_as_custom = false) const; void set_default_bed_shape() const; NotificationManager * get_notification_manager(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index c67f0ab..7b90ae4 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -4970,24 +4970,22 @@ wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent) { BedShapeDialog dlg(this); dlg.build_dialog(*m_config->option("bed_shape"), - //Y20 - *m_config->option("bed_exclude_area_0"), - *m_config->option("bed_exclude_area_1"), + //Y20 //B52 + *m_config->option("bed_exclude_area"), *m_config->option("bed_custom_texture"), *m_config->option("bed_custom_model")); if (dlg.ShowModal() == wxID_OK) { const std::vector& shape = dlg.get_shape(); - //Y20 - const std::vector& exclude_area_0 = dlg.get_exclude_area_0(); - const std::vector& exclude_area_1 = dlg.get_exclude_area_1(); + //Y20 //B52 + const std::vector& exclude_area = dlg.get_exclude_area(); const std::string& custom_texture = dlg.get_custom_texture(); const std::string& custom_model = dlg.get_custom_model(); - if (!shape.empty()) + //B52 + if (!shape.empty() || !exclude_area.empty()) { load_key_value("bed_shape", shape); - //Y20 - load_key_value("bed_exclude_area_0", exclude_area_0); - load_key_value("bed_exclude_area_1", exclude_area_1); + //Y20 //B52 + load_key_value("bed_exclude_area", exclude_area); load_key_value("bed_custom_texture", custom_texture); load_key_value("bed_custom_model", custom_model); update_changed_ui(); @@ -5000,9 +4998,8 @@ wxSizer* TabPrinter::create_bed_shape_widget(wxWindow* parent) { Search::OptionsSearcher& searcher = wxGetApp().sidebar().get_searcher(); const Search::GroupAndCategory& gc = searcher.get_group_and_category("bed_shape"); - //Y20 - searcher.add_key("bed_exclude_area_0", m_type, gc.group, gc.category); - searcher.add_key("bed_exclude_area_1", m_type, gc.group, gc.category); + //Y20 //B52 + searcher.add_key("bed_exclude_area", m_type, gc.group, gc.category); searcher.add_key("bed_custom_texture", m_type, gc.group, gc.category); searcher.add_key("bed_custom_model", m_type, gc.group, gc.category); } diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index bd88beb..7442a90 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -1199,17 +1199,14 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& return opt.has_value() ? _(from_u8(*opt)) : _L("Undef"); } case coPoints: { + //B52 if (opt_key == "bed_shape") { - BedShape shape(*config.option(opt_key)); + BedShape shape(*config.option(opt_key), *config.option("bed_exclude_area")); return shape.get_full_name_with_params(); } - //Y20 - if (opt_key == "bed_exclude_area_0") { - BedShape shape(*config.option(opt_key)); - return shape.get_full_name_with_params(); - } - if (opt_key == "bed_exclude_area_1") { - BedShape shape(*config.option(opt_key)); + //Y20 //B52 + if (opt_key == "bed_exclude_area") { + BedShape shape(*config.option("bed_shape") ,* config.option(opt_key)); return shape.get_full_name_with_params(); }