Esempio n. 1
0
 def calculate_point_height(self, x, y, func):
     point = Point(x, y, self.outer.minz)
     if not self.outer.is_point_inside(point):
         return None
     for poly in self.inner:
         if poly.is_point_inside(point):
             return None
     point = Point(x, y, self.outer.minz)
     line_distances = []
     for line in self.lines:
         cross_product = line.dir.cross(point.sub(line.p1))
         if cross_product.z > 0:
             close_points = []
             close_point = line.closest_point(point)
             if not line.is_point_inside(close_point):
                 close_points.append(line.p1)
                 close_points.append(line.p2)
             else:
                 close_points.append(close_point)
             for p in close_points:
                 direction = point.sub(p)
                 dist = direction.norm
                 line_distances.append(dist)
         elif cross_product.z == 0:
             # the point is on the line
             line_distances.append(0.0)
             # no other line can get closer than this
             break
         else:
             # the point is in the left of this line
             pass
     line_distances.sort()
     return self.z_level + func(line_distances[0])
Esempio n. 2
0
 def calculate_point_height(self, x, y, func):
     point = Point(x, y, self.outer.minz)
     if not self.outer.is_point_inside(point):
         return None
     for poly in self.inner:
         if poly.is_point_inside(point):
             return None
     point = Point(x, y, self.outer.minz)
     line_distances = []
     for line in self.lines:
         cross_product = line.dir.cross(point.sub(line.p1))
         if cross_product.z > 0:
             close_points = []
             close_point = line.closest_point(point)
             if not line.is_point_inside(close_point):
                 close_points.append(line.p1)
                 close_points.append(line.p2)
             else:
                 close_points.append(close_point)
             for p in close_points:
                 direction = point.sub(p)
                 dist = direction.norm
                 line_distances.append(dist)
         elif cross_product.z == 0:
             # the point is on the line
             line_distances.append(0.0)
             # no other line can get closer than this
             break
         else:
             # the point is in the left of this line
             pass
     line_distances.sort()
     return self.z_level + func(line_distances[0])
Esempio n. 3
0
def draw_direction_cone(p1, p2, position=0.5, precision=12, size=0.1):
    # convert p1 and p2 from list/tuple to Point
    if not hasattr(p1, "sub"):
        p1 = Point(*p1)
    if not hasattr(p2, "sub"):
        p2 = Point(*p2)
    distance = p2.sub(p1)
    length = distance.norm
    direction = distance.normalized()
    if direction is None:
        # zero-length line
        return
    cone_length = length * size
    cone_radius = cone_length / 3.0
    # move the cone to the middle of the line
    GL.glTranslatef((p1.x + p2.x) * position, (p1.y + p2.y) * position,
                    (p1.z + p2.z) * position)
    # rotate the cone according to the line direction
    # The cross product is a good rotation axis.
    cross = direction.cross(Point(0, 0, -1))
    if cross.norm != 0:
        # The line direction is not in line with the z axis.
        try:
            angle = math.asin(sqrt(direction.x**2 + direction.y**2))
        except ValueError:
            # invalid angle - just ignore this cone
            return
        # convert from radians to degree
        angle = angle / math.pi * 180
        if direction.z < 0:
            angle = 180 - angle
        GL.glRotatef(angle, cross.x, cross.y, cross.z)
    elif direction.z == -1:
        # The line goes down the z axis - turn it around.
        GL.glRotatef(180, 1, 0, 0)
    else:
        # The line goes up the z axis - nothing to be done.
        pass
    # center the cone
    GL.glTranslatef(0, 0, -cone_length * position)
    # draw the cone
    GLUT.glutSolidCone(cone_radius, cone_length, precision, 1)
Esempio n. 4
0
def draw_direction_cone(p1, p2, position=0.5, precision=12, size=0.1):
    # convert p1 and p2 from list/tuple to Point
    if not hasattr(p1, "sub"):
        p1 = Point(*p1)
    if not hasattr(p2, "sub"):
        p2 = Point(*p2)
    distance = p2.sub(p1)
    length = distance.norm
    direction = distance.normalized()
    if direction is None:
        # zero-length line
        return
    cone_length = length * size
    cone_radius = cone_length / 3.0
    # move the cone to the middle of the line
    GL.glTranslatef((p1.x + p2.x) * position,
            (p1.y + p2.y) * position, (p1.z + p2.z) * position)
    # rotate the cone according to the line direction
    # The cross product is a good rotation axis.
    cross = direction.cross(Point(0, 0, -1))
    if cross.norm != 0:
        # The line direction is not in line with the z axis.
        try:
            angle = math.asin(sqrt(direction.x ** 2 + direction.y ** 2))
        except ValueError:
            # invalid angle - just ignore this cone
            return
        # convert from radians to degree
        angle = angle / math.pi * 180
        if direction.z < 0:
            angle = 180 - angle
        GL.glRotatef(angle, cross.x, cross.y, cross.z)
    elif direction.z == -1:
        # The line goes down the z axis - turn it around.
        GL.glRotatef(180, 1, 0, 0)
    else:
        # The line goes up the z axis - nothing to be done.
        pass
    # center the cone
    GL.glTranslatef(0, 0, -cone_length * position)
    # draw the cone
    GLUT.glutSolidCone(cone_radius, cone_length, precision, 1)
Esempio n. 5
0
    def get_moves(self, safety_height, max_movement=None):
        class MoveContainer(object):
            def __init__(self, max_movement):
                self.max_movement = max_movement
                self.moved_distance = 0
                self.moves = []
                self.last_pos = None
                if max_movement is None:
                    self.append = self.append_without_movement_limit
                else:
                    self.append = self.append_with_movement_limit

            def append_with_movement_limit(self, new_position, rapid):
                if self.last_pos is None:
                    # first move with unknown start position - ignore it
                    self.moves.append((new_position, rapid))
                    self.last_pos = new_position
                    return True
                else:
                    distance = new_position.sub(self.last_pos).norm
                    if self.moved_distance + distance > self.max_movement:
                        partial = (self.max_movement - self.moved_distance) / \
                                distance
                        partial_dest = self.last_pos.add(
                            new_position.sub(self.last_pos).mul(partial))
                        self.moves.append((partial_dest, rapid))
                        self.last_pos = partial_dest
                        # we are finished
                        return False
                    else:
                        self.moves.append((new_position, rapid))
                        self.moved_distance += distance
                        self.last_pos = new_position
                        return True

            def append_without_movement_limit(self, new_position, rapid):
                self.moves.append((new_position, rapid))
                return True

        p_last = None
        result = MoveContainer(max_movement)
        for path in self.paths:
            if not path:
                # ignore empty paths
                continue
            p_next = path.points[0]
            if p_last is None:
                p_last = Point(p_next.x, p_next.y, safety_height)
                if not result.append(p_last, True):
                    return result.moves
            if ((abs(p_last.x - p_next.x) > epsilon) \
                    or (abs(p_last.y - p_next.y) > epsilon)):
                # Draw the connection between the last and the next path.
                # Respect the safety height.
                if (abs(p_last.z - p_next.z) > epsilon) \
                        or (p_last.sub(p_next).norm > \
                            self._max_safe_distance + epsilon):
                    # The distance between these two points is too far.
                    # This condition helps to prevent moves up/down for
                    # adjacent lines.
                    safety_last = Point(p_last.x, p_last.y, safety_height)
                    safety_next = Point(p_next.x, p_next.y, safety_height)
                    if not result.append(safety_last, True):
                        return result.moves
                    if not result.append(safety_next, True):
                        return result.moves
            for p in path.points:
                if not result.append(p, False):
                    return result.moves
            p_last = path.points[-1]
        if not p_last is None:
            p_last_safety = Point(p_last.x, p_last.y, safety_height)
            result.append(p_last_safety, True)
        return result.moves
Esempio n. 6
0
 def get_moves(self, safety_height, max_movement=None):
     class MoveContainer(object):
         def __init__(self, max_movement):
             self.max_movement = max_movement
             self.moved_distance = 0
             self.moves = []
             self.last_pos = None
             if max_movement is None:
                 self.append = self.append_without_movement_limit
             else:
                 self.append = self.append_with_movement_limit
         def append_with_movement_limit(self, new_position, rapid):
             if self.last_pos is None:
                 # first move with unknown start position - ignore it
                 self.moves.append((new_position, rapid))
                 self.last_pos = new_position
                 return True
             else:
                 distance = new_position.sub(self.last_pos).norm
                 if self.moved_distance + distance > self.max_movement:
                     partial = (self.max_movement - self.moved_distance) / \
                             distance
                     partial_dest = self.last_pos.add(new_position.sub(
                             self.last_pos).mul(partial))
                     self.moves.append((partial_dest, rapid))
                     self.last_pos = partial_dest
                     # we are finished
                     return False
                 else:
                     self.moves.append((new_position, rapid))
                     self.moved_distance += distance
                     self.last_pos = new_position
                     return True
         def append_without_movement_limit(self, new_position, rapid):
             self.moves.append((new_position, rapid))
             return True
     p_last = None
     max_safe_distance = 2 * self.toolpath_settings.get_tool().radius \
             + epsilon
     result = MoveContainer(max_movement)
     for path in self.get_paths():
         if not path:
             # ignore empty paths
             continue
         p_next = path.points[0]
         if p_last is None:
             p_last = Point(p_next.x, p_next.y, safety_height)
             if not result.append(p_last, True):
                 return result.moves
         if ((abs(p_last.x - p_next.x) > epsilon) \
                 or (abs(p_last.y - p_next.y) > epsilon)):
             # Draw the connection between the last and the next path.
             # Respect the safety height.
             if (abs(p_last.z - p_next.z) > epsilon) \
                     or (p_last.sub(p_next).norm > max_safe_distance):
                 # The distance between these two points is too far.
                 # This condition helps to prevent moves up/down for
                 # adjacent lines.
                 safety_last = Point(p_last.x, p_last.y, safety_height)
                 safety_next = Point(p_next.x, p_next.y, safety_height)
                 if not result.append(safety_last, True):
                     return result.moves
                 if not result.append(safety_next, True):
                     return result.moves
         for p in path.points:
             if not result.append(p, False):
                 return result.moves
         p_last = path.points[-1]
     if not p_last is None:
         p_last_safety = Point(p_last.x, p_last.y, safety_height)
         result.append(p_last_safety, True)
     return result.moves