diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 20fc0a38f9..1ca589fe83 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -62,6 +62,8 @@ #define ENABLE_RELOAD_FROM_DISK_REPLACE_FILE (1 && ENABLE_2_4_0_ALPHA2) // Enable the fix for the detection of the out of bed state for sinking objects #define ENABLE_FIX_SINKING_OBJECT_OUT_OF_BED_DETECTION (1 && ENABLE_2_4_0_ALPHA2) +// Enable detection of out of bed using the bed perimeter and other improvements +#define ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS (1 && ENABLE_2_4_0_ALPHA2) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 19864b36a4..3aba88a568 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -936,14 +936,13 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M const BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values)); BoundingBoxf3 print_volume({ unscale(bed_box_2D.min.x()), unscale(bed_box_2D.min.y()), 0.0 }, - { unscale(bed_box_2D.max.x()), unscale(bed_box_2D.max.y()), - config->opt_float("max_print_height") }); + { unscale(bed_box_2D.max.x()), unscale(bed_box_2D.max.y()), config->opt_float("max_print_height") }); // Allow the objects to protrude below the print bed - print_volume.min(2) = -1e10; - print_volume.min(0) -= BedEpsilon; - print_volume.min(1) -= BedEpsilon; - print_volume.max(0) += BedEpsilon; - print_volume.max(1) += BedEpsilon; + print_volume.min.z() = -1e10; + print_volume.min.x() -= BedEpsilon; + print_volume.min.y() -= BedEpsilon; + print_volume.max.x() += BedEpsilon; + print_volume.max.y() += BedEpsilon; ModelInstanceEPrintVolumeState state = ModelInstancePVS_Inside; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 83b907f013..68b0fd5f4d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5074,8 +5074,15 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type) if (m_config != nullptr) { const BoundingBoxf3& bed_bb = wxGetApp().plater()->get_bed().get_bounding_box(false); - m_volumes.set_print_box((float)bed_bb.min(0) - BedEpsilon, (float)bed_bb.min(1) - BedEpsilon, 0.0f, (float)bed_bb.max(0) + BedEpsilon, (float)bed_bb.max(1) + BedEpsilon, (float)m_config->opt_float("max_print_height")); + m_volumes.set_print_box((float)bed_bb.min.x() - BedEpsilon, (float)bed_bb.min.y() - BedEpsilon, 0.0f, (float)bed_bb.max.x() + BedEpsilon, (float)bed_bb.max.y() + BedEpsilon, (float)m_config->opt_float("max_print_height")); +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + if (m_requires_check_outside_state) { + m_volumes.check_outside_state(m_config, nullptr); + m_requires_check_outside_state = false; + } +#else m_volumes.check_outside_state(m_config, nullptr); +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS } } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index e03c4a71db..bbdcb9de6f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -475,6 +475,9 @@ private: const DynamicPrintConfig* m_config; Model* m_model; BackgroundSlicingProcess *m_process; +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + bool m_requires_check_outside_state{ false }; +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS std::array m_old_size{ 0, 0 }; @@ -611,6 +614,9 @@ public: void post_event(wxEvent &&event); void set_as_dirty(); +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + void requires_check_outside_state() { m_requires_check_outside_state = true; } +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS unsigned int get_volumes_count() const; const GLVolumeCollection& get_volumes() const { return m_volumes; } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 4a9c7cd564..6946bab0e4 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -715,6 +715,9 @@ void Selection::translate(const Vec3d& displacement, bool local) ensure_not_below_bed(); set_bounding_boxes_dirty(); +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + wxGetApp().plater()->canvas3D()->requires_check_outside_state(); +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS } // Rotate an object around one of the axes. Only one rotation component is expected to be changing. @@ -827,7 +830,10 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ volume.set_volume_offset(volume.get_volume_offset() + center_local - center_local_new); } - this->set_bounding_boxes_dirty(); + set_bounding_boxes_dirty(); +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + wxGetApp().plater()->canvas3D()->requires_check_outside_state(); +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS } void Selection::flattening_rotate(const Vec3d& normal) @@ -926,6 +932,9 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type ensure_on_bed(); set_bounding_boxes_dirty(); +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + wxGetApp().plater()->canvas3D()->requires_check_outside_state(); +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS } void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config) @@ -2125,10 +2134,10 @@ void Selection::ensure_not_below_bed() GLVolume* volume = (*m_volumes)[i]; if (!volume->is_wipe_tower && !volume->is_modifier) { const double max_z = volume->transformed_convex_hull_bounding_box().max.z(); - std::pair instance = std::make_pair(volume->object_idx(), volume->instance_idx()); + const std::pair instance = std::make_pair(volume->object_idx(), volume->instance_idx()); InstancesToZMap::iterator it = instances_max_z.find(instance); if (it == instances_max_z.end()) - it = instances_max_z.insert(InstancesToZMap::value_type(instance, -DBL_MAX)).first; + it = instances_max_z.insert({ instance, -DBL_MAX }).first; it->second = std::max(it->second, max_z); } @@ -2137,17 +2146,17 @@ void Selection::ensure_not_below_bed() if (is_any_volume()) { for (unsigned int i : m_list) { GLVolume& volume = *(*m_volumes)[i]; - std::pair instance = std::make_pair(volume.object_idx(), volume.instance_idx()); - InstancesToZMap::iterator it = instances_max_z.find(instance); - double z_shift = SINKING_MIN_Z_THRESHOLD - it->second; + const std::pair instance = std::make_pair(volume.object_idx(), volume.instance_idx()); + InstancesToZMap::const_iterator it = instances_max_z.find(instance); + const double z_shift = SINKING_MIN_Z_THRESHOLD - it->second; if (it != instances_max_z.end() && z_shift > 0.0) volume.set_volume_offset(Z, volume.get_volume_offset(Z) + z_shift); } } else { for (GLVolume* volume : *m_volumes) { - std::pair instance = std::make_pair(volume->object_idx(), volume->instance_idx()); - InstancesToZMap::iterator it = instances_max_z.find(instance); + const std::pair instance = std::make_pair(volume->object_idx(), volume->instance_idx()); + InstancesToZMap::const_iterator it = instances_max_z.find(instance); if (it != instances_max_z.end() && it->second < SINKING_MIN_Z_THRESHOLD) volume->set_instance_offset(Z, volume->get_instance_offset(Z) + SINKING_MIN_Z_THRESHOLD - it->second); }