Files
create/src/Mod/PartDesign/fcgear/svggear.py
Jonas Bähr 4f56b2654e PD: Expose new gear properties to the SVG generator
This little script has proven to be a vauable debugging aid, so it got
some love. All the new properties from #8184 can now be set, together
with the option to generate internal gears.
2023-02-13 02:31:28 +01:00

116 lines
4.6 KiB
Python

# (c) 2014 David Douard <david.douard@gmail.com>
#
# 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.
#
# FCGear 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 FCGear; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
import itertools
from involute import CreateExternalGear, CreateInternalGear, rotate
class SVGWireBuilder(object):
def __init__(self):
self.theta = 0.0
self.pos = None
self.svg = []
def move(self, p):
p = rotate(p, self.theta)
self.svg.append('M %s,%s' % (p[0], p[1]))
self.pos = p
def line(self, p):
p = rotate(p, self.theta)
self.svg.append('L %s,%s' % (p[0], p[1]))
self.pos = p
def arc(self, p, r, sweep):
p = rotate(p, self.theta)
self.svg.append('A %s,%s 0,0,%s %s,%s' % (r, r, str(sweep), p[0], p[1]))
self.pos = p
def curve(self, *points):
"""Add a Bezier curve from self.pos to points[-1]
every other points are the control points of the Bezier curve (which
will thus be of degree len(points) )
"""
assert len(points) == 3
points = [rotate(p, self.theta) for p in points]
self.svg.append('C %s,%s %s,%s %s,%s' % tuple(itertools.chain(*points)))
self.pos = points[-1]
def close(self):
self.svg.append('Z')
if __name__ == '__main__':
from optparse import OptionParser
p = OptionParser(
usage="usage: %prog [options] [[MODULE] NUMER_OF_TEETH]",
description=("Generates the outline of a metric, involute gear. "
"Prints out an SVG path. "
"This is mainly a debugging tool to quickly inspect the gear visually. "
"For this, online tools like https://yqnn.github.io/svg-path-editor/ are handy. "
"Most of the time it's enough to just use the first 20 lines or so, e.g.:\n\t"
"%prog -z50 | head -n20 | pbcopy"))
p.add_option('-z', '--numer-of-teeth',
help="The number of teeth for the gear.",
metavar='NUMER_OF_TEETH', type='int')
p.add_option('-m', '--module',
help="The metric module, in svg user unit, i.e. unit-less. [default: %default]",
metavar='MODULE', type='float', default=1)
p.add_option('-p', '--pressure-angle',
help="The pressure angle, in degree. [default: %default]",
metavar='PRESSURE_ANGLE', type='float', default=20)
p.add_option('-i', '--internal',
help=("Generates an internal gear, i.e. the addednum points towards the center "
"and the root fillet is at the outside. [default: %default]"),
action='store_true', default=False)
p.add_option('-a', '--addendum',
help=("The tooth height above the pitch line, normalized by the MODULE. "
"[default: %default]"),
metavar='ADDENDUM_COEFFICIENT', type='float', default=1)
p.add_option('-d', '--dedendum',
help=("The tooth height from the root to the pitch line, normalized by the MODULE. "
"[default: %default]"),
metavar='DEDENDUM_COEFFICIENT', type='float', default=1.25)
p.add_option('-f', '--fillet-radius',
help=("The radius of the root fillet, normalized by the MODULE. "
"[default: %default]"),
metavar='FILLET_RADIUS_COEFFICIENT', type='float', default=0.38)
opts, args = p.parse_args()
errors = []
if len(args) == 1:
opts.numer_of_teeth = int(args[0])
if len(args) == 2:
opts.module = float(args[0])
opts.numer_of_teeth = int(args[1])
if len(args) > 2:
errors.append("Too many arguments.")
if opts.numer_of_teeth is None:
errors.append("No number of teeth given.")
if len(errors) > 0:
errors.append("Try --help for more info.")
p.error("\n".join(errors))
w = SVGWireBuilder()
generator_func = CreateInternalGear if opts.internal else CreateExternalGear
generator_func(w, opts.module, opts.numer_of_teeth, opts.pressure_angle,
addCoeff=opts.addendum, dedCoeff=opts.dedendum,
filletCoeff=opts.fillet_radius)
for l in w.svg:
print(l)