Commit 0fd20d22 authored by sumpfralle's avatar sumpfralle

report an error, if a contour model with an offset causes intersections...

report an error, if a contour model with an offset causes intersections between lines of different line groups


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@419 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent b9e1bdbd
...@@ -130,3 +130,32 @@ class Line: ...@@ -130,3 +130,32 @@ class Line:
def get_points(self): def get_points(self):
return (self.p1, self.p2) return (self.p1, self.p2)
def get_intersection(self, line):
""" Get the point of intersection between two lines. Intersections
outside the length of these lines are ignored.
Returns None if no valid intersection was found.
"""
x1, x2, x3, x4 = self.p1, self.p2, line.p1, line.p2
a = x2.sub(x1)
b = x4.sub(x3)
c = x3.sub(x1)
# see http://mathworld.wolfram.com/Line-LineIntersection.html (24)
try:
factor = c.cross(b).dot(a.cross(b)) / a.cross(b).normsq()
except ZeroDivisionError:
# lines are parallel
return None
if 0 <= factor <= 1:
intersection = x1.add(a.mul(factor))
# check if the intersection is between x3 and x4
if (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.z, x4.z) <= intersection.z <= max(x3.z, x4.z)):
return intersection
else:
# intersection outside of the length of line(x3, x4)
return None
else:
# intersection outside of the length of line(x1, x2)
return None
...@@ -293,3 +293,44 @@ class ContourModel(BaseModel): ...@@ -293,3 +293,44 @@ class ContourModel(BaseModel):
result.append(line) result.append(line)
return result return result
def check_for_collisions(self):
def get_bounds_of_group(group):
minx, maxx, miny, maxy = None, None, None, None
for line in group:
lminx = min(line.p1.x, line.p2.x)
lmaxx = max(line.p1.x, line.p2.x)
lminy = min(line.p1.y, line.p2.y)
lmaxy = max(line.p1.y, line.p2.y)
if (minx is None) or (minx > lminx):
minx = lminx
if (maxx is None) or (maxx > lmaxx):
maxx = lmaxx
if (miny is None) or (miny > lminy):
miny = lminy
if (maxy is None) or (maxy > lmaxy):
maxy = lmaxy
return (minx, maxx, miny, maxy)
def check_bounds_of_groups(group1, group2):
bound1 = get_bounds_of_group(group1)
bound2 = get_bounds_of_group(group2)
if ((bound1[0] < bound2[0]) and not (bound1[1] > bound2[1])) or \
((bound2[0] < bound1[0]) and not (bound2[1] > bound1[1])):
# the x boundaries overlap
if ((bound1[2] < bound2[2]) and not (bound1[3] > bound2[3])) \
or ((bound2[2] < bound1[2]) \
and not (bound2[3] > bound1[3])):
# y also overlap
return True
return False
# check each pair of line groups for intersections
for group1 in self._line_groups:
for group2 in self._line_groups:
# check if both groups overlap - otherwise skip this pair
if check_bounds_of_groups(group1, group2):
# check each pair of lines for intersections
for line1 in group1:
for line2 in group2:
if line1.get_intersection(line2):
return True
return False
...@@ -124,6 +124,8 @@ def generate_toolpath(model, tool_settings=None, ...@@ -124,6 +124,8 @@ def generate_toolpath(model, tool_settings=None,
return "The thickness of the support grid must be a positive value" return "The thickness of the support grid must be a positive value"
if support_grid_height <= 0: if support_grid_height <= 0:
return "The height of the support grid must be a positive value" return "The height of the support grid must be a positive value"
if not callback is None:
callback(text="Preparing support grid model ...")
support_grid_model = pycam.Toolpath.SupportGrid.get_support_grid( support_grid_model = pycam.Toolpath.SupportGrid.get_support_grid(
minx, maxx, miny, maxy, minz, support_grid_distance, minx, maxx, miny, maxy, minz, support_grid_distance,
support_grid_distance, support_grid_thickness, support_grid_distance, support_grid_thickness,
...@@ -132,7 +134,15 @@ def generate_toolpath(model, tool_settings=None, ...@@ -132,7 +134,15 @@ def generate_toolpath(model, tool_settings=None,
# Adapt the contour_model to the engraving offset. This offset is # Adapt the contour_model to the engraving offset. This offset is
# considered to be part of the material_allowance. # considered to be part of the material_allowance.
if (not contour_model is None) and (engrave_offset > 0): if (not contour_model is None) and (engrave_offset > 0):
if not callback is None:
callback(text="Preparing contour model with offset ...")
contour_model = contour_model.get_offset_model(engrave_offset) contour_model = contour_model.get_offset_model(engrave_offset)
if not callback is None:
callback(text="Checking contour model with offset for collisions ...")
if contour_model.check_for_collisions():
return "The contour model contains colliding line groups." \
+ " This is not allowed in combination with an" \
+ " engraving offset."
# Due to some weirdness the height of the drill must be bigger than the object's size. # Due to some weirdness the height of the drill must be bigger than the object's size.
# Otherwise some collisions are not detected. # Otherwise some collisions are not detected.
cutter_height = 4 * (maxy - miny) cutter_height = 4 * (maxy - miny)
......
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