gsd_surf.c 51 KB

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