From 5a2b0e845ee62d43938378b251c7c7107601e484 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Tue, 23 Aug 2022 15:28:59 +0800 Subject: [PATCH] ENH: rendering: refine the rendering logic of GLVolume 1. set the unprintable volume to black even if it is mmu painted 2. add the bounding check logic when the object is partly inside of current plate Change-Id: I69ce25eb85a71398ed8fb1d275136c5d943796d6 --- resources/shaders/gouraud.fs | 17 +++++++++++++++++ src/slic3r/GUI/3DScene.cpp | 23 +++++++++++++++++------ src/slic3r/GUI/3DScene.hpp | 1 + src/slic3r/GUI/GLCanvas3D.cpp | 12 ++++++------ 4 files changed, 41 insertions(+), 12 deletions(-) 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();