CURA-4525 made PrintInformation multi buildplate-aware

This commit is contained in:
Jack Ha 2017-11-14 16:35:37 +01:00
parent f6c7ffac11
commit 4a893c048e
4 changed files with 81 additions and 38 deletions

View file

@ -15,7 +15,7 @@ class BuildPlateModel(ListModel):
Application.getInstance().getController().getScene().sceneChanged.connect(self.updateMaxBuildPlate) # it may be a bit inefficient when changing a lot simultaneously
self._max_build_plate = 1 # default
self._active_build_plate = 0
self._active_build_plate = -1
@pyqtSlot(int)
def setActiveBuildPlate(self, nr):

View file

@ -758,6 +758,8 @@ class CuraApplication(QtApplication):
def getBuildPlateModel(self, *args):
if self._build_plate_model is None:
self._build_plate_model = BuildPlateModel.createBuildPlateModel()
self._build_plate_model.setActiveBuildPlate(0) # default value
return self._build_plate_model
def getSettingInheritanceManager(self, *args):

View file

@ -53,10 +53,10 @@ class PrintInformation(QObject):
self.initializeCuraMessagePrintTimeProperties()
self._material_lengths = []
self._material_weights = []
self._material_costs = []
self._material_names = []
self._material_lengths = {} # indexed by build plate number
self._material_weights = {}
self._material_costs = {}
self._material_names = {}
self._pre_sliced = False
@ -68,10 +68,13 @@ class PrintInformation(QObject):
self._abbr_machine = ""
self._job_name = ""
self._project_name = ""
self._active_build_plate = 0
self._initVariablesWithBuildPlate(self._active_build_plate)
Application.getInstance().globalContainerStackChanged.connect(self._updateJobName)
Application.getInstance().fileLoaded.connect(self.setBaseName)
Application.getInstance().projectFileLoaded.connect(self.setProjectName)
Application.getInstance().getBuildPlateModel().activeBuildPlateChanged.connect(self._onActiveBuildPlateChanged)
Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged)
self._active_material_container = None
@ -83,7 +86,7 @@ class PrintInformation(QObject):
# Crate cura message translations and using translation keys initialize empty time Duration object for total time
# and time for each feature
def initializeCuraMessagePrintTimeProperties(self):
self._current_print_time = Duration(None, self)
self._current_print_time = {} # Duration(None, self)
self._print_time_message_translations = {
"inset_0": catalog.i18nc("@tooltip", "Outer Wall"),
@ -101,10 +104,26 @@ class PrintInformation(QObject):
self._print_time_message_values = {}
# Full fill message values using keys from _print_time_message_translations
for key in self._print_time_message_translations.keys():
self._print_time_message_values[key] = Duration(None, self)
def _initPrintTimeMessageValues(self, build_plate_number):
# Full fill message values using keys from _print_time_message_translations
self._print_time_message_values[build_plate_number] = {}
for key in self._print_time_message_translations.keys():
self._print_time_message_values[build_plate_number][key] = Duration(None, self)
def _initVariablesWithBuildPlate(self, build_plate_number):
if build_plate_number not in self._print_time_message_values:
self._initPrintTimeMessageValues(build_plate_number)
if self._active_build_plate not in self._material_lengths:
self._material_lengths[self._active_build_plate] = []
if self._active_build_plate not in self._material_weights:
self._material_weights[self._active_build_plate] = []
if self._active_build_plate not in self._material_costs:
self._material_costs[self._active_build_plate] = []
if self._active_build_plate not in self._material_names:
self._material_names[self._active_build_plate] = []
if self._active_build_plate not in self._current_print_time:
self._current_print_time[self._active_build_plate] = Duration(None, self)
currentPrintTimeChanged = pyqtSignal()
@ -120,53 +139,58 @@ class PrintInformation(QObject):
@pyqtProperty(Duration, notify = currentPrintTimeChanged)
def currentPrintTime(self):
return self._current_print_time
return self._current_print_time[self._active_build_plate]
materialLengthsChanged = pyqtSignal()
@pyqtProperty("QVariantList", notify = materialLengthsChanged)
def materialLengths(self):
return self._material_lengths
return self._material_lengths[self._active_build_plate]
materialWeightsChanged = pyqtSignal()
@pyqtProperty("QVariantList", notify = materialWeightsChanged)
def materialWeights(self):
return self._material_weights
return self._material_weights[self._active_build_plate]
materialCostsChanged = pyqtSignal()
@pyqtProperty("QVariantList", notify = materialCostsChanged)
def materialCosts(self):
return self._material_costs
return self._material_costs[self._active_build_plate]
materialNamesChanged = pyqtSignal()
@pyqtProperty("QVariantList", notify = materialNamesChanged)
def materialNames(self):
return self._material_names
return self._material_names[self._active_build_plate]
def _onPrintDurationMessage(self, print_time, material_amounts):
self._updateTotalPrintTimePerFeature(print_time)
def _onPrintDurationMessage(self, build_plate_number, print_time, material_amounts):
Logger.log("d", " ### print duration message for build plate %s", build_plate_number)
self._updateTotalPrintTimePerFeature(build_plate_number, print_time)
self.currentPrintTimeChanged.emit()
self._material_amounts = material_amounts
self._calculateInformation()
def _updateTotalPrintTimePerFeature(self, print_time):
def _updateTotalPrintTimePerFeature(self, build_plate_number, print_time):
total_estimated_time = 0
if build_plate_number not in self._print_time_message_values:
self._initPrintTimeMessageValues(build_plate_number)
for feature, time in print_time.items():
if time != time: # Check for NaN. Engine can sometimes give us weird values.
self._print_time_message_values.get(feature).setDuration(0)
self._print_time_message_values[build_plate_number].get(feature).setDuration(0)
Logger.log("w", "Received NaN for print duration message")
continue
total_estimated_time += time
self._print_time_message_values.get(feature).setDuration(time)
self._print_time_message_values[build_plate_number].get(feature).setDuration(time)
self._current_print_time.setDuration(total_estimated_time)
if build_plate_number not in self._current_print_time:
self._current_print_time[build_plate_number] = Duration(None, self)
self._current_print_time[build_plate_number].setDuration(total_estimated_time)
def _calculateInformation(self):
if Application.getInstance().getGlobalContainerStack() is None:
@ -174,10 +198,10 @@ class PrintInformation(QObject):
# Material amount is sent as an amount of mm^3, so calculate length from that
radius = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2
self._material_lengths = []
self._material_weights = []
self._material_costs = []
self._material_names = []
self._material_lengths[self._active_build_plate] = []
self._material_weights[self._active_build_plate] = []
self._material_costs[self._active_build_plate] = []
self._material_names[self._active_build_plate] = []
material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings"))
@ -215,10 +239,10 @@ class PrintInformation(QObject):
length = round((amount / (math.pi * radius ** 2)) / 1000, 2)
else:
length = 0
self._material_weights.append(weight)
self._material_lengths.append(length)
self._material_costs.append(cost)
self._material_names.append(material_name)
self._material_weights[self._active_build_plate].append(weight)
self._material_lengths[self._active_build_plate].append(length)
self._material_costs[self._active_build_plate].append(cost)
self._material_names[self._active_build_plate].append(material_name)
self.materialLengthsChanged.emit()
self.materialWeightsChanged.emit()
@ -245,6 +269,20 @@ class PrintInformation(QObject):
self._active_material_container = active_material_containers[0]
self._active_material_container.metaDataChanged.connect(self._onMaterialMetaDataChanged)
def _onActiveBuildPlateChanged(self):
new_active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate
if new_active_build_plate != self._active_build_plate:
Logger.log("d", " ## active build plate changed: %s", self._active_build_plate)
self._active_build_plate = new_active_build_plate
self._initVariablesWithBuildPlate(self._active_build_plate)
self.materialLengthsChanged.emit()
self.materialWeightsChanged.emit()
self.materialCostsChanged.emit()
self.materialNamesChanged.emit()
self.currentPrintTimeChanged.emit()
def _onMaterialMetaDataChanged(self, *args, **kwargs):
self._calculateInformation()
@ -341,7 +379,9 @@ class PrintInformation(QObject):
@pyqtSlot(result = "QVariantMap")
def getFeaturePrintTimes(self):
result = {}
for feature, time in self._print_time_message_values.items():
if self._active_build_plate not in self._print_time_message_values:
self._initPrintTimeMessageValues(self._active_build_plate)
for feature, time in self._print_time_message_values[self._active_build_plate].items():
if feature in self._print_time_message_translations:
result[self._print_time_message_translations[feature]] = time
else:
@ -349,10 +389,12 @@ class PrintInformation(QObject):
return result
# Simulate message with zero time duration
def setToZeroPrintInformation(self):
def setToZeroPrintInformation(self, build_plate_number):
temp_message = {}
for key in self._print_time_message_values.keys():
if build_plate_number not in self._print_time_message_values:
self._print_time_message_values[build_plate_number] = {}
for key in self._print_time_message_values[build_plate_number].keys():
temp_message[key] = 0
temp_material_amounts = [0]
self._onPrintDurationMessage(temp_message, temp_material_amounts)
self._onPrintDurationMessage(build_plate_number, temp_message, temp_material_amounts)

View file

@ -207,6 +207,7 @@ class CuraEngineBackend(QObject, Backend):
return
# see if we really have to slice
active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate
build_plate_to_be_sliced = self._build_plates_to_be_sliced.pop(0)
Logger.log("d", "Going to slice build plate [%s]!" % build_plate_to_be_sliced)
num_objects = self._numObjects()
@ -218,8 +219,8 @@ class CuraEngineBackend(QObject, Backend):
self._stored_layer_data = []
self._stored_optimized_layer_data[build_plate_to_be_sliced] = []
if Application.getInstance().getPrintInformation():
Application.getInstance().getPrintInformation().setToZeroPrintInformation()
if Application.getInstance().getPrintInformation() and build_plate_to_be_sliced == active_build_plate:
Application.getInstance().getPrintInformation().setToZeroPrintInformation(build_plate_to_be_sliced)
if self._process is None:
self._createSocket()
@ -547,11 +548,9 @@ class CuraEngineBackend(QObject, Backend):
replaced = replaced.replace("{filament_cost}", str(Application.getInstance().getPrintInformation().materialCosts))
replaced = replaced.replace("{jobname}", str(Application.getInstance().getPrintInformation().jobName))
#gcode_list[gcode_list.index(line)] = replaced
gcode_list[index] = replaced
self._slicing = False
#self._need_slicing = False
Logger.log("d", "Slicing took %s seconds", time() - self._slice_start_time )
# See if we need to process the sliced layers job.
@ -608,7 +607,7 @@ class CuraEngineBackend(QObject, Backend):
material_amounts.append(message.getRepeatedMessage("materialEstimates", index).material_amount)
times = self._parseMessagePrintTimes(message)
self.printDurationMessage.emit(times, material_amounts)
self.printDurationMessage.emit(self._start_slice_job_build_plate, times, material_amounts)
## Called for parsing message to retrieve estimated time per feature
#