ImplicitCAD 0.0.1 Release

I’m pleased to announce the second release of ImplicitCAD: 0.0.1. (The first release was 0.0.0 because 0 is the true first ordinal.)

Variable Twist Extrusion of a Rounded Union in ImplicitCAD

The point of this release is somewhat arbitrarily chosen. We were over due for one and no clean break was in sight. Then I woke up with a nasty headache and couldn’t seem to code, so I thought I’d do a release instead.

I’m going to try and martial together my thoughts and discuss changes in this release and what’s coming up. The TL;DR is that ImplicitCAD is going exciting places and if you are willing to tolerate bugs and file bug reports, you should become a beta user for it.

What has changed in this release of ImplicitCAD?

Bounding Box Determination

Previously, ImplicitCAD required users to provide the bounding boxes for their objects. This was tedious and irritating. And clearly something a computer should be handling.

And with this release, ImplicitCAD will have your computer do it for you.

Now you can write:

import Graphics.Implicit

out = union [
    rectR 0 (-40,-40) (40,40),
    translate (40,40) (circle 30) ]

main = writeSVG 2 "test.svg" out

Where previously the following was needed:

import Graphics.Implicit

out = union [
    rectR 0 (-40,-40) (40,40),
    translate (40,40) (circle 30) ]

main = writeSVG 2 (-40,-40) (70,70) "test.svg" out

Symbolic Rendering

Normally ImplicitCAD renders using a modified version of the Marching Cubes algorithm. For some objects, though, there are obvious ways to render them. ImplicitCAD now tries to do just that, falling back to cubes if it can’t.

Symbolic rendering is faster and produces nicer meshes at the same resolution of rendering. So when it can be used, it is a massive improvement for the end user. 🙂

OpenSCAD Parsing

Because of its popularity, ImplicitCAD is working to provide backwards compatibility with OpenSCAD. (Also, people have an irrational fear of Haskell.)

To this end, we provide the extopenscad tool, which runs a extended version of OpenSCAD. The extensions allow you to use the features that are new to ImplicitCAD while still enjoying the syntax of OpenSCAD. It does not yet have full backwards compatibility.

I’m really excited about some of the improvements we’ve made to OpenSCAD. A few demonstrations follow:

Proper programmatic capabilities — in OpenSCAD, there were a number of troubling limitations including not being able to reassign variables in loops:

a = 5;
for (c = [1, 2, 3]) {
    echo(c);
    a = a*c;
    echo(a);
}
1.0
5.0
2.0
10.0
3.0
30.0
Nothing to render

Functional programming!

echo(map(cos, [0, pi/2, pi]));

Rounding (r=?) for just about everything!

linear_extrude (40, r=8) 
        union (r=5) {
                translate ([-10,-10]) square (30, r=3);
                translate ([ 10, 10]) square (30, r=3);
        }

A Rounded Extrusion of a Rounded Union of Rounded Squares in ImplicitCAD

Higher order modules! Notice that twist is a function!

linear_extrude (height = 40, center=true, twist(h) = 35*cos(h*2*pi/60)) {
        union ( r = 8) {
                circle (10);
                translate ([22,0]) circle (10);
                translate ([0,22]) circle (10);
                translate ([-22,0]) circle (10);
                translate ([0,-22]) circle (10);
        }
}

Variable Twist Extrusion of a Rounded Union in ImplicitCAD

(These examples and more are available on thingiverse!)

Epic Refactoring

A ludicrous amount of code has changed since 0.0.0 (keep in mind that Haskell is a lot more dense than other other languages, so 2.5K lines of code is a much bigger project than some X0K lines of code in C projects I’ve worked on). A lot of that has been me trying to make the code approachable — I think that needs to be a priority, so that other people can extend ImplicitCAD. I got a lot of awesome advice from r/haskell (thanks in particular to Peaker the awesome essay length code review; I’m still working on using the feedback).

What’s Next?

Backwards Compatible OpenSCAD Parsing

There’s still a long ways to go with OpenSCAD parsing. There’s known bugs (like the lack of user defined modules — this is nearly implemented) and unknown bugs (these lurk deep in the code base, waiting to attack unsuspecting users).

This is something you can help with! Report bugs! They bight, I don’t!

More Symbolic Rendering

I think symbolic rendering can be extended to cover the majority of common use cases. I want to see this become a reality!

GCode Generation

Presently the only thing I really support is Hacklab‘s laser cutter. Really, it is compilers all over again and a lot of consideration needs to be given to how to implement GCode generation. People at my GTALUG talk recommended I study GCC’s architecture. This seems like sound reasoning to me.

Metadata

Adding metadata to objects is a clearly necessary step. One of my friends wants to use ImplicitCAD for generating models for some of his projects, but needs to be able to attach metadata about holes (exact radius, is there any threading?, and so on).

Performance Work

ImplicitCAD can’t guarantee Lipschitz Continuity (c=1) any more, so I had to gave up my O(n^{dim_{haus}(bd(S))}) Marching Cubes variant. This makes me very sad. Thankfully, I’ve hatched a plot to reacquire my beautiful algorithm…

Unit Testing via Algebraic Topology

Here’s an interesting problem: You want to unit test a CAD program. It gives you triangle meshes when you ask it to render objects. Obviously, there isn’t one ‘right’ triangle mesh. As long as it approximates the object, we’re pretty happy. And it is entirely valid for the triangle mesh to change if we update algorithms.

One test we can do is to calculate topological invariants of the triangle mesh and make sure they match the object.

As you may have gathered, I enjoy hitting computer science problems over the head with massively oversized mathematical hammers. Call it a hobby.

Also, it gives me an excuse to write a Topology library for Haskell.

I’m going to start with Euler Characteristic but I’d eventually like to calculate Homology Groups (the algorithms involved look interesting, at a glance at least).

More Refactoring

I want ImplicitCAD to break the stereotypes of unapproachable Haskell code. In fact, I intend for it to be a super approachable project.

You can help! Take a glance at the code and tell me what your experience was like.

Hijacking This Post for Important Transmissions

The third Toronto RepRap User Group Meeting is happening on February the 27th. If you live in Toronto and are reading this post, you should probably come!

You can keep up to date with the progress of ImplicitCAD by following my twitter account.

Tags: , , , , ,

30 Responses to “ImplicitCAD 0.0.1 Release”

  1. Xavier Snelgrove Says:

    Hey Chris,

    Any particular reason you’re rendering using an intermediate mesh representation from Marching Cubes? Unless I’m missing something, a raytracer would be fairly straightforward to implement as everything is implicit, and that would give you a “true” rendering of your surface. Or do you need the mesh representation for printer output?

    • colah Says:

      Hey Xavier,

      As you guessed, I need to export triangle meshes. In particular, STL files (which are triangle meshes) are pretty much the standard in open source 3D printing. And I’m not presently providing any visualization options myself.

      Chris

      • Xavier Snelgrove Says:

        It’s interesting, in some ways an implicit representation would make more sense for a 3d printer, after all, for a given nozzle position it would give you a quick expression to check whether that’s inside or outside the volume.

        • colah Says:

          Exactly! I’m producing the triangle meshes to interact with existing software, but I’m experimenting with producing GCode (kind of assembly for 3D printers) my self directly from the implicit functions. I think there’s a lot of cool potential there 🙂

          You also have me strongly considering writing a ray tracer 🙂 Except I’m trying to figure out how to do it with openCL acceleration… The trick is converting my haskell implicit functions into something it will play nice with. And this is why I never have free time.

          • tolomea Says:

            Good gcode generation is still an active research area, if you implement your own you are likely to end up lagging behind the dedicated slicer projects. Perhaps a better approach would be to try and improve the hand off between the CAD program and slicer, STL is a ridiculous format to be using for that interface.

          • Reinoud Zandijk Says:

            Generating gcode from the implicit functions would be neat yes. Especially with the shelling functions the outer circumflexes can be made easily. Thats where my gcode generator is currently stuck on; too many special cases 😦

            What would be very handy is being able to create an object, or load in an stl file (is that even possible now?) and then slice it when implicitCAD into bi-arc segments. This will make smooth outlines possible.

            Great idea btw to use Haskell. I’ve used Miranda/Gofer a long time ago but never dared to make the step to Haskell. Maybe i can help out?

  2. fliegenderfreund Says:

    Chris,
    I am a big fan of 3D-printing.
    I would like to support the RepRap community with
    bitcoins. If you install a client, and send me your bitcoin
    adress or post it on your blog I will donate 1 Bitcoin to your project.

    http://en.wikipedia.org/wiki/Bitcoin

    chris

    • colah Says:

      Hey Chris!

      Sorry about taking so long to respond. I was leaving your comment in my pending queue so that I couldn’t forget about it… and getting back to you to longer than expected.

      Thanks for the offer. ImplicitCAD doesn’t really have any expenses: there’s no supplies except a little bit of plastic used on test prints. Really, the only resources expended is my time. Some of my other projects require other materials (like my 3D printed lenses project), and that is likely what any donation would be spent on.

      In any case, I’ve had some technical issues with setting up bitcoin and, sadly, it’s not one of my higher priorities. If you’re still interested in donating 1 bitcoin, please let me know and I’ll work everything out 🙂

  3. stevetronics Says:

    colah, do you have any documentation anywhere? I’d love to really start using ImplicitCAD (REAL PROGRAMMATIC FEATURES!!!) but I would also love some documentation 😉

    • colah Says:

      The Haskell API has documentation that can be built by running “cabal haddock”.

      The extopenscad interface doesn’t really have that. One of the things I’m working on right now is autogenerating it from the source code. In the mean time, there’s some highly accessible source code you can look at. I’m also mostly compatible with openscad, which has great documentation in its User Manual.

      There should hopefully be generated documentation with in a few days 🙂

      • stevetronics Says:

        Christopher,
        I’ve been playing with that very source file. I am a bit of a noob with Haskell (didn’t know about it before ImplicitCAD) so digging through it (man it’s dense!) is fun. The doc call, though, is easy. What I’d really like to know about are the variable reassignment features you’ve added, perhaps making something like http://stevetronics-3dp.blogspot.com/2012/02/openscad-ahhhhh.html possible. I’ve been reading through your variable reassignment example too. Playing away. Does the above look possible? I don’t know if it’s just a basic failing of my logic or extopenscad.

        • colah Says:

          > Does the above look possible?

          Sure. The following should point you in the right direction 🙂

          r=5;
          N = 10;
          x=[];
          for (n = [0:N-1])
                x = x ++ [r*cos(2*pi*n/N)];
          echo(x);
          

          This has pointed out to me a desperate need for indexed assignment and some more assignment operator variations. Thanks!

          • stevetronics Says:

            I just pulled the latest from GitHub, and it appears you’ve outdone me :). The code snippet on my blog was a “polygon creator” and digging through primitives.hs, I see that you’ve added that very feature. I like it. Can I take some small measure of credit for inspiration? 😉

  4. 3D-printed broccoli | Composite Says:

    […] Chris will talk a bit about 3D printing and types of printers in general, the software ecosystem around 3D printing, his experience making *lenses* with printers, and his project implicitCAD. […]

  5. DrRob Says:

    Long story short – I recently built a ShapeOko (http://www.shapeoko.com) and have since been trying all sorts of software combinations for driving it, by trial and error (mostly error). I’d like to cut some cutting tool mounts, and like the idea of programmatically generating the design from the tool size and other parameters.

    I’ve tried a few different combinations of s/w, and today got started with OpenSCAD, but hit a shortcoming straight away – I want to specify the basic shapes, then have the code position them as required, but a module can’t query the dimensions of a component passed to it, so all the coordinates have to be calculated by the script. Ugh!

    What I really want is to be able to define layout combinators – things like, “line up these child components with a gap of 10mm between them”. Or “line up these child components so that hole 1 of child 0 lines up with hole 3 or child 1, and hole 2 of child 0 lines up with hole 2 of child 1.” (The metadata mentioned above will come in handy for this.)

    A quick google for ‘openscad’ “higher order” brought me here, and mention of my old friend Haskell jumped out at me.

    Enough of my waffle – I just want to say thanks for releasing this, and now I’ll download it and get started.

    Rob.

    • colah Says:

      Awesome!

      The functionality you’re asking about already exists in the dev version, BTW. For example:

      pack([30,30], sep=5) {
      for (n=[0,1,2]) cube(10);
      sphere(5);
      }

  6. Matt Says:

    Very approachable code indeed! I’d just hope that the very foundational geometric stuff like this would remain within reach for everybody and not be plagued by GPL, which renders the whole thing into the does-not-exist category for many ordinary people like me.

    Think about it, the global Haskell land is tiny. Do you see much evidence of people getting ripped off by commercial leechers. Is there any indication that this would change any time soon? No. The GPL riffle is shooting our own people here.

    • colah Says:

      There are definitely strong arguments in favor of a BSD license. I’ve given quite a bit of thought to ImplicitCAD’s licensing, and the correct course of action isn’t trivial to determine, I think. In any case, I’m sorry that ImplicitCAD’s utility to you is reduced by its licensing, and I’ll try to weight the utility of users that are not able to use GPLed software more strongly when I give reconsideration to licensing.

  7. Bert Says:

    Hi Chris,

    I ‘m trying to get ImplicitCad working on windows… not so easy.
    1. Cygwin didn’t install correctly in the default path, it should have no spaces, like c:\cygwin. Solved.
    2. cabal install implicit complains about “Abigious module name ‘Prelude'”. Not solved, but possible work around with latest snapshot, but:
    3. cabal install plugins fails with error: Lexical error in string/character literal at character ‘P’. This seems to be a known issue for installing ‘plugins’ at windows. A suggested solution is using ‘Hint’ instead.
    4. removing ‘plugins’ from libraries list in implicit.cabal to force the installation was unfortunately not sufficient: “… statements.hs:24:8:Could not find System/Plugins/Load

    So that’s where I’m stuck now.
    I don’t expect a quick solution, but I wanted to inform you about my findings, and any suggestions to get it work are welcome.

    I will try to get it running in a vm running debian.

    • colah Says:

      Hey Bert!

      Please email me (chris@colah.ca) and we’ll try to sort out the problems you’re having. A lot of people have been having issues with plugins, and I may just make a version of ImplicitCAD that doesn’t use them…

  8. Tom Hawkins Says:

    Hi Chris,

    Cool package! I’ll try it out when I get some time.

    I built a similar library awhile back called Mecha [1], which targets POVRay and OpenSCAD. The largest model I created was to demonstrate the kinematics of a new type of piston pump [2].

    As you alluded to, programmatic CAD has many advantages over conventional CAD (i.e. higher orderness, parametrics, etc). But I also think CSG combinator languages have a few drawbacks: mainly the tedious nature of describing complex parts and motion kinematics. One area that would be interesting to explore is what kind of high-level CAD languages could be created that are above the basic CSG operations; where part shapes are mostly synthesized from higher level descriptions. I think this is where the real productively gains could be made.

    -Tom

    [1] http://hackage.haskell.org/package/mecha
    [2] http://www.youtube.com/watch?v=Ow_z99MLvlg&feature=plcp

    • colah Says:

      Hey Tom,

      Mecha is also a cool package. I looked at it before writing ImplicitCAD, but I had a lot of really cool ideas for a graphics engine in a higher order langauge. And I thought it was important to have the graphics engine integrated into Haskell.

      I definitly agree with you that basic CSG is a tedious way to desing objects. I’ve been working on creating tools that aleviate this in someways: RCSG, higher order extrusions, and in the near future parts that intelligently snap together… But design will still remain tedious.

      Higher level descriptions would be awesome and I’ve been thinking about them a lot. I think they likely need to be very domain specific and targeted at the functionality of the object. Much like how programming languages abstract the actual manner in which an algorithm is executed from the algorithm. For example, one might make one for microfludic devices describing functionality, and the layout would be automatically generated (think parsec)… It’s something I’d like to work on at some point.

  9. DaveGadgeteer Says:

    I found this tremendously interesting, and especially liked your explanations of how things work.
    I’m new with 3D printing, and am frustrated by the other offerings available (e.g. OpenSCAD makes it very hard to generate screw thread shapes, and nobody makes it easy to combine scanned volumes with CAD-designed things (e.g. one might want to put a nice base and nameplate on a scanned bust)).
    But I see no activity in the last year, so I’m wondering whether this is a dead end already, or is it just dormant but at a usable level???

    • colah Says:

      Hey Dave,

      People do use ImplicitCAD for things, but there are bugs.

      Sadly, I’m too busy with machine learning research these days to work on ImplicitCAD (blog posts to come on my more recent work!). There are some people looking at taking over working on ImplicitCAD, though.

      Chris

  10. David Says:

    Hello,
    When I look at your tutorial at implicitcad.org, it looks as if the language is openSCAD compatible. But I would prefer to define my 3D objects in Haskell, as you do in this blog above. Is there a tutorial for that as well? Do you have some collection of examples in haskell for defining 3d objects?

    I have recently bought and built a reprap mendel90 3D printer from a kit, and I would like to use implicitCAD for making models to print.

    I wonder what is the status of implicitCAD’s g-code generation for 3D-printing?
    Right now, the available software seems to be only in python or C++. This is a pity, when there is such a language as Haskell…

    BR, David

    • colah Says:

      Hey there David!

      You can absolutely design objects in Haskell. It’s a more powerful interface than extopenscad. Most people are scared off by the word “Haskell” so I don’t advertise it much.

      Import “Graphics.Implicit” into ghci and take a look. 🙂 Sorry there isn’t a tutorial.

      Sadly, I’ve been very focused on machine learning research for some time and haven’t worked on ImplicitCAD. The gcode generator works for hacklab’s laser cutter, but doesn’t support anyting else. It could be easily modified to support many 2D CNC devices.

      Chris

  11. David Says:

    Hi again!
    eventually I am trying implicit again!
    I installed it from the git repo and managed to compile some simple openscad files with the extopenscad command.
    I tried the Benchmark.hs file, but the Criterion package seems to be out of sync, so I just commented it out. But from that file I got a picture of how to write models in haskell.
    I have a core 3.5 GHz i7 with 4 real cores, and 2 hyperthreads in each and 16GB RAM (and a CUDA card :), and I want to exploit the parallelism. When I run “writeSTL (1/8) “benchmark.stl” object2″ in ghci it takes several minutes, maybe half an hour, and my cpu monitor shows that only one cpu is loaded.
    Sorry for my ghc ignorance, but I wonder how to enable it to run in parallel. Should I use a special flag when compiling? I dont see any such option documented. Or maybe only certain kinds of models permit parallel rendering? Or maybe I have to be explicit about parallelism, using the parralels package features, when calling the functions? (havent looket that much in the souce yet, things take time…)

    About resolution:
    It seems that sharp edges typically get kind of “zig zag” because of how the mesh is rendered. This means that I have to choose a very hogh resolution to get a decent look. and this is expensive to render.
    Any hints of how to deal with this?

    BR,
    David

  12. David Says:

    Ok, I found how to run it (assuming a module Foo.hs) in parallel: Either run ghci +RTS -N8 -RTS Foo.hs, or run it with ./Foo +RTS -N8, after having compiled with ghc -threaded -rtsopts –make Foo.hs, for 8 parallel tasks. I guess many of you who frequently use Haskell think this is too basic, and not worth mentioning, but there are many others wanting to try, so I think mentioning this in the README, for instance, would help. (but in better formulations than I did 🙂

    On performance:
    The highest precision I could achieve on my computer for writeSTL on object2 in Benchmark.hs was 0.05 in 5 minutes, and then the generated stl file had visible “jacks” in the corners. I also exported object2 with writeSCAD3 and renered it in openscad — it took a second, and the stl has sharp corners. So is is an issue.
    It would be nice if you had an example in the other direction, something that takes time with openSCAD but is quick in implicit.

    I have to try more object and model something myself. I miss the mirror command–Isaw it was commented out in the parser as unimplemented. I hope someone takes over this (unless you can continue, Chris), because it deserves it!

    BR, David

  13. kpe Says:

    I’ve just sent the pull request https://github.com/colah/ImplicitCAD/pull/179 that allows to use scale() with negative arguments, i.e. one could write

    scale([-1,1,1])

    where

    mirror([1,0,0])

    is needed.

Leave a reply to colah Cancel reply