FreeCAD-macros

Форк
0
/
ScrewMaker.FCMacro 
5413 строк · 193.2 Кб
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
"""
4
Macro to generate screws with FreeCAD.
5
Version 1.4 from 1st of September 2013
6
Version 1.5 from 23rd of December 2013
7
Corrected hex-heads above M12 not done.
8
Version 1.6 from 15th of March 2014
9
Added PySide support
10

11
Version 1.7 from April 2014
12
fixed bool type error. (int is not anymore accepted at linux)
13
fixed starting point of real thread at some screw types.
14

15
Version 1.8 from July 2014
16
first approach for a faster real thread
17

18
Version 1.9 / 2.0 July 2015
19
new calculation of starting point of thread
20
shell-based approach for screw generation
21
added:
22
ISO 14582 Hexalobular socket countersunk head screws, high head
23
ISO 14584 Hexalobular socket raised countersunk head screws
24
ISO 7380-2 Hexagon socket button head screws with collar
25
DIN 967 Cross recessed pan head screws with collar
26
ISO 4032 Hexagon nuts, Style 1
27
ISO 4033 Hexagon nuts, Style 2
28
ISO 4035 Hexagon thin nuts, chamfered
29
EN 1661 Hexagon nuts with flange
30
ISO 7094 definitions  Plain washers - Extra large series
31
ISO 7092 definitions  Plain washers - Small series
32
ISO 7093-1 Plain washer - Large series
33
Screw-tap to drill inner threads in parts with user defined length
34

35
ScrewMaker can now also used as a python module.
36
The following shows how to generate a screw from a python script:
37
  import screw_maker2_0
38

39
  threadDef = 'M3.5'
40
  o = screw_maker2_0.Screw()
41
  t = screw_maker2_0.Screw.setThreadType(o,'real')
42
  # Creates a Document-Object with label describing the screw
43
  d = screw_maker2_0.Screw.createScrew(o, 'ISO1207', threadDef, '20', 'real')
44

45
  # creates a shape in memory
46
  t = screw_maker2_0.Screw.setThreadType(o,'real')
47
  s = screw_maker1_9d.Screw.makeIso7046(o, 'ISO14582', threadDef, 40.0)
48
  Part.show(s)
49

50
Version 2.1 August 2015
51
added:
52
ISO 8676 Hexagon head screw with metric fine pitch thread
53

54
Version 2.2 May 2018
55
- Extend function "moveScrew" to check for Body and Part.
56
- Add Screw to Part if Body is in Part.
57
- Search for plane support face to get correct orientation
58
- fix failed hex-head
59

60
Version 2.3 Oct 2018
61
- fix missing function equal_vertex
62

63
to do: check ISO7380 usage of rs and rt, actual only rs is used
64
check chamfer angle on hexogon heads and nuts
65
***************************************************************************
66
*   Copyright (c) 2013, 2014, 2015 2018                                   *
67
*   Ulrich Brammer <ulrich1a[at]users.sourceforge.net>                    *
68
*                                                                         *
69
*   This file is a supplement to the FreeCAD CAx development system.      *
70
*                                                                         *
71
*   This program is free software; you can redistribute it and/or modify  *
72
*   it under the terms of the GNU Lesser General Public License (LGPL)    *
73
*   as published by the Free Software Foundation; either version 2 of     *
74
*   the License, or (at your option) any later version.                   *
75
*   for detail see the LICENCE text file.                                 *
76
*                                                                         *
77
*   This software is distributed in the hope that it will be useful,      *
78
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
79
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
80
*   GNU Library General Public License for more details.                  *
81
*                                                                         *
82
*   You should have received a copy of the GNU Library General Public     *
83
*   License along with this macro; if not, write to the Free Software     *
84
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
85
*   USA                                                                   *
86
*                                                                         *
87
***************************************************************************
88
"""
89
from __future__ import division
90

91
__Name__ = 'Screw Maker'
92
__Comment__ = 'Generate a screw'
93
__Author__ = "Ulrich Brammer <ulrich1a@users.sourceforge.net>"
94
__Version__ = '2.3.1'
95
__Date__ = '2018-10-22'
96
__License__ = 'LGPL2+'
97
__Web__ = 'http://freecadweb.org/wiki/Macro_screw_maker1_2'
98
__Wiki__ = 'http://freecadweb.org/wiki/Macro_screw_maker1_2'
99
__Icon__ = ''
100
__Help__ = 'Select the characteristics of the screw and click on the create button'
101
__Status__ = ''
102
__Requires__ = ''
103
__Communication__ = ''
104
__Files__ = ''
105

106
import math
107

108
import FreeCAD
109
import FreeCADGui
110
import Part
111
from FreeCAD import Base
112
import DraftVecUtils
113

114
try:
115
  from PySide import QtCore, QtGui
116
  #FreeCAD.Console.PrintMessage("PySide is used" + "\n")
117
except ImportError:
118
  #FreeCAD.Console.PrintMessage("PyQt4 is needed" + "\n")
119
  from PyQt4 import QtCore, QtGui
120

121
try:
122
  _encoding = QtGui.QApplication.UnicodeUTF8
123
  def tr(context, text):
124
    return QtGui.QApplication.translate(context, text, None, _encoding)
125
except AttributeError:
126
  def tr(context, text):
127
    return QtGui.QApplication.translate(context, text, None)
128

129
DEBUG = False # set to True to show debug messages; does not work, still todo.
130

131
debObject = None
132

133
# Diameters included in this library/macro.
134
# Some ISO-standards may include more diameters!
135
# Dictionary used for user messages
136
standard_diameters = {
137
  'ISO4017': ('M1.6', 'M64'), # ISO 4017 Hex-head-screw
138
  'ISO4014': ('M1.6', 'M64'), # ISO 4014 Hex-head-bolt
139
  'EN1662':  ('M5',   'M16'), # EN 1662 Hexagon bolts with flange, small series
140
  'EN1665':  ('M5',   'M20'), # EN 1665 Hexagon bolts with flange, heavy series
141
  'ISO8676': ('M8x1', 'M64x4'), # ISO 8676 Hexagon head screw with metric fine pitch thread
142
  'ISO4762': ('M1.6', 'M64'), # ISO 4762 Hexagon socket head cap screws
143
  'ISO2009': ('M1.6', 'M10'), # ISO 2009 Slotted countersunk flat head screws
144
  'ISO2010': ('M1.6', 'M10'), # ISO 2010 Slotted raised countersunk head screws
145
  'ISO1580': ('M1.6', 'M10'), # ISO 1580 Slotted pan head screws
146
  'ISO7045': ('M1.6', 'M10'), # ISO 7045 Pan head screws type H cross recess
147
  'ISO7046': ('M1.6', 'M10'),
148
  'ISO7047': ('M1.6', 'M10'),
149
  'ISO1207': ('M3',   'M10'), # ISO 1207 Slotted cheese head screws
150
  'ISO7048': ('M2.5', 'M8'),  # ISO 7048 Cross-recessed cheese head screws with type H cross recess
151
  'ISO7380-1':('M3',  'M16'), # ISO 7380 Hexagon socket button head screws
152
  'ISO7380-2':('M3',  'M16'), # ISO 7380 Hexagon socket button head screws with collar
153
  'DIN967'  :('M3',   'M8'),  # DIN 967 Cross recessed pan head screws with collar
154
  'ISO10642':('M3',   'M20'), # ISO 10642 Hexagon socket countersunk head screws
155
  'ISO14579':('M2',   'M20'), # ISO 14579 Hexalobular socket head cap screws
156
  'ISO14580':('M2',   'M10'), # ISO 14580 Hexalobular socket cheese head screws
157
  'ISO14581':('M2',   'M10'), # ISO 14581 Hexalobular socket countersunk flat head screws (to do!!)
158
  'ISO14582':('M3',   'M10'), # ISO 14582 Hexalobular socket countersunk head screws, high head
159
  'ISO14583':('M2',   'M10'), # ISO 14583 Hexalobular socket pan head screws
160
  'ISO14584':('M2',   'M10'), # ISO 14584 Hexalobular socket raised countersunk head screws
161
  'ISO7089': ('M1.6', 'M64'), # Washer
162
  'ISO7090': ('M5',   'M64'), # ISO 7090 definitions Plain washers, chamfered - Normal series
163
  'ISO7091': ('M1.6', 'M64'), # ISO 7091 definitions  Plain washer - Normal series Product Grade C
164
  'ISO7092': ('M1.6', 'M36'), # ISO 7092 definitions  Plain washers - Small series
165
  'ISO7093-1': ('M3', 'M36'), # ISO 7093-1 Plain washer - Large series
166
  'ISO7094': ('M5',   'M36'), # ISO 7094 definitions  Plain washers - Extra large series
167
  'ISO4032': ('M1.6', 'M64'), # ISO 4032 Hexagon nuts, Style 1
168
  'ISO4033': ('M5',   'M36'), # ISO 4033 Hexagon nuts, Style 2
169
  'ISO4035': ('M1.6', 'M64'), # ISO 4035 Hexagon thin nuts, chamfered
170
  'ISO4036': ('M1.6', 'M10'), # ISO 4035 Hexagon thin nuts, unchamfered, todo no function coded
171
  'EN1661':  ('M5',   'M20')} # EN 1661 Hexagon nuts with flange
172

173
# ISO 4017 Hex-head-screw
174
#           P,    c,  dw,    e,     k,   r,   s
175
iso4017head={
176
  'M1.6':  (0.35, 0.2, 2.9,  3.4,   1.1, 0.1,  3.2),
177
  'M2':    (0.40, 0.2, 3.7,  4.4,   1.4, 0.1,  4.0),
178
  'M2.5':  (0.45, 0.2, 4.6,  5.5,   1.7, 0.1,  5.0),
179
  'M3':    (0.5,  0.2, 5.2,  6.1,   2.0, 0.1,  5.5),
180
  '(M3.5)':(0.6,  0.2, 5.2,  6.6,   2.4, 0.1,  5.5),
181
  'M4':    (0.7,  0.2, 6.6,  7.7,   2.8, 0.2,  7.0),
182
  'M5':    (0.8,  0.2, 7.5,  8.9,   3.5, 0.2,  8.0),
183
  'M6':    (1.0,  0.2, 9.5,  11.05, 4.0, 0.25, 10.0),
184
  'M8':    (1.25, 0.3, 11.7, 14.5,  5.3, 0.25, 13.0),
185
  'M10':   (1.50, 0.3, 14.7, 17.9,  6.4, 0.4,  16.0),
186
  'M12':   (1.75, 0.3, 16.7, 20.1,  7.5, 0.6,  18.0),
187
  '(M14)': (2.00, 0.3, 20.5, 24.5,  8.8, 0.6,  22.0),
188
  'M16':   (2.00, 0.4, 22.4, 26.9, 10.0, 0.6,  24.0),
189
  '(M18)': (2.50, 0.4, 25.4, 30.2, 11.5, 0.6,  27.0),
190
  'M20':   (2.50, 0.4, 28.2, 33.7, 12.5, 0.8,  30.0),
191
  '(M22)': (2.50, 0.4, 31.8, 37.7, 14.0, 0.8,  34.0),
192
  'M24':   (3.00, 0.4, 33.7, 40.1, 15.0, 0.8,  36.0),
193
  '(M27)': (3.00, 0.4, 38.0, 45.2, 17.0, 1.0,  41.0),
194
  'M30':   (3.50, 0.4, 42.8, 50.9, 18.7, 1.0,  46.0), #dw not in class A, e not in class A
195
  '(M33)': (3.50, 0.4, 46.6, 55.4, 21.0, 1.0,  50.0),
196
  'M36':   (4.00, 0.4, 51.2, 61.0, 22.5, 1.0,  55.0), #dw not in class A, e not in class A
197
  '(M39)': (4.00, 0.5, 55.9, 66.5, 25.0, 1.0,  60.0),
198
  'M42':   (4.50, 0.7, 60.0, 71.3, 26.0, 1.2,  65.0),
199
  '(M45)': (4.50, 0.7, 64.7, 77.0, 28.0, 1.2,  70.0),
200
  'M48':   (5.00, 0.7, 69.5, 82.6, 30.0, 1.6,  75.0),
201
  '(M52)': (5.00, 0.7, 74.5, 88.3, 33.0, 1.6,  80.0),
202
  'M56':   (5.50, 0.7, 78.7, 93.6, 35.0, 2.0,  85.0),
203
  '(M60)': (5.50, 0.7, 82.7, 99.2, 38.0, 2.0,  90.0),
204
  'M64':   (6.00, 0.7, 88.2,104.9, 40.0, 2.0,  95.0)
205
  }
206

207
iso4017length = {
208
  '2': ( 1.8,  2.2),
209
  '3': ( 2.8,  3.2),
210
  '4': ( 3.76, 4.24),
211
  '5': ( 4.76, 5.24),
212
  '6': ( 5.76, 6.24),
213
  '8': ( 7.71, 8.29),
214
  '10':( 9.71, 10.29),
215
  '12':(11.65, 12.35),
216
  '14':(13.65, 14.35),
217
  '16':(15.65, 16.35),
218
  '20':(19.58, 20.42),
219
  '25':(24.58, 25.42),
220
  '30':(29.58, 30.42),
221
  '35':(34.5,  35.5),
222
  '40':(39.5,  40.5),
223
  '45':(44.5,  45.5),
224
  '50':(49.5,  50.5),
225
  '55':(54.4, 55.6),
226
  '60':(59.4, 60.6),
227
  '65':(64.4, 65.6),
228
  '70':(69.4, 70.6),
229
  '80':(79.4, 80.6),
230
  '100':(99.3, 100.7),
231
  '110':(109.3, 110.7),
232
  '120':(119.3, 120.7),
233
  '130':(129.2, 130.8),
234
  '140':(139.2, 130.8),
235
  '150':(149.2, 150.8),
236
  '160':(159.2, 160.8),
237
  '180':(179.2, 180.8),
238
  '200':(199.1, 200.9)
239
  }
240

241
# range of typical screw lengths
242
#    min_length,  max_length
243
iso4017range = {
244
  'M1.6':  ('2', '16'),
245
  'M2':    ('4', '20'),
246
  'M2.5':  ('5', '25'),
247
  'M3':    ('5', '30'),
248
  '(M3.5)':('8', '35'),
249
  'M4':    ('6', '40'),
250
  'M5':    ('8', '50'),
251
  'M6':   ('12', '60'),
252
  'M8':   ('16', '80'),
253
  'M10':  ('20','100'),
254
  'M12':  ('25','120'),
255
  '(M14)':('25','140'),
256
  'M16':  ('30','150'),
257
  '(M18)':('35','200'),
258
  'M20':  ('40','160'),
259
  '(M22)':('45','200'),
260
  'M24':  ('50','180'),
261
  '(M27)':('50','100'),
262
  'M30':  ('60','200'),
263
  '(M33)':('65','200'),
264
  'M36':  ('70','200'),
265
  '(M39)':('80','200'),
266
  'M42':  ('70','200'),
267
  '(M45)':('90','200'),
268
  'M48': ('100','200'),
269
  '(M52)':('100','200'),
270
  'M56':  ('110','200'),
271
  '(M60)':('120','200'),
272
  'M64':  ('120','200')
273
  }
274

275
# ISO 8676 Hexagon head screw with metric fine pitch thread
276
#                P,    c,  dw,    e,     k,   r,   s
277
iso8676def={
278
  'M8x1':      (1.00, 0.3, 11.7, 14.5,  5.3, 0.25, 13.0),
279
  'M10x1':     (1.00, 0.3, 14.7, 17.9,  6.4, 0.4,  16.0),
280
  '(M10x1.25)':(1.25, 0.3, 14.7, 17.9,  6.4, 0.4,  16.0),
281
  'M12x1.5':   (1.50, 0.3, 16.7, 20.1,  7.5, 0.6,  18.0),
282
  '(M12x1.25)':(1.75, 0.3, 16.7, 20.1,  7.5, 0.6,  18.0),
283
  '(M14x1.5)': (1.50, 0.3, 20.5, 24.5,  8.8, 0.6,  22.0),
284
  'M16x1.5':   (1.50, 0.4, 22.4, 26.9, 10.0, 0.6,  24.0),
285
  '(M18x1.5)': (1.50, 0.4, 25.4, 30.2, 11.5, 0.6,  27.0),
286
  'M20x1.5':   (1.50, 0.4, 28.2, 33.7, 12.5, 0.8,  30.0),
287
  '(M20x2)':   (2.00, 0.4, 28.2, 33.7, 12.5, 0.8,  30.0),
288
  '(M22x1.5)': (1.50, 0.4, 31.8, 37.7, 14.0, 0.8,  34.0),
289
  'M24x2':     (2.00, 0.4, 33.7, 40.1, 15.0, 0.8,  36.0),
290
  '(M27x2)':   (2.00, 0.4, 38.0, 45.2, 17.0, 1.0,  41.0),
291
  'M30x2':     (2.00, 0.4, 42.8, 50.9, 18.7, 1.0,  46.0), #dw not in class A, e not in class A
292
  '(M33x2)':   (2.00, 0.4, 46.6, 55.4, 21.0, 1.0,  50.0),
293
  'M36x3':     (3.00, 0.4, 51.2, 61.0, 22.5, 1.0,  55.0), #dw not in class A, e not in class A
294
  '(M39x3)':   (3.00, 0.5, 55.9, 66.5, 25.0, 1.0,  60.0),
295
  'M42x3':     (3.00, 0.7, 60.0, 71.3, 26.0, 1.2,  65.0),
296
  '(M45x3)':   (3.00, 0.7, 64.7, 77.0, 28.0, 1.2,  70.0),
297
  'M48x3':     (3.00, 0.7, 69.5, 82.6, 30.0, 1.6,  75.0),
298
  '(M52x4)':   (4.00, 0.7, 74.5, 88.3, 33.0, 1.6,  80.0),
299
  'M56x4':     (4.00, 0.7, 78.7, 93.6, 35.0, 2.0,  85.0),
300
  '(M60x4)':   (4.00, 0.7, 82.7, 99.2, 38.0, 2.0,  90.0),
301
  'M64x4':     (4.00, 0.7, 88.2,104.9, 40.0, 2.0,  95.0)
302
  }
303

304
iso8676length = {
305
  '16':(15.65, 16.35),
306
  '20':(19.58, 20.42),
307
  '25':(24.58, 25.42),
308
  '30':(29.58, 30.42),
309
  '35':(34.5,  35.5),
310
  '40':(39.5,  40.5),
311
  '45':(44.5,  45.5),
312
  '50':(49.5,  50.5),
313
  '55':(54.4, 55.6),
314
  '60':(59.4, 60.6),
315
  '65':(64.4, 65.6),
316
  '70':(69.4, 70.6),
317
  '80':(79.4, 80.6),
318
  '100':(99.3, 100.7),
319
  '110':(109.3, 110.7),
320
  '120':(119.3, 120.7),
321
  '130':(129.2, 130.8),
322
  '140':(139.2, 130.8),
323
  '150':(149.2, 150.8),
324
  '160':(159.2, 160.8),
325
  '180':(179.2, 180.8),
326
  '200':(199.1, 200.9),
327
  '220':(217.7, 222.3),
328
  '240':(237.7, 242.3),
329
  '260':(219.1, 220.9),
330
  '280':(219.1, 220.9),
331
  '300':(219.1, 220.9),
332
  '320':(219.1, 220.9),
333
  '340':(219.1, 220.9),
334
  '360':(219.1, 220.9),
335
  '380':(219.1, 220.9),
336
  '400':(219.1, 220.9),
337
  '420':(219.1, 220.9),
338
  '440':(219.1, 220.9),
339
  '460':(219.1, 220.9),
340
  '480':(219.1, 220.9),
341
  '500':(496.85, 503.15)
342
  }
343

344
# range of typical screw lengths
345
#    min_length,  max_length
346
iso8676range = {
347
  'M8x1':      ('16', '80'),
348
  'M10x1':     ('20','100'),
349
  '(M10x1.25)':('20','100'),
350
  'M12x1.5':   ('25','120'),
351
  '(M12x1.25)':('25','120'),
352
  '(M14x1.5)': ('30','140'),
353
  'M16x1.5':   ('35','160'),
354
  '(M18x1.5)': ('35','180'),
355
  'M20x1.5':   ('40','200'),
356
  '(M20x2)':   ('40','200'),
357
  '(M22x1.5)': ('45','220'),
358
  'M24x2':     ('40','200'),
359
  '(M27x2)':   ('55','260'),
360
  'M30x2':     ('40','200'),
361
  '(M33x2)':   ('65','360'),
362
  'M36x3':     ('40','200'),
363
  '(M39x3)':   ('80','380'),
364
  'M42x3':     ('90','420'),
365
  '(M45x3)':   ('90','440'),
366
  'M48x3':     ('100','480'),
367
  '(M52x4)':   ('100','500'),
368
  'M56x4':     ('120','500'),
369
  '(M60x4)':   ('120','500'),
370
  'M64x4':     ('130','500')
371
  }
372

373
# ISO 4014 Hex-head-bolt
374
#          P,      b1,    b2,    b3,  c,   dw,    e,    k,   r,   s
375
iso4014head={
376
  'M1.6':  (0.35,   9.0,  15.0,  28.0, 0.2,  2.3,  3.4,  1.1, 0.1,  3.2),
377
  'M2':    (0.40,  10.0,  16.0,  29.0, 0.2,  3.0,  4.4,  1.4, 0.1,  4.0),
378
  'M2.5':  (0.45,  11.0,  17.0,  30.0, 0.2,  4.0,  5.5,  1.7, 0.1,  5.0),
379
  'M3':    (0.50,  12.0,  18.0,  31.0, 0.2,  4.6,  6.1,  2.0, 0.1,  5.5),
380
  '(M3.5)':(0.60,  13.0,  19.0,  32.0, 0.2,  5.1,  6.6,  2.4, 0.1,  6.0),
381
  'M4':    (0.70,  14.0,  20.0,  33.0, 0.2,  5.9,  7.7,  2.8, 0.2,  7.0),
382
  'M5':    (0.80,  16.0,  22.0,  35.0, 0.2,  6.9,  8.9,  3.5, 0.2,  8.0),
383
  'M6':    (1.00,  18.0,  24.0,  37.0, 0.2,  8.9, 11.05, 4.0, 0.25,10.0),
384
  'M8':    (1.25,  22.0,  28.0,  41.0, 0.3, 11.7, 14.5,  5.3, 0.4, 13.0),
385
  'M10':   (1.50,  26.0,  32.0,  45.0, 0.3, 14.7, 17.9,  6.4, 0.4, 16.0),
386
  'M12':   (1.75,  30.0,  36.0,  49.0, 0.3, 16.7, 20.1,  7.5, 0.6, 18.0),
387
  '(M14)': (2.00,  34.0,  40.0,  53.0, 0.3, 20.5, 24.5,  8.8, 0.6, 22.0),
388
  'M16':   (2.00,  38.0,  44.0,  57.0, 0.4, 22.4, 26.9, 10.0, 0.6, 24.0),
389
  '(M18)': (2.50,  42.0,  48.0,  61.0, 0.4, 25.4, 30.2, 11.5, 0.6, 27.0),
390
  'M20':   (2.50,  46.0,  52.0,  65.0, 0.4, 28.2, 33.7, 12.5, 0.8, 30.0),
391
  '(M22)': (2.50,  50.0,  56.0,  69.0, 0.4, 31.8, 37.7, 14.0, 0.8, 34.0),
392
  'M24':   (3.00,  54.0,  60.0,  73.0, 0.4, 33.7, 40.1, 15.0, 0.8, 36.0),
393
  '(M27)': (3.00,  60.0,  66.0,  79.0, 0.4, 38.0, 45.2, 17.0, 1.0, 41.0),
394
  'M30':   (3.50,  66.0,  72.0,  85.0, 0.4, 42.8, 50.9, 18.7, 1.0, 46.0), #dw not in class A, e not in class A
395
  '(M33)': (3.50,  78.0,  78.0,  91.0, 0.4, 46.6, 55.4, 21.0, 1.0, 50.0),
396
  'M36':   (4.00,  84.0,  84.0,  97.0, 0.4, 51.2, 60.8, 22.5, 1.0, 55.0),
397
  '(M39)': (4.00,  90.0,  90.0, 103.0, 0.5, 55.9, 66.5, 25.0, 1.0, 60.0),
398
  'M42':   (4.50,  96.0,  96.0, 109.0, 0.6, 60.0, 71.3, 26.0, 1.2, 65.0),
399
  '(M45)': (4.50, 102.0, 102.0, 115.0, 0.7, 64.7, 77.0, 28.0, 1.2, 70.0),
400
  'M48':   (5.00, 108.0, 108.0, 121.0, 0.6, 69.5, 82.6, 30.0, 1.6, 75.0),
401
  '(M52)': (5.00, 116.0, 116.0, 129.0, 0.7, 74.5, 88.3, 33.0, 1.6, 80.0),
402
  'M56':   (5.50, 137.0, 137.0, 137.0, 0.6, 78.7, 93.6, 35.0, 2.0, 85.0),
403
  '(M60)': (5.50, 145.0, 145.0, 145.0, 0.7, 82.7, 99.2, 38.0, 2.0, 90.0),
404
  'M64':   (6.00, 153.0, 153.0, 153.0, 0.6, 88.2,104.9, 40.0, 2.0, 55.0)
405
  }
406

407
iso4014length = {
408
  '12':(11.65, 12.35),
409
  '16':(15.65, 16.35),
410
  '20':(19.58, 20.42),
411
  '25':(24.58, 25.42),
412
  '30':(29.58, 30.42),
413
  '35':(34.5,  35.5),
414
  '40':(39.5,  40.5),
415
  '45':(44.5,  45.5),
416
  '50':(49.5,  50.5),
417
  '55':(54.4, 55.6),
418
  '60':(59.4, 60.6),
419
  '65':(64.4, 65.6),
420
  '70':(69.4, 70.6),
421
  '80':(79.4, 80.6),
422
  '100':(99.3, 100.7),
423
  '110':(109.3, 110.7),
424
  '120':(119.3, 120.7),
425
  '130':(129.2, 130.8),
426
  '140':(139.2, 130.8),
427
  '150':(149.2, 150.8),
428
  '160':(159.2, 160.8),
429
  '180':(179.2, 180.8),
430
  '200':(199.1, 200.9),
431
  '220':(219.1, 220.9),
432
  '240':(237.7, 242.3),
433
  '260':(219.1, 220.9),
434
  '280':(219.1, 220.9),
435
  '300':(219.1, 220.9),
436
  '320':(219.1, 220.9),
437
  '340':(219.1, 220.9),
438
  '360':(219.1, 220.9),
439
  '380':(219.1, 220.9),
440
  '400':(219.1, 220.9),
441
  '420':(219.1, 220.9),
442
  '440':(219.1, 220.9),
443
  '460':(219.1, 220.9),
444
  '480':(219.1, 220.9),
445
  '500':(496.85, 503.15),
446
  }
447

448
# range of typical screw lengths
449
#    min_length,  max_length
450
iso4014range = {
451
  'M1.6':('12', '16'),
452
  'M2':  ('16', '20'),
453
  'M2.5':('16', '25'),
454
  'M3':  ('20', '30'),
455
  '(M3.5)':('20', '35'),
456
  'M4':  ('25', '50'),
457
  'M5':  ('25', '50'),
458
  'M6':  ('30', '130'),
459
  'M8':  ('30', '180'),
460
  'M10': ('35', '150'),
461
  'M12': ('50', '150'),
462
  '(M14)': ('50', '160'),
463
  'M16': ('55', '200'),
464
  '(M18)':('70','180'),
465
  'M20': ('60', '300'),
466
  '(M22)':('70','220'),
467
  'M24': ('80', '220'),
468
  '(M27)':('90', '220'),
469
  'M30': ('110','300'),
470
  '(M33)':('130','320'),
471
  'M36': ('140','360'),
472
  '(M39)':('150','380'),
473
  'M42': ('160','440'),
474
  '(M45)':('180','440'),
475
  'M48': ('180','480'),
476
  '(M52)':('200','480'),
477
  'M56': ('220','500'),
478
  '(M60)':('220','500'),
479
  'M64': ('260','500')
480
  }
481

482
# EN 1662 Hexagon bolts with flange, small series
483
#          P,   b0,    b1,   b2,   b3,   c,  dc,    dw,    e,     k,   kw,  lf,  r1,   s
484
en1662def={
485
  'M5': (0.80, 25.0, 16.0,  0.0,  0.0, 1.0, 11.4,  9.4,  7.59,  5.6, 2.3, 1.4, 0.2, 7.0),
486
  'M6': (1.00, 30.0, 18.0,  0.0,  0.0, 1.1, 13.6, 11.6,  8.71,  6.9, 2.9, 1.6, 0.25, 8.0),
487
  'M8': (1.25, 35.0, 22.0, 28.0,  0.0, 1.2, 17.0, 14.9, 10.95,  8.5, 3.8, 2.1, 0.4, 10.0),
488
  'M10':(1.50, 40.0, 26.0, 32.0,  0.0, 1.5, 20.8, 18.7, 14.26,  9.7, 4.3, 2.1, 0.4, 13.0),
489
  'M12':(1.75, 45.0, 30.0, 36.0,  0.0, 1.8, 24.7, 22.5, 17.62, 12.1, 5.4, 2.1, 0.6, 16.0),
490
  '(M14)':(2.00, 50.0, 34.0, 40.0,  0.0, 2.1, 28.6, 26.4, 19.86, 12.9, 5.6, 2.1, 0.6, 18.0),
491
  'M16':(2.00, 55.0, 38.0, 44.0, 57.0, 2.4, 32.8, 30.6, 23.15, 15.2, 6.8, 3.2, 0.6, 21.0)}
492

493
# range of typical screw lengths
494
#    min_length,  max_length
495
en1662range = {
496
  'M5': ('10', '50'),
497
  'M6': ('12', '60'),
498
  'M8': ('16', '80'),
499
  'M10':('20','100'),
500
  'M12':('25','120'),
501
  '(M14)':('30','140'),
502
  'M16':('35','160')
503
  }
504

505
en1662length = {
506
  '10':( 9.71, 10.29),
507
  '12':(11.65, 12.35),
508
  '16':(15.65, 16.35),
509
  '20':(19.58, 20.42),
510
  '25':(24.58, 25.42),
511
  '30':(29.58, 30.42),
512
  '35':(34.5,  35.5),
513
  '40':(39.5,  40.5),
514
  '45':(44.5,  45.5),
515
  '50':(49.5,  50.5),
516
  '55':(54.4, 55.6),
517
  '60':(59.4, 60.6),
518
  '65':(64.4, 65.6),
519
  '70':(69.4, 70.6),
520
  '80':(79.4, 80.6),
521
  '90':(89.3, 90.7),
522
  '100':(99.3, 100.7),
523
  '110':(109.3, 110.7),
524
  '120':(119.3, 120.7),
525
  '130':(129.2, 130.8),
526
  '140':(139.2, 130.8),
527
  '150':(149.2, 150.8),
528
  '160':(159.2, 160.8)
529
  }
530

531
# EN 1665 Hexagon bolts with flange, heavy series
532
#          P,    b0,  b1,   b2,   b3,   c,  dc,    dw,    e,     k,   kw,  lf,  r1,   s
533
en1665def={
534
  'M5': (0.80, 25.0, 16.0,  0.0,  0.0, 1.0, 11.8,  9.8,  8.71,  5.8, 2.6, 1.4, 0.2,  8.0),
535
  'M6': (1.00, 30.0, 18.0,  0.0,  0.0, 1.1, 14.2, 12.2, 10.95,  6.6, 3.0, 1.6, 0.25,10.0),
536
  'M8': (1.25, 35.0, 22.0, 28.0,  0.0, 1.2, 18.0, 15.8, 14.26,  8.1, 3.9, 2.1, 0.4, 13.0),
537
  'M10':(1.50, 40.0, 26.0, 32.0,  0.0, 1.5, 22.3, 19.6, 17.62, 10.4, 4.1, 2.1, 0.4, 16.0),
538
  'M12':(1.75, 45.0, 30.0, 36.0,  0.0, 1.8, 26.6, 23.8, 19.86, 11.8, 5.6, 2.1, 0.6, 18.0),
539
  '(M14)':(2.00, 50.0, 34.0, 40.0,  0.0, 2.1, 30.5, 27.6, 23.15, 13.7, 6.5, 2.1, 0.6, 21.0),
540
  'M16':(2.00, 55.0, 38.0, 44.0, 57.0, 2.4, 35.0, 31.9, 26.51, 15.4, 7.3, 3.2, 0.6, 24.0),
541
  'M20':(2.50, 65.0, 46.0, 52.0, 65.0, 3.0, 43.0, 39.9, 33.23, 18.9, 8.9, 4.2, 0.8, 30.0)}
542

543
# range of typical screw lengths
544
#    min_length,  max_length
545
en1665range = {
546
  'M5': ('10', '50'),
547
  'M6': ('12', '60'),
548
  'M8': ('16', '80'),
549
  'M10':('20','100'),
550
  'M12':('25','120'),
551
  '(M14)':('30','140'),
552
  'M16':('35','160'),
553
  'M20':('65','200')
554
  }
555

556
en1665length = {
557
  '10':( 9.71, 10.29),
558
  '12':(11.65, 12.35),
559
  '16':(15.65, 16.35),
560
  '20':(19.58, 20.42),
561
  '25':(24.58, 25.42),
562
  '30':(29.58, 30.42),
563
  '35':(34.5,  35.5),
564
  '40':(39.5,  40.5),
565
  '45':(44.5,  45.5),
566
  '50':(49.5,  50.5),
567
  '55':(54.4, 55.6),
568
  '60':(59.4, 60.6),
569
  '65':(64.4, 65.6),
570
  '70':(69.4, 70.6),
571
  '80':(79.4, 80.6),
572
  '90':(89.3, 90.7),
573
  '100':(99.3, 100.7),
574
  '110':(109.3, 110.7),
575
  '120':(119.3, 120.7),
576
  '130':(129.2, 130.8),
577
  '140':(139.2, 130.8),
578
  '150':(149.2, 150.8),
579
  '160':(159.2, 160.8),
580
  '180':(179.2, 180.8),
581
  '200':(199.1, 200.9)
582
  }
583

584
# ISO 1207 definitions Class A, Slotted cheese head screws
585
#          P,     a,   b,   dk,  dk_mean, da,  k,  n_min, r, t_min, x
586
iso1207def={
587
  'M1.6':(0.35, 0.7, 25.0,  3.0,  2.9,  2.0, 1.1, 0.46, 0.1, 0.45, 0.9),
588
  'M2':  (0.40, 0.8, 25.0,  3.8,  3.7,  2.6, 1.4, 0.56, 0.1, 0.6, 1.0),
589
  'M2.5':(0.45, 0.9, 25.0,  4.5,  4.4,  3.1, 1.8, 0.66, 0.1, 0.7, 1.1),
590
  'M3':  (0.50, 1.0, 25.0,  5.5,  5.4,  3.6, 2.0, 0.86, 0.1, 0.85, 1.25),
591
  '(M3.5)':(0.60, 1.2, 38.0,  6.0,  5.9,  4.1, 2.4, 1.06, 0.1, 1.0, 1.5),
592
  'M4':  (0.70, 1.4, 38.0,  7.0,  6.9,  4.7, 2.6, 1.26, 0.2, 1.1, 1.75),
593
  'M5':  (0.80, 1.6, 38.0,  8.5,  8.4,  5.7, 3.3, 1.26, 0.2, 1.3, 2.0),
594
  'M6':  (1.00, 2.0, 38.0, 10.0,  9.9,  6.8, 3.9, 1.66, 0.25,1.6, 2.5),
595
  'M8':  (1.25, 2.5, 38.0, 13.0, 12.85, 9.2, 5.0, 2.06, 0.4, 2.0, 3.2),
596
  'M10': (1.50, 3.0, 38.0, 16.0, 15.85, 11.2,6.0, 2.56, 0.4, 2.4, 3.8)}
597

598
# range of typical screw lengths
599
#    min_length,  max_length
600
iso1207range = {
601
  'M1.6':('2', '16'),
602
  'M2':  ('3', '20'),
603
  'M2.5':('3', '25'),
604
  'M3':  ('4', '30'),
605
  '(M3.5)':('5', '35'),
606
  'M4':  ('5', '40'),
607
  'M5':  ('6', '50'),
608
  'M6':  ('8', '60'),
609
  'M8': ('10', '80'),
610
  'M10':('12', '80')}
611

612
# slotted cheese head screws
613
# nom length: l_min, l_max
614
iso1207length = {
615
  '2': (1.8,  2.2),
616
  '3': ( 2.8,  3.2),
617
  '4': ( 3.76, 4.24),
618
  '5': ( 4.76, 5.24),
619
  '6': ( 5.76, 6.24),
620
  '8': ( 7.71, 8.29),
621
  '10':( 9.71, 10.29),
622
  '12':(11.65, 12.35),
623
  '14':(13.65, 14.35),
624
  '16':(15.65, 16.35),
625
  '20':(19.58, 20.42),
626
  '25':(24.58, 25.42),
627
  '30':(29.58, 30.42),
628
  '35':(34.5,  35.5),
629
  '40':(39.5,  40.5),
630
  '45':(44.5,  45.5),
631
  '50':(49.5,  50.5),
632
  '55':(54.05, 55.95),
633
  '60':(59.05, 60.95),
634
  '65':(64.05, 65.95),
635
  '70':(69.05, 70.95),
636
  '75':(74.05, 75.95),
637
  '80':(79.05, 80.95)
638
  }
639

640
# ISO 14580 definitions , Hexalobular socket cheese head screws
641
#          P,     a,   b,   dk,  dk_mean, da,  k,  n_min, r, t_min, x
642
#           tt,    k,    A,  t_mean
643
iso14580def={
644
  'M2':  ('T6',  1.55, 1.75, 0.8),
645
  'M2.5':('T8',  1.85, 2.40, 0.9),
646
  'M3':  ('T10', 2.40, 2.80, 1.2),
647
  '(M3.5)':('T15', 2.60, 3.35, 1.3),
648
  'M4':  ('T20', 3.10, 3.95, 1.5),
649
  'M5':  ('T25', 3.65, 4.50, 1.7),
650
  'M6':  ('T30', 4.40, 5.60, 2.1),
651
  'M8':  ('T45', 5.80, 7.95, 2.9),
652
  'M10': ('T50', 6.90, 8.95, 3.3)}
653

654
# range of typical screw lengths
655
#    min_length,  max_length
656
# iso14580range = iso1207range
657

658
# nom length: l_min, l_max
659
iso14580length = {
660
  '3': ( 2.8,  3.2),
661
  '4': ( 3.76, 4.24),
662
  '5': ( 4.76, 5.24),
663
  '6': ( 5.76, 6.24),
664
  '8': ( 7.71, 8.29),
665
  '10':( 9.71, 10.29),
666
  '12':(11.65, 12.35),
667
  '14':(13.65, 14.35),
668
  '16':(15.65, 16.35),
669
  '20':(19.58, 20.42),
670
  '25':(24.58, 25.42),
671
  '30':(29.58, 30.42),
672
  '35':(34.5,  35.5),
673
  '40':(39.5,  40.5),
674
  '45':(44.5,  45.5),
675
  '50':(49.5,  50.5),
676
  '55':(54.05, 55.95),
677
  '60':(59.05, 60.95),
678
  '65':(64.05, 65.95),
679
  '70':(69.05, 70.95),
680
  '75':(74.05, 75.95),
681
  '80':(79.05, 80.95)
682
  }
683

684

685

686
# ISO 7048 definitions Class A,
687
# Cross-recessed cheese head screws with type H or Z cross recess
688
#          P,     a,   b,   dk,  dk_mean, da,  k,   r,   x, cT,   mH,   mZ
689
iso7048def={
690
  'M2.5':(0.45, 0.9, 25.0,  4.5,  4.4,  3.1, 1.8, 0.1, 1.1, '1', 2.7, 2.4),
691
  'M3':  (0.50, 1.0, 25.0,  5.5,  5.4,  3.6, 2.0, 0.1, 1.25,'2', 3.5, 3.5),
692
  '(M3.5)':(0.60, 1.2, 38.0,  6.0,  5.9,  4.1, 2.4, 0.1, 1.5, '2', 3.8, 3.7),
693
  'M4':  (0.70, 1.4, 38.0,  7.0,  6.9,  4.7, 2.6, 0.2, 1.75,'2', 4.1, 4.0),
694
  'M5':  (0.80, 1.6, 38.0,  8.5,  8.4,  5.7, 3.3, 0.2, 2.0, '2', 4.8, 4.6),
695
  'M6':  (1.00, 2.0, 38.0, 10.0,  9.9,  6.8, 3.9, 0.25,2.5, '3', 6.2, 6.1),
696
  'M8':  (1.25, 2.5, 38.0, 13.0, 12.85, 9.2, 5.0, 0.4, 3.2, '3', 7.7, 7.5)
697
  }
698

699
# range of typical screw lengths
700
#    min_length,  max_length
701
iso7048range = {
702
  'M2.5':('3', '25'),
703
  'M3':  ('4', '30'),
704
  '(M3.5)':('5', '35'),
705
  'M4':  ('5', '40'),
706
  'M5':  ('6', '50'),
707
  'M6':  ('8', '60'),
708
  'M8': ('10', '80')}
709

710
# nom length: l_min, l_max
711
iso7048length = {
712
  '3': ( 2.8,  3.2),
713
  '4': ( 3.76, 4.24),
714
  '5': ( 4.76, 5.24),
715
  '6': ( 5.76, 6.24),
716
  '8': ( 7.71, 8.29),
717
  '10':( 9.71, 10.29),
718
  '12':(11.65, 12.35),
719
  '16':(15.65, 16.35),
720
  '20':(19.58, 20.42),
721
  '25':(24.58, 25.42),
722
  '30':(29.58, 30.42),
723
  '35':(34.5,  35.5),
724
  '40':(39.5,  40.5),
725
  '45':(44.5,  45.5),
726
  '50':(49.5,  50.5),
727
  '60':(59.05, 60.95),
728
  '70':(69.05, 70.95),
729
  '80':(79.05, 80.95)
730
  }
731

732

733
# Button Head Screw
734
# nom length: l_min, l_max
735
iso7380length = {
736
  #'2.5':(2.3,  2.7),
737
  #'3': ( 2.8,  3.2),
738
  '4': ( 3.76, 4.24),
739
  '5': ( 4.76, 5.24),
740
  '6': ( 5.76, 6.24),
741
  '8': ( 7.71, 8.29),
742
  '10':( 9.71, 10.29),
743
  '12':(11.65, 12.35),
744
  '14':(13.65, 14.35),
745
  '16':(15.65, 16.35),
746
  '20':(19.58, 20.42),
747
  '25':(24.58, 25.42),
748
  '30':(29.58, 30.42),
749
  '35':(34.5,  35.5),
750
  '40':(39.5,  40.5),
751
  '45':(44.5,  45.5),
752
  '50':(49.5,  50.5),
753
  '55':(54.05, 55.95),
754
  '60':(59.05, 60.95),
755
  '65':(64.4, 65.6),
756
  '70':(69.4, 70.6),
757
  '80':(79.4, 80.6),
758
  '90':(89.3, 90.7)
759
  }
760

761
# ISO 7380-1 definitions Class A
762
# http://www.agrati.com/it/unificati/it/gamma/unificati/home02.htm
763
#          P,   b,     a,   da, dk,  dk_mean,s_mean,t_min, r, k,   e,    w,
764
iso7380def={
765
  'M3':  (0.50, 18.0, 1.0,  3.6,  5.7,  5.5, 2.03, 1.04, 0.1, 1.65, 2.3,  0.2),
766
  'M4':  (0.70, 20.0, 1.4,  4.7,  7.6,  7.4, 2.54, 1.30, 0.2, 2.20, 2.87, 0.3),
767
  'M5':  (0.80, 22.0, 1.6,  5.7,  9.5,  9.3, 3.05, 1.56, 0.2, 2.75, 3.44, 0.38),
768
  'M6':  (1.00, 24.0, 2.0,  6.8, 10.5, 10.3, 4.05, 2.08, 0.25,3.3,  4.58, 0.74),
769
  'M8':  (1.25, 28.0, 2.5,  9.2, 14.0, 13.8, 5.05, 2.60, 0.4, 4.4,  5.72, 1.05),
770
  'M10': (1.50, 32.0, 3.0, 11.2, 17.5, 17.3, 6.05, 3.12, 0.4, 5.5,  6.86, 1.45),
771
  'M12': (1.75, 36.0, 3.5, 13.7, 21.0, 20.7, 8.06, 4.16, 0.6, 6.6,  9.15, 1.63),
772
  'M16': (2.00, 44.0, 3.5, 17.7, 28.0, 27.8, 10.06,5.20, 0.6, 8.8, 11.43, 2.25)
773
  }
774

775
# range of typical screw lengths
776
#    min_length,  max_length
777
iso7380range = {
778
  'M3':  ('6', '30'),
779
  'M4':  ('6', '40'),
780
  'M5':  ('8', '50'),
781
  'M6':  ('10', '60'),
782
  'M8': ('12', '80'),
783
  'M10':('16', '90'),
784
  'M12':('20', '90'),
785
  'M16':('25', '90')}
786

787
# ISO 7380-2 definitions
788
#          P,   b,     c,   da, dk,    dk_c,s_mean,t_min, r,  k,   e,    w,
789
iso7380_2def={
790
  'M3':  (0.50, 18.0, 0.7,  3.6,  5.2,  6.9, 2.03, 1.04, 0.1, 1.65, 2.3,  0.2),
791
  'M4':  (0.70, 20.0, 0.8,  4.7,  7.2,  9.4, 2.54, 1.30, 0.2, 2.20, 2.87, 0.3),
792
  'M5':  (0.80, 22.0, 1.0,  5.7,  8.8, 11.8, 3.05, 1.56, 0.2, 2.75, 3.44, 0.38),
793
  'M6':  (1.00, 24.0, 1.2,  6.8, 10.0, 13.6, 4.05, 2.08, 0.25,3.3,  4.58, 0.74),
794
  'M8':  (1.25, 28.0, 1.5,  9.2, 13.2, 17.8, 5.05, 2.60, 0.4, 4.4,  5.72, 1.05),
795
  'M10': (1.50, 32.0, 2.0, 11.2, 16.5, 21.9, 6.05, 3.12, 0.4, 5.5,  6.86, 1.45),
796
  'M12': (1.75, 36.0, 2.4, 13.7, 19.4, 26.0, 8.06, 4.16, 0.6, 6.6,  9.15, 1.63),
797
  'M16': (2.00, 44.0, 2.8, 17.7, 26.0, 34.0, 10.06,5.20, 0.6, 8.8, 11.43, 2.25)
798
  }
799

800

801
# DIN 967 definitions: Cross recessed pan head screw with collar
802
#          P,   b,     c,   da,   dk,   r,  k,    rf,  x,    cT,  mH,   mZ
803
din967def={
804
  'M3':  (0.50, 25.0, 0.7,  3.6,  7.5, 0.1, 2.35,  3.8, 1.25, '1', 3.0, 2.9),
805
  '(M3.5)':(0.60, 38.0, 0.8,  4.1,  9.0, 0.1, 2.60,  4.6, 1.5,  '2', 4.2, 3.9),
806
  'M4':  (0.70, 38.0, 1.0,  4.7, 10.0, 0.2, 3.05,  5.8, 1.75, '2', 4.6, 4.3),
807
  'M5':  (0.80, 38.0, 1.2,  5.7, 11.5, 0.2, 3.55,  6.6, 2.0,  '2', 5.0, 4.7),
808
  'M6':  (1.00, 38.0, 1.6,  6.8, 14.5, 0.25,4.55,  8.2, 2.5,  '3', 7.1, 6.7),
809
  'M8':  (1.25, 38.0, 2.0,  9.2, 19.0, 0.4, 5.90, 11.0, 3.2,  '4', 9.0, 8.8)
810
  }
811

812
# range of typical screw lengths
813
#    min_length,  max_length
814
din967range = {
815
  'M3':  ('4', '30'),
816
  '(M3.5)':  ('5', '35'),
817
  'M4':  ('5', '40'),
818
  'M5':  ('6', '45'),
819
  'M6':  ('8', '60'),
820
  'M8': ('10', '60')
821
}
822
# Button Head Screw
823
# nom length: l_min, l_max
824
din967length = {
825
  '4': ( 3.76, 4.24),
826
  '5': ( 4.76, 5.24),
827
  '6': ( 5.76, 6.24),
828
  '8': ( 7.71, 8.29),
829
  '10':( 9.71, 10.29),
830
  '12':(11.65, 12.35),
831
  '14':(13.65, 14.35),
832
  '16':(15.65, 16.35),
833
  '20':(19.58, 20.42),
834
  '25':(24.58, 25.42),
835
  '30':(29.58, 30.42),
836
  '35':(34.5,  35.5),
837
  '40':(39.5,  40.5),
838
  '45':(44.5,  45.5),
839
  '50':(49.5,  50.5),
840
  '55':(54.05, 55.95),
841
  '60':(59.05, 60.95)
842
  }
843

844

845
L_iso2009length =['2.5','3','4','5','6','8','10','12','14','16','20', \
846
   '25','30','35','40','45','50','55','60','65','70','75','80']
847
# nom length: l_min, l_max
848
iso2009length = {
849
  '2.5':(2.3,  2.7),
850
  '3': ( 2.8,  3.2),
851
  '4': ( 3.76, 4.24),
852
  '5': ( 4.76, 5.24),
853
  '6': ( 5.76, 6.24),
854
  '8': ( 7.71, 8.29),
855
  '10':( 9.71, 10.29),
856
  '12':(11.65, 12.35),
857
  '14':(13.65, 14.35),
858
  '16':(15.65, 16.35),
859
  '20':(19.58, 20.42),
860
  '25':(24.58, 25.42),
861
  '30':(29.58, 30.42),
862
  '35':(34.5,  35.5),
863
  '40':(39.5,  40.5),
864
  '45':(44.5,  45.5),
865
  '50':(49.5,  50.5),
866
  '55':(54.05, 55.95),
867
  '60':(59.05, 60.95),
868
  '65':(64.05, 65.95),
869
  '70':(69.05, 70.95),
870
  '75':(74.05, 75.95),
871
  '80':(79.05, 80.95)
872
  }
873

874

875
# ISO 2009 definitions Class A
876
#          P, a, b, dk_theo, dk_mean, k, n_min, r, t_mean, x
877
iso2009def={
878
   'M1.6':(0.35, 0.7, 25, 3.6, 2.8,  1.0,  0.46, 0.2, 0.4, 0.9),
879
   'M2':  (0.40, 0.8, 25, 4.4, 3.6,  1.2,  0.56, 0.3, 0.5, 1.0),
880
   'M2.5':(0.45, 0.9, 25, 5.5, 4.5,  1.5,  0.66, 0.3, 0.6, 1.1),
881
   'M3':  (0.50, 1.0, 25, 6.3, 5.3,  1.65, 0.86, 0.4, 0.7, 1.25),
882
   '(M3.5)':(0.60, 1.2, 38, 8.2, 7.1,  2.35, 1.06, 0.4, 1.0, 1.5),
883
   'M4':  (0.70, 1.4, 38, 9.4, 8.2,  2.7,  1.26, 0.5, 1.1, 1.75),
884
   'M5':  (0.80, 1.6, 38,10.4, 9.2,  2.7,  1.26, 0.6, 1.2, 2.0),
885
   'M6':  (1.00, 2.0, 38,12.6, 11.2, 3.3,  1.66, 0.7, 1.4, 2.5),
886
   'M8':  (1.25, 2.5, 38,17.3, 15.6, 4.65, 2.06, 1.0, 2.0, 3.2),
887
   'M10': (1.50, 3.0, 38,20.0, 18.1, 5.0,  2.56, 1.2, 2.3, 3.8)}
888

889
# range of typical screw lengths
890
#    min_length,  max_length
891
iso2009range = {
892
  'M1.6':('2.5', '16'),
893
  'M2':  ('3', '20'),
894
  'M2.5':('4', '25'),
895
  'M3':  ('5', '30'),
896
  '(M3.5)':('6', '35'),
897
  'M4':  ('6', '40'),
898
  'M5':  ('8', '50'),
899
  'M6':  ('8', '60'),
900
  'M8': ('10', '80'),
901
  'M10':('12', '80')}
902

903

904
# ISO 7046 definitions Class A
905
# ISO 7046 Countersunk flat head screws (common head style)
906
# with type H or type Z cross recess
907
# Parameters P, a, b, dk_theo, dk_mean, k, r, x to be read from iso2009def
908
# Length = iso7045length
909
#          cT,   mH,   mZ
910
iso7046def={
911
  'M1.6':('0', 1.6, 1.6),
912
  'M2':  ('0', 1.9, 1.9),
913
  'M2.5':('1', 2.9, 2.8),
914
  'M3':  ('1', 3.2, 3.0),
915
  '(M3.5)':('2', 4.4, 4.1),
916
  'M4':  ('2', 4.6, 4.4),
917
  'M5':  ('2', 5.2, 4.0),
918
  'M6':  ('3', 6.8, 6.6),
919
  'M8':  ('4', 8.9, 8.8),
920
  'M10': ('4', 10.0,9.8)}
921

922
# range of typical screw lengths
923
#    min_length,  max_length
924
iso7046range = {
925
  'M1.6':('3', '16'),
926
  'M2':  ('3', '20'),
927
  'M2.5':('3', '25'),
928
  'M3':  ('4', '30'),
929
  '(M3.5)':('5', '35'),
930
  'M4':  ('5', '40'),
931
  'M5':  ('6', '50'),
932
  'M6':  ('8', '60'),
933
  'M8': ('10', '60'),
934
  'M10':('12', '60')}
935

936
# ISO 2010, ISO 7047 definitions Class A: Raised Countersunk head screws
937
# ISO 2010 slotted screws (common head style)   range = iso2009range
938
# ISO 7047  with type H or type Z cross recess  range = iso7046range
939
# Parameters P, a, b, dk_theo, dk_mean, k, r, x to be read from iso2009def
940
# Length = iso7045length
941
#          rf, t_mean, cT,   mH,   mZ
942
Raised_countersunk_def={
943
  'M1.6':(3.0,  0.7, '0', 1.9,  1.9),
944
  'M2':  (4.0,  0.9, '0', 2.0,  2.2),
945
  'M2.5':(5.0,  1.1, '1', 3.0,  2.8),
946
  'M3':  (6.0,  1.3, '1', 3.4,  3.1),
947
  '(M3.5)':(8.5,  1.5, '2', 4.8,  4.6),
948
  'M4':  (9.5,  1.8, '2', 5.2,  5.0),
949
  'M5':  (9.5,  2.2, '2', 5.4,  5.3),
950
  'M6':  (12.0, 2.6, '3', 7.3,  7.1),
951
  'M8':  (16.5, 3.5, '4', 9.6,  9.5),
952
  'M10': (19.5, 4.1, '4', 10.4,10.3)}
953

954

955

956
# ISO 14582 definitions
957
#          P,    a,    b, dk_theo, dk_mean,k,   r,  tt, A, t_mean
958
iso14582def={
959
  'M3':  (0.50, 1.0, 18.0,  7.40,  6.5, 2.20, 0.10, 'T10', 2.80, 1.1),
960
  'M4':  (0.70, 1.4, 20.0, 10.02,  9.0, 3.01, 0.20, 'T20', 3.95, 1.6),
961
  'M5':  (0.80, 1.6, 22.0, 12.00, 10.8, 3.50, 0.20, 'T25', 4.50, 1.8),
962
  'M6':  (1.00, 2.0, 24.0, 14.44, 13.1, 4.22, 0.25, 'T30', 5.60, 2.2),
963
  'M8':  (1.25, 2.5, 28.0, 19.38, 17.8, 5.69, 0.40, 'T45', 7.93, 2.8),
964
  'M10': (1.50, 3.0, 32.0, 23.00, 21.1, 6.50, 0.40, 'T50', 8.95, 3.3)}
965

966
# range of typical screw lengths
967
#    min_length,  max_length
968
iso14582range = {
969
  'M3':  ('8', '30'),
970
  'M4':  ('8', '40'),
971
  'M5':  ('8', '50'),
972
  'M6':  ('8', '60'),
973
  'M8': ('10', '80'),
974
  'M10':('12', '100')}
975

976
# nom length: l_min, l_max
977
iso14582length = {
978
  '8': ( 7.71, 8.29),
979
  '10':( 9.71, 10.29),
980
  '12':(11.65, 12.35),
981
  '14':(13.65, 14.35),
982
  '16':(15.65, 16.35),
983
  '20':(19.58, 20.42),
984
  '25':(24.58, 25.42),
985
  '30':(29.58, 30.42),
986
  '35':(34.5,  35.5),
987
  '40':(39.5,  40.5),
988
  '45':(44.5,  45.5),
989
  '50':(49.5,  50.5),
990
  '55':(54.4, 55.6),
991
  '60':(59.4, 60.6),
992
  '65':(64.4, 65.6),
993
  '70':(69.4, 70.6),
994
  '80':(79.4, 80.6),
995
  '90':(89.3, 90.7),
996
  '100':(99.3, 100.7)
997
  }
998

999

1000

1001
# ISO 1580 definitions Class A, Slotted pan head screws
1002
#           P,    a,   b, dk_max,da,  k, n_min,  r,  rf, t_mean, x
1003
iso1580def={
1004
  'M1.6':(0.35, 0.7, 25,  3.2, 2.0, 1.0, 0.46, 0.1, 0.5, 0.4, 0.9),
1005
  'M2':  (0.4,  0.8, 25,  4.0, 2.6, 1.3, 0.56, 0.1, 0.6, 0.5, 1.0),
1006
  'M2.5':(0.45, 0.9, 25,  5.0, 3.1, 1.5, 0.66, 0.1, 0.8, 0.6, 1.1),
1007
  'M3':  (0.5,  1.0, 25,  5.6, 3.6, 1.8, 0.86, 0.1, 0.9, 0.7, 1.25),
1008
  '(M3.5)':(0.6,  1.2, 38,  7.0, 4.1, 2.1, 1.06, 0.1, 1.0, 0.8, 1.5),
1009
  'M4':  (0.7,  1.4, 38,  8.0, 4.7, 2.4, 1.26, 0.2, 1.2, 1.0, 1.75),
1010
  'M5':  (0.8,  1.6, 38,  9.5, 5.7, 3.0, 1.26, 0.2, 1.5, 1.2, 2.0),
1011
  'M6':  (1.0,  2.0, 38, 12.0, 6.8, 3.6, 1.66, 0.25,1.8, 1.4, 2.5),
1012
  'M8':  (1.25, 2.5, 38, 16.0, 9.2, 4.8, 2.06, 0.4, 2.4, 1.9, 3.2),
1013
  'M10': (1.50, 3.0, 38, 20.0,11.2, 6.0, 2.56, 0.4, 3.0, 2.4, 3.8)}
1014

1015

1016

1017
# ISO 7045 definitions Class A, Pan head screws with type H or type Z
1018
# partly used also for ISO 14583 Hexalobular socket pan head screws
1019
#   cross recess; cT = size of cross recess
1020
#           P,    a,   b, dk_max,da,  k,   r,   rf,  x,  cT,   mH,   mZ
1021
iso7045def={
1022
  'M1.6':(0.35, 0.7, 25,  3.2, 2.0, 1.3, 0.1, 2.5, 0.9, '0', 1.7, 1.6),
1023
  'M2':  (0.4,  0.8, 25,  4.0, 2.6, 1.6, 0.1, 3.2, 1.0, '0', 1.9, 2.1),
1024
  'M2.5':(0.45, 0.9, 25,  5.0, 3.1, 2.1, 0.1, 4.0, 1.1, '1', 2.7, 2.6),
1025
  'M3':  (0.5,  1.0, 25,  5.6, 3.6, 2.4, 0.1, 5.0, 1.25,'1', 3.0, 2.8),
1026
  '(M3.5)':(0.6,  1.2, 38,  7.0, 4.1, 2.6, 0.1, 6.0, 1.5, '2', 3.9, 3.9),
1027
  'M4':  (0.7,  1.4, 38,  8.0, 4.7, 3.1, 0.2, 6.5, 1.75,'2', 4.4, 4.3),
1028
  'M5':  (0.8,  1.6, 38,  9.5, 5.7, 3.7, 0.2, 8.0, 2.0, '2', 4.9, 4.7),
1029
  'M6':  (1.0,  2.0, 38, 12.0, 6.8, 4.6, 0.25,10., 2.5, '3', 6.9, 6.7),
1030
  'M8':  (1.25, 2.5, 38, 16.0, 9.2, 6.0, 0.4, 13., 3.2, '4', 9.0, 8.8),
1031
  'M10': (1.50, 3.0, 38, 20.0,11.2, 7.5, 0.4, 16., 3.8, '4', 10.1,9.9)}
1032

1033
# nom length: l_min, l_max
1034
iso7045length = {
1035
  '3': ( 2.8,  3.2),
1036
  '4': ( 3.76, 4.24),
1037
  '5': ( 4.76, 5.24),
1038
  '6': ( 5.76, 6.24),
1039
  '8': ( 7.71, 8.29),
1040
  '10':( 9.71, 10.29),
1041
  '12':(11.65, 12.35),
1042
  '14':(13.65, 14.35),
1043
  '16':(15.65, 16.35),
1044
  '20':(19.58, 20.42),
1045
  '25':(24.58, 25.42),
1046
  '30':(29.58, 30.42),
1047
  '35':(34.5,  35.5),
1048
  '40':(39.5,  40.5),
1049
  '45':(44.5,  45.5),
1050
  '50':(49.5,  50.5),
1051
  '55':(54.05, 55.95),
1052
  '60':(59.05, 60.95)
1053
  }
1054

1055
# range of typical screw lengths
1056
#    min_length,  max_length
1057
iso7045range = {
1058
  'M1.6':('3', '16'),
1059
  'M2':  ('3', '20'),
1060
  'M2.5':('3', '25'),
1061
  'M3':  ('4', '30'),
1062
  '(M3.5)':('5', '35'),
1063
  'M4':  ('5', '40'),
1064
  'M5':  ('6', '45'),
1065
  'M6':  ('8', '60'),
1066
  'M8': ('10', '60'),
1067
  'M10':('12', '60')}
1068

1069

1070
# ISO 14583 Hexalobular socket pan head screws
1071
#   hexalobular recess;    tt = size of hexalobular recess
1072

1073
#           tt,    A,  t_mean
1074
iso14583def={
1075
  'M2':  ('T6',  1.75, 0.7),
1076
  'M2.5':('T8',  2.40, 1.0),
1077
  'M3':  ('T10', 2.80, 1.2),
1078
  '(M3.5)':('T15', 3.35, 1.3),
1079
  'M4':  ('T20', 3.95, 1.5),
1080
  'M5':  ('T25', 4.50, 1.7),
1081
  'M6':  ('T30', 5.60, 2.2),
1082
  'M8':  ('T45', 7.95, 3.0),
1083
  'M10': ('T50', 8.95, 3.8)}
1084

1085

1086
#iso14583range = iso7046range
1087
#iso14583length = iso7045length
1088

1089
# ISO 14584 Hexalobular socket raised countersunk head screws
1090
#           P,   b, dk_theo, dk_mean, f,  k,   r,   rf,    x,    tt,    A,  t_mean
1091
iso14584def={
1092
  'M2':  (0.40, 25.0,  4.4,  3.8,  0.5, 1.20, 0.2,  4.0, 1.00, 'T6',  1.75, 0.7),
1093
  'M2.5':(0.45, 25.0,  5.5,  4.7,  0.6, 1.50, 0.3,  5.0, 1.10, 'T8',  2.40, 1.0),
1094
  'M3':  (0.50, 25.0,  6.3,  5.5,  0.7, 1.65, 0.4,  6.0, 1.25, 'T10', 2.80, 1.2),
1095
  '(M3.5)':(0.60, 38.0,  8.2,  7.3,  0.8, 2.35, 0.4,  8.5, 1.50, 'T15', 3.35, 1.3),
1096
  'M4':  (0.70, 38.0,  9.4,  8.4,  1.0, 2.70, 0.5,  9.5, 1.75, 'T20', 3.95, 1.5),
1097
  'M5':  (0.80, 38.0, 10.4,  9.3,  1.2, 2.70, 0.6,  9.5, 2.00, 'T25', 4.50, 1.7),
1098
  'M6':  (1.00, 38.0, 12.6, 11.3,  1.4, 3.30, 0.7, 12.0, 2.50, 'T30', 5.60, 2.2),
1099
  'M8':  (1.25, 38.0, 17.3, 15.8,  2.0, 4.65, 1.0, 16.5, 3.20, 'T45', 7.95, 3.0),
1100
  'M10': (1.50, 38.0, 20.0, 18.3,  2.3, 5.00, 1.2, 19.5, 3.80, 'T50', 8.95, 3.8)}
1101

1102

1103
# range of typical screw lengths
1104
#    min_length,  max_length
1105
iso14584range = {
1106
  'M2':  ('3', '20'),
1107
  'M2.5':('3', '25'),
1108
  'M3':  ('4', '30'),
1109
  '(M3.5)':('5', '35'),
1110
  'M4':  ('5', '40'),
1111
  'M5':  ('6', '50'),
1112
  'M6':  ('8', '60'),
1113
  'M8': ('10', '60'),
1114
  'M10':('12', '60')}
1115

1116
#iso14584length = iso7045length
1117

1118

1119
# ISO 4762 Hexagon socket head cap screws (Allen screw)
1120
# ISO 4762 definitions
1121
#           P,   b,  dk_max,  da,  ds_min,   e,    lf,   k,   r,   s_mean, t,    v,   dw,   w
1122
iso4762def={
1123
  'M1.6':(0.35,  15.0,  3.0,  2.0,  1.46,  1.73, 0.34,  1.6, 0.1,  1.56,  0.7, 0.16, 2.72, 0.55),
1124
  'M2':  (0.40,  16.0,  3.8,  2.6,  1.86,  1.73, 0.51,  2.0, 0.1,  1.56,  1.0, 0.2,  3.48, 0.55),
1125
  'M2.5':(0.45,  17.0,  4.5,  3.1,  2.36,  2.30, 0.51,  2.5, 0.1,  2.06,  1.1, 0.25, 4.18, 0.85),
1126
  'M3':  (0.50,  18.0,  5.5,  3.6,  2.86,  2.87, 0.51,  3.0, 0.1,  2.56,  1.3, 0.3,  5.07, 1.15),
1127
  'M4':  (0.70,  20.0,  7.0,  4.7,  3.82,  3.44, 0.60,  4.0, 0.2,  3.06,  2.0, 0.4,  6.53, 1.40),
1128
  'M5':  (0.80,  22.0,  8.5,  5.7,  4.82,  4.58, 0.60,  5.0, 0.2,  4.06,  2.5, 0.5,  8.03, 1.9),
1129
  'M6':  (1.00,  24.0, 10.0,  6.8,  5.82,  5.72, 0.68,  6.0, 0.25, 5.06,  3.0, 0.6,  9.38, 2.3),
1130
  'M8':  (1.25,  28.0, 13.0,  9.2,  7.78,  6.86, 1.02,  8.0, 0.4,  6.06,  4.0, 0.8, 12.33, 3.3),
1131
  'M10': (1.50,  32.0, 16.0, 11.2,  9.78,  9.15, 1.02, 10.0, 0.4,  8.07,  5.0, 1.0, 15.33, 4.0),
1132
  'M12': (1.75,  36.0, 18.0, 13.7, 11.73, 11.43, 1.45, 12.0, 0.6, 10.07,  6.0, 1.2, 17.23, 4.8),
1133
  '(M14)':(2.00,  40.0, 21.0, 15.7, 13.73, 13.72, 1.45, 14.0, 0.6, 12.07,  7.0, 1.4, 20.17, 5.8),
1134
  'M16': (2.00,  44.0, 24.0, 17.7, 15.73, 16.00, 1.45, 16.0, 0.6, 14.08,  8.0, 1.6, 23.17, 6.8),
1135
  'M20': (2.50,  52.0, 30.0, 22.4, 19.67, 19.44, 2.04, 20.0, 0.8, 17.10, 10.0, 2.0, 28.87, 8.6),
1136
  'M24': (3.00,  60.0, 36.0, 26.4, 23.67, 21.73, 2.04, 24.0, 0.8, 19.15, 12.0, 2.0, 34.81, 10.4),
1137
  'M30': (3.50,  72.0, 45.0, 33.4, 29.67, 25.15, 2.89, 30.0, 1.0, 22.15, 15.5, 2.4, 43.61, 13.1),
1138
  'M36': (4.00,  84.0, 54.0, 39.4, 35.61, 30.85, 2.89, 36.0, 1.0, 27.15, 19.0, 3.0, 52.54, 15.3),
1139
  'M42': (4.50,  96.0, 63.0, 45.6, 41.61, 36.58, 3.06, 42.0, 1.2, 32.15, 24.0, 4.2, 61.34, 16.3),
1140
  'M48': (5.00, 108.0, 72.0, 52.6, 47.61, 41.14, 3.91, 48.0, 1.6, 36.15, 28.0, 4.8, 70.34, 17.5),
1141
  'M56': (5.50, 124.0, 84.0, 63.0, 55.54, 46.84, 5.95, 56.0, 2.0, 41.15, 34.0, 5.6, 82.26, 19.0),
1142
  'M64': (6.00, 140.0, 96.0, 71.0, 63.54, 52.54, 5.95, 64.0, 2.0, 46.15, 38.0, 6.4, 94.26, 22.0)
1143
  }
1144

1145
# nom length: l_min, l_max
1146
iso4762length = {
1147
  '2.5':(2.3,  2.7),
1148
  '3': ( 2.8,  3.2),
1149
  '4': ( 3.76, 4.24),
1150
  '5': ( 4.76, 5.24),
1151
  '6': ( 5.76, 6.24),
1152
  '8': ( 7.71, 8.29),
1153
  '10':( 9.71, 10.29),
1154
  '12':(11.65, 12.35),
1155
  '14':(13.65, 14.35),
1156
  '16':(15.65, 16.35),
1157
  '20':(19.58, 20.42),
1158
  '25':(24.58, 25.42),
1159
  '30':(29.58, 30.42),
1160
  '35':(34.5,  35.5),
1161
  '40':(39.5,  40.5),
1162
  '45':(44.5,  45.5),
1163
  '50':(49.5,  50.5),
1164
  '55':(54.4, 55.6),
1165
  '60':(59.4, 60.6),
1166
  '65':(64.4, 65.6),
1167
  '70':(69.4, 70.6),
1168
  '75':(74.4, 75.6),
1169
  '80':(79.4, 80.6),
1170
  '100':(99.3, 100.7),
1171
  '110':(109.3, 110.7),
1172
  '120':(119.3, 120.7),
1173
  '130':(129.2, 130.8),
1174
  '140':(139.2, 130.8),
1175
  '150':(149.2, 150.8),
1176
  '160':(159.2, 160.8),
1177
  '180':(179.2, 180.8),
1178
  '200':(199.1, 200.9),
1179
  '220':(219.1, 220.9),
1180
  '240':(237.7, 242.3),
1181
  '260':(219.1, 220.9),
1182
  '280':(219.1, 220.9),
1183
  '300':(219.1, 220.9)
1184
  }
1185

1186
# range of typical screw lengths
1187
#    min_length,  max_length
1188
iso4762range = {
1189
  'M1.6':('2.5', '16'),
1190
  'M2':  ('3', '20'),
1191
  'M2.5':('4', '25'),
1192
  'M3':  ('5', '30'),
1193
  '(M3.5)':('6', '35'),
1194
  'M4':  ('6', '40'),
1195
  'M5':  ('8', '50'),
1196
  'M6':  ('8', '60'),
1197
  'M8': ('10', '80'),
1198
  'M10':('16', '100'),
1199
  'M12':('20', '120'),
1200
  '(M14)':('25', '140'),
1201
  'M16':('25', '160'),
1202
  'M20':('16', '100'),
1203
  'M24':('40', '200'),
1204
  'M30':('45', '200'),
1205
  'M36':('55', '200'),
1206
  'M42':('60', '300'),
1207
  'M48':('100','300'),
1208
  'M56':('110','300'),
1209
  'M64':('120','300')
1210
  }
1211

1212

1213
# ISO 14579 Hexalobular socket head cap screws
1214
#   hexalobular recess;    tt = size of hexalobular recess
1215

1216
#           tt,    A,  t_mean
1217
iso14579def={
1218
  'M2':  ( 'T6',  1.75, 0.8),
1219
  'M2.5':( 'T8',  2.40, 1.0),
1220
  'M3':  ('T10',  2.80, 1.2),
1221
  'M4':  ('T20',  3.95, 1.7),
1222
  'M5':  ('T25',  4.50, 1.9),
1223
  'M6':  ('T30',  5.60, 2.3),
1224
  'M8':  ('T45',  7.95, 3.2),
1225
  'M10': ('T50',  8.95, 3.8),
1226
  'M12': ('T55', 11.35, 5.0),
1227
  '(M14)': ('T60', 13.45, 5.8),
1228
  'M16': ('T70', 15.70, 6.8),
1229
  '(M18)': ('T80', 17.75, 7.8),
1230
  'M20': ('T90', 20.20, 9.0),
1231
  }
1232

1233
# range of typical screw lengths
1234
#    min_length,  max_length
1235
iso14579range = {
1236
  'M2':  ('3', '20'),
1237
  'M2.5':('4', '25'),
1238
  'M3':  ('5', '30'),
1239
  'M4':  ('6', '40'),
1240
  'M5':  ('8', '50'),
1241
  'M6': ('10', '60'),
1242
  'M8': ('12', '80'),
1243
  'M10':('16','100'),
1244
  'M12':('20','120'),
1245
  '(M14)':('25','140'),
1246
  'M16':('25','160'),
1247
  '(M18)':('30','180'),
1248
  'M20':('30','200'),
1249
  }
1250

1251
iso14579length = {
1252
  '3': ( 2.8,  3.2),
1253
  '4': ( 3.76, 4.24),
1254
  '5': ( 4.76, 5.24),
1255
  '6': ( 5.76, 6.24),
1256
  '8': ( 7.71, 8.29),
1257
  '10':( 9.71, 10.29),
1258
  '12':(11.65, 12.35),
1259
  '16':(15.65, 16.35),
1260
  '20':(19.58, 20.42),
1261
  '25':(24.58, 25.42),
1262
  '30':(29.58, 30.42),
1263
  '35':(34.5,  35.5),
1264
  '40':(39.5,  40.5),
1265
  '45':(44.5,  45.5),
1266
  '50':(49.5,  50.5),
1267
  '55':(54.4, 55.6),
1268
  '60':(59.4, 60.6),
1269
  '65':(64.4, 65.6),
1270
  '70':(69.4, 70.6),
1271
  '80':(79.4, 80.6),
1272
  '90':(89.3, 90.7),
1273
  '100':(99.3, 100.7),
1274
  '110':(109.3, 110.7),
1275
  '120':(119.3, 120.7),
1276
  '130':(129.2, 130.8),
1277
  '140':(139.2, 130.8),
1278
  '150':(149.2, 150.8),
1279
  '160':(159.2, 160.8),
1280
  '180':(179.2, 180.8),
1281
  '200':(199.1, 200.9)
1282
  }
1283

1284

1285
# ISO 10642 Hexagon socket countersunk head screws (Allen screw)
1286
# ISO 10642 definitions
1287
#           P,   b,  dk_theo, dk_mean,da,  ds_min,   e,  k,   r,   s_mean, t,    w
1288
iso10642def={
1289
  'M3':  (0.50, 18.0,  6.72,  6.0,  3.3,  2.86,  2.31, 1.86, 0.1,  2.06,  1.1, 0.25),
1290
  'M4':  (0.70, 20.0,  8.96,  8.0,  4.4,  3.82,  2.88, 2.48, 0.2,  2.56,  1.5, 0.45),
1291
  'M5':  (0.80, 22.0, 11.20, 10.0,  5.5,  4.82,  3.45, 3.10, 0.2,  3.06,  1.9, 0.66),
1292
  'M6':  (1.00, 24.0, 13.44, 12.0,  6.6,  5.82,  4.59, 3.72, 0.25, 4.06,  2.2, 0.70),
1293
  'M8':  (1.25, 28.0, 17.92, 16.0,  8.54, 7.78,  5.73, 4.96, 0.4,  5.06,  3.0, 1.16),
1294
  'M10': (1.50, 32.0, 22.40, 20.5, 10.62, 9.78,  6.87, 6.20, 0.4,  6.06,  3.6, 1.62),
1295
  'M12': (1.75, 36.0, 26.88, 25.0, 13.5, 11.73,  9.15, 7.44, 0.6,  8.07,  4.3, 1.80),
1296
  '(M14)': (2.00, 40.0, 30.80, 28.4, 15.5, 13.73, 11.43, 8.40, 0.6, 10.07,  4.5, 1.62),
1297
  'M16': (2.00, 44.0, 33.60, 31.0, 17.5, 15.73, 11.43, 8.80, 0.6, 10.07,  4.8, 2.20),
1298
  'M20': (2.50, 52.0, 40.32, 38.0, 22.0, 19.67, 13.72, 10.16, 0.8, 12.10,  5.6, 2.20)}
1299

1300
# range of typical screw lengths
1301
#    min_length,  max_length
1302
iso10642range = {
1303
  'M3':  ('8', '30'),
1304
  'M4':  ('8', '40'),
1305
  'M5':  ('8', '50'),
1306
  'M6':  ('8', '60'),
1307
  'M8': ('10', '80'),
1308
  'M10':('12','100'),
1309
  'M12':('20','100'),
1310
  '(M14)':('25','100'),
1311
  'M16':('30','100'),
1312
  'M20':('35','100'),
1313
  }
1314

1315
iso10642length = {
1316
  '8': ( 7.71, 8.29),
1317
  '10':( 9.71, 10.29),
1318
  '12':(11.65, 12.35),
1319
  '16':(15.65, 16.35),
1320
  '20':(19.58, 20.42),
1321
  '25':(24.58, 25.42),
1322
  '30':(29.58, 30.42),
1323
  '35':(34.5,  35.5),
1324
  '40':(39.5,  40.5),
1325
  '45':(44.5,  45.5),
1326
  '50':(49.5,  50.5),
1327
  '55':(54.4, 55.6),
1328
  '60':(59.4, 60.6),
1329
  '65':(64.4, 65.6),
1330
  '70':(69.4, 70.6),
1331
  '80':(79.4, 80.6),
1332
  '90':(89.3, 90.7),
1333
  '100':(99.3, 100.7),
1334
  }
1335

1336

1337
# ISO 7089 definitions Washer
1338
#           d1_min, d2_max, h, h_max
1339
iso7089def={
1340
  'M1.6':( 1.7,  4.0, 0.3, 0.35),
1341
  'M2':  ( 2.2,  5.0, 0.3, 0.35),
1342
  'M2.5':( 2.7,  6.0, 0.5, 0.55),
1343
  'M3':  ( 3.2,  7.0, 0.5, 0.55),
1344
  'M4':  ( 4.3,  9.0, 0.8, 0.90),
1345
  'M5':  ( 5.3, 10.0, 1.0, 1.10),
1346
  'M6':  ( 6.4, 12.0, 1.6, 1.80),
1347
  'M8':  ( 8.4, 16.0, 1.6, 1.80),
1348
  'M10': (10.5, 20.0, 2.0, 2.20),
1349
  'M12': (13.0, 24.0, 2.5, 2.70),
1350
  'M16': (17.0, 30.0, 3.0, 3.30),
1351
  'M20': (21.0, 37.0, 3.0, 3.30),
1352
  'M24': (25.0, 44.0, 4.0, 4.30),
1353
  'M30': (31.0, 56.0, 4.0, 4.30),
1354
  'M36': (37.0, 66.0, 5.0, 5.60),
1355
  'M42': (45.0, 78.0, 8.0, 9.0),
1356
  'M48': (52.0, 92.0, 8.0, 9.0),
1357
  'M56': (62.0,105.0,10.0, 11.0),
1358
  'M64': (70.0,115.0,10.0, 11.0)
1359
  }
1360

1361

1362
# ISO 7090 definitions Plain washers, chamfered - Normal series
1363
# chamfer angle 30° / 45°
1364
# chamfer      h/4 / h/2
1365
#           d1_min, d2_max, h, h_max
1366
iso7090def={
1367
  'M5':  ( 5.3, 10.0, 1.0, 1.10),
1368
  'M6':  ( 6.4, 12.0, 1.6, 1.80),
1369
  'M8':  ( 8.4, 16.0, 1.6, 1.80),
1370
  'M10': (10.5, 20.0, 2.0, 2.20),
1371
  'M12': (13.0, 24.0, 2.5, 2.70),
1372
  'M16': (17.0, 30.0, 3.0, 3.30),
1373
  'M20': (21.0, 37.0, 3.0, 3.30),
1374
  'M24': (25.0, 44.0, 4.0, 4.30),
1375
  'M30': (31.0, 56.0, 4.0, 4.30),
1376
  'M36': (37.0, 66.0, 5.0, 5.60),
1377
  'M42': (45.0, 78.0, 8.0, 9.0),
1378
  'M48': (52.0, 92.0, 8.0, 9.0),
1379
  'M56': (62.0,105.0,10.0, 11.0),
1380
  'M64': (70.0,115.0,10.0, 11.0)
1381
  }
1382

1383

1384
# ISO 7091 definitions  Plain washer - Normal series Product Grade C
1385
#           d1_min, d2_max, h, h_max
1386
iso7091def={
1387
  'M1.6':( 1.8,  4.0, 0.3, 0.35),
1388
  'M2':  ( 2.4,  5.0, 0.3, 0.35),
1389
  'M2.5':( 2.9,  6.0, 0.5, 0.55),
1390
  'M3':  ( 3.4,  7.0, 0.5, 0.55),
1391
  'M4':  ( 4.5,  9.0, 0.8, 0.90),
1392
  'M5':  ( 5.5, 10.0, 1.0, 1.10),
1393
  'M6':  ( 6.6, 12.0, 1.6, 1.80),
1394
  'M8':  ( 9.0, 16.0, 1.6, 1.80),
1395
  'M10': (11.0, 20.0, 2.0, 2.20),
1396
  'M12': (13.5, 24.0, 2.5, 2.70),
1397
  'M16': (17.5, 30.0, 3.0, 3.30),
1398
  'M20': (22.0, 37.0, 3.0, 3.30),
1399
  'M24': (26.0, 44.0, 4.0, 4.30),
1400
  'M30': (33.0, 56.0, 4.0, 4.30),
1401
  'M36': (39.0, 66.0, 5.0, 5.60),
1402
  'M42': (45.0, 78.0, 8.0, 9.0),
1403
  'M48': (52.0, 92.0, 8.0, 9.0),
1404
  'M56': (62.0,105.0,10.0, 11.0),
1405
  'M64': (70.0,115.0,10.0, 11.0)
1406
  }
1407

1408

1409
# ISO 7092 definitions  Plain washers - Small series
1410
#           d1_min, d2_max, h, h_max
1411
iso7092def={
1412
  'M1.6':( 1.7,  3.5, 0.3, 0.35),
1413
  'M2':  ( 2.2,  4.5, 0.3, 0.35),
1414
  'M2.5':( 2.7,  5.0, 0.5, 0.55),
1415
  'M3':  ( 3.2,  6.0, 0.5, 0.55),
1416
  'M4':  ( 4.3,  8.0, 0.5, 0.55),
1417
  'M5':  ( 5.3,  9.0, 1.0, 1.10),
1418
  'M6':  ( 6.4, 11.0, 1.6, 1.80),
1419
  'M8':  ( 8.4, 15.0, 1.6, 1.80),
1420
  'M10': (10.5, 18.0, 1.6, 1.80),
1421
  'M12': (13.0, 20.0, 2.0, 2.20),
1422
  'M16': (17.0, 28.0, 2.5, 2.70),
1423
  'M20': (21.0, 34.0, 3.0, 3.30),
1424
  'M24': (25.0, 39.0, 4.0, 4.30),
1425
  'M30': (31.0, 50.0, 4.0, 4.30),
1426
  'M36': (37.0, 60.0, 5.0, 5.60)
1427
  }
1428

1429

1430

1431
# ISO 7093-1 definitions  Plain washers - Large series
1432
#           d1_min, d2_max, h, h_max
1433
iso7093def={
1434
  'M3':    ( 3.2,  9.0, 0.8, 0.90),
1435
  '(M3.5)':( 3.7, 11.0, 0.8, 0.90),
1436
  'M4':    ( 4.3, 12.0, 1.0, 1.10),
1437
  'M5':    ( 5.3, 15.0, 1.0, 1.10),
1438
  'M6':    ( 6.4, 18.0, 1.6, 1.80),
1439
  'M8':    ( 8.4, 24.0, 2.0, 2.20),
1440
  'M10':   (10.5, 30.0, 2.5, 2.70),
1441
  'M12':   (13.0, 37.0, 3.0, 3.30),
1442
  '(M14)': (15.0, 44.0, 3.0, 3.30),
1443
  'M16':   (17.0, 50.0, 3.0, 3.30),
1444
  '(M18)': (19.0, 56.0, 4.0, 4.30),
1445
  'M20':   (21.0, 60.0, 4.0, 4.30),
1446
  '(M22)': (23.0, 66.0, 5.0, 5.60),
1447
  'M24':   (25.0, 72.0, 5.0, 5.60),
1448
  '(M27)': (30.0, 85.0, 6.0, 6.60),
1449
  'M30':   (33.0, 92.0, 6.0, 6.60),
1450
  '(M33)': (36.0,105.0, 6.0, 6.60),
1451
  'M36':   (39.0,110.0, 8.0, 9.00)
1452
  }
1453

1454

1455
# ISO 7094 definitions  Plain washers - Extra large series
1456
#           d1_min, d2_max, h, h_max
1457
iso7094def={
1458
  'M5':    ( 5.5, 18.0, 2.0, 2.3),
1459
  'M6':    ( 6.6, 22.0, 2.0, 2.3),
1460
  'M8':    ( 9.0, 28.0, 3.0, 3.6),
1461
  'M10':   (11.0, 34.0, 3.0, 3.6),
1462
  'M12':   (13.5, 44.0, 4.0, 4.6),
1463
  '(M14)': (15.5, 50.0, 4.0, 4.6),
1464
  'M16':   (17.5, 56.0, 5.0, 6.0),
1465
  '(M18)': (20.0, 60.0, 5.0, 6.0),
1466
  'M20':   (22.0, 72.0, 6.0, 7.0),
1467
  '(M22)': (24.0, 80.0, 6.0, 7.0),
1468
  'M24':   (26.0, 85.0, 6.0, 7.0),
1469
  '(M27)': (30.0, 98.0, 6.0, 7.0),
1470
  'M30':   (33.0,105.0, 6.0, 7.0),
1471
  '(M33)': (36.0,115.0, 8.0, 9.2),
1472
  'M36':   (39.0,125.0, 8.0, 9.2)
1473
  }
1474

1475

1476

1477

1478
# ISO 4757:1983 Definition of cross recess type H
1479
#          b, e_min, g, f_mean, r, t1, alpha, beta
1480
iso4757def = {
1481
  '0': (0.61, 0.26, 0.81, 0.34, 0.3, 0.22, 138.0, 7.0 ),
1482
  '1': (0.97, 0.41, 1.27, 0.54, 0.5, 0.34, 138.0, 7.0 ),
1483
  '2': (1.47, 0.79, 2.29, 0.70, 0.6, 0.61, 140.0, 5.75),
1484
  '3': (2.41, 1.98, 3.81, 0.83, 0.8, 1.01, 146.0, 5.75),
1485
  '4': (3.48, 2.39, 5.08, 1.23, 1.0, 1.35, 153.0, 7.0 )
1486
  }
1487

1488
# ISO 10664 Hexalobular internal driving feature for bolts and screws
1489
#           A,     B,   Re
1490
iso10664def = {
1491
  'T6': ( 1.75,  1.205, 0.14),
1492
  'T8': ( 2.40,  1.67, 0.20),
1493
  'T10':( 2.80,  1.98, 0.24),
1494
  'T15':( 3.35,  2.35, 0.28),
1495
  'T20':( 3.95,  2.75, 0.32),
1496
  'T25':( 4.50,  3.16, 0.39),
1497
  'T30':( 5.60,  3.95, 0.46),
1498
  'T40':( 6.75,  4.76, 0.56),
1499
  'T45':( 7.93,  5.55, 0.59),
1500
  'T50':( 8.95,  6.36, 0.78),
1501
  'T55':(11.35,  7.92, 0.77),
1502
  'T60':(13.45,  9.48, 1.07),
1503
  'T70':(15.70, 11.08, 1.20),
1504
  'T80':(17.75, 12.64, 1.53),
1505
  'T90':(20.20, 14.22, 1.54),
1506
  'T100':(22.40,15.81, 1.73)
1507
  }
1508

1509

1510

1511
# ISO 4032 Hex-head-nut
1512
#           P,   c,  damax, dw,    e,     m,  mw,  s_nom
1513
iso4032def={
1514
  'M1.6':  (0.35, 0.2, 1.84, 2.9,  3.4,   1.3, 0.8,  3.2),
1515
  'M2':    (0.40, 0.2, 2.3,  3.7,  4.4,   1.6, 1.1,  4.0),
1516
  'M2.5':  (0.45, 0.2, 2.9,  4.6,  5.5,   2.0, 1.4,  5.0),
1517
  'M3':    (0.5,  0.2, 3.45, 5.2,  6.1,   2.4, 1.7,  5.5),
1518
  '(M3.5)':(0.6,  0.2, 4.00, 5.7,  6.6,   2.8, 2.0,  6.0),
1519
  'M4':    (0.7,  0.2, 4.6,  6.6,  7.7,   3.2, 2.3,  7.0),
1520
  'M5':    (0.8,  0.2, 5.75, 7.5,  8.9,   3.5, 3.5,  8.0),
1521
  'M6':    (1.0,  0.2, 6.75, 9.5,  11.05, 4.7, 3.9, 10.0),
1522
  'M8':    (1.25, 0.3, 8.75, 11.7, 14.5,  6.8, 5.2, 13.0),
1523
  'M10':   (1.50, 0.3, 10.8, 14.7, 17.9,  8.4, 6.4,  16.0),
1524
  'M12':   (1.75, 0.3, 13.0, 16.7, 20.1, 10.8, 8.3,  18.0),
1525
  '(M14)': (2.00, 0.3, 15.1, 20.5, 24.5, 12.8, 9.7,  22.0),
1526
  'M16':   (2.00, 0.4, 17.3, 22.4, 26.9, 14.8, 11.3,  24.0),
1527
  '(M18)': (2.50, 0.4, 19.5, 24.9, 29.6, 15.8, 12.3,  27.0),
1528
  'M20':   (2.50, 0.4, 21.6, 28.2, 33.7, 18.0, 13.5,  30.0),
1529
  '(M22)': (2.50, 0.4, 23.7, 31.4, 37.3, 19.4, 15.0,  34.0),
1530
  'M24':   (3.00, 0.4, 25.9, 33.7, 40.1, 21.5, 16.2,  36.0),
1531
  '(M27)': (3.00, 0.4, 29.1, 38.0, 45.2, 23.8, 18.0,  41.0),
1532
  'M30':   (3.50, 0.4, 32.4, 42.8, 50.9, 25.6, 19.4,  46.0),
1533
  '(M33)': (3.50, 0.4, 35.6, 46.6, 55.4, 28.7, 21.4,  50.0),
1534
  'M36':   (4.00, 0.4, 38.9, 51.2, 61.0, 31.0, 23.5,  55.0),
1535
  '(M39)': (4.00, 0.5, 42.1, 55.9, 66.5, 33.4, 24.5,  60.0),
1536
  'M42':   (4.50, 0.7, 45.4, 60.0, 71.3, 34.0, 25.9,  65.0),
1537
  '(M45)': (4.50, 0.7, 48.6, 64.7, 77.0, 36.0, 27.9,  70.0),
1538
  'M48':   (5.00, 0.7, 51.8, 69.5, 82.6, 38.0, 29.1,  75.0),
1539
  '(M52)': (5.00, 0.7, 56.2, 74.5, 88.3, 42.0, 32.1,  80.0),
1540
  'M56':   (5.50, 0.7, 60.5, 78.7, 93.6, 45.0, 34.7,  85.0),
1541
  '(M60)': (5.50, 0.7, 64.8, 82.7, 99.2, 48.0, 38.7,  90.0),
1542
  'M64':   (6.00, 0.7, 69.1, 88.2,104.9, 51.0, 39.3,  95.0)
1543
  }
1544

1545

1546

1547
# ISO 4033 Hexagon nuts style 2
1548
#           P,   c,  damax, dw,    e,     m,  mw,  s_nom
1549
iso4033def={
1550
  'M5':    (0.8,  0.2, 5.75, 7.5,  8.9,   5.1, 3.5,  8.0),
1551
  'M6':    (1.0,  0.2, 6.75, 9.5,  11.05, 5.7, 3.9, 10.0),
1552
  'M8':    (1.25, 0.3, 8.75, 11.7, 14.5,  7.5, 5.2, 13.0),
1553
  'M10':   (1.50, 0.3, 10.8, 14.7, 17.9,  9.3, 6.4,  16.0),
1554
  'M12':   (1.75, 0.3, 13.0, 16.7, 20.1, 12.0, 8.3,  18.0),
1555
  '(M14)': (2.00, 0.3, 15.1, 20.5, 24.5, 14.1, 9.7,  22.0),
1556
  'M16':   (2.00, 0.4, 17.3, 22.4, 26.9, 16.4, 11.3,  24.0),
1557
  'M20':   (2.50, 0.4, 21.6, 28.2, 33.7, 20.3, 13.5,  30.0),
1558
  'M24':   (3.00, 0.4, 25.9, 33.7, 40.1, 23.9, 16.2,  36.0),
1559
  'M30':   (3.50, 0.4, 32.4, 42.8, 50.9, 28.6, 19.4,  46.0),
1560
  'M36':   (4.00, 0.4, 38.9, 51.2, 61.0, 33.1, 23.5,  55.0)
1561
  }
1562

1563
# ISO 4035 Hexagon thin nuts, chamfered
1564
#           P,   c,  damax, dw,    e,     m,  mw,  s_nom
1565
iso4035def={
1566
  'M1.6':  (0.35, 0.2, 1.84, 2.9,  3.4,   1.0,  0.8,  3.2),
1567
  'M2':    (0.40, 0.2, 2.3,  3.7,  4.4,   1.2,  1.1,  4.0),
1568
  'M2.5':  (0.45, 0.2, 2.9,  4.6,  5.5,   1.6,  1.4,  5.0),
1569
  'M3':    (0.5,  0.2, 3.45, 5.2,  6.1,   1.8,  1.7,  5.5),
1570
  '(M3.5)':(0.6,  0.2, 4.00, 5.7,  6.6,   2.0,  2.0,  6.0),
1571
  'M4':    (0.7,  0.2, 4.6,  6.6,  7.7,   2.2,  2.3,  7.0),
1572
  'M5':    (0.8,  0.2, 5.75, 7.5,  8.9,   2.7,  3.5,  8.0),
1573
  'M6':    (1.0,  0.2, 6.75, 9.5,  11.05, 3.2,  3.9, 10.0),
1574
  'M8':    (1.25, 0.3, 8.75, 11.7, 14.5,  4.0,  5.2, 13.0),
1575
  'M10':   (1.50, 0.3, 10.8, 14.7, 17.9,  5.0,  6.4, 16.0),
1576
  'M12':   (1.75, 0.3, 13.0, 16.7, 20.1,  6.0,  8.3, 18.0),
1577
  '(M14)': (2.00, 0.3, 15.1, 20.5, 24.5,  7.0,  9.7, 22.0),
1578
  'M16':   (2.00, 0.4, 17.3, 22.4, 26.9,  8.0, 11.3, 24.0),
1579
  '(M18)': (2.50, 0.4, 19.5, 24.9, 29.6,  9.0, 12.3, 27.0),
1580
  'M20':   (2.50, 0.4, 21.6, 28.2, 33.7, 10.0, 13.5, 30.0),
1581
  '(M22)': (2.50, 0.4, 23.7, 31.4, 37.3, 11.0, 15.0, 34.0),
1582
  'M24':   (3.00, 0.4, 25.9, 33.7, 40.1, 12.0, 16.2, 36.0),
1583
  '(M27)': (3.00, 0.4, 29.1, 38.0, 45.2, 13.5, 18.0, 41.0),
1584
  'M30':   (3.50, 0.4, 32.4, 42.8, 50.9, 15.0, 19.4, 46.0),
1585
  '(M33)': (3.50, 0.4, 35.6, 46.6, 55.4, 16.5, 21.4, 50.0),
1586
  'M36':   (4.00, 0.4, 38.9, 51.2, 61.0, 18.0, 23.5, 55.0),
1587
  '(M39)': (4.00, 0.5, 42.1, 55.9, 66.5, 19.5, 24.5, 60.0),
1588
  'M42':   (4.50, 0.7, 45.4, 60.0, 71.3, 21.0, 25.9, 65.0),
1589
  '(M45)': (4.50, 0.7, 48.6, 64.7, 77.0, 22.5, 27.9, 70.0),
1590
  'M48':   (5.00, 0.7, 51.8, 69.5, 82.6, 24.0, 29.1, 75.0),
1591
  '(M52)': (5.00, 0.7, 56.2, 74.5, 88.3, 26.0, 32.1, 80.0),
1592
  'M56':   (5.50, 0.7, 60.5, 78.7, 93.6, 28.0, 34.7, 85.0),
1593
  '(M60)': (5.50, 0.7, 64.8, 82.7, 99.2, 30.0, 38.7, 90.0),
1594
  'M64':   (6.00, 0.7, 69.1, 88.2,104.9, 32.0, 39.3, 95.0)
1595
  }
1596

1597
# ISO 4036 Hexagon thin nuts, unchamfered
1598
#           P,      e,   m,  s_nom
1599
iso4036def={
1600
  'M1.6':  (0.35,  3.4, 1.0,  3.2),
1601
  'M2':    (0.40,  4.4, 1.2,  4.0),
1602
  'M2.5':  (0.45,  5.5, 1.6,  5.0),
1603
  'M3':    (0.5,   6.1, 1.8,  5.5),
1604
  '(M3.5)':(0.6,   6.6, 2.0,  6.0),
1605
  'M4':    (0.7,   7.7, 2.2,  7.0),
1606
  'M5':    (0.8,   8.9, 2.7,  8.0),
1607
  'M6':    (1.0,  10.9, 3.2, 10.0),
1608
  'M8':    (1.25, 14.5, 4.0, 13.0),
1609
  'M10':   (1.50, 17.9, 5.0, 16.0)}
1610

1611
# EN 1661 Hexagon nuts with flange
1612
#          P,    damax,  c,  dc,    dw,    e,     m,   mw,   r,   s
1613
en1661def={
1614
  'M5'   :(0.80,  5.75, 1.0, 11.8,  9.8,  8.79,  5.0, 2.5,  0.30,  8.0),
1615
  'M6'   :(1.00,  6.75, 1.1, 14.2, 12.2, 11.05,  6.0, 3.1,  0.36, 10.0),
1616
  'M8'   :(1.25,  8.75, 1.2, 17.9, 15.8, 14.38,  8.0, 4.6,  0.48, 13.0),
1617
  'M10'  :(1.50, 10.80, 1.5, 21.8, 19.6, 17.77, 10.0, 5.9,  0.60, 16.0),
1618
  'M12'  :(1.75, 13.00, 1.8, 26.0, 23.8, 20.03, 12.0, 6.8,  0.72, 18.0),
1619
  '(M14)':(2.00, 15.10, 2.1, 29.9, 27.6, 23.36, 14.0, 7.7,  0.88, 21.0),
1620
  'M16'  :(2.00, 17.30, 2.4, 34.5, 31.9, 26.75, 16.0, 8.9,  0.96, 24.0),
1621
  'M20'  :(2.50, 21.60, 3.0, 42.8, 39.9, 33.23, 20.0,10.7,  1.20, 30.0)}
1622

1623
# Tuning table to get valid shapes
1624
#         P, tunIn, tunEx
1625
tuningTable={
1626
  'M1.6':(0.35, 516, 516),
1627
  'M2':  (0.40, 515, 516),
1628
  'M2.5':(0.45, 515, 515),
1629
  'M3':  (0.5,  480, 502),
1630
  '(M3.5)':(0.6,  480, 502),
1631
  'M4':  (0.7,  510, 519), #last value needed for ISO7380
1632
  'M5':  (0.8,  510, 510),
1633
  'M6':  (1.0,  515, 515),
1634
  'M8':  (1.25, 516, 516),
1635
  'M10': (1.50, 515, 515),
1636
  'M12': (1.75, 513, 513),
1637
  '(M14)': (2.00, 513, 513),
1638
  'M16': (2.00, 513, 513),
1639
  'M20': (2.50, 513, 513),
1640
  'M24': (3.00, 513, 513),
1641
  '(M27)': (3.00, 513, 513),
1642
  'M30': (3.50, 513, 513),
1643
  '(M33)': (3.50, 513, 513),
1644
  'M36': (4.00, 513, 513),
1645
  'M42': (4.50, 515, 515),
1646
  '(M45)': (4.50, 515, 515),
1647
  'M48': (5.00, 515, 505), # ISO4014: 505, 502 or 488; ISO4017: above 505
1648
  '(M52)': (5.00, 508, 508),
1649
  'M56': (5.50, 508, 508),
1650
  '(M60)': (5.50, 508, 508),
1651
  'M64': (6.00, 489, 489) # Nut ISO4032: 489
1652
  }
1653

1654

1655
def equal_vertex(vert1, vert2, p=5):
1656
  # compares two vertices
1657
  return (round(vert1.X - vert2.X,p)==0 and round(vert1.Y - vert2.Y,p)==0 and round(vert1.Z - vert2.Z,p)==0)
1658

1659
try:
1660
  _fromUtf8 = QtCore.QString.fromUtf8
1661
except AttributeError:
1662
  _fromUtf8 = lambda s: s
1663

1664
class Ui_ScrewMaker(object):
1665
  def setupUi(self, ScrewMaker):
1666
    FCUi = FreeCADGui.UiLoader()
1667

1668
    ScrewMaker.setObjectName(_fromUtf8("ScrewMaker"))
1669
    ScrewMaker.resize(450, 362)
1670
    ScrewMaker.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedKingdom))
1671
    self.layoutWidget = QtGui.QWidget(ScrewMaker)
1672
    self.layoutWidget.setGeometry(QtCore.QRect(348, 35, 102, 161))
1673
    self.layoutWidget.setObjectName(_fromUtf8("layoutWidget"))
1674
    self.verticalLayout_2 = QtGui.QVBoxLayout(self.layoutWidget)
1675
    #self.verticalLayout_2.setMargin(0)
1676
    self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
1677
    self.ScrewTypeLabel = QtGui.QLabel(self.layoutWidget)
1678
    self.ScrewTypeLabel.setObjectName(_fromUtf8("ScrewTypeLabel"))
1679
    self.verticalLayout_2.addWidget(self.ScrewTypeLabel)
1680
    self.NomDiaLabel = QtGui.QLabel(self.layoutWidget)
1681
    self.NomDiaLabel.setObjectName(_fromUtf8("NomDiaLabel"))
1682
    self.verticalLayout_2.addWidget(self.NomDiaLabel)
1683
    self.NomLenLabel = QtGui.QLabel(self.layoutWidget)
1684
    self.NomLenLabel.setObjectName(_fromUtf8("NomLenLabel"))
1685
    self.verticalLayout_2.addWidget(self.NomLenLabel)
1686
    self.UserLenLabel = QtGui.QLabel(self.layoutWidget)
1687
    self.UserLenLabel.setObjectName(_fromUtf8("UserLenLabel"))
1688
    self.verticalLayout_2.addWidget(self.UserLenLabel)
1689

1690
    self.layoutWidget1 = QtGui.QWidget(ScrewMaker)
1691
    self.layoutWidget1.setGeometry(QtCore.QRect(3, 35, 350, 166))
1692
    #self.layoutWidget1.setGeometry(QtCore.QRect(10, 5, 315, 200))
1693
    self.layoutWidget1.setObjectName(_fromUtf8("layoutWidget1"))
1694
    self.verticalLayout = QtGui.QVBoxLayout(self.layoutWidget1)
1695
    #self.verticalLayout.setMargin(0)
1696
    self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
1697
    self.ScrewType = QtGui.QComboBox(self.layoutWidget1)
1698
    self.ScrewType.setObjectName(_fromUtf8("ScrewType"))
1699
    for i in range(33):
1700
      self.ScrewType.addItem(_fromUtf8(""))  # 0
1701

1702
    self.verticalLayout.addWidget(self.ScrewType)
1703
    self.NominalDiameter = QtGui.QComboBox(self.layoutWidget1)
1704
    self.NominalDiameter.setObjectName(_fromUtf8("NominalDiameter"))
1705
    for i in range(52):
1706
      self.NominalDiameter.addItem(_fromUtf8("")) # 0
1707

1708
    self.verticalLayout.addWidget(self.NominalDiameter)
1709
    self.NominalLength = QtGui.QComboBox(self.layoutWidget1)
1710
    self.NominalLength.setObjectName(_fromUtf8("NominalLength"))
1711
    for i in range(48):
1712
      self.NominalLength.addItem(_fromUtf8("")) #0
1713

1714
    self.verticalLayout.addWidget(self.NominalLength)
1715
    #self.UserLen = QtGui.QComboBox(self.layoutWidget1)
1716
    self.UserLen = FCUi.createWidget("Gui::InputField")
1717
    self.UserLen.setObjectName(_fromUtf8("UserLen"))
1718
    #self.UserLen.addItem(_fromUtf8(""))
1719
    self.UserLen.setProperty("text", "0 mm")
1720
    self.verticalLayout.addWidget(self.UserLen)
1721

1722
    #self.CommentLabel = QtGui.QLabel(self.layoutWidget)
1723
    self.CommentLabel = QtGui.QLabel(ScrewMaker)
1724
    self.CommentLabel.setObjectName(_fromUtf8("CommentLabel"))
1725
    self.CommentLabel.setGeometry(QtCore.QRect(10, 184, 411, 21))
1726
    #self.verticalLayout.addWidget(self.CommentLabel)
1727

1728
    self.layoutWidget2 = QtGui.QWidget(ScrewMaker)
1729
    #self.layoutWidget2.setGeometry(QtCore.QRect(10, 200, 321, 83))
1730
    self.layoutWidget2.setGeometry(QtCore.QRect(3, 200, 321, 120))
1731
    self.layoutWidget2.setObjectName(_fromUtf8("layoutWidget2"))
1732
    self.verticalLayout_3 = QtGui.QVBoxLayout(self.layoutWidget2)
1733
    #self.verticalLayout_3.setMargin(0)
1734
    self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
1735
    self.SimpleScrew = QtGui.QRadioButton(self.layoutWidget2)
1736
    self.SimpleScrew.setChecked(True)
1737
    self.SimpleScrew.setObjectName(_fromUtf8("SimpleScrew"))
1738
    self.verticalLayout_3.addWidget(self.SimpleScrew)
1739
    self.SymbolThread = QtGui.QRadioButton(self.layoutWidget2)
1740
    self.SymbolThread.setObjectName(_fromUtf8("SymbolThread"))
1741
    self.verticalLayout_3.addWidget(self.SymbolThread)
1742
    self.RealThread = QtGui.QRadioButton(self.layoutWidget2)
1743
    self.RealThread.setObjectName(_fromUtf8("RealThread"))
1744
    self.verticalLayout_3.addWidget(self.RealThread)
1745
    self.MessageLabel = QtGui.QLabel(ScrewMaker)
1746
    self.MessageLabel.setGeometry(QtCore.QRect(10, 10, 411, 21))
1747
    self.MessageLabel.setProperty("Empty_text", _fromUtf8(""))
1748
    self.MessageLabel.setObjectName(_fromUtf8("MessageLabel"))
1749
    self.CreateButton = QtGui.QToolButton(ScrewMaker)
1750
    self.CreateButton.setGeometry(QtCore.QRect(180, 320, 111, 26))
1751
    self.CreateButton.setObjectName(_fromUtf8("CreateButton"))
1752
    self.ScrewAvailable = True
1753

1754
    self.simpThread = self.SimpleScrew.isChecked()
1755
    self.symThread = self.SymbolThread.isChecked()
1756
    self.rThread = self.RealThread.isChecked()
1757

1758
    self.theScrew = Screw()
1759

1760
    self.retranslateUi(ScrewMaker)
1761
    self.NominalDiameter.setCurrentIndex(5)
1762
    self.NominalLength.setCurrentIndex(9)
1763
    QtCore.QObject.connect(self.ScrewType, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.guiCheck_Data)
1764
    QtCore.QObject.connect(self.CreateButton, QtCore.SIGNAL(_fromUtf8("pressed()")), self.guiCreateScrew)
1765
    QtCore.QObject.connect(self.NominalDiameter, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.guiCheck_Data)
1766
    QtCore.QObject.connect(self.NominalLength, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.guiCheck_Data)
1767
    QtCore.QMetaObject.connectSlotsByName(ScrewMaker)
1768

1769
  def retranslateUi(self, ScrewMaker):
1770
    ScrewMaker.setWindowTitle(tr('ScrewMaker', 'Screw-Maker 2.2'))
1771
    self.ScrewTypeLabel.setText(tr('ScrewMaker', 'Type of Screw'))
1772
    self.NomDiaLabel.setText(tr('ScrewMaker', 'Nomimal\nDiameter'))
1773
    self.NomLenLabel.setText(tr('ScrewMaker', 'Nominal\nLength'))
1774
    self.UserLenLabel.setText(tr('ScrewMaker', 'User length \nfor screw-tap'))
1775
    self.CommentLabel.setText(tr('ScrewMaker', 'Values in brackets are not recommended!'))
1776
    self.ScrewType.setItemText(0, tr('ScrewMaker', 'ISO4017: Hexagon head screws'))
1777
    self.ScrewType.setItemText(1, tr('ScrewMaker', 'ISO4014: Hexagon head bolts'))
1778
    self.ScrewType.setItemText(2, tr('ScrewMaker', 'EN1662: Hexagon bolts with flange, small\n    series'))
1779
    self.ScrewType.setItemText(3, tr('ScrewMaker', 'EN1665: Hexagon bolts with flange, heavy\n    series'))
1780
    self.ScrewType.setItemText(4, tr('ScrewMaker', 'ISO8676: Hexagon head screw with\n    metric fine pitch thread'))
1781
    self.ScrewType.setItemText(5, tr('ScrewMaker', 'ISO4762: Hexagon socket head cap screws'))
1782
    self.ScrewType.setItemText(6, tr('ScrewMaker', 'ISO7380-1: Hexagon socket button head\n    screws'))
1783
    self.ScrewType.setItemText(7, tr('ScrewMaker', 'ISO7380-2: Hexagon socket button head\n    screws with collar'))
1784
    self.ScrewType.setItemText(8, tr('ScrewMaker', 'DIN967: Cross recessed pan head screws\n    with collar'))
1785
    self.ScrewType.setItemText(9, tr('ScrewMaker', 'ISO10642: Hexagon socket countersunk \n    head screws'))
1786
    self.ScrewType.setItemText(10, tr('ScrewMaker', 'ISO2009: Slotted countersunk flat head\n    screws'))
1787
    self.ScrewType.setItemText(11, tr('ScrewMaker', 'ISO2010: Slotted raised countersunk head\n    screws'))
1788
    self.ScrewType.setItemText(12, tr('ScrewMaker', 'ISO1207: Slotted cheese head screws'))
1789
    self.ScrewType.setItemText(13, tr('ScrewMaker', 'ISO1580: Slotted pan head screws'))
1790
    self.ScrewType.setItemText(14, tr('ScrewMaker', 'ISO7045: Pan head screws, type H cross recess'))
1791
    self.ScrewType.setItemText(15, tr('ScrewMaker', 'ISO7046: Countersunk flat head screws\n    H cross recess'))
1792
    self.ScrewType.setItemText(16, tr('ScrewMaker', 'ISO7047: Raised countersunk head screws\n    H cross recess'))
1793
    self.ScrewType.setItemText(17, tr('ScrewMaker', 'ISO7048: Cheese head screws type H cross recess'))
1794
    self.ScrewType.setItemText(18, tr('ScrewMaker', 'ISO14579: Hexalobular socket head cap screws'))
1795
    self.ScrewType.setItemText(19, tr('ScrewMaker', 'ISO14580: Hexalobular socket cheese head\n    screws'))
1796
    self.ScrewType.setItemText(20, tr('ScrewMaker', 'ISO14583: Hexalobular socket pan head screws'))
1797
    self.ScrewType.setItemText(21, tr('ScrewMaker', 'ISO14582: Hexalobular socket countersunk\n    head screws, high head'))
1798
    self.ScrewType.setItemText(22, tr('ScrewMaker', 'ISO14584: Hexalobular socket raised\n    countersunk head screws'))
1799
    self.ScrewType.setItemText(23, tr('ScrewMaker', 'ISO7089: Plain washers - Normal series'))
1800
    self.ScrewType.setItemText(24, tr('ScrewMaker', 'ISO7090: Plain washers, chamfered - Normal series'))
1801
    self.ScrewType.setItemText(25, tr('ScrewMaker', 'ISO7092: Plain washers - Small series'))
1802
    self.ScrewType.setItemText(26, tr('ScrewMaker', 'ISO7093-1: Plain washer - Large series'))
1803
    self.ScrewType.setItemText(27, tr('ScrewMaker', 'ISO7094: Plain washers - Extra large series'))
1804
    self.ScrewType.setItemText(28, tr('ScrewMaker', 'ISO4032: Hexagon nuts, Style 1'))
1805
    self.ScrewType.setItemText(29, tr('ScrewMaker', 'ISO4033: Hexagon nuts, Style 2'))
1806
    self.ScrewType.setItemText(30, tr('ScrewMaker', 'ISO4035: Hexagon thin nuts, chamfered'))
1807
    self.ScrewType.setItemText(31, tr('ScrewMaker', 'EN1661: Hexagon nuts with flange'))
1808
    self.ScrewType.setItemText(32, tr('ScrewMaker', 'ScrewTap: ISO Screw-Tap'))
1809

1810
    self.NominalDiameter.setItemText(0, tr('ScrewMaker', 'M1.6'))
1811
    self.NominalDiameter.setItemText(1, tr('ScrewMaker', 'M2'))
1812
    self.NominalDiameter.setItemText(2, tr('ScrewMaker', 'M2.5'))
1813
    self.NominalDiameter.setItemText(3, tr('ScrewMaker', 'M3'))
1814
    self.NominalDiameter.setItemText(4, tr('ScrewMaker', '(M3.5)'))
1815
    self.NominalDiameter.setItemText(5, tr('ScrewMaker', 'M4'))
1816
    self.NominalDiameter.setItemText(6, tr('ScrewMaker', 'M5'))
1817
    self.NominalDiameter.setItemText(7, tr('ScrewMaker', 'M6'))
1818
    self.NominalDiameter.setItemText(8, tr('ScrewMaker', 'M8'))
1819
    self.NominalDiameter.setItemText(9, tr('ScrewMaker', 'M10'))
1820
    self.NominalDiameter.setItemText(10, tr('ScrewMaker', 'M12'))
1821
    self.NominalDiameter.setItemText(11, tr('ScrewMaker', '(M14)'))
1822
    self.NominalDiameter.setItemText(12, tr('ScrewMaker', 'M16'))
1823
    self.NominalDiameter.setItemText(13, tr('ScrewMaker', '(M18)'))
1824
    self.NominalDiameter.setItemText(14, tr('ScrewMaker', 'M20'))
1825
    self.NominalDiameter.setItemText(15, tr('ScrewMaker', '(M22)'))
1826
    self.NominalDiameter.setItemText(16, tr('ScrewMaker', 'M24'))
1827
    self.NominalDiameter.setItemText(17, tr('ScrewMaker', '(M27)'))
1828
    self.NominalDiameter.setItemText(18, tr('ScrewMaker', 'M30'))
1829
    self.NominalDiameter.setItemText(19, tr('ScrewMaker', 'M36'))
1830
    self.NominalDiameter.setItemText(20, tr('ScrewMaker', '(M33)'))
1831
    self.NominalDiameter.setItemText(21, tr('ScrewMaker', 'M42'))
1832
    self.NominalDiameter.setItemText(22, tr('ScrewMaker', '(M45)'))
1833
    self.NominalDiameter.setItemText(23, tr('ScrewMaker', 'M48'))
1834
    self.NominalDiameter.setItemText(24, tr('ScrewMaker', '(M52)'))
1835
    self.NominalDiameter.setItemText(25, tr('ScrewMaker', 'M54'))
1836
    self.NominalDiameter.setItemText(26, tr('ScrewMaker', '(M60)'))
1837
    self.NominalDiameter.setItemText(27, tr('ScrewMaker', 'M64'))
1838

1839
    self.NominalDiameter.setItemText(28, tr('ScrewMaker', 'M8x1'))
1840
    self.NominalDiameter.setItemText(29, tr('ScrewMaker', 'M10x1'))
1841
    self.NominalDiameter.setItemText(30, tr('ScrewMaker', '(M10x1.25)'))
1842
    self.NominalDiameter.setItemText(31, tr('ScrewMaker', 'M12x1.5'))
1843
    self.NominalDiameter.setItemText(32, tr('ScrewMaker', '(M12x1.25)'))
1844
    self.NominalDiameter.setItemText(33, tr('ScrewMaker', '(M14x1.5)'))
1845
    self.NominalDiameter.setItemText(34, tr('ScrewMaker', 'M16x1.5'))
1846
    self.NominalDiameter.setItemText(35, tr('ScrewMaker', '(M18x1.5)'))
1847
    self.NominalDiameter.setItemText(36, tr('ScrewMaker', 'M20x1.5'))
1848
    self.NominalDiameter.setItemText(37, tr('ScrewMaker', '(M20x2)'))
1849
    self.NominalDiameter.setItemText(38, tr('ScrewMaker', '(M22x1.5)'))
1850
    self.NominalDiameter.setItemText(39, tr('ScrewMaker', 'M24x2'))
1851
    self.NominalDiameter.setItemText(40, tr('ScrewMaker', '(M27x2)'))
1852
    self.NominalDiameter.setItemText(41, tr('ScrewMaker', 'M30x2'))
1853
    self.NominalDiameter.setItemText(42, tr('ScrewMaker', '(M33x2)'))
1854
    self.NominalDiameter.setItemText(43, tr('ScrewMaker', 'M36x3'))
1855
    self.NominalDiameter.setItemText(44, tr('ScrewMaker', '(M39x3)'))
1856
    self.NominalDiameter.setItemText(45, tr('ScrewMaker', 'M42x3'))
1857
    self.NominalDiameter.setItemText(46, tr('ScrewMaker', '(M45x3)'))
1858
    self.NominalDiameter.setItemText(47, tr('ScrewMaker', 'M48x3'))
1859
    self.NominalDiameter.setItemText(48, tr('ScrewMaker', '(M52x4)'))
1860
    self.NominalDiameter.setItemText(49, tr('ScrewMaker', 'M56x4'))
1861
    self.NominalDiameter.setItemText(50, tr('ScrewMaker', '(M60x4)'))
1862
    self.NominalDiameter.setItemText(51, tr('ScrewMaker', 'M64x4'))
1863

1864
    self.NominalLength.setItemText(0, tr('ScrewMaker', '2'))
1865
    self.NominalLength.setItemText(1, tr('ScrewMaker', '2.5'))
1866
    self.NominalLength.setItemText(2, tr('ScrewMaker', '3'))
1867
    self.NominalLength.setItemText(3, tr('ScrewMaker', '4'))
1868
    self.NominalLength.setItemText(4, tr('ScrewMaker', '5'))
1869
    self.NominalLength.setItemText(5, tr('ScrewMaker', '6'))
1870
    self.NominalLength.setItemText(6, tr('ScrewMaker', '8'))
1871
    self.NominalLength.setItemText(7, tr('ScrewMaker', '10'))
1872
    self.NominalLength.setItemText(8, tr('ScrewMaker', '12'))
1873
    self.NominalLength.setItemText(9, tr('ScrewMaker', '16'))
1874
    self.NominalLength.setItemText(10, tr('ScrewMaker', '20'))
1875
    self.NominalLength.setItemText(11, tr('ScrewMaker', '25'))
1876
    self.NominalLength.setItemText(12, tr('ScrewMaker', '30'))
1877
    self.NominalLength.setItemText(13, tr('ScrewMaker', '35'))
1878
    self.NominalLength.setItemText(14, tr('ScrewMaker', '40'))
1879
    self.NominalLength.setItemText(15, tr('ScrewMaker', '45'))
1880
    self.NominalLength.setItemText(16, tr('ScrewMaker', '50'))
1881
    self.NominalLength.setItemText(17, tr('ScrewMaker', '55'))
1882
    self.NominalLength.setItemText(18, tr('ScrewMaker', '60'))
1883
    self.NominalLength.setItemText(19, tr('ScrewMaker', '65'))
1884
    self.NominalLength.setItemText(20, tr('ScrewMaker', '70'))
1885
    self.NominalLength.setItemText(21, tr('ScrewMaker', '80'))
1886
    self.NominalLength.setItemText(22, tr('ScrewMaker', '90'))
1887
    self.NominalLength.setItemText(23, tr('ScrewMaker', '100'))
1888
    self.NominalLength.setItemText(24, tr('ScrewMaker', '110'))
1889
    self.NominalLength.setItemText(25, tr('ScrewMaker', '120'))
1890
    self.NominalLength.setItemText(26, tr('ScrewMaker', '130'))
1891
    self.NominalLength.setItemText(27, tr('ScrewMaker', '140'))
1892
    self.NominalLength.setItemText(28, tr('ScrewMaker', '150'))
1893
    self.NominalLength.setItemText(29, tr('ScrewMaker', '160'))
1894
    self.NominalLength.setItemText(30, tr('ScrewMaker', '180'))
1895
    self.NominalLength.setItemText(31, tr('ScrewMaker', '200'))
1896
    self.NominalLength.setItemText(32, tr('ScrewMaker', '220'))
1897
    self.NominalLength.setItemText(33, tr('ScrewMaker', '240'))
1898
    self.NominalLength.setItemText(34, tr('ScrewMaker', '260'))
1899
    self.NominalLength.setItemText(35, tr('ScrewMaker', '280'))
1900
    self.NominalLength.setItemText(36, tr('ScrewMaker', '300'))
1901
    self.NominalLength.setItemText(37, tr('ScrewMaker', '320'))
1902
    self.NominalLength.setItemText(38, tr('ScrewMaker', '340'))
1903
    self.NominalLength.setItemText(39, tr('ScrewMaker', '360'))
1904
    self.NominalLength.setItemText(40, tr('ScrewMaker', '380'))
1905
    self.NominalLength.setItemText(41, tr('ScrewMaker', '400'))
1906
    self.NominalLength.setItemText(42, tr('ScrewMaker', '420'))
1907
    self.NominalLength.setItemText(43, tr('ScrewMaker', '440'))
1908
    self.NominalLength.setItemText(44, tr('ScrewMaker', '460'))
1909
    self.NominalLength.setItemText(45, tr('ScrewMaker', '480'))
1910
    self.NominalLength.setItemText(46, tr('ScrewMaker', '500'))
1911
    self.NominalLength.setItemText(47, tr('ScrewMaker', 'User'))
1912
    #self.UserLen.setItemText(0, tr('ScrewMaker', 'regular pitch'))
1913
    self.SimpleScrew.setText(tr('ScrewMaker', 'Simple Screw (no thread at all!)'))
1914
    self.SymbolThread.setText(tr('ScrewMaker', 'Symbol Thread (not implemented yet)'))
1915
    self.RealThread.setText(tr('ScrewMaker', 'Real Thread (takes time, memory intensive)\nMay not work for all screws!'))
1916
    self.MessageLabel.setText(tr('ScrewMaker', 'Select your screw type'))
1917
    self.MessageLabel.setProperty('Errortext', tr('ScrewMaker', 'Combination not implemented'))
1918
    self.MessageLabel.setProperty('OK_text', tr('ScrewMaker', 'Screw is made'))
1919
    self.CreateButton.setText(tr('ScrewMaker', 'create'))
1920

1921
  def guiCheck_Data(self):
1922
    ST_text = str(self.ScrewType.currentText())
1923
    ST_text = ST_text.split(':')[0]
1924
    ND_text = str(self.NominalDiameter.currentText())
1925
    NL_text = str(self.NominalLength.currentText())
1926
    M_text, self.ScrewAvailable  = self.theScrew.check_Data(ST_text, ND_text, NL_text)
1927
    self.MessageLabel.setText(tr('ScrewMaker', M_text))
1928

1929
  def guiCreateScrew(self):
1930
    #self.simpThread = self.SimpleScrew.isChecked()
1931
    #self.symThread = self.SymbolThread.isChecked()
1932
    #self.rThread = self.RealThread.isChecked()
1933
    if self.SimpleScrew.isChecked():
1934
      threadType = 'simple'
1935
    if self.SymbolThread.isChecked():
1936
      threadType = 'symbol'
1937
    if self.RealThread.isChecked():
1938
      threadType = 'real'
1939

1940
    ND_text = str(self.NominalDiameter.currentText())
1941
    NL_text = str(self.NominalLength.currentText())
1942
    ST_text = str(self.ScrewType.currentText())
1943
    ST_text = ST_text.split(':')[0]
1944

1945
    if (ST_text == 'ScrewTap') or (ST_text == 'ISO8676'):
1946
      if NL_text == 'User':
1947
        textValue = self.UserLen.property("text")
1948
        stLength = FreeCAD.Units.parseQuantity(textValue).Value
1949
        NL_text = str(stLength)
1950

1951
    myObj = self.theScrew.createScrew(ST_text, ND_text, NL_text, threadType)
1952

1953

1954
def get_diameter(thread_type):
1955
  """Return the screw diameter as float
1956

1957
  Accepted input format are e.g. 'M5', 'M8x1', '(M3.5)', '(M10x1.25)'.
1958
  """
1959
  thread_string = thread_type.lstrip('(M').rstrip(')')
1960
  dia = float(thread_string.split('x')[0])
1961
  return dia
1962

1963

1964
class Screw(object):
1965
  def __init__(self):
1966
    self.objAvailable = True
1967
    self.Tuner = 510
1968
    testCirc=Part.makeCircle(2.0,Base.Vector(0.0,0.0,-0.0),Base.Vector(0.0,0.0,-1.0))
1969
    testDisk = Part.Face(Part.Wire(testCirc))
1970
    z = testDisk.Surface.Axis.z
1971
    if z > 0:
1972
      self.circleAxis = Base.Vector(0.0,0.0,1.0)
1973
    else:
1974
      self.circleAxis = Base.Vector(0.0,0.0,-1.0)
1975

1976
  def check_Data(self, ST_text, ND_text, NL_text):
1977
    #FreeCAD.Console.PrintMessage("Data checking" + NL_text + "\n")
1978
    #set screw not ok
1979
    self.objAvailable = False
1980
    M_text = "Select your screw type"
1981
    Type_text = ''
1982
    if ST_text == 'ISO4017':
1983
      table = iso4017head
1984
      tab_len = iso4017length
1985
      tab_range = iso4017range
1986
      Type_text = 'Screw'
1987

1988
    if ST_text == 'EN1662':
1989
      table = en1662def
1990
      tab_len = en1662length
1991
      tab_range = en1662range
1992
      Type_text = 'Screw'
1993

1994
    if ST_text == 'EN1665':
1995
      table = en1665def
1996
      tab_len = en1665length
1997
      tab_range = en1665range
1998
      Type_text = 'Screw'
1999

2000
    if ST_text == 'ISO8676':
2001
      table = iso8676def
2002
      tab_len = iso8676length
2003
      tab_range = iso8676range
2004
      Type_text = 'Screw'
2005

2006
    if ST_text == 'ISO2009':
2007
      table = iso2009def
2008
      tab_len = iso2009length
2009
      tab_range = iso2009range
2010
      Type_text = 'Screw'
2011
    if ST_text == 'ISO2010':
2012
      table = iso2009def
2013
      tab_len = iso2009length
2014
      tab_range = iso2009range
2015
      Type_text = 'Screw'
2016
    if ST_text == 'ISO4762':
2017
      table = iso4762def
2018
      tab_len = iso4762length
2019
      tab_range = iso4762range
2020
      Type_text = 'Screw'
2021

2022
    if ST_text == 'ISO10642':
2023
      table = iso10642def
2024
      tab_len = iso10642length
2025
      tab_range = iso10642range
2026
      Type_text = 'Screw'
2027

2028
    if ST_text == 'ISO4014':
2029
      table = iso4014head
2030
      tab_len = iso4014length
2031
      tab_range = iso4014range
2032
      Type_text = 'Screw'
2033

2034
    if ST_text == 'ISO1207':
2035
      table = iso1207def
2036
      tab_len = iso1207length
2037
      tab_range = iso1207range
2038
      Type_text = 'Screw'
2039
    if ST_text == 'ISO1580':
2040
      table = iso1580def
2041
      tab_len = iso2009length
2042
      tab_range = iso2009range
2043
      Type_text = 'Screw'
2044

2045
    if ST_text == 'ISO7045':
2046
      table = iso7045def
2047
      tab_len = iso7045length
2048
      tab_range = iso7045range
2049
      Type_text = 'Screw'
2050

2051
    if ST_text == 'ISO7046':
2052
      table = iso7046def  # contains only cross recess data
2053
      tab_len = iso7045length
2054
      tab_range = iso7046range
2055
      Type_text = 'Screw'
2056

2057
    if ST_text == 'ISO7047':
2058
      table = iso2009def
2059
      tab_len = iso7045length
2060
      tab_range = iso7046range
2061
      Type_text = 'Screw'
2062

2063
    if ST_text == 'ISO7048':
2064
      table = iso7048def
2065
      tab_len = iso7048length
2066
      tab_range = iso7048range
2067
      Type_text = 'Screw'
2068

2069
    if ST_text == 'ISO7380-1':
2070
      table = iso7380def
2071
      tab_len = iso7380length
2072
      tab_range = iso7380range
2073
      Type_text = 'Screw'
2074

2075
    if ST_text == 'ISO7380-2':
2076
      table = iso7380_2def
2077
      tab_len = iso7380length
2078
      tab_range = iso7380range
2079
      Type_text = 'Screw'
2080

2081
    if ST_text == 'DIN967':
2082
      table = din967def
2083
      tab_len = din967length
2084
      tab_range = din967range
2085
      Type_text = 'Screw'
2086

2087
    if ST_text == 'ISO14579':
2088
      table = iso14579def
2089
      tab_len = iso14579length
2090
      tab_range = iso14579range
2091
      Type_text = 'Screw'
2092

2093
    if ST_text == 'ISO14580':
2094
      table = iso14580def
2095
      tab_len = iso14580length
2096
      tab_range = iso1207range
2097
      Type_text = 'Screw'
2098

2099
    if ST_text == 'ISO14583':
2100
      table = iso14583def
2101
      tab_len = iso7045length
2102
      tab_range = iso7046range
2103
      Type_text = 'Screw'
2104

2105
    if ST_text == 'ISO14584':
2106
      table = iso14584def
2107
      tab_len = iso7045length
2108
      tab_range = iso14584range
2109
      Type_text = 'Screw'
2110

2111
    if ST_text == 'ISO14582':
2112
      table = iso14582def
2113
      tab_len = iso14582length
2114
      tab_range = iso14582range
2115
      Type_text = 'Screw'
2116

2117
    if ST_text == 'ISO7089':
2118
      table = iso7089def
2119
      Type_text = 'Washer'
2120

2121
    if ST_text == 'ISO7090':
2122
      table = iso7090def
2123
      Type_text = 'Washer'
2124

2125
    if ST_text == 'ISO7091':
2126
      table = iso7091def
2127
      Type_text = 'Washer'
2128

2129
    if ST_text == 'ISO7092':
2130
      table = iso7092def
2131
      Type_text = 'Washer'
2132

2133
    if ST_text == 'ISO7093-1':
2134
      table = iso7093def
2135
      Type_text = 'Washer'
2136

2137
    if ST_text == 'ISO7094':
2138
      table = iso7094def
2139
      Type_text = 'Washer'
2140

2141
    if ST_text == 'ISO4032':
2142
      table = iso4032def
2143
      Type_text = 'Nut'
2144

2145
    if ST_text == 'ISO4033':
2146
      table = iso4033def
2147
      Type_text = 'Nut'
2148

2149
    if ST_text == 'ISO4035':
2150
      table = iso4035def
2151
      Type_text = 'Nut'
2152

2153
    if ST_text == 'ISO4036':
2154
      table = iso4036def
2155
      Type_text = 'Nut'
2156

2157
    if ST_text == 'EN1661':
2158
      table = en1661def
2159
      Type_text = 'Nut'
2160

2161
    if ST_text == 'ScrewTap':
2162
      table = tuningTable
2163
      Type_text = 'Screw-Tap'
2164

2165
    if ND_text not in table:
2166
       ND_min, ND_max = standard_diameters[ST_text]
2167
       M_text = ST_text+' has diameters from '+ ND_min +' to ' + ND_max + ' and not ' + ND_text +'!'
2168
       self.objAvailable = False
2169
       # set scew not ok
2170
    else:
2171
      if Type_text == 'Screw':
2172
        #NL_text = str(self.NominalLength.currentText())
2173
        NL_min, NL_max = tab_range[ND_text]
2174
        NL_min_float = float(NL_min)
2175
        NL_max_float = float(NL_max)
2176
        if (NL_text == 'User') and (ST_text != 'ISO8676'):
2177
          M_text = 'User length is only available for the screw-tab and ISO 8676!'
2178
          self.objAvailable = False
2179
        else:
2180
          if NL_text == 'User':
2181
            M_text = 'ISO 8676 with user length is ok!'
2182
            self.objAvailable = True
2183
          else:
2184
            NL_text_float = float(NL_text)
2185
            if (NL_text_float<NL_min_float)or(NL_text_float>NL_max_float)or(NL_text not in tab_len):
2186
              if '(' in ND_text:
2187
                ND_text = ND_text.lstrip('(').rstrip(')')
2188
              M_text = ST_text+'-'+ ND_text +' has lengths from '+ NL_min +' to ' + NL_max + ' and not ' + NL_text +'!'
2189
              self.objAvailable = False
2190
              # set screw not ok
2191
            else:
2192
              if '(' in ND_text:
2193
                ND_text = ND_text.lstrip('(').rstrip(')')
2194
              M_text = ST_text+'-'+ ND_text +'x'+ NL_text +' is in library available! '
2195
              self.objAvailable = True
2196
              #set screw ok
2197
      else: # Washers and Nuts
2198
        if Type_text != 'Screw-Tap':
2199
          if '(' in ND_text:
2200
            ND_text = ND_text.lstrip('(').rstrip(')')
2201
          M_text = ST_text+'-'+ ND_text +' is available in library!'
2202
          self.objAvailable = True
2203
          #set washer/nut ok
2204
        else:
2205
          if NL_text == 'User':
2206
            M_text = 'Screw-tab with user length is ok!'
2207
            self.objAvailable = True
2208
          else:
2209
            #NL_text = str(self.NominalLength.currentText())
2210
            if '(' in ND_text:
2211
              ND_text = ND_text.lstrip('(').rstrip(')')
2212
            M_text = ST_text+'-'+ ND_text +' with '+ NL_text +'mm length is available in library!'
2213
            self.objAvailable = True
2214
            #set screwTap ok
2215

2216
    #print "Data checking: ", self.NominalLength.currentText(), "\n"
2217
    #FreeCAD.Console.PrintMessage("Set Check_result into text " + str(self.objAvailable) + M_text + "\n")
2218
    return M_text, self.objAvailable
2219

2220

2221
  def createScrew(self, ST_text, ND_text, NL_text, threadType):
2222
    #self.simpThread = self.SimpleScrew.isChecked()
2223
    #self.symThread = self.SymbolThread.isChecked()
2224
    #self.rThread = self.RealThread.isChecked()
2225
    if threadType == 'real':
2226
      self.rThread = True
2227
    else:
2228
      self.rThread = False
2229

2230
    if self.objAvailable:
2231
      try:
2232
        # first we check if valid numbers have been entered
2233
        #FreeCAD.Console.PrintMessage("NominalLength: " + self.NominalLength.currentText() + "\n")
2234
        #FreeCAD.Console.PrintMessage("NominalDiameter: " + self.NominalDiameter.currentText() + "\n")
2235
        #FreeCAD.Console.PrintMessage("SimpleThread: " + str(self.SimpleScrew.isChecked()) + "\n")
2236
        #FreeCAD.Console.PrintMessage("SymbolThread: " + str(self.SymbolThread.isChecked()) + "\n")
2237
        #FreeCAD.Console.PrintMessage("RealThread: " + str(self.RealThread.isChecked()) + "\n")
2238

2239
        #ND_text = str(self.NominalDiameter.currentText())
2240
        #NL_text = str(self.NominalLength.currentText())
2241
        #ST_text = str(self.ScrewType.currentText())
2242
        #ST_text = ST_text.split(':')[0]
2243
        #dia = float(ND_text.lstrip('M'))
2244
        l = float(NL_text)
2245
        if ST_text == 'ISO4017':
2246
           table = iso4017head
2247
        if ST_text == 'ISO4014':
2248
           table = iso4014head
2249
        if ST_text == 'EN1662':
2250
           table = en1662def
2251
        if ST_text == 'EN1665':
2252
           table = en1665def
2253
        if ST_text == 'ISO8676':
2254
           table = iso8676def
2255
        if ST_text == 'ISO2009':
2256
           table = iso2009def
2257
        if ST_text == 'ISO2010':
2258
           table = iso2009def
2259
        if ST_text == 'ISO4762':
2260
           table = iso4762def
2261
        if ST_text == 'ISO10642':
2262
           table = iso10642def
2263
        if ST_text == 'ISO1207':
2264
           table = iso1207def
2265
        if ST_text == 'ISO1580':
2266
           table = iso1580def
2267
        if ST_text == 'ISO7045':
2268
           table = iso7045def
2269
        if ST_text == 'ISO7046':
2270
           table = iso7045def
2271
        if ST_text == 'ISO7047':
2272
           table = iso7045def
2273
        if ST_text == 'ISO7048':
2274
           table = iso7048def
2275
        if ST_text == 'ISO7380-1':
2276
           table = iso7380def
2277
        if ST_text == 'ISO7380-2':
2278
           table = iso7380_2def
2279
        if ST_text == 'DIN967':
2280
           table = din967def
2281
        if ST_text == 'ISO14579':
2282
           table = iso14579def
2283
        if ST_text == 'ISO14580':
2284
           table = iso14580def
2285
        if ST_text == 'ISO14582':
2286
           table = iso14582def
2287
        if ST_text == 'ISO14583':
2288
           table = iso14583def
2289
        if ST_text == 'ISO14584':
2290
           table = iso14584def
2291
        if ST_text == 'ISO7089':
2292
           table = iso7089def
2293
        if ST_text == 'ISO7090':
2294
           table = iso7090def
2295
        if ST_text == 'ISO7091':
2296
           table = iso7091def
2297
        if ST_text == 'ISO7092':
2298
           table = iso7092def
2299
        if ST_text == 'ISO7093-1':
2300
           table = iso7093def
2301
        if ST_text == 'ISO7094':
2302
           table = iso7094def
2303
        if ST_text == 'ISO4032':
2304
           table = iso4032def
2305
        if ST_text == 'ISO4033':
2306
           table = iso4033def
2307
        if ST_text == 'ISO4035':
2308
           table = iso4035def
2309
        if ST_text == 'ISO4036':
2310
           table = iso4036def
2311
        if ST_text == 'EN1661':
2312
           table = en1661def
2313
        if ST_text == 'ScrewTap':
2314
           table = tuningTable
2315
        if ND_text not in table:
2316
           FreeCAD.Console.PrintMessage("Combination of type "+ST_text \
2317
              + " and diameter " + ND_text +" not available!" + "\n")
2318
        #self.MessageLabel.setText(tr('ScrewMaker', 'not implemented'))
2319

2320
      except ValueError:
2321
        #print "Error! nom_dia and length values must be valid numbers!"
2322
        FreeCAD.Console.PrintMessage("Error! nom_dia and length values must be valid numbers!\n")
2323
      else:
2324
        doc=FreeCAD.activeDocument()
2325
        done = False
2326
        if (ST_text == 'ISO4014') or (ST_text == 'ISO4017') or (ST_text == 'ISO8676'):
2327
          screw = self.makeIso4017_2(ST_text, ND_text,l)
2328
          Type_text = 'Screw'
2329
          done = True
2330
        if (ST_text == 'EN1662') or (ST_text == 'EN1665'):
2331
          screw = self.makeEN1662_2(ST_text, ND_text,l)
2332
          Type_text = 'Screw'
2333
          done = True
2334
        if (ST_text == 'ISO2009') or (ST_text == 'ISO2010') or (ST_text == 'ISO1580'):
2335
          screw = self.makeSlottedScrew(ST_text, ND_text,l)
2336
          Type_text = 'Screw'
2337
          done = True
2338
        if (ST_text == 'ISO4762') or (ST_text == 'ISO14579'):
2339
          screw = self.makeIso4762(ST_text, ND_text,l)
2340
          Type_text = 'Screw'
2341
          done = True
2342
        if (ST_text == 'ISO1207') or (ST_text == 'ISO14580') or (ST_text == 'ISO7048'):
2343
          screw = self.makeIso1207(ST_text, ND_text,l)
2344
          Type_text = 'Screw'
2345
          done = True
2346
        if (ST_text == 'ISO7045') or (ST_text == 'ISO14583'):
2347
          screw = self.makeIso7045(ST_text, ND_text,l)
2348
          Type_text = 'Screw'
2349
          done = True
2350
        if (ST_text == 'ISO7046') or (ST_text == 'ISO7047') or \
2351
          (ST_text == 'ISO14582') or (ST_text == 'ISO14584') or (ST_text == 'ISO10642'):
2352
          screw = self.makeIso7046(ST_text, ND_text,l)
2353
          Type_text = 'Screw'
2354
          done = True
2355
        if (ST_text == 'ISO7380-1') or (ST_text == 'ISO7380-2') or (ST_text == 'DIN967'):
2356
          screw = self.makeIso7380(ST_text, ND_text,l)
2357
          Type_text = 'Screw'
2358
          done = True
2359
        if (ST_text == 'ISO7089') or (ST_text == 'ISO7090') or (ST_text == 'ISO7093-1') or \
2360
          (ST_text == 'ISO7091') or (ST_text == 'ISO7092') or (ST_text == 'ISO7094'):
2361
          screw = self.makeIso7089(ST_text, ND_text)
2362
          Type_text = 'Washer'
2363
          done = True
2364
        if (ST_text == 'ISO4032') or (ST_text == 'ISO4033') or (ST_text == 'ISO4035'):
2365
          screw = self.makeIso4032(ST_text, ND_text)
2366
          Type_text = 'Nut'
2367
          done = True
2368
        if ST_text == 'EN1661':
2369
          screw = self.makeEN1661(ND_text)
2370
          Type_text = 'Nut'
2371
          done = True
2372
        if ST_text == 'ScrewTap':
2373
          screw = self.makeScrewTap(ND_text,l)
2374
          Type_text = 'Screw-Tap'
2375
          done = True
2376
        if not done:
2377
          FreeCAD.Console.PrintMessage("No valid Screw Type!" +  "\n")
2378
        if '(' in ND_text:
2379
          ND_text = ND_text.lstrip('(').rstrip(')')
2380

2381
        if Type_text == 'Screw':
2382
          label = ST_text + "-" + ND_text +"x"+ NL_text +"_"
2383
        else:
2384
          if (Type_text == 'Nut'):
2385
            label = ST_text + '-' + ND_text +'_'
2386
          else:
2387
            if Type_text == 'Screw-Tap':
2388
              label = ST_text + '-' + ND_text +'x'+ NL_text +'_'
2389
            else: # washer
2390
              label = ST_text + '-' + ND_text.lstrip('M') +'_'
2391
        ScrewObj = doc.addObject("Part::Feature")
2392
        ScrewObj.Label=label
2393
        ScrewObj.Shape=screw
2394
        #FreeCAD.Console.PrintMessage("Placement: "+ str(ScrewObj.Placement) +"\n")
2395
        #FreeCAD.Console.PrintMessage("The label: "+ label +"\n")
2396
        self.moveScrew(ScrewObj)
2397
        #ScrewObj.Label = label
2398
        if self.gotPart:
2399
          self.thePart.addObject(ScrewObj)
2400
        doc.recompute()
2401
        # Part.show(screw)
2402
        return ScrewObj
2403

2404
  def getFaceAxis(self, sp, c):
2405
    fList = []
2406
    fAxis = None
2407
    if len(c.Vertexes) ==1:
2408
      theVert = c.Vertexes[0]
2409
      # search for faces which have a vertex equal to theVert.
2410
      for f in sp.Faces:
2411
        for v in f.Vertexes:
2412
          if equal_vertex(v, theVert):
2413
            fList.append(f)
2414
    print (str(fList))
2415
    # search for a plane face
2416
    for f in fList:
2417
      if hasattr(f,'Surface'):
2418
        FreeCAD.Console.PrintMessage('type of surface: ', str(f.Surface))
2419
        if f.Surface.isPlanar():
2420
          fAxis = f.Surface.normal(0,0)
2421
          print ('got planar Face with normal: ', str(f.Surface.normal(0,0)))
2422
          print ('Orientation: ', str(f.Orientation))
2423
          if f.Orientation == 'Reversed':
2424
            fAxis = fAxis.multiply(-1.0)
2425
    return fAxis
2426

2427
  def moveScrew(self, ScrewObj_m):
2428
    #FreeCAD.Console.PrintMessage("In Move Screw: " + str(ScrewObj_m) + "\n")
2429
    self.gotBody = False
2430
    self.gotPart = False
2431

2432
    mylist = FreeCAD.Gui.Selection.getSelectionEx()
2433
    if (mylist.__len__() == 1):
2434
       # check selection
2435
       #FreeCAD.Console.PrintMessage("Selektionen: " + str(mylist.__len__()) + "\n")
2436
       Pnt1 = None
2437
       Axis1 = None
2438
       Axis2 = None
2439
       theSelection = mylist[0]
2440
       #FreeCAD.Console.PrintMessage( "ObjectName: " + str(theSelection.ObjectName) + "\n")
2441
       if hasattr(theSelection, 'Object'):
2442
         if hasattr(theSelection.Object, 'InList'):
2443
           inLength = len(theSelection.Object.InList)
2444
           #FreeCAD.Console.PrintMessage( "InList: " + str(theSelection.Object.InList) + "\n")
2445
           for b in theSelection.Object.InList:
2446
             #FreeCAD.Console.PrintMessage( "OType: " + str(b.TypeId) + "\n")
2447
             if b.TypeId == 'PartDesign::Body':
2448
               self.gotBody = True
2449
               self.bPlacement = b.Placement
2450
               for par in b.InList:
2451
                 if par.TypeId == 'App::Part':
2452
                   self.gotPart = True
2453
                   self.thePart = par
2454

2455
                   break
2456

2457
       for o in FreeCADGui.Selection.getSelectionEx():
2458
          #FreeCAD.Console.PrintMessage( "name: " + str(o) + "\n")
2459
          #FreeCAD.Console.PrintMessage( "Properties: " + str(o.PropertiesList) + "\n")
2460

2461
          #for s in o.SubElementNames:
2462
             #FreeCAD.Console.PrintMessage( "name: " + str(s) + "\n")
2463
          for s in o.SubObjects:
2464
             #FreeCAD.Console.PrintMessage( "object: "+ str(s) + "\n")
2465
             #FreeCAD.Console.PrintMessage( "Properties: " + str(s.PropertiesList) + "\n")
2466
             if hasattr(s,"Curve"):
2467
                #FreeCAD.Console.PrintMessage( "The Object is a Curve!\n")
2468
                if hasattr(s.Curve,"Center"):
2469
                   """
2470
                   FreeCAD.Console.PrintMessage( "The object has a Center!\n")
2471
                   FreeCAD.Console.PrintMessage( "Curve attribute. "+ str(s.__getattribute__('Curve')) + "\n")
2472
                   FreeCAD.Console.PrintMessage( "Center: "+ str(s.Curve.Center) + "\n")
2473
                   FreeCAD.Console.PrintMessage( "Axis: "+ str(s.Curve.Axis) + "\n")
2474
                   """
2475
                   Pnt1 = s.Curve.Center
2476
                   Axis1 = s.Curve.Axis
2477
                   fAxis = self.getFaceAxis(o.Object.Shape, s)
2478
                   if fAxis:
2479
                     Axis1 = fAxis
2480
             if hasattr(s,'Surface'):
2481
                #print 'the object is a face!'
2482
                if hasattr(s.Surface,'Axis'):
2483
                   Axis1 = s.Surface.Axis
2484

2485
             if hasattr(s,'Point'):
2486
                #FreeCAD.Console.PrintMessage( "the object seems to be a vertex! "+ str(s.Point) + "\n")
2487
                Pnt1 = s.Point
2488

2489
       if (Axis1 != None):
2490
          #FreeCAD.Console.PrintMessage( "Got Axis1: " + str(Axis1) + "\n")
2491
          Axis2 = Base.Vector(0.0,0.0,1.0)
2492
          Axis2_minus = Base.Vector(0.0,0.0,-1.0)
2493

2494
          # Calculate angle
2495
          if Axis1 == Axis2:
2496
             normvec = Base.Vector(1.0,0.0,0.0)
2497
             result = 0.0
2498
          else:
2499
             if Axis1 == Axis2_minus:
2500
                normvec = Base.Vector(1.0,0.0,0.0)
2501
                result = math.pi
2502
             else:
2503
                normvec = Axis1.cross(Axis2) # Berechne Achse der Drehung = normvec
2504
                normvec.normalize() # Normalisieren fuer Quaternionenrechnung
2505
                #normvec_rot = normvec
2506
                result = DraftVecUtils.angle(Axis1, Axis2, normvec) # Winkelberechnung
2507
          sin_res = math.sin(result/2.0)
2508
          cos_res = math.cos(result/2.0)
2509
          normvec.multiply(-sin_res) # Berechnung der Quaternionen-Elemente
2510
          #FreeCAD.Console.PrintMessage( "Winkel = "+ str(math.degrees(result)) + "\n")
2511
          #FreeCAD.Console.PrintMessage("Normalvektor: "+ str(normvec) + "\n")
2512

2513
          pl = FreeCAD.Placement()
2514
          pl.Rotation = (normvec.x,normvec.y,normvec.z,cos_res) #Drehungs-Quaternion
2515

2516
          #FreeCAD.Console.PrintMessage("pl mit Rot: "+ str(pl) + "\n")
2517
          #neuPlatz = Part2.Object.Placement.multiply(pl)
2518
          neuPlatz = ScrewObj_m.Placement
2519
          FreeCAD.Console.PrintMessage("The Position     "+ str(neuPlatz) + "\n")
2520
          neuPlatz.Rotation = pl.Rotation.multiply(ScrewObj_m.Placement.Rotation)
2521
          # neuPlatz.move(Pnt1)
2522
          FreeCAD.Console.PrintMessage("The Position in Body    "+ str(neuPlatz) + "\n")
2523
          if self.gotBody:
2524
            FreeCAD.Console.PrintMessage("got Placement: "+ str(self.bPlacement) + "\n")
2525
            #neuPlatz.Rotation = neuPlatz.Rotation.multiply(self.bPlacement.Rotation)
2526
            neuPlatz.Rotation = neuPlatz.Rotation.multiply(self.bPlacement.Rotation)
2527
            Pnt1 = self.bPlacement.multVec(Pnt1)
2528
          neuPlatz.move(Pnt1)
2529
          #if self.gotBody:
2530
            #neuPlatz.move(self.bPlacement.Base)
2531

2532
          # Python is not phytonic in FreeCAD 0.17, need to add allocation.
2533
          ScrewObj_m.Placement = neuPlatz
2534
          #FreeCAD.Console.PrintMessage("die rot. Position: "+ str(neuPlatz) + "\n")
2535

2536

2537

2538
  # make Washer
2539
  def makeIso7089(self,SType ='ISO7089', ThreadType ='M6'):
2540
    dia = get_diameter(ThreadType)
2541
    #FreeCAD.Console.PrintMessage("die Scheibe mit dia: " + str(dia) + "\n")
2542
    if SType == 'ISO7089':
2543
      d1_min, d2_max, h, h_max = iso7089def[ThreadType]
2544
    if SType == 'ISO7090':
2545
      d1_min, d2_max, h, h_max = iso7090def[ThreadType]
2546
    if SType == 'ISO7091':
2547
      d1_min, d2_max, h, h_max = iso7091def[ThreadType]
2548
    if SType == 'ISO7092':
2549
      d1_min, d2_max, h, h_max = iso7092def[ThreadType]
2550
    if SType == 'ISO7093-1':
2551
      d1_min, d2_max, h, h_max = iso7093def[ThreadType]
2552
    if SType == 'ISO7094':
2553
      d1_min, d2_max, h, h_max = iso7094def[ThreadType]
2554
      #FreeCAD.Console.PrintMessage("got: " + SType + "\n")
2555

2556
    #FreeCAD.Console.PrintMessage("die Scheibe mit d1_min: " + str(d1_min) + "\n")
2557

2558
    #Washer Points
2559
    Pnt0 = Base.Vector(d1_min/2.0,0.0,h_max)
2560
    Pnt2 = Base.Vector(d2_max/2.0,0.0,h_max)
2561
    Pnt3 = Base.Vector(d2_max/2.0,0.0,0.0)
2562
    Pnt4 = Base.Vector(d1_min/2.0,0.0,0.0)
2563
    if SType == 'ISO7090':
2564
      Pnt1 = Base.Vector(d2_max/2.0-h_max/4.0,0.0,h_max)
2565
      Pnt2 = Base.Vector(d2_max/2.0,0.0,h_max*0.75)
2566
      edge1 = Part.makeLine(Pnt0,Pnt1)
2567
      edgeCham = Part.makeLine(Pnt1,Pnt2)
2568
      edge1 = Part.Wire([edge1, edgeCham])
2569
    else:
2570
      edge1 = Part.makeLine(Pnt0,Pnt2)
2571

2572
    edge2 = Part.makeLine(Pnt2,Pnt3)
2573
    edge3 = Part.makeLine(Pnt3,Pnt4)
2574
    edge4 = Part.makeLine(Pnt4,Pnt0)
2575
    #FreeCAD.Console.PrintMessage("Edges made Pnt2: " + str(Pnt2) + "\n")
2576

2577
    aWire=Part.Wire([edge1,edge2,edge3,edge4])
2578
    #Part.show(aWire)
2579
    aFace =Part.Face(aWire)
2580
    head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
2581
    #FreeCAD.Console.PrintMessage("Washer revolved: " + str(dia) + "\n")
2582

2583
    return head
2584

2585

2586
  # make ISO 2009 Slotted countersunk flat head screws
2587
  # make ISO 2010 Slotted raised countersunk head screws
2588
  # make ISO 1580 Pan head slotted screw (Code is nearly identical to iso1207)
2589
  def makeSlottedScrew(self,SType ='ISO1580', ThreadType ='M6',l=25.0):
2590
    dia = get_diameter(ThreadType)
2591
    if SType == 'ISO1580':
2592
      #FreeCAD.Console.PrintMessage("der Kopf mit l: " + str(l) + "\n")
2593
      #P, a, b, dk, dk_mean, da, k, n_min, r, t_min, x = iso1580def[ThreadType]
2594
      P, a, b, dk_max, da, k, n_min, r, rf, t_min, x = iso1580def[ThreadType]
2595
      #FreeCAD.Console.PrintMessage("der Kopf mit iso: " + str(dk_max) + "\n")
2596
      ht = k
2597
      headEnd = r
2598

2599
      #Length for calculation of head fillet
2600
      sqrt2_ = 1.0/math.sqrt(2.0)
2601
      r_fil = rf
2602
      beta = math.radians(5.0)   # angle of pan head edge
2603
      alpha = math.radians(90.0 - (90.0+5.0)/2.0)
2604
      tan_beta = math.tan(beta)
2605
      # top head diameter without fillet
2606
      rK_top = dk_max/2.0 - k * tan_beta
2607
      fillet_center_x = rK_top - r_fil + r_fil * tan_beta
2608
      fillet_center_z = k - r_fil
2609
      fillet_arc_x = fillet_center_x + r_fil * math.sin(alpha)
2610
      fillet_arc_z = fillet_center_z + r_fil * math.cos(alpha)
2611
      #FreeCAD.Console.PrintMessage("rK_top: " + str(rK_top) + "\n")
2612
      if (b > (l - 1.0*P)):
2613
        bmax = l- 1.0*P
2614
      else:
2615
        bmax = b
2616

2617
      #Head Points
2618
      Pnt0 = Base.Vector(0.0,0.0,k)
2619
      Pnt2 = Base.Vector(fillet_center_x,0.0,k)
2620
      Pnt3 = Base.Vector(fillet_arc_x,0.0,fillet_arc_z)
2621
      Pnt4 = Base.Vector(fillet_center_x + r_fil*math.cos(beta),0.0,fillet_center_z+ r_fil * math.sin(beta))
2622
      Pnt5 = Base.Vector(dk_max/2.0,0.0,0.0)
2623
      Pnt6 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
2624
      Pnt7 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
2625
      #Pnt8 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
2626
      PntR = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
2627
      PntT0 = Base.Vector(0.0,0.0,-r)        # helper point for real thread
2628

2629
      edge1 = Part.makeLine(Pnt0,Pnt2)
2630
      edge2 = Part.Arc(Pnt2,Pnt3,Pnt4).toShape()
2631
      edge3 = Part.makeLine(Pnt4,Pnt5)
2632
      edge4 = Part.makeLine(Pnt5,Pnt6)
2633
      edge5 = Part.Arc(Pnt6,Pnt7,PntR).toShape()
2634
      headWire=Part.Wire([edge1,edge2,edge3,edge4,edge5])
2635

2636
    if (SType == 'ISO2009') or (SType == 'ISO2010'):
2637
      P, a, b, dk_theo, dk_mean, k, n_min, r, t_mean, x = iso2009def[ThreadType]
2638
      dk_max = dk_theo
2639
      t_min = t_mean
2640
      ht = 0.0 # Head height of flat head
2641
      if (SType == 'ISO2010'):
2642
        rf, t_mean, cT, mH, mZ = Raised_countersunk_def[ThreadType]
2643
        #Lengths and angles for calculation of head rounding
2644
        beta = math.asin(dk_mean /2.0 / rf)   # angle of head edge
2645
        tan_beta = math.tan(beta)
2646
        alpha = beta/2.0 # half angle
2647
        # height of raised head top
2648
        ht = rf - (dk_mean/2.0) / tan_beta
2649
        h_arc_x = rf * math.sin(alpha)
2650
        h_arc_z = ht - rf + rf * math.cos(alpha)
2651

2652
      cham = (dk_theo - dk_mean)/2.0
2653
      rad225 = math.radians(22.5)
2654
      rad45 = math.radians(45.0)
2655
      rtan = r*math.tan(rad225)
2656
      headEnd = k + rtan
2657

2658
      if (b > l - k - rtan/2.0 - 1.0*P):
2659
        bmax = l-k-rtan/2.0 - 1.0*P
2660
      else:
2661
        bmax = b
2662

2663
      #Head Points
2664
      Pnt0 = Base.Vector(0.0,0.0,ht)
2665
      Pnt1 = Base.Vector(dk_mean/2.0,0.0,0.0)
2666
      Pnt2 = Base.Vector(dk_mean/2.0,0.0,-cham)
2667
      Pnt3 = Base.Vector(dia/2.0+r-r*math.cos(rad45),0.0,-k-rtan+r*math.sin(rad45))
2668
      # Arc-points
2669
      Pnt4 = Base.Vector(dia/2.0+r-r*(math.cos(rad225)),0.0,-k-rtan+r*math.sin(rad225))
2670
      PntR = Base.Vector(dia/2.0,0.0,-k-rtan)
2671
      #PntA = Base.Vector(dia/2.0,0.0,-a_point)
2672
      PntT0 = Base.Vector(0.0,0.0,-k-rtan)        # helper point for real thread
2673

2674
      if (SType == 'ISO2010'): # make raised head rounding
2675
        Pnt0arc = Base.Vector(h_arc_x,0.0,h_arc_z)
2676
        edge1 = Part.Arc(Pnt0,Pnt0arc,Pnt1).toShape()
2677
      else:
2678
        edge1 = Part.makeLine(Pnt0,Pnt1)  # make flat head
2679

2680
      edge2 = Part.makeLine(Pnt1,Pnt2)
2681
      edge3 = Part.makeLine(Pnt2,Pnt3)
2682
      edgeArc = Part.Arc(Pnt3,Pnt4,PntR).toShape()
2683
      headWire=Part.Wire([edge1,edge2,edge3,edgeArc])
2684

2685

2686
    ### make the new code with math.modf(l)
2687
    residue, turns = math.modf((bmax)/P)
2688
    halfturns = 2*int(turns)
2689
    if residue < 0.5:
2690
      a_point = l - (turns+1.0) * P
2691
      halfturns = halfturns +1
2692
    else:
2693
      halfturns = halfturns + 2
2694
      a_point = l - (turns+2.0) * P
2695
    #halfturns = halfturns + 2
2696
    offSet = headEnd - a_point
2697
    PntA = Base.Vector(dia/2.0,0.0,-a_point)        # Start of thread
2698

2699

2700
    if self.rThread:
2701
      edgeZ1 = Part.makeLine(PntR,PntT0)
2702
      edgeZ0 = Part.makeLine(PntT0,Pnt0)
2703
      aWire=Part.Wire([headWire, edgeZ1, edgeZ0])
2704

2705
    else:
2706
      # bolt points
2707
      PntB1 = Base.Vector(dia/2.0,0.0,-l)
2708
      PntB2 = Base.Vector(0.0,0.0,-l)
2709

2710
      edgeB2 = Part.makeLine(PntB1,PntB2)
2711
      edgeZ0 = Part.makeLine(PntB2,Pnt0)
2712

2713
      if a_point <= r:
2714
        edgeB1 = Part.makeLine(PntR,PntB1)
2715
        aWire=Part.Wire([headWire, edgeB1, edgeB2, edgeZ0])
2716
      else:
2717
        edgeRA = Part.makeLine(PntR,PntA)
2718
        edgeB1 = Part.makeLine(PntA,PntB1)
2719
        aWire=Part.Wire([headWire, edgeRA, edgeB1, edgeB2, edgeZ0])
2720

2721
    aFace =Part.Face(aWire)
2722
    head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
2723
    #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
2724

2725
    #Parameter for slot-recess: dk_max, n_min, k, t_min
2726
    slot = Part.makePlane(dk_max, n_min, \
2727
        Base.Vector(dk_max/2.0,-n_min/2.0,ht+1.0),Base.Vector(0.0,0.0,-1.0))
2728
    slot = slot.extrude(Base.Vector(0.0,0.0,-t_min-1.0))
2729
    #Part.show(slot)
2730
    head = head.cut(slot)
2731
    #FreeCAD.Console.PrintMessage("der Kopf geschnitten: " + str(dia) + "\n")
2732
    #Part.show(head)
2733

2734
    if self.rThread:
2735
      rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
2736
      rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
2737
      #Part.show(rthread)
2738
      headFaces = []
2739
      if (SType == 'ISO2009'):
2740
        for i in range(0,len(head.Faces)-2):
2741
          headFaces.append(head.Faces[i])
2742
        headFaces.append(head.Faces[len(head.Faces)-1])
2743

2744
      if (SType == 'ISO1580') or (SType == 'ISO2010'):
2745
        for i in range(0,len(head.Faces)-1):
2746
          headFaces.append(head.Faces[i])
2747

2748
      for threadFace in rthread.Faces:
2749
        headFaces.append(threadFace)
2750

2751
      newHeadShell = Part.Shell(headFaces)
2752
      #Part.show(newHeadShell)
2753
      head = Part.Solid(newHeadShell)
2754

2755
    return head
2756

2757

2758

2759

2760

2761

2762
  # ISO 7045 Pan head screws with type H or type Z cross recess
2763
  # ISO 14583 Hexalobular socket pan head screws
2764
  def makeIso7045(self, SType ='ISO7045', ThreadType ='M6',l=25.0):
2765
    dia = get_diameter(ThreadType)
2766
    #FreeCAD.Console.PrintMessage("der Kopf mit l: " + str(l) + "\n")
2767
    P, a, b, dk_max,da, k, r, rf, x, cT, mH, mZ  = iso7045def[ThreadType]
2768
    #FreeCAD.Console.PrintMessage("der Kopf mit iso: " + str(dk_max) + "\n")
2769

2770
    #Lengths and angles for calculation of head rounding
2771
    beta = math.asin(dk_max /2.0 / rf)   # angle of head edge
2772
    #print 'beta: ', math.degrees(beta)
2773
    tan_beta = math.tan(beta)
2774

2775

2776
    if SType == 'ISO14583':
2777
       tt, A, t_mean = iso14583def[ThreadType]
2778
       beta_A = math.asin(A/2.0 / rf)   # angle of recess edge
2779
       tan_beta_A = math.tan(beta_A)
2780

2781
       alpha = (beta_A + beta)/2.0 # half angle
2782
       #print 'alpha: ', math.degrees(alpha)
2783
       # height of head edge
2784
       he = k - A/2.0/tan_beta_A + (dk_max/2.0) / tan_beta
2785
       #print 'he: ', he
2786
       h_arc_x = rf * math.sin(alpha)
2787
       h_arc_z = k - A/2.0/tan_beta_A + rf * math.cos(alpha)
2788
       #FreeCAD.Console.PrintMessage("h_arc_z: " + str(h_arc_z) + "\n")
2789
    else:
2790
       alpha = beta/2.0 # half angle
2791
       #print 'alpha: ', math.degrees(alpha)
2792
       # height of head edge
2793
       he = k - rf + (dk_max/2.0) / tan_beta
2794
       #print 'he: ', he
2795
       h_arc_x = rf * math.sin(alpha)
2796
       h_arc_z = k - rf + rf * math.cos(alpha)
2797
       #FreeCAD.Console.PrintMessage("h_arc_z: " + str(h_arc_z) + "\n")
2798

2799
    if (b > (l - 1.0*P)):
2800
       bmax = l- 1.0*P
2801
    else:
2802
       bmax = b
2803

2804
    ### make the new code with math.modf(l)
2805
    residue, turns = math.modf((bmax)/P)
2806
    halfturns = 2*int(turns)
2807
    if residue < 0.5:
2808
      a_point = l - (turns+1.0) * P
2809
      halfturns = halfturns +1
2810
    else:
2811
      halfturns = halfturns + 2
2812
      a_point = l - (turns+2.0) * P
2813
    #halfturns = halfturns + 2
2814
    offSet = r - a_point
2815
    #FreeCAD.Console.PrintMessage("The transition at a: " + str(a) + " turns " + str(turns) + "\n")
2816

2817
    sqrt2_ = 1.0/math.sqrt(2.0)
2818

2819
    #Head Points
2820
    Pnt1 = Base.Vector(h_arc_x,0.0,h_arc_z)
2821
    Pnt2 = Base.Vector(dk_max/2.0,0.0,he)
2822
    Pnt3 = Base.Vector(dk_max/2.0,0.0,0.0)
2823
    Pnt4 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
2824
    Pnt5 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
2825
    Pnt6 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
2826
    Pnt7 = Base.Vector(dia/2.0,0.0,-a_point)        # Start of thread
2827
    #FreeCAD.Console.PrintMessage("Points defined a_point: " + str(a_point) + "\n")
2828

2829

2830
    if (SType == 'ISO14583'):
2831
      #Pnt0 = Base.Vector(0.0,0.0,k-A/4.0)
2832
      Pnt0 = Base.Vector(0.0,0.0,k-A/8.0)
2833
      PntFlat = Base.Vector(A/8.0,0.0,k-A/8.0)
2834
      PntCham = Base.Vector(A/1.99,0.0,k)
2835
      edgeCham0 = Part.makeLine(Pnt0,PntFlat)
2836
      edgeCham1 = Part.makeLine(PntFlat,PntCham)
2837
      edgeCham2 = Part.Arc(PntCham,Pnt1,Pnt2).toShape()
2838
      #edge1 = Part.Wire([edgeCham0,edgeCham1,edgeCham2])
2839
      edge1 = Part.Wire([edgeCham0,edgeCham1])
2840
      edge2 = Part.makeLine(Pnt2,Pnt3)
2841
      edge2 = Part.Wire([edgeCham2, edge2])
2842
      # Part.show(edge2)
2843

2844
      # Here is the next approach to shorten the head building time
2845
      # Make two helper points to create a cutting tool for the
2846
      # recess and recess shell.
2847
      PntH1 = Base.Vector(A/1.99,0.0, 2.0*k)
2848
      PntH2 = Base.Vector(0.0,0.0, 2.0*k)
2849
      edgeH1 = Part.makeLine(PntCham,PntH1)
2850
      edgeH2 = Part.makeLine(PntH1,PntH2)
2851
      edgeH3 = Part.makeLine(PntH2,Pnt0)
2852

2853
    else:
2854
      Pnt0 = Base.Vector(0.0,0.0,k)
2855
      edge1 = Part.Arc(Pnt0,Pnt1,Pnt2).toShape()  # make round head
2856
      edge2 = Part.makeLine(Pnt2,Pnt3)
2857

2858
      # Here is the next approach to shorten the head building time
2859
      # Make two helper points to create a cutting tool for the
2860
      # recess and recess shell.
2861
      PntH1 = Base.Vector(dk_max/2.0,0.0, 2.0*k)
2862
      PntH2 = Base.Vector(0.0,0.0, 2.0*k)
2863
      edgeH1 = Part.makeLine(Pnt2,PntH1)
2864
      edgeH2 = Part.makeLine(PntH1,PntH2)
2865
      edgeH3 = Part.makeLine(PntH2,Pnt0)
2866

2867
    edge3 = Part.makeLine(Pnt3,Pnt4)
2868
    edge4 = Part.Arc(Pnt4,Pnt5,Pnt6).toShape()
2869
    #FreeCAD.Console.PrintMessage("Edges made h_arc_z: " + str(h_arc_z) + "\n")
2870

2871
    #if self.RealThread.isChecked():
2872
    if self.rThread:
2873
      aWire=Part.Wire([edge2,edge3,edge4])
2874
    else:
2875
      # bolt points
2876
      PntB1 = Base.Vector(dia/2.0,0.0,-l)
2877
      PntB2 = Base.Vector(0.0,0.0,-l)
2878
      edgeB2 = Part.makeLine(PntB1,PntB2)
2879
      if a_point <= r:
2880
        edgeB1 = Part.makeLine(Pnt6,PntB1)
2881
        aWire=Part.Wire([edge2, edge3, edge4, edgeB1, edgeB2])
2882
      else:
2883
        edge5 = Part.makeLine(Pnt6,Pnt7)
2884
        edgeB1 = Part.makeLine(Pnt7,PntB1)
2885
        aWire=Part.Wire([edge2, edge3, edge4, edge5, edgeB1, edgeB2])
2886

2887

2888

2889
    hWire = Part.Wire([edge1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
2890
    hFace = Part.Face(hWire)
2891
    hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
2892
    #Part.show(hWire)
2893

2894
    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
2895
    #head = Part.Solid(headShell)
2896
    #Part.show(aWire)
2897
    #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
2898
    headFaces = headShell.Faces
2899

2900
    if (SType == 'ISO14583'):
2901
      recess, recessShell = self.makeIso10664_3(tt, t_mean, k)
2902
      recessShell = recessShell.cut(hCut)
2903
      topFace = hCut.Faces[1]
2904
      topFace = topFace.cut(recess)
2905
      #Part.show(topFace)
2906
      #Part.show(recessShell)
2907
      #Part.show(headShell)
2908
      headFaces.append(topFace.Faces[0])
2909
      #headFaces.append(hCut.Faces[2])
2910

2911
    else:
2912
      #Lengths and angles for calculation of recess positioning
2913
      beta_cr = math.asin(mH /2.0 / rf)   # angle of recess edge
2914
      tan_beta_cr = math.tan(beta_cr)
2915
      # height of cross recess cutting
2916
      hcr = k - rf + (mH/2.0) / tan_beta_cr
2917
      #print 'hcr: ', hcr
2918

2919
      #Parameter for cross-recess type H: cT, mH
2920
      recess, recessShell = self.makeCross_H3(cT, mH, hcr)
2921
      recessShell = recessShell.cut(hCut)
2922
      topFace = hCut.Faces[0]
2923
      topFace = topFace.cut(recess)
2924
      #Part.show(topFace)
2925
      #Part.show(recessShell)
2926
      #Part.show(headShell)
2927
      headFaces.append(topFace.Faces[0])
2928

2929
    #Part.show(hCut)
2930
    headFaces.extend(recessShell.Faces)
2931

2932

2933
    #if self.RealThread.isChecked():
2934
    if self.rThread:
2935
      #head = self.cutIsoThread(head, dia, P, turns, l)
2936
      rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
2937
      rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
2938
      #head = head.fuse(rthread)
2939
      #Part.show(rthread)
2940
      for threadFace in rthread.Faces:
2941
        headFaces.append(threadFace)
2942

2943
    newHeadShell = Part.Shell(headFaces)
2944
    #Part.show(newHeadShell)
2945
    head = Part.Solid(newHeadShell)
2946

2947
    return head
2948

2949

2950
  # make Cheese head screw
2951
  # ISO 1207 slotted screw
2952
  # ISO 7048 cross recessed screw
2953
  # ISO 14580 Hexalobular socket cheese head screws
2954
  def makeIso1207(self,SType ='ISO1207', ThreadType ='M6',l=25.0):
2955
    dia = get_diameter(ThreadType)
2956
    '''
2957
    if '(' in TreadType:
2958
      threadString = ThreadType.lstrip('(M')
2959
      dia = float(ThreadType.rstrip(')'))
2960
    else:
2961
      dia=float(ThreadType.lstrip('M'))
2962
    '''
2963
    #FreeCAD.Console.PrintMessage("der Kopf mit l: " + str(l) + "\n")
2964
    if (SType == 'ISO1207') or (SType == 'ISO14580'):
2965
       P, a, b, dk, dk_mean, da, k, n_min, r, t_min, x = iso1207def[ThreadType]
2966
    if SType == 'ISO7048':
2967
       P, a, b, dk, dk_mean, da, k, r, x, cT, mH, mZ  = iso7048def[ThreadType]
2968
    if (SType == 'ISO14580'):
2969
       tt, k, A, t_min = iso14580def[ThreadType]
2970

2971
    #FreeCAD.Console.PrintMessage("der Kopf mit iso: " + str(dk) + "\n")
2972

2973
    #Length for calculation of head fillet
2974
    r_fil = r*2.0
2975
    beta = math.radians(5.0)   # angle of cheese head edge
2976
    alpha = math.radians(90.0 - (90.0+5.0)/2.0)
2977
    tan_beta = math.tan(beta)
2978
    # top head diameter without fillet
2979
    rK_top = dk/2.0 - k * tan_beta
2980
    fillet_center_x = rK_top - r_fil + r_fil * tan_beta
2981
    fillet_center_z = k - r_fil
2982
    fillet_arc_x = fillet_center_x + r_fil * math.sin(alpha)
2983
    fillet_arc_z = fillet_center_z + r_fil * math.cos(alpha)
2984
    #FreeCAD.Console.PrintMessage("rK_top: " + str(rK_top) + "\n")
2985

2986
    if (b > (l - 1.0*P)):
2987
       bmax = l- 1.0*P
2988
    else:
2989
       bmax = b
2990

2991
    ### make the new code with math.modf(l)
2992
    residue, turns = math.modf((bmax)/P)
2993
    halfturns = 2*int(turns)
2994
    if residue < 0.5:
2995
      a_point = l - (turns+1.0) * P
2996
      halfturns = halfturns +1
2997
    else:
2998
      halfturns = halfturns + 2
2999
      a_point = l - (turns+2.0) * P
3000
    #halfturns = halfturns + 2
3001
    offSet = r - a_point
3002

3003
    sqrt2_ = 1.0/math.sqrt(2.0)
3004

3005
    #Head Points
3006
    Pnt2 = Base.Vector(fillet_center_x,0.0,k)
3007
    Pnt3 = Base.Vector(fillet_arc_x,0.0,fillet_arc_z)
3008
    Pnt4 = Base.Vector(fillet_center_x + r_fil*math.cos(beta),0.0,fillet_center_z+ r_fil * math.sin(beta))
3009
    Pnt5 = Base.Vector(dk/2.0,0.0,0.0)
3010
    Pnt6 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
3011
    Pnt7 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
3012
    Pnt8 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
3013
    Pnt9 = Base.Vector(dia/2.0,0.0,-a_point)        # Start of thread
3014
    #FreeCAD.Console.PrintMessage("Points defined fillet_center_x: " + str(fillet_center_x) + "\n")
3015

3016
    if (SType == 'ISO14580'):
3017
      # Pnt0 = Base.Vector(0.0,0.0,k-A/4.0) #Center Point for countersunk
3018
      Pnt0 = Base.Vector(0.0,0.0,k-A/8.0) #Center Point for flat countersunk
3019
      PntFlat = Base.Vector(A/8.0,0.0,k-A/8.0) # End of flat part
3020
      Pnt1 = Base.Vector(A/1.99,0.0,k)     #countersunk edge at head
3021
      edgeCham0 = Part.makeLine(Pnt0,PntFlat)
3022
      edgeCham1 = Part.makeLine(PntFlat,Pnt1)
3023
      edgeCham2 = Part.makeLine(Pnt1,Pnt2)
3024
      edge1 = Part.Wire([edgeCham1,edgeCham2]) # make head with countersunk
3025
      PntH1 = Base.Vector(A/1.99,0.0, 2.0*k)
3026

3027
    else:
3028
      Pnt0 = Base.Vector(0.0,0.0,k)
3029
      edge1 = Part.makeLine(Pnt0,Pnt2)  # make flat head
3030

3031

3032
    edge2 = Part.Arc(Pnt2,Pnt3,Pnt4).toShape()
3033
    edge3 = Part.makeLine(Pnt4,Pnt5)
3034
    edge4 = Part.makeLine(Pnt5,Pnt6)
3035
    edge5 = Part.Arc(Pnt6,Pnt7,Pnt8).toShape()
3036
    #FreeCAD.Console.PrintMessage("Edges made fillet_center_z: " + str(fillet_center_z) + "\n")
3037

3038
    if SType == 'ISO1207':
3039
      #Parameter for slot-recess: dk, n_min, k, t_min
3040
      recess = Part.makePlane(dk, n_min, \
3041
        Base.Vector(dk/2.0,-n_min/2.0,k+1.0),Base.Vector(0.0,0.0,-1.0))
3042
      recess = recess.extrude(Base.Vector(0.0,0.0,-t_min-1.0))
3043

3044
      if self.rThread:
3045
        Pnt11 = Base.Vector(0.0,0.0,-r)        # helper point for real thread
3046
        edgeZ1 = Part.makeLine(Pnt8,Pnt11)
3047
        edgeZ0 = Part.makeLine(Pnt11,Pnt0)
3048
        aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5, \
3049
            edgeZ1, edgeZ0])
3050
      else:
3051
        # bolt points
3052
        PntB1 = Base.Vector(dia/2.0,0.0,-l)
3053
        PntB2 = Base.Vector(0.0,0.0,-l)
3054

3055
        edgeB2 = Part.makeLine(PntB1,PntB2)
3056

3057
        if a_point <= r:
3058
          edgeB1 = Part.makeLine(Pnt8,PntB1)
3059
          aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5, \
3060
              edgeB1, edgeB2])
3061
        else:
3062
          edge6 = Part.makeLine(Pnt8,Pnt9)
3063
          edgeB1 = Part.makeLine(Pnt9,PntB1)
3064
          aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6, \
3065
              edgeB1, edgeB2])
3066

3067
      aFace =Part.Face(aWire)
3068
      head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
3069
      head = head.cut(recess)
3070
      # FreeCAD.Console.PrintMessage("der Kopf geschnitten: " + str(dia) + "\n")
3071
      #Part.show(head)
3072
      if self.rThread:
3073
        screwFaces = []
3074
        for i in range(0, len(head.Faces)-1):
3075
          screwFaces.append(head.Faces[i])
3076
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
3077
        rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
3078
        for threadFace in rthread.Faces:
3079
          screwFaces.append(threadFace)
3080

3081
        screwShell = Part.Shell(screwFaces)
3082
        head = Part.Solid(screwShell)
3083

3084

3085

3086
    else:
3087
      if self.rThread:
3088
        aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5 ])
3089
      else:
3090
        # bolt points
3091
        PntB1 = Base.Vector(dia/2.0,0.0,-l)
3092
        PntB2 = Base.Vector(0.0,0.0,-l)
3093

3094
        edgeB2 = Part.makeLine(PntB1,PntB2)
3095

3096
        if a_point <= r:
3097
          edgeB1 = Part.makeLine(Pnt8,PntB1)
3098
          aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5, \
3099
              edgeB1, edgeB2])
3100
        else:
3101
          edge6 = Part.makeLine(Pnt8,Pnt9)
3102
          edgeB1 = Part.makeLine(Pnt9,PntB1)
3103
          aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6, \
3104
              edgeB1, edgeB2])
3105

3106
      #aFace =Part.Face(aWire)
3107
      headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
3108
      #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
3109

3110
      if SType == 'ISO7048':
3111
        # hCut should be just a cylinder
3112
        hCut = Part.makeCylinder(fillet_center_x,k,Pnt0)
3113
        recess, recessShell = self.makeCross_H3(cT, mH, k)
3114
        recessShell = recessShell.cut(hCut)
3115
        topFace = headShell.Faces[0].cut(recess)
3116
        screwFaces = [topFace.Faces[0]]
3117
        screwFaces.extend(recessShell.Faces)
3118
      if (SType == 'ISO14580'):
3119
        # Ring-cutter for recess shell
3120
        PntH2 = Base.Vector(A/8.0,0.0, 2.0*k)
3121
        edgeH1 = Part.makeLine(Pnt1,PntH1)
3122
        edgeH2 = Part.makeLine(PntH1,PntH2)
3123
        edgeH3 = Part.makeLine(PntH2,PntFlat)
3124
        hWire = Part.Wire([edgeCham1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
3125
        hFace = Part.Face(hWire)
3126
        hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
3127
        #Part.show(hWire)
3128

3129
        recess, recessShell = self.makeIso10664_3(tt, t_min, k)
3130
        recessShell = recessShell.cut(hCut)
3131
        topFace = headShell.Faces[0].cut(recess)
3132
        screwFaces = [topFace.Faces[0]]
3133
        screwFaces.extend(recessShell.Faces)
3134

3135
      for i in range(1, len(headShell.Faces)):
3136
        screwFaces.append(headShell.Faces[i])
3137

3138
      if self.rThread:
3139
        #head = self.cutIsoThread(head, dia, P, turns, l)
3140
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
3141
        rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
3142
        #head = head.fuse(rthread)
3143
        #Part.show(rthread)
3144
        for threadFace in rthread.Faces:
3145
          screwFaces.append(threadFace)
3146

3147
      screwShell = Part.Shell(screwFaces)
3148
      head = Part.Solid(screwShell)
3149

3150
    return head
3151

3152

3153

3154
  # make the ISO 4017 Hex-head-screw
3155
  # make the ISO 4014 Hex-head-bolt
3156
  def makeIso4017_2(self,SType ='ISO4017', ThreadType ='M6',l=40.0):
3157
    dia = get_diameter(ThreadType)
3158
    #FreeCAD.Console.PrintMessage("der Kopf mit l: " + str(l) + "\n")
3159
    if SType == 'ISO4017':
3160
      P, c, dw, e,k,r,s = iso4017head[ThreadType]
3161
      residue, turns = math.modf((l-1*P)/P)
3162
      halfturns = 2*int(turns)
3163

3164
    if SType == 'ISO8676':
3165
      P, c, dw, e,k,r,s = iso8676def[ThreadType]
3166
      residue, turns = math.modf((l-r-1*P)/P)
3167
      halfturns = 2*int(turns)
3168

3169
    if SType == 'ISO4014':
3170
      P, b1, b2, b3, c, dw, e, k, r, s = iso4014head[ThreadType]
3171
      if l<= 125.0:
3172
         b = b1
3173
      else:
3174
         if l<= 200.0:
3175
            b = b2
3176
         else:
3177
            b = b3
3178
      residue, turns = math.modf((b)/P)
3179
      halfturns = 2*int(turns)
3180

3181
    if residue < 0.5:
3182
      a = l - (turns+1.0) * P
3183
      halfturns = halfturns +1
3184
    else:
3185
      halfturns = halfturns + 2
3186
      a = l - (turns+2.0) * P
3187
    #halfturns = halfturns + 2
3188
    offSet = r - a
3189

3190
    sqrt2_ = 1.0/math.sqrt(2.0)
3191
    cham = (e-s)*math.sin(math.radians(15)) # needed for chamfer at head top
3192

3193
    #Head Points  Usage of k, s, cham, c, dw, dia, r, a
3194
    #FreeCAD.Console.PrintMessage("der Kopf mit halfturns: " + str(halfturns) + "\n")
3195
    Pnt0 = Base.Vector(0.0,0.0,k)
3196
    Pnt2 = Base.Vector(s/2.0,0.0,k)
3197
    Pnt3 = Base.Vector(s/math.sqrt(3.0),0.0,k-cham)
3198
    Pnt4 = Base.Vector(s/math.sqrt(3.0),0.0,c)
3199
    Pnt5 = Base.Vector(dw/2.0,0.0,c)
3200
    Pnt6 = Base.Vector(dw/2.0,0.0,0.0)
3201
    Pnt7 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
3202
    Pnt8 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
3203
    Pnt9 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
3204
    Pnt10 = Base.Vector(dia/2.0,0.0,-a)        # Start of thread
3205

3206
    edge1 = Part.makeLine(Pnt0,Pnt2)
3207
    edge2 = Part.makeLine(Pnt2,Pnt3)
3208
    edge3 = Part.makeLine(Pnt3,Pnt4)
3209
    edge4 = Part.makeLine(Pnt4,Pnt5)
3210
    edge5 = Part.makeLine(Pnt5,Pnt6)
3211
    edge6 = Part.makeLine(Pnt6,Pnt7)
3212
    edge7 = Part.Arc(Pnt7,Pnt8,Pnt9).toShape()
3213

3214
    # create cutting tool for hexagon head
3215
    # Parameters s, k, outer circle diameter =  e/2.0+10.0
3216
    extrude = self.makeHextool(s, k, s*2.0)
3217

3218
    #if self.RealThread.isChecked():
3219
    if self.rThread:
3220
      Pnt11 = Base.Vector(0.0,0.0,-r)        # helper point for real thread
3221
      edgeZ1 = Part.makeLine(Pnt9,Pnt11)
3222
      edgeZ0 = Part.makeLine(Pnt11,Pnt0)
3223
      aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6,edge7, \
3224
          edgeZ1, edgeZ0])
3225

3226
      aFace =Part.Face(aWire)
3227
      head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
3228
      #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
3229

3230
      # Part.show(extrude)
3231
      head = head.cut(extrude)
3232
      #FreeCAD.Console.PrintMessage("der Kopf geschnitten: " + str(dia) + "\n")
3233
      #Part.show(head)
3234

3235
      headFaces = []
3236
      for i in range(18):
3237
        headFaces.append(head.Faces[i])
3238

3239
      if (dia < 3.0) or (dia > 5.0):
3240
        rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
3241
        rthread.translate(Base.Vector(0.0, 0.0,-a-2.0*P))
3242
        #rthread.translate(Base.Vector(0.0, 0.0,-2.0*P))
3243
        #Part.show(rthread)
3244
        for tFace in rthread.Faces:
3245
          headFaces.append(tFace)
3246
        headShell = Part.Shell(headFaces)
3247
        head = Part.Solid(headShell)
3248
      else:
3249
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
3250
        rthread.translate(Base.Vector(0.0, 0.0,-a-2.0*P))
3251
        #rthread.translate(Base.Vector(0.0, 0.0,-2.0*P))
3252
        #Part.show(rthread)
3253
        for tFace in rthread.Faces:
3254
          headFaces.append(tFace)
3255
        headShell = Part.Shell(headFaces)
3256
        head = Part.Solid(headShell)
3257
        cyl = self.cutChamfer(dia, P, l)
3258
        #FreeCAD.Console.PrintMessage("vor Schnitt Ende: " + str(dia) + "\n")
3259
        head = head.cut(cyl)
3260

3261
    else:
3262
      # bolt points
3263
      cham_t = P*math.sqrt(3.0)/2.0*17.0/24.0
3264

3265
      PntB0 = Base.Vector(0.0,0.0,-a)
3266
      PntB1 = Base.Vector(dia/2.0,0.0,-l+cham_t)
3267
      PntB2 = Base.Vector(dia/2.0-cham_t,0.0,-l)
3268
      PntB3 = Base.Vector(0.0,0.0,-l)
3269

3270
      edgeB1 = Part.makeLine(Pnt10,PntB1)
3271
      edgeB2 = Part.makeLine(PntB1,PntB2)
3272
      edgeB3 = Part.makeLine(PntB2,PntB3)
3273

3274
      edgeZ0 = Part.makeLine(PntB3,Pnt0)
3275
      if a <= r:
3276
        edgeB1 = Part.makeLine(Pnt9,PntB1)
3277
        aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6,edge7, \
3278
            edgeB1, edgeB2, edgeB3, edgeZ0])
3279

3280
      else:
3281
        edge8 = Part.makeLine(Pnt9,Pnt10)
3282
        edgeB1 = Part.makeLine(Pnt10,PntB1)
3283
        aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6,edge7,edge8, \
3284
            edgeB1, edgeB2, edgeB3, edgeZ0])
3285

3286
      aFace =Part.Face(aWire)
3287
      head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
3288
      #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
3289

3290
      # Part.show(extrude)
3291
      head = head.cut(extrude)
3292
      #FreeCAD.Console.PrintMessage("der Kopf geschnitten: " + str(dia) + "\n")
3293

3294
    return head
3295

3296

3297
  # EN 1662 Hex-head-bolt with flange - small series
3298
  # EN 1665 Hexagon bolts with flange, heavy series
3299
  def makeEN1662_2(self,SType ='EN1662', ThreadType ='M8',l=25.0):
3300
    dia = get_diameter(ThreadType)
3301
    #FreeCAD.Console.PrintMessage("der Kopf mit l: " + str(l) + "\n")
3302
    if SType == 'EN1662':
3303
       P, b0, b1, b2, b3, c, dc, dw, e, k, kw,f, r1, s = en1662def[ThreadType]
3304
    else:
3305
       P, b0, b1, b2, b3, c, dc, dw, e, k, kw,f, r1, s = en1665def[ThreadType]
3306
    if l< b0:
3307
       b = l - 2*P
3308
    else:
3309
       if l<= 125.0:
3310
          b = b1
3311
       else:
3312
          if l<= 200.0:
3313
             b = b2
3314
          else:
3315
             b = b3
3316

3317
    #FreeCAD.Console.PrintMessage("der Kopf mit isoEN1662: " + str(c) + "\n")
3318
    cham = s*(2.0/math.sqrt(3.0)-1.0)*math.sin(math.radians(25)) # needed for chamfer at head top
3319

3320
    ### make the new code with math.modf(l)
3321
    residue, turns = math.modf((b)/P)
3322
    halfturns = 2*int(turns)
3323
    if residue < 0.5:
3324
      a_point = l - (turns+1.0) * P
3325
      halfturns = halfturns +1
3326
    else:
3327
      halfturns = halfturns + 2
3328
      a_point = l - (turns+2.0) * P
3329
    #halfturns = halfturns + 2
3330
    offSet = r1 - a_point
3331

3332
    sqrt2_ = 1.0/math.sqrt(2.0)
3333

3334
    # Flange is made with a radius of c
3335
    beta = math.radians(25.0)
3336
    tan_beta = math.tan(beta)
3337

3338
    # Calculation of Arc points of flange edge using dc and c
3339
    arc1_x = dc/2.0 - c/2.0 + (c/2.0)*math.sin(beta)
3340
    arc1_z = c/2.0 + (c/2.0)*math.cos(beta)
3341

3342
    hF = arc1_z + (arc1_x -s/2.0) * tan_beta  # height of flange at center
3343

3344
    kmean = arc1_z + (arc1_x - s/math.sqrt(3.0)) * tan_beta + kw * 1.1 + cham
3345
    #kmean = k * 0.95
3346

3347

3348
    #Hex-Head Points
3349
    #FreeCAD.Console.PrintMessage("der Kopf mit math a: " + str(a_point) + "\n")
3350
    PntH0 = Base.Vector(0.0,0.0,kmean*0.9)
3351
    PntH1 = Base.Vector(s/2.0*0.8 - r1/2.0,0.0,kmean*0.9)
3352
    PntH1a = Base.Vector(s/2.0*0.8-r1/2.0+r1/2.0*sqrt2_,0.0,kmean*0.9 +r1/2.0 -r1/2.0*sqrt2_)
3353
    PntH1b = Base.Vector(s/2.0*0.8,0.0,kmean*0.9 +r1/2.0)
3354
    PntH2 = Base.Vector(s/2.0*0.8,0.0,kmean -r1)
3355
    PntH2a = Base.Vector(s/2.0*0.8+r1-r1*sqrt2_,0.0,kmean -r1 +r1*sqrt2_)
3356
    PntH2b = Base.Vector(s/2.0*0.8 + r1 ,0.0,kmean)
3357
    PntH3 = Base.Vector(s/2.0,0.0,kmean)
3358
    #PntH4 = Base.Vector(s/math.sqrt(3.0),0.0,kmean-cham)   #s/math.sqrt(3.0)
3359
    #PntH5 = Base.Vector(s/math.sqrt(3.0),0.0,c)
3360
    #PntH6 = Base.Vector(0.0,0.0,c)
3361

3362
    edgeH1 = Part.makeLine(PntH0,PntH1)
3363
    edgeH2 = Part.Arc(PntH1,PntH1a,PntH1b).toShape()
3364
    edgeH3 = Part.makeLine(PntH1b,PntH2)
3365
    edgeH3a = Part.Arc(PntH2,PntH2a,PntH2b).toShape()
3366
    edgeH3b = Part.makeLine(PntH2b,PntH3)
3367

3368
    hWire=Part.Wire([edgeH1,edgeH2,edgeH3,edgeH3a,edgeH3b])
3369
    topShell = hWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
3370
    #Part.show(hWire)
3371
    #Part.show(topShell)
3372

3373
    # create a cutter ring to generate the chamfer at the top of the hex
3374
    chamHori = s/math.sqrt(3.0) - s/2.0
3375
    PntC1 = Base.Vector(s/2.0-chamHori,0.0,kmean+kmean)
3376
    PntC2 = Base.Vector(s/math.sqrt(3.0)+chamHori,0.0,kmean+kmean)
3377
    PntC3 = Base.Vector(s/2.0-chamHori,0.0,kmean+cham)
3378
    PntC4 = Base.Vector(s/math.sqrt(3.0)+chamHori,0.0,kmean-cham-cham)   #s/math.sqrt(3.0)
3379
    edgeC1 = Part.makeLine(PntC3, PntC1)
3380
    edgeC2 = Part.makeLine(PntC1, PntC2)
3381
    edgeC3 = Part.makeLine(PntC2, PntC4)
3382
    edgeC4 = Part.makeLine(PntC4, PntC3)
3383
    cWire = Part.Wire([edgeC4, edgeC1, edgeC2, edgeC3])
3384
    cFace = Part.Face(cWire)
3385
    chamCut = cFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
3386
    #Part.show(cWire)
3387
    #Part.show(chamCut)
3388

3389

3390
    # create hexagon
3391
    mhex=Base.Matrix()
3392
    mhex.rotateZ(math.radians(60.0))
3393
    polygon = []
3394
    vhex=Base.Vector(s/math.sqrt(3.0),0.0,kmean)
3395
    for i in range(6):
3396
       polygon.append(vhex)
3397
       vhex = mhex.multiply(vhex)
3398
    polygon.append(vhex)
3399
    hexagon = Part.makePolygon(polygon)
3400
    hexFace = Part.Face(hexagon)
3401
    solidHex = hexFace.extrude(Base.Vector(0.0,0.0,c-kmean))
3402
    #Part.show(solidHex)
3403
    hexCham = solidHex.cut(chamCut)
3404
    #Part.show(hexCham)
3405

3406
    topFaces = topShell.Faces
3407

3408
    topFaces.append(hexCham.Faces[6])
3409
    topFaces.append(hexCham.Faces[12])
3410
    topFaces.append(hexCham.Faces[14])
3411
    topFaces.append(hexCham.Faces[13])
3412
    topFaces.append(hexCham.Faces[8])
3413
    topFaces.append(hexCham.Faces[2])
3414
    topFaces.append(hexCham.Faces[1])
3415

3416
    hexFaces = [hexCham.Faces[5], hexCham.Faces[11], hexCham.Faces[10]]
3417
    hexFaces.extend([hexCham.Faces[9], hexCham.Faces[3], hexCham.Faces[0]])
3418
    hexShell = Part.Shell(hexFaces)
3419

3420
    # Center of flange:
3421
    Pnt0 = Base.Vector(0.0,0.0,hF)
3422
    Pnt1 = Base.Vector(s/2.0,0.0,hF)
3423

3424
    # arc edge of flange:
3425
    Pnt2 = Base.Vector(arc1_x,0.0,arc1_z)
3426
    Pnt3 = Base.Vector(dc/2.0,0.0,c/2.0)
3427
    Pnt4 = Base.Vector((dc-c)/2.0,0.0,0.0)
3428

3429
    Pnt5 = Base.Vector(dia/2.0+r1,0.0,0.0)     #start of fillet between head and shank
3430
    Pnt6 = Base.Vector(dia/2.0+r1-r1*sqrt2_,0.0,-r1+r1*sqrt2_) #arc-point of fillet
3431
    Pnt7 = Base.Vector(dia/2.0,0.0,-r1)        # end of fillet
3432
    Pnt8 = Base.Vector(dia/2.0,0.0,-a_point)        # Start of thread
3433

3434
    edge1 = Part.makeLine(Pnt0,Pnt1)
3435
    edge2 = Part.makeLine(Pnt1,Pnt2)
3436
    edge3 = Part.Arc(Pnt2,Pnt3,Pnt4).toShape()
3437
    edge4 = Part.makeLine(Pnt4,Pnt5)
3438
    edge5 = Part.Arc(Pnt5,Pnt6,Pnt7).toShape()
3439

3440
    # make a cutter for the hexShell
3441
    PntHC1 = Base.Vector(0.0,0.0,arc1_z)
3442
    PntHC2 = Base.Vector(0.0,0.0,0.0)
3443

3444
    edgeHC1 = Part.makeLine(Pnt2,PntHC1)
3445
    edgeHC2 = Part.makeLine(PntHC1,PntHC2)
3446
    edgeHC3 = Part.makeLine(PntHC2,Pnt0)
3447

3448
    HCWire = Part.Wire([edge2, edgeHC1, edgeHC2, edgeHC3, edge1])
3449
    HCFace = Part.Face(HCWire)
3450
    hex2Cut = HCFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
3451

3452
    hexShell = hexShell.cut(hex2Cut)
3453
    #Part.show(hexShell)
3454

3455
    topFaces.extend(hexShell.Faces)
3456

3457
    # bolt points
3458
    cham_t = P*math.sqrt(3.0)/2.0*17.0/24.0
3459

3460
    PntB0 = Base.Vector(0.0,0.0,-a_point)
3461
    PntB1 = Base.Vector(dia/2.0,0.0,-l+cham_t)
3462
    PntB2 = Base.Vector(dia/2.0-cham_t,0.0,-l)
3463
    PntB3 = Base.Vector(0.0,0.0,-l)
3464

3465
    edgeB2 = Part.makeLine(PntB1,PntB2)
3466
    edgeB3 = Part.makeLine(PntB2,PntB3)
3467

3468
    #if self.RealThread.isChecked():
3469
    if self.rThread:
3470
      aWire=Part.Wire([edge2,edge3,edge4,edge5])
3471
      boltIndex = 4
3472

3473
    else:
3474
      if a_point <=r1:
3475
        edgeB1 = Part.makeLine(Pnt7,PntB1)
3476
        aWire=Part.Wire([edge2,edge3,edge4,edge5, edgeB1, edgeB2, edgeB3])
3477
        boltIndex = 7
3478
      else:
3479
        edgeB1 = Part.makeLine(Pnt8,PntB1)
3480
        edge6 = Part.makeLine(Pnt7,Pnt8)
3481
        aWire=Part.Wire([edge2,edge3,edge4,edge5,edge6, \
3482
            edgeB1, edgeB2, edgeB3])
3483
        boltIndex = 8
3484

3485

3486
    #aFace =Part.Face(aWire)
3487
    #Part.show(aWire)
3488
    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
3489
    #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
3490
    #Part.show(headShell)
3491
    chamFace = headShell.Faces[0].cut(solidHex)
3492
    #Part.show(chamFace)
3493

3494
    topFaces.append(chamFace.Faces[0])
3495
    for i in range(1,boltIndex):
3496
      topFaces.append(headShell.Faces[i])
3497

3498

3499
    if self.rThread:
3500
      if (dia < 3.0) or (dia > 5.0):
3501
        rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
3502
        rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
3503
        for tFace in rthread.Faces:
3504
          topFaces.append(tFace)
3505
        headShell = Part.Shell(topFaces)
3506
        screw = Part.Solid(headShell)
3507
      else:
3508
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
3509
        rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
3510
        for tFace in rthread.Faces:
3511
          topFaces.append(tFace)
3512
        headShell = Part.Shell(topFaces)
3513
        head = Part.Solid(headShell)
3514
        cyl = self.cutChamfer(dia, P, l)
3515
        #FreeCAD.Console.PrintMessage("vor Schnitt Ende: " + str(dia) + "\n")
3516
        screw = head.cut(cyl)
3517
    else:
3518
      screwShell = Part.Shell(topFaces)
3519
      screw = Part.Solid(screwShell)
3520

3521
    return screw
3522

3523
  def makeIso7046(self, SType ='ISO7046', ThreadType ='M6', l=25.0):
3524
    """ISO 7046, ISO 7047, ISO 10642, ISO 14582, ISO 14584
3525

3526
    Used for ISO 7046 countersunk flat head screws with H cross recess
3527
    Used for ISO 7047 raised countersunk head screws with H cross recess
3528
    Used for ISO 10642 Hexagon socket countersunk head screws
3529
    Used for ISO 14582 Hexalobular socket countersunk head screws, high head
3530
    Used for ISO 14584 Hexalobular socket raised countersunk head screws
3531
    """
3532
    dia = get_diameter(ThreadType)
3533
    #FreeCAD.Console.PrintMessage("The 2009 head with l: " + str(l) + "\n")
3534
    if (SType == 'ISO10642'):
3535
      P,b,dk_theo,dk_mean,da, ds_min, e, k, r, s_mean, t, w =iso10642def[ThreadType]
3536
      ePrax = s_mean / math.sqrt(3.0) / 0.99
3537
      ht = 0.0
3538
      a = 2*P
3539
      t_mean = t
3540
    else: #still need the data from iso2009def, but this screw can not created here
3541
      P, a, b, dk_theo, dk_mean, k, n_min, r, t_mean, x = iso2009def[ThreadType]
3542
      ht = 0.0 # Head height of flat head
3543
    if SType == 'ISO7046':
3544
      cT, mH, mZ  = iso7046def[ThreadType]
3545
    if (SType == 'ISO7047'):
3546
      rf, t_mean, cT, mH, mZ = Raised_countersunk_def[ThreadType]
3547
      #Lengths and angles for calculation of head rounding
3548
      beta = math.asin(dk_mean /2.0 / rf)   # angle of head edge
3549
      tan_beta = math.tan(beta)
3550
      alpha = beta/2.0 # half angle
3551
      # height of raised head top
3552
      ht = rf - (dk_mean/2.0) / tan_beta
3553
      #print 'he: ', he
3554
      h_arc_x = rf * math.sin(alpha)
3555
      h_arc_z = ht - rf + rf * math.cos(alpha)
3556
      #FreeCAD.Console.PrintMessage("h_arc_z: " + str(h_arc_z) + "\n")
3557

3558
    if (SType == 'ISO14582'):
3559
      P, a, b, dk_theo, dk_mean, k, r, tt, A, t_mean = iso14582def[ThreadType]
3560
      ePrax = A / 2.0 / 0.99
3561

3562
    if (SType == 'ISO14584'):
3563
      P, b, dk_theo, dk_mean, f, k, r, rf, x, tt, A, t_mean = iso14584def[ThreadType]
3564
      ePrax = A / 2.0 / 0.99
3565
      #Lengths and angles for calculation of head rounding
3566
      beta = math.asin(dk_mean /2.0 / rf)   # angle of head edge
3567
      tan_beta = math.tan(beta)
3568
      ctp = - (dk_mean/2.0) / tan_beta # Center Top Edge = center for rf
3569
      betaA = math.asin(ePrax / rf)   # angle of head edge at start of recess
3570
      ht = ctp + ePrax / math.tan(betaA)
3571
      alpha = betaA + (beta - betaA)/2.0 # half angle of top Arc
3572
      h_arc_x = rf * math.sin(alpha)
3573
      h_arc_z = ctp + rf * math.cos(alpha)
3574

3575

3576
    FreeCAD.Console.PrintMessage("The head with iso r: " + str(r) + "\n")
3577
    cham = (dk_theo - dk_mean)/2.0
3578
    rad225 = math.radians(22.5)
3579
    rad45 = math.radians(45.0)
3580
    rtan = r*math.tan(rad225)
3581
    #FreeCAD.Console.PrintMessage("Checking rtan: " + str(rtan) + "\n")
3582

3583
    if (b > (l - k - rtan/2.0 - 1.0*P)):
3584
      bmax = l - k - rtan/2.0 - 1.0*P
3585
    else:
3586
      bmax = b
3587

3588
    ### make the new code with math.modf(l)
3589
    residue, turns = math.modf((bmax)/P)
3590
    halfturns = 2*int(turns)
3591
    if residue < 0.5:
3592
      a_point = l - (turns+1.0) * P
3593
      halfturns = halfturns +1
3594
    else:
3595
      halfturns = halfturns + 2
3596
      a_point = l - (turns+2.0) * P
3597
    #halfturns = halfturns + 2
3598
    offSet = k + rtan - a_point
3599

3600
    #Head Points
3601
    Pnt1 = Base.Vector(dk_mean/2.0,0.0,0.0)
3602
    Pnt2 = Base.Vector(dk_mean/2.0,0.0,-cham)
3603
    Pnt3 = Base.Vector(dia/2.0+r-r*math.cos(rad45),0.0,-k-rtan+r*math.sin(rad45))
3604

3605
    # Arc-points
3606
    Pnt4 = Base.Vector(dia/2.0+r-r*(math.cos(rad225)),0.0,-k-rtan+r*math.sin(rad225))
3607
    Pnt5 = Base.Vector(dia/2.0,0.0,-k-rtan)
3608
    Pnt6 = Base.Vector(dia/2.0,0.0,-a_point)
3609

3610
    if (SType == 'ISO10642') or (SType == 'ISO14582'):
3611
      if (SType == 'ISO10642'):
3612
        recess, recessShell = self.makeAllen2(s_mean, t_mean, 0.0 )
3613
        Pnt0 = Base.Vector(ePrax/2.0,0.0,-ePrax/2.0)
3614
        PntCham = Base.Vector(ePrax,0.0,0.0)
3615
        edge1 = Part.makeLine(Pnt0,PntCham)
3616
        edgeCham2 = Part.makeLine(PntCham,Pnt1)
3617
        edge2 = Part.makeLine(Pnt1,Pnt2)
3618
        edge2 = Part.Wire([edgeCham2,edge2])
3619
        PntH0 = Base.Vector(ePrax/2.0,0.0, ht + k)
3620
        PntH1 = Base.Vector(ePrax,0.0, ht + k)
3621
      if (SType == 'ISO14582'):
3622
        recess, recessShell = self.makeIso10664_3(tt, t_mean, 0.0) # hexalobular recess
3623
        Pnt0 = Base.Vector(0.0,0.0,0.0)
3624
        edge1 = Part.makeLine(Pnt0,Pnt1)
3625
        edge2 = Part.makeLine(Pnt1,Pnt2)
3626

3627

3628
      # bolt points with bolt chamfer
3629
      cham_b = P*math.sqrt(3.0)/2.0*17.0/24.0
3630

3631
      PntB1 = Base.Vector(dia/2.0,0.0,-l+cham_b)
3632
      PntB2 = Base.Vector(dia/2.0-cham_b,0.0,-l)
3633
      PntB3 = Base.Vector(0.0,0.0,-l)
3634
      if a_point <= (k + rtan):
3635
        edgeB0 = Part.makeLine(Pnt5,PntB1)
3636
      else:
3637
        edgeB0 = Part.makeLine(Pnt6,PntB1)
3638
      edgeB2 = Part.makeLine(PntB1,PntB2)
3639
      edgeB3 = Part.makeLine(PntB2,PntB3)
3640
      edgeB1 = Part.Wire([edgeB2,edgeB3])
3641

3642
    else:
3643
      # bolt points
3644
      PntB1 = Base.Vector(dia/2.0,0.0,-l)
3645
      PntB2 = Base.Vector(0.0,0.0,-l)
3646
      if a_point <= (k + rtan):
3647
        edgeB0 = Part.makeLine(Pnt5,PntB1)
3648
      else:
3649
        edgeB0 = Part.makeLine(Pnt6,PntB1)
3650
      edgeB1 = Part.makeLine(PntB1,PntB2)
3651

3652
      if (SType == 'ISO7047'): # make raised head rounding
3653
        Pnt0 = Base.Vector(0.0,0.0,ht)
3654
        Pnt0arc = Base.Vector(h_arc_x,0.0,h_arc_z)
3655
        edge1 = Part.Arc(Pnt0,Pnt0arc,Pnt1).toShape()
3656
        edge2 = Part.makeLine(Pnt1,Pnt2)
3657
        PntH0 = Base.Vector(0.0,0.0, ht + k)
3658
        PntH1 = Base.Vector(dk_mean/2.0,0.0, ht + k)
3659
        recess, recessShell = self.makeCross_H3(cT, mH, ht)
3660
      if (SType == 'ISO7046'):
3661
        # ISO7046
3662
        FreeCAD.Console.PrintMessage("ISO7046: " + str(ht) + "\n")
3663
        Pnt0 = Base.Vector(0.0,0.0,ht)
3664
        edge1 = Part.makeLine(Pnt0,Pnt1)  # make flat head
3665
        edge2 = Part.makeLine(Pnt1,Pnt2)
3666
        recess, recessShell = self.makeCross_H3(cT, mH, ht)
3667

3668
      if (SType == 'ISO14584'): # make raised head rounding with chamfer
3669
        Pnt0 = Base.Vector(ePrax/2.0,0.0,ht-ePrax/4.0)
3670
        PntCham = Base.Vector(ePrax,0.0,ht)
3671
        PntArc = Base.Vector(h_arc_x,0.0,h_arc_z)
3672
        edge1 = Part.makeLine(Pnt0,PntCham)
3673
        edgeArc = Part.Arc(PntCham,PntArc,Pnt1).toShape()
3674
        edge2 = Part.makeLine(Pnt1,Pnt2)
3675
        edge2 = Part.Wire([edgeArc,edge2])
3676
        PntH0 = Base.Vector(ePrax/2.0,0.0, ht + k)
3677
        PntH1 = Base.Vector(ePrax,0.0, ht + k)
3678
        recess, recessShell = self.makeIso10664_3(tt, t_mean, ht) # hexalobular recess
3679

3680
    edge3 = Part.makeLine(Pnt2,Pnt3)
3681
    edgeArc = Part.Arc(Pnt3,Pnt4,Pnt5).toShape()
3682
    edgeArc1 = Part.makeLine(Pnt3,Pnt4)
3683
    edgeArc2 = Part.makeLine(Pnt4,Pnt5)
3684
    edge6 = Part.makeLine(Pnt5,Pnt6)
3685

3686
    if self.rThread:
3687
      #aWire=Part.Wire([edge1,edge2,edge3,edgeArc])
3688
      aWire=Part.Wire([edge2,edge3,edgeArc])
3689
    else:
3690
      if a_point <= (k + rtan):
3691
        aWire=Part.Wire([edge2,edge3,edgeArc, edgeB0, edgeB1])
3692
      else:
3693
        aWire=Part.Wire([edge2,edge3,edgeArc,edge6, edgeB0, edgeB1])
3694

3695
    #Part.show(aWire)
3696
    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
3697
    headFaces = headShell.Faces
3698
    #Part.show(headShell)
3699

3700
    if (SType == 'ISO7046') or (SType == 'ISO14582'):
3701
      # hCut is just a cylinder for ISO7046
3702
      hCut = Part.makeCylinder(dk_mean/2.0,k,Pnt0)
3703
      #Part.show(hCut)
3704
      topFace = hCut.Faces[2]
3705
    else:
3706
      if (SType == 'ISO7047'):
3707
        edgeH1 = Part.makeLine(Pnt1,PntH1)
3708
      else:
3709
        edgeH1 = Part.makeLine(PntCham,PntH1)
3710
      edgeH2 = Part.makeLine(PntH1,PntH0)
3711
      edgeH3 = Part.makeLine(PntH0,Pnt0)
3712
      hWire = Part.Wire([edge1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
3713
      hFace = Part.Face(hWire)
3714
      hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
3715
      Part.show(hWire)
3716
      #Part.show(hCut)
3717
      topFace = hCut.Faces[0]
3718

3719
    recessShell = recessShell.cut(hCut)
3720
    topFace = topFace.cut(recess)
3721
    #Part.show(topFace)
3722
    #Part.show(recessShell)
3723
    #Part.show(headShell)
3724
    headFaces.append(topFace.Faces[0])
3725
    headFaces.extend(recessShell.Faces)
3726

3727

3728
    if (SType == 'ISO10642') or (SType == 'ISO14582'):
3729
      if self.rThread:
3730
        if (dia < 3.0) or (dia > 5.0):
3731
          #if True:
3732
          rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
3733
          rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
3734
          #head = head.fuse(rthread)
3735
          #Part.show(rthread)
3736
          for threadFace in rthread.Faces:
3737
            headFaces.append(threadFace)
3738

3739
          screwShell = Part.Shell(headFaces)
3740
          screw = Part.Solid(screwShell)
3741
        else:
3742
          '''
3743
          # head = self.cutIsoThread(head, dia, P, turns, l)
3744
          rthread = self.makeShellthread(dia, P, halfturns, False)
3745
          rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
3746
          head = head.fuse(rthread)
3747
          head = head.removeSplitter()
3748
          cyl = self.cutChamfer(dia, P, l)
3749
          #FreeCAD.Console.PrintMessage("vor Schnitt Ende: " + str(dia) + "\n")
3750
          head = head.cut(cyl)
3751
          '''
3752

3753
          rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
3754
          rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
3755
          #head = head.fuse(rthread)
3756
          #Part.show(rthread)
3757
          for threadFace in rthread.Faces:
3758
            headFaces.append(threadFace)
3759

3760
          screwShell = Part.Shell(headFaces)
3761
          screw = Part.Solid(screwShell)
3762
          cyl = self.cutChamfer(dia, P, l)
3763
          screw = screw.cut(cyl)
3764
      else:
3765
        screwShell = Part.Shell(headFaces)
3766
        screw = Part.Solid(screwShell)
3767

3768
    else:
3769
      if self.rThread:
3770
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
3771
        rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
3772
        #head = head.fuse(rthread)
3773
        #Part.show(rthread)
3774
        for threadFace in rthread.Faces:
3775
          headFaces.append(threadFace)
3776

3777
      screwShell = Part.Shell(headFaces)
3778
      screw = Part.Solid(screwShell)
3779

3780
    return screw
3781

3782
  def makeIso4762(self, SType ='ISO4762', ThreadType ='M6',l=25.0):
3783
    """ISO 4762 Allen Screw head and ISO 14579 Hexalobular socket head cap
3784
    """
3785
    dia = get_diameter(ThreadType)
3786
    #FreeCAD.Console.PrintMessage("der 4762Kopf mit l: " + str(l) + "\n")
3787
    P, b, dk_max, da, ds_mean, e, lf, k, r, s_mean, t, v, dw, w = iso4762def[ThreadType]
3788
    #FreeCAD.Console.PrintMessage("der Kopf mit iso r: " + str(r) + "\n")
3789
    if SType == 'ISO14579':
3790
      tt, A, t = iso14579def[ThreadType]
3791
      #Head Points 30° countersunk
3792
      # Pnt0 = Base.Vector(0.0,0.0,k-A/4.0) #Center Point for countersunk
3793
      Pnt0 = Base.Vector(0.0,0.0,k-A/8.0) #Center Point for flat countersunk
3794
      PntFlat = Base.Vector(A/8.0,0.0,k-A/8.0) # End of flat part
3795
      Pnt1 = Base.Vector(A/1.99,0.0,k)     #countersunk edge at head
3796
      edgeCham0 = Part.makeLine(Pnt0,PntFlat)
3797
      edgeCham1 = Part.makeLine(PntFlat,Pnt1)
3798
      edge1 = Part.Wire([edgeCham0,edgeCham1])
3799

3800
      # Here is the next approach to shorten the head building time
3801
      # Make two helper points to create a cutting tool for the
3802
      # recess and recess shell.
3803
      PntH1 = Base.Vector(A/1.99,0.0, 2.0*k)
3804

3805
    else:
3806
      e_cham = 2.0 * s_mean / math.sqrt(3.0)
3807
      #Head Points 45° countersunk
3808
      Pnt0 = Base.Vector(0.0,0.0,k-e_cham/1.99/2.0) #Center Point for countersunk
3809
      PntFlat = Base.Vector(e_cham/1.99/2.0,0.0,k-e_cham/1.99/2.0) # End of flat part
3810
      Pnt1 = Base.Vector(e_cham/1.99,0.0,k)     #countersunk edge at head
3811
      edgeCham0 = Part.makeLine(Pnt0,PntFlat)
3812
      edgeCham1 = Part.makeLine(PntFlat,Pnt1)
3813
      edge1 = Part.Wire([edgeCham0,edgeCham1])
3814
      PntH1 = Base.Vector(e_cham/1.99,0.0, 2.0*k)
3815

3816

3817
    PntH2 = Base.Vector(0.0,0.0, 2.0*k)
3818
    edgeH1 = Part.makeLine(Pnt1,PntH1)
3819
    edgeH2 = Part.makeLine(PntH1,PntH2)
3820
    edgeH3 = Part.makeLine(PntH2,Pnt0)
3821
    hWire = Part.Wire([edge1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
3822
    hFace = Part.Face(hWire)
3823
    hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
3824
    #Part.show(hWire)
3825
    '''
3826

3827

3828
    PntH2 = Base.Vector(A/8.0,0.0, 2.0*k)
3829
    edgeH1 = Part.makeLine(Pnt1,PntH1)
3830
    edgeH2 = Part.makeLine(PntH1,PntH2)
3831
    edgeH3 = Part.makeLine(PntH2,PntFlat)
3832
    hWire = Part.Wire([edgeCham1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
3833
    hFace = Part.Face(hWire)
3834
    hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
3835
    #Part.show(hWire)
3836
    '''
3837

3838

3839
    sqrt2_ = 1.0/math.sqrt(2.0)
3840
    #depth = s_mean / 3.0
3841

3842
    '''
3843
    if (b > l - 2*P):
3844
       bmax = l-2*P
3845
    else:
3846
       bmax = b
3847
    halfturns = round(2.0*(bmax+P)/P) # number of thread turns
3848
    if self.RealThread.isChecked():
3849
      a_real = l-(halfturns+2)*P/2.0  # point to fuse real thread
3850
    else:
3851
      a_real = l-halfturns*P/2.0  # starting point of thread
3852
    if a_real < r:
3853
      a_point = r*1.3
3854
    else:
3855
      a_point = a_real
3856
    '''
3857

3858

3859
    if (b > (l - 1.0*P)):
3860
       bmax = l- 1.0*P
3861
    else:
3862
       bmax = b
3863

3864
    ### make the new code with math.modf(l)
3865
    residue, turns = math.modf((bmax)/P)
3866
    halfturns = 2*int(turns)
3867
    if residue < 0.5:
3868
      a_point = l - (turns+1.0) * P
3869
      halfturns = halfturns +1
3870
    else:
3871
      halfturns = halfturns + 2
3872
      a_point = l - (turns+2.0) * P
3873
    #halfturns = halfturns + 2
3874
    offSet = r - a_point
3875
    #FreeCAD.Console.PrintMessage("The transition at a: " + str(a) + " turns " + str(turns) + "\n")
3876

3877

3878

3879

3880
    #rad30 = math.radians(30.0)
3881
    #Head Points
3882
    Pnt2 = Base.Vector(dk_max/2.0-v,0.0,k)   #start of fillet
3883
    Pnt3 = Base.Vector(dk_max/2.0-v+v*sqrt2_,0.0,k-v+v*sqrt2_) #arc-point of fillet
3884
    Pnt4 = Base.Vector(dk_max/2.0,0.0,k-v)   #end of fillet
3885
    Pnt5 = Base.Vector(dk_max/2.0,0.0,(dk_max-dw)/2.0) #we have a chamfer here
3886
    Pnt6 = Base.Vector(dw/2.0,0.0,0.0)           #end of chamfer
3887
    Pnt7 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
3888
    Pnt8 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
3889
    Pnt9 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
3890
    Pnt10 = Base.Vector(dia/2.0,0.0,-a_point)        # start of thread
3891

3892
    edge1 = Part.makeLine(Pnt0,Pnt1)
3893
    edge2 = Part.makeLine(Pnt1,Pnt2)
3894
    edge3 = Part.Arc(Pnt2,Pnt3,Pnt4).toShape()
3895
    edge4 = Part.makeLine(Pnt4,Pnt5)
3896
    edge5 = Part.makeLine(Pnt5,Pnt6)
3897
    edge6 = Part.makeLine(Pnt6,Pnt7)
3898
    edge7 = Part.Arc(Pnt7,Pnt8,Pnt9).toShape()
3899

3900
    '''
3901
    # bolt points
3902
    PntB1 = Base.Vector(dia/2.0,0.0,-l-P)  # Chamfer is made with a cut later
3903
    PntB2 = Base.Vector(0.0,0.0,-l-P)
3904
    #PntB3 = Base.Vector(0.0,0.0,-l)
3905

3906
    edgeB0 = Part.makeLine(Pnt10,PntB1)
3907
    edgeB1 = Part.makeLine(PntB1,PntB2)
3908
    #edgeB2 = Part.makeLine(PntB2,PntB3)
3909
    edgeZ0 = Part.makeLine(PntB2,Pnt0)
3910

3911

3912
    aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6,edge7,edge8, \
3913
        edgeB0, edgeB1, edgeZ0])
3914
    '''
3915

3916

3917

3918
    if self.rThread:
3919
      aWire=Part.Wire([edge2,edge3,edge4,edge5,edge6,edge7])
3920

3921
    else:
3922
      # bolt points
3923
      cham_t = P*math.sqrt(3.0)/2.0*17.0/24.0
3924

3925
      PntB1 = Base.Vector(dia/2.0,0.0,-l+cham_t)
3926
      PntB2 = Base.Vector(dia/2.0-cham_t,0.0,-l)
3927
      PntB3 = Base.Vector(0.0,0.0,-l)
3928

3929
      #edgeB1 = Part.makeLine(Pnt10,PntB1)
3930
      edgeB2 = Part.makeLine(PntB1,PntB2)
3931
      edgeB3 = Part.makeLine(PntB2,PntB3)
3932

3933
      if a_point <= r:
3934
        edgeB1 = Part.makeLine(Pnt9,PntB1)
3935
        aWire=Part.Wire([edge2,edge3,edge4,edge5,edge6,edge7, \
3936
            edgeB1, edgeB2, edgeB3])
3937
      else:
3938
        edge8 = Part.makeLine(Pnt9,Pnt10)
3939
        edgeB1 = Part.makeLine(Pnt10,PntB1)
3940
        aWire=Part.Wire([edge2,edge3,edge4,edge5,edge6,edge7,edge8, \
3941
            edgeB1, edgeB2, edgeB3])
3942
      #Part.show(aWire)
3943

3944
    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
3945
    #head = Part.Solid(headShell)
3946
    #Part.show(aWire)
3947
    #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
3948
    headFaces = headShell.Faces
3949

3950

3951
    if SType == 'ISO14579':
3952
      #recess = self.makeIso10664(tt, t, k) # hexalobular recess
3953
      recess, recessShell = self.makeIso10664_3(tt, t, k) # hexalobular recess
3954
    else:
3955
      recess, recessShell = self.makeAllen2(s_mean, t, k )
3956

3957
    recessShell = recessShell.cut(hCut)
3958
    topFace = hCut.Faces[1]
3959
    #topFace = hCut.Faces[0]
3960
    topFace = topFace.cut(recess)
3961
    #Part.show(topFace)
3962
    #Part.show(recessShell)
3963
    #Part.show(headShell)
3964
    headFaces.append(topFace.Faces[0])
3965
    #headFaces.append(hCut.Faces[2])
3966

3967
    #allenscrew = head.cut(recess)
3968
    #Part.show(hCut)
3969
    headFaces.extend(recessShell.Faces)
3970

3971
    #if self.RealThread.isChecked():
3972
    if self.rThread:
3973
      #if (dia < 3.0) or (dia > 5.0):
3974
      if True:
3975
        # head = self.cutIsoThread(head, dia, P, turns, l)
3976
        rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
3977
        rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
3978
        #Part.show(rthread)
3979
        for tFace in rthread.Faces:
3980
          headFaces.append(tFace)
3981
        headShell = Part.Shell(headFaces)
3982
        allenscrew = Part.Solid(headShell)
3983

3984
      else:
3985
        # head = self.cutIsoThread(head, dia, P, turns, l)
3986
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
3987
        rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
3988
        for tFace in rthread.Faces:
3989
          headFaces.append(tFace)
3990
        headShell = Part.Shell(headFaces)
3991
        allenscrew = Part.Solid(headShell)
3992
        cyl = self.cutChamfer(dia, P, l)
3993
        # FreeCAD.Console.PrintMessage("vor Schnitt Ende: " + str(dia) + "\n")
3994
        allenscrew = allenscrew.cut(cyl)
3995
    else:
3996
      headShell = Part.Shell(headFaces)
3997
      allenscrew = Part.Solid(headShell)
3998

3999

4000
    return allenscrew
4001

4002

4003

4004

4005
  # make ISO 7380-1 Button head Screw
4006
  # make ISO 7380-2 Button head Screw with collar
4007
  # make DIN 967 cross recessed pan head Screw with collar
4008
  def makeIso7380(self, SType ='ISO7380-1', ThreadType ='M6',l=25.0):
4009
    dia = get_diameter(ThreadType)
4010
    #todo: different radii for screws with thread to head or with shaft?
4011
    sqrt2_ = 1.0/math.sqrt(2.0)
4012

4013
    if (SType =='DIN967'):
4014
      P, b, c, da, dk, r, k, rf, x, cT, mH, mZ = din967def[ThreadType]
4015

4016
      rH = rf # radius of button arc
4017
      alpha = math.acos((rf-k+c)/rf)
4018

4019
      #Head Points
4020
      Pnt0 = Base.Vector(0.0,0.0,k)
4021
      PntArc = Base.Vector(rf*math.sin(alpha/2.0),0.0,k-rf + rf*math.cos(alpha/2.0)) #arc-point of button
4022
      Pnt1 = Base.Vector(rf*math.sin(alpha),0.0,c)     #end of button arc
4023
      PntC0 = Base.Vector((dk)/2.0,0.0,c)     #collar points
4024
      PntC2 = Base.Vector((dk)/2.0,0.0,0.0)     #collar points
4025
      Pnt4 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
4026

4027
      edge1 = Part.Arc(Pnt0,PntArc,Pnt1).toShape()
4028
      edgeC0 = Part.makeLine(Pnt1,PntC0)
4029
      edgeC1 = Part.makeLine(PntC0,PntC2)
4030
      edge2 = Part.Wire([edgeC0, edgeC1])
4031
      edge3 = Part.makeLine(PntC2,Pnt4)
4032
      #Points for recessShell cutter
4033
      PntH0 = Base.Vector(0.0,0.0,2.0*k)
4034
      PntH1 = Base.Vector(rf*math.sin(alpha),0.0,2.0*k)
4035
      recess, recessShell = self.makeCross_H3(cT, mH, k)
4036

4037
    else:
4038
      if (SType =='ISO7380-1'):
4039
        P, b, a, da, dk, dk_mean,s_mean, t_min, r, k, e, w = iso7380def[ThreadType]
4040

4041
        # Bottom of recess
4042
        e_cham = 2.0 * s_mean / math.sqrt(3.0) / 0.99
4043
        #depth = s_mean / 3.0
4044

4045
        ak = -(4*k**2 + e_cham**2 - dk**2)/(8*k) # helper value for button arc
4046
        rH = math.sqrt((dk/2.0)**2 + ak**2) # radius of button arc
4047
        alpha = (math.atan(2*(k + ak)/e_cham) + math.atan((2*ak)/dk))/2
4048

4049
        Pnt2 = Base.Vector(rH*math.cos(alpha),0.0,-ak + rH*math.sin(alpha)) #arc-point of button
4050
        Pnt3 = Base.Vector(dk/2.0,0.0,0.0)   #end of fillet
4051
        Pnt4 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
4052
        edge3 = Part.makeLine(Pnt3,Pnt4)
4053

4054
      if (SType =='ISO7380-2'):
4055
        P, b, c, da, dk, dk_c,s_mean,t_min, r, k, e, w = iso7380_2def[ThreadType]
4056

4057
        # Bottom of recess
4058
        e_cham = 2.0 * s_mean / math.sqrt(3.0) / 0.99
4059
        #depth = s_mean / 3.0
4060

4061
        ak = -(4*(k-c)**2 + e_cham**2 - dk**2)/(8*(k-c)) # helper value for button arc
4062
        rH = math.sqrt((dk/2.0)**2 + ak**2) # radius of button arc
4063
        alpha = (math.atan(2*(k -c + ak)/e_cham) + math.atan((2*ak)/dk))/2
4064

4065
        Pnt2 = Base.Vector(rH*math.cos(alpha),0.0,c -ak + rH*math.sin(alpha)) #arc-point of button
4066
        Pnt3 = Base.Vector(dk/2.0,0.0,c)   #end of fillet
4067
        Pnt4 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
4068
        PntC0 = Base.Vector((dk_c-c)/2.0,0.0,c)     #collar points
4069
        PntC1 = Base.Vector(dk_c/2.0,0.0,c/2.0)     #collar points
4070
        PntC2 = Base.Vector((dk_c-c)/2.0,0.0,0.0)     #collar points
4071

4072
        edgeC0 = Part.makeLine(Pnt3,PntC0)
4073
        edgeC1 = Part.Arc(PntC0,PntC1,PntC2).toShape()
4074
        edge3 = Part.makeLine(PntC2,Pnt4)
4075
        edge3 = Part.Wire([edgeC0, edgeC1, edge3])
4076

4077
      #Head Points
4078
      Pnt0 = Base.Vector(e_cham/4.0,0.0,k-e_cham/4.0) #Center Point for chamfer
4079
      Pnt1 = Base.Vector(e_cham/2.0,0.0,k)     #inner chamfer edge at head
4080
      #Points for recessShell cutter
4081
      PntH0 = Base.Vector(e_cham/4.0,0.0,2.0*k)
4082
      PntH1 = Base.Vector(e_cham/2.0,0.0,2.0*k)
4083

4084
      edge1 = Part.makeLine(Pnt0,Pnt1)
4085
      edge2 = Part.Arc(Pnt1,Pnt2,Pnt3).toShape()
4086
      recess, recessShell = self.makeAllen2(s_mean, t_min, k)
4087

4088
    if (b > (l - 1.0*P)):
4089
       bmax = l- 1.0*P
4090
    else:
4091
       bmax = b
4092

4093
    ### make the new code with math.modf(l)
4094
    residue, turns = math.modf((bmax)/P)
4095
    halfturns = 2*int(turns)
4096
    if residue < 0.5:
4097
      a_point = l - (turns+1.0) * P
4098
      halfturns = halfturns +1
4099
    else:
4100
      halfturns = halfturns + 2
4101
      a_point = l - (turns+2.0) * P
4102
    offSet = r - a_point
4103

4104

4105
    Pnt5 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
4106
    Pnt6 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
4107
    Pnt7 = Base.Vector(dia/2.0,0.0,-a_point)        # start of thread
4108

4109
    edge4 = Part.Arc(Pnt4,Pnt5,Pnt6).toShape()
4110
    edge5 = Part.makeLine(Pnt6,Pnt7)
4111

4112
    if (SType =='DIN967'):
4113
      # bolt points
4114
      PntB1 = Base.Vector(dia/2.0,0.0,-l)
4115
      PntB2 = Base.Vector(0.0,0.0,-l)
4116
      edgeB2 = Part.makeLine(PntB1,PntB2)
4117
    else:
4118
      # bolt points
4119
      cham_b = P*math.sqrt(3.0)/2.0*17.0/24.0
4120

4121
      PntB1 = Base.Vector(dia/2.0,0.0,-l+cham_b)
4122
      PntB2 = Base.Vector(dia/2.0-cham_b,0.0,-l)
4123
      PntB3 = Base.Vector(0.0,0.0,-l)
4124

4125
      edgeB2 = Part.makeLine(PntB1,PntB2)
4126
      edgeB3 = Part.makeLine(PntB2,PntB3)
4127
      edgeB2 = Part.Wire([edgeB2, edgeB3])
4128

4129
    if self.rThread:
4130
      aWire=Part.Wire([edge2,edge3,edge4])
4131
    else:
4132
      if a_point <= r:
4133
        edgeB1 = Part.makeLine(Pnt6,PntB1)
4134
        aWire=Part.Wire([edge2,edge3,edge4, edgeB1, edgeB2])
4135
      else:
4136
        edge5 = Part.makeLine(Pnt6,Pnt7)
4137
        edgeB1 = Part.makeLine(Pnt7,PntB1)
4138
        aWire=Part.Wire([edge2,edge3,edge4,edge5, edgeB1, edgeB2])
4139

4140
    #Part.show(aWire)
4141
    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
4142
    #Part.show(headShell)
4143
    headFaces = headShell.Faces
4144

4145
    edgeH1 = Part.makeLine(Pnt1,PntH1)
4146
    edgeH2 = Part.makeLine(PntH1,PntH0)
4147
    edgeH3 = Part.makeLine(PntH0,Pnt0)
4148
    hWire = Part.Wire([edge1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
4149
    hFace = Part.Face(hWire)
4150
    hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
4151
    #Part.show(hWire)
4152
    topFace = hCut.Faces[0]
4153

4154
    recessShell = recessShell.cut(hCut)
4155
    topFace = topFace.cut(recess)
4156
    #Part.show(topFace)
4157
    #Part.show(recessShell)
4158
    #Part.show(headShell)
4159
    headFaces.append(topFace.Faces[0])
4160
    headFaces.extend(recessShell.Faces)
4161

4162

4163
    if self.rThread:
4164
      #if (dia < 3.0) or (dia > 5.0):
4165
      if True:
4166
        if (SType =='DIN967'):
4167
          rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
4168
        else:
4169
          rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
4170
        rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
4171
        for threadFace in rthread.Faces:
4172
          headFaces.append(threadFace)
4173

4174
        screwShell = Part.Shell(headFaces)
4175
        screw = Part.Solid(screwShell)
4176
      else:
4177
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
4178
        rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
4179
        for threadFace in rthread.Faces:
4180
          headFaces.append(threadFace)
4181

4182
        screwShell = Part.Shell(headFaces)
4183
        screw = Part.Solid(screwShell)
4184
        cyl = self.cutChamfer(dia, P, l)
4185
        screw = screw.cut(cyl)
4186
    else:
4187
      screwShell = Part.Shell(headFaces)
4188
      screw = Part.Solid(screwShell)
4189

4190
    return screw
4191

4192

4193

4194

4195
  def makeHextool(self,s_hex, k_hex, cir_hex):
4196
    # makes a cylinder with an inner hex hole, used as cutting tool
4197
    # create hexagon
4198
    mhex=Base.Matrix()
4199
    mhex.rotateZ(math.radians(60.0))
4200
    polygon = []
4201
    vhex=Base.Vector(s_hex/math.sqrt(3.0),0.0,-k_hex*0.1)
4202
    for i in range(6):
4203
       polygon.append(vhex)
4204
       vhex = mhex.multiply(vhex)
4205
    polygon.append(vhex)
4206
    hexagon = Part.makePolygon(polygon)
4207
    # create circle
4208
    circ = Part.makeCircle(cir_hex/2.0, Base.Vector(0.0,0.0,-k_hex*0.1), self.circleAxis)
4209
    # Create the face with the circle as outline and the hexagon as hole
4210
    face=Part.Face([Part.Wire(circ),hexagon])
4211

4212
    # Extrude in z to create the final cutting tool
4213
    exHex=face.extrude(Base.Vector(0.0,0.0,k_hex*1.2))
4214
    # Part.show(exHex)
4215
    return exHex
4216

4217

4218
  def makeShellthread(self, d, P, halfrots, withcham, offSet):
4219
    d = float(d)
4220

4221
    #rotations = int(rots)-1
4222
    halfrots_int = int(halfrots)
4223
    rotations = (halfrots_int // 2) - 1
4224
    if halfrots_int % 2 == 1:
4225
      #FreeCAD.Console.PrintMessage("got half turn: " + str(halfrots_int) + "\n")
4226
      halfturn = True
4227
      # bot_off = - P/2.0 # transition of half a turn
4228
      bot_off = 0.0 # nominal length
4229
    else:
4230
      halfturn = False
4231
      bot_off = 0.0 # nominal length
4232

4233
    H=P*math.cos(math.radians(30)) # Gewindetiefe H
4234
    r=d/2.0
4235

4236
    # helix = Part.makeHelix(P,P,d*511/1000.0,0) # make just one turn, length is identical to pitch
4237
    helix = Part.makeHelix(P,P,d*self.Tuner/1000.0,0) # make just one turn, length is identical to pitch
4238
    helix.translate(FreeCAD.Vector(0.0, 0.0,-P*9.0/16.0))
4239

4240
    extra_rad = P
4241
    # points for screw profile
4242
    ps0 = (r,0.0, 0.0)
4243
    ps1 = (r-H*5.0/8.0,0.0, -P*5.0/16.0)
4244
    ps2 = (r-H*17.0/24.0,0.0, -P*7.0/16.0) # Center of Arc
4245
    ps3 = (r-H*5.0/8.0,0.0, -P*9.0/16.0 )
4246
    ps4 =  (r, 0.0, -P*14.0/16.0)
4247
    ps5 = (r,0.0, -P)
4248
    ps6 = (r+extra_rad,0.0, -P)
4249
    ps7 = (r+extra_rad,0.0, 0.0)
4250

4251
    edge0 = Part.makeLine(ps0,ps1)
4252
    edge1 = Part.Arc(FreeCAD.Vector(ps1),FreeCAD.Vector(ps2),FreeCAD.Vector(ps3)).toShape()
4253
    edge2 = Part.makeLine(ps3,ps4)
4254
    edge3 = Part.makeLine(ps4,ps5)
4255
    edge4 = Part.makeLine(ps5,ps6)
4256
    edge5 = Part.makeLine(ps6,ps7)
4257
    edge6 = Part.makeLine(ps7,ps0)
4258

4259
    W0 = Part.Wire([edge0, edge1, edge2, edge3, edge4, edge5, edge6])
4260

4261
    makeSolid=True
4262
    isFrenet=True
4263
    pipe0 = Part.Wire(helix).makePipeShell([W0],makeSolid,isFrenet)
4264
    # pipe1 = pipe0.copy()
4265

4266
    TheFaces = []
4267
    TheFaces.append(pipe0.Faces[0])
4268
    #Part.show(pipe0.Faces[0])
4269
    TheFaces.append(pipe0.Faces[1])
4270
    #Part.show(pipe0.Faces[1])
4271
    TheFaces.append(pipe0.Faces[2])
4272
    #Part.show(pipe0.Faces[2])
4273
    TheFaces.append(pipe0.Faces[3])
4274
    #Part.show(pipe0.Faces[3])
4275

4276
    TheShell = Part.Shell(TheFaces)
4277
    # print "Shellpoints: ", len(TheShell.Vertexes)
4278

4279

4280
    i = 1
4281
    for i in range(rotations-2):
4282
       TheShell.translate(FreeCAD.Vector(0.0, 0.0, -P))
4283

4284
       for flaeche in TheShell.Faces:
4285
         TheFaces.append(flaeche)
4286

4287
    #FreeCAD.Console.PrintMessage("Base-Shell: " + str(i) + "\n")
4288
    # Make separate faces for the tip of the screw
4289
    botFaces = []
4290
    for i in range(rotations-2, rotations, 1):
4291
       TheShell.translate(FreeCAD.Vector(0.0, 0.0, -P))
4292

4293
       for flaeche in TheShell.Faces:
4294
         botFaces.append(flaeche)
4295
    #FreeCAD.Console.PrintMessage("Bottom-Shell: " + str(i) + "\n")
4296

4297
    # making additional faces for transition to cylinder
4298

4299
    pc1 = (r + H/16.0,0.0,P*1/32.0)
4300
    pc2 = (r-H*5.0/8.0,0.0,-P*5.0/16.0 )
4301
    pc3 = (r-H*17.0/24.0,0.0, -P*7.0/16.0 ) # Center of Arc
4302
    pc4 = (r-H*5.0/8.0,0.0, -P*9.0/16.0 )
4303
    pc5 =  (r+ H/16.0, 0.0, -P*29.0/32.0 )
4304

4305
    edgec0 = Part.makeLine(pc5,pc1)
4306
    edgec1 = Part.makeLine(pc1,pc2)
4307
    edgec2 = Part.Arc(FreeCAD.Vector(pc2),FreeCAD.Vector(pc3),FreeCAD.Vector(pc4)).toShape()
4308
    edgec3 = Part.makeLine(pc4,pc5)
4309

4310
    cut_profile = Part.Wire([edgec1, edgec2, edgec3, edgec0 ])
4311

4312
    alpha_rad = math.atan(2*H*17.0/24.0/P)
4313
    alpha = math.degrees(alpha_rad)
4314
    Hyp = P/math.cos(alpha_rad)
4315
    # tuning = 511/1000.0
4316
    tuning = self.Tuner/1000.0
4317
    angled_Helix = Part.makeHelix(Hyp,Hyp*1.002/2.0,d*tuning,alpha)
4318

4319
    SH_faces = []
4320

4321
    if halfturn:
4322
      half_Helix = Part.makeHelix(P,P/2.0,d*self.Tuner/1000.0,0) # make just half a turn
4323
      angled_Helix.rotate(Base.Vector(0,0,0),Base.Vector(0,0,1),180)
4324
      angled_Helix.translate(FreeCAD.Vector(0.0, 0.0,P/2.0))
4325
      # Part.show(half_Helix)
4326
      # Part.show(angled_Helix)
4327
      pipe_cut = Part.Wire([half_Helix, angled_Helix]).makePipeShell([cut_profile],True,isFrenet)
4328
      SH_faces.append(pipe_cut.Faces[0])
4329
      SH_faces.append(pipe_cut.Faces[1])
4330
      SH_faces.append(pipe_cut.Faces[2])
4331
      SH_faces.append(pipe_cut.Faces[4])
4332
      SH_faces.append(pipe_cut.Faces[5])
4333
      SH_faces.append(pipe_cut.Faces[6])
4334

4335
    else:
4336
      pipe_cut = Part.Wire(angled_Helix).makePipeShell([cut_profile],True,isFrenet)
4337
      SH_faces.append(pipe_cut.Faces[0])
4338
      SH_faces.append(pipe_cut.Faces[1])
4339
      SH_faces.append(pipe_cut.Faces[2])
4340

4341
    # Part.show(pipe_cut)
4342

4343

4344
    Shell_helix = Part.Shell(SH_faces)
4345

4346
    # rect_helix_profile, needed for cutting a tube-shell
4347
    pr1 = (r +H/16.0, 0.0, 0.0)
4348
    pr2 = (r -H/16.0, 0.0, 0.0)
4349
    pr3 = (r -H/16.0, 0.0, P)
4350
    pr4 = (r +H/16.0, 0.0, P)
4351

4352
    edge_r1 = Part.makeLine(pr1,pr2)
4353
    edge_r2 = Part.makeLine(pr2,pr3)
4354
    edge_r3 = Part.makeLine(pr3,pr4)
4355
    edge_r4 = Part.makeLine(pr4,pr1)
4356
    rect_profile = Part.Wire([edge_r1, edge_r2, edge_r3, edge_r4 ])
4357
    rect_helix = Part.Wire(helix).makePipeShell([rect_profile], True, isFrenet)
4358
    # if halfturn:
4359
    #   rect_helix.rotate(Base.Vector(0,0,0),Base.Vector(0,0,1),180)
4360
    rect_helix.translate(FreeCAD.Vector(0.0, 0.0,- P))
4361
    # Part.show(rect_helix)
4362

4363
    # rect_ring, needed for cutting the Shell_helix
4364
    pr5 = (r +H*1.1, 0.0, P*1.1)
4365
    pr6 = (r, 0.0, P*1.1)
4366
    pr7 = (r, 0.0, -P*1.1)
4367
    pr8 = (r +H*1.1, 0.0, -P*1.1)
4368

4369
    edge_r5 = Part.makeLine(pr5,pr6)
4370
    edge_r6 = Part.makeLine(pr6,pr7)
4371
    edge_r7 = Part.makeLine(pr7,pr8)
4372
    edge_r8 = Part.makeLine(pr8,pr5)
4373
    rect_profile = Part.Wire([edge_r5, edge_r6, edge_r7, edge_r8 ])
4374

4375
    rect_Face =Part.Face(rect_profile)
4376
    rect_ring= rect_Face.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
4377
    #Part.show(rect_ring)
4378

4379
    Shell_helix = Shell_helix.cut(rect_ring)
4380
    Shell_helix.translate(FreeCAD.Vector(0.0, 0.0, P))
4381
    # Part.show(Shell_helix)
4382

4383
    # shell_ring, the transition to a cylinder
4384
    pr9 = (r, 0.0, P-offSet)
4385
    pr10 = (r, 0.0, -P )
4386
    edge_r9 = Part.makeLine(pr9,pr10)
4387
    shell_ring= edge_r9.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
4388

4389
    shell_ring = shell_ring.cut(pipe_cut)
4390
    #Part.show(shell_ring)
4391
    shell_ring = shell_ring.cut(rect_helix)
4392
    shell_ring.translate(FreeCAD.Vector(0.0, 0.0, P))
4393
    #Part.show(shell_ring)
4394

4395
    for flaeche in shell_ring.Faces:
4396
      TheFaces.append(flaeche)
4397

4398
    for flaeche in Shell_helix.Faces:
4399
      TheFaces.append(flaeche)
4400

4401
    if withcham:
4402
      #FreeCAD.Console.PrintMessage("with chamfer: " + str(i) + "\n")
4403
      # cutting of the bottom Faces
4404
      # bot_off = 0.0 # nominal length
4405
      cham_off = H/8.0
4406
      cham_t = P*math.sqrt(3.0)/2.0*17.0/24.0
4407

4408
      # points for chamfer: common-Method
4409
      pch0 =  (0.0, 0.0, -(rotations)*P + bot_off) # bottom center
4410
      pch1 =  (r-cham_t,0.0, -(rotations)*P + bot_off)
4411
      pch2 =  (r+cham_off, 0.0, -(rotations)*P + cham_t +cham_off  + bot_off)
4412
      pch3 =  (r+cham_off, 0.0, -(rotations)*P + 3.0*P + bot_off)
4413
      pch4 =  (0.0, 0.0, -(rotations)*P + 3.0*P + bot_off)
4414

4415
      edgech0 = Part.makeLine(pch0,pch1)
4416
      edgech1 = Part.makeLine(pch1,pch2)
4417
      edgech2 = Part.makeLine(pch2,pch3)
4418
      edgech3 = Part.makeLine(pch3,pch4)
4419
      edgech4 = Part.makeLine(pch4,pch0)
4420

4421
      Wch_wire = Part.Wire([edgech0, edgech1, edgech2, edgech3, edgech4])
4422
      cham_Face =Part.Face(Wch_wire)
4423
      cham_Solid = cham_Face.revolve(Base.Vector(0.0,0.0,-(rotations-1)*P),Base.Vector(0.0,0.0,1.0),360)
4424
      # Part.show(cham_Solid)
4425

4426
      BotShell = Part.Shell(botFaces)
4427
      BotShell = BotShell.common(cham_Solid)
4428
      # Part.show(BotShell)
4429

4430
      cham_faces = []
4431
      cham_faces.append(cham_Solid.Faces[0])
4432
      cham_faces.append(cham_Solid.Faces[1])
4433
      cham_Shell = Part.Shell(cham_faces)
4434
      # Part.show(cham_Shell)
4435

4436
      pipe0.translate(FreeCAD.Vector(0.0, 0.0, -(rotations-1)*P))
4437
      # Part.show(pipe0)
4438

4439
      # Part.show(Fillet_shell)
4440
      cham_Shell = cham_Shell.cut(pipe0)
4441
      pipe0.translate(FreeCAD.Vector(0.0, 0.0, -P))
4442
      # Part.show(pipe0)
4443
      cham_Shell = cham_Shell.cut(pipe0)
4444

4445
      '''
4446
      botFaces2 = []
4447
      for flaeche in BotShell.Faces:
4448
        botFaces2.append(flaeche)
4449
      for flaeche in cham_Shell.Faces:
4450
        botFaces2.append(flaeche)
4451
      '''
4452

4453
    else: # tip of screw without chamfer
4454
      #FreeCAD.Console.PrintMessage("without chamfer: " + str(i) + "\n")
4455

4456
      commonbox = Part.makeBox(d+4.0*P, d+4.0*P, 3.0*P)
4457
      commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-(rotations)*P+bot_off))
4458
      #commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-(rotations+3)*P+bot_off))
4459
      #Part.show(commonbox)
4460

4461
      BotShell = Part.Shell(botFaces)
4462
      #Part.show(BotShell)
4463

4464
      BotShell = BotShell.common(commonbox)
4465
      #BotShell = BotShell.cut(commonbox)
4466
      bot_edges =[]
4467
      bot_z =  1.0e-5 -(rotations)*P + bot_off
4468

4469
      for kante in BotShell.Edges:
4470
         if (kante.Vertexes[0].Point.z<=bot_z) and (kante.Vertexes[1].Point.z<=bot_z):
4471
            bot_edges.append(kante)
4472
            # Part.show(kante)
4473
      bot_wire = Part.Wire(Part.__sortEdges__(bot_edges))
4474

4475
      #botFaces2 = []
4476
      #for flaeche in BotShell.Faces:
4477
      #  botFaces2.append(flaeche)
4478

4479
      bot_face = Part.Face(bot_wire)
4480
      bot_face.reverse()
4481
      #botFaces2.append(bot_face)
4482

4483
    '''
4484

4485
    BotShell2 = Part.Shell(botFaces2)
4486
    # Part.show(BotShell2)
4487

4488
    TheShell2 = Part.Shell(TheFaces)
4489

4490
    # This gives a shell
4491
    FaceList = []
4492
    for flaeche in TheShell2.Faces:
4493
      FaceList.append(flaeche)
4494
    for flaeche in BotShell2.Faces:
4495
      FaceList.append(flaeche)
4496

4497
    TheShell = Part.Shell(FaceList)
4498
    # Part.show(TheShell)
4499
    '''
4500
    for flaeche in BotShell.Faces:
4501
      TheFaces.append(flaeche)
4502
    if withcham:
4503
      for flaeche in cham_Shell.Faces:
4504
        TheFaces.append(flaeche)
4505
    else:
4506
      TheFaces.append(bot_face)
4507
    TheShell = Part.Shell(TheFaces)
4508

4509
    #print self.Tuner, " ", TheShell.ShapeType, " ", TheShell.isValid(), " hrots: ", halfrots_int, " Shellpunkte: ", len(TheShell.Vertexes)
4510

4511
    return TheShell
4512

4513
  # if da<>None: make Shell for a nut else: make a screw tap
4514
  def makeInnerThread_2(self, d, P, rotations, da, l):
4515
    d = float(d)
4516
    bot_off = 0.0 # nominal length
4517

4518
    H=P*math.cos(math.radians(30)) # Gewindetiefe H
4519
    r=d/2.0
4520

4521
    helix = Part.makeHelix(P,P,d*self.Tuner/1000.0,0) # make just one turn, length is identical to pitch
4522
    helix.translate(FreeCAD.Vector(0.0, 0.0,-P*9.0/16.0))
4523

4524
    extra_rad = P
4525

4526
    # points for inner thread profile
4527
    ps0 = (r,0.0, 0.0)
4528
    ps1 = (r-H*5.0/8.0,0.0, -P*5.0/16.0)
4529
    ps2 = (r-H*5.0/8.0,0.0, -P*9.0/16.0 )
4530
    ps3 =  (r, 0.0, -P*14.0/16.0)
4531
    ps4 = (r+H*1/24.0,0.0, -P*31.0/32.0) # Center of Arc
4532
    ps5 = (r,0.0, -P)
4533
    ps6 = (r+extra_rad,0.0, -P)
4534
    ps7 = (r+extra_rad,0.0, 0.0)
4535

4536
    #ps6 = (r-extra_rad,0.0, -P)
4537
    #ps7 = (r-extra_rad,0.0, 0.0)
4538

4539
    edge0 = Part.makeLine(ps0,ps1)
4540
    edge1 = Part.makeLine(ps1,ps2)
4541
    edge2 = Part.makeLine(ps2,ps3)
4542
    edge3 = Part.Arc(FreeCAD.Vector(ps3),FreeCAD.Vector(ps4),FreeCAD.Vector(ps5)).toShape()
4543
    edge4 = Part.makeLine(ps5,ps6)
4544
    edge5 = Part.makeLine(ps6,ps7)
4545
    edge6 = Part.makeLine(ps7,ps0)
4546

4547
    W0 = Part.Wire([edge0, edge1, edge2, edge3, edge4, edge5, edge6])
4548
    # Part.show(W0)
4549

4550
    makeSolid=True
4551
    isFrenet=True
4552
    pipe0 = Part.Wire(helix).makePipeShell([W0],makeSolid,isFrenet)
4553
    # pipe1 = pipe0.copy()
4554

4555
    TheFaces = []
4556
    TheFaces.append(pipe0.Faces[0])
4557
    TheFaces.append(pipe0.Faces[1])
4558
    TheFaces.append(pipe0.Faces[2])
4559
    TheFaces.append(pipe0.Faces[3])
4560

4561
    TheShell = Part.Shell(TheFaces)
4562
    # print "Shellpoints: ", len(TheShell.Vertexes)
4563

4564
    # Handling of the top faces
4565
    if da is not None:
4566
      TheShell.translate(FreeCAD.Vector(0.0, 0.0, -P))
4567
      for flaeche in TheShell.Faces:
4568
       TheFaces.append(flaeche)
4569
      TheShell.translate(FreeCAD.Vector(0.0, 0.0, -P))
4570
      for flaeche in TheShell.Faces:
4571
       TheFaces.append(flaeche)
4572

4573
      cham_i_delta = da/2.0 - (r-H)
4574
      cham_i = cham_i_delta * math.tan(math.radians(15.0))
4575

4576
      offSet = rotations*P - l
4577
      #FreeCAD.Console.PrintMessage("Der Offset: " + str(offSet/P) + "\n")
4578

4579
      # points for chamfer: common-Method
4580
      pch0 =  (da/2.0-cham_i_delta, 0.0, -cham_i - offSet) # bottom chamfer
4581
      pch1 =  (da/2.0, 0.0, 0.0 - offSet)  #
4582
      pch2 =  (da/2.0, 0.0, -4.0*P - offSet)
4583
      pch3 =  (da/2.0-cham_i_delta, 0.0, -4.0*P - offSet)
4584

4585
      edgech0 = Part.makeLine(pch0,pch1)
4586
      edgech1 = Part.makeLine(pch1,pch2)
4587
      edgech2 = Part.makeLine(pch2,pch3)
4588
      edgech3 = Part.makeLine(pch3,pch0)
4589

4590
      Wch_wire = Part.Wire([edgech0, edgech1, edgech2, edgech3])
4591
      cham_Face =Part.Face(Wch_wire)
4592
      cham_Solid = cham_Face.revolve(Base.Vector(0.0,0.0,-(rotations-1)*P),Base.Vector(0.0,0.0,1.0),360)
4593
      #Part.show(cham_Solid)
4594
      #Part.show(Wch_wire)
4595

4596
      rawTopShell = Part.Shell(TheFaces)
4597
      topShell = rawTopShell.common(cham_Solid)
4598

4599
      # Making a Cutter for the cham face
4600
      commonbox = Part.makeBox(d+4.0*P, d+4.0*P, 2.0*P)
4601
      commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-2.0*P))
4602
      #Part.show(commonbox)
4603

4604
      cutterShell = rawTopShell.common(commonbox)
4605
      bot_edges =[]
4606
      bot_z =  1.0e-5 -2.0*P
4607

4608
      for kante in cutterShell.Edges:
4609
         if (kante.Vertexes[0].Point.z<=bot_z) and (kante.Vertexes[1].Point.z<=bot_z):
4610
            bot_edges.append(kante)
4611
            # Part.show(kante)
4612
      bot_wire = Part.Wire(Part.__sortEdges__(bot_edges))
4613

4614
      bot_face = Part.Face(bot_wire)
4615
      bot_face.reverse()
4616
      t_face = bot_face.copy()
4617
      t_face.translate(Base.Vector(0.0, 0.0, 2.0*P))
4618
      cutterFaces = cutterShell.Faces
4619
      cutterFaces.append(bot_face.Faces[0])
4620
      cutterFaces.append(t_face.Faces[0])
4621
      cutShell = Part.Shell(cutterFaces)
4622
      chamFcutter = Part.Solid(cutShell)
4623

4624
      #Part.show(chamFcutter)
4625
      topCham = cham_Solid.Faces[0]
4626
      topCham = topCham.cut(chamFcutter)
4627

4628
      #Part.show(topCham)
4629
      TheFaces = [topCham.Faces[0]]
4630
      TheFaces.extend(topShell.Faces)
4631

4632
      for i in range(rotations-4):
4633
         TheShell.translate(FreeCAD.Vector(0.0, 0.0,- P))
4634
         for flaeche in TheShell.Faces:
4635
           TheFaces.append(flaeche)
4636

4637
    else:
4638
      commonbox = Part.makeBox(d+4.0*P, d+4.0*P, 3.0*P)
4639
      commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-(3.0)*P))
4640
      topShell = TheShell.common(commonbox)
4641
      top_edges =[]
4642
      top_z =  -1.0e-5
4643

4644
      for kante in topShell.Edges:
4645
         if (kante.Vertexes[0].Point.z>=top_z) and (kante.Vertexes[1].Point.z>=top_z):
4646
            top_edges.append(kante)
4647
            # Part.show(kante)
4648
      top_wire = Part.Wire(Part.__sortEdges__(top_edges))
4649
      top_face = Part.Face(top_wire)
4650

4651
      TheFaces = [top_face.Faces[0]]
4652
      TheFaces.extend(topShell.Faces)
4653

4654
      for i in range(rotations-2):
4655
         TheShell.translate(FreeCAD.Vector(0.0, 0.0,- P))
4656
         for flaeche in TheShell.Faces:
4657
           TheFaces.append(flaeche)
4658

4659
    #FreeCAD.Console.PrintMessage("Base-Shell: " + str(i) + "\n")
4660
    # Make separate faces for the tip of the screw
4661
    botFaces = []
4662
    for i in range(rotations-2, rotations, 1):
4663
       TheShell.translate(FreeCAD.Vector(0.0, 0.0,- P))
4664

4665
       for flaeche in TheShell.Faces:
4666
         botFaces.append(flaeche)
4667
    #FreeCAD.Console.PrintMessage("Bottom-Shell: " + str(i) + "\n")
4668

4669
    if da is not None:
4670
      # points for chamfer: common-Method
4671
      pch0 =  (da/2-cham_i_delta, 0.0, -(rotations)*P + cham_i) # bottom chamfer
4672
      pch1 =  (da/2, 0.0, -(rotations)*P)  #
4673
      pch2 =  (da/2, 0.0, -(rotations)*P + 3.0*P)
4674
      pch3 =  (da/2-cham_i_delta, 0.0, -(rotations)*P + 3.0*P)
4675
      #pch4 =  (r-2.0*cham_i_delta, 0.0, -(rotations)*P + 3.0*P)
4676

4677
      edgech0 = Part.makeLine(pch0,pch1)
4678
      edgech1 = Part.makeLine(pch1,pch2)
4679
      edgech2 = Part.makeLine(pch2,pch3)
4680
      edgech3 = Part.makeLine(pch3,pch0)
4681

4682
      Wch_wire = Part.Wire([edgech0, edgech1, edgech2, edgech3])
4683
      cham_Face =Part.Face(Wch_wire)
4684
      cham_Solid = cham_Face.revolve(Base.Vector(0.0,0.0,-(rotations-1)*P),Base.Vector(0.0,0.0,1.0),360)
4685
      #Part.show(cham_Solid)
4686
      #Part.show(Wch_wire)
4687

4688
      BotShell = Part.Shell(botFaces)
4689
      #Part.show(BotShell)
4690
      chamFcutter.translate(FreeCAD.Vector(0.0, 0.0,-(rotations-1)*P))
4691
      #Part.show(chamFcutter)
4692

4693

4694
      BotShell = BotShell.common(cham_Solid)
4695
      #Part.show(BotShell)
4696

4697
      cham_face = cham_Solid.Faces[0]
4698
      cham_face = cham_face.cut(chamFcutter)
4699
      #Part.show(cham_face)
4700

4701
      for flaeche in BotShell.Faces:
4702
        TheFaces.append(flaeche)
4703
      if da is not None:
4704
        TheFaces.append(cham_face.Faces[0])
4705
      else:
4706
        TheFaces.append(bot_face)
4707
      TheShell = Part.Shell(TheFaces)
4708

4709
      #print self.Tuner, " ", TheShell.ShapeType, " ", TheShell.isValid(), " hrots: ", halfrots_int, " Shellpunkte: ", len(TheShell.Vertexes)
4710

4711
      return TheShell
4712

4713
    else: # make of screw tap
4714
      #FreeCAD.Console.PrintMessage("without chamfer: " + str(i) + "\n")
4715

4716
      commonbox = Part.makeBox(d+4.0*P, d+4.0*P, 3.0*P)
4717
      commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-(rotations)*P+bot_off))
4718
      #commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-(rotations+3)*P+bot_off))
4719
      #Part.show(commonbox)
4720

4721
      BotShell = Part.Shell(botFaces)
4722
      #Part.show(BotShell)
4723

4724
      BotShell = BotShell.common(commonbox)
4725
      #BotShell = BotShell.cut(commonbox)
4726
      bot_edges =[]
4727
      bot_z =  1.0e-5 -(rotations)*P + bot_off
4728

4729
      for kante in BotShell.Edges:
4730
         if (kante.Vertexes[0].Point.z<=bot_z) and (kante.Vertexes[1].Point.z<=bot_z):
4731
            bot_edges.append(kante)
4732
            # Part.show(kante)
4733
      bot_wire = Part.Wire(Part.__sortEdges__(bot_edges))
4734

4735
      bot_face = Part.Face(bot_wire)
4736
      bot_face.reverse()
4737

4738
      for flaeche in BotShell.Faces:
4739
        TheFaces.append(flaeche)
4740
      if da is not None:
4741
        raise NotImplementedError('da must be None')
4742
        # TODO: Fix cham_Shell undefined.
4743
        for flaeche in cham_Shell.Faces:
4744
          TheFaces.append(flaeche)
4745
      else:
4746
        TheFaces.append(bot_face)
4747
      TheShell = Part.Shell(TheFaces)
4748
      TheSolid = Part.Solid(TheShell)
4749

4750
      #print self.Tuner, " ", TheShell.ShapeType, " ", TheShell.isValid(), " hrots: ", halfrots_int, " Shellpunkte: ", len(TheShell.Vertexes)
4751

4752
      return TheSolid
4753

4754
  def makeIso4032(self, SType='ISO4032', ThreadType='M6'):
4755
    """ISO 4032 Hex-nut and 4033 Hex-nut"""
4756
    dia = get_diameter(ThreadType)
4757
    if SType == 'ISO4032':
4758
      # P, c, damax,  dw,    e,     m,   mw,   s_nom
4759
      P, c, da, dw, e, m, mw, s = iso4032def[ThreadType]
4760
    if SType == 'ISO4033':
4761
      # P, c, damax,  dw,    e,     m,   mw,   s_nom
4762
      P, c, da, dw, e, m, mw, s = iso4033def[ThreadType]
4763
    if SType == 'ISO4035':
4764
      # P, c, damax,  dw,    e,     m,   mw,   s_nom
4765
      P, c, da, dw, e, m, mw, s = iso4035def[ThreadType]
4766

4767
    residue, turns = math.modf(m/P)
4768
    #halfturns = 2*int(turns)
4769

4770
    if residue > 0.0:
4771
      turns += 1.0
4772
      #halfturns = halfturns +2
4773
    #offSet = r - a
4774

4775
    sqrt2_ = 1.0/math.sqrt(2.0)
4776
    cham = (e-s)*math.sin(math.radians(15)) # needed for chamfer at nut top
4777
    H=P*math.cos(math.radians(30)) # Gewindetiefe H
4778
    cham_i_delta = da/2.0 - (dia/2.0-H*5.0/8.0)
4779
    cham_i = cham_i_delta * math.tan(math.radians(15.0))
4780

4781

4782
    if self.rThread:
4783
      Pnt0 = Base.Vector(da/2.0-2.0*cham_i_delta,0.0,m - 2.0*cham_i)
4784
      Pnt7 = Base.Vector(da/2.0-2.0*cham_i_delta,0.0,0.0+ 2.0*cham_i)
4785
    else:
4786
      Pnt0 = Base.Vector(dia/2.0-H*5.0/8.0,0.0,m - cham_i)
4787
      Pnt7 = Base.Vector(dia/2.0-H*5.0/8.0,0.0,0.0+ cham_i)
4788

4789
    Pnt1 = Base.Vector(da/2.0,0.0,m)
4790
    Pnt2 = Base.Vector(s/2.0,0.0,m)
4791
    Pnt3 = Base.Vector(s/math.sqrt(3.0),0.0,m-cham)
4792
    Pnt4 = Base.Vector(s/math.sqrt(3.0),0.0,cham)
4793
    Pnt5 = Base.Vector(s/2.0,0.0,0.0)
4794
    Pnt6 = Base.Vector(da/2.0,0.0,0.0)
4795

4796
    edge0 = Part.makeLine(Pnt0,Pnt1)
4797
    edge1 = Part.makeLine(Pnt1,Pnt2)
4798
    edge2 = Part.makeLine(Pnt2,Pnt3)
4799
    edge3 = Part.makeLine(Pnt3,Pnt4)
4800
    edge4 = Part.makeLine(Pnt4,Pnt5)
4801
    edge5 = Part.makeLine(Pnt5,Pnt6)
4802
    edge6 = Part.makeLine(Pnt6,Pnt7)
4803
    edge7 = Part.makeLine(Pnt7,Pnt0)
4804

4805
    # create cutting tool for hexagon head
4806
    # Parameters s, k, outer circle diameter =  e/2.0+10.0
4807
    extrude = self.makeHextool(s, m, s*2.0)
4808

4809
    aWire=Part.Wire([edge0,edge1,edge2,edge3,edge4,edge5,edge6,edge7])
4810
    # Part.show(aWire)
4811
    aFace =Part.Face(aWire)
4812
    head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
4813
    #Part.show(head)
4814

4815
    # Part.show(extrude)
4816
    nut = head.cut(extrude)
4817
    # Part.show(nut)
4818

4819
    if self.rThread:
4820
      '''
4821
      threadCutter = self.makeInnerThread(dia, P, int(turns), None, m)
4822
      # Part.show(threadCutter)
4823
      threadCutter.translate(Base.Vector(0.0, 0.0,turns*P))
4824
      nut = nut.cut(threadCutter)
4825
      '''
4826
      nutFaces = [nut.Faces[2]]
4827
      for i in range(4,25):
4828
        nutFaces.append(nut.Faces[i])
4829

4830

4831
      threadShell = self.makeInnerThread_2(dia, P, int(turns), da, m)
4832
      threadShell.translate(Base.Vector(0.0, 0.0,turns*P))
4833
      #Part.show(threadShell)
4834
      nutFaces.extend(threadShell.Faces)
4835

4836
      nutShell = Part.Shell(nutFaces)
4837
      nut = Part.Solid(nutShell)
4838
      #Part.show(nutShell)
4839

4840
    return nut
4841

4842
  def makeEN1661(self, ThreadType='M8'):
4843
    """EN 1661 Hexagon nuts with flange
4844

4845
    chamfer at top of hexagon is wrong = more than 30°
4846
    """
4847
    dia = get_diameter(ThreadType)
4848
    P, da, c, dc, dw, e, m, mw, r1, s = en1661def[ThreadType]
4849

4850
    residue, turns = math.modf(m/P)
4851
    #halfturns = 2*int(turns)
4852

4853
    if residue > 0.0:
4854
      turns += 1.0
4855

4856
    #FreeCAD.Console.PrintMessage("the nut with isoEN1661: " + str(c) + "\n")
4857
    cham = s*(2.0/math.sqrt(3.0)-1.0)*math.sin(math.radians(25)) # needed for chamfer at head top
4858

4859
    sqrt2_ = 1.0/math.sqrt(2.0)
4860

4861
    # Flange is made with a radius of c
4862
    beta = math.radians(25.0)
4863
    tan_beta = math.tan(beta)
4864

4865
    # Calculation of Arc points of flange edge using dc and c
4866
    arc1_x = dc/2.0 - c/2.0 + (c/2.0)*math.sin(beta)
4867
    arc1_z = c/2.0 + (c/2.0)*math.cos(beta)
4868

4869
    hF = arc1_z + (arc1_x -s/2.0) * tan_beta  # height of flange at center
4870

4871
    #kmean = arc1_z + (arc1_x - s/math.sqrt(3.0)) * tan_beta + mw * 1.1 + cham
4872
    #kmean = k * 0.95
4873

4874

4875
    #Hex-Head Points
4876
    #FreeCAD.Console.PrintMessage("the nut with kmean: " + str(m) + "\n")
4877
    PntH0 = Base.Vector(da/2.0,0.0,m)
4878
    PntH1 = Base.Vector(s/2.0,0.0,m)
4879
    edgeH1 = Part.makeLine(PntH0,PntH1)
4880

4881
    hWire=Part.Wire([edgeH1])
4882
    topShell = hWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
4883
    #Part.show(hWire)
4884
    #Part.show(topShell)
4885

4886
    # create a cutter ring to generate the chamfer at the top of the hex
4887
    chamHori = s/math.sqrt(3.0) - s/2.0
4888
    PntC1 = Base.Vector(s/2.0-chamHori,0.0,m+m)
4889
    PntC2 = Base.Vector(s/math.sqrt(3.0)+chamHori,0.0,m+m)
4890
    PntC3 = Base.Vector(s/2.0-chamHori,0.0,m+cham)
4891
    PntC4 = Base.Vector(s/math.sqrt(3.0)+chamHori,0.0,m-cham-cham)   #s/math.sqrt(3.0)
4892
    edgeC1 = Part.makeLine(PntC3, PntC1)
4893
    edgeC2 = Part.makeLine(PntC1, PntC2)
4894
    edgeC3 = Part.makeLine(PntC2, PntC4)
4895
    edgeC4 = Part.makeLine(PntC4, PntC3)
4896
    cWire = Part.Wire([edgeC4, edgeC1, edgeC2, edgeC3])
4897
    cFace = Part.Face(cWire)
4898
    chamCut = cFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
4899
    #Part.show(cWire)
4900
    #Part.show(chamCut)
4901

4902

4903
    # create hexagon
4904
    mhex=Base.Matrix()
4905
    mhex.rotateZ(math.radians(60.0))
4906
    polygon = []
4907
    vhex=Base.Vector(s/math.sqrt(3.0),0.0,m)
4908
    for i in range(6):
4909
       polygon.append(vhex)
4910
       vhex = mhex.multiply(vhex)
4911
    polygon.append(vhex)
4912
    hexagon = Part.makePolygon(polygon)
4913
    hexFace = Part.Face(hexagon)
4914
    solidHex = hexFace.extrude(Base.Vector(0.0,0.0,c-m))
4915
    #Part.show(solidHex)
4916
    hexCham = solidHex.cut(chamCut)
4917
    #Part.show(hexCham)
4918

4919
    topFaces = topShell.Faces
4920

4921
    topFaces.append(hexCham.Faces[1])
4922
    topFaces.append(hexCham.Faces[2])
4923
    topFaces.append(hexCham.Faces[8])
4924
    topFaces.append(hexCham.Faces[13])
4925
    topFaces.append(hexCham.Faces[14])
4926
    topFaces.append(hexCham.Faces[12])
4927
    topFaces.append(hexCham.Faces[6])
4928

4929
    hexFaces = [hexCham.Faces[5], hexCham.Faces[11], hexCham.Faces[10]]
4930
    hexFaces.extend([hexCham.Faces[9], hexCham.Faces[3], hexCham.Faces[0]])
4931
    hexShell = Part.Shell(hexFaces)
4932

4933

4934
    H=P*math.cos(math.radians(30)) # Gewindetiefe H
4935
    cham_i_delta = da/2.0 - (dia/2.0-H*5.0/8.0)
4936
    cham_i = cham_i_delta * math.tan(math.radians(15.0))
4937

4938
    # Center of flange:
4939
    Pnt0 = Base.Vector(0.0,0.0,hF)
4940
    Pnt1 = Base.Vector(s/2.0,0.0,hF)
4941

4942
    # arc edge of flange:
4943
    Pnt2 = Base.Vector(arc1_x,0.0,arc1_z)
4944
    Pnt3 = Base.Vector(dc/2.0,0.0,c/2.0)
4945
    Pnt4 = Base.Vector((dc-c)/2.0,0.0,0.0)
4946
    Pnt5 = Base.Vector(da/2.0,0.0,0.0)     #start of fillet between flat and thread
4947

4948
    edge1 = Part.makeLine(Pnt0,Pnt1)
4949
    edge2 = Part.makeLine(Pnt1,Pnt2)
4950
    edge3 = Part.Arc(Pnt2,Pnt3,Pnt4).toShape()
4951
    edge4 = Part.makeLine(Pnt4,Pnt5)
4952

4953
    # make a cutter for the hexShell
4954
    PntHC1 = Base.Vector(0.0,0.0,arc1_z)
4955
    PntHC2 = Base.Vector(0.0,0.0,0.0)
4956

4957
    edgeHC1 = Part.makeLine(Pnt2,PntHC1)
4958
    edgeHC2 = Part.makeLine(PntHC1,PntHC2)
4959
    edgeHC3 = Part.makeLine(PntHC2,Pnt0)
4960

4961
    HCWire = Part.Wire([edge2, edgeHC1, edgeHC2, edgeHC3, edge1])
4962
    HCFace = Part.Face(HCWire)
4963
    hex2Cut = HCFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
4964

4965
    hexShell = hexShell.cut(hex2Cut)
4966
    #Part.show(hexShell)
4967

4968
    topFaces.extend(hexShell.Faces)
4969

4970
    if self.rThread:
4971
      aWire=Part.Wire([edge2,edge3,edge4])
4972
      boltIndex = 3
4973

4974
    else:
4975
      Pnt7 = Base.Vector(dia/2.0-H*5.0/8.0,0.0,m - cham_i)
4976
      Pnt6 = Base.Vector(dia/2.0-H*5.0/8.0,0.0,0.0+ cham_i)
4977
      edge5 = Part.makeLine(Pnt5,Pnt6)
4978
      edge6 = Part.makeLine(Pnt6,Pnt7)
4979
      edge7 = Part.makeLine(Pnt7,PntH0)
4980
      aWire=Part.Wire([edge2,edge3,edge4,edge5,edge6,edge7])
4981
      boltIndex = 6
4982

4983

4984
    #aFace =Part.Face(aWire)
4985
    #Part.show(aWire)
4986
    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
4987
    #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
4988
    #Part.show(headShell)
4989
    chamFace = headShell.Faces[0].cut(solidHex)
4990
    #Part.show(chamFace)
4991

4992
    topFaces.append(chamFace.Faces[0])
4993
    for i in range(1,boltIndex):
4994
      topFaces.append(headShell.Faces[i])
4995

4996

4997
    if self.rThread:
4998
      #rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
4999
      #rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
5000
      threadShell = self.makeInnerThread_2(dia, P, int(turns), da, m)
5001
      threadShell.translate(Base.Vector(0.0, 0.0,turns*P))
5002
      #Part.show(threadShell)
5003
      for tFace in threadShell.Faces:
5004
        topFaces.append(tFace)
5005
      headShell = Part.Shell(topFaces)
5006
      screw = Part.Solid(headShell)
5007
    else:
5008
      screwShell = Part.Shell(topFaces)
5009
      screw = Part.Solid(screwShell)
5010

5011
    return screw
5012

5013
  def makeScrewTap(self, ThreadType ='M6',l=25.0):
5014
    """ISO 7380-1, ISO 7380-2, DIN 967
5015

5016
    make ISO 7380-1 Button head Screw
5017
    make ISO 7380-2 Button head Screw with collar
5018
    make DIN 967 cross recessed pan head Screw with collar
5019
    """
5020
    dia = get_diameter(ThreadType)
5021

5022
    P, tunIn, tunEx  = tuningTable[ThreadType]
5023

5024
    residue, turns = math.modf((l)/P)
5025
    turns += 1.0
5026
    #FreeCAD.Console.PrintMessage("ScrewTap residue: " + str(residue) + " turns: " + str(turns) + "\n")
5027

5028

5029
    if self.rThread:
5030
      screwTap = self.makeInnerThread_2(dia, P, int(turns), None, 0.0)
5031
      screwTap.translate(Base.Vector(0.0, 0.0,(1-residue)*P))
5032
    else:
5033
      H=P*math.cos(math.radians(30)) # Gewindetiefe H
5034
      r=dia/2.0
5035

5036
      # points for inner thread profile
5037
      Pnt0 = Base.Vector(0.0,0.0,(1-residue)*P)
5038
      Pnt1 = Base.Vector(r-H*5.0/8.0,0.0,(1-residue)*P)
5039
      Pnt2 = Base.Vector(r-H*5.0/8.0,0.0,-l)
5040
      Pnt3 = Base.Vector(0.0,0.0,-l)
5041

5042
      edge1 = Part.makeLine(Pnt0,Pnt1)
5043
      edge2 = Part.makeLine(Pnt1,Pnt2)
5044
      edge3 = Part.makeLine(Pnt2,Pnt3)
5045
      aWire=Part.Wire([edge1,edge2,edge3])
5046
      headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
5047
      screwTap = Part.Solid(headShell)
5048

5049
    return screwTap
5050

5051
  def cutChamfer(self, dia_cC, P_cC, l_cC):
5052
    cham_t = P_cC*math.sqrt(3.0)/2.0*17.0/24.0
5053
    PntC0 = Base.Vector(0.0,0.0,-l_cC)
5054
    PntC1 = Base.Vector(dia_cC/2.0-cham_t,0.0,-l_cC)
5055
    PntC2 = Base.Vector(dia_cC/2.0+cham_t,0.0,-l_cC+cham_t+cham_t)
5056
    PntC3 = Base.Vector(dia_cC/2.0+cham_t,0.0,-l_cC-P_cC-cham_t)
5057
    PntC4 = Base.Vector(0.0,0.0,-l_cC-P_cC-cham_t)
5058

5059
    edgeC1 = Part.makeLine(PntC0,PntC1)
5060
    edgeC2 = Part.makeLine(PntC1,PntC2)
5061
    edgeC3 = Part.makeLine(PntC2,PntC3)
5062
    edgeC4 = Part.makeLine(PntC3,PntC4)
5063
    edgeC5 = Part.makeLine(PntC4,PntC0)
5064
    CWire=Part.Wire([edgeC1,edgeC2,edgeC3,edgeC4,edgeC5])
5065
    #Part.show(CWire)
5066
    CFace =Part.Face(CWire)
5067
    cyl = CFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
5068
    return cyl
5069

5070
  def makeCross_H3(self, CrossType = '2', m = 6.9, h = 0.0):
5071
    """Cross recess type H
5072

5073
    m = diameter of cross at top of screw at reference level for penetration depth
5074
    """
5075
    b, e_mean, g, f_mean, r, t1, alpha, beta = iso4757def[CrossType]
5076

5077
    rad265 = math.radians(26.5)
5078
    rad28 = math.radians(28.0)
5079
    tg = (m-g)/2.0/math.tan(rad265) # depth at radius of g
5080
    t_tot = tg + g/2.0 * math.tan(rad28) # total depth
5081
    #FreeCAD.Console.PrintMessage("Cross H3: " + str(b) + "\n")
5082

5083
    # print 'tg: ', tg,' t_tot: ', t_tot
5084
    hm = m / 4.0
5085
    hmc = m / 2.0
5086
    rmax = m / 2.0 + hm*math.tan(rad265)
5087

5088
    Pnt0 = Base.Vector(0.0,0.0,hm)
5089
    Pnt1 = Base.Vector(rmax,0.0,hm)
5090
    Pnt3 = Base.Vector(0.0,0.0,0.0)
5091
    Pnt4 = Base.Vector(g/2.0,0.0,-tg)
5092
    Pnt5 = Base.Vector(0.0,0.0,-t_tot)
5093

5094
    edge1 = Part.makeLine(Pnt0,Pnt1)
5095
    edge3 = Part.makeLine(Pnt1,Pnt4)
5096
    edge4 = Part.makeLine(Pnt4,Pnt5)
5097
    # FreeCAD.Console.PrintMessage("Edges made Pnt1: " + str(Pnt1) + "\n")
5098

5099
    aWire=Part.Wire([edge1,edge3,edge4])
5100
    crossShell = aWire.revolve(Pnt3,Base.Vector(0.0,0.0,1.0),360)
5101
    #FreeCAD.Console.PrintMessage("Peak-wire revolved: " + str(e_mean) + "\n")
5102
    cross = Part.Solid(crossShell)
5103
    #Part.show(cross)
5104

5105
    # the need to cut 4 corners out of the above shape.
5106
    # Definition of corner
5107
    # The angles 92 degrees and alpha are defined on a plane which has
5108
    # an angle of beta against our coordinate system.
5109
    # The projected angles are needed for easier calculation!
5110
    rad_alpha = math.radians(alpha/2.0)
5111
    rad92 = math.radians(92.0/2.0)
5112
    rad_beta = math.radians(beta)
5113

5114
    rad_alpha_p = math.atan(math.tan(rad_alpha)/math.cos(rad_beta))
5115
    rad92_p = math.atan(math.tan(rad92)/math.cos(rad_beta))
5116

5117
    tb = tg + (g-b)/2.0 * math.tan(rad28) # depth at dimension b
5118
    rbtop = b/2.0 + (hmc + tb)*math.tan(rad_beta) # radius of b-corner at hm
5119
    rbtot = b/2.0 - (t_tot - tb)*math.tan(rad_beta) # radius of b-corner at t_tot
5120

5121
    dre = e_mean/2.0 / math.tan(rad_alpha_p)  # delta between corner b and corner e in x direction
5122
    #FreeCAD.Console.PrintMessage("delta calculated: " + str(dre) + "\n")
5123

5124
    dx = m/2.0 * math.cos(rad92_p)
5125
    dy = m/2.0 * math.sin(rad92_p)
5126

5127
    PntC0 = Base.Vector(rbtop,0.0,hmc)
5128
    PntC1 = Base.Vector(rbtot,0.0,-t_tot)
5129
    PntC2 = Base.Vector(rbtop+dre,+e_mean/2.0,hmc)
5130
    PntC3 = Base.Vector(rbtot+dre,+e_mean/2.0,-t_tot)
5131
    PntC4 = Base.Vector(rbtop+dre,-e_mean/2.0,hmc)
5132
    PntC5 = Base.Vector(rbtot+dre,-e_mean/2.0,-t_tot)
5133

5134
    PntC6 = Base.Vector(rbtop+dre+dx,+e_mean/2.0+dy,hmc)
5135
    #PntC7 = Base.Vector(rbtot+dre+dx,+e_mean/2.0+dy,-t_tot)
5136
    PntC7 = Base.Vector(rbtot+dre+2.0*dx,+e_mean+2.0*dy,-t_tot)
5137
    PntC8 = Base.Vector(rbtop+dre+dx,-e_mean/2.0-dy,hmc)
5138
    #PntC9 = Base.Vector(rbtot+dre+dx,-e_mean/2.0-dy,-t_tot)
5139
    PntC9 = Base.Vector(rbtot+dre+2.0*dx,-e_mean-2.0*dy,-t_tot)
5140

5141
    #wire_hm = Part.makePolygon([PntC0,PntC2,PntC6,PntC8,PntC4,PntC0])
5142
    #face_hm =Part.Face(wire_hm)
5143
    #Part.show(face_hm)
5144

5145
    wire_t_tot = Part.makePolygon([PntC1,PntC3,PntC7,PntC9,PntC5,PntC1])
5146
    # Part.show(wire_t_tot)
5147
    edgeC1 = Part.makeLine(PntC0,PntC1)
5148
    #FreeCAD.Console.PrintMessage("edgeC1 mit PntC9" + str(PntC9) + "\n")
5149

5150
    makeSolid=True
5151
    isFrenet=False
5152
    corner = Part.Wire(edgeC1).makePipeShell([wire_t_tot],makeSolid,isFrenet)
5153
    #Part.show(corner)
5154

5155
    rot_axis = Base.Vector(0.,0.,1.0)
5156
    sin_res = math.sin(math.radians(90)/2.0)
5157
    cos_res = math.cos(math.radians(90)/2.0)
5158
    rot_axis.multiply(-sin_res) # Calculation of Quaternion-Elements
5159
    #FreeCAD.Console.PrintMessage("Quaternion-Elements" + str(cos_res) + "\n")
5160

5161
    pl_rot = FreeCAD.Placement()
5162
    pl_rot.Rotation = (rot_axis.x,rot_axis.y,rot_axis.z,cos_res) #Rotation-Quaternion 90° z-Axis
5163

5164
    crossShell = crossShell.cut(corner)
5165
    # Part.show(crossShell)
5166
    cutplace = corner.Placement
5167

5168
    cornerFaces = []
5169
    cornerFaces.append(corner.Faces[0])
5170
    cornerFaces.append(corner.Faces[1])
5171
    cornerFaces.append(corner.Faces[3])
5172
    cornerFaces.append(corner.Faces[4])
5173

5174
    cornerShell = Part.Shell(cornerFaces)
5175
    cornerShell = cornerShell.common(cross)
5176
    addPlace = cornerShell.Placement
5177

5178
    crossFaces = cornerShell.Faces
5179

5180
    for i in range(3):
5181
      #cutplace.Rotation = pl_rot.Rotation.multiply(corner.Placement.Rotation)
5182
      corner.Placement.Rotation = pl_rot.Rotation.multiply(corner.Placement.Rotation)
5183
      crossShell = crossShell.cut(corner)
5184
      #addPlace.Rotation = pl_rot.Rotation.multiply(cornerShell.Placement.Rotation)
5185
      cornerShell.Placement.Rotation = pl_rot.Rotation.multiply(cornerShell.Placement.Rotation)
5186
      for coFace in cornerShell.Faces:
5187
        crossFaces.append(coFace)
5188

5189
    # Part.show(crossShell)
5190
    for i in range(1,6):
5191
      crossFaces.append(crossShell.Faces[i])
5192

5193
    crossShell0 = Part.Shell(crossFaces)
5194

5195
    crossFaces.append(crossShell.Faces[0])
5196
    crossShell = Part.Shell(crossFaces)
5197

5198
    cross = Part.Solid(crossShell)
5199

5200

5201
    #FreeCAD.Console.PrintMessage("Placement: " + str(pl_rot) + "\n")
5202

5203
    cross.Placement.Base = Base.Vector(0.0,0.0,h)
5204
    crossShell0.Placement.Base = Base.Vector(0.0,0.0,h)
5205
    #Part.show(crossShell0)
5206
    #Part.show(cross)
5207
    return cross, crossShell0
5208

5209
  def makeAllen2(self, s_a=3.0, t_a=1.5, h_a=2.0):
5210
    """Allen recess cutting tool
5211

5212
    Parameters used: s_mean, k, t_min, dk
5213
    """
5214
    # h_a  top height location of cutting tool
5215
    # s_a hex width
5216
    # t_a dept of the allen
5217
    # dk_a diameter not needed anymore
5218

5219
    e_cham = 2.0 * s_a / math.sqrt(3.0)
5220
    depth = s_a / 3.0
5221
    #FreeCAD.Console.PrintMessage("allen tool: " + str(s_a) + "\n")
5222

5223
    # Points for an arc at the peak of the cone
5224
    rCone = e_cham/4.0
5225
    hyp = (depth*math.sqrt(e_cham**2/depth**2+1.0)*rCone)/e_cham
5226
    radAlpha = math.atan(e_cham/depth)
5227
    radBeta = math.pi/2.0 - radAlpha
5228
    zrConeCenter=hyp - depth -t_a
5229
    xArc1=math.sin(radBeta)*rCone
5230
    zArc1=zrConeCenter - math.cos(radBeta)*rCone
5231
    xArc2=math.sin(radBeta/2.0)*rCone
5232
    zArc2=zrConeCenter - math.cos(radBeta/2.0)*rCone
5233
    zArc3 = zrConeCenter - rCone
5234

5235
    # The round part of the cutting tool, we need for the allen hex recess
5236
    PntH1 = Base.Vector(0.0,0.0,-t_a-depth-depth)
5237
    PntH2 = Base.Vector(e_cham,0.0,-t_a-depth-depth)
5238
    PntH3 = Base.Vector(e_cham,0.0,-t_a+depth)
5239
    PntH4 = Base.Vector(0.0,0.0,-t_a-depth)
5240

5241
    PntA1 = Base.Vector(xArc1,0.0,zArc1)
5242
    PntA2 = Base.Vector(xArc2,0.0,zArc2)
5243
    PntA3 = Base.Vector(0.0,0.0,zArc3)
5244

5245
    edgeA1 = Part.Arc(PntA1,PntA2,PntA3).toShape()
5246

5247
    edgeH1 = Part.makeLine(PntH1,PntH2)
5248
    edgeH2 = Part.makeLine(PntH2,PntH3)
5249
    edgeH3 = Part.makeLine(PntH3,PntA1)
5250
    edgeH4 = Part.makeLine(PntA3,PntH1)
5251

5252
    hWire=Part.Wire([edgeH1,edgeH2,edgeH3,edgeA1,edgeH4])
5253
    # Part.show(hWire)
5254
    hFace =Part.Face(hWire)
5255
    roundtool = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
5256

5257
    # create hexagon
5258
    mhex=Base.Matrix()
5259
    mhex.rotateZ(math.radians(60.0))
5260
    polygon = []
5261
    vhex=Base.Vector(s_a/math.sqrt(3.0),0.0,1.0)
5262
    for i in range(6):
5263
       polygon.append(vhex)
5264
       vhex = mhex.multiply(vhex)
5265
    polygon.append(vhex)
5266
    hexagon = Part.makePolygon(polygon)
5267
    hexFace = Part.Face(hexagon)
5268
    solidHex = hexFace.extrude(Base.Vector(0.0,0.0,-1.0-t_a-depth*1.1))
5269
    allen = solidHex.cut(roundtool)
5270
    # Part.show(allen)
5271

5272
    allenFaces = [allen.Faces[0]]
5273
    for i in range(2,9):
5274
      allenFaces.append(allen.Faces[i])
5275
    allenShell = Part.Shell(allenFaces)
5276
    solidHex.Placement.Base = Base.Vector(0.0,0.0,h_a)
5277
    allenShell.Placement.Base = Base.Vector(0.0,0.0,h_a)
5278
    return solidHex, allenShell
5279

5280
  def makeIso10664_3(self,RType ='T20',t_hl=3.0, h_hl = 0):
5281
    """ISO 10664 Hexalobular internal driving feature for bolts and screws"""
5282
    # t_hl depth of the recess
5283
    # h_hl top height location of Cutting tool
5284
    A, B, Re = iso10664def[RType]
5285
    sqrt_3 = math.sqrt(3.0)
5286
    depth=A/4.0
5287
    offSet = 1.0
5288

5289
    # Chamfer cutter for the hexalobular recess
5290
    PntH1 = Base.Vector(0.0,0.0,-t_hl-depth-1.0)
5291
    #PntH2 = Base.Vector(A/2.0*1.02,0.0,-t_hl-depth-1.0)
5292
    #PntH3 = Base.Vector(A/2.0*1.02,0.0,-t_hl)
5293
    PntH2 = Base.Vector(A,0.0,-t_hl-depth-1.0)
5294
    PntH3 = Base.Vector(A,0.0,-t_hl+depth)
5295
    PntH4 = Base.Vector(0.0,0.0,-t_hl-depth)
5296

5297
    # Points for an arc at the peak of the cone
5298
    rCone = A/4.0
5299
    hyp = (depth*math.sqrt(A**2/depth**2+1.0)*rCone)/A
5300
    radAlpha = math.atan(A/depth)
5301
    radBeta = math.pi/2.0 - radAlpha
5302
    zrConeCenter=hyp - depth -t_hl
5303
    xArc1=math.sin(radBeta)*rCone
5304
    zArc1=zrConeCenter - math.cos(radBeta)*rCone
5305
    xArc2=math.sin(radBeta/2.0)*rCone
5306
    zArc2=zrConeCenter - math.cos(radBeta/2.0)*rCone
5307
    zArc3 = zrConeCenter - rCone
5308

5309
    PntA1 = Base.Vector(xArc1,0.0,zArc1)
5310
    PntA2 = Base.Vector(xArc2,0.0,zArc2)
5311
    PntA3 = Base.Vector(0.0,0.0,zArc3)
5312

5313
    edgeA1 = Part.Arc(PntA1,PntA2,PntA3).toShape()
5314

5315
    edgeH1 = Part.makeLine(PntH1,PntH2)
5316
    edgeH2 = Part.makeLine(PntH2,PntH3)
5317
    edgeH3 = Part.makeLine(PntH3,PntA1)
5318
    edgeH4 = Part.makeLine(PntA3,PntH1)
5319

5320
    hWire=Part.Wire([edgeH1,edgeH2,edgeH3,edgeA1])
5321
    cutShell = hWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
5322
    cutTool = Part.Solid(cutShell)
5323

5324

5325
    Ri = -((B+sqrt_3*(2.*Re-A))*B+(A-4.*Re)*A)/(4.*B-2.*sqrt_3*A+(4.*sqrt_3-8.)*Re)
5326
    #print '2nd  Ri last solution: ', Ri
5327
    beta=math.acos(A/(4*Ri+4*Re)-(2*Re)/(4*Ri+4*Re))-math.pi/6
5328
    #print 'beta: ', beta
5329
    Rh=(sqrt_3*(A/2.0-Re))/2.0
5330
    Re_x = A/2.0 - Re + Re*math.sin(beta)
5331
    Re_y = Re*math.cos(beta)
5332
    Ri_y = B/4.0
5333
    Ri_x = sqrt_3*B/4.0
5334

5335
    mhex=Base.Matrix()
5336
    mhex.rotateZ(math.radians(60.0))
5337
    hexlobWireList = []
5338

5339
    PntRe0=Base.Vector(Re_x,-Re_y,offSet)
5340
    PntRe1=Base.Vector(A/2.0,0.0,offSet)
5341
    PntRe2=Base.Vector(Re_x,Re_y,offSet)
5342
    edge0 = Part.Arc(PntRe0,PntRe1,PntRe2).toShape()
5343
    #Part.show(edge0)
5344
    hexlobWireList.append(edge0)
5345

5346
    PntRi = Base.Vector(Ri_x,Ri_y,offSet)
5347
    PntRi2 = mhex.multiply(PntRe0)
5348
    edge1 = Part.Arc(PntRe2,PntRi,PntRi2).toShape()
5349
    #Part.show(edge1)
5350
    hexlobWireList.append(edge1)
5351

5352
    for i in range(5):
5353
       PntRe1 = mhex.multiply(PntRe1)
5354
       PntRe2 = mhex.multiply(PntRe2)
5355
       edge0 = Part.Arc(PntRi2,PntRe1,PntRe2).toShape()
5356
       hexlobWireList.append(edge0)
5357
       PntRi = mhex.multiply(PntRi)
5358
       PntRi2 = mhex.multiply(PntRi2)
5359
       if i == 5:
5360
          edge1 = Part.Arc(PntRe2,PntRi,PntRe0).toShape()
5361
       else:
5362
          edge1 = Part.Arc(PntRe2,PntRi,PntRi2).toShape()
5363
       hexlobWireList.append(edge1)
5364
    hexlobWire=Part.Wire(hexlobWireList)
5365
    #Part.show(hWire)
5366

5367
    face=Part.Face(hexlobWire)
5368

5369
    # Extrude in z to create the cutting tool for the screw-head-face
5370
    Helo=face.extrude(Base.Vector(0.0,0.0,-t_hl-depth-offSet))
5371
    # Make the recess-shell for the screw-head-shell
5372

5373
    hexlob = Helo.cut(cutTool)
5374
    #Part.show(hexlob)
5375
    hexlobFaces = [hexlob.Faces[0]]
5376
    for i in range(2,15):
5377
      hexlobFaces.append(hexlob.Faces[i])
5378

5379
    hexlobShell = Part.Shell(hexlobFaces)
5380

5381
    hexlobShell.Placement.Base = Base.Vector(0.0,0.0,h_hl)
5382
    Helo.Placement.Base = Base.Vector(0.0,0.0,h_hl)
5383

5384
    return Helo, hexlobShell
5385

5386
  def setThreadType(self, TType = 'simple'):
5387
    self.simpThread = False
5388
    self.symThread = False
5389
    self.rThread = False
5390
    if TType == 'simple':
5391
      self.simpThread = True
5392
    if TType == 'symbol':
5393
      self.symThread = True
5394
    if TType == 'real':
5395
      self.rThread = True
5396

5397
  def setTuner(self, myTuner = 511):
5398
    self.Tuner = myTuner
5399

5400

5401
class ScrewMacro(object):
5402
  d = QtGui.QWidget()
5403
  d.ui = Ui_ScrewMaker()
5404
  d.ui.setupUi(d)
5405
  if __name__ == '__main__':
5406
    d.show()
5407

5408

5409
def main():
5410
  o = ScrewMacro()
5411

5412
if __name__ == '__main__':
5413
  main()
5414

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.