Skip to content

Instantly share code, notes, and snippets.

@thehans
Created February 11, 2012 03:55
Show Gist options
  • Save thehans/1796019 to your computer and use it in GitHub Desktop.
Save thehans/1796019 to your computer and use it in GitHub Desktop.
Helper functions for improving FreeCAD's Python API
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