@Gijs wrote:
addBolt.py (10.7 KB)Attached is a working script that adds metric bolts (hex, flat head, socket allen, M3 - M8). I wrote this mainly as a coding exercise.
Would like to get some feedback from more experienced coders if the way i did this with classes is done properly or not. Suggestions for optimizing the structure of the code highly appreciated…
edit: would like to record last selected bolt options to change the defaults at next run…how?
If you have additional suggestions for improvement of the functionality that would be nice too.
show the code (or download the above .py file)
import rhinoscriptsyntax as rs from Rhino.ApplicationSettings import * import Rhino import math import scriptcontext as sc """ addBolt version 0.1 this script will add a bolt (named block) in Metric size to the rhino document Bolt must be oriented on a surface and can be aligned with a center point needed user input : metric size, length, bolt type, (center)point on (poly)surface to do: -rewrite Bolt creation in Rhino Common so that redraw can stay on for showing selected center point script written by Gijs de Zwart www.studiogijs.nl """ class Bolt(): def __init__(self,msize,length): diameter = { 'M3':3, 'M4':4, 'M5':5, 'M6':6, 'M8':8 } pitch = { 'M3':0.5, 'M4':0.7, 'M5':1, 'M6':1, 'M8':1.25 } self.diameter = diameter[msize] self.length = length self.pitch = pitch[msize] self.name = msize+"x"+str(length) class hexBolt(Bolt): def __init__(self, msize, length): Bolt.__init__(self, msize, length) head_width = { 'M3':5.5, 'M4':7, 'M5':8, 'M6':10, 'M8':13 } head_height = { 'M3':2.2, 'M4':3, 'M5':3.2, 'M6':4, 'M8':5.3 } self.head_width = head_width[msize] self.head_height = head_height[msize] self.name += "(DIN993)" class flatBolt(Bolt): def __init__(self,msize,length): Bolt.__init__(self, msize, length) head_width = { 'M3':6, 'M4':8, 'M5':10, 'M6':12, 'M8':16 } head_height = { 'M3':1.7, 'M4':2.3, 'M5':2.8, 'M6':3.3, 'M8':4.4 } hex_socket = { 'M3':2, 'M4':2.5, 'M5':3, 'M6':4, 'M8':5 } self.head_width = head_width[msize] self.head_height = head_height[msize] self.head_dheight= self.head_height-(self.head_width-self.diameter)/2 self.hex_socket = hex_socket[msize] self.name += "(DIN7991)" class DIN912Bolt(Bolt): def __init__(self,msize,length): Bolt.__init__(self, msize, length) head_width = { 'M3':5.5, 'M4':7, 'M5':8.5, 'M6':10, 'M8':13 } head_height = { 'M3':3, 'M4':4, 'M5':5, 'M6':6, 'M8':8 } hex_socket = { 'M3':2.5, 'M4':3, 'M5':4, 'M6':5, 'M8':6 } hex_socket_depth = { 'M3':1.3, 'M4':2, 'M5':2.5, 'M6':3, 'M8':3.5 } self.head_width = head_width[msize] self.head_height = head_height[msize] self.hex_socket = hex_socket[msize] self.hex_socket_depth = hex_socket_depth[msize] self.name += "(DIN912)" def cen(): #this function turns off all Osnaps except center Osnap cen = Rhino.ApplicationSettings.OsnapModes.Center Rhino.ApplicationSettings.ModelAidSettings.Osnap = True Rhino.ApplicationSettings.ModelAidSettings.OsnapModes = cen def CreateBolt(): #this function asks the user to choose a metric size, length and bolt type, #then creates the geometry for the bolt # **************************************** # ************ USER OPTIONS ********** # **************************************** #get metric size go1 = Rhino.Input.Custom.GetOption() go1.SetCommandPrompt("Select bolt size") msizes = ['M3','M4','M5','M6','M8'] go1.AddOptionList("Metric_size", msizes, 0) size = None if go1.Get() == Rhino.Input.GetResult.Option: size = msizes[go1.Option().CurrentListOptionIndex] if size == None: size = 'M3' #get length for the bolt go2 = Rhino.Input.Custom.GetOption() go2.SetCommandPrompt("Select bolt length") lengths=['12mm','16mm','20mm','25mm','30mm','40mm','50mm','60mm','70mm','80mm'] go2.AddOptionList("Bolt_Length", lengths, 0) length=None if go2.Get() == Rhino.Input.GetResult.Option: length = lengths[go2.Option().CurrentListOptionIndex] if length == None: length = '12mm' #convert length for further use length = int(length[:-2]) #get type of bolt go3=Rhino.Input.Custom.GetOption() go3.SetCommandPrompt("Select headstyle") headstyles=['hex_head','flat_head','socket_allen'] go3.AddOptionList("Bolt_Type", headstyles, 0) headstyle=None if go3.Get() == Rhino.Input.GetResult.Option: headstyle = headstyles[go3.Option().CurrentListOptionIndex] if headstyle == None: headstyle = 'hex_head' # ************************************************* # *********** CREATE THE BOLT GEOMETRY ************ # ************************************************* #add bolt to the rhino scene rs.EnableRedraw(False) if headstyle=='hex_head': #create a hex bolt object bolt = hexBolt(size, length) #creat the head radius = bolt.head_width/2/math.cos(math.pi/6)#calculate radius of circle that circumscribes the hexagon hexagon = rs.AddCircle([0,0,0],radius) rs.RebuildCurve(hexagon, 1, 6) head = rs.ExtrudeCurveStraight(hexagon, [0,0,0], [0,0,bolt.head_height]) rs.CapPlanarHoles(head) rs.DeleteObject(hexagon) #create threaded part thread = rs.AddCylinder([0,0,0],[0,0,-bolt.length],bolt.diameter/2) hexbolt = rs.BooleanUnion([head, thread])[0] rs.ObjectName(hexbolt, bolt.name) #add cosmetic thread turns=bolt.length/bolt.pitch spiral=rs.AddSpiral([0,0,0],[0,0,-bolt.length], bolt.pitch,turns,bolt.diameter/2, bolt.diameter/2) rs.ObjectName(spiral, bolt.name) #add objects to the scene rs.AddGroup(bolt.name) rs.AddObjectsToGroup([hexbolt, spiral], bolt.name) addBolt(bolt) if headstyle=='flat_head': #create a flat head bolt object and some helper points bolt = flatBolt(size,length) point1 = [0,0,0] point2 = [0,0,-bolt.head_height]#position of head end point3 = [0,0,-bolt.head_dheight]#position of edge start #create the hexagon socket radius = bolt.hex_socket/2/math.cos(math.pi/6)#calculate radius of circle that circumscribes the hexagon hexagon = rs.AddCircle(point2,radius) rs.RebuildCurve(hexagon, 1, 6) socket = rs.ExtrudeCurveStraight(hexagon, point2, point1) rs.CapPlanarHoles(socket) rs.DeleteObject(hexagon) #create the head circle1 = rs.AddCircle(point2,bolt.diameter/2) circle2 = rs.AddCircle(point3,bolt.head_width/2) edge = rs.AddCylinder(point3,point1,bolt.head_width/2) head = rs.AddLoftSrf([circle1, circle2], loft_type=0) rs.CapPlanarHoles(head) rs.DeleteObjects([circle1, circle2]) #create threaded part thread = rs.AddCylinder(point2,[0,0,-bolt.length],bolt.diameter/2) flatbolt = rs.BooleanUnion([head, thread, edge])[0] flatbolt = rs.BooleanDifference(flatbolt, socket) rs.ObjectName(flatbolt, bolt.name) #add cosmetic thread turns = (bolt.length-bolt.head_height)/bolt.pitch spiral = rs.AddSpiral([0,0,-bolt.head_height],[0,0,-bolt.length], bolt.pitch,turns,bolt.diameter/2, bolt.diameter/2) rs.ObjectName(spiral, bolt.name) rs.AddGroup(bolt.name) rs.AddObjectsToGroup([flatbolt, spiral], bolt.name) #add objects to the scene addBolt(bolt) if headstyle=='socket_allen': #create a flat head bolt object and some helper points bolt = DIN912Bolt(size,length) point1 = [0,0,0] point2 = [0,0,bolt.head_height]#position of head end point3 = [0,0,(bolt.head_height-bolt.hex_socket_depth)] #create the hexagon socket radius = bolt.hex_socket/2/math.cos(math.pi/6)#calculate radius of circle that circumscribes the hexagon hexagon = rs.AddCircle(point2,radius) rs.RebuildCurve(hexagon, 1, 6) socket = rs.ExtrudeCurveStraight(hexagon, point3, point1) rs.CapPlanarHoles(socket) rs.DeleteObject(hexagon) #create the head head = rs.AddCylinder(point1,point2,bolt.head_width/2,True) #create threaded part thread = rs.AddCylinder(point2,[0,0,-bolt.length],bolt.diameter/2) din912bolt = rs.BooleanUnion([head, thread])[0] din912bolt = rs.BooleanDifference(din912bolt, socket) rs.ObjectName(din912bolt, bolt.name) #add cosmetic thread turns = bolt.length/bolt.pitch spiral = rs.AddSpiral(point1,[0,0,-bolt.length], bolt.pitch,turns,bolt.diameter/2, bolt.diameter/2) rs.ObjectName(spiral, bolt.name) #add objects to the scene rs.AddGroup(bolt.name) rs.AddObjectsToGroup([din912bolt, spiral], bolt.name) addBolt(bolt) rs.EnableRedraw(True) def addBolt(bolt): # this function ask the user to select a point on a surface to insert the bolt on # Surface to orient on gs = Rhino.Input.Custom.GetObject() gs.SetCommandPrompt("Surface to orient on") gs.GeometryFilter = Rhino.DocObjects.ObjectType.Surface gs.SubObjectSelect = True gs.DeselectAllBeforePostSelect = False gs.OneByOnePostSelect = True gs.Get() if gs.CommandResult()!=Rhino.Commands.Result.Success: objs=rs.ObjectsByGroup(bolt.name) rs.DeleteObjects(objs) return gs.CommandResult() objref = gs.Object(0) # get selected surface object obj = objref.Object() if not obj: return Rhino.Commands.Result.Failure # get selected surface (face) surface = objref.Surface() if not surface: return Rhino.Commands.Result.Failure # Unselect surface obj.Select(False) # Point on surface to orient to / activate center Osnap old_osnap_state = ModelAidSettings.OsnapModes #record Osnap state to reset later cen() gp=Rhino.Input.Custom.GetPoint() gp.SetCommandPrompt("Point on surface to orient to") gp.Constrain(surface, False) gp.Get() if gp.CommandResult()!=Rhino.Commands.Result.Success: ModelAidSettings.OsnapModes = old_osnap_state #reset to previous Osnap state return gp.CommandResult() rc = Rhino.Commands.Result.Failure getrc, u, v = surface.ClosestPoint(gp.Point()) if getrc: getrc, target_plane = surface.FrameAt(u,v) if getrc: # Build transformation source_plane = Rhino.Geometry.Plane.WorldXY xform = Rhino.Geometry.Transform.PlaneToPlane(source_plane, target_plane) # Do the transformation objs=rs.ObjectsByGroup(bolt.name) rs.AddBlock(objs,[0,0,0],bolt.name, True) newbolt = rs.InsertBlock2(bolt.name, xform) rs.ObjectName(newbolt, bolt.name) ModelAidSettings.OsnapModes = old_osnap_state #reset to previous Osnap state rc = Rhino.Commands.Result.Success return rc CreateBolt()
Posts: 3
Participants: 2
