Implement the python gear feature

This commit is contained in:
jriegel 2014-02-16 22:19:39 +01:00
parent 1d5cfbc9cc
commit 6d1d55dc15
8 changed files with 375 additions and 1 deletions

View File

@ -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})

View File

@ -11,6 +11,8 @@ INSTALL(
InitGui.py
TestPartDesignApp.py
TestPartDesignGui.py
InvoluteGearFeature.py
InvoluteGearFeature.ui
DESTINATION
Mod/PartDesign
)

View File

@ -15,6 +15,7 @@
<file>icons/PartDesign_Hole.svg</file>
<file>icons/Tree_PartDesign_Pad.svg</file>
<file>icons/Tree_PartDesign_Revolution.svg</file>
<file>icons/PartDesign_InvoluteGear.svg</file>
<file>translations/PartDesign_af.qm</file>
<file>translations/PartDesign_de.qm</file>
<file>translations/PartDesign_fi.qm</file>

View File

@ -0,0 +1,10 @@
<?xml version="1.0"?><svg width="1000" height="1000" xmlns="http://www.w3.org/2000/svg">
<title>High Resolution Gear</title>
<metadata id="metadata4083">image/svg+xml</metadata>
<g>
<title>Layer 1</title>
<g externalResourcesRequired="false" id="layer1">
<path d="m457.674194,1l-20.76886,118.302437l0.079987,0.079193c-25.386719,4.14814 -49.948639,10.796745 -73.40979,19.650475l0,-0.079178l-77.084137,-92.101566l-72.451248,41.857128l41.13826,112.790565l0.159546,0.079254c-19.642059,16.123276 -37.644791,34.189743 -53.759094,53.839432l-0.079803,-0.240234l-112.790565,-41.138397l-41.857117,72.45134l92.101555,77.164093c-8.839218,23.441681 -15.428467,47.966858 -19.570518,73.329895l-0.079956,-0.079315l-118.302452,20.768799l0,83.714264l118.302452,20.768799l0.079956,-0.079224c4.141754,25.362976 10.7313,49.888 19.570518,73.329773l-92.101555,77.164185l41.857117,72.450989l112.790565,-41.138062l0.079803,-0.240295c16.114304,19.649048 34.116806,37.716187 53.759094,53.838806l-0.159546,0.079285l-41.13826,112.790588l72.451248,41.857178l77.084137,-92.10083l0,-0.079834c23.461151,8.853882 48.023071,15.502441 73.40979,19.650452l-0.079987,0.079285l20.76886,118.302307l83.634155,0l20.76886,-118.302307l-0.079773,-0.079285c25.381592,-4.136658 49.950745,-10.72998 73.409912,-19.570618l77.163757,92.101685l72.451294,-41.857117l-41.218018,-112.790527c19.597717,-16.082031 37.591675,-34.086304 53.679321,-53.679382l112.8703,41.138245l41.777466,-72.451233l-92.02179,-77.164124c8.841187,-23.444763 15.507629,-47.963196 19.650513,-73.329834l118.302429,-20.688782l0,-83.714233l-118.302429,-20.768768c-4.143738,-25.339447 -10.818176,-49.828888 -19.650513,-73.250153l92.02179,-77.164093l-41.777466,-72.451157l-112.8703,41.138214c-16.088074,-19.593384 -34.080933,-37.597275 -53.679321,-53.679367l41.218018,-112.790497l-72.451294,-41.857121l-77.163757,92.101475c-23.459167,-8.83992 -48.02832,-15.433525 -73.409912,-19.570435l0.079773,-0.079254l-20.76886,-118.302377l-83.634155,0l0,-0.00054zm41.857117,203.693954c162.853027,0 294.916931,131.984085 294.916931,294.837265c0,162.852997 -132.063904,294.836945 -294.916931,294.836945c-162.852936,0 -294.836975,-131.983948 -294.836975,-294.836945c0,-162.85318 131.984039,-294.837265 294.836975,-294.837265z" id="path4050" stroke-dashoffset="0" stroke-miterlimit="4" stroke-linejoin="round" stroke-linecap="round" stroke-width="2" fill="#3f3f3f"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -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.

View File

@ -72,6 +72,7 @@ class PartDesignWorkbench ( Workbench ):
print "Wizard shaft not installed"
import PartDesignGui
import PartDesign
import InvoluteGearFeature
def GetClassName(self):
return "PartDesignGui::Workbench"

View File

@ -0,0 +1,192 @@
#***************************************************************************
#* *
#* Copyright (c) 2014 - Juergen Riegel <FreeCAD@juergen-riegel.net> *
#* *
#* 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())

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>InvoluteGearParameter</class>
<widget class="QWidget" name="InvoluteGearParameter">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>195</width>
<height>116</height>
</rect>
</property>
<property name="windowTitle">
<string>Involute parameter</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Number of teeth:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox_NumberOfTeeth">
<property name="minimum">
<number>3</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="value">
<number>26</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Modules:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::InputField" name="Quantity_Modules">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="unit" stdset="0">
<string>mm</string>
</property>
<property name="decimals" stdset="0">
<number>3</number>
</property>
<property name="maximum" stdset="0">
<double>2000.000000000000000</double>
</property>
<property name="singleStep" stdset="0">
<double>2.000000000000000</double>
</property>
<property name="value" stdset="0">
<double>2.500000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Pressure angle:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::InputField" name="Quantity_PressureAngle">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="unit" stdset="0">
<string>deg</string>
</property>
<property name="decimals" stdset="0">
<number>3</number>
</property>
<property name="maximum" stdset="0">
<double>90.000000000000000</double>
</property>
<property name="singleStep" stdset="0">
<double>2.000000000000000</double>
</property>
<property name="value" stdset="0">
<double>20.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Number of Curves:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBox_NumberOfCurves">
<property name="enabled">
<bool>false</bool>
</property>
<property name="editable">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>2x3</string>
</property>
</item>
<item>
<property name="text">
<string>1x4</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::InputField</class>
<extends>QLineEdit</extends>
<header>Gui/InputField.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>