def mill_temples(outdir, temples, order): #TODO: Replace with information in materials database print 'Creating milling program for temples' top_thickness = 4 # Assume 4mm temple top_raw = 4 if order.get("temple_material"): top_raw = order["temple_material"].get("top_raw_thickness") or order["temple_material"].get("top_thickness") or top_thickness print 'top raw', top_raw # Automatically determine some surfacing. The bottom thickness # is a lamination and should be thin. It should be thinned to 1mm. # The top should be thinned to bring total finished thickness to 6mm or less. thin_back = 0 if top_raw > top_thickness: thin_back = top_raw - top_thickness l_temple = temples['left_temple_contour'] r_temple = temples['right_temple_contour'] offset = frame_offset(l_temple) # Calculate entry points for bevelling operation program = [ cam.setup(), cam.select_fixture("blank_clamp"), cam.retract_spindle(), cam.rapid([0,0]), cam.activate_pin("stock_clamp"), surface_back(thin_back), index_holes(top_raw), # cam.rapid(l_temple[0]+[0]), # cam.contour(l_temple, True), # cam.move(l_temple[0]), # cam.rapid(r_temple[0]), # cam.contour(r_temple, True), rough_temple_bevel(l_temple, thin_back), rough_temple_bevel(r_temple, thin_back), cam.change_tool("1/16in endmill"), cam.rapid([0,0]), temple_hinge_pockets(temples, thin_back), cam.change_tool("dovetail"), bevel_temple(l_temple, thin_back), bevel_temple(r_temple, thin_back), temple_hinge_clearance(l_temple, thin_back), temple_hinge_clearance(r_temple, thin_back), cam.retract_spindle(), cam.deactivate_pin("stock_clamp"), cam.change_tool("1/8in endmill"), cam.end_program() ] open(outdir + "/temples_milling.ngc", "w").write(to_string(program))
def mill_hinges(outdir): """Creates the g-code for the first milling operation. The first milling operation is done on an unregistered plastic blank, so includes creating registration holes for subsequent operations.""" y_offsets = [y*15 for y in range(-5, 6)] x_offsets = [x*7 for x in range(-3, 4)] hinge = hinges.get_hinge(2); contour = hinge['face_contour'] contours = [] erode = poly.erode(1.5875/2, contour) while len(erode) > 0: if len(erode) >= 1: contours.append(erode[0]) else: break erode = poly.erode(1.5875/2, contours[-1]) program = [ cam.setup(), cam.select_fixture("blank_clamp"), cam.retract_spindle(), cam.activate_pin("stock_clamp"), cam.change_tool("1/16in endmill"), cam.rapid([0,0]), cam.start_spindle(20000), cam.dwell(3), # cam.pocket(contours, -1, -1), # cam.rapid([None, None, 20.0]), # cam.change_tool("1mm drill"), # cam.start_spindle(4500), # [cam.rmp(p + [-2.5], retract=10.0) for p in hinge['face_holes']], ] for y_offset in y_offsets: for x_offset in x_offsets: program += [ cam.rapid([x_offset, y_offset]), cam.temporary_offset((0,0)), cam.pocket(contours, -1.2, -1.2), cam.rapid([None, None, 20.0]), cam.remove_temporary_offset(), ] # program += [ # cam.change_tool("1mm drill"), # cam.start_spindle(4500), # ] # for y_offset in y_offsets: # for x_offset in x_offsets: # program += [ # cam.rapid([x_offset, y_offset]), # cam.temporary_offset((0,0)), # [cam.rmp(p + [-2.5], retract=10.0) for p in hinge['face_holes']], # cam.rapid([None, None, 20.0]), # cam.remove_temporary_offset(), # ] program += [ cam.deactivate_pin("stock_clamp"), cam.end_program(), ] open(outdir + "/face_stage1.ngc", "w").write(to_string(program))
def mill_fronts(outdir, order): """Creates the g-code for the first milling operation. The first milling operation is done on an unregistered plastic blank, so includes creating registration holes for subsequent operations.""" # Initial thickness of the forward-facing lamination. 0 if no lamination. top_thickness = 6 bottom_thickness = 0 top_raw = 6 bottom_raw = 0 if order.get("face_material"): top_thickness = order["face_material"].get("top_thickness") bottom_thickness = order["face_material"].get("bottom_thickness") or 0 top_raw = order["face_material"].get("top_raw_thickness") or top_thickness bottom_raw = order["face_material"].get("bottom_raw_thickness") or bottom_thickness frame_thickness = top_thickness + bottom_thickness machining_z_offset = bottom_raw - bottom_thickness # top_thickness = 6 # bottom_thickness = 0 # total_thickness = 6 # top_raw = 0 # Automatically determine some surfacing. The bottom thickness # is a lamination and should be thin. It should be thinned to 1mm. # The top should be thinned to bring total finished thickness to 6mm or less. thin_back = 0 if bottom_raw > bottom_thickness: thin_back = bottom_raw - bottom_thickness thin_front = 0 if top_raw > top_thickness: thin_front = top_raw - top_thickness # The machine has the stock clamp oriented 90 degrees to the way the # software creates the contours. face_c = poly.rotate_90(order["face_con"]) left_lens_c = poly.rotate_90(order["lhole_con"]) right_lens_c = poly.mirror_y(left_lens_c, True) face_c = face_c + poly.reverse(poly.mirror_y(face_c, False))[1:] temple_height = abs(order["ltemple_con"][0][1] - order["ltemple_con"][-1][1]) msg = check_frame_size(left_lens_c) if msg: print msg sys.exit(1) # Instead of offset, we'll make sure this thing is centered on the stock offset = frame_offset(face_c) top = poly.top(face_c) bottom = poly.bottom(face_c) left = poly.left(face_c) right = poly.right(face_c) print 'frame bounding box: ', top, bottom, left, right y_shift = (top + bottom)/2 x_shift = (left + right)/2 print 'x and y shift', x_shift, y_shift face_c = poly.translate(face_c, -x_shift, -y_shift) left_lens_c = poly.translate(left_lens_c, -x_shift, -y_shift) right_lens_c = poly.translate(right_lens_c, -x_shift, -y_shift) # Groove for lenses is 2/3 of the distance from back to front. # Here we're calculating the actual cutting depth so we need to add # back the material that we surfaced away from the back. groove_depth = -(float(machining_z_offset) + (2.0/3)*float(frame_thickness)) hinge_loc = order["ltemple_con"][0][1] - (order["ltemple_con"][0][1] - order["ltemple_con"][-1][1])/2 size_info = order.get('size_info') if not size_info and order.get('usersizes'): # Legacy order size_info = order.get('usersizes') size_info["noseradius"] = size_info["nose_radius"] size_info["noseheight"] = size_info["nose_height"] size_info["splayangle"] = size_info["nose_splayangle"] size_info["ridgeangle"] = size_info["nose_ridgeangle"] generic = not size_info or len(size_info) == 0 generic = True # TESTING program = [ cam.setup(), cam.select_fixture("blank_clamp"), cam.retract_spindle(), cam.activate_pin("stock_clamp"), cam.rapid([0,0]), surface_front(thin_front), surface_back(thin_back), cam.change_tool("1/8in endmill"), cam.rapid([0, 0]), # Note that X and Y parameters in the order are switched from our system #TODO: replace the thickness offset with the thickness of the TEMPLE, not the fronts. index_holes(frame_thickness+machining_z_offset), lens_holes(left_lens_c, right_lens_c, frame_thickness + machining_z_offset), lens_groove(left_lens_c, right_lens_c, groove_depth), # rough_nose_contour( # float(size_info["noseradius"]), # float(size_info["noseheight"]), # float(size_info["splayangle"]), # float(size_info["ridgeangle"]), # face_c, frame_thickness, machining_z_offset, -x_shift ), face_hinge_pockets(order.get("lhinge") or 1, hinge_loc, order["ltemple_x"], (-x_shift, -y_shift), machining_z_offset), #nose_pads(order, thickness), nose_contour( float(size_info["noseradius"]), float(size_info["noseheight"]), float(size_info["splayangle"]), float(size_info["ridgeangle"]), face_c, frame_thickness, machining_z_offset, -x_shift ), # nose_contour( # 7.0, 8.0, 30.0, 32.0, face_c, frame_thickness, machining_z_offset, -x_shift), #generic_nose_contour(face_c, frame_thickness, machining_z_offset, -x_shift), cam.retract_spindle(), cam.deactivate_pin("stock_clamp"), cam.change_tool("1/8in endmill"), # cam.rapid([face_c[0][0], face_c[0][1], -thin_back] ), # cam.contour(face_c, True), cam.end_program(), ] print 'Writing face milling program to ', outdir + "/face_stange1.ngc" open(outdir + "/face_stage1.ngc", "w").write(to_string(program))
def mill_lenses(outdir, order): def to_polar(polyline): return [[-math.sqrt(p[0]**2 + p[1]**2), math.degrees(math.atan2(p[1],p[0])) + 180] for p in polyline] """ Creates g-code for milling the left and right lenses for the frames.""" lens = g.Polygon(order['lhole_con']) x = lens.bounding_box() box = lens.bounding_box() center = g.Point((box.p2.x+box.p1.x)/2, (box.p2.y+box.p1.y)/2) shift_to_origin = g.Vector(-center.x, -center.y) lens = g.translate_polygon(lens, shift_to_origin) polar = g.polygon_to_uniform_polar(lens, 1500) # Inflate the polar form by 1/2 the diameter of the cutter, and convert # the angles to degrees tau = math.pi * 2 conv = 360/tau roughing = [(pt.theta*conv, pt.r+4.77) for pt in polar] # Expand for the roughing cut # left_lens_rough = poly.dilate(4.77, left_lens) # Convert to polar coordinates # left_lens_roughing_polar = to_polar(left_lens_rough) # Start the cut from 0 degrees # angle_list = [p[1] for p in left_lens_roughing_polar] # zero_idx = angle_list.index(min(angle_list)) # left_lens_roughing_polar = left_lens_roughing_polar[zero_idx:] + left_lens_roughing_polar[:zero_idx] # Cut it down to every 0.2 degrees # coarse = [] # for idx, pt in enumerate(left_lens_roughing_polar): # if idx == 0 or (pt[1]-coarse[-1][1]) >= 0.2: # coarse.append(pt) # The polar distances aren't correct quite. That's because the conversion assumed a flat # surface, but we'll actually be bending that contour around a sphere. The lens is already # spherical. So we need to adjust inwards a bit to account for the x distance actually being an arc # distance. # The radius of the sphere is 88mm (base 6 lens). ArcLength = Radius * angle, and chord # length is sin(angle) * radius. roughing = [(p[0], math.sin(-p[1]/88) * 88) for p in roughing] roughing.sort(key=lambda pt: pt[0]) closest = max([p[1] for p in roughing]) if abs(closest) < 22.5: print "Error! Cannot cut lens, it's too small.", closest roughing_reversed = [[-1*(math.degrees(-math.radians(p[1]))+360), p[1]] for p in roughing] program = [ cam.setup(), cam.select_fixture("lens_clamp"), cam.retract_spindle(), cam.change_tool("1/4in endmill"), cam.start_spindle(20000), cam.rapid([-50, 0]), ["G1 Z0 F500"], cam.polar_contour(roughing), ["G1 X-50"], ["G1 A0"], cam.stop_spindle(), cam.retract_spindle(), cam.end_program(), ] open(outdir + "/left_lens.ngc", "w").write(to_string(program)) program = [ cam.setup(), cam.select_fixture("lens_clamp"), cam.retract_spindle(), cam.change_tool("1/4in endmill"), cam.start_spindle(20000), cam.rapid([-50, 0]), ["G1 Z0 F500"], cam.polar_contour(roughing_reversed), ["G1 X-50"], ["G1 A0"], cam.stop_spindle(), cam.retract_spindle(), cam.end_program(), ] open(outdir + "/right_lens.ngc", "w").write(to_string(program))
def mill_fronts(outdir, order): """Creates the g-code for the first milling operation. The first milling operation is done on an unregistered plastic blank, so includes creating registration holes for subsequent operations.""" #TODO: Replace with information in materials database # Initial thickness of the forward-facing lamination. 0 if no lamination. front_surface_thickness = 0 # The final desired thickness of the fronto facing lamination. Must # be equal to or less than the front_surface_thickness. final_front_thickness = 0 # Initial thickness of the face side lamination. Use this thickness only if # stock is solid back_surface_thickness = 4 # The final thickness of the left and right extremes of the frame where the # hinge will go. Must be equal to or less than back_surface_thickness. hinge_thickness = 4 # The thickness of the highest point of the nosepad nosepad_thickness = 4 # Final thickness of the main part of the frame. Must be equal to or less than # the back_surface_thickness. final_back_thickness = 4 thickness = final_front_thickness + final_back_thickness front_surface_removal = final_front_thickness - front_surface_thickness back_surface_removal = final_back_thickness - back_surface_thickness # The machine has the stock clamp oriented 90 degrees to the way the # software creates the contours. face_c = poly.rotate_90(order["face_con"]) left_lens_c = poly.rotate_90(order["lhole_con"]) right_lens_c = poly.rotate_90(order["rhole_con"]) temple_height = abs(order["ltemple_con"][0][1] - order["ltemple_con"][-1][1]) msg = check_frame_size(face_c) if msg: print msg sys.exit(0) print 'milling front with hinge', order['lhinge'], order['rhinge'] offset = frame_offset(face_c) groove_height = back_surface_removal + (thickness / 2) print 'groove', groove_height, back_surface_removal, (thickness / 2) program = [ cam.setup(), cam.select_fixture("blank_clamp"), cam.retract_spindle(), cam.activate_pin("stock_clamp"), surface_front(front_surface_removal), # surface_back(back_surface_removal), cam.change_tool("1/8in endmill"), cam.rapid([0, 0]), cam.temporary_offset(offset), # Note that X and Y parameters in the order are switched from our system #TODO: replace the thickness offset with the thickness of the TEMPLE, not the fronts. index_holes([face_c], back_surface_thickness), lens_holes(left_lens_c, right_lens_c, back_surface_thickness), lens_groove(left_lens_c, right_lens_c, back_surface_removal - (thickness / 2)), # contour_face( # back_surface_removal, # back_surface_thickness - hinge_thickness, # back_surface_thickness - nosepad_thickness, # temple_height, # face_c, left_lens_c, order['lhinge_y']), face_hinge_pockets(order["lhinge"], order["lhinge_y"], order["ltemple_x"]), # nose_pads(order, thickness), nose_contour(order["nose_rad"], order["nose_h"], order["nose_sa"], order["nose_ra"], face_c, back_surface_thickness), cam.retract_spindle(), cam.deactivate_pin("stock_clamp"), cam.end_program(), ] open(outdir + "/face_stage1.ngc", "w").write(to_string(program))
def mill_fronts(outdir, order): """Creates the g-code for the first milling operation. The first milling operation is done on an unregistered plastic blank, so includes creating registration holes for subsequent operations.""" #TODO: Replace with information in materials database # Initial thickness of the forward-facing lamination. 0 if no lamination. front_surface_thickness = 0 # The final desired thickness of the fronto facing lamination. Must # be equal to or less than the front_surface_thickness. final_front_thickness = 0 # Initial thickness of the face side lamination. Use this thickness only if # stock is solid back_surface_thickness = 4 # The final thickness of the left and right extremes of the frame where the # hinge will go. Must be equal to or less than back_surface_thickness. hinge_thickness = 4 # The thickness of the highest point of the nosepad nosepad_thickness = 4 # Final thickness of the main part of the frame. Must be equal to or less than # the back_surface_thickness. final_back_thickness =4 thickness = final_front_thickness + final_back_thickness front_surface_removal = final_front_thickness - front_surface_thickness back_surface_removal = final_back_thickness - back_surface_thickness # The machine has the stock clamp oriented 90 degrees to the way the # software creates the contours. face_c = poly.rotate_90(order["face_con"]) left_lens_c = poly.rotate_90(order["lhole_con"]) right_lens_c = poly.rotate_90(order["rhole_con"]) temple_height = abs(order["ltemple_con"][0][1] - order["ltemple_con"][-1][1]) msg = check_frame_size(face_c) if msg: print msg sys.exit(0) print 'milling front with hinge', order['lhinge'], order['rhinge'] offset = frame_offset(face_c) groove_height = back_surface_removal + (thickness/2) print 'groove', groove_height, back_surface_removal, (thickness/2) program = [ cam.setup(), cam.select_fixture("blank_clamp"), cam.retract_spindle(), cam.activate_pin("stock_clamp"), surface_front(front_surface_removal), # surface_back(back_surface_removal), cam.change_tool("1/8in endmill"), cam.rapid([0, 0]), cam.temporary_offset(offset), # Note that X and Y parameters in the order are switched from our system #TODO: replace the thickness offset with the thickness of the TEMPLE, not the fronts. index_holes([face_c], back_surface_thickness), lens_holes(left_lens_c, right_lens_c, back_surface_thickness), lens_groove(left_lens_c, right_lens_c, back_surface_removal - (thickness/2)), # contour_face( # back_surface_removal, # back_surface_thickness - hinge_thickness, # back_surface_thickness - nosepad_thickness, # temple_height, # face_c, left_lens_c, order['lhinge_y']), face_hinge_pockets(order["lhinge"], order["lhinge_y"], order["ltemple_x"]), # nose_pads(order, thickness), nose_contour(order["nose_rad"], order["nose_h"], order["nose_sa"], order["nose_ra"], face_c, back_surface_thickness), cam.retract_spindle(), cam.deactivate_pin("stock_clamp"), cam.end_program(), ] open(outdir + "/face_stage1.ngc", "w").write(to_string(program))