| 34 |  |  | 
| 35 |  | #define  pvect(p)       printf(vformat, (p)[0], (p)[1], (p)[2]) | 
| 36 |  |  | 
| 37 | < | char  vformat[] = "%15.9g %15.9g %15.9g\n"; | 
| 38 | < | char  tsargs[] = "4 surf_dx surf_dy surf_dz surf.cal\n"; | 
| 37 | > | char  vformat[] = "%18.12g %18.12g %18.12g\n"; | 
| 38 | > | char  tsargs[] = "4 surf_dx surf_dy surf_dz surf.cal"; | 
| 39 |  | char  texname[] = "Phong"; | 
| 40 |  |  | 
| 41 |  | int  smooth = 0;                /* apply smoothing? */ | 
| 58 |  |  | 
| 59 |  | typedef struct { | 
| 60 |  | int  valid;     /* point is valid (vertex number) */ | 
| 61 | + | int  nvalid;    /* normal is valid */ | 
| 62 |  | FVECT  p;       /* vertex position */ | 
| 63 |  | FVECT  n;       /* average normal */ | 
| 64 |  | RREAL  uv[2];   /* (u,v) position */ | 
| 65 |  | } POINT; | 
| 66 |  |  | 
| 67 | + | int  nverts = 0;                /* vertex output count */ | 
| 68 | + | int  nnorms = 0;                /* normal output count */ | 
| 69 |  |  | 
| 70 |  | void loaddata(char *file, int m, int n, int pointsize); | 
| 71 |  | double l_dataval(char *nam); | 
| 72 |  | void putobjrow(POINT *rp, int n); | 
| 73 | + | void putobjvert(POINT *p); | 
| 74 |  | void putsquare(POINT *p0, POINT *p1, POINT *p2, POINT *p3); | 
| 75 |  | void comprow(double s, POINT *row, int siz); | 
| 76 |  | void compnorms(POINT *r0, POINT *r1, POINT *r2, int siz); | 
| 86 |  | int  i, j, m, n; | 
| 87 |  | char  stmp[256]; | 
| 88 |  |  | 
| 89 | + | esupport |= E_VARIABLE|E_FUNCTION|E_RCONST; | 
| 90 | + | esupport &= ~(E_OUTCHAN|E_INCHAN); | 
| 91 |  | varset("PI", ':', PI); | 
| 92 |  | funset("hermite", 5, ':', l_hermite); | 
| 93 |  | funset("bezier", 5, ':', l_bezier); | 
| 99 |  | for (i = 8; i < argc; i++) | 
| 100 |  | if (!strcmp(argv[i], "-e")) | 
| 101 |  | scompile(argv[++i], NULL, 0); | 
| 102 | < | else if (!strcmp(argv[i], "-f")) | 
| 103 | < | fcompile(argv[++i]); | 
| 104 | < | else if (!strcmp(argv[i], "-s")) | 
| 102 | > | else if (!strcmp(argv[i], "-f")) { | 
| 103 | > | char  *fpath = getpath(argv[++i], getrlibpath(), 0); | 
| 104 | > | if (fpath == NULL) { | 
| 105 | > | fprintf(stderr, "%s: cannot find file '%s'\n", | 
| 106 | > | argv[0], argv[i]); | 
| 107 | > | quit(1); | 
| 108 | > | } | 
| 109 | > | fcompile(fpath); | 
| 110 | > | } else if (!strcmp(argv[i], "-s")) | 
| 111 |  | smooth++; | 
| 112 |  | else if (!strcmp(argv[i], "-o")) | 
| 113 |  | objout++; | 
| 116 |  |  | 
| 117 |  | modname = argv[1]; | 
| 118 |  | surfname = argv[2]; | 
| 119 | < | m = atoi(argv[6]); | 
| 120 | < | n = atoi(argv[7]); | 
| 119 | > | m = eval(argv[6]) + .5; | 
| 120 | > | n = eval(argv[7]) + .5; | 
| 121 |  | if (m <= 0 || n <= 0) | 
| 122 |  | goto userror; | 
| 123 |  | if (!strcmp(argv[5], "-") || access(argv[5], 4) == 0) { /* file? */ | 
| 194 |  |  | 
| 195 |  | userror: | 
| 196 |  | fprintf(stderr, "Usage: %s material name ", argv[0]); | 
| 197 | < | fprintf(stderr, "x(s,t) y(s,t) z(s,t) m n [-s][-e expr][-f file]\n"); | 
| 197 | > | fprintf(stderr, "x(s,t) y(s,t) z(s,t) m n [-s][-o][-e expr][-f file]\n"); | 
| 198 |  | return 1; | 
| 199 |  | } | 
| 200 |  |  | 
| 209 |  | { | 
| 210 |  | FILE  *fp; | 
| 211 |  | char  word[64]; | 
| 212 | < | register int  size; | 
| 213 | < | register RREAL  *dp; | 
| 212 | > | int  size; | 
| 213 | > | RREAL  *dp; | 
| 214 |  |  | 
| 215 |  | datarec.flags = HASBORDER;              /* assume border values */ | 
| 216 |  | datarec.m = m+1; | 
| 241 |  | size--; | 
| 242 |  | } | 
| 243 |  | if (size == (m+n+1)*pointsize) {        /* no border after all */ | 
| 244 | < | dp = (RREAL *)realloc((void *)datarec.data, | 
| 244 | > | dp = (RREAL *)realloc(datarec.data, | 
| 245 |  | m*n*pointsize*sizeof(RREAL)); | 
| 246 |  | if (dp != NULL) | 
| 247 |  | datarec.data = dp; | 
| 266 |  | ) | 
| 267 |  | { | 
| 268 |  | double  u, v; | 
| 269 | < | register int  i, j; | 
| 270 | < | register RREAL  *dp; | 
| 269 | > | int  i, j; | 
| 270 | > | RREAL  *dp; | 
| 271 |  | double  d00, d01, d10, d11; | 
| 272 |  | /* compute coordinates */ | 
| 273 |  | u = argument(1); v = argument(2); | 
| 305 |  |  | 
| 306 |  | void | 
| 307 |  | putobjrow(                      /* output vertex row to .OBJ */ | 
| 308 | < | register POINT  *rp, | 
| 308 | > | POINT  *rp, | 
| 309 |  | int  n | 
| 310 |  | ) | 
| 311 |  | { | 
| 300 | – | static int      nverts = 0; | 
| 301 | – |  | 
| 312 |  | for ( ; n-- >= 0; rp++) { | 
| 313 |  | if (!rp->valid) | 
| 314 |  | continue; | 
| 315 |  | fputs("v ", stdout); | 
| 316 |  | pvect(rp->p); | 
| 317 | < | if (smooth && !ZEROVECT(rp->n)) | 
| 317 | > | if (smooth && !ZEROVECT(rp->n)) { | 
| 318 |  | printf("\tvn %.9g %.9g %.9g\n", | 
| 319 |  | rp->n[0], rp->n[1], rp->n[2]); | 
| 320 | + | rp->nvalid = ++nnorms; | 
| 321 | + | } else | 
| 322 | + | rp->nvalid = 0; | 
| 323 |  | printf("\tvt %.9g %.9g\n", rp->uv[0], rp->uv[1]); | 
| 324 |  | rp->valid = ++nverts; | 
| 325 |  | } | 
| 327 |  |  | 
| 328 |  |  | 
| 329 |  | void | 
| 330 | + | putobjvert(             /* put out OBJ vertex index triplet */ | 
| 331 | + | POINT *p | 
| 332 | + | ) | 
| 333 | + | { | 
| 334 | + | int     pti = p->valid ? p->valid-nverts-1 : 0; | 
| 335 | + | int     ni = p->nvalid ? p->nvalid-nnorms-1 : 0; | 
| 336 | + |  | 
| 337 | + | printf(" %d/%d/%d", pti, pti, ni); | 
| 338 | + | } | 
| 339 | + |  | 
| 340 | + |  | 
| 341 | + | void | 
| 342 |  | putsquare(              /* put out a square */ | 
| 343 |  | POINT *p0, | 
| 344 |  | POINT *p1, | 
| 369 |  | if (!(ok1 | ok2)) | 
| 370 |  | return; | 
| 371 |  | if (objout) {                   /* output .OBJ faces */ | 
| 347 | – | int     p0n=0, p1n=0, p2n=0, p3n=0; | 
| 348 | – | if (smooth) { | 
| 349 | – | if (!ZEROVECT(p0->n)) | 
| 350 | – | p0n = p0->valid; | 
| 351 | – | if (!ZEROVECT(p1->n)) | 
| 352 | – | p1n = p1->valid; | 
| 353 | – | if (!ZEROVECT(p2->n)) | 
| 354 | – | p2n = p2->valid; | 
| 355 | – | if (!ZEROVECT(p3->n)) | 
| 356 | – | p3n = p3->valid; | 
| 357 | – | } | 
| 372 |  | if (ok1 & ok2 && fdot(vc1,vc2) >= 1.0-FTINY*FTINY) { | 
| 373 | < | printf("f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d\n", | 
| 374 | < | p0->valid, p0->valid, p0n, | 
| 375 | < | p1->valid, p1->valid, p1n, | 
| 376 | < | p3->valid, p3->valid, p3n, | 
| 363 | < | p2->valid, p2->valid, p2n); | 
| 373 | > | putc('f', stdout); | 
| 374 | > | putobjvert(p0); putobjvert(p1); | 
| 375 | > | putobjvert(p3); putobjvert(p2); | 
| 376 | > | putc('\n', stdout); | 
| 377 |  | return; | 
| 378 |  | } | 
| 379 | < | if (ok1) | 
| 380 | < | printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n", | 
| 381 | < | p0->valid, p0->valid, p0n, | 
| 382 | < | p1->valid, p1->valid, p1n, | 
| 383 | < | p2->valid, p2->valid, p2n); | 
| 384 | < | if (ok2) | 
| 385 | < | printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n", | 
| 386 | < | p2->valid, p2->valid, p2n, | 
| 387 | < | p1->valid, p1->valid, p1n, | 
| 388 | < | p3->valid, p3->valid, p3n); | 
| 379 | > | if (ok1) { | 
| 380 | > | putc('f', stdout); | 
| 381 | > | putobjvert(p0); putobjvert(p1); putobjvert(p2); | 
| 382 | > | putc('\n', stdout); | 
| 383 | > | } | 
| 384 | > | if (ok2) { | 
| 385 | > | putc('f', stdout); | 
| 386 | > | putobjvert(p2); putobjvert(p1); putobjvert(p3); | 
| 387 | > | putc('\n', stdout); | 
| 388 | > | } | 
| 389 |  | return; | 
| 390 |  | } | 
| 391 |  | /* compute normal interpolation */ | 
| 395 |  | if (ok1 & ok2 && fdot(vc1,vc2) >= 1.0-FTINY*FTINY) { | 
| 396 |  | printf("\n%s ", modname); | 
| 397 |  | if (axis != -1) { | 
| 398 | < | printf("texfunc %s\n", texname); | 
| 386 | < | printf(tsargs); | 
| 398 | > | printf("texfunc %s\n%s\n", texname, tsargs); | 
| 399 |  | printf("0\n13\t%d\n", axis); | 
| 400 |  | pvect(norm[0]); | 
| 401 |  | pvect(norm[1]); | 
| 417 |  | if (ok1) { | 
| 418 |  | printf("\n%s ", modname); | 
| 419 |  | if (axis != -1) { | 
| 420 | < | printf("texfunc %s\n", texname); | 
| 409 | < | printf(tsargs); | 
| 420 | > | printf("texfunc %s\n%s\n", texname, tsargs); | 
| 421 |  | printf("0\n13\t%d\n", axis); | 
| 422 |  | pvect(norm[0]); | 
| 423 |  | pvect(norm[1]); | 
| 435 |  | if (ok2) { | 
| 436 |  | printf("\n%s ", modname); | 
| 437 |  | if (axis != -1) { | 
| 438 | < | printf("texfunc %s\n", texname); | 
| 428 | < | printf(tsargs); | 
| 438 | > | printf("texfunc %s\n%s\n", texname, tsargs); | 
| 439 |  | printf("0\n13\t%d\n", axis); | 
| 440 |  | pvect(norm[0]); | 
| 441 |  | pvect(norm[1]); | 
| 456 |  | void | 
| 457 |  | comprow(                        /* compute row of values */ | 
| 458 |  | double  s, | 
| 459 | < | register POINT  *row, | 
| 459 | > | POINT  *row, | 
| 460 |  | int  siz | 
| 461 |  | ) | 
| 462 |  | { | 
| 463 |  | double  st[2]; | 
| 464 |  | int  end; | 
| 465 |  | int  checkvalid; | 
| 466 | < | register int  i; | 
| 466 | > | int  i; | 
| 467 |  |  | 
| 468 |  | if (smooth) { | 
| 469 |  | i = -1;                 /* compute one past each end */ | 
| 497 |  |  | 
| 498 |  | void | 
| 499 |  | compnorms(              /* compute row of averaged normals */ | 
| 500 | < | register POINT  *r0, | 
| 501 | < | register POINT  *r1, | 
| 502 | < | register POINT  *r2, | 
| 500 | > | POINT  *r0, | 
| 501 | > | POINT  *r1, | 
| 502 | > | POINT  *r2, | 
| 503 |  | int  siz | 
| 504 |  | ) | 
| 505 |  | { | 
| 510 |  | /* compute row 1 normals */ | 
| 511 |  | while (siz-- >= 0) { | 
| 512 |  | if (!r1[0].valid) | 
| 513 | < | continue; | 
| 513 | > | goto skip; | 
| 514 |  | if (!r0[0].valid) { | 
| 515 |  | if (!r2[0].valid) { | 
| 516 |  | r1[0].n[0] = r1[0].n[1] = r1[0].n[2] = 0.0; | 
| 517 | < | continue; | 
| 517 | > | goto skip; | 
| 518 |  | } | 
| 519 |  | fvsum(v1, r2[0].p, r1[0].p, -1.0); | 
| 520 |  | } else if (!r2[0].valid) | 
| 524 |  | if (!r1[-1].valid) { | 
| 525 |  | if (!r1[1].valid) { | 
| 526 |  | r1[0].n[0] = r1[0].n[1] = r1[0].n[2] = 0.0; | 
| 527 | < | continue; | 
| 527 | > | goto skip; | 
| 528 |  | } | 
| 529 |  | fvsum(v2, r1[1].p, r1[0].p, -1.0); | 
| 530 |  | } else if (!r1[1].valid) | 
| 533 |  | fvsum(v2, r1[1].p, r1[-1].p, -1.0); | 
| 534 |  | fcross(r1[0].n, v1, v2); | 
| 535 |  | normalize(r1[0].n); | 
| 536 | + | skip: | 
| 537 |  | r0++; r1++; r2++; | 
| 538 |  | } | 
| 539 |  | } | 
| 541 |  |  | 
| 542 |  | int | 
| 543 |  | norminterp(     /* compute normal interpolation */ | 
| 544 | < | register FVECT  resmat[4], | 
| 544 | > | FVECT  resmat[4], | 
| 545 |  | POINT  *p0, | 
| 546 |  | POINT  *p1, | 
| 547 |  | POINT  *p2, | 
| 551 |  | #define u  ((ax+1)%3) | 
| 552 |  | #define v  ((ax+2)%3) | 
| 553 |  |  | 
| 554 | < | register int  ax; | 
| 554 | > | int  ax; | 
| 555 |  | MAT4  eqnmat; | 
| 556 |  | FVECT  v1; | 
| 557 | < | register int  i, j; | 
| 557 | > | int  i, j; | 
| 558 |  |  | 
| 559 |  | if (!smooth)                    /* no interpolation if no smoothing */ | 
| 560 |  | return(-1); |