Comparison of Free scripted 3D CAD systems, part 1
==================================================

Werner Almesberger <werner@almesberger.net>

This is a brief evaluation of the scripted 3D CAD systems OpenSCAD
and Cadmium, comparing the workflow, resource consumption, and the
quality of the results.


Introduction
============

This file and the sources of the models can be found in
http://projects.qi-hardware.com/index.php/p/wernermisc/source/tree/master/cad/test1/

Later experiments showed that small changes to the model can lead to
quite different results. The continuation is at
http://projects.qi-hardware.com/index.php/p/wernermisc/source/tree/master/cad/test2/


Objectives
----------

This test aims to determine the general suitability of currently
available Free scripted 3D CAD system for the construction of
real-life objects.

Aspects considered were the ease or difficulty of model development,
the clarity of the modeling language, resource consumption during
rendering, and the quality of the resulting mesh.

A second objective was to evaluate the suitability of CSG as the only
means for constructing models suitable for large-scale industrial
production.


Object description
------------------

The object to model is a simple button/key cap shape. The shape
consists of a top part shaped as a 10 x 15 mm rectangle with rounded
corners and at height of 1.5 mm. The top part rests on a base that's
0.5 mm thin and has a border of 1 mm on each side.

The corners of the rectangle are rounded with a radius of 2 mm. All
other external edges are rounded (chamfered) with a radius of 0.2 mm.
The edge where top and base meet is filleted with a radius of 0.4 mm.

Note that a real button would typically have an internal cavity,
possibly some depression or other structure on its top, and on the
bottom side a pusher in the middle and possibly other support
elements.

Also, if the design was to be used for injection molding, sidewalls
would be slightly tilted.

The rounding of the bottom plate is not strictly necessary and was
added for visual appearance.


Candidate 1: OpenSCAD
---------------------

OpenSCAD [1] uses its own language, somewhat similar to POV-Ray's, to
describe 3D objects. It has an IDE with a quick preview capability
using OpenCSG [2].

High-quality rendering, e.g., to STL, is done with CGAL [3] and can
also be run non-interactively.

OpenSCAD and OpenCSG are licensed under the GNU GPL v2. Parts of CGAL
are licensed under the GNU LGPL v2.1 while others are licensed under
the incompatible QPL. See [4] for details.

The version tested was the openscad 2011.06-1+lucid1 Ubuntu package.


OpenSCAD front-ends
-------------------

There also a number of Python-based scripted front-ends for OpenSCAD,
namely OpenSCADpy [5], PyOpenSCAD [6], and pySCAD [7].

Furthermore, there is Mecha [8, 9] for Haskell.

Cadmium (see below) appears to be on par or better in terms of syntax
clarity and tidiness than the OpenSCAD Python bindings. Therefore,
only pure OpenSCAD was considered for this comparison.


Candidate 2: Cadmium
--------------------

Cadmium [10] is similar in concept to OpenSCAD, but uses Python
instead of a homegrown language. Open CASCADE [11] (via pythonOCC
[12]) provides the 3D operations here.

The respective licenses are GNU AGPL v3 for Cadmium, GNU LGPL v3 for
pythonOCC, and a homegrown "LGPL-like" license [13] for Open CASCADE.

The Cadmium version tested was Sun Jul 10 16:04:07 2011 +0530 commit
d4ff63b150ee060a8179a74e369b5df3d0a4a3fc, with pythonOCC 0.5.


Results and observations
========================

Model development was efficient with both systems, with most of the
difficulties coming from the task of making the model, not from
inadequacies of the tools.

Both systems also also produced correct-looking meshes.

Notable differences exist in the time the rendering takes, where
rough previews with OpenSCAD are instantaneous and proper rendering
takes minutes, while Cadmium has no preview and the rendering takes
hours.

On the other hand, some small anomalies could be found in the mesh
generated by OpenSCAD while the Cadmium's mesh looks perfect.


Model development
-----------------

Both systems offer the same basic CSG primitives and operations,
which made the model development per se straightforward and the
porting from one system to the other effortless.

The very quick preview of OpenSCAD is immensely helpful during
development. The usefulness of the preview is diminished by
differences only being shown as unions of the solids involved, with
color indicating their role. It was thus often necessary to isolate
and simplify elements before the resulting shape could be guessed, or
to render with slower CGAL.

Given the slow rendering process, debugging non-trivial designs with
Cadmium is currently quite time-consuming.

Development of the basic model (without chamfers and fillets) was
first done with Cadmium. I then switched to OpenSCAD to develop the
more advanced features, and finally ported them back to the Cadmium
model.

Designing the model elements for filleting and chamfering was
somewhat awkward with only CSG and - without understanding the
entire construction process - it may not be easy to see what the
resulting code does.


Modeling language
-----------------

The limited programming language of OpenSCAD proved to be more than
adequate for this simple design. To ease comparison and to reduce the
porting effort, the Cadmium model has the same code structure as the
OpenSCAD model.

It should be noted that some redundancy could be avoided in Cadmium
if all the "rbox_*" functions were placed in a common class whose
objects could then remember the box's geometry for reuse with the
fillet and chamfer functions/methods.

One nuisance with OpenSCAD is that mistyped variable names merely
generate a warning but let rendering proceed - often with confusing
results.

One difficulty encountered when making the Cadmium model was that
there appears to be no null value for the "union" operation, which
means functions that generate all their objects in a loop have to
special-case the first element, making them look a bit awkward (e.g.,
rbox_chamfer_top_corners). It should be easy to remedy this
shortcoming.

The Python language also introduces complications to Cadmium that
OpenSCAD can avoid, such as the Python parser's limited ability to
detect continuation lines, requiring continuations to be marked with
a backslash, and the need to pay attention to the mixing of
floating-point and integer numbers when using divisions.

Cadmium's ability to use short operators instead of blocks generally
yielded only marginally more compact code, since many operations
ended up being longer than one line anyway. In fact, the code
structure often looks a bit tidier in OpenSCAD.

The placement of transformations before creation of the object in
OpenSCAD e.g.,
translate(...) rotate(...) cylinder(...);
is slightly less intuitive than the reverse order Cadmium uses, e.g.,
Cylinder(...).rotate(...).translate(...)

Furthermore, if each step is placed on a separate line, Cadmium's
syntax puts the object in a more prominent position than the list of
translations.


Bugs
----

OpenSCAD got stuck allocating excessive amounts of memory when trying
to preview with OpenCSG from the IDE.

Cadmium fails at line 113 of button.py if the "noise" parameter
introduced to work around this bug is absent or set to zero.

The mesh generated by Open SCAD appears to have some small anomalies,
see section "Resulting mesh".


Execution
---------

On a lightly loaded Intel Q6600, the "high quality" rendering time
was as follows:

		real		user		sys
OpenSCAD	 1m25.491s	 1m24.990s	0m00.410s
Cadmium		81m44.408s	81m41.110s	0m01.540s

This is consistent with the time the rendering of earlier stages of
the design took: OpenSCAD with CGAL was always much faster than
Cadmium with Open CASCADE.

I didn't attempt to systematically search for costly operations, but
observed that the crossed cubes/boxes forming the core of the rounded
box took considerably longer than a run with one of them removed.


Resulting mesh
--------------

The rendering results are available at
http://downloads.qi-hardware.com/people/werner/cad/test1/

The STL files are scad.stl.bz2 and cadmium.stl.bz2 for OpenSCAD and
Cadmium, respectively. scad.png and cadmium.png show screenshots of
the meshes rendered with MeshLab 1.2.2, with double side lighting and
"flat" rendering.

The two meshes are of similar size, as reported by MeshLab:

		Vertices	Faces
OpenSCAD	3351		7798
Cadmium		3183		8362

Note that the OpenSCAD model uses a slightly larger number of circle
segments (explicitly set with $fn) than the Cadmium model (which just
uses whatever is the default behaviour).

At earlier stages of the design, the Cadmium mesh was found to be
significantly larger then the OpenSCAD mesh. 

Both meshes look clean and at a first glance show now major
distortions (*).

(*) Note that the model already takes care of avoiding situations
    where the subtraction of volumes could leave behind solids with
    the thickness of a rounding error.

When viewed with MeshLab 1.2.2, with smooth rendering and
"Fancy Lighting", some faces appear to be inverted. These faces are
shown in red in
http://downloads.qi-hardware.com/people/werner/cad/test1/scad-reversed.png

A peek at the inside of the OpenSCAD-generated mesh reveals internal
structures left over from the construction process, as shown on
http://downloads.qi-hardware.com/people/werner/cad/test1/scad-inside.png

No anomalies could be found in the mesh generated by Cadmium.


Conclusion
==========

In the conclusions, I first consider the relative performance of the
two CAD system and then reflect on the whether the CSG-only workflow
as such proved to be satisfactory.


OpenSCAD vs. Cadmium
--------------------

Both systems succeeded in handling the task. OpenSCAD impressed with
fast response allowing highly interactive development, while Cadmium
---------------------------------------------------------------------
soon gets very slow. It is not clear whether this slowness is a
general shortcoming of Cadmium or whether it is a consequence of poor
choices made when making the model.

The mesh generated by OpenSCAD shows some anomalies, but it's not
clear whether they would affect further processing steps, e.g.,
conversion to toolpaths.

In terms of resource consumption and stability, even this relatively
simple model exhausted both systems, with OpenSCAD exhibiting
stability issues and Cadmium requiring excessive processing time.

Both modeling languages can be used in very similar ways and were
pleasant to use. Python-based Cadmium may be more suitable for tasks
requiring structured building blocks.


The CSG-only workflow
---------------------

With both systems, translating the mental models of the various
components into correct instructions was difficult where more
abstract operations were involved, requiring some amount of trial and
error.

Also, the resulting code does not easily reveal its purpose and
textual comments are an unsatisfactory means of illustrating
geometrical properties. (As an example, consider the above section
"Object description".)

A workflow that includes distinct steps with a visual representation
of intermediate results, e.g., instead of CSG, using extrusion with
shapes and paths generated by some 2D CAD system, may be less
demanding.

Also, while generating the basic shape was very easy, most of the
work went into the addition of fillets and chamfers. Neither of the
two systems provides operations to automate such tasks.


The story continues
-------------------

Later experiments showed that small changes to the model can lead to
quite different and generally better results. The continuation of
this evaluation is at
http://projects.qi-hardware.com/index.php/p/wernermisc/source/tree/master/cad/test2/


References
==========

[1] http://www.openscad.org/
[2] http://www.opencsg.org/
[3] http://www.cgal.org/
[4] http://www.cgal.org/license.html
[5] https://github.com/hmeyer/openscadpy
[6] https://github.com/etjones/MCAD/tree/master/PyOpenScad
[7] https://github.com/kevinmehall/pyscad
[8] http://hackage.haskell.org/package/mecha/
[9] https://github.com/tomahawkins/mecha/blob/master/Language/Mecha/Examples/CSG.hs
[10] http://jayesh3.github.com/cadmium/
[11] http://www.opencascade.org/
[12] http://www.pythonocc.org/
[13] http://www.opencascade.org/getocc/license/

---------------------------------------------------------------------
