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