mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-09-26 04:39:13 +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
|
// used when attachable() places the child
|
||||||
$anchor_override = all_zero(child_adjustment)? inside?child:undef
|
$anchor_override = all_zero(child_adjustment)? inside?child:undef
|
||||||
: child+child_adjustment;
|
: child+child_adjustment;
|
||||||
|
|
||||||
reference = two_d? BACK : UP;
|
reference = two_d? BACK : UP;
|
||||||
// inset_dir is the direction for insetting when alignment is in effect
|
// inset_dir is the direction for insetting when alignment is in effect
|
||||||
inset_dir = is_undef(align) ? CTR
|
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;
|
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))
|
if (norot || (approx(anchor_dir,reference) && anchor_spin==0))
|
||||||
translate(pos) rot(v=spinaxis,a=factor*spin) translate(olap) default_tag("remove",removetag) children();
|
translate(pos) rot(v=spinaxis,a=factor*spin) translate(olap) default_tag("remove",removetag) children();
|
||||||
else
|
else
|
||||||
@@ -4168,6 +4169,7 @@ function _find_anchor(anchor, geom)=
|
|||||||
let(
|
let(
|
||||||
vnf=geom[1],
|
vnf=geom[1],
|
||||||
override = geom[2](anchor)
|
override = geom[2](anchor)
|
||||||
|
,fd=echo(cp=cp)
|
||||||
) // CENTER anchors anchor on cp, "origin" anchors on [0,0]
|
) // 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)] :
|
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] :
|
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) {
|
if (std) {
|
||||||
for (anchor=_standard_anchors(two_d=two_d)) {
|
for (anchor=_standard_anchors(two_d=two_d)) {
|
||||||
if(two_d) {
|
if(two_d) {
|
||||||
attach(anchor) anchor_arrow2d(s);
|
attach(anchor,BOT) anchor_arrow2d(s);
|
||||||
} else {
|
} else {
|
||||||
attach(anchor) anchor_arrow(s);
|
attach(anchor,BOT) anchor_arrow(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (custom) {
|
if (custom) {
|
||||||
for (anchor=last($parent_geom)) {
|
for (anchor=last($parent_geom)) {
|
||||||
attach(anchor[0]) {
|
attach(anchor[0],BOT) {
|
||||||
if(two_d) {
|
if(two_d) {
|
||||||
anchor_arrow2d(s, color="cyan");
|
anchor_arrow2d(s, color="cyan");
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
[Previous: Using position()](Tutorial-Attachment-Position)
|
||||||
|
|
||||||
# Aligning children with align()
|
# Aligning children with align()
|
||||||
|
|
||||||
You may have noticed that with position() and orient(), specifying the
|
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)
|
align([1,.3],TOP)
|
||||||
color("lightblue")cuboid(5);
|
color("lightblue")cuboid(5);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[Next: Using attach()](Tutorial-Attachment-Attach)
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
[Prev: Using align()](Tutorial-Attachment-Align)
|
||||||
|
|
||||||
# Attachment using attach()
|
# Attachment using attach()
|
||||||
|
|
||||||
The `attach()` module can stick the child object to the parent object
|
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);
|
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
|
# Basic Object Positioning: Anchor, Spin and Orient
|
||||||
|
|
||||||
When you create attachable objects using BOSL2 you have some options
|
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>
|
include <BOSL2/std.scad>
|
||||||
square([40,30], anchor=BACK+LEFT, spin=30);
|
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
|
## Coloring Attachables
|
||||||
Usually, when coloring a shape with the `color()` module, the parent color overrides the colors of
|
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:
|
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
|
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
|
on attachable objects, so they will have no effect on objects you
|
||||||
create using `linear_extrude()` or `rotate_extrude()`.
|
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
|
# Using Attachment for Edge Profiling
|
||||||
|
|
||||||
You can use attachment in various ways to create edge profiles on
|
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);
|
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
|
# Making Attachables
|
||||||
|
|
||||||
To make a shape attachable, you just need to wrap it with an `attachable()` module with a
|
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);
|
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()`,
|
Some of these have attachable alternatives: `vnf_polyhedron()`,
|
||||||
`linear_sweep()`, `rotate_sweep()`, and `region()`.
|
`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()
|
# Placing Children using position()
|
||||||
|
|
||||||
If you make an object a child of another object then the child object
|
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)
|
orient(RIGHT)
|
||||||
anchor_arrow(40);
|
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: Placing Children using position(), align(), and attach()
|
||||||
|
|
||||||
Relative positioning is one of the most useful and powerful features
|
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
|
to other objects, you do not need to keep track of absolute positions
|
||||||
and orientations of objects in your model. This makes models simpler,
|
and orientations of objects in your model. This makes models simpler,
|
||||||
more intuitive, and easier to maintain.
|
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
|
# Tagged Operations
|
||||||
|
|
||||||
BOSL2 introduces the concept of tags. Tags are names that can be given to attachables, so that
|
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);
|
tag("keep")xcyl(h=100, d=20);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[Next: Edge Profiling with Attachment](Tutorial-Attachment-Edge-Profiling)
|
||||||
|
Reference in New Issue
Block a user