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