|
1 | 1 | #! /usr/bin/env python |
2 | 2 | # -*- coding: utf-8 -*- |
3 | 3 | from __future__ import division |
4 | | -import os, sys, re |
| 4 | +import os |
| 5 | +import sys |
| 6 | +import re |
5 | 7 |
|
6 | 8 | # Assumes SolidPython is in site-packages or elsewhwere in sys.path |
7 | 9 | from solid import * |
|
10 | 12 | SEGMENTS = 24 |
11 | 13 |
|
12 | 14 | # FIXME: ought to be 5 |
13 | | -DFM = 5 # Default Material thickness |
| 15 | +DFM = 5 # Default Material thickness |
14 | 16 |
|
15 | 17 | tab_width = 5 |
16 | 18 | tab_offset = 4 |
|
21 | 23 | # It might be easier to have the edges NOT overlap at all and then have tabs |
22 | 24 | # for the slots added programmatically. -ETJ 06 Mar 2013 |
23 | 25 |
|
24 | | -def t_slot_holes(poly, point=None, edge_vec=RIGHT_VEC, screw_vec=DOWN_VEC, screw_type='m3', screw_length=16, material_thickness=DFM, kerf=0 ): |
| 26 | + |
| 27 | +def t_slot_holes(poly, point=None, edge_vec=RIGHT_VEC, screw_vec=DOWN_VEC, screw_type='m3', screw_length=16, material_thickness=DFM, kerf=0): |
25 | 28 | ''' |
26 | 29 | Cuts a screw hole and two notches in poly so they'll |
27 | 30 | interface with the features cut by t_slot() |
28 | | - |
| 31 | +
|
29 | 32 | Returns a copy of poly with holes removed |
30 | | - |
| 33 | +
|
31 | 34 | -- material_thickness is the thickness of the material *that will |
32 | 35 | be attached** to the t-slot, NOT necessarily the material that poly |
33 | 36 | will be cut on. |
34 | | - |
| 37 | +
|
35 | 38 | -- screw_vec is the direction the screw through poly will face; normal to poly |
36 | 39 | -- edge_vec orients the holes to the edge they run parallel to |
37 | | - |
| 40 | +
|
38 | 41 | TODO: add kerf calculations |
39 | 42 | ''' |
40 | 43 | point = point if point else ORIGIN |
41 | | - point = euclidify(point, Point3) |
| 44 | + point = euclidify(point, Point3) |
42 | 45 | screw_vec = euclidify(screw_vec, Vector3) |
43 | | - edge_vec = euclidify(edge_vec, Vector3) |
44 | | - |
45 | | - src_up = screw_vec.cross(edge_vec) |
46 | | - |
47 | | - |
48 | | - a_hole = square( [tab_width, material_thickness], center=True) |
49 | | - move_hole = tab_offset + tab_width/2 |
50 | | - tab_holes = left(move_hole)(a_hole) + right(move_hole)(a_hole) |
51 | | - |
52 | | - |
| 46 | + edge_vec = euclidify(edge_vec, Vector3) |
| 47 | + |
| 48 | + src_up = screw_vec.cross(edge_vec) |
| 49 | + |
| 50 | + a_hole = square([tab_width, material_thickness], center=True) |
| 51 | + move_hole = tab_offset + tab_width / 2 |
| 52 | + tab_holes = left(move_hole)(a_hole) + right(move_hole)(a_hole) |
| 53 | + |
53 | 54 | # Only valid for m3-m5 screws now |
54 | 55 | screw_dict = screw_dimensions.get(screw_type.lower()) |
55 | 56 | if screw_dict: |
56 | 57 | screw_w = screw_dict['screw_outer_diam'] |
57 | 58 | else: |
58 | | - raise ValueError( "Don't have screw dimensions for requested screw size %s"%screw_type) |
59 | | - |
| 59 | + raise ValueError( |
| 60 | + "Don't have screw dimensions for requested screw size %s" % screw_type) |
| 61 | + |
60 | 62 | # add the screw hole |
61 | | - tab_holes += circle(screw_w/2) # NOTE: needs any extra space? |
62 | | - |
63 | | - tab_holes = transform_to_point(tab_holes, point, dest_normal=screw_vec, src_normal=UP_VEC, src_up=src_up) |
64 | | - |
| 63 | + tab_holes += circle(screw_w / 2) # NOTE: needs any extra space? |
| 64 | + |
| 65 | + tab_holes = transform_to_point( |
| 66 | + tab_holes, point, dest_normal=screw_vec, src_normal=UP_VEC, src_up=src_up) |
| 67 | + |
65 | 68 | return poly - tab_holes |
66 | 69 |
|
67 | | -def t_slot( poly, point=None, screw_vec=DOWN_VEC, face_normal=UP_VEC, screw_type='m3', screw_length=16, material_thickness=DFM, kerf=0 ): |
| 70 | + |
| 71 | +def t_slot(poly, point=None, screw_vec=DOWN_VEC, face_normal=UP_VEC, screw_type='m3', screw_length=16, material_thickness=DFM, kerf=0): |
68 | 72 | ''' |
69 | 73 | Cuts a t-shaped shot in poly and adds two tabs |
70 | 74 | on the outside edge of poly. |
71 | | - |
| 75 | +
|
72 | 76 | Needs to be combined with t_slot_holes() on another |
73 | 77 | poly to make a valid t-slot connection |
74 | | - |
| 78 | +
|
75 | 79 | -- material_thickness is the thickness of the material *that will |
76 | 80 | be attached** to the t-slot, NOT necessarily the material that poly |
77 | 81 | will be cut on. |
78 | | - |
| 82 | +
|
79 | 83 | -- This method will align the t-slots where you tell them to go, |
80 | 84 | using point, screw_vec (the direction the screw will be inserted), and |
81 | 85 | face_normal, a vector normal to the face being altered. To avoid confusion, |
82 | 86 | it's often easiest to work on the XY plane. |
83 | | - |
84 | | - |
| 87 | +
|
| 88 | +
|
85 | 89 | TODO: include kerf in calculations |
86 | 90 | ''' |
87 | 91 | point = point if point else ORIGIN |
88 | 92 | point = euclidify(point, Point3) |
89 | | - screw_vec = euclidify(screw_vec, Vector3) |
| 93 | + screw_vec = euclidify(screw_vec, Vector3) |
90 | 94 | face_normal = euclidify(face_normal, Vector3) |
91 | 95 |
|
92 | 96 | tab = tab_poly(material_thickness=material_thickness) |
93 | | - slot = nut_trap_slot(screw_type, screw_length, material_thickness=material_thickness) |
94 | | - |
| 97 | + slot = nut_trap_slot( |
| 98 | + screw_type, screw_length, material_thickness=material_thickness) |
| 99 | + |
95 | 100 | # NOTE: dest_normal & src_normal are the same. This should matter, right? |
96 | | - tab = transform_to_point(tab, point, dest_normal=face_normal, src_normal=face_normal, src_up=-screw_vec) |
97 | | - slot = transform_to_point(slot, point, dest_normal=face_normal, src_normal=face_normal, src_up=-screw_vec) |
98 | | - |
| 101 | + tab = transform_to_point( |
| 102 | + tab, point, dest_normal=face_normal, src_normal=face_normal, src_up=-screw_vec) |
| 103 | + slot = transform_to_point( |
| 104 | + slot, point, dest_normal=face_normal, src_normal=face_normal, src_up=-screw_vec) |
| 105 | + |
99 | 106 | return poly + tab - slot |
100 | | - |
| 107 | + |
| 108 | + |
101 | 109 | def tab_poly(material_thickness=DFM): |
102 | | - |
103 | | - r = [ [ tab_width + tab_offset, -EPSILON], |
104 | | - [ tab_offset, -EPSILON], |
105 | | - [ tab_offset, material_thickness], |
106 | | - [ tab_width + tab_offset, material_thickness],] |
107 | | - |
108 | | - l = [ [-rp[0], rp[1]] for rp in r] |
| 110 | + |
| 111 | + r = [[tab_width + tab_offset, -EPSILON], |
| 112 | + [tab_offset, -EPSILON], |
| 113 | + [tab_offset, material_thickness], |
| 114 | + [tab_width + tab_offset, material_thickness], ] |
| 115 | + |
| 116 | + l = [[-rp[0], rp[1]] for rp in r] |
109 | 117 | tab_pts = l + r |
110 | 118 |
|
111 | | - tab_faces = [[0,1,2,3], [4,5,6,7]] |
| 119 | + tab_faces = [[0, 1, 2, 3], [4, 5, 6, 7]] |
112 | 120 | tab = polygon(tab_pts, tab_faces) |
113 | | - |
| 121 | + |
114 | 122 | # Round off the top points so tabs slide in more easily |
115 | 123 | round_tabs = False |
116 | 124 | if round_tabs: |
117 | | - points_to_round = [ [r[1], r[2], r[3]], |
118 | | - [r[2], r[3], r[0]], |
119 | | - [l[1], l[2], l[3]], |
120 | | - [l[2], l[3], l[0]], |
121 | | - ] |
122 | | - tab = fillet_2d(three_point_sets=points_to_round, orig_poly=tab, |
123 | | - fillet_rad=1, remove_material=True) |
124 | | - |
| 125 | + points_to_round = [[r[1], r[2], r[3]], |
| 126 | + [r[2], r[3], r[0]], |
| 127 | + [l[1], l[2], l[3]], |
| 128 | + [l[2], l[3], l[0]], |
| 129 | + ] |
| 130 | + tab = fillet_2d(three_point_sets=points_to_round, orig_poly=tab, |
| 131 | + fillet_rad=1, remove_material=True) |
| 132 | + |
125 | 133 | return tab |
126 | 134 |
|
127 | 135 |
|
128 | 136 | def nut_trap_slot(screw_type='m3', screw_length=16, material_thickness=DFM): |
129 | 137 | # This shape has a couple uses. |
130 | 138 | # 1) Right angle joint between two pieces of material. |
131 | | - # A bolt goes through the second piece and into the first. |
132 | | - |
133 | | - # 2) Set-screw for attaching to motor spindles. |
| 139 | + # A bolt goes through the second piece and into the first. |
| 140 | + |
| 141 | + # 2) Set-screw for attaching to motor spindles. |
134 | 142 | # Bolt goes full length into a sheet of material. Set material_thickness |
135 | | - # to something small (1-2 mm) to make sure there's adequate room to |
| 143 | + # to something small (1-2 mm) to make sure there's adequate room to |
136 | 144 | # tighten onto the shaft |
137 | | - |
138 | | - |
| 145 | + |
139 | 146 | # Only valid for m3-m5 screws now |
140 | 147 | screw_dict = screw_dimensions.get(screw_type.lower()) |
141 | 148 | if screw_dict: |
142 | 149 | screw_w = screw_dict['screw_outer_diam'] |
143 | | - screw_w2 = screw_w/2 |
144 | | - nut_hole_x = (screw_dict[ 'nut_inner_diam'] + 0.2)/2 # NOTE: How are these tolerances? |
| 150 | + screw_w2 = screw_w / 2 |
| 151 | + # NOTE: How are these tolerances? |
| 152 | + nut_hole_x = (screw_dict['nut_inner_diam'] + 0.2) / 2 |
145 | 153 | nut_hole_h = screw_dict['nut_thickness'] + 0.5 |
146 | 154 | slot_depth = material_thickness - screw_length - 0.5 |
147 | 155 | # If a nut isn't far enough into the material, the sections |
148 | 156 | # that hold the nut in may break off. Make sure it's at least |
149 | 157 | # half a centimeter. More would be better, actually |
150 | 158 | nut_loc = -5 |
151 | 159 | else: |
152 | | - raise ValueError( "Don't have screw dimensions for requested screw size %s"%screw_type) |
153 | | - |
154 | | - slot_pts = [[ screw_w2, EPSILON ], |
155 | | - [ screw_w2, nut_loc], |
156 | | - [ nut_hole_x, nut_loc], |
157 | | - [ nut_hole_x, nut_loc - nut_hole_h], |
158 | | - [ screw_w2, nut_loc - nut_hole_h], |
159 | | - [ screw_w2, slot_depth], |
| 160 | + raise ValueError( |
| 161 | + "Don't have screw dimensions for requested screw size %s" % screw_type) |
| 162 | + |
| 163 | + slot_pts = [[screw_w2, EPSILON], |
| 164 | + [screw_w2, nut_loc], |
| 165 | + [nut_hole_x, nut_loc], |
| 166 | + [nut_hole_x, nut_loc - nut_hole_h], |
| 167 | + [screw_w2, nut_loc - nut_hole_h], |
| 168 | + [screw_w2, slot_depth], |
160 | 169 | ] |
161 | 170 | # mirror the slot points on the left |
162 | | - slot_pts += [[-x, y] for x,y in slot_pts][ -1::-1] |
163 | | - |
| 171 | + slot_pts += [[-x, y] for x, y in slot_pts][-1::-1] |
| 172 | + |
164 | 173 | # TODO: round off top corners of slot |
165 | | - |
| 174 | + |
166 | 175 | # Add circles around t edges to prevent acrylic breakage |
167 | 176 | slot = polygon(slot_pts) |
168 | 177 | slot = union()( |
169 | | - slot, |
170 | | - translate( [nut_hole_x, nut_loc])(circle(tab_curve_rad)), |
171 | | - translate( [-nut_hole_x, nut_loc])(circle(tab_curve_rad)) |
172 | | - ) |
| 178 | + slot, |
| 179 | + translate([nut_hole_x, nut_loc])(circle(tab_curve_rad)), |
| 180 | + translate([-nut_hole_x, nut_loc])(circle(tab_curve_rad)) |
| 181 | + ) |
173 | 182 | return render()(slot) |
174 | 183 |
|
| 184 | + |
175 | 185 | def assembly(): |
176 | 186 | a = union() |
177 | | - |
| 187 | + |
178 | 188 | return a |
179 | 189 |
|
180 | 190 | if __name__ == '__main__': |
181 | | - a = assembly() |
182 | | - scad_render_to_file(a, file_header='$fn = %s;'%SEGMENTS, include_orig_code=True) |
| 191 | + a = assembly() |
| 192 | + scad_render_to_file(a, file_header='$fn = %s;' % |
| 193 | + SEGMENTS, include_orig_code=True) |
0 commit comments