Saturday, June 22, 2013

[3dprint] new CURA engine

I just had a look at the new CURA engine code:

Nice, elegant C++ implementation. Internally it relies on Clipper, a fast library to perform operations on 2D polygons. That is an excellent choice: Intersecting each 3D triangle with the slice plane produces a bunch of segments. The segments are then linked back together to form polylines and 2D polygons. The Clipper library is used to compute polygon offsets, creating the perimeter and shells.

Now I have to work hard to make IceSL as fast :) There are quite a few places where large speed ups are possible, so we'll see.

Monday, June 17, 2013

[3dprint] IceSL: Model, slice and print without intermediate meshes

Short story: Model objects through a CSG language inspired by OpenSCAD but based on LUA with real time pixel-perfect CSG (with transparency) and direct slicing. Yes, this is both the modeler and slicer in a same package - no output mesh, only G-code. Small catch: you need a recent NVidia GPU (supporting OpenGL 4.2 ; Series 4 or above).


Long story: When I first discovered hobbyist 3D printing thanks to the great community around RepRap and derivatives, I was looking forward to modeling and printing my first objects. What's more, I had heard about OpenSCAD, where shapes are described by CSG operations between meshes and basic primitives. CSG (Constructive Solid Geometry) is good for modeling solids, because instead of worrying about a surface mesh you can focus on adding and subtracting matter. Modeling through scripting is also very efficient (reuse) and well suited to describe mechanical parts. It seems Makerbot and Thingiverse users largely agree.

However, what surprised me is how difficult the whole process was: The real-time rendering of OpenSCAD does not always succeed -- fast CSG display with basic OpenGL is no simple matter -- and sometimes the shape displayed on screen is very different from what it should be. When hitting the "Compile mesh" button you have to wait for a very long time before getting the final mesh. This is problematic since you are never quite sure that you positioned your shapes properly, unless waiting for minutes -- and it makes small trial-and-error adjustments tedious. In retrospect, this is to be expected: OpenSCAD is designed to produce very clean meshes and relies on CGAL to compute exact mesh-to-mesh intersections (in spite of numerical errors). This is a smart choice because it guarantees the quality of the output, at the price of more complex and time consuming algorithms, but that is the right way to go when meshes have to be produced.

At the same time I was also stuck with another part of the process: The slicer. I mainly used Skeinforge through ReplicatorG. There are many, many settings which all make sense individually but are really scary for a beginner (which I am/was). Now, ReplicatorG does a great job at hiding things, but ultimately you want to dive deeper and tweak parameters. The result - for me - was lower print quality after hours of tweaking :-). Thus, I decided to look deeper into the problem and started implementing my own slicer to understand the intricacies of the process. I soon realized that the nice mesh computed by minutes of clever state-of-the-art CGAL algorithms in OpenSCAD was ultimately sliced into bits and pieces -- and in fact the large number of triangles only made matters worse when primitives such as cylinders or spheres were being used.

The whole process now seemed a bit wrong: A lot of processing power and complex algorithms are devoted to generating a perfect mesh, but its quality is in fact a total overkill for the slicing that later takes place. So, ... do we really need this intermediate mesh? It turns out you do not need to produce a mesh. Not at all: not for display, not for slicing. IceSL is based on this principle: It is an alternative to OpenSCAD tailored specifically for additive manufacturing. It uses the same code path both for on screen rendering and slicing. And it is made fast by using just a little bit of GPU magic (note: obviously this also gives high requirement for the user - but I am doing research in hardcore graphics, right? ;-) ). This is only a first prototype of this idea: It is far from complete, far from optimized, and lacks many important features (infill patterns in particular, supports as well), but I hope you'll already enjoy the ability to quickly visualize your objects and the relatively fast slicing. IceSL can slice STL files ; it is relatively fast for this but not the fastest (not yet ;-) ). However, it is really fast when slicing CSG models: No need to generate the STL! What is intriguing is that the software, internally, never has to deal with triangles -- in fact, the source code does not even contain a triangle class (apart from what is required to load and send meshes to the GPU).

The way it works is by first building a CSG description of the scene through a scripting language. For this I choose LUA, which is a very nice, easy to learn language. In fact, converting between OpenSCAD and the LUA scripts is not difficult at all -- I include a number of examples such as involute parametric gears. It then relies on a real-time CSG rendering algorithm, which is reused during slicing. So what you see, truly is what you print. Now, after computing bitmaps for each slices the tool path is computed -- this part is more similar to other slicers as far as I can tell.

It turns out my beginner's intuition was not exactly novel: I recently discovered that RepRap Host includes a similar strategy to directly slice from 'csg' files produced by OpenSCAD. As far as I can tell the main difference is that my pipeline relies on a single algorithm for display and slicing, and is therefore somewhat simpler: Meshes (as input) are treated as any other primitive. Btw, I recommend anyone interested in the topic to read through the code of RepRap Host (main author is Adrian Bowyer!). It is easy to read and the wiki does describe parts of the algorithm. It was great to read through it after doing my own, as I was happy to discover that for some parts I made similar choices (although I do not use marching squares for perimeters -- have to consider this). My code relies more heavily on the GPU and rasterization, but the basic principles remain similar. Another interesting prior work I recently discovered is this paper. If you know of other works, please post a comment ; I'd like to get a good landscape of existing methods.

Hope you'll find IceSL useful.