import os print(os.getcwd()) import cadquery as cq import numpy as np dp = 2 print("Starting") r_hole = 4.6/2 if dp == 0: box_depth = 550 box_width = 160 box_height = 76 prefix = 'bench' t_small = 4.6 t_large = 4.6 elif dp == 1: box_depth = 100 box_width = 50 box_height = 50 prefix = 'small' t_small = 3.175 t_large = t_small*2 force_tab_width = True tab_width_if_forced = 5 elif dp == 2: box_depth = 540 + 25.4/2 box_width = 472 box_height = 3.15*25.4 prefix = 'orig' t_small = 3.175 t_large = t_small*2 force_tab_width = False tab_width_if_forced = 25 t1 = t_small t2 = t_large objs = list() def copy(obj): return obj.translate((0, 0, 0)) def intersect(wp1, wp2): """ Return geometric intersection between 2 cadquery.Workplane instances by exploiting. A n B = (A u B) - ((A - B) u (B - A)) """ neg1 = copy(wp1).cut(wp2) neg2 = copy(wp2).cut(wp1) negative = neg1.union(neg2) return copy(wp1).union(wp2).cut(negative) def add_rect(wplane, w, d): return wplane.lineTo(0,d).lineTo(w,d).lineTo(w,0).close() def add_fingers(r_side, f_side, num_tabs = 6, tab_width = None, cut = True): sliver = intersect(r_side, f_side) pts = list() for h in sliver.vertices().vals(): pts.append( ( h.X, h.Y, h.Z)) pt=np.asarray(pts) min_pts = np.min(pt, axis=0) max_pts = np.max(pt, axis=0) axis_step = np.argmax(max_pts - min_pts) axis_sq = list(set([0,1,2]).difference([axis_step])) sq_dim = (max_pts-min_pts)[axis_sq] total_sz = (max_pts-min_pts)[axis_step] if tab_width is not None: num_tabs = int(np.ceil(total_sz/tab_width)) elif force_tab_width: num_tabs = int(np.ceil(total_sz / tab_width_if_forced)) step_sz = total_sz / num_tabs box_sz = max_pts-min_pts box_sz[axis_step] /= num_tabs tbj = list() tbh = list() for i in range(num_tabs): xstep = [0,0,0] if (axis_sq[1]-axis_sq[0]) > 1: xstep[axis_sq[1]] = 1 flip = True else: xstep[axis_sq[0]] = 1 flip = False normal = [0,0,0] normal[axis_step] = 1 origin = min_pts.copy() origin[axis_step] += i * step_sz t_plane = cq.Plane(tuple(origin), tuple(xstep), tuple(normal)) if flip: tbj.append( add_rect(cq.Workplane(t_plane), sq_dim[1], sq_dim[0]).extrude(step_sz) ) else: tbj.append( add_rect(cq.Workplane(t_plane), sq_dim[0], sq_dim[1]).extrude(step_sz) ) if cut: for i in range(num_tabs): if i % 2 == 0: r_side = r_side.cut(tbj[i]) if i % 2 == 1: f_side = f_side.cut(tbj[i]) return r_side, f_side, tbj l_plane = cq.Plane(origin = (box_width,0,0), xDir=(0,1,0), normal=(1,0,0)) r_plane = cq.Plane(origin = (0,0,0), xDir=(0,1,0), normal=(1,0,0)) f_plane=cq.Plane(origin=(box_width, box_depth,0), xDir=(-1,0,0), normal = (0,1,0)) xy_wp = lambda: cq.Workplane('XY') xz_wp = lambda: cq.Workplane('XZ') yz_wp = lambda: cq.Workplane('YZ') l_wp = lambda: cq.Workplane(l_plane) f_wp = lambda: cq.Workplane(f_plane) bottom = add_rect(xy_wp(), box_width, box_depth).extrude(t2).translate((0,0,2)) l_side = add_rect(l_wp(), box_depth, box_height).extrude(-t2) r_side = add_rect(yz_wp(), box_depth, box_height).extrude(t2) b_side = add_rect(xz_wp(), box_width, box_height).extrude(-t2) f_side = add_rect(f_wp(), box_width, box_height).extrude(-t2) def ret_front_pts(bd, bh, spread = 96): pts = list() if spread == 0: pts.append( (bd/2, bh)) else: pts.append( (bd/2 - spread/2, bh)) pts.append( (bd/2 + spread/2, bh)) return pts def ret_pts(bd, bh, center = False, max_num = None, spacing = 32): pts = list() if center: ix = int(np.ceil(bd/spacing)/2) for i in range((-ix+1), ix ): pts.append((bd/2 + i*spacing, bh)) else: for i in range(1,int(np.ceil(bd/spacing)) - 1): pts.append((i*spacing, bh)) pts = tuple(pts) return pts def slide_pts(bd, bh, offset_from_back = 54, spacing = (192, 192)): pts = list() curr_pt = offset_from_back pts.append([curr_pt, bh]) for spc in spacing: curr_pt += spc pts.append([ curr_pt, bh]) return pts if 1: if dp==2: pts_holes = slide_pts(box_depth, box_height/2) r_side = r_side.cut(yz_wp().pushPoints(pts_holes).circle(r_hole).extrude(10)) l_side = l_side.cut(l_wp().pushPoints(pts_holes).circle(r_hole).extrude(-10)) bw = box_width * 0.6 f_side = f_side.cut(f_wp().pushPoints(ret_front_pts(box_width, box_height*0.3, spread=bw)).circle(r_hole).extrude(-10)) f_side = f_side.cut(f_wp().pushPoints(ret_front_pts(box_width, box_height * (0.7), spread=bw)).circle(r_hole).extrude(-10)) f_side = f_side.cut(f_wp().pushPoints(ret_front_pts(box_width, box_height * (0.7), spread=0)).circle(r_hole).extrude(-10)) f_side = f_side.cut(f_wp().pushPoints(ret_front_pts(box_width, box_height * (0.3), spread=0)).circle(r_hole).extrude(-10)) else: r_side = r_side.cut(yz_wp().pushPoints(ret_pts(box_depth, box_height/2)).circle(r_hole).extrude(10)) l_side = l_side.cut(l_wp().pushPoints(ret_pts(box_depth, box_height/2)).circle(r_hole).extrude(-10)) f_side = f_side.cut(f_wp().pushPoints(ret_front_pts(box_width, box_height/2, spread=96)).circle(r_hole).extrude(-10)) # if 1: r_side, f_side, _ = add_fingers(r_side, f_side) l_side, f_side, _ = add_fingers(l_side, f_side) l_side, b_side, _ = add_fingers(l_side, b_side) r_side, b_side, _ = add_fingers(r_side, b_side) bottom,l_side, _ = add_fingers(bottom,l_side, num_tabs = 15) bottom, r_side,_ = add_fingers(bottom,r_side, num_tabs = 15) bottom,f_side, _= add_fingers(bottom,f_side, num_tabs = 15) bottom,b_side, _ = add_fingers(bottom,b_side, num_tabs = 15) show_object(l_side) show_object(f_side) show_object(r_side) show_object(b_side) print(type(b_side)) t_w = 10 l_d = 50 l_w = 50 # <---> n_w = int(box_width / (2*l_w)) n_d = int(box_depth / (2*l_d)) b_dcent = box_depth/2 - t1/2 b_wcent = box_width/2 - t_w/2 d_dcent = box_depth/2 - t_w d_wcent = box_width/2 - t1/2 rectadd = None show_object(bottom) from cadquery import exporters as et import os models_export = ['bottom', 'l_side', 'r_side', 'f_side', 'b_side'] rt_dir = r'C:\\Users\\TheBears\\Seafile\\Designs\\Projects\\kickdrawers\\cadfree\\output\\' print(globals()['bottom']) for mod in models_export: fpath = os.path.join(rt_dir, prefix + '_'+ mod+'.stl') et.exportShape(globals()[mod], et.ExportTypes.STL, open(fpath,'w'))