mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
Update hull to support new tagging method. Change hulling to conv_hull
This commit is contained in:
parent
33d9ca4352
commit
458acdf803
2 changed files with 135 additions and 59 deletions
137
attachments.scad
137
attachments.scad
|
@ -541,19 +541,20 @@ module attach(from, to, overlap, norot=false)
|
|||
|
||||
// Module: tag()
|
||||
// Usage:
|
||||
// tag(tags) CHILDREN;
|
||||
// tag(tag) CHILDREN;
|
||||
// Topics: Attachments
|
||||
// See Also: force_tag(), recolor(), hide(), show_only(), diff(), intersect()
|
||||
// Description:
|
||||
// Sets the `$tag` variable as specified for all its children. This makes it easy to set the tag
|
||||
// on multiple items without having to repeat the tag setting for each one. Note that if you want
|
||||
// Assigns the specified tag to all of the children. Note that if you want
|
||||
// to apply a tag to non-tag-aware objects you need to use {{force_tag()}} instead.
|
||||
// This works by setting the `$tag` variable, but it provides extra error checking and
|
||||
// handling of scopes. You may set `$tag` directly yourself, but this is not recommended.
|
||||
// .
|
||||
// For a step-by-step explanation of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
|
||||
// Arguments:
|
||||
// tag = tag string, which must not contain any spaces.
|
||||
// Side Effects:
|
||||
// Sets `$tag` to the tags you specify.
|
||||
// Sets `$tag` to the tag you specify.
|
||||
// Example(3D): Applies the tag to both cuboids instead of having to repeat `$tag="remove"` for each one.
|
||||
// diff("remove")
|
||||
// cuboid(10){
|
||||
|
@ -582,7 +583,8 @@ module tag(tag)
|
|||
// Description:
|
||||
// You use this module when you want to make a non-attachable or non-BOSL2 module respect tags.
|
||||
// It applies to its children the tag specified (or the tag currently in force if you don't specify a tag),
|
||||
// making a final determination about whether to show or hide the children. This means that tagging in children's children will be ignored.
|
||||
// making a final determination about whether to show or hide the children.
|
||||
// This means that tagging in children's children will be ignored.
|
||||
// This module is specifically provided for operating on children that are not tag aware such as modules
|
||||
// that don't use {{attachable()}} or built in modules such as
|
||||
// - `polygon()`
|
||||
|
@ -592,6 +594,9 @@ module tag(tag)
|
|||
// - `rotate_extrude()`
|
||||
// - `surface()`
|
||||
// - `import()`
|
||||
// - `difference()`
|
||||
// - `intersection()`
|
||||
// - `hull()`
|
||||
// .
|
||||
// When you use tag-based modules like {{diff()}} with a non-attachable module, the result may be puzzling.
|
||||
// Any time a test occurs for display of child() that test will succeed. This means that when diff() checks
|
||||
|
@ -604,7 +609,7 @@ module tag(tag)
|
|||
// Arguments:
|
||||
// tag = tag string, which must not contain any spaces
|
||||
// Side Effects:
|
||||
// Sets `$tag` to the tags you specify.
|
||||
// Sets `$tag` to the tag you specify.
|
||||
// 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()
|
||||
// {
|
||||
|
@ -636,6 +641,7 @@ module force_tag(tag)
|
|||
// Description:
|
||||
// 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.
|
||||
// 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)
|
||||
// {
|
||||
|
@ -786,7 +792,8 @@ module tag_scope(scope){
|
|||
// right(20)
|
||||
// circle(5);
|
||||
// }
|
||||
// Example: Here is another example where two children are intersected using the native intersection operator, and then tagged with {{force_tag()}}
|
||||
// Example: Here is another example where two children are intersected using the native intersection operator, and then tagged with {{force_tag()}}. Note that because the children are at the save level, you don't need to use a tagged operator for their intersection.
|
||||
// $fn=32;
|
||||
// diff()
|
||||
// cuboid(10){
|
||||
// force_tag("remove")intersection()
|
||||
|
@ -797,6 +804,7 @@ module tag_scope(scope){
|
|||
// tag("keep")cyl(r=1,h=9);
|
||||
// }
|
||||
// Example: In this example the children that are subtracted are each at different nesting levels, with a kept object in between.
|
||||
// $fn=32;
|
||||
// diff()
|
||||
// cuboid(10){
|
||||
// tag("remove")cyl(r=4,h=11)
|
||||
|
@ -804,6 +812,7 @@ module tag_scope(scope){
|
|||
// tag("remove")position(RIGHT)cyl(r=2,h=18);
|
||||
// }
|
||||
// Example: Combining tag operators can be tricky. Here the `diff()` operation keeps two tags, "fullkeep" and "keep". Then {{intersect()}} intersects the "keep" tagged item with everything else, but keeps the "fullkeep" object.
|
||||
// $fn=32;
|
||||
// intersect("keep","fullkeep")
|
||||
// diff(keep="fullkeep keep")
|
||||
// cuboid(10){
|
||||
|
@ -864,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 tags you specify.
|
||||
// Sets `$tag` to the tag you specify.
|
||||
// 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);
|
||||
|
@ -931,8 +940,8 @@ module tag_diff(tag,remove="remove", keep="keep")
|
|||
// groups: objects matching the tags listed in `intersect`, objects
|
||||
// matching tags listed in `keep`, and the remaining objects that
|
||||
// don't match any of the listed tags. The intersection is computed
|
||||
// between the `intersect` tagged objects and the objects that don't
|
||||
// match the listed tags. Finally the objects listed in `keep` are
|
||||
// between the union of the `intersect` tagged objects and union of the objects that don't
|
||||
// match any of the listed tags. Finally the objects listed in `keep` are
|
||||
// unioned with the result. Attachable objects should be tagged using {{tag()}}
|
||||
// and non-attachable objects with {{force_tag()}}.
|
||||
// .
|
||||
|
@ -947,6 +956,7 @@ module tag_diff(tag,remove="remove", keep="keep")
|
|||
// tag("axle")xcyl(d=40, l=100);
|
||||
// }
|
||||
// Example: Combining tag operators can be tricky. Here the {{diff()}} operation keeps two tags, "fullkeep" and "keep". Then `intersect()` intersects the "keep" tagged item with everything else, but keeps the "fullkeep" object.
|
||||
// $fn=32;
|
||||
// intersect("keep","fullkeep")
|
||||
// diff(keep="fullkeep keep")
|
||||
// cuboid(10){
|
||||
|
@ -1003,8 +1013,18 @@ 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 tags you specify.
|
||||
// Sets `$tag` to the tag you specify.
|
||||
// Example: Without `tag_intersect()` the kept object is not included in the difference.
|
||||
// $fn=32;
|
||||
// diff()
|
||||
// cuboid([20,15,9])
|
||||
// tag("remove")intersect()
|
||||
// cuboid(10){
|
||||
// tag("intersect")position(RIGHT) cyl(r=7,h=10);
|
||||
// tag("keep")position(LEFT)cyl(r=4,h=10);
|
||||
// }
|
||||
// Example: Using tag_intersect corrects the problem.
|
||||
// $fn=32;
|
||||
// diff()
|
||||
// cuboid([20,15,9])
|
||||
// tag_intersect("remove")
|
||||
|
@ -1030,34 +1050,88 @@ module tag_intersect(tag,intersect="intersect",keep="keep")
|
|||
}
|
||||
|
||||
|
||||
// Module: hulling()
|
||||
// Module: conv_hull()
|
||||
// Usage:
|
||||
// hulling(hull) CHILDREN;
|
||||
// conv_hull([keep]) CHILDREN;
|
||||
// Topics: Attachments
|
||||
// See Also: tag(), recolor(), show_only(), hide(), diff(), intersect()
|
||||
// Description:
|
||||
// If `a` is not given, then all children are `hull()`ed together.
|
||||
// If `a` is given as a string, then all children with `$tag` that are in `a` are
|
||||
// `hull()`ed together and the result is then unioned with all the remaining children.
|
||||
// Cannot be used in conjunction with `diff()` or `intersect()` on the same parent object.
|
||||
// Performs a hull operation on the children using tags to determine what happens. The items
|
||||
// not tagged with the `keep` tags are combined into a convex hull, and the children tagged with the keep tags
|
||||
// are unioned with the result.
|
||||
// .
|
||||
// For a step-by-step explanation of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
|
||||
// Arguments:
|
||||
// hull = String containing space delimited set of tag names of children to hull.
|
||||
// keep = String containing space delimited set of tag names of children to keep out of the hull. Default: "keep"
|
||||
// Example:
|
||||
// hulling("body")
|
||||
// sphere(d=100, $tag="body") {
|
||||
// attach(CENTER) cube([40,90,90], anchor=CENTER, $tag="body");
|
||||
// attach(CENTER) xcyl(d=40, l=120, $tag="other");
|
||||
// conv_hull("keep")
|
||||
// sphere(d=100, $fn=64) {
|
||||
// cuboid([40,90,90]);
|
||||
// tag("keep")xcyl(d=40, l=120);
|
||||
// }
|
||||
module hulling(hull)
|
||||
// Example: difference combined with hull where all objects are relative to each other.
|
||||
// $fn=32;
|
||||
// diff()
|
||||
// conv_hull("remove")
|
||||
// cuboid(10)
|
||||
// position(RIGHT+BACK)cyl(r=4,h=10)
|
||||
// tag("remove")cyl(r=2,h=12);
|
||||
module conv_hull(keep="keep")
|
||||
{
|
||||
req_children($children);
|
||||
if (is_undef(hull)) {
|
||||
hull() children();
|
||||
} else {
|
||||
hull() show_only(hull) children();
|
||||
children();
|
||||
assert(is_string(keep),"keep must be a string of tags");
|
||||
if (_is_shown())
|
||||
hull() hide(keep) children();
|
||||
show_int(keep) children();
|
||||
}
|
||||
|
||||
|
||||
// Module: tag_conv_hull()
|
||||
// Usage:
|
||||
// tag,conv_hull(tag, [keep]) CHILDREN;
|
||||
// Topics: Attachments
|
||||
// See Also: tag(), recolor(), show_only(), hide(), diff(), intersect()
|
||||
// Description:
|
||||
// Perform a convex hull operation in the manner of {{conv_hull()}} using tags to control what happens,
|
||||
// and then tag the resulting hull object with the specified tag. This forces the specified
|
||||
// tag to be resolved at the level of the hull operation. In most cases, this is not necessary,
|
||||
// but if you have kept objects and want to operate on the hull object as a whole object using
|
||||
// more tag operations, you will probably not get the results you want if you simply use {{tag()}}.
|
||||
// .
|
||||
// For a step-by-step explanation of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
|
||||
// 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.
|
||||
// Example: With a regular tag, the kept object is not handled as desired:
|
||||
// diff(){
|
||||
// cuboid([30,30,9])
|
||||
// tag("remove")conv_hull("remove")
|
||||
// cuboid(10,anchor=LEFT+FRONT){
|
||||
// position(RIGHT+BACK)cyl(r=4,h=10);
|
||||
// tag("keep")position(FRONT+LEFT)cyl(r=4,h=10);
|
||||
// }
|
||||
// }
|
||||
// Example: Using `tag_conv_hull()` fixes the problem:
|
||||
// diff(){
|
||||
// cuboid([30,30,9])
|
||||
// tag_conv_hull("remove")
|
||||
// cuboid(10,anchor=LEFT+FRONT){
|
||||
// position(RIGHT+BACK)cyl(r=4,h=10);
|
||||
// tag("keep")position(FRONT+LEFT)cyl(r=4,h=10);
|
||||
// }
|
||||
// }
|
||||
module tag_conv_hull(tag,keep="keep")
|
||||
{
|
||||
req_children($children);
|
||||
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;
|
||||
if (_is_shown())
|
||||
show_all(){
|
||||
hull() hide(keep) children();
|
||||
show_only(keep) children();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1079,6 +1153,7 @@ module hulling(hull)
|
|||
// tag("B")attach(RIGHT, BOTTOM) cylinder(d=30, l=30);
|
||||
// }
|
||||
// Example: Use an invisible parent to position children. Note that children must be retagged because they inherit the parent tag.
|
||||
// $fn=16;
|
||||
// hide("hidden")
|
||||
// tag("hidden")cuboid(10)
|
||||
// tag("visible") {
|
||||
|
@ -1104,7 +1179,7 @@ module hide(tags)
|
|||
// Show only the children with the listed tags, which you sply as a space separated string. Only unhidden objects will be shown, so if an object is hidden either before or after the `show_only()` call then it will remain hidden. This overrides any previous `show_only()` calls. Unlike `hide()`, calls to `show_only()` are not cumulative.
|
||||
// For a step-by-step explanation of attachments, see the [[Attachments Tutorial|Tutorial-Attachments]].
|
||||
// Side Effects:
|
||||
// Sets `$tags_shown` to the tags you specify.
|
||||
// Sets `$tags_shown` to the tag you specify.
|
||||
// Example: Display the attachments but not the parent
|
||||
// show_only("visible")
|
||||
// cube(50, anchor=CENTER)
|
||||
|
@ -2491,11 +2566,11 @@ function _find_anchor(anchor, geom) =
|
|||
|
||||
/// Internal Function: _is_shown()
|
||||
// Usage:
|
||||
// bool = _is_shown(tags);
|
||||
// bool = _is_shown();
|
||||
/// Topics: Attachments
|
||||
/// See Also: reorient(), attachable()
|
||||
// Description:
|
||||
// Returns true if shapes tagged with any of the given space-delimited string of tag names should currently be shown.
|
||||
// Returns true if objects should currently be shown based on the tag settings.
|
||||
function _is_shown() =
|
||||
assert(is_list($tags_shown) || $tags_shown=="ALL")
|
||||
assert(is_list($tags_hidden))
|
||||
|
|
|
@ -402,11 +402,11 @@ cylinder(h=100, d=100, center=true)
|
|||
|
||||
## Tagged Operations
|
||||
BOSL2 introduces the concept of tags. Tags are names that can be given to attachables, so that
|
||||
you can refer to them when performing `diff()`, `intersect()`, and `hulling()` operations.
|
||||
you can refer to them when performing `diff()`, `intersect()`, and `conv_hull()` operations.
|
||||
|
||||
### `diff(neg, <keep>)`
|
||||
### `diff(remove, <keep>)`
|
||||
The `diff()` operator is used to difference away all shapes marked with the tag(s) given to
|
||||
`neg=`, from the other shapes.
|
||||
`remove=`, from the other shapes.
|
||||
|
||||
For example, to difference away a child cylinder from the middle of a parent cube, you can
|
||||
do this:
|
||||
|
@ -526,13 +526,14 @@ cube(100, center=true) {
|
|||
}
|
||||
```
|
||||
|
||||
### `hulling(a)`
|
||||
You can use the `hulling()` module to hull shapes marked with a given tag together, before
|
||||
unioning the result with every other shape.
|
||||
### `conv_hull(keep)`
|
||||
You can use the `conv_hull()` module to hull shapes together the
|
||||
shapes not marked with the keep tags, before unioning the keep shapes
|
||||
into the final result.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
hulling("hull")
|
||||
conv_hull("pole")
|
||||
cube(50, center=true, $tag="hull") {
|
||||
cyl(h=100, d=20);
|
||||
xcyl(h=100, d=20, $tag="pole");
|
||||
|
|
Loading…
Reference in a new issue