GRASS 8 Programmer's Manual  8.5.0dev(2025)-c070206eb1
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:147
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:228
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:350
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:3238
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
OGSF header file (structures)
#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(unsigned)
void free(void *)
Line instance.
Definition: ogsf.h:352
signed char highlighted
>0 Feature is highlighted.
Definition: ogsf.h:366
float norm[3]
Definition: ogsf.h:354
Point3 * p3
Definition: ogsf.h:356
struct g_line * next
Definition: ogsf.h:368
int npts
Definition: ogsf.h:355
gvstyle * style
Line instance look&feel.
Definition: ogsf.h:363
int type
Definition: ogsf.h:353
Point2 * p2
Definition: ogsf.h:357
int dims
Definition: ogsf.h:355
Definition: ogsf.h:266
float x_trans
Definition: ogsf.h:283
float yrange
Definition: ogsf.h:285
double ox
real world origin (i.e., SW corner)
Definition: ogsf.h:280
gsurf_att att[7]
mask, topo, color, etc.
Definition: ogsf.h:271
double oy
Definition: ogsf.h:280
float z_trans
Definition: ogsf.h:283
float y_trans
Definition: ogsf.h:283
int color
Line color.
Definition: ogsf.h:309
int width
Line width.
Definition: ogsf.h:325
Vector map (lines)
Definition: ogsf.h:372
geoline * fastlines
Definition: ogsf.h:386
gvstyle * hstyle
Definition: ogsf.h:396
float y_trans
Definition: ogsf.h:382
gvstyle_thematic * tstyle
thematic mapping
Definition: ogsf.h:392
gvstyle * style
Vector default look&feel.
Definition: ogsf.h:395
float z_trans
Definition: ogsf.h:382
int use_z
Definition: ogsf.h:379
float x_trans
Definition: ogsf.h:382
geoline * lines
Definition: ogsf.h:385
int gvect_id
Definition: ogsf.h:373
float constant
Definition: ogsf.h:258