diff --git a/cura/API/Interface/Settings.py b/cura/API/Interface/Settings.py index 084023b9bd..6437de268a 100644 --- a/cura/API/Interface/Settings.py +++ b/cura/API/Interface/Settings.py @@ -3,7 +3,7 @@ from dataclasses import asdict -from typing import cast, Dict, TYPE_CHECKING +from typing import cast, Dict, TYPE_CHECKING, Any from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.SettingFunction import SettingFunction @@ -54,6 +54,15 @@ class Settings: return self.application.getSidebarCustomMenuItems() + def getAllGlobalSettings(self) -> Dict[str, Any]: + global_stack = cast(GlobalStack, self.application.getGlobalContainerStack()) + + all_settings = {} + for setting in global_stack.getAllKeys(): + all_settings[setting] = self._retrieveValue(global_stack, setting) + + return all_settings + def getSliceMetadata(self) -> Dict[str, Dict[str, Dict[str, str]]]: """Get all changed settings and all settings. For each extruder and the global stack""" print_information = self.application.getPrintInformation() @@ -71,24 +80,16 @@ class Settings: "quality": asdict(machine_manager.activeQualityDisplayNameMap()), } - def _retrieveValue(container: InstanceContainer, setting_: str): - value_ = container.getProperty(setting_, "value") - for _ in range(0, 1024): # Prevent possibly endless loop by not using a limit. - if not isinstance(value_, SettingFunction): - return value_ # Success! - value_ = value_(container) - return 0 # Fallback value after breaking possibly endless loop. - global_stack = cast(GlobalStack, self.application.getGlobalContainerStack()) # Add global user or quality changes global_flattened_changes = InstanceContainer.createMergedInstanceContainer(global_stack.userChanges, global_stack.qualityChanges) for setting in global_flattened_changes.getAllKeys(): - settings["global"]["changes"][setting] = _retrieveValue(global_flattened_changes, setting) + settings["global"]["changes"][setting] = self._retrieveValue(global_flattened_changes, setting) # Get global all settings values without user or quality changes for setting in global_stack.getAllKeys(): - settings["global"]["all_settings"][setting] = _retrieveValue(global_stack, setting) + settings["global"]["all_settings"][setting] = self._retrieveValue(global_stack, setting) for i, extruder in enumerate(global_stack.extruderList): # Add extruder fields to settings dictionary @@ -100,10 +101,19 @@ class Settings: # Add extruder user or quality changes extruder_flattened_changes = InstanceContainer.createMergedInstanceContainer(extruder.userChanges, extruder.qualityChanges) for setting in extruder_flattened_changes.getAllKeys(): - settings[f"extruder_{i}"]["changes"][setting] = _retrieveValue(extruder_flattened_changes, setting) + settings[f"extruder_{i}"]["changes"][setting] = self._retrieveValue(extruder_flattened_changes, setting) # Get extruder all settings values without user or quality changes for setting in extruder.getAllKeys(): - settings[f"extruder_{i}"]["all_settings"][setting] = _retrieveValue(extruder, setting) + settings[f"extruder_{i}"]["all_settings"][setting] = self._retrieveValue(extruder, setting) return settings + + @staticmethod + def _retrieveValue(container: InstanceContainer, setting_: str): + value_ = container.getProperty(setting_, "value") + for _ in range(0, 1024): # Prevent possibly endless loop by not using a limit. + if not isinstance(value_, SettingFunction): + return value_ # Success! + value_ = value_(container) + return 0 # Fallback value after breaking possibly endless loop. \ No newline at end of file diff --git a/plugins/3MFWriter/BambuLabVariant.py b/plugins/3MFWriter/BambuLabVariant.py index 56337bbc31..69814505ad 100644 --- a/plugins/3MFWriter/BambuLabVariant.py +++ b/plugins/3MFWriter/BambuLabVariant.py @@ -31,6 +31,7 @@ GCODE_MD5_PATH = f"{GCODE_PATH}.md5" MODEL_SETTINGS_PATH = f"{METADATA_PATH}/model_settings.config" PLATE_DESC_PATH = f"{METADATA_PATH}/plate_1.json" SLICE_INFO_PATH = f"{METADATA_PATH}/slice_info.config" +PROJECT_SETTINGS_PATH = f"{METADATA_PATH}/project_settings.config" class BambuLabVariant(ThreeMFVariant): """BambuLab specific implementation of the 3MF format.""" @@ -48,7 +49,7 @@ class BambuLabVariant(ThreeMFVariant): # Add relations elements for thumbnails ET.SubElement(relations_element, "Relationship", Target="/" + THUMBNAIL_PATH_MULTIPLATE, Id="rel-2", - Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail") + pe="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail") ET.SubElement(relations_element, "Relationship", Target="/" + THUMBNAIL_PATH_MULTIPLATE, Id="rel-4", @@ -74,6 +75,7 @@ class BambuLabVariant(ThreeMFVariant): self._storeModelSettings(archive) self._storePlateDesc(archive) self._storeSliceInfo(archive) + self._storeProjectSettings(archive) def _storeGCode(self, archive: zipfile.ZipFile, metadata_relations_element: ET.Element): """Store GCode data in the archive.""" @@ -166,3 +168,9 @@ class BambuLabVariant(ThreeMFVariant): used_g=str(used_g)) self._writer._storeElementTree(archive, SLICE_INFO_PATH, config) + + def _storeProjectSettings(self, archive: zipfile.ZipFile): + api = CuraApplication.getInstance().getCuraAPI() + file = zipfile.ZipInfo(PROJECT_SETTINGS_PATH) + json_string = json.dumps(api.interface.settings.getAllGlobalSettings(), separators=(", ", ": "), indent=4) + archive.writestr(file, json_string.encode("UTF-8")) \ No newline at end of file