Cura/plugins/LayerView/LayerView.py
2016-09-07 14:01:58 +02:00

118 lines
4.4 KiB
Python

# Copyright (c) 2015 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
from UM.PluginRegistry import PluginRegistry
from UM.View.View import View
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Resources import Resources
from UM.Event import Event, KeyEvent
from UM.Signal import Signal
from UM.Scene.Selection import Selection
from UM.Math.Color import Color
from UM.Scene.SceneNode import SceneNode
from UM.View.GL.OpenGL import OpenGL
from cura.ConvexHullNode import ConvexHullNode
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication
from . import LayerViewProxy
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
from . import LayerPass
import os.path
## View used to display g-code paths.
class LayerView(View):
def __init__(self):
super().__init__()
self._proxy = LayerViewProxy.LayerViewProxy()
self._ghost_shader = None
self._layer_pass = None
self._composite_pass = None
self._old_layer_bindings = None
self._layerview_composite_shader = None
self._old_composite_shader = None
self._busy = False
def getLayerPass(self):
return self._layer_pass
busyChanged = Signal()
def isBusy(self):
return self._busy
def setBusy(self, busy):
if busy != self._busy:
self._busy = busy
self.busyChanged.emit()
def beginRendering(self):
scene = self.getController().getScene()
renderer = self.getRenderer()
if not self._ghost_shader:
self._ghost_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader"))
self._ghost_shader.setUniformValue("u_color", Color(32, 32, 32, 96))
for node in DepthFirstIterator(scene.getRoot()):
# We do not want to render ConvexHullNode as it conflicts with the bottom layers.
# However, it is somewhat relevant when the node is selected, so do render it then.
if type(node) is ConvexHullNode and not Selection.isSelected(node.getWatchedNode()):
continue
if not node.render(renderer):
if node.getMeshData() and node.isVisible():
renderer.queueNode(node, transparent = True, shader = self._ghost_shader)
## Hackish way to ensure the proxy is already created, which ensures that the layerview.qml is already created
# as this caused some issues.
def getProxy(self, engine, script_engine):
return self._proxy
def endRendering(self):
pass
def event(self, event):
modifiers = QApplication.keyboardModifiers()
ctrl_is_active = modifiers == Qt.ControlModifier
if event.type == Event.KeyPressEvent and ctrl_is_active:
if event.key == KeyEvent.UpKey:
self._layer_pass.setLayer(self._current_layer_num + 1)
return True
if event.key == KeyEvent.DownKey:
self._layer_pass.setLayer(self._current_layer_num - 1)
return True
if event.type == Event.ViewActivateEvent:
if not self._layer_pass:
# Currently the RenderPass constructor requires a size > 0
# This should be fixed in RenderPass's constructor.
self._layer_pass = LayerPass.LayerPass(1, 1)
self._layer_pass.setLayerView(self)
self.getRenderer().addRenderPass(self._layer_pass)
if not self._layerview_composite_shader:
self._layerview_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("LayerView"), "layerview_composite.shader"))
if not self._composite_pass:
self._composite_pass = self.getRenderer().getRenderPass("composite")
self._old_layer_bindings = self._composite_pass.getLayerBindings()
layer_bindings = self._old_layer_bindings[:] # make a copy
layer_bindings.append("layerview")
self._composite_pass.setLayerBindings(layer_bindings)
self._old_composite_shader = self._composite_pass.getCompositeShader()
self._composite_pass.setCompositeShader(self._layerview_composite_shader)
if event.type == Event.ViewDeactivateEvent:
self._composite_pass.setLayerBindings(self._old_layer_bindings)
self._composite_pass.setCompositeShader(self._old_composite_shader)