diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py new file mode 100644 index 0000000000..41d617f481 --- /dev/null +++ b/plugins/SolidView/SolidView.py @@ -0,0 +1,89 @@ +# Copyright (c) 2015 Ultimaker B.V. +# Uranium is released under the terms of the AGPLv3 or higher. + +from UM.View.View import View +from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator +from UM.Resources import Resources +from UM.Application import Application +from UM.Math.Color import Color +from UM.Preferences import Preferences +from UM.View.Renderer import Renderer + +from UM.View.GL.OpenGL import OpenGL + +import math + +## Standard view for mesh models. +class SolidView(View): + #EnabledColor = Color(1.0, 0.79, 0.14, 1.0) + #DisabledColor = Color(0.68, 0.68, 0.68, 1.0) + + def __init__(self): + super().__init__() + + Preferences.getInstance().addPreference("view/show_overhang", True) + #Preferences.getInstance().preferenceChanged.connect(self._onPreferenceChanged) + + self._enabled_shader = None + self._disabled_shader = None + + def beginRendering(self): + scene = self.getController().getScene() + renderer = self.getRenderer() + + if not self._enabled_shader: + #if Preferences.getInstance().getValue("view/show_overhang"): + #self._enabled_material = renderer.createMaterial(Resources.getPath(Resources.Shaders, "default.vert"), Resources.getPath(Resources.Shaders, "overhang.frag")) + #else: + #self._enabled_material = renderer.createMaterial(Resources.getPath(Resources.Shaders, "default.vert"), Resources.getPath(Resources.Shaders, "default.frag")) + + self._enabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader")) + + #self._enabled_material.setUniformValue("u_ambientColor", Color(0.3, 0.3, 0.3, 1.0)) + #self._enabled_material.setUniformValue("u_diffuseColor", self.EnabledColor) + #self._enabled_material.setUniformValue("u_specularColor", Color(0.4, 0.4, 0.4, 1.0)) + #self._enabled_material.setUniformValue("u_overhangColor", Color(1.0, 0.0, 0.0, 1.0)) + #self._enabled_material.setUniformValue("u_shininess", 20.) + + if not self._disabled_shader: + self._disabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader")) + self._disabled_shader.setUniformValue("u_diffuseColor", [0.68, 0.68, 0.68, 1.0]) + #self._disabled_material = renderer.createMaterial(Resources.getPath(Resources.Shaders, "default.vert"), Resources.getPath(Resources.Shaders, "default.frag")) + #self._disabled_material.setUniformValue("u_ambientColor", Color(0.3, 0.3, 0.3, 1.0)) + #self._disabled_material.setUniformValue("u_diffuseColor", self.DisabledColor) + #self._disabled_material.setUniformValue("u_specularColor", Color(0.4, 0.4, 0.4, 1.0)) + #self._disabled_material.setUniformValue("u_overhangColor", Color(1.0, 0.0, 0.0, 1.0)) + #self._disabled_material.setUniformValue("u_shininess", 20.) + + if Application.getInstance().getMachineManager().getActiveProfile(): + profile = Application.getInstance().getMachineManager().getActiveProfile() + + if profile.getSettingValue("support_enable") or not Preferences.getInstance().getValue("view/show_overhang"): + angle = profile.getSettingValue("support_angle") + if angle != None: + self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle))) + else: + self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) + + for node in DepthFirstIterator(scene.getRoot()): + if not node.render(renderer): + if node.getMeshData() and node.isVisible(): + # TODO: Find a better way to handle this + #if node.getBoundingBoxMesh(): + # renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(),mode = Renderer.RenderLines) + if hasattr(node, "_outside_buildarea"): + if node._outside_buildarea: + renderer.queueNode(node, shader = self._disabled_shader) + else: + renderer.queueNode(node, shader = self._enabled_shader) + else: + renderer.queueNode(node, material = self._enabled_shader) + if node.callDecoration("isGroup"): + renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(),mode = Renderer.RenderLines) + + def endRendering(self): + pass + + #def _onPreferenceChanged(self, preference): + #if preference == "view/show_overhang": ## Todo: This a printer only setting. Should be removed from Uranium. + #self._enabled_material = None diff --git a/plugins/SolidView/__init__.py b/plugins/SolidView/__init__.py new file mode 100644 index 0000000000..00dc1618fd --- /dev/null +++ b/plugins/SolidView/__init__.py @@ -0,0 +1,24 @@ +# Copyright (c) 2015 Ultimaker B.V. +# Uranium is released under the terms of the AGPLv3 or higher. + +from . import SolidView + +from UM.i18n import i18nCatalog +i18n_catalog = i18nCatalog("cura") + +def getMetaData(): + return { + "plugin": { + "name": i18n_catalog.i18nc("@label", "Solid View"), + "author": "Ultimaker", + "version": "1.0", + "decription": i18n_catalog.i18nc("@info:whatsthis", "Provides a normal solid mesh view."), + "api": 2 + }, + "view": { + "name": i18n_catalog.i18nc("@item:inmenu", "Solid") + } + } + +def register(app): + return { "view": SolidView.SolidView() } diff --git a/resources/shaders/overhang.shader b/resources/shaders/overhang.shader new file mode 100644 index 0000000000..4ae2821c7d --- /dev/null +++ b/resources/shaders/overhang.shader @@ -0,0 +1,80 @@ +[shaders] +vertex = + uniform highp mat4 u_modelMatrix; + uniform highp mat4 u_viewProjectionMatrix; + uniform highp mat4 u_normalMatrix; + + attribute highp vec4 a_vertex; + attribute highp vec4 a_normal; + attribute highp vec2 a_uvs; + + varying highp vec3 v_vertex; + varying highp vec3 v_normal; + + void main() + { + vec4 world_space_vert = u_modelMatrix * a_vertex; + gl_Position = u_viewProjectionMatrix * world_space_vert; + + v_vertex = world_space_vert.xyz; + v_normal = (u_normalMatrix * normalize(a_normal)).xyz; + } + +fragment = + uniform mediump vec4 u_ambientColor; + uniform mediump vec4 u_diffuseColor; + uniform mediump vec4 u_specularColor; + uniform highp vec3 u_lightPosition; + uniform mediump float u_shininess; + uniform highp vec3 u_viewPosition; + + uniform lowp float u_overhangAngle; + uniform lowp vec4 u_overhangColor; + + varying highp vec3 v_vertex; + varying highp vec3 v_normal; + + void main() + { + mediump vec4 finalColor = vec4(0.0); + + /* Ambient Component */ + finalColor += u_ambientColor; + + highp vec3 normal = normalize(v_normal); + highp vec3 lightDir = normalize(u_lightPosition - v_vertex); + + /* Diffuse Component */ + highp float NdotL = clamp(abs(dot(normal, lightDir)), 0.0, 1.0); + finalColor += (NdotL * u_diffuseColor); + + /* Specular Component */ + /* TODO: We should not do specularity for fragments facing away from the light.*/ + highp vec3 reflectedLight = reflect(-lightDir, normal); + highp vec3 viewVector = normalize(u_viewPosition - v_vertex); + highp float NdotR = clamp(dot(viewVector, reflectedLight), 0.0, 1.0); + finalColor += pow(NdotR, u_shininess) * u_specularColor; + + finalColor = (-normal.y > u_overhangAngle) ? u_overhangColor : finalColor; + + gl_FragColor = finalColor; + gl_FragColor.a = 1.0; + } + +[defaults] +u_ambientColor = [0.3, 0.3, 0.3, 1.0] +u_diffuseColor = [1.0, 0.79, 0.14, 1.0] +u_specularColor = [0.4, 0.4, 0.4, 1.0] +u_overhangColor = [1.0, 0.0, 0.0, 1.0] +u_shininess = 20.0 + +[bindings] +u_modelMatrix = model_matrix +u_viewProjectionMatrix = view_projection_matrix +u_normalMatrix = normal_matrix +u_viewPosition = view_position +u_lightPosition = light_0_position + +[attributes] +a_vertex = vertex +a_normal = normal