00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <string.h>
00024 #include <stdio.h>
00025 #include <math.h>
00026 #include "POV3DisplayDevice.h"
00027 #include "Matrix4.h"
00028 #include "Inform.h"
00029 #include "utilities.h"
00030 #include "DispCmds.h"
00031 #include "config.h"
00032 #include "Hershey.h"
00033
00034 #define DEFAULT_RADIUS 0.002f
00035 #define DASH_LENGTH 0.02f
00036 #define PHONG_DIVISOR 64.0f
00037
00038
00039
00040
00041
00042 #define POVRAY_BRAIN_DAMAGE_WORKAROUND 1
00043 #define POVRAY_SCALEHACK 1000.0f
00044
00046
00047
00048
00049 POV3DisplayDevice::POV3DisplayDevice() : FileRenderer("POV3", "POV-Ray 3.6", "vmdscene.pov", "povray +W%w +H%h -I%s -O%s.tga +D +X +A +FT") {
00050 reset_vars();
00051 }
00052
00053
00054 POV3DisplayDevice::~POV3DisplayDevice(void) { }
00055
00056
00057 void POV3DisplayDevice::reset_vars(void) {
00058 degenerate_triangles = 0;
00059 degenerate_cylinders = 0;
00060 degenerate_cones = 0;
00061 memset(&clip_on, 0, sizeof(clip_on));
00062 old_materialIndex = -1;
00063 }
00064
00065
00067
00068 void POV3DisplayDevice::text(float *pos, float size, float thickness,
00069 const char *str) {
00070 float textpos[3];
00071 float textsize, textthickness;
00072 hersheyhandle hh;
00073
00074
00075 (transMat.top()).multpoint3d(pos, textpos);
00076 textsize = size * 1.5f;
00077 textthickness = thickness*DEFAULT_RADIUS;
00078
00079 while (*str != '\0') {
00080 float lm, rm, x, y, ox, oy;
00081 int draw, odraw;
00082 ox=oy=x=y=0.0f;
00083 draw=odraw=0;
00084
00085 hersheyDrawInitLetter(&hh, *str, &lm, &rm);
00086 textpos[0] -= lm * textsize;
00087
00088 while (!hersheyDrawNextLine(&hh, &draw, &x, &y)) {
00089 float oldpt[3], newpt[3];
00090 if (draw) {
00091 newpt[0] = textpos[0] + textsize * x;
00092 newpt[1] = textpos[1] + textsize * y;
00093 newpt[2] = textpos[2];
00094
00095 if (odraw) {
00096
00097 oldpt[0] = textpos[0] + textsize * ox;
00098 oldpt[1] = textpos[1] + textsize * oy;
00099 oldpt[2] = textpos[2];
00100
00101 fprintf(outfile, "VMD_cylinder(<%.8f,%.8f,%.8f>,<%.8f,%.8f,%.8f>",
00102 oldpt[0], oldpt[1], -oldpt[2], newpt[0], newpt[1], -newpt[2]);
00103 fprintf(outfile, "%.4f,rgbt<%.3f,%.3f,%.3f,%.3f>,%d)\n",
00104 textthickness, matData[colorIndex][0], matData[colorIndex][1],
00105 matData[colorIndex][2], 1 - mat_opacity, 1);
00106
00107 fprintf(outfile, "VMD_sphere(<%.4f,%.4f,%.4f>,%.4f,",
00108 newpt[0], newpt[1], -newpt[2], textthickness);
00109 fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
00110 matData[colorIndex][0], matData[colorIndex][1],
00111 matData[colorIndex][2], 1 - mat_opacity);
00112 } else {
00113
00114 fprintf(outfile, "VMD_sphere(<%.4f,%.4f,%.4f>,%.4f,",
00115 newpt[0], newpt[1], -newpt[2], textthickness);
00116 fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
00117 matData[colorIndex][0], matData[colorIndex][1],
00118 matData[colorIndex][2], 1 - mat_opacity);
00119 }
00120 }
00121
00122 ox=x;
00123 oy=y;
00124 odraw=draw;
00125 }
00126 textpos[0] += rm * textsize;
00127
00128 str++;
00129 }
00130 }
00131
00132
00133
00134 void POV3DisplayDevice::point(float * spdata) {
00135 float vec[3];
00136
00137 (transMat.top()).multpoint3d(spdata, vec);
00138
00139
00140
00141
00142 fprintf(outfile, "VMD_point(<%.4f,%.4f,%.4f>,%.4f,rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
00143 vec[0], vec[1], -vec[2], ((float)pointSize)*DEFAULT_RADIUS,
00144 matData[colorIndex][0], matData[colorIndex][1],
00145 matData[colorIndex][2], 1 - mat_opacity);
00146 }
00147
00148
00149 void POV3DisplayDevice::sphere(float * spdata) {
00150 float vec[3];
00151 float radius;
00152
00153
00154 (transMat.top()).multpoint3d(spdata, vec);
00155 radius = scale_radius(spdata[3]);
00156
00157
00158
00159
00160 fprintf(outfile, "VMD_sphere(<%.4f,%.4f,%.4f>,%.4f,",
00161 vec[0], vec[1], -vec[2], radius);
00162 fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
00163 matData[colorIndex][0], matData[colorIndex][1], matData[colorIndex][2],
00164 1 - mat_opacity);
00165 }
00166
00167
00168 void POV3DisplayDevice::line(float *a, float*b) {
00169 int i, j, test;
00170 float dirvec[3], unitdirvec[3];
00171 float from[3], to[3], tmp1[3], tmp2[3];
00172
00173 if (lineStyle == ::SOLIDLINE) {
00174
00175 (transMat.top()).multpoint3d(a, from);
00176 (transMat.top()).multpoint3d(b, to);
00177
00178
00179
00180
00181 fprintf(outfile, "VMD_line(<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,",
00182 from[0], from[1], -from[2], to[0], to[1], -to[2]);
00183 fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
00184 matData[colorIndex][0], matData[colorIndex][1], matData[colorIndex][2],
00185 1 - mat_opacity);
00186
00187 }
00188 else if (lineStyle == ::DASHEDLINE) {
00189
00190 (transMat.top()).multpoint3d(a, tmp1);
00191 (transMat.top()).multpoint3d(b, tmp2);
00192
00193
00194 vec_sub(dirvec, tmp2, tmp1);
00195 vec_copy(unitdirvec, dirvec);
00196 vec_normalize(unitdirvec);
00197 test = 1;
00198 i = 0;
00199 while (test == 1) {
00200 for (j=0; j<3; j++) {
00201 from[j] = (float) (tmp1[j] + (2*i)*DASH_LENGTH*unitdirvec[j]);
00202 to[j] = (float) (tmp1[j] + (2*i + 1)*DASH_LENGTH*unitdirvec[j]);
00203 }
00204 if (fabsf(tmp1[0] - to[0]) >= fabsf(dirvec[0])) {
00205 vec_copy(to, tmp2);
00206 test = 0;
00207 }
00208
00209
00210
00211
00212 fprintf(outfile, "VMD_line(<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,",
00213 from[0], from[1], -from[2], to[0], to[1], -to[2]);
00214 fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
00215 matData[colorIndex][0], matData[colorIndex][1], matData[colorIndex][2],
00216 1 - mat_opacity);
00217
00218 i++;
00219 }
00220 }
00221 else {
00222 msgErr << "POV3DisplayDevice: Unknown line style " << lineStyle << sendmsg;
00223 }
00224 }
00225
00226
00227
00228 void POV3DisplayDevice::cylinder(float *a, float *b, float r, int filled) {
00229 float from[3], to[3];
00230 float radius;
00231
00232
00233 (transMat.top()).multpoint3d(a, from);
00234 (transMat.top()).multpoint3d(b, to);
00235 radius = scale_radius(r);
00236
00237
00238 if ( ((from[0]-to[0])*(from[0]-to[0]) +
00239 (from[1]-to[1])*(from[1]-to[1]) +
00240 (from[2]-to[2])*(from[2]-to[2])) < 1e-20 ) {
00241 degenerate_cylinders++;
00242 return;
00243 }
00244
00245
00246
00247 fprintf(outfile, "VMD_cylinder(<%g,%g,%g>,<%g,%g,%g>",
00248 from[0], from[1], -from[2], to[0], to[1], -to[2]);
00249 fprintf(outfile, "%.4f,rgbt<%.3f,%.3f,%.3f,%.3f>,%d)\n",
00250 radius, matData[colorIndex][0], matData[colorIndex][1],
00251 matData[colorIndex][2], 1 - mat_opacity, !filled);
00252 }
00253
00254
00255 void POV3DisplayDevice::cone(float *a, float *b, float r) {
00256 float from[3], to[3];
00257 float radius;
00258
00259
00260 (transMat.top()).multpoint3d(a, from);
00261 (transMat.top()).multpoint3d(b, to);
00262 radius = scale_radius(r);
00263
00264
00265 if ( ((from[0]-to[0])*(from[0]-to[0]) +
00266 (from[1]-to[1])*(from[1]-to[1]) +
00267 (from[2]-to[2])*(from[2]-to[2])) < 1e-20 ) {
00268 degenerate_cones++;
00269 return;
00270 }
00271
00272
00273
00274
00275 fprintf(outfile, "VMD_cone (<%g,%g,%g>,<%g,%g,%g>,%.4f,",
00276 from[0], from[1], -from[2], to[0], to[1], -to[2], radius);
00277 fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
00278 matData[colorIndex][0], matData[colorIndex][1], matData[colorIndex][2],
00279 1 - mat_opacity);
00280 }
00281
00282
00283
00284
00285
00286 void POV3DisplayDevice::triangle(const float *a, const float *b, const float *c,
00287 const float *n1, const float *n2, const float *n3) {
00288 float c1[3], c2[3], c3[3];
00289
00290 memcpy(c1, matData[colorIndex], 3 * sizeof(float));
00291 memcpy(c2, matData[colorIndex], 3 * sizeof(float));
00292 memcpy(c3, matData[colorIndex], 3 * sizeof(float));
00293
00294 tricolor(a, b, c, n1, n2, n3, c1, c2, c3);
00295 return;
00296 }
00297
00298
00299 void POV3DisplayDevice::tricolor(const float * xyz1, const float * xyz2, const float * xyz3,
00300 const float * n1, const float * n2, const float * n3,
00301 const float *c1, const float *c2, const float *c3) {
00302 float vec1[3], vec2[3], vec3[3], norm1[3], norm2[3], norm3[3];
00303 float leg1[3], leg2[3], trinorm[3], ang1, ang2, ang3;
00304
00305
00306 (transMat.top()).multpoint3d(xyz1, vec1);
00307 (transMat.top()).multpoint3d(xyz2, vec2);
00308 (transMat.top()).multpoint3d(xyz3, vec3);
00309
00310
00311 (transMat.top()).multnorm3d(n1, norm1);
00312 (transMat.top()).multnorm3d(n2, norm2);
00313 (transMat.top()).multnorm3d(n3, norm3);
00314
00315
00316
00317
00318
00319 vec_sub(leg1, vec2, vec1);
00320 vec_sub(leg2, vec3, vec1);
00321 cross_prod(trinorm, leg1, leg2);
00322 ang1 = dot_prod(trinorm, norm1);
00323 ang2 = dot_prod(trinorm, norm2);
00324 ang3 = dot_prod(trinorm, norm3);
00325 if ( ((ang1 >= 0.0) || (ang2 >= 0.0) || (ang3 >= 0.0)) &&
00326 ((ang1 <= 0.0) || (ang2 <= 0.0) || (ang3 <= 0.0)) ) {
00327 degenerate_triangles++;
00328 return;
00329 }
00330
00331
00332
00333 if ( (c1[0] == c2[0]) && (c1[0] == c3[0]) &&
00334 (c1[1] == c2[1]) && (c1[1] == c3[1]) &&
00335 (c1[2] == c2[2]) && (c1[2] == c3[2]) ) {
00336 fprintf(outfile, "VMD_triangle(");
00337 fprintf(outfile, "<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,",
00338 vec1[0], vec1[1], -vec1[2], vec2[0], vec2[1], -vec2[2],
00339 vec3[0], vec3[1], -vec3[2]);
00340 fprintf(outfile, "<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,",
00341 norm1[0], norm1[1], -norm1[2], norm2[0], norm2[1], -norm2[2],
00342 norm3[0], norm3[1], -norm3[2]);
00343 fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
00344 c1[0], c1[1], c1[2], 1 - mat_opacity);
00345 }
00346 else {
00347 fprintf(outfile, "VMD_tricolor(");
00348 fprintf(outfile, "<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,",
00349 vec1[0], vec1[1], -vec1[2], vec2[0], vec2[1], -vec2[2],
00350 vec3[0], vec3[1], -vec3[2]);
00351 fprintf(outfile, "<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,<%.8g,%.8g,%.8g>,",
00352 norm1[0], norm1[1], -norm1[2], norm2[0], norm2[1], -norm2[2],
00353 norm3[0], norm3[1], -norm3[2]);
00354 fprintf(outfile, "rgbt<%.3f,%.3f,%.3f,%.3f>,rgbt<%.3f,%.3f,%.3f,%.3f>,rgbt<%.3f,%.3f,%.3f,%.3f>)\n",
00355 c1[0], c1[1], c1[2], 1 - mat_opacity, c2[0], c2[1], c2[2],
00356 1 - mat_opacity, c3[0], c3[1], c3[2], 1 - mat_opacity);
00357 }
00358 }
00359
00360
00361 void POV3DisplayDevice::trimesh_c4n3v3(int numverts, float *cnv,
00362 int numfacets, int *facets) {
00363 float (*vert)[3], (*norm)[3], (*color)[3], prev_color[3];
00364 int i, ind, v0, v1, v2, *c_index, curr_index;
00365
00366
00367
00368 if (clip_on[2]) {
00369 fprintf(outfile, "intersection {\n");
00370 }
00371 fprintf(outfile, "mesh2 {\n");
00372
00373
00374
00375
00376 vert = new float[numfacets * 3][3];
00377 norm = new float[numfacets * 3][3];
00378 color = new float[numfacets * 3][3];
00379 c_index = new int[numfacets * 3];
00380 curr_index = -1;
00381 prev_color[0] = -1;
00382 prev_color[1] = -1;
00383 prev_color[2] = -1;
00384
00385 for (i = 0; i < numfacets; i++) {
00386 ind = i * 3;
00387 v0 = facets[ind ] * 10;
00388 v1 = facets[ind + 1] * 10;
00389 v2 = facets[ind + 2] * 10;
00390
00391
00392 transMat.top().multpoint3d(cnv + v0 + 7, vert[ind ]);
00393 transMat.top().multpoint3d(cnv + v1 + 7, vert[ind + 1]);
00394 transMat.top().multpoint3d(cnv + v2 + 7, vert[ind + 2]);
00395
00396
00397 transMat.top().multnorm3d(cnv + v0 + 4, norm[ind ]);
00398 transMat.top().multnorm3d(cnv + v1 + 4, norm[ind + 1]);
00399 transMat.top().multnorm3d(cnv + v2 + 4, norm[ind + 2]);
00400
00401 #if defined(POVRAY_BRAIN_DAMAGE_WORKAROUND)
00402 vert[ind ][0] *= POVRAY_SCALEHACK;
00403 vert[ind ][1] *= POVRAY_SCALEHACK;
00404 vert[ind ][2] *= POVRAY_SCALEHACK;
00405 vert[ind + 1][0] *= POVRAY_SCALEHACK;
00406 vert[ind + 1][1] *= POVRAY_SCALEHACK;
00407 vert[ind + 1][2] *= POVRAY_SCALEHACK;
00408 vert[ind + 2][0] *= POVRAY_SCALEHACK;
00409 vert[ind + 2][1] *= POVRAY_SCALEHACK;
00410 vert[ind + 2][2] *= POVRAY_SCALEHACK;
00411 #endif
00412
00413
00414
00415
00416
00417 if (memcmp(prev_color, (cnv + v0), 3*sizeof(float)) != 0) {
00418 curr_index++;
00419 memcpy(color[curr_index], (cnv + v0), 3*sizeof(float));
00420 memcpy(prev_color, (cnv + v0), 3*sizeof(float));
00421 }
00422 c_index[ind] = curr_index;
00423
00424 if (memcmp(prev_color, (cnv + v1), 3*sizeof(float)) != 0) {
00425 curr_index++;
00426 memcpy(color[curr_index], (cnv + v1), 3*sizeof(float));
00427 memcpy(prev_color, (cnv + v1), 3*sizeof(float));
00428 }
00429 c_index[ind+1] = curr_index;
00430
00431 if (memcmp(prev_color, (cnv + v2), 3*sizeof(float)) != 0) {
00432 curr_index++;
00433 memcpy(color[curr_index], (cnv + v2), 3*sizeof(float));
00434 memcpy(prev_color, (cnv + v2), 3*sizeof(float));
00435 }
00436 c_index[ind+2] = curr_index;
00437 }
00438
00439
00440 fprintf(outfile, " vertex_vectors {\n");
00441 fprintf(outfile, " %d,\n", numfacets * 3);
00442 for (i = 0; i < (numfacets * 3); i++) {
00443 fprintf(outfile, " <%.4f,%.4f,%.4f>,\n",
00444 vert[i][0], vert[i][1], -vert[i][2]);
00445 }
00446 fprintf(outfile, " }\n");
00447
00448
00449 fprintf(outfile, " normal_vectors {\n");
00450 fprintf(outfile, " %d,\n", numfacets * 3);
00451 for (i = 0; i < (numfacets * 3); i++) {
00452 fprintf(outfile, " <%.4f,%.4f,%.4f>,\n",
00453 norm[i][0], norm[i][1], -norm[i][2]);
00454 }
00455 fprintf(outfile, " }\n");
00456
00457
00458 fprintf(outfile, " texture_list {\n");
00459 fprintf(outfile, " %d,\n", curr_index+1);
00460 for (i = 0; i <= curr_index; i++) {
00461 fprintf(outfile, " VMDC(<%.3f,%.3f,%.3f,%.3f>)\n",
00462 color[i][0], color[i][1], color[i][2], 1 - mat_opacity);
00463 }
00464 fprintf(outfile, " }\n");
00465
00466
00467 fprintf(outfile, " face_indices {\n");
00468 fprintf(outfile, " %d\n", numfacets);
00469 for (i = 0; i < numfacets; i++) {
00470 ind = i * 3;
00471
00472
00473 if ((c_index[ind] == c_index[ind+1]) && (c_index[ind] == c_index[ind+2])) {
00474
00475
00476 fprintf(outfile, " <%d,%d,%d>,%d\n",
00477 ind, ind + 1, ind + 2, c_index[ind]);
00478 }
00479 else {
00480 fprintf(outfile, " <%d,%d,%d>,%d,%d,%d\n",
00481 ind, ind + 1, ind + 2,
00482 c_index[ind], c_index[ind+1], c_index[ind+2]);
00483 }
00484 }
00485 fprintf(outfile, " }\n");
00486
00487
00488 fprintf(outfile, " inside_vector <0, 0, 1>\n");
00489 if (clip_on[1]) {
00490 #if defined(POVRAY_BRAIN_DAMAGE_WORKAROUND)
00491 fprintf(outfile, " clipped_by { VMD_scaledclip[1] }\n");
00492 #else
00493 fprintf(outfile, " clipped_by { VMD_clip[1] }\n");
00494 #endif
00495 }
00496 if (!shadows_enabled())
00497 fprintf(outfile, " no_shadow\n");
00498
00499 #if defined(POVRAY_BRAIN_DAMAGE_WORKAROUND)
00500 Matrix4 hackmatrix;
00501 hackmatrix.identity();
00502 hackmatrix.scale(1.0f / POVRAY_SCALEHACK);
00503 const float *trans = hackmatrix.mat;
00504 fprintf(outfile, "matrix < \n");
00505 fprintf(outfile, " %f, %f, %f,\n", trans[ 0], trans[ 1], trans[ 2]);
00506 fprintf(outfile, " %f, %f, %f,\n", trans[ 4], trans[ 5], trans[ 6]);
00507 fprintf(outfile, " %f, %f, %f,\n", trans[ 8], trans[ 9], trans[10]);
00508 fprintf(outfile, " %f, %f, %f \n", trans[12], trans[13], trans[14]);
00509 fprintf(outfile, "> ");
00510 #endif
00511
00512 fprintf(outfile, "}\n");
00513
00514 if (clip_on[2]) {
00515 fprintf(outfile, " VMD_clip[2]\n");
00516 if (!shadows_enabled())
00517 fprintf(outfile, " no_shadow\n");
00518 fprintf(outfile, "}\n");
00519 }
00520
00521 delete [] vert;
00522 delete [] norm;
00523 delete [] color;
00524 delete [] c_index;
00525 }
00526
00527
00528 void POV3DisplayDevice::tristrip(int numverts, const float *cnv,
00529 int numstrips, const int *vertsperstrip,
00530 const int *facets) {
00531 int strip, v, i, numfacets;
00532 float (*vert)[3], (*norm)[3], (*color)[3];
00533
00534
00535
00536
00537
00538 int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
00539
00540
00541
00542 if (clip_on[2]) {
00543 fprintf(outfile, "intersection {\n");
00544 }
00545 fprintf(outfile, "mesh2 {\n");
00546
00547
00548
00549
00550 vert = new float[numverts][3];
00551 norm = new float[numverts][3];
00552 color = new float[numverts][3];
00553
00554 for (i = 0; i < numverts; i++) {
00555 transMat.top().multpoint3d(cnv + i*10 + 7, vert[i]);
00556 transMat.top().multnorm3d(cnv + i*10 + 4, norm[i]);
00557
00558 #if defined(POVRAY_BRAIN_DAMAGE_WORKAROUND)
00559 vert[i][0] *= POVRAY_SCALEHACK;
00560 vert[i][1] *= POVRAY_SCALEHACK;
00561 vert[i][2] *= POVRAY_SCALEHACK;
00562 #endif
00563
00564 memcpy(color[i], cnv + i*10, 3*sizeof(float));
00565 }
00566
00567
00568 fprintf(outfile, " vertex_vectors {\n");
00569 fprintf(outfile, " %d,\n", numverts);
00570 for (i = 0; i < numverts; i++) {
00571 fprintf(outfile, " <%.4f,%.4f,%.4f>,\n",
00572 vert[i][0], vert[i][1], -vert[i][2]);
00573 }
00574 fprintf(outfile, " }\n");
00575
00576
00577 fprintf(outfile, " normal_vectors {\n");
00578 fprintf(outfile, " %d,\n", numverts);
00579 for (i = 0; i < numverts; i++) {
00580 fprintf(outfile, " <%.4f,%.4f,%.4f>,\n",
00581 norm[i][0], norm[i][1], -norm[i][2]);
00582 }
00583 fprintf(outfile, " }\n");
00584
00585
00586 fprintf(outfile, " texture_list {\n");
00587 fprintf(outfile, " %d,\n", numverts);
00588 for (i = 0; i < numverts; i++) {
00589 fprintf(outfile, " VMDC(<%.3f,%.3f,%.3f,%.3f>)\n",
00590 color[i][0], color[i][1], color[i][2], 1 - mat_opacity);
00591 }
00592 fprintf(outfile, " }\n");
00593
00594
00595 numfacets = 0;
00596 for (strip = 0; strip < numstrips; strip++) {
00597 numfacets += (vertsperstrip[strip] - 2);
00598 }
00599
00600
00601 v = 0;
00602 fprintf(outfile, " face_indices {\n");
00603 fprintf(outfile, " %d\n", numfacets);
00604 for (strip = 0; strip < numstrips; strip++) {
00605 for (i = 0; i < (vertsperstrip[strip] - 2); i++) {
00606 fprintf(outfile, " <%d,%d,%d>,%d,%d,%d\n",
00607 facets[v + (stripaddr[i & 0x01][0])],
00608 facets[v + (stripaddr[i & 0x01][1])],
00609 facets[v + (stripaddr[i & 0x01][2])],
00610 facets[v + (stripaddr[i & 0x01][0])],
00611 facets[v + (stripaddr[i & 0x01][1])],
00612 facets[v + (stripaddr[i & 0x01][2])] );
00613 v++;
00614 }
00615 v += 2;
00616 }
00617 fprintf(outfile, " }\n");
00618
00619
00620 fprintf(outfile, " inside_vector <0, 0, 1>\n");
00621 if (clip_on[1]) {
00622 #if defined(POVRAY_BRAIN_DAMAGE_WORKAROUND)
00623 fprintf(outfile, " clipped_by { VMD_scaledclip[1] }\n");
00624 #else
00625 fprintf(outfile, " clipped_by { VMD_clip[1] }\n");
00626 #endif
00627 }
00628
00629 #if defined(POVRAY_BRAIN_DAMAGE_WORKAROUND)
00630 Matrix4 hackmatrix;
00631 hackmatrix.identity();
00632 hackmatrix.scale(1.0f / POVRAY_SCALEHACK);
00633 const float *trans = hackmatrix.mat;
00634 fprintf(outfile, "matrix < \n");
00635 fprintf(outfile, " %f, %f, %f,\n", trans[ 0], trans[ 1], trans[ 2]);
00636 fprintf(outfile, " %f, %f, %f,\n", trans[ 4], trans[ 5], trans[ 6]);
00637 fprintf(outfile, " %f, %f, %f,\n", trans[ 8], trans[ 9], trans[10]);
00638 fprintf(outfile, " %f, %f, %f \n", trans[12], trans[13], trans[14]);
00639 fprintf(outfile, "> ");
00640 #endif
00641
00642 if (!shadows_enabled())
00643 fprintf(outfile, " no_shadow\n");
00644 fprintf(outfile, "}\n");
00645
00646 if (clip_on[2]) {
00647 fprintf(outfile, " VMD_clip[2]\n");
00648 if (!shadows_enabled())
00649 fprintf(outfile, " no_shadow\n");
00650 fprintf(outfile, "}\n");
00651 }
00652
00653 delete [] vert;
00654 delete [] norm;
00655 delete [] color;
00656 }
00657
00658
00659 void POV3DisplayDevice::comment(const char *s) {
00660 fprintf (outfile, "// %s\n", s);
00661 }
00662
00664
00665 void POV3DisplayDevice::write_header() {
00666 long myXsize;
00667 float zDirection;
00668
00669
00670
00671 myXsize = xSize;
00672
00673
00674
00675
00676 fprintf(outfile, "// \n");
00677 fprintf(outfile, "// Molecular graphics export from VMD %s\n", VMDVERSION);
00678 fprintf(outfile, "// http://www.ks.uiuc.edu/Research/vmd/\n");
00679 fprintf(outfile, "// Requires POV-Ray 3.5 or later\n");
00680 fprintf(outfile, "// \n");
00681
00682 fprintf(outfile, "// POV 3.x input script : %s \n", my_filename);
00683 fprintf(outfile, "// try povray +W%ld +H%ld -I%s ", myXsize, ySize, my_filename);
00684 fprintf(outfile, "-O%s.tga +P +X +A +FT +C", my_filename);
00685
00686
00687 if (whichEye != DisplayDevice::NOSTEREO) fprintf(outfile, " -UV");
00688 fprintf(outfile, "\n");
00689
00690 #if 0
00691 msgInfo << "Default povray command line should be:" << sendmsg;
00692
00693 msgInfo << " povray +W" << myXsize << " +H" << ySize << " -I" << my_filename
00694 << " -O" << my_filename << ".tga +P +X +A +FT +C";
00695 if (whichEye != DisplayDevice::NOSTEREO) msgInfo << " -UV";
00696 msgInfo << sendmsg;
00697 #endif
00698
00699
00700
00701 fprintf(outfile, "#if (version < 3.5) \n");
00702 fprintf(outfile, "#error \"VMD POV3DisplayDevice has been compiled for POV-Ray 3.5 or above.\\nPlease upgrade POV-Ray or recompile VMD.\"\n");
00703 fprintf(outfile, "#end \n");
00704
00705
00706 fprintf(outfile, "#declare VMD_clip_on=array[3] {0, 0, 0};\n");
00707 fprintf(outfile, "#declare VMD_clip=array[3];\n");
00708 fprintf(outfile, "#declare VMD_scaledclip=array[3];\n");
00709 fprintf(outfile, "#declare VMD_line_width=%.4f;\n",
00710 ((float)lineWidth)*DEFAULT_RADIUS);
00711
00712
00713
00714
00715
00716
00717 fprintf(outfile, "#macro VMDC ( C1 )\n");
00718 fprintf(outfile, " texture { pigment { rgbt C1 }}\n");
00719 fprintf(outfile, "#end\n");
00720
00721
00722 fprintf(outfile, "#macro VMD_point (P1, R1, C1)\n");
00723 fprintf(outfile, " #local T = texture { finish { ambient 1.0 diffuse 0.0 phong 0.0 specular 0.0 } pigment { C1 } }\n");
00724 fprintf(outfile, " #if(VMD_clip_on[2])\n");
00725 fprintf(outfile, " intersection {\n");
00726 fprintf(outfile, " sphere {P1, R1 texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00727 fprintf(outfile, " VMD_clip[2]\n");
00728 fprintf(outfile, " }\n #else\n");
00729 fprintf(outfile, " sphere {P1, R1 texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00730 fprintf(outfile, " #end\n");
00731 fprintf(outfile, "#end\n");
00732
00733
00734 fprintf(outfile, "#macro VMD_line (P1, P2, C1)\n");
00735 fprintf(outfile, " #local T = texture { finish { ambient 1.0 diffuse 0.0 phong 0.0 specular 0.0 } pigment { C1 } }\n");
00736 fprintf(outfile, " #if(VMD_clip_on[2])\n");
00737 fprintf(outfile, " intersection {\n");
00738 fprintf(outfile, " cylinder {P1, P2, VMD_line_width texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00739 fprintf(outfile, " VMD_clip[2]\n");
00740 fprintf(outfile, " }\n #else\n");
00741 fprintf(outfile, " cylinder {P1, P2, VMD_line_width texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00742 fprintf(outfile, " #end\n");
00743 fprintf(outfile, "#end\n");
00744
00745
00746 fprintf(outfile, "#macro VMD_sphere (P1, R1, C1)\n");
00747 fprintf(outfile, " #local T = texture { pigment { C1 } }\n");
00748 fprintf(outfile, " #if(VMD_clip_on[2])\n");
00749 fprintf(outfile, " intersection {\n");
00750 fprintf(outfile, " sphere {P1, R1 texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00751 fprintf(outfile, " VMD_clip[2]\n");
00752 fprintf(outfile, " }\n #else\n");
00753 fprintf(outfile, " sphere {P1, R1 texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00754 fprintf(outfile, " #end\n");
00755 fprintf(outfile, "#end\n");
00756
00757
00758 fprintf(outfile, "#macro VMD_cylinder (P1, P2, R1, C1, O1)\n");
00759 fprintf(outfile, " #local T = texture { pigment { C1 } }\n");
00760 fprintf(outfile, " #if(VMD_clip_on[2])\n");
00761 fprintf(outfile, " intersection {\n");
00762 fprintf(outfile, " cylinder {P1, P2, R1 #if(O1) open #end texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00763 fprintf(outfile, " VMD_clip[2]\n");
00764 fprintf(outfile, " }\n #else\n");
00765 fprintf(outfile, " cylinder {P1, P2, R1 #if(O1) open #end texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00766 fprintf(outfile, " #end\n");
00767 fprintf(outfile, "#end\n");
00768
00769
00770 fprintf(outfile, "#macro VMD_cone (P1, P2, R1, C1)\n");
00771 fprintf(outfile, " #local T = texture { pigment { C1 } }\n");
00772 fprintf(outfile, " #if(VMD_clip_on[2])\n");
00773 fprintf(outfile, " intersection {\n");
00774 fprintf(outfile, " cone {P1, R1, P2, VMD_line_width texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00775 fprintf(outfile, " VMD_clip[2]\n");
00776 fprintf(outfile, " }\n #else\n");
00777 fprintf(outfile, " cone {P1, R1, P2, VMD_line_width texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00778 fprintf(outfile, " #end\n");
00779 fprintf(outfile, "#end\n");
00780
00781
00782
00783 fprintf(outfile, "#macro VMD_triangle (P1, P2, P3, N1, N2, N3, C1)\n");
00784 fprintf(outfile, " #local T = texture { pigment { C1 } }\n");
00785 fprintf(outfile, " smooth_triangle {P1, N1, P2, N2, P3, N3 texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00786 fprintf(outfile, "#end\n");
00787
00788
00789
00790 fprintf(outfile, "#macro VMD_tricolor (P1, P2, P3, N1, N2, N3, C1, C2, C3)\n");
00791 fprintf(outfile, " #local NX = P2-P1;\n");
00792 fprintf(outfile, " #local NY = P3-P1;\n");
00793 fprintf(outfile, " #local NZ = vcross(NX, NY);\n");
00794 fprintf(outfile, " #local T = texture { pigment {\n");
00795
00796
00797 fprintf(outfile, " average pigment_map {\n");
00798 fprintf(outfile, " [1 gradient x color_map {[0 rgb 0] [1 C2*3]}]\n");
00799 fprintf(outfile, " [1 gradient y color_map {[0 rgb 0] [1 C3*3]}]\n");
00800 fprintf(outfile, " [1 gradient z color_map {[0 rgb 0] [1 C1*3]}]\n");
00801 fprintf(outfile, " }\n");
00802
00803
00804 fprintf(outfile, " matrix <1.01,0,1,0,1.01,1,0,0,1,-.002,-.002,-1>\n");
00805 fprintf(outfile, " matrix <NX.x,NX.y,NX.z,NY.x,NY.y,NY.z,NZ.x,NZ.y,NZ.z,P1.x,P1.y,P1.z>\n");
00806 fprintf(outfile, " } }\n");
00807
00808 fprintf(outfile, " smooth_triangle {P1, N1, P2, N2, P3, N3 texture {T} #if(VMD_clip_on[1]) clipped_by {VMD_clip[1]} #end %s}\n", (shadows_enabled()) ? "" : "no_shadow");
00809 fprintf(outfile, "#end\n");
00810
00811
00812
00813
00814
00815
00816 switch (projection()) {
00817
00818 case DisplayDevice::ORTHOGRAPHIC:
00819
00820 fprintf(outfile, "camera {\n");
00821 fprintf(outfile, " orthographic\n");
00822 fprintf(outfile, " location <%.4f, %.4f, %.4f>\n",
00823 eyePos[0], eyePos[1], -eyePos[2]);
00824 fprintf(outfile, " look_at <%.4f, %.4f, %.4f>\n",
00825 eyeDir[0], eyeDir[1], -eyeDir[2]);
00826 fprintf(outfile, " up <0.0000, %.4f, 0.0000>\n", vSize / 2.0f);
00827 fprintf(outfile, " right <%.4f, 0.0000, 0.0000>\n", Aspect * vSize / 2.0f);
00828 fprintf(outfile, "}\n");
00829
00830 break;
00831
00832 case DisplayDevice::PERSPECTIVE:
00833 default:
00834
00835 if (whichEye != DisplayDevice::NOSTEREO) {
00836 if (whichEye == DisplayDevice::LEFTEYE)
00837 fprintf(outfile, "// Stereo rendering enabled. Now rendering left eye.\n");
00838 else
00839 fprintf(outfile, "// Stereo rendering enabled. Now rendering right eye.\n");
00840
00841 fprintf(outfile, "// POV-Ray may give you a warning about non-perpendicular\n");
00842 fprintf(outfile, "// camera vectors; this is a result of the stereo rendering.\n");
00843 fprintf(outfile, "#warning \"You may ignore the following warning about "
00844 "nonperpendicular camera vectors.\"\n");
00845 }
00846
00847 fprintf(outfile, "camera {\n");
00848 fprintf(outfile, " up <0, %.4f, 0>\n", vSize);
00849 fprintf(outfile, " right <%.4f, 0, 0>\n", Aspect * vSize);
00850 fprintf(outfile, " location <%.4f, %.4f, %.4f>\n",
00851 eyePos[0], eyePos[1], -eyePos[2]);
00852 fprintf(outfile, " look_at <%.4f, %.4f, %.4f>\n",
00853 eyePos[0] + eyeDir[0],
00854 eyePos[1] + eyeDir[1],
00855 -(eyePos[2] + eyeDir[2]));
00856
00857
00858
00859
00860
00861 zDirection = eyePos[2] - zDist;
00862 if (zDirection < 0) {
00863 fprintf(outfile, " direction <%.4f, %.4f, %.4f>\n",
00864 -eyePos[0], -eyePos[1], -zDirection);
00865 fprintf(outfile, " sky <0, -1, 0>\n");
00866 }
00867 else {
00868 fprintf(outfile, " direction <%.4f, %.4f, %.4f>\n",
00869 -eyePos[0], -eyePos[1], zDirection);
00870 }
00871
00872 fprintf(outfile, "}\n");
00873
00874 break;
00875
00876 }
00877
00878
00879 int i;
00880 for (i=0;i<DISP_LIGHTS;i++) {
00881 if (lightState[i].on) {
00882
00883 fprintf(outfile, "light_source { \n <%.4f, %.4f, %.4f> \n",
00884 lightState[i].pos[0], lightState[i].pos[1],
00885 -lightState[i].pos[2]);
00886 fprintf(outfile, " color rgb<%.3f, %.3f, %.3f> \n",
00887 lightState[i].color[0], lightState[i].color[1],
00888 lightState[i].color[2]);
00889 fprintf(outfile, " parallel \n point_at <0.0, 0.0, 0.0> \n}\n");
00890 }
00891 }
00892
00893
00894
00895 fprintf(outfile, "background {\n color rgb<%.3f, %.3f, %.3f>\n}\n",
00896 backColor[0], backColor[1], backColor[2]);
00897
00898
00899 if (backgroundmode == 1) {
00900 fprintf(outfile, "\n");
00901 fprintf(outfile, "sky_sphere {\n");
00902 fprintf(outfile, " pigment {\n");
00903 fprintf(outfile, " gradient y\n");
00904 fprintf(outfile, " color_map {\n");
00905 fprintf(outfile, " [ 0.0 color rgb<%.3f, %.3f, %.3f> ]\n",
00906 backgradientbotcolor[0], backgradientbotcolor[1], backgradientbotcolor[2]);
00907 fprintf(outfile, " [ 1.0 color rgb<%.3f, %.3f, %.3f> ]\n",
00908 backgradienttopcolor[0], backgradienttopcolor[1], backgradienttopcolor[2]);
00909 fprintf(outfile, " }\n");
00910 fprintf(outfile, " scale 2\n");
00911 fprintf(outfile, " translate -1\n");
00912 fprintf(outfile, " }\n");
00913 fprintf(outfile, "}\n");
00914 fprintf(outfile, "\n");
00915 }
00916
00917
00918 if (cueingEnabled && (get_cue_density() >= 1e-4)) {
00919 fprintf(outfile, "fog {\n");
00920
00921 switch (cueMode) {
00922 case CUE_EXP2:
00923 case CUE_LINEAR:
00924 case CUE_EXP:
00925
00926
00927 fprintf(outfile, " distance %.4f \n",
00928 (get_cue_density() >= 1e4) ? 1e-4 : 1.0/get_cue_density() );
00929 fprintf(outfile, " fog_type 1 \n");
00930 break;
00931
00932 case NUM_CUE_MODES:
00933
00934 break;
00935 }
00936
00937
00938 fprintf(outfile, " color rgb<%.3f, %.3f, %.3f> \n",
00939 backColor[0], backColor[1], backColor[2] );
00940 fprintf(outfile, "} \n");
00941 }
00942 }
00943
00944 void POV3DisplayDevice::write_trailer(void){
00945 fprintf(outfile, "// End of POV-Ray 3.x generation \n");
00946
00947 if (degenerate_cones != 0) {
00948 msgWarn << "Skipped " << degenerate_cones
00949 << " degenerate cones" << sendmsg;
00950 }
00951 if (degenerate_cylinders != 0) {
00952 msgWarn << "Skipped " << degenerate_cylinders
00953 << " degenerate cylinders" << sendmsg;
00954 }
00955 if (degenerate_triangles != 0) {
00956 msgWarn << "Skipped " << degenerate_triangles
00957 << " degenerate triangles" << sendmsg;
00958 }
00959
00960 reset_vars();
00961 }
00962
00963
00964 void POV3DisplayDevice::write_materials(void) {
00965 if (old_materialIndex != materialIndex) {
00966
00967 old_materialIndex = materialIndex;
00968
00969 fprintf(outfile, "#default { texture {\n");
00970 fprintf(outfile, " finish { ambient %.3f diffuse %.3f",
00971 mat_ambient, mat_diffuse);
00972 fprintf(outfile, " phong 0.1 phong_size %.3f specular %.3f }\n",
00973 mat_shininess, mat_specular);
00974 fprintf(outfile, "} }\n");
00975 }
00976 }
00977
00978
00979 void POV3DisplayDevice::start_clipgroup(void) {
00980 int i, num_clipplanes[3], mode;
00981 float pov_clip_center[3], pov_clip_distance[VMD_MAX_CLIP_PLANE];
00982 float pov_clip_normal[VMD_MAX_CLIP_PLANE][3];
00983
00984 write_materials();
00985
00986 memset(num_clipplanes, 0, 3*sizeof(int));
00987 for (i = 0; i < VMD_MAX_CLIP_PLANE; i++) {
00988 if (clip_mode[i] != 0) {
00989
00990 num_clipplanes[clip_mode[i]]++;
00991
00992
00993 (transMat.top()).multpoint3d(clip_center[i], pov_clip_center);
00994
00995
00996 (transMat.top()).multnorm3d(clip_normal[i], pov_clip_normal[i]);
00997 vec_negate(pov_clip_normal[i], pov_clip_normal[i]);
00998
00999
01000
01001 pov_clip_distance[i] = dot_prod(pov_clip_normal[i], pov_clip_center);
01002 }
01003 }
01004
01005
01006 for (mode = 1; mode < 3; mode++) {
01007 if (num_clipplanes[mode] > 0) {
01008
01009
01010 clip_on[mode] = 1;
01011
01012
01013
01014 fprintf(outfile, "#declare VMD_clip_on[%d]=1;\n", mode);
01015
01016 if (num_clipplanes[mode] == 1) {
01017 for (i = 0; i < VMD_MAX_CLIP_PLANE; i++) {
01018 if (clip_mode[i] == mode) {
01019 if (mode == 2) {
01020
01021 fprintf(outfile, "#declare VMD_clip[%d] = plane { <%.4f, %.4f, %.4f>, %.4f texture { pigment { rgbt<%.3f, %.3f, %.3f, %.3f> } } }\n",
01022 mode, pov_clip_normal[i][0], pov_clip_normal[i][1],
01023 -pov_clip_normal[i][2], pov_clip_distance[i],
01024 clip_color[i][0], clip_color[i][1], clip_color[i][2],
01025 1 - mat_opacity);
01026 } else {
01027
01028 fprintf(outfile, "#declare VMD_clip[%d] = plane { <%.4f, %.4f, %.4f>, %.4f }\n",
01029 mode, pov_clip_normal[i][0], pov_clip_normal[i][1],
01030 -pov_clip_normal[i][2], pov_clip_distance[i]);
01031
01032 #if defined(POVRAY_BRAIN_DAMAGE_WORKAROUND)
01033
01034
01035 fprintf(outfile, "#declare VMD_scaledclip[%d] = plane { <%.4f, %.4f, %.4f>, %.4f }\n",
01036 mode, pov_clip_normal[i][0], pov_clip_normal[i][1], -pov_clip_normal[i][2],
01037 pov_clip_distance[i] * POVRAY_SCALEHACK);
01038 #endif
01039 }
01040 }
01041 }
01042 }
01043
01044
01045 else {
01046 fprintf(outfile, "#declare VMD_clip[%d] = intersection {\n", mode);
01047 for (i = 0; i < VMD_MAX_CLIP_PLANE; i++) {
01048 if (clip_mode[i] == mode) {
01049 if (mode == 2) {
01050
01051 fprintf(outfile, " plane { <%.4f, %.4f, %.4f>, %.4f texture { pigment { rgbt<%.3f, %.3f, %.3f, %.3f> } } }\n",
01052 pov_clip_normal[i][0], pov_clip_normal[i][1],
01053 -pov_clip_normal[i][2], pov_clip_distance[i],
01054 clip_color[i][0], clip_color[i][1], clip_color[i][2],
01055 1 - mat_opacity);
01056 } else {
01057
01058 fprintf(outfile, " plane { <%.4f, %.4f, %.4f>, %.4f }\n",
01059 pov_clip_normal[i][0], pov_clip_normal[i][1],
01060 -pov_clip_normal[i][2], pov_clip_distance[i]);
01061 }
01062 }
01063 }
01064 fprintf(outfile, "}\n");
01065
01066 #if defined(POVRAY_BRAIN_DAMAGE_WORKAROUND)
01067 fprintf(outfile, "#declare VMD_scaledclip[%d] = intersection {\n", mode);
01068 for (i = 0; i < VMD_MAX_CLIP_PLANE; i++) {
01069 if (clip_mode[i] == mode) {
01070 if (mode == 2) {
01071
01072 fprintf(outfile, " plane { <%.4f, %.4f, %.4f>, %.4f texture { pigment { rgbt<%.3f, %.3f, %.3f, %.3f> } } }\n",
01073 pov_clip_normal[i][0], pov_clip_normal[i][1],
01074 -pov_clip_normal[i][2], pov_clip_distance[i] * POVRAY_SCALEHACK,
01075 clip_color[i][0], clip_color[i][1], clip_color[i][2],
01076 1 - mat_opacity);
01077 } else {
01078
01079 fprintf(outfile, " plane { <%.4f, %.4f, %.4f>, %.4f }\n",
01080 pov_clip_normal[i][0], pov_clip_normal[i][1],
01081 -pov_clip_normal[i][2], pov_clip_distance[i] * POVRAY_SCALEHACK);
01082 }
01083 }
01084 }
01085 fprintf(outfile, "}\n");
01086 #endif
01087
01088
01089 }
01090
01091 }
01092 }
01093 }
01094
01095 void POV3DisplayDevice::end_clipgroup(void) {
01096 int i;
01097 for (i = 0; i < 3; i++) {
01098 if (clip_on[i]) {
01099 fprintf(outfile, "#declare VMD_clip_on[%d]=0;\n", i);
01100 clip_on[i] = 0;
01101 }
01102 }
01103 }
01104
01105 void POV3DisplayDevice::set_line_width(int new_width) {
01106
01107
01108 {
01109 lineWidth = new_width;
01110 fprintf(outfile, "#declare VMD_line_width=%.4f;\n",
01111 ((float)new_width)*DEFAULT_RADIUS);
01112 }
01113 }
01114