BRL-CAD
vlist.c
Go to the documentation of this file.
1 /* V L I S T . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1992-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 
21 
22 #include "common.h"
23 
24 #include <stdio.h>
25 #include <string.h>
26 #include <math.h>
27 #include <string.h>
28 #include "bnetwork.h"
29 
30 #include "bu/cv.h"
31 #include "vmath.h"
32 
33 #include "bn.h"
34 #include "raytrace.h"
35 #include "plot3.h"
36 
37 
38 struct bn_vlblock *
39 bn_vlblock_init(struct bu_list *free_vlist_hd, /**< where to get/put free vlists */
40  int max_ent /**< maximum number of entities to get/put */)
41 {
42  struct bn_vlblock *vbp;
43  size_t i;
44 
45  if (!BU_LIST_IS_INITIALIZED(free_vlist_hd))
46  BU_LIST_INIT(free_vlist_hd);
47 
48  BU_ALLOC(vbp, struct bn_vlblock);
49  vbp->magic = BN_VLBLOCK_MAGIC;
51  vbp->max = max_ent;
52  vbp->head = (struct bu_list *)bu_calloc(vbp->max,
53  sizeof(struct bu_list), "head[]");
54  vbp->rgb = (long *)bu_calloc(vbp->max,
55  sizeof(long), "rgb[]");
56 
57  for (i=0; i < vbp->max; i++) {
58  vbp->rgb[i] = 0;
59  BU_LIST_INIT(&(vbp->head[i]));
60  }
61 
62  vbp->rgb[0] = 0xFFFF00L; /* Yellow, default */
63  vbp->rgb[1] = 0xFFFFFFL; /* White */
64  vbp->nused = 2;
65 
66  return vbp;
67 }
68 
69 
70 struct bn_vlblock *
72 {
73  return bn_vlblock_init(&RTG.rtg_vlfree, 32);
74 }
75 
76 
77 void
79 {
80  size_t i;
81 
82  BN_CK_VLBLOCK(vbp);
83  for (i=0; i < vbp->nused; i++) {
84  /* Release any remaining vlist storage */
85  if (vbp->rgb[i] == 0) continue;
86  if (BU_LIST_IS_EMPTY(&(vbp->head[i]))) continue;
87  BN_FREE_VLIST(vbp->free_vlist_hd, &(vbp->head[i]));
88  }
89 
90  bu_free((char *)(vbp->head), "head[]");
91  bu_free((char *)(vbp->rgb), "rgb[]");
92  bu_free((char *)vbp, "bn_vlblock");
93 
94 }
95 
96 
97 struct bu_list *
98 rt_vlblock_find(struct bn_vlblock *vbp, int r, int g, int b)
99 {
100  long newrgb;
101  size_t n;
102  size_t omax; /* old max */
103 
104  BN_CK_VLBLOCK(vbp);
105 
106  newrgb = ((r&0xFF)<<16)|((g&0xFF)<<8)|(b&0xFF);
107 
108  for (n=0; n < vbp->nused; n++) {
109  if (vbp->rgb[n] == newrgb)
110  return &(vbp->head[n]);
111  }
112  if (vbp->nused < vbp->max) {
113  /* Allocate empty slot */
114  n = vbp->nused++;
115  vbp->rgb[n] = newrgb;
116  return &(vbp->head[n]);
117  }
118 
119  /************** enlarge the table ****************/
120  omax = vbp->max;
121  vbp->max *= 2;
122 
123  /* Look for empty lists and mark for use below. */
124  for (n=0; n < omax; n++)
125  if (BU_LIST_IS_EMPTY(&vbp->head[n]))
126  vbp->head[n].forw = BU_LIST_NULL;
127 
128  vbp->head = (struct bu_list *)bu_realloc((void *)vbp->head,
129  vbp->max * sizeof(struct bu_list),
130  "head[]");
131  vbp->rgb = (long *)bu_realloc((void *)vbp->rgb,
132  vbp->max * sizeof(long),
133  "rgb[]");
134 
135  /* re-initialize pointers in lower half */
136  for (n=0; n < omax; n++) {
137  /*
138  * Check to see if list is empty
139  * (i.e. yellow and/or white are not used).
140  * Note - we can't use BU_LIST_IS_EMPTY here because
141  * the addresses of the list heads have possibly changed.
142  */
143  if (vbp->head[n].forw == BU_LIST_NULL) {
144  vbp->head[n].forw = &vbp->head[n];
145  vbp->head[n].back = &vbp->head[n];
146  } else {
147  vbp->head[n].forw->back = &vbp->head[n];
148  vbp->head[n].back->forw = &vbp->head[n];
149  }
150  }
151 
152  /* initialize upper half of memory */
153  for (n=omax; n < vbp->max; n++) {
154  vbp->rgb[n] = 0;
155  BU_LIST_INIT(&vbp->head[n]);
156  }
157 
158  /* here we go again */
159  return rt_vlblock_find(vbp, r, g, b);
160 }
161 
162 const char *
164 {
165  /* rt_vlist_cmd_descriptions contains descriptions of the first
166  * num_described_cmds vlist cmds
167  */
168  const int num_described_cmds = 13;
169  const char *rt_vlist_cmd_descriptions[] = {
170  "line move ",
171  "line draw ",
172  "poly start",
173  "poly move ",
174  "poly draw ",
175  "poly end ",
176  "poly vnorm",
177  "tri start",
178  "tri move",
179  "tri draw",
180  "tri end",
181  "tri vnorm",
182  "point draw"
183  };
184  if (cmd < num_described_cmds) {
185  return rt_vlist_cmd_descriptions[cmd];
186  } else {
187  return "**unknown*";
188  }
189 }
190 
191 int
192 rt_ck_vlist(const struct bu_list *vhead)
193 {
194  register struct bn_vlist *vp;
195  int npts = 0;
196 
197  for (BU_LIST_FOR(vp, bn_vlist, vhead)) {
198  register int i;
199  register int nused = vp->nused;
200  register int *cmd = vp->cmd;
201  register point_t *pt = vp->pt;
202 
203  BN_CK_VLIST(vp);
204  npts += nused;
205 
206  for (i = 0; i < nused; i++, cmd++, pt++) {
207  register int j;
208 
209  for (j=0; j < 3; j++) {
210  /*
211  * If (*pt)[j] is an IEEE NaN, then all comparisons
212  * between it and any genuine number will return
213  * FALSE. This test is formulated so that NaN values
214  * will activate the "else" clause.
215  */
216  if ((*pt)[j] > -INFINITY && (*pt)[j] < INFINITY) {
217  /* Number is good */
218  } else {
219  bu_log(" %s (%g, %g, %g)\n",
221  V3ARGS(*pt));
222  bu_bomb("rt_ck_vlist() bad coordinate value\n");
223  }
224  /* XXX Need a define for largest command number */
225  if (*cmd < 0 || *cmd > BN_VLIST_CMD_MAX) {
226  bu_log("cmd = x%x (%d.)\n", *cmd, *cmd);
227  bu_bomb("rt_ck_vlist() bad vlist command\n");
228  }
229  }
230  }
231  }
232  return npts;
233 }
234 
235 
236 void
237 rt_vlist_copy(struct bu_list *dest, const struct bu_list *src)
238 {
239  struct bn_vlist *vp;
240 
241  for (BU_LIST_FOR(vp, bn_vlist, src)) {
242  register int i;
243  register int nused = vp->nused;
244  register int *cmd = vp->cmd;
245  register point_t *pt = vp->pt;
246  for (i = 0; i < nused; i++, cmd++, pt++) {
247  BN_ADD_VLIST(&RTG.rtg_vlfree, dest, *pt, *cmd);
248  }
249  }
250 }
251 
252 
253 void
255 {
256  register struct bn_vlist *vp;
257 
258  if (!BU_LIST_IS_INITIALIZED(hd)) {
259  BU_LIST_INIT(hd);
260  return;
261  }
262 
263  while (BU_LIST_WHILE(vp, bn_vlist, hd)) {
264  BN_CK_VLIST(vp);
265  BU_LIST_DEQUEUE(&(vp->l));
266  bu_free((char *)vp, "bn_vlist");
267  }
268 }
269 
270 
271 void
273 {
275 }
276 
277 
278 void
279 bn_vlist_rpp(struct bu_list *hd, const point_t minn, const point_t maxx)
280 {
281  point_t p;
282 
283  VSET(p, minn[X], minn[Y], minn[Z]);
285 
286  /* first side */
287  VSET(p, minn[X], maxx[Y], minn[Z]);
289  VSET(p, minn[X], maxx[Y], maxx[Z]);
291  VSET(p, minn[X], minn[Y], maxx[Z]);
293  VSET(p, minn[X], minn[Y], minn[Z]);
295 
296  /* across */
297  VSET(p, maxx[X], minn[Y], minn[Z]);
299 
300  /* second side */
301  VSET(p, maxx[X], maxx[Y], minn[Z]);
303  VSET(p, maxx[X], maxx[Y], maxx[Z]);
305  VSET(p, maxx[X], minn[Y], maxx[Z]);
307  VSET(p, maxx[X], minn[Y], minn[Z]);
309 
310  /* front edge */
311  VSET(p, minn[X], maxx[Y], minn[Z]);
313  VSET(p, maxx[X], maxx[Y], minn[Z]);
315 
316  /* bottom back */
317  VSET(p, minn[X], minn[Y], maxx[Z]);
319  VSET(p, maxx[X], minn[Y], maxx[Z]);
321 
322  /* top back */
323  VSET(p, minn[X], maxx[Y], maxx[Z]);
325  VSET(p, maxx[X], maxx[Y], maxx[Z]);
327  }
328 
329 
330 void
331 rt_vlist_export(struct bu_vls *vls, struct bu_list *hp, const char *name)
332 {
333  register struct bn_vlist *vp;
334  size_t nelem;
335  size_t namelen;
336  size_t nbytes;
337  unsigned char *buf;
338  unsigned char *bp;
339 
340  BU_CK_VLS(vls);
341 
342  /* Count number of element in the vlist */
343  nelem = 0;
344  for (BU_LIST_FOR(vp, bn_vlist, hp)) {
345  nelem += vp->nused;
346  }
347 
348  /* Build output buffer for binary transmission
349  * nelem[4], String[n+1], cmds[nelem*1], pts[3*nelem*8]
350  */
351  namelen = strlen(name)+1;
352  nbytes = namelen + 4 + nelem * (1+ELEMENTS_PER_VECT*SIZEOF_NETWORK_DOUBLE) + 2;
353 
354  /* FIXME: this is pretty much an abuse of vls. should be using
355  * vlb for variable-length byte buffers.
356  */
357  bu_vls_setlen(vls, (int)nbytes);
358  buf = (unsigned char *)bu_vls_addr(vls);
359  *(uint32_t *)buf = htonl((uint32_t)nelem);
360  bp = buf+sizeof(uint32_t);
361  bu_strlcpy((char *)bp, name, namelen);
362  bp += namelen;
363 
364  /* Output cmds, as bytes */
365  for (BU_LIST_FOR(vp, bn_vlist, hp)) {
366  register int i;
367  register int nused = vp->nused;
368  register int *cmd = vp->cmd;
369  for (i = 0; i < nused; i++) {
370  *bp++ = *cmd++;
371  }
372  }
373 
374  /* Output points, as three 8-byte doubles */
375  for (BU_LIST_FOR(vp, bn_vlist, hp)) {
376  register int i;
377  register int nused = vp->nused;
378  register point_t *pt = vp->pt;
379 
380  /* must be double for import and export */
381  double point[ELEMENTS_PER_POINT];
382 
383  for (i = 0; i < nused; i++) {
384  VMOVE(point, pt[i]); /* convert fastf_t to double */
385  bu_cv_htond(bp, (unsigned char *)point, ELEMENTS_PER_VECT);
386  bp += ELEMENTS_PER_VECT*SIZEOF_NETWORK_DOUBLE;
387  }
388  }
389 }
390 
391 
392 void
393 rt_vlist_import(struct bu_list *hp, struct bu_vls *namevls, const unsigned char *buf)
394 {
395  register const unsigned char *bp;
396  const unsigned char *pp; /* point pointer */
397  size_t nelem;
398  size_t namelen;
399  size_t i;
400 
401  /* must be double for import and export */
402  double point[ELEMENTS_PER_POINT];
403 
404  BU_CK_VLS(namevls);
405 
406  nelem = ntohl(*(uint32_t *)buf);
407  bp = buf+4;
408 
409  namelen = strlen((char *)bp)+1;
410  bu_vls_strncpy(namevls, (char *)bp, namelen);
411  bp += namelen;
412 
413  pp = bp + nelem*1;
414 
415  for (i=0; i < nelem; i++) {
416  int cmd;
417 
418  cmd = *bp++;
419  bu_cv_ntohd((unsigned char *)point, pp, ELEMENTS_PER_POINT);
420  pp += ELEMENTS_PER_POINT*SIZEOF_NETWORK_DOUBLE;
421  BN_ADD_VLIST(&RTG.rtg_vlfree, hp, point, cmd);
422  }
423 }
424 
425 
426 void
427 rt_plot_vlblock(FILE *fp, const struct bn_vlblock *vbp)
428 {
429  size_t i;
430 
431  BN_CK_VLBLOCK(vbp);
432 
433  for (i=0; i < vbp->nused; i++) {
434  if (vbp->rgb[i] == 0) continue;
435  if (BU_LIST_IS_EMPTY(&(vbp->head[i]))) continue;
436  pl_color(fp,
437  (vbp->rgb[i]>>16) & 0xFF,
438  (vbp->rgb[i]>> 8) & 0xFF,
439  (vbp->rgb[i]) & 0xFF);
440  rt_vlist_to_uplot(fp, &(vbp->head[i]));
441  }
442 }
443 
444 
445 void
446 rt_vlist_to_uplot(FILE *fp, const struct bu_list *vhead)
447 {
448  register struct bn_vlist *vp;
449 
450  for (BU_LIST_FOR(vp, bn_vlist, vhead)) {
451  register int i;
452  register int nused = vp->nused;
453  register const int *cmd = vp->cmd;
454  register point_t *pt = vp->pt;
455 
456  for (i = 0; i < nused; i++, cmd++, pt++) {
457  switch (*cmd) {
458  case BN_VLIST_POLY_START:
459  case BN_VLIST_TRI_START:
460  break;
461  case BN_VLIST_POLY_MOVE:
462  case BN_VLIST_LINE_MOVE:
463  case BN_VLIST_TRI_MOVE:
464  pdv_3move(fp, *pt);
465  break;
466  case BN_VLIST_POLY_DRAW:
467  case BN_VLIST_POLY_END:
468  case BN_VLIST_LINE_DRAW:
469  case BN_VLIST_TRI_DRAW:
470  case BN_VLIST_TRI_END:
471  pdv_3cont(fp, *pt);
472  break;
473  default:
474  bu_log("rt_vlist_to_uplot: unknown vlist cmd x%x\n",
475  *cmd);
476  }
477  }
478  }
479 }
480 
481 
482 #define TBAD 0 /* no such command */
483 #define TNONE 1 /* no arguments */
484 #define TSHORT 2 /* Vax 16-bit short */
485 #define TIEEE 3 /* IEEE 64-bit floating */
486 #define TCHAR 4 /* unsigned chars */
487 #define TSTRING 5 /* linefeed terminated string */
488 
489 struct uplot {
490  int targ; /* type of args */
491  int narg; /* number or args */
492  char desc[14]; /* description */
493 };
494 static const struct uplot rt_uplot_error = { 0, 0, "error" };
495 static const struct uplot rt_uplot_letters[] = {
496  /*A*/ { 0, 0, "" },
497  /*B*/ { 0, 0, "" },
498  /*C*/ { TCHAR, 3, "color" },
499  /*D*/ { 0, 0, "" },
500  /*E*/ { 0, 0, "" },
501  /*F*/ { TNONE, 0, "flush" },
502  /*G*/ { 0, 0, "" },
503  /*H*/ { 0, 0, "" },
504  /*I*/ { 0, 0, "" },
505  /*J*/ { 0, 0, "" },
506  /*K*/ { 0, 0, "" },
507  /*L*/ { TSHORT, 6, "3line" },
508  /*M*/ { TSHORT, 3, "3move" },
509  /*N*/ { TSHORT, 3, "3cont" },
510  /*O*/ { TIEEE, 3, "d_3move" },
511  /*P*/ { TSHORT, 3, "3point" },
512  /*Q*/ { TIEEE, 3, "d_3cont" },
513  /*R*/ { 0, 0, "" },
514  /*S*/ { TSHORT, 6, "3space" },
515  /*T*/ { 0, 0, "" },
516  /*U*/ { 0, 0, "" },
517  /*V*/ { TIEEE, 6, "d_3line" },
518  /*W*/ { TIEEE, 6, "d_3space" },
519  /*X*/ { TIEEE, 3, "d_3point" },
520  /*Y*/ { 0, 0, "" },
521  /*Z*/ { 0, 0, "" },
522  /*[*/ { 0, 0, "" },
523  /*\*/ { 0, 0, "" },
524  /*]*/ { 0, 0, "" },
525  /*^*/ { 0, 0, "" },
526  /*_*/ { 0, 0, "" },
527  /*`*/ { 0, 0, "" },
528  /*a*/ { TSHORT, 6, "arc" },
529  /*b*/ { 0, 0, "" },
530  /*c*/ { TSHORT, 3, "circle" },
531  /*d*/ { 0, 0, "" },
532  /*e*/ { TNONE, 0, "erase" },
533  /*f*/ { TSTRING, 1, "linmod" },
534  /*g*/ { 0, 0, "" },
535  /*h*/ { 0, 0, "" },
536  /*i*/ { TIEEE, 3, "d_circle" },
537  /*j*/ { 0, 0, "" },
538  /*k*/ { 0, 0, "" },
539  /*l*/ { TSHORT, 4, "line" },
540  /*m*/ { TSHORT, 2, "move" },
541  /*n*/ { TSHORT, 2, "cont" },
542  /*o*/ { TIEEE, 2, "d_move" },
543  /*p*/ { TSHORT, 2, "point" },
544  /*q*/ { TIEEE, 2, "d_cont" },
545  /*r*/ { TIEEE, 6, "d_arc" },
546  /*s*/ { TSHORT, 4, "space" },
547  /*t*/ { TSTRING, 1, "label" },
548  /*u*/ { 0, 0, "" },
549  /*v*/ { TIEEE, 4, "d_line" },
550  /*w*/ { TIEEE, 4, "d_space" },
551  /*x*/ { TIEEE, 2, "d_point" },
552  /*y*/ { 0, 0, "" },
553  /*z*/ { 0, 0, "" }
554 };
555 
556 
557 /**
558  * Read VAX-order 16-bit number
559  */
560 static int
561 getshort(FILE *fp)
562 {
563  register long v, w;
564 
565  v = getc(fp);
566  v |= (getc(fp)<<8); /* order is important! */
567 
568  /* worry about sign extension - sigh */
569  if (v <= 0x7FFF) return v;
570  w = -1;
571  w &= ~0x7FFF;
572  return w | v;
573 }
574 
575 
576 static void
577 rt_uplot_get_args(FILE *fp, const struct uplot *up, char *carg, fastf_t *arg)
578 {
579  size_t ret;
580  int i, j;
581  int cc = 0;
582  char inbuf[SIZEOF_NETWORK_DOUBLE] = {'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'};
583 
584  for (i = 0; i < up->narg; i++) {
585  switch (up->targ) {
586  case TSHORT:
587  arg[i] = getshort(fp);
588  break;
589  case TIEEE:
590  {
591  double scan;
592  ret = fread(inbuf, SIZEOF_NETWORK_DOUBLE, 1, fp);
593  if (ret != 1)
594  bu_log("WARNING: uplot read failure\n");
595  bu_cv_ntohd((unsigned char *)&scan, (unsigned char *)inbuf, 1);
596  arg[i] = scan; /* convert double to fastf_t */
597  break;
598  }
599  case TSTRING:
600  j = 0;
601  while (!feof(fp) &&
602  (cc = getc(fp)) != '\n')
603  carg[j++] = cc;
604  carg[j] = '\0';
605  break;
606  case TCHAR:
607  cc = getc(fp);
608  if (cc == EOF)
609  return;
610 
611  carg[i] = cc;
612  arg[i] = 0;
613  break;
614  case TNONE:
615  default:
616  arg[i] = 0; /* ? */
617  break;
618  }
619  }
620 }
621 
622 
623 static void
624 rt_uplot_get_text_args(FILE *fp, const struct uplot *up, char *carg, fastf_t *arg)
625 {
626  int ret;
627  int i = 0;
628  unsigned int tchar = 0;
629  double val;
630 
631  for (i = 0; i < up->narg; i++) {
632  switch (up->targ) {
633  case TSHORT:
634  ret = fscanf(fp, "%lf", &val);
635  if (ret != 1)
636  bu_log("WARNING: uplot short input failure\n");
637  else
638  arg[i] = val;
639  break;
640  case TIEEE:
641  ret = fscanf(fp, "%lf", &val);
642  if (ret != 1)
643  bu_log("WARNING: uplot floating point input failure\n");
644  else
645  arg[i] = val;
646  break;
647  case TSTRING:
648  ret = fscanf(fp, "%256s\n", &carg[0]);
649  if (ret != 1)
650  bu_log("WARNING: uplot string input failure\n");
651  break;
652  case TCHAR:
653  ret = fscanf(fp, "%u", &tchar);
654  if (ret != 1)
655  bu_log("WARNING: uplot character input failure\n");
656  if (tchar > 255) tchar = 255;
657  carg[i] = tchar;
658  arg[i] = 0;
659  break;
660  case TNONE:
661  default:
662  arg[i] = 0; /* ? */
663  break;
664  }
665  }
666 }
667 
668 
669 int
670 rt_process_uplot_value(register struct bu_list **vhead,
671  struct bn_vlblock *vbp,
672  FILE *fp,
673  register int c,
674  double char_size,
675  int mode)
676 {
677  mat_t mat;
678  const struct uplot *up;
679 #define CARG_LEN 256
680 #define ARG_LEN 6
681  char carg[CARG_LEN];
682  fastf_t arg[ARG_LEN];
683  vect_t a, b;
684  point_t last_pos;
685  static point_t lpnt; /* last point of a move/draw series */
686  static int moved = 0; /* moved since color change */
687 
688  memset(carg, 0, sizeof(char)*CARG_LEN);
689  memset(arg, 0, sizeof(fastf_t)*ARG_LEN);
690 #undef ARG_LEN
691 #undef CARG_LEN
692 
693 
694  /* look it up */
695  if (c < 'A' || c > 'z') {
696  up = &rt_uplot_error;
697  } else {
698  up = &rt_uplot_letters[ c - 'A' ];
699  }
700 
701  if (up->targ == TBAD) {
702  fprintf(stderr, "Lee : Bad command '%c' (0x%02x)\n", c, c);
703  return -1;
704  }
705 
706  if (up->narg > 0) {
707  if (mode == PL_OUTPUT_MODE_BINARY)
708  rt_uplot_get_args(fp, up, carg, arg);
709  else
710  rt_uplot_get_text_args(fp, up, carg, arg);
711  }
712 
713  switch (c) {
714  case 's':
715  case 'w':
716  case 'S':
717  case 'W':
718  /* Space commands, do nothing. */
719  break;
720  case 'm':
721  case 'o':
722  /* 2-D move */
723  arg[Z] = 0;
724  BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE);
725  VMOVE(lpnt, arg);
726  moved = 1;
727  break;
728  case 'M':
729  case 'O':
730  /* 3-D move */
731  BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE);
732  VMOVE(lpnt, arg);
733  moved = 1;
734  break;
735  case 'n':
736  case 'q':
737  /*
738  * If no move command was issued since the last color
739  * change, insert one now using the last point from a
740  * move/draw.
741  */
742  if (!moved) {
743  BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, lpnt, BN_VLIST_LINE_MOVE);
744  moved = 1;
745  }
746 
747  /* 2-D draw */
748  arg[Z] = 0;
749  BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW);
750  VMOVE(lpnt, arg);
751  break;
752  case 'N':
753  case 'Q':
754  /*
755  * If no move command was issued since the last color
756  * change, insert one now using the last point from a
757  * move/draw.
758  */
759  if (!moved) {
760  BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, lpnt, BN_VLIST_LINE_MOVE);
761  moved = 1;
762  }
763 
764  /* 3-D draw */
765  BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW);
766  VMOVE(lpnt, arg);
767  break;
768  case 'l':
769  case 'v':
770  /* 2-D line */
771  VSET(a, arg[0], arg[1], 0.0);
772  VSET(b, arg[2], arg[3], 0.0);
775  break;
776  case 'L':
777  case 'V':
778  /* 3-D line */
779  VSET(a, arg[0], arg[1], arg[2]);
780  VSET(b, arg[3], arg[4], arg[5]);
783  break;
784  case 'p':
785  case 'x':
786  /* 2-D point */
787  arg[Z] = 0;
788  BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE);
789  BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW);
790  break;
791  case 'P':
792  case 'X':
793  /* 3-D point */
794  BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE);
795  BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW);
796  break;
797  case 'C':
798  /* Color */
799  *vhead = rt_vlblock_find(vbp,
800  carg[0], carg[1], carg[2]);
801  moved = 0;
802  break;
803  case 't':
804  /* Text string */
805  MAT_IDN(mat);
806  if (BU_LIST_NON_EMPTY(*vhead)) {
807  struct bn_vlist *vlp;
808  /* Use coordinates of last op */
809  vlp = BU_LIST_LAST(bn_vlist, *vhead);
810  VMOVE(last_pos, vlp->pt[vlp->nused-1]);
811  } else {
812  VSETALL(last_pos, 0);
813  }
814  bn_vlist_3string(*vhead, vbp->free_vlist_hd, carg, last_pos, mat, char_size);
815  break;
816  }
817 
818  return 0;
819 }
820 
821 
822 int
823 rt_uplot_to_vlist(struct bn_vlblock *vbp, register FILE *fp, double char_size, int mode)
824 {
825  struct bu_list *vhead;
826  register int c;
827 
828  vhead = rt_vlblock_find(vbp, 0xFF, 0xFF, 0x00); /* Yellow */
829 
830  while (!feof(fp) && (c=getc(fp)) != EOF) {
831  int ret;
832 
833  /* pass the address of vhead so it can be updated */
834  ret = rt_process_uplot_value(&vhead,
835  vbp,
836  fp,
837  c,
838  char_size,
839  mode);
840  if (ret)
841  return ret;
842  }
843 
844  return 0;
845 }
846 
847 
848 void
849 rt_label_vlist_verts(struct bn_vlblock *vbp, struct bu_list *src, fastf_t *mat, double sz, double mm2local)
850 {
851  struct bn_vlist *vp;
852  struct bu_list *vhead;
853  char label[256];
854 
855  vhead = rt_vlblock_find(vbp, 255, 255, 255); /* white */
856 
857  for (BU_LIST_FOR(vp, bn_vlist, src)) {
858  register int i;
859  register int nused = vp->nused;
860  register int *cmd = vp->cmd;
861  register point_t *pt = vp->pt;
862  for (i = 0; i < nused; i++, cmd++, pt++) {
863  /* XXX Skip polygon markers? */
864  sprintf(label, " %g, %g, %g",
865  (*pt)[0]*mm2local, (*pt)[1]*mm2local, (*pt)[2]*mm2local);
866  bn_vlist_3string(vhead, vbp->free_vlist_hd, label, (*pt), mat, sz);
867  }
868  }
869 }
870 
871 
872 /*
873  * Local Variables:
874  * mode: C
875  * tab-width: 8
876  * indent-tabs-mode: t
877  * c-file-style: "stroustrup"
878  * End:
879  * ex: shiftwidth=4 tabstop=8
880  */
Definition: db_flip.c:35
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
void rt_label_vlist_verts(struct bn_vlblock *vbp, struct bu_list *src, fastf_t *mat, double sz, double mm2local)
Definition: vlist.c:849
size_t nused
elements 0..nused active
Definition: vlist.h:73
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
Definition: vlist.c:489
struct bu_list l
magic, forw, back
Definition: vlist.h:72
#define SIZEOF_NETWORK_DOUBLE
Definition: cv.h:48
int rt_process_uplot_value(register struct bu_list **vhead, struct bn_vlblock *vbp, FILE *fp, register int c, double char_size, int mode)
Definition: vlist.c:670
void rt_vlblock_free(struct bn_vlblock *vbp)
Definition: vlist.c:78
Definition: list.h:118
#define BU_LIST_LAST(structure, hp)
Definition: list.h:306
#define ARG_LEN
void pdv_3move(register FILE *plotfp, const fastf_t *pt)
Definition: plot3.c:618
int cmd[BN_VLIST_CHUNK]
VL_CMD_*.
Definition: vlist.h:74
Definition: clone.c:90
struct bu_list rtg_vlfree
head of bn_vlist freelist
Definition: raytrace.h:1698
#define VSET(a, b, c, d)
Definition: color.c:53
#define VSETALL(a, s)
Definition: color.c:54
#define BU_LIST_IS_EMPTY(hp)
Definition: list.h:295
size_t max
Definition: vlist.h:172
#define BU_LIST_IS_INITIALIZED(_hp)
Definition: list.h:175
void rt_vlist_import(struct bu_list *hp, struct bu_vls *namevls, const unsigned char *buf)
Definition: vlist.c:393
void rt_vlist_to_uplot(FILE *fp, const struct bu_list *vhead)
Definition: vlist.c:446
#define CARG_LEN
void bu_vls_strncpy(struct bu_vls *vp, const char *s, size_t n)
Definition: vls.c:339
void rt_vlist_copy(struct bu_list *dest, const struct bu_list *src)
Definition: vlist.c:237
void rt_vlist_cleanup(void)
Definition: vlist.c:272
Header file for the BRL-CAD common definitions.
const char * rt_vlist_get_cmd_description(int cmd)
Definition: vlist.c:163
long * rgb
rgb[max] variable size array
Definition: vlist.h:173
struct bn_vlblock * rt_vlblock_init(void)
Definition: vlist.c:71
void bu_cv_htond(unsigned char *out, const unsigned char *in, size_t count)
#define BU_LIST_NON_EMPTY(hp)
Definition: list.h:296
struct bu_list * head
head[max] variable size array
Definition: vlist.h:174
#define TCHAR
Definition: vlist.c:486
#define BN_FREE_VLIST(_free_hd, hd)
Definition: vlist.h:118
#define BN_VLIST_POLY_MOVE
move to first poly vertex
Definition: vlist.h:85
struct bu_list * rt_vlblock_find(struct bn_vlblock *vbp, int r, int g, int b)
Definition: vlist.c:98
Definition: color.c:49
#define BU_CK_VLS(_vp)
Definition: vls.h:69
void * memset(void *s, int c, size_t n)
int narg
Definition: vlist.c:491
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
uint32_t magic
Definition: vlist.h:170
#define BN_VLIST_POLY_START
pt[] has surface normal
Definition: vlist.h:84
#define BN_VLIST_LINE_MOVE
Definition: vlist.h:82
#define bu_strlcpy(dst, src, size)
Definition: str.h:60
#define V3ARGS(a)
Definition: color.c:56
#define TSTRING
Definition: vlist.c:487
unsigned char * bp
Definition: rot.c:56
struct bu_list * back
"back", "last"
Definition: list.h:121
#define TSHORT
Definition: vlist.c:484
void bn_vlist_rpp(struct bu_list *hd, const point_t minn, const point_t maxx)
Definition: vlist.c:279
#define BN_VLIST_LINE_DRAW
Definition: vlist.h:83
#define BN_ADD_VLIST(_free_hd, _dest_hd, pnt, draw)
Definition: vlist.h:123
Coord * point
Definition: chull3d.cpp:52
void pdv_3cont(register FILE *plotfp, const fastf_t *pt)
Definition: plot3.c:630
#define BN_VLBLOCK_MAGIC
Definition: magic.h:76
void * bu_realloc(void *ptr, size_t siz, const char *str)
#define BN_VLIST_POLY_DRAW
subsequent poly vertex
Definition: vlist.h:86
#define TBAD
Definition: vlist.c:482
void rt_vlist_export(struct bu_vls *vls, struct bu_list *hp, const char *name)
Definition: vlist.c:331
void bn_vlist_3string(struct bu_list *vhead, struct bu_list *free_hd, const char *string, const point_t origin, const mat_t rot, double scale)
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bn_vlblock * bn_vlblock_init(struct bu_list *free_vlist_hd, int max_ent)
Definition: vlist.c:39
void bn_vlist_cleanup(struct bu_list *hd)
Definition: vlist.c:254
#define BN_VLIST_TRI_END
last vert (repeats 1st), draw poly
Definition: vlist.h:92
#define BU_LIST_WHILE(p, structure, hp)
Definition: list.h:410
void pl_color(register FILE *plotfp, int r, int g, int b)
Definition: plot3.c:325
#define BN_VLIST_CMD_MAX
Max command number.
Definition: vlist.h:97
char desc[14]
Definition: vlist.c:492
#define BN_CK_VLBLOCK(_p)
Definition: vlist.h:177
#define BN_VLIST_TRI_START
pt[] has surface normal
Definition: vlist.h:89
int rt_uplot_to_vlist(struct bn_vlblock *vbp, register FILE *fp, double char_size, int mode)
Definition: vlist.c:823
#define BU_LIST_INIT(_hp)
Definition: list.h:148
#define BN_CK_VLIST(_p)
Definition: vlist.h:78
void bu_cv_ntohd(unsigned char *out, const unsigned char *in, size_t count)
Definition: vlist.h:71
#define BN_VLIST_POLY_END
last vert (repeats 1st), draw poly
Definition: vlist.h:87
ustring label
#define BN_VLIST_TRI_DRAW
subsequent triangle vertex
Definition: vlist.h:91
Definition: color.c:51
#define BU_LIST_NULL
Definition: list.h:124
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
int targ
Definition: vlist.c:490
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
struct bu_list * forw
"forward", "next"
Definition: list.h:120
struct bu_list * free_vlist_hd
where to get/put free vlists
Definition: vlist.h:175
point_t pt[BN_VLIST_CHUNK]
associated 3-point/vect
Definition: vlist.h:75
void bu_vls_setlen(struct bu_vls *vp, size_t newlen)
Definition: vls.c:176
Definition: vls.h:56
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
double fastf_t
Definition: defines.h:300
#define TNONE
Definition: vlist.c:483
void rt_plot_vlblock(FILE *fp, const struct bn_vlblock *vbp)
Definition: vlist.c:427
int rt_ck_vlist(const struct bu_list *vhead)
Definition: vlist.c:192
Definition: color.c:50
size_t nused
Definition: vlist.h:171
#define TIEEE
Definition: vlist.c:485
struct rt_g RTG
Definition: globals.c:39
#define BN_VLIST_TRI_MOVE
move to first triangle vertex
Definition: vlist.h:90