Commit 9d6e928b authored by sumpfralle's avatar sumpfralle

r672@erker: lars | 2010-02-15 14:57:19 +0100

 implement the dropcutter code using the ODE collision detection


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@130 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 6a0e1176
...@@ -3,131 +3,177 @@ from pycam.Geometry import * ...@@ -3,131 +3,177 @@ from pycam.Geometry import *
from pycam.Geometry.utils import * from pycam.Geometry.utils import *
from pycam.Geometry.intersection import intersect_lines from pycam.Geometry.intersection import intersect_lines
class Dimension:
def __init__(self, start, end):
self.start = float(start)
self.end = float(end)
self._min = float(min(start, end))
self._max = float(max(start, end))
self.downward = start > end
self.value = 0.0
def check_bounds(self, value=None):
if value is None:
value = self.value
return (value >= self._min) and (value <= self._max)
def shift(self, distance):
if self.downward:
self.value -= distance
else:
self.value += distance
def set(self, value):
self.value = float(value)
def get(self):
return self.value
class DropCutter: class DropCutter:
def __init__(self, cutter, model, PathProcessor=None): def __init__(self, cutter, model, PathProcessor=None, physics=None):
self.cutter = cutter self.cutter = cutter
self.model = model self.model = model
self.processor = PathProcessor self.processor = PathProcessor
self.physics = physics
def GenerateToolPath(self, minx, maxx, miny, maxy, z0, z1, dx, dy, direction): def GenerateToolPath(self, minx, maxx, miny, maxy, z0, z1, d0, d1, direction):
if self.processor: if self.processor:
pa = self.processor pa = self.processor
else: else:
pa = PathAccumulator() pa = PathAccumulator()
if (direction==0): dim_x = Dimension(minx, maxx)
pa.new_direction(0) dim_y = Dimension(miny, maxy)
y = miny dim_height = Dimension(z1, z0)
while y<=maxy: dims = [None, None, None]
x = minx # map the scales according to the order of direction
if direction == 0:
x, y = 0, 1
dim_attrs = ["x", "y"]
else:
y, x = 0, 1
dim_attrs = ["y", "x"]
# order of the "dims" array: first dimension, second dimension
dims[x] = dim_x
dims[y] = dim_y
dim_height.set(dim_height.start)
pa.new_direction(direction)
dims[1].set(dims[1].start)
while dims[1].check_bounds():
dims[0].set(dims[0].start)
pa.new_scanline() pa.new_scanline()
t_last = None t_last = None
cl_last = None while dims[0].check_bounds():
while x<=maxx: p = Point(dims[x].get(), dims[y].get(), dim_height.get())
p = Point(x,y,z1)
z_max = -INFINITE
cl_max = None
t_max = None
self.cutter.moveto(p) self.cutter.moveto(p)
triangles = self.model.triangles(p.x-self.cutter.radius,p.y-self.cutter.radius,z0,p.x+self.cutter.radius,p.y+self.cutter.radius,+INFINITE)
for t in triangles: low, high = z0, z1
if t.normal().z < 0: continue; trip_start = 20
cl = self.cutter.drop(t) safe_z = None
if cl and (cl.z > z_max or cl_max is None): # check if the full step-down would be ok
z_max = cl.z self.physics.set_drill_position((dims[x].get(), dims[y].get(), z0))
cl_max = cl if self.physics.check_collision():
t_max = t # there is an object between z1 and z0 - we need more loops
if not cl_max or cl_max.z<z0: trips = trip_start
cl_max = Point(x,y,z0)
if cl_last and ((t_max and not t_last) or (t_last and not t_max)):
if cl_last.z < z_max:
pa.append(Point(cl_last.x,cl_last.y,cl_max.z))
else: else:
pa.append(Point(cl_max.x,cl_max.y,cl_last.z)) # no need for further collision detection - we can go down the whole range z1..z0
elif (t_max and t_last and cl_last and cl_max ) and (t_max != t_last): trips = 0
nxl = -t_last.normal().x safe_z = z0
nzl = t_last.normal().z while trips > 0:
nxm = -t_max.normal().x current_z = (low + high)/2.0
nzm = t_max.normal().z self.physics.set_drill_position((dims[x].get(), dims[y].get(), current_z))
xl = cl_last.x if self.physics.check_collision():
zl = cl_last.z low = current_z
xm = cl_max.x
zm = cl_max.z
(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-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: else:
pa.append(Point(X,Y,Z)) high = current_z
pa.append(cl_max) safe_z = current_z
trips -= 1
cl_last = cl_max #current_z -= dz
t_last = t_max if safe_z is None:
x += dx # no safe position was found - let's check the upper bound
self.physics.set_drill_position((dims[x].get(), dims[y].get(), z1))
pa.end_scanline() if self.physics.check_collision():
y += dy # the object fills the whole range of z0..z1 - we should issue a warning
pa.append(Point(dims[x].get(), dims[y].get(), INFINITE))
else:
pa.append(Point(dims[x].get(), dims[y].get(), z1))
else:
pa.append(Point(dims[x].get(), dims[y].get(), safe_z))
pa.end_direction() """
if direction==1: height_max = -INFINITE
pa.new_direction(1) cut_max = None
x = minx triangle_max = None
while x<=maxx: cut_last = None
y = miny
pa.new_scanline()
t_last = None
cl_last = None
while y<=maxy:
p = Point(x,y,z1)
z_max = -INFINITE
cl_max = None
t_max = None
self.cutter.moveto(p) self.cutter.moveto(p)
triangles = self.model.triangles(p.x-self.cutter.radius,p.y-self.cutter.radius,z0,p.x+self.cutter.radius,p.y+self.cutter.radius,+INFINITE) box_x_min = p.x - self.cutter.radius
box_x_max = p.x + self.cutter.radius
box_y_min = p.y - self.cutter.radius
box_y_max = p.y + self.cutter.radius
box_z_min = dim_height.end
box_z_max = +INFINITE
triangles = self.model.triangles(box_x_min, box_y_min, box_z_min, box_x_max, box_y_max, box_z_max)
for t in triangles: for t in triangles:
if t.normal().z < 0: continue; if t.normal().z < 0: continue;
cl = self.cutter.drop(t) cut = self.cutter.drop(t)
if cl and (cl.z > z_max or cl_max is None): if cut and (cut.z > height_max or height_max is None):
z_max = cl.z height_max = cut.z
cl_max = cl cut_max = cut
t_max = t triangle_max = t
if not cl_max or cl_max.z<z0: if not cut_max or not dim_height.check_bounds(cut_max.z):
cl_max = Point(x,y,z0) cut_max = Point(dims[x].get(), dims[y].get(), dim_height.end)
if cl_last and ((t_max and not t_last) or (t_last and not t_max)): if cut_last and ((triangle_max and not triangle_last) or (triangle_last and not triangle_max)):
if cl_last.z < z_max: if dim_height.check_bounds(cut_last.z):
pa.append(Point(cl_last.x,cl_last.y,cl_max.z)) pa.append(Point(cut_last.x, cut_last.y, cut_max.z))
else: else:
pa.append(Point(cl_max.x,cl_max.y,cl_last.z)) pa.append(Point(cut_max.x, cut_max.y, cut_last.z))
elif (t_max and t_last and cl_last and cl_max ) and (t_max != t_last): elif (triangle_max and triangle_last and cut_last and cut_max) and (triangle_max != triangle_last):
nyl = -t_last.normal().y nl = range(3)
nzl = t_last.normal().z nl[0] = -getattr(triangle_last.normal(), dim_attrs[0])
nym = -t_max.normal().y nl[2] = triangle_last.normal().z
nzm = t_max.normal().z nm = range(3)
yl = cl_last.y nm[0] = -getattr(triangle_max.normal(), dim_attrs[0])
zl = cl_last.z nm[2] = triangle_max.normal().z
ym = cl_max.y last = range(3)
zm = cl_max.z last[0] = getattr(cut_last, dim_attrs[0])
(Y,Z) = intersect_lines(yl, zl, nyl, nzl, ym, zm, nym, nzm) last[2] = cut_last.z
if Y and yl < Y and Y < ym and (Z > zl or Z > zm): mx = range(3)
X = cl_last.x mx[0] = getattr(cut_max, dim_attrs[0])
if Z<z0-10 or Z>z1+10: mx[2] = cut_max.z
print "^", "yl=",yl,", zl=",zl,"nyl=",nyl,", nzl=",nzl,", Y=", Y, ", Z=",Z,", ym=",ym,",zm=",zm, ", nym=",nym,",nzm=",nzm c = range(3)
(c[0], c[2]) = intersect_lines(last[0], last[2], nl[0], nl[2], mx[0], mx[2], nm[0], nm[2])
if c[0] and last[0] < c[0] and c[0] < mx[0] and (c[2] > last[2] or c[2] > mx[2]):
c[1] = getattr(cut_last, dim_attrs[1])
if c[2]<dims[2].min-10 or c[2]>dims[2].max+10:
print "^", "%sl=" % dim_attrs[0], last[0], \
", %sl=" % dim_attrs[2], last[2], \
", n%sl=" % dim_attrs[0], nl[0], \
", n%sl=" %dim_attrs[2], nl[2], \
", %s=" % dim_attrs[0].upper(), c[0], \
", %s=" % dim_attrs[2].upper(), c[2], \
", %sm=" % dim_attrs[0], mx[0], \
", %sm=" % dim_attrs[2], mx[2], \
", n%sm=" % dim_attrs[0], nm[0], \
", n%sm=" % dim_attrs[2], nm[2]
else: else:
pa.append(Point(X,Y,Z)) pa.append(Point(c[x], c[y], c[2]))
pa.append(cut_max)
pa.append(cl_max) cut_last = cut_max
triangle_last = triangle_max
"""
cl_last = cl_max dims[0].shift(d0)
t_last = t_max
y += dy
pa.end_scanline() pa.end_scanline()
x += dx dims[1].shift(d1)
pa.end_direction() pa.end_direction()
pa.finish() pa.finish()
return pa.paths return pa.paths
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