mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-07 15:58:41 +02:00
linear_sweep() fixes and tweaks to xrgn geometries.
This commit is contained in:
@@ -1567,7 +1567,7 @@ function named_anchor(name, pos, orient=UP, spin=0) = [name, pos, orient, spin];
|
|||||||
// Usage: Spheroid/Ovoid Geometry
|
// Usage: Spheroid/Ovoid Geometry
|
||||||
// geom = attach_geom(r=|d=, ...);
|
// geom = attach_geom(r=|d=, ...);
|
||||||
// Usage: Extruded 2D Path/Polygon/Region Geometry
|
// Usage: Extruded 2D Path/Polygon/Region Geometry
|
||||||
// geom = attach_geom(region=, l=|h=, [extent=], ...);
|
// geom = attach_geom(region=, l=|h=, [extent=], [shift=], [scale=], [twist=], ...);
|
||||||
// Usage: VNF Geometry
|
// Usage: VNF Geometry
|
||||||
// geom = attach_geom(vnf=, [extent=], ...);
|
// geom = attach_geom(vnf=, [extent=], ...);
|
||||||
//
|
//
|
||||||
@@ -1583,6 +1583,8 @@ function named_anchor(name, pos, orient=UP, spin=0) = [name, pos, orient, spin];
|
|||||||
// size = If given as a 3D vector, contains the XY size of the bottom of the cuboidal/prismoidal volume, and the Z height. If given as a 2D vector, contains the front X width of the rectangular/trapezoidal shape, and the Y length.
|
// size = If given as a 3D vector, contains the XY size of the bottom of the cuboidal/prismoidal volume, and the Z height. If given as a 2D vector, contains the front X width of the rectangular/trapezoidal shape, and the Y length.
|
||||||
// size2 = If given as a 2D vector, contains the XY size of the top of the prismoidal volume. If given as a number, contains the back width of the trapezoidal shape.
|
// size2 = If given as a 2D vector, contains the XY size of the top of the prismoidal volume. If given as a number, contains the back width of the trapezoidal shape.
|
||||||
// shift = If given as a 2D vector, shifts the top of the prismoidal or conical shape by the given amount. If given as a number, shifts the back of the trapezoidal shape right by that amount. Default: No shift.
|
// shift = If given as a 2D vector, shifts the top of the prismoidal or conical shape by the given amount. If given as a number, shifts the back of the trapezoidal shape right by that amount. Default: No shift.
|
||||||
|
// scale = If given as number or a 2D vector, scales the top of the shape, relative to the bottom. Default: `[1,1]`
|
||||||
|
// twist = If given as number, rotates the top of the shape by the given number of degrees clockwise, relative to the bottom. Default: `0`
|
||||||
// r = Radius of the cylindrical/conical volume. Can be a scalar, or a list of sizes per axis.
|
// r = Radius of the cylindrical/conical volume. Can be a scalar, or a list of sizes per axis.
|
||||||
// d = Diameter of the cylindrical/conical volume. Can be a scalar, or a list of sizes per axis.
|
// d = Diameter of the cylindrical/conical volume. Can be a scalar, or a list of sizes per axis.
|
||||||
// r1 = Radius of the bottom of the conical volume. Can be a scalar, or a list of sizes per axis.
|
// r1 = Radius of the bottom of the conical volume. Can be a scalar, or a list of sizes per axis.
|
||||||
@@ -1663,7 +1665,8 @@ function named_anchor(name, pos, orient=UP, spin=0) = [name, pos, orient, spin];
|
|||||||
// geom = attach_geom(region=region, l=length, extent=false);
|
// geom = attach_geom(region=region, l=length, extent=false);
|
||||||
//
|
//
|
||||||
function attach_geom(
|
function attach_geom(
|
||||||
size, size2, shift,
|
size, size2,
|
||||||
|
shift, scale, twist,
|
||||||
r,r1,r2, d,d1,d2, l,h,
|
r,r1,r2, d,d1,d2, l,h,
|
||||||
vnf, region,
|
vnf, region,
|
||||||
extent=true,
|
extent=true,
|
||||||
@@ -1713,9 +1716,17 @@ function attach_geom(
|
|||||||
? ["rgn_extent", region, cp, offset, anchors]
|
? ["rgn_extent", region, cp, offset, anchors]
|
||||||
: ["rgn_isect", region, cp, offset, anchors]
|
: ["rgn_isect", region, cp, offset, anchors]
|
||||||
: assert(is_finite(l))
|
: assert(is_finite(l))
|
||||||
|
let(
|
||||||
|
shift = default(shift, [0,0]),
|
||||||
|
scale = is_num(scale)? [scale,scale] : default(scale, [1,1]),
|
||||||
|
twist = default(twist, 0)
|
||||||
|
)
|
||||||
|
assert(is_vector(shift,2))
|
||||||
|
assert(is_vector(scale,2))
|
||||||
|
assert(is_num(twist))
|
||||||
extent==true
|
extent==true
|
||||||
? ["xrgn_extent", region, l, cp, offset, anchors]
|
? ["xrgn_extent", region, l, twist, scale, shift, cp, offset, anchors]
|
||||||
: ["xrgn_isect", region, l, cp, offset, anchors]
|
: ["xrgn_isect", region, l, twist, scale, shift, cp, offset, anchors]
|
||||||
) :
|
) :
|
||||||
let(
|
let(
|
||||||
r1 = get_radius(r1=r1,d1=d1,r=r,d=d,dflt=undef)
|
r1 = get_radius(r1=r1,d1=d1,r=r,d=d,dflt=undef)
|
||||||
@@ -1922,7 +1933,7 @@ function _get_cp(geom) =
|
|||||||
assert(type!="other", "Invalid cp value")
|
assert(type!="other", "Invalid cp value")
|
||||||
cp=="centroid" ? (
|
cp=="centroid" ? (
|
||||||
type=="vnf" && (len(geom[1][0])==0 || len(geom[1][1])==0) ? [0,0,0] :
|
type=="vnf" && (len(geom[1][0])==0 || len(geom[1][1])==0) ? [0,0,0] :
|
||||||
[each centroid(geom[1]), if (type=="xpath") geom[2]/2]
|
[each centroid(geom[1]), if (type=="xpath") 0]
|
||||||
)
|
)
|
||||||
: let(points = type=="vnf"?geom[1][0]:flatten(force_region(geom[1])))
|
: let(points = type=="vnf"?geom[1][0]:flatten(force_region(geom[1])))
|
||||||
cp=="mean" ? [each mean(points), if (type=="xpath") geom[2]/2]
|
cp=="mean" ? [each mean(points), if (type=="xpath") geom[2]/2]
|
||||||
@@ -2160,11 +2171,21 @@ function _find_anchor(anchor, geom) =
|
|||||||
assert(in_list(anchor.z,[-1,0,1]), "The Z component of an anchor for an extruded 2D shape must be -1, 0, or 1.")
|
assert(in_list(anchor.z,[-1,0,1]), "The Z component of an anchor for an extruded 2D shape must be -1, 0, or 1.")
|
||||||
let(
|
let(
|
||||||
anchor_xy = point2d(anchor),
|
anchor_xy = point2d(anchor),
|
||||||
L = geom[2]
|
rgn = geom[1],
|
||||||
|
L = geom[2],
|
||||||
|
twist = geom[3],
|
||||||
|
scale = geom[4],
|
||||||
|
shift = geom[5],
|
||||||
|
u = (anchor.z + 1) / 2,
|
||||||
|
shmat = move(lerp([0,0], shift, u)),
|
||||||
|
scmat = scale(lerp([1,1], scale, u)),
|
||||||
|
twmat = zrot(lerp(0, -twist, u)),
|
||||||
|
mat = shmat * scmat * twmat
|
||||||
)
|
)
|
||||||
approx(anchor_xy,[0,0]) ? [anchor, up(anchor.z*L/2,cp), anchor, oang] :
|
approx(anchor_xy,[0,0]) ? [anchor, apply(mat, up(anchor.z*L/2,cp)), anchor, oang] :
|
||||||
let(
|
let(
|
||||||
newgeom = list_set(geom, [0,len(geom)-3], [substr(geom[0],1), point2d(cp)]),
|
newrgn = apply(mat, rgn),
|
||||||
|
newgeom = attach_geom(two_d=true, region=newrgn, extent=type=="xrgn_extent", cp=cp),
|
||||||
result2d = _find_anchor(anchor_xy, newgeom),
|
result2d = _find_anchor(anchor_xy, newgeom),
|
||||||
pos = point3d(result2d[1], cp.z+anchor.z*L/2),
|
pos = point3d(result2d[1], cp.z+anchor.z*L/2),
|
||||||
vec = unit(point3d(result2d[2], anchor.z),UP),
|
vec = unit(point3d(result2d[2], anchor.z),UP),
|
||||||
|
41
skin.scad
41
skin.scad
@@ -523,15 +523,14 @@ function skin(profiles, slices, refine=1, method="direct", sampling, caps, close
|
|||||||
// maxseg = If given, then any long segments of the region will be subdivided to be shorter than this length. This can refine twisting flat faces a lot. Default: `undef` (no subsampling)
|
// maxseg = If given, then any long segments of the region will be subdivided to be shorter than this length. This can refine twisting flat faces a lot. Default: `undef` (no subsampling)
|
||||||
// style = The style to use when triangulating the surface of the object. Valid values are `"default"`, `"alt"`, or `"quincunx"`.
|
// style = The style to use when triangulating the surface of the object. Valid values are `"default"`, `"alt"`, or `"quincunx"`.
|
||||||
// convexity = Max number of surfaces any single ray could pass through. Module use only.
|
// convexity = Max number of surfaces any single ray could pass through. Module use only.
|
||||||
// cp = Centerpoint for determining intersection anchors or centering the shape. Determines the base of the anchor vector. Can be "centroid", "mean", "box" or a 3D point. Default: `[0,0,0]`
|
// cp = Centerpoint for determining intersection anchors or centering the shape. Determines the base of the anchor vector. Can be "centroid", "mean", "box" or a 3D point. Default: `"centroid"`
|
||||||
// atype = Set to "hull" or "intersect" to select anchor type. Default: "hull"
|
// atype = Set to "hull" or "intersect" to select anchor type. Default: "hull"
|
||||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `"origin"`
|
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `"origin"`
|
||||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
|
||||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#subsection-orient). Default: `UP`
|
||||||
// Extra Anchors:
|
// Extra Anchors:
|
||||||
// centroid_top = The centroid of the top of the shape, oriented UP.
|
// "origin" = Centers the extruded shape vertically only, but keeps the original path positions in the X and Y. Oriented UP.
|
||||||
// centroid = The centroid of the center of the shape, oriented UP.
|
// "original_base" = Keeps the original path positions in the X and Y, but at the bottom of the extrusion. Oriented UP.
|
||||||
// centroid_bot = The centroid of the bottom of the shape, oriented DOWN.
|
|
||||||
// Example: Extruding a Compound Region.
|
// Example: Extruding a Compound Region.
|
||||||
// rgn1 = [for (d=[10:10:60]) circle(d=d,$fn=8)];
|
// rgn1 = [for (d=[10:10:60]) circle(d=d,$fn=8)];
|
||||||
// rgn2 = [square(30,center=false)];
|
// rgn2 = [square(30,center=false)];
|
||||||
@@ -574,27 +573,27 @@ module linear_sweep(
|
|||||||
region, height, center,
|
region, height, center,
|
||||||
twist=0, scale=1, shift=[0,0],
|
twist=0, scale=1, shift=[0,0],
|
||||||
slices, maxseg, style="default", convexity,
|
slices, maxseg, style="default", convexity,
|
||||||
cp=[0,0,0], atype="hull", h,
|
cp, atype="hull", h,
|
||||||
anchor, spin=0, orient=UP
|
anchor, spin=0, orient=UP
|
||||||
) {
|
) {
|
||||||
h = first_defined([h, height, 1]);
|
h = first_defined([h, height, 1]);
|
||||||
region = force_region(region);
|
region = force_region(region);
|
||||||
check = assert(is_region(region),"Input is not a region");
|
check = assert(is_region(region),"Input is not a region");
|
||||||
anchor = get_anchor(anchor, center, BOT, BOT);
|
anchor = center==true? "origin" :
|
||||||
|
center == false? "original_base" :
|
||||||
|
default(anchor, "original_base");
|
||||||
vnf = linear_sweep(
|
vnf = linear_sweep(
|
||||||
region, height=h, style=style,
|
region, height=h, style=style,
|
||||||
twist=twist, scale=scale, shift=shift,
|
twist=twist, scale=scale, shift=shift,
|
||||||
slices=slices, maxseg=maxseg,
|
slices=slices, maxseg=maxseg,
|
||||||
anchor=CTR
|
anchor="origin"
|
||||||
);
|
);
|
||||||
cent = centroid(region);
|
|
||||||
anchors = [
|
anchors = [
|
||||||
named_anchor("centroid_top", point3d(cent, h/2), UP),
|
named_anchor("original_base", [0,0,-h/2], UP)
|
||||||
named_anchor("centroid", point3d(cent), UP),
|
|
||||||
named_anchor("centroid_bot", point3d(cent,-h/2), DOWN)
|
|
||||||
];
|
];
|
||||||
geom = atype=="hull"? attach_geom(cp=cp, region=region, h=h, extent=true, anchors=anchors) :
|
cp = default(cp, "centroid");
|
||||||
atype=="intersect"? attach_geom(cp=cp, region=region, h=h, extent=false, anchors=anchors) :
|
geom = atype=="hull"? attach_geom(cp=cp, region=region, h=h, extent=true, shift=shift, scale=scale, twist=twist, anchors=anchors) :
|
||||||
|
atype=="intersect"? attach_geom(cp=cp, region=region, h=h, extent=false, shift=shift, scale=scale, twist=twist, anchors=anchors) :
|
||||||
assert(in_list(atype, ["hull", "intersect"]));
|
assert(in_list(atype, ["hull", "intersect"]));
|
||||||
attachable(anchor,spin,orient, geom=geom) {
|
attachable(anchor,spin,orient, geom=geom) {
|
||||||
vnf_polyhedron(vnf, convexity=convexity);
|
vnf_polyhedron(vnf, convexity=convexity);
|
||||||
@@ -607,7 +606,7 @@ function linear_sweep(
|
|||||||
region, height, center,
|
region, height, center,
|
||||||
twist=0, scale=1, shift=[0,0],
|
twist=0, scale=1, shift=[0,0],
|
||||||
slices, maxseg, style="default",
|
slices, maxseg, style="default",
|
||||||
cp=[0,0,0], atype="hull", h,
|
cp, atype="hull", h,
|
||||||
anchor, spin=0, orient=UP
|
anchor, spin=0, orient=UP
|
||||||
) =
|
) =
|
||||||
let( region = force_region(region) )
|
let( region = force_region(region) )
|
||||||
@@ -616,7 +615,9 @@ function linear_sweep(
|
|||||||
assert(is_vector(shift, 2), str(shift))
|
assert(is_vector(shift, 2), str(shift))
|
||||||
let(
|
let(
|
||||||
h = first_defined([h, height, 1]),
|
h = first_defined([h, height, 1]),
|
||||||
anchor = get_anchor(anchor, center, BOT, BOT),
|
anchor = center==true? "origin" :
|
||||||
|
center == false? "original_base" :
|
||||||
|
default(anchor, "original_base"),
|
||||||
regions = region_parts(region),
|
regions = region_parts(region),
|
||||||
slices = default(slices, max(1,ceil(abs(twist)/5))),
|
slices = default(slices, max(1,ceil(abs(twist)/5))),
|
||||||
scale = is_num(scale)? [scale,scale] : point2d(scale),
|
scale = is_num(scale)? [scale,scale] : point2d(scale),
|
||||||
@@ -655,14 +656,12 @@ function linear_sweep(
|
|||||||
for (rgn = regions) vnf_from_region(rgn, down(h/2), reverse=true),
|
for (rgn = regions) vnf_from_region(rgn, down(h/2), reverse=true),
|
||||||
for (rgn = trgns) vnf_from_region(rgn, up(h/2), reverse=false)
|
for (rgn = trgns) vnf_from_region(rgn, up(h/2), reverse=false)
|
||||||
]),
|
]),
|
||||||
cent = centroid(region),
|
|
||||||
anchors = [
|
anchors = [
|
||||||
named_anchor("centroid_top", point3d(cent, h/2), UP),
|
named_anchor("original_base", [0,0,-h/2], UP)
|
||||||
named_anchor("centroid", point3d(cent), UP),
|
|
||||||
named_anchor("centroid_bot", point3d(cent,-h/2), DOWN)
|
|
||||||
],
|
],
|
||||||
geom = atype=="hull"? attach_geom(cp=cp, region=region, h=h, extent=true, anchors=anchors) :
|
cp = default(cp, "centroid"),
|
||||||
atype=="intersect"? attach_geom(cp=cp, region=region, h=h, extent=false, anchors=anchors) :
|
geom = atype=="hull"? attach_geom(cp=cp, region=region, h=h, extent=true, shift=shift, scale=scale, twist=twist, anchors=anchors) :
|
||||||
|
atype=="intersect"? attach_geom(cp=cp, region=region, h=h, extent=false, shift=shift, scale=scale, twist=twist, anchors=anchors) :
|
||||||
assert(in_list(atype, ["hull", "intersect"]))
|
assert(in_list(atype, ["hull", "intersect"]))
|
||||||
) reorient(anchor,spin,orient, geom=geom, p=vnf);
|
) reorient(anchor,spin,orient, geom=geom, p=vnf);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user