#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Macro to generate screws with FreeCAD.
Version 1.4 from 1st of September 2013
Version 1.5 from 23rd of December 2013
Corrected hex-heads above M12 not done.
Version 1.6 from 15th of March 2014
Added PySide support

Version 1.7 from April 2014
fixed bool type error. (int is not anymore accepted at linux)
fixed starting point of real thread at some screw types.

Version 1.8 from July 2014
first approach for a faster real thread

Version 1.9 / 2.0 July 2015
new calculation of starting point of thread
shell-based approach for screw generation
added:
ISO 14582 Hexalobular socket countersunk head screws, high head
ISO 14584 Hexalobular socket raised countersunk head screws
ISO 7380-2 Hexagon socket button head screws with collar
DIN 967 Cross recessed pan head screws with collar
ISO 4032 Hexagon nuts, Style 1
ISO 4033 Hexagon nuts, Style 2
ISO 4035 Hexagon thin nuts, chamfered
EN 1661 Hexagon nuts with flange
ISO 7094 definitions  Plain washers - Extra large series
ISO 7092 definitions  Plain washers - Small series
ISO 7093-1 Plain washer - Large series
Screw-tap to drill inner threads in parts with user defined length

ScrewMaker can now also used as a python module.
The following shows how to generate a screw from a python script:
  import screw_maker2_0

  threadDef = 'M3.5'
  o = screw_maker2_0.Screw()
  t = screw_maker2_0.Screw.setThreadType(o,'real')
  # Creates a Document-Object with label describing the screw
  d = screw_maker2_0.Screw.createScrew(o, 'ISO1207', threadDef, '20', 'real')

  # creates a shape in memory
  t = screw_maker2_0.Screw.setThreadType(o,'real')
  s = screw_maker1_9d.Screw.makeIso7046(o, 'ISO14582', threadDef, 40.0)
  Part.show(s)

Version 2.1 August 2015
added:
ISO 8676 Hexagon head screw with metric fine pitch thread

Version 2.2 May 2018
- Extend function "moveScrew" to check for Body and Part.
- Add Screw to Part if Body is in Part.
- Search for plane support face to get correct orientation
- fix failed hex-head

Version 2.3 Oct 2018
- fix missing function equal_vertex

to do: check ISO7380 usage of rs and rt, actual only rs is used
check chamfer angle on hexogon heads and nuts
***************************************************************************
*   Copyright (c) 2013, 2014, 2015 2018                                   *
*   Ulrich Brammer <ulrich1a[at]users.sourceforge.net>                    *
*                                                                         *
*   This file is a supplement to the FreeCAD CAx development system.      *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU Lesser General Public License (LGPL)    *
*   as published by the Free Software Foundation; either version 2 of     *
*   the License, or (at your option) any later version.                   *
*   for detail see the LICENCE text file.                                 *
*                                                                         *
*   This software is distributed in the hope that it will be useful,      *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU Library General Public License for more details.                  *
*                                                                         *
*   You should have received a copy of the GNU Library General Public     *
*   License along with this macro; if not, write to the Free Software     *
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
*   USA                                                                   *
*                                                                         *
***************************************************************************
"""
from __future__ import division

__Name__ = 'Screw Maker'
__Comment__ = 'Generate a screw'
__Author__ = "Ulrich Brammer <ulrich1a@users.sourceforge.net>"
__Version__ = '2.3.1'
__Date__ = '2018-10-22'
__License__ = 'LGPL2+'
__Web__ = 'http://freecadweb.org/wiki/Macro_screw_maker1_2'
__Wiki__ = 'http://freecadweb.org/wiki/Macro_screw_maker1_2'
__Icon__ = ''
__Help__ = 'Select the characteristics of the screw and click on the create button'
__Status__ = ''
__Requires__ = ''
__Communication__ = ''
__Files__ = ''

import math

import FreeCAD
import FreeCADGui
import Part
from FreeCAD import Base
import DraftVecUtils

try:
  from PySide import QtCore, QtGui
  #FreeCAD.Console.PrintMessage("PySide is used" + "\n")
except ImportError:
  #FreeCAD.Console.PrintMessage("PyQt4 is needed" + "\n")
  from PyQt4 import QtCore, QtGui

try:
  _encoding = QtGui.QApplication.UnicodeUTF8
  def tr(context, text):
    return QtGui.QApplication.translate(context, text, None, _encoding)
except AttributeError:
  def tr(context, text):
    return QtGui.QApplication.translate(context, text, None)

DEBUG = False # set to True to show debug messages; does not work, still todo.

debObject = None

# Diameters included in this library/macro.
# Some ISO-standards may include more diameters!
# Dictionary used for user messages
standard_diameters = {
  'ISO4017': ('M1.6', 'M64'), # ISO 4017 Hex-head-screw
  'ISO4014': ('M1.6', 'M64'), # ISO 4014 Hex-head-bolt
  'EN1662':  ('M5',   'M16'), # EN 1662 Hexagon bolts with flange, small series
  'EN1665':  ('M5',   'M20'), # EN 1665 Hexagon bolts with flange, heavy series
  'ISO8676': ('M8x1', 'M64x4'), # ISO 8676 Hexagon head screw with metric fine pitch thread
  'ISO4762': ('M1.6', 'M64'), # ISO 4762 Hexagon socket head cap screws
  'ISO2009': ('M1.6', 'M10'), # ISO 2009 Slotted countersunk flat head screws
  'ISO2010': ('M1.6', 'M10'), # ISO 2010 Slotted raised countersunk head screws
  'ISO1580': ('M1.6', 'M10'), # ISO 1580 Slotted pan head screws
  'ISO7045': ('M1.6', 'M10'), # ISO 7045 Pan head screws type H cross recess
  'ISO7046': ('M1.6', 'M10'),
  'ISO7047': ('M1.6', 'M10'),
  'ISO1207': ('M3',   'M10'), # ISO 1207 Slotted cheese head screws
  'ISO7048': ('M2.5', 'M8'),  # ISO 7048 Cross-recessed cheese head screws with type H cross recess
  'ISO7380-1':('M3',  'M16'), # ISO 7380 Hexagon socket button head screws
  'ISO7380-2':('M3',  'M16'), # ISO 7380 Hexagon socket button head screws with collar
  'DIN967'  :('M3',   'M8'),  # DIN 967 Cross recessed pan head screws with collar
  'ISO10642':('M3',   'M20'), # ISO 10642 Hexagon socket countersunk head screws
  'ISO14579':('M2',   'M20'), # ISO 14579 Hexalobular socket head cap screws
  'ISO14580':('M2',   'M10'), # ISO 14580 Hexalobular socket cheese head screws
  'ISO14581':('M2',   'M10'), # ISO 14581 Hexalobular socket countersunk flat head screws (to do!!)
  'ISO14582':('M3',   'M10'), # ISO 14582 Hexalobular socket countersunk head screws, high head
  'ISO14583':('M2',   'M10'), # ISO 14583 Hexalobular socket pan head screws
  'ISO14584':('M2',   'M10'), # ISO 14584 Hexalobular socket raised countersunk head screws
  'ISO7089': ('M1.6', 'M64'), # Washer
  'ISO7090': ('M5',   'M64'), # ISO 7090 definitions Plain washers, chamfered - Normal series
  'ISO7091': ('M1.6', 'M64'), # ISO 7091 definitions  Plain washer - Normal series Product Grade C
  'ISO7092': ('M1.6', 'M36'), # ISO 7092 definitions  Plain washers - Small series
  'ISO7093-1': ('M3', 'M36'), # ISO 7093-1 Plain washer - Large series
  'ISO7094': ('M5',   'M36'), # ISO 7094 definitions  Plain washers - Extra large series
  'ISO4032': ('M1.6', 'M64'), # ISO 4032 Hexagon nuts, Style 1
  'ISO4033': ('M5',   'M36'), # ISO 4033 Hexagon nuts, Style 2
  'ISO4035': ('M1.6', 'M64'), # ISO 4035 Hexagon thin nuts, chamfered
  'ISO4036': ('M1.6', 'M10'), # ISO 4035 Hexagon thin nuts, unchamfered, todo no function coded
  'EN1661':  ('M5',   'M20')} # EN 1661 Hexagon nuts with flange

# ISO 4017 Hex-head-screw
#           P,    c,  dw,    e,     k,   r,   s
iso4017head={
  'M1.6':  (0.35, 0.2, 2.9,  3.4,   1.1, 0.1,  3.2),
  'M2':    (0.40, 0.2, 3.7,  4.4,   1.4, 0.1,  4.0),
  'M2.5':  (0.45, 0.2, 4.6,  5.5,   1.7, 0.1,  5.0),
  'M3':    (0.5,  0.2, 5.2,  6.1,   2.0, 0.1,  5.5),
  '(M3.5)':(0.6,  0.2, 5.2,  6.6,   2.4, 0.1,  5.5),
  'M4':    (0.7,  0.2, 6.6,  7.7,   2.8, 0.2,  7.0),
  'M5':    (0.8,  0.2, 7.5,  8.9,   3.5, 0.2,  8.0),
  'M6':    (1.0,  0.2, 9.5,  11.05, 4.0, 0.25, 10.0),
  'M8':    (1.25, 0.3, 11.7, 14.5,  5.3, 0.25, 13.0),
  'M10':   (1.50, 0.3, 14.7, 17.9,  6.4, 0.4,  16.0),
  'M12':   (1.75, 0.3, 16.7, 20.1,  7.5, 0.6,  18.0),
  '(M14)': (2.00, 0.3, 20.5, 24.5,  8.8, 0.6,  22.0),
  'M16':   (2.00, 0.4, 22.4, 26.9, 10.0, 0.6,  24.0),
  '(M18)': (2.50, 0.4, 25.4, 30.2, 11.5, 0.6,  27.0),
  'M20':   (2.50, 0.4, 28.2, 33.7, 12.5, 0.8,  30.0),
  '(M22)': (2.50, 0.4, 31.8, 37.7, 14.0, 0.8,  34.0),
  'M24':   (3.00, 0.4, 33.7, 40.1, 15.0, 0.8,  36.0),
  '(M27)': (3.00, 0.4, 38.0, 45.2, 17.0, 1.0,  41.0),
  '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
  '(M33)': (3.50, 0.4, 46.6, 55.4, 21.0, 1.0,  50.0),
  '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
  '(M39)': (4.00, 0.5, 55.9, 66.5, 25.0, 1.0,  60.0),
  'M42':   (4.50, 0.7, 60.0, 71.3, 26.0, 1.2,  65.0),
  '(M45)': (4.50, 0.7, 64.7, 77.0, 28.0, 1.2,  70.0),
  'M48':   (5.00, 0.7, 69.5, 82.6, 30.0, 1.6,  75.0),
  '(M52)': (5.00, 0.7, 74.5, 88.3, 33.0, 1.6,  80.0),
  'M56':   (5.50, 0.7, 78.7, 93.6, 35.0, 2.0,  85.0),
  '(M60)': (5.50, 0.7, 82.7, 99.2, 38.0, 2.0,  90.0),
  'M64':   (6.00, 0.7, 88.2,104.9, 40.0, 2.0,  95.0)
  }

iso4017length = {
  '2': ( 1.8,  2.2),
  '3': ( 2.8,  3.2),
  '4': ( 3.76, 4.24),
  '5': ( 4.76, 5.24),
  '6': ( 5.76, 6.24),
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '14':(13.65, 14.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.4, 55.6),
  '60':(59.4, 60.6),
  '65':(64.4, 65.6),
  '70':(69.4, 70.6),
  '80':(79.4, 80.6),
  '100':(99.3, 100.7),
  '110':(109.3, 110.7),
  '120':(119.3, 120.7),
  '130':(129.2, 130.8),
  '140':(139.2, 130.8),
  '150':(149.2, 150.8),
  '160':(159.2, 160.8),
  '180':(179.2, 180.8),
  '200':(199.1, 200.9)
  }

# range of typical screw lengths
#    min_length,  max_length
iso4017range = {
  'M1.6':  ('2', '16'),
  'M2':    ('4', '20'),
  'M2.5':  ('5', '25'),
  'M3':    ('5', '30'),
  '(M3.5)':('8', '35'),
  'M4':    ('6', '40'),
  'M5':    ('8', '50'),
  'M6':   ('12', '60'),
  'M8':   ('16', '80'),
  'M10':  ('20','100'),
  'M12':  ('25','120'),
  '(M14)':('25','140'),
  'M16':  ('30','150'),
  '(M18)':('35','200'),
  'M20':  ('40','160'),
  '(M22)':('45','200'),
  'M24':  ('50','180'),
  '(M27)':('50','100'),
  'M30':  ('60','200'),
  '(M33)':('65','200'),
  'M36':  ('70','200'),
  '(M39)':('80','200'),
  'M42':  ('70','200'),
  '(M45)':('90','200'),
  'M48': ('100','200'),
  '(M52)':('100','200'),
  'M56':  ('110','200'),
  '(M60)':('120','200'),
  'M64':  ('120','200')
  }

# ISO 8676 Hexagon head screw with metric fine pitch thread
#                P,    c,  dw,    e,     k,   r,   s
iso8676def={
  'M8x1':      (1.00, 0.3, 11.7, 14.5,  5.3, 0.25, 13.0),
  'M10x1':     (1.00, 0.3, 14.7, 17.9,  6.4, 0.4,  16.0),
  '(M10x1.25)':(1.25, 0.3, 14.7, 17.9,  6.4, 0.4,  16.0),
  'M12x1.5':   (1.50, 0.3, 16.7, 20.1,  7.5, 0.6,  18.0),
  '(M12x1.25)':(1.75, 0.3, 16.7, 20.1,  7.5, 0.6,  18.0),
  '(M14x1.5)': (1.50, 0.3, 20.5, 24.5,  8.8, 0.6,  22.0),
  'M16x1.5':   (1.50, 0.4, 22.4, 26.9, 10.0, 0.6,  24.0),
  '(M18x1.5)': (1.50, 0.4, 25.4, 30.2, 11.5, 0.6,  27.0),
  'M20x1.5':   (1.50, 0.4, 28.2, 33.7, 12.5, 0.8,  30.0),
  '(M20x2)':   (2.00, 0.4, 28.2, 33.7, 12.5, 0.8,  30.0),
  '(M22x1.5)': (1.50, 0.4, 31.8, 37.7, 14.0, 0.8,  34.0),
  'M24x2':     (2.00, 0.4, 33.7, 40.1, 15.0, 0.8,  36.0),
  '(M27x2)':   (2.00, 0.4, 38.0, 45.2, 17.0, 1.0,  41.0),
  '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
  '(M33x2)':   (2.00, 0.4, 46.6, 55.4, 21.0, 1.0,  50.0),
  '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
  '(M39x3)':   (3.00, 0.5, 55.9, 66.5, 25.0, 1.0,  60.0),
  'M42x3':     (3.00, 0.7, 60.0, 71.3, 26.0, 1.2,  65.0),
  '(M45x3)':   (3.00, 0.7, 64.7, 77.0, 28.0, 1.2,  70.0),
  'M48x3':     (3.00, 0.7, 69.5, 82.6, 30.0, 1.6,  75.0),
  '(M52x4)':   (4.00, 0.7, 74.5, 88.3, 33.0, 1.6,  80.0),
  'M56x4':     (4.00, 0.7, 78.7, 93.6, 35.0, 2.0,  85.0),
  '(M60x4)':   (4.00, 0.7, 82.7, 99.2, 38.0, 2.0,  90.0),
  'M64x4':     (4.00, 0.7, 88.2,104.9, 40.0, 2.0,  95.0)
  }

iso8676length = {
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.4, 55.6),
  '60':(59.4, 60.6),
  '65':(64.4, 65.6),
  '70':(69.4, 70.6),
  '80':(79.4, 80.6),
  '100':(99.3, 100.7),
  '110':(109.3, 110.7),
  '120':(119.3, 120.7),
  '130':(129.2, 130.8),
  '140':(139.2, 130.8),
  '150':(149.2, 150.8),
  '160':(159.2, 160.8),
  '180':(179.2, 180.8),
  '200':(199.1, 200.9),
  '220':(217.7, 222.3),
  '240':(237.7, 242.3),
  '260':(219.1, 220.9),
  '280':(219.1, 220.9),
  '300':(219.1, 220.9),
  '320':(219.1, 220.9),
  '340':(219.1, 220.9),
  '360':(219.1, 220.9),
  '380':(219.1, 220.9),
  '400':(219.1, 220.9),
  '420':(219.1, 220.9),
  '440':(219.1, 220.9),
  '460':(219.1, 220.9),
  '480':(219.1, 220.9),
  '500':(496.85, 503.15)
  }

# range of typical screw lengths
#    min_length,  max_length
iso8676range = {
  'M8x1':      ('16', '80'),
  'M10x1':     ('20','100'),
  '(M10x1.25)':('20','100'),
  'M12x1.5':   ('25','120'),
  '(M12x1.25)':('25','120'),
  '(M14x1.5)': ('30','140'),
  'M16x1.5':   ('35','160'),
  '(M18x1.5)': ('35','180'),
  'M20x1.5':   ('40','200'),
  '(M20x2)':   ('40','200'),
  '(M22x1.5)': ('45','220'),
  'M24x2':     ('40','200'),
  '(M27x2)':   ('55','260'),
  'M30x2':     ('40','200'),
  '(M33x2)':   ('65','360'),
  'M36x3':     ('40','200'),
  '(M39x3)':   ('80','380'),
  'M42x3':     ('90','420'),
  '(M45x3)':   ('90','440'),
  'M48x3':     ('100','480'),
  '(M52x4)':   ('100','500'),
  'M56x4':     ('120','500'),
  '(M60x4)':   ('120','500'),
  'M64x4':     ('130','500')
  }

# ISO 4014 Hex-head-bolt
#          P,      b1,    b2,    b3,  c,   dw,    e,    k,   r,   s
iso4014head={
  'M1.6':  (0.35,   9.0,  15.0,  28.0, 0.2,  2.3,  3.4,  1.1, 0.1,  3.2),
  'M2':    (0.40,  10.0,  16.0,  29.0, 0.2,  3.0,  4.4,  1.4, 0.1,  4.0),
  'M2.5':  (0.45,  11.0,  17.0,  30.0, 0.2,  4.0,  5.5,  1.7, 0.1,  5.0),
  'M3':    (0.50,  12.0,  18.0,  31.0, 0.2,  4.6,  6.1,  2.0, 0.1,  5.5),
  '(M3.5)':(0.60,  13.0,  19.0,  32.0, 0.2,  5.1,  6.6,  2.4, 0.1,  6.0),
  'M4':    (0.70,  14.0,  20.0,  33.0, 0.2,  5.9,  7.7,  2.8, 0.2,  7.0),
  'M5':    (0.80,  16.0,  22.0,  35.0, 0.2,  6.9,  8.9,  3.5, 0.2,  8.0),
  'M6':    (1.00,  18.0,  24.0,  37.0, 0.2,  8.9, 11.05, 4.0, 0.25,10.0),
  'M8':    (1.25,  22.0,  28.0,  41.0, 0.3, 11.7, 14.5,  5.3, 0.4, 13.0),
  'M10':   (1.50,  26.0,  32.0,  45.0, 0.3, 14.7, 17.9,  6.4, 0.4, 16.0),
  'M12':   (1.75,  30.0,  36.0,  49.0, 0.3, 16.7, 20.1,  7.5, 0.6, 18.0),
  '(M14)': (2.00,  34.0,  40.0,  53.0, 0.3, 20.5, 24.5,  8.8, 0.6, 22.0),
  'M16':   (2.00,  38.0,  44.0,  57.0, 0.4, 22.4, 26.9, 10.0, 0.6, 24.0),
  '(M18)': (2.50,  42.0,  48.0,  61.0, 0.4, 25.4, 30.2, 11.5, 0.6, 27.0),
  'M20':   (2.50,  46.0,  52.0,  65.0, 0.4, 28.2, 33.7, 12.5, 0.8, 30.0),
  '(M22)': (2.50,  50.0,  56.0,  69.0, 0.4, 31.8, 37.7, 14.0, 0.8, 34.0),
  'M24':   (3.00,  54.0,  60.0,  73.0, 0.4, 33.7, 40.1, 15.0, 0.8, 36.0),
  '(M27)': (3.00,  60.0,  66.0,  79.0, 0.4, 38.0, 45.2, 17.0, 1.0, 41.0),
  '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
  '(M33)': (3.50,  78.0,  78.0,  91.0, 0.4, 46.6, 55.4, 21.0, 1.0, 50.0),
  'M36':   (4.00,  84.0,  84.0,  97.0, 0.4, 51.2, 60.8, 22.5, 1.0, 55.0),
  '(M39)': (4.00,  90.0,  90.0, 103.0, 0.5, 55.9, 66.5, 25.0, 1.0, 60.0),
  'M42':   (4.50,  96.0,  96.0, 109.0, 0.6, 60.0, 71.3, 26.0, 1.2, 65.0),
  '(M45)': (4.50, 102.0, 102.0, 115.0, 0.7, 64.7, 77.0, 28.0, 1.2, 70.0),
  'M48':   (5.00, 108.0, 108.0, 121.0, 0.6, 69.5, 82.6, 30.0, 1.6, 75.0),
  '(M52)': (5.00, 116.0, 116.0, 129.0, 0.7, 74.5, 88.3, 33.0, 1.6, 80.0),
  'M56':   (5.50, 137.0, 137.0, 137.0, 0.6, 78.7, 93.6, 35.0, 2.0, 85.0),
  '(M60)': (5.50, 145.0, 145.0, 145.0, 0.7, 82.7, 99.2, 38.0, 2.0, 90.0),
  'M64':   (6.00, 153.0, 153.0, 153.0, 0.6, 88.2,104.9, 40.0, 2.0, 55.0)
  }

iso4014length = {
  '12':(11.65, 12.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.4, 55.6),
  '60':(59.4, 60.6),
  '65':(64.4, 65.6),
  '70':(69.4, 70.6),
  '80':(79.4, 80.6),
  '100':(99.3, 100.7),
  '110':(109.3, 110.7),
  '120':(119.3, 120.7),
  '130':(129.2, 130.8),
  '140':(139.2, 130.8),
  '150':(149.2, 150.8),
  '160':(159.2, 160.8),
  '180':(179.2, 180.8),
  '200':(199.1, 200.9),
  '220':(219.1, 220.9),
  '240':(237.7, 242.3),
  '260':(219.1, 220.9),
  '280':(219.1, 220.9),
  '300':(219.1, 220.9),
  '320':(219.1, 220.9),
  '340':(219.1, 220.9),
  '360':(219.1, 220.9),
  '380':(219.1, 220.9),
  '400':(219.1, 220.9),
  '420':(219.1, 220.9),
  '440':(219.1, 220.9),
  '460':(219.1, 220.9),
  '480':(219.1, 220.9),
  '500':(496.85, 503.15),
  }

# range of typical screw lengths
#    min_length,  max_length
iso4014range = {
  'M1.6':('12', '16'),
  'M2':  ('16', '20'),
  'M2.5':('16', '25'),
  'M3':  ('20', '30'),
  '(M3.5)':('20', '35'),
  'M4':  ('25', '50'),
  'M5':  ('25', '50'),
  'M6':  ('30', '130'),
  'M8':  ('30', '180'),
  'M10': ('35', '150'),
  'M12': ('50', '150'),
  '(M14)': ('50', '160'),
  'M16': ('55', '200'),
  '(M18)':('70','180'),
  'M20': ('60', '300'),
  '(M22)':('70','220'),
  'M24': ('80', '220'),
  '(M27)':('90', '220'),
  'M30': ('110','300'),
  '(M33)':('130','320'),
  'M36': ('140','360'),
  '(M39)':('150','380'),
  'M42': ('160','440'),
  '(M45)':('180','440'),
  'M48': ('180','480'),
  '(M52)':('200','480'),
  'M56': ('220','500'),
  '(M60)':('220','500'),
  'M64': ('260','500')
  }

# EN 1662 Hexagon bolts with flange, small series
#          P,   b0,    b1,   b2,   b3,   c,  dc,    dw,    e,     k,   kw,  lf,  r1,   s
en1662def={
  '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),
  '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),
  '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),
  '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),
  '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),
  '(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),
  '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)}

# range of typical screw lengths
#    min_length,  max_length
en1662range = {
  'M5': ('10', '50'),
  'M6': ('12', '60'),
  'M8': ('16', '80'),
  'M10':('20','100'),
  'M12':('25','120'),
  '(M14)':('30','140'),
  'M16':('35','160')
  }

en1662length = {
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.4, 55.6),
  '60':(59.4, 60.6),
  '65':(64.4, 65.6),
  '70':(69.4, 70.6),
  '80':(79.4, 80.6),
  '90':(89.3, 90.7),
  '100':(99.3, 100.7),
  '110':(109.3, 110.7),
  '120':(119.3, 120.7),
  '130':(129.2, 130.8),
  '140':(139.2, 130.8),
  '150':(149.2, 150.8),
  '160':(159.2, 160.8)
  }

# EN 1665 Hexagon bolts with flange, heavy series
#          P,    b0,  b1,   b2,   b3,   c,  dc,    dw,    e,     k,   kw,  lf,  r1,   s
en1665def={
  '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),
  '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),
  '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),
  '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),
  '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),
  '(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),
  '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),
  '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)}

# range of typical screw lengths
#    min_length,  max_length
en1665range = {
  'M5': ('10', '50'),
  'M6': ('12', '60'),
  'M8': ('16', '80'),
  'M10':('20','100'),
  'M12':('25','120'),
  '(M14)':('30','140'),
  'M16':('35','160'),
  'M20':('65','200')
  }

en1665length = {
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.4, 55.6),
  '60':(59.4, 60.6),
  '65':(64.4, 65.6),
  '70':(69.4, 70.6),
  '80':(79.4, 80.6),
  '90':(89.3, 90.7),
  '100':(99.3, 100.7),
  '110':(109.3, 110.7),
  '120':(119.3, 120.7),
  '130':(129.2, 130.8),
  '140':(139.2, 130.8),
  '150':(149.2, 150.8),
  '160':(159.2, 160.8),
  '180':(179.2, 180.8),
  '200':(199.1, 200.9)
  }

# ISO 1207 definitions Class A, Slotted cheese head screws
#          P,     a,   b,   dk,  dk_mean, da,  k,  n_min, r, t_min, x
iso1207def={
  'M1.6':(0.35, 0.7, 25.0,  3.0,  2.9,  2.0, 1.1, 0.46, 0.1, 0.45, 0.9),
  'M2':  (0.40, 0.8, 25.0,  3.8,  3.7,  2.6, 1.4, 0.56, 0.1, 0.6, 1.0),
  'M2.5':(0.45, 0.9, 25.0,  4.5,  4.4,  3.1, 1.8, 0.66, 0.1, 0.7, 1.1),
  'M3':  (0.50, 1.0, 25.0,  5.5,  5.4,  3.6, 2.0, 0.86, 0.1, 0.85, 1.25),
  '(M3.5)':(0.60, 1.2, 38.0,  6.0,  5.9,  4.1, 2.4, 1.06, 0.1, 1.0, 1.5),
  'M4':  (0.70, 1.4, 38.0,  7.0,  6.9,  4.7, 2.6, 1.26, 0.2, 1.1, 1.75),
  'M5':  (0.80, 1.6, 38.0,  8.5,  8.4,  5.7, 3.3, 1.26, 0.2, 1.3, 2.0),
  'M6':  (1.00, 2.0, 38.0, 10.0,  9.9,  6.8, 3.9, 1.66, 0.25,1.6, 2.5),
  'M8':  (1.25, 2.5, 38.0, 13.0, 12.85, 9.2, 5.0, 2.06, 0.4, 2.0, 3.2),
  'M10': (1.50, 3.0, 38.0, 16.0, 15.85, 11.2,6.0, 2.56, 0.4, 2.4, 3.8)}

# range of typical screw lengths
#    min_length,  max_length
iso1207range = {
  'M1.6':('2', '16'),
  'M2':  ('3', '20'),
  'M2.5':('3', '25'),
  'M3':  ('4', '30'),
  '(M3.5)':('5', '35'),
  'M4':  ('5', '40'),
  'M5':  ('6', '50'),
  'M6':  ('8', '60'),
  'M8': ('10', '80'),
  'M10':('12', '80')}

# slotted cheese head screws
# nom length: l_min, l_max
iso1207length = {
  '2': (1.8,  2.2),
  '3': ( 2.8,  3.2),
  '4': ( 3.76, 4.24),
  '5': ( 4.76, 5.24),
  '6': ( 5.76, 6.24),
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '14':(13.65, 14.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.05, 55.95),
  '60':(59.05, 60.95),
  '65':(64.05, 65.95),
  '70':(69.05, 70.95),
  '75':(74.05, 75.95),
  '80':(79.05, 80.95)
  }

# ISO 14580 definitions , Hexalobular socket cheese head screws
#          P,     a,   b,   dk,  dk_mean, da,  k,  n_min, r, t_min, x
#           tt,    k,    A,  t_mean
iso14580def={
  'M2':  ('T6',  1.55, 1.75, 0.8),
  'M2.5':('T8',  1.85, 2.40, 0.9),
  'M3':  ('T10', 2.40, 2.80, 1.2),
  '(M3.5)':('T15', 2.60, 3.35, 1.3),
  'M4':  ('T20', 3.10, 3.95, 1.5),
  'M5':  ('T25', 3.65, 4.50, 1.7),
  'M6':  ('T30', 4.40, 5.60, 2.1),
  'M8':  ('T45', 5.80, 7.95, 2.9),
  'M10': ('T50', 6.90, 8.95, 3.3)}

# range of typical screw lengths
#    min_length,  max_length
# iso14580range = iso1207range

# nom length: l_min, l_max
iso14580length = {
  '3': ( 2.8,  3.2),
  '4': ( 3.76, 4.24),
  '5': ( 4.76, 5.24),
  '6': ( 5.76, 6.24),
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '14':(13.65, 14.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.05, 55.95),
  '60':(59.05, 60.95),
  '65':(64.05, 65.95),
  '70':(69.05, 70.95),
  '75':(74.05, 75.95),
  '80':(79.05, 80.95)
  }



# ISO 7048 definitions Class A,
# Cross-recessed cheese head screws with type H or Z cross recess
#          P,     a,   b,   dk,  dk_mean, da,  k,   r,   x, cT,   mH,   mZ
iso7048def={
  '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),
  'M3':  (0.50, 1.0, 25.0,  5.5,  5.4,  3.6, 2.0, 0.1, 1.25,'2', 3.5, 3.5),
  '(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),
  'M4':  (0.70, 1.4, 38.0,  7.0,  6.9,  4.7, 2.6, 0.2, 1.75,'2', 4.1, 4.0),
  'M5':  (0.80, 1.6, 38.0,  8.5,  8.4,  5.7, 3.3, 0.2, 2.0, '2', 4.8, 4.6),
  'M6':  (1.00, 2.0, 38.0, 10.0,  9.9,  6.8, 3.9, 0.25,2.5, '3', 6.2, 6.1),
  'M8':  (1.25, 2.5, 38.0, 13.0, 12.85, 9.2, 5.0, 0.4, 3.2, '3', 7.7, 7.5)
  }

# range of typical screw lengths
#    min_length,  max_length
iso7048range = {
  'M2.5':('3', '25'),
  'M3':  ('4', '30'),
  '(M3.5)':('5', '35'),
  'M4':  ('5', '40'),
  'M5':  ('6', '50'),
  'M6':  ('8', '60'),
  'M8': ('10', '80')}

# nom length: l_min, l_max
iso7048length = {
  '3': ( 2.8,  3.2),
  '4': ( 3.76, 4.24),
  '5': ( 4.76, 5.24),
  '6': ( 5.76, 6.24),
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '60':(59.05, 60.95),
  '70':(69.05, 70.95),
  '80':(79.05, 80.95)
  }


# Button Head Screw
# nom length: l_min, l_max
iso7380length = {
  #'2.5':(2.3,  2.7),
  #'3': ( 2.8,  3.2),
  '4': ( 3.76, 4.24),
  '5': ( 4.76, 5.24),
  '6': ( 5.76, 6.24),
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '14':(13.65, 14.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.05, 55.95),
  '60':(59.05, 60.95),
  '65':(64.4, 65.6),
  '70':(69.4, 70.6),
  '80':(79.4, 80.6),
  '90':(89.3, 90.7)
  }

# ISO 7380-1 definitions Class A
# http://www.agrati.com/it/unificati/it/gamma/unificati/home02.htm
#          P,   b,     a,   da, dk,  dk_mean,s_mean,t_min, r, k,   e,    w,
iso7380def={
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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)
  }

# range of typical screw lengths
#    min_length,  max_length
iso7380range = {
  'M3':  ('6', '30'),
  'M4':  ('6', '40'),
  'M5':  ('8', '50'),
  'M6':  ('10', '60'),
  'M8': ('12', '80'),
  'M10':('16', '90'),
  'M12':('20', '90'),
  'M16':('25', '90')}

# ISO 7380-2 definitions
#          P,   b,     c,   da, dk,    dk_c,s_mean,t_min, r,  k,   e,    w,
iso7380_2def={
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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)
  }


# DIN 967 definitions: Cross recessed pan head screw with collar
#          P,   b,     c,   da,   dk,   r,  k,    rf,  x,    cT,  mH,   mZ
din967def={
  'M3':  (0.50, 25.0, 0.7,  3.6,  7.5, 0.1, 2.35,  3.8, 1.25, '1', 3.0, 2.9),
  '(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),
  'M4':  (0.70, 38.0, 1.0,  4.7, 10.0, 0.2, 3.05,  5.8, 1.75, '2', 4.6, 4.3),
  'M5':  (0.80, 38.0, 1.2,  5.7, 11.5, 0.2, 3.55,  6.6, 2.0,  '2', 5.0, 4.7),
  'M6':  (1.00, 38.0, 1.6,  6.8, 14.5, 0.25,4.55,  8.2, 2.5,  '3', 7.1, 6.7),
  'M8':  (1.25, 38.0, 2.0,  9.2, 19.0, 0.4, 5.90, 11.0, 3.2,  '4', 9.0, 8.8)
  }

# range of typical screw lengths
#    min_length,  max_length
din967range = {
  'M3':  ('4', '30'),
  '(M3.5)':  ('5', '35'),
  'M4':  ('5', '40'),
  'M5':  ('6', '45'),
  'M6':  ('8', '60'),
  'M8': ('10', '60')
}
# Button Head Screw
# nom length: l_min, l_max
din967length = {
  '4': ( 3.76, 4.24),
  '5': ( 4.76, 5.24),
  '6': ( 5.76, 6.24),
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '14':(13.65, 14.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.05, 55.95),
  '60':(59.05, 60.95)
  }


L_iso2009length =['2.5','3','4','5','6','8','10','12','14','16','20', \
   '25','30','35','40','45','50','55','60','65','70','75','80']
# nom length: l_min, l_max
iso2009length = {
  '2.5':(2.3,  2.7),
  '3': ( 2.8,  3.2),
  '4': ( 3.76, 4.24),
  '5': ( 4.76, 5.24),
  '6': ( 5.76, 6.24),
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '14':(13.65, 14.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.05, 55.95),
  '60':(59.05, 60.95),
  '65':(64.05, 65.95),
  '70':(69.05, 70.95),
  '75':(74.05, 75.95),
  '80':(79.05, 80.95)
  }


# ISO 2009 definitions Class A
#          P, a, b, dk_theo, dk_mean, k, n_min, r, t_mean, x
iso2009def={
   'M1.6':(0.35, 0.7, 25, 3.6, 2.8,  1.0,  0.46, 0.2, 0.4, 0.9),
   'M2':  (0.40, 0.8, 25, 4.4, 3.6,  1.2,  0.56, 0.3, 0.5, 1.0),
   'M2.5':(0.45, 0.9, 25, 5.5, 4.5,  1.5,  0.66, 0.3, 0.6, 1.1),
   'M3':  (0.50, 1.0, 25, 6.3, 5.3,  1.65, 0.86, 0.4, 0.7, 1.25),
   '(M3.5)':(0.60, 1.2, 38, 8.2, 7.1,  2.35, 1.06, 0.4, 1.0, 1.5),
   'M4':  (0.70, 1.4, 38, 9.4, 8.2,  2.7,  1.26, 0.5, 1.1, 1.75),
   'M5':  (0.80, 1.6, 38,10.4, 9.2,  2.7,  1.26, 0.6, 1.2, 2.0),
   'M6':  (1.00, 2.0, 38,12.6, 11.2, 3.3,  1.66, 0.7, 1.4, 2.5),
   'M8':  (1.25, 2.5, 38,17.3, 15.6, 4.65, 2.06, 1.0, 2.0, 3.2),
   'M10': (1.50, 3.0, 38,20.0, 18.1, 5.0,  2.56, 1.2, 2.3, 3.8)}

# range of typical screw lengths
#    min_length,  max_length
iso2009range = {
  'M1.6':('2.5', '16'),
  'M2':  ('3', '20'),
  'M2.5':('4', '25'),
  'M3':  ('5', '30'),
  '(M3.5)':('6', '35'),
  'M4':  ('6', '40'),
  'M5':  ('8', '50'),
  'M6':  ('8', '60'),
  'M8': ('10', '80'),
  'M10':('12', '80')}


# ISO 7046 definitions Class A
# ISO 7046 Countersunk flat head screws (common head style)
# with type H or type Z cross recess
# Parameters P, a, b, dk_theo, dk_mean, k, r, x to be read from iso2009def
# Length = iso7045length
#          cT,   mH,   mZ
iso7046def={
  'M1.6':('0', 1.6, 1.6),
  'M2':  ('0', 1.9, 1.9),
  'M2.5':('1', 2.9, 2.8),
  'M3':  ('1', 3.2, 3.0),
  '(M3.5)':('2', 4.4, 4.1),
  'M4':  ('2', 4.6, 4.4),
  'M5':  ('2', 5.2, 4.0),
  'M6':  ('3', 6.8, 6.6),
  'M8':  ('4', 8.9, 8.8),
  'M10': ('4', 10.0,9.8)}

# range of typical screw lengths
#    min_length,  max_length
iso7046range = {
  'M1.6':('3', '16'),
  'M2':  ('3', '20'),
  'M2.5':('3', '25'),
  'M3':  ('4', '30'),
  '(M3.5)':('5', '35'),
  'M4':  ('5', '40'),
  'M5':  ('6', '50'),
  'M6':  ('8', '60'),
  'M8': ('10', '60'),
  'M10':('12', '60')}

# ISO 2010, ISO 7047 definitions Class A: Raised Countersunk head screws
# ISO 2010 slotted screws (common head style)   range = iso2009range
# ISO 7047  with type H or type Z cross recess  range = iso7046range
# Parameters P, a, b, dk_theo, dk_mean, k, r, x to be read from iso2009def
# Length = iso7045length
#          rf, t_mean, cT,   mH,   mZ
Raised_countersunk_def={
  'M1.6':(3.0,  0.7, '0', 1.9,  1.9),
  'M2':  (4.0,  0.9, '0', 2.0,  2.2),
  'M2.5':(5.0,  1.1, '1', 3.0,  2.8),
  'M3':  (6.0,  1.3, '1', 3.4,  3.1),
  '(M3.5)':(8.5,  1.5, '2', 4.8,  4.6),
  'M4':  (9.5,  1.8, '2', 5.2,  5.0),
  'M5':  (9.5,  2.2, '2', 5.4,  5.3),
  'M6':  (12.0, 2.6, '3', 7.3,  7.1),
  'M8':  (16.5, 3.5, '4', 9.6,  9.5),
  'M10': (19.5, 4.1, '4', 10.4,10.3)}



# ISO 14582 definitions
#          P,    a,    b, dk_theo, dk_mean,k,   r,  tt, A, t_mean
iso14582def={
  'M3':  (0.50, 1.0, 18.0,  7.40,  6.5, 2.20, 0.10, 'T10', 2.80, 1.1),
  'M4':  (0.70, 1.4, 20.0, 10.02,  9.0, 3.01, 0.20, 'T20', 3.95, 1.6),
  'M5':  (0.80, 1.6, 22.0, 12.00, 10.8, 3.50, 0.20, 'T25', 4.50, 1.8),
  'M6':  (1.00, 2.0, 24.0, 14.44, 13.1, 4.22, 0.25, 'T30', 5.60, 2.2),
  'M8':  (1.25, 2.5, 28.0, 19.38, 17.8, 5.69, 0.40, 'T45', 7.93, 2.8),
  'M10': (1.50, 3.0, 32.0, 23.00, 21.1, 6.50, 0.40, 'T50', 8.95, 3.3)}

# range of typical screw lengths
#    min_length,  max_length
iso14582range = {
  'M3':  ('8', '30'),
  'M4':  ('8', '40'),
  'M5':  ('8', '50'),
  'M6':  ('8', '60'),
  'M8': ('10', '80'),
  'M10':('12', '100')}

# nom length: l_min, l_max
iso14582length = {
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '14':(13.65, 14.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.4, 55.6),
  '60':(59.4, 60.6),
  '65':(64.4, 65.6),
  '70':(69.4, 70.6),
  '80':(79.4, 80.6),
  '90':(89.3, 90.7),
  '100':(99.3, 100.7)
  }



# ISO 1580 definitions Class A, Slotted pan head screws
#           P,    a,   b, dk_max,da,  k, n_min,  r,  rf, t_mean, x
iso1580def={
  'M1.6':(0.35, 0.7, 25,  3.2, 2.0, 1.0, 0.46, 0.1, 0.5, 0.4, 0.9),
  'M2':  (0.4,  0.8, 25,  4.0, 2.6, 1.3, 0.56, 0.1, 0.6, 0.5, 1.0),
  'M2.5':(0.45, 0.9, 25,  5.0, 3.1, 1.5, 0.66, 0.1, 0.8, 0.6, 1.1),
  'M3':  (0.5,  1.0, 25,  5.6, 3.6, 1.8, 0.86, 0.1, 0.9, 0.7, 1.25),
  '(M3.5)':(0.6,  1.2, 38,  7.0, 4.1, 2.1, 1.06, 0.1, 1.0, 0.8, 1.5),
  'M4':  (0.7,  1.4, 38,  8.0, 4.7, 2.4, 1.26, 0.2, 1.2, 1.0, 1.75),
  'M5':  (0.8,  1.6, 38,  9.5, 5.7, 3.0, 1.26, 0.2, 1.5, 1.2, 2.0),
  'M6':  (1.0,  2.0, 38, 12.0, 6.8, 3.6, 1.66, 0.25,1.8, 1.4, 2.5),
  'M8':  (1.25, 2.5, 38, 16.0, 9.2, 4.8, 2.06, 0.4, 2.4, 1.9, 3.2),
  'M10': (1.50, 3.0, 38, 20.0,11.2, 6.0, 2.56, 0.4, 3.0, 2.4, 3.8)}



# ISO 7045 definitions Class A, Pan head screws with type H or type Z
# partly used also for ISO 14583 Hexalobular socket pan head screws
#   cross recess; cT = size of cross recess
#           P,    a,   b, dk_max,da,  k,   r,   rf,  x,  cT,   mH,   mZ
iso7045def={
  'M1.6':(0.35, 0.7, 25,  3.2, 2.0, 1.3, 0.1, 2.5, 0.9, '0', 1.7, 1.6),
  'M2':  (0.4,  0.8, 25,  4.0, 2.6, 1.6, 0.1, 3.2, 1.0, '0', 1.9, 2.1),
  'M2.5':(0.45, 0.9, 25,  5.0, 3.1, 2.1, 0.1, 4.0, 1.1, '1', 2.7, 2.6),
  'M3':  (0.5,  1.0, 25,  5.6, 3.6, 2.4, 0.1, 5.0, 1.25,'1', 3.0, 2.8),
  '(M3.5)':(0.6,  1.2, 38,  7.0, 4.1, 2.6, 0.1, 6.0, 1.5, '2', 3.9, 3.9),
  'M4':  (0.7,  1.4, 38,  8.0, 4.7, 3.1, 0.2, 6.5, 1.75,'2', 4.4, 4.3),
  'M5':  (0.8,  1.6, 38,  9.5, 5.7, 3.7, 0.2, 8.0, 2.0, '2', 4.9, 4.7),
  'M6':  (1.0,  2.0, 38, 12.0, 6.8, 4.6, 0.25,10., 2.5, '3', 6.9, 6.7),
  'M8':  (1.25, 2.5, 38, 16.0, 9.2, 6.0, 0.4, 13., 3.2, '4', 9.0, 8.8),
  'M10': (1.50, 3.0, 38, 20.0,11.2, 7.5, 0.4, 16., 3.8, '4', 10.1,9.9)}

# nom length: l_min, l_max
iso7045length = {
  '3': ( 2.8,  3.2),
  '4': ( 3.76, 4.24),
  '5': ( 4.76, 5.24),
  '6': ( 5.76, 6.24),
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '14':(13.65, 14.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.05, 55.95),
  '60':(59.05, 60.95)
  }

# range of typical screw lengths
#    min_length,  max_length
iso7045range = {
  'M1.6':('3', '16'),
  'M2':  ('3', '20'),
  'M2.5':('3', '25'),
  'M3':  ('4', '30'),
  '(M3.5)':('5', '35'),
  'M4':  ('5', '40'),
  'M5':  ('6', '45'),
  'M6':  ('8', '60'),
  'M8': ('10', '60'),
  'M10':('12', '60')}


# ISO 14583 Hexalobular socket pan head screws
#   hexalobular recess;    tt = size of hexalobular recess

#           tt,    A,  t_mean
iso14583def={
  'M2':  ('T6',  1.75, 0.7),
  'M2.5':('T8',  2.40, 1.0),
  'M3':  ('T10', 2.80, 1.2),
  '(M3.5)':('T15', 3.35, 1.3),
  'M4':  ('T20', 3.95, 1.5),
  'M5':  ('T25', 4.50, 1.7),
  'M6':  ('T30', 5.60, 2.2),
  'M8':  ('T45', 7.95, 3.0),
  'M10': ('T50', 8.95, 3.8)}


#iso14583range = iso7046range
#iso14583length = iso7045length

# ISO 14584 Hexalobular socket raised countersunk head screws
#           P,   b, dk_theo, dk_mean, f,  k,   r,   rf,    x,    tt,    A,  t_mean
iso14584def={
  'M2':  (0.40, 25.0,  4.4,  3.8,  0.5, 1.20, 0.2,  4.0, 1.00, 'T6',  1.75, 0.7),
  '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),
  'M3':  (0.50, 25.0,  6.3,  5.5,  0.7, 1.65, 0.4,  6.0, 1.25, 'T10', 2.80, 1.2),
  '(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),
  'M4':  (0.70, 38.0,  9.4,  8.4,  1.0, 2.70, 0.5,  9.5, 1.75, 'T20', 3.95, 1.5),
  'M5':  (0.80, 38.0, 10.4,  9.3,  1.2, 2.70, 0.6,  9.5, 2.00, 'T25', 4.50, 1.7),
  'M6':  (1.00, 38.0, 12.6, 11.3,  1.4, 3.30, 0.7, 12.0, 2.50, 'T30', 5.60, 2.2),
  'M8':  (1.25, 38.0, 17.3, 15.8,  2.0, 4.65, 1.0, 16.5, 3.20, 'T45', 7.95, 3.0),
  'M10': (1.50, 38.0, 20.0, 18.3,  2.3, 5.00, 1.2, 19.5, 3.80, 'T50', 8.95, 3.8)}


# range of typical screw lengths
#    min_length,  max_length
iso14584range = {
  'M2':  ('3', '20'),
  'M2.5':('3', '25'),
  'M3':  ('4', '30'),
  '(M3.5)':('5', '35'),
  'M4':  ('5', '40'),
  'M5':  ('6', '50'),
  'M6':  ('8', '60'),
  'M8': ('10', '60'),
  'M10':('12', '60')}

#iso14584length = iso7045length


# ISO 4762 Hexagon socket head cap screws (Allen screw)
# ISO 4762 definitions
#           P,   b,  dk_max,  da,  ds_min,   e,    lf,   k,   r,   s_mean, t,    v,   dw,   w
iso4762def={
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '(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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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)
  }

# nom length: l_min, l_max
iso4762length = {
  '2.5':(2.3,  2.7),
  '3': ( 2.8,  3.2),
  '4': ( 3.76, 4.24),
  '5': ( 4.76, 5.24),
  '6': ( 5.76, 6.24),
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '14':(13.65, 14.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.4, 55.6),
  '60':(59.4, 60.6),
  '65':(64.4, 65.6),
  '70':(69.4, 70.6),
  '75':(74.4, 75.6),
  '80':(79.4, 80.6),
  '100':(99.3, 100.7),
  '110':(109.3, 110.7),
  '120':(119.3, 120.7),
  '130':(129.2, 130.8),
  '140':(139.2, 130.8),
  '150':(149.2, 150.8),
  '160':(159.2, 160.8),
  '180':(179.2, 180.8),
  '200':(199.1, 200.9),
  '220':(219.1, 220.9),
  '240':(237.7, 242.3),
  '260':(219.1, 220.9),
  '280':(219.1, 220.9),
  '300':(219.1, 220.9)
  }

# range of typical screw lengths
#    min_length,  max_length
iso4762range = {
  'M1.6':('2.5', '16'),
  'M2':  ('3', '20'),
  'M2.5':('4', '25'),
  'M3':  ('5', '30'),
  '(M3.5)':('6', '35'),
  'M4':  ('6', '40'),
  'M5':  ('8', '50'),
  'M6':  ('8', '60'),
  'M8': ('10', '80'),
  'M10':('16', '100'),
  'M12':('20', '120'),
  '(M14)':('25', '140'),
  'M16':('25', '160'),
  'M20':('16', '100'),
  'M24':('40', '200'),
  'M30':('45', '200'),
  'M36':('55', '200'),
  'M42':('60', '300'),
  'M48':('100','300'),
  'M56':('110','300'),
  'M64':('120','300')
  }


# ISO 14579 Hexalobular socket head cap screws
#   hexalobular recess;    tt = size of hexalobular recess

#           tt,    A,  t_mean
iso14579def={
  'M2':  ( 'T6',  1.75, 0.8),
  'M2.5':( 'T8',  2.40, 1.0),
  'M3':  ('T10',  2.80, 1.2),
  'M4':  ('T20',  3.95, 1.7),
  'M5':  ('T25',  4.50, 1.9),
  'M6':  ('T30',  5.60, 2.3),
  'M8':  ('T45',  7.95, 3.2),
  'M10': ('T50',  8.95, 3.8),
  'M12': ('T55', 11.35, 5.0),
  '(M14)': ('T60', 13.45, 5.8),
  'M16': ('T70', 15.70, 6.8),
  '(M18)': ('T80', 17.75, 7.8),
  'M20': ('T90', 20.20, 9.0),
  }

# range of typical screw lengths
#    min_length,  max_length
iso14579range = {
  'M2':  ('3', '20'),
  'M2.5':('4', '25'),
  'M3':  ('5', '30'),
  'M4':  ('6', '40'),
  'M5':  ('8', '50'),
  'M6': ('10', '60'),
  'M8': ('12', '80'),
  'M10':('16','100'),
  'M12':('20','120'),
  '(M14)':('25','140'),
  'M16':('25','160'),
  '(M18)':('30','180'),
  'M20':('30','200'),
  }

iso14579length = {
  '3': ( 2.8,  3.2),
  '4': ( 3.76, 4.24),
  '5': ( 4.76, 5.24),
  '6': ( 5.76, 6.24),
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.4, 55.6),
  '60':(59.4, 60.6),
  '65':(64.4, 65.6),
  '70':(69.4, 70.6),
  '80':(79.4, 80.6),
  '90':(89.3, 90.7),
  '100':(99.3, 100.7),
  '110':(109.3, 110.7),
  '120':(119.3, 120.7),
  '130':(129.2, 130.8),
  '140':(139.2, 130.8),
  '150':(149.2, 150.8),
  '160':(159.2, 160.8),
  '180':(179.2, 180.8),
  '200':(199.1, 200.9)
  }


# ISO 10642 Hexagon socket countersunk head screws (Allen screw)
# ISO 10642 definitions
#           P,   b,  dk_theo, dk_mean,da,  ds_min,   e,  k,   r,   s_mean, t,    w
iso10642def={
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '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),
  '(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),
  '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),
  '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)}

# range of typical screw lengths
#    min_length,  max_length
iso10642range = {
  'M3':  ('8', '30'),
  'M4':  ('8', '40'),
  'M5':  ('8', '50'),
  'M6':  ('8', '60'),
  'M8': ('10', '80'),
  'M10':('12','100'),
  'M12':('20','100'),
  '(M14)':('25','100'),
  'M16':('30','100'),
  'M20':('35','100'),
  }

iso10642length = {
  '8': ( 7.71, 8.29),
  '10':( 9.71, 10.29),
  '12':(11.65, 12.35),
  '16':(15.65, 16.35),
  '20':(19.58, 20.42),
  '25':(24.58, 25.42),
  '30':(29.58, 30.42),
  '35':(34.5,  35.5),
  '40':(39.5,  40.5),
  '45':(44.5,  45.5),
  '50':(49.5,  50.5),
  '55':(54.4, 55.6),
  '60':(59.4, 60.6),
  '65':(64.4, 65.6),
  '70':(69.4, 70.6),
  '80':(79.4, 80.6),
  '90':(89.3, 90.7),
  '100':(99.3, 100.7),
  }


# ISO 7089 definitions Washer
#           d1_min, d2_max, h, h_max
iso7089def={
  'M1.6':( 1.7,  4.0, 0.3, 0.35),
  'M2':  ( 2.2,  5.0, 0.3, 0.35),
  'M2.5':( 2.7,  6.0, 0.5, 0.55),
  'M3':  ( 3.2,  7.0, 0.5, 0.55),
  'M4':  ( 4.3,  9.0, 0.8, 0.90),
  'M5':  ( 5.3, 10.0, 1.0, 1.10),
  'M6':  ( 6.4, 12.0, 1.6, 1.80),
  'M8':  ( 8.4, 16.0, 1.6, 1.80),
  'M10': (10.5, 20.0, 2.0, 2.20),
  'M12': (13.0, 24.0, 2.5, 2.70),
  'M16': (17.0, 30.0, 3.0, 3.30),
  'M20': (21.0, 37.0, 3.0, 3.30),
  'M24': (25.0, 44.0, 4.0, 4.30),
  'M30': (31.0, 56.0, 4.0, 4.30),
  'M36': (37.0, 66.0, 5.0, 5.60),
  'M42': (45.0, 78.0, 8.0, 9.0),
  'M48': (52.0, 92.0, 8.0, 9.0),
  'M56': (62.0,105.0,10.0, 11.0),
  'M64': (70.0,115.0,10.0, 11.0)
  }


# ISO 7090 definitions Plain washers, chamfered - Normal series
# chamfer angle 30° / 45°
# chamfer      h/4 / h/2
#           d1_min, d2_max, h, h_max
iso7090def={
  'M5':  ( 5.3, 10.0, 1.0, 1.10),
  'M6':  ( 6.4, 12.0, 1.6, 1.80),
  'M8':  ( 8.4, 16.0, 1.6, 1.80),
  'M10': (10.5, 20.0, 2.0, 2.20),
  'M12': (13.0, 24.0, 2.5, 2.70),
  'M16': (17.0, 30.0, 3.0, 3.30),
  'M20': (21.0, 37.0, 3.0, 3.30),
  'M24': (25.0, 44.0, 4.0, 4.30),
  'M30': (31.0, 56.0, 4.0, 4.30),
  'M36': (37.0, 66.0, 5.0, 5.60),
  'M42': (45.0, 78.0, 8.0, 9.0),
  'M48': (52.0, 92.0, 8.0, 9.0),
  'M56': (62.0,105.0,10.0, 11.0),
  'M64': (70.0,115.0,10.0, 11.0)
  }


# ISO 7091 definitions  Plain washer - Normal series Product Grade C
#           d1_min, d2_max, h, h_max
iso7091def={
  'M1.6':( 1.8,  4.0, 0.3, 0.35),
  'M2':  ( 2.4,  5.0, 0.3, 0.35),
  'M2.5':( 2.9,  6.0, 0.5, 0.55),
  'M3':  ( 3.4,  7.0, 0.5, 0.55),
  'M4':  ( 4.5,  9.0, 0.8, 0.90),
  'M5':  ( 5.5, 10.0, 1.0, 1.10),
  'M6':  ( 6.6, 12.0, 1.6, 1.80),
  'M8':  ( 9.0, 16.0, 1.6, 1.80),
  'M10': (11.0, 20.0, 2.0, 2.20),
  'M12': (13.5, 24.0, 2.5, 2.70),
  'M16': (17.5, 30.0, 3.0, 3.30),
  'M20': (22.0, 37.0, 3.0, 3.30),
  'M24': (26.0, 44.0, 4.0, 4.30),
  'M30': (33.0, 56.0, 4.0, 4.30),
  'M36': (39.0, 66.0, 5.0, 5.60),
  'M42': (45.0, 78.0, 8.0, 9.0),
  'M48': (52.0, 92.0, 8.0, 9.0),
  'M56': (62.0,105.0,10.0, 11.0),
  'M64': (70.0,115.0,10.0, 11.0)
  }


# ISO 7092 definitions  Plain washers - Small series
#           d1_min, d2_max, h, h_max
iso7092def={
  'M1.6':( 1.7,  3.5, 0.3, 0.35),
  'M2':  ( 2.2,  4.5, 0.3, 0.35),
  'M2.5':( 2.7,  5.0, 0.5, 0.55),
  'M3':  ( 3.2,  6.0, 0.5, 0.55),
  'M4':  ( 4.3,  8.0, 0.5, 0.55),
  'M5':  ( 5.3,  9.0, 1.0, 1.10),
  'M6':  ( 6.4, 11.0, 1.6, 1.80),
  'M8':  ( 8.4, 15.0, 1.6, 1.80),
  'M10': (10.5, 18.0, 1.6, 1.80),
  'M12': (13.0, 20.0, 2.0, 2.20),
  'M16': (17.0, 28.0, 2.5, 2.70),
  'M20': (21.0, 34.0, 3.0, 3.30),
  'M24': (25.0, 39.0, 4.0, 4.30),
  'M30': (31.0, 50.0, 4.0, 4.30),
  'M36': (37.0, 60.0, 5.0, 5.60)
  }



# ISO 7093-1 definitions  Plain washers - Large series
#           d1_min, d2_max, h, h_max
iso7093def={
  'M3':    ( 3.2,  9.0, 0.8, 0.90),
  '(M3.5)':( 3.7, 11.0, 0.8, 0.90),
  'M4':    ( 4.3, 12.0, 1.0, 1.10),
  'M5':    ( 5.3, 15.0, 1.0, 1.10),
  'M6':    ( 6.4, 18.0, 1.6, 1.80),
  'M8':    ( 8.4, 24.0, 2.0, 2.20),
  'M10':   (10.5, 30.0, 2.5, 2.70),
  'M12':   (13.0, 37.0, 3.0, 3.30),
  '(M14)': (15.0, 44.0, 3.0, 3.30),
  'M16':   (17.0, 50.0, 3.0, 3.30),
  '(M18)': (19.0, 56.0, 4.0, 4.30),
  'M20':   (21.0, 60.0, 4.0, 4.30),
  '(M22)': (23.0, 66.0, 5.0, 5.60),
  'M24':   (25.0, 72.0, 5.0, 5.60),
  '(M27)': (30.0, 85.0, 6.0, 6.60),
  'M30':   (33.0, 92.0, 6.0, 6.60),
  '(M33)': (36.0,105.0, 6.0, 6.60),
  'M36':   (39.0,110.0, 8.0, 9.00)
  }


# ISO 7094 definitions  Plain washers - Extra large series
#           d1_min, d2_max, h, h_max
iso7094def={
  'M5':    ( 5.5, 18.0, 2.0, 2.3),
  'M6':    ( 6.6, 22.0, 2.0, 2.3),
  'M8':    ( 9.0, 28.0, 3.0, 3.6),
  'M10':   (11.0, 34.0, 3.0, 3.6),
  'M12':   (13.5, 44.0, 4.0, 4.6),
  '(M14)': (15.5, 50.0, 4.0, 4.6),
  'M16':   (17.5, 56.0, 5.0, 6.0),
  '(M18)': (20.0, 60.0, 5.0, 6.0),
  'M20':   (22.0, 72.0, 6.0, 7.0),
  '(M22)': (24.0, 80.0, 6.0, 7.0),
  'M24':   (26.0, 85.0, 6.0, 7.0),
  '(M27)': (30.0, 98.0, 6.0, 7.0),
  'M30':   (33.0,105.0, 6.0, 7.0),
  '(M33)': (36.0,115.0, 8.0, 9.2),
  'M36':   (39.0,125.0, 8.0, 9.2)
  }




# ISO 4757:1983 Definition of cross recess type H
#          b, e_min, g, f_mean, r, t1, alpha, beta
iso4757def = {
  '0': (0.61, 0.26, 0.81, 0.34, 0.3, 0.22, 138.0, 7.0 ),
  '1': (0.97, 0.41, 1.27, 0.54, 0.5, 0.34, 138.0, 7.0 ),
  '2': (1.47, 0.79, 2.29, 0.70, 0.6, 0.61, 140.0, 5.75),
  '3': (2.41, 1.98, 3.81, 0.83, 0.8, 1.01, 146.0, 5.75),
  '4': (3.48, 2.39, 5.08, 1.23, 1.0, 1.35, 153.0, 7.0 )
  }

# ISO 10664 Hexalobular internal driving feature for bolts and screws
#           A,     B,   Re
iso10664def = {
  'T6': ( 1.75,  1.205, 0.14),
  'T8': ( 2.40,  1.67, 0.20),
  'T10':( 2.80,  1.98, 0.24),
  'T15':( 3.35,  2.35, 0.28),
  'T20':( 3.95,  2.75, 0.32),
  'T25':( 4.50,  3.16, 0.39),
  'T30':( 5.60,  3.95, 0.46),
  'T40':( 6.75,  4.76, 0.56),
  'T45':( 7.93,  5.55, 0.59),
  'T50':( 8.95,  6.36, 0.78),
  'T55':(11.35,  7.92, 0.77),
  'T60':(13.45,  9.48, 1.07),
  'T70':(15.70, 11.08, 1.20),
  'T80':(17.75, 12.64, 1.53),
  'T90':(20.20, 14.22, 1.54),
  'T100':(22.40,15.81, 1.73)
  }



# ISO 4032 Hex-head-nut
#           P,   c,  damax, dw,    e,     m,  mw,  s_nom
iso4032def={
  'M1.6':  (0.35, 0.2, 1.84, 2.9,  3.4,   1.3, 0.8,  3.2),
  'M2':    (0.40, 0.2, 2.3,  3.7,  4.4,   1.6, 1.1,  4.0),
  'M2.5':  (0.45, 0.2, 2.9,  4.6,  5.5,   2.0, 1.4,  5.0),
  'M3':    (0.5,  0.2, 3.45, 5.2,  6.1,   2.4, 1.7,  5.5),
  '(M3.5)':(0.6,  0.2, 4.00, 5.7,  6.6,   2.8, 2.0,  6.0),
  'M4':    (0.7,  0.2, 4.6,  6.6,  7.7,   3.2, 2.3,  7.0),
  'M5':    (0.8,  0.2, 5.75, 7.5,  8.9,   3.5, 3.5,  8.0),
  'M6':    (1.0,  0.2, 6.75, 9.5,  11.05, 4.7, 3.9, 10.0),
  'M8':    (1.25, 0.3, 8.75, 11.7, 14.5,  6.8, 5.2, 13.0),
  'M10':   (1.50, 0.3, 10.8, 14.7, 17.9,  8.4, 6.4,  16.0),
  'M12':   (1.75, 0.3, 13.0, 16.7, 20.1, 10.8, 8.3,  18.0),
  '(M14)': (2.00, 0.3, 15.1, 20.5, 24.5, 12.8, 9.7,  22.0),
  'M16':   (2.00, 0.4, 17.3, 22.4, 26.9, 14.8, 11.3,  24.0),
  '(M18)': (2.50, 0.4, 19.5, 24.9, 29.6, 15.8, 12.3,  27.0),
  'M20':   (2.50, 0.4, 21.6, 28.2, 33.7, 18.0, 13.5,  30.0),
  '(M22)': (2.50, 0.4, 23.7, 31.4, 37.3, 19.4, 15.0,  34.0),
  'M24':   (3.00, 0.4, 25.9, 33.7, 40.1, 21.5, 16.2,  36.0),
  '(M27)': (3.00, 0.4, 29.1, 38.0, 45.2, 23.8, 18.0,  41.0),
  'M30':   (3.50, 0.4, 32.4, 42.8, 50.9, 25.6, 19.4,  46.0),
  '(M33)': (3.50, 0.4, 35.6, 46.6, 55.4, 28.7, 21.4,  50.0),
  'M36':   (4.00, 0.4, 38.9, 51.2, 61.0, 31.0, 23.5,  55.0),
  '(M39)': (4.00, 0.5, 42.1, 55.9, 66.5, 33.4, 24.5,  60.0),
  'M42':   (4.50, 0.7, 45.4, 60.0, 71.3, 34.0, 25.9,  65.0),
  '(M45)': (4.50, 0.7, 48.6, 64.7, 77.0, 36.0, 27.9,  70.0),
  'M48':   (5.00, 0.7, 51.8, 69.5, 82.6, 38.0, 29.1,  75.0),
  '(M52)': (5.00, 0.7, 56.2, 74.5, 88.3, 42.0, 32.1,  80.0),
  'M56':   (5.50, 0.7, 60.5, 78.7, 93.6, 45.0, 34.7,  85.0),
  '(M60)': (5.50, 0.7, 64.8, 82.7, 99.2, 48.0, 38.7,  90.0),
  'M64':   (6.00, 0.7, 69.1, 88.2,104.9, 51.0, 39.3,  95.0)
  }



# ISO 4033 Hexagon nuts style 2
#           P,   c,  damax, dw,    e,     m,  mw,  s_nom
iso4033def={
  'M5':    (0.8,  0.2, 5.75, 7.5,  8.9,   5.1, 3.5,  8.0),
  'M6':    (1.0,  0.2, 6.75, 9.5,  11.05, 5.7, 3.9, 10.0),
  'M8':    (1.25, 0.3, 8.75, 11.7, 14.5,  7.5, 5.2, 13.0),
  'M10':   (1.50, 0.3, 10.8, 14.7, 17.9,  9.3, 6.4,  16.0),
  'M12':   (1.75, 0.3, 13.0, 16.7, 20.1, 12.0, 8.3,  18.0),
  '(M14)': (2.00, 0.3, 15.1, 20.5, 24.5, 14.1, 9.7,  22.0),
  'M16':   (2.00, 0.4, 17.3, 22.4, 26.9, 16.4, 11.3,  24.0),
  'M20':   (2.50, 0.4, 21.6, 28.2, 33.7, 20.3, 13.5,  30.0),
  'M24':   (3.00, 0.4, 25.9, 33.7, 40.1, 23.9, 16.2,  36.0),
  'M30':   (3.50, 0.4, 32.4, 42.8, 50.9, 28.6, 19.4,  46.0),
  'M36':   (4.00, 0.4, 38.9, 51.2, 61.0, 33.1, 23.5,  55.0)
  }

# ISO 4035 Hexagon thin nuts, chamfered
#           P,   c,  damax, dw,    e,     m,  mw,  s_nom
iso4035def={
  'M1.6':  (0.35, 0.2, 1.84, 2.9,  3.4,   1.0,  0.8,  3.2),
  'M2':    (0.40, 0.2, 2.3,  3.7,  4.4,   1.2,  1.1,  4.0),
  'M2.5':  (0.45, 0.2, 2.9,  4.6,  5.5,   1.6,  1.4,  5.0),
  'M3':    (0.5,  0.2, 3.45, 5.2,  6.1,   1.8,  1.7,  5.5),
  '(M3.5)':(0.6,  0.2, 4.00, 5.7,  6.6,   2.0,  2.0,  6.0),
  'M4':    (0.7,  0.2, 4.6,  6.6,  7.7,   2.2,  2.3,  7.0),
  'M5':    (0.8,  0.2, 5.75, 7.5,  8.9,   2.7,  3.5,  8.0),
  'M6':    (1.0,  0.2, 6.75, 9.5,  11.05, 3.2,  3.9, 10.0),
  'M8':    (1.25, 0.3, 8.75, 11.7, 14.5,  4.0,  5.2, 13.0),
  'M10':   (1.50, 0.3, 10.8, 14.7, 17.9,  5.0,  6.4, 16.0),
  'M12':   (1.75, 0.3, 13.0, 16.7, 20.1,  6.0,  8.3, 18.0),
  '(M14)': (2.00, 0.3, 15.1, 20.5, 24.5,  7.0,  9.7, 22.0),
  'M16':   (2.00, 0.4, 17.3, 22.4, 26.9,  8.0, 11.3, 24.0),
  '(M18)': (2.50, 0.4, 19.5, 24.9, 29.6,  9.0, 12.3, 27.0),
  'M20':   (2.50, 0.4, 21.6, 28.2, 33.7, 10.0, 13.5, 30.0),
  '(M22)': (2.50, 0.4, 23.7, 31.4, 37.3, 11.0, 15.0, 34.0),
  'M24':   (3.00, 0.4, 25.9, 33.7, 40.1, 12.0, 16.2, 36.0),
  '(M27)': (3.00, 0.4, 29.1, 38.0, 45.2, 13.5, 18.0, 41.0),
  'M30':   (3.50, 0.4, 32.4, 42.8, 50.9, 15.0, 19.4, 46.0),
  '(M33)': (3.50, 0.4, 35.6, 46.6, 55.4, 16.5, 21.4, 50.0),
  'M36':   (4.00, 0.4, 38.9, 51.2, 61.0, 18.0, 23.5, 55.0),
  '(M39)': (4.00, 0.5, 42.1, 55.9, 66.5, 19.5, 24.5, 60.0),
  'M42':   (4.50, 0.7, 45.4, 60.0, 71.3, 21.0, 25.9, 65.0),
  '(M45)': (4.50, 0.7, 48.6, 64.7, 77.0, 22.5, 27.9, 70.0),
  'M48':   (5.00, 0.7, 51.8, 69.5, 82.6, 24.0, 29.1, 75.0),
  '(M52)': (5.00, 0.7, 56.2, 74.5, 88.3, 26.0, 32.1, 80.0),
  'M56':   (5.50, 0.7, 60.5, 78.7, 93.6, 28.0, 34.7, 85.0),
  '(M60)': (5.50, 0.7, 64.8, 82.7, 99.2, 30.0, 38.7, 90.0),
  'M64':   (6.00, 0.7, 69.1, 88.2,104.9, 32.0, 39.3, 95.0)
  }

# ISO 4036 Hexagon thin nuts, unchamfered
#           P,      e,   m,  s_nom
iso4036def={
  'M1.6':  (0.35,  3.4, 1.0,  3.2),
  'M2':    (0.40,  4.4, 1.2,  4.0),
  'M2.5':  (0.45,  5.5, 1.6,  5.0),
  'M3':    (0.5,   6.1, 1.8,  5.5),
  '(M3.5)':(0.6,   6.6, 2.0,  6.0),
  'M4':    (0.7,   7.7, 2.2,  7.0),
  'M5':    (0.8,   8.9, 2.7,  8.0),
  'M6':    (1.0,  10.9, 3.2, 10.0),
  'M8':    (1.25, 14.5, 4.0, 13.0),
  'M10':   (1.50, 17.9, 5.0, 16.0)}

# EN 1661 Hexagon nuts with flange
#          P,    damax,  c,  dc,    dw,    e,     m,   mw,   r,   s
en1661def={
  'M5'   :(0.80,  5.75, 1.0, 11.8,  9.8,  8.79,  5.0, 2.5,  0.30,  8.0),
  'M6'   :(1.00,  6.75, 1.1, 14.2, 12.2, 11.05,  6.0, 3.1,  0.36, 10.0),
  'M8'   :(1.25,  8.75, 1.2, 17.9, 15.8, 14.38,  8.0, 4.6,  0.48, 13.0),
  'M10'  :(1.50, 10.80, 1.5, 21.8, 19.6, 17.77, 10.0, 5.9,  0.60, 16.0),
  'M12'  :(1.75, 13.00, 1.8, 26.0, 23.8, 20.03, 12.0, 6.8,  0.72, 18.0),
  '(M14)':(2.00, 15.10, 2.1, 29.9, 27.6, 23.36, 14.0, 7.7,  0.88, 21.0),
  'M16'  :(2.00, 17.30, 2.4, 34.5, 31.9, 26.75, 16.0, 8.9,  0.96, 24.0),
  'M20'  :(2.50, 21.60, 3.0, 42.8, 39.9, 33.23, 20.0,10.7,  1.20, 30.0)}

# Tuning table to get valid shapes
#         P, tunIn, tunEx
tuningTable={
  'M1.6':(0.35, 516, 516),
  'M2':  (0.40, 515, 516),
  'M2.5':(0.45, 515, 515),
  'M3':  (0.5,  480, 502),
  '(M3.5)':(0.6,  480, 502),
  'M4':  (0.7,  510, 519), #last value needed for ISO7380
  'M5':  (0.8,  510, 510),
  'M6':  (1.0,  515, 515),
  'M8':  (1.25, 516, 516),
  'M10': (1.50, 515, 515),
  'M12': (1.75, 513, 513),
  '(M14)': (2.00, 513, 513),
  'M16': (2.00, 513, 513),
  'M20': (2.50, 513, 513),
  'M24': (3.00, 513, 513),
  '(M27)': (3.00, 513, 513),
  'M30': (3.50, 513, 513),
  '(M33)': (3.50, 513, 513),
  'M36': (4.00, 513, 513),
  'M42': (4.50, 515, 515),
  '(M45)': (4.50, 515, 515),
  'M48': (5.00, 515, 505), # ISO4014: 505, 502 or 488; ISO4017: above 505
  '(M52)': (5.00, 508, 508),
  'M56': (5.50, 508, 508),
  '(M60)': (5.50, 508, 508),
  'M64': (6.00, 489, 489) # Nut ISO4032: 489
  }


def equal_vertex(vert1, vert2, p=5):
  # compares two vertices
  return (round(vert1.X - vert2.X,p)==0 and round(vert1.Y - vert2.Y,p)==0 and round(vert1.Z - vert2.Z,p)==0)

try:
  _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
  _fromUtf8 = lambda s: s

class Ui_ScrewMaker(object):
  def setupUi(self, ScrewMaker):
    FCUi = FreeCADGui.UiLoader()

    ScrewMaker.setObjectName(_fromUtf8("ScrewMaker"))
    ScrewMaker.resize(450, 362)
    ScrewMaker.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedKingdom))
    self.layoutWidget = QtGui.QWidget(ScrewMaker)
    self.layoutWidget.setGeometry(QtCore.QRect(348, 35, 102, 161))
    self.layoutWidget.setObjectName(_fromUtf8("layoutWidget"))
    self.verticalLayout_2 = QtGui.QVBoxLayout(self.layoutWidget)
    #self.verticalLayout_2.setMargin(0)
    self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
    self.ScrewTypeLabel = QtGui.QLabel(self.layoutWidget)
    self.ScrewTypeLabel.setObjectName(_fromUtf8("ScrewTypeLabel"))
    self.verticalLayout_2.addWidget(self.ScrewTypeLabel)
    self.NomDiaLabel = QtGui.QLabel(self.layoutWidget)
    self.NomDiaLabel.setObjectName(_fromUtf8("NomDiaLabel"))
    self.verticalLayout_2.addWidget(self.NomDiaLabel)
    self.NomLenLabel = QtGui.QLabel(self.layoutWidget)
    self.NomLenLabel.setObjectName(_fromUtf8("NomLenLabel"))
    self.verticalLayout_2.addWidget(self.NomLenLabel)
    self.UserLenLabel = QtGui.QLabel(self.layoutWidget)
    self.UserLenLabel.setObjectName(_fromUtf8("UserLenLabel"))
    self.verticalLayout_2.addWidget(self.UserLenLabel)

    self.layoutWidget1 = QtGui.QWidget(ScrewMaker)
    self.layoutWidget1.setGeometry(QtCore.QRect(3, 35, 350, 166))
    #self.layoutWidget1.setGeometry(QtCore.QRect(10, 5, 315, 200))
    self.layoutWidget1.setObjectName(_fromUtf8("layoutWidget1"))
    self.verticalLayout = QtGui.QVBoxLayout(self.layoutWidget1)
    #self.verticalLayout.setMargin(0)
    self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
    self.ScrewType = QtGui.QComboBox(self.layoutWidget1)
    self.ScrewType.setObjectName(_fromUtf8("ScrewType"))
    for i in range(33):
      self.ScrewType.addItem(_fromUtf8(""))  # 0

    self.verticalLayout.addWidget(self.ScrewType)
    self.NominalDiameter = QtGui.QComboBox(self.layoutWidget1)
    self.NominalDiameter.setObjectName(_fromUtf8("NominalDiameter"))
    for i in range(52):
      self.NominalDiameter.addItem(_fromUtf8("")) # 0

    self.verticalLayout.addWidget(self.NominalDiameter)
    self.NominalLength = QtGui.QComboBox(self.layoutWidget1)
    self.NominalLength.setObjectName(_fromUtf8("NominalLength"))
    for i in range(48):
      self.NominalLength.addItem(_fromUtf8("")) #0

    self.verticalLayout.addWidget(self.NominalLength)
    #self.UserLen = QtGui.QComboBox(self.layoutWidget1)
    self.UserLen = FCUi.createWidget("Gui::InputField")
    self.UserLen.setObjectName(_fromUtf8("UserLen"))
    #self.UserLen.addItem(_fromUtf8(""))
    self.UserLen.setProperty("text", "0 mm")
    self.verticalLayout.addWidget(self.UserLen)

    #self.CommentLabel = QtGui.QLabel(self.layoutWidget)
    self.CommentLabel = QtGui.QLabel(ScrewMaker)
    self.CommentLabel.setObjectName(_fromUtf8("CommentLabel"))
    self.CommentLabel.setGeometry(QtCore.QRect(10, 184, 411, 21))
    #self.verticalLayout.addWidget(self.CommentLabel)

    self.layoutWidget2 = QtGui.QWidget(ScrewMaker)
    #self.layoutWidget2.setGeometry(QtCore.QRect(10, 200, 321, 83))
    self.layoutWidget2.setGeometry(QtCore.QRect(3, 200, 321, 120))
    self.layoutWidget2.setObjectName(_fromUtf8("layoutWidget2"))
    self.verticalLayout_3 = QtGui.QVBoxLayout(self.layoutWidget2)
    #self.verticalLayout_3.setMargin(0)
    self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3"))
    self.SimpleScrew = QtGui.QRadioButton(self.layoutWidget2)
    self.SimpleScrew.setChecked(True)
    self.SimpleScrew.setObjectName(_fromUtf8("SimpleScrew"))
    self.verticalLayout_3.addWidget(self.SimpleScrew)
    self.SymbolThread = QtGui.QRadioButton(self.layoutWidget2)
    self.SymbolThread.setObjectName(_fromUtf8("SymbolThread"))
    self.verticalLayout_3.addWidget(self.SymbolThread)
    self.RealThread = QtGui.QRadioButton(self.layoutWidget2)
    self.RealThread.setObjectName(_fromUtf8("RealThread"))
    self.verticalLayout_3.addWidget(self.RealThread)
    self.MessageLabel = QtGui.QLabel(ScrewMaker)
    self.MessageLabel.setGeometry(QtCore.QRect(10, 10, 411, 21))
    self.MessageLabel.setProperty("Empty_text", _fromUtf8(""))
    self.MessageLabel.setObjectName(_fromUtf8("MessageLabel"))
    self.CreateButton = QtGui.QToolButton(ScrewMaker)
    self.CreateButton.setGeometry(QtCore.QRect(180, 320, 111, 26))
    self.CreateButton.setObjectName(_fromUtf8("CreateButton"))
    self.ScrewAvailable = True

    self.simpThread = self.SimpleScrew.isChecked()
    self.symThread = self.SymbolThread.isChecked()
    self.rThread = self.RealThread.isChecked()

    self.theScrew = Screw()

    self.retranslateUi(ScrewMaker)
    self.NominalDiameter.setCurrentIndex(5)
    self.NominalLength.setCurrentIndex(9)
    QtCore.QObject.connect(self.ScrewType, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.guiCheck_Data)
    QtCore.QObject.connect(self.CreateButton, QtCore.SIGNAL(_fromUtf8("pressed()")), self.guiCreateScrew)
    QtCore.QObject.connect(self.NominalDiameter, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.guiCheck_Data)
    QtCore.QObject.connect(self.NominalLength, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.guiCheck_Data)
    QtCore.QMetaObject.connectSlotsByName(ScrewMaker)

  def retranslateUi(self, ScrewMaker):
    ScrewMaker.setWindowTitle(tr('ScrewMaker', 'Screw-Maker 2.2'))
    self.ScrewTypeLabel.setText(tr('ScrewMaker', 'Type of Screw'))
    self.NomDiaLabel.setText(tr('ScrewMaker', 'Nomimal\nDiameter'))
    self.NomLenLabel.setText(tr('ScrewMaker', 'Nominal\nLength'))
    self.UserLenLabel.setText(tr('ScrewMaker', 'User length \nfor screw-tap'))
    self.CommentLabel.setText(tr('ScrewMaker', 'Values in brackets are not recommended!'))
    self.ScrewType.setItemText(0, tr('ScrewMaker', 'ISO4017: Hexagon head screws'))
    self.ScrewType.setItemText(1, tr('ScrewMaker', 'ISO4014: Hexagon head bolts'))
    self.ScrewType.setItemText(2, tr('ScrewMaker', 'EN1662: Hexagon bolts with flange, small\n    series'))
    self.ScrewType.setItemText(3, tr('ScrewMaker', 'EN1665: Hexagon bolts with flange, heavy\n    series'))
    self.ScrewType.setItemText(4, tr('ScrewMaker', 'ISO8676: Hexagon head screw with\n    metric fine pitch thread'))
    self.ScrewType.setItemText(5, tr('ScrewMaker', 'ISO4762: Hexagon socket head cap screws'))
    self.ScrewType.setItemText(6, tr('ScrewMaker', 'ISO7380-1: Hexagon socket button head\n    screws'))
    self.ScrewType.setItemText(7, tr('ScrewMaker', 'ISO7380-2: Hexagon socket button head\n    screws with collar'))
    self.ScrewType.setItemText(8, tr('ScrewMaker', 'DIN967: Cross recessed pan head screws\n    with collar'))
    self.ScrewType.setItemText(9, tr('ScrewMaker', 'ISO10642: Hexagon socket countersunk \n    head screws'))
    self.ScrewType.setItemText(10, tr('ScrewMaker', 'ISO2009: Slotted countersunk flat head\n    screws'))
    self.ScrewType.setItemText(11, tr('ScrewMaker', 'ISO2010: Slotted raised countersunk head\n    screws'))
    self.ScrewType.setItemText(12, tr('ScrewMaker', 'ISO1207: Slotted cheese head screws'))
    self.ScrewType.setItemText(13, tr('ScrewMaker', 'ISO1580: Slotted pan head screws'))
    self.ScrewType.setItemText(14, tr('ScrewMaker', 'ISO7045: Pan head screws, type H cross recess'))
    self.ScrewType.setItemText(15, tr('ScrewMaker', 'ISO7046: Countersunk flat head screws\n    H cross recess'))
    self.ScrewType.setItemText(16, tr('ScrewMaker', 'ISO7047: Raised countersunk head screws\n    H cross recess'))
    self.ScrewType.setItemText(17, tr('ScrewMaker', 'ISO7048: Cheese head screws type H cross recess'))
    self.ScrewType.setItemText(18, tr('ScrewMaker', 'ISO14579: Hexalobular socket head cap screws'))
    self.ScrewType.setItemText(19, tr('ScrewMaker', 'ISO14580: Hexalobular socket cheese head\n    screws'))
    self.ScrewType.setItemText(20, tr('ScrewMaker', 'ISO14583: Hexalobular socket pan head screws'))
    self.ScrewType.setItemText(21, tr('ScrewMaker', 'ISO14582: Hexalobular socket countersunk\n    head screws, high head'))
    self.ScrewType.setItemText(22, tr('ScrewMaker', 'ISO14584: Hexalobular socket raised\n    countersunk head screws'))
    self.ScrewType.setItemText(23, tr('ScrewMaker', 'ISO7089: Plain washers - Normal series'))
    self.ScrewType.setItemText(24, tr('ScrewMaker', 'ISO7090: Plain washers, chamfered - Normal series'))
    self.ScrewType.setItemText(25, tr('ScrewMaker', 'ISO7092: Plain washers - Small series'))
    self.ScrewType.setItemText(26, tr('ScrewMaker', 'ISO7093-1: Plain washer - Large series'))
    self.ScrewType.setItemText(27, tr('ScrewMaker', 'ISO7094: Plain washers - Extra large series'))
    self.ScrewType.setItemText(28, tr('ScrewMaker', 'ISO4032: Hexagon nuts, Style 1'))
    self.ScrewType.setItemText(29, tr('ScrewMaker', 'ISO4033: Hexagon nuts, Style 2'))
    self.ScrewType.setItemText(30, tr('ScrewMaker', 'ISO4035: Hexagon thin nuts, chamfered'))
    self.ScrewType.setItemText(31, tr('ScrewMaker', 'EN1661: Hexagon nuts with flange'))
    self.ScrewType.setItemText(32, tr('ScrewMaker', 'ScrewTap: ISO Screw-Tap'))

    self.NominalDiameter.setItemText(0, tr('ScrewMaker', 'M1.6'))
    self.NominalDiameter.setItemText(1, tr('ScrewMaker', 'M2'))
    self.NominalDiameter.setItemText(2, tr('ScrewMaker', 'M2.5'))
    self.NominalDiameter.setItemText(3, tr('ScrewMaker', 'M3'))
    self.NominalDiameter.setItemText(4, tr('ScrewMaker', '(M3.5)'))
    self.NominalDiameter.setItemText(5, tr('ScrewMaker', 'M4'))
    self.NominalDiameter.setItemText(6, tr('ScrewMaker', 'M5'))
    self.NominalDiameter.setItemText(7, tr('ScrewMaker', 'M6'))
    self.NominalDiameter.setItemText(8, tr('ScrewMaker', 'M8'))
    self.NominalDiameter.setItemText(9, tr('ScrewMaker', 'M10'))
    self.NominalDiameter.setItemText(10, tr('ScrewMaker', 'M12'))
    self.NominalDiameter.setItemText(11, tr('ScrewMaker', '(M14)'))
    self.NominalDiameter.setItemText(12, tr('ScrewMaker', 'M16'))
    self.NominalDiameter.setItemText(13, tr('ScrewMaker', '(M18)'))
    self.NominalDiameter.setItemText(14, tr('ScrewMaker', 'M20'))
    self.NominalDiameter.setItemText(15, tr('ScrewMaker', '(M22)'))
    self.NominalDiameter.setItemText(16, tr('ScrewMaker', 'M24'))
    self.NominalDiameter.setItemText(17, tr('ScrewMaker', '(M27)'))
    self.NominalDiameter.setItemText(18, tr('ScrewMaker', 'M30'))
    self.NominalDiameter.setItemText(19, tr('ScrewMaker', 'M36'))
    self.NominalDiameter.setItemText(20, tr('ScrewMaker', '(M33)'))
    self.NominalDiameter.setItemText(21, tr('ScrewMaker', 'M42'))
    self.NominalDiameter.setItemText(22, tr('ScrewMaker', '(M45)'))
    self.NominalDiameter.setItemText(23, tr('ScrewMaker', 'M48'))
    self.NominalDiameter.setItemText(24, tr('ScrewMaker', '(M52)'))
    self.NominalDiameter.setItemText(25, tr('ScrewMaker', 'M54'))
    self.NominalDiameter.setItemText(26, tr('ScrewMaker', '(M60)'))
    self.NominalDiameter.setItemText(27, tr('ScrewMaker', 'M64'))

    self.NominalDiameter.setItemText(28, tr('ScrewMaker', 'M8x1'))
    self.NominalDiameter.setItemText(29, tr('ScrewMaker', 'M10x1'))
    self.NominalDiameter.setItemText(30, tr('ScrewMaker', '(M10x1.25)'))
    self.NominalDiameter.setItemText(31, tr('ScrewMaker', 'M12x1.5'))
    self.NominalDiameter.setItemText(32, tr('ScrewMaker', '(M12x1.25)'))
    self.NominalDiameter.setItemText(33, tr('ScrewMaker', '(M14x1.5)'))
    self.NominalDiameter.setItemText(34, tr('ScrewMaker', 'M16x1.5'))
    self.NominalDiameter.setItemText(35, tr('ScrewMaker', '(M18x1.5)'))
    self.NominalDiameter.setItemText(36, tr('ScrewMaker', 'M20x1.5'))
    self.NominalDiameter.setItemText(37, tr('ScrewMaker', '(M20x2)'))
    self.NominalDiameter.setItemText(38, tr('ScrewMaker', '(M22x1.5)'))
    self.NominalDiameter.setItemText(39, tr('ScrewMaker', 'M24x2'))
    self.NominalDiameter.setItemText(40, tr('ScrewMaker', '(M27x2)'))
    self.NominalDiameter.setItemText(41, tr('ScrewMaker', 'M30x2'))
    self.NominalDiameter.setItemText(42, tr('ScrewMaker', '(M33x2)'))
    self.NominalDiameter.setItemText(43, tr('ScrewMaker', 'M36x3'))
    self.NominalDiameter.setItemText(44, tr('ScrewMaker', '(M39x3)'))
    self.NominalDiameter.setItemText(45, tr('ScrewMaker', 'M42x3'))
    self.NominalDiameter.setItemText(46, tr('ScrewMaker', '(M45x3)'))
    self.NominalDiameter.setItemText(47, tr('ScrewMaker', 'M48x3'))
    self.NominalDiameter.setItemText(48, tr('ScrewMaker', '(M52x4)'))
    self.NominalDiameter.setItemText(49, tr('ScrewMaker', 'M56x4'))
    self.NominalDiameter.setItemText(50, tr('ScrewMaker', '(M60x4)'))
    self.NominalDiameter.setItemText(51, tr('ScrewMaker', 'M64x4'))

    self.NominalLength.setItemText(0, tr('ScrewMaker', '2'))
    self.NominalLength.setItemText(1, tr('ScrewMaker', '2.5'))
    self.NominalLength.setItemText(2, tr('ScrewMaker', '3'))
    self.NominalLength.setItemText(3, tr('ScrewMaker', '4'))
    self.NominalLength.setItemText(4, tr('ScrewMaker', '5'))
    self.NominalLength.setItemText(5, tr('ScrewMaker', '6'))
    self.NominalLength.setItemText(6, tr('ScrewMaker', '8'))
    self.NominalLength.setItemText(7, tr('ScrewMaker', '10'))
    self.NominalLength.setItemText(8, tr('ScrewMaker', '12'))
    self.NominalLength.setItemText(9, tr('ScrewMaker', '16'))
    self.NominalLength.setItemText(10, tr('ScrewMaker', '20'))
    self.NominalLength.setItemText(11, tr('ScrewMaker', '25'))
    self.NominalLength.setItemText(12, tr('ScrewMaker', '30'))
    self.NominalLength.setItemText(13, tr('ScrewMaker', '35'))
    self.NominalLength.setItemText(14, tr('ScrewMaker', '40'))
    self.NominalLength.setItemText(15, tr('ScrewMaker', '45'))
    self.NominalLength.setItemText(16, tr('ScrewMaker', '50'))
    self.NominalLength.setItemText(17, tr('ScrewMaker', '55'))
    self.NominalLength.setItemText(18, tr('ScrewMaker', '60'))
    self.NominalLength.setItemText(19, tr('ScrewMaker', '65'))
    self.NominalLength.setItemText(20, tr('ScrewMaker', '70'))
    self.NominalLength.setItemText(21, tr('ScrewMaker', '80'))
    self.NominalLength.setItemText(22, tr('ScrewMaker', '90'))
    self.NominalLength.setItemText(23, tr('ScrewMaker', '100'))
    self.NominalLength.setItemText(24, tr('ScrewMaker', '110'))
    self.NominalLength.setItemText(25, tr('ScrewMaker', '120'))
    self.NominalLength.setItemText(26, tr('ScrewMaker', '130'))
    self.NominalLength.setItemText(27, tr('ScrewMaker', '140'))
    self.NominalLength.setItemText(28, tr('ScrewMaker', '150'))
    self.NominalLength.setItemText(29, tr('ScrewMaker', '160'))
    self.NominalLength.setItemText(30, tr('ScrewMaker', '180'))
    self.NominalLength.setItemText(31, tr('ScrewMaker', '200'))
    self.NominalLength.setItemText(32, tr('ScrewMaker', '220'))
    self.NominalLength.setItemText(33, tr('ScrewMaker', '240'))
    self.NominalLength.setItemText(34, tr('ScrewMaker', '260'))
    self.NominalLength.setItemText(35, tr('ScrewMaker', '280'))
    self.NominalLength.setItemText(36, tr('ScrewMaker', '300'))
    self.NominalLength.setItemText(37, tr('ScrewMaker', '320'))
    self.NominalLength.setItemText(38, tr('ScrewMaker', '340'))
    self.NominalLength.setItemText(39, tr('ScrewMaker', '360'))
    self.NominalLength.setItemText(40, tr('ScrewMaker', '380'))
    self.NominalLength.setItemText(41, tr('ScrewMaker', '400'))
    self.NominalLength.setItemText(42, tr('ScrewMaker', '420'))
    self.NominalLength.setItemText(43, tr('ScrewMaker', '440'))
    self.NominalLength.setItemText(44, tr('ScrewMaker', '460'))
    self.NominalLength.setItemText(45, tr('ScrewMaker', '480'))
    self.NominalLength.setItemText(46, tr('ScrewMaker', '500'))
    self.NominalLength.setItemText(47, tr('ScrewMaker', 'User'))
    #self.UserLen.setItemText(0, tr('ScrewMaker', 'regular pitch'))
    self.SimpleScrew.setText(tr('ScrewMaker', 'Simple Screw (no thread at all!)'))
    self.SymbolThread.setText(tr('ScrewMaker', 'Symbol Thread (not implemented yet)'))
    self.RealThread.setText(tr('ScrewMaker', 'Real Thread (takes time, memory intensive)\nMay not work for all screws!'))
    self.MessageLabel.setText(tr('ScrewMaker', 'Select your screw type'))
    self.MessageLabel.setProperty('Errortext', tr('ScrewMaker', 'Combination not implemented'))
    self.MessageLabel.setProperty('OK_text', tr('ScrewMaker', 'Screw is made'))
    self.CreateButton.setText(tr('ScrewMaker', 'create'))

  def guiCheck_Data(self):
    ST_text = str(self.ScrewType.currentText())
    ST_text = ST_text.split(':')[0]
    ND_text = str(self.NominalDiameter.currentText())
    NL_text = str(self.NominalLength.currentText())
    M_text, self.ScrewAvailable  = self.theScrew.check_Data(ST_text, ND_text, NL_text)
    self.MessageLabel.setText(tr('ScrewMaker', M_text))

  def guiCreateScrew(self):
    #self.simpThread = self.SimpleScrew.isChecked()
    #self.symThread = self.SymbolThread.isChecked()
    #self.rThread = self.RealThread.isChecked()
    if self.SimpleScrew.isChecked():
      threadType = 'simple'
    if self.SymbolThread.isChecked():
      threadType = 'symbol'
    if self.RealThread.isChecked():
      threadType = 'real'

    ND_text = str(self.NominalDiameter.currentText())
    NL_text = str(self.NominalLength.currentText())
    ST_text = str(self.ScrewType.currentText())
    ST_text = ST_text.split(':')[0]

    if (ST_text == 'ScrewTap') or (ST_text == 'ISO8676'):
      if NL_text == 'User':
        textValue = self.UserLen.property("text")
        stLength = FreeCAD.Units.parseQuantity(textValue).Value
        NL_text = str(stLength)

    myObj = self.theScrew.createScrew(ST_text, ND_text, NL_text, threadType)


def get_diameter(thread_type):
  """Return the screw diameter as float

  Accepted input format are e.g. 'M5', 'M8x1', '(M3.5)', '(M10x1.25)'.
  """
  thread_string = thread_type.lstrip('(M').rstrip(')')
  dia = float(thread_string.split('x')[0])
  return dia


class Screw(object):
  def __init__(self):
    self.objAvailable = True
    self.Tuner = 510
    testCirc=Part.makeCircle(2.0,Base.Vector(0.0,0.0,-0.0),Base.Vector(0.0,0.0,-1.0))
    testDisk = Part.Face(Part.Wire(testCirc))
    z = testDisk.Surface.Axis.z
    if z > 0:
      self.circleAxis = Base.Vector(0.0,0.0,1.0)
    else:
      self.circleAxis = Base.Vector(0.0,0.0,-1.0)

  def check_Data(self, ST_text, ND_text, NL_text):
    #FreeCAD.Console.PrintMessage("Data checking" + NL_text + "\n")
    #set screw not ok
    self.objAvailable = False
    M_text = "Select your screw type"
    Type_text = ''
    if ST_text == 'ISO4017':
      table = iso4017head
      tab_len = iso4017length
      tab_range = iso4017range
      Type_text = 'Screw'

    if ST_text == 'EN1662':
      table = en1662def
      tab_len = en1662length
      tab_range = en1662range
      Type_text = 'Screw'

    if ST_text == 'EN1665':
      table = en1665def
      tab_len = en1665length
      tab_range = en1665range
      Type_text = 'Screw'

    if ST_text == 'ISO8676':
      table = iso8676def
      tab_len = iso8676length
      tab_range = iso8676range
      Type_text = 'Screw'

    if ST_text == 'ISO2009':
      table = iso2009def
      tab_len = iso2009length
      tab_range = iso2009range
      Type_text = 'Screw'
    if ST_text == 'ISO2010':
      table = iso2009def
      tab_len = iso2009length
      tab_range = iso2009range
      Type_text = 'Screw'
    if ST_text == 'ISO4762':
      table = iso4762def
      tab_len = iso4762length
      tab_range = iso4762range
      Type_text = 'Screw'

    if ST_text == 'ISO10642':
      table = iso10642def
      tab_len = iso10642length
      tab_range = iso10642range
      Type_text = 'Screw'

    if ST_text == 'ISO4014':
      table = iso4014head
      tab_len = iso4014length
      tab_range = iso4014range
      Type_text = 'Screw'

    if ST_text == 'ISO1207':
      table = iso1207def
      tab_len = iso1207length
      tab_range = iso1207range
      Type_text = 'Screw'
    if ST_text == 'ISO1580':
      table = iso1580def
      tab_len = iso2009length
      tab_range = iso2009range
      Type_text = 'Screw'

    if ST_text == 'ISO7045':
      table = iso7045def
      tab_len = iso7045length
      tab_range = iso7045range
      Type_text = 'Screw'

    if ST_text == 'ISO7046':
      table = iso7046def  # contains only cross recess data
      tab_len = iso7045length
      tab_range = iso7046range
      Type_text = 'Screw'

    if ST_text == 'ISO7047':
      table = iso2009def
      tab_len = iso7045length
      tab_range = iso7046range
      Type_text = 'Screw'

    if ST_text == 'ISO7048':
      table = iso7048def
      tab_len = iso7048length
      tab_range = iso7048range
      Type_text = 'Screw'

    if ST_text == 'ISO7380-1':
      table = iso7380def
      tab_len = iso7380length
      tab_range = iso7380range
      Type_text = 'Screw'

    if ST_text == 'ISO7380-2':
      table = iso7380_2def
      tab_len = iso7380length
      tab_range = iso7380range
      Type_text = 'Screw'

    if ST_text == 'DIN967':
      table = din967def
      tab_len = din967length
      tab_range = din967range
      Type_text = 'Screw'

    if ST_text == 'ISO14579':
      table = iso14579def
      tab_len = iso14579length
      tab_range = iso14579range
      Type_text = 'Screw'

    if ST_text == 'ISO14580':
      table = iso14580def
      tab_len = iso14580length
      tab_range = iso1207range
      Type_text = 'Screw'

    if ST_text == 'ISO14583':
      table = iso14583def
      tab_len = iso7045length
      tab_range = iso7046range
      Type_text = 'Screw'

    if ST_text == 'ISO14584':
      table = iso14584def
      tab_len = iso7045length
      tab_range = iso14584range
      Type_text = 'Screw'

    if ST_text == 'ISO14582':
      table = iso14582def
      tab_len = iso14582length
      tab_range = iso14582range
      Type_text = 'Screw'

    if ST_text == 'ISO7089':
      table = iso7089def
      Type_text = 'Washer'

    if ST_text == 'ISO7090':
      table = iso7090def
      Type_text = 'Washer'

    if ST_text == 'ISO7091':
      table = iso7091def
      Type_text = 'Washer'

    if ST_text == 'ISO7092':
      table = iso7092def
      Type_text = 'Washer'

    if ST_text == 'ISO7093-1':
      table = iso7093def
      Type_text = 'Washer'

    if ST_text == 'ISO7094':
      table = iso7094def
      Type_text = 'Washer'

    if ST_text == 'ISO4032':
      table = iso4032def
      Type_text = 'Nut'

    if ST_text == 'ISO4033':
      table = iso4033def
      Type_text = 'Nut'

    if ST_text == 'ISO4035':
      table = iso4035def
      Type_text = 'Nut'

    if ST_text == 'ISO4036':
      table = iso4036def
      Type_text = 'Nut'

    if ST_text == 'EN1661':
      table = en1661def
      Type_text = 'Nut'

    if ST_text == 'ScrewTap':
      table = tuningTable
      Type_text = 'Screw-Tap'

    if ND_text not in table:
       ND_min, ND_max = standard_diameters[ST_text]
       M_text = ST_text+' has diameters from '+ ND_min +' to ' + ND_max + ' and not ' + ND_text +'!'
       self.objAvailable = False
       # set scew not ok
    else:
      if Type_text == 'Screw':
        #NL_text = str(self.NominalLength.currentText())
        NL_min, NL_max = tab_range[ND_text]
        NL_min_float = float(NL_min)
        NL_max_float = float(NL_max)
        if (NL_text == 'User') and (ST_text != 'ISO8676'):
          M_text = 'User length is only available for the screw-tab and ISO 8676!'
          self.objAvailable = False
        else:
          if NL_text == 'User':
            M_text = 'ISO 8676 with user length is ok!'
            self.objAvailable = True
          else:
            NL_text_float = float(NL_text)
            if (NL_text_float<NL_min_float)or(NL_text_float>NL_max_float)or(NL_text not in tab_len):
              if '(' in ND_text:
                ND_text = ND_text.lstrip('(').rstrip(')')
              M_text = ST_text+'-'+ ND_text +' has lengths from '+ NL_min +' to ' + NL_max + ' and not ' + NL_text +'!'
              self.objAvailable = False
              # set screw not ok
            else:
              if '(' in ND_text:
                ND_text = ND_text.lstrip('(').rstrip(')')
              M_text = ST_text+'-'+ ND_text +'x'+ NL_text +' is in library available! '
              self.objAvailable = True
              #set screw ok
      else: # Washers and Nuts
        if Type_text != 'Screw-Tap':
          if '(' in ND_text:
            ND_text = ND_text.lstrip('(').rstrip(')')
          M_text = ST_text+'-'+ ND_text +' is available in library!'
          self.objAvailable = True
          #set washer/nut ok
        else:
          if NL_text == 'User':
            M_text = 'Screw-tab with user length is ok!'
            self.objAvailable = True
          else:
            #NL_text = str(self.NominalLength.currentText())
            if '(' in ND_text:
              ND_text = ND_text.lstrip('(').rstrip(')')
            M_text = ST_text+'-'+ ND_text +' with '+ NL_text +'mm length is available in library!'
            self.objAvailable = True
            #set screwTap ok

    #print "Data checking: ", self.NominalLength.currentText(), "\n"
    #FreeCAD.Console.PrintMessage("Set Check_result into text " + str(self.objAvailable) + M_text + "\n")
    return M_text, self.objAvailable


  def createScrew(self, ST_text, ND_text, NL_text, threadType):
    #self.simpThread = self.SimpleScrew.isChecked()
    #self.symThread = self.SymbolThread.isChecked()
    #self.rThread = self.RealThread.isChecked()
    if threadType == 'real':
      self.rThread = True
    else:
      self.rThread = False

    if self.objAvailable:
      try:
        # first we check if valid numbers have been entered
        #FreeCAD.Console.PrintMessage("NominalLength: " + self.NominalLength.currentText() + "\n")
        #FreeCAD.Console.PrintMessage("NominalDiameter: " + self.NominalDiameter.currentText() + "\n")
        #FreeCAD.Console.PrintMessage("SimpleThread: " + str(self.SimpleScrew.isChecked()) + "\n")
        #FreeCAD.Console.PrintMessage("SymbolThread: " + str(self.SymbolThread.isChecked()) + "\n")
        #FreeCAD.Console.PrintMessage("RealThread: " + str(self.RealThread.isChecked()) + "\n")

        #ND_text = str(self.NominalDiameter.currentText())
        #NL_text = str(self.NominalLength.currentText())
        #ST_text = str(self.ScrewType.currentText())
        #ST_text = ST_text.split(':')[0]
        #dia = float(ND_text.lstrip('M'))
        l = float(NL_text)
        if ST_text == 'ISO4017':
           table = iso4017head
        if ST_text == 'ISO4014':
           table = iso4014head
        if ST_text == 'EN1662':
           table = en1662def
        if ST_text == 'EN1665':
           table = en1665def
        if ST_text == 'ISO8676':
           table = iso8676def
        if ST_text == 'ISO2009':
           table = iso2009def
        if ST_text == 'ISO2010':
           table = iso2009def
        if ST_text == 'ISO4762':
           table = iso4762def
        if ST_text == 'ISO10642':
           table = iso10642def
        if ST_text == 'ISO1207':
           table = iso1207def
        if ST_text == 'ISO1580':
           table = iso1580def
        if ST_text == 'ISO7045':
           table = iso7045def
        if ST_text == 'ISO7046':
           table = iso7045def
        if ST_text == 'ISO7047':
           table = iso7045def
        if ST_text == 'ISO7048':
           table = iso7048def
        if ST_text == 'ISO7380-1':
           table = iso7380def
        if ST_text == 'ISO7380-2':
           table = iso7380_2def
        if ST_text == 'DIN967':
           table = din967def
        if ST_text == 'ISO14579':
           table = iso14579def
        if ST_text == 'ISO14580':
           table = iso14580def
        if ST_text == 'ISO14582':
           table = iso14582def
        if ST_text == 'ISO14583':
           table = iso14583def
        if ST_text == 'ISO14584':
           table = iso14584def
        if ST_text == 'ISO7089':
           table = iso7089def
        if ST_text == 'ISO7090':
           table = iso7090def
        if ST_text == 'ISO7091':
           table = iso7091def
        if ST_text == 'ISO7092':
           table = iso7092def
        if ST_text == 'ISO7093-1':
           table = iso7093def
        if ST_text == 'ISO7094':
           table = iso7094def
        if ST_text == 'ISO4032':
           table = iso4032def
        if ST_text == 'ISO4033':
           table = iso4033def
        if ST_text == 'ISO4035':
           table = iso4035def
        if ST_text == 'ISO4036':
           table = iso4036def
        if ST_text == 'EN1661':
           table = en1661def
        if ST_text == 'ScrewTap':
           table = tuningTable
        if ND_text not in table:
           FreeCAD.Console.PrintMessage("Combination of type "+ST_text \
              + " and diameter " + ND_text +" not available!" + "\n")
        #self.MessageLabel.setText(tr('ScrewMaker', 'not implemented'))

      except ValueError:
        #print "Error! nom_dia and length values must be valid numbers!"
        FreeCAD.Console.PrintMessage("Error! nom_dia and length values must be valid numbers!\n")
      else:
        doc=FreeCAD.activeDocument()
        done = False
        if (ST_text == 'ISO4014') or (ST_text == 'ISO4017') or (ST_text == 'ISO8676'):
          screw = self.makeIso4017_2(ST_text, ND_text,l)
          Type_text = 'Screw'
          done = True
        if (ST_text == 'EN1662') or (ST_text == 'EN1665'):
          screw = self.makeEN1662_2(ST_text, ND_text,l)
          Type_text = 'Screw'
          done = True
        if (ST_text == 'ISO2009') or (ST_text == 'ISO2010') or (ST_text == 'ISO1580'):
          screw = self.makeSlottedScrew(ST_text, ND_text,l)
          Type_text = 'Screw'
          done = True
        if (ST_text == 'ISO4762') or (ST_text == 'ISO14579'):
          screw = self.makeIso4762(ST_text, ND_text,l)
          Type_text = 'Screw'
          done = True
        if (ST_text == 'ISO1207') or (ST_text == 'ISO14580') or (ST_text == 'ISO7048'):
          screw = self.makeIso1207(ST_text, ND_text,l)
          Type_text = 'Screw'
          done = True
        if (ST_text == 'ISO7045') or (ST_text == 'ISO14583'):
          screw = self.makeIso7045(ST_text, ND_text,l)
          Type_text = 'Screw'
          done = True
        if (ST_text == 'ISO7046') or (ST_text == 'ISO7047') or \
          (ST_text == 'ISO14582') or (ST_text == 'ISO14584') or (ST_text == 'ISO10642'):
          screw = self.makeIso7046(ST_text, ND_text,l)
          Type_text = 'Screw'
          done = True
        if (ST_text == 'ISO7380-1') or (ST_text == 'ISO7380-2') or (ST_text == 'DIN967'):
          screw = self.makeIso7380(ST_text, ND_text,l)
          Type_text = 'Screw'
          done = True
        if (ST_text == 'ISO7089') or (ST_text == 'ISO7090') or (ST_text == 'ISO7093-1') or \
          (ST_text == 'ISO7091') or (ST_text == 'ISO7092') or (ST_text == 'ISO7094'):
          screw = self.makeIso7089(ST_text, ND_text)
          Type_text = 'Washer'
          done = True
        if (ST_text == 'ISO4032') or (ST_text == 'ISO4033') or (ST_text == 'ISO4035'):
          screw = self.makeIso4032(ST_text, ND_text)
          Type_text = 'Nut'
          done = True
        if ST_text == 'EN1661':
          screw = self.makeEN1661(ND_text)
          Type_text = 'Nut'
          done = True
        if ST_text == 'ScrewTap':
          screw = self.makeScrewTap(ND_text,l)
          Type_text = 'Screw-Tap'
          done = True
        if not done:
          FreeCAD.Console.PrintMessage("No valid Screw Type!" +  "\n")
        if '(' in ND_text:
          ND_text = ND_text.lstrip('(').rstrip(')')

        if Type_text == 'Screw':
          label = ST_text + "-" + ND_text +"x"+ NL_text +"_"
        else:
          if (Type_text == 'Nut'):
            label = ST_text + '-' + ND_text +'_'
          else:
            if Type_text == 'Screw-Tap':
              label = ST_text + '-' + ND_text +'x'+ NL_text +'_'
            else: # washer
              label = ST_text + '-' + ND_text.lstrip('M') +'_'
        ScrewObj = doc.addObject("Part::Feature")
        ScrewObj.Label=label
        ScrewObj.Shape=screw
        #FreeCAD.Console.PrintMessage("Placement: "+ str(ScrewObj.Placement) +"\n")
        #FreeCAD.Console.PrintMessage("The label: "+ label +"\n")
        self.moveScrew(ScrewObj)
        #ScrewObj.Label = label
        if self.gotPart:
          self.thePart.addObject(ScrewObj)
        doc.recompute()
        # Part.show(screw)
        return ScrewObj

  def getFaceAxis(self, sp, c):
    fList = []
    fAxis = None
    if len(c.Vertexes) ==1:
      theVert = c.Vertexes[0]
      # search for faces which have a vertex equal to theVert.
      for f in sp.Faces:
        for v in f.Vertexes:
          if equal_vertex(v, theVert):
            fList.append(f)
    print (str(fList))
    # search for a plane face
    for f in fList:
      if hasattr(f,'Surface'):
        FreeCAD.Console.PrintMessage('type of surface: ', str(f.Surface))
        if f.Surface.isPlanar():
          fAxis = f.Surface.normal(0,0)
          print ('got planar Face with normal: ', str(f.Surface.normal(0,0)))
          print ('Orientation: ', str(f.Orientation))
          if f.Orientation == 'Reversed':
            fAxis = fAxis.multiply(-1.0)
    return fAxis

  def moveScrew(self, ScrewObj_m):
    #FreeCAD.Console.PrintMessage("In Move Screw: " + str(ScrewObj_m) + "\n")
    self.gotBody = False
    self.gotPart = False

    mylist = FreeCAD.Gui.Selection.getSelectionEx()
    if (mylist.__len__() == 1):
       # check selection
       #FreeCAD.Console.PrintMessage("Selektionen: " + str(mylist.__len__()) + "\n")
       Pnt1 = None
       Axis1 = None
       Axis2 = None
       theSelection = mylist[0]
       #FreeCAD.Console.PrintMessage( "ObjectName: " + str(theSelection.ObjectName) + "\n")
       if hasattr(theSelection, 'Object'):
         if hasattr(theSelection.Object, 'InList'):
           inLength = len(theSelection.Object.InList)
           #FreeCAD.Console.PrintMessage( "InList: " + str(theSelection.Object.InList) + "\n")
           for b in theSelection.Object.InList:
             #FreeCAD.Console.PrintMessage( "OType: " + str(b.TypeId) + "\n")
             if b.TypeId == 'PartDesign::Body':
               self.gotBody = True
               self.bPlacement = b.Placement
               for par in b.InList:
                 if par.TypeId == 'App::Part':
                   self.gotPart = True
                   self.thePart = par

                   break

       for o in FreeCADGui.Selection.getSelectionEx():
          #FreeCAD.Console.PrintMessage( "name: " + str(o) + "\n")
          #FreeCAD.Console.PrintMessage( "Properties: " + str(o.PropertiesList) + "\n")

          #for s in o.SubElementNames:
             #FreeCAD.Console.PrintMessage( "name: " + str(s) + "\n")
          for s in o.SubObjects:
             #FreeCAD.Console.PrintMessage( "object: "+ str(s) + "\n")
             #FreeCAD.Console.PrintMessage( "Properties: " + str(s.PropertiesList) + "\n")
             if hasattr(s,"Curve"):
                #FreeCAD.Console.PrintMessage( "The Object is a Curve!\n")
                if hasattr(s.Curve,"Center"):
                   """
                   FreeCAD.Console.PrintMessage( "The object has a Center!\n")
                   FreeCAD.Console.PrintMessage( "Curve attribute. "+ str(s.__getattribute__('Curve')) + "\n")
                   FreeCAD.Console.PrintMessage( "Center: "+ str(s.Curve.Center) + "\n")
                   FreeCAD.Console.PrintMessage( "Axis: "+ str(s.Curve.Axis) + "\n")
                   """
                   Pnt1 = s.Curve.Center
                   Axis1 = s.Curve.Axis
                   fAxis = self.getFaceAxis(o.Object.Shape, s)
                   if fAxis:
                     Axis1 = fAxis
             if hasattr(s,'Surface'):
                #print 'the object is a face!'
                if hasattr(s.Surface,'Axis'):
                   Axis1 = s.Surface.Axis

             if hasattr(s,'Point'):
                #FreeCAD.Console.PrintMessage( "the object seems to be a vertex! "+ str(s.Point) + "\n")
                Pnt1 = s.Point

       if (Axis1 != None):
          #FreeCAD.Console.PrintMessage( "Got Axis1: " + str(Axis1) + "\n")
          Axis2 = Base.Vector(0.0,0.0,1.0)
          Axis2_minus = Base.Vector(0.0,0.0,-1.0)

          # Calculate angle
          if Axis1 == Axis2:
             normvec = Base.Vector(1.0,0.0,0.0)
             result = 0.0
          else:
             if Axis1 == Axis2_minus:
                normvec = Base.Vector(1.0,0.0,0.0)
                result = math.pi
             else:
                normvec = Axis1.cross(Axis2) # Berechne Achse der Drehung = normvec
                normvec.normalize() # Normalisieren fuer Quaternionenrechnung
                #normvec_rot = normvec
                result = DraftVecUtils.angle(Axis1, Axis2, normvec) # Winkelberechnung
          sin_res = math.sin(result/2.0)
          cos_res = math.cos(result/2.0)
          normvec.multiply(-sin_res) # Berechnung der Quaternionen-Elemente
          #FreeCAD.Console.PrintMessage( "Winkel = "+ str(math.degrees(result)) + "\n")
          #FreeCAD.Console.PrintMessage("Normalvektor: "+ str(normvec) + "\n")

          pl = FreeCAD.Placement()
          pl.Rotation = (normvec.x,normvec.y,normvec.z,cos_res) #Drehungs-Quaternion

          #FreeCAD.Console.PrintMessage("pl mit Rot: "+ str(pl) + "\n")
          #neuPlatz = Part2.Object.Placement.multiply(pl)
          neuPlatz = ScrewObj_m.Placement
          FreeCAD.Console.PrintMessage("The Position     "+ str(neuPlatz) + "\n")
          neuPlatz.Rotation = pl.Rotation.multiply(ScrewObj_m.Placement.Rotation)
          # neuPlatz.move(Pnt1)
          FreeCAD.Console.PrintMessage("The Position in Body    "+ str(neuPlatz) + "\n")
          if self.gotBody:
            FreeCAD.Console.PrintMessage("got Placement: "+ str(self.bPlacement) + "\n")
            #neuPlatz.Rotation = neuPlatz.Rotation.multiply(self.bPlacement.Rotation)
            neuPlatz.Rotation = neuPlatz.Rotation.multiply(self.bPlacement.Rotation)
            Pnt1 = self.bPlacement.multVec(Pnt1)
          neuPlatz.move(Pnt1)
          #if self.gotBody:
            #neuPlatz.move(self.bPlacement.Base)

          # Python is not phytonic in FreeCAD 0.17, need to add allocation.
          ScrewObj_m.Placement = neuPlatz
          #FreeCAD.Console.PrintMessage("die rot. Position: "+ str(neuPlatz) + "\n")



  # make Washer
  def makeIso7089(self,SType ='ISO7089', ThreadType ='M6'):
    dia = get_diameter(ThreadType)
    #FreeCAD.Console.PrintMessage("die Scheibe mit dia: " + str(dia) + "\n")
    if SType == 'ISO7089':
      d1_min, d2_max, h, h_max = iso7089def[ThreadType]
    if SType == 'ISO7090':
      d1_min, d2_max, h, h_max = iso7090def[ThreadType]
    if SType == 'ISO7091':
      d1_min, d2_max, h, h_max = iso7091def[ThreadType]
    if SType == 'ISO7092':
      d1_min, d2_max, h, h_max = iso7092def[ThreadType]
    if SType == 'ISO7093-1':
      d1_min, d2_max, h, h_max = iso7093def[ThreadType]
    if SType == 'ISO7094':
      d1_min, d2_max, h, h_max = iso7094def[ThreadType]
      #FreeCAD.Console.PrintMessage("got: " + SType + "\n")

    #FreeCAD.Console.PrintMessage("die Scheibe mit d1_min: " + str(d1_min) + "\n")

    #Washer Points
    Pnt0 = Base.Vector(d1_min/2.0,0.0,h_max)
    Pnt2 = Base.Vector(d2_max/2.0,0.0,h_max)
    Pnt3 = Base.Vector(d2_max/2.0,0.0,0.0)
    Pnt4 = Base.Vector(d1_min/2.0,0.0,0.0)
    if SType == 'ISO7090':
      Pnt1 = Base.Vector(d2_max/2.0-h_max/4.0,0.0,h_max)
      Pnt2 = Base.Vector(d2_max/2.0,0.0,h_max*0.75)
      edge1 = Part.makeLine(Pnt0,Pnt1)
      edgeCham = Part.makeLine(Pnt1,Pnt2)
      edge1 = Part.Wire([edge1, edgeCham])
    else:
      edge1 = Part.makeLine(Pnt0,Pnt2)

    edge2 = Part.makeLine(Pnt2,Pnt3)
    edge3 = Part.makeLine(Pnt3,Pnt4)
    edge4 = Part.makeLine(Pnt4,Pnt0)
    #FreeCAD.Console.PrintMessage("Edges made Pnt2: " + str(Pnt2) + "\n")

    aWire=Part.Wire([edge1,edge2,edge3,edge4])
    #Part.show(aWire)
    aFace =Part.Face(aWire)
    head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #FreeCAD.Console.PrintMessage("Washer revolved: " + str(dia) + "\n")

    return head


  # make ISO 2009 Slotted countersunk flat head screws
  # make ISO 2010 Slotted raised countersunk head screws
  # make ISO 1580 Pan head slotted screw (Code is nearly identical to iso1207)
  def makeSlottedScrew(self,SType ='ISO1580', ThreadType ='M6',l=25.0):
    dia = get_diameter(ThreadType)
    if SType == 'ISO1580':
      #FreeCAD.Console.PrintMessage("der Kopf mit l: " + str(l) + "\n")
      #P, a, b, dk, dk_mean, da, k, n_min, r, t_min, x = iso1580def[ThreadType]
      P, a, b, dk_max, da, k, n_min, r, rf, t_min, x = iso1580def[ThreadType]
      #FreeCAD.Console.PrintMessage("der Kopf mit iso: " + str(dk_max) + "\n")
      ht = k
      headEnd = r

      #Length for calculation of head fillet
      sqrt2_ = 1.0/math.sqrt(2.0)
      r_fil = rf
      beta = math.radians(5.0)   # angle of pan head edge
      alpha = math.radians(90.0 - (90.0+5.0)/2.0)
      tan_beta = math.tan(beta)
      # top head diameter without fillet
      rK_top = dk_max/2.0 - k * tan_beta
      fillet_center_x = rK_top - r_fil + r_fil * tan_beta
      fillet_center_z = k - r_fil
      fillet_arc_x = fillet_center_x + r_fil * math.sin(alpha)
      fillet_arc_z = fillet_center_z + r_fil * math.cos(alpha)
      #FreeCAD.Console.PrintMessage("rK_top: " + str(rK_top) + "\n")
      if (b > (l - 1.0*P)):
        bmax = l- 1.0*P
      else:
        bmax = b

      #Head Points
      Pnt0 = Base.Vector(0.0,0.0,k)
      Pnt2 = Base.Vector(fillet_center_x,0.0,k)
      Pnt3 = Base.Vector(fillet_arc_x,0.0,fillet_arc_z)
      Pnt4 = Base.Vector(fillet_center_x + r_fil*math.cos(beta),0.0,fillet_center_z+ r_fil * math.sin(beta))
      Pnt5 = Base.Vector(dk_max/2.0,0.0,0.0)
      Pnt6 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
      Pnt7 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
      #Pnt8 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
      PntR = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
      PntT0 = Base.Vector(0.0,0.0,-r)        # helper point for real thread

      edge1 = Part.makeLine(Pnt0,Pnt2)
      edge2 = Part.Arc(Pnt2,Pnt3,Pnt4).toShape()
      edge3 = Part.makeLine(Pnt4,Pnt5)
      edge4 = Part.makeLine(Pnt5,Pnt6)
      edge5 = Part.Arc(Pnt6,Pnt7,PntR).toShape()
      headWire=Part.Wire([edge1,edge2,edge3,edge4,edge5])

    if (SType == 'ISO2009') or (SType == 'ISO2010'):
      P, a, b, dk_theo, dk_mean, k, n_min, r, t_mean, x = iso2009def[ThreadType]
      dk_max = dk_theo
      t_min = t_mean
      ht = 0.0 # Head height of flat head
      if (SType == 'ISO2010'):
        rf, t_mean, cT, mH, mZ = Raised_countersunk_def[ThreadType]
        #Lengths and angles for calculation of head rounding
        beta = math.asin(dk_mean /2.0 / rf)   # angle of head edge
        tan_beta = math.tan(beta)
        alpha = beta/2.0 # half angle
        # height of raised head top
        ht = rf - (dk_mean/2.0) / tan_beta
        h_arc_x = rf * math.sin(alpha)
        h_arc_z = ht - rf + rf * math.cos(alpha)

      cham = (dk_theo - dk_mean)/2.0
      rad225 = math.radians(22.5)
      rad45 = math.radians(45.0)
      rtan = r*math.tan(rad225)
      headEnd = k + rtan

      if (b > l - k - rtan/2.0 - 1.0*P):
        bmax = l-k-rtan/2.0 - 1.0*P
      else:
        bmax = b

      #Head Points
      Pnt0 = Base.Vector(0.0,0.0,ht)
      Pnt1 = Base.Vector(dk_mean/2.0,0.0,0.0)
      Pnt2 = Base.Vector(dk_mean/2.0,0.0,-cham)
      Pnt3 = Base.Vector(dia/2.0+r-r*math.cos(rad45),0.0,-k-rtan+r*math.sin(rad45))
      # Arc-points
      Pnt4 = Base.Vector(dia/2.0+r-r*(math.cos(rad225)),0.0,-k-rtan+r*math.sin(rad225))
      PntR = Base.Vector(dia/2.0,0.0,-k-rtan)
      #PntA = Base.Vector(dia/2.0,0.0,-a_point)
      PntT0 = Base.Vector(0.0,0.0,-k-rtan)        # helper point for real thread

      if (SType == 'ISO2010'): # make raised head rounding
        Pnt0arc = Base.Vector(h_arc_x,0.0,h_arc_z)
        edge1 = Part.Arc(Pnt0,Pnt0arc,Pnt1).toShape()
      else:
        edge1 = Part.makeLine(Pnt0,Pnt1)  # make flat head

      edge2 = Part.makeLine(Pnt1,Pnt2)
      edge3 = Part.makeLine(Pnt2,Pnt3)
      edgeArc = Part.Arc(Pnt3,Pnt4,PntR).toShape()
      headWire=Part.Wire([edge1,edge2,edge3,edgeArc])


    ### make the new code with math.modf(l)
    residue, turns = math.modf((bmax)/P)
    halfturns = 2*int(turns)
    if residue < 0.5:
      a_point = l - (turns+1.0) * P
      halfturns = halfturns +1
    else:
      halfturns = halfturns + 2
      a_point = l - (turns+2.0) * P
    #halfturns = halfturns + 2
    offSet = headEnd - a_point
    PntA = Base.Vector(dia/2.0,0.0,-a_point)        # Start of thread


    if self.rThread:
      edgeZ1 = Part.makeLine(PntR,PntT0)
      edgeZ0 = Part.makeLine(PntT0,Pnt0)
      aWire=Part.Wire([headWire, edgeZ1, edgeZ0])

    else:
      # bolt points
      PntB1 = Base.Vector(dia/2.0,0.0,-l)
      PntB2 = Base.Vector(0.0,0.0,-l)

      edgeB2 = Part.makeLine(PntB1,PntB2)
      edgeZ0 = Part.makeLine(PntB2,Pnt0)

      if a_point <= r:
        edgeB1 = Part.makeLine(PntR,PntB1)
        aWire=Part.Wire([headWire, edgeB1, edgeB2, edgeZ0])
      else:
        edgeRA = Part.makeLine(PntR,PntA)
        edgeB1 = Part.makeLine(PntA,PntB1)
        aWire=Part.Wire([headWire, edgeRA, edgeB1, edgeB2, edgeZ0])

    aFace =Part.Face(aWire)
    head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")

    #Parameter for slot-recess: dk_max, n_min, k, t_min
    slot = Part.makePlane(dk_max, n_min, \
        Base.Vector(dk_max/2.0,-n_min/2.0,ht+1.0),Base.Vector(0.0,0.0,-1.0))
    slot = slot.extrude(Base.Vector(0.0,0.0,-t_min-1.0))
    #Part.show(slot)
    head = head.cut(slot)
    #FreeCAD.Console.PrintMessage("der Kopf geschnitten: " + str(dia) + "\n")
    #Part.show(head)

    if self.rThread:
      rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
      rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
      #Part.show(rthread)
      headFaces = []
      if (SType == 'ISO2009'):
        for i in range(0,len(head.Faces)-2):
          headFaces.append(head.Faces[i])
        headFaces.append(head.Faces[len(head.Faces)-1])

      if (SType == 'ISO1580') or (SType == 'ISO2010'):
        for i in range(0,len(head.Faces)-1):
          headFaces.append(head.Faces[i])

      for threadFace in rthread.Faces:
        headFaces.append(threadFace)

      newHeadShell = Part.Shell(headFaces)
      #Part.show(newHeadShell)
      head = Part.Solid(newHeadShell)

    return head






  # ISO 7045 Pan head screws with type H or type Z cross recess
  # ISO 14583 Hexalobular socket pan head screws
  def makeIso7045(self, SType ='ISO7045', ThreadType ='M6',l=25.0):
    dia = get_diameter(ThreadType)
    #FreeCAD.Console.PrintMessage("der Kopf mit l: " + str(l) + "\n")
    P, a, b, dk_max,da, k, r, rf, x, cT, mH, mZ  = iso7045def[ThreadType]
    #FreeCAD.Console.PrintMessage("der Kopf mit iso: " + str(dk_max) + "\n")

    #Lengths and angles for calculation of head rounding
    beta = math.asin(dk_max /2.0 / rf)   # angle of head edge
    #print 'beta: ', math.degrees(beta)
    tan_beta = math.tan(beta)


    if SType == 'ISO14583':
       tt, A, t_mean = iso14583def[ThreadType]
       beta_A = math.asin(A/2.0 / rf)   # angle of recess edge
       tan_beta_A = math.tan(beta_A)

       alpha = (beta_A + beta)/2.0 # half angle
       #print 'alpha: ', math.degrees(alpha)
       # height of head edge
       he = k - A/2.0/tan_beta_A + (dk_max/2.0) / tan_beta
       #print 'he: ', he
       h_arc_x = rf * math.sin(alpha)
       h_arc_z = k - A/2.0/tan_beta_A + rf * math.cos(alpha)
       #FreeCAD.Console.PrintMessage("h_arc_z: " + str(h_arc_z) + "\n")
    else:
       alpha = beta/2.0 # half angle
       #print 'alpha: ', math.degrees(alpha)
       # height of head edge
       he = k - rf + (dk_max/2.0) / tan_beta
       #print 'he: ', he
       h_arc_x = rf * math.sin(alpha)
       h_arc_z = k - rf + rf * math.cos(alpha)
       #FreeCAD.Console.PrintMessage("h_arc_z: " + str(h_arc_z) + "\n")

    if (b > (l - 1.0*P)):
       bmax = l- 1.0*P
    else:
       bmax = b

    ### make the new code with math.modf(l)
    residue, turns = math.modf((bmax)/P)
    halfturns = 2*int(turns)
    if residue < 0.5:
      a_point = l - (turns+1.0) * P
      halfturns = halfturns +1
    else:
      halfturns = halfturns + 2
      a_point = l - (turns+2.0) * P
    #halfturns = halfturns + 2
    offSet = r - a_point
    #FreeCAD.Console.PrintMessage("The transition at a: " + str(a) + " turns " + str(turns) + "\n")

    sqrt2_ = 1.0/math.sqrt(2.0)

    #Head Points
    Pnt1 = Base.Vector(h_arc_x,0.0,h_arc_z)
    Pnt2 = Base.Vector(dk_max/2.0,0.0,he)
    Pnt3 = Base.Vector(dk_max/2.0,0.0,0.0)
    Pnt4 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
    Pnt5 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
    Pnt6 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
    Pnt7 = Base.Vector(dia/2.0,0.0,-a_point)        # Start of thread
    #FreeCAD.Console.PrintMessage("Points defined a_point: " + str(a_point) + "\n")


    if (SType == 'ISO14583'):
      #Pnt0 = Base.Vector(0.0,0.0,k-A/4.0)
      Pnt0 = Base.Vector(0.0,0.0,k-A/8.0)
      PntFlat = Base.Vector(A/8.0,0.0,k-A/8.0)
      PntCham = Base.Vector(A/1.99,0.0,k)
      edgeCham0 = Part.makeLine(Pnt0,PntFlat)
      edgeCham1 = Part.makeLine(PntFlat,PntCham)
      edgeCham2 = Part.Arc(PntCham,Pnt1,Pnt2).toShape()
      #edge1 = Part.Wire([edgeCham0,edgeCham1,edgeCham2])
      edge1 = Part.Wire([edgeCham0,edgeCham1])
      edge2 = Part.makeLine(Pnt2,Pnt3)
      edge2 = Part.Wire([edgeCham2, edge2])
      # Part.show(edge2)

      # Here is the next approach to shorten the head building time
      # Make two helper points to create a cutting tool for the
      # recess and recess shell.
      PntH1 = Base.Vector(A/1.99,0.0, 2.0*k)
      PntH2 = Base.Vector(0.0,0.0, 2.0*k)
      edgeH1 = Part.makeLine(PntCham,PntH1)
      edgeH2 = Part.makeLine(PntH1,PntH2)
      edgeH3 = Part.makeLine(PntH2,Pnt0)

    else:
      Pnt0 = Base.Vector(0.0,0.0,k)
      edge1 = Part.Arc(Pnt0,Pnt1,Pnt2).toShape()  # make round head
      edge2 = Part.makeLine(Pnt2,Pnt3)

      # Here is the next approach to shorten the head building time
      # Make two helper points to create a cutting tool for the
      # recess and recess shell.
      PntH1 = Base.Vector(dk_max/2.0,0.0, 2.0*k)
      PntH2 = Base.Vector(0.0,0.0, 2.0*k)
      edgeH1 = Part.makeLine(Pnt2,PntH1)
      edgeH2 = Part.makeLine(PntH1,PntH2)
      edgeH3 = Part.makeLine(PntH2,Pnt0)

    edge3 = Part.makeLine(Pnt3,Pnt4)
    edge4 = Part.Arc(Pnt4,Pnt5,Pnt6).toShape()
    #FreeCAD.Console.PrintMessage("Edges made h_arc_z: " + str(h_arc_z) + "\n")

    #if self.RealThread.isChecked():
    if self.rThread:
      aWire=Part.Wire([edge2,edge3,edge4])
    else:
      # bolt points
      PntB1 = Base.Vector(dia/2.0,0.0,-l)
      PntB2 = Base.Vector(0.0,0.0,-l)
      edgeB2 = Part.makeLine(PntB1,PntB2)
      if a_point <= r:
        edgeB1 = Part.makeLine(Pnt6,PntB1)
        aWire=Part.Wire([edge2, edge3, edge4, edgeB1, edgeB2])
      else:
        edge5 = Part.makeLine(Pnt6,Pnt7)
        edgeB1 = Part.makeLine(Pnt7,PntB1)
        aWire=Part.Wire([edge2, edge3, edge4, edge5, edgeB1, edgeB2])



    hWire = Part.Wire([edge1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
    hFace = Part.Face(hWire)
    hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #Part.show(hWire)

    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #head = Part.Solid(headShell)
    #Part.show(aWire)
    #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
    headFaces = headShell.Faces

    if (SType == 'ISO14583'):
      recess, recessShell = self.makeIso10664_3(tt, t_mean, k)
      recessShell = recessShell.cut(hCut)
      topFace = hCut.Faces[1]
      topFace = topFace.cut(recess)
      #Part.show(topFace)
      #Part.show(recessShell)
      #Part.show(headShell)
      headFaces.append(topFace.Faces[0])
      #headFaces.append(hCut.Faces[2])

    else:
      #Lengths and angles for calculation of recess positioning
      beta_cr = math.asin(mH /2.0 / rf)   # angle of recess edge
      tan_beta_cr = math.tan(beta_cr)
      # height of cross recess cutting
      hcr = k - rf + (mH/2.0) / tan_beta_cr
      #print 'hcr: ', hcr

      #Parameter for cross-recess type H: cT, mH
      recess, recessShell = self.makeCross_H3(cT, mH, hcr)
      recessShell = recessShell.cut(hCut)
      topFace = hCut.Faces[0]
      topFace = topFace.cut(recess)
      #Part.show(topFace)
      #Part.show(recessShell)
      #Part.show(headShell)
      headFaces.append(topFace.Faces[0])

    #Part.show(hCut)
    headFaces.extend(recessShell.Faces)


    #if self.RealThread.isChecked():
    if self.rThread:
      #head = self.cutIsoThread(head, dia, P, turns, l)
      rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
      rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
      #head = head.fuse(rthread)
      #Part.show(rthread)
      for threadFace in rthread.Faces:
        headFaces.append(threadFace)

    newHeadShell = Part.Shell(headFaces)
    #Part.show(newHeadShell)
    head = Part.Solid(newHeadShell)

    return head


  # make Cheese head screw
  # ISO 1207 slotted screw
  # ISO 7048 cross recessed screw
  # ISO 14580 Hexalobular socket cheese head screws
  def makeIso1207(self,SType ='ISO1207', ThreadType ='M6',l=25.0):
    dia = get_diameter(ThreadType)
    '''
    if '(' in TreadType:
      threadString = ThreadType.lstrip('(M')
      dia = float(ThreadType.rstrip(')'))
    else:
      dia=float(ThreadType.lstrip('M'))
    '''
    #FreeCAD.Console.PrintMessage("der Kopf mit l: " + str(l) + "\n")
    if (SType == 'ISO1207') or (SType == 'ISO14580'):
       P, a, b, dk, dk_mean, da, k, n_min, r, t_min, x = iso1207def[ThreadType]
    if SType == 'ISO7048':
       P, a, b, dk, dk_mean, da, k, r, x, cT, mH, mZ  = iso7048def[ThreadType]
    if (SType == 'ISO14580'):
       tt, k, A, t_min = iso14580def[ThreadType]

    #FreeCAD.Console.PrintMessage("der Kopf mit iso: " + str(dk) + "\n")

    #Length for calculation of head fillet
    r_fil = r*2.0
    beta = math.radians(5.0)   # angle of cheese head edge
    alpha = math.radians(90.0 - (90.0+5.0)/2.0)
    tan_beta = math.tan(beta)
    # top head diameter without fillet
    rK_top = dk/2.0 - k * tan_beta
    fillet_center_x = rK_top - r_fil + r_fil * tan_beta
    fillet_center_z = k - r_fil
    fillet_arc_x = fillet_center_x + r_fil * math.sin(alpha)
    fillet_arc_z = fillet_center_z + r_fil * math.cos(alpha)
    #FreeCAD.Console.PrintMessage("rK_top: " + str(rK_top) + "\n")

    if (b > (l - 1.0*P)):
       bmax = l- 1.0*P
    else:
       bmax = b

    ### make the new code with math.modf(l)
    residue, turns = math.modf((bmax)/P)
    halfturns = 2*int(turns)
    if residue < 0.5:
      a_point = l - (turns+1.0) * P
      halfturns = halfturns +1
    else:
      halfturns = halfturns + 2
      a_point = l - (turns+2.0) * P
    #halfturns = halfturns + 2
    offSet = r - a_point

    sqrt2_ = 1.0/math.sqrt(2.0)

    #Head Points
    Pnt2 = Base.Vector(fillet_center_x,0.0,k)
    Pnt3 = Base.Vector(fillet_arc_x,0.0,fillet_arc_z)
    Pnt4 = Base.Vector(fillet_center_x + r_fil*math.cos(beta),0.0,fillet_center_z+ r_fil * math.sin(beta))
    Pnt5 = Base.Vector(dk/2.0,0.0,0.0)
    Pnt6 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
    Pnt7 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
    Pnt8 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
    Pnt9 = Base.Vector(dia/2.0,0.0,-a_point)        # Start of thread
    #FreeCAD.Console.PrintMessage("Points defined fillet_center_x: " + str(fillet_center_x) + "\n")

    if (SType == 'ISO14580'):
      # Pnt0 = Base.Vector(0.0,0.0,k-A/4.0) #Center Point for countersunk
      Pnt0 = Base.Vector(0.0,0.0,k-A/8.0) #Center Point for flat countersunk
      PntFlat = Base.Vector(A/8.0,0.0,k-A/8.0) # End of flat part
      Pnt1 = Base.Vector(A/1.99,0.0,k)     #countersunk edge at head
      edgeCham0 = Part.makeLine(Pnt0,PntFlat)
      edgeCham1 = Part.makeLine(PntFlat,Pnt1)
      edgeCham2 = Part.makeLine(Pnt1,Pnt2)
      edge1 = Part.Wire([edgeCham1,edgeCham2]) # make head with countersunk
      PntH1 = Base.Vector(A/1.99,0.0, 2.0*k)

    else:
      Pnt0 = Base.Vector(0.0,0.0,k)
      edge1 = Part.makeLine(Pnt0,Pnt2)  # make flat head


    edge2 = Part.Arc(Pnt2,Pnt3,Pnt4).toShape()
    edge3 = Part.makeLine(Pnt4,Pnt5)
    edge4 = Part.makeLine(Pnt5,Pnt6)
    edge5 = Part.Arc(Pnt6,Pnt7,Pnt8).toShape()
    #FreeCAD.Console.PrintMessage("Edges made fillet_center_z: " + str(fillet_center_z) + "\n")

    if SType == 'ISO1207':
      #Parameter for slot-recess: dk, n_min, k, t_min
      recess = Part.makePlane(dk, n_min, \
        Base.Vector(dk/2.0,-n_min/2.0,k+1.0),Base.Vector(0.0,0.0,-1.0))
      recess = recess.extrude(Base.Vector(0.0,0.0,-t_min-1.0))

      if self.rThread:
        Pnt11 = Base.Vector(0.0,0.0,-r)        # helper point for real thread
        edgeZ1 = Part.makeLine(Pnt8,Pnt11)
        edgeZ0 = Part.makeLine(Pnt11,Pnt0)
        aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5, \
            edgeZ1, edgeZ0])
      else:
        # bolt points
        PntB1 = Base.Vector(dia/2.0,0.0,-l)
        PntB2 = Base.Vector(0.0,0.0,-l)

        edgeB2 = Part.makeLine(PntB1,PntB2)

        if a_point <= r:
          edgeB1 = Part.makeLine(Pnt8,PntB1)
          aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5, \
              edgeB1, edgeB2])
        else:
          edge6 = Part.makeLine(Pnt8,Pnt9)
          edgeB1 = Part.makeLine(Pnt9,PntB1)
          aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6, \
              edgeB1, edgeB2])

      aFace =Part.Face(aWire)
      head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
      head = head.cut(recess)
      # FreeCAD.Console.PrintMessage("der Kopf geschnitten: " + str(dia) + "\n")
      #Part.show(head)
      if self.rThread:
        screwFaces = []
        for i in range(0, len(head.Faces)-1):
          screwFaces.append(head.Faces[i])
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
        for threadFace in rthread.Faces:
          screwFaces.append(threadFace)

        screwShell = Part.Shell(screwFaces)
        head = Part.Solid(screwShell)



    else:
      if self.rThread:
        aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5 ])
      else:
        # bolt points
        PntB1 = Base.Vector(dia/2.0,0.0,-l)
        PntB2 = Base.Vector(0.0,0.0,-l)

        edgeB2 = Part.makeLine(PntB1,PntB2)

        if a_point <= r:
          edgeB1 = Part.makeLine(Pnt8,PntB1)
          aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5, \
              edgeB1, edgeB2])
        else:
          edge6 = Part.makeLine(Pnt8,Pnt9)
          edgeB1 = Part.makeLine(Pnt9,PntB1)
          aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6, \
              edgeB1, edgeB2])

      #aFace =Part.Face(aWire)
      headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
      #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")

      if SType == 'ISO7048':
        # hCut should be just a cylinder
        hCut = Part.makeCylinder(fillet_center_x,k,Pnt0)
        recess, recessShell = self.makeCross_H3(cT, mH, k)
        recessShell = recessShell.cut(hCut)
        topFace = headShell.Faces[0].cut(recess)
        screwFaces = [topFace.Faces[0]]
        screwFaces.extend(recessShell.Faces)
      if (SType == 'ISO14580'):
        # Ring-cutter for recess shell
        PntH2 = Base.Vector(A/8.0,0.0, 2.0*k)
        edgeH1 = Part.makeLine(Pnt1,PntH1)
        edgeH2 = Part.makeLine(PntH1,PntH2)
        edgeH3 = Part.makeLine(PntH2,PntFlat)
        hWire = Part.Wire([edgeCham1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
        hFace = Part.Face(hWire)
        hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
        #Part.show(hWire)

        recess, recessShell = self.makeIso10664_3(tt, t_min, k)
        recessShell = recessShell.cut(hCut)
        topFace = headShell.Faces[0].cut(recess)
        screwFaces = [topFace.Faces[0]]
        screwFaces.extend(recessShell.Faces)

      for i in range(1, len(headShell.Faces)):
        screwFaces.append(headShell.Faces[i])

      if self.rThread:
        #head = self.cutIsoThread(head, dia, P, turns, l)
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
        #head = head.fuse(rthread)
        #Part.show(rthread)
        for threadFace in rthread.Faces:
          screwFaces.append(threadFace)

      screwShell = Part.Shell(screwFaces)
      head = Part.Solid(screwShell)

    return head



  # make the ISO 4017 Hex-head-screw
  # make the ISO 4014 Hex-head-bolt
  def makeIso4017_2(self,SType ='ISO4017', ThreadType ='M6',l=40.0):
    dia = get_diameter(ThreadType)
    #FreeCAD.Console.PrintMessage("der Kopf mit l: " + str(l) + "\n")
    if SType == 'ISO4017':
      P, c, dw, e,k,r,s = iso4017head[ThreadType]
      residue, turns = math.modf((l-1*P)/P)
      halfturns = 2*int(turns)

    if SType == 'ISO8676':
      P, c, dw, e,k,r,s = iso8676def[ThreadType]
      residue, turns = math.modf((l-r-1*P)/P)
      halfturns = 2*int(turns)

    if SType == 'ISO4014':
      P, b1, b2, b3, c, dw, e, k, r, s = iso4014head[ThreadType]
      if l<= 125.0:
         b = b1
      else:
         if l<= 200.0:
            b = b2
         else:
            b = b3
      residue, turns = math.modf((b)/P)
      halfturns = 2*int(turns)

    if residue < 0.5:
      a = l - (turns+1.0) * P
      halfturns = halfturns +1
    else:
      halfturns = halfturns + 2
      a = l - (turns+2.0) * P
    #halfturns = halfturns + 2
    offSet = r - a

    sqrt2_ = 1.0/math.sqrt(2.0)
    cham = (e-s)*math.sin(math.radians(15)) # needed for chamfer at head top

    #Head Points  Usage of k, s, cham, c, dw, dia, r, a
    #FreeCAD.Console.PrintMessage("der Kopf mit halfturns: " + str(halfturns) + "\n")
    Pnt0 = Base.Vector(0.0,0.0,k)
    Pnt2 = Base.Vector(s/2.0,0.0,k)
    Pnt3 = Base.Vector(s/math.sqrt(3.0),0.0,k-cham)
    Pnt4 = Base.Vector(s/math.sqrt(3.0),0.0,c)
    Pnt5 = Base.Vector(dw/2.0,0.0,c)
    Pnt6 = Base.Vector(dw/2.0,0.0,0.0)
    Pnt7 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
    Pnt8 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
    Pnt9 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
    Pnt10 = Base.Vector(dia/2.0,0.0,-a)        # Start of thread

    edge1 = Part.makeLine(Pnt0,Pnt2)
    edge2 = Part.makeLine(Pnt2,Pnt3)
    edge3 = Part.makeLine(Pnt3,Pnt4)
    edge4 = Part.makeLine(Pnt4,Pnt5)
    edge5 = Part.makeLine(Pnt5,Pnt6)
    edge6 = Part.makeLine(Pnt6,Pnt7)
    edge7 = Part.Arc(Pnt7,Pnt8,Pnt9).toShape()

    # create cutting tool for hexagon head
    # Parameters s, k, outer circle diameter =  e/2.0+10.0
    extrude = self.makeHextool(s, k, s*2.0)

    #if self.RealThread.isChecked():
    if self.rThread:
      Pnt11 = Base.Vector(0.0,0.0,-r)        # helper point for real thread
      edgeZ1 = Part.makeLine(Pnt9,Pnt11)
      edgeZ0 = Part.makeLine(Pnt11,Pnt0)
      aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6,edge7, \
          edgeZ1, edgeZ0])

      aFace =Part.Face(aWire)
      head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
      #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")

      # Part.show(extrude)
      head = head.cut(extrude)
      #FreeCAD.Console.PrintMessage("der Kopf geschnitten: " + str(dia) + "\n")
      #Part.show(head)

      headFaces = []
      for i in range(18):
        headFaces.append(head.Faces[i])

      if (dia < 3.0) or (dia > 5.0):
        rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a-2.0*P))
        #rthread.translate(Base.Vector(0.0, 0.0,-2.0*P))
        #Part.show(rthread)
        for tFace in rthread.Faces:
          headFaces.append(tFace)
        headShell = Part.Shell(headFaces)
        head = Part.Solid(headShell)
      else:
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a-2.0*P))
        #rthread.translate(Base.Vector(0.0, 0.0,-2.0*P))
        #Part.show(rthread)
        for tFace in rthread.Faces:
          headFaces.append(tFace)
        headShell = Part.Shell(headFaces)
        head = Part.Solid(headShell)
        cyl = self.cutChamfer(dia, P, l)
        #FreeCAD.Console.PrintMessage("vor Schnitt Ende: " + str(dia) + "\n")
        head = head.cut(cyl)

    else:
      # bolt points
      cham_t = P*math.sqrt(3.0)/2.0*17.0/24.0

      PntB0 = Base.Vector(0.0,0.0,-a)
      PntB1 = Base.Vector(dia/2.0,0.0,-l+cham_t)
      PntB2 = Base.Vector(dia/2.0-cham_t,0.0,-l)
      PntB3 = Base.Vector(0.0,0.0,-l)

      edgeB1 = Part.makeLine(Pnt10,PntB1)
      edgeB2 = Part.makeLine(PntB1,PntB2)
      edgeB3 = Part.makeLine(PntB2,PntB3)

      edgeZ0 = Part.makeLine(PntB3,Pnt0)
      if a <= r:
        edgeB1 = Part.makeLine(Pnt9,PntB1)
        aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6,edge7, \
            edgeB1, edgeB2, edgeB3, edgeZ0])

      else:
        edge8 = Part.makeLine(Pnt9,Pnt10)
        edgeB1 = Part.makeLine(Pnt10,PntB1)
        aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6,edge7,edge8, \
            edgeB1, edgeB2, edgeB3, edgeZ0])

      aFace =Part.Face(aWire)
      head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
      #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")

      # Part.show(extrude)
      head = head.cut(extrude)
      #FreeCAD.Console.PrintMessage("der Kopf geschnitten: " + str(dia) + "\n")

    return head


  # EN 1662 Hex-head-bolt with flange - small series
  # EN 1665 Hexagon bolts with flange, heavy series
  def makeEN1662_2(self,SType ='EN1662', ThreadType ='M8',l=25.0):
    dia = get_diameter(ThreadType)
    #FreeCAD.Console.PrintMessage("der Kopf mit l: " + str(l) + "\n")
    if SType == 'EN1662':
       P, b0, b1, b2, b3, c, dc, dw, e, k, kw,f, r1, s = en1662def[ThreadType]
    else:
       P, b0, b1, b2, b3, c, dc, dw, e, k, kw,f, r1, s = en1665def[ThreadType]
    if l< b0:
       b = l - 2*P
    else:
       if l<= 125.0:
          b = b1
       else:
          if l<= 200.0:
             b = b2
          else:
             b = b3

    #FreeCAD.Console.PrintMessage("der Kopf mit isoEN1662: " + str(c) + "\n")
    cham = s*(2.0/math.sqrt(3.0)-1.0)*math.sin(math.radians(25)) # needed for chamfer at head top

    ### make the new code with math.modf(l)
    residue, turns = math.modf((b)/P)
    halfturns = 2*int(turns)
    if residue < 0.5:
      a_point = l - (turns+1.0) * P
      halfturns = halfturns +1
    else:
      halfturns = halfturns + 2
      a_point = l - (turns+2.0) * P
    #halfturns = halfturns + 2
    offSet = r1 - a_point

    sqrt2_ = 1.0/math.sqrt(2.0)

    # Flange is made with a radius of c
    beta = math.radians(25.0)
    tan_beta = math.tan(beta)

    # Calculation of Arc points of flange edge using dc and c
    arc1_x = dc/2.0 - c/2.0 + (c/2.0)*math.sin(beta)
    arc1_z = c/2.0 + (c/2.0)*math.cos(beta)

    hF = arc1_z + (arc1_x -s/2.0) * tan_beta  # height of flange at center

    kmean = arc1_z + (arc1_x - s/math.sqrt(3.0)) * tan_beta + kw * 1.1 + cham
    #kmean = k * 0.95


    #Hex-Head Points
    #FreeCAD.Console.PrintMessage("der Kopf mit math a: " + str(a_point) + "\n")
    PntH0 = Base.Vector(0.0,0.0,kmean*0.9)
    PntH1 = Base.Vector(s/2.0*0.8 - r1/2.0,0.0,kmean*0.9)
    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_)
    PntH1b = Base.Vector(s/2.0*0.8,0.0,kmean*0.9 +r1/2.0)
    PntH2 = Base.Vector(s/2.0*0.8,0.0,kmean -r1)
    PntH2a = Base.Vector(s/2.0*0.8+r1-r1*sqrt2_,0.0,kmean -r1 +r1*sqrt2_)
    PntH2b = Base.Vector(s/2.0*0.8 + r1 ,0.0,kmean)
    PntH3 = Base.Vector(s/2.0,0.0,kmean)
    #PntH4 = Base.Vector(s/math.sqrt(3.0),0.0,kmean-cham)   #s/math.sqrt(3.0)
    #PntH5 = Base.Vector(s/math.sqrt(3.0),0.0,c)
    #PntH6 = Base.Vector(0.0,0.0,c)

    edgeH1 = Part.makeLine(PntH0,PntH1)
    edgeH2 = Part.Arc(PntH1,PntH1a,PntH1b).toShape()
    edgeH3 = Part.makeLine(PntH1b,PntH2)
    edgeH3a = Part.Arc(PntH2,PntH2a,PntH2b).toShape()
    edgeH3b = Part.makeLine(PntH2b,PntH3)

    hWire=Part.Wire([edgeH1,edgeH2,edgeH3,edgeH3a,edgeH3b])
    topShell = hWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #Part.show(hWire)
    #Part.show(topShell)

    # create a cutter ring to generate the chamfer at the top of the hex
    chamHori = s/math.sqrt(3.0) - s/2.0
    PntC1 = Base.Vector(s/2.0-chamHori,0.0,kmean+kmean)
    PntC2 = Base.Vector(s/math.sqrt(3.0)+chamHori,0.0,kmean+kmean)
    PntC3 = Base.Vector(s/2.0-chamHori,0.0,kmean+cham)
    PntC4 = Base.Vector(s/math.sqrt(3.0)+chamHori,0.0,kmean-cham-cham)   #s/math.sqrt(3.0)
    edgeC1 = Part.makeLine(PntC3, PntC1)
    edgeC2 = Part.makeLine(PntC1, PntC2)
    edgeC3 = Part.makeLine(PntC2, PntC4)
    edgeC4 = Part.makeLine(PntC4, PntC3)
    cWire = Part.Wire([edgeC4, edgeC1, edgeC2, edgeC3])
    cFace = Part.Face(cWire)
    chamCut = cFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #Part.show(cWire)
    #Part.show(chamCut)


    # create hexagon
    mhex=Base.Matrix()
    mhex.rotateZ(math.radians(60.0))
    polygon = []
    vhex=Base.Vector(s/math.sqrt(3.0),0.0,kmean)
    for i in range(6):
       polygon.append(vhex)
       vhex = mhex.multiply(vhex)
    polygon.append(vhex)
    hexagon = Part.makePolygon(polygon)
    hexFace = Part.Face(hexagon)
    solidHex = hexFace.extrude(Base.Vector(0.0,0.0,c-kmean))
    #Part.show(solidHex)
    hexCham = solidHex.cut(chamCut)
    #Part.show(hexCham)

    topFaces = topShell.Faces

    topFaces.append(hexCham.Faces[6])
    topFaces.append(hexCham.Faces[12])
    topFaces.append(hexCham.Faces[14])
    topFaces.append(hexCham.Faces[13])
    topFaces.append(hexCham.Faces[8])
    topFaces.append(hexCham.Faces[2])
    topFaces.append(hexCham.Faces[1])

    hexFaces = [hexCham.Faces[5], hexCham.Faces[11], hexCham.Faces[10]]
    hexFaces.extend([hexCham.Faces[9], hexCham.Faces[3], hexCham.Faces[0]])
    hexShell = Part.Shell(hexFaces)

    # Center of flange:
    Pnt0 = Base.Vector(0.0,0.0,hF)
    Pnt1 = Base.Vector(s/2.0,0.0,hF)

    # arc edge of flange:
    Pnt2 = Base.Vector(arc1_x,0.0,arc1_z)
    Pnt3 = Base.Vector(dc/2.0,0.0,c/2.0)
    Pnt4 = Base.Vector((dc-c)/2.0,0.0,0.0)

    Pnt5 = Base.Vector(dia/2.0+r1,0.0,0.0)     #start of fillet between head and shank
    Pnt6 = Base.Vector(dia/2.0+r1-r1*sqrt2_,0.0,-r1+r1*sqrt2_) #arc-point of fillet
    Pnt7 = Base.Vector(dia/2.0,0.0,-r1)        # end of fillet
    Pnt8 = Base.Vector(dia/2.0,0.0,-a_point)        # Start of thread

    edge1 = Part.makeLine(Pnt0,Pnt1)
    edge2 = Part.makeLine(Pnt1,Pnt2)
    edge3 = Part.Arc(Pnt2,Pnt3,Pnt4).toShape()
    edge4 = Part.makeLine(Pnt4,Pnt5)
    edge5 = Part.Arc(Pnt5,Pnt6,Pnt7).toShape()

    # make a cutter for the hexShell
    PntHC1 = Base.Vector(0.0,0.0,arc1_z)
    PntHC2 = Base.Vector(0.0,0.0,0.0)

    edgeHC1 = Part.makeLine(Pnt2,PntHC1)
    edgeHC2 = Part.makeLine(PntHC1,PntHC2)
    edgeHC3 = Part.makeLine(PntHC2,Pnt0)

    HCWire = Part.Wire([edge2, edgeHC1, edgeHC2, edgeHC3, edge1])
    HCFace = Part.Face(HCWire)
    hex2Cut = HCFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)

    hexShell = hexShell.cut(hex2Cut)
    #Part.show(hexShell)

    topFaces.extend(hexShell.Faces)

    # bolt points
    cham_t = P*math.sqrt(3.0)/2.0*17.0/24.0

    PntB0 = Base.Vector(0.0,0.0,-a_point)
    PntB1 = Base.Vector(dia/2.0,0.0,-l+cham_t)
    PntB2 = Base.Vector(dia/2.0-cham_t,0.0,-l)
    PntB3 = Base.Vector(0.0,0.0,-l)

    edgeB2 = Part.makeLine(PntB1,PntB2)
    edgeB3 = Part.makeLine(PntB2,PntB3)

    #if self.RealThread.isChecked():
    if self.rThread:
      aWire=Part.Wire([edge2,edge3,edge4,edge5])
      boltIndex = 4

    else:
      if a_point <=r1:
        edgeB1 = Part.makeLine(Pnt7,PntB1)
        aWire=Part.Wire([edge2,edge3,edge4,edge5, edgeB1, edgeB2, edgeB3])
        boltIndex = 7
      else:
        edgeB1 = Part.makeLine(Pnt8,PntB1)
        edge6 = Part.makeLine(Pnt7,Pnt8)
        aWire=Part.Wire([edge2,edge3,edge4,edge5,edge6, \
            edgeB1, edgeB2, edgeB3])
        boltIndex = 8


    #aFace =Part.Face(aWire)
    #Part.show(aWire)
    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
    #Part.show(headShell)
    chamFace = headShell.Faces[0].cut(solidHex)
    #Part.show(chamFace)

    topFaces.append(chamFace.Faces[0])
    for i in range(1,boltIndex):
      topFaces.append(headShell.Faces[i])


    if self.rThread:
      if (dia < 3.0) or (dia > 5.0):
        rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
        for tFace in rthread.Faces:
          topFaces.append(tFace)
        headShell = Part.Shell(topFaces)
        screw = Part.Solid(headShell)
      else:
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
        for tFace in rthread.Faces:
          topFaces.append(tFace)
        headShell = Part.Shell(topFaces)
        head = Part.Solid(headShell)
        cyl = self.cutChamfer(dia, P, l)
        #FreeCAD.Console.PrintMessage("vor Schnitt Ende: " + str(dia) + "\n")
        screw = head.cut(cyl)
    else:
      screwShell = Part.Shell(topFaces)
      screw = Part.Solid(screwShell)

    return screw

  def makeIso7046(self, SType ='ISO7046', ThreadType ='M6', l=25.0):
    """ISO 7046, ISO 7047, ISO 10642, ISO 14582, ISO 14584

    Used for ISO 7046 countersunk flat head screws with H cross recess
    Used for ISO 7047 raised countersunk head screws with H cross recess
    Used for ISO 10642 Hexagon socket countersunk head screws
    Used for ISO 14582 Hexalobular socket countersunk head screws, high head
    Used for ISO 14584 Hexalobular socket raised countersunk head screws
    """
    dia = get_diameter(ThreadType)
    #FreeCAD.Console.PrintMessage("The 2009 head with l: " + str(l) + "\n")
    if (SType == 'ISO10642'):
      P,b,dk_theo,dk_mean,da, ds_min, e, k, r, s_mean, t, w =iso10642def[ThreadType]
      ePrax = s_mean / math.sqrt(3.0) / 0.99
      ht = 0.0
      a = 2*P
      t_mean = t
    else: #still need the data from iso2009def, but this screw can not created here
      P, a, b, dk_theo, dk_mean, k, n_min, r, t_mean, x = iso2009def[ThreadType]
      ht = 0.0 # Head height of flat head
    if SType == 'ISO7046':
      cT, mH, mZ  = iso7046def[ThreadType]
    if (SType == 'ISO7047'):
      rf, t_mean, cT, mH, mZ = Raised_countersunk_def[ThreadType]
      #Lengths and angles for calculation of head rounding
      beta = math.asin(dk_mean /2.0 / rf)   # angle of head edge
      tan_beta = math.tan(beta)
      alpha = beta/2.0 # half angle
      # height of raised head top
      ht = rf - (dk_mean/2.0) / tan_beta
      #print 'he: ', he
      h_arc_x = rf * math.sin(alpha)
      h_arc_z = ht - rf + rf * math.cos(alpha)
      #FreeCAD.Console.PrintMessage("h_arc_z: " + str(h_arc_z) + "\n")

    if (SType == 'ISO14582'):
      P, a, b, dk_theo, dk_mean, k, r, tt, A, t_mean = iso14582def[ThreadType]
      ePrax = A / 2.0 / 0.99

    if (SType == 'ISO14584'):
      P, b, dk_theo, dk_mean, f, k, r, rf, x, tt, A, t_mean = iso14584def[ThreadType]
      ePrax = A / 2.0 / 0.99
      #Lengths and angles for calculation of head rounding
      beta = math.asin(dk_mean /2.0 / rf)   # angle of head edge
      tan_beta = math.tan(beta)
      ctp = - (dk_mean/2.0) / tan_beta # Center Top Edge = center for rf
      betaA = math.asin(ePrax / rf)   # angle of head edge at start of recess
      ht = ctp + ePrax / math.tan(betaA)
      alpha = betaA + (beta - betaA)/2.0 # half angle of top Arc
      h_arc_x = rf * math.sin(alpha)
      h_arc_z = ctp + rf * math.cos(alpha)


    FreeCAD.Console.PrintMessage("The head with iso r: " + str(r) + "\n")
    cham = (dk_theo - dk_mean)/2.0
    rad225 = math.radians(22.5)
    rad45 = math.radians(45.0)
    rtan = r*math.tan(rad225)
    #FreeCAD.Console.PrintMessage("Checking rtan: " + str(rtan) + "\n")

    if (b > (l - k - rtan/2.0 - 1.0*P)):
      bmax = l - k - rtan/2.0 - 1.0*P
    else:
      bmax = b

    ### make the new code with math.modf(l)
    residue, turns = math.modf((bmax)/P)
    halfturns = 2*int(turns)
    if residue < 0.5:
      a_point = l - (turns+1.0) * P
      halfturns = halfturns +1
    else:
      halfturns = halfturns + 2
      a_point = l - (turns+2.0) * P
    #halfturns = halfturns + 2
    offSet = k + rtan - a_point

    #Head Points
    Pnt1 = Base.Vector(dk_mean/2.0,0.0,0.0)
    Pnt2 = Base.Vector(dk_mean/2.0,0.0,-cham)
    Pnt3 = Base.Vector(dia/2.0+r-r*math.cos(rad45),0.0,-k-rtan+r*math.sin(rad45))

    # Arc-points
    Pnt4 = Base.Vector(dia/2.0+r-r*(math.cos(rad225)),0.0,-k-rtan+r*math.sin(rad225))
    Pnt5 = Base.Vector(dia/2.0,0.0,-k-rtan)
    Pnt6 = Base.Vector(dia/2.0,0.0,-a_point)

    if (SType == 'ISO10642') or (SType == 'ISO14582'):
      if (SType == 'ISO10642'):
        recess, recessShell = self.makeAllen2(s_mean, t_mean, 0.0 )
        Pnt0 = Base.Vector(ePrax/2.0,0.0,-ePrax/2.0)
        PntCham = Base.Vector(ePrax,0.0,0.0)
        edge1 = Part.makeLine(Pnt0,PntCham)
        edgeCham2 = Part.makeLine(PntCham,Pnt1)
        edge2 = Part.makeLine(Pnt1,Pnt2)
        edge2 = Part.Wire([edgeCham2,edge2])
        PntH0 = Base.Vector(ePrax/2.0,0.0, ht + k)
        PntH1 = Base.Vector(ePrax,0.0, ht + k)
      if (SType == 'ISO14582'):
        recess, recessShell = self.makeIso10664_3(tt, t_mean, 0.0) # hexalobular recess
        Pnt0 = Base.Vector(0.0,0.0,0.0)
        edge1 = Part.makeLine(Pnt0,Pnt1)
        edge2 = Part.makeLine(Pnt1,Pnt2)


      # bolt points with bolt chamfer
      cham_b = P*math.sqrt(3.0)/2.0*17.0/24.0

      PntB1 = Base.Vector(dia/2.0,0.0,-l+cham_b)
      PntB2 = Base.Vector(dia/2.0-cham_b,0.0,-l)
      PntB3 = Base.Vector(0.0,0.0,-l)
      if a_point <= (k + rtan):
        edgeB0 = Part.makeLine(Pnt5,PntB1)
      else:
        edgeB0 = Part.makeLine(Pnt6,PntB1)
      edgeB2 = Part.makeLine(PntB1,PntB2)
      edgeB3 = Part.makeLine(PntB2,PntB3)
      edgeB1 = Part.Wire([edgeB2,edgeB3])

    else:
      # bolt points
      PntB1 = Base.Vector(dia/2.0,0.0,-l)
      PntB2 = Base.Vector(0.0,0.0,-l)
      if a_point <= (k + rtan):
        edgeB0 = Part.makeLine(Pnt5,PntB1)
      else:
        edgeB0 = Part.makeLine(Pnt6,PntB1)
      edgeB1 = Part.makeLine(PntB1,PntB2)

      if (SType == 'ISO7047'): # make raised head rounding
        Pnt0 = Base.Vector(0.0,0.0,ht)
        Pnt0arc = Base.Vector(h_arc_x,0.0,h_arc_z)
        edge1 = Part.Arc(Pnt0,Pnt0arc,Pnt1).toShape()
        edge2 = Part.makeLine(Pnt1,Pnt2)
        PntH0 = Base.Vector(0.0,0.0, ht + k)
        PntH1 = Base.Vector(dk_mean/2.0,0.0, ht + k)
        recess, recessShell = self.makeCross_H3(cT, mH, ht)
      if (SType == 'ISO7046'):
        # ISO7046
        FreeCAD.Console.PrintMessage("ISO7046: " + str(ht) + "\n")
        Pnt0 = Base.Vector(0.0,0.0,ht)
        edge1 = Part.makeLine(Pnt0,Pnt1)  # make flat head
        edge2 = Part.makeLine(Pnt1,Pnt2)
        recess, recessShell = self.makeCross_H3(cT, mH, ht)

      if (SType == 'ISO14584'): # make raised head rounding with chamfer
        Pnt0 = Base.Vector(ePrax/2.0,0.0,ht-ePrax/4.0)
        PntCham = Base.Vector(ePrax,0.0,ht)
        PntArc = Base.Vector(h_arc_x,0.0,h_arc_z)
        edge1 = Part.makeLine(Pnt0,PntCham)
        edgeArc = Part.Arc(PntCham,PntArc,Pnt1).toShape()
        edge2 = Part.makeLine(Pnt1,Pnt2)
        edge2 = Part.Wire([edgeArc,edge2])
        PntH0 = Base.Vector(ePrax/2.0,0.0, ht + k)
        PntH1 = Base.Vector(ePrax,0.0, ht + k)
        recess, recessShell = self.makeIso10664_3(tt, t_mean, ht) # hexalobular recess

    edge3 = Part.makeLine(Pnt2,Pnt3)
    edgeArc = Part.Arc(Pnt3,Pnt4,Pnt5).toShape()
    edgeArc1 = Part.makeLine(Pnt3,Pnt4)
    edgeArc2 = Part.makeLine(Pnt4,Pnt5)
    edge6 = Part.makeLine(Pnt5,Pnt6)

    if self.rThread:
      #aWire=Part.Wire([edge1,edge2,edge3,edgeArc])
      aWire=Part.Wire([edge2,edge3,edgeArc])
    else:
      if a_point <= (k + rtan):
        aWire=Part.Wire([edge2,edge3,edgeArc, edgeB0, edgeB1])
      else:
        aWire=Part.Wire([edge2,edge3,edgeArc,edge6, edgeB0, edgeB1])

    #Part.show(aWire)
    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    headFaces = headShell.Faces
    #Part.show(headShell)

    if (SType == 'ISO7046') or (SType == 'ISO14582'):
      # hCut is just a cylinder for ISO7046
      hCut = Part.makeCylinder(dk_mean/2.0,k,Pnt0)
      #Part.show(hCut)
      topFace = hCut.Faces[2]
    else:
      if (SType == 'ISO7047'):
        edgeH1 = Part.makeLine(Pnt1,PntH1)
      else:
        edgeH1 = Part.makeLine(PntCham,PntH1)
      edgeH2 = Part.makeLine(PntH1,PntH0)
      edgeH3 = Part.makeLine(PntH0,Pnt0)
      hWire = Part.Wire([edge1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
      hFace = Part.Face(hWire)
      hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
      Part.show(hWire)
      #Part.show(hCut)
      topFace = hCut.Faces[0]

    recessShell = recessShell.cut(hCut)
    topFace = topFace.cut(recess)
    #Part.show(topFace)
    #Part.show(recessShell)
    #Part.show(headShell)
    headFaces.append(topFace.Faces[0])
    headFaces.extend(recessShell.Faces)


    if (SType == 'ISO10642') or (SType == 'ISO14582'):
      if self.rThread:
        if (dia < 3.0) or (dia > 5.0):
          #if True:
          rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
          rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
          #head = head.fuse(rthread)
          #Part.show(rthread)
          for threadFace in rthread.Faces:
            headFaces.append(threadFace)

          screwShell = Part.Shell(headFaces)
          screw = Part.Solid(screwShell)
        else:
          '''
          # head = self.cutIsoThread(head, dia, P, turns, l)
          rthread = self.makeShellthread(dia, P, halfturns, False)
          rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
          head = head.fuse(rthread)
          head = head.removeSplitter()
          cyl = self.cutChamfer(dia, P, l)
          #FreeCAD.Console.PrintMessage("vor Schnitt Ende: " + str(dia) + "\n")
          head = head.cut(cyl)
          '''

          rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
          rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
          #head = head.fuse(rthread)
          #Part.show(rthread)
          for threadFace in rthread.Faces:
            headFaces.append(threadFace)

          screwShell = Part.Shell(headFaces)
          screw = Part.Solid(screwShell)
          cyl = self.cutChamfer(dia, P, l)
          screw = screw.cut(cyl)
      else:
        screwShell = Part.Shell(headFaces)
        screw = Part.Solid(screwShell)

    else:
      if self.rThread:
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
        #head = head.fuse(rthread)
        #Part.show(rthread)
        for threadFace in rthread.Faces:
          headFaces.append(threadFace)

      screwShell = Part.Shell(headFaces)
      screw = Part.Solid(screwShell)

    return screw

  def makeIso4762(self, SType ='ISO4762', ThreadType ='M6',l=25.0):
    """ISO 4762 Allen Screw head and ISO 14579 Hexalobular socket head cap
    """
    dia = get_diameter(ThreadType)
    #FreeCAD.Console.PrintMessage("der 4762Kopf mit l: " + str(l) + "\n")
    P, b, dk_max, da, ds_mean, e, lf, k, r, s_mean, t, v, dw, w = iso4762def[ThreadType]
    #FreeCAD.Console.PrintMessage("der Kopf mit iso r: " + str(r) + "\n")
    if SType == 'ISO14579':
      tt, A, t = iso14579def[ThreadType]
      #Head Points 30° countersunk
      # Pnt0 = Base.Vector(0.0,0.0,k-A/4.0) #Center Point for countersunk
      Pnt0 = Base.Vector(0.0,0.0,k-A/8.0) #Center Point for flat countersunk
      PntFlat = Base.Vector(A/8.0,0.0,k-A/8.0) # End of flat part
      Pnt1 = Base.Vector(A/1.99,0.0,k)     #countersunk edge at head
      edgeCham0 = Part.makeLine(Pnt0,PntFlat)
      edgeCham1 = Part.makeLine(PntFlat,Pnt1)
      edge1 = Part.Wire([edgeCham0,edgeCham1])

      # Here is the next approach to shorten the head building time
      # Make two helper points to create a cutting tool for the
      # recess and recess shell.
      PntH1 = Base.Vector(A/1.99,0.0, 2.0*k)

    else:
      e_cham = 2.0 * s_mean / math.sqrt(3.0)
      #Head Points 45° countersunk
      Pnt0 = Base.Vector(0.0,0.0,k-e_cham/1.99/2.0) #Center Point for countersunk
      PntFlat = Base.Vector(e_cham/1.99/2.0,0.0,k-e_cham/1.99/2.0) # End of flat part
      Pnt1 = Base.Vector(e_cham/1.99,0.0,k)     #countersunk edge at head
      edgeCham0 = Part.makeLine(Pnt0,PntFlat)
      edgeCham1 = Part.makeLine(PntFlat,Pnt1)
      edge1 = Part.Wire([edgeCham0,edgeCham1])
      PntH1 = Base.Vector(e_cham/1.99,0.0, 2.0*k)


    PntH2 = Base.Vector(0.0,0.0, 2.0*k)
    edgeH1 = Part.makeLine(Pnt1,PntH1)
    edgeH2 = Part.makeLine(PntH1,PntH2)
    edgeH3 = Part.makeLine(PntH2,Pnt0)
    hWire = Part.Wire([edge1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
    hFace = Part.Face(hWire)
    hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #Part.show(hWire)
    '''


    PntH2 = Base.Vector(A/8.0,0.0, 2.0*k)
    edgeH1 = Part.makeLine(Pnt1,PntH1)
    edgeH2 = Part.makeLine(PntH1,PntH2)
    edgeH3 = Part.makeLine(PntH2,PntFlat)
    hWire = Part.Wire([edgeCham1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
    hFace = Part.Face(hWire)
    hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #Part.show(hWire)
    '''


    sqrt2_ = 1.0/math.sqrt(2.0)
    #depth = s_mean / 3.0

    '''
    if (b > l - 2*P):
       bmax = l-2*P
    else:
       bmax = b
    halfturns = round(2.0*(bmax+P)/P) # number of thread turns
    if self.RealThread.isChecked():
      a_real = l-(halfturns+2)*P/2.0  # point to fuse real thread
    else:
      a_real = l-halfturns*P/2.0  # starting point of thread
    if a_real < r:
      a_point = r*1.3
    else:
      a_point = a_real
    '''


    if (b > (l - 1.0*P)):
       bmax = l- 1.0*P
    else:
       bmax = b

    ### make the new code with math.modf(l)
    residue, turns = math.modf((bmax)/P)
    halfturns = 2*int(turns)
    if residue < 0.5:
      a_point = l - (turns+1.0) * P
      halfturns = halfturns +1
    else:
      halfturns = halfturns + 2
      a_point = l - (turns+2.0) * P
    #halfturns = halfturns + 2
    offSet = r - a_point
    #FreeCAD.Console.PrintMessage("The transition at a: " + str(a) + " turns " + str(turns) + "\n")




    #rad30 = math.radians(30.0)
    #Head Points
    Pnt2 = Base.Vector(dk_max/2.0-v,0.0,k)   #start of fillet
    Pnt3 = Base.Vector(dk_max/2.0-v+v*sqrt2_,0.0,k-v+v*sqrt2_) #arc-point of fillet
    Pnt4 = Base.Vector(dk_max/2.0,0.0,k-v)   #end of fillet
    Pnt5 = Base.Vector(dk_max/2.0,0.0,(dk_max-dw)/2.0) #we have a chamfer here
    Pnt6 = Base.Vector(dw/2.0,0.0,0.0)           #end of chamfer
    Pnt7 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
    Pnt8 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
    Pnt9 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
    Pnt10 = Base.Vector(dia/2.0,0.0,-a_point)        # start of thread

    edge1 = Part.makeLine(Pnt0,Pnt1)
    edge2 = Part.makeLine(Pnt1,Pnt2)
    edge3 = Part.Arc(Pnt2,Pnt3,Pnt4).toShape()
    edge4 = Part.makeLine(Pnt4,Pnt5)
    edge5 = Part.makeLine(Pnt5,Pnt6)
    edge6 = Part.makeLine(Pnt6,Pnt7)
    edge7 = Part.Arc(Pnt7,Pnt8,Pnt9).toShape()

    '''
    # bolt points
    PntB1 = Base.Vector(dia/2.0,0.0,-l-P)  # Chamfer is made with a cut later
    PntB2 = Base.Vector(0.0,0.0,-l-P)
    #PntB3 = Base.Vector(0.0,0.0,-l)

    edgeB0 = Part.makeLine(Pnt10,PntB1)
    edgeB1 = Part.makeLine(PntB1,PntB2)
    #edgeB2 = Part.makeLine(PntB2,PntB3)
    edgeZ0 = Part.makeLine(PntB2,Pnt0)


    aWire=Part.Wire([edge1,edge2,edge3,edge4,edge5,edge6,edge7,edge8, \
        edgeB0, edgeB1, edgeZ0])
    '''



    if self.rThread:
      aWire=Part.Wire([edge2,edge3,edge4,edge5,edge6,edge7])

    else:
      # bolt points
      cham_t = P*math.sqrt(3.0)/2.0*17.0/24.0

      PntB1 = Base.Vector(dia/2.0,0.0,-l+cham_t)
      PntB2 = Base.Vector(dia/2.0-cham_t,0.0,-l)
      PntB3 = Base.Vector(0.0,0.0,-l)

      #edgeB1 = Part.makeLine(Pnt10,PntB1)
      edgeB2 = Part.makeLine(PntB1,PntB2)
      edgeB3 = Part.makeLine(PntB2,PntB3)

      if a_point <= r:
        edgeB1 = Part.makeLine(Pnt9,PntB1)
        aWire=Part.Wire([edge2,edge3,edge4,edge5,edge6,edge7, \
            edgeB1, edgeB2, edgeB3])
      else:
        edge8 = Part.makeLine(Pnt9,Pnt10)
        edgeB1 = Part.makeLine(Pnt10,PntB1)
        aWire=Part.Wire([edge2,edge3,edge4,edge5,edge6,edge7,edge8, \
            edgeB1, edgeB2, edgeB3])
      #Part.show(aWire)

    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #head = Part.Solid(headShell)
    #Part.show(aWire)
    #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
    headFaces = headShell.Faces


    if SType == 'ISO14579':
      #recess = self.makeIso10664(tt, t, k) # hexalobular recess
      recess, recessShell = self.makeIso10664_3(tt, t, k) # hexalobular recess
    else:
      recess, recessShell = self.makeAllen2(s_mean, t, k )

    recessShell = recessShell.cut(hCut)
    topFace = hCut.Faces[1]
    #topFace = hCut.Faces[0]
    topFace = topFace.cut(recess)
    #Part.show(topFace)
    #Part.show(recessShell)
    #Part.show(headShell)
    headFaces.append(topFace.Faces[0])
    #headFaces.append(hCut.Faces[2])

    #allenscrew = head.cut(recess)
    #Part.show(hCut)
    headFaces.extend(recessShell.Faces)

    #if self.RealThread.isChecked():
    if self.rThread:
      #if (dia < 3.0) or (dia > 5.0):
      if True:
        # head = self.cutIsoThread(head, dia, P, turns, l)
        rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
        #Part.show(rthread)
        for tFace in rthread.Faces:
          headFaces.append(tFace)
        headShell = Part.Shell(headFaces)
        allenscrew = Part.Solid(headShell)

      else:
        # head = self.cutIsoThread(head, dia, P, turns, l)
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
        for tFace in rthread.Faces:
          headFaces.append(tFace)
        headShell = Part.Shell(headFaces)
        allenscrew = Part.Solid(headShell)
        cyl = self.cutChamfer(dia, P, l)
        # FreeCAD.Console.PrintMessage("vor Schnitt Ende: " + str(dia) + "\n")
        allenscrew = allenscrew.cut(cyl)
    else:
      headShell = Part.Shell(headFaces)
      allenscrew = Part.Solid(headShell)


    return allenscrew




  # make ISO 7380-1 Button head Screw
  # make ISO 7380-2 Button head Screw with collar
  # make DIN 967 cross recessed pan head Screw with collar
  def makeIso7380(self, SType ='ISO7380-1', ThreadType ='M6',l=25.0):
    dia = get_diameter(ThreadType)
    #todo: different radii for screws with thread to head or with shaft?
    sqrt2_ = 1.0/math.sqrt(2.0)

    if (SType =='DIN967'):
      P, b, c, da, dk, r, k, rf, x, cT, mH, mZ = din967def[ThreadType]

      rH = rf # radius of button arc
      alpha = math.acos((rf-k+c)/rf)

      #Head Points
      Pnt0 = Base.Vector(0.0,0.0,k)
      PntArc = Base.Vector(rf*math.sin(alpha/2.0),0.0,k-rf + rf*math.cos(alpha/2.0)) #arc-point of button
      Pnt1 = Base.Vector(rf*math.sin(alpha),0.0,c)     #end of button arc
      PntC0 = Base.Vector((dk)/2.0,0.0,c)     #collar points
      PntC2 = Base.Vector((dk)/2.0,0.0,0.0)     #collar points
      Pnt4 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank

      edge1 = Part.Arc(Pnt0,PntArc,Pnt1).toShape()
      edgeC0 = Part.makeLine(Pnt1,PntC0)
      edgeC1 = Part.makeLine(PntC0,PntC2)
      edge2 = Part.Wire([edgeC0, edgeC1])
      edge3 = Part.makeLine(PntC2,Pnt4)
      #Points for recessShell cutter
      PntH0 = Base.Vector(0.0,0.0,2.0*k)
      PntH1 = Base.Vector(rf*math.sin(alpha),0.0,2.0*k)
      recess, recessShell = self.makeCross_H3(cT, mH, k)

    else:
      if (SType =='ISO7380-1'):
        P, b, a, da, dk, dk_mean,s_mean, t_min, r, k, e, w = iso7380def[ThreadType]

        # Bottom of recess
        e_cham = 2.0 * s_mean / math.sqrt(3.0) / 0.99
        #depth = s_mean / 3.0

        ak = -(4*k**2 + e_cham**2 - dk**2)/(8*k) # helper value for button arc
        rH = math.sqrt((dk/2.0)**2 + ak**2) # radius of button arc
        alpha = (math.atan(2*(k + ak)/e_cham) + math.atan((2*ak)/dk))/2

        Pnt2 = Base.Vector(rH*math.cos(alpha),0.0,-ak + rH*math.sin(alpha)) #arc-point of button
        Pnt3 = Base.Vector(dk/2.0,0.0,0.0)   #end of fillet
        Pnt4 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
        edge3 = Part.makeLine(Pnt3,Pnt4)

      if (SType =='ISO7380-2'):
        P, b, c, da, dk, dk_c,s_mean,t_min, r, k, e, w = iso7380_2def[ThreadType]

        # Bottom of recess
        e_cham = 2.0 * s_mean / math.sqrt(3.0) / 0.99
        #depth = s_mean / 3.0

        ak = -(4*(k-c)**2 + e_cham**2 - dk**2)/(8*(k-c)) # helper value for button arc
        rH = math.sqrt((dk/2.0)**2 + ak**2) # radius of button arc
        alpha = (math.atan(2*(k -c + ak)/e_cham) + math.atan((2*ak)/dk))/2

        Pnt2 = Base.Vector(rH*math.cos(alpha),0.0,c -ak + rH*math.sin(alpha)) #arc-point of button
        Pnt3 = Base.Vector(dk/2.0,0.0,c)   #end of fillet
        Pnt4 = Base.Vector(dia/2.0+r,0.0,0.0)     #start of fillet between head and shank
        PntC0 = Base.Vector((dk_c-c)/2.0,0.0,c)     #collar points
        PntC1 = Base.Vector(dk_c/2.0,0.0,c/2.0)     #collar points
        PntC2 = Base.Vector((dk_c-c)/2.0,0.0,0.0)     #collar points

        edgeC0 = Part.makeLine(Pnt3,PntC0)
        edgeC1 = Part.Arc(PntC0,PntC1,PntC2).toShape()
        edge3 = Part.makeLine(PntC2,Pnt4)
        edge3 = Part.Wire([edgeC0, edgeC1, edge3])

      #Head Points
      Pnt0 = Base.Vector(e_cham/4.0,0.0,k-e_cham/4.0) #Center Point for chamfer
      Pnt1 = Base.Vector(e_cham/2.0,0.0,k)     #inner chamfer edge at head
      #Points for recessShell cutter
      PntH0 = Base.Vector(e_cham/4.0,0.0,2.0*k)
      PntH1 = Base.Vector(e_cham/2.0,0.0,2.0*k)

      edge1 = Part.makeLine(Pnt0,Pnt1)
      edge2 = Part.Arc(Pnt1,Pnt2,Pnt3).toShape()
      recess, recessShell = self.makeAllen2(s_mean, t_min, k)

    if (b > (l - 1.0*P)):
       bmax = l- 1.0*P
    else:
       bmax = b

    ### make the new code with math.modf(l)
    residue, turns = math.modf((bmax)/P)
    halfturns = 2*int(turns)
    if residue < 0.5:
      a_point = l - (turns+1.0) * P
      halfturns = halfturns +1
    else:
      halfturns = halfturns + 2
      a_point = l - (turns+2.0) * P
    offSet = r - a_point


    Pnt5 = Base.Vector(dia/2.0+r-r*sqrt2_,0.0,-r+r*sqrt2_) #arc-point of fillet
    Pnt6 = Base.Vector(dia/2.0,0.0,-r)        # end of fillet
    Pnt7 = Base.Vector(dia/2.0,0.0,-a_point)        # start of thread

    edge4 = Part.Arc(Pnt4,Pnt5,Pnt6).toShape()
    edge5 = Part.makeLine(Pnt6,Pnt7)

    if (SType =='DIN967'):
      # bolt points
      PntB1 = Base.Vector(dia/2.0,0.0,-l)
      PntB2 = Base.Vector(0.0,0.0,-l)
      edgeB2 = Part.makeLine(PntB1,PntB2)
    else:
      # bolt points
      cham_b = P*math.sqrt(3.0)/2.0*17.0/24.0

      PntB1 = Base.Vector(dia/2.0,0.0,-l+cham_b)
      PntB2 = Base.Vector(dia/2.0-cham_b,0.0,-l)
      PntB3 = Base.Vector(0.0,0.0,-l)

      edgeB2 = Part.makeLine(PntB1,PntB2)
      edgeB3 = Part.makeLine(PntB2,PntB3)
      edgeB2 = Part.Wire([edgeB2, edgeB3])

    if self.rThread:
      aWire=Part.Wire([edge2,edge3,edge4])
    else:
      if a_point <= r:
        edgeB1 = Part.makeLine(Pnt6,PntB1)
        aWire=Part.Wire([edge2,edge3,edge4, edgeB1, edgeB2])
      else:
        edge5 = Part.makeLine(Pnt6,Pnt7)
        edgeB1 = Part.makeLine(Pnt7,PntB1)
        aWire=Part.Wire([edge2,edge3,edge4,edge5, edgeB1, edgeB2])

    #Part.show(aWire)
    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #Part.show(headShell)
    headFaces = headShell.Faces

    edgeH1 = Part.makeLine(Pnt1,PntH1)
    edgeH2 = Part.makeLine(PntH1,PntH0)
    edgeH3 = Part.makeLine(PntH0,Pnt0)
    hWire = Part.Wire([edge1,edgeH1,edgeH2,edgeH3]) # Cutter for recess-Shell
    hFace = Part.Face(hWire)
    hCut = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #Part.show(hWire)
    topFace = hCut.Faces[0]

    recessShell = recessShell.cut(hCut)
    topFace = topFace.cut(recess)
    #Part.show(topFace)
    #Part.show(recessShell)
    #Part.show(headShell)
    headFaces.append(topFace.Faces[0])
    headFaces.extend(recessShell.Faces)


    if self.rThread:
      #if (dia < 3.0) or (dia > 5.0):
      if True:
        if (SType =='DIN967'):
          rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
        else:
          rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
        for threadFace in rthread.Faces:
          headFaces.append(threadFace)

        screwShell = Part.Shell(headFaces)
        screw = Part.Solid(screwShell)
      else:
        rthread = self.makeShellthread(dia, P, halfturns, False, offSet)
        rthread.translate(Base.Vector(0.0, 0.0,-a_point -2.0*P))
        for threadFace in rthread.Faces:
          headFaces.append(threadFace)

        screwShell = Part.Shell(headFaces)
        screw = Part.Solid(screwShell)
        cyl = self.cutChamfer(dia, P, l)
        screw = screw.cut(cyl)
    else:
      screwShell = Part.Shell(headFaces)
      screw = Part.Solid(screwShell)

    return screw




  def makeHextool(self,s_hex, k_hex, cir_hex):
    # makes a cylinder with an inner hex hole, used as cutting tool
    # create hexagon
    mhex=Base.Matrix()
    mhex.rotateZ(math.radians(60.0))
    polygon = []
    vhex=Base.Vector(s_hex/math.sqrt(3.0),0.0,-k_hex*0.1)
    for i in range(6):
       polygon.append(vhex)
       vhex = mhex.multiply(vhex)
    polygon.append(vhex)
    hexagon = Part.makePolygon(polygon)
    # create circle
    circ = Part.makeCircle(cir_hex/2.0, Base.Vector(0.0,0.0,-k_hex*0.1), self.circleAxis)
    # Create the face with the circle as outline and the hexagon as hole
    face=Part.Face([Part.Wire(circ),hexagon])

    # Extrude in z to create the final cutting tool
    exHex=face.extrude(Base.Vector(0.0,0.0,k_hex*1.2))
    # Part.show(exHex)
    return exHex


  def makeShellthread(self, d, P, halfrots, withcham, offSet):
    d = float(d)

    #rotations = int(rots)-1
    halfrots_int = int(halfrots)
    rotations = (halfrots_int // 2) - 1
    if halfrots_int % 2 == 1:
      #FreeCAD.Console.PrintMessage("got half turn: " + str(halfrots_int) + "\n")
      halfturn = True
      # bot_off = - P/2.0 # transition of half a turn
      bot_off = 0.0 # nominal length
    else:
      halfturn = False
      bot_off = 0.0 # nominal length

    H=P*math.cos(math.radians(30)) # Gewindetiefe H
    r=d/2.0

    # helix = Part.makeHelix(P,P,d*511/1000.0,0) # make just one turn, length is identical to pitch
    helix = Part.makeHelix(P,P,d*self.Tuner/1000.0,0) # make just one turn, length is identical to pitch
    helix.translate(FreeCAD.Vector(0.0, 0.0,-P*9.0/16.0))

    extra_rad = P
    # points for screw profile
    ps0 = (r,0.0, 0.0)
    ps1 = (r-H*5.0/8.0,0.0, -P*5.0/16.0)
    ps2 = (r-H*17.0/24.0,0.0, -P*7.0/16.0) # Center of Arc
    ps3 = (r-H*5.0/8.0,0.0, -P*9.0/16.0 )
    ps4 =  (r, 0.0, -P*14.0/16.0)
    ps5 = (r,0.0, -P)
    ps6 = (r+extra_rad,0.0, -P)
    ps7 = (r+extra_rad,0.0, 0.0)

    edge0 = Part.makeLine(ps0,ps1)
    edge1 = Part.Arc(FreeCAD.Vector(ps1),FreeCAD.Vector(ps2),FreeCAD.Vector(ps3)).toShape()
    edge2 = Part.makeLine(ps3,ps4)
    edge3 = Part.makeLine(ps4,ps5)
    edge4 = Part.makeLine(ps5,ps6)
    edge5 = Part.makeLine(ps6,ps7)
    edge6 = Part.makeLine(ps7,ps0)

    W0 = Part.Wire([edge0, edge1, edge2, edge3, edge4, edge5, edge6])

    makeSolid=True
    isFrenet=True
    pipe0 = Part.Wire(helix).makePipeShell([W0],makeSolid,isFrenet)
    # pipe1 = pipe0.copy()

    TheFaces = []
    TheFaces.append(pipe0.Faces[0])
    #Part.show(pipe0.Faces[0])
    TheFaces.append(pipe0.Faces[1])
    #Part.show(pipe0.Faces[1])
    TheFaces.append(pipe0.Faces[2])
    #Part.show(pipe0.Faces[2])
    TheFaces.append(pipe0.Faces[3])
    #Part.show(pipe0.Faces[3])

    TheShell = Part.Shell(TheFaces)
    # print "Shellpoints: ", len(TheShell.Vertexes)


    i = 1
    for i in range(rotations-2):
       TheShell.translate(FreeCAD.Vector(0.0, 0.0, -P))

       for flaeche in TheShell.Faces:
         TheFaces.append(flaeche)

    #FreeCAD.Console.PrintMessage("Base-Shell: " + str(i) + "\n")
    # Make separate faces for the tip of the screw
    botFaces = []
    for i in range(rotations-2, rotations, 1):
       TheShell.translate(FreeCAD.Vector(0.0, 0.0, -P))

       for flaeche in TheShell.Faces:
         botFaces.append(flaeche)
    #FreeCAD.Console.PrintMessage("Bottom-Shell: " + str(i) + "\n")

    # making additional faces for transition to cylinder

    pc1 = (r + H/16.0,0.0,P*1/32.0)
    pc2 = (r-H*5.0/8.0,0.0,-P*5.0/16.0 )
    pc3 = (r-H*17.0/24.0,0.0, -P*7.0/16.0 ) # Center of Arc
    pc4 = (r-H*5.0/8.0,0.0, -P*9.0/16.0 )
    pc5 =  (r+ H/16.0, 0.0, -P*29.0/32.0 )

    edgec0 = Part.makeLine(pc5,pc1)
    edgec1 = Part.makeLine(pc1,pc2)
    edgec2 = Part.Arc(FreeCAD.Vector(pc2),FreeCAD.Vector(pc3),FreeCAD.Vector(pc4)).toShape()
    edgec3 = Part.makeLine(pc4,pc5)

    cut_profile = Part.Wire([edgec1, edgec2, edgec3, edgec0 ])

    alpha_rad = math.atan(2*H*17.0/24.0/P)
    alpha = math.degrees(alpha_rad)
    Hyp = P/math.cos(alpha_rad)
    # tuning = 511/1000.0
    tuning = self.Tuner/1000.0
    angled_Helix = Part.makeHelix(Hyp,Hyp*1.002/2.0,d*tuning,alpha)

    SH_faces = []

    if halfturn:
      half_Helix = Part.makeHelix(P,P/2.0,d*self.Tuner/1000.0,0) # make just half a turn
      angled_Helix.rotate(Base.Vector(0,0,0),Base.Vector(0,0,1),180)
      angled_Helix.translate(FreeCAD.Vector(0.0, 0.0,P/2.0))
      # Part.show(half_Helix)
      # Part.show(angled_Helix)
      pipe_cut = Part.Wire([half_Helix, angled_Helix]).makePipeShell([cut_profile],True,isFrenet)
      SH_faces.append(pipe_cut.Faces[0])
      SH_faces.append(pipe_cut.Faces[1])
      SH_faces.append(pipe_cut.Faces[2])
      SH_faces.append(pipe_cut.Faces[4])
      SH_faces.append(pipe_cut.Faces[5])
      SH_faces.append(pipe_cut.Faces[6])

    else:
      pipe_cut = Part.Wire(angled_Helix).makePipeShell([cut_profile],True,isFrenet)
      SH_faces.append(pipe_cut.Faces[0])
      SH_faces.append(pipe_cut.Faces[1])
      SH_faces.append(pipe_cut.Faces[2])

    # Part.show(pipe_cut)


    Shell_helix = Part.Shell(SH_faces)

    # rect_helix_profile, needed for cutting a tube-shell
    pr1 = (r +H/16.0, 0.0, 0.0)
    pr2 = (r -H/16.0, 0.0, 0.0)
    pr3 = (r -H/16.0, 0.0, P)
    pr4 = (r +H/16.0, 0.0, P)

    edge_r1 = Part.makeLine(pr1,pr2)
    edge_r2 = Part.makeLine(pr2,pr3)
    edge_r3 = Part.makeLine(pr3,pr4)
    edge_r4 = Part.makeLine(pr4,pr1)
    rect_profile = Part.Wire([edge_r1, edge_r2, edge_r3, edge_r4 ])
    rect_helix = Part.Wire(helix).makePipeShell([rect_profile], True, isFrenet)
    # if halfturn:
    #   rect_helix.rotate(Base.Vector(0,0,0),Base.Vector(0,0,1),180)
    rect_helix.translate(FreeCAD.Vector(0.0, 0.0,- P))
    # Part.show(rect_helix)

    # rect_ring, needed for cutting the Shell_helix
    pr5 = (r +H*1.1, 0.0, P*1.1)
    pr6 = (r, 0.0, P*1.1)
    pr7 = (r, 0.0, -P*1.1)
    pr8 = (r +H*1.1, 0.0, -P*1.1)

    edge_r5 = Part.makeLine(pr5,pr6)
    edge_r6 = Part.makeLine(pr6,pr7)
    edge_r7 = Part.makeLine(pr7,pr8)
    edge_r8 = Part.makeLine(pr8,pr5)
    rect_profile = Part.Wire([edge_r5, edge_r6, edge_r7, edge_r8 ])

    rect_Face =Part.Face(rect_profile)
    rect_ring= rect_Face.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #Part.show(rect_ring)

    Shell_helix = Shell_helix.cut(rect_ring)
    Shell_helix.translate(FreeCAD.Vector(0.0, 0.0, P))
    # Part.show(Shell_helix)

    # shell_ring, the transition to a cylinder
    pr9 = (r, 0.0, P-offSet)
    pr10 = (r, 0.0, -P )
    edge_r9 = Part.makeLine(pr9,pr10)
    shell_ring= edge_r9.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)

    shell_ring = shell_ring.cut(pipe_cut)
    #Part.show(shell_ring)
    shell_ring = shell_ring.cut(rect_helix)
    shell_ring.translate(FreeCAD.Vector(0.0, 0.0, P))
    #Part.show(shell_ring)

    for flaeche in shell_ring.Faces:
      TheFaces.append(flaeche)

    for flaeche in Shell_helix.Faces:
      TheFaces.append(flaeche)

    if withcham:
      #FreeCAD.Console.PrintMessage("with chamfer: " + str(i) + "\n")
      # cutting of the bottom Faces
      # bot_off = 0.0 # nominal length
      cham_off = H/8.0
      cham_t = P*math.sqrt(3.0)/2.0*17.0/24.0

      # points for chamfer: common-Method
      pch0 =  (0.0, 0.0, -(rotations)*P + bot_off) # bottom center
      pch1 =  (r-cham_t,0.0, -(rotations)*P + bot_off)
      pch2 =  (r+cham_off, 0.0, -(rotations)*P + cham_t +cham_off  + bot_off)
      pch3 =  (r+cham_off, 0.0, -(rotations)*P + 3.0*P + bot_off)
      pch4 =  (0.0, 0.0, -(rotations)*P + 3.0*P + bot_off)

      edgech0 = Part.makeLine(pch0,pch1)
      edgech1 = Part.makeLine(pch1,pch2)
      edgech2 = Part.makeLine(pch2,pch3)
      edgech3 = Part.makeLine(pch3,pch4)
      edgech4 = Part.makeLine(pch4,pch0)

      Wch_wire = Part.Wire([edgech0, edgech1, edgech2, edgech3, edgech4])
      cham_Face =Part.Face(Wch_wire)
      cham_Solid = cham_Face.revolve(Base.Vector(0.0,0.0,-(rotations-1)*P),Base.Vector(0.0,0.0,1.0),360)
      # Part.show(cham_Solid)

      BotShell = Part.Shell(botFaces)
      BotShell = BotShell.common(cham_Solid)
      # Part.show(BotShell)

      cham_faces = []
      cham_faces.append(cham_Solid.Faces[0])
      cham_faces.append(cham_Solid.Faces[1])
      cham_Shell = Part.Shell(cham_faces)
      # Part.show(cham_Shell)

      pipe0.translate(FreeCAD.Vector(0.0, 0.0, -(rotations-1)*P))
      # Part.show(pipe0)

      # Part.show(Fillet_shell)
      cham_Shell = cham_Shell.cut(pipe0)
      pipe0.translate(FreeCAD.Vector(0.0, 0.0, -P))
      # Part.show(pipe0)
      cham_Shell = cham_Shell.cut(pipe0)

      '''
      botFaces2 = []
      for flaeche in BotShell.Faces:
        botFaces2.append(flaeche)
      for flaeche in cham_Shell.Faces:
        botFaces2.append(flaeche)
      '''

    else: # tip of screw without chamfer
      #FreeCAD.Console.PrintMessage("without chamfer: " + str(i) + "\n")

      commonbox = Part.makeBox(d+4.0*P, d+4.0*P, 3.0*P)
      commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-(rotations)*P+bot_off))
      #commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-(rotations+3)*P+bot_off))
      #Part.show(commonbox)

      BotShell = Part.Shell(botFaces)
      #Part.show(BotShell)

      BotShell = BotShell.common(commonbox)
      #BotShell = BotShell.cut(commonbox)
      bot_edges =[]
      bot_z =  1.0e-5 -(rotations)*P + bot_off

      for kante in BotShell.Edges:
         if (kante.Vertexes[0].Point.z<=bot_z) and (kante.Vertexes[1].Point.z<=bot_z):
            bot_edges.append(kante)
            # Part.show(kante)
      bot_wire = Part.Wire(Part.__sortEdges__(bot_edges))

      #botFaces2 = []
      #for flaeche in BotShell.Faces:
      #  botFaces2.append(flaeche)

      bot_face = Part.Face(bot_wire)
      bot_face.reverse()
      #botFaces2.append(bot_face)

    '''

    BotShell2 = Part.Shell(botFaces2)
    # Part.show(BotShell2)

    TheShell2 = Part.Shell(TheFaces)

    # This gives a shell
    FaceList = []
    for flaeche in TheShell2.Faces:
      FaceList.append(flaeche)
    for flaeche in BotShell2.Faces:
      FaceList.append(flaeche)

    TheShell = Part.Shell(FaceList)
    # Part.show(TheShell)
    '''
    for flaeche in BotShell.Faces:
      TheFaces.append(flaeche)
    if withcham:
      for flaeche in cham_Shell.Faces:
        TheFaces.append(flaeche)
    else:
      TheFaces.append(bot_face)
    TheShell = Part.Shell(TheFaces)

    #print self.Tuner, " ", TheShell.ShapeType, " ", TheShell.isValid(), " hrots: ", halfrots_int, " Shellpunkte: ", len(TheShell.Vertexes)

    return TheShell

  # if da<>None: make Shell for a nut else: make a screw tap
  def makeInnerThread_2(self, d, P, rotations, da, l):
    d = float(d)
    bot_off = 0.0 # nominal length

    H=P*math.cos(math.radians(30)) # Gewindetiefe H
    r=d/2.0

    helix = Part.makeHelix(P,P,d*self.Tuner/1000.0,0) # make just one turn, length is identical to pitch
    helix.translate(FreeCAD.Vector(0.0, 0.0,-P*9.0/16.0))

    extra_rad = P

    # points for inner thread profile
    ps0 = (r,0.0, 0.0)
    ps1 = (r-H*5.0/8.0,0.0, -P*5.0/16.0)
    ps2 = (r-H*5.0/8.0,0.0, -P*9.0/16.0 )
    ps3 =  (r, 0.0, -P*14.0/16.0)
    ps4 = (r+H*1/24.0,0.0, -P*31.0/32.0) # Center of Arc
    ps5 = (r,0.0, -P)
    ps6 = (r+extra_rad,0.0, -P)
    ps7 = (r+extra_rad,0.0, 0.0)

    #ps6 = (r-extra_rad,0.0, -P)
    #ps7 = (r-extra_rad,0.0, 0.0)

    edge0 = Part.makeLine(ps0,ps1)
    edge1 = Part.makeLine(ps1,ps2)
    edge2 = Part.makeLine(ps2,ps3)
    edge3 = Part.Arc(FreeCAD.Vector(ps3),FreeCAD.Vector(ps4),FreeCAD.Vector(ps5)).toShape()
    edge4 = Part.makeLine(ps5,ps6)
    edge5 = Part.makeLine(ps6,ps7)
    edge6 = Part.makeLine(ps7,ps0)

    W0 = Part.Wire([edge0, edge1, edge2, edge3, edge4, edge5, edge6])
    # Part.show(W0)

    makeSolid=True
    isFrenet=True
    pipe0 = Part.Wire(helix).makePipeShell([W0],makeSolid,isFrenet)
    # pipe1 = pipe0.copy()

    TheFaces = []
    TheFaces.append(pipe0.Faces[0])
    TheFaces.append(pipe0.Faces[1])
    TheFaces.append(pipe0.Faces[2])
    TheFaces.append(pipe0.Faces[3])

    TheShell = Part.Shell(TheFaces)
    # print "Shellpoints: ", len(TheShell.Vertexes)

    # Handling of the top faces
    if da is not None:
      TheShell.translate(FreeCAD.Vector(0.0, 0.0, -P))
      for flaeche in TheShell.Faces:
       TheFaces.append(flaeche)
      TheShell.translate(FreeCAD.Vector(0.0, 0.0, -P))
      for flaeche in TheShell.Faces:
       TheFaces.append(flaeche)

      cham_i_delta = da/2.0 - (r-H)
      cham_i = cham_i_delta * math.tan(math.radians(15.0))

      offSet = rotations*P - l
      #FreeCAD.Console.PrintMessage("Der Offset: " + str(offSet/P) + "\n")

      # points for chamfer: common-Method
      pch0 =  (da/2.0-cham_i_delta, 0.0, -cham_i - offSet) # bottom chamfer
      pch1 =  (da/2.0, 0.0, 0.0 - offSet)  #
      pch2 =  (da/2.0, 0.0, -4.0*P - offSet)
      pch3 =  (da/2.0-cham_i_delta, 0.0, -4.0*P - offSet)

      edgech0 = Part.makeLine(pch0,pch1)
      edgech1 = Part.makeLine(pch1,pch2)
      edgech2 = Part.makeLine(pch2,pch3)
      edgech3 = Part.makeLine(pch3,pch0)

      Wch_wire = Part.Wire([edgech0, edgech1, edgech2, edgech3])
      cham_Face =Part.Face(Wch_wire)
      cham_Solid = cham_Face.revolve(Base.Vector(0.0,0.0,-(rotations-1)*P),Base.Vector(0.0,0.0,1.0),360)
      #Part.show(cham_Solid)
      #Part.show(Wch_wire)

      rawTopShell = Part.Shell(TheFaces)
      topShell = rawTopShell.common(cham_Solid)

      # Making a Cutter for the cham face
      commonbox = Part.makeBox(d+4.0*P, d+4.0*P, 2.0*P)
      commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-2.0*P))
      #Part.show(commonbox)

      cutterShell = rawTopShell.common(commonbox)
      bot_edges =[]
      bot_z =  1.0e-5 -2.0*P

      for kante in cutterShell.Edges:
         if (kante.Vertexes[0].Point.z<=bot_z) and (kante.Vertexes[1].Point.z<=bot_z):
            bot_edges.append(kante)
            # Part.show(kante)
      bot_wire = Part.Wire(Part.__sortEdges__(bot_edges))

      bot_face = Part.Face(bot_wire)
      bot_face.reverse()
      t_face = bot_face.copy()
      t_face.translate(Base.Vector(0.0, 0.0, 2.0*P))
      cutterFaces = cutterShell.Faces
      cutterFaces.append(bot_face.Faces[0])
      cutterFaces.append(t_face.Faces[0])
      cutShell = Part.Shell(cutterFaces)
      chamFcutter = Part.Solid(cutShell)

      #Part.show(chamFcutter)
      topCham = cham_Solid.Faces[0]
      topCham = topCham.cut(chamFcutter)

      #Part.show(topCham)
      TheFaces = [topCham.Faces[0]]
      TheFaces.extend(topShell.Faces)

      for i in range(rotations-4):
         TheShell.translate(FreeCAD.Vector(0.0, 0.0,- P))
         for flaeche in TheShell.Faces:
           TheFaces.append(flaeche)

    else:
      commonbox = Part.makeBox(d+4.0*P, d+4.0*P, 3.0*P)
      commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-(3.0)*P))
      topShell = TheShell.common(commonbox)
      top_edges =[]
      top_z =  -1.0e-5

      for kante in topShell.Edges:
         if (kante.Vertexes[0].Point.z>=top_z) and (kante.Vertexes[1].Point.z>=top_z):
            top_edges.append(kante)
            # Part.show(kante)
      top_wire = Part.Wire(Part.__sortEdges__(top_edges))
      top_face = Part.Face(top_wire)

      TheFaces = [top_face.Faces[0]]
      TheFaces.extend(topShell.Faces)

      for i in range(rotations-2):
         TheShell.translate(FreeCAD.Vector(0.0, 0.0,- P))
         for flaeche in TheShell.Faces:
           TheFaces.append(flaeche)

    #FreeCAD.Console.PrintMessage("Base-Shell: " + str(i) + "\n")
    # Make separate faces for the tip of the screw
    botFaces = []
    for i in range(rotations-2, rotations, 1):
       TheShell.translate(FreeCAD.Vector(0.0, 0.0,- P))

       for flaeche in TheShell.Faces:
         botFaces.append(flaeche)
    #FreeCAD.Console.PrintMessage("Bottom-Shell: " + str(i) + "\n")

    if da is not None:
      # points for chamfer: common-Method
      pch0 =  (da/2-cham_i_delta, 0.0, -(rotations)*P + cham_i) # bottom chamfer
      pch1 =  (da/2, 0.0, -(rotations)*P)  #
      pch2 =  (da/2, 0.0, -(rotations)*P + 3.0*P)
      pch3 =  (da/2-cham_i_delta, 0.0, -(rotations)*P + 3.0*P)
      #pch4 =  (r-2.0*cham_i_delta, 0.0, -(rotations)*P + 3.0*P)

      edgech0 = Part.makeLine(pch0,pch1)
      edgech1 = Part.makeLine(pch1,pch2)
      edgech2 = Part.makeLine(pch2,pch3)
      edgech3 = Part.makeLine(pch3,pch0)

      Wch_wire = Part.Wire([edgech0, edgech1, edgech2, edgech3])
      cham_Face =Part.Face(Wch_wire)
      cham_Solid = cham_Face.revolve(Base.Vector(0.0,0.0,-(rotations-1)*P),Base.Vector(0.0,0.0,1.0),360)
      #Part.show(cham_Solid)
      #Part.show(Wch_wire)

      BotShell = Part.Shell(botFaces)
      #Part.show(BotShell)
      chamFcutter.translate(FreeCAD.Vector(0.0, 0.0,-(rotations-1)*P))
      #Part.show(chamFcutter)


      BotShell = BotShell.common(cham_Solid)
      #Part.show(BotShell)

      cham_face = cham_Solid.Faces[0]
      cham_face = cham_face.cut(chamFcutter)
      #Part.show(cham_face)

      for flaeche in BotShell.Faces:
        TheFaces.append(flaeche)
      if da is not None:
        TheFaces.append(cham_face.Faces[0])
      else:
        TheFaces.append(bot_face)
      TheShell = Part.Shell(TheFaces)

      #print self.Tuner, " ", TheShell.ShapeType, " ", TheShell.isValid(), " hrots: ", halfrots_int, " Shellpunkte: ", len(TheShell.Vertexes)

      return TheShell

    else: # make of screw tap
      #FreeCAD.Console.PrintMessage("without chamfer: " + str(i) + "\n")

      commonbox = Part.makeBox(d+4.0*P, d+4.0*P, 3.0*P)
      commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-(rotations)*P+bot_off))
      #commonbox.translate(FreeCAD.Vector(-(d+4.0*P)/2.0, -(d+4.0*P)/2.0,-(rotations+3)*P+bot_off))
      #Part.show(commonbox)

      BotShell = Part.Shell(botFaces)
      #Part.show(BotShell)

      BotShell = BotShell.common(commonbox)
      #BotShell = BotShell.cut(commonbox)
      bot_edges =[]
      bot_z =  1.0e-5 -(rotations)*P + bot_off

      for kante in BotShell.Edges:
         if (kante.Vertexes[0].Point.z<=bot_z) and (kante.Vertexes[1].Point.z<=bot_z):
            bot_edges.append(kante)
            # Part.show(kante)
      bot_wire = Part.Wire(Part.__sortEdges__(bot_edges))

      bot_face = Part.Face(bot_wire)
      bot_face.reverse()

      for flaeche in BotShell.Faces:
        TheFaces.append(flaeche)
      if da is not None:
        raise NotImplementedError('da must be None')
        # TODO: Fix cham_Shell undefined.
        for flaeche in cham_Shell.Faces:
          TheFaces.append(flaeche)
      else:
        TheFaces.append(bot_face)
      TheShell = Part.Shell(TheFaces)
      TheSolid = Part.Solid(TheShell)

      #print self.Tuner, " ", TheShell.ShapeType, " ", TheShell.isValid(), " hrots: ", halfrots_int, " Shellpunkte: ", len(TheShell.Vertexes)

      return TheSolid

  def makeIso4032(self, SType='ISO4032', ThreadType='M6'):
    """ISO 4032 Hex-nut and 4033 Hex-nut"""
    dia = get_diameter(ThreadType)
    if SType == 'ISO4032':
      # P, c, damax,  dw,    e,     m,   mw,   s_nom
      P, c, da, dw, e, m, mw, s = iso4032def[ThreadType]
    if SType == 'ISO4033':
      # P, c, damax,  dw,    e,     m,   mw,   s_nom
      P, c, da, dw, e, m, mw, s = iso4033def[ThreadType]
    if SType == 'ISO4035':
      # P, c, damax,  dw,    e,     m,   mw,   s_nom
      P, c, da, dw, e, m, mw, s = iso4035def[ThreadType]

    residue, turns = math.modf(m/P)
    #halfturns = 2*int(turns)

    if residue > 0.0:
      turns += 1.0
      #halfturns = halfturns +2
    #offSet = r - a

    sqrt2_ = 1.0/math.sqrt(2.0)
    cham = (e-s)*math.sin(math.radians(15)) # needed for chamfer at nut top
    H=P*math.cos(math.radians(30)) # Gewindetiefe H
    cham_i_delta = da/2.0 - (dia/2.0-H*5.0/8.0)
    cham_i = cham_i_delta * math.tan(math.radians(15.0))


    if self.rThread:
      Pnt0 = Base.Vector(da/2.0-2.0*cham_i_delta,0.0,m - 2.0*cham_i)
      Pnt7 = Base.Vector(da/2.0-2.0*cham_i_delta,0.0,0.0+ 2.0*cham_i)
    else:
      Pnt0 = Base.Vector(dia/2.0-H*5.0/8.0,0.0,m - cham_i)
      Pnt7 = Base.Vector(dia/2.0-H*5.0/8.0,0.0,0.0+ cham_i)

    Pnt1 = Base.Vector(da/2.0,0.0,m)
    Pnt2 = Base.Vector(s/2.0,0.0,m)
    Pnt3 = Base.Vector(s/math.sqrt(3.0),0.0,m-cham)
    Pnt4 = Base.Vector(s/math.sqrt(3.0),0.0,cham)
    Pnt5 = Base.Vector(s/2.0,0.0,0.0)
    Pnt6 = Base.Vector(da/2.0,0.0,0.0)

    edge0 = Part.makeLine(Pnt0,Pnt1)
    edge1 = Part.makeLine(Pnt1,Pnt2)
    edge2 = Part.makeLine(Pnt2,Pnt3)
    edge3 = Part.makeLine(Pnt3,Pnt4)
    edge4 = Part.makeLine(Pnt4,Pnt5)
    edge5 = Part.makeLine(Pnt5,Pnt6)
    edge6 = Part.makeLine(Pnt6,Pnt7)
    edge7 = Part.makeLine(Pnt7,Pnt0)

    # create cutting tool for hexagon head
    # Parameters s, k, outer circle diameter =  e/2.0+10.0
    extrude = self.makeHextool(s, m, s*2.0)

    aWire=Part.Wire([edge0,edge1,edge2,edge3,edge4,edge5,edge6,edge7])
    # Part.show(aWire)
    aFace =Part.Face(aWire)
    head = aFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
    #Part.show(head)

    # Part.show(extrude)
    nut = head.cut(extrude)
    # Part.show(nut)

    if self.rThread:
      '''
      threadCutter = self.makeInnerThread(dia, P, int(turns), None, m)
      # Part.show(threadCutter)
      threadCutter.translate(Base.Vector(0.0, 0.0,turns*P))
      nut = nut.cut(threadCutter)
      '''
      nutFaces = [nut.Faces[2]]
      for i in range(4,25):
        nutFaces.append(nut.Faces[i])


      threadShell = self.makeInnerThread_2(dia, P, int(turns), da, m)
      threadShell.translate(Base.Vector(0.0, 0.0,turns*P))
      #Part.show(threadShell)
      nutFaces.extend(threadShell.Faces)

      nutShell = Part.Shell(nutFaces)
      nut = Part.Solid(nutShell)
      #Part.show(nutShell)

    return nut

  def makeEN1661(self, ThreadType='M8'):
    """EN 1661 Hexagon nuts with flange

    chamfer at top of hexagon is wrong = more than 30°
    """
    dia = get_diameter(ThreadType)
    P, da, c, dc, dw, e, m, mw, r1, s = en1661def[ThreadType]

    residue, turns = math.modf(m/P)
    #halfturns = 2*int(turns)

    if residue > 0.0:
      turns += 1.0

    #FreeCAD.Console.PrintMessage("the nut with isoEN1661: " + str(c) + "\n")
    cham = s*(2.0/math.sqrt(3.0)-1.0)*math.sin(math.radians(25)) # needed for chamfer at head top

    sqrt2_ = 1.0/math.sqrt(2.0)

    # Flange is made with a radius of c
    beta = math.radians(25.0)
    tan_beta = math.tan(beta)

    # Calculation of Arc points of flange edge using dc and c
    arc1_x = dc/2.0 - c/2.0 + (c/2.0)*math.sin(beta)
    arc1_z = c/2.0 + (c/2.0)*math.cos(beta)

    hF = arc1_z + (arc1_x -s/2.0) * tan_beta  # height of flange at center

    #kmean = arc1_z + (arc1_x - s/math.sqrt(3.0)) * tan_beta + mw * 1.1 + cham
    #kmean = k * 0.95


    #Hex-Head Points
    #FreeCAD.Console.PrintMessage("the nut with kmean: " + str(m) + "\n")
    PntH0 = Base.Vector(da/2.0,0.0,m)
    PntH1 = Base.Vector(s/2.0,0.0,m)
    edgeH1 = Part.makeLine(PntH0,PntH1)

    hWire=Part.Wire([edgeH1])
    topShell = hWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #Part.show(hWire)
    #Part.show(topShell)

    # create a cutter ring to generate the chamfer at the top of the hex
    chamHori = s/math.sqrt(3.0) - s/2.0
    PntC1 = Base.Vector(s/2.0-chamHori,0.0,m+m)
    PntC2 = Base.Vector(s/math.sqrt(3.0)+chamHori,0.0,m+m)
    PntC3 = Base.Vector(s/2.0-chamHori,0.0,m+cham)
    PntC4 = Base.Vector(s/math.sqrt(3.0)+chamHori,0.0,m-cham-cham)   #s/math.sqrt(3.0)
    edgeC1 = Part.makeLine(PntC3, PntC1)
    edgeC2 = Part.makeLine(PntC1, PntC2)
    edgeC3 = Part.makeLine(PntC2, PntC4)
    edgeC4 = Part.makeLine(PntC4, PntC3)
    cWire = Part.Wire([edgeC4, edgeC1, edgeC2, edgeC3])
    cFace = Part.Face(cWire)
    chamCut = cFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #Part.show(cWire)
    #Part.show(chamCut)


    # create hexagon
    mhex=Base.Matrix()
    mhex.rotateZ(math.radians(60.0))
    polygon = []
    vhex=Base.Vector(s/math.sqrt(3.0),0.0,m)
    for i in range(6):
       polygon.append(vhex)
       vhex = mhex.multiply(vhex)
    polygon.append(vhex)
    hexagon = Part.makePolygon(polygon)
    hexFace = Part.Face(hexagon)
    solidHex = hexFace.extrude(Base.Vector(0.0,0.0,c-m))
    #Part.show(solidHex)
    hexCham = solidHex.cut(chamCut)
    #Part.show(hexCham)

    topFaces = topShell.Faces

    topFaces.append(hexCham.Faces[1])
    topFaces.append(hexCham.Faces[2])
    topFaces.append(hexCham.Faces[8])
    topFaces.append(hexCham.Faces[13])
    topFaces.append(hexCham.Faces[14])
    topFaces.append(hexCham.Faces[12])
    topFaces.append(hexCham.Faces[6])

    hexFaces = [hexCham.Faces[5], hexCham.Faces[11], hexCham.Faces[10]]
    hexFaces.extend([hexCham.Faces[9], hexCham.Faces[3], hexCham.Faces[0]])
    hexShell = Part.Shell(hexFaces)


    H=P*math.cos(math.radians(30)) # Gewindetiefe H
    cham_i_delta = da/2.0 - (dia/2.0-H*5.0/8.0)
    cham_i = cham_i_delta * math.tan(math.radians(15.0))

    # Center of flange:
    Pnt0 = Base.Vector(0.0,0.0,hF)
    Pnt1 = Base.Vector(s/2.0,0.0,hF)

    # arc edge of flange:
    Pnt2 = Base.Vector(arc1_x,0.0,arc1_z)
    Pnt3 = Base.Vector(dc/2.0,0.0,c/2.0)
    Pnt4 = Base.Vector((dc-c)/2.0,0.0,0.0)
    Pnt5 = Base.Vector(da/2.0,0.0,0.0)     #start of fillet between flat and thread

    edge1 = Part.makeLine(Pnt0,Pnt1)
    edge2 = Part.makeLine(Pnt1,Pnt2)
    edge3 = Part.Arc(Pnt2,Pnt3,Pnt4).toShape()
    edge4 = Part.makeLine(Pnt4,Pnt5)

    # make a cutter for the hexShell
    PntHC1 = Base.Vector(0.0,0.0,arc1_z)
    PntHC2 = Base.Vector(0.0,0.0,0.0)

    edgeHC1 = Part.makeLine(Pnt2,PntHC1)
    edgeHC2 = Part.makeLine(PntHC1,PntHC2)
    edgeHC3 = Part.makeLine(PntHC2,Pnt0)

    HCWire = Part.Wire([edge2, edgeHC1, edgeHC2, edgeHC3, edge1])
    HCFace = Part.Face(HCWire)
    hex2Cut = HCFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)

    hexShell = hexShell.cut(hex2Cut)
    #Part.show(hexShell)

    topFaces.extend(hexShell.Faces)

    if self.rThread:
      aWire=Part.Wire([edge2,edge3,edge4])
      boltIndex = 3

    else:
      Pnt7 = Base.Vector(dia/2.0-H*5.0/8.0,0.0,m - cham_i)
      Pnt6 = Base.Vector(dia/2.0-H*5.0/8.0,0.0,0.0+ cham_i)
      edge5 = Part.makeLine(Pnt5,Pnt6)
      edge6 = Part.makeLine(Pnt6,Pnt7)
      edge7 = Part.makeLine(Pnt7,PntH0)
      aWire=Part.Wire([edge2,edge3,edge4,edge5,edge6,edge7])
      boltIndex = 6


    #aFace =Part.Face(aWire)
    #Part.show(aWire)
    headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    #FreeCAD.Console.PrintMessage("der Kopf mit revolve: " + str(dia) + "\n")
    #Part.show(headShell)
    chamFace = headShell.Faces[0].cut(solidHex)
    #Part.show(chamFace)

    topFaces.append(chamFace.Faces[0])
    for i in range(1,boltIndex):
      topFaces.append(headShell.Faces[i])


    if self.rThread:
      #rthread = self.makeShellthread(dia, P, halfturns, True, offSet)
      #rthread.translate(Base.Vector(0.0, 0.0,-a_point-2.0*P))
      threadShell = self.makeInnerThread_2(dia, P, int(turns), da, m)
      threadShell.translate(Base.Vector(0.0, 0.0,turns*P))
      #Part.show(threadShell)
      for tFace in threadShell.Faces:
        topFaces.append(tFace)
      headShell = Part.Shell(topFaces)
      screw = Part.Solid(headShell)
    else:
      screwShell = Part.Shell(topFaces)
      screw = Part.Solid(screwShell)

    return screw

  def makeScrewTap(self, ThreadType ='M6',l=25.0):
    """ISO 7380-1, ISO 7380-2, DIN 967

    make ISO 7380-1 Button head Screw
    make ISO 7380-2 Button head Screw with collar
    make DIN 967 cross recessed pan head Screw with collar
    """
    dia = get_diameter(ThreadType)

    P, tunIn, tunEx  = tuningTable[ThreadType]

    residue, turns = math.modf((l)/P)
    turns += 1.0
    #FreeCAD.Console.PrintMessage("ScrewTap residue: " + str(residue) + " turns: " + str(turns) + "\n")


    if self.rThread:
      screwTap = self.makeInnerThread_2(dia, P, int(turns), None, 0.0)
      screwTap.translate(Base.Vector(0.0, 0.0,(1-residue)*P))
    else:
      H=P*math.cos(math.radians(30)) # Gewindetiefe H
      r=dia/2.0

      # points for inner thread profile
      Pnt0 = Base.Vector(0.0,0.0,(1-residue)*P)
      Pnt1 = Base.Vector(r-H*5.0/8.0,0.0,(1-residue)*P)
      Pnt2 = Base.Vector(r-H*5.0/8.0,0.0,-l)
      Pnt3 = Base.Vector(0.0,0.0,-l)

      edge1 = Part.makeLine(Pnt0,Pnt1)
      edge2 = Part.makeLine(Pnt1,Pnt2)
      edge3 = Part.makeLine(Pnt2,Pnt3)
      aWire=Part.Wire([edge1,edge2,edge3])
      headShell = aWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360.0)
      screwTap = Part.Solid(headShell)

    return screwTap

  def cutChamfer(self, dia_cC, P_cC, l_cC):
    cham_t = P_cC*math.sqrt(3.0)/2.0*17.0/24.0
    PntC0 = Base.Vector(0.0,0.0,-l_cC)
    PntC1 = Base.Vector(dia_cC/2.0-cham_t,0.0,-l_cC)
    PntC2 = Base.Vector(dia_cC/2.0+cham_t,0.0,-l_cC+cham_t+cham_t)
    PntC3 = Base.Vector(dia_cC/2.0+cham_t,0.0,-l_cC-P_cC-cham_t)
    PntC4 = Base.Vector(0.0,0.0,-l_cC-P_cC-cham_t)

    edgeC1 = Part.makeLine(PntC0,PntC1)
    edgeC2 = Part.makeLine(PntC1,PntC2)
    edgeC3 = Part.makeLine(PntC2,PntC3)
    edgeC4 = Part.makeLine(PntC3,PntC4)
    edgeC5 = Part.makeLine(PntC4,PntC0)
    CWire=Part.Wire([edgeC1,edgeC2,edgeC3,edgeC4,edgeC5])
    #Part.show(CWire)
    CFace =Part.Face(CWire)
    cyl = CFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    return cyl

  def makeCross_H3(self, CrossType = '2', m = 6.9, h = 0.0):
    """Cross recess type H

    m = diameter of cross at top of screw at reference level for penetration depth
    """
    b, e_mean, g, f_mean, r, t1, alpha, beta = iso4757def[CrossType]

    rad265 = math.radians(26.5)
    rad28 = math.radians(28.0)
    tg = (m-g)/2.0/math.tan(rad265) # depth at radius of g
    t_tot = tg + g/2.0 * math.tan(rad28) # total depth
    #FreeCAD.Console.PrintMessage("Cross H3: " + str(b) + "\n")

    # print 'tg: ', tg,' t_tot: ', t_tot
    hm = m / 4.0
    hmc = m / 2.0
    rmax = m / 2.0 + hm*math.tan(rad265)

    Pnt0 = Base.Vector(0.0,0.0,hm)
    Pnt1 = Base.Vector(rmax,0.0,hm)
    Pnt3 = Base.Vector(0.0,0.0,0.0)
    Pnt4 = Base.Vector(g/2.0,0.0,-tg)
    Pnt5 = Base.Vector(0.0,0.0,-t_tot)

    edge1 = Part.makeLine(Pnt0,Pnt1)
    edge3 = Part.makeLine(Pnt1,Pnt4)
    edge4 = Part.makeLine(Pnt4,Pnt5)
    # FreeCAD.Console.PrintMessage("Edges made Pnt1: " + str(Pnt1) + "\n")

    aWire=Part.Wire([edge1,edge3,edge4])
    crossShell = aWire.revolve(Pnt3,Base.Vector(0.0,0.0,1.0),360)
    #FreeCAD.Console.PrintMessage("Peak-wire revolved: " + str(e_mean) + "\n")
    cross = Part.Solid(crossShell)
    #Part.show(cross)

    # the need to cut 4 corners out of the above shape.
    # Definition of corner
    # The angles 92 degrees and alpha are defined on a plane which has
    # an angle of beta against our coordinate system.
    # The projected angles are needed for easier calculation!
    rad_alpha = math.radians(alpha/2.0)
    rad92 = math.radians(92.0/2.0)
    rad_beta = math.radians(beta)

    rad_alpha_p = math.atan(math.tan(rad_alpha)/math.cos(rad_beta))
    rad92_p = math.atan(math.tan(rad92)/math.cos(rad_beta))

    tb = tg + (g-b)/2.0 * math.tan(rad28) # depth at dimension b
    rbtop = b/2.0 + (hmc + tb)*math.tan(rad_beta) # radius of b-corner at hm
    rbtot = b/2.0 - (t_tot - tb)*math.tan(rad_beta) # radius of b-corner at t_tot

    dre = e_mean/2.0 / math.tan(rad_alpha_p)  # delta between corner b and corner e in x direction
    #FreeCAD.Console.PrintMessage("delta calculated: " + str(dre) + "\n")

    dx = m/2.0 * math.cos(rad92_p)
    dy = m/2.0 * math.sin(rad92_p)

    PntC0 = Base.Vector(rbtop,0.0,hmc)
    PntC1 = Base.Vector(rbtot,0.0,-t_tot)
    PntC2 = Base.Vector(rbtop+dre,+e_mean/2.0,hmc)
    PntC3 = Base.Vector(rbtot+dre,+e_mean/2.0,-t_tot)
    PntC4 = Base.Vector(rbtop+dre,-e_mean/2.0,hmc)
    PntC5 = Base.Vector(rbtot+dre,-e_mean/2.0,-t_tot)

    PntC6 = Base.Vector(rbtop+dre+dx,+e_mean/2.0+dy,hmc)
    #PntC7 = Base.Vector(rbtot+dre+dx,+e_mean/2.0+dy,-t_tot)
    PntC7 = Base.Vector(rbtot+dre+2.0*dx,+e_mean+2.0*dy,-t_tot)
    PntC8 = Base.Vector(rbtop+dre+dx,-e_mean/2.0-dy,hmc)
    #PntC9 = Base.Vector(rbtot+dre+dx,-e_mean/2.0-dy,-t_tot)
    PntC9 = Base.Vector(rbtot+dre+2.0*dx,-e_mean-2.0*dy,-t_tot)

    #wire_hm = Part.makePolygon([PntC0,PntC2,PntC6,PntC8,PntC4,PntC0])
    #face_hm =Part.Face(wire_hm)
    #Part.show(face_hm)

    wire_t_tot = Part.makePolygon([PntC1,PntC3,PntC7,PntC9,PntC5,PntC1])
    # Part.show(wire_t_tot)
    edgeC1 = Part.makeLine(PntC0,PntC1)
    #FreeCAD.Console.PrintMessage("edgeC1 mit PntC9" + str(PntC9) + "\n")

    makeSolid=True
    isFrenet=False
    corner = Part.Wire(edgeC1).makePipeShell([wire_t_tot],makeSolid,isFrenet)
    #Part.show(corner)

    rot_axis = Base.Vector(0.,0.,1.0)
    sin_res = math.sin(math.radians(90)/2.0)
    cos_res = math.cos(math.radians(90)/2.0)
    rot_axis.multiply(-sin_res) # Calculation of Quaternion-Elements
    #FreeCAD.Console.PrintMessage("Quaternion-Elements" + str(cos_res) + "\n")

    pl_rot = FreeCAD.Placement()
    pl_rot.Rotation = (rot_axis.x,rot_axis.y,rot_axis.z,cos_res) #Rotation-Quaternion 90° z-Axis

    crossShell = crossShell.cut(corner)
    # Part.show(crossShell)
    cutplace = corner.Placement

    cornerFaces = []
    cornerFaces.append(corner.Faces[0])
    cornerFaces.append(corner.Faces[1])
    cornerFaces.append(corner.Faces[3])
    cornerFaces.append(corner.Faces[4])

    cornerShell = Part.Shell(cornerFaces)
    cornerShell = cornerShell.common(cross)
    addPlace = cornerShell.Placement

    crossFaces = cornerShell.Faces

    for i in range(3):
      #cutplace.Rotation = pl_rot.Rotation.multiply(corner.Placement.Rotation)
      corner.Placement.Rotation = pl_rot.Rotation.multiply(corner.Placement.Rotation)
      crossShell = crossShell.cut(corner)
      #addPlace.Rotation = pl_rot.Rotation.multiply(cornerShell.Placement.Rotation)
      cornerShell.Placement.Rotation = pl_rot.Rotation.multiply(cornerShell.Placement.Rotation)
      for coFace in cornerShell.Faces:
        crossFaces.append(coFace)

    # Part.show(crossShell)
    for i in range(1,6):
      crossFaces.append(crossShell.Faces[i])

    crossShell0 = Part.Shell(crossFaces)

    crossFaces.append(crossShell.Faces[0])
    crossShell = Part.Shell(crossFaces)

    cross = Part.Solid(crossShell)


    #FreeCAD.Console.PrintMessage("Placement: " + str(pl_rot) + "\n")

    cross.Placement.Base = Base.Vector(0.0,0.0,h)
    crossShell0.Placement.Base = Base.Vector(0.0,0.0,h)
    #Part.show(crossShell0)
    #Part.show(cross)
    return cross, crossShell0

  def makeAllen2(self, s_a=3.0, t_a=1.5, h_a=2.0):
    """Allen recess cutting tool

    Parameters used: s_mean, k, t_min, dk
    """
    # h_a  top height location of cutting tool
    # s_a hex width
    # t_a dept of the allen
    # dk_a diameter not needed anymore

    e_cham = 2.0 * s_a / math.sqrt(3.0)
    depth = s_a / 3.0
    #FreeCAD.Console.PrintMessage("allen tool: " + str(s_a) + "\n")

    # Points for an arc at the peak of the cone
    rCone = e_cham/4.0
    hyp = (depth*math.sqrt(e_cham**2/depth**2+1.0)*rCone)/e_cham
    radAlpha = math.atan(e_cham/depth)
    radBeta = math.pi/2.0 - radAlpha
    zrConeCenter=hyp - depth -t_a
    xArc1=math.sin(radBeta)*rCone
    zArc1=zrConeCenter - math.cos(radBeta)*rCone
    xArc2=math.sin(radBeta/2.0)*rCone
    zArc2=zrConeCenter - math.cos(radBeta/2.0)*rCone
    zArc3 = zrConeCenter - rCone

    # The round part of the cutting tool, we need for the allen hex recess
    PntH1 = Base.Vector(0.0,0.0,-t_a-depth-depth)
    PntH2 = Base.Vector(e_cham,0.0,-t_a-depth-depth)
    PntH3 = Base.Vector(e_cham,0.0,-t_a+depth)
    PntH4 = Base.Vector(0.0,0.0,-t_a-depth)

    PntA1 = Base.Vector(xArc1,0.0,zArc1)
    PntA2 = Base.Vector(xArc2,0.0,zArc2)
    PntA3 = Base.Vector(0.0,0.0,zArc3)

    edgeA1 = Part.Arc(PntA1,PntA2,PntA3).toShape()

    edgeH1 = Part.makeLine(PntH1,PntH2)
    edgeH2 = Part.makeLine(PntH2,PntH3)
    edgeH3 = Part.makeLine(PntH3,PntA1)
    edgeH4 = Part.makeLine(PntA3,PntH1)

    hWire=Part.Wire([edgeH1,edgeH2,edgeH3,edgeA1,edgeH4])
    # Part.show(hWire)
    hFace =Part.Face(hWire)
    roundtool = hFace.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)

    # create hexagon
    mhex=Base.Matrix()
    mhex.rotateZ(math.radians(60.0))
    polygon = []
    vhex=Base.Vector(s_a/math.sqrt(3.0),0.0,1.0)
    for i in range(6):
       polygon.append(vhex)
       vhex = mhex.multiply(vhex)
    polygon.append(vhex)
    hexagon = Part.makePolygon(polygon)
    hexFace = Part.Face(hexagon)
    solidHex = hexFace.extrude(Base.Vector(0.0,0.0,-1.0-t_a-depth*1.1))
    allen = solidHex.cut(roundtool)
    # Part.show(allen)

    allenFaces = [allen.Faces[0]]
    for i in range(2,9):
      allenFaces.append(allen.Faces[i])
    allenShell = Part.Shell(allenFaces)
    solidHex.Placement.Base = Base.Vector(0.0,0.0,h_a)
    allenShell.Placement.Base = Base.Vector(0.0,0.0,h_a)
    return solidHex, allenShell

  def makeIso10664_3(self,RType ='T20',t_hl=3.0, h_hl = 0):
    """ISO 10664 Hexalobular internal driving feature for bolts and screws"""
    # t_hl depth of the recess
    # h_hl top height location of Cutting tool
    A, B, Re = iso10664def[RType]
    sqrt_3 = math.sqrt(3.0)
    depth=A/4.0
    offSet = 1.0

    # Chamfer cutter for the hexalobular recess
    PntH1 = Base.Vector(0.0,0.0,-t_hl-depth-1.0)
    #PntH2 = Base.Vector(A/2.0*1.02,0.0,-t_hl-depth-1.0)
    #PntH3 = Base.Vector(A/2.0*1.02,0.0,-t_hl)
    PntH2 = Base.Vector(A,0.0,-t_hl-depth-1.0)
    PntH3 = Base.Vector(A,0.0,-t_hl+depth)
    PntH4 = Base.Vector(0.0,0.0,-t_hl-depth)

    # Points for an arc at the peak of the cone
    rCone = A/4.0
    hyp = (depth*math.sqrt(A**2/depth**2+1.0)*rCone)/A
    radAlpha = math.atan(A/depth)
    radBeta = math.pi/2.0 - radAlpha
    zrConeCenter=hyp - depth -t_hl
    xArc1=math.sin(radBeta)*rCone
    zArc1=zrConeCenter - math.cos(radBeta)*rCone
    xArc2=math.sin(radBeta/2.0)*rCone
    zArc2=zrConeCenter - math.cos(radBeta/2.0)*rCone
    zArc3 = zrConeCenter - rCone

    PntA1 = Base.Vector(xArc1,0.0,zArc1)
    PntA2 = Base.Vector(xArc2,0.0,zArc2)
    PntA3 = Base.Vector(0.0,0.0,zArc3)

    edgeA1 = Part.Arc(PntA1,PntA2,PntA3).toShape()

    edgeH1 = Part.makeLine(PntH1,PntH2)
    edgeH2 = Part.makeLine(PntH2,PntH3)
    edgeH3 = Part.makeLine(PntH3,PntA1)
    edgeH4 = Part.makeLine(PntA3,PntH1)

    hWire=Part.Wire([edgeH1,edgeH2,edgeH3,edgeA1])
    cutShell = hWire.revolve(Base.Vector(0.0,0.0,0.0),Base.Vector(0.0,0.0,1.0),360)
    cutTool = Part.Solid(cutShell)


    Ri = -((B+sqrt_3*(2.*Re-A))*B+(A-4.*Re)*A)/(4.*B-2.*sqrt_3*A+(4.*sqrt_3-8.)*Re)
    #print '2nd  Ri last solution: ', Ri
    beta=math.acos(A/(4*Ri+4*Re)-(2*Re)/(4*Ri+4*Re))-math.pi/6
    #print 'beta: ', beta
    Rh=(sqrt_3*(A/2.0-Re))/2.0
    Re_x = A/2.0 - Re + Re*math.sin(beta)
    Re_y = Re*math.cos(beta)
    Ri_y = B/4.0
    Ri_x = sqrt_3*B/4.0

    mhex=Base.Matrix()
    mhex.rotateZ(math.radians(60.0))
    hexlobWireList = []

    PntRe0=Base.Vector(Re_x,-Re_y,offSet)
    PntRe1=Base.Vector(A/2.0,0.0,offSet)
    PntRe2=Base.Vector(Re_x,Re_y,offSet)
    edge0 = Part.Arc(PntRe0,PntRe1,PntRe2).toShape()
    #Part.show(edge0)
    hexlobWireList.append(edge0)

    PntRi = Base.Vector(Ri_x,Ri_y,offSet)
    PntRi2 = mhex.multiply(PntRe0)
    edge1 = Part.Arc(PntRe2,PntRi,PntRi2).toShape()
    #Part.show(edge1)
    hexlobWireList.append(edge1)

    for i in range(5):
       PntRe1 = mhex.multiply(PntRe1)
       PntRe2 = mhex.multiply(PntRe2)
       edge0 = Part.Arc(PntRi2,PntRe1,PntRe2).toShape()
       hexlobWireList.append(edge0)
       PntRi = mhex.multiply(PntRi)
       PntRi2 = mhex.multiply(PntRi2)
       if i == 5:
          edge1 = Part.Arc(PntRe2,PntRi,PntRe0).toShape()
       else:
          edge1 = Part.Arc(PntRe2,PntRi,PntRi2).toShape()
       hexlobWireList.append(edge1)
    hexlobWire=Part.Wire(hexlobWireList)
    #Part.show(hWire)

    face=Part.Face(hexlobWire)

    # Extrude in z to create the cutting tool for the screw-head-face
    Helo=face.extrude(Base.Vector(0.0,0.0,-t_hl-depth-offSet))
    # Make the recess-shell for the screw-head-shell

    hexlob = Helo.cut(cutTool)
    #Part.show(hexlob)
    hexlobFaces = [hexlob.Faces[0]]
    for i in range(2,15):
      hexlobFaces.append(hexlob.Faces[i])

    hexlobShell = Part.Shell(hexlobFaces)

    hexlobShell.Placement.Base = Base.Vector(0.0,0.0,h_hl)
    Helo.Placement.Base = Base.Vector(0.0,0.0,h_hl)

    return Helo, hexlobShell

  def setThreadType(self, TType = 'simple'):
    self.simpThread = False
    self.symThread = False
    self.rThread = False
    if TType == 'simple':
      self.simpThread = True
    if TType == 'symbol':
      self.symThread = True
    if TType == 'real':
      self.rThread = True

  def setTuner(self, myTuner = 511):
    self.Tuner = myTuner


class ScrewMacro(object):
  d = QtGui.QWidget()
  d.ui = Ui_ScrewMaker()
  d.ui.setupUi(d)
  if __name__ == '__main__':
    d.show()


def main():
  o = ScrewMacro()

if __name__ == '__main__':
  main()
