X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fextension%2Finternal%2Fpov-out.cpp;h=6dd62206c20402ce101af71d7315ff91637ced89;hb=db3d7e286956ffa1408807197971d5277eea3b31;hp=05811604038f727e39f842ed5eb65e044b463e0e;hpb=a6988c83e9af8585b15319bf204be9382260b739;p=inkscape.git diff --git a/src/extension/internal/pov-out.cpp b/src/extension/internal/pov-out.cpp index 058116040..6dd62206c 100644 --- a/src/extension/internal/pov-out.cpp +++ b/src/extension/internal/pov-out.cpp @@ -9,9 +9,9 @@ * http://www.povray.org * * Authors: - * Bob Jamison + * Bob Jamison * - * Copyright (C) 2004 Authors + * Copyright (C) 2004-2008 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -28,39 +28,26 @@ #include "libnr/n-art-bpath.h" #include "extension/system.h" - - #include "io/sys.h" -namespace Inkscape { -namespace Extension { -namespace Internal { +#include +#include +#include - -static const char * -dstr(gchar *sbuffer, double d) +namespace Inkscape +{ +namespace Extension +{ +namespace Internal { - return (const char *)g_ascii_formatd(sbuffer, - G_ASCII_DTOSTR_BUF_SIZE, "%.8g", (gdouble)d); -} -/** - * Make sure that we are in the database - */ -bool -PovOutput::check (Inkscape::Extension::Extension *module) -{ - /* We don't need a Key - if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_OUTPUT_POV)) - return FALSE; - */ - - return TRUE; -} +//######################################################################## +//# U T I L I T Y +//######################################################################## @@ -73,30 +60,16 @@ findElementsByTagName(std::vector &results, Inkscape::XML::Node *node, char const *name) { - if ( !name - || strcmp(node->name(), name) == 0 ) { + if ( !name || strcmp(node->name(), name) == 0 ) results.push_back(node); - } - for (Inkscape::XML::Node *child = node->firstChild() ; child ; child = child->next()) + for (Inkscape::XML::Node *child = node->firstChild() ; child ; + child = child->next()) findElementsByTagName( results, child, name ); } -/** - * used for saving information about shapes - */ -class PovShapeInfo -{ -public: - PovShapeInfo() - {} - virtual ~PovShapeInfo() - {} - std::string id; - std::string color; -}; @@ -104,96 +77,238 @@ static double effective_opacity(SPItem const *item) { double ret = 1.0; - for (SPObject const *obj = item; obj; obj = obj->parent) { + for (SPObject const *obj = item; obj; obj = obj->parent) + { SPStyle const *const style = SP_OBJECT_STYLE(obj); g_return_val_if_fail(style, ret); ret *= SP_SCALE24_TO_FLOAT(style->opacity.value); - } + } return ret; } + + + +//######################################################################## +//# OUTPUT FORMATTING +//######################################################################## + + +/** + * We want to control floating output format + */ +static PovOutput::String dstr(double d) +{ + char dbuf[G_ASCII_DTOSTR_BUF_SIZE+1]; + g_ascii_formatd(dbuf, G_ASCII_DTOSTR_BUF_SIZE, + "%.8f", (gdouble)d); + PovOutput::String s = dbuf; + return s; +} + + + + /** - * Saves the of an Inkscape SVG file as PovRay spline definitions -*/ -void -PovOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *uri) + * Output data to the buffer, printf()-style + */ +void PovOutput::out(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + gchar *output = g_strdup_vprintf(fmt, args); + va_end(args); + outbuf.append(output); + g_free(output); +} + + + + + +/** + * Output a 2d vector + */ +void PovOutput::vec2(double a, double b) +{ + out("<%s, %s>", dstr(a).c_str(), dstr(b).c_str()); +} + + + +/** + * Output a 3d vector + */ +void PovOutput::vec3(double a, double b, double c) +{ + out("<%s, %s, %s>", dstr(a).c_str(), dstr(b).c_str(), dstr(c).c_str()); +} + + + +/** + * Output a v4d ector + */ +void PovOutput::vec4(double a, double b, double c, double d) +{ + out("<%s, %s, %s, %s>", dstr(a).c_str(), dstr(b).c_str(), + dstr(c).c_str(), dstr(d).c_str()); +} + + + +/** + * Output an rgbf color vector + */ +void PovOutput::rgbf(double r, double g, double b, double f) +{ + //"rgbf < %1.3f, %1.3f, %1.3f %1.3f>" + out("rgbf "); + vec4(r, g, b, f); +} + + + +/** + * Output one bezier's start, start-control, end-control, and end nodes + */ +void PovOutput::segment(int segNr, + double startX, double startY, + double startCtrlX, double startCtrlY, + double endCtrlX, double endCtrlY, + double endX, double endY) +{ + //" /*%4d*/ <%f, %f>, <%f, %f>, <%f,%f>, <%f,%f>" + out(" /*%4d*/ ", segNr); + vec2(startX, startY); + out(", "); + vec2(startCtrlX, startCtrlY); + out(", "); + vec2(endCtrlX, endCtrlY); + out(", "); + vec2(endX, endY); +} + + + + + +/** + * Output the file header + */ +void PovOutput::doHeader() +{ + time_t tim = time(NULL); + out("/*###################################################################\n"); + out("### This PovRay document was generated by Inkscape\n"); + out("### http://www.inkscape.org\n"); + out("### Created: %s", ctime(&tim)); + out("### Version: %s\n", VERSION); + out("#####################################################################\n"); + out("### NOTES:\n"); + out("### ============\n"); + out("### POVRay information can be found at\n"); + out("### http://www.povray.org\n"); + out("###\n"); + out("### The 'AllShapes' objects at the bottom are provided as a\n"); + out("### preview of how the output would look in a trace. However,\n"); + out("### the main intent of this file is to provide the individual\n"); + out("### shapes for inclusion in a POV project.\n"); + out("###\n"); + out("### For an example of how to use this file, look at\n"); + out("### share/examples/istest.pov\n"); + out("###\n"); + out("### If you have any problems with this output, please see the\n"); + out("### Inkscape project at http://www.inkscape.org, or visit\n"); + out("### the #inkscape channel on irc.freenode.net . \n"); + out("###\n"); + out("###################################################################*/\n"); + out("\n\n"); + out("/*###################################################################\n"); + out("## Exports in this file\n"); + out("##==========================\n"); + out("## Shapes : %d\n", nrShapes); + out("## Segments : %d\n", nrSegments); + out("## Nodes : %d\n", nrNodes); + out("###################################################################*/\n"); + out("\n\n\n"); +} + + + +/** + * Output the file footer + */ +void PovOutput::doTail() +{ + out("\n\n"); + out("/*###################################################################\n"); + out("### E N D F I L E\n"); + out("###################################################################*/\n"); + out("\n\n"); +} + + + +/** + * Output the curve data to buffer + */ +void PovOutput::doCurves(SPDocument *doc) { std::vectorresults; //findElementsByTagName(results, SP_ACTIVE_DOCUMENT->rroot, "path"); - findElementsByTagName(results, SP_ACTIVE_DOCUMENT->rroot, NULL);//Check all nodes + findElementsByTagName(results, SP_ACTIVE_DOCUMENT->rroot, NULL); if (results.size() == 0) return; - Inkscape::IO::dump_fopen_call(uri, "L"); - FILE *f = Inkscape::IO::fopen_utf8name(uri, "w"); - if (!f) - return; - time_t tim = time(NULL); - fprintf(f, "/*#################################################\n"); - fprintf(f, "### This PovRay document was generated by Inkscape\n"); - fprintf(f, "### http://www.inkscape.org\n"); - fprintf(f, "### Created: %s", ctime(&tim)); - fprintf(f, "##################################################*/\n\n\n"); - - std::vectorpovShapes; //A list for saving information about the shapes - - //we only need 8 for printf() calls that call dstr() 8 times - gchar s1[G_ASCII_DTOSTR_BUF_SIZE + 1]; - gchar s2[G_ASCII_DTOSTR_BUF_SIZE + 1]; - gchar s3[G_ASCII_DTOSTR_BUF_SIZE + 1]; - gchar s4[G_ASCII_DTOSTR_BUF_SIZE + 1]; - gchar s5[G_ASCII_DTOSTR_BUF_SIZE + 1]; - gchar s6[G_ASCII_DTOSTR_BUF_SIZE + 1]; - gchar s7[G_ASCII_DTOSTR_BUF_SIZE + 1]; - gchar s8[G_ASCII_DTOSTR_BUF_SIZE + 1]; - double bignum = 1000000.0; double minx = bignum; double maxx = -bignum; double miny = bignum; double maxy = -bignum; - - - unsigned indx; - for (indx = 0; indx < results.size() ; indx++) - { + for (unsigned int indx = 0; indx < results.size() ; indx++) + { //### Fetch the object from the repr info Inkscape::XML::Node *rpath = results[indx]; - gchar *id = (gchar *)rpath->attribute("id"); + char *str = (char *) rpath->attribute("id"); + if (!str) + continue; + + String id = str; SPObject *reprobj = SP_ACTIVE_DOCUMENT->getObjectByRepr(rpath); if (!reprobj) continue; //### Get the transform of the item if (!SP_IS_ITEM(reprobj)) - { continue; - } + SPItem *item = SP_ITEM(reprobj); NR::Matrix tf = sp_item_i2d_affine(item); //### Get the Shape if (!SP_IS_SHAPE(reprobj))//Bulia's suggestion. Allow all shapes - { continue; - } + SPShape *shape = SP_SHAPE(reprobj); SPCurve *curve = shape->curve; - if (sp_curve_empty(curve)) + if (curve->is_empty()) continue; + + nrShapes++; PovShapeInfo shapeInfo; - - shapeInfo.id = id; - shapeInfo.color = ""; + shapeInfo.id = id; + shapeInfo.color = ""; //Try to get the fill color of the shape SPStyle *style = SP_OBJECT_STYLE(shape); /* fixme: Handle other fill types, even if this means translating gradients to a single flat colour. */ - if (style && (style->fill.type == SP_PAINT_TYPE_COLOR)) { + if (style && (style->fill.isColor())) + { // see color.h for how to parse SPColor float rgb[3]; sp_color_get_rgb_floatv(&style->fill.value.color, rgb); @@ -201,25 +316,25 @@ PovOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const * * effective_opacity(shape) ); //gchar *str = g_strdup_printf("rgbf < %1.3f, %1.3f, %1.3f %1.3f>", // rgb[0], rgb[1], rgb[2], 1.0 - dopacity); - gchar *str = g_strdup_printf("rgbf < %s, %s, %s %s>", - dstr(s1, rgb[0]), dstr(s2, rgb[1]), dstr(s3, rgb[2]), dstr(s4, 1.0 - dopacity)); - - shapeInfo.color += str; - g_free(str); - } + String rgbf = "rgbf <"; + rgbf.append(dstr(rgb[0])); rgbf.append(", "); + rgbf.append(dstr(rgb[1])); rgbf.append(", "); + rgbf.append(dstr(rgb[2])); rgbf.append(", "); + rgbf.append(dstr(1.0 - dopacity)); rgbf.append(">"); + shapeInfo.color += rgbf; + } povShapes.push_back(shapeInfo); //passed all tests. save the info - int curveNr; + int curveLength = SP_CURVE_LENGTH(curve); //Count the NR_CURVETOs/LINETOs int segmentCount=0; - NArtBpath *bp = curve->bpath; - for (curveNr=0 ; curveNrlength ; curveNr++, bp++) + NArtBpath const *bp = SP_CURVE_BPATH(curve); + for (int curveNr=0 ; curveNrcode == NR_CURVETO || bp->code == NR_LINETO) segmentCount++; - bp = curve->bpath; double cminx = bignum; double cmaxx = -bignum; double cminy = bignum; @@ -227,19 +342,25 @@ PovOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const * double lastx = 0.0; double lasty = 0.0; - fprintf(f, "/*##############################################\n"); - fprintf(f, "### PRISM: %s\n", id); - fprintf(f, "##############################################*/\n"); - fprintf(f, "#declare %s = prism {\n", id); - fprintf(f, " linear_sweep\n"); - fprintf(f, " bezier_spline\n"); - fprintf(f, " 1.0, //top\n"); - fprintf(f, " 0.0, //bottom\n"); - fprintf(f, " %d, //nr points\n", segmentCount * 4); + out("/*###################################################\n"); + out("### PRISM: %s\n", id.c_str()); + out("###################################################*/\n"); + out("#declare %s = prism {\n", id.c_str()); + out(" linear_sweep\n"); + out(" bezier_spline\n"); + out(" 1.0, //top\n"); + out(" 0.0, //bottom\n"); + out(" %d //nr points\n", segmentCount * 4); int segmentNr = 0; - for (bp = curve->bpath, curveNr=0 ; curveNrlength ; curveNr++, bp++) { + bp = SP_CURVE_BPATH(curve); + + nrSegments += curveLength; + + for (int curveNr=0 ; curveNr < curveLength ; curveNr++) + { using NR::X; using NR::Y; + //transform points. note overloaded '*' NR::Point const p1(bp->c(1) * tf); NR::Point const p2(bp->c(2) * tf); NR::Point const p3(bp->c(3) * tf); @@ -247,26 +368,26 @@ PovOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const * double const x2 = p2[X], y2 = p2[Y]; double const x3 = p3[X], y3 = p3[Y]; - switch (bp->code) { + switch (bp->code) + { case NR_MOVETO: case NR_MOVETO_OPEN: + { //fprintf(f, "moveto: %f %f\n", bp->x3, bp->y3); break; + } case NR_CURVETO: - + { //fprintf(f, " /*%4d*/ <%f, %f>, <%f, %f>, <%f,%f>, <%f,%f>", // segmentNr++, lastx, lasty, x1, y1, x2, y2, x3, y3); - fprintf(f, " /*%4d*/ <%s, %s>, <%s, %s>, <%s,%s>, <%s,%s>", - segmentNr++, - dstr(s1, lastx), dstr(s2, lasty), - dstr(s3, x1), dstr(s4, y1), - dstr(s5, x2), dstr(s6, y2), - dstr(s7, x3), dstr(s8, y3)); + segment(segmentNr++, + lastx, lasty, x1, y1, x2, y2, x3, y3); + nrNodes += 8; if (segmentNr < segmentCount) - fprintf(f, ",\n"); + out(",\n"); else - fprintf(f, "\n"); + out("\n"); if (lastx < cminx) cminx = lastx; @@ -277,21 +398,21 @@ PovOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const * if (lasty > cmaxy) cmaxy = lasty; break; + } case NR_LINETO: - + { + //NOTE: we need to carefully handle line->curve and curve->line + // transitions. //fprintf(f, " /*%4d*/ <%f, %f>, <%f, %f>, <%f,%f>, <%f,%f>", // segmentNr++, lastx, lasty, lastx, lasty, x3, y3, x3, y3); - fprintf(f, " /*%4d*/ <%s, %s>, <%s, %s>, <%s,%s>, <%s,%s>", - segmentNr++, - dstr(s1, lastx), dstr(s2, lasty), - dstr(s3, lastx), dstr(s4, lasty), - dstr(s5, x3), dstr(s6, y3), - dstr(s7, x3), dstr(s8, y3)); + segment(segmentNr++, + lastx, lasty, lastx, lasty, x3, y3, x3, y3); + nrNodes += 8; if (segmentNr < segmentCount) - fprintf(f, ",\n"); + out(",\n"); else - fprintf(f, "\n"); + out("\n"); //fprintf(f, "lineto\n"); if (lastx < cminx) @@ -303,38 +424,37 @@ PovOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const * if (lasty > cmaxy) cmaxy = lasty; break; + } case NR_END: + { //fprintf(f, "end\n"); break; - } + } + } lastx = x3; lasty = y3; - } - fprintf(f, "}\n"); - /* - fprintf(f, "#declare %s_MIN_X = %4.3f;\n", id, cminx); - fprintf(f, "#declare %s_CENTER_X = %4.3f;\n", id, (cmaxx+cminx)/2.0); - fprintf(f, "#declare %s_MAX_X = %4.3f;\n", id, cmaxx); - fprintf(f, "#declare %s_WIDTH = %4.3f;\n", id, cmaxx-cminx); - fprintf(f, "#declare %s_MIN_Y = %4.3f;\n", id, cminy); - fprintf(f, "#declare %s_CENTER_Y = %4.3f;\n", id, (cmaxy+cminy)/2.0); - fprintf(f, "#declare %s_MAX_Y = %4.3f;\n", id, cmaxy); - fprintf(f, "#declare %s_HEIGHT = %4.3f;\n", id, cmaxy-cminy); - */ - fprintf(f, "#declare %s_MIN_X = %s;\n", id, dstr(s1, cminx)); - fprintf(f, "#declare %s_CENTER_X = %s;\n", id, dstr(s1, (cmaxx+cminx)/2.0)); - fprintf(f, "#declare %s_MAX_X = %s;\n", id, dstr(s1, cmaxx)); - fprintf(f, "#declare %s_WIDTH = %s;\n", id, dstr(s1, cmaxx-cminx)); - fprintf(f, "#declare %s_MIN_Y = %s;\n", id, dstr(s1, cminy)); - fprintf(f, "#declare %s_CENTER_Y = %s;\n", id, dstr(s1, (cmaxy+cminy)/2.0)); - fprintf(f, "#declare %s_MAX_Y = %s;\n", id, dstr(s1, cmaxy)); - fprintf(f, "#declare %s_HEIGHT = %s;\n", id, dstr(s1, cmaxy-cminy)); + bp++; + } + out("}\n"); + + + //# prefix for following declarations + char *pfx = (char *)id.c_str(); + + out("#declare %s_MIN_X = %s;\n", pfx, dstr(cminx).c_str()); + out("#declare %s_CENTER_X = %s;\n", pfx, dstr((cmaxx+cminx)/2.0).c_str()); + out("#declare %s_MAX_X = %s;\n", pfx, dstr(cmaxx).c_str()); + out("#declare %s_WIDTH = %s;\n", pfx, dstr(cmaxx-cminx).c_str()); + out("#declare %s_MIN_Y = %s;\n", pfx, dstr(cminy).c_str()); + out("#declare %s_CENTER_Y = %s;\n", pfx, dstr((cmaxy+cminy)/2.0).c_str()); + out("#declare %s_MAX_Y = %s;\n", pfx, dstr(cmaxy).c_str()); + out("#declare %s_HEIGHT = %s;\n", pfx, dstr(cmaxy-cminy).c_str()); if (shapeInfo.color.length()>0) - fprintf(f, "#declare %s_COLOR = %s;\n", - id, shapeInfo.color.c_str()); - fprintf(f, "/*##############################################\n"); - fprintf(f, "### end %s\n", id); - fprintf(f, "##############################################*/\n\n\n\n"); + out("#declare %s_COLOR = %s;\n", + pfx, shapeInfo.color.c_str()); + out("/*###################################################\n"); + out("### end %s\n", id.c_str()); + out("###################################################*/\n\n\n\n"); if (cminx < minx) minx = cminx; if (cmaxx > maxx) @@ -344,103 +464,195 @@ PovOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const * if (cmaxy > maxy) maxy = cmaxy; - - }//for + }//for //## Let's make a union of all of the Shapes - if (!povShapes.empty()) { - char const *id = "AllShapes"; - fprintf(f, "/*##############################################\n"); - fprintf(f, "### UNION OF ALL SHAPES IN DOCUMENT\n"); - fprintf(f, "##############################################*/\n"); - fprintf(f, "\n\n"); - fprintf(f, "/**\n"); - fprintf(f, " * Allow the user to redefine the finish{}\n"); - fprintf(f, " * by declaring it before #including this file\n"); - fprintf(f, " */\n"); - fprintf(f, "#ifndef (%s_Finish)\n", id); - fprintf(f, "#declare %s_Finish = finish {\n", id); - fprintf(f, " phong 0.5\n"); - fprintf(f, " reflection 0.3\n"); - fprintf(f, " specular 0.5\n"); - fprintf(f, "}\n"); - fprintf(f, "#end\n"); - fprintf(f, "\n\n"); - fprintf(f, "#declare %s = union {\n", id); - for (unsigned i = 0 ; i < povShapes.size() ; i++) { - fprintf(f, " object { %s\n", povShapes[i].id.c_str()); - fprintf(f, " texture { \n"); + if (povShapes.size()>0) + { + String id = "AllShapes"; + char *pfx = (char *)id.c_str(); + out("/*###################################################\n"); + out("### UNION OF ALL SHAPES IN DOCUMENT\n"); + out("###################################################*/\n"); + out("\n\n"); + out("/**\n"); + out(" * Allow the user to redefine the finish{}\n"); + out(" * by declaring it before #including this file\n"); + out(" */\n"); + out("#ifndef (%s_Finish)\n", pfx); + out("#declare %s_Finish = finish {\n", pfx); + out(" phong 0.5\n"); + out(" reflection 0.3\n"); + out(" specular 0.5\n"); + out("}\n"); + out("#end\n"); + out("\n\n"); + out("#declare %s = union {\n", id.c_str()); + for (unsigned i = 0 ; i < povShapes.size() ; i++) + { + out(" object { %s\n", povShapes[i].id.c_str()); + out(" texture { \n"); if (povShapes[i].color.length()>0) - fprintf(f, " pigment { %s }\n", povShapes[i].color.c_str()); + out(" pigment { %s }\n", povShapes[i].color.c_str()); else - fprintf(f, " pigment { rgb <0,0,0> }\n"); - fprintf(f, " finish { %s_Finish }\n", id); - fprintf(f, " } \n"); - fprintf(f, " } \n"); - } - fprintf(f, "}\n\n\n\n"); + out(" pigment { rgb <0,0,0> }\n"); + out(" finish { %s_Finish }\n", pfx); + out(" } \n"); + out(" } \n"); + } + out("}\n\n\n\n"); double zinc = 0.2 / (double)povShapes.size(); - fprintf(f, "/*#### Same union, but with Z-diffs (actually Y in pov) ####*/\n"); - fprintf(f, "\n\n"); - fprintf(f, "/**\n"); - fprintf(f, " * Allow the user to redefine the Z-Increment\n"); - fprintf(f, " */\n"); - fprintf(f, "#ifndef (AllShapes_Z_Increment)\n"); - fprintf(f, "#declare AllShapes_Z_Increment = %s;\n", dstr(s1, zinc)); - fprintf(f, "#end\n"); - fprintf(f, "\n"); - fprintf(f, "#declare AllShapes_Z_Scale = 1.0;\n"); - fprintf(f, "\n\n"); - fprintf(f, "#declare %s_Z = union {\n", id); - for (unsigned i = 0 ; i < povShapes.size() ; i++) { - fprintf(f, " object { %s\n", povShapes[i].id.c_str()); - fprintf(f, " texture { \n"); + out("/*#### Same union, but with Z-diffs (actually Y in pov) ####*/\n"); + out("\n\n"); + out("/**\n"); + out(" * Allow the user to redefine the Z-Increment\n"); + out(" */\n"); + out("#ifndef (AllShapes_Z_Increment)\n"); + out("#declare AllShapes_Z_Increment = %s;\n", dstr(zinc).c_str()); + out("#end\n"); + out("\n"); + out("#declare AllShapes_Z_Scale = 1.0;\n"); + out("\n\n"); + out("#declare %s_Z = union {\n", pfx); + + for (unsigned i = 0 ; i < povShapes.size() ; i++) + { + out(" object { %s\n", povShapes[i].id.c_str()); + out(" texture { \n"); if (povShapes[i].color.length()>0) - fprintf(f, " pigment { %s }\n", povShapes[i].color.c_str()); + out(" pigment { %s }\n", povShapes[i].color.c_str()); else - fprintf(f, " pigment { rgb <0,0,0> }\n"); - fprintf(f, " finish { %s_Finish }\n", id); - fprintf(f, " } \n"); - fprintf(f, " scale <1, %s_Z_Scale, 1>\n", id); - fprintf(f, " } \n"); - fprintf(f, "#declare %s_Z_Scale = %s_Z_Scale + %s_Z_Increment;\n\n", - id, id, id); + out(" pigment { rgb <0,0,0> }\n"); + out(" finish { %s_Finish }\n", pfx); + out(" } \n"); + out(" scale <1, %s_Z_Scale, 1>\n", pfx); + out(" } \n"); + out("#declare %s_Z_Scale = %s_Z_Scale + %s_Z_Increment;\n\n", + pfx, pfx, pfx); + } + + out("}\n"); + + out("#declare %s_MIN_X = %s;\n", pfx, dstr(minx).c_str()); + out("#declare %s_CENTER_X = %s;\n", pfx, dstr((maxx+minx)/2.0).c_str()); + out("#declare %s_MAX_X = %s;\n", pfx, dstr(maxx).c_str()); + out("#declare %s_WIDTH = %s;\n", pfx, dstr(maxx-minx).c_str()); + out("#declare %s_MIN_Y = %s;\n", pfx, dstr(miny).c_str()); + out("#declare %s_CENTER_Y = %s;\n", pfx, dstr((maxy+miny)/2.0).c_str()); + out("#declare %s_MAX_Y = %s;\n", pfx, dstr(maxy).c_str()); + out("#declare %s_HEIGHT = %s;\n", pfx, dstr(maxy-miny).c_str()); + out("/*##############################################\n"); + out("### end %s\n", id.c_str()); + out("##############################################*/\n"); + out("\n\n"); } - fprintf(f, "}\n"); - /* - fprintf(f, "#declare %s_MIN_X = %4.3f;\n", id, minx); - fprintf(f, "#declare %s_CENTER_X = %4.3f;\n", id, (maxx+minx)/2.0); - fprintf(f, "#declare %s_MAX_X = %4.3f;\n", id, maxx); - fprintf(f, "#declare %s_WIDTH = %4.3f;\n", id, maxx-minx); - fprintf(f, "#declare %s_MIN_Y = %4.3f;\n", id, miny); - fprintf(f, "#declare %s_CENTER_Y = %4.3f;\n", id, (maxy+miny)/2.0); - fprintf(f, "#declare %s_MAX_Y = %4.3f;\n", id, maxy); - fprintf(f, "#declare %s_HEIGHT = %4.3f;\n", id, maxy-miny); - */ - fprintf(f, "#declare %s_MIN_X = %s;\n", id, dstr(s1, minx)); - fprintf(f, "#declare %s_CENTER_X = %s;\n", id, dstr(s1, (maxx+minx)/2.0)); - fprintf(f, "#declare %s_MAX_X = %s;\n", id, dstr(s1, maxx)); - fprintf(f, "#declare %s_WIDTH = %s;\n", id, dstr(s1, maxx-minx)); - fprintf(f, "#declare %s_MIN_Y = %s;\n", id, dstr(s1, miny)); - fprintf(f, "#declare %s_CENTER_Y = %s;\n", id, dstr(s1, (maxy+miny)/2.0)); - fprintf(f, "#declare %s_MAX_Y = %s;\n", id, dstr(s1, maxy)); - fprintf(f, "#declare %s_HEIGHT = %s;\n", id, dstr(s1, maxy-miny)); - fprintf(f, "/*##############################################\n"); - fprintf(f, "### end %s\n", id); - fprintf(f, "##############################################*/\n\n\n\n"); - } - - //All done +} + + + + +//######################################################################## +//# M A I N O U T P U T +//######################################################################## + + + +/** + * Set values back to initial state + */ +void PovOutput::reset() +{ + nrNodes = 0; + nrSegments = 0; + nrShapes = 0; + outbuf.clear(); + povShapes.clear(); +} + + + +/** + * Saves the of an Inkscape SVG file as PovRay spline definitions + */ +void PovOutput::saveDocument(SPDocument *doc, gchar const *uri) +{ + reset(); + + //###### SAVE IN POV FORMAT TO BUFFER + //# Lets do the curves first, to get the stats + doCurves(doc); + String curveBuf = outbuf; + outbuf.clear(); + + doHeader(); + + outbuf.append(curveBuf); + + doTail(); + + + + + //###### WRITE TO FILE + Inkscape::IO::dump_fopen_call(uri, "L"); + FILE *f = Inkscape::IO::fopen_utf8name(uri, "w"); + if (!f) + return; + + for (String::iterator iter = outbuf.begin() ; iter!=outbuf.end(); iter++) + { + int ch = *iter; + fputc(ch, f); + } + fclose(f); } + + + +//######################################################################## +//# EXTENSION API +//######################################################################## + + + #include "clear-n_.h" + + +/** + * API call to save document +*/ +void +PovOutput::save(Inkscape::Extension::Output *mod, + SPDocument *doc, gchar const *uri) +{ + saveDocument(doc, uri); +} + + + +/** + * Make sure that we are in the database + */ +bool PovOutput::check (Inkscape::Extension::Extension *module) +{ + /* We don't need a Key + if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_OUTPUT_POV)) + return FALSE; + */ + + return true; +} + + + /** * This is the definition of PovRay output. This function just * calls the extension system with the memory allocated XML that @@ -450,7 +662,7 @@ void PovOutput::init() { Inkscape::Extension::build_from_mem( - "\n" + "\n" "" N_("PovRay Output") "\n" "org.inkscape.output.pov\n" "\n" @@ -467,9 +679,9 @@ PovOutput::init() -} //namespace Internal -} //namespace Extension -} //namespace Inkscape +} // namespace Internal +} // namespace Extension +} // namespace Inkscape /*