1 /*!
2 \file lib/ogsf/gvl2.c
3
4 \brief OGSF library - loading and manipulating volumes
5
6 GRASS OpenGL gsurf OGSF Library
7
8 (C) 1999-2008 by the GRASS Development Team
9
10 This program is free software under the
11 GNU General Public License (>=v2).
12 Read the file COPYING that comes with GRASS
13 for details.
14
15 \author Bill Brown UI-GMSL (May 1997)
16 Tomas Paudits (February 2004)
17 */
18
19 #include <string.h>
20 #include <grass/gis.h>
21 #include <grass/raster3d.h>
22 #include <grass/ogsf.h>
23 #include <grass/glocale.h>
24 #include "gsget.h"
25
26 static int Vol_ID[MAX_VOLS];
27 static int Next_vol = 0;
28
29 static RASTER3D_Region wind3;
30 static double Region[6];
31
32 /*!
33 \brief Library initialization for volumes
34
35 Set region extent (N,S,W,E,T,B)
36 */
GVL_libinit(void)37 void GVL_libinit(void)
38 {
39 Rast3d_init_defaults();
40 Rast3d_get_window(&wind3);
41
42 Region[0] = wind3.north;
43 Region[1] = wind3.south;
44 Region[2] = wind3.west;
45 Region[3] = wind3.east;
46 Region[4] = wind3.top;
47 Region[5] = wind3.bottom;
48
49 return;
50 }
51
52 /*!
53 \brief Initialize 3D region
54
55 Set region extent (N,S,W,E,T,B)
56 */
GVL_init_region(void)57 void GVL_init_region(void)
58 {
59 Rast3d_read_window(&wind3, NULL);
60
61 Region[0] = wind3.north;
62 Region[1] = wind3.south;
63 Region[2] = wind3.west;
64 Region[3] = wind3.east;
65 Region[4] = wind3.top;
66 Region[5] = wind3.bottom;
67
68 return;
69 }
70
71 /*!
72 \brief Get region extent settings
73
74 \param[out] n,s,w,e north, south, west, east
75 \param[out] t,b top, bottom
76
77 \return 1
78 */
GVL_get_region(float * n,float * s,float * w,float * e,float * t,float * b)79 int GVL_get_region(float *n, float *s, float *w, float *e, float *t, float *b)
80 {
81 *n = Region[0];
82 *s = Region[1];
83 *w = Region[2];
84 *e = Region[3];
85 *t = Region[4];
86 *b = Region[5];
87
88 return (1);
89 }
90
91 /*!
92 \brief Get window
93
94 \todo gvl_file.c use this - change
95
96 \return pointer to RASTER3D_Region struct (static)
97 */
GVL_get_window()98 void *GVL_get_window()
99 {
100 return &wind3;
101 }
102
103 /*!
104 \brief Check if volume set exists
105
106 \param id volume set id
107
108 \return 1 found
109 \return 0 not found
110 */
GVL_vol_exists(int id)111 int GVL_vol_exists(int id)
112 {
113 int i, found = 0;
114
115 G_debug(3, "GVL_vol_exists");
116
117 if (NULL == gvl_get_vol(id)) {
118 return (0);
119 }
120
121 for (i = 0; i < Next_vol && !found; i++) {
122 if (Vol_ID[i] == id) {
123 found = 1;
124 }
125 }
126
127 return (found);
128 }
129
130 /*!
131 \brief Create new volume set
132
133 \return volume set id
134 \return -1 on error
135 */
GVL_new_vol(void)136 int GVL_new_vol(void)
137 {
138 geovol *nvl;
139
140 G_debug(3, "GVL_new_vol():");
141
142 if (Next_vol < MAX_VOLS) {
143 nvl = gvl_get_new_vol();
144
145 gvl_init_vol(nvl, wind3.west + wind3.ew_res / 2.,
146 wind3.south + wind3.ns_res / 2., wind3.bottom,
147 wind3.rows, wind3.cols, wind3.depths,
148 wind3.ew_res, wind3.ns_res, wind3.tb_res);
149
150 Vol_ID[Next_vol] = nvl->gvol_id;
151 ++Next_vol;
152
153 G_debug(3, " id=%d", nvl->gvol_id);
154
155 return (nvl->gvol_id);
156 }
157
158 return (-1);
159 }
160
161 /*!
162 \brief Get number of loaded volume sets
163
164 \return number of volume sets
165 */
GVL_num_vols(void)166 int GVL_num_vols(void)
167 {
168 return (gvl_num_vols());
169 }
170
171 /*!
172 \brief Get list of loaded volume sets
173
174 Must be freed if not needed!
175
176 \param[out] numvols number of volume sets
177
178 \return pointer to list of volume sets
179 \return NULL on error
180 */
GVL_get_vol_list(int * numvols)181 int *GVL_get_vol_list(int *numvols)
182 {
183 int i, *ret;
184
185 *numvols = Next_vol;
186
187 if (Next_vol) {
188 ret = (int *)G_malloc(Next_vol * sizeof(int));
189 if (!ret)
190 return (NULL);
191
192 for (i = 0; i < Next_vol; i++) {
193 ret[i] = Vol_ID[i];
194 }
195
196 return (ret);
197 }
198
199 return (NULL);
200 }
201
202 /*!
203 \brief Delete volume set from list
204
205 \param id volume set id
206
207 \return 1 on success
208 \return -1 on error (invalid volume set id)
209 */
GVL_delete_vol(int id)210 int GVL_delete_vol(int id)
211 {
212 int i, j, found = 0;
213
214 G_debug(3, "GVL_delete_vol");
215
216 if (GVL_vol_exists(id)) {
217
218 for (i = 0; i < GVL_isosurf_num_isosurfs(id); i++) {
219 GVL_isosurf_del(id, 0);
220 }
221
222 for (i = 0; i < GVL_slice_num_slices(id); i++) {
223 GVL_slice_del(id, 0);
224 }
225
226 gvl_delete_vol(id);
227
228 for (i = 0; i < Next_vol && !found; i++) {
229 if (Vol_ID[i] == id) {
230 found = 1;
231 for (j = i; j < Next_vol; j++) {
232 Vol_ID[j] = Vol_ID[j + 1];
233 }
234 }
235 }
236
237 if (found) {
238 --Next_vol;
239
240 return (1);
241 }
242 }
243
244 return (-1);
245 }
246
247 /*!
248 \brief Load 3d raster map to volume set
249
250 \param id volume set id
251 \param filename 3d raster map name
252
253 \return -1 on error
254 \return 0 on success
255 */
GVL_load_vol(int id,const char * filename)256 int GVL_load_vol(int id, const char *filename)
257 {
258 geovol *gvl;
259 int handle;
260
261 G_debug(3, "GVL_load_vol(): id=%d, name=%s", id, filename);
262
263 if (NULL == (gvl = gvl_get_vol(id))) {
264 return (-1);
265 }
266
267 G_message(_("Loading 3d raster map <%s>..."), filename);
268
269 if (0 > (handle = gvl_file_newh(filename, VOL_FTYPE_RASTER3D)))
270 return (-1);
271
272 gvl->hfile = handle;
273
274 return (0);
275 }
276
277 /*!
278 \brief Get volume set name
279
280 \param id volume set id
281 \param[out] filename name (must be allocated)
282
283 \return -1 on error
284 \return 1 on success
285 */
GVL_get_volname(int id,char * filename)286 int GVL_get_volname(int id, char *filename)
287 {
288 geovol *gvl;
289
290 if (NULL == (gvl = gvl_get_vol(id))) {
291 return (-1);
292 }
293
294 if (0 > gvl->hfile) {
295 return (-1);
296 }
297
298 strcpy(filename, gvl_file_get_name(gvl->hfile));
299
300 return (1);
301 }
302
303 /*!
304 \brief Get volume dimensions
305
306 \param id volume set id
307 \param[out] rows,cols,depths number of rows, cols, depths
308 */
GVL_get_dims(int id,int * rows,int * cols,int * depths)309 void GVL_get_dims(int id, int *rows, int *cols, int *depths)
310 {
311 geovol *gvl;
312
313 gvl = gvl_get_vol(id);
314
315 if (gvl) {
316 *rows = gvl->rows;
317 *cols = gvl->cols;
318 *depths = gvl->depths;
319 }
320
321 G_debug(3, "GVL_get_dims() id=%d, rows=%d, cols=%d, depths=%d",
322 gvl->gvol_id, gvl->rows, gvl->cols, gvl->depths);
323
324 return;
325 }
326
327 /*!
328 \brief Set trans ?
329
330 \param id volume set id
331 \param xtrans,ytrans,ztrans x/y/z trans values
332 */
GVL_set_trans(int id,float xtrans,float ytrans,float ztrans)333 void GVL_set_trans(int id, float xtrans, float ytrans, float ztrans)
334 {
335 geovol *gvl;
336
337 G_debug(3, "GVL_set_trans");
338
339 gvl = gvl_get_vol(id);
340
341 if (gvl) {
342 gvl->x_trans = xtrans;
343 gvl->y_trans = ytrans;
344 gvl->z_trans = ztrans;
345 }
346
347 return;
348 }
349
350 /*!
351 \brief Get trans ?
352
353 \param id volume set id
354 \param[out] xtrans,ytrans,ztrans x/y/z trans values
355
356 \return 1 on success
357 \return -1 on error
358 */
GVL_get_trans(int id,float * xtrans,float * ytrans,float * ztrans)359 int GVL_get_trans(int id, float *xtrans, float *ytrans, float *ztrans)
360 {
361 geovol *gvl;
362
363 gvl = gvl_get_vol(id);
364
365 if (gvl) {
366 *xtrans = gvl->x_trans;
367 *ytrans = gvl->y_trans;
368 *ztrans = gvl->z_trans;
369
370 return (1);
371 }
372
373 return (-1);
374 }
375
376 /*!
377 \brief Set drawing wire box
378
379 \param id volume set id
380 \param draw_wire 1 for drawing wire, 0 otherwise
381 */
GVL_set_draw_wire(int id,int draw_wire)382 void GVL_set_draw_wire(int id, int draw_wire)
383 {
384 geovol *gvl;
385
386 G_debug(3, "GVL_set_draw_wire");
387
388 gvl = gvl_get_vol(id);
389
390 if (gvl) {
391 gvl->draw_wire = draw_wire;
392 }
393
394 return;
395 }
396
397 /*!
398 \brief Draw volume set
399
400 \param vid volume set id
401 */
GVL_draw_vol(int vid)402 void GVL_draw_vol(int vid)
403 {
404 geovol *gvl;
405
406 gvl = gvl_get_vol(vid);
407
408 if (gvl) {
409 gvld_vol(gvl);
410 if (gvl->draw_wire) {
411 gvld_wind3_box(gvl);
412 }
413 }
414
415 return;
416 }
417
418 /*!
419 \brief Draw volume in wire mode
420
421 \param id volume set id
422 */
GVL_draw_wire(int id)423 void GVL_draw_wire(int id)
424 {
425 geovol *gvl;
426
427 G_debug(3, "GVL_draw_wire(): id=%d", id);
428
429 gvl = gvl_get_vol(id);
430
431 if (gvl) {
432 gvld_wire_vol(gvl);
433 }
434
435 return;
436 }
437
438 /*!
439 \brief Draw all volume sets
440 */
GVL_alldraw_vol(void)441 void GVL_alldraw_vol(void)
442 {
443 int id;
444
445 for (id = 0; id < Next_vol; id++) {
446 GVL_draw_vol(Vol_ID[id]);
447 }
448
449 return;
450 }
451
452 /*!
453 \brief Draw all volume sets in wire mode
454 */
GVL_alldraw_wire(void)455 void GVL_alldraw_wire(void)
456 {
457 int id;
458
459 for (id = 0; id < Next_vol; id++) {
460 GVL_draw_wire(Vol_ID[id]);
461 }
462
463 return;
464 }
465
466 /*!
467 \brief Set client data for volume set
468
469 \param id volume set id
470 \param clientd pointer to client data
471
472 \return 1 on success
473 \return -1 on error
474 */
GVL_Set_ClientData(int id,void * clientd)475 int GVL_Set_ClientData(int id, void *clientd)
476 {
477 geovol *gvl;
478
479 gvl = gvl_get_vol(id);
480
481 if (gvl) {
482 gvl->clientdata = clientd;
483
484 return (1);
485 }
486
487 return (-1);
488 }
489
490 /*!
491 \brief Get client data
492
493 \param id volume set id
494
495 \return pointer to client data
496 \return NULL on error
497 */
GVL_Get_ClientData(int id)498 void *GVL_Get_ClientData(int id)
499 {
500 geovol *gvl;
501
502 gvl = gvl_get_vol(id);
503
504 if (gvl) {
505 return (gvl->clientdata);
506 }
507
508 return (NULL);
509 }
510
511 /*!
512 \brief Set focus on map center
513
514 \param id volume set id
515 */
GVL_set_focus_center_map(int id)516 void GVL_set_focus_center_map(int id)
517 {
518 float center[3];
519 geovol *gvl;
520
521 G_debug(3, "GS_set_focus_center_map");
522
523 gvl = gvl_get_vol(id);
524
525 if (gvl) {
526 center[X] = (gvl->xmax - gvl->xmin) / 2.;
527 center[Y] = (gvl->ymax - gvl->ymin) / 2.;
528 center[Z] = (gvl->zmax - gvl->zmin) / 2.;
529
530 GS_set_focus(center);
531 }
532
533 return;
534 }
535
536 /************************************************************************/
537 /* ISOSURFACES */
538
539 /************************************************************************/
540
541 /*!
542 \brief Get draw resolution for isosurface
543
544 \todo error handling
545
546 \param id volume set id
547 \param[out] xres,yres,zres x/y/z resolution value
548 */
GVL_isosurf_get_drawres(int id,int * xres,int * yres,int * zres)549 void GVL_isosurf_get_drawres(int id, int *xres, int *yres, int *zres)
550 {
551 geovol *gvl;
552
553 G_debug(3, "GVL_isosurf_get_drawres");
554
555 gvl = gvl_get_vol(id);
556
557 if (gvl) {
558 *xres = gvl->isosurf_x_mod;
559 *yres = gvl->isosurf_y_mod;
560 *zres = gvl->isosurf_z_mod;
561 }
562
563 return;
564 }
565
566 /*!
567 \brief Set isosurface draw resolution
568
569 \param id volume set id
570 \param xres,yres,zres x/y/z resolution value
571
572 \return -1 on error (invalid values/volume set id)
573 \return 0 on success
574 */
GVL_isosurf_set_drawres(int id,int xres,int yres,int zres)575 int GVL_isosurf_set_drawres(int id, int xres, int yres, int zres)
576 {
577 geovol *gvl;
578 int i;
579
580 G_debug(3, "GVL_isosurf_set_drawres(): id=%d", id);
581
582 if (xres < 1 || yres < 1 || zres < 1) {
583 return (-1);
584 }
585
586 gvl = gvl_get_vol(id);
587
588 if (gvl) {
589 gvl->isosurf_x_mod = xres;
590 gvl->isosurf_y_mod = yres;
591 gvl->isosurf_z_mod = zres;
592
593 for (i = 0; i < gvl->n_isosurfs; i++) {
594 gvl_isosurf_set_att_changed(gvl->isosurf[i], ATT_TOPO);
595 }
596
597 return (0);
598 }
599
600 return (-1);
601 }
602
603 /*!
604 \brief Get isosurface draw mode
605
606 \param id volume set id
607 \param[out] mode draw-mode
608
609 \return 1 on success
610 \return -1 on error
611 */
GVL_isosurf_get_drawmode(int id,int * mode)612 int GVL_isosurf_get_drawmode(int id, int *mode)
613 {
614 geovol *gvl;
615
616 gvl = gvl_get_vol(id);
617
618 if (gvl) {
619 *mode = gvl->isosurf_draw_mode;
620
621 return (1);
622 }
623
624 return (-1);
625 }
626
627 /*!
628 \brief Set isosurface draw mode
629
630 \param id volume set id
631 \param mode draw mode
632
633 \return 0 on success
634 \return -1 on error (invalid volume set id)
635 */
GVL_isosurf_set_drawmode(int id,int mode)636 int GVL_isosurf_set_drawmode(int id, int mode)
637 {
638 geovol *gvl;
639
640 G_debug(3, "GVL_isosurf_set_drawmode(): id=%d mode=%d", id, mode);
641
642 gvl = gvl_get_vol(id);
643
644 if (gvl) {
645 gvl->isosurf_draw_mode = mode;
646
647 return (0);
648 }
649
650 return (-1);
651 }
652
653 /*!
654 \brief Add isosurface
655
656 \param id volume set id
657
658 \return -1 on error (invalid volume set id
659 \return 1 on success
660 */
GVL_isosurf_add(int id)661 int GVL_isosurf_add(int id)
662 {
663 geovol *gvl;
664 geovol_isosurf *isosurf;
665
666 G_debug(3, "GVL_isosurf_add() id=%d", id);
667
668 gvl = gvl_get_vol(id);
669
670 if (!gvl)
671 return (-1);
672
673 if (gvl->n_isosurfs == MAX_ISOSURFS)
674 return (-1);
675
676 isosurf = (geovol_isosurf *) G_malloc(sizeof(geovol_isosurf));
677 if (!isosurf) {
678 return (-1);
679 }
680
681 gvl_isosurf_init(isosurf);
682
683 gvl->n_isosurfs++;
684 gvl->isosurf[gvl->n_isosurfs - 1] = (geovol_isosurf *) isosurf;
685
686 return (1);
687 }
688
689 /*!
690 \brief Delete isosurface
691
692 \param id volume set id
693 \param isosurf_id isosurface id
694
695 \return -1 on error
696 \return 1 on success
697 */
GVL_isosurf_del(int id,int isosurf_id)698 int GVL_isosurf_del(int id, int isosurf_id)
699 {
700 geovol *gvl;
701 geovol_isosurf *isosurf;
702 int i;
703
704 G_debug(3, "GVL_isosurf_del");
705
706 isosurf = gvl_isosurf_get_isosurf(id, isosurf_id);
707
708 if (!isosurf)
709 return (-1);
710
711 if (!gvl_isosurf_freemem(isosurf)) {
712 return (-1);
713 }
714
715 gvl = gvl_get_vol(id);
716
717 G_free(gvl->isosurf[isosurf_id]);
718
719 for (i = isosurf_id + 1; i < gvl->n_isosurfs; i++) {
720 gvl->isosurf[i - 1] = gvl->isosurf[i];
721 }
722
723 gvl->n_isosurfs--;
724
725 return (1);
726 }
727
728 /*!
729 \brief Move up isosurface in list
730
731 \param id volume set id
732 \param isosurf_id isosurface id
733
734 \return -1 on error
735 \return 1 on success
736 */
GVL_isosurf_move_up(int id,int isosurf_id)737 int GVL_isosurf_move_up(int id, int isosurf_id)
738 {
739 geovol *gvl;
740 geovol_isosurf *tmp;
741
742 G_debug(3, "GVL_isosurf_move_up");
743
744 gvl = gvl_get_vol(id);
745
746 if (!gvl)
747 return (-1);
748
749 if (isosurf_id < 0 || isosurf_id > (gvl->n_isosurfs - 1))
750 return (-1);
751
752 if (isosurf_id == 0)
753 return (1);
754
755 tmp = gvl->isosurf[isosurf_id - 1];
756 gvl->isosurf[isosurf_id - 1] = gvl->isosurf[isosurf_id];
757 gvl->isosurf[isosurf_id] = tmp;
758
759 return (1);
760 }
761
762 /*!
763 \brief Move down isosurface in list
764
765 \param id volume set id
766 \param isosurf_id isosurface id
767
768 \return -1 on error
769 \return 1 on success
770 */
GVL_isosurf_move_down(int id,int isosurf_id)771 int GVL_isosurf_move_down(int id, int isosurf_id)
772 {
773 geovol *gvl;
774 geovol_isosurf *tmp;
775
776 G_debug(3, "GVL_isosurf_move_up");
777
778 gvl = gvl_get_vol(id);
779
780 if (!gvl)
781 return (-1);
782
783 if (isosurf_id < 0 || isosurf_id > (gvl->n_isosurfs - 1))
784 return (-1);
785
786 if (isosurf_id == (gvl->n_isosurfs - 1))
787 return (1);
788
789 tmp = gvl->isosurf[isosurf_id + 1];
790 gvl->isosurf[isosurf_id + 1] = gvl->isosurf[isosurf_id];
791 gvl->isosurf[isosurf_id] = tmp;
792
793 return (1);
794 }
795
796 /*!
797 \brief Get isosurface attributes
798
799 \param id volume set id
800 \param isosurf_id surface id
801 \param att attribute id
802 \param[out] set
803 \param[out] constant
804 \param[out] mapname
805
806 \return -1 on error
807 \return 1 on success
808 */
GVL_isosurf_get_att(int id,int isosurf_id,int att,int * set,float * constant,char * mapname)809 int GVL_isosurf_get_att(int id, int isosurf_id,
810 int att, int *set, float *constant, char *mapname)
811 {
812 int src;
813 geovol_isosurf *isosurf;
814
815 G_debug(3, "GVL_isosurf_get_att");
816
817 isosurf = gvl_isosurf_get_isosurf(id, isosurf_id);
818
819 if (isosurf) {
820 if (-1 != (src = gvl_isosurf_get_att_src(isosurf, att))) {
821 *set = src;
822
823 if (src == CONST_ATT) {
824 *constant = isosurf->att[att].constant;
825 }
826 else if (src == MAP_ATT) {
827 strcpy(mapname, gvl_file_get_name(isosurf->att[att].hfile));
828 }
829
830 return (1);
831 }
832
833 return (-1);
834 }
835
836 return (-1);
837 }
838
839 /*!
840 \brief Unset isosurface attributes
841
842 \param id volume set id
843 \param isosurface_id isosurface id
844 \param att attribute id
845
846 \return ?
847 \return -1 on error
848 */
GVL_isosurf_unset_att(int id,int isosurf_id,int att)849 int GVL_isosurf_unset_att(int id, int isosurf_id, int att)
850 {
851 geovol_isosurf *isosurf;
852
853 G_debug(3, "GVL_isosurf_unset_att");
854
855 isosurf = gvl_isosurf_get_isosurf(id, isosurf_id);
856
857 if (isosurf) {
858 return (gvl_isosurf_set_att_src(isosurf, att, NOTSET_ATT));
859 }
860
861 return (-1);
862 }
863
864 /*!
865 \brief Set constant isosurface attribute
866
867 Attributes:
868 - ATT_NORM
869 - ATT_TOPO topography (level) constant
870 - ATT_COLOR color map/constant
871 - ATT_MASK mask map
872 - ATT_TRANSP transparency map/constant
873 - ATT_SHINE shininess map/constant
874 - ATT_EMIT emission map/constant
875
876 \param id volume set id
877 \param isosurf_id isosurface id (0 - MAX_ISOSURFS)
878 \param att attribute descriptor
879 \param constant constant value
880
881 \return 1 on success
882 \return -1 on error
883 */
GVL_isosurf_set_att_const(int id,int isosurf_id,int att,float constant)884 int GVL_isosurf_set_att_const(int id, int isosurf_id, int att, float constant)
885 {
886 geovol_isosurf *isosurf;
887
888 G_debug(3, "GVL_isosurf_set_att_const() id=%d isosurf_id=%d "
889 "att=%d const=%f", id, isosurf_id, att, constant);
890
891 isosurf = gvl_isosurf_get_isosurf(id, isosurf_id);
892
893 if (isosurf) {
894 return (gvl_isosurf_set_att_const(isosurf, att, constant));
895 }
896
897 return (-1);
898 }
899
900 /*!
901 \brief Set isosurface map attribute
902
903 Attributes:
904 - ATT_NORM
905 - ATT_TOPO topography (level) constant
906 - ATT_COLOR color map/constant
907 - ATT_MASK mask map
908 - ATT_TRANSP transparency map/constant
909 - ATT_SHINE shininess map/constant
910 - ATT_EMIT emission map/constant
911
912 \param id volume set id
913 \param isosurf_id isosurface id (0 - MAX_ISOSURFS)
914 \param att attribute descriptor
915 \param filename map name
916
917 \return 1 on success
918 \return -1 on error
919 */
GVL_isosurf_set_att_map(int id,int isosurf_id,int att,const char * filename)920 int GVL_isosurf_set_att_map(int id, int isosurf_id, int att,
921 const char *filename)
922 {
923 geovol_isosurf *isosurf;
924
925 G_debug(3, "GVL_isosurf_set_att_map(): id=%d, isosurf_id=%d "
926 "att=%d map=%s", id, isosurf_id, att, filename);
927
928 isosurf = gvl_isosurf_get_isosurf(id, isosurf_id);
929
930 if (isosurf) {
931 return gvl_isosurf_set_att_map(isosurf, att, filename);
932 }
933
934 return (-1);
935 }
936
937 /*!
938 \brief Get isosurface flags
939
940 \param id volume set id
941 \param isosurf_id isosurface id
942 \param[out] inout map name
943
944 \return 1 on success
945 \return -1 on error
946 */
GVL_isosurf_get_flags(int id,int isosurf_id,int * inout)947 int GVL_isosurf_get_flags(int id, int isosurf_id, int *inout)
948 {
949 geovol_isosurf *isosurf;
950
951 G_debug(3, "GVL_isosurf_get_flags");
952
953 isosurf = gvl_isosurf_get_isosurf(id, isosurf_id);
954
955 if (isosurf) {
956 *inout = isosurf->inout_mode;
957
958 return (1);
959 }
960 return (-1);
961 }
962
963 /*!
964 \brief Set isosurface flags
965
966 \param id volume set id
967 \param isosurf_id isosurface id
968 \param inout map name
969
970 \return 1 on success
971 \return -1 on error
972 */
GVL_isosurf_set_flags(int id,int isosurf_id,int inout)973 int GVL_isosurf_set_flags(int id, int isosurf_id, int inout)
974 {
975 geovol_isosurf *isosurf;
976
977 G_debug(3, "GVL_isosurf_get_flags");
978
979 isosurf = gvl_isosurf_get_isosurf(id, isosurf_id);
980
981 if (isosurf) {
982 isosurf->inout_mode = inout;
983
984 return (1);
985 }
986
987 return (-1);
988 }
989
990 /*!
991 \brief Get number of available isosurfaces
992
993 \param id volume set id
994
995 \return number of isosurfaces
996 \return -1 on error
997 */
GVL_isosurf_num_isosurfs(int id)998 int GVL_isosurf_num_isosurfs(int id)
999 {
1000 geovol *gvl;
1001
1002 G_debug(3, "GVL_isosurf_num_isosurfs");
1003
1004 gvl = gvl_get_vol(id);
1005
1006 if (gvl) {
1007 return gvl->n_isosurfs;
1008 }
1009
1010 return (-1);
1011 }
1012
1013 /*!
1014 \brief Set mask attribute mode
1015
1016 Mask attribute special: constant is set to indicate invert or no
1017
1018 \param id volume set id
1019 \param isosurf_id isosurface id
1020 \param mode attribute mode
1021
1022 \return mode id
1023 \return -1 on error
1024 */
GVL_isosurf_set_maskmode(int id,int isosurf_id,int mode)1025 int GVL_isosurf_set_maskmode(int id, int isosurf_id, int mode)
1026 {
1027 geovol_isosurf *isosurf;
1028
1029 G_debug(3, "GVL_isosurf_set_att_const");
1030
1031 isosurf = gvl_isosurf_get_isosurf(id, isosurf_id);
1032
1033 if (isosurf) {
1034 isosurf->att[ATT_MASK].constant = mode;
1035
1036 return (mode);
1037 }
1038
1039 return (-1);
1040 }
1041
1042 /*!
1043 \brief Get isosurface mask mode
1044
1045 \param id volume set id
1046 \param isosurf_id isosurface id
1047 \param mode attribute mode
1048
1049 \return 1 on success
1050 \return -1 on error
1051 */
GVL_isosurf_get_maskmode(int id,int isosurf_id,int * mode)1052 int GVL_isosurf_get_maskmode(int id, int isosurf_id, int *mode)
1053 {
1054 geovol_isosurf *isosurf;
1055
1056 isosurf = gvl_isosurf_get_isosurf(id, isosurf_id);
1057
1058 if (isosurf) {
1059 *mode = isosurf->att[ATT_MASK].constant;
1060
1061 return (1);
1062 }
1063
1064 return (-1);
1065 }
1066
1067 /************************************************************************/
1068 /* SLICES */
1069
1070 /************************************************************************/
1071
1072 /*!
1073 \brief Get draw resolution of slice
1074
1075 \param id volume set id
1076 \param[out] xres,yres,zres x/y/z resolution value
1077 */
GVL_slice_get_drawres(int id,int * xres,int * yres,int * zres)1078 void GVL_slice_get_drawres(int id, int *xres, int *yres, int *zres)
1079 {
1080 geovol *gvl;
1081
1082 G_debug(3, "GVL_slice_get_drawres");
1083
1084 gvl = gvl_get_vol(id);
1085
1086 if (gvl) {
1087 *xres = gvl->slice_x_mod;
1088 *yres = gvl->slice_y_mod;
1089 *zres = gvl->slice_z_mod;
1090 }
1091
1092 return;
1093 }
1094
1095 /*!
1096 \brief Set slice draw resolution
1097
1098 \param id volume set id
1099 \param xres,yres,zres x/y/z resolution value
1100
1101 \return 0 on success
1102 \return -1 on error (invalid value or id)
1103 */
GVL_slice_set_drawres(int id,int xres,int yres,int zres)1104 int GVL_slice_set_drawres(int id, int xres, int yres, int zres)
1105 {
1106 geovol *gvl;
1107 int i;
1108
1109 G_debug(3, "GVL_slice_set_drawres(): id=%d", id);
1110
1111 if (xres < 1 || yres < 1 || zres < 1) {
1112 return (-1);
1113 }
1114
1115 gvl = gvl_get_vol(id);
1116
1117 if (gvl) {
1118 gvl->slice_x_mod = xres;
1119 gvl->slice_y_mod = yres;
1120 gvl->slice_z_mod = zres;
1121
1122 for (i = 0; i < gvl->n_slices; i++) {
1123 gvl->slice[i]->changed = 1;
1124 }
1125
1126 return (0);
1127 }
1128
1129 return (-1);
1130 }
1131
1132 /*!
1133 \brief Get slice draw mode
1134
1135 \param id volume set id
1136 \param[out] mode draw mode
1137
1138 \return 1 on success
1139 \return -1 on error (invalid id)
1140 */
GVL_slice_get_drawmode(int id,int * mode)1141 int GVL_slice_get_drawmode(int id, int *mode)
1142 {
1143 geovol *gvl;
1144
1145 gvl = gvl_get_vol(id);
1146
1147 if (gvl) {
1148 *mode = gvl->slice_draw_mode;
1149
1150 return (1);
1151 }
1152
1153 return (-1);
1154 }
1155
1156 /*!
1157 \brief Set slice draw mode
1158
1159 \param id volume set id
1160 \param mode draw mode
1161
1162 \return 0 on success
1163 \return -1 on error (invalid id)
1164 */
GVL_slice_set_drawmode(int id,int mode)1165 int GVL_slice_set_drawmode(int id, int mode)
1166 {
1167 geovol *gvl;
1168
1169 G_debug(3, "GVL_slice_set_drawmode(): id=%d, mode=%d", id, mode);
1170
1171 gvl = gvl_get_vol(id);
1172
1173 if (gvl) {
1174 gvl->slice_draw_mode = mode;
1175
1176 return (0);
1177 }
1178
1179 return (-1);
1180 }
1181
1182 /*!
1183 \brief Add slice
1184
1185 \param id volume set id
1186
1187 \return -1 on error
1188 \return 1 on success
1189 */
GVL_slice_add(int id)1190 int GVL_slice_add(int id)
1191 {
1192 geovol *gvl;
1193 geovol_slice *slice;
1194
1195 G_debug(3, "GVL_slice_add");
1196
1197 gvl = gvl_get_vol(id);
1198
1199 if (!gvl)
1200 return (-1);
1201
1202 if (gvl->n_slices == MAX_SLICES)
1203 return (-1);
1204
1205 if (NULL == (slice = (geovol_slice *) G_malloc(sizeof(geovol_slice)))) {
1206 return (-1);
1207 }
1208
1209 gvl_slice_init(slice);
1210
1211 gvl->n_slices++;
1212 gvl->slice[gvl->n_slices - 1] = (geovol_slice *) slice;
1213
1214 return (1);
1215 }
1216
1217 /*!
1218 \brief Delete slice
1219
1220 \param id volume set id
1221 \param slice_id slice id
1222
1223 \return -1 on error
1224 \return 1 on success
1225 */
GVL_slice_del(int id,int slice_id)1226 int GVL_slice_del(int id, int slice_id)
1227 {
1228 geovol *gvl;
1229 geovol_slice *slice;
1230 int i;
1231
1232 G_debug(3, "GVL_slice_del");
1233
1234 slice = gvl_slice_get_slice(id, slice_id);
1235
1236 if (!slice)
1237 return (-1);
1238
1239 if (!gvl_slice_freemem(slice)) {
1240 return (-1);
1241 }
1242
1243 gvl = gvl_get_vol(id);
1244
1245 G_free(gvl->slice[slice_id]);
1246
1247 for (i = slice_id + 1; i < gvl->n_slices; i++) {
1248 gvl->slice[i - 1] = gvl->slice[i];
1249 }
1250
1251 gvl->n_slices--;
1252
1253 return (1);
1254 }
1255
1256 /*!
1257 \brief Move up slice
1258
1259 \param id volume set id
1260 \param slice_id slice id
1261
1262 \return -1 on error
1263 \return 1 on success
1264 */
GVL_slice_move_up(int id,int slice_id)1265 int GVL_slice_move_up(int id, int slice_id)
1266 {
1267 geovol *gvl;
1268 geovol_slice *tmp;
1269
1270 G_debug(3, "GVL_slice_move_up");
1271
1272 gvl = gvl_get_vol(id);
1273
1274 if (!gvl)
1275 return (-1);
1276
1277 if (slice_id < 0 || slice_id > (gvl->n_slices - 1))
1278 return (-1);
1279
1280 if (slice_id == 0)
1281 return (1);
1282
1283 tmp = gvl->slice[slice_id - 1];
1284 gvl->slice[slice_id - 1] = gvl->slice[slice_id];
1285 gvl->slice[slice_id] = tmp;
1286
1287 return (1);
1288 }
1289
1290 /*!
1291 \brief Move down slice
1292
1293 \param id volume set id
1294 \param slice_id slice id
1295
1296 \return -1 on error
1297 \return 1 on success
1298 */
GVL_slice_move_down(int id,int slice_id)1299 int GVL_slice_move_down(int id, int slice_id)
1300 {
1301 geovol *gvl;
1302 geovol_slice *tmp;
1303
1304 G_debug(3, "GVL_slice_move_up");
1305
1306 gvl = gvl_get_vol(id);
1307
1308 if (!gvl)
1309 return (-1);
1310
1311 if (slice_id < 0 || slice_id > (gvl->n_slices - 1))
1312 return (-1);
1313
1314 if (slice_id == (gvl->n_slices - 1))
1315 return (1);
1316
1317 tmp = gvl->slice[slice_id + 1];
1318 gvl->slice[slice_id + 1] = gvl->slice[slice_id];
1319 gvl->slice[slice_id] = tmp;
1320
1321 return (1);
1322 }
1323
1324 /*!
1325 \brief Get number or slices
1326
1327 \param id volume set id
1328
1329 \return number of slices
1330 \return -1 on error
1331 */
GVL_slice_num_slices(int id)1332 int GVL_slice_num_slices(int id)
1333 {
1334 geovol *gvl;
1335
1336 G_debug(3, "GVL_isosurf_num_isosurfs");
1337
1338 gvl = gvl_get_vol(id);
1339
1340 if (gvl) {
1341 return gvl->n_slices;
1342 }
1343
1344 return (-1);
1345 }
1346
1347 /*!
1348 \brief Get slice position
1349
1350 \param id volume set id
1351 \param slice_id slice id
1352 \param[out] x1,y1,z1 coordinates ?
1353 \param[out] x2,y2,z2 coordinates ?
1354 \param[out] dir direction
1355
1356 \return -1 on error
1357 \return 1 on success
1358 */
GVL_slice_get_pos(int id,int slice_id,float * x1,float * x2,float * y1,float * y2,float * z1,float * z2,int * dir)1359 int GVL_slice_get_pos(int id, int slice_id,
1360 float *x1, float *x2, float *y1, float *y2, float *z1,
1361 float *z2, int *dir)
1362 {
1363 geovol *gvl;
1364 geovol_slice *slice;
1365 int cols, rows, depths;
1366
1367 gvl = gvl_get_vol(id);
1368
1369 if (!gvl)
1370 return (-1);
1371
1372 slice = gvl_slice_get_slice(id, slice_id);
1373
1374 if (!slice)
1375 return (-1);
1376
1377 if (slice->dir == X) {
1378 cols = gvl->rows;
1379 rows = gvl->depths;
1380 depths = gvl->cols;
1381 }
1382 else if (slice->dir == Y) {
1383 cols = gvl->cols;
1384 rows = gvl->depths;
1385 depths = gvl->rows;
1386 }
1387 else if (slice->dir == Z) {
1388 cols = gvl->cols;
1389 rows = gvl->rows;
1390 depths = gvl->depths;
1391 }
1392 else {
1393 return (-1);
1394 }
1395
1396 *x1 = slice->x1 / (cols - 1);
1397 *x2 = slice->x2 / (cols - 1);
1398 *y1 = slice->y1 / (rows - 1);
1399 *y2 = slice->y2 / (rows - 1);
1400 *z1 = slice->z1 / (depths - 1);
1401 *z2 = slice->z2 / (depths - 1);
1402
1403 *dir = slice->dir;
1404
1405 return (1);
1406 }
1407
1408 /*!
1409 \brief Get slice position
1410
1411 \param id volume set id
1412 \param slice_id slice id
1413 \param x1,y1,z1 coordinates ?
1414 \param x2,y2,z2 coordinates ?
1415 \param dir direction
1416
1417 \return -1 on error
1418 \return 1 on success
1419 */
GVL_slice_set_pos(int id,int slice_id,float x1,float x2,float y1,float y2,float z1,float z2,int dir)1420 int GVL_slice_set_pos(int id, int slice_id,
1421 float x1, float x2, float y1, float y2, float z1,
1422 float z2, int dir)
1423 {
1424 geovol *gvl;
1425 geovol_slice *slice;
1426 int cols, rows, depths;
1427
1428 gvl = gvl_get_vol(id);
1429
1430 if (!gvl)
1431 return (-1);
1432
1433 slice = gvl_slice_get_slice(id, slice_id);
1434
1435 if (!slice)
1436 return (-1);
1437
1438 if (dir == X) {
1439 cols = gvl->rows;
1440 rows = gvl->depths;
1441 depths = gvl->cols;
1442 }
1443 else if (dir == Y) {
1444 cols = gvl->cols;
1445 rows = gvl->depths;
1446 depths = gvl->rows;
1447 }
1448 else if (dir == Z) {
1449 cols = gvl->cols;
1450 rows = gvl->rows;
1451 depths = gvl->depths;
1452 }
1453 else {
1454 return (-1);
1455 }
1456
1457 slice->x1 = ((x1 < 0.) ? 0. : ((x1 > 1.) ? 1. : x1)) * (cols - 1);
1458 slice->x2 = ((x2 < 0.) ? 0. : ((x2 > 1.) ? 1. : x2)) * (cols - 1);
1459 slice->y1 = ((y1 < 0.) ? 0. : ((y1 > 1.) ? 1. : y1)) * (rows - 1);
1460 slice->y2 = ((y2 < 0.) ? 0. : ((y2 > 1.) ? 1. : y2)) * (rows - 1);
1461 slice->z1 = ((z1 < 0.) ? 0. : ((z1 > 1.) ? 1. : z1)) * (depths - 1);
1462 slice->z2 = ((z2 < 0.) ? 0. : ((z2 > 1.) ? 1. : z2)) * (depths - 1);
1463
1464 slice->dir = dir;
1465
1466 slice->changed = 1;
1467
1468 return (1);
1469 }
1470
1471 /*!
1472 \brief Get slice trans ?
1473
1474 \param id volume set id
1475 \param slice_id slice id
1476 \param[out] transp transp value
1477
1478 \return -1 on error
1479 \return 1 on success
1480 */
GVL_slice_get_transp(int id,int slice_id,int * transp)1481 int GVL_slice_get_transp(int id, int slice_id, int *transp)
1482 {
1483 geovol_slice *slice;
1484
1485 G_debug(3, "GVL_get_transp");
1486
1487 slice = gvl_slice_get_slice(id, slice_id);
1488
1489 if (!slice)
1490 return (-1);
1491
1492 *transp = slice->transp;
1493
1494 return (1);
1495 }
1496
1497 /*!
1498 \brief Set slice trans ?
1499
1500 \param id volume set id
1501 \param slice_id slice id
1502 \param transp transp value
1503
1504 \return -1 on error
1505 \return 1 on success
1506 */
GVL_slice_set_transp(int id,int slice_id,int transp)1507 int GVL_slice_set_transp(int id, int slice_id, int transp)
1508 {
1509 geovol_slice *slice;
1510
1511 G_debug(3, "GVL_set_transp");
1512
1513 slice = gvl_slice_get_slice(id, slice_id);
1514
1515 if (!slice)
1516 return (-1);
1517
1518 slice->transp = transp;
1519
1520 return (1);
1521 }
1522