Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Ultimaker/Cura.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCasper Lamboo <c.lamboo@ultimaker.com>2021-12-15 19:40:27 +0300
committerGitHub <noreply@github.com>2021-12-15 19:40:27 +0300
commit7c7a1016d0ea1bdccf84dea6909011309f68e713 (patch)
tree354db061a0a0dd94ec4bc8fb19dfcedd4983b1bf
parent03398422ddc300e4cdce6dfa0b352ed17f87c43b (diff)
parentd277109cc806cbb787ab153fc9d169f2fad5620d (diff)
Merge pull request #11075 from Ultimaker/CURA-8083_separate_z_shrinkage_comp
[CURA-8083] Separate Vertical and Horizontal Shrinkage Compensation.
-rwxr-xr-xcura/BuildVolume.py55
-rw-r--r--resources/definitions/fdmprinter.def.json37
-rw-r--r--tests/TestBuildVolume.py40
3 files changed, 110 insertions, 22 deletions
diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py
index 8374bddf74..45e4c9901a 100755
--- a/cura/BuildVolume.py
+++ b/cura/BuildVolume.py
@@ -66,6 +66,7 @@ class BuildVolume(SceneNode):
self._height = 0 # type: float
self._depth = 0 # type: float
self._shape = "" # type: str
+ self._scale_vector = Vector(1.0, 1.0, 1.0)
self._shader = None
@@ -513,6 +514,13 @@ class BuildVolume(SceneNode):
self._disallowed_area_size = max(size, self._disallowed_area_size)
return mb.build()
+ def _updateScaleFactor(self) -> None:
+ if not self._global_container_stack:
+ return
+ scale_xy = 100.0 / max(100.0, self._global_container_stack.getProperty("material_shrinkage_percentage_xy", "value"))
+ scale_z = 100.0 / max(100.0, self._global_container_stack.getProperty("material_shrinkage_percentage_z" , "value"))
+ self._scale_vector = Vector(scale_xy, scale_xy, scale_z)
+
def rebuild(self) -> None:
"""Recalculates the build volume & disallowed areas."""
@@ -554,9 +562,12 @@ class BuildVolume(SceneNode):
self._error_mesh = self._buildErrorMesh(min_w, max_w, min_h, max_h, min_d, max_d, disallowed_area_height)
+ self._updateScaleFactor()
+
self._volume_aabb = AxisAlignedBox(
- minimum = Vector(min_w, min_h - 1.0, min_d),
- maximum = Vector(max_w, max_h - self._raft_thickness - self._extra_z_clearance, max_d))
+ minimum = Vector(min_w, min_h - 1.0, min_d).scale(self._scale_vector),
+ maximum = Vector(max_w, max_h - self._raft_thickness - self._extra_z_clearance, max_d).scale(self._scale_vector)
+ )
bed_adhesion_size = self.getEdgeDisallowedSize()
@@ -564,15 +575,15 @@ class BuildVolume(SceneNode):
# This is probably wrong in all other cases. TODO!
# The +1 and -1 is added as there is always a bit of extra room required to work properly.
scale_to_max_bounds = AxisAlignedBox(
- minimum = Vector(min_w + bed_adhesion_size + 1, min_h, min_d + self._disallowed_area_size - bed_adhesion_size + 1),
- maximum = Vector(max_w - bed_adhesion_size - 1, max_h - self._raft_thickness - self._extra_z_clearance, max_d - self._disallowed_area_size + bed_adhesion_size - 1)
+ minimum = Vector(min_w + bed_adhesion_size + 1, min_h, min_d + self._disallowed_area_size - bed_adhesion_size + 1).scale(self._scale_vector),
+ maximum = Vector(max_w - bed_adhesion_size - 1, max_h - self._raft_thickness - self._extra_z_clearance, max_d - self._disallowed_area_size + bed_adhesion_size - 1).scale(self._scale_vector)
)
self._application.getController().getScene()._maximum_bounds = scale_to_max_bounds # type: ignore
self.updateNodeBoundaryCheck()
- def getBoundingBox(self):
+ def getBoundingBox(self) -> Optional[AxisAlignedBox]:
return self._volume_aabb
def getRaftThickness(self) -> float:
@@ -633,18 +644,18 @@ class BuildVolume(SceneNode):
for extruder in extruders:
extruder.propertyChanged.connect(self._onSettingPropertyChanged)
- self._width = self._global_container_stack.getProperty("machine_width", "value")
+ self._width = self._global_container_stack.getProperty("machine_width", "value") * self._scale_vector.x
machine_height = self._global_container_stack.getProperty("machine_height", "value")
if self._global_container_stack.getProperty("print_sequence", "value") == "one_at_a_time" and len(self._scene_objects) > 1:
- self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height)
- if self._height < machine_height:
+ self._height = min(self._global_container_stack.getProperty("gantry_height", "value") * self._scale_vector.z, machine_height)
+ if self._height < (machine_height * self._scale_vector.z):
self._build_volume_message.show()
else:
self._build_volume_message.hide()
else:
self._height = self._global_container_stack.getProperty("machine_height", "value")
self._build_volume_message.hide()
- self._depth = self._global_container_stack.getProperty("machine_depth", "value")
+ self._depth = self._global_container_stack.getProperty("machine_depth", "value") * self._scale_vector.y
self._shape = self._global_container_stack.getProperty("machine_shape", "value")
self._updateDisallowedAreas()
@@ -678,18 +689,18 @@ class BuildVolume(SceneNode):
if setting_key == "print_sequence":
machine_height = self._global_container_stack.getProperty("machine_height", "value")
if self._application.getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time" and len(self._scene_objects) > 1:
- self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height)
- if self._height < machine_height:
+ self._height = min(self._global_container_stack.getProperty("gantry_height", "value") * self._scale_vector.z, machine_height)
+ if self._height < (machine_height * self._scale_vector.z):
self._build_volume_message.show()
else:
self._build_volume_message.hide()
else:
- self._height = self._global_container_stack.getProperty("machine_height", "value")
+ self._height = self._global_container_stack.getProperty("machine_height", "value") * self._scale_vector.z
self._build_volume_message.hide()
update_disallowed_areas = True
# sometimes the machine size or shape settings are adjusted on the active machine, we should reflect this
- if setting_key in self._machine_settings:
+ if setting_key in self._machine_settings or setting_key in self._material_size_settings:
self._updateMachineSizeProperties()
update_extra_z_clearance = True
update_disallowed_areas = True
@@ -738,9 +749,10 @@ class BuildVolume(SceneNode):
def _updateMachineSizeProperties(self) -> None:
if not self._global_container_stack:
return
- self._height = self._global_container_stack.getProperty("machine_height", "value")
- self._width = self._global_container_stack.getProperty("machine_width", "value")
- self._depth = self._global_container_stack.getProperty("machine_depth", "value")
+ self._updateScaleFactor()
+ self._height = self._global_container_stack.getProperty("machine_height", "value") * self._scale_vector.z
+ self._width = self._global_container_stack.getProperty("machine_width", "value") * self._scale_vector.x
+ self._depth = self._global_container_stack.getProperty("machine_depth", "value") * self._scale_vector.y
self._shape = self._global_container_stack.getProperty("machine_shape", "value")
def _updateDisallowedAreasAndRebuild(self):
@@ -757,6 +769,12 @@ class BuildVolume(SceneNode):
self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks())
self.rebuild()
+ def _scaleAreas(self, result_areas: List["Polygons"]) -> None:
+ for i, polygon in enumerate(result_areas):
+ result_areas[i] = polygon.scale(
+ 100.0 / max(100.0, self._global_container_stack.getProperty("material_shrinkage_percentage_xy", "value"))
+ )
+
def _updateDisallowedAreas(self) -> None:
if not self._global_container_stack:
return
@@ -812,9 +830,11 @@ class BuildVolume(SceneNode):
self._disallowed_areas = []
for extruder_id in result_areas:
+ self._scaleAreas(result_areas[extruder_id])
self._disallowed_areas.extend(result_areas[extruder_id])
self._disallowed_areas_no_brim = []
for extruder_id in result_areas_no_brim:
+ self._scaleAreas(result_areas_no_brim[extruder_id])
self._disallowed_areas_no_brim.extend(result_areas_no_brim[extruder_id])
def _computeDisallowedAreasPrinted(self, used_extruders):
@@ -1200,4 +1220,5 @@ class BuildVolume(SceneNode):
_distance_settings = ["infill_wipe_dist", "travel_avoid_distance", "support_offset", "support_enable", "travel_avoid_other_parts", "travel_avoid_supports", "wall_line_count", "wall_line_width_0", "wall_line_width_x"]
_extruder_settings = ["support_enable", "support_bottom_enable", "support_roof_enable", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_bottom_extruder_nr", "support_roof_extruder_nr", "brim_line_count", "adhesion_extruder_nr", "adhesion_type"] #Settings that can affect which extruders are used.
_limit_to_extruder_settings = ["wall_extruder_nr", "wall_0_extruder_nr", "wall_x_extruder_nr", "top_bottom_extruder_nr", "infill_extruder_nr", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_bottom_extruder_nr", "support_roof_extruder_nr", "adhesion_extruder_nr"]
- _disallowed_area_settings = _skirt_settings + _prime_settings + _tower_settings + _ooze_shield_settings + _distance_settings + _extruder_settings
+ _material_size_settings = ["material_shrinkage_percentage", "material_shrinkage_percentage_xy", "material_shrinkage_percentage_z"]
+ _disallowed_area_settings = _skirt_settings + _prime_settings + _tower_settings + _ooze_shield_settings + _distance_settings + _extruder_settings + _material_size_settings
diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json
index 49ad2e3c5b..f54e64849c 100644
--- a/resources/definitions/fdmprinter.def.json
+++ b/resources/definitions/fdmprinter.def.json
@@ -2512,7 +2512,42 @@
"maximum_value_warning": "120",
"settable_per_mesh": false,
"settable_per_extruder": false,
- "resolve": "sum(extruderValues(\"material_shrinkage_percentage\")) / len(extruderValues(\"material_shrinkage_percentage\"))"
+ "resolve": "sum(extruderValues(\"material_shrinkage_percentage\")) / len(extruderValues(\"material_shrinkage_percentage\"))",
+ "children":
+ {
+ "material_shrinkage_percentage_xy":
+ {
+ "label": "Horizontal Scaling Factor Shrinkage Compensation",
+ "description": "To compensate for the shrinkage of the material as it cools down, the model will be scaled with this factor in the XY-direction (horizontally).",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100.0,
+ "enabled": false,
+ "minimum_value": "0.001",
+ "minimum_value_warning": "100",
+ "maximum_value_warning": "120",
+ "settable_per_mesh": false,
+ "settable_per_extruder": false,
+ "resolve": "sum(extruderValues(\"material_shrinkage_percentage_xy\")) / len(extruderValues(\"material_shrinkage_percentage_xy\"))",
+ "value": "material_shrinkage_percentage"
+ },
+ "material_shrinkage_percentage_z":
+ {
+ "label": "Vertical Scaling Factor Shrinkage Compensation",
+ "description": "To compensate for the shrinkage of the material as it cools down, the model will be scaled with this factor in the Z-direction (vertically).",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100.0,
+ "enabled": false,
+ "minimum_value": "0.001",
+ "minimum_value_warning": "100",
+ "maximum_value_warning": "120",
+ "settable_per_mesh": false,
+ "settable_per_extruder": false,
+ "resolve": "sum(extruderValues(\"material_shrinkage_percentage_z\")) / len(extruderValues(\"material_shrinkage_percentage_z\"))",
+ "value": "material_shrinkage_percentage"
+ }
+ }
},
"material_crystallinity":
{
diff --git a/tests/TestBuildVolume.py b/tests/TestBuildVolume.py
index 293b8e0270..f59d83df5e 100644
--- a/tests/TestBuildVolume.py
+++ b/tests/TestBuildVolume.py
@@ -57,7 +57,10 @@ class TestCalculateBedAdhesionSize:
"machine_depth": {"value": 200},
"skirt_line_count": {"value": 0},
"skirt_gap": {"value": 0},
- "raft_margin": {"value": 0}
+ "raft_margin": {"value": 0},
+ "material_shrinkage_percentage": {"value": 100.0},
+ "material_shrinkage_percentage_xy": {"value": 100.0},
+ "material_shrinkage_percentage_z": {"value": 100.0},
}
def getPropertySideEffect(*args, **kwargs):
@@ -109,6 +112,9 @@ 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},
"machine_depth": {"value": 200},
+ "material_shrinkage_percentage": {"value": 100.0},
+ "material_shrinkage_percentage_xy": {"value": 100.0},
+ "material_shrinkage_percentage_z": {"value": 100.0},
}
def getPropertySideEffect(*args, **kwargs):
@@ -157,7 +163,11 @@ class TestUpdateRaftThickness:
"raft_surface_thickness": {"value": 1},
"raft_airgap": {"value": 1},
"layer_0_z_overlap": {"value": 1},
- "adhesion_type": {"value": "raft"}}
+ "adhesion_type": {"value": "raft"},
+ "material_shrinkage_percentage": {"value": 100.0},
+ "material_shrinkage_percentage_xy": {"value": 100.0},
+ "material_shrinkage_percentage_z": {"value": 100.0},
+ }
def getPropertySideEffect(*args, **kwargs):
properties = TestUpdateRaftThickness.setting_property_dict.get(args[1])
@@ -208,6 +218,9 @@ class TestComputeDisallowedAreasPrimeBlob:
"extruder_prime_pos_x": {"value": 25},
"extruder_prime_pos_y": {"value": 50},
"machine_center_is_zero": {"value": True},
+ "material_shrinkage_percentage": {"value": 100.0},
+ "material_shrinkage_percentage_xy": {"value": 100.0},
+ "material_shrinkage_percentage_z": {"value": 100.0},
}
def getPropertySideEffect(*args, **kwargs):
@@ -248,7 +261,11 @@ class TestComputeDisallowedAreasPrimeBlob:
class TestCalculateExtraZClearance:
setting_property_dict = {"retraction_hop": {"value": 12},
- "retraction_hop_enabled": {"value": True}}
+ "retraction_hop_enabled": {"value": True},
+ "material_shrinkage_percentage": {"value": 100.0},
+ "material_shrinkage_percentage_xy": {"value": 100.0},
+ "material_shrinkage_percentage_z": {"value": 100.0},
+ }
def getPropertySideEffect(*args, **kwargs):
properties = TestCalculateExtraZClearance.setting_property_dict.get(args[1])
@@ -285,6 +302,16 @@ class TestCalculateExtraZClearance:
class TestRebuild:
+ setting_property_dict = {
+ "material_shrinkage_percentage": {"value": 100.0},
+ "material_shrinkage_percentage_xy": {"value": 100.0},
+ "material_shrinkage_percentage_z": {"value": 100.0},
+ }
+ def getPropertySideEffect(*args, **kwargs):
+ properties = TestCalculateExtraZClearance.setting_property_dict.get(args[1])
+ if properties:
+ return properties.get(args[2])
+
def test_zeroWidthHeightDepth(self, build_volume: BuildVolume):
build_volume.rebuild()
assert build_volume.getMeshData() is None
@@ -311,6 +338,7 @@ class TestRebuild:
build_volume.setDepth(10)
mocked_global_stack = MagicMock()
+ mocked_global_stack.getProperty = MagicMock(side_effect=self.getPropertySideEffect)
build_volume._global_container_stack = mocked_global_stack
build_volume.getEdgeDisallowedSize = MagicMock(return_value = 0)
build_volume.updateNodeBoundaryCheck = MagicMock()
@@ -328,7 +356,11 @@ class TestUpdateMachineSizeProperties:
setting_property_dict = {"machine_width": {"value": 50},
"machine_depth": {"value": 100},
"machine_height": {"value": 200},
- "machine_shape": {"value": "DERP!"}}
+ "machine_shape": {"value": "DERP!"},
+ "material_shrinkage_percentage": {"value": 100.0},
+ "material_shrinkage_percentage_xy": {"value": 100.0},
+ "material_shrinkage_percentage_z": {"value": 100.0},
+ }
def getPropertySideEffect(*args, **kwargs):
properties = TestUpdateMachineSizeProperties.setting_property_dict.get(args[1])