fix attachment scope problem, change default mask tag to "remove",

applied only when user doesn't give a tag
This commit is contained in:
Adrian Mariano 2022-06-26 12:08:22 -04:00
parent 61253b1f37
commit ec1bab7274
3 changed files with 75 additions and 65 deletions

View file

@ -554,7 +554,7 @@ module attach(from, to, overlap, norot=false)
// Arguments:
// tag = tag string, which must not contain any spaces.
// Side Effects:
// Sets `$tag` to the tag you specify.
// Sets `$tag` to the tag you specify, possibly with a scope prefix.
// Example(3D): Applies the tag to both cuboids instead of having to repeat `$tag="remove"` for each one.
// diff("remove")
// cuboid(10){
@ -609,7 +609,7 @@ module tag(tag)
// Arguments:
// tag = tag string, which must not contain any spaces
// Side Effects:
// Sets `$tag` to the tag you specify.
// Sets `$tag` to the tag you specify, possibly with a scope prefix.
// Example(2D): This example produces the full square without subtracting the "remove" item. When you use non-attachable modules with tags, results are unpredictable.
// diff()
// {
@ -628,8 +628,8 @@ module force_tag(tag)
{
req_children($children);
assert(is_undef(tag) || is_string(tag),"tag must be a string");
$tag = str($tag_prefix,default(tag,$tag));
assert(undef==str_find($tag," "),str("Tag string \"",$tag,"\" contains a space, which is not allowed"));
$tag = str($tag_prefix,is_def(tag) ? tag : $tag);
if(_is_shown())
show_all()
children();
@ -873,7 +873,7 @@ module diff(remove="remove", keep="keep")
// remove = String containing space delimited set of tag names of children to difference away. Default: `"remove"`
// keep = String containing space delimited set of tag names of children to keep; that is, to union into the model after differencing is completed. Default: `"keep"`
// Side Effects:
// Sets `$tag` to the tag you specify.
// Sets `$tag` to the tag you specify, possibly with a scope prefix.
// Example: In this example we have a difference with a kept object that is then subtracted from a cube, but we don't want the kept object to appear in the final output, so this result is wrong:
// diff("rem"){
// cuboid([20,10,30],anchor=FRONT);
@ -914,7 +914,7 @@ module tag_diff(tag,remove="remove", keep="keep")
assert(is_string(keep),"keep must be a string of tags");
assert(is_string(tag),"tag must be a string");
assert(undef==str_find(tag," "),str("Tag string \"",tag,"\" contains a space, which is not allowed"));
$tag=tag;
$tag=str($tag_prefix,tag);
if (_is_shown())
show_all(){
difference() {
@ -1013,7 +1013,7 @@ module intersect(intersect="intersect",keep="keep")
// intersect = String containing space delimited set of tag names of children to intersect. Default: "intersect"
// keep = String containing space delimited set of tag names of children to keep whole. Default: "keep"
// Side Effects:
// Sets `$tag` to the tag you specify.
// Sets `$tag` to the tag you specify, possibly with a scope prefix.
// Example: Without `tag_intersect()` the kept object is not included in the difference.
// $fn=32;
// diff()
@ -1038,7 +1038,7 @@ module tag_intersect(tag,intersect="intersect",keep="keep")
assert(is_string(keep),"keep must be a string of tags");
assert(is_string(tag),"tag must be a string");
assert(undef==str_find(tag," "),str("Tag string \"",tag,"\" contains a space, which is not allowed"));
$tag=tag;
$tag=str($tag_prefix,tag);
if (_is_shown())
show_all(){
intersection(){
@ -1102,7 +1102,7 @@ module conv_hull(keep="keep")
// Arguments:
// keep = String containing space delimited set of tag names of children to keep out of the hull. Default: "keep"
// Side Effects:
// Sets `$tag` to the tag you specify.
// Sets `$tag` to the tag you specify, possibly with a scope prefix.
// Example: With a regular tag, the kept object is not handled as desired:
// diff(){
// cuboid([30,30,9])
@ -1127,7 +1127,7 @@ module tag_conv_hull(tag,keep="keep")
assert(is_string(keep),"keep must be a string of tags");
assert(is_string(tag),"tag must be a string");
assert(undef==str_find(tag," "),str("Tag string \"",tag,"\" contains a space, which is not allowed"));
$tag=tag;
$tag=str($tag_prefix,tag);
if (_is_shown())
show_all(){
hull() hide(keep) children();
@ -1244,8 +1244,9 @@ module show_int(tags)
// See Also: attachable(), position(), attach(), face_profile(), edge_profile(), corner_mask()
// Description:
// Takes a 3D mask shape, and attaches it to the given edges, with the appropriate orientation to be
// `diff()`ed away. The mask shape should be vertically oriented (Z-aligned) with the back-right
// quadrant (X+Y+) shaped to be diffed away from the edge of parent attachable shape.
// differenced away. The mask shape should be vertically oriented (Z-aligned) with the back-right
// quadrant (X+Y+) shaped to be diffed away from the edge of parent attachable shape. If no tag is set
// then `edge_mask` sets the tag for children to "remove" so that it will work with the default {{diff()}} tag.
// For details on specifying the edges to mask see [Specifying Edges](attachments.scad#subsection-specifying-edges).
// For a step-by-step explanation of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
// Figure: A Typical Edge Rounding Mask
@ -1260,9 +1261,9 @@ module show_int(tags)
// edges = Edges to mask. See [Specifying Edges](attachments.scad#subsection-specifying-edges). Default: All edges.
// except = Edges to explicitly NOT mask. See [Specifying Edges](attachments.scad#subsection-specifying-edges). Default: No edges.
// Side Effects:
// Sets `$tag = "mask"` for all children.
// Example:
// diff("mask")
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
// Example:
// diff()
// cube([50,60,70],center=true)
// edge_mask([TOP,"Z"],except=[BACK,TOP+LEFT])
// rounding_edge_mask(l=71,r=10);
@ -1282,13 +1283,14 @@ module edge_mask(edges=EDGES_ALL, except=[]) {
$attach_to = undef;
$attach_anchor = anch;
$attach_norot = true;
$tag = "mask";
rotang =
vec.z<0? [90,0,180+v_theta(vec)] :
vec.z==0 && sign(vec.x)==sign(vec.y)? 135+v_theta(vec) :
vec.z==0 && sign(vec.x)!=sign(vec.y)? [0,180,45+v_theta(vec)] :
[-90,0,180+v_theta(vec)];
translate(anch[1]) rot(rotang) children();
translate(anch[1]) rot(rotang)
if ($tag=="") tag("remove") children();
else children();
}
}
@ -1300,16 +1302,17 @@ module edge_mask(edges=EDGES_ALL, except=[]) {
// 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
// be `diff()`ed away. The 3D corner mask shape should be designed to mask away the X+Y+Z+ octant.
// be differenced away. The 3D corner mask shape should be designed to mask away the X+Y+Z+ octant. If no tag is set
// then `corner_mask` sets the tag for children to "remove" so that it will work with the default {{diff()}} tag.
// See [Specifying Corners](attachments.scad#subsection-specifying-corners) for information on how to specify corner sets.
// For a step-by-step explanation of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
// Arguments:
// corners = Corners to mask. See [Specifying Corners](attachments.scad#subsection-specifying-corners). Default: All corners.
// except = Corners to explicitly NOT mask. See [Specifying Corners](attachments.scad#subsection-specifying-corners). Default: No corners.
// Side Effects:
// Sets `$tag = "mask"` for all children.
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
// Example:
// diff("mask")
// diff()
// cube(100, center=true)
// corner_mask([TOP,FRONT],LEFT+FRONT+TOP)
// difference() {
@ -1328,11 +1331,12 @@ module corner_mask(corners=CORNERS_ALL, except=[]) {
$attach_to = undef;
$attach_anchor = anch;
$attach_norot = true;
$tag = "mask";
rotang = vec.z<0?
[ 0,0,180+v_theta(vec)-45] :
[180,0,-90+v_theta(vec)-45];
translate(anch[1]) rot(rotang) children();
translate(anch[1]) rot(rotang)
if ($tag=="") tag("remove") children();
else children();
}
}
@ -1343,7 +1347,8 @@ module corner_mask(corners=CORNERS_ALL, except=[]) {
// Topics: Attachments
// 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.
// Given a 2D edge profile, extrudes it into a mask for all edges and corners bounding each given face. If no tag is set
// then `face_profile` sets the tag for children to "remove" so that it will work with the default {{diff()}} tag.
// See [Specifying Faces](attachments.scad#subsection-specifying-faces) for information on specifying faces.
// For a step-by-step explanation of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
// Arguments:
@ -1353,9 +1358,9 @@ module corner_mask(corners=CORNERS_ALL, except=[]) {
// d = Diameter of corner mask.
// convexity = Max number of times a line could intersect the perimeter of the mask shape. Default: 10
// Side Effects:
// Sets `$tag = "mask"` for all children.
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
// Example:
// diff("mask")
// diff()
// cube([50,60,70],center=true)
// face_profile(TOP,r=10)
// mask2d_roundover(r=10);
@ -1377,7 +1382,8 @@ module face_profile(faces=[], r, d, convexity=10) {
// 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
// extruded length to be `diff()`ed away, to give the edge a matching profile.
// extruded length to be `diff()`ed away, to give the edge a matching profile. If no tag is set
// then `edge_profile` sets the tag for children to "remove" so that it will work with the default {{diff()}} tag.
// For details on specifying the edges to mask see [Specifying Edges](attachments.scad#subsection-specifying-edges).
// For a step-by-step
// explanation of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
@ -1386,9 +1392,9 @@ module face_profile(faces=[], r, d, convexity=10) {
// except = Edges to explicitly NOT mask. See [Specifying Edges](attachments.scad#subsection-specifying-edges). Default: No edges.
// convexity = Max number of times a line could intersect the perimeter of the mask shape. Default: 10
// Side Effects:
// Sets `$tag = "mask"` for all children.
// Tags the children with "remove" (and hence sets `$tag`) if no tag is already set.
// Example:
// diff("mask")
// diff()
// cube([50,60,70],center=true)
// edge_profile([TOP,"Z"],except=[BACK,TOP+LEFT])
// mask2d_roundover(r=10, inset=2);
@ -1408,7 +1414,6 @@ module edge_profile(edges=EDGES_ALL, except=[], convexity=10) {
$attach_to = undef;
$attach_anchor = anch;
$attach_norot = true;
$tag = "mask";
psize = point3d($parent_size);
length = [for (i=[0:2]) if(!vec[i]) psize[i]][0]+0.1;
rotang =
@ -1419,7 +1424,8 @@ module edge_profile(edges=EDGES_ALL, except=[], convexity=10) {
translate(anch[1]) {
rot(rotang) {
linear_extrude(height=length, center=true, convexity=convexity) {
children();
if ($tag=="") tag("remove") children();
else children();
}
}
}
@ -1433,8 +1439,8 @@ module edge_profile(edges=EDGES_ALL, except=[], convexity=10) {
// 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
// to the selected corners with the appropriate orientation. Tags it as a "mask" to allow it to be
// `diff()`ed away, to give the corner a matching profile.
// to the selected corners with the appropriate orientation. If no tag is set
// then `corner_profile` sets the tag for children to "remove" so that it will work with the default {{diff()}} tag.
// See [Specifying Corners](attachments.scad#subsection-specifying-corners) for information on how to specify corner sets.
// For a step-by-step explanation of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
// Arguments:
@ -1445,9 +1451,9 @@ module edge_profile(edges=EDGES_ALL, except=[], convexity=10) {
// d = Diameter of corner mask.
// convexity = Max number of times a line could intersect the perimeter of the mask shape. Default: 10
// Side Effects:
// Sets `$tag = "mask"` for all children.
// Tags the children with "remove" (and hence sets $tag) if no tag is already set.
// Example:
// diff("mask")
// diff()
// cuboid([50,60,70],rounding=10,edges="Z",anchor=CENTER) {
// corner_profile(BOT,r=10)
// mask2d_teardrop(r=10, angle=40);
@ -1465,10 +1471,10 @@ module corner_profile(corners=CORNERS_ALL, except=[], r, d, convexity=10) {
$attach_to = undef;
$attach_anchor = anch;
$attach_norot = true;
$tag = "mask";
rotang = vec.z<0?
[ 0,0,180+v_theta(vec)-45] :
[180,0,-90+v_theta(vec)-45];
$tag = $tag=="" ? str($tag_prefix,"remove") : $tag;
translate(anch[1]) {
rot(rotang) {
render(convexity=convexity)
@ -2576,14 +2582,13 @@ function _is_shown() =
assert(is_list($tags_hidden))
let(
dummy=is_undef($tags) ? 0 : echo("Use tag() instead of $tags for specifying an object's tag."),
$tags = default($tag,$tags)
$tag = default($tag,$tags)
)
assert(is_string($tag), str("Tag value (",$tag,") is not a string"))
assert(undef==str_find($tag," "),str("Tag string \"",$tag,"\" contains a space, which is not allowed"))
let(
fulltag = $tag,
shown = $tags_shown=="ALL" || in_list(fulltag,$tags_shown),
hidden = in_list(fulltag, $tags_hidden)
shown = $tags_shown=="ALL" || in_list($tag,$tags_shown),
hidden = in_list($tag, $tags_hidden)
)
shown && !hidden;

View file

@ -72,33 +72,35 @@ module manfrotto_rc2_plate(chamfer="all",anchor,orient,spin)
left(10,back(-flat_height,select(pts,-3)))
];
tag_scope()
attachable(anchor,spin,orient,size=[botwid,length,thickness],size2=[topwid,length],shift=[.64115/2,0]){
tag_scope()
down(thickness/2)
diff()
linear_sweep(pts,h=length,convexity=4,orient=FWD,anchor=FWD){
zflip_copy()
down(.01)fwd(.01)left(.01)position(LEFT+FRONT+BOT)
cuboid([corner_space,(length-innerlen)/2,thickness+.02], chamfer=-chsize, $tag="remove",
orient=FWD,anchor=TOP+LEFT+FWD,edges=chamf_top?"ALL":TOP);
fwd(left_top)position(LEFT+BACK)linear_sweep(h=cutout_len,facet,convexity=4,$tag="remove",anchor=RIGHT+BACK);
tag("remove"){
zflip_copy()
down(.01)fwd(.01)left(.01)position(LEFT+FRONT+BOT)
cuboid([corner_space,(length-innerlen)/2,thickness+.02], chamfer=-chsize,
orient=FWD,anchor=TOP+LEFT+FWD,edges=chamf_top?"ALL":TOP);
fwd(left_top)position(LEFT+BACK)linear_sweep(h=cutout_len,facet,convexity=4,anchor=RIGHT+BACK);
}
if (chamf_bot){
edge_mask(FRONT+LEFT)chamfer_edge_mask(length,chsize,$tag="remove");
edge_mask(FRONT+RIGHT)chamfer_edge_mask(length,chsize,$tag="remove");
edge_mask(FRONT+TOP)chamfer_edge_mask(length,chsize,$tag="remove");
edge_mask(FRONT+BOT)chamfer_edge_mask(length,chsize,$tag="remove");
edge_mask(TOP+RIGHT)chamfer_edge_mask(length,chsize,$tag="remove");
edge_mask(BOT+RIGHT)chamfer_edge_mask(length,chsize,$tag="remove");
edge_mask(FRONT+LEFT)chamfer_edge_mask(length,chsize);
edge_mask(FRONT+RIGHT)chamfer_edge_mask(length,chsize);
edge_mask(FRONT+TOP)chamfer_edge_mask(length,chsize);
edge_mask(FRONT+BOT)chamfer_edge_mask(length,chsize);
edge_mask(TOP+RIGHT)chamfer_edge_mask(length,chsize);
edge_mask(BOT+RIGHT)chamfer_edge_mask(length,chsize);
zflip_copy(){
right(corner_space)edge_mask(TOP+LEFT) chamfer_edge_mask(length,chsize,$tag="remove");
down((length-innerlen)/2)edge_mask(TOP+LEFT) chamfer_edge_mask(length,chsize,$tag="remove");
right(corner_space)edge_mask(TOP+LEFT) chamfer_edge_mask(length,chsize);
down((length-innerlen)/2)edge_mask(TOP+LEFT) chamfer_edge_mask(length,chsize);
}
}
if (chamf_top){
edge_mask(BACK+LEFT)chamfer_edge_mask(length,chsize,$tag="remove");
edge_mask(BACK+RIGHT)chamfer_edge_mask(length,chsize,$tag="remove");
edge_mask(BACK+TOP)chamfer_edge_mask(length,chsize,$tag="remove");
edge_mask(BACK+BOT)chamfer_edge_mask(length,chsize,$tag="remove");
edge_mask(BACK+LEFT) chamfer_edge_mask(length,chsize);
edge_mask(BACK+RIGHT) chamfer_edge_mask(length,chsize);
edge_mask(BACK+TOP) chamfer_edge_mask(length,chsize);
edge_mask(BACK+BOT) chamfer_edge_mask(length,chsize);
}
}
children();

View file

@ -549,7 +549,8 @@ are a few specialized alternatives to the `attach()` and `position()` modules.
If you have a 3D mask shape that you want to difference away from various edges, you can use
the `edge_mask()` module. This module will take a vertically oriented shape, and will rotate
and move it such that the BACK, RIGHT (X+,Y+) side of the shape will be aligned with the given
edges. The shape will be tagged as a "mask" so that you can use `diff("mask")`. For example,
edges. The shape will be tagged as a "remove" so that you can use
`diff()` with its default "remove" tag. For example,
here's a shape for rounding an edge:
```openscad-3D
@ -573,7 +574,7 @@ module round_edge(l,r) difference() {
translate([r,r])
cylinder(h=l+1,r=r,center=true, $fn=quantup(segs(r),4));
}
diff("mask")
diff()
cube([50,60,70],center=true)
edge_mask([TOP,"Z"],except=[BACK,TOP+LEFT])
round_edge(l=71,r=10);
@ -583,7 +584,8 @@ cube([50,60,70],center=true)
If you have a 3D mask shape that you want to difference away from various corners, you can use
the `corner_mask()` module. This module will take a shape and rotate and move it such that the
BACK RIGHT TOP (X+,Y+,Z+) side of the shape will be aligned with the given corner. The shape
will be tagged as a "mask" so that you can use `diff("mask")`. For example, here's a shape for
will be tagged as a "remove" so that you can use `diff()` with its
default "remove" tag. For example, here's a shape for
rounding a corner:
```openscad-3D
@ -607,7 +609,7 @@ module round_corner(r) difference() {
translate([r,r,r])
sphere(r=r, style="aligned", $fn=quantup(segs(r),4));
}
diff("mask")
diff()
cube([50,60,70],center=true)
corner_mask([TOP,FRONT],LEFT+FRONT+TOP)
round_corner(r=10);
@ -630,7 +632,7 @@ module round_edge(l,r) difference() {
translate([r,r])
cylinder(h=l+1,r=r,center=true, $fn=quantup(segs(r),4));
}
diff("mask")
diff()
cube([50,60,70],center=true) {
edge_mask("ALL") round_edge(l=71,r=10);
corner_mask("ALL") round_corner(r=10);
@ -647,7 +649,8 @@ mask shape (via `rotate_extrude()`). This is where `edge_profile()`, `corner_pr
### `edge_profile()`
Using the `edge_profile()` module, you can provide a 2D profile shape and it will be linearly
extruded to a mask of the apropriate length for each given edge. The resultant mask will be
tagged with "mask" so that you can difference it away with `diff("mask")`. The 2D profile is
tagged with "remove" so that you can difference it away with `diff()`
with the default "remove" tag. The 2D profile is
assumed to be oriented with the BACK, RIGHT (X+,Y+) quadrant as the "cutter edge" that gets
re-oriented towards the edges of the parent shape. A typical mask profile for chamfering an
edge may look like:
@ -661,7 +664,7 @@ Using that mask profile, you can mask the edges of a cube like:
```openscad-3D
include <BOSL2/std.scad>
diff("mask")
diff()
cube([50,60,70],center=true)
edge_profile("ALL")
mask2d_roundover(10);
@ -672,7 +675,7 @@ You can use the same profile to make a rounded corner mask as well:
```openscad-3D
include <BOSL2/std.scad>
diff("mask")
diff()
cube([50,60,70],center=true)
corner_profile("ALL", r=10)
mask2d_roundover(10);
@ -684,7 +687,7 @@ As a simple shortcut to apply a profile mask to all edges and corners of a face,
```openscad-3D
include <BOSL2/std.scad>
diff("mask")
diff()
cube([50,60,70],center=true)
face_profile(TOP, r=10)
mask2d_roundover(10);