omdl  v0.9.8
OpenSCAD Mechanical Design Library
clamps.scad
Go to the documentation of this file.
1 //! Clamps, bushings, and grips for wires and hoses.
2 /***************************************************************************//**
3  \file
4  \author Roy Allen Sutton
5  \date 2025
6 
7  \copyright
8 
9  This file is part of [omdl] (https://github.com/royasutton/omdl),
10  an OpenSCAD mechanical design library.
11 
12  The \em omdl is free software; you can redistribute it and/or modify
13  it under the terms of the [GNU Lesser General Public License]
14  (http://www.gnu.org/licenses/lgpl.html) as published by the Free
15  Software Foundation; either version 2.1 of the License, or (at
16  your option) any later version.
17 
18  The \em omdl is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  Lesser General Public License for more details.
22 
23  You should have received a copy of the GNU Lesser General Public
24  License along with the \em omdl; if not, write to the Free Software
25  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26  02110-1301, USA; or see <http://www.gnu.org/licenses/>.
27 
28  \details
29 
30  \amu_define group_name (Clamps)
31  \amu_define group_brief (Clamps, bushings, and grips for wires and hoses.)
32 
33  \amu_include (include/amu/pgid_path_pstem_pg.amu)
34 *******************************************************************************/
35 
36 //----------------------------------------------------------------------------//
37 // group and macros.
38 //----------------------------------------------------------------------------//
39 
40 /***************************************************************************//**
41  \amu_include (include/amu/group_in_parent_start.amu)
42  \amu_define includes_required_add
43  (
44  models/3d/fastener/screws.scad
45  )
46  \amu_include (include/amu/includes_required.amu)
47 *******************************************************************************/
48 
49 //----------------------------------------------------------------------------//
50 
51 //! A clamp, bushing, and/or grip for wire/hose wall penetrations.
52 /***************************************************************************//**
53  \param size <decimal-list-2 | decimal> wire size; a list [w, h]
54  or a single decimal to set the wire diameter.
55 
56  \param clamp <datastruct | integer> screw clamp; structured data
57  or a single integer to set the clamp wall side {0|1}.
58 
59  \param cone <datastruct | integer> bushing cone; structured data
60  or a single integer to set the cone wall side {0|1}.
61 
62  \param grip <datastruct | integer> zip tie grip; structured data
63  or a single integer to set the grip wall side {0|1}.
64 
65  \param wth <decimal> wall thickness.
66 
67  \param gap <decimal> wire/hose gap percentage.
68 
69  \param mode <integer> operation mode {0=hole, 1=part-a, 2=part-b,
70  3=parts-a and b}.
71 
72  \details
73 
74  Construct a clamp, cone bushing, and/or a grip as a stand alone
75  part or as a wall penetration hole finish that can secure or
76  provide strain relief for passing wires and/or hoses. The
77  penetration can be circular or rectangular dependent on the size
78  specification.
79 
80  ## Multi-value and structured parameters
81 
82  ### clamp
83 
84  #### Data structure fields: clamp
85 
86  e | data type | default value | parameter description
87  ---:|:-----------------:|:-----------------:|:------------------------------------
88  0 | <integer-list-2 \| integer> | required | wall side
89  1 | <decimal> | wire height | base height
90  2 | <datastruct \| decimal> | (see below) | screw bore
91  3 | <decimal> | d*3 | clamp depth
92  4 | <decimal-list-2 \| decimal> | 15 | pinch bar size
93 
94  ##### clamp[0]: wall side
95 
96  The clamp can be placed on either side of the wall by assigning \b
97  0 or \b 1. To place a clamp on both sides of the wall, assign the
98  value list <b>[0, 1]</b>.
99 
100  ##### clamp[2]: screw bore
101 
102  e | data type | default value | parameter description
103  ---:|:-----------------:|:-----------------:|:------------------------------------
104  0 | <decimal> | max(size)/4 | \p d : bore diameter
105  1 | <decimal> | base height | \p l : bore length
106  2 | (see below) | [d*2, d/3, d/3] | \p h : screw head
107  3 | (see below) | \b undef | \p n : screw nut
108  4 | (see below) | \b undef | \p s : nut slot cutout
109 
110  See screw_bore() for documentation of the data types for the screw
111  bore parameters \p h, \p n, and \p s.
112 
113  ##### clamp[4]: pinch bar size
114 
115  The pinch bar size, [h, w], is specified as a percentage of the
116  penetration size height and the clamp depth. When a single decimal
117  is specified, the height and width percentage are the same.
118 
119  ### cone
120 
121  e | data type | default value | parameter description
122  ---:|:-----------------:|:-----------------:|:------------------------------------
123  0 | <integer-list-2 \| integer> | required| wall side
124  1 | <decimal> | max(size)/2 | cone base width
125  2 | <decimal> | max(size)/3 | cone height
126 
127  ##### cone[0]: wall side
128 
129  The cone can be placed on either side of the wall by assigning \b 0
130  or \b 1. To place a cone on both sides of the wall, assign the
131  value list <b>[0, 1]</b>.
132 
133  ### grip
134 
135  e | data type | default value | parameter description
136  ---:|:-----------------:|:-----------------:|:------------------------------------
137  0 | <integer-list-2 \| integer> | required| wall side
138  1 | <decimal> | max(size)/2 | zip tie width
139  2 | <decimal> | max(size)/6 | zip tie height
140  3 | <decimal> | max(size)*3/7 | grip base width
141  4 | <decimal> | max(size)*3/2 | grip height
142  5 | <integer> | 4 | cut count
143  6 | <decimal> | 4/5 | cut height fraction
144  7 | <decimal> | min(size)/5 | cut width
145  8 | <decimal> | 0 | cut rotational offset
146 
147  ##### grip[0]: wall side
148 
149  The grip can be placed on either side of the wall by assigning \b 0
150  or \b 1. To place a grip on both sides of the wall, assign the
151  value list <b>[0, 1]</b>.
152 
153  \amu_define scope_id (example_clamp)
154  \amu_define title (Clamp example)
155  \amu_define image_views (top back diag)
156  \amu_define image_size (sxga)
157 
158  \amu_include (include/amu/scope_diagrams_3d.amu)
159 
160  \amu_define scope_id (example_cone)
161  \amu_define title (Cone example)
162  \amu_define image_views (top back diag)
163  \amu_define image_size (sxga)
164 
165  \amu_include (include/amu/scope_diagrams_3d.amu)
166 
167  \amu_define scope_id (example_grip)
168  \amu_define title (Grip example)
169  \amu_define image_views (top back diag)
170  \amu_define image_size (sxga)
171 
172  \amu_include (include/amu/scope_diagrams_3d.amu)
173 *******************************************************************************/
174 module clamp_cg
175 (
176  size,
177 
178  clamp,
179  cone,
180  grip,
181 
182  wth = 0,
183  gap = 10,
184 
185  mode
186 )
187 {
188  //
189  // hole
190  //
191 
192  sw = defined_e_or(size, 0, size);
193  sh = defined_e_or(size, 1, sw);
194 
195  ww = sw * (1 + gap/100);
196  wh = sh * (1 + gap/100);
197 
198  wmax = max([ww, wh]);
199  wmin = min([ww, wh]);
200 
201  // type; 0=circle, 1=rectangle
202  wt = is_list(size) && (len(size) > 1) ? 1 : 0;
203 
204  wr = (wt == 0) ? ww/2 : wmin/4;
205  wl = (wt == 0) ? undef : [ww-wr*2, wh-wr*2];
206 
207  //
208  // removals
209  //
210 
211  if (mode == 0)
212  {
213  // hole passage
214  hull()
215  extrude_rotate_trl(l=wl, r=wr)
216  square([eps, wth+eps*8], center=true);
217  }
218 
219  else
220 
221  //
222  // additions
223  //
224 
225  {
226  // clamp
227  if ( is_defined(clamp) )
228  {
229  s = defined_e_or(clamp, 0, clamp); // wall side
230 
231  bh = defined_e_or(clamp, 1, wh); // base height
232  sb = defined_e_or(clamp, 2, wmax/4); // (1) screw bore
233 
234  // (1) screw bore: d, l, h, n, s
235  // * see screw_bore()
236  sbd = defined_e_or(sb, 0, sb);
237  sbl = defined_e_or(sb, 1, bh);
238  sbh = defined_e_or(sb, 2, [sbd*2, sbd/3, sbd/3]);
239  sbn = defined_e_or(sb, 3, undef);
240  sbs = defined_e_or(sb, 4, undef);
241 
242  cd = defined_e_or(clamp, 3, sbd*3); // clamp depth
243  pb = defined_e_or(clamp, 4, 15); // (2) pinch bar
244 
245  // (2) pinch bar: percentage of wire height and clamp depth [height, width]
246  php = defined_e_or(pb, 0, pb);
247  pwp = defined_e_or(pb, 1, php);
248 
249  pbh = php * wh / 100; // pinch bar height
250  pbw = pwp * cd / 100; // pinch bar width
251 
252  wsw = ww/2 * (1+5/10); // saddle width
253  ssw = cd; // screw bore shoulder width
254 
255  // clamp base
256  h_bp =
257  [
258  [0, -bh],
259  [wsw + ssw, -bh],
260  [wsw + ssw, -wh/2],
261  [wsw, -wh/2],
262  [wsw, 0],
263  ];
264 
265  h_bvr = [1, 1/2, 0, 1] * wmin/4;
266  h_bvrm = [1, 1, 0, 1];
267 
268  bp = concat( [for (i=h_bp) i], [for (i=reverse(h_bp)) [-i.x, i.y]] );
269  bvr = concat( [for (i=h_bvr) i], [for (i=reverse(h_bvr)) i] );
270  bvrm = concat( [for (i=h_bvrm) i], [for (i=reverse(h_bvrm)) i] );
271 
272  bpr = polygon_round_eve_all_p(bp, bvr, bvrm);
273 
274  // clamp strap
275  h_sp =
276  [
277  [0, -wh/2],
278  [wsw + ssw, -wh/2],
279  [wsw + ssw, wh/2],
280  [wsw, wh/2],
281  [wsw, wh],
282  ];
283 
284  h_svr = [1, 1/2, 1/2, 1] * wmin/4;
285  h_svrm = [5, 1, 1, 1];
286 
287  sp = concat( [for (i=h_sp) i], [for (i=reverse(h_sp)) [-i.x, i.y]] );
288  svr = concat( [for (i=h_svr) i], [for (i=reverse(h_svr)) i] );
289  svrm = concat( [for (i=h_svrm) i], [for (i=reverse(h_svrm)) i] );
290 
291  spr = polygon_round_eve_all_p(sp, svr, svrm);
292 
293  for (s = is_list(s) ? s : [s])
294  rotate([0, s * 180, 0])
295  translate([0, 0, cd/2 + wth/2])
296  union()
297  {
298  difference()
299  {
300  union()
301  {
302  // clamp strap
303  if ( binary_bit_is(mode, 1, 1) )
304  difference()
305  {
306  extrude_linear_mss( h=cd, center=true )
307  polygon(spr);
308 
309  translate([0, wh*(gap/100), 0])
310  scale([1+(gap/200), 1, 1+eps*4])
311  extrude_linear_mss( h=cd, center=true )
312  polygon(bpr);
313  }
314 
315  // clamp base
316  if ( binary_bit_is(mode, 0, 1) )
317  extrude_linear_mss( h=cd, center=true )
318  polygon(bpr);
319  }
320 
321  // remove hole
322  clamp_cg(size=size, wth=cd+eps*8, mode=0);
323 
324  // bore screws
325  for (x = [-1, 1] )
326  translate([x * (wsw + ssw/2), wh/2, 0])
327  rotate([270, 0, 0])
328  screw_bore(d=sbd, l=sbl +wh/2 + eps*8, h=sbh, n=sbn, s=sbs, a=1);
329  }
330 
331  // add strap pinch bars
332  if ( binary_bit_is(mode, 1, 1) )
333  for (i = [-1, 1] )
334  translate([0, +wh/2, i * (cd/2-pbw)])
335  rotate([0, 90, 0])
336  extrude_linear_mss( h=ww, center=true )
337  rhombus( [pbw, pbh*2], center=true);
338 
339  // add base pinch bar
340  if ( binary_bit_is(mode, 0, 1) )
341  translate([0, -wh/2, 0])
342  rotate([0, 90, 0])
343  extrude_linear_mss( h=ww, center=true )
344  rhombus( [pbw, pbh*2], center=true);
345  }
346  }
347 
348  // cone
349  if ( is_defined(cone) )
350  {
351  s = defined_e_or(cone, 0, cone);
352  w = defined_e_or(cone, 1, wmax/2);
353  h = defined_e_or(cone, 2, wmax/3);
354 
355  p =
356  [
357  origin2d,
358  [w, 0],
359  [w/3, h],
360  [0, h]
361  ];
362 
363  vr = [3, 1, 1, 0] * min([w, h])/4;
364  vrm = [3, 1, 1, 0];
365 
366  pr = polygon_round_eve_all_p(p, vr, vrm);
367 
368  for (s = is_list(s) ? s : [s])
369  rotate([0, s * 180, 0])
370  translate([0, 0, wth/2])
371  extrude_rotate_trl(l=wl, r=wr)
372  polygon(pr);
373  }
374 
375  // grip
376  if ( is_defined(grip) )
377  {
378  s = defined_e_or(grip, 0, grip);
379 
380  zw = defined_e_or(grip, 1, wmax/2);
381  zh = defined_e_or(grip, 2, wmax/6);
382 
383  w = defined_e_or(grip, 3, wmax*3/7);
384  h = defined_e_or(grip, 4, wmax*3/2);
385 
386  cn = defined_e_or(grip, 5, 4);
387  cf = defined_e_or(grip, 6, 4/5);
388  ct = defined_e_or(grip, 7, wmin/5);
389  co = defined_e_or(grip, 8, 0);
390 
391  p =
392  let
393  (
394  o = h-h/5, // offset from top
395  q = zh // zip-tie grove slant
396  )
397  [
398  origin2d,
399  [w, 0],
400  [w, o-zw-q],
401  [w-zh, o-zw],
402  [w-zh, o],
403  [w, o+q],
404  [w, h],
405  [0, h],
406 
407  [0, o], // tooth
408  [-zh/4, o-zw/2],
409  [0, o-zw]
410  ];
411 
412  vr = [3, 1, 0, 0, 1, 1, 1, 0] * min([w, h])/4;
413  vrm = [3, 1, 0, 0, 1, 1, 1, 0];
414 
415  pr = polygon_round_eve_all_p(p, vr, vrm);
416 
417  for (s = is_list(s) ? s : [s])
418  rotate([0, s * 180, 0])
419  difference()
420  {
421  translate([0, 0, wth/2])
422  extrude_rotate_trl(l=wl, r=wr)
423  polygon(pr);
424 
425  cw = wmax/2 + w*2;
426  ch = h*cf;
427 
428  repeat_radial(cn, o=co)
429  translate([cw/2, 0, wth/2 + h - ch/2])
430  cube([cw, ct, ch + eps*4], center=true);
431  }
432  }
433  }
434 }
435 
436 //! @}
437 //! @}
438 
439 
440 //----------------------------------------------------------------------------//
441 // openscad-amu auxiliary scripts
442 //----------------------------------------------------------------------------//
443 
444 /*
445 BEGIN_SCOPE example_clamp;
446  BEGIN_OPENSCAD;
447  include <omdl-base.scad>;
448  include <models/3d/fastener/screws.scad>;
449  include <parts/3d/enclosure/clamps.scad>;
450 
451  $fn = 36;
452 
453  d = 7.00;
454 
455  head = undef;
456  nut = [3.5, 1.5, 0, 4, 45, 1.25];
457  slot = [undef, -3];
458  bore = [3, undef, head, nut, slot];
459 
460  clamp_cg(size=d, clamp=[0, undef, bore], mode=3);
461 
462  // end_include
463  END_OPENSCAD;
464 
465  BEGIN_MFSCRIPT;
466  include --path "${INCLUDE_PATH}" {var_init,var_gen_png2eps}.mfs;
467  table_unset_all sizes;
468 
469  images name "sizes" types "sxga";
470  views name "views" views "top back diag";
471 
472  variables set_opts_combine "sizes views";
473  variables add_opts "--viewall --autocenter --view=axes";
474 
475  include --path "${INCLUDE_PATH}" scr_make_mf.mfs;
476  END_MFSCRIPT;
477 END_SCOPE;
478 
479 BEGIN_SCOPE example_cone;
480  BEGIN_OPENSCAD;
481  include <omdl-base.scad>;
482  include <models/3d/fastener/screws.scad>;
483  include <parts/3d/enclosure/clamps.scad>;
484 
485  $fn = 36;
486 
487  w = 2;
488  d = 7.00;
489  difference()
490  {
491  translate(-[d*2,d*2,w/2]) cube([d*4,d*4,w]);
492  clamp_cg(size=d, wth=w, mode=0);
493  }
494  clamp_cg(size=d, cone=[[0, 1]], mode=1);
495 
496  // end_include
497  END_OPENSCAD;
498 
499  BEGIN_MFSCRIPT;
500  include --path "${INCLUDE_PATH}" {var_init,var_gen_png2eps}.mfs;
501  table_unset_all sizes;
502 
503  images name "sizes" types "sxga";
504  views name "views" views "top back diag";
505 
506  variables set_opts_combine "sizes views";
507  variables add_opts "--viewall --autocenter --view=axes";
508 
509  include --path "${INCLUDE_PATH}" scr_make_mf.mfs;
510  END_MFSCRIPT;
511 END_SCOPE;
512 
513 BEGIN_SCOPE example_grip;
514  BEGIN_OPENSCAD;
515  include <omdl-base.scad>;
516  include <models/3d/fastener/screws.scad>;
517  include <parts/3d/enclosure/clamps.scad>;
518 
519  $fn = 36;
520 
521  w = 2;
522  d = [7.00, 3.50];
523  e = max(d);
524  difference()
525  {
526  translate(-[e*2,e*2,w/2]) cube([e*4,e*4,w]);
527  clamp_cg(size=d, wth=w, mode=0);
528  }
529  clamp_cg(size=d, grip=0, mode=1);
530 
531  // end_include
532  END_OPENSCAD;
533 
534  BEGIN_MFSCRIPT;
535  include --path "${INCLUDE_PATH}" {var_init,var_gen_png2eps}.mfs;
536  table_unset_all sizes;
537 
538  images name "sizes" types "sxga";
539  views name "views" views "top back diag";
540 
541  variables set_opts_combine "sizes views";
542  variables add_opts "--viewall --autocenter --view=axes";
543 
544  include --path "${INCLUDE_PATH}" scr_make_mf.mfs;
545  END_MFSCRIPT;
546 END_SCOPE;
547 */
548 
549 //----------------------------------------------------------------------------//
550 // end of file
551 //----------------------------------------------------------------------------//
552 
origin2d
<point-2d> The origin point coordinate in 2d Euclidean space.
Definition: constants.scad:407
eps
<decimal> Epsilon, small distance to deal with overlapping shapes.
Definition: constants.scad:195
function binary_bit_is(v, b, t=1)
Test if a binary bit position of an integer value equals a test bit.
function defined_e_or(v, i, d)
Return an element of an iterable when it exists or a default value otherwise.
function reverse(v)
Reverse the elements of an iterable value.
function is_defined(v)
Test if a value is defined.
function polygon_round_eve_all_p(c, vr=0, vrm=1, vfn, w=true, cw=true)
Compute coordinates that round all of the vertices between each adjacent edges in 2D.
module screw_bore(d=1, l=1, h, n, t, s, f, a)
Flat and beveled-head fastener bore with nut, nut slot, and bore tolerance.
Definition: screws.scad:358
module clamp_cg(size, clamp, cone, grip, wth=0, gap=10, mode)
A clamp, bushing, and/or grip for wire/hose wall penetrations.
Definition: clamps.scad:743
module rhombus(size, vr, center=false)
A rhombus.
Definition: basic_2d.scad:665
module cone(r=1, h, d, vr)
A cone.
Definition: basic_3d.scad:461
module extrude_linear_mss(h, center=false, c=true)
Linearly extrude a 2d shape with multi-segment uniformly-spaced profile scaling.
Definition: extrude.scad:748
module extrude_rotate_trl(r, pa=0, ra=360, l, m=255)
Translate, rotate, and revolve a 2d shape about the z-axis with linear elongation.
Definition: extrude.scad:562
module repeat_radial(n, r=1, o=0, angle=true, move=false)
Radially repeat copies of child objects about a z-axis radius.
Definition: repeat.scad:462