mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 07:27:29 -06:00
CURA-4525 refined the condition when to reslice build plates; however from the layer view it (still) doesn't always show the layers
This commit is contained in:
parent
e21acd1a07
commit
c732470169
2 changed files with 74 additions and 41 deletions
|
@ -26,5 +26,8 @@ class BuildPlateDecorator(SceneNodeDecorator):
|
||||||
def getPreviousBuildPlateNumber(self):
|
def getPreviousBuildPlateNumber(self):
|
||||||
return self._previous_build_plate_number
|
return self._previous_build_plate_number
|
||||||
|
|
||||||
|
def removePreviousBuildPlateNumber(self):
|
||||||
|
self._previous_build_plate_number = None
|
||||||
|
|
||||||
def __deepcopy__(self, memo):
|
def __deepcopy__(self, memo):
|
||||||
return BuildPlateDecorator()
|
return BuildPlateDecorator()
|
||||||
|
|
|
@ -16,6 +16,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
from UM.Qt.Duration import DurationFormat
|
from UM.Qt.Duration import DurationFormat
|
||||||
from PyQt5.QtCore import QObject, pyqtSlot
|
from PyQt5.QtCore import QObject, pyqtSlot
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
from . import ProcessSlicedLayersJob
|
from . import ProcessSlicedLayersJob
|
||||||
from . import StartSliceJob
|
from . import StartSliceJob
|
||||||
|
@ -117,7 +118,7 @@ class CuraEngineBackend(QObject, Backend):
|
||||||
|
|
||||||
self._backend_log_max_lines = 20000 # Maximum number of lines to buffer
|
self._backend_log_max_lines = 20000 # Maximum number of lines to buffer
|
||||||
self._error_message = None # Pop-up message that shows errors.
|
self._error_message = None # Pop-up message that shows errors.
|
||||||
self._last_num_objects = 0 # Count number of objects to see if there is something changed
|
self._last_num_objects = defaultdict(int) # Count number of objects to see if there is something changed
|
||||||
self._postponed_scene_change_sources = [] # scene change is postponed (by a tool)
|
self._postponed_scene_change_sources = [] # scene change is postponed (by a tool)
|
||||||
|
|
||||||
self.backendQuit.connect(self._onBackendQuit)
|
self.backendQuit.connect(self._onBackendQuit)
|
||||||
|
@ -192,17 +193,26 @@ class CuraEngineBackend(QObject, Backend):
|
||||||
|
|
||||||
## Perform a slice of the scene.
|
## Perform a slice of the scene.
|
||||||
def slice(self):
|
def slice(self):
|
||||||
Logger.log("d", "starting to slice again!")
|
Logger.log("d", "starting to slice!")
|
||||||
self._slice_start_time = time()
|
self._slice_start_time = time()
|
||||||
if not self._build_plates_to_be_sliced:
|
if not self._build_plates_to_be_sliced:
|
||||||
self.processingProgress.emit(1.0)
|
self.processingProgress.emit(1.0)
|
||||||
self.backendStateChange.emit(BackendState.Done)
|
self.backendStateChange.emit(BackendState.Done)
|
||||||
Logger.log("w", "Slice unnecessary, nothing has changed that needs reslicing.")
|
Logger.log("w", "Slice unnecessary, nothing has changed that needs reslicing.")
|
||||||
return
|
return
|
||||||
if Application.getInstance().getPrintInformation():
|
|
||||||
Application.getInstance().getPrintInformation().setToZeroPrintInformation()
|
# see if we really have to slice
|
||||||
|
build_plate_to_be_sliced = self._build_plates_to_be_sliced.pop(0)
|
||||||
|
num_objects = self._numObjects()
|
||||||
|
if build_plate_to_be_sliced not in num_objects or num_objects[build_plate_to_be_sliced] == 0:
|
||||||
|
Logger.log("d", " ## Build plate %s has 0 objects to be sliced, skipping", build_plate_to_be_sliced)
|
||||||
|
self._invokeSlice()
|
||||||
|
|
||||||
self._stored_layer_data = []
|
self._stored_layer_data = []
|
||||||
|
self._stored_optimized_layer_data[build_plate_to_be_sliced] = []
|
||||||
|
|
||||||
|
if Application.getInstance().getPrintInformation():
|
||||||
|
Application.getInstance().getPrintInformation().setToZeroPrintInformation()
|
||||||
|
|
||||||
if self._process is None:
|
if self._process is None:
|
||||||
self._createSocket()
|
self._createSocket()
|
||||||
|
@ -218,8 +228,7 @@ class CuraEngineBackend(QObject, Backend):
|
||||||
|
|
||||||
slice_message = self._socket.createMessage("cura.proto.Slice")
|
slice_message = self._socket.createMessage("cura.proto.Slice")
|
||||||
self._start_slice_job = StartSliceJob.StartSliceJob(slice_message)
|
self._start_slice_job = StartSliceJob.StartSliceJob(slice_message)
|
||||||
self._start_slice_job_build_plate = self._build_plates_to_be_sliced.pop(0)
|
self._start_slice_job_build_plate = build_plate_to_be_sliced
|
||||||
self._stored_optimized_layer_data[self._start_slice_job_build_plate] = []
|
|
||||||
self._start_slice_job.setBuildPlate(self._start_slice_job_build_plate)
|
self._start_slice_job.setBuildPlate(self._start_slice_job_build_plate)
|
||||||
self._start_slice_job.start()
|
self._start_slice_job.start()
|
||||||
self._start_slice_job.finished.connect(self._onStartSliceCompleted)
|
self._start_slice_job.finished.connect(self._onStartSliceCompleted)
|
||||||
|
@ -364,40 +373,62 @@ class CuraEngineBackend(QObject, Backend):
|
||||||
self.disableTimer()
|
self.disableTimer()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
## Return a dict with number of objects per build plate
|
||||||
|
def _numObjects(self):
|
||||||
|
num_objects = defaultdict(int)
|
||||||
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
|
# Only count sliceable objects
|
||||||
|
if node.callDecoration("isSliceable"):
|
||||||
|
build_plate_number = node.callDecoration("getBuildPlateNumber")
|
||||||
|
num_objects[build_plate_number] += 1
|
||||||
|
return num_objects
|
||||||
|
|
||||||
## Listener for when the scene has changed.
|
## Listener for when the scene has changed.
|
||||||
#
|
#
|
||||||
# This should start a slice if the scene is now ready to slice.
|
# This should start a slice if the scene is now ready to slice.
|
||||||
#
|
#
|
||||||
# \param source The scene node that was changed.
|
# \param source The scene node that was changed.
|
||||||
def _onSceneChanged(self, source):
|
def _onSceneChanged(self, source):
|
||||||
Logger.log("d", " ##### scene changed: %s", source)
|
|
||||||
if not issubclass(type(source), SceneNode):
|
if not issubclass(type(source), SceneNode):
|
||||||
return
|
return
|
||||||
|
|
||||||
root_scene_nodes_changed = False
|
build_plate_changed = set()
|
||||||
build_plates_changed = set()
|
source_build_plate_number = source.callDecoration("getBuildPlateNumber")
|
||||||
if source == self._scene.getRoot():
|
if source == self._scene.getRoot():
|
||||||
num_objects = 0
|
# we got the root node
|
||||||
|
num_objects = self._numObjects()
|
||||||
|
# num_objects = defaultdict(int)
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
# Only count sliceable objects
|
# # Only count sliceable objects
|
||||||
if node.callDecoration("isSliceable"):
|
# if node.callDecoration("isSliceable"):
|
||||||
num_objects += 1
|
# build_plate_number = node.callDecoration("getBuildPlateNumber")
|
||||||
build_plates_changed.add(node.callDecoration("getBuildPlateNumber"))
|
# num_objects[build_plate_number] += 1
|
||||||
build_plates_changed.add(node.callDecoration("getPreviousBuildPlateNumber"))
|
node.callDecoration("removePreviousBuildPlateNumber") # use the previous build plate number one time
|
||||||
if num_objects != self._last_num_objects:
|
for build_plate_number in list(self._last_num_objects.keys()) + list(num_objects.keys()):
|
||||||
self._last_num_objects = num_objects
|
if build_plate_number not in self._last_num_objects or num_objects[build_plate_number] != self._last_num_objects[build_plate_number]:
|
||||||
root_scene_nodes_changed = True
|
self._last_num_objects[build_plate_number] = num_objects[build_plate_number]
|
||||||
# else:
|
build_plate_changed.add(build_plate_number)
|
||||||
# return # ??
|
else:
|
||||||
build_plates_changed.discard(None)
|
# we got a single scenenode, how do we know if it's changed?
|
||||||
build_plates_changed.discard(-1) # object not on build plate
|
# build_plate_changed.add(source_build_plate_number)
|
||||||
Logger.log("d", " #### build plates changed: %s", build_plates_changed)
|
# build_plate_changed.add(source.callDecoration("getPreviousBuildPlateNumber"))
|
||||||
|
# source.callDecoration("removePreviousBuildPlateNumber") # use the previous build plate number one time
|
||||||
|
if not source.callDecoration("isGroup"):
|
||||||
|
if source.getMeshData() is None:
|
||||||
|
return
|
||||||
|
if source.getMeshData().getVertices() is None:
|
||||||
|
return
|
||||||
|
|
||||||
# if not source.callDecoration("isGroup") and not root_scene_nodes_changed:
|
# we got a single object and it passed all the tests of being changed
|
||||||
# if source.getMeshData() is None:
|
build_plate_changed.add(source_build_plate_number)
|
||||||
# return
|
build_plate_changed.add(source.callDecoration("getPreviousBuildPlateNumber"))
|
||||||
# if source.getMeshData().getVertices() is None:
|
source.callDecoration("removePreviousBuildPlateNumber") # use the previous build plate number one time
|
||||||
# return
|
|
||||||
|
build_plate_changed.discard(None)
|
||||||
|
build_plate_changed.discard(-1) # object not on build plate
|
||||||
|
if not build_plate_changed:
|
||||||
|
return
|
||||||
|
# Logger.log("d", " #### build plates changed: %s", build_plate_changed)
|
||||||
|
|
||||||
if self._tool_active:
|
if self._tool_active:
|
||||||
# do it later, each source only has to be done once
|
# do it later, each source only has to be done once
|
||||||
|
@ -405,17 +436,16 @@ class CuraEngineBackend(QObject, Backend):
|
||||||
self._postponed_scene_change_sources.append(source)
|
self._postponed_scene_change_sources.append(source)
|
||||||
return
|
return
|
||||||
|
|
||||||
if build_plates_changed:
|
Logger.log("d", " going to reslice: %s", build_plate_changed)
|
||||||
Logger.log("d", " going to reslice")
|
|
||||||
self.stopSlicing()
|
self.stopSlicing()
|
||||||
for build_plate_number in build_plates_changed:
|
for build_plate_number in build_plate_changed:
|
||||||
if build_plate_number not in self._build_plates_to_be_sliced:
|
if build_plate_number not in self._build_plates_to_be_sliced:
|
||||||
self._build_plates_to_be_sliced.append(build_plate_number)
|
self._build_plates_to_be_sliced.append(build_plate_number)
|
||||||
self.processingProgress.emit(0.0)
|
self.processingProgress.emit(0.0)
|
||||||
self.backendStateChange.emit(BackendState.NotStarted)
|
self.backendStateChange.emit(BackendState.NotStarted)
|
||||||
if not self._use_timer:
|
if not self._use_timer:
|
||||||
# With manually having to slice, we want to clear the old invalid layer data.
|
# With manually having to slice, we want to clear the old invalid layer data.
|
||||||
self._clearLayerData(build_plates_changed)
|
self._clearLayerData(build_plate_changed)
|
||||||
|
|
||||||
self._invokeSlice()
|
self._invokeSlice()
|
||||||
|
|
||||||
|
@ -445,7 +475,7 @@ class CuraEngineBackend(QObject, Backend):
|
||||||
def _clearLayerData(self, build_plate_numbers = set()):
|
def _clearLayerData(self, build_plate_numbers = set()):
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
if node.callDecoration("getLayerData"):
|
if node.callDecoration("getLayerData"):
|
||||||
if node.callDecoration("getBuildPlateNumber") in build_plate_numbers or not build_plate_numbers:
|
if not build_plate_numbers or node.callDecoration("getBuildPlateNumber") in build_plate_numbers:
|
||||||
node.getParent().removeChild(node)
|
node.getParent().removeChild(node)
|
||||||
|
|
||||||
def markSliceAll(self):
|
def markSliceAll(self):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue