diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 9664f27f6..a0d2e8c51 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -85,6 +85,17 @@ ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_ return ModelInstancePVS_Fully_Outside; } + +ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const BoundingBoxf3& box) +{ + const Polygon box_hull_2d({ + { scale_(box.min.x()), scale_(box.min.y()) }, + { scale_(box.max.x()), scale_(box.min.y()) }, + { scale_(box.max.x()), scale_(box.max.y()) }, + { scale_(box.min.x()), scale_(box.max.y()) } + }); + return printbed_collision_state(printbed_shape, print_volume_height, box_hull_2d, box.min.z(), box.max.z()); +} #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS #if ENABLE_SMOOTH_NORMALS @@ -984,11 +995,17 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M #if ENABLE_FIX_SINKING_OBJECT_OUT_OF_BED_DETECTION bool contained = false; bool intersects = false; - const BoundingBoxf3& bb = volume->transformed_non_sinking_bounding_box(); + bool is_sla = GUI::wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA; + const BoundingBoxf3 bb = is_sla ? volume->transformed_convex_hull_bounding_box() : volume->transformed_non_sinking_bounding_box(); #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS - const indexed_triangle_set& its = GUI::wxGetApp().plater()->model().objects[volume->object_idx()]->volumes[volume->volume_idx()]->mesh().its; - const Polygon volume_hull_2d = its_convex_hull_2d_above(its, volume->world_matrix().cast(), 0.0f); - const ModelInstanceEPrintVolumeState volume_state = printbed_collision_state(bed_poly, bed_height, volume_hull_2d, bb.min.z(), bb.max.z()); + ModelInstanceEPrintVolumeState volume_state; + if (is_sla) + volume_state = printbed_collision_state(bed_poly, bed_height, bb); + else { + const indexed_triangle_set& its = GUI::wxGetApp().plater()->model().objects[volume->object_idx()]->volumes[volume->volume_idx()]->mesh().its; + const Polygon volume_hull_2d = its_convex_hull_2d_above(its, volume->world_matrix().cast(), 0.0f); + volume_state = printbed_collision_state(bed_poly, bed_height, volume_hull_2d, bb.min.z(), bb.max.z()); + } contained = (volume_state == ModelInstancePVS_Inside); intersects = (volume_state == ModelInstancePVS_Partly_Outside); #else diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index b305d0231..ce57d5410 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -45,6 +45,9 @@ std::array color_from_model_volume(const ModelVolume& model_volume); // return the state of given object volume (extrusion along z of obj_hull_2d by obj_height) // with respect to the given print volume (extrusion along z of printbed_shape by print_volume_height) ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const Polygon& obj_hull_2d, double obj_min_z, double obj_max_z); +// return the state of given box +// with respect to the given print volume (extrusion along z of printbed_shape by print_volume_height) +ModelInstanceEPrintVolumeState printbed_collision_state(const Polygon& printbed_shape, double print_volume_height, const BoundingBoxf3& box); #endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS // A container for interleaved arrays of 3D vertices and normals, diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 12e829f8b..a5bba3471 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4984,6 +4984,7 @@ void GLCanvas3D::_rectangular_selection_picking_pass() _update_volumes_hover_state(); } +#if !ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS static BoundingBoxf3 print_volume(const DynamicPrintConfig& config) { // tolerance to avoid false detection at bed edges @@ -5000,6 +5001,7 @@ static BoundingBoxf3 print_volume(const DynamicPrintConfig& config) } return ret; } +#endif // !ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS void GLCanvas3D::_render_background() const { @@ -5013,18 +5015,17 @@ void GLCanvas3D::_render_background() const else { #if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS const ConfigOptionPoints* opt = dynamic_cast(m_config->option("bed_shape")); - if (opt != nullptr) { - const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast(scale_(BedEpsilon))).front(); - const float bed_height = m_config->opt_float("max_print_height"); - const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box(); - Polygon paths_hull_2d; - paths_hull_2d.append({ scale_(paths_volume.min.x()), scale_(paths_volume.min.y()) }); - paths_hull_2d.append({ scale_(paths_volume.max.x()), scale_(paths_volume.min.y()) }); - paths_hull_2d.append({ scale_(paths_volume.max.x()), scale_(paths_volume.max.y()) }); - paths_hull_2d.append({ scale_(paths_volume.min.x()), scale_(paths_volume.max.y()) }); - const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, paths_hull_2d, paths_volume.min.z(), paths_volume.max.z()); - use_error_color &= state != ModelInstancePVS_Inside; - } + const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast(scale_(BedEpsilon))).front(); + const float bed_height = m_config->opt_float("max_print_height"); + const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, m_gcode_viewer.get_paths_bounding_box()); +// const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box(); +// Polygon paths_hull_2d; +// paths_hull_2d.append({ scale_(paths_volume.min.x()), scale_(paths_volume.min.y()) }); +// paths_hull_2d.append({ scale_(paths_volume.max.x()), scale_(paths_volume.min.y()) }); +// paths_hull_2d.append({ scale_(paths_volume.max.x()), scale_(paths_volume.max.y()) }); +// paths_hull_2d.append({ scale_(paths_volume.min.x()), scale_(paths_volume.max.y()) }); +// const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, paths_hull_2d, paths_volume.min.z(), paths_volume.max.z()); + use_error_color &= state != ModelInstancePVS_Inside; #else const BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box(); @@ -6355,18 +6356,46 @@ void GLCanvas3D::_load_sla_shells() void GLCanvas3D::_update_toolpath_volumes_outside_state() { +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + const ConfigOptionPoints* opt = dynamic_cast(m_config->option("bed_shape")); + const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast(scale_(BedEpsilon))).front(); + const float bed_height = m_config->opt_float("max_print_height"); + for (GLVolume* volume : m_volumes.volumes) { + if (volume->is_extrusion_path) { + const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, volume->bounding_box()); + volume->is_outside = (state != ModelInstancePVS_Inside); + } + else + volume->is_outside = false; + } +#else BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); for (GLVolume* volume : m_volumes.volumes) { volume->is_outside = (test_volume.radius() > 0.0 && volume->is_extrusion_path) ? !test_volume.contains(volume->bounding_box()) : false; } +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS } void GLCanvas3D::_update_sla_shells_outside_state() { +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + const ConfigOptionPoints* opt = dynamic_cast(m_config->option("bed_shape")); + const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast(scale_(BedEpsilon))).front(); + const float bed_height = m_config->opt_float("max_print_height"); + for (GLVolume* volume : m_volumes.volumes) { + if (volume->shader_outside_printer_detection_enabled) { + const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, volume->transformed_convex_hull_bounding_box()); + volume->is_outside = (state != ModelInstancePVS_Inside); + } + else + volume->is_outside = false; + } +#else BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); for (GLVolume* volume : m_volumes.volumes) { volume->is_outside = (test_volume.radius() > 0.0 && volume->shader_outside_printer_detection_enabled) ? !test_volume.contains(volume->transformed_convex_hull_bounding_box()) : false; } +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS } void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning) @@ -6377,10 +6406,18 @@ void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning) show = _is_any_volume_outside(); else { if (wxGetApp().is_editor()) { +#if ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS + const ConfigOptionPoints* opt = dynamic_cast(m_config->option("bed_shape")); + const Polygon bed_poly = offset(Polygon::new_scale(opt->values), static_cast(scale_(BedEpsilon))).front(); + const float bed_height = m_config->opt_float("max_print_height"); + const ModelInstanceEPrintVolumeState state = printbed_collision_state(bed_poly, bed_height, m_gcode_viewer.get_paths_bounding_box()); + show = state != ModelInstancePVS_Inside; +#else BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box(); if (test_volume.radius() > 0.0 && paths_volume.radius() > 0.0) show = !test_volume.contains(paths_volume); +#endif // ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS } } _set_warning_notification(warning, show);