CSG for You and Me!

Here it is Monday, and where’s my new release?

Well, how about a couple of pretty pictures to look at?

What do we have here?  Well, on the left, we have a sphere with a cylinder sticking out of it.  On the right, we have a sphere with said cylinder removed through the magic of Constructive Solid Geometry (csg).

With Banate CAD, you can already create nifty solids from basics, like Bezier Surfaces, and other oddities.  But, the set of things you can construct can be dramatically improved if you can add CSG operations (union, intersect, difference).

The science of CSG has existed for a couple of decades now, with myriad implementations covering a broad spectrum of uses.  Recently, I saw an implementation in the form of the csg.js library.  That was pretty cool because it’s compact, designed to work with JavaScript for WebGL usage, and it basically gets the job done.

I thought similar could be done for Banate CAD.  My design goals for the operations are:  No external library dependencies, fast enough to render in “relative real-time”.  Robust enough to handle 90% of the things CSG is typically used for in doing simple 3D designs.

I explicitly was NOT going for the most robust and proveably complete CSG implementation.  I will be satisfied if every design I’ve implemented in OpenScad can be redone in Banate CAD.  If that turns out to be the case, then I’ll be happy enough with it.

There are a couple of usability things to consider now, before I actually release it as part of the product.

At the very core, CSG is done like this:

object1:union(object2)

or

object1:difference(object2)

etc.

But, that’s a bit clunky.  In OpenScad, I would do something like:

difference(){
functiontoinstantiateobject1()
functiontoinstantiateobject2()
}

That’s fairly easy to do, and is in line with OpenScad’s generally declarative way of doing things. But, Banate CAD does not really follow that declarative style. It is much more imperative (tell it exactly what to do). Aside from style, Banate CAD makes instancing front and center. That is, in order to make a cube, for instance, you can either do:
hexahedron(size), which will create an internal instance of a cube, and add it to the global scene, or you can be more explicit:

mycube = shape_hexahedron.new(size)
mycylinder = shape_cone.new(base, top)

Now that I’ve got an explicit instance of a cube, it makes more sense to do things with it:

myshape = mycube - mycylinder
addshape(myshape)

There are a couple of things here. First of all, overloading the ‘+’, ‘-‘, ‘%’ operators. That makes for a nice simple notation, but you’ll have to be very careful with operator precedence, and grouping with parenthesis. But, for very simple things, this might just work out.

At any rate, the basic functionality is now in hand, and it will surely show up in the release soon.



Leave a comment