Added $idx to various attachent modules.

This commit is contained in:
Revar Desmera 2023-01-14 23:00:55 -08:00
parent 4ddf71e3f3
commit ef5d197014

View file

@ -392,7 +392,7 @@ _ANCHOR_TYPES = ["intersect","hull"];
// Module: position()
// Usage:
// position(from) CHILDREN;
// PARENT() position(from) CHILDREN;
//
// Topics: Attachments
// See Also: attachable(), attach(), orient()
@ -402,6 +402,10 @@ _ANCHOR_TYPES = ["intersect","hull"];
// of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
// Arguments:
// from = The vector, or name of the parent anchor point to attach to.
// Side Effects:
// `$attach_anchor` for each `from=` anchor given, this is set to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for that anchor.
// `$attach_to` is set to `undef`.
// `$attach_norot` is set to `true`.
// Example:
// spheroid(d=20) {
// position(TOP) cyl(l=10, d1=10, d2=5, anchor=BOTTOM);
@ -426,7 +430,7 @@ module position(from)
// Module: orient()
// Usage:
// orient(dir, [spin=]) CHILDREN;
// orient(anchor=, [spin=]) CHILDREN;
// PARENT() orient(anchor=, [spin=]) CHILDREN;
// Topics: Attachments
// Description:
// Orients children such that their top is tilted towards the given direction, or towards the
@ -437,6 +441,10 @@ module position(from)
// ---
// anchor = The anchor on the parent which you want to match the orientation of. Use instead of `dir`.
// spin = The spin to add to the children. (Overrides anchor spin.)
// Side Effects:
// `$attach_anchor` is set to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for the `anchor=`, if given.
// `$attach_to` is set to `undef`.
// `$attach_norot` is set to `true`.
// See Also: attachable(), attach(), orient()
// Example: Orienting by Vector
// prismoid([50,50],[30,30],h=40) {
@ -494,8 +502,8 @@ module orient(dir, anchor, spin) {
// Module: attach()
// Usage:
// attach(from, [overlap=], [norot=]) CHILDREN;
// attach(from, to, [overlap=], [norot=]) CHILDREN;
// PARENT() attach(from, [overlap=], [norot=]) CHILDREN;
// PARENT() attach(from, to, [overlap=], [norot=]) CHILDREN;
// Topics: Attachments
// See Also: attachable(), position(), face_profile(), edge_profile(), corner_profile()
// Description:
@ -511,6 +519,11 @@ module orient(dir, anchor, spin) {
// ---
// overlap = Amount to sink child into the parent. Equivalent to `down(X)` after the attach. This defaults to the value in `$overlap`, which is `0` by default.
// norot = If true, don't rotate children when attaching to the anchor point. Only translate to the anchor point.
// Side Effects:
// `$idx` is set to the index number of each anchor if a list of anchors is given. Otherwise is set to `0`.
// `$attach_anchor` for each `from=` anchor given, this is set to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for that anchor.
// `$attach_to` is set to the value of the `to=` argument, if given. Otherwise, `undef`
// `$attach_norot` is set to the value of the `norot=` argument.
// Example:
// spheroid(d=20) {
// attach(TOP) down(1.5) cyl(l=11.5, d1=10, d2=5, anchor=BOTTOM);
@ -523,7 +536,8 @@ module attach(from, to, overlap, norot=false)
assert($parent_geom != undef, "No object to attach to!");
overlap = (overlap!=undef)? overlap : $overlap;
anchors = (is_vector(from)||is_string(from))? [from] : from;
for (anchr = anchors) {
for ($idx = idx(anchors)) {
anchr = anchors[$idx];
anch = _find_anchor(anchr, $parent_geom);
two_d = _attach_geom_2d($parent_geom);
$attach_to = to;
@ -543,7 +557,7 @@ module attach(from, to, overlap, norot=false)
// Module: tag()
// Usage:
// tag(tag) CHILDREN;
// PARENT() tag(tag) CHILDREN;
// Topics: Attachments
// See Also: force_tag(), recolor(), hide(), show_only(), diff(), intersect()
// Description:
@ -580,7 +594,7 @@ module tag(tag)
// Module: force_tag()
// Usage:
// force_tag([tag]) CHILDREN;
// PARENT() force_tag([tag]) CHILDREN;
// Topics: Attachments
// See Also: tag(), recolor(), hide(), show_only(), diff(), intersect()
// Description:
@ -642,7 +656,7 @@ module force_tag(tag)
// Module: default_tag()
// Usage:
// default_tag(tag) CHILDREN;
// PARENT() default_tag(tag) CHILDREN;
// Topics: Attachments
// See Also: force_tag(), recolor(), hide(), show_only(), diff(), intersect()
// Description:
@ -686,6 +700,8 @@ module default_tag(tag)
// Creates a tag scope with locally altered tag names to avoid tag name conflict with other code.
// This is necessary when writing modules because the module's caller might happen to use the same tags.
// Note that if you directly set the `$tag` variable then tag scoping will not work correctly.
// Side Effects:
// `$tag_prefix` is set to the value of `scope=` if given, otherwise is set to a random string.
// Example: In this example the ring module uses "remove" tags which will conflict with use of the same tags by the parent.
// module ring(r,h,w=1,anchor,spin,orient)
// {
@ -723,7 +739,7 @@ module tag_scope(scope){
// Module: diff()
// Usage:
// diff([remove], [keep]) CHILDREN;
// diff([remove], [keep]) PARENT() CHILDREN;
// Topics: Attachments
// See Also: tag(), force_tag(), recolor(), show_only(), hide(), tag_diff(), intersect(), tag_intersect()
// Description:
@ -904,7 +920,7 @@ module diff(remove="remove", keep="keep")
// Module: tag_diff()
// Usage:
// tag_diff(tag, [remove], [keep]) CHILDREN;
// tag_diff(tag, [remove], [keep]) PARENT() CHILDREN;
// Topics: Attachments
// See Also: tag(), force_tag(), recolor(), show_only(), hide(), diff(), intersect(), tag_intersect()
// Description:
@ -953,7 +969,6 @@ module diff(remove="remove", keep="keep")
// cyl(r=7,h=7)
// tag("remove")cyl(r=6,h=8)
// tag("keep")cyl(r=5,h=9);
//
module tag_diff(tag,remove="remove", keep="keep")
{
req_children($children);
@ -975,7 +990,7 @@ module tag_diff(tag,remove="remove", keep="keep")
// Module: intersect()
// Usage:
// intersect([intersect], [keep]) CHILDREN;
// intersect([intersect], [keep]) PARENT() CHILDREN;
// Topics: Attachments
// See Also: tag(), force_tag(), recolor(), show_only(), hide(), diff(), tag_diff(), tag_intersect()
// Description:
@ -1044,7 +1059,7 @@ module intersect(intersect="intersect",keep="keep")
// Module: tag_intersect()
// Usage:
// tag_intersect(tag, [intersect], [keep]) CHILDREN;
// tag_intersect(tag, [intersect], [keep]) PARENT() CHILDREN;
// Topics: Attachments
// See Also: tag(), force_tag(), recolor(), show_only(), hide(), diff(), tag_diff(), intersect()
// Description:
@ -1284,11 +1299,53 @@ module show_int(tags)
// Section: Attachable Masks
// Module: face_mask()
// Usage:
// PARENT() face_mask(faces) CHILDREN;
// Topics: Attachments, Masking
// Description:
// Takes a 3D mask shape, and attaches it to the given faces, with the appropriate orientation to be
// differenced away. The mask shape should be vertically oriented (Z-aligned) with the bottom half
// (Z-) shaped to be diffed away from the face of parent attachable shape. If no tag is set then
// `face_mask()` sets the tag for children to "remove" so that it will work with the default {{diff()}} tag.
// For details on specifying the faces to mask see [Specifying Faces](attachments.scad#subsection-specifying-faces).
// For a step-by-step explanation of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
// Arguments:
// edges = Faces to mask. See [Specifying Faces](attachments.scad#subsection-specifying-faces) for information on specifying faces. Default: All faces
// Side Effects:
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
// `$idx` is set to the index number of each face in the list of faces given.
// `$attach_anchor` is set for each face given, to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for that anchor.
// See Also: attachable(), position(), attach(), face_profile(), edge_profile(), corner_mask(), edge_mask()
// Example:
// diff()
// cylinder(r=30, h=60)
// face_mask(TOP) {
// rounding_cylinder_mask(r=30,rounding=5);
// cuboid([5,61,10]);
// }
// Example: Using `$idx`
// diff()
// cylinder(r=30, h=60)
// face_mask([TOP, BOT])
// zrot(45*$idx) zrot_copies([0,90]) cuboid([5,61,10]);
module face_mask(faces=[LEFT,RIGHT,FRONT,BACK,BOT,TOP]) {
req_children($children);
faces = is_vector(faces)? [faces] : faces;
assert(all([for (face=faces) is_vector(face) && sum([for (x=face) x!=0? 1 : 0])==1]), "Vector in faces doesn't point at a face.");
assert($parent_geom != undef, "No object to attach to!");
attach(faces) {
if ($tag=="") tag("remove") children();
else children();
}
}
// Module: edge_mask()
// Usage:
// edge_mask([edges], [except]) CHILDREN;
// Topics: Attachments
// See Also: attachable(), position(), attach(), face_profile(), edge_profile(), corner_mask()
// PARENT() edge_mask([edges], [except]) CHILDREN;
// Topics: Attachments, Masking
// See Also: attachable(), position(), attach(), face_profile(), edge_profile(), corner_mask(), face_mask()
// Description:
// Takes a 3D mask shape, and attaches it to the given edges, with the appropriate orientation to be
// differenced away. The mask shape should be vertically oriented (Z-aligned) with the back-right
@ -1309,6 +1366,10 @@ module show_int(tags)
// except = Edges to explicitly NOT mask. See [Specifying Edges](attachments.scad#subsection-specifying-edges). Default: No edges.
// Side Effects:
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
// Side Effects:
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
// `$idx` is set to the index number of each edge.
// `$attach_anchor` is set for each edge given, to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for that anchor.
// Example:
// diff()
// cube([50,60,70],center=true)
@ -1323,7 +1384,8 @@ module edge_mask(edges=EDGES_ALL, except=[]) {
if (edges[axis][i]>0)
EDGE_OFFSETS[axis][i]
];
for (vec = vecs) {
for ($idx = idx(vecs)) {
vec = vecs[$idx];
vcount = (vec.x?1:0) + (vec.y?1:0) + (vec.z?1:0);
dummy=assert(vcount == 2, "Not an edge vector!");
anch = _find_anchor(vec, $parent_geom);
@ -1344,8 +1406,8 @@ module edge_mask(edges=EDGES_ALL, except=[]) {
// Module: corner_mask()
// Usage:
// corner_mask([corners], [except]) CHILDREN;
// Topics: Attachments
// PARENT() corner_mask([corners], [except]) CHILDREN;
// Topics: Attachments, Masking
// See Also: attachable(), position(), attach(), face_profile(), edge_profile(), edge_mask()
// Description:
// Takes a 3D mask shape, and attaches it to the specified corners, with the appropriate orientation to
@ -1358,6 +1420,8 @@ module edge_mask(edges=EDGES_ALL, except=[]) {
// except = Corners to explicitly NOT mask. See [Specifying Corners](attachments.scad#subsection-specifying-corners). Default: No corners.
// Side Effects:
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
// `$idx` is set to the index number of each corner.
// `$attach_anchor` is set for each corner given, to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for that anchor.
// Example:
// diff()
// cube(100, center=true)
@ -1371,7 +1435,8 @@ module corner_mask(corners=CORNERS_ALL, except=[]) {
assert($parent_geom != undef, "No object to attach to!");
corners = _corners(corners, except=except);
vecs = [for (i = [0:7]) if (corners[i]>0) CORNER_OFFSETS[i]];
for (vec = vecs) {
for ($idx = idx(vecs)) {
vec = vecs[$idx];
vcount = (vec.x?1:0) + (vec.y?1:0) + (vec.z?1:0);
dummy=assert(vcount == 3, "Not an edge vector!");
anch = _find_anchor(vec, $parent_geom);
@ -1390,8 +1455,8 @@ module corner_mask(corners=CORNERS_ALL, except=[]) {
// Module: face_profile()
// Usage:
// face_profile(faces, r|d=, [convexity=]) CHILDREN;
// Topics: Attachments
// PARENT() face_profile(faces, r|d=, [convexity=]) CHILDREN;
// Topics: Attachments, Masking
// See Also: attachable(), position(), attach(), edge_profile(), corner_profile()
// Description:
// Given a 2D edge profile, extrudes it into a mask for all edges and corners bounding each given face. If no tag is set
@ -1406,6 +1471,9 @@ module corner_mask(corners=CORNERS_ALL, except=[]) {
// convexity = Max number of times a line could intersect the perimeter of the mask shape. Default: 10
// Side Effects:
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
// `$idx` is set to the index number of each face.
// `$attach_anchor` is set for each edge or corner given, to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for that anchor.
// `$profile_type` is set to `"edge"` or `"corner"`, depending on what is being masked.
// Example:
// diff()
// cube([50,60,70],center=true)
@ -1424,8 +1492,8 @@ module face_profile(faces=[], r, d, convexity=10) {
// Module: edge_profile()
// Usage:
// edge_profile([edges], [except], [convexity]) CHILDREN;
// Topics: Attachments
// PARENT() edge_profile([edges], [except], [convexity]) CHILDREN;
// Topics: Attachments, Masking
// See Also: attachable(), position(), attach(), face_profile(), corner_profile()
// Description:
// Takes a 2D mask shape and attaches it to the selected edges, with the appropriate orientation and
@ -1440,6 +1508,9 @@ module face_profile(faces=[], r, d, convexity=10) {
// convexity = Max number of times a line could intersect the perimeter of the mask shape. Default: 10
// Side Effects:
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
// `$idx` is set to the index number of each edge.
// `$attach_anchor` is set for each edge given, to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for that anchor.
// `$profile_type` is set to `"edge"`.
// Example:
// diff()
// cube([50,60,70],center=true)
@ -1454,13 +1525,15 @@ module edge_profile(edges=EDGES_ALL, except=[], convexity=10) {
if (edges[axis][i]>0)
EDGE_OFFSETS[axis][i]
];
for (vec = vecs) {
for ($idx = idx(vecs)) {
vec = vecs[$idx];
vcount = (vec.x?1:0) + (vec.y?1:0) + (vec.z?1:0);
dummy=assert(vcount == 2, "Not an edge vector!");
anch = _find_anchor(vec, $parent_geom);
$attach_to = undef;
$attach_anchor = anch;
$attach_norot = true;
$profile_type = "edge";
psize = point3d($parent_size);
length = [for (i=[0:2]) if(!vec[i]) psize[i]][0]+0.1;
rotang =
@ -1481,8 +1554,8 @@ module edge_profile(edges=EDGES_ALL, except=[], convexity=10) {
// Module: corner_profile()
// Usage:
// corner_profile([corners], [except], [r=|d=], [convexity=]) CHILDREN;
// Topics: Attachments
// PARENT() corner_profile([corners], [except], [r=|d=], [convexity=]) CHILDREN;
// Topics: Attachments, Masking
// See Also: attachable(), position(), attach(), face_profile(), edge_profile()
// Description:
// Takes a 2D mask shape, rotationally extrudes and converts it into a corner mask, and attaches it
@ -1499,6 +1572,9 @@ module edge_profile(edges=EDGES_ALL, except=[], convexity=10) {
// convexity = Max number of times a line could intersect the perimeter of the mask shape. Default: 10
// Side Effects:
// Tags the children with "remove" (and hence sets $tag) if no tag is already set.
// `$idx` is set to the index number of each corner.
// `$attach_anchor` is set for each corner given, to the `[ANCHOR, POSITION, ORIENT, SPIN]` information for that anchor.
// `$profile_type` is set to `"corner"`.
// Example:
// diff()
// cuboid([50,60,70],rounding=10,edges="Z",anchor=CENTER) {
@ -1511,13 +1587,15 @@ module corner_profile(corners=CORNERS_ALL, except=[], r, d, convexity=10) {
assert(is_num(r));
corners = _corners(corners, except=except);
vecs = [for (i = [0:7]) if (corners[i]>0) CORNER_OFFSETS[i]];
for (vec = vecs) {
for ($idx = idx(vecs)) {
vec = vecs[$idx];
vcount = (vec.x?1:0) + (vec.y?1:0) + (vec.z?1:0);
dummy=assert(vcount == 3, "Not an edge vector!");
anch = _find_anchor(vec, $parent_geom);
$attach_to = undef;
$attach_anchor = anch;
$attach_norot = true;
$profile_type = "corner";
rotang = vec.z<0?
[ 0,0,180+v_theta(vec)-45] :
[180,0,-90+v_theta(vec)-45];
@ -2371,7 +2449,6 @@ function _attach_transform(anchor, spin, orient, geom, p) =
function _get_cp(geom) =
let(cp=select(geom,-3))
is_vector(cp) ? cp
: let(
@ -3258,7 +3335,6 @@ module _show_cube_faces(faces, size=20, toplabel,botlabel) {
move(f*size/2) rot(from=UP,to=f)
cuboid([size,size,.1]);
}
vpr = [55,0,25];
color("black"){
if (is_def(toplabel))