Merge branch 'master' into feature_intent

Conflicts:
	plugins/VersionUpgrade/VersionUpgrade41to42/VersionUpgrade41to42.py -> There is a new version upgrade in master, so the old one is sort of obsolete. We may have to move this part to a new version upgrade for 4.3.
	plugins/VersionUpgrade/VersionUpgrade41to42/__init__.py
This commit is contained in:
Ghostkeeper 2019-06-19 13:10:36 +02:00
commit 5ab1881a21
No known key found for this signature in database
GPG key ID: 86BEF881AE2CF276
811 changed files with 1746 additions and 1169 deletions

View file

@ -21,7 +21,7 @@ To upload a project, try changing the extension to e.g. .curaproject.3mf.zip so
Thank you for using Cura! Thank you for using Cura!
--> -->
**Application Version** **Application version**
<!-- The version of the application this issue occurs with --> <!-- The version of the application this issue occurs with -->
**Platform** **Platform**
@ -30,11 +30,14 @@ Thank you for using Cura!
**Printer** **Printer**
<!-- Which printer was selected in Cura? If possible, please attach project file as .curaproject.3mf.zip --> <!-- Which printer was selected in Cura? If possible, please attach project file as .curaproject.3mf.zip -->
**Actual Results** **Reproduction steps**
<!-- How did you encounter the bug? -->
**Actual results**
<!-- What happens after the above steps have been followed --> <!-- What happens after the above steps have been followed -->
**Expected results** **Expected results**
<!-- What should happen after the above steps have been followed --> <!-- What should happen after the above steps have been followed -->
**Additional Information** **Additional information**
<!-- Extra information relevant to the issue, like screenshots --> <!-- Extra information relevant to the issue, like screenshots -->

View file

@ -1,6 +1,6 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from UM.Mesh.MeshData import MeshData
from cura.Scene.CuraSceneNode import CuraSceneNode from cura.Scene.CuraSceneNode import CuraSceneNode
from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderManager import ExtruderManager
from UM.Application import Application #To modify the maximum zoom level. from UM.Application import Application #To modify the maximum zoom level.
@ -20,13 +20,20 @@ from UM.Signal import Signal
from PyQt5.QtCore import QTimer from PyQt5.QtCore import QTimer
from UM.View.RenderBatch import RenderBatch from UM.View.RenderBatch import RenderBatch
from UM.View.GL.OpenGL import OpenGL from UM.View.GL.OpenGL import OpenGL
from cura.Settings.GlobalStack import GlobalStack
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
import numpy import numpy
import math import math
import copy import copy
from typing import List, Optional from typing import List, Optional, TYPE_CHECKING, Any, Set, cast, Iterable, Dict
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
from cura.Settings.ExtruderStack import ExtruderStack
from UM.Settings.ContainerStack import ContainerStack
# Radius of disallowed area in mm around prime. I.e. how much distance to keep from prime position. # Radius of disallowed area in mm around prime. I.e. how much distance to keep from prime position.
PRIME_CLEARANCE = 6.5 PRIME_CLEARANCE = 6.5
@ -36,45 +43,46 @@ PRIME_CLEARANCE = 6.5
class BuildVolume(SceneNode): class BuildVolume(SceneNode):
raftThicknessChanged = Signal() raftThicknessChanged = Signal()
def __init__(self, application, parent = None): def __init__(self, application: "CuraApplication", parent: Optional[SceneNode] = None) -> None:
super().__init__(parent) super().__init__(parent)
self._application = application self._application = application
self._machine_manager = self._application.getMachineManager() self._machine_manager = self._application.getMachineManager()
self._volume_outline_color = None self._volume_outline_color = None # type: Optional[Color]
self._x_axis_color = None self._x_axis_color = None # type: Optional[Color]
self._y_axis_color = None self._y_axis_color = None # type: Optional[Color]
self._z_axis_color = None self._z_axis_color = None # type: Optional[Color]
self._disallowed_area_color = None self._disallowed_area_color = None # type: Optional[Color]
self._error_area_color = None self._error_area_color = None # type: Optional[Color]
self._width = 0 #type: float self._width = 0 # type: float
self._height = 0 #type: float self._height = 0 # type: float
self._depth = 0 #type: float self._depth = 0 # type: float
self._shape = "" #type: str self._shape = "" # type: str
self._shader = None self._shader = None
self._origin_mesh = None self._origin_mesh = None # type: Optional[MeshData]
self._origin_line_length = 20 self._origin_line_length = 20
self._origin_line_width = 0.5 self._origin_line_width = 0.5
self._grid_mesh = None self._grid_mesh = None # type: Optional[MeshData]
self._grid_shader = None self._grid_shader = None
self._disallowed_areas = [] self._disallowed_areas = [] # type: List[Polygon]
self._disallowed_areas_no_brim = [] self._disallowed_areas_no_brim = [] # type: List[Polygon]
self._disallowed_area_mesh = None self._disallowed_area_mesh = None # type: Optional[MeshData]
self._disallowed_area_size = 0.
self._error_areas = [] self._error_areas = [] # type: List[Polygon]
self._error_mesh = None self._error_mesh = None # type: Optional[MeshData]
self.setCalculateBoundingBox(False) self.setCalculateBoundingBox(False)
self._volume_aabb = None self._volume_aabb = None # type: Optional[AxisAlignedBox]
self._raft_thickness = 0.0 self._raft_thickness = 0.0
self._extra_z_clearance = 0.0 self._extra_z_clearance = 0.0
self._adhesion_type = None self._adhesion_type = None # type: Any
self._platform = Platform(self) self._platform = Platform(self)
self._build_volume_message = Message(catalog.i18nc("@info:status", self._build_volume_message = Message(catalog.i18nc("@info:status",
@ -82,7 +90,7 @@ class BuildVolume(SceneNode):
" \"Print Sequence\" setting to prevent the gantry from colliding" " \"Print Sequence\" setting to prevent the gantry from colliding"
" with printed models."), title = catalog.i18nc("@info:title", "Build Volume")) " with printed models."), title = catalog.i18nc("@info:title", "Build Volume"))
self._global_container_stack = None self._global_container_stack = None # type: Optional[GlobalStack]
self._stack_change_timer = QTimer() self._stack_change_timer = QTimer()
self._stack_change_timer.setInterval(100) self._stack_change_timer.setInterval(100)
@ -100,7 +108,7 @@ class BuildVolume(SceneNode):
self._application.getController().getScene().sceneChanged.connect(self._onSceneChanged) self._application.getController().getScene().sceneChanged.connect(self._onSceneChanged)
#Objects loaded at the moment. We are connected to the property changed events of these objects. #Objects loaded at the moment. We are connected to the property changed events of these objects.
self._scene_objects = set() self._scene_objects = set() # type: Set[SceneNode]
self._scene_change_timer = QTimer() self._scene_change_timer = QTimer()
self._scene_change_timer.setInterval(100) self._scene_change_timer.setInterval(100)
@ -124,8 +132,8 @@ class BuildVolume(SceneNode):
# Enable and disable extruder # Enable and disable extruder
self._machine_manager.extruderChanged.connect(self.updateNodeBoundaryCheck) self._machine_manager.extruderChanged.connect(self.updateNodeBoundaryCheck)
# list of settings which were updated # List of settings which were updated
self._changed_settings_since_last_rebuild = [] self._changed_settings_since_last_rebuild = [] # type: List[str]
def _onSceneChanged(self, source): def _onSceneChanged(self, source):
if self._global_container_stack: if self._global_container_stack:
@ -219,9 +227,12 @@ class BuildVolume(SceneNode):
## For every sliceable node, update node._outside_buildarea ## For every sliceable node, update node._outside_buildarea
# #
def updateNodeBoundaryCheck(self): def updateNodeBoundaryCheck(self):
if not self._global_container_stack:
return
root = self._application.getController().getScene().getRoot() root = self._application.getController().getScene().getRoot()
nodes = list(BreadthFirstIterator(root)) nodes = cast(List[SceneNode], list(cast(Iterable, BreadthFirstIterator(root))))
group_nodes = [] group_nodes = [] # type: List[SceneNode]
build_volume_bounding_box = self.getBoundingBox() build_volume_bounding_box = self.getBoundingBox()
if build_volume_bounding_box: if build_volume_bounding_box:
@ -240,6 +251,9 @@ class BuildVolume(SceneNode):
group_nodes.append(node) # Keep list of affected group_nodes group_nodes.append(node) # Keep list of affected group_nodes
if node.callDecoration("isSliceable") or node.callDecoration("isGroup"): if node.callDecoration("isSliceable") or node.callDecoration("isGroup"):
if not isinstance(node, CuraSceneNode):
continue
if node.collidesWithBbox(build_volume_bounding_box): if node.collidesWithBbox(build_volume_bounding_box):
node.setOutsideBuildArea(True) node.setOutsideBuildArea(True)
continue continue
@ -277,8 +291,8 @@ class BuildVolume(SceneNode):
child_node.setOutsideBuildArea(group_node.isOutsideBuildArea()) child_node.setOutsideBuildArea(group_node.isOutsideBuildArea())
## Update the outsideBuildArea of a single node, given bounds or current build volume ## Update the outsideBuildArea of a single node, given bounds or current build volume
def checkBoundsAndUpdate(self, node: CuraSceneNode, bounds: Optional[AxisAlignedBox] = None): def checkBoundsAndUpdate(self, node: CuraSceneNode, bounds: Optional[AxisAlignedBox] = None) -> None:
if not isinstance(node, CuraSceneNode): if not isinstance(node, CuraSceneNode) or self._global_container_stack is None:
return return
if bounds is None: if bounds is None:
@ -310,7 +324,7 @@ class BuildVolume(SceneNode):
node.setOutsideBuildArea(False) node.setOutsideBuildArea(False)
def _buildGridMesh(self, min_w, max_w, min_h, max_h, min_d, max_d, z_fight_distance): def _buildGridMesh(self, min_w: float, max_w: float, min_h: float, max_h: float, min_d: float, max_d:float, z_fight_distance: float) -> MeshData:
mb = MeshBuilder() mb = MeshBuilder()
if self._shape != "elliptic": if self._shape != "elliptic":
# Build plate grid mesh # Build plate grid mesh
@ -346,7 +360,7 @@ class BuildVolume(SceneNode):
mb.setVertexUVCoordinates(n, v[0], v[2] * aspect) mb.setVertexUVCoordinates(n, v[0], v[2] * aspect)
return mb.build().getTransformed(scale_matrix) return mb.build().getTransformed(scale_matrix)
def _buildMesh(self, min_w, max_w, min_h, max_h, min_d, max_d, z_fight_distance): def _buildMesh(self, min_w: float, max_w: float, min_h: float, max_h: float, min_d: float, max_d:float, z_fight_distance: float) -> MeshData:
if self._shape != "elliptic": if self._shape != "elliptic":
# Outline 'cube' of the build volume # Outline 'cube' of the build volume
mb = MeshBuilder() mb = MeshBuilder()
@ -379,7 +393,7 @@ class BuildVolume(SceneNode):
mb.addArc(max_w, Vector.Unit_Y, center = (0, max_h, 0), color = self._volume_outline_color) mb.addArc(max_w, Vector.Unit_Y, center = (0, max_h, 0), color = self._volume_outline_color)
return mb.build().getTransformed(scale_matrix) return mb.build().getTransformed(scale_matrix)
def _buildOriginMesh(self, origin): def _buildOriginMesh(self, origin: Vector) -> MeshData:
mb = MeshBuilder() mb = MeshBuilder()
mb.addCube( mb.addCube(
width=self._origin_line_length, width=self._origin_line_length,
@ -404,16 +418,10 @@ class BuildVolume(SceneNode):
) )
return mb.build() return mb.build()
## Recalculates the build volume & disallowed areas. def _updateColors(self):
def rebuild(self):
if not self._width or not self._height or not self._depth:
return
if not self._engine_ready:
return
if not self._volume_outline_color:
theme = self._application.getTheme() theme = self._application.getTheme()
if theme is None:
return
self._volume_outline_color = Color(*theme.getColor("volume_outline").getRgb()) self._volume_outline_color = Color(*theme.getColor("volume_outline").getRgb())
self._x_axis_color = Color(*theme.getColor("x_axis").getRgb()) self._x_axis_color = Color(*theme.getColor("x_axis").getRgb())
self._y_axis_color = Color(*theme.getColor("y_axis").getRgb()) self._y_axis_color = Color(*theme.getColor("y_axis").getRgb())
@ -421,6 +429,70 @@ class BuildVolume(SceneNode):
self._disallowed_area_color = Color(*theme.getColor("disallowed_area").getRgb()) self._disallowed_area_color = Color(*theme.getColor("disallowed_area").getRgb())
self._error_area_color = Color(*theme.getColor("error_area").getRgb()) self._error_area_color = Color(*theme.getColor("error_area").getRgb())
def _buildErrorMesh(self, min_w: float, max_w: float, min_h: float, max_h: float, min_d: float, max_d: float, disallowed_area_height: float) -> Optional[MeshData]:
if not self._error_areas:
return None
mb = MeshBuilder()
for error_area in self._error_areas:
color = self._error_area_color
points = error_area.getPoints()
first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
self._clamp(points[0][1], min_d, max_d))
previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
self._clamp(points[0][1], min_d, max_d))
for point in points:
new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height,
self._clamp(point[1], min_d, max_d))
mb.addFace(first, previous_point, new_point, color=color)
previous_point = new_point
return mb.build()
def _buildDisallowedAreaMesh(self, min_w: float, max_w: float, min_h: float, max_h: float, min_d: float, max_d: float, disallowed_area_height: float) -> Optional[MeshData]:
if not self._disallowed_areas:
return None
mb = MeshBuilder()
color = self._disallowed_area_color
for polygon in self._disallowed_areas:
points = polygon.getPoints()
if len(points) == 0:
continue
first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
self._clamp(points[0][1], min_d, max_d))
previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
self._clamp(points[0][1], min_d, max_d))
for point in points:
new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height,
self._clamp(point[1], min_d, max_d))
mb.addFace(first, previous_point, new_point, color=color)
previous_point = new_point
# Find the largest disallowed area to exclude it from the maximum scale bounds.
# This is a very nasty hack. This pretty much only works for UM machines.
# This disallowed area_size needs a -lot- of rework at some point in the future: TODO
if numpy.min(points[:,
1]) >= 0: # This filters out all areas that have points to the left of the centre. This is done to filter the skirt area.
size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1]))
else:
size = 0
self._disallowed_area_size = max(size, self._disallowed_area_size)
return mb.build()
## Recalculates the build volume & disallowed areas.
def rebuild(self) -> None:
if not self._width or not self._height or not self._depth:
return
if not self._engine_ready:
return
if not self._global_container_stack:
return
if not self._volume_outline_color:
self._updateColors()
min_w = -self._width / 2 min_w = -self._width / 2
max_w = self._width / 2 max_w = self._width / 2
min_h = 0.0 min_h = 0.0
@ -442,52 +514,10 @@ class BuildVolume(SceneNode):
self._origin_mesh = self._buildOriginMesh(origin) self._origin_mesh = self._buildOriginMesh(origin)
disallowed_area_height = 0.1 disallowed_area_height = 0.1
disallowed_area_size = 0 self._disallowed_area_size = 0.
if self._disallowed_areas: self._disallowed_area_mesh = self._buildDisallowedAreaMesh(min_w, max_w, min_h, max_h, min_d, max_d, disallowed_area_height)
mb = MeshBuilder()
color = self._disallowed_area_color
for polygon in self._disallowed_areas:
points = polygon.getPoints()
if len(points) == 0:
continue
first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) self._error_mesh = self._buildErrorMesh(min_w, max_w, min_h, max_h, min_d, max_d, disallowed_area_height)
previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d))
for point in points:
new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d))
mb.addFace(first, previous_point, new_point, color = color)
previous_point = new_point
# Find the largest disallowed area to exclude it from the maximum scale bounds.
# This is a very nasty hack. This pretty much only works for UM machines.
# This disallowed area_size needs a -lot- of rework at some point in the future: TODO
if numpy.min(points[:, 1]) >= 0: # This filters out all areas that have points to the left of the centre. This is done to filter the skirt area.
size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1]))
else:
size = 0
disallowed_area_size = max(size, disallowed_area_size)
self._disallowed_area_mesh = mb.build()
else:
self._disallowed_area_mesh = None
if self._error_areas:
mb = MeshBuilder()
for error_area in self._error_areas:
color = self._error_area_color
points = error_area.getPoints()
first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
self._clamp(points[0][1], min_d, max_d))
previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
self._clamp(points[0][1], min_d, max_d))
for point in points:
new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height,
self._clamp(point[1], min_d, max_d))
mb.addFace(first, previous_point, new_point, color=color)
previous_point = new_point
self._error_mesh = mb.build()
else:
self._error_mesh = None
self._volume_aabb = AxisAlignedBox( self._volume_aabb = AxisAlignedBox(
minimum = Vector(min_w, min_h - 1.0, min_d), minimum = Vector(min_w, min_h - 1.0, min_d),
@ -499,21 +529,24 @@ class BuildVolume(SceneNode):
# This is probably wrong in all other cases. TODO! # This is probably wrong in all other cases. TODO!
# The +1 and -1 is added as there is always a bit of extra room required to work properly. # The +1 and -1 is added as there is always a bit of extra room required to work properly.
scale_to_max_bounds = AxisAlignedBox( scale_to_max_bounds = AxisAlignedBox(
minimum = Vector(min_w + bed_adhesion_size + 1, min_h, min_d + disallowed_area_size - bed_adhesion_size + 1), minimum = Vector(min_w + bed_adhesion_size + 1, min_h, min_d + self._disallowed_area_size - bed_adhesion_size + 1),
maximum = Vector(max_w - bed_adhesion_size - 1, max_h - self._raft_thickness - self._extra_z_clearance, max_d - disallowed_area_size + bed_adhesion_size - 1) maximum = Vector(max_w - bed_adhesion_size - 1, max_h - self._raft_thickness - self._extra_z_clearance, max_d - self._disallowed_area_size + bed_adhesion_size - 1)
) )
self._application.getController().getScene()._maximum_bounds = scale_to_max_bounds self._application.getController().getScene()._maximum_bounds = scale_to_max_bounds # type: ignore
self.updateNodeBoundaryCheck() self.updateNodeBoundaryCheck()
def getBoundingBox(self) -> AxisAlignedBox: def getBoundingBox(self):
return self._volume_aabb return self._volume_aabb
def getRaftThickness(self) -> float: def getRaftThickness(self) -> float:
return self._raft_thickness return self._raft_thickness
def _updateRaftThickness(self): def _updateRaftThickness(self) -> None:
if not self._global_container_stack:
return
old_raft_thickness = self._raft_thickness old_raft_thickness = self._raft_thickness
if self._global_container_stack.extruders: if self._global_container_stack.extruders:
# This might be called before the extruder stacks have initialised, in which case getting the adhesion_type fails # This might be called before the extruder stacks have initialised, in which case getting the adhesion_type fails
@ -533,28 +566,23 @@ class BuildVolume(SceneNode):
self.setPosition(Vector(0, -self._raft_thickness, 0), SceneNode.TransformSpace.World) self.setPosition(Vector(0, -self._raft_thickness, 0), SceneNode.TransformSpace.World)
self.raftThicknessChanged.emit() self.raftThicknessChanged.emit()
def _updateExtraZClearance(self) -> None: def _calculateExtraZClearance(self, extruders: List["ContainerStack"]) -> float:
if not self._global_container_stack:
return 0
extra_z = 0.0 extra_z = 0.0
extruders = ExtruderManager.getInstance().getUsedExtruderStacks()
use_extruders = False
for extruder in extruders: for extruder in extruders:
if extruder.getProperty("retraction_hop_enabled", "value"): if extruder.getProperty("retraction_hop_enabled", "value"):
retraction_hop = extruder.getProperty("retraction_hop", "value") retraction_hop = extruder.getProperty("retraction_hop", "value")
if extra_z is None or retraction_hop > extra_z: if extra_z is None or retraction_hop > extra_z:
extra_z = retraction_hop extra_z = retraction_hop
use_extruders = True return extra_z
if not use_extruders:
# If no extruders, take global value.
if self._global_container_stack.getProperty("retraction_hop_enabled", "value"):
extra_z = self._global_container_stack.getProperty("retraction_hop", "value")
if extra_z != self._extra_z_clearance:
self._extra_z_clearance = extra_z
def _onStackChanged(self): def _onStackChanged(self):
self._stack_change_timer.start() self._stack_change_timer.start()
## Update the build volume visualization ## Update the build volume visualization
def _onStackChangeTimerFinished(self): def _onStackChangeTimerFinished(self) -> None:
if self._global_container_stack: if self._global_container_stack:
self._global_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged) self._global_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged)
extruders = ExtruderManager.getInstance().getActiveExtruderStacks() extruders = ExtruderManager.getInstance().getActiveExtruderStacks()
@ -585,7 +613,7 @@ class BuildVolume(SceneNode):
self._updateDisallowedAreas() self._updateDisallowedAreas()
self._updateRaftThickness() self._updateRaftThickness()
self._updateExtraZClearance() self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks())
if self._engine_ready: if self._engine_ready:
self.rebuild() self.rebuild()
@ -594,20 +622,23 @@ class BuildVolume(SceneNode):
if camera: if camera:
diagonal = self.getDiagonalSize() diagonal = self.getDiagonalSize()
if diagonal > 1: if diagonal > 1:
camera.setZoomRange(min = 0.1, max = diagonal * 5) #You can zoom out up to 5 times the diagonal. This gives some space around the volume. # You can zoom out up to 5 times the diagonal. This gives some space around the volume.
camera.setZoomRange(min = 0.1, max = diagonal * 5) # type: ignore
def _onEngineCreated(self): def _onEngineCreated(self) -> None:
self._engine_ready = True self._engine_ready = True
self.rebuild() self.rebuild()
def _onSettingChangeTimerFinished(self): def _onSettingChangeTimerFinished(self) -> None:
if not self._global_container_stack:
return
rebuild_me = False rebuild_me = False
update_disallowed_areas = False update_disallowed_areas = False
update_raft_thickness = False update_raft_thickness = False
update_extra_z_clearance = True update_extra_z_clearance = True
for setting_key in self._changed_settings_since_last_rebuild: for setting_key in self._changed_settings_since_last_rebuild:
if setting_key == "print_sequence": if setting_key == "print_sequence":
machine_height = self._global_container_stack.getProperty("machine_height", "value") machine_height = self._global_container_stack.getProperty("machine_height", "value")
if self._application.getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time" and len(self._scene_objects) > 1: if self._application.getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time" and len(self._scene_objects) > 1:
@ -620,33 +651,26 @@ class BuildVolume(SceneNode):
self._height = self._global_container_stack.getProperty("machine_height", "value") self._height = self._global_container_stack.getProperty("machine_height", "value")
self._build_volume_message.hide() self._build_volume_message.hide()
update_disallowed_areas = True update_disallowed_areas = True
rebuild_me = True
# sometimes the machine size or shape settings are adjusted on the active machine, we should reflect this # sometimes the machine size or shape settings are adjusted on the active machine, we should reflect this
if setting_key in self._machine_settings: if setting_key in self._machine_settings:
self._height = self._global_container_stack.getProperty("machine_height", "value") self._updateMachineSizeProperties()
self._width = self._global_container_stack.getProperty("machine_width", "value")
self._depth = self._global_container_stack.getProperty("machine_depth", "value")
self._shape = self._global_container_stack.getProperty("machine_shape", "value")
update_extra_z_clearance = True update_extra_z_clearance = True
update_disallowed_areas = True update_disallowed_areas = True
rebuild_me = True
if setting_key in self._skirt_settings + self._prime_settings + self._tower_settings + self._ooze_shield_settings + self._distance_settings + self._extruder_settings: if setting_key in self._disallowed_area_settings:
update_disallowed_areas = True update_disallowed_areas = True
rebuild_me = True
if setting_key in self._raft_settings: if setting_key in self._raft_settings:
update_raft_thickness = True update_raft_thickness = True
rebuild_me = True
if setting_key in self._extra_z_settings: if setting_key in self._extra_z_settings:
update_extra_z_clearance = True update_extra_z_clearance = True
rebuild_me = True
if setting_key in self._limit_to_extruder_settings: if setting_key in self._limit_to_extruder_settings:
update_disallowed_areas = True update_disallowed_areas = True
rebuild_me = True
rebuild_me = update_extra_z_clearance or update_disallowed_areas or update_raft_thickness
# We only want to update all of them once. # We only want to update all of them once.
if update_disallowed_areas: if update_disallowed_areas:
@ -656,7 +680,7 @@ class BuildVolume(SceneNode):
self._updateRaftThickness() self._updateRaftThickness()
if update_extra_z_clearance: if update_extra_z_clearance:
self._updateExtraZClearance() self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks())
if rebuild_me: if rebuild_me:
self.rebuild() self.rebuild()
@ -664,7 +688,7 @@ class BuildVolume(SceneNode):
# We just did a rebuild, reset the list. # We just did a rebuild, reset the list.
self._changed_settings_since_last_rebuild = [] self._changed_settings_since_last_rebuild = []
def _onSettingPropertyChanged(self, setting_key: str, property_name: str): def _onSettingPropertyChanged(self, setting_key: str, property_name: str) -> None:
if property_name != "value": if property_name != "value":
return return
@ -675,6 +699,14 @@ class BuildVolume(SceneNode):
def hasErrors(self) -> bool: def hasErrors(self) -> bool:
return self._has_errors return self._has_errors
def _updateMachineSizeProperties(self) -> None:
if not self._global_container_stack:
return
self._height = self._global_container_stack.getProperty("machine_height", "value")
self._width = self._global_container_stack.getProperty("machine_width", "value")
self._depth = self._global_container_stack.getProperty("machine_depth", "value")
self._shape = self._global_container_stack.getProperty("machine_shape", "value")
## Calls _updateDisallowedAreas and makes sure the changes appear in the ## Calls _updateDisallowedAreas and makes sure the changes appear in the
# scene. # scene.
# #
@ -686,10 +718,10 @@ class BuildVolume(SceneNode):
def _updateDisallowedAreasAndRebuild(self): def _updateDisallowedAreasAndRebuild(self):
self._updateDisallowedAreas() self._updateDisallowedAreas()
self._updateRaftThickness() self._updateRaftThickness()
self._updateExtraZClearance() self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks())
self.rebuild() self.rebuild()
def _updateDisallowedAreas(self): def _updateDisallowedAreas(self) -> None:
if not self._global_container_stack: if not self._global_container_stack:
return return
@ -815,17 +847,10 @@ class BuildVolume(SceneNode):
prime_tower_x -= brim_size prime_tower_x -= brim_size
prime_tower_y += brim_size prime_tower_y += brim_size
if self._global_container_stack.getProperty("prime_tower_circular", "value"):
radius = prime_tower_size / 2 radius = prime_tower_size / 2
prime_tower_area = Polygon.approximatedCircle(radius) prime_tower_area = Polygon.approximatedCircle(radius)
prime_tower_area = prime_tower_area.translate(prime_tower_x - radius, prime_tower_y - radius) prime_tower_area = prime_tower_area.translate(prime_tower_x - radius, prime_tower_y - radius)
else:
prime_tower_area = Polygon([
[prime_tower_x - prime_tower_size, prime_tower_y - prime_tower_size],
[prime_tower_x, prime_tower_y - prime_tower_size],
[prime_tower_x, prime_tower_y],
[prime_tower_x - prime_tower_size, prime_tower_y],
])
prime_tower_area = prime_tower_area.getMinkowskiHull(Polygon.approximatedCircle(0)) prime_tower_area = prime_tower_area.getMinkowskiHull(Polygon.approximatedCircle(0))
for extruder in used_extruders: for extruder in used_extruders:
result[extruder.getId()].append(prime_tower_area) #The prime tower location is the same for each extruder, regardless of offset. result[extruder.getId()].append(prime_tower_area) #The prime tower location is the same for each extruder, regardless of offset.
@ -843,9 +868,10 @@ class BuildVolume(SceneNode):
# \param used_extruders The extruder stacks to generate disallowed areas # \param used_extruders The extruder stacks to generate disallowed areas
# for. # for.
# \return A dictionary with for each used extruder ID the prime areas. # \return A dictionary with for each used extruder ID the prime areas.
def _computeDisallowedAreasPrimeBlob(self, border_size, used_extruders): def _computeDisallowedAreasPrimeBlob(self, border_size: float, used_extruders: List["ExtruderStack"]) -> Dict[str, List[Polygon]]:
result = {} result = {} # type: Dict[str, List[Polygon]]
if not self._global_container_stack:
return result
machine_width = self._global_container_stack.getProperty("machine_width", "value") machine_width = self._global_container_stack.getProperty("machine_width", "value")
machine_depth = self._global_container_stack.getProperty("machine_depth", "value") machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
for extruder in used_extruders: for extruder in used_extruders:
@ -853,13 +879,13 @@ class BuildVolume(SceneNode):
prime_x = extruder.getProperty("extruder_prime_pos_x", "value") prime_x = extruder.getProperty("extruder_prime_pos_x", "value")
prime_y = -extruder.getProperty("extruder_prime_pos_y", "value") prime_y = -extruder.getProperty("extruder_prime_pos_y", "value")
#Ignore extruder prime position if it is not set or if blob is disabled # Ignore extruder prime position if it is not set or if blob is disabled
if (prime_x == 0 and prime_y == 0) or not prime_blob_enabled: if (prime_x == 0 and prime_y == 0) or not prime_blob_enabled:
result[extruder.getId()] = [] result[extruder.getId()] = []
continue continue
if not self._global_container_stack.getProperty("machine_center_is_zero", "value"): if not self._global_container_stack.getProperty("machine_center_is_zero", "value"):
prime_x = prime_x - machine_width / 2 #Offset by half machine_width and _depth to put the origin in the front-left. prime_x = prime_x - machine_width / 2 # Offset by half machine_width and _depth to put the origin in the front-left.
prime_y = prime_y + machine_depth / 2 prime_y = prime_y + machine_depth / 2
prime_polygon = Polygon.approximatedCircle(PRIME_CLEARANCE) prime_polygon = Polygon.approximatedCircle(PRIME_CLEARANCE)
@ -1015,14 +1041,86 @@ class BuildVolume(SceneNode):
# stack. # stack.
# #
# \return A sequence of setting values, one for each extruder. # \return A sequence of setting values, one for each extruder.
def _getSettingFromAllExtruders(self, setting_key): def _getSettingFromAllExtruders(self, setting_key: str) -> List[Any]:
all_values = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "value") all_values = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "value")
all_types = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "type") all_types = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "type")
for i in range(len(all_values)): for i, (setting_value, setting_type) in enumerate(zip(all_values, all_types)):
if not all_values[i] and (all_types[i] == "int" or all_types[i] == "float"): if not setting_value and (setting_type == "int" or setting_type == "float"):
all_values[i] = 0 all_values[i] = 0
return all_values return all_values
def _calculateBedAdhesionSize(self, used_extruders):
if self._global_container_stack is None:
return
container_stack = self._global_container_stack
adhesion_type = container_stack.getProperty("adhesion_type", "value")
skirt_brim_line_width = self._global_container_stack.getProperty("skirt_brim_line_width", "value")
initial_layer_line_width_factor = self._global_container_stack.getProperty("initial_layer_line_width_factor", "value")
# Use brim width if brim is enabled OR the prime tower has a brim.
if adhesion_type == "brim" or (self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and adhesion_type != "raft"):
brim_line_count = self._global_container_stack.getProperty("brim_line_count", "value")
bed_adhesion_size = skirt_brim_line_width * brim_line_count * initial_layer_line_width_factor / 100.0
for extruder_stack in used_extruders:
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
# We don't create an additional line for the extruder we're printing the brim with.
bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0
elif adhesion_type == "skirt": # No brim? Also not on prime tower? Then use whatever the adhesion type is saying: Skirt, raft or none.
skirt_distance = self._global_container_stack.getProperty("skirt_gap", "value")
skirt_line_count = self._global_container_stack.getProperty("skirt_line_count", "value")
bed_adhesion_size = skirt_distance + (
skirt_brim_line_width * skirt_line_count) * initial_layer_line_width_factor / 100.0
for extruder_stack in used_extruders:
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
# We don't create an additional line for the extruder we're printing the skirt with.
bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0
elif adhesion_type == "raft":
bed_adhesion_size = self._global_container_stack.getProperty("raft_margin", "value")
elif adhesion_type == "none":
bed_adhesion_size = 0
else:
raise Exception("Unknown bed adhesion type. Did you forget to update the build volume calculations for your new bed adhesion type?")
max_length_available = 0.5 * min(
self._global_container_stack.getProperty("machine_width", "value"),
self._global_container_stack.getProperty("machine_depth", "value")
)
bed_adhesion_size = min(bed_adhesion_size, max_length_available)
return bed_adhesion_size
def _calculateFarthestShieldDistance(self, container_stack):
farthest_shield_distance = 0
if container_stack.getProperty("draft_shield_enabled", "value"):
farthest_shield_distance = max(farthest_shield_distance, container_stack.getProperty("draft_shield_dist", "value"))
if container_stack.getProperty("ooze_shield_enabled", "value"):
farthest_shield_distance = max(farthest_shield_distance,container_stack.getProperty("ooze_shield_dist", "value"))
return farthest_shield_distance
def _calculateSupportExpansion(self, container_stack):
support_expansion = 0
support_enabled = self._global_container_stack.getProperty("support_enable", "value")
support_offset = self._global_container_stack.getProperty("support_offset", "value")
if support_enabled and support_offset:
support_expansion += support_offset
return support_expansion
def _calculateMoveFromWallRadius(self, used_extruders):
move_from_wall_radius = 0 # Moves that start from outer wall.
all_values = [move_from_wall_radius]
all_values.extend(self._getSettingFromAllExtruders("infill_wipe_dist"))
move_from_wall_radius = max(all_values)
avoid_enabled_per_extruder = [stack.getProperty("travel_avoid_other_parts", "value") for stack in used_extruders]
travel_avoid_distance_per_extruder = [stack.getProperty("travel_avoid_distance", "value") for stack in used_extruders]
for avoid_other_parts_enabled, avoid_distance in zip(avoid_enabled_per_extruder, travel_avoid_distance_per_extruder): # For each extruder (or just global).
if avoid_other_parts_enabled:
move_from_wall_radius = max(move_from_wall_radius, avoid_distance)
return move_from_wall_radius
## Calculate the disallowed radius around the edge. ## Calculate the disallowed radius around the edge.
# #
# This disallowed radius is to allow for space around the models that is # This disallowed radius is to allow for space around the models that is
@ -1039,65 +1137,10 @@ class BuildVolume(SceneNode):
if container_stack.getProperty("print_sequence", "value") == "one_at_a_time": if container_stack.getProperty("print_sequence", "value") == "one_at_a_time":
return 0.1 # Return a very small value, so we do draw disallowed area's near the edges. return 0.1 # Return a very small value, so we do draw disallowed area's near the edges.
adhesion_type = container_stack.getProperty("adhesion_type", "value") bed_adhesion_size = self._calculateBedAdhesionSize(used_extruders)
skirt_brim_line_width = self._global_container_stack.getProperty("skirt_brim_line_width", "value") support_expansion = self._calculateSupportExpansion(self._global_container_stack)
initial_layer_line_width_factor = self._global_container_stack.getProperty("initial_layer_line_width_factor", "value") farthest_shield_distance = self._calculateFarthestShieldDistance(self._global_container_stack)
#Use brim width if brim is enabled OR the prime tower has a brim. move_from_wall_radius = self._calculateMoveFromWallRadius(used_extruders)
if adhesion_type == "brim" or (self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and
adhesion_type != "raft"):
brim_line_count = self._global_container_stack.getProperty("brim_line_count", "value")
bed_adhesion_size = skirt_brim_line_width * brim_line_count * initial_layer_line_width_factor / 100.0
for extruder_stack in used_extruders:
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
# We don't create an additional line for the extruder we're printing the brim with.
bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0
elif adhesion_type == "skirt": #No brim? Also not on prime tower? Then use whatever the adhesion type is saying: Skirt, raft or none.
skirt_distance = self._global_container_stack.getProperty("skirt_gap", "value")
skirt_line_count = self._global_container_stack.getProperty("skirt_line_count", "value")
bed_adhesion_size = skirt_distance + (skirt_brim_line_width * skirt_line_count) * initial_layer_line_width_factor / 100.0
for extruder_stack in used_extruders:
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
# We don't create an additional line for the extruder we're printing the skirt with.
bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0
elif adhesion_type == "raft":
bed_adhesion_size = self._global_container_stack.getProperty("raft_margin", "value")
elif adhesion_type == "none":
bed_adhesion_size = 0
else:
raise Exception("Unknown bed adhesion type. Did you forget to update the build volume calculations for your new bed adhesion type?")
max_length_available = 0.5 * min(
self._global_container_stack.getProperty("machine_width", "value"),
self._global_container_stack.getProperty("machine_depth", "value")
)
bed_adhesion_size = min(bed_adhesion_size, max_length_available)
support_expansion = 0
support_enabled = self._global_container_stack.getProperty("support_enable", "value")
support_offset = self._global_container_stack.getProperty("support_offset", "value")
if support_enabled and support_offset:
support_expansion += support_offset
farthest_shield_distance = 0
if container_stack.getProperty("draft_shield_enabled", "value"):
farthest_shield_distance = max(farthest_shield_distance, container_stack.getProperty("draft_shield_dist", "value"))
if container_stack.getProperty("ooze_shield_enabled", "value"):
farthest_shield_distance = max(farthest_shield_distance, container_stack.getProperty("ooze_shield_dist", "value"))
move_from_wall_radius = 0 # Moves that start from outer wall.
move_from_wall_radius = max(move_from_wall_radius, max(self._getSettingFromAllExtruders("infill_wipe_dist")))
avoid_enabled_per_extruder = [stack.getProperty("travel_avoid_other_parts","value") for stack in used_extruders]
travel_avoid_distance_per_extruder = [stack.getProperty("travel_avoid_distance", "value") for stack in used_extruders]
for avoid_other_parts_enabled, avoid_distance in zip(avoid_enabled_per_extruder, travel_avoid_distance_per_extruder): #For each extruder (or just global).
if avoid_other_parts_enabled:
move_from_wall_radius = max(move_from_wall_radius, avoid_distance)
# Now combine our different pieces of data to get the final border size. # Now combine our different pieces of data to get the final border size.
# Support expansion is added to the bed adhesion, since the bed adhesion goes around support. # Support expansion is added to the bed adhesion, since the bed adhesion goes around support.
@ -1113,8 +1156,9 @@ class BuildVolume(SceneNode):
_raft_settings = ["adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap", "layer_0_z_overlap"] _raft_settings = ["adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap", "layer_0_z_overlap"]
_extra_z_settings = ["retraction_hop_enabled", "retraction_hop"] _extra_z_settings = ["retraction_hop_enabled", "retraction_hop"]
_prime_settings = ["extruder_prime_pos_x", "extruder_prime_pos_y", "extruder_prime_pos_z", "prime_blob_enable"] _prime_settings = ["extruder_prime_pos_x", "extruder_prime_pos_y", "extruder_prime_pos_z", "prime_blob_enable"]
_tower_settings = ["prime_tower_enable", "prime_tower_circular", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y", "prime_tower_brim_enable"] _tower_settings = ["prime_tower_enable", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y", "prime_tower_brim_enable"]
_ooze_shield_settings = ["ooze_shield_enabled", "ooze_shield_dist"] _ooze_shield_settings = ["ooze_shield_enabled", "ooze_shield_dist"]
_distance_settings = ["infill_wipe_dist", "travel_avoid_distance", "support_offset", "support_enable", "travel_avoid_other_parts", "travel_avoid_supports"] _distance_settings = ["infill_wipe_dist", "travel_avoid_distance", "support_offset", "support_enable", "travel_avoid_other_parts", "travel_avoid_supports"]
_extruder_settings = ["support_enable", "support_bottom_enable", "support_roof_enable", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_bottom_extruder_nr", "support_roof_extruder_nr", "brim_line_count", "adhesion_extruder_nr", "adhesion_type"] #Settings that can affect which extruders are used. _extruder_settings = ["support_enable", "support_bottom_enable", "support_roof_enable", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_bottom_extruder_nr", "support_roof_extruder_nr", "brim_line_count", "adhesion_extruder_nr", "adhesion_type"] #Settings that can affect which extruders are used.
_limit_to_extruder_settings = ["wall_extruder_nr", "wall_0_extruder_nr", "wall_x_extruder_nr", "top_bottom_extruder_nr", "infill_extruder_nr", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_bottom_extruder_nr", "support_roof_extruder_nr", "adhesion_extruder_nr"] _limit_to_extruder_settings = ["wall_extruder_nr", "wall_0_extruder_nr", "wall_x_extruder_nr", "top_bottom_extruder_nr", "infill_extruder_nr", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_bottom_extruder_nr", "support_roof_extruder_nr", "adhesion_extruder_nr"]
_disallowed_area_settings = _skirt_settings + _prime_settings + _tower_settings + _ooze_shield_settings + _distance_settings + _extruder_settings

View file

@ -145,7 +145,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 = 7 SettingVersion = 8
Created = False Created = False

View file

@ -62,6 +62,14 @@ class DiscoveredPrinter(QObject):
self._machine_type = machine_type self._machine_type = machine_type
self.machineTypeChanged.emit() self.machineTypeChanged.emit()
# Checks if the given machine type name in the available machine list.
# The machine type is a code name such as "ultimaker_3", while the machine type name is the human-readable name of
# the machine type, which is "Ultimaker 3" for "ultimaker_3".
def _hasHumanReadableMachineTypeName(self, machine_type_name: str) -> bool:
from cura.CuraApplication import CuraApplication
results = CuraApplication.getInstance().getContainerRegistry().findDefinitionContainersMetadata(name = machine_type_name)
return len(results) > 0
# Human readable machine type string # Human readable machine type string
@pyqtProperty(str, notify = machineTypeChanged) @pyqtProperty(str, notify = machineTypeChanged)
def readableMachineType(self) -> str: def readableMachineType(self) -> str:
@ -70,24 +78,30 @@ class DiscoveredPrinter(QObject):
# In ClusterUM3OutputDevice, when it updates a printer information, it updates the machine type using the field # In ClusterUM3OutputDevice, when it updates a printer information, it updates the machine type using the field
# "machine_variant", and for some reason, it's not the machine type ID/codename/... but a human-readable string # "machine_variant", and for some reason, it's not the machine type ID/codename/... but a human-readable string
# like "Ultimaker 3". The code below handles this case. # like "Ultimaker 3". The code below handles this case.
if machine_manager.hasHumanReadableMachineTypeName(self._machine_type): if self._hasHumanReadableMachineTypeName(self._machine_type):
readable_type = self._machine_type readable_type = self._machine_type
else: else:
readable_type = machine_manager.getMachineTypeNameFromId(self._machine_type) readable_type = self._getMachineTypeNameFromId(self._machine_type)
if not readable_type: if not readable_type:
readable_type = catalog.i18nc("@label", "Unknown") readable_type = catalog.i18nc("@label", "Unknown")
return readable_type return readable_type
@pyqtProperty(bool, notify = machineTypeChanged) @pyqtProperty(bool, notify = machineTypeChanged)
def isUnknownMachineType(self) -> bool: def isUnknownMachineType(self) -> bool:
from cura.CuraApplication import CuraApplication if self._hasHumanReadableMachineTypeName(self._machine_type):
machine_manager = CuraApplication.getInstance().getMachineManager()
if machine_manager.hasHumanReadableMachineTypeName(self._machine_type):
readable_type = self._machine_type readable_type = self._machine_type
else: else:
readable_type = machine_manager.getMachineTypeNameFromId(self._machine_type) readable_type = self._getMachineTypeNameFromId(self._machine_type)
return not readable_type return not readable_type
def _getMachineTypeNameFromId(self, machine_type_id: str) -> str:
machine_type_name = ""
from cura.CuraApplication import CuraApplication
results = CuraApplication.getInstance().getContainerRegistry().findDefinitionContainersMetadata(id = machine_type_id)
if results:
machine_type_name = results[0]["name"]
return machine_type_name
@pyqtProperty(QObject, constant = True) @pyqtProperty(QObject, constant = True)
def device(self) -> "NetworkedPrinterOutputDevice": def device(self) -> "NetworkedPrinterOutputDevice":
return self._device return self._device

View file

@ -202,9 +202,6 @@ class QualityManager(QObject):
def getQualityGroups(self, machine: "GlobalStack") -> Dict[str, QualityGroup]: def getQualityGroups(self, machine: "GlobalStack") -> Dict[str, QualityGroup]:
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition) machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition)
# This determines if we should only get the global qualities for the global stack and skip the global qualities for the extruder stacks
has_machine_specific_qualities = machine.getHasMachineQuality()
# To find the quality container for the GlobalStack, check in the following fall-back manner: # To find the quality container for the GlobalStack, check in the following fall-back manner:
# (1) the machine-specific node # (1) the machine-specific node
# (2) the generic node # (2) the generic node

View file

@ -1,4 +1,4 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from copy import deepcopy from copy import deepcopy
@ -14,6 +14,7 @@ import cura.CuraApplication #To get the build plate.
from cura.Settings.ExtruderStack import ExtruderStack #For typing. from cura.Settings.ExtruderStack import ExtruderStack #For typing.
from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator #For per-object settings. from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator #For per-object settings.
## Scene nodes that are models are only seen when selecting the corresponding build plate ## Scene nodes that are models are only seen when selecting the corresponding build plate
# Note that many other nodes can just be UM SceneNode objects. # Note that many other nodes can just be UM SceneNode objects.
class CuraSceneNode(SceneNode): class CuraSceneNode(SceneNode):
@ -85,16 +86,6 @@ class CuraSceneNode(SceneNode):
1.0 1.0
] ]
## Return if the provided bbox collides with the bbox of this scene node
def collidesWithBbox(self, check_bbox: AxisAlignedBox) -> bool:
bbox = self.getBoundingBox()
if bbox is not None:
# Mark the node as outside the build volume if the bounding box test fails.
if check_bbox.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection:
return True
return False
## Return if any area collides with the convex hull of this scene node ## Return if any area collides with the convex hull of this scene node
def collidesWithArea(self, areas: List[Polygon]) -> bool: def collidesWithArea(self, areas: List[Polygon]) -> bool:
convex_hull = self.callDecoration("getConvexHull") convex_hull = self.callDecoration("getConvexHull")

View file

@ -283,7 +283,7 @@ class CuraContainerRegistry(ContainerRegistry):
profile.addInstance(new_instance) profile.addInstance(new_instance)
profile.setDirty(True) profile.setDirty(True)
global_profile.removeInstance(qc_setting_key, postpone_emit=True) global_profile.removeInstance(qc_setting_key, postpone_emit = True)
extruder_profiles.append(profile) extruder_profiles.append(profile)
for profile in extruder_profiles: for profile in extruder_profiles:

View file

@ -180,7 +180,7 @@ class ExtruderManager(QObject):
# \param setting_key \type{str} The setting to get the property of. # \param setting_key \type{str} The setting to get the property of.
# \param property \type{str} The property to get. # \param property \type{str} The property to get.
# \return \type{List} the list of results # \return \type{List} the list of results
def getAllExtruderSettings(self, setting_key: str, prop: str) -> List: def getAllExtruderSettings(self, setting_key: str, prop: str) -> List[Any]:
result = [] result = []
for extruder_stack in self.getActiveExtruderStacks(): for extruder_stack in self.getActiveExtruderStacks():

View file

@ -264,18 +264,18 @@ class GlobalStack(CuraContainerStack):
def getHeadAndFansCoordinates(self): def getHeadAndFansCoordinates(self):
return self.getProperty("machine_head_with_fans_polygon", "value") return self.getProperty("machine_head_with_fans_polygon", "value")
def getHasMaterials(self) -> bool: @pyqtProperty(int, constant=True)
def hasMaterials(self):
return parseBool(self.getMetaDataEntry("has_materials", False)) return parseBool(self.getMetaDataEntry("has_materials", False))
def getHasVariants(self) -> bool: @pyqtProperty(int, constant=True)
def hasVariants(self):
return parseBool(self.getMetaDataEntry("has_variants", False)) return parseBool(self.getMetaDataEntry("has_variants", False))
def getHasVariantsBuildPlates(self) -> bool: @pyqtProperty(int, constant=True)
def hasVariantBuildplates(self) -> bool:
return parseBool(self.getMetaDataEntry("has_variant_buildplates", False)) return parseBool(self.getMetaDataEntry("has_variant_buildplates", False))
def getHasMachineQuality(self) -> bool:
return parseBool(self.getMetaDataEntry("has_machine_quality", False))
## Get default firmware file name if one is specified in the firmware ## Get default firmware file name if one is specified in the firmware
@pyqtSlot(result = str) @pyqtSlot(result = str)
def getDefaultFirmwareName(self) -> str: def getDefaultFirmwareName(self) -> str:

View file

@ -538,6 +538,7 @@ class MachineManager(QObject):
return bool(self._printer_output_devices) return bool(self._printer_output_devices)
@pyqtProperty(bool, notify = printerConnectedStatusChanged) @pyqtProperty(bool, notify = printerConnectedStatusChanged)
@deprecated("use Cura.MachineManager.activeMachine.configuredConnectionTypes instead", "4.2")
def activeMachineHasRemoteConnection(self) -> bool: def activeMachineHasRemoteConnection(self) -> bool:
if self._global_container_stack: if self._global_container_stack:
has_remote_connection = False has_remote_connection = False
@ -816,21 +817,24 @@ class MachineManager(QObject):
self.removeMachine(hidden_containers[0].getId()) self.removeMachine(hidden_containers[0].getId())
@pyqtProperty(bool, notify = globalContainerChanged) @pyqtProperty(bool, notify = globalContainerChanged)
@deprecated("use Cura.MachineManager.activeMachine.hasMaterials instead", "4.2")
def hasMaterials(self) -> bool: def hasMaterials(self) -> bool:
if self._global_container_stack: if self._global_container_stack:
return self._global_container_stack.getHasMaterials() return self._global_container_stack.hasMaterials
return False return False
@pyqtProperty(bool, notify = globalContainerChanged) @pyqtProperty(bool, notify = globalContainerChanged)
@deprecated("use Cura.MachineManager.activeMachine.hasVariants instead", "4.2")
def hasVariants(self) -> bool: def hasVariants(self) -> bool:
if self._global_container_stack: if self._global_container_stack:
return self._global_container_stack.getHasVariants() return self._global_container_stack.hasVariants
return False return False
@pyqtProperty(bool, notify = globalContainerChanged) @pyqtProperty(bool, notify = globalContainerChanged)
@deprecated("use Cura.MachineManager.activeMachine.hasVariantBuildplates instead", "4.2")
def hasVariantBuildplates(self) -> bool: def hasVariantBuildplates(self) -> bool:
if self._global_container_stack: if self._global_container_stack:
return self._global_container_stack.getHasVariantsBuildPlates() return self._global_container_stack.hasVariantBuildplates
return False return False
## The selected buildplate is compatible if it is compatible with all the materials in all the extruders ## The selected buildplate is compatible if it is compatible with all the materials in all the extruders
@ -917,9 +921,8 @@ class MachineManager(QObject):
# Apply quality changes that are incompatible to user changes, so we do not change the quality changes itself. # Apply quality changes that are incompatible to user changes, so we do not change the quality changes itself.
self._global_container_stack.userChanges.setProperty(setting_key, "value", self._default_extruder_position) self._global_container_stack.userChanges.setProperty(setting_key, "value", self._default_extruder_position)
if add_user_changes: if add_user_changes:
caution_message = Message(catalog.i18nc( caution_message = Message(
"@info:generic", catalog.i18nc("@info:message Followed by a list of settings.", "Settings have been changed to match the current availability of extruders:") + " [{settings_list}]".format(settings_list = ", ".join(add_user_changes)),
"Settings have been changed to match the current availability of extruders: [%s]" % ", ".join(add_user_changes)),
lifetime = 0, lifetime = 0,
title = catalog.i18nc("@info:title", "Settings updated")) title = catalog.i18nc("@info:title", "Settings updated"))
caution_message.show() caution_message.show()
@ -984,6 +987,7 @@ class MachineManager(QObject):
self.forceUpdateAllSettings() self.forceUpdateAllSettings()
@pyqtSlot(int, result = QObject) @pyqtSlot(int, result = QObject)
@deprecated("use Cura.MachineManager.activeMachine.extruders instead", "4.2")
def getExtruder(self, position: int) -> Optional[ExtruderStack]: def getExtruder(self, position: int) -> Optional[ExtruderStack]:
if self._global_container_stack: if self._global_container_stack:
return self._global_container_stack.extruders.get(str(position)) return self._global_container_stack.extruders.get(str(position))
@ -1097,6 +1101,7 @@ class MachineManager(QObject):
container.removeInstance(setting_name) container.removeInstance(setting_name)
@pyqtProperty("QVariantList", notify = globalContainerChanged) @pyqtProperty("QVariantList", notify = globalContainerChanged)
@deprecated("use Cura.MachineManager.activeMachine.extruders instead", "4.2")
def currentExtruderPositions(self) -> List[str]: def currentExtruderPositions(self) -> List[str]:
if self._global_container_stack is None: if self._global_container_stack is None:
return [] return []
@ -1642,21 +1647,6 @@ class MachineManager(QObject):
return abbr_machine return abbr_machine
# Checks if the given machine type name in the available machine list.
# The machine type is a code name such as "ultimaker_3", while the machine type name is the human-readable name of
# the machine type, which is "Ultimaker 3" for "ultimaker_3".
def hasHumanReadableMachineTypeName(self, machine_type_name: str) -> bool:
results = self._container_registry.findDefinitionContainersMetadata(name = machine_type_name)
return len(results) > 0
@pyqtSlot(str, result = str)
def getMachineTypeNameFromId(self, machine_type_id: str) -> str:
machine_type_name = ""
results = self._container_registry.findDefinitionContainersMetadata(id = machine_type_id)
if results:
machine_type_name = results[0]["name"]
return machine_type_name
# Gets all machines that belong to the given group_id. # Gets all machines that belong to the given group_id.
def getMachinesInGroup(self, group_id: str) -> List["GlobalStack"]: def getMachinesInGroup(self, group_id: str) -> List["GlobalStack"]:
return self._container_registry.findContainerStacks(type = "machine", group_id = group_id) return self._container_registry.findContainerStacks(type = "machine", group_id = group_id)

View file

@ -1,11 +1,14 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import configparser import configparser
from typing import List, Optional, Tuple
from UM.PluginRegistry import PluginRegistry from UM.PluginRegistry import PluginRegistry
from UM.Logger import Logger from UM.Logger import Logger
from UM.Settings.ContainerFormatError import ContainerFormatError from UM.Settings.ContainerFormatError import ContainerFormatError
from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make. from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make.
from cura.CuraApplication import CuraApplication #To get the current setting version.
from cura.ReaderWriters.ProfileReader import ProfileReader from cura.ReaderWriters.ProfileReader import ProfileReader
import zipfile import zipfile
@ -17,23 +20,26 @@ import zipfile
class CuraProfileReader(ProfileReader): class CuraProfileReader(ProfileReader):
## Initialises the cura profile reader. ## Initialises the cura profile reader.
# This does nothing since the only other function is basically stateless. # This does nothing since the only other function is basically stateless.
def __init__(self): def __init__(self) -> None:
super().__init__() super().__init__()
## Reads a cura profile from a file and returns it. ## Reads a cura profile from a file and returns it.
# #
# \param file_name The file to read the cura profile from. # \param file_name The file to read the cura profile from.
# \return The cura profile that was in the file, if any. If the file could # \return The cura profiles that were in the file, if any. If the file
# not be read or didn't contain a valid profile, \code None \endcode is # could not be read or didn't contain a valid profile, ``None`` is
# returned. # returned.
def read(self, file_name): def read(self, file_name: str) -> List[Optional[InstanceContainer]]:
try: try:
with zipfile.ZipFile(file_name, "r") as archive: with zipfile.ZipFile(file_name, "r") as archive:
results = [] results = [] #type: List[Optional[InstanceContainer]]
for profile_id in archive.namelist(): for profile_id in archive.namelist():
with archive.open(profile_id) as f: with archive.open(profile_id) as f:
serialized = f.read() serialized = f.read()
profile = self._loadProfile(serialized.decode("utf-8"), profile_id) upgraded_profiles = self._upgradeProfile(serialized.decode("utf-8"), profile_id) #After upgrading it may split into multiple profiles.
for upgraded_profile in upgraded_profiles:
serialization, new_id = upgraded_profile
profile = self._loadProfile(serialization, new_id)
if profile is not None: if profile is not None:
results.append(profile) results.append(profile)
return results return results
@ -41,15 +47,16 @@ class CuraProfileReader(ProfileReader):
except zipfile.BadZipFile: except zipfile.BadZipFile:
# It must be an older profile from Cura 2.1. # It must be an older profile from Cura 2.1.
with open(file_name, encoding = "utf-8") as fhandle: with open(file_name, encoding = "utf-8") as fhandle:
serialized = fhandle.read() serialized_bytes = fhandle.read()
return [self._loadProfile(serialized, profile_id) for serialized, profile_id in self._upgradeProfile(serialized, file_name)] return [self._loadProfile(serialized, profile_id) for serialized, profile_id in self._upgradeProfile(serialized_bytes, file_name)]
## Convert a profile from an old Cura to this Cura if needed. ## Convert a profile from an old Cura to this Cura if needed.
# #
# \param serialized \type{str} The profile data to convert in the serialized on-disk format. # \param serialized The profile data to convert in the serialized on-disk
# \param profile_id \type{str} The name of the profile. # format.
# \return \type{List[Tuple[str,str]]} List of serialized profile strings and matching profile names. # \param profile_id The name of the profile.
def _upgradeProfile(self, serialized, profile_id): # \return List of serialized profile strings and matching profile names.
def _upgradeProfile(self, serialized: str, profile_id: str) -> List[Tuple[str, str]]:
parser = configparser.ConfigParser(interpolation = None) parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized) parser.read_string(serialized)
@ -61,7 +68,7 @@ class CuraProfileReader(ProfileReader):
return [] return []
version = int(parser["general"]["version"]) version = int(parser["general"]["version"])
if InstanceContainer.Version != version: if InstanceContainer.Version != version or "metadata" not in parser or "setting_version" not in parser["metadata"] or parser["metadata"]["setting_version"] != str(CuraApplication.SettingVersion):
name = parser["general"]["name"] name = parser["general"]["name"]
return self._upgradeProfileVersion(serialized, name, version) return self._upgradeProfileVersion(serialized, name, version)
else: else:
@ -69,10 +76,10 @@ class CuraProfileReader(ProfileReader):
## Load a profile from a serialized string. ## Load a profile from a serialized string.
# #
# \param serialized \type{str} The profile data to read. # \param serialized The profile data to read.
# \param profile_id \type{str} The name of the profile. # \param profile_id The name of the profile.
# \return \type{InstanceContainer|None} # \return The profile that was stored in the string.
def _loadProfile(self, serialized, profile_id): def _loadProfile(self, serialized: str, profile_id: str) -> Optional[InstanceContainer]:
# Create an empty profile. # Create an empty profile.
profile = InstanceContainer(profile_id) profile = InstanceContainer(profile_id)
profile.setMetaDataEntry("type", "quality_changes") profile.setMetaDataEntry("type", "quality_changes")
@ -88,12 +95,12 @@ class CuraProfileReader(ProfileReader):
## Upgrade a serialized profile to the current profile format. ## Upgrade a serialized profile to the current profile format.
# #
# \param serialized \type{str} The profile data to convert. # \param serialized The profile data to convert.
# \param profile_id \type{str} The name of the profile. # \param profile_id The name of the profile.
# \param source_version \type{int} The profile version of 'serialized'. # \param source_version The profile version of 'serialized'.
# \return \type{List[Tuple[str,str]]} List of serialized profile strings and matching profile names. # \return List of serialized profile strings and matching profile names.
def _upgradeProfileVersion(self, serialized, profile_id, source_version): def _upgradeProfileVersion(self, serialized: str, profile_id: str, source_version: int) -> List[Tuple[str, str]]:
converter_plugins = PluginRegistry.getInstance().getAllMetaData(filter={"version_upgrade": {} }, active_only=True) converter_plugins = PluginRegistry.getInstance().getAllMetaData(filter = {"version_upgrade": {} }, active_only = True)
source_format = ("profile", source_version) source_format = ("profile", source_version)
profile_convert_funcs = [plugin["version_upgrade"][source_format][2] for plugin in converter_plugins profile_convert_funcs = [plugin["version_upgrade"][source_format][2] for plugin in converter_plugins

View file

@ -1,14 +1,32 @@
## Upgrades configurations from the state they were in at version 4.1 to the # Copyright (c) 2019 Ultimaker B.V.
# state they should be in at version 4.2. # Cura is released under the terms of the LGPLv3 or higher.
import configparser import configparser
import io import io
from typing import Tuple, List from typing import Dict, List, Tuple
from UM.VersionUpgrade import VersionUpgrade from UM.VersionUpgrade import VersionUpgrade
_renamed_settings = {
"support_minimal_diameter": "support_tower_maximum_supported_diameter"
} #type: Dict[str, str]
_removed_settings = ["prime_tower_circular"] # type: List[str]
## Upgrades configurations from the state they were in at version 4.1 to the
# state they should be in at version 4.2.
class VersionUpgrade41to42(VersionUpgrade): class VersionUpgrade41to42(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 4.1 format.
#
# Since the format may change, this is implemented for the 4.1 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: str) -> int: def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None) parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised) parser.read_string(serialised)
@ -16,17 +34,71 @@ class VersionUpgrade41to42(VersionUpgrade):
setting_version = int(parser.get("metadata", "setting_version", fallback = "0")) setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version return format_version * 1000000 + setting_version
## Upgrades instance containers to have the new version
# number.
#
# This renames the renamed settings in the containers.
def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized)
#Update version number.
parser["metadata"]["setting_version"] = "8"
#Rename settings.
if "values" in parser:
for old_name, new_name in _renamed_settings.items():
if old_name in parser["values"]:
parser["values"][new_name] = parser["values"][old_name]
del parser["values"][old_name]
#Remove settings.
for key in _removed_settings:
if key in parser["values"]:
del parser["values"][key]
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]
## Upgrades Preferences to have the new version number.
#
# This renames the renamed settings in the list of visible settings.
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized)
#Update version number.
parser["metadata"]["setting_version"] = "8"
#Renamed settings.
if "visible_settings" in parser["general"]:
visible_settings = parser["general"]["visible_settings"]
visible_setting_set = set(visible_settings.split(";"))
for old_name, new_name in _renamed_settings.items():
if old_name in visible_setting_set:
visible_setting_set.remove(old_name)
visible_setting_set.add(new_name)
for removed_key in _removed_settings:
if removed_key in visible_setting_set:
visible_setting_set.remove(removed_key)
parser["general"]["visible_settings"] = ";".join(visible_setting_set)
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]
## Upgrades stacks to have the new version number. ## Upgrades stacks to have the new version number.
def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
parser = configparser.ConfigParser(interpolation=None) parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized) parser.read_string(serialized)
#Update version number.
parser["metadata"]["setting_version"] = "8"
parser["general"]["version"] = "5"
# We should only have 6 levels when we start. # We should only have 6 levels when we start.
assert "7" not in parser["containers"] assert "7" not in parser["containers"]
# Update version number.
parser["general"]["version"] = "5"
# We added the intent container in Cura 4.2. This means that all other containers move one step down. # We added the intent container in Cura 4.2. This means that all other containers move one step down.
parser["containers"]["7"] = parser["containers"]["6"] parser["containers"]["7"] = parser["containers"]["6"]
parser["containers"]["6"] = parser["containers"]["5"] parser["containers"]["6"] = parser["containers"]["5"]
@ -37,6 +109,4 @@ class VersionUpgrade41to42(VersionUpgrade):
result = io.StringIO() result = io.StringIO()
parser.write(result) parser.write(result)
return [filename], [result.getvalue()] return [filename], [result.getvalue()]

View file

@ -14,10 +14,19 @@ def getMetaData() -> Dict[str, Any]:
return { return {
"version_upgrade": { "version_upgrade": {
# From To Upgrade function # From To Upgrade function
("machine_stack", 4000007): ("machine_stack", 5000007, upgrade.upgradeStack), ("preferences", 6000007): ("preferences", 6000008, upgrade.upgradePreferences),
("extruder_train", 4000007): ("extruder_train", 5000007, upgrade.upgradeStack) ("machine_stack", 4000007): ("machine_stack", 4000008, upgrade.upgradeStack),
("extruder_train", 4000007): ("extruder_train", 4000008, upgrade.upgradeStack),
("definition_changes", 4000007): ("definition_changes", 4000008, upgrade.upgradeInstanceContainer),
("quality_changes", 4000007): ("quality_changes", 4000008, upgrade.upgradeInstanceContainer),
("quality", 4000007): ("quality", 4000008, upgrade.upgradeInstanceContainer),
("user", 4000007): ("user", 4000008, upgrade.upgradeInstanceContainer),
}, },
"sources": { "sources": {
"preferences": {
"get_version": upgrade.getCfgVersion,
"location": {"."}
},
"machine_stack": { "machine_stack": {
"get_version": upgrade.getCfgVersion, "get_version": upgrade.getCfgVersion,
"location": {"./machine_instances"} "location": {"./machine_instances"}
@ -25,10 +34,30 @@ def getMetaData() -> Dict[str, Any]:
"extruder_train": { "extruder_train": {
"get_version": upgrade.getCfgVersion, "get_version": upgrade.getCfgVersion,
"location": {"./extruders"} "location": {"./extruders"}
},
"definition_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./definition_changes"}
},
"quality_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./quality_changes"}
},
"quality": {
"get_version": upgrade.getCfgVersion,
"location": {"./quality"}
},
"user": {
"get_version": upgrade.getCfgVersion,
"location": {"./user"}
} }
} }
} }
def register(app: "Application") -> Dict[str, Any]: def register(app: "Application") -> Dict[str, Any]:
<<<<<<< HEAD
return {"version_upgrade": upgrade} return {"version_upgrade": upgrade}
=======
return { "version_upgrade": upgrade }
>>>>>>> master

View file

@ -63,9 +63,19 @@ class XmlMaterialProfile(InstanceContainer):
Logger.log("w", "Can't change metadata {key} of material {material_id} because it's read-only.".format(key = key, material_id = self.getId())) Logger.log("w", "Can't change metadata {key} of material {material_id} because it's read-only.".format(key = key, material_id = self.getId()))
return return
# Some metadata such as diameter should also be instantiated to be a setting. Go though all values for the
# "properties" field and apply the new values to SettingInstances as well.
new_setting_values_dict = {}
if key == "properties":
for k, v in value.items():
if k in self.__material_properties_setting_map:
new_setting_values_dict[self.__material_properties_setting_map[k]] = v
# Prevent recursion # Prevent recursion
if not apply_to_all: if not apply_to_all:
super().setMetaDataEntry(key, value) super().setMetaDataEntry(key, value)
for k, v in new_setting_values_dict.items():
self.setProperty(k, "value", v)
return return
# Get the MaterialGroup # Get the MaterialGroup
@ -74,17 +84,23 @@ class XmlMaterialProfile(InstanceContainer):
material_group = material_manager.getMaterialGroup(root_material_id) material_group = material_manager.getMaterialGroup(root_material_id)
if not material_group: #If the profile is not registered in the registry but loose/temporary, it will not have a base file tree. if not material_group: #If the profile is not registered in the registry but loose/temporary, it will not have a base file tree.
super().setMetaDataEntry(key, value) super().setMetaDataEntry(key, value)
for k, v in new_setting_values_dict.items():
self.setProperty(k, "value", v)
return return
# Update the root material container # Update the root material container
root_material_container = material_group.root_material_node.getContainer() root_material_container = material_group.root_material_node.getContainer()
if root_material_container is not None: if root_material_container is not None:
root_material_container.setMetaDataEntry(key, value, apply_to_all = False) root_material_container.setMetaDataEntry(key, value, apply_to_all = False)
for k, v in new_setting_values_dict.items():
root_material_container.setProperty(k, "value", v)
# Update all containers derived from it # Update all containers derived from it
for node in material_group.derived_material_node_list: for node in material_group.derived_material_node_list:
container = node.getContainer() container = node.getContainer()
if container is not None: if container is not None:
container.setMetaDataEntry(key, value, apply_to_all = False) container.setMetaDataEntry(key, value, apply_to_all = False)
for k, v in new_setting_values_dict.items():
container.setProperty(k, "value", v)
## Overridden from InstanceContainer, similar to setMetaDataEntry. ## Overridden from InstanceContainer, similar to setMetaDataEntry.
# without this function the setName would only set the name of the specific nozzle / material / machine combination container # without this function the setName would only set the name of the specific nozzle / material / machine combination container

View file

@ -0,0 +1,121 @@
{
"name": "Erzay3D",
"version": 2,
"inherits": "fdmprinter",
"metadata": {
"visible": true,
"author": "Alexander Kirsanov",
"manufacturer": "Robokinetika",
"category": "Other",
"file_formats": "text/x-gcode",
"machine_extruder_trains":
{
"0": "erzay3d_extruder_0"
}
},
"overrides": {
"machine_start_gcode" : { "default_value": "G28\nG1 Z15.0 F6000\nG92 E0" },
"machine_shape": { "default_value": "elliptic"},
"machine_name": { "default_value": "Erzay3D" },
"machine_depth": { "default_value": 210 },
"machine_width": { "default_value": 210 },
"machine_height": { "default_value": 230 },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_center_is_zero": { "default_value": true },
"machine_extruder_count": { "default_value": 1 },
"machine_nozzle_size": { "default_value": 0.4 },
"material_diameter": { "default_value": 1.75 },
"machine_heated_bed": { "default_value": true },
"material_bed_temp_wait": { "default_value": true },
"material_print_temp_wait": { "default_value": true },
"material_print_temp_prepend": { "default_value": true },
"machine_buildplate_type": { "default_value": "glass" },
"machine_nozzle_head_distance": { "default_value": 2.5 },
"machine_heat_zone_length": { "default_value": 12.5 },
"machine_max_feedrate_x": { "default_value": 200 },
"machine_max_feedrate_y": { "default_value": 200 },
"machine_max_feedrate_z": { "default_value": 200 },
"machine_max_feedrate_e": { "default_value": 50 },
"machine_max_acceleration_x": { "default_value": 3000 },
"machine_max_acceleration_y": { "default_value": 3000 },
"machine_max_acceleration_z": { "default_value": 3000 },
"machine_max_acceleration_e": { "default_value": 3000 },
"machine_acceleration": { "default_value": 1000 },
"machine_max_jerk_xy": { "default_value": 10 },
"machine_max_jerk_z": { "default_value": 10 },
"machine_max_jerk_e": { "default_value": 10 },
"machine_steps_per_mm_x": { "default_value": 1600 },
"machine_steps_per_mm_y": { "default_value": 1600 },
"machine_steps_per_mm_z": { "default_value": 1600 },
"machine_steps_per_mm_e": { "default_value": 174 },
"machine_feeder_wheel_diameter": { "default_value": 12 },
"layer_height": { "default_value": 0.2 },
"layer_height_0": { "default_value": 0.2 },
"ironing_pattern": { "default_value": "concentric" },
"ironing_flow": { "default_value": 7.0 },
"roofing_pattern": { "default_value": "concentric" },
"infill_sparse_density": { "default_value": 20 },
"infill_line_distance": { "default_value": 4 },
"default_material_print_temperature": { "default_value": 220 },
"material_print_temperature": { "default_value": 220 },
"material_print_temperature_layer_0": { "default_value": 220 },
"material_initial_print_temperature": { "default_value": 220 },
"material_final_print_temperature": { "default_value": 220 },
"retraction_amount": { "default_value": 4 },
"speed_print": { "default_value": 40 },
"speed_infill": { "default_value": 60 },
"speed_wall": { "default_value": 20 },
"speed_wall_0": { "default_value": 20 },
"speed_wall_x": { "default_value": 40 },
"speed_roofing": { "default_value": 20 },
"speed_topbottom": { "default_value": 20 },
"speed_support": { "default_value": 40 },
"speed_support_infill": { "default_value": 40 },
"speed_support_interface": { "default_value": 25 },
"speed_support_roof": { "default_value": 25 },
"speed_support_bottom": { "default_value": 25 },
"speed_prime_tower": { "default_value": 40 },
"speed_travel": { "default_value": 100 },
"speed_layer_0": { "default_value": 20 },
"speed_print_layer_0": { "default_value": 20 },
"speed_travel_layer_0": { "default_value": 80 },
"skirt_brim_speed": { "default_value": 20 },
"speed_equalize_flow_enabled": { "default_value": true },
"speed_equalize_flow_max": { "default_value": 100 },
"acceleration_print": { "default_value": 1000 },
"acceleration_infill": { "default_value": 3000 },
"acceleration_wall": { "default_value": 1000 },
"acceleration_wall_0": { "default_value": 1000 },
"acceleration_wall_x": { "default_value": 1000 },
"acceleration_roofing": { "default_value": 1000 },
"acceleration_topbottom": { "default_value": 1000 },
"acceleration_support": { "default_value": 1000 },
"acceleration_support_infill": { "default_value": 1000 },
"acceleration_support_interface": { "default_value": 1000 },
"acceleration_support_roof": { "default_value": 1000 },
"acceleration_support_bottom": { "default_value": 1000 },
"acceleration_prime_tower": { "default_value": 1000 },
"acceleration_travel": { "default_value": 1500 },
"acceleration_layer_0": { "default_value": 1000 },
"acceleration_print_layer_0": { "default_value": 1000 },
"acceleration_travel_layer_0": { "default_value": 1000 },
"acceleration_skirt_brim": { "default_value": 1000 },
"jerk_print": { "default_value": 10 },
"support_angle": { "default_value": 65 },
"support_brim_enable": { "default_value": true },
"adhesion_type": { "default_value": "skirt" },
"brim_outside_only": { "default_value": false },
"meshfix_maximum_resolution": { "default_value": 0.05 }
}
}

View file

@ -6,7 +6,7 @@
"type": "extruder", "type": "extruder",
"author": "Ultimaker", "author": "Ultimaker",
"manufacturer": "Unknown", "manufacturer": "Unknown",
"setting_version": 7, "setting_version": 8,
"visible": false, "visible": false,
"position": "0" "position": "0"
}, },

View file

@ -7,7 +7,7 @@
"author": "Ultimaker", "author": "Ultimaker",
"category": "Other", "category": "Other",
"manufacturer": "Unknown", "manufacturer": "Unknown",
"setting_version": 7, "setting_version": 8,
"file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g",
"visible": false, "visible": false,
"has_materials": true, "has_materials": true,
@ -892,7 +892,7 @@
"maximum_value_warning": "3 * machine_nozzle_size", "maximum_value_warning": "3 * machine_nozzle_size",
"default_value": 0.4, "default_value": 0.4,
"type": "float", "type": "float",
"enabled": "support_enable", "enabled": "(support_enable or support_tree_enable)",
"value": "line_width", "value": "line_width",
"limit_to_extruder": "support_infill_extruder_nr", "limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -908,7 +908,7 @@
"minimum_value_warning": "0.1 + 0.4 * machine_nozzle_size", "minimum_value_warning": "0.1 + 0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size", "maximum_value_warning": "2 * machine_nozzle_size",
"type": "float", "type": "float",
"enabled": "support_enable and support_interface_enable", "enabled": "(support_enable or support_tree_enable) and support_interface_enable",
"limit_to_extruder": "support_interface_extruder_nr", "limit_to_extruder": "support_interface_extruder_nr",
"value": "line_width", "value": "line_width",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -925,7 +925,7 @@
"minimum_value_warning": "0.4 * machine_nozzle_size", "minimum_value_warning": "0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size", "maximum_value_warning": "2 * machine_nozzle_size",
"type": "float", "type": "float",
"enabled": "support_enable and support_roof_enable", "enabled": "(support_enable or support_tree_enable) and support_roof_enable",
"limit_to_extruder": "support_roof_extruder_nr", "limit_to_extruder": "support_roof_extruder_nr",
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_line_width')", "value": "extruderValue(support_roof_extruder_nr, 'support_interface_line_width')",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -941,7 +941,7 @@
"minimum_value_warning": "0.4 * machine_nozzle_size", "minimum_value_warning": "0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size", "maximum_value_warning": "2 * machine_nozzle_size",
"type": "float", "type": "float",
"enabled": "support_enable and support_bottom_enable", "enabled": "(support_enable or support_tree_enable) and support_bottom_enable",
"limit_to_extruder": "support_bottom_extruder_nr", "limit_to_extruder": "support_bottom_extruder_nr",
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_line_width')", "value": "extruderValue(support_bottom_extruder_nr, 'support_interface_line_width')",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -2070,7 +2070,7 @@
"maximum_value_warning": "285", "maximum_value_warning": "285",
"enabled": true, "enabled": true,
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": false
}, },
"material_print_temperature": "material_print_temperature":
{ {
@ -2401,7 +2401,7 @@
"description": "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure.", "description": "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure.",
"type": "bool", "type": "bool",
"default_value": true, "default_value": true,
"enabled": "retraction_enable and support_enable", "enabled": "retraction_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
}, },
@ -2619,7 +2619,7 @@
"maximum_value_warning": "150", "maximum_value_warning": "150",
"default_value": 60, "default_value": 60,
"value": "speed_print", "value": "speed_print",
"enabled": "support_enable", "enabled": "support_enable or support_tree_enable",
"settable_per_mesh": false, "settable_per_mesh": false,
"limit_to_extruder": "support_extruder_nr", "limit_to_extruder": "support_extruder_nr",
"settable_per_extruder": true, "settable_per_extruder": true,
@ -2636,7 +2636,7 @@
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)", "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "150", "maximum_value_warning": "150",
"value": "speed_support", "value": "speed_support",
"enabled": "support_enable", "enabled": "support_enable or support_tree_enable",
"limit_to_extruder": "support_infill_extruder_nr", "limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
@ -2651,7 +2651,7 @@
"minimum_value": "0.1", "minimum_value": "0.1",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)", "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "150", "maximum_value_warning": "150",
"enabled": "support_interface_enable and support_enable", "enabled": "support_interface_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_interface_extruder_nr", "limit_to_extruder": "support_interface_extruder_nr",
"value": "speed_support / 1.5", "value": "speed_support / 1.5",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -2668,7 +2668,7 @@
"minimum_value": "0.1", "minimum_value": "0.1",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)", "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "150", "maximum_value_warning": "150",
"enabled": "support_roof_enable and support_enable", "enabled": "support_roof_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_roof_extruder_nr", "limit_to_extruder": "support_roof_extruder_nr",
"value": "extruderValue(support_roof_extruder_nr, 'speed_support_interface')", "value": "extruderValue(support_roof_extruder_nr, 'speed_support_interface')",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -2684,7 +2684,7 @@
"minimum_value": "0.1", "minimum_value": "0.1",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)", "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "150", "maximum_value_warning": "150",
"enabled": "support_bottom_enable and support_enable", "enabled": "support_bottom_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_bottom_extruder_nr", "limit_to_extruder": "support_bottom_extruder_nr",
"value": "extruderValue(support_bottom_extruder_nr, 'speed_support_interface')", "value": "extruderValue(support_bottom_extruder_nr, 'speed_support_interface')",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -2972,7 +2972,7 @@
"maximum_value_warning": "10000", "maximum_value_warning": "10000",
"default_value": 3000, "default_value": 3000,
"value": "acceleration_print", "value": "acceleration_print",
"enabled": "resolveOrValue('acceleration_enabled') and support_enable", "enabled": "resolveOrValue('acceleration_enabled') and (support_enable or support_tree_enable)",
"settable_per_mesh": false, "settable_per_mesh": false,
"limit_to_extruder": "support_extruder_nr", "limit_to_extruder": "support_extruder_nr",
"settable_per_extruder": true, "settable_per_extruder": true,
@ -2989,7 +2989,7 @@
"minimum_value": "0.1", "minimum_value": "0.1",
"minimum_value_warning": "100", "minimum_value_warning": "100",
"maximum_value_warning": "10000", "maximum_value_warning": "10000",
"enabled": "resolveOrValue('acceleration_enabled') and support_enable", "enabled": "resolveOrValue('acceleration_enabled') and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_infill_extruder_nr", "limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
@ -3005,7 +3005,7 @@
"minimum_value": "0.1", "minimum_value": "0.1",
"minimum_value_warning": "100", "minimum_value_warning": "100",
"maximum_value_warning": "10000", "maximum_value_warning": "10000",
"enabled": "resolveOrValue('acceleration_enabled') and support_interface_enable and support_enable", "enabled": "resolveOrValue('acceleration_enabled') and support_interface_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_interface_extruder_nr", "limit_to_extruder": "support_interface_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true, "settable_per_extruder": true,
@ -3022,7 +3022,7 @@
"minimum_value": "0.1", "minimum_value": "0.1",
"minimum_value_warning": "100", "minimum_value_warning": "100",
"maximum_value_warning": "10000", "maximum_value_warning": "10000",
"enabled": "acceleration_enabled and support_roof_enable and support_enable", "enabled": "acceleration_enabled and support_roof_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_roof_extruder_nr", "limit_to_extruder": "support_roof_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
@ -3038,7 +3038,7 @@
"minimum_value": "0.1", "minimum_value": "0.1",
"minimum_value_warning": "100", "minimum_value_warning": "100",
"maximum_value_warning": "10000", "maximum_value_warning": "10000",
"enabled": "acceleration_enabled and support_bottom_enable and support_enable", "enabled": "acceleration_enabled and support_bottom_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_bottom_extruder_nr", "limit_to_extruder": "support_bottom_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
@ -3257,7 +3257,7 @@
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"value": "jerk_print", "value": "jerk_print",
"enabled": "resolveOrValue('jerk_enabled') and support_enable", "enabled": "resolveOrValue('jerk_enabled') and (support_enable or support_tree_enable)",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true, "settable_per_extruder": true,
"limit_to_extruder": "support_extruder_nr", "limit_to_extruder": "support_extruder_nr",
@ -3273,7 +3273,7 @@
"value": "jerk_support", "value": "jerk_support",
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled') and support_enable", "enabled": "resolveOrValue('jerk_enabled') and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_infill_extruder_nr", "limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
@ -3288,7 +3288,7 @@
"value": "jerk_support", "value": "jerk_support",
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled') and support_interface_enable and support_enable", "enabled": "resolveOrValue('jerk_enabled') and support_interface_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_interface_extruder_nr", "limit_to_extruder": "support_interface_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true, "settable_per_extruder": true,
@ -3304,7 +3304,7 @@
"value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')", "value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')",
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled') and support_roof_enable and support_enable", "enabled": "resolveOrValue('jerk_enabled') and support_roof_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_roof_extruder_nr", "limit_to_extruder": "support_roof_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
@ -3319,7 +3319,7 @@
"value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')", "value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')",
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled') and support_bottom_enable and support_enable", "enabled": "resolveOrValue('jerk_enabled') and support_bottom_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_bottom_extruder_nr", "limit_to_extruder": "support_bottom_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
@ -3970,7 +3970,7 @@
"minimum_value": "-180", "minimum_value": "-180",
"maximum_value": "180", "maximum_value": "180",
"default_value": 0, "default_value": 0,
"enabled": "support_enable and support_pattern != 'concentric' and support_infill_rate > 0", "enabled": "(support_enable or support_tree_enable) and support_pattern != 'concentric' and support_infill_rate > 0",
"limit_to_extruder": "support_infill_extruder_nr", "limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
@ -3995,7 +3995,7 @@
"default_value": 8.0, "default_value": 8.0,
"minimum_value": "0.0", "minimum_value": "0.0",
"maximum_value_warning": "50.0", "maximum_value_warning": "50.0",
"enabled": "support_enable", "enabled": "support_enable or support_tree_enable",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true, "settable_per_extruder": true,
"limit_to_extruder": "support_infill_extruder_nr", "limit_to_extruder": "support_infill_extruder_nr",
@ -4010,7 +4010,7 @@
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "50 / skirt_brim_line_width", "maximum_value_warning": "50 / skirt_brim_line_width",
"value": "math.ceil(support_brim_width / (skirt_brim_line_width * initial_layer_line_width_factor / 100.0))", "value": "math.ceil(support_brim_width / (skirt_brim_line_width * initial_layer_line_width_factor / 100.0))",
"enabled": "support_enable", "enabled": "support_enable or support_tree_enable",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true, "settable_per_extruder": true,
"limit_to_extruder": "support_infill_extruder_nr" "limit_to_extruder": "support_infill_extruder_nr"
@ -4132,7 +4132,7 @@
"support_join_distance": "support_join_distance":
{ {
"label": "Support Join Distance", "label": "Support Join Distance",
"description": "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one.", "description": "The maximum distance between support structures in the X/Y directions. When separate structures are closer together than this value, the structures merge into one.",
"unit": "mm", "unit": "mm",
"type": "float", "type": "float",
"default_value": 2.0, "default_value": 2.0,
@ -4299,7 +4299,7 @@
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "support_interface_height", "maximum_value_warning": "support_interface_height",
"limit_to_extruder": "support_interface_extruder_nr", "limit_to_extruder": "support_interface_extruder_nr",
"enabled": "support_interface_enable and support_enable", "enabled": "support_interface_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": true "settable_per_mesh": true
}, },
"support_interface_density": "support_interface_density":
@ -4457,7 +4457,7 @@
"minimum_value": "0", "minimum_value": "0",
"minimum_value_warning": "minimum_support_area", "minimum_value_warning": "minimum_support_area",
"limit_to_extruder": "support_interface_extruder_nr", "limit_to_extruder": "support_interface_extruder_nr",
"enabled": "support_interface_enable and support_enable", "enabled": "support_interface_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": true, "settable_per_mesh": true,
"children": "children":
{ {
@ -4472,7 +4472,7 @@
"minimum_value": "0", "minimum_value": "0",
"minimum_value_warning": "minimum_support_area", "minimum_value_warning": "minimum_support_area",
"limit_to_extruder": "support_roof_extruder_nr", "limit_to_extruder": "support_roof_extruder_nr",
"enabled": "support_roof_enable and support_enable", "enabled": "support_roof_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": true "settable_per_mesh": true
}, },
"minimum_bottom_area": "minimum_bottom_area":
@ -4486,7 +4486,7 @@
"minimum_value": "0", "minimum_value": "0",
"minimum_value_warning": "minimum_support_area", "minimum_value_warning": "minimum_support_area",
"limit_to_extruder": "support_bottom_extruder_nr", "limit_to_extruder": "support_bottom_extruder_nr",
"enabled": "support_bottom_enable and support_enable", "enabled": "support_bottom_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": true "settable_per_mesh": true
} }
} }
@ -4541,7 +4541,7 @@
"description": "When enabled, the print cooling fan speed is altered for the skin regions immediately above the support.", "description": "When enabled, the print cooling fan speed is altered for the skin regions immediately above the support.",
"type": "bool", "type": "bool",
"default_value": false, "default_value": false,
"enabled": "support_enable", "enabled": "support_enable or support_tree_enable",
"settable_per_mesh": false "settable_per_mesh": false
}, },
"support_supported_skin_fan_speed": "support_supported_skin_fan_speed":
@ -4553,7 +4553,7 @@
"maximum_value": "100", "maximum_value": "100",
"default_value": 100, "default_value": 100,
"type": "float", "type": "float",
"enabled": "support_enable and support_fan_enable", "enabled": "(support_enable or support_tree_enable) and support_fan_enable",
"settable_per_mesh": false "settable_per_mesh": false
}, },
"support_use_towers": "support_use_towers":
@ -4580,10 +4580,10 @@
"enabled": "support_enable and support_use_towers", "enabled": "support_enable and support_use_towers",
"settable_per_mesh": true "settable_per_mesh": true
}, },
"support_minimal_diameter": "support_tower_maximum_supported_diameter":
{ {
"label": "Minimum Diameter", "label": "Maximum Tower-Supported Diameter",
"description": "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.", "description": "Maximum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.",
"unit": "mm", "unit": "mm",
"type": "float", "type": "float",
"default_value": 3.0, "default_value": 3.0,
@ -4775,7 +4775,7 @@
"description": "Enforce brim to be printed around the model even if that space would otherwise be occupied by support. This replaces some regions of the first layer of support by brim regions.", "description": "Enforce brim to be printed around the model even if that space would otherwise be occupied by support. This replaces some regions of the first layer of support by brim regions.",
"type": "bool", "type": "bool",
"default_value": true, "default_value": true,
"enabled": "resolveOrValue('adhesion_type') == 'brim' and support_enable", "enabled": "resolveOrValue('adhesion_type') == 'brim' and (support_enable or support_tree_enable)",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true, "settable_per_extruder": true,
"limit_to_extruder": "support_infill_extruder_nr" "limit_to_extruder": "support_infill_extruder_nr"
@ -5281,17 +5281,6 @@
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false "settable_per_extruder": false
}, },
"prime_tower_circular":
{
"label": "Circular Prime Tower",
"description": "Make the prime tower as a circular shape.",
"type": "bool",
"enabled": "resolveOrValue('prime_tower_enable')",
"default_value": true,
"resolve": "any(extruderValues('prime_tower_circular'))",
"settable_per_mesh": false,
"settable_per_extruder": false
},
"prime_tower_size": "prime_tower_size":
{ {
"label": "Prime Tower Size", "label": "Prime Tower Size",
@ -5316,7 +5305,7 @@
"type": "float", "type": "float",
"default_value": 6, "default_value": 6,
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "((resolveOrValue('prime_tower_size') * 0.5) ** 2 * 3.14159 * resolveOrValue('layer_height') if prime_tower_circular else resolveOrValue('prime_tower_size') ** 2 * resolveOrValue('layer_height')) - sum(extruderValues('prime_tower_min_volume')) + prime_tower_min_volume", "maximum_value_warning": "((resolveOrValue('prime_tower_size') * 0.5) ** 2 * 3.14159 * resolveOrValue('layer_height')",
"enabled": "resolveOrValue('prime_tower_enable')", "enabled": "resolveOrValue('prime_tower_enable')",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
@ -5507,7 +5496,7 @@
"description": "Remove empty layers beneath the first printed layer if they are present. Disabling this setting can cause empty first layers if the Slicing Tolerance setting is set to Exclusive or Middle.", "description": "Remove empty layers beneath the first printed layer if they are present. Disabling this setting can cause empty first layers if the Slicing Tolerance setting is set to Exclusive or Middle.",
"type": "bool", "type": "bool",
"default_value": true, "default_value": true,
"enabled": "not support_enable", "enabled": "not (support_enable or support_tree_enable)",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false "settable_per_extruder": false
} }
@ -6240,7 +6229,7 @@
"support_conical_enabled": "support_conical_enabled":
{ {
"label": "Enable Conical Support", "label": "Enable Conical Support",
"description": "Experimental feature: Make support areas smaller at the bottom than at the overhang.", "description": "Make support areas smaller at the bottom than at the overhang.",
"type": "bool", "type": "bool",
"default_value": false, "default_value": false,
"enabled": "support_enable", "enabled": "support_enable",

View file

@ -73,13 +73,31 @@
"value": "30" "value": "30"
}, },
"acceleration_enabled": { "acceleration_enabled": {
"default_value": false "default_value": true
},
"acceleration_print": {
"default_value": 500
},
"acceleration_travel": {
"value": 500
},
"acceleration_travel_layer_0": {
"value": 500
}, },
"machine_acceleration": { "machine_acceleration": {
"default_value": 1500 "default_value": 1500
}, },
"jerk_enabled": { "jerk_enabled": {
"default_value": false "default_value": true
},
"jerk_print": {
"default_value": 8
},
"jerk_travel": {
"value": 8
},
"jerk_travel_layer_0": {
"value": 8
}, },
"machine_max_jerk_xy": { "machine_max_jerk_xy": {
"default_value": 6 "default_value": 6

View file

@ -0,0 +1,16 @@
{
"id": "erzay3d_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
"machine": "erzay3d",
"position": "0"
},
"overrides": {
"extruder_nr": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.4 },
"material_diameter": { "default_value": 1.75 }
}
}

View file

@ -67,6 +67,15 @@ Button
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
TextMetrics
{
id: buttonTextMetrics
text: buttonText.text
font: buttonText.font
elide: buttonText.elide
elideWidth: buttonText.width
}
Label Label
{ {
id: buttonText id: buttonText
@ -124,7 +133,7 @@ Button
Cura.ToolTip Cura.ToolTip
{ {
id: tooltip id: tooltip
visible: button.hovered visible: button.hovered && buttonTextMetrics.elidedText != buttonText.text
} }
BusyIndicator BusyIndicator

View file

@ -368,14 +368,30 @@ UM.PreferencesPage
{ {
width: childrenRect.width; width: childrenRect.width;
height: childrenRect.height; height: childrenRect.height;
text: catalog.i18nc("@info:tooltip", "Should zooming move in the direction of the mouse?") text: zoomToMouseCheckbox.enabled ? catalog.i18nc("@info:tooltip", "Should zooming move in the direction of the mouse?") : catalog.i18nc("@info:tooltip", "Zooming towards the mouse is not supported in the orthogonal perspective.")
CheckBox CheckBox
{ {
id: zoomToMouseCheckbox id: zoomToMouseCheckbox
text: catalog.i18nc("@action:button", "Zoom toward mouse direction"); text: catalog.i18nc("@action:button", "Zoom toward mouse direction")
checked: boolCheck(UM.Preferences.getValue("view/zoom_to_mouse")) checked: boolCheck(UM.Preferences.getValue("view/zoom_to_mouse")) && zoomToMouseCheckbox.enabled
onClicked: UM.Preferences.setValue("view/zoom_to_mouse", checked) onClicked: UM.Preferences.setValue("view/zoom_to_mouse", checked)
enabled: UM.Preferences.getValue("general/camera_perspective_mode") !== "orthogonal"
}
//Because there is no signal for individual preferences, we need to manually link to the onPreferenceChanged signal.
Connections
{
target: UM.Preferences
onPreferenceChanged:
{
if(preference != "general/camera_perspective_mode")
{
return;
}
zoomToMouseCheckbox.enabled = UM.Preferences.getValue("general/camera_perspective_mode") !== "orthogonal";
zoomToMouseCheckbox.checked = boolCheck(UM.Preferences.getValue("view/zoom_to_mouse")) && zoomToMouseCheckbox.enabled;
}
} }
} }

View file

@ -4,7 +4,7 @@ name = Fine
definition = abax_pri3 definition = abax_pri3
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Extra Fine
definition = abax_pri3 definition = abax_pri3
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Fine
definition = abax_pri3 definition = abax_pri3
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Fine
definition = abax_pri5 definition = abax_pri5
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Extra Fine
definition = abax_pri5 definition = abax_pri5
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Fine
definition = abax_pri5 definition = abax_pri5
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Fine
definition = abax_titan definition = abax_titan
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Extra Fine
definition = abax_titan definition = abax_titan
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Fine
definition = abax_titan definition = abax_titan
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Draft
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = draft quality_type = draft
weight = -2 weight = -2

View file

@ -4,7 +4,7 @@ name = High
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Draft
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = draft quality_type = draft
weight = -2 weight = -2

View file

@ -4,7 +4,7 @@ name = High
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Draft
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = draft quality_type = draft
weight = -2 weight = -2

View file

@ -4,7 +4,7 @@ name = High
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Draft
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = draft quality_type = draft
weight = -2 weight = -2

View file

@ -4,7 +4,7 @@ name = High
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Draft
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = draft quality_type = draft
weight = -2 weight = -2

View file

@ -4,7 +4,7 @@ name = High
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = anycubic_4max definition = anycubic_4max
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Draft
definition = anycubic_chiron definition = anycubic_chiron
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = draft quality_type = draft
weight = -2 weight = -2

View file

@ -4,7 +4,7 @@ name = High
definition = anycubic_chiron definition = anycubic_chiron
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = anycubic_chiron definition = anycubic_chiron
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Draft
definition = anycubic_i3_mega definition = anycubic_i3_mega
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = draft quality_type = draft
weight = -2 weight = -2

View file

@ -4,7 +4,7 @@ name = High
definition = anycubic_i3_mega definition = anycubic_i3_mega
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = anycubic_i3_mega definition = anycubic_i3_mega
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Coarse
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = coarse quality_type = coarse
weight = -1 weight = -1

View file

@ -4,7 +4,7 @@ name = High Quality
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Coarse
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = coarse quality_type = coarse
weight = -1 weight = -1

View file

@ -4,7 +4,7 @@ name = High Quality
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Coarse
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = coarse quality_type = coarse
weight = -1 weight = -1

View file

@ -4,7 +4,7 @@ name = High Quality
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Coarse
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = coarse quality_type = coarse
weight = -1 weight = -1

View file

@ -4,7 +4,7 @@ name = High Quality
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Coarse
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = coarse quality_type = coarse
weight = -1 weight = -1

View file

@ -4,7 +4,7 @@ name = High Quality
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Coarse
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = coarse quality_type = coarse
weight = -1 weight = -1

View file

@ -4,7 +4,7 @@ name = High Quality
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = builder_premium_small definition = builder_premium_small
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Coarse
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = coarse quality_type = coarse
weight = 3 weight = 3

View file

@ -4,7 +4,7 @@ name = Extra Coarse
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = extra coarse quality_type = extra coarse
weight = 4 weight = 4

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Coarse
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = coarse quality_type = coarse
weight = -3 weight = -3

View file

@ -4,7 +4,7 @@ name = Extra Coarse
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = extra coarse quality_type = extra coarse
weight = -4 weight = -4

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Coarse
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = coarse quality_type = coarse
weight = 3 weight = 3

View file

@ -4,7 +4,7 @@ name = Extra Coarse
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = extra coarse quality_type = extra coarse
weight = 4 weight = 4

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = Coarse
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = coarse quality_type = coarse
weight = 3 weight = 3

View file

@ -4,7 +4,7 @@ name = Extra Coarse
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = extra coarse quality_type = extra coarse
weight = 4 weight = 4

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

View file

@ -4,7 +4,7 @@ name = Normal
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = normal quality_type = normal
weight = 0 weight = 0

View file

@ -4,7 +4,7 @@ name = High
definition = cartesio definition = cartesio
[metadata] [metadata]
setting_version = 7 setting_version = 8
type = quality type = quality
quality_type = high quality_type = high
weight = 1 weight = 1

Some files were not shown because too many files have changed in this diff Show more