mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-30 00:09:37 +00:00
merge transform_anchor into named anchor; make path_sweep anchors work
with scaling.
This commit is contained in:
parent
097cace9cd
commit
392b67c9c8
2 changed files with 50 additions and 47 deletions
|
@ -2763,16 +2763,40 @@ function reorient(
|
|||
// See Also: reorient(), attachable()
|
||||
// Usage:
|
||||
// a = named_anchor(name, pos, [orient], [spin]);
|
||||
// a = named_anchor(name, [pos], rot=, [flip=]);
|
||||
// Description:
|
||||
// Creates an anchor data structure. For a step-by-step explanation of attachments,
|
||||
// Creates an anchor data structure. You can specify the position, orient direction and spin directly.
|
||||
// Alternatively for the 3D case you can give a 4x4 rotation matrix which can specify the orient and spin, and optionally
|
||||
// the position, using a translation component of the matrix. If you specify `pos` along with `rot` then the position you
|
||||
// give overrides any translation included in `rot`. For a step-by-step explanation of attachments,
|
||||
// see the [Attachments Tutorial](Tutorial-Attachments).
|
||||
// Arguments:
|
||||
// name = The string name of the anchor. Lowercase. Words separated by single dashes. No spaces.
|
||||
// pos = The [X,Y,Z] position of the anchor.
|
||||
// orient = A vector pointing in the direction parts should project from the anchor position. Default: UP
|
||||
// spin = If needed, the angle to rotate the part around the direction vector. Default: 0
|
||||
function named_anchor(name, pos, orient=UP, spin=0) = [name, pos, orient, spin];
|
||||
|
||||
// ---
|
||||
// rot = A 4x4 rotations matrix, which may include a translation
|
||||
// flip = If true, flip the anchor the opposite direction. Default: false
|
||||
function named_anchor(name, pos, orient, spin, rot, flip) =
|
||||
assert(num_defined([orient,spin])==0 || num_defined([rot,flip])==0, "Cannot mix orient or spin with rot or flip")
|
||||
assert(num_defined([pos,rot])>0, "Must give pos or rot")
|
||||
is_undef(rot) ? [name, pos, default(orient,UP), default(spin,0)]
|
||||
:
|
||||
let(
|
||||
flip = default(flip,false),
|
||||
pos = default(pos,apply(rot,CTR)),
|
||||
rotpart = _force_rot(rot),
|
||||
dummy = assert(approx(det4(rotpart),1), "Input rotation is not a rotation matrix"),
|
||||
dir = flip ? apply(rotpart,DOWN)
|
||||
: apply(rotpart,UP),
|
||||
rot = flip? affine3d_rot_by_axis(apply(rotpart,BACK),180)*rot
|
||||
: rot,
|
||||
decode=rot_decode(rot(to=UP,from=dir)*_force_rot(rot)),
|
||||
spin = decode[0]*sign(decode[1].z)
|
||||
)
|
||||
[name, pos, dir, spin];
|
||||
|
||||
|
||||
function _force_rot(T) =
|
||||
[for(i=[0:3])
|
||||
|
@ -2780,35 +2804,6 @@ function _force_rot(T) =
|
|||
i==3 ? 1
|
||||
: 0]];
|
||||
|
||||
// Function: transform_anchor()
|
||||
// Synopsis: Creates an anchor data structure from a transformation matrix
|
||||
// Topics: Attachments
|
||||
// See Also: reorient(), attachable()
|
||||
// Usage:
|
||||
// a = transform_anchor(name, transform, [flip]);
|
||||
// Description:
|
||||
// Creates an anchor data structure from a transformation matrix. For a step-by-step explanation of attachments,
|
||||
// see the [Attachments Tutorial](Tutorial-Attachments).
|
||||
// Arguments:
|
||||
// name = The string name of the anchor. Lowercase. Words separated by single dashes. No spaces.
|
||||
// transform = A rotation matrix (which may include translation)
|
||||
// flip = If true, flip the anchor the opposite direction. Default: false
|
||||
|
||||
function transform_anchor(name, transform, flip=false) =
|
||||
let(
|
||||
pos = apply(transform,CTR),
|
||||
rotpart = _force_rot(transform),
|
||||
dir = flip ? apply(rotpart,DOWN)
|
||||
: apply(rotpart,UP),
|
||||
transform = flip? affine3d_rot_by_axis(apply(rotpart,BACK),180)*transform
|
||||
: transform,
|
||||
decode=rot_decode(rot(to=UP,from=dir)*_force_rot(transform)),
|
||||
spin = decode[0]*sign(decode[1].z)
|
||||
)
|
||||
[name, pos,dir,spin];
|
||||
|
||||
|
||||
|
||||
// Function: attach_geom()
|
||||
// Synopsis: Returns the internal geometry description of an attachable object.
|
||||
// Topics: Attachments
|
||||
|
|
38
skin.scad
38
skin.scad
|
@ -1479,7 +1479,8 @@ module spiral_sweep(poly, h, r, turns=1, taper, r1, r2, d, d1, d2, internal=fals
|
|||
// atype = Select "hull" or "intersect" anchor types. Default: "hull"
|
||||
// cp = Centerpoint for determining "intersect" anchors or centering the shape. Determintes the base of the anchor vector. Can be "centroid", "mean", "box" or a 3D point. Default: "centroid"
|
||||
// Side Effects:
|
||||
// `$transforms` is set to the array of transformation matrices that define the swept object.
|
||||
// `$transforms` is set to the array of transformation matrices that define the swept object.
|
||||
// `$scales` is set to the array of scales that were applied at each point to create the swept object.
|
||||
// Anchor Types:
|
||||
// "hull" = Anchors to the virtual convex hull of the shape.
|
||||
// "intersect" = Anchors to the surface of the shape.
|
||||
|
@ -1775,33 +1776,38 @@ module spiral_sweep(poly, h, r, turns=1, taper, r1, r2, d, d1, d2, internal=fals
|
|||
// attach(["start-centroid","end-centroid"]) anchor_arrow(s=5);
|
||||
// }
|
||||
// Example(Med,NoScales,VPR=[78.1,0,43.2],VPT=[2.18042,-0.485127,1.90371],VPD=74.4017): Note that the "start" anchors are backwards compared to the direction of the sweep, so you have to attach the TOP to align the shape with its ends.
|
||||
// shape = back_half(right_half(star(n=5,id=5,od=10)),y=-1);
|
||||
// shape = back_half(right_half(star(n=5,id=5,od=10)),y=-1)[0];
|
||||
// path = arc(angle=[0,180],d=30);
|
||||
// path_sweep(shape,path,method="natural")
|
||||
// path_sweep(shape,path,method="natural",scale=[1,1.5])
|
||||
// recolor("red"){
|
||||
// attach("start",TOP) stroke([path3d(shape[0])],width=.5);
|
||||
// attach("end") stroke([path3d(last(shape))],width=.5);
|
||||
// attach("start",TOP) stroke([path3d(shape)],width=.5);
|
||||
// attach("end") stroke([path3d(yscale(1.5,shape))],width=.5);
|
||||
// }
|
||||
|
||||
|
||||
module path_sweep(shape, path, method="incremental", normal, closed, twist=0, twist_by_length=true, scale=1, scale_by_length=true,
|
||||
symmetry=1, last_normal, tangent, uniform=true, relaxed=false, caps, style="min_edge", convexity=10,
|
||||
anchor="origin",cp="centroid",spin=0, orient=UP, atype="hull",profiles=false,width=1)
|
||||
{
|
||||
dummy = assert(is_region(shape) || is_path(shape,2), "shape must be a 2D path or region")
|
||||
assert(in_list(atype, _ANCHOR_TYPES), "Anchor type must be \"hull\" or \"intersect\"");
|
||||
transforms = path_sweep(shape, path, method, normal, closed, twist, twist_by_length, scale, scale_by_length,
|
||||
symmetry, last_normal, tangent, uniform, relaxed, caps, style, transforms=true);
|
||||
trans_scale = path_sweep(shape, path, method, normal, closed, twist, twist_by_length, scale, scale_by_length,
|
||||
symmetry, last_normal, tangent, uniform, relaxed, caps, style, transforms=true,_return_scales=true);
|
||||
transforms = trans_scale[0];
|
||||
scales = trans_scale[1];
|
||||
firstscale = [1/scales[0].x, 1/scales[0].y];
|
||||
lastscale = [1/last(scales).x, 1/last(scales).y];
|
||||
echo(scales=firstscale,lastscale);
|
||||
vnf = sweep(is_path(shape)?clockwise_polygon(shape):shape, transforms, closed=false, caps=caps,style=style);
|
||||
shapecent = point3d(centroid(shape));
|
||||
$transforms = transforms;
|
||||
$scales = scales;
|
||||
anchors = closed ? []
|
||||
:
|
||||
[
|
||||
transform_anchor("start", transforms[0], flip=true),
|
||||
transform_anchor("end", last(transforms)),
|
||||
transform_anchor("start-centroid", transforms[0]*move(shapecent), flip=true),
|
||||
transform_anchor("end-centroid", last(transforms)*move(shapecent))
|
||||
named_anchor("start", rot=transforms[0]*scale(firstscale), flip=true),
|
||||
named_anchor("end", rot=last(transforms)*scale(lastscale)),
|
||||
named_anchor("start-centroid", rot=transforms[0]*move(shapecent)*scale(firstscale), flip=true),
|
||||
named_anchor("end-centroid", rot=last(transforms)*move(shapecent)*scale(lastscale))
|
||||
];
|
||||
if (profiles){
|
||||
rshape = is_path(shape) ? [path3d(shape)]
|
||||
|
@ -1821,11 +1827,11 @@ module path_sweep(shape, path, method="incremental", normal, closed, twist=0, tw
|
|||
|
||||
function path_sweep(shape, path, method="incremental", normal, closed, twist=0, twist_by_length=true, scale=1, scale_by_length=true,
|
||||
symmetry=1, last_normal, tangent, uniform=true, relaxed=false, caps, style="min_edge", transforms=false,
|
||||
anchor="origin",cp="centroid",spin=0, orient=UP, atype="hull") =
|
||||
anchor="origin",cp="centroid",spin=0, orient=UP, atype="hull",_return_scales=false) =
|
||||
is_1region(path) ? path_sweep(shape=shape,path=path[0], method=method, normal=normal, closed=default(closed,true),
|
||||
twist=twist, scale=scale, scale_by_length=scale_by_length, twist_by_length=twist_by_length, symmetry=symmetry, last_normal=last_normal,
|
||||
tangent=tangent, uniform=uniform, relaxed=relaxed, caps=caps, style=style, transforms=transforms,
|
||||
anchor=anchor, cp=cp, spin=spin, orient=orient, atype=atype) :
|
||||
anchor=anchor, cp=cp, spin=spin, orient=orient, atype=atype, _return_scales=_return_scales) :
|
||||
let(closed=default(closed,false))
|
||||
assert(in_list(atype, _ANCHOR_TYPES), "Anchor type must be \"hull\" or \"intersect\"")
|
||||
assert(!closed || twist % (360/symmetry)==0, str("For a closed sweep, twist must be a multiple of 360/symmetry = ",360/symmetry))
|
||||
|
@ -1977,7 +1983,9 @@ function path_sweep(shape, path, method="incremental", normal, closed, twist=0,
|
|||
apply(transform_list[L], rshape)),
|
||||
dummy = ends_match ? 0 : echo("WARNING: ***** The points do not match when closing the model in path_sweep() *****")
|
||||
)
|
||||
transforms ? transform_list
|
||||
transforms && _return_scales
|
||||
? [transform_list,scale]
|
||||
: transforms ? transform_lislt
|
||||
: sweep(is_path(shape)?clockwise_polygon(shape):shape, transform_list, closed=false, caps=fullcaps,style=style,
|
||||
anchor=anchor,cp=cp,spin=spin,orient=orient,atype=atype);
|
||||
|
||||
|
|
Loading…
Reference in a new issue