Commit 4b8afbdc authored by lode_leroy's avatar lode_leroy

add ContourCutter

git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@21 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 09281b60
...@@ -11,6 +11,11 @@ class PolygonExtractor: ...@@ -11,6 +11,11 @@ class PolygonExtractor:
MONOTONE=2 MONOTONE=2
def __init__(self, policy=MONOTONE): def __init__(self, policy=MONOTONE):
self.policy = policy self.policy = policy
self.hor_path_list = None
self.ver_path_list = None
self.merge_path_list = None
self.dx = 1
self.dy = 1
def append(self, p): def append(self, p):
if (self.current_dir==0): if (self.current_dir==0):
...@@ -302,10 +307,11 @@ class PolygonExtractor: ...@@ -302,10 +307,11 @@ class PolygonExtractor:
self.prev_line = self.curr_line self.prev_line = self.curr_line
def merge_path_lists(self): def merge_path_lists(self):
self.merge_path_list = [] if self.hor_path_list:
pass self.merge_path_list = self.hor_path_list
dx = 1 else:
dy = 1 self.merge_path_list = self.ver_path_list
return
# find matching path to merge with */ # find matching path to merge with */
for s0 in self.hor_path_list: for s0 in self.hor_path_list:
......
...@@ -239,6 +239,8 @@ class SimpleGui(Frame): ...@@ -239,6 +239,8 @@ class SimpleGui(Frame):
self.option = ZigZagCutter() self.option = ZigZagCutter()
elif self.PathProcessorName.get() == "PolygonCutter": elif self.PathProcessorName.get() == "PolygonCutter":
self.option = PolygonCutter() self.option = PolygonCutter()
elif self.PathProcessorName.get() == "ContourCutter":
self.option = ContourCutter()
else: else:
self.option = None self.option = None
self.pathgenerator = PushCutter(self.cutter, self.model, self.option); self.pathgenerator = PushCutter(self.cutter, self.model, self.option);
......
...@@ -56,7 +56,7 @@ class DropCutter: ...@@ -56,7 +56,7 @@ class DropCutter:
(X,Z) = intersect_lines(xl, zl, nxl, nzl, xm, zm, nxm, nzm) (X,Z) = intersect_lines(xl, zl, nxl, nzl, xm, zm, nxm, nzm)
if X and xl < X and X < xm and (Z > zl or Z > zm): if X and xl < X and X < xm and (Z > zl or Z > zm):
Y = cl_last.y Y = cl_last.y
if Z<z0 or Z>z1: if Z<z0-10 or Z>z1+10:
print "^", "xl=",xl,", zl=",zl,"nxl=",nxl,", nzl=",nzl,", X=", X, ", Z=",Z,", xm=",xm,",zm=",zm, ", nxm=",nxm,",nzm=",nzm print "^", "xl=",xl,", zl=",zl,"nxl=",nxl,", nzl=",nzl,", X=", X, ", Z=",Z,", xm=",xm,",zm=",zm, ", nxm=",nxm,",nzm=",nzm
else: else:
pa.append(Point(X,Y,Z)) pa.append(Point(X,Y,Z))
...@@ -111,7 +111,7 @@ class DropCutter: ...@@ -111,7 +111,7 @@ class DropCutter:
(Y,Z) = intersect_lines(yl, zl, nyl, nzl, ym, zm, nym, nzm) (Y,Z) = intersect_lines(yl, zl, nyl, nzl, ym, zm, nym, nzm)
if Y and yl < Y and Y < ym and (Z > zl or Z > zm): if Y and yl < Y and Y < ym and (Z > zl or Z > zm):
X = cl_last.x X = cl_last.x
if Z<z0 or Z>z1: if Z<z0-10 or Z>z1+10:
print "^", "yl=",yl,", zl=",zl,"nyl=",nyl,", nzl=",nzl,", Y=", Y, ", Z=",Z,", ym=",ym,",zm=",zm, ", nym=",nym,",nzm=",nzm print "^", "yl=",yl,", zl=",zl,"nyl=",nyl,", nzl=",nzl,", Y=", Y, ", Z=",Z,", ym=",ym,",zm=",zm, ", nym=",nym,",nzm=",nzm
else: else:
pa.append(Point(X,Y,Z)) pa.append(Point(X,Y,Z))
......
...@@ -19,107 +19,127 @@ class PushCutter: ...@@ -19,107 +19,127 @@ class PushCutter:
self.pa = pathextractor self.pa = pathextractor
def GenerateToolPath(self, minx, maxx, miny, maxy, minz, maxz, dx, dy, dz): def GenerateToolPath(self, minx, maxx, miny, maxy, minz, maxz, dx, dy, dz):
if dx==0: if dx != 0:
forward = Point(1,0,0) self.pa.dx = dx
backward = Point(-1,0,0) else:
elif dy == 0: self.pa.dx = dy
forward = Point(0,1,0)
backward = Point(0,-1,0) if dy != 0:
self.pa.dy = dy
else:
self.pa.dy = dx
z = maxz z = maxz
c = self.cutter
model = self.model
paths = [] paths = []
while z >= minz: while z >= minz:
self.pa.new_direction(0) if dy > 0:
x = minx self.pa.new_direction(0)
y = miny self.GenerateToolPathSlice(minx, maxx, miny, maxy, z, 0, dy)
while x<=maxx and y<=maxy: self.pa.end_direction()
self.pa.new_scanline() if dx > 0:
self.pa.new_direction(1)
# find all hits along scan line self.GenerateToolPathSlice(minx, maxx, miny, maxy, z, dx, 0)
hits = [] self.pa.end_direction()
prev = Point(x,y,z) self.pa.finish()
c.moveto(prev)
for t in model.triangles():
if t.normal().z < 0: continue;
# normals point outward... and we want to approach the model from the outside!
n = t.normal().dot(forward)
if n>=0:
(cl,d) = c.intersect(backward, t)
if cl:
# print "< cl=",cl,",d=",-d,",t=",t
hits.append(Hit(cl,t,-d,backward))
if n<=0:
(cl,d) = c.intersect(forward, t)
if cl:
# print "> cl=",cl,",d=",d,",t=",t
hits.append(Hit(cl,t,d,forward))
# sort along the scan direction
hits.sort(Hit.cmp)
# remove duplicates (typically edges)
i = 1
while i < len(hits):
while i<len(hits) and abs(hits[i].d - hits[i-1].d)<epsilon:
del hits[i]
i += 1
# find parts of scanline where model is below z-level
i = 0
while i < len(hits):
next = hits[i].cl
self.pa.append(prev)
self.pa.append(next)
i += 1
# find next hit cutter location that is below z-level if self.pa.paths:
while i < len(hits): paths += self.pa.paths
prev = hits[i].cl z -= dz
c.moveto(prev)
c.moveto(prev.sub(hits[i].dir.mul(epsilon)))
zmax = -INFINITE
for t in model.triangles():
if t.normal().z < 0: continue;
cl = c.drop(t)
if cl and cl.z > zmax and cl.z < INFINITE:
zmax = cl.z
i += 1 return paths
if zmax <= z+epsilon: def GenerateToolPathSlice(self, minx, maxx, miny, maxy, z, dx, dy):
break c = self.cutter
model = self.model
if dx == 0: if dx==0:
x = maxx forward = Point(1,0,0)
if dy == 0: backward = Point(-1,0,0)
y = maxy elif dy == 0:
forward = Point(0,1,0)
backward = Point(0,-1,0)
next = Point(x,y,z) x = minx
y = miny
while x<=maxx and y<=maxy:
self.pa.new_scanline()
# find all hits along scan line
hits = []
prev = Point(x,y,z)
c.moveto(prev)
for t in model.triangles():
if t.normal().z < 0: continue;
# normals point outward... and we want to approach the model from the outside!
n = t.normal().dot(forward)
if n>=0:
(cl,d) = c.intersect(backward, t)
if cl:
# print "< cl=",cl,",d=",-d,",t=",t
hits.append(Hit(cl,t,-d,backward))
if n<=0:
(cl,d) = c.intersect(forward, t)
if cl:
# print "> cl=",cl,",d=",d,",t=",t
hits.append(Hit(cl,t,d,forward))
# sort along the scan direction
hits.sort(Hit.cmp)
# remove duplicates (typically edges)
i = 1
while i < len(hits):
while i<len(hits) and abs(hits[i].d - hits[i-1].d)<epsilon:
del hits[i]
i += 1
# find parts of scanline where model is below z-level
i = 0
while i < len(hits):
next = hits[i].cl
self.pa.append(prev) self.pa.append(prev)
self.pa.append(next) self.pa.append(next)
i += 1
if dx != 0: # find next hit cutter location that is below z-level
x += dx while i < len(hits):
else: prev = hits[i].cl
x = minx c.moveto(prev)
if dy != 0: c.moveto(prev.sub(hits[i].dir.mul(epsilon)))
y += dy zmax = -INFINITE
else: for t in model.triangles():
y = miny if t.normal().z < 0: continue;
cl = c.drop(t)
if cl and cl.z > zmax and cl.z < INFINITE:
zmax = cl.z
self.pa.end_scanline() i += 1
self.pa.end_direction() if zmax <= z+epsilon:
self.pa.finish() break
paths += self.pa.paths if dx == 0:
z -= dz x = maxx
if dy == 0:
y = maxy
next = Point(x,y,z)
self.pa.append(prev)
self.pa.append(next)
if dx != 0:
x += dx
else:
x = minx
if dy != 0:
y += dy
else:
y = miny
self.pa.end_scanline()
return paths
from pycam.Geometry import *
from pycam.Geometry.PolygonExtractor import *
class ContourCutter:
def __init__(self):
self.paths = []
self.curr_path = None
self.scanline = None
self.pe = PolygonExtractor(PolygonExtractor.CONTOUR)
self.points = []
def append(self, p):
self.points.append(p)
def new_direction(self, dir):
self.pe.new_direction(dir)
def end_direction(self):
self.pe.end_direction()
def new_scanline(self):
self.pe.new_scanline()
self.points = []
def end_scanline(self):
for i in range(1, len(self.points)-1):
self.pe.append(self.points[i])
self.pe.end_scanline()
def finish(self):
self.pe.finish()
if True:
if self.pe.hor_path_list:
self.paths = self.pe.hor_path_list
else:
self.paths = self.pe.ver_path_list
for p in self.paths:
p.append(p.points[0])
else:
if self.pe.merge_path_list:
self.paths = self.pe.merge_path_list
...@@ -26,16 +26,29 @@ class PolygonCutter: ...@@ -26,16 +26,29 @@ class PolygonCutter:
def finish(self): def finish(self):
self.pe.finish() self.pe.finish()
paths = [] paths = []
for path in self.pe.hor_path_list: if self.pe.hor_path_list:
points = path.points for path in self.pe.hor_path_list:
for i in range(0, (len(points)+1)/2): points = path.points
p = Path() for i in range(0, (len(points)+1)/2):
if i % 2 == 0: p = Path()
p.append(points[i]) if i % 2 == 0:
p.append(points[-i-1]) p.append(points[i])
else: p.append(points[-i-1])
p.append(points[-i-1]) else:
p.append(points[i]) p.append(points[-i-1])
paths.append(p) p.append(points[i])
paths.append(p)
if self.pe.ver_path_list:
for path in self.pe.ver_path_list:
points = path.points
for i in range(0, (len(points)+1)/2):
p = Path()
if i % 2 == 0:
p.append(points[i])
p.append(points[-i-1])
else:
p.append(points[-i-1])
p.append(points[i])
paths.append(p)
self.paths = paths self.paths = paths
list = ["PathAccumulator", "SimpleCutter", "ZigZagCutter", "PolygonCutter"] list = ["PathAccumulator", "SimpleCutter", "ZigZagCutter", "PolygonCutter", "ContourCutter"]
__all__ = list __all__ = list
...@@ -6,3 +6,5 @@ from PathAccumulator import PathAccumulator ...@@ -6,3 +6,5 @@ from PathAccumulator import PathAccumulator
from SimpleCutter import SimpleCutter from SimpleCutter import SimpleCutter
from ZigZagCutter import ZigZagCutter from ZigZagCutter import ZigZagCutter
from PolygonCutter import PolygonCutter from PolygonCutter import PolygonCutter
from ContourCutter import ContourCutter
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