Move information related to print time etc. into a PrintInformation class

This commit is contained in:
Arjen Hiemstra 2015-04-21 16:50:11 +02:00
parent 1c11104dd2
commit 49e80c30e5
2 changed files with 194 additions and 14 deletions

190
PrintInformation.py Normal file
View File

@ -0,0 +1,190 @@
from PyQt5.QtCore import QObject, QDateTime, QTimer, pyqtSignal, pyqtSlot, pyqtProperty
from UM.Application import Application
from UM.Settings.MachineSettings import MachineSettings
from UM.Resources import Resources
from UM.Scene.SceneNode import SceneNode
## A class for processing and calculating minimum, currrent and maximum print time.
#
# This class contains all the logic relating to calculation and slicing for the
# time/quality slider concept. It is a rather tricky combination of event handling
# and state management. The logic behind this is as follows:
#
# - A scene change or settting change event happens.
# We track what the source was of the change, either a scene change, a setting change, an active machine change or something else.
# - This triggers a new slice with the current settings - this is the "current settings pass".
# - When the slice is done, we update the current print time and material amount.
# - If the source of the slice was not a Setting change, we start the second slice pass, the "low quality settings pass". Otherwise we stop here.
# - When that is done, we update the minimum print time and start the final slcice pass, the "high quality settings pass".
# - When the high quality pass is done, we update the maximum print time.
#
class PrintInformation(QObject):
class SlicePass:
CurrentSettings = 1
LowQualitySettings = 2
HighQualitySettings = 3
class SliceReason:
SceneChanged = 1
SettingChanged = 2
ActiveMachineChanged = 3
Other = 4
def __init__(self, parent = None):
super().__init__(parent)
self._minimum_print_time = QDateTime()
self._current_print_time = QDateTime()
self._maximum_print_time = QDateTime()
self._material_amount = -1
self._time_quality_value = 50
self._time_quality_changed_timer = QTimer()
self._time_quality_changed_timer.setInterval(500)
self._time_quality_changed_timer.setSingleShot(True)
self._time_quality_changed_timer.timeout.connect(self._updateTimeQualitySettings)
self._interpolation_settings = {
"layer_height": { "minimum": "low", "maximum": "high", "curve": "linear" }
}
self._low_quality_settings = None
self._current_settings = None
self._high_quality_settings = None
self._slice_pass = None
self._slice_reason = None
Application.getInstance().activeMachineChanged.connect(self._onActiveMachineChanged)
self._onActiveMachineChanged()
Application.getInstance().getController().getScene().sceneChanged.connect(self._onSceneChanged)
self._backend = Application.getInstance().getBackend()
if self._backend:
self._backend.printDurationMessage.connect(self._onPrintDurationMessage)
self._backend.slicingStarted.connect(self._onSlicingStarted)
minimumPrintTimeChanged = pyqtSignal()
@pyqtProperty(QDateTime, notify = minimumPrintTimeChanged)
def minimumPrintTime(self):
return self._minimum_print_time
currentPrintTimeChanged = pyqtSignal()
@pyqtProperty(QDateTime, notify = currentPrintTimeChanged)
def currentPrintTime(self):
return self._current_print_time
maximumPrintTimeChanged = pyqtSignal()
@pyqtProperty(QDateTime, notify = maximumPrintTimeChanged)
def maximumPrintTime(self):
return self._maximum_print_time
materialAmountChanged = pyqtSignal()
@pyqtProperty(float, notify = materialAmountChanged)
def materialAmount(self):
return self._material_amount
timeQualityValueChanged = pyqtSignal()
@pyqtProperty(int, notify = timeQualityValueChanged)
def timeQualityValue(self):
return self._time_quality_value
@pyqtSlot(int)
def setTimeQualityValue(self, value):
if value != self._time_quality_value:
self._time_quality_value = value
self.timeQualityValueChanged.emit()
self._time_quality_changed_timer.start()
def _onSlicingStarted(self):
if self._slice_pass is None:
self._slice_pass = self.SlicePass.CurrentSettings
if self._slice_reason is None:
self._slice_reason = self.SliceReason.Other
def _onPrintDurationMessage(self, time, amount):
if self._slice_pass == self.SlicePass.CurrentSettings:
self._current_print_time = QDateTime.fromMSecsSinceEpoch(round(time * 1000))
self.currentPrintTimeChanged.emit()
self._material_amount = round(amount / 10) / 100
self.materialAmountChanged.emit()
if self._slice_reason != self.SliceReason.SettingChanged:
self._slice_pass = self.SlicePass.LowQualitySettings
self._backend.slice(settings = self._low_quality_settings, save_gcode = False, save_polygons = False, force_restart = False)
else:
self._slice_pass = None
self._slice_reason = None
elif self._slice_pass == self.SlicePass.LowQualitySettings:
self._minimum_print_time = QDateTime.fromMSecsSinceEpoch(round(time * 1000))
self.minimumPrintTimeChanged.emit()
self._slice_pass = self.SlicePass.HighQualitySettings
self._backend.slice(settings = self._high_quality_settings, save_gcode = False, save_polygons = False, force_restart = False)
elif self._slice_pass == self.SlicePass.HighQualitySettings:
self._maximum_print_time = QDateTime.fromMSecsSinceEpoch(round(time * 1000))
self.maximumPrintTimeChanged.emit()
self._slice_pass = None
self._slice_reason = None
def _onActiveMachineChanged(self):
if self._current_settings:
self._current_settings.settingChanged.disconnect(self._onSettingChanged)
self._current_settings = Application.getInstance().getActiveMachine()
if self._current_settings:
self._current_settings.settingChanged.connect(self._onSettingChanged)
self._low_quality_settings = None
self._high_quality_settings = None
self._updateTimeQualitySettings()
self._slice_reason = self.SliceReason.ActiveMachineChanged
def _updateTimeQualitySettings(self):
if not self._current_settings:
return
if not self._low_quality_settings:
self._low_quality_settings = MachineSettings()
self._low_quality_settings.loadSettingsFromFile(Resources.getPath(Resources.SettingsLocation, self._current_settings.getTypeID() + '.json'))
self._low_quality_settings.loadValuesFromFile(Resources.getPath(Resources.SettingsLocation, 'profiles', 'low_quality.conf'))
if not self._high_quality_settings:
self._high_quality_settings = MachineSettings()
self._high_quality_settings.loadSettingsFromFile(Resources.getPath(Resources.SettingsLocation, self._current_settings.getTypeID() + '.json'))
self._high_quality_settings.loadValuesFromFile(Resources.getPath(Resources.SettingsLocation, 'profiles', 'high_quality.conf'))
for key, options in self._interpolation_settings.items():
minimum_value = None
if options['minimum'] == 'low':
minimum_value = self._low_quality_settings.getSettingValueByKey(key)
elif options['minimum'] == 'high':
minimum_value = self._high_quality_settings.getSettingValueByKey(key)
else:
continue
maximum_value = None
if options['maximum'] == 'low':
maximum_value = self._low_quality_settings.getSettingValueByKey(key)
elif options['maximum'] == 'high':
maximum_value = self._high_quality_settings.getSettingValueByKey(key)
else:
continue
setting_value = minimum_value + (maximum_value - minimum_value) * (self._time_quality_value / 100)
self._current_settings.setSettingValueByKey(key, setting_value)
def _onSceneChanged(self, source):
self._slice_reason = self.SliceReason.SceneChanged
def _onSettingChanged(self, source):
self._slice_reason = self.SliceReason.SettingChanged

View File

@ -23,6 +23,7 @@ from UM.Operations.SetTransformOperation import SetTransformOperation
from PlatformPhysics import PlatformPhysics
from BuildVolume import BuildVolume
from CameraAnimation import CameraAnimation
from PrintInformation import PrintInformation
from PyQt5.QtCore import pyqtSlot, QUrl, Qt, pyqtSignal, pyqtProperty
from PyQt5.QtGui import QColor
@ -56,8 +57,7 @@ class PrinterApplication(QtApplication):
'priority': 0
}
}
self._print_duration = -1
self._print_material_amount = -1
self._print_information = None
self.activeMachineChanged.connect(self._onActiveMachineChanged)
@ -117,8 +117,6 @@ class PrinterApplication(QtApplication):
self.getStorageDevice('LocalFileStorage').removableDrivesChanged.connect(self._removableDrivesChanged)
self.getBackend().printDurationMessage.connect(self._onPrintDurationMessage)
if self.getMachines():
active_machine_pref = Preferences.getInstance().getValue('cura/active_machine')
if active_machine_pref:
@ -139,6 +137,8 @@ class PrinterApplication(QtApplication):
def registerObjects(self, engine):
engine.rootContext().setContextProperty('Printer', self)
self._print_information = PrintInformation()
engine.rootContext().setContextProperty('PrintInformation', self._print_information)
def onSelectionChanged(self):
if Selection.hasSelection():
@ -263,16 +263,6 @@ class PrinterApplication(QtApplication):
return log
printDurationChanged = pyqtSignal()
@pyqtProperty(float, notify = printDurationChanged)
def printDuration(self):
return self._print_duration
@pyqtProperty(float, notify = printDurationChanged)
def printMaterialAmount(self):
return self._print_material_amount
def _onActiveMachineChanged(self):
machine = self.getActiveMachine()
if machine: