julesb / rhombrick

Combinatorial constructions with Clojure and Quil
9 stars 2 forks source link

Interface to Scad instead of quil? #1

Open EricGebhart opened 10 years ago

EricGebhart commented 10 years ago

Hello, I have always been fascinated by 3D tesselations. Lately I have been creating objects in OpenScad using the scad-clj library. I was recently reminded of your work here.

I have only looked over the code, so I have no idea how difficult this might be. But it seems the Quil layer is pretty thin. What do you think about creating an interface to scad? It would mean that ultimately some of these things could actually be printed on a 3d printer. Parts could also be used as building blocks for other things.

Eric

julesb commented 10 years ago

Hi Eric

I've always though it would be cool to be able to print objects from rhombrick, possibly to make puzzles or just as building blocks for freeform construction. I haven't had any experience with 3d printing workflows, file formats etc, but scad-clj/OpenScad looks like it would be a good way to go. Thanks for letting me know about it, I will definitely read up on it in the near future.

I think that the first approach would be to think about printing sets of tiles rather than printing the assemblages that rhombrick creates. There are two main ways rhombrick can generate tile geometry. There is the bezierbox way, which constructs the tiles out of triangle strips swept along bezier curves. The other way, which I think would be more interesting (and a better fit for 3d printing) is the using signed distance functions or field functions with boolean CSG operations, fed into marching cubes to create to triangles. The code for this is in marching_cubes.clj. It's slow and experimental, but does work. Doing it this way avoid the messiness of the bezierbox method which often creates overlapping triangle strips. Then again, from a quick look it seems that OpenScad has boolean ops so it may be relatively easy to implement a tilecode-to-openscad function which would take a tilecode and topology (cell shape) and output OpenScad primitives representing the tile. Doing it this way most of the rhombrick code (and quil) can be ignored.

Thanks for your interest, you have got my brain ticking now..

EricGebhart commented 10 years ago

Hello Jules,

I have only recently started doing anything with 3D printing. It is still new to me. I've experimented with some different software and ended up liking scad the best. 3d printing uses STL files which are then sliced, and fed to the printer which prints in ~.2 mm layers.

Scad generates STL files directly. I can edit the scad files or the scad-clj files in emacs and when I save them, scad sees the change, loads the file, recompiles and renders. The viewer is not fancy, but works pretty well.

That's what I thought about the code. I had found your page because I was searching for clojure and bezier. I have an scad bezier library, but thought I might be able to find a clojure one.

Bezierbox is where I landed. What I didn't get to is understanding the underlying geometry. But scad has nice primitives. It doesn't really matter how we create the tiles, the STL file format and the slicer take care of the 3d printing part. The only complication is if the object is 2 manifold. If it's not it won't save as STL.

I've attached the bezier.scad code. You might find it interesting. I didn't write it. I've only modified it a bit. The scad language is pretty simple and a bit cumbersome. Which is why scad-clj is so appealing. The documentation for scad is really nice, with plenty of examples so you can easily see what it can do.

Here are some links to OpenScad resources.

This is the post that started it all for me. I saw it on Clojure Reddit and I couldn't stop thinking about it. Now I have a 3d printer, and I'm designing things in Open Scad.

http://adereth.github.io/blog/2014/04/09/3d-printing-with-clojure/

http://www.openscad.org/

https://github.com/farrellm/scad-clj

Scad mode for emacs https://raw.githubusercontent.com/openscad/openscad/master/contrib/scad-mode.el

Two library sources. I'm sure there are others. Many things on thingiverse are defined with scad. The code is not always pretty. But many are very nice and parametric, so they can scale and adapt in many ways.

This guy has done a bunch of nice work with Open Scad. Math nut... http://www.thingiverse.com/WilliamAAdams/designs/page:1

https://github.com/mtu-most/most-scad-libraries

this is mostly for building printers but has lots of useful stuff. http://reprap.org/wiki/MCAD

----- julesb's Original Message -----

Hi Eric

I've always though it would be cool to be able to print objects from rhombrick, possibly to make puzzles or just as building blocks for freeform construction. I haven't had any experience with 3d printing workflows, file formats etc, but scad-clj/OpenScad looks like it would be a good way to go. Thanks for letting me know about it, I will definitely read up on it in the near future.

I think that the first approach would be to think about printing sets of tiles rather than printing the assemblages that rhombrick creates. There are two main ways rhombrick can generate tile geometry. There is the bezierbox way, which constructs the tiles out of triangle strips swept along bezier curves. The other way, which I think would be more interesting (and a better fit for 3d printing) is the using signed distance functions or field functions with boolean CSG operations, fed into marching cubes to create to triangles. The code for this is in marching_cubes.clj. It's slow and experimental, but does work. Doing it this way avoid the messiness of the bezierbox method which often creates overlapping triangle strips. Then again, from a quick look it seems that OpenScad has boolean ops so it may be relatively easy to implement a tilecode-to-openscad function which would take a tilecode and topology (cell shape) and output OpenScad primitives representing the tile. Doing it this way most of the rhombrick code (and quil) can be ignored.

Thanks for your interest, you have got my brain ticking now..


Reply to this email directly or view it on GitHub: https://github.com/julesb/rhombrick/issues/1#issuecomment-44911781

Eric Gebhart e.a.gebhart@gmail.com joinfactor = 0.125;

gFocalPoint = [0,0]; gSteps = 10; gHeight = 4;

BezQuadCurve( [[0, 15],[5,5],[10,5],[15,15]], [7.5,0], gSteps, gHeight);

//======================================= // Functions //======================================= function BEZ03(u) = pow((1-u), 3); function BEZ13(u) = 3u(pow((1-u),2)); function BEZ23(u) = 3(pow(u,2))(1-u); function BEZ33(u) = pow(u,3);

function PointAlongBez4(p0, p1, p2, p3, u) = [ BEZ03(u)_p0[0]+BEZ13(u)_p1[0]+BEZ23(u)_p2[0]+BEZ33(u)_p3[0], BEZ03(u)_p0[1]+BEZ13(u)_p1[1]+BEZ23(u)_p2[1]+BEZ33(u)_p3[1]];

//======================================= // Modules //======================================= // c - ControlPoints module BezQuadCurve(c, focalPoint, steps=gSteps, height=gHeight) { // Draw control points // Just comment this out when you're doing the real thing for(point=[0:3]) { translate(c[point]) color([1,0,0]) cylinder(r=1, h=height+joinfactor); }

for(step = [steps:1])
{
    linear_extrude(height = height, convexity = 10) 
    polygon(
        points=[
            focalPoint,
            PointAlongBez4(c[0], c[1], c[2],c[3], step/steps),
            PointAlongBez4(c[0], c[1], c[2],c[3], (step-1)/steps)],
        paths=[[0,1,2,0]]
    );
}

}

//============================================== // Test functions //============================================== //PlotBEZ0(100); //PlotBEZ1(100); //PlotBEZ2(100); //PlotBEZ3(100); //PlotBez4Blending();

module PlotBEZ0(steps) { cubeSize = 1; cubeHeight = steps;

for (step=[0:steps])
{
    translate([cubeSize*step, 0, 0])
    cube(size=[cubeSize, cubeSize, BEZ03(step/steps)*cubeHeight]);
}   

}

module PlotBEZ1(steps) { cubeSize = 1; cubeHeight = steps;

for (step=[0:steps])
{
    translate([cubeSize*step, 0, 0])
    cube(size=[cubeSize, cubeSize, BEZ13(step/steps)*cubeHeight]);
}   

}

module PlotBEZ2(steps) { cubeSize = 1; cubeHeight = steps;

for (step=[0:steps])
{
    translate([cubeSize*step, 0, 0])
    cube(size=[cubeSize, cubeSize, BEZ23(step/steps)*cubeHeight]);
}   

}

module PlotBEZ3(steps) { cubeSize = 1; cubeHeight = steps;

for (step=[0:steps])
{
    translate([cubeSize*step, 0, 0])
    cube(size=[cubeSize, cubeSize, BEZ33(step/steps)*cubeHeight]);
}   

}

module PlotBez4Blending() { sizing = 100;

translate([0, 0, sizing + 10])
PlotBEZ0(100);

translate([sizing+10, 0, sizing + 10])
PlotBEZ1(100);

translate([0, 0, 0])
PlotBEZ2(100);

translate([sizing+10, 0, 0])
PlotBEZ3(100);

}

julesb commented 10 years ago

Yeah I've been having a play with scad-clj and OpenScad, really cool. I wish I had known about it a few months ago when I was exploring the idea of creating tile representation using CSG/boolean ops. It's great to be able to get a reasonably quick preview of a CSG structure. I was using my marching cubes code to preview which was so slow with anything non-trivial that I became less inclined to experiment because of the waiting.

I made a crude attempt at creating a bezier tube in clojure/scad-clj by just getting the points for a bezier curve (in clojure) and then creating a union of spheres centered at each point.

see pic here: http://imgur.com/thWJzUf) It's not much but the code is in rhombrick/scad.clj, recently committed, if you want to look.

This doesn't work that well, and there's lot's of redundant geometry to be processed with all the overlapping spheres. I get a reasonable looking 3d bezier curve in OpenScad but it's taking way to long to do Compile and render(CGAL), which appears to be required to export STL. Possibly OpenSCAD is hanging or getting into a bad state somehow. I didn't let it run for more than around 1/2 an hour (render progress bar not moving) before giving up.

The problem with bezier boxes is that they are not really a generic 3d bezier object. When I made it I was only concerned with curves which connect two inner faces of a rhombic dodecahedron. You will find that the ordering of the four long box edges gets mixed when trying to use arbitrary endpoints. The code is ugly, I'm not sure I want to revisit it. I'm more interested in finding different ways to represent tilecodes as geometry. I consider it an open problem, I'm sure there are interesting ways that I haven't thought of yet.

If you are interested in using bezierboxes as they are, with above mentioned constraints, it wouldn't be that difficult to feed all the bezierbox verts/faces into the OpenScad polyhedron() primitive, plus add a quad at each end so there are no holes. I wouldn't mind having a go at that if you feel you could use it.

Thanks for all the info, very interesting stuff.

EricGebhart commented 10 years ago

I saw you had a pull request to add polyhedron to scad-clj. I've got one to add include and calls into external scad libraries. There is a lot of scad code out there that could be used.

That's pretty cool. I wonder why it is so slow. I have some native scad code that creates rounded rectangles by using overlapping cylinders. I have not seen any slowness from that. It seems to be a common way to create different shapes in scad.

I am interested in creating the tiles, I think they would be really interesting to use as building blocks.

Maybe it would be better to exlpore new ways since you are not so happy with the bezier boxes.

I am creating a few scad-clj libraries at the moment. I need them to create some parts for my printer. I coded them once in scad, Now I'm doing them in clojure. In the process I'm finding things that are missing in scad-clj, so I'm coding that too. I'm working on a bezier plate function now.

I wonder if linear extrude and intersect could be used to good advantage. Create a dodecahedron and then get the intersection of some linear extrusions through it.

I am interested in pursuing this, I think you should do what you think is interesting. I know how it feels to revisit code you don't particularly like. Exploring some new methods could be fun.

Eric

----- julesb's Original Message -----

Yeah I've been having a play with scad-clj and OpenScad, really cool. I wish I had known about it a few months ago when I was exploring the idea of creating tile representation using CSG/boolean ops. It's great to be able to get a reasonably quick preview of a CSG structure. I was using my marching cubes code to preview which was so slow with anything non-trivial that I became less inclined to experiment because of the waiting.

I made a crude attempt at creating a bezier tube in clojure/scad-clj by just getting the points for a bezier curve (in clojure) and then creating a union of spheres centered at each point.

see pic here: http://imgur.com/thWJzUf) It's not much but the code is in rhombrick/scad.clj, recently committed, if you want to look.

This doesn't work that well, and there's lot's of redundant geometry to be processed with all the overlapping spheres. I get a reasonable looking 3d bezier curve in OpenScad but it's taking way to long to do Compile and render(CGAL), which appears to be required to export STL. Possibly OpenSCAD is hanging or getting into a bad state somehow. I didn't let it run for more than around 1/2 an hour (render progress bar not moving) before giving up.

The problem with bezier boxes is that they are not really a generic 3d bezier object. When I made it I was only concerned with curves which connect two inner faces of a rhombic dodecahedron. You will find that the ordering of the four long box edges gets mixed when trying to use arbitrary endpoints. The code is ugly, I'm not sure I want to revisit it. I'm more interested in finding different ways to represent tilecodes as geometry. I consider it an open problem, I'm sure there are interesting ways that I haven't thought of yet.

If you are interested in using bezierboxes as they are, with above mentioned constraints, it wouldn't be that difficult to feed all the bezierbox verts/faces into the OpenScad polyhedron() primitive, plus add a quad at each end so there are no holes. I wouldn't mind having a go at that if you feel you could use it.

Thanks for all the info, very interesting stuff.


Reply to this email directly or view it on GitHub: https://github.com/julesb/rhombrick/issues/1#issuecomment-45431318

Eric Gebhart e.a.gebhart@gmail.com