diff --git a/plugins/LayerView/LayerView.py b/plugins/LayerView/LayerView.py index 78917e4e18..6261c4d706 100644 --- a/plugins/LayerView/LayerView.py +++ b/plugins/LayerView/LayerView.py @@ -10,13 +10,15 @@ from UM.Signal import Signal from UM.Scene.Selection import Selection from UM.Math.Color import Color from UM.Mesh.MeshData import MeshData +from UM.Job import Job from UM.View.RenderBatch import RenderBatch from UM.View.GL.OpenGL import OpenGL from cura.ConvexHullNode import ConvexHullNode -from PyQt5 import QtCore, QtWidgets +from PyQt5.QtCore import Qt, QTimer +from PyQt5.QtWidgets import QApplication from . import LayerViewProxy @@ -34,19 +36,25 @@ class LayerView(View): self._current_layer_num = 10 self._current_layer_mesh = None self._current_layer_jumps = None + self._top_layers_job = None self._activity = False self._solid_layers = 5 + self._top_layer_timer = QTimer() + self._top_layer_timer.setInterval(50) + self._top_layer_timer.setSingleShot(True) + self._top_layer_timer.timeout.connect(self._startUpdateTopLayers) + def getActivity(self): return self._activity def getCurrentLayer(self): return self._current_layer_num - + def _onSceneChanged(self, node): self.calculateMaxLayers() - + def getMaxLayers(self): return self._max_layers @@ -89,51 +97,11 @@ class LayerView(View): # This uses glDrawRangeElements internally to only draw a certain range of lines. renderer.queueNode(node, mesh = layer_data, mode = RenderBatch.RenderMode.Lines, range = (start, end)) - # We currently recreate the current "solid" layers every time a - if not self._current_layer_mesh: - self._current_layer_mesh = MeshData() - for i in range(self._solid_layers): - layer = self._current_layer_num - i - if layer < 0: - continue - try: - layer_mesh = layer_data.getLayer(layer).createMesh() - if not layer_mesh or layer_mesh.getVertices() is None: - continue - except: - continue - if self._current_layer_mesh: #Threading thing; Switching between views can cause the current layer mesh to be deleted. - self._current_layer_mesh.addVertices(layer_mesh.getVertices()) - - # Scale layer color by a brightness factor based on the current layer number - # This will result in a range of 0.5 - 1.0 to multiply colors by. - brightness = (2.0 - (i / self._solid_layers)) / 2.0 - if self._current_layer_mesh: - self._current_layer_mesh.addColors(layer_mesh.getColors() * brightness) if self._current_layer_mesh: renderer.queueNode(node, mesh = self._current_layer_mesh) - if not self._current_layer_jumps: - self._current_layer_jumps = MeshData() - for i in range(1): - layer = self._current_layer_num - i - if layer < 0: - continue - try: - layer_mesh = layer_data.getLayer(layer).createJumps() - if not layer_mesh or layer_mesh.getVertices() is None: - continue - except: - continue - - self._current_layer_jumps.addVertices(layer_mesh.getVertices()) - - # Scale layer color by a brightness factor based on the current layer number - # This will result in a range of 0.5 - 1.0 to multiply colors by. - brightness = (2.0 - (i / self._solid_layers)) / 2.0 - self._current_layer_jumps.addColors(layer_mesh.getColors() * brightness) - - renderer.queueNode(node, mesh = self._current_layer_jumps) + if self._current_layer_jumps: + renderer.queueNode(node, mesh = self._current_layer_jumps) def setLayer(self, value): if self._current_layer_num != value: @@ -145,6 +113,14 @@ class LayerView(View): self._current_layer_mesh = None self._current_layer_jumps = None + + self._top_layer_timer.start() + + if self._top_layers_job: + self._top_layers_job.finished.disconnect(self._updateCurrentLayerMesh) + self._top_layers_job.cancel() + self._top_layers_job = None + self.currentLayerNumChanged.emit() currentLayerNumChanged = Signal() @@ -180,18 +156,18 @@ class LayerView(View): maxLayersChanged = Signal() currentLayerNumChanged = 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): pass - + def event(self, event): - modifiers = QtWidgets.QApplication.keyboardModifiers() - ctrl_is_active = modifiers == QtCore.Qt.ControlModifier + modifiers = QApplication.keyboardModifiers() + ctrl_is_active = modifiers == Qt.ControlModifier if event.type == Event.KeyPressEvent and ctrl_is_active: if event.key == KeyEvent.UpKey: self.setLayer(self._current_layer_num + 1) @@ -199,3 +175,70 @@ class LayerView(View): if event.key == KeyEvent.DownKey: self.setLayer(self._current_layer_num - 1) return True + + def _startUpdateTopLayers(self): + self._top_layers_job = _CreateTopLayersJob(self._controller.getScene(), self._current_layer_num, self._solid_layers) + self._top_layers_job.finished.connect(self._updateCurrentLayerMesh) + self._top_layers_job.start() + + def _updateCurrentLayerMesh(self, job): + if not job.getResult(): + return + + self._current_layer_mesh = job.getResult().get("layers") + self._current_layer_jumps = job.getResult().get("jumps") + self._controller.getScene().sceneChanged.emit(self._controller.getScene().getRoot()) + + self._top_layers_job = None + +class _CreateTopLayersJob(Job): + def __init__(self, scene, layer_number, solid_layers): + super().__init__() + + self._scene = scene + self._layer_number = layer_number + self._solid_layers = solid_layers + self._cancel = False + + def run(self): + layer_data = None + for node in DepthFirstIterator(self._scene.getRoot()): + layer_data = node.callDecoration("getLayerData") + if not layer_data: + continue + + if self._cancel or not layer_data: + return + + layer_mesh = MeshData() + for i in range(self._solid_layers): + layer_number = self._layer_number - i + if layer_number < 0: + continue + #try: + layer = layer_data.getLayer(layer_number).createMesh() + if not layer or layer.getVertices() is None: + continue + + layer_mesh.addVertices(layer.getVertices()) + + # Scale layer color by a brightness factor based on the current layer number + # This will result in a range of 0.5 - 1.0 to multiply colors by. + brightness = (2.0 - (i / self._solid_layers)) / 2.0 + layer_mesh.addColors(layer.getColors() * brightness) + + if self._cancel: + return + + if self._cancel: + return + + jump_mesh = layer_data.getLayer(self._layer_number).createJumps() + if not jump_mesh or jump_mesh.getVertices() is None: + jump_mesh = None + + self.setResult({ "layers": layer_mesh, "jumps": jump_mesh }) + + def cancel(self): + self._cancel = True + super().cancel()