mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-15 04:36:01 +08:00
Merge branch 'master' into feature_extruder_per_feature
This commit is contained in:
commit
2a6a968540
@ -871,7 +871,7 @@ class BuildVolume(SceneNode):
|
||||
else:
|
||||
extruder_index = self._global_container_stack.getProperty(extruder_setting_key, "value")
|
||||
|
||||
if extruder_index == "-1": # If extruder index is -1 use global instead
|
||||
if str(extruder_index) == "-1": # If extruder index is -1 use global instead
|
||||
stack = self._global_container_stack
|
||||
else:
|
||||
extruder_stack_id = ExtruderManager.getInstance().extruderIds[str(extruder_index)]
|
||||
|
@ -2,6 +2,9 @@ import sys
|
||||
import platform
|
||||
import traceback
|
||||
import webbrowser
|
||||
import faulthandler
|
||||
import tempfile
|
||||
import os
|
||||
import urllib
|
||||
|
||||
from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, Qt, QCoreApplication
|
||||
@ -91,6 +94,17 @@ def show(exception_type, value, tb):
|
||||
crash_info = "Version: {0}\nPlatform: {1}\nQt: {2}\nPyQt: {3}\n\nException:\n{4}"
|
||||
crash_info = crash_info.format(version, platform.platform(), QT_VERSION_STR, PYQT_VERSION_STR, trace)
|
||||
|
||||
tmp_file_fd, tmp_file_path = tempfile.mkstemp(prefix = "cura-crash", text = True)
|
||||
os.close(tmp_file_fd)
|
||||
with open(tmp_file_path, "w") as f:
|
||||
faulthandler.dump_traceback(f, all_threads=True)
|
||||
with open(tmp_file_path, "r") as f:
|
||||
data = f.read()
|
||||
|
||||
msg = "-------------------------\n"
|
||||
msg += data
|
||||
crash_info += "\n\n" + msg
|
||||
|
||||
textarea.setText(crash_info)
|
||||
|
||||
buttons = QDialogButtonBox(QDialogButtonBox.Close, dialog)
|
||||
|
@ -138,13 +138,14 @@ class CuraApplication(QtApplication):
|
||||
# From which stack the setting would inherit if not defined per object (handled in the engine)
|
||||
# AND for settings which are not settable_per_mesh:
|
||||
# which extruder is the only extruder this setting is obtained from
|
||||
SettingDefinition.addSupportedProperty("limit_to_extruder", DefinitionPropertyType.Function, default = "-1")
|
||||
SettingDefinition.addSupportedProperty("limit_to_extruder", DefinitionPropertyType.Function, default = "-1", depends_on = "value")
|
||||
|
||||
# For settings which are not settable_per_mesh and not settable_per_extruder:
|
||||
# A function which determines the glabel/meshgroup value by looking at the values of the setting in all (used) extruders
|
||||
SettingDefinition.addSupportedProperty("resolve", DefinitionPropertyType.Function, default = None, depends_on = "value")
|
||||
|
||||
SettingDefinition.addSettingType("extruder", None, str, Validator)
|
||||
SettingDefinition.addSettingType("optional_extruder", None, str, None)
|
||||
|
||||
SettingDefinition.addSettingType("[int]", None, str, None)
|
||||
|
||||
@ -178,7 +179,8 @@ class CuraApplication(QtApplication):
|
||||
("machine_stack", ContainerStack.Version): (self.ResourceTypes.MachineStack, "application/x-uranium-containerstack"),
|
||||
("extruder_train", ContainerStack.Version): (self.ResourceTypes.ExtruderStack, "application/x-uranium-extruderstack"),
|
||||
("preferences", Preferences.Version): (Resources.Preferences, "application/x-uranium-preferences"),
|
||||
("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer")
|
||||
("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer"),
|
||||
("definition_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.DefinitionChangesContainer, "application/x-uranium-instancecontainer"),
|
||||
}
|
||||
)
|
||||
|
||||
@ -488,7 +490,7 @@ class CuraApplication(QtApplication):
|
||||
|
||||
self._plugin_registry.loadPlugins()
|
||||
|
||||
if self.getBackend() == None:
|
||||
if self.getBackend() is None:
|
||||
raise RuntimeError("Could not load the backend plugin!")
|
||||
|
||||
self._plugins_loaded = True
|
||||
@ -625,7 +627,9 @@ class CuraApplication(QtApplication):
|
||||
camera.lookAt(Vector(0, 0, 0))
|
||||
controller.getScene().setActiveCamera("3d")
|
||||
|
||||
self.getController().getTool("CameraTool").setOrigin(Vector(0, 100, 0))
|
||||
camera_tool = self.getController().getTool("CameraTool")
|
||||
camera_tool.setOrigin(Vector(0, 100, 0))
|
||||
camera_tool.setZoomRange(0.1, 200000)
|
||||
|
||||
self._camera_animation = CameraAnimation.CameraAnimation()
|
||||
self._camera_animation.setCameraTool(self.getController().getTool("CameraTool"))
|
||||
|
@ -700,7 +700,7 @@ class ContainerManager(QObject):
|
||||
self._container_registry.addContainer(duplicated_container)
|
||||
return self._getMaterialContainerIdForActiveMachine(new_id)
|
||||
|
||||
## Create a new material by cloning Generic PLA and setting the GUID to something unqiue
|
||||
## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue
|
||||
#
|
||||
# \return \type{str} the id of the newly created container.
|
||||
@pyqtSlot(result = str)
|
||||
@ -708,14 +708,25 @@ class ContainerManager(QObject):
|
||||
# Ensure all settings are saved.
|
||||
Application.getInstance().saveSettings()
|
||||
|
||||
containers = self._container_registry.findInstanceContainers(id="generic_pla")
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if not global_stack:
|
||||
return ""
|
||||
|
||||
approximate_diameter = round(global_stack.getProperty("material_diameter", "value"))
|
||||
containers = self._container_registry.findInstanceContainers(id = "generic_pla*", approximate_diameter = approximate_diameter)
|
||||
if not containers:
|
||||
Logger.log("d", "Unable to create a new material by cloning generic_pla, because it doesn't exist.")
|
||||
Logger.log("d", "Unable to create a new material by cloning Generic PLA, because it cannot be found for the material diameter for this machine.")
|
||||
return ""
|
||||
|
||||
base_file = containers[0].getMetaDataEntry("base_file")
|
||||
containers = self._container_registry.findInstanceContainers(id = base_file)
|
||||
if not containers:
|
||||
Logger.log("d", "Unable to create a new material by cloning Generic PLA, because the base file for Generic PLA for this machine can not be found.")
|
||||
return ""
|
||||
|
||||
# Create a new ID & container to hold the data.
|
||||
new_id = self._container_registry.uniqueName("custom_material")
|
||||
container_type = type(containers[0]) # Could be either a XMLMaterialProfile or a InstanceContainer
|
||||
container_type = type(containers[0]) # Always XMLMaterialProfile, since we specifically clone the base_file
|
||||
duplicated_container = container_type(new_id)
|
||||
|
||||
# Instead of duplicating we load the data from the basefile again.
|
||||
|
@ -15,7 +15,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
from UM.Settings.SettingFunction import SettingFunction
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||
from UM.Settings.Interfaces import DefinitionContainerInterface
|
||||
from typing import Optional, List, TYPE_CHECKING, Union
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -74,11 +74,12 @@ class ExtruderManager(QObject):
|
||||
except KeyError:
|
||||
return 0
|
||||
|
||||
@pyqtProperty("QVariantMap", notify=extrudersChanged)
|
||||
@pyqtProperty("QVariantMap", notify = extrudersChanged)
|
||||
def extruderIds(self):
|
||||
map = {}
|
||||
for position in self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()]:
|
||||
map[position] = self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][position].getId()
|
||||
global_stack_id = Application.getInstance().getGlobalContainerStack().getId()
|
||||
for position in self._extruder_trains[global_stack_id]:
|
||||
map[position] = self._extruder_trains[global_stack_id][position].getId()
|
||||
return map
|
||||
|
||||
@pyqtSlot(str, result = str)
|
||||
@ -150,14 +151,14 @@ class ExtruderManager(QObject):
|
||||
selected_nodes.append(node)
|
||||
|
||||
# Then, figure out which nodes are used by those selected nodes.
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
current_extruder_trains = self._extruder_trains.get(global_stack.getId())
|
||||
for node in selected_nodes:
|
||||
extruder = node.callDecoration("getActiveExtruder")
|
||||
if extruder:
|
||||
object_extruders.add(extruder)
|
||||
else:
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_stack.getId() in self._extruder_trains:
|
||||
object_extruders.add(self._extruder_trains[global_stack.getId()]["0"].getId())
|
||||
elif current_extruder_trains:
|
||||
object_extruders.add(current_extruder_trains["0"].getId())
|
||||
|
||||
self._selected_object_extruders = list(object_extruders)
|
||||
|
||||
@ -202,7 +203,7 @@ class ExtruderManager(QObject):
|
||||
# \param machine_definition The machine definition to add the extruders for.
|
||||
# \param machine_id The machine_id to add the extruders for.
|
||||
@deprecated("Use CuraStackBuilder", "2.6")
|
||||
def addMachineExtruders(self, machine_definition: DefinitionContainer, machine_id: str) -> None:
|
||||
def addMachineExtruders(self, machine_definition: DefinitionContainerInterface, machine_id: str) -> None:
|
||||
changed = False
|
||||
machine_definition_id = machine_definition.getId()
|
||||
if machine_id not in self._extruder_trains:
|
||||
@ -236,6 +237,13 @@ class ExtruderManager(QObject):
|
||||
if machine_id not in self._extruder_trains:
|
||||
self._extruder_trains[machine_id] = {}
|
||||
changed = True
|
||||
|
||||
# do not register if an extruder has already been registered at the position on this machine
|
||||
if any(item.getId() == extruder_train.getId() for item in self._extruder_trains[machine_id].values()):
|
||||
Logger.log("w", "Extruder [%s] has already been registered on machine [%s], not doing anything",
|
||||
extruder_train.getId(), machine_id)
|
||||
return
|
||||
|
||||
if extruder_train:
|
||||
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train
|
||||
changed = True
|
||||
@ -255,7 +263,7 @@ class ExtruderManager(QObject):
|
||||
# \param position The position of this extruder train in the extruder slots of the machine.
|
||||
# \param machine_id The id of the "global" stack this extruder is linked to.
|
||||
@deprecated("Use CuraStackBuilder::createExtruderStack", "2.6")
|
||||
def createExtruderTrain(self, extruder_definition: DefinitionContainer, machine_definition: DefinitionContainer,
|
||||
def createExtruderTrain(self, extruder_definition: DefinitionContainerInterface, machine_definition: DefinitionContainerInterface,
|
||||
position, machine_id: str) -> None:
|
||||
# Cache some things.
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
@ -462,6 +470,8 @@ class ExtruderManager(QObject):
|
||||
for extruder in self.getMachineExtruders(machine_id):
|
||||
ContainerRegistry.getInstance().removeContainer(extruder.userChanges.getId())
|
||||
ContainerRegistry.getInstance().removeContainer(extruder.getId())
|
||||
if machine_id in self._extruder_trains:
|
||||
del self._extruder_trains[machine_id]
|
||||
|
||||
## Returns extruders for a specific machine.
|
||||
#
|
||||
@ -515,7 +525,7 @@ class ExtruderManager(QObject):
|
||||
#
|
||||
# This is exposed to SettingFunction so it can be used in value functions.
|
||||
#
|
||||
# \param key The key of the setting to retieve values for.
|
||||
# \param key The key of the setting to retrieve values for.
|
||||
#
|
||||
# \return A list of values for all extruders. If an extruder does not have a value, it will not be in the list.
|
||||
# If no extruder has the value, the list will contain the global value.
|
||||
|
@ -1,22 +1,21 @@
|
||||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from typing import Any
|
||||
|
||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot
|
||||
from typing import Any, TYPE_CHECKING, Optional
|
||||
|
||||
from UM.Decorators import override
|
||||
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
||||
from UM.Settings.ContainerStack import ContainerStack, InvalidContainerStackError
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||
from UM.Settings.Interfaces import ContainerInterface
|
||||
|
||||
from . import Exceptions
|
||||
from .CuraContainerStack import CuraContainerStack
|
||||
from .ExtruderManager import ExtruderManager
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from cura.Settings.GlobalStack import GlobalStack
|
||||
|
||||
## Represents an Extruder and its related containers.
|
||||
#
|
||||
#
|
||||
@ -38,6 +37,10 @@ class ExtruderStack(CuraContainerStack):
|
||||
# For backward compatibility: Register the extruder with the Extruder Manager
|
||||
ExtruderManager.getInstance().registerExtruder(self, stack.id)
|
||||
|
||||
@override(ContainerStack)
|
||||
def getNextStack(self) -> Optional["GlobalStack"]:
|
||||
return super().getNextStack()
|
||||
|
||||
@classmethod
|
||||
def getLoadingPriority(cls) -> int:
|
||||
return 3
|
||||
@ -59,6 +62,13 @@ class ExtruderStack(CuraContainerStack):
|
||||
if not super().getProperty(key, "settable_per_extruder"):
|
||||
return self.getNextStack().getProperty(key, property_name)
|
||||
|
||||
limit_to_extruder = super().getProperty(key, "limit_to_extruder")
|
||||
if (limit_to_extruder is not None and limit_to_extruder != "-1") and self.getMetaDataEntry("position") != str(limit_to_extruder):
|
||||
if str(limit_to_extruder) in self.getNextStack().extruders:
|
||||
result = self.getNextStack().extruders[str(limit_to_extruder)].getProperty(key, property_name)
|
||||
if result is not None:
|
||||
return result
|
||||
|
||||
return super().getProperty(key, property_name)
|
||||
|
||||
@override(CuraContainerStack)
|
||||
|
@ -1,12 +1,15 @@
|
||||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer
|
||||
from typing import Iterable
|
||||
|
||||
import UM.Qt.ListModel
|
||||
from UM.Application import Application
|
||||
import UM.FlameProfiler
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
from cura.Settings.ExtruderStack import ExtruderStack #To listen to changes on the extruders.
|
||||
from cura.Settings.MachineManager import MachineManager #To listen to changes on the extruders of the currently active machine.
|
||||
|
||||
## Model that holds extruders.
|
||||
#
|
||||
@ -66,16 +69,13 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||
self._add_global = False
|
||||
self._simple_names = False
|
||||
|
||||
self._active_extruder_stack = None
|
||||
self._active_machine_extruders = [] # type: Iterable[ExtruderStack]
|
||||
self._use_optional_extruder = False
|
||||
|
||||
#Listen to changes.
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._updateExtruders)
|
||||
manager = ExtruderManager.getInstance()
|
||||
|
||||
self._updateExtruders()
|
||||
|
||||
manager.activeExtruderChanged.connect(self._onActiveExtruderChanged)
|
||||
self._onActiveExtruderChanged()
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._extrudersChanged) #When the machine is swapped we must update the active machine extruders.
|
||||
ExtruderManager.getInstance().extrudersChanged.connect(self._extrudersChanged) #When the extruders change we must link to the stack-changed signal of the new extruder.
|
||||
self._extrudersChanged() #Also calls _updateExtruders.
|
||||
|
||||
def setAddGlobal(self, add):
|
||||
if add != self._add_global:
|
||||
@ -89,6 +89,18 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||
def addGlobal(self):
|
||||
return self._add_global
|
||||
|
||||
useOptionalExtruderChanged = pyqtSignal()
|
||||
|
||||
def setUseOptionalExtruder(self, use_optional_extruder):
|
||||
if use_optional_extruder != self._use_optional_extruder:
|
||||
self._use_optional_extruder = use_optional_extruder
|
||||
self.useOptionalExtruderChanged.emit()
|
||||
self._updateExtruders()
|
||||
|
||||
@pyqtProperty(bool, fset = setUseOptionalExtruder, notify = useOptionalExtruderChanged)
|
||||
def useOptionalExtruder(self):
|
||||
return self._use_optional_extruder
|
||||
|
||||
## Set the simpleNames property.
|
||||
def setSimpleNames(self, simple_names):
|
||||
if simple_names != self._simple_names:
|
||||
@ -104,17 +116,31 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||
def simpleNames(self):
|
||||
return self._simple_names
|
||||
|
||||
def _onActiveExtruderChanged(self):
|
||||
manager = ExtruderManager.getInstance()
|
||||
active_extruder_stack = manager.getActiveExtruderStack()
|
||||
if self._active_extruder_stack != active_extruder_stack:
|
||||
if self._active_extruder_stack:
|
||||
self._active_extruder_stack.containersChanged.disconnect(self._onExtruderStackContainersChanged)
|
||||
## Links to the stack-changed signal of the new extruders when an extruder
|
||||
# is swapped out or added in the current machine.
|
||||
#
|
||||
# \param machine_id The machine for which the extruders changed. This is
|
||||
# filled by the ExtruderManager.extrudersChanged signal when coming from
|
||||
# that signal. Application.globalContainerStackChanged doesn't fill this
|
||||
# signal; it's assumed to be the current printer in that case.
|
||||
def _extrudersChanged(self, machine_id = None):
|
||||
if machine_id is not None:
|
||||
if Application.getInstance().getGlobalContainerStack() is None:
|
||||
return #No machine, don't need to update the current machine's extruders.
|
||||
if machine_id != Application.getInstance().getGlobalContainerStack().getId():
|
||||
return #Not the current machine.
|
||||
#Unlink from old extruders.
|
||||
for extruder in self._active_machine_extruders:
|
||||
extruder.containersChanged.disconnect(self._onExtruderStackContainersChanged)
|
||||
|
||||
if active_extruder_stack:
|
||||
# Update the model when the material container is changed
|
||||
active_extruder_stack.containersChanged.connect(self._onExtruderStackContainersChanged)
|
||||
self._active_extruder_stack = active_extruder_stack
|
||||
#Link to new extruders.
|
||||
self._active_machine_extruders = []
|
||||
extruder_manager = ExtruderManager.getInstance()
|
||||
for extruder in extruder_manager.getExtruderStacks():
|
||||
extruder.containersChanged.connect(self._onExtruderStackContainersChanged)
|
||||
self._active_machine_extruders.append(extruder)
|
||||
|
||||
self._updateExtruders() #Since the new extruders may have different properties, update our own model.
|
||||
|
||||
def _onExtruderStackContainersChanged(self, container):
|
||||
# Update when there is an empty container or material change
|
||||
@ -184,5 +210,16 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||
|
||||
if changed:
|
||||
items.sort(key = lambda i: i["index"])
|
||||
# We need optional extruder to be last, so add it after we do sorting.
|
||||
# This way we can simply intrepret the -1 of the index as the last item (which it now always is)
|
||||
if self._use_optional_extruder:
|
||||
item = {
|
||||
"id": "zomg",
|
||||
"name": "Not overridden",
|
||||
"color": "#ffffff",
|
||||
"index": -1,
|
||||
"definition": ""
|
||||
}
|
||||
items.append(item)
|
||||
self.setItems(items)
|
||||
self.modelChanged.emit()
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from typing import Any
|
||||
from typing import Any, Dict
|
||||
|
||||
from PyQt5.QtCore import pyqtProperty
|
||||
|
||||
@ -24,7 +24,7 @@ class GlobalStack(CuraContainerStack):
|
||||
|
||||
self.addMetaDataEntry("type", "machine") # For backward compatibility
|
||||
|
||||
self._extruders = []
|
||||
self._extruders = {}
|
||||
|
||||
# This property is used to track which settings we are calculating the "resolve" for
|
||||
# and if so, to bypass the resolve to prevent an infinite recursion that would occur
|
||||
@ -34,8 +34,8 @@ class GlobalStack(CuraContainerStack):
|
||||
## Get the list of extruders of this stack.
|
||||
#
|
||||
# \return The extruders registered with this stack.
|
||||
@pyqtProperty("QVariantList")
|
||||
def extruders(self) -> list:
|
||||
@pyqtProperty("QVariantMap")
|
||||
def extruders(self) -> Dict[str, "ExtruderStack"]:
|
||||
return self._extruders
|
||||
|
||||
@classmethod
|
||||
@ -52,8 +52,17 @@ class GlobalStack(CuraContainerStack):
|
||||
extruder_count = self.getProperty("machine_extruder_count", "value")
|
||||
if extruder_count and len(self._extruders) + 1 > extruder_count:
|
||||
Logger.log("w", "Adding extruder {meta} to {id} but its extruder count is {count}".format(id = self.id, count = extruder_count, meta = str(extruder.getMetaData())))
|
||||
return
|
||||
|
||||
self._extruders.append(extruder)
|
||||
position = extruder.getMetaDataEntry("position")
|
||||
if position is None:
|
||||
Logger.log("w", "No position defined for extruder {extruder}, cannot add it to stack {stack}", extruder = extruder.id, stack = self.id)
|
||||
return
|
||||
|
||||
if any(item.getId() == extruder.id for item in self._extruders.values()):
|
||||
Logger.log("w", "Extruder [%s] has already been added to this stack [%s]", extruder.id, self._id)
|
||||
return
|
||||
self._extruders[position] = extruder
|
||||
|
||||
## Overridden from ContainerStack
|
||||
#
|
||||
@ -71,6 +80,7 @@ class GlobalStack(CuraContainerStack):
|
||||
if not self.definition.findDefinitions(key = key):
|
||||
return None
|
||||
|
||||
# Handle the "resolve" property.
|
||||
if self._shouldResolve(key, property_name):
|
||||
self._resolving_settings.add(key)
|
||||
resolve = super().getProperty(key, "resolve")
|
||||
@ -78,6 +88,16 @@ class GlobalStack(CuraContainerStack):
|
||||
if resolve is not None:
|
||||
return resolve
|
||||
|
||||
# Handle the "limit_to_extruder" property.
|
||||
limit_to_extruder = super().getProperty(key, "limit_to_extruder")
|
||||
if limit_to_extruder is not None and limit_to_extruder != "-1" and limit_to_extruder in self._extruders:
|
||||
if super().getProperty(key, "settable_per_extruder"):
|
||||
result = self._extruders[str(limit_to_extruder)].getProperty(key, property_name)
|
||||
if result is not None:
|
||||
return result
|
||||
else:
|
||||
Logger.log("e", "Setting {setting} has limit_to_extruder but is not settable per extruder!", setting = key)
|
||||
|
||||
return super().getProperty(key, property_name)
|
||||
|
||||
## Overridden from ContainerStack
|
||||
|
@ -220,6 +220,7 @@ class MachineManager(QObject):
|
||||
|
||||
if old_index is not None:
|
||||
extruder_manager.setActiveExtruderIndex(old_index)
|
||||
self._auto_materials_changed = {} #Processed all of them now.
|
||||
|
||||
def _autoUpdateHotends(self):
|
||||
extruder_manager = ExtruderManager.getInstance()
|
||||
@ -236,6 +237,7 @@ class MachineManager(QObject):
|
||||
|
||||
if old_index is not None:
|
||||
extruder_manager.setActiveExtruderIndex(old_index)
|
||||
self._auto_hotends_changed = {} #Processed all of them now.
|
||||
|
||||
def _onGlobalContainerChanged(self):
|
||||
if self._global_container_stack:
|
||||
@ -703,7 +705,7 @@ class MachineManager(QObject):
|
||||
# Depending on from/to material+current variant, a quality profile is chosen and set.
|
||||
@pyqtSlot(str)
|
||||
def setActiveMaterial(self, material_id: str):
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = True):
|
||||
with postponeSignals(*self._getContainerChangedSignals()):
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(id = material_id)
|
||||
if not containers or not self._active_container_stack:
|
||||
return
|
||||
@ -768,7 +770,7 @@ class MachineManager(QObject):
|
||||
|
||||
@pyqtSlot(str)
|
||||
def setActiveVariant(self, variant_id: str):
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = True):
|
||||
with postponeSignals(*self._getContainerChangedSignals()):
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_id)
|
||||
if not containers or not self._active_container_stack:
|
||||
return
|
||||
@ -1061,19 +1063,19 @@ class MachineManager(QObject):
|
||||
# If the machine that is being removed is the currently active machine, set another machine as the active machine.
|
||||
activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id)
|
||||
|
||||
ExtruderManager.getInstance().removeMachineExtruders(machine_id)
|
||||
# activate a new machine before removing a machine because this is safer
|
||||
if activate_new_machine:
|
||||
machine_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine")
|
||||
other_machine_stacks = [s for s in machine_stacks if s.getId() != machine_id]
|
||||
if other_machine_stacks:
|
||||
Application.getInstance().setGlobalContainerStack(other_machine_stacks[0])
|
||||
|
||||
ExtruderManager.getInstance().removeMachineExtruders(machine_id)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "user", machine = machine_id)
|
||||
for container in containers:
|
||||
ContainerRegistry.getInstance().removeContainer(container.getId())
|
||||
ContainerRegistry.getInstance().removeContainer(machine_id)
|
||||
|
||||
if activate_new_machine:
|
||||
stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine")
|
||||
if stacks:
|
||||
Application.getInstance().setGlobalContainerStack(stacks[0])
|
||||
|
||||
|
||||
@pyqtProperty(bool, notify = globalContainerChanged)
|
||||
def hasMaterials(self) -> bool:
|
||||
if self._global_container_stack:
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal
|
||||
@ -35,7 +35,7 @@ class SettingInheritanceManager(QObject):
|
||||
## Get the keys of all children settings with an override.
|
||||
@pyqtSlot(str, result = "QStringList")
|
||||
def getChildrenKeysWithOverride(self, key):
|
||||
definitions = self._global_container_stack.getBottom().findDefinitions(key=key)
|
||||
definitions = self._global_container_stack.definition.findDefinitions(key=key)
|
||||
if not definitions:
|
||||
Logger.log("w", "Could not find definition for key [%s]", key)
|
||||
return []
|
||||
@ -55,7 +55,7 @@ class SettingInheritanceManager(QObject):
|
||||
Logger.log("w", "Unable to find extruder for current machine with index %s", extruder_index)
|
||||
return []
|
||||
|
||||
definitions = self._global_container_stack.getBottom().findDefinitions(key=key)
|
||||
definitions = self._global_container_stack.definition.findDefinitions(key=key)
|
||||
if not definitions:
|
||||
Logger.log("w", "Could not find definition for key [%s] (2)", key)
|
||||
return []
|
||||
@ -93,7 +93,7 @@ class SettingInheritanceManager(QObject):
|
||||
|
||||
def _onPropertyChanged(self, key, property_name):
|
||||
if (property_name == "value" or property_name == "enabled") and self._global_container_stack:
|
||||
definitions = self._global_container_stack.getBottom().findDefinitions(key = key)
|
||||
definitions = self._global_container_stack.definition.findDefinitions(key = key)
|
||||
if not definitions:
|
||||
return
|
||||
|
||||
@ -198,6 +198,10 @@ class SettingInheritanceManager(QObject):
|
||||
def _update(self):
|
||||
self._settings_with_inheritance_warning = [] # Reset previous data.
|
||||
|
||||
# Make sure that the GlobalStack is not None. sometimes the globalContainerChanged signal gets here late.
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
|
||||
# Check all setting keys that we know of and see if they are overridden.
|
||||
for setting_key in self._global_container_stack.getAllKeys():
|
||||
override = self._settingIsOverwritingInheritance(setting_key)
|
||||
@ -205,7 +209,7 @@ class SettingInheritanceManager(QObject):
|
||||
self._settings_with_inheritance_warning.append(setting_key)
|
||||
|
||||
# Check all the categories if any of their children have their inheritance overwritten.
|
||||
for category in self._global_container_stack.getBottom().findDefinitions(type = "category"):
|
||||
for category in self._global_container_stack.definition.findDefinitions(type = "category"):
|
||||
if self._recursiveCheck(category):
|
||||
self._settings_with_inheritance_warning.append(category.key)
|
||||
|
||||
|
@ -3,6 +3,7 @@ from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
|
||||
## A decorator that stores the amount an object has been moved below the platform.
|
||||
class ZOffsetDecorator(SceneNodeDecorator):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._z_offset = 0
|
||||
|
||||
def setZOffset(self, offset):
|
||||
|
@ -312,31 +312,20 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
return WorkspaceReader.PreReadResult.accepted
|
||||
|
||||
## Overrides an ExtruderStack in the given GlobalStack and returns the new ExtruderStack.
|
||||
def _overrideExtruderStack(self, global_stack, extruder_index, extruder_file_content):
|
||||
extruder_stack = global_stack.extruders[extruder_index]
|
||||
machine_extruder_count = len(global_stack.extruders)
|
||||
def _overrideExtruderStack(self, global_stack, extruder_file_content):
|
||||
# get extruder position first
|
||||
extruder_config = configparser.ConfigParser()
|
||||
extruder_config.read_string(extruder_file_content)
|
||||
if not extruder_config.has_option("metadata", "position"):
|
||||
msg = "Could not find 'metadata/position' in extruder stack file"
|
||||
Logger.log("e", "Could not find 'metadata/position' in extruder stack file")
|
||||
raise RuntimeError(msg)
|
||||
extruder_position = extruder_config.get("metadata", "position")
|
||||
|
||||
old_extruder_stack_id = extruder_stack.getId()
|
||||
|
||||
# HACK: There are two cases:
|
||||
# - the new ExtruderStack has the same ID as the one we are overriding
|
||||
# - they don't have the same ID
|
||||
# In the second case, directly overriding the existing ExtruderStack will leave the old stack file
|
||||
# in the Cura directory, and this will cause a problem when we restart Cura. So, we always delete
|
||||
# the existing file first.
|
||||
self._container_registry._deleteFiles(extruder_stack)
|
||||
extruder_stack = global_stack.extruders[extruder_position]
|
||||
|
||||
# override the given extruder stack
|
||||
extruder_stack.deserialize(extruder_file_content)
|
||||
# HACK: The deserialize() of ExtruderStack will add itself to the GlobalStack, which is redundant here.
|
||||
# So we need to remove the new entries in the GlobalStack.
|
||||
global_stack._extruders = global_stack._extruders[:machine_extruder_count]
|
||||
|
||||
# HACK: clean and fill the container query cache again
|
||||
if old_extruder_stack_id in self._container_registry._id_container_cache:
|
||||
del self._container_registry._id_container_cache[old_extruder_stack_id]
|
||||
new_extruder_stack_id = extruder_stack.getId()
|
||||
self._container_registry._id_container_cache[new_extruder_stack_id] = extruder_stack
|
||||
|
||||
# return the new ExtruderStack
|
||||
return extruder_stack
|
||||
@ -393,12 +382,23 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
global_stack_id_original = self._stripFileToId(global_stack_file)
|
||||
global_stack_id_new = global_stack_id_original
|
||||
global_stack_need_rename = False
|
||||
|
||||
extruder_stack_id_map = {} # new and old ExtruderStack IDs map
|
||||
if self._resolve_strategies["machine"] == "new":
|
||||
# We need a new id if the id already exists
|
||||
if self._container_registry.findContainerStacks(id = global_stack_id_original):
|
||||
global_stack_id_new = self.getNewId(global_stack_id_original)
|
||||
global_stack_need_rename = True
|
||||
|
||||
for each_extruder_stack_file in extruder_stack_files:
|
||||
old_container_id = self._stripFileToId(each_extruder_stack_file)
|
||||
new_container_id = old_container_id
|
||||
if self._container_registry.findContainerStacks(id = old_container_id):
|
||||
# get a new name for this extruder
|
||||
new_container_id = self.getNewId(old_container_id)
|
||||
|
||||
extruder_stack_id_map[old_container_id] = new_container_id
|
||||
|
||||
# TODO: For the moment we use pretty naive existence checking. If the ID is the same, we assume in quite a few
|
||||
# TODO: cases that the container loaded is the same (most notable in materials & definitions).
|
||||
# TODO: It might be possible that we need to add smarter checking in the future.
|
||||
@ -454,13 +454,13 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
container_id = self._stripFileToId(instance_container_file)
|
||||
serialized = archive.open(instance_container_file).read().decode("utf-8")
|
||||
|
||||
# HACK! we ignore the "metadata/type = quality" instance containers!
|
||||
# HACK! we ignore "quality" and "variant" instance containers!
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read_string(serialized)
|
||||
if not parser.has_option("metadata", "type"):
|
||||
Logger.log("w", "Cannot find metadata/type in %s, ignoring it", instance_container_file)
|
||||
continue
|
||||
if parser.get("metadata", "type") == "quality":
|
||||
if parser.get("metadata", "type") in self._ignored_instance_container_types:
|
||||
continue
|
||||
|
||||
instance_container = InstanceContainer(container_id)
|
||||
@ -470,6 +470,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
container_type = instance_container.getMetaDataEntry("type")
|
||||
Job.yieldThread()
|
||||
|
||||
#
|
||||
# IMPORTANT:
|
||||
# If an instance container (or maybe other type of container) exists, and user chooses "Create New",
|
||||
# we need to rename this container and all references to it, and changing those references are VERY
|
||||
# HARD.
|
||||
#
|
||||
if container_type in self._ignored_instance_container_types:
|
||||
# Ignore certain instance container types
|
||||
Logger.log("w", "Ignoring instance container [%s] with type [%s]", container_id, container_type)
|
||||
@ -486,9 +492,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
instance_container.setDirty(True)
|
||||
elif self._resolve_strategies["machine"] == "new":
|
||||
# The machine is going to get a spiffy new name, so ensure that the id's of user settings match.
|
||||
extruder_id = instance_container.getMetaDataEntry("extruder", None)
|
||||
if extruder_id:
|
||||
new_extruder_id = self.getNewId(extruder_id)
|
||||
old_extruder_id = instance_container.getMetaDataEntry("extruder", None)
|
||||
if old_extruder_id:
|
||||
new_extruder_id = extruder_stack_id_map[old_extruder_id]
|
||||
new_id = new_extruder_id + "_current_settings"
|
||||
instance_container._id = new_id
|
||||
instance_container.setName(new_id)
|
||||
@ -521,17 +527,17 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
elif self._resolve_strategies[container_type] == "new":
|
||||
# TODO: how should we handle the case "new" for quality_changes and definition_changes?
|
||||
|
||||
instance_container.setName(self._container_registry.uniqueName(instance_container.getName()))
|
||||
new_changes_container_id = self.getNewId(instance_container.getId())
|
||||
instance_container._id = new_changes_container_id
|
||||
instance_container.setName(new_changes_container_id)
|
||||
|
||||
# TODO: we don't know the following is correct or not, need to verify
|
||||
# AND REFACTOR!!!
|
||||
if self._resolve_strategies["machine"] == "new":
|
||||
# The machine is going to get a spiffy new name, so ensure that the id's of user settings match.
|
||||
extruder_id = instance_container.getMetaDataEntry("extruder", None)
|
||||
if extruder_id:
|
||||
new_extruder_id = self.getNewId(extruder_id)
|
||||
old_extruder_id = instance_container.getMetaDataEntry("extruder", None)
|
||||
if old_extruder_id:
|
||||
new_extruder_id = extruder_stack_id_map[old_extruder_id]
|
||||
instance_container.setMetaDataEntry("extruder", new_extruder_id)
|
||||
|
||||
machine_id = instance_container.getMetaDataEntry("machine", None)
|
||||
@ -631,13 +637,26 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
if self._resolve_strategies["machine"] == "override":
|
||||
# NOTE: This is the same code as those in the lower part
|
||||
# deserialize new extruder stack over the current ones
|
||||
stack = self._overrideExtruderStack(global_stack, index, extruder_file_content)
|
||||
stack = self._overrideExtruderStack(global_stack, extruder_file_content)
|
||||
|
||||
elif self._resolve_strategies["machine"] == "new":
|
||||
# create a new extruder stack from this one
|
||||
new_id = self.getNewId(container_id)
|
||||
new_id = extruder_stack_id_map[container_id]
|
||||
stack = ExtruderStack(new_id)
|
||||
stack.deserialize(archive.open(extruder_stack_file).read().decode("utf-8"))
|
||||
|
||||
# HACK: the global stack can have a new name, so we need to make sure that this extruder stack
|
||||
# references to the new name instead of the old one. Normally, this can be done after
|
||||
# deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize()
|
||||
# also does addExtruder() to its machine stack, so we have to make sure that it's pointing
|
||||
# to the right machine BEFORE deserialization.
|
||||
extruder_config = configparser.ConfigParser()
|
||||
extruder_config.read_string(extruder_file_content)
|
||||
extruder_config.set("metadata", "machine", global_stack_id_new)
|
||||
tmp_string_io = io.StringIO()
|
||||
extruder_config.write(tmp_string_io)
|
||||
extruder_file_content = tmp_string_io.getvalue()
|
||||
|
||||
stack.deserialize(extruder_file_content)
|
||||
|
||||
# Ensure a unique ID and name
|
||||
stack._id = new_id
|
||||
@ -649,22 +668,31 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
# No extruder stack with the same ID can be found
|
||||
if self._resolve_strategies["machine"] == "override":
|
||||
# deserialize new extruder stack over the current ones
|
||||
stack = self._overrideExtruderStack(global_stack, index, extruder_file_content)
|
||||
stack = self._overrideExtruderStack(global_stack, extruder_file_content)
|
||||
|
||||
elif self._resolve_strategies["machine"] == "new":
|
||||
# container not found, create a new one
|
||||
stack = ExtruderStack(container_id)
|
||||
stack.deserialize(archive.open(extruder_stack_file).read().decode("utf-8"))
|
||||
|
||||
# HACK: the global stack can have a new name, so we need to make sure that this extruder stack
|
||||
# references to the new name instead of the old one. Normally, this can be done after
|
||||
# deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize()
|
||||
# also does addExtruder() to its machine stack, so we have to make sure that it's pointing
|
||||
# to the right machine BEFORE deserialization.
|
||||
extruder_config = configparser.ConfigParser()
|
||||
extruder_config.read_string(extruder_file_content)
|
||||
extruder_config.set("metadata", "machine", global_stack_id_new)
|
||||
tmp_string_io = io.StringIO()
|
||||
extruder_config.write(tmp_string_io)
|
||||
extruder_file_content = tmp_string_io.getvalue()
|
||||
|
||||
stack.deserialize(extruder_file_content)
|
||||
self._container_registry.addContainer(stack)
|
||||
extruder_stacks_added.append(stack)
|
||||
containers_added.append(stack)
|
||||
else:
|
||||
Logger.log("w", "Unknown resolve strategy: %s" % str(self._resolve_strategies["machine"]))
|
||||
|
||||
if global_stack_need_rename:
|
||||
if stack.getMetaDataEntry("machine"):
|
||||
stack.setMetaDataEntry("machine", global_stack_id_new)
|
||||
|
||||
extruder_stacks.append(stack)
|
||||
except:
|
||||
Logger.logException("w", "We failed to serialize the stack. Trying to clean up.")
|
||||
@ -700,13 +728,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
if self._resolve_strategies[changes_container_type] == "new":
|
||||
# Quality changes needs to get a new ID, added to registry and to the right stacks
|
||||
for each_changes_container in quality_and_definition_changes_instance_containers:
|
||||
old_id = each_changes_container.getId()
|
||||
each_changes_container.setName(self._container_registry.uniqueName(each_changes_container.getName()))
|
||||
# We're not really supposed to change the ID in normal cases, but this is an exception.
|
||||
each_changes_container._id = self.getNewId(each_changes_container.getId())
|
||||
|
||||
# The container was not added yet, as it didn't have an unique ID. It does now, so add it.
|
||||
self._container_registry.addContainer(each_changes_container)
|
||||
# NOTE: The renaming and giving new IDs are possibly redundant because they are done in the
|
||||
# instance container loading part.
|
||||
new_id = each_changes_container.getId()
|
||||
|
||||
# Find the old (current) changes container in the global stack
|
||||
if changes_container_type == "quality_changes":
|
||||
@ -723,7 +747,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
# Replace the quality/definition changes container if it's in the GlobalStack
|
||||
# NOTE: we can get an empty container here, but the IDs will not match,
|
||||
# so this comparison is fine.
|
||||
if old_container.getId() == old_id:
|
||||
if self._id_mapping.get(old_container.getId()) == new_id:
|
||||
if changes_container_type == "quality_changes":
|
||||
global_stack.qualityChanges = each_changes_container
|
||||
elif changes_container_type == "definition_changes":
|
||||
@ -746,7 +770,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
|
||||
# NOTE: we can get an empty container here, but the IDs will not match,
|
||||
# so this comparison is fine.
|
||||
if changes_container.getId() == old_id:
|
||||
if self._id_mapping.get(changes_container.getId()) == new_id:
|
||||
if changes_container_type == "quality_changes":
|
||||
each_extruder_stack.qualityChanges = each_changes_container
|
||||
elif changes_container_type == "definition_changes":
|
||||
|
@ -85,6 +85,7 @@ class GCodeWriter(MeshWriter):
|
||||
|
||||
for key in instance_container1.getAllKeys():
|
||||
flat_container.setProperty(key, "value", instance_container1.getProperty(key, "value"))
|
||||
|
||||
return flat_container
|
||||
|
||||
|
||||
@ -106,6 +107,9 @@ class GCodeWriter(MeshWriter):
|
||||
return ""
|
||||
|
||||
flat_global_container = self._createFlattenedContainerInstance(stack.getTop(), container_with_profile)
|
||||
# If the quality changes is not set, we need to set type manually
|
||||
if flat_global_container.getMetaDataEntry("type", None) is None:
|
||||
flat_global_container.addMetaDataEntry("type", "quality_changes")
|
||||
|
||||
# Ensure that quality_type is set. (Can happen if we have empty quality changes).
|
||||
if flat_global_container.getMetaDataEntry("quality_type", None) is None:
|
||||
@ -120,6 +124,9 @@ class GCodeWriter(MeshWriter):
|
||||
Logger.log("w", "No extruder quality profile found, not writing quality for extruder %s to file!", extruder.getId())
|
||||
continue
|
||||
flat_extruder_quality = self._createFlattenedContainerInstance(extruder.getTop(), extruder_quality)
|
||||
# If the quality changes is not set, we need to set type manually
|
||||
if flat_extruder_quality.getMetaDataEntry("type", None) is None:
|
||||
flat_extruder_quality.addMetaDataEntry("type", "quality_changes")
|
||||
|
||||
# Ensure that extruder is set. (Can happen if we have empty quality changes).
|
||||
if flat_extruder_quality.getMetaDataEntry("extruder", None) is None:
|
||||
|
@ -341,7 +341,6 @@ Cura.MachineAction
|
||||
sourceComponent: numericTextFieldWithUnit
|
||||
property var propertyProvider: gantryHeightProvider
|
||||
property string unit: catalog.i18nc("@label", "mm")
|
||||
property bool forceUpdateOnChange: false
|
||||
}
|
||||
|
||||
Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
|
||||
@ -385,7 +384,6 @@ Cura.MachineAction
|
||||
sourceComponent: numericTextFieldWithUnit
|
||||
property var propertyProvider: materialDiameterProvider
|
||||
property string unit: catalog.i18nc("@label", "mm")
|
||||
property bool forceUpdateOnChange: false
|
||||
}
|
||||
Label
|
||||
{
|
||||
@ -399,7 +397,6 @@ Cura.MachineAction
|
||||
sourceComponent: numericTextFieldWithUnit
|
||||
property var propertyProvider: machineNozzleSizeProvider
|
||||
property string unit: catalog.i18nc("@label", "mm")
|
||||
property bool forceUpdateOnChange: false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -550,7 +547,6 @@ Cura.MachineAction
|
||||
sourceComponent: numericTextFieldWithUnit
|
||||
property var propertyProvider: extruderNozzleSizeProvider
|
||||
property string unit: catalog.i18nc("@label", "mm")
|
||||
property bool forceUpdateOnChange: false
|
||||
}
|
||||
|
||||
Label
|
||||
@ -564,6 +560,7 @@ Cura.MachineAction
|
||||
property var propertyProvider: extruderOffsetXProvider
|
||||
property string unit: catalog.i18nc("@label", "mm")
|
||||
property bool forceUpdateOnChange: true
|
||||
property bool allowNegative: true
|
||||
}
|
||||
Label
|
||||
{
|
||||
@ -576,6 +573,7 @@ Cura.MachineAction
|
||||
property var propertyProvider: extruderOffsetYProvider
|
||||
property string unit: catalog.i18nc("@label", "mm")
|
||||
property bool forceUpdateOnChange: true
|
||||
property bool allowNegative: true
|
||||
}
|
||||
}
|
||||
|
||||
@ -655,17 +653,21 @@ Cura.MachineAction
|
||||
Item {
|
||||
height: textField.height
|
||||
width: textField.width
|
||||
|
||||
property bool _allowNegative: (typeof(allowNegative) === 'undefined') ? false : allowNegative
|
||||
property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false: forceUpdateOnChange
|
||||
|
||||
TextField
|
||||
{
|
||||
id: textField
|
||||
text: (propertyProvider.properties.value) ? propertyProvider.properties.value : ""
|
||||
validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ }
|
||||
validator: RegExpValidator { regExp: _allowNegative ? /-?[0-9\.]{0,6}/ : /[0-9\.]{0,6}/ }
|
||||
onEditingFinished:
|
||||
{
|
||||
if (propertyProvider && text != propertyProvider.properties.value)
|
||||
{
|
||||
propertyProvider.setPropertyValue("value", text);
|
||||
if(forceUpdateOnChange)
|
||||
if(_forceUpdateOnChange)
|
||||
{
|
||||
var extruderIndex = ExtruderManager.activeExtruderIndex;
|
||||
manager.forceUpdate();
|
||||
|
@ -12,7 +12,6 @@ Cura.MachineAction
|
||||
anchors.fill: parent;
|
||||
property var selectedPrinter: null
|
||||
property bool completeProperties: true
|
||||
property var connectingToPrinter: null
|
||||
|
||||
Connections
|
||||
{
|
||||
@ -33,9 +32,8 @@ Cura.MachineAction
|
||||
if(base.selectedPrinter && base.completeProperties)
|
||||
{
|
||||
var printerKey = base.selectedPrinter.getKey()
|
||||
if(connectingToPrinter != printerKey) {
|
||||
// prevent an infinite loop
|
||||
connectingToPrinter = printerKey;
|
||||
if(manager.getStoredKey() != printerKey)
|
||||
{
|
||||
manager.setKey(printerKey);
|
||||
completed();
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ _printer_translations_profiles = {
|
||||
# as a set for which profiles were built-in.
|
||||
_profile_translations = {
|
||||
"Low Quality": "low",
|
||||
"Fine": "normal",
|
||||
"Extra Fine": "high",
|
||||
"Normal Quality": "normal",
|
||||
"High Quality": "high",
|
||||
"Ulti Quality": "high", #This one doesn't have an equivalent. Map it to high.
|
||||
"abs_0.25_normal": "um2p_abs_0.25_normal",
|
||||
"abs_0.4_fast": "um2p_abs_0.4_fast",
|
||||
|
@ -22,9 +22,10 @@ def getMetaData():
|
||||
("preferences", 4000000): ("preferences", 4000001, upgrade.upgradePreferences),
|
||||
# NOTE: All the instance containers share the same general/version, so we have to update all of them
|
||||
# if any is updated.
|
||||
("quality_changes", 2000000): ("quality_changes", 2000001, upgrade.upgradeInstanceContainer),
|
||||
("user", 2000000): ("user", 2000001, upgrade.upgradeInstanceContainer),
|
||||
("quality", 2000000): ("quality", 2000001, upgrade.upgradeInstanceContainer),
|
||||
("quality_changes", 2000000): ("quality_changes", 2000001, upgrade.upgradeInstanceContainer),
|
||||
("user", 2000000): ("user", 2000001, upgrade.upgradeInstanceContainer),
|
||||
("quality", 2000000): ("quality", 2000001, upgrade.upgradeInstanceContainer),
|
||||
("definition_changes", 2000000): ("definition_changes", 2000001, upgrade.upgradeInstanceContainer),
|
||||
},
|
||||
"sources": {
|
||||
"quality_changes": {
|
||||
@ -39,6 +40,10 @@ def getMetaData():
|
||||
"get_version": upgrade.getCfgVersion,
|
||||
"location": {"./user"}
|
||||
},
|
||||
"definition_changes": {
|
||||
"get_version": upgrade.getCfgVersion,
|
||||
"location": {"./machine_instances"}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,13 @@ from cura.CuraApplication import CuraApplication
|
||||
import UM.Dictionary
|
||||
from UM.Settings.InstanceContainer import InstanceContainer, InvalidInstanceError
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
|
||||
|
||||
|
||||
## Handles serializing and deserializing material containers from an XML file
|
||||
class XmlMaterialProfile(InstanceContainer):
|
||||
Version = 1
|
||||
|
||||
def __init__(self, container_id, *args, **kwargs):
|
||||
super().__init__(container_id, *args, **kwargs)
|
||||
self._inherited_files = []
|
||||
@ -386,11 +390,13 @@ class XmlMaterialProfile(InstanceContainer):
|
||||
self._path = ""
|
||||
|
||||
def getConfigurationTypeFromSerialized(self, serialized: str) -> Optional[str]:
|
||||
return "material"
|
||||
return "materials"
|
||||
|
||||
def getVersionFromSerialized(self, serialized: str) -> Optional[int]:
|
||||
version = None
|
||||
data = ET.fromstring(serialized)
|
||||
|
||||
# get format version
|
||||
version = None
|
||||
metadata = data.iterfind("./um:metadata/*", self.__namespaces)
|
||||
for entry in metadata:
|
||||
tag_name = _tag_without_namespace(entry)
|
||||
@ -402,14 +408,29 @@ class XmlMaterialProfile(InstanceContainer):
|
||||
break
|
||||
if version is None:
|
||||
raise InvalidInstanceError("Missing version in metadata")
|
||||
return version
|
||||
|
||||
# get setting version
|
||||
if "version" in data.attrib:
|
||||
setting_version = self.xmlVersionToSettingVersion(data.attrib["version"])
|
||||
else:
|
||||
setting_version = self.xmlVersionToSettingVersion("1.2")
|
||||
|
||||
if version is None:
|
||||
raise InvalidInstanceError("Missing version in metadata")
|
||||
|
||||
return version * 1000000 + setting_version
|
||||
|
||||
## Overridden from InstanceContainer
|
||||
def deserialize(self, serialized):
|
||||
# update the serialized data first
|
||||
from UM.Settings.Interfaces import ContainerInterface
|
||||
serialized = ContainerInterface.deserialize(self, serialized)
|
||||
data = ET.fromstring(serialized)
|
||||
|
||||
try:
|
||||
data = ET.fromstring(serialized)
|
||||
except:
|
||||
Logger.logException("e", "An exception occured while parsing the material profile")
|
||||
return
|
||||
|
||||
# Reset previous metadata
|
||||
self.clearData() # Ensure any previous data is gone.
|
||||
@ -544,7 +565,7 @@ class XmlMaterialProfile(InstanceContainer):
|
||||
variant_containers = ContainerRegistry.getInstance().findInstanceContainers(definition = definition.id, name = hotend_id)
|
||||
|
||||
if not variant_containers:
|
||||
Logger.log("d", "No variants found with ID or name %s for machine %s", hotend_id, definition.id)
|
||||
#Logger.log("d", "No variants found with ID or name %s for machine %s", hotend_id, definition.id)
|
||||
continue
|
||||
|
||||
hotend_compatibility = machine_compatibility
|
||||
|
62
plugins/XmlMaterialProfile/XmlMaterialUpgrader.py
Normal file
62
plugins/XmlMaterialProfile/XmlMaterialUpgrader.py
Normal file
@ -0,0 +1,62 @@
|
||||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from UM.VersionUpgrade import VersionUpgrade
|
||||
|
||||
|
||||
class XmlMaterialUpgrader(VersionUpgrade):
|
||||
def getXmlVersion(self, serialized):
|
||||
data = ET.fromstring(serialized)
|
||||
|
||||
# get format version
|
||||
version = None
|
||||
metadata = data.iterfind("./um:metadata/*")
|
||||
for entry in metadata:
|
||||
tag_name = entry.tag
|
||||
if tag_name == "version":
|
||||
try:
|
||||
version = int(entry.text)
|
||||
except Exception as e:
|
||||
raise ValueError("Invalid version string '%s': %s" % (entry.text, e))
|
||||
break
|
||||
if version is None:
|
||||
raise RuntimeError("Missing version in metadata")
|
||||
|
||||
# get setting version
|
||||
if "version" in data.attrib:
|
||||
setting_version = self._xmlVersionToSettingVersion(data.attrib["version"])
|
||||
else:
|
||||
setting_version = self._xmlVersionToSettingVersion("1.2")
|
||||
|
||||
if version is None:
|
||||
raise RuntimeError("Missing version in metadata")
|
||||
|
||||
return version * 1000000 + setting_version
|
||||
|
||||
def _xmlVersionToSettingVersion(self, xml_version: str) -> int:
|
||||
if xml_version == "1.3":
|
||||
return 1
|
||||
return 0 #Older than 1.3.
|
||||
|
||||
def upgradeMaterial(self, serialised, filename):
|
||||
data = ET.fromstring(serialised)
|
||||
|
||||
# update version
|
||||
metadata = data.iterfind("./um:metadata/*", {"um": "http://www.ultimaker.com/material"})
|
||||
for entry in metadata:
|
||||
if _tag_without_namespace(entry) == "version":
|
||||
entry.text = "2"
|
||||
break
|
||||
|
||||
data.attrib["version"] = "1.3"
|
||||
|
||||
# this makes sure that the XML header states encoding="utf-8"
|
||||
new_serialised = ET.tostring(data, encoding="utf-8").decode("utf-8")
|
||||
|
||||
return [filename], [new_serialised]
|
||||
|
||||
|
||||
def _tag_without_namespace(element):
|
||||
return element.tag[element.tag.rfind("}") + 1:]
|
@ -1,11 +1,16 @@
|
||||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from . import XmlMaterialProfile
|
||||
from . import XmlMaterialUpgrader
|
||||
|
||||
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
upgrader = XmlMaterialUpgrader.XmlMaterialUpgrader()
|
||||
|
||||
|
||||
def getMetaData():
|
||||
return {
|
||||
@ -19,15 +24,36 @@ def getMetaData():
|
||||
"settings_container": {
|
||||
"type": "material",
|
||||
"mimetype": "application/x-ultimaker-material-profile"
|
||||
},
|
||||
"version_upgrade": {
|
||||
("materials", 1000000): ("materials", 1000001, upgrader.upgradeMaterial),
|
||||
},
|
||||
"sources": {
|
||||
"materials": {
|
||||
"get_version": upgrader.getXmlVersion,
|
||||
"location": {"./materials"}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def register(app):
|
||||
# add Mime type
|
||||
mime_type = MimeType(
|
||||
name = "application/x-ultimaker-material-profile",
|
||||
comment = "Ultimaker Material Profile",
|
||||
suffixes = [ "xml.fdm_material" ]
|
||||
)
|
||||
MimeTypeDatabase.addMimeType(mime_type)
|
||||
return { "settings_container": XmlMaterialProfile.XmlMaterialProfile("default_xml_material_profile") }
|
||||
|
||||
# add upgrade version
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from UM.VersionUpgradeManager import VersionUpgradeManager
|
||||
VersionUpgradeManager.getInstance().registerCurrentVersion(
|
||||
("materials", XmlMaterialProfile.XmlMaterialProfile.Version * 1000000 + CuraApplication.SettingVersion),
|
||||
(CuraApplication.ResourceTypes.MaterialInstanceContainer, "application/x-uranium-instancecontainer")
|
||||
)
|
||||
|
||||
return {"version_upgrade": upgrader,
|
||||
"settings_container": XmlMaterialProfile.XmlMaterialProfile("default_xml_material_profile"),
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
"variants_name": "Nozzle size",
|
||||
"preferred_variant": "*0.8*",
|
||||
"preferred_material": "*pla*",
|
||||
"preferred_quality": "*high*",
|
||||
"preferred_quality": "*normal*",
|
||||
|
||||
"machine_extruder_trains":
|
||||
{
|
||||
@ -29,7 +29,7 @@
|
||||
"3": "cartesio_extruder_3"
|
||||
},
|
||||
"platform": "cartesio_platform.stl",
|
||||
"platform_offset": [ -120, -1.5, 130],
|
||||
"platform_offset": [ -220, -5, 150],
|
||||
"first_start_actions": ["MachineSettingsAction"],
|
||||
"supported_actions": ["MachineSettingsAction"]
|
||||
},
|
||||
|
@ -778,7 +778,7 @@
|
||||
"type": "float",
|
||||
"enabled": "support_enable and support_roof_enable",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"value": "support_interface_line_width",
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_line_width')",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
@ -794,7 +794,7 @@
|
||||
"type": "float",
|
||||
"enabled": "support_enable and support_bottom_enable",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"value": "support_interface_line_width",
|
||||
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_line_width')",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
}
|
||||
@ -2072,7 +2072,7 @@
|
||||
"minimum_value": "0.1",
|
||||
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
||||
"maximum_value_warning": "150",
|
||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
||||
"enabled": "support_interface_enable and support_enable",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"value": "speed_support / 1.5",
|
||||
"settable_per_mesh": false,
|
||||
@ -2089,9 +2089,9 @@
|
||||
"minimum_value": "0.1",
|
||||
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
||||
"maximum_value_warning": "150",
|
||||
"enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
||||
"enabled": "support_roof_enable and support_enable",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"value": "speed_support_interface",
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'speed_support_interface')",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
@ -2105,9 +2105,9 @@
|
||||
"minimum_value": "0.1",
|
||||
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
||||
"maximum_value_warning": "150",
|
||||
"enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
||||
"enabled": "support_bottom_enable and support_enable",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"value": "speed_support_interface",
|
||||
"value": "extruderValue(support_bottom_extruder_nr, 'speed_support_interface')",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
}
|
||||
@ -2399,7 +2399,7 @@
|
||||
"minimum_value": "0.1",
|
||||
"minimum_value_warning": "100",
|
||||
"maximum_value_warning": "10000",
|
||||
"enabled": "resolveOrValue('acceleration_enabled') and extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
||||
"enabled": "resolveOrValue('acceleration_enabled') and support_interface_enable and support_enable",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
@ -2412,11 +2412,11 @@
|
||||
"unit": "mm/s²",
|
||||
"type": "float",
|
||||
"default_value": 3000,
|
||||
"value": "acceleration_support_interface",
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'acceleration_support_interface')",
|
||||
"minimum_value": "0.1",
|
||||
"minimum_value_warning": "100",
|
||||
"maximum_value_warning": "10000",
|
||||
"enabled": "resolveOrValue('acceleration_enabled') and extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
||||
"enabled": "acceleration_enabled and support_roof_enable and support_enable",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
@ -2428,11 +2428,11 @@
|
||||
"unit": "mm/s²",
|
||||
"type": "float",
|
||||
"default_value": 3000,
|
||||
"value": "acceleration_support_interface",
|
||||
"value": "extruderValue(support_bottom_extruder_nr, 'acceleration_support_interface')",
|
||||
"minimum_value": "0.1",
|
||||
"minimum_value_warning": "100",
|
||||
"maximum_value_warning": "10000",
|
||||
"enabled": "resolveOrValue('acceleration_enabled') and extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
||||
"enabled": "acceleration_enabled and support_bottom_enable and support_enable",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
@ -2669,7 +2669,7 @@
|
||||
"value": "jerk_support",
|
||||
"minimum_value": "0.1",
|
||||
"maximum_value_warning": "50",
|
||||
"enabled": "resolveOrValue('jerk_enabled') and extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
||||
"enabled": "resolveOrValue('jerk_enabled') and support_interface_enable and support_enable",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
@ -2682,10 +2682,10 @@
|
||||
"unit": "mm/s",
|
||||
"type": "float",
|
||||
"default_value": 20,
|
||||
"value": "jerk_support_interface",
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')",
|
||||
"minimum_value": "0.1",
|
||||
"maximum_value_warning": "50",
|
||||
"enabled": "resolveOrValue('jerk_enabled') and extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
||||
"enabled": "resolveOrValue('jerk_enabled') and support_roof_enable and support_enable",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
@ -2697,10 +2697,10 @@
|
||||
"unit": "mm/s",
|
||||
"type": "float",
|
||||
"default_value": 20,
|
||||
"value": "jerk_support_interface",
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')",
|
||||
"minimum_value": "0.1",
|
||||
"maximum_value_warning": "50",
|
||||
"enabled": "resolveOrValue('jerk_enabled') and extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
||||
"enabled": "resolveOrValue('jerk_enabled') and support_bottom_enable and support_enable",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
@ -3285,7 +3285,7 @@
|
||||
"default_value": 0.1,
|
||||
"type": "float",
|
||||
"enabled": "support_enable",
|
||||
"value": "extruderValue(support_extruder_nr, 'support_z_distance')",
|
||||
"value": "extruderValue(support_roof_extruder_nr if support_roof_enable else support_infill_extruder_nr, 'support_z_distance')",
|
||||
"limit_to_extruder": "support_roof_extruder_nr if support_roof_enable else support_infill_extruder_nr",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
@ -3297,7 +3297,7 @@
|
||||
"minimum_value": "0",
|
||||
"maximum_value_warning": "machine_nozzle_size",
|
||||
"default_value": 0.1,
|
||||
"value": "extruderValue(support_extruder_nr, 'support_z_distance') if resolveOrValue('support_type') == 'everywhere' else 0",
|
||||
"value": "extruderValue(support_bottom_extruder_nr if support_bottom_enable else support_infill_extruder_nr, 'support_z_distance') if support_type == 'everywhere' else 0",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr if support_bottom_enable else support_infill_extruder_nr",
|
||||
"type": "float",
|
||||
"enabled": "support_enable and resolveOrValue('support_type') == 'everywhere'",
|
||||
@ -3340,11 +3340,11 @@
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"minimum_value": "0",
|
||||
"maximum_value_warning": "extruderValue(support_infill_extruder_nr, 'support_xy_distance')",
|
||||
"maximum_value_warning": "support_xy_distance",
|
||||
"default_value": 0.2,
|
||||
"value": "machine_nozzle_size / 2",
|
||||
"limit_to_extruder": "support_infill_extruder_nr",
|
||||
"enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_xy_overrides_z') == 'z_overrides_xy'",
|
||||
"enabled": "support_enable and support_xy_overrides_z == 'z_overrides_xy'",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"support_bottom_stair_step_height":
|
||||
@ -3416,7 +3416,7 @@
|
||||
"description": "Generate a dense slab of material between the top of support and the model. This will create a skin between the model and support.",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"value": "support_interface_enable",
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_enable')",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"enabled": "support_enable",
|
||||
"settable_per_mesh": true
|
||||
@ -3427,7 +3427,7 @@
|
||||
"description": "Generate a dense slab of material between the bottom of the support and the model. This will create a skin between the model and support.",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"value": "support_interface_enable",
|
||||
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_enable')",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"enabled": "support_enable",
|
||||
"settable_per_mesh": true
|
||||
@ -3442,10 +3442,10 @@
|
||||
"type": "float",
|
||||
"default_value": 1,
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "0.2 + resolveOrValue('layer_height')",
|
||||
"minimum_value_warning": "0.2 + layer_height",
|
||||
"maximum_value_warning": "10",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
||||
"enabled": "support_interface_enable and support_enable",
|
||||
"settable_per_mesh": true,
|
||||
"children":
|
||||
{
|
||||
@ -3457,11 +3457,11 @@
|
||||
"type": "float",
|
||||
"default_value": 1,
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "0.2 + resolveOrValue('layer_height')",
|
||||
"minimum_value_warning": "0.2 + layer_height",
|
||||
"maximum_value_warning": "10",
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_height')",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
||||
"enabled": "support_roof_enable and support_enable",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"support_bottom_height":
|
||||
@ -3473,10 +3473,10 @@
|
||||
"default_value": 1,
|
||||
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_height')",
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "min(0.2 + resolveOrValue('layer_height'), extruderValue(support_bottom_extruder_nr, 'support_bottom_stair_step_height'))",
|
||||
"minimum_value_warning": "min(0.2 + layer_height, support_bottom_stair_step_height)",
|
||||
"maximum_value_warning": "10",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
||||
"enabled": "support_bottom_enable and support_enable",
|
||||
"settable_per_mesh": true
|
||||
}
|
||||
}
|
||||
@ -3490,7 +3490,7 @@
|
||||
"minimum_value": "0",
|
||||
"maximum_value_warning": "support_interface_height",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
||||
"enabled": "support_interface_enable and support_enable",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"support_interface_density":
|
||||
@ -3503,7 +3503,7 @@
|
||||
"minimum_value": "0",
|
||||
"maximum_value_warning": "100",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
||||
"enabled": "support_interface_enable and support_enable",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
"children":
|
||||
@ -3518,7 +3518,8 @@
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "100",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
||||
"enabled": "support_roof_enable and support_enable",
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_density')",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
"children":
|
||||
@ -3534,7 +3535,7 @@
|
||||
"minimum_value_warning": "support_roof_line_width - 0.0001",
|
||||
"value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == 'grid' else (3 if support_roof_pattern == 'triangles' else 1))",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
||||
"enabled": "support_roof_enable and support_enable",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
}
|
||||
@ -3550,7 +3551,8 @@
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "100",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
||||
"enabled": "support_bottom_enable and support_enable",
|
||||
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_density')",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
"children":
|
||||
@ -3566,7 +3568,7 @@
|
||||
"minimum_value_warning": "support_bottom_line_width - 0.0001",
|
||||
"value": "0 if support_bottom_density == 0 else (support_bottom_line_width * 100) / support_bottom_density * (2 if support_bottom_pattern == 'grid' else (3 if support_bottom_pattern == 'triangles' else 1))",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
||||
"enabled": "support_bottom_enable and support_enable",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
}
|
||||
@ -3590,7 +3592,7 @@
|
||||
},
|
||||
"default_value": "concentric",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
||||
"enabled": "support_interface_enable and support_enable",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
"children":
|
||||
@ -3610,9 +3612,9 @@
|
||||
"zigzag": "Zig Zag"
|
||||
},
|
||||
"default_value": "concentric",
|
||||
"value": "support_interface_pattern",
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_pattern')",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
||||
"enabled": "support_roof_enable and support_enable",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
@ -3631,9 +3633,9 @@
|
||||
"zigzag": "Zig Zag"
|
||||
},
|
||||
"default_value": "concentric",
|
||||
"value": "support_interface_pattern",
|
||||
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_pattern')",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
||||
"enabled": "support_bottom_enable and support_enable",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
}
|
||||
@ -3660,7 +3662,7 @@
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "2 * machine_nozzle_size",
|
||||
"maximum_value_warning": "20",
|
||||
"enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_use_towers')",
|
||||
"enabled": "support_enable and support_use_towers",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"support_minimal_diameter":
|
||||
@ -3674,8 +3676,8 @@
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "2 * machine_nozzle_size",
|
||||
"maximum_value_warning": "20",
|
||||
"maximum_value": "extruderValue(support_infill_extruder_nr, 'support_tower_diameter')",
|
||||
"enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_use_towers')",
|
||||
"maximum_value": "support_tower_diameter",
|
||||
"enabled": "support_enable and support_use_towers",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"support_tower_roof_angle":
|
||||
@ -3688,7 +3690,7 @@
|
||||
"maximum_value": "90",
|
||||
"default_value": 65,
|
||||
"limit_to_extruder": "support_infill_extruder_nr",
|
||||
"enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_use_towers')",
|
||||
"enabled": "support_enable and support_use_towers",
|
||||
"settable_per_mesh": true
|
||||
}
|
||||
}
|
||||
@ -3914,7 +3916,7 @@
|
||||
"value": "resolveOrValue('layer_height')",
|
||||
"minimum_value": "0.001",
|
||||
"minimum_value_warning": "0.04",
|
||||
"maximum_value_warning": "0.75 * extruderValue(adhesion_extruder_nr, 'machine_nozzle_size')",
|
||||
"maximum_value_warning": "0.75 * machine_nozzle_size",
|
||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
@ -3929,8 +3931,8 @@
|
||||
"default_value": 0.4,
|
||||
"value": "line_width",
|
||||
"minimum_value": "0.001",
|
||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 0.1",
|
||||
"maximum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 2",
|
||||
"minimum_value_warning": "machine_nozzle_size * 0.1",
|
||||
"maximum_value_warning": "machine_nozzle_size * 2",
|
||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
@ -3944,8 +3946,8 @@
|
||||
"type": "float",
|
||||
"default_value": 0.4,
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'raft_surface_line_width')",
|
||||
"maximum_value_warning": "extruderValue(adhesion_extruder_nr, 'raft_surface_line_width') * 3",
|
||||
"minimum_value_warning": "raft_surface_line_width",
|
||||
"maximum_value_warning": "raft_surface_line_width * 3",
|
||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||
"value": "raft_surface_line_width",
|
||||
"settable_per_mesh": false,
|
||||
@ -3962,7 +3964,7 @@
|
||||
"value": "resolveOrValue('layer_height') * 1.5",
|
||||
"minimum_value": "0.001",
|
||||
"minimum_value_warning": "0.04",
|
||||
"maximum_value_warning": "0.75 * extruderValue(adhesion_extruder_nr, 'machine_nozzle_size')",
|
||||
"maximum_value_warning": "0.75 * machine_nozzle_size",
|
||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
@ -3977,8 +3979,8 @@
|
||||
"default_value": 0.7,
|
||||
"value": "line_width * 2",
|
||||
"minimum_value": "0.001",
|
||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 0.5",
|
||||
"maximum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 3",
|
||||
"minimum_value_warning": "machine_nozzle_size * 0.5",
|
||||
"maximum_value_warning": "machine_nozzle_size * 3",
|
||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
@ -3993,7 +3995,7 @@
|
||||
"default_value": 0.9,
|
||||
"value": "raft_interface_line_width + 0.2",
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'raft_interface_line_width')",
|
||||
"minimum_value_warning": "raft_interface_line_width",
|
||||
"maximum_value_warning": "15.0",
|
||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||
"settable_per_mesh": false,
|
||||
@ -4010,7 +4012,7 @@
|
||||
"value": "resolveOrValue('layer_height_0') * 1.2",
|
||||
"minimum_value": "0.001",
|
||||
"minimum_value_warning": "0.04",
|
||||
"maximum_value_warning": "0.75 * extruderValue(adhesion_extruder_nr, 'raft_base_line_width')",
|
||||
"maximum_value_warning": "0.75 * raft_base_line_width",
|
||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
@ -4024,9 +4026,9 @@
|
||||
"type": "float",
|
||||
"default_value": 0.8,
|
||||
"minimum_value": "0.001",
|
||||
"value": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 2",
|
||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 0.5",
|
||||
"maximum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 3",
|
||||
"value": "machine_nozzle_size * 2",
|
||||
"minimum_value_warning": "machine_nozzle_size * 0.5",
|
||||
"maximum_value_warning": "machine_nozzle_size * 3",
|
||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
@ -4041,7 +4043,7 @@
|
||||
"default_value": 1.6,
|
||||
"value": "raft_base_line_width * 2",
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'raft_base_line_width')",
|
||||
"minimum_value_warning": "raft_base_line_width",
|
||||
"maximum_value_warning": "100",
|
||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||
"settable_per_mesh": false,
|
||||
@ -4634,6 +4636,18 @@
|
||||
"settable_per_mesh": true,
|
||||
"enabled": "mold_enabled"
|
||||
},
|
||||
"mold_roof_height":
|
||||
{
|
||||
"label": "Mold Roof Height",
|
||||
"description": "The height above horizontal parts in your model which to print mold.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"minimum_value": "0",
|
||||
"maximum_value_warning": "5",
|
||||
"default_value": 0.5,
|
||||
"settable_per_mesh": true,
|
||||
"enabled": "mold_enabled"
|
||||
},
|
||||
"mold_angle":
|
||||
{
|
||||
"label": "Mold Angle",
|
||||
|
Binary file not shown.
@ -17,7 +17,7 @@ SettingItem
|
||||
id: control
|
||||
anchors.fill: parent
|
||||
|
||||
model: Cura.ExtrudersModel { }
|
||||
model: Cura.ExtrudersModel { onModelChanged: control.color = getItem(control.currentIndex).color }
|
||||
|
||||
textRole: "name"
|
||||
|
||||
@ -36,6 +36,17 @@ SettingItem
|
||||
onWheel: wheel.accepted = true;
|
||||
}
|
||||
|
||||
property string color: "#fff"
|
||||
|
||||
Binding
|
||||
{
|
||||
// We override the color property's value when the ExtruderModel changes. So we need to use an
|
||||
// explicit binding here otherwise we do not handle value changes after the model changes.
|
||||
target: control
|
||||
property: "color"
|
||||
value: control.currentText != "" ? control.model.getItem(control.currentIndex).color : ""
|
||||
}
|
||||
|
||||
style: ComboBoxStyle
|
||||
{
|
||||
background: Rectangle
|
||||
@ -83,7 +94,7 @@ SettingItem
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
|
||||
|
||||
color: control.currentText != "" ? control.model.getItem(control.currentIndex).color : ""
|
||||
color: control.color
|
||||
}
|
||||
Label
|
||||
{
|
||||
|
153
resources/qml/Settings/SettingOptionalExtruder.qml
Normal file
153
resources/qml/Settings/SettingOptionalExtruder.qml
Normal file
@ -0,0 +1,153 @@
|
||||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Uranium is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.1
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
|
||||
import UM 1.1 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
SettingItem
|
||||
{
|
||||
id: base
|
||||
|
||||
contents: ComboBox
|
||||
{
|
||||
id: control
|
||||
anchors.fill: parent
|
||||
|
||||
model: Cura.ExtrudersModel
|
||||
{
|
||||
onModelChanged: control.color = getItem(control.currentIndex).color
|
||||
useOptionalExtruder: true
|
||||
}
|
||||
|
||||
textRole: "name"
|
||||
|
||||
onActivated:
|
||||
{
|
||||
forceActiveFocus();
|
||||
propertyProvider.setPropertyValue("value", model.getItem(index).index);
|
||||
}
|
||||
|
||||
Binding
|
||||
{
|
||||
target: control
|
||||
property: "currentIndex"
|
||||
value:
|
||||
{
|
||||
if(propertyProvider.properties.value == -1)
|
||||
{
|
||||
return control.model.items.length - 1
|
||||
}
|
||||
return propertyProvider.properties.value
|
||||
}
|
||||
// Sometimes when the value is already changed, the model is still being built.
|
||||
// The when clause ensures that the current index is not updated when this happens.
|
||||
when: control.model.items.length > 0
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
onWheel: wheel.accepted = true;
|
||||
}
|
||||
|
||||
property string color: "#fff"
|
||||
|
||||
Binding
|
||||
{
|
||||
// We override the color property's value when the ExtruderModel changes. So we need to use an
|
||||
// explicit binding here otherwise we do not handle value changes after the model changes.
|
||||
target: control
|
||||
property: "color"
|
||||
value: control.currentText != "" ? control.model.getItem(control.currentIndex).color : ""
|
||||
}
|
||||
|
||||
style: ComboBoxStyle
|
||||
{
|
||||
background: Rectangle
|
||||
{
|
||||
color:
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
return UM.Theme.getColor("setting_control_disabled");
|
||||
}
|
||||
if(control.hovered || base.activeFocus)
|
||||
{
|
||||
return UM.Theme.getColor("setting_control_highlight");
|
||||
}
|
||||
else
|
||||
{
|
||||
return UM.Theme.getColor("setting_control");
|
||||
}
|
||||
}
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color:
|
||||
{
|
||||
if(!enabled)
|
||||
{
|
||||
return UM.Theme.getColor("setting_control_disabled_border");
|
||||
}
|
||||
if(control.hovered || base.activeFocus)
|
||||
{
|
||||
UM.Theme.getColor("setting_control_border_highlight")
|
||||
}
|
||||
|
||||
return UM.Theme.getColor("setting_control_border")
|
||||
}
|
||||
}
|
||||
label: Item
|
||||
{
|
||||
Rectangle
|
||||
{
|
||||
id: swatch
|
||||
height: UM.Theme.getSize("setting_control").height / 2
|
||||
width: height
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
|
||||
|
||||
color: control.color
|
||||
}
|
||||
Label
|
||||
{
|
||||
anchors
|
||||
{
|
||||
left: swatch.right;
|
||||
right: arrow.left;
|
||||
verticalCenter: parent.verticalCenter
|
||||
margins: UM.Theme.getSize("default_lining").width
|
||||
}
|
||||
width: parent.width - swatch.width;
|
||||
|
||||
text: control.currentText
|
||||
font: UM.Theme.getFont("default")
|
||||
color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
|
||||
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
UM.RecolorImage
|
||||
{
|
||||
id: arrow
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
source: UM.Theme.getIcon("arrow_bottom")
|
||||
width: UM.Theme.getSize("standard_arrow").width
|
||||
height: UM.Theme.getSize("standard_arrow").height
|
||||
sourceSize.width: width + 5
|
||||
sourceSize.height: width + 5
|
||||
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -195,7 +195,7 @@ Item
|
||||
//Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
|
||||
//In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
|
||||
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
|
||||
asynchronous: model.type != "enum" && model.type != "extruder"
|
||||
asynchronous: model.type != "enum" && model.type != "extruder" && model.type != "optional_extruder"
|
||||
active: model.type != undefined
|
||||
|
||||
source:
|
||||
@ -218,6 +218,8 @@ Item
|
||||
return "SettingTextField.qml"
|
||||
case "category":
|
||||
return "SettingCategory.qml"
|
||||
case "optional_extruder":
|
||||
return "SettingOptionalExtruder.qml"
|
||||
default:
|
||||
return "SettingUnknown.qml"
|
||||
}
|
||||
|
@ -45,6 +45,5 @@ speed_wall = =math.ceil(speed_print * 50 / 50)
|
||||
speed_wall_0 = =math.ceil(speed_wall * 40 / 50)
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_z_distance = =layer_height
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
wall_thickness = 1
|
||||
|
@ -45,5 +45,4 @@ speed_wall = =math.ceil(speed_print * 45 / 45)
|
||||
speed_wall_0 = =math.ceil(speed_wall * 35 / 45)
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_z_distance = =layer_height
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
|
@ -47,5 +47,4 @@ speed_wall = =math.ceil(speed_print * 35 / 40)
|
||||
speed_wall_0 = =math.ceil(speed_wall * 30 / 35)
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_z_distance = =layer_height
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
|
@ -46,5 +46,4 @@ speed_wall = =math.ceil(speed_print * 35 / 40)
|
||||
speed_wall_0 = =math.ceil(speed_wall * 30 / 35)
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_z_distance = =layer_height
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
|
@ -59,7 +59,6 @@ support_interface_pattern = lines
|
||||
switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 35
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =round(line_width * 0.4 / 0.35, 2)
|
||||
wall_thickness = 1.2
|
||||
|
@ -58,7 +58,6 @@ support_interface_pattern = lines
|
||||
switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 35
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =round(line_width * 0.4 / 0.35, 2)
|
||||
wall_thickness = 1.2
|
||||
|
@ -59,7 +59,6 @@ support_interface_pattern = lines
|
||||
switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 35
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =round(line_width * 0.4 / 0.35, 2)
|
||||
wall_thickness = 1.2
|
||||
|
@ -56,7 +56,6 @@ support_interface_pattern = lines
|
||||
switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 35
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =round(line_width * 0.4 / 0.35, 2)
|
||||
wall_thickness = 1.2
|
||||
|
@ -44,7 +44,7 @@ retraction_count_max = 12
|
||||
retraction_extra_prime_amount = 0.8
|
||||
retraction_extrusion_window = 1
|
||||
retraction_hop = 2
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_enabled = False
|
||||
retraction_hop_only_when_collides = True
|
||||
retraction_min_travel = 0.8
|
||||
retraction_prime_speed = 15
|
||||
@ -56,11 +56,12 @@ speed_travel = 300
|
||||
speed_wall = =math.ceil(speed_print * 25 / 25)
|
||||
speed_wall_0 = =math.ceil(speed_wall * 25 / 25)
|
||||
support_angle = 50
|
||||
skin_overlap = 5
|
||||
switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 35
|
||||
top_bottom_thickness = 0.7
|
||||
travel_avoid_distance = 3
|
||||
travel_avoid_distance = 0.5
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =line_width
|
||||
wall_thickness = 0.76
|
||||
|
@ -45,10 +45,11 @@ retraction_count_max = 12
|
||||
retraction_extra_prime_amount = 0.8
|
||||
retraction_extrusion_window = 1
|
||||
retraction_hop = 2
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_enabled = False
|
||||
retraction_hop_only_when_collides = True
|
||||
retraction_min_travel = 0.8
|
||||
retraction_prime_speed = 15
|
||||
skin_overlap = 5
|
||||
speed_equalize_flow_enabled = True
|
||||
speed_layer_0 = 18
|
||||
speed_print = 25
|
||||
@ -61,7 +62,7 @@ switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 35
|
||||
top_bottom_thickness = 0.7
|
||||
travel_avoid_distance = 3
|
||||
travel_avoid_distance = 0.5
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =line_width
|
||||
wall_thickness = 0.76
|
||||
|
@ -42,10 +42,11 @@ retraction_count_max = 12
|
||||
retraction_extra_prime_amount = 0.8
|
||||
retraction_extrusion_window = 1
|
||||
retraction_hop = 2
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_enabled = False
|
||||
retraction_hop_only_when_collides = True
|
||||
retraction_min_travel = 0.8
|
||||
retraction_prime_speed = 15
|
||||
skin_overlap = 5
|
||||
speed_equalize_flow_enabled = True
|
||||
speed_layer_0 = 18
|
||||
speed_print = 25
|
||||
@ -58,7 +59,7 @@ switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 35
|
||||
top_bottom_thickness = 0.7
|
||||
travel_avoid_distance = 3
|
||||
travel_avoid_distance = 0.5
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =line_width
|
||||
wall_thickness = 0.76
|
||||
|
@ -38,11 +38,11 @@ retract_at_layer_change = False
|
||||
retraction_count_max = 12
|
||||
retraction_extra_prime_amount = 0.5
|
||||
retraction_hop = 0.5
|
||||
retraction_hop_enabled = False
|
||||
retraction_hop_only_when_collides = False
|
||||
retraction_min_travel = 0.8
|
||||
retraction_prime_speed = 15
|
||||
skin_line_width = =round(line_width * 0.78 / 0.8, 2)
|
||||
skin_overlap = 15
|
||||
speed_print = 30
|
||||
speed_topbottom = =math.ceil(speed_print * 25 / 30)
|
||||
speed_travel = 300
|
||||
@ -56,6 +56,7 @@ switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 45
|
||||
top_bottom_thickness = 1.2
|
||||
travel_avoid_distance = 0.5
|
||||
travel_compensate_overlapping_walls_0_enabled = False
|
||||
wall_0_wipe_dist = =line_width * 2
|
||||
wall_line_width_x = =round(line_width * 0.6 / 0.8, 2)
|
||||
|
@ -39,11 +39,11 @@ retract_at_layer_change = False
|
||||
retraction_count_max = 12
|
||||
retraction_extra_prime_amount = 0.5
|
||||
retraction_hop = 0.5
|
||||
retraction_hop_enabled = False
|
||||
retraction_hop_only_when_collides = False
|
||||
retraction_min_travel = 0.8
|
||||
retraction_prime_speed = 15
|
||||
skin_line_width = =round(line_width * 0.78 / 0.8, 2)
|
||||
skin_overlap = 15
|
||||
speed_print = 30
|
||||
speed_topbottom = =math.ceil(speed_print * 20 / 30)
|
||||
speed_travel = 300
|
||||
@ -57,6 +57,7 @@ switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 45
|
||||
top_bottom_thickness = 1.2
|
||||
travel_avoid_distance = 0.5
|
||||
travel_compensate_overlapping_walls_0_enabled = False
|
||||
wall_0_wipe_dist = =line_width * 2
|
||||
wall_line_width_x = =round(line_width * 0.6 / 0.8, 2)
|
||||
|
@ -38,11 +38,11 @@ retract_at_layer_change = False
|
||||
retraction_count_max = 12
|
||||
retraction_extra_prime_amount = 0.5
|
||||
retraction_hop = 0.5
|
||||
retraction_hop_enabled = False
|
||||
retraction_hop_only_when_collides = False
|
||||
retraction_min_travel = 0.8
|
||||
retraction_prime_speed = 15
|
||||
skin_line_width = =round(line_width * 0.78 / 0.8, 2)
|
||||
skin_overlap = 15
|
||||
speed_print = 30
|
||||
speed_topbottom = =math.ceil(speed_print * 23 / 30)
|
||||
speed_travel = 300
|
||||
@ -56,6 +56,7 @@ switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 45
|
||||
top_bottom_thickness = 1.2
|
||||
travel_avoid_distance = 0.5
|
||||
travel_compensate_overlapping_walls_0_enabled = False
|
||||
wall_0_wipe_dist = =line_width * 2
|
||||
wall_line_width_x = =round(line_width * 0.6 / 0.8, 2)
|
||||
|
@ -4,7 +4,7 @@ name = Extra Fine
|
||||
definition = ultimaker3
|
||||
|
||||
[metadata]
|
||||
weight = 0
|
||||
weight = 1
|
||||
type = quality
|
||||
quality_type = high
|
||||
material = generic_pva_ultimaker3_BB_0.4
|
||||
|
@ -1,6 +1,6 @@
|
||||
[general]
|
||||
version = 2
|
||||
name = Draft Quality
|
||||
name = Fast
|
||||
definition = ultimaker3
|
||||
|
||||
[metadata]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[general]
|
||||
version = 2
|
||||
name = Fast Quality
|
||||
name = Normal
|
||||
definition = ultimaker3
|
||||
|
||||
[metadata]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[general]
|
||||
version = 2
|
||||
name = Superdraft Quality
|
||||
name = Sprint
|
||||
definition = ultimaker3
|
||||
|
||||
[metadata]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[general]
|
||||
version = 2
|
||||
name = Verydraft Quality
|
||||
name = Extra Fast
|
||||
definition = ultimaker3
|
||||
|
||||
[metadata]
|
||||
|
13
resources/variants/ultimaker2_extended_0.25.inst.cfg
Normal file
13
resources/variants/ultimaker2_extended_0.25.inst.cfg
Normal file
@ -0,0 +1,13 @@
|
||||
[general]
|
||||
name = 0.25 mm
|
||||
version = 2
|
||||
definition = ultimaker2_extended
|
||||
|
||||
[metadata]
|
||||
author = Ultimaker
|
||||
type = variant
|
||||
setting_version = 1
|
||||
|
||||
[values]
|
||||
machine_nozzle_size = 0.25
|
||||
machine_nozzle_tip_outer_diameter = 0.8
|
13
resources/variants/ultimaker2_extended_0.4.inst.cfg
Normal file
13
resources/variants/ultimaker2_extended_0.4.inst.cfg
Normal file
@ -0,0 +1,13 @@
|
||||
[general]
|
||||
name = 0.4 mm
|
||||
version = 2
|
||||
definition = ultimaker2_extended
|
||||
|
||||
[metadata]
|
||||
author = Ultimaker
|
||||
type = variant
|
||||
setting_version = 1
|
||||
|
||||
[values]
|
||||
machine_nozzle_size = 0.4
|
||||
machine_nozzle_tip_outer_diameter = 1.05
|
13
resources/variants/ultimaker2_extended_0.6.inst.cfg
Normal file
13
resources/variants/ultimaker2_extended_0.6.inst.cfg
Normal file
@ -0,0 +1,13 @@
|
||||
[general]
|
||||
name = 0.6 mm
|
||||
version = 2
|
||||
definition = ultimaker2_extended
|
||||
|
||||
[metadata]
|
||||
author = Ultimaker
|
||||
type = variant
|
||||
setting_version = 1
|
||||
|
||||
[values]
|
||||
machine_nozzle_size = 0.6
|
||||
machine_nozzle_tip_outer_diameter = 1.25
|
13
resources/variants/ultimaker2_extended_0.8.inst.cfg
Normal file
13
resources/variants/ultimaker2_extended_0.8.inst.cfg
Normal file
@ -0,0 +1,13 @@
|
||||
[general]
|
||||
name = 0.8 mm
|
||||
version = 2
|
||||
definition = ultimaker2_extended
|
||||
|
||||
[metadata]
|
||||
author = Ultimaker
|
||||
type = variant
|
||||
setting_version = 1
|
||||
|
||||
[values]
|
||||
machine_nozzle_size = 0.8
|
||||
machine_nozzle_tip_outer_diameter = 1.35
|
@ -60,7 +60,6 @@ support_z_distance = =layer_height * 2
|
||||
switch_extruder_prime_speed = 20
|
||||
switch_extruder_retraction_amount = 16.5
|
||||
top_bottom_thickness = 1.4
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =wall_line_width
|
||||
wall_thickness = 2
|
||||
|
@ -81,7 +81,6 @@ support_z_distance = 0
|
||||
switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 12
|
||||
top_bottom_thickness = 1
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =wall_line_width
|
||||
wall_thickness = 1
|
||||
|
@ -60,7 +60,6 @@ support_z_distance = =layer_height * 2
|
||||
switch_extruder_prime_speed = 20
|
||||
switch_extruder_retraction_amount = 16.5
|
||||
top_bottom_thickness = 1.4
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =wall_line_width
|
||||
wall_thickness = 2
|
||||
|
@ -81,7 +81,6 @@ support_z_distance = 0
|
||||
switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 12
|
||||
top_bottom_thickness = 1
|
||||
travel_avoid_distance = 3
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =wall_line_width
|
||||
wall_thickness = 1
|
||||
|
@ -250,7 +250,8 @@ def test_getPropertyFallThrough(extruder_stack):
|
||||
container_indices = cura.Settings.CuraContainerStack._ContainerIndexes #Cache.
|
||||
for type_id, type_name in container_indices.IndexTypeMap.items():
|
||||
container = unittest.mock.MagicMock()
|
||||
container.getProperty = lambda key, property, type_id = type_id: type_id if (key == "layer_height" and property == "value") else None #Returns the container type ID as layer height, in order to identify it.
|
||||
# Return type_id when asking for value and -1 when asking for limit_to_extruder
|
||||
container.getProperty = lambda key, property, type_id = type_id: type_id if (key == "layer_height" and property == "value") else (None if property != "limit_to_extruder" else "-1") #Returns the container type ID as layer height, in order to identify it.
|
||||
container.hasProperty = lambda key, property: key == "layer_height"
|
||||
container.getMetaDataEntry = unittest.mock.MagicMock(return_value = type_name)
|
||||
mock_layer_heights[type_id] = container
|
||||
|
@ -69,11 +69,13 @@ def test_addExtruder(global_stack):
|
||||
|
||||
assert len(global_stack.extruders) == 0
|
||||
first_extruder = unittest.mock.MagicMock()
|
||||
first_extruder.getMetaDataEntry = lambda key: 0 if key == "position" else None
|
||||
with unittest.mock.patch("cura.Settings.CuraContainerStack.DefinitionContainer", unittest.mock.MagicMock):
|
||||
global_stack.addExtruder(first_extruder)
|
||||
assert len(global_stack.extruders) == 1
|
||||
assert global_stack.extruders[0] == first_extruder
|
||||
second_extruder = unittest.mock.MagicMock()
|
||||
second_extruder.getMetaDataEntry = lambda key: 1 if key == "position" else None
|
||||
with unittest.mock.patch("cura.Settings.CuraContainerStack.DefinitionContainer", unittest.mock.MagicMock):
|
||||
global_stack.addExtruder(second_extruder)
|
||||
assert len(global_stack.extruders) == 2
|
||||
@ -350,7 +352,7 @@ def test_getPropertyResolveInInstance(global_stack):
|
||||
instance_containers = {}
|
||||
for container_type in container_indices.IndexTypeMap:
|
||||
instance_containers[container_type] = unittest.mock.MagicMock() #Sets the resolve and value for bed temperature.
|
||||
instance_containers[container_type].getProperty = lambda key, property: (7.5 if property == "resolve" else (InstanceState.User if property == "state" else 5)) if (key == "material_bed_temperature") else None #7.5 resolve, 5 value.
|
||||
instance_containers[container_type].getProperty = lambda key, property: (7.5 if property == "resolve" else (InstanceState.User if property == "state" else (5 if property != "limit_to_extruder" else "-1"))) if (key == "material_bed_temperature") else None #7.5 resolve, 5 value.
|
||||
instance_containers[container_type].getMetaDataEntry = unittest.mock.MagicMock(return_value = container_indices.IndexTypeMap[container_type]) #Make queries for the type return the desired type.
|
||||
instance_containers[container_indices.Definition].getProperty = lambda key, property: 10 if (key == "material_bed_temperature" and property == "value") else None #Definition only has value.
|
||||
with unittest.mock.patch("cura.Settings.CuraContainerStack.DefinitionContainer", unittest.mock.MagicMock): #To guard against the type checking.
|
||||
@ -374,7 +376,7 @@ def test_getPropertyResolveInInstance(global_stack):
|
||||
# definitions.
|
||||
def test_getPropertyInstancesBeforeResolve(global_stack):
|
||||
value = unittest.mock.MagicMock() #Sets just the value.
|
||||
value.getProperty = lambda key, property: (10 if property == "value" else InstanceState.User) if key == "material_bed_temperature" else None
|
||||
value.getProperty = lambda key, property: (10 if property == "value" else (InstanceState.User if property != "limit_to_extruder" else "-1")) if key == "material_bed_temperature" else None
|
||||
value.getMetaDataEntry = unittest.mock.MagicMock(return_value = "quality")
|
||||
resolve = unittest.mock.MagicMock() #Sets just the resolve.
|
||||
resolve.getProperty = lambda key, property: 7.5 if (key == "material_bed_temperature" and property == "resolve") else None
|
||||
|
Loading…
x
Reference in New Issue
Block a user