mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-14 22:05:59 +08:00
Merge branch '2.4'
This commit is contained in:
commit
67d2d74f75
@ -721,7 +721,12 @@ class BuildVolume(SceneNode):
|
||||
#
|
||||
# \return A sequence of setting values, one for each extruder.
|
||||
def _getSettingFromAllExtruders(self, setting_key, property = "value"):
|
||||
return ExtruderManager.getInstance().getAllExtruderSettings(setting_key, property)
|
||||
all_values = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, property)
|
||||
all_types = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "type")
|
||||
for i in range(len(all_values)):
|
||||
if not all_values[i] and (all_types[i] == "int" or all_types[i] == "float"):
|
||||
all_values[i] = 0
|
||||
return all_values
|
||||
|
||||
## Private convenience function to get a setting from the support infill
|
||||
# extruder.
|
||||
@ -745,16 +750,21 @@ class BuildVolume(SceneNode):
|
||||
multi_extrusion = self._global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
||||
|
||||
if not multi_extrusion:
|
||||
return self._global_container_stack.getProperty(setting_key, property)
|
||||
stack = self._global_container_stack
|
||||
else:
|
||||
extruder_index = self._global_container_stack.getProperty(extruder_setting_key, "value")
|
||||
|
||||
extruder_index = self._global_container_stack.getProperty(extruder_setting_key, "value")
|
||||
if 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)]
|
||||
stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
|
||||
if extruder_index == "-1": # If extruder index is -1 use global instead
|
||||
return self._global_container_stack.getProperty(setting_key, property)
|
||||
|
||||
extruder_stack_id = ExtruderManager.getInstance().extruderIds[str(extruder_index)]
|
||||
stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
return stack.getProperty(setting_key, property)
|
||||
value = stack.getProperty(setting_key, property)
|
||||
setting_type = stack.getProperty(setting_key, "type")
|
||||
if not value and (setting_type == "int" or setting_type == "float"):
|
||||
return 0
|
||||
return value
|
||||
|
||||
## Convenience function to calculate the disallowed radius around the edge.
|
||||
#
|
||||
|
@ -395,7 +395,12 @@ class ExtruderManager(QObject):
|
||||
# \return \type{List[ContainerStack]} a list of
|
||||
def getActiveExtruderStacks(self):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
return list(self._extruder_trains[global_stack.getId()].values()) if global_stack else []
|
||||
|
||||
result = []
|
||||
if global_stack:
|
||||
for extruder in sorted(self._extruder_trains[global_stack.getId()]):
|
||||
result.append(self._extruder_trains[global_stack.getId()][extruder])
|
||||
return result
|
||||
|
||||
def __globalContainerStackChanged(self):
|
||||
self._addCurrentMachineExtruders()
|
||||
|
@ -412,6 +412,17 @@ class MachineManager(QObject):
|
||||
|
||||
return False
|
||||
|
||||
@pyqtProperty(int, notify = activeStackValueChanged)
|
||||
def numUserSettings(self):
|
||||
if not self._global_container_stack:
|
||||
return 0
|
||||
num_user_settings = 0
|
||||
num_user_settings += len(self._global_container_stack.getTop().findInstances())
|
||||
stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
|
||||
for stack in stacks:
|
||||
num_user_settings += len(stack.getTop().findInstances())
|
||||
return num_user_settings
|
||||
|
||||
## Delete a user setting from the global stack and all extruder stacks.
|
||||
# \param key \type{str} the name of the key to delete
|
||||
@pyqtSlot(str)
|
||||
@ -487,6 +498,17 @@ class MachineManager(QObject):
|
||||
|
||||
return ""
|
||||
|
||||
@pyqtProperty("QVariantList", notify=activeVariantChanged)
|
||||
def activeVariantNames(self):
|
||||
result = []
|
||||
if ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() is not None:
|
||||
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
|
||||
variant_container = stack.findContainer({"type": "variant"})
|
||||
if variant_container and variant_container != self._empty_variant_container:
|
||||
result.append(variant_container.getName())
|
||||
|
||||
return result
|
||||
|
||||
@pyqtProperty("QVariantList", notify = activeMaterialChanged)
|
||||
def activeMaterialNames(self):
|
||||
result = []
|
||||
@ -971,6 +993,15 @@ class MachineManager(QObject):
|
||||
|
||||
return ""
|
||||
|
||||
@pyqtProperty(str, notify=globalContainerChanged)
|
||||
def activeDefinitionName(self):
|
||||
if self._global_container_stack:
|
||||
definition = self._global_container_stack.getBottom()
|
||||
if definition:
|
||||
return definition.getName()
|
||||
|
||||
return ""
|
||||
|
||||
## Get the Definition ID to use to select quality profiles for the currently active machine
|
||||
# \returns DefinitionID (string) if found, empty string otherwise
|
||||
# \sa getQualityDefinitionId
|
||||
|
@ -55,9 +55,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
Logger.log("w", "Could not find reader that was able to read the scene data for 3MF workspace")
|
||||
return WorkspaceReader.PreReadResult.failed
|
||||
|
||||
|
||||
machine_name = ""
|
||||
machine_type = ""
|
||||
variant_type_name = i18n_catalog.i18nc("@label", "Nozzle")
|
||||
|
||||
num_extruders = 0
|
||||
# Check if there are any conflicts, so we can ask the user.
|
||||
archive = zipfile.ZipFile(file_name, "r")
|
||||
cura_file_names = [name for name in archive.namelist() if name.startswith("Cura/")]
|
||||
@ -87,13 +89,22 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
if not definitions:
|
||||
definition_container = DefinitionContainer(container_id)
|
||||
definition_container.deserialize(archive.open(definition_container_file).read().decode("utf-8"))
|
||||
if definition_container.getMetaDataEntry("type") != "extruder":
|
||||
machine_type = definition_container.getName()
|
||||
|
||||
else:
|
||||
if definitions[0].getMetaDataEntry("type") != "extruder":
|
||||
machine_type = definitions[0].getName()
|
||||
definition_container = definitions[0]
|
||||
|
||||
if definition_container.getMetaDataEntry("type") != "extruder":
|
||||
machine_type = definition_container.getName()
|
||||
variant_type_name = definition_container.getMetaDataEntry("variants_name", variant_type_name)
|
||||
else:
|
||||
num_extruders += 1
|
||||
Job.yieldThread()
|
||||
|
||||
if num_extruders == 0:
|
||||
num_extruders = 1 # No extruder stacks found, which means there is one extruder
|
||||
|
||||
extruders = num_extruders * [""]
|
||||
|
||||
material_labels = []
|
||||
material_conflict = False
|
||||
xml_material_profile = self._getXmlProfileClass()
|
||||
@ -138,6 +149,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
quality_type = instance_container.getName()
|
||||
elif container_type == "user":
|
||||
num_user_settings += len(instance_container._instances)
|
||||
|
||||
Job.yieldThread()
|
||||
num_visible_settings = 0
|
||||
try:
|
||||
@ -168,6 +180,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
self._dialog.setMachineName(machine_name)
|
||||
self._dialog.setMaterialLabels(material_labels)
|
||||
self._dialog.setMachineType(machine_type)
|
||||
self._dialog.setExtruders(extruders)
|
||||
self._dialog.setVariantType(variant_type_name)
|
||||
self._dialog.setHasObjectsOnPlate(Application.getInstance().getPlatformActivity)
|
||||
self._dialog.show()
|
||||
|
||||
|
@ -43,7 +43,9 @@ class WorkspaceDialog(QObject):
|
||||
self._quality_type = ""
|
||||
self._machine_name = ""
|
||||
self._machine_type = ""
|
||||
self._variant_type = ""
|
||||
self._material_labels = []
|
||||
self._extruders = []
|
||||
self._objects_on_plate = False
|
||||
|
||||
machineConflictChanged = pyqtSignal()
|
||||
@ -59,6 +61,16 @@ class WorkspaceDialog(QObject):
|
||||
objectsOnPlateChanged = pyqtSignal()
|
||||
numUserSettingsChanged = pyqtSignal()
|
||||
machineTypeChanged = pyqtSignal()
|
||||
variantTypeChanged = pyqtSignal()
|
||||
extrudersChanged = pyqtSignal()
|
||||
|
||||
@pyqtProperty(str, notify=variantTypeChanged)
|
||||
def variantType(self):
|
||||
return self._variant_type
|
||||
|
||||
def setVariantType(self, variant_type):
|
||||
self._variant_type = variant_type
|
||||
self.variantTypeChanged.emit()
|
||||
|
||||
@pyqtProperty(str, notify=machineTypeChanged)
|
||||
def machineType(self):
|
||||
@ -92,6 +104,14 @@ class WorkspaceDialog(QObject):
|
||||
self._material_labels = material_labels
|
||||
self.materialLabelsChanged.emit()
|
||||
|
||||
@pyqtProperty("QVariantList", notify=extrudersChanged)
|
||||
def extruders(self):
|
||||
return self._extruders
|
||||
|
||||
def setExtruders(self, extruders):
|
||||
self._extruders = extruders
|
||||
self.extrudersChanged.emit()
|
||||
|
||||
@pyqtProperty(str, notify = machineNameChanged)
|
||||
def machineName(self):
|
||||
return self._machine_name
|
||||
|
@ -16,9 +16,9 @@ UM.Dialog
|
||||
minimumWidth: 550
|
||||
maximumWidth: 550
|
||||
|
||||
height: 350
|
||||
minimumHeight: 350
|
||||
maximumHeight: 350
|
||||
height: 400
|
||||
minimumHeight: 400
|
||||
maximumHeight: 400
|
||||
property int comboboxHeight: 15
|
||||
property int spacerHeight: 10
|
||||
onClosing: manager.notifyClosed()
|
||||
@ -33,7 +33,15 @@ UM.Dialog
|
||||
}
|
||||
Item
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.topMargin: 20
|
||||
anchors.bottomMargin: 20
|
||||
anchors.leftMargin:20
|
||||
anchors.rightMargin: 20
|
||||
|
||||
UM.I18nCatalog
|
||||
{
|
||||
@ -133,6 +141,7 @@ UM.Dialog
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item // Spacer
|
||||
{
|
||||
height: spacerHeight
|
||||
@ -321,30 +330,47 @@ UM.Dialog
|
||||
height: spacerHeight
|
||||
width: height
|
||||
}
|
||||
Label
|
||||
Row
|
||||
{
|
||||
text: catalog.i18nc("@action:warning", "Loading a project will clear all models on the buildplate")
|
||||
visible: manager.hasObjectsOnPlate
|
||||
color: "red"
|
||||
width: parent.width
|
||||
wrapMode: Text.Wrap
|
||||
height: childrenRect.height
|
||||
visible: manager.hasObjectsOnPlate
|
||||
UM.RecolorImage
|
||||
{
|
||||
width: warningLabel.height
|
||||
height: width
|
||||
|
||||
source: UM.Theme.getIcon("notice")
|
||||
color: "black"
|
||||
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: warningLabel
|
||||
text: catalog.i18nc("@action:warning", "Loading a project will clear all models on the buildplate")
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rightButtons: [
|
||||
Button
|
||||
{
|
||||
id: ok_button
|
||||
text: catalog.i18nc("@action:button","OK");
|
||||
onClicked: { manager.closeBackend(); manager.onOkButtonClicked() }
|
||||
enabled: true
|
||||
},
|
||||
Button
|
||||
{
|
||||
id: cancel_button
|
||||
text: catalog.i18nc("@action:button","Cancel");
|
||||
onClicked: { manager.onCancelButtonClicked() }
|
||||
enabled: true
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: ok_button.left
|
||||
anchors.bottomMargin: - 0.5 * height
|
||||
anchors.rightMargin:2
|
||||
}
|
||||
]
|
||||
Button
|
||||
{
|
||||
id: ok_button
|
||||
text: catalog.i18nc("@action:button","Open");
|
||||
onClicked: { manager.closeBackend(); manager.onOkButtonClicked() }
|
||||
anchors.bottomMargin: - 0.5 * height
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
@ -100,7 +100,7 @@ SettingItem
|
||||
|
||||
maximumLength: 10;
|
||||
|
||||
validator: RegExpValidator { regExp: (definition.type == "int") ? /^-?[0-9]{0,10}/ : /^-?[0-9.,]{0,10}/ } // definition.type property from parent loader used to disallow fractional number entry
|
||||
validator: RegExpValidator { regExp: (definition.type == "int") ? /^-?[0-9]{0,10}$/ : /^-?[0-9]?[.,]?[0-9]{0,10}$/ } // definition.type property from parent loader used to disallow fractional number entry
|
||||
|
||||
Binding
|
||||
{
|
||||
@ -113,7 +113,8 @@ SettingItem
|
||||
// 2: quality
|
||||
// 3: material -> user changed material in materialspage
|
||||
// 4: variant
|
||||
// 5: machine
|
||||
// 5: machine_changes
|
||||
// 6: machine
|
||||
if ((base.resolve != "None" && base.resolve) && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
|
@ -46,7 +46,16 @@ UM.Dialog
|
||||
|
||||
Item
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.topMargin: 20
|
||||
anchors.bottomMargin: 20
|
||||
anchors.leftMargin:20
|
||||
anchors.rightMargin: 20
|
||||
|
||||
UM.SettingDefinitionsModel
|
||||
{
|
||||
id: definitionsModel
|
||||
@ -91,7 +100,21 @@ UM.Dialog
|
||||
text: catalog.i18nc("@action:label", "Printer settings")
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Type")
|
||||
width: parent.width / 3
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: Cura.MachineManager.activeDefinitionName
|
||||
width: parent.width / 3
|
||||
}
|
||||
}
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
@ -106,8 +129,42 @@ UM.Dialog
|
||||
text: Cura.MachineManager.activeMachineName
|
||||
width: parent.width / 3
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: Cura.MachineManager.activeMaterialNames
|
||||
delegate: Column
|
||||
{
|
||||
Item // Spacer
|
||||
{
|
||||
height: spacerHeight
|
||||
width: height
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Extruder %1").arg(index+1)
|
||||
}
|
||||
height: childrenRect.height
|
||||
width: parent.width
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "%1 & material").arg(Cura.MachineManager.activeDefinitionVariantsName)
|
||||
width: parent.width / 3
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: Cura.MachineManager.activeVariantNames[index] + ", " + modelData
|
||||
width: parent.width / 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item // Spacer
|
||||
{
|
||||
height: spacerHeight
|
||||
@ -119,7 +176,21 @@ UM.Dialog
|
||||
text: catalog.i18nc("@action:label", "Profile settings")
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Not in profile")
|
||||
width: parent.width / 3
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "%1 override(s)").arg(Cura.MachineManager.numUserSettings)
|
||||
width: parent.width / 3
|
||||
}
|
||||
visible: Cura.MachineManager.numUserSettings
|
||||
}
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
@ -136,7 +207,7 @@ UM.Dialog
|
||||
}
|
||||
|
||||
}
|
||||
Item // Spacer
|
||||
/*Item // Spacer
|
||||
{
|
||||
height: spacerHeight
|
||||
width: height
|
||||
@ -166,8 +237,7 @@ UM.Dialog
|
||||
width: parent.width / 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
Item // Spacer
|
||||
{
|
||||
@ -202,22 +272,34 @@ UM.Dialog
|
||||
checked: dontShowAgain
|
||||
}
|
||||
}
|
||||
}
|
||||
rightButtons: [
|
||||
Button
|
||||
{
|
||||
id: cancel_button
|
||||
text: catalog.i18nc("@action:button","Cancel");
|
||||
enabled: true
|
||||
onClicked: close()
|
||||
},
|
||||
|
||||
|
||||
Button
|
||||
{
|
||||
id: ok_button
|
||||
text: catalog.i18nc("@action:button","Save");
|
||||
enabled: true
|
||||
onClicked: {
|
||||
close(); yes() }
|
||||
close()
|
||||
yes()
|
||||
}
|
||||
anchors.bottomMargin: - 0.5 * height
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
}
|
||||
]
|
||||
|
||||
Button
|
||||
{
|
||||
id: cancel_button
|
||||
text: catalog.i18nc("@action:button","Cancel");
|
||||
enabled: true
|
||||
onClicked: close()
|
||||
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: ok_button.left
|
||||
anchors.bottomMargin: - 0.5 * height
|
||||
anchors.rightMargin:2
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user