SoFCVectorizeSVGAction.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <iomanip>
00027 # include <ios>
00028 #endif
00029 #include <Inventor/SbBasic.h>
00030 #include <Inventor/SbBSPTree.h>
00031 
00032 #include <Base/FileInfo.h>
00033 #include "SoFCVectorizeSVGAction.h"
00034 
00035 using namespace Gui;
00036 
00037 class SoVectorizeItem {
00038 public:
00039     SoVectorizeItem() {
00040         this->type = UNDEFINED;
00041         this->depth = 0.0f;
00042     }
00043     // quick and easy type system
00044     enum Type {
00045         UNDEFINED,
00046         LINE,
00047         TRIANGLE,
00048         TEXT,
00049         POINT,
00050         IMAGE
00051     };
00052     int type;
00053     float depth; // for depth sorting
00054 };
00055 
00056 class SoVectorizePoint : public SoVectorizeItem {
00057 public:
00058     SoVectorizePoint(void) {
00059         this->type = POINT;
00060         this->size = 1.0f;
00061     }
00062     int vidx;       // index to BSPtree coordinate
00063     float size;     // Coin size (pixels)
00064     uint32_t col;
00065 };
00066 
00067 class SoVectorizeTriangle : public SoVectorizeItem {
00068 public:
00069     SoVectorizeTriangle(void) {
00070         this->type = TRIANGLE;
00071     }
00072     int vidx[3];      // indices to BSPtree coordinates
00073     uint32_t col[3];
00074 };
00075 
00076 class SoVectorizeLine : public SoVectorizeItem {
00077 public:
00078     SoVectorizeLine(void) {
00079         this->type = LINE;
00080         this->pattern = 0xffff;
00081         this->width = 1.0f;
00082     }
00083     int vidx[2];       // indices to BSPtree coordinates
00084     uint32_t col[2];
00085     uint16_t pattern;  // Coin line pattern
00086     float width;       // Coin line width (pixels)
00087 };
00088 
00089 class SoVectorizeText : public SoVectorizeItem {
00090 public:
00091     SoVectorizeText(void) {
00092         this->type = TEXT;
00093     }
00094 
00095     enum Justification {
00096         LEFT,
00097         RIGHT,
00098         CENTER
00099     };
00100 
00101     SbName fontname;
00102     float fontsize;    // size in normalized coordinates
00103     SbString string;
00104     SbVec2f pos;       // pos in normalized coordinates
00105     uint32_t col;
00106     Justification justification;
00107 };
00108 
00109 class SoVectorizeImage : public SoVectorizeItem {
00110 public:
00111     SoVectorizeImage(void) {
00112         this->type = IMAGE;
00113     }
00114 
00115     SbVec2f pos;        // pos in normalized coordinates
00116     SbVec2f size;       // size in normalized coordinates
00117 
00118     struct Image {
00119         const unsigned char * data;
00120         SbVec2s size;
00121         int nc;
00122     } image;
00123 };
00124 
00125 // ----------------------------------------------------------------
00126 
00127 SoSVGVectorOutput::SoSVGVectorOutput()
00128 {
00129 }
00130 
00131 SoSVGVectorOutput::~SoSVGVectorOutput()
00132 {
00133     closeFile();
00134 }
00135 
00136 SbBool SoSVGVectorOutput::openFile (const char *filename)
00137 {
00138     Base::FileInfo fi(filename);
00139 #ifdef _MSC_VER
00140     this->file.open(fi.toStdWString().c_str(), std::ios::out | std::ios::binary);
00141 #else
00142     this->file.open(fi.filePath().c_str(), std::ios::out | std::ios::binary);
00143 #endif
00144 
00145     return this->file.is_open();
00146 }
00147 
00148 void SoSVGVectorOutput::closeFile (void)
00149 {
00150     if (this->file.is_open())
00151         this->file.close();
00152 }
00153 
00154 std::fstream& SoSVGVectorOutput::getFileStream()
00155 {
00156     return this->file;
00157 }
00158 
00159 // ----------------------------------------------------------------
00160 
00161 namespace Gui {
00162 class SoFCVectorizeSVGActionP
00163 {
00164 public:
00165     SoFCVectorizeSVGActionP(SoFCVectorizeSVGAction * p) {
00166         this->publ = p;
00167     }
00168 
00169     void printCircle(const SbVec3f & v, const SbColor & c, const float radius) const;
00170     void printSquare(const SbVec3f & v, const SbColor & c, const float size) const;
00171     void printTriangle(const SbVec3f * v, const SbColor * c) const;
00172     void printTriangle(const SoVectorizeTriangle * item) const;
00173     void printLine(const SoVectorizeLine * item) const;
00174     void printPoint(const SoVectorizePoint * item) const;
00175     void printText(const SoVectorizeText * item) const;
00176     void printImage(const SoVectorizeImage * item) const;
00177 
00178 private:
00179     SoFCVectorizeSVGAction * publ;
00180 };
00181 }
00182 
00183 void SoFCVectorizeSVGActionP::printText(const SoVectorizeText * item) const
00184 {
00185     SbVec2f mul = publ->getRotatedViewportSize();
00186     SbVec2f add = publ->getRotatedViewportStartpos();
00187     float posx = item->pos[0]*mul[0]+add[0];
00188     float posy = item->pos[1]*mul[1]+add[1];
00189 
00190     std::ostream& str = publ->getSVGOutput()->getFileStream();
00191     str << "<text x=\"" << posx << "\" y=\"" << posy << "\" "
00192            "font-size=\"" << item->fontsize * mul[1] << "px\">" 
00193         << item->string.getString() << "</text>" << std::endl;
00194 }
00195 
00196 void SoFCVectorizeSVGActionP::printTriangle(const SoVectorizeTriangle * item) const
00197 {
00198     SbVec2f mul = publ->getRotatedViewportSize();
00199     SbVec2f add = publ->getRotatedViewportStartpos();
00200 
00201     const SbBSPTree & bsp = publ->getBSPTree();
00202 
00203     SbVec3f v[3];
00204     SbColor c[3];
00205     float t[3];
00206 
00207     for (int i = 0; i < 3; i++) {
00208         v[i] = bsp.getPoint(item->vidx[i]);
00209         v[i][0] = (v[i][0] * mul[0]) + add[0];
00210         v[i][1] = ((1.0f-v[i][1]) * mul[1]) + add[1];
00211         c[i].setPackedValue(item->col[i], t[i]);
00212     }
00213     this->printTriangle((SbVec3f*)v, (SbColor*)c);
00214 }
00215 /* TODO: Support gradients, e.g.
00216   <defs>
00217     <linearGradient id="verlauf" x1="0%" y1="100%" x2="100%" y2="100%">
00218       <stop offset="0%" stop-color="black" stop-opacity="100%" />
00219       <stop offset="100%" stop-color="white" stop-opacity="50%" />
00220     </linearGradient>
00221   </defs>
00222 */
00223 /* Example: color per vertex
00224 #Inventor V2.1 ascii
00225 Separator {
00226 
00227   Coordinate3 {
00228     point [ 0.000000  0.000000  0.000000,
00229         100.000000  50.000000  0.000000,
00230         0.000000  100.000000  0.000000 ]
00231 
00232   }
00233   Material {
00234     diffuseColor [ 1 1 0, 0 0 1, 1 0 0 ]
00235   }
00236   
00237   MaterialBinding {
00238     value PER_VERTEX
00239   }
00240   IndexedFaceSet {
00241     coordIndex [ 0, 1, 2, -1 ]
00242   }
00243 }
00244 
00245 <?xml version="1.0"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
00246         "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
00247 <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
00248         <defs>
00249                 <linearGradient id="red" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="35" y2="80">
00250                         <stop offset="0" stop-color="rgb(255,0,0)" stop-opacity="1"/>
00251                         <stop offset="1" stop-color="rgb(255,0,0)" stop-opacity="0"/>
00252                 </linearGradient>
00253                 <linearGradient id="blue" gradientUnits="userSpaceOnUse" x1="100" y1="50" x2="0" y2="50">
00254                         <stop offset="0" stop-color="rgb(0,0,255)" stop-opacity="1"/>
00255                         <stop offset="1" stop-color="rgb(0,0,255)" stop-opacity="0"/>
00256                 </linearGradient>
00257                 <linearGradient id="yellow" gradientUnits="userSpaceOnUse" x1="0" y1="100" x2="40" y2="20">
00258                         <stop offset="0" stop-color="rgb(255,255,0)" stop-opacity="1"/>
00259                         <stop offset="1" stop-color="rgb(255,255,0)" stop-opacity="0"/>
00260                 </linearGradient>
00261                 <path id="triangle1" d="M0 0 L100 50 L0 100 z"/>
00262 <filter id="colorAdd">
00263         <feComposite in="SourceGraphic" in2="BackgroundImage" operator="arithmetic" k2="1" k3="1"/>
00264 </filter>
00265 <filter id="Matrix1">
00266         <feColorMatrix type="matrix" values="
00267         1 0 0 0 0
00268         0 1 0 0 0
00269         0 0 1 0 0
00270         1 1 1 1 0
00271         0 0 0 0 1
00272         "/>
00273 </filter>
00274 </defs>
00275 <g filter="url(#Matrix1)">
00276         <use xlink:href="#triangle1" fill="url(#blue)"/>
00277         <use xlink:href="#triangle1" fill="url(#yellow)" filter="url(#colorAdd)"/>
00278         <use xlink:href="#triangle1" fill="url(#red)" filter="url(#colorAdd)"/>
00279 </g>
00280 </svg>
00281 */
00282 void SoFCVectorizeSVGActionP::printTriangle(const SbVec3f * v, const SbColor * c) const
00283 {
00284     if (v[0] == v[1] || v[1] == v[2] || v[0] == v[2]) return;
00285     uint32_t cc = c->getPackedValue();
00286 
00287     std::ostream& str = publ->getSVGOutput()->getFileStream();
00288     str << "<path d=\"M "
00289         << v[2][0] << "," << v[2][1] << " L "
00290         << v[1][0] << "," << v[1][1] << " "
00291         << v[0][0] << "," << v[0][1] << " z\"" << std::endl
00292         << "    style=\"fill:#"
00293         << std::hex << std::setw(6) << std::setfill('0') << (cc >> 8)
00294         << "; stroke:#"
00295         << std::hex << std::setw(6) << std::setfill('0') << (cc >> 8)
00296         << ";" << std::endl
00297         << "    stroke-width:1.0;" << std::endl
00298         << "    stroke-linecap:round;stroke-linejoin:round\"/>" << std::endl;
00299 }
00300 
00301 void SoFCVectorizeSVGActionP::printCircle(const SbVec3f & v, const SbColor & c, const float radius) const
00302 {
00303     // todo
00304 }
00305 
00306 void SoFCVectorizeSVGActionP::printSquare(const SbVec3f & v, const SbColor & c, const float size) const
00307 {
00308     // todo
00309 }
00310 
00311 void SoFCVectorizeSVGActionP::printLine(const SoVectorizeLine * item) const
00312 {
00313     SbVec2f mul = publ->getRotatedViewportSize();
00314     SbVec2f add = publ->getRotatedViewportStartpos();
00315 
00316     const SbBSPTree & bsp = publ->getBSPTree();
00317 
00318     SbVec3f v[2];
00319     SbColor c[2];
00320     float t[2];
00321 
00322     for (int i = 0; i < 2; i++) {
00323         v[i] = bsp.getPoint(item->vidx[i]);
00324         v[i][0] = (v[i][0] * mul[0]) + add[0];
00325         v[i][1] = ((1.0f-v[i][1]) * mul[1]) + add[1];
00326         c[i].setPackedValue(item->col[i], t[i]);
00327     }
00328     uint32_t cc = c->getPackedValue();
00329 
00330     std::ostream& str = publ->getSVGOutput()->getFileStream();
00331     str << "<line "
00332         << "x1=\"" << v[0][0] << "\" y1=\"" << v[0][1] << "\" "
00333         << "x2=\"" << v[1][0] << "\" y2=\"" << v[1][1] << "\" "
00334         << "stroke=\"#"
00335         << std::hex << std::setw(6) << std::setfill('0') << (cc >> 8)
00336         << "\" stroke-width=\"1px\" />\n";
00337 }
00338 
00339 void SoFCVectorizeSVGActionP::printPoint(const SoVectorizePoint * item) const
00340 {
00341     // todo
00342 }
00343 
00344 void SoFCVectorizeSVGActionP::printImage(const SoVectorizeImage * item) const
00345 {
00346     // todo
00347 }
00348 
00349 // -------------------------------------------------------
00350 
00351 SO_ACTION_SOURCE(SoFCVectorizeSVGAction);
00352 
00353 void SoFCVectorizeSVGAction::initClass(void)
00354 {
00355     SO_ACTION_INIT_CLASS(SoFCVectorizeSVGAction, SoVectorizeAction);
00356 }
00357 
00358 SoFCVectorizeSVGAction::SoFCVectorizeSVGAction()
00359 {
00360     SO_ACTION_CONSTRUCTOR(SoFCVectorizeSVGAction);
00361     this->setOutput(new SoSVGVectorOutput);
00362     this->p = new SoFCVectorizeSVGActionP(this);
00363 }
00364 
00365 SoFCVectorizeSVGAction::~SoFCVectorizeSVGAction()
00366 {
00367     delete this->p;
00368 }
00369 
00370 SoSVGVectorOutput *
00371 SoFCVectorizeSVGAction::getSVGOutput(void) const
00372 {
00373     return static_cast<SoSVGVectorOutput*>(SoVectorizeAction::getOutput());
00374 }
00375 
00376 void SoFCVectorizeSVGAction::printHeader(void) const
00377 {
00378     std::ostream& str = this->getSVGOutput()->getFileStream();
00379     str << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" << std::endl;
00380     str << "<!-- Created with FreeCAD (http://free-cad.sourceforge.net) -->" << std::endl;
00381     str << "<svg xmlns=\"http://www.w3.org/2000/svg\"" << std::endl;
00382     str << "     xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:ev=\"http://www.w3.org/2001/xml-events\"" << std::endl;
00383     str << "     version=\"1.1\" baseProfile=\"full\"" << std::endl;
00384 
00385     SbVec2f size = getPageSize();
00386     if (this->getOrientation() == LANDSCAPE)
00387         SbSwap<float>(size[0], size[1]);
00388     str << "     width=\"" << size[0] << "\" height=\"" << size[1] << "\">" << std::endl;
00389     str << "<g>" << std::endl;
00390 }
00391 
00392 void SoFCVectorizeSVGAction::printFooter(void) const
00393 {
00394     std::ostream& str = this->getSVGOutput()->getFileStream();
00395     str << "</g>" << std::endl;
00396     str << "</svg>";
00397 }
00398 
00399 void SoFCVectorizeSVGAction::printViewport(void) const
00400 {
00401 }
00402 
00403 void SoFCVectorizeSVGAction::printBackground(void) const
00404 {
00405     SbVec2f mul = getRotatedViewportSize();
00406     SbVec2f add = getRotatedViewportStartpos();
00407 
00408     float x[2],y[2];
00409     x[0] = add[0];
00410     x[1] = mul[0] - add[0];
00411     y[0] = add[1];
00412     y[1] = mul[1] - add[1];
00413 
00414     SbColor bg;
00415     (void)this->getBackgroundColor(bg);
00416     uint32_t cc = bg.getPackedValue();
00417 
00418     std::ostream& str = this->getSVGOutput()->getFileStream();
00419     str << "</g>" << std::endl;
00420     str << "<path" << std::endl;
00421     str << "   d=\"M "
00422         << x[0] << "," << y[0] << " L "
00423         << x[1] << "," << y[0] << " L "
00424         << x[1] << "," << y[1] << " L "
00425         << x[0] << "," << y[1] << " L "
00426         << x[0] << "," << y[0] << " z \"" << std::endl;
00427     str << "   style=\"fill:#"
00428         << std::hex << std::setw(6) << std::setfill('0') << (cc >> 8)
00429         << ";fill-opacity:1;fill-rule:evenodd;stroke:none;"
00430            "stroke-width:1px;stroke-linecap:butt;stroke-linejoin:"
00431            "miter;stroke-opacity:1\" />\n";
00432     str << "<g>" << std::endl;
00433 }
00434 
00435 void SoFCVectorizeSVGAction::printItem(const SoVectorizeItem * item) const
00436 {
00437     switch (item->type) {
00438     case SoVectorizeItem::TRIANGLE:
00439         this->p->printTriangle(static_cast<const SoVectorizeTriangle*>(item));
00440         break;
00441     case SoVectorizeItem::LINE:
00442         this->p->printLine(static_cast<const SoVectorizeLine*>(item));
00443         break;
00444     case SoVectorizeItem::POINT:
00445         this->p->printPoint(static_cast<const SoVectorizePoint*>(item));
00446         break;
00447     case SoVectorizeItem::TEXT:
00448         this->p->printText(static_cast<const SoVectorizeText*>(item));
00449         break;
00450     case SoVectorizeItem::IMAGE:
00451         this->p->printImage(static_cast<const SoVectorizeImage*>(item));
00452         break;
00453     default:
00454         assert(0 && "unsupported item");
00455         break;
00456     }
00457 }

Generated on Wed Nov 23 19:00:40 2011 for FreeCAD by  doxygen 1.6.1