Bezier Mesh Surface V0.9

by WilliamAAdams May 24, 2011
Download All Files

Thing Apps Enabled

Please Login to Comment

I've added a .stl file here that demonstrates surfaces can be generated from the polyhedra making up the Bezier surface. In this particular case, I have actually made modifications to the test_bezier.scad file, which I have yet to publish. There are no cracks or gaps in the surface, and it can participate fully in CSG operations.

It's a cheat though. For the second surface, I mirely drop the 'inner' polygon by the thickness amount, and call it a day. This will work well for some models and not for others.

The real end result will have to use the surface normal of the face to offset the right amount in the right direct

So basically you have implemented linear_extrude() that actually works (imho the way it should work in openscad and the way it does work in rapcad) but you are also trying to implement an inset() module. is it possible that you could implement inset in such a way that it will work with all primitives?

Yes, the current form is essentially a linear_extrude for surfaces. It's not the best way of dealing with curves though. Think of when you have a surface with an overhang, especially if it hangs over itself. Things just won't be 'correct'. But, for a great many shapes, this particular method will be worthwhile.

The best though, is to us the normals to 'inset' as it were into the interior of the object, rather than just dropping down in z value. Perhaps I should give the current technique a name such as 'bezier_surface_extrude'.

I'm not quite sure how 'inset' would generalize to all primitives. What wo
uld that mean for a cube, for example?

So thinking about it there are two types of inset, prehaps this one would be called inset_extrude and can be used to make 3d forms from sufaces such as yours.

A general inset() module for a cube would do the same as scaling it, but this doesn't work perfectly for rounded cubes:


Its hard to see but the rounded corners of the cup are not a uniform thickness.

et()/offset() would also be extreemly usefull for creating enclosures, create some primitives that represent the components you want to enclose, use hull() to create a convex hull around those components, then offset the result and subtract the original to get a shell.

It's beginning to sound like the professional CAD programs out there. There's a certain amount that can be done with the limitations of OpenScad. At the very least, we now understand how to do a linear_extrude on a Bezier surface. The same technique can be applied to any surface that can be tesselated. The thing can be rotated as well, if that's interesting.

Beyond that, the final frontier for this kind of surface is to be able to create arbitrary surfaces, so that you can go beyond simple linear extrude.

There's a fundamental problem with the OpenScad language. You don't have any way of dynamically constructing arrays of arbitrary size. Since I ca
n't do that, I can't express my surface as one big array. I have to actually construct the polyhedrons one by one. By the same token, it's kind of hard to calculate the 'hull' without actually going ahead and displaying the thing... But then again, now that I think of it...

The challenge here co
mes down to state management. I could possibly get a hull value, by repeatedly calling a min/max function, but the loop would occur within a module, and there I don't have good variable state storage. But I'm babbling.

We've now got surfaces with thickness. That's a good step in the right direct

Dynamic arrays is not something that I had considered when developing rapcad, RapCAD does support real assign operators though so maybe you can append to an existing array that way? I would need to test it.

Also I am gearing up towards a 0.1.0 preview release of RapCAD soon, so once that is out of the way I will see about implementing dynamic arrays, and built in BezierSurface support.



I think it would be awesome if you did built in Bezier surface support. Doing at least as much as I have done here is fairly straight forward. The blend functions are absolutely trivial, and so is figuring out quads along the curves. the rest is just placing a quad of the right thickness into the right place. OpenScad isn't the most powerful and flexible language in the world, so if it can be done in OpenScad, it can probably be done anywhere.

I look forward to using RapCAD.

If you generalize it enough to surfaces in general, the world will be a better place. If you at least do generalized patch placement, then I, or anyone else, can create surfaces of any variety. If you at least do dynamic arrays, that will also help.

You could also union() convex hulls around spheres with the desired thickness (diameter) at the bezier points. Would be horribly slow, though.

I think the problem could better be solved by adding a BezierSurface Module the the application itself, its sufficiently non-trival and broadly useful. It seems as though you have gone though terrible pains to coax openscad into achieving what you desire.

I have done some experiments with RapCAD


One advantage RapCAD has over openscad is that it dosen't have a 2D subsystem, and that is actually an advantag
e because all the primitives, square polyline, circle are actually fully dimensional.

As such, when you linear extrude a curved surface it doesn't project the surface onto the 2d plane and extrude that, instead it just makes a copy of the surface points with z values incremented by h, and adds side

The other example is just to show that you might want to create a printable shape using convex hull, i.e. a flat bottom.



That RapCad looks very interesting as well. It would be great if it could do a true surface with thickness. Then I could model, and print, the two halves of my mouse, print them out, and get a new mouse case.

I have played with the flat bottom approach. That might be good in some cases.

Using my granules renderer (back before the 0.5 version), I could do any level of complexity, but it was a bit piggy.

My current efforts are to essentially improve on that granule renderer.

I was able to at least do Bezier based fillets:

And even rotated B
ezier ribbons:

And a few others that are solid and useful.

The generalized surface is possible. It just requires properly placing extruded polygon triangles in the proper places, and that will be that.

Why bother with all this? Yes, the Bezier functions sho
uld just be a part of OpenScad. But, seeing as how the last revision before the current version, was a year ago, I thought it useful to go ahead and produce a library. If it turns out to be interesting enough, then it should be included, or something like it, in the core of OpenScad.

Along the w
ay, I've also thought, it might be better to just use WebGL and JavaScript. That way platform reach is maintained, and you get a better language to boot.

But, that's an argument for another day.

For now, I'll just perfect what I've been doing, and move on to actually using it to make nice things.

Public Domain OpenScad Bezier Function
Bezier Ribbons 3D

Hello. This is great, the maths is sound and the functionality is getting there. However, I think the implementation is a bit wrong.

For example add the following module to test_bezier.scad

module print_polyhedron(points,triangles)

and replace the calls to the polyhedron module in PlaceTriangle with print_polyhedron the output is the following:

O: "polyhedron(points=[[0.787037, 1.66667, 1.57407], [0, 0, 0], [1.66667, -1.57407, 0]],triangles=[[0, 1, 2]]);"
ECHO: "polyhedron(points=[[0.787037, 1.66667, 1.57407], [1.66667, -1.57407, 0], [2.32253, 0.334786, 1.81483]],triangles=[[0, 1, 2]]);"
ECHO: "polyhedron(points=[[1.48148, 3.33333, 2.96296
], [0.787037, 1.66667, 1.57407], [2.32253, 0.334786, 1.81483]],triangles=[[0, 1, 2]]);"
ECHO: "polyhedron(points=[[1.48148, 3.33333, 2.96296], [2.32253, 0.334786, 1.81483], [2.90123, 2.21989, 3.41615]],triangles=[[0, 1, 2]]);"

Basically, what you are doing here is creating 600 or so polyhed
rons, what I think you need to do instead is create a single polyhedron including the top surface, the bottom surface, and the sides.

If you press F6 for example you will see the problem. (and you need to be able to render it using CGAL before you will be able to export it to STL)



Yep, that's why it's still version 0.9

At the moment, the mechanism is to tesselate the surface, and for each triangle generated, create its 'inside' mate by looking at the surface normal for that triangle.

I would like to take an approach that's slightly different. I don't need to enclose each triangle. I only need to enclose the e
ntire space.

I can do that by displaying the 'top' then the 'bottom' and then stitching up the sides.

I'd like to generate one large polyhedron, but frankly, I don't know how to do that. How do you construct a variable length array in OpenScad? That's the fundamental problem I face. If I know t
hat answer, then I can do everything in one single module, and not have to generate multiple polys.

I faced the same question with the extrude-transform work. I don't know of a way to do this in OpenSCAD.

I tried to union polyhedrons that were individually non-manifold but together should have been, and I couldn't get it to work.

I also don't know of a way to define large arrays procedurally.

the real ultimate solution for me will be to use extruded polygon (triangles). They are solid, and they'll be manifold, and CSG-able.

The current round makes for nice fast processing. In my particular library, I will just swap out the renderer for one that will actually do proper solid triangles, and all will be well.

That will work for yours as well. The polyhedrons are a good step along the path, and the final is to use pro
perly placed extruded polygon triangles.

Well, the polyhedrons, properly defined, work well for me for generating STLs and Skeinforge is prefectly happy to slice them. If you want to really optimize them, a quick trip to netfabb will do fine but is not strictly necessary.

Here you go, nice clean difference CSG on a pile of polyhedrons, done in a minute and exported as a 200kB STL file. :-)

I don't like to just extrude the triangles because that is less flexible than a properly defined polyhderon. You can twist the extrusion, but you can't tilt the second face, resize it, etc...

In this version 0.9, you calculate the normals of the points of a quad by using the other quad points. That way, the normals of two adjacent quads are different and the patches don't line up nicely.

Shouldn't it work if you would calculate the normal of the bezier itself in the corners of the quad? That way, two adjacent quads would use the same norma for the same pointl and the 'extruded' triangles should end up using the exact same corner points.

Since the construction of the bezier already involves the tangent, calculating the normal can't be hard (hmm ;) )

Yes, normals at the curve points. And use those to calculate the points for the 'inner' quad, then build a polyhedron from there.

In the code currently on my machine, I've added another module "PlaceShard", which takes two triangles, and does the closed polyhedron thing. So, the task is simply, for each triangle that you're going to place, calculate the 'inner' triangle, and place the shard.

And yes, if I use the curve to
calculate the normals, adjacent ones should line up exactly.

I have in fact uploaded a .stl that is almost using that technique.

One more step closer!

great work here! keep it up!

If there was a way to have a parameter or set of parameters generate the two bezier curves offset by the thickness from the same function(s), you could generate the two set of vertices easily, and they would always match up for both surfaces. That's how I do it with the screw thread modules.

You could also generalize the concept to create solids defined by two bezier surfaces that are not just offset by a set thickness.

It might be a simple as changing the weights for the control points for the two surfaces... perhaps?

The way I did it for the triangles was to just calculate the normals at each of the vertices, and use that to drive the offsets.

I was thinking of doing the same for the control points of the Bezier's. Take the normal of the quads between the control points, or something. that might get a bit tricky.

But yes, the generalization to work between two surfaces, whatever they are, would be very neat indeed. You could easily
make chairs for example, or other shapes that are an interpolation between two surfaces.

The door is cracking open I think.