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