GRASS GIS 8 Programmer's Manual 8.2.1RC1(2022)-exported
gsd_surf.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gsd_surf.c
3
4 \brief OGSF library - loading and manipulating surfaces
5
6 GRASS OpenGL gsurf OGSF Library
7
8 (C) 1999-2008 by the GRASS Development Team
9
10 This program is free software under the
11 GNU General Public License (>=v2).
12 Read the file COPYING that comes with GRASS
13 for details.
14
15 \author Bill Brown USACERL (October 1993)
16 \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
17 */
18
19#include <stdlib.h>
20
21#include <grass/gis.h>
22#include <grass/glocale.h>
23#include <grass/ogsf.h>
24
25#include "gsget.h"
26#include "rowcol.h"
27
28/*
29 #define CALC_AREA
30 */
31
32/*
33 #define DO_ARROW_SOLID
34 #define DEBUG_ARROW ((row && !(row%surf->y_modw))&&(col && !(col%surf->x_modw)))
35 */
36
37/*
38 #define DO_ARROW
39 */
40
41#define DEBUG_ARROW (0)
42
43/*!
44 \brief MACROS for use in gsd_ortho_wall ONLY !!!
45 */
46#define SET_SCOLOR(sf) \
47 if(check_color[sf]) \
48 { \
49 tx = points[sf][i][X] - gsurfs[sf]->x_trans; \
50 ty = points[sf][i][Y] - gsurfs[sf]->y_trans; \
51 offset = XY2OFF(gsurfs[sf], tx, ty); \
52 colors[sf] = gs_mapcolor(cobuf[sf], coloratt[sf], offset); \
53 }
54
55static int transpoint_is_masked(geosurf *, Point3);
56static int get_point_below(Point3 **, geosurf **, int, int, int, int *);
57
58static int FCmode;
59
60
61/************************************************************************/
62/* Notes on exageration:
63 vertical exageration is of two forms:
64 1) global exageration (from geoview struct)
65 2) vertical exageration for each surface (UN-IMPLEMENTED)
66 */
67
68/************************************************************************/
69/* may need to add more parameters to tell it which window or off_screen
70 * pixmap to draw into.
71 */
72
73/*!
74 \brief ADD
75
76 \param surf surface (geosurf)
77
78 \return
79 \return -1 on error
80 */
81int gsd_surf(geosurf * surf)
82{
83 int desc, ret;
84
85 G_debug(5, "gsd_surf(): id=%d", surf->gsurf_id);
86
87 desc = ATT_TOPO;
88
89 /* won't recalculate if update not needed, but may want to check
90 to see if lights are on */
91 gs_calc_normals(surf);
92
93 switch (gs_get_att_src(surf, desc)) {
94 case NOTSET_ATT:
95 ret = (-1);
96
97 break;
98
99 case MAP_ATT:
100 ret = (gsd_surf_map(surf)); /* changed to use test draw routine */
101
102#ifdef DO_ARROW
103 gsd_norm_arrows(surf);
104
105 /* Not ready yet - need to recalc normals for proper res
106 gsd_wire_arrows(surf);
107 */
108#endif
109
110 break;
111
112 case CONST_ATT:
113 ret = (gsd_surf_const(surf, surf->att[desc].constant));
114
115 break;
116
117 case FUNC_ATT:
118 ret = (gsd_surf_func(surf, surf->att[desc].user_func));
119
120 break;
121
122 default:
123 ret = (-1);
124
125 break;
126 }
127
128 return (ret);
129}
130
131/*!
132 \brief ADD
133
134 Using tmesh - not confident with qstrips portability
135
136 \param surf surface (geosurf)
137
138 \return
139 */
140int gsd_surf_map_old(geosurf * surf)
141{
142 int check_mask, check_color, check_transp;
143 int check_material, check_emis, check_shin;
144 typbuff *buff, *cobuff, *trbuff, *embuff, *shbuff;
145 int xmod, ymod, row, col, cnt, xcnt, ycnt;
146 long offset, y1off, y2off;
147 float x1, x2, y1, y2, tx, ty, tz, ttr;
148 float n[3], pt[4], xres, yres, ymax, zexag;
149 int em_src, sh_src, trans_src, col_src, curcolor;
150 gsurf_att *ematt, *shatt, *tratt, *coloratt;
151
152
153 /* Viewport variables for accelerated drawing */
154 GLdouble modelMatrix[16], projMatrix[16];
155 GLint viewport[4];
156 GLint window[4];
157
158#ifdef CALC_AREA
159 float sz, mag, tedge1[3], tedge2[3], crossp[3], triv[3][3];
160 double asurf = 0.0, axsurf = 0.0;
161#endif
162
163 int zeros, dr1, dr2, dr3, dr4;
164 int datarow1, datacol1, datarow2, datacol2;
165
166 float kem, ksh, pkem, pksh;
167 unsigned int ktrans;
168
169 G_debug(3, "gsd_surf_map_old");
170
171 /* avoid scaling by zero */
172 GS_get_scale(&tx, &ty, &tz, 1);
173
174 if (tz == 0.0) {
175 return (gsd_surf_const(surf, 0.0));
176 }
177 /* else if (surf->z_exag == 0.0)
178 {
179 return(gsd_surf_const(surf, surf->z_min));
180 }
181 NOT YET IMPLEMENTED */
182
183 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
184 cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
185
186 gs_update_curmask(surf);
187 check_mask = surf->curmask ? 1 : 0;
188
189 /*
190 checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
191 combine it/them with any current mask, put in surf->curmask:
192 */
193 xmod = surf->x_mod;
194 ymod = surf->y_mod;
195 xres = xmod * surf->xres;
196 yres = ymod * surf->yres;
197 ymax = (surf->rows - 1) * surf->yres;
198
199 xcnt = VCOLS(surf);
200 ycnt = VROWS(surf);
201
202 /* Get viewport */
203 gsd_getwindow(window, viewport, modelMatrix, projMatrix);
204 /* adjust window */
205 window[0] += (int)(yres * 2);
206 window[1] -= (int)(yres * 2);
207 window[2] -= (int)(xres * 2);
208 window[3] += (int)(xres * 2);
209
210 gsd_colormode(CM_DIFFUSE);
212 gsd_do_scale(1);
213 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
214 zexag = surf->z_exag;
215
216 /* CURRENTLY ALWAYS 1.0 */
217#ifdef CALC_AREA
218 sz = GS_global_exag();
219#endif
220
221 /* TESTING */
222 /*
223 fprintf(stderr, "This machine has %d alpha bits\n", getgdesc(GD_BITS_NORM_DBL_ALPHA));
224 fprintf(stderr, "GD_BLEND = %d \n", getgdesc(GD_BLEND));
225 fprintf(stderr, "GD_CLIPPLANES = %d \n", getgdesc(GD_CLIPPLANES));
226 */
227
228 /* TODO: get rid of (define) these magic numbers scaling the attribute vals */
229 check_transp = 0;
230 tratt = &(surf->att[ATT_TRANSP]);
231 ktrans = (255 << 24);
232 trans_src = surf->att[ATT_TRANSP].att_src;
233
234 if (CONST_ATT == trans_src && surf->att[ATT_TRANSP].constant != 0.0) {
235 ktrans = (255 - (int)surf->att[ATT_TRANSP].constant) << 24;
236 gsd_blend(1);
237 gsd_zwritemask(0x0);
238 }
239 else if (MAP_ATT == trans_src) {
240 trbuff = gs_get_att_typbuff(surf, ATT_TRANSP, 0);
241 check_transp = trbuff ? 1 : 0;
242 gsd_blend(1);
243 gsd_zwritemask(0x0);
244 }
245
246 check_emis = 0;
247 ematt = &(surf->att[ATT_EMIT]);
248 kem = 0.0;
249 pkem = 1.0;
250 em_src = surf->att[ATT_EMIT].att_src;
251
252 if (CONST_ATT == em_src) {
253 kem = surf->att[ATT_EMIT].constant / 255.;
254 }
255 else if (MAP_ATT == em_src) {
256 embuff = gs_get_att_typbuff(surf, ATT_EMIT, 0);
257 check_emis = embuff ? 1 : 0;
258 }
259
260 check_shin = 0;
261 shatt = &(surf->att[ATT_SHINE]);
262 ksh = 0.0;
263 pksh = 1.0;
264 sh_src = surf->att[ATT_SHINE].att_src;
265
266 if (CONST_ATT == sh_src) {
267 ksh = surf->att[ATT_SHINE].constant / 255.;
268 gsd_set_material(1, 0, ksh, kem, 0x0);
269 }
270 else if (MAP_ATT == sh_src) {
271 shbuff = gs_get_att_typbuff(surf, ATT_SHINE, 0);
272 check_shin = shbuff ? 1 : 0;
273 }
274
275 /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
276 or else use more general and inefficient gets */
277 check_color = 1;
278 coloratt = &(surf->att[ATT_COLOR]);
279 col_src = surf->att[ATT_COLOR].att_src;
280
281 if (col_src != MAP_ATT) {
282 if (col_src == CONST_ATT) {
283 curcolor = (int)surf->att[ATT_COLOR].constant;
284 }
285 else {
286 curcolor = surf->wire_color;
287 }
288
289 check_color = 0;
290 }
291
292 check_material = (check_shin || check_emis || (kem && check_color));
293
294 /* would also be good to check if colormap == surfmap, to increase speed */
295 /* will also need to set check_transp, check_shine, etc & fix material */
296 cnt = 0;
297
298 for (row = 0; row < ycnt; row++) {
299 if (GS_check_cancel()) {
301 gsd_blend(0);
302 gsd_zwritemask(0xffffffff);
303
304 return (-1);
305 }
306
307 datarow1 = row * ymod;
308 datarow2 = (row + 1) * ymod;
309
310 y1 = ymax - row * yres;
311 y2 = ymax - (row + 1) * yres;
312 y1off = row * ymod * surf->cols;
313 y2off = (row + 1) * ymod * surf->cols;
314
315 gsd_bgntmesh();
316
317 zeros = 0;
318 dr1 = dr2 = dr3 = dr4 = 1;
319
320 if (check_mask) {
321 if (BM_get(surf->curmask, 0, datarow1)) {
322 /*TL*/ ++zeros;
323 dr1 = 0;
324 }
325
326 if (BM_get(surf->curmask, 0, datarow2)) {
327 /*BL*/ ++zeros;
328 dr2 = 0;
329 }
330 }
331
332 if (dr1 && dr2) {
333 offset = y1off; /* TL */
334 FNORM(surf->norms[offset], n);
335 pt[X] = 0;
336 pt[Y] = y1;
337 GET_MAPATT(buff, offset, pt[Z]);
338 pt[Z] *= zexag;
339
340 if (check_color) {
341 curcolor = gs_mapcolor(cobuff, coloratt, offset);
342 }
343
344 if (check_transp) {
345 GET_MAPATT(trbuff, offset, ttr);
346 ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
347 ktrans = (char)(255 - ktrans) << 24;
348 }
349
350 gsd_litvert_func(n, ktrans | curcolor, pt);
351
352#ifdef CALC_AREA
353 GS_v3eq(triv[cnt % 3], pt);
354#endif
355
356 cnt++;
357
358 offset = y2off; /* BL */
359 FNORM(surf->norms[offset], n);
360 pt[X] = 0;
361 pt[Y] = y2;
362 GET_MAPATT(buff, offset, pt[Z]);
363 pt[Z] *= zexag;
364
365 if (check_color) {
366 curcolor = gs_mapcolor(cobuff, coloratt, offset);
367 }
368
369 if (check_transp) {
370 GET_MAPATT(trbuff, offset, ttr);
371 ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
372 ktrans = (char)(255 - ktrans) << 24;
373 }
374
375 if (check_material) {
376 if (check_emis) {
377 GET_MAPATT(embuff, offset, kem);
378 kem = SCALE_ATT(ematt, kem, 0., 1.);
379 }
380
381 if (check_shin) {
382 GET_MAPATT(shbuff, offset, ksh);
383 ksh = SCALE_ATT(shatt, ksh, 0., 1.);
384 }
385
386 if (pksh != ksh || pkem != kem || (kem && check_color)) {
387 /* expensive */
388 pksh = ksh;
389 pkem = kem;
390 gsd_set_material(check_shin, check_emis, ksh, kem,
391 curcolor);
392 }
393 }
394
395 gsd_litvert_func(n, ktrans | curcolor, pt);
396
397#ifdef CALC_AREA
398 GS_v3eq(triv[cnt % 3], pt);
399#endif
400
401 cnt++;
402 }
403
404 for (col = 0; col < xcnt; col++) {
405 datacol1 = col * xmod;
406 datacol2 = (col + 1) * xmod;
407
408 x1 = col * xres;
409 x2 = (col + 1) * xres;
410
411 zeros = 0;
412 dr1 = dr2 = dr3 = dr4 = 1;
413
414 if (check_mask) {
415 if (BM_get(surf->curmask, datacol1, datarow1)) {
416 /*TL*/ ++zeros;
417 dr1 = 0;
418 }
419
420 if (BM_get(surf->curmask, datacol1, datarow2)) {
421 /*BL*/ ++zeros;
422 dr2 = 0;
423 }
424
425 if (BM_get(surf->curmask, datacol2, datarow2)) {
426 /*BR*/ ++zeros;
427 dr3 = 0;
428 }
429
430 if (BM_get(surf->curmask, datacol2, datarow1)) {
431 /*TR*/ ++zeros;
432 dr4 = 0;
433 }
434
435 if ((zeros > 1) && cnt) {
436 gsd_endtmesh();
437 cnt = 0;
438 gsd_bgntmesh();
439 continue;
440 }
441 }
442
443 if (cnt > 252) {
444 /* not needed! - no limit for tmesh */
445 cnt = 0;
446 gsd_endtmesh();
447 gsd_bgntmesh();
448
449 if (dr1) {
450 offset = y1off + datacol1; /* TL */
451 FNORM(surf->norms[offset], n);
452 pt[X] = x1;
453 pt[Y] = y1;
454 GET_MAPATT(buff, offset, pt[Z]);
455 pt[Z] *= zexag;
456
458 (pt, window, viewport, modelMatrix, projMatrix)) {
459 gsd_endtmesh();
460 cnt = 0;
461 gsd_bgntmesh();
462 continue;
463 }
464
465 if (check_color) {
466 curcolor = gs_mapcolor(cobuff, coloratt, offset);
467 }
468
469 if (check_transp) {
470 GET_MAPATT(trbuff, offset, ttr);
471 ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
472 ktrans = (char)(255 - ktrans) << 24;
473 }
474
475 if (check_material) {
476 if (check_emis) {
477 GET_MAPATT(embuff, offset, kem);
478 kem = SCALE_ATT(ematt, kem, 0., 1.);
479 }
480
481 if (check_shin) {
482 GET_MAPATT(shbuff, offset, ksh);
483 ksh = SCALE_ATT(shatt, ksh, 0., 1.);
484 }
485
486 if (pksh != ksh || pkem != kem
487 || (kem && check_color)) {
488 pksh = ksh;
489 pkem = kem;
490 gsd_set_material(check_shin, check_emis,
491 ksh, kem, curcolor);
492 }
493 }
494
495 gsd_litvert_func(n, ktrans | curcolor, pt);
496
497#ifdef CALC_AREA
498 GS_v3eq(triv[cnt % 3], pt);
499#endif
500
501 cnt++;
502 }
503
504 if (dr2) {
505 offset = y2off + datacol1; /* BL */
506 FNORM(surf->norms[offset], n);
507 pt[X] = x1;
508 pt[Y] = y2;
509 GET_MAPATT(buff, offset, pt[Z]);
510 pt[Z] *= zexag;
511
513 (pt, window, viewport, modelMatrix, projMatrix)) {
514 gsd_endtmesh();
515 cnt = 0;
516 gsd_bgntmesh();
517 continue;
518 }
519
520 if (check_color) {
521 curcolor = gs_mapcolor(cobuff, coloratt, offset);
522 }
523
524 if (check_transp) {
525 GET_MAPATT(trbuff, offset, ttr);
526 ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
527 ktrans = (char)(255 - ktrans) << 24;
528 }
529
530 if (check_material) {
531 if (check_emis) {
532 GET_MAPATT(embuff, offset, kem);
533 kem = SCALE_ATT(ematt, kem, 0., 1.);
534 }
535
536 if (check_shin) {
537 GET_MAPATT(shbuff, offset, ksh);
538 ksh = SCALE_ATT(shatt, ksh, 0., 1.);
539 }
540
541 if (pksh != ksh || pkem != kem
542 || (kem && check_color)) {
543 pksh = ksh;
544 pkem = kem;
545 gsd_set_material(check_shin, check_emis,
546 ksh, kem, curcolor);
547 }
548 }
549
550 gsd_litvert_func(n, ktrans | curcolor, pt);
551
552#ifdef CALC_AREA
553 GS_v3eq(triv[cnt % 3], pt);
554#endif
555
556 cnt++;
557 }
558 }
559
560 if (dr4) {
561 offset = y1off + datacol2; /* TR */
562 FNORM(surf->norms[offset], n);
563 pt[X] = x2;
564 pt[Y] = y1;
565 GET_MAPATT(buff, offset, pt[Z]);
566 pt[Z] *= zexag;
567
569 (pt, window, viewport, modelMatrix, projMatrix)) {
570 gsd_endtmesh();
571 cnt = 0;
572 gsd_bgntmesh();
573 continue;
574 }
575
576 if (check_color) {
577 curcolor = gs_mapcolor(cobuff, coloratt, offset);
578 }
579
580 if (check_transp) {
581 GET_MAPATT(trbuff, offset, ttr);
582 ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
583 ktrans = (char)(255 - ktrans) << 24;
584 }
585
586 if (check_material) {
587 if (check_emis) {
588 GET_MAPATT(embuff, offset, kem);
589 kem = SCALE_ATT(ematt, kem, 0., 1.);
590 }
591
592 if (check_shin) {
593 GET_MAPATT(shbuff, offset, ksh);
594 ksh = SCALE_ATT(shatt, ksh, 0., 1.);
595 }
596
597 if (pksh != ksh || pkem != kem || (kem && check_color)) {
598 pksh = ksh;
599 pkem = kem;
600 gsd_set_material(check_shin, check_emis,
601 ksh, kem, curcolor);
602 }
603 }
604
605 gsd_litvert_func(n, ktrans | curcolor, pt);
606
607#ifdef CALC_AREA
608 GS_v3eq(triv[cnt % 3], pt);
609
610 if (cnt > 1) {
611 GS_v3eq(tedge1, triv[1]);
612 GS_v3eq(tedge2, triv[2]);
613 GS_v3sub(tedge1, triv[0]);
614 GS_v3sub(tedge2, triv[1]);
615 GS_v3cross(tedge1, tedge2, crossp);
616 GS_v3mag(crossp, &mag);
617 asurf += .5 * mag;
618 tedge1[Z] *= sz;
619 tedge2[Z] *= sz;
620 GS_v3cross(tedge1, tedge2, crossp);
621 GS_v3mag(crossp, &mag);
622 axsurf += .5 * mag;
623 }
624#endif
625
626 cnt++;
627 }
628
629 if (dr3) {
630 offset = y2off + datacol2; /* BR */
631 FNORM(surf->norms[offset], n);
632 pt[X] = x2;
633 pt[Y] = y2;
634 GET_MAPATT(buff, offset, pt[Z]);
635 pt[Z] *= zexag;
636
638 (pt, window, viewport, modelMatrix, projMatrix)) {
639 gsd_endtmesh();
640 cnt = 0;
641 gsd_bgntmesh();
642 continue;
643 }
644
645 if (check_color) {
646 curcolor = gs_mapcolor(cobuff, coloratt, offset);
647 }
648
649 if (check_transp) {
650 GET_MAPATT(trbuff, offset, ttr);
651 ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
652 ktrans = (char)(255 - ktrans) << 24;
653 }
654
655 if (check_material) {
656 if (check_emis) {
657 GET_MAPATT(embuff, offset, kem);
658 kem = SCALE_ATT(ematt, kem, 0., 1.);
659 }
660
661 if (check_shin) {
662 GET_MAPATT(shbuff, offset, ksh);
663 ksh = SCALE_ATT(shatt, ksh, 0., 1.);
664 }
665
666 if (pksh != ksh || pkem != kem || (kem && check_color)) {
667 pksh = ksh;
668 pkem = kem;
669 gsd_set_material(check_shin, check_emis,
670 ksh, kem, curcolor);
671 }
672 }
673
674 gsd_litvert_func(n, ktrans | curcolor, pt);
675
676#ifdef CALC_AREA
677 GS_v3eq(triv[cnt % 3], pt);
678
679 if (cnt > 1) {
680 GS_v3eq(tedge1, triv[1]);
681 GS_v3eq(tedge2, triv[2]);
682 GS_v3sub(tedge1, triv[0]);
683 GS_v3sub(tedge2, triv[1]);
684 GS_v3cross(tedge1, tedge2, crossp);
685 GS_v3mag(crossp, &mag);
686 asurf += .5 * mag;
687 tedge1[Z] *= sz;
688 tedge2[Z] *= sz;
689 GS_v3cross(tedge1, tedge2, crossp);
690 GS_v3mag(crossp, &mag);
691 axsurf += .5 * mag;
692 }
693#endif
694
695 cnt++;
696 }
697 } /* ea col */
698
699 gsd_endtmesh();
700 } /* ea row */
701
703 gsd_blend(0);
704 gsd_zwritemask(0xffffffff);
705
707
708#ifdef CALC_AREA
709 G_debug(5, " Surface Area: %.12lf", asurf);
710 G_debug(5, " Exaggerated Surface Area: %.12lf", axsurf);
711#endif
712
713 return (0);
714}
715
716/*!
717 \brief
718
719 Using tmesh - not confident with qstrips portability
720
721 \todo FIX: do_diff won't work right - needs normals - maybe
722 calculate on the fly
723
724 \param surf surface (geosurf)
725 \param k
726
727 \return
728 */
729int gsd_surf_const(geosurf * surf, float k)
730{
731 int do_diff, check_mask, check_color;
732 typbuff *cobuff;
733 int xmod, ymod, row, col, cnt, xcnt, ycnt;
734 long offset, y1off, y2off;
735 float x1, x2, y1, y2, tx, ty, tz;
736 float n[3], pt[4], xres, yres, ymax, zexag;
737 int col_src, curcolor;
738 gsurf_att *coloratt;
739
740 /* Viewport variables */
741 GLdouble modelMatrix[16], projMatrix[16];
742 GLint viewport[4];
743 GLint window[4];
744
745 int zeros, dr1, dr2, dr3, dr4;
746 int datarow1, datacol1, datarow2, datacol2;
747
748 unsigned int ktrans = 255;
749
750 G_debug(5, "gsd_surf_const(): id=%d", surf->gsurf_id);
751
752 if (GS_check_cancel()) {
753 return (-1);
754 }
755
756 cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
757
758 gs_update_curmask(surf);
759 check_mask = surf->curmask ? 1 : 0;
760
761 /*
762 checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
763 combine it/them with any current mask, put in surf->curmask:
764 */
765 do_diff = (NULL != gsdiff_get_SDref());
766 xmod = surf->x_mod;
767 ymod = surf->y_mod;
768 xres = xmod * surf->xres;
769 yres = ymod * surf->yres;
770
771 xcnt = VCOLS(surf);
772 ycnt = VROWS(surf);
773 ymax = (surf->rows - 1) * surf->yres;
774
775 /* Get Viewport */
776 gsd_getwindow(window, viewport, modelMatrix, projMatrix);
777 /* adjust window */
778 window[0] += (int)(yres * 2);
779 window[1] -= (int)(yres * 2);
780 window[2] -= (int)(xres * 2);
781 window[3] += (int)(xres * 2);
782
783
784 gsd_colormode(CM_DIFFUSE);
786
787 /* avoid scaling by zero */
788 GS_get_scale(&tx, &ty, &tz, 1);
789
790 if (tz == 0.0) {
791 k = 0.0;
792 gsd_do_scale(0);
793 }
794 else {
795 gsd_do_scale(1);
796 }
797
798 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
799 zexag = surf->z_exag;
800
801 if (CONST_ATT == surf->att[ATT_TRANSP].att_src) {
802 gsd_blend(1);
803 ktrans = 255 - (int)surf->att[ATT_TRANSP].constant;
804 gsd_zwritemask(0x0);
805 }
806
807 ktrans = (ktrans << 24);
808
809 /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
810 or else use more general and inefficient gets */
811
812 check_color = 1;
813 coloratt = &(surf->att[ATT_COLOR]);
814 col_src = surf->att[ATT_COLOR].att_src;
815
816 if (col_src != MAP_ATT) {
817 if (col_src == CONST_ATT) {
818 curcolor = (int)surf->att[ATT_COLOR].constant;
819 }
820 else {
821 curcolor = surf->wire_color;
822 }
823
824 check_color = 0;
825 }
826
827 /* CONSTANTS */
828 pt[Z] = k * zexag;
829 n[X] = n[Y] = 0.0;
830 n[Z] = 1.0;
831
832 /* just draw one polygon if no color mapped */
833 /* fast, but specular reflection will prob. be poor */
834 if (!check_color && !check_mask && !do_diff) {
836
837 pt[X] = pt[Y] = 0;
838 gsd_litvert_func(n, ktrans | curcolor, pt);
839
840 pt[X] = xcnt * xres;
841 gsd_litvert_func(n, ktrans | curcolor, pt);
842
843 pt[Y] = ycnt * yres;
844 gsd_litvert_func(n, ktrans | curcolor, pt);
845
846 pt[X] = 0;
847 gsd_litvert_func(n, ktrans | curcolor, pt);
848
851 gsd_blend(0);
852 gsd_zwritemask(0xffffffff);
853
854 return (0);
855 }
856
857 cnt = 0;
858
859 for (row = 0; row < ycnt; row++) {
860 if (GS_check_cancel()) {
862 gsd_blend(0);
863 gsd_zwritemask(0xffffffff);
864
865 return (-1);
866 }
867
868 datarow1 = row * ymod;
869 datarow2 = (row + 1) * ymod;
870
871 y1 = ymax - row * yres;
872 y2 = ymax - (row + 1) * yres;
873 y1off = row * ymod * surf->cols;
874 y2off = (row + 1) * ymod * surf->cols;
875
876 gsd_bgntmesh();
877
878 zeros = 0;
879 dr1 = dr2 = dr3 = dr4 = 1;
880
881 if (check_mask) {
882 if (BM_get(surf->curmask, 0, datarow1)) {
883 /*TL*/ ++zeros;
884 dr1 = 0;
885 }
886
887 if (BM_get(surf->curmask, 0, datarow2)) {
888 /*BL*/ ++zeros;
889 dr2 = 0;
890 }
891 }
892
893 if (dr1 && dr2) {
894 offset = y1off; /* TL */
895 pt[X] = 0;
896 pt[Y] = y1;
897
898 if (check_color) {
899 curcolor = gs_mapcolor(cobuff, coloratt, offset);
900 }
901
902 if (do_diff) {
903 pt[Z] = gsdiff_do_SD(k * zexag, offset);
904 }
905
906 gsd_litvert_func(n, ktrans | curcolor, pt);
907 cnt++;
908
909 offset = y2off; /* BL */
910 pt[X] = 0;
911 pt[Y] = y2;
912
913 if (check_color) {
914 curcolor = gs_mapcolor(cobuff, coloratt, offset);
915 }
916
917 if (do_diff) {
918 pt[Z] = gsdiff_do_SD(k * zexag, offset);
919 }
920
921 gsd_litvert_func(n, ktrans | curcolor, pt);
922 cnt++;
923 }
924
925 for (col = 0; col < xcnt; col++) {
926 datacol1 = col * xmod;
927 datacol2 = (col + 1) * xmod;
928
929 x1 = col * xres;
930 x2 = (col + 1) * xres;
931
932 zeros = 0;
933 dr1 = dr2 = dr3 = dr4 = 1;
934
935 if (check_mask) {
936 if (BM_get(surf->curmask, datacol1, datarow1)) {
937 /*TL*/ ++zeros;
938 dr1 = 0;
939 }
940
941 if (BM_get(surf->curmask, datacol1, datarow2)) {
942 /*BL*/ ++zeros;
943 dr2 = 0;
944 }
945
946 if (BM_get(surf->curmask, datacol2, datarow2)) {
947 /*BR*/ ++zeros;
948 dr3 = 0;
949 }
950
951 if (BM_get(surf->curmask, datacol2, datarow1)) {
952 /*TR*/ ++zeros;
953 dr4 = 0;
954 }
955
956 if ((zeros > 1) && cnt) {
957 gsd_endtmesh();
958 cnt = 0;
959 gsd_bgntmesh();
960 continue;
961 }
962
963 }
964
965 if (cnt > 250) {
966 cnt = 0;
967 gsd_endtmesh();
968 gsd_bgntmesh();
969
970 if (dr1) {
971 offset = y1off + datacol1; /* TL */
972 pt[X] = x1;
973 pt[Y] = y1;
974
976 (pt, window, viewport, modelMatrix, projMatrix)) {
977 gsd_endtmesh();
978 cnt = 0;
979 gsd_bgntmesh();
980 continue;
981 }
982
983 if (check_color) {
984 curcolor = gs_mapcolor(cobuff, coloratt, offset);
985 }
986
987 if (do_diff) {
988 pt[Z] = gsdiff_do_SD(k * zexag, offset);
989 }
990
991 gsd_litvert_func(n, ktrans | curcolor, pt);
992 cnt++;
993 }
994
995 if (dr2) {
996 offset = y2off + datacol1; /* BL */
997 pt[X] = x1;
998 pt[Y] = y2;
999
1000 if (gsd_checkpoint
1001 (pt, window, viewport, modelMatrix, projMatrix)) {
1002 gsd_endtmesh();
1003 cnt = 0;
1004 gsd_bgntmesh();
1005 continue;
1006 }
1007
1008 if (check_color) {
1009 curcolor = gs_mapcolor(cobuff, coloratt, offset);
1010 }
1011
1012 if (do_diff) {
1013 pt[Z] = gsdiff_do_SD(k * zexag, offset);
1014 }
1015
1016 gsd_litvert_func(n, ktrans | curcolor, pt);
1017 cnt++;
1018 }
1019 }
1020
1021 if (dr4) {
1022 offset = y1off + datacol2; /* TR */
1023 pt[X] = x2;
1024 pt[Y] = y1;
1025
1026 if (gsd_checkpoint
1027 (pt, window, viewport, modelMatrix, projMatrix)) {
1028 gsd_endtmesh();
1029 cnt = 0;
1030 gsd_bgntmesh();
1031 continue;
1032 }
1033
1034 if (check_color) {
1035 curcolor = gs_mapcolor(cobuff, coloratt, offset);
1036 }
1037
1038 if (do_diff) {
1039 pt[Z] = gsdiff_do_SD(k * zexag, offset);
1040 }
1041
1042 gsd_litvert_func(n, ktrans | curcolor, pt);
1043 cnt++;
1044 }
1045
1046 if (dr3) {
1047 offset = y2off + datacol2; /* BR */
1048 pt[X] = x2;
1049 pt[Y] = y2;
1050
1051 if (gsd_checkpoint
1052 (pt, window, viewport, modelMatrix, projMatrix)) {
1053 gsd_endtmesh();
1054 cnt = 0;
1055 gsd_bgntmesh();
1056 continue;
1057 }
1058
1059 if (check_color) {
1060 curcolor = gs_mapcolor(cobuff, coloratt, offset);
1061 }
1062
1063 if (do_diff) {
1064 pt[Z] = gsdiff_do_SD(k * zexag, offset);
1065 }
1066
1067 gsd_litvert_func(n, ktrans | curcolor, pt);
1068 cnt++;
1069 }
1070 } /* ea col */
1071
1072 gsd_endtmesh();
1073 } /* ea row */
1074
1075 gsd_popmatrix();
1076 gsd_blend(0);
1077 gsd_zwritemask(0xffffffff);
1078
1079 return (0);
1080}
1081
1082/*!
1083 \brief Define user function
1084
1085 Not yet supported
1086
1087 \param gs surface (geosurf)
1088 \param user_func user function
1089
1090 \return 1
1091 */
1092int gsd_surf_func(geosurf * gs, int (*user_func) ())
1093{
1094
1095 return (1);
1096}
1097
1098/*!
1099 \brief ADD
1100
1101 \param npts1
1102 \param npts2
1103 \param surf1 first surface (geosurf)
1104 \param surf2 second surface (geosurf)
1105 \param points1
1106 \param points2
1107 \param norm
1108
1109 \return 1
1110 */
1111int gsd_triangulated_wall(int npts1, int npts2, geosurf * surf1,
1112 geosurf * surf2, Point3 * points1, Point3 * points2,
1113 float *norm)
1114{
1115 int i, i1, i2, nlong, offset, col_src;
1116 int check_color1, check_color2, color1, color2;
1117 typbuff *cobuf1, *cobuf2;
1118 gsurf_att *coloratt1, *coloratt2;
1119
1120 check_color1 = check_color2 = 1;
1121
1122 col_src = surf1->att[ATT_COLOR].att_src;
1123
1124 if (col_src != MAP_ATT) {
1125 if (col_src == CONST_ATT) {
1126 color1 = (int)surf1->att[ATT_COLOR].constant;
1127 }
1128 else {
1129 color1 = surf1->wire_color;
1130 }
1131
1132 check_color1 = 0;
1133 }
1134
1135 coloratt1 = &(surf1->att[ATT_COLOR]);
1136 cobuf1 = gs_get_att_typbuff(surf1, ATT_COLOR, 0);
1137
1138 col_src = surf2->att[ATT_COLOR].att_src;
1139 if (col_src != MAP_ATT) {
1140 if (col_src == CONST_ATT) {
1141 color2 = (int)surf2->att[ATT_COLOR].constant;
1142 }
1143 else {
1144 color2 = surf2->wire_color;
1145 }
1146
1147 check_color2 = 0;
1148 }
1149
1150 coloratt2 = &(surf2->att[ATT_COLOR]);
1151 cobuf2 = gs_get_att_typbuff(surf2, ATT_COLOR, 0);
1152
1153 gsd_colormode(CM_DIFFUSE);
1155 gsd_do_scale(1);
1156
1157 gsd_bgntmesh();
1158
1159 for (nlong = (npts1 > npts2 ? npts1 : npts2), i = 0; i < nlong; i++) {
1160 i1 = i * npts1 / nlong;
1161 i2 = i * npts2 / nlong;
1162 offset = XY2OFF(surf1, points1[i1][X], points1[i1][Y]);
1163
1164 if (check_color1) {
1165 color1 = gs_mapcolor(cobuf1, coloratt1, offset);
1166 }
1167
1168 offset = XY2OFF(surf1, points2[i2][X], points2[i2][Y]);
1169
1170 if (check_color2) {
1171 color2 = gs_mapcolor(cobuf2, coloratt2, offset);
1172 }
1173
1174 /* start with long line to ensure triangle */
1175 if (npts1 > npts2) {
1176 points1[i1][X] += surf1->x_trans;
1177 points1[i1][Y] += surf1->y_trans;
1178 points1[i1][Z] += surf1->z_trans;
1179 gsd_litvert_func(norm, color1, points1[i1]);
1180 points2[i2][X] += surf2->x_trans;
1181 points2[i2][Y] += surf2->y_trans;
1182 points2[i2][Z] += surf2->z_trans;
1183 gsd_litvert_func(norm, color2, points2[i2]);
1184 }
1185 else {
1186 points2[i2][X] += surf2->x_trans;
1187 points2[i2][Y] += surf2->y_trans;
1188 points2[i2][Z] += surf2->z_trans;
1189 gsd_litvert_func(norm, color2, points2[i2]);
1190 points1[i1][X] += surf1->x_trans;
1191 points1[i1][Y] += surf1->y_trans;
1192 points1[i1][Z] += surf1->z_trans;
1193 gsd_litvert_func(norm, color1, points1[i1]);
1194 }
1195 }
1196
1197 gsd_endtmesh();
1198 gsd_popmatrix();
1199
1200 return (1);
1201}
1202
1203/*!
1204 \brief ADD
1205
1206 \param mode
1207 */
1208void gsd_setfc(int mode)
1209{
1210 FCmode = mode;
1211
1212 return;
1213}
1214
1215/*!
1216 \brief ADD
1217
1218 \return
1219 */
1220int gsd_getfc(void)
1221{
1222 return (FCmode);
1223}
1224
1225/*!
1226 \brief ADD
1227
1228 \param surf surface (geosurf)
1229 \param point
1230
1231 \return
1232 */
1233static int transpoint_is_masked(geosurf * surf, Point3 point)
1234{
1235 Point3 tp;
1236
1237 tp[X] = point[X] - surf->x_trans;
1238 tp[Y] = point[Y] - surf->y_trans;
1239
1240 return (gs_point_is_masked(surf, tp));
1241}
1242
1243/*!
1244 \brief ADD
1245
1246 \param points
1247 \param gsurf
1248 \param ptn
1249 \param cursurf
1250 \param numsurfs
1251 \param belowsurf
1252
1253 \return 0 if there is no surface below the current,
1254 \return -1 if the current surface is masked,
1255 \return 1 if the surface below the current surface is not masked
1256 (belowsurf is assigned)
1257 */
1258static int get_point_below(Point3 ** points, geosurf ** gsurfs, int ptn,
1259 int cursurf, int numsurfs, int *belowsurf)
1260{
1261 int n, found = -1;
1262 float nearz = 0.0, diff;
1263
1264 if (gsurfs[cursurf]->curmask) {
1265 if (transpoint_is_masked(gsurfs[cursurf], points[cursurf][ptn])) {
1266 return (-1);
1267 }
1268 }
1269
1270 for (n = 0; n < numsurfs; ++n) {
1271 diff = points[cursurf][ptn][Z] - points[n][ptn][Z];
1272
1273 if (diff > 0) {
1274 if (!nearz || diff < nearz) {
1275 if (gsurfs[n]->curmask) {
1276 if (transpoint_is_masked(gsurfs[n], points[n][ptn])) {
1277 continue;
1278 }
1279 }
1280
1281 nearz = diff;
1282 found = n;
1283 }
1284 }
1285 /* else if (diff == 0.0 && n != cursurf)
1286 {
1287 if (gsurfs[n]->curmask)
1288 {
1289 if (transpoint_is_masked(gsurfs[n], points[n][ptn]))
1290 {
1291 continue;
1292 }
1293 }
1294
1295 nearz=diff;
1296 found = n;
1297 break;
1298 }
1299 */
1300 }
1301
1302 if (found != -1) {
1303 *belowsurf = found;
1304
1305 return (1);
1306 }
1307
1308 return (0);
1309}
1310
1311
1312/*
1313 #define CPDEBUG
1314 */
1315
1316/*!
1317 \brief ADD
1318
1319 \param np
1320 \param ns
1321 \param gsurfs
1322 \param points
1323 \param norm
1324
1325 \return
1326 */
1327int gsd_ortho_wall(int np, int ns, geosurf ** gsurfs, Point3 ** points,
1328 float *norm)
1329{
1330 int n, i, offset, col_src, check_color[MAX_SURFS];
1331 int color, colors[MAX_SURFS], nocolor;
1332 typbuff *cobuf[MAX_SURFS];
1333 gsurf_att *coloratt[MAX_SURFS];
1334
1335 nocolor = FCmode == FC_GREY ? 1 : 0;
1336
1337 if (!nocolor) {
1338 for (n = 0; n < ns; ++n) {
1339 check_color[n] = 1;
1340
1341 col_src = gsurfs[n]->att[ATT_COLOR].att_src;
1342
1343 if (col_src != MAP_ATT) {
1344 if (col_src == CONST_ATT) {
1345 colors[n] = (int)gsurfs[n]->att[ATT_COLOR].constant;
1346 }
1347 else {
1348 colors[n] = gsurfs[n]->wire_color;
1349 }
1350
1351 check_color[n] = 0;
1352 }
1353
1354 coloratt[n] = &(gsurfs[n]->att[ATT_COLOR]);
1355 cobuf[n] = gs_get_att_typbuff(gsurfs[n], ATT_COLOR, 0);
1356 }
1357 }
1358
1359#ifdef CPDEBUG
1360 {
1361 GS_set_draw(GSD_BOTH);
1362 }
1363#endif
1364
1365 /* changed from CM_DIFFUSE - July 25, 2005
1366 * should display proper color for cut planes
1367 */
1368 gsd_colormode(CM_COLOR);
1369
1370 /* actually ought to write a GS_set_fencetransp() */
1371 if (nocolor) {
1372 color = 0x80808080;
1373 gsd_blend(1);
1374 gsd_zwritemask(0x0);
1375 }
1376
1378 gsd_do_scale(1);
1379
1380 /* using segs_intersect here with segments projected to
1381 the 2d clipping plane */
1382 {
1383 float tx, ty;
1384 int bn, bnl, ctop, cbot, ctopl, cbotl, bsret;
1385 Point3 xing;
1386
1387 if (nocolor) {
1388 ctop = cbot = ctopl = cbotl = color;
1389 }
1390
1391 for (n = 0; n < ns; ++n) {
1392 for (i = 0; i < np; i++) {
1393 if (0 <
1394 (bsret =
1395 get_point_below(points, gsurfs, i, n, ns, &bn))) {
1396 gsd_bgntmesh();
1397
1398 if (!nocolor) {
1399 SET_SCOLOR(n);
1400 SET_SCOLOR(bn);
1401
1402 if (FCmode == FC_ABOVE) {
1403 ctop = cbot = colors[n];
1404 }
1405 else if (FCmode == FC_BELOW) {
1406 ctop = cbot = colors[bn];
1407 }
1408 else {
1409 cbot = colors[bn];
1410 ctop = colors[n];
1411 }
1412 }
1413
1414 if (i) {
1415 /* need to find crossing? */
1416 if (!transpoint_is_masked(gsurfs[n], points[n][i - 1])
1417 && !transpoint_is_masked(gsurfs[bn],
1418 points[bn][i - 1])) {
1419 if (1 ==
1420 segs_intersect(0.0, points[n][i - 1][Z], 1.0,
1421 points[n][i][Z], 0.0,
1422 points[bn][i - 1][Z], 1.0,
1423 points[bn][i][Z], &tx, &ty)) {
1424 xing[Z] = ty;
1425 xing[Y] = points[n][i - 1][Y] + tx *
1426 (points[n][i][Y] - points[n][i - 1][Y]);
1427 xing[X] = points[n][i - 1][X] + tx *
1428 (points[n][i][X] - points[n][i - 1][X]);
1429 gsd_litvert_func(norm, ctop, xing);
1430 xing[Z] = points[bn][i - 1][Z] + tx *
1431 (points[bn][i][Z] - points[bn][i - 1][Z]);
1432 gsd_litvert_func(norm, cbot, xing);
1433 }
1434 }
1435 }
1436
1437 gsd_litvert_func(norm, ctop, points[n][i]);
1438 gsd_litvert_func(norm, cbot, points[bn][i]);
1439 i++;
1440
1441 bnl = -1;
1442
1443 while (i < np && 0 < (bsret =
1444 get_point_below(points, gsurfs, i,
1445 n, ns, &bn))) {
1446#ifdef CPDEBUG
1447 {
1448 int lower = 0;
1449
1450 if (GS_check_cancel()) {
1451 break;
1452 }
1453 }
1454#endif
1455
1456 if (!nocolor) {
1457 ctopl = ctop;
1458 cbotl = cbot;
1459 SET_SCOLOR(n);
1460 SET_SCOLOR(bn);
1461
1462 if (FCmode == FC_ABOVE) {
1463 ctop = cbot = colors[n];
1464 }
1465 else if (FCmode == FC_BELOW) {
1466 ctop = cbot = colors[bn];
1467 }
1468 else {
1469 cbot = colors[bn];
1470 ctop = colors[n];
1471 }
1472 }
1473
1474 /*
1475 IF UPPER crossing :
1476 (crossing is between current & new lower surf)
1477 IF XING going DOWN:
1478 - plot crossing point (color previous upper)
1479 - endtmesh/bgntmesh
1480 - plot crossing point (color current upper)
1481 - plot "equivalent" point below (color current lower)
1482 IF XING going UP:
1483 - plot crossing point (color previous upper)
1484 - plot "equivalent" point below (color previous lower)
1485 - endtmesh/bgntmesh
1486 - plot crossing point (color current upper)
1487 ELSE IF LOWER crossing:
1488 (crossing between new & previous lower surfs):
1489 - plot "equivalent" point above (color previous upper)
1490 - plot crossing below (color previous lower)
1491 - endtmesh/bgntmesh
1492 - plot "equivalent" point above (color current upper)
1493 - plot crossing below (color current lower)
1494 */
1495 if (bnl >= 0 && bnl != bn) {
1496 /* crossing */
1497 float z1, z2;
1498 int upper = 0;
1499
1500 if (!transpoint_is_masked(gsurfs[n],
1501 points[n][i - 1]) &&
1502 !transpoint_is_masked(gsurfs[bnl],
1503 points[bnl][i - 1]) &&
1504 !transpoint_is_masked(gsurfs[bn],
1505 points[bn][i - 1])) {
1506
1507 if (1 == segs_intersect(0.0,
1508 points[n][i - 1][Z],
1509 1.0, points[n][i][Z],
1510 0.0,
1511 points[bn][i - 1][Z],
1512 1.0, points[bn][i][Z],
1513 &tx, &ty)) {
1514 /* crossing going up */
1515
1516 G_debug(5,
1517 "crossing going up at surf %d no. %d",
1518 n, i);
1519
1520 upper = 1;
1521 xing[Z] = ty;
1522 xing[Y] = points[n][i - 1][Y] + tx *
1523 (points[n][i][Y] -
1524 points[n][i - 1][Y]);
1525 xing[X] =
1526 points[n][i - 1][X] +
1527 tx * (points[n][i][X] -
1528 points[n][i - 1][X]);
1529 gsd_litvert_func(norm, ctopl, xing);
1530 z1 = xing[Z];
1531 xing[Z] = points[bnl][i - 1][Z] + tx *
1532 (points[bnl][i][Z] -
1533 points[bnl][i - 1][Z]);
1534 gsd_litvert_func(norm, cbotl, xing);
1535 xing[Z] = z1;
1536 gsd_endtmesh();
1537 gsd_bgntmesh();
1538 gsd_litvert_func(norm, ctop, xing);
1539 }
1540 else if (1 == segs_intersect(0.0,
1541 points[n][i -
1542 1][Z],
1543 1.0,
1544 points[n][i][Z],
1545 0.0,
1546 points[bnl][i -
1547 1]
1548 [Z], 1.0,
1549 points[bnl][i]
1550 [Z], &tx, &ty)) {
1551 /* crossing going down */
1552
1553 G_debug(5,
1554 "crossing going down at surf %d no. %d",
1555 n, i);
1556
1557 upper = 1;
1558 xing[Z] = ty;
1559 xing[Y] = points[n][i - 1][Y] + tx *
1560 (points[n][i][Y] -
1561 points[n][i - 1][Y]);
1562 xing[X] =
1563 points[n][i - 1][X] +
1564 tx * (points[n][i][X] -
1565 points[n][i - 1][X]);
1566 gsd_litvert_func(norm, ctopl, xing);
1567 z1 = xing[Z];
1568 xing[Z] = points[bnl][i - 1][Z] + tx *
1569 (points[bnl][i][Z] -
1570 points[bnl][i - 1][Z]);
1571 gsd_litvert_func(norm, cbotl, xing);
1572 xing[Z] = z1;
1573 gsd_endtmesh();
1574 gsd_bgntmesh();
1575 gsd_litvert_func(norm, ctop, xing);
1576 xing[Z] = points[bn][i - 1][Z] + tx *
1577 (points[bn][i][Z] -
1578 points[bn][i - 1][Z]);
1579 gsd_litvert_func(norm, cbot, xing);
1580 }
1581 }
1582
1583 if (!upper &&
1584 !transpoint_is_masked(gsurfs[bn],
1585 points[bn][i - 1]) &&
1586 !transpoint_is_masked(gsurfs[bnl],
1587 points[bnl][i - 1])) {
1588
1589 if (1 == segs_intersect(0.0,
1590 points[bn][i - 1][Z],
1591 1.0, points[bn][i][Z],
1592 0.0,
1593 points[bnl][i - 1][Z],
1594 1.0,
1595 points[bnl][i][Z],
1596 &tx, &ty)) {
1597#ifdef CPDEBUG
1598 {
1599 lower = 1;
1600 }
1601#endif
1602 G_debug(5,
1603 "lower crossing at surf %d no. %d between surfs %d & %d",
1604 n, i, bn, bnl);
1605
1606 xing[Z] = ty;
1607 xing[Y] = points[bn][i - 1][Y] + tx *
1608 (points[bn][i][Y] -
1609 points[bn][i - 1][Y]);
1610 xing[X] = points[bn][i - 1][X] + tx *
1611 (points[bn][i][X] -
1612 points[bn][i - 1][X]);
1613 z2 = xing[Z];
1614 z1 = xing[Z] = points[n][i - 1][Z] + tx *
1615 (points[n][i][Z] -
1616 points[n][i - 1][Z]);
1617 gsd_litvert_func(norm, ctopl, xing);
1618 xing[Z] = z2;
1619 gsd_litvert_func(norm, cbotl, xing);
1620 gsd_endtmesh();
1621 gsd_bgntmesh();
1622 xing[Z] = z1;
1623 gsd_litvert_func(norm, ctop, xing);
1624 xing[Z] = z2;
1625 gsd_litvert_func(norm, cbot, xing);
1626 }
1627 }
1628
1629#ifdef CPDEBUG
1630 {
1631 if (!upper && !lower) {
1632 G_debug(5,
1633 "Crossing NOT found or masked:");
1634 G_debug(5,
1635 " current surf: %d [ %.2f %.2f %.2f -> %.2f %.2f %f",
1636 n, points[n][i - 1][X],
1637 points[n][i - 1][Y],
1638 points[n][i - 1][Z],
1639 points[n][i][X], points[n][i][Y],
1640 points[n][i][Z]);
1641 G_debug(5,
1642 " below surf: %d [ %.2f %.2f %.2f -> %.2f %.2f %f\n",
1643 bn, points[bn][i - 1][X],
1644 points[bn][i - 1][Y],
1645 points[bn][i - 1][Z],
1646 points[bn][i][X],
1647 points[bn][i][Y],
1648 points[bn][i][Z]);
1649 G_debug(5, gs
1650 " last below surf: %d [ %.2f %.2f %.2f -> %.2f %.2f %f\n",
1651 bnl, points[bnl][i - 1][X],
1652 points[bnl][i - 1][Y],
1653 points[bnl][i - 1][Z],
1654 points[bnl][i][X],
1655 points[bnl][i][Y],
1656 points[bnl][i][Z]);
1657 }
1658 }
1659#endif
1660 }
1661
1662 gsd_litvert_func(norm, ctop, points[n][i]);
1663 gsd_litvert_func(norm, cbot, points[bn][i]);
1664 bnl = bn;
1665 i++;
1666 }
1667
1668 if (i < np) {
1669 /* need to find crossing? */
1670 if (!transpoint_is_masked(gsurfs[n], points[n][i - 1])
1671 && !transpoint_is_masked(gsurfs[bn],
1672 points[bn][i - 1])) {
1673 if (1 ==
1674 segs_intersect(0.0, points[n][i - 1][Z], 1.0,
1675 points[n][i][Z], 0.0,
1676 points[bn][i - 1][Z], 1.0,
1677 points[bn][i][Z], &tx, &ty)) {
1678 xing[Z] = ty;
1679 xing[Y] = points[n][i - 1][Y] + tx *
1680 (points[n][i][Y] - points[n][i - 1][Y]);
1681 xing[X] = points[n][i - 1][X] + tx *
1682 (points[n][i][X] - points[n][i - 1][X]);
1683 gsd_litvert_func(norm, ctop, xing);
1684 }
1685
1686 i--;
1687 }
1688 }
1689
1690 gsd_endtmesh();
1691 }
1692 }
1693 }
1694 }
1695
1696 gsd_colormode(CM_DIFFUSE); /* set colormode back to DIFFUSE */
1697 gsd_popmatrix();
1698 gsd_blend(0);
1699 gsd_zwritemask(0xffffffff);
1700
1701 return (1);
1702}
1703
1704/*!
1705 \brief ADD
1706
1707 bgn,end should already be in world modeling coords, but have to
1708 be reverse-translated to apply to each surface
1709
1710 \param bgn,end 2d line for cutting plane
1711 \param norm indicates which way wall faces
1712
1713 \return
1714 */
1715int gsd_wall(float *bgn, float *end, float *norm)
1716{
1717 geosurf *gsurfs[MAX_SURFS];
1718 Point3 *points[MAX_SURFS], *tmp;
1719 int nsurfs, ret, npts, npts1, n, i, err = 0;
1720 float bgn1[2], end1[2];
1721
1722 if (norm[Z] > 0.0001 || norm[Z] < -.0001) {
1723 return (0); /* can't do tilted wall yet */
1724 }
1725
1726 if (FCmode == FC_OFF) {
1727 return (0);
1728 }
1729
1730 nsurfs = gs_getall_surfaces(gsurfs);
1731
1732 for (n = 0; n < nsurfs; n++) {
1733 /* get drape points for surf */
1734 bgn1[X] = bgn[X] - gsurfs[n]->x_trans;
1735 bgn1[Y] = bgn[Y] - gsurfs[n]->y_trans;
1736 end1[X] = end[X] - gsurfs[n]->x_trans;
1737 end1[Y] = end[Y] - gsurfs[n]->y_trans;
1738 tmp = gsdrape_get_allsegments(gsurfs[n], bgn1, end1, &npts1);
1739
1740 if (n) {
1741 if (npts != npts1) {
1742 G_warning(_("Cut-plane points mis-match between surfaces. "
1743 "Check resolution(s)."));
1744 err = 1;
1745 nsurfs = n;
1746
1747 break;
1748 }
1749 }
1750
1751 npts = npts1;
1752
1753 if (n == nsurfs - 1) {
1754 /* last surf - don't need to copy */
1755 points[n] = tmp;
1756
1757 for (i = 0; i < npts1; i++) {
1758 /* DOING translation here! */
1759 points[n][i][X] += gsurfs[n]->x_trans;
1760 points[n][i][Y] += gsurfs[n]->y_trans;
1761 points[n][i][Z] += gsurfs[n]->z_trans;
1762 }
1763
1764 break;
1765 }
1766
1767 /* allocate space in points and copy tmp to points */
1768 points[n] = (Point3 *) G_calloc(npts1, sizeof(Point3)); /* G_fatal_error */
1769
1770 for (i = 0; i < npts1; i++) {
1771 GS_v3eq(points[n][i], tmp[i]);
1772
1773 /* DOING translation here! */
1774 points[n][i][X] += gsurfs[n]->x_trans;
1775 points[n][i][Y] += gsurfs[n]->y_trans;
1776 points[n][i][Z] += gsurfs[n]->z_trans;
1777 }
1778 } /* done for */
1779
1780 if (err) {
1781 for (n = 0; n < nsurfs; n++) {
1782 if (points[n]) {
1783 G_free(points[n]);
1784 }
1785 }
1786 return (0);
1787 }
1788
1789
1790 ret = gsd_ortho_wall(npts, nsurfs, gsurfs, points, norm);
1791
1792 for (n = 0; n < nsurfs - 1; n++) {
1793 /* don't free last - it's constant */
1794 G_free(points[n]);
1795 }
1796
1797 return (ret);
1798}
1799
1800/*!
1801 \brief ADD
1802
1803 Need to do Zexag scale of normal for arrow direction, drawing
1804 routine unexags z for arrow
1805
1806 \param surf surface (geosurf)
1807
1808 \return
1809 */
1810int gsd_norm_arrows(geosurf * surf)
1811{
1812 typbuff *buff, *cobuff;
1813 int check_mask, check_color;
1814 int xmod, ymod, row, col, cnt, xcnt, ycnt;
1815 long offset, y1off, y2off;
1816 float x1, x2, y1, y2, tx, ty, tz, sz;
1817 float n[3], pt[4], xres, yres, ymax, zexag;
1818 int col_src, curcolor;
1819 gsurf_att *coloratt;
1820
1821 int zeros, dr1, dr2, dr3, dr4;
1822 int datarow1, datacol1, datarow2, datacol2;
1823
1824 G_debug(3, "gsd_norm_arrows");
1825
1826 /* avoid scaling by zero */
1827 GS_get_scale(&tx, &ty, &tz, 1);
1828
1829 if (tz == 0.0) {
1830 return (0);
1831 }
1832
1833 sz = GS_global_exag();
1834
1835 /*
1836 checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
1837 combine it/them with any current mask, put in surf->curmask:
1838 */
1839 gs_update_curmask(surf);
1840 check_mask = surf->curmask ? 1 : 0;
1841
1842 check_color = 1;
1843 coloratt = &(surf->att[ATT_COLOR]);
1844 col_src = surf->att[ATT_COLOR].att_src;
1845
1846 if (col_src != MAP_ATT) {
1847 if (col_src == CONST_ATT) {
1848 curcolor = (int)surf->att[ATT_COLOR].constant;
1849 }
1850 else {
1851 curcolor = surf->wire_color;
1852 }
1853
1854 check_color = 0;
1855 }
1856
1857 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
1858 cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
1859
1860 xmod = surf->x_mod;
1861 ymod = surf->y_mod;
1862 xres = xmod * surf->xres;
1863 yres = ymod * surf->yres;
1864 ymax = (surf->rows - 1) * surf->yres;
1865
1866 xcnt = VCOLS(surf);
1867 ycnt = VROWS(surf);
1868
1870 gsd_do_scale(1);
1871 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
1872
1873 zexag = surf->z_exag;
1874 /* CURRENTLY ALWAYS 1.0 */
1875
1876#ifdef DO_ARROW_SOLID
1877 gsd_colormode(CM_DIFFUSE);
1878#else
1879 gsd_colormode(CM_COLOR);
1880#endif
1881
1882 cnt = 0;
1883
1884 for (row = 0; row < ycnt; row++) {
1885 if (GS_check_cancel()) {
1886 gsd_popmatrix();
1887
1888 return (-1);
1889 }
1890
1891 datarow1 = row * ymod;
1892 datarow2 = (row + 1) * ymod;
1893
1894 y1 = ymax - row * yres;
1895 y2 = ymax - (row + 1) * yres;
1896 y1off = row * ymod * surf->cols;
1897 y2off = (row + 1) * ymod * surf->cols;
1898
1899 zeros = 0;
1900 dr1 = dr2 = dr3 = dr4 = 1;
1901
1902 if (check_mask) {
1903 if (BM_get(surf->curmask, 0, datarow1)) {
1904 /*TL*/ ++zeros;
1905 dr1 = 0;
1906 }
1907
1908 if (BM_get(surf->curmask, 0, datarow2)) {
1909 /*BL*/ ++zeros;
1910 dr2 = 0;
1911 }
1912 }
1913
1914 if (dr1 && dr2) {
1915 offset = y1off; /* TL */
1916 FNORM(surf->norms[offset], n);
1917 pt[X] = 0;
1918 pt[Y] = y2;
1919 GET_MAPATT(buff, offset, pt[Z]);
1920 pt[Z] *= zexag;
1921
1922 if (check_color) {
1923 curcolor = gs_mapcolor(cobuff, coloratt, offset);
1924 }
1925
1926#ifdef DO_ARROW_SOLID
1927 gsd_3darrow(pt, curcolor, xres * 2, xres / 2, n, sz);
1928#else
1929 if (DEBUG_ARROW) {
1930 gsd_arrow(pt, 0x000000, xres * 2, n, sz, surf);
1931 }
1932#endif
1933
1934 cnt++;
1935
1936 offset = y2off; /* BL */
1937 FNORM(surf->norms[offset], n);
1938 pt[X] = 0;
1939 pt[Y] = y2;
1940 GET_MAPATT(buff, offset, pt[Z]);
1941 pt[Z] *= zexag;
1942
1943 if (check_color) {
1944 curcolor = gs_mapcolor(cobuff, coloratt, offset);
1945 }
1946
1947#ifdef DO_ARROW_SOLID
1948 gsd_3darrow(pt, curcolor, xres * 2, xres / 2, n, sz);
1949#else
1950 if (DEBUG_ARROW) {
1951 gsd_arrow(pt, 0x000000, xres * 2, n, sz, surf);
1952 }
1953#endif
1954
1955 cnt++;
1956 }
1957
1958 for (col = 0; col < xcnt; col++) {
1959 datacol1 = col * xmod;
1960 datacol2 = (col + 1) * xmod;
1961
1962 x1 = col * xres;
1963 x2 = (col + 1) * xres;
1964
1965 zeros = 0;
1966 dr1 = dr2 = dr3 = dr4 = 1;
1967
1968 if (check_mask) {
1969 if (BM_get(surf->curmask, datacol1, datarow1)) {
1970 /*TL*/ ++zeros;
1971 dr1 = 0;
1972 }
1973
1974 if (BM_get(surf->curmask, datacol1, datarow2)) {
1975 /*BL*/ ++zeros;
1976 dr2 = 0;
1977 }
1978
1979 if (BM_get(surf->curmask, datacol2, datarow2)) {
1980 /*BR*/ ++zeros;
1981 dr3 = 0;
1982 }
1983
1984 if (BM_get(surf->curmask, datacol2, datarow1)) {
1985 /*TR*/ ++zeros;
1986 dr4 = 0;
1987 }
1988
1989 if ((zeros > 1) && cnt) {
1990 cnt = 0;
1991 continue;
1992 }
1993
1994 }
1995
1996 if (dr4) {
1997 offset = y1off + datacol2; /* TR */
1998 FNORM(surf->norms[offset], n);
1999 pt[X] = x2;
2000 pt[Y] = y1;
2001 GET_MAPATT(buff, offset, pt[Z]);
2002 pt[Z] *= zexag;
2003
2004 if (check_color) {
2005 curcolor = gs_mapcolor(cobuff, coloratt, offset);
2006 }
2007
2008#ifdef DO_ARROW_SOLID
2009 gsd_3darrow(pt, curcolor, xres * 2, xres / 2, n, sz);
2010#else
2011 if (DEBUG_ARROW) {
2012 gsd_arrow(pt, 0x000000, xres * 2, n, sz, surf);
2013 }
2014#endif
2015
2016 cnt++;
2017 }
2018
2019 if (dr3) {
2020 offset = y2off + datacol2; /* BR */
2021 FNORM(surf->norms[offset], n);
2022 pt[X] = x2;
2023 pt[Y] = y2;
2024 GET_MAPATT(buff, offset, pt[Z]);
2025 pt[Z] *= zexag;
2026
2027 if (check_color) {
2028 curcolor = gs_mapcolor(cobuff, coloratt, offset);
2029 }
2030
2031#ifdef DO_ARROW_SOLID
2032 gsd_3darrow(pt, curcolor, xres * 2, xres / 2, n, sz);
2033#else
2034 if (DEBUG_ARROW) {
2035 gsd_arrow(pt, 0x000000, xres * 2, n, sz, surf);
2036 }
2037#endif
2038
2039 cnt++;
2040 }
2041 } /* ea col */
2042 } /* ea row */
2043 gsd_popmatrix();
2044
2045 return (1);
2046}
2047
2048
2049/*!
2050 \brief Draw surface using triangle fan instead of strip
2051
2052 Optimized by getting rid of BM_get mask check - GET_MAPPATT does same
2053 and returns zero if masked
2054
2055 Only do in window check on Fan center(v0) to further optimize -- this runs
2056 the risk of trimming points in view !!
2057
2058 \param surf surface (geosurf)
2059
2060 \return
2061 */
2062int gsd_surf_map(geosurf * surf)
2063{
2064 int check_mask, check_color, check_transp;
2065 int check_material, check_emis, check_shin;
2066 typbuff *buff, *cobuff, *trbuff, *embuff, *shbuff;
2067 int xmod, ymod;
2068 int row, col, cnt, xcnt, ycnt;
2069 long y1off, y2off, y3off;
2070 long offset2[10];
2071 float pt2[10][2];
2072 int ii;
2073 float x1, x2, x3, y1, y2, y3, tx, ty, tz, ttr;
2074 float n[3], pt[4], xres, yres, ymax, zexag;
2075 int em_src, sh_src, trans_src, col_src, curcolor;
2076 gsurf_att *ematt, *shatt, *tratt, *coloratt;
2077
2078
2079 /* Viewport variables for accelerated drawing */
2080 GLdouble modelMatrix[16], projMatrix[16];
2081 GLint viewport[4];
2082 GLint window[4];
2083 int cnt1 = 0, cnt2 = 0;
2084
2085 int datarow1, datacol1, datarow2, datacol2, datarow3, datacol3;
2086
2087 float kem, ksh, pkem, pksh;
2088 unsigned int ktrans;
2089
2090 int step_val = 2; /* should always be factor of 2 for fan */
2091 int start_val = 1; /* one half of step_val */
2092
2093 /* avoid scaling by zero */
2094 GS_get_scale(&tx, &ty, &tz, 1);
2095
2096 if (tz == 0.0) {
2097 return (gsd_surf_const(surf, 0.0));
2098 }
2099 /* else if (surf->z_exag == 0.0)
2100 {
2101 return(gsd_surf_const(surf, surf->z_min));
2102 }
2103 NOT YET IMPLEMENTED */
2104
2105 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
2106 cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
2107
2108 gs_update_curmask(surf);
2109 check_mask = surf->curmask ? 1 : 0;
2110
2111 /*
2112 checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
2113 combine it/them with any current mask, put in surf->curmask:
2114 */
2115 xmod = surf->x_mod;
2116 ymod = surf->y_mod;
2117 xres = xmod * surf->xres;
2118 yres = ymod * surf->yres;
2119 ymax = (surf->rows - 1) * surf->yres;
2120
2121 xcnt = VCOLS(surf);
2122 ycnt = VROWS(surf);
2123
2124 /* Get viewport */
2125 gsd_getwindow(window, viewport, modelMatrix, projMatrix);
2126
2127
2128 gsd_colormode(CM_DIFFUSE);
2130 gsd_do_scale(1);
2131 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
2132 zexag = surf->z_exag;
2133
2134 /* adjust window */
2135 window[0] += (int)(yres * 4 * zexag);
2136 window[1] -= (int)(yres * 4 * zexag);
2137 window[2] -= (int)(xres * 4 * zexag);
2138 window[3] += (int)(xres * 4 * zexag);
2139
2140 /* CURRENTLY ALWAYS 1.0 */
2141#ifdef CALC_AREA
2142 sz = GS_global_exag();
2143#endif
2144
2145 /* TODO: get rid of (define) these magic numbers scaling the attribute vals */
2146 check_transp = 0;
2147 tratt = &(surf->att[ATT_TRANSP]);
2148 ktrans = (255 << 24);
2149 trans_src = surf->att[ATT_TRANSP].att_src;
2150
2151 if (CONST_ATT == trans_src && surf->att[ATT_TRANSP].constant != 0.0) {
2152 ktrans = (255 - (int)surf->att[ATT_TRANSP].constant) << 24;
2153 gsd_blend(1);
2154 gsd_zwritemask(0x0);
2155 }
2156 else if (MAP_ATT == trans_src) {
2157 trbuff = gs_get_att_typbuff(surf, ATT_TRANSP, 0);
2158 check_transp = trbuff ? 1 : 0;
2159 gsd_blend(1);
2160 gsd_zwritemask(0x0);
2161 }
2162
2163 check_emis = 0;
2164 ematt = &(surf->att[ATT_EMIT]);
2165 kem = 0.0;
2166 pkem = 1.0;
2167 em_src = surf->att[ATT_EMIT].att_src;
2168
2169 if (CONST_ATT == em_src) {
2170 kem = surf->att[ATT_EMIT].constant / 255.;
2171 }
2172 else if (MAP_ATT == em_src) {
2173 embuff = gs_get_att_typbuff(surf, ATT_EMIT, 0);
2174 check_emis = embuff ? 1 : 0;
2175 }
2176
2177 check_shin = 0;
2178 shatt = &(surf->att[ATT_SHINE]);
2179 ksh = 0.0;
2180 pksh = 1.0;
2181 sh_src = surf->att[ATT_SHINE].att_src;
2182
2183 if (CONST_ATT == sh_src) {
2184 ksh = surf->att[ATT_SHINE].constant / 255.;
2185 gsd_set_material(1, 0, ksh, kem, 0x0);
2186 }
2187 else if (MAP_ATT == sh_src) {
2188 shbuff = gs_get_att_typbuff(surf, ATT_SHINE, 0);
2189 check_shin = shbuff ? 1 : 0;
2190 }
2191
2192 /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
2193 or else use more general and inefficient gets */
2194 check_color = 1;
2195 coloratt = &(surf->att[ATT_COLOR]);
2196 col_src = surf->att[ATT_COLOR].att_src;
2197
2198 if (col_src != MAP_ATT) {
2199 if (col_src == CONST_ATT) {
2200 curcolor = (int)surf->att[ATT_COLOR].constant;
2201 }
2202 else {
2203 curcolor = surf->wire_color;
2204 }
2205
2206 check_color = 0;
2207 }
2208
2209 check_material = (check_shin || check_emis || (kem && check_color));
2210
2211 /* would also be good to check if colormap == surfmap, to increase speed */
2212 /* will also need to set check_transp, check_shine, etc & fix material */
2213 cnt = 0;
2214
2215 for (row = start_val; row < ycnt; row += step_val) {
2216 if (GS_check_cancel()) {
2217 gsd_popmatrix();
2218 gsd_blend(0);
2219 gsd_zwritemask(0xffffffff);
2220
2221 return (-1);
2222 }
2223
2224 /*
2225 if (row == 201 && new_fan == 0) {
2226 xmod *= 2;
2227 ymod *= 2;
2228 xres = xmod * surf->xres;
2229 yres = ymod * surf->yres;
2230 step_val *= 2;
2231 new_fan = 1;
2232 row -= 1;
2233 row /= 2;
2234 }
2235 */
2236 datarow1 = row * ymod;
2237 datarow2 = (row - (step_val / 2)) * ymod;
2238 datarow3 = (row + (step_val / 2)) * ymod;
2239
2240
2241 y1 = ymax - row * yres;
2242 y2 = ymax - (row - (step_val / 2)) * yres;
2243 y3 = ymax - (row + (step_val / 2)) * yres;
2244
2245 y1off = row * ymod * surf->cols;
2246 y2off = (row - (step_val / 2)) * ymod * surf->cols;
2247 y3off = (row + (step_val / 2)) * ymod * surf->cols;
2248
2249
2250 for (col = start_val; col < xcnt; col += step_val) {
2251 datacol1 = col * xmod;
2252 datacol2 = (col - (step_val / 2)) * xmod;
2253 datacol3 = (col + (step_val / 2)) * xmod;
2254
2255 x1 = col * xres;
2256 x2 = (col - (step_val / 2)) * xres;
2257 x3 = (col + (step_val / 2)) * xres;
2258
2259
2260 /* 0 */
2261 /*
2262 if (check_mask) {
2263 if (BM_get(surf->curmask, datacol1, datarow1))
2264 continue;
2265 }
2266 */
2267
2268 cnt1++;
2269
2270 /* Do not need BM_get because GET_MAPATT calls
2271 * same and returns zero if masked
2272 */
2273 offset2[0] = y1off + datacol1; /* fan center */
2274 pt2[0][X] = x1;
2275 pt2[0][Y] = y1; /* fan center */
2276 pt[X] = pt2[0][X];
2277 pt[Y] = pt2[0][Y];
2278 if (!GET_MAPATT(buff, offset2[0], pt[Z]))
2279 continue; /* masked */
2280 else {
2281 pt[Z] *= zexag;
2282 if (gsd_checkpoint
2283 (pt, window, viewport, modelMatrix, projMatrix))
2284 continue;
2285 }
2286
2287
2288 offset2[1] = y2off + datacol2;
2289 offset2[2] = y2off + datacol1;
2290 offset2[3] = y2off + datacol3;
2291 offset2[4] = y1off + datacol3;
2292 offset2[5] = y3off + datacol3;
2293 offset2[6] = y3off + datacol1;
2294 offset2[7] = y3off + datacol2;
2295 offset2[8] = y1off + datacol2;
2296 offset2[9] = y2off + datacol2; /* repeat 1st corner to close */
2297
2298 pt2[1][X] = x2;
2299 pt2[1][Y] = y2;
2300 pt2[2][X] = x1;
2301 pt2[2][Y] = y2;
2302 pt2[3][X] = x3;
2303 pt2[3][Y] = y2;
2304 pt2[4][X] = x3;
2305 pt2[4][Y] = y1;
2306 pt2[5][X] = x3;
2307 pt2[5][Y] = y3;
2308 pt2[6][X] = x1;
2309 pt2[6][Y] = y3;
2310 pt2[7][X] = x2;
2311 pt2[7][Y] = y3;
2312 pt2[8][X] = x2;
2313 pt2[8][Y] = y1;
2314 pt2[9][X] = x2;
2315 pt2[9][Y] = y2; /* repeat 1st corner to close */
2316
2317
2318 /* Run through triangle fan */
2319 gsd_bgntfan();
2320 for (ii = 0; ii < 10; ii++) {
2321
2322 if (ii > 0) {
2323 pt[X] = pt2[ii][X];
2324 pt[Y] = pt2[ii][Y];
2325 if (!GET_MAPATT(buff, offset2[ii], pt[Z]))
2326 continue;
2327 pt[Z] *= zexag;
2328 }
2329
2330 FNORM(surf->norms[offset2[ii]], n);
2331
2332 if (check_color)
2333 curcolor = gs_mapcolor(cobuff, coloratt, offset2[ii]);
2334
2335 if (check_transp) {
2336 GET_MAPATT(trbuff, offset2[ii], ttr);
2337 ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
2338 ktrans = (char)(255 - ktrans) << 24;
2339 }
2340
2341 if (check_material) {
2342 if (check_emis) {
2343 GET_MAPATT(embuff, offset2[ii], kem);
2344 kem = SCALE_ATT(ematt, kem, 0., 1.);
2345 }
2346
2347 if (check_shin) {
2348 GET_MAPATT(shbuff, offset2[ii], ksh);
2349 ksh = SCALE_ATT(shatt, ksh, 0., 1.);
2350 }
2351
2352 if (pksh != ksh || pkem != kem || (kem && check_color)) {
2353 pksh = ksh;
2354 pkem = kem;
2355 gsd_set_material(check_shin, check_emis,
2356 ksh, kem, curcolor);
2357 }
2358 }
2359
2360 gsd_litvert_func(n, ktrans | curcolor, pt);
2361
2362
2363 } /* close ii loop */
2364 gsd_endtfan();
2365 cnt2++;
2366 } /* end col */
2367 } /* end row */
2368
2369
2370 gsd_popmatrix();
2371 gsd_blend(0);
2372 gsd_zwritemask(0xffffffff);
2373
2374 return (0);
2375}
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
int BM_get(struct BM *map, int x, int y)
Gets 'val' from the bitmap.
Definition: bitmap.c:223
#define NULL
Definition: ccmath.h:32
if(!DBFLoadRecord(psDBF, hEntity)) return NULL
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
void GS_get_scale(float *sx, float *sy, float *sz, int doexag)
Get axis scale.
Definition: gs2.c:3240
void GS_set_draw(int where)
Sets which buffer to draw to.
Definition: gs2.c:2462
float GS_global_exag(void)
Get global z-exag value.
Definition: gs2.c:1999
int gs_mapcolor(typbuff *cobuff, gsurf_att *coloratt, int offset)
Call this one when you already know att_src is MAP_ATT.
Definition: gs.c:969
int gs_getall_surfaces(geosurf **gsurfs)
Get array of geosurf structs.
Definition: gs.c:108
typbuff * gs_get_att_typbuff(geosurf *gs, int desc, int to_write)
Get attribute data buffer.
Definition: gs.c:681
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
int gs_calc_normals(geosurf *gs)
Calculate normals.
Definition: gs_norms.c:124
void GS_v3sub(float *v1, float *v2)
Subtract vectors.
Definition: gs_util.c:212
void GS_v3mag(float *v1, float *mag)
Magnitude of vector.
Definition: gs_util.c:421
void GS_v3eq(float *v1, float *v2)
Copy vector values.
Definition: gs_util.c:178
void GS_v3cross(float *v1, float *v2, float *v3)
Get the cross product v3 = v1 cross v2.
Definition: gs_util.c:406
void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2, float *dir, float sz)
Draw 3d north arrow.
Definition: gsd_objs.c:1082
int gsd_arrow(float *center, unsigned long colr, float siz, float *dir, float sz, geosurf *onsurf)
ADD.
Definition: gsd_objs.c:923
void gsd_endtfan(void)
ADD.
Definition: gsd_prim.c:346
void gsd_endtmesh(void)
ADD.
Definition: gsd_prim.c:306
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:510
void gsd_zwritemask(unsigned long n)
Write out z-mask.
Definition: gsd_prim.c:240
void gsd_litvert_func(float *norm, unsigned long col, float *pt)
Set the current normal vector & specify vertex.
Definition: gsd_prim.c:660
void gsd_colormode(int cm)
Set color mode.
Definition: gsd_prim.c:97
void gsd_bgnpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:371
void gsd_blend(int yesno)
Specify pixel arithmetic.
Definition: gsd_prim.c:996
void show_colormode(void)
Print color mode to stderr.
Definition: gsd_prim.c:150
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:500
void gsd_bgntfan(void)
ADD.
Definition: gsd_prim.c:336
int gsd_checkpoint(float pt[4], int window[4], int viewport[4], double modelMatrix[16], double projMatrix[16])
ADD.
Definition: gsd_prim.c:585
void gsd_translate(float dx, float dy, float dz)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:538
void gsd_bgntmesh(void)
ADD.
Definition: gsd_prim.c:296
void gsd_getwindow(int *window, int *viewport, double *modelMatrix, double *projMatrix)
Get viewport.
Definition: gsd_prim.c:553
void gsd_endpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:386
void gsd_set_material(int set_shin, int set_emis, float sh, float em, int emcolor)
Set material.
Definition: gsd_prim.c:806
int gsd_getfc(void)
ADD.
Definition: gsd_surf.c:1220
int gsd_triangulated_wall(int npts1, int npts2, geosurf *surf1, geosurf *surf2, Point3 *points1, Point3 *points2, float *norm)
ADD.
Definition: gsd_surf.c:1111
int gsd_ortho_wall(int np, int ns, geosurf **gsurfs, Point3 **points, float *norm)
ADD.
Definition: gsd_surf.c:1327
void gsd_setfc(int mode)
ADD.
Definition: gsd_surf.c:1208
#define DEBUG_ARROW
Definition: gsd_surf.c:41
int gsd_norm_arrows(geosurf *surf)
ADD.
Definition: gsd_surf.c:1810
int gsd_surf_func(geosurf *gs, int(*user_func)())
Define user function.
Definition: gsd_surf.c:1092
int gsd_surf_const(geosurf *surf, float k)
Using tmesh - not confident with qstrips portability.
Definition: gsd_surf.c:729
int gsd_surf_map(geosurf *surf)
Draw surface using triangle fan instead of strip.
Definition: gsd_surf.c:2062
int gsd_wall(float *bgn, float *end, float *norm)
ADD.
Definition: gsd_surf.c:1715
int gsd_surf(geosurf *surf)
ADD.
Definition: gsd_surf.c:81
#define SET_SCOLOR(sf)
MACROS for use in gsd_ortho_wall ONLY !!!
Definition: gsd_surf.c:46
int gsd_surf_map_old(geosurf *surf)
ADD.
Definition: gsd_surf.c:140
void gsd_do_scale(int doexag)
Set current scale.
Definition: gsd_views.c:355
float gsdiff_do_SD(float val, int offset)
ADD.
Definition: gsdiff.c:94
geosurf * gsdiff_get_SDref(void)
ADD.
Definition: gsdiff.c:77
int segs_intersect(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float *x, float *y)
Line intersect.
Definition: gsdrape.c:1210
Point3 * gsdrape_get_allsegments(geosurf *gs, float *bgn, float *end, int *num)
Get all segments.
Definition: gsdrape.c:401
#define FNORM(i, nv)
Definition: gsget.h:50
#define SCALE_ATT(att, val, low, high)
Definition: gsget.h:22
#define GET_MAPATT(buff, offset, att)
Definition: gsget.h:27
int GS_check_cancel(void)
Check for cancel.
Definition: gsx.c:30
#define VCOLS(gs)
Definition: rowcol.h:14
#define VROWS(gs)
Definition: rowcol.h:13
#define XY2OFF(gs, px, py)
Definition: rowcol.h:24
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: symbol/read.c:220
#define X(j)
#define Y(j)