diff --git a/plugins/gear_generator/gear_generator/__init__.py b/plugins/gear_generator/gear_generator/__init__.py index c313e3a..15b6a64 100644 --- a/plugins/gear_generator/gear_generator/__init__.py +++ b/plugins/gear_generator/gear_generator/__init__.py @@ -1 +1 @@ -from .main import * \ No newline at end of file +from .main import * diff --git a/plugins/gear_generator/gear_generator/helpers.py b/plugins/gear_generator/gear_generator/helpers.py index c1c7b80..858e0ec 100644 --- a/plugins/gear_generator/gear_generator/helpers.py +++ b/plugins/gear_generator/gear_generator/helpers.py @@ -1,6 +1,7 @@ from math import cos, sin, radians, acos import cadquery as cq + def involute(r: float, sign: int = 1): """ Defines an involute curve to create the flanks of the involute gears @@ -12,12 +13,15 @@ def involute(r: float, sign: int = 1): Returns: x,y -> tuple() : 2-tuple of x and y coordinates in space """ + def curve(t): - x = r*(cos(t) + t*sin(t)) - y = r*(sin(t) - t*cos(t)) - return x,sign*y + x = r * (cos(t) + t * sin(t)) + y = r * (sin(t) - t * cos(t)) + return x, sign * y + return curve + def spherical_involute(delta, delta_b, R): """ Equation of the spherical involute that lies on a sphere @@ -30,12 +34,15 @@ def spherical_involute(delta, delta_b, R): Returns: x,y,z -> tuple() : 3-tuple of x and y and z coordinates in space """ - theta = acos(cos(delta)/cos(delta_b))/sin(delta_b) - x = R*cos(theta*sin(delta_b))*sin(delta_b)*cos(theta) - R*sin(theta*sin(delta_b))* - sin(theta) - y = R*cos(theta*sin(delta_b))*sin(delta_b)*sin(theta) - R*sin(theta*sin(delta_b))* cos(theta) - z = R*cos(theta*sin(delta_b))*cos(delta_b) - return x,y,z - + theta = acos(cos(delta) / cos(delta_b)) / sin(delta_b) + x = R * cos(theta * sin(delta_b)) * sin(delta_b) * cos(theta) - R * sin( + theta * sin(delta_b) + ) * -sin(theta) + y = R * cos(theta * sin(delta_b)) * sin(delta_b) * sin(theta) - R * sin( + theta * sin(delta_b) + ) * cos(theta) + z = R * cos(theta * sin(delta_b)) * cos(delta_b) + return x, y, z def rotate_vector_2D(vector: cq.Vector, angle: float): @@ -43,6 +50,6 @@ def rotate_vector_2D(vector: cq.Vector, angle: float): Rotates a 2D cq.Vector `vector`by an angle of `angle` in degrees """ angle = radians(angle) - x = cos(angle)*vector.x - sin(angle)*vector.y - y = sin(angle)*vector.x + cos(angle)*vector.y - return cq.Vector((x,y)) \ No newline at end of file + x = cos(angle) * vector.x - sin(angle) * vector.y + y = sin(angle) * vector.x + cos(angle) * vector.y + return cq.Vector((x, y)) diff --git a/plugins/gear_generator/gear_generator/main.py b/plugins/gear_generator/gear_generator/main.py index 0c58d07..f4bcced 100644 --- a/plugins/gear_generator/gear_generator/main.py +++ b/plugins/gear_generator/gear_generator/main.py @@ -2,6 +2,7 @@ from math import pi, cos, sin, tan, sqrt, degrees, radians, atan2, atan, acos, asin from .helpers import involute, spherical_involute, rotate_vector_2D + class BaseGear: """Base gear class This class stores attributes that are shared by any types of gear @@ -28,11 +29,11 @@ def __init__(self, m: float, z: int, b: float, alpha: float, helix_angle: float) z : gear number of teeth alpha : gear pressure angle (degrees) helix_angle : helix angle for helical bevel gear (degrees) - """ - self.m = m - self.b = b - self.z = z - self.p = pi*self.m + """ + self.m = m + self.b = b + self.z = z + self.p = pi * self.m self.r_p = m * z / 2 self.alpha = radians(alpha) self.helix_angle = radians(helix_angle) @@ -59,10 +60,23 @@ class BevelGear(BaseGear): r_f : tooth root circle radius theta_p : angle of rotation of the involute curve to have tooth tickness = p at pitch circle """ + __doc__ = BaseGear.__doc__ + __doc__ - def __init__(self, m: float, z: int , b: int, delta_p: float, R: float, clearance: float = None, alpha: float = 15, helix_angle: float = 0, right_handed: bool = True, N: int = 4): - + def __init__( + self, + m: float, + z: int, + b: int, + delta_p: float, + R: float, + clearance: float = None, + alpha: float = 15, + helix_angle: float = 0, + right_handed: bool = True, + N: int = 4, + ): + """ Args: m : gear modulus @@ -78,54 +92,87 @@ def __init__(self, m: float, z: int , b: int, delta_p: float, R: float, clearanc """ if clearance is None: - self.clearance = m*z/10 - else : + self.clearance = m * z / 10 + else: self.clearance = clearance super().__init__(m, z, b, alpha, helix_angle) self.right_handed = right_handed self.N = N - self.delta_p = radians(delta_p) #pitch cone angle + self.delta_p = radians(delta_p) # pitch cone angle self.R = R self.R_min = R - b - self.delta_b = asin(sin(self.delta_p)*cos(self.alpha)) + self.delta_b = asin(sin(self.delta_p) * cos(self.alpha)) self.r_b = R * sin(self.delta_b) self.theta_a = atan2(m, R) - self.theta_f = atan2(1.25*m, R) + self.theta_f = atan2(1.25 * m, R) self.delta_a = self.delta_p + self.theta_a self.delta_f = self.delta_p - self.theta_f - self.r_a = R*sin(self.delta_a) - self.r_f = R*sin(self.delta_f) - self.theta_p = self.p/(R*sin(self.delta_p))/4 #angle of rotation of the involute curve to have tooth tickness = p at pitch circle + self.r_a = R * sin(self.delta_a) + self.r_f = R * sin(self.delta_f) + self.theta_p = ( + self.p / (R * sin(self.delta_p)) / 4 + ) # angle of rotation of the involute curve to have tooth tickness = p at pitch circle def make_tooth_profile(self, radius): """ This method creates the tooth profile wire that lie on a sphere of radius `radius` """ - right_involute = cq.Workplane().parametricCurve(lambda delta : spherical_involute(delta, self.delta_b, radius), start = self.delta_b, stop = self.delta_a).rotate((0,0,0),(0,0,1),-degrees(self.theta_p)) - left_involute = right_involute.mirror("ZX") + right_involute = ( + cq.Workplane() + .parametricCurve( + lambda delta: spherical_involute(delta, self.delta_b, radius), + start=self.delta_b, + stop=self.delta_a, + ) + .rotate((0, 0, 0), (0, 0, 1), -degrees(self.theta_p)) + ) + left_involute = right_involute.mirror("ZX") right_top_pt = right_involute.val().endPoint() left_top_pt = left_involute.val().endPoint() right_bot_pt = right_involute.val().startPoint() left_bot_pt = left_involute.val().startPoint() - end_point = right_top_pt-left_top_pt + end_point = right_top_pt - left_top_pt if right_top_pt.y > 0: - raise ValueError("Inputed parameters leads to undefined tooth geometry.\nThis is due to either : too high gear ratio (z1/z2), too high pressure angle (alpha) or too big tooth face width (b).\ - \nIn general higher gear ratio needs lower pressure angle to obtain to good tooth geometry.") - top_arc = cq.Workplane("XY", origin=left_top_pt.toTuple()).radiusArc(end_point.toTuple(), self.r_a) - pos = (0,0,radius*cos(self.delta_f)) - - if self.r_b <= self.r_f: #if undercut - bot_arc = cq.Edge.makeCircle(self.r_f, pos, (0,0,1), angle1 = -self.theta_p, angle2 = self.theta_p) - tooth_profile = cq.Wire.assembleEdges([right_involute.val(), top_arc.val(), left_involute.val(), bot_arc]) - else: - bot_arc = cq.Edge.makeCircle(tan(self.delta_f)*(radius*cos(self.delta_f)), pos, (0,0,1), angle1=-degrees(self.theta_p), angle2=degrees(self.theta_p)) + raise ValueError( + "Inputed parameters leads to undefined tooth geometry.\nThis is due to either : too high gear ratio (z1/z2), too high pressure angle (alpha) or too big tooth face width (b).\ + \nIn general higher gear ratio needs lower pressure angle to obtain to good tooth geometry." + ) + top_arc = cq.Workplane("XY", origin=left_top_pt.toTuple()).radiusArc( + end_point.toTuple(), self.r_a + ) + pos = (0, 0, radius * cos(self.delta_f)) + + if self.r_b <= self.r_f: # if undercut + bot_arc = cq.Edge.makeCircle( + self.r_f, pos, (0, 0, 1), angle1=-self.theta_p, angle2=self.theta_p + ) + tooth_profile = cq.Wire.assembleEdges( + [right_involute.val(), top_arc.val(), left_involute.val(), bot_arc] + ) + else: + bot_arc = cq.Edge.makeCircle( + tan(self.delta_f) * (radius * cos(self.delta_f)), + pos, + (0, 0, 1), + angle1=-degrees(self.theta_p), + angle2=degrees(self.theta_p), + ) left_bot_arc_pt = bot_arc.endPoint() right_bot_arc_pt = bot_arc.startPoint() - left_bot_line = cq.Edge.makeLine(left_bot_arc_pt,left_bot_pt) - right_bot_line = cq.Edge.makeLine(right_bot_arc_pt,right_bot_pt) - - tooth_profile = cq.Wire.assembleEdges([right_involute.val(), top_arc.val(), left_involute.val(), left_bot_line, bot_arc, right_bot_line]) + left_bot_line = cq.Edge.makeLine(left_bot_arc_pt, left_bot_pt) + right_bot_line = cq.Edge.makeLine(right_bot_arc_pt, right_bot_pt) + print(type(right_involute.val()).__name__) + tooth_profile = cq.Wire.assembleEdges( + [ + right_involute.edges().val(), + top_arc.edges().val(), + left_involute.edges().val(), + left_bot_line, + bot_arc, + right_bot_line, + ] + ) return tooth_profile @@ -134,41 +181,62 @@ def make_tooth(self): This function creates the tooth solid from lofting tooth section wires. If the gear is standard, loft from wire at R radius to wire at R_min radius. If the gear is helical, creates intermediary tooth profiles rotated along the cone height. Finally loft by all the tooth sections. - """ + """ N = self.N - R_sphere = cq.Solid.makeSphere(self.R,angleDegrees1=-90, angleDegrees2=90).rotate((0,0,0),(0,0,1),90) - Rmin_sphere = cq.Solid.makeSphere(self.R_min,angleDegrees1=-90, angleDegrees2=90).rotate((0,0,0),(0,0,1),90) - outer = self.make_tooth_profile(self.R*1.2) - inner = self.make_tooth_profile(self.R_min*0.8) - splitter = cq.Solid.makeLoft([outer,inner]) - - closing_face1 = R_sphere.Faces()[0].split(splitter).Faces()[1] # cuts a sphere to retrieve the surface enclosed by tooth profile wire - closing_face2 = Rmin_sphere.Faces()[0].split(splitter).Faces()[1] # cuts a sphere to retrieve the surface enclosed by tooth profile wire - + R_sphere = cq.Solid.makeSphere( + self.R, angleDegrees1=-90, angleDegrees2=90 + ).rotate((0, 0, 0), (0, 0, 1), 90) + Rmin_sphere = cq.Solid.makeSphere( + self.R_min, angleDegrees1=-90, angleDegrees2=90 + ).rotate((0, 0, 0), (0, 0, 1), 90) + outer = self.make_tooth_profile(self.R * 1.2) + inner = self.make_tooth_profile(self.R_min * 0.8) + splitter = cq.Solid.makeLoft([outer, inner]) + + closing_face1 = ( + R_sphere.Faces()[0].split(splitter).Faces()[1] + ) # cuts a sphere to retrieve the surface enclosed by tooth profile wire + closing_face2 = ( + Rmin_sphere.Faces()[0].split(splitter).Faces()[1] + ) # cuts a sphere to retrieve the surface enclosed by tooth profile wire + sections = [] - dr = (self.b)/N - dangle = degrees(self.b * tan(self.helix_angle) / self.r_p) / N + dr = (self.b) / N + dangle = degrees(self.b * tan(self.helix_angle) / self.r_p) / N - if self.helix_angle == 0: - tooth = cq.Solid.makeLoft([closing_face1.Wires()[0], closing_face2.Wires()[0]]) - else : + if self.helix_angle == 0: + tooth = cq.Solid.makeLoft( + [closing_face1.Wires()[0], closing_face2.Wires()[0]] + ) + else: if self.right_handed: rot_dir = -1 else: rot_dir = 1 - for i in range(N+1): - sections.append(self.make_tooth_profile(self.R-dr*i).rotate((0,0,0),(0,0,1),rot_dir*dangle*i)) + for i in range(N + 1): + sections.append( + self.make_tooth_profile(self.R - dr * i).rotate( + (0, 0, 0), (0, 0, 1), rot_dir * dangle * i + ) + ) sides = cq.Solid.makeLoft(sections) - closing_face2 = Rmin_sphere.Faces()[0].split(sides).Faces()[1] # cuts a sphere to retrieve the surface enclosed by tooth profile wire - sections[0] = closing_face1.Wires()[0]# remove the first and last section since we will loft from the closing face wires + closing_face2 = ( + Rmin_sphere.Faces()[0].split(sides).Faces()[1] + ) # cuts a sphere to retrieve the surface enclosed by tooth profile wire + sections[0] = closing_face1.Wires()[ + 0 + ] # remove the first and last section since we will loft from the closing face wires sections[-1] = closing_face2.Wires()[0] - - sides = cq.Solid.makeLoft(sections) # There is a bug here, the solid isnt valid for unknown reasons. - shell = cq.Shell.makeShell([closing_face1, sides, closing_face2]) # But the workaround is to build a shell from the faces that are valid + sides = cq.Solid.makeLoft( + sections + ) # There is a bug here, the solid isnt valid for unknown reasons. + shell = cq.Shell.makeShell( + [closing_face1, sides, closing_face2] + ) # But the workaround is to build a shell from the faces that are valid tooth = cq.Solid.makeSolid(shell) - + return tooth def build(self): @@ -181,24 +249,28 @@ def build(self): tooths = [] tooth = self.make_tooth() - for i in range(1,self.z+1): - angle = i*360/self.z - tooths.append(tooth.rotate(cq.Vector(0,0,0),cq.Vector(0,0,1),angle)) + for i in range(1, self.z + 1): + angle = i * 360 / self.z + tooths.append(tooth.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), angle)) comp = cq.Compound.makeCompound(tooths) + self.gear = ( + cq.Workplane("ZX", obj=comp) + .moveTo(self.R_min * cos(self.delta_f), 0) + .vLineTo(self.R_min * sin(self.delta_f)) + .lineTo(self.R * cos(self.delta_f), self.R * sin(self.delta_f)) + .line( + self.clearance * sin(self.delta_p), -self.clearance * cos(self.delta_p) + ) + .vLineTo(0) + .close() + .revolve(axisStart=(0, 0, 0), axisEnd=(1, 0, 0)) + ) + return self.gear + - self.gear = (cq.Workplane("ZX",obj=comp).moveTo(self.R_min*cos(self.delta_f),0) - .vLineTo(self.R_min*sin(self.delta_f)) - .lineTo(self.R*cos(self.delta_f),self.R*sin(self.delta_f)) - .line(self.clearance*sin(self.delta_p), -self.clearance*cos(self.delta_p)) - .vLineTo(0) - .close() - .revolve(axisStart=(0,0,0), axisEnd=(1,0,0)) - ) - return self.gear - -class BevelGearSystem(): +class BevelGearSystem: """Inherits BaseGear class This class compute the right parameters for the creation of a system of 2 bevels gears positioned in a way they can mesh. @@ -216,9 +288,21 @@ class BevelGearSystem(): R : radius of the inscribed sphere at pitch circle radius N : number of tooth sections to interpolate when creating a spiral bevel gear system """ + __doc__ = BaseGear.__doc__ + __doc__ - def __init__(self, m: float, z1: int, z2: int, b: float, clearance1: float = None, clearance2: float = None, helix_angle: float = 0, alpha: float = 15, N: int = 4): + def __init__( + self, + m: float, + z1: int, + z2: int, + b: float, + clearance1: float = None, + clearance2: float = None, + helix_angle: float = 0, + alpha: float = 15, + N: int = 4, + ): """ Args: m : gears modulus (gears can mesh only if they have the same modulus) @@ -233,26 +317,26 @@ def __init__(self, m: float, z1: int, z2: int, b: float, clearance1: float = Non N : number of tooth sections to interpolate when creating a spiral bevel gear system """ - if z1>z2: - z1,z2 = z2,z1 + if z1 > z2: + z1, z2 = z2, z1 if clearance1 == None: - self.clearance1 = m*z1/20 + self.clearance1 = m * z1 / 20 else: self.clearance1 = clearance1 if clearance2 == None: - self.clearance2 = m*z2/20 + self.clearance2 = m * z2 / 20 else: self.clearance2 = clearance2 - self.m = m + self.m = m self.b = b - self.z1 = z1 + self.z1 = z1 self.z2 = z2 - self.delta_p1 = degrees(atan2(z1, z2)) #pitch cone angle - self.delta_p2 = degrees(atan2(z2, z1)) #pitch cone angle - self.R = (m*z2/2)/sin(radians(self.delta_p2)) + self.delta_p1 = degrees(atan2(z1, z2)) # pitch cone angle + self.delta_p2 = degrees(atan2(z2, z1)) # pitch cone angle + self.R = (m * z2 / 2) / sin(radians(self.delta_p2)) self.helix_angle = helix_angle self.alpha = alpha - self.N = N + self.N = N def build(self): """ @@ -261,20 +345,59 @@ def build(self): Returns: pinion, gear -> tuple(cq.Workplane, cq.Workplane) : The pinion and gear bevel gears of the system positionned correctly in space """ - self.pinion = BevelGear(self.m, self.z1, self.b, self.delta_p1, self.R, self.clearance1, helix_angle=self.helix_angle, right_handed=False, alpha=self.alpha, N=self.N) - self.gear = BevelGear(self.m, self.z2, self.b, self.delta_p2, self.R, self.clearance2, helix_angle=self.helix_angle, alpha=self.alpha, N=self.N) + self.pinion = BevelGear( + self.m, + self.z1, + self.b, + self.delta_p1, + self.R, + self.clearance1, + helix_angle=self.helix_angle, + right_handed=False, + alpha=self.alpha, + N=self.N, + ) + self.gear = BevelGear( + self.m, + self.z2, + self.b, + self.delta_p2, + self.R, + self.clearance2, + helix_angle=self.helix_angle, + alpha=self.alpha, + N=self.N, + ) if self.gear.z % 2 == 0: - return self.pinion.build(), self.gear.build().rotate((0,0,0),(0,1,0), 90).rotate((0,0,0),(1,0,0), (360/self.gear.z)/2) + return ( + self.pinion.build(), + self.gear.build() + .rotate((0, 0, 0), (0, 1, 0), 90) + .rotate((0, 0, 0), (1, 0, 0), (360 / self.gear.z) / 2), + ) else: - return self.pinion.build(), self.gear.build().rotate((0,0,0),(0,1,0),90) + return ( + self.pinion.build(), + self.gear.build().rotate((0, 0, 0), (0, 1, 0), 90), + ) + class Gear(BaseGear): """Inherits BaseGear """ + __doc__ = BaseGear.__doc__ + __doc__ - def __init__(self, m: float, z: int, b: float, alpha: float = 20, helix_angle: float = 0, raw: bool = False): + def __init__( + self, + m: float, + z: int, + b: float, + alpha: float = 20, + helix_angle: float = 0, + raw: bool = False, + ): """ Args: m : gear modulus @@ -288,9 +411,9 @@ def __init__(self, m: float, z: int, b: float, alpha: float = 20, helix_angle: f self.raw = raw self.r_a = self.r_p + m - self.r_b = self.r_p*cos(self.alpha) - self.r_f = self.r_p - 1.25*m - + self.r_b = self.r_p * cos(self.alpha) + self.r_f = self.r_p - 1.25 * m + def make_tooth_profile(self): """ Creates a single tooth wire to be rotated to create the full cross section of the gear @@ -298,65 +421,78 @@ def make_tooth_profile(self): Returns: cq.Wire : a wire representing the tooth wire """ - inv = lambda a: tan(a) - a + inv = lambda a: tan(a) - a # angles of interest alpha_inv = inv(self.alpha) - alpha_tip = acos(self.r_b/self.r_a) - alpha_tip_inv = inv(alpha_tip) - a = 90/self.z + degrees(alpha_inv) - a2 = 90/self.z + degrees(alpha_inv)-degrees(alpha_tip_inv) - STOP = sqrt((self.r_a/self.r_b)**2 - 1) + alpha_tip = acos(self.r_b / self.r_a) + alpha_tip_inv = inv(alpha_tip) + a = 90 / self.z + degrees(alpha_inv) + a2 = 90 / self.z + degrees(alpha_inv) - degrees(alpha_tip_inv) + STOP = sqrt((self.r_a / self.r_b) ** 2 - 1) # construct all the profiles left = ( cq.Workplane() - .transformed(rotate=(0,0,a)) - .parametricCurve(involute(self.r_b,-1), start=0, stop = STOP, makeWire=False, N=8) + .transformed(rotate=(0, 0, a)) + .parametricCurve( + involute(self.r_b, -1), start=0, stop=STOP, makeWire=False, N=8 + ) .val() ) - + right = ( cq.Workplane() - .transformed(rotate=(0,0,-a)) - .parametricCurve(involute(self.r_b), start=0, stop = STOP, makeWire=False, N=8) + .transformed(rotate=(0, 0, -a)) + .parametricCurve( + involute(self.r_b), start=0, stop=STOP, makeWire=False, N=8 + ) .val() ) - top = cq.Edge.makeCircle(self.r_a,angle1=-a2, angle2=a2) + top = cq.Edge.makeCircle(self.r_a, angle1=-a2, angle2=a2) p0 = left.startPoint() - p1 = right.startPoint() - side0 = cq.Workplane(origin=p0.toTuple()).hLine(self.r_f-self.r_b).val() - side1 = cq.Workplane(origin=p1.toTuple()).hLine(self.r_f-self.r_b).val() - side2 = side0.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), -360/self.z) + p1 = right.startPoint() + side0 = cq.Workplane(origin=p0.toTuple()).hLine(self.r_f - self.r_b).val() + side1 = cq.Workplane(origin=p1.toTuple()).hLine(self.r_f - self.r_b).val() + side2 = side0.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), -360 / self.z) p_bot_left = side1.endPoint() - p_bot_right = rotate_vector_2D(side0.endPoint(), -360/self.z) + p_bot_right = rotate_vector_2D(side0.endPoint(), -360 / self.z) - bottom = cq.Workplane().moveTo(p_bot_left.x, p_bot_left.y).radiusArc(p_bot_right,self.r_f).val() + bottom = ( + cq.Workplane() + .moveTo(p_bot_left.x, p_bot_left.y) + .radiusArc(p_bot_right, self.r_f) + .val() + ) # single tooth profile - profile = cq.Wire.assembleEdges([left,top,right,side1,bottom, side2]) + profile = cq.Wire.assembleEdges([left, top, right, side1, bottom, side2]) # return cross_section if not self.raw: - profile = profile.fillet2D(0.25*self.m, profile.Vertices()[-3:-1]) + profile = profile.fillet2D(0.25 * self.m, profile.Vertices()[-3:-1]) return profile - def build(self) : + def build(self): """ Creates the gear and returns it in a cq.Workplane """ # complete cross section gear = ( cq.Workplane() - .polarArray(0,0,360,self.z) + .polarArray(0, 0, 360, self.z) .each(lambda loc: self.make_tooth_profile().located(loc)) .consolidateWires() ) if self.helix_angle == 0: - self.gear = gear.extrude(self.b) + self.gear = gear.extrude(self.b, combine=False) else: - self.gear = gear.twistExtrude(self.b, degrees(self.b * tan(self.helix_angle))/self.r_p) + self.gear = gear.twistExtrude( + self.b, + degrees(self.b * tan(self.helix_angle)) / self.r_p, + combine=False, + ) return self.gear diff --git a/plugins/gear_generator/setup.py b/plugins/gear_generator/setup.py index 5255ede..2eb22f6 100644 --- a/plugins/gear_generator/setup.py +++ b/plugins/gear_generator/setup.py @@ -1,44 +1,45 @@ from setuptools import setup, find_packages -version = '1.0.0' # Please update this version number when updating the plugin -plugin_name = 'gear_generator' -description = 'Add classes to create all sort of gears' -long_description = '' -author = 'Romain FERRU' -author_email = 'Romain.ferru@gmail.com' -install_requires = [] # Any dependencies that pip also needs to install to make this plugin work +version = "1.0.0" # Please update this version number when updating the plugin +plugin_name = "gear_generator" +description = "Add classes to create all sort of gears" +long_description = "" +author = "Romain FERRU" +author_email = "Romain.ferru@gmail.com" +install_requires = ( + [] +) # Any dependencies that pip also needs to install to make this plugin work setup( name=plugin_name, version=version, - url='https://github.com/CadQuery/cadquery-plugins', - license='Apache Public License 2.0', + url="https://github.com/CadQuery/cadquery-plugins", + license="Apache Public License 2.0", author=author, author_email=author_email, description=description, long_description=long_description, - packages=find_packages(where='gear_generator'), + packages=find_packages(where="gear_generator"), install_requires=install_requires, include_package_data=True, zip_safe=False, - platforms='any', - test_suite='tests', - + platforms="any", + test_suite="tests", classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Intended Audience :: End Users/Desktop', - 'Intended Audience :: Information Technology', - 'Intended Audience :: Science/Research', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: POSIX', - 'Operating System :: MacOS', - 'Operating System :: Unix', - 'Programming Language :: Python', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: Internet', - 'Topic :: Scientific/Engineering' - ] + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: End Users/Desktop", + "Intended Audience :: Information Technology", + "Intended Audience :: Science/Research", + "Intended Audience :: System Administrators", + "License :: OSI Approved :: Apache Software License", + "Operating System :: POSIX", + "Operating System :: MacOS", + "Operating System :: Unix", + "Programming Language :: Python", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Internet", + "Topic :: Scientific/Engineering", + ], ) diff --git a/tests/test_gear_generator.py b/tests/test_gear_generator.py index aebbf8d..fd6c2f8 100644 --- a/tests/test_gear_generator.py +++ b/tests/test_gear_generator.py @@ -3,6 +3,7 @@ from unittest import TestCase from math import sin, radians + class TestGearGenerator(TestCase): def test_bevel_gear(self): """ @@ -12,22 +13,23 @@ def test_bevel_gear(self): """ m = 1.5 z = 16 - b = 6 + b = 6 delta = 45 - R = (m*z/2) / sin(radians(delta)) + R = (m * z / 2) / sin(radians(delta)) alpha = 20 helix_angle = 20 clearance = 6 - gear1 = BevelGear(m, z, b, delta, R, alpha = alpha, clearance = clearance).build() - gear2 = BevelGear(m, z, b, delta, R, alpha = alpha, clearance = clearance, helix_angle=helix_angle).build() - + gear1 = BevelGear(m, z, b, delta, R, alpha=alpha, clearance=clearance).build() + gear2 = BevelGear( + m, z, b, delta, R, alpha=alpha, clearance=clearance, helix_angle=helix_angle + ).build() + self.assertTrue(gear1.val().isValid()) - self.assertAlmostEqual(gear1.val().Volume(),2505.7966225157024,1) + self.assertAlmostEqual(gear1.val().Volume(), 2505.7966225157024, 1) self.assertTrue(gear2.val().isValid()) - self.assertAlmostEqual(gear1.val().Volume(),2505.7531046471067,1) - + self.assertAlmostEqual(gear1.val().Volume(), 2505.7531046471067, 1) def test_bevel_gear_system(self): """ @@ -43,17 +45,28 @@ def test_bevel_gear_system(self): helix_angle = 20 clearance = 3 - pinion1, gear1 = BevelGearSystem(m, z1, z2, b, clearance1 = clearance, clearance2= clearance, alpha=alpha).build() + pinion1, gear1 = BevelGearSystem( + m, z1, z2, b, clearance1=clearance, clearance2=clearance, alpha=alpha + ).build() self.assertTrue(pinion1.val().isValid()) self.assertTrue(gear1.val().isValid()) - self.assertAlmostEqual(pinion1.val().Volume(),483.3443067836134,1) - self.assertAlmostEqual(gear1.val().Volume(),1126.5921554741049,1) + self.assertAlmostEqual(pinion1.val().Volume(), 483.3443067836134, 1) + self.assertAlmostEqual(gear1.val().Volume(), 1126.5921554741049, 1) - pinion2, gear2 = BevelGearSystem(m, z1, z2, b, clearance1 = clearance, clearance2= clearance, helix_angle=helix_angle, alpha=alpha).build() + pinion2, gear2 = BevelGearSystem( + m, + z1, + z2, + b, + clearance1=clearance, + clearance2=clearance, + helix_angle=helix_angle, + alpha=alpha, + ).build() self.assertTrue(pinion2.val().isValid()) self.assertTrue(gear2.val().isValid()) - self.assertAlmostEqual(pinion2.val().Volume(),483.3523144907097,1) - self.assertAlmostEqual(gear2.val().Volume(),1126.605502545581,1) + self.assertAlmostEqual(pinion2.val().Volume(), 483.3523144907097, 1) + self.assertAlmostEqual(gear2.val().Volume(), 1126.605502545581, 1) def test_gear(self): """ @@ -67,12 +80,12 @@ def test_gear(self): alpha = 14 helix_angle = 35 - gear1 = Gear(m, z, b, alpha=alpha, raw = False).build() + gear1 = Gear(m, z, b, alpha=alpha, raw=False).build() self.assertTrue(gear1.val().isValid()) - self.assertTrue((gear1.val().Volume() > 10113 - 70 and gear1.val().Volume() < 10113 + 70)) + self.assertTrue( + (gear1.val().Volume() > 10113 - 70 and gear1.val().Volume() < 10113 + 70) + ) - gear2 = Gear(m, z, b, alpha=alpha, helix_angle = helix_angle, raw = True).build() + gear2 = Gear(m, z, b, alpha=alpha, helix_angle=helix_angle, raw=True).build() self.assertTrue(gear2.val().isValid()) - self.assertAlmostEqual(gear2.val().Volume(),10033.574314576623,1) - - + self.assertAlmostEqual(gear2.val().Volume(), 10033.574314576623, 1)