Merge pull request #11678 from Ultimaker/brim_per_material_optimized_order

Brim overhaul: New features and bug fixes
This commit is contained in:
Remco Burema 2022-10-30 17:59:36 +01:00 committed by GitHub
commit f75cb7a48b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 96 deletions

View File

@ -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"),

View File

@ -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")

View File

@ -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):

View File

@ -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):

View File

@ -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")

View File

@ -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":
{

View File

@ -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},