-
Notifications
You must be signed in to change notification settings - Fork 177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possibility of supporting ImplicitCAD (extopenscad)? #134
Comments
I've been following Chris Olah's work for a long time now. Dudes' straight-up brilliant. ImplicitCAD's integral rounding is pretty sweet. I've been revisiting fillets & 2D offsetting in SP in the last couple weeks. I don't know how much you've looked at the OpenSCAD's That doesn't really get you to the impressive state of ImplicitCAD's 3D rounding, though. Because SP is just a translation layer from Python to OpenSCAD, it's difficult to just add functionality to the base functions like A couple directions I could see this going are:
So that's a long way of saying, no, SolidPython probably won't have explicit support for ImplicitCAD; it's different enough that we'd have to make some deep changes and I think it's dangerous for a project to try to serve two masters like that. I'd be happy to see a PyImplicitCAD fork of SP, though. I don't think it would take too much work, and could open up ImplicitCAD's potential use cases a lot farther. If that's something you want to take on, I'd be happy to talk you through any of the less-clear bits of SolidPython's rendering codebase. |
Hmm. On thinking about this a little more, it would actually be a pretty simple (although touching a lot of classes) change to allow all SP classes ( You also might be able to write a monkey-patching system, |
Sounds entertaining. Never monkey patched before, but quick search makes it look straightforward enough. As a starting point (80% solution), I would focus on cube, union, difference, and intersection. Haven't looked at the SolidPython code yet, but is that 4 classes, or noticeably more complicated than that? Guess I should just clone the repo and look :) Glancing and thinking out loud:
|
Just thought I'd mention that you can get a cube with rounded edges using the Minkowski sum with a sphere; in solidpython, e.g.:
That being said, ImplicitCAD does look intriguing, and I'd consider contributing to |
STL generation speed is dependent on the resolution you request. Basically, ImplicitCAD is building a "field strength" model, and then it uses some variant of marching cubes to tile triangles at the "field strength == 0" surface. (Oversimplified, and probably wrong in critical details, but close enough to distinguish it from OpenSCAD's approach) Building up the internal model seems to be ridiculously fast. Marching the cubes over it can be fast, or can be painful... It's a little like setting $fn too high, except that $fn only affects curved surfaces, but setting ImplicitCAD's output resolution too high affects everything. Still, pretty easy to have a couple of resolution settings for preview and final. And the compiler will pick a resolution on its own that lets it do a pretty-fast-but-not-very-clean model. (I love minkowski, but I hate the render times...) |
So... I got to thinking about this one and decided to just go ahead and implement it. I've pushed a trial to a branch, and the monkey patch code is here. Basically, for any of several SolidPython classes (cube, union, etc.), I subclass the original classes and add a from solid.implicit import * #( Or from solid import cube, union... if you want to be precise)
c = cube(2, r=1)
implicitcad_render_to_file(c) # outputs a file with '.escad' suffix by default
I'm going to leave this issue open for now. Ideas or edits welcome! |
Just tried this out on ImplicitCad.org's web editor. Here's a SP version of the first rounded ImplicitCad shape in their docs from solid.implicit import *
a = union(r=14)(
square(80),
translate([80,80])(
circle(30)
)
)
print(implicitcad_render(a)) Yields the ImplicitCad code:
This renders correctly on http://www.implicitcad.org/, but generates a bunch of errors; looks like this feature might require some more massaging to keep those APIs synced up. Error samples from code above:
|
I've never really done animation in OpenSCAD/ImplicitCAD, so I'm probably not going to be much use there, even for ideas. As a ludicrously cheesy pass-through solution, could your implicit rendering code check the type of the values in the object, and if it's a string, just place that string directly in the .escad code? Would allow passing functions into ImplicitCAD, but it's probably too horrible to consider... My personal experience with parameters to ImplicitCAD suggested that it doesn't really understand named parameters. At least, the only way I was able to get stuff to work without errors was to use positional arguments. So, the cube() call (at least for me) had to be Hmmm... Played with that example some more, and it appears that ImplicitCAD does understand named parameters and can handle them being "out of order", but there must be some kind of pre-parser that is out of sync with the actual logic, and uses different rules to validate the syntax. So you get syntax "errors", and then it goes ahead and does the right thing anyway... For now, it looks like the quick patch got the job done, and the extraneous errors need to be fixed on the ImplicitCAD side. |
So, turns out that the "stable" build of ImplicitCAD may be almost 2 years old, so the warnings from the online interpreter might just be stale artifacts. Sounds like you've got a good enough implementation for now. Thanks! |
Nice! I think it wouldn't be too hard to do a custom version of |
Hi guys - I just looked over this some more. There's some more work -- unit tests, documentation, README-- that I want to add before merging to master. I've got some things going on right now (baby on the way, yay!) that mean I may not get to that maintenance work right away, but I'll leave this issue open for the moment with a pointer to the branch for anybody who stumbles on it. I'll update when I've cleaned up all the plumbing work. |
loaded from builtins.openscad (scad)-file - this could be interesting for SolidCode#134 - this is only tested very little! It seems to work pretty well, but might be buggy! (e.g. typos in builtins.openscad)
The mentioned branch above is based ontop of the This allows it to easily replace the complete set of builtins (e.g. OpenSCAD builtins / parameters) with a different set of builtins (e.g. ImplicitCAD builtins / parameters) by just editing or adding an OpenSCAD file which only includes module definitions and looks like this:
If I understand the "issue(s) with ImplicitCAD" right (basically a different set of parameters to the builtins?), this could be a pretty nice way to get there by changing a config file (and reducing the code size). One would only need to create an interface to switch between builtins.openscad and builtins.implicitCAD config file. This is not tested a lot! These are all more drafts and proof of concepts than ready to ship code. |
Works with ImplicitCAD 0.3.0.1 and the online renderer without any issues. BUT this creates limitations: you can't use a lot of libraries (mcad, bosl, bosl2 they all seem to be not ImplicitCAD compatible). You can only use the implicit builtins / api. |
[...]
def ex2():
twist_func = scad_inline_parameter_func("twist(h) = 90*cos(h*2*pi/40)")
return linear_extrude (height = 40, twist = twist_func) (
difference () (
shell(2) (circle (10)),
square(x=[0,20], y=[-4,4]),
)
).rotate(0, 0, 90).left(50)
[...] https://github.com/jeff-dh/SolidPython/blob/exp_solid/solid/examples/15-implicitCAD2.py |
ImplicitCAD doesn't yet have everything that OpenSCAD has. But it does have at least one killer feature that OpenSCAD lacks: trivial fillets for cubes and boolean operations.
https://github.com/colah/ImplicitCAD
(It has several other nice features -- but fillets are the one single thing that would force me to leave OpenSCAD and use FreeCAD or something else that "gets" fillets. So it makes me happy to have them in an "extended OpenSCAD" compiler.)
Instead of
cube([10,10,10]);
, if you saycube([10,10,10],false,1);
, you'll get a 10 unit cube with 1 unit fillets along all edges. (The 'false' is a value for 'centered'. My quick and dirty experiments only worked if I used positional arguments in that order, but there may be better ways to do this).difference(), union(), and intersection() now all take an 'r' parameter that specifies the radius of the fillet to apply along the edges.
It's fairly trivial to load the result of scad_render_to_file(object) into a text editor and just paste the necessary extra parameters into place, but it would be slick if there was some way to do this directly from SolidPython.
Not sure of the best approach, but probably one settable flag to enable .escad output, and then a way to specify a fillet radius. My lazy feeling is to just make it a setting in the solid library, so that I can tell solid to use 1 unit fillets and then go on about my business of creating geometry, knowing that it will apply a 1 unit r to any cubes or operations that it generates. In my head, this seems reasonable, because you probably want the same fillet for each conceptual chunk of your model, so set it once, build, then change it before building a different piece.
You could allow the fillet radius in the cube function easily enough. And you could likewise accept and pass through the fillet in the union/difference/intersection functions. But it's kind of slick to be able to use +, -, and * instead, and there's no straightforward way to give them that extra parameter...
Alternatively, maybe there could be a way to specify a fillet radius for a SCAD object. That seems more complicated to me, because then you have to answer some design questions:
Sorry if this is rambling or disorganized. I found ImplicitCAD and SolidPython essentially on the same day after years of loving OpenSCAD's programmability and hating how hard it made some things. I may have gotten a bit over-excited ;)
The text was updated successfully, but these errors were encountered: