diff --git a/src/libslic3r/BoundingBox.hpp b/src/libslic3r/BoundingBox.hpp index b90081b0de..8a5f419828 100644 --- a/src/libslic3r/BoundingBox.hpp +++ b/src/libslic3r/BoundingBox.hpp @@ -70,6 +70,26 @@ public: return ! (this->max(0) < other.min(0) || this->min(0) > other.max(0) || this->max(1) < other.min(1) || this->min(1) > other.max(1)); } + PointClass operator[](size_t idx) const { + switch (idx) { + case 0: + return min; + break; + case 1: + return PointClass(max(0), min(1)); + break; + case 2: + return max; + break; + case 3: + return PointClass(min(0), max(1)); + break; + default: + return PointClass(); + break; + } + return PointClass(); + } bool operator==(const BoundingBoxBase &rhs) { return this->min == rhs.min && this->max == rhs.max; } bool operator!=(const BoundingBoxBase &rhs) { return ! (*this == rhs); } friend std::ostream &operator<<(std::ostream &os, const BoundingBoxBase &bbox) diff --git a/src/libslic3r/BuildVolume.cpp b/src/libslic3r/BuildVolume.cpp index 4e4e593c1b..05274c0b61 100644 --- a/src/libslic3r/BuildVolume.cpp +++ b/src/libslic3r/BuildVolume.cpp @@ -24,7 +24,7 @@ BuildVolume::BuildVolume(const std::vector &printable_area, const double if (printable_area.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_type = BuildVolume_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 (printable_area.size() > 3) { @@ -52,16 +52,16 @@ BuildVolume::BuildVolume(const std::vector &printable_area, const double prev = p; } if (is_circle) { - m_type = Type::Circle; + m_type = BuildVolume_Type::Circle; m_circle.center = scaled(m_circle.center); m_circle.radius = scaled(m_circle.radius); } } - if (printable_area.size() >= 3 && m_type == Type::Invalid) { + if (printable_area.size() >= 3 && m_type == BuildVolume_Type::Invalid) { // Circle check is not used for Convex / Custom shapes, fill it with something reasonable. m_circle = Geometry::smallest_enclosing_circle_welzl(m_convex_hull.points); - m_type = (m_convex_hull.area() - m_area) < sqr(SCALED_EPSILON) ? Type::Convex : Type::Custom; + m_type = (m_convex_hull.area() - m_area) < sqr(SCALED_EPSILON) ? BuildVolume_Type::Convex : BuildVolume_Type::Custom; // Initialize the top / bottom decomposition for inside convex polygon check. Do it with two different epsilons applied. auto convex_decomposition = [](const Polygon &in, double epsilon) { Polygon src = expand(in, float(epsilon)).front(); @@ -272,7 +272,7 @@ BuildVolume::ObjectState object_state_templ(const indexed_triangle_set &its, con BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& its, const Transform3f& trafo, bool may_be_below_bed, bool ignore_bottom) const { switch (m_type) { - case Type::Rectangle: + case BuildVolume_Type::Rectangle: { BoundingBox3Base build_volume = this->bounding_volume().inflated(SceneEpsilon); if (m_max_print_height == 0.0) @@ -285,20 +285,20 @@ BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& i //FIXME This test does NOT correctly interprets intersection of a non-convex object with a rectangular build volume. return object_state_templ(its, trafo, may_be_below_bed, [build_volumef](const Vec3f &pt) { return build_volumef.contains(pt); }); } - case Type::Circle: + case BuildVolume_Type::Circle: { Geometry::Circlef circle { unscaled(m_circle.center), unscaled(m_circle.radius + SceneEpsilon) }; return m_max_print_height == 0.0 ? object_state_templ(its, trafo, may_be_below_bed, [circle](const Vec3f &pt) { return circle.contains(to_2d(pt)); }) : object_state_templ(its, trafo, may_be_below_bed, [circle, z = m_max_print_height + SceneEpsilon](const Vec3f &pt) { return pt.z() < z && circle.contains(to_2d(pt)); }); } - case Type::Convex: + case BuildVolume_Type::Convex: //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently. - case Type::Custom: + case BuildVolume_Type::Custom: return m_max_print_height == 0.0 ? object_state_templ(its, trafo, may_be_below_bed, [this](const Vec3f &pt) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_scene, to_2d(pt).cast()); }) : object_state_templ(its, trafo, may_be_below_bed, [this, z = m_max_print_height + SceneEpsilon](const Vec3f &pt) { return pt.z() < z && Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_scene, to_2d(pt).cast()); }); - case Type::Invalid: + case BuildVolume_Type::Invalid: default: return ObjectState::Inside; } @@ -306,7 +306,7 @@ BuildVolume::ObjectState BuildVolume::object_state(const indexed_triangle_set& i BuildVolume::ObjectState BuildVolume::volume_state_bbox(const BoundingBoxf3& volume_bbox, bool ignore_bottom) const { - assert(m_type == Type::Rectangle); + assert(m_type == BuildVolume_Type::Rectangle); BoundingBox3Base build_volume = this->bounding_volume().inflated(SceneEpsilon); if (m_max_print_height == 0.0) build_volume.max.z() = std::numeric_limits::max(); @@ -325,7 +325,7 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult& paths, const Boun static constexpr const double epsilon = BedEpsilon; switch (m_type) { - case Type::Rectangle: + case BuildVolume_Type::Rectangle: { BoundingBox3Base build_volume = this->bounding_volume().inflated(epsilon); if (m_max_print_height == 0.0) @@ -334,7 +334,7 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult& paths, const Boun build_volume.min.z() = -std::numeric_limits::max(); return build_volume.contains(paths_bbox); } - case Type::Circle: + case BuildVolume_Type::Circle: { const Vec2f c = unscaled(m_circle.center); const float r = unscaled(m_circle.radius) + epsilon; @@ -345,9 +345,9 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult& paths, const Boun std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, c, r2, z = m_max_print_height + epsilon](const GCodeProcessorResult::MoveVertex& move) { return ! move_valid(move) || ((to_2d(move.position) - c).squaredNorm() <= r2 && move.position.z() <= z); }); } - case Type::Convex: + case BuildVolume_Type::Convex: //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently. - case Type::Custom: + case BuildVolume_Type::Custom: return m_max_print_height == 0.0 ? std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, this](const GCodeProcessorResult::MoveVertex &move) { return ! move_valid(move) || Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(move.position).cast()); }) : @@ -375,7 +375,7 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v assert(paths.size() % 6 == 0); static constexpr const double epsilon = BedEpsilon; switch (m_type) { - case Type::Rectangle: + case BuildVolume_Type::Rectangle: { BoundingBox3Base build_volume = this->bounding_volume().inflated(epsilon); if (m_max_print_height == 0.0) @@ -384,7 +384,7 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v build_volume.min.z() = -std::numeric_limits::max(); return build_volume.contains(paths_bbox.min().cast()) && build_volume.contains(paths_bbox.max().cast()); } - case Type::Circle: + case BuildVolume_Type::Circle: { const Vec2f c = unscaled(m_circle.center); const float r = unscaled(m_circle.radius) + float(epsilon); @@ -393,9 +393,9 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v all_inside_vertices_normals_interleaved(paths, [c, r2](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2; }) : all_inside_vertices_normals_interleaved(paths, [c, r2, z = m_max_print_height + epsilon](Vec3f p) { return (to_2d(p) - c).squaredNorm() <= r2 && p.z() <= z; }); } - case Type::Convex: + case BuildVolume_Type::Convex: //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently. - case Type::Custom: + case BuildVolume_Type::Custom: return m_max_print_height == 0.0 ? all_inside_vertices_normals_interleaved(paths, [this](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast()); }) : all_inside_vertices_normals_interleaved(paths, [this, z = m_max_print_height + epsilon](Vec3f p) { return Geometry::inside_convex_polygon(m_top_bottom_convex_hull_decomposition_bed, to_2d(p).cast()) && p.z() <= z; }); @@ -404,15 +404,15 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v } } -std::string_view BuildVolume::type_name(Type type) +std::string_view BuildVolume::type_name(BuildVolume_Type type) { using namespace std::literals; switch (type) { - case Type::Invalid: return "Invalid"sv; - case Type::Rectangle: return "Rectangle"sv; - case Type::Circle: return "Circle"sv; - case Type::Convex: return "Convex"sv; - case Type::Custom: return "Custom"sv; + case BuildVolume_Type::Invalid: return "Invalid"sv; + case BuildVolume_Type::Rectangle: return "Rectangle"sv; + case BuildVolume_Type::Circle: return "Circle"sv; + case BuildVolume_Type::Convex: return "Convex"sv; + case BuildVolume_Type::Custom: return "Custom"sv; } // make visual studio happy assert(false); diff --git a/src/libslic3r/BuildVolume.hpp b/src/libslic3r/BuildVolume.hpp index 7154807636..4ab007f8b8 100644 --- a/src/libslic3r/BuildVolume.hpp +++ b/src/libslic3r/BuildVolume.hpp @@ -12,24 +12,23 @@ namespace Slic3r { struct GCodeProcessorResult; - +enum class BuildVolume_Type : unsigned char { + // Not set yet or undefined. + Invalid, + // Rectangular print bed. Most common, cheap to work with. + Rectangle, + // Circular print bed. Common on detals, cheap to work with. + Circle, + // Convex print bed. Complex to process. + Convex, + // Some non convex shape. + Custom +}; // For collision detection of objects and G-code (extrusion paths) against the build volume. class BuildVolume { public: - enum class Type : unsigned char - { - // Not set yet or undefined. - Invalid, - // Rectangular print bed. Most common, cheap to work with. - Rectangle, - // Circular print bed. Common on detals, cheap to work with. - Circle, - // Convex print bed. Complex to process. - Convex, - // Some non convex shape. - Custom - }; + // Initialized to empty, all zeros, Invalid. BuildVolume() {} @@ -41,11 +40,11 @@ public: double printable_height() const { return m_max_print_height; } // Derived data - Type type() const { return m_type; } + BuildVolume_Type type() const { return m_type; } // Format the type for console output. - static std::string_view type_name(Type type); + static std::string_view type_name(BuildVolume_Type type); std::string_view type_name() const { return type_name(m_type); } - bool valid() const { return m_type != Type::Invalid; } + bool valid() const { return m_type != BuildVolume_Type::Invalid; } // Same as printable_area(), but scaled coordinates. const Polygon& polygon() const { return m_polygon; } // Bounding box of polygon(), scaled. @@ -101,7 +100,7 @@ private: double m_max_print_height { 0.f }; // Derived values. - Type m_type { Type::Invalid }; + BuildVolume_Type m_type { BuildVolume_Type::Invalid }; // Geometry of the print bed, scaled copy of m_bed_shape. Polygon m_polygon; // Scaled snug bounding box around m_polygon. diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index af3f22591f..f6daadddf1 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -131,6 +131,9 @@ public: // Was the model generated procedurally? bool is_custom() const { return m_type == Type::Custom; } + // get the bed shape type + BuildVolume_Type get_build_volume_type() const { return m_build_volume.type(); } + // Bounding box around the print bed, axes and model, for rendering. const BoundingBoxf3& extended_bounding_box() const { return m_extended_bounding_box; } diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 5cbb412e42..6887e459bd 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1414,14 +1414,14 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo state = BuildVolume::ObjectState::Below; else { switch (plate_build_volume.type()) { - case BuildVolume::Type::Rectangle: + case BuildVolume_Type::Rectangle: //FIXME this test does not evaluate collision of a build volume bounding box with non-convex objects. state = plate_build_volume.volume_state_bbox(bb); break; - case BuildVolume::Type::Circle: - case BuildVolume::Type::Convex: + case BuildVolume_Type::Circle: + case BuildVolume_Type::Convex: //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently. - case BuildVolume::Type::Custom: + case BuildVolume_Type::Custom: state = plate_build_volume.object_state(volume_convex_mesh(*volume).its, volume->world_matrix().cast(), volume_sinking(*volume)); break; default: diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp index 9f730d112a..b6863cac34 100644 --- a/src/slic3r/GUI/BedShapeDialog.cpp +++ b/src/slic3r/GUI/BedShapeDialog.cpp @@ -88,11 +88,11 @@ wxString BedShape::get_name(PageType type) BedShape::PageType BedShape::get_page_type() { switch (m_build_volume.type()) { - case BuildVolume::Type::Rectangle: - case BuildVolume::Type::Invalid: return PageType::Rectangle; - case BuildVolume::Type::Circle: return PageType::Circle; - case BuildVolume::Type::Convex: - case BuildVolume::Type::Custom: return PageType::Custom; + case BuildVolume_Type::Rectangle: + case BuildVolume_Type::Invalid: return PageType::Rectangle; + case BuildVolume_Type::Circle: return PageType::Circle; + case BuildVolume_Type::Convex: + case BuildVolume_Type::Custom: return PageType::Custom; } // make visual studio happy assert(false); @@ -103,7 +103,7 @@ wxString BedShape::get_full_name_with_params() { wxString out = _L("Shape") + ": " + get_name(this->get_page_type()); switch (m_build_volume.type()) { - case BuildVolume::Type::Circle: + case BuildVolume_Type::Circle: out += "\n" + _L(get_option_label(Parameter::Diameter)) + ": [" + double_to_string(2. * unscaled(m_build_volume.circle().radius)) + "]"; break; default: @@ -118,7 +118,7 @@ wxString BedShape::get_full_name_with_params() void BedShape::apply_optgroup_values(ConfigOptionsGroupShp optgroup) { switch (m_build_volume.type()) { - case BuildVolume::Type::Circle: + case BuildVolume_Type::Circle: optgroup->set_value("diameter", double_to_string(2. * unscaled(m_build_volume.circle().radius))); break; default: diff --git a/src/slic3r/GUI/BedShapeDialog.hpp b/src/slic3r/GUI/BedShapeDialog.hpp index 032aa28800..638edd30b6 100644 --- a/src/slic3r/GUI/BedShapeDialog.hpp +++ b/src/slic3r/GUI/BedShapeDialog.hpp @@ -35,7 +35,7 @@ struct BedShape BedShape(const ConfigOptionPoints& points); - bool is_custom() { return m_build_volume.type() == BuildVolume::Type::Convex || m_build_volume.type() == BuildVolume::Type::Custom; } + bool is_custom() { return m_build_volume.type() == BuildVolume_Type::Convex || m_build_volume.type() == BuildVolume_Type::Custom; } static void append_option_line(ConfigOptionsGroupShp optgroup, Parameter param); static wxString get_name(PageType type); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 3d084d0a9e..1078f60402 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -116,7 +116,7 @@ RetinaHelper::~RetinaHelper() {} float RetinaHelper::get_scale_factor() { return float(m_window->GetContentScaleFactor()); } #endif // __WXGTK3__ -// Fixed the collision between BuildVolume::Type::Convex and macro Convex defined inside /usr/include/X11/X.h that is included by WxWidgets 3.0. +// Fixed the collision between BuildVolume_Type::Convex and macro Convex defined inside /usr/include/X11/X.h that is included by WxWidgets 3.0. #if defined(__linux__) && defined(Convex) #undef Convex #endif @@ -6542,22 +6542,22 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with if (const BuildVolume &build_volume = m_bed.build_volume(); build_volume.valid()) { switch (build_volume.type()) { - case BuildVolume::Type::Rectangle: { + case BuildVolume_Type::Rectangle: { const BoundingBox3Base bed_bb = build_volume.bounding_volume().inflated(BuildVolume::SceneEpsilon); m_volumes.set_print_volume({ 0, // Rectangle { float(bed_bb.min.x()), float(bed_bb.min.y()), float(bed_bb.max.x()), float(bed_bb.max.y()) }, { 0.0f, float(build_volume.printable_height()) } }); break; } - case BuildVolume::Type::Circle: { + case BuildVolume_Type::Circle: { m_volumes.set_print_volume({ 1, // Circle { unscaled(build_volume.circle().center.x()), unscaled(build_volume.circle().center.y()), unscaled(build_volume.circle().radius + BuildVolume::SceneEpsilon), 0.0f }, { 0.0f, float(build_volume.printable_height() + BuildVolume::SceneEpsilon) } }); break; } default: - case BuildVolume::Type::Convex: - case BuildVolume::Type::Custom: { + case BuildVolume_Type::Convex: + case BuildVolume_Type::Custom: { m_volumes.set_print_volume({ static_cast(type), { -FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX }, { -FLT_MAX, FLT_MAX } } diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 6c3be2a0c1..e9c4a3675a 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -437,7 +437,8 @@ void PartPlate::calc_vertex_for_number(int index, bool one_number, GeometryBuffe poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP + PARTPLATE_ICON_SIZE - offset_x), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP)- PARTPLATE_ICON_GAP - PARTPLATE_TEXT_OFFSET_Y)}); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP + offset_x), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP)- PARTPLATE_ICON_GAP - PARTPLATE_TEXT_OFFSET_Y) }); #else //in the bottom - Vec2d& p = m_shape[1]; + auto bed_ext = get_extents(m_shape); + Vec2d p = bed_ext[1]; float offset_x = one_number?PARTPLATE_TEXT_OFFSET_X1: PARTPLATE_TEXT_OFFSET_X2; poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) + PARTPLATE_TEXT_OFFSET_Y) }); @@ -453,7 +454,11 @@ void PartPlate::calc_vertex_for_number(int index, bool one_number, GeometryBuffe void PartPlate::calc_vertex_for_icons(int index, GeometryBuffer &buffer) { ExPolygon poly; - Vec2d& p = m_shape[2]; + auto bed_ext = get_extents(m_shape); + Vec2d p = bed_ext[2]; + if (m_plater->get_build_volume_type() == BuildVolume_Type::Circle) + p[1] -= std::max( + 0.0, (bed_ext.size()(1) - 5 * PARTPLATE_ICON_SIZE - 4 * PARTPLATE_ICON_GAP_Y - PARTPLATE_ICON_GAP_TOP) / 2); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y) - PARTPLATE_ICON_GAP_TOP - PARTPLATE_ICON_SIZE) }); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + PARTPLATE_ICON_SIZE), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y)- PARTPLATE_ICON_GAP_TOP - PARTPLATE_ICON_SIZE) }); @@ -468,7 +473,8 @@ void PartPlate::calc_vertex_for_icons(int index, GeometryBuffer &buffer) void PartPlate::calc_vertex_for_icons_background(int icon_count, GeometryBuffer &buffer) { ExPolygon poly; - Vec2d& p = m_shape[2]; + auto bed_ext = get_extents(m_shape); + Vec2d p = bed_ext[2]; poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT), scale_(p(1) - icon_count * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y) - PARTPLATE_ICON_GAP_TOP) }); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + PARTPLATE_ICON_SIZE), scale_(p(1) - icon_count * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y)- PARTPLATE_ICON_GAP_TOP) }); @@ -1576,7 +1582,7 @@ void PartPlate::generate_plate_name_texture() float offset_x = 1; w = int(factor * (m_name_texture.get_width() * 16) / m_name_texture.get_height()); h = int(factor * 16); - Vec2d p = m_shape[3] + Vec2d(0, h*0.6); + Vec2d p = bed_ext[3] + Vec2d(0, h*0.6); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) - h + PARTPLATE_TEXT_OFFSET_Y) }); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w - offset_x), scale_(p(1) - h + PARTPLATE_TEXT_OFFSET_Y) }); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w - offset_x), scale_(p(1) - PARTPLATE_TEXT_OFFSET_Y)}); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index fcac4bda99..cd41b3e714 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6862,8 +6862,8 @@ bool Plater::priv::has_assemble_view() const #if ENABLE_ENHANCED_PRINT_VOLUME_FIT bool Plater::priv::can_scale_to_print_volume() const { - const BuildVolume::Type type = this->bed.build_volume().type(); - return !view3D->get_canvas3d()->get_selection().is_empty() && (type == BuildVolume::Type::Rectangle || type == BuildVolume::Type::Circle); + const BuildVolume_Type type = this->bed.build_volume().type(); + return !view3D->get_canvas3d()->get_selection().is_empty() && (type == BuildVolume_Type::Rectangle || type == BuildVolume_Type::Circle); } #endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT @@ -8369,6 +8369,7 @@ void Plater::calib_VFA(const Calib_Params& params) p->background_process.fff_print()->set_calib_params(params); } +BuildVolume_Type Plater::get_build_volume_type() const { return p->bed.get_build_volume_type(); } void Plater::import_sl1_archive() { if (!p->m_ui_jobs.is_any_running()) diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 909f93925f..44c5fef571 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -38,6 +38,7 @@ class Button; namespace Slic3r { class BuildVolume; +enum class BuildVolume_Type : unsigned char; class Model; class ModelObject; enum class ModelObjectCutAttribute : int; @@ -236,6 +237,8 @@ public: void calib_max_vol_speed(const Calib_Params& params); void calib_VFA(const Calib_Params& params); + BuildVolume_Type get_build_volume_type() const; + //BBS: add only gcode mode bool only_gcode_mode() { return m_only_gcode; } void set_only_gcode(bool only_gcode) { m_only_gcode = only_gcode; } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index dea947993a..753bbf08b4 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1234,8 +1234,8 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume) switch (volume.type()) { - case BuildVolume::Type::Rectangle: { fit_rectangle(volume); break; } - case BuildVolume::Type::Circle: { fit_circle(volume); break; } + case BuildVolume_Type::Rectangle: { fit_rectangle(volume); break; } + case BuildVolume_Type::Circle: { fit_circle(volume); break; } default: { break; } } }