def mill_temples(outdir, temples, temple_length):
#TODO: Replace with information in materials database
    front_surface_thickness = 0
    back_surface_thickness = 4
    final_front_thickness = 0
    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

    r_temple = poly.rotate_90(temples['right_temple_contour'])
    l_temple = poly.rotate_90(temples['left_temple_contour'])

    offset = frame_offset(l_temple)
    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/16in endmill"),
        cam.rapid([0,0]),
        cam.temporary_offset(offset),
        temple_hinge_pockets(temples),
        index_holes([l_temple, r_temple], thickness),
        #thin_temples([l_temple, r_temple], temple_length),
    ]
    open(outdir + "/temples_milling.ngc", "w").write(to_string(program))
Exemple #2
0
def mill_temples(outdir, temples, temple_length):
    #TODO: Replace with information in materials database
    front_surface_thickness = 0
    back_surface_thickness = 4
    final_front_thickness = 0
    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

    r_temple = poly.rotate_90(temples['right_temple_contour'])
    l_temple = poly.rotate_90(temples['left_temple_contour'])

    offset = frame_offset(l_temple)
    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/16in endmill"),
        cam.rapid([0, 0]),
        cam.temporary_offset(offset),
        temple_hinge_pockets(temples),
        index_holes([l_temple, r_temple], thickness),
        #thin_temples([l_temple, r_temple], temple_length),
    ]
    open(outdir + "/temples_milling.ngc", "w").write(to_string(program))
Exemple #3
0
def temple_hinge_pockets(temples):
    # We're operating in a 90 degree rotated fixture
    #l_hinge = poly.rotate_90(temples["left_hinge_contour"])
    #r_hinge = poly.rotate_90(temples["right_hinge_contour"])

    l_hinge = temples["left_hinge_contour"]
    r_hinge = temples["right_hinge_contour"]
    if not poly.is_ccw(l_hinge):
        l_hinge = poly.reverse(l_hinge)
    if not poly.is_ccw(r_hinge):
        r_hinge = poly.reverse(r_hinge)

    left_hinge_pocket_contours = []
    while len(l_hinge) > 0:
        l_hinge = poly.erode(1.5875 / 2, l_hinge)
        if len(l_hinge) > 0:
            l_hinge = l_hinge[0]
            left_hinge_pocket_contours.append(l_hinge)

    right_hinge_pocket_contours = []
    while len(r_hinge) > 0:
        r_hinge = poly.erode(1.5875 / 2, r_hinge)
        if len(r_hinge) > 0:
            r_hinge = r_hinge[0]
            right_hinge_pocket_contours.append(r_hinge)
    r = [
        cam.comment("Hinge Pockets"),
        cam.feedrate(750),
        cam.change_tool("1/16in endmill"),
        cam.start_spindle(15000),
        cam.dwell(3),
        cam.comment("Right Hinge Pocket"),
        cam.pocket(right_hinge_pocket_contours,
                   -abs(temples['pocket_depth']),
                   retract=0),
        cam.rapid([None, None, 20.0]),
        cam.comment("Left Hinge Pocket"),
        cam.pocket(left_hinge_pocket_contours,
                   -abs(temples['pocket_depth']),
                   retract=0),
        cam.rapid([None, None, 20.0]),
        cam.comment("Hinge Holes"),
        cam.change_tool("1mm drill"),
        cam.start_spindle(4500),
        cam.dwell(2),
        [
            cam.rmp(p + [-8.0], retract=10.0)
            for p in temples['right_hinge_holes']
        ],
        [
            cam.rmp(p + [-8.0], retract=10.0)
            for p in temples['left_hinge_holes']
        ],
        cam.rapid([None, None, 20.0]),
        cam.move([None, None, 0]),
        cam.contour(poly.rotate_90(temples['left_temple_contour']), True),
        cam.contour(poly.rotate_90(temples['right_temple_contour']), True),
    ]
    return r
def temple_hinge_pockets(temples):
    # We're operating in a 90 degree rotated fixture
    #l_hinge = poly.rotate_90(temples["left_hinge_contour"])
    #r_hinge = poly.rotate_90(temples["right_hinge_contour"])

    l_hinge = temples["left_hinge_contour"]
    r_hinge = temples["right_hinge_contour"]
    if not poly.is_ccw(l_hinge):
        l_hinge = poly.reverse(l_hinge)
    if not poly.is_ccw(r_hinge):
        r_hinge = poly.reverse(r_hinge)

    left_hinge_pocket_contours = [];
    while len(l_hinge) > 0:
        l_hinge = poly.erode(1.5875/2, l_hinge)
        if len(l_hinge) > 0:
            l_hinge = l_hinge[0]
            left_hinge_pocket_contours.append(l_hinge)

    right_hinge_pocket_contours = [];
    while len(r_hinge) > 0:
            r_hinge = poly.erode(1.5875/2, r_hinge)
            if len(r_hinge) > 0:
                r_hinge = r_hinge[0]
                right_hinge_pocket_contours.append(r_hinge)
    r = [
        cam.comment("Hinge Pockets"),
        cam.feedrate(750),
        cam.change_tool("1/16in endmill"),
        cam.start_spindle(15000),
        cam.dwell(3),
        cam.comment("Right Hinge Pocket"),
        cam.pocket(right_hinge_pocket_contours, -abs(temples['pocket_depth']), retract=0),
        cam.rapid([None, None, 20.0]),
        cam.comment("Left Hinge Pocket"),
        cam.pocket(left_hinge_pocket_contours, -abs(temples['pocket_depth']), retract=0),
        cam.rapid([None, None, 20.0]),
        cam.comment("Hinge Holes"),
        cam.change_tool("1mm drill"),
        cam.start_spindle(4500),
        cam.dwell(2),
        [cam.rmp(p + [-8.0], retract=10.0) for p in temples['right_hinge_holes']],
        [cam.rmp(p + [-8.0], retract=10.0) for p in temples['left_hinge_holes']],
        cam.rapid([None, None, 20.0]),

        cam.move([None, None, 0]),
        cam.contour(poly.rotate_90(temples['left_temple_contour']), True),
        cam.contour(poly.rotate_90(temples['right_temple_contour']), True),
    ]
    return r
Exemple #5
0
def nose_poly(r, h, sa, ra, xfloor, erode=0.0, depth=0.0):
    """
    Generates an open contour polygon to match the described nose.
    r, h, sa and ra are standard radius, height of intercept, splay angle and ridge angle parameters (in radians)
    yfloor is the end point in the y direction of the nose side lines, for getting the right size of contour
    optional erode parameter will erode the contour by the given amount, usually the radius of the cutting tool
    optional depth parameter will generate a contour that matches the nose profile at the given depth
    """

    nose_radius = r
    r -= erode
    h -= erode
    half_sa = sa / 2.0
    xfloor = float(xfloor)
    depth = float(depth)
    depth_displacement = -depth / math.tan(ra)
    translation = h - depth_displacement - nose_radius
    xfloor -= translation

    p2 = tangent_point(sa, r)
    p1 = [
        p2[0] +
        math.sin(half_sa) * abs(xfloor) / math.sin(tau / 4.0 - half_sa), xfloor
    ]
    rpoly = poly.arc(r, half_sa, tau / 2.0 - half_sa)
    p3 = [-p2[0], p2[1]]
    p4 = [-p1[0], p1[1]]

    base = [p1] + [p2] + rpoly + [p3] + [p4]

    ret = poly.translate(base, 0.0, translation)

    return poly.rotate_90(ret)
Exemple #6
0
def face_hinge_pockets(hinge_num, hinge_height, temple_position, centering_shift, thin_back):

    print 'Generating face hinge pockets', hinge_num
    xposition = hinge_height;
    yposition = temple_position+3.0; # 4mm for the temple, but less 1mm for temple hinge pocket
    print 'Position is ', xposition, yposition
    left_hinge = hinges.get_hinge(hinge_num)
    print 'Got left hinge'
    right_hinge = hinges.get_hinge(hinge_num, False)
    print 'Retrieved hinge contours'
    left_translate = [xposition, yposition]
    right_translate = [xposition, -yposition]
    print 'Calculated hinge translations'
    #right_translate = [xposition, 0]
    # Adjust by pocket depth of hinge
    #pocket_depth = left_hinge['pocket_depth']+thin_back

    pocket_depth = 1 + thin_back
    drill_depth = -thin_back - 2.0

    left_contour = poly.mirror_x(poly.rotate_90(left_hinge["face_contour"]), False)
    right_contour = poly.mirror_x(poly.rotate_90(right_hinge["face_contour"]), False)
    left_holes = poly.mirror_x(poly.rotate_90(left_hinge["face_holes"]), False)
    right_holes = poly.mirror_x(poly.rotate_90(right_hinge["face_holes"]), False)
    left_contour = poly.translate(left_contour, left_translate[0], -left_translate[1])
    right_contour = poly.translate(right_contour, right_translate[0], -right_translate[1])
    left_holes = poly.translate(left_holes, left_translate[0], -left_translate[1])
    right_holes = poly.translate(right_holes, right_translate[0], -right_translate[1])

    # Now center everything on the stock
    left_contour = poly.translate(left_contour, centering_shift[0], -centering_shift[1])
    right_contour = poly.translate(right_contour, centering_shift[0], -centering_shift[1])
    left_holes = poly.translate(left_holes, centering_shift[0], -centering_shift[1])
    right_holes = poly.translate(right_holes, centering_shift[0], -centering_shift[1])

    if not poly.is_ccw(left_contour):
        left_contour = poly.reverse(left_contour)
    if not poly.is_ccw(right_contour):
        right_contour = poly.reverse(right_contour)

    left_hinge_pocket_contours = [];
    while len(left_contour) > 0:
        left_contour = poly.erode(1.5875/2, left_contour)
        if len(left_contour) > 0:
            left_contour = left_contour[0]
            left_hinge_pocket_contours.append(left_contour)

    right_hinge_pocket_contours = [];
    while len(right_contour) > 0:
            right_contour = poly.erode(1.5875/2, right_contour)
            if len(right_contour) > 0:
                right_contour = right_contour[0]
                right_hinge_pocket_contours.append(right_contour)
    r = [
        cam.comment("Hinge Pockets"),
        cam.feedrate(750),
        cam.change_tool("1/16in endmill"),
        cam.start_spindle(20000),
        cam.dwell(3),
        cam.comment("Right Hinge Pocket"),
        cam.pocket(right_hinge_pocket_contours, -abs(pocket_depth), retract=-abs(pocket_depth)),
        cam.rapid([None, None, 20.0]),
        cam.comment("Left Hinge Pocket"),
        cam.pocket(left_hinge_pocket_contours, -abs(pocket_depth), retract=-abs(pocket_depth)),
        cam.rapid([None, None, 20.0]),
        cam.comment("Hinge Holes"),
        cam.change_tool("1mm drill"),
        cam.start_spindle(5000),
        cam.dwell(2),
        [cam.rmp(p + [drill_depth], retract=10.0) for p in right_holes],
        [cam.rmp(p + [drill_depth], retract=10.0) for p in left_holes],
        cam.rapid([None, None, 20.0]),
    ]
    return r
Exemple #7
0
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))
Exemple #8
0
def main():
    """Run as a command line program."""
    parser = OptionParser()
    parser.add_option("-i", "--infile", dest="infile",
                      help="read specification from INFILE", metavar="INFILE")
    parser.add_option("-o", "--out", dest="outname",
            help="Name of output director", metavar="OUTDIR")
    parser.add_option("-u", "--url", dest="url",
                      help="read specification from URL", metavar="URL")
    (options, args) = parser.parse_args()
    if options.infile == None and options.url == None:
        log("Insufficient arguments.")
        parser.print_help()
        sys.exit(0)
    infile = open(options.infile) if options.infile else urllib.urlopen(options.url)
    o = json.loads(infile.read())

#    if o["usersizes"]:
#        # This is a legacy order - we need to scale the temples because
#        # it hasn't been done already.
#        templescale = float(o["usersizes"]["temple_length"]) / 100.0
#        temp = o["ltemple_con"]
#        hinge = o["lhinge"]
#        for i in range(1, len(temp)-2):
#            temp[i][0] = temp[i][0] * templescale;

    order_id = o.get("order_id") or "testorder"
    # outname = datetime.date.today().isoformat() + "/" + order_id
#    if options.outname == None:
#        print "extracting out name from ", options.infile
#        outname = options.infile.split("/")[-1]
#        outname = outname.split(".")[0]
#        outname = datetime.date.today().isoformat() + "/" + outname
#        print "out file is ", outname
#    else:
#        outname = options.outname
    # Create the output director
    #order_dir = "/Users/rodfrey/Dropbox/guild_orders/" + outname
    #order_dir = "/Volumes/Untitled/" + outname
    # order_dir = "/Users/ana0/Development/framebot2/" + outname
    order_dir = options.outname
    if not os.path.exists(order_dir):
        os.makedirs(order_dir)
        print 'Created dir', order_dir
    else:
        for i in range(1, 101):
            candidate = order_dir + "_" + str(i)
            print 'checking directory', candidate
            if i == 100:
                print 'Too many directories!  Could not create order directory'
                sys.exit(1)
            if not os.path.exists(candidate):
                order_dir = candidate
                os.makedirs(order_dir)
                print "Created dir", order_dir
                break



    # Create the milling program for the lens holes/groove, hinge pockets, etc.
    # and the dxf for the laser for the fronts
    mill_fronts(order_dir, o)
    laser_face = o['face_con']
    laser_face = laser_face + poly.reverse(poly.mirror_x(laser_face, False))[1:]

    # Rearrange the face curve a bit so the laser starts outside the curve.
    # Otherwise it leaves a little scar where it starts.
    laser_face = poly.new_start(laser_face, poly.leftmost_index(laser_face))
    laser_face.append(laser_face[0]) # Close the curve

    first_vector = [laser_face[1][0]-laser_face[0][0], laser_face[1][1]-laser_face[0][1]]
    unit = math.sqrt(first_vector[0]**2 + first_vector[1]**2)
    leadin_vector = [(4*first_vector[0])/unit,(4*first_vector[1])/unit]
    leadin_start = [laser_face[0][0] - leadin_vector[0], laser_face[0][1] - leadin_vector[1]]

    last_vector = [laser_face[-2][0]-laser_face[-1][0], laser_face[-2][1]-laser_face[-1][1]]
    unit = math.sqrt(last_vector[0]**2 + last_vector[1]**2)
    leadout_vector = [(4*last_vector[0])/unit,(4*last_vector[1])/unit]
    leadout_end = [laser_face[-1][0] + leadout_vector[0], laser_face[-1][1] + leadout_vector[1]]

#    laser_face.insert(0, leadin_start)
    create_dxf(order_dir + "/face_contour.dxf", [laser_face], close=False)

#    temple_dxf(o, order_dir + "/left_temple.dxf", 1, False)
#    temple_dxf(o, order_dir + "/right_temple.dxf", 1, True)


    # Arrange the temples to fit on the stock
    temples =  arrange_temple_curves(o['ltemple_con'], o.get('lhinge') or 1)
    left_hinge = poly.rotate_90(temples['left_hinge_contour'])
    right_hinge = poly.rotate_90(temples['right_hinge_contour'])
#
    l_temple = poly.rotate_90(temples['left_temple_contour']);
    r_temple = poly.rotate_90(temples['right_temple_contour']);
#
    create_dxf(order_dir + "/temple_contour.dxf",
            [poly.rotate_90(temples['left_temple_contour']),
             poly.rotate_90(temples['right_temple_contour'])[::-1],
#             left_hinge,
#             right_hinge,
            ],
            close_with_arc=False,
            close=False)

    mill_temples(order_dir, temples, o)
Exemple #9
0
def arrange_temple_curves(left_temple_contour, hinge):
    # Normalize temple to get origin at 0,0
    left_temple_contour = poly.translate(left_temple_contour, -left_temple_contour[0][0], -left_temple_contour[0][1])

    right_temple_contour = poly.mirror_x(left_temple_contour, False)

    left_hinge = hinges.get_hinge(hinge)
    right_hinge = hinges.get_hinge(hinge, False)
    hinge_y = (left_temple_contour[0][1]+left_temple_contour[-1][1])/2

    left_holes = left_hinge['temple_holes']
    right_holes = right_hinge['temple_holes'] # opposite direction.  FIX someday
    right_hinge_contour = right_hinge['temple_contour']
    left_hinge_contour = left_hinge['temple_contour']

    # y offset is mucked up because it's calculated from the center of the hinge boxing
    # square, not the center of the straight edge
    highpoint = poly.top(left_hinge_contour);
    lowpoint = poly.bottom(left_hinge_contour);
    y_offset = hinge_y-(lowpoint + (highpoint-lowpoint)/2.0) # Distance to move hinge to center it on temple

    # strategy for hinge placement.  Align corner of
    print left_temple_contour[0][0], left_temple_contour[-1][0]
    temple_x = left_temple_contour[0][0] - (left_temple_contour[0][0] - left_temple_contour[-1][0]) / 2
    x_offset =   temple_x - left_hinge_contour[0][0] - 2.5

    left_hinge_contour = poly.translate(left_hinge_contour, x_offset, y_offset)
    left_holes = poly.translate(left_holes, x_offset, y_offset)
    right_hinge_contour = poly.translate(right_hinge_contour, -x_offset, y_offset)
    right_holes = poly.translate(right_holes, -x_offset, y_offset)

    left_temple_contour = poly.rotate_90(left_temple_contour)
    left_hinge_contour = poly.rotate_90(left_hinge_contour)
    left_holes = poly.rotate_90(left_holes)
    right_temple_contour = poly.rotate(right_temple_contour, 90)
    right_hinge_contour = poly.rotate(right_hinge_contour, 90)
    right_holes = poly.rotate(right_holes, 90)

    # Move them apart so they're not touching
    height = poly.right(left_temple_contour) - poly.left(left_temple_contour)+1
    left_temple_contour = poly.translate(left_temple_contour, height, 0)
    left_holes = poly.translate(left_holes, height, 0)
    left_hinge_contour = poly.translate(left_hinge_contour, height, 0)
    right_temple_contour = poly.translate(right_temple_contour, -height, 0)
    right_holes = poly.translate(right_holes, -height, 0)
    right_hinge_contour = poly.translate(right_hinge_contour, -height, 0)



#    # Move left one left, right one right to offset them
    temple_width = poly.top(left_temple_contour) - poly.bottom(left_temple_contour)
    optimization_offset = (160-temple_width)/2.0
    print 'optimization offset', optimization_offset, temple_width
    left_temple_contour = poly.translate(left_temple_contour, 0, optimization_offset)
    left_holes = poly.translate(left_holes, 0, optimization_offset)
    left_hinge_contour = poly.translate(left_hinge_contour, 0, optimization_offset)

    right_temple_contour = poly.translate(right_temple_contour, 0, -optimization_offset)
    right_hinge_contour = poly.translate(right_hinge_contour, 0, -optimization_offset)
    right_holes = poly.translate(right_holes, 0, -optimization_offset)



    # Make sure they're not intersecting
#    translation_step = 2.5
#    intersection = poly.intersection(left_temple_contour, right_temple_contour)
#    while(len(intersection) > 0):
#        left_temple_contour = poly.translate(left_temple_contour, translation_step, 0)
#        left_holes = poly.translate(left_holes, translation_step, 0)
#        left_hinge_contour = poly.translate(left_hinge_contour, translation_step, 0)
#        right_temple_contour = poly.translate(right_temple_contour, -translation_step, 0)
#        right_holes = poly.translate(right_holes, -translation_step, 0)
#        right_hinge_contour = poly.translate(right_hinge_contour, -translation_step, 0)
#        intersection = poly.intersection(left_temple_contour, right_temple_contour)
    # Move them together until they touch (may will not have moved at all above because they are far)
    # then back off.
    #smaller translation step (was 1.0)
    translation_step = 0.1

    intersection = []
    while(len(intersection) == 0):
        print "still intersecting", len(intersection)
        left_temple_contour = poly.translate(left_temple_contour, -translation_step, 0)
        left_holes = poly.translate(left_holes, -translation_step, 0)
        left_hinge_contour = poly.translate(left_hinge_contour, -translation_step, 0)
        right_temple_contour = poly.translate(right_temple_contour, translation_step, 0)
        right_holes = poly.translate(right_holes, translation_step, 0)
        right_hinge_contour = poly.translate(right_hinge_contour, translation_step, 0)
        intersection = poly.intersection(left_temple_contour, right_temple_contour)
#
    # Sarah commented the code below out as it seems to be speading the temples out farther than necessary
    # And I don't think we need it?

    # We're just overlapping, so now back off
    # translation_step = 0.5
    # left_temple_contour = poly.translate(left_temple_contour, translation_step, 0)
    # left_holes = poly.translate(left_holes, translation_step, 0)
    # left_hinge_contour = poly.translate(left_hinge_contour, translation_step, 0)
    # right_temple_contour = poly.translate(right_temple_contour, -translation_step, 0)
    # right_holes = poly.translate(right_holes, -translation_step, 0)
    # right_hinge_contour = poly.translate(right_hinge_contour, -translation_step, 0)


#    # sanity check that we fit on stock
    total_width =  poly.right(left_temple_contour) - poly.left(right_temple_contour)
    print "before spreading, total width is:", total_width
    if total_width > 55:
        print 'Error! temples did not pack tight enough.', total_width
        raise 'Sizing error'
#
## Spread them out
    while total_width < 55:
        print "spreading out temples"
        left_temple_contour = poly.translate(left_temple_contour, translation_step, 0)
        left_holes = poly.translate(left_holes, translation_step, 0)
        left_hinge_contour = poly.translate(left_hinge_contour, translation_step, 0)
        right_temple_contour = poly.translate(right_temple_contour, -translation_step, 0)
        right_holes = poly.translate(right_holes, -translation_step, 0)
        right_hinge_contour = poly.translate(right_hinge_contour, -translation_step, 0)
        total_width =  poly.right(left_temple_contour) - poly.left(right_temple_contour)

    intersection = poly.intersection(left_temple_contour, right_temple_contour)
    if len(intersection) > 0:
        print 'Error!  Temples are too big to fit on stock.', total_width
        raise 'Sizing Error'

    print 'Total width of temples', total_width

    # Now they're packed togegther OK but not centred on the stock
    #Midpoint of curves should be 0, so that's how much we'll shift it
    y_centering_shift = poly.bottom(right_temple_contour) + (poly.top(left_temple_contour) - poly.bottom(right_temple_contour))/2.0
    x_centering_shift = (poly.right(left_temple_contour) + poly.left(right_temple_contour))/2;


    left_temple_contour = poly.translate(left_temple_contour, -x_centering_shift, -y_centering_shift)
    right_temple_contour = poly.translate(right_temple_contour, -x_centering_shift, -y_centering_shift)
    left_hinge_contour = poly.translate(left_hinge_contour, -x_centering_shift, -y_centering_shift)
    right_hinge_contour = poly.translate(right_hinge_contour, -x_centering_shift, -y_centering_shift)
    left_holes = poly.translate(left_holes, -x_centering_shift, -y_centering_shift)
    right_holes = poly.translate(right_holes, -x_centering_shift, -y_centering_shift)

    # The temple contours aren't closed, close them here
    # NOTE: Taken out because we close the curves with a little arc to account for front curvature
    #left_temple_contour.append(left_temple_contour[0])
    #right_temple_contour.append(right_temple_contour[0])

    return {
        "pocket_depth": 1,
        "left_hinge_contour": left_hinge_contour,
        "right_hinge_contour": right_hinge_contour,
        "left_hinge_holes": left_holes,
        "right_hinge_holes": right_holes,
        "left_temple_contour": left_temple_contour,
        "right_temple_contour": right_temple_contour
            }
Exemple #10
0
def arrange_temple_curves(left_temple_contour, right_temple_contour, hinge,
                          lhinge_y, rhinge_y):
    left_hinge = hinges.get_hinge(hinge)
    right_hinge = hinges.get_hinge(hinge, False)

    print 'first and last point of left_temple_contour'
    print left_temple_contour[0], left_temple_contour[-1]
    left_holes = poly.rotate_90(left_hinge['temple_holes'])
    right_holes = poly.rotate(right_hinge['temple_holes'],
                              90)  # opposite direction.  FIX someday
    left_hinge_contour = poly.rotate_90(left_hinge['temple_contour'])
    right_hinge_contour = poly.rotate(right_hinge['temple_contour'], 90)

    #right_hinge_contour = right_hinge['temple_contour']
    #left_holes = left_hinge['temple_holes']
    #right_holes = right_hinge['temple_holes']

    # Get the thing as horizontal as possible
    # When top-bottom distance is minimized, it's horizontal
    height = poly.top(left_temple_contour) - poly.bottom(left_temple_contour)
    opt_angle = 0

    for angle in range(2, 41):
        candidate_contour = poly.rotate(left_temple_contour, -angle)
        candidate_height = poly.top(candidate_contour) - poly.bottom(
            candidate_contour)
        if candidate_height < height:
            height = candidate_height
            opt_angle = angle
        else:
            break

    # The temple is raised or lowered as compared to the Y axis.  We need
    # to bring it to the Y origin for rotation to avoid offsetting it, then
    # send it back to its original spot.
    original_y_offset = left_temple_contour[0][1] - (
        left_temple_contour[0][1] - left_temple_contour[-1][1]) / 2

    left_temple_contour = poly.translate(left_temple_contour, 0,
                                         -original_y_offset)
    left_temple_contour = poly.rotate(left_temple_contour, -opt_angle)
    left_temple_contour = poly.translate(left_temple_contour, 0,
                                         original_y_offset)

    right_temple_contour = poly.translate(right_temple_contour, 0,
                                          -original_y_offset)
    right_temple_contour = poly.rotate(right_temple_contour, opt_angle)
    right_temple_contour = poly.translate(right_temple_contour, 0,
                                          original_y_offset)

    #left_holes = poly.rotate(left_hinge['temple_holes'], -opt_angle)
    #right_holes = poly.rotate(right_hinge['temple_holes'], opt_angle)
    #left_hinge_contour = poly.rotate(left_hinge['temple_contour'], -opt_angle)
    #right_hinge_contour = poly.rotate(right_hinge['temple_contour'], opt_angle)

    left_holes = poly.rotate(left_holes, -opt_angle)
    right_holes = poly.rotate(right_holes, opt_angle)
    left_hinge_contour = poly.rotate(left_hinge_contour, -opt_angle)
    right_hinge_contour = poly.rotate(right_hinge_contour, opt_angle)
    left_hinge_contour = poly.translate(left_hinge_contour, lhinge_y,
                                        -left_hinge['pocket_depth'])
    right_hinge_contour = poly.translate(right_hinge_contour, rhinge_y,
                                         right_hinge['pocket_depth'])
    # Left and right translate are reversed because we've rotated everything
    left_holes = poly.translate(left_holes, lhinge_y,
                                -left_hinge['pocket_depth'])
    right_holes = poly.translate(right_holes, rhinge_y,
                                 right_hinge['pocket_depth'])

    temple_width = poly.right(left_temple_contour) - poly.left(
        left_temple_contour)
    print "temple width", temple_width
    lt_trans = [temple_width / 2, 0]
    rt_trans = [-lt_trans[0], 0]

    #lt_trans = [180-poly.right(left_temple_contour), -poly.top(left_temple_contour) - 30]
    #lt_trans = [-poly.right(left_temple_contour)-30, 180 -poly.top(left_temple_contour)]
    #rt_trans = [-poly.left(right_temple_contour)+25, lt_trans[1]-height]

    # Translate them
    left_temple_contour = poly.translate(left_temple_contour, lt_trans[0],
                                         lt_trans[1])
    right_temple_contour = poly.translate(right_temple_contour, rt_trans[0],
                                          rt_trans[1])
    left_hinge_contour = poly.translate(left_hinge_contour, lt_trans[1],
                                        -lt_trans[0])
    right_hinge_contour = poly.translate(right_hinge_contour, rt_trans[1],
                                         -rt_trans[0])
    left_holes = poly.translate(left_holes, lt_trans[1], -lt_trans[0])
    right_holes = poly.translate(right_holes, rt_trans[1], -rt_trans[0])

    # Translate bottom one upward as much as we can
    trans_amount = poly.bottom(left_temple_contour) - poly.top(
        right_temple_contour) - 8
    for i in range(1, 100):
        candidate = poly.translate(right_temple_contour, 0, trans_amount + i)
        intersection = poly.intersection(candidate, left_temple_contour)
        if len(intersection) > 0:
            trans_amount = trans_amount + i - 8
            right_temple_contour = poly.translate(right_temple_contour, 0,
                                                  trans_amount)
            break
    print 'trans amount:', trans_amount

    right_hinge_contour = poly.translate(right_hinge_contour, trans_amount, 0)
    right_holes = poly.translate(right_holes, trans_amount, 0)

    return {
        "pocket_depth": left_hinge['pocket_depth'],
        "left_hinge_contour": left_hinge_contour,
        "right_hinge_contour": right_hinge_contour,
        "left_hinge_holes": left_holes,
        "right_hinge_holes": right_holes,
        "left_temple_contour": left_temple_contour,
        "right_temple_contour": right_temple_contour
    }
Exemple #11
0
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))
def arrange_temple_curves(left_temple_contour, right_temple_contour, hinge, lhinge_y, rhinge_y):
    left_hinge = hinges.get_hinge(hinge)
    right_hinge = hinges.get_hinge(hinge, False)

    print 'first and last point of left_temple_contour'
    print left_temple_contour[0], left_temple_contour[-1]
    left_holes = poly.rotate_90(left_hinge['temple_holes'])
    right_holes = poly.rotate(right_hinge['temple_holes'], 90) # opposite direction.  FIX someday
    left_hinge_contour = poly.rotate_90(left_hinge['temple_contour'])
    right_hinge_contour = poly.rotate(right_hinge['temple_contour'], 90)

    #right_hinge_contour = right_hinge['temple_contour']
    #left_holes = left_hinge['temple_holes']
    #right_holes = right_hinge['temple_holes']

    # Get the thing as horizontal as possible
    # When top-bottom distance is minimized, it's horizontal
    height = poly.top(left_temple_contour) - poly.bottom(left_temple_contour)
    opt_angle = 0

    for angle in range(2, 41):
        candidate_contour = poly.rotate(left_temple_contour, -angle)
        candidate_height = poly.top(candidate_contour)-poly.bottom(candidate_contour)
        if candidate_height < height:
            height = candidate_height
            opt_angle = angle
        else:
            break

    # The temple is raised or lowered as compared to the Y axis.  We need
    # to bring it to the Y origin for rotation to avoid offsetting it, then
    # send it back to its original spot.
    original_y_offset = left_temple_contour[0][1] - (left_temple_contour[0][1] - left_temple_contour[-1][1])/2

    left_temple_contour = poly.translate(left_temple_contour, 0, -original_y_offset)
    left_temple_contour = poly.rotate(left_temple_contour, -opt_angle);
    left_temple_contour = poly.translate(left_temple_contour, 0, original_y_offset)

    right_temple_contour = poly.translate(right_temple_contour, 0, -original_y_offset)
    right_temple_contour = poly.rotate(right_temple_contour, opt_angle);
    right_temple_contour = poly.translate(right_temple_contour, 0, original_y_offset)

    #left_holes = poly.rotate(left_hinge['temple_holes'], -opt_angle)
    #right_holes = poly.rotate(right_hinge['temple_holes'], opt_angle)
    #left_hinge_contour = poly.rotate(left_hinge['temple_contour'], -opt_angle)
    #right_hinge_contour = poly.rotate(right_hinge['temple_contour'], opt_angle)

    left_holes = poly.rotate(left_holes, -opt_angle)
    right_holes = poly.rotate(right_holes, opt_angle)
    left_hinge_contour = poly.rotate(left_hinge_contour, -opt_angle)
    right_hinge_contour = poly.rotate(right_hinge_contour, opt_angle)
    left_hinge_contour = poly.translate(left_hinge_contour,  lhinge_y, -left_hinge['pocket_depth'])
    right_hinge_contour = poly.translate(right_hinge_contour, rhinge_y, right_hinge['pocket_depth'])
    # Left and right translate are reversed because we've rotated everything
    left_holes = poly.translate(left_holes, lhinge_y, -left_hinge['pocket_depth'])
    right_holes = poly.translate(right_holes, rhinge_y, right_hinge['pocket_depth'])

    temple_width = poly.right(left_temple_contour) - poly.left(left_temple_contour)
    print "temple width", temple_width
    lt_trans = [temple_width/2, 0]
    rt_trans = [-lt_trans[0], 0]

    #lt_trans = [180-poly.right(left_temple_contour), -poly.top(left_temple_contour) - 30]
    #lt_trans = [-poly.right(left_temple_contour)-30, 180 -poly.top(left_temple_contour)]
    #rt_trans = [-poly.left(right_temple_contour)+25, lt_trans[1]-height]

   # Translate them
    left_temple_contour = poly.translate(left_temple_contour, lt_trans[0], lt_trans[1])
    right_temple_contour = poly.translate(right_temple_contour, rt_trans[0], rt_trans[1])
    left_hinge_contour = poly.translate(left_hinge_contour, lt_trans[1], -lt_trans[0])
    right_hinge_contour = poly.translate(right_hinge_contour, rt_trans[1], -rt_trans[0])
    left_holes = poly.translate(left_holes, lt_trans[1], -lt_trans[0])
    right_holes = poly.translate(right_holes, rt_trans[1], -rt_trans[0])


    # Translate bottom one upward as much as we can
    trans_amount = poly.bottom(left_temple_contour) - poly.top(right_temple_contour) - 8
    for i in range(1, 100):
        candidate = poly.translate(right_temple_contour, 0, trans_amount + i)
        intersection = poly.intersection(candidate, left_temple_contour)
        if len(intersection) > 0:
            trans_amount = trans_amount + i -8
            right_temple_contour = poly.translate(right_temple_contour, 0, trans_amount)
            break
    print 'trans amount:', trans_amount

    right_hinge_contour = poly.translate(right_hinge_contour, trans_amount, 0)
    right_holes = poly.translate(right_holes, trans_amount, 0)

    return {
        "pocket_depth": left_hinge['pocket_depth'],
        "left_hinge_contour": left_hinge_contour,
        "right_hinge_contour": right_hinge_contour,
        "left_hinge_holes": left_holes,
        "right_hinge_holes": right_holes,
        "left_temple_contour": left_temple_contour,
        "right_temple_contour": right_temple_contour
            }