MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/mpm/drawarea2d.h
Go to the documentation of this file.
00001 /************************************************************************
00002  * MechSys - Open Library for Mechanical Systems                        *
00003  * Copyright (C) 2005 Dorival M. Pedroso                                *
00004  *                                                                      *
00005  * This program is free software: you can redistribute it and/or modify *
00006  * it under the terms of the GNU General Public License as published by *
00007  * the Free Software Foundation, either version 3 of the License, or    *
00008  * any later version.                                                   *
00009  *                                                                      *
00010  * This program is distributed in the hope that it will be useful,      *
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         *
00013  * GNU General Public License for more details.                         *
00014  *                                                                      *
00015  * You should have received a copy of the GNU General Public License    *
00016  * along with this program. If not, see <http://www.gnu.org/licenses/>  *
00017  ************************************************************************/
00018 
00019 /* DrawArea2D - Copyright (C) 2007 Dorival de Moraes Pedroso */
00020 
00021 #ifndef MPM_DRAWAREA2D_H
00022 #define MPM_DRAWAREA2D_H
00023 
00024 // STL
00025 #include <cmath>  // for ceil and floor
00026 #include <cfloat> // for DBL_EPSILON
00027 
00028 // FLTK
00029 #include <FL/Fl.H>
00030 #include <FL/Fl_Input.H>
00031 #include <FL/Fl_Button.H>
00032 #include <FL/Fl_Choice.H>
00033 #include <FL/Fl_Round_Button.H>
00034 #include <FL/Fl_Check_Button.H>
00035 #include <FL/Fl_Group.H>
00036 #include <FL/fl_draw.H>
00037 #include <FL/Fl_Pixmap.H>
00038 #include <FL/Enumerations.H> // for Fl_Color
00039 
00040 // libpng
00041 #include <png.h>
00042 
00043 // MechSys
00044 #include <mechsys/util/array.h>
00045 #include <mechsys/util/fatal.h>
00046 
00047 // Local
00048 #include <mechsys/mpm/defs.h>
00049 #include <mechsys/mpm/grid2d.h>
00050 #include <mechsys/mpm/tensors.h>
00051 #include <mechsys/mpm/mpoints2d.h>
00052 #include <mechsys/mpm/infobox.h>
00053 #include <mechsys/mpm/colormaps.h>
00054 
00055 // Pixmaps
00056 #include <mechsys/mpm/fixx.xpm>
00057 #include <mechsys/mpm/fixy.xpm>
00058 #include <mechsys/mpm/fixxy.xpm>
00059 
00060 namespace MPM {
00061 
00062 /* Structures. */
00063 Fl_Menu_Item FldItems[] =
00064 {
00065     {"Strain-xx" , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00066     {"Strain-yy" , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00067     {"Strain-zz" , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00068     {"Strain-xy" , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00069     {"Stress-xx" , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00070     {"Stress-yy" , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00071     {"Stress-zz" , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00072     {"Stress-xy" , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00073     {"Cam-p"     , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00074     {"Cam-q"     , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00075     {"Vel-norm"  , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00076     {"ClrIdx"    , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00077     {0,0,0,0,0,0,0,0,0}
00078 };
00079 Fl_Menu_Item PtType[] =
00080 {
00081     {"BoxBord" , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00082     {"Box"     , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00083     {"Circles" , 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 0, 0},
00084     {0,0,0,0,0,0,0,0,0}
00085 };
00086 
00087 /* Drawing area 2D. */
00088 class DrawArea2D : public Fl_Group
00089 {
00090 public:
00091     /* Constructor. */
00092     DrawArea2D (int xmin, int ymin, int width, int height); // Screen coordinates
00093 
00094     /* Destructor. */
00095     virtual ~DrawArea2D ();
00096 
00097     // Methods
00098     void   SetGrid   (Grid2D    const * G) { _g = G; } 
00099     void   SetPoints (MPoints2D const * P) { _p = P; } 
00100     void   SetTime   (double    const * t) { _t = t; } 
00101     void   SetM      (double    const * M) { _M = M; } 
00102     void   CalcSF    ();                               
00103     size_t SelP      () const        { return _selp; } 
00104     size_t SelN      () const        { return _seln; } 
00105     void   ResetSelP (size_t i);                       
00106 
00107     // Set methods
00108     DrawArea2D & EqScales  (bool EQScales=true) { _eqsf=EQScales;  return (*this); } 
00109     DrawArea2D & RecalcSF  (bool REcalcSF=true) { _recsf=REcalcSF; return (*this); } 
00110     DrawArea2D & WithFrame (bool WFrame  =true) { _wframe=WFrame;  return (*this); } 
00111 
00112     // Output method
00113     void SavePNG (char const * Filename)
00114     {
00115         FILE * fp = fopen (Filename, "wb");
00116         if (fp!=NULL)
00117         {
00118             int xmin = _x(_g->xMin());
00119             int xmax = _x(_g->xMax());
00120             int ymin = _y(_g->yMin());
00121             int ymax = _y(_g->yMax());
00122             int ww   = xmax - xmin;
00123             int hh   = ymin - ymax;
00124             if (ww>0 && hh>0)
00125             {
00126                 // write png header information
00127                 png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, (void*)NULL, NULL, NULL);
00128                 png_infop   inf_ptr = png_create_info_struct  (png_ptr);
00129                 png_init_io    (png_ptr, fp);
00130                 png_set_IHDR   (png_ptr, inf_ptr, ww, hh, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
00131                 png_write_info (png_ptr, inf_ptr);
00132                 
00133                 // write pixels
00134                 uchar * pixels = fl_read_image (NULL, xmin, ymax, ww, hh, 0);
00135                 for (int k=0; k<hh; k++) png_write_row (png_ptr, pixels + 3*k*ww);
00136                 delete [] pixels;
00137                 png_write_end (png_ptr, inf_ptr);
00138                 png_destroy_write_struct (&png_ptr, &inf_ptr);
00139             }
00140         }
00141         fclose (fp);
00142     }
00143 
00145     void draw ();
00146 
00147 protected:
00149     int handle (int E);
00150 
00151 private:
00152     // Widgets
00153     Fl_Input        * _w_psz; 
00154     Fl_Choice       * _w_pty; 
00155     Fl_Choice       * _w_cmt; 
00156     Fl_Choice       * _w_fld; 
00157     Fl_Button       * _w_set; 
00158     Fl_Check_Button * _w_inv; 
00159     Fl_Check_Button * _w_ldg; 
00160     Fl_Check_Button * _w_vel; 
00161     Fl_Check_Button * _w_sel; 
00162     Fl_Check_Button * _w_cbr; 
00163     
00164     // Data
00165     double     _sfX;    
00166     double     _sfY;    
00167     bool       _eqsf;   
00168     bool       _recsf;  
00169     bool       _sfok;   
00170     bool       _wframe; 
00171     double     _Xmin;   
00172     double     _Ymin;   
00173     double     _Xmax;   
00174     double     _Ymax;   
00175     int        _hb;     
00176     int        _vb;     
00177     int        _lfz;    
00178     int        _selp;   
00179     int        _seln;   
00180     int        _pselp;  
00181     int        _pseln;  
00182     int        _ctrh;   
00183     int        _cmbw;   
00184     int        _cmbh;   
00185     ClrMapType _cmtype; 
00186     FieldType  _field;  
00187     bool       _cmrinv; 
00188     bool       _loads;  
00189     bool       _veloc;  
00190     bool       _selec;  
00191     bool       _cbar;   
00192 
00193     // Elements
00194     Grid2D    const * _g;  
00195     MPoints2D const * _p;  
00196     double    const * _t;  
00197     double    const * _M;  
00198     CurveProps        _cg; 
00199     CurveProps        _cp; 
00200     
00201     // XPMs
00202     Fl_Pixmap * _fixx;  
00203     Fl_Pixmap * _fixy;  
00204     Fl_Pixmap * _fixxy; 
00205     int         _hf;    
00206     int         _vf;    
00207 
00208     // Private methods
00209     int    _x (double X) const { return static_cast<int>((x()+1+_hb)                          +_sfX*(X-_Xmin));     } 
00210     int    _y (double Y) const { return static_cast<int>((y()+1+_vb+_ctrh)+(h()-2-2*_vb-_ctrh)-_sfY*(Y-_Ymin));     } 
00211     int    _l (double L) const { return static_cast<int>((_sfX>_sfY?_sfY:_sfX)*L);                      } 
00212     double _X (int   xx) const { return _Xmin+(static_cast<double>(xx)-(x()+1+_hb))/_sfX;               } 
00213     double _Y (int   yy) const { return _Ymin+((y()+1+_vb)+(h()-2-2*_vb)-static_cast<double>(yy))/_sfY; } 
00214 
00215     // Private methods
00216     void _draw_vector_field (Array<Vector3D> const & P, Array<Vector3D> const & V, Fl_Color Clr); 
00217     void _draw_arrow        (int xi, int yi, int xf, int yf, Fl_Color Clr=FL_BLUE);               
00218     void _draw_loaded_nodes ();                                                                   
00219     void _draw_coords       ();                                                                   
00220     void _draw_selected     ();                                                                   
00221     void _draw_loaded_points();
00222     void _draw_disp_points  ();
00223     void _draw_colorbar     ();
00224     void _draw_colorbar_labels(double min, double max);
00225 
00226     // Callbacks (must be static)
00227     static void _set_cb (Fl_Widget * o, void * v) { ((DrawArea2D*)v)->_set(); }
00228 
00229     // Control methods
00230     void _set();
00231 
00232 }; // class DrawArea2D
00233 
00234 
00236 
00237 
00238 /* public */
00239 
00240 inline DrawArea2D::DrawArea2D(int xmin, int ymin, int width, int height)
00241     : Fl_Group (xmin,ymin,width,height,0), // {
00242       _sfX    (1.0),
00243       _sfY    (1.0),
00244       _eqsf   (true),
00245       _recsf  (false),
00246       _sfok   (false),
00247       _wframe (true),
00248       _Xmin   (0.0),
00249       _Ymin   (0.0),
00250       _Xmax   (1.0),
00251       _Ymax   (1.0),
00252       _lfz    (8),
00253       _selp   (-1),
00254       _seln   (-1),
00255       _pselp  (-1),
00256       _pseln  (-1),
00257       _ctrh   (25),
00258       _cmbw   (50),
00259       _cmbh   (200),
00260       _cmtype (CMT_JET),
00261       _field  (FLD_TAG),//FLD_CAMQ),
00262       _cmrinv (false),
00263       _g      (NULL),
00264       _p      (NULL),
00265       _t      (NULL),
00266       _M      (NULL),
00267       _hf     (11),
00268       _vf     (11)
00269 {
00270     _w_psz = new Fl_Input        (x(), y(), 0, 0, "Sz");
00271     _w_pty = new Fl_Choice       (x(), y(), 0, 0, "Ty");
00272     _w_ldg = new Fl_Check_Button (x(), y(), 0, 0, "Loads");
00273     _w_vel = new Fl_Check_Button (x(), y(), 0, 0, "Veloc");
00274     _w_sel = new Fl_Check_Button (x(), y(), 0, 0, "Sel");
00275     _w_cbr = new Fl_Check_Button (x(), y(), 0, 0, "CBar");
00276     _w_cmt = new Fl_Choice       (x(), y(), 0, 0, "CMap");
00277     _w_fld = new Fl_Choice       (x(), y(), 0, 0, "Field");
00278     _w_set = new Fl_Button       (x(), y(), 0, 0, "Set");
00279     _w_inv = new Fl_Check_Button (x(), y(), 0, 0, "Inv");
00280     end();
00281 
00282     // Set curve properties for drawing nodes
00283     _cg.Typ = CT_BOTH;
00284     _cg.Clr = FL_GRAY;
00285     _cg.Lty = FL_SOLID;
00286     _cg.Lwd = 1;
00287     _cg.Pch = 1;
00288     _cg.Psz = 4;
00289 
00290     // Set curve properties for drawing material points
00291     _cp.Typ = CT_POINTS;
00292     _cp.Clr = FL_RED;
00293     _cp.Lty = FL_SOLID;
00294     _cp.Lwd = 1;
00295     _cp.Pch = 0;
00296     _cp.Psz = 8;
00297 
00298     // Borders
00299     _hb = 6+_hf+1; // 6 for border + hf for icons (xpms)
00300     _vb = 6+_vf+1; // 6 for border + vf for icons (xpms)
00301 
00302     // Set pixmaps
00303     _fixx  = new Fl_Pixmap (fixx_xpm);
00304     _fixy  = new Fl_Pixmap (fixy_xpm);
00305     _fixxy = new Fl_Pixmap (fixxy_xpm);
00306 
00307     // Initialize widgets
00308     _w_pty->menu  (PtType);
00309     _w_cmt->menu  (ClrMap::Items);
00310     _w_cmt->value (static_cast<int>(_cmtype));
00311     _w_fld->menu  (FldItems);
00312     _w_fld->value (static_cast<int>(_field));
00313     char buf[256];
00314     snprintf(buf, 256, "%d", _cp.Psz); _w_psz->value(buf);
00315 
00316     // Callbacks
00317     _w_set->callback (_set_cb, this);
00318 } // }
00319 
00320 inline DrawArea2D::~DrawArea2D()
00321 {
00322     delete _fixx;
00323     delete _fixy;
00324     delete _fixxy;
00325 }
00326 
00327 inline void DrawArea2D::CalcSF()
00328 {
00329     // Check input
00330     if (_g==NULL)       return;
00331     if (_g->nNodes()<2) return;
00332 
00333     // Bounding box
00334     _Xmin = _g->X(0)(0);
00335     _Ymin = _g->X(0)(1);
00336     _Xmax = _g->X(1)(0);
00337     _Ymax = _g->X(1)(1);
00338     for (size_t i=0; i<_g->nNodes(); ++i)
00339     {
00340         if (_g->X(i)(0)<_Xmin) _Xmin = _g->X(i)(0);
00341         if (_g->X(i)(0)>_Xmax) _Xmax = _g->X(i)(0);
00342         if (_g->X(i)(1)<_Ymin) _Ymin = _g->X(i)(1);
00343         if (_g->X(i)(1)>_Ymax) _Ymax = _g->X(i)(1);
00344     }
00345 
00346     // Scale factors
00347     _sfX = static_cast<double>((w()-2-2*_hb      )/(_Xmax-_Xmin));
00348     _sfY = static_cast<double>((h()-2-2*_vb-_ctrh)/(_Ymax-_Ymin));
00349     if (_eqsf)
00350     {
00351         double sf = (_sfX>_sfY ? _sfY : _sfX);
00352         _sfX = sf;
00353         _sfY = sf;
00354     }
00355 }
00356 
00357 inline void DrawArea2D::ResetSelP(size_t i)
00358 {
00359     _pselp = -1;
00360     _selp  = i;
00361 }
00362 
00363 inline void DrawArea2D::draw()
00364 {
00365     // User damage ONLY ?
00366     if (damage()==FL_DAMAGE_USER1)
00367     {
00368         // Just draw coords and done
00369         _draw_coords();
00370         return;
00371     }
00372 
00373     // Just draw selected points or nodes and done
00374     if (damage()==FL_DAMAGE_USER2)
00375     {
00376         _draw_selected();
00377         return;
00378     }
00379 
00380     // Clear control background
00381     fl_color (FL_BACKGROUND_COLOR);
00382     fl_rectf (x(), y(), w(), _ctrh);
00383 
00384     // Let group draw itself
00385     _w_psz->resize(x()+20,      y(), 40, 25);
00386     _w_pty->resize(x()+20+70,   y(), 90, 25);
00387     _w_ldg->resize(x()+20+170,  y(), 80, 25);
00388     _w_vel->resize(x()+20+235,  y(), 80, 25);
00389     _w_sel->resize(x()+20+300,  y(), 70, 25);
00390     _w_cbr->resize(x()+w()-460, y(), 80, 25);
00391     _w_cmt->resize(x()+w()-350, y(), 80, 25);
00392     _w_inv->resize(x()+w()-260, y(), 60, 25);
00393     _w_fld->resize(x()+w()-170, y(),100, 25);
00394     _w_set->resize(x()+w()-62,  y(), 60, 25);
00395     Fl_Group::draw();
00396 
00397     // Clear the background
00398     fl_color (FL_WHITE);
00399     fl_rectf (x(), y()+_ctrh, w(), h()-_ctrh);
00400 
00401     // Draw an all-around frame
00402     if (_wframe)
00403     {
00404         fl_color      (FL_BLACK);
00405         fl_line_style (FL_SOLID, 1);
00406         fl_rect       (x(), y()+_ctrh, w(), h()-_ctrh);
00407     }
00408 
00409     // Check input
00410     if (_g==NULL)       return;
00411     if (_g->nNodes()<2) return;
00412 
00413     // Calculate scale factors and draw rulers
00414     if (_recsf || !_sfok)
00415     {
00416         CalcSF ();
00417         _sfok = true;
00418     }
00419 
00420     // Set clipping in order to avoid drawing outside drawing area
00421     fl_push_clip (x()+1, y()+_ctrh+1, w()-2, h()-_ctrh-2);
00422 
00423     // Draw lines
00424     if (_cg.Typ==CT_LINES || _cg.Typ==CT_BOTH)
00425     {
00426         fl_color      (_cg.Clr);
00427         fl_line_style (_cg.Lty, _cg.Lwd);
00428 
00429         for (size_t i=0; i<_g->nRow(); ++i)
00430             fl_line (_x(_g->xMin()), _y(_g->yMin()+i*_g->L(1)), _x(_g->xMax()), _y(_g->yMin()+i*_g->L(1)));
00431 
00432         for (size_t j=0; j<_g->nCol(); ++j)
00433             fl_line (_x(_g->xMin()+j*_g->L(0)), _y(_g->yMin()), _x(_g->xMin()+j*_g->L(0)), _y(_g->yMax()));
00434     }
00435 
00436     // Draw fixed nodes
00437     for (size_t i=0; i<_g->nFix(); ++i)
00438     {
00439         int x = _x(_g->FixN(i)(0));
00440         int y = _y(_g->FixN(i)(1));
00441         switch (_g->FixT(i))
00442         {
00443             case FIX_X   : { _fixx->draw(x-_hf,y-_vf/2); break; }
00444             case FIX_Y   : { _fixy->draw(x-_hf/2,y);     break; }
00445             case FIX_Z   : {                             break; }
00446             case FIX_XY  : { _fixxy->draw(x-_hf/2,y);    break; }
00447             case FIX_YZ  : {                             break; }
00448             case FIX_ZX  : {                             break; }
00449             case FIX_XYZ : {                             break; }
00450         }
00451     }
00452 
00453     // Draw cell ids
00454     char buf[256];
00455     /*
00456     fl_font  (0, 8);
00457     fl_color (FL_BLACK);
00458     for (size_t i=0; i<_g->nCells(); ++i)
00459     {
00460         int p0 = _g->C(i)(0);
00461         int p1 = _g->C(i)(1);
00462         int p2 = _g->C(i)(2);
00463         int p3 = _g->C(i)(3);
00464         int xc = _x(0.5*(_g->X(p0)(0)+_g->X(p2)(0)));
00465         int yc = _y(0.5*(_g->X(p0)(1)+_g->X(p2)(1)));
00466         snprintf (buf, 256, "%d\n(%d,%d,%d,%d)", i,p0,p1,p2,p3); // format text
00467         fl_draw  (buf, xc, yc, 0, 0, FL_ALIGN_CENTER);           // draw text
00468     }
00469     */
00470 
00471     // Draw node ids
00472     /*
00473     for (size_t i=0; i<_g->nNodes(); ++i)
00474     {
00475         int xi = _x(_g->X(i)(0));
00476         int yi = _y(_g->X(i)(1));
00477         snprintf (buf, 256, "%d", i);
00478         fl_draw  (buf, xi, yi, 0, 0, FL_ALIGN_CENTER); // draw text
00479     }
00480     */
00481 
00482     // Check input
00483     if (_p==NULL) return;
00484 
00485     // Draw points
00486     double min = 0;
00487     double max = 0;
00488     if (_cp.Typ==CT_POINTS || _cp.Typ==CT_BOTH)
00489     {
00490         int r = _cp.Psz/2;
00491         switch (_field)
00492         {
00493             case FLD_EPSXX: { _p->MinMaxE(0,min,max);                     break; }
00494             case FLD_EPSYY: { _p->MinMaxE(1,min,max);                     break; }
00495             case FLD_EPSZZ: { _p->MinMaxE(2,min,max);                     break; }
00496             case FLD_EPSXY: { _p->MinMaxE(3,min,max); min*=SQ2; max*=SQ2; break; }
00497             case FLD_SIGXX: { _p->MinMaxS(0,min,max);                     break; }
00498             case FLD_SIGYY: { _p->MinMaxS(1,min,max);                     break; }
00499             case FLD_SIGZZ: { _p->MinMaxS(2,min,max);                     break; }
00500             case FLD_SIGXY: { _p->MinMaxS(3,min,max); min*=SQ2; max*=SQ2; break; }
00501             case FLD_CAMP:  { _p->MinMaxCamp(min,max);                    break; }
00502             case FLD_CAMQ:  { _p->MinMaxCamq(min,max);                    break; }
00503             case FLD_VELN:  { _p->MinMaxVelN(min,max);                    break; }
00504             case FLD_TAG:   { break; }
00505         }
00506         if (!(max-min>1.0e-9)) max=min;
00507         fl_line_style (FL_SOLID, 1);
00508         for (size_t i=0; i<_p->nPoints(); ++i)
00509         {
00510             /*
00511             int xi = _x(_p->P(i)(0)-_p->l(i)(0));
00512             int yi = _y(_p->P(i)(1)-_p->l(i)(1));
00513             int xf = _x(_p->P(i)(0)+_p->l(i)(0));
00514             int yf = _y(_p->P(i)(1)+_p->l(i)(1));
00515             fl_color (FL_RED);
00516             fl_rectf (xi, yf, xf-xi, yi-yf);
00517             fl_color (FL_BLACK);
00518             fl_rect  (xi, yf, xf-xi, yi-yf);
00519             */
00520             Fl_Color clr = FL_WHITE;
00521             double   val = max;
00522             if (max-min>1.0e-9)
00523             {
00524                 switch (_field)
00525                 {
00526                     case FLD_EPSXX: { val=(_p->e(i)(0)    -min)/(max-min); break; }
00527                     case FLD_EPSYY: { val=(_p->e(i)(1)    -min)/(max-min); break; }
00528                     case FLD_EPSZZ: { val=(_p->e(i)(2)    -min)/(max-min); break; }
00529                     case FLD_EPSXY: { val=(_p->e(i)(3)*SQ2-min)/(max-min); break; }
00530                     case FLD_SIGXX: { val=(_p->s(i)(0)    -min)/(max-min); break; }
00531                     case FLD_SIGYY: { val=(_p->s(i)(1)    -min)/(max-min); break; }
00532                     case FLD_SIGZZ: { val=(_p->s(i)(2)    -min)/(max-min); break; }
00533                     case FLD_SIGXY: { val=(_p->s(i)(3)*SQ2-min)/(max-min); break; }
00534                     case FLD_CAMP:  { val=(Calc_pcam(_p->s(i))-min)/(max-min); break; }
00535                     case FLD_CAMQ:  { val=(Calc_qcam(_p->s(i))-min)/(max-min); break; }
00536                     case FLD_VELN:  { val=(NormV(_p->v(i))-min)/(max-min); break; }
00537                     case FLD_TAG:   { break; }
00538                 }
00539             }
00540             if (_field==FLD_TAG) clr = ClrMap::GetColor(_p->Clr(i));
00541             else
00542             {
00543                 switch (_cmtype)
00544                 {
00545                     case CMT_JET: { int idx=static_cast<int>(_cmrinv?ClrMap::JET_NCOLORS-1-(ClrMap::JET_NCOLORS-1.0)*val:(ClrMap::JET_NCOLORS-1.0)*val); clr=ClrMap::JET[idx]; break; }
00546                     case CMT_HOT: { int idx=static_cast<int>(_cmrinv?ClrMap::HOT_NCOLORS-1-(ClrMap::HOT_NCOLORS-1.0)*val:(ClrMap::HOT_NCOLORS-1.0)*val); clr=ClrMap::HOT[idx]; break; }
00547                     case CMT_BWP: { int idx=static_cast<int>(_cmrinv?ClrMap::BWP_NCOLORS-1-(ClrMap::BWP_NCOLORS-1.0)*val:(ClrMap::BWP_NCOLORS-1.0)*val); clr=ClrMap::BWP[idx]; break; }
00548                 }
00549             }
00550             //if (_p->HasT(i)) clr=FL_BLACK;
00551             fl_color   (clr);
00552             if (_cp.Pch==0) // Real cube
00553             {
00554                 _p->CalcC(i);
00555                 fl_polygon ( _x(_p->C[0](0)),
00556                              _y(_p->C[0](1)),
00557                              _x(_p->C[1](0)),
00558                              _y(_p->C[1](1)),
00559                              _x(_p->C[2](0)),
00560                              _y(_p->C[2](1)),
00561                              _x(_p->C[3](0)),
00562                              _y(_p->C[3](1)) );
00563                 fl_color (FL_BLACK);
00564                 fl_loop  ( _x(_p->C[0](0)),
00565                            _y(_p->C[0](1)),
00566                            _x(_p->C[1](0)),
00567                            _y(_p->C[1](1)),
00568                            _x(_p->C[2](0)),
00569                            _y(_p->C[2](1)),
00570                            _x(_p->C[3](0)),
00571                            _y(_p->C[3](1)) );
00572             }
00573             else if (_cp.Pch==1) // Real cube with borders
00574             {
00575                 _p->CalcC(i);
00576                 fl_polygon ( _x(_p->C[0](0)),
00577                              _y(_p->C[0](1)),
00578                              _x(_p->C[1](0)),
00579                              _y(_p->C[1](1)),
00580                              _x(_p->C[2](0)),
00581                              _y(_p->C[2](1)),
00582                              _x(_p->C[3](0)),
00583                              _y(_p->C[3](1)) );
00584             }
00585             else if (_cp.Pch==2) // Filled circle
00586             {
00587                 fl_pie (_x(_p->P(i)(0))-r, _y(_p->P(i)(1))-r, 2*r+1, 2*r+1, 0,360);
00588             }
00589         }
00590     }
00591 
00592     // Draw points lengths
00593     /*
00594     for (size_t i=0; i<_p->nPoints(); ++i)
00595     {
00596         _draw_arrow (_x(_p->P(i)(0)), _y(_p->P(i)(1)), _x(_p->P(i)(0)+_p->lx(i)(0)), _y(_p->P(i)(1)+_p->lx(i)(1)));
00597         _draw_arrow (_x(_p->P(i)(0)), _y(_p->P(i)(1)), _x(_p->P(i)(0)+_p->ly(i)(0)), _y(_p->P(i)(1)+_p->ly(i)(1)));
00598     }
00599     */
00600 
00601     // Draw mat points ids
00602     /*
00603     fl_font  (0, 8);
00604     fl_color (FL_BLACK);
00605     for (size_t i=0; i<_p->nPoints(); ++i)
00606     {
00607         int xc = _x(_p->P(i)(0));
00608         int yc = _y(_p->P(i)(1));
00609         snprintf (buf, 256, "%d", i);                  // format text
00610         fl_draw  (buf, xc, yc, 0, 0, FL_ALIGN_CENTER); // draw text
00611     }
00612     */
00613     
00614     // Draw velocity field
00615     if (_veloc) _draw_vector_field (_p->Ps(), _p->v(), FL_BLUE);
00616 
00617     // Draw boundary mat points
00618     /*
00619     if (_p->nPointsOnBry()>0)
00620     {
00621         int r = _cp.Psz/2+1;
00622         fl_color      (FL_BLACK);
00623         fl_line_style (FL_SOLID, 2);
00624         for (size_t i=0; i<_p->nPointsOnBry(); ++i)
00625             fl_pie (_x(_p->B(i)(0))-r, _y(_p->B(i)(1))-r, 2*r+1, 2*r+1, 0,360);
00626     }
00627     */
00628 
00629     // Draw time
00630     if (_t==NULL) return;
00631     snprintf (buf, 256, "t=%g", (*_t)); // format text
00632     fl_font  (0, 16);                   // Set font for labels
00633     fl_color (FL_RED);                  // set color
00634     fl_draw  (buf, x()+w()-148, y()+h()-18-18, 0, 0, FL_ALIGN_LEFT_TOP); // draw text
00635     /*
00636     fl_font  (0, 22);                      // Set font for labels
00637     fl_color (FL_RED);                    // set color
00638     fl_draw  (buf, x()+w()-2, y(), 0, 0, FL_ALIGN_RIGHT_TOP); // draw text
00639     */
00640 
00641     // Draw coords
00642     _draw_coords();
00643 
00644     // Draw loaded nodes and points
00645     if (_loads)
00646     {
00647         //_draw_loaded_nodes ();
00648         _draw_loaded_points();
00649     }
00650 
00651     // Draw selected
00652     if (_selec) _draw_selected();
00653 
00654     // Draw points with disp (velocity) prescribed
00655     _draw_disp_points();
00656 
00657     // Draw colorbar
00658     if (_cbar)
00659     {
00660         _draw_colorbar();
00661         _draw_colorbar_labels(min,max);
00662     }
00663 
00664     // Pop clipping
00665     fl_pop_clip ();
00666 }
00667 
00668 inline int DrawArea2D::handle(int E)
00669 {
00670     int ret = Fl_Group::handle(E);
00671     switch (E)
00672     {
00673         case FL_MOVE:
00674         {
00675             damage (FL_DAMAGE_USER1);
00676             return 1;
00677         }
00678         case FL_PUSH:
00679         {
00680             if (_g==NULL) return ret;
00681 
00682             /*
00683             char   buf[256];
00684             double X = _X(Fl::event_x());
00685             double Y = _Y(Fl::event_y());
00686             sprintf(buf, "Selected: x=%.4g y=%.4g", X, Y);
00687             */
00688 
00689             // Search mat points
00690             _pselp = _selp; // previous selected
00691             _selp  = -1;    // current selected
00692             for (size_t i=0; i<_p->nPoints(); ++i)
00693             {
00694                 long dx = _x(_p->P(i)(0))-static_cast<long>(Fl::event_x());
00695                 long dy = _y(_p->P(i)(1))-static_cast<long>(Fl::event_y());
00696                 long d  = static_cast<long>(sqrt(dx*dx+dy*dy));
00697                 if (d<10) { _selp=i; break; }
00698             }
00699 
00700             // Search nodes
00701             /*
00702             _pseln = _seln; // previous selected
00703             _seln  = -1;    // current selected
00704             if (_selp<0)
00705             {
00706                 for (size_t i=0; i<_g->nNodes(); ++i)
00707                 {
00708                     long dx = _x(_g->X(i)(0))-static_cast<long>(Fl::event_x());
00709                     long dy = _y(_g->X(i)(1))-static_cast<long>(Fl::event_y());
00710                     long d  = static_cast<long>(sqrt(dx*dx+dy*dy));
00711                     if (d<4) { _seln=i; break; }
00712                 }
00713             }
00714             */
00715 
00716             // Execute selection action
00717             if (_selp>=0) (*callback()) (this, user_data());
00718 
00719             // Redraw
00720             damage (FL_DAMAGE_USER2);
00721             return 1;
00722         }
00723     }
00724     return ret;
00725 }
00726 
00727 
00728 /* private */
00729 
00730 inline void DrawArea2D::_draw_vector_field (Array<Vector3D> const & P, Array<Vector3D> const & V, Fl_Color Clr)
00731 {
00732     // Check
00733     if (P.Size()<1) return;
00734 
00735     // Boundaries
00736     double maxvnorm = NormV(V[0]);
00737     for (size_t i=0; i<P.Size(); ++i)
00738     {
00739         double vnorm = NormV(V[i]);
00740         if (vnorm>maxvnorm) maxvnorm = vnorm;
00741     }
00742 
00743     // Draw
00744     if (maxvnorm>0.0)
00745     {
00746         for (size_t i=0; i<P.Size(); ++i)
00747         {
00748             int xi = _x(P[i](0));
00749             int yi = _y(P[i](1));
00750             int xf = _x(P[i](0)+V[i](0)/maxvnorm);
00751             int yf = _y(P[i](1)+V[i](1)/maxvnorm);
00752             _draw_arrow (xi, yi, xf, yf, Clr);
00753         }
00754     }
00755 }
00756 
00757 inline void DrawArea2D::_draw_arrow (int xi, int yi, int xf, int yf, Fl_Color Clr)
00758 {
00759     fl_color      (Clr);
00760     fl_line_style (FL_SOLID, 1);
00761     fl_line       (xi, yi, xf, yf);
00762     fl_line_style (FL_SOLID, 2);
00763     fl_line       ((xi+xf)/2, (yi+yf)/2, xf, yf); 
00764 }
00765 
00766 inline void DrawArea2D::_draw_loaded_nodes ()
00767 {
00768     // Check
00769     if (_g->nLd()<1) return;
00770 
00771     // Boundaries
00772     double maxfnx = _g->Ld(0)(0);
00773     double maxfny = _g->Ld(0)(1);
00774     for (size_t i=0; i<_g->nLd(); ++i)
00775     {
00776         if (_g->Ld(i)(0)>maxfnx) maxfnx = _g->Ld(i)(0);
00777         if (_g->Ld(i)(1)>maxfny) maxfny = _g->Ld(i)(1);
00778     }
00779 
00780     // Draw
00781     char buf[80];
00782     for (size_t i=0; i<_g->nLd(); ++i)
00783     {
00784         int lfx = 20*static_cast<int>(fabs(_g->Ld(i)(0)/maxfnx+1));
00785         int lfy = 20*static_cast<int>(fabs(_g->Ld(i)(1)/maxfny+1));
00786         if (lfx>0 || lfy>0)
00787         {
00788             int xi = _x(_g->LdN(i)(0));
00789             int yi = _y(_g->LdN(i)(1));
00790             int xf = (_g->Ld(i)(0)>0 ? xi+lfx : xi-lfx);
00791             int yf = (_g->Ld(i)(1)>0 ? yi-lfy : yi+lfy);
00792             _draw_arrow (xi, yi, xf, yf, FL_MAGENTA);
00793             // Write text
00794             sprintf(buf, "%g\n%g",_g->Ld(i)(0)*(*_M),_g->Ld(i)(1)*(*_M));
00795             fl_color (FL_BLACK);
00796             fl_font  (0, 10);
00797             fl_draw  (buf, xf, yf, 0, 0, FL_ALIGN_CENTER);
00798         }
00799     }
00800 }
00801 
00802 inline void DrawArea2D::_draw_loaded_points ()
00803 {
00804     for (size_t i=0; i<_p->nPoints(); ++i)
00805     {
00806         if (_p->HasT(i))
00807         {
00808             // coordinates
00809             int xi = _x(_p->P(i)(0));
00810             int yi = _y(_p->P(i)(1));
00811             int xf = _x(_p->P(i)(0)+_p->t(i)(0));
00812             int yf = _y(_p->P(i)(1)+_p->t(i)(1));
00813             // icon
00814             int r = _cp.Psz/2;
00815             fl_color      (FL_BLACK);
00816             fl_line_style (FL_SOLID, 1);
00817             fl_pie        (xi-r, yi-r, 2*r+1, 2*r+1, 0,360);
00818             // arrow
00819             _draw_arrow (xi,yi, xf,yf, FL_RED);
00820             // text
00821             char buf[256];
00822             sprintf(buf, "(%.3g,%.3g)", _p->t(i)(0), _p->t(i)(1));
00823             fl_color (FL_BLACK);
00824             fl_font  (0, 9);
00825             fl_draw  (buf, xf, yf, 0, 0, FL_ALIGN_CENTER);
00826         }
00827     }
00828 }
00829 
00830 inline void DrawArea2D::_draw_disp_points ()
00831 {
00832     for (size_t i=0; i<_p->nPoints(); ++i)
00833     {
00834         if (_p->HasU(i))
00835         {
00836             // coordinates
00837             int xi = _x(_p->P(i)(0));
00838             int yi = _y(_p->P(i)(1));
00839             // icon
00840             int r = _cp.Psz/2+2;
00841             fl_color      (FL_RED);
00842             fl_line_style (FL_SOLID, 1);
00843             fl_pie        (xi-r, yi-r, 2*r+1, 2*r+1, 0,360);
00844             // text
00845             char buf[256];
00846             sprintf(buf, "%g", _p->fu(i)(0));
00847             fl_color (FL_BLACK);
00848             fl_font  (0, 8);
00849             fl_draw  (buf, xi, yi, 0, 0, FL_ALIGN_CENTER);
00850         }
00851     }
00852 }
00853 
00854 inline void DrawArea2D::_draw_coords()
00855 {
00856     // Coordinates as a string
00857     char s[80];
00858     sprintf(s, "x=%.4g y=%.4g", _X(Fl::event_x()), _Y(Fl::event_y()));
00859     fl_color (FL_WHITE);
00860     fl_rectf (x()+w()-151,y()+h()-19,150,18);
00861     fl_color (FL_BLACK);
00862     fl_font  (0, 12);
00863     fl_draw  (s, x()+w()-148, y()+h()-18, 0, 0, FL_ALIGN_LEFT_TOP);
00864     /*
00865     // Background
00866     fl_color (0xefebe700);
00867     fl_rectf (x()+1,y()+1,150,18);
00868     // Write text
00869     fl_color (FL_BLACK);
00870     fl_font  (0, 12);
00871     fl_draw  (s, x()+2, y()+1, 0, 0, FL_ALIGN_LEFT_TOP);
00872     */
00873     // Frame
00874     /*
00875     fl_color      (FL_BLACK);
00876     fl_line_style (FL_SOLID, 1);
00877     fl_rect       (x(), y(), 150, 18);
00878     */
00879 }
00880 
00881 inline void DrawArea2D::_draw_selected()
00882 {
00883     // Mat points
00884     if (_p!=NULL)
00885     {
00886         if (_p->nPoints()>0 && _pselp>=0) // erase previous
00887         {
00888             int xx = _x(_p->P(_pselp)(0));
00889             int yy = _y(_p->P(_pselp)(1));
00890             int r  = _cp.Psz/2;
00891             // Clear background
00892             fl_color      (FL_WHITE);
00893             fl_line_style (FL_SOLID, 3);
00894             fl_circle     (xx, yy, r);
00895             // Draw previous
00896             if (_cp.Typ==CT_POINTS || _cp.Typ==CT_BOTH)
00897             {
00898                 if (_cp.Pch==1) // Open circle
00899                 {
00900                     fl_color      (FL_BLACK);
00901                     fl_line_style (FL_SOLID, 1);
00902                     fl_circle     (xx, yy, r);
00903                 }
00904                 else if (_cp.Pch==16) // Filled circle
00905                 {
00906                     fl_color      (_cp.Clr);
00907                     fl_line_style (FL_SOLID, 1);
00908                     fl_pie        (xx-r, yy-r, 2*r+1, 2*r+1, 0,360);
00909                 }
00910             }
00911         }
00912         if (_p->nPoints()>0 && _selp>=0) // draw selected
00913         {
00914             int r = _cp.Psz/2;
00915             fl_color      (FL_GREEN);
00916             fl_line_style (FL_SOLID, 3);
00917             fl_circle     (_x(_p->P(_selp)(0)), _y(_p->P(_selp)(1)), r);
00918         }
00919     }
00920 
00921     // Grid nodes
00922     if (_g!=NULL)
00923     {
00924         if (_g->nNodes()>0 && _pseln>=0) // erase previous
00925         {
00926             int xx = _x(_g->X(_pseln)(0));
00927             int yy = _y(_g->X(_pseln)(1));
00928             int r  = _cg.Psz/2;
00929             // Clear background
00930             fl_color      (FL_WHITE);
00931             fl_line_style (FL_SOLID, 3);
00932             fl_circle     (xx, yy, r);
00933             // Draw pieces of grid lines
00934             if (_cg.Typ==CT_LINES || _cg.Typ==CT_BOTH)
00935             {
00936                 fl_color      (_cg.Clr);
00937                 fl_line_style (_cg.Lty, _cg.Lwd);
00938                 fl_line       (xx-r-2, yy, xx+r+2, yy);
00939                 fl_line       (xx, yy-r-2, xx, yy+r+2);
00940             }
00941             // Draw previous
00942             if (_cg.Typ==CT_POINTS || _cg.Typ==CT_BOTH)
00943             {
00944                 if (_cg.Pch==1) // Open circle
00945                 {
00946                     fl_color      (FL_BLACK);
00947                     fl_line_style (FL_SOLID, 1);
00948                     fl_circle     (xx, yy, r);
00949                 }
00950                 else if (_cg.Pch==16) // Filled circle
00951                 {
00952                     fl_color      (_cg.Clr);
00953                     fl_line_style (FL_SOLID, 1);
00954                     fl_pie        (xx-r, yy-r, 2*r+1, 2*r+1, 0,360);
00955                 }
00956             }
00957         }
00958         if (_g->nNodes()>0 && _seln>=0) // draw selected
00959         {
00960             int r = _cg.Psz/2;
00961             fl_color      (FL_MAGENTA);
00962             fl_line_style (FL_SOLID, 3);
00963             fl_circle     (_x(_g->X(_seln)(0)), _y(_g->X(_seln)(1)), r);
00964         }
00965     }
00966 }
00967 
00968 inline void DrawArea2D::_draw_colorbar()
00969 {
00970     size_t     nclr = 0;
00971     Fl_Color * map  = NULL;
00972     switch (_cmtype)
00973     {
00974         case CMT_BWP: { nclr=ClrMap::BWP_NCOLORS; map=ClrMap::BWP; break; }
00975         case CMT_HOT: { nclr=ClrMap::HOT_NCOLORS; map=ClrMap::HOT; break; }
00976         case CMT_JET: { nclr=ClrMap::JET_NCOLORS; map=ClrMap::JET; break; }
00977     }
00978     if (map==NULL) return;
00979     int cmbh = _cmbh/nclr;
00980     fl_line_style (FL_SOLID, 1);
00981     int xi,yi,xf;//,yf;
00982     for (size_t i=0; i<nclr; ++i)
00983     {
00984         xi = x()+w()-_cmbw-20;
00985         yi = y()+_ctrh+_cmbh-cmbh*(i+1);
00986         xf = xi+_cmbw;
00987         //yf = yi+cmbh;
00988         int idx=(_cmrinv?nclr-1-i:i);
00989         fl_color (map[idx]);
00990         fl_rectf (xi, yi, _cmbw, cmbh);
00991         fl_color (FL_BLACK);
00992         fl_line  (xi, yi, xf, yi);
00993     }
00994     //fl_line (xi, yf, xf, yf);
00995 }
00996 
00997 inline void DrawArea2D::_draw_colorbar_labels(double min, double max)
00998 {
00999     size_t     nclr = 0;
01000     Fl_Color * map  = NULL;
01001     switch (_cmtype)
01002     {
01003         case CMT_BWP: { nclr=ClrMap::BWP_NCOLORS; map=ClrMap::BWP; break; }
01004         case CMT_HOT: { nclr=ClrMap::HOT_NCOLORS; map=ClrMap::HOT; break; }
01005         case CMT_JET: { nclr=ClrMap::JET_NCOLORS; map=ClrMap::JET; break; }
01006     }
01007     if (map==NULL) return;
01008     int cmbh = _cmbh/nclr;
01009     fl_line_style (FL_SOLID, 1);
01010     int xi,yi;//,xf,yf;
01011     char buf[256];
01012     for (size_t i=0; i<nclr+1; ++i)
01013     {
01014         xi = x()+w()-_cmbw-22;
01015         yi = y()+_ctrh+_cmbh-cmbh*i;
01016         //xf = xi+_cmbw;
01017         //yf = yi+cmbh;
01018         fl_color (FL_BLACK);
01019         snprintf (buf, 256, "%g", min+i*(max-min)/static_cast<double>(nclr));
01020         fl_draw  (buf, xi, yi, 0, 0, FL_ALIGN_RIGHT);
01021     }
01022     //fl_line (xi, yf, xf, yf);
01023 }
01024 
01025 inline void DrawArea2D::_set()
01026 {
01027     // Input
01028     _cp.Psz = atoi(_w_psz->value());
01029     _cp.Pch = _w_pty->value();
01030     _cmtype = static_cast<ClrMapType>(_w_cmt->value());
01031     _field  = static_cast<FieldType> (_w_fld->value());
01032     _cmrinv = (_w_inv->value()==1 ? true : false);
01033     _loads  = (_w_ldg->value()==1 ? true : false);
01034     _veloc  = (_w_vel->value()==1 ? true : false);
01035     _selec  = (_w_sel->value()==1 ? true : false);
01036     _cbar   = (_w_cbr->value()==1 ? true : false);
01037 
01038     // Redraw
01039     redraw   ();
01040     Fl::wait (0);
01041 }
01042 
01043 }; // namespace MPM
01044 
01045 #endif // MPM_DRAWAREA2D_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines