1/***********************************************************************/ 2/* Open Visualization Data Explorer */ 3/* (C) Copyright IBM Corp. 1989,1999 */ 4/* ALL RIGHTS RESERVED */ 5/* This code licensed under the */ 6/* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ 7/***********************************************************************/ 8 9 10INCLUDE3 <dxconfig.h> 11 12INCLUDE1 "triangles.h" 13INCLUDE2 "triangles.h" 14 15INCLUDE3 <string.h> 16INCLUDE3 <dx/dx.h> 17INCLUDE3 "render.h" 18INCLUDE3 "internals.h" 19 20DEFINE3 CAT(a,b) a##b 21 22 23#define QUADS(pstr, pptr, shrgb, sho, col, face, TEST, PIXEL, LABEL) { $\ 24 $\ 25 Point *p; $\ 26 int v1, v2, v3, i, width, height; $\ 27 int i1, i2, i3; $\ 28 float ox, oy; $\ 29 InvalidComponentHandle iElts; $\ 30 RGBColor vcolors[8]; $\ 31 int shademe; $\ 32 char fcst = xf->fcst, bcst = xf->bcst, ncst = xf->ncst; $\ 33 $\ 34 iElts = (invalid_status == INV_UNKNOWN) ? xf->iElts : NULL; $\ 35 $\ 36 width = buf->width, height = buf->height; $\ 37 ox = buf->ox, oy = buf->oy; $\ 38 $\ 39 if (shrgb && xf->lights) { $\ 40 fcolors = (Pointer)vcolors; $\ 41 bcolors = (Pointer)(vcolors+4); $\ 42 _dxfInitApplyLights(xf->kaf, xf->kdf, xf->ksf, xf->kspf, $\ 43 xf->kab, xf->kdb, xf->ksb, xf->kspb, $\ 44 xf->fcolors, xf->bcolors, xf->cmap, $\ 45 xf->normals, xf->lights, $\ 46 xf->colors_dep, xf->normals_dep, $\ 47 fcolors, bcolors, 4, fcst, bcst, ncst, $\ 48 fbyte, bbyte); $\ 49 cmap = NULL; $\ 50 shademe = 1; $\ 51 } else { $\ 52 shademe = 0; $\ 53 if (fbyte || bbyte) $\ 54 _dxf_initUbyteToFloat(); $\ 55 } $\ 56 $\ 57 for (i=0; i<nquad; i++, quad++) { $\ 58 int index = (indices == NULL) ? i : indices[i]; $\ 59 $\ 60 if (iElts && DXIsElementInvalid(iElts, index)) $\ 61 continue; $\ 62 $\ 63 /* points */ $\ 64 v1=quad->p, p= &xf->positions[v1], x1=p->x, y1=p->y, z1=p->z; $\ 65 v2=quad->r, p= &xf->positions[v2], x2=p->x, y2=p->y, z2=p->z; $\ 66 v3=quad->s, p= &xf->positions[v3], x3=p->x, y3=p->y, z3=p->z; $\ 67 $\ 68 if (shademe) $\ 69 { $\ 70 i1 = 0; i2 = 2; i3 = 3; $\ 71 if (! _dxfApplyLights((int *)quad, &index, 1)) $\ 72 return ERROR; $\ 73 } $\ 74 $\ 75 if (xf->tile.perspective) { $\ 76 if (z1>nearPlane || z2>nearPlane || z3>nearPlane) $\ 77 goto CAT(LABEL,1); $\ 78 z1=(float)-1.0/z1; x1*=z1; y1*=z1; $\ 79 z2=(float)-1.0/z2; x2*=z2; y2*=z2; $\ 80 z3=(float)-1.0/z3; x3*=z3; y3*=z3; $\ 81 } $\ 82 if (!((x1<minx && x2<minx && x3<minx) || $\ 83 (x1>maxx && x2>maxx && x3>maxx) || $\ 84 (y1<miny && y2<miny && y3<miny) || $\ 85 (y1>maxy && y2>maxy && y3>maxy))) $\ 86 { $\ 87 $\ 88 buf->triangles++; $\ 89 TRIANGLEX1(pstr, pptr, shrgb, sho, col, face, TEST, PIXEL, LABEL, 1) $\ 90 TRIANGLEX2(pstr, pptr, shrgb, sho, col, face, TEST, PIXEL, LABEL, 1);$\ 91 } $\ 92 $\ 93 CAT(LABEL,1) : $\ 94 /* points */ $\ 95 v1=quad->p, p= &xf->positions[v1], x1=p->x, y1=p->y, z1=p->z; $\ 96 v2=quad->s, p= &xf->positions[v2], x2=p->x, y2=p->y, z2=p->z; $\ 97 v3=quad->q, p= &xf->positions[v3], x3=p->x, y3=p->y, z3=p->z; $\ 98 $\ 99 if (shademe) i1 = 0, i2 = 3, i3 = 1; $\ 100 $\ 101 if (xf->tile.perspective) { $\ 102 if (z1>nearPlane || z2>nearPlane || z3>nearPlane) $\ 103 continue; $\ 104 z1=(float)-1.0/z1; x1*=z1; y1*=z1; $\ 105 z2=(float)-1.0/z2; x2*=z2; y2*=z2; $\ 106 z3=(float)-1.0/z3; x3*=z3; y3*=z3; $\ 107 } $\ 108 if ((x1<minx && x2<minx && x3<minx) || $\ 109 (x1>maxx && x2>maxx && x3>maxx) || $\ 110 (y1<miny && y2<miny && y3<miny) || $\ 111 (y1>maxy && y2>maxy && y3>maxy)) $\ 112 continue; $\ 113 $\ 114 buf->triangles++; $\ 115 TRIANGLEX1(pstr, pptr, shrgb, sho, col, face, TEST, PIXEL, LABEL, 2) $\ 116 TRIANGLEX2(pstr, pptr, shrgb, sho, col, face, TEST, PIXEL, LABEL, 2);$\ 117 $\ 118 CAT(LABEL,2) : $\ 119 continue; $\ 120 } $\ 121} 122 123/* 124 * Quads 125 * 126 * p q 127 * r s 128 */ 129 130#define TRI_QR_1 v1=quad[i].p, v2=quad[i].r, v3=quad[i].q 131#define TRI_QR_2 v1=quad[i].q, v2=quad[i].r, v3=quad[i].s 132 133#define TRI_PS_1 v1=quad[i].p, v2=quad[i].r, v3=quad[i].s 134#define TRI_PS_2 v1=quad[i].q, v2=quad[i].p, v3=quad[i].s 135 136 137#define DIFF(i1, i2) ( $\ 138 c1 = cmap? &cmap[((unsigned char *)colors)[i1]] $\ 139 : &((RGBColor *)colors)[i1], $\ 140 c2 = cmap? &cmap[((unsigned char *)colors)[i2]] $\ 141 : &((RGBColor *)colors)[i2], $\ 142 dr = c1->r - c2->r, $\ 143 dg = c1->g - c2->g, $\ 144 db = c1->b - c2->b, $\ 145 dr*dr + dg*dg + db*db $\ 146) 147 148#define QUAD_VOLUME(pstr, pptr, shrgb, sho, col, face, TEST, PIXEL, LABEL){ $\ 149 $\ 150 Point *p; $\ 151 int v1, v2, v3, width, height, valid; $\ 152 float ox, oy; $\ 153 InvalidComponentHandle iElts; $\ 154 RGBColor *colors; $\ 155 /*int cstcolors;*/ $\ 156 $\ 157 if (xf->fcolors) { $\ 158 colors = xf->fcolors /*, cstcolors = xf->fcst */; $\ 159 } else { $\ 160 colors = xf->bcolors /*, cstcolors = xf->bcst */; $\ 161 } $\ 162 $\ 163 if (! colors) $\ 164 DXErrorReturn(ERROR_MISSING_DATA, "no colors in field"); $\ 165 $\ 166 /* for volume quads, we determine validity here $\ 167 */ $\ 168 switch(invalid_status) { $\ 169 case INV_VALID: iElts = NULL; valid = 1; break; $\ 170 case INV_INVALID: iElts = NULL; valid = 0; break; $\ 171 case INV_UNKNOWN: iElts = xf->iElts; break; $\ 172 } $\ 173 $\ 174 width = buf->width, height = buf->height; $\ 175 ox = buf->ox, oy = buf->oy; $\ 176 $\ 177 for (i=0; i<nquad; i++, quad++) { $\ 178 int index = (indices == NULL) ? i : indices[i]; $\ 179 $\ 180 if (iElts) $\ 181 valid = DXIsElementValid(iElts, index); $\ 182 $\ 183 TRI_PS_1; $\ 184 $\ 185 /* points */ $\ 186 p = &xf->positions[v1], x1=p->x, y1=p->y, z1=p->z; $\ 187 p = &xf->positions[v2], x2=p->x, y2=p->y, z2=p->z; $\ 188 p = &xf->positions[v3], x3=p->x, y3=p->y, z3=p->z; $\ 189 $\ 190 if (!((x1<minx && x2<minx && x3<minx) || $\ 191 (x1>maxx && x2>maxx && x3>maxx) || $\ 192 (y1<miny && y2<miny && y3<miny) || $\ 193 (y1>maxy && y2>maxy && y3>maxy))) $\ 194 { $\ 195 buf->triangles++; $\ 196 TRIANGLEV1(pstr, pptr, shrgb, sho, col, face, TEST, PIXEL, LABEL, 1) $\ 197 TRIANGLEV2(pstr, pptr, shrgb, sho, col, face, TEST, PIXEL, LABEL, 1);$\ 198 } $\ 199 $\ 200 CAT(LABEL,1) : $\ 201 TRI_PS_2; $\ 202 $\ 203 /* points */ $\ 204 p = &xf->positions[v1], x1=p->x, y1=p->y, z1=p->z; $\ 205 p = &xf->positions[v2], x2=p->x, y2=p->y, z2=p->z; $\ 206 p = &xf->positions[v3], x3=p->x, y3=p->y, z3=p->z; $\ 207 $\ 208 if ((x1<minx && x2<minx && x3<minx) || $\ 209 (x1>maxx && x2>maxx && x3>maxx) || $\ 210 (y1<miny && y2<miny && y3<miny) || $\ 211 (y1>maxy && y2>maxy && y3>maxy)) $\ 212 continue; $\ 213 $\ 214 buf->triangles++; $\ 215 TRIANGLEV1(pstr, pptr, shrgb, sho, col, face, TEST, PIXEL, LABEL, 2);$\ 216 TRIANGLEV2(pstr, pptr, shrgb, sho, col, face, TEST, PIXEL, LABEL, 2);$\ 217 CAT(LABEL,2) : $\ 218 continue; $\ 219 } $\ 220} 221 222#define QUADDCL $\ 223 RGBColor *c1, *c2, *c3; $\ 224 float x1, y1, x2, y2, x3, y3; $\ 225 float r1, g1, b1, o1, z1, r2, g2, b2, o2, z2, r3, g3, b3, o3, z3; $\ 226 float Qx, dxo, dxz, dxr, dxg, dxb; $\ 227 float Qy, dyr, dyg, dyb, dyo, dyz, dyA, dyB; $\ 228 float r, g, b, o, obar, z, nearPlane=xf->nearPlane ; $\ 229 float A, B, d, d1, d2, d3; $\ 230 int iy1, iy2, iy3; $\ 231 int iA, iB, iy, i, n, nn, left, right; $\ 232 float minx = buf->min.x, miny = buf->min.y; $\ 233 float maxx = buf->max.x, maxy = buf->max.y 234 235 236 237/* 238 * The following are the templates for the quad rendering routines 239 */ 240 241#define QUADPROLOGUE(name) $\ 242 static Error $\ 243 name( $\ 244 struct buffer *buf, $\ 245 struct xfield *xf, $\ 246 int nquad, $\ 247 Quadrilateral *quad, $\ 248 int *indices, $\ 249 int surface, $\ 250 int clip_status, $\ 251 inv_stat invalid_status $\ 252 ) { $\ 253 QUADDCL; $\ 254 Pointer fcolors = xf->fcolors; $\ 255 Pointer bcolors = xf->bcolors; $\ 256 Pointer opacities = xf->opacities; $\ 257 RGBColor *cmap = xf->cmap; $\ 258 float *omap = xf->omap; $\ 259 char fbyte = xf->fbyte, bbyte = xf->bbyte; $\ 260 261#define QUADEPILOGUE $\ 262 return OK; $\ 263 } 264 265 266 267QUADPROLOGUE(quad_vol) 268 float cmul = xf->tile.color_multiplier; 269 float omul = xf->tile.opacity_multiplier / cmul; 270 if (xf->tile.perspective) 271 DXErrorReturn(ERROR_BAD_PARAMETER, 272 "perspective volume rendering is not supported"); 273 if (!buf->merged) 274 _dxf_MergeBackIntoZ(buf); 275 if (opacities) { 276 QUAD_VOLUME(struct big, u.big, SHRGB, SHO, COL, 0, 1, VOLUME, qvo); 277 } else { 278 QUAD_VOLUME(struct big, u.big, SHRGB,NOSHO, COL, 0, 1, VOLUME, qvno); 279 } 280QUADEPILOGUE 281 282 283QUADPROLOGUE(quad_translucent) 284 if (xf->colors_dep == dep_connections) 285 { 286 if (clip_status) { 287 QUADS(struct big,u.big,SHRGB,NOSHO,COL, 288 0,TRANSCLIPZ,TRANSLUCENT, qtcdc); 289 } else if (buf->pix_type==pix_fast) { 290 QUADS(struct fast,u.fast,SHRGB,NOSHO,COL, 291 0,NOCLIPZ,TRANSLUCENT, qtfdc); 292 } else if (buf->pix_type==pix_big) { 293 QUADS(struct big,u.big,SHRGB,NOSHO,COL, 294 0,NOCLIPZ,TRANSLUCENT, qtbdc); 295 } else { 296 DXSetError(ERROR_INTERNAL, "unknown pix_type %d", buf->pix_type); 297 return ERROR; 298 } 299 } 300 else 301 { 302 if (clip_status) { 303 QUADS(struct big,u.big,SHRGB,SHO,COL, 304 0,TRANSCLIPZ,TRANSLUCENT,qtcdp); 305 } else if (buf->pix_type==pix_fast) { 306 QUADS(struct fast,u.fast,SHRGB,SHO,COL, 307 0,NOCLIPZ,TRANSLUCENT,qtfdp); 308 } else if (buf->pix_type==pix_big) { 309 QUADS(struct big,u.big,SHRGB,SHO,COL, 310 0,NOCLIPZ,TRANSLUCENT,qtbdp); 311 } else { 312 DXSetError(ERROR_INTERNAL, "unknown pix_type %d", buf->pix_type); 313 return ERROR; 314 } 315 } 316QUADEPILOGUE 317 318 319QUADPROLOGUE(quad_opaque) 320 if (clip_status) { 321 QUADS(struct big,u.big,SHRGB,NOSHO,COL,0,CLIPZ,OPAQUE,qoc); 322 } else if (buf->pix_type==pix_fast) { 323 QUADS(struct fast,u.fast,SHRGB,NOSHO,COL,0,NOCLIPZ,OPAQUE,qof); 324 } else if (buf->pix_type==pix_big) { 325 QUADS(struct big,u.big,SHRGB,NOSHO,COL,0,NOCLIPZ,OPAQUE,qob); 326 } else { 327 DXSetError(ERROR_INTERNAL, "unknown pix_type %d", buf->pix_type); 328 return ERROR; 329 } 330QUADEPILOGUE 331 332Error 333_dxf_QuadClipping( 334 struct buffer *buf, 335 struct xfield *xf, 336 int nquad, 337 Quadrilateral *quad, 338 int *indices) 339{ 340 QUADDCL; 341 Pointer fcolors = NULL; /* UNCOL guarantees not ref'ed */ 342 Pointer bcolors = NULL; /* UNCOL guarantees not ref'ed */ 343 Pointer opacities = NULL; 344 RGBColor *cmap = NULL; 345 float *omap = NULL; 346 inv_stat invalid_status = INV_VALID; 347 char fbyte = xf->fbyte, bbyte = xf->bbyte; 348 349 if (xf->tile.perspective) { 350 struct xfield xx; 351 for (i=0; i<nquad; ) { 352 i = _dxf_zclip_quads(xf, (int *)quad, i, indices, nquad, &xx, INV_VALID); 353 if (xx.nconnections) 354 _dxf_TriangleClipping(buf, &xx, xx.nconnections, 355 xx.c.triangles, xx.indices); 356 } 357 } 358 359 QUADS(struct big,u.big,NOSHRGB,NOSHO,UNCOL,0,1,CLIPPINGPIXEL, qc); 360 return OK; 361} 362 363static Error 364_dxf_QuadComposite( 365 struct buffer *buf, 366 struct xfield *xf, 367 int nquad, 368 Quadrilateral *quad, 369 int *indices, 370 int clip_status, 371 inv_stat invalid_status 372) { 373 QUADDCL; 374 Pointer fcolors = xf->fcolors; 375 Pointer bcolors = xf->bcolors; 376 Pointer opacities = xf->opacities; 377 RGBColor *cmap = xf->cmap; 378 float *omap = xf->omap; 379 char fbyte = xf->fbyte, bbyte = xf->bbyte; 380 381 if (xf->tile.perspective) 382 DXErrorReturn(ERROR_BAD_PARAMETER, 383 "perspective volume rendering is not supported"); 384 385 if (clip_status) { 386 QUADS(struct big,u.big,SHRGB,SHO,COL,0,TRANSCLIPZ,COMPOSITE,qcc); 387 } else if (buf->pix_type==pix_fast) { 388 QUADS(struct fast,u.fast,SHRGB,SHO,COL,0,NOCLIPZ,COMPOSITE,qcf); 389 } else if (buf->pix_type==pix_big) { 390 QUADS(struct big,u.big,SHRGB,SHO,COL,0,NOCLIPZ,COMPOSITE,qcb); 391 } else { 392 DXSetError(ERROR_INTERNAL, "unknown pix_type %d", buf->pix_type); 393 return ERROR; 394 } 395 396 return OK; 397} 398 399Error 400_dxf_Quad(struct buffer *buf, 401 struct xfield *xf, 402 int nquad, 403 Quadrilateral *quad, 404 int *indices, 405 int surface, 406 int clip_status, 407 inv_stat invalid_status) 408{ 409 int i; 410 411 if (xf->tile.perspective) { 412 struct xfield xx; 413 for (i=0; i<nquad; ) { 414 i = _dxf_zclip_quads(xf, (int *)quad, i, indices, nquad, &xx, invalid_status); 415 if (xx.nconnections) 416 _dxf_Triangle(buf, &xx, xx.nconnections, xx.c.triangles, 417 xx.indices, surface, clip_status, INV_VALID); 418 } 419 } 420 421 if (xf->volume) 422 return quad_vol(buf, xf, nquad, quad, indices, surface, 423 clip_status, invalid_status); 424 if (xf->opacities) 425 return quad_translucent(buf, xf, nquad, quad, indices, surface, 426 clip_status, invalid_status); 427 else 428 return quad_opaque(buf, xf, nquad, quad, indices, surface, 429 clip_status, invalid_status); 430} 431 432 433#define QUADFLATPROLOGUE(name) $\ 434 static Error $\ 435 name( $\ 436 struct buffer *buf, $\ 437 struct xfield *xf, $\ 438 int nquad, $\ 439 Quadrilateral *quad, $\ 440 int *indices, $\ 441 Pointer fcolors, $\ 442 Pointer bcolors, $\ 443 Pointer opacities, $\ 444 int surface, $\ 445 int clip_status, $\ 446 inv_stat invalid_status $\ 447 ) { $\ 448 QUADDCL; $\ 449 RGBColor *cmap = xf->cmap; $\ 450 float *omap = xf->omap; $\ 451 char fbyte = xf->fbyte, bbyte = xf->bbyte; $\ 452 /*char obyte = xf->obyte;*/ 453 454#define QUADFLATEPILOGUE $\ 455 return OK; $\ 456 } 457 458 459QUADFLATPROLOGUE(quad_flat_face) 460 QUADS(struct big, u.big, NOSHRGB, NOSHO, COL, 1, 1, FACE,qff); 461QUADFLATEPILOGUE 462 463 464QUADFLATPROLOGUE(quad_flat_vol) 465 float cmul = xf->tile.color_multiplier; 466 float omul = xf->tile.opacity_multiplier / cmul; 467 if (xf->tile.perspective) 468 DXErrorReturn(ERROR_BAD_PARAMETER, 469 "perspective volume rendering is not supported"); 470 if (!buf->merged) 471 _dxf_MergeBackIntoZ(buf); 472 QUAD_VOLUME(struct big, u.big, NOSHRGB, NOSHO, COL, 0, 1, VOLUME, qfv); 473QUADFLATEPILOGUE 474 475 476QUADFLATPROLOGUE(quad_flat_translucent) 477 if (clip_status) { 478 QUADS(struct big,u.big,NOSHRGB,NOSHO,COL, 479 0,TRANSCLIPZ,TRANSLUCENT,qftc); 480 } else if (buf->pix_type==pix_fast) { 481 QUADS(struct fast,u.fast,NOSHRGB,NOSHO,COL, 482 0,NOCLIPZ,TRANSLUCENT,qftf); 483 } else if (buf->pix_type==pix_big) { 484 QUADS(struct big,u.big,NOSHRGB,NOSHO,COL, 485 0,NOCLIPZ,TRANSLUCENT,qftb); 486 } else { 487 DXSetError(ERROR_INTERNAL, "unknown pix_type %d", buf->pix_type); 488 return ERROR; 489 } 490QUADFLATEPILOGUE 491 492 493QUADFLATPROLOGUE(quad_flat_opaque) 494 if (clip_status) { 495 QUADS(struct big,u.big,NOSHRGB,NOSHO,COL, 496 0,CLIPZ,OPAQUE,qfoc); 497 } else if (buf->pix_type==pix_fast) { 498 QUADS(struct fast,u.fast,NOSHRGB,NOSHO,COL, 499 0,NOCLIPZ,OPAQUE,qfof); 500 } else if (buf->pix_type==pix_big) { 501 QUADS(struct big,u.big,NOSHRGB,NOSHO,COL, 502 0,NOCLIPZ,OPAQUE,qfob); 503 } else { 504 DXSetError(ERROR_INTERNAL, "unknown pix_type %d", buf->pix_type); 505 return ERROR; 506 } 507QUADFLATEPILOGUE 508 509 510Error 511_dxf_QuadFlat( 512 struct buffer *buf, 513 struct xfield *xf, 514 int nquad, 515 Quadrilateral *quad, 516 int *indices, 517 Pointer fcolors, 518 Pointer bcolors, 519 Pointer opacities, 520 int surface, 521 int clip_status, 522 inv_stat invalid_status 523) { 524 QUADDCL; 525 526 if (xf->tile.perspective) { 527 struct xfield xx; 528 for (i=0; i<nquad; ) { 529 i = _dxf_zclip_quads(xf, (int *)quad, i, indices, nquad, &xx, invalid_status); 530 if (xx.nconnections) 531 _dxf_TriangleFlat(buf, &xx, xx.nconnections, xx.c.triangles, 532 xx.indices, xx.fcolors, xx.bcolors, xx.opacities, 533 surface, clip_status, invalid_status); 534 } 535 } 536 537 538 539 if (xf->ct!=ct_triangles && xf->ct!=ct_quads) 540 return quad_flat_vol(buf, xf, nquad, quad, indices, 541 fcolors, bcolors, opacities, 542 surface, clip_status, invalid_status); 543 else if (xf->opacities) 544 return quad_flat_translucent(buf, xf, nquad, quad, indices, 545 fcolors, bcolors, opacities, 546 surface, clip_status, invalid_status); 547 else 548 return quad_flat_opaque(buf, xf, nquad, quad, indices, 549 fcolors, bcolors, opacities, 550 surface, clip_status, invalid_status); 551} 552