GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-835afb4352
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 
55 static int transpoint_is_masked(geosurf *, Point3);
56 static int get_point_below(Point3 **, geosurf **, int, int, int, int *);
57 
58 static 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  */
80 int 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  */
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 
209  gsd_pushmatrix();
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()) {
300  gsd_popmatrix();
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 
702  gsd_popmatrix();
703  gsd_blend(0);
704  gsd_zwritemask(0xffffffff);
705 
706  show_colormode();
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  */
729 int 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 
784  gsd_pushmatrix();
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) {
834  gsd_bgnpolygon();
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 
848  gsd_endpolygon();
849  gsd_popmatrix();
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()) {
860  gsd_popmatrix();
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  */
1090 int 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  */
1109 int 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 
1151  gsd_pushmatrix();
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  */
1205 void gsd_setfc(int mode)
1206 {
1207  FCmode = mode;
1208 
1209  return;
1210 }
1211 
1212 /*!
1213  \brief ADD
1214 
1215  \return
1216  */
1217 int 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  */
1230 static 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  */
1255 static 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  */
1323 int 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  {
1358  }
1359 #endif
1360 
1361  /* changed from CM_DIFFUSE - July 25, 2005
1362  * should display proper color for cut planes
1363  */
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 
1373  gsd_pushmatrix();
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  */
1710 int 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  */
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 
1870  gsd_pushmatrix();
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
1879 #else
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  */
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 
2127  gsd_pushmatrix();
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 }
#define NULL
Definition: ccmath.h:32
int BM_get(struct BM *, int, int)
Gets 'val' from the bitmap.
Definition: bitmap.c:217
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
#define G_calloc(m, n)
Definition: defs/gis.h:95
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
int gs_point_is_masked(geosurf *, float *)
Check if point is masked.
Definition: gs.c:1314
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 GS_set_draw(int)
Sets which buffer to draw to.
Definition: gs2.c:2459
void gsd_getwindow(int *, int *, double *, double *)
Get viewport.
Definition: gsd_prim.c:554
int gs_getall_surfaces(geosurf **)
Get array of geosurf structs.
Definition: gs.c:109
void gsd_do_scale(int)
Set current scale.
Definition: gsd_views.c:355
void GS_v3sub(float *, float *)
Subtract vectors.
Definition: gs_util.c:212
void GS_v3mag(float *, float *)
Magnitude of vector.
Definition: gs_util.c:418
int gs_get_att_src(geosurf *, int)
Get attribute source.
Definition: gs.c:656
void gsd_bgnpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:372
int gs_calc_normals(geosurf *)
Calculate normals.
Definition: gs_norms.c:124
int segs_intersect(float, float, float, float, float, float, float, float, float *, float *)
Line intersect.
Definition: gsdrape.c:1202
int gsd_checkpoint(float[4], int[4], int[4], double[16], double[16])
ADD.
Definition: gsd_prim.c:585
void GS_v3eq(float *, float *)
Copy vector values.
Definition: gs_util.c:178
int gs_mapcolor(typbuff *, gsurf_att *, int)
Call this one when you already know att_src is MAP_ATT.
Definition: gs.c:968
int gs_update_curmask(geosurf *)
Update current maps.
Definition: gs_bm.c:231
void show_colormode(void)
Print color mode to stderr.
Definition: gsd_prim.c:151
void gsd_translate(float, float, float)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:539
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:501
void GS_v3cross(float *, float *, float *)
Get the cross product v3 = v1 cross v2.
Definition: gs_util.c:403
void gsd_zwritemask(unsigned long)
Write out z-mask.
Definition: gsd_prim.c:241
Point3 * gsdrape_get_allsegments(geosurf *, float *, float *, int *)
Get all segments.
Definition: gsdrape.c:399
void gsd_colormode(int)
Set color mode.
Definition: gsd_prim.c:98
geosurf * gsdiff_get_SDref(void)
ADD.
Definition: gsdiff.c:77
void GS_get_scale(float *, float *, float *, int)
Get axis scale.
Definition: gs2.c:3236
void gsd_bgntfan(void)
ADD.
Definition: gsd_prim.c:337
void gsd_set_material(int, int, float, float, int)
Set material.
Definition: gsd_prim.c:803
typbuff * gs_get_att_typbuff(geosurf *, int, int)
Get attribute data buffer.
Definition: gs.c:681
void gsd_3darrow(float *, unsigned long, float, float, float *, float)
Draw 3d north arrow.
Definition: gsd_objs.c:1057
float gsdiff_do_SD(float, int)
ADD.
Definition: gsdiff.c:94
void gsd_blend(int)
Specify pixel arithmetic.
Definition: gsd_prim.c:994
void gsd_bgntmesh(void)
ADD.
Definition: gsd_prim.c:297
int GS_check_cancel(void)
Check for cancel.
Definition: gsx.c:30
int gsd_arrow(float *, unsigned long, float, float *, float, geosurf *)
ADD.
Definition: gsd_objs.c:898
void gsd_endpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:387
void gsd_litvert_func(float *, unsigned long, float *)
Set the current normal vector & specify vertex.
Definition: gsd_prim.c:657
float GS_global_exag(void)
Get global z-exag value.
Definition: gs2.c:1997
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition: gis.h:47
#define _(str)
Definition: glocale.h:10
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
#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
#define NOTSET_ATT
Definition: ogsf.h:84
#define CM_DIFFUSE
Definition: ogsf.h:151
#define X
Definition: ogsf.h:140
#define ATT_TOPO
Definition: ogsf.h:75
#define ATT_COLOR
Definition: ogsf.h:76
float Point3[3]
Definition: ogsf.h:205
#define ATT_EMIT
Definition: ogsf.h:80
#define Z
Definition: ogsf.h:142
#define GSD_BOTH
Definition: ogsf.h:106
#define FC_GREY
Definition: ogsf.h:113
#define ATT_SHINE
Definition: ogsf.h:79
#define Y
Definition: ogsf.h:141
#define MAP_ATT
Definition: ogsf.h:85
#define CM_COLOR
Definition: ogsf.h:148
#define MAX_SURFS
Definition: ogsf.h:40
#define FC_OFF
Definition: ogsf.h:109
#define FUNC_ATT
Definition: ogsf.h:87
#define FC_BELOW
Definition: ogsf.h:111
#define FC_ABOVE
Definition: ogsf.h:110
#define CONST_ATT
Definition: ogsf.h:86
#define ATT_TRANSP
Definition: ogsf.h:78
#define VCOLS(gs)
Definition: rowcol.h:14
#define VROWS(gs)
Definition: rowcol.h:13
#define XY2OFF(gs, px, py)
Definition: rowcol.h:24
if(!(yy_init))
Definition: sqlp.yy.c:775
Definition: ogsf.h:256
float x_trans
Definition: ogsf.h:266
int rows
Definition: ogsf.h:258
double yres
Definition: ogsf.h:264
int cols
Definition: ogsf.h:258
long wire_color
Definition: ogsf.h:262
gsurf_att att[MAX_ATTS]
Definition: ogsf.h:259
unsigned long * norms
Definition: ogsf.h:273
int gsurf_id
Definition: ogsf.h:257
int y_mod
Definition: ogsf.h:270
double xres
Definition: ogsf.h:264
struct BM * curmask
Definition: ogsf.h:274
int x_mod
Definition: ogsf.h:270
float z_exag
Definition: ogsf.h:265
float z_trans
Definition: ogsf.h:266
float y_trans
Definition: ogsf.h:266
float constant
Definition: ogsf.h:250
IFLAG att_src
Definition: ogsf.h:246
int(* user_func)(void)
Definition: ogsf.h:249
Definition: ogsf.h:208
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
Definition: symbol/read.c:216