GRASS GIS 8 Programmer's Manual 8.2.1RC1(2022)-exported
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 */
39int 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 */
79int 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
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
121 gsd_colormode(CM_COLOR);
122
123 check = 0;
124 if (do_fast) {
125 if (!gv->fastlines) {
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);
142
143 return 0;
144 }
145 }
146
147 if (gln->highlighted > 0) {
148 gsd_color_func(gv->hstyle->color);
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);
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 */
300void 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}
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
#define NULL
Definition: ccmath.h:32
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
void GS_get_scale(float *sx, float *sy, float *sz, int doexag)
Get axis scale.
Definition: gs2.c:3240
int gs_get_zrange(float *min, float *max)
Get z-range.
Definition: gs.c:1088
int gs_point_is_masked(geosurf *gs, float *pt)
Check if point is masked.
Definition: gs.c:1317
int gs_get_att_src(geosurf *gs, int desc)
Get attribute source.
Definition: gs.c:656
int gs_update_curmask(geosurf *surf)
Update current maps.
Definition: gs_bm.c:232
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:510
void gsd_vert_func(float *pt)
ADD.
Definition: gsd_prim.c:689
void gsd_colormode(int cm)
Set color mode.
Definition: gsd_prim.c:97
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:500
void gsd_endline(void)
End line.
Definition: gsd_prim.c:406
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:396
void gsd_translate(float dx, float dy, float dz)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:538
void gsd_color_func(unsigned int col)
Set current color.
Definition: gsd_prim.c:701
void gsd_linewidth(short n)
Set width of rasterized lines.
Definition: gsd_prim.c:266
void gsd_do_scale(int doexag)
Set current scale.
Definition: gsd_views.c:355
Point3 * gsdrape_get_segments(geosurf *gs, float *bgn, float *end, int *num)
ADD.
Definition: gsdrape.c:350
int GS_check_cancel(void)
Check for cancel.
Definition: gsx.c:30
int gv_decimate_lines(geovect *gv)
Decimate line.
Definition: gv_quick.c:232
#define CHK_FREQ
Definition: gvd.c:23
void gvd_draw_lineonsurf(geosurf *gs, float *bgn, float *end, int color)
Draw line on surface.
Definition: gvd.c:300
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:39
#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
#define X(j)
#define Y(j)