epswrite.C

Go to the documentation of this file.
00001 
00006 #ifdef HAVE_CONFIG_H
00007 #include <tumble-conf.h>
00008 #endif /* HAVE_CONFIG_H */
00009 
00010 #include "epswrite.h"
00011 
00012 #include "beziermesh.h"
00013 #include "boundarymesh.h"
00014 
00015 #include <cstdio>
00016 #include <cstdlib>
00017 #include <iostream>
00018 
00019 using namespace std;
00020 
00021 #define INCH_TO_PT( inch ) (unsigned)(inch * 72.0 + 0.5)
00022 
00023 
00024 EPSWrite::EPSWrite(BezierMesh *_bezier_mesh, BoundaryMesh *_bdry_mesh )
00025 {
00026     if(!_bezier_mesh || !_bdry_mesh){
00027         cout<<"EPSWrite --- given bad mesh!"<<endl;
00028         return;
00029     }
00030 
00031     /* copy over mesh pointers */
00032     bdry_mesh = _bdry_mesh;
00033     bezier_mesh = _bezier_mesh;
00034 
00035     /* initialize color mapping */
00036     default_eps_rgb_map(rgb_map);
00037     default_eps_grayscale_map(grayscale_map);
00038 
00039 
00040     /* get world dimensions */
00041     Point2D top, bot;
00042     double height, width;
00043     bdry_mesh->bbox(top, bot);
00044     height = top.y() - bot.y();
00045     width = top.x() - bot.x();
00046 
00047     top.coords[0] += width * 0.01;
00048     bot.coords[0] -= width * 0.01;
00049     top.coords[1] += height * 0.01;
00050     bot.coords[1] -= height * 0.01;
00051 
00052     set_world_view(bot, top);
00053 
00054     /* set defualt drawing */
00055     set_page_dim(0,0,790,610,5);
00056     set_border_ink(1, 1.0);
00057     set_edge_ink(1, 1.0);
00058     set_bdry_draw(DRAW_OFF);
00059     set_face_draw(DRAW_OFF);
00060 }
00061 
00062 /*
00063 int EPSWrite::load_rgb_map(char *filename)
00064 {
00065     if( !filename ) return -1;
00066     char buf[MAX_FILENAME];
00067     if( add_filename_extension(filename,"tcm",buf, MAX_FILENAME) ) return -1;
00068     return load_map(rgb_map);
00069 }
00070 */
00071 /*
00072 int EPSWrite::load_grayscale_map(char *filename)
00073 {
00074     if( !filename ) return -1;
00075     char buf[MAX_FILENAME];
00076     if( add_filename_extension(filename,"tgm",buf, MAX_FILENAME) ) return -1;
00077     return load_map(grayscale_map);
00078 }
00079 */
00080 
00081 int EPSWrite::map_rgbcolor(int idx, const Color &color)
00082 {
00083     if( !color.is_valid() ) return -1;
00084     rgb_map[idx] = color;
00085     return 0;
00086 }
00087 
00088 int EPSWrite::map_grayscale(int idx, float scale)
00089 {
00090     if( scale < 0.0 || scale > 1.0 ) return -1;
00091     grayscale_map[idx] = scale;
00092     return 0;
00093 }
00094 
00095 int EPSWrite::set_border_draw(int mode)
00096 {
00097     if( (mode != DRAW_OFF) &&
00098          (mode != DRAW_GRAYSCALE) &&
00099          (mode != DRAW_RGB) ) return -1;
00100     border.mode = mode;
00101     return 0;
00102 }
00103 
00104 int EPSWrite::set_border_ink(unsigned linewidth, float shade)
00105 {
00106     if(( shade < 0.0 ) || ( shade > 1.0)) return -1;
00107     border.mode = DRAW_GRAYSCALE;
00108     border.linewidth = linewidth;
00109     border.grayscale = shade;
00110     return 0;
00111 }
00112 
00113 int EPSWrite::set_border_ink(unsigned linewidth, const Color &rgbcolor)
00114 {
00115     if( !rgbcolor.is_valid() ) return -1;
00116     border.mode = DRAW_RGB;
00117     border.linewidth = linewidth;
00118     border.rgbcolor = rgbcolor;
00119     return 0;
00120 }
00121 
00122 int EPSWrite::set_bdry_draw(int mode)
00123 {
00124     if( (mode != DRAW_OFF) &&
00125          (mode != DRAW_GRAYSCALE) &&
00126          (mode != DRAW_RGB) ) return -1;
00127     bdry.mode = mode;
00128     return 0;
00129 }
00130 
00131 int EPSWrite::set_bdry_ink(unsigned linewidth, float shade)
00132 {
00133     if(( shade < 0.0 ) || ( shade > 1.0)) return -1;
00134     bdry.mode = DRAW_GRAYSCALE;
00135     bdry.linewidth = linewidth;
00136     bdry.grayscale = shade;
00137     return 0;
00138 }
00139 
00140 int EPSWrite::set_bdry_ink(unsigned linewidth, const Color &rgbcolor)
00141 {
00142     if( !rgbcolor.is_valid() ) return -1;
00143     bdry.mode = DRAW_RGB;
00144     bdry.linewidth = linewidth;
00145     bdry.rgbcolor = rgbcolor;
00146     return 0;
00147 }
00148 
00149 int EPSWrite::set_edge_draw(int mode)
00150 {
00151     if( (mode != DRAW_OFF) &&
00152          (mode != DRAW_GRAYSCALE) &&
00153          (mode != DRAW_RGB) ) return -1;
00154     edges.mode = mode;
00155     return 0;
00156 }
00157 
00158 int EPSWrite::set_edge_ink(unsigned linewidth, float shade)
00159 {
00160     if(( shade < 0.0 ) || ( shade > 1.0)) return -1;
00161     edges.mode = DRAW_GRAYSCALE;
00162     edges.linewidth = linewidth;
00163     edges.grayscale = shade;
00164     return 0;
00165 }
00166 
00167 int EPSWrite::set_edge_ink(unsigned linewidth, const Color &rgbcolor)
00168 {
00169     if( !rgbcolor.is_valid() ) return -1;
00170     edges.mode = DRAW_RGB;
00171     edges.linewidth = linewidth;
00172     edges.rgbcolor = rgbcolor;
00173     return 0;
00174 }
00175 
00176 int EPSWrite::set_face_draw(int mode)
00177 {
00178     if( (mode != DRAW_OFF) &&
00179          (mode != DRAW_GRAYSCALE) &&
00180          (mode != DRAW_RGB) ) return -1;
00181     shade_face_mode = mode;
00182     return 0;
00183 }
00184 
00185 int EPSWrite::set_page_dim(unsigned xmin, unsigned ymin, unsigned xmax, unsigned ymax, unsigned margin)
00186 {
00187     if( ( xmin >= xmax ) || ( ymin >= ymax ) ) return -1;
00188     if( (2*margin >= xmax - xmin) || (2*margin >= ymax - ymin) ) return -1;
00189 
00190     page_bot.x = xmin;
00191     page_bot.y = ymin;
00192     page_top.x = xmax;
00193     page_top.y = ymax;
00194     page_width = xmax - xmin;
00195     page_height = ymax - ymin;
00196     margin_width = margin;
00197 
00198     canvas_bot.x = xmin + margin;
00199     canvas_bot.y = ymin + margin;
00200     canvas_top.x = xmax - margin;
00201     canvas_top.y = ymax - margin;
00202     canvas_width = canvas_top.x - canvas_bot.x;
00203     canvas_height = canvas_top.y - canvas_bot.y;
00204     project_to_canvas();
00205     return 0;
00206 }
00207 
00208 int EPSWrite::set_page_dim_inch(float xmin, float ymin, float xmax, float ymax, float margin)
00209 {
00210     if( (xmin < 0.0) || (ymin < 0.0) ||(xmax < 0.0) || (ymax < 0.0) || (margin < 0.0) ) return -1;
00211     return set_page_dim(INCH_TO_PT(xmin), INCH_TO_PT(ymin), INCH_TO_PT(xmax), INCH_TO_PT(ymax), INCH_TO_PT(margin));
00212 }
00213 
00214 int EPSWrite::set_world_view(const Point2D &bot, const Point2D &top)
00215 {
00216     if((bot.x() >= top.x()) || (bot.y() >= top.y())) return -1;
00217     world_bot = bot;
00218     world_top = top;
00219     world_width  = world_top.x() - world_bot.x();
00220     world_height = world_top.y() - world_bot.y();
00221     project_to_canvas();
00222     return 0;
00223 }
00224 
00225 void EPSWrite::project_to_canvas()
00226 {
00227     Point2D world_center;
00228     double world_ratio = world_width / world_height;
00229     double canvas_ratio = (double)canvas_width / (double)canvas_height;
00230     double ny, nx;
00231     world_center.coords[0] = world_bot.x() + world_width * 0.5;
00232     world_center.coords[1] = world_bot.y() + world_height * 0.5;
00233     //cout<<"world ratio: "<<world_ratio<<"  canvas_ratio: "<<canvas_ratio<<endl;
00234     //cout<<"world center: "<<world_center<<endl;
00235 
00236     if(world_ratio > canvas_ratio){
00237         ny = world_width * (1.0 / canvas_ratio) * 0.5;
00238         view_top.assign(world_top.x(), world_center.y() + ny);
00239         view_bot.assign(world_bot.x(), world_center.y() - ny);
00240     }
00241     else{
00242         nx = world_height * canvas_ratio * 0.5;
00243         view_top.assign(world_center.x() + nx, world_top.y());
00244         view_bot.assign(world_center.x() - nx, world_bot.y());
00245     }
00246     view_width = view_top.x() - view_bot.x();
00247     view_height = view_top.y() - view_bot.y();
00248     //cout<<"view top: "<<view_top<<"   view bot: "<<view_bot<<endl;
00249 }
00250 
00251 int EPSWrite::write(char *epsfilename)
00252 {
00253     if(!bdry_mesh || !bezier_mesh) return -1;
00254     if(!epsfilename) return -1;
00255 
00256     epsfile = fopen( epsfilename, "w" );
00257     if(!epsfile) return -1;
00258 
00259     /* initialize eps */
00260     print_header();
00261     set_options();
00262     set_clip();
00263 
00264     cout<<"World Top:"<<world_top<<" World Bot:"<<world_bot<<endl;
00265     cout<<"World Width:"<<world_width<<" World Height:"<<world_height<<endl;
00266     cout<<"Page Width:"<<page_width<< " Page Height:"<<page_height<<endl;
00267     cout<<"Canvas Width:"<<canvas_width<<" Canvas Height:"<<canvas_height<<endl;
00268 
00269     /* draw objects */
00270     if(shade_face_mode != DRAW_OFF) draw_faces();
00271     if(edges.mode != DRAW_OFF)      draw_edges();
00272     if(bdry.mode != DRAW_OFF)       draw_bdry();
00273     if(border.mode != DRAW_OFF)     draw_border();
00274 
00275     /* close up file */
00276     if( !fclose( epsfile ) ) return -1;
00277     return 0;
00278 }
00279 
00280 void EPSWrite::draw_bdry()
00281 {
00282     set_ink(bdry);
00283     BezierMesh::Bezier_Edge_Hash_T::const_iterator i;
00284     for(i = bezier_mesh->get_edges_begin(); 
00285         i != bezier_mesh->get_edges_end(); ++i) {
00286         if( (*i)->is_boundary() ) draw_edge(*i);
00287     }
00288 }
00289 
00290 void EPSWrite::draw_faces()
00291 {
00292     BezierMesh::Bezier_Face_Hash_T::const_iterator i;
00293     for(i = bezier_mesh->get_faces_begin(); 
00294         i != bezier_mesh->get_faces_end(); ++i) {
00295         shade_triangle(*i);
00296     }
00297 }
00298 
00299 void EPSWrite::draw_edges()
00300 {
00301     set_ink(edges);
00302     BezierMesh::Bezier_Edge_Hash_T::const_iterator i;
00303     for(i = bezier_mesh->get_edges_begin(); 
00304         i != bezier_mesh->get_edges_end(); ++i) {
00305         draw_edge(*i);
00306     }
00307 }
00308 
00309 PSCoord EPSWrite::convert_coords(const Point2D &p)
00310 {
00311     PSCoord q;
00312     q.x = canvas_bot.x + (unsigned)( ( (double)canvas_width  * (p.x() - view_bot.x()) / view_width  ) + 0.5);
00313     q.y = canvas_bot.y + (unsigned)( ( (double)canvas_height * (p.y() - view_bot.y()) / view_height ) + 0.5);
00314     return q;
00315 }
00316 
00317 void EPSWrite::print_header()
00318 {
00319 
00320     fprintf(epsfile,"%%!PS-Adobe-3.0 EPSF-3.0\n");
00321     fprintf(epsfile,"%%%%Pages: 0\n");
00322     fprintf(epsfile,"%%%%BoundingBox: %u %u %u %u\n", page_bot.x, page_bot.y, page_top.x, page_top.y);
00323     fprintf(epsfile,"%%%%Creator: TUMBLE\n");
00324     fprintf(epsfile,"%%%%EndComments\n");
00325 }
00326 
00327 void EPSWrite::set_options()
00328 {
00329     fprintf(epsfile,"%% setting global options\n");
00330     fprintf(epsfile,"1 setlinecap\n");
00331     fprintf(epsfile,"1 setlinejoin\n\n");
00332 }
00333 
00334 void EPSWrite::set_clip()
00335 {
00336     fprintf(epsfile,"%%clip the bounding box\n");
00337     fprintf(epsfile,"newpath\n");
00338     fprintf(epsfile,"%u %u moveto\n", canvas_bot.x, canvas_bot.y);
00339     fprintf(epsfile,"%u %u lineto\n", canvas_top.x, canvas_bot.y);
00340     fprintf(epsfile,"%u %u lineto\n", canvas_top.x, canvas_top.y);
00341     fprintf(epsfile,"%u %u lineto\n", canvas_bot.x, canvas_top.y);
00342     fprintf(epsfile,"closepath\n");
00343     fprintf(epsfile,"clip\n\n");
00344 }
00345 
00346 
00347 void EPSWrite::set_ink(const PSDrawMode &mode)
00348 {
00349     fprintf(epsfile,"%%set ink style\n");
00350     fprintf(epsfile,"%u setlinewidth\n",mode.linewidth);
00351     if(mode.mode == DRAW_GRAYSCALE) {
00352         fprintf(epsfile,"/DeviceGray setcolorspace\n");
00353         fprintf(epsfile,"%f setgray\n", mode.grayscale);
00354     }
00355     else if(mode.mode == DRAW_RGB) {
00356         fprintf(epsfile,"/DeviceRGB setcolorspace\n");
00357         fprintf(epsfile,"%f %f %f setrgbcolor\n", mode.rgbcolor.R(), mode.rgbcolor.G(), mode.rgbcolor.B());
00358     }
00359 }
00360 
00361 void EPSWrite::draw_border()
00362 {
00363     unsigned a = (unsigned) ((double)border.linewidth / 2.0);
00364     set_ink(border);
00365     fprintf(epsfile,"%%draw the border\n");
00366     fprintf(epsfile,"newpath\n");
00367     fprintf(epsfile,"%u %u moveto\n", canvas_bot.x + a, canvas_bot.y + a);
00368     fprintf(epsfile,"%u %u lineto\n", canvas_top.x - a, canvas_bot.y + a);
00369     fprintf(epsfile,"%u %u lineto\n", canvas_top.x - a, canvas_top.y - a);
00370     fprintf(epsfile,"%u %u lineto\n", canvas_bot.x + a, canvas_top.y - a);
00371     fprintf(epsfile,"closepath\n");
00372     fprintf(epsfile,"stroke\n\n");
00373 }
00374 
00375 void EPSWrite::draw_edge(BezierEdge *e)
00376 {
00377     PSCoord p0, p1, p2, p3;
00378 
00379     p0 = convert_coords( e->get_cp(0) );
00380     p1 = convert_coords( e->get_cp(0) * 1.0/3.0 + e->get_cp(1) * 2.0/3.0);
00381     p2 = convert_coords( e->get_cp(2) * 1.0/3.0 + e->get_cp(1) * 2.0/3.0);
00382     p3 = convert_coords( e->get_cp(2) );
00383 
00384     fprintf(epsfile,"%%draw edge\n");
00385     fprintf(epsfile,"newpath\n");
00386     fprintf(epsfile,"%u %u moveto\n",p0.x, p0.y);
00387     fprintf(epsfile,"%u %u %u %u %u %u curveto\n",p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
00388     fprintf(epsfile,"closepath\n");
00389     fprintf(epsfile,"stroke\n\n");
00390 }
00391 
00392 void EPSWrite::shade_triangle(BezierTriangle *t)
00393 {
00394     PSDrawMode mode;
00395     PSCoord p0, p1, p2, p3;
00396     BezierEdge *e;
00397     BezierVertex *v, *vold;
00398     BezierTuple tup = bezier_mesh->get_tuple(t);
00399 
00400     mode.mode = shade_face_mode;
00401     mode.linewidth = 1;
00402     mode.grayscale = grayscale_map[ t->get_color() ];
00403     mode.rgbcolor  = rgb_map[ t->get_color() ];
00404     set_ink( mode );
00405 
00406     fprintf(epsfile,"%%shade triangle\n");
00407     fprintf(epsfile,"newpath\n");
00408     p0 = convert_coords( tup.e->get_cp(0) );
00409     fprintf(epsfile,"%u %u moveto\n",p0.x, p0.y);
00410 
00411     for(int i =0; i < 3; i++){
00412         e = tup.e;
00413         vold = tup.v;
00414         tup = bezier_mesh->Switch(0, tup);
00415         v = tup.v;
00416         p1 = convert_coords( vold->get_cp() * 1.0/3.0 + e->get_cp(1) * 2.0/3.0 );
00417         p2 = convert_coords( v->get_cp() * 1.0/3.0 + e->get_cp(1) * 2.0/3.0 );
00418         p3 = convert_coords( v->get_cp() );
00419 
00420         fprintf(epsfile,"%u %u %u %u %u %u curveto\n", p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
00421         tup = bezier_mesh->Switch( 1, tup );
00422     }
00423     fprintf(epsfile,"closepath\n");
00424 
00425     /* incase no edges are displayed make sure to fill in any gaps with a perimiter stroke command */
00426     if( edges.mode == DRAW_OFF ){
00427         fprintf(epsfile,"gsave\n");
00428         fprintf(epsfile,"stroke\n");
00429         fprintf(epsfile,"grestore\n");
00430     }
00431     fprintf(epsfile,"fill\n\n");
00432 }
00433 
00434 

Generated on Mon May 24 09:53:30 2010 for TUMBLE by  doxygen 1.5.2