Commit 263a23f0 authored by sumpfralle's avatar sumpfralle

unify min/max properties for geometry objects

calculate all properties during instanciation (not on demand)


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@561 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent d1e456b7
...@@ -39,10 +39,10 @@ class BaseCutter(object): ...@@ -39,10 +39,10 @@ class BaseCutter(object):
self.id = BaseCutter.id self.id = BaseCutter.id
BaseCutter.id += 1 BaseCutter.id += 1
self.radius = radius self.radius = radius
self.radiussq = radius*radius self.radiussq = radius ** 2
self.required_distance = 0 self.required_distance = 0
self.distance_radius = self.radius self.distance_radius = self.radius
self.distance_radiussq = self.distance_radius * self.distance_radius self.distance_radiussq = self.distance_radius ** 2
# self.minx, self.maxx, self.miny and self.maxy are defined as # self.minx, self.maxx, self.miny and self.maxy are defined as
# properties below # properties below
self.shape = {} self.shape = {}
...@@ -98,20 +98,20 @@ class BaseCutter(object): ...@@ -98,20 +98,20 @@ class BaseCutter(object):
def drop(self, triangle): def drop(self, triangle):
# check bounding box collision # check bounding box collision
if self.minx > triangle.maxx(): if self.minx > triangle.maxx:
return None return None
if self.maxx < triangle.minx(): if self.maxx < triangle.minx:
return None return None
if self.miny > triangle.maxy(): if self.miny > triangle.maxy:
return None return None
if self.maxy < triangle.miny(): if self.maxy < triangle.miny:
return None return None
# check bounding circle collision # check bounding circle collision
c = triangle.center() c = triangle.center
if (c.x - self.location.x) ** 2 + (c.y - self.location.y) ** 2 \ if (c.x - self.location.x) ** 2 + (c.y - self.location.y) ** 2 \
> (self.distance_radiussq + 2 * self.distance_radius \ > (self.distance_radiussq + 2 * self.distance_radius \
* triangle.radius() + triangle.radiussq()): * triangle.radius + triangle.radiussq):
return None return None
(cl, d)= self.intersect(BaseCutter.vertical, triangle) (cl, d)= self.intersect(BaseCutter.vertical, triangle)
...@@ -121,22 +121,22 @@ class BaseCutter(object): ...@@ -121,22 +121,22 @@ class BaseCutter(object):
""" TODO: this function is never used - remove it? """ """ TODO: this function is never used - remove it? """
# check bounding box collision # check bounding box collision
if dx == 0: if dx == 0:
if self.miny > triangle.maxy(): if self.miny > triangle.maxy:
return None return None
if self.maxy < triangle.miny(): if self.maxy < triangle.miny:
return None return None
if dy == 0: if dy == 0:
if self.minx > triangle.maxx(): if self.minx > triangle.maxx:
return None return None
if self.maxx < triangle.minx(): if self.maxx < triangle.minx:
return None return None
if triangle.maxz() < self.location.z: if triangle.maxz < self.location.z:
return None return None
# check bounding sphere collision # check bounding sphere collision
c = triangle.center() c = triangle.center
d = (c.x - self.location.x) * dy -(c.y - self.location.y) * dx d = (c.x - self.location.x) * dy -(c.y - self.location.y) * dx
t = self.radius + triangle.radius() t = self.radius + triangle.radius
if abs(d) > t: if abs(d) > t:
return None return None
......
...@@ -175,8 +175,8 @@ class CylindricalCutter(BaseCutter): ...@@ -175,8 +175,8 @@ class CylindricalCutter(BaseCutter):
(cl, ccp, cp, l) = self.intersect_circle_line(direction, edge) (cl, ccp, cp, l) = self.intersect_circle_line(direction, edge)
if cp: if cp:
# check if the contact point is between the endpoints # check if the contact point is between the endpoints
m = cp.sub(edge.p1).dot(edge.dir()) m = cp.sub(edge.p1).dot(edge.dir)
if (m < 0) or (m > edge.len()): if (m < 0) or (m > edge.len):
return (None, INFINITE) return (None, INFINITE)
return (cl, l) return (cl, l)
...@@ -208,8 +208,8 @@ class CylindricalCutter(BaseCutter): ...@@ -208,8 +208,8 @@ class CylindricalCutter(BaseCutter):
(cl, ccp, cp, l) = self.intersect_cylinder_line(direction, edge) (cl, ccp, cp, l) = self.intersect_cylinder_line(direction, edge)
if not ccp: if not ccp:
return (None, INFINITE) return (None, INFINITE)
m = cp.sub(edge.p1).dot(edge.dir()) m = cp.sub(edge.p1).dot(edge.dir)
if (m < 0) or (m > edge.len()): if (m < 0) or (m > edge.len):
return (None, INFINITE) return (None, INFINITE)
if ccp.z < self.center.z: if ccp.z < self.center.z:
return (None, INFINITE) return (None, INFINITE)
......
...@@ -188,7 +188,7 @@ class SphericalCutter(BaseCutter): ...@@ -188,7 +188,7 @@ class SphericalCutter(BaseCutter):
# check if the contact point is between the endpoints # check if the contact point is between the endpoints
d = edge.p2.sub(edge.p1) d = edge.p2.sub(edge.p1)
m = cp.sub(edge.p1).dot(d) m = cp.sub(edge.p1).dot(d)
if (m < 0) or (m > d.normsq()): if (m < 0) or (m > d.normsq):
return (None, INFINITE) return (None, INFINITE)
return (cl, l) return (cl, l)
...@@ -220,8 +220,8 @@ class SphericalCutter(BaseCutter): ...@@ -220,8 +220,8 @@ class SphericalCutter(BaseCutter):
(cl, ccp, cp, l) = self.intersect_cylinder_line(direction, edge) (cl, ccp, cp, l) = self.intersect_cylinder_line(direction, edge)
if not ccp: if not ccp:
return (None, INFINITE) return (None, INFINITE)
m = cp.sub(edge.p1).dot(edge.dir()) m = cp.sub(edge.p1).dot(edge.dir)
if (m < 0) or (m > edge.len()): if (m < 0) or (m > edge.len):
return (None, INFINITE) return (None, INFINITE)
if ccp.z < self.center.z: if ccp.z < self.center.z:
return (None, INFINITE) return (None, INFINITE)
...@@ -299,7 +299,7 @@ class SphericalCutter(BaseCutter): ...@@ -299,7 +299,7 @@ class SphericalCutter(BaseCutter):
def drop_bis(self, triangle): def drop_bis(self, triangle):
""" TODO: this function is never called - remove it? """ """ TODO: this function is never called - remove it? """
n = triangle.normal() n = triangle.normal
if abs(n.dot(self.axis)) < epsilon: if abs(n.dot(self.axis)) < epsilon:
d = triangle.p1.sub(self.center).dot(n) d = triangle.p1.sub(self.center).dot(n)
if abs(d) >= self.radius - epsilon: if abs(d) >= self.radius - epsilon:
......
...@@ -151,7 +151,7 @@ class ToroidalCutter(BaseCutter): ...@@ -151,7 +151,7 @@ class ToroidalCutter(BaseCutter):
min_m = 0 min_m = 0
min_l = INFINITE min_l = INFINITE
min_cl = None min_cl = None
scale = int(edge.len() / self.distance_minorradius * 2) scale = int(edge.len / self.distance_minorradius * 2)
scale = max(3, scale) scale = max(3, scale)
for i in range(scale + 1): for i in range(scale + 1):
m = float(i) / scale m = float(i) / scale
...@@ -208,8 +208,8 @@ class ToroidalCutter(BaseCutter): ...@@ -208,8 +208,8 @@ class ToroidalCutter(BaseCutter):
if ccp and ccp.z < self.center.z: if ccp and ccp.z < self.center.z:
return (None, INFINITE) return (None, INFINITE)
if ccp: if ccp:
m = cp.sub(edge.p1).dot(edge.dir()) m = cp.sub(edge.p1).dot(edge.dir)
if (m < 0) or (m > edge.len()): if (m < 0) or (m > edge.len):
return (None, INFINITE) return (None, INFINITE)
return (cl, l) return (cl, l)
...@@ -254,8 +254,8 @@ class ToroidalCutter(BaseCutter): ...@@ -254,8 +254,8 @@ class ToroidalCutter(BaseCutter):
(cl, ccp, cp, l) = self.intersect_circle_line(direction, edge) (cl, ccp, cp, l) = self.intersect_circle_line(direction, edge)
if cp: if cp:
# check if the contact point is between the endpoints # check if the contact point is between the endpoints
m = cp.sub(edge.p1).dot(edge.dir()) m = cp.sub(edge.p1).dot(edge.dir)
if (m < 0) or (m > edge.len()): if (m < 0) or (m > edge.len):
return (None, INFINITE) return (None, INFINITE)
return (cl, l) return (cl, l)
......
...@@ -51,7 +51,7 @@ class STLExporter: ...@@ -51,7 +51,7 @@ class STLExporter:
for line in self.comment.split(self.linesep): for line in self.comment.split(self.linesep):
yield(";%s" % line) yield(";%s" % line)
for tr in self.model.triangles(): for tr in self.model.triangles():
norm = tr.normal().normalize() norm = tr.normal.normalized()
yield "facet normal %f %f %f" % (norm.x, norm.y, norm.z) yield "facet normal %f %f %f" % (norm.x, norm.y, norm.z)
yield " outer loop" yield " outer loop"
for p in (tr.p1, tr.p2, tr.p3): for p in (tr.p1, tr.p2, tr.p3):
......
This diff is collapsed.
...@@ -121,8 +121,7 @@ def get_rotation_matrix_from_to(v_orig, v_dest): ...@@ -121,8 +121,7 @@ def get_rotation_matrix_from_to(v_orig, v_dest):
# destination vectors. # destination vectors.
rot_axis = Point(v_orig[1] * v_dest[2] - v_orig[2] * v_dest[1], rot_axis = Point(v_orig[1] * v_dest[2] - v_orig[2] * v_dest[1],
v_orig[2] * v_dest[0] - v_orig[0] * v_dest[2], v_orig[2] * v_dest[0] - v_orig[0] * v_dest[2],
v_orig[0] * v_dest[1] - v_orig[1] * v_dest[0]) v_orig[0] * v_dest[1] - v_orig[1] * v_dest[0]).normalized()
rot_axis.normalize()
# get the rotation matrix # get the rotation matrix
# see http://www.fastgraph.com/makegames/3drotation/ # see http://www.fastgraph.com/makegames/3drotation/
c = math.cos(rot_angle) c = math.cos(rot_angle)
......
...@@ -92,26 +92,20 @@ class BaseModel(TransformableContainer): ...@@ -92,26 +92,20 @@ class BaseModel(TransformableContainer):
+ "support the 'export' function.") % str(type(self))) + "support the 'export' function.") % str(type(self)))
def _update_limits(self, item): def _update_limits(self, item):
if callable(item.minx):
minx, miny, minz = item.minx(), item.miny(), item.minz()
maxx, maxy, maxz = item.maxx(), item.maxy(), item.maxz()
else:
minx, miny, minz = item.minx, item.miny, item.minz
maxx, maxy, maxz = item.maxx, item.maxy, item.maxz
if self.minx is None: if self.minx is None:
self.minx = minx self.minx = item.minx
self.miny = miny self.miny = item.miny
self.minz = minz self.minz = item.minz
self.maxx = maxx self.maxx = item.maxx
self.maxy = maxy self.maxy = item.maxy
self.maxz = maxz self.maxz = item.maxz
else: else:
self.minx = min(self.minx, minx) self.minx = min(self.minx, item.minx)
self.miny = min(self.miny, miny) self.miny = min(self.miny, item.miny)
self.minz = min(self.minz, minz) self.minz = min(self.minz, item.minz)
self.maxx = max(self.maxx, maxx) self.maxx = max(self.maxx, item.maxx)
self.maxy = max(self.maxy, maxy) self.maxy = max(self.maxy, item.maxy)
self.maxz = max(self.maxz, maxz) self.maxz = max(self.maxz, item.maxz)
def append(self, item): def append(self, item):
self._update_limits(item) self._update_limits(item)
......
...@@ -35,9 +35,9 @@ class Plane: ...@@ -35,9 +35,9 @@ class Plane:
return "Plane<%s,%s>" % (self.p, self.n) return "Plane<%s,%s>" % (self.p, self.n)
def intersect_point(self, direction, point): def intersect_point(self, direction, point):
if direction.norm() != 1: if direction.norm != 1:
# calculations will go wrong, if the direction is not a unit vector # calculations will go wrong, if the direction is not a unit vector
direction = Point(direction.x, direction.y, direction.z).normalize() direction = Point(direction.x, direction.y, direction.z).normalized()
denom = self.n.dot(direction) denom = self.n.dot(direction)
if denom == 0: if denom == 0:
return (None, INFINITE) return (None, INFINITE)
......
...@@ -36,8 +36,7 @@ class Point: ...@@ -36,8 +36,7 @@ class Point:
self.x = float(x) self.x = float(x)
self.y = float(y) self.y = float(y)
self.z = float(z) self.z = float(z)
self._norm = None self.reset_cache()
self._normsq = None
def __repr__(self): def __repr__(self):
return "Point%d<%g,%g,%g>" % (self.id, self.x, self.y, self.z) return "Point%d<%g,%g,%g>" % (self.id, self.x, self.y, self.z)
...@@ -74,13 +73,14 @@ class Point: ...@@ -74,13 +73,14 @@ class Point:
self.reset_cache() self.reset_cache()
def reset_cache(self): def reset_cache(self):
self._norm = None self.normsq = self.dot(self)
self._normsq = None self.norm = math.sqrt(self.normsq)
def mul(self, c): def mul(self, c):
return Point(self.x * c, self.y * c, self.z * c) return Point(self.x * c, self.y * c, self.z * c)
def div(self, c): def div(self, c):
c = float(c)
return Point(self.x / c, self.y / c, self.z / c) return Point(self.x / c, self.y / c, self.z / c)
def add(self, p): def add(self, p):
...@@ -96,23 +96,10 @@ class Point: ...@@ -96,23 +96,10 @@ class Point:
return Point(self.y * p.z - p.y * self.z, p.x * self.z - self.x * p.z, return Point(self.y * p.z - p.y * self.z, p.x * self.z - self.x * p.z,
self.x * p.y - p.x * self.y) self.x * p.y - p.x * self.y)
def normsq(self): def normalized(self):
if self._normsq is None: n = self.norm
self._normsq = self.dot(self) if n == 0:
return self._normsq return None
else:
def norm(self): return Point(self.x / n, self.y / n, self.z / n)
if self._norm is None:
self._norm = math.sqrt(self.normsq())
return self._norm
def normalize(self):
n = self.norm()
if n != 0:
self.x /= n
self.y /= n
self.z /= n
self._norm = 1.0
self._normsq = 1.0
return self
This diff is collapsed.
...@@ -61,8 +61,7 @@ def intersect_lines(xl, zl, nxl, nzl, xm, zm, nxm, nzm): ...@@ -61,8 +61,7 @@ def intersect_lines(xl, zl, nxl, nzl, xm, zm, nxm, nzm):
def intersect_cylinder_point(center, axis, radius, radiussq, direction, point): def intersect_cylinder_point(center, axis, radius, radiussq, direction, point):
# take a plane along direction and axis # take a plane along direction and axis
n = direction.cross(axis) n = direction.cross(axis).normalized()
n.normalize()
# distance of the point to this plane # distance of the point to this plane
d = n.dot(point) - n.dot(center) d = n.dot(point) - n.dot(center)
if abs(d) > radius: if abs(d) > radius:
...@@ -77,14 +76,14 @@ def intersect_cylinder_point(center, axis, radius, radiussq, direction, point): ...@@ -77,14 +76,14 @@ def intersect_cylinder_point(center, axis, radius, radiussq, direction, point):
return (ccp, point, -l) return (ccp, point, -l)
def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge): def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge):
d = edge.dir() d = edge.dir
# take a plane throught the line and along the cylinder axis (1) # take a plane throught the line and along the cylinder axis (1)
n = d.cross(axis) n = d.cross(axis)
if n.normsq() == 0: if n.norm == 0:
# no contact point, but should check here if cylinder *always* # no contact point, but should check here if cylinder *always*
# intersects line... # intersects line...
return (None, None, INFINITE) return (None, None, INFINITE)
n.normalize() n = n.normalized()
# the contact line between the cylinder and this plane (1) # the contact line between the cylinder and this plane (1)
# is where the surface normal is perpendicular to the plane # is where the surface normal is perpendicular to the plane
# so line := ccl + \lambda * axis # so line := ccl + \lambda * axis
...@@ -94,11 +93,11 @@ def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge): ...@@ -94,11 +93,11 @@ def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge):
ccl = center.add(n.mul(radius)) ccl = center.add(n.mul(radius))
# now extrude the contact line along the direction, this is a plane (2) # now extrude the contact line along the direction, this is a plane (2)
n2 = direction.cross(axis) n2 = direction.cross(axis)
if n2.normsq() == 0: if n2.norm == 0:
# no contact point, but should check here if cylinder *always* # no contact point, but should check here if cylinder *always*
# intersects line... # intersects line...
return (None, None, INFINITE) return (None, None, INFINITE)
n2.normalize() n2 = n2.normalized()
plane1 = Plane(ccl, n2) plane1 = Plane(ccl, n2)
# intersect this plane with the line, this gives us the contact point # intersect this plane with the line, this gives us the contact point
(cp, l) = plane1.intersect_point(d, edge.p1) (cp, l) = plane1.intersect_point(d, edge.p1)
...@@ -115,20 +114,20 @@ def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge): ...@@ -115,20 +114,20 @@ def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge):
def intersect_circle_plane(center, radius, direction, triangle): def intersect_circle_plane(center, radius, direction, triangle):
# let n be the normal to the plane # let n be the normal to the plane
n = triangle.normal() n = triangle.normal
if n.dot(direction) == 0: if n.dot(direction) == 0:
return (None, None, INFINITE) return (None, None, INFINITE)
# project onto z=0 # project onto z=0
n2 = Point(n.x, n.y, 0) n2 = Point(n.x, n.y, 0)
if n2.normsq() == 0: if n2.norm == 0:
(cp, d) = triangle.plane().intersect_point(direction, center) (cp, d) = triangle.plane.intersect_point(direction, center)
ccp = cp.sub(direction.mul(d)) ccp = cp.sub(direction.mul(d))
return (ccp, cp, d) return (ccp, cp, d)
n2.normalize() n2 = n2.normalized()
# the cutter contact point is on the circle, where the surface normal is n # the cutter contact point is on the circle, where the surface normal is n
ccp = center.add(n2.mul(-radius)) ccp = center.add(n2.mul(-radius))
# intersect the plane with a line through the contact point # intersect the plane with a line through the contact point
(cp, d) = triangle.plane().intersect_point(direction, ccp) (cp, d) = triangle.plane.intersect_point(direction, ccp)
return (ccp, cp, d) return (ccp, cp, d)
def intersect_circle_point(center, axis, radius, radiussq, direction, point): def intersect_circle_point(center, axis, radius, radiussq, direction, point):
...@@ -137,13 +136,13 @@ def intersect_circle_point(center, axis, radius, radiussq, direction, point): ...@@ -137,13 +136,13 @@ def intersect_circle_point(center, axis, radius, radiussq, direction, point):
# intersect with line gives ccp # intersect with line gives ccp
(ccp, l) = plane.intersect_point(direction, point) (ccp, l) = plane.intersect_point(direction, point)
# check if inside circle # check if inside circle
if ccp and (center.sub(ccp).normsq() <= radiussq): if ccp and (center.sub(ccp).normsq <= radiussq):
return (ccp, point, -l) return (ccp, point, -l)
return (None, None, INFINITE) return (None, None, INFINITE)
def intersect_circle_line(center, axis, radius, radiussq, direction, edge): def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
# make a plane by sliding the line along the direction (1) # make a plane by sliding the line along the direction (1)
d = edge.dir() d = edge.dir
if d.dot(axis) == 0: if d.dot(axis) == 0:
if direction.dot(axis) == 0: if direction.dot(axis) == 0:
return (None, None, INFINITE) return (None, None, INFINITE)
...@@ -151,7 +150,7 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge): ...@@ -151,7 +150,7 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
(p1, l) = plane.intersect_point(direction, edge.p1) (p1, l) = plane.intersect_point(direction, edge.p1)
(p2, l) = plane.intersect_point(direction, edge.p2) (p2, l) = plane.intersect_point(direction, edge.p2)
pc = Line(p1, p2).closest_point(center) pc = Line(p1, p2).closest_point(center)
d_sq = pc.sub(center).normsq() d_sq = pc.sub(center).normsq
if d_sq > radiussq: if d_sq > radiussq:
return (None, None, INFINITE) return (None, None, INFINITE)
a = sqrt(radiussq - d_sq) a = sqrt(radiussq - d_sq)
...@@ -170,11 +169,11 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge): ...@@ -170,11 +169,11 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
cp = pc.sub(direction.mul(l)) cp = pc.sub(direction.mul(l))
return (ccp, cp, -l) return (ccp, cp, -l)
n = d.cross(direction) n = d.cross(direction)
if n.normsq() == 0: if n.norm == 0:
# no contact point, but should check here if circle *always* intersects # no contact point, but should check here if circle *always* intersects
# line... # line...
return (None, None, INFINITE) return (None, None, INFINITE)
n.normalize() n = n.normalized()
# take a plane through the base # take a plane through the base
plane = Plane(center, axis) plane = Plane(center, axis)
# intersect base with line # intersect base with line
...@@ -183,14 +182,14 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge): ...@@ -183,14 +182,14 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
return (None, None, INFINITE) return (None, None, INFINITE)
# intersection of 2 planes: lp + \lambda v # intersection of 2 planes: lp + \lambda v
v = axis.cross(n) v = axis.cross(n)
if v.normsq() == 0: if v.norm == 0:
return (None, None, INFINITE) return (None, None, INFINITE)
v.normalize() v = v.normalized()
# take plane through intersection line and parallel to axis # take plane through intersection line and parallel to axis
n2 = v.cross(axis) n2 = v.cross(axis)
if n2.normsq() == 0: if n2.norm == 0:
return (None, None, INFINITE) return (None, None, INFINITE)
n2.normalize() n2 = n2.normalized()
# distance from center to this plane # distance from center to this plane
dist = n2.dot(center) - n2.dot(lp) dist = n2.dot(center) - n2.dot(lp)
distsq = dist * dist distsq = dist * dist
...@@ -207,7 +206,7 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge): ...@@ -207,7 +206,7 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
def intersect_sphere_plane(center, radius, direction, triangle): def intersect_sphere_plane(center, radius, direction, triangle):
# let n be the normal to the plane # let n be the normal to the plane
n = triangle.normal() n = triangle.normal
if n.dot(direction) == 0: if n.dot(direction) == 0:
return (None, None, INFINITE) return (None, None, INFINITE)
# the cutter contact point is on the sphere, where the surface normal is n # the cutter contact point is on the sphere, where the surface normal is n
...@@ -216,7 +215,7 @@ def intersect_sphere_plane(center, radius, direction, triangle): ...@@ -216,7 +215,7 @@ def intersect_sphere_plane(center, radius, direction, triangle):
else: else:
ccp = center.add(n.mul(radius)) ccp = center.add(n.mul(radius))
# intersect the plane with a line through the contact point # intersect the plane with a line through the contact point
(cp, d) = triangle.plane().intersect_point(direction, ccp) (cp, d) = triangle.plane.intersect_point(direction, ccp)
return (ccp, cp, d) return (ccp, cp, d)
def intersect_sphere_point(center, radius, radiussq, direction, point): def intersect_sphere_point(center, radius, radiussq, direction, point):
...@@ -226,9 +225,9 @@ def intersect_sphere_point(center, radius, radiussq, direction, point): ...@@ -226,9 +225,9 @@ def intersect_sphere_point(center, radius, radiussq, direction, point):
# (2) (x-x_0)^2 = R^2 # (2) (x-x_0)^2 = R^2
# (1) in (2) gives a quadratic in \lambda # (1) in (2) gives a quadratic in \lambda
p0_x0 = center.sub(point) p0_x0 = center.sub(point)
a = direction.normsq() a = direction.normsq
b = 2 * p0_x0.dot(direction) b = 2 * p0_x0.dot(direction)
c = p0_x0.normsq() - radiussq c = p0_x0.normsq - radiussq
d = b * b - 4 * a * c d = b * b - 4 * a * c
if d < 0: if d < 0:
return (None, None, INFINITE) return (None, None, INFINITE)
...@@ -242,13 +241,13 @@ def intersect_sphere_point(center, radius, radiussq, direction, point): ...@@ -242,13 +241,13 @@ def intersect_sphere_point(center, radius, radiussq, direction, point):
def intersect_sphere_line(center, radius, radiussq, direction, edge): def intersect_sphere_line(center, radius, radiussq, direction, edge):
# make a plane by sliding the line along the direction (1) # make a plane by sliding the line along the direction (1)
d = edge.dir() d = edge.dir
n = d.cross(direction) n = d.cross(direction)
if n.normsq() == 0: if n.norm == 0:
# no contact point, but should check here if sphere *always* intersects # no contact point, but should check here if sphere *always* intersects
# line... # line...
return (None, None, INFINITE) return (None, None, INFINITE)
n.normalize() n = n.normalized()
# calculate the distance from the sphere center to the plane # calculate the distance from the sphere center to the plane
dist = - center.dot(n) - edge.p1.dot(n) dist = - center.dot(n) - edge.p1.dot(n)
...@@ -260,8 +259,7 @@ def intersect_sphere_line(center, radius, radiussq, direction, edge): ...@@ -260,8 +259,7 @@ def intersect_sphere_line(center, radius, radiussq, direction, edge):
# find the center on the circle closest to this plane # find the center on the circle closest to this plane
# which means the other component is perpendicular to this plane (2) # which means the other component is perpendicular to this plane (2)
n2 = n.cross(d) n2 = n.cross(d).normalized()
n2.normalize()
# the contact point is on a big circle through the sphere... # the contact point is on a big circle through the sphere...
dist2 = sqrt(radiussq - dist * dist) dist2 = sqrt(radiussq - dist * dist)
...@@ -277,7 +275,7 @@ def intersect_sphere_line(center, radius, radiussq, direction, edge): ...@@ -277,7 +275,7 @@ def intersect_sphere_line(center, radius, radiussq, direction, edge):
def intersect_torus_plane(center, axis, majorradius, minorradius, direction, def intersect_torus_plane(center, axis, majorradius, minorradius, direction,
triangle): triangle):
# take normal to the plane # take normal to the plane
n = triangle.normal() n = triangle.normal
if n.dot(direction) == 0: if n.dot(direction) == 0:
return (None, None, INFINITE) return (None, None, INFINITE)
if n.dot(axis) == 1: if n.dot(axis) == 1:
...@@ -286,14 +284,13 @@ def intersect_torus_plane(center, axis, majorradius, minorradius, direction, ...@@ -286,14 +284,13 @@ def intersect_torus_plane(center, axis, majorradius, minorradius, direction,
b = n.mul(-1) b = n.mul(-1)
z = axis z = axis
a = b.sub(z.mul(z.dot(b))) a = b.sub(z.mul(z.dot(b)))
a_sq = a.normsq() a_sq = a.normsq
if a_sq <= 0: if a_sq <= 0:
return (None, None, INFINITE) return (None, None, INFINITE)
a = a.div(sqrt(a_sq)) a = a.div(sqrt(a_sq))
ccp = center.add(a.mul(majorradius)).add(b.mul(minorradius)) ccp = center.add(a.mul(majorradius)).add(b.mul(minorradius))
# find intersection with plane # find intersection with plane
plane = triangle.plane() (cp, l) = triangle.plane.intersect_point(direction, ccp)
(cp, l) = plane.intersect_point(direction, ccp)
return (ccp, cp, l) return (ccp, cp, l)
def intersect_torus_point(center, axis, majorradius, minorradius, majorradiussq, def intersect_torus_point(center, axis, majorradius, minorradius, majorradiussq,
......
...@@ -91,7 +91,7 @@ class Camera: ...@@ -91,7 +91,7 @@ class Camera:
dimz = s.get("maxz") - s.get("minz") dimz = s.get("maxz") - s.get("minz")
max_dim = max(max(dimx, dimy), dimz) max_dim = max(max(dimx, dimy), dimz)
distv = Point(v["distance"][0], v["distance"][1], distv = Point(v["distance"][0], v["distance"][1],
v["distance"][2]).normalize() v["distance"][2]).normalized()
# The multiplier "2.0" is based on: sqrt(2) + margin -- the squre root # The multiplier "2.0" is based on: sqrt(2) + margin -- the squre root
# makes sure, that the the diagonal fits. # makes sure, that the the diagonal fits.
distv = distv.mul((max_dim * 2.0) / math.sin(v["fovy"]/2)) distv = distv.mul((max_dim * 2.0) / math.sin(v["fovy"]/2))
...@@ -216,8 +216,8 @@ class Camera: ...@@ -216,8 +216,8 @@ class Camera:
# Calculate the proportion of each model axis according to the x axis of # Calculate the proportion of each model axis according to the x axis of
# the screen. # the screen.
distv = self.view["distance"] distv = self.view["distance"]
distv = Point(distv[0], distv[1], distv[2]).normalize() distv = Point(distv[0], distv[1], distv[2]).normalized()
factors_x = distv.cross(Point(v_up[0], v_up[1], v_up[2])).normalize() factors_x = distv.cross(Point(v_up[0], v_up[1], v_up[2])).normalized()
factors_x = (factors_x.x, factors_x.y, factors_x.z) factors_x = (factors_x.x, factors_x.y, factors_x.z)
return (factors_x, factors_y) return (factors_x, factors_y)
......
...@@ -79,8 +79,8 @@ class DXFParser: ...@@ -79,8 +79,8 @@ class DXFParser:
current_group = [] current_group = []
groups.append(current_group) groups.append(current_group)
def get_distance_between_groups(group1, group2): def get_distance_between_groups(group1, group2):
forward = group1[-1].p2.sub(group2[0].p1).norm() forward = group1[-1].p2.sub(group2[0].p1).norm
backward = group2[-1].p2.sub(group1[0].p1).norm() backward = group2[-1].p2.sub(group1[0].p1).norm
return min(forward, backward) return min(forward, backward)
remaining_groups = groups[:] remaining_groups = groups[:]
ordered_groups = [] ordered_groups = []
......
...@@ -232,8 +232,7 @@ def ImportModel(filename, use_kdtree=True, program_locations=None): ...@@ -232,8 +232,7 @@ def ImportModel(filename, use_kdtree=True, program_locations=None):
m = endfacet.match(line) m = endfacet.match(line)
if m: if m:
if not n: if not n:
n = p3.sub(p1).cross(p2.sub(p1)) n = p3.sub(p1).cross(p2.sub(p1)).normalized()
n.normalize()
# make sure the points are in ClockWise order # make sure the points are in ClockWise order
dotcross = n.dot(p3.sub(p1).cross(p2.sub(p1))) dotcross = n.dot(p3.sub(p1).cross(p2.sub(p1)))
......
...@@ -106,13 +106,13 @@ class ZBuffer: ...@@ -106,13 +106,13 @@ class ZBuffer:
self.add_triangle(t) self.add_triangle(t)
def add_triangle(self, t): def add_triangle(self, t):
minx = int((t.minx() - self.minx) / (self.maxx - self.minx) \ minx = int((t.minx - self.minx) / (self.maxx - self.minx) \
* self.xres) - 1 * self.xres) - 1
maxx = int((t.maxx() - self.minx) / (self.maxx - self.minx) \ maxx = int((t.maxx - self.minx) / (self.maxx - self.minx) \
* self.xres) + 1 * self.xres) + 1
miny = int((t.miny() - self.miny) / (self.maxy - self.miny) \ miny = int((t.miny - self.miny) / (self.maxy - self.miny) \
* self.yres) - 1 * self.yres) - 1
maxy = int((t.maxy() - self.miny) / (self.maxy - self.miny) \ maxy = int((t.maxy - self.miny) / (self.maxy - self.miny) \
* self.yres) + 2 * self.yres) + 2
if minx < 0: if minx < 0:
minx = 0 minx = 0
......
...@@ -31,10 +31,8 @@ log = pycam.Utils.log.get_logger() ...@@ -31,10 +31,8 @@ log = pycam.Utils.log.get_logger()
def _check_colinearity(p1, p2, p3): def _check_colinearity(p1, p2, p3):
v1 = p2.sub(p1) v1 = p2.sub(p1).normalized()
v2 = p3.sub(p2) v2 = p3.sub(p2).normalized()
v1.normalize()
v2.normalize()
# compare if the normalized distances between p1-p2 and p2-p3 are equal # compare if the normalized distances between p1-p2 and p2-p3 are equal
return v1 == v2 return v1 == v2
...@@ -120,7 +118,7 @@ class ToolPath: ...@@ -120,7 +118,7 @@ class ToolPath:
result["time"] = 0 result["time"] = 0
result["position"] = start_position result["position"] = start_position
def move(new_pos): def move(new_pos):
result["time"] += new_pos.sub(result["position"]).norm() / feedrate result["time"] += new_pos.sub(result["position"]).norm / feedrate
result["position"] = new_pos result["position"] = new_pos
# move to safey height at the starting position # move to safey height at the starting position
safety_height = settings.get_process_settings()["safety_height"] safety_height = settings.get_process_settings()["safety_height"]
......
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