From 6d1d55dc1535bde73c685b6c44e26884eab7967f Mon Sep 17 00:00:00 2001 From: jriegel Date: Sun, 16 Feb 2014 22:19:39 +0100 Subject: [PATCH] Implement the python gear feature --- src/Mod/PartDesign/App/CMakeLists.txt | 7 + src/Mod/PartDesign/CMakeLists.txt | 2 + .../PartDesign/Gui/Resources/PartDesign.qrc | 1 + .../icons/PartDesign_InvoluteGear.svg | 10 + src/Mod/PartDesign/Gui/Workbench.cpp | 3 +- src/Mod/PartDesign/InitGui.py | 1 + src/Mod/PartDesign/InvoluteGearFeature.py | 192 ++++++++++++++++++ src/Mod/PartDesign/InvoluteGearFeature.ui | 160 +++++++++++++++ 8 files changed, 375 insertions(+), 1 deletion(-) create mode 100644 src/Mod/PartDesign/Gui/Resources/icons/PartDesign_InvoluteGear.svg create mode 100644 src/Mod/PartDesign/InvoluteGearFeature.py create mode 100644 src/Mod/PartDesign/InvoluteGearFeature.ui diff --git a/src/Mod/PartDesign/App/CMakeLists.txt b/src/Mod/PartDesign/App/CMakeLists.txt index e2783c49a..b6b17ff8b 100644 --- a/src/Mod/PartDesign/App/CMakeLists.txt +++ b/src/Mod/PartDesign/App/CMakeLists.txt @@ -101,6 +101,8 @@ SET(PartDesign_Scripts __init__.py Init.py TestPartDesignApp.py + InvoluteGearFeature.py + InvoluteGearFeature.ui Scripts/__init__.py Scripts/Gear.py Scripts/DistanceBolt.py @@ -108,6 +110,11 @@ SET(PartDesign_Scripts Scripts/RadialCopy.py Scripts/Parallelepiped.py Scripts/Spring.py + fcgear/__init__.py + fcgear/fcgear.py + fcgear/fcgeardialog.py + fcgear/involute.py + fcgear/svggear.py ) add_library(PartDesign SHARED ${PartDesign_SRCS}) diff --git a/src/Mod/PartDesign/CMakeLists.txt b/src/Mod/PartDesign/CMakeLists.txt index 9ad8c1d81..526755f72 100644 --- a/src/Mod/PartDesign/CMakeLists.txt +++ b/src/Mod/PartDesign/CMakeLists.txt @@ -11,6 +11,8 @@ INSTALL( InitGui.py TestPartDesignApp.py TestPartDesignGui.py + InvoluteGearFeature.py + InvoluteGearFeature.ui DESTINATION Mod/PartDesign ) diff --git a/src/Mod/PartDesign/Gui/Resources/PartDesign.qrc b/src/Mod/PartDesign/Gui/Resources/PartDesign.qrc index f8bfeae51..662de39d7 100644 --- a/src/Mod/PartDesign/Gui/Resources/PartDesign.qrc +++ b/src/Mod/PartDesign/Gui/Resources/PartDesign.qrc @@ -15,6 +15,7 @@ icons/PartDesign_Hole.svg icons/Tree_PartDesign_Pad.svg icons/Tree_PartDesign_Revolution.svg + icons/PartDesign_InvoluteGear.svg translations/PartDesign_af.qm translations/PartDesign_de.qm translations/PartDesign_fi.qm diff --git a/src/Mod/PartDesign/Gui/Resources/icons/PartDesign_InvoluteGear.svg b/src/Mod/PartDesign/Gui/Resources/icons/PartDesign_InvoluteGear.svg new file mode 100644 index 000000000..15f18113f --- /dev/null +++ b/src/Mod/PartDesign/Gui/Resources/icons/PartDesign_InvoluteGear.svg @@ -0,0 +1,10 @@ + + High Resolution Gear + image/svg+xml + + Layer 1 + + + + + \ No newline at end of file diff --git a/src/Mod/PartDesign/Gui/Workbench.cpp b/src/Mod/PartDesign/Gui/Workbench.cpp index b272e4d0a..72573757f 100644 --- a/src/Mod/PartDesign/Gui/Workbench.cpp +++ b/src/Mod/PartDesign/Gui/Workbench.cpp @@ -221,7 +221,8 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "PartDesign_LinearPattern" << "PartDesign_PolarPattern" // << "PartDesign_Scaled" - << "PartDesign_MultiTransform"; + << "PartDesign_MultiTransform" + << "PartDesign_InvoluteGear"; // For 0.13 a couple of python packages like numpy, matplotlib and others // are not deployed with the installer on Windows. Thus, the WizardShaft is // not deployed either hence the check for the existence of the command. diff --git a/src/Mod/PartDesign/InitGui.py b/src/Mod/PartDesign/InitGui.py index 717a2cd32..855d3d8a6 100644 --- a/src/Mod/PartDesign/InitGui.py +++ b/src/Mod/PartDesign/InitGui.py @@ -72,6 +72,7 @@ class PartDesignWorkbench ( Workbench ): print "Wizard shaft not installed" import PartDesignGui import PartDesign + import InvoluteGearFeature def GetClassName(self): return "PartDesignGui::Workbench" diff --git a/src/Mod/PartDesign/InvoluteGearFeature.py b/src/Mod/PartDesign/InvoluteGearFeature.py new file mode 100644 index 000000000..9ee902af1 --- /dev/null +++ b/src/Mod/PartDesign/InvoluteGearFeature.py @@ -0,0 +1,192 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2014 - Juergen Riegel * +#* * +#* This program is free software; you can redistribute it and/or modify * +#* it under the terms of the GNU Lesser General Public License (LGPL) * +#* as published by the Free Software Foundation; either version 2 of * +#* the License, or (at your option) any later version. * +#* for detail see the LICENCE text file. * +#* * +#* 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 Library General Public License for more details. * +#* * +#* You should have received a copy of the GNU Library General Public * +#* License along with this program; if not, write to the Free Software * +#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +#* USA * +#* * +#*************************************************************************** + +import FreeCAD, Part +from fcgear import involute +from fcgear import fcgear + +if FreeCAD.GuiUp: + import FreeCADGui + from PySide import QtCore, QtGui + from FreeCADGui import PySideUic as uic + +__title__="PartDesign InvoluteGearObject managment" +__author__ = "Juergen Riegel" +__url__ = "http://www.freecadweb.org" + + + +def makeInvoluteGear(name): + '''makeInvoluteGear(name): makes an InvoluteGear''' + obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython",name) + _InvoluteGear(obj) + _ViewProviderInvoluteGear(obj.ViewObject) + #FreeCAD.ActiveDocument.recompute() + return obj + +class _CommandInvoluteGear: + "the Fem InvoluteGear command definition" + def GetResources(self): + return {'Pixmap' : 'PartDesign_InvoluteGear', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("PartDesign_InvoluteGear","Involute gear..."), + 'Accel': "", + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PartDesign_InvoluteGear","Creates or edit the involute gear definition.")} + + def Activated(self): + + FreeCAD.ActiveDocument.openTransaction("Create involute gear") + FreeCADGui.addModule("InvoluteGearFeature") + FreeCADGui.doCommand("InvoluteGearFeature.makeInvoluteGear('InvoluteGear')") + FreeCADGui.doCommand("Gui.activeDocument().setEdit(App.ActiveDocument.ActiveObject.Name,0)") + + def IsActive(self): + if FreeCAD.ActiveDocument: + return True + else: + return False + + +class _InvoluteGear: + "The InvoluteGear object" + def __init__(self,obj): + self.Type = "InvoluteGear" + obj.addProperty("App::PropertyInteger","NumberOfTeeth","Gear","Number of gear teeth") + obj.addProperty("App::PropertyLength","Modules","Gear","Modules of the gear") + obj.addProperty("App::PropertyAngle","PressureAngle","Gear","Pressure angle of gear teeth") + obj.addProperty("App::PropertyInteger","NumberOfCurves","Gear","0=2x3 1=1x4 ") + + obj.NumberOfTeeth = 26 + obj.Modules = "2.5 mm" + obj.PressureAngle = "20 deg" + obj.NumberOfCurves = 0 + + obj.Proxy = self + + + def execute(self,obj): + print "_InvoluteGear.execute()" + w = fcgear.FCWireBuilder() + involute.CreateExternalGear(w, obj.Modules.Value,obj.NumberOfTeeth, obj.PressureAngle.Value, obj.NumberOfCurves == 0) + gearw = Part.Wire([o.toShape() for o in w.wire]) + obj.Shape = gearw + return + + +class _ViewProviderInvoluteGear: + "A View Provider for the InvoluteGear object" + + def __init__(self,vobj): + vobj.Proxy = self + + def getIcon(self): + return ":/icons/PartDesign_InvoluteGear.svg" + + def attach(self, vobj): + self.ViewObject = vobj + self.Object = vobj.Object + + + def setEdit(self,vobj,mode): + taskd = _InvoluteGearTaskPanel(self.Object,mode) + taskd.obj = vobj.Object + taskd.update() + FreeCADGui.Control.showDialog(taskd) + return True + + def unsetEdit(self,vobj,mode): + FreeCADGui.Control.closeDialog() + return + + +class _InvoluteGearTaskPanel: + '''The editmode TaskPanel for InvoluteGear objects''' + def __init__(self,obj,mode): + self.obj = obj + + self.form=FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/PartDesign/InvoluteGearFeature.ui") + + QtCore.QObject.connect(self.form.Quantity_Modules, QtCore.SIGNAL("valueChanged(double)"), self.modulesChanged) + QtCore.QObject.connect(self.form.Quantity_PressureAngle, QtCore.SIGNAL("valueChanged(double)"), self.angleChanged) + QtCore.QObject.connect(self.form.spinBox_NumberOfTeeth, QtCore.SIGNAL("valueChanged(int)"), self.numTeethChanged) + + self.update() + + if mode == 0: # fresh created + self.obj.Proxy.execute(self.obj) # calculate once + + def transferTo(self): + "Transfer from the dialog to the object" + self.obj.NumberOfTeeth = self.form.spinBox_NumberOfTeeth.value() + self.obj.Modules = self.form.Quantity_Modules.text() + self.obj.PressureAngle = self.form.Quantity_PressureAngle.text() + self.obj.NumberOfCurves = self.form.comboBox_NumberOfCurves.currentIndex() + + + def transferFrom(self): + "Transfer from the object to the dialog" + self.form.spinBox_NumberOfTeeth.setValue(self.obj.NumberOfTeeth) + self.form.Quantity_Modules.setText(self.obj.Modules.UserString) + self.form.Quantity_PressureAngle.setText(self.obj.PressureAngle.UserString) + self.form.comboBox_NumberOfCurves.setCurrentIndex(self.obj.NumberOfCurves) + + def modulesChanged(self, value): + print value + self.obj.Modules = value + self.obj.Proxy.execute(self.obj) + + def angleChanged(self, value): + print value + self.obj.PressureAngle = value + self.obj.Proxy.execute(self.obj) + + def numTeethChanged(self, value): + print value + self.obj.NumberOfTeeth = value + self.obj.Proxy.execute(self.obj) + + def getStandardButtons(self): + return int(QtGui.QDialogButtonBox.Ok) | int(QtGui.QDialogButtonBox.Cancel)| int(QtGui.QDialogButtonBox.Apply) + + def clicked(self,button): + if button == QtGui.QDialogButtonBox.Apply: + print "Apply" + self.transferTo() + self.obj.Proxy.execute(self.obj) + + def update(self): + 'fills the widgets' + self.transferFrom() + + def accept(self): + print 'accept(self)' + self.transferTo() + FreeCAD.ActiveDocument.recompute() + FreeCADGui.ActiveDocument.resetEdit() + + + def reject(self): + print 'reject(self)' + FreeCADGui.ActiveDocument.resetEdit() + + + +FreeCADGui.addCommand('PartDesign_InvoluteGear',_CommandInvoluteGear()) diff --git a/src/Mod/PartDesign/InvoluteGearFeature.ui b/src/Mod/PartDesign/InvoluteGearFeature.ui new file mode 100644 index 000000000..19b9c4a2c --- /dev/null +++ b/src/Mod/PartDesign/InvoluteGearFeature.ui @@ -0,0 +1,160 @@ + + + InvoluteGearParameter + + + + 0 + 0 + 195 + 116 + + + + Involute parameter + + + + + + Number of teeth: + + + + + + + 3 + + + 9999 + + + 26 + + + + + + + Modules: + + + + + + + + 0 + 0 + + + + + 80 + 20 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + mm + + + 3 + + + 2000.000000000000000 + + + 2.000000000000000 + + + 2.500000000000000 + + + + + + + Pressure angle: + + + + + + + + 0 + 0 + + + + + 80 + 20 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + deg + + + 3 + + + 90.000000000000000 + + + 2.000000000000000 + + + 20.000000000000000 + + + + + + + Number of Curves: + + + + + + + false + + + false + + + + 2x3 + + + + + 1x4 + + + + + + + + + Gui::InputField + QLineEdit +
Gui/InputField.h
+
+
+ + +