From 5374d253e9a260b84c9ddd3d2361aeb13de8d169 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 26 Jan 2016 13:27:42 +0100 Subject: [PATCH 1/4] Evaluate to old defaults if setting is missing If the setting is missing from the legacy profile, let it evaluate to the default in the legacy Cura. Contributes to issue CURA-37. --- .../LegacyProfileReader/DictionaryOfDoom.json | 82 +++++++++++++++++++ .../LegacyProfileReader.py | 25 +++--- 2 files changed, 97 insertions(+), 10 deletions(-) diff --git a/plugins/LegacyProfileReader/DictionaryOfDoom.json b/plugins/LegacyProfileReader/DictionaryOfDoom.json index f07bd61279..06c06aa497 100644 --- a/plugins/LegacyProfileReader/DictionaryOfDoom.json +++ b/plugins/LegacyProfileReader/DictionaryOfDoom.json @@ -71,5 +71,87 @@ "prime_tower_enable": "wipe_tower", "prime_tower_size": "math.sqrt(float(wipe_tower_volume) / float(layer_height))", "ooze_shield_enabled": "ooze_shield" + }, + + "defaults": { + "bottom_layer_speed": "20", + "bottom_thickness": "0.3", + "brim_line_count": "20", + "cool_head_lift": "False", + "cool_min_feedrate": "10", + "cool_min_layer_time": "5", + "fan_enabled": "True", + "fan_full_height": "0.5", + "fan_speed": "100", + "fan_speed_max": "100", + "filament_diameter": "2.85", + "filament_diameter2": "0", + "filament_diameter3": "0", + "filament_diameter4": "0", + "filament_diameter5": "0", + "filament_flow": "100.0", + "fill_density": "20", + "fill_overlap": "15", + "fix_horrible_extensive_stitching": "False", + "fix_horrible_union_all_type_a": "True", + "fix_horrible_union_all_type_b": "False", + "fix_horrible_use_open_bits": "False", + "infill_speed": "0.0", + "inset0_speed": "0.0", + "insetx_speed": "0.0", + "layer_height": "0.1", + "layer0_width_factor": "100", + "nozzle_size": "0.4", + "object_sink": "0.0", + "ooze_shield": "False", + "overlap_dual": "0.15", + "perimeter_before_infill": "False", + "platform_adhesion": "None", + "print_bed_temperature": "70", + "print_speed": "50", + "print_temperature": "210", + "print_temperature2": "0", + "print_temperature3": "0", + "print_temperature4": "0", + "print_temperature5": "0", + "raft_airgap": "0.22", + "raft_airgap_all": "0.0", + "raft_base_linewidth": "1.0", + "raft_base_thickness": "0.3", + "raft_interface_linewidth": "0.4", + "raft_interface_thickness": "0.27", + "raft_line_spacing": "3.0", + "raft_margin": "5.0", + "raft_surface_layers": "2", + "raft_surface_linewidth": "0.4", + "raft_surface_thickness": "0.27", + "retraction_amount": "4.5", + "retraction_combing": "All", + "retraction_dual_amount": "16.5", + "retraction_enable": "True", + "retraction_hop": "0.0", + "retraction_min_travel": "1.5", + "retraction_minimal_extrusion": "0.02", + "retraction_speed": "40.0", + "simple_mode": "False", + "skirt_gap": "3.0", + "skirt_line_count": "1", + "skirt_minimal_length": "150.0", + "solid_bottom": "True", + "solid_layer_thickness": "0.6", + "solid_top": "True", + "solidarea_speed": "0.0", + "spiralize": "False", + "support": "None", + "support_angle": "60", + "support_dual_extrusion": "Both", + "support_fill_rate": "15", + "support_type": "Lines", + "support_xy_distance": "0.7", + "support_z_distance": "0.15", + "travel_speed": "150.0", + "wall_thickness": "0.8", + "wipe_tower": "False", + "wipe_tower_volume": "15" } } \ No newline at end of file diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 923c6f92f9..f2709b1d91 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -30,16 +30,21 @@ class LegacyProfileReader(ProfileReader): # and their values, so that they can be used in evaluating the new setting # values as Python code. # - # \param parser The ConfigParser that finds the settings in the legacy - # profile. - # \param section The section in the profile where the settings should be - # found. + # \param config_parser The ConfigParser that finds the settings in the + # legacy profile. + # \param config_section The section in the profile where the settings + # should be found. + # \param json The JSON file to load the default setting values from. This + # should not be an URL but a pre-loaded JSON handle. # \return A set of local variables, one for each setting in the legacy # profile. - def prepareLocals(self, parser, section): + def prepareLocals(self, config_parser, config_section, json): locals = {} - for option in parser.options(section): - locals[option] = parser.get(section, option) + for key in json["defaults"]: #We have to copy over all defaults from the JSON handle to a normal dict. + locals[key] = json["defaults"][key] + print("Setting " + key + " to " + json["defaults"][key]) + for option in config_parser.options(config_section): + locals[option] = config_parser.get(config_section, option) return locals ## Reads a legacy Cura profile from a file and returns it. @@ -70,8 +75,6 @@ class LegacyProfileReader(ProfileReader): if not section: #No section starting with "profile" was found. Probably not a proper INI file. return None - legacy_settings = self.prepareLocals(parser, section) #Gets the settings from the legacy profile. - try: with open(os.path.join(PluginRegistry.getInstance().getPluginPath("LegacyProfileReader"), "DictionaryOfDoom.json"), "r", -1, "utf-8") as f: dict_of_doom = json.load(f) #Parse the Dictionary of Doom. @@ -82,6 +85,8 @@ class LegacyProfileReader(ProfileReader): Logger.log("e", "Could not parse DictionaryOfDoom.json: %s", str(e)) return None + legacy_settings = self.prepareLocals(parser, section, dict_of_doom) #Gets the settings from the legacy profile. + #Check the target version in the Dictionary of Doom with this application version. if "target_version" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no target version. Is it the correct JSON file?") @@ -99,7 +104,7 @@ class LegacyProfileReader(ProfileReader): try: new_value = eval(compiled, {"math": math}, legacy_settings) #Pass the legacy settings as local variables to allow access to in the evaluation. except Exception as e: #Probably some setting name that was missing or something else that went wrong in the ini file. - Logger.log("w", "Setting " + new_setting + " could not be set because the evaluation failed. Something is probably missing from the imported legacy profile.") + Logger.log("w", "Setting " + new_setting + " could not be set because the evaluation failed (" + old_setting_expression + "). Something is probably missing from the imported legacy profile.") continue if profile.getSettingValue(new_setting) != new_value: #Not equal to the default. profile.setSettingValue(new_setting, new_value) #Store the setting in the profile! From c0b5832a5953201eca7ba8e30e89d1834f5a0ff6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 26 Jan 2016 13:32:52 +0100 Subject: [PATCH 2/4] Remove debug prints Shouldn't have committed those. Sorry! Contributes to issue CURA-37. --- plugins/LegacyProfileReader/LegacyProfileReader.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index f2709b1d91..61fbe3d815 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -42,7 +42,6 @@ class LegacyProfileReader(ProfileReader): locals = {} for key in json["defaults"]: #We have to copy over all defaults from the JSON handle to a normal dict. locals[key] = json["defaults"][key] - print("Setting " + key + " to " + json["defaults"][key]) for option in config_parser.options(config_section): locals[option] = config_parser.get(config_section, option) return locals @@ -104,7 +103,7 @@ class LegacyProfileReader(ProfileReader): try: new_value = eval(compiled, {"math": math}, legacy_settings) #Pass the legacy settings as local variables to allow access to in the evaluation. except Exception as e: #Probably some setting name that was missing or something else that went wrong in the ini file. - Logger.log("w", "Setting " + new_setting + " could not be set because the evaluation failed (" + old_setting_expression + "). Something is probably missing from the imported legacy profile.") + Logger.log("w", "Setting " + new_setting + " could not be set because the evaluation failed. Something is probably missing from the imported legacy profile.") continue if profile.getSettingValue(new_setting) != new_value: #Not equal to the default. profile.setSettingValue(new_setting, new_value) #Store the setting in the profile! From e7b2586d367a9413e1a66db9744c9de3a53696b7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 26 Jan 2016 13:50:46 +0100 Subject: [PATCH 3/4] Don't add to profile if setting is legacy default If a setting is equal to the legacy setting's default value, then it doesn't get added to the profile either. Contributes to issue CURA-37. --- .../LegacyProfileReader.py | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 61fbe3d815..bd38b50a84 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -23,6 +23,19 @@ class LegacyProfileReader(ProfileReader): def __init__(self): super().__init__() + ## Prepares the default values of all legacy settings. + # + # These are loaded from the Dictionary of Doom. + # + # \param json The JSON file to load the default setting values from. This + # should not be a URL but a pre-loaded JSON handle. + # \return A dictionary of the default values of the legacy Cura version. + def prepareDefaults(self, json): + defaults = {} + for key in json["defaults"]: #We have to copy over all defaults from the JSON handle to a normal dict. + defaults[key] = json["defaults"][key] + return defaults + ## Prepares the local variables that can be used in evaluation of computing # new setting values from the old ones. # @@ -34,14 +47,11 @@ class LegacyProfileReader(ProfileReader): # legacy profile. # \param config_section The section in the profile where the settings # should be found. - # \param json The JSON file to load the default setting values from. This - # should not be an URL but a pre-loaded JSON handle. + # \param defaults The default values for all settings in the legacy Cura. # \return A set of local variables, one for each setting in the legacy # profile. - def prepareLocals(self, config_parser, config_section, json): - locals = {} - for key in json["defaults"]: #We have to copy over all defaults from the JSON handle to a normal dict. - locals[key] = json["defaults"][key] + def prepareLocals(self, config_parser, config_section, defaults): + locals = defaults.copy() #Don't edit the original! for option in config_parser.options(config_section): locals[option] = config_parser.get(config_section, option) return locals @@ -84,7 +94,8 @@ class LegacyProfileReader(ProfileReader): Logger.log("e", "Could not parse DictionaryOfDoom.json: %s", str(e)) return None - legacy_settings = self.prepareLocals(parser, section, dict_of_doom) #Gets the settings from the legacy profile. + defaults = self.prepareDefaults(dict_of_doom) + legacy_settings = self.prepareLocals(parser, section, defaults) #Gets the settings from the legacy profile. #Check the target version in the Dictionary of Doom with this application version. if "target_version" not in dict_of_doom: @@ -102,10 +113,11 @@ class LegacyProfileReader(ProfileReader): compiled = compile(old_setting_expression, new_setting, "eval") try: new_value = eval(compiled, {"math": math}, legacy_settings) #Pass the legacy settings as local variables to allow access to in the evaluation. + value_using_defaults = eval(compiled, {"math": math}, defaults) #Evaluate again using only the default values to try to see if they are default. except Exception as e: #Probably some setting name that was missing or something else that went wrong in the ini file. Logger.log("w", "Setting " + new_setting + " could not be set because the evaluation failed. Something is probably missing from the imported legacy profile.") continue - if profile.getSettingValue(new_setting) != new_value: #Not equal to the default. + if new_value != value_using_defaults and profile.getSettingValue(new_setting) != new_value: #Not equal to the default in the new Cura OR the default in the legacy Cura. profile.setSettingValue(new_setting, new_value) #Store the setting in the profile! return profile \ No newline at end of file From f09b92728860a3ae4c29ebf07222aeb40667e0bf Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 26 Jan 2016 13:58:00 +0100 Subject: [PATCH 4/4] Add check if resulting profile is empty If it is, a warning is logged. Contributes to issue CURA-37. --- plugins/LegacyProfileReader/LegacyProfileReader.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index bd38b50a84..6b5a4a3aca 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -63,6 +63,7 @@ class LegacyProfileReader(ProfileReader): # file could not be read or didn't contain a valid profile, \code None # \endcode is returned. def read(self, file_name): + Logger.log("i", "Importing legacy profile from file " + file_name + ".") profile = Profile(machine_manager = Application.getInstance().getMachineManager(), read_only = False) #Create an empty profile. profile.setName("Imported Legacy Profile") @@ -120,4 +121,7 @@ class LegacyProfileReader(ProfileReader): if new_value != value_using_defaults and profile.getSettingValue(new_setting) != new_value: #Not equal to the default in the new Cura OR the default in the legacy Cura. profile.setSettingValue(new_setting, new_value) #Store the setting in the profile! + if len(profile.getChangedSettings()) == 0: + Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.") + return profile \ No newline at end of file