last of the bugfixes

This commit is contained in:
Adrian Mariano
2025-03-25 22:26:08 -04:00
parent 49a439fc3d
commit 15f07e1ac4

View File

@@ -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 // 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 // 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 // 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 // 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 // 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) ? : is_path(base) ?
let( let(
mapped = apply(yrot(-90),axisline), 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)") assert(answer,"Prism center doesn't intersect prism (base)")
apply(yrot(90),answer) 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, prism_end_T = aux=="none" ? IDENT : prism_end_T,
aux = aux=="none" && aux_fillet!=0 ? "plane" : aux, aux = aux=="none" && aux_fillet!=0 ? "plane" : aux,
end_center = apply(aux_T,CENTER), 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 end_prelim = is_def(end) ? end
:apply(move(start)*prism_end_T*move(-start), :apply(move(start)*prism_end_T*move(-start),
aux=="sphere" ? aux=="sphere" ?
@@ -3613,7 +3614,7 @@ function join_prism(polygon, base, base_r, base_d, base_T=IDENT,
: is_path(aux) ? : is_path(aux) ?
let( let(
mapped = apply(yrot(90),[start,start+ndir]), 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)") assert(answer,"Prism center doesn't intersect prism (aux)")
apply(aux_T*yrot(-90),answer) 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) ? : is_path(aux) ?
let( let(
mapped = apply(yrot(90)*move(-end_center),[start,end_prelim]), 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)") assert(answer,"Prism center doesn't intersect prism (aux)")
apply(move(end_center)*yrot(-90),answer) 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_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])]), topmesh = apply(aux_T,[for(i=[len(topmesh_reversed)-1:-1:0]) reverse_polygon(topmesh_reversed[i])]),
round_dir = select(topmesh,-1)-botmesh[0], 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) 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") 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=="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=="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) : 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"); : 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" 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]])] 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( let(
base_normal = -path3d(path_normals(path2d(isect), closed=true)), base_normal = -path3d(path_normals(path2d(isect), closed=true)),
mesh = transpose([for(i=idx(top)) 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,[ d==0 ? yrot(90,[
isect, isect,
if (overlap!=0) isect,
if (overlap!=0) [for(p=isect) point3d(unit(point2d(p))*(norm(point2d(p))-sign(R)*overlap),p.z)] 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, 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( let(
tangent = path_tangents(isect,closed=true), tangent = path_tangents(isect,closed=true),
@@ -3896,14 +3902,15 @@ function _polygon_step(poly, ind, u, dir, length) =
// This function needs more error checking? // This function needs more error checking?
// Needs check for zero overlap case and zero joint case // 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( let(
inside=sign(inside),
top = yrot(-90,top), top = yrot(-90,top),
bot = yrot(-90,bot), bot = yrot(-90,bot),
basepoly = clockwise_polygon(basepoly), basepoly = clockwise_polygon(basepoly),
segpairs = pair(basepoly,wrap=true), segpairs = pair(basepoly,wrap=true),
isect_ind = [for (i=idx(top)) 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,")")) assert(isect, str("Prism doesn't fully intersect prism (",name,")"))
isect isect
], ],
@@ -3914,6 +3921,7 @@ function _prism_fillet_prism(name, basepoly, bot, top, d, k, N, overlap, uniform
) )
d==0 ? yrot(90,[ d==0 ? yrot(90,[
isect, isect,
if (overlap!=0) isect,
if (overlap!=0) if (overlap!=0)
[for(i=idx(isect)) [for(i=idx(isect))
let(normal = point3d(_getnormal(basepoly,index[i],uval[i],smooth_normals))) 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)) mesh = transpose([for(i=idx(top))
let( let(
normal = point3d(_getnormal(basepoly,index[i],uval[i],smooth_normals)), 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, zpart = d*dir.z,
length_needed = d*norm(point2d(dir)), length_needed = d*norm(point2d(dir)),
edgept2d = _polygon_step(basepoly, index[i], uval[i], sign(cross(point2d(dir),point2d(normal))), length_needed), 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), each bezier_curve(bez, N, endpoint=true),
if (overlap!=0) edgepoint-unit(point3d(normal))*overlap if (overlap!=0) edgepoint-unit(point3d(normal))*overlap*inside
] ]
]) ])
) )
@@ -4500,17 +4508,18 @@ module prism_connector(profile, desc1, anchor1, desc2, anchor2, shift1=0, shift2
base_type = _get_obj_type(1,base[1],base_anchor,profile); base_type = _get_obj_type(1,base[1],base_anchor,profile);
base_axis = base_type=="cyl" ? base[1][5] : RIGHT; base_axis = base_type=="cyl" ? base[1][5] : RIGHT;
base_edge = _is_geom_an_edge(base[1],base_anchor); 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_anch = _find_anchor(base_anchor, base[1]);
base_spin = base_anch[3]; base_spin = base_anch[3];
base_anch_pos = base_anch[1]; base_anch_pos = base_anch[1];
base_anch_dir = base_anch[2]; base_anch_dir = base_anch[2];
prelim_shift1 = _check_join_shift(1,base_type,shift1,true); prelim_shift1 = _check_join_shift(1,base_type,shift1,true);
shift1 = corrected_base_anchor ? corrected_base_anchor[1] + prelim_shift1 : prelim_shift1; shift1 = corrected_base_anchor ? corrected_base_anchor[1] + prelim_shift1 : prelim_shift1;
aux_type = _get_obj_type(2,aux[1],aux_anchor,profile); aux_type = _get_obj_type(2,aux[1],aux_anchor,profile);
aux_anch = _find_anchor(aux_anchor, aux[1]); aux_anch = _find_anchor(aux_anchor, aux[1]);
aux_edge = _is_geom_an_edge(aux[1],aux_anchor); 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_pos = aux_anch[1];
aux_anch_dir = aux_anch[2]; aux_anch_dir = aux_anch[2];
aux_spin = aux_anch[3]; 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); : 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; base_root = base_type=="plane" || is_list(base_type) || base_anchor==CTR ? CENTER : base_r*UP;
prism_axis = aux_root-base_root; prism_axis = aux_root-base_root;
base_inside = prism_axis.z<0 ? -1 : 1; 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) move(base_root)rot(from=UP,to=prism_axis)
linear_extrude(height=norm(base_root-aux_root))zrot(base_spin-spin)polygon(profile); linear_extrude(height=norm(base_root-aux_root))zrot(base_spin-spin)polygon(profile);
else{ 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), join_prism(zrot(base_spin-spin,profile),
base=base_type, base_r=u_mul(base_r,base_inside), 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), 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 // vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap