Пример #1
0
    def setUp(self):
        self.segmentGroup = SegmentGroup()
        self.segmentGroup2 = SegmentGroup()

        self.pt1 = Point(0, 0, 0)
        self.pt2 = Point(100, 0, 100)
        self.pt3 = Point(100, 0, 0)
        self.pt4 = Point(0, 0, 100)
        self.pt5 = Point(-120.12, 0, 214.09)
        self.pt6 = Point(-179.88, 0, 85.91)
        self.pt7 = Point(-214.09, 0, 179.88)
        self.pt8 = Point(-85.91, 0, 120.12)
        self.pt9 = Point(-164.74, 0, 118.39)
        self.pt10 = Point(-137.55, 0, 176.70)

        self.lineSegment1 = Segment(self.pt1, self.pt2)
        self.lineSegment2 = Segment(self.pt5, self.pt6)
        self.lineSegment3 = Segment(self.pt9, self.pt10)
        self.lineSegment4 = Segment(self.pt2, self.pt1)

        self.inverseLineSegment1 = Segment(self.pt3, self.pt4)

        self.hfeed = 100
        self.vfeed = 50
        self.step_over = 1.5
        self.finish_passes = 2
Пример #2
0
    def generate_path(self):
        """Generate the path for the profile operation"""

        part_boundbox = self.part_segment_group.boundbox()
        x_min = self.stock.x_min - self.extra_dia * 0.5 - self.clearance
        x_max = 0 - self.min_dia * 0.5
        z_max = self.stock.z_max + self.start_offset

        self.clearing_paths = []
        length = z_max - part_boundbox.z_max + self.stock_to_leave
        step_over = self.step_over
        line_count = math.ceil(length / step_over)
        zstart = part_boundbox.z_max + step_over * line_count + self.stock_to_leave

        # build list of segments
        segmentgroup = SegmentGroup()
        # TODO: Move the final pass to finishing passes for a slower pass
        counter = 0
        while counter < line_count + 1:
            zpt = zstart - counter * self.step_over
            pt1 = Point(x_min, 0, zpt)
            pt2 = Point(x_max, 0, zpt)
            path_line = Segment(pt1, pt2)
            seg = path_line
            segmentgroup.add_segment(seg)

            pt3 = pt2.project(self.leadout_angle, self.step_over)
            leadout = Segment(pt2, pt3)
            segmentgroup.add_segment(leadout)

            counter += 1

        self.clearing_paths.append(segmentgroup)
Пример #3
0
    def boundbox(self):
        """Return the boundbox for the segmentgroup"""

        xvalues = []
        yvalues = []
        zvalues = []

        # collect all points from each segment by direction
        for segment in self.get_segments():
            xvalues.extend(segment.get_all_axis_positions('X'))
            yvalues.extend(segment.get_all_axis_positions('Y'))
            zvalues.extend(segment.get_all_axis_positions('Z'))

        x_min = min(xvalues, key=abs)
        x_max = max(xvalues, key=abs)
        y_min = min(yvalues, key=abs)
        y_max = max(yvalues, key=abs)
        z_min = min(zvalues, key=abs)
        z_max = max(zvalues, key=abs)

        pt1 = Point(x_min, y_min, z_min)
        pt2 = Point(x_max, y_max, z_max)

        segmentgroupBoundBox = BoundBox(pt1, pt2)

        return segmentgroupBoundBox
Пример #4
0
 def __init__(self,
              start=Point(0.0, 0.0, 0.0),
              end=Point(0.0, 0.0, 0.0),
              bulge=0.0):
     self.start = start
     self.end = end
     self.bulge = bulge
Пример #5
0
    def setUp(self):
        self.pt1 = Point(0, 0, 0)
        self.pt2 = Point(100, 100, 100)
        self.boundBox1 = BoundBox(self.pt1, self.pt2)

        self.pt3 = Point(-100, -100, -100.5)
        self.pt4 = Point(100, 100, 100)
        self.boundBox2 = BoundBox(self.pt3, self.pt4)
Пример #6
0
    def test_get_centre_point(self):
        lineCentrePt = self.lineSegment1.get_centre_point()
        self.assertEqual(lineCentrePt, None)

        arcCentrePt = self.arcSegment1.get_centre_point()
        centrePt = Point(70.83333333333333, 0.0, 29.166666666666668)
        self.assertTrue(arcCentrePt.is_same(centrePt))

        invArcCenPt = self.inverseArcSegment1.get_centre_point()
        centrePt = Point(29.166666666666668, 0.0, 70.83333333333333)
        self.assertTrue(invArcCenPt.is_same(centrePt))
Пример #7
0
    def z_at_x(self, x):
        """get the z value at the first intersection at the given x position"""
        boundbox = self.boundbox()
        offset = boundbox.z_length()
        start_pt = Point(x, 0, boundbox.z_max + offset)
        end_pt = Point(x, 0, boundbox.z_min - offset)

        line_segment = Segment(start_pt, end_pt)
        for segment in self.get_segments():
            intersect, pts = segment.intersect(line_segment)
            if intersect:
                return pts[0].Z
        return None
Пример #8
0
    def setUp(self):

        # Define Part Geometry
        part_segments = []

        PartPt1 = Point(0, 0, 10)
        PartPt2 = Point(-5, 0, -9)
        PartPt3 = Point(-9.5, 0, -15.85)
        PartPt4 = Point(-5.4, 0, -22)
        PartPt5 = Point(-5.4, 0, -40)
        PartPt6 = Point(-13, 0, -45)
        PartPt7 = Point(-13, 0, -48)
        PartPt8 = Point(0, 0, -48)

        part_segments.append(Segment(PartPt1, PartPt2, -0.75))
        part_segments.append(Segment(PartPt2, PartPt3))
        part_segments.append(Segment(PartPt3, PartPt4))
        part_segments.append(Segment(PartPt4, PartPt5))
        part_segments.append(Segment(PartPt5, PartPt6))
        part_segments.append(Segment(PartPt6, PartPt8))
        part_segments.append(Segment(PartPt7, PartPt8))

        # Define stock bounds
        stockPt1 = Point(0, 0, 15)
        stockPt2 = Point(-25, 0, -47.5)
        stock_boundbox = BoundBox(stockPt1, stockPt2)

        # set feed rate to test
        self.hfeed = 10

        # Define Operations Properties
        params = {}
        params['min_dia'] = 0
        params['extra_dia'] = 0
        params['start_offset'] = 0
        params['end_offset'] = 0
        params['allow_grooving'] = True
        params['step_over'] = 1
        params['finish_passes'] = 2
        params['stock_to_leave'] = 0
        params['hfeed'] = self.hfeed
        params['vfeed'] = 10

        self.op = RoughOP()
        self.op.set_params(params)
        self.op.add_stock(stock_boundbox)
        self.op.add_part_edges(part_segments)
        tool = Tool()
        tool.set_tool_from_string('DCMT070204R')
        self.op.add_tool(tool)
Пример #9
0
    def find_next_good_edge(self,
                            current_index,
                            stock_z_min,
                            tool,
                            allow_grooving,
                            pt=None):
        segments = self.get_segments()
        index = current_index
        if pt is None:
            pt1 = segments[index].start
        else:
            pt1 = pt

        index += 1
        while index < len(segments):

            if allow_grooving:
                # create a new point at the max angle from pt1
                ang = tool.get_tool_cutting_angle()
                # calculate the length required to project the point to the centreline
                length = abs(pt1.X / math.cos(math.radians(ang - 90)))
                pt2 = pt1.project(ang, length)
            else:
                pt2 = Point(pt1.X, pt1.Y, stock_z_min)

            # create a new projected segment
            seg = Segment(pt1, pt2)

            # loop through the remaining segments and see if the projected segments
            idx = index
            while idx < len(segments):
                intersect, pts = seg.intersect(segments[idx])
                if intersect:
                    return idx, pts[0]
                idx += 1
            index += 1

        stock_pt = Point(pt1.X, pt1.Y, stock_z_min)
        seg = Segment(pt1, stock_pt)
        index = current_index
        index += 1

        while index < len(segments):
            intersect, pts = seg.intersect(segments[index])
            if intersect:
                return index, pts[0]

            index += 1
        # No solution :(
        return False, stock_pt
Пример #10
0
    def test_angle_to(self):

        angle = self.pt1.angle_to(Point(0, 0, 100))
        self.assertEqual(angle, 0)

        angle = self.pt1.angle_to(Point(100, 0, 100))
        self.assertEqual(angle, 45)

        angle = self.pt1.angle_to(Point(100, 0, 0))
        self.assertEqual(angle, 90)

        angle = self.pt1.angle_to(Point(100, 0, -100))
        self.assertEqual(angle, 135)

        angle = self.pt1.angle_to(Point(0, 0, -100))
        self.assertEqual(angle, 180)

        angle = self.pt1.angle_to(Point(-100, 0, -100))
        self.assertEqual(angle, 225)

        angle = self.pt1.angle_to(Point(-100, 0, 0))
        self.assertEqual(angle, 270)

        angle = self.pt1.angle_to(Point(-100, 0, 100))
        self.assertEqual(angle, 315)
Пример #11
0
    def get_centre_point(self):
        """Returns the centre point of the arc"""

        if self.bulge == 0:
            return None

        normal = math.sqrt(
            math.pow((self.end.X - self.start.X), 2) +
            math.pow((self.end.Z - self.start.Z), 2))

        basex = math.sqrt(
            math.pow(self.get_radius(), 2) -
            math.pow((normal / 2), 2)) * (self.start.Z - self.end.Z) / normal
        basey = math.sqrt(
            math.pow(self.get_radius(), 2) -
            math.pow((normal / 2), 2)) * (self.end.X - self.start.X) / normal

        # invert for positive bulge values
        if self.bulge > 0:
            basex = -basex
            basey = -basey

        x = (self.start.X + self.end.X) / 2 + basex
        z = (self.start.Z + self.end.Z) / 2 + basey

        p = Point(x, 0, z)

        return p
Пример #12
0
    def intersect_circle_circle(self, seg, extend=False):
        # ref http://paulbourke.net/geometry/circlesphere/

        c1 = self.get_centre_point()
        r1 = self.get_radius()
        c2 = seg.get_centre_point()
        r2 = seg.get_radius()
        intersect = False
        pts = []
        ptsout = []

        # Determine actual distance between circle centres
        c_dist = c1.distance_to(c2)

        if round(c_dist, 5) >= round(r1 + r2, 5):
            # too far apart to intersect or just touching
            return intersect, ptsout

        if c_dist < abs(r1 - r2):
            # inside each other
            return intersect, ptsout

        if c1.is_same(c2) or round(c_dist, 5) == 0:
            # concentric
            return intersect, ptsout

        # get the chord distance
        a = (r1**2 - r2**2 + c_dist**2) / (2 * c_dist)

        # A**2 + B**2 = C**2; h**2 + a**2 = r1**2 therefore:
        h = math.sqrt(r1**2 - a**2)
        p = c1.lerp(c2, a / c_dist)
        b = h / c_dist
        pts.append(Point(p.X - b * (c2.Z - c1.Z), 0, p.Z + b * (c2.X - c1.X)))
        pts.append(Point(p.X + b * (c2.Z - c1.Z), 0, p.Z - b * (c2.X - c1.X)))

        for pnt in pts:
            # check if the point is on both segments
            if self.point_on_segment(pnt) and seg.point_on_segment(pnt):
                ptsout.append(pnt)

        if len(ptsout):
            intersect = True

        return intersect, ptsout
Пример #13
0
    def generate_path(self):
        """Generate the path for the Part operation"""

        self.tool_paths = []

        toolWidth = self.tool.get_width()
        xmin = self.stock.XMin - self.extra_dia * 0.5
        xmax = 0 - self.min_dia * 0.5
        zmin = self.stock.ZMin - toolWidth

        # build list of segments
        segmentgroup = SegmentGroup()
        startPt = Point(xmin, 0, zmin)
        endPt = Point(xmax, 0, zmin)
        seg = Segment(startPt, endPt)
        segmentgroup.add_segment(seg)

        self.tool_paths.append(segmentgroup)
Пример #14
0
        def get_pos(pnt):
            x = pnt.X
            y = pnt.Y
            z = pnt.Z

            if invert_x:
                x = 0 - x

            return Point(x, y, z)
Пример #15
0
    def test_normalise_to(self):
        normal = self.pt1.normalise_to(Point(100, 0, 100))
        self.assertEqual(normal.X, 0.7071067811865475)
        self.assertEqual(normal.Y, 0)
        self.assertEqual(normal.Z, 0.7071067811865475)

        normal = self.pt1.normalise_to(self.pt1)
        self.assertEqual(normal.X, 0)
        self.assertEqual(normal.Y, 0)
        self.assertEqual(normal.Z, 0)
Пример #16
0
    def intersectCircleCircle(self, seg, extend=False):

        c1 = self.get_centre_point()
        r1 = self.get_radius()
        c2 = seg.get_centre_point()
        r2 = seg.get_radius()
        intersect = False
        pts = []
        ptsout = []

        # Determine actual distance between circle centres
        c_dist = c1.distance_to(c2)

        if c_dist > r1 + r2:
            # too far apart to intersect
            return intersect, ptsout

        if c_dist < abs(r1 - r2):
            # inside each other
            return intersect, ptsout

        if c1.is_same(c2):
            # concentric
            return intersect, ptsout

        a = (r1 ** 2 - r2 ** 2 + c_dist ** 2) / (2 * c_dist)
        h = math.sqrt(r1 ** 2 - a ** 2)
        p = c1.lerp(c2, a / c_dist)
        b = h / c_dist
        pts.append(Point(p.X - b * (c2.Z - c1.Z), 0, p.Z + b * (c2.X - c1.X)))
        pts.append(Point(p.X + b * (c2.Z - c1.Z), 0, p.Z - b * (c2.X - c1.X)))

        for pnt in pts:
            # check if the point is on both segments
            if self.point_on_segment(pnt) and seg.point_on_segment(pnt):
                ptsout.append(pnt)

        if len(ptsout):
            intersect = True

        return intersect, ptsout
Пример #17
0
    def setUp(self):
        self.pt1 = Point(0, 0, 0)
        self.pt2 = Point(100, 0, 100)
        self.pt3 = Point(100, 0, 0)
        self.pt4 = Point(0, 0, 100)
        self.pt5 = Point(-120.12, 0, 214.09)
        self.pt6 = Point(-179.88, 0, 85.91)
        self.pt7 = Point(-214.09, 0, 179.88)
        self.pt8 = Point(-85.91, 0, 120.12)
        self.pt9 = Point(-164.74, 0, 118.39)
        self.pt10 = Point(-137.55, 0, 176.70)

        self.lineSegment1 = Segment(self.pt1, self.pt2)
        self.lineSegment2 = Segment(self.pt5, self.pt6)
        self.lineSegment3 = Segment(self.pt9, self.pt10)

        self.inverseLineSegment1 = Segment(self.pt3, self.pt4)

        self.arcSegment1 = Segment(self.pt1, self.pt2, 1.5)
        self.arcSegment2 = Segment(self.pt7, self.pt8, 1.5)
        self.arcSegment3 = Segment(self.pt3, self.pt4, 1.5)

        self.inverseArcSegment1 = Segment(self.pt1, self.pt2, -1.5)
        self.inverseArcSegment2 = Segment(self.pt7, self.pt8, -1.5)
Пример #18
0
    def intersectLineLine(self, seg, extend=False):

        a1 = self.start
        a2 = self.end
        b1 = seg.start
        b2 = seg.end
        intersect = False
        pts = []

        ua_t = (b2.X - b1.X) * (a1.Z - b1.Z) - (b2.Z - b1.Z) * (a1.X - b1.X)
        ub_t = (a2.X - a1.X) * (a1.Z - b1.Z) - (a2.Z - a1.Z) * (a1.X - b1.X)
        u_b = (b2.Z - b1.Z) * (a2.X - a1.X) - (b2.X - b1.X) * (a2.Z - a1.Z)

        if (u_b != 0):
            ua = ua_t / u_b
            ub = ub_t / u_b

            if ((0 <= ua and ua <= 1) and (0 <= ub and ub <= 1)) or extend:
                intersect = True
                pt = Point(a1.X + ua * (a2.X - a1.X), 0, a1.Z + ua * (a2.Z - a1.Z))
                pts.append(pt)

        return intersect, pts
Пример #19
0
    def test_intersect(self):

        intersect, pts = self.lineSegment1.intersect(self.inverseLineSegment1)
        pt = pts[0]
        self.assertTrue(intersect)
        intersectionPt = Point(50, 0.0, 50)
        self.assertTrue(pt.is_same(intersectionPt))

        intersect, pts = self.arcSegment1.intersect(self.inverseLineSegment1)
        pt = pts[0]
        self.assertTrue(intersect)
        intersectionPt = Point(16.666666666666657, 0.0, 83.33333333333334)
        self.assertTrue(pt.is_same(intersectionPt))

        intersect, pts = self.inverseArcSegment1.intersect(
            self.inverseLineSegment1)
        pt = pts[0]
        self.assertTrue(intersect)
        intersectionPt = Point(83.33333333333334, 0.0, 16.66666666666666)
        self.assertTrue(pt.is_same(intersectionPt))

        intersect, pts = self.arcSegment2.intersect(self.lineSegment2)
        pt = pts[0]
        self.assertTrue(intersect)
        intersectionPt = Point(-130.08000000000004, 0.0, 192.72666666666657)
        self.assertTrue(pt.is_same(intersectionPt))

        intersect, pts = self.inverseArcSegment2.intersect(self.lineSegment2)
        pt = pts[0]
        self.assertTrue(intersect)
        intersectionPt = Point(-169.91999999999996, 0.0, 107.27333333333338)
        self.assertTrue(pt.is_same(intersectionPt))

        intersect, pts = self.arcSegment1.intersect(self.arcSegment3)
        pt = pts[0]
        self.assertTrue(intersect)
        intersectionPt = Point(-2.882525053975556, 0.0, 50)
        self.assertTrue(pts[0].is_same(intersectionPt))

        # false intersection tests
        intersect, pts = self.inverseArcSegment2.intersect(self.lineSegment1)
        self.assertFalse(intersect)

        intersect, pts = self.arcSegment2.intersect(self.lineSegment3)
        self.assertFalse(intersect)
Пример #20
0
class test_point(unittest.TestCase):
    """Test for point.py"""
    def setUp(self):
        self.pt1 = Point(0, 0, 0)
        self.pt2 = Point(100, 100, 100)
        self.pt3 = Point(150, 130, 200)
        self.pt4 = Point(200, 200, 200)
        self.pt5 = Point(-100, 0, 100)
        self.pt6 = Point(0, 100, 200)
        self.pt7 = Point(-200, -200, -200)
        self.pt8 = Point(-400, -400, -400)
        self.pt9 = Point(-200, -200, -200)
        self.pt10 = Point(200, 200, 200)

    def test_distance_to(self):
        distance = self.pt1.distance_to(self.pt2)
        self.assertEqual(distance, 173.20508075688772)

    def test_angle_to(self):
        angle = self.pt1.angle_to(self.pt2)
        self.assertEqual(angle, 45)

    def test_nearest(self):
        pts = [self.pt2, self.pt3]
        nearest = self.pt1.nearest(pts)
        self.assertEqual(nearest, self.pt2)

    def test_is_same_return_false(self):
        same = self.pt1.is_same(self.pt2)
        self.assertFalse(same)

    def test_is_same_return_true(self):
        same = self.pt1.is_same(self.pt1)
        self.assertTrue(same)

    def test_sub(self):
        sub = self.pt4.sub(self.pt2)
        self.assertEqual(sub.X, self.pt2.X)
        self.assertEqual(sub.Y, self.pt2.Y)
        self.assertEqual(sub.Z, self.pt2.Z)

        subNegative = self.pt7.add(self.pt7)
        self.assertEqual(subNegative.X, self.pt8.X)
        self.assertEqual(subNegative.Y, self.pt8.Y)
        self.assertEqual(subNegative.Z, self.pt8.Z)

    def test_add(self):
        add = self.pt2.add(self.pt2)
        self.assertEqual(add.X, self.pt4.X)
        self.assertEqual(add.Y, self.pt4.Y)
        self.assertEqual(add.Z, self.pt4.Z)

        addNegative = self.pt5.add(self.pt2)
        self.assertEqual(addNegative.X, self.pt6.X)
        self.assertEqual(addNegative.Y, self.pt6.Y)
        self.assertEqual(addNegative.Z, self.pt6.Z)

    def test_multiply(self):
        multiply = self.pt2.multiply(0)
        self.assertEqual(multiply.X, self.pt1.X)
        self.assertEqual(multiply.Y, self.pt1.Y)
        self.assertEqual(multiply.Z, self.pt1.Z)

        multiplyNegative = self.pt7.multiply(1)
        self.assertEqual(multiplyNegative.X, self.pt7.X)
        self.assertEqual(multiplyNegative.Y, self.pt7.Y)
        self.assertEqual(multiplyNegative.Z, self.pt7.Z)

    def test_rotate(self):
        rotate = self.pt2.rotate(90)
        self.assertEqual(rotate.X, 100)
        self.assertEqual(rotate.Y, 100)
        self.assertEqual(rotate.Z, -100)

    def test_mid(self):
        mid = self.pt2.mid(self.pt4)
        self.assertEqual(mid.X, 150)
        self.assertEqual(mid.Y, 150)
        self.assertEqual(mid.Z, 150)

    def test_project(self):
        projected = self.pt1.project(270, 5)
        self.assertEqual(projected.X, self.pt1.X)
        self.assertEqual(projected.Y, self.pt1.Y)
        self.assertEqual(projected.Z, -5)
Пример #21
0
class test_point(unittest.TestCase):
    """Test for point.py"""
    def setUp(self):
        self.pt1 = Point(0, 0, 0)
        self.pt2 = Point(100, 100, 100)
        self.pt3 = Point(150, 130, 200)
        self.pt4 = Point(200, 200, 200)
        self.pt5 = Point(-100, 0, 100)
        self.pt6 = Point(0, 100, 200)
        self.pt7 = Point(-200, -200, -200)
        self.pt8 = Point(-400, -400, -400)
        self.pt9 = Point(-200, -200, -200)
        self.pt10 = Point(200, 200, 200)

    def test_distance_to(self):
        distance = self.pt1.distance_to(self.pt2)
        self.assertEqual(distance, 173.20508075688772)

    def test_angle_to(self):

        angle = self.pt1.angle_to(Point(0, 0, 100))
        self.assertEqual(angle, 0)

        angle = self.pt1.angle_to(Point(100, 0, 100))
        self.assertEqual(angle, 45)

        angle = self.pt1.angle_to(Point(100, 0, 0))
        self.assertEqual(angle, 90)

        angle = self.pt1.angle_to(Point(100, 0, -100))
        self.assertEqual(angle, 135)

        angle = self.pt1.angle_to(Point(0, 0, -100))
        self.assertEqual(angle, 180)

        angle = self.pt1.angle_to(Point(-100, 0, -100))
        self.assertEqual(angle, 225)

        angle = self.pt1.angle_to(Point(-100, 0, 0))
        self.assertEqual(angle, 270)

        angle = self.pt1.angle_to(Point(-100, 0, 100))
        self.assertEqual(angle, 315)

    def test_nearest(self):
        pts = [self.pt2, self.pt3]
        nearest = self.pt1.nearest(pts)
        self.assertEqual(nearest, self.pt2)

    def test_is_same_return_false(self):
        same = self.pt1.is_same(self.pt2)
        self.assertFalse(same)

    def test_is_same_return_true(self):
        same = self.pt1.is_same(self.pt1)
        self.assertTrue(same)

    def test_sub(self):
        sub = self.pt4.sub(self.pt2)
        self.assertEqual(sub.X, self.pt2.X)
        self.assertEqual(sub.Y, self.pt2.Y)
        self.assertEqual(sub.Z, self.pt2.Z)

        subNegative = self.pt7.add(self.pt7)
        self.assertEqual(subNegative.X, self.pt8.X)
        self.assertEqual(subNegative.Y, self.pt8.Y)
        self.assertEqual(subNegative.Z, self.pt8.Z)

    def test_add(self):
        add = self.pt2.add(self.pt2)
        self.assertEqual(add.X, self.pt4.X)
        self.assertEqual(add.Y, self.pt4.Y)
        self.assertEqual(add.Z, self.pt4.Z)

        addNegative = self.pt5.add(self.pt2)
        self.assertEqual(addNegative.X, self.pt6.X)
        self.assertEqual(addNegative.Y, self.pt6.Y)
        self.assertEqual(addNegative.Z, self.pt6.Z)

    def test_multiply(self):
        multiply = self.pt2.multiply(0)
        self.assertEqual(multiply.X, self.pt1.X)
        self.assertEqual(multiply.Y, self.pt1.Y)
        self.assertEqual(multiply.Z, self.pt1.Z)

        multiplyNegative = self.pt7.multiply(1)
        self.assertEqual(multiplyNegative.X, self.pt7.X)
        self.assertEqual(multiplyNegative.Y, self.pt7.Y)
        self.assertEqual(multiplyNegative.Z, self.pt7.Z)

    def test_lerp(self):
        lerp = self.pt1.lerp(self.pt2, 0.5)
        self.assertEqual(lerp.X, 50)
        self.assertEqual(lerp.Y, 50)
        self.assertEqual(lerp.Z, 50)

    def test_normalise_to(self):
        normal = self.pt1.normalise_to(Point(100, 0, 100))
        self.assertEqual(normal.X, 0.7071067811865475)
        self.assertEqual(normal.Y, 0)
        self.assertEqual(normal.Z, 0.7071067811865475)

        normal = self.pt1.normalise_to(self.pt1)
        self.assertEqual(normal.X, 0)
        self.assertEqual(normal.Y, 0)
        self.assertEqual(normal.Z, 0)

    def test_rotate(self):
        rotate = self.pt2.rotate(90)
        self.assertEqual(rotate.X, -100)
        self.assertEqual(rotate.Y, 100)
        self.assertEqual(rotate.Z, 100)

    def test_mid(self):
        mid = self.pt2.mid(self.pt4)
        self.assertEqual(mid.X, 150)
        self.assertEqual(mid.Y, 150)
        self.assertEqual(mid.Z, 150)

    def test_project(self):
        projected = self.pt1.project(0, 5)
        self.assertEqual(projected.X, 0)
        self.assertEqual(projected.Y, 0)
        self.assertEqual(projected.Z, 5)

        projected = self.pt1.project(45, 5)
        self.assertEqual(projected.X, 3.53553)
        self.assertEqual(projected.Y, 0)
        self.assertEqual(projected.Z, 3.53553)

        projected = self.pt1.project(90, 5)
        self.assertEqual(projected.X, 5)
        self.assertEqual(projected.Y, 0)
        self.assertEqual(projected.Z, 0)

        projected = self.pt1.project(135, 5)
        self.assertEqual(projected.X, 3.53553)
        self.assertEqual(projected.Y, 0)
        self.assertEqual(projected.Z, -3.53553)

        projected = self.pt1.project(180, 5)
        self.assertEqual(projected.X, 0)
        self.assertEqual(projected.Y, 0)
        self.assertEqual(projected.Z, -5)

        projected = self.pt1.project(225, 5)
        self.assertEqual(projected.X, -3.53553)
        self.assertEqual(projected.Y, 0)
        self.assertEqual(projected.Z, -3.53553)

        projected = self.pt1.project(270, 5)
        self.assertEqual(projected.X, -5)
        self.assertEqual(projected.Y, 0)
        self.assertEqual(projected.Z, 0)
Пример #22
0
    def remove_the_groove(self, stock_z_min, tool, allow_grooving=False):
        segments = self.get_segments()
        segs_out = SegmentGroup()
        index = 0

        while index < len(segments):
            seg = segments[index]
            next_index = False
            pt1 = seg.start
            pt2 = seg.end
            pt = None

            # TO DO: Tidy this mess

            if seg.bulge > 0:
                segAng = round(math.degrees(seg.get_angle()), 5)
                # get angle tangent to the start point
                startPtAng = round(
                    pt1.angle_to(seg.get_centre_point()) - 90, 5)
                if startPtAng >= tool.get_tool_cutting_angle():
                    if startPtAng + segAng <= 270:
                        segs_out.add_segment(seg)
                else:
                    ang = tool.get_tool_cutting_angle()
                    # calculate the length required to project the point to the centreline
                    length = abs(pt1.X / math.cos(math.radians(ang - 90)))
                    proj_pt = pt1.project(ang, length)
                    projseg = Segment(pt1, proj_pt)
                    intersect, pts = projseg.intersect(segments[index])
                    if intersect and allow_grooving:
                        # add the intersecting line to the segment_group
                        new_seg = Segment(pt1, pts[0])
                        segs_out.add_segment(new_seg)
                        # add the remainder of the arc to the segment_group
                        remaining_seg = Segment(pts[0], pt2)
                        remaining_seg.derive_bulge(seg)
                        segs_out.add_segment(remaining_seg)
                    else:
                        if seg.start.angle_to(seg.end) <= 180:
                            seg = Segment(pt1, pt2)
                            segs_out.add_segment(seg)
                        else:
                            pt = seg.start
                            next_index, pt = self.find_next_good_edge(
                                index, stock_z_min, tool, allow_grooving, pt)

            if seg.bulge < 0:
                # Limit the arc movement to the X extents or the tangent at the max tool angle if allow_grooving
                angle_limit = 270 if allow_grooving is False else tool.get_tool_cutting_angle(
                ) + 90
                if seg.get_centre_point().angle_to(pt2) >= angle_limit:
                    segs_out.add_segment(seg)
                else:
                    rad = seg.get_radius()
                    if not allow_grooving:
                        # define a point vertically down on the x axis.
                        x = seg.get_centre_point().X - rad
                        y = seg.get_centre_point().Y
                        z = seg.get_centre_point().Z
                        pt = Point(x, y, z)
                    else:
                        # project a point from the centre of the arc along the angle limit to the radius
                        pt = seg.get_centre_point().project(angle_limit, rad)

                    nseg = Segment(pt1, pt)
                    nseg.derive_bulge(seg, rad)
                    segs_out.add_segment(nseg)

                    pt1 = pt
                    next_index, pt = self.find_next_good_edge(
                        index, stock_z_min, tool, allow_grooving, pt)

            elif seg.bulge == 0:
                if pt1.angle_to(pt2) < tool.get_tool_cutting_angle():
                    next_index, pt = self.find_next_good_edge(
                        index, stock_z_min, tool, allow_grooving)
                else:
                    segs_out.add_segment(seg)

            if next_index is False and pt is not None:
                seg = Segment(pt1, pt)
                segs_out.add_segment(seg)
                break
            if next_index is not False and next_index != index:
                seg = Segment(pt1, pt)
                segs_out.add_segment(seg)

                next_pt1 = pt
                next_pt2 = segments[next_index].end
                seg = Segment(next_pt1, next_pt2)
                seg.derive_bulge(segments[next_index])
                segs_out.add_segment(seg)

                next_index += 1
                index = next_index
                continue

            index += 1
        segs_out.merge_segments()
        return segs_out
Пример #23
0
def getliblatheBoundBox(FcBB):
    liblatheBoundbox = BoundBox(Point(FcBB.XMin, FcBB.YMin, FcBB.ZMin),
                                Point(FcBB.XMax, FcBB.YMax, FcBB.ZMax))
    return liblatheBoundbox
Пример #24
0
    def generate_path(self):
        """Generate the path for the Rough operation"""

        self.part_segment_group = self.part_segment_group.remove_the_groove(
            self.stock.z_min, self.tool, self.allow_grooving)
        self.clearing_paths = []
        z_max = self.stock.z_max + self.start_offset + self.clearance
        line_count = int(
            math.ceil((self.stock.x_length() + self.extra_dia * 0.5) /
                      self.step_over))
        xstart = 0 - (self.step_over * line_count + self.min_dia * 0.5)

        # create roughing boundary offset by the stock to leave value
        roughing_boundary = self.part_segment_group.offset_path(
            self.stock_to_leave)

        for roughing_pass in range(line_count):
            xpt = xstart + roughing_pass * self.step_over

            # check if the roughing pass start is outside the stock
            boundary_z = roughing_boundary.z_at_x(xpt)
            if boundary_z and round(boundary_z, 5) >= round(
                    self.stock.z_max, 5):
                continue

            pt1 = Point(xpt, 0, z_max)
            pt2 = Point(xpt, 0,
                        z_max - self.stock.z_length() - self.start_offset)
            path_line = Segment(pt1, pt2)
            intersections = []
            for seg in roughing_boundary.get_segments():
                intersect, point = seg.intersect(path_line)
                if intersect:
                    for p in point:
                        intersection = Intersection(p, seg)
                        intersections.append(intersection)

            # build list of segments
            segmentgroup = SegmentGroup()

            if not intersections:
                seg = path_line
                segmentgroup.add_segment(seg)

            if len(intersections) == 1:
                # Only one intersection, trim line to intersection.
                seg = Segment(pt1, intersections[0].point)
                segmentgroup.add_segment(seg)
                if intersections[0].seg:
                    # add lead out
                    startPt = intersections[0].point
                    endPt = startPt.project(self.leadout_angle, self.step_over)
                    path_line = Segment(startPt, endPt)
                    segmentgroup.add_segment(path_line)

            if len(intersections) > 1:
                # more than one intersection
                # add the end points of the pass to generate new segments
                intersection = Intersection(pt1, None)
                intersections.insert(0, intersection)

                intersection2 = Intersection(pt2, None)
                intersections.append(intersection2)

                #  sort the a list of intersections by their z position
                intersections = sorted(intersections,
                                       key=lambda p: p.point.Z,
                                       reverse=True)

                for i in range(len(intersections)):
                    if i + 1 < len(intersections):
                        if i % 2 == 0:
                            # primary segment
                            primary_segment = Segment(
                                intersections[i].point,
                                intersections[i + 1].point)

                            # check the length of the pass before adding to the segmentgroup
                            if primary_segment.get_length() < self.step_over:
                                continue

                            # if the intersection is connected to another segment
                            if intersections[i].seg:
                                # add a lead in
                                # TODO: optimise this to match the max tool angle
                                endPt = intersections[i].point
                                startPt = endPt.project(
                                    self.leadin_angle, self.step_over)
                                path_line = Segment(startPt, endPt)
                                segmentgroup.add_segment(path_line)

                            # add the primary segment to the segment group
                            segmentgroup.add_segment(primary_segment)

                            # if the intersection is connected to another segment
                            if intersections[i + 1].seg:
                                # add a lead out
                                startPt = intersections[i + 1].point
                                endPt = startPt.project(
                                    self.leadout_angle, self.step_over)
                                path_line = Segment(startPt, endPt)
                                segmentgroup.add_segment(path_line)

            if segmentgroup.count():
                self.tool_paths.append(segmentgroup)
Пример #25
0
    def remove_the_groove(self, stock_zmin, tool, allow_grooving=False):
        segments = self.get_segments()
        segs_out = SegmentGroup()
        index = 0

        while index < len(segments):
            seg = segments[index]
            next_index = False
            pt1 = seg.start
            pt2 = seg.end
            pt = None

            if seg.bulge != 0:
                print('arc segment')
                if seg.bulge > 0:
                    # TODO: handle segments with a positive bulge
                    seg = Segment(pt1, pt2)
                    segs_out.add_segment(seg)
                if seg.bulge < 0:
                    # Limit the arc movement to the X extents or the tangent at the max tool angle if allow_grooving
                    angle_limit = 180 if allow_grooving is False else tool.get_tool_cutting_angle() - 90
                    if seg.get_centre_point().angle_to(pt2) <= angle_limit:
                        segs_out.add_segment(seg)
                    else:
                        rad = seg.get_radius()
                        if not allow_grooving:
                            x = seg.get_centre_point().X - rad
                            y = seg.get_centre_point().Y
                            z = seg.get_centre_point().Z
                            pt = Point(x, y, z)
                        else:
                            pt = seg.get_centre_point().project(angle_limit, rad)

                        if seg.bulge < 0:
                            rad = 0 - rad

                        seg = Segment(pt1, pt)
                        seg.set_bulge_from_radius(rad)
                        segs_out.add_segment(seg)

                        pt1 = pt
                        next_index, pt = self.find_next_good_edge(index, stock_zmin, tool, allow_grooving, pt)

            elif seg.bulge == 0:
                print('line segment')
                if pt1.angle_to(pt2) > tool.get_tool_cutting_angle():
                    next_index, pt = self.find_next_good_edge(index, stock_zmin, tool, allow_grooving)
                else:
                    segs_out.add_segment(seg)

            if next_index is False and pt is not None:
                seg = Segment(pt1, pt)
                segs_out.add_segment(seg)
                break
            if next_index is not False and next_index != index:
                seg = Segment(pt1, pt)
                segs_out.add_segment(seg)
                next_pt1 = pt
                next_pt2 = segments[next_index].end
                seg = Segment(next_pt1, next_pt2)
                segs_out.add_segment(seg)
                next_index += 1
                index = next_index
                continue

            index += 1
        return segs_out
Пример #26
0
import sys

thisFolder = os.path.dirname(os.path.abspath(__file__))
parentFolder = os.path.dirname(thisFolder)
sys.path.append(parentFolder)

from liblathe.boundbox import BoundBox
from liblathe.point import Point
from liblathe.profile_op import ProfileOP
from liblathe.segment import Segment
from liblathe.plot import Plot

# Define Part Geometry
part_segments = []

PartPt1 = Point(0, 0, 0)
PartPt2 = Point(-15, 0, -5)
PartPt3 = Point(-15, 0, -15)
PartPt4 = Point(0, 0, -20)

part_segments.append(Segment(PartPt1, PartPt2))
part_segments.append(Segment(PartPt2, PartPt3))
part_segments.append(Segment(PartPt3, PartPt4))
part_segments.append(Segment(PartPt4, PartPt1))

# Define stock bounds
stockPt1 = Point(0, 0, 5)
stockPt2 = Point(-20, 0, -20)
StockBoundingBox = BoundBox(stockPt1, stockPt2)

# Define Operations Properties
Пример #27
0
    def get_part_outline(self):
        '''
        Get Part Outline
        '''
        # TODO: Revisit the edge extraction and find a more elegant method
        model = self.model[0].Shape
        # get a section through the part origin on the XZ Plane
        sections = Path.Area().add(model).makeSections(
            mode=0, heights=[0.0], project=True, plane=self.stock_silhoutte)
        part_silhoutte = sections[0].setParams(Offset=0.0).getShape()
        # get an offset section larger than the part section
        part_bound_face = sections[0].setParams(Offset=0.1).getShape()

        # ensure the cutplane is larger than the part or segments will be missed
        modelBB = model.BoundBox
        plane_length = modelBB.ZLength * 1.5
        plane_width = (modelBB.XLength / 2) * 1.5
        z_ref = modelBB.ZMax + (plane_length - modelBB.ZLength) / 2

        # create a plane larger than the part
        cut_plane = Part.makePlane(plane_length, plane_width,
                                   FreeCAD.Vector(-plane_width, 0, z_ref),
                                   FreeCAD.Vector(0, -1, 0))
        # Cut the part section from the cut plane
        path_area = cut_plane.cut(part_silhoutte)

        part_edges = []
        part_segments = []

        # interate through the edges and check if each is inside the bound_face
        for edge in path_area.Edges:
            edge_in = True
            for vertex in edge.Vertexes:
                if not part_bound_face.isInside(vertex.Point, 0.1, True):
                    edge_in = False

            if edge_in:
                part_edges.append(edge)
                vert = edge.Vertexes
                pt1 = Point(vert[0].X, vert[0].Y, vert[0].Z)
                pt2 = Point(vert[-1].X, vert[-1].Y, vert[-1].Z)
                seg = Segment(pt1, pt2)

                if isinstance(edge.Curve, Part.Circle):
                    line1 = Part.makeLine(edge.Curve.Location,
                                          edge.Vertexes[0].Point)
                    line2 = Part.makeLine(edge.Curve.Location,
                                          edge.Vertexes[-1].Point)
                    part_edges.append(line1)
                    part_edges.append(line2)

                    angle = edge.LastParameter - edge.FirstParameter
                    direction = edge.Curve.Axis.y
                    # print('bulge angle', direction, angle * direction)
                    # TODO: set the correct sign for the bulge +-
                    seg.set_bulge(angle * direction)

                part_segments.append(seg)

        # path_profile = Part.makeCompound(part_edges)
        # Part.show(path_profile, 'Final_pass')
        return part_segments
Пример #28
0
 def setUp(self):
     self.pt1 = Point(0, 0, 0)
     self.pt2 = Point(100, 100, 100)
     self.pt3 = Point(150, 130, 200)
     self.pt4 = Point(200, 200, 200)
     self.pt5 = Point(-100, 0, 100)
     self.pt6 = Point(0, 100, 200)
     self.pt7 = Point(-200, -200, -200)
     self.pt8 = Point(-400, -400, -400)
     self.pt9 = Point(-200, -200, -200)
     self.pt10 = Point(200, 200, 200)
Пример #29
0
thisFolder = os.path.dirname(os.path.abspath(__file__))
parentFolder = os.path.dirname(thisFolder)
sys.path.append(parentFolder)

from liblathe.boundbox import BoundBox
from liblathe.point import Point
from liblathe.profile_op import ProfileOP
from liblathe.segment import Segment
from liblathe.plot import Plot
from liblathe.tool import Tool

# Define Part Geometry
part_segments = []

PartPt1 = Point(0, 0, 10)
PartPt2 = Point(-5, 0, -9)
PartPt3 = Point(-9.5, 0, -15.85)
PartPt4 = Point(-5.4, 0, -22)
PartPt5 = Point(-5.4, 0, -40)
PartPt6 = Point(-13, 0, -45)
PartPt7 = Point(-13, 0, -48)
PartPt8 = Point(0, 0, -48)

part_segments.append(Segment(PartPt1, PartPt2, -0.75))
part_segments.append(Segment(PartPt2, PartPt3))
part_segments.append(Segment(PartPt3, PartPt4))
part_segments.append(Segment(PartPt4, PartPt5))
part_segments.append(Segment(PartPt5, PartPt6))
part_segments.append(Segment(PartPt6, PartPt8))
part_segments.append(Segment(PartPt7, PartPt8))
Пример #30
0
 def multiply(self, val):
     v = Point(self.X * val, self.Y * val, self.Z * val)
     return v