diff --git a/freecad/gears/commands.py b/freecad/gears/commands.py
index 212d65d..592b798 100644
--- a/freecad/gears/commands.py
+++ b/freecad/gears/commands.py
@@ -19,14 +19,13 @@
import os
import FreeCAD
import FreeCADGui as Gui
+
from .features import (
ViewProviderGear,
InvoluteGear,
InternalInvoluteGear,
InvoluteGearRack,
CycloidGearRack,
-)
-from .features import (
CycloidGear,
BevelGear,
CrownGear,
@@ -36,6 +35,8 @@ from .features import (
HypoCycloidGear,
BaseGear,
)
+from .timing_gear_t import TimingGearT
+
from .connector import GearConnector, ViewProviderGearConnector
@@ -167,6 +168,14 @@ class CreateWormGear(BaseCommand):
ToolTip = "Create a Worm gear"
+class CreateTimingGearT(BaseCommand):
+ NAME = "TimingGearT"
+ GEAR_FUNCTION = TimingGearT
+ Pixmap = os.path.join(BaseCommand.ICONDIR, "timinggear_t.svg")
+ MenuText = "Timing Gear T-shape"
+ ToolTip = "Create a Timing gear T-shape"
+
+
class CreateTimingGear(BaseCommand):
NAME = "TimingGear"
GEAR_FUNCTION = TimingGear
diff --git a/freecad/gears/features.py b/freecad/gears/features.py
index 300170f..19209f5 100644
--- a/freecad/gears/features.py
+++ b/freecad/gears/features.py
@@ -16,7 +16,6 @@
# * *
# ***************************************************************************
-from __future__ import division
import os
import sys
diff --git a/freecad/gears/icons/timinggear_t.svg b/freecad/gears/icons/timinggear_t.svg
new file mode 100644
index 0000000..b25e312
--- /dev/null
+++ b/freecad/gears/icons/timinggear_t.svg
@@ -0,0 +1,404 @@
+
+
diff --git a/freecad/gears/init_gui.py b/freecad/gears/init_gui.py
index 08ce227..6f3a8d7 100644
--- a/freecad/gears/init_gui.py
+++ b/freecad/gears/init_gui.py
@@ -105,6 +105,7 @@ class GearWorkbench(Workbench):
"CreateBevelGear",
"CreateCrownGear",
"CreateWormGear",
+ "CreateTimingGearT",
"CreateTimingGear",
"CreateLanternGear",
"CreateHypoCycloidGear",
@@ -119,15 +120,20 @@ class GearWorkbench(Workbench):
CreateCycloidGear,
CreateInvoluteGear,
CreateInternalInvoluteGear,
+ CreateBevelGear,
+ CreateInvoluteRack,
+ CreateCrownGear,
+ CreateWormGear,
+ CreateTimingGearT,
+ CreateTimingGear,
+ CreateLanternGear,
+ CreateHypoCycloidGear,
+ CreateCycloidRack,
+ CreateGearConnector
)
- from .commands import CreateBevelGear, CreateInvoluteRack, CreateCrownGear
- from .commands import CreateWormGear, CreateTimingGear, CreateLanternGear
- from .commands import CreateHypoCycloidGear, CreateCycloidRack
- from .commands import CreateGearConnector
self.appendToolbar("Gear", self.commands)
self.appendMenu("Gear", self.commands)
- # Gui.addIconPath(App.getHomePath()+"Mod/gear/icons/")
Gui.addCommand("CreateInvoluteGear", CreateInvoluteGear())
Gui.addCommand("CreateInternalInvoluteGear", CreateInternalInvoluteGear())
Gui.addCommand("CreateCycloidGear", CreateCycloidGear())
@@ -136,6 +142,7 @@ class GearWorkbench(Workbench):
Gui.addCommand("CreateInvoluteRack", CreateInvoluteRack())
Gui.addCommand("CreateCrownGear", CreateCrownGear())
Gui.addCommand("CreateWormGear", CreateWormGear())
+ Gui.addCommand("CreateTimingGearT", CreateTimingGearT())
Gui.addCommand("CreateTimingGear", CreateTimingGear())
Gui.addCommand("CreateLanternGear", CreateLanternGear())
Gui.addCommand("CreateHypoCycloidGear", CreateHypoCycloidGear())
diff --git a/freecad/gears/timing_gear_t.py b/freecad/gears/timing_gear_t.py
new file mode 100644
index 0000000..4eded90
--- /dev/null
+++ b/freecad/gears/timing_gear_t.py
@@ -0,0 +1,113 @@
+# -*- coding: utf-8 -*-
+# ***************************************************************************
+# * *
+# * This program is free software: you can redistribute it and/or modify *
+# * it under the terms of the GNU General Public License as published by *
+# * the Free Software Foundation, either version 3 of the License, or *
+# * (at your option) any later version. *
+# * *
+# * 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 General Public License for more details. *
+# * *
+# * You should have received a copy of the GNU General Public License *
+# * along with this program. If not, see . *
+# * *
+# ***************************************************************************
+
+
+import numpy as np
+import scipy as sp
+
+import FreeCAD as App
+import Part
+
+from pygears._functions import (
+ rotation,
+ reflection
+)
+
+from .features import BaseGear, fcvec
+
+
+class TimingGearT(BaseGear):
+ def __init__(self, obj):
+ print("hello gear")
+ obj.addProperty("App::PropertyLength", "pitch", "base", "pitch of gear")
+ obj.addProperty("App::PropertyInteger", "teeth", "base", "number of teeth")
+ obj.addProperty("App::PropertyLength", "tooth_height", "base", "radial height of tooth")
+ obj.addProperty("App::PropertyLength", "u", "base", "radial distance from tooth-head to pitch circle")
+ obj.addProperty("App::PropertyAngle", "alpha", "base", "angle of tooth flanks")
+ obj.addProperty("App::PropertyLength", "height", "base", "extrusion height")
+ obj.pitch = "5. mm"
+ obj.teeth = 15
+ obj.tooth_height = "1.2 mm"
+ obj.u = "0.6 mm"
+ obj.alpha = "40. deg"
+ obj.height = "5 mm"
+ self.obj = obj
+ obj.Proxy = self
+
+ def generate_gear_shape(self, fp):
+ print("generate gear shape")
+ pitch = fp.pitch.Value
+ teeth = fp.teeth
+ u = fp.u.Value
+ tooth_height = fp.tooth_height.Value
+ alpha = fp.alpha.Value / 180. * np.pi # we need radiant
+ height = fp.height.Value
+
+ r_p = pitch * teeth / 2. / np.pi
+ gamma_0 = pitch / r_p
+ gamma_1 = gamma_0 / 4
+
+ p_A = np.array([
+ np.cos(-gamma_1),
+ np.sin(-gamma_1)
+ ]) * (r_p - u - tooth_height / 2)
+
+ def line(s):
+ p = p_A + np.array([
+ np.cos(alpha / 2 - gamma_1),
+ np.sin(alpha / 2 - gamma_1)
+ ]) * s
+ return p
+
+ def dist_p1(s):
+ return (np.linalg.norm(line(s)) - (r_p - u - tooth_height)) ** 2
+
+ def dist_p2(s):
+ return (np.linalg.norm(line(s)) - (r_p - u)) ** 2
+
+ s1 = sp.optimize.minimize(dist_p1, 0.).x
+ s2 = sp.optimize.minimize(dist_p2, 0.).x
+
+ p_1 = line(s1)
+ p_2 = line(s2)
+
+ mirror = reflection(0.) # reflect the points at the x-axis
+ p_3, p_4 = mirror(np.array([p_2, p_1]))
+
+ rot = rotation(-gamma_0) # why is the rotation in wrong direction ???
+ p_5 = rot(np.array([p_1]))[0] # the rotation expects a list of points
+
+ l1 = Part.LineSegment(fcvec(p_1), fcvec(p_2)).toShape()
+ l2 = Part.LineSegment(fcvec(p_2), fcvec(p_3)).toShape()
+ l3 = Part.LineSegment(fcvec(p_3), fcvec(p_4)).toShape()
+ l4 = Part.LineSegment(fcvec(p_4), fcvec(p_5)).toShape()
+ w = Part.Wire([l1, l2, l3, l4])
+
+ # now using a FreeCAD Matrix (this will turn in the right direction)
+ rot = App.Matrix()
+ rot.rotateZ(gamma_0)
+ wires = []
+ for i in range(teeth):
+ w = w.transformGeometry(rot)
+ wires.append(w.copy())
+ contour = Part.Wire(wires)
+ if height == 0:
+ return contour
+ else:
+ face = Part.Face(Part.Wire(wires))
+ return face.extrude(App.Vector(0., 0., height))
diff --git a/pygears/_functions.py b/pygears/_functions.py
index cddd399..80fefc1 100644
--- a/pygears/_functions.py
+++ b/pygears/_functions.py
@@ -22,9 +22,11 @@ from numpy.linalg import solve, norm
def reflection(angle):
- mat = array([[cos(2 * angle), -sin(2 * angle)], [-sin(2 * angle), -cos(2 * angle)]])
+ mat = array([[cos(2 * angle), -sin(2 * angle)],
+ [-sin(2 * angle), -cos(2 * angle)]])
def func(x):
+ # why not use mat @ x???
return dot(x, mat)
return func
@@ -40,6 +42,7 @@ def reflection3D(angle):
)
def func(x):
+ # why not use mat @ x
return dot(x, mat)
return func