Skip to content
Snippets Groups Projects
createMesh.py 81.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • # ##### BEGIN GPL LICENSE BLOCK #####
    
    #
    #  This program is free software; you can redistribute it and/or
    #  modify it under the terms of the GNU General Public License
    #  as published by the Free Software Foundation; either version 2
    #  of the License, or (at your option) any later version.
    #
    #  This program 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 General Public License for more details.
    #
    #  You should have received a copy of the GNU General Public License
    #  along with this program; if not, write to the Free Software Foundation,
    #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ##### END GPL LICENSE BLOCK #####
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    import bpy
    
    from mathutils import (
            Matrix,
            Vector,
    
    Aaron Keith's avatar
    Aaron Keith committed
            geometry,
    
            )
    from math import (
    
    Aaron Keith's avatar
    Aaron Keith committed
            tan, radians,atan,degrees
    
    from random import triangular
    
    Aaron Keith's avatar
    Aaron Keith committed
    from bpy_extras.object_utils import AddObjectHelper, object_data_add
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    NARROW_UI = 180
    MAX_INPUT_NUMBER = 50
    
    
    GLOBAL_SCALE = 1       # 1 blender unit = X mm
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    
    # next two utility functions are stolen from import_obj.py
    
    def unpack_list(list_of_tuples):
        l = []
        for t in list_of_tuples:
            l.extend(t)
        return l
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def unpack_face_list(list_of_tuples):
        l = []
        for t in list_of_tuples:
            face = [i for i in t]
    
            if len(face) != 3 and len(face) != 4:
    
                raise RuntimeError("{0} vertices in face".format(len(face)))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            # rotate indices if the 4th is 0
            if len(face) == 4 and face[3] == 0:
                face = [face[3], face[0], face[1], face[2]]
    
            if len(face) == 3:
                face.append(0)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            l.extend(face)
    
        return l
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    Remove Doubles takes a list on Verts and a list of Faces and
    removes the doubles, much like Blender does in edit mode.
    
    Aaron Keith's avatar
    Aaron Keith committed
    It doesn't have the range function  but it will round the corrdinates
    
    and remove verts that are very close together.  The function
    
    Aaron Keith's avatar
    Aaron Keith committed
    is useful because you can perform a "Remove Doubles" with out
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    having to enter Edit Mode. Having to enter edit mode has the
    disadvantage of not being able to interactively change the properties.
    
    def RemoveDoubles(verts, faces, Decimal_Places=4):
    
        new_verts = []
        new_faces = []
        dict_verts = {}
        Rounded_Verts = []
    
            Rounded_Verts.append([round(v[0], Decimal_Places),
                                  round(v[1], Decimal_Places),
                                  round(v[2], Decimal_Places)])
    
    
        for face in faces:
            new_face = []
            for vert_index in face:
                Real_co = tuple(verts[vert_index])
                Rounded_co = tuple(Rounded_Verts[vert_index])
    
                if Rounded_co not in dict_verts:
                    dict_verts[Rounded_co] = len(dict_verts)
                    new_verts.append(Real_co)
    
                if dict_verts[Rounded_co] not in new_face:
    
                    new_face.append(dict_verts[Rounded_co])
            if len(new_face) == 3 or len(new_face) == 4:
                new_faces.append(new_face)
    
        return new_verts, new_faces
    
    def Scale_Mesh_Verts(verts, scale_factor):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Ret_verts = []
        for v in verts:
    
            Ret_verts.append([v[0] * scale_factor, v[1] * scale_factor, v[2] * scale_factor])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        return Ret_verts
    
    
    
    # Create a matrix representing a rotation.
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    
    # Parameters:
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    #
    #        * angle (float) - The angle of rotation desired.
    #        * matSize (int) - The size of the rotation matrix to construct. Can be 2d, 3d, or 4d.
    #        * axisFlag (string (optional)) - Possible values:
    #              o "x - x-axis rotation"
    #              o "y - y-axis rotation"
    #              o "z - z-axis rotation"
    #              o "r - arbitrary rotation around vector"
    #        * axis (Vector object. (optional)) - The arbitrary axis of rotation used with "R"
    #
    
    # Returns: Matrix object.
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def Simple_RotationMatrix(angle, matSize, axisFlag):
    
        if matSize != 4:
            print("Simple_RotationMatrix can only do 4x4")
    
        q = radians(angle)  # make the rotation go clockwise
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        if axisFlag == 'x':
    
            matrix = Matrix.Rotation(q, 4, 'X')
        elif axisFlag == 'y':
            matrix = Matrix.Rotation(q, 4, 'Y')
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        elif axisFlag == 'z':
    
            matrix = Matrix.Rotation(q, 4, 'Z')
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        else:
    
            print("Simple_RotationMatrix can only do x y z axis")
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        return matrix
    
    
    
    # ####################################################################
    #              Converter Functions For Bolt Factory
    # ####################################################################
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def Flat_To_Radius(FLAT):
    
        h = (float(FLAT) / 2) / cos(radians(30))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        return h
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def Get_Phillips_Bit_Height(Bit_Dia):
    
        Flat_Width_half = (Bit_Dia * (0.5 / 1.82)) / 2.0
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Bit_Rad = Bit_Dia / 2.0
        x = Bit_Rad - Flat_Width_half
    
        y = tan(radians(60)) * x
    
    # ####################################################################
    #                    Miscellaneous Utilities
    # ####################################################################
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    # Returns a list of verts rotated by the given matrix. Used by SpinDup
    
    def Rot_Mesh(verts, matrix):
    
    Aaron Keith's avatar
    Aaron Keith committed
        return [(matrix @ Vector(v))[:] for v in verts]
    
    # Returns a list of faces that has there index incremented by offset
    
    def Copy_Faces(faces, offset):
    
        return [[(i + offset) for i in f] for f in faces]
    
    # Much like Blenders built in SpinDup
    def SpinDup(VERTS, FACES, DEGREE, DIVISIONS, AXIS):
        verts = []
        faces = []
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        if DIVISIONS == 0:
    
        step = DEGREE / DIVISIONS  # set step so pieces * step = degrees in arc
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        for i in range(int(DIVISIONS)):
    
            rotmat = Simple_RotationMatrix(step * i, 4, AXIS)  # 4x4 rotation matrix, 30d about the x axis.
            Rot = Rot_Mesh(VERTS, rotmat)
            faces.extend(Copy_Faces(FACES, len(verts)))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            verts.extend(Rot)
    
        return verts, faces
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    
    # Returns a list of verts that have been moved up the z axis by DISTANCE
    
    def Move_Verts_Up_Z(VERTS, DISTANCE):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        ret = []
        for v in VERTS:
    
            ret.append([v[0], v[1], v[2] + DISTANCE])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        return ret
    
    
    
    # Returns a list of verts and faces that has been mirrored in the AXIS
    
    def Mirror_Verts_Faces(VERTS, FACES, AXIS, FLIP_POINT=0):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        ret_vert = []
        ret_face = []
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        if AXIS == 'y':
            for v in VERTS:
                Delta = v[0] - FLIP_POINT
    
                ret_vert.append([FLIP_POINT - Delta, v[1], v[2]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        if AXIS == 'x':
            for v in VERTS:
                Delta = v[1] - FLIP_POINT
    
                ret_vert.append([v[0], FLIP_POINT - Delta, v[2]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        if AXIS == 'z':
            for v in VERTS:
                Delta = v[2] - FLIP_POINT
    
                ret_vert.append([v[0], v[1], FLIP_POINT - Delta])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        for f in FACES:
            fsub = []
            for i in range(len(f)):
    
                fsub.append(f[i] + offset)
            fsub.reverse()  # flip the order to make norm point out
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            ret_face.append(fsub)
    
        return ret_vert, ret_face
    
    # Returns a list of faces that
    # make up an array of 4 point polygon.
    
    def Build_Face_List_Quads(OFFSET, COLUMN, ROW, FLIP=0):
    
        Ret = []
        RowStart = 0
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        for j in range(ROW):
    
                Res1 = RowStart + i
    
                Res2 = RowStart + i + (COLUMN + 1)
                Res3 = RowStart + i + (COLUMN + 1) + 1
    
                Res4 = RowStart + i + 1
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                if FLIP:
    
                    Ret.append([OFFSET + Res1, OFFSET + Res2, OFFSET + Res3, OFFSET + Res4])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                else:
    
                    Ret.append([OFFSET + Res4, OFFSET + Res3, OFFSET + Res2, OFFSET + Res1])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        return Ret
    
    
    
    # Returns a list of faces that makes up a fill pattern for a
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    # circle
    
    def Fill_Ring_Face(OFFSET, NUM, FACE_DOWN=0):
        Ret = []
        Face = [1, 2, 0]
        TempFace = [0, 0, 0]
    
    Campbell Barton's avatar
    Campbell Barton committed
        # A = 0  # UNUSED
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        B = 1
        C = 2
        if NUM < 3:
            return None
    
        for i in range(NUM - 2):
            if (i % 2):
                TempFace[0] = Face[C]
                TempFace[1] = Face[C] + 1
                TempFace[2] = Face[B]
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                if FACE_DOWN:
    
                    Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                else:
    
                    Ret.append([OFFSET + Face[0], OFFSET + Face[1], OFFSET + Face[2]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            else:
    
                TempFace[0] = Face[C]
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                if Face[C] == 0:
    
                    TempFace[1] = NUM - 1
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                else:
    
                    TempFace[1] = Face[C] - 1
                TempFace[2] = Face[B]
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                if FACE_DOWN:
    
                    Ret.append([OFFSET + Face[0], OFFSET + Face[1], OFFSET + Face[2]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                else:
    
                    Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            Face[0] = TempFace[0]
            Face[1] = TempFace[1]
            Face[2] = TempFace[2]
        return Ret
    
    Aaron Keith's avatar
    Aaron Keith committed
    # Returns a list of faces that makes up a fill pattern around the last vert
    def Fill_Fan_Face(OFFSET, NUM, FACE_DOWN=0):
        Ret = []
        Face = [NUM-1,0,1]
        TempFace = [0, 0, 0]
        A = 0  
        #B = 1 unsed
        C = 2
        if NUM < 3:
            return None
        for _i in range(NUM - 2):
            TempFace[0] = Face[A]
            TempFace[1] = Face[C] 
            TempFace[2] = Face[C]+1
            if FACE_DOWN:
                Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
            else:
                Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
    
            Face[0] = TempFace[0]
            Face[1] = TempFace[1]
            Face[2] = TempFace[2]
        return Ret
    
    # ####################################################################
    #                    Create Allen Bit
    # ####################################################################
    
    def Allen_Fill(OFFSET, FLIP=0):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        faces = []
    
        Lookup = [[19, 1, 0],
                  [19, 2, 1],
                  [19, 3, 2],
                  [19, 20, 3],
                  [20, 4, 3],
                  [20, 5, 4],
                  [20, 6, 5],
                  [20, 7, 6],
                  [20, 8, 7],
                  [20, 9, 8],
    
                  [20, 21, 9],
    
                  [21, 10, 9],
                  [21, 11, 10],
                  [21, 12, 11],
                  [21, 13, 12],
                  [21, 14, 13],
                  [21, 15, 14],
    
                  [21, 22, 15],
                  [22, 16, 15],
                  [22, 17, 16],
                  [22, 18, 17]
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                  ]
        for i in Lookup:
            if FLIP:
    
                faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            else:
    
                faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        return faces
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def Allen_Bit_Dia(FLAT_DISTANCE):
    
        Flat_Radius = (float(FLAT_DISTANCE) / 2.0) / cos(radians(30))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        return (Flat_Radius * 1.05) * 2.0
    
    def Allen_Bit_Dia_To_Flat(DIA):
        Flat_Radius = (DIA / 2.0) / 1.05
        return (Flat_Radius * cos(radians(30))) * 2.0
    
    def Create_Allen_Bit(FLAT_DISTANCE, HEIGHT):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        verts = []
        faces = []
    
        Flat_Radius = (float(FLAT_DISTANCE) / 2.0) / cos(radians(30))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        OUTTER_RADIUS = Flat_Radius * 1.05
    
        Outter_Radius_Height = Flat_Radius * (0.1 / 5.77)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        FaceStart_Outside = len(verts)
    
        Deg_Step = 360.0 / float(DIV_COUNT)
    
        for i in range(int(DIV_COUNT / 2) + 1):  # only do half and mirror later
            x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
            y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
            verts.append([x, y, 0])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        FaceStart_Inside = len(verts)
    
        Deg_Step = 360.0 / float(6)
        for i in range(int(6 / 2) + 1):
            x = sin(radians(i * Deg_Step)) * Flat_Radius
            y = cos(radians(i * Deg_Step)) * Flat_Radius
            verts.append([x, y, 0 - Outter_Radius_Height])
    
        faces.extend(Allen_Fill(FaceStart_Outside, 0))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        FaceStart_Bottom = len(verts)
    
        Deg_Step = 360.0 / float(6)
        for i in range(int(6 / 2) + 1):
            x = sin(radians(i * Deg_Step)) * Flat_Radius
            y = cos(radians(i * Deg_Step)) * Flat_Radius
            verts.append([x, y, 0 - HEIGHT])
    
        faces.extend(Build_Face_List_Quads(FaceStart_Inside, 3, 1, True))
        faces.extend(Fill_Ring_Face(FaceStart_Bottom, 4))
    
        M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'y')
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        verts.extend(M_Verts)
        faces.extend(M_Faces)
    
        return verts, faces, OUTTER_RADIUS * 2.0
    
    Aaron Keith's avatar
    Aaron Keith committed
    # ####################################################################
    #                    Create Torx Bit
    # ####################################################################
    
    def Torx_Bit_Size_To_Point_Distance(Bit_Size):
        if Bit_Size == 'bf_Torx_T10':
            return 2.83
        elif Bit_Size == 'bf_Torx_T20':
            return 3.94
        elif Bit_Size == 'bf_Torx_T25':
            return 4.52
        elif Bit_Size == 'bf_Torx_T30':
            return 5.61
        elif Bit_Size == 'bf_Torx_T40':
            return 6.75
        elif Bit_Size == 'bf_Torx_T50':
            return 8.94
        elif Bit_Size == 'bf_Torx_T55':
            return 8.94
        else:
            return 2.83  #default to M3
    
    def Torx_Fill(OFFSET, FLIP=0):
        faces = []
        Lookup = [[0,10,11],
                [0,11, 12],
                [0,12,1],
                
                [1, 12, 13],
                [1, 13, 14],
                [1, 14, 15],
                [1, 15, 2],
                
                [2, 15, 16],
                [2, 16, 17],
                [2, 17, 18],
                [2, 18, 19],
                [2, 19, 3],
                
                [3, 19, 20],
                [3, 20, 21],
                [3, 21, 22],
                [3, 22, 23],
                [3, 23, 24],
                [3, 24, 25],
                [3, 25, 4],
                
                
                [4, 25, 26],
                [4, 26, 27],
                [4, 27, 28],
                [4, 28, 29],
                [4, 29, 30],
                [4, 30, 31],
                [4, 31, 5],
                
                [5, 31, 32],
                [5, 32, 33],
                [5, 33, 34],
                [5, 34, 35],
                [5, 35, 36],
                [5, 36, 6],
                
                [6, 36, 37],
                [6, 37, 38],
                [6, 38, 39],
                [6, 39, 7],
                
                [7, 39, 40],
                [7, 40, 41],
                [7, 41, 42],
                [7, 42, 43],
                [7, 43, 8],
                
                [8, 43, 44],
                [8, 44, 45],
                [8, 45, 46],
                [8, 46, 47],
                [8, 47, 48],
                [8, 48, 49],
                [8, 49, 50],
                [8, 50, 51],
                [8, 51, 52],
                [8, 52, 9],
                  ]
        for i in Lookup:
            if FLIP:
                faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
            else:
                faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
    
        return faces
    
    
    
    Aaron Keith's avatar
    Aaron Keith committed
    def Create_Torx_Bit(Point_Distance, HEIGHT):
        verts = []
        faces = []
    
        POINT_RADIUS = Point_Distance * 0.5
        OUTTER_RADIUS = POINT_RADIUS * 1.05
    
        POINT_1_Y = POINT_RADIUS * 0.816592592592593
        POINT_2_X = POINT_RADIUS * 0.511111111111111 
        POINT_2_Y = POINT_RADIUS * 0.885274074074074     
        POINT_3_X = POINT_RADIUS * 0.7072 
        POINT_3_Y = POINT_RADIUS * 0.408296296296296 
        POINT_4_X = POINT_RADIUS * 1.02222222222222 
        SMALL_RADIUS = POINT_RADIUS * 0.183407407407407 
        BIG_RADIUS = POINT_RADIUS * 0.333333333333333 
    #     Values for T40    #     POINT_1_Y = 2.756
    #     POINT_2_X = 1.725
    #     POINT_2_Y = 2.9878    
    #     POINT_3_X = 2.3868
    #     POINT_3_Y = 1.378
    #     POINT_4_X = 3.45
    #     
    #     SMALL_RADIUS = 0.619
    #     BIG_RADIUS = 1.125
    
        def Do_Curve(Curve_Height):
            for i in range(0, 90, 10):  
                x = sin(radians(i)) * SMALL_RADIUS
                y = cos(radians(i)) * SMALL_RADIUS
                verts.append([x, POINT_1_Y + y, Curve_Height])
        
            for i in range(260, 150, -10):  
                x = sin(radians(i)) * BIG_RADIUS
                y = cos(radians(i)) * BIG_RADIUS
                verts.append([POINT_2_X + x, POINT_2_Y + y, Curve_Height])
        
            for i in range(340, 150 + 360, 10):
                x = sin(radians(i%360)) * SMALL_RADIUS
                y = cos(radians(i%360)) * SMALL_RADIUS
                verts.append([POINT_3_X + x, POINT_3_Y + y, Curve_Height])
        
            for i in range(320, 260, -10):  
                x = sin(radians(i)) * BIG_RADIUS
                y = cos(radians(i)) * BIG_RADIUS
                verts.append([POINT_4_X + x, y, Curve_Height])
    
        FaceStart_Outside = len(verts)
    
        for i in range(0, 100, 10):
            x = sin(radians(i)) * OUTTER_RADIUS
            y = cos(radians(i)) * OUTTER_RADIUS
            verts.append([x, y, 0])
    
        FaceStart_Top_Curve= len(verts)
        Do_Curve(0)
        faces.extend(Torx_Fill(FaceStart_Outside, 0))
        
        FaceStart_Bottom_Curve= len(verts)
        Do_Curve(0 - HEIGHT)
        
        faces.extend(Build_Face_List_Quads(FaceStart_Top_Curve,42 ,1 , True))
     
        verts.append([0,0,0 - HEIGHT]) # add center point for fill Fan
        faces.extend(Fill_Fan_Face(FaceStart_Bottom_Curve, 44))
     
        M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'x')
        verts.extend(M_Verts)
        faces.extend(M_Faces)
      
        M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'y')
        verts.extend(M_Verts)
        faces.extend(M_Faces)
    
        return verts, faces, OUTTER_RADIUS * 2.0
    
    # ####################################################################
    #                    Create Phillips Bit
    # ####################################################################
    
    def Phillips_Fill(OFFSET, FLIP=0):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        faces = []
    
        Lookup = [[0, 1, 10],
                  [1, 11, 10],
                  [1, 2, 11],
                  [2, 12, 11],
    
                  [2, 3, 12],
                  [3, 4, 12],
                  [4, 5, 12],
                  [5, 6, 12],
                  [6, 7, 12],
    
                  [7, 13, 12],
                  [7, 8, 13],
                  [8, 14, 13],
                  [8, 9, 14],
    
                  [10, 11, 16, 15],
                  [11, 12, 16],
                  [12, 13, 16],
                  [13, 14, 17, 16],
                  [15, 16, 17, 18]
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                  ]
        for i in Lookup:
            if FLIP:
                if len(i) == 3:
    
                    faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
    
                    faces.append([OFFSET + i[3], OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            else:
                if len(i) == 3:
    
                    faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                else:
    
                    faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2], OFFSET + i[3]])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        return faces
    
    
    
    def Create_Phillips_Bit(FLAT_DIA, FLAT_WIDTH, HEIGHT):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        verts = []
        faces = []
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        FLAT_RADIUS = FLAT_DIA * 0.5
        OUTTER_RADIUS = FLAT_RADIUS * 1.05
    
        Flat_Half = float(FLAT_WIDTH) / 2.0
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        FaceStart_Outside = len(verts)
    
        Deg_Step = 360.0 / float(DIV_COUNT)
        for i in range(int(DIV_COUNT / 4) + 1):  # only do half and mirror later
            x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
            y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
            verts.append([x, y, 0])
    
        # FaceStart_Inside = len(verts)               # UNUSED
        verts.append([0, FLAT_RADIUS, 0])             # 10
        verts.append([Flat_Half, FLAT_RADIUS, 0])     # 11
        verts.append([Flat_Half, Flat_Half, 0])       # 12
        verts.append([FLAT_RADIUS, Flat_Half, 0])     # 13
        verts.append([FLAT_RADIUS, 0, 0])             # 14
    
        verts.append([0, Flat_Half, 0 - HEIGHT])          # 15
        verts.append([Flat_Half, Flat_Half, 0 - HEIGHT])  # 16
        verts.append([Flat_Half, 0, 0 - HEIGHT])          # 17
    
        verts.append([0, 0, 0 - HEIGHT])            # 18
    
        faces.extend(Phillips_Fill(FaceStart_Outside, True))
    
        Spin_Verts, Spin_Face = SpinDup(verts, faces, 360, 4, 'z')
    
        return Spin_Verts, Spin_Face, OUTTER_RADIUS * 2
    
    # ####################################################################
    #                    Create Head Types
    # ####################################################################
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    def Max_Pan_Bit_Dia(HEAD_DIA):
        HEAD_RADIUS = HEAD_DIA * 0.5
        XRad = HEAD_RADIUS * 1.976
    
        return (sin(radians(10)) * XRad) * 2.0
    
    def Create_Pan_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, FACE_OFFSET, DIV_COUNT):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
        HOLE_RADIUS = HOLE_DIA * 0.5
        HEAD_RADIUS = HEAD_DIA * 0.5
        SHANK_RADIUS = SHANK_DIA * 0.5
    
        verts = []
        faces = []
        Row = 0
    
    Campbell Barton's avatar
    Campbell Barton committed
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        XRad = HEAD_RADIUS * 1.976
        ZRad = HEAD_RADIUS * 1.768
        EndRad = HEAD_RADIUS * 0.284
        EndZOffset = HEAD_RADIUS * 0.432
        HEIGHT = HEAD_RADIUS * 0.59
    
        """
        Dome_Rad =  5.6
        RAD_Offset = 4.9
        OtherRad = 0.8
        OtherRad_X_Offset = 4.2
        OtherRad_Z_Offset = 2.52
        XRad = 9.88
        ZRad = 8.84
        EndRad = 1.42
        EndZOffset = 2.16
        HEIGHT = 2.95
        """
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        FaceStart = FACE_OFFSET
    
    
        z = cos(radians(10)) * ZRad
        verts.append([HOLE_RADIUS, 0.0, (0.0 - ZRad) + z])
        Start_Height = 0 - ((0.0 - ZRad) + z)
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
    
        # for i in range(0,30,10):  was 0 to 30 more work needed to make this look good.
        for i in range(10, 30, 10):
            x = sin(radians(i)) * XRad
            z = cos(radians(i)) * ZRad
            verts.append([x, 0.0, (0.0 - ZRad) + z])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            Row += 1
    
    
        for i in range(20, 140, 10):
            x = sin(radians(i)) * EndRad
            z = cos(radians(i)) * EndRad
            if ((0.0 - EndZOffset) + z) < (0.0 - HEIGHT):
                verts.append([(HEAD_RADIUS - EndRad) + x, 0.0, 0.0 - HEIGHT])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            else:
    
                verts.append([(HEAD_RADIUS - EndRad) + x, 0.0, (0.0 - EndZOffset) + z])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            Row += 1
    
        verts.append([SHANK_RADIUS, 0.0, (0.0 - HEIGHT)])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
        verts.append([SHANK_RADIUS, 0.0, (0.0 - HEIGHT) - Start_Height])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
    
        sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
        sVerts.extend(verts)  # add the start verts to the Spin verts to complete the loop
    
        faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
    
    Campbell Barton's avatar
    Campbell Barton committed
        # Global_Head_Height = HEIGHT  # UNUSED
    
        return Move_Verts_Up_Z(sVerts, Start_Height), faces, HEIGHT
    
    def Create_Dome_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, FACE_OFFSET, DIV_COUNT):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        HOLE_RADIUS = HOLE_DIA * 0.5
        HEAD_RADIUS = HEAD_DIA * 0.5
        SHANK_RADIUS = SHANK_DIA * 0.5
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        verts = []
        faces = []
        Row = 0
    
        # Dome_Rad =  HEAD_RADIUS * (1.0/1.75)
    
        Dome_Rad = HEAD_RADIUS * 1.12
        # Head_Height = HEAD_RADIUS * 0.78
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        RAD_Offset = HEAD_RADIUS * 0.98
        Dome_Height = HEAD_RADIUS * 0.64
        OtherRad = HEAD_RADIUS * 0.16
        OtherRad_X_Offset = HEAD_RADIUS * 0.84
        OtherRad_Z_Offset = HEAD_RADIUS * 0.504
    
        """
        Dome_Rad =  5.6
        RAD_Offset = 4.9
        Dome_Height = 3.2
        OtherRad = 0.8
        OtherRad_X_Offset = 4.2
        OtherRad_Z_Offset = 2.52
       """
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        FaceStart = FACE_OFFSET
    
        verts.append([HOLE_RADIUS, 0.0, 0.0])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
    
        for i in range(0, 60, 10):
            x = sin(radians(i)) * Dome_Rad
            z = cos(radians(i)) * Dome_Rad
            if ((0.0 - RAD_Offset) + z) <= 0:
                verts.append([x, 0.0, (0.0 - RAD_Offset) + z])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
                Row += 1
    
    
        for i in range(60, 160, 10):
            x = sin(radians(i)) * OtherRad
            z = cos(radians(i)) * OtherRad
            z = (0.0 - OtherRad_Z_Offset) + z
            if z < (0.0 - Dome_Height):
                z = (0.0 - Dome_Height)
            verts.append([OtherRad_X_Offset + x, 0.0, z])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            Row += 1
    
        verts.append([SHANK_RADIUS, 0.0, (0.0 - Dome_Height)])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
    
        sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
        sVerts.extend(verts)   # add the start verts to the Spin verts to complete the loop
    
        faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
    
        return sVerts, faces, Dome_Height
    
    def Create_CounterSink_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, DIV_COUNT):
    
        HOLE_RADIUS = HOLE_DIA * 0.5
        HEAD_RADIUS = HEAD_DIA * 0.5
        SHANK_RADIUS = SHANK_DIA * 0.5
    
        verts = []
        faces = []
        Row = 0
    
    
        # HEAD_RADIUS = (HEIGHT/tan(radians(60))) + SHANK_RADIUS
    
        HEIGHT = tan(radians(60)) * (HEAD_RADIUS - SHANK_RADIUS)
    
        FaceStart = len(verts)
    
    
        verts.append([HOLE_RADIUS, 0.0, 0.0])
    
        Row += 1
    
    
        # rad
        for i in range(0, 100, 10):
            x = sin(radians(i)) * RAD1
            z = cos(radians(i)) * RAD1
            verts.append([(HEAD_RADIUS - RAD1) + x, 0.0, (0.0 - RAD1) + z])
    
            Row += 1
    
        verts.append([SHANK_RADIUS, 0.0, 0.0 - HEIGHT])
    
        Row += 1
    
    
        sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
        sVerts.extend(verts)    # add the start verts to the Spin verts to complete the loop
    
        faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
    
        return sVerts, faces, HEIGHT
    
    def Create_Cap_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, DIV_COUNT):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        HOLE_RADIUS = HOLE_DIA * 0.5
        HEAD_RADIUS = HEAD_DIA * 0.5
        SHANK_RADIUS = SHANK_DIA * 0.5
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        verts = []
        faces = []
        Row = 0
        BEVEL = HEIGHT * 0.01
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        FaceStart = len(verts)
    
    
        verts.append([HOLE_RADIUS, 0.0, 0.0])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
    
        # rad
        for i in range(0, 100, 10):
            x = sin(radians(i)) * RAD1
            z = cos(radians(i)) * RAD1
            verts.append([(HEAD_RADIUS - RAD1) + x, 0.0, (0.0 - RAD1) + z])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            Row += 1
    
        verts.append([HEAD_RADIUS, 0.0, 0.0 - HEIGHT + BEVEL])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
    
        verts.append([HEAD_RADIUS - BEVEL, 0.0, 0.0 - HEIGHT])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
    
        # rad2
        for i in range(0, 100, 10):
            x = sin(radians(i)) * RAD2
            z = cos(radians(i)) * RAD2
            verts.append([(SHANK_RADIUS + RAD2) - x, 0.0, (0.0 - HEIGHT - RAD2) + z])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
            Row += 1
    
        sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
        sVerts.extend(verts)    # add the start verts to the Spin verts to complete the loop
    
        faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
    
        return sVerts, faces, HEIGHT + RAD2
    
    def Create_Hex_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT):
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        verts = []
        faces = []
        HOLE_RADIUS = HOLE_DIA * 0.5
    
        Half_Flat = FLAT / 2
        TopBevelRadius = Half_Flat - (Half_Flat * (0.05 / 8))
        Undercut_Height = (Half_Flat * (0.05 / 8))
        Shank_Bevel = (Half_Flat * (0.05 / 8))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel
    
        # Undercut_Height = 5
        SHANK_RADIUS = SHANK_DIA / 2
        Row = 0
    
        verts.append([0.0, 0.0, 0.0])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        FaceStart = len(verts)
    
        # inner hole
        x = sin(radians(0)) * HOLE_RADIUS
        y = cos(radians(0)) * HOLE_RADIUS
        verts.append([x, y, 0.0])
    
        x = sin(radians(60 / 6)) * HOLE_RADIUS
        y = cos(radians(60 / 6)) * HOLE_RADIUS
        verts.append([x, y, 0.0])
    
        x = sin(radians(60 / 3)) * HOLE_RADIUS
        y = cos(radians(60 / 3)) * HOLE_RADIUS
        verts.append([x, y, 0.0])
    
        x = sin(radians(60 / 2)) * HOLE_RADIUS
        y = cos(radians(60 / 2)) * HOLE_RADIUS
        verts.append([x, y, 0.0])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
        # bevel
        x = sin(radians(0)) * TopBevelRadius
        y = cos(radians(0)) * TopBevelRadius
        vec1 = Vector([x, y, 0.0])
        verts.append([x, y, 0.0])
    
        x = sin(radians(60 / 6)) * TopBevelRadius
        y = cos(radians(60 / 6)) * TopBevelRadius
        vec2 = Vector([x, y, 0.0])
        verts.append([x, y, 0.0])
    
        x = sin(radians(60 / 3)) * TopBevelRadius
        y = cos(radians(60 / 3)) * TopBevelRadius
        vec3 = Vector([x, y, 0.0])
        verts.append([x, y, 0.0])
    
        x = sin(radians(60 / 2)) * TopBevelRadius
        y = cos(radians(60 / 2)) * TopBevelRadius
        vec4 = Vector([x, y, 0.0])
        verts.append([x, y, 0.0])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
        # Flats
        x = tan(radians(0)) * Half_Flat
        dvec = vec1 - Vector([x, Half_Flat, 0.0])
        verts.append([x, Half_Flat, -dvec.length])
    
        x = tan(radians(60 / 6)) * Half_Flat
        dvec = vec2 - Vector([x, Half_Flat, 0.0])
        verts.append([x, Half_Flat, -dvec.length])
    
        x = tan(radians(60 / 3)) * Half_Flat
        dvec = vec3 - Vector([x, Half_Flat, 0.0])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Lowest_Point = -dvec.length
    
        verts.append([x, Half_Flat, -dvec.length])
    
        x = tan(radians(60 / 2)) * Half_Flat
        dvec = vec4 - Vector([x, Half_Flat, 0.0])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Lowest_Point = -dvec.length
    
        verts.append([x, Half_Flat, -dvec.length])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
        # down Bits Tri
        x = tan(radians(0)) * Half_Flat
        verts.append([x, Half_Flat, Lowest_Point])
    
        x = tan(radians(60 / 6)) * Half_Flat
        verts.append([x, Half_Flat, Lowest_Point])
    
        x = tan(radians(60 / 3)) * Half_Flat
        verts.append([x, Half_Flat, Lowest_Point])
    
        x = tan(radians(60 / 2)) * Half_Flat
        verts.append([x, Half_Flat, Lowest_Point])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
    
        x = tan(radians(0)) * Half_Flat
        verts.append([x, Half_Flat, -Flat_Height])
    
        x = tan(radians(60 / 6)) * Half_Flat
        verts.append([x, Half_Flat, -Flat_Height])
    
        x = tan(radians(60 / 3)) * Half_Flat
        verts.append([x, Half_Flat, -Flat_Height])
    
        x = tan(radians(60 / 2)) * Half_Flat
        verts.append([x, Half_Flat, -Flat_Height])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
        # Under cut
        x = sin(radians(0)) * Half_Flat
        y = cos(radians(0)) * Half_Flat
        vec1 = Vector([x, y, 0.0])
        verts.append([x, y, -Flat_Height])
    
        x = sin(radians(60 / 6)) * Half_Flat
        y = cos(radians(60 / 6)) * Half_Flat
        vec2 = Vector([x, y, 0.0])
        verts.append([x, y, -Flat_Height])
    
        x = sin(radians(60 / 3)) * Half_Flat
        y = cos(radians(60 / 3)) * Half_Flat
        vec3 = Vector([x, y, 0.0])
        verts.append([x, y, -Flat_Height])
    
        x = sin(radians(60 / 2)) * Half_Flat
        y = cos(radians(60 / 2)) * Half_Flat
        vec3 = Vector([x, y, 0.0])
        verts.append([x, y, -Flat_Height])
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Row += 1
    
        # Under cut down bit
        x = sin(radians(0)) * Half_Flat