mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-24 07:03:56 -06:00
Move setting error checking to StartSliceJob and allow the job to return a proper response
Now the job can determine if we can continue with slicing or not and if not, why not. This also means we can now show a message when we cannot find any slicable objects. Contributes to CURA-1278
This commit is contained in:
parent
cd2b853fff
commit
8039184c18
3 changed files with 56 additions and 38 deletions
|
@ -82,7 +82,7 @@ class CuraEngineBackend(Backend):
|
||||||
self._always_restart = True #Always restart the engine when starting a new slice. Don't keep the process running. TODO: Fix engine statelessness.
|
self._always_restart = True #Always restart the engine when starting a new slice. Don't keep the process running. TODO: Fix engine statelessness.
|
||||||
self._process_layers_job = None #The currently active job to process layers, or None if it is not processing layers.
|
self._process_layers_job = None #The currently active job to process layers, or None if it is not processing layers.
|
||||||
|
|
||||||
self._message = None #Pop-up message that shows the slicing progress bar (or an error message).
|
self._error_message = None #Pop-up message that shows errors.
|
||||||
|
|
||||||
self.backendQuit.connect(self._onBackendQuit)
|
self.backendQuit.connect(self._onBackendQuit)
|
||||||
self.backendConnected.connect(self._onBackendConnected)
|
self.backendConnected.connect(self._onBackendConnected)
|
||||||
|
@ -134,26 +134,8 @@ class CuraEngineBackend(Backend):
|
||||||
self._process_layers_job.abort()
|
self._process_layers_job.abort()
|
||||||
self._process_layers_job = None
|
self._process_layers_job = None
|
||||||
|
|
||||||
# #Don't slice if there is a setting with an error value.
|
if self._error_message:
|
||||||
# stack = Application.getInstance().getGlobalContainerStack()
|
self._error_message.hide()
|
||||||
# for key in stack.getAllKeys():
|
|
||||||
# validation_state = stack.getProperty(key, "validationState")
|
|
||||||
# #Only setting instances have a validation state, so settings which
|
|
||||||
# #are not overwritten by any instance will have none. The property
|
|
||||||
# #then, and only then, evaluates to None. We make the assumption that
|
|
||||||
# #the definition defines the setting with a default value that is
|
|
||||||
# #valid. Therefore we can allow both ValidatorState.Valid and None as
|
|
||||||
# #allowable validation states.
|
|
||||||
# #TODO: This assumption is wrong! If the definition defines an inheritance function that through inheritance evaluates to a disallowed value, a setting is still invalid even though it's default!
|
|
||||||
# #TODO: Therefore we must also validate setting definitions.
|
|
||||||
# if validation_state != None and validation_state != ValidatorState.Valid:
|
|
||||||
# Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state)
|
|
||||||
# if self._message: #Hide any old message before creating a new one.
|
|
||||||
# self._message.hide()
|
|
||||||
# self._message = None
|
|
||||||
# self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors."))
|
|
||||||
# self._message.show()
|
|
||||||
# return
|
|
||||||
|
|
||||||
self.processingProgress.emit(0.0)
|
self.processingProgress.emit(0.0)
|
||||||
self.backendStateChange.emit(BackendState.NotStarted)
|
self.backendStateChange.emit(BackendState.NotStarted)
|
||||||
|
@ -200,12 +182,31 @@ class CuraEngineBackend(Backend):
|
||||||
# Note that cancelled slice jobs can still call this method.
|
# Note that cancelled slice jobs can still call this method.
|
||||||
if self._start_slice_job is job:
|
if self._start_slice_job is job:
|
||||||
self._start_slice_job = None
|
self._start_slice_job = None
|
||||||
if job.isCancelled() or job.getError() or job.getResult() != True:
|
|
||||||
|
if job.isCancelled() or job.getError() or job.getResult() == StartSliceJob.StartJobResult.Error:
|
||||||
return
|
return
|
||||||
else:
|
|
||||||
# Preparation completed, send it to the backend.
|
if job.getResult() == StartSliceJob.StartJobResult.SettingError:
|
||||||
self._socket.sendMessage(job.getSettingsMessage())
|
if Application.getInstance().getPlatformActivity:
|
||||||
self._socket.sendMessage(job.getSliceMessage())
|
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors."), lifetime = 10)
|
||||||
|
self._error_message.show()
|
||||||
|
self.backendStateChange.emit(BackendState.Error)
|
||||||
|
else:
|
||||||
|
self.backendStateChange.emit(BackendState.NotStarted)
|
||||||
|
return
|
||||||
|
|
||||||
|
if job.getResult() == StartSliceJob.StartJobResult.NothingToSlice:
|
||||||
|
if Application.getInstance().getPlatformActivity:
|
||||||
|
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice. No suitable objects found."), lifetime = 10)
|
||||||
|
self._error_message.show()
|
||||||
|
self.backendStateChange.emit(BackendState.Error)
|
||||||
|
else:
|
||||||
|
self.backendStateChange.emit(BackendState.NotStarted)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Preparation completed, send it to the backend.
|
||||||
|
self._socket.sendMessage(job.getSettingsMessage())
|
||||||
|
self._socket.sendMessage(job.getSliceMessage())
|
||||||
|
|
||||||
## Listener for when the scene has changed.
|
## Listener for when the scene has changed.
|
||||||
#
|
#
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import numpy
|
import numpy
|
||||||
from string import Formatter
|
from string import Formatter
|
||||||
import traceback
|
import traceback
|
||||||
|
from enum import IntEnum
|
||||||
|
|
||||||
from UM.Job import Job
|
from UM.Job import Job
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
|
@ -12,8 +13,15 @@ from UM.Logger import Logger
|
||||||
from UM.Scene.SceneNode import SceneNode
|
from UM.Scene.SceneNode import SceneNode
|
||||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
|
|
||||||
|
from UM.Settings.Validator import ValidatorState
|
||||||
|
|
||||||
from cura.OneAtATimeIterator import OneAtATimeIterator
|
from cura.OneAtATimeIterator import OneAtATimeIterator
|
||||||
|
|
||||||
|
class StartJobResult(IntEnum):
|
||||||
|
Finished = 1
|
||||||
|
Error = 2
|
||||||
|
SettingError = 3
|
||||||
|
NothingToSlice = 4
|
||||||
|
|
||||||
## Formatter class that handles token expansion in start/end gcod
|
## Formatter class that handles token expansion in start/end gcod
|
||||||
class GcodeStartEndFormatter(Formatter):
|
class GcodeStartEndFormatter(Formatter):
|
||||||
|
@ -48,9 +56,19 @@ class StartSliceJob(Job):
|
||||||
def run(self):
|
def run(self):
|
||||||
stack = Application.getInstance().getGlobalContainerStack()
|
stack = Application.getInstance().getGlobalContainerStack()
|
||||||
if not stack:
|
if not stack:
|
||||||
self.setResult(False)
|
self.setResult(StartJobResult.Error)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
#Don't slice if there is a setting with an error value.
|
||||||
|
for key in stack.getAllKeys():
|
||||||
|
validation_state = stack.getProperty(key, "validationState")
|
||||||
|
if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
|
||||||
|
Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state)
|
||||||
|
self.setResult(StartJobResult.SettingError)
|
||||||
|
return
|
||||||
|
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
with self._scene.getSceneLock():
|
with self._scene.getSceneLock():
|
||||||
# Remove old layer data.
|
# Remove old layer data.
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
|
@ -91,6 +109,7 @@ class StartSliceJob(Job):
|
||||||
object_groups.append(temp_list)
|
object_groups.append(temp_list)
|
||||||
|
|
||||||
if not object_groups:
|
if not object_groups:
|
||||||
|
self.setResult(StartJobResult.NothingToSlice)
|
||||||
return
|
return
|
||||||
|
|
||||||
self._buildGlobalSettingsMessage(stack)
|
self._buildGlobalSettingsMessage(stack)
|
||||||
|
@ -116,7 +135,7 @@ class StartSliceJob(Job):
|
||||||
|
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
|
|
||||||
self.setResult(True)
|
self.setResult(StartJobResult.Finished)
|
||||||
|
|
||||||
def cancel(self):
|
def cancel(self):
|
||||||
super().cancel()
|
super().cancel()
|
||||||
|
@ -131,7 +150,7 @@ class StartSliceJob(Job):
|
||||||
fmt = GcodeStartEndFormatter()
|
fmt = GcodeStartEndFormatter()
|
||||||
return str(fmt.format(value, **settings)).encode("utf-8")
|
return str(fmt.format(value, **settings)).encode("utf-8")
|
||||||
except:
|
except:
|
||||||
Logger.log("w", "Unabled to do token replacement on start/end gcode %s", traceback.format_exc())
|
Logger.logException("w", "Unable to do token replacement on start/end gcode")
|
||||||
return str(value).encode("utf-8")
|
return str(value).encode("utf-8")
|
||||||
|
|
||||||
## Sends all global settings to the engine.
|
## Sends all global settings to the engine.
|
||||||
|
|
|
@ -21,16 +21,14 @@ Rectangle {
|
||||||
property string fileBaseName
|
property string fileBaseName
|
||||||
property string statusText:
|
property string statusText:
|
||||||
{
|
{
|
||||||
|
if(!activity)
|
||||||
|
{
|
||||||
|
return catalog.i18nc("@label:PrintjobStatus", "Please load a 3d model");
|
||||||
|
}
|
||||||
|
|
||||||
if(base.backendState == 1)
|
if(base.backendState == 1)
|
||||||
{
|
{
|
||||||
if(!activity)
|
return catalog.i18nc("@label:PrintjobStatus", "Preparing to slice...");
|
||||||
{
|
|
||||||
return catalog.i18nc("@label:PrintjobStatus", "Please load a 3d model");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return catalog.i18nc("@label:PrintjobStatus", "Preparing to slice...");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(base.backendState == 2)
|
else if(base.backendState == 2)
|
||||||
{
|
{
|
||||||
|
@ -42,7 +40,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
else if(base.backendState == 4)
|
else if(base.backendState == 4)
|
||||||
{
|
{
|
||||||
return catalog.i18nc("@label:PrintjobStatus", "Unable to slice due to errors")
|
return catalog.i18nc("@label:PrintjobStatus", "Unable to Slice")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue