Skip to content
Snippets Groups Projects
createMesh.py 65.6 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
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    try: 
    
        import mathutils as MATHUTILS
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    except:
    
        import Mathutils as MATHUTILS
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    
    
    from math import *
    from itertools import * 
    
    NARROW_UI = 180
    MAX_INPUT_NUMBER = 50
    
    #Global_Scale = 0.001    #1 blender unit = X mm
    GLOBAL_SCALE = 0.1    #1 blender unit = X mm
    #Global_Scale = 1.0    #1 blender unit = X mm
    
    
    
    
    # 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
    
    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)
                
            l.extend(face)
    
        return l
    
    '''
    Remove Doubles takes a list on Verts and a list of Faces and
    removes the doubles, much like Blender does in edit mode.
    It doesn’t have the range function  but it will round the corrdinates
    and remove verts that are very close togther.  The function
    is useful because you can perform a “Remove Doubles” with out
    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 = []
            
            for v in 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):
        Ret_verts = []
        for v in verts:
            Ret_verts.append([v[0]*scale_factor,v[1]*scale_factor,v[2]*scale_factor])
        return Ret_verts
    
    
    
    
    
    #Create a matrix representing a rotation.
    #
    #Parameters:
    #
    #        * 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.
    #    A new rotation matrix. 
    def Simple_RotationMatrix(angle, matSize, axisFlag):
        if matSize != 4 :
            print ("Simple_RotationMatrix can only do 4x4")
            
        q = radians(angle)  #make the rotation go clockwise
        
        if axisFlag == 'x':
    
            matrix = MATHUTILS.Matrix(((1,0,0,0),(0,cos(q),sin(q),0),(0,-sin(q),cos(q),0),(0,0,0,1)))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        elif  axisFlag == 'y':
    
            matrix = MATHUTILS.Matrix(((cos(q),0,-sin(q),0),(0,1,0,0),(sin(q),0,cos(q),0),(0,0,0,1)))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        elif axisFlag == 'z':
    
            matrix = MATHUTILS.Matrix(((cos(q),sin(q),0,0),(-sin(q),cos(q),0,0),(0,0,1,0),(0,0,0,1)))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        else:
            print   ("Simple_RotationMatrix can only do x y z axis")
        return matrix
    
    
    ##########################################################################################
    ##########################################################################################
    ##                    Converter Functions For Bolt Factory 
    ##########################################################################################
    ##########################################################################################
    
    
    def Flat_To_Radius(FLAT):
        h = (float(FLAT)/2)/cos(radians(30))
        return h
    
    def Get_Phillips_Bit_Height(Bit_Dia):
        Flat_Width_half = (Bit_Dia*(0.5/1.82))/2.0
        Bit_Rad = Bit_Dia / 2.0
        x = Bit_Rad - Flat_Width_half
        y = tan(radians(60))*x
        return float(y) 
    
    
    ##########################################################################################
    ##########################################################################################
    ##                    Miscellaneous Utilities
    ##########################################################################################
    ##########################################################################################
    
    # Returns a list of verts rotated by the given matrix. Used by SpinDup
    
    def Rot_Mesh(verts, matrix):
        Vector = MATHUTILS.Vector
        return [(matrix * Vector(v))[:] for v in verts]
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    # 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]
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
    
    # Much like Blenders built in SpinDup.
    def SpinDup(VERTS,FACES,DEGREE,DIVISIONS,AXIS):
        verts=[]
        faces=[]
        
        if DIVISIONS == 0:
           DIVISIONS = 1  
      
        step = DEGREE/DIVISIONS # set step so pieces * step = degrees in arc
        
        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)))    
            verts.extend(Rot)
        return verts,faces
    
    
    
    # Returns a list of verts that have been moved up the z axis by DISTANCE
    def Move_Verts_Up_Z(VERTS,DISTANCE):        
        ret = []
        for v in VERTS:
            ret.append([v[0],v[1],v[2]+DISTANCE])
        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):
        ret_vert = []
        ret_face = []
        offset = len(VERTS)    
        if AXIS == 'y':
            for v in VERTS:
                Delta = v[0] - FLIP_POINT
                ret_vert.append([FLIP_POINT-Delta,v[1],v[2]]) 
        if AXIS == 'x':
            for v in VERTS:
                Delta = v[1] - FLIP_POINT
                ret_vert.append([v[0],FLIP_POINT-Delta,v[2]]) 
        if AXIS == 'z':
            for v in VERTS:
                Delta = v[2] - FLIP_POINT
                ret_vert.append([v[0],v[1],FLIP_POINT-Delta]) 
                
        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
            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,COLUM,ROW,FLIP = 0):
        Ret =[]
        RowStart = 0;
        for j in range(ROW):
            for i in range(COLUM):
                Res1 = RowStart + i;
                Res2 = RowStart + i + (COLUM +1)
                Res3 = RowStart + i + (COLUM +1) +1
                Res4 = RowStart+i+1
                if FLIP:
                    Ret.append([OFFSET+Res1,OFFSET+Res2,OFFSET+Res3,OFFSET+Res4])
                else:
                    Ret.append([OFFSET+Res4,OFFSET+Res3,OFFSET+Res2,OFFSET+Res1])
            RowStart += COLUM+1
        return Ret
    
    
    # Returns a list of faces that makes up a fill pattern for a 
    # 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];
                if FACE_DOWN:
                    Ret.append([OFFSET+Face[2],OFFSET+Face[1],OFFSET+Face[0]])
                else:
                    Ret.append([OFFSET+Face[0],OFFSET+Face[1],OFFSET+Face[2]])
            else:
                TempFace[0] =Face[C];
                if Face[C] == 0:
                    TempFace[1] = NUM-1; 
                else:
                    TempFace[1] = Face[C] - 1;
                TempFace[2] = Face[B];
                if FACE_DOWN:
                    Ret.append([OFFSET+Face[0],OFFSET+Face[1],OFFSET+Face[2]])
                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):
        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]
                  ]
        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
    
    def Allen_Bit_Dia(FLAT_DISTANCE):
        Flat_Radius = (float(FLAT_DISTANCE)/2.0)/cos(radians(30))
        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):
        Div = 36
        verts = []
        faces = []
        
        Flat_Radius = (float(FLAT_DISTANCE)/2.0)/cos(radians(30))
        OUTTER_RADIUS = Flat_Radius * 1.05
        Outter_Radius_Height = Flat_Radius * (0.1/5.77)
        FaceStart_Outside = len(verts)
        Deg_Step = 360.0 /float(Div)
        
        for i in range(int(Div/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])
        
        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))
        
        
        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')
        verts.extend(M_Verts)
        faces.extend(M_Faces)
        
        return verts,faces,OUTTER_RADIUS * 2.0
    
    
    ##########################################################################################
    ##########################################################################################
    ##                    Create Phillips Bit
    ##########################################################################################
    ##########################################################################################
    
    
    def Phillips_Fill(OFFSET,FLIP= 0):
        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]
                  
                  
                  ]
        for i in Lookup:
            if FLIP:
                if len(i) == 3:
                    faces.append([OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]])
                else:    
                    faces.append([OFFSET+i[3],OFFSET+i[2],OFFSET+i[1],OFFSET+i[0]])
            else:
                if len(i) == 3:
                    faces.append([OFFSET+i[0],OFFSET+i[1],OFFSET+i[2]])
                else:
                    faces.append([OFFSET+i[0],OFFSET+i[1],OFFSET+i[2],OFFSET+i[3]])
        return faces
    
    
    
    def Create_Phillips_Bit(FLAT_DIA,FLAT_WIDTH,HEIGHT):
        Div = 36
        verts = []
        faces = []
        
        FLAT_RADIUS = FLAT_DIA * 0.5
        OUTTER_RADIUS = FLAT_RADIUS * 1.05
        
        Flat_Half = float(FLAT_WIDTH)/2.0
            
        FaceStart_Outside = len(verts)
        Deg_Step = 360.0 /float(Div)
        for i in range(int(Div/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])
        
            
    
    Campbell Barton's avatar
    Campbell Barton committed
        # FaceStart_Inside = len(verts)  # UNUSED
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        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
    ##########################################################################################
    ##########################################################################################
    
    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 = 36
        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
        
        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)
        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])
            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])
            else:
                verts.append([(HEAD_RADIUS -EndRad)+x,0.0,(0.0 - EndZOffset)+z])
            Row += 1
            
            
        verts.append([SHANK_RADIUS,0.0,(0.0-HEIGHT)])
        Row += 1
        
        verts.append([SHANK_RADIUS,0.0,(0.0-HEIGHT)-Start_Height])
        Row += 1
    
    
        sVerts,sFaces = SpinDup(verts,faces,360,DIV,'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))
    
    Campbell Barton's avatar
    Campbell Barton committed
        # Global_Head_Height = HEIGHT  # UNUSED
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
        
        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 = 36
        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
        # BEVEL = HEIGHT * 0.01  # UNUSED
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        #Dome_Rad =  HEAD_RADIUS * (1.0/1.75)
        
        Dome_Rad =  HEAD_RADIUS * 1.12
        #Head_Height = HEAD_RADIUS * 0.78
        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
    #    
        
        FaceStart = FACE_OFFSET
        
        verts.append([HOLE_RADIUS,0.0,0.0])
        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])
                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])
            Row += 1
            
        verts.append([SHANK_RADIUS,0.0,(0.0-Dome_Height)])
        Row += 1
    
    
        sVerts,sFaces = SpinDup(verts,faces,360,DIV,'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))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    
        return sVerts,faces,Dome_Height
    
    
    
    
    def Create_CounterSink_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1):
        DIV = 36
        
        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)
        #print (RAD1)
        
        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,'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,1))
        
        return sVerts,faces,HEIGHT
    
    
    
    
    
    Brendon Murphy's avatar
    Brendon Murphy committed
    def Create_Cap_Head(HOLE_DIA,HEAD_DIA,SHANK_DIA,HEIGHT,RAD1,RAD2):
        DIV = 36
        
        HOLE_RADIUS = HOLE_DIA * 0.5
        HEAD_RADIUS = HEAD_DIA * 0.5
        SHANK_RADIUS = SHANK_DIA * 0.5
        
        verts = []
        faces = []
        Row = 0
        BEVEL = HEIGHT * 0.01
        
        
        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([HEAD_RADIUS,0.0,0.0-HEIGHT+BEVEL])
        Row += 1
    
        verts.append([HEAD_RADIUS-BEVEL,0.0,0.0-HEIGHT])
        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])
            Row += 1
        
    
        sVerts,sFaces = SpinDup(verts,faces,360,DIV,'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))
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        
        return sVerts,faces,HEIGHT+RAD2
    
    
    def Create_Hex_Head(FLAT,HOLE_DIA,SHANK_DIA,HEIGHT):
        
        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)) 
        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])
        
        
        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])
        Row += 1
        
        #bevel
        
        x = sin(radians(0))*TopBevelRadius
        y = cos(radians(0))*TopBevelRadius
        vec1 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,0.0])
        
        
        x = sin(radians(60/6))*TopBevelRadius
        y = cos(radians(60/6))*TopBevelRadius
        vec2 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,0.0])
        
        
        x = sin(radians(60/3))*TopBevelRadius
        y = cos(radians(60/3))*TopBevelRadius
        vec3 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,0.0])
        
        
        x = sin(radians(60/2))*TopBevelRadius
        y = cos(radians(60/2))*TopBevelRadius
        vec4 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,0.0])
        Row += 1
        
        #Flats
        
        x = tan(radians(0))*Half_Flat
        dvec = vec1 - MATHUTILS.Vector([x,Half_Flat,0.0])
        verts.append([x,Half_Flat,-dvec.length])
        
        
        x = tan(radians(60/6))*Half_Flat
        dvec = vec2 - MATHUTILS.Vector([x,Half_Flat,0.0])
        verts.append([x,Half_Flat,-dvec.length])
        
    
        x = tan(radians(60/3))*Half_Flat
        dvec = vec3 - MATHUTILS.Vector([x,Half_Flat,0.0])
        Lowest_Point = -dvec.length
        verts.append([x,Half_Flat,-dvec.length])
        
    
        x = tan(radians(60/2))*Half_Flat
        dvec = vec4 - MATHUTILS.Vector([x,Half_Flat,0.0])
        Lowest_Point = -dvec.length
        verts.append([x,Half_Flat,-dvec.length])
        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])
        Row += 1
    
        #down Bits
        
        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])
        Row += 1
        
        
        #under cut 
           
        x = sin(radians(0))*Half_Flat
        y = cos(radians(0))*Half_Flat
        vec1 = MATHUTILS.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 = MATHUTILS.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 = MATHUTILS.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 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height])
        Row += 1
        
        #under cut down bit
        x = sin(radians(0))*Half_Flat
        y = cos(radians(0))*Half_Flat
        vec1 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height])
        
        x = sin(radians(60/6))*Half_Flat
        y = cos(radians(60/6))*Half_Flat
        vec2 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height])
        
        x = sin(radians(60/3))*Half_Flat
        y = cos(radians(60/3))*Half_Flat
        vec3 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height])
        
        x = sin(radians(60/2))*Half_Flat
        y = cos(radians(60/2))*Half_Flat
        vec3 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height])
        Row += 1
        
        #under cut to Shank BEVEAL
        x = sin(radians(0))*(SHANK_RADIUS+Shank_Bevel)
        y = cos(radians(0))*(SHANK_RADIUS+Shank_Bevel)
        vec1 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height])
        
        x = sin(radians(60/6))*(SHANK_RADIUS+Shank_Bevel)
        y = cos(radians(60/6))*(SHANK_RADIUS+Shank_Bevel)
        vec2 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height])
        
        x = sin(radians(60/3))*(SHANK_RADIUS+Shank_Bevel)
        y = cos(radians(60/3))*(SHANK_RADIUS+Shank_Bevel)
        vec3 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height])
        
        x = sin(radians(60/2))*(SHANK_RADIUS+Shank_Bevel)
        y = cos(radians(60/2))*(SHANK_RADIUS+Shank_Bevel)
        vec3 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height])
        Row += 1
        
        #under cut to Shank BEVEAL
        x = sin(radians(0))*SHANK_RADIUS
        y = cos(radians(0))*SHANK_RADIUS
        vec1 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel])
        
        x = sin(radians(60/6))*SHANK_RADIUS
        y = cos(radians(60/6))*SHANK_RADIUS
        vec2 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel])
        
        x = sin(radians(60/3))*SHANK_RADIUS
        y = cos(radians(60/3))*SHANK_RADIUS
        vec3 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel])
        
        x = sin(radians(60/2))*SHANK_RADIUS
        y = cos(radians(60/2))*SHANK_RADIUS
        vec3 = MATHUTILS.Vector([x,y,0.0])
        verts.append([x,y,-Flat_Height-Undercut_Height-Shank_Bevel])
        Row += 1
        
        
        #Global_Head_Height = 0 - (-HEIGHT-0.1)
        faces.extend(Build_Face_List_Quads(FaceStart,3,Row - 1))
           
        
        Mirror_Verts,Mirror_Faces = Mirror_Verts_Faces(verts,faces,'y')
        verts.extend(Mirror_Verts)
        faces.extend(Mirror_Faces)
        
        Spin_Verts,Spin_Faces = SpinDup(verts,faces,360,6,'z')
        
        
        return Spin_Verts,Spin_Faces,0 - (-HEIGHT)
       
    
    ##########################################################################################
    ##########################################################################################
    ##                    Create External Thread
    ##########################################################################################
    ##########################################################################################
    
    
    
    def Thread_Start3(verts,INNER_RADIUS,OUTTER_RADIUS,PITCH,DIV,CREST_PERCENT,ROOT_PERCENT,Height_Offset):
        
        
        Ret_Row = 0;
        
    
    Campbell Barton's avatar
    Campbell Barton committed
        # Half_Pitch = float(PITCH)/2  # UNUSED
    
    Brendon Murphy's avatar
    Brendon Murphy committed
        Height_Start = Height_Offset - PITCH
        Height_Step = float(PITCH)/float(DIV)
        Deg_Step = 360.0 /float(DIV)
        
        Crest_Height = float(PITCH) * float(CREST_PERCENT)/float(100)
        Root_Height = float(PITCH) * float(ROOT_PERCENT)/float(100)
        Root_to_Crest_Height = Crest_to_Root_Height = (float(PITCH) - (Crest_Height + Root_Height))/2.0
       
    #theard start
    
        Rank = float(OUTTER_RADIUS - INNER_RADIUS)/float(DIV)
        for j in range(4):
            
            for i in range(DIV+1):
                z = Height_Offset - (Height_Step*i) 
                if z > Height_Start:
                    z = Height_Start
                x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
                y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
                verts.append([x,y,z])
            Height_Offset -= Crest_Height
            Ret_Row += 1
        
            for i in range(DIV+1):
                z = Height_Offset - (Height_Step*i) 
                if z > Height_Start:
                    z = Height_Start
                
                x = sin(radians(i*Deg_Step))*OUTTER_RADIUS
                y = cos(radians(i*Deg_Step))*OUTTER_RADIUS
                verts.append([x,y,z ])
            Height_Offset -= Crest_to_Root_Height
            Ret_Row += 1