00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <stdio.h>
00046 #include "Primitive.h"
00047 #include "Exporter.h"
00048 #include "math.h"
00049
00050 using namespace vrender ;
00051 using namespace std ;
00052
00053 const double EPSExporter::EPS_GOURAUD_THRESHOLD = 0.05 ;
00054 const char *EPSExporter::CREATOR = "VRender library - (c) Cyril Soler 2005" ;
00055
00056 float EPSExporter::last_r = -1.0 ;
00057 float EPSExporter::last_g = -1.0 ;
00058 float EPSExporter::last_b = -1.0 ;
00059
00060 EPSExporter::EPSExporter()
00061 {
00062 last_r = -1 ;
00063 last_g = -1 ;
00064 last_b = -1 ;
00065 }
00066
00067 void EPSExporter::writeHeader(QTextStream& out) const
00068 {
00069
00070
00071 out << "%!PS-Adobe-2.0 EPSF-2.0\n";
00072
00073 out << "%%%%HiResBoundingBox: " << _xmin << " " << _ymin << " " << _xmax << " " << _ymax << "\n";
00074
00075 out << "%%%%Creator: " << CREATOR << " (using OpenGL feedback)\n";
00076 out << "%%EndComments\n\ngsave\n\n";
00077
00078 out << "%\n";
00079 out << "% Contributors:\n";
00080 out << "%\n";
00081 out << "% Frederic Delhoume (delhoume@ilog.fr):\n";
00082 out << "% Gouraud triangle PostScript fragment\n";
00083 out << "%\n";
00084 out << "% Cyril Soler (csoler@imag.fr):\n";
00085 out << "% BSP Sort,\n";
00086 out << "% Topological and advanced topological Sort,\n";
00087 out << "% Hidden surface removal,\n";
00088 out << "% Xfig3.2 (and EPS) format\n";
00089 out << "%\n\n";
00090
00091 out << "/threshold " << EPS_GOURAUD_THRESHOLD << " def\n";
00092
00093 for(int i = 0; GOURAUD_TRIANGLE_EPS[i] != NULL; i++)
00094 out << GOURAUD_TRIANGLE_EPS[i] << "\n";
00095 #ifdef A_VOIR
00096 out << "\n" << << " setlinewidth\n\n", _lineWidth;
00097 #endif
00098
00099
00100 if(_clearBG)
00101 {
00102 out << _clearR << " " << _clearG << " " << _clearB << " setrgbcolor\n";
00103 out << _xmin << " " << _ymin << " " << _xmax << " " << _ymax << " rectfill\n\n";
00104 }
00105 }
00106
00107 void EPSExporter::writeFooter(QTextStream& out) const
00108 {
00109 out << "grestore\n\n";
00110
00111 out << "% uncomment next line to be able to print to a printer.\n";
00112 out << "% showpage\n";
00113 }
00114
00115 void PSExporter::writeFooter(QTextStream& out) const
00116 {
00117 out << "showpage\n";
00118 }
00119
00120 const char *EPSExporter::GOURAUD_TRIANGLE_EPS[] =
00121 {
00122 "/bd{bind def}bind def /triangle { aload pop ",
00123 "setrgbcolor aload pop 5 3 roll 4 2 roll 3 2 roll exch moveto lineto ",
00124 "lineto closepath fill } bd /computediff1 { 2 copy sub abs threshold ",
00125 "ge {pop pop pop true} { exch 2 index sub abs threshold ge { pop pop ",
00126 "true} { sub abs threshold ge } ifelse } ifelse } bd /computediff3 { 3 ",
00127 "copy 0 get 3 1 roll 0 get 3 1 roll 0 get computediff1 {true} { 3 copy ",
00128 "1 get 3 1 roll 1 get 3 1 roll 1 get computediff1 {true} { 3 copy 2 ",
00129 "get 3 1 roll 2 get 3 1 roll 2 get computediff1 } ifelse } ifelse } ",
00130 "bd /middlecolor { aload pop 4 -1 roll aload pop 4 -1 roll add 2 div 5 ",
00131 "1 roll 3 -1 roll add 2 div 3 1 roll add 2 div 3 1 roll exch 3 array ",
00132 "astore } bd /gdt { computediff3 { 4 -1 roll aload 7 1 roll ",
00133 "6 -1 roll pop 3 -1 roll pop add 2 div 3 1 roll add 2 div exch 3 -1 roll ",
00134 "aload 7 1 roll exch pop 4 -1 roll pop add 2 div 3 1 roll add 2 div ",
00135 "exch 3 -1 roll aload 7 1 roll pop 3 -1 roll pop add 2 div 3 1 roll add ",
00136 "2 div exch 7 3 roll 10 -3 roll dup 3 index middlecolor 4 1 roll 2 copy ",
00137 "middlecolor 4 1 roll 3 copy pop middlecolor 4 1 roll 13 -1 roll aload ",
00138 "pop 17 index 6 index 15 index 19 index 6 index 17 index 6 array astore ",
00139 "10 index 10 index 14 index gdt 17 index 5 index 17 index ",
00140 "19 index 5 index 19 index 6 array astore 10 index 9 index 13 index ",
00141 "gdt 13 index 16 index 5 index 15 index 18 index 5 index 6 ",
00142 "array astore 12 index 12 index 9 index gdt 17 index 16 ",
00143 "index 15 index 19 index 18 index 17 index 6 array astore 10 index 12 ",
00144 "index 14 index gdt 18 {pop} repeat } { aload pop 5 3 roll ",
00145 "aload pop 7 3 roll aload pop 9 3 roll 8 index 6 index 4 index add add 3 ",
00146 "div 10 1 roll 7 index 5 index 3 index add add 3 div 10 1 roll 6 index 4 ",
00147 "index 2 index add add 3 div 10 1 roll 9 {pop} repeat 3 array astore ",
00148 "triangle } ifelse } bd",
00149 NULL
00150 };
00151
00152 void EPSExporter::spewPolygone(const Polygone *P, QTextStream& out)
00153 {
00154 int nvertices;
00155 GLfloat red, green, blue;
00156 bool smooth;
00157
00158 nvertices = P->nbVertices() ;
00159
00160 const Feedback3DColor& vertex = Feedback3DColor(P->sommet3DColor(0)) ;
00161
00162 if(nvertices > 0)
00163 {
00164 red = vertex.red();
00165 green = vertex.green();
00166 blue = vertex.blue();
00167
00168 smooth = false;
00169
00170 for(int i=1;i < nvertices && !smooth; i++)
00171 if(fabs(red - P->sommet3DColor(i).red()) > 0.01 || fabs(green - P->sommet3DColor(i).green()) > 0.01 || fabs(blue - P->sommet3DColor(i).blue()) > 0.01)
00172 smooth = true;
00173
00174 if(smooth && !_blackAndWhite)
00175 {
00176
00177
00178
00179 for (int j = 0; j < nvertices - 2; j++)
00180 {
00181 out << "[" << P->sommet3DColor(0).x() << " " << P->sommet3DColor(j + 1).x() << " " << P->sommet3DColor(j + 2).x()
00182 << " " << P->sommet3DColor(0).y() << " " << P->sommet3DColor(j + 1).y() << " " << P->sommet3DColor(j + 2).y() << "]";
00183
00184 out << " [" << P->sommet3DColor(0 ).red() << " " << P->sommet3DColor(0 ).green() << " " << P->sommet3DColor(0 ).blue()
00185 << "] [" << P->sommet3DColor(j + 1).red() << " " << P->sommet3DColor(j + 1).green() << " " << P->sommet3DColor(j + 1).blue()
00186 << "] [" << P->sommet3DColor(j + 2).red() << " " << P->sommet3DColor(j + 2).green() << " " << P->sommet3DColor(j + 2).blue() << "] gdt\n";
00187
00188 last_r = last_g = last_b = -1.0 ;
00189 }
00190 }
00191 else
00192 {
00193
00194
00195 out << "newpath\n";
00196
00197 if(_blackAndWhite)
00198 setColor(out,1.0,1.0,1.0) ;
00199 else
00200 setColor(out,red,green,blue) ;
00201
00202
00203
00204 out << P->sommet3DColor(0).x() << " " << P->sommet3DColor(0).y() << " moveto\n";
00205
00206 for (int i = 1; i < nvertices; i++)
00207 out << P->sommet3DColor(i).x() << " " << P->sommet3DColor(i).y() << " lineto\n";
00208
00209 out << "closepath fill\n\n";
00210 }
00211 }
00212 }
00213
00214 void EPSExporter::spewSegment(const Segment *S, QTextStream& out)
00215 {
00216 GLdouble dx, dy;
00217 GLfloat dr, dg, db, absR, absG, absB, colormax;
00218 int steps;
00219 GLdouble xstep=0.0, ystep=0.0;
00220 GLfloat rstep=0.0, gstep=0.0, bstep=0.0;
00221 GLdouble xnext=0.0, ynext=0.0, distance=0.0;
00222 GLfloat rnext=0.0, gnext=0.0, bnext=0.0;
00223
00224 const Feedback3DColor& P1 = Feedback3DColor(S->sommet3DColor(0)) ;
00225 const Feedback3DColor& P2 = Feedback3DColor(S->sommet3DColor(1)) ;
00226
00227 dr = P2.red() - P1.red();
00228 dg = P2.green() - P1.green();
00229 db = P2.blue() - P1.blue();
00230
00231 if((!_blackAndWhite)&&(dr != 0 || dg != 0 || db != 0))
00232 {
00233
00234
00235 dx = P2.x() - P1.x();
00236 dy = P2.y() - P1.y();
00237
00238 distance = sqrt(dx*dx + dy*dy);
00239
00240 absR = fabs(dr);
00241 absG = fabs(dg);
00242 absB = fabs(db);
00243
00244 colormax = max(absR, max(absG, absB));
00245 steps = int(0.5f + max(1.0, colormax * distance * EPS_SMOOTH_LINE_FACTOR));
00246
00247 xstep = dx / steps;
00248 ystep = dy / steps;
00249
00250 rstep = dr / steps;
00251 gstep = dg / steps;
00252 bstep = db / steps;
00253
00254 xnext = P1.x();
00255 ynext = P1.y();
00256 rnext = P1.red();
00257 gnext = P1.green();
00258 bnext = P1.blue();
00259
00260
00261
00262
00263 xnext -= xstep / 2.0;
00264 ynext -= ystep / 2.0;
00265 rnext -= rstep / 2.0f;
00266 gnext -= gstep / 2.0f;
00267 bnext -= bstep / 2.0f;
00268 }
00269 else
00270 steps = 0;
00271
00272 if(_blackAndWhite)
00273 setColor(out,0.0,0.0,0.0) ;
00274 else
00275 setColor(out,P1.red(),P1.green(),P1.blue()) ;
00276
00277 out << P1.x() << " " << P1.y() << " moveto\n";
00278
00279 for(int i = 0;i < steps;i++)
00280 {
00281 xnext += xstep;
00282 ynext += ystep;
00283 rnext += rstep;
00284 gnext += gstep;
00285 bnext += bstep;
00286
00287 out << xnext << " " << ynext << " lineto stroke\n";
00288 out << rnext << " " << gnext << " " << bnext << " setrgbcolor\n";
00289 out << xnext << " " << ynext << " moveto\n";
00290
00291 last_r = last_g = last_b = -1.0 ;
00292 }
00293 out << P2.x() << " " << P2.y() << " lineto stroke\n";
00294 }
00295
00296 void EPSExporter::spewPoint(const Point *P, QTextStream& out)
00297 {
00298 const Feedback3DColor& p = Feedback3DColor(P->sommet3DColor(0)) ;
00299
00300 if(_blackAndWhite)
00301 setColor(out,0.0,0.0,0.0) ;
00302 else
00303 setColor(out,p.red(),p.green(),p.blue()) ;
00304
00305 out << p.x() << " " << p.y() << " " << (_pointSize / 2.0) << " 0 360 arc fill\n\n";
00306 }
00307
00308 void EPSExporter::setColor(QTextStream& out, float red, float green, float blue)
00309 {
00310 if(last_r != red || last_g != green || last_b != blue)
00311 out << red << " " << green << " " << blue << " setrgbcolor\n";
00312
00313 last_r = red ;
00314 last_g = green ;
00315 last_b = blue ;
00316 }
00317