GRASS Programmer's Manual
6.4.2(2012)
|
00001 00019 #include <stdio.h> 00020 #include <stdlib.h> 00021 00022 #include <grass/gis.h> 00023 #include <grass/gstypes.h> 00024 00025 #include "rowcol.h" 00026 00027 #define CHK_FREQ 5 00028 /* check for cancel every CHK_FREQ lines */ 00029 00043 int gs_clip_segment(geosurf * gs, float *bgn, float *end, float *region) 00044 { 00045 float top, bottom, left, right; 00046 00047 if (!region) { 00048 top = gs->yrange; 00049 bottom = VROW2Y(gs, VROWS(gs)); 00050 left = 0.0; 00051 right = VCOL2X(gs, VCOLS(gs)); 00052 } 00053 else { 00054 top = region[0]; 00055 bottom = region[1]; 00056 left = region[2]; 00057 right = region[3]; 00058 } 00059 00060 /* for now, ignore any segments with an end outside */ 00061 return (bgn[X] >= left && bgn[X] <= right && 00062 end[X] >= left && end[X] <= right && 00063 bgn[Y] >= bottom && bgn[Y] <= top && 00064 end[Y] >= bottom && end[Y] <= top); 00065 } 00066 00083 int gvd_vect(geovect * gv, geosurf * gs, int do_fast) 00084 { 00085 int i, j, k; 00086 float bgn[3], end[3], tx, ty, tz, konst; 00087 float zmin, zmax, fudge; 00088 Point3 *points; 00089 int npts, src, check; 00090 geoline *gln; 00091 00092 G_debug(5, "gvd_vect(): id=%d", gv->gvect_id); 00093 00094 if (GS_check_cancel()) { 00095 return (0); 00096 } 00097 00098 gs_update_curmask(gs); 00099 00100 src = gs_get_att_src(gs, ATT_TOPO); 00101 GS_get_scale(&tx, &ty, &tz, 1); 00102 gs_get_zrange(&zmin, &zmax); 00103 fudge = (zmax - zmin) / 500.; 00104 00105 if (src == CONST_ATT) { 00106 konst = gs->att[ATT_TOPO].constant; 00107 bgn[Z] = end[Z] = konst; 00108 } 00109 00110 gsd_pushmatrix(); 00111 00112 /* avoid scaling by zero */ 00113 if (tz == 0.0) { 00114 src = CONST_ATT; 00115 konst = 0.0; 00116 bgn[Z] = end[Z] = konst; 00117 gsd_do_scale(0); 00118 } 00119 else { 00120 gsd_do_scale(1); 00121 } 00122 00123 gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans + fudge); 00124 00125 gsd_colormode(CM_COLOR); 00126 gsd_color_func(gv->color); 00127 gsd_linewidth(gv->width); 00128 00129 check = 0; 00130 if (do_fast) { 00131 if (!gv->fastlines) { 00132 gv_decimate_lines(gv); 00133 } 00134 00135 gln = gv->fastlines; 00136 } 00137 else { 00138 gln = gv->lines; 00139 } 00140 00141 for (; gln; gln = gln->next) { 00142 G_debug(5, "gvd_vect(): type = %d dims = %d", gln->type, gln->dims); 00143 00144 if (!(++check % CHK_FREQ)) { 00145 if (GS_check_cancel()) { 00146 gsd_linewidth(1); 00147 gsd_popmatrix(); 00148 00149 return (0); 00150 } 00151 } 00152 00153 if (gln->type == OGSF_LINE) { /* line */ 00154 if (gln->dims == 2) { /* 2d line */ 00155 G_debug(5, "gvd_vect(): 2D vector line"); 00156 for (k = 0; k < gln->npts - 1; k++) { 00157 bgn[X] = gln->p2[k][X] + gv->x_trans - gs->ox; 00158 bgn[Y] = gln->p2[k][Y] + gv->y_trans - gs->oy; 00159 end[X] = gln->p2[k + 1][X] + gv->x_trans - gs->ox; 00160 end[Y] = gln->p2[k + 1][Y] + gv->y_trans - gs->oy; 00161 00162 if (src == MAP_ATT) { 00163 points = gsdrape_get_segments(gs, bgn, end, &npts); 00164 gsd_bgnline(); 00165 00166 for (i = 0, j = 0; i < npts; i++) { 00167 if (gs_point_is_masked(gs, points[i])) { 00168 if (j) { 00169 gsd_endline(); 00170 gsd_bgnline(); 00171 j = 0; 00172 } 00173 continue; 00174 } 00175 points[i][Z] += gv->z_trans; 00176 gsd_vert_func(points[i]); 00177 j++; 00178 if (j > 250) { 00179 gsd_endline(); 00180 gsd_bgnline(); 00181 gsd_vert_func(points[i]); 00182 j = 1; 00183 } 00184 } 00185 gsd_endline(); 00186 } 00187 /* need to handle MASK! */ 00188 else if (src == CONST_ATT) { 00189 /* for now - but later, do seg intersect maskedge */ 00190 if (gs_point_is_masked(gs, bgn) || 00191 gs_point_is_masked(gs, end)) 00192 continue; 00193 00194 if (gs_clip_segment(gs, bgn, end, NULL)) { 00195 gsd_bgnline(); 00196 gsd_vert_func(bgn); 00197 gsd_vert_func(end); 00198 gsd_endline(); 00199 } 00200 } 00201 } 00202 } 00203 else { /* 3D line */ 00204 00205 G_debug(5, "gvd_vect(): 3D vector line"); 00206 points = (Point3 *) malloc(sizeof(Point3)); 00207 00208 gsd_color_func(gv->color); 00209 gsd_bgnline(); 00210 for (k = 0; k < gln->npts; k++) { 00211 points[0][X] = 00212 (float)(gln->p3[k][X] + gv->x_trans - gs->ox); 00213 points[0][Y] = 00214 (float)(gln->p3[k][Y] + gv->y_trans - gs->oy); 00215 points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans); 00216 00217 gsd_vert_func(points[0]); 00218 } 00219 gsd_endline(); 00220 free(points); 00221 } 00222 } 00223 else if (gln->type == OGSF_POLYGON) { /* polygon */ 00224 if (gln->dims == 3) { /* 3D polygon */ 00225 G_debug(5, "gvd_vect(): draw 3D polygon"); 00226 00227 /* We want at least 3 points */ 00228 if (gln->npts >= 3) { 00229 points = (Point3 *) malloc(2 * sizeof(Point3)); 00230 glEnable(GL_NORMALIZE); 00231 00232 glEnable(GL_COLOR_MATERIAL); 00233 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); 00234 00235 glEnable(GL_LIGHTING); 00236 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); 00237 00238 glShadeModel(GL_FLAT); 00239 00240 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 00241 00242 glBegin(GL_POLYGON); 00243 glColor3f(1.0, 0, 0); 00244 gsd_color_func(gv->color); 00245 glNormal3fv(gln->norm); 00246 00247 for (k = 0; k < gln->npts; k++) { 00248 points[0][X] = 00249 (float)(gln->p3[k][X] + gv->x_trans - gs->ox); 00250 points[0][Y] = 00251 (float)(gln->p3[k][Y] + gv->y_trans - gs->oy); 00252 points[0][Z] = (float)(gln->p3[k][Z] + gv->z_trans); 00253 glVertex3fv(points[0]); 00254 } 00255 glEnd(); 00256 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); 00257 G_free(points); 00258 } 00259 } 00260 else { /* 2D polygons */ 00261 /* TODO */ 00262 } 00263 } 00264 } 00265 00266 gsd_linewidth(1); 00267 gsd_popmatrix(); 00268 00269 return (1); 00270 } 00271 00280 void gvd_draw_lineonsurf(geosurf * gs, float *bgn, float *end, int color) 00281 { 00282 Point3 *points; 00283 int npts, i, j; 00284 00285 gsd_color_func(color); 00286 points = gsdrape_get_segments(gs, bgn, end, &npts); 00287 gsd_bgnline(); 00288 00289 for (i = 0, j = 0; i < npts; i++) { 00290 if (gs_point_is_masked(gs, points[i])) { 00291 if (j) { 00292 gsd_endline(); 00293 gsd_bgnline(); 00294 j = 0; 00295 } 00296 00297 continue; 00298 } 00299 00300 gsd_vert_func(points[i]); 00301 j++; 00302 00303 if (j > 250) { 00304 gsd_endline(); 00305 gsd_bgnline(); 00306 gsd_vert_func(points[i]); 00307 j = 1; 00308 } 00309 } 00310 00311 gsd_endline(); 00312 00313 return; 00314 }