mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-09-01 09:43:03 +02:00
revamp extruded region attachables and apply to linear_sweep.
This commit is contained in:
102
attachments.scad
102
attachments.scad
@@ -1515,10 +1515,10 @@ function _attach_transform(anchor, spin, orient, geom, p) =
|
||||
|
||||
|
||||
function _get_cp(geom) =
|
||||
|
||||
let(cp=select(geom,-3))
|
||||
is_vector(cp) ? cp
|
||||
: let(
|
||||
f=echo(type=geom[0]),
|
||||
type = in_list(geom[0],["vnf_extent","vnf_isect"]) ? "vnf"
|
||||
: in_list(geom[0],["rgn_extent","rgn_isect"]) ? "path"
|
||||
: in_list(geom[0],["xrgn_extent","xrgn_isect"]) ? "xpath"
|
||||
@@ -1549,20 +1549,22 @@ function _get_cp(geom) =
|
||||
// anchor = Vector or named anchor string.
|
||||
// geom = The geometry description of the shape.
|
||||
function _find_anchor(anchor, geom) =
|
||||
is_string(anchor)? (
|
||||
anchor=="origin"? [anchor, CENTER, UP, 0]
|
||||
: let(
|
||||
anchors = last(geom),
|
||||
found = search([anchor], anchors, num_returns_per_match=1)[0]
|
||||
)
|
||||
assert(found!=[], str("Unknown anchor: ",anchor))
|
||||
anchors[found]
|
||||
) :
|
||||
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)? (
|
||||
anchor=="origin"? [anchor, CENTER, UP, 0]
|
||||
: let(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))
|
||||
assert(is_vector(anchor),str("Invalid anchor: anchor=",anchor))
|
||||
let(anchor = point3d(anchor))
|
||||
anchor==CENTER? [anchor, cp, UP, 0] :
|
||||
let(
|
||||
@@ -1725,8 +1727,7 @@ function _find_anchor(anchor, geom) =
|
||||
) : type == "rgn_isect"? ( //region
|
||||
assert(anchor.z==0, "The Z component of an anchor for a 2D shape must be 0.")
|
||||
let(
|
||||
rgn_raw = move(-point2d(cp), p=geom[1]),
|
||||
rgn = is_region(rgn_raw)? rgn_raw : [rgn_raw],
|
||||
rgn = force_region(move(-point2d(cp), p=geom[1])),
|
||||
anchor = point2d(anchor),
|
||||
isects = [
|
||||
for (path=rgn, t=triplet(path,true)) let(
|
||||
@@ -1753,68 +1754,27 @@ function _find_anchor(anchor, geom) =
|
||||
let(
|
||||
rgn = force_region(geom[1]),
|
||||
anchor = point2d(anchor),
|
||||
m = rot(from=anchor, to=RIGHT) * move(-[cp.x, cp.y, 0]),
|
||||
rpts = apply(m, flatten(rgn)),
|
||||
rpts = rot(from=anchor, to=RIGHT, p=flatten(rgn)),
|
||||
maxx = max(column(rpts,0)),
|
||||
idxs = [for (i = idx(rpts)) if (approx(rpts[i].x, maxx)) i],
|
||||
miny = min([for (i=idxs) rpts[i].y]),
|
||||
maxy = max([for (i=idxs) rpts[i].y]),
|
||||
midy = (miny+maxy)/2,
|
||||
pos = point2d(cp) + rot(from=RIGHT, to=anchor, p=[maxx,midy])
|
||||
) [anchor, pos, anchor, 0]
|
||||
) : type == "xrgn_isect"? ( //region
|
||||
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(
|
||||
rgn_raw = move(-point2d(cp), p=geom[1]),
|
||||
l = geom[2],
|
||||
rgn = is_region(rgn_raw)? rgn_raw : [rgn_raw],
|
||||
anchor = point3d(anchor),
|
||||
xyanch = point2d(anchor)
|
||||
) approx(xyanch,[0,0])? [anchor, [0,0,anchor.z*l/2], unit(anchor,UP), 0] :
|
||||
let(
|
||||
isects = [
|
||||
for (path=rgn, t=triplet(path,true)) let(
|
||||
seg1 = [t[0],t[1]],
|
||||
seg2 = [t[1],t[2]],
|
||||
isect = line_intersection([[0,0],xyanch], seg1, RAY, SEGMENT),
|
||||
n = is_undef(isect)? [0,1] :
|
||||
!approx(isect, t[1])? line_normal(seg1) :
|
||||
unit((line_normal(seg1)+line_normal(seg2))/2,[0,1]),
|
||||
n2 = vector_angle(xyanch,n)>90? -n : n
|
||||
)
|
||||
if(!is_undef(isect) && !approx(isect,t[0]))
|
||||
[norm(isect), isect, n2]
|
||||
],
|
||||
maxidx = max_index(column(isects,0)),
|
||||
isect = isects[maxidx],
|
||||
pos = point3d(cp) + point3d(isect[1]) + unit([0,0,anchor.z],CENTER)*l/2,
|
||||
xyvec = unit(isect[2],[0,1]),
|
||||
vec = unit((point3d(xyvec)+UP*anchor.z)/2,UP),
|
||||
oang = approx(xyvec, [0,0])? 0 : atan2(xyvec.y, xyvec.x) + 90
|
||||
) [anchor, pos, vec, oang]
|
||||
) : type == "xrgn_extent"? ( //region
|
||||
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(
|
||||
rgn = force_region(geom[1]),
|
||||
l = geom[2],
|
||||
anchor = point3d(anchor),
|
||||
xyanch = point2d(anchor),
|
||||
m = (
|
||||
approx(xyanch,[0,0])? [[1,0,0],[0,1,0],[0,0,1]] :
|
||||
rot(from=xyanch, to=RIGHT, planar=true)
|
||||
) * move(-[cp.x, cp.y]),
|
||||
rpts = apply(m, flatten(rgn)),
|
||||
maxx = max(column(rpts,0)),
|
||||
idxs = [for (i = idx(rpts)) if (approx(rpts[i].x, maxx)) i],
|
||||
ys = [for (i=idxs) rpts[i].y],
|
||||
ys = [for (pt=rpts) if (approx(pt.x, maxx)) pt.y],
|
||||
midy = (min(ys)+max(ys))/2,
|
||||
xypos = point2d(cp) + (
|
||||
approx(xyanch,[0,0])? [0,0] :
|
||||
rot(from=RIGHT, to=xyanch, p=[maxx,midy])
|
||||
),
|
||||
pos = point3d(xypos) + unit([0,0,anchor.z],CENTER)*l/2,
|
||||
vec = unit((point3d(xyanch)+UP*anchor.z)/2,UP)
|
||||
) [anchor, pos, vec, oang]
|
||||
pos = rot(from=RIGHT, to=anchor, p=[maxx,midy])
|
||||
) [anchor, pos, unit(anchor), 0]
|
||||
) : type=="xrgn_extent" || type=="xrgn_isect" ? ( // extruded region
|
||||
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(
|
||||
anchor_xy = point2d(anchor),
|
||||
L = geom[2]
|
||||
)
|
||||
approx(anchor_xy,[0,0]) ? [anchor, up(anchor.z*L/2,cp), anchor, oang] :
|
||||
let(
|
||||
newgeom = list_set(geom, [0,len(geom)-3], [substr(geom[0],1), point2d(cp)]),
|
||||
result2d = _find_anchor(anchor_xy, newgeom),
|
||||
pos = point3d(result2d[1], cp.z+anchor.z*L/2),
|
||||
vec = unit(point3d(result2d[2], anchor.z),UP),
|
||||
oang = atan2(vec.y,vec.x) + 90
|
||||
)
|
||||
[anchor, pos, vec, oang]
|
||||
) :
|
||||
assert(false, "Unknown attachment geometry type.");
|
||||
|
||||
|
Reference in New Issue
Block a user