00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include "DepthSortObj.h"
00027 #include "Matrix4.h"
00028 #include "PSDisplayDevice.h"
00029 #include "VMDDisplayList.h"
00030 #include "Inform.h"
00031
00032
00033 PSDisplayDevice::PSDisplayDevice(void)
00034 : FileRenderer ("PostScript", "PostScript (vector graphics)", "vmdscene.ps","ghostview %s &") {
00035 memerror = 0;
00036 x_offset = 306;
00037 y_offset = 396;
00038
00039
00040
00041 sph_iter = -1;
00042 sph_desired_iter = 0;
00043 sph_nverts = 0;
00044 sph_verts = NULL;
00045
00046 memusage = 0;
00047 points = 0;
00048 objects = 0;
00049 }
00050
00051
00052 PSDisplayDevice::~PSDisplayDevice(void) {
00053
00054
00055 if (sph_nverts && sph_verts) free(sph_verts);
00056 }
00057
00058
00059 void PSDisplayDevice::render(const VMDDisplayList *display_list) {
00060 DepthSortObject depth_obj;
00061 char *cmd_ptr;
00062 int draw;
00063 int tok;
00064 int nc;
00065 float a[3], b[3], c[3], d[3];
00066 float cent[3];
00067 float r;
00068 Matrix4 ident;
00069 float textsize=1.0f;
00070
00071
00072 while (transMat.num())
00073 transMat.pop();
00074
00075
00076 transMat.push(ident);
00077
00078
00079 super_multmatrix(display_list->mat.mat);
00080
00081
00082
00083 norm_light[0] = lightState[0].pos[0];
00084 norm_light[1] = lightState[0].pos[1];
00085 norm_light[2] = lightState[0].pos[2];
00086 if (norm_light[0] || norm_light[1] || norm_light[2])
00087 vec_normalize(norm_light);
00088
00089
00090 ResizeArray<Matrix4> pbcImages;
00091 find_pbc_images(display_list, pbcImages);
00092 int nimages = pbcImages.num();
00093
00094 for (int pbcimage = 0; pbcimage < nimages; pbcimage++) {
00095 transMat.dup();
00096 super_multmatrix(pbcImages[pbcimage].mat);
00097
00098
00099
00100 VMDDisplayList::VMDLinkIter cmditer;
00101 display_list->first(&cmditer);
00102 while ((tok = display_list->next(&cmditer, cmd_ptr)) != DLASTCOMMAND) {
00103 draw = 0;
00104 nc = -1;
00105
00106 switch (tok) {
00107 case DPOINT:
00108
00109 depth_obj.points = (float *) malloc(sizeof(float) * 2);
00110 if (!depth_obj.points) {
00111
00112 if (!memerror) {
00113 memerror = 1;
00114 msgErr << "PSDisplayDevice: Out of memory. Some " <<
00115 "objects were not drawn." << sendmsg;
00116 }
00117 break;
00118 }
00119
00120
00121 depth_obj.npoints = 1;
00122 depth_obj.color = colorIndex;
00123 (transMat.top()).multpoint3d(((DispCmdPoint *) cmd_ptr)->pos, a);
00124 memcpy(depth_obj.points, a, sizeof(float) * 2);
00125
00126
00127 depth_obj.dist = compute_dist(a);
00128
00129
00130 draw = 1;
00131 break;
00132
00133 case DSPHERE:
00134 {
00135 (transMat.top()).multpoint3d(((DispCmdSphere *) cmd_ptr)->pos_r, c);
00136 r = scale_radius(((DispCmdSphere *) cmd_ptr)->pos_r[3]);
00137
00138 sphere_approx(c, r);
00139 break;
00140 }
00141
00142 case DSPHEREARRAY:
00143 {
00144 DispCmdSphereArray *sa = (DispCmdSphereArray *) cmd_ptr;
00145 int cIndex, rIndex;
00146
00147 float * centers;
00148 float * radii;
00149 float * colors;
00150 sa->getpointers(centers, radii, colors);
00151
00152 set_sphere_res(sa->sphereres);
00153
00154 for (cIndex = 0, rIndex=0; rIndex < sa->numspheres;
00155 cIndex+=3, rIndex++)
00156 {
00157 colorIndex = nearest_index(colors[cIndex],
00158 colors[cIndex+1],
00159 colors[cIndex+2]);
00160 (transMat.top()).multpoint3d(¢ers[cIndex] , c);
00161 r = scale_radius(radii[rIndex]);
00162
00163 sphere_approx(c, r);
00164 }
00165
00166 break;
00167 }
00168
00169 case DLINE:
00170
00171 if (!memcmp(((DispCmdLine *) cmd_ptr)->pos1,
00172 ((DispCmdLine *) cmd_ptr)->pos2,
00173 sizeof(float) * 3)) {
00174
00175 break;
00176 }
00177
00178
00179 depth_obj.points = (float *) malloc(sizeof(float) * 4);
00180 if (!depth_obj.points) {
00181
00182 if (!memerror) {
00183 memerror = 1;
00184 msgErr << "PSDisplayDevice: Out of memory. Some " <<
00185 "objects were not drawn." << sendmsg;
00186 }
00187 break;
00188 }
00189
00190
00191 depth_obj.npoints = 2;
00192 depth_obj.color = colorIndex;
00193 (transMat.top()).multpoint3d(((DispCmdLine *) cmd_ptr)->pos1, a);
00194 (transMat.top()).multpoint3d(((DispCmdLine *) cmd_ptr)->pos2, b);
00195 memcpy(depth_obj.points, a, sizeof(float) * 2);
00196 memcpy(&depth_obj.points[2], b, sizeof(float) * 2);
00197
00198
00199 cent[0] = (a[0] + b[0]) / 2;
00200 cent[1] = (a[1] + b[1]) / 2;
00201 cent[2] = (a[2] + b[2]) / 2;
00202
00203
00204 depth_obj.dist = compute_dist(cent);
00205
00206
00207 draw = 1;
00208 break;
00209
00210 case DLINEARRAY:
00211 {
00212
00213 float *v = (float *)cmd_ptr;
00214 int nlines = (int)v[0];
00215 v++;
00216 for (int i=0; i<nlines; i++) {
00217
00218 if (!memcmp(v,v+3,3*sizeof(float)))
00219 break;
00220
00221
00222 depth_obj.points = (float *) malloc(sizeof(float) * 4);
00223 if (!depth_obj.points) {
00224
00225 if (!memerror) {
00226 memerror = 1;
00227 msgErr << "PSDisplayDevice: Out of memory. Some " <<
00228 "objects were not drawn." << sendmsg;
00229 }
00230 break;
00231 }
00232
00233
00234 depth_obj.npoints = 2;
00235 depth_obj.color = colorIndex;
00236 (transMat.top()).multpoint3d(v, a);
00237 (transMat.top()).multpoint3d(v+3, b);
00238 memcpy(depth_obj.points, a, sizeof(float) * 2);
00239 memcpy(&depth_obj.points[2], b, sizeof(float) * 2);
00240
00241
00242 cent[0] = (a[0] + b[0]) / 2;
00243 cent[1] = (a[1] + b[1]) / 2;
00244 cent[2] = (a[2] + b[2]) / 2;
00245
00246
00247 depth_obj.dist = compute_dist(cent);
00248
00249
00250 draw = 0;
00251 memusage += sizeof(float) * 2 * depth_obj.npoints;
00252 points += depth_obj.npoints;
00253 objects++;
00254 depth_list.append(depth_obj);
00255
00256 v += 6;
00257 }
00258 }
00259 break;
00260
00261 case DPOLYLINEARRAY:
00262 {
00263
00264 float *v = (float *)cmd_ptr;
00265 int nverts = (int)v[0];
00266 v++;
00267 for (int i=0; i<nverts-1; i++) {
00268
00269 if (!memcmp(v,v+3,3*sizeof(float)))
00270 break;
00271
00272
00273 depth_obj.points = (float *) malloc(sizeof(float) * 4);
00274 if (!depth_obj.points) {
00275
00276 if (!memerror) {
00277 memerror = 1;
00278 msgErr << "PSDisplayDevice: Out of memory. Some " <<
00279 "objects were not drawn." << sendmsg;
00280 }
00281 break;
00282 }
00283
00284
00285 depth_obj.npoints = 2;
00286 depth_obj.color = colorIndex;
00287 (transMat.top()).multpoint3d(v, a);
00288 (transMat.top()).multpoint3d(v+3, b);
00289 memcpy(depth_obj.points, a, sizeof(float) * 2);
00290 memcpy(&depth_obj.points[2], b, sizeof(float) * 2);
00291
00292
00293 cent[0] = (a[0] + b[0]) / 2;
00294 cent[1] = (a[1] + b[1]) / 2;
00295 cent[2] = (a[2] + b[2]) / 2;
00296
00297
00298 depth_obj.dist = compute_dist(cent);
00299
00300
00301 draw = 0;
00302 memusage += sizeof(float) * 2 * depth_obj.npoints;
00303 points += depth_obj.npoints;
00304 objects++;
00305 depth_list.append(depth_obj);
00306
00307 v += 3;
00308 }
00309 }
00310 break;
00311
00312 case DCYLINDER:
00313 {
00314 int res;
00315
00316 (transMat.top()).multpoint3d((float *) cmd_ptr, a);
00317 (transMat.top()).multpoint3d(&((float *) cmd_ptr)[3], b);
00318 r = scale_radius(((float *) cmd_ptr)[6]);
00319 res = (int) ((float *) cmd_ptr)[7];
00320
00321 cylinder_approx(a, b, r, res, (int) ((float *) cmd_ptr)[8]);
00322 break;
00323 }
00324
00325 case DCONE:
00326 {
00327 (transMat.top()).multpoint3d(((DispCmdCone *) cmd_ptr)->pos1, a);
00328 (transMat.top()).multpoint3d(((DispCmdCone *) cmd_ptr)->pos2, b);
00329 float r1 = scale_radius(((DispCmdCone *) cmd_ptr)->radius);
00330 float r2 = scale_radius(((DispCmdCone *) cmd_ptr)->radius2);
00331
00332
00333 if (r2 > 0.0f) {
00334 msgWarn << "PSDisplayDevice) can't draw truncated cones"
00335 << sendmsg;
00336 }
00337 cone_approx(a, b, r1);
00338 break;
00339 }
00340
00341 case DTEXTSIZE:
00342 textsize = ((DispCmdTextSize *)cmd_ptr)->size;
00343 break;
00344
00345 case DTEXT:
00346 {
00347 float* pos = (float *)cmd_ptr;
00348 #if 0
00349
00350 float thickness = pos[3];
00351 #endif
00352 char* txt = (char *)(pos+4);
00353 int txtlen = strlen(txt);
00354
00355 depth_obj.points = (float *) malloc(sizeof(float) * 2);
00356 depth_obj.text = (char *) malloc(sizeof(char) * (txtlen+1));
00357 if ( !(depth_obj.points || depth_obj.text) ) {
00358
00359 if (!memerror) {
00360 memerror = 1;
00361 msgErr << "PSDisplayDevice: Out of memory. Some " <<
00362 "objects were not drawn." << sendmsg;
00363 }
00364 break;
00365 }
00366
00367
00368 depth_obj.npoints = 1;
00369 depth_obj.color = colorIndex;
00370 (transMat.top()).multpoint3d(((DispCmdPoint *) cmd_ptr)->pos, a);
00371 memcpy(depth_obj.points, a, sizeof(float) * 2);
00372 strcpy(depth_obj.text , txt);
00373
00374
00375
00376 depth_obj.light_scale = textsize * 15;
00377
00378
00379 depth_obj.dist = compute_dist(a);
00380
00381
00382 draw = 1;
00383 break;
00384 }
00385
00386 case DTRIANGLE:
00387
00388 if (!memcmp(((DispCmdTriangle *) cmd_ptr)->pos1,
00389 ((DispCmdTriangle *) cmd_ptr)->pos2,
00390 sizeof(float) * 3) ||
00391 !memcmp(((DispCmdTriangle *) cmd_ptr)->pos2,
00392 ((DispCmdTriangle *) cmd_ptr)->pos3,
00393 sizeof(float) * 3) ||
00394 !memcmp(((DispCmdTriangle *) cmd_ptr)->pos2,
00395 ((DispCmdTriangle *) cmd_ptr)->pos3,
00396 sizeof(float) * 3)) {
00397
00398 break;
00399 }
00400
00401
00402 depth_obj.points = (float *) malloc(sizeof(float) * 6);
00403 if (!depth_obj.points) {
00404
00405 if (!memerror) {
00406 memerror = 1;
00407 msgErr << "PSDisplayDevice: Out of memory. Some " <<
00408 "objects were not drawn." << sendmsg;
00409 }
00410 break;
00411 }
00412
00413
00414 depth_obj.npoints = 3;
00415 depth_obj.color = (nc >= 0) ? nc : colorIndex;
00416 (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos1, a);
00417 (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos2, b);
00418 (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos3, c);
00419 memcpy(depth_obj.points, a, sizeof(float) * 2);
00420 memcpy(&depth_obj.points[2], b, sizeof(float) * 2);
00421 memcpy(&depth_obj.points[4], c, sizeof(float) * 2);
00422
00423
00424 cent[0] = (a[0] + b[0] + c[0]) / 3;
00425 cent[1] = (a[1] + b[1] + c[1]) / 3;
00426 cent[2] = (a[2] + b[2] + c[2]) / 3;
00427
00428
00429 depth_obj.dist = compute_dist(cent);
00430
00431
00432 depth_obj.light_scale = compute_light(a, b, c);
00433
00434
00435 draw = 1;
00436 break;
00437
00438 case DTRIMESH_C4F_N3F_V3F:
00439
00440
00441 decompose_mesh((DispCmdTriMesh *) cmd_ptr);
00442 break;
00443
00444 case DTRISTRIP:
00445
00446
00447 decompose_tristrip((DispCmdTriStrips *) cmd_ptr);
00448 break;
00449
00450 case DSQUARE:
00451
00452 if (!memcmp(((DispCmdSquare *) cmd_ptr)->pos1,
00453 ((DispCmdSquare *) cmd_ptr)->pos2,
00454 sizeof(float) * 3) ||
00455 !memcmp(((DispCmdSquare *) cmd_ptr)->pos1,
00456 ((DispCmdSquare *) cmd_ptr)->pos3,
00457 sizeof(float) * 3) ||
00458 !memcmp(((DispCmdSquare *) cmd_ptr)->pos1,
00459 ((DispCmdSquare *) cmd_ptr)->pos4,
00460 sizeof(float) * 3) ||
00461 !memcmp(((DispCmdSquare *) cmd_ptr)->pos2,
00462 ((DispCmdSquare *) cmd_ptr)->pos3,
00463 sizeof(float) * 3) ||
00464 !memcmp(((DispCmdSquare *) cmd_ptr)->pos2,
00465 ((DispCmdSquare *) cmd_ptr)->pos4,
00466 sizeof(float) * 3) ||
00467 !memcmp(((DispCmdSquare *) cmd_ptr)->pos3,
00468 ((DispCmdSquare *) cmd_ptr)->pos4,
00469 sizeof(float) * 3)) {
00470
00471 break;
00472 }
00473
00474
00475 depth_obj.points = (float *) malloc(sizeof(float) * 8);
00476 if (!depth_obj.points) {
00477
00478 if (!memerror) {
00479 memerror = 1;
00480 msgErr << "PSDisplayDevice: Out of memory. Some " <<
00481 "objects were not drawn." << sendmsg;
00482 }
00483 break;
00484 }
00485
00486
00487 depth_obj.npoints = 4;
00488 depth_obj.color = colorIndex;
00489 (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos1, a);
00490 (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos2, b);
00491 (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos3, c);
00492 (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos4, d);
00493 memcpy(depth_obj.points, a, sizeof(float) * 2);
00494 memcpy(&depth_obj.points[2], b, sizeof(float) * 2);
00495 memcpy(&depth_obj.points[4], c, sizeof(float) * 2);
00496 memcpy(&depth_obj.points[6], d, sizeof(float) * 2);
00497
00498
00499 cent[0] = (a[0] + b[0] + c[0] + d[0]) / 4;
00500 cent[1] = (a[1] + b[1] + c[1] + d[1]) / 4;
00501 cent[2] = (a[2] + b[2] + c[2] + d[2]) / 4;
00502
00503
00504 depth_obj.dist = compute_dist(cent);
00505
00506
00507 depth_obj.light_scale = compute_light(a, b, c);
00508
00509
00510 draw = 1;
00511 break;
00512
00513 case DCOLORINDEX:
00514 colorIndex = ((DispCmdColorIndex *) cmd_ptr)->color;
00515 break;
00516
00517 case DSPHERERES:
00518 set_sphere_res(((int *) cmd_ptr)[0]);
00519 break;
00520
00521 default:
00522
00523 break;
00524 }
00525
00526
00527 if (draw && depth_obj.npoints) {
00528 memusage += sizeof(float) * 2 * depth_obj.npoints;
00529 if ( depth_obj.text )
00530 memusage += sizeof(char) * (1+strlen(depth_obj.text));
00531 points += depth_obj.npoints;
00532 objects++;
00533 depth_list.append(depth_obj);
00534 }
00535
00536 depth_obj.npoints = 0;
00537 depth_obj.points = NULL;
00538
00539 }
00540
00541 transMat.pop();
00542 }
00543 }
00544
00545
00546
00547
00548
00549
00550 void PSDisplayDevice::render_done() {
00551 x_scale = 1.33f * 792 / Aspect / vSize;
00552 y_scale = x_scale;
00553
00554 msgInfo << "PSDisplayDevice: peak memory totals: " << sendmsg;
00555 msgInfo << " total dynamic memory used: " <<
00556 (long) (memusage + sizeof(DepthSortObject) * objects) << sendmsg;
00557 msgInfo << " total dynamic points: " << points << sendmsg;
00558 msgInfo << " total depthsorted object: " << objects << sendmsg;
00559
00560 if (depth_list.num()) {
00561 depth_list.qsort(0, depth_list.num() - 1);
00562 process_depth_list();
00563 }
00564 }
00565
00566
00567 void PSDisplayDevice::process_depth_list(void) {
00568 DepthSortObject obj;
00569 int i, nobjs;
00570
00571 nobjs = depth_list.num();
00572 float textsize = -20;
00573 for (i = 0; i < nobjs; i++) {
00574 obj = depth_list.item(i);
00575
00576 if (obj.text) {
00577
00578
00579
00580 if (obj.light_scale != textsize) {
00581 textsize = obj.light_scale;
00582 fprintf(outfile, "%f ts\n", textsize);
00583 }
00584 fprintf(outfile, "%d 1 c (%s) %d %d text\n",
00585 obj.color,
00586 obj.text,
00587 (int) (obj.points[0] * x_scale + x_offset),
00588 (int) (obj.points[1] * y_scale + y_offset));
00589 } else {
00590 switch (obj.npoints) {
00591 case 1:
00592 fprintf(outfile, "%d 1 c %d %d p\n",
00593 obj.color,
00594 (int) (obj.points[0] * x_scale + x_offset),
00595 (int) (obj.points[1] * y_scale + y_offset));
00596 break;
00597
00598 case 2:
00599 fprintf(outfile, "%d 1 c %d %d %d %d l\n",
00600 obj.color,
00601 (int) (obj.points[0] * x_scale + x_offset),
00602 (int) (obj.points[1] * y_scale + y_offset),
00603 (int) (obj.points[2] * x_scale + x_offset),
00604 (int) (obj.points[3] * y_scale + y_offset));
00605 break;
00606
00607 case 3:
00608 fprintf(outfile, "%d %.2f c %d %d %d %d %d %d t\n",
00609 obj.color, obj.light_scale,
00610 (int) (obj.points[0] * x_scale + x_offset),
00611 (int) (obj.points[1] * y_scale + y_offset),
00612 (int) (obj.points[2] * x_scale + x_offset),
00613 (int) (obj.points[3] * y_scale + y_offset),
00614 (int) (obj.points[4] * x_scale + x_offset),
00615 (int) (obj.points[5] * y_scale + y_offset));
00616 break;
00617
00618 case 4:
00619 fprintf(outfile, "%d %.2f c %d %d %d %d %d %d %d %d s\n",
00620 obj.color, obj.light_scale,
00621 (int) (obj.points[0] * x_scale + x_offset),
00622 (int) (obj.points[1] * y_scale + y_offset),
00623 (int) (obj.points[2] * x_scale + x_offset),
00624 (int) (obj.points[3] * y_scale + y_offset),
00625 (int) (obj.points[4] * x_scale + x_offset),
00626 (int) (obj.points[5] * y_scale + y_offset),
00627 (int) (obj.points[6] * x_scale + x_offset),
00628 (int) (obj.points[7] * y_scale + y_offset));
00629 break;
00630 }
00631 }
00632
00633
00634 memusage -= sizeof(float) * 2 * obj.npoints;
00635 if (obj.npoints) free(obj.points);
00636 if (obj.text) {
00637 memusage -= sizeof(char) * (1+strlen(obj.text));
00638 free(obj.text);
00639 }
00640 }
00641
00642
00643 fprintf(outfile, "showpage\n");
00644 close_file();
00645
00646
00647 depth_list.remove(-1, -1);
00648
00649 msgInfo << "PSDisplayDevice: end memory summary:" << sendmsg;
00650 msgInfo << " total dynamic memory used: " << memusage << sendmsg;
00651 msgInfo << " total dynamic points: " << points << sendmsg;
00652 msgInfo << " total depthsorted object: " << objects << sendmsg;
00653
00654
00655 memusage = 0;
00656 objects = 0;
00657 points = 0;
00658
00659
00660 }
00661
00662
00663 void PSDisplayDevice::set_sphere_res(int res)
00664 {
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 const int sph_iter_table[] = {
00675 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
00676 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4 };
00677
00678 if (res < 0) return;
00679 else if (res < 32) sph_desired_iter = sph_iter_table[res];
00680 else sph_desired_iter = (int) (0.8f * sqrtf((float) res));
00681 }
00682
00683
00684 void PSDisplayDevice::sphere_approx(float *c, float r) {
00685 DepthSortObject depth_obj;
00686 float x[3], y[3], z[3];
00687 float cent[3];
00688 int pi, ni;
00689 int i;
00690
00691
00692
00693
00694 if (!sph_verts || !sph_nverts || sph_iter != sph_desired_iter) {
00695 float a[3], b[3], c[3];
00696 float *newverts;
00697 float *oldverts;
00698 int nverts, ntris;
00699 int level;
00700
00701
00702 if (sph_verts && sph_nverts) free(sph_verts);
00703
00704
00705
00706
00707
00708
00709 newverts = (float *) malloc(sizeof(float) * 36);
00710 nverts = 12;
00711 ntris = 4;
00712
00713
00714
00715
00716 newverts[0] = -1; newverts[1] = 0; newverts[2] = 0;
00717 newverts[3] = 0; newverts[4] = 1; newverts[5] = 0;
00718 newverts[6] = 0; newverts[7] = 0; newverts[8] = 1;
00719
00720
00721 newverts[9] = 0; newverts[10] = 0; newverts[11] = 1;
00722 newverts[12] = 0; newverts[13] = 1; newverts[14] = 0;
00723 newverts[15] = 1; newverts[16] = 0; newverts[17] = 0;
00724
00725
00726 newverts[18] = 0; newverts[19] = 0; newverts[20] = 1;
00727 newverts[21] = 1; newverts[22] = 0; newverts[23] = 0;
00728 newverts[24] = 0; newverts[25] = -1; newverts[26] = 0;
00729
00730
00731 newverts[27] = 0; newverts[28] = 0; newverts[29] = 1;
00732 newverts[30] = 0; newverts[31] = -1; newverts[32] = 0;
00733 newverts[33] = -1; newverts[34] = 0; newverts[35] = 0;
00734
00735 for (level = 1; level < sph_desired_iter; level++) {
00736 oldverts = newverts;
00737
00738
00739
00740 newverts = (float *) malloc(sizeof(float) * 12 * nverts);
00741 if (!newverts) {
00742
00743 sph_iter = -1;
00744 sph_nverts = 0;
00745 sph_verts = NULL;
00746 free(oldverts);
00747
00748 if (!memerror) {
00749 memerror = 1;
00750 msgErr << "PSDisplayDevice: Out of memory. Some "
00751 << "objects were not drawn." << sendmsg;
00752 }
00753
00754 return;
00755 }
00756
00757 pi = 0;
00758 ni = 0;
00759 for (i = 0; i < ntris; i++) {
00760
00761 a[0] = (oldverts[pi ] + oldverts[pi + 6]) / 2;
00762 a[1] = (oldverts[pi + 1] + oldverts[pi + 7]) / 2;
00763 a[2] = (oldverts[pi + 2] + oldverts[pi + 8]) / 2;
00764 vec_normalize(a);
00765 b[0] = (oldverts[pi ] + oldverts[pi + 3]) / 2;
00766 b[1] = (oldverts[pi + 1] + oldverts[pi + 4]) / 2;
00767 b[2] = (oldverts[pi + 2] + oldverts[pi + 5]) / 2;
00768 vec_normalize(b);
00769 c[0] = (oldverts[pi + 3] + oldverts[pi + 6]) / 2;
00770 c[1] = (oldverts[pi + 4] + oldverts[pi + 7]) / 2;
00771 c[2] = (oldverts[pi + 5] + oldverts[pi + 8]) / 2;
00772 vec_normalize(c);
00773
00774
00775 memcpy(&newverts[ni ], &oldverts[pi], sizeof(float) * 3);
00776 memcpy(&newverts[ni + 3 ], b, sizeof(float) * 3);
00777 memcpy(&newverts[ni + 6 ], a, sizeof(float) * 3);
00778
00779 memcpy(&newverts[ni + 9 ], b, sizeof(float) * 3);
00780 memcpy(&newverts[ni + 12], &oldverts[pi + 3], sizeof(float) * 3);
00781 memcpy(&newverts[ni + 15], c, sizeof(float) * 3);
00782
00783 memcpy(&newverts[ni + 18], a, sizeof(float) * 3);
00784 memcpy(&newverts[ni + 21], b, sizeof(float) * 3);
00785 memcpy(&newverts[ni + 24], c, sizeof(float) * 3);
00786
00787 memcpy(&newverts[ni + 27], a, sizeof(float) * 3);
00788 memcpy(&newverts[ni + 30], c, sizeof(float) * 3);
00789 memcpy(&newverts[ni + 33], &oldverts[pi + 6], sizeof(float) * 3);
00790
00791 pi += 9;
00792 ni += 36;
00793 }
00794
00795 free(oldverts);
00796
00797 nverts *= 4;
00798 ntris *= 4;
00799 }
00800
00801 sph_iter = sph_desired_iter;
00802 sph_nverts = nverts;
00803 sph_verts = newverts;
00804 }
00805
00806
00807
00808
00809
00810 #if 0
00811 if (!points) {
00812
00813 if (!memerror) {
00814 memerror = 1;
00815 msgErr << "PSDisplayDevice: Out of memory. Some " <<
00816 "objects were not drawn." << sendmsg;
00817 }
00818 return;
00819 }
00820 #endif
00821
00822
00823
00824 depth_obj.npoints = 3;
00825 depth_obj.color = colorIndex;
00826
00827 pi = 0;
00828 for (i = 0; i < sph_nverts / 3; i++) {
00829
00830 depth_obj.points = (float *) malloc(sizeof(float) * 6);
00831 if (!depth_obj.points) {
00832
00833 if (!memerror) {
00834 memerror = 1;
00835 msgErr << "PSDisplayDevice: Out of memory. Some "
00836 << "objects were not drawn." << sendmsg;
00837 }
00838 return;
00839 }
00840
00841
00842 x[0] = r * sph_verts[pi] + c[0];
00843 x[1] = r * sph_verts[pi + 1] + c[1];
00844 x[2] = r * sph_verts[pi + 2] + c[2];
00845 y[0] = r * sph_verts[pi + 3] + c[0];
00846 y[1] = r * sph_verts[pi + 4] + c[1];
00847 y[2] = r * sph_verts[pi + 5] + c[2];
00848 z[0] = r * sph_verts[pi + 6] + c[0];
00849 z[1] = r * sph_verts[pi + 7] + c[1];
00850 z[2] = r * sph_verts[pi + 8] + c[2];
00851
00852 memcpy(depth_obj.points, x, sizeof(float) * 2);
00853 memcpy(&depth_obj.points[2], y, sizeof(float) * 2);
00854 memcpy(&depth_obj.points[4], z, sizeof(float) * 2);
00855
00856
00857 cent[0] = (x[0] + y[0] + z[0]) / 3;
00858 cent[1] = (x[1] + y[1] + z[1]) / 3;
00859 cent[2] = (x[2] + y[2] + z[2]) / 3;
00860 depth_obj.dist = compute_dist(cent);
00861 depth_obj.light_scale = compute_light(x, y, z);
00862
00863
00864 memusage += sizeof(float) * 2 * depth_obj.npoints;
00865 points += depth_obj.npoints;
00866 objects++;
00867 depth_list.append(depth_obj);
00868
00869 pi += 9;
00870 }
00871 }
00872
00873
00874 void PSDisplayDevice::cylinder_approx(float *a, float *b, float r, int res,
00875 int filled) {
00876
00877 float axis[3];
00878 float perp1[3], perp2[3];
00879 float pt1[3], pt2[3];
00880 float cent[3];
00881 float theta, theta_inc;
00882 float my_sin, my_cos;
00883 float w[3], x[3], y[3], z[3];
00884 int n;
00885
00886 DepthSortObject cyl_body, cyl_trailcap, cyl_leadcap;
00887
00888
00889 if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) return;
00890 if (r <= 0) return;
00891
00892
00893 axis[0] = b[0] - a[0];
00894 axis[1] = b[1] - a[1];
00895 axis[2] = b[2] - a[2];
00896 vec_normalize(axis);
00897
00898
00899 if ((ABS(axis[0]) < ABS(axis[1])) &&
00900 (ABS(axis[0]) < ABS(axis[2]))) {
00901 perp1[0] = 0;
00902 perp1[1] = axis[2];
00903 perp1[2] = -axis[1];
00904 }
00905 else if ((ABS(axis[1]) < ABS(axis[2]))) {
00906 perp1[0] = -axis[2];
00907 perp1[1] = 0;
00908 perp1[2] = axis[0];
00909 }
00910 else {
00911 perp1[0] = axis[1];
00912 perp1[1] = -axis[0];
00913 perp1[2] = 0;
00914 }
00915 vec_normalize(perp1);
00916
00917
00918
00919 cross_prod(perp2, axis, perp1);
00920
00921
00922 cyl_body.npoints = 4;
00923 cyl_body.color = colorIndex;
00924
00925 if (filled & CYLINDER_TRAILINGCAP) {
00926 cyl_trailcap.npoints = 3;
00927 cyl_trailcap.color = colorIndex;
00928 }
00929
00930 if (filled & CYLINDER_LEADINGCAP) {
00931 cyl_leadcap.npoints = 3;
00932 cyl_leadcap.color = colorIndex;
00933 }
00934
00935
00936 pt1[0] = r * perp2[0];
00937 pt1[1] = r * perp2[1];
00938 pt1[2] = r * perp2[2];
00939 theta = 0;
00940 theta_inc = (float) (VMD_TWOPI / res);
00941 for (n = 1; n <= res; n++) {
00942
00943 memcpy(pt2, pt1, sizeof(float) * 3);
00944
00945
00946 theta += theta_inc;
00947 my_sin = sinf(theta);
00948 my_cos = cosf(theta);
00949
00950
00951 pt1[0] = r * (perp2[0] * my_cos + perp1[0] * my_sin);
00952 pt1[1] = r * (perp2[1] * my_cos + perp1[1] * my_sin);
00953 pt1[2] = r * (perp2[2] * my_cos + perp1[2] * my_sin);
00954
00955 cyl_body.points = (float *) malloc(sizeof(float) * 8);
00956 cyl_trailcap.points = (float *) malloc(sizeof(float) * 6);
00957 cyl_leadcap.points = (float *) malloc(sizeof(float) * 6);
00958 if (!(cyl_body.points && cyl_trailcap.points && cyl_leadcap.points)) {
00959
00960 if (!memerror) {
00961 memerror = 1;
00962 msgErr << "PSDisplayDevice: Out of memory. Some " <<
00963 "objects were not drawn." << sendmsg;
00964 }
00965 continue;
00966 }
00967
00968
00969 w[0] = pt1[0] + a[0];
00970 w[1] = pt1[1] + a[1];
00971 w[2] = pt1[2] + a[2];
00972 x[0] = pt2[0] + a[0];
00973 x[1] = pt2[1] + a[1];
00974 x[2] = pt2[2] + a[2];
00975 y[0] = pt2[0] + b[0];
00976 y[1] = pt2[1] + b[1];
00977 y[2] = pt2[2] + b[2];
00978 z[0] = pt1[0] + b[0];
00979 z[1] = pt1[1] + b[1];
00980 z[2] = pt1[2] + b[2];
00981
00982 memcpy(cyl_body.points, w, sizeof(float) * 2);
00983 memcpy(&cyl_body.points[2], x, sizeof(float) * 2);
00984 memcpy(&cyl_body.points[4], y, sizeof(float) * 2);
00985 memcpy(&cyl_body.points[6], z, sizeof(float) * 2);
00986
00987
00988
00989
00990
00991 cent[0] = (w[0] + y[0]) / 2;
00992 cent[1] = (w[1] + y[1]) / 2;
00993 cent[2] = (w[2] + y[2]) / 2;
00994 cyl_body.dist = compute_dist(cent);
00995
00996
00997 cyl_body.light_scale = compute_light(w, x, y);
00998
00999
01000 memusage += sizeof(float) * 2 * cyl_body.npoints;
01001 points += cyl_body.npoints;
01002 objects++;
01003 depth_list.append(cyl_body);
01004
01005
01006 if (filled & CYLINDER_TRAILINGCAP) {
01007 memcpy(&cyl_trailcap.points[0], x, sizeof(float) * 2);
01008 memcpy(&cyl_trailcap.points[2], w, sizeof(float) * 2);
01009 memcpy(&cyl_trailcap.points[4], a, sizeof(float) * 2);
01010
01011
01012 cent[0] = (x[0] + w[0] + a[0]) / 3;
01013 cent[1] = (x[1] + w[1] + a[1]) / 3;
01014 cent[2] = (x[2] + w[2] + a[2]) / 3;
01015 cyl_trailcap.dist = compute_dist(cent);
01016
01017
01018 cyl_trailcap.light_scale = compute_light(x, w, a);
01019
01020 memusage += sizeof(float) * 2 * cyl_trailcap.npoints;
01021 points += cyl_trailcap.npoints;
01022 objects++;
01023 depth_list.append(cyl_trailcap);
01024 }
01025
01026
01027 if (filled & CYLINDER_LEADINGCAP) {
01028 memcpy(cyl_leadcap.points, z, sizeof(float) * 2);
01029 memcpy(&cyl_leadcap.points[2], y, sizeof(float) * 2);
01030 memcpy(&cyl_leadcap.points[4], b, sizeof(float) * 2);
01031
01032
01033 cent[0] = (z[0] + y[0] + b[0]) / 3;
01034 cent[1] = (z[1] + y[1] + b[1]) / 3;
01035 cent[2] = (z[2] + y[2] + b[2]) / 3;
01036 cyl_leadcap.dist = compute_dist(cent);
01037
01038
01039 cyl_leadcap.light_scale = compute_light(z, y, b);
01040
01041 memusage += sizeof(float) * 2 * cyl_leadcap.npoints;
01042 points += cyl_leadcap.npoints;
01043 objects++;
01044 depth_list.append(cyl_leadcap);
01045 }
01046 }
01047 }
01048
01049
01050 void PSDisplayDevice::cone_approx(float *a, float *b, float r) {
01051
01052 const int tris = 20;
01053
01054 float axis[3];
01055 float perp1[3], perp2[3];
01056 float pt1[3], pt2[3];
01057 float cent[3];
01058 float x[3], y[3], z[3];
01059 float theta, theta_inc;
01060 float my_sin, my_cos;
01061 int n;
01062
01063 DepthSortObject depth_obj;
01064
01065
01066 if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) return;
01067 if (r <= 0) return;
01068
01069
01070 axis[0] = b[0] - a[0];
01071 axis[1] = b[1] - a[1];
01072 axis[2] = b[2] - a[2];
01073 vec_normalize(axis);
01074
01075
01076 if ((ABS(axis[0]) < ABS(axis[1])) &&
01077 (ABS(axis[0]) < ABS(axis[2]))) {
01078 perp1[0] = 0;
01079 perp1[1] = axis[2];
01080 perp1[2] = -axis[1];
01081 }
01082 else if ((ABS(axis[1]) < ABS(axis[2]))) {
01083 perp1[0] = -axis[2];
01084 perp1[1] = 0;
01085 perp1[2] = axis[0];
01086 }
01087 else {
01088 perp1[0] = axis[1];
01089 perp1[1] = -axis[0];
01090 perp1[2] = 0;
01091 }
01092 vec_normalize(perp1);
01093
01094
01095
01096 cross_prod(perp2, axis, perp1);
01097
01098
01099 depth_obj.npoints = 3;
01100 depth_obj.color = colorIndex;
01101
01102
01103 pt1[0] = r * perp2[0];
01104 pt1[1] = r * perp2[1];
01105 pt1[2] = r * perp2[2];
01106 theta = 0;
01107 theta_inc = (float) (VMD_TWOPI / tris);
01108 for (n = 1; n <= tris; n++) {
01109
01110 memcpy(pt2, pt1, sizeof(float) * 3);
01111
01112
01113 theta += theta_inc;
01114 my_sin = sinf(theta);
01115 my_cos = cosf(theta);
01116
01117
01118 pt1[0] = r * (perp2[0] * my_cos + perp1[0] * my_sin);
01119 pt1[1] = r * (perp2[1] * my_cos + perp1[1] * my_sin);
01120 pt1[2] = r * (perp2[2] * my_cos + perp1[2] * my_sin);
01121
01122 depth_obj.points = (float *) malloc(sizeof(float) * 6);
01123 if (!depth_obj.points) {
01124
01125 if (!memerror) {
01126 memerror = 1;
01127 msgErr << "PSDisplayDevice: Out of memory. Some " <<
01128 "objects were not drawn." << sendmsg;
01129 }
01130 continue;
01131 }
01132
01133
01134 x[0] = pt1[0] + a[0];
01135 x[1] = pt1[1] + a[1];
01136 x[2] = pt1[2] + a[2];
01137 y[0] = pt2[0] + a[0];
01138 y[1] = pt2[1] + a[1];
01139 y[2] = pt2[2] + a[2];
01140
01141
01142 z[0] = b[0];
01143 z[1] = b[1];
01144 z[2] = b[2];
01145
01146 memcpy(depth_obj.points, x, sizeof(float) * 2);
01147 memcpy(&depth_obj.points[2], y, sizeof(float) * 2);
01148 memcpy(&depth_obj.points[4], z, sizeof(float) * 2);
01149
01150
01151
01152 cent[0] = (x[0] + y[0] + z[0]) / 3;
01153 cent[1] = (x[1] + y[1] + z[1]) / 3;
01154 cent[2] = (x[2] + y[2] + z[2]) / 3;
01155 depth_obj.dist = compute_dist(cent);
01156
01157
01158 depth_obj.light_scale = compute_light(x, y, z);
01159
01160
01161 memusage += sizeof(float) * 2 * depth_obj.npoints;
01162 points += depth_obj.npoints;
01163 objects++;
01164 depth_list.append(depth_obj);
01165 }
01166 }
01167
01168
01169 void PSDisplayDevice::decompose_mesh(DispCmdTriMesh *mesh) {
01170 int i;
01171 int fi;
01172 int f1, f2, f3;
01173 float r, g, b;
01174 float x[3], y[3], z[3], cent[3];
01175 float *cnv;
01176 int *f;
01177 mesh->getpointers(cnv, f);
01178 DepthSortObject depth_obj;
01179
01180 depth_obj.npoints = 3;
01181
01182 fi = -3;
01183 for (i = 0; i < mesh->numfacets; i++) {
01184 fi += 3;
01185 f1 = f[fi ] * 10;
01186 f2 = f[fi + 1] * 10;
01187 f3 = f[fi + 2] * 10;
01188
01189
01190 depth_obj.points = (float *) malloc(6 * sizeof(float));
01191 if (!depth_obj.points) {
01192 if (!memerror) {
01193 memerror = 1;
01194 msgErr << "PSDisplayDevice: Out of memory. Some " <<
01195 "objects were not drawn." << sendmsg;
01196 }
01197 continue;
01198 }
01199
01200
01201
01202 r = (cnv[f1] + cnv[f2] + cnv[f3]) / 3;
01203 g = (cnv[f1 + 1] + cnv[f2 + 1] + cnv[f3 + 1]) / 3;
01204 b = (cnv[f1 + 2] + cnv[f2 + 2] + cnv[f3 + 2]) / 3;
01205 depth_obj.color = nearest_index(r, g, b);
01206
01207
01208
01209 (transMat.top()).multpoint3d(&cnv[f1 + 7], x);
01210 (transMat.top()).multpoint3d(&cnv[f2 + 7], y);
01211 (transMat.top()).multpoint3d(&cnv[f3 + 7], z);
01212 memcpy(depth_obj.points, x, sizeof(float) * 2);
01213 memcpy(&depth_obj.points[2], y, sizeof(float) * 2);
01214 memcpy(&depth_obj.points[4], z, sizeof(float) * 2);
01215
01216
01217 cent[0] = (x[0] + y[0] + z[0]) / 3;
01218 cent[1] = (x[1] + y[1] + z[1]) / 3;
01219 cent[2] = (x[2] + y[2] + z[2]) / 3;
01220
01221
01222 depth_obj.dist = compute_dist(cent);
01223
01224
01225 depth_obj.light_scale = compute_light(x, y, z);
01226
01227
01228 memusage += sizeof(float) * 2 * depth_obj.npoints;
01229 points += depth_obj.npoints;
01230 objects++;
01231 depth_list.append(depth_obj);
01232 }
01233
01234 }
01235
01236
01237 void PSDisplayDevice::decompose_tristrip(DispCmdTriStrips *strip)
01238 {
01239 int s, t, v = 0;
01240 int v0, v1, v2;
01241 float r, g, b;
01242 float x[3], y[3], z[3], cent[3];
01243 DepthSortObject depth_obj;
01244
01245 depth_obj.npoints = 3;
01246
01247
01248 const int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
01249
01250 float *cnv;
01251 int *f;
01252 int *vertsperstrip;
01253 strip->getpointers(cnv, f, vertsperstrip);
01254
01255
01256 for (s = 0; s < strip->numstrips; s++)
01257 {
01258
01259 for (t = 0; t < vertsperstrip[s] - 2; t++)
01260 {
01261 v0 = f[v + (stripaddr[t & 0x01][0])] * 10;
01262 v1 = f[v + (stripaddr[t & 0x01][1])] * 10;
01263 v2 = f[v + (stripaddr[t & 0x01][2])] * 10;
01264
01265
01266 depth_obj.points = (float *) malloc(6 * sizeof(float));
01267 if (!depth_obj.points) {
01268 if (!memerror) {
01269 memerror = 1;
01270 msgErr << "PSDisplayDevice: Out of memory. Some "
01271 << "objects were not drawn." << sendmsg;
01272 }
01273 continue;
01274 }
01275
01276
01277
01278 r = (cnv[v0+0] + cnv[v1+0] + cnv[v2+0]) / 3;
01279 g = (cnv[v0+1] + cnv[v1+1] + cnv[v2+1]) / 3;
01280 b = (cnv[v0+2] + cnv[v1+2] + cnv[v2+2]) / 3;
01281 depth_obj.color = nearest_index(r, g, b);
01282
01283
01284
01285 (transMat.top()).multpoint3d(&cnv[v0 + 7], x);
01286 (transMat.top()).multpoint3d(&cnv[v1 + 7], y);
01287 (transMat.top()).multpoint3d(&cnv[v2 + 7], z);
01288 memcpy(depth_obj.points, x, sizeof(float) * 2);
01289 memcpy(&depth_obj.points[2], y, sizeof(float) * 2);
01290 memcpy(&depth_obj.points[4], z, sizeof(float) * 2);
01291
01292
01293 cent[0] = (x[0] + y[0] + z[0]) / 3;
01294 cent[1] = (x[1] + y[1] + z[1]) / 3;
01295 cent[2] = (x[2] + y[2] + z[2]) / 3;
01296
01297
01298 depth_obj.dist = compute_dist(cent);
01299
01300
01301 depth_obj.light_scale = compute_light(x, y, z);
01302
01303
01304 memusage += sizeof(float) * 2 * depth_obj.npoints;
01305 points += depth_obj.npoints;
01306 objects++;
01307 depth_list.append(depth_obj);
01308
01309 v++;
01310 }
01311 v+=2;
01312 }
01313 }
01314
01315
01316 void PSDisplayDevice::write_header(void) {
01317 int i;
01318
01319 fprintf(outfile, "%%!PS-Adobe-1.0\n");
01320 fprintf(outfile, "%%%%DocumentFonts:Helvetica\n");
01321 fprintf(outfile, "%%%%Title:vmd.ps\n");
01322 fprintf(outfile, "%%%%Creator:VMD -- Visual Molecular Dynamics\n");
01323 fprintf(outfile, "%%%%CreationDate:\n");
01324 fprintf(outfile, "%%%%Pages:1\n");
01325 fprintf(outfile, "%%%%BoundingBox:0 0 612 792\n");
01326 fprintf(outfile, "%%%%EndComments\n");
01327 fprintf(outfile, "%%%%Page:1 1\n");
01328
01329 fprintf(outfile, "%3.2f %3.2f %3.2f setrgbcolor %% background color\n",
01330 backColor[0], backColor[1], backColor[2]);
01331 fprintf(outfile, "newpath\n");
01332 fprintf(outfile, "0 0 moveto\n");
01333 fprintf(outfile, "0 792 lineto\n");
01334 fprintf(outfile, "792 792 lineto\n");
01335 fprintf(outfile, "792 0 lineto\n");
01336 fprintf(outfile, "closepath\nfill\nstroke\n");
01337
01338
01339
01340 fprintf(outfile, "/s\n");
01341 fprintf(outfile, "{ newpath moveto lineto lineto lineto closepath fill stroke } def\n");
01342
01343
01344 fprintf(outfile, "/sw\n");
01345 fprintf(outfile, "{ newpath moveto lineto lineto lineto closepath stroke } def\n");
01346
01347
01348 fprintf(outfile, "/t\n");
01349 fprintf(outfile, "{ newpath moveto lineto lineto closepath fill stroke } def\n");
01350
01351
01352 fprintf(outfile, "/tw\n");
01353 fprintf(outfile, "{ newpath moveto lineto lineto closepath stroke } def\n");
01354
01355
01356
01357
01358
01359
01360 fprintf(outfile, "/p\n");
01361 fprintf(outfile, "{ dup dup dup 5 -1 roll dup dup dup 8 -1 roll exch 8 -1\n");
01362 fprintf(outfile, " roll 4 1 roll 8 -1 roll 6 1 roll newpath -1 add moveto\n");
01363 fprintf(outfile, " 1 add lineto exch -1 add exch moveto exch 1 add exch\n");
01364 fprintf(outfile, " lineto closepath stroke } def\n");
01365
01366
01367 fprintf(outfile, "/l\n");
01368 fprintf(outfile, "{ newpath moveto lineto closepath stroke } def\n");
01369
01370
01371
01372
01373 fprintf(outfile, "/mc\n");
01374 fprintf(outfile, "{ dup 4 1 roll dup 3 1 roll mul 5 1 roll mul 4 1 roll\n");
01375 fprintf(outfile, " mul 3 1 roll } def\n");
01376
01377
01378
01379 fprintf(outfile, "/gc\n");
01380 fprintf(outfile, "{ 2 1 roll dup 3 -1 roll get dup dup 0 get 3 1 roll\n");
01381 fprintf(outfile, " 1 get 3 1 roll 2 get 3 -1 roll exch } def\n");
01382
01383
01384 fprintf(outfile, "/text\n");
01385 fprintf(outfile,"{ moveto show } def\n");
01386
01387
01388 fprintf(outfile, "/ts\n");
01389 fprintf(outfile, "{ /Helvetica findfont exch scalefont setfont } def\n");
01390
01391
01392
01393
01394
01395
01396 fprintf(outfile, "/c\n");
01397 fprintf(outfile, "{ 3 1 roll gc 5 -1 roll mc setrgbcolor } def\n");
01398
01399
01400
01401
01402
01403 fprintf(outfile, "\n");
01404 for (i = 0; i < MAXCOLORS; i++) {
01405 fprintf(outfile, "[ %.2f %.2f %.2f ]\n",
01406 matData[i][0],
01407 matData[i][1],
01408 matData[i][2]);
01409 }
01410 fprintf(outfile, "%d array astore\n", MAXCOLORS);
01411 }
01412
01413
01414 void PSDisplayDevice::write_trailer(void) {
01415 }
01416
01417
01418 void PSDisplayDevice::comment(const char *s) {
01419 fprintf(outfile, "%%%% %s\n", s);
01420 }
01421
01422
01423 inline float PSDisplayDevice::compute_dist(float *s) {
01424 return
01425 (s[0] - eyePos[0]) * (s[0] - eyePos[0]) +
01426 (s[1] - eyePos[1]) * (s[1] - eyePos[1]) +
01427 (s[2] - eyePos[2]) * (s[2] - eyePos[2]);
01428 }
01429
01430
01431 float PSDisplayDevice::compute_light(float *a, float *b, float *c) {
01432 float norm[3];
01433 float light_scale;
01434
01435
01436 norm[0] =
01437 a[1] * (b[2] - c[2]) +
01438 b[1] * (c[2] - a[2]) +
01439 c[1] * (a[2] - b[2]);
01440 norm[1] =
01441 a[2] * (b[0] - c[0]) +
01442 b[2] * (c[0] - a[0]) +
01443 c[2] * (a[0] - b[0]);
01444 norm[2] =
01445 a[0] * (b[1] - c[1]) +
01446 b[0] * (c[1] - a[1]) +
01447 c[0] * (a[1] - b[1]);
01448
01449
01450
01451 if (!norm[0] && !norm[1] && !norm[2]) {
01452 light_scale = 0;
01453 } else {
01454
01455
01456 vec_normalize(norm);
01457 light_scale = dot_prod(norm, norm_light);
01458 if (light_scale < 0) light_scale = -light_scale;
01459 }
01460
01461 return light_scale;
01462 }