diff --git a/.github/ISSUE_TEMPLATE/featurerequest.yaml b/.github/ISSUE_TEMPLATE/featurerequest.yaml index 83c448fe44..bbdd3908bd 100644 --- a/.github/ISSUE_TEMPLATE/featurerequest.yaml +++ b/.github/ISSUE_TEMPLATE/featurerequest.yaml @@ -1,6 +1,6 @@ name: Feature Request description: Suggest an idea for this project. -labels: "Type: New Feature" +labels: ["Type: New Feature", "Status: Triage"] body: - type: markdown attributes: @@ -41,4 +41,4 @@ body: - type: textarea attributes: label: Additional information & file uploads - description: You can add pictures or files to visualize your feature request in the comments below. \ No newline at end of file + description: You can add pictures or files to visualize your feature request in the comments below. diff --git a/.github/workflows/conan-package-create.yml b/.github/workflows/conan-package-create.yml index 4af608b7ac..a3b769fdb3 100644 --- a/.github/workflows/conan-package-create.yml +++ b/.github/workflows/conan-package-create.yml @@ -3,6 +3,14 @@ name: Create and Upload Conan package on: workflow_call: inputs: + project_name: + required: true + type: string + + build_id: + required: true + type: number + recipe_id_full: required: true type: string @@ -128,7 +136,13 @@ jobs: - name: Create the Packages if: ${{ !inputs.create_from_source }} - run: conan install ${{ inputs.recipe_id_full }} --build=missing --update + run: | + conan_build_info --v2 start ${{ inputs.project_name }} ${{ github.run_number }}000${{ inputs.build_id }} + conan lock create --reference ${{ inputs.recipe_id_full }} --build=missing --update + conan install ${{ inputs.recipe_id_full }} --build=missing --update --lockfile=conan.lock + conan_build_info --v2 create buildinfo.json --lockfile conan.lock --user ${{ secrets.CONAN_USER }} --password ${{ secrets.CONAN_PASS }} + conan_build_info --v2 publish buildinfo.json --url https://ultimaker.jfrog.io/artifactory --user ${{ secrets.CONAN_USER }} --password ${{ secrets.CONAN_PASS }} + conan_build_info --v2 stop - name: Create the Packages (from source) if: ${{ inputs.create_from_source }} diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 8a9de2e37f..0a3d4447c1 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -81,6 +81,8 @@ jobs: uses: ultimaker/cura/.github/workflows/conan-package-create.yml@main with: + project_name: cura + build_id: 1 recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} runs_on: 'ubuntu-20.04' python_version: '3.10.x' diff --git a/.github/workflows/conan-recipe-version.yml b/.github/workflows/conan-recipe-version.yml index f1dfc67bf3..eb1824c8f7 100644 --- a/.github/workflows/conan-recipe-version.yml +++ b/.github/workflows/conan-recipe-version.yml @@ -93,12 +93,13 @@ jobs: issue_number = "${{ github.ref }}".split('/')[2] is_tag = "${{ github.ref_type }}" == "tag" is_release_branch = False + ref_name = "${{ github.base_ref }}" if event_name == "pull_request" else "${{ github.ref_name }}" buildmetadata = "" if "${{ inputs.additional_buildmetadata }}" == "" else "${{ inputs.additional_buildmetadata }}_" # FIXME: for when we push a tag (such as an release) channel = "testing" if is_tag: - branch_version = tools.Version("${{ github.ref_name }}") + branch_version = tools.Version(ref_name) is_release_branch = True channel = "_" user = "_" @@ -108,10 +109,10 @@ jobs: branch_version = tools.Version(repo.active_branch.name) except ConanException: branch_version = tools.Version('0.0.0') - if "${{ github.ref_name }}" == f"{branch_version.major}.{branch_version.minor}": + if ref_name == f"{branch_version.major}.{branch_version.minor}": channel = 'stable' is_release_branch = True - elif "${{ github.ref_name }}" in ("main", "master"): + elif ref_name in ("main", "master"): channel = 'testing' else: channel = repo.active_branch.name.split("_")[0].replace("-", "_").lower() @@ -165,15 +166,6 @@ jobs: bump_up_minor = int(latest_branch_version.minor) + 1 reset_patch = 0 actual_version = f"{latest_branch_version.major}.{bump_up_minor}.{reset_patch}-alpha+{buildmetadata}{channel_metadata}" - else: - # FIXME: for external PR's - actual_version = f"5.3.0-alpha+{buildmetadata}pr_{issue_number}" - - if is_tag and "${{ github.ref_name }}" == "5.2.0-beta": - actual_version = "5.2.0-beta" - is_release_branch = True - user = "_" - channel = "_" # %% print to output cmd_name = ["echo", f"::set-output name=name::{project_name}"] diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 776d92a1f6..1536d541c7 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -810,11 +810,6 @@ class BuildVolume(SceneNode): break if prime_tower_collision: # Already found a collision. break - if self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and self._global_container_stack.getProperty("adhesion_type", "value") != "raft": - brim_size = self._calculateBedAdhesionSize(used_extruders, "brim") - # Use 2x the brim size, since we need 1x brim size distance due to the object brim and another - # times the brim due to the brim of the prime tower - prime_tower_areas[extruder_id][area_index] = prime_tower_area.getMinkowskiHull(Polygon.approximatedCircle(2 * brim_size, num_segments = 24)) if not prime_tower_collision: result_areas[extruder_id].extend(prime_tower_areas[extruder_id]) result_areas_no_brim[extruder_id].extend(prime_tower_areas[extruder_id]) @@ -840,9 +835,13 @@ class BuildVolume(SceneNode): result = {} skirt_brim_extruder: ExtruderStack = None + skirt_brim_extruder_nr = self._global_container_stack.getProperty("skirt_brim_extruder_nr", "value") + for extruder in used_extruders: - if int(extruder.getProperty("extruder_nr", "value")) == int(self._global_container_stack.getProperty("skirt_brim_extruder_nr", "value")): - skirt_brim_extruder = extruder + if skirt_brim_extruder_nr == -1: + skirt_brim_extruder = used_extruders[0] # The prime tower brim is always printed with the first extruder + elif int(extruder.getProperty("extruder_nr", "value")) == int(skirt_brim_extruder_nr): + skirt_brim_extruder = extruder result[extruder.getId()] = [] # Currently, the only normally printed object is the prime tower. @@ -856,15 +855,6 @@ class BuildVolume(SceneNode): prime_tower_x = prime_tower_x - machine_width / 2 #Offset by half machine_width and _depth to put the origin in the front-left. prime_tower_y = prime_tower_y + machine_depth / 2 - if skirt_brim_extruder is not None and self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and self._global_container_stack.getProperty("adhesion_type", "value") != "raft": - brim_size = ( - skirt_brim_extruder.getProperty("brim_line_count", "value") * - skirt_brim_extruder.getProperty("skirt_brim_line_width", "value") / 100.0 * - skirt_brim_extruder.getProperty("initial_layer_line_width_factor", "value") - ) - prime_tower_x -= brim_size - prime_tower_y += brim_size - radius = prime_tower_size / 2 prime_tower_area = Polygon.approximatedCircle(radius, num_segments = 24) prime_tower_area = prime_tower_area.translate(prime_tower_x - radius, prime_tower_y - radius) @@ -1076,7 +1066,7 @@ class BuildVolume(SceneNode): all_values[i] = 0 return all_values - def _calculateBedAdhesionSize(self, used_extruders, adhesion_override = None): + def _calculateBedAdhesionSize(self, used_extruders): """Get the bed adhesion size for the global container stack and used extruders :param adhesion_override: override adhesion type. @@ -1086,52 +1076,12 @@ class BuildVolume(SceneNode): return None container_stack = self._global_container_stack - adhesion_type = adhesion_override - if adhesion_type is None: - adhesion_type = container_stack.getProperty("adhesion_type", "value") + adhesion_type = container_stack.getProperty("adhesion_type", "value") - # Skirt_brim_line_width is a bit of an odd one out. The primary bit of the skirt/brim is printed - # with the adhesion extruder, but it also prints one extra line by all other extruders. As such, the - # setting does *not* have a limit_to_extruder setting (which means that we can't ask the global extruder what - # the value is. - skirt_brim_extruder_nr = self._global_container_stack.getProperty("skirt_brim_extruder_nr", "value") - try: - skirt_brim_stack = self._global_container_stack.extruderList[int(skirt_brim_extruder_nr)] - except IndexError: - Logger.warning(f"Couldn't find extruder with index '{skirt_brim_extruder_nr}', defaulting to 0 instead.") - skirt_brim_stack = self._global_container_stack.extruderList[0] - skirt_brim_line_width = skirt_brim_stack.getProperty("skirt_brim_line_width", "value") - - initial_layer_line_width_factor = skirt_brim_stack.getProperty("initial_layer_line_width_factor", "value") - # Use brim width if brim is enabled OR the prime tower has a brim. - if adhesion_type == "brim": - brim_line_count = skirt_brim_stack.getProperty("brim_line_count", "value") - brim_gap = skirt_brim_stack.getProperty("brim_gap", "value") - bed_adhesion_size = brim_gap + skirt_brim_line_width * brim_line_count * initial_layer_line_width_factor / 100.0 - - for extruder_stack in used_extruders: - bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0 - - # We don't create an additional line for the extruder we're printing the brim with. - bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0 - elif adhesion_type == "skirt": - skirt_distance = skirt_brim_stack.getProperty("skirt_gap", "value") - skirt_line_count = skirt_brim_stack.getProperty("skirt_line_count", "value") - - bed_adhesion_size = skirt_distance + ( - skirt_brim_line_width * skirt_line_count) * initial_layer_line_width_factor / 100.0 - - for extruder_stack in used_extruders: - bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0 - - # We don't create an additional line for the extruder we're printing the skirt with. - bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0 - elif adhesion_type == "raft": + if adhesion_type == "raft": bed_adhesion_size = self._global_container_stack.getProperty("raft_margin", "value") # Should refer to the raft extruder if set. - elif adhesion_type == "none": + else: # raft, brim or skirt. Those last two are handled by CuraEngine. bed_adhesion_size = 0 - else: - raise Exception("Unknown bed adhesion type. Did you forget to update the build volume calculations for your new bed adhesion type?") max_length_available = 0.5 * min( self._global_container_stack.getProperty("machine_width", "value"), diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 52d63b611b..f429a0de19 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -275,7 +275,7 @@ class ExtruderManager(QObject): for extruder_setting in used_adhesion_extruders: extruder_str_nr = str(global_stack.getProperty(extruder_setting, "value")) if extruder_str_nr == "-1": - extruder_str_nr = self._application.getMachineManager().defaultExtruderPosition + continue # An optional extruder doesn't force any extruder to be used if it isn't used already if extruder_str_nr in self.extruderIds: used_extruder_stack_ids.add(self.extruderIds[extruder_str_nr]) @@ -298,7 +298,7 @@ class ExtruderManager(QObject): # Starts with the adhesion extruder. adhesion_type = global_stack.getProperty("adhesion_type", "value") if adhesion_type in {"skirt", "brim"}: - return global_stack.getProperty("skirt_brim_extruder_nr", "value") + return max(0, int(global_stack.getProperty("skirt_brim_extruder_nr", "value"))) # optional skirt/brim extruder defaults to zero if adhesion_type == "raft": return global_stack.getProperty("raft_base_extruder_nr", "value") diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index e93193818c..eba41569b7 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -142,8 +142,6 @@ class ExtruderStack(CuraContainerStack): limit_to_extruder = super().getProperty(key, "limit_to_extruder", context) if limit_to_extruder is not None: - if limit_to_extruder == -1: - limit_to_extruder = int(cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition) limit_to_extruder = str(limit_to_extruder) if (limit_to_extruder is not None and limit_to_extruder != "-1") and self.getMetaDataEntry("position") != str(limit_to_extruder): diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index 041bd19d3a..25fc74b28f 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -226,8 +226,6 @@ class GlobalStack(CuraContainerStack): # Handle the "limit_to_extruder" property. limit_to_extruder = super().getProperty(key, "limit_to_extruder", context) if limit_to_extruder is not None: - if limit_to_extruder == -1: - limit_to_extruder = int(cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition) limit_to_extruder = str(limit_to_extruder) if limit_to_extruder is not None and limit_to_extruder != "-1" and limit_to_extruder in self._extruders: if super().getProperty(key, "settable_per_extruder", context): diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 64216f373f..d06136a2b4 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -487,6 +487,10 @@ class StartSliceJob(Job): settings["machine_start_gcode"] = self._expandGcodeTokens(settings["machine_start_gcode"], initial_extruder_nr) settings["machine_end_gcode"] = self._expandGcodeTokens(settings["machine_end_gcode"], initial_extruder_nr) + # Manually add 'nozzle offsetting', since that is a metadata-entry instead for some reason. + # NOTE: This probably needs to be an actual setting at some point. + settings["nozzle_offsetting_for_disallowed_areas"] = CuraApplication.getInstance().getGlobalContainerStack().getMetaDataEntry("nozzle_offsetting_for_disallowed_areas", True) + # Add all sub-messages for each individual setting. for key, value in settings.items(): setting_message = self._slice_message.getMessage("global_settings").addRepeatedMessage("settings") diff --git a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py index 5923a53adf..6afac57359 100644 --- a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py +++ b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py @@ -58,16 +58,25 @@ class PauseAtHeight(Script): "default_value": "marlin", "value": "\\\"griffin\\\" if machine_gcode_flavor==\\\"Griffin\\\" else \\\"reprap\\\" if machine_gcode_flavor==\\\"RepRap (RepRap)\\\" else \\\"repetier\\\" if machine_gcode_flavor==\\\"Repetier\\\" else \\\"bq\\\" if \\\"BQ\\\" in machine_name or \\\"Flying Bear Ghost 4S\\\" in machine_name else \\\"marlin\\\"" }, + "hold_steppers_on": + { + "label": "Keep motors engaged", + "description": "Keep the steppers engaged to allow change of filament without moving the head. Applying too much force will move the head/bed anyway", + "type": "bool", + "default_value": true, + "enabled": "pause_method != \\\"griffin\\\"" + }, "disarm_timeout": { "label": "Disarm timeout", - "description": "After this time steppers are going to disarm (meaning that they can easily lose their positions). Set this to 0 if you don't want to set any duration.", + "description": "After this time steppers are going to disarm (meaning that they can easily lose their positions). Set this to 0 if you don't want to set any duration and disarm immediately.", "type": "int", "value": "0", "minimum_value": "0", "minimum_value_warning": "0", "maximum_value_warning": "1800", - "unit": "s" + "unit": "s", + "enabled": "not hold_steppers_on" }, "head_park_enabled": { @@ -192,6 +201,22 @@ class PauseAtHeight(Script): "default_value": "RepRap (Marlin/Sprinter)", "enabled": false }, + "beep_at_pause": + { + "label": "Beep at pause", + "description": "Make a beep when pausing", + "type": "bool", + "default_value": true + }, + "beep_length": + { + "label": "Beep length", + "description": "How much should the beep last", + "type": "int", + "default_value": "1000", + "unit": "ms", + "enabled": "beep_at_pause" + }, "custom_gcode_before_pause": { "label": "G-code Before Pause", @@ -242,6 +267,7 @@ class PauseAtHeight(Script): pause_at = self.getSettingValueByKey("pause_at") pause_height = self.getSettingValueByKey("pause_height") pause_layer = self.getSettingValueByKey("pause_layer") + hold_steppers_on = self.getSettingValueByKey("hold_steppers_on") disarm_timeout = self.getSettingValueByKey("disarm_timeout") retraction_amount = self.getSettingValueByKey("retraction_amount") retraction_speed = self.getSettingValueByKey("retraction_speed") @@ -260,6 +286,8 @@ class PauseAtHeight(Script): display_text = self.getSettingValueByKey("display_text") gcode_before = self.getSettingValueByKey("custom_gcode_before_pause") gcode_after = self.getSettingValueByKey("custom_gcode_after_pause") + beep_at_pause = self.getSettingValueByKey("beep_at_pause") + beep_length = self.getSettingValueByKey("beep_length") pause_method = self.getSettingValueByKey("pause_method") pause_command = { @@ -437,19 +465,26 @@ class PauseAtHeight(Script): prepend_gcode += "M117 " + display_text + "\n" # Set the disarm timeout - if disarm_timeout > 0: - prepend_gcode += self.putValue(M = 18, S = disarm_timeout) + " ; Set the disarm timeout\n" + if hold_steppers_on: + prepend_gcode += self.putValue(M = 84, S = 3600) + " ; Keep steppers engaged for 1h\n" + elif disarm_timeout > 0: + prepend_gcode += self.putValue(M = 84, S = disarm_timeout) + " ; Set the disarm timeout\n" + + # Beep at pause + if beep_at_pause: + prepend_gcode += self.putValue(M = 300, S = 440, P = beep_length) + " ; Beep\n" + # Set a custom GCODE section before pause if gcode_before: - prepend_gcode += gcode_before + "\n" + prepend_gcode += gcode_before.replace(";","\n") + "\n" # Wait till the user continues printing prepend_gcode += pause_command + " ; Do the actual pause\n" # Set a custom GCODE section before pause if gcode_after: - prepend_gcode += gcode_after + "\n" + prepend_gcode += gcode_after.replace(";","\n") + "\n" if pause_method == "repetier": #Push the filament back, diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 15bd6914b5..08a895c9fa 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -4785,7 +4785,6 @@ "default_value": 8.0, "minimum_value": "0.0", "maximum_value_warning": "50.0", - "maximum_value": "0.5 * min(machine_width, machine_depth)", "enabled": "(support_enable or support_meshes_present) and support_brim_enable", "settable_per_mesh": false, "settable_per_extruder": true, @@ -4800,7 +4799,6 @@ "default_value": 20, "minimum_value": "0", "maximum_value_warning": "50 / skirt_brim_line_width", - "maximum_value": "0.5 * min(machine_width, machine_depth) / skirt_brim_line_width", "value": "math.ceil(support_brim_width / (skirt_brim_line_width * initial_layer_line_width_factor / 100.0))", "enabled": "(support_enable or support_meshes_present) and support_brim_enable", "settable_per_mesh": false, @@ -5559,10 +5557,11 @@ { "label": "Skirt/Brim Extruder", "description": "The extruder train to use for printing the skirt or brim. This is used in multi-extrusion.", - "type": "extruder", + "type": "optional_extruder", "default_value": "0", "value": "adhesion_extruder_nr", "enabled": "extruders_enabled_count > 1 and (resolveOrValue('adhesion_type') == 'skirt' or resolveOrValue('adhesion_type') == 'brim' or resolveOrValue('prime_tower_brim_enable'))", + "resolve": "'-1' if '-1' in extruderValues('skirt_brim_extruder_nr') else adhesion_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -5614,9 +5613,9 @@ "maximum_value_warning": "10", "maximum_value": "0.5 * min(machine_width, machine_depth) / skirt_brim_line_width", "enabled": "resolveOrValue('adhesion_type') == 'skirt'", + "limit_to_extruder": "skirt_brim_extruder_nr", "settable_per_mesh": false, - "settable_per_extruder": true, - "limit_to_extruder": "skirt_brim_extruder_nr" + "settable_per_extruder": true }, "skirt_gap": { @@ -5628,9 +5627,9 @@ "minimum_value_warning": "max(extruderValues('machine_nozzle_size'))", "maximum_value_warning": "10", "enabled": "resolveOrValue('adhesion_type') == 'skirt'", + "limit_to_extruder": "skirt_brim_extruder_nr", "settable_per_mesh": false, - "settable_per_extruder": true, - "limit_to_extruder": "skirt_brim_extruder_nr" + "settable_per_extruder": true }, "skirt_brim_minimal_length": { @@ -5643,6 +5642,7 @@ "minimum_value_warning": "25", "maximum_value_warning": "2500", "enabled": "resolveOrValue('adhesion_type') == 'skirt' or resolveOrValue('adhesion_type') == 'brim' or resolveOrValue('prime_tower_brim_enable')", + "limit_to_extruder": "skirt_brim_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true }, @@ -5655,11 +5655,10 @@ "default_value": 8.0, "minimum_value": "0.0", "maximum_value_warning": "50.0", - "maximum_value": "0.5 * min(machine_width, machine_depth)", "enabled": "resolveOrValue('adhesion_type') == 'brim' or resolveOrValue('prime_tower_brim_enable')", + "limit_to_extruder": "skirt_brim_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true, - "limit_to_extruder": "skirt_brim_extruder_nr", "children": { "brim_line_count": @@ -5670,12 +5669,11 @@ "default_value": 20, "minimum_value": "0", "maximum_value_warning": "50 / skirt_brim_line_width", - "maximum_value": "0.5 * min(machine_width, machine_depth) / skirt_brim_line_width", "value": "math.ceil(brim_width / (skirt_brim_line_width * initial_layer_line_width_factor / 100.0))", "enabled": "resolveOrValue('adhesion_type') == 'brim' or resolveOrValue('prime_tower_brim_enable')", + "limit_to_extruder": "skirt_brim_extruder_nr", "settable_per_mesh": false, - "settable_per_extruder": true, - "limit_to_extruder": "skirt_brim_extruder_nr" + "settable_per_extruder": true } } }, @@ -5689,9 +5687,9 @@ "minimum_value": "0", "maximum_value_warning": "skirt_brim_line_width", "enabled": "resolveOrValue('adhesion_type') == 'brim'", + "limit_to_extruder": "skirt_brim_extruder_nr", "settable_per_mesh": true, - "settable_per_extruder": true, - "limit_to_extruder": "skirt_brim_extruder_nr" + "settable_per_extruder": true }, "brim_replaces_support": { @@ -5700,9 +5698,9 @@ "type": "bool", "default_value": true, "enabled": "resolveOrValue('adhesion_type') == 'brim' and (support_enable or support_meshes_present)", + "limit_to_extruder": "skirt_brim_extruder_nr", "settable_per_mesh": false, - "settable_per_extruder": true, - "limit_to_extruder": "support_infill_extruder_nr" + "settable_per_extruder": true }, "brim_outside_only": { @@ -5711,9 +5709,22 @@ "type": "bool", "default_value": true, "enabled": "resolveOrValue('adhesion_type') == 'brim'", + "limit_to_extruder": "skirt_brim_extruder_nr", "settable_per_mesh": false, - "settable_per_extruder": true, - "limit_to_extruder": "skirt_brim_extruder_nr" + "settable_per_extruder": true + }, + "brim_inside_margin": + { + "label": "Brim Inside Avoid Margin", + "description": "If brim is only on outside then parts fully enclosed inside another part will get a brim which might overlap with the internal holes of the outer part. This setting controls how far to stay away from those internal holes. Set to a high value to prevent any brim from being generated for parts enclosed within the holes of other parts.", + "unit": "mm", + "type": "float", + "default_value": 5, + "minimum_value": "0", + "enabled": "resolveOrValue('adhesion_type') == 'brim' and any(extruderValues('brim_outside_only'))", + "limit_to_extruder": "skirt_brim_extruder_nr", + "settable_per_mesh": false, + "settable_per_extruder": true }, "raft_margin": { diff --git a/resources/images/cura.png b/resources/images/cura.png index 66b10d5118..ac1677f3f8 100644 Binary files a/resources/images/cura.png and b/resources/images/cura.png differ diff --git a/resources/images/cura_enterprise.png b/resources/images/cura_enterprise.png index fd5025b67c..4a200a8c6b 100644 Binary files a/resources/images/cura_enterprise.png and b/resources/images/cura_enterprise.png differ diff --git a/resources/images/cura_wip.png b/resources/images/cura_wip.png index f98957a0b5..5c2c8104cc 100644 Binary files a/resources/images/cura_wip.png and b/resources/images/cura_wip.png differ diff --git a/resources/themes/cura-light/images/logo.svg b/resources/themes/cura-light/images/logo.svg index 611840e248..63449bb296 100644 --- a/resources/themes/cura-light/images/logo.svg +++ b/resources/themes/cura-light/images/logo.svg @@ -1,18 +1,20 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/tests/TestBuildVolume.py b/tests/TestBuildVolume.py index 458b7afad3..5012784bdf 100644 --- a/tests/TestBuildVolume.py +++ b/tests/TestBuildVolume.py @@ -86,12 +86,12 @@ class TestCalculateBedAdhesionSize: ({"adhesion_type": {"value": "skirt"}}, 0), ({"adhesion_type": {"value": "raft"}}, 0), ({"adhesion_type": {"value": "none"}}, 0), - ({"adhesion_type": {"value": "skirt"}, "skirt_line_count": {"value": 2}, "initial_layer_line_width_factor": {"value": 1}, "skirt_brim_line_width": {"value": 2}}, 0.02), + ({"adhesion_type": {"value": "skirt"}, "skirt_line_count": {"value": 2}, "initial_layer_line_width_factor": {"value": 1}, "skirt_brim_line_width": {"value": 2}}, 0), # Even though it's marked as skirt, it should behave as a brim as the prime tower has a brim (skirt line count is still at 0!) - ({"adhesion_type": {"value": "skirt"}, "prime_tower_brim_enable": {"value": True}, "skirt_brim_line_width": {"value": 2}, "initial_layer_line_width_factor": {"value": 3}}, -0.06), + ({"adhesion_type": {"value": "skirt"}, "prime_tower_brim_enable": {"value": True}, "skirt_brim_line_width": {"value": 2}, "initial_layer_line_width_factor": {"value": 3}}, 0), ({"brim_line_count": {"value": 1}, "skirt_brim_line_width": {"value": 2}, "initial_layer_line_width_factor": {"value": 3}}, 0), - ({"brim_line_count": {"value": 2}, "skirt_brim_line_width": {"value": 2}, "initial_layer_line_width_factor": {"value": 3}}, 0.06), - ({"brim_line_count": {"value": 9000000}, "skirt_brim_line_width": {"value": 90000}, "initial_layer_line_width_factor": {"value": 9000}}, 100), # Clamped at half the max size of buildplate + ({"brim_line_count": {"value": 2}, "skirt_brim_line_width": {"value": 2}, "initial_layer_line_width_factor": {"value": 3}}, 0), + ({"brim_line_count": {"value": 9000000}, "skirt_brim_line_width": {"value": 90000}, "initial_layer_line_width_factor": {"value": 9000}}, 0), # Clamped at half the max size of buildplate ]) def test_singleExtruder(self, build_volume: BuildVolume, setting_dict, result): self.createAndSetGlobalStack(build_volume) @@ -106,14 +106,6 @@ class TestCalculateBedAdhesionSize: with patch.dict(self.setting_property_dict, patched_dictionary): assert build_volume._calculateBedAdhesionSize([]) == result - def test_unknownBedAdhesion(self, build_volume: BuildVolume): - self.createAndSetGlobalStack(build_volume) - patched_dictionary = self.setting_property_dict.copy() - patched_dictionary.update({"adhesion_type": {"value": "OMGZOMGBBQ"}}) - with patch.dict(self.setting_property_dict, patched_dictionary): - with pytest.raises(Exception): - build_volume._calculateBedAdhesionSize([]) - class TestComputeDisallowedAreasStatic: setting_property_dict = {"machine_disallowed_areas": {"value": [[[-200, 112.5], [ -82, 112.5], [ -84, 102.5], [-115, 102.5]]]}, "machine_width": {"value": 200},