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!
-->
**Application Version**
**Application version**
<!-- The version of the application this issue occurs with -->
**Platform**
@ -30,11 +30,14 @@ Thank you for using Cura!
**Printer**
<!-- 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 -->
**Expected results**
<!-- What should happen after the above steps have been followed -->
**Additional Information**
**Additional information**
<!-- Extra information relevant to the issue, like screenshots -->

View file

@ -1,6 +1,6 @@
# Copyright (c) 2019 Ultimaker B.V.
# 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.Settings.ExtruderManager import ExtruderManager
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 UM.View.RenderBatch import RenderBatch
from UM.View.GL.OpenGL import OpenGL
from cura.Settings.GlobalStack import GlobalStack
catalog = i18nCatalog("cura")
import numpy
import math
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.
PRIME_CLEARANCE = 6.5
@ -36,45 +43,46 @@ PRIME_CLEARANCE = 6.5
class BuildVolume(SceneNode):
raftThicknessChanged = Signal()
def __init__(self, application, parent = None):
def __init__(self, application: "CuraApplication", parent: Optional[SceneNode] = None) -> None:
super().__init__(parent)
self._application = application
self._machine_manager = self._application.getMachineManager()
self._volume_outline_color = None
self._x_axis_color = None
self._y_axis_color = None
self._z_axis_color = None
self._disallowed_area_color = None
self._error_area_color = None
self._volume_outline_color = None # type: Optional[Color]
self._x_axis_color = None # type: Optional[Color]
self._y_axis_color = None # type: Optional[Color]
self._z_axis_color = None # type: Optional[Color]
self._disallowed_area_color = None # type: Optional[Color]
self._error_area_color = None # type: Optional[Color]
self._width = 0 #type: float
self._height = 0 #type: float
self._depth = 0 #type: float
self._shape = "" #type: str
self._width = 0 # type: float
self._height = 0 # type: float
self._depth = 0 # type: float
self._shape = "" # type: str
self._shader = None
self._origin_mesh = None
self._origin_mesh = None # type: Optional[MeshData]
self._origin_line_length = 20
self._origin_line_width = 0.5
self._grid_mesh = None
self._grid_mesh = None # type: Optional[MeshData]
self._grid_shader = None
self._disallowed_areas = []
self._disallowed_areas_no_brim = []
self._disallowed_area_mesh = None
self._disallowed_areas = [] # type: List[Polygon]
self._disallowed_areas_no_brim = [] # type: List[Polygon]
self._disallowed_area_mesh = None # type: Optional[MeshData]
self._disallowed_area_size = 0.
self._error_areas = []
self._error_mesh = None
self._error_areas = [] # type: List[Polygon]
self._error_mesh = None # type: Optional[MeshData]
self.setCalculateBoundingBox(False)
self._volume_aabb = None
self._volume_aabb = None # type: Optional[AxisAlignedBox]
self._raft_thickness = 0.0
self._extra_z_clearance = 0.0
self._adhesion_type = None
self._adhesion_type = None # type: Any
self._platform = Platform(self)
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"
" 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.setInterval(100)
@ -100,7 +108,7 @@ class BuildVolume(SceneNode):
self._application.getController().getScene().sceneChanged.connect(self._onSceneChanged)
#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.setInterval(100)
@ -124,8 +132,8 @@ class BuildVolume(SceneNode):
# Enable and disable extruder
self._machine_manager.extruderChanged.connect(self.updateNodeBoundaryCheck)
# list of settings which were updated
self._changed_settings_since_last_rebuild = []
# List of settings which were updated
self._changed_settings_since_last_rebuild = [] # type: List[str]
def _onSceneChanged(self, source):
if self._global_container_stack:
@ -219,9 +227,12 @@ class BuildVolume(SceneNode):
## For every sliceable node, update node._outside_buildarea
#
def updateNodeBoundaryCheck(self):
if not self._global_container_stack:
return
root = self._application.getController().getScene().getRoot()
nodes = list(BreadthFirstIterator(root))
group_nodes = []
nodes = cast(List[SceneNode], list(cast(Iterable, BreadthFirstIterator(root))))
group_nodes = [] # type: List[SceneNode]
build_volume_bounding_box = self.getBoundingBox()
if build_volume_bounding_box:
@ -240,6 +251,9 @@ class BuildVolume(SceneNode):
group_nodes.append(node) # Keep list of affected group_nodes
if node.callDecoration("isSliceable") or node.callDecoration("isGroup"):
if not isinstance(node, CuraSceneNode):
continue
if node.collidesWithBbox(build_volume_bounding_box):
node.setOutsideBuildArea(True)
continue
@ -277,8 +291,8 @@ class BuildVolume(SceneNode):
child_node.setOutsideBuildArea(group_node.isOutsideBuildArea())
## Update the outsideBuildArea of a single node, given bounds or current build volume
def checkBoundsAndUpdate(self, node: CuraSceneNode, bounds: Optional[AxisAlignedBox] = None):
if not isinstance(node, CuraSceneNode):
def checkBoundsAndUpdate(self, node: CuraSceneNode, bounds: Optional[AxisAlignedBox] = None) -> None:
if not isinstance(node, CuraSceneNode) or self._global_container_stack is None:
return
if bounds is None:
@ -310,7 +324,7 @@ class BuildVolume(SceneNode):
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()
if self._shape != "elliptic":
# Build plate grid mesh
@ -346,7 +360,7 @@ class BuildVolume(SceneNode):
mb.setVertexUVCoordinates(n, v[0], v[2] * aspect)
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":
# Outline 'cube' of the build volume
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)
return mb.build().getTransformed(scale_matrix)
def _buildOriginMesh(self, origin):
def _buildOriginMesh(self, origin: Vector) -> MeshData:
mb = MeshBuilder()
mb.addCube(
width=self._origin_line_length,
@ -404,22 +418,80 @@ class BuildVolume(SceneNode):
)
return mb.build()
def _updateColors(self):
theme = self._application.getTheme()
if theme is None:
return
self._volume_outline_color = Color(*theme.getColor("volume_outline").getRgb())
self._x_axis_color = Color(*theme.getColor("x_axis").getRgb())
self._y_axis_color = Color(*theme.getColor("y_axis").getRgb())
self._z_axis_color = Color(*theme.getColor("z_axis").getRgb())
self._disallowed_area_color = Color(*theme.getColor("disallowed_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):
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:
theme = self._application.getTheme()
self._volume_outline_color = Color(*theme.getColor("volume_outline").getRgb())
self._x_axis_color = Color(*theme.getColor("x_axis").getRgb())
self._y_axis_color = Color(*theme.getColor("y_axis").getRgb())
self._z_axis_color = Color(*theme.getColor("z_axis").getRgb())
self._disallowed_area_color = Color(*theme.getColor("disallowed_area").getRgb())
self._error_area_color = Color(*theme.getColor("error_area").getRgb())
self._updateColors()
min_w = -self._width / 2
max_w = self._width / 2
@ -442,52 +514,10 @@ class BuildVolume(SceneNode):
self._origin_mesh = self._buildOriginMesh(origin)
disallowed_area_height = 0.1
disallowed_area_size = 0
if self._disallowed_areas:
mb = MeshBuilder()
color = self._disallowed_area_color
for polygon in self._disallowed_areas:
points = polygon.getPoints()
if len(points) == 0:
continue
self._disallowed_area_size = 0.
self._disallowed_area_mesh = self._buildDisallowedAreaMesh(min_w, max_w, min_h, max_h, min_d, max_d, disallowed_area_height)
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
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._error_mesh = self._buildErrorMesh(min_w, max_w, min_h, max_h, min_d, max_d, disallowed_area_height)
self._volume_aabb = AxisAlignedBox(
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!
# The +1 and -1 is added as there is always a bit of extra room required to work properly.
scale_to_max_bounds = AxisAlignedBox(
minimum = Vector(min_w + bed_adhesion_size + 1, min_h, min_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 - 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 - 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()
def getBoundingBox(self) -> AxisAlignedBox:
def getBoundingBox(self):
return self._volume_aabb
def getRaftThickness(self) -> float:
return self._raft_thickness
def _updateRaftThickness(self):
def _updateRaftThickness(self) -> None:
if not self._global_container_stack:
return
old_raft_thickness = self._raft_thickness
if self._global_container_stack.extruders:
# This might be called before the extruder stacks have initialised, in which case getting the adhesion_type fails
@ -524,7 +557,7 @@ class BuildVolume(SceneNode):
self._global_container_stack.getProperty("raft_base_thickness", "value") +
self._global_container_stack.getProperty("raft_interface_thickness", "value") +
self._global_container_stack.getProperty("raft_surface_layers", "value") *
self._global_container_stack.getProperty("raft_surface_thickness", "value") +
self._global_container_stack.getProperty("raft_surface_thickness", "value") +
self._global_container_stack.getProperty("raft_airgap", "value") -
self._global_container_stack.getProperty("layer_0_z_overlap", "value"))
@ -533,28 +566,23 @@ class BuildVolume(SceneNode):
self.setPosition(Vector(0, -self._raft_thickness, 0), SceneNode.TransformSpace.World)
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
extruders = ExtruderManager.getInstance().getUsedExtruderStacks()
use_extruders = False
for extruder in extruders:
if extruder.getProperty("retraction_hop_enabled", "value"):
retraction_hop = extruder.getProperty("retraction_hop", "value")
if extra_z is None or retraction_hop > extra_z:
extra_z = retraction_hop
use_extruders = True
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
return extra_z
def _onStackChanged(self):
self._stack_change_timer.start()
## Update the build volume visualization
def _onStackChangeTimerFinished(self):
def _onStackChangeTimerFinished(self) -> None:
if self._global_container_stack:
self._global_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged)
extruders = ExtruderManager.getInstance().getActiveExtruderStacks()
@ -585,7 +613,7 @@ class BuildVolume(SceneNode):
self._updateDisallowedAreas()
self._updateRaftThickness()
self._updateExtraZClearance()
self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks())
if self._engine_ready:
self.rebuild()
@ -594,20 +622,23 @@ class BuildVolume(SceneNode):
if camera:
diagonal = self.getDiagonalSize()
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.rebuild()
def _onSettingChangeTimerFinished(self):
def _onSettingChangeTimerFinished(self) -> None:
if not self._global_container_stack:
return
rebuild_me = False
update_disallowed_areas = False
update_raft_thickness = False
update_extra_z_clearance = True
for setting_key in self._changed_settings_since_last_rebuild:
if setting_key == "print_sequence":
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:
@ -620,33 +651,26 @@ class BuildVolume(SceneNode):
self._height = self._global_container_stack.getProperty("machine_height", "value")
self._build_volume_message.hide()
update_disallowed_areas = True
rebuild_me = True
# sometimes the machine size or shape settings are adjusted on the active machine, we should reflect this
if setting_key in self._machine_settings:
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")
self._updateMachineSizeProperties()
update_extra_z_clearance = 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
rebuild_me = True
if setting_key in self._raft_settings:
update_raft_thickness = True
rebuild_me = True
if setting_key in self._extra_z_settings:
update_extra_z_clearance = True
rebuild_me = True
if setting_key in self._limit_to_extruder_settings:
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.
if update_disallowed_areas:
@ -656,7 +680,7 @@ class BuildVolume(SceneNode):
self._updateRaftThickness()
if update_extra_z_clearance:
self._updateExtraZClearance()
self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks())
if rebuild_me:
self.rebuild()
@ -664,7 +688,7 @@ class BuildVolume(SceneNode):
# We just did a rebuild, reset the list.
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":
return
@ -675,6 +699,14 @@ class BuildVolume(SceneNode):
def hasErrors(self) -> bool:
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
# scene.
#
@ -686,10 +718,10 @@ class BuildVolume(SceneNode):
def _updateDisallowedAreasAndRebuild(self):
self._updateDisallowedAreas()
self._updateRaftThickness()
self._updateExtraZClearance()
self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks())
self.rebuild()
def _updateDisallowedAreas(self):
def _updateDisallowedAreas(self) -> None:
if not self._global_container_stack:
return
@ -815,17 +847,10 @@ class BuildVolume(SceneNode):
prime_tower_x -= brim_size
prime_tower_y += brim_size
if self._global_container_stack.getProperty("prime_tower_circular", "value"):
radius = prime_tower_size / 2
prime_tower_area = Polygon.approximatedCircle(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],
])
radius = prime_tower_size / 2
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.getMinkowskiHull(Polygon.approximatedCircle(0))
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.
@ -843,9 +868,10 @@ class BuildVolume(SceneNode):
# \param used_extruders The extruder stacks to generate disallowed areas
# for.
# \return A dictionary with for each used extruder ID the prime areas.
def _computeDisallowedAreasPrimeBlob(self, border_size, used_extruders):
result = {}
def _computeDisallowedAreasPrimeBlob(self, border_size: float, used_extruders: List["ExtruderStack"]) -> Dict[str, List[Polygon]]:
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_depth = self._global_container_stack.getProperty("machine_depth", "value")
for extruder in used_extruders:
@ -853,13 +879,13 @@ class BuildVolume(SceneNode):
prime_x = extruder.getProperty("extruder_prime_pos_x", "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:
result[extruder.getId()] = []
continue
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_polygon = Polygon.approximatedCircle(PRIME_CLEARANCE)
@ -1015,14 +1041,86 @@ class BuildVolume(SceneNode):
# stack.
#
# \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_types = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "type")
for i in range(len(all_values)):
if not all_values[i] and (all_types[i] == "int" or all_types[i] == "float"):
for i, (setting_value, setting_type) in enumerate(zip(all_values, all_types)):
if not setting_value and (setting_type == "int" or setting_type == "float"):
all_values[i] = 0
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.
#
# 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":
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")
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)
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)
bed_adhesion_size = self._calculateBedAdhesionSize(used_extruders)
support_expansion = self._calculateSupportExpansion(self._global_container_stack)
farthest_shield_distance = self._calculateFarthestShieldDistance(self._global_container_stack)
move_from_wall_radius = self._calculateMoveFromWallRadius(used_extruders)
# 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.
@ -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"]
_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"]
_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"]
_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.
_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.
# You need to make sure that this version number needs to be increased if there is any non-backwards-compatible
# changes of the settings.
SettingVersion = 7
SettingVersion = 8
Created = False

View file

@ -62,6 +62,14 @@ class DiscoveredPrinter(QObject):
self._machine_type = machine_type
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
@pyqtProperty(str, notify = machineTypeChanged)
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
# "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.
if machine_manager.hasHumanReadableMachineTypeName(self._machine_type):
if self._hasHumanReadableMachineTypeName(self._machine_type):
readable_type = self._machine_type
else:
readable_type = machine_manager.getMachineTypeNameFromId(self._machine_type)
readable_type = self._getMachineTypeNameFromId(self._machine_type)
if not readable_type:
readable_type = catalog.i18nc("@label", "Unknown")
return readable_type
@pyqtProperty(bool, notify = machineTypeChanged)
def isUnknownMachineType(self) -> bool:
from cura.CuraApplication import CuraApplication
machine_manager = CuraApplication.getInstance().getMachineManager()
if machine_manager.hasHumanReadableMachineTypeName(self._machine_type):
if self._hasHumanReadableMachineTypeName(self._machine_type):
readable_type = self._machine_type
else:
readable_type = machine_manager.getMachineTypeNameFromId(self._machine_type)
readable_type = self._getMachineTypeNameFromId(self._machine_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)
def device(self) -> "NetworkedPrinterOutputDevice":
return self._device

View file

@ -202,9 +202,6 @@ class QualityManager(QObject):
def getQualityGroups(self, machine: "GlobalStack") -> Dict[str, QualityGroup]:
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:
# (1) the machine-specific 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.
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.SettingOverrideDecorator import SettingOverrideDecorator #For per-object settings.
## 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.
class CuraSceneNode(SceneNode):
@ -85,16 +86,6 @@ class CuraSceneNode(SceneNode):
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
def collidesWithArea(self, areas: List[Polygon]) -> bool:
convex_hull = self.callDecoration("getConvexHull")

View file

@ -283,7 +283,7 @@ class CuraContainerRegistry(ContainerRegistry):
profile.addInstance(new_instance)
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)
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 property \type{str} The property to get.
# \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 = []
for extruder_stack in self.getActiveExtruderStacks():

View file

@ -264,18 +264,18 @@ class GlobalStack(CuraContainerStack):
def getHeadAndFansCoordinates(self):
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))
def getHasVariants(self) -> bool:
@pyqtProperty(int, constant=True)
def hasVariants(self):
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))
def getHasMachineQuality(self) -> bool:
return parseBool(self.getMetaDataEntry("has_machine_quality", False))
## Get default firmware file name if one is specified in the firmware
@pyqtSlot(result = str)
def getDefaultFirmwareName(self) -> str:

View file

@ -538,6 +538,7 @@ class MachineManager(QObject):
return bool(self._printer_output_devices)
@pyqtProperty(bool, notify = printerConnectedStatusChanged)
@deprecated("use Cura.MachineManager.activeMachine.configuredConnectionTypes instead", "4.2")
def activeMachineHasRemoteConnection(self) -> bool:
if self._global_container_stack:
has_remote_connection = False
@ -816,21 +817,24 @@ class MachineManager(QObject):
self.removeMachine(hidden_containers[0].getId())
@pyqtProperty(bool, notify = globalContainerChanged)
@deprecated("use Cura.MachineManager.activeMachine.hasMaterials instead", "4.2")
def hasMaterials(self) -> bool:
if self._global_container_stack:
return self._global_container_stack.getHasMaterials()
return self._global_container_stack.hasMaterials
return False
@pyqtProperty(bool, notify = globalContainerChanged)
@deprecated("use Cura.MachineManager.activeMachine.hasVariants instead", "4.2")
def hasVariants(self) -> bool:
if self._global_container_stack:
return self._global_container_stack.getHasVariants()
return self._global_container_stack.hasVariants
return False
@pyqtProperty(bool, notify = globalContainerChanged)
@deprecated("use Cura.MachineManager.activeMachine.hasVariantBuildplates instead", "4.2")
def hasVariantBuildplates(self) -> bool:
if self._global_container_stack:
return self._global_container_stack.getHasVariantsBuildPlates()
return self._global_container_stack.hasVariantBuildplates
return False
## 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.
self._global_container_stack.userChanges.setProperty(setting_key, "value", self._default_extruder_position)
if add_user_changes:
caution_message = Message(catalog.i18nc(
"@info:generic",
"Settings have been changed to match the current availability of extruders: [%s]" % ", ".join(add_user_changes)),
caution_message = Message(
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)),
lifetime = 0,
title = catalog.i18nc("@info:title", "Settings updated"))
caution_message.show()
@ -984,6 +987,7 @@ class MachineManager(QObject):
self.forceUpdateAllSettings()
@pyqtSlot(int, result = QObject)
@deprecated("use Cura.MachineManager.activeMachine.extruders instead", "4.2")
def getExtruder(self, position: int) -> Optional[ExtruderStack]:
if self._global_container_stack:
return self._global_container_stack.extruders.get(str(position))
@ -1097,6 +1101,7 @@ class MachineManager(QObject):
container.removeInstance(setting_name)
@pyqtProperty("QVariantList", notify = globalContainerChanged)
@deprecated("use Cura.MachineManager.activeMachine.extruders instead", "4.2")
def currentExtruderPositions(self) -> List[str]:
if self._global_container_stack is None:
return []
@ -1642,21 +1647,6 @@ class MachineManager(QObject):
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.
def getMachinesInGroup(self, group_id: str) -> List["GlobalStack"]:
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.
import configparser
from typing import List, Optional, Tuple
from UM.PluginRegistry import PluginRegistry
from UM.Logger import Logger
from UM.Settings.ContainerFormatError import ContainerFormatError
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
import zipfile
@ -17,39 +20,43 @@ import zipfile
class CuraProfileReader(ProfileReader):
## Initialises the cura profile reader.
# This does nothing since the only other function is basically stateless.
def __init__(self):
def __init__(self) -> None:
super().__init__()
## Reads a cura profile from a file and returns it.
#
# \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
# not be read or didn't contain a valid profile, \code None \endcode is
# \return The cura profiles that were in the file, if any. If the file
# could not be read or didn't contain a valid profile, ``None`` is
# returned.
def read(self, file_name):
def read(self, file_name: str) -> List[Optional[InstanceContainer]]:
try:
with zipfile.ZipFile(file_name, "r") as archive:
results = []
results = [] #type: List[Optional[InstanceContainer]]
for profile_id in archive.namelist():
with archive.open(profile_id) as f:
serialized = f.read()
profile = self._loadProfile(serialized.decode("utf-8"), profile_id)
if profile is not None:
results.append(profile)
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:
results.append(profile)
return results
except zipfile.BadZipFile:
# It must be an older profile from Cura 2.1.
with open(file_name, encoding = "utf-8") as fhandle:
serialized = fhandle.read()
return [self._loadProfile(serialized, profile_id) for serialized, profile_id in self._upgradeProfile(serialized, file_name)]
serialized_bytes = fhandle.read()
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.
#
# \param serialized \type{str} The profile data to convert in the serialized on-disk format.
# \param profile_id \type{str} The name of the profile.
# \return \type{List[Tuple[str,str]]} List of serialized profile strings and matching profile names.
def _upgradeProfile(self, serialized, profile_id):
# \param serialized The profile data to convert in the serialized on-disk
# format.
# \param profile_id The name of the profile.
# \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.read_string(serialized)
@ -61,7 +68,7 @@ class CuraProfileReader(ProfileReader):
return []
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"]
return self._upgradeProfileVersion(serialized, name, version)
else:
@ -69,10 +76,10 @@ class CuraProfileReader(ProfileReader):
## Load a profile from a serialized string.
#
# \param serialized \type{str} The profile data to read.
# \param profile_id \type{str} The name of the profile.
# \return \type{InstanceContainer|None}
def _loadProfile(self, serialized, profile_id):
# \param serialized The profile data to read.
# \param profile_id The name of the profile.
# \return The profile that was stored in the string.
def _loadProfile(self, serialized: str, profile_id: str) -> Optional[InstanceContainer]:
# Create an empty profile.
profile = InstanceContainer(profile_id)
profile.setMetaDataEntry("type", "quality_changes")
@ -88,12 +95,12 @@ class CuraProfileReader(ProfileReader):
## Upgrade a serialized profile to the current profile format.
#
# \param serialized \type{str} The profile data to convert.
# \param profile_id \type{str} The name of the profile.
# \param source_version \type{int} The profile version of 'serialized'.
# \return \type{List[Tuple[str,str]]} List of serialized profile strings and matching profile names.
def _upgradeProfileVersion(self, serialized, profile_id, source_version):
converter_plugins = PluginRegistry.getInstance().getAllMetaData(filter={"version_upgrade": {} }, active_only=True)
# \param serialized The profile data to convert.
# \param profile_id The name of the profile.
# \param source_version The profile version of 'serialized'.
# \return List of serialized profile strings and matching profile names.
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)
source_format = ("profile", source_version)
profile_convert_funcs = [plugin["version_upgrade"][source_format][2] for plugin in converter_plugins

View file

@ -14,7 +14,7 @@ def getMetaData() -> Dict[str, Any]:
return {
"version_upgrade": {
# From To Upgrade function
("preferences", 6000006): ("preferences", 6000007, upgrade.upgradePreferences),
("preferences", 6000006): ("preferences", 6000007, upgrade.upgradePreferences),
("machine_stack", 4000006): ("machine_stack", 4000007, upgrade.upgradeStack),
("extruder_train", 4000006): ("extruder_train", 4000007, upgrade.upgradeStack),
("definition_changes", 4000006): ("definition_changes", 4000007, upgrade.upgradeInstanceContainer),

View file

@ -1,14 +1,32 @@
## Upgrades configurations from the state they were in at version 4.1 to the
# state they should be in at version 4.2.
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import configparser
import io
from typing import Tuple, List
from typing import Dict, List, Tuple
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):
## 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:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
@ -16,17 +34,71 @@ class VersionUpgrade41to42(VersionUpgrade):
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
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.
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)
#Update version number.
parser["metadata"]["setting_version"] = "8"
parser["general"]["version"] = "5"
# We should only have 6 levels when we start.
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.
parser["containers"]["7"] = parser["containers"]["6"]
parser["containers"]["6"] = parser["containers"]["5"]
@ -37,6 +109,4 @@ class VersionUpgrade41to42(VersionUpgrade):
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]
return [filename], [result.getvalue()]

View file

@ -14,10 +14,19 @@ def getMetaData() -> Dict[str, Any]:
return {
"version_upgrade": {
# From To Upgrade function
("machine_stack", 4000007): ("machine_stack", 5000007, upgrade.upgradeStack),
("extruder_train", 4000007): ("extruder_train", 5000007, upgrade.upgradeStack)
("preferences", 6000007): ("preferences", 6000008, upgrade.upgradePreferences),
("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": {
"preferences": {
"get_version": upgrade.getCfgVersion,
"location": {"."}
},
"machine_stack": {
"get_version": upgrade.getCfgVersion,
"location": {"./machine_instances"}
@ -25,10 +34,30 @@ def getMetaData() -> Dict[str, Any]:
"extruder_train": {
"get_version": upgrade.getCfgVersion,
"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]:
<<<<<<< HEAD
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()))
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
if not apply_to_all:
super().setMetaDataEntry(key, value)
for k, v in new_setting_values_dict.items():
self.setProperty(k, "value", v)
return
# Get the MaterialGroup
@ -74,17 +84,23 @@ class XmlMaterialProfile(InstanceContainer):
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.
super().setMetaDataEntry(key, value)
for k, v in new_setting_values_dict.items():
self.setProperty(k, "value", v)
return
# Update the root material container
root_material_container = material_group.root_material_node.getContainer()
if root_material_container is not None:
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
for node in material_group.derived_material_node_list:
container = node.getContainer()
if container is not None:
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.
# 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",
"author": "Ultimaker",
"manufacturer": "Unknown",
"setting_version": 7,
"setting_version": 8,
"visible": false,
"position": "0"
},

View file

@ -7,7 +7,7 @@
"author": "Ultimaker",
"category": "Other",
"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",
"visible": false,
"has_materials": true,
@ -892,7 +892,7 @@
"maximum_value_warning": "3 * machine_nozzle_size",
"default_value": 0.4,
"type": "float",
"enabled": "support_enable",
"enabled": "(support_enable or support_tree_enable)",
"value": "line_width",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
@ -908,7 +908,7 @@
"minimum_value_warning": "0.1 + 0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size",
"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",
"value": "line_width",
"settable_per_mesh": false,
@ -925,7 +925,7 @@
"minimum_value_warning": "0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size",
"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",
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_line_width')",
"settable_per_mesh": false,
@ -941,7 +941,7 @@
"minimum_value_warning": "0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size",
"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",
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_line_width')",
"settable_per_mesh": false,
@ -2070,7 +2070,7 @@
"maximum_value_warning": "285",
"enabled": true,
"settable_per_mesh": false,
"settable_per_extruder": true
"settable_per_extruder": false
},
"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.",
"type": "bool",
"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_extruder": true
},
@ -2619,7 +2619,7 @@
"maximum_value_warning": "150",
"default_value": 60,
"value": "speed_print",
"enabled": "support_enable",
"enabled": "support_enable or support_tree_enable",
"settable_per_mesh": false,
"limit_to_extruder": "support_extruder_nr",
"settable_per_extruder": true,
@ -2636,7 +2636,7 @@
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "150",
"value": "speed_support",
"enabled": "support_enable",
"enabled": "support_enable or support_tree_enable",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@ -2651,7 +2651,7 @@
"minimum_value": "0.1",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"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",
"value": "speed_support / 1.5",
"settable_per_mesh": false,
@ -2668,7 +2668,7 @@
"minimum_value": "0.1",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"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",
"value": "extruderValue(support_roof_extruder_nr, 'speed_support_interface')",
"settable_per_mesh": false,
@ -2684,7 +2684,7 @@
"minimum_value": "0.1",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"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",
"value": "extruderValue(support_bottom_extruder_nr, 'speed_support_interface')",
"settable_per_mesh": false,
@ -2972,7 +2972,7 @@
"maximum_value_warning": "10000",
"default_value": 3000,
"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,
"limit_to_extruder": "support_extruder_nr",
"settable_per_extruder": true,
@ -2989,7 +2989,7 @@
"minimum_value": "0.1",
"minimum_value_warning": "100",
"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",
"settable_per_mesh": false,
"settable_per_extruder": true
@ -3005,7 +3005,7 @@
"minimum_value": "0.1",
"minimum_value_warning": "100",
"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",
"settable_per_mesh": false,
"settable_per_extruder": true,
@ -3022,7 +3022,7 @@
"minimum_value": "0.1",
"minimum_value_warning": "100",
"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",
"settable_per_mesh": false,
"settable_per_extruder": true
@ -3038,7 +3038,7 @@
"minimum_value": "0.1",
"minimum_value_warning": "100",
"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",
"settable_per_mesh": false,
"settable_per_extruder": true
@ -3257,7 +3257,7 @@
"maximum_value_warning": "50",
"default_value": 20,
"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_extruder": true,
"limit_to_extruder": "support_extruder_nr",
@ -3273,7 +3273,7 @@
"value": "jerk_support",
"minimum_value": "0",
"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",
"settable_per_mesh": false,
"settable_per_extruder": true
@ -3288,7 +3288,7 @@
"value": "jerk_support",
"minimum_value": "0",
"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",
"settable_per_mesh": false,
"settable_per_extruder": true,
@ -3304,7 +3304,7 @@
"value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')",
"minimum_value": "0",
"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",
"settable_per_mesh": false,
"settable_per_extruder": true
@ -3319,7 +3319,7 @@
"value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')",
"minimum_value": "0",
"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",
"settable_per_mesh": false,
"settable_per_extruder": true
@ -3970,7 +3970,7 @@
"minimum_value": "-180",
"maximum_value": "180",
"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",
"settable_per_mesh": false,
"settable_per_extruder": true
@ -3995,7 +3995,7 @@
"default_value": 8.0,
"minimum_value": "0.0",
"maximum_value_warning": "50.0",
"enabled": "support_enable",
"enabled": "support_enable or support_tree_enable",
"settable_per_mesh": false,
"settable_per_extruder": true,
"limit_to_extruder": "support_infill_extruder_nr",
@ -4010,7 +4010,7 @@
"minimum_value": "0",
"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))",
"enabled": "support_enable",
"enabled": "support_enable or support_tree_enable",
"settable_per_mesh": false,
"settable_per_extruder": true,
"limit_to_extruder": "support_infill_extruder_nr"
@ -4132,7 +4132,7 @@
"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",
"type": "float",
"default_value": 2.0,
@ -4299,7 +4299,7 @@
"minimum_value": "0",
"maximum_value_warning": "support_interface_height",
"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
},
"support_interface_density":
@ -4457,7 +4457,7 @@
"minimum_value": "0",
"minimum_value_warning": "minimum_support_area",
"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,
"children":
{
@ -4472,7 +4472,7 @@
"minimum_value": "0",
"minimum_value_warning": "minimum_support_area",
"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
},
"minimum_bottom_area":
@ -4486,7 +4486,7 @@
"minimum_value": "0",
"minimum_value_warning": "minimum_support_area",
"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
}
}
@ -4541,7 +4541,7 @@
"description": "When enabled, the print cooling fan speed is altered for the skin regions immediately above the support.",
"type": "bool",
"default_value": false,
"enabled": "support_enable",
"enabled": "support_enable or support_tree_enable",
"settable_per_mesh": false
},
"support_supported_skin_fan_speed":
@ -4553,7 +4553,7 @@
"maximum_value": "100",
"default_value": 100,
"type": "float",
"enabled": "support_enable and support_fan_enable",
"enabled": "(support_enable or support_tree_enable) and support_fan_enable",
"settable_per_mesh": false
},
"support_use_towers":
@ -4580,10 +4580,10 @@
"enabled": "support_enable and support_use_towers",
"settable_per_mesh": true
},
"support_minimal_diameter":
"support_tower_maximum_supported_diameter":
{
"label": "Minimum Diameter",
"description": "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.",
"label": "Maximum Tower-Supported Diameter",
"description": "Maximum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.",
"unit": "mm",
"type": "float",
"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.",
"type": "bool",
"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_extruder": true,
"limit_to_extruder": "support_infill_extruder_nr"
@ -5281,17 +5281,6 @@
"settable_per_mesh": 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":
{
"label": "Prime Tower Size",
@ -5316,7 +5305,7 @@
"type": "float",
"default_value": 6,
"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')",
"settable_per_mesh": false,
"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.",
"type": "bool",
"default_value": true,
"enabled": "not support_enable",
"enabled": "not (support_enable or support_tree_enable)",
"settable_per_mesh": false,
"settable_per_extruder": false
}
@ -6240,7 +6229,7 @@
"support_conical_enabled":
{
"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",
"default_value": false,
"enabled": "support_enable",

View file

@ -13,7 +13,7 @@
}
},
"overrides": {
"machine_name": {
"machine_name": {
"default_value": "Tevo Tornado"
},
"machine_width": {
@ -25,8 +25,8 @@
"machine_depth": {
"default_value": 300
},
"machine_center_is_zero": {
"default_value": false
"machine_center_is_zero": {
"default_value": false
},
"machine_head_polygon": {
"default_value": [
@ -73,18 +73,36 @@
"value": "30"
},
"acceleration_enabled": {
"default_value": false
"default_value": true
},
"machine_acceleration": {
"default_value": 1500
"acceleration_print": {
"default_value": 500
},
"acceleration_travel": {
"value": 500
},
"acceleration_travel_layer_0": {
"value": 500
},
"machine_acceleration": {
"default_value": 1500
},
"jerk_enabled": {
"default_value": false
"default_value": true
},
"machine_max_jerk_xy": {
"default_value": 6
"jerk_print": {
"default_value": 8
},
"machine_gcode_flavor": {
"jerk_travel": {
"value": 8
},
"jerk_travel_layer_0": {
"value": 8
},
"machine_max_jerk_xy": {
"default_value": 6
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {

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
}
TextMetrics
{
id: buttonTextMetrics
text: buttonText.text
font: buttonText.font
elide: buttonText.elide
elideWidth: buttonText.width
}
Label
{
id: buttonText
@ -124,7 +133,7 @@ Button
Cura.ToolTip
{
id: tooltip
visible: button.hovered
visible: button.hovered && buttonTextMetrics.elidedText != buttonText.text
}
BusyIndicator

View file

@ -368,14 +368,30 @@ UM.PreferencesPage
{
width: childrenRect.width;
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
{
id: zoomToMouseCheckbox
text: catalog.i18nc("@action:button", "Zoom toward mouse direction");
checked: boolCheck(UM.Preferences.getValue("view/zoom_to_mouse"))
text: catalog.i18nc("@action:button", "Zoom toward mouse direction")
checked: boolCheck(UM.Preferences.getValue("view/zoom_to_mouse")) && zoomToMouseCheckbox.enabled
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
[metadata]
setting_version = 7
setting_version = 8
type = quality
quality_type = normal
weight = 0

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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