discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

BOSL2 attachments and anchoring

RV
Roel Vanhout
Wed, Jan 31, 2024 3:46 PM

Hello all,

I've tried (again) to learn how attaching and anchoring works with BOSL2,
as I have a feeling that it will solve much of the tediousness I experience
when programming models with openscad. Unlike previous attempts at learning
this, this time I sat down and read both the manual and the
https://github.com/BelfrySCAD/BOSL2/wiki/Tutorial-Attachments tutorial
front to back (I'll admit that I sort of glossed over the parts of the
manual where it just became too much of a jargon mumble for me to
understand). And while I do feel that I sort of get the nuances of the
terminology now, in the first test project I want to apply it to, I'm
already hitting a roadblock pretty much straight away.

I have a snap-in clip hook (sorry don't know a better word) which consists
of a few cubes, plus a filleted and extruded 2d shape (example of complete
part in fig 1 below). I thought I could make the clip a separate module,
and the base and sides another, define attachment points and which way is
'up' on both. So like figs 2 and 3 below. And then say 'instantiate module
'base' as well as module 'clip', and position it so that points A and B
touch'. And then I could maybe also define an attachment point at the back
of the base of the clip, and use it with the BOSL2 fillet() module with the
right position and alignment, so that I get the result in fig 4. While in
this concrete example the number of lines of codes wouldn't be drastically
different, my idea of the goal of attachments (and what I'd like to use it
for) is that I could move to a mental model where I first construct simple
parts at the origin, and then assemble them together in a final step, using
attachment points defined in the smaller parts - so without having to do
translations and rotations that depend on the exact sizes of the individual
parts, which are quite often details that are local yet have to be stored
in global variables to make this positioning possible, at least if you want
to prevent a lot of ad hoc argument passing.

There are lots of examples of how to set various points on simple shapes in
the tutorial, but how do I go about setting attachment points on 'compound
shapes', even ones as simple as those presented here?

I've included the stripped down code at the bottom to clarify what I've
been doing.

Thanks.

Fig 1:

[image: image.png]

Fig 2:

[image: image.png]

Fig 3:

[image: image.png]

Fig 4:

[image: image.png]

include <BOSL2-master/std.scad>
include <BOSL2-master/transforms.scad>

clip_width = 10;
clip_height = 30;
clip_thickness = 2;            // Thickness of the 'spring' part
hook_height = 10;
hook_depth = 2.5;
hook_press_length = 7;
hook_fillet_radius = 1;

hook_clearance = 0.2;  // Distance to keep between parts that should fit
into each other snugly but without friction.

base_depth = 7;
base_width = 20;
base_height = 10;

side_clip_distance = 1; // Distance between the clip and the stems next to
it.

female_wall_thickness = 2;
female_play = 0.2;

// Calculated variables
side_width = (base_width - clip_width - (2 * side_clip_distance)) / 2;
// This is the width of the stems on the left and right of the clip

// Copied from OpenSCAD manual for offset(), but there, the r/-r are
swapped and that version doesn't work.
module fillet_2d_shape(r) {
offset(r = r) {
offset(delta = -r) {
children();
}
}
}

module hook2(extra_clearance) {
up(base_height) xrot(90) yrot(90)
union() {
linear_extrude(clip_width + (2 * extra_clearance), center=false)
union() {
//p1 = [0, 0];
//p2 = [clip_thickness, 0];
p2 = [clip_thickness, clip_height - hook_height -
hook_press_length];
p3 = [clip_thickness, clip_height];
p4 = [0, clip_height];
p5 = [-hook_depth, clip_height - hook_height];
p6 = [-hook_depth, clip_height - hook_height -
hook_press_length];
p7 = [0, clip_height - hook_height - hook_press_length];
fillet_2d_shape(hook_fillet_radius)
polygon(points = [ p2, p3, p4, p5, p6, p7 ]);
square([clip_thickness, clip_height - hook_height]);
};

        up(clip_width / 2) right(clip_thickness)
            fillet(clip_width, base_depth - clip_thickness, orient=UP);
    }

}

module frame(extra_clearance) {
cube([base_width + (2 * extra_clearance), base_depth + (2 *
extra_clearance), base_height + extra_clearance]);

// Sides
up(base_height)
    cube([side_width, base_depth + (2 * extra_clearance), clip_height +

extra_clearance]);
up(base_height) right(base_width - side_width + (2 * extra_clearance))
cube([side_width, base_depth + (2 * extra_clearance), clip_height +
extra_clearance]);
}

module snap_fit_male(extra_clearance) {
frame(extra_clearance);

right(side_width + side_clip_distance)
    hook2(extra_clearance);

}

module snap_fit_female() {
difference() {
total_female_width = base_width + (2 * female_wall_thickness) + (2

  • hook_clearance);

      cube([ total_female_width,
          base_depth + (2 * female_wall_thickness) + (2 * hook_clearance),
          base_height + clip_height + female_wall_thickness]);
    
      // Render the male part with slight clearance, so that it fits less
    

loose.
right(female_wall_thickness + hook_clearance)
back(female_wall_thickness + hook_clearance)
union() {
hull()
frame(hook_clearance);
snap_fit_male(hook_clearance);
}

    // Cut an extra 'groove' on the backside, so that the clip (when it

slides in) has some more room to be pressed
// down into the female enclosure.

    groove_width = clip_width + (side_clip_distance * 2);
    groove_depth = 1;
    groove_length = clip_height;
    back(base_depth + hook_clearance + female_wall_thickness)

right((total_female_width / 2) - (groove_width / 2)) up(groove_depth)
#cube([groove_width, groove_depth, groove_length]);

    // Chamfer the front inside a little bit, so the clip can slide in

more easily.
chamfer_angle = 60;
//sin(20) = x / female_wall_thickness
y_offset = sin(chamfer_angle) * female_wall_thickness;
z_offset = cos(chamfer_angle) * female_wall_thickness;
back(y_offset + (female_wall_thickness / 2)) down(z_offset)
xrot(chamfer_angle) right((total_female_width / 2) -
(groove_width / 2)) back()
#cube([groove_width, female_wall_thickness * 2,
female_wall_thickness]);
}
}

snap_fit_male(0);

right(50)
snap_fit_female();

Hello all, I've tried (again) to learn how attaching and anchoring works with BOSL2, as I have a feeling that it will solve much of the tediousness I experience when programming models with openscad. Unlike previous attempts at learning this, this time I sat down and read both the manual and the https://github.com/BelfrySCAD/BOSL2/wiki/Tutorial-Attachments tutorial front to back (I'll admit that I sort of glossed over the parts of the manual where it just became too much of a jargon mumble for me to understand). And while I do feel that I sort of get the nuances of the terminology now, in the first test project I want to apply it to, I'm already hitting a roadblock pretty much straight away. I have a snap-in clip hook (sorry don't know a better word) which consists of a few cubes, plus a filleted and extruded 2d shape (example of complete part in fig 1 below). I thought I could make the clip a separate module, and the base and sides another, define attachment points and which way is 'up' on both. So like figs 2 and 3 below. And then say 'instantiate module 'base' as well as module 'clip', and position it so that points A and B touch'. And then I could maybe also define an attachment point at the back of the base of the clip, and use it with the BOSL2 fillet() module with the right position and alignment, so that I get the result in fig 4. While in this concrete example the number of lines of codes wouldn't be drastically different, my idea of the goal of attachments (and what I'd like to use it for) is that I could move to a mental model where I first construct simple parts at the origin, and then assemble them together in a final step, using attachment points defined in the smaller parts - so without having to do translations and rotations that depend on the exact sizes of the individual parts, which are quite often details that are local yet have to be stored in global variables to make this positioning possible, at least if you want to prevent a lot of ad hoc argument passing. There are lots of examples of how to set various points on simple shapes in the tutorial, but how do I go about setting attachment points on 'compound shapes', even ones as simple as those presented here? I've included the stripped down code at the bottom to clarify what I've been doing. Thanks. Fig 1: [image: image.png] Fig 2: [image: image.png] Fig 3: [image: image.png] Fig 4: [image: image.png] include <BOSL2-master/std.scad> include <BOSL2-master/transforms.scad> clip_width = 10; clip_height = 30; clip_thickness = 2; // Thickness of the 'spring' part hook_height = 10; hook_depth = 2.5; hook_press_length = 7; hook_fillet_radius = 1; hook_clearance = 0.2; // Distance to keep between parts that should fit into each other snugly but without friction. base_depth = 7; base_width = 20; base_height = 10; side_clip_distance = 1; // Distance between the clip and the stems next to it. female_wall_thickness = 2; female_play = 0.2; // Calculated variables side_width = (base_width - clip_width - (2 * side_clip_distance)) / 2; // This is the width of the stems on the left and right of the clip // Copied from OpenSCAD manual for offset(), but there, the r/-r are swapped and that version doesn't work. module fillet_2d_shape(r) { offset(r = r) { offset(delta = -r) { children(); } } } module hook2(extra_clearance) { up(base_height) xrot(90) yrot(90) union() { linear_extrude(clip_width + (2 * extra_clearance), center=false) union() { //p1 = [0, 0]; //p2 = [clip_thickness, 0]; p2 = [clip_thickness, clip_height - hook_height - hook_press_length]; p3 = [clip_thickness, clip_height]; p4 = [0, clip_height]; p5 = [-hook_depth, clip_height - hook_height]; p6 = [-hook_depth, clip_height - hook_height - hook_press_length]; p7 = [0, clip_height - hook_height - hook_press_length]; fillet_2d_shape(hook_fillet_radius) polygon(points = [ p2, p3, p4, p5, p6, p7 ]); square([clip_thickness, clip_height - hook_height]); }; up(clip_width / 2) right(clip_thickness) fillet(clip_width, base_depth - clip_thickness, orient=UP); } } module frame(extra_clearance) { cube([base_width + (2 * extra_clearance), base_depth + (2 * extra_clearance), base_height + extra_clearance]); // Sides up(base_height) cube([side_width, base_depth + (2 * extra_clearance), clip_height + extra_clearance]); up(base_height) right(base_width - side_width + (2 * extra_clearance)) cube([side_width, base_depth + (2 * extra_clearance), clip_height + extra_clearance]); } module snap_fit_male(extra_clearance) { frame(extra_clearance); right(side_width + side_clip_distance) hook2(extra_clearance); } module snap_fit_female() { difference() { total_female_width = base_width + (2 * female_wall_thickness) + (2 * hook_clearance); cube([ total_female_width, base_depth + (2 * female_wall_thickness) + (2 * hook_clearance), base_height + clip_height + female_wall_thickness]); // Render the male part with slight clearance, so that it fits less loose. right(female_wall_thickness + hook_clearance) back(female_wall_thickness + hook_clearance) union() { hull() frame(hook_clearance); snap_fit_male(hook_clearance); } // Cut an extra 'groove' on the backside, so that the clip (when it slides in) has some more room to be pressed // down into the female enclosure. groove_width = clip_width + (side_clip_distance * 2); groove_depth = 1; groove_length = clip_height; back(base_depth + hook_clearance + female_wall_thickness) right((total_female_width / 2) - (groove_width / 2)) up(groove_depth) #cube([groove_width, groove_depth, groove_length]); // Chamfer the front inside a little bit, so the clip can slide in more easily. chamfer_angle = 60; //sin(20) = x / female_wall_thickness y_offset = sin(chamfer_angle) * female_wall_thickness; z_offset = cos(chamfer_angle) * female_wall_thickness; back(y_offset + (female_wall_thickness / 2)) down(z_offset) xrot(chamfer_angle) right((total_female_width / 2) - (groove_width / 2)) back() #cube([groove_width, female_wall_thickness * 2, female_wall_thickness]); } } snap_fit_male(0); right(50) snap_fit_female();
AM
Adrian Mariano
Wed, Jan 31, 2024 10:53 PM

To create an object with anchor points you use the attachable() module,
possibly with named anchors to provide for special attachment points.
However, I think you probably want to reserve the use of this module for
actual finished parts, or components that will get a lot of use.  It's not
the easiest process to create well-behaved attachable modules, so I don't
think it makes sense to do it for intermediate one-off parts of a larger
model.  (It will basically be no easier than manually placing the part
where it needed to go.)

In the case of the object you show, I'd probably create a cuboid base.
That has attachable point A available.  Then you create the two side parts
by attaching them with align().  Then you can position() the fillet on top
and likewise the extruded part (which needs to be constructed so B is at
the origin).  If you plan to use the extruded part repeatedly it could make
sense to wrap it with attachable() and create the You might be able to get
linear_sweep to put an attachment point at B, but it is probably not worth
the trouble, and could fail down the road if you change the dimensions of
the part.

Once you have the final part constructed, then it makes sense to wrap it in
attachable() and create any named anchors that seem useful.

Your code could make more use of attachments.  I would make the basic
shape like this:

cuboid([10,5,5]){
xflip_copy() align(TOP+RIGHT) cuboid([2,5,10]);
}

When constructing a part I usually use position() or align() for every
part that I add to the basic part, because positions relative to the part
make more sense than absolute positions.

On Wed, Jan 31, 2024 at 10:46 AM Roel Vanhout via Discuss <
discuss@lists.openscad.org> wrote:

Hello all,

I've tried (again) to learn how attaching and anchoring works with BOSL2,
as I have a feeling that it will solve much of the tediousness I experience
when programming models with openscad. Unlike previous attempts at learning
this, this time I sat down and read both the manual and the
https://github.com/BelfrySCAD/BOSL2/wiki/Tutorial-Attachments tutorial
front to back (I'll admit that I sort of glossed over the parts of the
manual where it just became too much of a jargon mumble for me to
understand). And while I do feel that I sort of get the nuances of the
terminology now, in the first test project I want to apply it to, I'm
already hitting a roadblock pretty much straight away.

I have a snap-in clip hook (sorry don't know a better word) which consists
of a few cubes, plus a filleted and extruded 2d shape (example of complete
part in fig 1 below). I thought I could make the clip a separate module,
and the base and sides another, define attachment points and which way is
'up' on both. So like figs 2 and 3 below. And then say 'instantiate module
'base' as well as module 'clip', and position it so that points A and B
touch'. And then I could maybe also define an attachment point at the back
of the base of the clip, and use it with the BOSL2 fillet() module with the
right position and alignment, so that I get the result in fig 4. While in
this concrete example the number of lines of codes wouldn't be drastically
different, my idea of the goal of attachments (and what I'd like to use it
for) is that I could move to a mental model where I first construct simple
parts at the origin, and then assemble them together in a final step, using
attachment points defined in the smaller parts - so without having to do
translations and rotations that depend on the exact sizes of the individual
parts, which are quite often details that are local yet have to be stored
in global variables to make this positioning possible, at least if you want
to prevent a lot of ad hoc argument passing.

There are lots of examples of how to set various points on simple shapes
in the tutorial, but how do I go about setting attachment points on
'compound shapes', even ones as simple as those presented here?

I've included the stripped down code at the bottom to clarify what I've
been doing.

Thanks.

Fig 1:

[image: image.png]

Fig 2:

[image: image.png]

Fig 3:

[image: image.png]

Fig 4:

[image: image.png]

include <BOSL2-master/std.scad>
include <BOSL2-master/transforms.scad>

clip_width = 10;
clip_height = 30;
clip_thickness = 2;            // Thickness of the 'spring' part
hook_height = 10;
hook_depth = 2.5;
hook_press_length = 7;
hook_fillet_radius = 1;

hook_clearance = 0.2;  // Distance to keep between parts that should fit
into each other snugly but without friction.

base_depth = 7;
base_width = 20;
base_height = 10;

side_clip_distance = 1; // Distance between the clip and the stems next to
it.

female_wall_thickness = 2;
female_play = 0.2;

// Calculated variables
side_width = (base_width - clip_width - (2 * side_clip_distance)) / 2;
// This is the width of the stems on the left and right of the clip

// Copied from OpenSCAD manual for offset(), but there, the r/-r are
swapped and that version doesn't work.
module fillet_2d_shape(r) {
offset(r = r) {
offset(delta = -r) {
children();
}
}
}

module hook2(extra_clearance) {
up(base_height) xrot(90) yrot(90)
union() {
linear_extrude(clip_width + (2 * extra_clearance),
center=false)
union() {
//p1 = [0, 0];
//p2 = [clip_thickness, 0];
p2 = [clip_thickness, clip_height - hook_height -
hook_press_length];
p3 = [clip_thickness, clip_height];
p4 = [0, clip_height];
p5 = [-hook_depth, clip_height - hook_height];
p6 = [-hook_depth, clip_height - hook_height -
hook_press_length];
p7 = [0, clip_height - hook_height -
hook_press_length];
fillet_2d_shape(hook_fillet_radius)
polygon(points = [ p2, p3, p4, p5, p6, p7 ]);
square([clip_thickness, clip_height - hook_height]);
};

         up(clip_width / 2) right(clip_thickness)
             fillet(clip_width, base_depth - clip_thickness, orient=UP);
     }

}

module frame(extra_clearance) {
cube([base_width + (2 * extra_clearance), base_depth + (2 *
extra_clearance), base_height + extra_clearance]);

 // Sides
 up(base_height)
     cube([side_width, base_depth + (2 * extra_clearance), clip_height
  • extra_clearance]);
    up(base_height) right(base_width - side_width + (2 * extra_clearance))
    cube([side_width, base_depth + (2 * extra_clearance), clip_height
  • extra_clearance]);
    }

module snap_fit_male(extra_clearance) {
frame(extra_clearance);

 right(side_width + side_clip_distance)
     hook2(extra_clearance);

}

module snap_fit_female() {
difference() {
total_female_width = base_width + (2 * female_wall_thickness) + (2

  • hook_clearance);

      cube([ total_female_width,
          base_depth + (2 * female_wall_thickness) + (2 *
    

hook_clearance),
base_height + clip_height + female_wall_thickness]);

     // Render the male part with slight clearance, so that it fits

less loose.
right(female_wall_thickness + hook_clearance)
back(female_wall_thickness + hook_clearance)
union() {
hull()
frame(hook_clearance);
snap_fit_male(hook_clearance);
}

     // Cut an extra 'groove' on the backside, so that the clip (when

it slides in) has some more room to be pressed
// down into the female enclosure.

     groove_width = clip_width + (side_clip_distance * 2);
     groove_depth = 1;
     groove_length = clip_height;
     back(base_depth + hook_clearance + female_wall_thickness)

right((total_female_width / 2) - (groove_width / 2)) up(groove_depth)
#cube([groove_width, groove_depth, groove_length]);

     // Chamfer the front inside a little bit, so the clip can slide in

more easily.
chamfer_angle = 60;
//sin(20) = x / female_wall_thickness
y_offset = sin(chamfer_angle) * female_wall_thickness;
z_offset = cos(chamfer_angle) * female_wall_thickness;
back(y_offset + (female_wall_thickness / 2)) down(z_offset)
xrot(chamfer_angle) right((total_female_width / 2) -
(groove_width / 2)) back()
#cube([groove_width, female_wall_thickness * 2,
female_wall_thickness]);
}
}

snap_fit_male(0);

right(50)
snap_fit_female();


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

To create an object with anchor points you use the attachable() module, possibly with named anchors to provide for special attachment points. However, I think you probably want to reserve the use of this module for actual finished parts, or components that will get a lot of use. It's not the easiest process to create well-behaved attachable modules, so I don't think it makes sense to do it for intermediate one-off parts of a larger model. (It will basically be no easier than manually placing the part where it needed to go.) In the case of the object you show, I'd probably create a cuboid base. That has attachable point A available. Then you create the two side parts by attaching them with align(). Then you can position() the fillet on top and likewise the extruded part (which needs to be constructed so B is at the origin). If you plan to use the extruded part repeatedly it could make sense to wrap it with attachable() and create the You might be able to get linear_sweep to put an attachment point at B, but it is probably not worth the trouble, and could fail down the road if you change the dimensions of the part. Once you have the final part constructed, then it makes sense to wrap it in attachable() and create any named anchors that seem useful. Your code could make more use of attachments. I would make the basic shape like this: cuboid([10,5,5]){ xflip_copy() align(TOP+RIGHT) cuboid([2,5,10]); } When constructing a part I usually use position() or align() for *every* part that I add to the basic part, because positions relative to the part make more sense than absolute positions. On Wed, Jan 31, 2024 at 10:46 AM Roel Vanhout via Discuss < discuss@lists.openscad.org> wrote: > Hello all, > > I've tried (again) to learn how attaching and anchoring works with BOSL2, > as I have a feeling that it will solve much of the tediousness I experience > when programming models with openscad. Unlike previous attempts at learning > this, this time I sat down and read both the manual and the > https://github.com/BelfrySCAD/BOSL2/wiki/Tutorial-Attachments tutorial > front to back (I'll admit that I sort of glossed over the parts of the > manual where it just became too much of a jargon mumble for me to > understand). And while I do feel that I sort of get the nuances of the > terminology now, in the first test project I want to apply it to, I'm > already hitting a roadblock pretty much straight away. > > I have a snap-in clip hook (sorry don't know a better word) which consists > of a few cubes, plus a filleted and extruded 2d shape (example of complete > part in fig 1 below). I thought I could make the clip a separate module, > and the base and sides another, define attachment points and which way is > 'up' on both. So like figs 2 and 3 below. And then say 'instantiate module > 'base' as well as module 'clip', and position it so that points A and B > touch'. And then I could maybe also define an attachment point at the back > of the base of the clip, and use it with the BOSL2 fillet() module with the > right position and alignment, so that I get the result in fig 4. While in > this concrete example the number of lines of codes wouldn't be drastically > different, my idea of the goal of attachments (and what I'd like to use it > for) is that I could move to a mental model where I first construct simple > parts at the origin, and then assemble them together in a final step, using > attachment points defined in the smaller parts - so without having to do > translations and rotations that depend on the exact sizes of the individual > parts, which are quite often details that are local yet have to be stored > in global variables to make this positioning possible, at least if you want > to prevent a lot of ad hoc argument passing. > > There are lots of examples of how to set various points on simple shapes > in the tutorial, but how do I go about setting attachment points on > 'compound shapes', even ones as simple as those presented here? > > I've included the stripped down code at the bottom to clarify what I've > been doing. > > Thanks. > > > Fig 1: > > [image: image.png] > > Fig 2: > > [image: image.png] > > Fig 3: > > [image: image.png] > > Fig 4: > > [image: image.png] > > > > include <BOSL2-master/std.scad> > include <BOSL2-master/transforms.scad> > > clip_width = 10; > clip_height = 30; > clip_thickness = 2; // Thickness of the 'spring' part > hook_height = 10; > hook_depth = 2.5; > hook_press_length = 7; > hook_fillet_radius = 1; > > hook_clearance = 0.2; // Distance to keep between parts that should fit > into each other snugly but without friction. > > base_depth = 7; > base_width = 20; > base_height = 10; > > side_clip_distance = 1; // Distance between the clip and the stems next to > it. > > female_wall_thickness = 2; > female_play = 0.2; > > // Calculated variables > side_width = (base_width - clip_width - (2 * side_clip_distance)) / 2; > // This is the width of the stems on the left and right of the clip > > // Copied from OpenSCAD manual for offset(), but there, the r/-r are > swapped and that version doesn't work. > module fillet_2d_shape(r) { > offset(r = r) { > offset(delta = -r) { > children(); > } > } > } > > module hook2(extra_clearance) { > up(base_height) xrot(90) yrot(90) > union() { > linear_extrude(clip_width + (2 * extra_clearance), > center=false) > union() { > //p1 = [0, 0]; > //p2 = [clip_thickness, 0]; > p2 = [clip_thickness, clip_height - hook_height - > hook_press_length]; > p3 = [clip_thickness, clip_height]; > p4 = [0, clip_height]; > p5 = [-hook_depth, clip_height - hook_height]; > p6 = [-hook_depth, clip_height - hook_height - > hook_press_length]; > p7 = [0, clip_height - hook_height - > hook_press_length]; > fillet_2d_shape(hook_fillet_radius) > polygon(points = [ p2, p3, p4, p5, p6, p7 ]); > square([clip_thickness, clip_height - hook_height]); > }; > > up(clip_width / 2) right(clip_thickness) > fillet(clip_width, base_depth - clip_thickness, orient=UP); > } > } > > module frame(extra_clearance) { > cube([base_width + (2 * extra_clearance), base_depth + (2 * > extra_clearance), base_height + extra_clearance]); > > // Sides > up(base_height) > cube([side_width, base_depth + (2 * extra_clearance), clip_height > + extra_clearance]); > up(base_height) right(base_width - side_width + (2 * extra_clearance)) > cube([side_width, base_depth + (2 * extra_clearance), clip_height > + extra_clearance]); > } > > module snap_fit_male(extra_clearance) { > frame(extra_clearance); > > right(side_width + side_clip_distance) > hook2(extra_clearance); > } > > module snap_fit_female() { > difference() { > total_female_width = base_width + (2 * female_wall_thickness) + (2 > * hook_clearance); > > cube([ total_female_width, > base_depth + (2 * female_wall_thickness) + (2 * > hook_clearance), > base_height + clip_height + female_wall_thickness]); > > // Render the male part with slight clearance, so that it fits > less loose. > right(female_wall_thickness + hook_clearance) > back(female_wall_thickness + hook_clearance) > union() { > hull() > frame(hook_clearance); > snap_fit_male(hook_clearance); > } > > // Cut an extra 'groove' on the backside, so that the clip (when > it slides in) has some more room to be pressed > // down into the female enclosure. > > groove_width = clip_width + (side_clip_distance * 2); > groove_depth = 1; > groove_length = clip_height; > back(base_depth + hook_clearance + female_wall_thickness) > right((total_female_width / 2) - (groove_width / 2)) up(groove_depth) > #cube([groove_width, groove_depth, groove_length]); > > // Chamfer the front inside a little bit, so the clip can slide in > more easily. > chamfer_angle = 60; > //sin(20) = x / female_wall_thickness > y_offset = sin(chamfer_angle) * female_wall_thickness; > z_offset = cos(chamfer_angle) * female_wall_thickness; > back(y_offset + (female_wall_thickness / 2)) down(z_offset) > xrot(chamfer_angle) right((total_female_width / 2) - > (groove_width / 2)) back() > #cube([groove_width, female_wall_thickness * 2, > female_wall_thickness]); > } > } > > snap_fit_male(0); > > right(50) > snap_fit_female(); > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >