mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-19 12:47:49 -06:00
Merge branch 'Ultimaker:main' into main
This commit is contained in:
commit
642b9fa799
5 changed files with 100 additions and 73 deletions
4
.github/workflows/installers.yml
vendored
4
.github/workflows/installers.yml
vendored
|
@ -95,7 +95,7 @@ jobs:
|
||||||
enterprise: ${{ github.event.inputs.enterprise == 'true' }}
|
enterprise: ${{ github.event.inputs.enterprise == 'true' }}
|
||||||
staging: ${{ github.event.inputs.staging == 'true' }}
|
staging: ${{ github.event.inputs.staging == 'true' }}
|
||||||
architecture: X64
|
architecture: X64
|
||||||
operating_system: macos-12
|
operating_system: self-hosted-X64
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
macos-arm-installer:
|
macos-arm-installer:
|
||||||
|
@ -107,7 +107,7 @@ jobs:
|
||||||
enterprise: ${{ github.event.inputs.enterprise == 'true' }}
|
enterprise: ${{ github.event.inputs.enterprise == 'true' }}
|
||||||
staging: ${{ github.event.inputs.staging == 'true' }}
|
staging: ${{ github.event.inputs.staging == 'true' }}
|
||||||
architecture: ARM64
|
architecture: ARM64
|
||||||
operating_system: self-hosted
|
operating_system: self-hosted-ARM64
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
# Run and update nightly release when the nightly input is set to true or if the schedule is triggered
|
# Run and update nightly release when the nightly input is set to true or if the schedule is triggered
|
||||||
|
|
13
.github/workflows/macos.yml
vendored
13
.github/workflows/macos.yml
vendored
|
@ -27,7 +27,7 @@ on:
|
||||||
architecture:
|
architecture:
|
||||||
description: 'Architecture'
|
description: 'Architecture'
|
||||||
required: true
|
required: true
|
||||||
default: 'X64'
|
default: 'ARM64'
|
||||||
type: choice
|
type: choice
|
||||||
options:
|
options:
|
||||||
- X64
|
- X64
|
||||||
|
@ -35,10 +35,11 @@ on:
|
||||||
operating_system:
|
operating_system:
|
||||||
description: 'OS'
|
description: 'OS'
|
||||||
required: true
|
required: true
|
||||||
default: 'macos-11'
|
default: 'self-hosted-ARM64'
|
||||||
type: choice
|
type: choice
|
||||||
options:
|
options:
|
||||||
- self-hosted
|
- self-hosted-X64
|
||||||
|
- self-hosted-ARM64
|
||||||
- macos-11
|
- macos-11
|
||||||
- macos-12
|
- macos-12
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
@ -66,12 +67,12 @@ on:
|
||||||
architecture:
|
architecture:
|
||||||
description: 'Architecture'
|
description: 'Architecture'
|
||||||
required: true
|
required: true
|
||||||
default: 'X64'
|
default: 'ARM64'
|
||||||
type: string
|
type: string
|
||||||
operating_system:
|
operating_system:
|
||||||
description: 'OS'
|
description: 'OS'
|
||||||
required: true
|
required: true
|
||||||
default: 'macos-11'
|
default: 'self-hosted-ARM64'
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
@ -102,7 +103,7 @@ jobs:
|
||||||
- name: Setup Python and pip
|
- name: Setup Python and pip
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: '3.10.x'
|
python-version: '3.11.x'
|
||||||
cache: 'pip'
|
cache: 'pip'
|
||||||
cache-dependency-path: .github/workflows/requirements-conan-package.txt
|
cache-dependency-path: .github/workflows/requirements-conan-package.txt
|
||||||
|
|
||||||
|
|
|
@ -186,6 +186,13 @@ class ThreeMFReader(MeshReader):
|
||||||
if len(um_node.getAllChildren()) == 1:
|
if len(um_node.getAllChildren()) == 1:
|
||||||
# We don't want groups of one, so move the node up one "level"
|
# We don't want groups of one, so move the node up one "level"
|
||||||
child_node = um_node.getChildren()[0]
|
child_node = um_node.getChildren()[0]
|
||||||
|
# Move all the meshes of children so that toolhandles are shown in the correct place.
|
||||||
|
if child_node.getMeshData():
|
||||||
|
extents = child_node.getMeshData().getExtents()
|
||||||
|
move_matrix = Matrix()
|
||||||
|
move_matrix.translate(-extents.center)
|
||||||
|
child_node.setMeshData(child_node.getMeshData().getTransformed(move_matrix))
|
||||||
|
child_node.translate(extents.center)
|
||||||
parent_transformation = um_node.getLocalTransformation()
|
parent_transformation = um_node.getLocalTransformation()
|
||||||
child_transformation = child_node.getLocalTransformation()
|
child_transformation = child_node.getLocalTransformation()
|
||||||
child_node.setTransformation(parent_transformation.multiply(child_transformation))
|
child_node.setTransformation(parent_transformation.multiply(child_transformation))
|
||||||
|
@ -226,7 +233,8 @@ class ThreeMFReader(MeshReader):
|
||||||
if mesh_data is not None:
|
if mesh_data is not None:
|
||||||
extents = mesh_data.getExtents()
|
extents = mesh_data.getExtents()
|
||||||
if extents is not None:
|
if extents is not None:
|
||||||
center_vector = Vector(extents.center.x, extents.center.y, extents.center.z)
|
# We use a different coordinate space, so flip Z and Y
|
||||||
|
center_vector = Vector(extents.center.x, extents.center.z, extents.center.y)
|
||||||
transform_matrix.setByTranslation(center_vector)
|
transform_matrix.setByTranslation(center_vector)
|
||||||
transform_matrix.multiply(um_node.getLocalTransformation())
|
transform_matrix.multiply(um_node.getLocalTransformation())
|
||||||
um_node.setTransformation(transform_matrix)
|
um_node.setTransformation(transform_matrix)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2021-2022 Ultimaker B.V.
|
# Copyright (c) 2023 UltiMaker
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
from UM.Scene.Scene import Scene #For typing.
|
from UM.Scene.Scene import Scene #For typing.
|
||||||
from UM.Settings.Validator import ValidatorState
|
from UM.Settings.Validator import ValidatorState
|
||||||
from UM.Settings.SettingRelation import RelationType
|
from UM.Settings.SettingRelation import RelationType
|
||||||
|
from UM.Settings.SettingFunction import SettingFunction
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
from cura.Scene.CuraSceneNode import CuraSceneNode
|
from cura.Scene.CuraSceneNode import CuraSceneNode
|
||||||
|
@ -46,44 +47,60 @@ class StartJobResult(IntEnum):
|
||||||
|
|
||||||
|
|
||||||
class GcodeStartEndFormatter(Formatter):
|
class GcodeStartEndFormatter(Formatter):
|
||||||
"""Formatter class that handles token expansion in start/end gcode"""
|
# Formatter class that handles token expansion in start/end gcode
|
||||||
|
# Example of a start/end gcode string:
|
||||||
|
# ```
|
||||||
|
# M104 S{material_print_temperature_layer_0, 0} ;pre-heat
|
||||||
|
# M140 S{material_bed_temperature_layer_0} ;heat bed
|
||||||
|
# M204 P{acceleration_print, 0} T{acceleration_travel, 0}
|
||||||
|
# M205 X{jerk_print, 0}
|
||||||
|
# ```
|
||||||
|
# Any expression between curly braces will be evaluated and replaced with the result, using the
|
||||||
|
# context of the provided default extruder. If no default extruder is provided, the global stack
|
||||||
|
# will be used. Alternatively, if the expression is formatted as "{[expression], [extruder_nr]}",
|
||||||
|
# then the expression will be evaluated with the extruder stack of the specified extruder_nr.
|
||||||
|
|
||||||
def __init__(self, default_extruder_nr: int = -1) -> None:
|
_extruder_regex = re.compile(r"^\s*(?P<expression>.*)\s*,\s*(?P<extruder_nr>\d+)\s*$")
|
||||||
|
|
||||||
|
def __init__(self, default_extruder_nr: int = -1, *,
|
||||||
|
additional_per_extruder_settings: Optional[Dict[str, Dict[str, any]]] = None) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._default_extruder_nr = default_extruder_nr
|
self._default_extruder_nr: int = default_extruder_nr
|
||||||
|
self._additional_per_extruder_settings: Optional[Dict[str, Dict[str, any]]] = additional_per_extruder_settings
|
||||||
def get_value(self, key: str, args: str, kwargs: dict) -> str: #type: ignore # [CodeStyle: get_value is an overridden function from the Formatter class]
|
|
||||||
# The kwargs dictionary contains a dictionary for each stack (with a string of the extruder_nr as their key),
|
|
||||||
# and a default_extruder_nr to use when no extruder_nr is specified
|
|
||||||
|
|
||||||
|
def get_value(self, expression: str, args: [str], kwargs: dict) -> str:
|
||||||
extruder_nr = self._default_extruder_nr
|
extruder_nr = self._default_extruder_nr
|
||||||
|
|
||||||
key_fragments = [fragment.strip() for fragment in key.split(",")]
|
# The settings may specify a specific extruder to use. This is done by
|
||||||
if len(key_fragments) == 2:
|
# formatting the expression as "{expression}, {extruder_nr}". If the
|
||||||
try:
|
# expression is formatted like this, we extract the extruder_nr and use
|
||||||
extruder_nr = int(key_fragments[1])
|
# it to get the value from the correct extruder stack.
|
||||||
except ValueError:
|
match = self._extruder_regex.match(expression)
|
||||||
try:
|
if match:
|
||||||
extruder_nr = int(kwargs["-1"][key_fragments[1]]) # get extruder_nr values from the global stack #TODO: How can you ever provide the '-1' kwarg?
|
expression = match.group("expression")
|
||||||
except (KeyError, ValueError):
|
extruder_nr = int(match.group("extruder_nr"))
|
||||||
# either the key does not exist, or the value is not an int
|
|
||||||
Logger.log("w", "Unable to determine stack nr '%s' for key '%s' in start/end g-code, using global stack", key_fragments[1], key_fragments[0])
|
|
||||||
elif len(key_fragments) != 1:
|
|
||||||
Logger.log("w", "Incorrectly formatted placeholder '%s' in start/end g-code", key)
|
|
||||||
return "{" + key + "}"
|
|
||||||
|
|
||||||
key = key_fragments[0]
|
if self._additional_per_extruder_settings is not None and str(
|
||||||
|
extruder_nr) in self._additional_per_extruder_settings:
|
||||||
|
additional_variables = self._additional_per_extruder_settings[str(extruder_nr)]
|
||||||
|
else:
|
||||||
|
additional_variables = dict()
|
||||||
|
|
||||||
default_value_str = "{" + key + "}"
|
# Add the arguments and keyword arguments to the additional settings. These
|
||||||
value = default_value_str
|
# are currently _not_ used, but they are added for consistency with the
|
||||||
# "-1" is global stack, and if the setting value exists in the global stack, use it as the fallback value.
|
# base Formatter class.
|
||||||
if key in kwargs["-1"]:
|
for key, value in enumerate(args):
|
||||||
value = kwargs["-1"][key]
|
additional_variables[key] = value
|
||||||
if str(extruder_nr) in kwargs and key in kwargs[str(extruder_nr)]:
|
for key, value in kwargs.items():
|
||||||
value = kwargs[str(extruder_nr)][key]
|
additional_variables[key] = value
|
||||||
|
|
||||||
if value == default_value_str:
|
if extruder_nr == -1:
|
||||||
Logger.log("w", "Unable to replace '%s' placeholder in start/end g-code", key)
|
container_stack = CuraApplication.getInstance().getGlobalContainerStack()
|
||||||
|
else:
|
||||||
|
container_stack = ExtruderManager.getInstance().getExtruderStack(extruder_nr)
|
||||||
|
|
||||||
|
setting_function = SettingFunction(expression)
|
||||||
|
value = setting_function(container_stack, additional_variables=additional_variables)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@ -426,13 +443,14 @@ class StartSliceJob(Job):
|
||||||
self._cacheAllExtruderSettings()
|
self._cacheAllExtruderSettings()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# any setting can be used as a token
|
# Get "replacement-keys" for the extruders. In the formatter the settings stack is used to get the
|
||||||
fmt = GcodeStartEndFormatter(default_extruder_nr = default_extruder_nr)
|
# replacement values for the setting-keys. However, the values for `material_id`, `material_type`,
|
||||||
if self._all_extruders_settings is None:
|
# etc are not in the settings stack.
|
||||||
return ""
|
additional_per_extruder_settings = self._all_extruders_settings.copy()
|
||||||
settings = self._all_extruders_settings.copy()
|
additional_per_extruder_settings["default_extruder_nr"] = default_extruder_nr
|
||||||
settings["default_extruder_nr"] = default_extruder_nr
|
fmt = GcodeStartEndFormatter(default_extruder_nr=default_extruder_nr,
|
||||||
return str(fmt.format(value, **settings))
|
additional_per_extruder_settings=additional_per_extruder_settings)
|
||||||
|
return str(fmt.format(value))
|
||||||
except:
|
except:
|
||||||
Logger.logException("w", "Unable to do token replacement on start/end g-code")
|
Logger.logException("w", "Unable to do token replacement on start/end g-code")
|
||||||
return str(value)
|
return str(value)
|
||||||
|
|
|
@ -380,6 +380,14 @@ msgctxt "machine_max_feedrate_x label"
|
||||||
msgid "Maximum Speed X"
|
msgid "Maximum Speed X"
|
||||||
msgstr "Velocidad máxima sobre el eje X"
|
msgstr "Velocidad máxima sobre el eje X"
|
||||||
|
|
||||||
|
msgctxt "lightning_infill_support_angle description"
|
||||||
|
msgid "Determines when a lightning infill layer has to support anything above it. Measured in the angle given the thickness of a layer."
|
||||||
|
msgstr "Determina cuándo una capa de relleno de rayos tiene que soportar algo por encima de ella. Medido en el ángulo dado el espesor de una capa."
|
||||||
|
|
||||||
|
msgctxt "lightning_infill_overhang_angle description"
|
||||||
|
msgid "Determines when a lightning infill layer has to support the model above it. Measured in the angle given the thickness."
|
||||||
|
msgstr "Determina cuándo una capa de relleno de rayos tiene que soportar el modelo que está por encima. Medido en el ángulo dado el espesor."
|
||||||
|
|
||||||
msgctxt "machine_max_feedrate_x description"
|
msgctxt "machine_max_feedrate_x description"
|
||||||
msgid "The maximum speed for the motor of the X-direction."
|
msgid "The maximum speed for the motor of the X-direction."
|
||||||
msgstr "Velocidad máxima del motor de la dirección X."
|
msgstr "Velocidad máxima del motor de la dirección X."
|
||||||
|
@ -1438,7 +1446,7 @@ msgstr "Patrón de relleno"
|
||||||
|
|
||||||
msgctxt "infill_pattern description"
|
msgctxt "infill_pattern description"
|
||||||
msgid "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle, tri-hexagon, cubic, octet, quarter cubic, cross and concentric patterns are fully printed every layer. Gyroid, cubic, quarter cubic and octet infill change with every layer to provide a more equal distribution of strength over each direction. Lightning infill tries to minimize the infill, by only supporting the ceiling of the object."
|
msgid "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle, tri-hexagon, cubic, octet, quarter cubic, cross and concentric patterns are fully printed every layer. Gyroid, cubic, quarter cubic and octet infill change with every layer to provide a more equal distribution of strength over each direction. Lightning infill tries to minimize the infill, by only supporting the ceiling of the object."
|
||||||
msgstr "Patrón del material de relleno de la impresión. El método de llenado en línea y en zigzag cambia de dirección en capas alternas para reducir los costes de material. Los patrones de rejilla, triángulo, trihexágono, cubo, octaédrico, cubo bitruncado, transversal y concéntrico se imprimen en todas las capas por completo. Los rellenos de giroide, cúbico, cúbico bitruncado y octaédrico se alternan en cada capa para lograr una distribución más uniforme de la fuerza en todas las direcciones. El relleno de iluminación intenta minimizar el relleno apoyando solo la parte superior del objeto."
|
msgstr "Patrón del material de relleno de la impresión. El método de llenado en línea y en zigzag cambia de dirección en capas alternas para reducir los costes de material. Los patrones de rejilla, triángulo, trihexágono, cubo, octaédrico, cubo bitruncado, transversal y concéntrico se imprimen en todas las capas por completo. Los rellenos de giroide, cúbico, cúbico bitruncado y octaédrico se alternan en cada capa para lograr una distribución más uniforme de la fuerza en todas las direcciones. El relleno de rayos intenta minimizar el relleno apoyando solo la parte superior del objeto."
|
||||||
|
|
||||||
msgctxt "infill_pattern option grid"
|
msgctxt "infill_pattern option grid"
|
||||||
msgid "Grid"
|
msgid "Grid"
|
||||||
|
@ -1494,7 +1502,23 @@ msgstr "Giroide"
|
||||||
|
|
||||||
msgctxt "infill_pattern option lightning"
|
msgctxt "infill_pattern option lightning"
|
||||||
msgid "Lightning"
|
msgid "Lightning"
|
||||||
msgstr "Iluminación"
|
msgstr "Rayos"
|
||||||
|
|
||||||
|
msgctxt "lightning_infill_overhang_angle label"
|
||||||
|
msgid "Lightning Infill Overhang Angle"
|
||||||
|
msgstr "Ángulo del voladizo de relleno de rayos"
|
||||||
|
|
||||||
|
msgctxt "lightning_infill_prune_angle label"
|
||||||
|
msgid "Lightning Infill Prune Angle"
|
||||||
|
msgstr "Ángulo de recorte de relleno de rayos"
|
||||||
|
|
||||||
|
msgctxt "lightning_infill_straightening_angle label"
|
||||||
|
msgid "Lightning Infill Straightening Angle"
|
||||||
|
msgstr "Ángulo de enderezamiento de rayos"
|
||||||
|
|
||||||
|
msgctxt "lightning_infill_support_angle label"
|
||||||
|
msgid "Lightning Infill Support Angle"
|
||||||
|
msgstr "Ángulo de sujeción de relleno de rayos"
|
||||||
|
|
||||||
msgctxt "zig_zaggify_infill label"
|
msgctxt "zig_zaggify_infill label"
|
||||||
msgid "Connect Infill Lines"
|
msgid "Connect Infill Lines"
|
||||||
|
@ -1664,34 +1688,10 @@ msgctxt "skin_edge_support_layers description"
|
||||||
msgid "The number of infill layers that supports skin edges."
|
msgid "The number of infill layers that supports skin edges."
|
||||||
msgstr "El número de capas de relleno que soportan los bordes del forro."
|
msgstr "El número de capas de relleno que soportan los bordes del forro."
|
||||||
|
|
||||||
msgctxt "lightning_infill_support_angle label"
|
|
||||||
msgid "Lightning Infill Support Angle"
|
|
||||||
msgstr "Ángulo de sujeción de relleno de iluminación"
|
|
||||||
|
|
||||||
msgctxt "lightning_infill_support_angle description"
|
|
||||||
msgid "Determines when a lightning infill layer has to support anything above it. Measured in the angle given the thickness of a layer."
|
|
||||||
msgstr "Determina cuándo una capa de iluminación tiene que soportar algo por encima de ella. Medido en el ángulo dado el espesor de una capa."
|
|
||||||
|
|
||||||
msgctxt "lightning_infill_overhang_angle label"
|
|
||||||
msgid "Lightning Infill Overhang Angle"
|
|
||||||
msgstr "Ángulo del voladizo de relleno de iluminación"
|
|
||||||
|
|
||||||
msgctxt "lightning_infill_overhang_angle description"
|
|
||||||
msgid "Determines when a lightning infill layer has to support the model above it. Measured in the angle given the thickness."
|
|
||||||
msgstr "Determina cuándo una capa de relleno de iluminación tiene que soportar el modelo que está por encima. Medido en el ángulo dado el espesor."
|
|
||||||
|
|
||||||
msgctxt "lightning_infill_prune_angle label"
|
|
||||||
msgid "Lightning Infill Prune Angle"
|
|
||||||
msgstr "Ángulo de recorte de relleno de iluminación"
|
|
||||||
|
|
||||||
msgctxt "lightning_infill_prune_angle description"
|
msgctxt "lightning_infill_prune_angle description"
|
||||||
msgid "The endpoints of infill lines are shortened to save on material. This setting is the angle of overhang of the endpoints of these lines."
|
msgid "The endpoints of infill lines are shortened to save on material. This setting is the angle of overhang of the endpoints of these lines."
|
||||||
msgstr "Los extremos de las líneas de relleno se acortan para ahorrar material. Esta configuración es el ángulo de voladizo de los extremos de estas líneas."
|
msgstr "Los extremos de las líneas de relleno se acortan para ahorrar material. Esta configuración es el ángulo de voladizo de los extremos de estas líneas."
|
||||||
|
|
||||||
msgctxt "lightning_infill_straightening_angle label"
|
|
||||||
msgid "Lightning Infill Straightening Angle"
|
|
||||||
msgstr "Ángulo de enderezamiento de iluminación"
|
|
||||||
|
|
||||||
msgctxt "lightning_infill_straightening_angle description"
|
msgctxt "lightning_infill_straightening_angle description"
|
||||||
msgid "The infill lines are straightened out to save on printing time. This is the maximum angle of overhang allowed across the length of the infill line."
|
msgid "The infill lines are straightened out to save on printing time. This is the maximum angle of overhang allowed across the length of the infill line."
|
||||||
msgstr "Las líneas de relleno se simplifican para ahorrar tiempo al imprimir. Este es el ángulo máximo permitido del voladizo sobre la longitud de la línea de relleno."
|
msgstr "Las líneas de relleno se simplifican para ahorrar tiempo al imprimir. Este es el ángulo máximo permitido del voladizo sobre la longitud de la línea de relleno."
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue