diff --git a/.github/workflows/installers.yml b/.github/workflows/installers.yml index 0c2873cf31..805f1917aa 100644 --- a/.github/workflows/installers.yml +++ b/.github/workflows/installers.yml @@ -93,7 +93,7 @@ jobs: enterprise: ${{ github.event.inputs.enterprise == 'true' }} staging: ${{ github.event.inputs.staging == 'true' }} architecture: X64 - operating_system: ubuntu-22.04 + operating_system: self-hosted-Ubuntu22-X64 secrets: inherit macos-installer: diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 08c59c9158..f9d800c77d 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -34,10 +34,11 @@ on: operating_system: description: 'OS' required: true - default: 'ubuntu-22.04' + default: 'self-hosted-Ubuntu22-X64' type: choice options: - ubuntu-22.04 + - self-hosted-Ubuntu22-X64 jobs: linux-installer: @@ -49,4 +50,4 @@ jobs: staging: ${{ inputs.staging }} architecture: ${{ inputs.architecture }} operating_system: ${{ inputs.operating_system }} - secrets: inherit \ No newline at end of file + secrets: inherit diff --git a/.printer-linter b/.printer-linter index 45b1f2c9e0..31376f4dad 100644 --- a/.printer-linter +++ b/.printer-linter @@ -2,6 +2,7 @@ checks: diagnostic-mesh-file-extension: true diagnostic-mesh-file-size: true diagnostic-definition-redundant-override: true + diagnostic-definition-experimental-setting: true diagnostic-resources-macos-app-directory-name: true diagnostic-incorrect-formula: true diagnostic-resource-file-deleted: true diff --git a/printer-linter/src/printerlinter/factory.py b/printer-linter/src/printerlinter/factory.py index 37a11d471a..fa78c7137e 100644 --- a/printer-linter/src/printerlinter/factory.py +++ b/printer-linter/src/printerlinter/factory.py @@ -14,10 +14,10 @@ def getLinter(file: Path, settings: dict) -> Optional[List[Linter]]: if not file.exists(): return [Directory(file, settings)] - if ".inst" in file.suffixes and ".cfg" in file.suffixes: + if ".inst" in file.suffixes and file.suffixes[-1] == ".cfg": return [Directory(file, settings), Profile(file, settings), Formulas(file, settings)] - if ".def" in file.suffixes and ".json" in file.suffixes: + if ".def" in file.suffixes and file.suffixes[-1] == ".json": if file.stem in ("fdmprinter.def", "fdmextruder.def"): return [Formulas(file, settings)] return [Directory(file, settings), Definition(file, settings), Formulas(file, settings)] diff --git a/printer-linter/src/printerlinter/linters/defintion.py b/printer-linter/src/printerlinter/linters/defintion.py index 2d68e20db9..a95fede55a 100644 --- a/printer-linter/src/printerlinter/linters/defintion.py +++ b/printer-linter/src/printerlinter/linters/defintion.py @@ -13,8 +13,11 @@ class Definition(Linter): def __init__(self, file: Path, settings: dict) -> None: super().__init__(file, settings) self._definitions = {} + self._definition_name = None + self._experimental_settings = [] self._loadDefinitionFiles(file) self._content = self._file.read_text() + self._loadExperimentalSettings() self._loadBasePrinterSettings() @property @@ -32,6 +35,10 @@ class Definition(Linter): for check in self.checkMaterialTemperature(): yield check + if self._settings["checks"].get("diagnostic-definition-experimental-setting", False): + for check in self.checkExperimentalSetting(): + yield check + # Add other which will yield Diagnostic's # TODO: A check to determine if the user set value is with the min and max value defined in the parent and doesn't trigger a warning # TODO: A check if the key exist in the first place @@ -41,9 +48,8 @@ class Definition(Linter): def checkRedefineOverride(self) -> Iterator[Diagnostic]: """ Checks if definition file overrides its parents settings with the same value. """ - definition_name = list(self._definitions.keys())[0] - definition = self._definitions[definition_name] - if "overrides" in definition and definition_name not in ("fdmprinter", "fdmextruder"): + definition = self._definitions[self._definition_name] + if "overrides" in definition and self._definition_name not in ("fdmprinter", "fdmextruder"): for key, value_dict in definition["overrides"].items(): is_redefined, child_key, child_value, parent, inherited_by= self._isDefinedInParent(key, value_dict, definition['inherits']) if is_redefined: @@ -71,9 +77,8 @@ class Definition(Linter): def checkMaterialTemperature(self) -> Iterator[Diagnostic]: """Checks if definition file has material tremperature defined within them""" - definition_name = list(self._definitions.keys())[0] - definition = self._definitions[definition_name] - if "overrides" in definition and definition_name not in ("fdmprinter", "fdmextruder"): + definition = self._definitions[self._definition_name] + if "overrides" in definition and self._definition_name not in ("fdmprinter", "fdmextruder"): for key, value_dict in definition["overrides"].items(): if "temperature" in key and "material" in key: @@ -97,6 +102,22 @@ class Definition(Linter): replacements=replacements ) + def checkExperimentalSetting(self) -> Iterator[Diagnostic]: + """Checks if definition uses experimental settings""" + definition = self._definitions[self._definition_name] + if "overrides" in definition and self._definition_name not in ("fdmprinter", "fdmextruder"): + for setting in definition["overrides"]: + if setting in self._experimental_settings: + redefined = re.compile(setting) + found = redefined.search(self._content) + yield Diagnostic( + file=self._file, + diagnostic_name="diagnostic-definition-experimental-setting", + message=f"Setting {setting} is still experimental and should not be used in default profiles", + level="Warning", + offset=found.span(0)[0] + ) + def _loadDefinitionFiles(self, definition_file) -> None: """ Loads definition file contents into self._definitions. Also load parent definition if it exists. """ definition_name = Path(definition_file.stem).stem @@ -104,6 +125,9 @@ class Definition(Linter): if not definition_file.exists() or definition_name in self._definitions: return + if self._definition_name is None: + self._definition_name = definition_name + # Load definition file into dictionary self._definitions[definition_name] = json.loads(definition_file.read_text()) @@ -152,6 +176,12 @@ class Definition(Linter): return self._isDefinedInParent(key, value_dict, parent["inherits"]) return False, None, None, None, None + def _loadExperimentalSettings(self): + try: + self._experimental_settings = self._definitions[self.base_def]["settings"]["experimental"]["children"].keys() + except: + pass + def _loadBasePrinterSettings(self): settings = {} for k, v in self._definitions[self.base_def]["settings"].items(): diff --git a/printer-linter/src/printerlinter/linters/formulas.py b/printer-linter/src/printerlinter/linters/formulas.py index ad5b7ee943..aa31619678 100644 --- a/printer-linter/src/printerlinter/linters/formulas.py +++ b/printer-linter/src/printerlinter/linters/formulas.py @@ -146,12 +146,13 @@ class Formulas(Linter): available_sections = ["values"] for section in available_sections: - options = config.options(section) - for option in options: - values ={} - values["value"] = config.get(section, option) - overrides[option] = values - file_data["overrides"]= overrides# Process the value here + if config.has_section(section): + options = config.options(section) + for option in options: + values ={} + values["value"] = config.get(section, option) + overrides[option] = values + file_data["overrides"]= overrides# Process the value here return file_data diff --git a/printer-linter/src/printerlinter/linters/profile.py b/printer-linter/src/printerlinter/linters/profile.py index 4ca3ded964..347b0fbe90 100644 --- a/printer-linter/src/printerlinter/linters/profile.py +++ b/printer-linter/src/printerlinter/linters/profile.py @@ -37,6 +37,6 @@ class Profile(Linter): config = ConfigParser() config.read([self._file]) name_of_profile = config.get("general", "name") - redefined = re.compile(name_of_profile) + redefined = re.compile(re.escape(name_of_profile)) found = redefined.search(self._content) return name_of_profile, found diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index c23500bfd4..3ea1ba7ac6 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1342,6 +1342,15 @@ "limit_to_extruder": "wall_0_extruder_nr", "settable_per_mesh": true }, + "z_seam_on_vertex": + { + "label": "Z Seam On Vertex", + "description": "Place the z-seam on a polygon vertex. Switching this off can place the seam between vertices as well. (Keep in mind that this won't override the restrictions on placing the seam on an unsupported overhang.)", + "type": "bool", + "default_value": true, + "settable_per_mesh": true, + "enabled": "z_seam_type == 'back' or z_seam_type == 'shortest'" + }, "z_seam_position": { "label": "Z Seam Position", @@ -8222,6 +8231,19 @@ "default_value": 90, "settable_per_mesh": true }, + "seam_overhang_angle": + { + "label": "Seam Overhanging Wall Angle", + "description": "Try to prevent seams on walls that overhang more than this angle. When the value is 90, no walls will be treated as overhanging.", + "unit": "\u00b0", + "type": "float", + "minimum_value": "0", + "minimum_value_warning": "2", + "maximum_value": "90", + "default_value": 90, + "value": "wall_overhang_angle", + "settable_per_mesh": true + }, "wall_overhang_speed_factor": { "label": "Overhanging Wall Speed", diff --git a/resources/setting_visibility/expert.cfg b/resources/setting_visibility/expert.cfg index dee3188dd5..3742fc9f60 100644 --- a/resources/setting_visibility/expert.cfg +++ b/resources/setting_visibility/expert.cfg @@ -41,6 +41,7 @@ xy_offset_layer_0 hole_xy_offset hole_xy_offset_max_diameter z_seam_type +z_seam_on_vertex z_seam_position z_seam_x z_seam_y