Commit c482213d authored by sumpfralle's avatar sumpfralle

added "factor" result to "get_intersection" between lines

allow (optional) line intersection outside the length of both lines


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@559 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 6813871a
...@@ -158,10 +158,12 @@ class Line(TransformableContainer): ...@@ -158,10 +158,12 @@ class Line(TransformableContainer):
def get_points(self): def get_points(self):
return (self.p1, self.p2) return (self.p1, self.p2)
def get_intersection(self, line): def get_intersection(self, line, infinite_lines=False):
""" Get the point of intersection between two lines. Intersections """ Get the point of intersection between two lines. Intersections
outside the length of these lines are ignored. outside the length of these lines are ignored.
Returns None if no valid intersection was found. Returns (None, None) if no valid intersection was found.
Otherwise the result is (CollisionPoint, distance). Distance is between
0 and 1.
""" """
x1, x2, x3, x4 = self.p1, self.p2, line.p1, line.p2 x1, x2, x3, x4 = self.p1, self.p2, line.p1, line.p2
a = x2.sub(x1) a = x2.sub(x1)
...@@ -174,32 +176,34 @@ class Line(TransformableContainer): ...@@ -174,32 +176,34 @@ class Line(TransformableContainer):
# lines are parallel # lines are parallel
# check if they are _one_ line # check if they are _one_ line
if a.cross(c).normsq() != 0: if a.cross(c).normsq() != 0:
# the lines are parallel with a disctance # the lines are parallel with a distance
return None return None, None
# the lines are on one straight # the lines are on one straight
if self.is_point_in_line(x3): if self.is_point_in_line(x3):
return x3 return x3, a.len() / c.len()
elif self.is_point_in_line(x4): elif self.is_point_in_line(x4):
return x4 return x4, a.len() / line.p2.sub(self.p1).len()
elif line.is_point_in_line(x1): elif line.is_point_in_line(x1):
return x1 return x1, 0
elif line.is_point_in_line(x2): elif line.is_point_in_line(x2):
return x2 return x2, 1
else: else:
return None return None, None
if 0 <= factor <= 1: if infinite_lines or (0 <= factor <= 1):
intersection = x1.add(a.mul(factor)) intersection = x1.add(a.mul(factor))
# check if the intersection is between x3 and x4 # check if the intersection is between x3 and x4
if (min(x3.x, x4.x) <= intersection.x <= max(x3.x, x4.x)) \ if infinite_lines:
return intersection, factor
elif (min(x3.x, x4.x) <= intersection.x <= max(x3.x, x4.x)) \
and (min(x3.y, x4.y) <= intersection.y <= max(x3.y, x4.y)) \ and (min(x3.y, x4.y) <= intersection.y <= max(x3.y, x4.y)) \
and (min(x3.z, x4.z) <= intersection.z <= max(x3.z, x4.z)): and (min(x3.z, x4.z) <= intersection.z <= max(x3.z, x4.z)):
return intersection return intersection, factor
else: else:
# intersection outside of the length of line(x3, x4) # intersection outside of the length of line(x3, x4)
return None return None, None
else: else:
# intersection outside of the length of line(x1, x2) # intersection outside of the length of line(x1, x2)
return None return None, None
def get_cropped_line(self, minx, maxx, miny, maxy, minz, maxz): def get_cropped_line(self, minx, maxx, miny, maxy, minz, maxz):
if (minx <= self.minx() <= self.maxx() <= maxx) \ if (minx <= self.minx() <= self.maxx() <= maxx) \
...@@ -283,6 +287,9 @@ class LineGroup(TransformableContainer): ...@@ -283,6 +287,9 @@ class LineGroup(TransformableContainer):
self._update_limits(line) self._update_limits(line)
self._is_closed = self._lines[0].p1 == self._lines[-1].p2 self._is_closed = self._lines[0].p1 == self._lines[-1].p2
def __str__(self):
return "LineGroup %s" % str([line.p1 for line in self._lines])
def is_connectable(self, line): def is_connectable(self, line):
if self._is_closed: if self._is_closed:
return False return False
...@@ -552,7 +559,7 @@ class LineGroup(TransformableContainer): ...@@ -552,7 +559,7 @@ class LineGroup(TransformableContainer):
if index_distance > 1: if index_distance > 1:
line1 = new_group[index1] line1 = new_group[index1]
line2 = new_group[index2] line2 = new_group[index2]
intersection = line1.get_intersection(line2) intersection, factor = line1.get_intersection(line2)
if intersection and (intersection != line1.p1) \ if intersection and (intersection != line1.p1) \
and (intersection != line1.p2): and (intersection != line1.p2):
del new_group[index1] del new_group[index1]
......
...@@ -283,9 +283,10 @@ class ContourModel(BaseModel): ...@@ -283,9 +283,10 @@ class ContourModel(BaseModel):
return self._cached_offset_models[offset] return self._cached_offset_models[offset]
result = ContourModel() result = ContourModel()
for group in self._line_groups: for group in self._line_groups:
new_group = group.get_offset_line_group(offset) new_groups = group.get_offset_line_groups(offset)
if not new_group is None: if not new_groups is None:
result.append(new_group) for new_group in new_groups:
result.append(new_group)
if callback and callback(): if callback and callback():
return None return None
# cache the result # cache the result
...@@ -327,8 +328,9 @@ class ContourModel(BaseModel): ...@@ -327,8 +328,9 @@ class ContourModel(BaseModel):
# check each pair of lines for intersections # check each pair of lines for intersections
for line1 in group1.next(): for line1 in group1.next():
for line2 in group2.next(): for line2 in group2.next():
intersection = line1.get_intersection(line2) intersection, factor = line1.get_intersection(line2)
if intersection: if intersection:
# return just the place of intersection
return intersection return intersection
# update the progress visualization and quit if requested # update the progress visualization and quit if requested
if callback and callback(): if callback and callback():
......
...@@ -26,6 +26,9 @@ import pycam.Cutters ...@@ -26,6 +26,9 @@ import pycam.Cutters
import pycam.Toolpath.SupportGrid import pycam.Toolpath.SupportGrid
import pycam.Geometry.Model import pycam.Geometry.Model
from pycam.Utils import ProgressCounter from pycam.Utils import ProgressCounter
import pycam.Utils.log
log = pycam.Utils.log.get_logger()
DIRECTIONS = frozenset(("x", "y", "xy")) DIRECTIONS = frozenset(("x", "y", "xy"))
...@@ -186,10 +189,11 @@ def generate_toolpath(model, tool_settings=None, ...@@ -186,10 +189,11 @@ def generate_toolpath(model, tool_settings=None,
if result is None: if result is None:
return None return None
elif result: elif result:
return "The contour model contains colliding line groups. " \ warning = "The contour model contains colliding line groups. " \
+ "This is not allowed in combination with an " \ + "This is not allowed in combination with an " \
+ "engraving offset.\nA collision was detected at " \ + "engraving offset.\nA collision was detected at " \
+ "(%.2f, %.2f, %.2f)." % (result.x, result.y, result.z) + "(%.2f, %.2f, %.2f)." % (result.x, result.y, result.z)
log.warning(warning)
else: else:
# no collisions and no user interruption # no collisions and no user interruption
pass pass
......
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