mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-05 23:04:30 +08:00
Merge branch 'master' into WIP_feature_infill_slider
This commit is contained in:
commit
e8df185261
@ -45,11 +45,19 @@ if(NOT APPLE AND NOT WIN32)
|
|||||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||||
RENAME cura)
|
RENAME cura)
|
||||||
install(DIRECTORY cura
|
if(EXISTS /etc/debian_version)
|
||||||
|
install(DIRECTORY cura
|
||||||
DESTINATION lib/python${PYTHON_VERSION_MAJOR}/dist-packages
|
DESTINATION lib/python${PYTHON_VERSION_MAJOR}/dist-packages
|
||||||
FILES_MATCHING PATTERN *.py)
|
FILES_MATCHING PATTERN *.py)
|
||||||
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
|
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
|
||||||
DESTINATION lib/python${PYTHON_VERSION_MAJOR}/dist-packages/cura)
|
DESTINATION lib/python${PYTHON_VERSION_MAJOR}/dist-packages/cura)
|
||||||
|
else()
|
||||||
|
install(DIRECTORY cura
|
||||||
|
DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages
|
||||||
|
FILES_MATCHING PATTERN *.py)
|
||||||
|
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
|
||||||
|
DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/cura)
|
||||||
|
endif()
|
||||||
install(FILES ${CMAKE_BINARY_DIR}/cura.desktop
|
install(FILES ${CMAKE_BINARY_DIR}/cura.desktop
|
||||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/resources/images/cura-icon.png
|
install(FILES ${CMAKE_SOURCE_DIR}/resources/images/cura-icon.png
|
||||||
|
@ -34,9 +34,11 @@ Dependencies
|
|||||||
|
|
||||||
Configuring Cura
|
Configuring Cura
|
||||||
----------------
|
----------------
|
||||||
* Link your CuraEngine backend by inserting the following line in home/.config/cura/config.cfg :
|
Link your CuraEngine backend by inserting the following lines in `$HOME/.config/cura/config.cfg` :
|
||||||
|
```
|
||||||
[backend]
|
[backend]
|
||||||
location = /[path_to_the..]/CuraEngine/build/CuraEngine
|
location = /[path_to_the..]/CuraEngine/build/CuraEngine
|
||||||
|
```
|
||||||
|
|
||||||
Build scripts
|
Build scripts
|
||||||
-------------
|
-------------
|
||||||
|
@ -956,14 +956,14 @@ class BuildVolume(SceneNode):
|
|||||||
if adhesion_type == "skirt":
|
if adhesion_type == "skirt":
|
||||||
skirt_distance = self._getSettingFromAdhesionExtruder("skirt_gap")
|
skirt_distance = self._getSettingFromAdhesionExtruder("skirt_gap")
|
||||||
skirt_line_count = self._getSettingFromAdhesionExtruder("skirt_line_count")
|
skirt_line_count = self._getSettingFromAdhesionExtruder("skirt_line_count")
|
||||||
bed_adhesion_size = skirt_distance + (skirt_line_count * self._getSettingFromAdhesionExtruder("skirt_brim_line_width")) * self._getSettingFromAdhesionExtruder("initial_layer_line_width_factor") / 100.0
|
bed_adhesion_size = skirt_distance + (self._getSettingFromAdhesionExtruder("skirt_brim_line_width") * skirt_line_count) * self._getSettingFromAdhesionExtruder("initial_layer_line_width_factor") / 100.0
|
||||||
if len(used_extruders) > 1:
|
if len(used_extruders) > 1:
|
||||||
for extruder_stack in used_extruders:
|
for extruder_stack in used_extruders:
|
||||||
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
|
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
|
||||||
#We don't create an additional line for the extruder we're printing the skirt with.
|
#We don't create an additional line for the extruder we're printing the skirt with.
|
||||||
bed_adhesion_size -= self._getSettingFromAdhesionExtruder("skirt_brim_line_width", "value") * self._getSettingFromAdhesionExtruder("initial_layer_line_width_factor", "value") / 100.0
|
bed_adhesion_size -= self._getSettingFromAdhesionExtruder("skirt_brim_line_width", "value") * self._getSettingFromAdhesionExtruder("initial_layer_line_width_factor", "value") / 100.0
|
||||||
elif adhesion_type == "brim":
|
elif adhesion_type == "brim":
|
||||||
bed_adhesion_size = self._getSettingFromAdhesionExtruder("brim_line_count") * self._getSettingFromAdhesionExtruder("skirt_brim_line_width") * self._getSettingFromAdhesionExtruder("initial_layer_line_width_factor") / 100.0
|
bed_adhesion_size = self._getSettingFromAdhesionExtruder("skirt_brim_line_width") * self._getSettingFromAdhesionExtruder("brim_line_count") * self._getSettingFromAdhesionExtruder("initial_layer_line_width_factor") / 100.0
|
||||||
if self._global_container_stack.getProperty("machine_extruder_count", "value") > 1:
|
if self._global_container_stack.getProperty("machine_extruder_count", "value") > 1:
|
||||||
for extruder_stack in used_extruders:
|
for extruder_stack in used_extruders:
|
||||||
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
|
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
|
||||||
|
@ -41,7 +41,7 @@ class PlatformPhysics:
|
|||||||
def _onSceneChanged(self, source):
|
def _onSceneChanged(self, source):
|
||||||
self._change_timer.start()
|
self._change_timer.start()
|
||||||
|
|
||||||
def _onChangeTimerFinished(self):
|
def _onChangeTimerFinished(self, was_triggered_by_tool=False):
|
||||||
if not self._enabled:
|
if not self._enabled:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -71,14 +71,15 @@ class PlatformPhysics:
|
|||||||
# Check if this is the first time a project file node was loaded (disable auto drop in that case), defaults to True
|
# Check if this is the first time a project file node was loaded (disable auto drop in that case), defaults to True
|
||||||
should_auto_drop = node.getSetting("auto_drop", True)
|
should_auto_drop = node.getSetting("auto_drop", True)
|
||||||
|
|
||||||
|
# This should NOT happen if the scene change was triggered by a tool (like translate), only on project load
|
||||||
|
if was_triggered_by_tool:
|
||||||
|
should_auto_drop = True
|
||||||
|
|
||||||
# If a node is grouped or it's loaded from a project file (auto-drop disabled), don't move it down
|
# If a node is grouped or it's loaded from a project file (auto-drop disabled), don't move it down
|
||||||
if Preferences.getInstance().getValue("physics/automatic_drop_down") and not (node.getParent() and node.getParent().callDecoration("isGroup")) and node.isEnabled() and should_auto_drop:
|
if Preferences.getInstance().getValue("physics/automatic_drop_down") and not (node.getParent() and node.getParent().callDecoration("isGroup")) and node.isEnabled() and should_auto_drop:
|
||||||
z_offset = node.callDecoration("getZOffset") if node.getDecorator(ZOffsetDecorator.ZOffsetDecorator) else 0
|
z_offset = node.callDecoration("getZOffset") if node.getDecorator(ZOffsetDecorator.ZOffsetDecorator) else 0
|
||||||
move_vector = move_vector.set(y=-bbox.bottom + z_offset)
|
move_vector = move_vector.set(y=-bbox.bottom + z_offset)
|
||||||
|
|
||||||
# Enable auto-drop after processing the project file node for the first time
|
|
||||||
node.setSetting("auto_drop", False)
|
|
||||||
|
|
||||||
# If there is no convex hull for the node, start calculating it and continue.
|
# If there is no convex hull for the node, start calculating it and continue.
|
||||||
if not node.getDecorator(ConvexHullDecorator):
|
if not node.getDecorator(ConvexHullDecorator):
|
||||||
node.addDecorator(ConvexHullDecorator())
|
node.addDecorator(ConvexHullDecorator())
|
||||||
@ -167,4 +168,4 @@ class PlatformPhysics:
|
|||||||
node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator)
|
node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator)
|
||||||
|
|
||||||
self._enabled = True
|
self._enabled = True
|
||||||
self._onChangeTimerFinished()
|
self._onChangeTimerFinished(True)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2015 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty
|
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty
|
||||||
@ -51,20 +51,7 @@ class PrintInformation(QObject):
|
|||||||
def __init__(self, parent = None):
|
def __init__(self, parent = None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
self._current_print_time = Duration(None, self)
|
self.initializeCuraMessagePrintTimeProperties()
|
||||||
self._print_times_per_feature = {
|
|
||||||
"none": Duration(None, self),
|
|
||||||
"inset_0": Duration(None, self),
|
|
||||||
"inset_x": Duration(None, self),
|
|
||||||
"skin": Duration(None, self),
|
|
||||||
"support": Duration(None, self),
|
|
||||||
"skirt": Duration(None, self),
|
|
||||||
"infill": Duration(None, self),
|
|
||||||
"support_infill": Duration(None, self),
|
|
||||||
"travel": Duration(None, self),
|
|
||||||
"retract": Duration(None, self),
|
|
||||||
"support_interface": Duration(None, self)
|
|
||||||
}
|
|
||||||
|
|
||||||
self._material_lengths = []
|
self._material_lengths = []
|
||||||
self._material_weights = []
|
self._material_weights = []
|
||||||
@ -91,6 +78,33 @@ class PrintInformation(QObject):
|
|||||||
|
|
||||||
self._material_amounts = []
|
self._material_amounts = []
|
||||||
|
|
||||||
|
|
||||||
|
# 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._print_time_message_translations = {
|
||||||
|
"inset_0": catalog.i18nc("@tooltip", "Outer Wall"),
|
||||||
|
"inset_x": catalog.i18nc("@tooltip", "Inner Walls"),
|
||||||
|
"skin": catalog.i18nc("@tooltip", "Skin"),
|
||||||
|
"infill": catalog.i18nc("@tooltip", "Infill"),
|
||||||
|
"support_infill": catalog.i18nc("@tooltip", "Support Infill"),
|
||||||
|
"support_interface": catalog.i18nc("@tooltip", "Support Interface"),
|
||||||
|
"support": catalog.i18nc("@tooltip", "Support"),
|
||||||
|
"skirt": catalog.i18nc("@tooltip", "Skirt"),
|
||||||
|
"travel": catalog.i18nc("@tooltip", "Travel"),
|
||||||
|
"retract": catalog.i18nc("@tooltip", "Retractions"),
|
||||||
|
"none": catalog.i18nc("@tooltip", "Other")
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
currentPrintTimeChanged = pyqtSignal()
|
currentPrintTimeChanged = pyqtSignal()
|
||||||
|
|
||||||
preSlicedChanged = pyqtSignal()
|
preSlicedChanged = pyqtSignal()
|
||||||
@ -107,10 +121,6 @@ class PrintInformation(QObject):
|
|||||||
def currentPrintTime(self):
|
def currentPrintTime(self):
|
||||||
return self._current_print_time
|
return self._current_print_time
|
||||||
|
|
||||||
@pyqtProperty("QVariantMap", notify = currentPrintTimeChanged)
|
|
||||||
def printTimesPerFeature(self):
|
|
||||||
return self._print_times_per_feature
|
|
||||||
|
|
||||||
materialLengthsChanged = pyqtSignal()
|
materialLengthsChanged = pyqtSignal()
|
||||||
|
|
||||||
@pyqtProperty("QVariantList", notify = materialLengthsChanged)
|
@pyqtProperty("QVariantList", notify = materialLengthsChanged)
|
||||||
@ -129,22 +139,28 @@ class PrintInformation(QObject):
|
|||||||
def materialCosts(self):
|
def materialCosts(self):
|
||||||
return self._material_costs
|
return self._material_costs
|
||||||
|
|
||||||
def _onPrintDurationMessage(self, time_per_feature, material_amounts):
|
def _onPrintDurationMessage(self, print_time, material_amounts):
|
||||||
total_time = 0
|
|
||||||
for feature, time in time_per_feature.items():
|
|
||||||
if time != time: # Check for NaN. Engine can sometimes give us weird values.
|
|
||||||
self._print_times_per_feature[feature].setDuration(0)
|
|
||||||
Logger.log("w", "Received NaN for print duration message")
|
|
||||||
continue
|
|
||||||
total_time += time
|
|
||||||
self._print_times_per_feature[feature].setDuration(time)
|
|
||||||
self._current_print_time.setDuration(total_time)
|
|
||||||
|
|
||||||
|
self._updateTotalPrintTimePerFeature(print_time)
|
||||||
self.currentPrintTimeChanged.emit()
|
self.currentPrintTimeChanged.emit()
|
||||||
|
|
||||||
self._material_amounts = material_amounts
|
self._material_amounts = material_amounts
|
||||||
self._calculateInformation()
|
self._calculateInformation()
|
||||||
|
|
||||||
|
def _updateTotalPrintTimePerFeature(self, print_time):
|
||||||
|
total_estimated_time = 0
|
||||||
|
|
||||||
|
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)
|
||||||
|
Logger.log("w", "Received NaN for print duration message")
|
||||||
|
continue
|
||||||
|
|
||||||
|
total_estimated_time += time
|
||||||
|
self._print_time_message_values.get(feature).setDuration(time)
|
||||||
|
|
||||||
|
self._current_print_time.setDuration(total_estimated_time)
|
||||||
|
|
||||||
def _calculateInformation(self):
|
def _calculateInformation(self):
|
||||||
if Application.getInstance().getGlobalContainerStack() is None:
|
if Application.getInstance().getGlobalContainerStack() is None:
|
||||||
return
|
return
|
||||||
@ -294,3 +310,23 @@ class PrintInformation(QObject):
|
|||||||
## Utility method that strips accents from characters (eg: â -> a)
|
## Utility method that strips accents from characters (eg: â -> a)
|
||||||
def _stripAccents(self, str):
|
def _stripAccents(self, str):
|
||||||
return ''.join(char for char in unicodedata.normalize('NFD', str) if unicodedata.category(char) != 'Mn')
|
return ''.join(char for char in unicodedata.normalize('NFD', str) if unicodedata.category(char) != 'Mn')
|
||||||
|
|
||||||
|
@pyqtSlot(result = "QVariantMap")
|
||||||
|
def getFeaturePrintTimes(self):
|
||||||
|
result = {}
|
||||||
|
for feature, time in self._print_time_message_values.items():
|
||||||
|
if feature in self._print_time_message_translations:
|
||||||
|
result[self._print_time_message_translations[feature]] = time
|
||||||
|
else:
|
||||||
|
result[feature] = time
|
||||||
|
return result
|
||||||
|
|
||||||
|
# Simulate message with zero time duration
|
||||||
|
def setToZeroPrintInformation(self):
|
||||||
|
temp_message = {}
|
||||||
|
for key in self._print_time_message_values.keys():
|
||||||
|
temp_message[key] = 0
|
||||||
|
|
||||||
|
temp_material_amounts = [0]
|
||||||
|
self._onPrintDurationMessage(temp_message, temp_material_amounts)
|
||||||
|
|
||||||
|
@ -77,7 +77,10 @@ class ThreeMFReader(MeshReader):
|
|||||||
# \returns Uranium SceneNode.
|
# \returns Uranium SceneNode.
|
||||||
def _convertSavitarNodeToUMNode(self, savitar_node):
|
def _convertSavitarNodeToUMNode(self, savitar_node):
|
||||||
um_node = SceneNode()
|
um_node = SceneNode()
|
||||||
um_node.setSetting("auto_drop", False) # Disable the auto-drop feature when loading a project file and processing the nodes for the first time
|
|
||||||
|
# Disable the auto-drop feature when loading a project file and processing the nodes for the first time
|
||||||
|
um_node.setSetting("auto_drop", False)
|
||||||
|
|
||||||
transformation = self._createMatrixFromTransformationString(savitar_node.getTransformation())
|
transformation = self._createMatrixFromTransformationString(savitar_node.getTransformation())
|
||||||
um_node.setTransformation(transformation)
|
um_node.setTransformation(transformation)
|
||||||
mesh_builder = MeshBuilder()
|
mesh_builder = MeshBuilder()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2015 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from UM.Backend.Backend import Backend, BackendState
|
from UM.Backend.Backend import Backend, BackendState
|
||||||
@ -196,19 +196,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||||||
Logger.log("w", "Slice unnecessary, nothing has changed that needs reslicing.")
|
Logger.log("w", "Slice unnecessary, nothing has changed that needs reslicing.")
|
||||||
return
|
return
|
||||||
|
|
||||||
self.printDurationMessage.emit({
|
Application.getInstance().getPrintInformation().setToZeroPrintInformation()
|
||||||
"none": 0,
|
|
||||||
"inset_0": 0,
|
|
||||||
"inset_x": 0,
|
|
||||||
"skin": 0,
|
|
||||||
"support": 0,
|
|
||||||
"skirt": 0,
|
|
||||||
"infill": 0,
|
|
||||||
"support_infill": 0,
|
|
||||||
"travel": 0,
|
|
||||||
"retract": 0,
|
|
||||||
"support_interface": 0
|
|
||||||
}, [0])
|
|
||||||
|
|
||||||
self._stored_layer_data = []
|
self._stored_layer_data = []
|
||||||
self._stored_optimized_layer_data = []
|
self._stored_optimized_layer_data = []
|
||||||
@ -278,7 +266,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||||||
if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible:
|
if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible:
|
||||||
if Application.getInstance().platformActivity:
|
if Application.getInstance().platformActivity:
|
||||||
self._error_message = Message(catalog.i18nc("@info:status",
|
self._error_message = Message(catalog.i18nc("@info:status",
|
||||||
"The selected material is incompatible with the selected machine or configuration."), title = catalog.i18nc("@info:title", "Material Details"))
|
"The selected material is incompatible with the selected machine or configuration."), title = catalog.i18nc("@info:title", "Incompatible material"))
|
||||||
self._error_message.show()
|
self._error_message.show()
|
||||||
self.backendStateChange.emit(BackendState.Error)
|
self.backendStateChange.emit(BackendState.Error)
|
||||||
else:
|
else:
|
||||||
@ -306,7 +294,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||||||
|
|
||||||
error_labels = ", ".join(error_labels)
|
error_labels = ", ".join(error_labels)
|
||||||
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. The following settings have errors: {0}".format(error_labels)),
|
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. The following settings have errors: {0}".format(error_labels)),
|
||||||
title = catalog.i18nc("@info:title", "Setting Details"))
|
title = catalog.i18nc("@info:title", "Invalid settings"))
|
||||||
self._error_message.show()
|
self._error_message.show()
|
||||||
self.backendStateChange.emit(BackendState.Error)
|
self.backendStateChange.emit(BackendState.Error)
|
||||||
else:
|
else:
|
||||||
@ -514,29 +502,6 @@ class CuraEngineBackend(QObject, Backend):
|
|||||||
def _onGCodePrefixMessage(self, message):
|
def _onGCodePrefixMessage(self, message):
|
||||||
self._scene.gcode_list.insert(0, message.data.decode("utf-8", "replace"))
|
self._scene.gcode_list.insert(0, message.data.decode("utf-8", "replace"))
|
||||||
|
|
||||||
## Called when a print time message is received from the engine.
|
|
||||||
#
|
|
||||||
# \param message The protobuf message containing the print time per feature and
|
|
||||||
# material amount per extruder
|
|
||||||
def _onPrintTimeMaterialEstimates(self, message):
|
|
||||||
material_amounts = []
|
|
||||||
for index in range(message.repeatedMessageCount("materialEstimates")):
|
|
||||||
material_amounts.append(message.getRepeatedMessage("materialEstimates", index).material_amount)
|
|
||||||
feature_times = {
|
|
||||||
"none": message.time_none,
|
|
||||||
"inset_0": message.time_inset_0,
|
|
||||||
"inset_x": message.time_inset_x,
|
|
||||||
"skin": message.time_skin,
|
|
||||||
"support": message.time_support,
|
|
||||||
"skirt": message.time_skirt,
|
|
||||||
"infill": message.time_infill,
|
|
||||||
"support_infill": message.time_support_infill,
|
|
||||||
"travel": message.time_travel,
|
|
||||||
"retract": message.time_retract,
|
|
||||||
"support_interface": message.time_support_interface
|
|
||||||
}
|
|
||||||
self.printDurationMessage.emit(feature_times, material_amounts)
|
|
||||||
|
|
||||||
## Creates a new socket connection.
|
## Creates a new socket connection.
|
||||||
def _createSocket(self):
|
def _createSocket(self):
|
||||||
super()._createSocket(os.path.abspath(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "Cura.proto")))
|
super()._createSocket(os.path.abspath(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "Cura.proto")))
|
||||||
@ -555,6 +520,38 @@ class CuraEngineBackend(QObject, Backend):
|
|||||||
else:
|
else:
|
||||||
self._change_timer.start()
|
self._change_timer.start()
|
||||||
|
|
||||||
|
## Called when a print time message is received from the engine.
|
||||||
|
#
|
||||||
|
# \param message The protobuf message containing the print time per feature and
|
||||||
|
# material amount per extruder
|
||||||
|
def _onPrintTimeMaterialEstimates(self, message):
|
||||||
|
material_amounts = []
|
||||||
|
for index in range(message.repeatedMessageCount("materialEstimates")):
|
||||||
|
material_amounts.append(message.getRepeatedMessage("materialEstimates", index).material_amount)
|
||||||
|
|
||||||
|
times = self._parseMessagePrintTimes(message)
|
||||||
|
self.printDurationMessage.emit(times, material_amounts)
|
||||||
|
|
||||||
|
## Called for parsing message to retrieve estimated time per feature
|
||||||
|
#
|
||||||
|
# \param message The protobuf message containing the print time per feature
|
||||||
|
def _parseMessagePrintTimes(self, message):
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"inset_0": message.time_inset_0,
|
||||||
|
"inset_x": message.time_inset_x,
|
||||||
|
"skin": message.time_skin,
|
||||||
|
"infill": message.time_infill,
|
||||||
|
"support_infill": message.time_support_infill,
|
||||||
|
"support_interface": message.time_support_interface,
|
||||||
|
"support": message.time_support,
|
||||||
|
"skirt": message.time_skirt,
|
||||||
|
"travel": message.time_travel,
|
||||||
|
"retract": message.time_retract,
|
||||||
|
"none": message.time_none
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
|
||||||
## Called when the back-end connects to the front-end.
|
## Called when the back-end connects to the front-end.
|
||||||
def _onBackendConnected(self):
|
def _onBackendConnected(self):
|
||||||
if self._restart:
|
if self._restart:
|
||||||
|
@ -60,7 +60,7 @@ class RemovableDriveOutputDevice(OutputDevice):
|
|||||||
|
|
||||||
if len(file_formats) == 0:
|
if len(file_formats) == 0:
|
||||||
Logger.log("e", "There are no file formats available to write with!")
|
Logger.log("e", "There are no file formats available to write with!")
|
||||||
raise OutputDeviceError.WriteRequestFailedError()
|
raise OutputDeviceError.WriteRequestFailedError(catalog.i18nc("There are no file formats available to write with!"))
|
||||||
|
|
||||||
# Just take the first file format available.
|
# Just take the first file format available.
|
||||||
if file_handler is not None:
|
if file_handler is not None:
|
||||||
@ -115,7 +115,7 @@ class RemovableDriveOutputDevice(OutputDevice):
|
|||||||
name = child.getName()
|
name = child.getName()
|
||||||
if name:
|
if name:
|
||||||
return name
|
return name
|
||||||
raise OutputDeviceError.WriteRequestFailedError("Could not find a file name when trying to write to {device}.".format(device = self.getName()))
|
raise OutputDeviceError.WriteRequestFailedError(catalog.i18nc("@info:status Don't translate the tag {device}!", "Could not find a file name when trying to write to {device}.").format(device = self.getName()))
|
||||||
|
|
||||||
def _onProgress(self, job, progress):
|
def _onProgress(self, job, progress):
|
||||||
self.writeProgress.emit(self, progress)
|
self.writeProgress.emit(self, progress)
|
||||||
|
@ -162,7 +162,7 @@ class SliceInfo(Extension):
|
|||||||
|
|
||||||
data["models"].append(model)
|
data["models"].append(model)
|
||||||
|
|
||||||
print_times = print_information.printTimesPerFeature
|
print_times = print_information._print_time_message_values
|
||||||
data["print_times"] = {"travel": int(print_times["travel"].getDisplayString(DurationFormat.Format.Seconds)),
|
data["print_times"] = {"travel": int(print_times["travel"].getDisplayString(DurationFormat.Format.Seconds)),
|
||||||
"support": int(print_times["support"].getDisplayString(DurationFormat.Format.Seconds)),
|
"support": int(print_times["support"].getDisplayString(DurationFormat.Format.Seconds)),
|
||||||
"infill": int(print_times["infill"].getDisplayString(DurationFormat.Format.Seconds)),
|
"infill": int(print_times["infill"].getDisplayString(DurationFormat.Format.Seconds)),
|
||||||
|
@ -238,22 +238,22 @@ Item {
|
|||||||
if(!control.enabled)
|
if(!control.enabled)
|
||||||
return UM.Theme.getColor("action_button_disabled_border");
|
return UM.Theme.getColor("action_button_disabled_border");
|
||||||
else if(control.pressed)
|
else if(control.pressed)
|
||||||
return UM.Theme.getColor("action_button_active_border");
|
return UM.Theme.getColor("print_button_ready_pressed_border");
|
||||||
else if(control.hovered)
|
else if(control.hovered)
|
||||||
return UM.Theme.getColor("action_button_hovered_border");
|
return UM.Theme.getColor("print_button_ready_hovered_border");
|
||||||
else
|
else
|
||||||
return UM.Theme.getColor("action_button_border");
|
return UM.Theme.getColor("print_button_ready_border");
|
||||||
}
|
}
|
||||||
color:
|
color:
|
||||||
{
|
{
|
||||||
if(!control.enabled)
|
if(!control.enabled)
|
||||||
return UM.Theme.getColor("action_button_disabled");
|
return UM.Theme.getColor("action_button_disabled");
|
||||||
else if(control.pressed)
|
else if(control.pressed)
|
||||||
return UM.Theme.getColor("action_button_active");
|
return UM.Theme.getColor("print_button_ready_pressed");
|
||||||
else if(control.hovered)
|
else if(control.hovered)
|
||||||
return UM.Theme.getColor("action_button_hovered");
|
return UM.Theme.getColor("print_button_ready_hovered");
|
||||||
else
|
else
|
||||||
return UM.Theme.getColor("action_button");
|
return UM.Theme.getColor("print_button_ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on color { ColorAnimation { duration: 50; } }
|
Behavior on color { ColorAnimation { duration: 50; } }
|
||||||
@ -268,11 +268,11 @@ Item {
|
|||||||
if(!control.enabled)
|
if(!control.enabled)
|
||||||
return UM.Theme.getColor("action_button_disabled_text");
|
return UM.Theme.getColor("action_button_disabled_text");
|
||||||
else if(control.pressed)
|
else if(control.pressed)
|
||||||
return UM.Theme.getColor("action_button_active_text");
|
return UM.Theme.getColor("print_button_ready_text");
|
||||||
else if(control.hovered)
|
else if(control.hovered)
|
||||||
return UM.Theme.getColor("action_button_hovered_text");
|
return UM.Theme.getColor("print_button_ready_text");
|
||||||
else
|
else
|
||||||
return UM.Theme.getColor("action_button_text");
|
return UM.Theme.getColor("print_button_ready_text");
|
||||||
}
|
}
|
||||||
font: UM.Theme.getFont("action_button")
|
font: UM.Theme.getFont("action_button")
|
||||||
text: control.text;
|
text: control.text;
|
||||||
|
@ -26,7 +26,6 @@ Rectangle
|
|||||||
property bool monitoringPrint: false
|
property bool monitoringPrint: false
|
||||||
|
|
||||||
property variant printDuration: PrintInformation.currentPrintTime
|
property variant printDuration: PrintInformation.currentPrintTime
|
||||||
property variant printDurationPerFeature: PrintInformation.printTimesPerFeature
|
|
||||||
property variant printMaterialLengths: PrintInformation.materialLengths
|
property variant printMaterialLengths: PrintInformation.materialLengths
|
||||||
property variant printMaterialWeights: PrintInformation.materialWeights
|
property variant printMaterialWeights: PrintInformation.materialWeights
|
||||||
property variant printMaterialCosts: PrintInformation.materialCosts
|
property variant printMaterialCosts: PrintInformation.materialCosts
|
||||||
@ -314,54 +313,53 @@ Rectangle
|
|||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
|
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
|
||||||
anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height
|
anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height
|
||||||
height: childrenRect.height
|
height: timeDetails.height + timeSpecDescription.height + lengthSpec.height
|
||||||
visible: !monitoringPrint
|
visible: !monitoringPrint
|
||||||
|
|
||||||
UM.TooltipArea
|
Text
|
||||||
{
|
{
|
||||||
id: timeSpecPerFeatureTooltipArea
|
id: timeDetails
|
||||||
width: timeSpec.width
|
|
||||||
height: timeSpec.height
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.bottom: timeSpecDescription.top
|
anchors.bottom: timeSpecDescription.top
|
||||||
|
font: UM.Theme.getFont("large")
|
||||||
|
color: UM.Theme.getColor("text_subtext")
|
||||||
|
text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
|
||||||
|
|
||||||
text: {
|
MouseArea
|
||||||
var order = ["inset_0", "inset_x", "skin", "infill", "support_infill", "support_interface", "support", "travel", "retract", "none"];
|
{
|
||||||
var visible_names = {
|
id: infillMouseArea
|
||||||
"inset_0": catalog.i18nc("@tooltip", "Outer Wall"),
|
anchors.fill: parent
|
||||||
"inset_x": catalog.i18nc("@tooltip", "Inner Walls"),
|
hoverEnabled: true
|
||||||
"skin": catalog.i18nc("@tooltip", "Skin"),
|
//enabled: base.settingsEnabled
|
||||||
"infill": catalog.i18nc("@tooltip", "Infill"),
|
|
||||||
"support_infill": catalog.i18nc("@tooltip", "Support Infill"),
|
onEntered:
|
||||||
"support_interface": catalog.i18nc("@tooltip", "Support Interface"),
|
|
||||||
"support": catalog.i18nc("@tooltip", "Support"),
|
|
||||||
"travel": catalog.i18nc("@tooltip", "Travel"),
|
|
||||||
"retract": catalog.i18nc("@tooltip", "Retractions"),
|
|
||||||
"none": catalog.i18nc("@tooltip", "Other")
|
|
||||||
};
|
|
||||||
var result = "";
|
|
||||||
for(var feature in order)
|
|
||||||
{
|
{
|
||||||
feature = order[feature];
|
|
||||||
if(base.printDurationPerFeature[feature] && base.printDurationPerFeature[feature].totalSeconds > 0)
|
if(base.printDuration.valid && !base.printDuration.isTotalDurationZero)
|
||||||
{
|
{
|
||||||
result += "<br/>" + visible_names[feature] + ": " + base.printDurationPerFeature[feature].getDisplayString(UM.DurationFormat.Short);
|
// All the time information for the different features is achieved
|
||||||
|
var print_time = PrintInformation.getFeaturePrintTimes()
|
||||||
|
|
||||||
|
// A message is created and displayed when the user hover the time label
|
||||||
|
var content = catalog.i18nc("@tooltip", "<b>Time information</b>")
|
||||||
|
for(var feature in print_time)
|
||||||
|
{
|
||||||
|
if(!print_time[feature].isTotalDurationZero)
|
||||||
|
{
|
||||||
|
content += "<br /><i>" + feature + "</i>: " + print_time[feature].getDisplayString(UM.DurationFormat.Short)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = result.replace(/^\<br\/\>/, ""); // remove newline before first item
|
onExited:
|
||||||
return result;
|
{
|
||||||
}
|
base.hideTooltip();
|
||||||
|
}
|
||||||
Text
|
|
||||||
{
|
|
||||||
id: timeSpec
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
font: UM.Theme.getFont("large")
|
|
||||||
color: UM.Theme.getColor("text_subtext")
|
|
||||||
text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text
|
Text
|
||||||
{
|
{
|
||||||
id: timeSpecDescription
|
id: timeSpecDescription
|
||||||
|
@ -44,10 +44,8 @@ Item
|
|||||||
{
|
{
|
||||||
id: resolutionLabel
|
id: resolutionLabel
|
||||||
anchors.top: resolutionSlider.top
|
anchors.top: resolutionSlider.top
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height * 1.2
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
|
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
|
||||||
width: UM.Theme.getSize("sidebar").width * .45 - UM.Theme.getSize("sidebar_margin").width
|
|
||||||
|
|
||||||
text: catalog.i18nc("@label", "Layer Height")
|
text: catalog.i18nc("@label", "Layer Height")
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
@ -57,10 +55,9 @@ Item
|
|||||||
Text
|
Text
|
||||||
{
|
{
|
||||||
id: speedLabel
|
id: speedLabel
|
||||||
anchors.top: resolutionLabel.bottom
|
anchors.bottom: resolutionSlider.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
|
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height * 1.5
|
|
||||||
|
|
||||||
text: catalog.i18nc("@label", "Print Speed")
|
text: catalog.i18nc("@label", "Print Speed")
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
@ -70,7 +67,7 @@ Item
|
|||||||
Text
|
Text
|
||||||
{
|
{
|
||||||
id: speedLabelSlower
|
id: speedLabelSlower
|
||||||
anchors.top: speedLabel.top
|
anchors.bottom: speedLabel.bottom
|
||||||
anchors.left: resolutionSlider.left
|
anchors.left: resolutionSlider.left
|
||||||
|
|
||||||
text: catalog.i18nc("@label", "Slower")
|
text: catalog.i18nc("@label", "Slower")
|
||||||
@ -82,7 +79,7 @@ Item
|
|||||||
Text
|
Text
|
||||||
{
|
{
|
||||||
id: speedLabelFaster
|
id: speedLabelFaster
|
||||||
anchors.top: speedLabel.top
|
anchors.bottom: speedLabel.bottom
|
||||||
anchors.right: resolutionSlider.right
|
anchors.right: resolutionSlider.right
|
||||||
|
|
||||||
text: catalog.i18nc("@label", "Faster")
|
text: catalog.i18nc("@label", "Faster")
|
||||||
@ -95,11 +92,11 @@ Item
|
|||||||
{
|
{
|
||||||
id: resolutionSlider
|
id: resolutionSlider
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
||||||
anchors.left: infillCellRight.left
|
anchors.left: infillCellRight.left
|
||||||
anchors.right: infillCellRight.right
|
anchors.right: infillCellRight.right
|
||||||
|
|
||||||
width: UM.Theme.getSize("sidebar").width * .55
|
width: UM.Theme.getSize("sidebar").width * .55
|
||||||
height: UM.Theme.getSize("quality_slider_bar").height * 30
|
height: UM.Theme.getSize("quality_slider_bar").height * 25
|
||||||
|
|
||||||
property var model: Cura.ProfilesModel
|
property var model: Cura.ProfilesModel
|
||||||
|
|
||||||
@ -349,23 +346,12 @@ Item
|
|||||||
}
|
}
|
||||||
else if (i == total_tick_count - 1)
|
else if (i == total_tick_count - 1)
|
||||||
{
|
{
|
||||||
start_x = current_start_x - offset * 2;
|
start_x = current_start_x - offset * 2.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.fillText(resolutionSlider.model.getItem(i).layer_height_without_unit, start_x, text_top);
|
ctx.fillText(resolutionSlider.model.getItem(i).layer_height_without_unit, start_x, text_top);
|
||||||
current_start_x += step_size;
|
current_start_x += step_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print currently selected quality text
|
|
||||||
if (resolutionSlider.showQualityText && resolutionSlider.currentQualityIndex != undefine)
|
|
||||||
{
|
|
||||||
const text_top = parent.height / 2 + tick_height + tick_text_height * 2;
|
|
||||||
total_tick_count = resolutionSlider.totalTickCount;
|
|
||||||
const step_size = resolutionSlider.tickStepSize;
|
|
||||||
current_start_x = (tick_left_right_margin) + step_size * (resolutionSlider.currentQualityIndex - resolutionSlider.fullRangeMin);
|
|
||||||
ctx.fillStyle = UM.Theme.getColor("quality_slider_text");
|
|
||||||
ctx.fillText(resolutionSlider.model.getItem(resolutionSlider.currentQualityIndex).name, current_start_x - 6, text_top);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea
|
MouseArea
|
||||||
|
@ -116,20 +116,6 @@
|
|||||||
"sync_button_text": [120, 120, 120, 255],
|
"sync_button_text": [120, 120, 120, 255],
|
||||||
"sync_button_text_hovered": [0, 0, 0, 255],
|
"sync_button_text_hovered": [0, 0, 0, 255],
|
||||||
|
|
||||||
"tab_checked": [255, 255, 255, 255],
|
|
||||||
"tab_checked_border": [255, 255, 255, 255],
|
|
||||||
"tab_checked_text": [24, 41, 77, 255],
|
|
||||||
"tab_unchecked": [245, 245, 245, 255],
|
|
||||||
"tab_unchecked_border": [245, 245, 245, 255],
|
|
||||||
"tab_unchecked_text": [127, 127, 127, 255],
|
|
||||||
"tab_hovered": [245, 245, 245, 255],
|
|
||||||
"tab_hovered_border": [245, 245, 245, 255],
|
|
||||||
"tab_hovered_text": [32, 166, 219, 255],
|
|
||||||
"tab_active": [255, 255, 255, 255],
|
|
||||||
"tab_active_border": [255, 255, 255, 255],
|
|
||||||
"tab_active_text": [24, 41, 77, 255],
|
|
||||||
"tab_background": [245, 245, 245, 255],
|
|
||||||
|
|
||||||
"action_button": [255, 255, 255, 255],
|
"action_button": [255, 255, 255, 255],
|
||||||
"action_button_text": [0, 0, 0, 255],
|
"action_button_text": [0, 0, 0, 255],
|
||||||
"action_button_border": [127, 127, 127, 255],
|
"action_button_border": [127, 127, 127, 255],
|
||||||
@ -143,6 +129,14 @@
|
|||||||
"action_button_disabled_text": [127, 127, 127, 255],
|
"action_button_disabled_text": [127, 127, 127, 255],
|
||||||
"action_button_disabled_border": [245, 245, 245, 255],
|
"action_button_disabled_border": [245, 245, 245, 255],
|
||||||
|
|
||||||
|
"print_button_ready": [12, 169, 227, 255],
|
||||||
|
"print_button_ready_border": [12, 169, 227, 255],
|
||||||
|
"print_button_ready_text": [255, 255, 255, 255],
|
||||||
|
"print_button_ready_hovered": [12, 169, 255, 255],
|
||||||
|
"print_button_ready_hovered_border": [12, 169, 227, 255],
|
||||||
|
"print_button_ready_pressed": [12, 169, 220, 255],
|
||||||
|
"print_button_ready_pressed_border": [12, 169, 227, 255],
|
||||||
|
|
||||||
"scrollbar_background": [255, 255, 255, 255],
|
"scrollbar_background": [255, 255, 255, 255],
|
||||||
"scrollbar_handle": [24, 41, 77, 255],
|
"scrollbar_handle": [24, 41, 77, 255],
|
||||||
"scrollbar_handle_hover": [12, 159, 227, 255],
|
"scrollbar_handle_hover": [12, 159, 227, 255],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user