Move layerdata and busy handling back into LayerView

This reverts commits 17b12b9048 and 66f8a62e6c.

# Conflicts:
#	plugins/LayerView/LayerPass.py
#	plugins/LayerView/LayerView.py
This commit is contained in:
fieldOfView 2016-09-19 17:59:24 +02:00
parent 155fe326b7
commit 087ad6f472
4 changed files with 226 additions and 218 deletions

View file

@ -1,118 +1,30 @@
# Copyright (c) 2016 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
from UM.Logger import Logger
from UM.Application import Application
from UM.Resources import Resources
from UM.Preferences import Preferences
from UM.Signal import Signal
from UM.Job import Job
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Resources import Resources
from UM.Scene.SceneNode import SceneNode
from UM.Scene.ToolHandle import ToolHandle
from UM.Mesh.MeshBuilder import MeshBuilder
from UM.Application import Application
from UM.View.RenderPass import RenderPass
from UM.View.RenderBatch import RenderBatch
from UM.View.GL.OpenGL import OpenGL
import numpy
## RenderPass used to display g-code paths.
class LayerPass(RenderPass):
def __init__(self, width, height):
super().__init__("layerview", width, height)
self._controller = Application.getInstance().getController()
self._shader = None
self._tool_handle_shader = None
self._gl = OpenGL.getInstance().getBindingsObject()
self._scene = self._controller.getScene()
self._scene = Application.getInstance().getController().getScene()
self._scene.getRoot().childrenChanged.connect(self._onSceneChanged)
self._max_layers = 0
self._current_layer_num = 0
self._current_layer_mesh = None
self._current_layer_jumps = None
self._top_layers_job = None
self._activity = False
self._old_max_layers = 0
self._layer_view = None
self._busy = False
Preferences.getInstance().addPreference("view/top_layer_count", 5)
Preferences.getInstance().addPreference("view/only_show_top_layers", False)
Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged)
self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count"))
self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers"))
busyChanged = Signal()
def isBusy(self):
return self._busy
def setBusy(self, busy):
if busy != self._busy:
self._busy = busy
self.busyChanged.emit()
def getActivity(self):
return self._activity
def getCurrentLayer(self):
return self._current_layer_num
def getMaxLayers(self):
return self._max_layers
def resetLayerData(self):
self._current_layer_mesh = None
self._current_layer_jumps = None
def setLayer(self, 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._startUpdateTopLayers()
self.currentLayerNumChanged.emit()
def calculateMaxLayers(self):
self._activity = True
self._old_max_layers = self._max_layers
## Recalculate num max layers
new_max_layers = 0
for node in DepthFirstIterator(self._scene.getRoot()):
layer_data = node.callDecoration("getLayerData")
if not layer_data:
continue
if new_max_layers < len(layer_data.getLayers()):
new_max_layers = len(layer_data.getLayers()) - 1
if new_max_layers > 0 and new_max_layers != self._old_max_layers:
self._max_layers = new_max_layers
# The qt slider has a bit of weird behavior that the maxvalue needs to be changed first
# if it's the largest value. If we don't do this, we can have a slider block outside of the
# slider.
if new_max_layers > self._current_layer_num:
self.maxLayersChanged.emit()
self.setLayer(int(self._max_layers))
else:
self.setLayer(int(self._max_layers))
self.maxLayersChanged.emit()
self._startUpdateTopLayers()
maxLayersChanged = Signal()
currentLayerNumChanged = Signal()
def setLayerView(self, layerview):
self._layerview = layerview
def render(self):
if not self._shader:
@ -134,12 +46,12 @@ class LayerPass(RenderPass):
continue
# Render all layers below a certain number as line mesh instead of vertices.
if self._current_layer_num - self._solid_layers > -1 and not self._only_show_top_layers:
if self._layerview._current_layer_num - self._layerview._solid_layers > -1 and not self._layerview._only_show_top_layers:
start = 0
end = 0
element_counts = layer_data.getElementCounts()
for layer, counts in element_counts.items():
if layer + self._solid_layers > self._current_layer_num:
if layer + self._layerview._solid_layers > self._layerview._current_layer_num:
break
end += counts
@ -151,11 +63,11 @@ class LayerPass(RenderPass):
# Create a new batch that is not range-limited
batch = RenderBatch(self._shader, type = RenderBatch.RenderType.Solid)
if self._current_layer_mesh:
batch.addItem(node.getWorldTransformation(), self._current_layer_mesh)
if self._layerview._current_layer_mesh:
batch.addItem(node.getWorldTransformation(), self._layerview._current_layer_mesh)
if self._current_layer_jumps:
batch.addItem(node.getWorldTransformation(), self._current_layer_jumps)
if self._layerview._current_layer_jumps:
batch.addItem(node.getWorldTransformation(), self._layerview._current_layer_jumps)
if len(batch.items) > 0:
batch.render(self._scene.getActiveCamera())
@ -165,101 +77,3 @@ class LayerPass(RenderPass):
tool_handle_batch.render(self._scene.getActiveCamera())
self.release()
def _onSceneChanged(self, node):
self.calculateMaxLayers()
def _startUpdateTopLayers(self):
if self._top_layers_job:
self._top_layers_job.finished.disconnect(self._updateCurrentLayerMesh)
self._top_layers_job.cancel()
self.setBusy(True)
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):
self.setBusy(False)
if not job.getResult():
return
self.resetLayerData() # Reset the layer data only when job is done. Doing it now prevents "blinking" data.
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
def _onPreferencesChanged(self, preference):
if preference != "view/top_layer_count" and preference != "view/only_show_top_layers":
return
self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count"))
self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers"))
self._startUpdateTopLayers()
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 layer_data:
break
if self._cancel or not layer_data:
return
layer_mesh = MeshBuilder()
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()
except Exception:
Logger.logException("w", "An exception occurred while creating layer mesh.")
return
if not layer or layer.getVertices() is None:
continue
layer_mesh.addIndices(layer_mesh.getVertexCount() + layer.getIndices())
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 = numpy.ones((1, 4), dtype=numpy.float32) * (2.0 - (i / self._solid_layers)) / 2.0
brightness[0, 3] = 1.0
layer_mesh.addColors(layer.getColors() * brightness)
if self._cancel:
return
Job.yieldThread()
if self._cancel:
return
Job.yieldThread()
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.build(), "jumps": jump_mesh})
def cancel(self):
self._cancel = True
super().cancel()