mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-07-26 08:44:28 +08:00
Merge branch 'main' into CURA-9514_collapsable_printers_list
This commit is contained in:
commit
d1ae3136aa
3
.github/workflows/conan-recipe-version.yml
vendored
3
.github/workflows/conan-recipe-version.yml
vendored
@ -135,6 +135,9 @@ jobs:
|
|||||||
user = "_"
|
user = "_"
|
||||||
channel = "_"
|
channel = "_"
|
||||||
else:
|
else:
|
||||||
|
if latest_branch_version.prerelease and not "." in latest_branch_version.prerelease:
|
||||||
|
# The prerealese did not contain a version number, default it to 1
|
||||||
|
latest_branch_version.prerelease += ".1"
|
||||||
if event_name == "pull_request":
|
if event_name == "pull_request":
|
||||||
actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{latest_branch_version.prerelease.lower()}+{buildmetadata}pr_{issue_number}_{no_commits}"
|
actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{latest_branch_version.prerelease.lower()}+{buildmetadata}pr_{issue_number}_{no_commits}"
|
||||||
else:
|
else:
|
||||||
|
@ -11,3 +11,4 @@ CuraCloudAPIVersion = "{{ cura_cloud_api_version }}"
|
|||||||
CuraCloudAccountAPIRoot = "{{ cura_cloud_account_api_root }}"
|
CuraCloudAccountAPIRoot = "{{ cura_cloud_account_api_root }}"
|
||||||
CuraMarketplaceRoot = "{{ cura_marketplace_root }}"
|
CuraMarketplaceRoot = "{{ cura_marketplace_root }}"
|
||||||
CuraDigitalFactoryURL = "{{ cura_digital_factory_url }}"
|
CuraDigitalFactoryURL = "{{ cura_digital_factory_url }}"
|
||||||
|
CuraLatestURL = "{{ cura_latest_url }}"
|
||||||
|
@ -100,6 +100,10 @@ class CuraConan(ConanFile):
|
|||||||
def _digital_factory_url(self):
|
def _digital_factory_url(self):
|
||||||
return "https://digitalfactory-staging.ultimaker.com" if self._staging else "https://digitalfactory.ultimaker.com"
|
return "https://digitalfactory-staging.ultimaker.com" if self._staging else "https://digitalfactory.ultimaker.com"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _cura_latest_url(self):
|
||||||
|
return "https://software.ultimaker.com/latest.json"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def requirements_txts(self):
|
def requirements_txts(self):
|
||||||
if self.options.devtools:
|
if self.options.devtools:
|
||||||
@ -161,7 +165,8 @@ class CuraConan(ConanFile):
|
|||||||
cura_cloud_api_version = self.options.cloud_api_version,
|
cura_cloud_api_version = self.options.cloud_api_version,
|
||||||
cura_cloud_account_api_root = self._cloud_account_api_root,
|
cura_cloud_account_api_root = self._cloud_account_api_root,
|
||||||
cura_marketplace_root = self._marketplace_root,
|
cura_marketplace_root = self._marketplace_root,
|
||||||
cura_digital_factory_url = self._digital_factory_url))
|
cura_digital_factory_url = self._digital_factory_url,
|
||||||
|
cura_latest_url = self._cura_latest_url))
|
||||||
|
|
||||||
def _generate_pyinstaller_spec(self, location, entrypoint_location, icon_path, entitlements_file):
|
def _generate_pyinstaller_spec(self, location, entrypoint_location, icon_path, entitlements_file):
|
||||||
pyinstaller_metadata = self._um_data()["pyinstaller"]
|
pyinstaller_metadata = self._um_data()["pyinstaller"]
|
||||||
|
@ -9,12 +9,20 @@ DEFAULT_CURA_DISPLAY_NAME = "Ultimaker Cura"
|
|||||||
DEFAULT_CURA_VERSION = "dev"
|
DEFAULT_CURA_VERSION = "dev"
|
||||||
DEFAULT_CURA_BUILD_TYPE = ""
|
DEFAULT_CURA_BUILD_TYPE = ""
|
||||||
DEFAULT_CURA_DEBUG_MODE = False
|
DEFAULT_CURA_DEBUG_MODE = False
|
||||||
|
DEFAULT_CURA_LATEST_URL = "https://software.ultimaker.com/latest.json"
|
||||||
|
|
||||||
# Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for
|
# Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for
|
||||||
# example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the
|
# example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the
|
||||||
# CuraVersion.py.in template.
|
# CuraVersion.py.in template.
|
||||||
CuraSDKVersion = "8.1.0"
|
CuraSDKVersion = "8.1.0"
|
||||||
|
|
||||||
|
try:
|
||||||
|
from cura.CuraVersion import CuraLatestURL
|
||||||
|
if CuraLatestURL == "":
|
||||||
|
CuraLatestURL = DEFAULT_CURA_LATEST_URL
|
||||||
|
except ImportError:
|
||||||
|
CuraLatestURL = DEFAULT_CURA_LATEST_URL
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from cura.CuraVersion import CuraAppName # type: ignore
|
from cura.CuraVersion import CuraAppName # type: ignore
|
||||||
if CuraAppName == "":
|
if CuraAppName == "":
|
||||||
|
@ -145,6 +145,8 @@ class CuraApplication(QtApplication):
|
|||||||
DefinitionChangesContainer = Resources.UserType + 10
|
DefinitionChangesContainer = Resources.UserType + 10
|
||||||
SettingVisibilityPreset = Resources.UserType + 11
|
SettingVisibilityPreset = Resources.UserType + 11
|
||||||
IntentInstanceContainer = Resources.UserType + 12
|
IntentInstanceContainer = Resources.UserType + 12
|
||||||
|
AbstractMachineStack = Resources.UserType + 13
|
||||||
|
|
||||||
|
|
||||||
pyqtEnum(ResourceTypes)
|
pyqtEnum(ResourceTypes)
|
||||||
|
|
||||||
@ -152,6 +154,7 @@ class CuraApplication(QtApplication):
|
|||||||
super().__init__(name = ApplicationMetadata.CuraAppName,
|
super().__init__(name = ApplicationMetadata.CuraAppName,
|
||||||
app_display_name = ApplicationMetadata.CuraAppDisplayName,
|
app_display_name = ApplicationMetadata.CuraAppDisplayName,
|
||||||
version = ApplicationMetadata.CuraVersion if not ApplicationMetadata.IsAlternateVersion else ApplicationMetadata.CuraBuildType,
|
version = ApplicationMetadata.CuraVersion if not ApplicationMetadata.IsAlternateVersion else ApplicationMetadata.CuraBuildType,
|
||||||
|
latest_url = ApplicationMetadata.CuraLatestURL,
|
||||||
api_version = ApplicationMetadata.CuraSDKVersion,
|
api_version = ApplicationMetadata.CuraSDKVersion,
|
||||||
build_type = ApplicationMetadata.CuraBuildType,
|
build_type = ApplicationMetadata.CuraBuildType,
|
||||||
is_debug_mode = ApplicationMetadata.CuraDebugMode,
|
is_debug_mode = ApplicationMetadata.CuraDebugMode,
|
||||||
@ -422,6 +425,7 @@ class CuraApplication(QtApplication):
|
|||||||
Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
|
Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
|
||||||
Resources.addStorageType(self.ResourceTypes.SettingVisibilityPreset, "setting_visibility")
|
Resources.addStorageType(self.ResourceTypes.SettingVisibilityPreset, "setting_visibility")
|
||||||
Resources.addStorageType(self.ResourceTypes.IntentInstanceContainer, "intent")
|
Resources.addStorageType(self.ResourceTypes.IntentInstanceContainer, "intent")
|
||||||
|
Resources.addStorageType(self.ResourceTypes.AbstractMachineStack, "abstract_machine_instances")
|
||||||
|
|
||||||
self._container_registry.addResourceType(self.ResourceTypes.QualityInstanceContainer, "quality")
|
self._container_registry.addResourceType(self.ResourceTypes.QualityInstanceContainer, "quality")
|
||||||
self._container_registry.addResourceType(self.ResourceTypes.QualityChangesInstanceContainer, "quality_changes")
|
self._container_registry.addResourceType(self.ResourceTypes.QualityChangesInstanceContainer, "quality_changes")
|
||||||
@ -432,6 +436,7 @@ class CuraApplication(QtApplication):
|
|||||||
self._container_registry.addResourceType(self.ResourceTypes.MachineStack, "machine")
|
self._container_registry.addResourceType(self.ResourceTypes.MachineStack, "machine")
|
||||||
self._container_registry.addResourceType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
|
self._container_registry.addResourceType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
|
||||||
self._container_registry.addResourceType(self.ResourceTypes.IntentInstanceContainer, "intent")
|
self._container_registry.addResourceType(self.ResourceTypes.IntentInstanceContainer, "intent")
|
||||||
|
self._container_registry.addResourceType(self.ResourceTypes.AbstractMachineStack, "abstract_machine")
|
||||||
|
|
||||||
Resources.addType(self.ResourceTypes.QmlFiles, "qml")
|
Resources.addType(self.ResourceTypes.QmlFiles, "qml")
|
||||||
Resources.addType(self.ResourceTypes.Firmware, "firmware")
|
Resources.addType(self.ResourceTypes.Firmware, "firmware")
|
||||||
@ -480,6 +485,7 @@ class CuraApplication(QtApplication):
|
|||||||
("variant", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.VariantInstanceContainer, "application/x-uranium-instancecontainer"),
|
("variant", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.VariantInstanceContainer, "application/x-uranium-instancecontainer"),
|
||||||
("setting_visibility", SettingVisibilityPresetsModel.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.SettingVisibilityPreset, "application/x-uranium-preferences"),
|
("setting_visibility", SettingVisibilityPresetsModel.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.SettingVisibilityPreset, "application/x-uranium-preferences"),
|
||||||
("machine", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"),
|
("machine", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"),
|
||||||
|
("abstract_machine", 1): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"),
|
||||||
("extruder", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer")
|
("extruder", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
35
cura/Settings/AbstractMachine.py
Normal file
35
cura/Settings/AbstractMachine.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
from UM.Settings.ContainerStack import ContainerStack
|
||||||
|
from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
||||||
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractMachine(GlobalStack):
|
||||||
|
""" Represents a group of machines of the same type. This allows the user to select settings before selecting a printer. """
|
||||||
|
|
||||||
|
def __init__(self, container_id: str) -> None:
|
||||||
|
super().__init__(container_id)
|
||||||
|
self.setMetaDataEntry("type", "abstract_machine")
|
||||||
|
|
||||||
|
def getMachines(self) -> List[ContainerStack]:
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
|
application = CuraApplication.getInstance()
|
||||||
|
registry = application.getContainerRegistry()
|
||||||
|
|
||||||
|
printer_type = self.definition.getId()
|
||||||
|
return [machine for machine in registry.findContainerStacks(type="machine") if machine.definition.id == printer_type and ConnectionType.CloudConnection in machine.configuredConnectionTypes]
|
||||||
|
|
||||||
|
|
||||||
|
## private:
|
||||||
|
_abstract_machine_mime = MimeType(
|
||||||
|
name = "application/x-cura-abstract-machine",
|
||||||
|
comment = "Cura Abstract Machine",
|
||||||
|
suffixes = ["global.cfg"]
|
||||||
|
)
|
||||||
|
|
||||||
|
MimeTypeDatabase.addMimeType(_abstract_machine_mime)
|
||||||
|
ContainerRegistry.addContainerTypeByName(AbstractMachine, "abstract_machine", _abstract_machine_mime.name)
|
@ -108,7 +108,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
:param container_type: :type{string} Type of the container (machine, quality, ...)
|
:param container_type: :type{string} Type of the container (machine, quality, ...)
|
||||||
:param container_name: :type{string} Name to check
|
:param container_name: :type{string} Name to check
|
||||||
"""
|
"""
|
||||||
container_class = ContainerStack if container_type == "machine" else InstanceContainer
|
container_class = ContainerStack if "machine" in container_type else InstanceContainer
|
||||||
|
|
||||||
return self.findContainersMetadata(container_type = container_class, id = container_name, type = container_type, ignore_case = True) or \
|
return self.findContainersMetadata(container_type = container_class, id = container_name, type = container_type, ignore_case = True) or \
|
||||||
self.findContainersMetadata(container_type = container_class, name = container_name, type = container_type)
|
self.findContainersMetadata(container_type = container_class, name = container_name, type = container_type)
|
||||||
|
@ -427,4 +427,4 @@ class _ContainerIndexes:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Reverse lookup: type -> index
|
# Reverse lookup: type -> index
|
||||||
TypeIndexMap = dict([(v, k) for k, v in IndexTypeMap.items()])
|
TypeIndexMap = {v: k for k, v in IndexTypeMap.items()}
|
||||||
|
@ -9,6 +9,7 @@ from UM.Settings.Interfaces import DefinitionContainerInterface
|
|||||||
from UM.Settings.InstanceContainer import InstanceContainer
|
from UM.Settings.InstanceContainer import InstanceContainer
|
||||||
|
|
||||||
from cura.Machines.ContainerTree import ContainerTree
|
from cura.Machines.ContainerTree import ContainerTree
|
||||||
|
from .AbstractMachine import AbstractMachine
|
||||||
from .GlobalStack import GlobalStack
|
from .GlobalStack import GlobalStack
|
||||||
from .ExtruderStack import ExtruderStack
|
from .ExtruderStack import ExtruderStack
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ class CuraStackBuilder:
|
|||||||
:return: The new global stack or None if an error occurred.
|
:return: The new global stack or None if an error occurred.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication # inline import needed due to circular import
|
||||||
application = CuraApplication.getInstance()
|
application = CuraApplication.getInstance()
|
||||||
registry = application.getContainerRegistry()
|
registry = application.getContainerRegistry()
|
||||||
container_tree = ContainerTree.getInstance()
|
container_tree = ContainerTree.getInstance()
|
||||||
@ -91,7 +92,7 @@ class CuraStackBuilder:
|
|||||||
:param extruder_position: The position of the current extruder.
|
:param extruder_position: The position of the current extruder.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication # inline import needed due to circular import
|
||||||
application = CuraApplication.getInstance()
|
application = CuraApplication.getInstance()
|
||||||
registry = application.getContainerRegistry()
|
registry = application.getContainerRegistry()
|
||||||
|
|
||||||
@ -199,13 +200,21 @@ class CuraStackBuilder:
|
|||||||
|
|
||||||
:return: A new Global stack instance with the specified parameters.
|
:return: A new Global stack instance with the specified parameters.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
|
||||||
application = CuraApplication.getInstance()
|
|
||||||
registry = application.getContainerRegistry()
|
|
||||||
|
|
||||||
stack = GlobalStack(new_stack_id)
|
stack = GlobalStack(new_stack_id)
|
||||||
stack.setDefinition(definition)
|
stack.setDefinition(definition)
|
||||||
|
cls.createUserContainer(new_stack_id, definition, stack, variant_container, material_container, quality_container)
|
||||||
|
return stack
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def createUserContainer(cls, new_stack_id: str, definition: DefinitionContainerInterface,
|
||||||
|
stack: GlobalStack,
|
||||||
|
variant_container: "InstanceContainer",
|
||||||
|
material_container: "InstanceContainer",
|
||||||
|
quality_container: "InstanceContainer") -> None:
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
application = CuraApplication.getInstance()
|
||||||
|
|
||||||
|
registry = application.getContainerRegistry()
|
||||||
|
|
||||||
# Create user container
|
# Create user container
|
||||||
user_container = cls.createUserChangesContainer(new_stack_id + "_user", definition.getId(), new_stack_id,
|
user_container = cls.createUserChangesContainer(new_stack_id + "_user", definition.getId(), new_stack_id,
|
||||||
@ -221,8 +230,6 @@ class CuraStackBuilder:
|
|||||||
|
|
||||||
registry.addContainer(user_container)
|
registry.addContainer(user_container)
|
||||||
|
|
||||||
return stack
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def createUserChangesContainer(cls, container_name: str, definition_id: str, stack_id: str,
|
def createUserChangesContainer(cls, container_name: str, definition_id: str, stack_id: str,
|
||||||
is_global_stack: bool) -> "InstanceContainer":
|
is_global_stack: bool) -> "InstanceContainer":
|
||||||
@ -259,3 +266,49 @@ class CuraStackBuilder:
|
|||||||
container_stack.definitionChanges = definition_changes_container
|
container_stack.definitionChanges = definition_changes_container
|
||||||
|
|
||||||
return definition_changes_container
|
return definition_changes_container
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def createAbstractMachine(cls, definition_id: str) -> Optional[AbstractMachine]:
|
||||||
|
"""Create a new instance of an abstract machine.
|
||||||
|
|
||||||
|
:param definition_id: The ID of the machine definition to use.
|
||||||
|
|
||||||
|
:return: The new Abstract Machine or None if an error occurred.
|
||||||
|
"""
|
||||||
|
abstract_machine_id = definition_id + "_abstract_machine"
|
||||||
|
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
application = CuraApplication.getInstance()
|
||||||
|
registry = application.getContainerRegistry()
|
||||||
|
container_tree = ContainerTree.getInstance()
|
||||||
|
|
||||||
|
if registry.findContainerStacks(type = "abstract_machine", id = abstract_machine_id):
|
||||||
|
# This abstract machine already exists
|
||||||
|
return None
|
||||||
|
|
||||||
|
match registry.findDefinitionContainers(type = "machine", id = definition_id):
|
||||||
|
case []:
|
||||||
|
# It should not be possible for the definition to be missing since an abstract machine will only
|
||||||
|
# be created as a result of a machine with definition_id being created.
|
||||||
|
Logger.error(f"Definition {definition_id} was not found!")
|
||||||
|
return None
|
||||||
|
case [machine_definition, *_definitions]:
|
||||||
|
machine_node = container_tree.machines[machine_definition.getId()]
|
||||||
|
name = machine_definition.getName()
|
||||||
|
|
||||||
|
stack = AbstractMachine(abstract_machine_id)
|
||||||
|
stack.setDefinition(machine_definition)
|
||||||
|
cls.createUserContainer(
|
||||||
|
name,
|
||||||
|
machine_definition,
|
||||||
|
stack,
|
||||||
|
application.empty_variant_container,
|
||||||
|
application.empty_material_container,
|
||||||
|
machine_node.preferredGlobalQuality().container,
|
||||||
|
)
|
||||||
|
|
||||||
|
stack.setName(name)
|
||||||
|
|
||||||
|
registry.addContainer(stack)
|
||||||
|
|
||||||
|
return stack
|
||||||
|
@ -400,11 +400,13 @@ class CloudOutputDeviceManager:
|
|||||||
# We do not use use MachineManager.addMachine here because we need to set the cluster ID before activating it.
|
# We do not use use MachineManager.addMachine here because we need to set the cluster ID before activating it.
|
||||||
new_machine = CuraStackBuilder.createMachine(device.name, device.printerType, show_warning_message=False)
|
new_machine = CuraStackBuilder.createMachine(device.name, device.printerType, show_warning_message=False)
|
||||||
if not new_machine:
|
if not new_machine:
|
||||||
Logger.log("e", "Failed creating a new machine")
|
Logger.error(f"Failed creating a new machine for {device.name}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self._setOutputDeviceMetadata(device, new_machine)
|
self._setOutputDeviceMetadata(device, new_machine)
|
||||||
|
|
||||||
|
_abstract_machine = CuraStackBuilder.createAbstractMachine(device.printerType)
|
||||||
|
|
||||||
if activate:
|
if activate:
|
||||||
CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId())
|
CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId())
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user