Skip to main content

An interpreter for OpenSCAD that renders to build123d objects

Project description

buildSCAD

An interpreter for OpenSCAD that emits OCC objects, wrapped with build123d.

Rationale

Today's 3D programs can import STEP models, thus can deal with "real" curves and solids instead of mesh approximations.

Unfortunately, the CGAL 3D package used by OpenSCAD is mesh-based. Owch.

On the other hand, OpenSCAD is somewhat widely used for creating parameterized models algorithmically. Sites like Thingiverse or Printables contain quite a few models built with it.

The code in this package interprets OpenSCAD code and returns "real" 3D models.

Approach

The OpenSCAD code is parsed into a syntax tree and interpreted on the fly when a "module" (in OpenSCAD terms) is called.

The result is an OCC Solid (or sketch if 2D), wrapped with build123d. It can be used just like any other OCCT object.

Functional replacements

If a module cannot be implemented in build123d/OCC, most likely because it uses hull or minkowsky, the most expedient fix is to write a replacement in Python.

Usage: simply call set_mod(NAME, pymod) on the parse result.

The same is possible with functions, and even the values of variables. Because BuildSCAD evaluates all expressions at runtime, this works seamlessly.

To read global variables, Python code can access the current environment via the contextvar buildscad.cur_env.

Limitations

This tool started off as a proof of concept. A few OpenSCAD built-ins and some rarely-used syntax rules are not implemented yet, though the grammar itself should be complete.

Variables whose name start with a '$' are usable. However, they cannot be passed to functions as keywords. Instead, $-prefixed keywords get passed to called functions in the environment so that functions implemented in Python don't have to deal with them.

Creating a six-sided polygon by calling circle(r=2, $fn=6) is not supported.

BuildSCAD is entirely non-optimized. That's not a problem in practice because most time is spent inside OCCT anyway.

The minkowski and hull operators don't exist in OCCT. Implementing them is way out of scope for this project.

undef is evaluated as None.

Differences to OpenSCAD

Evaluation Order

Our parser delays evaluation of variables until they're needed.

In other words, this …

:: bar = foo(b); function foo(x) = x; a = 5; b = 2 * a;

… works just fine; b will change if you override a.

Variable handling

Unknown variables (i.e. those that are never assigned to) cause an error. As in OpenSCAD, unfilled parameters are undef/None, i.e.

function xx(a,b) = b;
echo(xx(1));

emits "ECHO: None".

Included Files

Variables declared in include files can be overridden in the main code, as in OpenSCAD. However, values from included files don't filter back to the main code.

Invalid Values

OpenSCAD tends to return undef whenever it doesn't understand something, which typically results in any numer of follow-up warnings.

We don't do that. Errors raise exceptions.

Testing

The subdirectory tests/models includes various OpenSCAD files, with accompanying Python code.

The models in these files are built in three ways:

  • directly by OpenSCAD
  • by emulating OpenSCAD
  • by Python code (optional)

The test builder calls the work function (Python) / module (OpenSCAD). If that doesn't exist, top-level objects (OpenSCAD) / variables (Python) are used.

The following Python variables are recognized:

  • tolerance

    The maximum difference (volume) between the various models. The default is 0.001 but anything that depends on OpenSCAD's $fn probably requires looser constraints.

  • volume

    The volume (in mm³) that the model is supposed to have.

  • skip

    Skip this test when running pytest. Used when the test takes way too long or crashes OCCT (yes it happens …).

  • no_add

    When set to True, do not add the various volumes. This is a workaround for an OCCT bug which causes an endless loop.

    Setting this flag causes the testcase to only compare volumes and bounding boxes, which is not as accurate.

  • trace

    Log (some) calls to build123. Seee below.

If the Python part of the test only contains constants, it must declare work=None. Otherwise the test code assumes that you wrote e.g. Sphere(42) without assigning the result to anything, and thus refuses to accept the testcase.

If you want to test the result of a function call against OpenSCAD, the best way is to create a Box(result,1,1) object.

Viewing tests

examples/test_viewer.py can be opened with CQ-Editor to compare test results visually.

Test Traces

If the testcase sets tracing=True, the actual build123d calls will be logged and the STL file from OpenSCAD will not be deleted.

The trace output is executable Python code so that you can find prolems more easily when a test fails, or if/when OCCT misbehaves.

Trace support is still somewhat incomplete.

TODO

Improve error reporting. Seriously.

To fix:

  • linear_extrude with scaling
  • linear_extrude with scaling and twist
  • use/include from a library (via envvar OPENSCADPATH)

Implement missing functions.

Test working with 2D.

An option to generate an (algebraic) build123d script that mirrors the OpenSCAD code structure would be nice.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

buildscad-0.4.3.tar.gz (31.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

buildscad-0.4.3-py3-none-any.whl (26.6 kB view details)

Uploaded Python 3

File details

Details for the file buildscad-0.4.3.tar.gz.

File metadata

  • Download URL: buildscad-0.4.3.tar.gz
  • Upload date:
  • Size: 31.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for buildscad-0.4.3.tar.gz
Algorithm Hash digest
SHA256 47f700155133f74fc4ba0fd8c668cbcae98e50863f6d1a5b2eeeb6dfa4bdd1a1
MD5 72b98d6ddd19eab7d75048099415eb49
BLAKE2b-256 f49dda585bfc86c4262e46afcdf5a372c2cdad431b8db1887758f456330a2828

See more details on using hashes here.

File details

Details for the file buildscad-0.4.3-py3-none-any.whl.

File metadata

  • Download URL: buildscad-0.4.3-py3-none-any.whl
  • Upload date:
  • Size: 26.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for buildscad-0.4.3-py3-none-any.whl
Algorithm Hash digest
SHA256 d5b5a4641099c627e9d4891f513f399af9f8ef071af28dde6e7c1aa8fbafc39b
MD5 97b854ab46b7b08e1ef688540d1dae17
BLAKE2b-256 e319fdbbc5260c6d0b1cc5b3267730793739ee1f2d024c952be522a3e4d58216

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page