Skip to content

New Functions in PythonSCAD

OpenSCAD already got a rich set of functions, however, there could be some more ...

divmatrix

Sometimes its helpful to use multmatrix with the inverse of a matrix. Why don't use divmatrix right from the beginning ?

from openscad import *
mat=[[1,0,0,10],[0,1,0,0],[0,0,1,0],[0,0,0,1]] # Move to the right by 10

a=cube([1,1,1])
b=a.multmatrix(mat) # move to right
c=b.divmatrix(mat) # move back left
c.show()

mesh

With mesh function you can convert solid to a set of vertices and triangles like so:

from openscad import *

u=cube([1,1,1]) | cylinder(d=1,h=10)

pts, tris = u.mesh()
# Now you could use the pts for further processing or even manipulate them and do this ...

v = polyhedron(pts, tris)
v.show()

path_extrude

OpenSCAD has linear_extrude to move along a straight line and rotate_extrude to extrude along an arc. But there is nothing which can extrude along an arbritary line. This is reason to create path_extrude. With path_extrude you can extrude any shape along a path given by points. A 4th parameter in a vertex means the radius in this corner

from openscad import *
p=path_extrude(square(1),[[0,0,0],[0,0,10,3], [10,0,10,3],[10,10,10]]);
show(p);

quick transformations

Sometime translate or rotate is quite a burden to write when you just want to change one coordinate and still have to specify 3 values in the transformation
from openscad import *
# these are easier to write instead specifying full translate or rotate
obj=cube(2)
part1 = obj.right(2.5)
part2 = obj.left(2.5)
part3 = obj.up(2.5)
part4 = obj.down(2.5)
part5 = obj.front(2.5)
part6 = obj.back(2.5)
part7 = obj.rotx(90)
part8 = obj.roty(135)
part9 = obj.rotz(-45)
part5.show()

pulling objects apart

Sometimes its helpful to alter an existings STL and just adjust dimensions, whowever scale is not the right approach because you only want the new dimension just on one place, not all over the object. This is where pull can be helpful pull defines one point one direction where it inserts "void" right into the spanned area. Best use this to work on STL's

from openscad import *
# One Cube
c=cube([2,2,5])

p=c.pull([1,1,3],[4,-2,5])  # Attach Point , Pull amount
p.show()

Flower

Signed distance Functions within OpenSCAD

No need to create SDF objects in other tools and import into OpenSCAD after. Thanks to embedded libfive this can be done online. Watch this small sample to get an idea, how easy it is:

from openscad import *
from pylibfive import *

# Just assemble you libfive object first
c=lv_coord()
s1=lv_sphere(lv_trans(c,[2,2,2]),2)
b1=lv_box(c,[2,2,2])
sdf=lv_union_stairs(s1,b1,1,3)

# And mesh it finally to get something, that PythonSCAD can display
fobj=frep(sdf,[-4,-4,-4],[4,4,4],20)
show(fobj)
Flower

On a lower level, SDF used a formula and creates surfaces in the area, where this function hits zero. All functions, which are provided by libfive are also available in openSCAD. These are

import libfivew as lv
lv.x() # returns x coodinate
lv.y() # returns y coodinate
lv.z() # returns z coodinate
lv.sqrt(x)
lv.square(x)
lv.abs(x)
lv.max(x,y)
lv.min(x,y)
lv.sin(x)
lv.cos(x)
lv.tan(x)
lv.asin(x)
lv.acos(x)
lv.atan(x)
lv.exp(x)
lv.log(x)
lv.pow(x)
lv.comp(a,b)
lv.atan2(x,y)
lv.print(formula) # print tree of formula
A great introduction to the world of SDF can be found in here

align

Align can be used to combine combjects together without difficult transformations

from openscad import *
c = cube()
c1 = c
# scale with -1 will also invert the directions of all handles, so the objects will be abutting instead of coincident
c2 = c.align(scale(c1.origin,-1), c.origin)

show(c1 | c2)

edge

PythonSCAD has a new primitive called "edge" which just has a length

from openscad import *
e = edge(size=10, center=True)

# and of course you can extrude it
square = linear_extrude(e, height=10)
square.show()

# or get back the edges in a python list
all_e = square.edges()

fillet

You can use fillet to add roundings and chamfers to your existing object an easy cases, so dont challenge the algorithmus. Usually if you have an idea, how to fillet, the tool can do it, too

from openscad import *

c=cube(10);

mask=cube([30,1,30],center=True)

demo = [
    c.fillet(1), # Normal fillet with r=1, fn=2, thus bevel
    c.fillet(2,fn=5).right(15), #fillet with r=2 and more points
    c.fillet(3,mask,fn=20).right(30), # really round, but just with masked edges(which are front)
]
show(demo)
Flower

faces

You can retrieve a list of faces for any solid in a python list

from openscad import *

core=sphere(r=2)
faces = core.faces()

flower = core
for f in faces:
    flower |= f.linear_extrude(height=4)
flower.show()
Flower note that objects returned by faces (and edges) have a property called 'matrix' which is a 4x4 eigen matrix which shows their orientation in space. it can be used to filter them

export

You can use this to export your data to disk programmatically like so:

from openscad import *
c = cube(10)
cyl = cylinder(r=4,h=4)

c.export("mycube.stl")

# with 3mf format you can even store many objects at once

export( {
    "cube" : c,
    "cylinder" : cyl
},"myfile.3mf")

spline

Spline is like 'polygon' just with the difference, that the resulting object is very round and will meet the given points

from openscad import *

pts=[[0,6],[10,-5],[20,10],[0,19]]
s = spline(pts,fn=20).linear_extrude(height=1)
for pt in pts:
    s |= (cylinder(r=0.3,h=10,fn=20)+pt)
s.show()
Spline

skin

Thanks to scrameta, pythonscad got wonderful skin. skin is like you put arbritary 2d objects in space and skin will cover all of them tightly

This is basically morphing a square into a circle

from openscad import *
a=square(4,center=True).roty(40)
b=circle(r=2,fn=20).rotx(40).up(10)
s=skin(a,b)
s.show()
Skin

add_parameter

This is how PythonSCAD can interact with the customizer. The customizer allows users to modify parameters through a GUI without editing code.

Basic Usage

from openscad import *

# Simple parameter with default value
width = add_parameter("width", 10)
name = add_parameter("name", "default")
enabled = add_parameter("enabled", True)

cube([width, width, width]).show()

Parameter Options

Option Type Description
description str Help text shown in customizer
group str Tab name (default: "Parameters")
range range/tuple Min/max for slider (numbers/vectors)
step float Step increment for spinbox
max_length int Maximum length (strings only)
options list/dict Dropdown options

Sliders (Numbers)

from openscad import *

# Integer slider using range() - note: range is exclusive, use 101 for max 100
quality = add_parameter("quality", 50, range=range(0, 101, 5))

# Float slider using tuple (min, max) or (min, max, step)
scale = add_parameter("scale", 1.0, range=(0.1, 10.0, 0.1))

# Spinbox with step (no slider)
angle = add_parameter("angle", 45.0, step=0.5)
from openscad import *

# Simple options list
color = add_parameter("color", "red", options=["red", "green", "blue"])

# Labeled options (value: label)
quality = add_parameter("quality", 10, options={10: "Low", 20: "Medium", 30: "High"})

Vectors

from openscad import *

# Vector with constraints (applied to all elements, max 4 elements)
size = add_parameter("size", [10, 20, 30], range=(1, 100, 1))

Groups and Organization

from openscad import *

# Organize parameters into tabs
width = add_parameter("width", 10, group="Dimensions")
height = add_parameter("height", 20, group="Dimensions")
color = add_parameter("color", "red", group="Appearance")

# Special groups
debug = add_parameter("debug", False, group="Hidden")    # Not shown in UI
units = add_parameter("units", "mm", group="Global")     # Appears on all tabs

Descriptions

from openscad import *

# Add help text
width = add_parameter("width", 10,
    description="Width of the model in mm",
    group="Dimensions")

concat

Concat concatenates the triangles and vertices of serveral objects without actually createing an Union operation on them. This is useful when the sub-parts are not yet water-tight and CSG would fail on them.

from openscad import *

alltogether = concat(part1, part2, part3)

existing functions are improved

Some of the existing functions got additional useful parameters

union, difference

Specify r or fn as an additional parameter and the new created common edges get nice roundings

circle gets an angle parameter

from openscad import *

pie = circle(r=5,angle=70)
pie.show()
Circle Pie

same for cylinder, why should it be missing

from openscad import *

pie = cylinder(r=5,h=6, angle=90)
pie.show()
Cylinder Pie

sphere can accept a function which receives a 3d vector and will output a radius

from openscad import *

def rfunc(v):
  cf = abs(v[0])+abs(v[1])+abs(v[2])+3
  return 10/cf
sphere(rfunc,fs=0.5,fn=10).show()
Sphere with custom radius

linear_extrude can also extrude a python function. this will get a height and shall return a 2d polygon

from openscad import *
from math import *
def xsection(h):
    v =5+sin(h)
    return [[-v,-v],[v,-v],[v,v],[-v,v]]

prisma = linear_extrude(xsection, height=10,fn=20)
prisma.show()
Linear Extrude with custom xsection

rotate_extrude can also extrude a python function. this will get a height and shall return a 2d polygon

from openscad import *
from math import *
def xsection(h):
    v =2*sin(4*pi*h)
    res=[[10+v,-v],[15-v,-v],[15-v,5+v],[10+v,5+v]]
    return res
rotate_extrude(xsection,fn=50).show()
Rotate Extrude with custom xsection

rotate_extrude has a v parameter , when not [0,0,0] it will do nice helix

from  openscad import *

circle(3).right(10).rotate_extrude(v=[0,0,20],angle=600).show()
Sphere with custom radius