From b3761c454bba281517f1cd21d3fa4d669c7e39ba Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 21 Oct 2019 17:30:21 +0200 Subject: [PATCH 01/37] fix xray error visualization missing red faces --- plugins/XRayView/xray_composite.shader | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/XRayView/xray_composite.shader b/plugins/XRayView/xray_composite.shader index 7ea5287f96..8bb0f83e9b 100644 --- a/plugins/XRayView/xray_composite.shader +++ b/plugins/XRayView/xray_composite.shader @@ -51,7 +51,7 @@ fragment = result = layer0 * layer0.a + result * (1.0 - layer0.a); float intersection_count = (texture2D(u_layer2, v_uvs).r * 255.0) / 5.0; - if(mod(intersection_count, 2.0) == 1.0) + if(mod(intersection_count, 2.0) >= 1.0) { result = u_error_color; } @@ -122,7 +122,7 @@ fragment41core = result = layer0 * layer0.a + result * (1.0 - layer0.a); float intersection_count = (texture(u_layer2, v_uvs).r * 255.0) / 5.0; - if(mod(intersection_count, 2.0) == 1.0) + if(mod(intersection_count, 2.0) >= 1.0) { result = u_error_color; } From fc4c66b62a7173d1260e40c121bc6133fbca6a88 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 21 Oct 2019 17:34:23 +0200 Subject: [PATCH 02/37] show xray errors in solid view --- {plugins/XRayView => cura}/XRayPass.py | 3 +- plugins/SolidView/SolidView.py | 74 +++++++- plugins/SolidView/xray_composite.shader | 166 ++++++++++++++++++ plugins/SolidView/xray_overlay.shader | 50 ++++++ plugins/XRayView/XRayView.py | 6 +- .../shaders}/xray.shader | 0 6 files changed, 295 insertions(+), 4 deletions(-) rename {plugins/XRayView => cura}/XRayPass.py (93%) create mode 100644 plugins/SolidView/xray_composite.shader create mode 100755 plugins/SolidView/xray_overlay.shader rename {plugins/XRayView => resources/shaders}/xray.shader (100%) diff --git a/plugins/XRayView/XRayPass.py b/cura/XRayPass.py similarity index 93% rename from plugins/XRayView/XRayPass.py rename to cura/XRayPass.py index a75d393b35..edc20ce62d 100644 --- a/plugins/XRayView/XRayPass.py +++ b/cura/XRayPass.py @@ -3,6 +3,7 @@ import os.path +from UM.Resources import Resources from UM.Application import Application from UM.PluginRegistry import PluginRegistry @@ -23,7 +24,7 @@ class XRayPass(RenderPass): def render(self): if not self._shader: - self._shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray.shader")) + self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) batch = RenderBatch(self._shader, type = RenderBatch.RenderType.NoType, backface_cull = False, blend_mode = RenderBatch.BlendMode.Additive) for node in DepthFirstIterator(self._scene.getRoot()): diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 4f15bafedb..565a704b0a 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -1,17 +1,29 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import os.path from UM.View.View import View from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Selection import Selection from UM.Resources import Resources +from PyQt5.QtGui import QOpenGLContext + from UM.Application import Application -from UM.View.RenderBatch import RenderBatch +from UM.Logger import Logger from UM.Math.Color import Color +from UM.PluginRegistry import PluginRegistry +from UM.Platform import Platform +from UM.Event import Event + +from UM.View.RenderBatch import RenderBatch from UM.View.GL.OpenGL import OpenGL +from cura.CuraApplication import CuraApplication + from cura.Settings.ExtruderManager import ExtruderManager +from cura import XRayPass + import math ## Standard view for mesh models. @@ -27,12 +39,20 @@ class SolidView(View): self._non_printing_shader = None self._support_mesh_shader = None + self._xray_shader = None + self._xray_pass = None + self._xray_composite_shader = None + self._composite_pass = None + self._extruders_model = None self._theme = None self._support_angle = 90 self._global_stack = None + self._old_composite_shader = None + self._old_layer_bindings = None + Application.getInstance().engineCreatedSignal.connect(self._onGlobalContainerChanged) def _onGlobalContainerChanged(self) -> None: @@ -98,6 +118,32 @@ class SolidView(View): self._checkSetup() + if not self._xray_shader: + self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) + self._xray_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("xray").getRgb())) + + if not self._xray_composite_shader: + self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SolidView"), "xray_composite.shader")) + theme = Application.getInstance().getTheme() + self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) + self._xray_composite_shader.setUniformValue("u_error_color", Color(*theme.getColor("xray_error").getRgb())) + self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) + + if not self.getRenderer().getRenderPass("xray"): + # Currently the RenderPass constructor requires a size > 0 + # This should be fixed in RenderPass's constructor. + self._xray_pass = XRayPass.XRayPass(1, 1) + + self.getRenderer().addRenderPass(self._xray_pass) + + if not self._composite_pass: + self._composite_pass = self.getRenderer().getRenderPass("composite") + + self._old_layer_bindings = self._composite_pass.getLayerBindings() + self._composite_pass.setLayerBindings(["default", "selection", "xray"]) + self._old_composite_shader = self._composite_pass.getCompositeShader() + self._composite_pass.setCompositeShader(self._xray_composite_shader) + global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: if Application.getInstance().getPreferences().getValue("view/show_overhang"): @@ -174,5 +220,31 @@ class SolidView(View): if node.callDecoration("isGroup") and Selection.isSelected(node): renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(), mode = RenderBatch.RenderMode.LineLoop) + def endRendering(self): pass + + def event(self, event): + if event.type == Event.ViewActivateEvent: + # FIX: on Max OS X, somehow QOpenGLContext.currentContext() can become None during View switching. + # This can happen when you do the following steps: + # 1. Start Cura + # 2. Load a model + # 3. Switch to Custom mode + # 4. Select the model and click on the per-object tool icon + # 5. Switch view to Layer view or X-Ray + # 6. Cura will very likely crash + # It seems to be a timing issue that the currentContext can somehow be empty, but I have no clue why. + # This fix tries to reschedule the view changing event call on the Qt thread again if the current OpenGL + # context is None. + if Platform.isOSX(): + if QOpenGLContext.currentContext() is None: + Logger.log("d", "current context of OpenGL is empty on Mac OS X, will try to create shaders later") + CuraApplication.getInstance().callLater(lambda e = event: self.event(e)) + return + + + if event.type == Event.ViewDeactivateEvent: + self.getRenderer().removeRenderPass(self._xray_pass) + self._composite_pass.setLayerBindings(self._old_layer_bindings) + self._composite_pass.setCompositeShader(self._old_composite_shader) diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader new file mode 100644 index 0000000000..e3ac2162a7 --- /dev/null +++ b/plugins/SolidView/xray_composite.shader @@ -0,0 +1,166 @@ +[shaders] +vertex = + uniform highp mat4 u_modelViewProjectionMatrix; + attribute highp vec4 a_vertex; + attribute highp vec2 a_uvs; + + varying highp vec2 v_uvs; + + void main() + { + gl_Position = u_modelViewProjectionMatrix * a_vertex; + v_uvs = a_uvs; + } + +fragment = + #ifdef GL_ES + #ifdef GL_FRAGMENT_PRECISION_HIGH + precision highp float; + #else + precision mediump float; + #endif // GL_FRAGMENT_PRECISION_HIGH + #endif // GL_ES + uniform sampler2D u_layer0; //Default pass. + uniform sampler2D u_layer1; //Selection pass. + uniform sampler2D u_layer2; //X-ray pass. + + uniform vec2 u_offset[9]; + + uniform float u_outline_strength; + uniform vec4 u_outline_color; + uniform vec4 u_error_color; + uniform vec4 u_background_color; + + const vec3 x_axis = vec3(1.0, 0.0, 0.0); + const vec3 y_axis = vec3(0.0, 1.0, 0.0); + const vec3 z_axis = vec3(0.0, 0.0, 1.0); + + varying vec2 v_uvs; + + float kernel[9]; + + void main() + { + kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; + kernel[3] = 1.0; kernel[4] = -4.0; kernel[5] = 1.0; + kernel[6] = 0.0; kernel[7] = 1.0; kernel[8] = 0.0; + + vec4 result = u_background_color; + vec4 layer0 = texture2D(u_layer0, v_uvs); + + result = layer0 * layer0.a + result * (1.0 - layer0.a); + + float intersection_count = (texture2D(u_layer2, v_uvs).r * 255.0) / 5.0; + if(mod(intersection_count, 2.0) >= 1.0) + { + result = u_error_color; + } + + vec4 sum = vec4(0.0); + for (int i = 0; i < 9; i++) + { + vec4 color = vec4(texture2D(u_layer1, v_uvs.xy + u_offset[i]).a); + sum += color * (kernel[i] / u_outline_strength); + } + + vec4 layer1 = texture2D(u_layer1, v_uvs); + if((layer1.rgb == x_axis || layer1.rgb == y_axis || layer1.rgb == z_axis)) + { + gl_FragColor = result; + } + else + { + gl_FragColor = mix(result, u_outline_color, abs(sum.a)); + } + + gl_FragColor.a = gl_FragColor.a > 0.5 ? 1.0 : 0.0; + } + +vertex41core = + #version 410 + uniform highp mat4 u_modelViewProjectionMatrix; + in highp vec4 a_vertex; + in highp vec2 a_uvs; + + out highp vec2 v_uvs; + + void main() + { + gl_Position = u_modelViewProjectionMatrix * a_vertex; + v_uvs = a_uvs; + } + +fragment41core = + #version 410 + uniform sampler2D u_layer0; //Default pass. + uniform sampler2D u_layer1; //Selection pass. + uniform sampler2D u_layer2; //X-ray pass. + + uniform vec2 u_offset[9]; + + uniform float u_outline_strength; + uniform vec4 u_outline_color; + uniform vec4 u_error_color; + uniform vec4 u_background_color; + + const vec3 x_axis = vec3(1.0, 0.0, 0.0); + const vec3 y_axis = vec3(0.0, 1.0, 0.0); + const vec3 z_axis = vec3(0.0, 0.0, 1.0); + + in vec2 v_uvs; + out vec4 frag_color; + + float kernel[9]; + + void main() + { + kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; + kernel[3] = 1.0; kernel[4] = -4.0; kernel[5] = 1.0; + kernel[6] = 0.0; kernel[7] = 1.0; kernel[8] = 0.0; + + vec4 result = u_background_color; + vec4 layer0 = texture(u_layer0, v_uvs); + + result = layer0 * layer0.a + result * (1.0 - layer0.a); + + float intersection_count = (texture(u_layer2, v_uvs).r * 255.0) / 5.0; + if(mod(intersection_count, 2.0) >= 1.0) + { + result = u_error_color; + } + + vec4 sum = vec4(0.0); + for (int i = 0; i < 9; i++) + { + vec4 color = vec4(texture(u_layer1, v_uvs.xy + u_offset[i]).a); + sum += color * (kernel[i] / u_outline_strength); + } + + vec4 layer1 = texture(u_layer1, v_uvs); + if((layer1.rgb == x_axis || layer1.rgb == y_axis || layer1.rgb == z_axis)) + { + frag_color = result; + } + else + { + frag_color = mix(result, u_outline_color, abs(sum.a)); + } + + frag_color.a = frag_color.a > 0.5 ? 1.0 : 0.0; + } + +[defaults] +u_layer0 = 0 +u_layer1 = 1 +u_layer2 = 2 +u_background_color = [0.965, 0.965, 0.965, 1.0] +u_outline_strength = 1.0 +u_outline_color = [0.05, 0.66, 0.89, 1.0] +u_error_color = [1.0, 0.0, 0.0, 1.0] + +[bindings] + +[attributes] +a_vertex = vertex +a_uvs = uv + diff --git a/plugins/SolidView/xray_overlay.shader b/plugins/SolidView/xray_overlay.shader new file mode 100755 index 0000000000..ba032b2123 --- /dev/null +++ b/plugins/SolidView/xray_overlay.shader @@ -0,0 +1,50 @@ +[shaders] +vertex = + uniform highp mat4 u_modelViewProjectionMatrix; + + attribute highp vec4 a_vertex; + + void main() + { + gl_Position = u_modelViewProjectionMatrix * a_vertex; + } + +fragment = + uniform lowp vec4 u_xray_error; + + void main() + { + gl_FragColor = u_xray_error; + } + +vertex41core = + #version 410 + uniform highp mat4 u_modelViewProjectionMatrix; + + in highp vec4 a_vertex; + + void main() + { + gl_Position = u_modelViewProjectionMatrix * a_vertex; + } + +fragment41core = + #version 410 + uniform lowp vec4 u_xray_error; + + out vec4 frag_color; + + void main() + { + + frag_color = u_xray_error; + } + +[defaults] +u_xray_error = [1.0, 1.0, 1.0, 1.0] + +[bindings] +u_modelViewProjectionMatrix = model_view_projection_matrix + +[attributes] +a_vertex = vertex diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py index 88a5a441b8..d94835c65e 100644 --- a/plugins/XRayView/XRayView.py +++ b/plugins/XRayView/XRayView.py @@ -8,6 +8,7 @@ from UM.Application import Application from UM.Logger import Logger from UM.Math.Color import Color from UM.PluginRegistry import PluginRegistry +from UM.Resources import Resources from UM.Platform import Platform from UM.Event import Event from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator @@ -19,7 +20,8 @@ from cura.CuraApplication import CuraApplication from cura.CuraView import CuraView from cura.Scene.ConvexHullNode import ConvexHullNode -from . import XRayPass +from cura import XRayPass + ## View used to display a see-through version of objects with errors highlighted. class XRayView(CuraView): @@ -38,7 +40,7 @@ class XRayView(CuraView): renderer = self.getRenderer() if not self._xray_shader: - self._xray_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray.shader")) + self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) self._xray_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("xray").getRgb())) for node in BreadthFirstIterator(scene.getRoot()): diff --git a/plugins/XRayView/xray.shader b/resources/shaders/xray.shader similarity index 100% rename from plugins/XRayView/xray.shader rename to resources/shaders/xray.shader From b515a0f74468983b7c66178fda54b6abe7277983 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 21 Oct 2019 19:30:28 +0200 Subject: [PATCH 03/37] make xray errors exhibit static noise and see-through --- plugins/SolidView/xray_composite.shader | 35 +++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader index e3ac2162a7..9e8d1545a4 100644 --- a/plugins/SolidView/xray_composite.shader +++ b/plugins/SolidView/xray_composite.shader @@ -30,6 +30,7 @@ fragment = uniform vec4 u_outline_color; uniform vec4 u_error_color; uniform vec4 u_background_color; + uniform float u_xray_error_strength; const vec3 x_axis = vec3(1.0, 0.0, 0.0); const vec3 y_axis = vec3(0.0, 1.0, 0.0); @@ -39,6 +40,13 @@ fragment = float kernel[9]; + float hash12(vec2 p) + { + vec2 pp = p * 1234.3; + vec2 p2 = fract(pp) + fract(dot(pp, pp.yx + vec2(12.0,51.0))); + return fract(fract(p2.x * p2.y) * 123.312); + } + void main() { kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; @@ -53,7 +61,14 @@ fragment = float intersection_count = (texture2D(u_layer2, v_uvs).r * 255.0) / 5.0; if(mod(intersection_count, 2.0) >= 1.0) { - result = u_error_color; + if (hash12(v_uvs) > 0.5) + { + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_error_color; + } + else + { + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * (vec4(1.0) - u_error_color); + } } vec4 sum = vec4(0.0); @@ -102,6 +117,7 @@ fragment41core = uniform vec4 u_outline_color; uniform vec4 u_error_color; uniform vec4 u_background_color; + uniform float u_xray_error_strength; const vec3 x_axis = vec3(1.0, 0.0, 0.0); const vec3 y_axis = vec3(0.0, 1.0, 0.0); @@ -112,6 +128,13 @@ fragment41core = float kernel[9]; + float hash12(vec2 p) + { + vec2 pp = p * 1234.3; + vec2 p2 = fract(pp) + fract(dot(pp, pp.yx + vec2(12.0,51.0))); + return fract(fract(p2.x * p2.y) * 123.312); + } + void main() { kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; @@ -126,7 +149,14 @@ fragment41core = float intersection_count = (texture(u_layer2, v_uvs).r * 255.0) / 5.0; if(mod(intersection_count, 2.0) >= 1.0) { - result = u_error_color; + if (hash12(v_uvs) > 0.5) + { + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_error_color; + } + else + { + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * (vec4(1.0) - u_error_color); + } } vec4 sum = vec4(0.0); @@ -157,6 +187,7 @@ u_background_color = [0.965, 0.965, 0.965, 1.0] u_outline_strength = 1.0 u_outline_color = [0.05, 0.66, 0.89, 1.0] u_error_color = [1.0, 0.0, 0.0, 1.0] +u_xray_error_strength = 0.4 [bindings] From 4a8385e3e8b91e0a6443b104b4d6a6320648314f Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 22 Oct 2019 11:27:30 +0200 Subject: [PATCH 04/37] make xray counting color hardcoded value Somewhere between the xray.shader and the xray_composite.shader the colors are stored as unsigned int. Since we want to count the integer number of faces behind a pixel in the red channel, we simply use a color with an r value of 1/255. --- plugins/SolidView/SolidView.py | 1 - plugins/SolidView/xray_composite.shader | 4 ++-- plugins/XRayView/xray_composite.shader | 4 ++-- resources/shaders/xray.shader | 5 ++--- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 565a704b0a..bf8eb67782 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -120,7 +120,6 @@ class SolidView(View): if not self._xray_shader: self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) - self._xray_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("xray").getRgb())) if not self._xray_composite_shader: self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SolidView"), "xray_composite.shader")) diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader index 9e8d1545a4..db661d5540 100644 --- a/plugins/SolidView/xray_composite.shader +++ b/plugins/SolidView/xray_composite.shader @@ -58,7 +58,7 @@ fragment = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = (texture2D(u_layer2, v_uvs).r * 255.0) / 5.0; + float intersection_count = texture2D(u_layer2, v_uvs).r * 255.0; if(mod(intersection_count, 2.0) >= 1.0) { if (hash12(v_uvs) > 0.5) @@ -146,7 +146,7 @@ fragment41core = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = (texture(u_layer2, v_uvs).r * 255.0) / 5.0; + float intersection_count = texture(u_layer2, v_uvs).r * 255.0; if(mod(intersection_count, 2.0) >= 1.0) { if (hash12(v_uvs) > 0.5) diff --git a/plugins/XRayView/xray_composite.shader b/plugins/XRayView/xray_composite.shader index 8bb0f83e9b..8e21bf00c8 100644 --- a/plugins/XRayView/xray_composite.shader +++ b/plugins/XRayView/xray_composite.shader @@ -50,7 +50,7 @@ fragment = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = (texture2D(u_layer2, v_uvs).r * 255.0) / 5.0; + float intersection_count = texture2D(u_layer2, v_uvs).r * 255.0; if(mod(intersection_count, 2.0) >= 1.0) { result = u_error_color; @@ -121,7 +121,7 @@ fragment41core = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = (texture(u_layer2, v_uvs).r * 255.0) / 5.0; + float intersection_count = texture(u_layer2, v_uvs).r * 255.0; if(mod(intersection_count, 2.0) >= 1.0) { result = u_error_color; diff --git a/resources/shaders/xray.shader b/resources/shaders/xray.shader index 45cb16c44c..2f36a6fc0e 100644 --- a/resources/shaders/xray.shader +++ b/resources/shaders/xray.shader @@ -12,7 +12,7 @@ vertex = } fragment = - uniform lowp vec4 u_color; + const lowp vec4 u_color = vec4(1.0 / 255.0, 0.0, 0.0, 1.0); void main() { @@ -34,7 +34,7 @@ vertex41core = fragment41core = #version 410 - uniform lowp vec4 u_color; + const lowp vec4 u_color = vec4(1.0 / 255.0, 0.0, 0.0, 1.0); out vec4 frag_color; @@ -44,7 +44,6 @@ fragment41core = } [defaults] -u_color = [0.02, 0.02, 0.02, 1.0] [bindings] u_modelMatrix = model_matrix From 1b2cc7f7a78ae92ccad0962381b6f013d984c3e0 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 22 Oct 2019 11:37:39 +0200 Subject: [PATCH 05/37] make xray error noise depend on background color --- plugins/SolidView/xray_composite.shader | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader index db661d5540..d5732d3757 100644 --- a/plugins/SolidView/xray_composite.shader +++ b/plugins/SolidView/xray_composite.shader @@ -61,7 +61,8 @@ fragment = float intersection_count = texture2D(u_layer2, v_uvs).r * 255.0; if(mod(intersection_count, 2.0) >= 1.0) { - if (hash12(v_uvs) > 0.5) + float lightness = (result.r + result.g + result.b) / 3.0; + if (hash12(v_uvs) < lightness) { result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_error_color; } @@ -149,7 +150,8 @@ fragment41core = float intersection_count = texture(u_layer2, v_uvs).r * 255.0; if(mod(intersection_count, 2.0) >= 1.0) { - if (hash12(v_uvs) > 0.5) + float lightness = (result.r + result.g + result.b) / 3.0; + if (hash12(v_uvs) < lightness) { result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_error_color; } From 82b2f236896cd77f7b8c233d0ce89399ba44d31e Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 22 Oct 2019 13:46:39 +0200 Subject: [PATCH 06/37] make xray solid color depending on what it occludes --- plugins/SolidView/SolidView.py | 3 ++- plugins/SolidView/xray_composite.shader | 24 ++++++++++++------- .../themes/cura-dark-colorblind/theme.json | 2 ++ resources/themes/cura-dark/theme.json | 2 ++ .../themes/cura-light-colorblind/theme.json | 3 ++- resources/themes/cura-light/theme.json | 2 ++ 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index bf8eb67782..478cf7331b 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -125,7 +125,8 @@ class SolidView(View): self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SolidView"), "xray_composite.shader")) theme = Application.getInstance().getTheme() self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) - self._xray_composite_shader.setUniformValue("u_error_color", Color(*theme.getColor("xray_error").getRgb())) + self._xray_composite_shader.setUniformValue("u_xray_error_dark", Color(*theme.getColor("xray_error_dark").getRgb())) + self._xray_composite_shader.setUniformValue("u_xray_error_light", Color(*theme.getColor("xray_error_light").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) if not self.getRenderer().getRenderPass("xray"): diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader index d5732d3757..75bbbf22ec 100644 --- a/plugins/SolidView/xray_composite.shader +++ b/plugins/SolidView/xray_composite.shader @@ -28,7 +28,8 @@ fragment = uniform float u_outline_strength; uniform vec4 u_outline_color; - uniform vec4 u_error_color; + uniform vec4 u_xray_error_dark; + uniform vec4 u_xray_error_light; uniform vec4 u_background_color; uniform float u_xray_error_strength; @@ -62,13 +63,14 @@ fragment = if(mod(intersection_count, 2.0) >= 1.0) { float lightness = (result.r + result.g + result.b) / 3.0; - if (hash12(v_uvs) < lightness) + //if ( (mod((v_uvs.x / u_offset[8].x - v_uvs.y / u_offset[8].y) * 0.1, 2.0) >= 1.0) == (mod((v_uvs.x / u_offset[8].x + v_uvs.y / u_offset[8].y) * 0.1, 2.0) >= 1.0) ) // diamond pattern + if (lightness > 0.5) { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_error_color; + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_xray_error_dark; } else { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * (vec4(1.0) - u_error_color); + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_xray_error_light; } } @@ -116,7 +118,8 @@ fragment41core = uniform float u_outline_strength; uniform vec4 u_outline_color; - uniform vec4 u_error_color; + uniform vec4 u_xray_error_dark; + uniform vec4 u_xray_error_light; uniform vec4 u_background_color; uniform float u_xray_error_strength; @@ -151,13 +154,14 @@ fragment41core = if(mod(intersection_count, 2.0) >= 1.0) { float lightness = (result.r + result.g + result.b) / 3.0; - if (hash12(v_uvs) < lightness) + //if ( (mod((v_uvs.x / u_offset[8].x - v_uvs.y / u_offset[8].y) * 0.1, 2.0) >= 1.0) == (mod((v_uvs.x / u_offset[8].x + v_uvs.y / u_offset[8].y) * 0.1, 2.0) >= 1.0) ) // diamond pattern + if (lightness > 0.5) { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_error_color; + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_xray_error_dark; } else { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * (vec4(1.0) - u_error_color); + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_xray_error_light; } } @@ -188,7 +192,9 @@ u_layer2 = 2 u_background_color = [0.965, 0.965, 0.965, 1.0] u_outline_strength = 1.0 u_outline_color = [0.05, 0.66, 0.89, 1.0] -u_error_color = [1.0, 0.0, 0.0, 1.0] +u_error_color = [0.0, 0.0, 0.0, 1.0] +u_xray_error_dark = [1.0, 0.0, 0.0, 1.0] +u_xray_error_light = [1.0, 1.0, 0.0, 1.0] u_xray_error_strength = 0.4 [bindings] diff --git a/resources/themes/cura-dark-colorblind/theme.json b/resources/themes/cura-dark-colorblind/theme.json index 9559101d24..c98fb0c815 100644 --- a/resources/themes/cura-dark-colorblind/theme.json +++ b/resources/themes/cura-dark-colorblind/theme.json @@ -12,6 +12,8 @@ "model_overhang": [200, 0, 255, 255], + "xray_error_dark": [255, 0, 0, 255], + "xray_error_light": [255, 255, 0, 255], "xray": [26, 26, 62, 255], "xray_error": [255, 0, 0, 255], diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index 9db024397a..8df336cfec 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -190,6 +190,8 @@ "model_unslicable_alt": [172, 172, 127, 255], "model_selection_outline": [12, 169, 227, 255], + "xray_error_dark": [255, 0, 0, 255], + "xray_error_light": [255, 255, 0, 255], "xray": [26, 26, 62, 255], "xray_error": [255, 0, 0, 255], diff --git a/resources/themes/cura-light-colorblind/theme.json b/resources/themes/cura-light-colorblind/theme.json index 10349acbfd..5628fad880 100644 --- a/resources/themes/cura-light-colorblind/theme.json +++ b/resources/themes/cura-light-colorblind/theme.json @@ -10,9 +10,10 @@ "y_axis": [64, 64, 255, 255], "model_default": [156, 201, 36, 255], "model_overhang": [200, 0, 255, 255], - "model_selection_outline": [12, 169, 227, 255], + "xray_error_dark": [255, 0, 0, 255], + "xray_error_light": [255, 255, 0, 255], "xray": [26, 26, 62, 255], "xray_error": [255, 0, 0, 255], diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 225e0db569..bb7409da39 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -369,6 +369,8 @@ "model_selection_outline": [50, 130, 255, 255], "model_non_printing": [122, 122, 122, 255], + "xray_error_dark": [255, 0, 0, 255], + "xray_error_light": [255, 255, 0, 255], "xray": [26, 26, 62, 255], "xray_error": [255, 0, 0, 255], From 0f184219e6fa3158ae8facf2b93204a5e52ad3b9 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 2 Jan 2020 19:03:36 +0100 Subject: [PATCH 07/37] use tiled image for xray error instead of a uniform color temporarily use the cura logo as placeholder image didn't correctly determine window size yet --- plugins/SolidView/SolidView.py | 18 ++++++++++--- plugins/SolidView/xray_composite.shader | 35 ++++++------------------- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 478cf7331b..8600234173 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -6,7 +6,7 @@ from UM.View.View import View from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Selection import Selection from UM.Resources import Resources -from PyQt5.QtGui import QOpenGLContext +from PyQt5.QtGui import QOpenGLContext, QImage from UM.Application import Application from UM.Logger import Logger @@ -43,6 +43,8 @@ class SolidView(View): self._xray_pass = None self._xray_composite_shader = None self._composite_pass = None + self._xray_error_image = None + self._xray_error_image_size = None self._extruders_model = None self._theme = None @@ -118,6 +120,15 @@ class SolidView(View): self._checkSetup() + if not self._xray_error_image: + self._xray_error_image = OpenGL.getInstance().createTexture() + texture_file = "cura-icon-32.png" #TODO make an img for this! + try: + self._xray_error_image.load(Resources.getPath(Resources.Images, texture_file)) + except FileNotFoundError: + Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) + self._xray_error_image_size = QImage(Resources.getPath(Resources.Images, texture_file)).size() + if not self._xray_shader: self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) @@ -125,9 +136,10 @@ class SolidView(View): self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SolidView"), "xray_composite.shader")) theme = Application.getInstance().getTheme() self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) - self._xray_composite_shader.setUniformValue("u_xray_error_dark", Color(*theme.getColor("xray_error_dark").getRgb())) - self._xray_composite_shader.setUniformValue("u_xray_error_light", Color(*theme.getColor("xray_error_light").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) + self._xray_composite_shader.setTexture(3, self._xray_error_image) + [ww,wh] = [1920,1080] + self._xray_composite_shader.setUniformValue("u_xray_error_img_scaling", [ww / self._xray_error_image_size.width(), wh / self._xray_error_image_size.height()]) if not self.getRenderer().getRenderPass("xray"): # Currently the RenderPass constructor requires a size > 0 diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader index 75bbbf22ec..f24d14f165 100644 --- a/plugins/SolidView/xray_composite.shader +++ b/plugins/SolidView/xray_composite.shader @@ -23,15 +23,15 @@ fragment = uniform sampler2D u_layer0; //Default pass. uniform sampler2D u_layer1; //Selection pass. uniform sampler2D u_layer2; //X-ray pass. + uniform sampler2D u_xray_error; //X-ray error image. uniform vec2 u_offset[9]; uniform float u_outline_strength; uniform vec4 u_outline_color; - uniform vec4 u_xray_error_dark; - uniform vec4 u_xray_error_light; uniform vec4 u_background_color; uniform float u_xray_error_strength; + uniform vec2 u_xray_error_img_scaling; const vec3 x_axis = vec3(1.0, 0.0, 0.0); const vec3 y_axis = vec3(0.0, 1.0, 0.0); @@ -62,16 +62,7 @@ fragment = float intersection_count = texture2D(u_layer2, v_uvs).r * 255.0; if(mod(intersection_count, 2.0) >= 1.0) { - float lightness = (result.r + result.g + result.b) / 3.0; - //if ( (mod((v_uvs.x / u_offset[8].x - v_uvs.y / u_offset[8].y) * 0.1, 2.0) >= 1.0) == (mod((v_uvs.x / u_offset[8].x + v_uvs.y / u_offset[8].y) * 0.1, 2.0) >= 1.0) ) // diamond pattern - if (lightness > 0.5) - { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_xray_error_dark; - } - else - { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_xray_error_light; - } + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * u_xray_error_img_scaling); } vec4 sum = vec4(0.0); @@ -113,15 +104,15 @@ fragment41core = uniform sampler2D u_layer0; //Default pass. uniform sampler2D u_layer1; //Selection pass. uniform sampler2D u_layer2; //X-ray pass. + uniform sampler2D u_xray_error; //X-ray error image. uniform vec2 u_offset[9]; uniform float u_outline_strength; uniform vec4 u_outline_color; - uniform vec4 u_xray_error_dark; - uniform vec4 u_xray_error_light; uniform vec4 u_background_color; uniform float u_xray_error_strength; + uniform vec2 u_xray_error_img_scaling; const vec3 x_axis = vec3(1.0, 0.0, 0.0); const vec3 y_axis = vec3(0.0, 1.0, 0.0); @@ -153,16 +144,7 @@ fragment41core = float intersection_count = texture(u_layer2, v_uvs).r * 255.0; if(mod(intersection_count, 2.0) >= 1.0) { - float lightness = (result.r + result.g + result.b) / 3.0; - //if ( (mod((v_uvs.x / u_offset[8].x - v_uvs.y / u_offset[8].y) * 0.1, 2.0) >= 1.0) == (mod((v_uvs.x / u_offset[8].x + v_uvs.y / u_offset[8].y) * 0.1, 2.0) >= 1.0) ) // diamond pattern - if (lightness > 0.5) - { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_xray_error_dark; - } - else - { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * u_xray_error_light; - } + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * u_xray_error_img_scaling); } vec4 sum = vec4(0.0); @@ -189,13 +171,12 @@ fragment41core = u_layer0 = 0 u_layer1 = 1 u_layer2 = 2 +u_xray_error = 3 u_background_color = [0.965, 0.965, 0.965, 1.0] u_outline_strength = 1.0 u_outline_color = [0.05, 0.66, 0.89, 1.0] -u_error_color = [0.0, 0.0, 0.0, 1.0] -u_xray_error_dark = [1.0, 0.0, 0.0, 1.0] -u_xray_error_light = [1.0, 1.0, 0.0, 1.0] u_xray_error_strength = 0.4 +u_xray_error_img_scaling = [1.0,1.0] [bindings] From 28abf6ff8c4982c5a35a956ff090848b783fcc85 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 2 Jan 2020 19:31:25 +0100 Subject: [PATCH 08/37] fix xray error image scaling --- plugins/SolidView/SolidView.py | 4 ---- plugins/SolidView/xray_composite.shader | 9 ++++----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 8600234173..94aa648197 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -44,7 +44,6 @@ class SolidView(View): self._xray_composite_shader = None self._composite_pass = None self._xray_error_image = None - self._xray_error_image_size = None self._extruders_model = None self._theme = None @@ -127,7 +126,6 @@ class SolidView(View): self._xray_error_image.load(Resources.getPath(Resources.Images, texture_file)) except FileNotFoundError: Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) - self._xray_error_image_size = QImage(Resources.getPath(Resources.Images, texture_file)).size() if not self._xray_shader: self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) @@ -138,8 +136,6 @@ class SolidView(View): self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) self._xray_composite_shader.setTexture(3, self._xray_error_image) - [ww,wh] = [1920,1080] - self._xray_composite_shader.setUniformValue("u_xray_error_img_scaling", [ww / self._xray_error_image_size.width(), wh / self._xray_error_image_size.height()]) if not self.getRenderer().getRenderPass("xray"): # Currently the RenderPass constructor requires a size > 0 diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader index f24d14f165..9a28e05013 100644 --- a/plugins/SolidView/xray_composite.shader +++ b/plugins/SolidView/xray_composite.shader @@ -31,7 +31,6 @@ fragment = uniform vec4 u_outline_color; uniform vec4 u_background_color; uniform float u_xray_error_strength; - uniform vec2 u_xray_error_img_scaling; const vec3 x_axis = vec3(1.0, 0.0, 0.0); const vec3 y_axis = vec3(0.0, 1.0, 0.0); @@ -62,7 +61,8 @@ fragment = float intersection_count = texture2D(u_layer2, v_uvs).r * 255.0; if(mod(intersection_count, 2.0) >= 1.0) { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * u_xray_error_img_scaling); + vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); } vec4 sum = vec4(0.0); @@ -112,7 +112,6 @@ fragment41core = uniform vec4 u_outline_color; uniform vec4 u_background_color; uniform float u_xray_error_strength; - uniform vec2 u_xray_error_img_scaling; const vec3 x_axis = vec3(1.0, 0.0, 0.0); const vec3 y_axis = vec3(0.0, 1.0, 0.0); @@ -144,7 +143,8 @@ fragment41core = float intersection_count = texture(u_layer2, v_uvs).r * 255.0; if(mod(intersection_count, 2.0) >= 1.0) { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * u_xray_error_img_scaling); + vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); } vec4 sum = vec4(0.0); @@ -176,7 +176,6 @@ u_background_color = [0.965, 0.965, 0.965, 1.0] u_outline_strength = 1.0 u_outline_color = [0.05, 0.66, 0.89, 1.0] u_xray_error_strength = 0.4 -u_xray_error_img_scaling = [1.0,1.0] [bindings] From c16f677bf0a7f03e9c1cea597c79581a7bfae96e Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 2 Jan 2020 19:32:09 +0100 Subject: [PATCH 09/37] make a new xray error image includes SVG source file --- plugins/SolidView/SolidView.py | 2 +- resources/images/xray_error.png | Bin 0 -> 1092 bytes resources/images/xray_error.svg | 136 ++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 resources/images/xray_error.png create mode 100644 resources/images/xray_error.svg diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 94aa648197..3770939cc7 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -121,7 +121,7 @@ class SolidView(View): if not self._xray_error_image: self._xray_error_image = OpenGL.getInstance().createTexture() - texture_file = "cura-icon-32.png" #TODO make an img for this! + texture_file = "xray_error.png" try: self._xray_error_image.load(Resources.getPath(Resources.Images, texture_file)) except FileNotFoundError: diff --git a/resources/images/xray_error.png b/resources/images/xray_error.png new file mode 100644 index 0000000000000000000000000000000000000000..3709613a71df753fee58c59ba7f10860206dbf7f GIT binary patch literal 1092 zcmV-K1iSl*P)BD3&+RCR4SE5qnVkSntl3ItJNx%%10g#6&7w7&}wOJ?t|Q1 z0H0M=(e2xG=T6ndivX-v>&n6c>2wWmi{m@!f~8V zr(2ktqr-=Zu{8i=bm)+GVL`9ga~$`;?WWSwkO94Z#p}(^&Ia&BT^-%Lx%zz_z!>%Q z)z#Jl$jr=K7DbAT3=L>%>gwzSkdTn@doV~zNpA%b5}r#^Qc@Ct?yfFsYzzTNPX0}j z;^X51eAC-YSFZe9dJ|xb>g#)ZdH}@6#y*oI+Pn8%z`#IFbu|Es#j>)vNZYo(1JLPK z=I3*AasYf@Q$x3I{U?x{J2yM4)9E;ldpJ5ur%tV@$^wj0aq%OMN2ye5wc4L%X6WeA zw*VYRn}@DTs>%_xPDK&-DRgw11NAh>G5MyD&>Il=ZEg!2M`$< z>GOK&;KB8)=WwiE6%NPx(t!g3Q8X9~00!^fql$_*fbH8~`TgnX=>WcLZl)VIWOi46 zK8Yd;0@>{{)y~f5rX~PsX=#5hEzyo0Yk{j*+pb*$kdl(}LXs#hPUaVaV6j+uo+qzY zrWzCTha{z@rULk?t&Lh+Ujz2-`(9$<{Bt6c*F z0HUIze)jt*E$tuR?%m1@7XW;C(6gZtUJPbx; zFc`vksf8Q{gMkq-GMQ+4dgCi2lhe~=GAU>)CjVN5^Z5OL0)GMJHzjw8bzd|90000< KMNUMnLSTYHe*z2u literal 0 HcmV?d00001 diff --git a/resources/images/xray_error.svg b/resources/images/xray_error.svg new file mode 100644 index 0000000000..fdaed96df9 --- /dev/null +++ b/resources/images/xray_error.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + From 426a4b63f63ca630204368bb53b93539e21f9ff4 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 2 Jan 2020 19:36:56 +0100 Subject: [PATCH 10/37] use less detail in xray error icon --- resources/images/xray_error.png | Bin 1092 -> 789 bytes resources/images/xray_error.svg | 124 ++++++-------------------------- 2 files changed, 23 insertions(+), 101 deletions(-) diff --git a/resources/images/xray_error.png b/resources/images/xray_error.png index 3709613a71df753fee58c59ba7f10860206dbf7f..8bfde4e21e04b8bf197c0475a62f91297f79dd34 100644 GIT binary patch delta 748 zcmVzO-NKx6vuz(&e#ltiAp3WnuOq{MJ@!33276g zJ8`9ju4-2{6QU5zVqyjbKUx&%a^7fApsNU6w2EXxauI|u5Cj<}F-lZs&Ai*<_F!^8 z9CcjuXBKZb=bqm==e~2EXpUFz(p@#o1JDO@pkpQera^&%>3@TqD%EcjYC(x8ky_X+ zJK%;%-w1A&7qAKyCVeB33Ro>8;Ifl`cXxMJSC=W`64+${JTcKlJRZ;5+FCN1^m@HY zM8VUe1Af3+C;ebBsI}Hw2Lb_8#2NU0L_pYyURPI_N~J8zvMg(Rd%M2A-Z1VT1@IA0 zI(IueI~$9|%zx;_VzHT-8FSl}@Zr#aYfk!YZEfjvIur^SKqwT-WHRmT?WTz9MT4k9 z6TS?O0TEzoYRctuWm}a}larGog2+6)EW9c518fMG0!4azdpkQjbA9}Ne@{;jA{y?1 zeIS4ZuK^LS*E=>gRw%oPi3y+2hsYaFn<_qZf-6FXl!g88X7Wf9D%PT z0wVAUP^zJ!VR(4BP;{fw(b1-+CY1UNc`Mxucn=Twd$-YOw6e0YIKb!gg~MS0kx5AI z3%CnE0g;Z5j=sLW;?a%z`}_TVKO(-~u3GhO2DS8m*VXZD;*2CjbE3wCEYUD!gwGCj}Rw+W?ML e1;1$j4d4&?(7T8ymb@nb0000W7u$H&H0DwRf~nVFiJefm_Z)hd&n6c>2wPMiSnaY+ezJOqRT zl$QQ5GQx43PN!R#o1?>riLo^RV|3_{cVR)V*K-{A!0o2e(vShYe#Ps}&dvt#MO_`; zyt(>)9e=;#aIknnpjNJ&X=1ridTOHxu&5`gZm zE^2HH0Z2~%O_Ji{;{klr+e=rj{9AexV2tYPdwY5S#Ky)xlO)=^_g%oiKuvWu0E@-4 zvbadww!H(;=~m|Fb8>P3d|p#Sw{HC>kefRaI9Vx4#)b^fdc_iG#Cs32JhXYii$UY?b~1Z{psoH z0Dr!0Zl)VIWOi46K8Yd;0@>{{)y~f5rX~PsX=#5hEzyo0Yk{j*+pb*$kdl(}LXs#h zPUaVaV6j+uo+qzYrWzCTha{z@rULk?t&Lh+Ujz2-`(9$<{Bt6c*F0HUIze)jt*E$tuR?tk6N3l{)*Mjo;=ZLG%A&9VtkyImp7O{PEM-TYPDKDIWa-``HY5# z3!F}DK@>QhG&~GOWH1=Qc&UXP27`eSF*2EGdV1q4Ba_q9WHKpeD<=P1g!B0Qe-{FO Y0p&L(cZqdhGynhq07*qoM6N<$f)FnIn*aa+ diff --git a/resources/images/xray_error.svg b/resources/images/xray_error.svg index fdaed96df9..bf26eac5da 100644 --- a/resources/images/xray_error.svg +++ b/resources/images/xray_error.svg @@ -1,52 +1,17 @@ - - + version="1.1" + viewBox="0 0 8.4666665 8.4666665" + height="31.999998" + width="31.999998"> - - - @@ -60,77 +25,34 @@ + transform="translate(0,-59.266663)" + id="layer2"> + x="0" + height="8.4666662" + width="8.4666662" + id="rect860" + style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:2.11666656;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99014779" /> + transform="translate(0,-288.53333)" + id="layer1"> + id="path855" + style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99014779" /> - - - + - + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99014779" /> From ffa16727fe3a665ba7558f423bd8851dd4286abd Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 2 Jan 2020 19:46:05 +0100 Subject: [PATCH 11/37] add cross to background of xray error image prevents that small error regions are totally covered by the background and therefore invisible --- resources/images/xray_error.png | Bin 789 -> 906 bytes resources/images/xray_error.svg | 120 +++++++++++++++++++++++++------- 2 files changed, 93 insertions(+), 27 deletions(-) diff --git a/resources/images/xray_error.png b/resources/images/xray_error.png index 8bfde4e21e04b8bf197c0475a62f91297f79dd34..e54eebdd936c70c6b4ab7e00d87c1cd2dec79728 100644 GIT binary patch delta 866 zcmV-o1D*Vp28sueHGcy?Nkl|%vtC%asI6$XPjFNV&|jAb^b z7pEu9kM~Vpi(d}pkmsD|`+a_$L^Nd(;m#d^jSX~#r7^tj>VMKwO6PLgARgD{CO<14 ze|I;R(@K@TSMPX~Vtt)N;&Q58kw~z4^4_j-II(<=quS&;6fG^>{Iv2F2 zP$=yirzm6PhkwK2a5!v&$oNfBqayzSADQGRwYIjly1J^AQX(Pv-B*ztwdof|zEXXC zeT72d;^Lyezh5b(AmOV`>kisa5U}#Mx3`UbXJ^L*5rCJC2hG(Sk83ExXIB3B__*UZ z(P%UpjXI7qHa2F0xCuon-=a#19_fq6HEh`0wzRbD?|<*7(`nNe>2&(=@Guw*nrc6; zBB(56O%kW3^wg9V$-{Lke_>%kYn@7^3_&WD(po2zNfX31_^0x2xlhkw`PO>x=;$~- zJ*_1;J3H&_>@*xHZ$An*{03P&eM?JAp-`yyOj}#q;^Ly2zGe8;W9Hlm?m-?985kIt zo}Ts^*ngRsnZdz9ME-@Z{S*8MPXG}S$!4=kxr+dlQrT=)L=f46AN&v$;jSr;$mHbY z$jFG7cY~p!p^1qJlgzvDrXfKNUI8M(V6fDe^^wVBT3cHY`5C^iPw+R~H#?DJG8u_P z%B{`K%~czNuCA{6`FRt>H}F>#LwQTh+t!RkB7f)S=eiQ*lU!xW=kwj&-KJ&lRr-9t zb0BD+ovp1ceMxL?Zkh+G1%7cQ_}t1L9v&_hi?uEs$BD&au~@7&0)x@fQ4_@NT7u{H z*$D&!ySuxt_m`KKO;%S{R$LG4?d>%+HJJzMSvkS~@TrwQH#g^%1jliDdU|?$dk+o{ zyj#x9&d!=3K7m4s;DMDN3Wbi2j=V1W!SV5NdwaVH;ychFf5OLbVt>uA3|hBqy$^vG saALo@N&+~67v|%J{YQ1R>js>_TW0?LV5r$!fdBvi07*qoM6N<$g2v6R&;S4c delta 748 zcmVzO-NKx6vuz(&e#ltiAp3WnuOq{MJ@!33276g zJ8`9ju4-2{6QU5zVqyjbKUx&%a^7fApsNU6w2EXxauI|u5Cj<}F-lZs&Ai*<_F!^8 z9CcjuXBKZb=bqm==e~2EXpUFz(p@#o1JDO@pkpQera^&%>3@TqD%EcjYC(x8ky_X+ zJK%;%-w1A&7qAKyCVeB33Ro>8;Ifl`cXxMJSC=W`64+${JTcKlJRZ;5+FCN1^m@HY zM8VUe1Af3+C;ebBsI}Hw2Lb_8#2NU0L_pYyURPI_N~J8zvMg(Rd%M2A-Z1VT1@IA0 zI(IueI~$9|%zx;_VzHT-8FSl}@Zr#aYfk!YZEfjvIur^SKqwT-WHRmT?WTz9MT4k9 z6TS?O0TEzoYRctuWm}a}larGog2+6)EW9c518fMG0!4azdpkQjbA9}Ne@{;jA{y?1 zeIS4ZuK^LS*E=>gRw%oPi3y+2hsYaFn<_qZf-6FXl!g88X7Wf9D%PT z0wVAUP^zJ!VR(4BP;{fw(b1-+CY1UNc`Mxucn=Twd$-YOw6e0YIKb!gg~MS0kx5AI z3%CnE0g;Z5j=sLW;?a%z`}_TVKO(-~u3GhO2DS8m*VXZD;*2CjbE3wCEYUD!gwGCj}Rw+W?ML e1;1$j4d4&?(7T8ymb@nb0000 + + + viewBox="0 0 8.4666665 8.4666665" + version="1.1" + id="svg8" + inkscape:version="0.92.3 (2405546, 2018-03-11)" + sodipodi:docname="xray_error.svg"> + + + @@ -25,34 +60,65 @@ + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Layer 2" + transform="translate(0,-59.266663)"> + width="8.4666662" + height="8.4666662" + x="0" + y="59.266663" + ry="1.7101378e-07" /> + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-288.53333)"> + + + + + + id="path1155" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374993;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 1.5875,289.0625 -3.1749998,3.175 m 0,-3.175 3.1749998,3.175" + inkscape:connector-curvature="0" /> - + inkscape:connector-curvature="0" + d="m 10.054167,289.0625 -3.1750001,3.175 m 0,-3.175 3.1750001,3.175" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374993;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path1158" /> From 01643f5feef430f04b6867e5633c0ad484a4fa0a Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 3 Jan 2020 17:18:29 +0100 Subject: [PATCH 12/37] remove outdated unused shader functions --- plugins/SolidView/xray_composite.shader | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader index 9a28e05013..634dd33f70 100644 --- a/plugins/SolidView/xray_composite.shader +++ b/plugins/SolidView/xray_composite.shader @@ -40,13 +40,6 @@ fragment = float kernel[9]; - float hash12(vec2 p) - { - vec2 pp = p * 1234.3; - vec2 p2 = fract(pp) + fract(dot(pp, pp.yx + vec2(12.0,51.0))); - return fract(fract(p2.x * p2.y) * 123.312); - } - void main() { kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; @@ -122,13 +115,6 @@ fragment41core = float kernel[9]; - float hash12(vec2 p) - { - vec2 pp = p * 1234.3; - vec2 p2 = fract(pp) + fract(dot(pp, pp.yx + vec2(12.0,51.0))); - return fract(fract(p2.x * p2.y) * 123.312); - } - void main() { kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; From b4c3703dc44c923ae05ee9236e0a3d0c1fd7219c Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 26 Feb 2020 17:56:22 +0100 Subject: [PATCH 13/37] Check xray overlay for badness in model every 1.0 second --- plugins/SolidView/SolidView.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 3770939cc7..ec8167aeeb 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -8,6 +8,9 @@ from UM.Scene.Selection import Selection from UM.Resources import Resources from PyQt5.QtGui import QOpenGLContext, QImage +import numpy as np +import time + from UM.Application import Application from UM.Logger import Logger from UM.Math.Color import Color @@ -54,6 +57,9 @@ class SolidView(View): self._old_composite_shader = None self._old_layer_bindings = None + self._last_xray_checking_time = time.time() + self._xray_checking_update_time = 1.0 # seconds + Application.getInstance().engineCreatedSignal.connect(self._onGlobalContainerChanged) def _onGlobalContainerChanged(self) -> None: @@ -228,9 +234,21 @@ class SolidView(View): if node.callDecoration("isGroup") and Selection.isSelected(node): renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(), mode = RenderBatch.RenderMode.LineLoop) - def endRendering(self): - pass + # check whether the xray overlay is showing badness + if time.time() > self._last_xray_checking_time + self._xray_checking_update_time: + self._last_xray_checking_time = time.time() + xray_img = self._xray_pass.getOutput() + xray_img = xray_img.convertToFormat(QImage.Format.Format_RGB888) + + ptr = xray_img.bits() + ptr.setsize(xray_img.byteCount()) + reds = np.array(ptr).reshape(xray_img.height(), xray_img.width(), 3)[:,:,0] # Copies the data + + bad_pixel_count = np.sum(np.mod(reds, 2)) + + if bad_pixel_count > 0: + Logger.log("d", "Super bad xray, man! : %d" % bad_pixel_count) def event(self, event): if event.type == Event.ViewActivateEvent: From 643b27e1606d80f5246233d34d27c64970d57d54 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 26 Feb 2020 19:21:43 +0100 Subject: [PATCH 14/37] add xray error warning message --- plugins/SolidView/SolidView.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index ec8167aeeb..40877bf477 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -13,6 +13,7 @@ import time from UM.Application import Application from UM.Logger import Logger +from UM.Message import Message from UM.Math.Color import Color from UM.PluginRegistry import PluginRegistry from UM.Platform import Platform @@ -21,6 +22,8 @@ from UM.Event import Event from UM.View.RenderBatch import RenderBatch from UM.View.GL.OpenGL import OpenGL +from UM.i18n import i18nCatalog + from cura.CuraApplication import CuraApplication from cura.Settings.ExtruderManager import ExtruderManager @@ -29,9 +32,13 @@ from cura import XRayPass import math +catalog = i18nCatalog("cura") + ## Standard view for mesh models. class SolidView(View): + _show_xray_warning_preference = "view/show_xray_warning" + def __init__(self): super().__init__() application = Application.getInstance() @@ -57,8 +64,15 @@ class SolidView(View): self._old_composite_shader = None self._old_layer_bindings = None - self._last_xray_checking_time = time.time() + self._next_xray_checking_time = time.time() self._xray_checking_update_time = 1.0 # seconds + self._xray_warning_cooldown = 1 # reshow Model error message every 10 minutes + self._xray_warning_message = Message(catalog.i18nc("@info:status", "Your model is not manifold. The highlighted areas indicate either missing or extraneous surfaces.") + , lifetime = 60 * 5 # leave message for 5 minutes + , title = catalog.i18nc("@info:title", "Model errors"), + option_text = catalog.i18nc("@info:option_text", "Do not show this message again"), option_state = False) + self._xray_warning_message.optionToggled.connect(self._onDontAskMeAgain) + CuraApplication.getInstance().getPreferences().addPreference(self._show_xray_warning_preference, True) Application.getInstance().engineCreatedSignal.connect(self._onGlobalContainerChanged) @@ -236,19 +250,24 @@ class SolidView(View): def endRendering(self): # check whether the xray overlay is showing badness - if time.time() > self._last_xray_checking_time + self._xray_checking_update_time: - self._last_xray_checking_time = time.time() + if time.time() > self._next_xray_checking_time\ + and CuraApplication.getInstance().getPreferences().getValue(self._show_xray_warning_preference): + self._next_xray_checking_time = time.time() + self._xray_checking_update_time + xray_img = self._xray_pass.getOutput() xray_img = xray_img.convertToFormat(QImage.Format.Format_RGB888) - ptr = xray_img.bits() ptr.setsize(xray_img.byteCount()) reds = np.array(ptr).reshape(xray_img.height(), xray_img.width(), 3)[:,:,0] # Copies the data + bad_pixel_count = np.sum(np.mod(reds, 2)) # check number of pixels with an odd intersection count - bad_pixel_count = np.sum(np.mod(reds, 2)) + if bad_pixel_count > 10: # allow for 10 pixels to be erroneously marked as problematic + self._next_xray_checking_time = time.time() + self._xray_warning_cooldown + self._xray_warning_message.show() + Logger.log("i", "Xray overlay found %d non-manifold pixels." % bad_pixel_count) - if bad_pixel_count > 0: - Logger.log("d", "Super bad xray, man! : %d" % bad_pixel_count) + def _onDontAskMeAgain(self, checked: bool) -> None: + CuraApplication.getInstance().getPreferences().setValue(self._show_xray_warning_preference, not checked) def event(self, event): if event.type == Event.ViewActivateEvent: @@ -274,3 +293,4 @@ class SolidView(View): self.getRenderer().removeRenderPass(self._xray_pass) self._composite_pass.setLayerBindings(self._old_layer_bindings) self._composite_pass.setCompositeShader(self._old_composite_shader) + self._xray_warning_message.hide() From 4b1a426873a61cfc057214fb522d17e97a614ab4 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 26 Feb 2020 19:21:55 +0100 Subject: [PATCH 15/37] add xray error warning preference --- resources/qml/Preferences/GeneralPage.qml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index e3e5062049..69f46a3e3a 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -86,6 +86,8 @@ UM.PreferencesPage prefixJobNameCheckbox.checked = boolCheck(UM.Preferences.getValue("cura/jobname_prefix")) UM.Preferences.resetPreference("view/show_overhang"); showOverhangCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_overhang")) + UM.Preferences.resetPreference("view/show_xray_error"); + showXrayErrorCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_xray_error")) UM.Preferences.resetPreference("view/center_on_select"); centerOnSelectCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select")) UM.Preferences.resetPreference("view/invert_zoom"); @@ -336,6 +338,25 @@ UM.PreferencesPage } } + + UM.TooltipArea + { + width: childrenRect.width; + height: childrenRect.height; + + text: catalog.i18nc("@info:tooltip", "Highlight missing or extraneous surfaces of the model using warning signs. The toolpaths will often be missing parts of the intended geometry.") + + CheckBox + { + id: showXrayErrorCheckbox + + checked: boolCheck(UM.Preferences.getValue("view/show_xray_warning")) + onClicked: UM.Preferences.setValue("view/show_xray_warning", checked) + + text: catalog.i18nc("@option:check", "Display model errors"); + } + } + UM.TooltipArea { width: childrenRect.width; From 0e633a0dfaa202e4b95720d99428a5f4c790301a Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 27 Feb 2020 08:46:52 +0100 Subject: [PATCH 16/37] allow immediate change of preference for showing xray errors in solid view --- plugins/SolidView/SolidView.py | 72 ++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 40877bf477..82a66cd66b 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -139,38 +139,49 @@ class SolidView(View): self._checkSetup() - if not self._xray_error_image: - self._xray_error_image = OpenGL.getInstance().createTexture() - texture_file = "xray_error.png" - try: - self._xray_error_image.load(Resources.getPath(Resources.Images, texture_file)) - except FileNotFoundError: - Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) + if not CuraApplication.getInstance().getPreferences().getValue(self._show_xray_warning_preference): + self._xray_error_image = None + self._xray_shader = None + self._xray_composite_shader = None + if self._composite_pass and 'xray' in self._composite_pass.getLayerBindings(): + self._composite_pass.setLayerBindings(self._old_layer_bindings) + self._composite_pass.setCompositeShader(self._old_composite_shader) + self._old_layer_bindings = None + self._old_composite_shader = None + self._xray_warning_message.hide() + else: + if not self._xray_error_image: + self._xray_error_image = OpenGL.getInstance().createTexture() + texture_file = "xray_error.png" + try: + self._xray_error_image.load(Resources.getPath(Resources.Images, texture_file)) + except FileNotFoundError: + Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) - if not self._xray_shader: - self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) + if not self._xray_shader: + self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) - if not self._xray_composite_shader: - self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SolidView"), "xray_composite.shader")) - theme = Application.getInstance().getTheme() - self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) - self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) - self._xray_composite_shader.setTexture(3, self._xray_error_image) + if not self._xray_composite_shader: + self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SolidView"), "xray_composite.shader")) + theme = Application.getInstance().getTheme() + self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) + self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) + self._xray_composite_shader.setTexture(3, self._xray_error_image) - if not self.getRenderer().getRenderPass("xray"): - # Currently the RenderPass constructor requires a size > 0 - # This should be fixed in RenderPass's constructor. - self._xray_pass = XRayPass.XRayPass(1, 1) + if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings(): + # Currently the RenderPass constructor requires a size > 0 + # This should be fixed in RenderPass's constructor. + self._xray_pass = XRayPass.XRayPass(1, 1) - self.getRenderer().addRenderPass(self._xray_pass) + self.getRenderer().addRenderPass(self._xray_pass) - if not self._composite_pass: - self._composite_pass = self.getRenderer().getRenderPass("composite") + if not self._composite_pass: + self._composite_pass = self.getRenderer().getRenderPass("composite") - self._old_layer_bindings = self._composite_pass.getLayerBindings() - self._composite_pass.setLayerBindings(["default", "selection", "xray"]) - self._old_composite_shader = self._composite_pass.getCompositeShader() - self._composite_pass.setCompositeShader(self._xray_composite_shader) + self._old_layer_bindings = self._composite_pass.getLayerBindings() + self._composite_pass.setLayerBindings(["default", "selection", "xray"]) + self._old_composite_shader = self._composite_pass.getCompositeShader() + self._composite_pass.setCompositeShader(self._xray_composite_shader) global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: @@ -290,7 +301,8 @@ class SolidView(View): if event.type == Event.ViewDeactivateEvent: - self.getRenderer().removeRenderPass(self._xray_pass) - self._composite_pass.setLayerBindings(self._old_layer_bindings) - self._composite_pass.setCompositeShader(self._old_composite_shader) - self._xray_warning_message.hide() + if self._composite_pass and 'xray' in self._composite_pass.getLayerBindings(): + self.getRenderer().removeRenderPass(self._xray_pass) + self._composite_pass.setLayerBindings(self._old_layer_bindings) + self._composite_pass.setCompositeShader(self._old_composite_shader) + self._xray_warning_message.hide() From b51b6997155b7d074e0e8112b3afedac13ba5d94 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 27 Feb 2020 18:17:07 +0100 Subject: [PATCH 17/37] fix old xray view I don't understand why it only seems to work if I define u_color via [default] andd why it doesn't work when I set it inside the shader itself. --- plugins/SolidView/xray_composite.shader | 10 ++++++---- plugins/XRayView/xray_composite.shader | 10 ++++++---- resources/shaders/xray.shader | 6 ++++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader index 634dd33f70..55e2167308 100644 --- a/plugins/SolidView/xray_composite.shader +++ b/plugins/SolidView/xray_composite.shader @@ -51,8 +51,9 @@ fragment = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = texture2D(u_layer2, v_uvs).r * 255.0; - if(mod(intersection_count, 2.0) >= 1.0) + float intersection_count = texture2D(u_layer2, v_uvs).r * 50; // 1 / .02 + float rest = mod(intersection_count, 2.0); + if (rest > 0.5 && rest < 1.5) { vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); @@ -126,8 +127,9 @@ fragment41core = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = texture(u_layer2, v_uvs).r * 255.0; - if(mod(intersection_count, 2.0) >= 1.0) + float intersection_count = texture(u_layer2, v_uvs).r * 50; // 1 / .02 + float rest = mod(intersection_count, 2.0); + if (rest > 0.5 && rest < 1.5) { vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); diff --git a/plugins/XRayView/xray_composite.shader b/plugins/XRayView/xray_composite.shader index 8e21bf00c8..51e1cf326f 100644 --- a/plugins/XRayView/xray_composite.shader +++ b/plugins/XRayView/xray_composite.shader @@ -50,8 +50,9 @@ fragment = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = texture2D(u_layer2, v_uvs).r * 255.0; - if(mod(intersection_count, 2.0) >= 1.0) + float intersection_count = texture2D(u_layer2, v_uvs).r * 50; // 1 / .02 + float rest = mod(intersection_count, 2.0); + if (rest > 0.5 && rest < 1.5) { result = u_error_color; } @@ -121,8 +122,9 @@ fragment41core = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = texture(u_layer2, v_uvs).r * 255.0; - if(mod(intersection_count, 2.0) >= 1.0) + float intersection_count = texture(u_layer2, v_uvs).r * 50; // 1 / .02 + float rest = mod(intersection_count, 2.0); + if (rest > 0.5 && rest < 1.5) { result = u_error_color; } diff --git a/resources/shaders/xray.shader b/resources/shaders/xray.shader index 2f36a6fc0e..c375d4300c 100644 --- a/resources/shaders/xray.shader +++ b/resources/shaders/xray.shader @@ -12,7 +12,7 @@ vertex = } fragment = - const lowp vec4 u_color = vec4(1.0 / 255.0, 0.0, 0.0, 1.0); + uniform vec4 u_color; void main() { @@ -34,7 +34,8 @@ vertex41core = fragment41core = #version 410 - const lowp vec4 u_color = vec4(1.0 / 255.0, 0.0, 0.0, 1.0); + + uniform vec4 u_color; out vec4 frag_color; @@ -44,6 +45,7 @@ fragment41core = } [defaults] +u_color = [0.02, 0.02, 0.02, 1.0] [bindings] u_modelMatrix = model_matrix From 5d90fd31d9828ab430b70cb3183b534b34c50d17 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 27 Feb 2020 18:42:27 +0100 Subject: [PATCH 18/37] fix xray for high intersection count models I don't understand why, but any deviation from this produces worse results --- plugins/SolidView/xray_composite.shader | 12 ++++++------ plugins/XRayView/xray_composite.shader | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader index 55e2167308..c67e3392f3 100644 --- a/plugins/SolidView/xray_composite.shader +++ b/plugins/SolidView/xray_composite.shader @@ -51,9 +51,9 @@ fragment = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = texture2D(u_layer2, v_uvs).r * 50; // 1 / .02 - float rest = mod(intersection_count, 2.0); - if (rest > 0.5 && rest < 1.5) + float intersection_count = texture2D(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) + float rest = mod(intersection_count + .01, 2.0); + if (rest > 1.0 && rest < 1.5) { vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); @@ -127,9 +127,9 @@ fragment41core = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = texture(u_layer2, v_uvs).r * 50; // 1 / .02 - float rest = mod(intersection_count, 2.0); - if (rest > 0.5 && rest < 1.5) + float intersection_count = texture(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) + float rest = mod(intersection_count + .01, 2.0); + if (rest > 1.0 && rest < 1.5) { vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); diff --git a/plugins/XRayView/xray_composite.shader b/plugins/XRayView/xray_composite.shader index 51e1cf326f..41b02a54a5 100644 --- a/plugins/XRayView/xray_composite.shader +++ b/plugins/XRayView/xray_composite.shader @@ -50,9 +50,9 @@ fragment = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = texture2D(u_layer2, v_uvs).r * 50; // 1 / .02 - float rest = mod(intersection_count, 2.0); - if (rest > 0.5 && rest < 1.5) + float intersection_count = texture2D(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) + float rest = mod(intersection_count + .01, 2.0); + if (rest > 1.0 && rest < 1.5) { result = u_error_color; } @@ -122,9 +122,9 @@ fragment41core = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = texture(u_layer2, v_uvs).r * 50; // 1 / .02 - float rest = mod(intersection_count, 2.0); - if (rest > 0.5 && rest < 1.5) + float intersection_count = texture(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) + float rest = mod(intersection_count + .01, 2.0); + if (rest > 1.0 && rest < 1.5) { result = u_error_color; } From 890b6dc0b4243d41892c676e82b63ba18cc2256c Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 27 Feb 2020 20:03:35 +0100 Subject: [PATCH 19/37] prevent false negative xray error for high overlap count --- plugins/SolidView/xray_composite.shader | 4 ++-- plugins/XRayView/xray_composite.shader | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/SolidView/xray_composite.shader b/plugins/SolidView/xray_composite.shader index c67e3392f3..6eccc2d4e5 100644 --- a/plugins/SolidView/xray_composite.shader +++ b/plugins/SolidView/xray_composite.shader @@ -53,7 +53,7 @@ fragment = float intersection_count = texture2D(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) float rest = mod(intersection_count + .01, 2.0); - if (rest > 1.0 && rest < 1.5) + if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); @@ -129,7 +129,7 @@ fragment41core = float intersection_count = texture(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) float rest = mod(intersection_count + .01, 2.0); - if (rest > 1.0 && rest < 1.5) + if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); diff --git a/plugins/XRayView/xray_composite.shader b/plugins/XRayView/xray_composite.shader index 41b02a54a5..d8c90a5259 100644 --- a/plugins/XRayView/xray_composite.shader +++ b/plugins/XRayView/xray_composite.shader @@ -52,7 +52,7 @@ fragment = float intersection_count = texture2D(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) float rest = mod(intersection_count + .01, 2.0); - if (rest > 1.0 && rest < 1.5) + if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { result = u_error_color; } @@ -124,7 +124,7 @@ fragment41core = float intersection_count = texture(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) float rest = mod(intersection_count + .01, 2.0); - if (rest > 1.0 && rest < 1.5) + if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { result = u_error_color; } From 42a1b02d4cf45b7c83929db46a7cddb844b816f1 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 27 Feb 2020 20:29:58 +0100 Subject: [PATCH 20/37] use transparency in xray view and merge shader duplication --- plugins/SolidView/SolidView.py | 2 +- plugins/XRayView/XRayView.py | 16 +- plugins/XRayView/xray_composite.shader | 164 ------------------ .../shaders}/xray_composite.shader | 0 4 files changed, 13 insertions(+), 169 deletions(-) delete mode 100644 plugins/XRayView/xray_composite.shader rename {plugins/SolidView => resources/shaders}/xray_composite.shader (100%) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 82a66cd66b..52e0cf936f 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -162,7 +162,7 @@ class SolidView(View): self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) if not self._xray_composite_shader: - self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SolidView"), "xray_composite.shader")) + self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray_composite.shader")) theme = Application.getInstance().getTheme() self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py index d94835c65e..29fcfbca53 100644 --- a/plugins/XRayView/XRayView.py +++ b/plugins/XRayView/XRayView.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import os.path -from PyQt5.QtGui import QOpenGLContext +from PyQt5.QtGui import QOpenGLContext, QImage from UM.Application import Application from UM.Logger import Logger @@ -34,6 +34,7 @@ class XRayView(CuraView): self._composite_pass = None self._old_composite_shader = None self._old_layer_bindings = None + self._xray_error_image = None def beginRendering(self): scene = self.getController().getScene() @@ -88,12 +89,19 @@ class XRayView(CuraView): self.getRenderer().addRenderPass(self._xray_pass) - if not self._xray_composite_shader: - self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray_composite.shader")) + if not self._xray_error_image: + self._xray_error_image = OpenGL.getInstance().createTexture() + img = QImage(1, 1, QImage.Format_RGB888) theme = Application.getInstance().getTheme() + img.setPixelColor(0, 0, theme.getColor("xray_error")) + self._xray_error_image.setImage(img) + + if not self._xray_composite_shader: + self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray_composite.shader")) self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) - self._xray_composite_shader.setUniformValue("u_error_color", Color(*theme.getColor("xray_error").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) + self._xray_composite_shader.setUniformValue("u_xray_error_strength", 0.8) + self._xray_composite_shader.setTexture(3, self._xray_error_image) if not self._composite_pass: self._composite_pass = self.getRenderer().getRenderPass("composite") diff --git a/plugins/XRayView/xray_composite.shader b/plugins/XRayView/xray_composite.shader deleted file mode 100644 index d8c90a5259..0000000000 --- a/plugins/XRayView/xray_composite.shader +++ /dev/null @@ -1,164 +0,0 @@ -[shaders] -vertex = - uniform highp mat4 u_modelViewProjectionMatrix; - attribute highp vec4 a_vertex; - attribute highp vec2 a_uvs; - - varying highp vec2 v_uvs; - - void main() - { - gl_Position = u_modelViewProjectionMatrix * a_vertex; - v_uvs = a_uvs; - } - -fragment = - #ifdef GL_ES - #ifdef GL_FRAGMENT_PRECISION_HIGH - precision highp float; - #else - precision mediump float; - #endif // GL_FRAGMENT_PRECISION_HIGH - #endif // GL_ES - uniform sampler2D u_layer0; //Default pass. - uniform sampler2D u_layer1; //Selection pass. - uniform sampler2D u_layer2; //X-ray pass. - - uniform vec2 u_offset[9]; - - uniform float u_outline_strength; - uniform vec4 u_outline_color; - uniform vec4 u_error_color; - uniform vec4 u_background_color; - - const vec3 x_axis = vec3(1.0, 0.0, 0.0); - const vec3 y_axis = vec3(0.0, 1.0, 0.0); - const vec3 z_axis = vec3(0.0, 0.0, 1.0); - - varying vec2 v_uvs; - - float kernel[9]; - - void main() - { - kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; - kernel[3] = 1.0; kernel[4] = -4.0; kernel[5] = 1.0; - kernel[6] = 0.0; kernel[7] = 1.0; kernel[8] = 0.0; - - vec4 result = u_background_color; - vec4 layer0 = texture2D(u_layer0, v_uvs); - - result = layer0 * layer0.a + result * (1.0 - layer0.a); - - float intersection_count = texture2D(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) - float rest = mod(intersection_count + .01, 2.0); - if (rest > 1.0 && rest < 1.5 && intersection_count < 49) - { - result = u_error_color; - } - - vec4 sum = vec4(0.0); - for (int i = 0; i < 9; i++) - { - vec4 color = vec4(texture2D(u_layer1, v_uvs.xy + u_offset[i]).a); - sum += color * (kernel[i] / u_outline_strength); - } - - vec4 layer1 = texture2D(u_layer1, v_uvs); - if((layer1.rgb == x_axis || layer1.rgb == y_axis || layer1.rgb == z_axis)) - { - gl_FragColor = result; - } - else - { - gl_FragColor = mix(result, vec4(abs(sum.a)) * u_outline_color, abs(sum.a)); - } - } - -vertex41core = - #version 410 - uniform highp mat4 u_modelViewProjectionMatrix; - in highp vec4 a_vertex; - in highp vec2 a_uvs; - - out highp vec2 v_uvs; - - void main() - { - gl_Position = u_modelViewProjectionMatrix * a_vertex; - v_uvs = a_uvs; - } - -fragment41core = - #version 410 - uniform sampler2D u_layer0; //Default pass. - uniform sampler2D u_layer1; //Selection pass. - uniform sampler2D u_layer2; //X-ray pass. - - uniform vec2 u_offset[9]; - - uniform float u_outline_strength; - uniform vec4 u_outline_color; - uniform vec4 u_error_color; - uniform vec4 u_background_color; - - const vec3 x_axis = vec3(1.0, 0.0, 0.0); - const vec3 y_axis = vec3(0.0, 1.0, 0.0); - const vec3 z_axis = vec3(0.0, 0.0, 1.0); - - in vec2 v_uvs; - out vec4 frag_color; - - float kernel[9]; - - void main() - { - kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; - kernel[3] = 1.0; kernel[4] = -4.0; kernel[5] = 1.0; - kernel[6] = 0.0; kernel[7] = 1.0; kernel[8] = 0.0; - - vec4 result = u_background_color; - vec4 layer0 = texture(u_layer0, v_uvs); - - result = layer0 * layer0.a + result * (1.0 - layer0.a); - - float intersection_count = texture(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) - float rest = mod(intersection_count + .01, 2.0); - if (rest > 1.0 && rest < 1.5 && intersection_count < 49) - { - result = u_error_color; - } - - vec4 sum = vec4(0.0); - for (int i = 0; i < 9; i++) - { - vec4 color = vec4(texture(u_layer1, v_uvs.xy + u_offset[i]).a); - sum += color * (kernel[i] / u_outline_strength); - } - - vec4 layer1 = texture(u_layer1, v_uvs); - if((layer1.rgb == x_axis || layer1.rgb == y_axis || layer1.rgb == z_axis)) - { - frag_color = result; - } - else - { - frag_color = mix(result, vec4(abs(sum.a)) * u_outline_color, abs(sum.a)); - } - } - -[defaults] -u_layer0 = 0 -u_layer1 = 1 -u_layer2 = 2 -u_background_color = [0.965, 0.965, 0.965, 1.0] -u_outline_strength = 1.0 -u_outline_color = [0.05, 0.66, 0.89, 1.0] -u_error_color = [1.0, 0.0, 0.0, 1.0] - -[bindings] - -[attributes] -a_vertex = vertex -a_uvs = uv - diff --git a/plugins/SolidView/xray_composite.shader b/resources/shaders/xray_composite.shader similarity index 100% rename from plugins/SolidView/xray_composite.shader rename to resources/shaders/xray_composite.shader From 3919b1292e40db992f1387e7d0436f3ee9b6b11d Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 27 Feb 2020 20:39:19 +0100 Subject: [PATCH 21/37] fix cooldown for xray warning --- plugins/SolidView/SolidView.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 52e0cf936f..f0d1d75690 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -66,7 +66,7 @@ class SolidView(View): self._next_xray_checking_time = time.time() self._xray_checking_update_time = 1.0 # seconds - self._xray_warning_cooldown = 1 # reshow Model error message every 10 minutes + self._xray_warning_cooldown = 60 * 10 # reshow Model error message every 10 minutes self._xray_warning_message = Message(catalog.i18nc("@info:status", "Your model is not manifold. The highlighted areas indicate either missing or extraneous surfaces.") , lifetime = 60 * 5 # leave message for 5 minutes , title = catalog.i18nc("@info:title", "Model errors"), From a4fbf3c613bfe8f91b1bb63b472e2f9ff22b69bb Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 25 Mar 2020 15:13:33 +0100 Subject: [PATCH 22/37] Move X-ray set-up code into _checkSetup That's what that function is meant for. It's executing essentially the same, since before it was executed right after the call to _checkSetup() and now it's at the end inside that function. Contributes to issue CURA-7262. --- plugins/SolidView/SolidView.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index f0d1d75690..65ae03d140 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -133,12 +133,6 @@ class SolidView(View): self._support_mesh_shader.setUniformValue("u_vertical_stripes", True) self._support_mesh_shader.setUniformValue("u_width", 5.0) - def beginRendering(self): - scene = self.getController().getScene() - renderer = self.getRenderer() - - self._checkSetup() - if not CuraApplication.getInstance().getPreferences().getValue(self._show_xray_warning_preference): self._xray_error_image = None self._xray_shader = None @@ -183,6 +177,12 @@ class SolidView(View): self._old_composite_shader = self._composite_pass.getCompositeShader() self._composite_pass.setCompositeShader(self._xray_composite_shader) + def beginRendering(self): + scene = self.getController().getScene() + renderer = self.getRenderer() + + self._checkSetup() + global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: if Application.getInstance().getPreferences().getValue("view/show_overhang"): From 4c770587e2d9d7c8a10fe6e6c828c7d58803dfb2 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 25 Mar 2020 18:00:14 +0100 Subject: [PATCH 23/37] Fix getting additional bytes from QImage QImage's bytes are aligned to memory words per column of pixels. That means that one of these columns contains 99% valid image data, but with several bytes of unassigned noise at the end. How many of these padding bytes there are would depend on the image size, i.e. Cura's window size. In the end, the total number of bytes in the image ends up slightly more than w*h*3. As a result, Cura would crash because it couldn't reshape the image. Reshaping was completely unnecessary anyway, but this random noise was giving false positives also. But how do you then get only the actual pixels from each column of data? We can't just go iterating over this array, as that would be an iteration of thousands of columns which is prohibitively slow in Python. No, we're going to do some Numpy magic. We're going to create a class that pretends to be a Numpy array. Give this class some data and say that this data has a certain pixel size but also a certain STRIDE LENGTH. This stride length can be the length of the actual pixel data. As a result when Numpy sees this object it will read out the data using these strides, all done efficiently within the C code of Numpy. Framerate is fantastic on my computer. No problems at all. Pretty powerful computer though. But also a big 5k screen. Still no problem for Numpy. Seems to be decently efficient. Took me quite a while to figure all of this out. Contributes to issue CURA-7262. --- plugins/SolidView/SolidView.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 65ae03d140..6acd72e615 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -267,10 +267,31 @@ class SolidView(View): xray_img = self._xray_pass.getOutput() xray_img = xray_img.convertToFormat(QImage.Format.Format_RGB888) - ptr = xray_img.bits() - ptr.setsize(xray_img.byteCount()) - reds = np.array(ptr).reshape(xray_img.height(), xray_img.width(), 3)[:,:,0] # Copies the data - bad_pixel_count = np.sum(np.mod(reds, 2)) # check number of pixels with an odd intersection count + + # We can't just read the image since the pixels are aligned to internal memory positions. + # xray_img.byteCount() != xray_img.width() * xray_img.height() * 3 + # The byte count is a little higher sometimes. We need to check the data per line, but fast using Numpy. + # See https://stackoverflow.com/questions/5810970/get-raw-data-from-qimage for a description of the problem. + # We can't use that solution though, since it doesn't perform well in Python. + class QImageArrayView: + """ + Class that ducktypes to be a Numpy ndarray. + """ + def __init__(self, qimage): + self.__array_interface__ = { + "shape": (qimage.height(), qimage.width()), + "typestr": "|u4", # Use 4 bytes per pixel rather than 3, since Numpy doesn't support 3. + "data": (int(qimage.bits()), False), + "strides": (qimage.bytesPerLine(), 3), # This does the magic: For each line, skip the correct number of bytes. Bytes per pixel is always 3 due to QImage.Format.Format_RGB888. + "version": 3 + } + array = np.asarray(QImageArrayView(xray_img)).view(np.dtype({ + "r": (np.uint8, 0, "red"), + "g": (np.uint8, 1, "green"), + "b": (np.uint8, 2, "blue"), + "a": (np.uint8, 3, "alpha") # Never filled since QImage was reformatted to RGB888. + }), np.recarray) + bad_pixel_count = np.sum(np.mod(array.r, 2)) # check number of pixels in the red channel with an odd intersection count if bad_pixel_count > 10: # allow for 10 pixels to be erroneously marked as problematic self._next_xray_checking_time = time.time() + self._xray_warning_cooldown From c2651d1141b9794d46462c082accdf92df7b033b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 25 Mar 2020 18:46:37 +0100 Subject: [PATCH 24/37] Unobfuscate and document this SVG These numbers end up beautifully on round numbers if you were to just scale them to their original size and apply these mysterious translation operations. Also do away with all of the Inkscape and Sodipodi metadata. They don't make it any easier to read. Contributes to issue CURA-7262. --- resources/images/xray_error.svg | 138 ++++---------------------------- 1 file changed, 17 insertions(+), 121 deletions(-) diff --git a/resources/images/xray_error.svg b/resources/images/xray_error.svg index a67b2bbd93..76c8e3c1bc 100644 --- a/resources/images/xray_error.svg +++ b/resources/images/xray_error.svg @@ -1,124 +1,20 @@ - - + + + + + + + + - - - - - - - - - image/svg+xml - - - - - - - - - - - - - + + + + + + + + - - - + From 986284052d4bb460074cbe11de8d33aea293b849 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 25 Mar 2020 18:57:30 +0100 Subject: [PATCH 25/37] Show warning on any invalid pixel, not just 10 Now that we have no noise any more we can do this. Possibly cuts the processing time in half, too. Contributes to issue CURA-7262. --- plugins/SolidView/SolidView.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 6acd72e615..4db938017d 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -291,12 +291,10 @@ class SolidView(View): "b": (np.uint8, 2, "blue"), "a": (np.uint8, 3, "alpha") # Never filled since QImage was reformatted to RGB888. }), np.recarray) - bad_pixel_count = np.sum(np.mod(array.r, 2)) # check number of pixels in the red channel with an odd intersection count - - if bad_pixel_count > 10: # allow for 10 pixels to be erroneously marked as problematic + if np.any(np.mod(array.r, 2)): self._next_xray_checking_time = time.time() + self._xray_warning_cooldown self._xray_warning_message.show() - Logger.log("i", "Xray overlay found %d non-manifold pixels." % bad_pixel_count) + Logger.log("i", "X-Ray overlay found non-manifold pixels.") def _onDontAskMeAgain(self, checked: bool) -> None: CuraApplication.getInstance().getPreferences().setValue(self._show_xray_warning_preference, not checked) From 0794766644e169b2c1d1614cc2712b0d9db286b6 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 27 Mar 2020 23:24:20 +0100 Subject: [PATCH 26/37] Fix xray composite shader for opengl 2.1 textureSize() is not available in opengl 2.1, so we calculate the xray error image scale outside the shader (which is also a theoretical performance improvement because now the scale does not get computed over and over for each pixel) --- plugins/SolidView/SolidView.py | 16 ++++++++++++---- plugins/XRayView/XRayView.py | 9 +++++---- resources/shaders/xray_composite.shader | 8 ++++---- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 4db938017d..0604315f3b 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019 Ultimaker B.V. +# Copyright (c) 2020 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os.path @@ -7,6 +7,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Selection import Selection from UM.Resources import Resources from PyQt5.QtGui import QOpenGLContext, QImage +from PyQt5.QtCore import QSize import numpy as np import time @@ -54,6 +55,7 @@ class SolidView(View): self._xray_composite_shader = None self._composite_pass = None self._xray_error_image = None + self._xray_error_image_size = QSize(1,1) self._extruders_model = None self._theme = None @@ -148,7 +150,9 @@ class SolidView(View): self._xray_error_image = OpenGL.getInstance().createTexture() texture_file = "xray_error.png" try: - self._xray_error_image.load(Resources.getPath(Resources.Images, texture_file)) + texture_image = QImage(Resources.getPath(Resources.Images, texture_file)).mirrored() + self._xray_error_image.setImage(texture_image) + self._xray_error_image_size = texture_image.size() except FileNotFoundError: Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) @@ -162,12 +166,13 @@ class SolidView(View): self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) self._xray_composite_shader.setTexture(3, self._xray_error_image) + renderer = self.getRenderer() if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings(): # Currently the RenderPass constructor requires a size > 0 # This should be fixed in RenderPass's constructor. self._xray_pass = XRayPass.XRayPass(1, 1) - self.getRenderer().addRenderPass(self._xray_pass) + renderer.addRenderPass(self._xray_pass) if not self._composite_pass: self._composite_pass = self.getRenderer().getRenderPass("composite") @@ -177,6 +182,9 @@ class SolidView(View): self._old_composite_shader = self._composite_pass.getCompositeShader() self._composite_pass.setCompositeShader(self._xray_composite_shader) + error_image_scale = [renderer.getViewportWidth() / self._xray_error_image_size.width(), renderer.getViewportHeight() / self._xray_error_image_size.height()] + self._xray_composite_shader.setUniformValue("u_xray_error_scale", error_image_scale) + def beginRendering(self): scene = self.getController().getScene() renderer = self.getRenderer() @@ -266,7 +274,7 @@ class SolidView(View): self._next_xray_checking_time = time.time() + self._xray_checking_update_time xray_img = self._xray_pass.getOutput() - xray_img = xray_img.convertToFormat(QImage.Format.Format_RGB888) + xray_img = xray_img.convertToFormat(QImage.Format_RGB888) # We can't just read the image since the pixels are aligned to internal memory positions. # xray_img.byteCount() != xray_img.width() * xray_img.height() * 3 diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py index 29fcfbca53..1b6fcca4c6 100644 --- a/plugins/XRayView/XRayView.py +++ b/plugins/XRayView/XRayView.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2020 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os.path @@ -91,16 +91,17 @@ class XRayView(CuraView): if not self._xray_error_image: self._xray_error_image = OpenGL.getInstance().createTexture() - img = QImage(1, 1, QImage.Format_RGB888) + dummy_image = QImage(1, 1, QImage.Format_RGB888) theme = Application.getInstance().getTheme() - img.setPixelColor(0, 0, theme.getColor("xray_error")) - self._xray_error_image.setImage(img) + dummy_image.setPixelColor(0, 0, theme.getColor("xray_error")) + self._xray_error_image.setImage(dummy_image) if not self._xray_composite_shader: self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray_composite.shader")) self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) self._xray_composite_shader.setUniformValue("u_xray_error_strength", 0.8) + self._xray_composite_shader.setUniformValue("u_xray_error_scale", [1, 1]) # irrelevant, because we don't use an actual texture self._xray_composite_shader.setTexture(3, self._xray_error_image) if not self._composite_pass: diff --git a/resources/shaders/xray_composite.shader b/resources/shaders/xray_composite.shader index 6eccc2d4e5..f71cdbf901 100644 --- a/resources/shaders/xray_composite.shader +++ b/resources/shaders/xray_composite.shader @@ -25,6 +25,7 @@ fragment = uniform sampler2D u_layer2; //X-ray pass. uniform sampler2D u_xray_error; //X-ray error image. + uniform vec2 u_xray_error_scale; uniform vec2 u_offset[9]; uniform float u_outline_strength; @@ -55,8 +56,7 @@ fragment = float rest = mod(intersection_count + .01, 2.0); if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { - vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * u_xray_error_scale); } vec4 sum = vec4(0.0); @@ -100,6 +100,7 @@ fragment41core = uniform sampler2D u_layer2; //X-ray pass. uniform sampler2D u_xray_error; //X-ray error image. + uniform vec2 u_xray_error_scale; uniform vec2 u_offset[9]; uniform float u_outline_strength; @@ -131,8 +132,7 @@ fragment41core = float rest = mod(intersection_count + .01, 2.0); if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { - vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * u_xray_error_scale); } vec4 sum = vec4(0.0); From b2fc155c3be175e1d19f8c655b68a9e8cb2a179f Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 31 Mar 2020 11:26:21 +0200 Subject: [PATCH 27/37] Fix legacy glsl shaders By @smartavionics --- resources/shaders/xray.shader | 7 +++++++ resources/shaders/xray_composite.shader | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/resources/shaders/xray.shader b/resources/shaders/xray.shader index c375d4300c..278b5b1dd3 100644 --- a/resources/shaders/xray.shader +++ b/resources/shaders/xray.shader @@ -12,6 +12,13 @@ vertex = } fragment = + #ifdef GL_ES + #ifdef GL_FRAGMENT_PRECISION_HIGH + precision highp float; + #else + precision mediump float; + #endif // GL_FRAGMENT_PRECISION_HIGH + #endif // GL_ES uniform vec4 u_color; void main() diff --git a/resources/shaders/xray_composite.shader b/resources/shaders/xray_composite.shader index f71cdbf901..648611ecc3 100644 --- a/resources/shaders/xray_composite.shader +++ b/resources/shaders/xray_composite.shader @@ -52,11 +52,11 @@ fragment = result = layer0 * layer0.a + result * (1.0 - layer0.a); - float intersection_count = texture2D(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) + float intersection_count = texture2D(u_layer2, v_uvs).r * 51.0; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) float rest = mod(intersection_count + .01, 2.0); - if (rest > 1.0 && rest < 1.5 && intersection_count < 49) + if (rest > 1.0 && rest < 1.5 && intersection_count < 49.0) { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * u_xray_error_scale); + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture2D(u_xray_error, v_uvs * u_xray_error_scale); } vec4 sum = vec4(0.0); From 4638e2b72b1dcc7982e478682979262f3a1e6072 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 31 Mar 2020 11:27:25 +0200 Subject: [PATCH 28/37] Fix resetting show xray warning --- resources/qml/Preferences/GeneralPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index 7b1263b061..57b6e5e91a 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -86,8 +86,8 @@ UM.PreferencesPage prefixJobNameCheckbox.checked = boolCheck(UM.Preferences.getValue("cura/jobname_prefix")) UM.Preferences.resetPreference("view/show_overhang"); showOverhangCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_overhang")) - UM.Preferences.resetPreference("view/show_xray_error"); - showXrayErrorCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_xray_error")) + UM.Preferences.resetPreference("view/show_xray_warning"); + showXrayErrorCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_xray_warning")) UM.Preferences.resetPreference("view/center_on_select"); centerOnSelectCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select")) UM.Preferences.resetPreference("view/invert_zoom"); From a2f9eac23babaa630a4a8a78e406d9dbeda27aa4 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 31 Mar 2020 11:29:34 +0200 Subject: [PATCH 29/37] Remove unused import --- plugins/SolidView/SolidView.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 0604315f3b..0785ae91d6 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -25,8 +25,6 @@ from UM.View.GL.OpenGL import OpenGL from UM.i18n import i18nCatalog -from cura.CuraApplication import CuraApplication - from cura.Settings.ExtruderManager import ExtruderManager from cura import XRayPass @@ -74,9 +72,9 @@ class SolidView(View): , title = catalog.i18nc("@info:title", "Model errors"), option_text = catalog.i18nc("@info:option_text", "Do not show this message again"), option_state = False) self._xray_warning_message.optionToggled.connect(self._onDontAskMeAgain) - CuraApplication.getInstance().getPreferences().addPreference(self._show_xray_warning_preference, True) + application.getPreferences().addPreference(self._show_xray_warning_preference, True) - Application.getInstance().engineCreatedSignal.connect(self._onGlobalContainerChanged) + application.engineCreatedSignal.connect(self._onGlobalContainerChanged) def _onGlobalContainerChanged(self) -> None: if self._global_stack: @@ -135,7 +133,7 @@ class SolidView(View): self._support_mesh_shader.setUniformValue("u_vertical_stripes", True) self._support_mesh_shader.setUniformValue("u_width", 5.0) - if not CuraApplication.getInstance().getPreferences().getValue(self._show_xray_warning_preference): + if not Application.getInstance().getPreferences().getValue(self._show_xray_warning_preference): self._xray_error_image = None self._xray_shader = None self._xray_composite_shader = None @@ -270,7 +268,7 @@ class SolidView(View): def endRendering(self): # check whether the xray overlay is showing badness if time.time() > self._next_xray_checking_time\ - and CuraApplication.getInstance().getPreferences().getValue(self._show_xray_warning_preference): + and Application.getInstance().getPreferences().getValue(self._show_xray_warning_preference): self._next_xray_checking_time = time.time() + self._xray_checking_update_time xray_img = self._xray_pass.getOutput() @@ -305,7 +303,7 @@ class SolidView(View): Logger.log("i", "X-Ray overlay found non-manifold pixels.") def _onDontAskMeAgain(self, checked: bool) -> None: - CuraApplication.getInstance().getPreferences().setValue(self._show_xray_warning_preference, not checked) + Application.getInstance().getPreferences().setValue(self._show_xray_warning_preference, not checked) def event(self, event): if event.type == Event.ViewActivateEvent: @@ -323,7 +321,7 @@ class SolidView(View): if Platform.isOSX(): if QOpenGLContext.currentContext() is None: Logger.log("d", "current context of OpenGL is empty on Mac OS X, will try to create shaders later") - CuraApplication.getInstance().callLater(lambda e = event: self.event(e)) + Application.getInstance().callLater(lambda e = event: self.event(e)) return From b7898b5a97b674ccb4babd70975df26a1177d786 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 31 Mar 2020 11:39:05 +0200 Subject: [PATCH 30/37] Change preference to only hide the xray message, not the visualization --- plugins/SolidView/SolidView.py | 73 ++++++++++------------- resources/qml/Preferences/GeneralPage.qml | 4 +- 2 files changed, 33 insertions(+), 44 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 0785ae91d6..a5739d19e7 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -133,55 +133,44 @@ class SolidView(View): self._support_mesh_shader.setUniformValue("u_vertical_stripes", True) self._support_mesh_shader.setUniformValue("u_width", 5.0) - if not Application.getInstance().getPreferences().getValue(self._show_xray_warning_preference): - self._xray_error_image = None - self._xray_shader = None - self._xray_composite_shader = None - if self._composite_pass and 'xray' in self._composite_pass.getLayerBindings(): - self._composite_pass.setLayerBindings(self._old_layer_bindings) - self._composite_pass.setCompositeShader(self._old_composite_shader) - self._old_layer_bindings = None - self._old_composite_shader = None - self._xray_warning_message.hide() - else: - if not self._xray_error_image: - self._xray_error_image = OpenGL.getInstance().createTexture() - texture_file = "xray_error.png" - try: - texture_image = QImage(Resources.getPath(Resources.Images, texture_file)).mirrored() - self._xray_error_image.setImage(texture_image) - self._xray_error_image_size = texture_image.size() - except FileNotFoundError: - Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) + if not self._xray_error_image: + self._xray_error_image = OpenGL.getInstance().createTexture() + texture_file = "xray_error.png" + try: + texture_image = QImage(Resources.getPath(Resources.Images, texture_file)).mirrored() + self._xray_error_image.setImage(texture_image) + self._xray_error_image_size = texture_image.size() + except FileNotFoundError: + Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) - if not self._xray_shader: - self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) + if not self._xray_shader: + self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) - if not self._xray_composite_shader: - self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray_composite.shader")) - theme = Application.getInstance().getTheme() - self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) - self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) - self._xray_composite_shader.setTexture(3, self._xray_error_image) + if not self._xray_composite_shader: + self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray_composite.shader")) + theme = Application.getInstance().getTheme() + self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) + self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) + self._xray_composite_shader.setTexture(3, self._xray_error_image) - renderer = self.getRenderer() - if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings(): - # Currently the RenderPass constructor requires a size > 0 - # This should be fixed in RenderPass's constructor. - self._xray_pass = XRayPass.XRayPass(1, 1) + renderer = self.getRenderer() + if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings(): + # Currently the RenderPass constructor requires a size > 0 + # This should be fixed in RenderPass's constructor. + self._xray_pass = XRayPass.XRayPass(1, 1) - renderer.addRenderPass(self._xray_pass) + renderer.addRenderPass(self._xray_pass) - if not self._composite_pass: - self._composite_pass = self.getRenderer().getRenderPass("composite") + if not self._composite_pass: + self._composite_pass = self.getRenderer().getRenderPass("composite") - self._old_layer_bindings = self._composite_pass.getLayerBindings() - self._composite_pass.setLayerBindings(["default", "selection", "xray"]) - self._old_composite_shader = self._composite_pass.getCompositeShader() - self._composite_pass.setCompositeShader(self._xray_composite_shader) + self._old_layer_bindings = self._composite_pass.getLayerBindings() + self._composite_pass.setLayerBindings(["default", "selection", "xray"]) + self._old_composite_shader = self._composite_pass.getCompositeShader() + self._composite_pass.setCompositeShader(self._xray_composite_shader) - error_image_scale = [renderer.getViewportWidth() / self._xray_error_image_size.width(), renderer.getViewportHeight() / self._xray_error_image_size.height()] - self._xray_composite_shader.setUniformValue("u_xray_error_scale", error_image_scale) + error_image_scale = [renderer.getViewportWidth() / self._xray_error_image_size.width(), renderer.getViewportHeight() / self._xray_error_image_size.height()] + self._xray_composite_shader.setUniformValue("u_xray_error_scale", error_image_scale) def beginRendering(self): scene = self.getController().getScene() diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index 57b6e5e91a..eacf2f60e2 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -345,7 +345,7 @@ UM.PreferencesPage width: childrenRect.width; height: childrenRect.height; - text: catalog.i18nc("@info:tooltip", "Highlight missing or extraneous surfaces of the model using warning signs. The toolpaths will often be missing parts of the intended geometry.") + text: catalog.i18nc("@info:tooltip", "Show a message if missing or extraneous surfaces are detected. The toolpaths will often be missing parts of the intended geometry.") CheckBox { @@ -354,7 +354,7 @@ UM.PreferencesPage checked: boolCheck(UM.Preferences.getValue("view/show_xray_warning")) onClicked: UM.Preferences.setValue("view/show_xray_warning", checked) - text: catalog.i18nc("@option:check", "Display model errors"); + text: catalog.i18nc("@option:check", "Display message if model errors are detected"); } } From ccc05894955bf2ee8131a0c6a54e8c44037abd84 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 31 Mar 2020 11:50:16 +0200 Subject: [PATCH 31/37] Remove the checkbox option to set the preference to hide the messagebox --- plugins/SolidView/SolidView.py | 86 +++++++++++++---------- resources/qml/Preferences/GeneralPage.qml | 26 ++++++- 2 files changed, 70 insertions(+), 42 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index a5739d19e7..7d7f231388 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -67,11 +67,11 @@ class SolidView(View): self._next_xray_checking_time = time.time() self._xray_checking_update_time = 1.0 # seconds self._xray_warning_cooldown = 60 * 10 # reshow Model error message every 10 minutes - self._xray_warning_message = Message(catalog.i18nc("@info:status", "Your model is not manifold. The highlighted areas indicate either missing or extraneous surfaces.") - , lifetime = 60 * 5 # leave message for 5 minutes - , title = catalog.i18nc("@info:title", "Model errors"), - option_text = catalog.i18nc("@info:option_text", "Do not show this message again"), option_state = False) - self._xray_warning_message.optionToggled.connect(self._onDontAskMeAgain) + self._xray_warning_message = Message( + catalog.i18nc("@info:status", "Your model is not manifold. The highlighted areas indicate either missing or extraneous surfaces."), + lifetime = 60 * 5, # leave message for 5 minutes + title = catalog.i18nc("@info:title", "Model errors"), + ) application.getPreferences().addPreference(self._show_xray_warning_preference, True) application.engineCreatedSignal.connect(self._onGlobalContainerChanged) @@ -133,44 +133,55 @@ class SolidView(View): self._support_mesh_shader.setUniformValue("u_vertical_stripes", True) self._support_mesh_shader.setUniformValue("u_width", 5.0) - if not self._xray_error_image: - self._xray_error_image = OpenGL.getInstance().createTexture() - texture_file = "xray_error.png" - try: - texture_image = QImage(Resources.getPath(Resources.Images, texture_file)).mirrored() - self._xray_error_image.setImage(texture_image) - self._xray_error_image_size = texture_image.size() - except FileNotFoundError: - Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) + if not Application.getInstance().getPreferences().getValue(self._show_xray_warning_preference): + self._xray_error_image = None + self._xray_shader = None + self._xray_composite_shader = None + if self._composite_pass and 'xray' in self._composite_pass.getLayerBindings(): + self._composite_pass.setLayerBindings(self._old_layer_bindings) + self._composite_pass.setCompositeShader(self._old_composite_shader) + self._old_layer_bindings = None + self._old_composite_shader = None + self._xray_warning_message.hide() + else: + if not self._xray_error_image: + self._xray_error_image = OpenGL.getInstance().createTexture() + texture_file = "xray_error.png" + try: + texture_image = QImage(Resources.getPath(Resources.Images, texture_file)).mirrored() + self._xray_error_image.setImage(texture_image) + self._xray_error_image_size = texture_image.size() + except FileNotFoundError: + Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) - if not self._xray_shader: - self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) + if not self._xray_shader: + self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) - if not self._xray_composite_shader: - self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray_composite.shader")) - theme = Application.getInstance().getTheme() - self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) - self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) - self._xray_composite_shader.setTexture(3, self._xray_error_image) + if not self._xray_composite_shader: + self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray_composite.shader")) + theme = Application.getInstance().getTheme() + self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) + self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) + self._xray_composite_shader.setTexture(3, self._xray_error_image) - renderer = self.getRenderer() - if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings(): - # Currently the RenderPass constructor requires a size > 0 - # This should be fixed in RenderPass's constructor. - self._xray_pass = XRayPass.XRayPass(1, 1) + renderer = self.getRenderer() + if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings(): + # Currently the RenderPass constructor requires a size > 0 + # This should be fixed in RenderPass's constructor. + self._xray_pass = XRayPass.XRayPass(1, 1) - renderer.addRenderPass(self._xray_pass) + renderer.addRenderPass(self._xray_pass) - if not self._composite_pass: - self._composite_pass = self.getRenderer().getRenderPass("composite") + if not self._composite_pass: + self._composite_pass = self.getRenderer().getRenderPass("composite") - self._old_layer_bindings = self._composite_pass.getLayerBindings() - self._composite_pass.setLayerBindings(["default", "selection", "xray"]) - self._old_composite_shader = self._composite_pass.getCompositeShader() - self._composite_pass.setCompositeShader(self._xray_composite_shader) + self._old_layer_bindings = self._composite_pass.getLayerBindings() + self._composite_pass.setLayerBindings(["default", "selection", "xray"]) + self._old_composite_shader = self._composite_pass.getCompositeShader() + self._composite_pass.setCompositeShader(self._xray_composite_shader) - error_image_scale = [renderer.getViewportWidth() / self._xray_error_image_size.width(), renderer.getViewportHeight() / self._xray_error_image_size.height()] - self._xray_composite_shader.setUniformValue("u_xray_error_scale", error_image_scale) + error_image_scale = [renderer.getViewportWidth() / self._xray_error_image_size.width(), renderer.getViewportHeight() / self._xray_error_image_size.height()] + self._xray_composite_shader.setUniformValue("u_xray_error_scale", error_image_scale) def beginRendering(self): scene = self.getController().getScene() @@ -291,9 +302,6 @@ class SolidView(View): self._xray_warning_message.show() Logger.log("i", "X-Ray overlay found non-manifold pixels.") - def _onDontAskMeAgain(self, checked: bool) -> None: - Application.getInstance().getPreferences().setValue(self._show_xray_warning_preference, not checked) - def event(self, event): if event.type == Event.ViewActivateEvent: # FIX: on Max OS X, somehow QOpenGLContext.currentContext() can become None during View switching. diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index eacf2f60e2..375ad9e4c1 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -87,7 +87,9 @@ UM.PreferencesPage UM.Preferences.resetPreference("view/show_overhang"); showOverhangCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_overhang")) UM.Preferences.resetPreference("view/show_xray_warning"); - showXrayErrorCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_xray_warning")) + showXrayErrorCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_warning")) + UM.Preferences.resetPreference("view/show_xray_warning_message"); + showXrayErrorMessageCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_warning_message")) UM.Preferences.resetPreference("view/center_on_select"); centerOnSelectCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select")) UM.Preferences.resetPreference("view/invert_zoom"); @@ -345,7 +347,7 @@ UM.PreferencesPage width: childrenRect.width; height: childrenRect.height; - text: catalog.i18nc("@info:tooltip", "Show a message if missing or extraneous surfaces are detected. The toolpaths will often be missing parts of the intended geometry.") + text: catalog.i18nc("@info:tooltip", "Highlight missing or extraneous surfaces of the model using warning signs. The toolpaths will often be missing parts of the intended geometry.") CheckBox { @@ -354,7 +356,25 @@ UM.PreferencesPage checked: boolCheck(UM.Preferences.getValue("view/show_xray_warning")) onClicked: UM.Preferences.setValue("view/show_xray_warning", checked) - text: catalog.i18nc("@option:check", "Display message if model errors are detected"); + text: catalog.i18nc("@option:check", "Display model errors"); + } + } + + UM.TooltipArea + { + width: childrenRect.width; + height: childrenRect.height; + + text: catalog.i18nc("@info:tooltip", "Highlight missing or extraneous surfaces of the model using warning signs. The toolpaths will often be missing parts of the intended geometry.") + + CheckBox + { + id: showXrayErrorMessageCheckbox + + checked: boolCheck(UM.Preferences.getValue("view/show_xray_warning_message")) + onClicked: UM.Preferences.setValue("view/show_xray_warning_message", checked) + + text: catalog.i18nc("@option:check", "Display model errors"); } } From 1b3c51d98a4b71a347f4b9035b043ecb2fbb6ae9 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 31 Mar 2020 11:57:45 +0200 Subject: [PATCH 32/37] Remove extraneous preference --- resources/qml/Preferences/GeneralPage.qml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index 375ad9e4c1..404c961a90 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -88,8 +88,6 @@ UM.PreferencesPage showOverhangCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_overhang")) UM.Preferences.resetPreference("view/show_xray_warning"); showXrayErrorCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_warning")) - UM.Preferences.resetPreference("view/show_xray_warning_message"); - showXrayErrorMessageCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_warning_message")) UM.Preferences.resetPreference("view/center_on_select"); centerOnSelectCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select")) UM.Preferences.resetPreference("view/invert_zoom"); @@ -360,24 +358,6 @@ UM.PreferencesPage } } - UM.TooltipArea - { - width: childrenRect.width; - height: childrenRect.height; - - text: catalog.i18nc("@info:tooltip", "Highlight missing or extraneous surfaces of the model using warning signs. The toolpaths will often be missing parts of the intended geometry.") - - CheckBox - { - id: showXrayErrorMessageCheckbox - - checked: boolCheck(UM.Preferences.getValue("view/show_xray_warning_message")) - onClicked: UM.Preferences.setValue("view/show_xray_warning_message", checked) - - text: catalog.i18nc("@option:check", "Display model errors"); - } - } - UM.TooltipArea { width: childrenRect.width; From e23b9a94fa272449343b9349ed58d3fc93b6f501 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 3 Apr 2020 15:07:28 +0200 Subject: [PATCH 33/37] Shader: Use builtin rather than mix ourselves. part of CURA-7262 --- resources/shaders/xray_composite.shader | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/shaders/xray_composite.shader b/resources/shaders/xray_composite.shader index 648611ecc3..a5d1f9c22d 100644 --- a/resources/shaders/xray_composite.shader +++ b/resources/shaders/xray_composite.shader @@ -56,7 +56,7 @@ fragment = float rest = mod(intersection_count + .01, 2.0); if (rest > 1.0 && rest < 1.5 && intersection_count < 49.0) { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture2D(u_xray_error, v_uvs * u_xray_error_scale); + result = mix(result, texture2D(u_xray_error, v_uvs * u_xray_error_scale), u_xray_error_strength); } vec4 sum = vec4(0.0); @@ -132,7 +132,7 @@ fragment41core = float rest = mod(intersection_count + .01, 2.0); if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * u_xray_error_scale); + result = mix(result, texture(u_xray_error, v_uvs * u_xray_error_scale), u_xray_error_strength); } vec4 sum = vec4(0.0); From 60bd676b44ab8fb86f1b078e16ac74aca88b93a5 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 3 Apr 2020 21:01:55 +0200 Subject: [PATCH 34/37] Shader: More use builtin rather than adhoc mix. part of CURA-7262 --- resources/shaders/xray_composite.shader | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/shaders/xray_composite.shader b/resources/shaders/xray_composite.shader index a5d1f9c22d..5ef84a5145 100644 --- a/resources/shaders/xray_composite.shader +++ b/resources/shaders/xray_composite.shader @@ -50,7 +50,7 @@ fragment = vec4 result = u_background_color; vec4 layer0 = texture2D(u_layer0, v_uvs); - result = layer0 * layer0.a + result * (1.0 - layer0.a); + result = mix(result, layer0, layer0.a); float intersection_count = texture2D(u_layer2, v_uvs).r * 51.0; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) float rest = mod(intersection_count + .01, 2.0); @@ -126,7 +126,7 @@ fragment41core = vec4 result = u_background_color; vec4 layer0 = texture(u_layer0, v_uvs); - result = layer0 * layer0.a + result * (1.0 - layer0.a); + result = mix(result, layer0, layer0.a); float intersection_count = texture(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) float rest = mod(intersection_count + .01, 2.0); From b59d38e6c9b64045a46f1cbf5ec460d965dd6e9f Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 7 Apr 2020 12:06:13 +0200 Subject: [PATCH 35/37] Replace warning image with triadic colors. part of CURA-7262 --- resources/shaders/overhang.shader | 15 +++++++++---- resources/shaders/xray_composite.shader | 28 +++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/resources/shaders/overhang.shader b/resources/shaders/overhang.shader index 7f1b04dd59..b73ed3c701 100644 --- a/resources/shaders/overhang.shader +++ b/resources/shaders/overhang.shader @@ -38,9 +38,13 @@ fragment = varying highp vec3 f_vertex; varying highp vec3 f_normal; + float round(float f) + { + return sign(f) * floor(abs(f) + 0.5); + } + void main() { - mediump vec4 finalColor = vec4(0.0); // Ambient Component @@ -62,8 +66,10 @@ fragment = finalColor = (-normal.y > u_overhangAngle) ? u_overhangColor : finalColor; + vec3 grid = vec3(f_vertex.x - round(f_vertex.x), f_vertex.y - round(f_vertex.y), f_vertex.z - round(f_vertex.z)); + finalColor.a = dot(grid, grid) < 0.245 ? 0.667 : 1.0; + gl_FragColor = finalColor; - gl_FragColor.a = 1.0; } vertex41core = @@ -111,7 +117,6 @@ fragment41core = void main() { - mediump vec4 finalColor = vec4(0.0); // Ambient Component @@ -134,7 +139,9 @@ fragment41core = finalColor = (u_faceId != gl_PrimitiveID) ? ((-normal.y > u_overhangAngle) ? u_overhangColor : finalColor) : u_faceColor; frag_color = finalColor; - frag_color.a = 1.0; + + vec3 grid = f_vertex - round(f_vertex); + frag_color.a = dot(grid, grid) < 0.245 ? 0.667 : 1.0; } [defaults] diff --git a/resources/shaders/xray_composite.shader b/resources/shaders/xray_composite.shader index 5ef84a5145..4233067ec4 100644 --- a/resources/shaders/xray_composite.shader +++ b/resources/shaders/xray_composite.shader @@ -41,6 +41,13 @@ fragment = float kernel[9]; + vec3 shiftHue(vec3 color, float hue) + { + const vec3 k = vec3(0.57735, 0.57735, 0.57735); + float cosAngle = cos(hue); + return vec3(color * cosAngle + cross(k, color) * sin(hue) + k * dot(k, color) * (1.0 - cosAngle)); + } + void main() { kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; @@ -50,13 +57,18 @@ fragment = vec4 result = u_background_color; vec4 layer0 = texture2D(u_layer0, v_uvs); + float hue_shift = (layer0.a - 0.333) * 6.2831853; + if (layer0.a > 0.5) + { + layer0.a = 1.0; + } result = mix(result, layer0, layer0.a); float intersection_count = texture2D(u_layer2, v_uvs).r * 51.0; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) float rest = mod(intersection_count + .01, 2.0); if (rest > 1.0 && rest < 1.5 && intersection_count < 49.0) { - result = mix(result, texture2D(u_xray_error, v_uvs * u_xray_error_scale), u_xray_error_strength); + result = vec4(shiftHue(layer0.rgb, hue_shift), result.a); } vec4 sum = vec4(0.0); @@ -117,6 +129,13 @@ fragment41core = float kernel[9]; + vec3 shiftHue(vec3 color, float hue) + { + const vec3 k = vec3(0.57735, 0.57735, 0.57735); + float cosAngle = cos(hue); + return vec3(color * cosAngle + cross(k, color) * sin(hue) + k * dot(k, color) * (1.0 - cosAngle)); + } + void main() { kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; @@ -126,13 +145,18 @@ fragment41core = vec4 result = u_background_color; vec4 layer0 = texture(u_layer0, v_uvs); + float hue_shift = (layer0.a - 0.333) * 6.2831853; + if (layer0.a > 0.5) + { + layer0.a = 1.0; + } result = mix(result, layer0, layer0.a); float intersection_count = texture(u_layer2, v_uvs).r * 51; // (1 / .02) + 1 (+1 magically fixes issues with high intersection count models) float rest = mod(intersection_count + .01, 2.0); if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { - result = mix(result, texture(u_xray_error, v_uvs * u_xray_error_scale), u_xray_error_strength); + result = vec4(shiftHue(layer0.rgb, hue_shift), result.a); } vec4 sum = vec4(0.0); From 5494a09eefa4b65a5c763becdd518215f7216aa9 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 7 Apr 2020 12:46:32 +0200 Subject: [PATCH 36/37] Make sure warning works for greyscale colors. part of CURA-7262 --- resources/shaders/xray_composite.shader | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/resources/shaders/xray_composite.shader b/resources/shaders/xray_composite.shader index 4233067ec4..8a2f3aa6c4 100644 --- a/resources/shaders/xray_composite.shader +++ b/resources/shaders/xray_composite.shader @@ -43,6 +43,13 @@ fragment = vec3 shiftHue(vec3 color, float hue) { + // Make sure colors are distinct when grey-scale is used too: + if ((max(max(color.r, color.g), color.b) - min(min(color.r, color.g), color.b)) < 0.1) + { + color = vec3(1.0, 0.0, 0.0); + } + + // The actual hue shift: const vec3 k = vec3(0.57735, 0.57735, 0.57735); float cosAngle = cos(hue); return vec3(color * cosAngle + cross(k, color) * sin(hue) + k * dot(k, color) * (1.0 - cosAngle)); @@ -131,6 +138,13 @@ fragment41core = vec3 shiftHue(vec3 color, float hue) { + // Make sure colors are distinct when grey-scale is used too: + if ((max(max(color.r, color.g), color.b) - min(min(color.r, color.g), color.b)) < 0.1) + { + color = vec3(1.0, 0.0, 0.0); + } + + // The actual hue shift: const vec3 k = vec3(0.57735, 0.57735, 0.57735); float cosAngle = cos(hue); return vec3(color * cosAngle + cross(k, color) * sin(hue) + k * dot(k, color) * (1.0 - cosAngle)); From b7e6b2888adce703c1905866ba558d95d4f9eb35 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 7 Apr 2020 12:57:07 +0200 Subject: [PATCH 37/37] Actually remove xray error image (because colors). part of CURA-7262 --- plugins/SolidView/SolidView.py | 17 ----------------- plugins/XRayView/XRayView.py | 11 ----------- resources/images/xray_error.png | Bin 906 -> 0 bytes resources/images/xray_error.svg | 20 -------------------- resources/shaders/xray_composite.shader | 6 ------ 5 files changed, 54 deletions(-) delete mode 100644 resources/images/xray_error.png delete mode 100644 resources/images/xray_error.svg diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 7d7f231388..8c9967be03 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -52,8 +52,6 @@ class SolidView(View): self._xray_pass = None self._xray_composite_shader = None self._composite_pass = None - self._xray_error_image = None - self._xray_error_image_size = QSize(1,1) self._extruders_model = None self._theme = None @@ -134,7 +132,6 @@ class SolidView(View): self._support_mesh_shader.setUniformValue("u_width", 5.0) if not Application.getInstance().getPreferences().getValue(self._show_xray_warning_preference): - self._xray_error_image = None self._xray_shader = None self._xray_composite_shader = None if self._composite_pass and 'xray' in self._composite_pass.getLayerBindings(): @@ -144,16 +141,6 @@ class SolidView(View): self._old_composite_shader = None self._xray_warning_message.hide() else: - if not self._xray_error_image: - self._xray_error_image = OpenGL.getInstance().createTexture() - texture_file = "xray_error.png" - try: - texture_image = QImage(Resources.getPath(Resources.Images, texture_file)).mirrored() - self._xray_error_image.setImage(texture_image) - self._xray_error_image_size = texture_image.size() - except FileNotFoundError: - Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) - if not self._xray_shader: self._xray_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray.shader")) @@ -162,7 +149,6 @@ class SolidView(View): theme = Application.getInstance().getTheme() self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) - self._xray_composite_shader.setTexture(3, self._xray_error_image) renderer = self.getRenderer() if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings(): @@ -180,9 +166,6 @@ class SolidView(View): self._old_composite_shader = self._composite_pass.getCompositeShader() self._composite_pass.setCompositeShader(self._xray_composite_shader) - error_image_scale = [renderer.getViewportWidth() / self._xray_error_image_size.width(), renderer.getViewportHeight() / self._xray_error_image_size.height()] - self._xray_composite_shader.setUniformValue("u_xray_error_scale", error_image_scale) - def beginRendering(self): scene = self.getController().getScene() renderer = self.getRenderer() diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py index 1b6fcca4c6..8fc47cee74 100644 --- a/plugins/XRayView/XRayView.py +++ b/plugins/XRayView/XRayView.py @@ -34,7 +34,6 @@ class XRayView(CuraView): self._composite_pass = None self._old_composite_shader = None self._old_layer_bindings = None - self._xray_error_image = None def beginRendering(self): scene = self.getController().getScene() @@ -89,20 +88,10 @@ class XRayView(CuraView): self.getRenderer().addRenderPass(self._xray_pass) - if not self._xray_error_image: - self._xray_error_image = OpenGL.getInstance().createTexture() - dummy_image = QImage(1, 1, QImage.Format_RGB888) - theme = Application.getInstance().getTheme() - dummy_image.setPixelColor(0, 0, theme.getColor("xray_error")) - self._xray_error_image.setImage(dummy_image) - if not self._xray_composite_shader: self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray_composite.shader")) self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) - self._xray_composite_shader.setUniformValue("u_xray_error_strength", 0.8) - self._xray_composite_shader.setUniformValue("u_xray_error_scale", [1, 1]) # irrelevant, because we don't use an actual texture - self._xray_composite_shader.setTexture(3, self._xray_error_image) if not self._composite_pass: self._composite_pass = self.getRenderer().getRenderPass("composite") diff --git a/resources/images/xray_error.png b/resources/images/xray_error.png deleted file mode 100644 index e54eebdd936c70c6b4ab7e00d87c1cd2dec79728..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 906 zcmV;519kj~P)g<>bWTzwS=gE=pT&drQvHm4V-C(V!d zO zzE|&flwy6IMB;L)U6DwzzK*hc8^ z<%h%Ja5!v&$oNfBqayzSADQGRwYIjly1J^AQX(Pv-B*ztwdof|zEXXCeT72d;^Lye zzh5b(AmOV`>kisa5U}#Mx3`UbXJ^L*5rCJC2hG(Sk83ExXIB3B__*UZ(P%UpjXI7q zHa2F0xCuon-=a#19_fq6HEh`0wzRbD@9(G6Y10?!bo%h{Fc=J)YCoKXj6@>m=jXZ-<&#`x%IEXl-QA{T?^XJIzjGjHpPj9(EqzIB zZf=?fss(;=CHUORA08eq7K^nm9LI^pVzF4PHUfju(NPn`?OKB8_Sp#p0=v7ruJ@Oh zmrYhzR#sdO?CtF}H8q(B>RCC#|M01mKQ}k$l?2CedU|?#dwUNK4!q9H&d!=3K7m4s z;DMDN3Wbi2j=V1W!SV5NdwaVH;ychFf5OLbVt>uA3|hBqy$^vGaALo@N&+~67v|%J g{YQ1R>js>_TW0?LV5r$!fdBvi07*qoM6N<$g1+;%CjbBd diff --git a/resources/images/xray_error.svg b/resources/images/xray_error.svg deleted file mode 100644 index 76c8e3c1bc..0000000000 --- a/resources/images/xray_error.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/resources/shaders/xray_composite.shader b/resources/shaders/xray_composite.shader index 8a2f3aa6c4..c955d4fc18 100644 --- a/resources/shaders/xray_composite.shader +++ b/resources/shaders/xray_composite.shader @@ -23,9 +23,7 @@ fragment = uniform sampler2D u_layer0; //Default pass. uniform sampler2D u_layer1; //Selection pass. uniform sampler2D u_layer2; //X-ray pass. - uniform sampler2D u_xray_error; //X-ray error image. - uniform vec2 u_xray_error_scale; uniform vec2 u_offset[9]; uniform float u_outline_strength; @@ -117,9 +115,7 @@ fragment41core = uniform sampler2D u_layer0; //Default pass. uniform sampler2D u_layer1; //Selection pass. uniform sampler2D u_layer2; //X-ray pass. - uniform sampler2D u_xray_error; //X-ray error image. - uniform vec2 u_xray_error_scale; uniform vec2 u_offset[9]; uniform float u_outline_strength; @@ -197,11 +193,9 @@ fragment41core = u_layer0 = 0 u_layer1 = 1 u_layer2 = 2 -u_xray_error = 3 u_background_color = [0.965, 0.965, 0.965, 1.0] u_outline_strength = 1.0 u_outline_color = [0.05, 0.66, 0.89, 1.0] -u_xray_error_strength = 0.4 [bindings]