BRL-CAD
view_obj.c
Go to the documentation of this file.
1 /* V I E W _ O B J . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1997-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/view_obj.c
23  *
24  * A view object contains the attributes and methods for controlling
25  * viewing transformations.
26  *
27  */
28 /** @} */
29 
30 #include "common.h"
31 
32 #include <string.h>
33 #include <math.h>
34 
35 #include "tcl.h"
36 
37 
38 #include "bn.h"
39 #include "bu/cmd.h"
40 #include "bu/units.h"
41 #include "vmath.h"
42 #include "ged.h"
43 #include "obj.h"
44 
45 
46 /* FIXME: this should not exist. pass from application code, not
47  * library global.
48  */
49 struct view_obj HeadViewObj; /* head of view object list */
50 
51 
52 static void
53 vo_deleteProc(void *clientData)
54 {
55  struct view_obj *vop = (struct view_obj *)clientData;
56 
57  /* free observers */
58  bu_observer_free(&vop->vo_observers);
59 
60  bu_vls_free(&vop->vo_name);
61  BU_LIST_DEQUEUE(&vop->l);
62  BU_PUT(vop, struct view_obj);
63 }
64 
65 
66 void
67 vo_update(struct view_obj *vop,
68  int oflag)
69 {
70  vect_t work, work1;
71  vect_t temp, temp1;
72 
73  /* set up the view matrix */
74  bn_mat_mul(vop->vo_model2view, vop->vo_rotation, vop->vo_center);
75  vop->vo_model2view[15] = vop->vo_scale;
76 
77  /* XXX validation needs to occur before here to make sure we're
78  * not attempting to invert a singular matrix.
79  */
80  bn_mat_inv(vop->vo_view2model, vop->vo_model2view);
81 
82  /* Find current azimuth, elevation, and twist angles */
83  VSET(work, 0.0, 0.0, 1.0); /* view z-direction */
84  MAT4X3VEC(temp, vop->vo_view2model, work);
85  VSET(work1, 1.0, 0.0, 0.0); /* view x-direction */
86  MAT4X3VEC(temp1, vop->vo_view2model, work1);
87 
88  /* calculate angles using accuracy of 0.005, since display
89  * shows 2 digits right of decimal point */
90  bn_aet_vec(&vop->vo_aet[0],
91  &vop->vo_aet[1],
92  &vop->vo_aet[2],
93  temp, temp1, (fastf_t)0.005);
94 
95  /* Force azimuth range to be [0, 360] */
96  if ((NEAR_EQUAL(vop->vo_aet[1], 90.0, (fastf_t)0.005) ||
97  NEAR_EQUAL(vop->vo_aet[1], -90.0, (fastf_t)0.005)) &&
98  vop->vo_aet[0] < 0 &&
99  !NEAR_ZERO(vop->vo_aet[0], (fastf_t)0.005))
100  vop->vo_aet[0] += 360.0;
101  else if (NEAR_ZERO(vop->vo_aet[0], (fastf_t)0.005))
102  vop->vo_aet[0] = 0.0;
103 
104  /* apply the perspective angle to model2view */
105  bn_mat_mul(vop->vo_pmodel2view, vop->vo_pmat, vop->vo_model2view);
106 
107  if (vop->vo_callback)
108  (*vop->vo_callback)(vop->vo_clientData, vop);
109  else if (oflag)
110  bu_observer_notify(vop->interp, &vop->vo_observers, bu_vls_addr(&vop->vo_name));
111 }
112 
113 
114 void
115 vo_mat_aet(struct view_obj *vop)
116 {
117  mat_t tmat;
118  fastf_t twist;
119  fastf_t c_twist;
120  fastf_t s_twist;
121 
122  bn_mat_angles(vop->vo_rotation,
123  270.0 + vop->vo_aet[1],
124  0.0,
125  270.0 - vop->vo_aet[0]);
126 
127  twist = -vop->vo_aet[2] * DEG2RAD;
128  c_twist = cos(twist);
129  s_twist = sin(twist);
130  bn_mat_zrot(tmat, s_twist, c_twist);
131  bn_mat_mul2(tmat, vop->vo_rotation);
132 }
133 
134 
135 /*
136  * Create an command/object named "oname".
137  */
138 struct view_obj *
139 vo_open_cmd(const char *oname)
140 {
141  struct view_obj *vop;
142 
143  BU_GET(vop, struct view_obj);
144 
145  /* initialize view_obj */
146  bu_vls_init(&vop->vo_name);
147  bu_vls_strcpy(&vop->vo_name, oname);
148  vop->vo_scale = 1.0;
149  vop->vo_size = 2.0 * vop->vo_scale;
150  vop->vo_invSize = 1.0 / vop->vo_size;
151  vop->vo_local2base = 1.0; /* default units - mm */
152  vop->vo_base2local = 1.0; /* default units - mm */
153  VSET(vop->vo_eye_pos, 0.0, 0.0, 1.0);
154  MAT_IDN(vop->vo_rotation);
155  MAT_IDN(vop->vo_center);
156  VSETALL(vop->vo_keypoint, 0.0);
157  vop->vo_coord = 'v';
158  vop->vo_rotate_about = 'v';
159  vo_update(vop, 0);
160  BU_LIST_INIT(&vop->vo_observers.l);
161  vop->vo_callback = (void (*)())0;
162 
163  /* append to list of view_obj's */
164  BU_LIST_APPEND(&HeadViewObj.l, &vop->l);
165 
166  return vop;
167 }
168 
169 
170 /****************** View Object Methods ********************/
171 
172 
173 void
174 vo_size(struct view_obj *vop,
175  fastf_t size)
176 {
177  vop->vo_size = vop->vo_local2base * size;
178  if (vop->vo_size < SQRT_SMALL_FASTF)
179  vop->vo_size = SQRT_SMALL_FASTF;
180  if (vop->vo_size < RT_MINVIEWSIZE)
181  vop->vo_size = RT_MINVIEWSIZE;
182  vop->vo_invSize = 1.0 / vop->vo_size;
183  vop->vo_scale = 0.5 * vop->vo_size;
184  vo_update(vop, 1);
185 }
186 
187 
188 int
189 vo_size_cmd(struct view_obj *vop,
190  int argc,
191  const char *argv[])
192 {
193  struct bu_vls vls;
194 
195  /* intentionally double for scan */
196  double size;
197 
198  /* get view size */
199  if (argc == 1) {
200  bu_vls_init(&vls);
201  bu_vls_printf(&vls, "%g", vop->vo_size * vop->vo_base2local);
202  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
203  bu_vls_free(&vls);
204 
205  return TCL_OK;
206  }
207 
208  /* set view size */
209  if (argc == 2) {
210  if (sscanf(argv[1], "%lf", &size) != 1 || size < SMALL_FASTF) {
211  Tcl_AppendResult(vop->interp, "bad size - ", argv[1], (char *)NULL);
212  return TCL_ERROR;
213  }
214 
215  vo_size(vop, size);
216  return TCL_OK;
217  }
218 
219  /* compose error message */
220  bu_vls_init(&vls);
221  bu_vls_printf(&vls, "helplib_alias vo_size %s", argv[0]);
222  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
223  bu_vls_free(&vls);
224 
225  return TCL_ERROR;
226 }
227 
228 
229 /*
230  * Get or set the view size.
231  *
232  * Usage:
233  * procname size [s]
234  */
235 static int
236 vo_size_tcl(void *clientData,
237  int argc,
238  const char *argv[])
239 {
240  struct view_obj *vop = (struct view_obj *)clientData;
241 
242  return vo_size_cmd(vop, argc-1, argv+1);
243 }
244 
245 
246 int
247 vo_invSize_cmd(struct view_obj *vop,
248  int argc,
249  const char *argv[])
250 {
251  struct bu_vls vls;
252 
253  if (argc == 1) {
254  bu_vls_init(&vls);
255  bu_vls_printf(&vls, "%g", vop->vo_invSize * vop->vo_base2local);
256  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
257  bu_vls_free(&vls);
258 
259  return TCL_OK;
260  }
261 
262  /* compose error message */
263  bu_vls_init(&vls);
264  bu_vls_printf(&vls, "helplib_alias vo_invSize %s", argv[0]);
265  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
266  bu_vls_free(&vls);
267 
268  return TCL_ERROR;
269 }
270 
271 
272 /*
273  * Get the inverse view size.
274  *
275  * Usage:
276  * procname
277  */
278 static int
279 vo_invSize_tcl(void *clientData,
280  int argc,
281  const char *argv[])
282 {
283  struct view_obj *vop = (struct view_obj *)clientData;
284 
285  return vo_invSize_cmd(vop, argc-1, argv+1);
286 }
287 
288 
289 int
290 vo_aet_cmd(struct view_obj *vop,
291  int argc,
292  const char *argv[])
293 {
294  struct bu_vls vls;
295  vect_t aet;
296  int iflag = 0;
297 
298  if (argc == 1) {
299  /* get aet */
300  bu_vls_init(&vls);
301  bn_encode_vect(&vls, vop->vo_aet);
302  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
303  bu_vls_free(&vls);
304 
305  return TCL_OK;
306  }
307 
308  /* Check for -i option */
309  if (argv[1][0] == '-' && argv[1][1] == 'i') {
310  iflag = 1; /* treat arguments as incremental values */
311  ++argv;
312  --argc;
313  }
314 
315  if (argc == 2) {
316  /* set aet */
317  int n;
318 
319  if ((n = bn_decode_vect(aet, argv[1])) == 2)
320  aet[2] = 0;
321  else if (n != 3)
322  goto bad;
323 
324  if (iflag) {
325  VADD2(vop->vo_aet, vop->vo_aet, aet);
326  } else {
327  VMOVE(vop->vo_aet, aet);
328  }
329  vo_mat_aet(vop);
330  vo_update(vop, 1);
331 
332  return TCL_OK;
333  }
334 
335  if (argc == 3 || argc == 4) {
336  double scan[3];
337 
338  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
339  Tcl_AppendResult(vop->interp, "vo_aet: bad azimuth - ", argv[1], "\n", (char *)0);
340  return TCL_ERROR;
341  }
342 
343  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
344  Tcl_AppendResult(vop->interp, "vo_aet: bad elevation - ", argv[2], "\n", (char *)0);
345  return TCL_ERROR;
346  }
347 
348  if (argc == 4) {
349  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
350  Tcl_AppendResult(vop->interp, "vo_aet: bad twist - ", argv[3], "\n", (char *)0);
351  return TCL_ERROR;
352  }
353  } else
354  scan[Z] = 0.0;
355 
356  /* convert double to fastf_t */
357  VMOVE(aet, scan);
358 
359  if (iflag) {
360  VADD2(vop->vo_aet, vop->vo_aet, aet);
361  } else {
362  VMOVE(vop->vo_aet, aet);
363  }
364  vo_mat_aet(vop);
365  vo_update(vop, 1);
366 
367  return TCL_OK;
368  }
369 
370 bad:
371  /* compose error message */
372  bu_vls_init(&vls);
373  bu_vls_printf(&vls, "helplib_alias vo_aet %s", argv[0]);
374  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
375  bu_vls_free(&vls);
376 
377  return TCL_ERROR;
378 }
379 
380 
381 /*
382  * Get or set the azimuth, elevation and twist.
383  *
384  * Usage:
385  * procname ae [[-i] az el [tw]]
386  */
387 static int
388 vo_aet_tcl(void *clientData,
389  int argc,
390  const char *argv[])
391 {
392  struct view_obj *vop = (struct view_obj *)clientData;
393 
394  return vo_aet_cmd(vop, argc-1, argv+1);
395 }
396 
397 
398 int
399 vo_rmat_cmd(struct view_obj *vop,
400  int argc,
401  const char *argv[])
402 {
403  struct bu_vls vls;
404  mat_t rotation;
405 
406  if (argc == 1) {
407  /* get rotation matrix */
408  bu_vls_init(&vls);
409  bn_encode_mat(&vls, vop->vo_rotation);
410  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
411  bu_vls_free(&vls);
412 
413  return TCL_OK;
414  } else if (argc == 2) {
415  /* set rotation matrix */
416  if (bn_decode_mat(rotation, argv[1]) != 16)
417  return TCL_ERROR;
418 
419  MAT_COPY(vop->vo_rotation, rotation);
420  vo_update(vop, 1);
421 
422  return TCL_OK;
423  }
424 
425  /* compose error message */
426  bu_vls_init(&vls);
427  bu_vls_printf(&vls, "helplib_alias vo_rmat %s", argv[0]);
428  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
429  bu_vls_free(&vls);
430 
431  return TCL_ERROR;
432 }
433 
434 
435 /*
436  * Get or set the rotation matrix.
437  *
438  * Usage:
439  * procname
440  */
441 static int
442 vo_rmat_tcl(void *clientData,
443  int argc,
444  const char *argv[])
445 {
446  struct view_obj *vop = (struct view_obj *)clientData;
447 
448  return vo_rmat_cmd(vop, argc-1, argv+1);
449 }
450 
451 
452 void
453 vo_center(struct view_obj *vop,
454  point_t center)
455 {
456  VSCALE(center, center, vop->vo_local2base);
457  MAT_DELTAS_VEC_NEG(vop->vo_center, center);
458  vo_update(vop, 1);
459 }
460 
461 
462 int
463 vo_center_cmd(struct view_obj *vop,
464  int argc,
465  const char *argv[])
466 {
467  point_t center;
468  struct bu_vls vls;
469 
470 
471  /* get view center */
472  if (argc == 1) {
473  MAT_DELTAS_GET_NEG(center, vop->vo_center);
474  VSCALE(center, center, vop->vo_base2local);
475  bu_vls_init(&vls);
476  bn_encode_vect(&vls, center);
477  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
478  bu_vls_free(&vls);
479 
480  return TCL_OK;
481  }
482 
483  /* set view center */
484  if (argc == 2 || argc == 4) {
485  if (argc == 2) {
486  if (bn_decode_vect(center, argv[1]) != 3)
487  goto bad;
488  } else {
489  double scan[3];
490 
491  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
492  Tcl_AppendResult(vop->interp, "vo_center: bad X value - ", argv[1], "\n", (char *)0);
493  return TCL_ERROR;
494  }
495 
496  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
497  Tcl_AppendResult(vop->interp, "vo_center: bad Y value - ", argv[2], "\n", (char *)0);
498  return TCL_ERROR;
499  }
500 
501  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
502  Tcl_AppendResult(vop->interp, "vo_center: bad Z value - ", argv[3], "\n", (char *)0);
503  return TCL_ERROR;
504  }
505 
506  /* convert double to fastf_t */
507  VMOVE(center, scan);
508  }
509 
510  vo_center(vop, center);
511  return TCL_OK;
512  }
513 
514 bad:
515  /* compose error message */
516  bu_vls_init(&vls);
517  bu_vls_printf(&vls, "helplib_alias vo_center %s", argv[0]);
518  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
519  bu_vls_free(&vls);
520 
521  return TCL_ERROR;
522 }
523 
524 
525 /*
526  * Get or set the view center.
527  *
528  * Usage:
529  * procname
530  */
531 static int
532 vo_center_tcl(void *clientData,
533  int argc,
534  const char *argv[])
535 {
536  struct view_obj *vop = (struct view_obj *)clientData;
537 
538  return vo_center_cmd(vop, argc-1, argv+1);
539 }
540 
541 
542 int
543 vo_model2view_cmd(struct view_obj *vop,
544  int argc,
545  const char *argv[])
546 {
547  struct bu_vls vls;
548 
549  if (argc == 1) {
550  bu_vls_init(&vls);
551  bn_encode_mat(&vls, vop->vo_model2view);
552  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
553  bu_vls_free(&vls);
554 
555  return TCL_OK;
556  }
557 
558  /* compose error message */
559  bu_vls_init(&vls);
560  bu_vls_printf(&vls, "helplib_alias vo_model2view %s", argv[0]);
561  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
562  bu_vls_free(&vls);
563 
564  return TCL_ERROR;
565 }
566 
567 
568 /*
569  * Get the model2view matrix.
570  *
571  * Usage:
572  * procname
573  */
574 static int
575 vo_model2view_tcl(void *clientData,
576  int argc,
577  const char *argv[])
578 {
579  struct view_obj *vop = (struct view_obj *)clientData;
580 
581  return vo_model2view_cmd(vop, argc-1, argv+1);
582 }
583 
584 
585 int
586 vo_pmodel2view_cmd(struct view_obj *vop,
587  int argc,
588  const char *argv[])
589 {
590  struct bu_vls vls;
591 
592  if (argc == 1) {
593  bu_vls_init(&vls);
594  bn_encode_mat(&vls, vop->vo_pmodel2view);
595  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
596  bu_vls_free(&vls);
597 
598  return TCL_OK;
599  }
600 
601  /* compose error message */
602  bu_vls_init(&vls);
603  bu_vls_printf(&vls, "helplib_alias vo_pmodel2view %s", argv[0]);
604  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
605  bu_vls_free(&vls);
606 
607  return TCL_ERROR;
608 }
609 
610 
611 /*
612  * Get the pmodel2view matrix.
613  *
614  * Usage:
615  * procname pmodel2view
616  */
617 static int
618 vo_pmodel2view_tcl(void *clientData,
619  int argc,
620  const char *argv[])
621 {
622  struct view_obj *vop = (struct view_obj *)clientData;
623 
624  return vo_pmodel2view_cmd(vop, argc-1, argv+1);
625 }
626 
627 
628 int
629 vo_view2model_cmd(struct view_obj *vop,
630  int argc,
631  const char *argv[])
632 {
633  struct bu_vls vls;
634 
635  if (argc == 1) {
636  bu_vls_init(&vls);
637  bn_encode_mat(&vls, vop->vo_view2model);
638  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
639  bu_vls_free(&vls);
640 
641  return TCL_OK;
642  }
643 
644  /* compose error message */
645  bu_vls_init(&vls);
646  bu_vls_printf(&vls, "helplib_alias vo_view2model %s", argv[0]);
647  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
648  bu_vls_free(&vls);
649 
650  return TCL_ERROR;
651 }
652 
653 
654 /*
655  * Usage:
656  * procname view2model
657  */
658 static int
659 vo_view2model_tcl(void *clientData,
660  int argc,
661  const char *argv[])
662 {
663  struct view_obj *vop = (struct view_obj *)clientData;
664 
665  return vo_view2model_cmd(vop, argc-1, argv+1);
666 }
667 
668 int
669 vo_perspective_cmd(struct view_obj *vop,
670  int argc,
671  const char *argv[])
672 {
673  struct bu_vls vls;
674 
675  /* intentionally double for scan */
676  double perspective;
677 
678  /* get the perspective angle */
679  if (argc == 1) {
680  bu_vls_init(&vls);
681  bu_vls_printf(&vls, "%g", vop->vo_perspective);
682  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
683  bu_vls_free(&vls);
684 
685  return TCL_OK;
686  }
687 
688  /* set the perspective angle */
689  if (argc == 2) {
690  if (sscanf(argv[1], "%lf", &perspective) != 1) {
691  Tcl_AppendResult(vop->interp, "bad perspective angle - ",
692  argv[1], (char *)NULL);
693  return TCL_ERROR;
694  }
695 
696  vop->vo_perspective = perspective;
697 
698  /* This way works, with reasonable Z-clipping */
699  persp_mat(vop->vo_pmat, vop->vo_perspective,
700  1.0, 0.01, 1.0e10, 1.0);
701  vo_update(vop, 1);
702 
703  return TCL_OK;
704  }
705 
706  /* Compose error message */
707  bu_vls_init(&vls);
708  bu_vls_printf(&vls, "helplib_alias vo_perspective %s", argv[0]);
709  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
710  bu_vls_free(&vls);
711 
712  return TCL_ERROR;
713 }
714 
715 
716 /*
717  * Get/set the perspective angle.
718  *
719  * Usage:
720  * procname perspective [angle]
721  */
722 static int
723 vo_perspective_tcl(void *clientData,
724  int argc,
725  const char *argv[])
726 {
727  struct view_obj *vop = (struct view_obj *)clientData;
728 
729  return vo_perspective_cmd(vop, argc-1, argv+1);
730 }
731 
732 
733 int
734 vo_pmat_cmd(struct view_obj *vop,
735  int argc,
736  const char *argv[])
737 {
738  struct bu_vls vls;
739 
740  if (argc == 1) {
741  bu_vls_init(&vls);
742  bn_encode_mat(&vls, vop->vo_pmat);
743  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
744  bu_vls_free(&vls);
745 
746  return TCL_OK;
747  }
748 
749  /* compose error message */
750  bu_vls_init(&vls);
751  bu_vls_printf(&vls, "helplib_alias vo_pmat %s", argv[0]);
752  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
753  bu_vls_free(&vls);
754 
755  return TCL_ERROR;
756 }
757 
758 
759 /*
760  * Get the perspective matrix.
761  *
762  * Usage:
763  * procname pmat
764  */
765 static int
766 vo_pmat_tcl(void *clientData,
767  int argc,
768  const char *argv[])
769 {
770  struct view_obj *vop = (struct view_obj *)clientData;
771 
772  return vo_pmat_cmd(vop, argc-1, argv+1);
773 }
774 
775 
776 int
777 vo_eye_cmd(struct view_obj *vop,
778  int argc,
779  const char *argv[])
780 {
781  point_t eye_model;
782  vect_t xlate;
783  vect_t new_cent;
784  struct bu_vls vls;
785 
786  /* get eye */
787  if (argc == 1) {
788  point_t eye;
789 
790  /* calculate eye point */
791  VSET(xlate, 0.0, 0.0, 1.0);
792  MAT4X3PNT(eye, vop->vo_view2model, xlate);
793  VSCALE(eye, eye, vop->vo_base2local);
794 
795  bu_vls_init(&vls);
796  bn_encode_vect(&vls, eye);
797  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
798  bu_vls_free(&vls);
799 
800  return TCL_OK;
801  }
802 
803  if (argc != 2 && argc != 4)
804  goto bad;
805 
806  if (argc == 2) {
807  if (bn_decode_vect(eye_model, argv[1]) != 3)
808  goto bad;
809  } else {
810  double scan[3];
811 
812  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
813  Tcl_AppendResult(vop->interp, "vo_eye: bad X value - ", argv[1], "\n", (char *)0);
814  return TCL_ERROR;
815  }
816 
817  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
818  Tcl_AppendResult(vop->interp, "vo_eye: bad Y value - ", argv[2], "\n", (char *)0);
819  return TCL_ERROR;
820  }
821 
822  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
823  Tcl_AppendResult(vop->interp, "vo_eye: bad Z value - ", argv[3], "\n", (char *)0);
824  return TCL_ERROR;
825  }
826 
827  /* convert double to fastf_t */
828  VMOVE(eye_model, scan);
829  }
830 
831  VSCALE(eye_model, eye_model, vop->vo_local2base);
832 
833  /* First step: put eye at view center (view 0, 0, 0) */
834  MAT_DELTAS_VEC_NEG(vop->vo_center, eye_model);
835  vo_update(vop, 0);
836 
837  /* Second step: put eye at view 0, 0, 1.
838  * For eye to be at 0, 0, 1, the old 0, 0, -1 needs to become 0, 0, 0.
839  */
840  VSET(xlate, 0.0, 0.0, -1.0); /* correction factor */
841  MAT4X3PNT(new_cent, vop->vo_view2model, xlate);
842  MAT_DELTAS_VEC_NEG(vop->vo_center, new_cent);
843  vo_update(vop, 1);
844 
845  return TCL_OK;
846 
847 bad:
848  bu_vls_init(&vls);
849  bu_vls_printf(&vls, "helplib_alias vo_eye %s", argv[0]);
850  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
851  bu_vls_free(&vls);
852  return TCL_ERROR;
853 }
854 
855 
856 /*
857  * Get/set the eye point.
858  *
859  * Usage:
860  * procname eye [eye_point]
861  */
862 static int
863 vo_eye_tcl(void *clientData,
864  int argc,
865  const char *argv[])
866 {
867  struct view_obj *vop = (struct view_obj *)clientData;
868 
869  return vo_eye_cmd(vop, argc-1, argv+1);
870 }
871 
872 
873 int
874 vo_eye_pos_cmd(struct view_obj *vop,
875  int argc,
876  const char *argv[])
877 {
878  vect_t eye_pos;
879  struct bu_vls vls;
880 
881  if (argc != 2 && argc != 4)
882  goto bad;
883 
884  if (argc == 2) {
885  if (bn_decode_vect(eye_pos, argv[1]) != 3)
886  goto bad;
887  } else {
888  double scan[3];
889 
890  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
891  Tcl_AppendResult(vop->interp, "vo_eye_pos: bad X value - ", argv[1], "\n", (char *)0);
892  return TCL_ERROR;
893  }
894 
895  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
896  Tcl_AppendResult(vop->interp, "vo_eye_pos: bad Y value - ", argv[2], "\n", (char *)0);
897  return TCL_ERROR;
898  }
899 
900  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
901  Tcl_AppendResult(vop->interp, "vo_eye_pos: bad Z value - ", argv[3], "\n", (char *)0);
902  return TCL_ERROR;
903  }
904 
905  /* convert double to fastf_t */
906  VMOVE(eye_pos, scan);
907  }
908 
909  VSCALE(eye_pos, eye_pos, vop->vo_local2base);
910  VMOVE(vop->vo_eye_pos, eye_pos);
911 
912  /* update perspective matrix */
913  mike_persp_mat(vop->vo_pmat, vop->vo_eye_pos);
914 
915  /* update all other view related matrices */
916  vo_update(vop, 1);
917 
918  return TCL_OK;
919 
920 bad:
921  bu_vls_init(&vls);
922  bu_vls_printf(&vls, "helplib_alias vo_eye_pos %s", argv[0]);
923  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
924  bu_vls_free(&vls);
925  return TCL_ERROR;
926 }
927 
928 
929 /*
930  * Set the eye position.
931  *
932  * Usage:
933  * procname eye_pos pos
934  */
935 static int
936 vo_eye_pos_tcl(void *clientData,
937  int argc,
938  const char *argv[])
939 {
940  struct view_obj *vop = (struct view_obj *)clientData;
941 
942  return vo_eye_pos_cmd(vop, argc-1, argv+1);
943 }
944 
945 
946 int
947 vo_lookat_cmd(struct view_obj *vop,
948  int argc,
949  const char *argv[])
950 {
951  point_t look;
952  point_t eye;
953  point_t tmp;
954  point_t new_center;
955  vect_t dir;
956  fastf_t new_az, new_el;
957  struct bu_vls vls;
958 
959  if (argc != 2 && argc != 4)
960  goto bad;
961 
962  if (argc == 2) {
963  if (bn_decode_vect(look, argv[1]) != 3)
964  goto bad;
965  } else {
966  double scan[3];
967 
968  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
969  Tcl_AppendResult(vop->interp, "vo_lookat: bad X value - ", argv[1], "\n", (char *)0);
970  return TCL_ERROR;
971  }
972 
973  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
974  Tcl_AppendResult(vop->interp, "vo_lookat: bad Y value - ", argv[2], "\n", (char *)0);
975  return TCL_ERROR;
976  }
977 
978  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
979  Tcl_AppendResult(vop->interp, "vo_lookat: bad Z value - ", argv[3], "\n", (char *)0);
980  return TCL_ERROR;
981  }
982 
983  /* convert double to fastf_t */
984  VMOVE(look, scan);
985  }
986 
987  VSCALE(look, look, vop->vo_local2base);
988 
989  VSET(tmp, 0.0, 0.0, 1.0);
990  MAT4X3PNT(eye, vop->vo_view2model, tmp);
991 
992  VSUB2(dir, eye, look);
993  VUNITIZE(dir);
994  bn_ae_vec(&new_az, &new_el, dir);
995 
996  VSET(vop->vo_aet, new_az, new_el, vop->vo_aet[Z]);
997  vo_mat_aet(vop);
998 
999  VJOIN1(new_center, eye, -vop->vo_scale, dir);
1000  MAT_DELTAS_VEC_NEG(vop->vo_center, new_center);
1001 
1002  vo_update(vop, 1);
1003 
1004  return TCL_OK;
1005 
1006 bad:
1007  bu_vls_init(&vls);
1008  bu_vls_printf(&vls, "helplib_alias vo_lookat %s", argv[0]);
1009  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1010  bu_vls_free(&vls);
1011  return TCL_ERROR;
1012 }
1013 
1014 
1015 /*
1016  * Set look-at point.
1017  *
1018  * Usage:
1019  * procname lookat lookat_point
1020  */
1021 static int
1022 vo_lookat_tcl(void *clientData,
1023  int argc,
1024  const char *argv[])
1025 {
1026  struct view_obj *vop = (struct view_obj *)clientData;
1027 
1028  return vo_lookat_cmd(vop, argc-1, argv+1);
1029 }
1030 
1031 
1032 int
1033 vo_orientation_cmd(struct view_obj *vop,
1034  int argc,
1035  const char *argv[])
1036 {
1037  quat_t quat;
1038  struct bu_vls vls;
1039 
1040  if (argc != 2 && argc != 5)
1041  goto bad;
1042 
1043  if (argc == 2) {
1044  if (bn_decode_quat(quat, argv[1]) != 4)
1045  goto bad;
1046  } else {
1047  int i;
1048 
1049  for (i = 1; i < 5; ++i) {
1050  double scan;
1051  if (sscanf(argv[i], "%lf", &scan) != 1)
1052  goto bad;
1053  quat[i-1] = scan;
1054  }
1055  }
1056 
1057  quat_quat2mat(vop->vo_rotation, quat);
1058  vo_update(vop, 1);
1059 
1060  return TCL_OK;
1061 
1062 bad:
1063  bu_vls_init(&vls);
1064  bu_vls_printf(&vls, "helplib_alias vo_orient %s", argv[0]);
1065  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1066  bu_vls_free(&vls);
1067  return TCL_ERROR;
1068 }
1069 
1070 
1071 /*
1072  * Usage:
1073  * procname orient quat
1074  */
1075 static int
1076 vo_orientation_tcl(void *clientData,
1077  int argc,
1078  const char *argv[])
1079 {
1080  struct view_obj *vop = (struct view_obj *)clientData;
1081 
1082  return vo_orientation_cmd(vop, argc-1, argv+1);
1083 }
1084 
1085 
1086 int
1087 vo_pov_cmd(struct view_obj *vop,
1088  int argc,
1089  const char *argv[])
1090 {
1091  vect_t center;
1092  quat_t quat;
1093  vect_t eye_pos;
1094 
1095  /* intentionally double for scan */
1096  double scale;
1097  double perspective;
1098 
1099  if (argc != 6) {
1100  struct bu_vls vls;
1101 
1102  bu_vls_init(&vls);
1103  bu_vls_printf(&vls, "helplib_alias vo_pov %s", argv[0]);
1104  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1105  bu_vls_free(&vls);
1106  return TCL_ERROR;
1107  }
1108 
1109  /***************** Get the arguments *******************/
1110 
1111  if (bn_decode_vect(center, argv[1]) != 3) {
1112  Tcl_AppendResult(vop->interp, "vo_pov: bad center - ", argv[1], "\n", (char *)0);
1113  return TCL_ERROR;
1114  }
1115 
1116  if (bn_decode_quat(quat, argv[2]) != 4) {
1117  Tcl_AppendResult(vop->interp, "vo_pov: bad quat - ", argv[2], "\n", (char *)0);
1118  return TCL_ERROR;
1119  }
1120 
1121  if (sscanf(argv[3], "%lf", &scale) != 1) {
1122  Tcl_AppendResult(vop->interp, "vo_pov: bad scale - ", argv[3], "\n", (char *)0);
1123  return TCL_ERROR;
1124  }
1125 
1126  if (bn_decode_vect(eye_pos, argv[4]) != 3) {
1127  Tcl_AppendResult(vop->interp, "vo_pov: bad eye position - ", argv[4], "\n", (char *)0);
1128  return TCL_ERROR;
1129  }
1130 
1131  if (sscanf(argv[5], "%lf", &perspective) != 1) {
1132  Tcl_AppendResult(vop->interp, "vo_pov: bad perspective - ", argv[5], "\n", (char *)0);
1133  return TCL_ERROR;
1134  }
1135 
1136  /***************** Use the arguments *******************/
1137 
1138  VSCALE(center, center, vop->vo_local2base);
1139  MAT_DELTAS_VEC_NEG(vop->vo_center, center);
1140  quat_quat2mat(vop->vo_rotation, quat);
1141  vop->vo_scale = vop->vo_local2base * scale;
1142  VSCALE(eye_pos, eye_pos, vop->vo_local2base);
1143  VMOVE(vop->vo_eye_pos, eye_pos);
1144  vop->vo_perspective = perspective;
1145 
1146  vo_update(vop, 1);
1147 
1148  return TCL_OK;
1149 }
1150 
1151 
1152 /*
1153  * Usage:
1154  * procname pov center quat scale eye_pos perspective
1155  */
1156 static int
1157 vo_pov_tcl(void *clientData,
1158  int argc,
1159  const char *argv[])
1160 {
1161  struct view_obj *vop = (struct view_obj *)clientData;
1162 
1163  return vo_pov_cmd(vop, argc-1, argv+1);
1164 }
1165 
1166 
1167 int
1168 vo_zoom(struct view_obj *vop,
1169  fastf_t sf)
1170 {
1171  if (sf <= SMALL_FASTF || INFINITY < sf) {
1172  Tcl_AppendResult(vop->interp, "vo_zoom - scale factor out of range\n", (char *)0);
1173  return TCL_ERROR;
1174  }
1175 
1176  vop->vo_scale /= sf;
1177  if (vop->vo_scale < RT_MINVIEWSCALE)
1178  vop->vo_scale = RT_MINVIEWSCALE;
1179  vop->vo_size = 2.0 * vop->vo_scale;
1180  vop->vo_invSize = 1.0 / vop->vo_size;
1181  vo_update(vop, 1);
1182 
1183  return TCL_OK;
1184 }
1185 
1186 
1187 int
1188 vo_zoom_cmd(struct view_obj *vop,
1189  int argc,
1190  const char *argv[])
1191 {
1192  double sf;
1193 
1194  if (argc != 2) {
1195  struct bu_vls vls;
1196 
1197  bu_vls_init(&vls);
1198  bu_vls_printf(&vls, "helplib_alias vo_zoom %s", argv[0]);
1199  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1200  bu_vls_free(&vls);
1201 
1202  return TCL_ERROR;
1203  }
1204 
1205  if (sscanf(argv[1], "%lf", &sf) != 1) {
1206  Tcl_AppendResult(vop->interp, "bad zoom value - ", argv[1], "\n", (char *)0);
1207  return TCL_ERROR;
1208  }
1209 
1210  return vo_zoom(vop, sf);
1211 }
1212 
1213 
1214 /*
1215  * Usage:
1216  * procname zoom scale_factor
1217  */
1218 static int
1219 vo_zoom_tcl(void *clientData,
1220  int argc,
1221  const char *argv[])
1222 {
1223  struct view_obj *vop = (struct view_obj *)clientData;
1224 
1225  return vo_zoom_cmd(vop, argc-1, argv+1);
1226 }
1227 
1228 
1229 int
1230 vo_units_cmd(struct view_obj *vop,
1231  int argc,
1232  const char *argv[])
1233 {
1234  struct bu_vls vls;
1235 
1236  /* get units */
1237  if (argc == 1) {
1238  bu_vls_init(&vls);
1239  bu_vls_printf(&vls, "%s", bu_units_string(vop->vo_local2base));
1240  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
1241  bu_vls_free(&vls);
1242 
1243  return TCL_OK;
1244  }
1245 
1246  /* set units */
1247  if (argc == 2) {
1248  double uval;
1249 
1250  uval = bu_units_conversion(argv[1]);
1251  if (ZERO(uval)) {
1252  bu_vls_init(&vls);
1253  bu_vls_printf(&vls, "unrecognized unit type - %s\n", argv[1]);
1254  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
1255  bu_vls_free(&vls);
1256 
1257  return TCL_ERROR;
1258  }
1259 
1260  vop->vo_local2base = uval;
1261  vop->vo_base2local = 1.0 / vop->vo_local2base;
1262 
1263  return TCL_OK;
1264  }
1265 
1266  bu_vls_init(&vls);
1267  bu_vls_printf(&vls, "helplib_alias vo_units %s", argv[0]);
1268  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1269  bu_vls_free(&vls);
1270 
1271  return TCL_ERROR;
1272 }
1273 
1274 
1275 /*
1276  * Set/get local units.
1277  *
1278  * Usage:
1279  * procname units [unit_spec]
1280  */
1281 static int
1282 vo_units_tcl(void *clientData,
1283  int argc,
1284  const char *argv[])
1285 {
1286  struct view_obj *vop = (struct view_obj *)clientData;
1287 
1288  return vo_units_cmd(vop, argc-1, argv+1);
1289 }
1290 
1291 
1292 int
1293 vo_base2local_cmd(struct view_obj *vop,
1294  int argc,
1295  const char *argv[])
1296 {
1297  struct bu_vls vls;
1298 
1299  bu_vls_init(&vls);
1300 
1301  if (argc != 1) {
1302  bu_vls_printf(&vls, "helplib_alias vo_base2local %s", argv[0]);
1303  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1304  bu_vls_free(&vls);
1305 
1306  return TCL_ERROR;
1307  }
1308 
1309  bu_vls_printf(&vls, "%g", vop->vo_base2local);
1310  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
1311  bu_vls_free(&vls);
1312 
1313  return TCL_OK;
1314 }
1315 
1316 
1317 /*
1318  * Get base2local conversion factor.
1319  *
1320  * Usage:
1321  * procname base2local
1322  */
1323 static int
1324 vo_base2local_tcl(void *clientData,
1325  int argc,
1326  const char *argv[])
1327 {
1328  struct view_obj *vop = (struct view_obj *)clientData;
1329 
1330  return vo_base2local_cmd(vop, argc-1, argv+1);
1331 }
1332 
1333 
1334 int
1335 vo_local2base_cmd(struct view_obj *vop,
1336  int argc,
1337  const char *argv[])
1338 {
1339  struct bu_vls vls;
1340 
1341  bu_vls_init(&vls);
1342 
1343  if (argc != 1) {
1344  bu_vls_printf(&vls, "helplib_alias vo_local2base %s", argv[0]);
1345  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1346  bu_vls_free(&vls);
1347 
1348  return TCL_ERROR;
1349  }
1350 
1351  bu_vls_printf(&vls, "%g", vop->vo_local2base);
1352  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
1353  bu_vls_free(&vls);
1354 
1355  return TCL_OK;
1356 }
1357 
1358 
1359 /*
1360  * Get local2base conversion factor.
1361  *
1362  * Usage:
1363  * procname local2base
1364  */
1365 static int
1366 vo_local2base_tcl(void *clientData,
1367  int argc,
1368  const char *argv[])
1369 {
1370  struct view_obj *vop = (struct view_obj *)clientData;
1371 
1372  return vo_local2base_cmd(vop, argc-1, argv+1);
1373 }
1374 
1375 
1376 int
1377 vo_rot(struct view_obj *vop,
1378  char coord,
1379  char rotate_about,
1380  mat_t rmat,
1381  int (*func)())
1382 {
1383  mat_t temp1, temp2;
1384 
1385  if (func != (int (*)())0)
1386  return (*func)(vop, coord, rotate_about, rmat);
1387 
1388  switch (coord) {
1389  case 'm':
1390  /* transform model rotations into view rotations */
1391  bn_mat_inv(temp1, vop->vo_rotation);
1392  bn_mat_mul(temp2, vop->vo_rotation, rmat);
1393  bn_mat_mul(rmat, temp2, temp1);
1394  break;
1395  case 'v':
1396  default:
1397  break;
1398  }
1399 
1400  /* Calculate new view center */
1401  if (rotate_about != 'v') {
1402  point_t rot_pt;
1403  point_t new_origin;
1404  mat_t viewchg, viewchginv;
1405  point_t new_cent_view;
1406  point_t new_cent_model;
1407 
1408  switch (rotate_about) {
1409  case 'e':
1410  VSET(rot_pt, 0.0, 0.0, 1.0);
1411  break;
1412  case 'k':
1413  MAT4X3PNT(rot_pt, vop->vo_model2view, vop->vo_keypoint);
1414  break;
1415  case 'm':
1416  /* rotate around model center (0, 0, 0) */
1417  VSET(new_origin, 0.0, 0.0, 0.0);
1418  MAT4X3PNT(rot_pt, vop->vo_model2view, new_origin);
1419  break;
1420  default: {
1421  struct bu_vls vls;
1422 
1423  bu_vls_init(&vls);
1424  bu_vls_printf(&vls, "vo_rot_tcl: bad rotate_about - %c\n", rotate_about);
1425  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)0);
1426  bu_vls_free(&vls);
1427  return TCL_ERROR;
1428  }
1429  }
1430 
1431  bn_mat_xform_about_pt(viewchg, rmat, rot_pt);
1432  bn_mat_inv(viewchginv, viewchg);
1433 
1434  /* Convert origin in new (viewchg) coords back to old view coords */
1435  VSET(new_origin, 0.0, 0.0, 0.0);
1436  MAT4X3PNT(new_cent_view, viewchginv, new_origin);
1437  MAT4X3PNT(new_cent_model, vop->vo_view2model, new_cent_view);
1438  MAT_DELTAS_VEC_NEG(vop->vo_center, new_cent_model);
1439  }
1440 
1441  /* pure rotation */
1442  bn_mat_mul2(rmat, vop->vo_rotation);
1443  vo_update(vop, 1);
1444 
1445  return TCL_OK;
1446 }
1447 
1448 
1449 int
1450 vo_rot_cmd(struct view_obj *vop,
1451  int argc,
1452  const char *argv[],
1453  int (*func)())
1454 {
1455  vect_t rvec;
1456  mat_t rmat;
1457  char coord = vop->vo_coord;
1458  struct bu_vls vls;
1459 
1460  if (argc < 2 || 5 < argc)
1461  goto bad;
1462 
1463  /* process coord flag */
1464  if (argv[1][0] == '-' && (argv[1][1] == 'v' || argv[1][1] == 'm') && argv[1][2] == '\0') {
1465  coord = argv[1][1];
1466  --argc;
1467  ++argv;
1468  }
1469 
1470  if (argc != 2 && argc != 4)
1471  goto bad;
1472 
1473  if (argc == 2) {
1474  if (bn_decode_vect(rvec, argv[1]) != 3)
1475  goto bad;
1476  } else {
1477  double scan[3];
1478 
1479  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
1480  Tcl_AppendResult(vop->interp, "vo_rot: bad X value - ", argv[1], "\n", (char *)0);
1481  return TCL_ERROR;
1482  }
1483 
1484  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
1485  Tcl_AppendResult(vop->interp, "vo_rot: bad Y value - ", argv[2], "\n", (char *)0);
1486  return TCL_ERROR;
1487  }
1488 
1489  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
1490  Tcl_AppendResult(vop->interp, "vo_rot: bad Z value - ", argv[3], "\n", (char *)0);
1491  return TCL_ERROR;
1492  }
1493 
1494  /* convert double to fastf_t */
1495  VMOVE(rvec, scan);
1496  }
1497 
1498  VSCALE(rvec, rvec, -1.0);
1499  bn_mat_angles(rmat, rvec[X], rvec[Y], rvec[Z]);
1500 
1501  return vo_rot(vop, coord, vop->vo_rotate_about, rmat, func);
1502 
1503 bad:
1504  bu_vls_init(&vls);
1505  bu_vls_printf(&vls, "helplib_alias vo_rot %s", argv[0]);
1506  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1507  bu_vls_free(&vls);
1508 
1509  return TCL_ERROR;
1510 }
1511 
1512 
1513 /*
1514  * Rotate the view according to xyz.
1515  *
1516  * Usage:
1517  * procname rot [-v|-m] xyz
1518  */
1519 static int
1520 vo_rot_tcl(void *clientData,
1521  int argc,
1522  const char *argv[])
1523 {
1524  struct view_obj *vop = (struct view_obj *)clientData;
1525 
1526  return vo_rot_cmd(vop, argc-1, argv+1, (int (*)())0);
1527 }
1528 
1529 
1530 int
1531 vo_tra(struct view_obj *vop,
1532  char coord,
1533  vect_t tvec,
1534  int (*func)())
1535 {
1536  point_t delta;
1537  point_t work;
1538  point_t vc, nvc;
1539 
1540  if (func != (int (*)())0)
1541  return (*func)(vop, coord, tvec);
1542 
1543  switch (coord) {
1544  case 'm':
1545  VSCALE(delta, tvec, vop->vo_local2base);
1546  MAT_DELTAS_GET_NEG(vc, vop->vo_center);
1547  break;
1548  case 'v':
1549  default:
1550  VSCALE(tvec, tvec, -2.0*vop->vo_local2base*vop->vo_invSize);
1551  MAT4X3PNT(work, vop->vo_view2model, tvec);
1552  MAT_DELTAS_GET_NEG(vc, vop->vo_center);
1553  VSUB2(delta, work, vc);
1554  break;
1555  }
1556 
1557  VSUB2(nvc, vc, delta);
1558  MAT_DELTAS_VEC_NEG(vop->vo_center, nvc);
1559  vo_update(vop, 1);
1560 
1561  return TCL_OK;
1562 }
1563 
1564 
1565 int
1566 vo_tra_cmd(struct view_obj *vop,
1567  int argc,
1568  const char *argv[],
1569  int (*func)())
1570 {
1571  vect_t tvec;
1572  char coord = vop->vo_coord;
1573  struct bu_vls vls;
1574 
1575  if (argc < 2 || 5 < argc)
1576  goto bad;
1577 
1578  /* process coord flag */
1579  if (argv[1][0] == '-' && (argv[1][1] == 'v' || argv[1][1] == 'm') && argv[1][2] == '\0') {
1580  coord = argv[1][1];
1581  --argc;
1582  ++argv;
1583  }
1584 
1585  if (argc != 2 && argc != 4)
1586  goto bad;
1587 
1588  if (argc == 2) {
1589  if (bn_decode_vect(tvec, argv[1]) != 3)
1590  goto bad;
1591  } else {
1592  double scan[3];
1593 
1594  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
1595  Tcl_AppendResult(vop->interp, "vo_tra: bad X value - ", argv[1], "\n", (char *)0);
1596  return TCL_ERROR;
1597  }
1598 
1599  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
1600  Tcl_AppendResult(vop->interp, "vo_tra: bad Y value - ", argv[2], "\n", (char *)0);
1601  return TCL_ERROR;
1602  }
1603 
1604  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
1605  Tcl_AppendResult(vop->interp, "vo_tra: bad Z value - ", argv[3], "\n", (char *)0);
1606  return TCL_ERROR;
1607  }
1608 
1609  /* convert double to fastf_t */
1610  VMOVE(tvec, scan);
1611  }
1612 
1613  return vo_tra(vop, coord, tvec, func);
1614 
1615 bad:
1616  bu_vls_init(&vls);
1617  bu_vls_printf(&vls, "helplib_alias vo_tra %s", argv[0]);
1618  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1619  bu_vls_free(&vls);
1620 
1621  return TCL_ERROR;
1622 }
1623 
1624 
1625 /*
1626  * Translate the view according to xyz.
1627  *
1628  * Usage:
1629  * procname tra [-v|-m] xyz
1630  */
1631 static int
1632 vo_tra_tcl(void *clientData,
1633  int argc,
1634  const char *argv[])
1635 {
1636  struct view_obj *vop = (struct view_obj *)clientData;
1637 
1638  return vo_tra_cmd(vop, argc-1, argv+1, (int (*)())0);
1639 }
1640 
1641 
1642 int
1643 vo_slew(struct view_obj *vop,
1644  vect_t svec)
1645 {
1646  point_t model_center;
1647 
1648  MAT4X3PNT(model_center, vop->vo_view2model, svec);
1649  MAT_DELTAS_VEC_NEG(vop->vo_center, model_center);
1650  vo_update(vop, 1);
1651 
1652  return TCL_OK;
1653 }
1654 
1655 
1656 int
1657 vo_slew_cmd(struct view_obj *vop,
1658  int argc,
1659  const char *argv[])
1660 {
1661  struct bu_vls vls;
1662  vect_t svec;
1663 
1664  if (argc == 2) {
1665  int n;
1666 
1667  if ((n = bn_decode_vect(svec, argv[1])) != 3) {
1668  if (n != 2)
1669  goto bad;
1670 
1671  svec[Z] = 0.0;
1672  }
1673 
1674  return vo_slew(vop, svec);
1675  }
1676 
1677  if (argc == 3 || argc == 4) {
1678  double scan[3];
1679 
1680  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
1681  Tcl_AppendResult(vop->interp, "vo_slew: bad X value - ", argv[1], "\n", (char *)0);
1682  return TCL_ERROR;
1683  }
1684 
1685  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
1686  Tcl_AppendResult(vop->interp, "vo_slew: bad Y value - ", argv[2], "\n", (char *)0);
1687  return TCL_ERROR;
1688  }
1689 
1690  if (argc == 4) {
1691  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
1692  Tcl_AppendResult(vop->interp, "vo_slew: bad Z value - ", argv[3], "\n", (char *)0);
1693  return TCL_ERROR;
1694  }
1695  } else
1696  scan[Z] = 0.0;
1697 
1698  /* convert double to scan */
1699  VMOVE(svec, scan);
1700 
1701  return vo_slew(vop, svec);
1702  }
1703 
1704 bad:
1705  bu_vls_init(&vls);
1706  bu_vls_printf(&vls, "helplib_alias vo_slew %s", argv[0]);
1707  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1708  bu_vls_free(&vls);
1709 
1710  return TCL_ERROR;
1711 }
1712 
1713 
1714 /*
1715  * Make xyz the new view center.
1716  *
1717  * Usage:
1718  * procname slew xy
1719  */
1720 static int
1721 vo_slew_tcl(void *clientData,
1722  int argc,
1723  const char *argv[])
1724 {
1725  struct view_obj *vop = (struct view_obj *)clientData;
1726 
1727  return vo_slew_cmd(vop, argc-1, argv+1);
1728 }
1729 
1730 
1731 int
1732 vo_observer_cmd(struct view_obj *vop,
1733  int argc,
1734  const char *argv[])
1735 {
1736  if (argc < 2) {
1737  bu_log("ERROR: expecting two or more arguments\n");
1738  return TCL_ERROR;
1739  }
1740 
1741  return bu_observer_cmd((ClientData)&vop->vo_observers, argc-1, (const char **)argv+1);
1742 }
1743 
1744 
1745 /*
1746  * Attach/detach observers to/from list.
1747  *
1748  * Usage:
1749  * procname observer cmd [args]
1750  */
1751 static int
1752 vo_observer_tcl(void *clientData,
1753  int argc,
1754  const char *argv[])
1755 {
1756  struct view_obj *vop = (struct view_obj *)clientData;
1757 
1758  return vo_observer_cmd(vop, argc-1, argv+1);
1759 }
1760 
1761 
1762 int
1763 vo_coord_cmd(struct view_obj *vop,
1764  int argc,
1765  const char *argv[])
1766 {
1767  struct bu_vls vls;
1768 
1769  /* Get coord */
1770  if (argc == 1) {
1771  bu_vls_init(&vls);
1772  bu_vls_printf(&vls, "%c", vop->vo_coord);
1773  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)0);
1774  bu_vls_free(&vls);
1775  return TCL_OK;
1776  }
1777 
1778  /* Set coord */
1779  if (argc == 2) {
1780  switch (argv[1][0]) {
1781  case 'm':
1782  case 'v':
1783  vop->vo_coord = argv[1][0];
1784  return TCL_OK;
1785  }
1786  }
1787 
1788  /* return help message */
1789  bu_vls_init(&vls);
1790  bu_vls_printf(&vls, "helplib_alias vo_coord %s", argv[0]);
1791  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1792  bu_vls_free(&vls);
1793  return TCL_ERROR;
1794 }
1795 
1796 
1797 /*
1798  * Get/set the coordinate system.
1799  *
1800  * Usage:
1801  * procname coord [v|m]
1802  */
1803 static int
1804 vo_coord_tcl(void *clientData,
1805  int argc,
1806  const char *argv[])
1807 {
1808  struct view_obj *vop = (struct view_obj *)clientData;
1809 
1810  return vo_coord_cmd(vop, argc-1, argv+1);
1811 }
1812 
1813 
1814 int
1815 vo_rotate_about_cmd(struct view_obj *vop,
1816  int argc,
1817  const char *argv[])
1818 {
1819  struct bu_vls vls;
1820 
1821  /* Get rotate_about */
1822  if (argc == 1) {
1823  bu_vls_init(&vls);
1824  bu_vls_printf(&vls, "%c", vop->vo_rotate_about);
1825  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)0);
1826  bu_vls_free(&vls);
1827  return TCL_OK;
1828  }
1829 
1830  /* Set rotate_about */
1831  if (argc == 2 && argv[1][1] == '\0') {
1832  switch (argv[1][0]) {
1833  case 'e':
1834  case 'k':
1835  case 'm':
1836  case 'v':
1837  vop->vo_rotate_about = argv[1][0];
1838  return TCL_OK;
1839  }
1840  }
1841 
1842  /* return help message */
1843  bu_vls_init(&vls);
1844  bu_vls_printf(&vls, "helplib_alias vo_rotate_about %s", argv[0]);
1845  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1846  bu_vls_free(&vls);
1847  return TCL_ERROR;
1848 }
1849 
1850 
1851 /*
1852  * Get/set the rotate about point.
1853  *
1854  * Usage:
1855  * procname rotate_about [e|k|m|v]
1856  */
1857 static int
1858 vo_rotate_about_tcl(void *clientData,
1859  int argc,
1860  const char *argv[])
1861 {
1862  struct view_obj *vop = (struct view_obj *)clientData;
1863 
1864  return vo_rotate_about_cmd(vop, argc-1, argv+1);
1865 }
1866 
1867 
1868 int
1869 vo_keypoint_cmd(struct view_obj *vop,
1870  int argc,
1871  const char *argv[])
1872 {
1873  struct bu_vls vls;
1874  vect_t tvec = VINIT_ZERO;
1875 
1876  /* Get the keypoint */
1877  if (argc == 1) {
1878  bu_vls_init(&vls);
1879  VSCALE(tvec, vop->vo_keypoint, vop->vo_base2local);
1880  bn_encode_vect(&vls, tvec);
1881  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)0);
1882  bu_vls_free(&vls);
1883  return TCL_OK;
1884  }
1885 
1886  /* Set the keypoint */
1887  if (argc == 2) {
1888  if (bn_decode_vect(tvec, argv[1]) != 3)
1889  goto bad;
1890  } else if (argc == 4) {
1891  double scan[3];
1892 
1893  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
1894  Tcl_AppendResult(vop->interp, "vo_keypoint: bad X value - ", argv[1], "\n", (char *)0);
1895  return TCL_ERROR;
1896  }
1897 
1898  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
1899  Tcl_AppendResult(vop->interp, "vo_keypoint: bad Y value - ", argv[2], "\n", (char *)0);
1900  return TCL_ERROR;
1901  }
1902 
1903  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
1904  Tcl_AppendResult(vop->interp, "vo_keypoint: bad Z value - ", argv[3], "\n", (char *)0);
1905  return TCL_ERROR;
1906  }
1907 
1908  /* convert double to fastf_t */
1909  VMOVE(tvec, scan);
1910  }
1911 
1912  VSCALE(vop->vo_keypoint, tvec, vop->vo_local2base);
1913  return TCL_OK;
1914 
1915 bad:
1916  bu_vls_init(&vls);
1917  bu_vls_printf(&vls, "helplib_alias vo_keypoint %s", argv[0]);
1918  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
1919  bu_vls_free(&vls);
1920  return TCL_ERROR;
1921 }
1922 
1923 
1924 /*
1925  * Get/set the keypoint.
1926  *
1927  * Usage:
1928  * procname keypoint [point]
1929  */
1930 static int
1931 vo_keypoint_tcl(void *clientData,
1932  int argc,
1933  const char *argv[])
1934 {
1935  struct view_obj *vop = (struct view_obj *)clientData;
1936 
1937  return vo_keypoint_cmd(vop, argc-1, argv+1);
1938 }
1939 
1940 
1941 /*
1942  * Set the view. Angles are DOUBLES, in degrees.
1943  *
1944  * Given that viewvec = scale . rotate . (xlate to view center) . modelvec,
1945  * we just replace the rotation matrix.
1946  * (This assumes rotation around the view center).
1947  */
1948 void
1949 vo_setview(struct view_obj *vop,
1950  vect_t rvec) /* DOUBLE angles, in degrees */
1951 {
1952  bn_mat_angles(vop->vo_rotation, rvec[X], rvec[Y], rvec[Z]);
1953  vo_update(vop, 1);
1954 }
1955 
1956 
1957 int
1958 vo_setview_cmd(struct view_obj *vop,
1959  int argc,
1960  const char *argv[])
1961 {
1962  vect_t rvec;
1963  struct bu_vls vls;
1964 
1965  if (argc != 2 && argc != 4)
1966  goto bad;
1967 
1968  if (argc == 2) {
1969  if (bn_decode_vect(rvec, argv[1]) != 3)
1970  goto bad;
1971  } else {
1972  double scan[3];
1973 
1974  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
1975  Tcl_AppendResult(vop->interp, "vo_setview_cmd: bad X value - ", argv[1], "\n", (char *)0);
1976  return TCL_ERROR;
1977  }
1978 
1979  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
1980  Tcl_AppendResult(vop->interp, "vo_setview_cmd: bad Y value - ", argv[2], "\n", (char *)0);
1981  return TCL_ERROR;
1982  }
1983 
1984  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
1985  Tcl_AppendResult(vop->interp, "vo_setview_cmd: bad Z value - ", argv[3], "\n", (char *)0);
1986  return TCL_ERROR;
1987  }
1988 
1989  /* convert double to fastf_t */
1990  VMOVE(rvec, scan);
1991  }
1992 
1993  vo_setview(vop, rvec);
1994  return TCL_OK;
1995 
1996 bad:
1997  bu_vls_init(&vls);
1998  bu_vls_printf(&vls, "helplib_alias vo_setview %s", argv[0]);
1999  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2000  bu_vls_free(&vls);
2001  return TCL_ERROR;
2002 }
2003 
2004 
2005 /*
2006  * Usage:
2007  * procname setview x y z
2008  */
2009 static int
2010 vo_setview_tcl(void *clientData,
2011  int argc,
2012  const char *argv[])
2013 {
2014  struct view_obj *vop = (struct view_obj *)clientData;
2015 
2016  return vo_setview_cmd(vop, argc-1, argv+1);
2017 }
2018 
2019 
2020 int
2021 vo_arot_cmd(struct view_obj *vop,
2022  int argc,
2023  const char *argv[],
2024  int (*func)())
2025 {
2026  mat_t newrot;
2027  point_t pt;
2028  vect_t axis;
2029 
2030  /* intentionally double for scan */
2031  double angle;
2032  double scan[3];
2033 
2034  if (argc != 5) {
2035  struct bu_vls vls;
2036 
2037  bu_vls_init(&vls);
2038  bu_vls_printf(&vls, "helplib_alias vo_arot %s", argv[0]);
2039  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2040  bu_vls_free(&vls);
2041  return TCL_ERROR;
2042  }
2043 
2044  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
2045  Tcl_AppendResult(vop->interp, "vo_arot: bad X value - ", argv[1], "\n", (char *)0);
2046  return TCL_ERROR;
2047  }
2048 
2049  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
2050  Tcl_AppendResult(vop->interp, "vo_arot: bad Y value - ", argv[2], "\n", (char *)0);
2051  return TCL_ERROR;
2052  }
2053 
2054  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
2055  Tcl_AppendResult(vop->interp, "vo_arot: bad Z value - ", argv[3], "\n", (char *)0);
2056  return TCL_ERROR;
2057  }
2058 
2059  /* convert double to fastf_t */
2060  VMOVE(axis, scan);
2061 
2062  if (sscanf(argv[4], "%lf", &angle) != 1) {
2063  Tcl_AppendResult(vop->interp, "vo_arot: bad angle - ", argv[4], "\n", (char *)0);
2064  return TCL_ERROR;
2065  }
2066 
2067  VSETALL(pt, 0.0);
2068  VUNITIZE(axis);
2069 
2070  bn_mat_arb_rot(newrot, pt, axis, angle*DEG2RAD);
2071 
2072  return vo_rot(vop, vop->vo_coord, vop->vo_rotate_about, newrot, func);
2073 }
2074 
2075 
2076 /*
2077  * Usage:
2078  * procname arot x y z angle
2079  */
2080 static int
2081 vo_arot_tcl(void *clientData,
2082  int argc,
2083  const char *argv[])
2084 {
2085  struct view_obj *vop = (struct view_obj *)clientData;
2086 
2087  return vo_arot_cmd(vop, argc-1, argv+1, (int (*)())0);
2088 }
2089 
2090 
2091 int
2092 vo_vrot_cmd(struct view_obj *vop,
2093  int argc,
2094  const char *argv[])
2095 {
2096  vect_t rvec;
2097  mat_t rmat;
2098  struct bu_vls vls;
2099 
2100  if (argc != 2 && argc != 4)
2101  goto bad;
2102 
2103  if (argc == 2) {
2104  if (bn_decode_vect(rvec, argv[1]) != 3)
2105  goto bad;
2106  } else {
2107  double scan[3];
2108 
2109  if (sscanf(argv[1], "%lf", &scan[X]) < 1) {
2110  Tcl_AppendResult(vop->interp, "vo_vrot: bad X value - ", argv[1], "\n", (char *)0);
2111  return TCL_ERROR;
2112  }
2113 
2114  if (sscanf(argv[2], "%lf", &scan[Y]) < 1) {
2115  Tcl_AppendResult(vop->interp, "vo_vrot: bad Y value - ", argv[2], "\n", (char *)0);
2116  return TCL_ERROR;
2117  }
2118 
2119  if (sscanf(argv[3], "%lf", &scan[Z]) < 1) {
2120  Tcl_AppendResult(vop->interp, "vo_vrot: bad Z value - ", argv[3], "\n", (char *)0);
2121  return TCL_ERROR;
2122  }
2123 
2124  /* convert double to fastf_t */
2125  VMOVE(rvec, scan);
2126  }
2127 
2128  VSCALE(rvec, rvec, -1.0);
2129  bn_mat_angles(rmat, rvec[X], rvec[Y], rvec[Z]);
2130 
2131  return vo_rot(vop, 'v', vop->vo_rotate_about, rmat, (int (*)())0);
2132 
2133 bad:
2134  bu_vls_init(&vls);
2135  bu_vls_printf(&vls, "helplib_alias vo_vrot %s", argv[0]);
2136  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2137  bu_vls_free(&vls);
2138  return TCL_ERROR;
2139 }
2140 
2141 
2142 /*
2143  * Usage:
2144  * procname vrot x y z
2145  */
2146 static int
2147 vo_vrot_tcl(void *clientData,
2148  int argc,
2149  const char *argv[])
2150 {
2151  struct view_obj *vop = (struct view_obj *)clientData;
2152 
2153  return vo_vrot_cmd(vop, argc-1, argv+1);
2154 }
2155 
2156 
2157 int
2158 vo_mrot_cmd(struct view_obj *vop,
2159  int argc,
2160  const char *argv[],
2161  int (*func)())
2162 {
2163  vect_t rvec;
2164  mat_t rmat;
2165  struct bu_vls vls;
2166 
2167  if (argc != 2 && argc != 4)
2168  goto bad;
2169 
2170  if (argc == 2) {
2171  if (bn_decode_vect(rvec, argv[1]) != 3)
2172  goto bad;
2173  } else {
2174  double scan[3];
2175 
2176  if (sscanf(argv[1], "%lf", &scan[X]) < 1) {
2177  Tcl_AppendResult(vop->interp, "vo_mrot: bad X value - ", argv[1], "\n", (char *)0);
2178  return TCL_ERROR;
2179  }
2180 
2181  if (sscanf(argv[2], "%lf", &scan[Y]) < 1) {
2182  Tcl_AppendResult(vop->interp, "vo_mrot: bad Y value - ", argv[2], "\n", (char *)0);
2183  return TCL_ERROR;
2184  }
2185 
2186  if (sscanf(argv[3], "%lf", &scan[Z]) < 1) {
2187  Tcl_AppendResult(vop->interp, "vo_mrot: bad Z value - ", argv[3], "\n", (char *)0);
2188  return TCL_ERROR;
2189  }
2190 
2191  /* convert double to fastf_t */
2192  VMOVE(rvec, scan);
2193  }
2194 
2195  VSCALE(rvec, rvec, -1.0);
2196  bn_mat_angles(rmat, rvec[X], rvec[Y], rvec[Z]);
2197 
2198  return vo_rot(vop, 'm', vop->vo_rotate_about, rmat, func);
2199 
2200 bad:
2201  bu_vls_init(&vls);
2202  bu_vls_printf(&vls, "helplib_alias vo_mrot %s", argv[0]);
2203  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2204  bu_vls_free(&vls);
2205  return TCL_ERROR;
2206 }
2207 
2208 
2209 /*
2210  * Usage:
2211  * procname mrot x y z
2212  */
2213 static int
2214 vo_mrot_tcl(void *clientData,
2215  int argc,
2216  const char *argv[])
2217 {
2218  struct view_obj *vop = (struct view_obj *)clientData;
2219 
2220  return vo_mrot_cmd(vop, argc-1, argv+1, (int (*)())0);
2221 }
2222 
2223 
2224 int
2225 vo_mrotPoint_cmd(struct view_obj *vop,
2226  int argc,
2227  const char *argv[])
2228 {
2229  struct bu_vls vls;
2230 
2231  /* Parse the incoming point */
2232  if (argc == 2 || argc == 4) {
2233  point_t viewPt;
2234  point_t modelPt;
2235  mat_t invRot;
2236 
2237  if (argc == 2) {
2238  if (bn_decode_vect(viewPt, argv[1]) != 3)
2239  goto bad;
2240  } else {
2241  double scan[3];
2242 
2243  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
2244  Tcl_AppendResult(vop->interp,
2245  "vo_mrotPoint: bad X value - ",
2246  argv[1],
2247  "\n",
2248  (char *)0);
2249  return TCL_ERROR;
2250  }
2251 
2252  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
2253  Tcl_AppendResult(vop->interp,
2254  "vo_mrotPoint: bad Y value - ",
2255  argv[2],
2256  "\n",
2257  (char *)0);
2258  return TCL_ERROR;
2259  }
2260 
2261  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
2262  Tcl_AppendResult(vop->interp,
2263  "vo_mrotPoint: bad Z value - ",
2264  argv[3],
2265  "\n",
2266  (char *)0);
2267  return TCL_ERROR;
2268  }
2269 
2270  /* convert double to fastf_t */
2271  VMOVE(viewPt, scan);
2272  }
2273 
2274  bu_vls_init(&vls);
2275  bn_mat_inv(invRot, vop->vo_rotation);
2276  MAT4X3PNT(modelPt, invRot, viewPt);
2277  bn_encode_vect(&vls, modelPt);
2278  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
2279  bu_vls_free(&vls);
2280 
2281  return TCL_OK;
2282  }
2283 
2284 bad:
2285  /* compose error message */
2286  bu_vls_init(&vls);
2287  bu_vls_printf(&vls, "helplib_alias vo_mrotPoint %s", argv[0]);
2288  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2289  bu_vls_free(&vls);
2290 
2291  return TCL_ERROR;
2292 }
2293 
2294 
2295 /*
2296  * Convert view point to a model point (rotation only).
2297  *
2298  * Usage:
2299  * procname mrotPoint vx vy vz
2300  */
2301 static int
2302 vo_mrotPoint_tcl(void *clientData,
2303  int argc,
2304  const char *argv[])
2305 {
2306  struct view_obj *vop = (struct view_obj *)clientData;
2307 
2308  return vo_mrotPoint_cmd(vop, argc-1, argv+1);
2309 }
2310 
2311 
2312 int
2313 vo_m2vPoint_cmd(struct view_obj *vop,
2314  int argc,
2315  const char *argv[])
2316 {
2317  struct bu_vls vls;
2318 
2319  /* Parse the incoming point */
2320  if (argc == 2 || argc == 4) {
2321  point_t viewPt = VINIT_ZERO;
2322  /* intentionally using double for scan */
2323  double modelPt[3] = VINIT_ZERO;
2324 
2325  if (argc == 2) {
2326  if (bn_decode_vect(viewPt, argv[1]) != 3)
2327  goto bad;
2328  } else {
2329  if (sscanf(argv[1], "%lf", &modelPt[X]) != 1) {
2330  Tcl_AppendResult(vop->interp,
2331  "vo_m2vPoint: bad X value - ",
2332  argv[1],
2333  "\n",
2334  (char *)0);
2335  return TCL_ERROR;
2336  }
2337 
2338  if (sscanf(argv[2], "%lf", &modelPt[Y]) != 1) {
2339  Tcl_AppendResult(vop->interp,
2340  "vo_m2vPoint: bad Y value - ",
2341  argv[2],
2342  "\n",
2343  (char *)0);
2344  return TCL_ERROR;
2345  }
2346 
2347  if (sscanf(argv[3], "%lf", &modelPt[Z]) != 1) {
2348  Tcl_AppendResult(vop->interp,
2349  "vo_m2vPoint: bad Z value - ",
2350  argv[3],
2351  "\n",
2352  (char *)0);
2353  return TCL_ERROR;
2354  }
2355  }
2356 
2357  bu_vls_init(&vls);
2358  MAT4X3PNT(viewPt, vop->vo_model2view, modelPt);
2359  bn_encode_vect(&vls, viewPt);
2360  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
2361  bu_vls_free(&vls);
2362 
2363  return TCL_OK;
2364  }
2365 
2366 bad:
2367  /* compose error message */
2368  bu_vls_init(&vls);
2369  bu_vls_printf(&vls, "helplib_alias vo_m2vPoint %s", argv[0]);
2370  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2371  bu_vls_free(&vls);
2372 
2373  return TCL_ERROR;
2374 }
2375 
2376 
2377 /*
2378  * Convert model point to a view point.
2379  *
2380  * Usage:
2381  * procname m2vPoint vx vy vz
2382  */
2383 static int
2384 vo_m2vPoint_tcl(void *clientData,
2385  int argc,
2386  const char *argv[])
2387 {
2388  struct view_obj *vop = (struct view_obj *)clientData;
2389 
2390  return vo_m2vPoint_cmd(vop, argc-1, argv+1);
2391 }
2392 
2393 
2394 int
2395 vo_v2mPoint_cmd(struct view_obj *vop,
2396  int argc,
2397  const char *argv[])
2398 {
2399  struct bu_vls vls;
2400 
2401  /* Parse the incoming point */
2402  if (argc == 2 || argc == 4) {
2403  point_t viewPt;
2404  point_t modelPt;
2405 
2406  if (argc == 2) {
2407  if (bn_decode_vect(viewPt, argv[1]) != 3)
2408  goto bad;
2409  } else {
2410  double scan[3];
2411 
2412  if (sscanf(argv[1], "%lf", &scan[X]) != 1) {
2413  Tcl_AppendResult(vop->interp,
2414  "vo_v2mPoint: bad X value - ",
2415  argv[1],
2416  "\n",
2417  (char *)0);
2418  return TCL_ERROR;
2419  }
2420 
2421  if (sscanf(argv[2], "%lf", &scan[Y]) != 1) {
2422  Tcl_AppendResult(vop->interp,
2423  "vo_v2mPoint: bad Y value - ",
2424  argv[2],
2425  "\n",
2426  (char *)0);
2427  return TCL_ERROR;
2428  }
2429 
2430  if (sscanf(argv[3], "%lf", &scan[Z]) != 1) {
2431  Tcl_AppendResult(vop->interp,
2432  "vo_v2mPoint: bad Z value - ",
2433  argv[3],
2434  "\n",
2435  (char *)0);
2436  return TCL_ERROR;
2437  }
2438 
2439  /* convert double to fastf_t */
2440  VMOVE(viewPt, scan);
2441  }
2442 
2443  bu_vls_init(&vls);
2444  MAT4X3PNT(modelPt, vop->vo_view2model, viewPt);
2445  bn_encode_vect(&vls, modelPt);
2446  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
2447  bu_vls_free(&vls);
2448 
2449  return TCL_OK;
2450  }
2451 
2452 bad:
2453  /* compose error message */
2454  bu_vls_init(&vls);
2455  bu_vls_printf(&vls, "helplib_alias vo_v2mPoint %s", argv[0]);
2456  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2457  bu_vls_free(&vls);
2458 
2459  return TCL_ERROR;
2460 }
2461 
2462 
2463 /*
2464  * Convert view point to a model point.
2465  *
2466  * Usage:
2467  * procname v2mPoint vx vy vz
2468  */
2469 static int
2470 vo_v2mPoint_tcl(void *clientData,
2471  int argc,
2472  const char *argv[])
2473 {
2474  struct view_obj *vop = (struct view_obj *)clientData;
2475 
2476  return vo_v2mPoint_cmd(vop, argc-1, argv+1);
2477 }
2478 
2479 
2480 int
2481 vo_sca(struct view_obj *vop,
2482  fastf_t sf,
2483  int (*func)())
2484 {
2485  if (func != (int (*)())0)
2486  return (*func)(vop, sf);
2487 
2488  if (sf <= SMALL_FASTF || INFINITY < sf)
2489  return TCL_OK;
2490 
2491  vop->vo_scale *= sf;
2492  if (vop->vo_scale < RT_MINVIEWSIZE)
2493  vop->vo_scale = RT_MINVIEWSIZE;
2494  vop->vo_size = 2.0 * vop->vo_scale;
2495  vop->vo_invSize = 1.0 / vop->vo_size;
2496  vo_update(vop, 1);
2497  return TCL_OK;
2498 }
2499 
2500 
2501 int
2502 vo_sca_cmd(struct view_obj *vop,
2503  int argc,
2504  const char *argv[],
2505  int (*func)())
2506 {
2507  /* intentionally using double for scan */
2508  double sf;
2509 
2510  if (argc != 2) {
2511  struct bu_vls vls;
2512 
2513  bu_vls_init(&vls);
2514  bu_vls_printf(&vls, "helplib_alias vo_sca %s", argv[0]);
2515  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2516  bu_vls_free(&vls);
2517  return TCL_ERROR;
2518  }
2519 
2520  if (sscanf(argv[1], "%lf", &sf) != 1) {
2521  Tcl_AppendResult(vop->interp, "vo_sca: bad scale factor - ", argv[1], "\n", (char *)0);
2522  return TCL_ERROR;
2523  }
2524 
2525  return vo_sca(vop, sf, func);
2526 }
2527 
2528 
2529 /*
2530  * Usage:
2531  * procname sca [sf]
2532  */
2533 static int
2534 vo_sca_tcl(void *clientData,
2535  int argc,
2536  const char *argv[])
2537 {
2538  struct view_obj *vop = (struct view_obj *)clientData;
2539 
2540  return vo_sca_cmd(vop, argc-1, argv+1, (int (*)())0);
2541 }
2542 
2543 
2544 int
2545 vo_viewDir_cmd(struct view_obj *vop,
2546  int argc,
2547  const char *argv[])
2548 {
2549  vect_t view;
2550  vect_t model;
2551  mat_t invRot;
2552  struct bu_vls vls;
2553  int iflag = 0;
2554 
2555  if (2 < argc) {
2556  bu_vls_init(&vls);
2557  bu_vls_printf(&vls, "helplib_alias vo_viewDir %s", argv[0]);
2558  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2559  bu_vls_free(&vls);
2560  return TCL_ERROR;
2561  }
2562 
2563  /* Look for -i option */
2564  if (argc == 2 &&
2565  argv[1][0] == '-' &&
2566  argv[1][1] == 'i' &&
2567  argv[1][2] == '\0')
2568  iflag = 1;
2569 
2570  if (iflag) {
2571  VSET(view, 0.0, 0.0, -1.0);
2572  } else {
2573  VSET(view, 0.0, 0.0, 1.0);
2574  }
2575 
2576  bn_mat_inv(invRot, vop->vo_rotation);
2577  MAT4X3PNT(model, invRot, view);
2578 
2579  bu_vls_init(&vls);
2580  bn_encode_vect(&vls, model);
2581  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
2582  bu_vls_free(&vls);
2583 
2584  return TCL_OK;
2585 }
2586 
2587 
2588 /*
2589  * Usage:
2590  * procname viewDir[-i]
2591  */
2592 static int
2593 vo_viewDir_tcl(void *clientData,
2594  int argc,
2595  const char *argv[])
2596 {
2597  struct view_obj *vop = (struct view_obj *)clientData;
2598 
2599  return vo_viewDir_cmd(vop, argc-1, argv+1);
2600 }
2601 
2602 
2603 /* skeleton functions for view_obj methods */
2604 int
2605 vo_ae2dir_cmd(struct view_obj *vop, int argc, const char *argv[])
2606 {
2607  vect_t dir;
2608  int iflag;
2609  struct bu_vls vls;
2610 
2611  /* intentionally using double for scan */
2612  double az, el;
2613 
2614  if (argc < 3 || 4 < argc) {
2615  bu_vls_init(&vls);
2616  bu_vls_printf(&vls, "helplib_alias vo_ae2dir %s", argv[0]);
2617  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2618  bu_vls_free(&vls);
2619  return TCL_ERROR;
2620  }
2621 
2622  /* Look for -i option */
2623  if (argc == 4) {
2624  if (argv[1][0] != '-' ||
2625  argv[1][1] != 'i' ||
2626  argv[1][2] != '\0') {
2627  bu_vls_init(&vls);
2628  bu_vls_printf(&vls, "helplib_alias vo_ae2dir %s", argv[0]);
2629  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2630  bu_vls_free(&vls);
2631  return TCL_ERROR;
2632  }
2633 
2634  if (sscanf(argv[2], "%lf", &az) != 1 ||
2635  sscanf(argv[3], "%lf", &el) != 1) {
2636  bu_vls_init(&vls);
2637  bu_vls_printf(&vls, "helplib_alias vo_ae2dir %s", argv[0]);
2638  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2639  bu_vls_free(&vls);
2640  return TCL_ERROR;
2641  }
2642 
2643  iflag = 1;
2644  } else {
2645  if (sscanf(argv[1], "%lf", &az) != 1 ||
2646  sscanf(argv[2], "%lf", &el) != 1) {
2647  bu_vls_init(&vls);
2648  bu_vls_printf(&vls, "helplib_alias vo_ae2dir %s", argv[0]);
2649  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2650  bu_vls_free(&vls);
2651  return TCL_ERROR;
2652  }
2653 
2654  iflag = 0;
2655  }
2656 
2657  az *= DEG2RAD;
2658  el *= DEG2RAD;
2659  V3DIR_FROM_AZEL(dir, az, el);
2660 
2661  if (iflag)
2662  VSCALE(dir, dir, -1);
2663 
2664  bu_vls_init(&vls);
2665  bn_encode_vect(&vls, dir);
2666  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
2667  bu_vls_free(&vls);
2668 
2669  return TCL_OK;
2670 }
2671 
2672 
2673 /*
2674  * Usage:
2675  * procname ae2dir [-i] az el
2676  */
2677 static int
2678 vo_ae2dir_tcl(void *clientData,
2679  int argc,
2680  const char *argv[])
2681 {
2682  struct view_obj *vop = (struct view_obj *)clientData;
2683 
2684  return vo_ae2dir_cmd(vop, argc-1, argv+1);
2685 }
2686 
2687 
2688 /**
2689  * guts to the dir2ae command
2690  */
2691 int
2692 vo_dir2ae_cmd(struct view_obj *vop, int argc, const char *argv[])
2693 {
2694  fastf_t az, el;
2695  vect_t dir;
2696  int iflag = 0;
2697  struct bu_vls vls;
2698  double scan[3];
2699 
2700  if (argc < 4 || 5 < argc) {
2701  bu_vls_init(&vls);
2702  bu_vls_printf(&vls, "helplib_alias vo_dir2ae %s", argv[0]);
2703  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2704  bu_vls_free(&vls);
2705  return TCL_ERROR;
2706  }
2707 
2708  /* Look for -i option */
2709  if (argc == 5) {
2710  if (argv[1][0] != '-' ||
2711  argv[1][1] != 'i' ||
2712  argv[1][2] != '\0') {
2713  bu_vls_init(&vls);
2714  bu_vls_printf(&vls, "helplib_alias vo_dir2ae %s", argv[0]);
2715  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2716  bu_vls_free(&vls);
2717  return TCL_ERROR;
2718  }
2719  iflag = 1;
2720  argc--; argv++;
2721  }
2722 
2723  if (sscanf(argv[1], "%lf", &scan[X]) != 1 ||
2724  sscanf(argv[2], "%lf", &scan[Y]) != 1 ||
2725  sscanf(argv[3], "%lf", &scan[Z]) != 1) {
2726  bu_vls_init(&vls);
2727  bu_vls_printf(&vls, "helplib_alias vo_dir2ae %s", argv[0]);
2728  Tcl_Eval(vop->interp, bu_vls_addr(&vls));
2729  bu_vls_free(&vls);
2730  return TCL_ERROR;
2731  }
2732 
2733  /* convert from double to fastf_t */
2734  VMOVE(dir, scan);
2735 
2736  AZEL_FROM_V3DIR(az, el, dir);
2737 
2738  if (iflag)
2739  VSCALE(dir, dir, -1);
2740 
2741  bu_vls_init(&vls);
2742  bu_vls_printf(&vls, "%lf %lf", az, el);
2743  Tcl_AppendResult(vop->interp, bu_vls_addr(&vls), (char *)NULL);
2744  bu_vls_free(&vls);
2745 
2746  return TCL_OK;
2747 }
2748 
2749 
2750 /**
2751  * Usage:
2752  * procname dir2ae [-i] x y z
2753  */
2754 static int
2755 vo_dir2ae_tcl(void *clientData,
2756  int argc,
2757  const char *argv[])
2758 {
2759  struct view_obj *vop = (struct view_obj *)clientData;
2760 
2761  return vo_dir2ae_cmd(vop, argc-1, argv+1);
2762 }
2763 
2764 
2765 static int
2766 vo_cmd(ClientData clientData,
2767  Tcl_Interp *UNUSED(interp),
2768  int argc,
2769  const char *argv[])
2770 {
2771  int ret;
2772 
2773  static struct bu_cmdtab vo_cmds[] = {
2774  {"ae", vo_aet_tcl},
2775  {"ae2dir", vo_ae2dir_tcl},
2776  {"arot", vo_arot_tcl},
2777  {"base2local", vo_base2local_tcl},
2778  {"center", vo_center_tcl},
2779  {"coord", vo_coord_tcl},
2780  {"dir2ae", vo_dir2ae_tcl},
2781  {"eye", vo_eye_tcl},
2782  {"eye_pos", vo_eye_pos_tcl},
2783  {"invSize", vo_invSize_tcl},
2784  {"keypoint", vo_keypoint_tcl},
2785  {"local2base", vo_local2base_tcl},
2786  {"lookat", vo_lookat_tcl},
2787  {"m2vPoint", vo_m2vPoint_tcl},
2788  {"model2view", vo_model2view_tcl},
2789  {"mrot", vo_mrot_tcl},
2790  {"mrotPoint", vo_mrotPoint_tcl},
2791  {"observer", vo_observer_tcl},
2792  {"orientation", vo_orientation_tcl},
2793  {"perspective", vo_perspective_tcl},
2794  {"pmat", vo_pmat_tcl},
2795  {"pmodel2view", vo_pmodel2view_tcl},
2796  {"pov", vo_pov_tcl},
2797  {"rmat", vo_rmat_tcl},
2798  {"rot", vo_rot_tcl},
2799  {"rotate_about", vo_rotate_about_tcl},
2800  {"sca", vo_sca_tcl},
2801  {"setview", vo_setview_tcl},
2802  {"size", vo_size_tcl},
2803  {"slew", vo_slew_tcl},
2804  {"tra", vo_tra_tcl},
2805  {"units", vo_units_tcl},
2806  {"v2mPoint", vo_v2mPoint_tcl},
2807  {"view2model", vo_view2model_tcl},
2808  {"viewDir", vo_viewDir_tcl},
2809  {"vrot", vo_vrot_tcl},
2810  {"zoom", vo_zoom_tcl},
2811  {(const char *)NULL, BU_CMD_NULL}
2812  };
2813 
2814  if (bu_cmd(vo_cmds, argc, argv, 1, clientData, &ret) == BRLCAD_OK)
2815  return ret;
2816 
2817  bu_log("ERROR: '%s' command not found\n", argv[1]);
2818  return BRLCAD_ERROR;
2819 }
2820 
2821 
2822 /*
2823  * Open a view object.
2824  *
2825  * USAGE: v_open [name]
2826  */
2827 static int
2828 vo_open_tcl(ClientData UNUSED(clientData),
2829  Tcl_Interp *interp,
2830  int argc,
2831  const char *argv[])
2832 {
2833  struct view_obj *vop;
2834 
2835  if (argc == 1) {
2836  /* get list of view objects */
2837  for (BU_LIST_FOR(vop, view_obj, &HeadViewObj.l))
2838  Tcl_AppendResult(interp, bu_vls_addr(&vop->vo_name), " ", (char *)NULL);
2839 
2840  return TCL_OK;
2841  }
2842 
2843  /* first, delete any commands by this name */
2844  (void)Tcl_DeleteCommand(interp, argv[1]);
2845 
2846  vop = vo_open_cmd(argv[1]);
2847  vop->interp = interp;
2848  (void)Tcl_CreateCommand(interp,
2849  bu_vls_addr(&vop->vo_name),
2850  (Tcl_CmdProc *)vo_cmd,
2851  (ClientData)vop,
2852  vo_deleteProc);
2853 
2854  /* Return new function name as result */
2855  Tcl_ResetResult(interp);
2856  Tcl_AppendResult(interp, bu_vls_addr(&vop->vo_name), (char *)NULL);
2857 
2858  return TCL_OK;
2859 }
2860 
2861 
2862 int
2863 Vo_Init(Tcl_Interp *interp)
2864 {
2866  (void)Tcl_CreateCommand(interp, "v_open", vo_open_tcl,
2867  (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
2868 
2869  return TCL_OK;
2870 }
2871 
2872 
2873 /*
2874  * Local Variables:
2875  * mode: C
2876  * tab-width: 8
2877  * indent-tabs-mode: t
2878  * c-file-style: "stroustrup"
2879  * End:
2880  * ex: shiftwidth=4 tabstop=8
2881  */
void bn_ae_vec(fastf_t *azp, fastf_t *elp, const vect_t v)
Definition: mat.c:374
void vo_setview(struct view_obj *vop, vect_t rvec)
Definition: view_obj.c:1949
Definition: cmd.h:48
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
int vo_aet_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:290
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
int vo_zoom(struct view_obj *vop, fastf_t sf)
Definition: view_obj.c:1168
int vo_slew(struct view_obj *vop, vect_t svec)
Definition: view_obj.c:1643
int vo_rotate_about_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1815
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
int vo_orientation_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1033
int vo_rot(struct view_obj *vop, char coord, char rotate_about, mat_t rmat, int(*func)())
Definition: view_obj.c:1377
struct view_obj * vo_open_cmd(const char *oname)
Definition: view_obj.c:139
int bn_decode_quat(quat_t q, const char *str)
int vo_mrot_cmd(struct view_obj *vop, int argc, const char *argv[], int(*func)())
Definition: view_obj.c:2158
void bn_encode_vect(struct bu_vls *vp, const vect_t v)
int bu_observer_cmd(void *clientData, int argc, const char *argv[])
ustring interp
int vo_units_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1230
#define RT_MINVIEWSIZE
Definition: raytrace.h:1301
int vo_perspective_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:669
int vo_base2local_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1293
int vo_slew_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1657
#define VSET(a, b, c, d)
Definition: color.c:53
#define VSETALL(a, s)
Definition: color.c:54
struct view_obj HeadViewObj
Definition: view_obj.c:49
#define SMALL_FASTF
Definition: defines.h:342
void vo_center(struct view_obj *vop, point_t center)
Definition: view_obj.c:453
int vo_invSize_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:247
Header file for the BRL-CAD common definitions.
#define BU_CMD_NULL
Definition: cmd.h:37
#define BU_LIST_APPEND(old, new)
Definition: list.h:197
int vo_rot_cmd(struct view_obj *vop, int argc, const char *argv[], int(*func)())
Definition: view_obj.c:1450
int vo_arot_cmd(struct view_obj *vop, int argc, const char *argv[], int(*func)())
Definition: view_obj.c:2021
int vo_setview_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1958
int vo_local2base_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1335
int vo_mrotPoint_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:2225
void bn_mat_mul2(const mat_t i, mat_t o)
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
int Vo_Init(Tcl_Interp *interp)
Definition: view_obj.c:2863
Definition: color.c:49
int vo_zoom_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1188
void vo_size(struct view_obj *vop, fastf_t size)
Definition: view_obj.c:174
int vo_rmat_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:399
double bu_units_conversion(const char *str)
Definition: units.c:234
void vo_mat_aet(struct view_obj *vop)
Definition: view_obj.c:115
int vo_eye_pos_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:874
int vo_sca(struct view_obj *vop, fastf_t sf, int(*func)())
Definition: view_obj.c:2481
void bn_mat_inv(mat_t output, const mat_t input)
#define NEAR_ZERO(val, epsilon)
Definition: color.c:55
#define BRLCAD_OK
Definition: defines.h:71
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
#define SQRT_SMALL_FASTF
Definition: defines.h:346
int vo_ae2dir_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:2605
void persp_mat(mat_t m, fastf_t fovy, fastf_t aspect, fastf_t near1, fastf_t far1, fastf_t backoff)
Definition: mat.c:1209
int vo_pmodel2view_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:586
#define UNUSED(parameter)
Definition: common.h:239
int bn_decode_vect(vect_t v, const char *str)
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
int vo_tra(struct view_obj *vop, char coord, vect_t tvec, int(*func)())
Definition: view_obj.c:1531
void bn_mat_mul(mat_t o, const mat_t a, const mat_t b)
int vo_pmat_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:734
int vo_view2model_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:629
int vo_observer_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1732
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
void vo_update(struct view_obj *vop, int oflag)
Definition: view_obj.c:67
void bn_mat_angles(mat_t mat, double alpha, double beta, double ggamma)
void mike_persp_mat(fastf_t *pmat, const fastf_t *eye)
Definition: mat.c:1243
int bn_decode_mat(mat_t m, const char *str)
Support routines for the math functions.
int vo_viewDir_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:2545
#define ZERO(val)
Definition: units.c:38
#define BU_LIST_INIT(_hp)
Definition: list.h:148
const char * bu_units_string(const double mm)
axis
Definition: color.c:48
void bn_aet_vec(fastf_t *az, fastf_t *el, fastf_t *twist, vect_t vec_ae, vect_t vec_twist, fastf_t accuracy)
int vo_lookat_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:947
void bu_observer_free(struct bu_observer *)
Definition: observer.c:162
int vo_eye_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:777
int vo_model2view_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:543
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
int vo_m2vPoint_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:2313
int vo_tra_cmd(struct view_obj *vop, int argc, const char *argv[], int(*func)())
Definition: view_obj.c:1566
int vo_pov_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1087
int vo_center_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:463
void quat_quat2mat(mat_t mat, const quat_t quat)
Convert Quaternion to Matrix.
Definition: color.c:51
void bu_vls_strcpy(struct bu_vls *vp, const char *s)
Definition: vls.c:310
int vo_coord_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1763
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
int vo_v2mPoint_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:2395
void bn_mat_xform_about_pt(mat_t mat, const mat_t xform, const point_t pt)
Definition: mat.c:909
int vo_dir2ae_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:2692
#define RT_MINVIEWSCALE
Definition: raytrace.h:1302
int vo_size_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:189
Definition: vls.h:56
#define BRLCAD_ERROR
Definition: defines.h:72
HIDDEN const point_t delta
Definition: sh_prj.c:618
double fastf_t
Definition: defines.h:300
int vo_vrot_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:2092
int vo_sca_cmd(struct view_obj *vop, int argc, const char *argv[], int(*func)())
Definition: view_obj.c:2502
void bn_mat_zrot(mat_t m, double sinz, double cosz)
void bn_mat_arb_rot(mat_t m, const point_t pt, const vect_t dir, const fastf_t ang)
Definition: mat.c:987
Definition: color.c:50
int vo_keypoint_cmd(struct view_obj *vop, int argc, const char *argv[])
Definition: view_obj.c:1869
int bu_cmd(const struct bu_cmdtab *cmds, int argc, const char *argv[], int cmd_index, void *data, int *result)
void bu_observer_notify(Tcl_Interp *interp, struct bu_observer *headp, char *self)
Definition: observer.c:140
void bn_encode_mat(struct bu_vls *vp, const mat_t m)
Definition: tcl.c:108