Commit b633f23f authored by sumpfralle's avatar sumpfralle

r704@erker: lars | 2010-02-22 00:24:19 +0100

 make sure that the path generators never get stuck in in infinite loop caused by floating point inaccuracies
 define a maximum recursion depth (20) for the PushCutter algorithm (i.e. maximum precision = 1/(1^20) of bounding box width)


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@156 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent e30b290d
...@@ -48,8 +48,10 @@ class DropCutter: ...@@ -48,8 +48,10 @@ class DropCutter:
finished_plane = False finished_plane = False
self._boundary_warning_already_shown = False self._boundary_warning_already_shown = False
last_outer_loop = False
while not finished_plane: while not finished_plane:
last_inner_loop = False
finished_line = False finished_line = False
dims[0].set(dims[0].start) dims[0].set(dims[0].start)
pa.new_scanline() pa.new_scanline()
...@@ -71,10 +73,9 @@ class DropCutter: ...@@ -71,10 +73,9 @@ class DropCutter:
# make sure, that the we also handle the outmost border of the bounding box # make sure, that the we also handle the outmost border of the bounding box
if dims[0].check_bounds(tolerance=d0): if dims[0].check_bounds(tolerance=d0):
# check if we are still within the strict limits if not dims[0].check_bounds() and not last_inner_loop:
if not dims[0].check_bounds():
# we exceeded the maximum, but we are still within step width
dims[0].set(dims[0].end) dims[0].set(dims[0].end)
last_inner_loop = True
else: else:
finished_line = True finished_line = True
...@@ -83,10 +84,9 @@ class DropCutter: ...@@ -83,10 +84,9 @@ class DropCutter:
# make sure, that the we also handle the outmost border of the bounding box # make sure, that the we also handle the outmost border of the bounding box
if dims[1].check_bounds(tolerance=d1): if dims[1].check_bounds(tolerance=d1):
# check if we are still within the strict limits if not dims[1].check_bounds() and not last_outer_loop:
if not dims[1].check_bounds():
# we crossed the maximum, but we are still within step width
dims[1].set(dims[1].end) dims[1].set(dims[1].end)
last_outer_loop = True
else: else:
finished_plane = True finished_plane = True
......
...@@ -144,6 +144,7 @@ class PushCutter: ...@@ -144,6 +144,7 @@ class PushCutter:
""" """
# max_deviation_x = dx/accuracy # max_deviation_x = dx/accuracy
accuracy = 20 accuracy = 20
max_depth = 20
x = minx x = minx
y = miny y = miny
...@@ -151,10 +152,13 @@ class PushCutter: ...@@ -151,10 +152,13 @@ class PushCutter:
if dx > 0: if dx > 0:
depth_x = math.log(accuracy * (maxx-minx) / dx) / math.log(2) depth_x = math.log(accuracy * (maxx-minx) / dx) / math.log(2)
depth_x = max(math.ceil(int(depth_x)), 4) depth_x = max(math.ceil(int(depth_x)), 4)
depth_x = min(depth_x, max_depth)
else: else:
depth_y = math.log(accuracy * (maxy-miny) / dy) / math.log(2) depth_y = math.log(accuracy * (maxy-miny) / dy) / math.log(2)
depth_y = max(math.ceil(int(depth_y)), 4) depth_y = max(math.ceil(int(depth_y)), 4)
depth_y = min(depth_y, max_depth)
last_loop = False
while (x <= maxx) and (y <= maxy): while (x <= maxx) and (y <= maxy):
points = [] points = []
self.pa.new_scanline() self.pa.new_scanline()
...@@ -174,11 +178,13 @@ class PushCutter: ...@@ -174,11 +178,13 @@ class PushCutter:
if dx > 0: if dx > 0:
x += dx x += dx
if (x > maxx) and (x - dx < maxx): if (x > maxx) and not last_loop:
last_loop = True
x = maxx x = maxx
else: else:
y += dy y += dy
if (y > maxy) and (y - dy < maxy): if (y > maxy) and not last_loop:
last_loop = True
y = maxy y = maxy
def DropCutterTest(self, point, model): def DropCutterTest(self, point, model):
...@@ -215,6 +221,7 @@ class PushCutter: ...@@ -215,6 +221,7 @@ class PushCutter:
line = 0 line = 0
last_loop = False
while x<=maxx and y<=maxy: while x<=maxx and y<=maxy:
self.pa.new_scanline() self.pa.new_scanline()
if False: if False:
...@@ -361,15 +368,17 @@ class PushCutter: ...@@ -361,15 +368,17 @@ class PushCutter:
if dx != 0: if dx != 0:
x += dx x += dx
# never skip the outermost bounding limit - reduce the step size if required # never skip the outermost bounding limit - reduce the step size if required
if (x > maxx) and (x - dx < maxx): if (x > maxx) and not last_loop:
x = maxx x = maxx
last_loop = True
else: else:
x = minx x = minx
if dy != 0: if dy != 0:
y += dy y += dy
# never skip the outermost bounding limit - reduce the step size if required # never skip the outermost bounding limit - reduce the step size if required
if (y > maxy) and (y - dy < maxy): if (y > maxy) and not last_loop:
y = maxy y = maxy
last_loop = True
else: else:
y = miny y = miny
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment