|
Graphviz
2.29.20120524.0446
|
00001 /* $Id: */ 00002 /* vim:set shiftwidth=8 ts=8: */ 00003 00004 /********************************************************** 00005 * Copyright (c) 2011 Andy Jeutter * 00006 * AKA HallerHarry at gmx.de * 00007 * All rights reserved. * 00008 **********************************************************/ 00009 00010 /************************************************************************* 00011 * This program and the accompanying materials 00012 * are made available under the terms of the Eclipse Public License v1.0 00013 * which accompanies this distribution, and is available at 00014 * http://www.eclipse.org/legal/epl-v10.html 00015 * 00016 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00017 *************************************************************************/ 00018 00019 #ifdef HAVE_CONFIG_H 00020 #define _GNU_SOURCE 00021 #include "config.h" 00022 #endif 00023 00024 #include <stdarg.h> 00025 #include <stdlib.h> 00026 #include <string.h> 00027 #include <ctype.h> 00028 #include <errno.h> 00029 00030 #include "macros.h" 00031 #include "const.h" 00032 00033 #include "gvplugin_render.h" 00034 #include "gvplugin_device.h" 00035 #include "gvio.h" 00036 #include "gvcint.h" 00037 00038 #define POV_VERSION \ 00039 "#version 3.6;\n" 00040 00041 #define POV_GLOBALS \ 00042 "global_settings { assumed_gamma 1.0 }\n" 00043 00044 #define POV_DEFAULT \ 00045 "#default { finish { ambient 0.1 diffuse 0.9 } }\n" 00046 00047 #define POV_INCLUDE \ 00048 "#include \"colors.inc\"\n"\ 00049 "#include \"textures.inc\"\n"\ 00050 "#include \"shapes.inc\"\n" 00051 00052 #define POV_LIGHT \ 00053 "light_source { <1500,3000,-2500> color White }\n" 00054 00055 #define POV_CAMERA \ 00056 "camera { location <%.3f , %.3f , %.3f>\n"\ 00057 " look_at <%.3f , %.3f , %.3f>\n"\ 00058 " right x * image_width / image_height\n"\ 00059 " angle %.3f\n"\ 00060 "}\n" 00061 00062 #define POV_SKY_AND_GND \ 00063 "//sky\n"\ 00064 "plane { <0, 1, 0>, 1 hollow\n"\ 00065 " texture {\n"\ 00066 " pigment { bozo turbulence 0.95\n"\ 00067 " color_map {\n"\ 00068 " [0.00 rgb <0.05, 0.20, 0.50>]\n"\ 00069 " [0.50 rgb <0.05, 0.20, 0.50>]\n"\ 00070 " [0.75 rgb <1.00, 1.00, 1.00>]\n"\ 00071 " [0.75 rgb <0.25, 0.25, 0.25>]\n"\ 00072 " [1.00 rgb <0.50, 0.50, 0.50>]\n"\ 00073 " }\n"\ 00074 " scale <1.00, 1.00, 1.50> * 2.50\n"\ 00075 " translate <0.00, 0.00, 0.00>\n"\ 00076 " }\n"\ 00077 " finish { ambient 1 diffuse 0 }\n"\ 00078 " }\n"\ 00079 " scale 10000\n"\ 00080 "}\n"\ 00081 "//mist\n"\ 00082 "fog { fog_type 2\n"\ 00083 " distance 50\n"\ 00084 " color rgb <1.00, 1.00, 1.00> * 0.75\n"\ 00085 " fog_offset 0.10\n"\ 00086 " fog_alt 1.50\n"\ 00087 " turbulence 1.75\n"\ 00088 "}\n"\ 00089 "//gnd\n"\ 00090 "plane { <0.00, 1.00, 0.00>, 0\n"\ 00091 " texture {\n"\ 00092 " pigment{ color rgb <0.25, 0.45, 0.00> }\n"\ 00093 " normal { bumps 0.75 scale 0.01 }\n"\ 00094 " finish { phong 0.10 }\n"\ 00095 " }\n"\ 00096 "}\n" 00097 00098 #define POV_BOX \ 00099 "box { <%.3f, %.3f, %.3f>, <%.3f, %.3f, %.3f>\n" 00100 00101 #define POV_SCALE1 \ 00102 "scale %.3f\n" 00103 00104 #define POV_SCALE3 \ 00105 "scale "POV_VECTOR3"\n" 00106 00107 #define POV_ROTATE \ 00108 "rotate "POV_VECTOR3"\n" 00109 00110 #define POV_TRANSLATE \ 00111 "translate"POV_VECTOR3"\n" 00112 00113 #define END \ 00114 "}\n" 00115 00116 #define POV_TORUS \ 00117 "torus { %.3f, %.3f\n" 00118 00119 #define POV_SPHERE_SWEEP \ 00120 "sphere_sweep {\n"\ 00121 " %s\n"\ 00122 " %d,\n" 00123 00124 #define POV_SPHERE \ 00125 "sphere {"POV_VECTOR3", 1.0\n" // center, radius 00126 00127 #define POV_TEXT \ 00128 "text {\n"\ 00129 " ttf \"%s\",\n"\ 00130 " \"%s\", %.3f, %.3f\n" 00131 00132 #define POV_DECLARE \ 00133 "#declare %s = %s;\n" 00134 00135 #define POV_OBJECT \ 00136 "object { %s }\n" 00137 00138 #define POV_VERBATIM \ 00139 "%s\n" 00140 00141 #define POV_DEBUG \ 00142 "#debug %s\n" 00143 00144 #define POV_POLYGON \ 00145 "polygon { %d,\n" 00146 00147 #define POV_VECTOR3 \ 00148 "<%9.3f, %9.3f, %9.3f>" 00149 00150 #define POV_PIGMENT_COLOR \ 00151 "pigment { color %s }\n" 00152 00153 #define POV_COLOR_NAME \ 00154 "%s transmit %.3f" 00155 00156 #define POV_COLOR_RGB \ 00157 "rgb"POV_VECTOR3" transmit %.3f" 00158 00159 //colors are taken from /usr/share/povray-3.6/include/colors.inc 00160 //list must be LANG_C sorted (all lower case) 00161 #define POV_COLORS \ 00162 "aquamarine",\ 00163 "bakerschoc",\ 00164 "black",\ 00165 "blue",\ 00166 "blueviolet",\ 00167 "brass",\ 00168 "brightgold",\ 00169 "bronze",\ 00170 "bronze2",\ 00171 "brown",\ 00172 "cadetblue",\ 00173 "clear",\ 00174 "coolcopper",\ 00175 "copper",\ 00176 "coral",\ 00177 "cornflowerblue",\ 00178 "cyan",\ 00179 "darkbrown",\ 00180 "darkgreen",\ 00181 "darkolivegreen",\ 00182 "darkorchid",\ 00183 "darkpurple",\ 00184 "darkslateblue",\ 00185 "darkslategray",\ 00186 "darkslategrey",\ 00187 "darktan",\ 00188 "darkturquoise",\ 00189 "darkwood",\ 00190 "dkgreencopper",\ 00191 "dustyrose",\ 00192 "feldspar",\ 00193 "firebrick",\ 00194 "flesh",\ 00195 "forestgreen",\ 00196 "gold",\ 00197 "goldenrod",\ 00198 "gray05",\ 00199 "gray10",\ 00200 "gray15",\ 00201 "gray20",\ 00202 "gray25",\ 00203 "gray30",\ 00204 "gray35",\ 00205 "gray40",\ 00206 "gray45",\ 00207 "gray50",\ 00208 "gray55",\ 00209 "gray60",\ 00210 "gray65",\ 00211 "gray70",\ 00212 "gray75",\ 00213 "gray80",\ 00214 "gray85",\ 00215 "gray90",\ 00216 "gray95",\ 00217 "green",\ 00218 "greencopper",\ 00219 "greenyellow",\ 00220 "huntersgreen",\ 00221 "indianred",\ 00222 "khaki",\ 00223 "lightblue",\ 00224 "light_purple",\ 00225 "lightsteelblue",\ 00226 "lightwood",\ 00227 "limegreen",\ 00228 "magenta",\ 00229 "mandarinorange",\ 00230 "maroon",\ 00231 "mediumaquamarine",\ 00232 "mediumblue",\ 00233 "mediumforestgreen",\ 00234 "mediumgoldenrod",\ 00235 "mediumorchid",\ 00236 "mediumseagreen",\ 00237 "mediumslateblue",\ 00238 "mediumspringgreen",\ 00239 "mediumturquoise",\ 00240 "mediumvioletred",\ 00241 "mediumwood",\ 00242 "med_purple",\ 00243 "mica",\ 00244 "midnightblue",\ 00245 "navy",\ 00246 "navyblue",\ 00247 "neonblue",\ 00248 "neonpink",\ 00249 "newmidnightblue",\ 00250 "newtan",\ 00251 "oldgold",\ 00252 "orange",\ 00253 "orangered",\ 00254 "orchid",\ 00255 "palegreen",\ 00256 "pink",\ 00257 "plum",\ 00258 "quartz",\ 00259 "red",\ 00260 "richblue",\ 00261 "salmon",\ 00262 "scarlet",\ 00263 "seagreen",\ 00264 "semiSweetChoc",\ 00265 "sienna",\ 00266 "silver",\ 00267 "skyblue",\ 00268 "slateblue",\ 00269 "spicypink",\ 00270 "springgreen",\ 00271 "steelblue",\ 00272 "summersky",\ 00273 "tan",\ 00274 "thistle",\ 00275 "turquoise",\ 00276 "verydarkbrown",\ 00277 "very_light_purple",\ 00278 "violet",\ 00279 "violetred",\ 00280 "wheat",\ 00281 "white",\ 00282 "yellow",\ 00283 "yellowgreen" 00284 00285 #define GV_OBJ_EXT(type, obj, name) \ 00286 do { \ 00287 char debug_str[256]; \ 00288 gvprintf(job, POV_DECLARE, type, obj); \ 00289 gvprintf(job, POV_OBJECT, type); \ 00290 gvprintf(job, POV_DECLARE, "Min", "min_extent("type")"); \ 00291 gvprintf(job, POV_DECLARE, "Max", "max_extent("type")"); \ 00292 snprintf(debug_str, 256, \ 00293 "concat(\"Dim = \" , vstr(3, Max - Min, \", \", 0, 3)," \ 00294 " \" "type": %s\", \"\\n\")", name); \ 00295 gvprintf(job, POV_DEBUG, debug_str); \ 00296 } while (0) 00297 00298 /* 00299 //png, gif, NO jpg! 00300 pigment 00301 { image_map 00302 { gif "image.gif" 00303 map_type 1 00304 } 00305 } 00306 */ 00307 00308 /* 00309 #declare Sphere = 00310 sphere { 00311 <0,0,0>, 1 00312 pigment { rgb <1,0,0> } 00313 } 00314 #declare Min = min_extent ( Sphere ); 00315 #declare Max = max_extent ( Sphere ); 00316 object { Sphere } 00317 box { 00318 Min, Max 00319 pigment { rgbf <1,1,1,0.5> } 00320 scale<20,20,20> 00321 } 00322 */ 00323 00324 /* 00325 STRING functions 00326 00327 str( float , min_len , digits_after_dot ) 00328 concat( STRING , STRING , [STRING ,...]) 00329 chr( INT ) 00330 substr( STRING , INT , INT ) 00331 strupr( STRING ) 00332 strlwr( STRING ) 00333 vstr( vec_dimension , vec, sep_str, min_len, digits_after_dot ) 00334 00335 examples: 00336 #debug vstr(3, Min, ", ", 0, 3) 00337 #debug "\n*****************\n" 00338 #debug concat ( "Max =", vstr(3, Max, ", ", 0, 3), chr(13), chr(10) ) 00339 */ 00340 00341 00342 #define DPI 72.0 00343 #define RENDERER_COLOR_TYPE RGBA_BYTE 00344 typedef enum { FORMAT_POV, } format_type; 00345 00346 //#define DEBUG 00347 00348 //TODO: check why this dot file does not work (90 rotated) 00349 // /usr/share/graphviz/graphs/directed/NaN.gv 00350 //TODO: add Texttures 00351 //TODO: check how we can receive attributes from dot file 00352 // if we can't receive attributes set defaults in pov include file 00353 // - put #include "graph-scheme-fancy.inc" in pov file 00354 // - run povray with +L`pwd` 00355 // - put e.g. #declare mycolor = Gold; in graph-scheme-fancy.inc 00356 // - use textures and color: pigment { color mycolor transmit 0.000 } 00357 //TODO: idea, put the whole graph in a declare= and then 00358 // print it with something along the line: 00359 // object{ graph translate{page->translation, ...} rotate{page->rotation, ...} } 00360 00361 static char *pov_knowncolors[] = { POV_COLORS }; 00362 00363 static float layerz = 0; 00364 static float z = 0; 00365 00366 char *el(GVJ_t* job, char *template, ...) 00367 { 00368 #if defined(HAVE_VASPRINTF) 00369 char *str; 00370 va_list arglist; 00371 00372 va_start(arglist, template); 00373 vasprintf(&str, template, arglist); 00374 va_end(arglist); 00375 00376 return str; 00377 #elif defined(HAVE_VSNPRINTF) 00378 char buf[BUFSIZ]; 00379 size_t len; 00380 char *str; 00381 va_list arglist; 00382 00383 va_start(arglist, template); 00384 len = vsnprintf((char *)buf, BUFSIZ, template, arglist); 00385 if (len < 0) { 00386 job->common->errorfn("pov renderer:el - %s\n", strerror(errno)); 00387 str = strdup (""); 00388 } 00389 else if (len >= BUFSIZ) { 00390 str = malloc (len+1); 00391 va_end(arglist); 00392 va_start(arglist, template); 00393 len = vsprintf(str, template, arglist); 00394 } 00395 else { 00396 str = strdup (buf); 00397 } 00398 va_end(arglist); 00399 00400 return str; 00401 #else 00402 /* Dummy function that will never be used */ 00403 return strdup(""); 00404 #endif 00405 } 00406 00407 static char *pov_color_as_str(GVJ_t * job, gvcolor_t color, float transparency) 00408 { 00409 char *pov, *c; 00410 switch (color.type) { 00411 case COLOR_STRING: 00412 #ifdef DEBUG 00413 gvprintf(job, "// type = %d, color = %s\n", color.type, color.u.string); 00414 #endif 00415 if (!strcmp(color.u.string, "red")) 00416 c = el(job, POV_COLOR_NAME, "Red", transparency); 00417 else if (!strcmp(color.u.string, "green")) 00418 c = el(job, POV_COLOR_NAME, "Green", transparency); 00419 else if (!strcmp(color.u.string, "blue")) 00420 c = el(job, POV_COLOR_NAME, "Blue", transparency); 00421 else 00422 c = el(job, POV_COLOR_NAME, color.u.string, transparency); 00423 break; 00424 case RENDERER_COLOR_TYPE: 00425 #ifdef DEBUG 00426 gvprintf(job, "// type = %d, color = %d, %d, %d\n", 00427 color.type, color.u.rgba[0], color.u.rgba[1], 00428 color.u.rgba[2]); 00429 #endif 00430 c = el(job, POV_COLOR_RGB, 00431 color.u.rgba[0] / 256.0, color.u.rgba[1] / 256.0, 00432 color.u.rgba[2] / 256.0, transparency); 00433 break; 00434 default: 00435 fprintf(stderr, 00436 "oops, internal error: unhandled color type=%d %s\n", 00437 color.type, color.u.string); 00438 assert(0); //oops, wrong type set in gvrender_features_t? 00439 } 00440 pov = el(job, POV_PIGMENT_COLOR, c); 00441 free(c); 00442 return pov; 00443 } 00444 00445 static void pov_comment(GVJ_t * job, char *str) 00446 { 00447 gvprintf(job, "//*** comment: %s\n", str); 00448 } 00449 00450 static void pov_begin_job(GVJ_t * job) 00451 { 00452 gvputs(job, POV_VERSION); 00453 gvputs(job, POV_GLOBALS); 00454 gvputs(job, POV_DEFAULT); 00455 gvputs(job, POV_INCLUDE); 00456 gvprintf(job, POV_DECLARE, "black", "Black"); 00457 gvprintf(job, POV_DECLARE, "white", "White"); 00458 } 00459 00460 static void pov_begin_graph(GVJ_t * job) 00461 { 00462 float x, y, d, px, py; 00463 00464 gvprintf(job, "//*** begin_graph %s\n", agnameof(job->obj->u.g)); 00465 #ifdef DEBUG 00466 gvprintf(job, "// graph_index = %d, pages = %d, layer = %d/%d\n", 00467 job->graph_index, job->numPages, job->layerNum, 00468 job->numLayers); 00469 gvprintf(job, "// pagesArraySize.x,y = %d,%d\n", job->pagesArraySize.x, 00470 job->pagesArraySize.y); 00471 gvprintf(job, "// pagesArrayFirst.x,y = %d,%d\n", 00472 job->pagesArrayFirst.x, job->pagesArrayFirst.y); 00473 gvprintf(job, "// pagesArrayElem.x,y = %d,%d\n", job->pagesArrayElem.x, 00474 job->pagesArrayElem.y); 00475 gvprintf(job, "// bb.LL,UR = %.3f,%.3f, %.3f,%.3f\n", job->bb.LL.x, 00476 job->bb.LL.y, job->bb.UR.x, job->bb.UR.y); 00477 gvprintf(job, "// pageBox in graph LL,UR = %.3f,%.3f, %.3f,%.3f\n", 00478 job->pageBox.LL.x, job->pageBox.LL.y, job->pageBox.UR.x, 00479 job->pageBox.UR.y); 00480 gvprintf(job, "// pageSize.x,y = %.3f,%.3f\n", job->pageSize.x, 00481 job->pageSize.y); 00482 gvprintf(job, "// focus.x,y = %.3f,%.3f\n", job->focus.x, job->focus.y); 00483 gvprintf(job, "// zoom = %.3f, rotation = %d\n", job->zoom, 00484 (float)job->rotation); 00485 gvprintf(job, "// view port.x,y = %.3f,%.3f\n", job->view.x, 00486 job->view.y); 00487 gvprintf(job, "// canvasBox LL,UR = %.3f,%.3f, %.3f,%.3f\n", 00488 job->canvasBox.LL.x, job->canvasBox.LL.y, job->canvasBox.UR.x, 00489 job->canvasBox.UR.y); 00490 gvprintf(job, "// pageBoundingBox LL,UR = %d,%d, %d,%d\n", 00491 job->pageBoundingBox.LL.x, job->pageBoundingBox.LL.y, 00492 job->pageBoundingBox.UR.x, job->pageBoundingBox.UR.y); 00493 gvprintf(job, "// boundingBox (all pages) LL,UR = %d,%d, %d,%d\n", 00494 job->boundingBox.LL.x, job->boundingBox.LL.y, 00495 job->boundingBox.UR.x, job->boundingBox.UR.y); 00496 gvprintf(job, "// scale.x,y = %.3f,%.3f\n", job->scale.x, job->scale.y); 00497 gvprintf(job, "// translation.x,y = %.3f,%.3f\n", job->translation.x, 00498 job->translation.y); 00499 gvprintf(job, "// devscale.x,y = %.3f,%.3f\n", job->devscale.x, 00500 job->devscale.y); 00501 gvprintf(job, "// verbose = %d\n", job->common->verbose); 00502 gvprintf(job, "// cmd = %s\n", job->common->cmdname); 00503 gvprintf(job, "// info = %s, %s, %s\n", job->common->info[0], 00504 job->common->info[1], job->common->info[2]); 00505 #endif 00506 00507 //setup scene 00508 x = job->view.x / 2.0 * job->scale.x; 00509 y = job->view.y / 2.0 * job->scale.y; 00510 d = -500; 00511 px = atanf(x / abs(d)) * 180 / M_PI * 2; 00512 py = atanf(y / abs(d)) * 180 / M_PI * 2; 00513 gvprintf(job, POV_CAMERA, x, y, d, x, y, 0.0, 00514 (px > py ? px : py) * 1.2); 00515 gvputs(job, POV_SKY_AND_GND); 00516 gvputs(job, POV_LIGHT); 00517 } 00518 00519 static void pov_end_graph(GVJ_t * job) 00520 { 00521 gvputs(job, "//*** end_graph\n"); 00522 } 00523 00524 static void pov_begin_layer(GVJ_t * job, char *layername, int layerNum, int numLayers) 00525 { 00526 gvprintf(job, "//*** begin_layer: %s, %d/%d\n", layername, layerNum, 00527 numLayers); 00528 layerz = layerNum * -10; 00529 } 00530 00531 static void pov_end_layer(GVJ_t * job) 00532 { 00533 gvputs(job, "//*** end_layer\n"); 00534 } 00535 00536 static void pov_begin_page(GVJ_t * job) 00537 { 00538 gvputs(job, "//*** begin_page\n"); 00539 } 00540 00541 static void pov_end_page(GVJ_t * job) 00542 { 00543 gvputs(job, "//*** end_page\n"); 00544 } 00545 00546 static void pov_begin_cluster(GVJ_t * job) 00547 { 00548 gvputs(job, "//*** begin_cluster\n"); 00549 layerz -= 2; 00550 } 00551 00552 static void pov_end_cluster(GVJ_t * job) 00553 { 00554 gvputs(job, "//*** end_cluster\n"); 00555 } 00556 00557 static void pov_begin_node(GVJ_t * job) 00558 { 00559 gvprintf(job, "//*** begin_node: %s\n", agnameof(job->obj->u.n)); 00560 } 00561 00562 static void pov_end_node(GVJ_t * job) 00563 { 00564 gvputs(job, "//*** end_node\n"); 00565 } 00566 00567 static void pov_begin_edge(GVJ_t * job) 00568 { 00569 gvputs(job, "//*** begin_edge\n"); 00570 layerz -= 5; 00571 #ifdef DEBUG 00572 gvprintf(job, "// layerz = %.3f\n", layerz); 00573 #endif 00574 } 00575 00576 static void pov_end_edge(GVJ_t * job) 00577 { 00578 gvputs(job, "//*** end_edge\n"); 00579 layerz += 5; 00580 #ifdef DEBUG 00581 gvprintf(job, "// layerz = %.3f\n", layerz); 00582 #endif 00583 } 00584 00585 static void pov_textpara(GVJ_t * job, pointf c, textpara_t * para) 00586 { 00587 double x, y; 00588 char *pov, *s, *r, *t, *p; 00589 00590 gvprintf(job, "//*** textpara: %s, fontsize = %.3f, fontname = %s\n", 00591 para->str, para->fontsize, para->fontname); 00592 z = layerz - 9; 00593 00594 #ifdef DEBUG 00595 if (para->postscript_alias) 00596 gvputs(job, "// Warning: postscript_alias not handled!\n"); 00597 #endif 00598 00599 //handle text justification 00600 switch (para->just) { 00601 case 'l': //left justified 00602 break; 00603 case 'r': //right justified 00604 c.x = c.x - para->width; 00605 break; 00606 default: 00607 case 'n': //centered 00608 c.x = c.x - para->width / 2.0; 00609 break; 00610 } 00611 00612 x = (c.x + job->translation.x) * job->scale.x; 00613 y = (c.y + job->translation.y) * job->scale.y; 00614 00615 s = el(job, POV_SCALE1, para->fontsize * job->scale.x); 00616 r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); 00617 t = el(job, POV_TRANSLATE, x, y, z); 00618 p = pov_color_as_str(job, job->obj->pencolor, 0.0); 00619 00620 //pov bundled fonts: timrom.ttf, cyrvetic.ttf 00621 pov = el(job, POV_TEXT " %s %s %s %s %s" END, 00622 para->fontname, 0.25, 0.0, //font, depth (0.5 ... 2.0), offset 00623 para->str, " no_shadow\n", s, r, t, p); 00624 00625 #ifdef DEBUG 00626 GV_OBJ_EXT("Text", pov, para->str); 00627 gvprintf(job, "sphere{<0, 0, 0>, 2\ntranslate<%f, %f, %f>\n" 00628 "pigment{color Red}\nno_shadow\n}\n", x, y, z - 1); 00629 #else 00630 gvputs(job, pov); 00631 #endif 00632 00633 free(pov); 00634 free(r); 00635 free(p); 00636 free(t); 00637 free(s); 00638 } 00639 00640 static void pov_ellipse(GVJ_t * job, pointf * A, int filled) 00641 { 00642 char *pov, *s, *r, *t, *p; 00643 float cx, cy, rx, ry, w; 00644 00645 gvputs(job, "//*** ellipse\n"); 00646 z = layerz - 6; 00647 00648 // A[0] center, A[1] corner of ellipse 00649 cx = (A[0].x + job->translation.x) * job->scale.x; 00650 cy = (A[0].y + job->translation.y) * job->scale.y; 00651 rx = (A[1].x - A[0].x) * job->scale.x; 00652 ry = (A[1].y - A[0].y) * job->scale.y; 00653 w = job->obj->penwidth / (rx + ry) / 2.0 * 5; 00654 00655 //draw rim (torus) 00656 s = el(job, POV_SCALE3, rx, (rx + ry) / 4.0, ry); 00657 r = el(job, POV_ROTATE, 90.0, 0.0, (float)job->rotation); 00658 t = el(job, POV_TRANSLATE, cx, cy, z); 00659 p = pov_color_as_str(job, job->obj->pencolor, 0.0); 00660 00661 pov = el(job, POV_TORUS " %s %s %s %s" END, 1.0, w, //radius, size of ring 00662 s, r, t, p); 00663 00664 #ifdef DEBUG 00665 GV_OBJ_EXT("Torus", pov, ""); 00666 gvprintf(job, "sphere{<0, 0, 0>, 2\ntranslate<%f, %f, %f>\n" 00667 "pigment{color Green}\nno_shadow\n}\n", cx, cy, z - 1); 00668 #else 00669 gvputs(job, pov); 00670 #endif 00671 00672 free(s); 00673 free(r); 00674 free(t); 00675 free(p); 00676 free(pov); 00677 00678 //backgroud of ellipse if filled 00679 if (filled) { 00680 s = el(job, POV_SCALE3, rx, ry, 1.0); 00681 r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); 00682 t = el(job, POV_TRANSLATE, cx, cy, z); 00683 p = pov_color_as_str(job, job->obj->fillcolor, 0.0); 00684 00685 pov = el(job, POV_SPHERE " %s %s %s %s" END, 00686 0.0, 0.0, 0.0, s, r, t, p); 00687 00688 gvputs(job, pov); 00689 00690 free(s); 00691 free(r); 00692 free(t); 00693 free(p); 00694 free(pov); 00695 } 00696 } 00697 00698 static void pov_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start, 00699 int arrow_at_end, int filled) 00700 { 00701 int i; 00702 char *v, *x; 00703 char *pov, *s, *r, *t, *p; 00704 00705 gvputs(job, "//*** bezier\n"); 00706 z = layerz - 4; 00707 00708 s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0); 00709 r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); 00710 t = el(job, POV_TRANSLATE, 0.0, 0.0, z - 2); 00711 p = pov_color_as_str(job, job->obj->fillcolor, 0.0); 00712 00713 pov = el(job, POV_SPHERE_SWEEP, "b_spline", n + 2); 00714 00715 for (i = 0; i < n; i++) { 00716 v = el(job, POV_VECTOR3 ", %.3f\n", A[i].x + job->translation.x, A[i].y + job->translation.y, 0.0, job->obj->penwidth); //z coordinate, thickness 00717 x = el(job, "%s %s", pov, v); //catenate pov & vector v 00718 free(v); 00719 free(pov); 00720 pov = x; 00721 00722 //TODO: we currently just use the start and end points of the curve as 00723 //control points but we should use center of nodes 00724 if (i == 0 || i == n - 1) { 00725 v = el(job, POV_VECTOR3 ", %.3f\n", A[i].x + job->translation.x, A[i].y + job->translation.y, 0.0, job->obj->penwidth); //z coordinate, thickness 00726 x = el(job, "%s %s", pov, v); //catenate pov & vector v 00727 free(v); 00728 free(pov); 00729 pov = x; 00730 } 00731 #ifdef DEBUG 00732 gvprintf(job, "sphere{<0, 0, 0>, 2\ntranslate<%f, %f, %f>\n" 00733 "pigment{color Yellow}\nno_shadow\n}\n", 00734 (A[i].x + job->translation.x) * job->scale.x, 00735 (A[i].y + job->translation.y) * job->scale.y, z - 2); 00736 #endif 00737 } 00738 x = el(job, " tolerance 0.01\n %s %s %s %s" END, s, r, t, 00739 p); 00740 pov = el(job, "%s%s", pov, x); //catenate pov & end str 00741 free(x); 00742 00743 gvputs(job, pov); 00744 00745 free(s); 00746 free(r); 00747 free(t); 00748 free(p); 00749 free(pov); 00750 } 00751 00752 static void pov_polygon(GVJ_t * job, pointf * A, int n, int filled) 00753 { 00754 char *pov, *s, *r, *t, *p, *v, *x; 00755 int i; 00756 00757 gvputs(job, "//*** polygon\n"); 00758 z = layerz - 2; 00759 00760 s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0); 00761 r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); 00762 t = el(job, POV_TRANSLATE, 0.0, 0.0, z - 2); 00763 p = pov_color_as_str(job, job->obj->pencolor, 0.0); 00764 00765 pov = el(job, POV_SPHERE_SWEEP, "linear_spline", n + 1); 00766 00767 for (i = 0; i < n; i++) { 00768 v = el(job, POV_VECTOR3 ", %.3f\n", A[i].x + job->translation.x, A[i].y + job->translation.y, 0.0, job->obj->penwidth); //z coordinate, thickness 00769 x = el(job, "%s %s", pov, v); //catenate pov & vector v 00770 free(v); 00771 free(pov); 00772 pov = x; 00773 } 00774 00775 //close polygon, add starting point as final point^ 00776 v = el(job, POV_VECTOR3 ", %.3f\n", A[0].x + job->translation.x, A[0].y + job->translation.y, 0.0, job->obj->penwidth); //z coordinate, thickness 00777 00778 x = el(job, "%s %s", pov, v); //catenate pov & vector v 00779 free(v); 00780 free(pov); 00781 pov = x; 00782 00783 x = el(job, " tolerance 0.1\n %s %s %s %s" END, s, r, t, p); 00784 pov = el(job, "%s%s", pov, x); //catenate pov & end str 00785 free(x); 00786 00787 gvputs(job, pov); 00788 00789 free(s); 00790 free(r); 00791 free(t); 00792 free(p); 00793 free(pov); 00794 00795 //create fill background 00796 if (filled) { 00797 s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0); 00798 r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); 00799 t = el(job, POV_TRANSLATE, 0.0, 0.0, z - 2); 00800 p = pov_color_as_str(job, job->obj->fillcolor, 0.25); 00801 00802 pov = el(job, POV_POLYGON, n); 00803 00804 for (i = 0; i < n; i++) { 00805 //create on z = 0 plane, then translate to real z pos 00806 v = el(job, POV_VECTOR3, 00807 A[i].x + job->translation.x, 00808 A[i].y + job->translation.y, 0.0); 00809 x = el(job, "%s\n %s", pov, v); //catenate pov & vector v 00810 free(v); 00811 free(pov); 00812 pov = x; 00813 } 00814 x = el(job, "\n %s %s %s %s" END, s, r, t, p); 00815 pov = el(job, "%s%s", pov, x); //catenate pov & end str 00816 free(x); 00817 00818 gvputs(job, pov); 00819 00820 free(s); 00821 free(r); 00822 free(t); 00823 free(p); 00824 free(pov); 00825 } 00826 } 00827 00828 static void pov_polyline(GVJ_t * job, pointf * A, int n) 00829 { 00830 char *pov, *s, *r, *t, *p, *v, *x; 00831 int i; 00832 00833 gvputs(job, "//*** polyline\n"); 00834 z = layerz - 6; 00835 00836 s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0); 00837 r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); 00838 t = el(job, POV_TRANSLATE, 0.0, 0.0, z); 00839 p = pov_color_as_str(job, job->obj->pencolor, 0.0); 00840 00841 pov = el(job, POV_SPHERE_SWEEP, "linear_spline", n); 00842 00843 for (i = 0; i < n; i++) { 00844 v = el(job, POV_VECTOR3 ", %.3f\n", A[i].x + job->translation.x, A[i].y + job->translation.y, 0.0, job->obj->penwidth); //z coordinate, thickness 00845 x = el(job, "%s %s", pov, v); //catenate pov & vector v 00846 free(v); 00847 free(pov); 00848 pov = x; 00849 } 00850 00851 x = el(job, " tolerance 0.01\n %s %s %s %s" END, s, r, t, p); 00852 pov = el(job, "%s%s", pov, x); //catenate pov & end str 00853 free(x); 00854 00855 gvputs(job, pov); 00856 00857 free(s); 00858 free(r); 00859 free(t); 00860 free(p); 00861 free(pov); 00862 } 00863 00864 gvrender_engine_t pov_engine = { 00865 pov_begin_job, 00866 0, /* pov_end_job */ 00867 pov_begin_graph, 00868 pov_end_graph, 00869 pov_begin_layer, 00870 pov_end_layer, 00871 pov_begin_page, 00872 pov_end_page, 00873 pov_begin_cluster, 00874 pov_end_cluster, 00875 0, /* pov_begin_nodes */ 00876 0, /* pov_end_nodes */ 00877 0, /* pov_begin_edges */ 00878 0, /* pov_end_edges */ 00879 pov_begin_node, 00880 pov_end_node, 00881 pov_begin_edge, 00882 pov_end_edge, 00883 0, /* pov_begin_anchor */ 00884 0, /* pov_end_anchor */ 00885 0, /* pov_begin_label */ 00886 0, /* pov_end_label */ 00887 pov_textpara, 00888 0, /* pov_resolve_color */ 00889 pov_ellipse, 00890 pov_polygon, 00891 pov_bezier, 00892 pov_polyline, 00893 pov_comment, 00894 0, /* pov_library_shape */ 00895 }; 00896 00897 gvrender_features_t render_features_pov = { 00898 /* flags */ 00899 GVDEVICE_DOES_LAYERS 00900 | GVRENDER_DOES_MAP_RECTANGLE 00901 | GVRENDER_DOES_MAP_CIRCLE 00902 | GVRENDER_DOES_MAP_POLYGON 00903 | GVRENDER_DOES_MAP_ELLIPSE 00904 | GVRENDER_DOES_MAP_BSPLINE 00905 | GVRENDER_NO_WHITE_BG 00906 | GVRENDER_DOES_TRANSFORM 00907 | GVRENDER_DOES_Z | GVRENDER_DOES_MAP_BSPLINE, 00908 4.0, /* default pad - graph units */ 00909 pov_knowncolors, /* knowncolors */ 00910 sizeof(pov_knowncolors) / sizeof(char *), /* strings in knowncolors */ 00911 RENDERER_COLOR_TYPE /* set renderer color type */ 00912 }; 00913 00914 gvdevice_features_t device_features_pov = { 00915 GVDEVICE_DOES_TRUECOLOR, /* flags */ 00916 {0.0, 0.0}, /* default margin - points */ 00917 {0.0, 0.0}, /* default page width, height - points */ 00918 {DPI, DPI}, /* default dpi */ 00919 }; 00920 00921 gvplugin_installed_t gvrender_pov_types[] = { 00922 #ifdef HAVE_VSNPRINTF 00923 {FORMAT_POV, "pov", 1, &pov_engine, &render_features_pov}, 00924 #endif 00925 {0, NULL, 0, NULL, NULL} 00926 }; 00927 00928 gvplugin_installed_t gvdevice_pov_types[] = { 00929 #ifdef HAVE_VSNPRINTF 00930 {FORMAT_POV, "pov:pov", 1, NULL, &device_features_pov}, 00931 #endif 00932 {0, NULL, 0, NULL, NULL} 00933 }; 00934
1.7.5