BRL-CAD
coil.c
Go to the documentation of this file.
1 /* C O I L . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2009-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @file coil.c
21  *
22  * Generator logic for creating coils.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32 
33 #include "bu/getopt.h"
34 #include "vmath.h"
35 #include "bn.h"
36 #include "raytrace.h"
37 #include "wdb.h"
38 #include "ged.h"
39 
40 
41 #define D2R(x) (x * DEG2RAD)
42 #define DEFAULT_COIL_OBJECT "coil"
43 #define DEFAULT_COIL_FILENAME "coil.g"
44 
46 
47 struct coil_data_t {
48  struct bu_list l;
49  int nt; /*Number of Turns*/
50  fastf_t od; /*Outer Diameter*/
51  fastf_t wd; /*Wire Diameter*/
52  fastf_t ha; /*Helix Angle*/
53  fastf_t p; /*Pitch*/
54  int lhf; /*Winding Direction - 1 is Right Handed, -1 is Left Handed*/
55 };
56 
57 
58 fastf_t
59 cap_squared(struct bu_list *head, fastf_t mean_outer_diameter, fastf_t wire_diameter, fastf_t helix_angle, fastf_t pitch, fastf_t starting_pitch, int is_start, int *need_subtraction, int lhf)
60 {
61  fastf_t pipe_bend, coil_radius;
62  point_t pnt1, pnt2, pnt4, pnt6, pnt8;
63 
64  coil_radius = (mean_outer_diameter - wire_diameter)/2.0;
65  pipe_bend = coil_radius;
66 
67  *need_subtraction += 0;
68 
69  if (is_start == 1) {
70  VSET(pnt1, 0, -coil_radius, starting_pitch - sin(D2R(helix_angle))*coil_radius);
71  VSET(pnt2, lhf*coil_radius , -coil_radius, starting_pitch - sin(D2R(helix_angle))*coil_radius);
72  VSET(pnt4, lhf*coil_radius , coil_radius, starting_pitch - sin(D2R(helix_angle))*coil_radius);
73  VSET(pnt6, lhf*-coil_radius , coil_radius, pitch/2+starting_pitch - sin(D2R(helix_angle))*coil_radius);
74  VSET(pnt8, lhf*-coil_radius , -coil_radius, pitch+starting_pitch - sin(D2R(helix_angle))*coil_radius);
75  mk_add_pipe_pt(head, pnt1, wire_diameter, 0.0, pipe_bend);
76  mk_add_pipe_pt(head, pnt2, wire_diameter, 0.0, pipe_bend);
77  mk_add_pipe_pt(head, pnt4, wire_diameter, 0.0, pipe_bend);
78  mk_add_pipe_pt(head, pnt6, wire_diameter, 0.0, pipe_bend);
79  mk_add_pipe_pt(head, pnt8, wire_diameter, 0.0, pipe_bend);
80  return pitch + starting_pitch;
81  } else {
82  VSET(pnt2, lhf*coil_radius , -coil_radius, starting_pitch + pitch/8);
83  VSET(pnt4, lhf*coil_radius , coil_radius, starting_pitch + pitch*3/8 + sin(D2R(helix_angle))*coil_radius);
84  VSET(pnt6, lhf*-coil_radius , coil_radius, starting_pitch + pitch + sin(D2R(helix_angle))*coil_radius);
85  VSET(pnt8, lhf*-coil_radius , -coil_radius, starting_pitch + pitch + sin(D2R(helix_angle))*coil_radius);
86  VSET(pnt1, 0 , -coil_radius, starting_pitch + pitch + sin(D2R(helix_angle))*coil_radius);
87  mk_add_pipe_pt(head, pnt2, wire_diameter, 0.0, pipe_bend);
88  mk_add_pipe_pt(head, pnt4, wire_diameter, 0.0, pipe_bend);
89  mk_add_pipe_pt(head, pnt6, wire_diameter, 0.0, pipe_bend);
90  mk_add_pipe_pt(head, pnt8, wire_diameter, 0.0, pipe_bend);
91  mk_add_pipe_pt(head, pnt1, wire_diameter, 0.0, pipe_bend);
92  return starting_pitch + pitch + sin(D2R(helix_angle))*coil_radius;
93  }
94 
95  return 0;
96 }
97 
98 
99 fastf_t
100 cap_squared_ground(struct rt_wdb *file, struct bu_list *head, char *prefix, struct wmember *coil_subtractions, fastf_t mean_outer_diameter, fastf_t wire_diameter, fastf_t helix_angle, fastf_t pitch, fastf_t starting_pitch, int is_start, int *need_subtraction, int lhf)
101 {
102  fastf_t pipe_bend, coil_radius;
103  point_t origin, height, pnt1, pnt2, pnt4, pnt6, pnt8;
104  struct bu_vls str1 = BU_VLS_INIT_ZERO;
105 
106  coil_radius = (mean_outer_diameter - wire_diameter)/2.0;
107  pipe_bend = coil_radius;
108 
109  *need_subtraction += 1;
110 
111  if (is_start == 1) {
112  VSET(pnt1, 0, -coil_radius, starting_pitch);
113  VSET(pnt2, lhf*coil_radius , -coil_radius, starting_pitch);
114  VSET(pnt4, lhf*coil_radius , coil_radius, starting_pitch);
115  VSET(pnt6, lhf*-coil_radius , coil_radius, pitch/2+starting_pitch);
116  VSET(pnt8, lhf*-coil_radius , -coil_radius, pitch+starting_pitch);
117  mk_add_pipe_pt(head, pnt1, wire_diameter, 0.0, pipe_bend);
118  mk_add_pipe_pt(head, pnt2, wire_diameter, 0.0, pipe_bend);
119  mk_add_pipe_pt(head, pnt4, wire_diameter, 0.0, pipe_bend);
120  mk_add_pipe_pt(head, pnt6, wire_diameter, 0.0, pipe_bend);
121  mk_add_pipe_pt(head, pnt8, wire_diameter, 0.0, pipe_bend);
122  VSET(origin, 0, 0, starting_pitch);
123  VSET(height, 0, 0, -wire_diameter);
124  bu_vls_sprintf(&str1, "%s-startcap.s", prefix);
125  mk_rcc(file, bu_vls_addr(&str1), origin, height, coil_radius+wire_diameter+.1*wire_diameter);
126  (void)mk_addmember(bu_vls_addr(&str1), &(*coil_subtractions).l, NULL, WMOP_UNION);
127  bu_vls_free(&str1);
128  return pitch + starting_pitch;
129  } else {
130  VSET(pnt2, lhf*coil_radius , -coil_radius, starting_pitch + pitch/8);
131  VSET(pnt4, lhf*coil_radius , coil_radius, starting_pitch + pitch*3/8 + sin(D2R(helix_angle))*coil_radius);
132  VSET(pnt6, lhf*-coil_radius , coil_radius, starting_pitch + pitch + sin(D2R(helix_angle))*coil_radius);
133  VSET(pnt8, lhf*-coil_radius , -coil_radius, starting_pitch + pitch + sin(D2R(helix_angle))*coil_radius);
134  VSET(pnt1, 0 , -coil_radius, starting_pitch + pitch + sin(D2R(helix_angle))*coil_radius);
135  mk_add_pipe_pt(head, pnt2, wire_diameter, 0.0, pipe_bend);
136  mk_add_pipe_pt(head, pnt4, wire_diameter, 0.0, pipe_bend);
137  mk_add_pipe_pt(head, pnt6, wire_diameter, 0.0, pipe_bend);
138  mk_add_pipe_pt(head, pnt8, wire_diameter, 0.0, pipe_bend);
139  mk_add_pipe_pt(head, pnt1, wire_diameter, 0.0, pipe_bend);
140  VSET(origin, 0, 0, starting_pitch + pitch + sin(D2R(helix_angle))*coil_radius);
141  VSET(height, 0, 0, wire_diameter);
142  bu_vls_sprintf(&str1, "%s-endcap.s", prefix);
143  mk_rcc(file, bu_vls_addr(&str1), origin, height, coil_radius+wire_diameter+.1*wire_diameter);
144  (void)mk_addmember(bu_vls_addr(&str1), &(*coil_subtractions).l, NULL, WMOP_UNION);
145  bu_vls_free(&str1);
146  return starting_pitch + pitch + sin(D2R(helix_angle))*coil_radius;
147  }
148 }
149 
150 
151 fastf_t
152 cap_ground(struct rt_wdb *file, struct bu_list *head, char *prefix, struct wmember *coil_subtractions, fastf_t mean_outer_diameter, fastf_t wire_diameter, fastf_t helix_angle, fastf_t pitch, fastf_t starting_pitch, int is_start, int *need_subtraction, int lhf)
153 {
154  fastf_t coil_radius, pipe_bend, center_height;
155  point_t origin, height, pnt1, pnt2, pnt4, pnt6, pnt8;
156  struct bu_vls str1 = BU_VLS_INIT_ZERO;
157 
158  coil_radius = (mean_outer_diameter - wire_diameter)/2.0;
159  pipe_bend = coil_radius;
160 
161  *need_subtraction += 1;
162 
163  center_height = sqrt(((coil_radius/cos(D2R(helix_angle)))*(coil_radius/cos(D2R(helix_angle))))-coil_radius*coil_radius) + 0.25*pitch*cos(D2R(helix_angle));
164 
165  if (is_start == 1) {
166  VSET(pnt1, 0, -coil_radius, starting_pitch);
167  VSET(pnt2, lhf*coil_radius , -coil_radius, pitch/8 + starting_pitch + sin(D2R(helix_angle))*coil_radius);
168  VSET(pnt4, lhf*coil_radius , coil_radius, pitch*3/8 + starting_pitch + sin(D2R(helix_angle))*coil_radius);
169  VSET(pnt6, lhf*-coil_radius , coil_radius, pitch*5/8 + starting_pitch - sin(D2R(helix_angle))*coil_radius);
170  VSET(pnt8, lhf*-coil_radius , -coil_radius, pitch*7/8 + starting_pitch - sin(D2R(helix_angle))*coil_radius);
171  mk_add_pipe_pt(head, pnt1, wire_diameter, 0.0, pipe_bend);
172  mk_add_pipe_pt(head, pnt2, wire_diameter, 0.0, pipe_bend);
173  mk_add_pipe_pt(head, pnt4, wire_diameter, 0.0, pipe_bend);
174  mk_add_pipe_pt(head, pnt6, wire_diameter, 0.0, pipe_bend);
175  mk_add_pipe_pt(head, pnt8, wire_diameter, 0.0, pipe_bend);
176  VSET(origin, 0, 0, 0);
177  VSET(height, sin(D2R(helix_angle))*(wire_diameter+0.25*pitch), 0, -wire_diameter - 0.25*pitch);
178  bu_vls_trunc(&str1, 0);
179  bu_vls_printf(&str1, "%s-startcap.s", prefix);
180  mk_rcc(file, bu_vls_addr(&str1), origin, height, coil_radius*(1+sin(D2R(helix_angle)))+wire_diameter+.1*wire_diameter);
181  (void)mk_addmember(bu_vls_addr(&str1), &(*coil_subtractions).l, NULL, WMOP_UNION);
182  bu_vls_free(&str1);
183  return pitch + starting_pitch;
184  } else {
185  VSET(pnt2, lhf*coil_radius , -coil_radius, pitch/8 + starting_pitch + sin(D2R(helix_angle))*coil_radius);
186  VSET(pnt4, lhf*coil_radius , coil_radius, pitch*3/8 + starting_pitch + sin(D2R(helix_angle))*coil_radius);
187  VSET(pnt6, lhf*-coil_radius , coil_radius, pitch*5/8 + starting_pitch - sin(D2R(helix_angle))*coil_radius);
188  VSET(pnt8, lhf*-coil_radius , -coil_radius, pitch*7/8 + starting_pitch - sin(D2R(helix_angle))*coil_radius);
189  VSET(pnt1, 0 , -coil_radius, pitch+starting_pitch);
190  mk_add_pipe_pt(head, pnt2, wire_diameter, 0.0, pipe_bend);
191  mk_add_pipe_pt(head, pnt4, wire_diameter, 0.0, pipe_bend);
192  mk_add_pipe_pt(head, pnt6, wire_diameter, 0.0, pipe_bend);
193  mk_add_pipe_pt(head, pnt8, wire_diameter, 0.0, pipe_bend);
194  mk_add_pipe_pt(head, pnt1, wire_diameter, 0.0, pipe_bend);
195  VSET(origin, 0, 0, starting_pitch + 15/8*pitch - center_height + sin(D2R(helix_angle))*coil_radius);
196  VSET(height, -sin(D2R(helix_angle))*(wire_diameter+0.25*pitch), 0, wire_diameter + 0.25*pitch);
197  bu_vls_trunc(&str1, 0);
198  bu_vls_printf(&str1, "%s-endcap.s", prefix);
199  mk_rcc(file, bu_vls_addr(&str1), origin, height, coil_radius*(1+sin(D2R(helix_angle)))+wire_diameter+.1*wire_diameter);
200  (void)mk_addmember(bu_vls_addr(&str1), &(*coil_subtractions).l, NULL, WMOP_UNION);
201  bu_vls_free(&str1);
202  return pitch+starting_pitch;
203  }
204 }
205 
206 
207 fastf_t
208 helical_coil_plain(struct bu_list *head, fastf_t mean_outer_diameter, fastf_t wire_diameter, fastf_t helix_angle, fastf_t pitch, fastf_t starting_pitch, int nt, int lhf)
209 {
210  int i;
211  fastf_t coil_radius, pipe_bend;
212  point_t pnt2, pnt4, pnt6, pnt8;
213 
214  coil_radius = (mean_outer_diameter - wire_diameter)/2.0;
215  pipe_bend = coil_radius;
216 
217  for (i = 0; i < nt; i++) {
218  VSET(pnt2, lhf*coil_radius , -coil_radius, i*pitch + pitch/8 + starting_pitch + sin(D2R(helix_angle))*coil_radius);
219  VSET(pnt4, lhf*coil_radius , coil_radius, i*pitch + pitch*3/8 + starting_pitch + sin(D2R(helix_angle))*coil_radius);
220  VSET(pnt6, lhf*-coil_radius , coil_radius, i*pitch + pitch*5/8 + starting_pitch - sin(D2R(helix_angle))*coil_radius);
221  VSET(pnt8, lhf*-coil_radius , -coil_radius, i*pitch + pitch*7/8 + starting_pitch - sin(D2R(helix_angle))*coil_radius);
222  mk_add_pipe_pt(head, pnt2, wire_diameter, 0.0, pipe_bend);
223  mk_add_pipe_pt(head, pnt4, wire_diameter, 0.0, pipe_bend);
224  mk_add_pipe_pt(head, pnt6, wire_diameter, 0.0, pipe_bend);
225  mk_add_pipe_pt(head, pnt8, wire_diameter, 0.0, pipe_bend);
226  }
227 
228  return (nt-1)*pitch + pitch*7/8 + starting_pitch;
229 }
230 
231 
232 void
233 make_coil(struct rt_wdb (*file), char *prefix, struct bu_list *sections, int start_cap_type, int end_cap_type)
234 {
235  struct bu_list head;
236  fastf_t last_pitch_pt;
237  point_t pnt1;
238  int need_subtractions = 0;
239  struct wmember coil;
240  struct wmember coil_subtractions;
241  struct coil_data_t *s_data;
242  struct coil_data_t *e_data;
243  struct coil_data_t *cd;
244  struct bu_vls str = BU_VLS_INIT_ZERO;
245 
246  BU_LIST_INIT(&coil.l);
247  BU_LIST_INIT(&coil_subtractions.l);
248  mk_pipe_init(&head);
249 
250  s_data = BU_LIST_FIRST(coil_data_t, &(*sections));
251  e_data = BU_LIST_LAST(coil_data_t, &(*sections));
252 
253  last_pitch_pt = 0;
254 
255  switch (start_cap_type) {
256  case 0:
257  VSET(pnt1, 0, -1*(s_data->od/2-s_data->wd/2), last_pitch_pt);
258  mk_add_pipe_pt(&head, pnt1, s_data->wd, 0.0, (s_data->od/2-s_data->wd/2));
259  break;
260  case 1:
261  last_pitch_pt = cap_squared(&head, s_data->od, s_data->wd, s_data->ha, s_data->p, 0, 1, &need_subtractions, s_data->lhf);
262  break;
263  case 2:
264  last_pitch_pt = cap_ground(file, &head, prefix, &coil_subtractions, s_data->od, s_data->wd, s_data->ha, s_data->p, 0, 1, &need_subtractions, s_data->lhf);
265  break;
266  case 3:
267  last_pitch_pt = cap_squared_ground(file, &head, prefix, &coil_subtractions, s_data->od, s_data->wd, s_data->ha, s_data->p, 0, 1, &need_subtractions, s_data->lhf);
268  break;
269  default:
270  break;
271  }
272 
273  for (BU_LIST_FOR(cd, coil_data_t, &(*sections))) {
274  last_pitch_pt = helical_coil_plain(&head, cd->od, cd->wd, cd->ha, cd->p, last_pitch_pt, cd->nt, cd->lhf);
275  }
276 
277  switch (end_cap_type) {
278  case 0:
279  VSET(pnt1, 0 , -1*(e_data->od/2-e_data->wd/2), 0.125*(e_data->p)+last_pitch_pt);
280  mk_add_pipe_pt(&head, pnt1, e_data->wd, 0.0, (e_data->od/2-e_data->wd/2));
281  break;
282  case 1:
283  last_pitch_pt = cap_squared(&head, e_data->od, e_data->wd, e_data->ha, e_data->p, last_pitch_pt, 0, &need_subtractions, s_data->lhf);
284  break;
285  case 2:
286  last_pitch_pt = cap_ground(file, &head, prefix, &coil_subtractions, e_data->od, e_data->wd, e_data->ha, e_data->p, last_pitch_pt, 0, &need_subtractions, s_data->lhf);
287  break;
288  case 3:
289  last_pitch_pt = cap_squared_ground(file, &head, prefix, &coil_subtractions, e_data->od, e_data->wd, e_data->ha, e_data->p, last_pitch_pt, 0, &need_subtractions, s_data->lhf);
290  break;
291  default:
292  break;
293  }
294 
295  bu_vls_trunc(&str, 0);
296  bu_vls_printf(&str, "%s_core.s", prefix);
297  mk_pipe(file, bu_vls_addr(&str), &head);
298 
299  (void)mk_addmember(bu_vls_addr(&str), &coil.l, NULL, WMOP_UNION);
300 
301  if (need_subtractions > 0) {
302  bu_vls_trunc(&str, 0);
303  bu_vls_printf(&str, "%s_subtractions.c", prefix);
304  mk_lcomb(file, bu_vls_addr(&str), &coil_subtractions, 0, NULL, NULL, NULL, 0);
305  (void)mk_addmember(bu_vls_addr(&str), &coil.l, NULL, WMOP_SUBTRACT);
306  }
307 
308  mk_lcomb(file, prefix, &coil, 0, NULL, NULL, NULL, 0);
309 
310  bu_vls_free(&str);
311  mk_pipe_free(&head);
312 }
313 
314 
315 void usage(struct ged *gedp)
316 {
317  bu_vls_printf(gedp->ged_result_str, "Usage: coil [-d mean_outer_diameter] [-w wire_diameter] [-H helix_angle] [-p pitch]\n");
318  bu_vls_printf(gedp->ged_result_str, " [-n number_of_turns] [-s start_cap_type] [-e end_cap_type]\n");
319  bu_vls_printf(gedp->ged_result_str, " [-S coil_data_structure] [-l overall_length] [-L]\n");
320  bu_vls_printf(gedp->ged_result_str, " (units mm)\n");
321 }
322 
323 
324 /* Process command line arguments */
325 int
326 ReadArgs(struct ged *gedp, int argc, const char *argv[], struct bu_vls *name, struct bu_list *sections, fastf_t *mean_outer_diameter, fastf_t *wire_diameter, fastf_t *helix_angle, fastf_t *pitch, int *nt, int *start_cap_type, int *end_cap_type, fastf_t *overall_length, int *lhf)
327 {
328  int c = 0;
329  char *options="d:w:H:p:n:s:e:S:l:Lh?";
330  int numturns, stype, etype, lhflag;
331  float mean_od, wired, h_angle, ptch, lngth;
332  int d1, d6;
333  float d2, d3, d4, d5;
334  char s1, s2, s3, s4, s5;
335  int have_name = 0;
336  struct coil_data_t *coil_data;
337 
338  usedefaults = (argc == 1) ;
339 
340  while ((c=bu_getopt(argc, (char * const *)argv, options)) != -1) {
341  switch (c) {
342  case 'd' :
343  sscanf(bu_optarg, "%f", &mean_od);
344  *mean_outer_diameter = mean_od;
345  break;
346  case 'w':
347  sscanf(bu_optarg, "%f", &wired);
348  *wire_diameter = wired;
349  break;
350  case 'H':
351  sscanf(bu_optarg, "%f", &h_angle);
352  *helix_angle = h_angle;
353  break;
354  case 'L':
355  lhflag = -1;
356  *lhf = lhflag;
357  break;
358  case 'p':
359  sscanf(bu_optarg, "%f", &ptch);
360  *pitch = ptch;
361  break;
362  case 'n':
363  sscanf(bu_optarg, "%d", &numturns);
364  *nt = numturns;
365  break;
366  case 's':
367  sscanf(bu_optarg, "%d", &stype);
368  *start_cap_type = stype;
369  break;
370  case 'e':
371  sscanf(bu_optarg, "%d", &etype);
372  *end_cap_type = etype;
373  break;
374  case 'l':
375  sscanf(bu_optarg, "%f", &lngth);
376  *overall_length = lngth;
377  break;
378  case 'S':
379  BU_ALLOC(coil_data, struct coil_data_t);
380  sscanf(bu_optarg, "%d%c%f%c%f%c%f%c%f%c%d", &d1, &s1, &d2, &s2, &d3, &s3, &d4, &s4, &d5, &s5, &d6);
381  coil_data->nt = d1;
382  coil_data->od = d2;
383  coil_data->wd = d3;
384  coil_data->ha = d4;
385  coil_data->p = d5;
386  if (d6 == 1)
387  coil_data->lhf = 1;
388  else
389  coil_data->lhf = -1;
390  BU_LIST_INSERT(&(*sections), &((*coil_data).l));
391  break;
392  default:
393  usage(gedp);
394  return GED_ERROR;
395  }
396  }
397  if (argc == 1) {
398  usage(gedp);
399  bu_vls_printf(gedp->ged_result_str,"\n Program continues running:\n\n");
400  }
401  if ((argc - bu_optind) == 1) {
402  have_name = 1;
403  bu_vls_sprintf(name, "%s", argv[bu_optind]);
404  }
405  if (!have_name) {
406  bu_vls_sprintf(name, "%s", DEFAULT_COIL_OBJECT);
407  }
408  return GED_OK;
409 }
410 
411 
412 int
413 ged_coil(struct ged *gedp, int argc, const char *argv[])
414 {
415 
416  struct bu_vls name;
417  struct rt_wdb *db_fp = gedp->ged_wdbp;
418  struct bu_vls str = BU_VLS_INIT_ZERO;
419  fastf_t mean_outer_diameter, wire_diameter, overall_length, nominal_length;
420  fastf_t helix_angle, pitch;
421 
422  struct coil_data_t *coil_data = NULL;
423  struct bu_list sections;
424 
425  int nt; /* Number of turns */
426  int start_cap_type, end_cap_type;
427  int lhf; /* Winding flag */
428 
431 
432  /* initialize result */
433  bu_vls_trunc(gedp->ged_result_str, 0);
434  bu_vls_init(&name);
435  BU_LIST_INIT(&sections);
436 
437  mean_outer_diameter = 0;
438  wire_diameter = 0;
439  helix_angle = 0;
440  pitch = 0;
441  nt = 0;
442  start_cap_type = 0;
443  end_cap_type = 0;
444  overall_length = 0;
445  lhf = 1;
446 
447  /* Process arguments */
448  if (ReadArgs(gedp, argc, argv, &name, &sections, &mean_outer_diameter, &wire_diameter, &helix_angle, &pitch, &nt, &start_cap_type, &end_cap_type, &overall_length, &lhf) != GED_OK) {
449 /* bu_vls_printf(gedp->ged_result_str, "Nothing created"); */
450  return GED_ERROR;
451  }
452 
453  /* Handle various potential errors in args and set defaults if nothing supplied */
454 
455  if (BU_LIST_IS_EMPTY(&sections)) {
456 
457  if (usedefaults)
458  bu_vls_printf(gedp->ged_result_str, "Creating %s with default parameters.\n",DEFAULT_COIL_FILENAME);
459 
460  if (mean_outer_diameter < 0 || wire_diameter < 0 || helix_angle < 0 || pitch < 0 || nt < 0 || start_cap_type < 0 || end_cap_type < 0) {
461  bu_vls_printf(gedp->ged_result_str, "negative value in one or more arguments supplied to coil");
462  return GED_ERROR;
463  }
464 
465  if (ZERO(wire_diameter) && ZERO(mean_outer_diameter)) {
466  mean_outer_diameter = 1000;
467  wire_diameter = 100;
468  }
469 
470  if (ZERO(wire_diameter) && mean_outer_diameter > 0)
471  wire_diameter = mean_outer_diameter/10;
472 
473  if (ZERO(mean_outer_diameter) && wire_diameter > 0)
474  mean_outer_diameter = wire_diameter * 10;
475 
476  if (ZERO(pitch))
477  pitch = wire_diameter;
478 
479  if (pitch < wire_diameter) {
480  bu_vls_printf(gedp->ged_result_str, "WARNING: Pitch less than wire diameter. Setting pitch to wire diameter: %f mm\n", wire_diameter);
481  pitch = wire_diameter;
482  }
483 
484  if (nt == 0)
485  nt = 30;
486 
487  BU_ALLOC(coil_data, struct coil_data_t);
488  coil_data->nt = nt;
489  coil_data->od = mean_outer_diameter;
490  coil_data->wd = wire_diameter;
491  coil_data->ha = helix_angle;
492  coil_data->p = pitch;
493  coil_data->lhf = lhf;
494 
495  BU_LIST_APPEND(&(sections), &((*coil_data).l));
496 
497  coil_data = BU_LIST_FIRST(coil_data_t, &sections);
498  }
499 
500  /* If hard clamping the length, have to check some things and maybe clamp some values */
501 
502  if (!ZERO(overall_length)) {
503  bu_vls_printf(gedp->ged_result_str, "Note: Length clamping overrides other specified values. If supplied values are\n"
504  "inconsistent with specified length, they will be overridden in this order:\n\n"
505  "When Shrinking: pitch, number of turns, wire diameter\n"
506  "When Expanding: number of turns, pitch\n\n");
507 
508  /* broken up for c90 and readability */
509  bu_vls_printf(gedp->ged_result_str, "Currently, this override order is independent of whether the value is supplied\n"
510  "by the user or calculated internally. That is, there is no preference for \n"
511  "protecting user specified properties. Moreover, length clamping will NOT \n"
512  "override explicit section specification with -S\n");
513 
514  if (coil_data) {
515  if (start_cap_type != 0 || end_cap_type != 0) {
516  bu_vls_printf(gedp->ged_result_str, "Note: At this time only uncapped coils are allowed when length is constrained.\n");
517  start_cap_type = 0;
518  end_cap_type = 0;
519  }
520  if (!ZERO(helix_angle)) {
521  bu_vls_printf(gedp->ged_result_str, "Note: At this time variable helix angles are unsupported when length is constrained.\n");
522  helix_angle = 0;
523  }
524  /* Thanks to earlier checks, we're guaranteed to have valid data for this calculation regardless of
525  * user input */
526  nominal_length = coil_data->wd + coil_data->p * coil_data->nt;
527  if (nominal_length > overall_length) {
528  /* Something has to give - start with pitch */
529  coil_data->p = (overall_length - coil_data->wd)/coil_data->nt;
530  while (coil_data->p < coil_data->wd) {
531  /* That didn't work, start knocking off turns*/
532  while ((coil_data->nt > 1) && (coil_data->p < coil_data->wd)) {
533  coil_data->nt--;
534  coil_data->p = (overall_length - coil_data->wd)/coil_data->nt;
535  }
536  if (coil_data->nt == 1) {
537  /* THAT didn't work, change the wire diameter */
538  coil_data->wd = overall_length/2;
539  coil_data->p = coil_data->wd ;
540  }
541  }
542  } else {
543  if (!EQUAL(nominal_length, overall_length)) {
544  /* Add turns first, then adjust pitch */
545  while (nominal_length < overall_length) {
546  coil_data->nt++;
547  nominal_length = coil_data->wd + coil_data->p * coil_data->nt;
548  }
549  coil_data->nt--;
550  coil_data->p = (overall_length - coil_data->wd)/coil_data->nt;
551  }
552  }
553  }
554  }
555 
556  /* do it. */
557  make_coil(db_fp, DEFAULT_COIL_OBJECT, &sections, start_cap_type, end_cap_type);
558 
559  bu_vls_free(&str);
560  bu_vls_free(&name);
561 
562  return GED_OK;
563 }
564 
565 
566 /*
567  * Local Variables:
568  * mode: C
569  * tab-width: 8
570  * indent-tabs-mode: t
571  * c-file-style: "stroustrup"
572  * End:
573  * ex: shiftwidth=4 tabstop=8
574  */
fastf_t p
Definition: coil.c:53
fastf_t cap_squared(struct bu_list *head, fastf_t mean_outer_diameter, fastf_t wire_diameter, fastf_t helix_angle, fastf_t pitch, fastf_t starting_pitch, int is_start, int *need_subtraction, int lhf)
Definition: coil.c:59
void usage(struct ged *gedp)
Definition: coil.c:315
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
#define GED_OK
Definition: ged.h:55
int mk_pipe(struct rt_wdb *fp, const char *name, struct bu_list *headp)
Definition: pipe.c:66
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
int mk_rcc(struct rt_wdb *fp, const char *name, const point_t base, const vect_t height, fastf_t radius)
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
void mk_pipe_init(struct bu_list *headp)
Definition: pipe.c:120
void mk_pipe_free(struct bu_list *headp)
Definition: pipe.c:86
Definition: list.h:118
#define BU_LIST_LAST(structure, hp)
Definition: list.h:306
Definition: ged.h:338
Definition: clone.c:90
#define VSET(a, b, c, d)
Definition: color.c:53
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define BU_LIST_IS_EMPTY(hp)
Definition: list.h:295
void make_coil(struct rt_wdb(*file), char *prefix, struct bu_list *sections, int start_cap_type, int end_cap_type)
Definition: coil.c:233
int ReadArgs(struct ged *gedp, int argc, const char *argv[], struct bu_vls *name, struct bu_list *sections, fastf_t *mean_outer_diameter, fastf_t *wire_diameter, fastf_t *helix_angle, fastf_t *pitch, int *nt, int *start_cap_type, int *end_cap_type, fastf_t *overall_length, int *lhf)
Definition: coil.c:326
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Definition: wdb.h:64
char * bu_optarg
Definition: globals.c:91
Header file for the BRL-CAD common definitions.
int bu_optind
Definition: globals.c:89
#define WMOP_SUBTRACT
Definition: wdb.h:886
#define BU_LIST_APPEND(old, new)
Definition: list.h:197
void mk_add_pipe_pt(struct bu_list *headp, const point_t coord, double od, double id, double bendradius)
Definition: pipe.c:98
#define WMOP_UNION
Definition: wdb.h:887
int bu_getopt(int nargc, char *const nargv[], const char *ostr)
Definition: getopt.c:43
struct bu_list l
Definition: wdb.h:65
#define GED_ERROR
Definition: ged.h:61
#define mk_lcomb(_fp, _name, _headp, _rf, _shadername, _shaderargs, _rgb, _inh)
Definition: wdb.h:820
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
int ged_coil(struct ged *gedp, int argc, const char *argv[])
Definition: coil.c:413
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
fastf_t helical_coil_plain(struct bu_list *head, fastf_t mean_outer_diameter, fastf_t wire_diameter, fastf_t helix_angle, fastf_t pitch, fastf_t starting_pitch, int nt, int lhf)
Definition: coil.c:208
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
#define D2R(x)
Definition: coil.c:41
void bu_vls_sprintf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:707
char * options
Definition: gqa.c:56
fastf_t cap_squared_ground(struct rt_wdb *file, struct bu_list *head, char *prefix, struct wmember *coil_subtractions, fastf_t mean_outer_diameter, fastf_t wire_diameter, fastf_t helix_angle, fastf_t pitch, fastf_t starting_pitch, int is_start, int *need_subtraction, int lhf)
Definition: coil.c:100
#define DEFAULT_COIL_OBJECT
Definition: coil.c:42
struct wmember * mk_addmember(const char *name, struct bu_list *headp, mat_t mat, int op)
Definition: reg.c:181
struct bu_list l
Definition: coil.c:48
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
fastf_t od
Definition: coil.c:50
int lhf
Definition: coil.c:54
fastf_t ha
Definition: coil.c:52
#define ZERO(val)
Definition: units.c:38
#define BU_LIST_INIT(_hp)
Definition: list.h:148
int nt
Definition: coil.c:49
#define DEFAULT_COIL_FILENAME
Definition: coil.c:43
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
int usedefaults
Definition: coil.c:45
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
fastf_t cap_ground(struct rt_wdb *file, struct bu_list *head, char *prefix, struct wmember *coil_subtractions, fastf_t mean_outer_diameter, fastf_t wire_diameter, fastf_t helix_angle, fastf_t pitch, fastf_t starting_pitch, int is_start, int *need_subtraction, int lhf)
Definition: coil.c:152
#define GED_CHECK_READ_ONLY(_gedp, _flags)
Definition: ged.h:181
Definition: vls.h:56
double fastf_t
Definition: defines.h:300
fastf_t wd
Definition: coil.c:51
#define BU_LIST_FIRST(structure, hp)
Definition: list.h:312