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