nophead / NopSCADlib

Library of parts modelled in OpenSCAD and a framework for making projects
GNU General Public License v3.0
1.17k stars 155 forks source link

Horicylinder too tall and doesn't compile at layer_hight=2 extrusion_width=0.5 #241

Open drf5n opened 1 year ago

drf5n commented 1 year ago

There's a couple extra layers on top of a horicylinder if the layer_height >= 4 extrusion_width. This is an odd case, but I was looking at printing out how 3DP holes work in a tangible-sized model and ran into this unexpected rendering/problem.

image


$explode = 0; // [0, 1]
assembly = "main"; // [main, back, RPI, case, enviro_case, RPI_case]

/* [Hidden] */

show_box = true;
show_enviroplus = true;
$pp1_colour = "grey";
$extrusion_width = 0.5;

// slicing params, for modules that car about filaments, like horihole
$nozzle = 0.4;
$layer_height = 1; // default 0.25 in global_defs.scad
$layer_height0 = 0.2; // default 0.25 in global_defs.scad

include <NopSCADlib/lib.scad>
//use <NopSCADlib/utils/core/core.scad>
//use <NopSCADlib/utils/core/teardrops.scad> // 
use <NopSCADlib/utils/horiholes.scad> // https://github.com/nophead/NopSCADlib/blob/master/utils/horiholes.scad

translate([10,0,0])ex2(z=0,h=10);

module ex2(d=5,z=0,h=0){
  rotate([00,0,0]){

    // cylinder(h=h*2,d=d,center=true);
      horicylinder(d/2,z=z,h=h);

      translate([d*2,0,0])difference(){
          cube([d*3,d*3,h]);
          translate([d*3/2,d*3/2,-eps])horihole(d/2,z=z,h=h+2*eps,center=false);
      //teardrop_plus(r=d/2,h=h*2); 

      }
  }
}  
nophead commented 1 year ago

I think layer height > width isn't physically possible because the nozzle would be too high to place the filament on the bed, or the layer below.

layer_heigth0 is a new addition and only affects round_to_layer at the moment. These utilities would need changing to take it into account I think. I will take a look later as I have to go out now.

drf5n commented 1 year ago

Yes, it is a muddled, out-of-bounds edge case. At first I was trying to understand horiholes and horicylinders using only use <NopSCADlib/utils/horiholes.scad>, then core, and then lib.scad for the teardrops, etc...

Because:

for(i = [-10:1:10]){
echo(str("i = ",i,": ",teardrop_minus_x(5, i, 1)));
}

result: 
ECHO: "i = -10: 0"
ECHO: "i = -9: 0"
ECHO: "i = -8: 0"
ECHO: "i = -7: 0"
ECHO: "i = -6: 0"
ECHO: "i = -5: 0"
ECHO: "i = -4: 0"
ECHO: "i = -3: 3.8541"
ECHO: "i = -2: 4.53113"
ECHO: "i = -1: 4.88748"
ECHO: "i = 0: 5"
ECHO: "i = 1: 4.88748"
ECHO: "i = 2: 4.53113"
ECHO: "i = 3: 3.8541"
ECHO: "i = 4: 2.56155"
ECHO: "i = 5: 0.5"
ECHO: "i = 6: 0.5"
ECHO: "i = 7: 0.5"
ECHO: "i = 8: 0.5"
ECHO: "i = 9: 0.5"
ECHO: "i = 10: 0.5"

...it might be in here:

https://github.com/nophead/NopSCADlib/blob/master/utils/horiholes.scad#L59-L67

function teardrop_minus_x(r, y, h) = //! Calculate the ordinate of a compensated teardrop given y and layer height.
    let(fr = h / 2,
        hpot = r - fr,
        x2 = sqr(hpot) - sqr(y),
        x = x2 > 0 ? sqrt(x2) : 0,
        X = y >= -hpot / sqrt(2) ? x + fr : 0
    )
    X >= extrusion_width ? X : 0;

If When x goes to zero above the hole, then X = fr, and then if fr >= extrusion_width, tearDrop_minus will return the filament radius.

nophead commented 1 year ago

Probably needs an assert() to check extrusion_width >= layer_height. It can never be less when extruding a perimeter. The filament is either squashed to make it wider than it is high or it just has a circular cross section if not. It can't be stretched vertically.