Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e6223bffa | ||
|
|
07bfe0446d | ||
|
|
05d2afef44 | ||
|
|
2ede7f0bdc | ||
|
|
6042cb8b4d | ||
|
|
2e25ba6b97 | ||
|
|
6a9baf4fed | ||
|
|
1cf83e7344 | ||
|
|
39e5ce1378 | ||
|
|
9f1e87bedb | ||
|
|
7c4723c9b7 | ||
|
|
d0e7720988 | ||
|
|
da42164552 | ||
|
|
73f6b7f1f7 | ||
|
|
590994984f | ||
|
|
b4783df755 | ||
|
|
2ecc0e8744 | ||
|
|
d77f5c1ab4 | ||
|
|
4aa2559629 | ||
|
|
5846ffbfdc | ||
|
|
7edc50c32d | ||
|
|
05abf3054d | ||
|
|
10d4bf0bbf | ||
|
|
ea904a2a7d | ||
|
|
0eca70d832 | ||
|
|
469e00cd98 | ||
|
|
3668892abe | ||
|
|
8b8f8e0779 | ||
|
|
ef73b66040 | ||
|
|
89e99bef0e | ||
|
|
15f3f2410d | ||
|
|
fd363e2b84 | ||
|
|
81d6a77218 | ||
|
|
b75336b0ea | ||
|
|
95a14777b9 | ||
|
|
7cb84f17e1 | ||
|
|
b7a4192f70 | ||
|
|
4db17dd2b0 | ||
|
|
165b52d967 | ||
|
|
f1531a183b | ||
|
|
055aab2e07 | ||
|
|
c40bae47b3 | ||
|
|
6daa3114be | ||
|
|
4e16fd2560 | ||
|
|
56acace6ef | ||
|
|
37b99b119d | ||
|
|
9983f5ee61 | ||
|
|
bd6c2107ee | ||
|
|
9225b5b4ed | ||
|
|
175b746a7a | ||
|
|
1f70e28ac1 | ||
|
|
403505ae95 | ||
|
|
ae1c272c42 | ||
|
|
9ddd493b82 | ||
|
|
3c9f6f0c6b | ||
|
|
8174345a38 | ||
|
|
3dedcf3e21 |
@@ -26,6 +26,10 @@ __python > 3 (for python2 use branch py2)__
|
||||
|
||||

|
||||
|
||||
### Cycloid Rack
|
||||
|
||||

|
||||
|
||||
### Spherical Involute Bevel-Gear
|
||||
* Spiral
|
||||
|
||||
|
||||
6
TODO.md
Normal file
6
TODO.md
Normal file
@@ -0,0 +1,6 @@
|
||||
#TODO:
|
||||
|
||||
## refactoring
|
||||
|
||||
- [ ] fp.gear.z -> fp.gear.num_teeth
|
||||
- [ ] fp.teeth -> fp.gear.num_teeth
|
||||
BIN
examples/cycloid-rack.png
Normal file
BIN
examples/cycloid-rack.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 188 KiB |
@@ -1,21 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * 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 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 Library General Public License for more details. *
|
||||
# * 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 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 *
|
||||
# * You should have received a copy of the GNU General Public License *
|
||||
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * 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 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 Library General Public License for more details. *
|
||||
# * 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 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 *
|
||||
# * You should have received a copy of the GNU General Public License *
|
||||
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import os
|
||||
import FreeCAD
|
||||
import FreeCADGui as Gui
|
||||
from .features import ViewProviderGear, InvoluteGear, InvoluteGearRack
|
||||
from .features import CycloidGear, BevelGear, CrownGear, WormGear, TimingGear, LanternGear, HypoCycloidGear
|
||||
from .features import ViewProviderGear, InvoluteGear, InternalInvoluteGear, InvoluteGearRack, CycloidGearRack
|
||||
from .features import CycloidGear, BevelGear, CrownGear, WormGear, TimingGear, LanternGear, HypoCycloidGear, BaseGear
|
||||
from .connector import GearConnector, ViewProviderGearConnector
|
||||
|
||||
|
||||
class BaseCommand(object):
|
||||
@@ -59,11 +57,11 @@ class BaseCommand(object):
|
||||
obj = FreeCAD.ActiveDocument.addObject("PartDesign::FeaturePython", cls.NAME)
|
||||
else:
|
||||
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", cls.NAME)
|
||||
ViewProviderGear(obj.ViewObject)
|
||||
ViewProviderGear(obj.ViewObject, cls.Pixmap)
|
||||
cls.GEAR_FUNCTION(obj)
|
||||
|
||||
if body:
|
||||
body.Group += [obj]
|
||||
body.addObject(obj)
|
||||
elif part:
|
||||
part.Group += [obj]
|
||||
else:
|
||||
@@ -78,70 +76,108 @@ class BaseCommand(object):
|
||||
|
||||
|
||||
class CreateInvoluteGear(BaseCommand):
|
||||
NAME = "involutegear"
|
||||
NAME = "InvoluteGear"
|
||||
GEAR_FUNCTION = InvoluteGear
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'involutegear.svg')
|
||||
MenuText = 'Involute gear'
|
||||
ToolTip = 'Create an Involute gear'
|
||||
MenuText = 'Involute Gear'
|
||||
ToolTip = 'Create an external involute gear'
|
||||
|
||||
|
||||
class CreateInternalInvoluteGear(BaseCommand):
|
||||
NAME = "InternalInvoluteGear"
|
||||
GEAR_FUNCTION = InternalInvoluteGear
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'internalinvolutegear.svg')
|
||||
MenuText = 'Internal Involute Gear'
|
||||
ToolTip = 'Create an internal involute gear'
|
||||
|
||||
|
||||
class CreateInvoluteRack(BaseCommand):
|
||||
NAME = "involuterack"
|
||||
NAME = "InvoluteRack"
|
||||
GEAR_FUNCTION = InvoluteGearRack
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'involuterack.svg')
|
||||
MenuText = 'Involute rack'
|
||||
MenuText = 'Involute Rack'
|
||||
ToolTip = 'Create an Involute rack'
|
||||
|
||||
class CreateCycloidRack(BaseCommand):
|
||||
NAME = "CycloidRack"
|
||||
GEAR_FUNCTION = CycloidGearRack
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'cycloidrack.svg')
|
||||
MenuText = 'Cycloid Rack'
|
||||
ToolTip = 'Create an Cycloid rack'
|
||||
|
||||
|
||||
class CreateCrownGear(BaseCommand):
|
||||
NAME = "crowngear"
|
||||
NAME = "CrownGear"
|
||||
GEAR_FUNCTION = CrownGear
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'crowngear.svg')
|
||||
MenuText = 'Crown gear'
|
||||
MenuText = 'Crown Gear'
|
||||
ToolTip = 'Create a Crown gear'
|
||||
|
||||
|
||||
class CreateCycloidGear(BaseCommand):
|
||||
NAME = "cycloidgear"
|
||||
NAME = "CycloidGear"
|
||||
GEAR_FUNCTION = CycloidGear
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'cycloidgear.svg')
|
||||
MenuText = 'Cycloid gear'
|
||||
MenuText = 'Cycloid Gear'
|
||||
ToolTip = 'Create a Cycloid gear'
|
||||
|
||||
|
||||
class CreateBevelGear(BaseCommand):
|
||||
NAME = "bevelgear"
|
||||
NAME = "BevelGear"
|
||||
GEAR_FUNCTION = BevelGear
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'bevelgear.svg')
|
||||
MenuText = 'Bevel gear'
|
||||
MenuText = 'Bevel Gear'
|
||||
ToolTip = 'Create a Bevel gear'
|
||||
|
||||
class CreateHypoCycloidGear(BaseCommand):
|
||||
NAME = "hypocycloidgear"
|
||||
NAME = "HypocycloidGear"
|
||||
GEAR_FUNCTION = HypoCycloidGear
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'hypocycloidgear.svg')
|
||||
MenuText = 'HypoCycloid gear'
|
||||
MenuText = 'HypoCycloid Gear'
|
||||
ToolTip = 'Create a HypoCycloid gear with its pins'
|
||||
|
||||
|
||||
class CreateWormGear(BaseCommand):
|
||||
NAME = "wormgear"
|
||||
NAME = "WormGear"
|
||||
GEAR_FUNCTION = WormGear
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'wormgear.svg')
|
||||
MenuText = 'Worm gear'
|
||||
MenuText = 'Worm Gear'
|
||||
ToolTip = 'Create a Worm gear'
|
||||
|
||||
|
||||
class CreateTimingGear(BaseCommand):
|
||||
NAME = "timinggear"
|
||||
NAME = "TimingGear"
|
||||
GEAR_FUNCTION = TimingGear
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'timinggear.svg')
|
||||
MenuText = 'Timing gear'
|
||||
MenuText = 'Timing Gear'
|
||||
ToolTip = 'Create a Timing gear'
|
||||
|
||||
class CreateLanternGear(BaseCommand):
|
||||
NAME = "lanterngear"
|
||||
NAME = "LanternGear"
|
||||
GEAR_FUNCTION = LanternGear
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'lanterngear.svg')
|
||||
MenuText = 'Lantern gear'
|
||||
MenuText = 'Lantern Gear'
|
||||
ToolTip = 'Create a Lantern gear'
|
||||
|
||||
class CreateGearConnector(BaseCommand):
|
||||
NAME = "GearConnector"
|
||||
GEAR_FUNCTION = GearConnector
|
||||
Pixmap = os.path.join(BaseCommand.ICONDIR, 'gearconnector.svg')
|
||||
MenuText = 'Combine two gears'
|
||||
ToolTip = 'Combine two gears'
|
||||
|
||||
def Activated(self):
|
||||
gear1 = Gui.Selection.getSelection()[0]
|
||||
assert isinstance(gear1.Proxy, BaseGear)
|
||||
|
||||
gear2 = Gui.Selection.getSelection()[1]
|
||||
assert isinstance(gear2.Proxy, BaseGear)
|
||||
|
||||
# check if selected objects are beams
|
||||
|
||||
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", self.NAME)
|
||||
GearConnector(obj, gear1, gear2)
|
||||
ViewProviderGearConnector(obj.ViewObject)
|
||||
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return obj
|
||||
|
||||
161
freecad/gears/connector.py
Normal file
161
freecad/gears/connector.py
Normal file
@@ -0,0 +1,161 @@
|
||||
# -*- 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 <http://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import os
|
||||
import copy
|
||||
import numpy as np
|
||||
import FreeCAD
|
||||
from pygears import __version__
|
||||
from .features import InvoluteGear, CycloidGear, InvoluteGearRack, CycloidGearRack, InternalInvoluteGear
|
||||
from pygears.computation import compute_shifted_gears
|
||||
|
||||
class ViewProviderGearConnector(object):
|
||||
def __init__(self, vobj, icon_fn=None):
|
||||
# Set this object to the proxy object of the actual view provider
|
||||
vobj.Proxy = self
|
||||
dirname = os.path.dirname(__file__)
|
||||
self.icon_fn = icon_fn or os.path.join(dirname, "icons", "gearconnector.svg")
|
||||
|
||||
def attach(self, vobj):
|
||||
self.vobj = vobj
|
||||
|
||||
def getIcon(self):
|
||||
return self.icon_fn
|
||||
|
||||
def __getstate__(self):
|
||||
return {"icon_fn": self.icon_fn}
|
||||
|
||||
def __setstate__(self, state):
|
||||
self.icon_fn = state["icon_fn"]
|
||||
|
||||
|
||||
class GearConnector(object):
|
||||
def __init__(self, obj, master_gear, slave_gear):
|
||||
obj.addProperty("App::PropertyString", "version", "version", "freecad.gears-version", 1)
|
||||
obj.addProperty("App::PropertyLink","master_gear","gear","master gear", 1)
|
||||
obj.addProperty("App::PropertyLink","slave_gear","gear","slave gear", 1)
|
||||
obj.addProperty("App::PropertyAngle", "angle1", "gear", "angle at which second gear is placed", 0)
|
||||
obj.addProperty("App::PropertyAngle", "angle2", "gear", "angle at which second gear is placed", 1)
|
||||
obj.version = __version__
|
||||
obj.master_gear = master_gear
|
||||
obj.slave_gear = slave_gear
|
||||
obj.angle1 = 0
|
||||
obj.angle2 = 0
|
||||
obj.Proxy = self
|
||||
|
||||
def onChanged(self, fp, prop):
|
||||
# fp.angle2 = fp.master_gear.Placement.Rotation.Angle
|
||||
if isinstance(fp.master_gear.Proxy, InvoluteGear) and isinstance(fp.slave_gear.Proxy, InvoluteGear):
|
||||
angle_master = fp.master_gear.Placement.Rotation.Angle * sum(fp.master_gear.Placement.Rotation.Axis)
|
||||
dw_master = fp.master_gear.dw
|
||||
dw_slave = fp.slave_gear.dw
|
||||
dist = (dw_master + dw_slave) / 2
|
||||
if fp.master_gear.shift != 0 or fp.slave_gear.shift != 0:
|
||||
dist, alpha_w = compute_shifted_gears(
|
||||
fp.master_gear.module,
|
||||
np.deg2rad(fp.master_gear.pressure_angle.Value),
|
||||
fp.master_gear.teeth,
|
||||
fp.slave_gear.teeth,
|
||||
fp.master_gear.shift,
|
||||
fp.slave_gear.shift)
|
||||
|
||||
mat0 = FreeCAD.Matrix() # unity matrix
|
||||
trans = FreeCAD.Vector(dist)
|
||||
mat0.move(trans)
|
||||
rot = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), fp.angle1).toMatrix()
|
||||
angle2 = dw_master / dw_slave * fp.angle1.Value
|
||||
angle4 = dw_master / dw_slave * np.rad2deg(angle_master)
|
||||
rot2 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle2).toMatrix()
|
||||
angle3 = abs(fp.slave_gear.teeth % 2 - 1) * 180. / fp.slave_gear.teeth
|
||||
rot3 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle3).toMatrix()
|
||||
rot4 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), -angle4).toMatrix()
|
||||
mat1 = rot * mat0 * rot2 * rot3 * rot4
|
||||
mat1.move(fp.master_gear.Placement.Base)
|
||||
fp.slave_gear.Placement = mat1
|
||||
|
||||
if isinstance(fp.master_gear.Proxy, InternalInvoluteGear) and isinstance(fp.slave_gear.Proxy, InvoluteGear):
|
||||
angle_master = fp.master_gear.Placement.Rotation.Angle * sum(fp.master_gear.Placement.Rotation.Axis)
|
||||
dw_master = fp.master_gear.dw
|
||||
dw_slave = fp.slave_gear.dw
|
||||
dist = (dw_master - dw_slave) / 2
|
||||
if fp.master_gear.shift != 0 or fp.slave_gear.shift != 0:
|
||||
dist, alpha_w = compute_shifted_gears(
|
||||
fp.master_gear.module,
|
||||
np.deg2rad(fp.master_gear.pressure_angle.Value),
|
||||
fp.master_gear.teeth,
|
||||
fp.slave_gear.teeth,
|
||||
fp.master_gear.shift,
|
||||
fp.slave_gear.shift)
|
||||
|
||||
mat0 = FreeCAD.Matrix() # unity matrix
|
||||
trans = FreeCAD.Vector(dist)
|
||||
mat0.move(trans)
|
||||
rot = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), fp.angle1).toMatrix()
|
||||
angle2 = -dw_master / dw_slave * fp.angle1.Value
|
||||
angle4 = -dw_master / dw_slave * np.rad2deg(angle_master)
|
||||
rot2 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle2).toMatrix()
|
||||
angle3 = abs(fp.slave_gear.teeth % 2 - 1) * 180. / fp.slave_gear.teeth
|
||||
rot3 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle3).toMatrix()
|
||||
rot4 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), -angle4).toMatrix()
|
||||
mat1 = rot * mat0 * rot2 * rot3 * rot4
|
||||
mat1.move(fp.master_gear.Placement.Base)
|
||||
fp.slave_gear.Placement = mat1
|
||||
|
||||
if ((isinstance(fp.master_gear.Proxy, InvoluteGear) and isinstance(fp.slave_gear.Proxy, InvoluteGearRack))
|
||||
or (isinstance(fp.master_gear.Proxy, CycloidGear) and isinstance(fp.slave_gear.Proxy, CycloidGearRack))):
|
||||
angle_master = fp.master_gear.Placement.Rotation.Angle * sum(fp.master_gear.Placement.Rotation.Axis)
|
||||
dw_master = fp.master_gear.dw.Value
|
||||
dw_slave = 0
|
||||
dist = -(dw_master + dw_slave) / 2
|
||||
mat0 = FreeCAD.Matrix() # unity matrix
|
||||
mat0.move(FreeCAD.Vector(dist, 0, 0))
|
||||
mat1 = FreeCAD.Matrix()
|
||||
mat1.move(FreeCAD.Vector(0, np.deg2rad(fp.angle1.Value) * dw_master / 2, 0))
|
||||
mat2 = FreeCAD.Matrix()
|
||||
mat2.move(FreeCAD.Vector(0, -np.deg2rad(fp.angle2.Value) * dw_master / 2, 0))
|
||||
rot = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), fp.angle1).toMatrix()
|
||||
mat3 = rot * mat2 *mat1 * mat0
|
||||
mat3.move(fp.master_gear.Placement.Base)
|
||||
fp.slave_gear.Placement = mat3
|
||||
|
||||
if isinstance(fp.master_gear.Proxy, CycloidGear) and isinstance(fp.slave_gear.Proxy, CycloidGear):
|
||||
angle_master = fp.master_gear.Placement.Rotation.Angle * sum(fp.master_gear.Placement.Rotation.Axis)
|
||||
dw_master = fp.master_gear.dw
|
||||
dw_slave = fp.slave_gear.dw
|
||||
dist = (dw_master + dw_slave) / 2
|
||||
mat0 = FreeCAD.Matrix() # unity matrix
|
||||
trans = FreeCAD.Vector(dist, 0, 0)
|
||||
mat0.move(trans)
|
||||
rot = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), fp.angle1).toMatrix()
|
||||
angle2 = dw_master / dw_slave * fp.angle1.Value
|
||||
angle4 = dw_master / dw_slave * np.rad2deg(angle_master)
|
||||
rot2 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle2).toMatrix()
|
||||
angle3 = abs(fp.slave_gear.teeth % 2 - 1) * 180. / fp.slave_gear.teeth
|
||||
rot3 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle3).toMatrix()
|
||||
rot4 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), -angle4).toMatrix()
|
||||
mat1 = rot * mat0 * rot2 * rot3 * rot4
|
||||
mat1.move(fp.master_gear.Placement.Base)
|
||||
fp.slave_gear.Placement = mat1
|
||||
|
||||
def execute(self, fp):
|
||||
self.onChanged(fp, None)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
596
freecad/gears/icons/cycloidrack.svg
Normal file
596
freecad/gears/icons/cycloidrack.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 21 KiB |
352
freecad/gears/icons/gearconnector.svg
Normal file
352
freecad/gears/icons/gearconnector.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
346
freecad/gears/icons/internalinvolutegear.svg
Normal file
346
freecad/gears/icons/internalinvolutegear.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 14 KiB |
@@ -1,21 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * 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 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 Library General Public License for more details. *
|
||||
# * 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 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 *
|
||||
# * You should have received a copy of the GNU General Public License *
|
||||
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
@@ -40,29 +37,35 @@ class GearWorkbench(Workbench):
|
||||
Icon = os.path.join(__dirname__, 'icons', 'gearworkbench.svg')
|
||||
commands = [
|
||||
"CreateInvoluteGear",
|
||||
"CreateInternalInvoluteGear",
|
||||
"CreateInvoluteRack",
|
||||
"CreateCycloidGear",
|
||||
"CreateCycloidRack",
|
||||
"CreateBevelGear",
|
||||
"CreateCrownGear",
|
||||
"CreateWormGear",
|
||||
"CreateTimingGear",
|
||||
"CreateLanternGear",
|
||||
"CreateHypoCycloidGear"]
|
||||
"CreateHypoCycloidGear",
|
||||
"CreateGearConnector"]
|
||||
|
||||
def GetClassName(self):
|
||||
return "Gui::PythonWorkbench"
|
||||
|
||||
def Initialize(self):
|
||||
from .commands import CreateCycloidGear, CreateInvoluteGear
|
||||
from .commands import CreateCycloidGear, CreateInvoluteGear, CreateInternalInvoluteGear
|
||||
from .commands import CreateBevelGear, CreateInvoluteRack, CreateCrownGear
|
||||
from .commands import CreateWormGear, CreateTimingGear, CreateLanternGear
|
||||
from .commands import CreateHypoCycloidGear
|
||||
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())
|
||||
Gui.addCommand('CreateCycloidRack', CreateCycloidRack())
|
||||
Gui.addCommand('CreateBevelGear', CreateBevelGear())
|
||||
Gui.addCommand('CreateInvoluteRack', CreateInvoluteRack())
|
||||
Gui.addCommand('CreateCrownGear', CreateCrownGear())
|
||||
@@ -70,6 +73,7 @@ class GearWorkbench(Workbench):
|
||||
Gui.addCommand('CreateTimingGear', CreateTimingGear())
|
||||
Gui.addCommand('CreateLanternGear', CreateLanternGear())
|
||||
Gui.addCommand('CreateHypoCycloidGear', CreateHypoCycloidGear())
|
||||
Gui.addCommand('CreateGearConnector', CreateGearConnector())
|
||||
|
||||
def Activated(self):
|
||||
pass
|
||||
|
||||
24
package.xml
Normal file
24
package.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<package format="1" xmlns="https://wiki.freecad.org/Package_Metadata">
|
||||
<name>freecad.gears workbench</name>
|
||||
<description>A gear workbench for FreeCAD</description>
|
||||
<version>1.0</version>
|
||||
<date>2022-02-07</date>
|
||||
<maintainer email="sppedflyer@gmail.com">looooo</maintainer>
|
||||
<license file="LICENSE">GPL 3</license>
|
||||
<url type="repository" branch="develop">https://github.com/looooo/freecad.gears</url>
|
||||
<url type="bugtracker">https://github.com/looooo/freecad.gears/issues</url>
|
||||
<url type="documentation">https://wiki.freecad.org/FCGear_Workbench</url>
|
||||
<icon>freecad/gears/icons/gearworkbench.svg</icon>
|
||||
|
||||
<content>
|
||||
<workbench>
|
||||
<classname>GearWorkbench</classname>
|
||||
<subdirectory>./</subdirectory>
|
||||
<freecadmin>0.19</freecadmin>
|
||||
<tag>gear</tag>
|
||||
<tag>gears</tag>
|
||||
</workbench>
|
||||
</content>
|
||||
|
||||
</package>
|
||||
@@ -1,22 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * 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 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 Library General Public License for more details. *
|
||||
# * 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 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 *
|
||||
# * You should have received a copy of the GNU General Public License *
|
||||
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
__version__ = "0.0.3"
|
||||
__version__ = "0.0.4"
|
||||
@@ -1,21 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * 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 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 Library General Public License for more details. *
|
||||
# * 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 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 *
|
||||
# * You should have received a copy of the GNU General Public License *
|
||||
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * 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 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 Library General Public License for more details. *
|
||||
# * 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 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 *
|
||||
# * You should have received a copy of the GNU General Public License *
|
||||
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
@@ -33,6 +30,7 @@ class BevelTooth(object):
|
||||
self.z = z
|
||||
self.clearance = clearance
|
||||
self.backlash = backlash
|
||||
self.angular_backlash = backlash / (z * module / 2)
|
||||
self.module = module
|
||||
|
||||
self.involute_end = arccos(
|
||||
@@ -111,7 +109,7 @@ class BevelTooth(object):
|
||||
intersection_point = intersection_line_circle(xy[i], point, r_cut)
|
||||
xy = array([intersection_point] + list(xy[i+1:]))
|
||||
xyz = [[p[0], p[1], 1] for p in xy]
|
||||
backlash_rot = rotation3D(self.backlash / 4)
|
||||
backlash_rot = rotation3D(self.angular_backlash / 2)
|
||||
xyz = backlash_rot(xyz)
|
||||
return(xyz)
|
||||
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * 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 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 Library General Public License for more details. *
|
||||
# * 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 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 *
|
||||
# * You should have received a copy of the GNU General Public License *
|
||||
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import numpy as np
|
||||
from scipy import optimize as opt
|
||||
|
||||
|
||||
def compute_shifted_gears(m, alpha, t1, t2, x1, x2):
|
||||
@@ -37,10 +33,32 @@ def compute_shifted_gears(m, alpha, t1, t2, x1, x2):
|
||||
Returns:
|
||||
(float, float): distance between gears [length], pressure angle of the assembly [rad]
|
||||
"""
|
||||
def inv(x): return np.tan(x) - x
|
||||
def inv(x):
|
||||
return np.tan(x) - x
|
||||
|
||||
inv_alpha_w = inv(alpha) + 2 * np.tan(alpha) * (x1 + x2) / (t1 + t2)
|
||||
|
||||
def root_inv(x): return inv(x) - inv_alpha_w
|
||||
alpha_w = opt.fsolve(root_inv, 0.)
|
||||
def root_inv(x):
|
||||
return inv(x) - inv_alpha_w
|
||||
|
||||
def d_root_inv(x):
|
||||
return 1. / np.cos(x) - 1
|
||||
|
||||
alpha_w = find_root(alpha, root_inv, d_root_inv)
|
||||
dist = m * (t1 + t2) / 2 * np.cos(alpha) / np.cos(alpha_w)
|
||||
return dist, alpha_w
|
||||
|
||||
|
||||
def find_root(x0, f, df, epsilon=2e-10, max_iter=100):
|
||||
x_n = x0
|
||||
for i in range(max_iter):
|
||||
f_xn = f(x_n)
|
||||
if abs(f_xn) < epsilon:
|
||||
return x_n
|
||||
else:
|
||||
df_xn = df(x_n)
|
||||
if df_xn == 0:
|
||||
return None
|
||||
else:
|
||||
x_n = x_n - f_xn / df_xn / 2 # adding (/ 2) to avoid oscillation
|
||||
return None
|
||||
@@ -1,21 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * 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 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 Library General Public License for more details. *
|
||||
# * 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 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 *
|
||||
# * You should have received a copy of the GNU General Public License *
|
||||
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
@@ -25,13 +22,14 @@ from ._functions import rotation, reflection
|
||||
|
||||
|
||||
class CycloidTooth():
|
||||
def __init__(self, z1=5, z2=5, z=14, m=5, clearance=0.12, backlash=0.00):
|
||||
def __init__(self, z1=5, z2=5, z=14, m=5, clearance=0.25, backlash=0.00, head=0.0):
|
||||
self.m = m
|
||||
self.z = z
|
||||
self.clearance = clearance
|
||||
self.backlash = backlash
|
||||
self.z1 = z1
|
||||
self.z2 = z2
|
||||
self.head = head
|
||||
self._calc_gear_factors()
|
||||
|
||||
def _calc_gear_factors(self):
|
||||
@@ -39,9 +37,10 @@ class CycloidTooth():
|
||||
self.d2 = self.z2 * self.m
|
||||
self.phi = self.m * pi
|
||||
self.d = self.z * self.m
|
||||
self.da = self.d + 2*self.m
|
||||
self.di = self.d - 2*self.m - self.clearance * self.m
|
||||
self.da = self.d + 2 * (1 + self.head) * self.m
|
||||
self.di = self.d - 2 * (1 + self.clearance) * self.m
|
||||
self.phipart = 2 * pi / self.z
|
||||
self.angular_backlash = self.backlash / (self.d / 2)
|
||||
|
||||
def epicycloid_x(self):
|
||||
def func(t):
|
||||
@@ -94,7 +93,7 @@ class CycloidTooth():
|
||||
pts_outer = transpose([pts_outer_x, pts_outer_y])
|
||||
pts_inner = transpose([pts_inner_x, pts_inner_y])
|
||||
pts1 = vstack([pts_inner[:-2], pts_outer])
|
||||
rot = rotation(self.phipart / 4 - self.backlash)
|
||||
rot = rotation(self.phipart / 4 - self.angular_backlash / 2)
|
||||
pts1 = rot(pts1)
|
||||
ref = reflection(0.)
|
||||
pts2 = ref(pts1)[::-1]
|
||||
@@ -103,5 +102,5 @@ class CycloidTooth():
|
||||
|
||||
def _update(self):
|
||||
self.__init__(m=self.m, z=self.z, z1=self.z1, z2=self.z2,
|
||||
clearance=self.clearance, backlash=self.backlash)
|
||||
clearance=self.clearance, backlash=self.backlash, head=self.head)
|
||||
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * 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 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 Library General Public License for more details. *
|
||||
# * 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 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 *
|
||||
# * You should have received a copy of the GNU General Public License *
|
||||
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
@@ -72,6 +69,7 @@ class InvoluteTooth():
|
||||
self.involute_rot2 = 1 / self.z * \
|
||||
(pi / 2 + 2 * self.shift * tan(self.pressure_angle_t))
|
||||
self.involute_rot = self.involute_rot1 + self.involute_rot2
|
||||
self.angular_backlash = self.backlash / (self.d / 2)
|
||||
self.involute_start = 0.
|
||||
if self.dg <= self.df:
|
||||
self.involute_start = sqrt(self.df ** 2 - self.dg ** 2) / self.dg
|
||||
@@ -84,7 +82,7 @@ class InvoluteTooth():
|
||||
y = array(list(map(fy, pts)))
|
||||
xy = transpose([x, y])
|
||||
rotate = rotation(
|
||||
self.undercut_rot + self.phipart / 2 - self.backlash / 4)
|
||||
self.undercut_rot + self.phipart / 2 - self.angular_backlash / 2)
|
||||
xy = rotate(xy)
|
||||
return(array(xy))
|
||||
|
||||
@@ -94,7 +92,7 @@ class InvoluteTooth():
|
||||
x = array(list(map(fx, pts)))
|
||||
fy = self.involute_function_y()
|
||||
y = array(list(map(fy, pts)))
|
||||
rot = rotation(self.involute_rot - self.backlash / 4)
|
||||
rot = rotation(self.involute_rot - self.angular_backlash / 2)
|
||||
xy = rot(transpose(array([x, y])))
|
||||
return(xy)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user