forked from jeffminton/keyboard_stl_generator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparameters.py
366 lines (268 loc) · 14.4 KB
/
parameters.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
import logging
import math
import sys
from pathlib import PurePath
from switch_config import SwitchConfig
# from cell import Cell
class Parameters():
# SWITCH_SPACING = 19.05
def __init__(self, parameter_dict: dict = None):
self.logger = logging.getLogger(__name__)
self.parameter_dict = parameter_dict
# self.default_parameter_dict = {
# 'plate_supports': True,
# 'x_build_size' : 200,
# 'y_build_size' : 200,
# 'switch_type': 'mx_openable',
# 'stabilizer_type': 'cherry',
# 'custom_shape': False,
# 'custom_shape_points': None,
# 'custom_shape_path': None,
# 'kerf' : 0.00,
# 'top_margin' : 0,
# 'bottom_margin' : 0,
# 'left_margin' : 0,
# 'right_margin' : 0,
# 'case_height' : 10,
# # 'plate_wall_thickness' : 2.0,
# 'case_wall_thickness' : 0.0,
# 'plate_thickness' : 1.111,
# 'plate_corner_radius' : 0,
# 'bottom_cover_thickness': 0,
# 'support_bar_height' : 3.0,
# 'support_bar_width' : 1.0,
# 'tilt': 0.0,
# 'simple_test': False,
# 'screw_count': 0,
# 'screw_diameter': 0,
# 'screw_edge_inset': 0,
# 'cable_hole': False,
# 'hole_width': 10,
# 'hole_height': 10,
# 'cable_hole_down_offset': 1
# }
self.paramater_alternate_dict = {
'plate_wall_thickness': 'case_wall_thickness'
}
self.switch_spacing = 19.05
self.x_build_size = 200
self.y_build_size = 200
self.kerf = 0.01
self.switch_type = 'mx_openable'
self.stabilizer_type = 'cherry_costar'
# Custom Switch Cutout Attributes
self.custom_shape = False
self.custom_shape_points = None
self.custom_shape_path = None
self.plate_supports = True
self.support_bar_height = 3.0
self.support_bar_width = 3.0
self.top_margin = 10
self.bottom_margin = 10
self.left_margin = 10
self.right_margin = 10
self.case_height = 18
self.case_wall_thickness = 3.0
self.plate_thickness = 1.111
self.plate_corner_radius = 4
self.bottom_cover_thickness = 1
self.tilt = 2.0
self.simple_test = False
self.screw_count = 4
self.screw_diameter = 4
self.screw_edge_inset = 7
self.screw_edge_x_inset = None
self.screw_edge_y_inset = None
self.screw_hole_body_wall_width = 2
self.screw_hole_body_support_x_factor = 4
self.custom_screw_hole_coordinates_origin = [0, 0]
self.custom_screw_hole_coordinates = None
self.cable_hole = False
self.cable_diameter = 4
self.cable_hole_width = 10
self.cable_hole_height = 10
self.cable_hole_up_offset = 1
self.cable_hole_down_offset = 1
self.custom_polygons = None
self.custom_pcb = None
self.pcb_width = None
self.pcb_height = None
self.pcb_top_left_coordinates = None
self.pcb_left_switch_center_x_coordinate = None
self.pcb_top_switch_center_y_coordinate = None
self.pcb_case_top_margin = None
self.pcb_case_bottom_margin = None
self.pcb_case_right_margin = None
self.pcb_case_left_margin = None
self.test_block = False
self.test_block_x_start = 0
self.test_block_x_end = 0
self.test_block_y_start = 0
self.test_block_y_end = 0
self.test_block_z_start = 0
self.test_block_z_end = 0
self.switch_config = None
self.min_x = 0.0
self.max_x = 0.0
self.min_y = 0.0
self.max_y = 0.0
self.real_max_x = 0.0
self.real_max_y = 0.0
self.real_case_width = 0.0
self.real_case_height = 0.0
self.case_height_extra = 50
# Calculated attributes
self.case_height_base_removed = None
self.case_height_extra_fill = None
self.side_margin_diff = None
self.top_margin_diff = None
self.screw_tap_hole_diameter = None
self.screw_hole_body_diameter = None
self.screw_hole_body_radius = None
self.x_screw_width = None
self.y_screw_width = None
self.bottom_section_count = None
self.screw_hole_body_support_end_x = None
if self.parameter_dict is not None:
self.build_attr_from_dict(self.parameter_dict)
# self.validate_parameters()
def __repr__(self):
output = 'Parameters:\n'
ignore_attr_names = [
'logger', 'parameter_dict', 'switch_config',
'min_x', 'max_x', 'min_y', 'max_y',
'real_max_x', 'real_max_y',
# 'real_case_width', 'real_case_height',
'case_height_extra', 'case_height_base_removed', 'case_height_extra_fill', 'side_margin_diff',
'top_margin_diff', 'screw_tap_hole_diameter', 'screw_hole_body_diameter', 'screw_hole_body_radius',
'x_screw_width', 'y_screw_width', 'bottom_section_count', 'screw_hole_body_support_end_x',
'test_block', 'test_block_x_start', 'test_block_x_end', 'test_block_y_start',
'test_block_y_end', 'test_block_z_start', 'test_block_z_end'
]
for attr_name in self.__dict__:
if attr_name not in ignore_attr_names:
output += '%s: %s\n' % (attr_name, str(self.__dict__[attr_name]))
return output
def U(self, u_value):
return u_value * self.switch_spacing
def update_calculated_attributes(self):
# Calculated attributes
if self.screw_edge_x_inset is None:
self.screw_edge_x_inset = self.screw_edge_inset
if self.screw_edge_y_inset is None:
self.screw_edge_y_inset = self.screw_edge_inset
self.case_height_base_removed = self.case_height - self.bottom_cover_thickness
self.case_height_extra_fill = self.case_height + self.case_height_extra
self.side_margin_diff = self.right_margin - self.left_margin
self.top_margin_diff = self.bottom_margin - self.top_margin
self.screw_tap_hole_diameter = self.screw_diameter - 0.35
self.screw_hole_body_diameter = self.screw_diameter + (self.screw_hole_body_wall_width * 2)
self.screw_hole_body_radius = self.screw_hole_body_diameter / 2
self.x_screw_width = self.real_case_width - ((self.screw_edge_x_inset * 2))# + self.screw_diameter)
self.y_screw_width = self.real_case_height - ((self.screw_edge_y_inset * 2))# + self.screw_diameter)
self.bottom_section_count = math.ceil(self.real_case_width / self.x_build_size)
self.screw_hole_body_support_end_x = (self.case_height_extra_fill / self.screw_hole_body_support_x_factor) + self.screw_hole_body_radius
def set_dimensions(self, max_x, min_y, min_x, max_y):
self.max_x = max_x
self.max_x = max_x
self.min_y = min_y
self.max_y = max_y
self.logger.debug('min_x: %f, max_x: %f, max_y: %f, min_y: %f', self.min_x, self.max_x, self.max_y, self.min_y)
# Get rhe calculated real max and y sizes of the board
self.real_max_x = self.U(self.max_x)
self.real_max_y = self.U(abs(self.min_y))
self.real_case_width = self.real_max_x + self.left_margin + self.right_margin
self.real_case_height = self.real_max_y + self.top_margin + self.bottom_margin
if self.custom_screw_hole_coordinates is not None:
self.screw_edge_x_inset = 0
self.screw_edge_y_inset = 0
self.logger.debug('Custom Screw Default: screw_edge_x_inset: %f, screw_edge_y_inset: %f', self.screw_edge_x_inset, self.screw_edge_y_inset)
if self.custom_pcb == True:
half_u = self.U(1) / 2
# Get the top left coordinates for the PCB itself.
pcb_x_coordinate = 0
pcb_y_coordinate = 0
if self.pcb_top_left_coordinates is not None:
pcb_x_coordinate = self.pcb_top_left_coordinates[0]
pcb_y_coordinate = self.pcb_top_left_coordinates[1]
# Get the x any y coordinates of the top reference switch and left reference switch
left_switch_left_x_coordinate = self.pcb_left_switch_center_x_coordinate - half_u
top_switch_top_y_coordinate = self.pcb_top_switch_center_y_coordinate - half_u
# Get the margin built into the left and top of the PCB
pcb_left_margin = left_switch_left_x_coordinate - pcb_x_coordinate
pcb_top_margin = top_switch_top_y_coordinate - pcb_y_coordinate
pcb_right_margin = self.pcb_width - (pcb_left_margin + self.real_max_x)
pcb_bottom_margin = self.pcb_height - (pcb_top_margin + self.real_max_y)
self.left_margin = self.case_wall_thickness + self.pcb_case_left_margin + pcb_left_margin
self.right_margin = self.case_wall_thickness + self.pcb_case_right_margin + pcb_right_margin
self.top_margin = self.case_wall_thickness + self.pcb_case_top_margin + pcb_top_margin
self.bottom_margin = self.case_wall_thickness + self.pcb_case_bottom_margin + pcb_bottom_margin
if self.custom_screw_hole_coordinates is not None:
screw_hole_origin_x = self.custom_screw_hole_coordinates_origin[0]
screw_hole_origin_y = self.custom_screw_hole_coordinates_origin[1]
screw_hole_pcb_origin_x_offset = screw_hole_origin_x - pcb_x_coordinate
screw_hole_pcb_origin_y_offset = (pcb_y_coordinate + self.pcb_height) - screw_hole_origin_y
self.screw_edge_x_inset = self.case_wall_thickness + self.pcb_case_left_margin + screw_hole_pcb_origin_x_offset
self.screw_edge_y_inset = self.case_wall_thickness + self.pcb_case_bottom_margin + screw_hole_pcb_origin_y_offset
self.logger.debug('PCB settings: screw_edge_x_inset: %f, screw_edge_y_inset: %f', self.screw_edge_x_inset, self.screw_edge_y_inset)
self.logger.debug('real_max_x: %d, real_max_y: %s', self.real_max_x, self.real_max_y)
self.update_calculated_attributes()
def build_attr_from_dict(self, parameter_dict):
for param in parameter_dict.keys():
ignore_deprecated = False
value = parameter_dict[param]
# If the current parameter has been deprecated by another parameter get the new parameter name
if param in self.paramater_alternate_dict.keys():
alt_param = self.paramater_alternate_dict[param]
# If the new version of the parameter is not in the paramter dict then us the value in the deprectaed parameter
if alt_param not in parameter_dict.keys():
param = alt_param
else:
# If the new version of the parameter is in the dict then ignore the current deprecated parameter
ignore_deprecated = True
if param == 'custom_switch':
if 'points' not in value.keys():
raise AttributeError('A set of "points" must exist in the "custom_switch" to use a custom switch')
self.custom_shape_points = value['points']
if 'path' in value.keys():
self.custom_shape_path = value['path']
else:
self.logger.warning('Custom Switch defined but no "path" list defined. Points in "ponts" list will be used in defined order')
self.custom_shape = True
if ignore_deprecated == False:
setattr(self, param, value)
self.switch_config = SwitchConfig(kerf = self.kerf, switch_type = self.switch_type, stabilizer_type = self.stabilizer_type, custom_shape = self.custom_shape, custom_shape_points = self.custom_shape_points, custom_shape_path = self.custom_shape_path)
self.update_calculated_attributes()
self.validate_parameters()
def set_parameter_dict(self, parameter_dict):
self.parameter_dict = parameter_dict
self.build_attr_from_dict(self.parameter_dict)
# def get_param(self, paramaeter_name):
# if self.parameter_dict is not None and paramaeter_name in self.parameter_dict.keys():
# return self.parameter_dict[paramaeter_name]
# elif paramaeter_name in self.default_parameter_dict.keys():
# return self.default_parameter_dict[paramaeter_name]
# else:
# raise ValueError('No paramter exists with name %s' % (paramaeter_name))
def validate_parameters(self):
parameter_error = False
error_message = ''
# if self.screw_edge_inset < self.case_wall_thickness + self.screw_hole_body_radius:
# parameter_error = True
# error_message += 'Screw Edge Inset %f must be greater than case_wall_thickness: %f + screw_hole_body_radius: %f = %f\n' % (self.screw_edge_inset, self.case_wall_thickness, self.screw_hole_body_radius, self.case_wall_thickness + self.screw_hole_body_radius)
if self.screw_count > 0 :
if self.screw_count < 4:
parameter_error = True
error_message += 'Screw count must be at least 4\n'
if self.screw_count % 2 != 0:
parameter_error = True
error_message += 'Screw count must be even\n'
if self.switch_type not in self.switch_config.switch_type_function_dict.keys():
parameter_error = True
error_message += 'switch type %s is not a valid switch type' % (self.switch_type)
if self.stabilizer_type not in self.switch_config.stab_type_function_dict.keys():
parameter_error = True
error_message += 'stabilizer type %s is not a valid stabilizer type' % (self.stabilizer_type)
if parameter_error == True:
print('ERROR:', error_message)
exit(1)