diff --git a/src/Mod/CAM/CAMTests/TestLinkingGenerator.py b/src/Mod/CAM/CAMTests/TestLinkingGenerator.py index 072741e4f6..77effc94f0 100644 --- a/src/Mod/CAM/CAMTests/TestLinkingGenerator.py +++ b/src/Mod/CAM/CAMTests/TestLinkingGenerator.py @@ -82,6 +82,20 @@ class TestGetLinkingMoves(PathTestUtils.PathTestBase): solids=[blocking_box], ) + def test_path_blocked_by_solid_with_tolerance(self): + blocking_box = Part.makeBox(1, 10, 10) + blocking_box.translate(FreeCAD.Vector(5, -5, 0)) + with self.assertRaises(RuntimeError): + generator.get_linking_moves( + start_position=self.start, + target_position=self.target, + local_clearance=5, + global_clearance=11, + tool_shape=self.tool, + tolerance=1.1, + solids=[blocking_box], + ) + def test_plunge_to_zero_depth(self): """Test that plunge moves correctly go to Z=0 (regression test for depth==0 bug)""" start = FreeCAD.Vector(0, 0, 1) # Start below clearance diff --git a/src/Mod/CAM/Path/Base/Generator/linking.py b/src/Mod/CAM/Path/Base/Generator/linking.py index f410de22f9..d80b85cb1e 100644 --- a/src/Mod/CAM/Path/Base/Generator/linking.py +++ b/src/Mod/CAM/Path/Base/Generator/linking.py @@ -62,7 +62,7 @@ def check_collision( # Create direct path wire wire = Part.Wire([Part.makeLine(start_position, target_position)]) distance = wire.distToShape(collision_model)[0] - return distance < tolerance + return distance < tolerance and not Path.Geom.isRoughly(distance, tolerance) def get_linking_moves( @@ -74,6 +74,7 @@ def get_linking_moves( solids: Optional[List[Part.Shape]] = None, retract_height_offset: Optional[float] = None, skip_if_no_collision: bool = False, + tolerance: float = 0.001, ) -> list: """ Generate linking moves from start to target position. @@ -121,7 +122,7 @@ def get_linking_moves( # Try each height for height in heights: wire = make_linking_wire(start_position, target_position, height) - if is_wire_collision_free(wire, collision_model): + if is_wire_collision_free(wire, collision_model, tolerance): cmds = Path.fromShape(wire).Commands # Ensure all commands have complete XYZ coordinates # Path.fromShape() may omit coordinates that don't change @@ -170,4 +171,4 @@ def is_wire_collision_free( if not solid: return True distance = wire.distToShape(solid)[0] - return distance >= tolerance + return distance >= tolerance or Path.Geom.isRoughly(distance, tolerance)