omdl  v0.9.5
OpenSCAD Mechanical Design Library
operation.scad
Go to the documentation of this file.
1 //! Drafting tools and general operations.
2 /***************************************************************************//**
3  \file
4  \author Roy Allen Sutton
5  \date 2019-2023
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 (Operations)
31  \amu_define group_brief (Drafting tools and general operations.)
32 
33  \amu_include (include/amu/pgid_path_pstem_g.amu)
34 *******************************************************************************/
35 
36 //----------------------------------------------------------------------------//
37 // group and macros.
38 //----------------------------------------------------------------------------//
39 
40 /***************************************************************************//**
41  \amu_include (include/amu/group_in_parent_start.amu)
42 
43  \amu_include (include/amu/scope_diagram_2d_object.amu)
44 *******************************************************************************/
45 
46 //----------------------------------------------------------------------------//
47 
48 //----------------------------------------------------------------------------//
49 
50 //! \name Layers
51 //! @{
52 
53 //! Assign one or more layers to child objects.
54 /***************************************************************************//**
55  \param layers <string-list> The List of drafting layer names.
56 
57  \details
58 
59  All children will be assigned the specified layer or layers and
60  will be subsequently shown only when one of these layers are active
61  as indicated by \ref draft_layers_show.
62 *******************************************************************************/
63 module draft_in_layers
64 (
65  layers = draft_get_config("layers-default")
66 )
67 {
68  if (draft_layers_any_active(layers))
69  children();
70 }
71 
72 //! @}
73 
74 //----------------------------------------------------------------------------//
75 
76 //! \name Placement
77 //! @{
78 
79 //! Move one or more child objects to sheet a reference zone.
80 /***************************************************************************//**
81  \param list <datastruct-list> A List alignment references, zones,
82  and child object indexes.
83 
84  \details
85 
86  Each list element specified the placement of a child object and has
87  the form:
88 
89  \verbatim
90  <datastruct> = [ 0:<alignment-point>, 1:<zone-reference>, 2:<child-index> ]
91  \endverbatim
92 
93  field | description | data type
94  :------:|-----------------------|:--------------------------
95  0 | [px, py] | <decimal-list-2>
96  1 | [rx, ry] or [ix, iy] | <string-list-2 \| decimal-list-2>
97  2 | index | <integer>
98 
99  \amu_eval ( html_image_w=512 latex_image_w="3.00in" object=draft_move ${object_diagram_2d} )
100 
101  \sa draft_sheet_get_zone()
102 *******************************************************************************/
103 module draft_move
104 (
105  list
106 )
107 {
108  // do nothing when no children
109  if ( $children )
110  for ( i = [0:max($children-1, len(list)-1)] )
111  {
112  e = list[i];
113 
114  // default alignment
115  p = defined_or(e[0], [0, 0]);
116 
117  // numerical or string references
118  n = all_numbers(e[1]) ? e[1] : [undef, undef];
119  s = all_strings(e[1]) ? e[1] : [undef, undef];;
120 
121  // child index default
122  c = defined_or(e[2], i);
123 
124  translate
125  (
127  (
128  rx=s[0], ry=s[1],
129  ix=n[0], iy=n[1],
130  zp=p,
131  frame=false, window=false
132  )
133  )
134  children(c);
135  }
136 }
137 
138 //! @}
139 
140 //----------------------------------------------------------------------------//
141 
142 //! \name Sheet
143 //! @{
144 
145 //! Construct a drafting sheet with frame, zone, grid, and origin.
146 /***************************************************************************//**
147  \param sheet <value-list-2> A sheet line configuration that
148  overrides sheet line <width, [style]>.
149  \param frame <value-list-2> A frame line configuration that
150  overrides frame line <width, [style]>.
151  \param zone <value-list-2> A zone line configuration that
152  overrides zone line <width, [style]>.
153  \param grid <value-list-2> A grid line configuration that
154  overrides grid line <width, [style]>.
155  \param origin <value-list-4> An origin line configuration that
156  overrides origin line <width, [style], length, [arrow]>.
157 
158  \param check <boolean> Check current sheet configuration.
159 
160  \param layers <string-list> The List of drafting layer names.
161 
162  \details
163 
164  When a parameter is not specified, the default value is use for the
165  current sheet configuration. The sheet configuration defaults are
166  set by \ref draft_sheet_config.
167 
168  The parameters \p sheet, \p frame, \p zone, \p and grid accepts a
169  list of two values. The first value sets the construction line
170  width and the second sets the construction line style; <width,
171  style>. The style value may also be a list to configure the details
172  of the style as documented in draft_line(). The parameter \p origin
173  accepts a list of four values: <width, style, length, arrow>. The
174  style may be any of those available in draft_line() and the arrow
175  may be any available in draft_arrow().
176 
177  \amu_eval ( html_image_w=512 latex_image_w="3.00in" object=draft_sheet ${object_diagram_2d} )
178 
179  [style]: \ref draft_line()
180  [arrow]: \ref draft_arrow()
181 *******************************************************************************/
182 module draft_sheet
183 (
184  sheet,
185  frame,
186  zone,
187  grid,
188  origin,
189  check = false,
190  layers = draft_get_config("layers-sheet")
191 )
192 {
193  assert
194  (
195  table_exists( r=draft_sheet_config_tr, ri=draft_sheet_config ),
196  str("unknown sheet configuration [", draft_sheet_config, "]")
197  );
198 
199  if (draft_layers_any_active(layers))
201  {
202  // check tables
203  if ( check )
204  {
205  table_check( r=draft_sheet_config_tr, c=draft_sheet_config_tc );
206  table_check( r=draft_sheet_size_tr, c=draft_sheet_size_tc );
207  }
208 
209  //
210  // get configuration values (scale all lengths)
211  //
212 
213  // sheet size
214  sdx = draft_get_sheet_size(ci="sdx") * draft_sheet_scale;
215  sdy = draft_get_sheet_size(ci="sdy") * draft_sheet_scale;
216 
217  // sheet layout
218  sll = draft_get_sheet_config(ci="sll");
219 
220  // sheet frame and zone margins
221  smx = draft_get_sheet_config(ci="smx") * draft_sheet_scale;
222  smy = draft_get_sheet_config(ci="smy") * draft_sheet_scale;
223  szm = draft_get_sheet_config(ci="szm") * draft_sheet_scale;
224 
225  // reference zone labels
226  zox = draft_get_sheet_config(ci="zox");
227  zoy = draft_get_sheet_config(ci="zoy");
228  zlx = draft_get_sheet_config(ci="zlx");
229  zly = draft_get_sheet_config(ci="zly");
230  zrf = draft_get_sheet_config(ci="zrf");
231  zfs = draft_get_sheet_config(ci="zfs");
232 
233  // sheet, frame, zone, grid, and origin line configuration
234  slc = draft_get_sheet_config(ci="slc");
235  flc = draft_get_sheet_config(ci="flc");
236  zlc = draft_get_sheet_config(ci="zlc");
237  glc = draft_get_sheet_config(ci="glc");
238  olc = draft_get_sheet_config(ci="olc");
239 
240  // set draft scale for sheet
242 
243  //
244  // derived values
245  //
246 
247  // sheet layout dimensions
248  ldx = sll ? sdy : sdx;
249  ldy = sll ? sdx : sdy;
250 
251  // sheet frame dimensions
252  fdx = ldx - smx;
253  fdy = ldy - smy;
254 
255  //
256  // sheet layout
257  //
258  sheet_w = defined_e_or(defined_or(sheet, slc), 0, defined_or(sheet, slc));
259  if ( sheet_w )
260  {
261  sheet_s = defined_e_or(defined_or(sheet, slc), 1, 4);
262 
263  // layout
264  draft_rectangle( d=[ldx, ldy], w=sheet_w, s=sheet_s );
265  }
266 
267  //
268  // sheet frame
269  //
270  frame_w = defined_e_or(defined_or(frame, flc), 0, defined_or(frame, flc));
271  if ( frame_w )
272  {
273  frame_s = defined_e_or(defined_or(frame, flc), 1, 1);
274 
275  // frame
276  draft_rectangle( d=[fdx, fdy], w=frame_w, s=frame_s );
277  }
278 
279  //
280  // zone reference
281  //
282  zone_w = defined_e_or(defined_or(zone, zlc), 0, defined_or(zone, zlc));
283  if ( zone_w )
284  {
285  zone_s = defined_e_or(defined_or(zone, zlc), 1, 1);
286 
287  // zone frame
288  draft_rectangle( d=[fdx, fdy]-2*[szm, szm], w=zone_w, s=zone_s );
289 
290  // zone x-grid and references
291  for ( ix = [0:len(zlx)-1], iyo = [1,-1] )
292  {
293  x = ix * fdx/len(zlx) - fdx/2;
294  yo = iyo * (fdy/2 - szm/2);
295 
296  if (ix > 0)
297  draft_line( l=[ [x, yo-szm/2], [x, yo+szm/2] ], w=zone_w, s=zone_s );
298 
299  zlt = (zox > 0) ? zlx[ix] : zlx[len(zlx)-1-ix];
300  translate( [x + fdx/len(zlx)/2, yo] )
301  text(zlt, font=zrf, size=szm*zfs, halign="center", valign="center");
302  }
303 
304  // zone y-grid and references
305  for ( iy = [0:len(zly)-1], ixo = [1,-1] )
306  {
307  y = iy * fdy/len(zly) - fdy/2;
308  xo = ixo * (fdx/2 - szm/2);
309 
310  if (iy > 0)
311  draft_line( l=[ [xo-szm/2, y], [xo+szm/2, y] ], w=zone_w, s=zone_s );
312 
313  zlt = (zoy > 0) ? zly[iy] : zly[len(zly)-1-iy];
314  translate( [xo, y + fdy/len(zly)/2] )
315  text(zlt, font=zrf, size=szm*zfs, halign="center", valign="center");
316  }
317  }
318 
319  //
320  // field grid
321  //
322  grid_w = defined_e_or(defined_or(grid, glc), 0, defined_or(grid, glc));
323  if ( grid_w )
324  {
325  grid_s = defined_e_or(defined_or(grid, glc), 1, 2);
326 
327  // x-grid
328  for ( ix = [1:len(zlx)-1], iyo = [1,-1] )
329  {
330  x = ix * fdx/len(zlx) - fdx/2;
331  draft_line( l=[ [x, -fdy/2], [x, fdy/2] ], w=grid_w, s=grid_s );
332  }
333  // y-grid
334  for ( iy = [1:len(zly)-1], ixo = [1,-1] )
335  {
336  y = iy * fdy/len(zly) - fdy/2;
337  draft_line( l=[ [-fdx/2, y], [fdx/2, y] ], w=grid_w, s=grid_s );
338  }
339  }
340 
341  //
342  // origin tics
343  //
344  origin_w = defined_e_or(defined_or(origin, olc), 0, defined_or(origin, olc));
345  if ( origin_w )
346  {
347  origin_s = defined_e_or(defined_or(origin, olc), 1, 1); // line style
348  origin_l = defined_e_or(defined_or(origin, olc), 2, 1); // length factor
349  origin_a = defined_e_or(defined_or(origin, olc), 3, 1); // arrow style
350 
351  // x-origin
352  for ( ix = [1,-1] )
353  draft_line
354  (
355  l=ix*[[fdx/2-szm, 0], [fdx/2-szm*origin_l, 0]],
356  w=origin_w, s=origin_s, a2=origin_a
357  );
358 
359  // y-origin
360  for ( iy = [1,-1] )
361  draft_line
362  (
363  l=iy*[[0, fdy/2-szm], [0, fdy/2-szm*origin_l]],
364  w=origin_w, s=origin_s, a2=origin_a
365  );
366  }
367  }
368 }
369 
370 //! Construct drafting sheet axes.
371 /***************************************************************************//**
372  \param size <decimal-list-2-list-2|decimal-list-2|decimal>
373  An optional list [[-x, +x], [-y, +y]] or [-x/y, +x/y] of
374  decimals or a single decimal for (-+x=-+y). The x and y
375  negative and positive axes lengths.
376 
377  \param w <decimal-list-2 | decimal> A list [-w, +w] or a single
378  decimal for (-w=+w). The negative and positive axes segment
379  weights.
380  \param s <integer-list-2-list|integer-list-2|integer> A list
381  [-[s], +[s]] or [-s, +s] of integers or a single integer
382  for (-s=+s). The negative and positive axes [styles].
383  \param a <integer-list-2-list|integer-list-2|integer> A list
384  [-[a], +[a]] or [-a, +a] of integers or a single integer
385  for (-a=+a). The negative and positive axes [arrows].
386 
387  \param ts <decimal> The axes label text size.
388 
389  \param layers <string-list> The List of drafting layer names.
390 
391  \details
392 
393  \amu_eval ( html_image_w=384 latex_image_w="2.25in" object=draft_axes ${object_diagram_2d} )
394 
395  When \p size is not specified, the axes will span the entire sheet
396  frame.
397 
398  [styles]: \ref draft_line()
399  [arrows]: \ref draft_arrow()
400 *******************************************************************************/
401 module draft_axes
402 (
403  size,
404 
405  w = 1,
406  s = 2,
407  a = 0,
408 
409  ts = 0,
410 
411  layers = draft_get_config("layers-sheet")
412 )
413 {
414  if (draft_layers_any_active(layers))
416  {
417  axy = is_defined(size) ? size
418  : let
419  (
420  //
421  // use sheet frame when size is not specified.
422  //
423 
424  // sheet size
425  sdx = draft_get_sheet_size(ci="sdx") * draft_sheet_scale,
426  sdy = draft_get_sheet_size(ci="sdy") * draft_sheet_scale,
427 
428  // sheet layout
429  sll = draft_get_sheet_config(ci="sll"),
430 
431  // sheet frame and zone margins
432  smx = draft_get_sheet_config(ci="smx") * draft_sheet_scale,
433  smy = draft_get_sheet_config(ci="smy") * draft_sheet_scale,
434  szm = draft_get_sheet_config(ci="szm") * draft_sheet_scale,
435 
436  //
437  // derived values
438  //
439 
440  // sheet layout dimensions
441  ldx = sll ? sdy : sdx,
442  ldy = sll ? sdx : sdy,
443 
444  // sheet frame dimensions
445  fdx = ldx - smx,
446  fdy = ldy - smy
447  )
448  // sheet frame less zone margins
449  [fdx/2-szm, fdy/2-szm];
450 
451  for (i = [ [x_axis_ci, x_axis2d_uv, "x"], [y_axis_ci, y_axis2d_uv, "y"] ])
452  {
453  li = defined_e_or(axy, first(i), axy);
454 
455  // negative axes
456  ni = defined_e_or(li, 0, li);
457  if ( ni < 0 )
458  draft_line
459  (
460  l = second(i) * ni,
461  s = defined_e_or(s, 0, s),
462  w = defined_e_or(w, 0, w),
463  a2 = defined_e_or(a, 0, a)
464  );
465 
466  // positive axes
467  pi = defined_e_or(li, 1, ni);
468  if ( pi > 0 )
469  {
470  draft_line
471  (
472  l = +second(i) * pi,
473  s = defined_e_or(s, 1, s),
474  w = defined_e_or(w, 1, w),
475  a2 = defined_e_or(a, 1, a)
476  );
477 
478  // labels
479  if ( ts > 0 )
480  {
481  translate(second(i) * pi * (1 + ts/pi))
482  text(third(i), valign="center", halign="center", size=ts);
483  }
484  }
485  }
486  }
487 }
488 
489 //! Construct a drafting sheet ruler.
490 /***************************************************************************//**
491  \param units <string> The ruler units.
492  \param marks <integer> The number of unit marks per group.
493  \param groups <integer> The number of groups.
494 
495  \param mark_size <decimal> The distance between unit marks
496  (in \p units).
497  \param group_height <decimal> The group-line mark height.
498 
499  \param label_scale <decimal> The text label size scaler.
500  \param label_hide <boolean> Hide ruler text label.
501 
502  \param order <integer-list-2 | integer> The ruler marks horizontal
503  and vertical direction. A list [x, y] of decimals or a
504  single decimal for (x=y).
505 
506  \param w <decimal> The line segment weight.
507 
508  \param layers <string-list> The List of drafting layer names.
509 
510  \details
511 
512  \amu_eval ( html_image_w=512 latex_image_w="3.00in" object=draft_ruler ${object_diagram_2d} )
513 *******************************************************************************/
514 module draft_ruler
515 (
516  units = "mm",
517  marks = 10,
518  groups = 5,
519  mark_size = 1,
520  group_height = 5,
521  label_scale = 2/3,
522  label_hide = false,
523  order = 1,
524  w = 1,
525  layers = draft_get_config("layers-sheet")
526 )
527 {
528 
529  if (draft_layers_any_active(layers))
531  {
532  // one mark unit length
533  ul = length(mark_size, units);
534 
535  // group-line mark size
536  s = ul * group_height * $draft_scale;
537 
538  // order
539  ox = defined_e_or(order, 0, order);
540  oy = defined_e_or(order, 1, ox);
541  oo = [ox, oy];
542 
543  // draw marks and group ticks
544  // initial group begins mid-group to avoid 2D ruler crossing
545  for ( i=[marks/2:groups*marks], j=[0, 1] )
546  {
547  p = i * ul * oo[j] * $draft_scale;
548  l = line2d_new
549  (
550  m = (
551  (i%marks == marks/2) ? s*2/3
552  : (i%marks) ? s/2
553  : s
554  ) * oo[(j==0)?1:0],
555  p1 = (j == 0) ? [p, 0] : [0, p],
556  v = (j == 0) ? y_axis2d_uv : x_axis2d_uv
557  );
558 
559  // draft tick
560  draft_line (l=l, w=(i%marks) ? w/2 : w, s=1 );
561 
562  // label measurement
563  if ((i == groups*marks) && !label_hide)
564  {
565  // text offset from group tick
566  offset = ul * $draft_scale;
567 
568  translate
569  (
570  (line_ip(l) + line_tp(l))/2 +
571  (j == 0 ? [offset, 0] : [0, offset])
572  )
573  rotate( (j == 0) ? 0 : 90 )
574  text
575  (
576  str
577  (
578  mark_size * marks * groups * $draft_scale,
579  " ", units
580  ),
581  valign="center", size=s*label_scale
582  );
583  }
584  }
585  }
586 }
587 
588 //! @}
589 
590 //----------------------------------------------------------------------------//
591 
592 //! \name Tables
593 //! @{
594 
595 //! Construct a text table that is populated by rows and columns.
596 /***************************************************************************//**
597  \param map <map> A table definition map.
598  \param fmap <map> A table format map.
599 
600  \param zp <integer-list-2 | integer> The center coordinate scaler. A
601  list [zpx, zpy] of decimals or a single decimal for (zpx=zpy).
602 
603  \param window <boolean> Return table window rectangle.
604 
605  \param layers <string-list> The List of drafting layer names.
606 
607  \details
608 
609  \amu_eval ( html_image_w=256 latex_image_w="1.50in" object=draft_table ${object_diagram_2d} )
610 
611  | see: \ref draft_config_map |
612  |:---------------------------:|
613  | table-text-format |
614 *******************************************************************************/
615 module draft_table
616 (
617  map,
618  fmap,
619  zp = 0,
620  window = false,
621  layers = draft_get_config("layers-table")
622 )
623 {
624  if (draft_layers_any_active(layers))
626  {
627  translate( -draft_table_get_cell(zp=zp, map=map, fmap=fmap) )
628  if (window)
629  { // solid rectangular window
630  polygon(draft_table_get_cell(window=true, map=map, fmap=fmap));
631  }
632  else
633  {
634  //
635  // get table format
636  //
637  cmh = map_get_firstof2_or(map, fmap, "cmh", draft_get_config("table-cmh")) * $draft_scale;
638  cmv = map_get_firstof2_or(map, fmap, "cmv", draft_get_config("table-cmv")) * $draft_scale;
639 
640  coh = map_get_firstof2_or(map, fmap, "coh", draft_get_config("table-coh"));
641  cov = map_get_firstof2_or(map, fmap, "cov", draft_get_config("table-cov"));
642 
643  //
644  // default lines when not in map nor fmap:
645  // no horizontal or vertical lines.
646  //
647  hlines = map_get_firstof2_or(map, fmap, "hlines", draft_get_config("table-hlines"));
648  vlines = map_get_firstof2_or(map, fmap, "vlines", draft_get_config("table-vlines"));
649 
650  //
651  // cell default text format when not in map nor fmap:
652  //
653  tdefs = map_get_firstof2_or(map, fmap, "tdefs", draft_get_config("table-text-format"));
654  hdefs = map_get_firstof2_or(map, fmap, "hdefs", draft_get_config("table-text-format"));
655  edefs = map_get_firstof2_or(map, fmap, "edefs", draft_get_config("table-text-format"));
656 
657  //
658  // get table contents
659  //
660  title = map_get_value(map, "title");
661  heads = map_get_value(map, "heads");
662  cols = map_get_value(map, "cols");
663  rows = map_get_value(map, "rows");
664 
665  // draw hlines
666  for( i=[0:len(rows)+2] )
667  {
668  ic = 0; // from left
669  tc = len(cols); // to right
670 
671  // get line configuration
672  lc = (i == 0) ? hlines[0] // top
673  : (i == len(rows)+2) ? hlines[1] // bottom
674  : (i == 1) ? hlines[2] // title
675  : (i == 2) ? hlines[3] // headings
676  : hlines[4]; // rows
677 
678  //
679  // don't draw title or headings lines when they are
680  // not defined. set line style to '0' no line.
681  //
682  lw = lc[0];
683  ls = (is_undef(title) && (i==1)) ? 0
684  : (is_undef(heads) && (i==2)) ? 0
685  : lc[1];
686 
687  ip = draft_table_get_point( ix=ic, iy=i, map=map, fmap=fmap );
688  tp = draft_table_get_point( ix=tc, iy=i, map=map, fmap=fmap );
689 
690  draft_line (l=[ip, tp], w=lw, s=ls );
691  }
692 
693  // draw vlines
694  for( i=[0:len(cols)] )
695  {
696  ic = (i==0||i==len(cols)) ? 0 : 1; // left & right start at top
697  tc = len(rows)+2; // to bottom of table
698 
699  // get line configuration
700  lc = (i == 0) ? vlines[0] // left
701  : (i == len(cols)) ? vlines[1] // right
702  : vlines[2]; // columns
703 
704  lw = lc[0]; // line weight
705  ls = lc[1]; // line style
706 
707  ip = draft_table_get_point( ix=i, iy=ic, map=map, fmap=fmap );
708  tp = draft_table_get_point( ix=i, iy=tc, map=map, fmap=fmap );
709 
710  draft_line (l=[ip, tp], w=lw, s=ls );
711  }
712 
713  // add title text
714  draft_table_text( 0, 0, title[0], cmh, tdefs, map, fmap );
715 
716  // add heading entries text
717  for ( c = [0:len(cols)-1] )
718  draft_table_text( c, 1, heads[0][c], cmh/2, hdefs, map, fmap );
719 
720  // add cell entries text
721  for ( r = [2:len(rows)+1], c = [0:len(cols)-1] )
722  draft_table_text( c, r, rows[r-2][0][c], cmh/2, edefs, map, fmap );
723 
724  } // window
725  } // layers
726 }
727 
728 //! Construct a text table that is populated by predefined zones.
729 /***************************************************************************//**
730  \param text <value-list> The list of zone values, where each value
731  is <string | string-list>, a single or multi-line string for
732  the corresponding zone.
733 
734  \param map <map> A zone table definition map.
735 
736  \param zp <integer-list-2 | integer> The center coordinate scaler. A
737  list [zpx, zpy] of decimals or a single decimal for (zpx=zpy).
738 
739  \param number <boolean> Number the defined table zones.
740  \param window <boolean> Return table window rectangle.
741 
742  \param layers <string-list> The List of drafting layer names.
743 
744  \details
745 
746  \amu_eval ( html_image_w=768 latex_image_w="4.50in" object=draft_ztable ${object_diagram_2d} )
747 *******************************************************************************/
748 module draft_ztable
749 (
750  text,
751  map,
752  zp = 0,
753  number = false,
754  window = false,
755  layers = draft_get_config("layers-table")
756 )
757 {
758  if (draft_layers_any_active(layers))
760  {
761  translate( -draft_ztable_get_zone(zp=zp, map=map) )
762  if (window)
763  { // solid rectangular window
764  polygon(draft_ztable_get_zone(window=true, map=map));
765  }
766  else
767  {
768  // number: zones, hlines, and vlines
769  num_zn = defined_e_or(number, 0, number);
770  num_hl = defined_e_or(number, 1, num_zn);
771  num_vl = defined_e_or(number, 2, num_hl);
772 
773  // get title block configuration
774  cmh = map_get_value(map, "cmh") * $draft_scale;
775  cmv = map_get_value(map, "cmv") * $draft_scale;
776 
777  // coh = map_get_value(map, "coh");
778  cov = map_get_value(map, "cov");
779 
780  hldata = map_get_value(map, "hlines");
781  vldata = map_get_value(map, "vlines");
782 
783  htdefs = map_get_value(map, "hdefs");
784  etdefs = map_get_value(map, "edefs");
785  zddata = map_get_value(map, "zones");
786 
787  lts = cmv/6;
788  tts = cmv/6;
789 
790  // draw hlines
791  for( i=[0:len(hldata)-1] )
792  {
793  ic = hldata[i][1][0]; // start hline
794  tc = hldata[i][1][1]; // end hline
795  lw = hldata[i][2]; // line weight
796  ls = hldata[i][3]; // line style
797 
798  ip = draft_ztable_get_point( ix=ic, iy=i, map=map );
799  tp = draft_ztable_get_point( ix=tc, iy=i, map=map );
800 
801  draft_line (l=[ip, tp], w=lw, s=ls );
802 
803  // number horizontal lines
804  if ( num_hl )
805  {
806  translate(tp + [lts, lts/2, 0])
807  text(str("H", i), size=lts);
808  }
809  }
810 
811  // draw vlines
812  for( i=[0:len(vldata)-1] )
813  {
814  ic = vldata[i][1][0]; // start vline
815  tc = vldata[i][1][1]; // end vline
816  lw = vldata[i][2]; // line weight
817  ls = vldata[i][3]; // line style
818 
819  ip = draft_ztable_get_point( ix=i, iy=ic, map=map );
820  tp = draft_ztable_get_point( ix=i, iy=tc, map=map );
821 
822  draft_line (l=[ip, tp], w=lw, s=ls );
823 
824  // number vertical lines
825  if ( num_vl )
826  {
827  translate(ip - [lts/2, -lts, 0]) rotate(90)
828  text(str("V", i), size=lts);
829  }
830  }
831 
832  // add zone text
833  for( i=[0:len(zddata)-1] )
834  {
835  hidden = zddata[i][2];
836 
837  if ( !zddata[i][2] )
838  {
839  // number zone
840  if ( num_zn )
841  {
842  translate
843  (
844  draft_ztable_get_zone( i=i, zp=[1,1], map=map ) - [1/2, 1] * lts
845  )
846  text ( str( "Z", i ), valign="center", halign="right", size=lts );
847  }
848 
849  // zone heading-text
850  draft_ztable_text( i, zddata[i][3][0], tts, htdefs, zddata[i][3], map );
851 
852  // zone entry-text
853  et = (is_empty(text[i]) || is_undef(text[i])) ?
854  zddata[i][4][0]
855  : text[i];
856 
857  draft_ztable_text( i, et, tts, etdefs, zddata[i][4], map );
858  } // not hidden
859  } // zone text
860  } // window
861  } // layers
862 }
863 
864 //! Construct a text note with optional heading and boarder.
865 /***************************************************************************//**
866  \param head <string> The optional note heading.
867  \param note <string | string-list> A single or multi-line note
868  text string.
869 
870  \param size <decimal-list-3> A list of decimals that define the
871  <width, line-height, heading-height> of the note.
872  \param line <value-list-2> The boarder line configuration override
873  that sets the line construction width and style;
874  <width, [style]>.
875 
876  \param halign <string> The text horizontal alignment. One of the
877  predefined strings: < \b "left" | \b "center" | \b "right" >.
878 
879  \param cmh <decimal> The horizontal width minimum unit cell size.
880  \param cmv <decimal> The vertical height minimum unit cell size.
881 
882  \param zp <integer-list-2 | integer> The center coordinate scaler. A
883  list [zpx, zpy] of decimals or a single decimal for (zpx=zpy).
884 
885  \param window <boolean> Return table window rectangle.
886 
887  \param layers <string-list> The List of drafting layer names.
888 
889  \details
890 
891  The boarder line style value may be configure as as documented in
892  draft_line().
893 
894  \amu_eval ( html_image_w=768 latex_image_w="4.50in" object=draft_note ${object_diagram_2d} )
895 
896  [style]: \ref draft_line()
897 *******************************************************************************/
898 module draft_note
899 (
900  head,
901  note,
902  size,
903  line,
904  halign = "left",
905  cmh = draft_get_config("note-cmh"),
906  cmv = draft_get_config("note-cmv"),
907  zp = 0,
908  window = false,
909  layers = draft_get_config("layers-note")
910 )
911 {
912  if (draft_layers_any_active(layers))
913  // draft_make_3d_if_configured() handled by draft_table()
914  {
915  // default line configuration
916  lnd = defined_or(line, [1, 1]);
917  lnc = is_list(lnd[0]) ? [lnd[0], lnd[1]] : [lnd, lnd];
918 
919  // default heading text when size specified without text
920  htd = is_defined(size[2]) && is_undef(head) ? empty_str : head;
921 
922  // local table map
923  map =
924  [
925  ["cmh", cmh],
926  ["cmv", cmv],
927 
928  is_undef(head) ? empty_lst :
929  ["heads", [[htd], defined_e_or(size, 2, 1)]],
930 
931  ["cols", [defined_e_or(size, 0, defined_or(size, 1))]],
932  ["rows", [[[note], defined_e_or(size, 1, 1)]]],
933 
934  ["hlines", concat(consts(3,lnc[0]), consts(2,lnc[1]))],
935  ["vlines", consts(3,lnc[0])]
936  ];
937 
938  // local table format map
939  fmap = (halign == "center") ? draft_table_format_map_ccc
940  : (halign == "left") ? draft_table_format_map_cll
941  : (halign == "right") ? draft_table_format_map_crr
942  : undef;
943 
945  (
946  map=map, fmap=fmap, zp=zp, window=window, layers=layers
947  );
948  } // layers
949 }
950 
951 //! Construct a sheet title block.
952 /***************************************************************************//**
953  \copydetails draft_ztable()
954 
955  \details
956 
957  A title block is a ztable with a predetermined layout specified by
958  a style map. See the \ref tools_drafting_config "configuration"
959  section for the available title block style maps.
960 
961  \sa draft_title_block_map_style1.
962 *******************************************************************************/
963 module draft_title_block
964 (
965  text,
967  zp = 0,
968  number = false,
969  window = false,
970  layers = draft_get_config("layers-titleblock")
971 )
972 {
974  (
975  text=text, map=map, zp=zp, number=number, window=window, layers=layers
976  );
977 }
978 
979 //! @}
980 
981 //! @}
982 //! @}
983 
984 //----------------------------------------------------------------------------//
985 // openscad-amu auxiliary scripts
986 //----------------------------------------------------------------------------//
987 
988 /*
989 BEGIN_SCOPE diagram;
990  BEGIN_OPENSCAD;
991  include <omdl-base.scad>;
992  include <tools/align.scad>;
993  include <tools/operation_cs.scad>;
994  include <tools/polytope.scad>;
995  include <tools/drafting/draft-base.scad>;
996 
997  object = "draft_move";
998 
999  if (object == "draft_move") {
1000  draft_sheet();
1001  draft_move ( [for (x=[0:7], y=[0:3]) [[0,0], [x,y], is_even(x)?0:1]] )
1002  {
1003  square(10, center=true);
1004  circle(d=10);
1005  }
1006  }
1007 
1008  if (object == "draft_sheet") {
1009  draft_sheet( sheet=[5, [5, 4, 5, 5, 25]] );
1010  }
1011 
1012  if (object == "draft_axes") {
1013  draft_axes([[-10,100], [-10,60]], w=[1/2, 3], s=[2, 1], a=[0, [1,1,2,2]], ts=5);
1014  }
1015 
1016  if (object == "draft_ruler") {
1017  draft_ruler();
1018 
1019  translate([75,0])
1020  draft_ruler(units="in", marks=16, groups=2, mark_size=length(1/16/25.4, "in"));
1021  }
1022 
1023  if (object == "draft_table") {
1024  map= [ [ "title", [ "TABLE", 3/2 ] ],
1025  [ "heads", [ ["col1", "col2", "col3"], 3/4 ] ],
1026  [ "cols", [ 2, 2, 2 ] ],
1027  [ "rows", [ [ ["d00", "d01", "d02"], 1 ],
1028  [ ["d10", "d11", "d12"], 1 ],
1029  [ ["d20", "d21", "d22"], 1 ],
1030  [ ["d30", "d31", "d32"], 1 ] ] ] ];
1031 
1032  draft_table( map=map, fmap=draft_table_format_map_ccc );
1033  }
1034 
1035  if (object == "draft_ztable")
1036  {
1037  text= [ [ "data0.0", "data0.1" ],
1038  "data1", "data2", "data3", "data4", "data5", "data6",
1039  "data7", "data8", "data9", "data10", "data11",
1040  [ "data12.0", "data12.1", "data12.2", "data12.3" ] ];
1041 
1042  draft_ztable( text=text, map=draft_title_block_map_style1 );
1043  }
1044 
1045  if (object == "draft_note")
1046  {
1047  for (i = [[-40, "left", [1,0]], [0, "center", [4,0]], [40, "right", 3]] )
1048  translate([first(i), 0])
1049  draft_note
1050  (
1051  head="NOTE",
1052  note=["note 1", "note 2", "note 3"],
1053  size=[3, 2, 3/4],
1054  halign = second(i),
1055  line = [1, third(i)]
1056  );
1057  }
1058  END_OPENSCAD;
1059 
1060  BEGIN_MFSCRIPT;
1061  include --path "${INCLUDE_PATH}" {var_init,var_gen_svg}.mfs;
1062 
1063  defines name "objects" define "object"
1064  strings "
1065  draft_move
1066  draft_sheet
1067  draft_axes
1068  draft_ruler
1069  draft_table
1070  draft_ztable
1071  draft_note
1072  ";
1073  variables add_opts_combine "objects";
1074  variables add_opts "--viewall --autocenter";
1075 
1076  include --path "${INCLUDE_PATH}" scr_make_mf.mfs;
1077  END_MFSCRIPT;
1078 END_SCOPE;
1079 */
1080 
1081 //----------------------------------------------------------------------------//
1082 // end of file
1083 //----------------------------------------------------------------------------//
x_axis_ci
<integer> The coordinate axis index for the Euclidean space x-axis.
Definition: constants.scad:395
y_axis_ci
<integer> The coordinate axis index for the Euclidean space y-axis.
Definition: constants.scad:398
x_axis2d_uv
<vector-2d> The unit vector of the positive x-axis in 2d Euclidean space.
Definition: constants.scad:410
y_axis2d_uv
<vector-2d> The unit vector of the positive y-axis in 2d Euclidean space.
Definition: constants.scad:413
pi
<decimal> The ratio of a circle's circumference to its diameter.
Definition: constants.scad:198
empty_str
<string> A string with no characters (the empty string).
Definition: constants.scad:301
empty_lst
<list> A list with no values (the empty list).
Definition: constants.scad:304
function line_tp(l)
Return the terminal point of a line or vector.
function line_ip(l)
Return the initial point of a line or vector.
function line2d_new(m=1, a=0, p1=origin2d, p2, v)
Construct a 2 dimensional directed line.
function defined_e_or(v, i, d)
Return an element of an iterable when it exists or a default value otherwise.
function third(v)
Return the third element of an iterable value.
function second(v)
Return the second element of an iterable value.
function first(v)
Return the first element of an iterable value.
function all_numbers(v, c=0)
Test if all elements of an iterable value are numbers.
function is_empty(v)
Test if an iterable value is empty.
function all_strings(v, c=0)
Test if all elements of an iterable value are strings.
function consts(l, v, u=false)
Create a list of constant or incrementing elements.
function map_get_value(m, k)
Get the map value associated with a key.
function map_get_firstof2_or(m1, m2, k, d)
Get the the first value associated with an existing key in one of two maps.
function defined_or(v, d)
Return given value, if defined, or a secondary value, if primary is not defined.
function is_defined(v)
Test if a value is defined.
function table_exists(r, c, ri, ci)
Test the existence of a table row identifier, table column identifier, or both.
module table_check(r, c, verbose=false)
Perform basic format checks on a table and output errors to console.
Definition: table.scad:595
draft_table_format_map_cll
<map> Table format map; centered, left, left –justified.
Definition: config.scad:1282
draft_table_format_map_crr
<map> Table format map; centered, right, right –justified.
Definition: config.scad:1306
function draft_get_sheet_config(ci)
Get sheet configuration value helper function.
$draft_scale
<integer> Line construction drafting scale multiplier.
Definition: config.scad:98
draft_table_format_map_ccc
<map> Table format map; centered, centered, centered –justified.
Definition: config.scad:1258
draft_title_block_map_style1
<map> A title block map; style 1.
Definition: config.scad:1107
function draft_get_config(k)
Get drafting configuration default helper function.
function draft_get_sheet_size(ci)
Get sheet size value helper function.
draft_sheet_config
<string> Drafting sheet configuration identifier.
Definition: config.scad:538
draft_sheet_scale
<integer> Sheet construction drafting scale multiplier.
Definition: config.scad:101
module draft_title_block(text, map=draft_title_block_map_style1, zp=0, number=false, window=false, layers=draft_get_config("layers-titleblock"))
Construct a sheet title block.
module draft_sheet(sheet, frame, zone, grid, origin, check=false, layers=draft_get_config("layers-sheet"))
Construct a drafting sheet with frame, zone, grid, and origin.
Definition: operation.scad:308
module draft_ruler(units="mm", marks=10, groups=5, mark_size=1, group_height=5, label_scale=2/3, label_hide=false, order=1, w=1, layers=draft_get_config("layers-sheet"))
Construct a drafting sheet ruler.
Definition: operation.scad:648
module draft_axes(size, w=1, s=2, a=0, ts=0, layers=draft_get_config("layers-sheet"))
Construct drafting sheet axes.
Definition: operation.scad:531
module draft_move(list)
Move one or more child objects to sheet a reference zone.
Definition: operation.scad:225
module draft_table(map, fmap, zp=0, window=false, layers=draft_get_config("layers-table"))
Construct a text table that is populated by rows and columns.
Definition: operation.scad:753
module draft_ztable(text, map, zp=0, number=false, window=false, layers=draft_get_config("layers-table"))
Construct a text table that is populated by predefined zones.
Definition: operation.scad:890
module draft_note(head, note, size, line, halign="left", cmh=draft_get_config("note-cmh"), cmv=draft_get_config("note-cmv"), zp=0, window=false, layers=draft_get_config("layers-note"))
Construct a text note with optional heading and boarder.
module draft_in_layers(layers=draft_get_config("layers-default"))
Assign one or more layers to child objects.
Definition: operation.scad:181
module draft_line(l=x_axis2d_ul, w=1, s=1, a1=0, a2=0)
Draft a line with configurable style and optional arrowheads.
module draft_rectangle(d=1, c=origin2d, w=1, s=1)
Draft a rectangle with configurable style.
function draft_sheet_get_zone(rx, ry, ix, iy, zp=0, window=false, frame=false)
Get sheet, sheet-frame, or sheet-zone reference coordinates.
function draft_ztable_get_zone(i, zp=0, limits=false, window=false, map)
Get ztable zone coordinates given a zone index.
function draft_table_get_cell(ix, iy, zp=0, limits=false, window=false, map, fmap)
Get table cell coordinates given a column and row.
module draft_make_3d_if_configured()
Extrude 2D drafted constructions to 3D if configured.
function draft_layers_any_active(layers=draft_get_config("layers-default"))
Check if any identified layers are active.
module draft_ztable_text(i, text, size, fmt, dfmt, map)
Add text to ztable at a given zone index.
Definition: primitive.scad:853
module draft_table_text(ix, iy, text, size, dfmt, map, fmap)
Add text to table cell at a given a column and row.
Definition: primitive.scad:628
function length(v, from=length_unit_default, to=length_unit_base, d=1)
Convert a value from from one units to another with dimensions.