From 8fe6e82459e305b4aba7fb8c9f791ddf74bef521 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 23 Jan 2018 11:14:57 +0100 Subject: [PATCH 01/11] Added Setting visibility preset CURA-3710 --- resources/visibility_presets/advanced.cfg | 32 +++++++++++ resources/visibility_presets/basic.cfg | 66 +++++++++++++++++++++++ resources/visibility_presets/expert.cfg | 66 +++++++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 resources/visibility_presets/advanced.cfg create mode 100644 resources/visibility_presets/basic.cfg create mode 100644 resources/visibility_presets/expert.cfg diff --git a/resources/visibility_presets/advanced.cfg b/resources/visibility_presets/advanced.cfg new file mode 100644 index 0000000000..335ae67afe --- /dev/null +++ b/resources/visibility_presets/advanced.cfg @@ -0,0 +1,32 @@ +[general] +name = Advanced +weight = 2 + +[machine_settings] + +[resolution] +layer_height + +[shell] + +[infill] + +[material] + +[speed] + +[travel] + +[cooling] + +[support] + +[platform_adhesion] + +[dual] + +[meshfix] + +[blackmagic] + +[experimental] \ No newline at end of file diff --git a/resources/visibility_presets/basic.cfg b/resources/visibility_presets/basic.cfg new file mode 100644 index 0000000000..062feb9189 --- /dev/null +++ b/resources/visibility_presets/basic.cfg @@ -0,0 +1,66 @@ +[general] +name = Basic +weight = 1 + +[machine_settings] + +[resolution] +layer_height + +[shell] +wall_thickness +top_bottom_thickness +z_seam_x +z_seam_y + +[infill] +infill_sparse_density +gradual_infill_steps + +[material] +material_print_temperature +material_bed_temperature +material_diameter +material_flow +retraction_enable + +[speed] +speed_print +speed_travel +acceleration_print +acceleration_travel +jerk_print +jerk_travel + +[travel] + +[cooling] +cool_fan_enabled + +[support] +support_enable +support_extruder_nr +support_type + +[platform_adhesion] +adhesion_type +adhesion_extruder_nr +brim_width +raft_airgap +layer_0_z_overlap +raft_surface_layers + +[dual] +prime_tower_enable +prime_tower_size +prime_tower_position_x +prime_tower_position_y + +[meshfix] + +[blackmagic] +print_sequence +infill_mesh +cutting_mesh + +[experimental] \ No newline at end of file diff --git a/resources/visibility_presets/expert.cfg b/resources/visibility_presets/expert.cfg new file mode 100644 index 0000000000..130c75c6b9 --- /dev/null +++ b/resources/visibility_presets/expert.cfg @@ -0,0 +1,66 @@ +[general] +name = Expert +weight = 3 + +[machine_settings] + +[resolution] +layer_height + +[shell] +wall_thickness +top_bottom_thickness +z_seam_x +z_seam_y + +[infill] +infill_sparse_density +gradual_infill_steps + +[material] +material_print_temperature +material_bed_temperature +material_diameter +material_flow +retraction_enable + +[speed] +speed_print +speed_travel +acceleration_print +acceleration_travel +jerk_print +jerk_travel + +[travel] + +[cooling] +cool_fan_enabled + +[support] +support_enable +support_extruder_nr +support_type + +[platform_adhesion] +adhesion_type +adhesion_extruder_nr +brim_width +raft_airgap +layer_0_z_overlap +raft_surface_layers + +[dual] +prime_tower_enable +prime_tower_size +prime_tower_position_x +prime_tower_position_y + +[meshfix] + +[blackmagic] +print_sequence +infill_mesh +cutting_mesh + +[experimental] \ No newline at end of file From 54dc63a596d99cd9dd292a69856a6f11bdd3612a Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 23 Jan 2018 11:24:27 +0100 Subject: [PATCH 02/11] Add missing changes CURA-3710 --- cura/CuraApplication.py | 151 ++++++++++++------ plugins/3MFReader/ThreeMFWorkspaceReader.py | 1 + .../qml/Preferences/SettingVisibilityPage.qml | 108 ++++++++++++- 3 files changed, 206 insertions(+), 54 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 9261f0df1a..0df64dbacb 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -87,6 +87,7 @@ from PyQt5.QtGui import QColor, QIcon from PyQt5.QtWidgets import QMessageBox from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType +from configparser import ConfigParser import sys import os.path import numpy @@ -348,57 +349,19 @@ class CuraApplication(QtApplication): preferences.setDefault("local_file/last_used_type", "text/x-gcode") - preferences.setDefault("general/visible_settings", """ - machine_settings - resolution - layer_height - shell - wall_thickness - top_bottom_thickness - z_seam_x - z_seam_y - infill - infill_sparse_density - gradual_infill_steps - material - material_print_temperature - material_bed_temperature - material_diameter - material_flow - retraction_enable - speed - speed_print - speed_travel - acceleration_print - acceleration_travel - jerk_print - jerk_travel - travel - cooling - cool_fan_enabled - support - support_enable - support_extruder_nr - support_type - platform_adhesion - adhesion_type - adhesion_extruder_nr - brim_width - raft_airgap - layer_0_z_overlap - raft_surface_layers - dual - prime_tower_enable - prime_tower_size - prime_tower_position_x - prime_tower_position_y - meshfix - blackmagic - print_sequence - infill_mesh - cutting_mesh - experimental - """.replace("\n", ";").replace(" ", "")) + setting_visibily_preset_names = self.getVisibilitySettingsPresetTypes() + preferences.setDefault("general/visible_settings_preset", setting_visibily_preset_names) + + visible_settings_preset_choice = Preferences.getInstance().getValue("general/visible_settings_preset_choice") + + default_visibility_preset = "Basic" + if visible_settings_preset_choice == "" or visible_settings_preset_choice is None: + if not visible_settings_preset_choice in setting_visibily_preset_names: + visible_settings_preset_choice = default_visibility_preset + + visible_settings = self.getVisibilitySettingPreset(settings_preset_name = visible_settings_preset_choice) + preferences.setDefault("general/visible_settings", visible_settings) + preferences.setDefault("general/visible_settings_preset_choice", visible_settings_preset_choice) self.applicationShuttingDown.connect(self.saveSettings) self.engineCreatedSignal.connect(self._onEngineCreated) @@ -410,6 +373,92 @@ class CuraApplication(QtApplication): self.getCuraSceneController().setActiveBuildPlate(0) # Initialize + @pyqtSlot(str, result=str) + def getVisibilitySettingPreset(self, settings_preset_name): + + result = self._load_visibilyty_setting_preset(settings_preset_name) + + formatted_preset_settings = self.format_visibility_setting_preset(result) + + return formatted_preset_settings + + def format_visibility_setting_preset(self, settings_data): + + result_string = "" + + for key in settings_data: + result_string += key + ";" + + for value in settings_data[key]: + result_string += value + ";" + + return result_string + + + def _load_visibilyty_setting_preset(self, visibility_preset_name): + preset_dir = Resources.getPath(Resources.VisibilitySettingsPreset) + + result = {} + right_preset_found = False + + for item in os.listdir(preset_dir): + file_path = os.path.join(preset_dir, item) + if not os.path.isfile(file_path): + continue + + parser = ConfigParser(allow_no_value=True) # accept options without any value, + + try: + parser.read([file_path]) + + if not parser.has_option("general", "name"): + continue + + if parser["general"]["name"] == visibility_preset_name: + right_preset_found = True + for section in parser.sections(): + if section == 'general': + continue + else: + section_settings = [] + for option in parser[section]._options(): + section_settings.append(option) + + result[section] = section_settings + + if right_preset_found: + break + + except Exception as e: + Logger.log("e", "Failed to load setting visibility preset %s: %s", file_path, str(e)) + + return result + + def getVisibilitySettingsPresetTypes(self): + preset_dir = Resources.getPath(Resources.VisibilitySettingsPreset) + result = {} + + for item in os.listdir(preset_dir): + file_path = os.path.join(preset_dir, item) + if not os.path.isfile(file_path): + continue + + parser = ConfigParser(allow_no_value=True) # accept options without any value, + + try: + parser.read([file_path]) + + if not parser.has_option("general", "name") and not parser.has_option("general", "weight"): + continue + + result[parser["general"]["weight"]] = parser["general"]["name"] + + except Exception as e: + Logger.log("e", "Failed to load setting preset %s: %s", file_path, str(e)) + + return result + + def _onEngineCreated(self): self._engine.addImageProvider("camera", CameraImageProvider.CameraImageProvider()) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 913cea4f26..1c6cef2b7e 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -420,6 +420,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): Logger.log("w", "Workspace did not contain visible settings. Leaving visibility unchanged") else: global_preferences.setValue("general/visible_settings", visible_settings) + global_preferences.setValue("general/visible_settings_preset_choice", "Custom") categories_expanded = temp_preferences.getValue("cura/categories_expanded") if categories_expanded is None: diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index 5198ab1030..e1707fa196 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -24,6 +24,11 @@ UM.PreferencesPage function reset() { UM.Preferences.resetPreference("general/visible_settings") + + // After calling this function update Setting visibility preset combobox. + // Reset should set "Basic" setting preset + visibilityPreset.setBasicPreset() + } resetEnabled: true; @@ -72,6 +77,9 @@ UM.PreferencesPage { definitionsModel.setAllVisible(false) } + + // After change set "Custom" option + visibilityPreset.currentIndex = visibilityPreset.model.count - 1 } } } @@ -85,7 +93,8 @@ UM.PreferencesPage top: parent.top left: toggleVisibleSettings.right leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right + right: visibilityPreset.left + rightMargin: UM.Theme.getSize("default_margin").width } placeholderText: catalog.i18nc("@label:textbox", "Filter...") @@ -93,6 +102,88 @@ UM.PreferencesPage onTextChanged: definitionsModel.filter = {"i18n_label": "*" + text} } + ComboBox + { + property int customOptionValue: 100 + + function setBasicPreset() + { + var index = 0 + for(var i = 0; i < presetNamesList.count; ++i) + { + if(model.get(i).text == "Basic") + { + index = i; + break; + } + } + + visibilityPreset.currentIndex = index + } + + id: visibilityPreset + width: 150 + anchors + { + top: parent.top + right: parent.right + } + + model: ListModel + { + id: presetNamesList + Component.onCompleted: + { + // returned value is Dictionary (Ex: {1:"Basic"}, The number 1 is the weight and sort by weight) + var itemsDict = UM.Preferences.getValue("general/visible_settings_preset") + var sorted = []; + for(var key in itemsDict) { + sorted[sorted.length] = key; + } + + sorted.sort(); + for(var i = 0; i < sorted.length; i++) { + presetNamesList.append({text: itemsDict[sorted[i]], value: i}); + } + + // By agreement lets "Custom" option will have value 100 + presetNamesList.append({text: "Custom", value: visibilityPreset.customOptionValue}); + } + } + + currentIndex: + { + // Load previously selected preset. + var text = UM.Preferences.getValue("general/visible_settings_preset_choice"); + + + + var index = 0; + for(var i = 0; i < presetNamesList.count; ++i) + { + if(model.get(i).text == text) + { + index = i; + break; + } + } + return index; + } + + onActivated: + { + // TODO What to do if user is selected "Custom from Combobox" ? + if (model.get(index).text == "Custom") + return + + console.log("SETTING VALUE : " + model.get(index).text) + + var newVisibleSettings = CuraApplication.getVisibilitySettingPreset(model.get(index).text) + UM.Preferences.setValue("general/visible_settings", newVisibleSettings) + UM.Preferences.setValue("general/visible_settings_preset_choice", model.get(index).text) + } + } + ScrollView { id: scrollView @@ -162,7 +253,18 @@ UM.PreferencesPage { id: settingVisibilityItem; - UM.SettingVisibilityItem { } + UM.SettingVisibilityItem { + + // after changing any visibility of settings, set the preset to the "Custom" option + visibilityChangeCallback : function() + { + // If already "Custom" then don't do nothing + if (visibilityPreset.currentIndex != visibilityPreset.model.count - 1) + { + visibilityPreset.currentIndex = visibilityPreset.model.count - 1 + } + } + } } } -} +} \ No newline at end of file From f065a08c82221d51e8b2cd2d69d2890ef4a6f9fd Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 30 Jan 2018 15:26:15 +0100 Subject: [PATCH 03/11] Added visible settings CURA-3710 --- cura/CuraApplication.py | 33 +-- .../qml/Preferences/SettingVisibilityPage.qml | 2 - resources/visibility_presets/advanced.cfg | 222 ++++++++++++++++++ resources/visibility_presets/expert.cfg | 221 ++++++++++++++++- 4 files changed, 460 insertions(+), 18 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0df64dbacb..e2719b7a5d 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1,6 +1,7 @@ -# Copyright (c) 2017 Ultimaker B.V. -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +#Type hinting. +from typing import Dict from PyQt5.QtNetwork import QLocalServer from PyQt5.QtNetwork import QLocalSocket @@ -96,6 +97,7 @@ import os import argparse import json + numpy.seterr(all="ignore") MYPY = False @@ -349,7 +351,7 @@ class CuraApplication(QtApplication): preferences.setDefault("local_file/last_used_type", "text/x-gcode") - setting_visibily_preset_names = self.getVisibilitySettingsPresetTypes() + setting_visibily_preset_names = self.getVisibilitySettingPresetTypes() preferences.setDefault("general/visible_settings_preset", setting_visibily_preset_names) visible_settings_preset_choice = Preferences.getInstance().getValue("general/visible_settings_preset_choice") @@ -373,30 +375,29 @@ class CuraApplication(QtApplication): self.getCuraSceneController().setActiveBuildPlate(0) # Initialize - @pyqtSlot(str, result=str) - def getVisibilitySettingPreset(self, settings_preset_name): - + @pyqtSlot(str, result = str) + def getVisibilitySettingPreset(self, settings_preset_name) -> str: result = self._load_visibilyty_setting_preset(settings_preset_name) - formatted_preset_settings = self.format_visibility_setting_preset(result) return formatted_preset_settings - def format_visibility_setting_preset(self, settings_data): - + ## Format visibitlity settings into string which is concatenated by ";" + # + def format_visibility_setting_preset(self, settings_data) -> str: result_string = "" for key in settings_data: result_string += key + ";" - for value in settings_data[key]: result_string += value + ";" return result_string - - def _load_visibilyty_setting_preset(self, visibility_preset_name): - preset_dir = Resources.getPath(Resources.VisibilitySettingsPreset) + ## Load visibility settings according to selected preset name + # + def _load_visibilyty_setting_preset(self, visibility_preset_name) -> Dict[str, str]: + preset_dir = Resources.getPath(Resources.VisibilitySettingPresets) result = {} right_preset_found = False @@ -434,8 +435,10 @@ class CuraApplication(QtApplication): return result - def getVisibilitySettingsPresetTypes(self): - preset_dir = Resources.getPath(Resources.VisibilitySettingsPreset) + ## Check visibility setting preset folder and returns available types + # + def getVisibilitySettingPresetTypes(self): + preset_dir = Resources.getPath(Resources.VisibilitySettingPresets) result = {} for item in os.listdir(preset_dir): diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index e1707fa196..967c0d05bf 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -176,8 +176,6 @@ UM.PreferencesPage if (model.get(index).text == "Custom") return - console.log("SETTING VALUE : " + model.get(index).text) - var newVisibleSettings = CuraApplication.getVisibilitySettingPreset(model.get(index).text) UM.Preferences.setValue("general/visible_settings", newVisibleSettings) UM.Preferences.setValue("general/visible_settings_preset_choice", model.get(index).text) diff --git a/resources/visibility_presets/advanced.cfg b/resources/visibility_presets/advanced.cfg index 335ae67afe..ab2d2faa99 100644 --- a/resources/visibility_presets/advanced.cfg +++ b/resources/visibility_presets/advanced.cfg @@ -6,27 +6,249 @@ weight = 2 [resolution] layer_height +layer_height_0 +slicing_tolerance +line_width [shell] +wall_extruder_nr +wall_thickness +wall_0_wipe_dist +roofing_extruder_nr +roofing_layer_count +roofing_pattern +roofing_angles +top_bottom_extruder_nr +top_bottom_thickness +top_bottom_pattern +top_bottom_pattern_0 +skin_angles +wall_0_inset +optimize_wall_printing_order +outer_inset_first +alternate_extra_perimeter +travel_compensate_overlapping_walls_enabled +fill_perimeter_gaps +filter_out_tiny_gaps +fill_outline_gaps +xy_offset +xy_offset_layer_0 +z_seam_type +z_seam_x +z_seam_y +z_seam_corner +z_seam_relative +skin_no_small_gaps_heuristic +skin_outline_count +ironing_enabled +ironing_only_highest_layer +ironing_pattern +ironing_line_spacing +ironing_flow +ironing_inset +speed_ironing +acceleration_ironing +jerk_ironing [infill] +infill_extruder_nr +infill_sparse_density +infill_pattern +zig_zaggify_infill +infill_angles +infill_offset_x +infill_offset_y +sub_div_rad_add +infill_overlap +skin_overlap +infill_wipe_dist +infill_sparse_thickness +gradual_infill_steps +gradual_infill_step_height +infill_before_walls +min_infill_area +skin_preshrink +expand_skins_expand_distance +max_skin_angle_for_expansion +infill_enable_travel_optimization [material] +material_flow_dependent_temperature +default_material_print_temperature +material_print_temperature +material_print_temperature_layer_0 +material_initial_print_temperature +material_final_print_temperature +material_flow_temp_graph +material_extrusion_cool_down_speed +default_material_bed_temperature +material_bed_temperature +material_bed_temperature_layer_0 +material_diameter +material_adhesion_tendency +material_surface_energy +material_flow +retraction_enable +retract_at_layer_change +retraction_amount +retraction_speed +retraction_extra_prime_amount +retraction_min_travel +retraction_count_max +retraction_extrusion_window +material_standby_temperature +switch_extruder_retraction_amount +switch_extruder_retraction_speeds [speed] +speed_print +speed_travel +speed_layer_0 +skirt_brim_speed +max_feedrate_z_override +speed_slowdown_layers +speed_equalize_flow_enabled +speed_equalize_flow_max +acceleration_enabled +acceleration_print +acceleration_travel +acceleration_layer_0 +acceleration_skirt_brim +jerk_enabled +jerk_print +jerk_travel +jerk_layer_0 +jerk_skirt_brim [travel] +retraction_combing +travel_retract_before_outer_wall +travel_avoid_other_parts +travel_avoid_distance +start_layers_at_same_position +layer_start_x +layer_start_y +retraction_hop_enabled +retraction_hop_only_when_collides +retraction_hop +retraction_hop_after_extruder_switch [cooling] +cool_fan_enabled +cool_fan_speed +cool_min_layer_time_fan_speed_max +cool_fan_speed_0 +cool_fan_full_at_height +cool_min_layer_time +cool_min_speed +cool_lift_head [support] +support_enable +support_tree_enable +support_extruder_nr +support_type +support_angle +support_pattern +support_connect_zigzags +support_infill_rate +support_z_distance +support_xy_distance +support_xy_overrides_z +support_xy_distance_overhang +support_bottom_stair_step_height +support_bottom_stair_step_width +support_join_distance +support_offset +support_infill_sparse_thickness +support_tree_angle +support_tree_branch_distance +support_tree_branch_diameter +support_tree_branch_diameter_angle +support_tree_collision_resolution +support_tree_wall_thickness +gradual_support_infill_steps +gradual_support_infill_step_height +support_interface_enable +support_interface_height +support_interface_skip_height +support_interface_density +support_interface_pattern +support_use_towers +support_tower_diameter +support_minimal_diameter +support_tower_roof_angle +support_mesh_drop_down [platform_adhesion] +prime_blob_enable +extruder_prime_pos_x +extruder_prime_pos_y +adhesion_type +adhesion_extruder_nr +skirt_line_count +skirt_gap +skirt_brim_minimal_length +brim_width +brim_outside_only +raft_margin +raft_smoothing +raft_airgap +layer_0_z_overlap +raft_surface_layers +raft_surface_thickness +raft_surface_line_width +raft_surface_line_spacing +raft_interface_thickness +raft_interface_line_width +raft_interface_line_spacing +raft_base_thickness +raft_base_line_width +raft_base_line_spacing +raft_speed +raft_acceleration +raft_jerk +raft_fan_speed [dual] +prime_tower_enable +prime_tower_size +prime_tower_min_volume +prime_tower_position_x +prime_tower_position_y +prime_tower_flow +prime_tower_wipe_enabled +dual_pre_wipe +prime_tower_purge_volume +ooze_shield_enabled +ooze_shield_angle +ooze_shield_dist [meshfix] +meshfix_union_all +meshfix_union_all_remove_holes +meshfix_extensive_stitching +meshfix_keep_open_polygons +meshfix_maximum_resolution +multiple_mesh_overlap +carve_multiple_volumes +alternate_carve_order +remove_empty_first_layers [blackmagic] +print_sequence +infill_mesh +infill_mesh_order +cutting_mesh +mold_enabled +mold_width +mold_roof_height +mold_angle +support_mesh +anti_overhang_mesh +magic_mesh_surface_mode +magic_spiralize +smooth_spiralized_contours +relative_extrusion [experimental] \ No newline at end of file diff --git a/resources/visibility_presets/expert.cfg b/resources/visibility_presets/expert.cfg index 130c75c6b9..38e756e6b8 100644 --- a/resources/visibility_presets/expert.cfg +++ b/resources/visibility_presets/expert.cfg @@ -6,61 +6,280 @@ weight = 3 [resolution] layer_height +layer_height_0 +slicing_tolerance +line_width [shell] +wall_extruder_nr wall_thickness +wall_0_wipe_dist +roofing_extruder_nr +roofing_layer_count +roofing_pattern +roofing_angles +top_bottom_extruder_nr top_bottom_thickness +top_bottom_pattern +top_bottom_pattern_0 +skin_angles +wall_0_inset +optimize_wall_printing_order +outer_inset_first +alternate_extra_perimeter +travel_compensate_overlapping_walls_enabled +fill_perimeter_gaps +filter_out_tiny_gaps +fill_outline_gaps +xy_offset +xy_offset_layer_0 +z_seam_type z_seam_x z_seam_y +z_seam_corner +z_seam_relative +skin_no_small_gaps_heuristic +skin_outline_count +ironing_enabled +ironing_only_highest_layer +ironing_pattern +ironing_line_spacing +ironing_flow +ironing_inset +speed_ironing +acceleration_ironing +jerk_ironing [infill] +infill_extruder_nr infill_sparse_density +infill_pattern +zig_zaggify_infill +infill_angles +infill_offset_x +infill_offset_y +sub_div_rad_add +infill_overlap +skin_overlap +infill_wipe_dist +infill_sparse_thickness gradual_infill_steps +gradual_infill_step_height +infill_before_walls +min_infill_area +skin_preshrink +expand_skins_expand_distance +max_skin_angle_for_expansion +infill_enable_travel_optimization [material] +material_flow_dependent_temperature +default_material_print_temperature material_print_temperature +material_print_temperature_layer_0 +material_initial_print_temperature +material_final_print_temperature +material_flow_temp_graph +material_extrusion_cool_down_speed +default_material_bed_temperature material_bed_temperature +material_bed_temperature_layer_0 material_diameter +material_adhesion_tendency +material_surface_energy material_flow retraction_enable +retract_at_layer_change +retraction_amount +retraction_speed +retraction_extra_prime_amount +retraction_min_travel +retraction_count_max +retraction_extrusion_window +material_standby_temperature +switch_extruder_retraction_amount +switch_extruder_retraction_speeds [speed] speed_print speed_travel +speed_layer_0 +skirt_brim_speed +max_feedrate_z_override +speed_slowdown_layers +speed_equalize_flow_enabled +speed_equalize_flow_max +acceleration_enabled acceleration_print acceleration_travel +acceleration_layer_0 +acceleration_skirt_brim +jerk_enabled jerk_print jerk_travel +jerk_layer_0 +jerk_skirt_brim [travel] +retraction_combing +travel_retract_before_outer_wall +travel_avoid_other_parts +travel_avoid_distance +start_layers_at_same_position +layer_start_x +layer_start_y +retraction_hop_enabled +retraction_hop_only_when_collides +retraction_hop +retraction_hop_after_extruder_switch [cooling] cool_fan_enabled +cool_fan_speed +cool_min_layer_time_fan_speed_max +cool_fan_speed_0 +cool_fan_full_at_height +cool_min_layer_time +cool_min_speed +cool_lift_head [support] support_enable +support_tree_enable support_extruder_nr support_type +support_angle +support_pattern +support_connect_zigzags +support_infill_rate +support_z_distance +support_xy_distance +support_xy_overrides_z +support_xy_distance_overhang +support_bottom_stair_step_height +support_bottom_stair_step_width +support_join_distance +support_offset +support_infill_sparse_thickness +support_tree_angle +support_tree_branch_distance +support_tree_branch_diameter +support_tree_branch_diameter_angle +support_tree_collision_resolution +support_tree_wall_thickness +gradual_support_infill_steps +gradual_support_infill_step_height +support_interface_enable +support_interface_height +support_interface_skip_height +support_interface_density +support_interface_pattern +support_use_towers +support_tower_diameter +support_minimal_diameter +support_tower_roof_angle +support_mesh_drop_down [platform_adhesion] +prime_blob_enable +extruder_prime_pos_x +extruder_prime_pos_y adhesion_type adhesion_extruder_nr +skirt_line_count +skirt_gap +skirt_brim_minimal_length brim_width +brim_outside_only +raft_margin +raft_smoothing raft_airgap layer_0_z_overlap raft_surface_layers +raft_surface_thickness +raft_surface_line_width +raft_surface_line_spacing +raft_interface_thickness +raft_interface_line_width +raft_interface_line_spacing +raft_base_thickness +raft_base_line_width +raft_base_line_spacing +raft_speed +raft_acceleration +raft_jerk +raft_fan_speed [dual] prime_tower_enable prime_tower_size +prime_tower_min_volume prime_tower_position_x prime_tower_position_y +prime_tower_flow +prime_tower_wipe_enabled +dual_pre_wipe +prime_tower_purge_volume +ooze_shield_enabled +ooze_shield_angle +ooze_shield_dist [meshfix] +meshfix_union_all +meshfix_union_all_remove_holes +meshfix_extensive_stitching +meshfix_keep_open_polygons +meshfix_maximum_resolution +multiple_mesh_overlap +carve_multiple_volumes +alternate_carve_order +remove_empty_first_layers [blackmagic] print_sequence infill_mesh +infill_mesh_order cutting_mesh +mold_enabled +mold_width +mold_roof_height +mold_angle +support_mesh +anti_overhang_mesh +magic_mesh_surface_mode +magic_spiralize +smooth_spiralized_contours +relative_extrusion -[experimental] \ No newline at end of file +[experimental] +support_skip_some_zags +support_skip_zag_per_mm +draft_shield_enabled +draft_shield_dist +draft_shield_height_limitation +draft_shield_height +conical_overhang_enabled +conical_overhang_angle +coasting_enable +coasting_volume +coasting_min_volume +coasting_speed +skin_alternate_rotation +cross_infill_pocket_size +cross_infill_apply_pockets_alternatingly +spaghetti_infill_enabled +spaghetti_infill_stepped +spaghetti_max_infill_angle +spaghetti_max_height +spaghetti_inset +spaghetti_flow +spaghetti_infill_extra_volume +support_conical_enabled +support_conical_angle +support_conical_min_width +infill_hollow +magic_fuzzy_skin_enabled +magic_fuzzy_skin_thickness +magic_fuzzy_skin_point_density +flow_rate_max_extrusion_offset +flow_rate_extrusion_offset_factor \ No newline at end of file From 76703ce23cc1ec3193ae4043dba5018293e7190a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Feb 2018 10:53:42 +0100 Subject: [PATCH 04/11] Add a validation script for preset settings files CURA-3710 --- tools/check_preset_settings.py | 126 +++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 tools/check_preset_settings.py diff --git a/tools/check_preset_settings.py b/tools/check_preset_settings.py new file mode 100644 index 0000000000..5ba6d9724b --- /dev/null +++ b/tools/check_preset_settings.py @@ -0,0 +1,126 @@ +import configparser +import json +import os +import sys + + +class PresetSettingsValidator: + + def __init__(self, cura_dir: str): + self._cura_dir = os.path.abspath(cura_dir) + self._resource_dir = os.path.join(self._cura_dir, "resources") + self._definitions_dir = os.path.join(self._resource_dir, "definitions") + self._preset_settings_dir = os.path.join(self._resource_dir, "visibility_presets") + + self._fdmprinter_def_path = os.path.join(self._definitions_dir, "fdmprinter.def.json") + + def validate(self) -> bool: + """ + Validates the preset settings files and returns True or False indicating whether there are invalid files. + """ + if not os.path.isfile(self._fdmprinter_def_path): + raise FileNotFoundError("[%s] is not a file or doesn't exist, please make sure you have specified the correct cura directory [%s]." % (self._fdmprinter_def_path, self._cura_dir)) + + if not os.path.isdir(self._preset_settings_dir): + raise FileNotFoundError("[%s] is not a directory or doesn't exist, please make sure you have specified the correct cura directory [%s]." % (self._preset_settings_dir, self._cura_dir)) + + # parse the definition file + setting_tree_dict = self._parse_definition_file(self._fdmprinter_def_path) + + has_invalid_files = False + + # go through all the preset settings files + for root_dir, _, filenames in os.walk(self._preset_settings_dir): + for filename in filenames: + file_path = os.path.join(root_dir, filename) + print("Validating [%s] ..." % file_path) + + incorrect_sections = [] + incorrect_settings = {} + + parser = configparser.ConfigParser(allow_no_value = True) + with open(file_path, "r", encoding = "utf-8") as f: + parser.read_file(f) + + for key in parser: + # skip general + if key in ("general", configparser.DEFAULTSECT): + continue + + if key not in setting_tree_dict: + incorrect_sections.append(key) + continue + + for setting_key in parser[key]: + if setting_key not in setting_tree_dict[key]: + if setting_key not in incorrect_settings: + incorrect_settings[setting_key] = {"seen_in": [], + "should_be_in": self._should_setting_be_in(setting_tree_dict, setting_key)} + + incorrect_settings[setting_key]["seen_in"].append(key) + + # show results + print("==========================================") + if incorrect_settings or incorrect_settings: + has_invalid_files = True + print("[INVALID] [%s] is invalid, details below" % file_path) + + # show details + for section_name in incorrect_sections: + print(" -- section name [%s] is incorrect, please check fdmprinter.def.json." % section_name) + for setting_name, details_dict in incorrect_settings.items(): + msg = " -- setting [%s] is found in sections [%s], " % (setting_name, ", ".join(details_dict["seen_in"])) + if details_dict["should_be_in"] is not None: + msg += "but should be in section [%s] only." % details_dict["should_be_in"] + else: + msg += "but it cannot be found in fdmprinter.def.json" + print(msg) + + else: + print("[%s] is valid" % file_path) + print("==========================================") + + return not has_invalid_files + + def _parse_definition_file(self, file_path: str): + with open(file_path, "r", encoding = "utf-8") as f: + def_dict = json.load(f, encoding = "utf-8") + + tree_dict = {} + for key, item in def_dict.get("settings", {}).items(): + setting_list = [] + self._generate_tree(setting_list, item.get("children", {})) + tree_dict[key] = setting_list + + return tree_dict + + def _generate_tree(self, setting_list: list, setting_dict: dict): + for key, item in setting_dict.items(): + setting_list.append(key) + if "children" in item: + self._generate_tree(setting_list, item["children"]) + + def _should_setting_be_in(self, setting_dict: dict, setting_name: str) -> str: + """ + Check which section the given setting belongs to. Returns None if the setting cannot be found. + """ + section_name = None + for key, setting_list in setting_dict.items(): + if setting_name in setting_list: + section_name = key + break + return section_name + + +if __name__ == "__main__": + script_dir = os.path.dirname(os.path.realpath(__file__)) + cura_dir = os.path.abspath(os.path.join(script_dir, "..")) + + validator = PresetSettingsValidator(cura_dir) + is_everything_validate = validator.validate() + + if not is_everything_validate: + print("Please") + + ret_code = 0 if is_everything_validate else 1 + sys.exit(ret_code) From c5cafff8aa5cbfb44bf1a1817e2a81ab6195e6be Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Feb 2018 10:56:10 +0100 Subject: [PATCH 05/11] Add Sha Bang for tool python scripts CURA-3710 --- tools/check_preset_settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/check_preset_settings.py b/tools/check_preset_settings.py index 5ba6d9724b..9ee3615d67 100644 --- a/tools/check_preset_settings.py +++ b/tools/check_preset_settings.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python import configparser import json import os From cf68d57148ec5c7189285aea64b62dcb8e68099b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Feb 2018 10:57:49 +0100 Subject: [PATCH 06/11] Clean up check_preset_settings.py CURA-3710 --- tools/check_preset_settings.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/check_preset_settings.py b/tools/check_preset_settings.py index 9ee3615d67..675075ee07 100644 --- a/tools/check_preset_settings.py +++ b/tools/check_preset_settings.py @@ -120,8 +120,5 @@ if __name__ == "__main__": validator = PresetSettingsValidator(cura_dir) is_everything_validate = validator.validate() - if not is_everything_validate: - print("Please") - ret_code = 0 if is_everything_validate else 1 sys.exit(ret_code) From 0fbc56a025276bc3ec3b7bb81e6029ccd034b482 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Feb 2018 11:17:16 +0100 Subject: [PATCH 07/11] Show validation results in sorted order CURA-3710 --- tools/check_preset_settings.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/check_preset_settings.py b/tools/check_preset_settings.py index 675075ee07..dfcea4849f 100644 --- a/tools/check_preset_settings.py +++ b/tools/check_preset_settings.py @@ -67,9 +67,11 @@ class PresetSettingsValidator: print("[INVALID] [%s] is invalid, details below" % file_path) # show details - for section_name in incorrect_sections: + for section_name in sorted(incorrect_sections): print(" -- section name [%s] is incorrect, please check fdmprinter.def.json." % section_name) - for setting_name, details_dict in incorrect_settings.items(): + + for setting_name in sorted(incorrect_settings.keys()): + details_dict = incorrect_settings[setting_name] msg = " -- setting [%s] is found in sections [%s], " % (setting_name, ", ".join(details_dict["seen_in"])) if details_dict["should_be_in"] is not None: msg += "but should be in section [%s] only." % details_dict["should_be_in"] From 1801f1f27cff0665487ebb8bc240701ec7c1a918 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Feb 2018 11:17:57 +0100 Subject: [PATCH 08/11] Update advanced and export presets with some settings moved to exp. CURA-3710 Some settings have been moved to experimental. --- resources/visibility_presets/advanced.cfg | 30 +++++++++++------------ resources/visibility_presets/expert.cfg | 30 +++++++++++------------ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/resources/visibility_presets/advanced.cfg b/resources/visibility_presets/advanced.cfg index ab2d2faa99..3bbe0ce065 100644 --- a/resources/visibility_presets/advanced.cfg +++ b/resources/visibility_presets/advanced.cfg @@ -7,7 +7,6 @@ weight = 2 [resolution] layer_height layer_height_0 -slicing_tolerance line_width [shell] @@ -16,8 +15,6 @@ wall_thickness wall_0_wipe_dist roofing_extruder_nr roofing_layer_count -roofing_pattern -roofing_angles top_bottom_extruder_nr top_bottom_thickness top_bottom_pattern @@ -70,16 +67,13 @@ min_infill_area skin_preshrink expand_skins_expand_distance max_skin_angle_for_expansion -infill_enable_travel_optimization [material] -material_flow_dependent_temperature default_material_print_temperature material_print_temperature material_print_temperature_layer_0 material_initial_print_temperature material_final_print_temperature -material_flow_temp_graph material_extrusion_cool_down_speed default_material_bed_temperature material_bed_temperature @@ -145,7 +139,6 @@ cool_lift_head [support] support_enable -support_tree_enable support_extruder_nr support_type support_angle @@ -161,12 +154,6 @@ support_bottom_stair_step_width support_join_distance support_offset support_infill_sparse_thickness -support_tree_angle -support_tree_branch_distance -support_tree_branch_diameter -support_tree_branch_diameter_angle -support_tree_collision_resolution -support_tree_wall_thickness gradual_support_infill_steps gradual_support_infill_step_height support_interface_enable @@ -229,7 +216,6 @@ meshfix_union_all meshfix_union_all_remove_holes meshfix_extensive_stitching meshfix_keep_open_polygons -meshfix_maximum_resolution multiple_mesh_overlap carve_multiple_volumes alternate_carve_order @@ -251,4 +237,18 @@ magic_spiralize smooth_spiralized_contours relative_extrusion -[experimental] \ No newline at end of file +[experimental] +infill_enable_travel_optimization +material_flow_dependent_temperature +material_flow_temp_graph +meshfix_maximum_resolution +roofing_angles +roofing_pattern +slicing_tolerance +support_tree_angle +support_tree_branch_diameter +support_tree_branch_diameter_angle +support_tree_branch_distance +support_tree_collision_resolution +support_tree_enable +support_tree_wall_thickness diff --git a/resources/visibility_presets/expert.cfg b/resources/visibility_presets/expert.cfg index 38e756e6b8..1be5ca7804 100644 --- a/resources/visibility_presets/expert.cfg +++ b/resources/visibility_presets/expert.cfg @@ -7,7 +7,6 @@ weight = 3 [resolution] layer_height layer_height_0 -slicing_tolerance line_width [shell] @@ -16,8 +15,6 @@ wall_thickness wall_0_wipe_dist roofing_extruder_nr roofing_layer_count -roofing_pattern -roofing_angles top_bottom_extruder_nr top_bottom_thickness top_bottom_pattern @@ -70,16 +67,13 @@ min_infill_area skin_preshrink expand_skins_expand_distance max_skin_angle_for_expansion -infill_enable_travel_optimization [material] -material_flow_dependent_temperature default_material_print_temperature material_print_temperature material_print_temperature_layer_0 material_initial_print_temperature material_final_print_temperature -material_flow_temp_graph material_extrusion_cool_down_speed default_material_bed_temperature material_bed_temperature @@ -145,7 +139,6 @@ cool_lift_head [support] support_enable -support_tree_enable support_extruder_nr support_type support_angle @@ -161,12 +154,6 @@ support_bottom_stair_step_width support_join_distance support_offset support_infill_sparse_thickness -support_tree_angle -support_tree_branch_distance -support_tree_branch_diameter -support_tree_branch_diameter_angle -support_tree_collision_resolution -support_tree_wall_thickness gradual_support_infill_steps gradual_support_infill_step_height support_interface_enable @@ -229,7 +216,6 @@ meshfix_union_all meshfix_union_all_remove_holes meshfix_extensive_stitching meshfix_keep_open_polygons -meshfix_maximum_resolution multiple_mesh_overlap carve_multiple_volumes alternate_carve_order @@ -282,4 +268,18 @@ magic_fuzzy_skin_enabled magic_fuzzy_skin_thickness magic_fuzzy_skin_point_density flow_rate_max_extrusion_offset -flow_rate_extrusion_offset_factor \ No newline at end of file +flow_rate_extrusion_offset_factor +infill_enable_travel_optimization +material_flow_dependent_temperature +material_flow_temp_graph +meshfix_maximum_resolution +roofing_angles +roofing_pattern +slicing_tolerance +support_tree_angle +support_tree_branch_diameter +support_tree_branch_diameter_angle +support_tree_branch_distance +support_tree_collision_resolution +support_tree_enable +support_tree_wall_thickness From 367e50669d18c48d4c0d45a9c46313ba6f9ccd05 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Feb 2018 13:56:49 +0100 Subject: [PATCH 09/11] Refactor code CURA-3710 --- cura/CuraApplication.py | 34 +++++++++---------- plugins/3MFReader/ThreeMFWorkspaceReader.py | 2 +- .../advanced.cfg | 0 .../basic.cfg | 0 .../expert.cfg | 0 .../qml/Preferences/SettingVisibilityPage.qml | 4 +-- tools/check_preset_settings.py | 2 +- 7 files changed, 21 insertions(+), 21 deletions(-) rename resources/{visibility_presets => preset_setting_visibility_groups}/advanced.cfg (100%) rename resources/{visibility_presets => preset_setting_visibility_groups}/basic.cfg (100%) rename resources/{visibility_presets => preset_setting_visibility_groups}/expert.cfg (100%) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 087530a99e..086cc8bd72 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -354,16 +354,16 @@ class CuraApplication(QtApplication): setting_visibily_preset_names = self.getVisibilitySettingPresetTypes() preferences.setDefault("general/visible_settings_preset", setting_visibily_preset_names) - visible_settings_preset_choice = Preferences.getInstance().getValue("general/visible_settings_preset_choice") + preset_setting_visibility_choice = Preferences.getInstance().getValue("general/preset_setting_visibility_choice") - default_visibility_preset = "Basic" - if visible_settings_preset_choice == "" or visible_settings_preset_choice is None: - if not visible_settings_preset_choice in setting_visibily_preset_names: - visible_settings_preset_choice = default_visibility_preset + default_preset_visibility_group_name = "Basic" + if preset_setting_visibility_choice == "" or preset_setting_visibility_choice is None: + if preset_setting_visibility_choice not in setting_visibily_preset_names: + preset_setting_visibility_choice = default_preset_visibility_group_name - visible_settings = self.getVisibilitySettingPreset(settings_preset_name = visible_settings_preset_choice) + visible_settings = self.getVisibilitySettingPreset(settings_preset_name = preset_setting_visibility_choice) preferences.setDefault("general/visible_settings", visible_settings) - preferences.setDefault("general/visible_settings_preset_choice", visible_settings_preset_choice) + preferences.setDefault("general/preset_setting_visibility_choice", preset_setting_visibility_choice) self.applicationShuttingDown.connect(self.saveSettings) self.engineCreatedSignal.connect(self._onEngineCreated) @@ -377,14 +377,14 @@ class CuraApplication(QtApplication): @pyqtSlot(str, result = str) def getVisibilitySettingPreset(self, settings_preset_name) -> str: - result = self._load_visibilyty_setting_preset(settings_preset_name) - formatted_preset_settings = self.format_visibility_setting_preset(result) + result = self._loadPresetSettingVisibilityGroup(settings_preset_name) + formatted_preset_settings = self._serializePresetSettingVisibilityData(result) return formatted_preset_settings - ## Format visibitlity settings into string which is concatenated by ";" + ## Serialise the given preset setting visibitlity group dictionary into a string which is concatenated by ";" # - def format_visibility_setting_preset(self, settings_data) -> str: + def _serializePresetSettingVisibilityData(self, settings_data: dict) -> str: result_string = "" for key in settings_data: @@ -394,10 +394,10 @@ class CuraApplication(QtApplication): return result_string - ## Load visibility settings according to selected preset name + ## Load the preset setting visibility group with the given name # - def _load_visibilyty_setting_preset(self, visibility_preset_name) -> Dict[str, str]: - preset_dir = Resources.getPath(Resources.VisibilitySettingPresets) + def _loadPresetSettingVisibilityGroup(self, visibility_preset_name) -> Dict[str, str]: + preset_dir = Resources.getPath(Resources.PresetSettingVisibilityGroups) result = {} right_preset_found = False @@ -407,7 +407,7 @@ class CuraApplication(QtApplication): if not os.path.isfile(file_path): continue - parser = ConfigParser(allow_no_value=True) # accept options without any value, + parser = ConfigParser(allow_no_value = True) # accept options without any value, try: parser.read([file_path]) @@ -422,7 +422,7 @@ class CuraApplication(QtApplication): continue else: section_settings = [] - for option in parser[section]._options(): + for option in parser[section].keys(): section_settings.append(option) result[section] = section_settings @@ -438,7 +438,7 @@ class CuraApplication(QtApplication): ## Check visibility setting preset folder and returns available types # def getVisibilitySettingPresetTypes(self): - preset_dir = Resources.getPath(Resources.VisibilitySettingPresets) + preset_dir = Resources.getPath(Resources.PresetSettingVisibilityGroups) result = {} for item in os.listdir(preset_dir): diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index c67815b306..b28490ce4e 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -453,7 +453,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): Logger.log("w", "Workspace did not contain visible settings. Leaving visibility unchanged") else: global_preferences.setValue("general/visible_settings", visible_settings) - global_preferences.setValue("general/visible_settings_preset_choice", "Custom") + global_preferences.setValue("general/preset_setting_visibility_choice", "Custom") categories_expanded = temp_preferences.getValue("cura/categories_expanded") if categories_expanded is None: diff --git a/resources/visibility_presets/advanced.cfg b/resources/preset_setting_visibility_groups/advanced.cfg similarity index 100% rename from resources/visibility_presets/advanced.cfg rename to resources/preset_setting_visibility_groups/advanced.cfg diff --git a/resources/visibility_presets/basic.cfg b/resources/preset_setting_visibility_groups/basic.cfg similarity index 100% rename from resources/visibility_presets/basic.cfg rename to resources/preset_setting_visibility_groups/basic.cfg diff --git a/resources/visibility_presets/expert.cfg b/resources/preset_setting_visibility_groups/expert.cfg similarity index 100% rename from resources/visibility_presets/expert.cfg rename to resources/preset_setting_visibility_groups/expert.cfg diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index 967c0d05bf..561c1f8f9d 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -154,7 +154,7 @@ UM.PreferencesPage currentIndex: { // Load previously selected preset. - var text = UM.Preferences.getValue("general/visible_settings_preset_choice"); + var text = UM.Preferences.getValue("general/preset_setting_visibility_choice"); @@ -178,7 +178,7 @@ UM.PreferencesPage var newVisibleSettings = CuraApplication.getVisibilitySettingPreset(model.get(index).text) UM.Preferences.setValue("general/visible_settings", newVisibleSettings) - UM.Preferences.setValue("general/visible_settings_preset_choice", model.get(index).text) + UM.Preferences.setValue("general/preset_setting_visibility_choice", model.get(index).text) } } diff --git a/tools/check_preset_settings.py b/tools/check_preset_settings.py index dfcea4849f..8afad38344 100644 --- a/tools/check_preset_settings.py +++ b/tools/check_preset_settings.py @@ -11,7 +11,7 @@ class PresetSettingsValidator: self._cura_dir = os.path.abspath(cura_dir) self._resource_dir = os.path.join(self._cura_dir, "resources") self._definitions_dir = os.path.join(self._resource_dir, "definitions") - self._preset_settings_dir = os.path.join(self._resource_dir, "visibility_presets") + self._preset_settings_dir = os.path.join(self._resource_dir, "preset_setting_visibility_groups") self._fdmprinter_def_path = os.path.join(self._definitions_dir, "fdmprinter.def.json") From caeb6c65eaee13924d2309b96b7bf9254d1e85d1 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 1 Feb 2018 13:57:24 +0100 Subject: [PATCH 10/11] Change check_preset_settings.py to UNIX EOLs CURA-3710 --- tools/check_preset_settings.py | 252 ++++++++++++++++----------------- 1 file changed, 126 insertions(+), 126 deletions(-) diff --git a/tools/check_preset_settings.py b/tools/check_preset_settings.py index 8afad38344..e634d9decd 100644 --- a/tools/check_preset_settings.py +++ b/tools/check_preset_settings.py @@ -1,126 +1,126 @@ -#!/usr/bin/env python -import configparser -import json -import os -import sys - - -class PresetSettingsValidator: - - def __init__(self, cura_dir: str): - self._cura_dir = os.path.abspath(cura_dir) - self._resource_dir = os.path.join(self._cura_dir, "resources") - self._definitions_dir = os.path.join(self._resource_dir, "definitions") - self._preset_settings_dir = os.path.join(self._resource_dir, "preset_setting_visibility_groups") - - self._fdmprinter_def_path = os.path.join(self._definitions_dir, "fdmprinter.def.json") - - def validate(self) -> bool: - """ - Validates the preset settings files and returns True or False indicating whether there are invalid files. - """ - if not os.path.isfile(self._fdmprinter_def_path): - raise FileNotFoundError("[%s] is not a file or doesn't exist, please make sure you have specified the correct cura directory [%s]." % (self._fdmprinter_def_path, self._cura_dir)) - - if not os.path.isdir(self._preset_settings_dir): - raise FileNotFoundError("[%s] is not a directory or doesn't exist, please make sure you have specified the correct cura directory [%s]." % (self._preset_settings_dir, self._cura_dir)) - - # parse the definition file - setting_tree_dict = self._parse_definition_file(self._fdmprinter_def_path) - - has_invalid_files = False - - # go through all the preset settings files - for root_dir, _, filenames in os.walk(self._preset_settings_dir): - for filename in filenames: - file_path = os.path.join(root_dir, filename) - print("Validating [%s] ..." % file_path) - - incorrect_sections = [] - incorrect_settings = {} - - parser = configparser.ConfigParser(allow_no_value = True) - with open(file_path, "r", encoding = "utf-8") as f: - parser.read_file(f) - - for key in parser: - # skip general - if key in ("general", configparser.DEFAULTSECT): - continue - - if key not in setting_tree_dict: - incorrect_sections.append(key) - continue - - for setting_key in parser[key]: - if setting_key not in setting_tree_dict[key]: - if setting_key not in incorrect_settings: - incorrect_settings[setting_key] = {"seen_in": [], - "should_be_in": self._should_setting_be_in(setting_tree_dict, setting_key)} - - incorrect_settings[setting_key]["seen_in"].append(key) - - # show results - print("==========================================") - if incorrect_settings or incorrect_settings: - has_invalid_files = True - print("[INVALID] [%s] is invalid, details below" % file_path) - - # show details - for section_name in sorted(incorrect_sections): - print(" -- section name [%s] is incorrect, please check fdmprinter.def.json." % section_name) - - for setting_name in sorted(incorrect_settings.keys()): - details_dict = incorrect_settings[setting_name] - msg = " -- setting [%s] is found in sections [%s], " % (setting_name, ", ".join(details_dict["seen_in"])) - if details_dict["should_be_in"] is not None: - msg += "but should be in section [%s] only." % details_dict["should_be_in"] - else: - msg += "but it cannot be found in fdmprinter.def.json" - print(msg) - - else: - print("[%s] is valid" % file_path) - print("==========================================") - - return not has_invalid_files - - def _parse_definition_file(self, file_path: str): - with open(file_path, "r", encoding = "utf-8") as f: - def_dict = json.load(f, encoding = "utf-8") - - tree_dict = {} - for key, item in def_dict.get("settings", {}).items(): - setting_list = [] - self._generate_tree(setting_list, item.get("children", {})) - tree_dict[key] = setting_list - - return tree_dict - - def _generate_tree(self, setting_list: list, setting_dict: dict): - for key, item in setting_dict.items(): - setting_list.append(key) - if "children" in item: - self._generate_tree(setting_list, item["children"]) - - def _should_setting_be_in(self, setting_dict: dict, setting_name: str) -> str: - """ - Check which section the given setting belongs to. Returns None if the setting cannot be found. - """ - section_name = None - for key, setting_list in setting_dict.items(): - if setting_name in setting_list: - section_name = key - break - return section_name - - -if __name__ == "__main__": - script_dir = os.path.dirname(os.path.realpath(__file__)) - cura_dir = os.path.abspath(os.path.join(script_dir, "..")) - - validator = PresetSettingsValidator(cura_dir) - is_everything_validate = validator.validate() - - ret_code = 0 if is_everything_validate else 1 - sys.exit(ret_code) +#!/usr/bin/env python +import configparser +import json +import os +import sys + + +class PresetSettingsValidator: + + def __init__(self, cura_dir: str): + self._cura_dir = os.path.abspath(cura_dir) + self._resource_dir = os.path.join(self._cura_dir, "resources") + self._definitions_dir = os.path.join(self._resource_dir, "definitions") + self._preset_settings_dir = os.path.join(self._resource_dir, "preset_setting_visibility_groups") + + self._fdmprinter_def_path = os.path.join(self._definitions_dir, "fdmprinter.def.json") + + def validate(self) -> bool: + """ + Validates the preset settings files and returns True or False indicating whether there are invalid files. + """ + if not os.path.isfile(self._fdmprinter_def_path): + raise FileNotFoundError("[%s] is not a file or doesn't exist, please make sure you have specified the correct cura directory [%s]." % (self._fdmprinter_def_path, self._cura_dir)) + + if not os.path.isdir(self._preset_settings_dir): + raise FileNotFoundError("[%s] is not a directory or doesn't exist, please make sure you have specified the correct cura directory [%s]." % (self._preset_settings_dir, self._cura_dir)) + + # parse the definition file + setting_tree_dict = self._parse_definition_file(self._fdmprinter_def_path) + + has_invalid_files = False + + # go through all the preset settings files + for root_dir, _, filenames in os.walk(self._preset_settings_dir): + for filename in filenames: + file_path = os.path.join(root_dir, filename) + print("Validating [%s] ..." % file_path) + + incorrect_sections = [] + incorrect_settings = {} + + parser = configparser.ConfigParser(allow_no_value = True) + with open(file_path, "r", encoding = "utf-8") as f: + parser.read_file(f) + + for key in parser: + # skip general + if key in ("general", configparser.DEFAULTSECT): + continue + + if key not in setting_tree_dict: + incorrect_sections.append(key) + continue + + for setting_key in parser[key]: + if setting_key not in setting_tree_dict[key]: + if setting_key not in incorrect_settings: + incorrect_settings[setting_key] = {"seen_in": [], + "should_be_in": self._should_setting_be_in(setting_tree_dict, setting_key)} + + incorrect_settings[setting_key]["seen_in"].append(key) + + # show results + print("==========================================") + if incorrect_settings or incorrect_settings: + has_invalid_files = True + print("[INVALID] [%s] is invalid, details below" % file_path) + + # show details + for section_name in sorted(incorrect_sections): + print(" -- section name [%s] is incorrect, please check fdmprinter.def.json." % section_name) + + for setting_name in sorted(incorrect_settings.keys()): + details_dict = incorrect_settings[setting_name] + msg = " -- setting [%s] is found in sections [%s], " % (setting_name, ", ".join(details_dict["seen_in"])) + if details_dict["should_be_in"] is not None: + msg += "but should be in section [%s] only." % details_dict["should_be_in"] + else: + msg += "but it cannot be found in fdmprinter.def.json" + print(msg) + + else: + print("[%s] is valid" % file_path) + print("==========================================") + + return not has_invalid_files + + def _parse_definition_file(self, file_path: str): + with open(file_path, "r", encoding = "utf-8") as f: + def_dict = json.load(f, encoding = "utf-8") + + tree_dict = {} + for key, item in def_dict.get("settings", {}).items(): + setting_list = [] + self._generate_tree(setting_list, item.get("children", {})) + tree_dict[key] = setting_list + + return tree_dict + + def _generate_tree(self, setting_list: list, setting_dict: dict): + for key, item in setting_dict.items(): + setting_list.append(key) + if "children" in item: + self._generate_tree(setting_list, item["children"]) + + def _should_setting_be_in(self, setting_dict: dict, setting_name: str) -> str: + """ + Check which section the given setting belongs to. Returns None if the setting cannot be found. + """ + section_name = None + for key, setting_list in setting_dict.items(): + if setting_name in setting_list: + section_name = key + break + return section_name + + +if __name__ == "__main__": + script_dir = os.path.dirname(os.path.realpath(__file__)) + cura_dir = os.path.abspath(os.path.join(script_dir, "..")) + + validator = PresetSettingsValidator(cura_dir) + is_everything_validate = validator.validate() + + ret_code = 0 if is_everything_validate else 1 + sys.exit(ret_code) From e2fb8ab762d7baa7696fd948bd2986ed37be3541 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 5 Feb 2018 09:45:22 +0100 Subject: [PATCH 11/11] Fixed typo --- tools/check_preset_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/check_preset_settings.py b/tools/check_preset_settings.py index e634d9decd..3996d6bcb5 100644 --- a/tools/check_preset_settings.py +++ b/tools/check_preset_settings.py @@ -62,7 +62,7 @@ class PresetSettingsValidator: # show results print("==========================================") - if incorrect_settings or incorrect_settings: + if incorrect_sections or incorrect_settings: has_invalid_files = True print("[INVALID] [%s] is invalid, details below" % file_path)