Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Ultimaker/Cura.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Kuipers <t.kuipers@ultimaker.com>2019-10-21 18:34:23 +0300
committerTim Kuipers <t.kuipers@ultimaker.com>2020-02-27 18:41:13 +0300
commitfc4c66b62a7173d1260e40c121bc6133fbca6a88 (patch)
tree5b34b01c2e51fb1412e919d1c89c2add12a9ddb6 /plugins/SolidView
parentb3761c454bba281517f1cd21d3fa4d669c7e39ba (diff)
show xray errors in solid view
Diffstat (limited to 'plugins/SolidView')
-rw-r--r--plugins/SolidView/SolidView.py74
-rw-r--r--plugins/SolidView/xray_composite.shader166
-rwxr-xr-xplugins/SolidView/xray_overlay.shader50
3 files changed, 289 insertions, 1 deletions
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