+ =
Python | OpenSCAD

Leverage one of the world's most popular programming languages to express parametric 3D models.

Download
Motivation

OpenSCAD is a very cool tool that lets you express 3D models using its own language. Unfortunately the language itself comes with a lot of intentional limitations.

  • No mutation of variables (immutability, "single assignment of any variable")
  • Limited number of iterations
  • No file I/O

These exist for the reason that they don't want the language to be able to do bad things to people's computers, which allows the "script sharing culture" to be safe.

Additionally the choice to use their own language brings with it a whole new mental model that must be learned and mastered. This is a problem for wide adoption.

This fork lets you use Python inside of OpenSCAD as its native language

No extra external script to create OpenSCAD code. And as its based on openscad we aim to keep all the features which already exist in openscad. Only added features, no skipped ones ...

Before I continue I'd like to say I fully appreciate all the efforts the team and the Open Source community has contributed towards it over the years. The project is truly a work of love and has brought for many the joy of programming back into their lives. I believe the choice to have a safe script language is a good one.

These limitations cause OpenSCAD programs to be written in the most convoluted ways, making them difficult to understand. While my goal to be able to use Python with OpenSCAD is actually completed, the problem that remains is getting it merged into mainline OpenSCAD.

The argument is Python will introduce a massive security hole into the sharing culture. So the proposed solution is to put the Python capability behind an option, which I have done. Additionally OpenSCAD asks you, if you trust to a new Python Script and it will saves this decsion for you in an SHA256 hash. Now I hope it's just a matter of time until things are merged.

This is where you come in. Use this fork, have your say, and let's get it in!

A nice tutorial walking you through some exercises can be found here

Get started

If you're new to "code CAD", please first read this short introduction and browse the plethora of already existing solutions to this problem space.

Before downloading it, please understand that "Python | OpenSCAD" is a fork currently maintained by myself, gsohler. I heavily wish for this fork/branch to be merged into mainline OpenSCAD and have been working towards making it happen. You can follow the progress here.

There are several benefits to using Python over OpenSCAD's DSL (domain specific language):

  1. Faster general computation due to faster interpreter
  2. Utilize any pip packages
  3. More familiar syntax
  4. More familiar computation model

Hopefully these benefits will help draw more people to the wonderful world of code CAD!

Ok, now it's probably a good idea to download it. Dont forget to enable python experimental feature in the preference. You might also want start openscad with '--trust-python' to disable annoying warnings as python is considered unsafe by the openscad developers. In case you like my work i would love to see my branch forked

If you rather want to compile it yourself, these are the steps to get it done.

git clone https://github.com/gsohler/openscad.git
cd openscad
git checkout python
git submodule update --init --recursive
sudo ./scripts/uni-get-dependencies.sh
# make sure to get cryptopp and python dev packages installed, additionally
mkdir build
cd build
cmake -DEXPERIMENTAL=1 -DENABLE_PYTHON=1 -DENABLE_LIBFIVE=1 ..
make
sudo make install

Vote for even more Features ?
Do you feel, that OpenSCAD is missing an important feature ? Vote here , what you want to see next

Your Name
Email (optional)

Contact

Python-Openscad related discussion is on our IRC Channel.
A Formum to raise questions is available at Reddit
If you have comments, criticism or even improvement suggestions, don't hesitate to write to me at guenther.sohler@gmail.com

Usage samples

Not quite like "Hello world!" but hey, we need to start somewhere. Here's an example of a table:

def foot(x,y):
	c=cube([1,1,10])
	return translate(c,[x,y,0])

def plate():
	return cube([11,11,1])

parts=[]
parts.append(translate(plate(),[0,0,10]))

for y in [0,10]:
	for x in [0,10]:
		parts.append(foot(x,y))

output(parts)
      		

Many applications are possible like

a QR code generator

or Using Figlet 3D Ascii art

or A Gyroid

or even GDS File Parser used for creating Microchips

Additional features

On top of Python support, this fork also has the following extra capabilities.

Texture your models

Use textures to make your objects more impressive!

texture("texture1.jpg"); // get a texture index
color(texture=1) // specify the index to use
  cube(10); // on the object
            
F-REP/SDF engine (libfive)

Use SDFs to create organic meshes!

from pylibfive import *
c=lv_coord()
s1=lv_sphere(lv_trans(c,[2,2,2]),2)
b1=lv_box(c,[2,2,2])
sdf=lv_union_smooth(s1,b1,0.6)
fobj=frep(sdf,[-4,-4,-4],[4,4,4],20)
output(fobj)

            

If you're unfamiliar please look up "Inigo Quilez", the god-father of SDFs.

The available operators are:

  • X()
  • Y()
  • Z()
  • operators + = * / %
  • sqrt()
  • abs()
  • max()
  • min()
  • sin()
  • cos()
  • tan()
  • asin()
  • acos()
  • atan()
  • atan2()
  • exp()
  • log()

I've integrated libfive into OpenSCAD, but only through the Python bindings.

See example at libfive_example.py or collosseum.py

ifrep

There is first support for ifrep. ifrep takes an OpenSCAD solid as input and returns a variable which you can use along with your other SDF equations. You can use it for offsetting exising objects.

Objects double as dictionaries

Each of the generated objects has a built-in dictionary, which can be used to store additional information along with the object. e.g to store coordinate information about special locations of the object.

  myobject["top"] = [10,10,90]
          
Path extrude

path_extrude works very similar to linear_extrude or rotate_extrude. IMHO it can actually act as a superset of both of them. Like in linear_extrude and rotate_extrude, the extruded 2D shape is always perpendicular to the extrusion. The syntax is:

square().path_extrude([[0,0,0],[0,0,10]])
          	

Possible parameters are:

  • path - list of points in 3d space where to feed the path. Points can optionally specified as a 4-value-vector where the 4th value acts as a radius parameter for round corners
  • twist - amount of degrees to twist the profile along the path
  • origin - determines 2D center point of the twist rotation within the profile
  • scale - factor to scale the profile along the path, can also be 2d vector
  • closed - whether to close the path to form a ring . true/false
  • xdir - Direction of the x vector of the profile for the very first path segment.

See example at path_extrude_example.py

3D offset

In this version offset also operates on 3D objects in addition. For example, you can use this feature to downsize connection parts from stl files from the internet if they are too tight to assemble.

 

outer=sphere(10) inner=offset(outer,-1) shell=outer-iner output(shell-cube(15))