diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index 419855bdb2..adaaa49112 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -609,7 +609,11 @@ class depth_params(object): self.__step_down = math.fabs(step_down) self.__z_finish_step = math.fabs(z_finish_step) self.__final_depth = final_depth - self.__user_depths = user_depths + self.__user_depths = ( + None + if user_depths is None + else self.__filter_roughly_equal_depths(user_depths) + ) self.data = self.__get_depths(equalstep=equalstep) self.index = 0 @@ -718,7 +722,65 @@ class depth_params(object): )[1:] depths.reverse() - return depths + + if len(depths) < 2: + return depths + + return self.__filter_roughly_equal_depths(depths) + + def __filter_roughly_equal_depths(self, depths): + """Depths arrive sorted from largest to smallest, positive to negative. + Return unique list of depths, using PathGeom.isRoughly() method to determine + if the two values are equal. Only one of two consecutive equals are removed. + + The assumption is that there are not enough consecutively roughly-equal depths + to be removed, so as to eliminate an effective step-down depth with the removal + of repetitive roughly-equal values.""" + + if len(depths) == 2: + if PathGeom.isRoughly(depths[0], depths[1]): + return [depths[1]] + return depths + + # print("raw depths: {}".format(depths)) + + uniqueDepths = depths + lastDepth = None + maxLoops = 0 + while maxLoops < 10: + # print("\nStart scan... uniqueDepths: {}".format(uniqueDepths)) + stop = True + keep = [] + # Filter out unique values from consecutive pairs + for i in range(0, len(uniqueDepths) - 1): + dep1 = uniqueDepths[i] + dep2 = uniqueDepths[i + 1] + # print("comparing: {} and {}".format(dep1, dep2)) + # print("lastDepth: {}".format(lastDepth)) + + if PathGeom.isRoughly(dep1, dep2): + if PathGeom.isRoughly(lastDepth, dep2): + keep.pop() + keep.append(dep2) + # Cycle again if a roughly-equal pair is found + stop = False + else: + if lastDepth is None: + keep.append(dep1) + else: + if not PathGeom.isRoughly(lastDepth, dep1): + keep.append(dep1) + keep.append(dep2) + + lastDepth = dep2 + # Efor + uniqueDepths = keep + maxLoops += 1 + if stop: + break + + # print("uniqueDepths: {}".format(uniqueDepths)) + return uniqueDepths def __equal_steps(self, start, stop, max_size): """returns a list of depths beginning with the bottom (included), ending diff --git a/src/Mod/Path/PathTests/TestPathDepthParams.py b/src/Mod/Path/PathTests/TestPathDepthParams.py index fed0779fc8..cc25ec0088 100644 --- a/src/Mod/Path/PathTests/TestPathDepthParams.py +++ b/src/Mod/Path/PathTests/TestPathDepthParams.py @@ -211,3 +211,43 @@ class depthTestCases(unittest.TestCase): "user_depths": None, } self.assertRaises(ValueError, PathUtils.depth_params, **args) + + def test90(self): + """stepping down with single stepdown exactly equal to total depth""" + args = { + "clearance_height": 20.0, + "safe_height": 15.0, + "start_depth": 10.0, + "step_down": 10.0, + "z_finish_step": 0.0, + "final_depth": 0.0, + "user_depths": None, + } + + expected = [0] + + d = PathUtils.depth_params(**args) + r = [i for i in d] + self.assertListEqual( + r, expected, "Expected {}, but result of {}".format(expected, r) + ) + + def test100(self): + """stepping down with single stepdown roughly equal to total depth""" + args = { + "clearance_height": 20.0, + "safe_height": 15.0, + "start_depth": 10.000000001, + "step_down": 10.0, + "z_finish_step": 0.0, + "final_depth": 0.0, + "user_depths": None, + } + + expected = [0] + + d = PathUtils.depth_params(**args) + r = [i for i in d] + self.assertListEqual( + r, expected, "Expected {}, but result of {}".format(expected, r) + )