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)
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
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, -30) PartPt6 = Point(-5.4, 0, -35) PartPt7 = Point(-5.4, 0, -40) PartPt8 = Point(-13, 0, -45) PartPt9 = Point(-13, 0, -48) PartPt10 = 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, 0.25)) part_segments.append(Segment(PartPt5, PartPt6)) part_segments.append(Segment(PartPt6, PartPt8)) part_segments.append(Segment(PartPt7, PartPt8)) part_segments.append(Segment(PartPt8, PartPt9)) part_segments.append(Segment(PartPt9, PartPt10)) # Define stock bounds stockPt1 = Point(0, 0, 15) stockPt2 = Point(-25, 0, -55) 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'] = 3 params['stock_to_leave'] = 0 params['hfeed'] = self.hfeed params['vfeed'] = 10 self.op = ProfileOP() 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)
def join_segments(self): """join segments of the segmentgroup""" segments = self.get_segments() segmentgroupOut = SegmentGroup() for i in range(len(segments)): pt1 = segments[i].start pt2 = segments[i].end if i != 0: seg1 = segments[i - 1] intersect, pt = seg1.intersect(segments[i], extend=True) if intersect: if type(pt) is list: pt = pt1.nearest(pt) pt1 = pt if i != len(segments) - 1: seg2 = segments[i + 1] intersect2, pt = seg2.intersect(segments[i], extend=True) if intersect2: # print('intersect2') if type(pt) is list: # print('join_segments type of', type(pt)) pt = pt2.nearest(pt) pt2 = pt # print('join_segments', i, pt1, pt2, pt2.X, pt2.Z) if pt1 and pt2: if segments[i].bulge != 0: nseg = Segment(pt1, pt2) rad = segments[i].get_centre_point().distance_to(pt1) if segments[i].bulge < 0: rad = 0 - rad nseg.set_bulge_from_radius(rad) segmentgroupOut.add_segment(nseg) else: segmentgroupOut.add_segment(Segment(pt1, pt2)) else: # No Intersections found. Return the segment in its current state # print('join_segments - No Intersection found for index:', i) segmentgroupOut.add_segment(segments[i]) self.segments = segmentgroupOut.get_segments() self.clean_offset_path()
def join_segments(self): """join segments of the segmentgroup""" segments = self.get_segments() segmentgroupOut = SegmentGroup() for i in range(len(segments)): pt1 = segments[i].start pt2 = segments[i].end if i != 0: seg1 = segments[i - 1] intersect, pt = seg1.intersect(segments[i], extend=True) if intersect: if type(pt) is list: pt = pt1.nearest(pt) pt1 = pt if i != len(segments) - 1: seg2 = segments[i + 1] intersect2, pt = seg2.intersect(segments[i], extend=True) if intersect2: if type(pt) is list: pt = pt2.nearest(pt) pt2 = pt if pt1 and pt2: if segments[i].bulge != 0: rad = segments[i].get_centre_point().distance_to(pt1) nseg = Segment(pt1, pt2) nseg.derive_bulge(segments[i], rad) segmentgroupOut.add_segment(nseg) else: segmentgroupOut.add_segment(Segment(pt1, pt2)) else: # No Intersections found. Return the segment in its current state segmentgroupOut.add_segment(segments[i]) self.segments = segmentgroupOut.get_segments() self.clean_offset_path()
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
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)
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
def offset_path(self, step_over): # TODO Sort Edges to ensure they're in order. if step_over == 0: return self segs = self.get_segments() segmentgroup = SegmentGroup() for i in range(len(segs)): seg = segs[i] if seg.bulge != 0: if seg.bulge > 0: # get normal from end point to centre start_normal = seg.start.normalise_to( seg.get_centre_point()) end_normal = seg.end.normalise_to(seg.get_centre_point()) # get point in the direction of the normal with magnitude of step_over pt1 = start_normal.multiply(step_over) pt2 = end_normal.multiply(step_over) # get the new start and end points new_start = seg.start.add(pt1) new_end = seg.end.add(pt2) rad = seg.get_radius() - step_over else: # get normal from the centre to the end points start_normal = seg.get_centre_point().normalise_to( seg.start) end_normal = seg.get_centre_point().normalise_to(seg.end) # get point in the direction of the normal with magnitude of step_over pt1 = start_normal.multiply(step_over) pt2 = end_normal.multiply(step_over) # get the new start and end points new_start = pt1.add(seg.start) new_end = pt2.add(seg.end) rad = seg.get_radius() + step_over segment = Segment(new_start, new_end) segment.derive_bulge(seg, rad) if seg.bulge == 0: normal = seg.start.normalise_to(seg.end).rotate(-90) pt = normal.multiply(step_over) segment = Segment(pt.add(seg.start), pt.add(seg.end)) segmentgroup.add_segment(segment) segmentgroup.join_segments() return segmentgroup
def offsetPath(self, step_over): # TODO Sort Edges to ensure they're in order. if step_over == 0: return self segs = self.get_segments() segmentgroup = SegmentGroup() for i in range(len(segs)): seg = segs[i] if seg.bulge != 0: if seg.bulge > 0: vec = Vector().normalise(seg.start, seg.get_centre_point()) vec2 = Vector().normalise(seg.end, seg.get_centre_point()) pt = vec.multiply(step_over) pt2 = vec2.multiply(step_over) new_start = seg.start.add(pt) new_end = seg.end.add(pt2) new_start.X = new_start.X - step_over new_end.X = new_end.X - step_over rad = seg.get_radius() - step_over # print('offsetPath arc dims', new_start.X, new_start.Z, new_end.X, new_end.Z) else: vec = Vector().normalise(seg.get_centre_point(), seg.start) vec2 = Vector().normalise(seg.get_centre_point(), seg.end) pt = vec.multiply(step_over) pt2 = vec2.multiply(step_over) new_start = pt.add(seg.start) new_end = pt2.add(seg.end) rad = seg.get_radius() + step_over # seg.get_centre_point().distance_to(new_start) segment = Segment(new_start, new_end) if seg.bulge < 0: rad = 0 - rad segment.set_bulge_from_radius(rad) if seg.bulge == 0: vec = Vector().normalise(seg.start, seg.end) vec = vec.rotate_x(-1.570796) pt = vec.multiply(step_over) segment = Segment(pt.add(seg.start), pt.add(seg.end)) segmentgroup.add_segment(segment) segmentgroup.join_segments() return segmentgroup
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
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)
class test_segment(unittest.TestCase): """Test for segment.py""" 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) def test_get_angle(self): angle = self.lineSegment1.get_angle() self.assertEqual(angle, 180) arcAngle = self.arcSegment1.get_angle() self.assertEqual(arcAngle, 3.931174892989316) def test_set_bulge(self): tempSegment = self.lineSegment1 tempSegment.set_bulge(3.931174892989316) self.assertEqual(tempSegment.bulge, 1.5) def test_set_bulge_from_radius(self): tempSegment = self.lineSegment1 tempSegment.set_bulge_from_radius(76.60323462854265) self.assertEqual(tempSegment.bulge, 0.6666666666666667) 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)) def test_get_radius(self): lineRadius = self.lineSegment1.get_radius() self.assertEqual(lineRadius, 0) arcRadius = self.arcSegment1.get_radius() self.assertEqual(arcRadius, 76.60323462854265) def test_get_rotation(self): angle = self.lineSegment1.get_rotation() self.assertEqual(angle, 45) def test_get_extent_min(self): extentMinX = self.lineSegment2.get_extent_min('X') self.assertEqual(extentMinX, self.pt5.X) extentMinY = self.lineSegment2.get_extent_min('Y') self.assertEqual(extentMinY, self.pt5.Y) extentMinZ = self.lineSegment2.get_extent_min('Z') self.assertEqual(extentMinZ, self.pt6.Z) AecExtentMinX = self.arcSegment2.get_extent_min('X') self.assertEqual(AecExtentMinX, self.pt8.X) AecExtentMinY = self.arcSegment2.get_extent_min('Y') self.assertEqual(AecExtentMinY, self.pt5.Y) AecExtentMinZ = self.arcSegment2.get_extent_min('Z') self.assertEqual(AecExtentMinZ, 46.68997508893331) def test_get_extent_max(self): extentMaxX = self.lineSegment2.get_extent_max('X') self.assertEqual(extentMaxX, self.pt6.X) extentMaxY = self.lineSegment2.get_extent_max('Y') self.assertEqual(extentMaxY, self.pt5.Y) extentMaxZ = self.lineSegment2.get_extent_max('Z') self.assertEqual(extentMaxZ, self.pt5.Z) AecExtentMaxX = self.arcSegment2.get_extent_max('X') self.assertEqual(AecExtentMaxX, -239.0558582444) AecExtentMaxY = self.arcSegment2.get_extent_max('Y') self.assertEqual(AecExtentMaxY, -76.60585824440003) AecExtentMaxZ = self.arcSegment2.get_extent_max('Z') self.assertEqual(AecExtentMaxZ, self.pt7.Z) def test_get_all_axis_positions(self): allAxisPosX = self.lineSegment2.get_all_axis_positions('X') self.assertEqual(allAxisPosX, [self.pt5.X, self.pt6.X]) allAxisPosY = self.lineSegment2.get_all_axis_positions('Y') self.assertEqual(allAxisPosY, [self.pt5.Y, self.pt6.Y]) allAxisPosZ = self.lineSegment2.get_all_axis_positions('Z') self.assertEqual(allAxisPosZ, [self.pt5.Z, self.pt6.Z]) arcAllAxisPosX = self.arcSegment2.get_all_axis_positions('X') self.assertEqual(arcAllAxisPosX, [self.pt7.X, self.pt8.X, -239.0558582444]) arcAllAxisPosY = self.arcSegment2.get_all_axis_positions('Y') self.assertEqual(arcAllAxisPosY, [self.pt7.Y, self.pt8.Y, -76.60585824440003]) arcAllAxisPosZ = self.arcSegment2.get_all_axis_positions('Z') self.assertEqual(arcAllAxisPosZ, [self.pt7.Z, self.pt8.Z, 46.68997508893331]) def test_get_length(self): length = self.lineSegment1.get_length() self.assertEqual(length, 141.4213562373095) arcSegmentLength = self.arcSegment1.get_length() self.assertEqual(arcSegmentLength, 141.4213562373095) def test_get_eta(self): eta = self.lineSegment1.get_eta() self.assertEqual(eta, 90) arcEta = self.arcSegment1.get_eta() self.assertEqual(arcEta, 1.965587446494658) def test_get_epsilon(self): epsilon = self.lineSegment1.get_epsilon() self.assertEqual(epsilon, 0) arcEpsilon = self.arcSegment1.get_epsilon() self.assertEqual(arcEpsilon, 0.982793723247329) def test_get_phi(self): phi = self.lineSegment1.get_phi() self.assertEqual(phi, -88.42920367320511) arcPhi = self.arcSegment1.get_phi() self.assertEqual(arcPhi, 0.5880026035475675) def test_is_same(self): lineComparison = self.lineSegment1.is_same(self.lineSegment1) self.assertTrue(lineComparison) arcComparison = self.arcSegment1.is_same(self.arcSegment1) self.assertTrue(arcComparison) lineArcComparison = self.lineSegment1.is_same(self.arcSegment1) self.assertFalse(lineArcComparison) 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)
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
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 props = {} props['min_dia'] = 0 props['extra_dia'] = 0 props['start_offset'] = 0 props['end_offset'] = 0
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)) # Define stock bounds stockPt1 = Point(0, 0, 15) stockPt2 = Point(-25, 0, -55) StockBoundingBox = BoundBox(stockPt1, stockPt2) # Define Operations Properties params = {} params['min_dia'] = 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)
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