mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-07 06:57:28 -06:00
Merge remote-tracking branch 'Ultimaker/master'
This commit is contained in:
commit
bca7c75cd2
333 changed files with 1935 additions and 1157 deletions
|
@ -45,7 +45,6 @@ Please checkout [cura-build](https://github.com/Ultimaker/cura-build)
|
||||||
|
|
||||||
Third party plugins
|
Third party plugins
|
||||||
-------------
|
-------------
|
||||||
* [Print Cost Calculator](https://github.com/nallath/PrintCostCalculator): Calculates weight and monetary cost of your print.
|
|
||||||
* [Post Processing Plugin](https://github.com/nallath/PostProcessingPlugin): Allows for post-processing scripts to run on g-code.
|
* [Post Processing Plugin](https://github.com/nallath/PostProcessingPlugin): Allows for post-processing scripts to run on g-code.
|
||||||
* [Barbarian Plugin](https://github.com/nallath/BarbarianPlugin): Simple scale tool for imperial to metric.
|
* [Barbarian Plugin](https://github.com/nallath/BarbarianPlugin): Simple scale tool for imperial to metric.
|
||||||
* [X3G Writer](https://github.com/Ghostkeeper/X3GWriter): Adds support for exporting X3G files.
|
* [X3G Writer](https://github.com/Ghostkeeper/X3GWriter): Adds support for exporting X3G files.
|
||||||
|
|
|
@ -718,8 +718,8 @@ class BuildVolume(SceneNode):
|
||||||
|
|
||||||
# For certain machines we don't need to compute disallowed areas for each nozzle.
|
# For certain machines we don't need to compute disallowed areas for each nozzle.
|
||||||
# So we check here and only do the nozzle offsetting if needed.
|
# So we check here and only do the nozzle offsetting if needed.
|
||||||
no_nozzle_offsetting_for_disallowed_areas = self._global_container_stack.getMetaDataEntry(
|
nozzle_offsetting_for_disallowed_areas = self._global_container_stack.getMetaDataEntry(
|
||||||
"no_nozzle_offsetting_for_disallowed_areas", False)
|
"nozzle_offsetting_for_disallowed_areas", True)
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
for extruder in used_extruders:
|
for extruder in used_extruders:
|
||||||
|
@ -727,9 +727,11 @@ class BuildVolume(SceneNode):
|
||||||
offset_x = extruder.getProperty("machine_nozzle_offset_x", "value")
|
offset_x = extruder.getProperty("machine_nozzle_offset_x", "value")
|
||||||
if offset_x is None:
|
if offset_x is None:
|
||||||
offset_x = 0
|
offset_x = 0
|
||||||
offset_y = -extruder.getProperty("machine_nozzle_offset_y", "value")
|
offset_y = extruder.getProperty("machine_nozzle_offset_y", "value")
|
||||||
if offset_y is None:
|
if offset_y is None:
|
||||||
offset_y = 0
|
offset_y = 0
|
||||||
|
else:
|
||||||
|
offset_y = -offset_y
|
||||||
result[extruder_id] = []
|
result[extruder_id] = []
|
||||||
|
|
||||||
for polygon in machine_disallowed_polygons:
|
for polygon in machine_disallowed_polygons:
|
||||||
|
@ -742,7 +744,7 @@ class BuildVolume(SceneNode):
|
||||||
bottom_unreachable_border = 0
|
bottom_unreachable_border = 0
|
||||||
|
|
||||||
# Only do nozzle offsetting if needed
|
# Only do nozzle offsetting if needed
|
||||||
if not no_nozzle_offsetting_for_disallowed_areas:
|
if nozzle_offsetting_for_disallowed_areas:
|
||||||
#The build volume is defined as the union of the area that all extruders can reach, so we need to know the relative offset to all extruders.
|
#The build volume is defined as the union of the area that all extruders can reach, so we need to know the relative offset to all extruders.
|
||||||
for other_extruder in ExtruderManager.getInstance().getActiveExtruderStacks():
|
for other_extruder in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||||
other_offset_x = other_extruder.getProperty("machine_nozzle_offset_x", "value")
|
other_offset_x = other_extruder.getProperty("machine_nozzle_offset_x", "value")
|
||||||
|
|
|
@ -257,7 +257,11 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
||||||
# \return New Polygon instance that is offset with everything that
|
# \return New Polygon instance that is offset with everything that
|
||||||
# influences the collision area.
|
# influences the collision area.
|
||||||
def _offsetHull(self, convex_hull):
|
def _offsetHull(self, convex_hull):
|
||||||
horizontal_expansion = self._getSettingProperty("xy_offset", "value")
|
horizontal_expansion = max(
|
||||||
|
self._getSettingProperty("xy_offset", "value"),
|
||||||
|
self._getSettingProperty("xy_offset_layer_0", "value")
|
||||||
|
)
|
||||||
|
|
||||||
mold_width = 0
|
mold_width = 0
|
||||||
if self._getSettingProperty("mold_enabled", "value"):
|
if self._getSettingProperty("mold_enabled", "value"):
|
||||||
mold_width = self._getSettingProperty("mold_width", "value")
|
mold_width = self._getSettingProperty("mold_width", "value")
|
||||||
|
@ -332,4 +336,4 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
||||||
## Settings that change the convex hull.
|
## Settings that change the convex hull.
|
||||||
#
|
#
|
||||||
# If these settings change, the convex hull should be recalculated.
|
# If these settings change, the convex hull should be recalculated.
|
||||||
_influencing_settings = {"xy_offset", "mold_enabled", "mold_width"}
|
_influencing_settings = {"xy_offset", "xy_offset_layer_0", "mold_enabled", "mold_width"}
|
||||||
|
|
|
@ -26,7 +26,6 @@ from UM.Settings.Validator import Validator
|
||||||
from UM.Message import Message
|
from UM.Message import Message
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
from UM.Workspace.WorkspaceReader import WorkspaceReader
|
from UM.Workspace.WorkspaceReader import WorkspaceReader
|
||||||
from UM.Platform import Platform
|
|
||||||
from UM.Decorators import deprecated
|
from UM.Decorators import deprecated
|
||||||
|
|
||||||
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
|
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
|
||||||
|
@ -105,7 +104,7 @@ class CuraApplication(QtApplication):
|
||||||
# SettingVersion represents the set of settings available in the machine/extruder definitions.
|
# SettingVersion represents the set of settings available in the machine/extruder definitions.
|
||||||
# You need to make sure that this version number needs to be increased if there is any non-backwards-compatible
|
# You need to make sure that this version number needs to be increased if there is any non-backwards-compatible
|
||||||
# changes of the settings.
|
# changes of the settings.
|
||||||
SettingVersion = 1
|
SettingVersion = 2
|
||||||
|
|
||||||
class ResourceTypes:
|
class ResourceTypes:
|
||||||
QmlFiles = Resources.UserType + 1
|
QmlFiles = Resources.UserType + 1
|
||||||
|
@ -179,9 +178,9 @@ class CuraApplication(QtApplication):
|
||||||
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
|
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
|
||||||
{
|
{
|
||||||
("quality_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
|
("quality_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
|
||||||
("machine_stack", ContainerStack.Version): (self.ResourceTypes.MachineStack, "application/x-uranium-containerstack"),
|
("machine_stack", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.MachineStack, "application/x-cura-globalstack"),
|
||||||
("extruder_train", ContainerStack.Version): (self.ResourceTypes.ExtruderStack, "application/x-uranium-extruderstack"),
|
("extruder_train", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.ExtruderStack, "application/x-cura-extruderstack"),
|
||||||
("preferences", Preferences.Version): (Resources.Preferences, "application/x-uranium-preferences"),
|
("preferences", Preferences.Version * 1000000 + self.SettingVersion): (Resources.Preferences, "application/x-uranium-preferences"),
|
||||||
("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer"),
|
("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer"),
|
||||||
("definition_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.DefinitionChangesContainer, "application/x-uranium-instancecontainer"),
|
("definition_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.DefinitionChangesContainer, "application/x-uranium-instancecontainer"),
|
||||||
}
|
}
|
||||||
|
@ -268,6 +267,9 @@ class CuraApplication(QtApplication):
|
||||||
with ContainerRegistry.getInstance().lockFile():
|
with ContainerRegistry.getInstance().lockFile():
|
||||||
ContainerRegistry.getInstance().load()
|
ContainerRegistry.getInstance().load()
|
||||||
|
|
||||||
|
# set the setting version for Preferences
|
||||||
|
Preferences.getInstance().addPreference("metadata/setting_version", CuraApplication.SettingVersion)
|
||||||
|
|
||||||
Preferences.getInstance().addPreference("cura/active_mode", "simple")
|
Preferences.getInstance().addPreference("cura/active_mode", "simple")
|
||||||
|
|
||||||
Preferences.getInstance().addPreference("cura/categories_expanded", "")
|
Preferences.getInstance().addPreference("cura/categories_expanded", "")
|
||||||
|
|
|
@ -218,20 +218,25 @@ class ContainerManager(QObject):
|
||||||
entries = entry_name.split("/")
|
entries = entry_name.split("/")
|
||||||
entry_name = entries.pop()
|
entry_name = entries.pop()
|
||||||
|
|
||||||
|
sub_item_changed = False
|
||||||
if entries:
|
if entries:
|
||||||
root_name = entries.pop(0)
|
root_name = entries.pop(0)
|
||||||
root = container.getMetaDataEntry(root_name)
|
root = container.getMetaDataEntry(root_name)
|
||||||
|
|
||||||
item = root
|
item = root
|
||||||
for entry in entries:
|
for _ in range(len(entries)):
|
||||||
item = item.get(entries.pop(0), { })
|
item = item.get(entries.pop(0), { })
|
||||||
|
|
||||||
|
if item[entry_name] != entry_value:
|
||||||
|
sub_item_changed = True
|
||||||
item[entry_name] = entry_value
|
item[entry_name] = entry_value
|
||||||
|
|
||||||
entry_name = root_name
|
entry_name = root_name
|
||||||
entry_value = root
|
entry_value = root
|
||||||
|
|
||||||
container.setMetaDataEntry(entry_name, entry_value)
|
container.setMetaDataEntry(entry_name, entry_value)
|
||||||
|
if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed.
|
||||||
|
container.metaDataChanged.emit(container)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Copyright (c) 2017 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 typing import Any, Dict
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtProperty
|
from PyQt5.QtCore import pyqtProperty
|
||||||
|
|
||||||
|
@ -42,6 +42,17 @@ class GlobalStack(CuraContainerStack):
|
||||||
def getLoadingPriority(cls) -> int:
|
def getLoadingPriority(cls) -> int:
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
|
def getConfigurationTypeFromSerialized(self, serialized: str) -> Optional[str]:
|
||||||
|
configuration_type = None
|
||||||
|
try:
|
||||||
|
parser = self._readAndValidateSerialized(serialized)
|
||||||
|
configuration_type = parser["metadata"].get("type")
|
||||||
|
if configuration_type == "machine":
|
||||||
|
configuration_type = "machine_stack"
|
||||||
|
except Exception as e:
|
||||||
|
Logger.log("e", "Could not get configuration type: %s", e)
|
||||||
|
return configuration_type
|
||||||
|
|
||||||
## Add an extruder to the list of extruders of this stack.
|
## Add an extruder to the list of extruders of this stack.
|
||||||
#
|
#
|
||||||
# \param extruder The extruder to add.
|
# \param extruder The extruder to add.
|
||||||
|
|
|
@ -49,6 +49,9 @@ class MaterialManager(QObject):
|
||||||
if button == "Undo":
|
if button == "Undo":
|
||||||
container_manager = ContainerManager.getInstance()
|
container_manager = ContainerManager.getInstance()
|
||||||
container_manager.setContainerMetaDataEntry(self._material_diameter_warning_message.material_id, "properties/diameter", self._material_diameter_warning_message.previous_diameter)
|
container_manager.setContainerMetaDataEntry(self._material_diameter_warning_message.material_id, "properties/diameter", self._material_diameter_warning_message.previous_diameter)
|
||||||
|
approximate_previous_diameter = str(round(float(self._material_diameter_warning_message.previous_diameter)))
|
||||||
|
container_manager.setContainerMetaDataEntry(self._material_diameter_warning_message.material_id, "approximate_diameter", approximate_previous_diameter)
|
||||||
|
container_manager.setContainerProperty(self._material_diameter_warning_message.material_id, "material_diameter", "value", self._material_diameter_warning_message.previous_diameter);
|
||||||
message.hide()
|
message.hide()
|
||||||
else:
|
else:
|
||||||
Logger.log("w", "Unknown button action for material diameter warning message: {action}".format(action = button))
|
Logger.log("w", "Unknown button action for material diameter warning message: {action}".format(action = button))
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "3MF Reader",
|
"name": "3MF Reader",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides support for reading 3MF files.",
|
"description": "Provides support for reading 3MF files.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "3MF Writer",
|
"name": "3MF Writer",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides support for writing 3MF files.",
|
"description": "Provides support for writing 3MF files.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Auto Save",
|
"name": "Auto Save",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Automatically saves Preferences, Machines and Profiles after changes.",
|
"description": "Automatically saves Preferences, Machines and Profiles after changes.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Changelog",
|
"name": "Changelog",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Shows changes since latest checked version.",
|
"description": "Shows changes since latest checked version.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2016 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.
|
||||||
|
|
||||||
import gc
|
import gc
|
||||||
|
@ -173,19 +173,14 @@ class ProcessSlicedLayersJob(Job):
|
||||||
if extruders:
|
if extruders:
|
||||||
material_color_map = numpy.zeros((len(extruders), 4), dtype=numpy.float32)
|
material_color_map = numpy.zeros((len(extruders), 4), dtype=numpy.float32)
|
||||||
for extruder in extruders:
|
for extruder in extruders:
|
||||||
material = extruder.findContainer({"type": "material"})
|
|
||||||
position = int(extruder.getMetaDataEntry("position", default="0")) # Get the position
|
position = int(extruder.getMetaDataEntry("position", default="0")) # Get the position
|
||||||
color_code = material.getMetaDataEntry("color_code", default="#e0e000")
|
color_code = extruder.material.getMetaDataEntry("color_code", default="#e0e000")
|
||||||
color = colorCodeToRGBA(color_code)
|
color = colorCodeToRGBA(color_code)
|
||||||
material_color_map[position, :] = color
|
material_color_map[position, :] = color
|
||||||
else:
|
else:
|
||||||
# Single extruder via global stack.
|
# Single extruder via global stack.
|
||||||
material_color_map = numpy.zeros((1, 4), dtype=numpy.float32)
|
material_color_map = numpy.zeros((1, 4), dtype=numpy.float32)
|
||||||
material = global_container_stack.findContainer({"type": "material"})
|
color_code = global_container_stack.material.getMetaDataEntry("color_code", default="#e0e000")
|
||||||
color_code = "#e0e000"
|
|
||||||
if material:
|
|
||||||
if material.getMetaDataEntry("color_code") is not None:
|
|
||||||
color_code = material.getMetaDataEntry("color_code")
|
|
||||||
color = colorCodeToRGBA(color_code)
|
color = colorCodeToRGBA(color_code)
|
||||||
material_color_map[0, :] = color
|
material_color_map[0, :] = color
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,14 @@ class GcodeStartEndFormatter(Formatter):
|
||||||
|
|
||||||
## Job class that builds up the message of scene data to send to CuraEngine.
|
## Job class that builds up the message of scene data to send to CuraEngine.
|
||||||
class StartSliceJob(Job):
|
class StartSliceJob(Job):
|
||||||
|
## Meshes that are sent to the engine regardless of being outside of the
|
||||||
|
# build volume.
|
||||||
|
#
|
||||||
|
# If these settings are True for any mesh, the build volume is ignored.
|
||||||
|
# Note that Support Mesh is not in here because it actually generates
|
||||||
|
# g-code in the volume of the mesh.
|
||||||
|
_not_printed_mesh_settings = {"anti_overhang_mesh", "infill_mesh", "cutting_mesh"}
|
||||||
|
|
||||||
def __init__(self, slice_message):
|
def __init__(self, slice_message):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
@ -132,7 +140,8 @@ class StartSliceJob(Job):
|
||||||
temp_list = []
|
temp_list = []
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
||||||
if not getattr(node, "_outside_buildarea", False):
|
if not getattr(node, "_outside_buildarea", False)\
|
||||||
|
or (node.callDecoration("getStack") and any(node.callDecoration("getStack").getProperty(setting, "value") for setting in self._not_printed_mesh_settings)):
|
||||||
temp_list.append(node)
|
temp_list.append(node)
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "CuraEngine Backend",
|
"name": "CuraEngine Backend",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"description": "Provides the link to the CuraEngine slicing backend.",
|
"description": "Provides the link to the CuraEngine slicing backend.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Cura Profile Reader",
|
"name": "Cura Profile Reader",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides support for importing Cura profiles.",
|
"description": "Provides support for importing Cura profiles.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Cura Profile Writer",
|
"name": "Cura Profile Writer",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides support for exporting Cura profiles.",
|
"description": "Provides support for exporting Cura profiles.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "GCode Profile Reader",
|
"name": "GCode Profile Reader",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides support for importing profiles from g-code files.",
|
"description": "Provides support for importing profiles from g-code files.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2016 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.Mesh.MeshWriter import MeshWriter
|
from UM.Mesh.MeshWriter import MeshWriter
|
||||||
|
@ -113,7 +113,7 @@ class GCodeWriter(MeshWriter):
|
||||||
|
|
||||||
# Ensure that quality_type is set. (Can happen if we have empty quality changes).
|
# Ensure that quality_type is set. (Can happen if we have empty quality changes).
|
||||||
if flat_global_container.getMetaDataEntry("quality_type", None) is None:
|
if flat_global_container.getMetaDataEntry("quality_type", None) is None:
|
||||||
flat_global_container.addMetaDataEntry("quality_type", stack.findContainer({"type": "quality"}).getMetaDataEntry("quality_type", "normal"))
|
flat_global_container.addMetaDataEntry("quality_type", stack.quality.getMetaDataEntry("quality_type", "normal"))
|
||||||
|
|
||||||
serialized = flat_global_container.serialize()
|
serialized = flat_global_container.serialize()
|
||||||
data = {"global_quality": serialized}
|
data = {"global_quality": serialized}
|
||||||
|
@ -134,7 +134,7 @@ class GCodeWriter(MeshWriter):
|
||||||
|
|
||||||
# Ensure that quality_type is set. (Can happen if we have empty quality changes).
|
# Ensure that quality_type is set. (Can happen if we have empty quality changes).
|
||||||
if flat_extruder_quality.getMetaDataEntry("quality_type", None) is None:
|
if flat_extruder_quality.getMetaDataEntry("quality_type", None) is None:
|
||||||
flat_extruder_quality.addMetaDataEntry("quality_type", extruder.findContainer({"type": "quality"}).getMetaDataEntry("quality_type", "normal"))
|
flat_extruder_quality.addMetaDataEntry("quality_type", extruder.quality.getMetaDataEntry("quality_type", "normal"))
|
||||||
extruder_serialized = flat_extruder_quality.serialize()
|
extruder_serialized = flat_extruder_quality.serialize()
|
||||||
data.setdefault("extruder_quality", []).append(extruder_serialized)
|
data.setdefault("extruder_quality", []).append(extruder_serialized)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "GCode Writer",
|
"name": "GCode Writer",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Writes GCode to a file.",
|
"description": "Writes GCode to a file.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Image Reader",
|
"name": "Image Reader",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Enables ability to generate printable geometry from 2D image files.",
|
"description": "Enables ability to generate printable geometry from 2D image files.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -39,6 +39,8 @@ Item
|
||||||
height: parent.height
|
height: parent.height
|
||||||
z: slider.z - 1
|
z: slider.z - 1
|
||||||
color: UM.Theme.getColor("tool_panel_background")
|
color: UM.Theme.getColor("tool_panel_background")
|
||||||
|
borderWidth: UM.Theme.getSize("default_lining").width
|
||||||
|
borderColor: UM.Theme.getColor("lining")
|
||||||
|
|
||||||
target: parent.buttonTarget
|
target: parent.buttonTarget
|
||||||
arrowSize: UM.Theme.getSize("default_arrow").width
|
arrowSize: UM.Theme.getSize("default_arrow").width
|
||||||
|
@ -530,27 +532,20 @@ Item
|
||||||
target: Qt.point(0, slider.activeHandle.y + slider.activeHandle.height / 2)
|
target: Qt.point(0, slider.activeHandle.y + slider.activeHandle.height / 2)
|
||||||
arrowSize: UM.Theme.getSize("default_arrow").width
|
arrowSize: UM.Theme.getSize("default_arrow").width
|
||||||
|
|
||||||
height: (Math.floor(UM.Theme.getSize("slider_handle").height + UM.Theme.getSize("default_margin").height) / 2) * 2 // Make sure height has an integer middle so drawing a pointy border is easier
|
height: UM.Theme.getSize("slider_handle").height + UM.Theme.getSize("default_margin").height
|
||||||
width: valueLabel.width + UM.Theme.getSize("default_margin").width
|
width: valueLabel.width + UM.Theme.getSize("default_margin").width
|
||||||
Behavior on height { NumberAnimation { duration: 50; } }
|
Behavior on height { NumberAnimation { duration: 50; } }
|
||||||
|
|
||||||
color: UM.Theme.getColor("lining");
|
color: UM.Theme.getColor("tool_panel_background")
|
||||||
|
borderColor: UM.Theme.getColor("lining")
|
||||||
|
borderWidth: UM.Theme.getSize("default_lining").width
|
||||||
|
|
||||||
visible: slider.layersVisible
|
visible: slider.layersVisible
|
||||||
|
|
||||||
UM.PointingRectangle
|
|
||||||
{
|
|
||||||
color: UM.Theme.getColor("tool_panel_background")
|
|
||||||
target: Qt.point(0, height / 2 + UM.Theme.getSize("default_lining").width)
|
|
||||||
arrowSize: UM.Theme.getSize("default_arrow").width
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: UM.Theme.getSize("default_lining").width
|
|
||||||
|
|
||||||
MouseArea //Catch all mouse events (so scene doesnt handle them)
|
MouseArea //Catch all mouse events (so scene doesnt handle them)
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TextField
|
TextField
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Layer View",
|
"name": "Layer View",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides the Layer view.",
|
"description": "Provides the Layer view.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Legacy Cura Profile Reader",
|
"name": "Legacy Cura Profile Reader",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides support for importing profiles from legacy Cura versions.",
|
"description": "Provides support for importing profiles from legacy Cura versions.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Per Model Settings Tool",
|
"name": "Per Model Settings Tool",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides the Per Model Settings.",
|
"description": "Provides the Per Model Settings.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -8,7 +8,7 @@ from UM.PluginRegistry import PluginRegistry
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Version import Version
|
from UM.Version import Version
|
||||||
|
|
||||||
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
|
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
||||||
from PyQt5.QtCore import QUrl, QObject, Qt, pyqtProperty, pyqtSignal, pyqtSlot
|
from PyQt5.QtCore import QUrl, QObject, Qt, pyqtProperty, pyqtSignal, pyqtSlot
|
||||||
from PyQt5.QtQml import QQmlComponent, QQmlContext
|
from PyQt5.QtQml import QQmlComponent, QQmlContext
|
||||||
|
|
||||||
|
@ -66,7 +66,9 @@ class PluginBrowser(QObject, Extension):
|
||||||
self._createDialog()
|
self._createDialog()
|
||||||
self._dialog.show()
|
self._dialog.show()
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
def requestPluginList(self):
|
def requestPluginList(self):
|
||||||
|
Logger.log("i", "Requesting plugin list")
|
||||||
url = QUrl(self._api_url + "plugins")
|
url = QUrl(self._api_url + "plugins")
|
||||||
self._plugin_list_request = QNetworkRequest(url)
|
self._plugin_list_request = QNetworkRequest(url)
|
||||||
self._plugin_list_request.setRawHeader(*self._request_header)
|
self._plugin_list_request.setRawHeader(*self._request_header)
|
||||||
|
@ -94,17 +96,23 @@ class PluginBrowser(QObject, Extension):
|
||||||
def _onDownloadPluginProgress(self, bytes_sent, bytes_total):
|
def _onDownloadPluginProgress(self, bytes_sent, bytes_total):
|
||||||
if bytes_total > 0:
|
if bytes_total > 0:
|
||||||
new_progress = bytes_sent / bytes_total * 100
|
new_progress = bytes_sent / bytes_total * 100
|
||||||
if new_progress > self._download_progress:
|
self.setDownloadProgress(new_progress)
|
||||||
self._download_progress = new_progress
|
|
||||||
self.onDownloadProgressChanged.emit()
|
|
||||||
self._download_progress = new_progress
|
|
||||||
if new_progress == 100.0:
|
if new_progress == 100.0:
|
||||||
self.setIsDownloading(False)
|
self.setIsDownloading(False)
|
||||||
self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadPluginProgress)
|
self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadPluginProgress)
|
||||||
self._temp_plugin_file = tempfile.NamedTemporaryFile(suffix = ".curaplugin")
|
|
||||||
self._temp_plugin_file.write(self._download_plugin_reply.readAll())
|
|
||||||
|
|
||||||
result = PluginRegistry.getInstance().installPlugin("file://" + self._temp_plugin_file.name)
|
# must not delete the temporary file on Windows
|
||||||
|
self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curaplugin", delete = False)
|
||||||
|
location = self._temp_plugin_file.name
|
||||||
|
|
||||||
|
# write first and close, otherwise on Windows, it cannot read the file
|
||||||
|
self._temp_plugin_file.write(self._download_plugin_reply.readAll())
|
||||||
|
self._temp_plugin_file.close()
|
||||||
|
|
||||||
|
# open as read
|
||||||
|
if not location.startswith("/"):
|
||||||
|
location = "/" + location # Ensure that it starts with a /, as otherwise it doesn't work on windows.
|
||||||
|
result = PluginRegistry.getInstance().installPlugin("file://" + location)
|
||||||
|
|
||||||
self._newly_installed_plugin_ids.append(result["id"])
|
self._newly_installed_plugin_ids.append(result["id"])
|
||||||
self.pluginsMetadataChanged.emit()
|
self.pluginsMetadataChanged.emit()
|
||||||
|
@ -117,6 +125,11 @@ class PluginBrowser(QObject, Extension):
|
||||||
def downloadProgress(self):
|
def downloadProgress(self):
|
||||||
return self._download_progress
|
return self._download_progress
|
||||||
|
|
||||||
|
def setDownloadProgress(self, progress):
|
||||||
|
if progress != self._download_progress:
|
||||||
|
self._download_progress = progress
|
||||||
|
self.onDownloadProgressChanged.emit()
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def downloadAndInstallPlugin(self, url):
|
def downloadAndInstallPlugin(self, url):
|
||||||
Logger.log("i", "Attempting to download & install plugin from %s", url)
|
Logger.log("i", "Attempting to download & install plugin from %s", url)
|
||||||
|
@ -124,11 +137,21 @@ class PluginBrowser(QObject, Extension):
|
||||||
self._download_plugin_request = QNetworkRequest(url)
|
self._download_plugin_request = QNetworkRequest(url)
|
||||||
self._download_plugin_request.setRawHeader(*self._request_header)
|
self._download_plugin_request.setRawHeader(*self._request_header)
|
||||||
self._download_plugin_reply = self._network_manager.get(self._download_plugin_request)
|
self._download_plugin_reply = self._network_manager.get(self._download_plugin_request)
|
||||||
self._download_progress = 0
|
self.setDownloadProgress(0)
|
||||||
self.setIsDownloading(True)
|
self.setIsDownloading(True)
|
||||||
self.onDownloadProgressChanged.emit()
|
|
||||||
self._download_plugin_reply.downloadProgress.connect(self._onDownloadPluginProgress)
|
self._download_plugin_reply.downloadProgress.connect(self._onDownloadPluginProgress)
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def cancelDownload(self):
|
||||||
|
Logger.log("i", "user cancelled the download of a plugin")
|
||||||
|
self._download_plugin_reply.abort()
|
||||||
|
self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadPluginProgress)
|
||||||
|
self._download_plugin_reply = None
|
||||||
|
self._download_plugin_request = None
|
||||||
|
|
||||||
|
self.setDownloadProgress(0)
|
||||||
|
self.setIsDownloading(False)
|
||||||
|
|
||||||
@pyqtProperty(QObject, notify=pluginsMetadataChanged)
|
@pyqtProperty(QObject, notify=pluginsMetadataChanged)
|
||||||
def pluginsModel(self):
|
def pluginsModel(self):
|
||||||
if self._plugins_model is None:
|
if self._plugins_model is None:
|
||||||
|
@ -180,6 +203,20 @@ class PluginBrowser(QObject, Extension):
|
||||||
|
|
||||||
def _onRequestFinished(self, reply):
|
def _onRequestFinished(self, reply):
|
||||||
reply_url = reply.url().toString()
|
reply_url = reply.url().toString()
|
||||||
|
if reply.error() == QNetworkReply.TimeoutError:
|
||||||
|
Logger.log("w", "Got a timeout.")
|
||||||
|
# Reset everything.
|
||||||
|
self.setDownloadProgress(0)
|
||||||
|
self.setIsDownloading(False)
|
||||||
|
if self._download_plugin_reply:
|
||||||
|
self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadPluginProgress)
|
||||||
|
self._download_plugin_reply.abort()
|
||||||
|
self._download_plugin_reply = None
|
||||||
|
return
|
||||||
|
elif reply.error() == QNetworkReply.HostNotFoundError:
|
||||||
|
Logger.log("w", "Unable to reach server.")
|
||||||
|
return
|
||||||
|
|
||||||
if reply.operation() == QNetworkAccessManager.GetOperation:
|
if reply.operation() == QNetworkAccessManager.GetOperation:
|
||||||
if reply_url == self._api_url + "plugins":
|
if reply_url == self._api_url + "plugins":
|
||||||
try:
|
try:
|
||||||
|
@ -193,9 +230,20 @@ class PluginBrowser(QObject, Extension):
|
||||||
# Ignore any operation that is not a get operation
|
# Ignore any operation that is not a get operation
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def _onNetworkAccesibleChanged(self, accessible):
|
||||||
|
if accessible == 0:
|
||||||
|
self.setDownloadProgress(0)
|
||||||
|
self.setIsDownloading(False)
|
||||||
|
if self._download_plugin_reply:
|
||||||
|
self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadPluginProgress)
|
||||||
|
self._download_plugin_reply.abort()
|
||||||
|
self._download_plugin_reply = None
|
||||||
|
|
||||||
def _createNetworkManager(self):
|
def _createNetworkManager(self):
|
||||||
if self._network_manager:
|
if self._network_manager:
|
||||||
self._network_manager.finished.disconnect(self._onRequestFinished)
|
self._network_manager.finished.disconnect(self._onRequestFinished)
|
||||||
|
self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccesibleChanged)
|
||||||
|
|
||||||
self._network_manager = QNetworkAccessManager()
|
self._network_manager = QNetworkAccessManager()
|
||||||
self._network_manager.finished.connect(self._onRequestFinished)
|
self._network_manager.finished.connect(self._onRequestFinished)
|
||||||
|
self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged)
|
|
@ -14,6 +14,11 @@ UM.Dialog
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: topBar
|
||||||
|
height: childrenRect.height;
|
||||||
|
width: parent.width
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
id: introText
|
id: introText
|
||||||
|
@ -21,11 +26,21 @@ UM.Dialog
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 30
|
height: 30
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: refresh
|
||||||
|
text: catalog.i18nc("@action:button", "Refresh")
|
||||||
|
onClicked: manager.requestPluginList()
|
||||||
|
anchors.right: parent.right
|
||||||
|
enabled: !manager.isDownloading
|
||||||
|
}
|
||||||
|
}
|
||||||
ScrollView
|
ScrollView
|
||||||
{
|
{
|
||||||
width: parent.width
|
width: parent.width
|
||||||
anchors.top: introText.bottom
|
anchors.top: topBar.bottom
|
||||||
anchors.bottom: progressbar.top
|
anchors.bottom: bottomBar.top
|
||||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
||||||
frameVisible: true
|
frameVisible: true
|
||||||
ListView
|
ListView
|
||||||
|
@ -34,19 +49,45 @@ UM.Dialog
|
||||||
model: manager.pluginsModel
|
model: manager.pluginsModel
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property var activePlugin
|
||||||
delegate: pluginDelegate
|
delegate: pluginDelegate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: bottomBar
|
||||||
|
width: parent.width
|
||||||
|
height: closeButton.height
|
||||||
|
anchors.bottom:parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
ProgressBar
|
ProgressBar
|
||||||
{
|
{
|
||||||
id: progressbar
|
id: progressbar
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
style: UM.Theme.styles.progressbar
|
|
||||||
minimumValue: 0;
|
minimumValue: 0;
|
||||||
maximumValue: 100
|
maximumValue: 100
|
||||||
width: parent.width
|
anchors.left:parent.left
|
||||||
height: 10
|
anchors.right: closeButton.left
|
||||||
value: manager.downloadProgress
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
value: manager.isDownloading ? manager.downloadProgress : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: closeButton
|
||||||
|
text: catalog.i18nc("@action:button", "Close")
|
||||||
|
iconName: "dialog-close"
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
if (manager.isDownloading)
|
||||||
|
{
|
||||||
|
manager.cancelDownload()
|
||||||
|
}
|
||||||
|
base.close();
|
||||||
|
}
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item
|
Item
|
||||||
|
@ -58,10 +99,11 @@ UM.Dialog
|
||||||
Rectangle
|
Rectangle
|
||||||
{
|
{
|
||||||
width: pluginList.width;
|
width: pluginList.width;
|
||||||
height: childrenRect.height;
|
height: texts.height;
|
||||||
color: index % 2 ? palette.base : palette.alternateBase
|
color: index % 2 ? palette.base : palette.alternateBase
|
||||||
Column
|
Column
|
||||||
{
|
{
|
||||||
|
id: texts
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
@ -88,13 +130,48 @@ UM.Dialog
|
||||||
Button
|
Button
|
||||||
{
|
{
|
||||||
id: downloadButton
|
id: downloadButton
|
||||||
text: !model.already_installed ? catalog.i18nc("@action:button", "Download") : model.can_upgrade ? catalog.i18nc("@action:button", "Upgrade") : catalog.i18nc("@action:button", "Download")
|
text:
|
||||||
onClicked: manager.downloadAndInstallPlugin(model.file_location)
|
{
|
||||||
|
if (manager.isDownloading && pluginList.activePlugin == model)
|
||||||
|
{
|
||||||
|
return catalog.i18nc("@action:button", "Cancel");
|
||||||
|
}
|
||||||
|
else if (model.already_installed)
|
||||||
|
{
|
||||||
|
if (model.can_upgrade)
|
||||||
|
{
|
||||||
|
return catalog.i18nc("@action:button", "Upgrade");
|
||||||
|
}
|
||||||
|
return catalog.i18nc("@action:button", "Installed");
|
||||||
|
}
|
||||||
|
return catalog.i18nc("@action:button", "Download");
|
||||||
|
}
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
if(!manager.isDownloading)
|
||||||
|
{
|
||||||
|
pluginList.activePlugin = model;
|
||||||
|
manager.downloadAndInstallPlugin(model.file_location);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
manager.cancelDownload();
|
||||||
|
}
|
||||||
|
}
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
enabled: (!model.already_installed || model.can_upgrade) && !manager.isDownloading
|
enabled:
|
||||||
|
{
|
||||||
|
if (manager.isDownloading)
|
||||||
|
{
|
||||||
|
return (pluginList.activePlugin == model);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (!model.already_installed || model.can_upgrade);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Plugin Browser",
|
"name": "Plugin Browser",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
"description": "Find, manage and install new plugins."
|
"description": "Find, manage and install new plugins."
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
# Copyright (c) 2015 Ultimaker B.V.
|
# Copyright (c) 2015 Ultimaker B.V.
|
||||||
# Copyright (c) 2013 David Braam
|
# Copyright (c) 2013 David Braam
|
||||||
# Uranium is released under the terms of the AGPLv3 or higher.
|
# Uranium is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
|
||||||
catalog = i18nCatalog("cura")
|
|
||||||
|
|
||||||
from . import RemovableDrivePlugin
|
from . import RemovableDrivePlugin
|
||||||
|
|
||||||
import string
|
import string
|
||||||
import ctypes # type: ignore
|
import ctypes
|
||||||
from ctypes import wintypes # Using ctypes.wintypes in the code below does not seem to work
|
from ctypes import wintypes # Using ctypes.wintypes in the code below does not seem to work
|
||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
# Ignore windows error popups. Fixes the whole "Can't open drive X" when user has an SD card reader.
|
||||||
|
ctypes.windll.kernel32.SetErrorMode(1)
|
||||||
|
|
||||||
# WinAPI Constants that we need
|
# WinAPI Constants that we need
|
||||||
# Hardcoded here due to stupid WinDLL stuff that does not give us access to these values.
|
# Hardcoded here due to stupid WinDLL stuff that does not give us access to these values.
|
||||||
DRIVE_REMOVABLE = 2 # [CodeStyle: Windows Enum value]
|
DRIVE_REMOVABLE = 2 # [CodeStyle: Windows Enum value]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Removable Drive Output Device Plugin",
|
"name": "Removable Drive Output Device Plugin",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"description": "Provides removable drive hotplugging and writing support.",
|
"description": "Provides removable drive hotplugging and writing support.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,69 +1,37 @@
|
||||||
# Copyright (c) 2015 Ultimaker B.V.
|
# Copyright (c) 2015 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 typing import Any
|
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
|
|
||||||
from UM.Extension import Extension
|
from UM.Extension import Extension
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Preferences import Preferences
|
from UM.Preferences import Preferences
|
||||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
from UM.Scene.SceneNode import SceneNode
|
|
||||||
from UM.Message import Message
|
from UM.Message import Message
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Platform import Platform
|
|
||||||
|
import time
|
||||||
|
|
||||||
from UM.Qt.Duration import DurationFormat
|
from UM.Qt.Duration import DurationFormat
|
||||||
from UM.Job import Job
|
|
||||||
|
from .SliceInfoJob import SliceInfoJob
|
||||||
|
|
||||||
import platform
|
import platform
|
||||||
import math
|
import math
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import ssl
|
|
||||||
import hashlib
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
class SliceInfoJob(Job):
|
|
||||||
data = None # type: Any
|
|
||||||
url = None # type: str
|
|
||||||
|
|
||||||
def __init__(self, url, data):
|
|
||||||
super().__init__()
|
|
||||||
self.url = url
|
|
||||||
self.data = data
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
if not self.url or not self.data:
|
|
||||||
Logger.log("e", "URL or DATA for sending slice info was not set!")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Submit data
|
|
||||||
kwoptions = {"data" : self.data,
|
|
||||||
"timeout" : 5
|
|
||||||
}
|
|
||||||
|
|
||||||
if Platform.isOSX():
|
|
||||||
kwoptions["context"] = ssl._create_unverified_context()
|
|
||||||
|
|
||||||
Logger.log("d", "Sending anonymous slice info to [%s]...", self.url)
|
|
||||||
|
|
||||||
try:
|
|
||||||
f = urllib.request.urlopen(self.url, **kwoptions)
|
|
||||||
Logger.log("i", "Sent anonymous slice info.")
|
|
||||||
f.close()
|
|
||||||
except urllib.error.HTTPError as http_exception:
|
|
||||||
Logger.log("e", "An HTTP error occurred while trying to send slice information: %s" % http_exception)
|
|
||||||
except Exception as e: # We don't want any exception to cause problems
|
|
||||||
Logger.log("e", "An exception occurred while trying to send slice information: %s" % e)
|
|
||||||
|
|
||||||
## This Extension runs in the background and sends several bits of information to the Ultimaker servers.
|
## This Extension runs in the background and sends several bits of information to the Ultimaker servers.
|
||||||
# The data is only sent when the user in question gave permission to do so. All data is anonymous and
|
# The data is only sent when the user in question gave permission to do so. All data is anonymous and
|
||||||
# no model files are being sent (Just a SHA256 hash of the model).
|
# no model files are being sent (Just a SHA256 hash of the model).
|
||||||
class SliceInfo(Extension):
|
class SliceInfo(Extension):
|
||||||
info_url = "https://stats.youmagine.com/curastats/slice"
|
info_url = "http://stats.ultimaker.com/api/cura"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -87,59 +55,137 @@ class SliceInfo(Extension):
|
||||||
Logger.log("d", "'info/send_slice_info' is turned off.")
|
Logger.log("d", "'info/send_slice_info' is turned off.")
|
||||||
return # Do nothing, user does not want to send data
|
return # Do nothing, user does not want to send data
|
||||||
|
|
||||||
|
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
|
print_information = Application.getInstance().getPrintInformation()
|
||||||
|
|
||||||
|
data = dict() # The data that we're going to submit.
|
||||||
|
data["time_stamp"] = time.time()
|
||||||
|
data["schema_version"] = 0
|
||||||
|
data["cura_version"] = Application.getInstance().getVersion()
|
||||||
|
|
||||||
|
active_mode = Preferences.getInstance().getValue("cura/active_mode")
|
||||||
|
if active_mode == 0:
|
||||||
|
data["active_mode"] = "recommended"
|
||||||
|
else:
|
||||||
|
data["active_mode"] = "custom"
|
||||||
|
|
||||||
|
data["machine_settings_changed_by_user"] = global_container_stack.definitionChanges.getId() != "empty"
|
||||||
|
data["language"] = Preferences.getInstance().getValue("general/language")
|
||||||
|
data["os"] = {"type": platform.system(), "version": platform.version()}
|
||||||
|
|
||||||
|
data["active_machine"] = {"definition_id": global_container_stack.definition.getId(), "manufacturer": global_container_stack.definition.getMetaData().get("manufacturer","")}
|
||||||
|
|
||||||
|
data["extruders"] = []
|
||||||
|
extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId()))
|
||||||
|
extruders = sorted(extruders, key = lambda extruder: extruder.getMetaDataEntry("position"))
|
||||||
|
|
||||||
|
if not extruders:
|
||||||
|
extruders = [global_container_stack]
|
||||||
|
|
||||||
|
for extruder in extruders:
|
||||||
|
extruder_dict = dict()
|
||||||
|
extruder_dict["active"] = ExtruderManager.getInstance().getActiveExtruderStack() == extruder
|
||||||
|
extruder_dict["material"] = {"GUID": extruder.material.getMetaData().get("GUID", ""),
|
||||||
|
"type": extruder.material.getMetaData().get("material", ""),
|
||||||
|
"brand": extruder.material.getMetaData().get("brand", "")
|
||||||
|
}
|
||||||
|
extruder_dict["material_used"] = print_information.materialLengths[int(extruder.getMetaDataEntry("position", "0"))]
|
||||||
|
extruder_dict["variant"] = extruder.variant.getName()
|
||||||
|
extruder_dict["nozzle_size"] = extruder.getProperty("machine_nozzle_size", "value")
|
||||||
|
|
||||||
|
extruder_settings = dict()
|
||||||
|
extruder_settings["wall_line_count"] = extruder.getProperty("wall_line_count", "value")
|
||||||
|
extruder_settings["retraction_enable"] = extruder.getProperty("retraction_enable", "value")
|
||||||
|
extruder_settings["infill_sparse_density"] = extruder.getProperty("infill_sparse_density", "value")
|
||||||
|
extruder_settings["infill_pattern"] = extruder.getProperty("infill_pattern", "value")
|
||||||
|
extruder_settings["gradual_infill_steps"] = extruder.getProperty("gradual_infill_steps", "value")
|
||||||
|
extruder_settings["default_material_print_temperature"] = extruder.getProperty("default_material_print_temperature", "value")
|
||||||
|
extruder_settings["material_print_temperature"] = extruder.getProperty("material_print_temperature", "value")
|
||||||
|
extruder_dict["extruder_settings"] = extruder_settings
|
||||||
|
data["extruders"].append(extruder_dict)
|
||||||
|
|
||||||
|
data["quality_profile"] = global_container_stack.quality.getMetaData().get("quality_type")
|
||||||
|
|
||||||
|
data["models"] = []
|
||||||
# Listing all files placed on the build plate
|
# Listing all files placed on the build plate
|
||||||
modelhashes = []
|
|
||||||
for node in DepthFirstIterator(CuraApplication.getInstance().getController().getScene().getRoot()):
|
for node in DepthFirstIterator(CuraApplication.getInstance().getController().getScene().getRoot()):
|
||||||
if node.callDecoration("isSliceable"):
|
if node.callDecoration("isSliceable"):
|
||||||
modelhashes.append(node.getMeshData().getHash())
|
model = dict()
|
||||||
|
model["hash"] = node.getMeshData().getHash()
|
||||||
|
bounding_box = node.getBoundingBox()
|
||||||
|
model["bounding_box"] = {"minimum": {"x": bounding_box.minimum.x,
|
||||||
|
"y": bounding_box.minimum.y,
|
||||||
|
"z": bounding_box.minimum.z},
|
||||||
|
"maximum": {"x": bounding_box.maximum.x,
|
||||||
|
"y": bounding_box.maximum.y,
|
||||||
|
"z": bounding_box.maximum.z}}
|
||||||
|
model["transformation"] = {"data": str(node.getWorldTransformation().getData()).replace("\n", "")}
|
||||||
|
extruder_position = node.callDecoration("getActiveExtruderPosition")
|
||||||
|
model["extruder"] = 0 if extruder_position is None else int(extruder_position)
|
||||||
|
|
||||||
# Creating md5sums and formatting them as discussed on JIRA
|
model_settings = dict()
|
||||||
modelhash_formatted = ",".join(modelhashes)
|
model_stack = node.callDecoration("getStack")
|
||||||
|
if model_stack:
|
||||||
|
model_settings["support_enabled"] = model_stack.getProperty("support_enable", "value")
|
||||||
|
model_settings["support_extruder_nr"] = int(model_stack.getProperty("support_extruder_nr", "value"))
|
||||||
|
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
# Mesh modifiers;
|
||||||
|
model_settings["infill_mesh"] = model_stack.getProperty("infill_mesh", "value")
|
||||||
|
model_settings["cutting_mesh"] = model_stack.getProperty("cutting_mesh", "value")
|
||||||
|
model_settings["support_mesh"] = model_stack.getProperty("support_mesh", "value")
|
||||||
|
model_settings["anti_overhang_mesh"] = model_stack.getProperty("anti_overhang_mesh", "value")
|
||||||
|
|
||||||
# Get total material used (in mm^3)
|
model_settings["wall_line_count"] = model_stack.getProperty("wall_line_count", "value")
|
||||||
print_information = Application.getInstance().getPrintInformation()
|
model_settings["retraction_enable"] = model_stack.getProperty("retraction_enable", "value")
|
||||||
material_radius = 0.5 * global_container_stack.getProperty("material_diameter", "value")
|
|
||||||
|
|
||||||
# Send material per extruder
|
# Infill settings
|
||||||
material_used = [str(math.pi * material_radius * material_radius * material_length) for material_length in print_information.materialLengths]
|
model_settings["infill_sparse_density"] = model_stack.getProperty("infill_sparse_density", "value")
|
||||||
material_used = ",".join(material_used)
|
model_settings["infill_pattern"] = model_stack.getProperty("infill_pattern", "value")
|
||||||
|
model_settings["gradual_infill_steps"] = model_stack.getProperty("gradual_infill_steps", "value")
|
||||||
|
|
||||||
containers = { "": global_container_stack.serialize() }
|
model["model_settings"] = model_settings
|
||||||
for container in global_container_stack.getContainers():
|
|
||||||
container_id = container.getId()
|
|
||||||
try:
|
|
||||||
container_serialized = container.serialize()
|
|
||||||
except NotImplementedError:
|
|
||||||
Logger.log("w", "Container %s could not be serialized!", container_id)
|
|
||||||
continue
|
|
||||||
if container_serialized:
|
|
||||||
containers[container_id] = container_serialized
|
|
||||||
else:
|
|
||||||
Logger.log("i", "No data found in %s to be serialized!", container_id)
|
|
||||||
|
|
||||||
# Bundle the collected data
|
data["models"].append(model)
|
||||||
submitted_data = {
|
|
||||||
"processor": platform.processor(),
|
print_times = print_information.printTimesPerFeature
|
||||||
"machine": platform.machine(),
|
data["print_times"] = {"travel": int(print_times["travel"].getDisplayString(DurationFormat.Format.Seconds)),
|
||||||
"platform": platform.platform(),
|
"support": int(print_times["support"].getDisplayString(DurationFormat.Format.Seconds)),
|
||||||
"settings": json.dumps(containers), # bundle of containers with their serialized contents
|
"infill": int(print_times["infill"].getDisplayString(DurationFormat.Format.Seconds)),
|
||||||
"version": Application.getInstance().getVersion(),
|
"total": int(print_information.currentPrintTime.getDisplayString(DurationFormat.Format.Seconds))}
|
||||||
"modelhash": modelhash_formatted,
|
|
||||||
"printtime": print_information.currentPrintTime.getDisplayString(DurationFormat.Format.ISO8601),
|
print_settings = dict()
|
||||||
"filament": material_used,
|
print_settings["layer_height"] = global_container_stack.getProperty("layer_height", "value")
|
||||||
"language": Preferences.getInstance().getValue("general/language"),
|
|
||||||
}
|
# Support settings
|
||||||
|
print_settings["support_enabled"] = global_container_stack.getProperty("support_enable", "value")
|
||||||
|
print_settings["support_extruder_nr"] = int(global_container_stack.getProperty("support_extruder_nr", "value"))
|
||||||
|
|
||||||
|
# Platform adhesion settings
|
||||||
|
print_settings["adhesion_type"] = global_container_stack.getProperty("adhesion_type", "value")
|
||||||
|
|
||||||
|
# Shell settings
|
||||||
|
print_settings["wall_line_count"] = global_container_stack.getProperty("wall_line_count", "value")
|
||||||
|
print_settings["retraction_enable"] = global_container_stack.getProperty("retraction_enable", "value")
|
||||||
|
|
||||||
|
# Prime tower settings
|
||||||
|
print_settings["prime_tower_enable"] = global_container_stack.getProperty("prime_tower_enable", "value")
|
||||||
|
|
||||||
|
# Infill settings
|
||||||
|
print_settings["infill_sparse_density"] = global_container_stack.getProperty("infill_sparse_density", "value")
|
||||||
|
print_settings["infill_pattern"] = global_container_stack.getProperty("infill_pattern", "value")
|
||||||
|
print_settings["gradual_infill_steps"] = global_container_stack.getProperty("gradual_infill_steps", "value")
|
||||||
|
|
||||||
|
print_settings["print_sequence"] = global_container_stack.getProperty("print_sequence", "value")
|
||||||
|
|
||||||
|
data["print_settings"] = print_settings
|
||||||
|
|
||||||
# Convert data to bytes
|
# Convert data to bytes
|
||||||
submitted_data = urllib.parse.urlencode(submitted_data)
|
binary_data = json.dumps(data).encode("utf-8")
|
||||||
binary_data = submitted_data.encode("utf-8")
|
|
||||||
|
|
||||||
# Sending slice info non-blocking
|
# Sending slice info non-blocking
|
||||||
reportJob = SliceInfoJob(self.info_url, binary_data)
|
reportJob = SliceInfoJob(self.info_url, binary_data)
|
||||||
reportJob.start()
|
reportJob.start()
|
||||||
except Exception as e:
|
except Exception:
|
||||||
# We really can't afford to have a mistake here, as this would break the sending of g-code to a device
|
# We really can't afford to have a mistake here, as this would break the sending of g-code to a device
|
||||||
# (Either saving or directly to a printer). The functionality of the slice data is not *that* important.
|
# (Either saving or directly to a printer). The functionality of the slice data is not *that* important.
|
||||||
Logger.log("e", "Exception raised while sending slice info: %s" %(repr(e))) # But we should be notified about these problems of course.
|
Logger.logException("e", "Exception raised while sending slice info.") # But we should be notified about these problems of course.
|
||||||
|
|
38
plugins/SliceInfoPlugin/SliceInfoJob.py
Normal file
38
plugins/SliceInfoPlugin/SliceInfoJob.py
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
from UM.Job import Job
|
||||||
|
from UM.Logger import Logger
|
||||||
|
from UM.Platform import Platform
|
||||||
|
|
||||||
|
import ssl
|
||||||
|
import urllib.request
|
||||||
|
import urllib.error
|
||||||
|
|
||||||
|
|
||||||
|
class SliceInfoJob(Job):
|
||||||
|
def __init__(self, url, data):
|
||||||
|
super().__init__()
|
||||||
|
self._url = url
|
||||||
|
self._data = data
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
if not self._url or not self._data:
|
||||||
|
Logger.log("e", "URL or DATA for sending slice info was not set!")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Submit data
|
||||||
|
kwoptions = {"data" : self._data, "timeout" : 5}
|
||||||
|
|
||||||
|
if Platform.isOSX():
|
||||||
|
kwoptions["context"] = ssl._create_unverified_context()
|
||||||
|
|
||||||
|
Logger.log("i", "Sending anonymous slice info to [%s]...", self._url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
f = urllib.request.urlopen(self._url, **kwoptions)
|
||||||
|
Logger.log("i", "Sent anonymous slice info.")
|
||||||
|
f.close()
|
||||||
|
except urllib.error.HTTPError:
|
||||||
|
Logger.logException("e", "An HTTP error occurred while trying to send slice information")
|
||||||
|
except Exception: # We don't want any exception to cause problems
|
||||||
|
Logger.logException("e", "An exception occurred while trying to send slice information")
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Slice info",
|
"name": "Slice info",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Submits anonymous slice info. Can be disabled through preferences.",
|
"description": "Submits anonymous slice info. Can be disabled through preferences.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Solid View",
|
"name": "Solid View",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides a normal solid mesh view.",
|
"description": "Provides a normal solid mesh view.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -625,7 +625,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
|
||||||
# is ignored.
|
# is ignored.
|
||||||
# \param kwargs Keyword arguments.
|
# \param kwargs Keyword arguments.
|
||||||
def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None, **kwargs):
|
def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None, **kwargs):
|
||||||
if self._printer_state != "idle":
|
if self._printer_state not in ["idle", ""]:
|
||||||
self._error_message = Message(
|
self._error_message = Message(
|
||||||
i18n_catalog.i18nc("@info:status", "Unable to start a new print job, printer is busy. Current printer status is %s.") % self._printer_state)
|
i18n_catalog.i18nc("@info:status", "Unable to start a new print job, printer is busy. Current printer status is %s.") % self._printer_state)
|
||||||
self._error_message.show()
|
self._error_message.show()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "UM3 Network Connection",
|
"name": "UM3 Network Connection",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"description": "Manages network connections to Ultimaker 3 printers",
|
"description": "Manages network connections to Ultimaker 3 printers",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "USB printing",
|
"name": "USB printing",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
|
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Ultimaker machine actions",
|
"name": "Ultimaker machine actions",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc)",
|
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc)",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Version Upgrade 2.1 to 2.2",
|
"name": "Version Upgrade 2.1 to 2.2",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
|
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Version Upgrade 2.2 to 2.4",
|
"name": "Version Upgrade 2.2 to 2.4",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
|
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -5,7 +5,6 @@ import configparser #To parse the files we need to upgrade and write the new fil
|
||||||
import io #To serialise configparser output to a string.
|
import io #To serialise configparser output to a string.
|
||||||
|
|
||||||
from UM.VersionUpgrade import VersionUpgrade
|
from UM.VersionUpgrade import VersionUpgrade
|
||||||
from cura.CuraApplication import CuraApplication
|
|
||||||
|
|
||||||
_removed_settings = { #Settings that were removed in 2.5.
|
_removed_settings = { #Settings that were removed in 2.5.
|
||||||
"start_layers_at_same_position",
|
"start_layers_at_same_position",
|
||||||
|
@ -62,8 +61,13 @@ class VersionUpgrade25to26(VersionUpgrade):
|
||||||
parser["general"]["visible_settings"] = ";".join(new_visible_settings)
|
parser["general"]["visible_settings"] = ";".join(new_visible_settings)
|
||||||
|
|
||||||
#Change the version number in the file.
|
#Change the version number in the file.
|
||||||
if parser.has_section("general"): #It better have!
|
if "general" not in parser:
|
||||||
parser["general"]["version"] = "5"
|
parser["general"] = {}
|
||||||
|
parser.set("general", "version", "4")
|
||||||
|
|
||||||
|
if "metadata" not in parser:
|
||||||
|
parser["metadata"] = {}
|
||||||
|
parser.set("metadata", "setting_version", "1")
|
||||||
|
|
||||||
#Re-serialise the file.
|
#Re-serialise the file.
|
||||||
output = io.StringIO()
|
output = io.StringIO()
|
||||||
|
@ -91,11 +95,9 @@ class VersionUpgrade25to26(VersionUpgrade):
|
||||||
if not parser.has_section(each_section):
|
if not parser.has_section(each_section):
|
||||||
parser.add_section(each_section)
|
parser.add_section(each_section)
|
||||||
|
|
||||||
# Change the version number in the file.
|
# Update version numbers
|
||||||
parser["metadata"]["setting_version"] = str(CuraApplication.SettingVersion)
|
|
||||||
|
|
||||||
# Update version
|
|
||||||
parser["general"]["version"] = "2"
|
parser["general"]["version"] = "2"
|
||||||
|
parser["metadata"]["setting_version"] = "1"
|
||||||
|
|
||||||
#Re-serialise the file.
|
#Re-serialise the file.
|
||||||
output = io.StringIO()
|
output = io.StringIO()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Version Upgrade 2.5 to 2.6",
|
"name": "Version Upgrade 2.5 to 2.6",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
|
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
|
import configparser #To parse the files we need to upgrade and write the new files.
|
||||||
|
import io #To serialise configparser output to a string.
|
||||||
|
|
||||||
|
from UM.VersionUpgrade import VersionUpgrade
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
|
# a dict of renamed quality profiles: <old_id> : <new_id>
|
||||||
|
_renamed_quality_profiles = {
|
||||||
|
"um3_aa0.4_PVA_Not_Supported_Quality": "um3_aa0.4_PVA_Fast_Print",
|
||||||
|
|
||||||
|
"um3_aa0.8_CPEP_Not_Supported_Quality": "um3_aa0.8_CPEP_Fast_Print",
|
||||||
|
"um3_aa0.8_CPEP_Not_Supported_Superdraft_Quality": "um3_aa0.8_CPEP_Superdraft_Print",
|
||||||
|
"um3_aa0.8_CPEP_Not_Supported_Verydraft_Quality": "um3_aa0.8_CPEP_Verydraft_Print",
|
||||||
|
|
||||||
|
"um3_aa0.8_PC_Not_Supported_Quality": "um3_aa0.8_PC_Fast_Print",
|
||||||
|
"um3_aa0.8_PC_Not_Supported_Superdraft_Quality": "um3_aa0.8_PC_Superdraft_Print",
|
||||||
|
"um3_aa0.8_PC_Not_Supported_Verydraft_Quality": "um3_aa0.8_PC_Verydraft_Print",
|
||||||
|
|
||||||
|
"um3_aa0.8_PVA_Not_Supported_Quality": "um3_aa0.8_PVA_Fast_Print",
|
||||||
|
"um3_aa0.8_PVA_Not_Supported_Superdraft_Quality": "um3_aa0.8_PVA_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.4_ABS_Not_Supported_Quality": "um3_bb0.4_ABS_Fast_print",
|
||||||
|
"um3_bb0.4_ABS_Not_Supported_Superdraft_Quality": "um3_bb0.4_ABS_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.4_CPE_Not_Supported_Quality": "um3_bb0.4_CPE_Fast_Print",
|
||||||
|
"um3_bb0.4_CPE_Not_Supported_Superdraft_Quality": "um3_bb0.4_CPE_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.4_CPEP_Not_Supported_Quality": "um3_bb0.4_CPEP_Fast_Print",
|
||||||
|
"um3_bb0.4_CPEP_Not_Supported_Superdraft_Quality": "um3_bb0.4_CPEP_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.4_Nylon_Not_Supported_Quality": "um3_bb0.4_Nylon_Fast_Print",
|
||||||
|
"um3_bb0.4_Nylon_Not_Supported_Superdraft_Quality": "um3_bb0.4_Nylon_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.4_PC_Not_Supported_Quality": "um3_bb0.4_PC_Fast_Print",
|
||||||
|
|
||||||
|
"um3_bb0.4_PLA_Not_Supported_Quality": "um3_bb0.4_PLA_Fast_Print",
|
||||||
|
"um3_bb0.4_PLA_Not_Supported_Superdraft_Quality": "um3_bb0.4_PLA_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.4_TPU_Not_Supported_Quality": "um3_bb0.4_TPU_Fast_Print",
|
||||||
|
"um3_bb0.4_TPU_Not_Supported_Superdraft_Quality": "um3_bb0.4_TPU_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.8_ABS_Not_Supported_Quality": "um3_bb0.8_ABS_Fast_Print",
|
||||||
|
"um3_bb0.8_ABS_Not_Supported_Superdraft_Quality": "um3_bb0.8_ABS_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.8_CPE_Not_Supported_Quality": "um3_bb0.8_CPE_Fast_Print",
|
||||||
|
"um3_bb0.8_CPE_Not_Supported_Superdraft_Quality": "um3_bb0.8_CPE_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.8_CPEP_Not_Supported_Quality": "um3_bb0.um3_bb0.8_CPEP_Fast_Print",
|
||||||
|
"um3_bb0.8_CPEP_Not_Supported_Superdraft_Quality": "um3_bb0.8_CPEP_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.8_Nylon_Not_Supported_Quality": "um3_bb0.8_Nylon_Fast_Print",
|
||||||
|
"um3_bb0.8_Nylon_Not_Supported_Superdraft_Quality": "um3_bb0.8_Nylon_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.8_PC_Not_Supported_Quality": "um3_bb0.8_PC_Fast_Print",
|
||||||
|
"um3_bb0.8_PC_Not_Supported_Superdraft_Quality": "um3_bb0.8_PC_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.8_PLA_Not_Supported_Quality": "um3_bb0.8_PLA_Fast_Print",
|
||||||
|
"um3_bb0.8_PLA_Not_Supported_Superdraft_Quality": "um3_bb0.8_PLA_Superdraft_Print",
|
||||||
|
|
||||||
|
"um3_bb0.8_TPU_Not_Supported_Quality": "um3_bb0.8_TPU_Fast_print",
|
||||||
|
"um3_bb0.8_TPU_Not_Supported_Superdraft_Quality": "um3_bb0.8_TPU_Superdraft_Print",
|
||||||
|
}
|
||||||
|
|
||||||
|
## A collection of functions that convert the configuration of the user in Cura
|
||||||
|
# 2.6 to a configuration for Cura 2.7.
|
||||||
|
#
|
||||||
|
# All of these methods are essentially stateless.
|
||||||
|
class VersionUpgrade26to27(VersionUpgrade):
|
||||||
|
## Gets the version number from a CFG file in Uranium's 2.6 format.
|
||||||
|
#
|
||||||
|
# Since the format may change, this is implemented for the 2.6 format only
|
||||||
|
# and needs to be included in the version upgrade system rather than
|
||||||
|
# globally in Uranium.
|
||||||
|
#
|
||||||
|
# \param serialised The serialised form of a CFG file.
|
||||||
|
# \return The version number stored in the CFG file.
|
||||||
|
# \raises ValueError The format of the version number in the file is
|
||||||
|
# incorrect.
|
||||||
|
# \raises KeyError The format of the file is incorrect.
|
||||||
|
def getCfgVersion(self, serialised):
|
||||||
|
parser = configparser.ConfigParser(interpolation = None)
|
||||||
|
parser.read_string(serialised)
|
||||||
|
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
|
||||||
|
setting_version = int(parser.get("metadata", "setting_version", fallback = 0))
|
||||||
|
return format_version * 1000000 + setting_version
|
||||||
|
|
||||||
|
## Upgrades a preferences file from version 2.6 to 2.7.
|
||||||
|
#
|
||||||
|
# \param serialised The serialised form of a preferences file.
|
||||||
|
# \param filename The name of the file to upgrade.
|
||||||
|
def upgradePreferences(self, serialised, filename):
|
||||||
|
parser = configparser.ConfigParser(interpolation=None)
|
||||||
|
parser.read_string(serialised)
|
||||||
|
|
||||||
|
# Update version numbers
|
||||||
|
if "general" not in parser:
|
||||||
|
parser["general"] = {}
|
||||||
|
parser["general"]["version"] = "4"
|
||||||
|
|
||||||
|
if "metadata" not in parser:
|
||||||
|
parser["metadata"] = {}
|
||||||
|
parser["metadata"]["setting_version"] = "2"
|
||||||
|
|
||||||
|
# Re-serialise the file.
|
||||||
|
output = io.StringIO()
|
||||||
|
parser.write(output)
|
||||||
|
return [filename], [output.getvalue()]
|
||||||
|
|
||||||
|
## Upgrades a container file other than a container stack file from version 2.6 to 2.7.
|
||||||
|
#
|
||||||
|
# \param serialised The serialised form of a container file.
|
||||||
|
# \param filename The name of the file to upgrade.
|
||||||
|
def upgradeOtherContainer(self, serialised, filename):
|
||||||
|
parser = configparser.ConfigParser(interpolation=None)
|
||||||
|
parser.read_string(serialised)
|
||||||
|
|
||||||
|
# Update version numbers
|
||||||
|
if "general" not in parser:
|
||||||
|
parser["general"] = {}
|
||||||
|
parser["general"]["version"] = "2"
|
||||||
|
|
||||||
|
if "metadata" not in parser:
|
||||||
|
parser["metadata"] = {}
|
||||||
|
parser["metadata"]["setting_version"] = "2"
|
||||||
|
|
||||||
|
# Re-serialise the file.
|
||||||
|
output = io.StringIO()
|
||||||
|
parser.write(output)
|
||||||
|
return [filename], [output.getvalue()]
|
||||||
|
|
||||||
|
## Upgrades a container stack from version 2.6 to 2.7.
|
||||||
|
#
|
||||||
|
# \param serialised The serialised form of a container stack.
|
||||||
|
# \param filename The name of the file to upgrade.
|
||||||
|
def upgradeStack(self, serialised, filename):
|
||||||
|
parser = configparser.ConfigParser(interpolation = None)
|
||||||
|
parser.read_string(serialised)
|
||||||
|
|
||||||
|
# Update IDs of the renamed quality profiles
|
||||||
|
if parser.has_section("containers"):
|
||||||
|
key_list = [key for key in parser["containers"].keys()]
|
||||||
|
for key in key_list:
|
||||||
|
container_id = parser.get("containers", key)
|
||||||
|
new_id = _renamed_quality_profiles.get(container_id)
|
||||||
|
if new_id is not None:
|
||||||
|
parser.set("containers", key, new_id)
|
||||||
|
|
||||||
|
for each_section in ("general", "metadata"):
|
||||||
|
if not parser.has_section(each_section):
|
||||||
|
parser.add_section(each_section)
|
||||||
|
|
||||||
|
# Update version numbers
|
||||||
|
if "general" not in parser:
|
||||||
|
parser["general"] = {}
|
||||||
|
parser["general"]["version"] = "3"
|
||||||
|
|
||||||
|
if "metadata" not in parser:
|
||||||
|
parser["metadata"] = {}
|
||||||
|
parser["metadata"]["setting_version"] = "2"
|
||||||
|
|
||||||
|
# Re-serialise the file.
|
||||||
|
output = io.StringIO()
|
||||||
|
parser.write(output)
|
||||||
|
return [filename], [output.getvalue()]
|
62
plugins/VersionUpgrade/VersionUpgrade26to27/__init__.py
Normal file
62
plugins/VersionUpgrade/VersionUpgrade26to27/__init__.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
|
from . import VersionUpgrade26to27
|
||||||
|
|
||||||
|
from UM.i18n import i18nCatalog
|
||||||
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
upgrade = VersionUpgrade26to27.VersionUpgrade26to27()
|
||||||
|
|
||||||
|
def getMetaData():
|
||||||
|
return {
|
||||||
|
"version_upgrade": {
|
||||||
|
# From To Upgrade function
|
||||||
|
("machine_stack", 3000000): ("machine_stack", 3000002, upgrade.upgradeStack),
|
||||||
|
("extruder_train", 3000000): ("extruder_train", 3000002, upgrade.upgradeStack),
|
||||||
|
|
||||||
|
# In 2.6.x, Preferences are saved with "version = 4" and no setting_version.
|
||||||
|
# This means those Preferences files will still be treated as "4.0" as defined in VersionUpgrade25to26,
|
||||||
|
# so the 25to26 upgrade routine will be called again.
|
||||||
|
#
|
||||||
|
# To fix this, we first fix the upgrade routine for 25to26 so it actually upgrades to "4.1", and then
|
||||||
|
# here we can upgrade from "4.1" to "4.2" safely.
|
||||||
|
#
|
||||||
|
("preferences", 4000001): ("preferences", 4000002, upgrade.upgradePreferences),
|
||||||
|
# NOTE: All the instance containers share the same general/version, so we have to update all of them
|
||||||
|
# if any is updated.
|
||||||
|
("quality_changes", 2000001): ("quality_changes", 2000002, upgrade.upgradeOtherContainer),
|
||||||
|
("user", 2000001): ("user", 2000002, upgrade.upgradeOtherContainer),
|
||||||
|
("quality", 2000001): ("quality", 2000002, upgrade.upgradeOtherContainer),
|
||||||
|
("definition_changes", 2000001): ("definition_changes", 2000002, upgrade.upgradeOtherContainer),
|
||||||
|
},
|
||||||
|
"sources": {
|
||||||
|
"machine_stack": {
|
||||||
|
"get_version": upgrade.getCfgVersion,
|
||||||
|
"location": {"./machine_instances"}
|
||||||
|
},
|
||||||
|
"extruder_train": {
|
||||||
|
"get_version": upgrade.getCfgVersion,
|
||||||
|
"location": {"./extruders"}
|
||||||
|
},
|
||||||
|
"preferences": {
|
||||||
|
"get_version": upgrade.getCfgVersion,
|
||||||
|
"location": {"."}
|
||||||
|
},
|
||||||
|
"quality_changes": {
|
||||||
|
"get_version": upgrade.getCfgVersion,
|
||||||
|
"location": {"./quality"}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"get_version": upgrade.getCfgVersion,
|
||||||
|
"location": {"./user"}
|
||||||
|
},
|
||||||
|
"definition_changes": {
|
||||||
|
"get_version": upgrade.getCfgVersion,
|
||||||
|
"location": {"./machine_instances"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def register(app):
|
||||||
|
return { "version_upgrade": upgrade }
|
8
plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
Normal file
8
plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "Version Upgrade 2.6 to 2.7",
|
||||||
|
"author": "Ultimaker B.V.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Upgrades configurations from Cura 2.6 to Cura 2.7.",
|
||||||
|
"api": 4,
|
||||||
|
"i18n-catalog": "cura"
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
|
import configparser #To check whether the appropriate exceptions are raised.
|
||||||
|
import pytest #To register tests with.
|
||||||
|
|
||||||
|
import VersionUpgrade26to27 #The module we're testing.
|
||||||
|
|
||||||
|
## Creates an instance of the upgrader to test with.
|
||||||
|
@pytest.fixture
|
||||||
|
def upgrader():
|
||||||
|
return VersionUpgrade26to27.VersionUpgrade26to27()
|
||||||
|
|
||||||
|
test_cfg_version_good_data = [
|
||||||
|
{
|
||||||
|
"test_name": "Simple",
|
||||||
|
"file_data": """[general]
|
||||||
|
version = 1
|
||||||
|
""",
|
||||||
|
"version": 1000000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_name": "Other Data Around",
|
||||||
|
"file_data": """[nonsense]
|
||||||
|
life = good
|
||||||
|
|
||||||
|
[general]
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[values]
|
||||||
|
layer_height = 0.12
|
||||||
|
infill_sparse_density = 42
|
||||||
|
""",
|
||||||
|
"version": 3000000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_name": "Negative Version", #Why not?
|
||||||
|
"file_data": """[general]
|
||||||
|
version = -20
|
||||||
|
""",
|
||||||
|
"version": -20000000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_name": "Setting Version",
|
||||||
|
"file_data": """[general]
|
||||||
|
version = 1
|
||||||
|
[metadata]
|
||||||
|
setting_version = 1
|
||||||
|
""",
|
||||||
|
"version": 1000001
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_name": "Negative Setting Version",
|
||||||
|
"file_data": """[general]
|
||||||
|
version = 1
|
||||||
|
[metadata]
|
||||||
|
setting_version = -3
|
||||||
|
""",
|
||||||
|
"version": 999997
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
## Tests the technique that gets the version number from CFG files.
|
||||||
|
#
|
||||||
|
# \param data The parametrised data to test with. It contains a test name
|
||||||
|
# to debug with, the serialised contents of a CFG file and the correct
|
||||||
|
# version number in that CFG file.
|
||||||
|
# \param upgrader The instance of the upgrade class to test.
|
||||||
|
@pytest.mark.parametrize("data", test_cfg_version_good_data)
|
||||||
|
def test_cfgVersionGood(data, upgrader):
|
||||||
|
version = upgrader.getCfgVersion(data["file_data"])
|
||||||
|
assert version == data["version"]
|
||||||
|
|
||||||
|
test_cfg_version_bad_data = [
|
||||||
|
{
|
||||||
|
"test_name": "Empty",
|
||||||
|
"file_data": "",
|
||||||
|
"exception": configparser.Error #Explicitly not specified further which specific error we're getting, because that depends on the implementation of configparser.
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_name": "No General",
|
||||||
|
"file_data": """[values]
|
||||||
|
layer_height = 0.1337
|
||||||
|
""",
|
||||||
|
"exception": configparser.Error
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_name": "No Version",
|
||||||
|
"file_data": """[general]
|
||||||
|
true = false
|
||||||
|
""",
|
||||||
|
"exception": configparser.Error
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_name": "Not a Number",
|
||||||
|
"file_data": """[general]
|
||||||
|
version = not-a-text-version-number
|
||||||
|
""",
|
||||||
|
"exception": ValueError
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_name": "Setting Value NaN",
|
||||||
|
"file_data": """[general]
|
||||||
|
version = 4
|
||||||
|
[metadata]
|
||||||
|
setting_version = latest_or_something
|
||||||
|
""",
|
||||||
|
"exception": ValueError
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_name": "Major-Minor",
|
||||||
|
"file_data": """[general]
|
||||||
|
version = 1.2
|
||||||
|
""",
|
||||||
|
"exception": ValueError
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
## Tests whether getting a version number from bad CFG files gives an
|
||||||
|
# exception.
|
||||||
|
#
|
||||||
|
# \param data The parametrised data to test with. It contains a test name
|
||||||
|
# to debug with, the serialised contents of a CFG file and the class of
|
||||||
|
# exception it needs to throw.
|
||||||
|
# \param upgrader The instance of the upgrader to test.
|
||||||
|
@pytest.mark.parametrize("data", test_cfg_version_bad_data)
|
||||||
|
def test_cfgVersionBad(data, upgrader):
|
||||||
|
with pytest.raises(data["exception"]):
|
||||||
|
upgrader.getCfgVersion(data["file_data"])
|
||||||
|
|
||||||
|
test_upgrade_stacks_with_not_supported_data = [
|
||||||
|
{
|
||||||
|
"test_name": "Global stack with Not Supported quality profile",
|
||||||
|
"file_data": """[general]
|
||||||
|
version = 3
|
||||||
|
name = Ultimaker 3
|
||||||
|
id = Ultimaker 3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = machine
|
||||||
|
|
||||||
|
[containers]
|
||||||
|
0 = Ultimaker 3_user
|
||||||
|
1 = empty
|
||||||
|
2 = um3_global_Normal_Quality
|
||||||
|
3 = empty
|
||||||
|
4 = empty
|
||||||
|
5 = empty
|
||||||
|
6 = ultimaker3
|
||||||
|
"""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_name": "Extruder stack left with Not Supported quality profile",
|
||||||
|
"file_data": """[general]
|
||||||
|
version = 3
|
||||||
|
name = Extruder 1
|
||||||
|
id = ultimaker3_extruder_left #2
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
position = 0
|
||||||
|
machine = Ultimaker 3
|
||||||
|
type = extruder_train
|
||||||
|
|
||||||
|
[containers]
|
||||||
|
0 = ultimaker3_extruder_left #2_user
|
||||||
|
1 = empty
|
||||||
|
2 = um3_aa0.4_PVA_Not_Supported_Quality
|
||||||
|
3 = generic_pva_ultimaker3_AA_0.4
|
||||||
|
4 = ultimaker3_aa04
|
||||||
|
5 = ultimaker3_extruder_left #2_settings
|
||||||
|
6 = ultimaker3_extruder_left
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
## Tests whether the "Not Supported" quality profiles in the global and extruder stacks are renamed for the 2.7
|
||||||
|
# version of preferences.
|
||||||
|
@pytest.mark.parametrize("data", test_upgrade_stacks_with_not_supported_data)
|
||||||
|
def test_upgradeStacksWithNotSupportedQuality(data, upgrader):
|
||||||
|
# Read old file
|
||||||
|
original_parser = configparser.ConfigParser(interpolation = None)
|
||||||
|
original_parser.read_string(data["file_data"])
|
||||||
|
|
||||||
|
# Perform the upgrade.
|
||||||
|
_, upgraded_stacks = upgrader.upgradeStack(data["file_data"], "<string>")
|
||||||
|
upgraded_stack = upgraded_stacks[0]
|
||||||
|
|
||||||
|
# Find whether the not supported profile has been renamed
|
||||||
|
parser = configparser.ConfigParser(interpolation = None)
|
||||||
|
parser.read_string(upgraded_stack)
|
||||||
|
assert("Not_Supported" not in parser.get("containers", "2"))
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "X-Ray View",
|
"name": "X-Ray View",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides the X-Ray view.",
|
"description": "Provides the X-Ray view.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -12,9 +12,8 @@ from UM.Util import parseBool
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
import UM.Dictionary
|
import UM.Dictionary
|
||||||
from UM.Settings.InstanceContainer import InstanceContainer, InvalidInstanceError
|
from UM.Settings.InstanceContainer import InstanceContainer
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
|
|
||||||
|
|
||||||
|
|
||||||
## Handles serializing and deserializing material containers from an XML file
|
## Handles serializing and deserializing material containers from an XML file
|
||||||
|
@ -37,7 +36,7 @@ class XmlMaterialProfile(InstanceContainer):
|
||||||
# \return The corresponding setting_version.
|
# \return The corresponding setting_version.
|
||||||
def xmlVersionToSettingVersion(self, xml_version: str) -> int:
|
def xmlVersionToSettingVersion(self, xml_version: str) -> int:
|
||||||
if xml_version == "1.3":
|
if xml_version == "1.3":
|
||||||
return 1
|
return 2
|
||||||
return 0 #Older than 1.3.
|
return 0 #Older than 1.3.
|
||||||
|
|
||||||
def getInheritedFiles(self):
|
def getInheritedFiles(self):
|
||||||
|
|
|
@ -21,7 +21,7 @@ class XmlMaterialUpgrader(VersionUpgrade):
|
||||||
|
|
||||||
def _xmlVersionToSettingVersion(self, xml_version: str) -> int:
|
def _xmlVersionToSettingVersion(self, xml_version: str) -> int:
|
||||||
if xml_version == "1.3":
|
if xml_version == "1.3":
|
||||||
return 1
|
return 2
|
||||||
return 0 #Older than 1.3.
|
return 0 #Older than 1.3.
|
||||||
|
|
||||||
def upgradeMaterial(self, serialised, filename):
|
def upgradeMaterial(self, serialised, filename):
|
||||||
|
|
|
@ -19,7 +19,7 @@ def getMetaData():
|
||||||
"mimetype": "application/x-ultimaker-material-profile"
|
"mimetype": "application/x-ultimaker-material-profile"
|
||||||
},
|
},
|
||||||
"version_upgrade": {
|
"version_upgrade": {
|
||||||
("materials", 1000000): ("materials", 1000001, upgrader.upgradeMaterial),
|
("materials", 1000000): ("materials", 1000002, upgrader.upgradeMaterial),
|
||||||
},
|
},
|
||||||
"sources": {
|
"sources": {
|
||||||
"materials": {
|
"materials": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Material Profiles",
|
"name": "Material Profiles",
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Provides capabilities to read and write XML-based material profiles.",
|
"description": "Provides capabilities to read and write XML-based material profiles.",
|
||||||
"api": 4,
|
"api": 4,
|
||||||
|
|
|
@ -50,11 +50,15 @@
|
||||||
"prime_tower_wall_thickness": { "resolve": 0.7 },
|
"prime_tower_wall_thickness": { "resolve": 0.7 },
|
||||||
"prime_tower_position_x": { "default_value": 50 },
|
"prime_tower_position_x": { "default_value": 50 },
|
||||||
"prime_tower_position_y": { "default_value": 150 },
|
"prime_tower_position_y": { "default_value": 150 },
|
||||||
|
"machine_max_feedrate_z": { "default_value": 20 },
|
||||||
|
"machine_disallowed_areas": { "default_value": [
|
||||||
|
[[215, 135], [-215, 135], [-215, 75], [215, 75]]
|
||||||
|
]},
|
||||||
"machine_start_gcode": {
|
"machine_start_gcode": {
|
||||||
"default_value": "\nM92 E159 ;2288 for V5 extruder\n\nM104 S120 T1\nM104 S120 T2\nM104 S120 T3\n\nG21\nG90\nM42 S255 P13 ;chamber lights\nM42 S255 P12 ;fume extraction\nM204 S300 ;default acceleration\nM205 X10 ;default jerk\n\nM117 Homing Y ......\nG28 Y\nM117 Homing X ......\nG28 X\nM117 Homing Z ......\nG28 Z F100\nG1 Z10 F600\nG1 X70 Y20 F9000;go to wipe point\n\nM190 S{material_bed_temperature_layer_0}\n\nM117 Heating for 50 sec.\nG4 S20\nM117 Heating for 30 sec.\nG4 S20\nM117 Heating for 10 sec.\nM300 S1200 P1000\nG4 S9\n\nM117 purging nozzle....\nT0\nG92 E0;set E\nG1 E10 F100\nG92 E0\nG1 E-1 F600\n\nM117 wiping nozzle....\nG1 X1 Y24 F3000\nG1 X70 F9000\nG1 Z10 F900\n\nM104 S21 T1\nM104 S21 T2\nM104 S21 T3\n\nM117 Printing .....\n"
|
"default_value": "\nM92 E159 ;2288 for V5 extruder\n\nM104 S120 T1\nM104 S120 T2\nM104 S120 T3\n\nG21\nG90\nM42 S255 P13 ;chamber lights\nM42 S255 P12 ;fume extraction\nM204 S300 ;default acceleration\nM205 X10 ;default jerk\n\nM117 Homing Y ......\nG28 Y\nM117 Homing X ......\nG28 X\nM117 Homing Z ......\nG28 Z F100\nG1 Z10 F600\nG1 X70 Y20 F9000;go to wipe point\n\nM190 S{material_bed_temperature_layer_0}\n\nM117 Heating for 50 sec.\nG4 S20\nM117 Heating for 30 sec.\nG4 S20\nM117 Heating for 10 sec.\nM300 S1200 P1000\nG4 S9\n\nM117 purging nozzle....\nT0\nG92 E0;set E\nG1 E10 F100\nG92 E0\nG1 E-1 F600\n\nM117 wiping nozzle....\nG1 X1 Y24 F3000\nG1 X70 F9000\nG1 Z10 F900\n\nM104 S21 T1\nM104 S21 T2\nM104 S21 T3\n\nM117 Printing .....\n"
|
||||||
},
|
},
|
||||||
"machine_end_gcode": {
|
"machine_end_gcode": {
|
||||||
"default_value": "; -- END GCODE --\nM106 S255\nM140 S5\nM104 S5 T0\nM104 S5 T1\nM104 S5 T2\nM104 S5 T3\n\nG91\nG1 Z1 F900\nG90\n\nG1 X20.0 Y260.0 F6000\nG4 S7\nM84\nG4 S90\nM107\nM42 P12 S0\nM42 P13 S0\nM84\nT0\n; -- end of GCODE --"
|
"default_value": "; -- END GCODE --\nM117 cooling down....\nM106 S255\nM140 S5\nM104 S5 T0\nM104 S5 T1\nM104 S5 T2\nM104 S5 T3\n\nG91\nG1 Z1 F900\nG90\n\nG1 X20.0 Y260.0 F6000\nG4 S7\nM84\nG4 S90\nM107\nM42 P12 S0\nM42 P13 S0\nM84\nT0\nM117 Finished.\n; -- end of GCODE --"
|
||||||
},
|
},
|
||||||
"layer_height": { "maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
|
"layer_height": { "maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
|
||||||
"layer_height_0": { "maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
|
"layer_height_0": { "maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
|
||||||
|
|
|
@ -303,8 +303,9 @@
|
||||||
"type": "enum",
|
"type": "enum",
|
||||||
"options":
|
"options":
|
||||||
{
|
{
|
||||||
"RepRap (Marlin/Sprinter)": "RepRap (Marlin/Sprinter)",
|
"RepRap (Marlin/Sprinter)": "Marlin",
|
||||||
"RepRap (Volumatric)": "RepRap (Volumetric)",
|
"RepRap (Volumatric)": "Marlin (Volumetric)",
|
||||||
|
"RepRap (RepRap)": "RepRap",
|
||||||
"UltiGCode": "Ultimaker 2",
|
"UltiGCode": "Ultimaker 2",
|
||||||
"Griffin": "Griffin",
|
"Griffin": "Griffin",
|
||||||
"Makerbot": "Makerbot",
|
"Makerbot": "Makerbot",
|
||||||
|
@ -677,7 +678,7 @@
|
||||||
"minimum_value_warning": "(0.1 + 0.4 * machine_nozzle_size) if outer_inset_first else 0.1 * machine_nozzle_size",
|
"minimum_value_warning": "(0.1 + 0.4 * machine_nozzle_size) if outer_inset_first else 0.1 * machine_nozzle_size",
|
||||||
"maximum_value_warning": "2 * machine_nozzle_size",
|
"maximum_value_warning": "2 * machine_nozzle_size",
|
||||||
"default_value": 0.4,
|
"default_value": 0.4,
|
||||||
"value": "wall_line_width",
|
"value": "extruderValue(wall_0_extruder_nr, 'wall_line_width')",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"limit_to_extruder": "wall_0_extruder_nr",
|
"limit_to_extruder": "wall_0_extruder_nr",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
|
@ -1136,6 +1137,19 @@
|
||||||
"limit_to_extruder": "wall_0_extruder_nr",
|
"limit_to_extruder": "wall_0_extruder_nr",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
|
"xy_offset_layer_0":
|
||||||
|
{
|
||||||
|
"label": "Initial Layer Horizontal Expansion",
|
||||||
|
"description": "Amount of offset applied to all polygons in the first layer. A negative value can compensate for squishing of the first layer known as \"elephant's foot\".",
|
||||||
|
"unit": "mm",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value_warning": "-1",
|
||||||
|
"maximum_value_warning": "1",
|
||||||
|
"default_value": 0,
|
||||||
|
"value": "xy_offset",
|
||||||
|
"limit_to_extruder": "wall_0_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
"z_seam_type":
|
"z_seam_type":
|
||||||
{
|
{
|
||||||
"label": "Z Seam Alignment",
|
"label": "Z Seam Alignment",
|
||||||
|
@ -1175,6 +1189,17 @@
|
||||||
"limit_to_extruder": "wall_0_extruder_nr",
|
"limit_to_extruder": "wall_0_extruder_nr",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
|
"z_seam_relative":
|
||||||
|
{
|
||||||
|
"label": "Z Seam Relative",
|
||||||
|
"description": "When enabled, the z seam coordinates are relative to each part's centre. When disabled, the coordinates define an absolute position on the build plate.",
|
||||||
|
"unit": "mm",
|
||||||
|
"type": "bool",
|
||||||
|
"default_value": false,
|
||||||
|
"enabled": "z_seam_type == 'back'",
|
||||||
|
"limit_to_extruder": "wall_0_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
"skin_no_small_gaps_heuristic":
|
"skin_no_small_gaps_heuristic":
|
||||||
{
|
{
|
||||||
"label": "Ignore Small Z Gaps",
|
"label": "Ignore Small Z Gaps",
|
||||||
|
@ -1524,6 +1549,7 @@
|
||||||
"maximum_value_warning": "285",
|
"maximum_value_warning": "285",
|
||||||
"enabled": "machine_nozzle_temp_enabled",
|
"enabled": "machine_nozzle_temp_enabled",
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
|
"settable_per_mesh": false,
|
||||||
"minimum_value": "-273.15"
|
"minimum_value": "-273.15"
|
||||||
},
|
},
|
||||||
"material_print_temperature":
|
"material_print_temperature":
|
||||||
|
@ -4357,7 +4383,7 @@
|
||||||
"unit": "mm",
|
"unit": "mm",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 2,
|
"default_value": 2,
|
||||||
"value": "round(max(2 * max(extruderValues('prime_tower_line_width')), 0.5 * (resolveOrValue('prime_tower_size') - math.sqrt(max(0, resolveOrValue('prime_tower_size') ** 2 - max(extruderValues('prime_tower_min_volume')) / resolveOrValue('layer_height'))))), 3)",
|
"value": "round(max(2 * prime_tower_line_width, 0.5 * (prime_tower_size - math.sqrt(max(0, prime_tower_size ** 2 - prime_tower_min_volume / layer_height)))), 3)",
|
||||||
"resolve": "max(extruderValues('prime_tower_wall_thickness'))",
|
"resolve": "max(extruderValues('prime_tower_wall_thickness'))",
|
||||||
"minimum_value": "0.001",
|
"minimum_value": "0.001",
|
||||||
"minimum_value_warning": "2 * min(extruderValues('prime_tower_line_width')) - 0.0001",
|
"minimum_value_warning": "2 * min(extruderValues('prime_tower_line_width')) - 0.0001",
|
||||||
|
@ -4376,8 +4402,6 @@
|
||||||
"unit": "mm",
|
"unit": "mm",
|
||||||
"enabled": "resolveOrValue('prime_tower_enable')",
|
"enabled": "resolveOrValue('prime_tower_enable')",
|
||||||
"default_value": 200,
|
"default_value": 200,
|
||||||
"minimum_value_warning": "-1000",
|
|
||||||
"maximum_value_warning": "1000",
|
|
||||||
"maximum_value": "machine_width / 2 if machine_center_is_zero else machine_width",
|
"maximum_value": "machine_width / 2 if machine_center_is_zero else machine_width",
|
||||||
"minimum_value": "resolveOrValue('prime_tower_size') - machine_width / 2 if machine_center_is_zero else resolveOrValue('prime_tower_size')",
|
"minimum_value": "resolveOrValue('prime_tower_size') - machine_width / 2 if machine_center_is_zero else resolveOrValue('prime_tower_size')",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
|
@ -4391,8 +4415,6 @@
|
||||||
"unit": "mm",
|
"unit": "mm",
|
||||||
"enabled": "resolveOrValue('prime_tower_enable')",
|
"enabled": "resolveOrValue('prime_tower_enable')",
|
||||||
"default_value": 200,
|
"default_value": 200,
|
||||||
"minimum_value_warning": "-1000",
|
|
||||||
"maximum_value_warning": "1000",
|
|
||||||
"maximum_value": "machine_depth / 2 - resolveOrValue('prime_tower_size') if machine_center_is_zero else machine_depth - resolveOrValue('prime_tower_size')",
|
"maximum_value": "machine_depth / 2 - resolveOrValue('prime_tower_size') if machine_center_is_zero else machine_depth - resolveOrValue('prime_tower_size')",
|
||||||
"minimum_value": "machine_depth / -2 if machine_center_is_zero else 0",
|
"minimum_value": "machine_depth / -2 if machine_center_is_zero else 0",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
|
@ -4897,6 +4919,16 @@
|
||||||
"limit_to_extruder": "infill_extruder_nr",
|
"limit_to_extruder": "infill_extruder_nr",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
|
"spaghetti_infill_stepped":
|
||||||
|
{
|
||||||
|
"label": "Spaghetti Infill Stepping",
|
||||||
|
"description": "Whether to print spaghetti infill in steps or extrude all the infill filament at the end of the print.",
|
||||||
|
"type": "bool",
|
||||||
|
"default_value": true,
|
||||||
|
"enabled": "infill_sparse_density > 0 and spaghetti_infill_enabled",
|
||||||
|
"limit_to_extruder": "infill_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
"spaghetti_max_infill_angle":
|
"spaghetti_max_infill_angle":
|
||||||
{
|
{
|
||||||
"label": "Spaghetti Maximum Infill Angle",
|
"label": "Spaghetti Maximum Infill Angle",
|
||||||
|
@ -4907,7 +4939,7 @@
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value": "90",
|
"maximum_value": "90",
|
||||||
"maximum_value_warning": "45",
|
"maximum_value_warning": "45",
|
||||||
"enabled": "infill_sparse_density > 0 and spaghetti_infill_enabled",
|
"enabled": "infill_sparse_density > 0 and spaghetti_infill_enabled and spaghetti_infill_stepped",
|
||||||
"limit_to_extruder": "infill_extruder_nr",
|
"limit_to_extruder": "infill_extruder_nr",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
|
@ -4920,7 +4952,7 @@
|
||||||
"default_value": 2.0,
|
"default_value": 2.0,
|
||||||
"minimum_value": "layer_height",
|
"minimum_value": "layer_height",
|
||||||
"maximum_value_warning": "10.0",
|
"maximum_value_warning": "10.0",
|
||||||
"enabled": "infill_sparse_density > 0 and spaghetti_infill_enabled",
|
"enabled": "infill_sparse_density > 0 and spaghetti_infill_enabled and spaghetti_infill_stepped",
|
||||||
"limit_to_extruder": "infill_extruder_nr",
|
"limit_to_extruder": "infill_extruder_nr",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
|
@ -4950,6 +4982,19 @@
|
||||||
"limit_to_extruder": "infill_extruder_nr",
|
"limit_to_extruder": "infill_extruder_nr",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
|
"spaghetti_infill_extra_volume":
|
||||||
|
{
|
||||||
|
"label": "Spaghetti Infill Extra Volume",
|
||||||
|
"description": "A correction term to adjust the total volume being extruded each time when filling spaghetti.",
|
||||||
|
"unit": "mm³",
|
||||||
|
"type": "float",
|
||||||
|
"default_value": 0,
|
||||||
|
"minimum_value_warning": "0",
|
||||||
|
"maximum_value_warning": "100",
|
||||||
|
"enabled": "infill_sparse_density > 0 and spaghetti_infill_enabled",
|
||||||
|
"limit_to_extruder": "infill_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
"support_conical_enabled":
|
"support_conical_enabled":
|
||||||
{
|
{
|
||||||
"label": "Enable Conical Support",
|
"label": "Enable Conical Support",
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"maximum_value": "3"
|
"maximum_value": "3"
|
||||||
},
|
},
|
||||||
"machine_nozzle_offset_x": { "default_value": 0.0 },
|
"machine_nozzle_offset_x": { "default_value": 0.0 },
|
||||||
"machine_nozzle_offset_y": { "default_value": 60.0 },
|
"machine_nozzle_offset_y": { "default_value": 0.0 },
|
||||||
"machine_extruder_start_code": {
|
"machine_extruder_start_code": {
|
||||||
"default_value": "\n;start extruder_2\n\nM117 printing\n"
|
"default_value": "\n;start extruder_2\n\nM117 printing\n"
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
"default_value": 3,
|
"default_value": 3,
|
||||||
"maximum_value": "3"
|
"maximum_value": "3"
|
||||||
},
|
},
|
||||||
"machine_nozzle_offset_x": { "default_value": 24.0 },
|
"machine_nozzle_offset_x": { "default_value": 0.0 },
|
||||||
"machine_nozzle_offset_y": { "default_value": 60.0 },
|
"machine_nozzle_offset_y": { "default_value": 0.0 },
|
||||||
"machine_extruder_start_code": {
|
"machine_extruder_start_code": {
|
||||||
"default_value": "\n;start extruder_3\n\nM117 printing\n"
|
"default_value": "\n;start extruder_3\n\nM117 printing\n"
|
||||||
},
|
},
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
import QtQuick 2.2
|
import QtQuick 2.2
|
||||||
|
@ -18,7 +18,24 @@ UM.MainWindow
|
||||||
//: Cura application window title
|
//: Cura application window title
|
||||||
title: catalog.i18nc("@title:window","Cura");
|
title: catalog.i18nc("@title:window","Cura");
|
||||||
viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0)
|
viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0)
|
||||||
property bool monitoringPrint: false
|
property bool showPrintMonitor: false
|
||||||
|
|
||||||
|
Connections
|
||||||
|
{
|
||||||
|
target: Printer
|
||||||
|
onShowPrintMonitor:
|
||||||
|
{
|
||||||
|
if (show)
|
||||||
|
{
|
||||||
|
topbar.startMonitoringPrint()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
topbar.stopMonitoringPrint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted:
|
Component.onCompleted:
|
||||||
{
|
{
|
||||||
CuraApplication.setMinimumWindowSize(UM.Theme.getSize("window_minimum_size"))
|
CuraApplication.setMinimumWindowSize(UM.Theme.getSize("window_minimum_size"))
|
||||||
|
@ -329,7 +346,8 @@ UM.MainWindow
|
||||||
tooltip: '';
|
tooltip: '';
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
top: parent.top;
|
top: topbar.bottom;
|
||||||
|
topMargin: UM.Theme.getSize("default_margin").height;
|
||||||
left: parent.left;
|
left: parent.left;
|
||||||
}
|
}
|
||||||
action: Cura.Actions.open;
|
action: Cura.Actions.open;
|
||||||
|
@ -371,19 +389,30 @@ UM.MainWindow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Topbar
|
||||||
|
{
|
||||||
|
id: topbar
|
||||||
|
anchors.left:parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
monitoringPrint: base.showPrintMonitor
|
||||||
|
onStartMonitoringPrint: base.showPrintMonitor = true
|
||||||
|
onStopMonitoringPrint: base.showPrintMonitor = false
|
||||||
|
}
|
||||||
|
|
||||||
Sidebar
|
Sidebar
|
||||||
{
|
{
|
||||||
id: sidebar;
|
id: sidebar;
|
||||||
|
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
top: parent.top;
|
top: topbar.bottom;
|
||||||
bottom: parent.bottom;
|
bottom: parent.bottom;
|
||||||
right: parent.right;
|
right: parent.right;
|
||||||
}
|
}
|
||||||
z: 1
|
z: 1
|
||||||
onMonitoringPrintChanged: base.monitoringPrint = monitoringPrint
|
|
||||||
width: UM.Theme.getSize("sidebar").width;
|
width: UM.Theme.getSize("sidebar").width;
|
||||||
|
monitoringPrint: base.showPrintMonitor
|
||||||
}
|
}
|
||||||
|
|
||||||
Button
|
Button
|
||||||
|
@ -412,13 +441,13 @@ UM.MainWindow
|
||||||
color: UM.Theme.getColor("viewport_overlay")
|
color: UM.Theme.getColor("viewport_overlay")
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
top: parent.top
|
top: topbar.bottom
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
left:parent.left
|
left:parent.left
|
||||||
right: sidebar.left
|
right: sidebar.left
|
||||||
}
|
}
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
opacity: base.monitoringPrint ? 0.75 : 0
|
opacity: base.showPrintMonitor ? 0.75 : 0
|
||||||
|
|
||||||
Behavior on opacity { NumberAnimation { duration: 100; } }
|
Behavior on opacity { NumberAnimation { duration: 100; } }
|
||||||
|
|
||||||
|
@ -433,12 +462,10 @@ UM.MainWindow
|
||||||
Loader
|
Loader
|
||||||
{
|
{
|
||||||
sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null
|
sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null
|
||||||
visible: base.monitoringPrint
|
visible: base.showPrintMonitor
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.horizontalCenterOffset: - UM.Theme.getSize("sidebar").width / 2
|
anchors.horizontalCenterOffset: - UM.Theme.getSize("sidebar").width / 2
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UM.MessageStack
|
UM.MessageStack
|
||||||
|
|
|
@ -86,6 +86,8 @@ UM.PreferencesPage
|
||||||
centerOnSelectCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select"))
|
centerOnSelectCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select"))
|
||||||
UM.Preferences.resetPreference("view/invert_zoom");
|
UM.Preferences.resetPreference("view/invert_zoom");
|
||||||
invertZoomCheckbox.checked = boolCheck(UM.Preferences.getValue("view/invert_zoom"))
|
invertZoomCheckbox.checked = boolCheck(UM.Preferences.getValue("view/invert_zoom"))
|
||||||
|
UM.Preferences.resetPreference("view/zoom_to_mouse");
|
||||||
|
zoomToMouseCheckbox.checked = boolCheck(UM.Preferences.getValue("view/zoom_to_mouse"))
|
||||||
UM.Preferences.resetPreference("view/top_layer_count");
|
UM.Preferences.resetPreference("view/top_layer_count");
|
||||||
topLayerCountCheckbox.checked = boolCheck(UM.Preferences.getValue("view/top_layer_count"))
|
topLayerCountCheckbox.checked = boolCheck(UM.Preferences.getValue("view/top_layer_count"))
|
||||||
|
|
||||||
|
@ -355,6 +357,20 @@ UM.PreferencesPage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UM.TooltipArea {
|
||||||
|
width: childrenRect.width;
|
||||||
|
height: childrenRect.height;
|
||||||
|
text: catalog.i18nc("@info:tooltip", "Should zooming move in the direction of the mouse?")
|
||||||
|
|
||||||
|
CheckBox
|
||||||
|
{
|
||||||
|
id: zoomToMouseCheckbox
|
||||||
|
text: catalog.i18nc("@action:button", "Zoom toward mouse direction");
|
||||||
|
checked: boolCheck(UM.Preferences.getValue("view/zoom_to_mouse"))
|
||||||
|
onClicked: UM.Preferences.setValue("view/zoom_to_mouse", checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UM.TooltipArea {
|
UM.TooltipArea {
|
||||||
width: childrenRect.width
|
width: childrenRect.width
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
|
|
|
@ -169,9 +169,11 @@ TabView
|
||||||
// This does not use a SettingPropertyProvider, because we need to make the change to all containers
|
// This does not use a SettingPropertyProvider, because we need to make the change to all containers
|
||||||
// which derive from the same base_file
|
// which derive from the same base_file
|
||||||
var old_diameter = Cura.ContainerManager.getContainerProperty(base.containerId, "material_diameter", "value").toString();
|
var old_diameter = Cura.ContainerManager.getContainerProperty(base.containerId, "material_diameter", "value").toString();
|
||||||
base.setMetaDataEntry("approximate_diameter", properties.approximate_diameter, Math.round(value).toString());
|
var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
|
||||||
|
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, Math.round(value).toString());
|
||||||
base.setMetaDataEntry("properties/diameter", properties.diameter, value);
|
base.setMetaDataEntry("properties/diameter", properties.diameter, value);
|
||||||
if (Cura.MachineManager.filterMaterialsByMachine && properties.approximate_diameter != Cura.MachineManager.activeMachine.approximateMaterialDiameter)
|
var new_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
|
||||||
|
if (Cura.MachineManager.filterMaterialsByMachine && new_approximate_diameter != Cura.MachineManager.activeMachine.approximateMaterialDiameter)
|
||||||
{
|
{
|
||||||
Cura.MaterialManager.showMaterialWarningMessage(base.containerId, old_diameter);
|
Cura.MaterialManager.showMaterialWarningMessage(base.containerId, old_diameter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2016 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.
|
||||||
|
|
||||||
import QtQuick 2.1
|
import QtQuick 2.1
|
||||||
|
@ -139,6 +139,7 @@ UM.ManagementPage
|
||||||
enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials
|
enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials
|
||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
|
forceActiveFocus();
|
||||||
Cura.MachineManager.setActiveMaterial(base.currentItem.id)
|
Cura.MachineManager.setActiveMaterial(base.currentItem.id)
|
||||||
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
|
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
|
||||||
}
|
}
|
||||||
|
@ -149,6 +150,7 @@ UM.ManagementPage
|
||||||
iconName: "list-add"
|
iconName: "list-add"
|
||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
|
forceActiveFocus();
|
||||||
var material_id = Cura.ContainerManager.createMaterial()
|
var material_id = Cura.ContainerManager.createMaterial()
|
||||||
if(material_id == "")
|
if(material_id == "")
|
||||||
{
|
{
|
||||||
|
@ -168,6 +170,7 @@ UM.ManagementPage
|
||||||
enabled: base.currentItem != null
|
enabled: base.currentItem != null
|
||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
|
forceActiveFocus();
|
||||||
var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file")
|
var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file")
|
||||||
// We need to copy the base container instead of the specific variant.
|
// We need to copy the base container instead of the specific variant.
|
||||||
var material_id = base_file == "" ? Cura.ContainerManager.duplicateMaterial(base.currentItem.id): Cura.ContainerManager.duplicateMaterial(base_file)
|
var material_id = base_file == "" ? Cura.ContainerManager.duplicateMaterial(base.currentItem.id): Cura.ContainerManager.duplicateMaterial(base_file)
|
||||||
|
@ -187,20 +190,32 @@ UM.ManagementPage
|
||||||
text: catalog.i18nc("@action:button", "Remove");
|
text: catalog.i18nc("@action:button", "Remove");
|
||||||
iconName: "list-remove";
|
iconName: "list-remove";
|
||||||
enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id)
|
enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id)
|
||||||
onClicked: confirmDialog.open()
|
onClicked:
|
||||||
|
{
|
||||||
|
forceActiveFocus();
|
||||||
|
confirmDialog.open();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Button
|
Button
|
||||||
{
|
{
|
||||||
text: catalog.i18nc("@action:button", "Import");
|
text: catalog.i18nc("@action:button", "Import");
|
||||||
iconName: "document-import";
|
iconName: "document-import";
|
||||||
onClicked: importDialog.open();
|
onClicked:
|
||||||
|
{
|
||||||
|
forceActiveFocus();
|
||||||
|
importDialog.open();
|
||||||
|
}
|
||||||
visible: true;
|
visible: true;
|
||||||
},
|
},
|
||||||
Button
|
Button
|
||||||
{
|
{
|
||||||
text: catalog.i18nc("@action:button", "Export")
|
text: catalog.i18nc("@action:button", "Export")
|
||||||
iconName: "document-export"
|
iconName: "document-export"
|
||||||
onClicked: exportDialog.open()
|
onClicked:
|
||||||
|
{
|
||||||
|
forceActiveFocus();
|
||||||
|
exportDialog.open();
|
||||||
|
}
|
||||||
enabled: currentItem != null
|
enabled: currentItem != null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
import QtQuick 2.2
|
import QtQuick 2.2
|
||||||
|
@ -24,7 +24,7 @@ Item {
|
||||||
{
|
{
|
||||||
if(!activity)
|
if(!activity)
|
||||||
{
|
{
|
||||||
return catalog.i18nc("@label:PrintjobStatus", "Please load a 3d model");
|
return catalog.i18nc("@label:PrintjobStatus", "Please load a 3D model");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(base.backendState)
|
switch(base.backendState)
|
||||||
|
|
|
@ -15,24 +15,15 @@ Rectangle
|
||||||
id: base;
|
id: base;
|
||||||
|
|
||||||
property int currentModeIndex;
|
property int currentModeIndex;
|
||||||
property bool monitoringPrint: false; // When adding more "tabs", one want to replace this bool with a ListModel
|
|
||||||
property bool hideSettings: PrintInformation.preSliced
|
property bool hideSettings: PrintInformation.preSliced
|
||||||
Connections
|
|
||||||
{
|
|
||||||
target: Printer
|
|
||||||
onShowPrintMonitor:
|
|
||||||
{
|
|
||||||
base.monitoringPrint = show;
|
|
||||||
showSettings.checked = !show;
|
|
||||||
showMonitor.checked = show;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is there an output device for this printer?
|
// Is there an output device for this printer?
|
||||||
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
|
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
|
||||||
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
|
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
|
||||||
property int backendState: UM.Backend.state;
|
property int backendState: UM.Backend.state;
|
||||||
|
|
||||||
|
property bool monitoringPrint: false
|
||||||
|
|
||||||
color: UM.Theme.getColor("sidebar")
|
color: UM.Theme.getColor("sidebar")
|
||||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||||
|
|
||||||
|
@ -88,227 +79,10 @@ Rectangle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Printer selection and mode selection buttons for changing between Setting & Monitor print mode
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
id: sidebarHeaderBar
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
height: childrenRect.height
|
|
||||||
color: UM.Theme.getColor("sidebar_header_bar")
|
|
||||||
|
|
||||||
Row
|
|
||||||
{
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
spacing: UM.Theme.getSize("default_margin").width
|
|
||||||
|
|
||||||
ToolButton
|
|
||||||
{
|
|
||||||
id: machineSelection
|
|
||||||
text: Cura.MachineManager.activeMachineName
|
|
||||||
|
|
||||||
width: parent.width - (showSettings.width + showMonitor.width + 2 * UM.Theme.getSize("default_margin").width)
|
|
||||||
height: UM.Theme.getSize("sidebar_header").height
|
|
||||||
tooltip: Cura.MachineManager.activeMachineName
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
style: ButtonStyle {
|
|
||||||
background: Rectangle {
|
|
||||||
color: {
|
|
||||||
if(control.pressed) {
|
|
||||||
return UM.Theme.getColor("sidebar_header_active");
|
|
||||||
} else if(control.hovered) {
|
|
||||||
return UM.Theme.getColor("sidebar_header_hover");
|
|
||||||
} else {
|
|
||||||
return UM.Theme.getColor("sidebar_header_bar");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Behavior on color { ColorAnimation { duration: 50; } }
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: underline;
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
height: UM.Theme.getSize("sidebar_header_highlight").height
|
|
||||||
color: UM.Theme.getColor("sidebar_header_highlight_hover")
|
|
||||||
visible: control.hovered || control.pressed
|
|
||||||
}
|
|
||||||
|
|
||||||
UM.RecolorImage {
|
|
||||||
id: downArrow
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
width: UM.Theme.getSize("standard_arrow").width
|
|
||||||
height: UM.Theme.getSize("standard_arrow").height
|
|
||||||
sourceSize.width: width
|
|
||||||
sourceSize.height: width
|
|
||||||
color: UM.Theme.getColor("text_reversed")
|
|
||||||
source: UM.Theme.getIcon("arrow_bottom")
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: sidebarComboBoxLabel
|
|
||||||
color: UM.Theme.getColor("text_reversed")
|
|
||||||
text: control.text;
|
|
||||||
elide: Text.ElideRight;
|
|
||||||
anchors.left: parent.left;
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.right: downArrow.left;
|
|
||||||
anchors.rightMargin: control.rightMargin;
|
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
|
||||||
font: UM.Theme.getFont("large")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
label: Label{}
|
|
||||||
}
|
|
||||||
|
|
||||||
menu: PrinterMenu { }
|
|
||||||
}
|
|
||||||
|
|
||||||
Button
|
|
||||||
{
|
|
||||||
id: showSettings
|
|
||||||
width: height
|
|
||||||
height: UM.Theme.getSize("sidebar_header").height
|
|
||||||
onClicked: monitoringPrint = false
|
|
||||||
iconSource: UM.Theme.getIcon("tab_settings");
|
|
||||||
property color overlayColor: "transparent"
|
|
||||||
property string overlayIconSource: ""
|
|
||||||
|
|
||||||
checkable: true
|
|
||||||
checked: !monitoringPrint
|
|
||||||
exclusiveGroup: sidebarHeaderBarGroup
|
|
||||||
property string tooltipText: catalog.i18nc("@tooltip", "<b>Print Setup</b><br/><br/>Edit or review the settings for the active print job.")
|
|
||||||
|
|
||||||
onHoveredChanged: {
|
|
||||||
if (hovered)
|
|
||||||
{
|
|
||||||
tooltipDelayTimer.item = showSettings
|
|
||||||
tooltipDelayTimer.text = tooltipText
|
|
||||||
tooltipDelayTimer.start();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tooltipDelayTimer.stop();
|
|
||||||
base.hideTooltip();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
style: UM.Theme.styles.sidebar_header_tab
|
|
||||||
}
|
|
||||||
|
|
||||||
Button
|
|
||||||
{
|
|
||||||
id: showMonitor
|
|
||||||
width: height
|
|
||||||
height: UM.Theme.getSize("sidebar_header").height
|
|
||||||
onClicked: monitoringPrint = true
|
|
||||||
iconSource: printerConnected ? UM.Theme.getIcon("tab_monitor_with_status") : UM.Theme.getIcon("tab_monitor")
|
|
||||||
property color overlayColor:
|
|
||||||
{
|
|
||||||
if(!printerAcceptsCommands)
|
|
||||||
{
|
|
||||||
return UM.Theme.getColor("status_unknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance")
|
|
||||||
{
|
|
||||||
return UM.Theme.getColor("status_busy");
|
|
||||||
}
|
|
||||||
switch(Cura.MachineManager.printerOutputDevices[0].jobState)
|
|
||||||
{
|
|
||||||
case "printing":
|
|
||||||
case "pre_print":
|
|
||||||
case "wait_cleanup":
|
|
||||||
case "pausing":
|
|
||||||
case "resuming":
|
|
||||||
return UM.Theme.getColor("status_busy");
|
|
||||||
case "ready":
|
|
||||||
case "":
|
|
||||||
return UM.Theme.getColor("status_ready");
|
|
||||||
case "paused":
|
|
||||||
return UM.Theme.getColor("status_paused");
|
|
||||||
case "error":
|
|
||||||
return UM.Theme.getColor("status_stopped");
|
|
||||||
case "offline":
|
|
||||||
return UM.Theme.getColor("status_offline");
|
|
||||||
default:
|
|
||||||
return UM.Theme.getColor("text_reversed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
property string overlayIconSource:
|
|
||||||
{
|
|
||||||
if(!printerConnected)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
else if(!printerAcceptsCommands)
|
|
||||||
{
|
|
||||||
return UM.Theme.getIcon("tab_status_unknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance")
|
|
||||||
{
|
|
||||||
return UM.Theme.getIcon("tab_status_busy");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(Cura.MachineManager.printerOutputDevices[0].jobState)
|
|
||||||
{
|
|
||||||
case "printing":
|
|
||||||
case "pre_print":
|
|
||||||
case "wait_cleanup":
|
|
||||||
case "pausing":
|
|
||||||
case "resuming":
|
|
||||||
return UM.Theme.getIcon("tab_status_busy");
|
|
||||||
case "ready":
|
|
||||||
case "":
|
|
||||||
return UM.Theme.getIcon("tab_status_connected")
|
|
||||||
case "paused":
|
|
||||||
return UM.Theme.getIcon("tab_status_paused")
|
|
||||||
case "error":
|
|
||||||
return UM.Theme.getIcon("tab_status_stopped")
|
|
||||||
case "offline":
|
|
||||||
return UM.Theme.getIcon("tab_status_offline")
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkable: true
|
|
||||||
checked: monitoringPrint
|
|
||||||
exclusiveGroup: sidebarHeaderBarGroup
|
|
||||||
property string tooltipText: catalog.i18nc("@tooltip", "<b>Print Monitor</b><br/><br/>Monitor the state of the connected printer and the print job in progress.")
|
|
||||||
|
|
||||||
onHoveredChanged: {
|
|
||||||
if (hovered)
|
|
||||||
{
|
|
||||||
tooltipDelayTimer.item = showMonitor
|
|
||||||
tooltipDelayTimer.text = tooltipText
|
|
||||||
tooltipDelayTimer.start();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tooltipDelayTimer.stop();
|
|
||||||
base.hideTooltip();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
style: UM.Theme.styles.sidebar_header_tab
|
|
||||||
}
|
|
||||||
ExclusiveGroup { id: sidebarHeaderBarGroup }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SidebarHeader {
|
SidebarHeader {
|
||||||
id: header
|
id: header
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
anchors.top: sidebarHeaderBar.bottom
|
|
||||||
|
|
||||||
onShowTooltip: base.showTooltip(item, location, text)
|
onShowTooltip: base.showTooltip(item, location, text)
|
||||||
onHideTooltip: base.hideTooltip()
|
onHideTooltip: base.hideTooltip()
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,23 +106,14 @@ Item
|
||||||
opacity: panel.item && panel.width > 0 ? 1 : 0
|
opacity: panel.item && panel.width > 0 ? 1 : 0
|
||||||
Behavior on opacity { NumberAnimation { duration: 100 } }
|
Behavior on opacity { NumberAnimation { duration: 100 } }
|
||||||
|
|
||||||
color: UM.Theme.getColor("lining");
|
color: UM.Theme.getColor("tool_panel_background")
|
||||||
|
borderColor: UM.Theme.getColor("lining")
|
||||||
|
borderWidth: UM.Theme.getSize("default_lining").width
|
||||||
|
|
||||||
UM.PointingRectangle
|
|
||||||
{
|
|
||||||
id: panelBackground;
|
|
||||||
|
|
||||||
color: UM.Theme.getColor("tool_panel_background");
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: UM.Theme.getSize("default_lining").width
|
|
||||||
|
|
||||||
target: Qt.point(-UM.Theme.getSize("default_margin").width, UM.Theme.getSize("button").height/2)
|
|
||||||
arrowSize: parent.arrowSize
|
|
||||||
MouseArea //Catch all mouse events (so scene doesnt handle them)
|
MouseArea //Catch all mouse events (so scene doesnt handle them)
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Loader
|
Loader
|
||||||
{
|
{
|
||||||
|
|
216
resources/qml/Topbar.qml
Normal file
216
resources/qml/Topbar.qml
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
// Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
// Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
|
import QtQuick 2.2
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Styles 1.1
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import UM 1.2 as UM
|
||||||
|
import Cura 1.0 as Cura
|
||||||
|
import "Menus"
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: base
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
height: UM.Theme.getSize("sidebar_header").height
|
||||||
|
color: UM.Theme.getColor("sidebar_header_bar")
|
||||||
|
|
||||||
|
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
|
||||||
|
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
|
||||||
|
property bool monitoringPrint: false
|
||||||
|
signal startMonitoringPrint()
|
||||||
|
signal stopMonitoringPrint()
|
||||||
|
UM.I18nCatalog
|
||||||
|
{
|
||||||
|
id: catalog
|
||||||
|
name:"cura"
|
||||||
|
}
|
||||||
|
|
||||||
|
Row
|
||||||
|
{
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: machineSelection.left
|
||||||
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
spacing: UM.Theme.getSize("default_margin").width
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: showSettings
|
||||||
|
height: UM.Theme.getSize("sidebar_header").height
|
||||||
|
onClicked: base.stopMonitoringPrint()
|
||||||
|
iconSource: UM.Theme.getIcon("tab_settings");
|
||||||
|
property color overlayColor: "transparent"
|
||||||
|
property string overlayIconSource: ""
|
||||||
|
text: catalog.i18nc("@title:tab","Prepare")
|
||||||
|
checkable: true
|
||||||
|
checked: !base.monitoringPrint
|
||||||
|
exclusiveGroup: sidebarHeaderBarGroup
|
||||||
|
|
||||||
|
style: UM.Theme.styles.topbar_header_tab
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: showMonitor
|
||||||
|
height: UM.Theme.getSize("sidebar_header").height
|
||||||
|
onClicked: base.startMonitoringPrint()
|
||||||
|
text: catalog.i18nc("@title:tab", "Print")
|
||||||
|
iconSource: printerConnected ? UM.Theme.getIcon("tab_monitor_with_status") : UM.Theme.getIcon("tab_monitor")
|
||||||
|
property color overlayColor:
|
||||||
|
{
|
||||||
|
if(!printerAcceptsCommands)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("status_unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance")
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("status_busy");
|
||||||
|
}
|
||||||
|
switch(Cura.MachineManager.printerOutputDevices[0].jobState)
|
||||||
|
{
|
||||||
|
case "printing":
|
||||||
|
case "pre_print":
|
||||||
|
case "wait_cleanup":
|
||||||
|
case "pausing":
|
||||||
|
case "resuming":
|
||||||
|
return UM.Theme.getColor("status_busy");
|
||||||
|
case "ready":
|
||||||
|
case "":
|
||||||
|
return UM.Theme.getColor("status_ready");
|
||||||
|
case "paused":
|
||||||
|
return UM.Theme.getColor("status_paused");
|
||||||
|
case "error":
|
||||||
|
return UM.Theme.getColor("status_stopped");
|
||||||
|
case "offline":
|
||||||
|
return UM.Theme.getColor("status_offline");
|
||||||
|
default:
|
||||||
|
return UM.Theme.getColor("text_reversed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
property string overlayIconSource:
|
||||||
|
{
|
||||||
|
if(!printerConnected)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else if(!printerAcceptsCommands)
|
||||||
|
{
|
||||||
|
return UM.Theme.getIcon("tab_status_unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance")
|
||||||
|
{
|
||||||
|
return UM.Theme.getIcon("tab_status_busy");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(Cura.MachineManager.printerOutputDevices[0].jobState)
|
||||||
|
{
|
||||||
|
case "printing":
|
||||||
|
case "pre_print":
|
||||||
|
case "wait_cleanup":
|
||||||
|
case "pausing":
|
||||||
|
case "resuming":
|
||||||
|
return UM.Theme.getIcon("tab_status_busy");
|
||||||
|
case "ready":
|
||||||
|
case "":
|
||||||
|
return UM.Theme.getIcon("tab_status_connected")
|
||||||
|
case "paused":
|
||||||
|
return UM.Theme.getIcon("tab_status_paused")
|
||||||
|
case "error":
|
||||||
|
return UM.Theme.getIcon("tab_status_stopped")
|
||||||
|
case "offline":
|
||||||
|
return UM.Theme.getIcon("tab_status_offline")
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkable: true
|
||||||
|
checked: base.monitoringPrint
|
||||||
|
exclusiveGroup: sidebarHeaderBarGroup
|
||||||
|
|
||||||
|
style: UM.Theme.styles.topbar_header_tab
|
||||||
|
}
|
||||||
|
|
||||||
|
ExclusiveGroup { id: sidebarHeaderBarGroup }
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolButton
|
||||||
|
{
|
||||||
|
id: machineSelection
|
||||||
|
text: Cura.MachineManager.activeMachineName
|
||||||
|
|
||||||
|
width: UM.Theme.getSize("sidebar").width;
|
||||||
|
height: UM.Theme.getSize("sidebar_header").height
|
||||||
|
tooltip: Cura.MachineManager.activeMachineName
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
style: ButtonStyle
|
||||||
|
{
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
color:
|
||||||
|
{
|
||||||
|
if(control.pressed)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("sidebar_header_active");
|
||||||
|
} else if(control.hovered)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("sidebar_header_hover");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("sidebar_header_bar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on color { ColorAnimation { duration: 50; } }
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: underline;
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
height: UM.Theme.getSize("sidebar_header_highlight").height
|
||||||
|
color: UM.Theme.getColor("sidebar_header_highlight_hover")
|
||||||
|
visible: control.hovered || control.pressed
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.RecolorImage
|
||||||
|
{
|
||||||
|
id: downArrow
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
width: UM.Theme.getSize("standard_arrow").width
|
||||||
|
height: UM.Theme.getSize("standard_arrow").height
|
||||||
|
sourceSize.width: width
|
||||||
|
sourceSize.height: width
|
||||||
|
color: UM.Theme.getColor("text_reversed")
|
||||||
|
source: UM.Theme.getIcon("arrow_bottom")
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: sidebarComboBoxLabel
|
||||||
|
color: UM.Theme.getColor("text_reversed")
|
||||||
|
text: control.text;
|
||||||
|
elide: Text.ElideRight;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
anchors.right: downArrow.left;
|
||||||
|
anchors.rightMargin: control.rightMargin;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
font: UM.Theme.getFont("large")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label: Label {}
|
||||||
|
}
|
||||||
|
|
||||||
|
menu: PrinterMenu { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
weight = 0
|
weight = 0
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.2
|
layer_height = 0.2
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
weight = 1
|
weight = 1
|
||||||
quality_type = high
|
quality_type = high
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.1
|
layer_height = 0.1
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
weight = 0
|
weight = 0
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.2
|
layer_height = 0.2
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
weight = 0
|
weight = 0
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.2
|
layer_height = 0.2
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
weight = 1
|
weight = 1
|
||||||
quality_type = high
|
quality_type = high
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.1
|
layer_height = 0.1
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
weight = 0
|
weight = 0
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.2
|
layer_height = 0.2
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
weight = 0
|
weight = 0
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.2
|
layer_height = 0.2
|
||||||
|
|
|
@ -7,7 +7,7 @@ type = quality
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
weight = 1
|
weight = 1
|
||||||
quality_type = high
|
quality_type = high
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.1
|
layer_height = 0.1
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
weight = 0
|
weight = 0
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.2
|
layer_height = 0.2
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
material = generic_abs_175_cartesio_0.25_mm
|
material = generic_abs_175_cartesio_0.25_mm
|
||||||
weight = 1
|
weight = 1
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.3
|
infill_line_width = 0.3
|
||||||
|
@ -35,7 +35,7 @@ speed_print = 50
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = =round(speed_print / 5 * 4)
|
speed_layer_0 = =round(speed_print / 5 * 4)
|
||||||
speed_wall = =round(speed_print / 2)
|
speed_wall = =round(speed_print / 2)
|
||||||
speed_wall_0 = =10 if speed_wall < 11 else (speed_print / 5 *3)
|
speed_wall_0 = =10 if speed_wall < 11 else 15
|
||||||
speed_topbottom = =round(speed_print / 5 * 4)
|
speed_topbottom = =round(speed_print / 5 * 4)
|
||||||
speed_travel = =round(speed_print if magic_spiralize else 150)
|
speed_travel = =round(speed_print if magic_spiralize else 150)
|
||||||
speed_travel_layer_0 = =speed_travel
|
speed_travel_layer_0 = =speed_travel
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
material = generic_abs_175_cartesio_0.25_mm
|
material = generic_abs_175_cartesio_0.25_mm
|
||||||
weight = 2
|
weight = 2
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.3
|
infill_line_width = 0.3
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
material = generic_abs_175_cartesio_0.4_mm
|
material = generic_abs_175_cartesio_0.4_mm
|
||||||
weight = 1
|
weight = 1
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.5
|
infill_line_width = 0.5
|
||||||
|
@ -35,7 +35,7 @@ speed_print = 50
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = =round(speed_print / 5 * 4)
|
speed_layer_0 = =round(speed_print / 5 * 4)
|
||||||
speed_wall = =round(speed_print / 2)
|
speed_wall = =round(speed_print / 2)
|
||||||
speed_wall_0 = =10 if speed_wall < 11 else (speed_print / 5 *3)
|
speed_wall_0 = =10 if speed_wall < 11 else 15
|
||||||
speed_topbottom = =round(speed_print / 5 * 4)
|
speed_topbottom = =round(speed_print / 5 * 4)
|
||||||
speed_travel = =round(speed_print if magic_spiralize else 150)
|
speed_travel = =round(speed_print if magic_spiralize else 150)
|
||||||
speed_travel_layer_0 = =speed_travel
|
speed_travel_layer_0 = =speed_travel
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
material = generic_abs_175_cartesio_0.4_mm
|
material = generic_abs_175_cartesio_0.4_mm
|
||||||
weight = 2
|
weight = 2
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.5
|
infill_line_width = 0.5
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = coarse
|
quality_type = coarse
|
||||||
material = generic_abs_175_cartesio_0.8_mm
|
material = generic_abs_175_cartesio_0.8_mm
|
||||||
weight = 3
|
weight = 3
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = extra coarse
|
quality_type = extra coarse
|
||||||
material = generic_abs_175_cartesio_0.8_mm
|
material = generic_abs_175_cartesio_0.8_mm
|
||||||
weight = 4
|
weight = 4
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
material = generic_abs_175_cartesio_0.8_mm
|
material = generic_abs_175_cartesio_0.8_mm
|
||||||
weight = 1
|
weight = 1
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
@ -35,7 +35,7 @@ speed_print = 50
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = =round(speed_print / 5 * 4)
|
speed_layer_0 = =round(speed_print / 5 * 4)
|
||||||
speed_wall = =round(speed_print / 2)
|
speed_wall = =round(speed_print / 2)
|
||||||
speed_wall_0 = =10 if speed_wall < 11 else (speed_print / 5 *3)
|
speed_wall_0 = =10 if speed_wall < 11 else 15
|
||||||
speed_topbottom = =round(speed_print / 5 * 4)
|
speed_topbottom = =round(speed_print / 5 * 4)
|
||||||
speed_travel = =round(speed_print if magic_spiralize else 150)
|
speed_travel = =round(speed_print if magic_spiralize else 150)
|
||||||
speed_travel_layer_0 = =speed_travel
|
speed_travel_layer_0 = =speed_travel
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
material = generic_abs_175_cartesio_0.8_mm
|
material = generic_abs_175_cartesio_0.8_mm
|
||||||
weight = 2
|
weight = 2
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
material = dsm_arnitel2045_175_cartesio_0.4_mm
|
material = dsm_arnitel2045_175_cartesio_0.4_mm
|
||||||
weight = 1
|
weight = 1
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.5
|
infill_line_width = 0.5
|
||||||
|
@ -35,7 +35,7 @@ speed_print = 25
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = =round(speed_print / 5 * 4)
|
speed_layer_0 = =round(speed_print / 5 * 4)
|
||||||
speed_wall = =round(speed_print / 2)
|
speed_wall = =round(speed_print / 2)
|
||||||
speed_wall_0 = =10 if speed_wall < 11 else (speed_print / 5 *3)
|
speed_wall_0 = =10 if speed_wall < 11 else 15
|
||||||
speed_topbottom = =round(speed_print / 5 * 4)
|
speed_topbottom = =round(speed_print / 5 * 4)
|
||||||
speed_travel = =round(speed_print if magic_spiralize else 150)
|
speed_travel = =round(speed_print if magic_spiralize else 150)
|
||||||
speed_travel_layer_0 = =speed_travel
|
speed_travel_layer_0 = =speed_travel
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
material = dsm_arnitel2045_175_cartesio_0.4_mm
|
material = dsm_arnitel2045_175_cartesio_0.4_mm
|
||||||
weight = 2
|
weight = 2
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.5
|
infill_line_width = 0.5
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = coarse
|
quality_type = coarse
|
||||||
global_quality = True
|
global_quality = True
|
||||||
weight = 0
|
weight = 0
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.4
|
layer_height = 0.4
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = extra coarse
|
quality_type = extra coarse
|
||||||
global_quality = True
|
global_quality = True
|
||||||
weight = 0
|
weight = 0
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.6
|
layer_height = 0.6
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
global_quality = True
|
global_quality = True
|
||||||
weight = 0
|
weight = 0
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.1
|
layer_height = 0.1
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
global_quality = True
|
global_quality = True
|
||||||
weight = 0
|
weight = 0
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
layer_height = 0.2
|
layer_height = 0.2
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
material = generic_hips_175_cartesio_0.25_mm
|
material = generic_hips_175_cartesio_0.25_mm
|
||||||
weight = 1
|
weight = 1
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.3
|
infill_line_width = 0.3
|
||||||
|
@ -35,7 +35,7 @@ speed_print = 50
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = =round(speed_print / 5 * 4)
|
speed_layer_0 = =round(speed_print / 5 * 4)
|
||||||
speed_wall = =round(speed_print / 2)
|
speed_wall = =round(speed_print / 2)
|
||||||
speed_wall_0 = =10 if speed_wall < 11 else (speed_print / 5 *3)
|
speed_wall_0 = =10 if speed_wall < 11 else 15
|
||||||
speed_topbottom = =round(speed_print / 5 * 4)
|
speed_topbottom = =round(speed_print / 5 * 4)
|
||||||
speed_travel = =round(speed_print if magic_spiralize else 150)
|
speed_travel = =round(speed_print if magic_spiralize else 150)
|
||||||
speed_travel_layer_0 = =speed_travel
|
speed_travel_layer_0 = =speed_travel
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
material = generic_hips_175_cartesio_0.25_mm
|
material = generic_hips_175_cartesio_0.25_mm
|
||||||
weight = 2
|
weight = 2
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.3
|
infill_line_width = 0.3
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
material = generic_hips_175_cartesio_0.4_mm
|
material = generic_hips_175_cartesio_0.4_mm
|
||||||
weight = 1
|
weight = 1
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.5
|
infill_line_width = 0.5
|
||||||
|
@ -35,7 +35,7 @@ speed_print = 50
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = =round(speed_print / 5 * 4)
|
speed_layer_0 = =round(speed_print / 5 * 4)
|
||||||
speed_wall = =round(speed_print / 2)
|
speed_wall = =round(speed_print / 2)
|
||||||
speed_wall_0 = =10 if speed_wall < 11 else (speed_print / 5 *3)
|
speed_wall_0 = =10 if speed_wall < 11 else 15
|
||||||
speed_topbottom = =round(speed_print / 5 * 4)
|
speed_topbottom = =round(speed_print / 5 * 4)
|
||||||
speed_travel = =round(speed_print if magic_spiralize else 150)
|
speed_travel = =round(speed_print if magic_spiralize else 150)
|
||||||
speed_travel_layer_0 = =speed_travel
|
speed_travel_layer_0 = =speed_travel
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
material = generic_hips_175_cartesio_0.4_mm
|
material = generic_hips_175_cartesio_0.4_mm
|
||||||
weight = 2
|
weight = 2
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.5
|
infill_line_width = 0.5
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = coarse
|
quality_type = coarse
|
||||||
material = generic_hips_175_cartesio_0.8_mm
|
material = generic_hips_175_cartesio_0.8_mm
|
||||||
weight = 3
|
weight = 3
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = extra coarse
|
quality_type = extra coarse
|
||||||
material = generic_hips_175_cartesio_0.8_mm
|
material = generic_hips_175_cartesio_0.8_mm
|
||||||
weight = 4
|
weight = 4
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
material = generic_hips_175_cartesio_0.8_mm
|
material = generic_hips_175_cartesio_0.8_mm
|
||||||
weight = 1
|
weight = 1
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
@ -35,7 +35,7 @@ speed_print = 50
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = =round(speed_print / 5 * 4)
|
speed_layer_0 = =round(speed_print / 5 * 4)
|
||||||
speed_wall = =round(speed_print / 2)
|
speed_wall = =round(speed_print / 2)
|
||||||
speed_wall_0 = =10 if speed_wall < 11 else (speed_print / 5 *3)
|
speed_wall_0 = =10 if speed_wall < 11 else 15
|
||||||
speed_topbottom = =round(speed_print / 5 * 4)
|
speed_topbottom = =round(speed_print / 5 * 4)
|
||||||
speed_travel = =round(speed_print if magic_spiralize else 150)
|
speed_travel = =round(speed_print if magic_spiralize else 150)
|
||||||
speed_travel_layer_0 = =speed_travel
|
speed_travel_layer_0 = =speed_travel
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
material = generic_hips_175_cartesio_0.8_mm
|
material = generic_hips_175_cartesio_0.8_mm
|
||||||
weight = 2
|
weight = 2
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
material = generic_nylon_175_cartesio_0.25_mm
|
material = generic_nylon_175_cartesio_0.25_mm
|
||||||
weight = 1
|
weight = 1
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.3
|
infill_line_width = 0.3
|
||||||
|
@ -35,7 +35,7 @@ speed_print = 50
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = =round(speed_print / 5 * 4)
|
speed_layer_0 = =round(speed_print / 5 * 4)
|
||||||
speed_wall = =round(speed_print / 2)
|
speed_wall = =round(speed_print / 2)
|
||||||
speed_wall_0 = =10 if speed_wall < 11 else (speed_print / 5 *3)
|
speed_wall_0 = =10 if speed_wall < 11 else 15
|
||||||
speed_topbottom = =round(speed_print / 5 * 4)
|
speed_topbottom = =round(speed_print / 5 * 4)
|
||||||
speed_travel = =round(speed_print if magic_spiralize else 150)
|
speed_travel = =round(speed_print if magic_spiralize else 150)
|
||||||
speed_travel_layer_0 = =speed_travel
|
speed_travel_layer_0 = =speed_travel
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
material = generic_nylon_175_cartesio_0.25_mm
|
material = generic_nylon_175_cartesio_0.25_mm
|
||||||
weight = 2
|
weight = 2
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.3
|
infill_line_width = 0.3
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
material = generic_nylon_175_cartesio_0.4_mm
|
material = generic_nylon_175_cartesio_0.4_mm
|
||||||
weight = 1
|
weight = 1
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.5
|
infill_line_width = 0.5
|
||||||
|
@ -35,7 +35,7 @@ speed_print = 50
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = =round(speed_print / 5 * 4)
|
speed_layer_0 = =round(speed_print / 5 * 4)
|
||||||
speed_wall = =round(speed_print / 2)
|
speed_wall = =round(speed_print / 2)
|
||||||
speed_wall_0 = =10 if speed_wall < 11 else (speed_print / 5 *3)
|
speed_wall_0 = =10 if speed_wall < 11 else 15
|
||||||
speed_topbottom = =round(speed_print / 5 * 4)
|
speed_topbottom = =round(speed_print / 5 * 4)
|
||||||
speed_travel = =round(speed_print if magic_spiralize else 150)
|
speed_travel = =round(speed_print if magic_spiralize else 150)
|
||||||
speed_travel_layer_0 = =speed_travel
|
speed_travel_layer_0 = =speed_travel
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = normal
|
quality_type = normal
|
||||||
material = generic_nylon_175_cartesio_0.4_mm
|
material = generic_nylon_175_cartesio_0.4_mm
|
||||||
weight = 2
|
weight = 2
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.5
|
infill_line_width = 0.5
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = coarse
|
quality_type = coarse
|
||||||
material = generic_nylon_175_cartesio_0.8_mm
|
material = generic_nylon_175_cartesio_0.8_mm
|
||||||
weight = 3
|
weight = 3
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = extra coarse
|
quality_type = extra coarse
|
||||||
material = generic_nylon_175_cartesio_0.8_mm
|
material = generic_nylon_175_cartesio_0.8_mm
|
||||||
weight = 4
|
weight = 4
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
|
|
@ -8,7 +8,7 @@ type = quality
|
||||||
quality_type = high
|
quality_type = high
|
||||||
material = generic_nylon_175_cartesio_0.8_mm
|
material = generic_nylon_175_cartesio_0.8_mm
|
||||||
weight = 1
|
weight = 1
|
||||||
setting_version = 1
|
setting_version = 2
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
infill_line_width = 0.9
|
infill_line_width = 0.9
|
||||||
|
@ -35,7 +35,7 @@ speed_print = 50
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = =round(speed_print / 5 * 4)
|
speed_layer_0 = =round(speed_print / 5 * 4)
|
||||||
speed_wall = =round(speed_print / 2)
|
speed_wall = =round(speed_print / 2)
|
||||||
speed_wall_0 = =10 if speed_wall < 11 else (speed_print / 5 *3)
|
speed_wall_0 = =10 if speed_wall < 11 else 15
|
||||||
speed_topbottom = =round(speed_print / 5 * 4)
|
speed_topbottom = =round(speed_print / 5 * 4)
|
||||||
speed_travel = =round(speed_print if magic_spiralize else 150)
|
speed_travel = =round(speed_print if magic_spiralize else 150)
|
||||||
speed_travel_layer_0 = =speed_travel
|
speed_travel_layer_0 = =speed_travel
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue