GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
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 &&
35 !(col%surf->x_modw)))
36 */
37
38/*
39 #define DO_ARROW
40 */
41
42#define DEBUG_ARROW (0)
43
44/*!
45 \brief MACROS for use in gsd_ortho_wall ONLY !!!
46 */
47#define SET_SCOLOR(sf) \
48 if (check_color[sf]) { \
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/* Notes on exageration:
62 vertical exageration is of two forms:
63 1) global exageration (from geoview struct)
64 2) vertical exageration for each surface (UN-IMPLEMENTED)
65 */
66
67/************************************************************************/
68/* may need to add more parameters to tell it which window or off_screen
69 * pixmap to draw into.
70 */
71
72/*!
73 \brief ADD
74
75 \param surf surface (geosurf)
76
77 \return
78 \return -1 on error
79 */
80int gsd_surf(geosurf *surf)
81{
82 int desc, ret;
83
84 G_debug(5, "gsd_surf(): id=%d", surf->gsurf_id);
85
86 desc = ATT_TOPO;
87
88 /* won't recalculate if update not needed, but may want to check
89 to see if lights are on */
90 gs_calc_normals(surf);
91
92 switch (gs_get_att_src(surf, desc)) {
93 case NOTSET_ATT:
94 ret = (-1);
95
96 break;
97
98 case MAP_ATT:
99 ret = (gsd_surf_map(surf)); /* changed to use test draw routine */
100
101#ifdef DO_ARROW
102 gsd_norm_arrows(surf);
103
104 /* Not ready yet - need to recalc normals for proper res
105 gsd_wire_arrows(surf);
106 */
107#endif
108
109 break;
110
111 case CONST_ATT:
112 ret = (gsd_surf_const(surf, surf->att[desc].constant));
113
114 break;
115
116 case FUNC_ATT:
117 ret = (gsd_surf_func(surf, surf->att[desc].user_func));
118
119 break;
120
121 default:
122 ret = (-1);
123
124 break;
125 }
126
127 return (ret);
128}
129
130/*!
131 \brief ADD
132
133 Using tmesh - not confident with qstrips portability
134
135 \param surf surface (geosurf)
136
137 \return
138 */
139int gsd_surf_map_old(geosurf *surf)
140{
141 int check_mask, check_color, check_transp;
142 int check_material, check_emis, check_shin;
143 typbuff *buff, *cobuff, *trbuff, *embuff, *shbuff;
144 int xmod, ymod, row, col, cnt, xcnt, ycnt;
145 long offset, y1off, y2off;
146 float x1, x2, y1, y2, tx, ty, tz, ttr;
147 float n[3], pt[4], xres, yres, ymax, zexag;
148 int em_src, sh_src, trans_src, col_src, curcolor;
149 gsurf_att *ematt, *shatt, *tratt, *coloratt;
150
151 /* Viewport variables for accelerated drawing */
152 GLdouble modelMatrix[16], projMatrix[16];
153 GLint viewport[4];
154 GLint window[4];
155
156#ifdef CALC_AREA
157 float sz, mag, tedge1[3], tedge2[3], crossp[3], triv[3][3];
158 double asurf = 0.0, axsurf = 0.0;
159#endif
160
161 int zeros, dr1, dr2, dr3, dr4;
162 int datarow1, datacol1, datarow2, datacol2;
163
164 float kem, ksh, pkem, pksh;
165 unsigned int ktrans;
166
167 G_debug(3, "gsd_surf_map_old");
168
169 /* avoid scaling by zero */
170 GS_get_scale(&tx, &ty, &tz, 1);
171
172 if (tz == 0.0) {
173 return (gsd_surf_const(surf, 0.0));
174 }
175 /* else if (surf->z_exag == 0.0)
176 {
177 return(gsd_surf_const(surf, surf->z_min));
178 }
179 NOT YET IMPLEMENTED */
180
181 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
182 cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
183
184 gs_update_curmask(surf);
185 check_mask = surf->curmask ? 1 : 0;
186
187 /*
188 checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
189 combine it/them with any current mask, put in surf->curmask:
190 */
191 xmod = surf->x_mod;
192 ymod = surf->y_mod;
193 xres = xmod * surf->xres;
194 yres = ymod * surf->yres;
195 ymax = (surf->rows - 1) * surf->yres;
196
197 xcnt = VCOLS(surf);
198 ycnt = VROWS(surf);
199
200 /* Get viewport */
201 gsd_getwindow(window, viewport, modelMatrix, projMatrix);
202 /* adjust window */
203 window[0] += (int)(yres * 2);
204 window[1] -= (int)(yres * 2);
205 window[2] -= (int)(xres * 2);
206 window[3] += (int)(xres * 2);
207
208 gsd_colormode(CM_DIFFUSE);
210 gsd_do_scale(1);
211 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
212 zexag = surf->z_exag;
213
214 /* CURRENTLY ALWAYS 1.0 */
215#ifdef CALC_AREA
216 sz = GS_global_exag();
217#endif
218
219 /* TESTING */
220 /*
221 fprintf(stderr, "This machine has %d alpha bits\n",
222 getgdesc(GD_BITS_NORM_DBL_ALPHA)); fprintf(stderr, "GD_BLEND = %d \n",
223 getgdesc(GD_BLEND)); fprintf(stderr, "GD_CLIPPLANES = %d \n",
224 getgdesc(GD_CLIPPLANES));
225 */
226
227 /* TODO: get rid of (define) these magic numbers scaling the attribute vals
228 */
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
457 if (gsd_checkpoint(pt, window, viewport, modelMatrix,
458 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, ksh, kem,
491 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
512 if (gsd_checkpoint(pt, window, viewport, modelMatrix,
513 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, ksh, kem,
546 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
568 if (gsd_checkpoint(pt, window, viewport, modelMatrix,
569 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, ksh, kem,
601 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
637 if (gsd_checkpoint(pt, window, viewport, modelMatrix,
638 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, ksh, kem,
670 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 gsd_colormode(CM_DIFFUSE);
785
786 /* avoid scaling by zero */
787 GS_get_scale(&tx, &ty, &tz, 1);
788
789 if (tz == 0.0) {
790 k = 0.0;
791 gsd_do_scale(0);
792 }
793 else {
794 gsd_do_scale(1);
795 }
796
797 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
798 zexag = surf->z_exag;
799
800 if (CONST_ATT == surf->att[ATT_TRANSP].att_src) {
801 gsd_blend(1);
802 ktrans = 255 - (int)surf->att[ATT_TRANSP].constant;
803 gsd_zwritemask(0x0);
804 }
805
806 ktrans = (ktrans << 24);
807
808 /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
809 or else use more general and inefficient gets */
810
811 check_color = 1;
812 coloratt = &(surf->att[ATT_COLOR]);
813 col_src = surf->att[ATT_COLOR].att_src;
814
815 if (col_src != MAP_ATT) {
816 if (col_src == CONST_ATT) {
817 curcolor = (int)surf->att[ATT_COLOR].constant;
818 }
819 else {
820 curcolor = surf->wire_color;
821 }
822
823 check_color = 0;
824 }
825
826 /* CONSTANTS */
827 pt[Z] = k * zexag;
828 n[X] = n[Y] = 0.0;
829 n[Z] = 1.0;
830
831 /* just draw one polygon if no color mapped */
832 /* fast, but specular reflection will prob. be poor */
833 if (!check_color && !check_mask && !do_diff) {
835
836 pt[X] = pt[Y] = 0;
837 gsd_litvert_func(n, ktrans | curcolor, pt);
838
839 pt[X] = xcnt * xres;
840 gsd_litvert_func(n, ktrans | curcolor, pt);
841
842 pt[Y] = ycnt * yres;
843 gsd_litvert_func(n, ktrans | curcolor, pt);
844
845 pt[X] = 0;
846 gsd_litvert_func(n, ktrans | curcolor, pt);
847
850 gsd_blend(0);
851 gsd_zwritemask(0xffffffff);
852
853 return (0);
854 }
855
856 cnt = 0;
857
858 for (row = 0; row < ycnt; row++) {
859 if (GS_check_cancel()) {
861 gsd_blend(0);
862 gsd_zwritemask(0xffffffff);
863
864 return (-1);
865 }
866
867 datarow1 = row * ymod;
868 datarow2 = (row + 1) * ymod;
869
870 y1 = ymax - row * yres;
871 y2 = ymax - (row + 1) * yres;
872 y1off = row * ymod * surf->cols;
873 y2off = (row + 1) * ymod * surf->cols;
874
875 gsd_bgntmesh();
876
877 zeros = 0;
878 dr1 = dr2 = dr3 = dr4 = 1;
879
880 if (check_mask) {
881 if (BM_get(surf->curmask, 0, datarow1)) {
882 /*TL*/ ++zeros;
883 dr1 = 0;
884 }
885
886 if (BM_get(surf->curmask, 0, datarow2)) {
887 /*BL*/ ++zeros;
888 dr2 = 0;
889 }
890 }
891
892 if (dr1 && dr2) {
893 offset = y1off; /* TL */
894 pt[X] = 0;
895 pt[Y] = y1;
896
897 if (check_color) {
898 curcolor = gs_mapcolor(cobuff, coloratt, offset);
899 }
900
901 if (do_diff) {
902 pt[Z] = gsdiff_do_SD(k * zexag, offset);
903 }
904
905 gsd_litvert_func(n, ktrans | curcolor, pt);
906 cnt++;
907
908 offset = y2off; /* BL */
909 pt[X] = 0;
910 pt[Y] = y2;
911
912 if (check_color) {
913 curcolor = gs_mapcolor(cobuff, coloratt, offset);
914 }
915
916 if (do_diff) {
917 pt[Z] = gsdiff_do_SD(k * zexag, offset);
918 }
919
920 gsd_litvert_func(n, ktrans | curcolor, pt);
921 cnt++;
922 }
923
924 for (col = 0; col < xcnt; col++) {
925 datacol1 = col * xmod;
926 datacol2 = (col + 1) * xmod;
927
928 x1 = col * xres;
929 x2 = (col + 1) * xres;
930
931 zeros = 0;
932 dr1 = dr2 = dr3 = dr4 = 1;
933
934 if (check_mask) {
935 if (BM_get(surf->curmask, datacol1, datarow1)) {
936 /*TL*/ ++zeros;
937 dr1 = 0;
938 }
939
940 if (BM_get(surf->curmask, datacol1, datarow2)) {
941 /*BL*/ ++zeros;
942 dr2 = 0;
943 }
944
945 if (BM_get(surf->curmask, datacol2, datarow2)) {
946 /*BR*/ ++zeros;
947 dr3 = 0;
948 }
949
950 if (BM_get(surf->curmask, datacol2, datarow1)) {
951 /*TR*/ ++zeros;
952 dr4 = 0;
953 }
954
955 if ((zeros > 1) && cnt) {
956 gsd_endtmesh();
957 cnt = 0;
958 gsd_bgntmesh();
959 continue;
960 }
961 }
962
963 if (cnt > 250) {
964 cnt = 0;
965 gsd_endtmesh();
966 gsd_bgntmesh();
967
968 if (dr1) {
969 offset = y1off + datacol1; /* TL */
970 pt[X] = x1;
971 pt[Y] = y1;
972
973 if (gsd_checkpoint(pt, window, viewport, modelMatrix,
974 projMatrix)) {
975 gsd_endtmesh();
976 cnt = 0;
977 gsd_bgntmesh();
978 continue;
979 }
980
981 if (check_color) {
982 curcolor = gs_mapcolor(cobuff, coloratt, offset);
983 }
984
985 if (do_diff) {
986 pt[Z] = gsdiff_do_SD(k * zexag, offset);
987 }
988
989 gsd_litvert_func(n, ktrans | curcolor, pt);
990 cnt++;
991 }
992
993 if (dr2) {
994 offset = y2off + datacol1; /* BL */
995 pt[X] = x1;
996 pt[Y] = y2;
997
998 if (gsd_checkpoint(pt, window, viewport, modelMatrix,
999 projMatrix)) {
1000 gsd_endtmesh();
1001 cnt = 0;
1002 gsd_bgntmesh();
1003 continue;
1004 }
1005
1006 if (check_color) {
1007 curcolor = gs_mapcolor(cobuff, coloratt, offset);
1008 }
1009
1010 if (do_diff) {
1011 pt[Z] = gsdiff_do_SD(k * zexag, offset);
1012 }
1013
1014 gsd_litvert_func(n, ktrans | curcolor, pt);
1015 cnt++;
1016 }
1017 }
1018
1019 if (dr4) {
1020 offset = y1off + datacol2; /* TR */
1021 pt[X] = x2;
1022 pt[Y] = y1;
1023
1024 if (gsd_checkpoint(pt, window, viewport, modelMatrix,
1025 projMatrix)) {
1026 gsd_endtmesh();
1027 cnt = 0;
1028 gsd_bgntmesh();
1029 continue;
1030 }
1031
1032 if (check_color) {
1033 curcolor = gs_mapcolor(cobuff, coloratt, offset);
1034 }
1035
1036 if (do_diff) {
1037 pt[Z] = gsdiff_do_SD(k * zexag, offset);
1038 }
1039
1040 gsd_litvert_func(n, ktrans | curcolor, pt);
1041 cnt++;
1042 }
1043
1044 if (dr3) {
1045 offset = y2off + datacol2; /* BR */
1046 pt[X] = x2;
1047 pt[Y] = y2;
1048
1049 if (gsd_checkpoint(pt, window, viewport, modelMatrix,
1050 projMatrix)) {
1051 gsd_endtmesh();
1052 cnt = 0;
1053 gsd_bgntmesh();
1054 continue;
1055 }
1056
1057 if (check_color) {
1058 curcolor = gs_mapcolor(cobuff, coloratt, offset);
1059 }
1060
1061 if (do_diff) {
1062 pt[Z] = gsdiff_do_SD(k * zexag, offset);
1063 }
1064
1065 gsd_litvert_func(n, ktrans | curcolor, pt);
1066 cnt++;
1067 }
1068 } /* ea col */
1069
1070 gsd_endtmesh();
1071 } /* ea row */
1072
1073 gsd_popmatrix();
1074 gsd_blend(0);
1075 gsd_zwritemask(0xffffffff);
1076
1077 return (0);
1078}
1079
1080/*!
1081 \brief Define user function
1082
1083 Not yet supported
1084
1085 \param gs surface (geosurf) [unused]
1086 \param user_func user function [unused]
1087
1088 \return 1
1089 */
1090int gsd_surf_func(geosurf *gs UNUSED, int (*user_func)(void) UNUSED)
1091{
1092
1093 return (1);
1094}
1095
1096/*!
1097 \brief ADD
1098
1099 \param npts1
1100 \param npts2
1101 \param surf1 first surface (geosurf)
1102 \param surf2 second surface (geosurf)
1103 \param points1
1104 \param points2
1105 \param norm
1106
1107 \return 1
1108 */
1109int gsd_triangulated_wall(int npts1, int npts2, geosurf *surf1, geosurf *surf2,
1110 Point3 *points1, Point3 *points2, float *norm)
1111{
1112 int i, i1, i2, nlong, offset, col_src;
1113 int check_color1, check_color2, color1, color2;
1114 typbuff *cobuf1, *cobuf2;
1115 gsurf_att *coloratt1, *coloratt2;
1116
1117 check_color1 = check_color2 = 1;
1118
1119 col_src = surf1->att[ATT_COLOR].att_src;
1120
1121 if (col_src != MAP_ATT) {
1122 if (col_src == CONST_ATT) {
1123 color1 = (int)surf1->att[ATT_COLOR].constant;
1124 }
1125 else {
1126 color1 = surf1->wire_color;
1127 }
1128
1129 check_color1 = 0;
1130 }
1131
1132 coloratt1 = &(surf1->att[ATT_COLOR]);
1133 cobuf1 = gs_get_att_typbuff(surf1, ATT_COLOR, 0);
1134
1135 col_src = surf2->att[ATT_COLOR].att_src;
1136 if (col_src != MAP_ATT) {
1137 if (col_src == CONST_ATT) {
1138 color2 = (int)surf2->att[ATT_COLOR].constant;
1139 }
1140 else {
1141 color2 = surf2->wire_color;
1142 }
1143
1144 check_color2 = 0;
1145 }
1146
1147 coloratt2 = &(surf2->att[ATT_COLOR]);
1148 cobuf2 = gs_get_att_typbuff(surf2, ATT_COLOR, 0);
1149
1150 gsd_colormode(CM_DIFFUSE);
1152 gsd_do_scale(1);
1153
1154 gsd_bgntmesh();
1155
1156 for (nlong = (npts1 > npts2 ? npts1 : npts2), i = 0; i < nlong; i++) {
1157 i1 = i * npts1 / nlong;
1158 i2 = i * npts2 / nlong;
1159 offset = XY2OFF(surf1, points1[i1][X], points1[i1][Y]);
1160
1161 if (check_color1) {
1162 color1 = gs_mapcolor(cobuf1, coloratt1, offset);
1163 }
1164
1165 offset = XY2OFF(surf1, points2[i2][X], points2[i2][Y]);
1166
1167 if (check_color2) {
1168 color2 = gs_mapcolor(cobuf2, coloratt2, offset);
1169 }
1170
1171 /* start with long line to ensure triangle */
1172 if (npts1 > npts2) {
1173 points1[i1][X] += surf1->x_trans;
1174 points1[i1][Y] += surf1->y_trans;
1175 points1[i1][Z] += surf1->z_trans;
1176 gsd_litvert_func(norm, color1, points1[i1]);
1177 points2[i2][X] += surf2->x_trans;
1178 points2[i2][Y] += surf2->y_trans;
1179 points2[i2][Z] += surf2->z_trans;
1180 gsd_litvert_func(norm, color2, points2[i2]);
1181 }
1182 else {
1183 points2[i2][X] += surf2->x_trans;
1184 points2[i2][Y] += surf2->y_trans;
1185 points2[i2][Z] += surf2->z_trans;
1186 gsd_litvert_func(norm, color2, points2[i2]);
1187 points1[i1][X] += surf1->x_trans;
1188 points1[i1][Y] += surf1->y_trans;
1189 points1[i1][Z] += surf1->z_trans;
1190 gsd_litvert_func(norm, color1, points1[i1]);
1191 }
1192 }
1193
1194 gsd_endtmesh();
1195 gsd_popmatrix();
1196
1197 return (1);
1198}
1199
1200/*!
1201 \brief ADD
1202
1203 \param mode
1204 */
1205void gsd_setfc(int mode)
1206{
1207 FCmode = mode;
1208
1209 return;
1210}
1211
1212/*!
1213 \brief ADD
1214
1215 \return
1216 */
1217int gsd_getfc(void)
1218{
1219 return (FCmode);
1220}
1221
1222/*!
1223 \brief ADD
1224
1225 \param surf surface (geosurf)
1226 \param point
1227
1228 \return
1229 */
1230static int transpoint_is_masked(geosurf *surf, Point3 point)
1231{
1232 Point3 tp;
1233
1234 tp[X] = point[X] - surf->x_trans;
1235 tp[Y] = point[Y] - surf->y_trans;
1236
1237 return (gs_point_is_masked(surf, tp));
1238}
1239
1240/*!
1241 \brief ADD
1242
1243 \param points
1244 \param gsurf
1245 \param ptn
1246 \param cursurf
1247 \param numsurfs
1248 \param belowsurf
1249
1250 \return 0 if there is no surface below the current,
1251 \return -1 if the current surface is masked,
1252 \return 1 if the surface below the current surface is not masked
1253 (belowsurf is assigned)
1254 */
1255static int get_point_below(Point3 **points, geosurf **gsurfs, int ptn,
1256 int cursurf, int numsurfs, int *belowsurf)
1257{
1258 int n, found = -1;
1259 float nearz = 0.0, diff;
1260
1261 if (gsurfs[cursurf]->curmask) {
1262 if (transpoint_is_masked(gsurfs[cursurf], points[cursurf][ptn])) {
1263 return (-1);
1264 }
1265 }
1266
1267 for (n = 0; n < numsurfs; ++n) {
1268 diff = points[cursurf][ptn][Z] - points[n][ptn][Z];
1269
1270 if (diff > 0) {
1271 if (!nearz || diff < nearz) {
1272 if (gsurfs[n]->curmask) {
1273 if (transpoint_is_masked(gsurfs[n], points[n][ptn])) {
1274 continue;
1275 }
1276 }
1277
1278 nearz = diff;
1279 found = n;
1280 }
1281 }
1282 /* else if (diff == 0.0 && n != cursurf)
1283 {
1284 if (gsurfs[n]->curmask)
1285 {
1286 if (transpoint_is_masked(gsurfs[n], points[n][ptn]))
1287 {
1288 continue;
1289 }
1290 }
1291
1292 nearz=diff;
1293 found = n;
1294 break;
1295 }
1296 */
1297 }
1298
1299 if (found != -1) {
1300 *belowsurf = found;
1301
1302 return (1);
1303 }
1304
1305 return (0);
1306}
1307
1308/*
1309 #define CPDEBUG
1310 */
1311
1312/*!
1313 \brief ADD
1314
1315 \param np
1316 \param ns
1317 \param gsurfs
1318 \param points
1319 \param norm
1320
1321 \return
1322 */
1323int gsd_ortho_wall(int np, int ns, geosurf **gsurfs, Point3 **points,
1324 float *norm)
1325{
1326 int n, i, offset, col_src, check_color[MAX_SURFS];
1327 int color, colors[MAX_SURFS], nocolor;
1328 typbuff *cobuf[MAX_SURFS];
1329 gsurf_att *coloratt[MAX_SURFS];
1330
1331 nocolor = FCmode == FC_GREY ? 1 : 0;
1332
1333 if (!nocolor) {
1334 for (n = 0; n < ns; ++n) {
1335 check_color[n] = 1;
1336
1337 col_src = gsurfs[n]->att[ATT_COLOR].att_src;
1338
1339 if (col_src != MAP_ATT) {
1340 if (col_src == CONST_ATT) {
1341 colors[n] = (int)gsurfs[n]->att[ATT_COLOR].constant;
1342 }
1343 else {
1344 colors[n] = gsurfs[n]->wire_color;
1345 }
1346
1347 check_color[n] = 0;
1348 }
1349
1350 coloratt[n] = &(gsurfs[n]->att[ATT_COLOR]);
1351 cobuf[n] = gs_get_att_typbuff(gsurfs[n], ATT_COLOR, 0);
1352 }
1353 }
1354
1355#ifdef CPDEBUG
1356 {
1357 GS_set_draw(GSD_BOTH);
1358 }
1359#endif
1360
1361 /* changed from CM_DIFFUSE - July 25, 2005
1362 * should display proper color for cut planes
1363 */
1364 gsd_colormode(CM_COLOR);
1365
1366 /* actually ought to write a GS_set_fencetransp() */
1367 if (nocolor) {
1368 color = 0x80808080;
1369 gsd_blend(1);
1370 gsd_zwritemask(0x0);
1371 }
1372
1374 gsd_do_scale(1);
1375
1376 /* using segs_intersect here with segments projected to
1377 the 2d clipping plane */
1378 {
1379 float tx, ty;
1380 int bn, bnl, ctop, cbot, ctopl, cbotl, bsret;
1381 Point3 xing;
1382
1383 if (nocolor) {
1384 ctop = cbot = ctopl = cbotl = color;
1385 }
1386
1387 for (n = 0; n < ns; ++n) {
1388 for (i = 0; i < np; i++) {
1389 if (0 <
1390 (bsret = get_point_below(points, gsurfs, i, n, ns, &bn))) {
1391 gsd_bgntmesh();
1392
1393 if (!nocolor) {
1394 SET_SCOLOR(n);
1395 SET_SCOLOR(bn);
1396
1397 if (FCmode == FC_ABOVE) {
1398 ctop = cbot = colors[n];
1399 }
1400 else if (FCmode == FC_BELOW) {
1401 ctop = cbot = colors[bn];
1402 }
1403 else {
1404 cbot = colors[bn];
1405 ctop = colors[n];
1406 }
1407 }
1408
1409 if (i) {
1410 /* need to find crossing? */
1411 if (!transpoint_is_masked(gsurfs[n],
1412 points[n][i - 1]) &&
1413 !transpoint_is_masked(gsurfs[bn],
1414 points[bn][i - 1])) {
1415 if (1 == segs_intersect(0.0, points[n][i - 1][Z],
1416 1.0, points[n][i][Z], 0.0,
1417 points[bn][i - 1][Z], 1.0,
1418 points[bn][i][Z], &tx,
1419 &ty)) {
1420 xing[Z] = ty;
1421 xing[Y] = points[n][i - 1][Y] +
1422 tx * (points[n][i][Y] -
1423 points[n][i - 1][Y]);
1424 xing[X] = points[n][i - 1][X] +
1425 tx * (points[n][i][X] -
1426 points[n][i - 1][X]);
1427 gsd_litvert_func(norm, ctop, xing);
1428 xing[Z] = points[bn][i - 1][Z] +
1429 tx * (points[bn][i][Z] -
1430 points[bn][i - 1][Z]);
1431 gsd_litvert_func(norm, cbot, xing);
1432 }
1433 }
1434 }
1435
1436 gsd_litvert_func(norm, ctop, points[n][i]);
1437 gsd_litvert_func(norm, cbot, points[bn][i]);
1438 i++;
1439
1440 bnl = -1;
1441
1442 while (i < np && 0 < (bsret = get_point_below(
1443 points, gsurfs, i, n, ns, &bn))) {
1444#ifdef CPDEBUG
1445 {
1446 int lower = 0;
1447
1448 if (GS_check_cancel()) {
1449 break;
1450 }
1451 }
1452#endif
1453
1454 if (!nocolor) {
1455 ctopl = ctop;
1456 cbotl = cbot;
1457 SET_SCOLOR(n);
1458 SET_SCOLOR(bn);
1459
1460 if (FCmode == FC_ABOVE) {
1461 ctop = cbot = colors[n];
1462 }
1463 else if (FCmode == FC_BELOW) {
1464 ctop = cbot = colors[bn];
1465 }
1466 else {
1467 cbot = colors[bn];
1468 ctop = colors[n];
1469 }
1470 }
1471
1472 /*
1473 IF UPPER crossing :
1474 (crossing is between current & new lower surf)
1475 IF XING going DOWN:
1476 - plot crossing point (color previous upper)
1477 - endtmesh/bgntmesh
1478 - plot crossing point (color current upper)
1479 - plot "equivalent" point below (color current lower)
1480 IF XING going UP:
1481 - plot crossing point (color previous upper)
1482 - plot "equivalent" point below (color previous
1483 lower)
1484 - endtmesh/bgntmesh
1485 - plot crossing point (color current upper)
1486 ELSE IF LOWER crossing:
1487 (crossing between new & previous lower surfs):
1488 - plot "equivalent" point above (color previous
1489 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(
1508 0.0, points[n][i - 1][Z], 1.0,
1509 points[n][i][Z], 0.0,
1510 points[bn][i - 1][Z], 1.0,
1511 points[bn][i][Z], &tx, &ty)) {
1512 /* crossing going up */
1513
1514 G_debug(
1515 5,
1516 "crossing going up at surf %d no. %d",
1517 n, i);
1518
1519 upper = 1;
1520 xing[Z] = ty;
1521 xing[Y] = points[n][i - 1][Y] +
1522 tx * (points[n][i][Y] -
1523 points[n][i - 1][Y]);
1524 xing[X] = points[n][i - 1][X] +
1525 tx * (points[n][i][X] -
1526 points[n][i - 1][X]);
1527 gsd_litvert_func(norm, ctopl, xing);
1528 z1 = xing[Z];
1529 xing[Z] = points[bnl][i - 1][Z] +
1530 tx * (points[bnl][i][Z] -
1531 points[bnl][i - 1][Z]);
1532 gsd_litvert_func(norm, cbotl, xing);
1533 xing[Z] = z1;
1534 gsd_endtmesh();
1535 gsd_bgntmesh();
1536 gsd_litvert_func(norm, ctop, xing);
1537 }
1538 else if (1 == segs_intersect(
1539 0.0, points[n][i - 1][Z], 1.0,
1540 points[n][i][Z], 0.0,
1541 points[bnl][i - 1][Z], 1.0,
1542 points[bnl][i][Z], &tx,
1543 &ty)) {
1544 /* crossing going down */
1545
1546 G_debug(
1547 5,
1548 "crossing going down at surf %d no. %d",
1549 n, i);
1550
1551 upper = 1;
1552 xing[Z] = ty;
1553 xing[Y] = points[n][i - 1][Y] +
1554 tx * (points[n][i][Y] -
1555 points[n][i - 1][Y]);
1556 xing[X] = points[n][i - 1][X] +
1557 tx * (points[n][i][X] -
1558 points[n][i - 1][X]);
1559 gsd_litvert_func(norm, ctopl, xing);
1560 z1 = xing[Z];
1561 xing[Z] = points[bnl][i - 1][Z] +
1562 tx * (points[bnl][i][Z] -
1563 points[bnl][i - 1][Z]);
1564 gsd_litvert_func(norm, cbotl, xing);
1565 xing[Z] = z1;
1566 gsd_endtmesh();
1567 gsd_bgntmesh();
1568 gsd_litvert_func(norm, ctop, xing);
1569 xing[Z] = points[bn][i - 1][Z] +
1570 tx * (points[bn][i][Z] -
1571 points[bn][i - 1][Z]);
1572 gsd_litvert_func(norm, cbot, xing);
1573 }
1574 }
1575
1576 if (!upper &&
1577 !transpoint_is_masked(gsurfs[bn],
1578 points[bn][i - 1]) &&
1579 !transpoint_is_masked(gsurfs[bnl],
1580 points[bnl][i - 1])) {
1581
1582 if (1 == segs_intersect(
1583 0.0, points[bn][i - 1][Z], 1.0,
1584 points[bn][i][Z], 0.0,
1585 points[bnl][i - 1][Z], 1.0,
1586 points[bnl][i][Z], &tx, &ty)) {
1587#ifdef CPDEBUG
1588 {
1589 lower = 1;
1590 }
1591#endif
1592 G_debug(5,
1593 "lower crossing at surf %d no. %d "
1594 "between surfs %d & %d",
1595 n, i, bn, bnl);
1596
1597 xing[Z] = ty;
1598 xing[Y] = points[bn][i - 1][Y] +
1599 tx * (points[bn][i][Y] -
1600 points[bn][i - 1][Y]);
1601 xing[X] = points[bn][i - 1][X] +
1602 tx * (points[bn][i][X] -
1603 points[bn][i - 1][X]);
1604 z2 = xing[Z];
1605 z1 = xing[Z] = points[n][i - 1][Z] +
1606 tx * (points[n][i][Z] -
1607 points[n][i - 1][Z]);
1608 gsd_litvert_func(norm, ctopl, xing);
1609 xing[Z] = z2;
1610 gsd_litvert_func(norm, cbotl, xing);
1611 gsd_endtmesh();
1612 gsd_bgntmesh();
1613 xing[Z] = z1;
1614 gsd_litvert_func(norm, ctop, xing);
1615 xing[Z] = z2;
1616 gsd_litvert_func(norm, cbot, xing);
1617 }
1618 }
1619
1620#ifdef CPDEBUG
1621 {
1622 if (!upper && !lower) {
1623 G_debug(5, "Crossing NOT found or masked:");
1624 G_debug(5,
1625 " current surf: %d [ %.2f %.2f "
1626 "%.2f -> %.2f %.2f %f",
1627 n, points[n][i - 1][X],
1628 points[n][i - 1][Y],
1629 points[n][i - 1][Z],
1630 points[n][i][X], points[n][i][Y],
1631 points[n][i][Z]);
1632 G_debug(5,
1633 " below surf: %d [ %.2f %.2f %.2f "
1634 "-> %.2f %.2f %f\n",
1635 bn, points[bn][i - 1][X],
1636 points[bn][i - 1][Y],
1637 points[bn][i - 1][Z],
1638 points[bn][i][X], points[bn][i][Y],
1639 points[bn][i][Z]);
1640 G_debug(5,
1641 gs " last below surf: %d [ %.2f "
1642 "%.2f %.2f -> %.2f %.2f %f\n",
1643 bnl, points[bnl][i - 1][X],
1644 points[bnl][i - 1][Y],
1645 points[bnl][i - 1][Z],
1646 points[bnl][i][X],
1647 points[bnl][i][Y],
1648 points[bnl][i][Z]);
1649 }
1650 }
1651#endif
1652 }
1653
1654 gsd_litvert_func(norm, ctop, points[n][i]);
1655 gsd_litvert_func(norm, cbot, points[bn][i]);
1656 bnl = bn;
1657 i++;
1658 }
1659
1660 if (i < np) {
1661 /* need to find crossing? */
1662 if (!transpoint_is_masked(gsurfs[n],
1663 points[n][i - 1]) &&
1664 !transpoint_is_masked(gsurfs[bn],
1665 points[bn][i - 1])) {
1666 if (1 == segs_intersect(0.0, points[n][i - 1][Z],
1667 1.0, points[n][i][Z], 0.0,
1668 points[bn][i - 1][Z], 1.0,
1669 points[bn][i][Z], &tx,
1670 &ty)) {
1671 xing[Z] = ty;
1672 xing[Y] = points[n][i - 1][Y] +
1673 tx * (points[n][i][Y] -
1674 points[n][i - 1][Y]);
1675 xing[X] = points[n][i - 1][X] +
1676 tx * (points[n][i][X] -
1677 points[n][i - 1][X]);
1678 gsd_litvert_func(norm, ctop, xing);
1679 }
1680
1681 i--;
1682 }
1683 }
1684
1685 gsd_endtmesh();
1686 }
1687 }
1688 }
1689 }
1690
1691 gsd_colormode(CM_DIFFUSE); /* set colormode back to DIFFUSE */
1692 gsd_popmatrix();
1693 gsd_blend(0);
1694 gsd_zwritemask(0xffffffff);
1695
1696 return (1);
1697}
1698
1699/*!
1700 \brief ADD
1701
1702 bgn,end should already be in world modeling coords, but have to
1703 be reverse-translated to apply to each surface
1704
1705 \param bgn,end 2d line for cutting plane
1706 \param norm indicates which way wall faces
1707
1708 \return
1709 */
1710int gsd_wall(float *bgn, float *end, float *norm)
1711{
1712 geosurf *gsurfs[MAX_SURFS];
1713 Point3 *points[MAX_SURFS], *tmp;
1714 int nsurfs, ret, npts, npts1, n, i, err = 0;
1715 float bgn1[2], end1[2];
1716
1717 if (norm[Z] > 0.0001 || norm[Z] < -.0001) {
1718 return (0); /* can't do tilted wall yet */
1719 }
1720
1721 if (FCmode == FC_OFF) {
1722 return (0);
1723 }
1724
1725 nsurfs = gs_getall_surfaces(gsurfs);
1726
1727 for (n = 0; n < nsurfs; n++) {
1728 /* get drape points for surf */
1729 bgn1[X] = bgn[X] - gsurfs[n]->x_trans;
1730 bgn1[Y] = bgn[Y] - gsurfs[n]->y_trans;
1731 end1[X] = end[X] - gsurfs[n]->x_trans;
1732 end1[Y] = end[Y] - gsurfs[n]->y_trans;
1733 tmp = gsdrape_get_allsegments(gsurfs[n], bgn1, end1, &npts1);
1734
1735 if (n) {
1736 if (npts != npts1) {
1737 G_warning(_("Cut-plane points mis-match between surfaces. "
1738 "Check resolution(s)."));
1739 err = 1;
1740 nsurfs = n;
1741
1742 break;
1743 }
1744 }
1745
1746 npts = npts1;
1747
1748 if (n == nsurfs - 1) {
1749 /* last surf - don't need to copy */
1750 points[n] = tmp;
1751
1752 for (i = 0; i < npts1; i++) {
1753 /* DOING translation here! */
1754 points[n][i][X] += gsurfs[n]->x_trans;
1755 points[n][i][Y] += gsurfs[n]->y_trans;
1756 points[n][i][Z] += gsurfs[n]->z_trans;
1757 }
1758
1759 break;
1760 }
1761
1762 /* allocate space in points and copy tmp to points */
1763 points[n] =
1764 (Point3 *)G_calloc(npts1, sizeof(Point3)); /* G_fatal_error */
1765
1766 for (i = 0; i < npts1; i++) {
1767 GS_v3eq(points[n][i], tmp[i]);
1768
1769 /* DOING translation here! */
1770 points[n][i][X] += gsurfs[n]->x_trans;
1771 points[n][i][Y] += gsurfs[n]->y_trans;
1772 points[n][i][Z] += gsurfs[n]->z_trans;
1773 }
1774 } /* done for */
1775
1776 if (err) {
1777 for (n = 0; n < nsurfs; n++) {
1778 if (points[n]) {
1779 G_free(points[n]);
1780 }
1781 }
1782 return (0);
1783 }
1784
1785 ret = gsd_ortho_wall(npts, nsurfs, gsurfs, points, norm);
1786
1787 for (n = 0; n < nsurfs - 1; n++) {
1788 /* don't free last - it's constant */
1789 G_free(points[n]);
1790 }
1791
1792 return (ret);
1793}
1794
1795/*!
1796 \brief ADD
1797
1798 Need to do Zexag scale of normal for arrow direction, drawing
1799 routine unexags z for arrow
1800
1801 \param surf surface (geosurf)
1802
1803 \return
1804 */
1805int gsd_norm_arrows(geosurf *surf)
1806{
1807 typbuff *buff;
1808 int check_mask;
1809 int xmod, ymod, row, col, cnt, xcnt, ycnt;
1810 long offset, y1off, y2off;
1811 float /* x1, */ x2, y1, y2, tx, ty, tz, sz;
1812 float n[3], pt[4], xres, yres, ymax, zexag;
1813
1814#ifdef DO_ARROW_SOLID
1815 int col_src;
1816 typbuff *cobuff;
1817 gsurf_att *coloratt;
1818 int curcolor;
1819 int check_color = 1;
1820#endif
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#ifdef DO_ARROW_SOLID
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 check_color = 0;
1854 }
1855
1856 cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
1857#endif
1858
1859 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
1860
1861 xmod = surf->x_mod;
1862 ymod = surf->y_mod;
1863 xres = xmod * surf->xres;
1864 yres = ymod * surf->yres;
1865 ymax = (surf->rows - 1) * surf->yres;
1866
1867 xcnt = VCOLS(surf);
1868 ycnt = VROWS(surf);
1869
1871 gsd_do_scale(1);
1872 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
1873
1874 zexag = surf->z_exag;
1875 /* CURRENTLY ALWAYS 1.0 */
1876
1877#ifdef DO_ARROW_SOLID
1878 gsd_colormode(CM_DIFFUSE);
1879#else
1880 gsd_colormode(CM_COLOR);
1881#endif
1882
1883 cnt = 0;
1884
1885 for (row = 0; row < ycnt; row++) {
1886 if (GS_check_cancel()) {
1887 gsd_popmatrix();
1888
1889 return (-1);
1890 }
1891
1892 datarow1 = row * ymod;
1893 datarow2 = (row + 1) * ymod;
1894
1895 y1 = ymax - row * yres;
1896 y2 = ymax - (row + 1) * yres;
1897 y1off = row * ymod * surf->cols;
1898 y2off = (row + 1) * ymod * surf->cols;
1899
1900 zeros = 0;
1901 dr1 = dr2 = dr3 = dr4 = 1;
1902
1903 if (check_mask) {
1904 if (BM_get(surf->curmask, 0, datarow1)) {
1905 /*TL*/ ++zeros;
1906 dr1 = 0;
1907 }
1908
1909 if (BM_get(surf->curmask, 0, datarow2)) {
1910 /*BL*/ ++zeros;
1911 dr2 = 0;
1912 }
1913 }
1914
1915 if (dr1 && dr2) {
1916 offset = y1off; /* TL */
1917 FNORM(surf->norms[offset], n);
1918 pt[X] = 0;
1919 pt[Y] = y2;
1920 GET_MAPATT(buff, offset, pt[Z]);
1921 pt[Z] *= zexag;
1922
1923#ifdef DO_ARROW_SOLID
1924 if (check_color) {
1925 curcolor = gs_mapcolor(cobuff, coloratt, offset);
1926 }
1927
1928 gsd_3darrow(pt, curcolor, xres * 2, xres / 2, n, sz);
1929#else
1930 if (DEBUG_ARROW) {
1931 gsd_arrow(pt, 0x000000, xres * 2, n, sz, surf);
1932 }
1933#endif
1934
1935 cnt++;
1936
1937 offset = y2off; /* BL */
1938 FNORM(surf->norms[offset], n);
1939 pt[X] = 0;
1940 pt[Y] = y2;
1941 GET_MAPATT(buff, offset, pt[Z]);
1942 pt[Z] *= zexag;
1943
1944#ifdef DO_ARROW_SOLID
1945 if (check_color) {
1946 curcolor = gs_mapcolor(cobuff, coloratt, offset);
1947 }
1948
1949 gsd_3darrow(pt, curcolor, xres * 2, xres / 2, n, sz);
1950#else
1951 if (DEBUG_ARROW) {
1952 gsd_arrow(pt, 0x000000, xres * 2, n, sz, surf);
1953 }
1954#endif
1955
1956 cnt++;
1957 }
1958
1959 for (col = 0; col < xcnt; col++) {
1960 datacol1 = col * xmod;
1961 datacol2 = (col + 1) * xmod;
1962
1963 /* x1 = col * xres; */
1964 x2 = (col + 1) * xres;
1965
1966 zeros = 0;
1967 dr1 = dr2 = dr3 = dr4 = 1;
1968
1969 if (check_mask) {
1970 if (BM_get(surf->curmask, datacol1, datarow1)) {
1971 /*TL*/ ++zeros;
1972 dr1 = 0;
1973 }
1974
1975 if (BM_get(surf->curmask, datacol1, datarow2)) {
1976 /*BL*/ ++zeros;
1977 dr2 = 0;
1978 }
1979
1980 if (BM_get(surf->curmask, datacol2, datarow2)) {
1981 /*BR*/ ++zeros;
1982 dr3 = 0;
1983 }
1984
1985 if (BM_get(surf->curmask, datacol2, datarow1)) {
1986 /*TR*/ ++zeros;
1987 dr4 = 0;
1988 }
1989
1990 if ((zeros > 1) && cnt) {
1991 cnt = 0;
1992 continue;
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#ifdef DO_ARROW_SOLID
2005 if (check_color) {
2006 curcolor = gs_mapcolor(cobuff, coloratt, offset);
2007 }
2008
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#ifdef DO_ARROW_SOLID
2028 if (check_color) {
2029 curcolor = gs_mapcolor(cobuff, coloratt, offset);
2030 }
2031
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 \brief Draw surface using triangle fan instead of strip
2050
2051 Optimized by getting rid of BM_get mask check - GET_MAPPATT does same
2052 and returns zero if masked
2053
2054 Only do in window check on Fan center(v0) to further optimize -- this runs
2055 the risk of trimming points in view !!
2056
2057 \param surf surface (geosurf)
2058
2059 \return
2060 */
2061int gsd_surf_map(geosurf *surf)
2062{
2063 int /* check_mask, */ check_color, check_transp;
2064 int check_material, check_emis, check_shin;
2065 typbuff *buff, *cobuff, *trbuff, *embuff, *shbuff;
2066 int xmod, ymod;
2067 int row, col, xcnt, ycnt;
2068 long y1off, y2off, y3off;
2069 long offset2[10];
2070 float pt2[10][2];
2071 int ii;
2072 float x1, x2, x3, y1, y2, y3, tx, ty, tz, ttr;
2073 float n[3], pt[4], xres, yres, ymax, zexag;
2074 int em_src, sh_src, trans_src, col_src, curcolor;
2075 gsurf_att *ematt, *shatt, *tratt, *coloratt;
2076
2077 /* Viewport variables for accelerated drawing */
2078 GLdouble modelMatrix[16], projMatrix[16];
2079 GLint viewport[4];
2080 GLint window[4];
2081
2082 int datacol1, datacol2, datacol3;
2083
2084 /* int datarow1, datarow2, datarow3; */
2085
2086 float kem, ksh, pkem, pksh;
2087 unsigned int ktrans;
2088
2089 int step_val = 2; /* should always be factor of 2 for fan */
2090 int start_val = 1; /* one half of step_val */
2091
2092 /* avoid scaling by zero */
2093 GS_get_scale(&tx, &ty, &tz, 1);
2094
2095 if (tz == 0.0) {
2096 return (gsd_surf_const(surf, 0.0));
2097 }
2098 /* else if (surf->z_exag == 0.0)
2099 {
2100 return(gsd_surf_const(surf, surf->z_min));
2101 }
2102 NOT YET IMPLEMENTED */
2103
2104 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
2105 cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
2106
2107 gs_update_curmask(surf);
2108 /* check_mask = surf->curmask ? 1 : 0; */
2109
2110 /*
2111 checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
2112 combine it/them with any current mask, put in surf->curmask:
2113 */
2114 xmod = surf->x_mod;
2115 ymod = surf->y_mod;
2116 xres = xmod * surf->xres;
2117 yres = ymod * surf->yres;
2118 ymax = (surf->rows - 1) * surf->yres;
2119
2120 xcnt = VCOLS(surf);
2121 ycnt = VROWS(surf);
2122
2123 /* Get viewport */
2124 gsd_getwindow(window, viewport, modelMatrix, projMatrix);
2125
2126 gsd_colormode(CM_DIFFUSE);
2128 gsd_do_scale(1);
2129 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
2130 zexag = surf->z_exag;
2131
2132 /* adjust window */
2133 window[0] += (int)(yres * 4 * zexag);
2134 window[1] -= (int)(yres * 4 * zexag);
2135 window[2] -= (int)(xres * 4 * zexag);
2136 window[3] += (int)(xres * 4 * zexag);
2137
2138 /* CURRENTLY ALWAYS 1.0 */
2139#ifdef CALC_AREA
2140 sz = GS_global_exag();
2141#endif
2142
2143 /* TODO: get rid of (define) these magic numbers scaling the attribute vals
2144 */
2145 check_transp = 0;
2146 tratt = &(surf->att[ATT_TRANSP]);
2147 ktrans = (255 << 24);
2148 trans_src = surf->att[ATT_TRANSP].att_src;
2149
2150 if (CONST_ATT == trans_src && surf->att[ATT_TRANSP].constant != 0.0) {
2151 ktrans = (255 - (int)surf->att[ATT_TRANSP].constant) << 24;
2152 gsd_blend(1);
2153 gsd_zwritemask(0x0);
2154 }
2155 else if (MAP_ATT == trans_src) {
2156 trbuff = gs_get_att_typbuff(surf, ATT_TRANSP, 0);
2157 check_transp = trbuff ? 1 : 0;
2158 gsd_blend(1);
2159 gsd_zwritemask(0x0);
2160 }
2161
2162 check_emis = 0;
2163 ematt = &(surf->att[ATT_EMIT]);
2164 kem = 0.0;
2165 pkem = 1.0;
2166 em_src = surf->att[ATT_EMIT].att_src;
2167
2168 if (CONST_ATT == em_src) {
2169 kem = surf->att[ATT_EMIT].constant / 255.;
2170 }
2171 else if (MAP_ATT == em_src) {
2172 embuff = gs_get_att_typbuff(surf, ATT_EMIT, 0);
2173 check_emis = embuff ? 1 : 0;
2174 }
2175
2176 check_shin = 0;
2177 shatt = &(surf->att[ATT_SHINE]);
2178 ksh = 0.0;
2179 pksh = 1.0;
2180 sh_src = surf->att[ATT_SHINE].att_src;
2181
2182 if (CONST_ATT == sh_src) {
2183 ksh = surf->att[ATT_SHINE].constant / 255.;
2184 gsd_set_material(1, 0, ksh, kem, 0x0);
2185 }
2186 else if (MAP_ATT == sh_src) {
2187 shbuff = gs_get_att_typbuff(surf, ATT_SHINE, 0);
2188 check_shin = shbuff ? 1 : 0;
2189 }
2190
2191 /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
2192 or else use more general and inefficient gets */
2193 check_color = 1;
2194 coloratt = &(surf->att[ATT_COLOR]);
2195 col_src = surf->att[ATT_COLOR].att_src;
2196
2197 if (col_src != MAP_ATT) {
2198 if (col_src == CONST_ATT) {
2199 curcolor = (int)surf->att[ATT_COLOR].constant;
2200 }
2201 else {
2202 curcolor = surf->wire_color;
2203 }
2204
2205 check_color = 0;
2206 }
2207
2208 check_material = (check_shin || check_emis || (kem && check_color));
2209
2210 /* would also be good to check if colormap == surfmap, to increase speed */
2211 /* will also need to set check_transp, check_shine, etc & fix material */
2212
2213 for (row = start_val; row < ycnt; row += step_val) {
2214 if (GS_check_cancel()) {
2215 gsd_popmatrix();
2216 gsd_blend(0);
2217 gsd_zwritemask(0xffffffff);
2218
2219 return (-1);
2220 }
2221
2222 /*
2223 if (row == 201 && new_fan == 0) {
2224 xmod *= 2;
2225 ymod *= 2;
2226 xres = xmod * surf->xres;
2227 yres = ymod * surf->yres;
2228 step_val *= 2;
2229 new_fan = 1;
2230 row -= 1;
2231 row /= 2;
2232 }
2233 */
2234 /*
2235 datarow1 = row * ymod;
2236 datarow2 = (row - (step_val / 2)) * ymod;
2237 datarow3 = (row + (step_val / 2)) * ymod;
2238 */
2239
2240 y1 = ymax - row * yres;
2241 y2 = ymax - (row - (step_val / 2)) * yres;
2242 y3 = ymax - (row + (step_val / 2)) * yres;
2243
2244 y1off = row * ymod * surf->cols;
2245 y2off = (row - (step_val / 2)) * ymod * surf->cols;
2246 y3off = (row + (step_val / 2)) * ymod * surf->cols;
2247
2248 for (col = start_val; col < xcnt; col += step_val) {
2249 datacol1 = col * xmod;
2250 datacol2 = (col - (step_val / 2)) * xmod;
2251 datacol3 = (col + (step_val / 2)) * xmod;
2252
2253 x1 = col * xres;
2254 x2 = (col - (step_val / 2)) * xres;
2255 x3 = (col + (step_val / 2)) * xres;
2256
2257 /* 0 */
2258 /*
2259 if (check_mask) {
2260 if (BM_get(surf->curmask, datacol1, datarow1))
2261 continue;
2262 }
2263 */
2264
2265 /* Do not need BM_get because GET_MAPATT calls
2266 * same and returns zero if masked
2267 */
2268 offset2[0] = y1off + datacol1; /* fan center */
2269 pt2[0][X] = x1;
2270 pt2[0][Y] = y1; /* fan center */
2271 pt[X] = pt2[0][X];
2272 pt[Y] = pt2[0][Y];
2273 if (!GET_MAPATT(buff, offset2[0], pt[Z]))
2274 continue; /* masked */
2275 else {
2276 pt[Z] *= zexag;
2277 if (gsd_checkpoint(pt, window, viewport, modelMatrix,
2278 projMatrix))
2279 continue;
2280 }
2281
2282 offset2[1] = y2off + datacol2;
2283 offset2[2] = y2off + datacol1;
2284 offset2[3] = y2off + datacol3;
2285 offset2[4] = y1off + datacol3;
2286 offset2[5] = y3off + datacol3;
2287 offset2[6] = y3off + datacol1;
2288 offset2[7] = y3off + datacol2;
2289 offset2[8] = y1off + datacol2;
2290 offset2[9] = y2off + datacol2; /* repeat 1st corner to close */
2291
2292 pt2[1][X] = x2;
2293 pt2[1][Y] = y2;
2294 pt2[2][X] = x1;
2295 pt2[2][Y] = y2;
2296 pt2[3][X] = x3;
2297 pt2[3][Y] = y2;
2298 pt2[4][X] = x3;
2299 pt2[4][Y] = y1;
2300 pt2[5][X] = x3;
2301 pt2[5][Y] = y3;
2302 pt2[6][X] = x1;
2303 pt2[6][Y] = y3;
2304 pt2[7][X] = x2;
2305 pt2[7][Y] = y3;
2306 pt2[8][X] = x2;
2307 pt2[8][Y] = y1;
2308 pt2[9][X] = x2;
2309 pt2[9][Y] = y2; /* repeat 1st corner to close */
2310
2311 /* Run through triangle fan */
2312 gsd_bgntfan();
2313 for (ii = 0; ii < 10; ii++) {
2314
2315 if (ii > 0) {
2316 pt[X] = pt2[ii][X];
2317 pt[Y] = pt2[ii][Y];
2318 if (!GET_MAPATT(buff, offset2[ii], pt[Z]))
2319 continue;
2320 pt[Z] *= zexag;
2321 }
2322
2323 FNORM(surf->norms[offset2[ii]], n);
2324
2325 if (check_color)
2326 curcolor = gs_mapcolor(cobuff, coloratt, offset2[ii]);
2327
2328 if (check_transp) {
2329 GET_MAPATT(trbuff, offset2[ii], ttr);
2330 ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
2331 ktrans = (char)(255 - ktrans) << 24;
2332 }
2333
2334 if (check_material) {
2335 if (check_emis) {
2336 GET_MAPATT(embuff, offset2[ii], kem);
2337 kem = SCALE_ATT(ematt, kem, 0., 1.);
2338 }
2339
2340 if (check_shin) {
2341 GET_MAPATT(shbuff, offset2[ii], ksh);
2342 ksh = SCALE_ATT(shatt, ksh, 0., 1.);
2343 }
2344
2345 if (pksh != ksh || pkem != kem || (kem && check_color)) {
2346 pksh = ksh;
2347 pkem = kem;
2348 gsd_set_material(check_shin, check_emis, ksh, kem,
2349 curcolor);
2350 }
2351 }
2352
2353 gsd_litvert_func(n, ktrans | curcolor, pt);
2354
2355 } /* close ii loop */
2356 gsd_endtfan();
2357 } /* end col */
2358 } /* end row */
2359
2360 gsd_popmatrix();
2361 gsd_blend(0);
2362 gsd_zwritemask(0xffffffff);
2363
2364 return (0);
2365}
void G_free(void *buf)
Free allocated memory.
Definition alloc.c:150
int BM_get(struct BM *map, int x, int y)
Gets 'val' from the bitmap.
Definition bitmap.c:217
#define NULL
Definition ccmath.h:32
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition gis/error.c:203
void GS_get_scale(float *sx, float *sy, float *sz, int doexag)
Get axis scale.
Definition gs2.c:3236
void GS_set_draw(int where)
Sets which buffer to draw to.
Definition gs2.c:2459
float GS_global_exag(void)
Get global z-exag value.
Definition gs2.c:1997
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:968
int gs_getall_surfaces(geosurf **gsurfs)
Get array of geosurf structs.
Definition gs.c:109
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:1314
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:231
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:418
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:403
void gsd_3darrow(float *center, unsigned long colr, float siz1, float siz2, float *dir, float sz)
Draw 3d north arrow.
Definition gsd_objs.c:1057
int gsd_arrow(float *center, unsigned long colr, float siz, float *dir, float sz, geosurf *onsurf)
ADD.
Definition gsd_objs.c:898
void gsd_endtfan(void)
ADD.
Definition gsd_prim.c:347
void gsd_endtmesh(void)
ADD.
Definition gsd_prim.c:307
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition gsd_prim.c:511
void gsd_zwritemask(unsigned long n)
Write out z-mask.
Definition gsd_prim.c:241
void gsd_litvert_func(float *norm, unsigned long col, float *pt)
Set the current normal vector & specify vertex.
Definition gsd_prim.c:657
void gsd_colormode(int cm)
Set color mode.
Definition gsd_prim.c:98
void gsd_bgnpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition gsd_prim.c:372
void gsd_blend(int yesno)
Specify pixel arithmetic.
Definition gsd_prim.c:994
void show_colormode(void)
Print color mode to stderr.
Definition gsd_prim.c:151
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition gsd_prim.c:501
void gsd_bgntfan(void)
ADD.
Definition gsd_prim.c:337
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:539
void gsd_bgntmesh(void)
ADD.
Definition gsd_prim.c:297
void gsd_getwindow(int *window, int *viewport, double *modelMatrix, double *projMatrix)
Get viewport.
Definition gsd_prim.c:554
void gsd_endpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition gsd_prim.c:387
void gsd_set_material(int set_shin, int set_emis, float sh, float em, int emcolor)
Set material.
Definition gsd_prim.c:803
int gsd_getfc(void)
ADD.
Definition gsd_surf.c:1217
int gsd_triangulated_wall(int npts1, int npts2, geosurf *surf1, geosurf *surf2, Point3 *points1, Point3 *points2, float *norm)
ADD.
Definition gsd_surf.c:1109
int gsd_ortho_wall(int np, int ns, geosurf **gsurfs, Point3 **points, float *norm)
ADD.
Definition gsd_surf.c:1323
void gsd_setfc(int mode)
ADD.
Definition gsd_surf.c:1205
int gsd_surf_func(geosurf *gs UNUSED, int(*user_func)(void) UNUSED)
Define user function.
Definition gsd_surf.c:1090
#define DEBUG_ARROW
Definition gsd_surf.c:42
int gsd_norm_arrows(geosurf *surf)
ADD.
Definition gsd_surf.c:1805
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:2061
int gsd_wall(float *bgn, float *end, float *norm)
ADD.
Definition gsd_surf.c:1710
int gsd_surf(geosurf *surf)
ADD.
Definition gsd_surf.c:80
#define SET_SCOLOR(sf)
MACROS for use in gsd_ortho_wall ONLY !!!
Definition gsd_surf.c:47
int gsd_surf_map_old(geosurf *surf)
ADD.
Definition gsd_surf.c:139
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:1202
Point3 * gsdrape_get_allsegments(geosurf *gs, float *bgn, float *end, int *num)
Get all segments.
Definition gsdrape.c:399
#define FNORM(i, nv)
Definition gsget.h:51
#define SCALE_ATT(att, val, low, high)
Definition gsget.h:24
#define GET_MAPATT(buff, offset, att)
Definition gsget.h:29
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)
#define X(j)
#define Y(j)