Commit 1a77f369 authored by lode_leroy's avatar lode_leroy

another try at fixing PushCutter

git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@39 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 6d54c6c6
...@@ -14,6 +14,7 @@ class Hit: ...@@ -14,6 +14,7 @@ class Hit:
self.t = t self.t = t
self.d = d self.d = d
self.dir = dir self.dir = dir
self.z = -INFINITE
def cmp(a,b): def cmp(a,b):
return cmp(a.d, b.d) return cmp(a.d, b.d)
...@@ -88,9 +89,13 @@ class PushCutter: ...@@ -88,9 +89,13 @@ class PushCutter:
if dx==0: if dx==0:
forward = Point(1,0,0) forward = Point(1,0,0)
backward = Point(-1,0,0) backward = Point(-1,0,0)
forward_small = Point(epsilon,0,0)
backward_small = Point(-epsilon,0,0)
elif dy == 0: elif dy == 0:
forward = Point(0,1,0) forward = Point(0,1,0)
backward = Point(0,-1,0) backward = Point(0,-1,0)
forward_small = Point(0,epsilon,0)
backward_small = Point(0,-epsilon,0)
x = minx x = minx
y = miny y = miny
...@@ -101,7 +106,7 @@ class PushCutter: ...@@ -101,7 +106,7 @@ class PushCutter:
self.pa.new_scanline() self.pa.new_scanline()
if False: if False:
line += 1 line += 1
if line == 13: if line == 10:
DEBUG_PUSHCUTTER=True DEBUG_PUSHCUTTER=True
DEBUG_PUSHCUTTER2=True DEBUG_PUSHCUTTER2=True
DEBUG_PUSHCUTTER3=True DEBUG_PUSHCUTTER3=True
...@@ -120,14 +125,10 @@ class PushCutter: ...@@ -120,14 +125,10 @@ class PushCutter:
if DEBUG_PUSHCUTTER3: if DEBUG_PUSHCUTTER3:
self.svg.stroke('gray')
self.svg.AddLine(minx, z, maxx, z)
self.svg.fill('lightgreen') self.svg.fill('lightgreen')
p = Point(minx, y, 10) p = Point(minx, y, 10)
for i in range(0,100): for i in range(0,100):
p.x = minx + float(i)/100*float(maxx-minx) p.x = minx + float(i)/100*float(maxx-minx)
(zmax, tmax) = self.DropCutterTest(p, model)
if DEBUG_PUSHCUTTER: print "v cl=",p,",zmax=",zmax
self.svg.AddDot(p.x, zmax) self.svg.AddDot(p.x, zmax)
self.svg.fill('black') self.svg.fill('black')
...@@ -135,114 +136,102 @@ class PushCutter: ...@@ -135,114 +136,102 @@ class PushCutter:
# find all hits along scan line # find all hits along scan line
hits = [] hits = []
prev = Point(x,y,z) prev = Point(x,y,z)
c.moveto(prev) hits.append(Hit(prev, None, 0, None))
for t in model.triangles(): for t in model.triangles():
#if t.normal().z < 0: continue; #if t.normal().z < 0: continue;
# normals point outward... and we want to approach the model from the outside! # normals point outward... and we want to approach the model from the outside!
n = t.normal().dot(forward) n = t.normal().dot(forward)
c.moveto(prev)
if n>=0: if n>=0:
(cl,d) = c.intersect(backward, t) (cl,d) = c.intersect(backward, t)
if cl: if cl:
#if DEBUG_PUSHCUTTER: print "< cl=",cl,",d=",-d,",t=",t if DEBUG_PUSHCUTTER: print "< cl=",cl,",d=",-d,",t=",t.id,",t.n=",t.normal(),",n=",n
hits.append(Hit(cl,t,-d,backward)) hits.append(Hit(cl,t,-d,backward))
hits.append(Hit(cl.sub(backward_small),t,-d+epsilon,backward))
if DEBUG_PUSHCUTTER3: self.svg.AddDot(cl.x, cl.z) if DEBUG_PUSHCUTTER3: self.svg.AddDot(cl.x, cl.z)
else:
if DEBUG_PUSHCUTTER: print "< cl=",cl,",0",",t=",t.id
if n<=0: if n<=0:
(cl,d) = c.intersect(forward, t) (cl,d) = c.intersect(forward, t)
if cl: if cl:
#if DEBUG_PUSHCUTTER: print "> cl=",cl,",d=",d,",t=",t if DEBUG_PUSHCUTTER: print "> cl=",cl,",d=",d,",t=",t.id,",t.n=",t.normal(),",n=",n
hits.append(Hit(cl,t,d,forward)) hits.append(Hit(cl,t,d,forward))
hits.append(Hit(cl.sub(forward_small),t,d-epsilon,forward))
if DEBUG_PUSHCUTTER3: self.svg.AddDot(cl.x, cl.z) if DEBUG_PUSHCUTTER3: self.svg.AddDot(cl.x, cl.z)
else:
if DEBUG_PUSHCUTTER: print "> cl=",cl,",0",",t=",t.id
if dx == 0:
x = maxx
if dy == 0:
y = maxy
next = Point(x, y, z)
hits.append(Hit(next, None, maxx-minx, None))
# sort along the scan direction # sort along the scan direction
hits.sort(Hit.cmp) hits.sort(Hit.cmp)
# # remove duplicates (typically edges) # remove duplicates (typically shared edges)
# i = 1 i = 1
# while i < len(hits): while i < len(hits):
# while i<len(hits) and abs(hits[i].d - hits[i-1].d)<epsilon: while i<len(hits) and abs(hits[i].d - hits[i-1].d)<epsilon/2:
# del hits[i] del hits[i]
# i += 1 i += 1
# determine height at each interesting point
for h in hits:
(zmax, tmax) = self.DropCutterTest(h.cl, model)
h.z = zmax
if DEBUG_PUSHCUTTER: print "@ cl=",h.cl,",d=",h.d,",z=",h.z
if DEBUG_PUSHCUTTER3: self.svg.fill("blue"); self.svg.AddDot(h.cl.x, h.z)
if DEBUG_PUSHCUTTER or DEBUG_PUSHCUTTER3: if DEBUG_PUSHCUTTER or DEBUG_PUSHCUTTER3:
yt = -4
i = 0
for h in hits: for h in hits:
(zmax, tmax) = self.DropCutterTest(h.cl, model)
if DEBUG_PUSHCUTTER: print " cl=",h.cl,",d=",h.d,",zmax=",zmax
if DEBUG_PUSHCUTTER3: if DEBUG_PUSHCUTTER3:
self.svg.fill('black')
self.svg.stroke('gray') self.svg.stroke('gray')
self.svg.AddLine(h.cl.x, -1, h.cl.x, zmax) self.svg.AddLine(h.cl.x, yt, h.cl.x, h.z)
self.svg.AddText(h.cl.x, yt, str(h.cl.x))
# find parts of scanline where model is below z-level yt -= 0.5
i = 0
while i < len(hits):
# find next hit cutter location that is below z-level
while i < len(hits):
(zmax, tmax) = self.DropCutterTest(prev, model)
if DEBUG_PUSHCUTTER: print "1", prev, "z=",zmax
if zmax <= z+epsilon:
break
if DEBUG_PUSHCUTTER3:
self.svg.stroke('lightred')
self.svg.AddLine(prev.x, prev.z, prev.x, zmax)
prev = hits[i].cl
i += 1 i += 1
if DEBUG_PUSHCUTTER3:
self.svg.stroke('red')
self.svg.AddLine(prev.x, prev.z, prev.x, zmax)
# find next hit cutter location that is above z-level
while i < len(hits):
next = hits[i].cl
(zmax, tmax) = self.DropCutterTest(next, model)
if DEBUG_PUSHCUTTER: print "2", next, "z=",zmax
i += 1
if zmax >= z-epsilon:
break
if DEBUG_PUSHCUTTER3:
self.svg.stroke('lightblue')
self.svg.AddLine(next.x, next.z, next.x, zmax)
if DEBUG_PUSHCUTTER3:
self.svg.stroke('blue')
self.svg.AddLine(next.x, next.z, next.x, zmax)
if i < len(hits):
self.pa.append(prev)
self.pa.append(next)
if DEBUG_PUSHCUTTER: print "C ", prev, next, "z=",zmax
if DEBUG_PUSHCUTTER3:
self.svg.stroke('red')
self.svg.AddLine(prev.x, z-0.1, next.x, z-0.1)
prev = hits[i].cl
if dx == 0:
x = maxx
if dy == 0:
y = maxy
next = Point(x,y,z)
(zmax, tmax) = self.DropCutterTest(next, model)
if DEBUG_PUSHCUTTER: print "3 ", next, "z=",zmax
if zmax <= z+epsilon: # find first hit cutter location that is below z-level
self.pa.append(prev) begin = hits[0].cl
self.pa.append(next) end = None
if DEBUG_PUSHCUTTER: print "C ", prev, next, "z=",zmax for h in hits:
if h.z >= z - epsilon/10:
if begin and end:
if DEBUG_PUSHCUTTER:
print "C ", begin, " - ", end
self.pa.append(begin)
self.pa.append(end)
if DEBUG_PUSHCUTTER3:
self.svg.stroke("red' stroke-width='0.1")
self.svg.AddLine(begin.x, z-0.1, end.x, z-0.1)
begin = None
end = None
if h.z <= z + epsilon/10:
if not begin:
begin = h.cl
else:
end = h.cl
if begin and end:
if DEBUG_PUSHCUTTER:
print "C ", begin, " - ", end
self.pa.append(begin)
self.pa.append(end)
if DEBUG_PUSHCUTTER3: if DEBUG_PUSHCUTTER3:
self.svg.stroke('red') self.svg.stroke("red' stroke-width='0.1")
self.svg.AddLine(prev.x, z-0.1, next.x, z-0.1) self.svg.AddLine(begin.x, z-0.1, end.x, z-0.1)
if dx != 0: if dx != 0:
x += dx x += dx
......
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