BRL-CAD
Loading...
Searching...
No Matches
plot3.h
Go to the documentation of this file.
1/* P L O T 3 . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2025 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 bv_plot
21 *
22 * @brief A public-domain UNIX plot library, for 2-D and 3-D plotting in 16-bit
23 * VAX signed integer spaces, or 64-bit IEEE floating point.
24 *
25 * These routines generate "UNIX plot" output (with the addition of 3-D
26 * commands). They behave almost exactly like the regular libplot routines,
27 * except:
28 *
29 * -# These all take a stdio file pointer, and can thus be used to create
30 * multiple plot files simultaneously.
31 * -# There are 3-D versions of most commands.
32 * -# There are IEEE floating point versions of the commands.
33 * -# The names have been changed.
34 *
35 * The 3-D extensions are those of Doug Gwyn, from his System V extensions.
36 *
37 * These are the ascii command letters allocated to various actions. Care has
38 * been taken to consistently match lowercase and uppercase letters.
39 *
40 * @code
41 2d 3d 2df 3df
42 space s S w W
43 move m M o O
44 cont n N q Q
45 point p P x X
46 line l L v V
47 circle c i
48 arc a r
49 linmod f
50 label t
51 erase e
52 color C
53 flush F
54
55 bd gh jk uyz
56 ABDEGHIJKRTUYZ
57
58 @endcode
59 *
60 * The calling sequence is the same as the original Bell Labs routines, with
61 * the exception of the pl_ prefix on the name.
62 *
63 * NOTE: from libbv's perspective, plot3.h is a stand-alone header that does
64 * not use any other library functionality. To use this header without libbv,
65 * define PLOT3_IMPLEMENTATION before including the plot3.h header.
66 * The PLOT_PREFIX_STR mechanism below also can be used to allow
67 * PLOT3_IMPLEMENTATION to be included multiple times without conflict. (TODO
68 * - check if we can use inline instead of static to achieve a similar
69 * result...)
70 *
71 * Of interest: the Plan 9 sources (recently MIT licensed) appear to be
72 * related to the original code that would have formed the conceptual basis for
73 * these routines:
74 *
75 * https://plan9.io/sources/plan9/sys/src/cmd/plot/libplot/
76 *
77 * Don't know if there would be any improvements that could be retrofitted onto
78 * this version, but might be worth looking. In particular, curious if the
79 * spline routine might be useful...
80 */
81/** @{ */
82/** @file plot3.h */
83
84#ifndef PLOT3_H
85#define PLOT3_H
86
87#include "common.h"
88
89#include "vmath.h"
90#include "bu/color.h"
91#include "bu/file.h"
92
93#ifndef PLOT3_EXPORT
94# if defined(PLOT3_DLL_EXPORTS) && defined(PLOT3_DLL_IMPORTS)
95# error "Only PLOT3_DLL_EXPORTS or PLOT3_DLL_IMPORTS can be defined, not both."
96# elif defined(PLOT3_DLL_EXPORTS)
97# define PLOT3_EXPORT COMPILER_DLLEXPORT
98# elif defined(PLOT3_DLL_IMPORTS)
99# define PLOT3_EXPORT COMPILER_DLLIMPORT
100# else
101# define PLOT3_EXPORT
102# endif
103#endif
104
106#define PL_OUTPUT_MODE_BINARY 0
107#define PL_OUTPUT_MODE_TEXT 1
109#if !defined(PLOT_PREFIX_STR)
110# define PLOT_PREFIX_STR plot3_
111#endif
112#define PL_CONCAT2(a, b) a ## b
113#define PL_CONCAT(a, b) PL_CONCAT2(a,b)
114#define PL_ADD_PREFIX(b) PL_CONCAT(PLOT_PREFIX_STR,b)
116/* All linked symbols */
117#define pd_3box PL_ADD_PREFIX(pd_3box)
118#define pd_3cont PL_ADD_PREFIX(pd_3cont)
119#define pd_3line PL_ADD_PREFIX(pd_3line)
120#define pd_3move PL_ADD_PREFIX(pd_3move)
121#define pd_3point PL_ADD_PREFIX(pd_3point)
122#define pd_3space PL_ADD_PREFIX(pd_3space)
123#define pd_arc PL_ADD_PREFIX(pd_arc)
124#define pd_box PL_ADD_PREFIX(pd_box)
125#define pd_circle PL_ADD_PREFIX(pd_circle)
126#define pd_cont PL_ADD_PREFIX(pd_cont)
127#define pd_line PL_ADD_PREFIX(pd_line)
128#define pd_move PL_ADD_PREFIX(pd_move)
129#define pd_point PL_ADD_PREFIX(pd_point)
130#define pd_space PL_ADD_PREFIX(pd_space)
131#define pdv_3box PL_ADD_PREFIX(pdv_3box)
132#define pdv_3cont PL_ADD_PREFIX(pdv_3cont)
133#define pdv_3line PL_ADD_PREFIX(pdv_3line)
134#define pdv_3move PL_ADD_PREFIX(pdv_3move)
135#define pdv_3point PL_ADD_PREFIX(pdv_3point)
136#define pdv_3ray PL_ADD_PREFIX(pdv_3ray)
137#define pdv_3space PL_ADD_PREFIX(pdv_3space)
138#define pl_3box PL_ADD_PREFIX(pl_3box)
139#define pl_3cont PL_ADD_PREFIX(pl_3cont)
140#define pl_3line PL_ADD_PREFIX(pl_3line)
141#define pl_3move PL_ADD_PREFIX(pl_3move)
142#define pl_3point PL_ADD_PREFIX(pl_3point)
143#define pl_3space PL_ADD_PREFIX(pl_3space)
144#define pl_arc PL_ADD_PREFIX(pl_arc)
145#define pl_box PL_ADD_PREFIX(pl_box)
146#define pl_circle PL_ADD_PREFIX(pl_circle)
147#define pl_color PL_ADD_PREFIX(pl_color)
148#define pl_color_buc PL_ADD_PREFIX(pl_color_buc)
149#define pl_cont PL_ADD_PREFIX(pl_cont)
150#define pl_erase PL_ADD_PREFIX(pl_erase)
151#define pl_flush PL_ADD_PREFIX(pl_flush)
152#define pl_getOutputMode PL_ADD_PREFIX(pl_getOutputMode)
153#define pl_label PL_ADD_PREFIX(pl_label)
154#define pl_line PL_ADD_PREFIX(pl_line)
155#define pl_linmod PL_ADD_PREFIX(pl_linmod)
156#define pl_move PL_ADD_PREFIX(pl_move)
157#define pl_point PL_ADD_PREFIX(pl_point)
158#define pl_setOutputMode PL_ADD_PREFIX(pl_setOutputMode)
159#define pl_space PL_ADD_PREFIX(pl_space)
160#define plot3_invalid PL_ADD_PREFIX(plot3_invalid)
162
163PLOT3_EXPORT extern int pl_getOutputMode(void);
164PLOT3_EXPORT extern void pl_setOutputMode(int mode);
165PLOT3_EXPORT extern void pl_point(FILE *plotfp,
166 int x,
167 int y);
168PLOT3_EXPORT extern void pl_line(FILE *plotfp,
169 int fx,
170 int fy,
171 int tx,
172 int ty);
173PLOT3_EXPORT extern void pl_linmod(FILE *plotfp,
174 const char *s);
175PLOT3_EXPORT extern void pl_move(FILE *plotfp,
176 int x,
177 int y);
178PLOT3_EXPORT extern void pl_cont(FILE *plotfp,
179 int x,
180 int y);
181PLOT3_EXPORT extern void pl_label(FILE *plotfp,
182 const char *s);
183PLOT3_EXPORT extern void pl_space(FILE *plotfp,
184 int x_1,
185 int y_1,
186 int x_2,
187 int y_2);
188PLOT3_EXPORT extern void pl_erase(FILE *plotfp);
189PLOT3_EXPORT extern void pl_circle(FILE *plotfp,
190 int x,
191 int y,
192 int r);
193PLOT3_EXPORT extern void pl_arc(FILE *plotfp,
194 int xc,
195 int yc,
196 int x_1,
197 int y_1,
198 int x_2,
199 int y_2);
200PLOT3_EXPORT extern void pl_box(FILE *plotfp,
201 int x_1,
202 int y_1,
203 int x_2,
204 int y_2);
205
206/*
207 * BRL extensions to the UNIX-plot file format.
208 */
209PLOT3_EXPORT extern void pl_color(FILE *plotfp,
210 int r,
211 int g,
212 int b);
213PLOT3_EXPORT extern void pl_color_buc(FILE *plotfp,
214 struct bu_color *c);
215PLOT3_EXPORT extern void pl_flush(FILE *plotfp);
216PLOT3_EXPORT extern void pl_3space(FILE *plotfp,
217 int x_1,
218 int y_1,
219 int z_1,
220 int x_2,
221 int y_2,
222 int z_2);
223PLOT3_EXPORT extern void pl_3point(FILE *plotfp,
224 int x,
225 int y,
226 int z);
227PLOT3_EXPORT extern void pl_3move(FILE *plotfp,
228 int x,
229 int y,
230 int z);
231PLOT3_EXPORT extern void pl_3cont(FILE *plotfp,
232 int x,
233 int y,
234 int z);
235PLOT3_EXPORT extern void pl_3line(FILE *plotfp,
236 int x_1,
237 int y_1,
238 int z_1,
239 int x_2,
240 int y_2,
241 int z_2);
242PLOT3_EXPORT extern void pl_3box(FILE *plotfp,
243 int x_1,
244 int y_1,
245 int z_1,
246 int x_2,
247 int y_2,
248 int z_2);
249
250/* Double floating point versions */
251PLOT3_EXPORT extern void pd_point(FILE *plotfp,
252 double x,
253 double y);
254PLOT3_EXPORT extern void pd_line(FILE *plotfp,
255 double fx,
256 double fy,
257 double tx,
258 double ty);
259PLOT3_EXPORT extern void pd_move(FILE *plotfp,
260 double x,
261 double y);
262PLOT3_EXPORT extern void pd_cont(FILE *plotfp,
263 double x,
264 double y);
265PLOT3_EXPORT extern void pd_space(FILE *plotfp,
266 double x_1,
267 double y_1,
268 double x_2,
269 double y_2);
270PLOT3_EXPORT extern void pd_circle(FILE *plotfp,
271 double x,
272 double y,
273 double r);
274PLOT3_EXPORT extern void pd_arc(FILE *plotfp,
275 double xc,
276 double yc,
277 double x_1,
278 double y_1,
279 double x_2,
280 double y_2);
281PLOT3_EXPORT extern void pd_box(FILE *plotfp,
282 double x_1,
283 double y_1,
284 double x_2,
285 double y_2);
286
287/* Double 3-D both in vector and enumerated versions */
288#ifdef VMATH_H
289PLOT3_EXPORT extern void pdv_3space(FILE *plotfp,
290 const vect_t min,
291 const vect_t max);
292PLOT3_EXPORT extern void pdv_3point(FILE *plotfp,
293 const vect_t pt);
294PLOT3_EXPORT extern void pdv_3move(FILE *plotfp,
295 const vect_t pt);
296PLOT3_EXPORT extern void pdv_3cont(FILE *plotfp,
297 const vect_t pt);
298PLOT3_EXPORT extern void pdv_3line(FILE *plotfp,
299 const vect_t a,
300 const vect_t b);
301PLOT3_EXPORT extern void pdv_3box(FILE *plotfp,
302 const vect_t a,
303 const vect_t b);
304#endif /* VMATH_H */
305PLOT3_EXPORT extern void pd_3space(FILE *plotfp,
306 double x_1,
307 double y_1,
308 double z_1,
309 double x_2,
310 double y_2,
311 double z_2);
312PLOT3_EXPORT extern void pd_3point(FILE *plotfp,
313 double x,
314 double y,
315 double z);
316PLOT3_EXPORT extern void pd_3move(FILE *plotfp,
317 double x,
318 double y,
319 double z);
320PLOT3_EXPORT extern void pd_3cont(FILE *plotfp,
321 double x,
322 double y,
323 double z);
324PLOT3_EXPORT extern void pd_3line(FILE *plotfp,
325 double x_1,
326 double y_1,
327 double z_1,
328 double x_2,
329 double y_2,
330 double z_2);
331PLOT3_EXPORT extern void pd_3box(FILE *plotfp,
332 double x_1,
333 double y_1,
334 double z_1,
335 double x_2,
336 double y_2,
337 double z_2);
338PLOT3_EXPORT extern void pdv_3ray(FILE *fp,
339 const point_t pt,
340 const vect_t dir,
341 double t);
342
343
344PLOT3_EXPORT extern int plot3_invalid(FILE *fp, int mode);
347
348#if defined(PLOT3_IMPLEMENTATION)
349#include <stdio.h>
350#include "bu/cv.h"
351
353
354/* For the sake of efficiency, we trust putc() to write only one byte */
355#define putsi(a) putc(a, plotfp); putc((a>>8), plotfp)
356
357/* Making a common pd_3 to be used in pd_3cont and pd_3move */
358static void
359pd_3(FILE *plotfp, double x, double y, double z, char c)
360{
361 size_t ret;
362 double in[3];
363 unsigned char out[3*8+1];
364
366 in[0] = x;
367 in[1] = y;
368 in[2] = z;
369 bu_cv_htond(&out[1], (unsigned char *)in, 3);
370
371 out[0] = c;
372 ret = fwrite(out, 1, 3*8+1, plotfp);
373 if (ret != 3*8+1) {
374 perror("fwrite");
375 }
376 } else {
377 fprintf(plotfp, "%c %g %g %g\n", c, x, y, z);
378 }
379}
380
381/* Making a common pdv_3 to be used in pdv_3cont and pdv_3move */
382static void
383pdv_3(FILE *plotfp, const fastf_t *pt, char c)
384{
385 size_t ret;
386 unsigned char out[3*8+1];
387
389 bu_cv_htond(&out[1], (unsigned char *)pt, 3);
390
391 out[0] = c;
392 ret = fwrite(out, 1, 3*8+1, plotfp);
393 if (ret != 3*8+1) {
394 perror("fwrite");
395 }
396 } else {
397 fprintf(plotfp, "%c %g %g %g\n", c, V3ARGS(pt));
398 }
399}
400
401/* Making a common pd to be used in pd_cont and pd_move */
402static void
403common_pd(FILE *plotfp, double x, double y, char c)
404{
405 size_t ret;
406 double in[2];
407 unsigned char out[2*8+1];
408
410 in[0] = x;
411 in[1] = y;
412 bu_cv_htond(&out[1], (unsigned char *)in, 2);
413
414 out[0] = c;
415 ret = fwrite(out, 1, 2*8+1, plotfp);
416 if (ret != 2*8+1) {
417 perror("fwrite");
418 }
419 } else {
420 fprintf(plotfp, "%c %g %g\n", c, x, y);
421 }
422}
423
424/* Making a common pl_3 to be used in pl_3cont and pl_3move */
425static void
426pl_3(FILE *plotfp, int x, int y, int z, char c)
427{
429 putc( c, plotfp);
430 putsi(x);
431 putsi(y);
432 putsi(z);
433 } else {
434 fprintf(plotfp, "%c %d %d %d\n", c, x, y, z);
435 }
436}
437
438/*
439 * These interfaces provide the standard UNIX-Plot functionality
440 */
441
442int
443pl_getOutputMode(void) {
444 return pl_outputMode;
445}
446
447void
450}
451
452/**
453 * @brief
454 * plot a point
455 */
456void
457pl_point(FILE *plotfp, int x, int y)
458{
460 putc('p', plotfp);
461 putsi(x);
462 putsi(y);
463 } else {
464 fprintf(plotfp, "p %d %d\n", x, y);
465 }
466}
467
468void
469pl_line(FILE *plotfp, int px1, int py1, int px2, int py2)
470{
472 putc('l', plotfp);
473 putsi(px1);
474 putsi(py1);
475 putsi(px2);
476 putsi(py2);
477 } else {
478 fprintf(plotfp, "l %d %d %d %d\n", px1, py1, px2, py2);
479 }
480}
481
482void
483pl_linmod(FILE *plotfp, const char *s)
484{
486 putc('f', plotfp);
487 while (*s)
488 putc(*s++, plotfp);
489 putc('\n', plotfp);
490 } else {
491 fprintf(plotfp, "f %s\n", s);
492 }
493}
494
495void
496pl_move(FILE *plotfp, int x, int y)
497{
499 putc('m', plotfp);
500 putsi(x);
501 putsi(y);
502 } else {
503 fprintf(plotfp, "m %d %d\n", x, y);
504 }
505}
506
507void
508pl_cont(FILE *plotfp, int x, int y)
509{
511 putc('n', plotfp);
512 putsi(x);
513 putsi(y);
514 } else {
515 fprintf(plotfp, "n %d %d\n", x, y);
516 }
517}
518
519void
520pl_label(FILE *plotfp, const char *s)
521{
523 putc('t', plotfp);
524 while (*s)
525 putc(*s++, plotfp);
526 putc('\n', plotfp);
527 } else {
528 fprintf(plotfp, "t %s\n", s);
529 }
530}
531
532void
533pl_space(FILE *plotfp, int px1, int py1, int px2, int py2)
534{
536 putc('s', plotfp);
537 putsi(px1);
538 putsi(py1);
539 putsi(px2);
540 putsi(py2);
541 } else {
542 fprintf(plotfp, "s %d %d %d %d\n", px1, py1, px2, py2);
543 }
544}
545
546void
547pl_erase(FILE *plotfp)
548{
550 putc('e', plotfp);
551 else
552 fprintf(plotfp, "e\n");
553}
554
555void
556pl_circle(FILE *plotfp, int x, int y, int r)
557{
559 putc('c', plotfp);
560 putsi(x);
561 putsi(y);
562 putsi(r);
563 } else {
564 fprintf(plotfp, "c %d %d %d\n", x, y, r);
565 }
566}
567
568void
569pl_arc(FILE *plotfp, int xc, int yc, int px1, int py1, int px2, int py2)
570{
572 putc('a', plotfp);
573 putsi(xc);
574 putsi(yc);
575 putsi(px1);
576 putsi(py1);
577 putsi(px2);
578 putsi(py2);
579 } else {
580 fprintf(plotfp, "a %d %d %d %d %d %d\n", xc, yc, px1, py1, px2, py2);
581 }
582}
583
584void
585pl_box(FILE *plotfp, int px1, int py1, int px2, int py2)
586{
593}
594
595/*
596 * Here lie the BRL 3-D extensions.
597 */
598
599/* Warning: r, g, b are ints. The output is chars. */
600void
601pl_color(FILE *plotfp, int r, int g, int b)
602{
604 putc('C', plotfp);
605 putc(r, plotfp);
606 putc(g, plotfp);
607 putc(b, plotfp);
608 } else {
609 fprintf(plotfp, "C %d %d %d\n", r, g, b);
610 }
611}
612
613void
614pl_color_buc(FILE *plotfp, struct bu_color *c)
615{
616 int r = 0;
617 int g = 0;
618 int b = 0;
619 (void)bu_color_to_rgb_ints(c, &r, &g, &b);
620 pl_color(plotfp, r, g, b);
621}
622
623void
624pl_flush(FILE *plotfp)
625{
627 putc('F', plotfp);
628 } else {
629 fprintf(plotfp, "F\n");
630 }
631
632 fflush(plotfp);
633}
634
635void
636pl_3space(FILE *plotfp, int px1, int py1, int pz1, int px2, int py2, int pz2)
637{
639 putc('S', plotfp);
640 putsi(px1);
641 putsi(py1);
642 putsi(pz1);
643 putsi(px2);
644 putsi(py2);
645 putsi(pz2);
646 } else {
647 fprintf(plotfp, "S %d %d %d %d %d %d\n", px1, py1, pz1, px2, py2, pz2);
648 }
649}
650
651void
652pl_3point(FILE *plotfp, int x, int y, int z)
653{
654 pl_3(plotfp, x, y, z, 'P'); /* calling common function pl_3 */
655}
656
657void
658pl_3move(FILE *plotfp, int x, int y, int z)
659{
660 pl_3(plotfp, x, y, z, 'M'); /* calling common function pl_3 */
661}
662
663void
664pl_3cont(FILE *plotfp, int x, int y, int z)
665{
666 pl_3(plotfp, x, y, z, 'N'); /* calling common function pl_3 */
667}
668
669void
670pl_3line(FILE *plotfp, int px1, int py1, int pz1, int px2, int py2, int pz2)
671{
673 putc('L', plotfp);
674 putsi(px1);
675 putsi(py1);
676 putsi(pz1);
677 putsi(px2);
678 putsi(py2);
679 putsi(pz2);
680 } else {
681 fprintf(plotfp, "L %d %d %d %d %d %d\n", px1, py1, pz1, px2, py2, pz2);
682 }
683}
684
685void
686pl_3box(FILE *plotfp, int px1, int py1, int pz1, int px2, int py2, int pz2)
687{
689 /* first side */
694 /* across */
696 /* second side */
701 /* front edge */
704 /* bottom back */
707 /* top back */
710}
711
712/*
713 * Double floating point versions
714 */
715
716void
717pd_point(FILE *plotfp, double x, double y)
718{
719 common_pd( plotfp, x, y, 'x'); /* calling common function pd */
720}
721
722void
723pd_line(FILE *plotfp, double px1, double py1, double px2, double py2)
724{
725 size_t ret;
726 double in[4];
727 unsigned char out[4*8+1];
728
730 in[0] = px1;
731 in[1] = py1;
732 in[2] = px2;
733 in[3] = py2;
734 bu_cv_htond(&out[1], (unsigned char *)in, 4);
735
736 out[0] = 'v';
737 ret = fwrite(out, 1, 4*8+1, plotfp);
738 if (ret != 4*8+1) {
739 perror("fwrite");
740 }
741 } else {
742 fprintf(plotfp, "v %g %g %g %g\n", px1, py1, px2, py2);
743 }
744}
745
746/* Note: no pd_linmod(), just use pl_linmod() */
747
748void
749pd_move(FILE *plotfp, double x, double y)
750{
751 common_pd( plotfp, x, y, 'o'); /* calling common function pd */
752}
753
754void
755pd_cont(FILE *plotfp, double x, double y)
756{
757 common_pd( plotfp, x, y, 'q'); /* calling common function pd */
758}
759
760void
761pd_space(FILE *plotfp, double px1, double py1, double px2, double py2)
762{
763 size_t ret;
764 double in[4];
765 unsigned char out[4*8+1];
766
768 in[0] = px1;
769 in[1] = py1;
770 in[2] = px2;
771 in[3] = py2;
772 bu_cv_htond(&out[1], (unsigned char *)in, 4);
773
774 out[0] = 'w';
775 ret = fwrite(out, 1, 4*8+1, plotfp);
776 if (ret != 4*8+1) {
777 perror("fwrite");
778 }
779 } else {
780 fprintf(plotfp, "w %g %g %g %g\n", px1, py1, px2, py2);
781 }
782}
783
784void
785pd_circle(FILE *plotfp, double x, double y, double r)
786{
787 size_t ret;
788 double in[3];
789 unsigned char out[3*8+1];
790
792 in[0] = x;
793 in[1] = y;
794 in[2] = r;
795 bu_cv_htond(&out[1], (unsigned char *)in, 3);
796
797 out[0] = 'i';
798 ret = fwrite(out, 1, 3*8+1, plotfp);
799 if (ret != 3*8+1) {
800 perror("fwrite");
801 }
802 } else {
803 fprintf(plotfp, "i %g %g %g\n", x, y, r);
804 }
805}
806
807void
808pd_arc(FILE *plotfp, double xc, double yc, double px1, double py1, double px2, double py2)
809{
810 size_t ret;
811 double in[6];
812 unsigned char out[6*8+1];
813
815 in[0] = xc;
816 in[1] = yc;
817 in[2] = px1;
818 in[3] = py1;
819 in[4] = px2;
820 in[5] = py2;
821 bu_cv_htond(&out[1], (unsigned char *)in, 6);
822
823 out[0] = 'r';
824 ret = fwrite(out, 1, 6*8+1, plotfp);
825 if (ret != 6*8+1) {
826 perror("fwrite");
827 }
828 } else {
829 fprintf(plotfp, "r %g %g %g %g %g %g\n", xc, yc, px1, py1, px2, py2);
830 }
831}
832
833void
834pd_box(FILE *plotfp, double px1, double py1, double px2, double py2)
835{
842}
843
844/* Double 3-D, both in vector and enumerated versions */
845void
846pdv_3space(FILE *plotfp, const vect_t min, const vect_t max)
847{
848 size_t ret;
849 unsigned char out[6*8+1];
850
852 bu_cv_htond(&out[1], (unsigned char *)min, 3);
853 bu_cv_htond(&out[3*8+1], (unsigned char *)max, 3);
854
855 out[0] = 'W';
856 ret = fwrite(out, 1, 6*8+1, plotfp);
857 if (ret != 6*8+1) {
858 perror("fwrite");
859 }
860 } else {
861 fprintf(plotfp, "W %g %g %g %g %g %g\n", V3ARGS(min), V3ARGS(max));
862 }
863}
864
865void
866pd_3space(FILE *plotfp, double px1, double py1, double pz1, double px2, double py2, double pz2)
867{
868 size_t ret;
869 double in[6];
870 unsigned char out[6*8+1];
871
873 in[0] = px1;
874 in[1] = py1;
875 in[2] = pz1;
876 in[3] = px2;
877 in[4] = py2;
878 in[5] = pz2;
879 bu_cv_htond(&out[1], (unsigned char *)in, 6);
880
881 out[0] = 'W';
882 ret = fwrite(out, 1, 6*8+1, plotfp);
883 if (ret != 6*8+1) {
884 perror("fwrite");
885 }
886 } else {
887 fprintf(plotfp, "W %g %g %g %g %g %g\n", px1, py1, pz1, px2, py2, pz2);
888 }
889}
890
891void
892pdv_3point(FILE *plotfp, const point_t pt)
893{
894 pdv_3(plotfp, pt, 'X'); /* calling common function pdv_3 */
895}
896
897void
898pd_3point(FILE *plotfp, double x, double y, double z)
899{
900 pd_3(plotfp, x, y, z, 'X'); /* calling common function pd_3 */
901}
902
903void
904pdv_3move(FILE *plotfp, const point_t pt)
905{
906 pdv_3(plotfp, pt, 'O'); /* calling common function pdv_3 */
907}
908
909void
910pd_3move(FILE *plotfp, double x, double y, double z)
911{
912 pd_3(plotfp, x, y, z, 'O'); /* calling common function pd_3 */
913}
914
915void
916pdv_3cont(FILE *plotfp, const point_t pt)
917{
918 pdv_3(plotfp, pt, 'Q'); /* calling common function pdv_3 */
919}
920
921void
922pd_3cont(FILE *plotfp, double x, double y, double z)
923{
924 pd_3(plotfp, x, y, z, 'Q'); /* calling common function pd_3 */
925}
926
927void
928pdv_3line(FILE *plotfp, const vect_t a, const vect_t b)
929{
930 size_t ret;
931 unsigned char out[6*8+1];
932
934 bu_cv_htond(&out[1], (unsigned char *)a, 3);
935 bu_cv_htond(&out[3*8+1], (unsigned char *)b, 3);
936
937 out[0] = 'V';
938 ret = fwrite(out, 1, 6*8+1, plotfp);
939 if (ret != 6*8+1) {
940 perror("fwrite");
941 }
942 } else {
943 fprintf(plotfp, "V %g %g %g %g %g %g\n", V3ARGS(a), V3ARGS(b));
944 }
945}
946
947void
948pd_3line(FILE *plotfp, double px1, double py1, double pz1, double px2, double py2, double pz2)
949{
950 size_t ret;
951 double in[6];
952 unsigned char out[6*8+1];
953
955 in[0] = px1;
956 in[1] = py1;
957 in[2] = pz1;
958 in[3] = px2;
959 in[4] = py2;
960 in[5] = pz2;
961 bu_cv_htond(&out[1], (unsigned char *)in, 6);
962
963 out[0] = 'V';
964 ret = fwrite(out, 1, 6*8+1, plotfp);
965 if (ret != 6*8+1) {
966 perror("fwrite");
967 }
968 } else {
969 fprintf(plotfp, "V %g %g %g %g %g %g\n", px1, py1, pz1, px2, py2, pz2);
970 }
971}
972
973void
974pdv_3box(FILE *plotfp, const vect_t a, const vect_t b)
975{
976 pd_3move(plotfp, a[X], a[Y], a[Z]);
977 /* first side */
978 pd_3cont(plotfp, a[X], b[Y], a[Z]);
979 pd_3cont(plotfp, a[X], b[Y], b[Z]);
980 pd_3cont(plotfp, a[X], a[Y], b[Z]);
981 pd_3cont(plotfp, a[X], a[Y], a[Z]);
982 /* across */
983 pd_3cont(plotfp, b[X], a[Y], a[Z]);
984 /* second side */
985 pd_3cont(plotfp, b[X], b[Y], a[Z]);
986 pd_3cont(plotfp, b[X], b[Y], b[Z]);
987 pd_3cont(plotfp, b[X], a[Y], b[Z]);
988 pd_3cont(plotfp, b[X], a[Y], a[Z]);
989 /* front edge */
990 pd_3move(plotfp, a[X], b[Y], a[Z]);
991 pd_3cont(plotfp, b[X], b[Y], a[Z]);
992 /* bottom back */
993 pd_3move(plotfp, a[X], a[Y], b[Z]);
994 pd_3cont(plotfp, b[X], a[Y], b[Z]);
995 /* top back */
996 pd_3move(plotfp, a[X], b[Y], b[Z]);
997 pd_3cont(plotfp, b[X], b[Y], b[Z]);
998}
999
1000void
1001pd_3box(FILE *plotfp, double px1, double py1, double pz1, double px2, double py2, double pz2)
1002{
1004 /* first side */
1009 /* across */
1011 /* second side */
1016 /* front edge */
1019 /* bottom back */
1022 /* top back */
1025}
1026
1027/**
1028 * Draw a ray
1029 */
1030void
1031pdv_3ray(FILE *fp, const point_t pt, const vect_t dir, double t)
1032{
1033 point_t tip;
1034
1035 VJOIN1(tip, pt, t, dir);
1036 pdv_3move(fp, pt);
1037 pdv_3cont(fp, tip);
1038}
1039
1040
1041/*
1042 * Routines to validate a plot file
1043 */
1044
1045static int
1046read_short(FILE *fp, int cnt, int mode)
1047{
1048 if (mode == PL_OUTPUT_MODE_BINARY) {
1049 for (int i = 0; i < cnt * 2; i++) {
1050 if (getc(fp) == EOF)
1051 return 1;
1052 }
1053 return 0;
1054 }
1055 if (mode == PL_OUTPUT_MODE_TEXT) {
1056 int ret;
1057 double val;
1058 for (int i = 0; i < cnt; i++) {
1059 ret = fscanf(fp, "%lf", &val);
1060 if (ret != 1)
1061 return 1;
1062 }
1063 return 0;
1064 }
1065
1066 return 1;
1067}
1068
1069static int
1070read_ieee(FILE *fp, int cnt, int mode)
1071{
1072 size_t ret;
1073 if (mode == PL_OUTPUT_MODE_BINARY) {
1074 for (int i = 0; i < cnt; i++) {
1077 if (ret != 1)
1078 return 1;
1079 }
1080 return 0;
1081 }
1082 if (mode == PL_OUTPUT_MODE_TEXT) {
1083 double val;
1084 for (int i = 0; i < cnt; i++) {
1085 ret = (size_t)fscanf(fp, "%lf", &val);
1086 if (ret != 1)
1087 return 1;
1088 }
1089 return 0;
1090 }
1091 return 1;
1092}
1093
1094static int
1095read_tstring(FILE *fp, int mode)
1096{
1097 int ret;
1098 if (mode == PL_OUTPUT_MODE_BINARY) {
1099 int str_done = 0;
1100 int cc;
1101 while (!feof(fp) && !str_done) {
1102 cc = getc(fp);
1103 if (cc == '\n')
1104 str_done = 1;
1105 }
1106 return 0;
1107 }
1108 if (mode == PL_OUTPUT_MODE_TEXT) {
1109 char carg[256] = {0};
1110 ret = fscanf(fp, "%255s\n", &carg[0]);
1111 if (ret != 1)
1112 return 1;
1113 return 0;
1114 }
1115 return 1;
1116}
1117
1118int
1119plot3_invalid(FILE *fp, int mode)
1120{
1121
1122 /* Only two valid modes */
1124 return 1;
1125 }
1126
1127 /* A non-readable file isn't a valid file */
1128 if (!fp) {
1129 return 1;
1130 }
1131
1132 int i = 0;
1133 int c;
1134 unsigned int tchar = 0;
1135
1136 while (!feof(fp) && (c=getc(fp)) != EOF) {
1137 if (c < 'A' || c > 'z') {
1138 return 1;
1139 }
1140 switch (c) {
1141 case 'C':
1142 // TCHAR, 3, "color"
1143 if (mode == PL_OUTPUT_MODE_BINARY) {
1144 for (i = 0; i < 3; i++) {
1145 if (getc(fp) == EOF)
1146 return 1;
1147 }
1148 }
1149 if (mode == PL_OUTPUT_MODE_TEXT) {
1150 i = fscanf(fp, "%u", &tchar);
1151 if (i != 1)
1152 return 1;
1153 }
1154 break;
1155 case 'F':
1156 // TNONE, 0, "flush"
1157 break;
1158 case 'L':
1159 // TSHORT, 6, "3line"
1160 if (read_short(fp, 6, mode))
1161 return 1;
1162 break;
1163 case 'M':
1164 // TSHORT, 3, "3move"
1165 if (read_short(fp, 3, mode))
1166 return 1;
1167 break;
1168 case 'N':
1169 // TSHORT, 3, "3cont"
1170 if (read_short(fp, 3, mode))
1171 return 1;
1172 break;
1173 case 'O':
1174 // TIEEE, 3, "d_3move"
1175 if (read_ieee(fp, 3, mode))
1176 return 1;
1177 break;
1178 case 'P':
1179 // TSHORT, 3, "3point"
1180 if (read_short(fp, 3, mode))
1181 return 1;
1182 break;
1183 case 'Q':
1184 // TIEEE, 3, "d_3cont"
1185 if (read_ieee(fp, 3, mode))
1186 return 1;
1187 break;
1188 case 'S':
1189 // TSHORT, 6, "3space"
1190 if (read_short(fp, 6, mode))
1191 return 1;
1192 break;
1193 case 'V':
1194 // TIEEE, 6, "d_3line"
1195 if (read_ieee(fp, 6, mode))
1196 return 1;
1197 break;
1198 case 'W':
1199 // TIEEE, 6, "d_3space"
1200 if (read_ieee(fp, 6, mode))
1201 return 1;
1202 break;
1203 case 'X':
1204 // TIEEE, 3, "d_3point"
1205 if (read_ieee(fp, 3, mode))
1206 return 1;
1207 break;
1208 case 'a':
1209 // TSHORT, 6, "arc"
1210 if (read_short(fp, 6, mode))
1211 return 1;
1212 break;
1213 case 'c':
1214 // TSHORT, 3, "circle"
1215 if (read_short(fp, 3, mode))
1216 return 1;
1217 break;
1218 case 'e':
1219 // TNONE, 0, "erase"
1220 break;
1221 case 'f':
1222 // TSTRING, 1, "linmod"
1223 if (read_tstring(fp, mode))
1224 return 1;
1225 break;
1226 case 'i':
1227 // TIEEE, 3, "d_circle"
1228 if (read_ieee(fp, 3, mode))
1229 return 1;
1230 break;
1231 case 'l':
1232 // TSHORT, 4, "line"
1233 if (read_short(fp, 4, mode))
1234 return 1;
1235 break;
1236 case 'm':
1237 // TSHORT, 2, "move"
1238 if (read_short(fp, 2, mode))
1239 return 1;
1240 break;
1241 case 'n':
1242 // TSHORT, 2, "cont"
1243 if (read_short(fp, 2, mode))
1244 return 1;
1245 break;
1246 case 'o':
1247 // TIEEE, 2, "d_move"
1248 if (read_ieee(fp, 2, mode))
1249 return 1;
1250 break;
1251 case 'p':
1252 // TSHORT, 2, "point"
1253 if (read_short(fp, 2, mode))
1254 return 1;
1255 break;
1256 case 'q':
1257 // TIEEE, 2, "d_cont"
1258 if (read_ieee(fp, 2, mode))
1259 return 1;
1260 break;
1261 case 'r':
1262 // TIEEE, 6, "d_arc"
1263 if (read_ieee(fp, 6, mode))
1264 return 1;
1265 break;
1266 case 's':
1267 // TSHORT, 4, "space"
1268 if (read_short(fp, 4, mode))
1269 return 1;
1270 break;
1271 case 't':
1272 // TSTRING, 1, "label"
1273 if (read_tstring(fp, mode))
1274 return 1;
1275 break;
1276 case 'v':
1277 // TIEEE, 4, "d_line"
1278 if (read_ieee(fp, 4, mode))
1279 return 1;
1280 break;
1281 case 'w':
1282 // TIEEE, 4, "d_space"
1283 if (read_ieee(fp, 4, mode))
1284 return 1;
1285 break;
1286 case 'x':
1287 // TIEEE, 2, "d_point"
1288 if (read_ieee(fp, 2, mode))
1289 return 1;
1290 break;
1291 default:
1292 return 1;
1293 break;
1294 };
1295 }
1296
1297 return 0;
1298}
1299
1300#endif // PLOT3_IMPLEMENTATION
1301
1302#endif /* PLOT3_H */
1303
1304/** @} */
1305/*
1306 * Local Variables:
1307 * mode: C
1308 * tab-width: 8
1309 * indent-tabs-mode: t
1310 * c-file-style: "stroustrup"
1311 * End:
1312 * ex: shiftwidth=4 tabstop=8
1313 */
Definition dvec.h:74
Header file for the BRL-CAD common definitions.
int bu_color_to_rgb_ints(const struct bu_color *cp, int *r, int *g, int *b)
#define SIZEOF_NETWORK_DOUBLE
Definition cv.h:100
void bu_cv_htond(unsigned char *out, const unsigned char *in, size_t count)
void float float * fy
Definition tig.h:283
#define pl_3space
Definition plot3.h:144
#define pl_circle
Definition plot3.h:147
#define pl_line
Definition plot3.h:155
#define PL_OUTPUT_MODE_BINARY
Definition plot3.h:107
#define pl_3move
Definition plot3.h:142
#define pdv_3cont
Definition plot3.h:133
#define pd_box
Definition plot3.h:125
#define pd_3line
Definition plot3.h:120
#define pl_3point
Definition plot3.h:143
#define pl_erase
Definition plot3.h:151
#define pl_3box
Definition plot3.h:139
#define pd_3box
Definition plot3.h:118
#define pdv_3line
Definition plot3.h:134
#define pl_color
Definition plot3.h:148
#define pd_space
Definition plot3.h:131
#define pl_point
Definition plot3.h:158
#define pl_flush
Definition plot3.h:152
#define pl_3line
Definition plot3.h:141
#define pl_cont
Definition plot3.h:150
#define pdv_3move
Definition plot3.h:135
#define pl_arc
Definition plot3.h:145
void float float * y
Definition tig.h:73
#define plot3_invalid
Definition plot3.h:161
#define pd_arc
Definition plot3.h:124
void float float float float * tx
Definition tig.h:285
#define pd_3space
Definition plot3.h:123
void int char * mode
Definition tig.h:179
void int char int int double * min
Definition tig.h:182
#define pdv_3box
Definition plot3.h:132
void float * fx
Definition tig.h:282
#define pl_label
Definition plot3.h:154
#define PLOT3_EXPORT
Definition plot3.h:102
#define pd_point
Definition plot3.h:130
#define pl_3cont
Definition plot3.h:140
#define pd_circle
Definition plot3.h:126
#define pdv_3point
Definition plot3.h:136
void float float float float float * ty
Definition tig.h:286
#define pl_linmod
Definition plot3.h:156
#define pl_color_buc
Definition plot3.h:149
void float float float * z
Definition tig.h:90
#define pd_move
Definition plot3.h:129
void int * c
Definition tig.h:139
#define pd_cont
Definition plot3.h:127
#define pl_box
Definition plot3.h:146
#define pl_move
Definition plot3.h:157
#define pl_space
Definition plot3.h:160
#define pdv_3ray
Definition plot3.h:137
#define pl_getOutputMode
Definition plot3.h:153
#define pd_3move
Definition plot3.h:121
void float * x
Definition tig.h:72
#define pl_setOutputMode
Definition plot3.h:159
#define pd_3point
Definition plot3.h:122
#define PL_OUTPUT_MODE_TEXT
Definition plot3.h:108
#define pd_3cont
Definition plot3.h:119
#define pdv_3space
Definition plot3.h:138
#define pd_line
Definition plot3.h:128
fastf_t vect_t[ELEMENTS_PER_VECT]
3-tuple vector
Definition vmath.h:349
double fastf_t
fastest 64-bit (or larger) floating point type
Definition vmath.h:334
#define VJOIN1(o, a, sb, b)
Definition vmath.h:1335
fastf_t point_t[ELEMENTS_PER_POINT]
3-tuple point
Definition vmath.h:355
#define V3ARGS(a)
Definition vmath.h:1543
@ Y
Definition vmath.h:402
@ X
Definition vmath.h:401
@ Z
Definition vmath.h:403
fundamental vector, matrix, quaternion math macros