mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-12 06:49:00 +08:00
Merge pull request #11678 from Ultimaker/brim_per_material_optimized_order
Brim overhaul: New features and bug fixes
This commit is contained in:
commit
f75cb7a48b
@ -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"),
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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")
|
||||
|
@ -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":
|
||||
{
|
||||
|
@ -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},
|
||||
|
Loading…
x
Reference in New Issue
Block a user