Gear.py

Go to the documentation of this file.
00001 #Involute Gears Generation Script
00002 #by Marcin Wanczyk (dj_who)
00003 #(c) 2011 LGPL
00004 
00005 
00006 import FreeCAD, FreeCADGui, Part, Draft, math, MeshPart, Mesh
00007 from PyQt4 import QtGui,QtCore
00008 App=FreeCAD
00009 Gui=FreeCADGui
00010 
00011 def proceed():    
00012     QtGui.qApp.setOverrideCursor(QtCore.Qt.WaitCursor)
00013    
00014     if FreeCAD.ActiveDocument==None:
00015         FreeCAD.newDocument("Gear")
00016 
00017     oldDocumentObjects=App.ActiveDocument.Objects
00018 
00019     try:
00020         N = int(l1.text())   
00021         p = float(l2.text())
00022         alfa = int(l3.text())
00023         y = float(l4.text())       #standard value y<1 for gear drives y>1 for Gear pumps
00024         m=p/math.pi                #standard value 0.06, 0.12, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 60 (polish norm)
00025         c = float(l5.text())*m     #standard value 0,1*m - 0,3*m
00026         j = float(l6.text())*m     #standard value 0,015 - 0,04*m
00027         width = float(l7.text())   #gear width           
00028     except:
00029         FreeCAD.Console.PrintError("Wrong input! Only numbers allowed...\n")
00030     
00031     
00032     #tooth hight
00033     h=2*y*m+c    
00034 
00035     #pitch diameter
00036     d=N*m
00037 
00038     #root diameter    
00039     df=d - 2*y*m - 2*c              #df=d-2hf where and hf=y*m+c 
00040 
00041     #addendum diameter    
00042     da=d + 2*y*m                    #da=d+2ha where ha=y*m    
00043 
00044     #base diameter for involute
00045     db=d * math.cos(math.radians(alfa))
00046 
00047 
00048     #Base circle
00049     baseCircle=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","BaseCircle")
00050     Draft.Circle(baseCircle)
00051     Draft.ViewProviderCircle(baseCircle.ViewObject)
00052     baseCircle.Radius = db/2
00053     baseCircle.FirstAngle=0.0
00054     baseCircle.LastAngle=0.0
00055     
00056     #Root circle
00057     rootCircle=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","RootCircle")
00058     Draft.Circle(rootCircle)
00059     Draft.ViewProviderCircle(rootCircle.ViewObject)
00060     rootCircle.Radius = df/2
00061     rootCircle.FirstAngle=0.0
00062     rootCircle.LastAngle=0.0
00063 
00064     #Addendum circle
00065     addendumCircle=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","AddendumCircle")
00066     Draft.Circle(addendumCircle)
00067     Draft.ViewProviderCircle(addendumCircle.ViewObject)
00068     addendumCircle.Radius = da/2
00069     addendumCircle.FirstAngle=0.0
00070     addendumCircle.LastAngle=0.0
00071 
00072     #Pitch circle
00073     pitchCircle=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","PitchCircle")
00074     Draft.Circle(pitchCircle)
00075     Draft.ViewProviderCircle(pitchCircle.ViewObject)
00076     pitchCircle.Radius = d/2
00077     pitchCircle.FirstAngle=0.0
00078     pitchCircle.LastAngle=0.0
00079 
00080 #************ Calculating right sides of teeth
00081     #Involute of base circle
00082     involute=[]
00083     involutee=[]
00084     involutesav=[]
00085 
00086     for t in range(0,60,1):
00087         x=db/2*(math.cos(math.radians(t))+math.radians(t)*math.sin(math.radians(t)))
00088         y=db/2*(math.sin(math.radians(t))-math.radians(t)*math.cos(math.radians(t)))    
00089         involute.append(Part.Vertex(x,y,0).Point)
00090 
00091 #************ Drawing rigth sides of teeth   
00092     involutesav.extend(involute)
00093     involutee.extend(involute)
00094 
00095     for angle in range(1,N+1,1):
00096         involuteobj = FreeCAD.ActiveDocument.addObject("Part::Feature","InvoluteL"+str(angle))
00097         involutee.insert(0,(0,0,0))        
00098         involuteshape = Part.makePolygon(involutee)        
00099         involuteobj.Shape=involuteshape
00100         involutee=[]
00101         for num in range(0,60,1):
00102             point=involute.pop()
00103             pointt=Part.Vertex(point.x*math.cos(math.radians(angle*360/N)) - point.y*math.sin(math.radians(angle*360/N)),point.x*math.sin(math.radians(angle*360/N)) + point.y*math.cos(math.radians(angle*360/N)),0).Point
00104             involutee.insert(0,pointt)
00105         involute.extend(involutesav)
00106     involutee=[]
00107     
00108 #************ Calculating difference between tooth spacing on BaseCircle and PitchCircle
00109 
00110     pc=App.ActiveDocument.getObject("PitchCircle")
00111     inv=App.ActiveDocument.getObject("InvoluteL1")
00112     cut=inv.Shape.cut(pc.Shape)
00113 #    FreeCAD.ActiveDocument.addObject("Part::Feature","CutInv").Shape=cut
00114     invPoint=cut.Vertexes[0].Point
00115 
00116 
00117     diff=invPoint.y*2        # instead of making axial symmetry and calculating point distance.
00118     anglediff=2*math.asin(diff/d)
00119 
00120 #************ Calculating left sides of teeth
00121 
00122 #************ Inversing Involute
00123     for num in range(0,60,1):
00124         point=involute.pop()
00125         pointt=Part.Vertex(point.x,point.y*-1,0).Point
00126         involutee.insert(0,pointt)
00127     involute.extend(involutee)
00128     involutee=[]
00129 
00130 #Normal tooth size calculated as: 0,5*  p    -      j                         j=m * 0,1 below are calculations
00131 #                                 0,5*  p    -      m      * 0,1
00132 #                                 0,5*  p    -     p   /pi * 0,1
00133 #                                 0,5*360/N  - ((360/N)/pi)* 0,1
00134 #                                 0,5*360/N  - (360/N)*((1/pi)*0,1)           j=(p/pi)*0,1
00135 #                                 0,5*360/N  - (360/N)*((p/pi)*0,1)/p
00136 #                                 0,5*360/N  - (360/N)*(    j     )/p
00137     for num in range(0,60,1):
00138         point=involute.pop()
00139         pointt=Part.Vertex(point.x*math.cos(math.radians(180/N-(360/N)*(j/p))+anglediff) - point.y*math.sin(math.radians(180/N-(360/N)*(j/p))+anglediff),point.x*math.sin(math.radians(180/N-(360/N)*(j/p))+anglediff) + point.y*math.cos(math.radians(180/N-(360/N)*(j/p))+anglediff),0).Point
00140         involutee.insert(0,pointt)
00141     involute.extend(involutee)
00142     involutesav=[]
00143     involutesav.extend(involute)
00144 
00145 #************ Drawing left sides of teeth
00146     for angle in range(1,N+1,1):
00147         involuteobj = FreeCAD.ActiveDocument.addObject("Part::Feature","InvoluteR"+str(angle))
00148         involutee.insert(0,(0,0,0))
00149         involuteshape = Part.makePolygon(involutee)
00150         involuteobj.Shape=involuteshape
00151         involutee=[]
00152         for num in range(0,60,1):
00153             point=involute.pop()
00154             pointt=Part.Vertex(point.x*math.cos(math.radians(angle*360/N)) - point.y*math.sin(math.radians(angle*360/N)),point.x*math.sin(math.radians(angle*360/N)) + point.y*math.cos(math.radians(angle*360/N)),0).Point
00155             involutee.insert(0,pointt)
00156         involute.extend(involutesav)
00157 
00158     Gui.SendMsgToActiveView("ViewFit")
00159 
00160 #************ Forming teeth
00161 
00162     cutCircle=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","CutCircle")
00163     Draft.Circle(cutCircle)
00164     Draft.ViewProviderCircle(cutCircle.ViewObject)
00165     cutCircle.Radius = da    # da because must be bigger than addendumCircle and bigger than whole construction da is right for this but it not has to be.       
00166     cutCircle.FirstAngle=0.0
00167     cutCircle.LastAngle=0.0
00168 
00169     
00170     cutTool=cutCircle.Shape.cut(addendumCircle.Shape)
00171     #cutshape=Part.show(cutTool)
00172     
00173     gearShape=rootCircle.Shape
00174 
00175     for invNum in range(1,N+1,1):      
00176         invL=App.ActiveDocument.getObject("InvoluteL"+str(invNum))
00177         invR=App.ActiveDocument.getObject("InvoluteR"+str(invNum))
00178         cutL=invL.Shape.cut(cutTool)
00179         cutR=invR.Shape.cut(cutTool)
00180         pointL=cutL.Vertexes.pop().Point
00181         pointR=cutR.Vertexes.pop().Point
00182         faceEdge=Part.makeLine(pointL,pointR)
00183         
00184         toothWhole=cutL.fuse(cutR)
00185         toothWhole=toothWhole.fuse(faceEdge)
00186         toothWire=Part.Wire(toothWhole.Edges)
00187         toothShape=Part.Face(toothWire)
00188 #        tooth=App.ActiveDocument.addObject("Part::Feature","Tooth"+str(invNum))
00189 #        tooth.Shape=toothShape
00190         gearShape=gearShape.fuse(toothShape)
00191 
00192 
00193     for o in App.ActiveDocument.Objects:
00194         if oldDocumentObjects.count(o)==0:
00195             App.ActiveDocument.removeObject(o.Name)
00196 
00197     gearFlat=App.ActiveDocument.addObject("Part::Feature","GearFlat")
00198     gearFlat.Shape=gearShape
00199     Gui.ActiveDocument.getObject(gearFlat.Name).Visibility=False
00200 
00201     gear=App.ActiveDocument.addObject("Part::Extrusion","Gear3D")
00202     gear.Base=gearFlat
00203     gear.Dir=(0,0,width)
00204     App.ActiveDocument.recompute()
00205 
00206     
00207     if c1.isChecked()==True:
00208         gearMesh=App.ActiveDocument.addObject("Mesh::Feature","Gear3D-mesh")
00209 
00210         faces = []
00211         triangles = gear.Shape.tessellate(1) # the number represents the precision of the tessellation)
00212         for tri in triangles[1]:
00213             face = []
00214             for i in range(3):
00215                 vindex = tri[i]
00216                 face.append(triangles[0][vindex])
00217             faces.append(face)
00218         mesh = Mesh.Mesh(faces)
00219 
00220         gearMesh.Mesh=mesh
00221         App.ActiveDocument.removeObject(gear.Name)
00222         App.ActiveDocument.removeObject(gearFlat.Name)
00223 
00224 
00225     App.ActiveDocument.recompute()
00226     Gui.SendMsgToActiveView("ViewFit")
00227     
00228     QtGui.qApp.restoreOverrideCursor()
00229  
00230 
00231     hide()
00232 
00233 def hide():
00234     dialog.hide()
00235 
00236 dialog = QtGui.QDialog()
00237 dialog.resize(200,450)
00238 dialog.setWindowTitle("Gear")
00239 la = QtGui.QVBoxLayout(dialog)
00240 t1 = QtGui.QLabel("Number of teeth (N)")
00241 la.addWidget(t1)
00242 l1 = QtGui.QLineEdit()
00243 l1.setText("16")
00244 la.addWidget(l1)
00245 t2 = QtGui.QLabel("Circular pitch (p)")
00246 la.addWidget(t2)
00247 l2 = QtGui.QLineEdit()
00248 l2.setText("1.65")
00249 la.addWidget(l2)
00250 t3 = QtGui.QLabel("Pressure angle (alfa)")
00251 la.addWidget(t3)
00252 l3 = QtGui.QLineEdit()
00253 l3.setText("20")
00254 la.addWidget(l3)
00255 t4 = QtGui.QLabel("Tooth hight factor (y)")   
00256 la.addWidget(t4)
00257 l4 = QtGui.QLineEdit()
00258 l4.setText("1.0")
00259 la.addWidget(l4)
00260 t5 = QtGui.QLabel("Tooth clearance (c)")   
00261 la.addWidget(t5)
00262 l5 = QtGui.QLineEdit()
00263 l5.setText("0.1")
00264 la.addWidget(l5)
00265 t6 = QtGui.QLabel("Tooth lateral clearance (j)")   
00266 la.addWidget(t6)
00267 l6 = QtGui.QLineEdit()
00268 l6.setText("0.04")
00269 la.addWidget(l6)
00270 t7 = QtGui.QLabel("Gear width")   
00271 la.addWidget(t7)
00272 l7 = QtGui.QLineEdit()
00273 l7.setText("6.0")
00274 la.addWidget(l7)
00275 c1 = QtGui.QCheckBox("Create as a Mesh")
00276 la.addWidget(c1)
00277 e1 = QtGui.QLabel("(for faster rendering)")
00278 commentFont=QtGui.QFont("Times",8,True)
00279 e1.setFont(commentFont)
00280 la.addWidget(e1)
00281 
00282 okbox = QtGui.QDialogButtonBox(dialog)
00283 okbox.setOrientation(QtCore.Qt.Horizontal)
00284 okbox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
00285 la.addWidget(okbox)
00286 QtCore.QObject.connect(okbox, QtCore.SIGNAL("accepted()"), proceed)
00287 QtCore.QObject.connect(okbox, QtCore.SIGNAL("rejected()"), hide)
00288 QtCore.QMetaObject.connectSlotsByName(dialog)
00289 dialog.show()

Generated on Wed Nov 23 19:00:15 2011 for FreeCAD by  doxygen 1.6.1