|
@@ -3,9 +3,14 @@
|
|
|
|
|
|
import configparser #To parse the files we need to upgrade and write the new files.
|
|
|
import io #To serialise configparser output to a string.
|
|
|
+import os
|
|
|
+from urllib.parse import quote_plus
|
|
|
|
|
|
+from UM.Resources import Resources
|
|
|
from UM.VersionUpgrade import VersionUpgrade
|
|
|
|
|
|
+from cura.CuraApplication import CuraApplication
|
|
|
+
|
|
|
_removed_settings = { #Settings that were removed in 2.5.
|
|
|
"start_layers_at_same_position",
|
|
|
"sub_div_rad_mult"
|
|
@@ -20,6 +25,11 @@ _split_settings = { #These settings should be copied to all settings it was spli
|
|
|
#
|
|
|
# All of these methods are essentially stateless.
|
|
|
class VersionUpgrade25to26(VersionUpgrade):
|
|
|
+
|
|
|
+ def __init__(self):
|
|
|
+ super().__init__()
|
|
|
+ self._current_fdm_printer_count = 2
|
|
|
+
|
|
|
## Gets the version number from a CFG file in Uranium's 2.5 format.
|
|
|
#
|
|
|
# Since the format may change, this is implemented for the 2.5 format only
|
|
@@ -103,3 +113,145 @@ class VersionUpgrade25to26(VersionUpgrade):
|
|
|
output = io.StringIO()
|
|
|
parser.write(output)
|
|
|
return [filename], [output.getvalue()]
|
|
|
+
|
|
|
+ def upgradeMachineStack(self, serialised, filename):
|
|
|
+ parser = configparser.ConfigParser(interpolation=None)
|
|
|
+ parser.read_string(serialised)
|
|
|
+
|
|
|
+ # NOTE: This is for Custom FDM printers
|
|
|
+ # In 2.5, Custom FDM printers don't support multiple extruders, but since 2.6 they do.
|
|
|
+ machine_id = parser["general"]["id"]
|
|
|
+ quality_container_id = parser["containers"]["2"]
|
|
|
+ material_container_id = parser["containers"]["3"]
|
|
|
+ definition_container_id = parser["containers"]["6"]
|
|
|
+
|
|
|
+ if definition_container_id == "custom" and not self._checkCustomFdmPrinterHasExtruderStack(machine_id):
|
|
|
+ # go through all extruders and make sure that this custom FDM printer has 8 extruder stacks.
|
|
|
+ self._getNextUniqueCustomFdmPrinterExtruderStackIdIndex()
|
|
|
+ for position in range(8):
|
|
|
+ self._createCustomFdmPrinterExtruderStack(machine_id, position, quality_container_id, material_container_id)
|
|
|
+
|
|
|
+ # Update version numbers
|
|
|
+ parser["general"]["version"] = "3"
|
|
|
+ parser["metadata"]["setting_version"] = "1"
|
|
|
+
|
|
|
+ # Re-serialise the file.
|
|
|
+ output = io.StringIO()
|
|
|
+ parser.write(output)
|
|
|
+
|
|
|
+ return [filename], [output.getvalue()]
|
|
|
+
|
|
|
+ def _getNextUniqueCustomFdmPrinterExtruderStackIdIndex(self):
|
|
|
+ extruder_stack_dir = Resources.getPath(CuraApplication.ResourceTypes.ExtruderStack)
|
|
|
+ file_name_list = os.listdir(extruder_stack_dir)
|
|
|
+ file_name_list = [os.path.basename(file_name) for file_name in file_name_list]
|
|
|
+ while True:
|
|
|
+ self._current_fdm_printer_count += 1
|
|
|
+ stack_id_exists = False
|
|
|
+ for position in range(8):
|
|
|
+ stack_id = "custom_extruder_%s" % (position + 1)
|
|
|
+ if self._current_fdm_printer_count > 1:
|
|
|
+ stack_id += " #%s" % self._current_fdm_printer_count
|
|
|
+
|
|
|
+ if stack_id in file_name_list:
|
|
|
+ stack_id_exists = True
|
|
|
+ break
|
|
|
+ if not stack_id_exists:
|
|
|
+ break
|
|
|
+
|
|
|
+ return self._current_fdm_printer_count
|
|
|
+
|
|
|
+ def _checkCustomFdmPrinterHasExtruderStack(self, machine_id):
|
|
|
+ # go through all extruders and make sure that this custom FDM printer has extruder stacks.
|
|
|
+ extruder_stack_dir = Resources.getPath(CuraApplication.ResourceTypes.ExtruderStack)
|
|
|
+ has_extruders = False
|
|
|
+ for item in os.listdir(extruder_stack_dir):
|
|
|
+ file_path = os.path.join(extruder_stack_dir, item)
|
|
|
+ if not os.path.isfile(file_path):
|
|
|
+ continue
|
|
|
+
|
|
|
+ parser = configparser.ConfigParser()
|
|
|
+ try:
|
|
|
+ parser.read([file_path])
|
|
|
+ except:
|
|
|
+ # skip, it is not a valid stack file
|
|
|
+ continue
|
|
|
+
|
|
|
+ if "metadata" not in parser:
|
|
|
+ continue
|
|
|
+ if "machine" not in parser["metadata"]:
|
|
|
+ continue
|
|
|
+
|
|
|
+ if machine_id != parser["metadata"]["machine"]:
|
|
|
+ continue
|
|
|
+ has_extruders = True
|
|
|
+
|
|
|
+ return has_extruders
|
|
|
+
|
|
|
+ def _createCustomFdmPrinterExtruderStack(self, machine_id: str, position: int, quality_id: str, material_id: str):
|
|
|
+ stack_id = "custom_extruder_%s" % (position + 1)
|
|
|
+ if self._current_fdm_printer_count > 1:
|
|
|
+ stack_id += " #%s" % self._current_fdm_printer_count
|
|
|
+
|
|
|
+ definition_id = "custom_extruder_%s" % (position + 1)
|
|
|
+
|
|
|
+ # create a definition changes container for this stack
|
|
|
+ definition_changes_parser = self._getCustomFdmPrinterDefinitionChanges(stack_id)
|
|
|
+ definition_changes_id = definition_changes_parser["general"]["name"]
|
|
|
+
|
|
|
+ parser = configparser.ConfigParser()
|
|
|
+ parser.add_section("general")
|
|
|
+ parser["general"]["version"] = str(2)
|
|
|
+ parser["general"]["name"] = "Extruder %s" % (position + 1)
|
|
|
+ parser["general"]["id"] = stack_id
|
|
|
+
|
|
|
+ parser.add_section("metadata")
|
|
|
+ parser["metadata"]["type"] = "extruder_train"
|
|
|
+ parser["metadata"]["machine"] = machine_id
|
|
|
+ parser["metadata"]["position"] = str(position)
|
|
|
+
|
|
|
+ parser.add_section("containers")
|
|
|
+ parser["containers"]["0"] = "empty"
|
|
|
+ parser["containers"]["1"] = "empty_quality_changes"
|
|
|
+ parser["containers"]["2"] = quality_id
|
|
|
+ parser["containers"]["3"] = material_id
|
|
|
+ parser["containers"]["4"] = "empty_variant"
|
|
|
+ parser["containers"]["5"] = definition_changes_id
|
|
|
+ parser["containers"]["6"] = definition_id
|
|
|
+
|
|
|
+ definition_changes_output = io.StringIO()
|
|
|
+ definition_changes_parser.write(definition_changes_output)
|
|
|
+ definition_changes_filename = quote_plus(definition_changes_id) + ".inst.cfg"
|
|
|
+
|
|
|
+ extruder_output = io.StringIO()
|
|
|
+ parser.write(extruder_output)
|
|
|
+ extruder_filename = quote_plus(stack_id) + ".extruder.cfg"
|
|
|
+
|
|
|
+ extruder_stack_dir = Resources.getPath(CuraApplication.ResourceTypes.ExtruderStack)
|
|
|
+ definition_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.DefinitionChangesContainer)
|
|
|
+
|
|
|
+ with open(os.path.join(definition_changes_dir, definition_changes_filename), "w") as f:
|
|
|
+ f.write(definition_changes_output.getvalue())
|
|
|
+ with open(os.path.join(extruder_stack_dir, extruder_filename), "w") as f:
|
|
|
+ f.write(extruder_output.getvalue())
|
|
|
+
|
|
|
+ ## Creates a definition changes container which doesn't contain anything for the Custom FDM Printers.
|
|
|
+ # The container ID will be automatically generated according to the given stack name.
|
|
|
+ def _getCustomFdmPrinterDefinitionChanges(self, stack_id: str):
|
|
|
+ # In 2.5, there is no definition_changes container for the Custom FDM printer, so it should be safe to use the
|
|
|
+ # default name unless some one names the printer as something like "Custom FDM Printer_settings".
|
|
|
+ definition_changes_id = stack_id + "_settings"
|
|
|
+
|
|
|
+ parser = configparser.ConfigParser()
|
|
|
+ parser.add_section("general")
|
|
|
+ parser["general"]["version"] = str(2)
|
|
|
+ parser["general"]["name"] = definition_changes_id
|
|
|
+ parser["general"]["definition"] = "custom"
|
|
|
+
|
|
|
+ parser.add_section("metadata")
|
|
|
+ parser["metadata"]["type"] = "definition_changes"
|
|
|
+ parser["metadata"]["setting_version"] = str(1)
|
|
|
+
|
|
|
+ parser.add_section("values")
|
|
|
+
|
|
|
+ return parser
|