Werner's Miscellanea
Sign in or create your account | Project List | Help
Werner's Miscellanea Git Source Tree
Root/
| 1 | Comparison of Free scripted 3D CAD systems, part 1 |
| 2 | ================================================== |
| 3 | |
| 4 | Werner Almesberger <werner@almesberger.net> |
| 5 | |
| 6 | This is a brief evaluation of the scripted 3D CAD systems OpenSCAD |
| 7 | and Cadmium, comparing the workflow, resource consumption, and the |
| 8 | quality of the results. |
| 9 | |
| 10 | |
| 11 | Introduction |
| 12 | ============ |
| 13 | |
| 14 | This file and the sources of the models can be found in |
| 15 | http://projects.qi-hardware.com/index.php/p/wernermisc/source/tree/master/cad/test1/ |
| 16 | |
| 17 | Later experiments showed that small changes to the model can lead to |
| 18 | quite different results. The continuation is at |
| 19 | http://projects.qi-hardware.com/index.php/p/wernermisc/source/tree/master/cad/test2/ |
| 20 | |
| 21 | |
| 22 | Objectives |
| 23 | ---------- |
| 24 | |
| 25 | This test aims to determine the general suitability of currently |
| 26 | available Free scripted 3D CAD system for the construction of |
| 27 | real-life objects. |
| 28 | |
| 29 | Aspects considered were the ease or difficulty of model development, |
| 30 | the clarity of the modeling language, resource consumption during |
| 31 | rendering, and the quality of the resulting mesh. |
| 32 | |
| 33 | A second objective was to evaluate the suitability of CSG as the only |
| 34 | means for constructing models suitable for large-scale industrial |
| 35 | production. |
| 36 | |
| 37 | |
| 38 | Object description |
| 39 | ------------------ |
| 40 | |
| 41 | The object to model is a simple button/key cap shape. The shape |
| 42 | consists of a top part shaped as a 10 x 15 mm rectangle with rounded |
| 43 | corners and at height of 1.5 mm. The top part rests on a base that's |
| 44 | 0.5 mm thin and has a border of 1 mm on each side. |
| 45 | |
| 46 | The corners of the rectangle are rounded with a radius of 2 mm. All |
| 47 | other external edges are rounded (chamfered) with a radius of 0.2 mm. |
| 48 | The edge where top and base meet is filleted with a radius of 0.4 mm. |
| 49 | |
| 50 | Note that a real button would typically have an internal cavity, |
| 51 | possibly some depression or other structure on its top, and on the |
| 52 | bottom side a pusher in the middle and possibly other support |
| 53 | elements. |
| 54 | |
| 55 | Also, if the design was to be used for injection molding, sidewalls |
| 56 | would be slightly tilted. |
| 57 | |
| 58 | The rounding of the bottom plate is not strictly necessary and was |
| 59 | added for visual appearance. |
| 60 | |
| 61 | |
| 62 | Candidate 1: OpenSCAD |
| 63 | --------------------- |
| 64 | |
| 65 | OpenSCAD [1] uses its own language, somewhat similar to POV-Ray's, to |
| 66 | describe 3D objects. It has an IDE with a quick preview capability |
| 67 | using OpenCSG [2]. |
| 68 | |
| 69 | High-quality rendering, e.g., to STL, is done with CGAL [3] and can |
| 70 | also be run non-interactively. |
| 71 | |
| 72 | OpenSCAD and OpenCSG are licensed under the GNU GPL v2. Parts of CGAL |
| 73 | are licensed under the GNU LGPL v2.1 while others are licensed under |
| 74 | the incompatible QPL. See [4] for details. |
| 75 | |
| 76 | The version tested was the openscad 2011.06-1+lucid1 Ubuntu package. |
| 77 | |
| 78 | |
| 79 | OpenSCAD front-ends |
| 80 | ------------------- |
| 81 | |
| 82 | There also a number of Python-based scripted front-ends for OpenSCAD, |
| 83 | namely OpenSCADpy [5], PyOpenSCAD [6], and pySCAD [7]. |
| 84 | |
| 85 | Furthermore, there is Mecha [8, 9] for Haskell. |
| 86 | |
| 87 | Cadmium (see below) appears to be on par or better in terms of syntax |
| 88 | clarity and tidiness than the OpenSCAD Python bindings. Therefore, |
| 89 | only pure OpenSCAD was considered for this comparison. |
| 90 | |
| 91 | |
| 92 | Candidate 2: Cadmium |
| 93 | -------------------- |
| 94 | |
| 95 | Cadmium [10] is similar in concept to OpenSCAD, but uses Python |
| 96 | instead of a homegrown language. Open CASCADE [11] (via pythonOCC |
| 97 | [12]) provides the 3D operations here. |
| 98 | |
| 99 | The respective licenses are GNU AGPL v3 for Cadmium, GNU LGPL v3 for |
| 100 | pythonOCC, and a homegrown "LGPL-like" license [13] for Open CASCADE. |
| 101 | |
| 102 | The Cadmium version tested was Sun Jul 10 16:04:07 2011 +0530 commit |
| 103 | d4ff63b150ee060a8179a74e369b5df3d0a4a3fc, with pythonOCC 0.5. |
| 104 | |
| 105 | |
| 106 | Results and observations |
| 107 | ======================== |
| 108 | |
| 109 | Model development was efficient with both systems, with most of the |
| 110 | difficulties coming from the task of making the model, not from |
| 111 | inadequacies of the tools. |
| 112 | |
| 113 | Both systems also also produced correct-looking meshes. |
| 114 | |
| 115 | Notable differences exist in the time the rendering takes, where |
| 116 | rough previews with OpenSCAD are instantaneous and proper rendering |
| 117 | takes minutes, while Cadmium has no preview and the rendering takes |
| 118 | hours. |
| 119 | |
| 120 | On the other hand, some small anomalies could be found in the mesh |
| 121 | generated by OpenSCAD while the Cadmium's mesh looks perfect. |
| 122 | |
| 123 | |
| 124 | Model development |
| 125 | ----------------- |
| 126 | |
| 127 | Both systems offer the same basic CSG primitives and operations, |
| 128 | which made the model development per se straightforward and the |
| 129 | porting from one system to the other effortless. |
| 130 | |
| 131 | The very quick preview of OpenSCAD is immensely helpful during |
| 132 | development. The usefulness of the preview is diminished by |
| 133 | differences only being shown as unions of the solids involved, with |
| 134 | color indicating their role. It was thus often necessary to isolate |
| 135 | and simplify elements before the resulting shape could be guessed, or |
| 136 | to render with slower CGAL. |
| 137 | |
| 138 | Given the slow rendering process, debugging non-trivial designs with |
| 139 | Cadmium is currently quite time-consuming. |
| 140 | |
| 141 | Development of the basic model (without chamfers and fillets) was |
| 142 | first done with Cadmium. I then switched to OpenSCAD to develop the |
| 143 | more advanced features, and finally ported them back to the Cadmium |
| 144 | model. |
| 145 | |
| 146 | Designing the model elements for filleting and chamfering was |
| 147 | somewhat awkward with only CSG and - without understanding the |
| 148 | entire construction process - it may not be easy to see what the |
| 149 | resulting code does. |
| 150 | |
| 151 | |
| 152 | Modeling language |
| 153 | ----------------- |
| 154 | |
| 155 | The limited programming language of OpenSCAD proved to be more than |
| 156 | adequate for this simple design. To ease comparison and to reduce the |
| 157 | porting effort, the Cadmium model has the same code structure as the |
| 158 | OpenSCAD model. |
| 159 | |
| 160 | It should be noted that some redundancy could be avoided in Cadmium |
| 161 | if all the "rbox_*" functions were placed in a common class whose |
| 162 | objects could then remember the box's geometry for reuse with the |
| 163 | fillet and chamfer functions/methods. |
| 164 | |
| 165 | One nuisance with OpenSCAD is that mistyped variable names merely |
| 166 | generate a warning but let rendering proceed - often with confusing |
| 167 | results. |
| 168 | |
| 169 | One difficulty encountered when making the Cadmium model was that |
| 170 | there appears to be no null value for the "union" operation, which |
| 171 | means functions that generate all their objects in a loop have to |
| 172 | special-case the first element, making them look a bit awkward (e.g., |
| 173 | rbox_chamfer_top_corners). It should be easy to remedy this |
| 174 | shortcoming. |
| 175 | |
| 176 | The Python language also introduces complications to Cadmium that |
| 177 | OpenSCAD can avoid, such as the Python parser's limited ability to |
| 178 | detect continuation lines, requiring continuations to be marked with |
| 179 | a backslash, and the need to pay attention to the mixing of |
| 180 | floating-point and integer numbers when using divisions. |
| 181 | |
| 182 | Cadmium's ability to use short operators instead of blocks generally |
| 183 | yielded only marginally more compact code, since many operations |
| 184 | ended up being longer than one line anyway. In fact, the code |
| 185 | structure often looks a bit tidier in OpenSCAD. |
| 186 | |
| 187 | The placement of transformations before creation of the object in |
| 188 | OpenSCAD e.g., |
| 189 | translate(...) rotate(...) cylinder(...); |
| 190 | is slightly less intuitive than the reverse order Cadmium uses, e.g., |
| 191 | Cylinder(...).rotate(...).translate(...) |
| 192 | |
| 193 | Furthermore, if each step is placed on a separate line, Cadmium's |
| 194 | syntax puts the object in a more prominent position than the list of |
| 195 | translations. |
| 196 | |
| 197 | |
| 198 | Bugs |
| 199 | ---- |
| 200 | |
| 201 | OpenSCAD got stuck allocating excessive amounts of memory when trying |
| 202 | to preview with OpenCSG from the IDE. |
| 203 | |
| 204 | Cadmium fails at line 113 of button.py if the "noise" parameter |
| 205 | introduced to work around this bug is absent or set to zero. |
| 206 | |
| 207 | The mesh generated by Open SCAD appears to have some small anomalies, |
| 208 | see section "Resulting mesh". |
| 209 | |
| 210 | |
| 211 | Execution |
| 212 | --------- |
| 213 | |
| 214 | On a lightly loaded Intel Q6600, the "high quality" rendering time |
| 215 | was as follows: |
| 216 | |
| 217 | real user sys |
| 218 | OpenSCAD 1m25.491s 1m24.990s 0m00.410s |
| 219 | Cadmium 81m44.408s 81m41.110s 0m01.540s |
| 220 | |
| 221 | This is consistent with the time the rendering of earlier stages of |
| 222 | the design took: OpenSCAD with CGAL was always much faster than |
| 223 | Cadmium with Open CASCADE. |
| 224 | |
| 225 | I didn't attempt to systematically search for costly operations, but |
| 226 | observed that the crossed cubes/boxes forming the core of the rounded |
| 227 | box took considerably longer than a run with one of them removed. |
| 228 | |
| 229 | |
| 230 | Resulting mesh |
| 231 | -------------- |
| 232 | |
| 233 | The rendering results are available at |
| 234 | http://downloads.qi-hardware.com/people/werner/cad/test1/ |
| 235 | |
| 236 | The STL files are scad.stl.bz2 and cadmium.stl.bz2 for OpenSCAD and |
| 237 | Cadmium, respectively. scad.png and cadmium.png show screenshots of |
| 238 | the meshes rendered with MeshLab 1.2.2, with double side lighting and |
| 239 | "flat" rendering. |
| 240 | |
| 241 | The two meshes are of similar size, as reported by MeshLab: |
| 242 | |
| 243 | Vertices Faces |
| 244 | OpenSCAD 3351 7798 |
| 245 | Cadmium 3183 8362 |
| 246 | |
| 247 | Note that the OpenSCAD model uses a slightly larger number of circle |
| 248 | segments (explicitly set with $fn) than the Cadmium model (which just |
| 249 | uses whatever is the default behaviour). |
| 250 | |
| 251 | At earlier stages of the design, the Cadmium mesh was found to be |
| 252 | significantly larger then the OpenSCAD mesh. |
| 253 | |
| 254 | Both meshes look clean and at a first glance show now major |
| 255 | distortions (*). |
| 256 | |
| 257 | (*) Note that the model already takes care of avoiding situations |
| 258 | where the subtraction of volumes could leave behind solids with |
| 259 | the thickness of a rounding error. |
| 260 | |
| 261 | When viewed with MeshLab 1.2.2, with smooth rendering and |
| 262 | "Fancy Lighting", some faces appear to be inverted. These faces are |
| 263 | shown in red in |
| 264 | http://downloads.qi-hardware.com/people/werner/cad/test1/scad-reversed.png |
| 265 | |
| 266 | A peek at the inside of the OpenSCAD-generated mesh reveals internal |
| 267 | structures left over from the construction process, as shown on |
| 268 | http://downloads.qi-hardware.com/people/werner/cad/test1/scad-inside.png |
| 269 | |
| 270 | No anomalies could be found in the mesh generated by Cadmium. |
| 271 | |
| 272 | |
| 273 | Conclusion |
| 274 | ========== |
| 275 | |
| 276 | In the conclusions, I first consider the relative performance of the |
| 277 | two CAD system and then reflect on the whether the CSG-only workflow |
| 278 | as such proved to be satisfactory. |
| 279 | |
| 280 | |
| 281 | OpenSCAD vs. Cadmium |
| 282 | -------------------- |
| 283 | |
| 284 | Both systems succeeded in handling the task. OpenSCAD impressed with |
| 285 | fast response allowing highly interactive development, while Cadmium |
| 286 | --------------------------------------------------------------------- |
| 287 | soon gets very slow. It is not clear whether this slowness is a |
| 288 | general shortcoming of Cadmium or whether it is a consequence of poor |
| 289 | choices made when making the model. |
| 290 | |
| 291 | The mesh generated by OpenSCAD shows some anomalies, but it's not |
| 292 | clear whether they would affect further processing steps, e.g., |
| 293 | conversion to toolpaths. |
| 294 | |
| 295 | In terms of resource consumption and stability, even this relatively |
| 296 | simple model exhausted both systems, with OpenSCAD exhibiting |
| 297 | stability issues and Cadmium requiring excessive processing time. |
| 298 | |
| 299 | Both modeling languages can be used in very similar ways and were |
| 300 | pleasant to use. Python-based Cadmium may be more suitable for tasks |
| 301 | requiring structured building blocks. |
| 302 | |
| 303 | |
| 304 | The CSG-only workflow |
| 305 | --------------------- |
| 306 | |
| 307 | With both systems, translating the mental models of the various |
| 308 | components into correct instructions was difficult where more |
| 309 | abstract operations were involved, requiring some amount of trial and |
| 310 | error. |
| 311 | |
| 312 | Also, the resulting code does not easily reveal its purpose and |
| 313 | textual comments are an unsatisfactory means of illustrating |
| 314 | geometrical properties. (As an example, consider the above section |
| 315 | "Object description".) |
| 316 | |
| 317 | A workflow that includes distinct steps with a visual representation |
| 318 | of intermediate results, e.g., instead of CSG, using extrusion with |
| 319 | shapes and paths generated by some 2D CAD system, may be less |
| 320 | demanding. |
| 321 | |
| 322 | Also, while generating the basic shape was very easy, most of the |
| 323 | work went into the addition of fillets and chamfers. Neither of the |
| 324 | two systems provides operations to automate such tasks. |
| 325 | |
| 326 | |
| 327 | The story continues |
| 328 | ------------------- |
| 329 | |
| 330 | Later experiments showed that small changes to the model can lead to |
| 331 | quite different and generally better results. The continuation of |
| 332 | this evaluation is at |
| 333 | http://projects.qi-hardware.com/index.php/p/wernermisc/source/tree/master/cad/test2/ |
| 334 | |
| 335 | |
| 336 | References |
| 337 | ========== |
| 338 | |
| 339 | [1] http://www.openscad.org/ |
| 340 | [2] http://www.opencsg.org/ |
| 341 | [3] http://www.cgal.org/ |
| 342 | [4] http://www.cgal.org/license.html |
| 343 | [5] https://github.com/hmeyer/openscadpy |
| 344 | [6] https://github.com/etjones/MCAD/tree/master/PyOpenScad |
| 345 | [7] https://github.com/kevinmehall/pyscad |
| 346 | [8] http://hackage.haskell.org/package/mecha/ |
| 347 | [9] https://github.com/tomahawkins/mecha/blob/master/Language/Mecha/Examples/CSG.hs |
| 348 | [10] http://jayesh3.github.com/cadmium/ |
| 349 | [11] http://www.opencascade.org/ |
| 350 | [12] http://www.pythonocc.org/ |
| 351 | [13] http://www.opencascade.org/getocc/license/ |
| 352 | |
| 353 | --------------------------------------------------------------------- |
| 354 |
Branches:
master
