Created
February 11, 2012 03:55
-
-
Save thehans/1796019 to your computer and use it in GitHub Desktop.
Helper functions for improving FreeCAD's Python API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math as _math | |
from math import ceil, exp, floor, log as ln, log10 as log, pow, sqrt | |
from FreeCAD import Base | |
import Part | |
# Trigonometric wrappers | |
def acos(x): | |
"""Return the arc cosine of x, in degrees.""" | |
return _math.degrees(_math.acos(x)) | |
def asin(x): | |
"""Return the arc sine of x, in degrees.""" | |
return _math.degrees(_math.asin(x)) | |
def atan(x): | |
"""Return the arc tangent of x, in degrees.""" | |
return _math.degrees(_math.atan(x)) | |
def atan2(x, y): | |
"""Return atan(y / x), in degrees. | |
The result is between -pi and pi. The vector in the plane from the origin to point (x, y) makes this angle with the positive X axis. | |
The point of atan2() is that the signs of both inputs are known to it, so it can compute the correct quadrant for the angle. | |
For example, atan(1) and atan2(1, 1) are both 45 degrees, but atan2(-1, -1) is -135 degrees.""" | |
return _math.degrees(_math.atan2(x, y)) | |
def sin(x): | |
"""Return the sine of x degrees.""" | |
return _math.sin(_math.radians(x)) | |
def cos(x): | |
"""Return the cosine of x degrees.""" | |
return _math.cos(_math.radians(x)) | |
def tan(x): | |
"""Return the tangent of x degrees.""" | |
return _math.tan(_math.radians(x)) | |
# convenience functions | |
def show(*args): | |
"""Show shapes in document. | |
Accepts a variable length argument list""" | |
for arg in args: | |
Part.show(arg) | |
def vector(x, default=None): | |
"""Create a Base.Vector object from a given sequence x.""" | |
if x is None: | |
if default is None: | |
return | |
x = default | |
if isinstance(x, Base.Vector): | |
return x | |
else: | |
return Base.Vector(*x) | |
# CSG with variable length argument lists | |
def difference(*args): | |
"""Return the difference of two or more shapes | |
Accepts a variable number of arguments""" | |
if len(args) > 0: | |
return reduce(lambda x,y: x.cut(y), args) | |
def union(*args): | |
"""Return the union of two or more shapes | |
Accepts a variable number of arguments""" | |
if len(args) > 0: | |
return reduce(lambda x,y: x.fuse(y), args) | |
def intersection(*args): | |
"""Return the intersetion of two or more shapes | |
Accepts a variable number of arguments""" | |
if len(args) > 0: | |
return reduce(lambda x,y: x.common(y), args) | |
#Part generators | |
def cylinder(r=1, h=1, pnt=None, dir=None, angle=None): | |
"""Create a cylinder shape. | |
r: Number representing cylinder radius, default 1 | |
h: Number representing the cylinder height, default 1 | |
pnt: List or tuple specifies the center point from which the cylinder is created. default (0,0,0) | |
dir: List or tuple specifies the direction which the cylinder faces. default (0,0,1) | |
angle: Number representing angle in degrees for cylinder section. default 360 | |
""" | |
pnt = vector(pnt, (0,0,0)) | |
dir = vector(dir, (0,0,1)) | |
if angle is None: | |
angle = 360 | |
return Part.makeCylinder(r,h,pnt,dir, angle) | |
def box(l=1,w=1,h=1,pnt=None,dir=None): | |
"""Create a box/cuboid shape. | |
l: Number representing length of box, default 1 | |
w: Number representing width of box, default 1 | |
l: Number representing height of box, default 1 | |
pnt: List or tuple specifies the center point from which the box is created. default (0,0,0) | |
dir: List or tuple specifies the direction which the box faces. default (0,0,1) | |
""" | |
pnt = vector(pnt, (0,0,0)) | |
dir = vector(dir, (0,0,1)) | |
return Part.makeBox(l,w,h,pnt,dir) | |
def sphere(r=1, pnt=None, dir=None, angle1=-90, angle2=90, angle3=360): | |
"""Create a sphere shape. | |
r: Number representing sphere radius, default 1 | |
pnt: List or tuple specifies the center point from which the sphere is created. default (0,0,0) | |
dir: List or typle specifies the direction which the sphere faces. default (0,0,1) | |
angle1: Number for vertical minimum angle of sphere in degrees. default -90 | |
angle2: Number for vertical maximum angle of sphere in degrees. default 90 | |
angle3: Number for angle of the sphere diameter in degrees. default 360 | |
""" | |
pnt = vector(pnt, (0,0,0)) | |
dir = vector(dir, (0,0,1)) | |
return Part.makeSphere(r, pnt, dir, angle1, angle2, angle3) | |
def cone(r1=1, r2=0, h=1, pnt=None, dir=None, angle=360): | |
"""Create a cone shape. | |
r1: Number representing lower cone radius, default 1 | |
r1: Number representing upper cone radius, default 0 | |
pnt: List or tuple specifies the center point from which the cone is created. default (0,0,0) | |
dir: List or typle specifies the direction which the cone faces. default (0,0,1) | |
angle: Number for angle of cone section in degrees. default 360 | |
""" | |
pnt = vector(pnt, (0,0,0)) | |
dir = vector(dir, (0,0,1)) | |
return Part.makeCone(r1, r2, h, pnt, dir, angle) | |
def torus(r1=2, r2=1, pnt=None, dir=None, angle1=0, angle2=360, angle=360): | |
"""Create a donut shape. | |
Consider a torus as small circle sweeping along a big circle. | |
r1: Number for radius of big circle, default 2 | |
r2: Number for radius of small circle, default 1 | |
pnt: List or tuple specifies the center point from which the sphere is created. default (0,0,0) | |
dir: List or typle specifies the direction which the sphere faces. default (0,0,1) | |
angle1: Number for start angle of small circle in degrees. default 0 | |
angle2: Number for end angle of small circle in degrees. default 360 | |
angle: Number for angle of the big circle section in degrees. default 360 | |
""" | |
pnt = vector(pnt, (0,0,0)) | |
dir = vector(dir, (0,0,1)) | |
return Part.makeTorus(r1, r2, pnt, dir, angle1, angle2, angle) | |
def polygon(points, makeFace=True, extrude=None): | |
"""Create a torus/donut shape. | |
Consider a torus as small circle sweeping along a big circle. | |
points: Sequence of x,y,z (or even just x,y) tuple representing points that make up a polygon. | |
makeFace: Boolean , if extrude is specified, (this argument is ignored, assumed True) | |
""" | |
points = map(vector, points) | |
points.append(points[0]) | |
result = Part.makePolygon(points) | |
if makeFace or extrude is not None: | |
result = Part.Face(result) | |
if extrude is not None: | |
result = result.extrude(vector(extrude)) | |
return result | |
def extrude(part, dir): | |
return Part.extrude(vector(dir)) | |
#Tranfsormations | |
def rotate(part, angle, pnt=None, dir=None): | |
"""Rotate a part by angle degrees | |
part: The part which to rotate | |
angle: Number for the angle which to rotate the part | |
pnt: Optional list or tuple for the origin of rotation. default (0,0,0) | |
dir: List or tuple for the axis of rotation. default (0,0,1) | |
""" | |
pnt = vector(pnt, (0,0,0)) | |
dir = vector(dir, (0,0,1)) | |
part = part.copy() | |
part.rotate(pnt, dir, angle) | |
return part | |
def rotateX(part, angle, pnt=None): | |
"""Rotate a part about the X axis by angle degrees. | |
part: The part which to rotate | |
angle: Number for the angle which to rotate the part | |
pnt: optional list or tuple for the origin of rotation""" | |
return rotate(part, angle, pnt, (1,0,0)) | |
def rotateY(part, angle, pnt=None): | |
"""Rotate a part about the Y axis by angle degrees. | |
part: The part which to rotate | |
angle: Number for the angle which to rotate the part | |
pnt: optional list or tuple for the origin of rotation""" | |
return rotate(part, angle, pnt, (0,1,0)) | |
def rotateZ(part, angle, pnt=None): | |
"""Rotate a part about the Z axis by angle degrees. | |
part: The part which to rotate | |
angle: Number for the angle which to rotate the part | |
pnt: optional list or tuple for the origin of rotation""" | |
return rotate(part, angle, pnt, (0,0,1)) | |
def translate(part, dir): | |
"""Translate a part by dir vector. | |
part: The part which to rotate | |
dir: List or tuple for the vector amount to translate the part""" | |
dir = vector(dir) | |
part = part.copy() | |
part.translate(dir) | |
return part | |
def scale(part, scale): | |
"""Scale a part by dir vector. | |
part: The part which to rotate | |
dir: List or tuple for the vector amount to scale the part along each axis""" | |
matrix = Base.Matrix() | |
matrix.scale(vector(scale)) | |
return part.transformGeometry(matrix) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment