diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index c8e72ba399..ee28fd718f 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -990,22 +990,24 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M } }; - auto check_against_circular_bed = [](GLVolume& volume, ModelInstanceEPrintVolumeState& state, const Vec2d& center, double radius) { - const TriangleMesh* mesh = (volume.is_sinking() && volume.object_idx() != -1 && volume.volume_idx() != -1)? &GUI::wxGetApp().plater()->model().objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : volume.convex_hull(); - //FIXME 2D convex hull is O(n log n), while testing the 2D points against 2D circle is O(n). - const Polygon volume_hull_2d = its_convex_hull_2d_above(mesh->its, volume.world_matrix().cast(), 0.0f); - size_t outside_count = 0; + auto check_against_circular_bed = [bed_height](GLVolume& volume, ModelInstanceEPrintVolumeState& state, const Vec2d& center, double radius) { + const TriangleMesh* mesh = (volume.is_sinking() && volume.object_idx() != -1 && volume.volume_idx() != -1) ? &GUI::wxGetApp().plater()->model().objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : volume.convex_hull(); const double sq_radius = sqr(radius); - for (const Point& p : volume_hull_2d.points) { - if (sq_radius < (unscale(p) - center).squaredNorm()) - ++outside_count; + size_t outside_count = 0; + size_t valid_count = 0; + for (const Vec3f& v : mesh->its.vertices) { + const Vec3f world_v = volume.world_matrix().cast() * v; + if (0.0f <= world_v.z()) { + ++valid_count; + if (sq_radius < sqr(world_v.x() - center.x()) + sqr(world_v.y() - center.y()) || bed_height < world_v.z()) + ++outside_count; + } } - volume.is_outside = outside_count > 0; if (volume.printable) { if (state == ModelInstancePVS_Inside && volume.is_outside) state = ModelInstancePVS_Fully_Outside; - if (state == ModelInstancePVS_Fully_Outside && volume.is_outside && outside_count < volume_hull_2d.size()) + if (state == ModelInstancePVS_Fully_Outside && volume.is_outside && outside_count < valid_count) state = ModelInstancePVS_Partly_Outside; } }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b44fa167a3..4af16fc1dc 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2150,10 +2150,18 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors, c // Release OpenGL data before generating new data. this->reset_volumes(); +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + bool requires_convex_hulls = wxGetApp().plater()->get_bed().get_shape_type() != Bed3D::EShapeType::Rectangle; + _load_print_toolpaths(requires_convex_hulls); + _load_wipe_tower_toolpaths(str_tool_colors, requires_convex_hulls); + for (const PrintObject* object : print->objects()) + _load_print_object_toolpaths(*object, str_tool_colors, color_print_values, requires_convex_hulls); +#else _load_print_toolpaths(); _load_wipe_tower_toolpaths(str_tool_colors); for (const PrintObject* object : print->objects()) _load_print_object_toolpaths(*object, str_tool_colors, color_print_values); +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS _update_toolpath_volumes_outside_state(); _set_warning_notification_if_needed(EWarning::ToolpathOutside); @@ -5804,7 +5812,11 @@ void GLCanvas3D::_stop_timer() m_timer.Stop(); } +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS +void GLCanvas3D::_load_print_toolpaths(bool generate_convex_hulls) +#else void GLCanvas3D::_load_print_toolpaths() +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS { const Print *print = this->fff_print(); if (print == nullptr) @@ -5858,12 +5870,17 @@ void GLCanvas3D::_load_print_toolpaths() } } #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS - volume->calc_convex_hull_3d(); + if (generate_convex_hulls) + volume->calc_convex_hull_3d(); #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS volume->indexed_vertex_array.finalize_geometry(m_initialized); } +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS +void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values, bool generate_convex_hulls) +#else void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values) +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS { std::vector> tool_colors = _parse_colors(str_tool_colors); @@ -6153,7 +6170,8 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) { GLVolume* v = m_volumes.volumes[i]; - v->calc_convex_hull_3d(); + if (generate_convex_hulls) + v->calc_convex_hull_3d(); v->indexed_vertex_array.finalize_geometry(m_initialized); } #else @@ -6164,7 +6182,11 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info(); } +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS +void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_tool_colors, bool generate_convex_hulls) +#else void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_tool_colors) +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS { const Print *print = this->fff_print(); if (print == nullptr || print->wipe_tower_data().tool_changes.empty()) @@ -6318,7 +6340,8 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) { GLVolume* v = m_volumes.volumes[i]; - v->calc_convex_hull_3d(); + if (generate_convex_hulls) + v->calc_convex_hull_3d(); v->indexed_vertex_array.finalize_geometry(m_initialized); } #else diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a18f1ec072..e521add98f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -955,6 +955,18 @@ private: void _start_timer(); void _stop_timer(); +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + // Create 3D thick extrusion lines for a skirt and brim. + // Adds a new Slic3r::GUI::3DScene::Volume to volumes. + void _load_print_toolpaths(bool generate_convex_hulls = false); + // Create 3D thick extrusion lines for object forming extrusions. + // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes, + // one for perimeters, one for infill and one for supports. + void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, + const std::vector& color_print_values, bool generate_convex_hulls = false); + // Create 3D thick extrusion lines for wipe tower extrusions + void _load_wipe_tower_toolpaths(const std::vector& str_tool_colors, bool generate_convex_hulls = false); +#else // Create 3D thick extrusion lines for a skirt and brim. // Adds a new Slic3r::GUI::3DScene::Volume to volumes. void _load_print_toolpaths(); @@ -962,9 +974,10 @@ private: // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes, // one for perimeters, one for infill and one for supports. void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, - const std::vector& color_print_values); + const std::vector& color_print_values); // Create 3D thick extrusion lines for wipe tower extrusions void _load_wipe_tower_toolpaths(const std::vector& str_tool_colors); +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS // Load SLA objects and support structures for objects, for which the slaposSliceSupports step has been finished. void _load_sla_shells();