mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-08 16:46:55 +02:00
add attachable parts section and links between sections
This commit is contained in:
@@ -1046,6 +1046,7 @@ module attach(parent, child, overlap, align, spin=0, norot, inset=0, shiftout=0,
|
||||
// used when attachable() places the child
|
||||
$anchor_override = all_zero(child_adjustment)? inside?child:undef
|
||||
: child+child_adjustment;
|
||||
|
||||
reference = two_d? BACK : UP;
|
||||
// inset_dir is the direction for insetting when alignment is in effect
|
||||
inset_dir = is_undef(align) ? CTR
|
||||
@@ -1058,7 +1059,7 @@ module attach(parent, child, overlap, align, spin=0, norot, inset=0, shiftout=0,
|
||||
|
||||
|
||||
spinaxis = two_d? UP : anchor_dir;
|
||||
olap = - overlap * reference - inset*inset_dir + shiftout * (inset_dir + factor*reference);
|
||||
olap = - overlap * reference - inset*inset_dir + shiftout * (inset_dir + factor*reference*($anchor_inside?-1:1));
|
||||
if (norot || (approx(anchor_dir,reference) && anchor_spin==0))
|
||||
translate(pos) rot(v=spinaxis,a=factor*spin) translate(olap) default_tag("remove",removetag) children();
|
||||
else
|
||||
@@ -4168,6 +4169,7 @@ function _find_anchor(anchor, geom)=
|
||||
let(
|
||||
vnf=geom[1],
|
||||
override = geom[2](anchor)
|
||||
,fd=echo(cp=cp)
|
||||
) // CENTER anchors anchor on cp, "origin" anchors on [0,0]
|
||||
approx(anchor,CTR)? [anchor, default(override[0],cp),default(override[1],UP),default(override[2], 0)] :
|
||||
vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor,UP), 0] :
|
||||
@@ -4448,15 +4450,15 @@ module show_anchors(s=10, std=true, custom=true) {
|
||||
if (std) {
|
||||
for (anchor=_standard_anchors(two_d=two_d)) {
|
||||
if(two_d) {
|
||||
attach(anchor) anchor_arrow2d(s);
|
||||
attach(anchor,BOT) anchor_arrow2d(s);
|
||||
} else {
|
||||
attach(anchor) anchor_arrow(s);
|
||||
attach(anchor,BOT) anchor_arrow(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (custom) {
|
||||
for (anchor=last($parent_geom)) {
|
||||
attach(anchor[0]) {
|
||||
attach(anchor[0],BOT) {
|
||||
if(two_d) {
|
||||
anchor_arrow2d(s, color="cyan");
|
||||
} else {
|
||||
|
@@ -1,3 +1,5 @@
|
||||
[Previous: Using position()](Tutorial-Attachment-Position)
|
||||
|
||||
# Aligning children with align()
|
||||
|
||||
You may have noticed that with position() and orient(), specifying the
|
||||
@@ -125,3 +127,5 @@ cyl(h=20,d=10,$fn=128)
|
||||
align([1,.3],TOP)
|
||||
color("lightblue")cuboid(5);
|
||||
```
|
||||
|
||||
[Next: Using attach()](Tutorial-Attachment-Attach)
|
||||
|
@@ -1,3 +1,5 @@
|
||||
[Prev: Using align()](Tutorial-Attachment-Align)
|
||||
|
||||
# Attachment using attach()
|
||||
|
||||
The `attach()` module can stick the child object to the parent object
|
||||
@@ -674,3 +676,5 @@ circle(d=50){
|
||||
trapezoid(w1=30,w2=0,h=30);
|
||||
}
|
||||
```
|
||||
|
||||
[Next: Attachable Parts](Tutorial-Attachment-Parts)
|
||||
|
@@ -1,3 +1,5 @@
|
||||
[Previous: Attachments Overview](Tutorial-Attachment-Overview)
|
||||
|
||||
# Basic Object Positioning: Anchor, Spin and Orient
|
||||
|
||||
When you create attachable objects using BOSL2 you have some options
|
||||
@@ -320,3 +322,5 @@ For 2D shapes, you can mix `anchor=` with `spin=`, but not with `orient=`.
|
||||
include <BOSL2/std.scad>
|
||||
square([40,30], anchor=BACK+LEFT, spin=30);
|
||||
```
|
||||
|
||||
[Next: Relative Positioning of Children](Tutorial-Attachment-Relative-Positioning)
|
||||
|
@@ -1,3 +1,5 @@
|
||||
[Prev: Attachable Parts](Tutorial-Attachment-Parts)
|
||||
|
||||
## Coloring Attachables
|
||||
Usually, when coloring a shape with the `color()` module, the parent color overrides the colors of
|
||||
all children. This is often not what you want:
|
||||
@@ -57,3 +59,5 @@ affecting its descendents.
|
||||
As with all of the attachable features, these color, highlight and ghost modules only work
|
||||
on attachable objects, so they will have no effect on objects you
|
||||
create using `linear_extrude()` or `rotate_extrude()`.
|
||||
|
||||
[Next: Tagged Operations with Attachments](Tutorial-Attachment-Tags)
|
||||
|
@@ -1,3 +1,5 @@
|
||||
[Prev: Tagged Operations with Attachments](Tutorial-Attachment-Tags)
|
||||
|
||||
# Using Attachment for Edge Profiling
|
||||
|
||||
You can use attachment in various ways to create edge profiles on
|
||||
@@ -163,4 +165,4 @@ cube([50,60,70],center=true)
|
||||
mask2d_roundover(10);
|
||||
```
|
||||
|
||||
|
||||
[Next: Making Attachable Objects](Tutorial-Attachment-Making)
|
||||
|
@@ -1,3 +1,5 @@
|
||||
[Prev: Edge Profiling with Attachment](Tutorial-Attachment-Edge-Profiling)
|
||||
|
||||
# Making Attachables
|
||||
|
||||
To make a shape attachable, you just need to wrap it with an `attachable()` module with a
|
||||
@@ -531,3 +533,140 @@ module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) {
|
||||
}
|
||||
cubic_barbell(100) show_anchors(30);
|
||||
```
|
||||
|
||||
## Making Gometry With attach_geom()
|
||||
|
||||
Sometimes it may be advantageous to create the attachable geometry as
|
||||
a data structure. This can be particularly useful if you want to
|
||||
implement anchor types with an object, because it allows for an easy
|
||||
way to create different anchor options without having to repeat code.
|
||||
|
||||
Suppose we create a simple tetrahedron object:
|
||||
|
||||
```openscad-3D
|
||||
include<BOSL2/std.scad>
|
||||
module tetrahedron(base, height, spin=0, anchor=FWD+LEFT+BOT, orient=UP)
|
||||
{
|
||||
base_poly = path3d([[0,0],[0,base],[base,0]]);
|
||||
top = [0,0,height];
|
||||
vnf = vnf_vertex_array([base_poly, repeat(top,3)],col_wrap=true,cap1=true);
|
||||
attachable(anchor=anchor,orient=orient,spin=spin,vnf=vnf,cp="centroid"){
|
||||
vnf_polyhedron(vnf);
|
||||
children();
|
||||
}
|
||||
}
|
||||
tetrahedron(20,18) show_anchors();
|
||||
```
|
||||
|
||||
For this module we have used VNF anchors, but this tetrahedron is half
|
||||
related to a cuboid, so maybe sometimes you prefer to use anchors
|
||||
based on the bounding box. You could create a module with bounding
|
||||
box anchors like this, where we have had to explicitly center the VNF
|
||||
to make it work with the prismoid type anchoring:
|
||||
|
||||
```openscad-3D
|
||||
include<BOSL2/std.scad>
|
||||
module tetrahedron(base, height, spin=0, anchor=FWD+LEFT+BOT, orient=UP)
|
||||
{
|
||||
base_poly = path3d([[0,0],[0,base],[base,0]]);
|
||||
top = [0,0,height];
|
||||
vnf = move([-base/2,-base/2,-height/2],
|
||||
vnf_vertex_array([base_poly, repeat(top,3)],col_wrap=true,cap1=true));
|
||||
attachable(anchor=anchor,orient=orient,spin=spin,size=[base,base,height]){
|
||||
vnf_polyhedron(vnf);
|
||||
children();
|
||||
}
|
||||
}
|
||||
tetrahedron(20,18) show_anchors();
|
||||
```
|
||||
|
||||
The arguments needed to attachable are different in this case. If you
|
||||
want to conditionally switch between these two modes of operation,
|
||||
this presents a complication. While it is possible to work around
|
||||
this by conditionally setting parameters to `undef`, the resulting
|
||||
code will be more complex and harder to read. A better solution is to
|
||||
compute the geometry conditionally. Then the geometry can be passed
|
||||
to `attachable()`.
|
||||
|
||||
```openscad-3D;Big
|
||||
include<BOSL2/std.scad>
|
||||
module tetrahedron(base, height, atype="vnf", spin=0, anchor=FWD+LEFT+BOT, orient=UP)
|
||||
{
|
||||
assert(atype=="vnf" || atype=="box");
|
||||
base_poly = path3d([[0,0],[0,base],[base,0]]);
|
||||
top = [0,0,height];
|
||||
vnf = move([-base/2,-base/2,-height/2],
|
||||
vnf_vertex_array([base_poly, repeat(top,3)],col_wrap=true,cap1=true));
|
||||
geom = atype=="vnf" ? attach_geom(vnf=vnf,cp="centroid")
|
||||
: attach_geom(size=[base,base,height]);
|
||||
attachable(anchor=anchor,orient=orient,spin=spin,geom=geom){
|
||||
vnf_polyhedron(vnf);
|
||||
children();
|
||||
}
|
||||
}
|
||||
tetrahedron(20,18,atype="vnf")
|
||||
color("green")attach(TOP,BOT) cuboid(4);
|
||||
right(25)
|
||||
tetrahedron(20,18,atype="box")
|
||||
color("lightblue")attach(TOP,BOT) cuboid(4);
|
||||
```
|
||||
|
||||
Here we have created an `atype` argument that accepts two attachment
|
||||
types and we compute the geometry conditionally based on the atype
|
||||
setting. We can then invoke `attachable()` once with the `geom`
|
||||
parameter to specify the geometry.
|
||||
|
||||
|
||||
## Creating Attachable Parts
|
||||
|
||||
If your object has multiple distinct parts you may wish to create
|
||||
attachble parts for your object. In the library, `tube()` create
|
||||
an attachable part called "inside" that lets you attach to the inside
|
||||
of the tube.
|
||||
|
||||
Below we create an example where an object is made from two
|
||||
cylindrical parts, and we want to be able to attach to either one.
|
||||
In order to create attchable parts you must pass a list of the parts
|
||||
to `attachable()`. You create a part using the `define_part()`
|
||||
function which requires the part's name and its geometry. You can
|
||||
optionally provide a transformation using the `T=` parameter and give
|
||||
a flat with the `inside=` parameter.
|
||||
|
||||
```openscad-3D;Big
|
||||
include<BOSL2/std.scad>
|
||||
module twocyl(d1, d2, sep, h, ang=20)
|
||||
{
|
||||
parts = [
|
||||
define_part("left", attach_geom(r=d1/2,h=h),
|
||||
T=left(sep/2)*yrot(-ang)),
|
||||
define_part("right", attach_geom(r=d2/2,h=h),
|
||||
T=right(sep/2)*yrot(ang)),
|
||||
];
|
||||
attachable(size=[sep+d1/2+d2/2,max(d1,d2),h], parts=parts){
|
||||
union(){
|
||||
left(sep/2) yrot(-ang) cyl(d=d1,h=h);
|
||||
right(sep/2) yrot(ang) cyl(d=d2,h=h);
|
||||
}
|
||||
children();
|
||||
}
|
||||
}
|
||||
twocyl(d1=10,d2=13,sep=20,h=10){
|
||||
attach_part("left") attach(FWD,BOT)
|
||||
color("lightblue") cuboid(3);
|
||||
attach_part("right") attach(RIGHT,BOT)
|
||||
color("green") cuboid(3);
|
||||
}
|
||||
```
|
||||
|
||||
In the above example we create a parts list containing two parts named
|
||||
"left" and "right". Each part has its own geometry corresponding to
|
||||
the size of the cylinder, and it has a transformation specifying where
|
||||
the cylinder is located relative to the part's overall geometry.
|
||||
|
||||
If you create an "inside" part for a tube, the inside object will
|
||||
naturally have its anchors on the inner cylinder **pointing
|
||||
outward**. You can anchor on the inside by setting `inside=true` when
|
||||
invoking `attach()` or `align()`, but another option set `inside=true`
|
||||
when creating the part with `define_part()`. This cause `align()` and
|
||||
`attach()` to invert the meaning of the `inside` parameter so that
|
||||
objects will attach on the inside by default.
|
||||
|
@@ -24,4 +24,6 @@ tutorial. The non-attachables are `polyhedron()`, `linear_extrude()`,
|
||||
Some of these have attachable alternatives: `vnf_polyhedron()`,
|
||||
`linear_sweep()`, `rotate_sweep()`, and `region()`.
|
||||
|
||||
[Next: Basic Positioning](Tutorial-Attachment-Basic-Positioning)
|
||||
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
[Previous: Relative Positioning of Children](Tutorial-Attachment-Relative-Positioning)
|
||||
|
||||
# Placing Children using position()
|
||||
|
||||
If you make an object a child of another object then the child object
|
||||
@@ -203,3 +205,5 @@ prismoid([50,50],[30,30],h=40)
|
||||
orient(RIGHT)
|
||||
anchor_arrow(40);
|
||||
```
|
||||
|
||||
[Next: Using align()](Tutorial-Attachment-Align)
|
||||
|
@@ -1,3 +1,5 @@
|
||||
[Prev: Basic Positioning](Tutorial-Attachment-Basic-Positioning)
|
||||
|
||||
# Relative Positioning: Placing Children using position(), align(), and attach()
|
||||
|
||||
Relative positioning is one of the most useful and powerful features
|
||||
@@ -17,3 +19,5 @@ Relative positioning means that since objects are positioned relative
|
||||
to other objects, you do not need to keep track of absolute positions
|
||||
and orientations of objects in your model. This makes models simpler,
|
||||
more intuitive, and easier to maintain.
|
||||
|
||||
[Next: Using position()](Tutorial-Attachment-Position)
|
||||
|
@@ -1,3 +1,5 @@
|
||||
[Prev: Using color with attachments](Tutorial-Attachment-Color)
|
||||
|
||||
# Tagged Operations
|
||||
|
||||
BOSL2 introduces the concept of tags. Tags are names that can be given to attachables, so that
|
||||
@@ -183,3 +185,5 @@ cube(50, center=true) {
|
||||
tag("keep")xcyl(h=100, d=20);
|
||||
}
|
||||
```
|
||||
|
||||
[Next: Edge Profiling with Attachment](Tutorial-Attachment-Edge-Profiling)
|
||||
|
Reference in New Issue
Block a user