BOSL2
BOSL2 copied to clipboard
Sparse shapes beyond wall
Is your feature request related to a problem? Please describe. I love the strength and efficiency of the sparse wall, but not everything I do is oriented as a wall. Usually I start my design using cuboids and then realize I am wasting too much material and convert them to sparse walls. It drives me crazy to get the orientation and parameters right in the conversion from
cuboid([10,20,30]);
to
sparse_wall(h=10, l=20, thick=30);
Usually the holes end up the wrong direction, then all my anchors and positions get messed up when I try to tweak orientation of the wall.
Describe the solution you'd like At this point, I'd like to see a sparse cuboid, but if it makes sense, this could be expanded to other 3d shapes. A sparse_cuboid takes the same parameters as a cuboid, but adds the cutouts of the sparse_wall and puts the cutouts in the right orientation.
Describe alternatives you've considered Here's my lame version of a sparse cuboid. It assumes the holes should align with the shortest dimension. A more elegant version might have a parameter that chooses hole orientation. I would love it if all the features of cuboids were available, like rounding.
Example Code
include <BOSL2/std.scad>
include <BOSL2/walls.scad>
module sparse_cuboid(size, maxang=30, strut=5, max_bridge=20, anchor=CENTER, spin=0, orient=UP) {
if (size[0] <= size[1] && size[0] <= size[2]) // x skinny
attachable(anchor=anchor, spin=spin, orient=orient, size=size) {
sparse_wall(h=size[2], l=size[1], thick=size[0], maxang=maxang, strut=strut,
max_bridge=max_bridge);
children();
}
else if (size[1] <= size[0] && size[1] <= size[2]) // y skinny
attachable(anchor=anchor, spin=spin, orient=orient, size=size) {
zrot(90) sparse_wall(h=size[2], l=size[0], thick=size[1], maxang=maxang, strut=strut,
max_bridge=max_bridge);
children();
}
else if (size[2] <= size[0] && size[2] <= size[1]) // z skinny
attachable(anchor=anchor, spin=spin, orient=orient, size=size) {
xrot(90) zrot(90) sparse_wall(h=size[0], l=size[1], thick=size[2], maxang=maxang, strut=strut,
max_bridge=max_bridge);
children();
}
else echo("Failed sparse cuboid");
}
Here's what three cuboids look like when converted to sparse_wall.
Here's what I would like it to look like:
sparse_cuboid([10,20,30], strut=1);
fwd(30) sparse_cuboid([30,20,10], strut=1);
fwd(60) sparse_cuboid([20,10,30], strut=1);
Yes, these are the same three shapes with different orientation, but I can never figure out how to fix the orientation without major side-effects.
sparse_wall(h=30, l=20, thick=10, strut=1);
I think I'm confused. Is this proposal just an interface change to use a size=[X,Y,Z] triplet, with the holes through the skinny axis?
It's to use the triplet and manage the orientation of the holes (and ideally, the other cuboid parameters like rounding).
The rightmost shape in my example is the shape you reproduced, and is the shape oriented correctly for the sparse_wall. The other two shapes have suboptimal holes cut compared to my ideal results.
My full request would be for any 3d shape to be sparseable.
Making cylinders sparseable along their axis is doable, but I'm unclear that spheres or arbitrary 3D shapes would be practical.
Agreed on arbitrary shapes, that would be too broad. Prismoids, wedges, and octahedrons would be the other shapes from the library that could be practical.
I would imagine a sphere would be something like this, assuming someone smarter than me figured out how to size the holes correctly. And maybe instead of circular holes, you could do cutout so that the remaining material was essentially the lat/long lines of the sphere.
Probably would get better results with a phi spiral a la sphere_copies().
difference() {
sphere(d=100);
sphere(d=80);
sphere_copies(d=100, n=50, cone_ang=180) cyl(d=10, h=20, anchor=CTR);
}
Wireframed icosahedrons could be useful too.
vnf_wireframe(spheroid(d=100, style="icosa", $fn=5), width=5, $fn=24);
This can, of course be increased in sides by upping the first $fn= in increments of 5.
would a "sparse_wall_mask" that could be constrained take a polygon address some of these issues? Then it could be attached with diff() to faces of any object.
module sparse_cuboid(size, dir, strut=5, maxang=30, max_bridge=20,
chamfer,
rounding,
edges=EDGES_ALL,
except=[],
except_edges,
trimcorners=true,
teardrop=false,
anchor=CENTER, spin=0, orient=UP)
{
dummy1=assert(is_vector(dir,3), "dir must be a 3-vector");
count = len([for(d=dir) if (d!=0) d]);
dummy2=assert(count==1 && len(dir)<=3, "dir must have exactly one non-zero component");
attachable(anchor,spin,orient,size=size){
intersection(){
if (dir.x)
sparse_wall(size.z,size.y,size.x,strut=strut,maxang=maxang, max_bridge=max_bridge);
else if (dir.y)
zrot(90)
sparse_wall(size.z,size.x,size.y,strut=strut,maxang=maxang, max_bridge=max_bridge);
else
yrot(90)
sparse_wall(size.x,size.y,size.z,strut=strut,maxang=maxang, max_bridge=max_bridge);
cuboid(size=size, chamfer=chamfer, rounding=rounding,edges=edges, except=except, except_edges=except_edges,
trimcorners=trimcorners, teardrop=teardrop);
}
children();
}
}
sparse_cuboid([10,20,30], strut=1, dir=RIGHT, rounding=3);
fwd(30) sparse_cuboid([30,20,10], strut=1, dir=UP, chamfer=1);
fwd(60) sparse_cuboid([20,10,30], strut=1, dir=FWD);
So something like the above? Seems like you can get into trouble with roundings. And also what you really want is for all the bracing to be rounded as well, which unlike the above, is nontrivial.
I agree with jdanders comment "but I can never figure out how to fix the orientation without major side-effects", and in my case at least, it applies in other parts of BOSL2. (e.g. linear_sweep()). Hence our discussion recently on Gitter about having a "reset" for the reference frame.
If you've built a model with objects that have children and change the orientation of an object it will screw up everything downstream. But a "reset" will only help if the object in question has enough symmetry that it's anchors don't change when you change the orientation. Otherwise you'll have trouble with positioning.