mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-09 06:45:09 -06:00
Merge branch 'master' of github.com:Ultimaker/Cura into network_rewrite
This commit is contained in:
commit
219e285b20
112 changed files with 30880 additions and 14277 deletions
|
@ -4,6 +4,7 @@
|
|||
import os
|
||||
import os.path
|
||||
import re
|
||||
import configparser
|
||||
|
||||
from typing import Optional
|
||||
|
||||
|
@ -19,6 +20,7 @@ from UM.Message import Message
|
|||
from UM.Platform import Platform
|
||||
from UM.PluginRegistry import PluginRegistry # For getting the possible profile writers to write with.
|
||||
from UM.Util import parseBool
|
||||
from UM.Resources import Resources
|
||||
|
||||
from . import ExtruderStack
|
||||
from . import GlobalStack
|
||||
|
@ -409,7 +411,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
extruder_stack = None
|
||||
|
||||
# if extruders are defined in the machine definition use those instead
|
||||
if machine.extruders and len(machine.extruders) > 0:
|
||||
if machine.extruders and "0" in machine.extruders:
|
||||
new_extruder_id = machine.extruders["0"].getId()
|
||||
extruder_stack = machine.extruders["0"]
|
||||
|
||||
|
@ -444,14 +446,84 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
self.addContainer(user_container)
|
||||
|
||||
variant_id = "default"
|
||||
if machine.variant.getId() != "empty_variant":
|
||||
if machine.variant.getId() not in ("empty", "empty_variant"):
|
||||
variant_id = machine.variant.getId()
|
||||
else:
|
||||
variant_id = "empty_variant"
|
||||
extruder_stack.setVariantById(variant_id)
|
||||
extruder_stack.setMaterialById("default")
|
||||
extruder_stack.setQualityById("default")
|
||||
|
||||
material_id = "default"
|
||||
if machine.material.getId() not in ("empty", "empty_material"):
|
||||
# TODO: find the ID that's suitable for this extruder
|
||||
pass
|
||||
else:
|
||||
material_id = "empty_material"
|
||||
extruder_stack.setMaterialById(material_id)
|
||||
|
||||
quality_id = "default"
|
||||
if machine.quality.getId() not in ("empty", "empty_quality"):
|
||||
# TODO: find the ID that's suitable for this extruder
|
||||
pass
|
||||
else:
|
||||
quality_id = "empty_quality"
|
||||
extruder_stack.setQualityById(quality_id)
|
||||
|
||||
if machine.qualityChanges.getId() not in ("empty", "empty_quality_changes"):
|
||||
extruder_quality_changes_container = self.findInstanceContainers(name = machine.qualityChanges.getName(), extruder = extruder_id)
|
||||
if extruder_quality_changes_container:
|
||||
extruder_quality_changes_container = extruder_quality_changes_container[0]
|
||||
quality_changes_id = extruder_quality_changes_container.getId()
|
||||
extruder_stack.setQualityChangesById(quality_changes_id)
|
||||
else:
|
||||
# Some extruder quality_changes containers can be created at runtime as files in the qualities
|
||||
# folder. Those files won't be loaded in the registry immediately. So we also need to search
|
||||
# the folder to see if the quality_changes exists.
|
||||
extruder_quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine.qualityChanges.getName())
|
||||
if extruder_quality_changes_container:
|
||||
quality_changes_id = extruder_quality_changes_container.getId()
|
||||
extruder_stack.setQualityChangesById(quality_changes_id)
|
||||
|
||||
if not extruder_quality_changes_container:
|
||||
Logger.log("w", "Could not find quality_changes named [%s] for extruder [%s]",
|
||||
machine.qualityChanges.getName(), extruder_stack.getId())
|
||||
|
||||
self.addContainer(extruder_stack)
|
||||
|
||||
return extruder_stack
|
||||
|
||||
def _findQualityChangesContainerInCuraFolder(self, name):
|
||||
quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer)
|
||||
|
||||
instance_container = None
|
||||
|
||||
for item in os.listdir(quality_changes_dir):
|
||||
file_path = os.path.join(quality_changes_dir, item)
|
||||
if not os.path.isfile(file_path):
|
||||
continue
|
||||
|
||||
parser = configparser.ConfigParser()
|
||||
try:
|
||||
parser.read([file_path])
|
||||
except:
|
||||
# skip, it is not a valid stack file
|
||||
continue
|
||||
|
||||
if not parser.has_option("general", "name"):
|
||||
continue
|
||||
|
||||
if parser["general"]["name"] == name:
|
||||
# load the container
|
||||
container_id = os.path.basename(file_path).replace(".inst.cfg", "")
|
||||
|
||||
instance_container = InstanceContainer(container_id)
|
||||
with open(file_path, "r") as f:
|
||||
serialized = f.read()
|
||||
instance_container.deserialize(serialized, file_path)
|
||||
self.addContainer(instance_container)
|
||||
break
|
||||
|
||||
return instance_container
|
||||
|
||||
# Fix the extruders that were upgraded to ExtruderStack instances during addContainer.
|
||||
# The stacks are now responsible for setting the next stack on deserialize. However,
|
||||
# due to problems with loading order, some stacks may not have the proper next stack
|
||||
|
|
|
@ -41,9 +41,20 @@ class CuraContainerStack(ContainerStack):
|
|||
def __init__(self, container_id: str, *args, **kwargs):
|
||||
super().__init__(container_id, *args, **kwargs)
|
||||
|
||||
self._empty_instance_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
|
||||
self._container_registry = ContainerRegistry.getInstance()
|
||||
|
||||
self._empty_instance_container = self._container_registry.getEmptyInstanceContainer()
|
||||
|
||||
self._empty_quality_changes = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0]
|
||||
self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0]
|
||||
self._empty_material = self._container_registry.findInstanceContainers(id = "empty_material")[0]
|
||||
self._empty_variant = self._container_registry.findInstanceContainers(id = "empty_variant")[0]
|
||||
|
||||
self._containers = [self._empty_instance_container for i in range(len(_ContainerIndexes.IndexTypeMap))]
|
||||
self._containers[_ContainerIndexes.QualityChanges] = self._empty_quality_changes
|
||||
self._containers[_ContainerIndexes.Quality] = self._empty_quality
|
||||
self._containers[_ContainerIndexes.Material] = self._empty_material
|
||||
self._containers[_ContainerIndexes.Variant] = self._empty_variant
|
||||
|
||||
self.containersChanged.connect(self._onContainersChanged)
|
||||
|
||||
|
@ -348,8 +359,8 @@ class CuraContainerStack(ContainerStack):
|
|||
#
|
||||
# \throws InvalidContainerStackError Raised when no definition can be found for the stack.
|
||||
@override(ContainerStack)
|
||||
def deserialize(self, contents: str) -> None:
|
||||
super().deserialize(contents)
|
||||
def deserialize(self, contents: str, file_name: Optional[str] = None) -> None:
|
||||
super().deserialize(contents, file_name)
|
||||
|
||||
new_containers = self._containers.copy()
|
||||
while len(new_containers) < len(_ContainerIndexes.IndexTypeMap):
|
||||
|
@ -456,7 +467,7 @@ class CuraContainerStack(ContainerStack):
|
|||
else:
|
||||
search_criteria["definition"] = "fdmprinter"
|
||||
|
||||
if self.material != self._empty_instance_container:
|
||||
if self.material != self._empty_material:
|
||||
search_criteria["name"] = self.material.name
|
||||
else:
|
||||
preferred_material = definition.getMetaDataEntry("preferred_material")
|
||||
|
@ -503,7 +514,7 @@ class CuraContainerStack(ContainerStack):
|
|||
else:
|
||||
search_criteria["definition"] = "fdmprinter"
|
||||
|
||||
if self.quality != self._empty_instance_container:
|
||||
if self.quality != self._empty_quality:
|
||||
search_criteria["name"] = self.quality.name
|
||||
else:
|
||||
preferred_quality = definition.getMetaDataEntry("preferred_quality")
|
||||
|
|
|
@ -92,8 +92,8 @@ class ExtruderStack(CuraContainerStack):
|
|||
return self.getNextStack()._getMachineDefinition()
|
||||
|
||||
@override(CuraContainerStack)
|
||||
def deserialize(self, contents: str) -> None:
|
||||
super().deserialize(contents)
|
||||
def deserialize(self, contents: str, file_name: Optional[str] = None) -> None:
|
||||
super().deserialize(contents, file_name)
|
||||
stacks = ContainerRegistry.getInstance().findContainerStacks(id=self.getMetaDataEntry("machine", ""))
|
||||
if stacks:
|
||||
self.setNextStack(stacks[0])
|
||||
|
|
|
@ -620,12 +620,17 @@ class MachineManager(QObject):
|
|||
@pyqtProperty(str, notify=activeQualityChanged)
|
||||
def activeQualityId(self) -> str:
|
||||
if self._active_container_stack:
|
||||
quality = self._active_container_stack.qualityChanges
|
||||
if quality and not isinstance(quality, type(self._empty_quality_changes_container)):
|
||||
return quality.getId()
|
||||
quality = self._active_container_stack.quality
|
||||
if quality:
|
||||
return quality.getId()
|
||||
if isinstance(quality, type(self._empty_quality_container)):
|
||||
return ""
|
||||
quality_changes = self._active_container_stack.qualityChanges
|
||||
if quality and quality_changes:
|
||||
if isinstance(quality_changes, type(self._empty_quality_changes_container)):
|
||||
# It's a built-in profile
|
||||
return quality.getId()
|
||||
else:
|
||||
# Custom profile
|
||||
return quality_changes.getId()
|
||||
return ""
|
||||
|
||||
@pyqtProperty(str, notify=activeQualityChanged)
|
||||
|
@ -690,9 +695,9 @@ class MachineManager(QObject):
|
|||
@pyqtProperty(str, notify = activeQualityChanged)
|
||||
def activeQualityChangesId(self) -> str:
|
||||
if self._active_container_stack:
|
||||
changes = self._active_container_stack.qualityChanges
|
||||
if changes and changes.getId() != "empty":
|
||||
return changes.getId()
|
||||
quality_changes = self._active_container_stack.qualityChanges
|
||||
if quality_changes and not isinstance(quality_changes, type(self._empty_quality_changes_container)):
|
||||
return quality_changes.getId()
|
||||
return ""
|
||||
|
||||
## Check if a container is read_only
|
||||
|
@ -864,17 +869,12 @@ class MachineManager(QObject):
|
|||
"quality_changes": stack_quality_changes
|
||||
})
|
||||
|
||||
has_user_interaction = False
|
||||
# show the keep/discard dialog after the containers have been switched. Otherwise, the default values on
|
||||
# the dialog will be the those before the switching.
|
||||
self._executeDelayedActiveContainerStackChanges()
|
||||
|
||||
if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
|
||||
# Show the keep/discard user settings dialog
|
||||
has_user_interaction = Application.getInstance().discardOrKeepProfileChanges()
|
||||
|
||||
# If there is no interaction with the user (it means the dialog showing "keep" or "discard" was not shown)
|
||||
# because either there are not user changes or because the used already decided to always keep or discard,
|
||||
# then the quality instance container is replaced, in which case, the activeQualityChanged signal is emitted.
|
||||
if not has_user_interaction:
|
||||
self._executeDelayedActiveContainerStackChanges()
|
||||
Application.getInstance().discardOrKeepProfileChanges()
|
||||
|
||||
## Used to update material and variant in the active container stack with a delay.
|
||||
# This delay prevents the stack from triggering a lot of signals (eventually resulting in slicing)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue