GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
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 functions)
5 
6  (C) 1999-2008, 2011 by the GRASS Development Team
7 
8  This program is free software under the GNU General Public License
9  (>=v2). Read the file COPYING that comes with GRASS for details.
10 
11  \author Bill Brown USACERL (December 1993)
12  \author Doxygenized by Martin Landa (June 2008)
13  */
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 
18 #include <grass/gis.h>
19 #include <grass/ogsf.h>
20 
21 #include "rowcol.h"
22 
23 #define CHK_FREQ 5
24 /* check for cancel every CHK_FREQ lines */
25 
26 /*!
27  \brief Clip segment
28 
29  \todo to use fast clipping and move to gs.c
30 
31  \param gs surface
32  \param bgn begin point
33  \param end end point
34  \param region region settings
35 
36  \return 1 segment inside region
37  \return 0 segment outside region
38  */
39 int gs_clip_segment(geosurf * gs, float *bgn, float *end, float *region)
40 {
41  float top, bottom, left, right;
42 
43  if (!region) {
44  top = gs->yrange;
45  bottom = VROW2Y(gs, VROWS(gs));
46  left = 0.0;
47  right = VCOL2X(gs, VCOLS(gs));
48  }
49  else {
50  top = region[0];
51  bottom = region[1];
52  left = region[2];
53  right = region[3];
54  }
55 
56  /* for now, ignore any segments with an end outside */
57  return (bgn[X] >= left && bgn[X] <= right &&
58  end[X] >= left && end[X] <= right &&
59  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  {
168  bgn[X] = gln->p3[k][X] + gv->x_trans - gs->ox;
169  bgn[Y] = gln->p3[k][Y] + gv->y_trans - gs->oy;
170  end[X] = gln->p3[k + 1][X] + gv->x_trans - gs->ox;
171  end[Y] = gln->p3[k + 1][Y] + gv->y_trans - gs->oy;
172  }
173  else {
174  bgn[X] = gln->p2[k][X] + gv->x_trans - gs->ox;
175  bgn[Y] = gln->p2[k][Y] + gv->y_trans - gs->oy;
176  end[X] = gln->p2[k + 1][X] + gv->x_trans - gs->ox;
177  end[Y] = gln->p2[k + 1][Y] + gv->y_trans - gs->oy;
178  }
179 
180  if (src == MAP_ATT) {
181  points = gsdrape_get_segments(gs, bgn, end, &npts);
182  gsd_bgnline();
183 
184  for (i = 0, j = 0; i < npts; i++) {
185  if (gs_point_is_masked(gs, points[i])) {
186  if (j) {
187  gsd_endline();
188  gsd_bgnline();
189  j = 0;
190  }
191  continue;
192  }
193  points[i][Z] += gv->z_trans;
194  gsd_vert_func(points[i]);
195  j++;
196  if (j > 250) {
197  gsd_endline();
198  gsd_bgnline();
199  gsd_vert_func(points[i]);
200  j = 1;
201  }
202  }
203  gsd_endline();
204  }
205  /* need to handle MASK! */
206  else if (src == CONST_ATT) {
207  /* for now - but later, do seg intersect maskedge */
208  if (gs_point_is_masked(gs, bgn) ||
209  gs_point_is_masked(gs, end))
210  continue;
211 
212  if (gs_clip_segment(gs, bgn, end, NULL)) {
213  gsd_bgnline();
214  gsd_vert_func(bgn);
215  gsd_vert_func(end);
216  gsd_endline();
217  }
218  }
219  }
220  }
221  /* 3D line */
222  else {
223  G_debug(5, "gvd_vect(): 3D vector line");
224  points = (Point3 *) malloc(sizeof(Point3));
225 
226  gsd_bgnline();
227  for (k = 0; k < gln->npts; k++) {
228  points[0][X] =
229  (float)(gln->p3[k][X] + gv->x_trans - gs->ox);
230  points[0][Y] =
231  (float)(gln->p3[k][Y] + gv->y_trans - gs->oy);
232  points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans);
233 
234  gsd_vert_func(points[0]);
235  }
236  gsd_endline();
237  free(points);
238  }
239  }
240  /* polygon */
241  else if (gln->type == OGSF_POLYGON) {
242  /* 3D polygon */
243  if (gln->dims == 3) {
244  G_debug(5, "gvd_vect(): draw 3D polygon");
245 
246  /* We want at least 3 points */
247  if (gln->npts >= 3) {
248  points = (Point3 *) malloc(2 * sizeof(Point3));
249  glEnable(GL_NORMALIZE);
250 
251  glEnable(GL_COLOR_MATERIAL);
252  glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
253 
254  glEnable(GL_LIGHTING);
255  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
256 
257  glShadeModel(GL_FLAT);
258 
259  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
260 
261  glBegin(GL_POLYGON);
262  glColor3f(1.0, 0, 0);
263  gsd_color_func(gv->style->color);
264  glNormal3fv(gln->norm);
265 
266  for (k = 0; k < gln->npts; k++) {
267  points[0][X] =
268  (float)(gln->p3[k][X] + gv->x_trans - gs->ox);
269  points[0][Y] =
270  (float)(gln->p3[k][Y] + gv->y_trans - gs->oy);
271  points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans);
272  glVertex3fv(points[0]);
273  }
274  glEnd();
275  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
276  G_free(points);
277  }
278  }
279  else {
280  /* 2D polygons */
281  /* TODO */
282  }
283  }
284  }
285 
286  gsd_linewidth(1);
287  gsd_popmatrix();
288 
289  return 1;
290 }
291 
292 /*!
293  \brief Draw line on surface
294 
295  \param gs surface
296  \param bgn first line point
297  \param end end line point
298  \param color color value
299  */
300 void gvd_draw_lineonsurf(geosurf * gs, float *bgn, float *end, int color)
301 {
302  Point3 *points;
303  int npts, i, j;
304 
305  gsd_color_func(color);
306  points = gsdrape_get_segments(gs, bgn, end, &npts);
307  gsd_bgnline();
308 
309  for (i = 0, j = 0; i < npts; i++) {
310  if (gs_point_is_masked(gs, points[i])) {
311  if (j) {
312  gsd_endline();
313  gsd_bgnline();
314  j = 0;
315  }
316 
317  continue;
318  }
319 
320  gsd_vert_func(points[i]);
321  j++;
322 
323  if (j > 250) {
324  gsd_endline();
325  gsd_bgnline();
326  gsd_vert_func(points[i]);
327  j = 1;
328  }
329  }
330 
331  gsd_endline();
332 
333  return;
334 }
float x_trans
Definition: ogsf.h:338
void gvd_draw_lineonsurf(geosurf *gs, float *bgn, float *end, int color)
Draw line on surface.
Definition: gvd.c:300
float z_trans
Definition: ogsf.h:338
#define VCOL2X(gs, vcol)
Definition: rowcol.h:40
int use_z
Definition: ogsf.h:335
int gv_decimate_lines(geovect *)
Decimate line.
Definition: gv_quick.c:232
double ox
Definition: ogsf.h:264
int gvect_id
Definition: ogsf.h:332
int gs_get_zrange(float *, float *)
Get z-range.
Definition: gs.c:1088
signed char highlighted
Definition: ogsf.h:324
#define VROWS(gs)
Definition: rowcol.h:13
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:500
#define VCOLS(gs)
Definition: rowcol.h:14
#define ATT_TOPO
Definition: ogsf.h:73
int gs_get_att_src(geosurf *, int)
Get attribute source.
Definition: gs.c:656
gvstyle_thematic * tstyle
Definition: ogsf.h:346
int color
Definition: ogsf.h:288
gvstyle * style
Definition: ogsf.h:347
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
struct g_line * next
Definition: ogsf.h:326
float Point3[3]
Definition: ogsf.h:201
geoline * lines
Definition: ogsf.h:340
void free(void *)
#define NULL
Definition: ccmath.h:32
gvstyle * style
Definition: ogsf.h:323
int gs_clip_segment(geosurf *gs, float *bgn, float *end, float *region)
Clip segment.
Definition: gvd.c:39
#define OGSF_POLYGON
Definition: ogsf.h:194
int gvd_vect(geovect *gv, geosurf *gs, int do_fast)
Draw vector set.
Definition: gvd.c:79
void * malloc(YYSIZE_T)
#define VROW2Y(gs, vrow)
Definition: rowcol.h:39
float yrange
Definition: ogsf.h:269
void gsd_colormode(int)
Set color mode.
Definition: gsd_prim.c:97
int width
Definition: ogsf.h:291
float x_trans
Definition: ogsf.h:267
#define CM_COLOR
Definition: ogsf.h:145
void gsd_color_func(unsigned int)
Set current color.
Definition: gsd_prim.c:701
int gs_update_curmask(geosurf *)
Update current maps.
Definition: gs_bm.c:232
Definition: ogsf.h:330
void gsd_endline(void)
End line.
Definition: gsd_prim.c:406
int type
Definition: ogsf.h:316
#define MAP_ATT
Definition: ogsf.h:83
void gsd_translate(float, float, float)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:538
float norm[3]
Definition: ogsf.h:317
gvstyle * hstyle
Definition: ogsf.h:348
int npts
Definition: ogsf.h:318
#define Z
Definition: ogsf.h:139
double oy
Definition: ogsf.h:264
gsurf_att att[MAX_ATTS]
Definition: ogsf.h:261
float y_trans
Definition: ogsf.h:267
#define Y
Definition: ogsf.h:138
#define OGSF_LINE
Definition: ogsf.h:193
int gs_point_is_masked(geosurf *, float *)
Check if point is masked.
Definition: gs.c:1317
void gsd_linewidth(short)
Set width of rasterized lines.
Definition: gsd_prim.c:266
#define CHK_FREQ
Definition: gvd.c:23
int dims
Definition: ogsf.h:318
Point3 * p3
Definition: ogsf.h:319
int GS_check_cancel(void)
Check for cancel.
Definition: gsx.c:30
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:510
#define X
Definition: ogsf.h:137
float y_trans
Definition: ogsf.h:338
Point3 * gsdrape_get_segments(geosurf *, float *, float *, int *)
ADD.
Definition: gsdrape.c:350
void GS_get_scale(float *, float *, float *, int)
Get axis scale.
Definition: gs2.c:3240
geoline * fastlines
Definition: ogsf.h:341
float z_trans
Definition: ogsf.h:267
#define CONST_ATT
Definition: ogsf.h:84
void gsd_do_scale(int)
Set current scale.
Definition: gsd_views.c:355
int G_debug(int, const char *,...) __attribute__((format(printf
Definition: ogsf.h:257
float constant
Definition: ogsf.h:251
Definition: ogsf.h:314
Point2 * p2
Definition: ogsf.h:320
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:396
void gsd_vert_func(float *)
ADD.
Definition: gsd_prim.c:689