GRASS 8 Programmer's Manual  8.5.0dev(2025)-26b3fb6cca
nviz.c
Go to the documentation of this file.
1 /*!
2  \file lib/nviz/nviz.c
3 
4  \brief Nviz library -- Data management
5 
6  Based on visualization/nviz/src/
7 
8  (C) 2008, 2010 by the GRASS Development Team
9  This program is free software under the GNU General Public License
10  (>=v2). Read the file COPYING that comes with GRASS for details.
11 
12  \author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC
13  2008/2010)
14  */
15 
16 #include <grass/colors.h>
17 #include <grass/raster.h>
18 #include <grass/glocale.h>
19 #include <grass/nviz.h>
20 
21 /*!
22  \brief Initialize Nviz data
23 
24  \param data nviz data
25  */
27 {
28  unsigned int i;
29 
30  /* data range */
31  data->zrange = 0;
32  data->xyrange = 0;
33 
34  /* clip planes, turn off by default */
35  data->num_cplanes = 0;
36  data->cur_cplane = 0;
37  for (i = 0; i < MAX_CPLANES; i++) {
38  Nviz_new_cplane(data, i);
39  Nviz_off_cplane(data, i);
40  }
41 
42  /* lights */
44 
45  for (i = 0; i < MAX_LIGHTS - 1; i++) {
46  Nviz_new_light(data);
47  }
48 
49  /* fringe */
50  data->num_fringes = 0;
51  data->fringe = NULL;
52 
53  /* north arrow */
54  data->draw_arrow = 0;
55  data->arrow = NULL;
56 
57  /* scale bar */
58  data->num_scalebars = 0;
59  data->scalebar = NULL;
60 
61  return;
62 }
63 
64 /*! \brief Free allocated space by nv_data struct
65 
66  \param data nviz data
67  */
69 {
70  int i;
71 
72  for (i = 0; i < data->num_fringes; i++) {
73  G_free(data->fringe[i]);
74  data->fringe[i] = NULL;
75  }
76  data->num_fringes = 0;
77  data->fringe = NULL;
78 
79  if (data->arrow) {
80  G_free(data->arrow);
81  data->arrow = NULL;
82  data->draw_arrow = 0;
83  }
84 
85  for (i = 0; i < data->num_scalebars; i++) {
86  G_free(data->scalebar[i]);
87  data->scalebar[i] = NULL;
88  }
89  data->num_scalebars = 0;
90  data->scalebar = NULL;
91 }
92 
93 /*!
94  \brief Set background color
95 
96  \param data nviz data
97  \param color color value
98  */
99 void Nviz_set_bgcolor(nv_data *data, int color)
100 {
101  data->bgcolor = color;
102 
103  return;
104 }
105 
106 /*!
107  \brief Get background color
108 
109  \param data nviz data
110 
111  \return color color value
112  */
114 {
115  return data->bgcolor;
116 }
117 
118 /*!
119  \brief Get color value from color string (name or RGB triplet)
120 
121  \param color_str color string
122 
123  \return color value
124  */
125 int Nviz_color_from_str(const char *color_str)
126 {
127  int red, grn, blu;
128 
129  if (G_str_to_color(color_str, &red, &grn, &blu) != 1) {
130  G_warning(_("Invalid color (%s), using \"white\" as default"),
131  color_str);
132  red = grn = blu = 255;
133  }
134 
135  return (red & RED_MASK) + ((int)((grn) << 8) & GRN_MASK) +
136  ((int)((blu) << 16) & BLU_MASK);
137 }
138 
139 /*! Add new fringe
140 
141  \param data nviz data
142  \param id surface id
143  \param color color
144  \param elev fringe elevation
145  \param nw,ne,sw,se 1 (turn on) 0 (turn off)
146 
147  \return pointer to allocated fringe_data structure
148  \return NULL on error
149  */
150 struct fringe_data *Nviz_new_fringe(nv_data *data, int id, unsigned long color,
151  double elev, int nw, int ne, int sw, int se)
152 {
153  int num;
154  int *surf = NULL;
155  struct fringe_data *f;
156 
157  if (!GS_surf_exists(id)) {
158  /* select first surface from the list */
159  surf = GS_get_surf_list(&num);
160  if (!surf) {
161  return NULL;
162  }
163  id = surf[0];
164  G_free(surf);
165  }
166 
167  f = (struct fringe_data *)G_malloc(sizeof(struct fringe_data));
168  f->id = id;
169  f->color = color;
170  f->elev = elev;
171  f->where[0] = nw;
172  f->where[1] = ne;
173  f->where[2] = sw;
174  f->where[3] = se;
175 
176  data->fringe = (struct fringe_data **)G_realloc(
177  data->fringe, data->num_fringes + 1 * sizeof(struct fringe_data *));
178  data->fringe[data->num_fringes++] = f;
179 
180  return f;
181 }
182 
183 /*! Set fringe
184 
185  \param data nviz data
186  \param id surface id
187  \param color color
188  \param elev fringe elevation
189  \param nw,ne,sw,se 1 (turn on) 0 (turn off)
190 
191  \return pointer to allocated fringe_data structure
192  \return NULL on error
193  */
194 struct fringe_data *Nviz_set_fringe(nv_data *data, int id, unsigned long color,
195  double elev, int nw, int ne, int sw, int se)
196 {
197  int i, num;
198  int *surf = NULL;
199  struct fringe_data *f;
200 
201  if (!GS_surf_exists(id)) {
202  /* select first surface from the list */
203  surf = GS_get_surf_list(&num);
204  if (!surf) {
205  return NULL;
206  }
207  id = surf[0];
208  G_free(surf);
209  }
210 
211  for (i = 0; i < data->num_fringes; i++) {
212  f = data->fringe[i];
213  if (f->id == id) {
214  f->color = color;
215  f->elev = elev;
216  f->where[0] = nw;
217  f->where[1] = ne;
218  f->where[2] = sw;
219  f->where[3] = se;
220 
221  return f;
222  }
223  }
224 
225  f = Nviz_new_fringe(data, id, color, elev, nw, ne, sw, se);
226 
227  return f;
228 }
229 
230 /*! Draw fringe
231 
232  \param data nviz data
233  */
235 {
236  int i;
237 
238  for (i = 0; i < data->num_fringes; i++) {
239  struct fringe_data *f = data->fringe[i];
240 
241  GS_draw_fringe(f->id, f->color, f->elev, f->where);
242  }
243 }
244 
245 /*!
246  \brief Sets the North Arrow position and return world coords
247 
248  \param data nviz data
249  \param sx,sy screen coordinates
250  \param size arrow length
251  \param color arrow/text color
252  */
253 int Nviz_set_arrow(nv_data *data, int sx, int sy, float size,
254  unsigned int color)
255 {
256  int id, pt[2];
257  int *surf_list, num_surfs;
258  float coords[3];
259  struct arrow_data *arw;
260 
261  if (GS_num_surfs() > 0) {
262  surf_list = GS_get_surf_list(&num_surfs);
263  id = surf_list[0];
264  G_free(surf_list);
265 
266  pt[0] = sx;
267  pt[1] = sy;
268 
269  GS_set_Narrow(pt, id, coords);
270 
271  if (data->arrow) {
272  data->arrow->color = color;
273  data->arrow->size = size;
274  data->arrow->where[0] = coords[0];
275  data->arrow->where[1] = coords[1];
276  data->arrow->where[2] = coords[2];
277  }
278  else {
279  arw = (struct arrow_data *)G_malloc(sizeof(struct arrow_data));
280  arw->color = color;
281  arw->size = size;
282  arw->where[0] = coords[0];
283  arw->where[1] = coords[1];
284  arw->where[2] = coords[2];
285 
286  data->arrow = arw;
287  }
288  return 1;
289  }
290  return 0;
291 }
292 
293 /*!
294  \brief Draws the North Arrow
295 
296  \param data nviz data
297  */
299 {
300 
301  struct arrow_data *arw = data->arrow;
302  GLuint FontBase = 0; /* don't know how to get fontbase */
303 
304  data->draw_arrow = 1;
305  gsd_north_arrow(arw->where, arw->size, FontBase, arw->color, arw->color);
306 
307  return 1;
308 }
309 
310 /*!
311  \brief Deletes the North Arrow
312 
313  \param data nviz data
314  */
316 {
317  data->draw_arrow = 0;
318 
319  return;
320 }
321 
322 /*! Add new scalebar
323 
324  \param data nviz data
325  \param bar_id scale bar id
326  \param coords real(?) coordinates
327  \param size scale bar length
328  \param color scalebar/text color
329 
330  \return pointer to allocated scalebar_data structure
331  \return NULL on error
332  */
333 struct scalebar_data *Nviz_new_scalebar(nv_data *data, int bar_id,
334  float *coords, float size,
335  unsigned int color)
336 {
337  struct scalebar_data *s;
338 
339  s = (struct scalebar_data *)G_malloc(sizeof(struct scalebar_data));
340  s->id = bar_id;
341  s->color = color;
342  s->size = size;
343  s->where[0] = coords[0];
344  s->where[1] = coords[1];
345  s->where[2] = coords[2];
346 
347  data->scalebar = (struct scalebar_data **)G_realloc(
348  data->scalebar,
349  (data->num_scalebars + 1) * sizeof(struct scalebar_data *));
350  data->scalebar[data->num_scalebars++] = s;
351 
352  return s;
353 }
354 
355 /*!
356  \brief Sets the scale bar position and return world coords
357 
358  \param data nviz data
359  \param bar_id scale bar id
360  \param sx,sy screen coordinates
361  \param size scale bar length
362  \param color scalebar/text color
363 
364  \return pointer to allocated scalebar_data structure
365  \return NULL when there's no surface
366  */
367 struct scalebar_data *Nviz_set_scalebar(nv_data *data, int bar_id, int sx,
368  int sy, float size, unsigned int color)
369 {
370  int i, id, pt[2];
371  int *surf_list, num_surfs;
372  float coords[3];
373  struct scalebar_data *s;
374 
375  if (GS_num_surfs() > 0) {
376  surf_list = GS_get_surf_list(&num_surfs);
377  id = surf_list[0];
378  G_free(surf_list);
379 
380  pt[0] = sx;
381  pt[1] = sy;
382 
383  GS_set_Narrow(pt, id, coords); /* the same like arrow */
384 
385  for (i = 0; i < data->num_scalebars; i++) {
386  if (data->scalebar[i]) {
387  s = data->scalebar[i];
388  if (s->id == bar_id) {
389  s->color = color;
390  s->size = size;
391  s->where[0] = coords[0];
392  s->where[1] = coords[1];
393  s->where[2] = coords[2];
394 
395  return s;
396  }
397  }
398  }
399 
400  s = Nviz_new_scalebar(data, bar_id, coords, size, color);
401 
402  return s;
403  }
404  return NULL;
405 }
406 
407 /*!
408  \brief Draws the Scale bar
409 
410  \param data nviz data
411  */
413 {
414  int i;
415 
416  GLuint FontBase = 0; /* don't know how to get fontbase */
417 
418  for (i = 0; i < data->num_scalebars; i++) {
419  if (data->scalebar[i]) {
420  struct scalebar_data *s = data->scalebar[i];
421 
422  gsd_scalebar_v2(s->where, s->size, FontBase, s->color, s->color);
423  }
424  }
425 }
426 
427 /*!
428  \brief Deletes scale bar
429 
430  When scalebar is freed, array then contains NULL,
431  which must be tested during drawing.
432 
433  \param data nviz data
434  */
435 void Nviz_delete_scalebar(nv_data *data, int bar_id)
436 {
437  if (bar_id < data->num_scalebars && data->scalebar[bar_id] != NULL) {
438  G_free(data->scalebar[bar_id]);
439  data->scalebar[bar_id] = NULL;
440  }
441 }
#define NULL
Definition: ccmath.h:32
int G_str_to_color(const char *, int *, int *, int *)
Parse color string and set red,green,blue.
Definition: color_str.c:103
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:147
#define G_realloc(p, n)
Definition: defs/gis.h:96
void G_warning(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition: defs/gis.h:94
int Nviz_off_cplane(nv_data *, int)
Turn off (make inactive) the given clip plane.
Definition: cplanes_obj.c:63
int Nviz_new_cplane(nv_data *, int)
Creates a clip plane object.
Definition: cplanes_obj.c:31
int Nviz_new_light(nv_data *)
Define new light.
Definition: lights.c:165
int GS_surf_exists(int)
Definition: gs2.c:194
int * GS_get_surf_list(int *)
Get surface list.
Definition: gs2.c:1532
void GS_set_Narrow(int *, int, float *)
Set decoration, north arrow ??
Definition: gs2.c:564
int GS_num_surfs(void)
Get number of surfaces.
Definition: gs2.c:1517
void GS_set_light_reset(int)
Definition: gs2.c:250
int gsd_north_arrow(float *, float, GLuint, unsigned long, unsigned long)
Draw North Arrow.
Definition: gsd_objs.c:851
int gsd_scalebar_v2(float *, float, GLuint, unsigned long, unsigned long)
Draw Scalebar (as lines)
Definition: gsd_objs.c:1282
void GS_draw_fringe(int, unsigned long, float, int *)
Draw fringe around data (surface) at selected corners.
Definition: gs2.c:820
#define _(str)
Definition: glocale.h:10
int Nviz_get_bgcolor(nv_data *data)
Get background color.
Definition: nviz.c:113
void Nviz_delete_arrow(nv_data *data)
Deletes the North Arrow.
Definition: nviz.c:315
struct fringe_data * Nviz_new_fringe(nv_data *data, int id, unsigned long color, double elev, int nw, int ne, int sw, int se)
Definition: nviz.c:150
void Nviz_init_data(nv_data *data)
Initialize Nviz data.
Definition: nviz.c:26
int Nviz_draw_arrow(nv_data *data)
Draws the North Arrow.
Definition: nviz.c:298
void Nviz_delete_scalebar(nv_data *data, int bar_id)
Deletes scale bar.
Definition: nviz.c:435
void Nviz_draw_scalebar(nv_data *data)
Draws the Scale bar.
Definition: nviz.c:412
struct scalebar_data * Nviz_set_scalebar(nv_data *data, int bar_id, int sx, int sy, float size, unsigned int color)
Sets the scale bar position and return world coords.
Definition: nviz.c:367
struct fringe_data * Nviz_set_fringe(nv_data *data, int id, unsigned long color, double elev, int nw, int ne, int sw, int se)
Definition: nviz.c:194
int Nviz_set_arrow(nv_data *data, int sx, int sy, float size, unsigned int color)
Sets the North Arrow position and return world coords.
Definition: nviz.c:253
void Nviz_set_bgcolor(nv_data *data, int color)
Set background color.
Definition: nviz.c:99
int Nviz_color_from_str(const char *color_str)
Get color value from color string (name or RGB triplet)
Definition: nviz.c:125
void Nviz_destroy_data(nv_data *data)
Free allocated space by nv_data struct.
Definition: nviz.c:68
void Nviz_draw_fringe(nv_data *data)
Definition: nviz.c:234
struct scalebar_data * Nviz_new_scalebar(nv_data *data, int bar_id, float *coords, float size, unsigned int color)
Definition: nviz.c:333
#define MAX_CPLANES
Definition: ogsf.h:47
#define RED_MASK
Definition: ogsf.h:200
#define BLU_MASK
Definition: ogsf.h:202
#define GRN_MASK
Definition: ogsf.h:201
#define MAX_LIGHTS
Definition: ogsf.h:46
float where[3]
Definition: nviz.h:87
unsigned long color
Definition: nviz.h:85
float size
Definition: nviz.h:86
float elev
Definition: nviz.h:80
unsigned long color
Definition: nviz.h:79
int id
Definition: nviz.h:78
int where[4]
Definition: nviz.h:81
Definition: nviz.h:97
struct scalebar_data ** scalebar
Definition: nviz.h:120
int cur_cplane
Definition: nviz.h:103
int num_cplanes
Definition: nviz.h:102
int num_fringes
Definition: nviz.h:111
float xyrange
Definition: nviz.h:99
float zrange
Definition: nviz.h:99
struct fringe_data ** fringe
Definition: nviz.h:112
struct arrow_data * arrow
Definition: nviz.h:116
int bgcolor
Definition: nviz.h:123
int draw_arrow
Definition: nviz.h:115
int num_scalebars
Definition: nviz.h:119
float where[3]
Definition: nviz.h:94
int id
Definition: nviz.h:91
unsigned long color
Definition: nviz.h:92
float size
Definition: nviz.h:93