Implemented feature described by #30

This commit is contained in:
Jaime van Kessel 2015-06-05 17:40:57 +02:00
parent 33c69b32f8
commit a2c099a7d8
4 changed files with 128 additions and 21 deletions

View File

@ -5,6 +5,9 @@ from UM.View.View import View
from UM.View.Renderer import Renderer from UM.View.Renderer import Renderer
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Resources import Resources from UM.Resources import Resources
from UM.Event import Event, KeyEvent
from UM.Signal import Signal
from . import LayerViewProxy
## View used to display g-code paths. ## View used to display g-code paths.
class LayerView(View): class LayerView(View):
@ -13,11 +16,27 @@ class LayerView(View):
self._material = None self._material = None
self._num_layers = 0 self._num_layers = 0
self._layer_percentage = 0 # what percentage of layers need to be shown (SLider gives value between 0 - 100) self._layer_percentage = 0 # what percentage of layers need to be shown (SLider gives value between 0 - 100)
self._current_layer_num = 0
self._proxy = LayerViewProxy.LayerViewProxy()
self._controller.getScene().sceneChanged.connect(self._onSceneChanged)
self._max_layers = 10
def getCurrentLayer(self):
return self._current_layer_num
def _onSceneChanged(self, node):
self.calculateMaxLayers()
def getMaxLayers(self):
return self._max_layers
def beginRendering(self): def beginRendering(self):
scene = self.getController().getScene() scene = self.getController().getScene()
renderer = self.getRenderer() renderer = self.getRenderer()
renderer.setRenderSelection(False) renderer.setRenderSelection(False)
## Recalculate num max layers
#self.calculateMaxLayers()
if not self._material: if not self._material:
self._material = renderer.createMaterial(Resources.getPath(Resources.ShadersLocation, "basic.vert"), Resources.getPath(Resources.ShadersLocation, "vertexcolor.frag")) self._material = renderer.createMaterial(Resources.getPath(Resources.ShadersLocation, "basic.vert"), Resources.getPath(Resources.ShadersLocation, "vertexcolor.frag"))
@ -31,26 +50,65 @@ class LayerView(View):
except AttributeError: except AttributeError:
continue continue
if self._layer_percentage < 100: start = 0
start = 0 end = 0
end_layer = round(len(layer_data.getLayers()) * (self._layer_percentage / 100))
end = 0
element_counts = layer_data.getElementCounts() element_counts = layer_data.getElementCounts()
for layer, counts in element_counts.items(): for layer, counts in element_counts.items():
end += sum(counts) end += sum(counts)
## Hack to ensure the end is correct. Not quite sure what causes this ## Hack to ensure the end is correct. Not quite sure what causes this
end += 2 * len(counts) end += 2 * len(counts)
if layer >= end_layer: if layer >= self._current_layer_num:
break break
renderer.queueNode(node, mesh = layer_data, material = self._material, mode = Renderer.RenderLines, start = start, end = end)
renderer.queueNode(node, mesh = layer_data, material = self._material, mode = Renderer.RenderLines, start = start, end = end)
else:
renderer.queueNode(node, mesh = layer_data, material = self._material, mode = Renderer.RenderLines)
def setLayer(self, value): def setLayer(self, value):
self._layer_percentage = value if self._current_layer_num != value:
self._current_layer_num = value
if self._current_layer_num < 0:
self._current_layer_num = 0
if self._current_layer_num > self._max_layers:
self._current_layer_num = self._max_layers
self.currentLayerNumChanged.emit()
currentLayerNumChanged = Signal()
def calculateMaxLayers(self):
scene = self.getController().getScene()
renderer = self.getRenderer()
if renderer and self._material:
renderer.setRenderSelection(False)
self._old_max_layers = self._max_layers
## Recalculate num max layers
self._max_layers = 0
for node in DepthFirstIterator(scene.getRoot()):
if not node.render(renderer):
if node.getMeshData() and node.isVisible():
try:
layer_data = node.getMeshData().layerData
except AttributeError:
continue
if self._max_layers < len(layer_data.getLayers()):
self._max_layers = len(layer_data.getLayers())
if self._max_layers != self._old_max_layers:
self.maxLayersChanged.emit()
maxLayersChanged = Signal()
## 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): def endRendering(self):
pass pass
def event(self, event):
if event.type == Event.KeyPressEvent:
if event.key == KeyEvent.UpKey:
self.setLayer(self._current_layer_num + 1)
if event.key == KeyEvent.DownKey:
self.setLayer(self._current_layer_num - 1)

View File

@ -20,10 +20,10 @@ Item
anchors.right : parent.right anchors.right : parent.right
orientation: Qt.Vertical orientation: Qt.Vertical
minimumValue: 0; minimumValue: 0;
maximumValue: 100; maximumValue: UM.LayerView.numLayers;
value: 100; value: UM.LayerView.currentLayer
onValueChanged: UM.ActiveView.triggerAction("setLayer", value) onValueChanged: UM.LayerView.setCurrentLayer(value)
style: UM.Theme.styles.slider; style: UM.Theme.styles.slider;
} }

View File

@ -0,0 +1,44 @@
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty
from UM.Application import Application
import LayerView
class LayerViewProxy(QObject):
def __init__(self, parent = None):
super().__init__(parent)
self._current_layer = 0
self._controller = Application.getInstance().getController()
self._controller.activeViewChanged.connect(self._onActiveViewChanged)
self._onActiveViewChanged()
currentLayerChanged = pyqtSignal()
maxLayersChanged = pyqtSignal()
@pyqtProperty(int, notify = maxLayersChanged)
def numLayers(self):
active_view = self._controller.getActiveView()
#print("num max layers " , active_view.getMaxLayers())
return active_view.getMaxLayers()
#return 100
@pyqtProperty(int, notify = currentLayerChanged)
def currentLayer(self):
active_view = self._controller.getActiveView()
if type(active_view) == LayerView.LayerView.LayerView:
return active_view.getCurrentLayer()
@pyqtSlot(int)
def setCurrentLayer(self, layer_num):
active_view = self._controller.getActiveView()
if type(active_view) == LayerView.LayerView.LayerView:
active_view.setLayer(layer_num)
def _onLayerChanged(self):
self.currentLayerChanged.emit()
def _onMaxLayersChanged(self):
self.maxLayersChanged.emit()
def _onActiveViewChanged(self):
active_view = self._controller.getActiveView()
if type(active_view) == LayerView.LayerView.LayerView:
active_view.currentLayerNumChanged.connect(self._onLayerChanged)
active_view.maxLayersChanged.connect(self._onMaxLayersChanged)

View File

@ -1,7 +1,8 @@
# Copyright (c) 2015 Ultimaker B.V. # Copyright (c) 2015 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher. # Cura is released under the terms of the AGPLv3 or higher.
from . import LayerView from . import LayerView, LayerViewProxy
from PyQt5.QtQml import qmlRegisterType, qmlRegisterSingletonType
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
@ -21,6 +22,10 @@ def getMetaData():
} }
} }
def createLayerViewProxy(engine, script_engine):
return LayerViewProxy.LayerViewProxy()
def register(app): def register(app):
layer_view = LayerView.LayerView()
qmlRegisterSingletonType(LayerViewProxy.LayerViewProxy, "UM", 1, 0, "LayerView", layer_view.getProxy)
return { "view": LayerView.LayerView() } return { "view": LayerView.LayerView() }