1 /*!
2 \file lib/nviz/map_obj.c
3
4 \brief Nviz library -- Define creation and interface functions for map objects.
5
6 Map objects are considered to be surfaces, vector plots, or site
7 files.
8
9 Based on visualization/nviz/src/map_obj.c
10
11 (C) 2008, 2010 by the GRASS Development Team
12 This program is free software under the GNU General Public License
13 (>=v2). Read the file COPYING that comes with GRASS for details.
14
15 \author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
16 */
17
18 #include <stdlib.h>
19 #include <time.h>
20
21 #include <grass/glocale.h>
22 #include <grass/nviz.h>
23
24 /*!
25 \brief Create a new map object which can be one of surf, vect, vol or site.
26
27 This routine creates the object internally in the gsf libraryb.
28 Optionally, a logical name may be specified for the new map object.
29 If no name is specified, a logical name is assigned to the new
30 object automatically. Note that maintaining unique logical names is
31 not the responsibility of the library (currently).
32
33 Initially map objects contain no data, use the attribute commands to
34 set attributes such as topology, color, etc.
35
36 \param type map object type
37 \param name map name (NULL for constant)
38 \param value constant (used if <i>name</i> is NULL)
39 \param data nviz data
40
41 \return map object id
42 \return -1 on error
43 */
Nviz_new_map_obj(int type,const char * name,double value,nv_data * data)44 int Nviz_new_map_obj(int type, const char *name, double value, nv_data * data)
45 {
46 int new_id, i;
47 int num_surfs, *surf_list;
48
49 /*
50 * For each type of map obj do the following --
51 * 1) Verify we haven't maxed out the number of
52 * allowed objects.
53 * 2) Call the internal library to generate a new
54 * map object of the specified type.
55 */
56 /* raster -> surface */
57 if (type == MAP_OBJ_SURF) {
58 if (GS_num_surfs() >= MAX_SURFS) {
59 G_warning(_("Maximum surfaces loaded!"));
60 return -1;
61 }
62
63 new_id = GS_new_surface();
64
65 if (new_id < 0) {
66 return -1;
67 }
68
69 if (name) {
70 /* map */
71 if (!Nviz_set_attr(new_id, MAP_OBJ_SURF, ATT_TOPO,
72 MAP_ATT, name, -1.0, data)) {
73 return -1;
74 }
75 }
76 else {
77 /* constant */
78 if (!Nviz_set_attr(new_id, MAP_OBJ_SURF, ATT_TOPO,
79 CONST_ATT, NULL, value,
80 data)) {
81 return -1;
82 }
83 }
84 }
85 /* vector overlay */
86 else if (type == MAP_OBJ_VECT) {
87 if (GV_num_vects() >= MAX_VECTS) {
88 G_warning(_("Maximum vector line maps loaded!"));
89 return -1;
90 }
91
92 new_id = GV_new_vector();
93
94 if (name) {
95 if (GV_load_vector(new_id, name) < 0) {
96 GV_delete_vector(new_id);
97 G_warning(_("Error loading vector map <%s>"), name);
98 return -1;
99 }
100 }
101
102 /* initialize display parameters
103 automatically select all surfaces to draw vector */
104 GV_set_style(new_id, 1, 0x000000, 2, 0);
105 surf_list = GS_get_surf_list(&num_surfs);
106 if (num_surfs) {
107 for (i = 0; i < num_surfs; i++) {
108 GV_select_surf(new_id, surf_list[i]);
109 }
110 }
111 G_free(surf_list);
112 }
113 /* vector points overlay */
114 else if (type == MAP_OBJ_SITE) {
115 if (GP_num_sites() >= MAX_SITES) {
116 G_warning(_("Maximum vector point maps loaded!"));
117 return -1;
118 }
119
120 new_id = GP_new_site();
121
122 /* initizalize site attributes */
123 Nviz_set_vpoint_attr_default(new_id);
124
125 /* load vector points */
126 if (0 > GP_load_site(new_id, name)) {
127 GP_delete_site(new_id);
128 G_warning(_("Error loading vector map <%s>"), name);
129 return -1;
130 }
131
132 /* initialize display parameters */
133 GP_set_style(new_id, 0x000000, 2, 100, ST_X);
134 surf_list = GS_get_surf_list(&num_surfs);
135 for (i = 0; i < num_surfs; i++) {
136 GP_select_surf(new_id, surf_list[i]);
137 }
138 G_free(surf_list);
139 }
140 /* 3d raster map -> volume */
141 else if (type == MAP_OBJ_VOL) {
142 if (GVL_num_vols() >= MAX_VOLS) {
143 G_warning(_("Maximum volumes loaded!"));
144 return -1;
145 }
146
147 new_id = GVL_new_vol();
148
149 /* load volume */
150 if (0 > GVL_load_vol(new_id, name)) {
151 GVL_delete_vol(new_id);
152 G_warning(_("Error loading 3d raster map <%s>"), name);
153 return -1;
154 }
155
156 /* initilaze volume attributes */
157 Nviz_set_volume_attr_default(new_id);
158 }
159 else {
160 G_warning(_("Nviz_new_map_obj(): unsupported data type"));
161 return -1;
162 }
163
164 return new_id;
165 }
166
167 /*!
168 Set map object attribute
169
170 \param id map object id
171 \param type map object type (MAP_OBJ_SURF, MAP_OBJ_VECT, ...)
172 \param desc attribute descriptor
173 \param src attribute source
174 \param str_value attribute value as string (if NULL, check for <i>num_value</i>)
175 \param num_value attribute value as double
176
177 \return 1 on success
178 \return 0 on failure
179 */
Nviz_set_attr(int id,int type,int desc,int src,const char * str_value,double num_value,nv_data * data)180 int Nviz_set_attr(int id, int type, int desc, int src,
181 const char *str_value, double num_value, nv_data * data)
182 {
183 int ret;
184 double value;
185
186 switch (type) {
187 case (MAP_OBJ_SURF):{
188 /* Basically two cases, either we are setting to a constant field, or
189 * we are loading an actual file. Setting a constant is the easy part
190 * so we try and do that first.
191 */
192 if (src == CONST_ATT) {
193 /* Get the value for the constant
194 * Note that we require the constant to be an integer
195 */
196 if (str_value)
197 value = (double)atof(str_value);
198 else
199 value = num_value;
200
201 /* Only special case is setting constant color.
202 * In this case we have to decode the constant Tcl
203 * returns so that the gsf library understands it.
204 */
205 if (desc == ATT_COLOR) {
206 /* TODO check this - sometimes gets reversed when save state
207 saves a surface with constant color
208
209 int r, g, b;
210 r = (((int) value) & RED_MASK) >> 16;
211 g = (((int) value) & GRN_MASK) >> 8;
212 b = (((int) value) & BLU_MASK);
213 value = r + (g << 8) + (b << 16);
214 */
215 }
216
217 /* Once the value is parsed, set it */
218 ret = GS_set_att_const(id, desc, value);
219 }
220 else if (src == MAP_ATT) {
221 ret = GS_load_att_map(id, str_value, desc);
222 }
223 else
224 ret = -1;
225
226 /* After we've loaded a constant map or a file,
227 * may need to adjust resolution if we are resetting
228 * topology (for example)
229 */
230 if (0 <= ret) {
231 if (desc == ATT_TOPO) {
232 int rows, cols, max;
233 int max2;
234
235 /* If topology attribute is being set then need to set
236 * resolution of incoming map to some sensible value so we
237 * don't wait all day for drawing.
238 */
239 GS_get_dims(id, &rows, &cols);
240 max = (rows > cols) ? rows : cols;
241 max = max / 50;
242 if (max < 1)
243 max = 1;
244 max2 = max / 5;
245 if (max2 < 1)
246 max2 = 1;
247 /* reset max to finer for coarse surf drawing */
248 max = max2 + max2 / 2;
249 if (max < 1)
250 max = 1;
251
252 GS_set_drawres(id, max2, max2, max, max);
253 GS_set_drawmode(id, DM_GOURAUD | DM_POLY | DM_GRID_SURF);
254 }
255
256 /* Not sure about this next line, should probably just
257 * create separate routines to figure the Z range as well
258 * as the XYrange
259 */
260 Nviz_update_ranges(data);
261
262 break;
263 }
264 default:{
265 return 0;
266 }
267 }
268 }
269
270 return 1;
271 }
272
273 /*!
274 \brief Set default surface attributes
275 */
Nviz_set_surface_attr_default()276 void Nviz_set_surface_attr_default()
277 {
278 float defs[MAX_ATTS];
279
280 defs[ATT_TOPO] = 0;
281 defs[ATT_COLOR] = DEFAULT_SURF_COLOR;
282 defs[ATT_MASK] = 0;
283 defs[ATT_TRANSP] = 0;
284 defs[ATT_SHINE] = 60;
285 defs[ATT_EMIT] = 0;
286
287 GS_set_att_defaults(defs, defs);
288
289 return;
290 }
291
292 /*!
293 \brief Set default vector point attributes
294
295 \param id vector point set id
296
297 \return 1 on success
298 \return 0 on failure
299 */
Nviz_set_vpoint_attr_default(int id)300 int Nviz_set_vpoint_attr_default(int id)
301 {
302 geosite *gp;
303
304 gp = gp_get_site(id);
305
306 if (!gp)
307 return 0;
308
309 return 1;
310 }
311
312 /*!
313 \brief Set default volume attributes
314
315 \param id volume set id
316
317 \return 1 on success
318 \return 0 on failure
319 */
Nviz_set_volume_attr_default(int id)320 int Nviz_set_volume_attr_default(int id)
321 {
322 int rows, cols, depths;
323 int max;
324
325 GVL_get_dims(id, &rows, &cols, &depths);
326 max = (rows > cols) ? rows : cols;
327 max = (depths > max) ? depths : max;
328 max = max / 35;
329 if (max < 1)
330 max = 1;
331
332 if (max > cols)
333 max = cols / 2;
334 if (max > rows)
335 max = rows / 2;
336 if (max > depths)
337 max = depths / 2;
338
339 /* set default drawres and drawmode for isosurfaces */
340 GVL_isosurf_set_drawres(id, max, max, max);
341 GVL_isosurf_set_drawmode(id, DM_GOURAUD);
342
343 /* set default drawres and drawmode for slices */
344 GVL_slice_set_drawres(id, 1, 1, 1);
345 GVL_slice_set_drawmode(id, DM_GOURAUD | DM_POLY);
346
347 return 1;
348 }
349
350 /*!
351 Unset map object attribute
352
353 \param id map object id
354 \param type map object type (MAP_OBJ_SURF, MAP_OBJ_VECT, ...)
355 \param desc attribute descriptor
356
357 \return 1 on success
358 \return 0 on failure
359 */
Nviz_unset_attr(int id,int type,int desc)360 int Nviz_unset_attr(int id, int type, int desc)
361 {
362 if (type == MAP_OBJ_SURF) {
363 return GS_unset_att(id, desc);
364 }
365
366 return 0;
367 }
368