mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Make linear_sweep center in z direction with center option by adding
"zcenter" named anchor.
This commit is contained in:
parent
6de156528b
commit
d5ce3615cf
2 changed files with 22 additions and 19 deletions
|
@ -1117,7 +1117,7 @@ function reorient(
|
|||
two_d=false,
|
||||
axis=UP,
|
||||
p=undef
|
||||
) =
|
||||
) =
|
||||
assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("Got: ",anchor))
|
||||
assert(is_undef(spin) || is_vector(spin,3) || is_num(spin), str("Got: ",spin))
|
||||
assert(is_undef(orient) || is_vector(orient,3), str("Got: ",orient))
|
||||
|
@ -1526,19 +1526,19 @@ function _get_cp(geom) =
|
|||
// anchor = Vector or named anchor string.
|
||||
// geom = The geometry description of the shape.
|
||||
function _find_anchor(anchor, geom) =
|
||||
let(
|
||||
let(
|
||||
cp = _get_cp(geom),
|
||||
offset_raw = select(geom,-2),
|
||||
offset = [for (i=[0:2]) anchor[i]==0? 0 : offset_raw[i]], // prevents bad centering.
|
||||
anchors = last(geom),
|
||||
type = geom[0]
|
||||
)
|
||||
is_string(anchor)? (
|
||||
is_string(anchor)? (
|
||||
anchor=="origin"? [anchor, CENTER, UP, 0]
|
||||
: let(found = search([anchor], anchors, num_returns_per_match=1)[0])
|
||||
: let(ff=echo(ss=anchors),found = search([anchor], anchors, num_returns_per_match=1)[0])
|
||||
assert(found!=[], str("Unknown anchor: ",anchor))
|
||||
anchors[found]
|
||||
) :
|
||||
) :
|
||||
assert(is_vector(anchor),str("anchor=",anchor))
|
||||
let(anchor = point3d(anchor))
|
||||
anchor==CENTER? [anchor, cp, UP, 0] :
|
||||
|
|
31
regions.scad
31
regions.scad
|
@ -390,14 +390,16 @@ function region_parts(region) =
|
|||
// If called as a module, creates a polyhedron that is the linear extrusion of the given 2D region or path.
|
||||
// If called as a function, returns a VNF that can be used to generate a polyhedron of the linear extrusion
|
||||
// of the given 2D region or path. The benefit of using this, over using `linear_extrude region(rgn)` is
|
||||
// that you can use `anchor`, `spin`, `orient` and attachments with it. You can set `cp` to "mean", "centroid"
|
||||
// or "box" to get different centerpoint computations, or you can give a custom vector centerpoint.
|
||||
// Also, you can make more refined
|
||||
// that it supports `anchor`, `spin`, `orient` and attachments. You can also make more refined
|
||||
// twisted extrusions by using `maxseg` to subsample flat faces.
|
||||
// Note that the center option centers vertically using the named anchor "zcenter" whereas
|
||||
// `anchor=CENTER` centers the entire shape relative to
|
||||
// the shape's centroid, or other centerpoint you specify. The centerpoint can be "centroid", "mean", "box" or
|
||||
// a custom point location.
|
||||
// Arguments:
|
||||
// region = The 2D [Region](regions.scad) or path that is to be extruded.
|
||||
// height = The height to extrude the region. Default: 1
|
||||
// center = If true, the created polyhedron will be vertically centered. If false, it will be extruded upwards from the origin. Default: `false`
|
||||
// center = If true, the created polyhedron will be vertically centered. If false, it will be extruded upwards from the XY plane. Default: `false`
|
||||
// slices = The number of slices to divide the shape into along the Z axis, to allow refinement of detail, especially when working with a twist. Default: `twist/5`
|
||||
// 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)
|
||||
// twist = The number of degrees to rotate the shape clockwise around the Z axis, as it rises from bottom to top. Default: 0
|
||||
|
@ -406,7 +408,7 @@ function region_parts(region) =
|
|||
// convexity = Max number of surfaces any single ray could pass through. Module use only.
|
||||
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#anchor). Default: `"origin"`
|
||||
// anchor_isect = If true, anchoring it performed by finding where the anchor vector intersects the swept shape. Default: false
|
||||
// cp = Centerpoint for determining intersection anchors or centering the shape. Determintes the base of the anchor vector. Default: "centroid"
|
||||
// cp = Centerpoint for determining intersection anchors or centering the shape. Determintes the base of the anchor vector. Can be "centroid", "mean", "box" or a 3D point. Default: "centroid"
|
||||
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#spin). Default: `0`
|
||||
// orient = Vector to rotate top towards, after spin. See [orient](attachments.scad#orient). Default: `UP`
|
||||
// Example: Extruding a Compound Region.
|
||||
|
@ -430,17 +432,18 @@ function region_parts(region) =
|
|||
// mrgn = union(rgn1,rgn2);
|
||||
// orgn = difference(mrgn,rgn3);
|
||||
// linear_sweep(orgn,height=20,convexity=16) show_anchors();
|
||||
module linear_sweep(region, height=1, center, twist=0, scale=1, slices, maxseg, style="default", convexity, anchor_isect=false, anchor, spin=0, orient=UP, cp="centroid") {
|
||||
module linear_sweep(region, height=1, center, twist=0, scale=1, slices, maxseg, style="default", convexity, anchor_isect=false, anchor, spin=0, orient=UP, cp="centroid", anchor="origin") {
|
||||
region = force_region(region);
|
||||
dummy=assert(is_region(region),"Input is not a region");
|
||||
anchor = get_anchor(anchor, center, "origin", "origin");
|
||||
anchor = center ? "zcenter" : anchor;
|
||||
anchors = [named_anchor("zcenter", [0,0,height/2], UP)];
|
||||
vnf = linear_sweep(
|
||||
region, height=height,
|
||||
twist=twist, scale=scale,
|
||||
slices=slices, maxseg=maxseg,
|
||||
style=style
|
||||
);
|
||||
attachable(anchor,spin,orient, cp=cp, vnf=vnf, extent=!anchor_isect) {
|
||||
attachable(anchor,spin,orient, cp=cp, vnf=vnf, extent=!anchor_isect, anchors=anchors) {
|
||||
vnf_polyhedron(vnf, convexity=convexity);
|
||||
children();
|
||||
}
|
||||
|
@ -454,9 +457,9 @@ function linear_sweep(region, height=1, center, twist=0, scale=1, slices,
|
|||
)
|
||||
assert(is_region(region), "Input is not a region")
|
||||
let(
|
||||
anchor = get_anchor(anchor,center,"origin","origin"),
|
||||
anchor = center ? "zcenter" : anchor,
|
||||
anchors = [named_anchor("zcenter", [0,0,height/2], UP)],
|
||||
regions = region_parts(region),
|
||||
// cp = mean(pointlist_bounds(flatten(region))),
|
||||
slices = default(slices, floor(twist/5+1)),
|
||||
step = twist/slices,
|
||||
hstep = height/slices,
|
||||
|
@ -486,14 +489,14 @@ function linear_sweep(region, height=1, center, twist=0, scale=1, slices,
|
|||
for (i=[0:1:slices]) let(
|
||||
sc = lerp(1, scale, i/slices),
|
||||
ang = i * step,
|
||||
h = i * hstep - height/2
|
||||
h = i * hstep //- height/2
|
||||
) scale([sc,sc,1], p=rot(ang, p=path3d(path,h)))
|
||||
]
|
||||
) vnf_vertex_array(verts, caps=false, col_wrap=true, style=style),
|
||||
for (rgn = regions) vnf_from_region(rgn, down(height/2), reverse=true),
|
||||
for (rgn = trgns) vnf_from_region(rgn, up(height/2), reverse=false)
|
||||
for (rgn = regions) vnf_from_region(rgn, ident(4), reverse=true),
|
||||
for (rgn = trgns) vnf_from_region(rgn, up(height), reverse=false)
|
||||
])
|
||||
) reorient(anchor,spin,orient, cp=cp, vnf=vnf, extent=!anchor_isect, p=vnf);
|
||||
) reorient(anchor,spin,orient, cp=cp, vnf=vnf, extent=!anchor_isect, p=vnf, anchors=anchors);
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue