core/vgui/vgui_easy2D_tableau.cxx

Go to the documentation of this file.
00001 // This is core/vgui/vgui_easy2D_tableau.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \brief  See vgui_easy2D_tableau.h for a description of this file.
00008 // \author Philip C. Pritchett, RRG, University of Oxford
00009 // \date   24 Sep 1999
00010 //
00011 // \verbatim
00012 //  Modifications
00013 //   24-SEP-1999 P.Pritchett - Initial version.
00014 // \endverbatim
00015 
00016 #include "vgui_easy2D_tableau.h"
00017 
00018 #include <vcl_vector.h>
00019 #include <vcl_cassert.h>
00020 #include <vcl_cstdlib.h> // for abort
00021 
00022 #include <vxl_config.h> // for vxl_byte
00023 
00024 #include <vul/vul_psfile.h>
00025 
00026 #include <vil1/vil1_image.h>
00027 #include <vil1/vil1_pixel.h>
00028 
00029 #include <vil/vil_image_view.h>
00030 #include <vil/vil_image_resource.h>
00031 
00032 #include <vgui/vgui_event.h>
00033 #include <vgui/vgui_macro.h>
00034 #include <vgui/vgui_soview2D.h>
00035 #include <vgui/vgui_displaylist2D_tableau.h>
00036 #include <vgui/vgui_image_tableau.h>
00037 #include <vgui/vgui_style.h>
00038 
00039 #ifdef DEBUG
00040 #include <vil/vil_save.h>
00041 #endif
00042 
00043 static bool debug = false;
00044 
00045 vgui_easy2D_tableau::vgui_easy2D_tableau(const char* n) : image_slot(this), name_(n), style_(vgui_style::new_style())
00046 {
00047   style_->rgba[0] = 1.0f;
00048   style_->rgba[1] = 1.0f;
00049   style_->rgba[2] = 0.0f;
00050 
00051   style_->line_width = 1;
00052   style_->point_size = 3;
00053 }
00054 
00055 
00056 vgui_easy2D_tableau::vgui_easy2D_tableau(vgui_image_tableau_sptr const& i, const char* n)
00057   : image_slot(this,i), image_image(i), name_(n), style_(vgui_style::new_style())
00058 {
00059   style_->rgba[0] = 1.0f;
00060   style_->rgba[1] = 1.0f;
00061   style_->rgba[2] = 0.0f;
00062 
00063   style_->line_width = 1;
00064   style_->point_size = 3;
00065 }
00066 
00067 
00068 vgui_easy2D_tableau::vgui_easy2D_tableau(vgui_tableau_sptr const& i, const char* n)
00069   : image_slot(this,i), name_(n), style_(vgui_style::new_style())
00070 {
00071   style_->rgba[0] = 1.0f;
00072   style_->rgba[1] = 1.0f;
00073   style_->rgba[2] = 0.0f;
00074 
00075   style_->line_width = 1;
00076   style_->point_size = 3;
00077 }
00078 
00079 
00080 bool vgui_easy2D_tableau::handle(vgui_event const& e)
00081 {
00082   if (image_slot && (e.type != vgui_DRAW || gl_mode != GL_SELECT))
00083     image_slot.handle(e);
00084 
00085   return vgui_displaylist2D_tableau::handle(e);
00086 }
00087 
00088 vcl_string vgui_easy2D_tableau::file_name() const
00089 {
00090   if (image_slot)
00091     return type_name() + "[" + name_ + ",i=" + image_slot->file_name() + "]";
00092   else
00093     return name_;
00094 }
00095 
00096 
00097 vcl_string vgui_easy2D_tableau::pretty_name() const
00098 {
00099   if (image_slot)
00100     return type_name() + "[" + name_ + ",i=" + image_slot->file_name() + "]";
00101   else
00102     return type_name() + "[" + name_ + ",i=null]";
00103 }
00104 
00105 vcl_string vgui_easy2D_tableau::type_name() const
00106 {
00107   return "vgui_easy2D_tableau";
00108 }
00109 
00110 //: Set the child tableau to be the given image_tableau.
00111 void vgui_easy2D_tableau::set_image(vcl_string const& fn)
00112 {
00113   image_image->set_image(fn.c_str());
00114 }
00115 
00116 //: Set the child tableau to be the given tableau.
00117 void vgui_easy2D_tableau::set_child(vgui_tableau_sptr const& i)
00118 {
00119   if (i->type_name() != "vgui_image_tableau" &&
00120       i->type_name() != "xcv_image_tableau")
00121     vgui_macro_warning << "assigning what seems like a non-image to my child : i = " << i << vcl_endl;
00122   image_slot.assign(i);
00123 }
00124 
00125 //: Set the colour of objects to the given red, green, blue, alpha values.
00126 void vgui_easy2D_tableau::set_foreground(float r, float g, float b, float a)
00127 {
00128   // create a new style object so that already added objects don't
00129   // suddenly change
00130   style_ = vgui_style::new_style( style_ );
00131   style_->rgba[0] = r;
00132   style_->rgba[1] = g;
00133   style_->rgba[2] = b;
00134   style_->rgba[3] = a;
00135 }
00136 
00137 //: Set the width of lines to the given width.
00138 void vgui_easy2D_tableau::set_line_width(float w)
00139 {
00140   // create a new style object so that already added objects don't
00141   // suddenly change
00142   style_ = vgui_style::new_style( style_ );
00143   style_->line_width = w;
00144 }
00145 
00146 //: Set the radius of points to the given radius.
00147 void vgui_easy2D_tableau::set_point_radius(float r)
00148 {
00149   // create a new style object so that already added objects don't
00150   // suddenly change
00151   style_ = vgui_style::new_style( style_ );
00152   style_->point_size = r;
00153 }
00154 
00155 //: Add the given two-dimensional object to the display.
00156 void vgui_easy2D_tableau::add(vgui_soview2D* object)
00157 {
00158   object->set_style(style_);
00159   vgui_displaylist2D_tableau::add(object);
00160 }
00161 
00162 //: Add a point at the given position to the display.
00163 vgui_soview2D_point* vgui_easy2D_tableau::add_point(float x, float y)
00164 {
00165   vgui_soview2D_point *obj = new vgui_soview2D_point;
00166 
00167   obj->x = x;
00168   obj->y = y;
00169   add(obj);
00170   return obj;
00171 }
00172 
00173 //: Add a finite line with the given start and end points to the display.
00174 //  Note that this will be added as a vgui_lineseg (not vgui_line - which doesn't exist).
00175 vgui_soview2D_lineseg* vgui_easy2D_tableau::add_line(float x0, float y0, float x1, float y1)
00176 {
00177   vgui_soview2D_lineseg *obj = new vgui_soview2D_lineseg;
00178 
00179   obj->x0 = x0;
00180   obj->y0 = y0;
00181   obj->x1 = x1;
00182   obj->y1 = y1;
00183 
00184   add(obj);
00185   return obj;
00186 }
00187 
00188 //: Add an infinite line (ax + by +c = 0) to the display.
00189 vgui_soview2D_infinite_line* vgui_easy2D_tableau::add_infinite_line(float a, float b, float c)
00190 {
00191   vgui_soview2D_infinite_line *obj = new vgui_soview2D_infinite_line;
00192 
00193   obj->a = a;
00194   obj->b = b;
00195   obj->c = c;
00196 
00197   add(obj);
00198   return obj;
00199 }
00200 
00201 //: Add a circle with the given centre and radius to the display.
00202 vgui_soview2D_circle* vgui_easy2D_tableau::add_circle(float x, float y, float r)
00203 {
00204   vgui_soview2D_circle *obj = new vgui_soview2D_circle;
00205 
00206   obj->x = x;
00207   obj->y = y;
00208   obj->r = r;
00209 
00210   add(obj);
00211   return obj;
00212 }
00213 
00214 vgui_soview2D_ellipse* vgui_easy2D_tableau::add_ellipse(float x, float y, float w, float h, float phi)
00215 {
00216   vgui_soview2D_ellipse *obj = new vgui_soview2D_ellipse;
00217 
00218   obj->x = x;
00219   obj->y = y;
00220   obj->w = w;
00221   obj->h = h;
00222   obj->phi = phi;
00223 
00224   add(obj);
00225   return obj;
00226 }
00227 
00228 //: Add a point with the given projective coordinates.
00229 vgui_soview2D_point* vgui_easy2D_tableau::add_point_3dv(double const p[3])
00230 {
00231   return add_point(float(p[0]/p[2]), float(p[1]/p[2]));
00232 }
00233 
00234 //: Add a line with the given projective start and end points.
00235 vgui_soview2D_lineseg* vgui_easy2D_tableau::add_line_3dv_3dv(double const p[3], double const q[3])
00236 {
00237   return add_line(float(p[0]/p[2]), float(p[1]/p[2]),
00238                   float(q[0]/q[2]), float(q[1]/q[2]));
00239 }
00240 
00241 //: Add an infinite line with the given projective coordinates.
00242 vgui_soview2D_infinite_line* vgui_easy2D_tableau::add_infinite_line_3dv(double const l[3])
00243 {
00244   return add_infinite_line(float(l[0]), float(l[1]), float(l[2]));
00245 }
00246 
00247 //: Add a circle with the given centre (in projective coords) and radius to the display.
00248 vgui_soview2D_circle* vgui_easy2D_tableau::add_circle_3dv(double const point[3], float r)
00249 {
00250   return add_circle(float(point[0]/point[2]), float(point[1]/point[2]), r);
00251 }
00252 
00253 //: Add a linestrip with the given n vertices to the display.
00254 vgui_soview2D_linestrip* vgui_easy2D_tableau::add_linestrip(unsigned n, float const *x, float const *y)
00255 {
00256   vgui_soview2D_linestrip *obj = new vgui_soview2D_linestrip(n, x, y);
00257 
00258   add(obj);
00259   return obj;
00260 }
00261 
00262 //: Add  polygon with the given n vertices to the display.
00263 vgui_soview2D_polygon* vgui_easy2D_tableau::add_polygon(unsigned n, float const *x, float const *y)
00264 {
00265   vgui_soview2D_polygon *obj = new vgui_soview2D_polygon(n, x, y);
00266 
00267   add(obj);
00268   return obj;
00269 }
00270 
00271 //: Screen dump to postscript file.
00272 //  Specify the optional arguments in case this tableau does not contain
00273 //  an image tableau, or if you want a smaller part of the image printed.
00274 //  If wd or ht are 0, no image is printed at all.
00275 void vgui_easy2D_tableau::print_psfile(vcl_string filename, int reduction_factor, bool print_geom_objs, int wd, int ht)
00276 {
00277   // Set wd and ht from the image tableau, if not specified as parameters
00278   if (wd < 0 || ht < 0)
00279   {
00280     assert(get_image_tableau());
00281     if (get_image_tableau()->get_image_resource())
00282     {
00283       vil_image_resource_sptr img_sptr = get_image_tableau()->get_image_resource();
00284       if (wd < 0) wd = img_sptr->ni();
00285       if (ht < 0) ht = img_sptr->nj();
00286     }
00287     else
00288     {
00289       vil1_image img = get_image_tableau()->get_image();
00290       if (wd < 0) wd = img.width();
00291       if (ht < 0) ht = img.height();
00292       assert (wd <= img.width());
00293       assert (ht <= img.height());
00294     }
00295   }
00296 
00297   // Write PostScript header
00298   vul_psfile psfile(filename.c_str(), false);
00299   psfile.set_paper_layout(vul_psfile::MAX);
00300   psfile.set_reduction_factor(reduction_factor);
00301   // psfile.set_parameters(wd, ht); // no longer needed - vul_psfile does this
00302 
00303   // Write image, if present
00304   if (get_image_tableau() && wd*ht > 0)
00305   {
00306     if (get_image_tableau()->get_image_resource())
00307     {
00308       vil_image_resource_sptr img_sptr = get_image_tableau()->get_image_resource();
00309       vil_image_view<vxl_byte> img= img_sptr->get_view();
00310       if (!img)
00311       {
00312         // invalid pixel type
00313         vgui_macro_warning<< "failed to print image of unsupported pixel format: "
00314                           << img << vcl_endl;
00315       }
00316       if (img.nplanes()==1) // greyscale image
00317       {
00318         if (img.istep() != 1)
00319           vgui_macro_warning<< "The istep of this image view is not 1: "
00320                             << img << vcl_endl;
00321         else {
00322           if (debug)
00323             vcl_cerr << "vgui_easy2D_tableau::print_psfile printing greyscale image to"
00324                      << filename.c_str() << '\n';
00325           psfile.print_greyscale_image(img.top_left_ptr(), img.ni(), img.nj());
00326         }
00327       }
00328       else if (img.nplanes() == 3) // color image
00329       {}
00330       else
00331         // urgh
00332         vgui_macro_warning<< "Don't know how to handle image with "
00333                           << img.nplanes() << " planes" << vcl_endl;
00334     }
00335     else
00336     {
00337       vil1_image img = get_image_tableau()->get_image();
00338       unsigned char* data = new unsigned char[img.get_size_bytes()];
00339       img.get_section(data, 0, 0, wd, ht);
00340       if (vil1_pixel_format(img) == VIL1_BYTE)
00341       {
00342         if (debug)
00343           vcl_cerr << "vgui_easy2D_tableau::print_psfile printing greyscale image to"
00344                    << filename.c_str() << '\n';
00345         psfile.print_greyscale_image(data, wd, ht);
00346       }
00347       else if (vil1_pixel_format(img) == VIL1_RGB_BYTE)
00348       {
00349         if (debug)
00350           vcl_cerr << "vgui_easy2D_tableau::print_psfile printing color image to "
00351                    << filename.c_str() << '\n';
00352         psfile.print_color_image(data, wd, ht);
00353       }
00354       else
00355         // urgh
00356         vgui_macro_warning<< "failed to print image of unsupported pixel format: "
00357                           << img << vcl_endl;
00358       delete[] data;
00359     }
00360   }
00361 
00362   // Skip the rest of this function if no geometry is wanted
00363   if (!print_geom_objs) return;
00364   if (debug)
00365     vcl_cerr << "vgui_easy2D_tableau: Printing geometric objects\n";
00366 
00367   vcl_vector<vgui_soview*> all_objs = get_all();
00368   vgui_style_sptr style = 0;
00369   float style_point_size = 0;
00370   for (vcl_vector<vgui_soview*>::iterator i = all_objs.begin(); i != all_objs.end(); ++i)
00371   {
00372     vgui_soview* sv = *i;
00373     if (sv == NULL) {
00374        vgui_macro_warning << "An object in soview list is null\n";
00375        continue;
00376     }
00377     // Send style info if it has changed.
00378     vgui_style_sptr svstyle = sv->get_style();
00379     if (svstyle != style) {
00380       // rgba, line_width, point_size
00381       style = svstyle;
00382       psfile.set_line_width(style->line_width);
00383       style_point_size = style->point_size;
00384       psfile.set_fg_color(style->rgba[0],style->rgba[1],style->rgba[2]);
00385     }
00386 
00387     if (sv->type_name() == "vgui_soview2D_point")
00388     {
00389       vgui_soview2D_point* pt = (vgui_soview2D_point*)sv;
00390       psfile.point(pt->x, pt->y, style_point_size);
00391       if (debug)
00392         vcl_cerr << "  vgui_easy2D_tableau: Adding a point at "
00393                  << pt->x << ", " << pt->y << '\n';
00394     }
00395     else if (sv->type_name() == "vgui_soview2D_circle")
00396     {
00397       vgui_soview2D_circle* circ = (vgui_soview2D_circle*)sv;
00398       psfile.circle(circ->x, circ->y, circ->r);
00399       if (debug)
00400         vcl_cerr << "  vgui_easy2D_tableau: Adding circle, center " << circ->x << ", "
00401                  << circ->y << " radius " << circ->r << '\n';
00402     }
00403     else if (sv->type_name() == "vgui_soview2D_lineseg")
00404     {
00405       vgui_soview2D_lineseg* line = (vgui_soview2D_lineseg*)sv;
00406       psfile.line(line->x0, line->y0, line->x1, line->y1);
00407       if (debug)
00408         vcl_cerr << " vgui_easy2D_tableau: Adding line between " << line->x0 << ", "
00409                  << line->y0 << " and " << line->x1 << ", " << line->y1 << '\n';
00410     }
00411     else if (sv->type_name() == "vgui_soview2D_linestrip")
00412     {
00413       vgui_soview2D_linestrip *linestrip = (vgui_soview2D_linestrip *)sv;
00414       for (unsigned int ii = 1; ii<linestrip->n; ++ii)
00415         psfile.line(linestrip->x[ii-1],linestrip->y[ii-1],
00416                     linestrip->x[ii  ],linestrip->y[ii  ]);
00417       if (debug)
00418         vcl_cerr<< " vgui_easy2D_tableau: Adding linestrip\n";
00419     }
00420     else if (sv->type_name() == "vgui_soview2D_polygon")
00421     {
00422       vgui_soview2D_polygon *polygon = (vgui_soview2D_polygon *)sv;
00423       for (unsigned int ii = 1; ii<polygon->n; ++ii)
00424         psfile.line(polygon->x[ii-1],polygon->y[ii-1],
00425                     polygon->x[ii  ],polygon->y[ii  ]);
00426       psfile.line(polygon->x[polygon->n - 1],
00427                   polygon->y[polygon->n - 1],
00428                   polygon->x[0], polygon->y[0]);
00429       if (debug)
00430         vcl_cerr<< " vgui_easy2D_tableau: Adding polygon\n";
00431     }
00432     else if (sv->type_name() == "vgui_soview2D_ellipse")
00433     {
00434       vgui_soview2D_ellipse* ellip = (vgui_soview2D_ellipse*)sv;
00435       psfile.ellipse(ellip->x, ellip->y, ellip->w, ellip->h, int(57.2957795 * ellip->phi + 0.5)); // convert radians to degrees
00436       if (debug)
00437         vcl_cerr << "  vgui_easy2D_tableau: Adding ellipse, center " << ellip->x << ", "
00438                  << ellip->y << " width " << ellip->w << " height " << ellip->h
00439                  << " angle " << ellip->phi << " (" << int(57.2957795 * ellip->phi + 0.5) << " deg)\n";
00440     }
00441     else
00442       vgui_macro_warning << "unknown soview typename = " << sv->type_name() << vcl_endl;
00443   }
00444 }
00445 
00446 //: Add an image at the given position to the display.
00447 vgui_soview2D_image* vgui_easy2D_tableau::add_image( float x, float y,
00448                                                      vil1_image const& img )
00449 {
00450   // Assume alpha blending is necessary iff there are four components
00451   // in the image
00452   bool blend = false;
00453   if ( img.components() == 4 )
00454     blend = true;
00455   vgui_soview2D_image *obj = new vgui_soview2D_image( x, y, img, blend );
00456   add(obj);
00457   return obj;
00458 }
00459 
00460 //: Add an image at the given position to the display.
00461 vgui_soview2D_image* vgui_easy2D_tableau::add_image( float x, float y,
00462                                                      vil_image_view_base const& img )
00463 {
00464   // Assume alpha blending is necessary iff there are four components
00465   // in the image
00466   bool blend = false;
00467   if ( img.nplanes() == 4 )
00468     blend = true;
00469   vgui_soview2D_image *obj = new vgui_soview2D_image( x, y, img, blend );
00470   add(obj);
00471   return obj;
00472 }
00473 
00474 #if 0 // deprecated method
00475 vgui_soview2D_image* vgui_easy2D_tableau::add_image( float x, float y,
00476                                                      float width, float height,
00477                                                      char *data,
00478                                                      unsigned int format, unsigned int type )
00479 {
00480   if ( type != GL_UNSIGNED_BYTE ) {
00481     vcl_cerr << "Don't know how to add non-byte sprites using old interface\n";
00482     vcl_abort();
00483   }
00484   unsigned w = unsigned(width);
00485   unsigned h = unsigned(height);
00486   vil_image_view<vxl_byte> img;
00487   if ( format == GL_RGB ) {
00488     img = vil_image_view<vxl_byte>( reinterpret_cast<vxl_byte*>(data), w, h, 3, 3, w*3, 1 );
00489 #ifdef DEBUG
00490     vil_save(img, "tmp_image_GL_RGB.jpeg", "jpeg");
00491 #endif
00492   }
00493   else if ( format == GL_RGBA ) {
00494     img = vil_image_view<vxl_byte>( reinterpret_cast<vxl_byte*>(data), w, h, 4, 4, w*4, 1 );
00495 #ifdef DEBUG // inserted debugging jr Oct 24, 2003
00496     vil_save(img, "tmp_image_GL_RGBA.jpeg", "jpeg");
00497 #endif
00498   }
00499   else {
00500     vcl_cerr << "Don't know how to handle format " << format << " with old interface\n";
00501     vcl_abort();
00502   }
00503   return this->add_image( x, y, img );
00504 }
00505 #endif // 0

Generated on Mon Mar 8 05:12:27 2010 for core/vgui by  doxygen 1.5.1