Skip to content

Commit e8ff45a

Browse files
committed
Merge branch 'master' of https://github.com/RAMilewski/BOSL2
2 parents d36a040 + d6d862c commit e8ff45a

5 files changed

Lines changed: 86 additions & 53 deletions

File tree

attachments.scad

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3871,34 +3871,37 @@ module show_anchors(s=10, std=true, custom=true) {
38713871
}
38723872
}
38733873
}
3874+
textsize = s/4;
38743875
if (custom) {
38753876
for (anchor=last($parent_geom)) {
3876-
attach(anchor[0],BOT) {
3877+
attach(anchor[0]) {
38773878
if(two_d) {
38783879
anchor_arrow2d(s, color="cyan");
38793880
} else {
38803881
anchor_arrow(s, color="cyan");
38813882
}
3882-
color("black")
3883+
3884+
color("white")
38833885
tag("anchor-arrow") {
3884-
xrot(two_d? 0 : 90) {
3885-
back(s/3) {
3886-
yrot_copies(n=2)
3887-
up(two_d? 0.51 : s/30) {
3888-
linear_extrude(height=0.01, convexity=12, center=true) {
3889-
text(text=anchor[0], size=s/4, halign="center", valign="center", font="Helvetica", $fn=36);
3890-
}
3891-
}
3892-
}
3893-
}
3886+
if(two_d)
3887+
back(s/2)
3888+
square([s/4.5*len(anchor[0]), s*.37], center=true);
3889+
else
3890+
up(s*.45)
3891+
xrot(90)
3892+
cube([s/4.5*len(anchor[0]), s*.37, 0.01], center=true);
38943893
}
3895-
color([1, 1, 1, 1])
3894+
color("black")
38963895
tag("anchor-arrow") {
3897-
xrot(two_d? 0 : 90) {
3898-
back(s/3) {
3899-
cube([s/4.5*len(anchor[0]), s/3, 0.01], center=true);
3900-
}
3901-
}
3896+
if(two_d)
3897+
back(s/2)
3898+
text(text=anchor[0], size=textsize, halign="center", valign="center", font="Helvetica", $fn=36);
3899+
else
3900+
up(s*.45)
3901+
xrot(90)
3902+
yrot_copies(n=2)
3903+
up(s/30)
3904+
text3d(text=anchor[0],h=.01, size=textsize, center=true, font="Helvetica", $fn=36);
39023905
}
39033906
}
39043907
}
@@ -3956,12 +3959,12 @@ module anchor_arrow(s=10, color=[0.333,0.333,1], flag=true, $tag="anchor-arrow",
39563959
// Description:
39573960
// Show an anchor orientation arrow.
39583961
// Arguments:
3959-
// s = Length of the arrows.
3962+
// s = Length of the arrows. Default: 10
39603963
// color = Color of the arrow.
39613964
// Example:
39623965
// anchor_arrow2d(s=20);
3963-
module anchor_arrow2d(s=15, color=[0.333,0.333,1], $tag="anchor-arrow") {
3964-
color(color) stroke([[0,0],[0,s]], width=s/10, endcap1="butt", endcap2="arrow2");
3966+
module anchor_arrow2d(s=10, color=[0.333,0.333,1], $tag="anchor-arrow") {
3967+
color(color) stroke([[0,0],[0,s]], width=s/15, endcap1="butt", endcap2="arrow2");
39653968
}
39663969

39673970

rounding.scad

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2429,15 +2429,19 @@ module rounded_prism(bottom, top, joint_bot=0, joint_top=0, joint_sides=0, k_bot
24292429
dummy1 = assert(in_list(atype, ["intersect","hull","surf_intersect","surf_hull","prismoid"]),
24302430
"Anchor type must be one of: \"hull\", \"intersect\", \"surf_hull\", \"surf_intersect\" or \"prismoid\"")
24312431
assert(atype!="prismoid" || len(bottom)==4, "Anchor type \"prismoid\" requires that len(bottom)=4");
2432+
2433+
top_path = force_path(top,"top");
2434+
bot_path = force_path(bottom,"bottom");
24322435

2433-
result = rounded_prism(bottom=bottom, top=top, joint_bot=joint_bot, joint_top=joint_top, joint_sides=joint_sides,
2436+
result = rounded_prism(bottom=bot_path, top=top_path, joint_bot=joint_bot, joint_top=joint_top, joint_sides=joint_sides,
24342437
k_bot=k_bot, k_top=k_top, k_sides=k_sides, k=k, splinesteps=splinesteps, h=h, length=length, height=height, l=l,
24352438
debug=debug, _full_info=true);
24362439
height = one_defined([l,h,height,length], "l,h,height,length", dflt=undef);
2437-
top = is_undef(top) ? path3d(bottom,height/2) :
2438-
len(top[0])==2 ? path3d(top,height/2) :
2439-
top;
2440-
bottom = len(bottom[0])==2 ? path3d(bottom,-height/2) : bottom;
2440+
top = is_undef(top_path) ? path3d(bot_path,height/2) :
2441+
len(top_path[0])==2 ? path3d(top_path,height/2) :
2442+
top_path;
2443+
bottom = len(bot_path[0])==2 ? path3d(bot_path,-height/2) : bot_path;
2444+
24412445
unrounded = vnf_vertex_array([top,bottom],caps=true, col_wrap=true,reverse=true);
24422446

24432447
vnf = result[1];

shapes3d.scad

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,7 +3347,10 @@ function sphere(r, d, anchor=CENTER, spin=0, orient=UP) =
33473347
// vnf = spheroid(r|d, [circum], [style]);
33483348
// Description:
33493349
// Creates a spheroid object, with support for anchoring and attachments.
3350-
// This is a drop-in replacement for the built-in `sphere()` module.
3350+
// This is a drop-in replacement for the built-in `sphere()` module. The `r` or `d` value can
3351+
// be a 3-vector to produce an ellipsoid. This differs from scaling the ellipsoid manually because
3352+
// it doesn't rescale children that you attach to the ellipsoid.
3353+
// .
33513354
// When called as a function, returns a [VNF](vnf.scad) for a spheroid.
33523355
// The exact triangulation of this spheroid can be controlled via the `style=`
33533356
// argument, where the value can be one of `"orig"`, `"aligned"`, `"stagger"`,
@@ -3379,10 +3382,10 @@ function sphere(r, d, anchor=CENTER, spin=0, orient=UP) =
33793382
// The "octa" style has the property that it blends neatly with a cylinder of the same $fn along any of the coordinate axes.
33803383
// This is true for both the regular and circumscribed "octa" spheroid.
33813384
// Arguments:
3382-
// r = Radius of the spheroid.
3385+
// r = Radius of the spheroid or 3-vector giving the 3 semiaxes.
33833386
// style = The style of the spheroid's construction. One of "orig", "aligned", "stagger", "octa", or "icosa". Default: "aligned"
33843387
// ---
3385-
// d = Diameter of the spheroid.
3388+
// d = Diameter of the spheroid or 3-vector giving three axes lengths.
33863389
// circum = If true, the approximate sphere circumscribes the true sphere of the requested size. Otherwise inscribes. Note that for some styles, the circumscribed sphere looks different than the inscribed sphere. Default: false (inscribes)
33873390
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
33883391
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
@@ -3415,6 +3418,8 @@ function sphere(r, d, anchor=CENTER, spin=0, orient=UP) =
34153418
// $fn=16;
34163419
// color("lightblue")spheroid(r=10, style="octa", circum=true);
34173420
// xcyl(r=10.01, h=15, anchor=RIGHT, circum=true);
3421+
// Example: Ellipsoid
3422+
// spheroid(r=[100,50,35]);
34183423
// Example: Anchoring
34193424
// spheroid(d=100, anchor=FRONT);
34203425
// Example: Spin
@@ -3445,10 +3450,11 @@ function sphere(r, d, anchor=CENTER, spin=0, orient=UP) =
34453450
module spheroid(r, style="aligned", d, circum=false, dual=false, anchor=CENTER, spin=0, orient=UP)
34463451
{
34473452
r = get_radius(r=r, d=d, dflt=1);
3448-
sides = segs(r);
3449-
vsides = ceil(sides/2);
3453+
assert((is_finite(r) && r>=0) || (is_vector(r,3) && all_positive(r)),"\nr/d must be a nonnegative value or a positive 3-vector");
34503454
attachable(anchor,spin,orient, r=r) {
34513455
if (style=="orig" && !circum) {
3456+
sides = segs(min(r));
3457+
vsides = ceil(sides/2);
34523458
merids = [ for (i=[0:1:vsides-1]) 90-(i+0.5)*180/vsides ];
34533459
path = [
34543460
let(a = merids[0]) [0, sin(a)],
@@ -3460,9 +3466,11 @@ module spheroid(r, style="aligned", d, circum=false, dual=false, anchor=CENTER,
34603466
// Don't now how to construct faces for these efficiently, so use hull_points, which
34613467
// is much faster than using hull() as happens in the spheroid() function
34623468
else if (circum && (style=="octa" || style=="icosa")) {
3463-
orig_sphere = spheroid(r,style,circum=false);
3469+
minr = min(r);
3470+
scale = r/minr;
3471+
orig_sphere = spheroid(minr,style,circum=false);
34643472
dualvert = _dual_vertices(orig_sphere);
3465-
hull_points(dualvert,fast=true);
3473+
hull_points(scale(scale,dualvert),fast=true);
34663474
} else {
34673475
vnf = spheroid(r=r, circum=circum, style=style);
34683476
vnf_polyhedron(vnf, convexity=2);
@@ -3651,8 +3659,16 @@ let(
36513659
function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, orient=UP) =
36523660
assert(in_list(style, ["orig", "aligned", "stagger", "octa", "icosa"]))
36533661
let(
3654-
r = get_radius(r=r, d=d, dflt=1),
3655-
hsides = segs(r),
3662+
r = get_radius(r=r, d=d, dflt=1)
3663+
)
3664+
is_vector(r,3) ? let(
3665+
minr = min(r),
3666+
scale = r/minr
3667+
)
3668+
scale(scale,spheroid(minr, style=style, circum=circum, anchor=anchor,
3669+
spin=spin, orient=orient))
3670+
: let(
3671+
hsides = segs(min(r)),
36563672
vsides = max(2,ceil(hsides/2)),
36573673
icosa_steps = round(max(5,hsides)/5),
36583674
stagger = style=="stagger"

threading.scad

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,26 +2029,29 @@ module generic_threaded_rod(
20292029
assert(r1adj+pmax-clip_bev1>0, "bevel1 is too large to fit screw diameter")
20302030
assert(r2adj+pmax-clip_bev2>0, "bevel2 is too large to fit screw diameter")
20312031
assert(abs(clip_bev1)+abs(clip_bev2)<len, "Combined bevel size exceeds length of screw");
2032+
20322033
attachable(anchor,spin,orient, r1=r1adj, r2=r2adj, l=len) {
20332034
union(){
20342035
difference() {
2035-
vnf_polyhedron(thread_vnf,convexity=10);
2036-
if (clip_bev1>0)
2037-
rotate_extrude()
2038-
polygon([[ 0,-len/2],
2039-
[r1adj+pmax-clip_bev1 ,-len/2],
2040-
[r1adj+pmax-slope*clip_bev1,-len/2+clip_bev1],
2041-
[ rmax+1,-len/2+clip_bev1],
2042-
[ rmax+1, len1-1],
2043-
[ 0, len1-1]]);
2044-
if (clip_bev2>0)
2045-
rotate_extrude()
2046-
polygon([[ 0, len/2],
2047-
[r2adj+pmax-clip_bev2 , len/2],
2048-
[r2adj+pmax+slope*clip_bev2, len/2-clip_bev2],
2049-
[ rmax+1, len/2-clip_bev2],
2050-
[ rmax+1, len2+1],
2051-
[ 0, len2+1]]);
2036+
vnf_polyhedron(thread_vnf,convexity=10);
2037+
__rot_if_old(){ // works around change in rotate_extrude starting point
2038+
if (clip_bev1>0)
2039+
rotate_extrude(angle=360)
2040+
polygon([[ 0,-len/2],
2041+
[r1adj+pmax-clip_bev1 ,-len/2],
2042+
[r1adj+pmax-slope*clip_bev1,-len/2+clip_bev1],
2043+
[ rmax+1,-len/2+clip_bev1],
2044+
[ rmax+1, len1-1],
2045+
[ 0, len1-1]]);
2046+
if (clip_bev2>0)
2047+
rotate_extrude(angle=360)
2048+
polygon([[ 0, len/2],
2049+
[r2adj+pmax-clip_bev2 , len/2],
2050+
[r2adj+pmax+slope*clip_bev2, len/2-clip_bev2],
2051+
[ rmax+1, len/2-clip_bev2],
2052+
[ rmax+1, len2+1],
2053+
[ 0, len2+1]]);
2054+
}
20522055
if (!blunt_start1 && clip_bev1<=0)
20532056
down(len/2) cuboid([2*rmax+1,2*rmax+1, -len1+1], anchor=TOP);
20542057
if (!blunt_start2 && clip_bev2<=0)
@@ -2094,6 +2097,13 @@ module generic_threaded_rod(
20942097

20952098

20962099

2100+
module __rot_if_old()
2101+
{
2102+
if (version_num()>=20250106) children();
2103+
else zrot(180) children();
2104+
}
2105+
2106+
20972107
// Module: generic_threaded_nut()
20982108
// Synopsis: Creates a generic threaded nut.
20992109
// SynTags: Geom

version.scad

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ _BOSL2_VERSION = is_undef(_BOSL2_STD) && (is_undef(BOSL2_NO_STD_WARNING) || !BOS
1414

1515

1616

17-
BOSL_VERSION = [2,0,743];
17+
BOSL_VERSION = [2,0,744];
1818

1919

2020

0 commit comments

Comments
 (0)