GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-835afb4352
gvd.c
Go to the documentation of this file.
1 /*!
2  \file lib/ogsf/gvd.c
3 
4  \brief OGSF library - loading and manipulating vector sets (lower level
5  functions)
6 
7  (C) 1999-2008, 2011 by the GRASS Development Team
8 
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 Bill Brown USACERL (December 1993)
13  \author Doxygenized by Martin Landa (June 2008)
14  */
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 
19 #include <grass/gis.h>
20 #include <grass/ogsf.h>
21 
22 #include "rowcol.h"
23 
24 #define CHK_FREQ 5
25 /* check for cancel every CHK_FREQ lines */
26 
27 /*!
28  \brief Clip segment
29 
30  \todo to use fast clipping and move to gs.c
31 
32  \param gs surface
33  \param bgn begin point
34  \param end end point
35  \param region region settings
36 
37  \return 1 segment inside region
38  \return 0 segment outside region
39  */
40 int gs_clip_segment(geosurf *gs, float *bgn, float *end, float *region)
41 {
42  float top, bottom, left, right;
43 
44  if (!region) {
45  top = gs->yrange;
46  bottom = VROW2Y(gs, VROWS(gs));
47  left = 0.0;
48  right = VCOL2X(gs, VCOLS(gs));
49  }
50  else {
51  top = region[0];
52  bottom = region[1];
53  left = region[2];
54  right = region[3];
55  }
56 
57  /* for now, ignore any segments with an end outside */
58  return (bgn[X] >= left && bgn[X] <= right && end[X] >= left &&
59  end[X] <= right && bgn[Y] >= bottom && bgn[Y] <= top &&
60  end[Y] >= bottom && end[Y] <= top);
61 }
62 
63 /*!
64  \brief Draw vector set
65 
66  Need to think about translations - If user translates surface,
67  vector should automatically go with it, but translating vector should
68  translate it relative to surface on which it's displayed?
69 
70  Handling mask checking here, but may be more appropriate to
71  handle in get_drape_segments?
72 
73  \param gv vector set
74  \param gs surface
75  \param do_fast non-zero for fast mode
76 
77  \return
78  */
79 int gvd_vect(geovect *gv, geosurf *gs, int do_fast)
80 {
81  int i, j, k;
82  float bgn[3], end[3], tx, ty, tz, konst;
83  float zmin, zmax, fudge;
84  Point3 *points;
85  int npts, src, check;
86  geoline *gln;
87 
88  G_debug(5, "gvd_vect(): id=%d", gv->gvect_id);
89 
90  if (GS_check_cancel()) {
91  return 0;
92  }
93 
95 
96  src = gs_get_att_src(gs, ATT_TOPO);
97  GS_get_scale(&tx, &ty, &tz, 1);
98  gs_get_zrange(&zmin, &zmax);
99  fudge = (zmax - zmin) / 500.;
100 
101  if (src == CONST_ATT) {
102  konst = gs->att[ATT_TOPO].constant;
103  bgn[Z] = end[Z] = konst + gv->z_trans;
104  }
105 
106  gsd_pushmatrix();
107 
108  /* avoid scaling by zero */
109  if (tz == 0.0) {
110  src = CONST_ATT;
111  konst = 0.0;
112  bgn[Z] = end[Z] = konst;
113  gsd_do_scale(0);
114  }
115  else {
116  gsd_do_scale(1);
117  }
118 
119  gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans + fudge);
120 
122 
123  check = 0;
124  if (do_fast) {
125  if (!gv->fastlines) {
126  gv_decimate_lines(gv);
127  }
128 
129  gln = gv->fastlines;
130  }
131  else {
132  gln = gv->lines;
133  }
134 
135  for (; gln; gln = gln->next) {
136  G_debug(5, "gvd_vect(): type = %d dims = %d", gln->type, gln->dims);
137 
138  if (!(++check % CHK_FREQ)) {
139  if (GS_check_cancel()) {
140  gsd_linewidth(1);
141  gsd_popmatrix();
142 
143  return 0;
144  }
145  }
146 
147  if (gln->highlighted > 0) {
149  gsd_linewidth(gv->hstyle->width);
150  }
151  else if (gv->tstyle && gv->tstyle->active) {
152  gsd_color_func(gln->style->color);
153  gsd_linewidth(gln->style->width);
154  }
155  else {
156  gsd_color_func(gv->style->color);
157  gsd_linewidth(gv->style->width);
158  }
159 
160  /* line */
161  if (gln->type == OGSF_LINE) {
162  /* 2D line */
163  if (gln->dims == 2 || !gv->use_z) {
164  G_debug(5, "gvd_vect(): 2D vector line");
165  for (k = 0; k < gln->npts - 1; k++) {
166  if (gln->dims == 3) {
167  bgn[X] = gln->p3[k][X] + gv->x_trans - gs->ox;
168  bgn[Y] = gln->p3[k][Y] + gv->y_trans - gs->oy;
169  end[X] = gln->p3[k + 1][X] + gv->x_trans - gs->ox;
170  end[Y] = gln->p3[k + 1][Y] + gv->y_trans - gs->oy;
171  }
172  else {
173  bgn[X] = gln->p2[k][X] + gv->x_trans - gs->ox;
174  bgn[Y] = gln->p2[k][Y] + gv->y_trans - gs->oy;
175  end[X] = gln->p2[k + 1][X] + gv->x_trans - gs->ox;
176  end[Y] = gln->p2[k + 1][Y] + gv->y_trans - gs->oy;
177  }
178 
179  if (src == MAP_ATT) {
180  points = gsdrape_get_segments(gs, bgn, end, &npts);
181  gsd_bgnline();
182 
183  for (i = 0, j = 0; i < npts; i++) {
184  if (gs_point_is_masked(gs, points[i])) {
185  if (j) {
186  gsd_endline();
187  gsd_bgnline();
188  j = 0;
189  }
190  continue;
191  }
192  points[i][Z] += gv->z_trans;
193  gsd_vert_func(points[i]);
194  j++;
195  if (j > 250) {
196  gsd_endline();
197  gsd_bgnline();
198  gsd_vert_func(points[i]);
199  j = 1;
200  }
201  }
202  gsd_endline();
203  }
204  /* need to handle MASK! */
205  else if (src == CONST_ATT) {
206  /* for now - but later, do seg intersect maskedge */
207  if (gs_point_is_masked(gs, bgn) ||
208  gs_point_is_masked(gs, end))
209  continue;
210 
211  if (gs_clip_segment(gs, bgn, end, NULL)) {
212  gsd_bgnline();
213  gsd_vert_func(bgn);
214  gsd_vert_func(end);
215  gsd_endline();
216  }
217  }
218  }
219  }
220  /* 3D line */
221  else {
222  G_debug(5, "gvd_vect(): 3D vector line");
223  points = (Point3 *)malloc(sizeof(Point3));
224 
225  gsd_bgnline();
226  for (k = 0; k < gln->npts; k++) {
227  points[0][X] =
228  (float)(gln->p3[k][X] + gv->x_trans - gs->ox);
229  points[0][Y] =
230  (float)(gln->p3[k][Y] + gv->y_trans - gs->oy);
231  points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans);
232 
233  gsd_vert_func(points[0]);
234  }
235  gsd_endline();
236  free(points);
237  }
238  }
239  /* polygon */
240  else if (gln->type == OGSF_POLYGON) {
241  /* 3D polygon */
242  if (gln->dims == 3) {
243  G_debug(5, "gvd_vect(): draw 3D polygon");
244 
245  /* We want at least 3 points */
246  if (gln->npts >= 3) {
247  points = (Point3 *)malloc(2 * sizeof(Point3));
248  glEnable(GL_NORMALIZE);
249 
250  glEnable(GL_COLOR_MATERIAL);
251  glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
252 
253  glEnable(GL_LIGHTING);
254  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
255 
256  glShadeModel(GL_FLAT);
257 
258  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
259 
260  glBegin(GL_POLYGON);
261  glColor3f(1.0, 0, 0);
262  gsd_color_func(gv->style->color);
263  glNormal3fv(gln->norm);
264 
265  for (k = 0; k < gln->npts; k++) {
266  points[0][X] =
267  (float)(gln->p3[k][X] + gv->x_trans - gs->ox);
268  points[0][Y] =
269  (float)(gln->p3[k][Y] + gv->y_trans - gs->oy);
270  points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans);
271  glVertex3fv(points[0]);
272  }
273  glEnd();
274  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
275  G_free(points);
276  }
277  }
278  else {
279  /* 2D polygons */
280  /* TODO */
281  }
282  }
283  }
284 
285  gsd_linewidth(1);
286  gsd_popmatrix();
287 
288  return 1;
289 }
290 
291 /*!
292  \brief Draw line on surface
293 
294  \param gs surface
295  \param bgn first line point
296  \param end end line point
297  \param color color value
298  */
299 void gvd_draw_lineonsurf(geosurf *gs, float *bgn, float *end, int color)
300 {
301  Point3 *points;
302  int npts, i, j;
303 
304  gsd_color_func(color);
305  points = gsdrape_get_segments(gs, bgn, end, &npts);
306  gsd_bgnline();
307 
308  for (i = 0, j = 0; i < npts; i++) {
309  if (gs_point_is_masked(gs, points[i])) {
310  if (j) {
311  gsd_endline();
312  gsd_bgnline();
313  j = 0;
314  }
315 
316  continue;
317  }
318 
319  gsd_vert_func(points[i]);
320  j++;
321 
322  if (j > 250) {
323  gsd_endline();
324  gsd_bgnline();
325  gsd_vert_func(points[i]);
326  j = 1;
327  }
328  }
329 
330  gsd_endline();
331 
332  return;
333 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
int G_debug(int, const char *,...) __attribute__((format(printf
int gs_point_is_masked(geosurf *, float *)
Check if point is masked.
Definition: gs.c:1314
int gv_decimate_lines(geovect *)
Decimate line.
Definition: gv_quick.c:231
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:511
void gsd_do_scale(int)
Set current scale.
Definition: gsd_views.c:355
int gs_get_zrange(float *, float *)
Get z-range.
Definition: gs.c:1086
int gs_get_att_src(geosurf *, int)
Get attribute source.
Definition: gs.c:656
int gs_update_curmask(geosurf *)
Update current maps.
Definition: gs_bm.c:231
void gsd_color_func(unsigned int)
Set current color.
Definition: gsd_prim.c:698
Point3 * gsdrape_get_segments(geosurf *, float *, float *, int *)
ADD.
Definition: gsdrape.c:349
void gsd_translate(float, float, float)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:539
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:501
void gsd_linewidth(short)
Set width of rasterized lines.
Definition: gsd_prim.c:267
void gsd_endline(void)
End line.
Definition: gsd_prim.c:407
void gsd_colormode(int)
Set color mode.
Definition: gsd_prim.c:98
void GS_get_scale(float *, float *, float *, int)
Get axis scale.
Definition: gs2.c:3236
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:397
void gsd_vert_func(float *)
ADD.
Definition: gsd_prim.c:686
int GS_check_cancel(void)
Check for cancel.
Definition: gsx.c:30
#define CHK_FREQ
Definition: gvd.c:24
void gvd_draw_lineonsurf(geosurf *gs, float *bgn, float *end, int color)
Draw line on surface.
Definition: gvd.c:299
int gvd_vect(geovect *gv, geosurf *gs, int do_fast)
Draw vector set.
Definition: gvd.c:79
int gs_clip_segment(geosurf *gs, float *bgn, float *end, float *region)
Clip segment.
Definition: gvd.c:40
#define X
Definition: ogsf.h:140
#define ATT_TOPO
Definition: ogsf.h:75
float Point3[3]
Definition: ogsf.h:205
#define Z
Definition: ogsf.h:142
#define Y
Definition: ogsf.h:141
#define MAP_ATT
Definition: ogsf.h:85
#define CM_COLOR
Definition: ogsf.h:148
#define OGSF_LINE
Definition: ogsf.h:197
#define CONST_ATT
Definition: ogsf.h:86
#define OGSF_POLYGON
Definition: ogsf.h:198
#define VCOL2X(gs, vcol)
Definition: rowcol.h:40
#define VCOLS(gs)
Definition: rowcol.h:14
#define VROWS(gs)
Definition: rowcol.h:13
#define VROW2Y(gs, vrow)
Definition: rowcol.h:39
void * malloc(YYSIZE_T)
void free(void *)
Definition: ogsf.h:312
signed char highlighted
Definition: ogsf.h:322
float norm[3]
Definition: ogsf.h:314
Point3 * p3
Definition: ogsf.h:316
struct g_line * next
Definition: ogsf.h:324
int npts
Definition: ogsf.h:315
gvstyle * style
Definition: ogsf.h:321
int type
Definition: ogsf.h:313
Point2 * p2
Definition: ogsf.h:317
int dims
Definition: ogsf.h:315
Definition: ogsf.h:256
float x_trans
Definition: ogsf.h:266
float yrange
Definition: ogsf.h:268
double ox
Definition: ogsf.h:263
gsurf_att att[MAX_ATTS]
Definition: ogsf.h:259
double oy
Definition: ogsf.h:263
float z_trans
Definition: ogsf.h:266
float y_trans
Definition: ogsf.h:266
int color
Definition: ogsf.h:286
int width
Definition: ogsf.h:289
Definition: ogsf.h:328
geoline * fastlines
Definition: ogsf.h:338
gvstyle * hstyle
Definition: ogsf.h:345
float y_trans
Definition: ogsf.h:335
gvstyle_thematic * tstyle
Definition: ogsf.h:343
gvstyle * style
Definition: ogsf.h:344
float z_trans
Definition: ogsf.h:335
int use_z
Definition: ogsf.h:332
float x_trans
Definition: ogsf.h:335
geoline * lines
Definition: ogsf.h:337
int gvect_id
Definition: ogsf.h:329
float constant
Definition: ogsf.h:250