yacwc
This commit is contained in:
258
finger_rewrite.py
Normal file
258
finger_rewrite.py
Normal file
@@ -0,0 +1,258 @@
|
||||
from pprint import pprint
|
||||
import os
|
||||
import datetime as dt
|
||||
print('===============', str(dt.datetime.now()), '===============')
|
||||
from palettable.cartocolors.qualitative import Vivid_10 as cmap
|
||||
import numpy as np
|
||||
import importlib as ir
|
||||
from cadquery import exporters as et
|
||||
import cadquery as cq
|
||||
from scipy.spatial.distance import pdist, squareform
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
try:
|
||||
try:
|
||||
root_dir = r'C:\\Users\\TheBears\\Seafile\\Designs\\Projects\\kickdrawers\\cadfree\\code\\'
|
||||
os.chdir(root_dir)
|
||||
except:
|
||||
root_dir = r'C:\\Users\\Ishan\\Seafile\\Designs\\Projects\\kickdrawers\\cadfree\\code\\'
|
||||
os.chdir(root_dir)
|
||||
except:
|
||||
root_dir = r'/home/thebears/Seafile/Designs/Projects/kickdrawers/cadfree/code'
|
||||
os.chdir(root_dir)
|
||||
|
||||
import items as it
|
||||
import util as u
|
||||
import cadquery as cq
|
||||
ir.reload(it)
|
||||
ir.reload(u)
|
||||
add_rect = u.add_rect
|
||||
|
||||
def xy_wp():
|
||||
return cq.Workplane('XY')
|
||||
|
||||
def xz_wp():
|
||||
return cq.Workplane('XZ')
|
||||
|
||||
def yz_wp():
|
||||
|
||||
return cq.Workplane('YZ')
|
||||
|
||||
|
||||
t1 = 3.175
|
||||
rod_r = 23/2
|
||||
spool_diameter = 60 + t1*2
|
||||
spool_width = 25
|
||||
total_width = spool_width*6 + 2*t1
|
||||
wire_friction_width = 25
|
||||
pt_r = 2/2
|
||||
pt_spacing = 5
|
||||
off_edge = 9
|
||||
|
||||
|
||||
oxb = u.add_rect(xz_wp(),total_width+t1+2*t1, spool_diameter).extrude(t1).translate((-t1,spool_diameter,0))
|
||||
|
||||
oxr = u.add_rect(yz_wp(), spool_diameter, spool_diameter).extrude(t1)
|
||||
oxl = u.add_rect(yz_wp(), spool_diameter, spool_diameter).extrude(t1).translate((total_width,0,0))
|
||||
|
||||
ox_cyl = yz_wp().pushPoints([[spool_diameter/2,spool_diameter/2]]).circle(rod_r).extrude(total_width+t1)
|
||||
oxl = oxl.cut(ox_cyl)
|
||||
oxr = oxr.cut(ox_cyl)
|
||||
|
||||
oxf = u.add_rect(xz_wp(), total_width+t1+2*t1, wire_friction_width).extrude(-t1).translate((-t1,0,spool_diameter/2 - wire_friction_width/2))
|
||||
|
||||
wp2 = oxl
|
||||
wp1 = oxf
|
||||
|
||||
# wp1 = u.add_rect(xy_wp(), 20, 15).extrude(3).rotate((0,0,0),(0,1,0), 30)#.translate((0,5,10))
|
||||
# wp2 = u.add_rect(yz_wp(), 15,20).extrude(3).rotate((0,0,0),(0,1,0), 30)#.translate((0,5,10))
|
||||
|
||||
|
||||
num_tabs = 5
|
||||
r_hole = 0.5
|
||||
slot_depth = 7
|
||||
nut_width = 2.5
|
||||
nut_thickness = 1
|
||||
nut_depth = 4
|
||||
|
||||
# wp1 = wp1.rotate((0,0,0),(1,0,0), 45)
|
||||
# wp2 = wp2.rotate((0,0,0),(1,0,0), 45)
|
||||
|
||||
def norm_vector(vec):
|
||||
return vec / np.linalg.norm(vec)
|
||||
|
||||
def vertices_to_array(verts):
|
||||
pts = list()
|
||||
for h in verts:
|
||||
pts.append( (h.X, h.Y, h.Z))
|
||||
|
||||
return np.asarray(pts)
|
||||
|
||||
def intersect(wp1,wp2):
|
||||
neg1 = wp1.cut(wp2)
|
||||
neg2 = wp2.cut(wp1)
|
||||
negative = neg1.union(neg2)
|
||||
intersected = wp1.union(wp2).cut(negative)
|
||||
return intersected
|
||||
|
||||
def pround(vals, decimals= 5):
|
||||
return np.around(vals, decimals = decimals)
|
||||
|
||||
def vector_to_array(vector):
|
||||
return np.asarray([vector.x, vector.y, vector.z])
|
||||
|
||||
def workplane_along_vector(v_vec):
|
||||
most_sig_vec = norm_vector(v_vec)
|
||||
orth_vector = np.cross(most_sig_vec, np.random.randn(3))
|
||||
c_work_vec = cq.Workplane(cq.Plane(origin=(0,0,0), xDir=tuple(most_sig_vec), normal = tuple(orth_vector)))
|
||||
return c_work_vec
|
||||
|
||||
sliver = intersect(wp1,wp2)
|
||||
out = vertices_to_array(sliver.vertices().vals())
|
||||
|
||||
|
||||
dist_mat = squareform(pdist(out))
|
||||
distances = defaultdict(lambda: dict())
|
||||
|
||||
for x1 in range(len(out)):
|
||||
for x2 in range(len(out)):
|
||||
distances[np.around(dist_mat[x1,x2], decimals=5)][(x1,x2)] = out[x2] - out[x1]
|
||||
|
||||
|
||||
|
||||
long_vec = None
|
||||
long_idces = None
|
||||
long_arr = None
|
||||
for dist, ou in distances.items():
|
||||
ds = np.asarray([y for x,y in ou.items()])
|
||||
avg_vec = pround(np.mean(np.abs(ds), axis=0))
|
||||
cross_products = np.cross(ds, avg_vec)
|
||||
total_mag = np.linalg.norm(np.abs(cross_products))
|
||||
if dist > 0:
|
||||
if pround(total_mag) == 0:
|
||||
long_vec = avg_vec
|
||||
long_idces = [x for x in ou]
|
||||
long_arr = ds
|
||||
|
||||
vec_dir = norm_vector(long_vec)
|
||||
|
||||
wp1_com = cq.Shape.centerOfMass(wp1.objects[0])
|
||||
wp2_com = cq.Shape.centerOfMass(wp2.objects[0])
|
||||
|
||||
selector = cq.DirectionMinMaxSelector(cq.Vector(tuple(vec_dir)))
|
||||
wp1_top_face_vert = vertices_to_array(wp1.faces(selector).vertices().vals())
|
||||
wp2_top_face_vert = vertices_to_array(wp2.faces(selector).vertices().vals())
|
||||
|
||||
|
||||
orientations = np.dot(long_arr, long_vec)
|
||||
face_group_1 = list()
|
||||
face_group_2 = list()
|
||||
for idc, val in zip(long_idces, orientations):
|
||||
if val < 0:
|
||||
face_group_1.append(idc[0])
|
||||
face_group_2.append(idc[1])
|
||||
|
||||
|
||||
face_group_1_verts = out[face_group_1]
|
||||
face_group_2_verts = out[face_group_2]
|
||||
|
||||
face_group_1_mean = np.average(face_group_1_verts, axis=0);
|
||||
face_group_2_mean = np.average(face_group_2_verts, axis=0);
|
||||
|
||||
|
||||
wp1_top_mean = np.average(wp1_top_face_vert, axis=0)
|
||||
wp2_top_mean = np.average(wp2_top_face_vert, axis=0)
|
||||
|
||||
face_to_wp1_top = wp1_top_mean - face_group_1_mean
|
||||
face_to_wp2_top = wp2_top_mean - face_group_1_mean
|
||||
|
||||
|
||||
dir_to_wp1 = norm_vector( face_to_wp1_top - (np.dot(vec_dir, face_to_wp1_top))*vec_dir )
|
||||
dir_to_wp2 = norm_vector( face_to_wp2_top - (np.dot(vec_dir, face_to_wp2_top))*vec_dir )
|
||||
|
||||
step_d = (face_group_2_mean - face_group_1_mean)/(num_tabs)
|
||||
origins = list()
|
||||
for x in range(num_tabs+1):
|
||||
origins.append(np.average(face_group_1_verts, axis=0) + step_d*x)
|
||||
|
||||
objs = list()
|
||||
step_mag = float(np.linalg.norm(step_d))
|
||||
csel = cq.DirectionMinMaxSelector(cq.Vector(tuple(step_d)))
|
||||
cut_objs = list()
|
||||
for i_st in range(num_tabs):
|
||||
offset = -step_mag
|
||||
new_obj = sliver.faces(selector=csel).workplane(offset).split(keepTop=True, keepBottom=True)
|
||||
new_obj_0 = sliver.newObject([new_obj.objects[0]])
|
||||
new_obj_1 = sliver.newObject([new_obj.objects[1]])
|
||||
sliver = new_obj_1
|
||||
cut_objs.append(new_obj_0)
|
||||
|
||||
|
||||
|
||||
csel_wp1 = cq.DirectionMinMaxSelector(cq.Vector(tuple(dir_to_wp1)), directionMax=False)
|
||||
csel_wp2 = cq.DirectionMinMaxSelector(cq.Vector(tuple(dir_to_wp2)), directionMax=False)
|
||||
|
||||
csel_wp1_max = cq.DirectionMinMaxSelector(cq.Vector(tuple(dir_to_wp1)), directionMax=True)
|
||||
csel_wp2_max = cq.DirectionMinMaxSelector(cq.Vector(tuple(dir_to_wp2)), directionMax=True)
|
||||
|
||||
|
||||
|
||||
def cut_finger(wp1, cobj):
|
||||
wp1 = wp1.cut(cobj)
|
||||
return wp1
|
||||
|
||||
def cut_screw_slots(wp1, wp2, csel_wp1, csel_wp1_max, cobj, step_d):
|
||||
os1 = cobj.faces(csel_wp1).workplane()
|
||||
os1 = os1.cut(cobj)
|
||||
|
||||
if np.dot(vector_to_array(os1.plane.zDir), step_d) == 0:
|
||||
do_swap = True
|
||||
else:
|
||||
do_swap = False
|
||||
|
||||
os_s = os1.pushPoints([[0,0]]).circle(r_hole).extrude(-10)
|
||||
wp2 = wp2.cut(os_s)
|
||||
|
||||
|
||||
|
||||
pa = nut_width
|
||||
pb = 25
|
||||
if do_swap:
|
||||
pa, pb = pb, pa
|
||||
|
||||
os1 = cut_objs[idx].faces(csel_wp1_max).workplane()
|
||||
nut_slot = add_rect(os1.workplane(nut_depth),pa,pb,offx=-pa/2, offy=-pb/2).extrude(nut_thickness)
|
||||
wp1 = wp1.cut(nut_slot)
|
||||
|
||||
na = 2*r_hole
|
||||
nb = 25
|
||||
if do_swap:
|
||||
na, nb = nb, na
|
||||
|
||||
os1a = cut_objs[idx].faces(csel_wp1_max).workplane()
|
||||
screw_slot = add_rect(os1a,na,nb,offx=-na/2, offy=-nb/2).extrude(slot_depth)
|
||||
wp1 = wp1.cut(screw_slot)
|
||||
|
||||
return wp1, wp2, os_s, screw_slot, nut_slot, [os1, os1a]
|
||||
|
||||
for idx in range(len(cut_objs)):
|
||||
if idx % 2:
|
||||
wp1 = cut_finger(wp1, cut_objs[idx])
|
||||
wp1, wp2, hole, screw_slot, nut_slot, os1_planes = cut_screw_slots(wp1, wp2, csel_wp1, csel_wp1_max, cut_objs[idx], step_d)
|
||||
|
||||
else:
|
||||
wp2 = cut_finger(wp2, cut_objs[idx])
|
||||
wp2, wp1, hole, screw_slot, nut_slot, os2_planes = cut_screw_slots(wp2, wp1, csel_wp2, csel_wp2_max, cut_objs[idx], step_d)
|
||||
|
||||
# objs.append(nut_slot)
|
||||
# objs.append(screw_slot)
|
||||
objs.append(wp1)
|
||||
objs.append(wp2)
|
||||
|
||||
|
||||
for idx,x in enumerate(objs):
|
||||
show_object(x, options={'color':tuple(cmap.colors[idx%10]), 'alpha':0.5})
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user