mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-14 07:56:00 +08:00
Merge branch '2.3' of https://github.com/Ultimaker/Cura into 2.3
This commit is contained in:
commit
73d7e22efe
@ -58,9 +58,9 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
||||
def setReadOnly(self, read_only):
|
||||
super().setReadOnly(read_only)
|
||||
|
||||
basefile = self.getMetaDataEntry("base_file", self._id) #if basefile is none, this is a basefile.
|
||||
basefile = self.getMetaDataEntry("base_file", self._id) # if basefile is self.id, this is a basefile.
|
||||
for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile):
|
||||
container._read_only = read_only
|
||||
container._read_only = read_only # prevent loop instead of calling setReadOnly
|
||||
|
||||
## Overridden from InstanceContainer
|
||||
def setMetaDataEntry(self, key, value):
|
||||
@ -69,7 +69,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
||||
|
||||
super().setMetaDataEntry(key, value)
|
||||
|
||||
basefile = self.getMetaDataEntry("base_file", self._id) #if basefile is none, this is a basefile.
|
||||
basefile = self.getMetaDataEntry("base_file", self._id) #if basefile is self.id, this is a basefile.
|
||||
# Update all containers that share GUID and basefile
|
||||
for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile):
|
||||
container.setMetaData(copy.deepcopy(self._metadata))
|
||||
@ -95,15 +95,15 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
||||
container.setName(new_name)
|
||||
|
||||
## Overridden from InstanceContainer
|
||||
def setProperty(self, key, property_name, property_value, container = None):
|
||||
if self.isReadOnly():
|
||||
return
|
||||
|
||||
super().setProperty(key, property_name, property_value)
|
||||
|
||||
basefile = self.getMetaDataEntry("base_file", self._id) #if basefile is none, this is a basefile.
|
||||
for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile):
|
||||
container._dirty = True
|
||||
# def setProperty(self, key, property_name, property_value, container = None):
|
||||
# if self.isReadOnly():
|
||||
# return
|
||||
#
|
||||
# super().setProperty(key, property_name, property_value)
|
||||
#
|
||||
# basefile = self.getMetaDataEntry("base_file", self._id) #if basefile is self.id, this is a basefile.
|
||||
# for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile):
|
||||
# container._dirty = True
|
||||
|
||||
## Overridden from InstanceContainer
|
||||
def serialize(self):
|
||||
@ -272,29 +272,90 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
||||
self._inherited_files.append(path)
|
||||
return ET.fromstring(contents)
|
||||
|
||||
# The XML material profile can have specific settings for machines.
|
||||
# Some machines share profiles, so they are only created once.
|
||||
# This function duplicates those elements so that each machine tag only has one identifier.
|
||||
def _flattenMachinesXML(self, element):
|
||||
settings_element = element.find("./um:settings", self.__namespaces)
|
||||
machines = settings_element.iterfind("./um:machine", self.__namespaces)
|
||||
machines_to_add = []
|
||||
machines_to_remove = []
|
||||
for machine in machines:
|
||||
identifiers = list(machine.iterfind("./um:machine_identifier", self.__namespaces))
|
||||
has_multiple_identifiers = len(identifiers) > 1
|
||||
if has_multiple_identifiers:
|
||||
# Multiple identifiers found. We need to create a new machine element and copy all it's settings there.
|
||||
for identifier in identifiers:
|
||||
new_machine = copy.deepcopy(machine)
|
||||
# Create list of identifiers that need to be removed from the copied element.
|
||||
other_identifiers = [self._createKey(other_identifier) for other_identifier in identifiers if other_identifier is not identifier]
|
||||
# As we can only remove by exact object reference, we need to look through the identifiers of copied machine.
|
||||
new_machine_identifiers = list(new_machine.iterfind("./um:machine_identifier", self.__namespaces))
|
||||
for new_machine_identifier in new_machine_identifiers:
|
||||
key = self._createKey(new_machine_identifier)
|
||||
# Key was in identifiers to remove, so this element needs to be purged
|
||||
if key in other_identifiers:
|
||||
new_machine.remove(new_machine_identifier)
|
||||
machines_to_add.append(new_machine)
|
||||
machines_to_remove.append(machine)
|
||||
else:
|
||||
pass # Machine only has one identifier. Nothing to do.
|
||||
# Remove & add all required machines.
|
||||
for machine_to_remove in machines_to_remove:
|
||||
settings_element.remove(machine_to_remove)
|
||||
for machine_to_add in machines_to_add:
|
||||
settings_element.append(machine_to_add)
|
||||
return element
|
||||
|
||||
def _mergeXML(self, first, second):
|
||||
result = copy.deepcopy(first)
|
||||
self._combineElement(result, second)
|
||||
self._combineElement(self._flattenMachinesXML(result), self._flattenMachinesXML(second))
|
||||
return result
|
||||
|
||||
def _createKey(self, element):
|
||||
key = element.tag.split("}")[-1]
|
||||
if "key" in element.attrib:
|
||||
key += " key:" + element.attrib["key"]
|
||||
if "manufacturer" in element.attrib:
|
||||
key += " manufacturer:" + element.attrib["manufacturer"]
|
||||
if "product" in element.attrib:
|
||||
key += " product:" + element.attrib["product"]
|
||||
if key == "machine":
|
||||
for item in element:
|
||||
if "machine_identifier" in item.tag:
|
||||
key += " " + item.attrib["product"]
|
||||
return key
|
||||
|
||||
# Recursively merges XML elements. Updates either the text or children if another element is found in first.
|
||||
# If it does not exist, copies it from second.
|
||||
def _combineElement(self, first, second):
|
||||
# Create a mapping from tag name to element.
|
||||
mapping = {el.tag: el for el in first}
|
||||
for el in second:
|
||||
if len(el): # Check if element has children.
|
||||
|
||||
mapping = {}
|
||||
for element in first:
|
||||
key = self._createKey(element)
|
||||
mapping[key] = element
|
||||
for element in second:
|
||||
key = self._createKey(element)
|
||||
if len(element): # Check if element has children.
|
||||
try:
|
||||
self._combineElement(mapping[el.tag], el) # Multiple elements, handle those.
|
||||
if "setting " in key:
|
||||
# Setting can have points in it. In that case, delete all values and override them.
|
||||
for child in list(mapping[key]):
|
||||
mapping[key].remove(child)
|
||||
for child in element:
|
||||
mapping[key].append(child)
|
||||
else:
|
||||
self._combineElement(mapping[key], element) # Multiple elements, handle those.
|
||||
except KeyError:
|
||||
mapping[el.tag] = el
|
||||
first.append(el)
|
||||
mapping[key] = element
|
||||
first.append(element)
|
||||
else:
|
||||
try:
|
||||
mapping[el.tag].text = el.text
|
||||
mapping[key].text = element.text
|
||||
except KeyError: # Not in the mapping, so simply add it
|
||||
mapping[el.tag] = el
|
||||
first.append(el)
|
||||
mapping[key] = element
|
||||
first.append(element)
|
||||
|
||||
## Overridden from InstanceContainer
|
||||
def deserialize(self, serialized):
|
||||
@ -305,7 +366,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
||||
|
||||
# TODO: Add material verfication
|
||||
self.addMetaDataEntry("status", "unknown")
|
||||
|
||||
|
||||
inherits = data.find("./um:inherits", self.__namespaces)
|
||||
if inherits is not None:
|
||||
inherited = self._resolveInheritance(inherits.text)
|
||||
|
@ -8,6 +8,7 @@
|
||||
"author": "Calvindog717",
|
||||
"manufacturer": "PrintrBot",
|
||||
"category": "Other",
|
||||
"platform": "printrbot_simple_metal_platform.stl",
|
||||
"file_formats": "text/x-gcode"
|
||||
},
|
||||
|
||||
@ -17,7 +18,7 @@
|
||||
"machine_height": { "default_value": 150 },
|
||||
"machine_depth": { "default_value": 140 },
|
||||
"machine_center_is_zero": { "default_value": false },
|
||||
"machine_nozzle_size": { "default_value": 0.3 },
|
||||
"machine_nozzle_size": { "default_value": 0.4 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"machine_nozzle_heat_up_speed": { "default_value": 2 },
|
||||
"machine_nozzle_cool_down_speed": { "default_value": 2 },
|
||||
@ -33,10 +34,10 @@
|
||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||
|
||||
"machine_start_gcode": {
|
||||
"default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG29 ; auto bed-levelling\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."
|
||||
"default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;home X/Y\nG28 Z0 ;home Z\nG92 E0 ;zero the extruded length\nG29 ;initiate auto bed leveling sequence\nG92 X132.4 Y20 ;correct bed origin (G29 changes it)"
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning"
|
||||
"default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nM106 S0 ;fan off\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit\nG1 Z+1 E-5 F9000 ;move Z up a bit and retract even more\nG28 X0 Y0 ;home X/Y, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
Automatically generated PLA profile. Data in this file may not be not correct.
|
||||
-->
|
||||
<fdmmaterial xmlns="http://www.ultimaker.com/material">
|
||||
<inherits>generic_pla</inherits>
|
||||
<metadata>
|
||||
<name>
|
||||
<brand>Ultimaker</brand>
|
||||
@ -36,16 +37,15 @@ Automatically generated PLA profile. Data in this file may not be not correct.
|
||||
<machine_identifier manufacturer="Ultimaker" product="Ultimaker 2"/>
|
||||
<machine_identifier manufacturer="Ultimaker" product="Ultimaker 2 Go"/>
|
||||
<machine_identifier manufacturer="Ultimaker" product="Ultimaker 2 Extended"/>
|
||||
<setting key="standby temperature">150</setting>
|
||||
<setting key="processing temperature graph">
|
||||
<point flow="2" temperature="180"/>
|
||||
<point flow="10" temperature="230"/>
|
||||
<point flow="2" temperature="20"/>
|
||||
<point flow="10" temperature="20"/>
|
||||
</setting>
|
||||
</machine>
|
||||
|
||||
<machine>
|
||||
<machine_identifier manufacturer="Ultimaker" product="Ultimaker Original"/>
|
||||
<setting key="standby temperature">150</setting>
|
||||
<setting key="standby temperature">180</setting>
|
||||
</machine>
|
||||
</settings>
|
||||
</fdmmaterial>
|
||||
|
BIN
resources/meshes/printrbot_simple_metal_platform.stl
Normal file
BIN
resources/meshes/printrbot_simple_metal_platform.stl
Normal file
Binary file not shown.
@ -129,6 +129,7 @@ UM.ManagementPage
|
||||
enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId
|
||||
onClicked: Cura.MachineManager.setActiveMaterial(base.currentItem.id)
|
||||
},
|
||||
/* // apparently visible does not work on OS X
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Duplicate");
|
||||
@ -153,6 +154,7 @@ UM.ManagementPage
|
||||
}
|
||||
visible: false;
|
||||
},
|
||||
*/
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Remove");
|
||||
@ -160,6 +162,7 @@ UM.ManagementPage
|
||||
enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id)
|
||||
onClicked: confirmDialog.open()
|
||||
},
|
||||
/* // apparently visible does not work on OS X
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Import");
|
||||
@ -167,6 +170,7 @@ UM.ManagementPage
|
||||
onClicked: importDialog.open();
|
||||
visible: false;
|
||||
},
|
||||
*/
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Export")
|
||||
|
@ -246,8 +246,8 @@ Item {
|
||||
// This ensures that the value in any of the deeper containers need not be removed, which is
|
||||
// needed for the reset button (which deletes the top value) to correctly go back to profile
|
||||
// defaults.
|
||||
propertyProvider.setPropertyValue("state", "InstanceState.Calculated")
|
||||
propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry))
|
||||
propertyProvider.setPropertyValue("state", "InstanceState.Calculated")
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user