diff --git a/resources/shaders/gouraud.fs b/resources/shaders/gouraud.fs index d5f7442d4..3aa2b0294 100644 --- a/resources/shaders/gouraud.fs +++ b/resources/shaders/gouraud.fs @@ -64,6 +64,23 @@ void main() alpha = 1.0; } + // if the fragment is outside the print volume -> use darker color + vec3 pv_check_min = ZERO; + vec3 pv_check_max = ZERO; + if (print_volume.type == 0) { + // rectangle + pv_check_min = world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x); + pv_check_max = world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y); + color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color; + } + else if (print_volume.type == 1) { + // circle + float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy); + pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x); + pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y); + color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color; + } + //BBS: add outline_color if (is_outline) gl_FragColor = uniform_color; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index e5d9cc246..20af61a7d 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -434,6 +434,7 @@ GLVolume::GLVolume(float r, float g, float b, float a) , zoom_to_volumes(true) , shader_outside_printer_detection_enabled(false) , is_outside(false) + , partly_inside(false) , hover(HS_None) , is_modifier(false) , is_wipe_tower(false) @@ -679,7 +680,7 @@ void GLVolume::render(bool with_outline) const bool color_volume = false; ModelObjectPtrs& model_objects = GUI::wxGetApp().model().objects; do { - if (object_idx() >= model_objects.size()) + if ((!printable) || object_idx() >= model_objects.size()) break; ModelObject* mo = model_objects[object_idx()]; @@ -907,7 +908,7 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj ModelObject* model_object = nullptr; ModelVolume* model_volume = nullptr; do { - if (object_idx() >= model_objects.size()) + if ((!printable) || object_idx() >= model_objects.size()) break; model_object = model_objects[object_idx()]; @@ -1290,9 +1291,16 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab //shader->set_uniform("print_volume.xy_data", m_render_volume.data); //shader->set_uniform("print_volume.z_data", m_render_volume.zs); - /*shader->set_uniform("print_volume.type", static_cast(m_print_volume.type)); - shader->set_uniform("print_volume.xy_data", m_print_volume.data); - shader->set_uniform("print_volume.z_data", m_print_volume.zs);*/ + if (volume.first->partly_inside) { + //only partly inside volume need to be painted with boundary check + shader->set_uniform("print_volume.type", static_cast(m_print_volume.type)); + shader->set_uniform("print_volume.xy_data", m_print_volume.data); + shader->set_uniform("print_volume.z_data", m_print_volume.zs); + } + else { + //use -1 ad a invalid type + shader->set_uniform("print_volume.type", -1); + } shader->set_uniform("volume_world_matrix", volume.first->world_matrix()); shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower); shader->set_uniform("slope.volume_world_normal_matrix", static_cast(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast())); @@ -1405,6 +1413,7 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo int64_t comp_id = ((int64_t)volume->composite_id.object_id << 32) | ((int64_t)volume->composite_id.instance_id); volume->is_outside = state != BuildVolume::ObjectState::Inside; + volume->partly_inside = (state == BuildVolume::ObjectState::Colliding); if (volume->printable) { if (overall_state == ModelInstancePVS_Inside && volume->is_outside) { overall_state = ModelInstancePVS_Fully_Outside; @@ -1459,8 +1468,10 @@ void GLVolumeCollection::reset_outside_state() { for (GLVolume* volume : this->volumes) { - if (volume != nullptr) + if (volume != nullptr) { volume->is_outside = false; + volume->partly_inside = false; + } } } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 2eaf09ed8..b1ad7671d 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -371,6 +371,7 @@ public: bool shader_outside_printer_detection_enabled : 1; // Wheter or not this volume is outside print volume. bool is_outside : 1; + bool partly_inside : 1; // Wheter or not this volume has been generated from a modifier bool is_modifier : 1; // Wheter or not this volume has been generated from the wipe tower diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e9a54f7da..c6db973d6 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2153,7 +2153,7 @@ void GLCanvas3D::bind_event_handlers() m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Bind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this); m_event_handlers_bound = true; - + m_canvas->Bind(wxEVT_GESTURE_PAN, &GLCanvas3D::on_gesture, this); m_canvas->Bind(wxEVT_GESTURE_ZOOM, &GLCanvas3D::on_gesture, this); m_canvas->Bind(wxEVT_GESTURE_ROTATE, &GLCanvas3D::on_gesture, this); @@ -2190,7 +2190,7 @@ void GLCanvas3D::unbind_event_handlers() m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Unbind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this); m_event_handlers_bound = false; - + m_canvas->Unbind(wxEVT_GESTURE_PAN, &GLCanvas3D::on_gesture, this); m_canvas->Unbind(wxEVT_GESTURE_ZOOM, &GLCanvas3D::on_gesture, this); m_canvas->Unbind(wxEVT_GESTURE_ROTATE, &GLCanvas3D::on_gesture, this); @@ -5670,13 +5670,13 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with switch (build_volume.type()) { case BuildVolume::Type::Rectangle: { const BoundingBox3Base bed_bb = build_volume.bounding_volume().inflated(BuildVolume::SceneEpsilon); - m_volumes.set_print_volume({ 0, // circle + 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: { - m_volumes.set_print_volume({ 1, // rectangle + 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; @@ -6627,10 +6627,10 @@ void GLCanvas3D::_render_paint_toolbar() const float gray = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]; if (gray < 80){ - ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), item_text.c_str()); + ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), item_text.c_str()); } else{ ImGui::TextColored(ImVec4(0.0f, 0.0f, 0.0f, 1.0f), item_text.c_str()); - } + } } ImGui::AlignTextToFramePadding(); imgui.end();