// Last edited on 2019-12-08 11:27:16 by jstolfi #include "wshop_drawer_handle.inc" #include "wshop_drawer_rail.inc" #include "wshop_drawer_tray.inc" #include "painted_box.inc" #include "show_volume.inc" #macro wshop_drawer ( dr_space_dim, rail_dim, handle_dim, face_th, side_th, rear_th, rear_dx, bot_th, bot_dz, clear_dz, face_ey, face_ebot, face_etop, face_only, show_face, xopen, tx_face, tx_tray, tx_handle, tx_rail, tagg, what, dim_only ) // A single drawer for the lab bench drawer chest, with the supporting rails. // The X axis is back to front. // The Y axis is along the bench, left to right. // The Z axis is up. // The origin is at the back left bottom corner of the nominal dimensions. // {dr_space_dim} is the overall dimensions of the drawer; // including the face plate, space for rails, and top/bot clearances, // but excluding the {face_ey} face plate overshoots, the handle, and any back clearance. // {rail_dim} is a box that encloses the whole rail when closed. // {handle_dim} is the dimensions of a box that encloses the handle, nominally. // {face_th} is the thickness of the front wall (face plate). // {side_th} is the thickness of the left and right walls. // {rear_th} is the thickness of the rear wall. // {rear_dx} is the displacement of the rear wall rel to the rear edge of the side walls. // {bot_th} is the thickness of the bottom wall. // {bot_dz} is the vertical displacement of the bottom rel to the bottom edge of the side walls. // {clear_dz} is the clearance above and below the drawer's tray. // These parms tell how much the face plate should extend beyond {dr_space_dim} (maybe negative): // {face_ey} lateral overshoot (in the ±Y direction). // {face_ebot} bottom overshot (in the -Z direction). // {face_etop} top overshoot (in the +Z direction). // If {face_only} is true, omits the handle, tray, and rails, leaving only face plate; // but still includes the tray in the dimensions. // If {show_face} is false, omits the face plate and handle, but still includes them // in the dimensions. // The drawer will be pulled open by {xopen}. // {tagg} is a string that identifies the pieces of this drawer in the cutout plan. // If {what=1} returns the object. // If {what=0} returns the useful drawer cavity. // If {what=-1} returns the handle. // If {what=-2} returns the handle mounting's hole (to be subtracted from the face plate). // If {dim_only} is true returns only the nominal bounding box of the (sub)object. // The nominal bounding box of the drawer includes the X extent // of the drawer face plate and the {clear_dz} clearances, // and the Y extent of the rails, but it does not include the handle, // the Y and Z overshoots {ey,ebot,etop}, or any clearances in the // back, below, or above the drawer relative to the cavity where it fits in. // Overall drawer dimensions and X displacement: #if (face_only) #local drawer_dim = < face_th, dr_space_dim.y, dr_space_dim.z >; #local drawer_disp = (dr_space_dim.x - face_th)*x; #else #local drawer_dim = < dr_space_dim.x, dr_space_dim.y, dr_space_dim.z >; #local drawer_disp = < 0, 0, 0 >; #end #local whole = 1; // Value of {what} for whole object. #if ((what = whole) & dim_only) // Nominal bounding box of drawer only. #local res = box{ <0,0,0>, drawer_dim texture{ tx_space } translate drawer_dx*x } #else // Drawer object, drawer space hole, or just the handle. // Outer dims of drawer's tray EXCLUDING rails and face plate, and dims of useful space: #if (face_only) // A fake drawer, just the face plate: #local tray_odim = < 0, drawer_dim.y - 2*rail_dim.y, drawer_dim.z - 2*clear_dz >; #else // A true drawer. #local tray_odim = < drawer_dim.x - face_th, drawer_dim.y - 2*rail_dim.y, drawer_dim.z - 2*clear_dz >; #end #local otray_disp = < drawer_dim.x - tray_odim.x, rail_dim.y, clear_dz >; #if (what = 0) // Return useful drawer space or its bounding box: #local itray = wshop_drawer_tray(tray_odim, side_th, rear_th, rear_dx, bot_th, bot_dz, tx_tray, tagg, dim_only); #local res = object{ itray translate otray_disp } #elseif ((what = -1) | (what = -2)) // Return handle, its mounting hole, or their bounding boxes: #local res = object{ wshop_drawer_handle(handle_dim, tx_handle, face_th, tx_tray, what+2, dim_only) translate < dr_space_dim.x, dr_space_dim.y/2, dr_space_dim.z/2 > #if (what = -1) translate 1.0*dexp*x #else translate 0.9*dexp*x #end } #else // The whole drawer object: #local drawer_obj = wshop_drawer_obj ( dr_space_dim, tray_odim, rail_dim, handle_dim, face_th, side_th, rear_th, rear_dx, bot_th, bot_dz, face_ey, face_ebot, face_etop, clear_dz, face_only, show_face, xopen, tx_face, tx_tray, tx_handle, tx_rail, tagg ) #local res = object{ drawer_obj translate drawer_disp } #end #end res #end #macro wshop_drawer_obj ( dr_space_dim, tray_odim, rail_dim, handle_dim, face_th, side_th, rear_th, rear_dx, bot_th, bot_dz, face_ey, face_ebot, face_etop, clear_dz, face_only, show_face, xopen, tx_face, tx_tray, tx_handle, tx_rail, tagg ) // A single drawer object. // Other parameters are as in {wshop_drawer}. // The nominal bounding box of a drawer includes the handle. #local dexp = 1.0 * xplode; // Max displacement in exploded view. #local drawer = union{ // Face plate dimensions: #local face_dim = < face_th, dr_space_dim.y + 2*face_ey, dr_space_dim.z + face_ebot + face_etop >; #if (! dim_only) write_pieces("plywd", concat(tagg,".f"), 1, face_dim.y, face_dim.z, face_dim.x, "face plate") #end // Face plate. Origin is at lower left front corner of drawer hole: #if (show_face > 0) #local face_plate = object{ painted_box(face_dim, 0,1, 1,1, 1,1, tx_tray, tx_face ) translate < 0, - face_ey, - face_ebot > translate 0.9*dexp*x } #end #if (tray_odim.x < 1.01*face_th) // A false drawer, just the face plate. #local drawer_norail = object{ face_plate } #else // A true drawer // Rail; origin is at left back bottom corner of rail itself. #local rail_obj = object{ wshop_drawer_rail(rail_dim, xopen, tx_rail, 1) translate -0.5*dexp*y } // Left and right rail objects. Origin is at left back bottom corner of drawer hole: #local rail_dx = 10; // X displacement of rail from front of drawer hole. #local rail_dz = (dr_space_dim.z - rail_dim.z)/2; // Z displacement of rail from top of drawer hole. #local rail_disp = < dr_space_dim.x - face_th - rail_dim.x - rail_dx, 0, dr_space_dim.z - rail_dim.z - rail_dz >; #local lrail = object{ rail_obj translate rail_disp } object{ lrail } #local rrail = object{ lrail scale < +1, -1, +1> translate dr_space_dim.y*y } object{ rrail } // Handle. Origin is at center of back surface. #local handle = object{ wshop_drawer_handle(handle_dim, tx_handle, face_th, tx_tray, 1, false) translate < face_th, dr_space_dim.y/2, dr_space_dim.z/2 > translate 1.0*dexp*x } // Handle mounting hole(s). Origin is at center of back surface. #local handle_hole = object{ wshop_drawer_handle(handle_dim, tx_handle, face_th, tx_tray, 0, false) translate < face_th, dr_space_dim.y/2, dr_space_dim.z/2 > translate 0.9*dexp*x } // The drawer's tray: #local drawer_tray = object{ wshop_drawer_tray(tray_odim, side_th, rear_th, rear_dx, bot_th, bot_dz, tx_tray, tagg, false) } #local drawer_norail = union{ object{ drawer_tray translate < 0, rail_dim.y, clear_dz > } union{ difference{ object{ face_plate } object{ handle_hole } } object{ handle } translate tray_odim.x*x } } #end object{ drawer_norail translate xopen*x } } drawer #end