/* * Draw a rounded edge in one quadrant * * Draw a arc from corner point vc plus rector ra to vc+rb. vc+ra is stored * in va and vc+rb is stored in vb. */ #define Q(va, vb, vc, ra, rb) \ va: vec vc ra; \ vb: vec vc rb; \ vc##_center: vec va rb; \ arc vc##_center va vb #define QLL(pfx, r) \ Q(pfx##lly, pfx##llx, pfx##ll, (0mm, r), (r, 0mm)) #define QLR(pfx, r) \ Q(pfx##lrx, pfx##lry, pfx##lr, (-(r), 0mm), (0mm, r)) #define QUL(pfx, r) \ Q(pfx##ulx, pfx##uly, pfx##ul, (r, 0mm), (0mm, -(r))) #define QUR(pfx, r) \ Q(pfx##ury, pfx##urx, pfx##ur, (0mm, -(r)), (-(r), 0mm)) /* * Rectangle with rounded corners. * * pfx is the prefix for all the names generated by this macro. origin is the * lower left corner. w and h are the width and height. r is the radius of the * corners. */ #define RRECT_SETUP(pfx, origin, w, h) \ pfx##ll: vec origin(0mm, 0mm); \ pfx##lr: vec pfx##ll(w, 0mm); \ pfx##ul: vec pfx##ll(0mm, h); \ pfx##ur: vec pfx##ll(w, h); \ #define RRECT_DRAW_ARCS(pfx, r) \ QLL(pfx, r); \ QLR(pfx, r); \ QUL(pfx, r); \ QUR(pfx, r) #define RRECT_DRAW_LINES(pfx) \ line pfx##llx pfx##lrx; \ line pfx##ulx pfx##urx; \ line pfx##lly pfx##uly; \ line pfx##lry pfx##ury #define RRECT(pfx, origin, w, h, r) \ RRECT_SETUP(pfx, origin, w, h); \ RRECT_DRAW_ARCS(pfx, r); \ RRECT_DRAW_LINES(pfx) /* ----- Top part ---------------------------------------------------------- */ frame top_outline { RRECT(edge_, @, width, length, ro_edge) } frame top_window { loop if = 1, top_window set off = topborder+topridge frame top_outline @ win_orig: vec @(off+pcbgap+win_x0, off) RRECT(win_, win_orig, win_x1-win_x0, length-2*off, win_r) cmp_orig: vec @(off+pcbgap+cmp_x0, off+pcbgap+cmp_y0) RRECT(cmp_, cmp_orig, cmp_x1-cmp_x0, cmp_y1-cmp_y0, cmp_r) } frame top_pcb { loop if = 1, top_pcb set off = topborder+topridge frame top_outline @ ll: vec @(off, off) RRECT(pcb_, ll, width-2*off, length-2*off, ri_ridge) } frame top_ridge { loop if = 1, top_ridge set inside = topborder+topridge ro: vec @(topborder, topborder) RRECT(ridge_o_, ro, width-2*topborder, length-2*topborder, ro_ridge) ri: vec ro(topridge, topridge) RRECT(ridge_i_, ri, width-2*inside, length-2*inside, ri_ridge) } frame top_surface { loop if = 1, top_surface frame top_outline @ } /* ----- Middle part ------------------------------------------------------- */ frame mid_rrect_ridge { RRECT_SETUP(edge_, @, width, length); RRECT_DRAW_ARCS(edge_, ro_edge); base: vec @(red, red) RRECT_SETUP(ridge_, base, width-2*red, length-2*red); RRECT_DRAW_ARCS(ridge_, r); usb_ur: vec edge_ur(-usb_roff, 0mm) usb_ul: vec usb_ur(-usb_w, 0mm) usb_ll: vec usb_ul(0mm, -red) usb_lr: vec usb_ur(0mm, -red) line edge_lly edge_uly /* outside */ line edge_ulx usb_ul line usb_ul usb_ll /* USB bay */ line usb_ll ridge_ulx line ridge_uly ridge_lly /* inside */ line ridge_llx ridge_lrx line ridge_lry ridge_ury line ridge_urx usb_lr line usb_lr usb_ur /* USB bay */ line usb_ur edge_urx line edge_ury edge_lry /* outside */ line edge_lrx edge_llx } frame mid_rrect_body { RRECT_SETUP(edge_, @, width, length); RRECT_DRAW_ARCS(edge_, ro_edge); usb_ur: vec edge_ur(-usb_roff, 0mm) usb_ul: vec usb_ur(-usb_w, 0mm) usb_ll: vec usb_ul(0mm, -usb_d) usb_lr: vec usb_ur(0mm, -usb_d) line edge_llx edge_lrx line edge_ulx usb_ul line usb_ul usb_ll /* USB bay */ line usb_ll usb_lr line usb_lr usb_ur line usb_ur edge_urx line edge_lly edge_uly line edge_lry edge_ury } frame mid_ridge { loop if = 1, mid_ridge set red = topborder set r = ro_ridge frame mid_rrect_ridge @ } frame mid_pcb { loop if = 1, mid_pcb set red = topborder+topridge set r = ri_ridge frame mid_rrect_ridge @ } frame post { vec @(r, 0mm) circ @ . } frame mid_body { loop if = 1, mid_body frame mid_rrect_body @ bc: vec @(width/2, batt_y) br: vec bc(batt_d/2, 0mm) circ bc br set r = post_do/2 vec @(post_x, cvr_f+cvr_d+post_y) frame post . vec @(width-post_x, cvr_f+cvr_d+post_y) frame post . } /* ----- Bottom part ------------------------------------------------------- */ frame bot_rrect { base: vec @(0mm, cvr_f) RRECT_SETUP(edge_, base, width, length-cvr_f); QUL(edge_, ro_edge); QUR(edge_, ro_edge); set side = (width-cvr_w-2*cvr_play)/2-red cvr_ll: vec edge_ll(side, 0mm) cvr_lr: vec edge_lr(-side, 0mm) cvr_ul: vec cvr_ll(0mm, cvr_d+2*cvr_play+red) cvr_ur: vec cvr_lr(0mm, cvr_d+2*cvr_play+red) line edge_ll cvr_ll /* outside */ QUL(cvr_, cvr_r+red+cvr_play) /* cover bay */ QUR(cvr_, cvr_r+red+cvr_play) line cvr_ll cvr_uly line cvr_ulx cvr_urx line cvr_ury cvr_lr line cvr_lr edge_lr /* outside */ line edge_ll edge_uly line edge_lr edge_ury line edge_ulx edge_urx } frame bot_posts { loop if = 1, bot_posts set r = post_di/2 vec @(post_x, cvr_f+cvr_d+post_y) frame post . vec @(width-post_x, cvr_f+cvr_d+post_y) frame post . } frame bot_base { loop if = 1, bot_base set red = cvr_foot frame bot_rrect @ } frame bot_surface { loop if = 1, bot_surface set red = 0mm frame bot_rrect @ } /* ----- Main -------------------------------------------------------------- */ package "$part-$z" unit mm table { part, z, top_surface, top_window, top_pcb, top_ridge, mid_ridge, mid_pcb, mid_body, bot_posts, bot_base, bot_surface} { "top_surface", 2.5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } { "top_window", 1.5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 } // { "top_pcb", 0.5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } { "top_ridge", 0.5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 } { "mid_ridge", 0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } { "mid_pcb", 1.0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } { "mid_body", 4.5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 } { "bot_posts", 1.2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } { "bot_base", 2.0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } { "bot_surface", 2.7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } table { pcbw, pcbl, pcbgap } { 20mm, 45mm, 0.2mm } table /* window position relative to left edge of PCB */ { topridge, topborder, win_x0, win_x1, win_r } { 1.0mm, 1.0mm, 1.0mm, 5.0mm, 1.6mm } table /* component area position relative to lower left corner of PCB */ { cmp_x0, cmp_y0, cmp_x1, cmp_y1, cmp_r } { 6.5mm, 1.0mm, 19.5mm, 30.0mm, 2.0mm } table /* usb_roff = offset from right outer case edge */ { usb_w, usb_d, usb_roff } { 8.5mm, 6.0mm, 4.5mm } table /* post_y is from the edge of the battery bay. post_x is from the edge */ { batt_d, batt_y, post_do, post_di, post_y, post_x } { 20.2mm, 12.1mm, 4.1mm, 4.0mm, 5.0mm, 4.5mm } table { cvr_w, cvr_d, cvr_f, cvr_foot, cvr_play, cvr_r } { 20.0mm, 15.0mm, 5.0mm, 0.8mm, 0.1mm, 2.0mm } set width = pcbw+2*(pcbgap+topridge+topborder) set length = pcbl+2*(pcbgap+topridge+topborder) set ri_ridge = 2.0mm set ro_ridge = ri_ridge+topridge /* * ro_edge is an outer edge, so we can make the radius smaller than ro_ridge, * for added strength and less fruity esthetics. */ set ro_edge = 1.5mm frame top_ridge @ frame top_pcb @ frame top_window @ frame top_surface @ frame mid_ridge @ frame mid_pcb @ frame mid_body @ frame bot_posts @ frame bot_base @ frame bot_surface @ measx top_outline.edge_ul -> top_outline.edge_ur 4mm measy top_outline.edge_ll -> top_outline.edge_ul 4mm measx top_pcb.pcb_ul -> top_pcb.pcb_ur 3mm measy top_pcb.pcb_ll -> top_pcb.pcb_ul 3mm measx top_ridge.ridge_o_ul -> top_ridge.ridge_o_ur 4mm measy top_ridge.ridge_o_ll -> top_ridge.ridge_o_ul 4mm measx top_ridge.ridge_i_ul -> top_ridge.ridge_i_ur 3mm measy top_ridge.ridge_i_ll -> top_ridge.ridge_i_ul 3mm measy bot_rrect.edge_ll -> bot_rrect.edge_ul 4mm measx bot_rrect.edge_ll -> bot_rrect.cvr_ll -3mm