Graphviz  2.41.20170921.2350
gvrender_core_pov.c
Go to the documentation of this file.
1 /* $Id: */
2 /* vim:set shiftwidth=8 ts=8: */
3 
4 /**********************************************************
5 * Copyright (c) 2011 Andy Jeutter *
6 * AKA HallerHarry at gmx.de *
7 * All rights reserved. *
8 **********************************************************/
9 
10 /*************************************************************************
11  * This program and the accompanying materials
12  * are made available under the terms of the Eclipse Public License v1.0
13  * which accompanies this distribution, and is available at
14  * http://www.eclipse.org/legal/epl-v10.html
15  *
16  * Contributors: See CVS logs. Details at http://www.graphviz.org/
17  *************************************************************************/
18 
19 #define _GNU_SOURCE
20 #include "config.h"
21 
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <errno.h>
27 
28 #include "macros.h"
29 #include "const.h"
30 
31 #include "gvplugin_render.h"
32 #include "gvplugin_device.h"
33 #include "gvio.h"
34 #include "gvcint.h"
35 
36 #define POV_VERSION \
37  "#version 3.6;\n"
38 
39 #define POV_GLOBALS \
40  "global_settings { assumed_gamma 1.0 }\n"
41 
42 #define POV_DEFAULT \
43  "#default { finish { ambient 0.1 diffuse 0.9 } }\n"
44 
45 #define POV_INCLUDE \
46  "#include \"colors.inc\"\n"\
47  "#include \"textures.inc\"\n"\
48  "#include \"shapes.inc\"\n"
49 
50 #define POV_LIGHT \
51  "light_source { <1500,3000,-2500> color White }\n"
52 
53 #define POV_CAMERA \
54  "camera { location <%.3f , %.3f , %.3f>\n"\
55  " look_at <%.3f , %.3f , %.3f>\n"\
56  " right x * image_width / image_height\n"\
57  " angle %.3f\n"\
58  "}\n"
59 
60 #define POV_SKY_AND_GND \
61  "//sky\n"\
62  "plane { <0, 1, 0>, 1 hollow\n"\
63  " texture {\n"\
64  " pigment { bozo turbulence 0.95\n"\
65  " color_map {\n"\
66  " [0.00 rgb <0.05, 0.20, 0.50>]\n"\
67  " [0.50 rgb <0.05, 0.20, 0.50>]\n"\
68  " [0.75 rgb <1.00, 1.00, 1.00>]\n"\
69  " [0.75 rgb <0.25, 0.25, 0.25>]\n"\
70  " [1.00 rgb <0.50, 0.50, 0.50>]\n"\
71  " }\n"\
72  " scale <1.00, 1.00, 1.50> * 2.50\n"\
73  " translate <0.00, 0.00, 0.00>\n"\
74  " }\n"\
75  " finish { ambient 1 diffuse 0 }\n"\
76  " }\n"\
77  " scale 10000\n"\
78  "}\n"\
79  "//mist\n"\
80  "fog { fog_type 2\n"\
81  " distance 50\n"\
82  " color rgb <1.00, 1.00, 1.00> * 0.75\n"\
83  " fog_offset 0.10\n"\
84  " fog_alt 1.50\n"\
85  " turbulence 1.75\n"\
86  "}\n"\
87  "//gnd\n"\
88  "plane { <0.00, 1.00, 0.00>, 0\n"\
89  " texture {\n"\
90  " pigment{ color rgb <0.25, 0.45, 0.00> }\n"\
91  " normal { bumps 0.75 scale 0.01 }\n"\
92  " finish { phong 0.10 }\n"\
93  " }\n"\
94  "}\n"
95 
96 #define POV_BOX \
97  "box { <%.3f, %.3f, %.3f>, <%.3f, %.3f, %.3f>\n"
98 
99 #define POV_SCALE1 \
100  "scale %.3f\n"
101 
102 #define POV_SCALE3 \
103  "scale "POV_VECTOR3"\n"
104 
105 #define POV_ROTATE \
106  "rotate "POV_VECTOR3"\n"
107 
108 #define POV_TRANSLATE \
109  "translate"POV_VECTOR3"\n"
110 
111 #define END \
112  "}\n"
113 
114 #define POV_TORUS \
115  "torus { %.3f, %.3f\n"
116 
117 #define POV_SPHERE_SWEEP \
118  "sphere_sweep {\n"\
119  " %s\n"\
120  " %d,\n"
121 
122 #define POV_SPHERE \
123  "sphere {"POV_VECTOR3", 1.0\n" // center, radius
124 
125 #define POV_TEXT \
126  "text {\n"\
127  " ttf \"%s\",\n"\
128  " \"%s\", %.3f, %.3f\n"
129 
130 #define POV_DECLARE \
131  "#declare %s = %s;\n"
132 
133 #define POV_OBJECT \
134  "object { %s }\n"
135 
136 #define POV_VERBATIM \
137  "%s\n"
138 
139 #define POV_DEBUG \
140  "#debug %s\n"
141 
142 #define POV_POLYGON \
143  "polygon { %d,\n"
144 
145 #define POV_VECTOR3 \
146  "<%9.3f, %9.3f, %9.3f>"
147 
148 #define POV_PIGMENT_COLOR \
149  "pigment { color %s }\n"
150 
151 #define POV_COLOR_NAME \
152  "%s transmit %.3f"
153 
154 #define POV_COLOR_RGB \
155  "rgb"POV_VECTOR3" transmit %.3f"
156 
157 //colors are taken from /usr/share/povray-3.6/include/colors.inc
158 //list must be LANG_C sorted (all lower case)
159 #define POV_COLORS \
160 "aquamarine",\
161 "bakerschoc",\
162 "black",\
163 "blue",\
164 "blueviolet",\
165 "brass",\
166 "brightgold",\
167 "bronze",\
168 "bronze2",\
169 "brown",\
170 "cadetblue",\
171 "clear",\
172 "coolcopper",\
173 "copper",\
174 "coral",\
175 "cornflowerblue",\
176 "cyan",\
177 "darkbrown",\
178 "darkgreen",\
179 "darkolivegreen",\
180 "darkorchid",\
181 "darkpurple",\
182 "darkslateblue",\
183 "darkslategray",\
184 "darkslategrey",\
185 "darktan",\
186 "darkturquoise",\
187 "darkwood",\
188 "dkgreencopper",\
189 "dustyrose",\
190 "feldspar",\
191 "firebrick",\
192 "flesh",\
193 "forestgreen",\
194 "gold",\
195 "goldenrod",\
196 "gray05",\
197 "gray10",\
198 "gray15",\
199 "gray20",\
200 "gray25",\
201 "gray30",\
202 "gray35",\
203 "gray40",\
204 "gray45",\
205 "gray50",\
206 "gray55",\
207 "gray60",\
208 "gray65",\
209 "gray70",\
210 "gray75",\
211 "gray80",\
212 "gray85",\
213 "gray90",\
214 "gray95",\
215 "green",\
216 "greencopper",\
217 "greenyellow",\
218 "huntersgreen",\
219 "indianred",\
220 "khaki",\
221 "lightblue",\
222 "light_purple",\
223 "lightsteelblue",\
224 "lightwood",\
225 "limegreen",\
226 "magenta",\
227 "mandarinorange",\
228 "maroon",\
229 "mediumaquamarine",\
230 "mediumblue",\
231 "mediumforestgreen",\
232 "mediumgoldenrod",\
233 "mediumorchid",\
234 "mediumseagreen",\
235 "mediumslateblue",\
236 "mediumspringgreen",\
237 "mediumturquoise",\
238 "mediumvioletred",\
239 "mediumwood",\
240 "med_purple",\
241 "mica",\
242 "midnightblue",\
243 "navy",\
244 "navyblue",\
245 "neonblue",\
246 "neonpink",\
247 "newmidnightblue",\
248 "newtan",\
249 "oldgold",\
250 "orange",\
251 "orangered",\
252 "orchid",\
253 "palegreen",\
254 "pink",\
255 "plum",\
256 "quartz",\
257 "red",\
258 "richblue",\
259 "salmon",\
260 "scarlet",\
261 "seagreen",\
262 "semiSweetChoc",\
263 "sienna",\
264 "silver",\
265 "skyblue",\
266 "slateblue",\
267 "spicypink",\
268 "springgreen",\
269 "steelblue",\
270 "summersky",\
271 "tan",\
272 "thistle",\
273 "turquoise",\
274 "verydarkbrown",\
275 "very_light_purple",\
276 "violet",\
277 "violetred",\
278 "wheat",\
279 "white",\
280 "yellow",\
281 "yellowgreen"
282 
283 #define GV_OBJ_EXT(type, obj, name) \
284  do { \
285  char debug_str[256]; \
286  gvprintf(job, POV_DECLARE, type, obj); \
287  gvprintf(job, POV_OBJECT, type); \
288  gvprintf(job, POV_DECLARE, "Min", "min_extent("type")"); \
289  gvprintf(job, POV_DECLARE, "Max", "max_extent("type")"); \
290  snprintf(debug_str, 256, \
291  "concat(\"Dim = \" , vstr(3, Max - Min, \", \", 0, 3)," \
292  " \" "type": %s\", \"\\n\")", name); \
293  gvprintf(job, POV_DEBUG, debug_str); \
294  } while (0)
295 
296 /*
297 //png, gif, NO jpg!
298 pigment
299 { image_map
300  { gif "image.gif"
301  map_type 1
302  }
303 }
304 */
305 
306 /*
307 #declare Sphere =
308 sphere {
309  <0,0,0>, 1
310  pigment { rgb <1,0,0> }
311 }
312 #declare Min = min_extent ( Sphere );
313 #declare Max = max_extent ( Sphere );
314 object { Sphere }
315 box {
316  Min, Max
317  pigment { rgbf <1,1,1,0.5> }
318  scale<20,20,20>
319 }
320 */
321 
322 /*
323 STRING functions
324 
325 str( float , min_len , digits_after_dot )
326 concat( STRING , STRING , [STRING ,...])
327 chr( INT )
328 substr( STRING , INT , INT )
329 strupr( STRING )
330 strlwr( STRING )
331 vstr( vec_dimension , vec, sep_str, min_len, digits_after_dot )
332 
333 examples:
334 #debug vstr(3, Min, ", ", 0, 3)
335 #debug "\n*****************\n"
336 #debug concat ( "Max =", vstr(3, Max, ", ", 0, 3), chr(13), chr(10) )
337 */
338 
339 
340 #define DPI 72.0
341 #define RENDERER_COLOR_TYPE RGBA_BYTE
342 typedef enum { FORMAT_POV, } format_type;
343 
344 //#define DEBUG
345 
346 //TODO: check why this dot file does not work (90 rotated)
347 // /usr/share/graphviz/graphs/directed/NaN.gv
348 //TODO: add Texttures
349 //TODO: check how we can receive attributes from dot file
350 // if we can't receive attributes set defaults in pov include file
351 // - put #include "graph-scheme-fancy.inc" in pov file
352 // - run povray with +L`pwd`
353 // - put e.g. #declare mycolor = Gold; in graph-scheme-fancy.inc
354 // - use textures and color: pigment { color mycolor transmit 0.000 }
355 //TODO: idea, put the whole graph in a declare= and then
356 // print it with something along the line:
357 // object{ graph translate{page->translation, ...} rotate{page->rotation, ...} }
358 
359 static char *pov_knowncolors[] = { POV_COLORS };
360 
361 static float layerz = 0;
362 static float z = 0;
363 
364 char *el(GVJ_t* job, char *template, ...)
365 {
366 #if defined(HAVE_VASPRINTF)
367  char *str;
368  va_list arglist;
369 
370  va_start(arglist, template);
371  vasprintf(&str, template, arglist);
372  va_end(arglist);
373 
374  return str;
375 #elif defined(HAVE_VSNPRINTF)
376  char buf[BUFSIZ];
377  int len;
378  char *str;
379  va_list arglist;
380 
381  va_start(arglist, template);
382  len = vsnprintf((char *)buf, BUFSIZ, template, arglist);
383  if (len < 0) {
384  job->common->errorfn("pov renderer:el - %s\n", strerror(errno));
385  str = strdup ("");
386  }
387  else if (len >= BUFSIZ) {
388  str = malloc (len+1);
389  va_end(arglist);
390  va_start(arglist, template);
391  len = vsprintf(str, template, arglist);
392  }
393  else {
394  str = strdup (buf);
395  }
396  va_end(arglist);
397 
398  return str;
399 #else
400 /* Dummy function that will never be used */
401  return strdup("");
402 #endif
403 }
404 
405 static char *pov_color_as_str(GVJ_t * job, gvcolor_t color, float transparency)
406 {
407  char *pov, *c = NULL;
408  switch (color.type) {
409  case COLOR_STRING:
410 #ifdef DEBUG
411  gvprintf(job, "// type = %d, color = %s\n", color.type, color.u.string);
412 #endif
413  if (!strcmp(color.u.string, "red"))
414  c = el(job, POV_COLOR_NAME, "Red", transparency);
415  else if (!strcmp(color.u.string, "green"))
416  c = el(job, POV_COLOR_NAME, "Green", transparency);
417  else if (!strcmp(color.u.string, "blue"))
418  c = el(job, POV_COLOR_NAME, "Blue", transparency);
419  else
420  c = el(job, POV_COLOR_NAME, color.u.string, transparency);
421  break;
422  case RENDERER_COLOR_TYPE:
423 #ifdef DEBUG
424  gvprintf(job, "// type = %d, color = %d, %d, %d\n",
425  color.type, color.u.rgba[0], color.u.rgba[1],
426  color.u.rgba[2]);
427 #endif
428  c = el(job, POV_COLOR_RGB,
429  color.u.rgba[0] / 256.0, color.u.rgba[1] / 256.0,
430  color.u.rgba[2] / 256.0, transparency);
431  break;
432  default:
433  fprintf(stderr,
434  "oops, internal error: unhandled color type=%d %s\n",
435  color.type, color.u.string);
436  assert(0); //oops, wrong type set in gvrender_features_t?
437  }
438  pov = el(job, POV_PIGMENT_COLOR, c);
439  free(c);
440  return pov;
441 }
442 
443 static void pov_comment(GVJ_t * job, char *str)
444 {
445  gvprintf(job, "//*** comment: %s\n", str);
446 }
447 
448 static void pov_begin_job(GVJ_t * job)
449 {
450  gvputs(job, POV_VERSION);
451  gvputs(job, POV_GLOBALS);
452  gvputs(job, POV_DEFAULT);
453  gvputs(job, POV_INCLUDE);
454  gvprintf(job, POV_DECLARE, "black", "Black");
455  gvprintf(job, POV_DECLARE, "white", "White");
456 }
457 
458 static void pov_begin_graph(GVJ_t * job)
459 {
460  float x, y, d, px, py;
461 
462  gvprintf(job, "//*** begin_graph %s\n", agnameof(job->obj->u.g));
463 #ifdef DEBUG
464  gvprintf(job, "// graph_index = %d, pages = %d, layer = %d/%d\n",
465  job->graph_index, job->numPages, job->layerNum,
466  job->numLayers);
467  gvprintf(job, "// pagesArraySize.x,y = %d,%d\n", job->pagesArraySize.x,
468  job->pagesArraySize.y);
469  gvprintf(job, "// pagesArrayFirst.x,y = %d,%d\n",
470  job->pagesArrayFirst.x, job->pagesArrayFirst.y);
471  gvprintf(job, "// pagesArrayElem.x,y = %d,%d\n", job->pagesArrayElem.x,
472  job->pagesArrayElem.y);
473  gvprintf(job, "// bb.LL,UR = %.3f,%.3f, %.3f,%.3f\n", job->bb.LL.x,
474  job->bb.LL.y, job->bb.UR.x, job->bb.UR.y);
475  gvprintf(job, "// pageBox in graph LL,UR = %.3f,%.3f, %.3f,%.3f\n",
476  job->pageBox.LL.x, job->pageBox.LL.y, job->pageBox.UR.x,
477  job->pageBox.UR.y);
478  gvprintf(job, "// pageSize.x,y = %.3f,%.3f\n", job->pageSize.x,
479  job->pageSize.y);
480  gvprintf(job, "// focus.x,y = %.3f,%.3f\n", job->focus.x, job->focus.y);
481  gvprintf(job, "// zoom = %.3f, rotation = %d\n", job->zoom,
482  (float)job->rotation);
483  gvprintf(job, "// view port.x,y = %.3f,%.3f\n", job->view.x,
484  job->view.y);
485  gvprintf(job, "// canvasBox LL,UR = %.3f,%.3f, %.3f,%.3f\n",
486  job->canvasBox.LL.x, job->canvasBox.LL.y, job->canvasBox.UR.x,
487  job->canvasBox.UR.y);
488  gvprintf(job, "// pageBoundingBox LL,UR = %d,%d, %d,%d\n",
489  job->pageBoundingBox.LL.x, job->pageBoundingBox.LL.y,
490  job->pageBoundingBox.UR.x, job->pageBoundingBox.UR.y);
491  gvprintf(job, "// boundingBox (all pages) LL,UR = %d,%d, %d,%d\n",
492  job->boundingBox.LL.x, job->boundingBox.LL.y,
493  job->boundingBox.UR.x, job->boundingBox.UR.y);
494  gvprintf(job, "// scale.x,y = %.3f,%.3f\n", job->scale.x, job->scale.y);
495  gvprintf(job, "// translation.x,y = %.3f,%.3f\n", job->translation.x,
496  job->translation.y);
497  gvprintf(job, "// devscale.x,y = %.3f,%.3f\n", job->devscale.x,
498  job->devscale.y);
499  gvprintf(job, "// verbose = %d\n", job->common->verbose);
500  gvprintf(job, "// cmd = %s\n", job->common->cmdname);
501  gvprintf(job, "// info = %s, %s, %s\n", job->common->info[0],
502  job->common->info[1], job->common->info[2]);
503 #endif
504 
505  //setup scene
506  x = job->view.x / 2.0 * job->scale.x;
507  y = job->view.y / 2.0 * job->scale.y;
508  d = -500;
509  px = atanf(x / fabsf(d)) * 180 / M_PI * 2;
510  py = atanf(y / fabsf(d)) * 180 / M_PI * 2;
511  gvprintf(job, POV_CAMERA, x, y, d, x, y, 0.0,
512  (px > py ? px : py) * 1.2);
513  gvputs(job, POV_SKY_AND_GND);
514  gvputs(job, POV_LIGHT);
515 }
516 
517 static void pov_end_graph(GVJ_t * job)
518 {
519  gvputs(job, "//*** end_graph\n");
520 }
521 
522 static void pov_begin_layer(GVJ_t * job, char *layername, int layerNum, int numLayers)
523 {
524  gvprintf(job, "//*** begin_layer: %s, %d/%d\n", layername, layerNum,
525  numLayers);
526  layerz = layerNum * -10;
527 }
528 
529 static void pov_end_layer(GVJ_t * job)
530 {
531  gvputs(job, "//*** end_layer\n");
532 }
533 
534 static void pov_begin_page(GVJ_t * job)
535 {
536  gvputs(job, "//*** begin_page\n");
537 }
538 
539 static void pov_end_page(GVJ_t * job)
540 {
541  gvputs(job, "//*** end_page\n");
542 }
543 
544 static void pov_begin_cluster(GVJ_t * job)
545 {
546  gvputs(job, "//*** begin_cluster\n");
547  layerz -= 2;
548 }
549 
550 static void pov_end_cluster(GVJ_t * job)
551 {
552  gvputs(job, "//*** end_cluster\n");
553 }
554 
555 static void pov_begin_node(GVJ_t * job)
556 {
557  gvprintf(job, "//*** begin_node: %s\n", agnameof(job->obj->u.n));
558 }
559 
560 static void pov_end_node(GVJ_t * job)
561 {
562  gvputs(job, "//*** end_node\n");
563 }
564 
565 static void pov_begin_edge(GVJ_t * job)
566 {
567  gvputs(job, "//*** begin_edge\n");
568  layerz -= 5;
569 #ifdef DEBUG
570  gvprintf(job, "// layerz = %.3f\n", layerz);
571 #endif
572 }
573 
574 static void pov_end_edge(GVJ_t * job)
575 {
576  gvputs(job, "//*** end_edge\n");
577  layerz += 5;
578 #ifdef DEBUG
579  gvprintf(job, "// layerz = %.3f\n", layerz);
580 #endif
581 }
582 
583 static void pov_textspan(GVJ_t * job, pointf c, textspan_t * span)
584 {
585  double x, y;
586  char *pov, *s, *r, *t, *p;
587 
588  gvprintf(job, "//*** textspan: %s, fontsize = %.3f, fontname = %s\n",
589  span->str, span->font->size, span->font->name);
590  z = layerz - 9;
591 
592 #ifdef DEBUG
593  if (span->font->postscript_alias)
594  gvputs(job, "// Warning: postscript_alias not handled!\n");
595 #endif
596 
597  //handle text justification
598  switch (span->just) {
599  case 'l': //left justified
600  break;
601  case 'r': //right justified
602  c.x = c.x - span->size.x;
603  break;
604  default:
605  case 'n': //centered
606  c.x = c.x - span->size.x / 2.0;
607  break;
608  }
609 
610  x = (c.x + job->translation.x) * job->scale.x;
611  y = (c.y + job->translation.y) * job->scale.y;
612 
613  s = el(job, POV_SCALE1, span->font->size * job->scale.x);
614  r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation);
615  t = el(job, POV_TRANSLATE, x, y, z);
616  p = pov_color_as_str(job, job->obj->pencolor, 0.0);
617 
618  //pov bundled fonts: timrom.ttf, cyrvetic.ttf
619  pov = el(job, POV_TEXT " %s %s %s %s %s" END,
620  span->font->name, 0.25, 0.0, //font, depth (0.5 ... 2.0), offset
621  span->str, " no_shadow\n", s, r, t, p);
622 
623 #ifdef DEBUG
624  GV_OBJ_EXT("Text", pov, span->str);
625  gvprintf(job, "sphere{<0, 0, 0>, 2\ntranslate<%f, %f, %f>\n"
626  "pigment{color Red}\nno_shadow\n}\n", x, y, z - 1);
627 #else
628  gvputs(job, pov);
629 #endif
630 
631  free(pov);
632  free(r);
633  free(p);
634  free(t);
635  free(s);
636 }
637 
638 static void pov_ellipse(GVJ_t * job, pointf * A, int filled)
639 {
640  char *pov, *s, *r, *t, *p;
641  float cx, cy, rx, ry, w;
642 
643  gvputs(job, "//*** ellipse\n");
644  z = layerz - 6;
645 
646  // A[0] center, A[1] corner of ellipse
647  cx = (A[0].x + job->translation.x) * job->scale.x;
648  cy = (A[0].y + job->translation.y) * job->scale.y;
649  rx = (A[1].x - A[0].x) * job->scale.x;
650  ry = (A[1].y - A[0].y) * job->scale.y;
651  w = job->obj->penwidth / (rx + ry) / 2.0 * 5;
652 
653  //draw rim (torus)
654  s = el(job, POV_SCALE3, rx, (rx + ry) / 4.0, ry);
655  r = el(job, POV_ROTATE, 90.0, 0.0, (float)job->rotation);
656  t = el(job, POV_TRANSLATE, cx, cy, z);
657  p = pov_color_as_str(job, job->obj->pencolor, 0.0);
658 
659  pov = el(job, POV_TORUS " %s %s %s %s" END, 1.0, w, //radius, size of ring
660  s, r, t, p);
661 
662 #ifdef DEBUG
663  GV_OBJ_EXT("Torus", pov, "");
664  gvprintf(job, "sphere{<0, 0, 0>, 2\ntranslate<%f, %f, %f>\n"
665  "pigment{color Green}\nno_shadow\n}\n", cx, cy, z - 1);
666 #else
667  gvputs(job, pov);
668 #endif
669 
670  free(s);
671  free(r);
672  free(t);
673  free(p);
674  free(pov);
675 
676  //backgroud of ellipse if filled
677  if (filled) {
678  s = el(job, POV_SCALE3, rx, ry, 1.0);
679  r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation);
680  t = el(job, POV_TRANSLATE, cx, cy, z);
681  p = pov_color_as_str(job, job->obj->fillcolor, 0.0);
682 
683  pov = el(job, POV_SPHERE " %s %s %s %s" END,
684  0.0, 0.0, 0.0, s, r, t, p);
685 
686  gvputs(job, pov);
687 
688  free(s);
689  free(r);
690  free(t);
691  free(p);
692  free(pov);
693  }
694 }
695 
696 static void pov_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
697  int arrow_at_end, int filled)
698 {
699  int i;
700  char *v, *x;
701  char *pov, *s, *r, *t, *p;
702 
703  gvputs(job, "//*** bezier\n");
704  z = layerz - 4;
705 
706  s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0);
707  r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation);
708  t = el(job, POV_TRANSLATE, 0.0, 0.0, z - 2);
709  p = pov_color_as_str(job, job->obj->fillcolor, 0.0);
710 
711  pov = el(job, POV_SPHERE_SWEEP, "b_spline", n + 2);
712 
713  for (i = 0; i < n; i++) {
714  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
715  x = el(job, "%s %s", pov, v); //catenate pov & vector v
716  free(v);
717  free(pov);
718  pov = x;
719 
720  //TODO: we currently just use the start and end points of the curve as
721  //control points but we should use center of nodes
722  if (i == 0 || i == n - 1) {
723  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
724  x = el(job, "%s %s", pov, v); //catenate pov & vector v
725  free(v);
726  free(pov);
727  pov = x;
728  }
729 #ifdef DEBUG
730  gvprintf(job, "sphere{<0, 0, 0>, 2\ntranslate<%f, %f, %f>\n"
731  "pigment{color Yellow}\nno_shadow\n}\n",
732  (A[i].x + job->translation.x) * job->scale.x,
733  (A[i].y + job->translation.y) * job->scale.y, z - 2);
734 #endif
735  }
736  x = el(job, " tolerance 0.01\n %s %s %s %s" END, s, r, t,
737  p);
738  pov = el(job, "%s%s", pov, x); //catenate pov & end str
739  free(x);
740 
741  gvputs(job, pov);
742 
743  free(s);
744  free(r);
745  free(t);
746  free(p);
747  free(pov);
748 }
749 
750 static void pov_polygon(GVJ_t * job, pointf * A, int n, int filled)
751 {
752  char *pov, *s, *r, *t, *p, *v, *x;
753  int i;
754 
755  gvputs(job, "//*** polygon\n");
756  z = layerz - 2;
757 
758  s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0);
759  r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation);
760  t = el(job, POV_TRANSLATE, 0.0, 0.0, z - 2);
761  p = pov_color_as_str(job, job->obj->pencolor, 0.0);
762 
763  pov = el(job, POV_SPHERE_SWEEP, "linear_spline", n + 1);
764 
765  for (i = 0; i < n; i++) {
766  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
767  x = el(job, "%s %s", pov, v); //catenate pov & vector v
768  free(v);
769  free(pov);
770  pov = x;
771  }
772 
773  //close polygon, add starting point as final point^
774  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
775 
776  x = el(job, "%s %s", pov, v); //catenate pov & vector v
777  free(v);
778  free(pov);
779  pov = x;
780 
781  x = el(job, " tolerance 0.1\n %s %s %s %s" END, s, r, t, p);
782  pov = el(job, "%s%s", pov, x); //catenate pov & end str
783  free(x);
784 
785  gvputs(job, pov);
786 
787  free(s);
788  free(r);
789  free(t);
790  free(p);
791  free(pov);
792 
793  //create fill background
794  if (filled) {
795  s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0);
796  r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation);
797  t = el(job, POV_TRANSLATE, 0.0, 0.0, z - 2);
798  p = pov_color_as_str(job, job->obj->fillcolor, 0.25);
799 
800  pov = el(job, POV_POLYGON, n);
801 
802  for (i = 0; i < n; i++) {
803  //create on z = 0 plane, then translate to real z pos
804  v = el(job, POV_VECTOR3,
805  A[i].x + job->translation.x,
806  A[i].y + job->translation.y, 0.0);
807  x = el(job, "%s\n %s", pov, v); //catenate pov & vector v
808  free(v);
809  free(pov);
810  pov = x;
811  }
812  x = el(job, "\n %s %s %s %s" END, s, r, t, p);
813  pov = el(job, "%s%s", pov, x); //catenate pov & end str
814  free(x);
815 
816  gvputs(job, pov);
817 
818  free(s);
819  free(r);
820  free(t);
821  free(p);
822  free(pov);
823  }
824 }
825 
826 static void pov_polyline(GVJ_t * job, pointf * A, int n)
827 {
828  char *pov, *s, *r, *t, *p, *v, *x;
829  int i;
830 
831  gvputs(job, "//*** polyline\n");
832  z = layerz - 6;
833 
834  s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0);
835  r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation);
836  t = el(job, POV_TRANSLATE, 0.0, 0.0, z);
837  p = pov_color_as_str(job, job->obj->pencolor, 0.0);
838 
839  pov = el(job, POV_SPHERE_SWEEP, "linear_spline", n);
840 
841  for (i = 0; i < n; i++) {
842  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
843  x = el(job, "%s %s", pov, v); //catenate pov & vector v
844  free(v);
845  free(pov);
846  pov = x;
847  }
848 
849  x = el(job, " tolerance 0.01\n %s %s %s %s" END, s, r, t, p);
850  pov = el(job, "%s%s", pov, x); //catenate pov & end str
851  free(x);
852 
853  gvputs(job, pov);
854 
855  free(s);
856  free(r);
857  free(t);
858  free(p);
859  free(pov);
860 }
861 
863  pov_begin_job,
864  0, /* pov_end_job */
865  pov_begin_graph,
866  pov_end_graph,
867  pov_begin_layer,
868  pov_end_layer,
869  pov_begin_page,
870  pov_end_page,
871  pov_begin_cluster,
872  pov_end_cluster,
873  0, /* pov_begin_nodes */
874  0, /* pov_end_nodes */
875  0, /* pov_begin_edges */
876  0, /* pov_end_edges */
877  pov_begin_node,
878  pov_end_node,
879  pov_begin_edge,
880  pov_end_edge,
881  0, /* pov_begin_anchor */
882  0, /* pov_end_anchor */
883  0, /* pov_begin_label */
884  0, /* pov_end_label */
885  pov_textspan,
886  0, /* pov_resolve_color */
887  pov_ellipse,
888  pov_polygon,
889  pov_bezier,
890  pov_polyline,
891  pov_comment,
892  0, /* pov_library_shape */
893 };
894 
896  /* flags */
906  4.0, /* default pad - graph units */
907  pov_knowncolors, /* knowncolors */
908  sizeof(pov_knowncolors) / sizeof(char *), /* strings in knowncolors */
909  RENDERER_COLOR_TYPE /* set renderer color type */
910 };
911 
913  GVDEVICE_DOES_TRUECOLOR, /* flags */
914  {0.0, 0.0}, /* default margin - points */
915  {0.0, 0.0}, /* default page width, height - points */
916  {DPI, DPI}, /* default dpi */
917 };
918 
920 #ifdef HAVE_VSNPRINTF
921  {FORMAT_POV, "pov", 1, &pov_engine, &render_features_pov},
922 #endif
923  {0, NULL, 0, NULL, NULL}
924 };
925 
927 #ifdef HAVE_VSNPRINTF
928  {FORMAT_POV, "pov:pov", 1, NULL, &device_features_pov},
929 #endif
930  {0, NULL, 0, NULL, NULL}
931 };
932 
pointf size
Definition: textspan.h:64
#define GVRENDER_DOES_MAP_ELLIPSE
Definition: gvcjob.h:104
point pagesArrayFirst
Definition: gvcjob.h:314
int rotation
Definition: gvcjob.h:328
box boundingBox
Definition: gvcjob.h:339
#define DPI
union color_s::@10 u
#define POV_POLYGON
#define POV_TORUS
int numLayers
Definition: gvcjob.h:310
double size
Definition: textspan.h:52
point pagesArraySize
Definition: gvcjob.h:313
#define GVRENDER_DOES_MAP_POLYGON
Definition: gvcjob.h:103
#define assert(x)
Definition: cghdr.h:47
Definition: geom.h:28
#define POV_ROTATE
#define POV_TRANSLATE
gvrender_features_t render_features_pov
#define POV_TEXT
#define POV_VECTOR3
#define POV_COLORS
Definition: color.h:34
gvcolor_t pencolor
Definition: gvcjob.h:203
#define RENDERER_COLOR_TYPE
Definition: gvcjob.h:271
gvplugin_installed_t gvdevice_pov_types[]
char * name
Definition: textspan.h:49
point UR
Definition: geom.h:33
int x
Definition: geom.h:26
#define GVRENDER_DOES_MAP_RECTANGLE
Definition: gvcjob.h:101
char * cmdname
Definition: gvcommon.h:23
#define GVRENDER_DOES_TRANSFORM
Definition: gvcjob.h:97
#define POV_SPHERE
#define POV_SCALE1
boxf pageBox
Definition: gvcjob.h:323
obj_state_t * obj
Definition: gvcjob.h:278
gvplugin_installed_t gvrender_pov_types[]
int gvputs(GVJ_t *job, const char *s)
Definition: gvdevice.c:270
pointf devscale
Definition: gvcjob.h:343
#define POV_COLOR_NAME
#define GV_OBJ_EXT(type, obj, name)
box pageBoundingBox
Definition: gvcjob.h:338
char * str
Definition: textspan.h:59
#define POV_VERSION
color_type_t type
Definition: color.h:44
#define GVRENDER_DOES_Z
Definition: gvcjob.h:108
int graph_index
Definition: gvcjob.h:281
#define GVRENDER_DOES_MAP_CIRCLE
Definition: gvcjob.h:102
#define POV_COLOR_RGB
#define GVDEVICE_DOES_LAYERS
Definition: gvcjob.h:90
boxf canvasBox
Definition: gvcjob.h:331
double y
Definition: geom.h:28
#define POV_DECLARE
CGRAPH_API char * agnameof(void *)
Definition: id.c:143
pointf focus
Definition: gvcjob.h:325
char * string
Definition: color.h:41
pointf scale
Definition: gvcjob.h:341
GVCOMMON_t * common
Definition: gvcjob.h:276
char ** info
Definition: gvcommon.h:22
point pagesArrayElem
Definition: gvcjob.h:317
pointf view
Definition: gvcjob.h:330
PostscriptAlias * postscript_alias
Definition: textspan.h:51
point LL
Definition: geom.h:33
Definition: grammar.c:79
boxf bb
Definition: gvcjob.h:320
graph_t * g
Definition: gvcjob.h:195
void(* errorfn)(const char *fmt,...)
Definition: gvcommon.h:26
#define POV_LIGHT
#define GVRENDER_NO_WHITE_BG
Definition: gvcjob.h:109
#define POV_CAMERA
#define POV_SCALE3
pointf pageSize
Definition: gvcjob.h:324
int layerNum
Definition: gvcjob.h:311
format_type
int verbose
Definition: gvcommon.h:24
#define NULL
Definition: logic.h:39
pointf translation
Definition: gvcjob.h:342
#define POV_PIGMENT_COLOR
double x
Definition: geom.h:28
#define POV_SPHERE_SWEEP
int numPages
Definition: gvcjob.h:318
char just
Definition: textspan.h:65
pointf LL
Definition: geom.h:35
union obj_state_s::@23 u
#define POV_GLOBALS
#define END
gvdevice_features_t device_features_pov
gvrender_engine_t pov_engine
#define M_PI
Definition: arith.h:77
agxbuf * str
Definition: htmlparse.c:85
gvcolor_t fillcolor
Definition: gvcjob.h:203
node_t * n
Definition: gvcjob.h:197
double penwidth
Definition: gvcjob.h:208
#define POV_DEFAULT
#define POV_INCLUDE
int y
Definition: geom.h:26
unsigned char rgba[4]
Definition: color.h:38
double zoom
Definition: gvcjob.h:327
char * el(GVJ_t *job, char *template,...)
pointf UR
Definition: geom.h:35
#define GVDEVICE_DOES_TRUECOLOR
Definition: gvcjob.h:92
void gvprintf(GVJ_t *job, const char *format,...)
Definition: gvdevice.c:389
textfont_t * font
Definition: textspan.h:60
#define GVRENDER_DOES_MAP_BSPLINE
Definition: gvcjob.h:105
#define POV_SKY_AND_GND