// povrays.cmd // Surface Evolver command for producing POV-Ray input file. // Output is to stdout, so redirect to desired file. // Programmer: Ken Brakke, brakke@susqu.edu, http://www.susqu.edu/brakke // Like povray.cmd, but with vertex normals for a smooth surface. // A normal at a vertex of a facet is the average of all adjacent // facet normals within a certain angle of the original facet normal // Usage: // Use the "show edge where ..." command to declare which // edges are to be depicted as thin cylinders. // Set "edge_radius" to desired radius of edge cylinders. // Set "critcos" to critical cosine of angle for facets // regarded as smoothly joined. // Run "povrays" with output redirected to a file, e.g. // Enter command: povrays >>> "something.pov" edge_radius := 0.003; // adjust this for desired radius of edge cylinders critcos := 0.8; // criterion for vertex normal averaging. procedure print_color(integer ev_color) { if ( ev_color == white ) then printf " t_white " else if ( ev_color == black ) then printf " t_black " else if ( ev_color == blue) then printf " t_blue " else if ( ev_color == green ) then printf " t_green " else if ( ev_color == cyan ) then printf " t_cyan " else if ( ev_color == red ) then printf " t_red " else if ( ev_color == magenta ) then printf " t_magenta " else if ( ev_color == brown ) then printf " t_brown " else if ( ev_color == lightgray ) then printf " t_lightgray " else if ( ev_color == darkgray ) then printf " t_darkgray " else if ( ev_color == lightblue ) then printf " t_lightblue " else if ( ev_color == lightgreen ) then printf " t_lightgreen " else if ( ev_color == lightcyan ) then printf " t_lightcyan " else if ( ev_color == lightred ) then printf " t_lightred " else if ( ev_color == lightmagenta ) then printf " t_lightmagenta " else if ( ev_color == yellow ) then printf " t_yellow "; } povrays := { local ffx,ffy,ffz,ffnorm,vernum,nx,ny,nz,fffx,fffy,fffz,fffnorm; local costheta,nnorm; // Check assumptions if torus then { errprintf "Cannot run 'povrays' command in torus mode. Do 'detorus' first.\n"; abort; }; if symmetry_group then { errprintf "Cannot run 'povrays' command in symmetry group mode. Do 'detorus' first.\n"; abort; }; if space_dimension != 3 then { errprintf "The 'povrays' command must be run in three-dimensional space.\n"; abort; }; if surface_dimension == 1 then { errprintf "The 'povrays' command is not meant for the string model.\n"; abort; }; if simplex_representation then { errprintf "The 'povrays' command is not meant for the simplex model.\n"; abort; }; if lagrange_order >= 2 then { errprintf "The 'povrays' command is meant for the linear model, not quadratic or Lagrange.\n"; abort; }; if rgb_colors then { errprintf "The 'povrays' command does not do RGB colors; do rgb_colors off.\n"; abort; }; printf "// %s in POV-Ray format.\n\n",datafilename; printf "light_source { <0,0,300> color rgb <1,1,1> }\n"; printf "light_source { <100,0,0> color rgb <1,1,1> }\n"; printf "camera { location <12,0,0> sky <0,0,1> // right handed \n"; printf " up <0,0,1> right <1.3,0,0> look_at <0,0,0> angle 15 }\n"; printf "background { color <0.3,0.8,1.0> } // light blue\n\n"; printf "// Textures corresponding to Evolver colors\n\n"; printf "#declare t_black = texture { pigment { rgb <0.0,0.0,0.0> }}\n"; printf "#declare t_blue = texture { pigment { rgb <0.0,0.0,1.,> }}\n"; printf "#declare t_green = texture { pigment { rgb <0.0,1.,0.0,> }}\n"; printf "#declare t_cyan = texture { pigment { rgb <0.0,1.,1.,> }}\n"; printf "#declare t_red = texture { pigment { rgb <1.,0.0,0.0,> }}\n"; printf "#declare t_magenta = texture { pigment { rgb <1.,0.0,1.,> }}\n"; printf "#declare t_brown = texture { pigment { rgb <1.,0.5,0.,> }}\n"; printf "#declare t_lightgray = texture { pigment { rgb <.6,.6,.6,> }}\n"; printf "#declare t_darkgray = texture { pigment { rgb <.3,.3,.3,> }}\n"; printf "#declare t_lightblue = texture { pigment { rgb <.3,.8,1.,> }}\n"; printf "#declare t_lightgreen = texture { pigment { rgb <.5,1.,.5,> }}\n"; printf "#declare t_lightcyan = texture { pigment { rgb <.5,1.,1.,> }}\n"; printf "#declare t_lightred = texture { pigment { rgb <1.,.5,.5,> }}\n"; printf "#declare t_lightmagenta = texture { pigment { rgb <1.,.5,1.,> }}\n"; printf "#declare t_yellow = texture { pigment { rgb <1.,1.,.0,> }}\n"; printf "#declare t_white = texture { pigment { rgb <1.,1.,1.,> }}\n"; printf "\n//One overall object.\n"; printf "union {\n"; printf "// All facets in one big mesh object for efficiency.\n"; printf " mesh { \n"; foreach facet ff where show and color >= 0 do { printf " smooth_triangle { "; ffx := ff.x; ffy := ff.y; ffz := ff.z; ffnorm := sqrt(ffx^2 + ffy^2 + ffz^2); vernum := 1; while ( vernum <= 3 ) do { nx := 0; ny := 0; nz := 0; foreach ff.vertex[vernum].facet fff do { fffx := fff.x; fffy := fff.y; fffz := fff.z; fffnorm := sqrt(fffx^2 + fffy^2 + fffz^2); costheta := (fffx*ffx+fffy*ffy+fffz*ffz)/ffnorm/fffnorm; if ( costheta > critcos ) then { nx := nx + fffx/fffnorm; ny := ny + fffy/fffnorm; nz := nz + fffz/fffnorm; } else if ( costheta < -critcos ) then // in case nonorientable { nx := nx - fffx/fffnorm; ny := ny - fffy/fffnorm; nz := nz - fffz/fffnorm; } }; nnorm := sqrt(nx^2+ny^2+nz^2); if vernum > 1 then printf ","; printf "<%f,%f,%f>,<%f,%f,%f>", ff.vertex[vernum].x,ff.vertex[vernum].y,ff.vertex[vernum].z, nx/nnorm,ny/nnorm,nz/nnorm; vernum := vernum + 1; }; printf " texture {"; if view_matrix[1][1]*ffx + view_matrix[1][2]*ffy + view_matrix[1][3]*ffz > 0 then print_color(ff.frontcolor) else print_color(ff.backcolor); printf " } }\n"; }; printf " } // end of mesh object\n"; // Do desired edges printf "#declare edge_radius = %f;\n",edge_radius; foreach edge ee where ee.show do { printf "cylinder { <%f,%f,%f>,<%f,%f,%f> edge_radius texture {", ee.vertex[1].x,ee.vertex[1].y,ee.vertex[1].z, ee.vertex[2].x,ee.vertex[2].y,ee.vertex[2].z; print_color(ee.color); printf "} }\n"; }; // Windup printf "// overall viewing transformation\n"; printf " matrix < %f,%f,%f,\n", view_matrix[1][1],view_matrix[2][1],view_matrix[3][1]; printf " %f,%f,%f,\n", view_matrix[1][2],view_matrix[2][2],view_matrix[3][2]; printf " %f,%f,%f,\n", view_matrix[1][3],view_matrix[2][3],view_matrix[3][3]; printf " %f,%f,%f>\n", view_matrix[1][4],view_matrix[2][4],view_matrix[3][4]; printf " } // end of all objects\n"; } // End povrays.cmd // Usage: // Use the "show edge where ..." command to declare which // edges are to be depicted as thin cylinders. // Set "edge_radius" to desired radius of edge cylinders. // Set "critcos" to critical cosine of angle for facets // regarded as smoothly joined. // Run "povray" and redirect to desired file, e.g. // Enter command: povray >>> "something.pov" // Run "povrays" with output redirected to a file, e.g. // Enter command: povrays >>> "something.pov"