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:
MONOTONE=2
def __init__(self, policy=MONOTONE):
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):
if (self.current_dir==0):
......@@ -302,10 +307,11 @@ class PolygonExtractor:
self.prev_line = self.curr_line
def merge_path_lists(self):
self.merge_path_list = []
pass
dx = 1
dy = 1
if self.hor_path_list:
self.merge_path_list = self.hor_path_list
else:
self.merge_path_list = self.ver_path_list
return
# find matching path to merge with */
for s0 in self.hor_path_list:
......
......@@ -239,6 +239,8 @@ class SimpleGui(Frame):
self.option = ZigZagCutter()
elif self.PathProcessorName.get() == "PolygonCutter":
self.option = PolygonCutter()
elif self.PathProcessorName.get() == "ContourCutter":
self.option = ContourCutter()
else:
self.option = None
self.pathgenerator = PushCutter(self.cutter, self.model, self.option);
......
......@@ -56,7 +56,7 @@ class DropCutter:
(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):
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
else:
pa.append(Point(X,Y,Z))
......@@ -111,7 +111,7 @@ class DropCutter:
(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):
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
else:
pa.append(Point(X,Y,Z))
......
......@@ -19,107 +19,127 @@ class PushCutter:
self.pa = pathextractor
def GenerateToolPath(self, minx, maxx, miny, maxy, minz, maxz, dx, dy, dz):
if dx==0:
forward = Point(1,0,0)
backward = Point(-1,0,0)
elif dy == 0:
forward = Point(0,1,0)
backward = Point(0,-1,0)
if dx != 0:
self.pa.dx = dx
else:
self.pa.dx = dy
if dy != 0:
self.pa.dy = dy
else:
self.pa.dy = dx
z = maxz
c = self.cutter
model = self.model
paths = []
while z >= minz:
self.pa.new_direction(0)
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(next)
i += 1
if dy > 0:
self.pa.new_direction(0)
self.GenerateToolPathSlice(minx, maxx, miny, maxy, z, 0, dy)
self.pa.end_direction()
if dx > 0:
self.pa.new_direction(1)
self.GenerateToolPathSlice(minx, maxx, miny, maxy, z, dx, 0)
self.pa.end_direction()
self.pa.finish()
# find next hit cutter location that is below z-level
while i < len(hits):
prev = hits[i].cl
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
if self.pa.paths:
paths += self.pa.paths
z -= dz
i += 1
return paths
if zmax <= z+epsilon:
break
def GenerateToolPathSlice(self, minx, maxx, miny, maxy, z, dx, dy):
c = self.cutter
model = self.model
if dx == 0:
x = maxx
if dy == 0:
y = maxy
if dx==0:
forward = Point(1,0,0)
backward = Point(-1,0,0)
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(next)
i += 1
if dx != 0:
x += dx
else:
x = minx
if dy != 0:
y += dy
else:
y = miny
# find next hit cutter location that is below z-level
while i < len(hits):
prev = hits[i].cl
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
self.pa.end_scanline()
i += 1
self.pa.end_direction()
self.pa.finish()
if zmax <= z+epsilon:
break
paths += self.pa.paths
z -= dz
if dx == 0:
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:
def finish(self):
self.pe.finish()
paths = []
for path in self.pe.hor_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)
if self.pe.hor_path_list:
for path in self.pe.hor_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)
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
list = ["PathAccumulator", "SimpleCutter", "ZigZagCutter", "PolygonCutter"]
list = ["PathAccumulator", "SimpleCutter", "ZigZagCutter", "PolygonCutter", "ContourCutter"]
__all__ = list
......@@ -6,3 +6,5 @@ from PathAccumulator import PathAccumulator
from SimpleCutter import SimpleCutter
from ZigZagCutter import ZigZagCutter
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