![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
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