BRL-CAD
vdraw.c
Go to the documentation of this file.
1 /* V D R A W . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-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 /** @addtogroup libged */
21 /** @{ */
22 /** @file libged/vdraw.c
23  *
24  * Edit vector lists and display them as pseudosolids.
25  *
26  * OPEN COMMAND
27  * vdraw open - with no argument, asks if there is
28  * an open vlist (1 yes, 0 no)
29  *
30  * name - opens the specified vlist
31  * returns 1 if creating new vlist
32  * 0 if opening an existing vlist
33  *
34  * EDITING COMMANDS - no return value
35  *
36  * vdraw write i c x y z - write params into i-th vector
37  * next c x y z - write params to end of vector list
38  *
39  * vdraw insert i c x y z - insert params in front of i-th vector
40  *
41  * vdraw delete i - delete i-th vector
42  * last - delete last vector on list
43  * all - delete all vectors on list
44  *
45  * PARAMETER SETTING COMMAND - no return value
46  * vdraw params color - set the current color with 6 hex digits
47  * representing rrggbb
48  * name - change the name of the current vlist
49  *
50  * QUERY COMMAND
51  * vdraw read i - returns contents of i-th vector "c x y z"
52  * color - return the current color in hex
53  * length - return number of vectors in list
54  * name - return name of current vlist
55  *
56  * DISPLAY COMMAND -
57  * vdraw send - send the current vlist to the display
58  * returns 0 on success, -1 if the name
59  * conflicts with an existing true solid
60  *
61  * CURVE COMMANDS
62  * vdraw vlist list - return list of all existing vlists
63  * delete name - delete the named vlist
64  *
65  * All textual arguments can be replaced by their first letter.
66  * (e.g. "vdraw d a" instead of "vdraw delete all"
67  *
68  * In the above listing:
69  * "i" refers to an integer
70  * "c" is an integer representing one of the following bn_vlist commands:
71  *
72  * BN_VLIST_LINE_MOVE 0 / begin new line /
73  * BN_VLIST_LINE_DRAW 1 / draw line /
74  * BN_VLIST_POLY_START 2 / pt[] has surface normal /
75  * BN_VLIST_POLY_MOVE 3 / move to first poly vertex /
76  * BN_VLIST_POLY_DRAW 4 / subsequent poly vertex /
77  * BN_VLIST_POLY_END 5 / last vert (repeats 1st), draw poly /
78  * BN_VLIST_POLY_VERTNORM 6 / per-vertex normal, for interpolation /
79  *
80  * "x y z" refer to floating point values which represent a point or
81  * normal vector. For commands 0, 1, 3, 4, and 5, they represent a
82  * point, while for commands 2 and 6 they represent normal vectors
83  *
84  * Example Use -
85  * vdraw open rays
86  * vdraw delete all
87  * foreach partition $ray {
88  * ...stuff...
89  * vdraw write next 0 $inpt
90  * vdraw write next 1 $outpt
91  * }
92  * vdraw send
93  *
94  */
95 /** @} */
96 
97 #include "common.h"
98 
99 #include <stdlib.h>
100 #include <string.h>
101 #include <math.h>
102 #include <signal.h>
103 
104 #include "tcl.h"
105 
106 #include "bu/cmd.h"
107 #include "bn.h"
108 #include "vmath.h"
109 #include "mater.h"
110 #include "nmg.h"
111 
112 #include "./ged_private.h"
113 
114 
115 #define REV_BU_LIST_FOR(p, structure, hp) \
116  (p)=BU_LIST_LAST(structure, hp); \
117  BU_LIST_NOT_HEAD(p, hp); \
118  (p)=BU_LIST_PLAST(structure, p)
119 
120 
121 /*
122  * Usage:
123  * vdraw write i|next c x y z
124  */
125 static int
126 vdraw_write(void *data, int argc, const char *argv[])
127 {
128  struct ged *gedp = (struct ged *)data;
129  size_t idx;
130  unsigned long uind = 0;
131  struct bn_vlist *vp, *cp;
132  static const char *usage = "i|next c x y z";
133 
134  /* must be wanting help */
135  if (argc == 2) {
136  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
137  return GED_HELP;
138  }
139 
140  if (!gedp->ged_gdp->gd_currVHead) {
141  bu_vls_printf(gedp->ged_result_str, "vdraw write: no vlist is currently open.");
142  return GED_ERROR;
143  }
144  if (argc < 5) {
145  bu_vls_printf(gedp->ged_result_str, "vdraw write: not enough args\n");
146  return GED_ERROR;
147  }
148  if (argv[2][0] == 'n') {
149  /* next */
150  for (REV_BU_LIST_FOR(vp, bn_vlist, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
151  if (vp->nused > 0) {
152  break;
153  }
154  }
155  if (BU_LIST_IS_HEAD(vp, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
156  /* we went all the way through */
157  vp = BU_LIST_PNEXT(bn_vlist, vp);
158  if (BU_LIST_IS_HEAD(vp, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
159  RT_GET_VLIST(vp);
160  BU_LIST_INSERT(&(gedp->ged_gdp->gd_currVHead->vdc_vhd), &(vp->l));
161  }
162  }
163  if (vp->nused >= BN_VLIST_CHUNK) {
164  vp = BU_LIST_PNEXT(bn_vlist, vp);
165  if (BU_LIST_IS_HEAD(vp, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
166  RT_GET_VLIST(vp);
167  BU_LIST_INSERT(&(gedp->ged_gdp->gd_currVHead->vdc_vhd), &(vp->l));
168  }
169  }
170  cp = vp;
171  idx = vp->nused;
172  } else if (sscanf(argv[2], "%lu", &uind) < 1) {
173  bu_vls_printf(gedp->ged_result_str, "vdraw: write index not an integer\n");
174  return GED_ERROR;
175  } else {
176  /* uind holds user-specified index */
177  /* only allow one past the end */
178 
179  for (BU_LIST_FOR(vp, bn_vlist, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
180  if ((size_t)uind < BN_VLIST_CHUNK) {
181  /* this is the right vlist */
182  break;
183  }
184  if (vp->nused == 0) {
185  break;
186  }
187  uind -= vp->nused;
188  }
189 
190  if (BU_LIST_IS_HEAD(vp, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
191  if (uind > 0) {
192  bu_vls_printf(gedp->ged_result_str, "vdraw: write out of range\n");
193  return GED_ERROR;
194  }
195  RT_GET_VLIST(vp);
196  BU_LIST_INSERT(&(gedp->ged_gdp->gd_currVHead->vdc_vhd), &(vp->l));
197  }
198  if ((size_t)uind > vp->nused) {
199  bu_vls_printf(gedp->ged_result_str, "vdraw: write out of range\n");
200  return GED_ERROR;
201  }
202  cp = vp;
203  idx = uind;
204  }
205 
206  /* This should never happen. Adding this to silence covarity. */
207  if (idx >= BN_VLIST_CHUNK) {
208  bu_vls_printf(gedp->ged_result_str, "vdraw: vlist chunk size exceeded!\n");
209  return GED_ERROR;
210  }
211 
212  if (sscanf(argv[3], "%d", &(cp->cmd[idx])) < 1) {
213  bu_vls_printf(gedp->ged_result_str, "vdraw: cmd not an integer\n");
214  return GED_ERROR;
215  }
216  if (argc == 7) {
217  cp->pt[idx][0] = atof(argv[4]);
218  cp->pt[idx][1] = atof(argv[5]);
219  cp->pt[idx][2] = atof(argv[6]);
220  } else {
221  if (argc != 5 ||
222  bn_decode_vect(cp->pt[idx], argv[4]) != 3) {
223  bu_vls_printf(gedp->ged_result_str, "vdraw write: wrong # args, need either x y z or {x y z}\n");
224  return GED_ERROR;
225  }
226  }
227  /* increment counter only if writing onto end */
228  if (idx == cp->nused)
229  cp->nused++;
230 
231  return GED_OK;
232 }
233 
234 
235 /*
236  * Usage:
237  * vdraw insert i c x y z
238  */
239 int
240 vdraw_insert(void *data, int argc, const char *argv[])
241 {
242  struct ged *gedp = (struct ged *)data;
243  struct bn_vlist *vp, *cp, *wp;
244  size_t i;
245  size_t idx;
246  unsigned long uind = 0;
247  static const char *usage = "i c x y z";
248 
249  /* must be wanting help */
250  if (argc == 2) {
251  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
252  return GED_HELP;
253  }
254 
255  if (!gedp->ged_gdp->gd_currVHead) {
256  bu_vls_printf(gedp->ged_result_str, "vdraw: no vlist is currently open.");
257  return GED_ERROR;
258  }
259  if (argc < 7) {
260  bu_vls_printf(gedp->ged_result_str, "vdraw: not enough args");
261  return GED_ERROR;
262  }
263  if (sscanf(argv[2], "%lu", &uind) < 1) {
264  bu_vls_printf(gedp->ged_result_str, "vdraw: insert index not an integer\n");
265  return GED_ERROR;
266  }
267 
268  /* uinds hold user specified index */
269  for (BU_LIST_FOR(vp, bn_vlist, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
270  if ((size_t)uind < BN_VLIST_CHUNK) {
271  /* this is the right vlist */
272  break;
273  }
274  if (vp->nused == 0) {
275  break;
276  }
277  uind -= vp->nused;
278  }
279 
280  if (BU_LIST_IS_HEAD(vp, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
281  if (uind > 0) {
282  bu_vls_printf(gedp->ged_result_str, "vdraw: insert out of range\n");
283  return GED_ERROR;
284  }
285  RT_GET_VLIST(vp);
286  BU_LIST_INSERT(&(gedp->ged_gdp->gd_currVHead->vdc_vhd), &(vp->l));
287  }
288  if ((size_t)uind > vp->nused) {
289  bu_vls_printf(gedp->ged_result_str, "vdraw: insert out of range\n");
290  return GED_ERROR;
291  }
292 
293 
294  cp = vp;
295  idx = uind;
296 
298  vp->nused++;
299 
300  while (vp != cp) {
301  for (i = vp->nused-1; i > 0; i--) {
302  vp->cmd[i] = vp->cmd[i-1];
303  VMOVE(vp->pt[i], vp->pt[i-1]);
304  }
305  wp = BU_LIST_PLAST(bn_vlist, vp);
306  vp->cmd[0] = wp->cmd[BN_VLIST_CHUNK-1];
307  VMOVE(vp->pt[0], wp->pt[BN_VLIST_CHUNK-1]);
308  vp = wp;
309  }
310 
311  for (i = vp->nused - 1; i > idx; i--) {
312  vp->cmd[i] = vp->cmd[i-1];
313  VMOVE(vp->pt[i], vp->pt[i-1]);
314  }
315  if (sscanf(argv[3], "%d", &(vp->cmd[idx])) < 1) {
316  bu_vls_printf(gedp->ged_result_str, "vdraw: cmd not an integer\n");
317  return GED_ERROR;
318  }
319  vp->pt[idx][0] = atof(argv[4]);
320  vp->pt[idx][1] = atof(argv[5]);
321  vp->pt[idx][2] = atof(argv[6]);
322 
323  return GED_OK;
324 }
325 
326 
327 /*
328  * Usage:
329  * vdraw delete i|last|all
330  */
331 int
332 vdraw_delete(void *data, int argc, const char *argv[])
333 {
334  struct ged *gedp = (struct ged *)data;
335  struct bn_vlist *vp, *wp;
336  size_t i;
337  unsigned long uind = 0;
338  static const char *usage = "i|last|all";
339 
340  /* must be wanting help */
341  if (argc == 2) {
342  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
343  return GED_HELP;
344  }
345 
346  if (!gedp->ged_gdp->gd_currVHead) {
347  bu_vls_printf(gedp->ged_result_str, "%s %s: no vlist is currently open.", argv[0], argv[1]);
348  return GED_ERROR;
349  }
350  if (argc < 3) {
351  bu_vls_printf(gedp->ged_result_str, "%s %s: not enough args\n", argv[0], argv[1]);
352  return GED_ERROR;
353  }
354  if (argv[2][0] == 'a') {
355  /* delete all */
356  for (BU_LIST_FOR(vp, bn_vlist, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
357  vp->nused = 0;
358  }
359  return GED_OK;
360  }
361  if (argv[2][0] == 'l') {
362  /* delete last */
363  for (REV_BU_LIST_FOR(vp, bn_vlist, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
364  if (vp->nused > 0) {
365  vp->nused--;
366  break;
367  }
368  }
369  return GED_OK;
370  }
371  if (sscanf(argv[2], "%lu", &uind) < 1) {
372  bu_vls_printf(gedp->ged_result_str, "%s %s: delete index not an integer\n", argv[0], argv[1]);
373  return GED_ERROR;
374  }
375 
376  for (BU_LIST_FOR(vp, bn_vlist, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
377  if ((size_t)uind < BN_VLIST_CHUNK) {
378  /* this is the right vlist */
379  break;
380  }
381  if (vp->nused == 0) {
382  /* no point going further */
383  break;
384  }
385  uind -= vp->nused;
386  }
387 
388  /* make sure we start in a valid delete range */
389  if ((size_t)uind >= vp->nused || uind >= BN_VLIST_CHUNK) {
390  bu_vls_printf(gedp->ged_result_str, "%s %s: delete out of range\n", argv[0], argv[1]);
391  return GED_ERROR;
392  }
393 
394  for (i = (size_t)uind; i < vp->nused - 1; i++) {
395  if (i >= BN_VLIST_CHUNK-1)
396  break;
397  vp->cmd[i] = vp->cmd[i+1];
398  VMOVE(vp->pt[i], vp->pt[i+1]);
399  }
400 
401  wp = BU_LIST_PNEXT(bn_vlist, vp);
402  while (BU_LIST_NOT_HEAD(wp, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
403  if (wp->nused == 0) {
404  break;
405  }
406 
407  vp->cmd[BN_VLIST_CHUNK-1] = wp->cmd[0];
408  VMOVE(vp->pt[BN_VLIST_CHUNK-1], wp->pt[0]);
409 
410  for (i = 0; i < wp->nused - 1; i++) {
411  if (i >= BN_VLIST_CHUNK-1)
412  break;
413  wp->cmd[i] = wp->cmd[i+1];
414  VMOVE(wp->pt[i], wp->pt[i+1]);
415  }
416  vp = wp;
417  wp = BU_LIST_PNEXT(bn_vlist, vp);
418  }
419 
420  if (vp->nused <= 0) {
421  /* this shouldn't happen */
422  bu_vls_printf(gedp->ged_result_str, "%s %s: vlist corrupt", argv[0], argv[1]);
423  return GED_ERROR;
424  }
425  vp->nused--;
426 
427  return GED_OK;
428 }
429 
430 
431 /*
432  * Usage:
433  * vdraw read i|color|length|name
434  */
435 static int
436 vdraw_read(void *data, int argc, const char *argv[])
437 {
438  struct ged *gedp = (struct ged *)data;
439  struct bn_vlist *vp;
440  unsigned long uind = 0;
441  int length;
442  static const char *usage = "read i|color|length|name";
443 
444  /* must be wanting help */
445  if (argc == 2) {
446  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
447  return GED_HELP;
448  }
449 
450  if (!gedp->ged_gdp->gd_currVHead) {
451  bu_vls_printf(gedp->ged_result_str, "%s %s: no vlist is currently open.", argv[0], argv[1]);
452  return GED_ERROR;
453  }
454  if (argc < 3) {
455  bu_vls_printf(gedp->ged_result_str, "%s %s: need index to read\n", argv[0], argv[1]);
456  return GED_ERROR;
457  }
458  if (argv[2][0] == 'c') {
459  /* read color of current solid */
460  bu_vls_printf(gedp->ged_result_str, "%.6lx", gedp->ged_gdp->gd_currVHead->vdc_rgb);
461  return GED_OK;
462  }
463  if (argv[2][0] == 'n') {
464  /*read name of currently open solid*/
465  bu_vls_printf(gedp->ged_result_str, "%.89s", gedp->ged_gdp->gd_currVHead->vdc_name);
466  return GED_OK;
467  }
468  if (argv[2][0] == 'l') {
469  /* return length of list */
470  length = 0;
472  while (!BU_LIST_IS_HEAD(vp, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
473  length += vp->nused;
474  vp = BU_LIST_PNEXT(bn_vlist, vp);
475  }
476  bu_vls_printf(gedp->ged_result_str, "%d", length);
477  return GED_OK;
478  }
479  if (sscanf(argv[2], "%lu", &uind) < 1) {
480  bu_vls_printf(gedp->ged_result_str, "%s %s: read index not an integer\n", argv[0], argv[1]);
481  return GED_ERROR;
482  }
483 
484  for (BU_LIST_FOR(vp, bn_vlist, &(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
485  if ((size_t)uind < BN_VLIST_CHUNK) {
486  /* this is the right vlist */
487  break;
488  }
489  if (vp->nused == 0) {
490  /* no point going further */
491  break;
492  }
493  uind -= vp->nused;
494  }
495 
496  /* The comparison to BN_VLIST_CHUNK is to silence covarity */
497  if ((size_t)uind >= vp->nused || uind >= BN_VLIST_CHUNK) {
498  bu_vls_printf(gedp->ged_result_str, "%s %s: read out of range\n", argv[0], argv[1]);
499  return GED_ERROR;
500  }
501 
502  bu_vls_printf(gedp->ged_result_str, "%d %.12e %.12e %.12e",
503  vp->cmd[uind], vp->pt[uind][0],
504  vp->pt[uind][1], vp->pt[uind][2]);
505 
506  return GED_OK;
507 }
508 
509 
510 /*
511  * Usage:
512  * vdraw send
513  */
514 static int
515 vdraw_send(void *data, int argc, const char *argv[])
516 {
517  struct ged *gedp = (struct ged *)data;
518  struct directory *dp;
519  char solid_name [RT_VDRW_MAXNAME+RT_VDRW_PREFIX_LEN+1];
520  int idx;
521  int real_flag;
522 
523  if (argc < 2) {
524  bu_vls_printf(gedp->ged_result_str, "ERROR: missing parameter after [%s]", argv[0]);
525  return GED_ERROR;
526  }
527 
528  if (!gedp->ged_gdp->gd_currVHead) {
529  bu_vls_printf(gedp->ged_result_str, "%s %s: no vlist is currently open.", argv[0], argv[1]);
530  return GED_ERROR;
531  }
532 
533  snprintf(solid_name, RT_VDRW_MAXNAME+RT_VDRW_PREFIX_LEN+1, "%s%s", RT_VDRW_PREFIX, gedp->ged_gdp->gd_currVHead->vdc_name);
534  if ((dp = db_lookup(gedp->ged_wdbp->dbip, solid_name, LOOKUP_QUIET)) == RT_DIR_NULL) {
535  real_flag = 0;
536  } else {
537  real_flag = (dp->d_addr == RT_DIR_PHONY_ADDR) ? 0 : 1;
538  }
539 
540  if (real_flag) {
541  /* solid exists - don't kill */
542  bu_vls_printf(gedp->ged_result_str, "-1");
543  return GED_OK;
544  }
545 
546  /* 0 means OK, -1 means conflict with real solid name */
547  idx = invent_solid(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, gedp->ged_create_vlist_callback, gedp->ged_free_vlist_callback, solid_name, &(gedp->ged_gdp->gd_currVHead->vdc_vhd), gedp->ged_gdp->gd_currVHead->vdc_rgb, 1, 0.0, 0, gedp->freesolid, 0);
548 
549  bu_vls_printf(gedp->ged_result_str, "%d", idx);
550 
551  return GED_OK;
552 }
553 
554 
555 /*
556  * Usage:
557  * vdraw params color|name
558  */
559 static int
560 vdraw_params(void *data, int argc, const char *argv[])
561 {
562  struct ged *gedp = (struct ged *)data;
563  struct vd_curve *rcp;
564  unsigned long rgb;
565  static const char *usage = "color|name args";
566 
567  /* must be wanting help */
568  if (argc == 2) {
569  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
570  return GED_HELP;
571  }
572 
573  if (!gedp->ged_gdp->gd_currVHead) {
574  bu_vls_printf(gedp->ged_result_str, "%s %s: no vlist is currently open.", argv[0], argv[1]);
575  return GED_ERROR;
576  }
577  if (argc < 4) {
578  bu_vls_printf(gedp->ged_result_str, "%s %s: need params to set\n", argv[0], argv[1]);
579  return GED_ERROR;
580  }
581  if (argv[2][0] == 'c') {
582  if (sscanf(argv[3], "%lx", &rgb)>0)
583  gedp->ged_gdp->gd_currVHead->vdc_rgb = rgb;
584  return GED_OK;
585  }
586  if (argv[2][0] == 'n') {
587  /* check for conflicts with existing vlists*/
588  for (BU_LIST_FOR(rcp, vd_curve, gedp->ged_gdp->gd_headVDraw)) {
589  if (!bu_strncmp(rcp->vdc_name, argv[2], RT_VDRW_MAXNAME)) {
590  bu_vls_printf(gedp->ged_result_str, "%s %s: name %.40s is already in use\n", argv[0], argv[1], argv[2]);
591  return GED_ERROR;
592  }
593  }
594  /* otherwise name not yet used */
596 
597  bu_vls_printf(gedp->ged_result_str, "0");
598  return GED_OK;
599  }
600 
601  return GED_OK;
602 }
603 
604 
605 /*
606  * Usage:
607  * vdraw open [name]
608  */
609 static int
610 vdraw_open(void *data, int argc, const char *argv[])
611 {
612  struct ged *gedp = (struct ged *)data;
613  struct vd_curve *rcp;
614  struct bn_vlist *vp;
615  char temp_name[RT_VDRW_MAXNAME+1];
616  static const char *usage = "[name]";
617 
618  if (argc == 2) {
619  if (gedp->ged_gdp->gd_currVHead) {
620  bu_vls_printf(gedp->ged_result_str, "1");
621  return GED_OK;
622  } else {
623  bu_vls_printf(gedp->ged_result_str, "0");
624  return GED_OK;
625  }
626  }
627 
628  if (3 < argc) {
629  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
630  return GED_ERROR;
631  }
632 
633  bu_strlcpy(temp_name, argv[2], RT_VDRW_MAXNAME);
634 
635  gedp->ged_gdp->gd_currVHead = (struct vd_curve *) NULL;
636  for (BU_LIST_FOR(rcp, vd_curve, gedp->ged_gdp->gd_headVDraw)) {
637  if (!bu_strncmp(rcp->vdc_name, temp_name, RT_VDRW_MAXNAME)) {
638  gedp->ged_gdp->gd_currVHead = rcp;
639  break;
640  }
641  }
642 
643  if (!gedp->ged_gdp->gd_currVHead) {
644  /* create new entry */
645  BU_GET(rcp, struct vd_curve);
646  BU_LIST_APPEND(gedp->ged_gdp->gd_headVDraw, &(rcp->l));
647 
648  bu_strlcpy(rcp->vdc_name, temp_name, RT_VDRW_MAXNAME);
649 
650  rcp->vdc_rgb = RT_VDRW_DEF_COLOR;
651  BU_LIST_INIT(&(rcp->vdc_vhd));
652  RT_GET_VLIST(vp);
653  BU_LIST_APPEND(&(rcp->vdc_vhd), &(vp->l));
654  gedp->ged_gdp->gd_currVHead = rcp;
655  /* 1 means new entry */
656  bu_vls_printf(gedp->ged_result_str, "1");
657  return GED_OK;
658  } else {
659  /* entry already existed */
660  if (BU_LIST_IS_EMPTY(&(gedp->ged_gdp->gd_currVHead->vdc_vhd))) {
661  RT_GET_VLIST(vp);
662  BU_LIST_APPEND(&(gedp->ged_gdp->gd_currVHead->vdc_vhd), &(vp->l));
663  }
664  gedp->ged_gdp->gd_currVHead->vdc_name[RT_VDRW_MAXNAME] = '\0'; /*safety*/
665  /* 0 means entry already existed*/
666  bu_vls_printf(gedp->ged_result_str, "0");
667  return GED_OK;
668  }
669 }
670 
671 
672 /*
673  * Usage:
674  * vdraw vlist list
675  * vdraw vlist delete name
676  */
677 static int
678 vdraw_vlist(void *data, int argc, const char *argv[])
679 {
680  struct ged *gedp = (struct ged *)data;
681  struct vd_curve *rcp, *rcp2;
682  static const char *usage = "list\n\tdelete name";
683 
684  /* must be needing help */
685  if (argc < 3 || argc > 4) {
686  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argc>0?argv[0]:"vdraw", argc>1?argv[1]:"vlist", usage);
687  return GED_HELP;
688  }
689 
690  switch (argv[2][0]) {
691  case 'l':
692  for (BU_LIST_FOR(rcp, vd_curve, gedp->ged_gdp->gd_headVDraw)) {
694  bu_vls_strcat(gedp->ged_result_str, " ");
695  }
696 
697  return GED_OK;
698  case 'd':
699  rcp2 = (struct vd_curve *)NULL;
700  for (BU_LIST_FOR(rcp, vd_curve, gedp->ged_gdp->gd_headVDraw)) {
701  if (!bu_strncmp(rcp->vdc_name, argv[3], RT_VDRW_MAXNAME)) {
702  rcp2 = rcp;
703  break;
704  }
705  }
706  if (!rcp2) {
707  bu_vls_printf(gedp->ged_result_str, "%s %s: vlist %.40s not found", argv[0], argv[1], argv[3]);
708  return GED_ERROR;
709  }
710  BU_LIST_DEQUEUE(&(rcp2->l));
711  if (gedp->ged_gdp->gd_currVHead == rcp2) {
712  if (BU_LIST_IS_EMPTY(gedp->ged_gdp->gd_headVDraw)) {
713  gedp->ged_gdp->gd_currVHead = (struct vd_curve *)NULL;
714  } else {
716  }
717  }
718  RT_FREE_VLIST(&(rcp2->vdc_vhd));
719  BU_PUT(rcp2, struct vd_curve);
720  return GED_OK;
721  default:
722  bu_vls_printf(gedp->ged_result_str, "%s %s: unknown option to vdraw vlist", argv[0], argv[1]);
723  return GED_ERROR;
724  }
725 }
726 
727 
728 static int
729 vdraw_cmd(struct ged *gedp, int argc, const char *argv[])
730 {
731  int ret;
732 
733  /**
734  * view draw command table
735  */
736  static struct bu_cmdtab vdraw_cmds[] = {
737  {"write", vdraw_write},
738  {"insert", vdraw_insert},
739  {"delete", vdraw_delete},
740  {"read", vdraw_read},
741  {"send", vdraw_send},
742  {"params", vdraw_params},
743  {"open", vdraw_open},
744  {"vlist", vdraw_vlist},
745  {(const char *)NULL, BU_CMD_NULL}
746  };
747 
748  static const char *usage = "write|insert|delete|read|send|params|open|vlist [args]";
749 
752  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
753 
754  /* initialize result */
755  bu_vls_trunc(gedp->ged_result_str, 0);
756 
757  /* must be wanting help */
758  if (argc == 1) {
759  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
760  return GED_HELP;
761  }
762 
763 
764  if (bu_cmd(vdraw_cmds, argc, argv, 1, gedp, &ret) == BRLCAD_OK)
765  return ret;
766 
767  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
768 
769  return GED_ERROR;
770 }
771 
772 
773 int
774 ged_vdraw(struct ged *gedp, int argc, const char *argv[])
775 {
776  return vdraw_cmd(gedp, argc, argv);
777 }
778 
779 
780 /*
781  * Local Variables:
782  * mode: C
783  * tab-width: 8
784  * indent-tabs-mode: t
785  * c-file-style: "stroustrup"
786  * End:
787  * ex: shiftwidth=4 tabstop=8
788  */
Definition: cmd.h:48
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
Definition: ged.h:296
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
size_t nused
elements 0..nused active
Definition: vlist.h:73
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
struct bu_list l
magic, forw, back
Definition: vlist.h:72
long vdc_rgb
color
Definition: ged.h:299
#define BU_LIST_LAST(structure, hp)
Definition: list.h:306
int cmd[BN_VLIST_CHUNK]
VL_CMD_*.
Definition: vlist.h:74
Definition: ged.h:338
int invent_solid(struct bu_list *hdlp, struct db_i *dbip, void(*callback_create)(struct display_list *), void(*callback_free)(unsigned int, int), char *name, struct bu_list *vhead, long int rgb, int copy, fastf_t transparency, int dmode, struct solid *freesolid, int csoltab)
struct db_i * dbip
Definition: raytrace.h:1266
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define BU_LIST_IS_EMPTY(hp)
Definition: list.h:295
#define GED_CHECK_ARGC_GT_0(_gedp, _argc, _flags)
Definition: ged.h:202
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
int vdraw_insert(void *data, int argc, const char *argv[])
Definition: vdraw.c:240
#define RT_VDRW_DEF_COLOR
Definition: ged.h:295
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
#define BU_CMD_NULL
Definition: cmd.h:37
#define RT_FREE_VLIST(hd)
Definition: raytrace.h:1863
void(* ged_free_vlist_callback)(unsigned int, int)
function to call after freeing a vlist
Definition: ged.h:371
#define BU_LIST_APPEND(old, new)
Definition: list.h:197
#define REV_BU_LIST_FOR(p, structure, hp)
Definition: vdraw.c:115
struct bu_list * gd_headDisplay
head of display list
Definition: ged.h:307
#define GED_ERROR
Definition: ged.h:61
struct solid * freesolid
Definition: ged.h:345
struct bu_list l
Definition: ged.h:297
#define RT_GET_VLIST(p)
Definition: raytrace.h:1860
int bu_strncmp(const char *string1, const char *string2, size_t n)
Definition: str.c:191
COMPLEX data[64]
Definition: fftest.c:34
#define BU_LIST_IS_HEAD(p, hp)
Definition: list.h:322
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
#define BU_LIST_PLAST(structure, p)
Definition: list.h:424
#define LOOKUP_QUIET
Definition: raytrace.h:893
#define bu_strlcpy(dst, src, size)
Definition: str.h:60
#define BRLCAD_OK
Definition: defines.h:71
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
void(* ged_create_vlist_callback)(struct display_list *)
function to call after creating a vlist
Definition: ged.h:370
#define RT_DIR_PHONY_ADDR
Special marker for d_addr field.
Definition: raytrace.h:879
#define BU_LIST_PNEXT(structure, p)
Definition: list.h:422
#define GED_CHECK_DRAWABLE(_gedp, _flags)
Definition: ged.h:129
int bn_decode_vect(vect_t v, const char *str)
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
struct bu_list * gd_headVDraw
head of vdraw list
Definition: ged.h:308
#define RT_VDRW_PREFIX
Definition: ged.h:292
struct bu_vls * ged_result_str
Definition: ged.h:357
#define RT_VDRW_MAXNAME
Definition: ged.h:294
struct ged_drawable * ged_gdp
Definition: ged.h:360
struct bu_list vdc_vhd
head of list of vertices
Definition: ged.h:300
#define BU_LIST_INIT(_hp)
Definition: list.h:148
Definition: vlist.h:71
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define RT_DIR_NULL
Definition: raytrace.h:875
#define GED_HELP
Definition: ged.h:62
int vdraw_delete(void *data, int argc, const char *argv[])
Definition: vdraw.c:332
#define RT_VDRW_PREFIX_LEN
Definition: ged.h:293
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
#define BN_VLIST_CHUNK
Definitions for handling lists of vectors (really vertices, or points) and polygons in 3-space...
Definition: vlist.h:45
point_t pt[BN_VLIST_CHUNK]
associated 3-point/vect
Definition: vlist.h:75
int ged_vdraw(struct ged *gedp, int argc, const char *argv[])
Definition: vdraw.c:774
#define BU_LIST_NOT_HEAD(p, hp)
Definition: list.h:324
struct vd_curve * gd_currVHead
current vdraw head
Definition: ged.h:309
#define BU_LIST_FIRST(structure, hp)
Definition: list.h:312
int bu_cmd(const struct bu_cmdtab *cmds, int argc, const char *argv[], int cmd_index, void *data, int *result)
char vdc_name[RT_VDRW_MAXNAME+1]
name array
Definition: ged.h:298