macro pour poulie GT2

Forum destiné aux questions et discussions en français
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
mario52
Veteran
Posts: 4692
Joined: Wed May 16, 2012 2:13 pm

Re: macro pour poulie GT2

Post by mario52 »

Bonjour
pour cette partie ?

Code: Select all

   aa = doc.addObject("PartDesign::Pad","Pad")
   aa.Sketch = App.activeDocument().Sketch
juste placé la fonction dans une variable c'est plus intéressant et facile à travailler on peut ainsi donner un nom à chaque commade
et "App.activeDocument()" peut être remplacé par:

Code: Select all

#### ajout 2##################################
   doc = FreeCAD.ActiveDocument
#### ajout 2##################################
on aurait alors:

Code: Select all

   aa = doc.addObject("PartDesign::Pad","Pad")
   aa.Sketch = doc.Sketch
(comme pour la ligne du dessus)

mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
User avatar
blonblon
Posts: 253
Joined: Sat Sep 24, 2016 6:06 pm
Location: Uzes (Gard), France

Re: macro pour poulie GT2

Post by blonblon »

Merci Mario52

Ca ressemble un peu au Delphi une commande peu etre mise dans une variable cela donne un code moins touffu
User avatar
eaguirre
Posts: 9
Joined: Tue Apr 23, 2019 3:03 am
Location: Montréal, QC. Canada

Re: macro pour poulie GT2

Post by eaguirre »

[Nouvelle version 1.2 ]
- GT5 ajouté
- Ça marche avec Freecad 0.18
- Maintenant on peut ajouter des cylindres en bas et haut pour empecher le courroie de distribution (timing belt) d'échapper.
_____________________________________________
Après beaucoup de recherche dans la web, je n'ai trouvé pas une autre macro pour générer
des poulies GT2 , GT3 et GT5 que le tienne. Mais comme c'était un WIP (work in progress) j'ai décidé de
faire mon propre macro.

Donc voici ma version. Ca marche bien et vous pouvez générer des poulies GT2 et GT3 de 5 a 360 dents.
(le diametre de la poulie est donne par le calcule suivante: (No. de dents * pitch)/3.14159265

Bonne continuation!

Code: Select all

# -*- coding: utf-8 -*-

# ---------------------------------------------------------------------------------------
# 						Copyright (c) 2019 - Emilio Aguirre
# ---------------------------------------------------------------------------------------                                                                                               
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights 
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLEFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
# USE OR OTHER DEALINGS IN THE SOFTWARE.    
# ---------------------------------------------------------------------------------------
  
__title__   = "GT2/GT3/GT5 Timing Gear Creator"
__author__  = "eaguirre"
__version__ = "1.2"
__date__    = "25/04/2019"
__url__     = "http://www.emilioaguirre.com"
__Comment__ = "GT2/GT3/GT5 Gear Creator Macro (any gear size from 5 to 360 teeth)"
__Communication__ = "info@emilioaguirre.com"

import math
import Part
import sys
import time
import FreeCAD, FreeCADGui
import Sketcher, PartDesign
import ProfileLib.RegularPolygon
from FreeCAD import Base
from PySide import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)
# -----------------------------------
# QT Window Class
# -----------------------------------
class GTWnd(object):

	def __init__(self, MainWindow):
		self.shaft = True
		self.isCircle = True
		self.shaft_radius = 2.0
		self.hgear = 6.0
		self.base_height = 1.0
		self.base_radius = 6.37
		self.top_height = 1.0
		self.top_radius = 6.37
		self.addBase = False
		self.addTop = False
		self.max_radius_shaft = 100.0
		self.teeth = 20
		self.w = 300.0
		self.h = 320.0
		
		# UI Definition
		self.window = MainWindow
		MainWindow.setObjectName(_fromUtf8("MainWindow"))
		MainWindow.resize(self.w, self.h)
		self.central_wdgt = QtGui.QWidget(MainWindow)
		self.central_wdgt.setObjectName(_fromUtf8("centralWidget"))
		
		# UI Elements
		self.typeLbl = QtGui.QLabel(self.central_wdgt)
		self.typeLbl.setGeometry(QtCore.QRect(self.w*0.05, self.h*0.01, 150, 16))
		self.typeLbl.setObjectName("typeLbl")
		
		self.gt_type = QtGui.QComboBox(self.central_wdgt)
		self.gt_type.addItems(["GT2", "GT3", "GT5"])
		self.gt_type.setGeometry(QtCore.QRect(self.w*0.45, self.h*0.01, 95, 20))
		self.gt_type.setObjectName(_fromUtf8("gt_type"))
		self.gt_type.currentIndexChanged.connect(self.on_gt_type_change)

		self.teethLbl = QtGui.QLabel(self.central_wdgt)
		self.teethLbl.setGeometry(QtCore.QRect(self.w*0.05, self.h*0.09, 150, 16))
		self.teethLbl.setObjectName("teethLbl")
		
		self.num_teeth = QtGui.QSpinBox(self.central_wdgt)                       
		self.num_teeth.setGeometry(QtCore.QRect(self.w*0.45, self.h*0.09, 100, 22))
		self.num_teeth.setMinimum(5)
		self.num_teeth.setMaximum(360)
		self.num_teeth.setSingleStep(1)
		self.num_teeth.setValue(int(self.teeth))
		self.num_teeth.setObjectName(_fromUtf8("num_teeth"))
		self.num_teeth.valueChanged.connect(self.on_num_teeth_changed)

		self.rangeLbl = QtGui.QLabel(self.central_wdgt)
		self.rangeLbl.setGeometry(QtCore.QRect(self.w*0.80, self.h*0.09, 150, 16))
		self.rangeLbl.setObjectName("typeLbl")
		
		self.heightLbl = QtGui.QLabel(self.central_wdgt)
		self.heightLbl.setGeometry(QtCore.QRect(self.w*0.05, self.h*0.18, 150, 16))
		self.heightLbl.setObjectName("heightLbl")
		
		self.hgearear = QtGui.QDoubleSpinBox(self.central_wdgt)                       
		self.hgearear.setGeometry(QtCore.QRect(self.w*0.45, self.h*0.18, 100, 22))
		self.hgearear.setMinimum(0.01)
		self.hgearear.setMaximum(100.0)
		self.hgearear.setSingleStep(0.01)
		self.hgearear.setValue(float(self.hgear))
		self.hgearear.setObjectName(_fromUtf8("hgearear"))
		self.hgearear.valueChanged.connect(self.on_hgearear_valuechanged)
		
		self.mmLbl = QtGui.QLabel(self.central_wdgt)
		self.mmLbl.setGeometry(QtCore.QRect(self.w*0.80, self.h*0.18, 32, 16))
		self.mmLbl.setObjectName("mmLbl")

		# Shaft Information
		self.checkShaft = QtGui.QCheckBox("Shaft hole", self.central_wdgt)
		self.checkShaft.setGeometry(QtCore.QRect(self.w*0.05, self.h*0.27, 200, 25))                  
		self.checkShaft.setChecked(self.shaft)                                                 
		self.checkShaft.clicked.connect(self.on_checkShaft_clicked)

		self.radio_shaft = QtGui.QDoubleSpinBox(self.central_wdgt)                       
		self.radio_shaft.setGeometry(QtCore.QRect(self.w*0.45, self.h*0.27, 100, 22))                 
		self.radio_shaft.setMinimum(0.01)                                      
		self.radio_shaft.setMaximum(100.0)                                        
		self.radio_shaft.setSingleStep(0.01)
		self.radio_shaft.setValue(self.shaft_radius)                                        
		self.radio_shaft.setObjectName(_fromUtf8("radio_shaft"))                  
		self.radio_shaft.valueChanged.connect(self.on_radio_shaft_valuechanged)   
		
		self.mm2Lbl = QtGui.QLabel(self.central_wdgt)
		self.mm2Lbl.setGeometry(QtCore.QRect(self.w*0.8, self.h*0.27, 32, 16))
		self.mm2Lbl.setObjectName("mm2Lbl")
		
		self.radioCircle = QtGui.QRadioButton("Circle",self.central_wdgt)
		self.radioCircle.move(self.w*0.45, self.h*0.36)                  
		self.radioCircle.setChecked(self.isCircle)    
		self.radioCircle.clicked.connect(self.on_radioCircle_clicked)                    

		self.radioHex = QtGui.QRadioButton("Hexagon",self.central_wdgt)
		self.radioHex.move(self.w*0.7, self.h*0.36)                                 
		self.radioHex.setChecked(not self.isCircle) 
		self.radioHex.clicked.connect(self.on_radioHex_clicked)

		# Base information
		self.checkBase = QtGui.QCheckBox("Add base", self.central_wdgt)
		self.checkBase.move(self.w*0.05, self.h*0.45)                    
		self.checkBase.setChecked(self.addBase)                                                 
		self.checkBase.clicked.connect(self.on_checkBase_clicked)

		self.heightBaseLbl = QtGui.QLabel(self.central_wdgt)
		self.heightBaseLbl.setGeometry(QtCore.QRect(self.w*0.4, self.h*0.45, 32, 16))
		self.heightBaseLbl.setObjectName("heightBaseLbl")
		self.heightBaseLbl.hide()
		
		self.height_base = QtGui.QDoubleSpinBox(self.central_wdgt)                       
		self.height_base.setGeometry(QtCore.QRect(self.w*0.45, self.h*0.45, 100, 22))                 
		self.height_base.setMinimum(0.01)                                      
		self.height_base.setMaximum(100.0)                                        
		self.height_base.setSingleStep(0.5)
		self.height_base.setValue(self.base_height)                                        
		self.height_base.setObjectName(_fromUtf8("height_base"))                  
		self.height_base.valueChanged.connect(self.on_height_base_valuechanged)   
		self.height_base.hide()
		
		self.mm3Lbl = QtGui.QLabel(self.central_wdgt)
		self.mm3Lbl.setGeometry(QtCore.QRect(self.w*0.8, self.h*0.45, 32, 16))
		self.mm3Lbl.setObjectName("mm3Lbl")
		self.mm3Lbl.hide()
			
		self.radiusBaseLbl = QtGui.QLabel(self.central_wdgt)
		self.radiusBaseLbl.setGeometry(QtCore.QRect(self.w*0.4, self.h*0.54, 32, 16))
		self.radiusBaseLbl.setObjectName("radiusBaseLbl")
		self.radiusBaseLbl.hide()
		
		self.radius_base = QtGui.QDoubleSpinBox(self.central_wdgt)                       
		self.radius_base.setGeometry(QtCore.QRect(self.w*0.45, self.h*0.54, 100, 22))                 
		self.radius_base.setMinimum(self.shaft_radius)                                      
		self.radius_base.setMaximum(500.0)                                        
		self.radius_base.setSingleStep(0.5)
		self.radius_base.setValue(self.base_radius)                                        
		self.radius_base.setObjectName(_fromUtf8("radius_base"))                  
		self.radius_base.valueChanged.connect(self.on_radius_base_valuechanged)   
		self.radius_base.hide()
		
		self.mm4Lbl = QtGui.QLabel(self.central_wdgt)
		self.mm4Lbl.setGeometry(QtCore.QRect(self.w*0.8, self.h*0.54, 32, 16))
		self.mm4Lbl.setObjectName("mm4Lbl")
		self.mm4Lbl.hide()
		
		# Top information
		self.checkTop = QtGui.QCheckBox("Add top", self.central_wdgt)
		self.checkTop.move(self.w*0.05, self.h*0.7)                    
		self.checkTop.setChecked(self.addBase)                                                 
		self.checkTop.clicked.connect(self.on_checkTop_clicked)

		self.heightTopLbl = QtGui.QLabel(self.central_wdgt)
		self.heightTopLbl.setGeometry(QtCore.QRect(self.w*0.4, self.h*0.63, 32, 16))
		self.heightTopLbl.setObjectName("heightTopLbl")
		self.heightTopLbl.hide()
		
		self.height_top = QtGui.QDoubleSpinBox(self.central_wdgt)                       
		self.height_top.setGeometry(QtCore.QRect(self.w*0.45, self.h*0.63, 100, 22))                 
		self.height_top.setMinimum(0.01)                                      
		self.height_top.setMaximum(100.0)                                        
		self.height_top.setSingleStep(0.5)
		self.height_top.setValue(self.base_height)                                        
		self.height_top.setObjectName(_fromUtf8("height_top"))                  
		self.height_top.valueChanged.connect(self.on_height_top_valuechanged)   
		self.height_top.hide()
		
		self.mm5Lbl = QtGui.QLabel(self.central_wdgt)
		self.mm5Lbl.setGeometry(QtCore.QRect(self.w*0.8, self.h*0.63, 32, 16))
		self.mm5Lbl.setObjectName("mm5Lbl")
		self.mm5Lbl.hide()
			
		self.radiusTopLbl = QtGui.QLabel(self.central_wdgt)
		self.radiusTopLbl.setGeometry(QtCore.QRect(self.w*0.4, self.h*0.72, 32, 16))
		self.radiusTopLbl.setObjectName("radiusTopLbl")
		self.radiusTopLbl.hide()
		
		self.radius_top = QtGui.QDoubleSpinBox(self.central_wdgt)                       
		self.radius_top.setGeometry(QtCore.QRect(self.w*0.45, self.h*0.72, 100, 22))                 
		self.radius_top.setMinimum(self.shaft_radius)                                      
		self.radius_top.setMaximum(500.0)                                        
		self.radius_top.setSingleStep(0.5)
		self.radius_top.setValue(self.top_radius)                                        
		self.radius_top.setObjectName(_fromUtf8("radius_top"))                  
		self.radius_top.valueChanged.connect(self.on_radius_top_valuechanged)   
		self.radius_top.hide()
		
		self.mm6Lbl = QtGui.QLabel(self.central_wdgt)
		self.mm6Lbl.setGeometry(QtCore.QRect(self.w*0.8, self.h*0.72, 32, 16))
		self.mm6Lbl.setObjectName("mm6Lbl")
		self.mm6Lbl.hide()
		
		self.createBtn = QtGui.QPushButton(self.central_wdgt)
		self.createBtn.setGeometry(QtCore.QRect(self.w*0.65, self.h*0.81, 80, 28))
		self.createBtn.setObjectName(_fromUtf8("Create"))
		self.createBtn.clicked.connect(self.on_create_clicked)

		self.cancelBtn = QtGui.QPushButton(self.central_wdgt)
		self.cancelBtn.setGeometry(QtCore.QRect(self.w*0.2, self.h*0.81, 80, 28))
		self.cancelBtn.setObjectName(_fromUtf8("cancel"))
		self.cancelBtn.clicked.connect(self.on_cancel_clicked)
		
		# Set UI elements to window
		MainWindow.setCentralWidget(self.central_wdgt)
		
		# Set strings to UI
		self.retranslateUi(MainWindow)
		
		# -----------------------------------
		# Gear Data
		# pitch - distance between two teeth
		# u     - pitch differential. The radial distance between pitch diameter 
		#		  and pulley outer diameter is called pitch differential.
		# h     - Tooth height
		# H     - Belt height
		# r0	- Inner circle radius
		# r1    - Side circle radius that define the side of a tooth
		# rs    - Small circle radius that define the corner of a tooth
		# offset- Offset of the side circle center 
		# name  - Gear name
		# group - Type of Gear
		# -----------------------------------
		
		# GT2 Gear Data 
		self.gt2 = {'pitch':2.0,
			'u':0.254,
			'h':0.75,
			'H':1.38,
			'r0':0.555,
			'r1':1.0,
			'rs':0.15,
			'offset':0.40,
			'name':'GT2',
			'group':'GT'
			}
		# GT3 Gear Data
		self.gt3 = {'pitch':3.0,
			'u':0.381,
			'h':1.14,
			'H':2.40,
			'r0':0.85,
			'r1':1.52,
			'rs':0.25,
			'offset':0.61,
			'name':'GT3',
			'group':'GT'
			}
		# GT5 Gear Data
		self.gt5 = {'pitch':5.0,
			'u':0.5715,
			'h':1.93,
			'H':3.81,
			'r0':1.44,
			'r1':2.57,
			'rs':0.416,
			'offset':1.03,
			'name':'GT5',
			'group':'GT'
			}

	def polar(self, angle, radio, pt):
		"""
			Convert from polar coordinates (Theta, radius) to
			cartesian coordinates. The result is added to the
			given vector pt
		"""
		p = App.Vector(0,0,0)
		p[0] = pt[0] + (radio * math.cos(math.radians(angle)))
		p[1] = pt[1] + (radio * math.sin(math.radians(angle)))
		return p

	def get_middle_vector(self,v1, v2, m):
		"""
			Find the middle vector between two vectors. 
		"""
		return (v1 + v2).normalize() * m

	def gt_tooth(self, step, data):
		"""
			Calculate the coordinates of the GT tooth vertices.
			(the teeth of the gear, not the teeth of the timing belt)
			This calculates the right size of the previous tooth
			and the left side of the next tooth
		"""
		up = App.Vector(0,0,1)
		zero = App.Vector(0,0,0)
	
		r = (data['dr0'] - data['h']) + data['r0']	
		c0 = self.polar(step, r, zero)
		cm = self.polar(step, r - data['r0'], zero)
		pt = self.polar(step, data['dr0'],zero)
		ptn = pt.cross(up).normalize()
		ptd = App.Vector(pt).normalize() * -1
	
		pr = pt + (ptn * data['offset'])
		pl = pt + (ptn * -data['offset'])
		a = data['r1']/2
		b = a * math.sqrt(3)

		cl = pr + (ptn * -b) + (ptd * a)
		cl0 = pr + (ptn * -(data['r1']+data['rs'])) 
		cl1 = pr + (ptn * -data['r1']) + (ptd * data['rs'])
		ecl = cl0 + (ptd * data['rs'])
		cl2 = ecl + self.get_middle_vector(cl0 - ecl, cl1 - ecl, data['rs'])
		cl3 = pr + self.get_middle_vector(cl - pr, cl1 - pr, data['r1'])
	
		cr = pl + (ptn * b)  + (ptd * a)
		cr0 = pl + (ptn * (data['r1']+data['rs']))
		cr1 = pl + (ptn * data['r1']) + (ptd * data['rs'])
		ecr = cr0 + (ptd * data['rs'])
		cr2 = ecr + self.get_middle_vector(cr0 - ecr, cr1 - ecr, data['rs'])
		cr3 = pl + self.get_middle_vector(cr - pl, cr1 - pl, data['r1'])
		return [cr0, cr2, cr1, cr1, cr3, cr, cr, cm, cl, cl, cl3, cl1, cl1, cl2, cl0]

	def create_gear(self, doc, data):
		"""
			Create the geometry of the gear. Each tooth is a sequence of arcs 
			(3 points non coincidental vertices). 
		"""
		teeth = data['teeth']
		angle = 360.0/teeth
		gear = []
		for idx in range(teeth):
			step = angle * idx
			t = None
			if data['group'] == "GT":
				t = self.gt_tooth(step, data)
			else:
				raise Exception("Invalid group %s" % data['group'])	
			if len(gear)>0:
				doc.SketchGear.addGeometry(Part.LineSegment(gear[-1], t[0]))
			gear.extend(t)
			for idx in range(0,len(t)-1,3):
				doc.SketchGear.addGeometry(Part.ArcOfCircle(t[idx], t[idx+1], t[idx+2]))
		doc.SketchGear.addGeometry(Part.LineSegment(gear[-1], gear[0]))
		doc.recompute()
	
	def create(self, data):
		"""
			Creating the Freecad elements inside a new document
		"""
		progress_bar = Base.ProgressIndicator()
		progress_bar.start("Running creating  gear...", 0)

		FreeCAD.newDocument(data['name'])
		doc = FreeCAD.ActiveDocument

		App.activeDocument().addObject('PartDesign::Body','Gear')
		Gui.activeView().setActiveObject('pdbody', App.activeDocument().Gear)
		App.activeDocument().Gear.newObject('Sketcher::SketchObject','SketchGear')
		App.activeDocument().SketchGear.Support = (App.activeDocument().XY_Plane, [''])
		App.activeDocument().SketchGear.MapMode = 'FlatFace'
		App.activeDocument().SketchGear.Placement = App.Placement(
									App.Vector(0.000000,0.000000,0.000000),
									App.Rotation(0.000000,0.000000,0.000000,1.000000))
		App.activeDocument().recompute()
		
		self.create_gear(doc, data)
		
		if self.shaft:
			if self.isCircle:
				doc.SketchGear.addGeometry(Part.Circle(App.Vector(0,0,0),
							 App.Vector(0,0,1),
							 float(self.shaft_radius)))
			else:
				ProfileLib.RegularPolygon.makeRegularPolygon(
					'SketchGear',6,App.Vector(0.000000,0.000000,0),
					App.Vector(self.shaft_radius,0,0),False)
		
		Gui.activeView().setActiveObject('pdbody', App.activeDocument().Gear)
		App.activeDocument().Gear.newObject("PartDesign::Pad","Pad")
		App.activeDocument().Pad.Profile = App.activeDocument().SketchGear
		
		App.activeDocument().Pad.Profile = doc.SketchGear
		App.activeDocument().Pad.Length = float(self.hgear)
		App.activeDocument().recompute()
		Gui.activeDocument().hide("SketchGear")
		Gui.activeDocument().resetEdit()
		
		# Add base to the Gear
		if self.addBase:
			Gui.activeView().setActiveObject('pdbody', App.activeDocument().Gear)
			App.activeDocument().Gear.newObject('Sketcher::SketchObject','SketchBase')
			App.activeDocument().SketchBase.Support = (App.activeDocument().XY_Plane, [''])
			App.activeDocument().SketchBase.MapMode = 'FlatFace'
			App.activeDocument().SketchBase.Placement = App.Placement(
										App.Vector(0.000000,0.000000,0.000000),
										App.Rotation(0.000000,0.000000,0.000000,1.000000))
			App.activeDocument().recompute()
		
			doc.SketchBase.addGeometry(Part.Circle(App.Vector(0,0,-float(self.base_height)),
								 App.Vector(0,0,1),
								 self.base_radius))
			if self.shaft:
				if self.isCircle:
					doc.SketchBase.addGeometry(Part.Circle(App.Vector(0,0,0),
								 App.Vector(0,0,1),
								 float(self.shaft_radius)))
				else:
					ProfileLib.RegularPolygon.makeRegularPolygon(
						'SketchBase',6,App.Vector(0.000000,0.000000,0),
						App.Vector(self.shaft_radius,0,0),False)
						
			Gui.activeView().setActiveObject('pdbody', App.activeDocument().Gear)
			App.activeDocument().Gear.newObject("PartDesign::Pad","PadBase")
			App.activeDocument().PadBase.Profile = App.activeDocument().SketchBase
		
			App.activeDocument().PadBase.Profile = doc.SketchBase
			App.activeDocument().PadBase.Length = float(self.base_height)
			App.activeDocument().recompute()
			
			#TODO - Investigate how to take the correct edge 
			#App.activeDocument().Gear.newObject("PartDesign::Fillet","Fillet")
			#App.activeDocument().Fillet.Base = (App.ActiveDocument.PadBase,["Edge364"])
			#App.ActiveDocument.Fillet.Radius = 0.2
			#App.ActiveDocument.recompute()
		
			Gui.activeDocument().hide("SketchBase")
			Gui.activeDocument().resetEdit()
		
		# Add Top to the Gear
		if self.addTop:
			Gui.activeView().setActiveObject('pdbody', App.activeDocument().Gear)
			App.activeDocument().Gear.newObject('Sketcher::SketchObject','SketchTop')
			App.activeDocument().SketchTop.Support = (App.ActiveDocument.PadBase,["Face1"])
			App.activeDocument().SketchTop.MapMode = 'FlatFace'
			App.activeDocument().SketchTop.Placement = App.Placement(
										App.Vector(0.000000,0.000000,0),
										App.Rotation(0.000000,0.000000,0.000000,1.000000))
			App.activeDocument().recompute()
		
			doc.SketchTop.addGeometry(Part.Circle(App.Vector(0,0,float(self.hgear)),
								 App.Vector(0,0,1),
								 self.top_radius))
			if self.shaft:
				if self.isCircle:
					doc.SketchTop.addGeometry(Part.Circle(App.Vector(0,0,float(self.hgear)),
								 App.Vector(0,0,1),
								 float(self.shaft_radius)))
				else:
					ProfileLib.RegularPolygon.makeRegularPolygon(
						'SketchBase',6,App.Vector(0.000000,0.000000,float(self.hgear)),
						App.Vector(self.shaft_radius,0,0),False)
						
			Gui.activeView().setActiveObject('pdbody', App.activeDocument().Gear)
			App.activeDocument().Gear.newObject("PartDesign::Pad","PadTop")
			App.activeDocument().PadTop.Profile = App.activeDocument().SketchTop
		
			App.activeDocument().PadTop.Profile = doc.SketchTop
			App.activeDocument().PadTop.Length = float(self.top_height)
			App.activeDocument().recompute()
			
			#TODO - Investigate how to take the correct edge 
			#App.activeDocument().Gear.newObject("PartDesign::Fillet","Fillet")
			#App.activeDocument().Fillet.Base = (App.ActiveDocument.PadTop,["Edge484"])
			#App.ActiveDocument.Fillet.Radius = 0.2
			#App.ActiveDocument.recompute()

			Gui.activeDocument().hide("SketchTop")
			Gui.activeDocument().resetEdit()
			
		Gui.SendMsgToActiveView("ViewFit")
		progress_bar.stop()

		
	def retranslateUi(self, window):
		"""
			Setting the UI text
		"""
		window.setWindowTitle(_translate("MainWindow", "GT2/GT3/GT5 Gear Creator",
				 None))
		self.createBtn.setText(_translate("MainWindow", "Create", None))
		self.cancelBtn.setText(_translate("MainWindow", "Exit", None))
	
		self.teethLbl.setText(QtGui.QApplication.translate("MainWindow",
						 "No. of teeth:", None))
		self.heightLbl.setText(QtGui.QApplication.translate("MainWindow",
						 "Height gear:", None))
		self.typeLbl.setText(QtGui.QApplication.translate("MainWindow",
						 "Pick type of gear:", None))
		self.mmLbl.setText(QtGui.QApplication.translate("MainWindow",
						 "mm", None))
		self.mm2Lbl.setText(QtGui.QApplication.translate("MainWindow",
						 "mm", None))
		self.mm3Lbl.setText(QtGui.QApplication.translate("MainWindow",
						 "mm", None))
		self.mm4Lbl.setText(QtGui.QApplication.translate("MainWindow",
						 "mm", None))
		self.mm5Lbl.setText(QtGui.QApplication.translate("MainWindow",
						 "mm", None))
		self.mm6Lbl.setText(QtGui.QApplication.translate("MainWindow",
						 "mm", None))
		self.rangeLbl.setText(QtGui.QApplication.translate("MainWindow",
						 "(5 ~ 360)", None))
		self.checkShaft.setText(QtGui.QApplication.translate("MainWindow",
						 "Add shaft", None))
		self.radioHex.setText(QtGui.QApplication.translate("MainWindow",
						 "Hexagon", None))
		self.heightBaseLbl.setText(QtGui.QApplication.translate("MainWindow",
						 "H:", None))
		self.radiusBaseLbl.setText(QtGui.QApplication.translate("MainWindow",
						 "r:", None))
		self.heightTopLbl.setText(QtGui.QApplication.translate("MainWindow",
						 "H:", None))
		self.radiusTopLbl.setText(QtGui.QApplication.translate("MainWindow",
						 "r:", None))
	
	
	def update_max_radius_shaft(self):
		info = None					
		type_gear = str(self.gt_type.currentText())
		if type_gear== "GT2":
			info = dict(self.gt2)
		elif type_gear == "GT3":
			info = dict(self.gt3)
		else:
			info = dict(self.gt5)
		
		self.max_radius_shaft = ((self.teeth * info['pitch'])/ math.pi)/2
		self.radio_shaft.setMaximum(self.max_radius_shaft)  
		self.checkShaft.setText(QtGui.QApplication.translate("MainWindow",
						'Add shaft\r\n(max ' + 
						'{0:.2f}'.format(self.max_radius_shaft) + ' mm)',
						 None))
		self.radius_base.setValue(self.max_radius_shaft)     
		self.radius_top.setValue(self.max_radius_shaft)     
				 
		
	# -----------------------------------		
	# 		UI widgets callbacks
	# -----------------------------------
	def on_gt_type_change(self,idx):
		App.Console.PrintMessage("Current index %d selection changed %s\r\n" % 
				(idx,self.gt_type.currentText()))
		self.update_max_radius_shaft()
	
	def on_num_teeth_changed(self,value):
		App.Console.PrintMessage("%s Number of Teeths\r\n" % value)
		self.teeth = value
		self.update_max_radius_shaft()
	
	def errorDialog(self,msg):
		diag = QtGui.QMessageBox(QtGui.QMessageBox.Warning, 'Error in macro MessageBox',
								 msg)
		diag.setWindowModality(QtCore.Qt.ApplicationModal)
		diag.exec_()
    
	def on_create_clicked(self):
		if self.teeth>=5 and self.teeth<=360:
			App.Console.PrintMessage("Creating Gear %s \r\n" % self.gt_type.currentText())
			type_gear = str(self.gt_type.currentText())
			if type_gear== "GT2":
				data = dict(self.gt2)
			elif type_gear == "GT3":
				data = dict(self.gt3)
			else:
				data = dict(self.gt5)
			data['teeth'] = self.teeth
			data['d'] = (data['teeth'] * data['pitch'])/ math.pi
			data['d0'] = data['d'] - (2 * data['u'])
			data['dr0'] = data['d0']/2	
			App.Console.PrintMessage("pitch %s \r\n" % data['pitch'])
			App.Console.PrintMessage("teeth %s \r\n" % data['teeth'])
			App.Console.PrintMessage("u %s \r\n" % data['u'])
			App.Console.PrintMessage("d %s \r\n" % data['d'])
			App.Console.PrintMessage("d0 %s \r\n" % data['d0'])
			App.Console.PrintMessage("dr0 %s \r\n" % data['dr0'])
			self.create(data)	
		else:
			msg = 'The number of teeth should be between 5 and 360!'
			self.errorDialog(msg)
				
	def on_cancel_clicked(self):
		App.Console.PrintMessage("Exit Gear Generator\r\n")
		self.window.hide()

	def on_hgearear_valuechanged(self, value):
		App.Console.PrintMessage(str(value)+
									" height gear\r\n")
		self.hgear = value

	def on_radioCircle_clicked(self):
		self.isCircle = True
		
	def on_radioHex_clicked(self):
		self.isCircle = False
		
	def on_radio_shaft_valuechanged(self, value):
		App.Console.PrintMessage(str(value)+
									" Shaft radius\r\n")
		if value <= self.max_radius_shaft:
			self.shaft_radius = value
			self.radius_base.setMinimum(self.shaft_radius)
			if self.base_radius < self.shaft_radius:
				self.base_radius = self.shaft_radius
			
			self.radius_top.setMinimum(self.shaft_radius) 
			if self.top_radius < self.shaft_radius:
				self.top_radius = self.shaft_radius
		else:
			self.shaft_radius = max_radius
			msg = 'The shaft radius should be less than: %s' % max_radius
			self.errorDialog(msg)
		
	def on_height_base_valuechanged(self, value):
		App.Console.PrintMessage(str(value)+
									" Height base\r\n")
		self.base_height = value
		
	def on_radius_base_valuechanged(self, value):
		App.Console.PrintMessage(str(value)+
									" Radius base\r\n")
		self.base_radius = value
	
	def on_height_top_valuechanged(self, value):
		App.Console.PrintMessage(str(value)+
									" Height top\r\n")
		self.top_height = value
		
	def on_radius_top_valuechanged(self, value):
		App.Console.PrintMessage(str(value)+
									" Radius top\r\n")
		self.top_radius = value
		
	def on_checkShaft_clicked(self):
		self.shaft = not self.shaft
		if self.shaft:
			self.radioCircle.show()
			self.radioHex.show()
			self.radio_shaft.show()
			self.mm2Lbl.show()
		else:
			self.radioCircle.hide()
			self.radioHex.hide()
			self.radio_shaft.hide()
			self.mm2Lbl.hide()
	
	def on_checkBase_clicked(self):
		self.addBase = not self.addBase
		if self.addBase:
			self.height_base.show()
			self.radius_base.show()
			self.heightBaseLbl.show()
			self.radiusBaseLbl.show()
			self.mm3Lbl.show()
			self.mm4Lbl.show()
		else:
			self.height_base.hide()
			self.radius_base.hide()
			self.heightBaseLbl.hide()
			self.radiusBaseLbl.hide()
			self.mm3Lbl.hide()
			self.mm4Lbl.hide()
			
	def on_checkTop_clicked(self):
		self.addTop = not self.addTop
		if self.addTop:
			self.height_top.show()
			self.radius_top.show()
			self.heightTopLbl.show()
			self.radiusTopLbl.show()
			self.mm5Lbl.show()
			self.mm6Lbl.show()
		else:
			self.height_top.hide()
			self.radius_top.hide()
			self.heightTopLbl.hide()
			self.radiusTopLbl.hide()
			self.mm5Lbl.hide()
			self.mm6Lbl.hide()
# -----------------------------------
# Create and display the main window
# -----------------------------------
MainWindow = QtGui.QMainWindow()
ui = GTWnd(MainWindow)
MainWindow.show()

Last edited by eaguirre on Fri Apr 26, 2019 1:27 pm, edited 1 time in total.
User avatar
blonblon
Posts: 253
Joined: Sat Sep 24, 2016 6:06 pm
Location: Uzes (Gard), France

Re: macro pour poulie GT2

Post by blonblon »

Bonjour eaguirre

Merci pour le partage, je testerais ;)
User avatar
FaDa3D
Posts: 873
Joined: Tue Aug 08, 2017 8:21 am
Location: Savoie France

Re: macro pour poulie GT2

Post by FaDa3D »

Bonsoir,
Une autre façon de procéder pour modéliser une instance d'une famille de pièces (vocabulaire emprunté à un logiciel professionnel) est d'entrer les dimensions des instances en colonne dans une feuille de calcul. Une autre colonne -celle de l'instance courante- récolte les dimensions de l'instance choisie et sert de donnée de base à la construction du modèle. En cas de non choix, la colonne de l'instance courante récolte les données d'une instance générique afin que le modèle se construise sans échec.
Dans l'exemple ultra simple suivant, le choix se fait par introduction de 0 ou 1 dans la colonne de l'instance choisie. Mais on peut imaginer une macro qui le fasse plus ergonomiquement.
L'avantage est qu'une fois la feuille peaufinée et validée, elle peut servir pour n'importe quel modèle et on entre les valeurs qu'une fois. on peut même les importer d'une autre feuille de calcul extérieure.
A creuser.
Attachments
Famille1.FCStd
Exemple d'une famille de rondelles.
(11.03 KiB) Downloaded 55 times
Fada de 3D.
Linux Mint
joel
Posts: 195
Joined: Thu Jan 26, 2017 8:17 pm
Location: Thonon les Bains

Re: macro pour poulie GT2

Post by joel »

eaguirre wrote: Wed Apr 24, 2019 5:07 am Donc voici ma version. Ca marche bien et vous pouvez générer des poulies GT2 et GT3 de 5 a 360 dents.
(le diametre de la poulie est donne par le calcule suivante: (No. de dents * pitch)/3.14159265
La macro est super. Merci pour le partage
User avatar
eaguirre
Posts: 9
Joined: Tue Apr 23, 2019 3:03 am
Location: Montréal, QC. Canada

Re: macro pour poulie GT2

Post by eaguirre »

Je viens de modifier mon derniere "poste" avec un nouvelle version qui marche avec Freecad 0.18 avec plus d'options (GT5, cylindres en bas/haute pour empecher la courroie de distribution "timing belt" de bouger)
User avatar
meme2704
Veteran
Posts: 2926
Joined: Sat Apr 01, 2017 2:47 pm
Location: Vosges

Re: macro pour poulie GT2

Post by meme2704 »

J'ai passer de longues heures à chercher pourquoi le résultat ne correspondait pas à l'idée que je m'en faisais
c'est alors que je me suis souvenu avoir dans mon fourbit de chose inutile (tant qu'on a pas l'utilisation , la preuve :lol: ) une pompe à eau et la courroie de distribution récup de ma bagnole , c'est une GT10 et poulie de 20 dents,
et en 10mn ça collait (d'où l'inutilité d'une macro :?: )
et je me suis dit : si j'utilise l'outil "Involute gear" ça vat m'aider : le principe est le même MxP / pi = diamètre primitif , mais voilà , pourquoi , saperlipopète , faut-il que je choisisse un module de 3 pour que les diamètre primitif correspondent :?: :mrgreen:
ça défie mes vieux souvenir d'études technique et les vieux grimoires que je relis depuis plusieurs heures
Attachments
GT10belt.PNG
GT10belt.PNG (58.81 KiB) Viewed 1627 times
User avatar
blonblon
Posts: 253
Joined: Sat Sep 24, 2016 6:06 pm
Location: Uzes (Gard), France

Re: macro pour poulie GT2

Post by blonblon »

Bonjour meme2704

Je ne comprend pas ton histoire de pompe à eau et la courroie de distribution, surtout que cela est dans le seul but de nous dire (d'où l'inutilité d'une macro), tu n'a pas lu le titre du poste (macro pour poulie GT2), (Involute gear) est une macro qui n'est pas prévu pour les courroies GT3, GT3, M5, T5, ..., ou ta courroie de distribution, maintenant si tu a quelque chose de constructif au sujet des différentes macros proposées ne t'en prive pas tous les participants en seront ravis.

Cordialement :mrgreen:
User avatar
meme2704
Veteran
Posts: 2926
Joined: Sat Apr 01, 2017 2:47 pm
Location: Vosges

Re: macro pour poulie GT2

Post by meme2704 »

T'as raison, je retire cette remarque
Sinon, c'était pour dire qu'aillant un exemple concret sous les yeux, j'ai vérifié ne pas être dans l'erreur de tracé
Qu'en a la comparaison avec "Ivolute gear", si je compare le principe que m x nb de dents / pi = diamètre primitif avec p x nb de dents / pi = diamètre primitif de la poulie devrait me guider , mais ça marche pas
Post Reply