From 15f07e1ac48d4446b9100744646a6113133cc0f2 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Tue, 25 Mar 2025 22:26:08 -0400 Subject: [PATCH 1/3] last of the bugfixes --- rounding.scad | 52 +++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/rounding.scad b/rounding.scad index 5bdc74e9..897ba2eb 100644 --- a/rounding.scad +++ b/rounding.scad @@ -2860,7 +2860,8 @@ Access to the derivative smoothing parameter? // For the cylinder and spherical objects you may wish to joint a prism to the concave surface. You can do this by setting a negative // radius for the base or auxiliary object. When `base_r` is negative, and the joiner prism axis is vertical, the prism root is **below** the // XY plane. In this case it is actually possible to use the same object for base and aux and you can get a joiner prism that crosses a cylindrical -// or spherical hole. +// or spherical hole. You can also attach to the inside of a prism object by setting the corresponding radius to a negative value. Only the sign +// matters in this case. // . // When placing prisms inside a hole, an ambiguity can arise about how to identify the root and end of the joiner prism. The prism axis has // two intersections with a cylinder and both are potentially valid roots. When the auxiliary object is entirely inside the hole, or the auxiliary @@ -3586,7 +3587,7 @@ function join_prism(polygon, base, base_r, base_d, base_T=IDENT, : is_path(base) ? let( mapped = apply(yrot(-90),axisline), - answer = _prism_line_isect(pair(base,wrap=true),mapped,mapped[1])[0] + answer = _prism_line_isect(pair(base,wrap=true),mapped,sign(base_r)*mapped[1])[0] ) assert(answer,"Prism center doesn't intersect prism (base)") apply(yrot(90),answer) @@ -3596,7 +3597,7 @@ function join_prism(polygon, base, base_r, base_d, base_T=IDENT, prism_end_T = aux=="none" ? IDENT : prism_end_T, aux = aux=="none" && aux_fillet!=0 ? "plane" : aux, end_center = apply(aux_T,CENTER), - ndir = base_r<0 ? unit(start_center-start) : unit(end_center-start_center,UP), + ndir = base_r<0 && in_list(base,["cylinder","cyl","sphere"]) ? unit(start_center-start) : unit(end_center-start_center,UP), end_prelim = is_def(end) ? end :apply(move(start)*prism_end_T*move(-start), aux=="sphere" ? @@ -3613,7 +3614,7 @@ function join_prism(polygon, base, base_r, base_d, base_T=IDENT, : is_path(aux) ? let( mapped = apply(yrot(90),[start,start+ndir]), - answer = _prism_line_isect(pair(aux,wrap=true),mapped,mapped[0]-mapped[1])[0] + answer = _prism_line_isect(pair(aux,wrap=true),mapped,sign(aux_r)*(mapped[0]-mapped[1]))[0] //!!! ) assert(answer,"Prism center doesn't intersect prism (aux)") apply(aux_T*yrot(-90),answer) @@ -3634,7 +3635,7 @@ function join_prism(polygon, base, base_r, base_d, base_T=IDENT, : is_path(aux) ? let( mapped = apply(yrot(90)*move(-end_center),[start,end_prelim]), - answer = _prism_line_isect(pair(aux,wrap=true),mapped,mapped[0]-mapped[1])[0] + answer = _prism_line_isect(pair(aux,wrap=true),mapped,sign(aux_r)*(mapped[0]-mapped[1]))[0] ) assert(answer,"Prism center doesn't intersect prism (aux)") apply(move(end_center)*yrot(-90),answer) @@ -3652,7 +3653,7 @@ function join_prism(polygon, base, base_r, base_d, base_T=IDENT, topmesh_reversed = _prism_fillet(_name2,aux, aux_r, aux_top, aux_bot, aux_fillet, aux_k, aux_n, aux_overlap,aux_uniform,aux_smooth_normals,debug), topmesh = apply(aux_T,[for(i=[len(topmesh_reversed)-1:-1:0]) reverse_polygon(topmesh_reversed[i])]), round_dir = select(topmesh,-1)-botmesh[0], - roundings_cross = [for(i=idx(truetop)) if (round_dir[i]*(truetop[i]-truebot[i])<0) echo(truetop[i],truebot[i],round_dir[i]) i], + roundings_cross = [for(i=idx(truetop)) if (round_dir[i]*(truetop[i]-truebot[i])<0) i], vnf = vnf_vertex_array(concat(topmesh,botmesh),col_wrap=true, caps=true, reverse=true) ) assert(debug || roundings_cross==[],"Roundings from the two ends cross on the prism: decrease size of roundings") @@ -3730,7 +3731,7 @@ function _prism_fillet(name, base, R, bot, top, d, k, N, overlap,uniform,smooth_ : base=="plane" ? _prism_fillet_plane(name,bot, top, d, k, N, overlap,debug) : base=="cyl" || base=="cylinder" ? _prism_fillet_cyl(name, R, bot, top, d, k, N, overlap,uniform,debug) : base=="sphere" ? _prism_fillet_sphere(name, R, bot, top, d, k, N, overlap,uniform,debug) - : is_path(base,2) ? _prism_fillet_prism(name, base, bot, top, d, k, N, overlap,uniform,smooth_normals, debug) + : is_path(base,2) ? _prism_fillet_prism(name, base, bot, top, d, k, N, overlap,uniform,smooth_normals, R, debug) : assert(false,"Unknown base type"); @@ -3739,7 +3740,10 @@ function _prism_fillet_plane(name, bot, top, d, k, N, overlap,debug) = dir = sign(top[0].z-bot[0].z), // Negative if we are upside down, with "top" below "bot" isect = [for (i=idx(top)) plane_line_intersection([0,0,1,0], [top[i],bot[i]])] ) - d==0 ? [isect, if (overlap!=0) move(overlap*dir*DOWN,isect)] : + d==0 ? [isect, + if (overlap!=0) isect, + if (overlap!=0) move(overlap*dir*DOWN,isect), + ] : let( base_normal = -path3d(path_normals(path2d(isect), closed=true)), mesh = transpose([for(i=idx(top)) @@ -3774,6 +3778,7 @@ function _prism_fillet_cyl(name, R, bot, top, d, k, N, overlap, uniform, debug) ) d==0 ? yrot(90,[ isect, + if (overlap!=0) isect, if (overlap!=0) [for(p=isect) point3d(unit(point2d(p))*(norm(point2d(p))-sign(R)*overlap),p.z)] ]) : @@ -3821,7 +3826,8 @@ function _prism_fillet_sphere(name, R,bot, top, d, k, N, overlap, uniform, debug ] ) d==0 ? [isect, - if (overlap!=0) [for(p=isect) echo(p=p, overlap=overlap, R=R) p - 0*overlap*sign(R)*unit(p)] + if (overlap!=0) isect, + if (overlap!=0) [for(p=isect) p - overlap*sign(R)*unit(p)] ] : let( tangent = path_tangents(isect,closed=true), @@ -3896,14 +3902,15 @@ function _polygon_step(poly, ind, u, dir, length) = // This function needs more error checking? // Needs check for zero overlap case and zero joint case -function _prism_fillet_prism(name, basepoly, bot, top, d, k, N, overlap, uniform, smooth_normals, debug)= +function _prism_fillet_prism(name, basepoly, bot, top, d, k, N, overlap, uniform, smooth_normals,inside, debug)= let( + inside=sign(inside), top = yrot(-90,top), bot = yrot(-90,bot), basepoly = clockwise_polygon(basepoly), segpairs = pair(basepoly,wrap=true), isect_ind = [for (i=idx(top)) - let(isect = _prism_line_isect(segpairs, [top[i], bot[i]], top[i])) + let(isect = _prism_line_isect(segpairs, [top[i], bot[i]], inside*top[i])) assert(isect, str("Prism doesn't fully intersect prism (",name,")")) isect ], @@ -3914,6 +3921,7 @@ function _prism_fillet_prism(name, basepoly, bot, top, d, k, N, overlap, uniform ) d==0 ? yrot(90,[ isect, + if (overlap!=0) isect, if (overlap!=0) [for(i=idx(isect)) let(normal = point3d(_getnormal(basepoly,index[i],uval[i],smooth_normals))) @@ -3924,7 +3932,7 @@ function _prism_fillet_prism(name, basepoly, bot, top, d, k, N, overlap, uniform mesh = transpose([for(i=idx(top)) let( normal = point3d(_getnormal(basepoly,index[i],uval[i],smooth_normals)), - dir = unit(cross(normal,tangent[i])), + dir = inside*unit(cross(normal,tangent[i])), zpart = d*dir.z, length_needed = d*norm(point2d(dir)), edgept2d = _polygon_step(basepoly, index[i], uval[i], sign(cross(point2d(dir),point2d(normal))), length_needed), @@ -3949,7 +3957,7 @@ function _prism_fillet_prism(name, basepoly, bot, top, d, k, N, overlap, uniform ) [ each bezier_curve(bez, N, endpoint=true), - if (overlap!=0) edgepoint-unit(point3d(normal))*overlap + if (overlap!=0) edgepoint-unit(point3d(normal))*overlap*inside ] ]) ) @@ -4496,21 +4504,22 @@ module prism_connector(profile, desc1, anchor1, desc2, anchor2, shift1=0, shift2 dummy = assert(is_vector(base_anchor) || is_string(base_anchor), "anchor1 must be a string or a 3-vector") assert(is_vector(aux_anchor) || is_string(aux_anchor), "anchor2 must be a string or a 3-vector") assert(is_rotation(auxmap), "desc1 and desc2 are not related to each other by a rotation (and translation)"); - + base_type = _get_obj_type(1,base[1],base_anchor,profile); base_axis = base_type=="cyl" ? base[1][5] : RIGHT; base_edge = _is_geom_an_edge(base[1],base_anchor); - base_r = in_list(base_type,["cyl","sphere"]) ? base[1][1] : undef; + base_r = in_list(base_type,["cyl","sphere"]) ? base[1][1] : 1; base_anch = _find_anchor(base_anchor, base[1]); base_spin = base_anch[3]; base_anch_pos = base_anch[1]; base_anch_dir = base_anch[2]; + prelim_shift1 = _check_join_shift(1,base_type,shift1,true); shift1 = corrected_base_anchor ? corrected_base_anchor[1] + prelim_shift1 : prelim_shift1; aux_type = _get_obj_type(2,aux[1],aux_anchor,profile); aux_anch = _find_anchor(aux_anchor, aux[1]); aux_edge = _is_geom_an_edge(aux[1],aux_anchor); - aux_r = aux_type=="plane" ? undef : aux[1][1]; + aux_r = in_list(aux_type,["cyl","sphere"]) ? aux[1][1] : 1; aux_anch_pos = aux_anch[1]; aux_anch_dir = aux_anch[2]; aux_spin = aux_anch[3]; @@ -4551,6 +4560,7 @@ module prism_connector(profile, desc1, anchor1, desc2, anchor2, shift1=0, shift2 : apply(aux_T * matrix_inverse(aux_to_canonical), aux_anch_pos); base_root = base_type=="plane" || is_list(base_type) || base_anchor==CTR ? CENTER : base_r*UP; + prism_axis = aux_root-base_root; base_inside = prism_axis.z<0 ? -1 : 1; @@ -4592,8 +4602,6 @@ module prism_connector(profile, desc1, anchor1, desc2, anchor2, shift1=0, shift2 move(base_root)rot(from=UP,to=prism_axis) linear_extrude(height=norm(base_root-aux_root))zrot(base_spin-spin)polygon(profile); else{ -// aux_type = is_string(aux_type) ? aux_type : _flip(aux_type); -// base_type = is_string(base_type) ? base_type : _flip(base_type); join_prism(zrot(base_spin-spin,profile), base=base_type, base_r=u_mul(base_r,base_inside), aux=aux_type, aux_T=aux_T, aux_r=u_mul(aux_r,aux_inside), @@ -4608,13 +4616,5 @@ module prism_connector(profile, desc1, anchor1, desc2, anchor2, shift1=0, shift2 } } -function _flip(prof) = - [ - prof[0], - each xflip(prof), - last(prof) - ]; - - // vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap From c4492e07ee19cd23e09cb681cfe80466c9d84423 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Wed, 26 Mar 2025 06:32:03 -0400 Subject: [PATCH 2/3] doc fixes & bugfix --- attachments.scad | 7 +++++++ rounding.scad | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/attachments.scad b/attachments.scad index cea36a33..c76d6e81 100644 --- a/attachments.scad +++ b/attachments.scad @@ -5270,6 +5270,13 @@ function transform_desc(T,desc) = // See the last examples in {{prism_connector()}} for examples using this module. // Arguments: // transforms = list of transformation matrices to apply to the children +// Side Effect: +// `$count` is set to the number of transformations +// `$idx` is set to the index number of the current transformation +// `$is_last` is set to true if this is the last copy and false otherwise +// `$next()` is set to a function literal that produces the next description (see above) +// `$prev()` is set to a function literal that produces the previous description (see above) +// `$desc()` is set to a function literal that produces the description at a specified index (see above) module desc_copies(transforms) { diff --git a/rounding.scad b/rounding.scad index 897ba2eb..f6730d9e 100644 --- a/rounding.scad +++ b/rounding.scad @@ -3560,7 +3560,8 @@ function join_prism(polygon, base, base_r, base_d, base_T=IDENT, assert(!in_list(aux,["sphere","cyl","cylinder"]) || (is_num(aux_r) && !approx(aux_r,0)), str("Must give nonzero aux_r with base ",base)) assert(!short || (in_list(base,["sphere","cyl","cylinder"]) && base_r<0), "You can only set short to true if the base is a sphere or cylinder with radius<0") let( - base_r=default(base_r,0), + base_r=default(base_r,1), + aux_r=default(aux_r,1), polygon=clockwise_polygon(polygon), start_center = CENTER, aux_T_horiz = submatrix(aux_T,[0:2],[0:2]) == ident(3) && aux_T[2][3]==0, @@ -3972,7 +3973,6 @@ function _prism_fillet_prism(name, basepoly, bot, top, d, k, N, overlap, uniform // See Also: parent(), join_prism(), linear_sweep() // Usage: // prism_connector(desc1, anchor1, desc2, anchor2, [spin_align=]); - // Description: // Given descriptions and anchors for two objects, construct a filleted prism that connects the // anchor points on those objects, with a filleted joint at each end. This is an alternative interface From d06a27503e94e5c7f8b08837f78abf3202cb09a2 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Wed, 26 Mar 2025 07:27:54 -0400 Subject: [PATCH 3/3] doc fix --- attachments.scad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attachments.scad b/attachments.scad index c76d6e81..0e6b6ccc 100644 --- a/attachments.scad +++ b/attachments.scad @@ -5270,7 +5270,7 @@ function transform_desc(T,desc) = // See the last examples in {{prism_connector()}} for examples using this module. // Arguments: // transforms = list of transformation matrices to apply to the children -// Side Effect: +// Side Effects: // `$count` is set to the number of transformations // `$idx` is set to the index number of the current transformation // `$is_last` is set to true if this is the last copy and false otherwise