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