Hermes2D  2.0
order_view.cpp
1 // This file is part of Hermes2D.
2 //
3 // Copyright 2005-2008 Jakub Cerveny <jakub.cerveny@gmail.com>
4 // Copyright 2005-2008 Lenka Dubcova <dubcova@gmail.com>
5 // Copyright 2005-2008 Pavel Solin <solin@unr.edu>
6 // Copyright 2009-2010 Ivo Hanak <hanak@byte.cz>
7 //
8 // Hermes2D is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation, either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // Hermes2D is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with Hermes2D. If not, see <http://www.gnu.org/licenses/>.
20 
21 // $Id: view4.cpp 1086 2008-10-21 09:05:44Z jakub $
22 
23 #ifndef NOGLUT
24 
25 #include <GL/freeglut.h>
26 #include "global.h"
27 #include "order_view.h"
28 #include "space.h"
29 
30 namespace Hermes
31 {
32  namespace Hermes2D
33  {
34  namespace Views
35  {
36  OrderView::OrderView(const char* title, WinGeom* wg)
37  : View(title, wg)
38  {
39  b_scale = true;
40  b_orders = false;
41  scale_width = 36;
42  scale_box_height = 25;
43  scale_box_skip = 9;
44  }
45 
46  OrderView::OrderView(char* title, WinGeom* wg)
47  : View(title, wg)
48  {
49  b_scale = true;
50  b_orders = false;
51  scale_width = 36;
52  scale_box_height = 25;
53  scale_box_skip = 9;
54  }
55 
56  static int order_palette[] =
57  {
58  0x7f7f7f,
59  0x7f2aff,
60  0x2a2aff,
61  0x2a7fff,
62  0x00d4aa,
63  0x00aa44,
64  0xabc837,
65  0xffd42a,
66  0xc87137,
67  0xc83737,
68  0xff0000
69  };
70 
71  template<typename Scalar>
72  void OrderView::show(const Space<Scalar>* space)
73  {
74  if(!space->is_up_to_date())
75  throw Hermes::Exceptions::Exception("The space is not up to date.");
76 
77  ord.lock_data();
78  ord.process_space(space);
79  ord.calc_vertices_aabb(&vertices_min_x, &vertices_max_x, &vertices_min_y, &vertices_max_y);
80  init_order_palette(ord.get_vertices());
81  ord.unlock_data();
82 
83  create();
84  update_layout();
85  reset_view(false);
86  refresh();
87  wait_for_draw();
88  }
89 
90  void OrderView::init_order_palette(double3* vert)
91  {
92  int min = 1, max = (int) vert[0][2];
93  for (int i = 0; i < ord.get_num_vertices(); i++)
94  {
95  if((int) vert[i][2] < min) min = (int) vert[i][2];
96  if((int) vert[i][2] > max) max = (int) vert[i][2];
97  }
98 
99  num_boxes = max - min + 1;
100  char* buf = text_buffer;
101  for (int i = 0; i < num_boxes; i++)
102  {
103  if(pal_type == H2DV_PT_DEFAULT)
104  {
105  order_colors[i + min][0] = (float) (order_palette[i + min] >> 16) / 0xff;
106  order_colors[i + min][1] = (float) ((order_palette[i + min] >> 8) & 0xff) / 0xff;
107  order_colors[i + min][2] = (float) (order_palette[i + min] & 0xff) / 0xff;
108  }
109  else
110  {
111  get_palette_color((i + min) / (double)H2DV_MAX_VIEWABLE_ORDER, &order_colors[i + min][0]);
112  }
113 
114  sprintf(buf, "%d", i + min);
115  box_names[i] = buf;
116  buf += strlen(buf) + 1;
117  }
118 
119  scale_height = num_boxes * scale_box_height + (num_boxes-1) * scale_box_skip;
120  order_min = min;
121  }
122 
123  void OrderView::set_b_orders(bool set)
124  {
125  b_orders = set;
126  refresh();
127  }
128 
129  void OrderView::on_display()
130  {
131  set_ortho_projection();
132  glDisable(GL_TEXTURE_1D);
133  glDisable(GL_LIGHTING);
134  glDisable(GL_DEPTH_TEST);
135 
136  // transform all vertices
137  ord.lock_data();
138  int i, nv = ord.get_num_vertices();
139  double3* vert = ord.get_vertices();
140  double2* tvert = new double2[nv];
141  for (i = 0; i < nv; i++)
142  {
143  tvert[i][0] = transform_x(vert[i][0]);
144  tvert[i][1] = transform_y(vert[i][1]);
145  }
146 
147  // draw all triangles
148  int3* tris = ord.get_triangles();
149  glBegin(GL_TRIANGLES);
150  for (i = 0; i < ord.get_num_triangles(); i++)
151  {
152  const float* color = order_colors[(int) vert[tris[i][0]][2]];
153  glColor3f(color[0], color[1], color[2]);
154 
155  glVertex2d(tvert[tris[i][0]][0], tvert[tris[i][0]][1]);
156  glVertex2d(tvert[tris[i][1]][0], tvert[tris[i][1]][1]);
157  glVertex2d(tvert[tris[i][2]][0], tvert[tris[i][2]][1]);
158  }
159  glEnd();
160 
161  // draw all edges
162  if(pal_type == 0)
163  glColor3f(0.4f, 0.4f, 0.4f);
164  else if(pal_type == 1)
165  glColor3f(1.0f, 1.0f, 1.0f);
166  else
167  glColor3f(0.0f, 0.0f, 0.0f);
168  glBegin(GL_LINES);
169  int2* edges = ord.get_edges();
170  for (i = 0; i < ord.get_num_edges(); i++)
171  {
172  glVertex2d(tvert[edges[i][0]][0], tvert[edges[i][0]][1]);
173  glVertex2d(tvert[edges[i][1]][0], tvert[edges[i][1]][1]);
174  }
175  glEnd();
176 
177  // draw labels
178  if(b_orders)
179  {
180  int* lvert;
181  char** ltext;
182  double2* lbox;
183  int nl = ord.get_labels(lvert, ltext, lbox);
184  for (i = 0; i < nl; i++)
185  if(lbox[i][0] * scale > get_text_width(ltext[i]) &&
186  lbox[i][1] * scale > 13)
187  {
188  //color = get_palette_color((vert[lvert[i]][2] - 1) / 9.0);
189  const float* color = order_colors[(int) vert[lvert[i]][2]];
190  if((color[0]*0.39f + color[1]*0.50f + color[2]*0.11f) > 0.5f)
191  glColor3f(0, 0, 0);
192  else
193  glColor3f(1, 1, 1);
194 
195  draw_text(tvert[lvert[i]][0], tvert[lvert[i]][1], ltext[i], 0);
196  }
197  }
198 
199  delete [] tvert;
200  ord.unlock_data();
201  }
202 
203  int OrderView::measure_scale_labels()
204  {
205  return 0;
206  }
207 
208  void OrderView::scale_dispatch()
209  {
210  draw_discrete_scale(num_boxes, box_names, order_colors + order_min);
211  }
212 
213  void OrderView::on_key_down(unsigned char key, int x, int y)
214  {
215  switch (key)
216  {
217  case 'c':
218  reset_view(true);
219  refresh();
220  break;
221 
222  case 'm':
223  b_orders = !b_orders;
224  refresh();
225  break;
226 
227  case 'p':
228  {
229  switch(pal_type)
230  {
231  case H2DV_PT_DEFAULT: pal_type = H2DV_PT_HUESCALE; break;
232  case H2DV_PT_HUESCALE: pal_type = H2DV_PT_GRAYSCALE; break;
233  case H2DV_PT_GRAYSCALE: pal_type = H2DV_PT_INVGRAYSCALE; break;
234  case H2DV_PT_INVGRAYSCALE: pal_type = H2DV_PT_DEFAULT; break;
235  default: throw Hermes::Exceptions::Exception("Invalid palette type");
236  }
237  ord.lock_data();
238  init_order_palette(ord.get_vertices());
239  ord.unlock_data();
240  refresh();
241  break;
242  }
243 
244  default:
245  View::on_key_down(key, x, y);
246  break;
247  }
248  }
249 
250  const char* OrderView::get_help_text() const
251  {
252  return
253  "OrderView\n\n"
254  "Controls:\n"
255  " Left mouse - pan\n"
256  " Right mouse - zoom\n"
257  " C - center image\n"
258  " M - toggle element orders\n"
259  " H - render high-quality frame\n"
260  " P - cycle palettes\n"
261  " S - save screenshot\n"
262  " F1 - this help\n"
263  " Esc, Q - quit";
264  }
265 
266  template HERMES_API void OrderView::show<double>(const Space<double>* space);
267  template HERMES_API void OrderView::show<std::complex<double> >(const Space<std::complex<double> >* space);
268  }
269  }
270 }
271 #endif