My first OpenSCAD project - open for feedback

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

My first OpenSCAD project - open for feedback

ESF_nl
Proudly I present you my first OpenSCAD project!

I'm not a programmer but managed to program a 'zero clearance insert plate'
for a table saw.
<http://forum.openscad.org/file/t3069/Table_saw_image1.jpg>
Table_saw_zero_clearance_throat_plate_Robland_customizable.zip
<http://forum.openscad.org/file/t3069/Table_saw_zero_clearance_throat_plate_Robland_customizable.zip>  

I'd highly appreciate any feedback.

For example:
- can i better group all add-ons and substractions?
- can i use the if statement (currently marked //)? "If (scope=="first
half")"

Thank you in advance!
Erik




--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: My first OpenSCAD project - open for feedback

JordanBrown
On 1/4/2021 10:42 AM, ESF_nl wrote:
Proudly I present you my first OpenSCAD project! 

For a first project, by a non-programmer, that's really really good.

I haven't reviewed it end-to-end, but one thing that I notice is that in roundedCube you seem to need to do a lot of translation/rotation gymnastics to get the "negative" parts into place.

My biggest hint there is to pick your origin for "meniscus" carefully.  You have its origin being one end of the shape, in the center of the circle.  That might be the most inconvenient place possible.

Here's meniscus(30,10):


First, let's consider the X-Y position.  You're going to want to position this at corners of the thing you're cutting, right?  So design it so that when you position it to that corner, it's in the right place to cut - which means that the origin should be along the corner.  The X-Y origin should be at what is [10,10] in my picture above.  To make it a little more obvious, let's have it cut into +X and +Y.

That shape would then be fundamentally a cube with a translated cylinder subtracted from it.  It will look something like so:
module meniscus(h, r, fn=128){
	$fn=fn;

	difference()
	{
		cube([r, r, h]);
		translate([r,r,0]) cylinder(h=h, r=r);
	}
}


(We'll come back to the Z-fighting adjustment, the 0.2 in your program, in a moment.) 

Next, let's talk about Z.  Where is the object you're cutting going to be in Z?  Is it going to be in +Z, -Z, or centered?

There's an easy trick:  make this "negative" object be three times as long as the biggest edge you're going to cut, and center it in Z.  That way it's long enough, whether you position it at one end, the other, or in the middle.  (Three is overkill.  All you really need is two plus a little.  But 3 is easier to type than 2.1.)

Now, back to the X-Y adjustment for Z-fighting.  A similar trick works:  if we make the cube 2*r in X and Y, and 3*h in Z, and center it, it's all lined up for that cylinder to be subtracted, without having to add and subtract Z-fighting adjustments anywhere.

Once you've done those things, the module will look like
module meniscus(h, r, fn=128){
	$fn=fn;

	difference()
	{
		cube([r*2, r*2, h*3], center=true);
		translate([r,r,0]) cylinder(h=h*9, r=r, center=true);
	}
}

(Note that I applied the times-three-and-center trick to the cylinder so that I don't have to worry about how it aligns with the cube.)

It will produce:


Now, you can easily position and rotate that to each of the edges you need to cut.
w = 20;
d = 30;
h = 10;
r = 3;
cut_h = max(w,d,h);

difference() {
    cube([w, d, h]);
    translate([0,0,0]) rotate([0,0,0]) meniscus(h=cut_h, r=r);
    translate([w,0,0]) rotate([0,0,90]) meniscus(h=cut_h, r=r);
    translate([w,d,0]) rotate([0,0,180]) meniscus(h=cut_h, r=r);
    translate([0,d,0]) rotate([0,0,-90]) meniscus(h=cut_h, r=r);

    translate([0,0,0]) rotate([0,-90,0]) meniscus(h=cut_h, r=r);
    translate([0,0,h]) rotate([0,90,0]) meniscus(h=cut_h, r=r);
    translate([0,d,0]) rotate([90,0,-90]) meniscus(h=cut_h, r=r);
    translate([0,d,h]) rotate([-90,0,-90]) meniscus(h=cut_h, r=r);

    translate([0,0,0]) rotate([90,0,0]) meniscus(h=cut_h, r=r);
    translate([0,0,h]) rotate([-90,0,0]) meniscus(h=cut_h, r=r);
    translate([w,0,0]) rotate([-90,180,0]) meniscus(h=cut_h, r=r);
    translate([w,0,h]) rotate([-90,90,0]) meniscus(h=cut_h, r=r);
}

module meniscus(h, r, fn=128){
	$fn=fn;

	difference()
	{
		cube([r*2, r*2, h*3], center=true);
		translate([r,r,0]) cylinder(h=h*9, r=r, center=true);
	}
}
A final tidbit:  Setting $fn gets you obvious behavior, but it can also seriously hurt performance in some cases.  Performance is highly dependent on the number of faces in your model, with spheres being the biggest contributor.  A common new-user problem is to see that the defaults give you circles that you don't like, set $fn to some big number, and be happy until you do something a bit more complex and can't understand why performance is awful.  You may end up wanting to tweak it for each individual object.  $fa and $fs are a bit more subtle, but can automatically handle most cases without requiring tweaking.

$fn directly controls the number of sides.  Unless you're trying to generate a regular polygon, that's not what you want.  You want to control how far away it is from a perfect circle, with respect to the accuracy of your device (typically, your 3d printer).  At small sizes, you want to have the length of a side be a bit bigger than the printer resolution.  At large sizes, you want to have enough sides that the angle between them is a good approximation of a circle.  Having 128 sides on a 10mm-diameter circle is pointless overkill; each side is less than a quarter of a millimeter.  Even at large sizes, it's more than enough.  $fa and $fs let you adjust things so that you don't have that pointless overkill, but you do have adequate quality at large scale.  Most importantly, you can usually just set a couple of values and leave them alone.

Roughly, $fs controls the behavior of small circles, and $fa controls the behavior of large circles.

Even for a large circle, sides that are 5° across are hard to see.  Set $fa to 5.  For a 100mm-diameter circle, that gets you 72 sides.

Here's a zoomed in picture of that circle.  The sides are barely visible.



Sides much smaller than a millimeter are overkill.  (Even if your circle is only a millimeter across, it's going to be built out of 0.4mm filament traces so there's only so much you can do.)  Set $fs to, say, 2.  For a 10mm-diameter circle, that gets you ~16 sides.  That doesn't seem like very many, but we're talking about a small circle.  This screen shot is about 2x size on my monitor, maybe a bit smaller on yours.  It's still a pretty good-looking circle:



Play with those values, and print samples.  If your small circles aren't smooth enough, make $fs smaller... but that won't make your large circles have more sides than they need.  If your large circles aren't smooth enough, make $fa smaller... but that won't make your small circles have more sides than they need.

Also, since you can probably set these once for your model, you can put them out at the top of the model where you can tweak them to trade off performance versus quality.  If you're having performance problems, set them higher while you're working and then lower when you're ready for a final render.

I think that the OpenSCAD default for $fs, 2, is pretty good.  Maybe 1 would be better.  The $fa default, 12, is I think too big.  I think that if it was 5, many fewer people would feel the need to tweak it.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org